<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">--- lib/Mail/SpamAssassin/DnsResolver.pm.ORG	2018-01-28 14:58:47.274812647 +0100
+++ lib/Mail/SpamAssassin/DnsResolver.pm	2018-01-28 14:57:17.426780200 +0100
@@ -37,7 +37,7 @@ package Mail::SpamAssassin::DnsResolver;
 
 use strict;
 use warnings;
-use bytes;
+# use bytes;
 use re 'taint';
 
 require 5.008001;  # needs utf8::is_utf8()
@@ -581,7 +581,7 @@ sub new_dns_packet {
     #    time, $domain, $type, $packet-&gt;id);
     1;
   } or do {
-    # this can if a domain name in a query is invalid, or if a timeout signal
+    # get here if a domain name in a query is invalid, or if a timeout signal
     # happened to be trapped by this eval, or if Net::DNS signalled an error
     my $eval_stat = $@ ne '' ? $@ : "errno=$!";  chomp $eval_stat;
     # resignal if alarm went off
@@ -592,6 +592,9 @@ sub new_dns_packet {
   };
 
   if ($packet) {
+    # RD flag needs to be set explicitly since Net::DNS 1.01, Bug 7223	
+    $packet-&gt;header-&gt;rd(1);
+
   # my $udp_payload_size = $self-&gt;{res}-&gt;udppacketsize;
     my $udp_payload_size = $self-&gt;{conf}-&gt;{dns_options}-&gt;{edns};
     if ($udp_payload_size &amp;&amp; $udp_payload_size &gt; 512) {
@@ -722,6 +725,37 @@ sub bgsend {
 
 ###########################################################################
 
+=item $id = $res-&gt;bgread()
+
+Similar to C&lt;Net::DNS::Resolver::bgread&gt;.  Reads a DNS packet from
+a supplied socket, decodes it, and returns a Net::DNS::Packet object
+if successful.  Dies on error.
+
+=cut
+
+sub bgread() {
+  my ($self) = @_;
+  my $sock = $self-&gt;{sock};
+  my $packetsize = $self-&gt;{res}-&gt;udppacketsize;
+  $packetsize = 512  if $packetsize &lt; 512;  # just in case
+  my $data = '';
+  my $peeraddr = $sock-&gt;recv($data, $packetsize+256);  # with some size margin for troubleshooting
+  defined $peeraddr or die "bgread: recv() failed: $!";
+  my $peerhost = $sock-&gt;peerhost;
+  $data ne '' or die "bgread: received empty packet from $peerhost";
+  dbg("dns: bgread: received %d bytes from %s", length($data), $peerhost);
+  my($answerpkt, $decoded_length) = Net::DNS::Packet-&gt;new(\$data);
+  $answerpkt or die "bgread: decoding DNS packet failed: $@";
+  $answerpkt-&gt;answerfrom($peerhost);
+  if (defined $decoded_length &amp;&amp; $decoded_length ne "" &amp;&amp; $decoded_length != length($data)) {
+    warn sprintf("bgread: received a %d bytes packet from %s, decoded %d bytes\n",
+                 length($data), $peerhost, $decoded_length);
+  }
+  return $answerpkt;
+}
+
+###########################################################################
+
 =item $nfound = $res-&gt;poll_responses()
 
 See if there are any C&lt;bgsend&gt; reply packets ready, and return
@@ -769,13 +803,24 @@ sub poll_responses {
     $timeout = 0;  # next time around collect whatever is available, then exit
     last  if $nfound == 0;
 
-    my $packet = $self-&gt;{res}-&gt;bgread($self-&gt;{sock});
+    my $packet;
+    # Bug 7265, use our own bgread() below
+    # $packet = $self-&gt;{res}-&gt;bgread($self-&gt;{sock});
+    eval {
+      $packet = $self-&gt;bgread();  # Bug 7265, use our own bgread()
+    } or do {
+      undef $packet;
+      my $eval_stat = $@ ne '' ? $@ : "errno=$!";  chomp $eval_stat;
+      # resignal if alarm went off
+      die $eval_stat  if $eval_stat =~ /__alarm__ignore__\(.*\)/s;
+      info("dns: bad dns reply: %s", $eval_stat);
+    };
 
     if (!$packet) {
-      my $dns_err = $self-&gt;{res}-&gt;errorstring;
-      # resignal if alarm went off
-      die "dns (3) $dns_err\n"  if $dns_err =~ /__alarm__ignore__\(.*\)/s;
-      info("dns: bad dns reply: $dns_err");
+      # error already reported above
+#     my $dns_err = $self-&gt;{res}-&gt;errorstring;
+#     die "dns (3) $dns_err\n"  if $dns_err =~ /__alarm__ignore__\(.*\)/s;
+#     info("dns: bad dns reply: $dns_err");
     } else {
       my $header = $packet-&gt;header;
       if (!$header) {
@@ -861,7 +906,8 @@ Emulates C&lt;Net::DNS::Resolver::send()&gt;.
 This subroutine is a simple synchronous leftover from SpamAssassin version
 3.3 and does not participate in packet query caching and callback grouping
 as implemented by AsyncLoop::bgsend_and_start_lookup().  As such it should
-be avoided for mainstream usage.
+be avoided for mainstream usage.  Currently used through Mail::SPF::Server
+by the SPF plugin.
 
 =cut
 
</pre></body></html>