You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spamassassin.apache.org by jm...@apache.org on 2005/04/13 05:03:01 UTC

svn commit: r161148 - in spamassassin/trunk: lib/Mail/SpamAssassin.pm lib/Mail/SpamAssassin/Dns.pm lib/Mail/SpamAssassin/Plugin/URIDNSBL.pm lib/Mail/SpamAssassin/Util.pm spamd/spamd.raw

Author: jm
Date: Tue Apr 12 20:02:59 2005
New Revision: 161148

URL: http://svn.apache.org/viewcvs?view=rev&rev=161148
Log:
bug 3997: possible solution to the DNS answers getting mixed up bug, by using our own ID counter for DNS packets to avoid it getting reused between search() and bgsend().

Modified:
    spamassassin/trunk/lib/Mail/SpamAssassin.pm
    spamassassin/trunk/lib/Mail/SpamAssassin/Dns.pm
    spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/URIDNSBL.pm
    spamassassin/trunk/lib/Mail/SpamAssassin/Util.pm
    spamassassin/trunk/spamd/spamd.raw

Modified: spamassassin/trunk/lib/Mail/SpamAssassin.pm
URL: http://svn.apache.org/viewcvs/spamassassin/trunk/lib/Mail/SpamAssassin.pm?view=diff&r1=161147&r2=161148
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin.pm Tue Apr 12 20:02:59 2005
@@ -1291,10 +1291,11 @@
 
   # Allow init() to be called multiple times, but only run once.
   if (defined $self->{_initted}) {
-    # If the PID changes, reseed the PRNG
+    # If the PID changes, reseed the PRNG and the DNS ID counter
     if ($self->{_initted} != $$) {
       $self->{_initted} = $$;
       srand;
+      Mail::SpamAssassin::Util::init_dns_counter_from_pid();
     }
     return;
   }

Modified: spamassassin/trunk/lib/Mail/SpamAssassin/Dns.pm
URL: http://svn.apache.org/viewcvs/spamassassin/trunk/lib/Mail/SpamAssassin/Dns.pm?view=diff&r1=161147&r2=161148
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Dns.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/Dns.pm Tue Apr 12 20:02:59 2005
@@ -108,7 +108,7 @@
     dbg("dns: launching DNS $type query for $host in background");
     $self->{rbl_launch} = time;
     $self->{dnspending}->{$type}->{$host}->[BGSOCK] =
-	$self->{res}->bgsend($host, $type);
+        $self->res_bgsend($host, $type);
   }
 
   # always add set
@@ -137,9 +137,15 @@
     dbg("dns: launching DNS $type query for $host in background");
     $self->{rbl_launch} = time;
     $self->{dnspending}->{$type}->{$host}->[BGSOCK] =
-	$self->{res}->bgsend($host, $type);
+        $self->res_bgsend($host, $type);
   }
   push @{$self->{dnspending}->{$type}->{$host}->[RULES]}, $rule;
+}
+
+sub res_bgsend {
+  my ($self, $host, $type) = @_;
+  return $self->{res}->bgsend(
+            Mail::SpamAssassin::Util::new_dns_packet($host, $type));
 }
 
 ###########################################################################

Modified: spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/URIDNSBL.pm
URL: http://svn.apache.org/viewcvs/spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/URIDNSBL.pm?view=diff&r1=161147&r2=161148
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/URIDNSBL.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/URIDNSBL.pm Tue Apr 12 20:02:59 2005
@@ -519,7 +519,7 @@
   return if $scanstate->{pending_lookups}->{$key};
 
   # dig $dom ns
-  my $ent = $self->start_lookup ($scanstate, 'NS', $self->{res}->bgsend ($dom, 'NS'));
+  my $ent = $self->start_lookup ($scanstate, 'NS', $self->res_bgsend($dom, 'NS'));
   $ent->{obj} = $obj;
   $scanstate->{pending_lookups}->{$key} = $ent;
 }
@@ -565,7 +565,7 @@
   return if $scanstate->{pending_lookups}->{$key};
 
   # dig $hname a
-  my $ent = $self->start_lookup ($scanstate, 'A', $self->{res}->bgsend ($hname, 'A'));
+  my $ent = $self->start_lookup ($scanstate, 'A', $self->res_bgsend($hname, 'A'));
   $ent->{obj} = $obj;
   $scanstate->{pending_lookups}->{$key} = $ent;
 }
@@ -612,7 +612,7 @@
 
   # dig $ip txt
   my $ent = $self->start_lookup ($scanstate, 'DNSBL',
-				$self->{res}->bgsend ($item, $qtype));
+        $self->res_bgsend($item, $qtype));
   $ent->{obj} = $obj;
   $ent->{rulename} = $rulename;
   $ent->{zone} = $dnsbl;
@@ -827,6 +827,12 @@
 }
 
 # ---------------------------------------------------------------------------
+
+sub res_bgsend {
+  my ($self, $name, $type) = @_;
+  return $self->{res}->bgsend (
+    Mail::SpamAssassin::Util::new_dns_packet($name, $type));
+}
 
 sub log_dns_result {
   #my $self = shift;

Modified: spamassassin/trunk/lib/Mail/SpamAssassin/Util.pm
URL: http://svn.apache.org/viewcvs/spamassassin/trunk/lib/Mail/SpamAssassin/Util.pm?view=diff&r1=161147&r2=161148
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Util.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/Util.pm Tue Apr 12 20:02:59 2005
@@ -53,6 +53,18 @@
 use constant HAS_MIME_BASE64 => eval { require MIME::Base64; };
 use constant RUNNING_ON_WINDOWS => ($^O =~ /^(?:mswin|dos|os2)/oi);
 
+# a counter value to use for DNS ID numbers in new_dns_packet().
+# range: 0x0000 - 0xffff
+our $DNS_ID_COUNTER;
+
+sub init_dns_id_counter_from_pid {
+  $DNS_ID_COUNTER = (($$ >> 10) | (($$ << 6) & 0xffff));
+}
+
+BEGIN {
+  init_dns_id_counter_from_pid();    # always init at startup
+}
+
 ###########################################################################
 
 # find an executable in the current $PATH (or whatever for that platform)
@@ -1236,6 +1248,48 @@
     # may be using "safe" signals with %SIG; use POSIX to avoid it
     POSIX::sigaction POSIX::SIGALRM(), new POSIX::SigAction $handler;
   }
+}
+
+###########################################################################
+
+=item $packet = new_dns_packet ($host, $type, $class)
+
+A wrapper for C<Net::DNS::Packet::new()> which ensures that the
+packet's ID field uses a new, unique value for this process.
+This is to avoid SpamAssassin bug 3997.
+
+To use this, change calls to C<Net::DNS::Resolver::bgsend> from:
+
+    $res->bgsend($hostname, $type);
+
+to:
+
+    $res->bgsend(Mail::SpamAssassin::Util::new_dns_packet($hostname, $type));
+
+=cut
+
+sub new_dns_packet {
+  my ($host, $type, $class) = @_;
+
+  # increment our counter, and ensure it stays in range
+  $DNS_ID_COUNTER = (($DNS_ID_COUNTER+1) & 0xffff);
+
+  my $packet;
+  eval {
+    $packet = Net::DNS::Packet->new($host, $type, $class);
+    # set the ID on the packet to avoid bug 3997
+    $packet->header()->id($DNS_ID_COUNTER);
+
+    # a bit noisy, so commented by default...
+    # dbg("util: new DNS packet h=$host t=$type id=$DNS_ID_COUNTER");
+  };
+
+  if ($@) {
+    # this can happen if Net::DNS isn't available -- but in this 
+    # case this function should never be called!
+    warn "cannot create Net::DNS::Packet, but new_dns_packet() was called: $@ $!";
+  }
+  return $packet;
 }
 
 ###########################################################################

Modified: spamassassin/trunk/spamd/spamd.raw
URL: http://svn.apache.org/viewcvs/spamassassin/trunk/spamd/spamd.raw?view=diff&r1=161147&r2=161148
==============================================================================
--- spamassassin/trunk/spamd/spamd.raw (original)
+++ spamassassin/trunk/spamd/spamd.raw Tue Apr 12 20:02:59 2005
@@ -2116,12 +2116,16 @@
 sub child_handler {
   my ($sig) = @_;
 
-  if (defined($sig) && !$main::INHIBIT_LOGGING_IN_SIGCHLD_HANDLER) {
-    logmsg("server hit by SIG$sig");
-  }
+  # do NOT call syslog here unless the child's pid is in our list of known
+  # children.  This is due to syslog-ng brokenness -- bugs 3625, 4237.
 
   # clean up any children which have exited
   while((my $pid = waitpid(-1, WNOHANG)) > 0) {
+    if (!defined $children{$pid}) {
+      # ignore this child; we didn't realise we'd forked it. bug 4237
+      next;
+    }
+
     # remove them from our child listing
     delete $children{$pid};
 
@@ -2133,7 +2137,8 @@
     }
 
     unless ($main::INHIBIT_LOGGING_IN_SIGCHLD_HANDLER) {
-      logmsg("handled cleanup of child pid $pid");
+      logmsg("handled cleanup of child pid $pid ".
+                (defined $sig) ? "due to SIG$sig" : "");
     }
   }