Net-DNSBL-MultiDaemon
view release on metacpan or search on metacpan
MultiDaemon.pm view on Meta::CPAN
$comment = 'format error 2';
# if CLASS
} elsif (!($eXT && exists $eXT->{CLASS} && $eXT->{CLASS}->($eXT,$get,$put,$id,$opcode,\$name,\$type,\$class)) &&
$class != C_IN) { # class must be C_IN
s_response(\$msg,REFUSED,$id,$qdcount,$ancount,$nscount,$arcount);
$comment = 'refused';
# if NAME
} elsif (($eXT && exists $eXT->{NAME} && $eXT->{NAME}->($eXT,$get,$put,$id,$opcode,\$name,\$type,\$class)) ||
$name !~ /$BLzone$/i) { # question must be for this zone
s_response(\$msg,NXDOMAIN,$id,1,0,0,0);
$comment = 'not this zone';
} else {
# THIS IS OUR ZONE request, generate a thread to handle it
print STDERR $name,' ',TypeTxt->{$type},' ' if $DEBUG & $D_VERBOSE;
# if TYPE
if ($eXT && exists $eXT->{TYPE} && (my $rv = $eXT->{TYPE}->($eXT,$get,$put,$id,$opcode,\$name,\$type,\$class))) {
$msg = $rv;
$comment = 'Extension type';
} elsif ( $type == T_A ||
$type == T_ANY ||
$type == T_TXT) {
if (( $notRHBL &&
$name =~ /^((\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3}))\.(.+)/ &&
($rip = $1) &&
($targetIP = "$5.$4.$3.$2") &&
($zone = $6) &&
$BLzone eq lc $zone) ||
# check for valid RFC1034 domain name, but allow digits in the first character
(!$notRHBL && # check RHBL zones
###### CHANGE this REGEXP to alter permissible domain name patterns
$name =~ /^([a-zA-Z0-9][a-zA-Z0-9\.\-]+[a-zA-Z0-9])\.$BLzone$/ && # valid domain name
($rip = $1) &&
($targetIP = '' || 1) &&
($zone = $BLzone))) {
my $expires;
# if CACHE
if ($eXT && exists $eXT->{CACHE} && (my $rv = $eXT->{CACHE}->($eXT,$get,$put,$id,$opcode,$rip,\$name,\$type,\$class,$ubl))) {
$msg = $rv;
}
# if local white/black lists
elsif (!$notRHBL && $ubl && # right side checking and local white/black lists
do {
if ($ubl->urblwhite($rip)) {
not_found($put,$name,$type,$id,\$msg,$SOAptr);
$rv = 'whitelisted';
}
elsif ($ubl->urblblack($rip)) {
($msg) = _ansrbak($put,$id,1,$rip,$zone,$type,3600,A1272,$BLzone,$myip,'blacklisted');
$rv = 'blacklisted';
}
}
) {
$comment = $rv;
}
elsif ($rip eq '2.0.0.127') { # checkfor DNSBL test
($msg) = _ansrbak($put,$id,1,$rip,$zone,$type,3600,A1272,$BLzone,$myip,'DNSBL test response to 127.0.0.2');
$comment = 'just testing';
}
### NOTE, $now does not get updated very often if the host is busy processing in this routine, but at least every 5 minutes.... good enough
elsif ( $csize && # cacheing enabled
exists $cache{$rip} && # item exists in cache
($expires = $cache{$rip}->{expires}) > $now ) { # cache not expired
$cache{$rip}->{used} = $now; # update last used time
my $blist_0 = $cache{$rip}->{who};
my $txt = $cache{$rip}->{txt};
$txt = $txt ? $txt . $targetIP : '';
($msg) = _ansrbak($put,$id,1,$rip,$zone,$type,$expires - $now,A1272,$BLzone,$myip,$txt); # send cached record
$comment = 'cache record';
bump_stats($STATs,$blist_0);
}
elsif ($type == T_TXT) { # none of the rest of static stuff has TXT records
not_found($put,$name,$type,$id,\$msg,$SOAptr);
$comment = 'no TXT';
}
elsif ($notRHBL && @NAignore && matchNetAddr($targetIP,\@NAignore)) { # check for IP's to always pass
not_found($put,$name,$type,$id,\$msg,$SOAptr); # return unconditional NOT FOUND
$STATs->{WhiteList} += 1; # bump WhiteList count
$comment = 'IGNORE';
}
elsif ($notRHBL && @NAblock && matchNetAddr($targetIP,\@NAblock)) { # check for IP's to always block
($msg) = _ansrbak($put,$id,1,$rip,$zone,$type,3600,A1275,$BLzone,$myip); # answer 127.0.0.5
$STATs->{BlackList} += 1; # bump BlackList count
$comment = 'BLOCK';
}
elsif ($notRHBL && $BBC && # check for IP's to block by country
($cc = $BBC->country_code_by_addr($targetIP)) &&
(grep($cc eq $_,@{$DNSBL->{BBC}}))) {
($msg) = _ansrbak($put,$id,1,$rip,$zone,$type,3600,A1276,$BLzone,$myip); # answer 127.0.0.6
$STATs->{$cc} += 1; # bump statistics count
$newstat = 1 unless $newstat; # notify refresh that update may be needed
$comment = "block $cc";
}
else {
#test here for GENERIC
@blist = ();
foreach(sort { by_average($STATs,$a,$b) } keys %$STATs) {
next unless $_ =~ /\./; # drop passed,white,black,bbc entries
push @blist, $_;
}
push @blist, 'genericPTR' if $regexptr;
# add bread crumbs for Extensions if necessary
$rid = undef; # trial remote ID
if ($eXT && exists $eXT->{LOOKUP}) {
$rid = uniqueID();
$rid = $eXT->{LOOKUP}->($eXT,$get,$put,$rid,$id,$opcode,\$name,\$type,\$class,\%remoteThreads);
}
$rid = setURBLdom($rip,$rid,$notRHBL,$ubl,$DNSBL->{$blist[0]},\%remoteThreads,0); # initialize urbl domain lookup name
bl_lookup($put,\$msg,\%remoteThreads,$l_Sin,_alarm($blist[0]),$rid,$id,$rip,$type,$zone,@blist);
send($R,$msg,0,$R_Sin); # udp may not block
print STDERR $blist[0] if $DEBUG & $D_VERBOSE;
last;
}
}
elsif ($BLzone eq lc $name && $type != T_TXT) {
my $noff = newhead(\$msg,
$id,
BITS_QUERY | QR,
1,1,1,0,
);
MultiDaemon.pm view on Meta::CPAN
$Oname,$Otype,$Oclass,$Ottl,$Odata);
} elsif ($Otype == T_AAAA) {
($noff,@dnptrs) = $put->AAAA(\$nmsg,$noff,\@dnptrs,
$Oname,$Otype,$Oclass,$Ottl,$Odata);
} else {
next; # skip unknown authority types
}
}
} # end FATans
# if ANSWER
if ($eXT && exists $eXT->{ANSWER} && $eXT->{ANSWER}->($eXT,$get,$put,$rid,$ttl,\$nmsg,\%remoteThreads)) {
; # will update $nmsg
}
delete $remoteThreads{$rid};
$msg = $nmsg;
$ROK = 0 if $DEBUG & $D_ANSTOP;
}
# no answer
elsif (do {
print STDERR '+' if $DEBUG & $D_VERBOSE;
#print Tmp "While eliminate $rid $blist[0]\n";
my $rv = 0;
while(!$rv) {
shift @blist;
unless (@blist) {
$rv = 1;
} else {
last unless $deadDNSBL{"$blist[0]"} > $numberoftries; # ignore hosts that don't answer
}
}
$rv;
}) { # if no more hosts
# if NOTFOUND
not_found($put,$rip .'.'. $zone,$type,$id,\$msg,$SOAptr) # send not found response
unless $eXT && exists $eXT->{NOTFOUND} && $eXT->{NOTFOUND}->($eXT,$get,$put,$rid,$rip,\$type,\$zone,\$msg,\%remoteThreads);
delete $remoteThreads{$rid};
# endif
$STATs->{Passed} += 1;
$newstat = 1 unless $newstat; # notify refresh that update may be needed
} else {
$deadDNSBL{"$blist[0]"} = 1; # reset retry count
#print Tmp "NOTFOUND bl_lookup, R \n";
$rid = setURBLdom($rip,$rid,$notRHBL,$ubl,$DNSBL->{$blist[0]},\%remoteThreads,1); # initialize urbl domain lookup name
bl_lookup($put,\$msg,\%remoteThreads,$l_Sin,_alarm($blist[0]),$rid,$id,$rip,$type,$zone,@blist);
print STDERR $blist[0] if $DEBUG & $D_VERBOSE;
send($R,$msg,0,$R_Sin); # udp may not block
last;
}
send($L,$msg,0,$l_Sin);
if ($DEBUG & $D_VERBOSE) {
if ($answer) {
print STDERR ' ',inet_ntoa($answer),"\n";
} else {
print STDERR " no bl\n";
}
}
last;
}
}
##################### TIMEOUT, do busywork #######################
else { # must be timeout
my $prpshadow = $prp;
$now = time; # check various alarm status
unless ($now < $next) {
average($STATs);
purge_cache() if $prp < 0; # initiate cache purge every 5 minutes or so
}
purge_cache() unless $prpshadow < 0; # run cache purge thread unless just initiated
foreach $rid (keys %remoteThreads) {
next unless $remoteThreads{$rid}->{expire} < $now; # expired??
($l_Sin,$rip,$id,$type,$zone,@blist) = @{$remoteThreads{$rid}->{args}};
if (++$deadDNSBL{"$blist[0]"} > $numberoftries) {
$deadDNSBL{"$blist[0]"} = 3600; # wait an hour to retry
if ($LogLevel) {
syslog($LogLevel, "timeout connecting to $blist[0]\n");
}
}
if ($blist[0] eq 'in-addr.arpa') { # expired reverse DNS lookup ?
delete $remoteThreads{$rid};
$deadDNSBL{"$blist[0]"} = 0; # reset timeout (this one never expires)
my $txt = exists $DNSBL->{$blist[0]}
? $DNSBL->{$blist[0]}->{error}
: '';
$cache{$rip} = {
expires => $now + 3600, # always an hour
used => $now,
who => $blist[0],
txt => $txt
};
bump_stats($STATs,$blist[0]);
# $STATs->{"$blist[0]"} += 1; # bump statistics count
# if (exists $CNTs{"$blist[0]"}) {
# $CNTs{"$blist[0]"} += 1;
# } else {
# $CNTs{"$blist[0]"} = 1;
# $AVGs{"$blist[0]"} = 1;
# }
# $newstat = 1 unless $newstat; # notify refresh that update may be needed
($msg) = _ansrbak($put,$id,1,$rip,$zone,$type,3600,A1274,$BLzone,$myip,$txt);
send($L,$msg,0,$l_Sin);
print STDERR " expired Rdns\n" if $DEBUG & $D_VERBOSE;
}
elsif (do {
print STDERR '?' if $DEBUG & $D_VERBOSE;
my $rv = 0;
while(!$rv) {
shift @blist;
unless (@blist) {
$rv = 1;
} else {
last unless $deadDNSBL{"$blist[0]"} > $numberoftries; # ignore hosts that don't answer
}
}
$rv;
}) { # if no more hosts
# if NOTFOUND
not_found($put,$rip .'.'. $BLzone,$type,$id,\$msg,$SOAptr) # send not found response
( run in 0.937 second using v1.01-cache-2.11-cpan-39bf76dae61 )