# Fix for Gentoo bug 579222 (SpamAssassin bug 7265). # Two different revisions from that bug have been concatenated # together into this patch. --- a/lib/Mail/SpamAssassin/DnsResolver.pm 2015/11/19 15:23:56 1715196 +++ b/lib/Mail/SpamAssassin/DnsResolver.pm 2015/11/19 15:31:49 1715197 @@ -725,6 +725,37 @@ ########################################################################### +=item $id = $res->bgread() + +Similar to C. 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 reply packets ready, and return @@ -772,13 +803,25 @@ $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) { --- a/lib/Mail/SpamAssassin/Plugin/DKIM.pm 2015/11/19 19:20:06 1715247 +++ b/lib/Mail/SpamAssassin/Plugin/DKIM.pm 2015/11/19 19:22:25 1715248 @@ -793,7 +793,8 @@ # 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); } }