Mail-SMTP-Honeypot
view release on metacpan or search on metacpan
Honeypot.pm view on Meta::CPAN
sock => $dns,
alarm => 0,
# name => '4.3.2.1.in-addr.arpa',
# read => \&dns_rcv
};
$dns = {}; # dns transaction hash
}
sub my_dump {
my %names;
local *pref = __PACKAGE__ . '::';
foreach(keys %{*pref}) {
$names{'*'.$_} = \&{*pref->{$_}};
}
my @d = (
$threads => 'threads',
$dns => 'dns',
);
for ($_=0;$_<@d;$_+=2) {
my $d = new Data::Dumper([$d[$_]],[$d[$_+1]]);
$d->Seen(\%names);
@_ = split(/\n/,$d->Dump);
foreach(@_) {
logit($_ ."\n");
}
}
}
sub daemon {
unless ($syslog && $syslog eq 'STDERR') {
open STDERR, '>/dev/null' or die "Can't dup STDERR to /dev/null: $!";
}
# initialization complete, log start up message
logit('Initiated...');
my $run = 1;
local $SIG{TERM} = sub {$run = 0};
local $SIG{USR1} = \&my_dump;
local $SIG{PIPE} = 'IGNORE';
my $then = time;
my $sock = open_listenNB($port,$laddr);
die "could not open listen socket on port $port\n"
unless $sock;
my $fileno = fileno($sock);
my $go_listen = $threads->{$fileno} = {
sock => $sock,
alarm => 0,
read => \&newthread,
# next => \&next thing to do
};
my($rin,$win,$rout,$wout,$delta,$nfound);
while($run) {
$win = $rin = '';
$threads->{$DNSfileno}->{read} = \&dns_rcv; # always armed
foreach(grep(!/\D/,keys %$threads)) { # each thread key
vec($rin,$_,1) = 1 if $threads->{$_}->{read}; # set read selects
vec($win,$_,1) = 1 if $threads->{$_}->{write}; # set write selects
}
$go_listen->{read} = \&newthread; # re-arm listner if it was busy
$nfound = select($rout=$rin,$wout=$win,undef,1); # tick each second
if ($nfound > 0) {
do_thread($wout,'write') if $wout;
do_thread($rout,'read') if $rout;
}
elsif ($delta = ($_ = time) - $then) { # timer = next second or more
$then = $_;
my @threads = keys %$threads;
foreach(@threads) { # each receive thread
next unless exists $threads->{$_};
my $tptr = $threads->{$_};
if ($tptr->{alarm} &&
($tptr->{alarm} + $delay) < $then) {
$tptr->{alarm} = time + $disconnect - $delay;
my($logtxt,$go);
if ($tptr->{tout}) {
$go = $tptr->{tout};
$logtxt = 'tout ';
} else {
$go = $tptr->{next};
$logtxt = 'next ';
}
if ($verbose > 3) { # deep trace
$logtxt = &who ."delay ended for '$_' $logtxt => ".
(exists $subref{$go}) ? $subref{$go} : 'sub ref not defined';
logit($logtxt);
}
elsif ($verbose > 2) {
logit(&who ."delay ended for '$_'\n");
}
$go->($_);
if (exists $threads->{$_} && ! $threads->{$_}->{tout}) {
$threads->{$_}->{tout} = \&terminate
}
last;
}
}
foreach(keys %$dns) { # each dns thread
if ($dns->{$_}->{alarm} &&
($dns->{$_}->{alarm} + $delay) < $then) {
logit(&who ."dns ended for id $_ for $dns->{$_}->{fileno}\n") unless $verbose < 3;
delete $dns->{$_};
last; # only do one per check for efficiancy
}
}
}
}
&close_all;
logit('Exiting...');
closelog();
exit 0;
}
#
# execute a thread based on what the select routine returns
# sort used for testing only
#
sub do_thread { # t => do_thread.t
( run in 0.526 second using v1.01-cache-2.11-cpan-800906f7e73 )