--- sa-orig/lib/Mail/SpamAssassin/Dns.pm 2010/03/24 00:41:05 926883 +++ lib/Mail/SpamAssassin/Dns.pm 2010/03/30 01:29:47 928958 @@ -189,7 +189,7 @@ $log =~ s/(?<![<([])(https?:\/\/\S+)/<$1>/g; } elsif ($question->string =~ m/^(\d+)\.(\d+)\.(\d+)\.(\d+)\.(\S+\w)/) { - $log = "$4.$3.$2.$1 listed in $5"; + $log = "$4.$3.$2.$1 listed in ".lc($5); } } @@ -652,17 +652,14 @@ $self->clear_resolver(); goto done unless $self->load_resolver(); - my @nameservers = $self->{resolver}->nameservers(); - - # optionally shuffle the list of nameservers to distribute the load - if ($self->{conf}->{dns_options}->{rotate}) { - Mail::SpamAssassin::Util::fisher_yates_shuffle(\@nameservers); - dbg("dns: shuffled NS list: ".join(", ", @nameservers)); - $self->{resolver}->nameservers(@nameservers); - $self->{resolver}->connect_sock(); - } - if ($dnsopt eq "yes") { + # optionally shuffle the list of nameservers to distribute the load + if ($self->{conf}->{dns_options}->{rotate}) { + my @nameservers = $self->{resolver}->available_nameservers(); + Mail::SpamAssassin::Util::fisher_yates_shuffle(\@nameservers); + dbg("dns: shuffled NS list: " . join(", ", @nameservers)); + $self->{resolver}->available_nameservers(@nameservers); + } $IS_DNS_AVAILABLE = 1; dbg("dns: dns_available set to yes in config file, skipping test"); return $IS_DNS_AVAILABLE; @@ -678,49 +675,48 @@ @domains = @EXISTING_DOMAINS; } - # Net::DNS::Resolver scans a list of nameservers when it does a foreground - # query but only uses the first in a background query like we use. - # Try the different nameservers here in case the first one is not working - - my @good_nameservers = (); - dbg("dns: testing resolver nameservers: " . join(", ", @nameservers)); - my $ns; - while( $ns = shift(@nameservers)) { - for(my $retry = 3; $retry > 0 and $#domains>-1; $retry--) { + # do the test with a full set of configured nameservers + my @nameservers = $self->{resolver}->configured_nameservers(); + + # optionally shuffle the list of nameservers to distribute the load + if ($self->{conf}->{dns_options}->{rotate}) { + Mail::SpamAssassin::Util::fisher_yates_shuffle(\@nameservers); + dbg("dns: shuffled NS list, testing: " . join(", ", @nameservers)); + } else { + dbg("dns: testing resolver nameservers: " . join(", ", @nameservers)); + } + + # Try the different nameservers here and collect a list of working servers + my @good_nameservers; + foreach my $ns (@nameservers) { + $self->{resolver}->available_nameservers($ns); # try just this one + for (my $retry = 3; $retry > 0 && @domains; $retry--) { my $domain = splice(@domains, rand(@domains), 1); - dbg("dns: trying ($retry) $domain..."); + dbg("dns: trying ($retry) $domain, server $ns ..."); my $result = $self->lookup_ns($domain); - if(defined $result) { - if (scalar @$result > 0) { - dbg("dns: NS lookup of $domain using $ns succeeded => DNS available". - " (set dns_available to override)"); - $IS_DNS_AVAILABLE = 1; - push(@good_nameservers, $ns); - last; - } - else { - dbg("dns: NS lookup of $domain using $ns failed, no results found"); - next; - } - } - else { + $self->{resolver}->finish_socket(); + if (!$result) { dbg("dns: NS lookup of $domain using $ns failed horribly, ". "may not be a valid nameserver"); - $IS_DNS_AVAILABLE = 0; # should already be 0, but let's be sure. - last; + last; + } elsif (!@$result) { + dbg("dns: NS lookup of $domain using $ns failed, no results found"); + } else { + dbg("dns: NS lookup of $domain using $ns succeeded => DNS available". + " (set dns_available to override)"); + push(@good_nameservers, $ns); + last; } } - $self->{resolver}->nameservers(@nameservers); - $self->{resolver}->connect_sock(); # reconnect socket to new nameserver } - if ($IS_DNS_AVAILABLE == 1) - { - dbg("dns: NS list: ".join(", ", @good_nameservers)); - $self->{resolver}->nameservers(@good_nameservers); - $self->{resolver}->connect_sock(); + if (!@good_nameservers) { + dbg("dns: all NS queries failed => DNS unavailable ". + "(set dns_available to override)"); } else { - dbg("dns: all NS queries failed => DNS unavailable (set dns_available to override)"); + $IS_DNS_AVAILABLE = 1; + dbg("dns: NS list: ".join(", ", @good_nameservers)); + $self->{resolver}->available_nameservers(@good_nameservers); } done: @@ -754,7 +750,7 @@ dbg("dns: entering helper-app run mode"); $self->{old_slash} = $/; # Razor pollutes this %{$self->{old_env}} = (); - if ( defined %ENV ) { + if ( %ENV ) { # undefined values in %ENV can result due to autovivification elsewhere, # this prevents later possible warnings when we restore %ENV while (my ($key, $value) = each %ENV) {