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 06:49:07 UTC

svn commit: r161157 - in spamassassin/trunk/lib/Mail/SpamAssassin: Dns.pm Plugin/URIDNSBL.pm

Author: jm
Date: Tue Apr 12 21:49:06 2005
New Revision: 161157

URL: http://svn.apache.org/viewcvs?view=rev&rev=161157
Log:
bug 3997: second half of fix ;)   check the ID values of response packets to make sure they match the appropriate query, before we use the data in a response.

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

Modified: spamassassin/trunk/lib/Mail/SpamAssassin/Dns.pm
URL: http://svn.apache.org/viewcvs/spamassassin/trunk/lib/Mail/SpamAssassin/Dns.pm?view=diff&r1=161156&r2=161157
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Dns.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/Dns.pm Tue Apr 12 21:49:06 2005
@@ -98,6 +98,7 @@
 use constant BGSOCK => 0;
 use constant RULES => 1;
 use constant SETS => 2;
+use constant ID => 3;
 
 # TODO: $server is currently unused
 sub do_rbl_lookup {
@@ -109,6 +110,8 @@
     $self->{rbl_launch} = time;
     $self->{dnspending}->{$type}->{$host}->[BGSOCK] =
         $self->res_bgsend($host, $type);
+    $self->{dnspending}->{$type}->{$host}->[ID] =
+        $self->{last_id};
   }
 
   # always add set
@@ -138,14 +141,17 @@
     $self->{rbl_launch} = time;
     $self->{dnspending}->{$type}->{$host}->[BGSOCK] =
         $self->res_bgsend($host, $type);
+    $self->{dnspending}->{$type}->{$host}->[ID] =
+        $self->{last_id};
   }
   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));
+  my $pkt = Mail::SpamAssassin::Util::new_dns_packet($host, $type);
+  $self->{last_id} = $pkt->header()->id();
+  return $self->{res}->bgsend($pkt);
 }
 
 ###########################################################################
@@ -184,16 +190,23 @@
   }
 }
 
+# returns 1 on successful packet processing
 sub process_dnsbl_result {
   my ($self, $query) = @_;
 
   my $packet = $self->{res}->bgread($query->[BGSOCK]);
-  undef $query->[BGSOCK];
   return unless (defined $packet &&
 		 defined $packet->header &&
 		 defined $packet->question &&
 		 defined $packet->answer);
 
+  my $respid = $packet->header->id;
+  if ($respid != $query->[ID]) {    # bug 3997
+    warn "dns: received out-of-order response packet: id=$respid want=".
+            $query->[ID].": ".$packet->string;
+    return;     # keep waiting
+  }
+
   my $question = ($packet->question)[0];
   return if !defined $question;
 
@@ -226,6 +239,7 @@
       }
     }
   }
+  return 1;
 }
 
 sub process_dnsbl_set {
@@ -306,12 +320,14 @@
     while (@waiting) {
       @left = ();
       for my $query (@waiting) {
-        if ($self->{res}->bgisready($query->[BGSOCK])) {
-          $self->process_dnsbl_result($query);
-        }
-        else {
-          push(@left, $query);
+        if ($self->{res}->bgisready($query->[BGSOCK]) &&
+                    $self->process_dnsbl_result($query))
+        {
+          # ok, the response was useful; close the socket
+          undef $query->[BGSOCK];
+          next;
         }
+        push(@left, $query);
       }
 
       $self->{main}->call_plugins ("check_tick", { permsgstatus => $self });

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=161156&r2=161157
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/URIDNSBL.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/URIDNSBL.pm Tue Apr 12 21:49:06 2005
@@ -521,14 +521,14 @@
   # dig $dom ns
   my $ent = $self->start_lookup ($scanstate, 'NS', $self->res_bgsend($dom, 'NS'));
   $ent->{obj} = $obj;
+  $ent->{dns_id} = $self->{last_id};
   $scanstate->{pending_lookups}->{$key} = $ent;
 }
 
 sub complete_ns_lookup {
   my ($self, $scanstate, $ent, $dom) = @_;
 
-  my $packet = $self->{res}->bgread($ent->{sock});
-  $self->close_ent_socket ($ent);
+  my $packet = $ent->{response_packet};
   my @answer = $packet->answer;
 
   my $IPV4_ADDRESS = IPV4_ADDRESS;
@@ -567,14 +567,14 @@
   # dig $hname a
   my $ent = $self->start_lookup ($scanstate, 'A', $self->res_bgsend($hname, 'A'));
   $ent->{obj} = $obj;
+  $ent->{dns_id} = $self->{last_id};
   $scanstate->{pending_lookups}->{$key} = $ent;
 }
 
 sub complete_a_lookup {
   my ($self, $scanstate, $ent, $hname) = @_;
 
-  my $packet = $self->{res}->bgread($ent->{sock});
-  $self->close_ent_socket ($ent);
+  my $packet = $ent->{response_packet};
   my @answer = $packet->answer;
 
   foreach my $rr (@answer) {
@@ -614,6 +614,7 @@
   my $ent = $self->start_lookup ($scanstate, 'DNSBL',
         $self->res_bgsend($item, $qtype));
   $ent->{obj} = $obj;
+  $ent->{dns_id} = $self->{last_id};
   $ent->{rulename} = $rulename;
   $ent->{zone} = $dnsbl;
   $scanstate->{pending_lookups}->{$key} = $ent;
@@ -628,9 +629,9 @@
   my $rulename = $ent->{rulename};
   my $rulecf = $conf->{uridnsbls}->{$rulename};
 
-  my $packet = $self->{res}->bgread($ent->{sock});
-  $self->close_ent_socket ($ent);
+  my $packet = $ent->{response_packet};
   my @answer = $packet->answer;
+
   my $uridnsbl_subs = $conf->{uridnsbl_subs}->{$ent->{zone}};
   my $uridnsbl_subs_bits = 0;
   $uridnsbl_subs_bits |= $_ for keys %{$uridnsbl_subs};
@@ -733,7 +734,10 @@
     my $type = $ent->{type};
     $key =~ /:(\S+)$/; my $val = $1;
 
-    if (!$self->{res}->bgisready ($ent->{sock})) {
+    my $packet;
+    if (!$self->{res}->bgisready ($ent->{sock})
+            || !$self->validate_response_packet($ent))
+    {
       $typecount{$type}++;
       #$stillwaiting = 1;
       next;
@@ -799,6 +803,27 @@
   return (!$stillwaiting);
 }
 
+sub validate_response_packet {
+  my ($self, $ent) = @_;
+
+  my $packet = $self->{res}->bgread($ent->{sock});
+  return unless (defined $packet &&
+                 defined $packet->header &&
+                 defined $packet->question &&
+                 defined $packet->answer);
+
+  my $respid = $packet->header->id;
+  if ($respid != $ent->{dns_id}) {    # bug 3997
+    warn "dns: received out-of-order response packet: id=$respid want=".
+            $ent->{dns_id}.": ".$packet->string;
+    return;     # keep waiting
+  }
+
+  $ent->{response_packet} = $packet;
+  $self->close_ent_socket ($ent);
+  return 1;
+}
+
 # ---------------------------------------------------------------------------
 
 sub abort_remaining_lookups  {
@@ -829,9 +854,10 @@
 # ---------------------------------------------------------------------------
 
 sub res_bgsend {
-  my ($self, $name, $type) = @_;
-  return $self->{res}->bgsend (
-    Mail::SpamAssassin::Util::new_dns_packet($name, $type));
+  my ($self, $host, $type) = @_;
+  my $pkt = Mail::SpamAssassin::Util::new_dns_packet($host, $type);
+  $self->{last_id} = $pkt->header()->id();
+  return $self->{res}->bgsend($pkt);
 }
 
 sub log_dns_result {