https://bz.apache.org/SpamAssassin/show_bug.cgi?id=7265 diff -Naurp Mail-SpamAssassin-3.4.1/lib/Mail/SpamAssassin/DnsResolver.pm Mail-SpamAssassin-3.4.1.oden/lib/Mail/SpamAssassin/DnsResolver.pm --- Mail-SpamAssassin-3.4.1/lib/Mail/SpamAssassin/DnsResolver.pm 2015-04-28 21:56:49.000000000 +0200 +++ Mail-SpamAssassin-3.4.1.oden/lib/Mail/SpamAssassin/DnsResolver.pm 2015-12-27 15:36:52.519554065 +0100 @@ -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) { diff -Naurp Mail-SpamAssassin-3.4.1/lib/Mail/SpamAssassin/Plugin/DKIM.pm Mail-SpamAssassin-3.4.1.oden/lib/Mail/SpamAssassin/Plugin/DKIM.pm --- Mail-SpamAssassin-3.4.1/lib/Mail/SpamAssassin/Plugin/DKIM.pm 2015-04-28 21:56:47.000000000 +0200 +++ Mail-SpamAssassin-3.4.1.oden/lib/Mail/SpamAssassin/Plugin/DKIM.pm 2015-12-27 15:39:33.501345612 +0100 @@ -786,7 +786,8 @@ sub _check_dkim_signature { # Only do so if EDNS0 provides a reasonably-sized UDP payload size, # as our interface does not provide a DNS fallback to TCP, unlike # the Net::DNS::Resolver::send which does provide it. - my $res = $self->{main}->{resolver}->get_resolver; + my $res = $self->{main}->{resolver}; + dbg("dkim: providing our own resolver: %s", ref $res); Mail::DKIM::DNS::resolver($res); } }