$OpenBSD: patch-lib_Mail_SpamAssassin_DnsResolver_pm,v 1.4 2016/03/04 00:05:35 sthen Exp $
--- lib/Mail/SpamAssassin/DnsResolver.pm.orig	Tue Apr 28 20:56:49 2015
+++ lib/Mail/SpamAssassin/DnsResolver.pm	Thu Mar  3 23:59:55 2016
@@ -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->header->rd(1);
+
   # my $udp_payload_size = $self->{res}->udppacketsize;
     my $udp_payload_size = $self->{conf}->{dns_options}->{edns};
     if ($udp_payload_size && $udp_payload_size > 512) {
@@ -722,6 +725,37 @@ sub bgsend {
 
 ###########################################################################
 
+=item $id = $res->bgread()
+
+Similar to C<Net::DNS::Resolver::bgread>.  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->{sock};
+  my $packetsize = $self->{res}->udppacketsize;
+  $packetsize = 512  if $packetsize < 512;  # just in case
+  my $data = '';
+  my $peeraddr = $sock->recv($data, $packetsize+256);  # with some size margin for troubleshooting
+  defined $peeraddr or die "bgread: recv() failed: $!";
+  my $peerhost = $sock->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->new(\$data);
+  $answerpkt or die "bgread: decoding DNS packet failed: $@";
+  $answerpkt->answerfrom($peerhost);
+  if ($decoded_length ne 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->poll_responses()
 
 See if there are any C<bgsend> reply packets ready, and return
@@ -769,13 +803,25 @@ sub poll_responses {
     $timeout = 0;  # next time around collect whatever is available, then exit
     last  if $nfound == 0;
 
-    my $packet = $self->{res}->bgread($self->{sock});
+    my $packet;
+    eval {
+      $packet = $self->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);
+    };
 
+#   Bug 7265, use our own bgread()
+#   my $packet = $self->{res}->bgread($self->{sock});
+
     if (!$packet) {
-      my $dns_err = $self->{res}->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->{res}->errorstring;
+#     die "dns (3) $dns_err\n"  if $dns_err =~ /__alarm__ignore__\(.*\)/s;
+#     info("dns: bad dns reply: $dns_err");
     } else {
       my $header = $packet->header;
       if (!$header) {
