You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spamassassin.apache.org by mm...@apache.org on 2013/04/24 21:22:31 UTC
svn commit: r1471605 - /spamassassin/trunk/sa-update.raw
Author: mmartinec
Date: Wed Apr 24 19:22:30 2013
New Revision: 1471605
URL: http://svn.apache.org/r1471605
Log:
sa-update: use the same decision logic as in spamd for choosing IO::Socket::IP vs
IO::Socket::INET6, prefer the former for consistency, let the underlying module
pick the right address family instead of forcing it through local_address();
added some debugging and cosmetics
Modified:
spamassassin/trunk/sa-update.raw
Modified: spamassassin/trunk/sa-update.raw
URL: http://svn.apache.org/viewvc/spamassassin/trunk/sa-update.raw?rev=1471605&r1=1471604&r2=1471605&view=diff
==============================================================================
--- spamassassin/trunk/sa-update.raw (original)
+++ spamassassin/trunk/sa-update.raw Wed Apr 24 19:22:30 2013
@@ -87,7 +87,7 @@ use HTTP::Date qw(time2str);
use Archive::Tar 1.23;
use IO::Zlib 1.04;
-use vars qw($have_lwp $have_inet4 $have_inet6);
+use vars qw($have_lwp $io_socket_module_name $have_inet4 $have_inet6);
BEGIN {
# Deal with optional modules
@@ -99,19 +99,33 @@ BEGIN {
require LWP::UserAgent;
};
- $have_inet4 = eval {
- require IO::Socket::INET;
- my $sock = IO::Socket::INET->new(LocalAddr => '0.0.0.0', Proto => 'udp');
- $sock->close or die "error closing inet socket: $!" if $sock;
- $sock ? 1 : undef;
- };
+ if (eval { require IO::Socket::IP }) { # handles IPv6 and IPv4
+ $io_socket_module_name = 'IO::Socket::IP';
+
+ } elsif (eval { require IO::Socket::INET6 }) { # handles IPv6 and IPv4
+ $io_socket_module_name = 'IO::Socket::INET6';
+
+ } elsif (eval { require IO::Socket::INET }) { # IPv4 only
+ $io_socket_module_name = 'IO::Socket::INET';
+ }
+
+ $have_inet4 = # can we create a PF_INET socket?
+ defined $io_socket_module_name && eval {
+ my $sock =
+ $io_socket_module_name->new(LocalAddr => '0.0.0.0', Proto => 'tcp');
+ $sock->close or die "error closing socket: $!" if $sock;
+ $sock ? 1 : undef;
+ };
- $have_inet6 = eval {
- require IO::Socket::INET6;
- my $sock = IO::Socket::INET6->new(LocalAddr => '::', Proto => 'udp');
- $sock->close or die "error closing inet6 socket: $!" if $sock;
- $sock ? 1 : undef;
- };
+ $have_inet6 = # can we create a PF_INET6 socket?
+ defined $io_socket_module_name &&
+ $io_socket_module_name ne 'IO::Socket::INET' &&
+ eval {
+ my $sock =
+ $io_socket_module_name->new(LocalAddr => '::', Proto => 'tcp');
+ $sock->close or die "error closing socket: $!" if $sock;
+ $sock ? 1 : undef;
+ };
}
# These should already be available
@@ -124,6 +138,8 @@ use Mail::SpamAssassin::Util qw(untaint_
*dbg=\&Mail::SpamAssassin::dbg;
sub dbg;
+$| = 1; # autoflushing STDOUT makes verbose output consistent with warnings
+
# Clean up PATH appropriately
Mail::SpamAssassin::Util::clean_path_in_taint_mode();
@@ -620,10 +636,10 @@ foreach my $channel (@channels) {
}
foreach my $mirror (@mirrors) {
my $result_fname;
- ($mirby, $result_fname) =
- http_get($mirror, $UPDDir, $mirby_path);
+ ($mirby, $result_fname) = http_get($mirror, $UPDDir, $mirby_path);
unless ($mirby) {
- dbg("channel: no mirror data available for channel $channel from $mirror");
+ dbg("channel: no mirror data available for channel %s from %s",
+ $channel, $mirror);
next;
}
last;
@@ -636,11 +652,11 @@ foreach my $channel (@channels) {
$mirby_just_downloaded = 1;
$preserve_files{$mirby_path} = 1;
- dbg("channel: MIRRORED.BY file retrieved");
+ dbg("channel: MIRRORED.BY file for channel %s retrieved", $channel);
}
# Parse the list of mirrors
- dbg("channel: parsing MIRRORED.BY file");
+ dbg("channel: parsing MIRRORED.BY file for channel %s", $channel);
my %mirrors;
my @mirrors = split(/^/, $mirby);
while(my $mirror = shift @mirrors) {
@@ -1289,30 +1305,45 @@ sub do_dns_query {
##############################################################################
sub init_lwp {
- if ($have_inet6 && (!$opt{'force_pf'} || $opt{'force_pf'} eq 'inet6')) {
- # LWP module has no support yet for IPv6.
- # Use hotpatching, copying IO::Socket::INET6 to IO::Socket::INET.
+ if ($have_inet6 &&
+ (!$opt{'force_pf'} || $opt{'force_pf'} eq 'inet6') &&
+ ($io_socket_module_name eq 'IO::Socket::IP' ||
+ $io_socket_module_name eq 'IO::Socket::INET6') )
+ {
+ # LWP module has no support for IPv6. Use hotpatching,
+ # copying IO::Socket::IP or IO::Socket::INET6 to IO::Socket::INET.
# 'Borrowed' from Net::INET6Glue::INET_is_INET6 :
- $INC{'IO/Socket/INET.pm'} = $INC{'IO/Socket/INET6.pm'};
+
+ printf("http: (lwp) hotpatching IO::Socket::INET by module %s\n",
+ $io_socket_module_name) if $opt{'verbose'};
+ my $io_socket_module_hash_name = $io_socket_module_name . '::';
+ my $io_socket_module_path = $io_socket_module_name . '.pm';
+ $io_socket_module_path =~ s{::}{/}g;
+ $INC{'IO/Socket/INET.pm'} = $INC{$io_socket_module_path};
no strict 'refs';
no warnings 'redefine';
- for ( keys %{IO::Socket::INET6::} ) {
- ref(my $v = $IO::Socket::INET6::{$_}) and next;
+ for ( keys %{$io_socket_module_hash_name} ) {
+ ref(my $v = $io_socket_module_hash_name->{$_}) and next;
*{ 'IO::Socket::INET::'.$_ } =
- \&{ 'IO::Socket::INET6::'.$_ } if *{$v}{CODE};
+ \&{ $io_socket_module_hash_name . $_ } if *{$v}{CODE};
}
}
my $ua = LWP::UserAgent->new();
$ua->agent("sa-update/$VERSION/$SAVersion");
$ua->timeout(60); # a good long timeout; 10 is too short for Coral!
$ua->env_proxy;
- if ($opt{'force_pf'}) {
- if ($have_inet4 && $opt{'force_pf'} eq 'inet') {
- $ua->local_address('0.0.0.0');
- } elsif ($have_inet6 && $opt{'force_pf'} eq 'inet6') {
- $ua->local_address('::');
- }
- }
+
+# if ($opt{'force_pf'}) {
+# # No longer needed and can be harmful as we don't know which address family
+# # will be picked by the IO::Socket::* module in case of multihomed servers.
+# # The IO::Socket::IP should choose the right protocol family automatically.
+# if ($have_inet4 && $opt{'force_pf'} eq 'inet') {
+# $ua->local_address('0.0.0.0');
+# } elsif ($have_inet6 && $opt{'force_pf'} eq 'inet6') {
+# $ua->local_address('::');
+# }
+# }
+
return $ua;
}
@@ -1402,7 +1433,9 @@ sub http_get {
my $out_fname_short = $out_fname;
$out_fname_short =~ s{^\Q$dir\E/*}{};
+ printf("fetching %s\n", $url) if $opt{'verbose'} && $opt{'verbose'} > 1;
dbg("http: url: %s", $url);
+
my $out_fname_exists = -e $out_fname;
dbg("http: downloading to: %s, %s", $out_fname,
!$out_fname_exists ? 'new' : $force_reload ? 'replace' : 'update');
@@ -1439,12 +1472,18 @@ sub http_get {
or die "Cannot create a file $out_fname: $!";
binmode($out_fh) or die "Can't set binmode on $out_fname: $!";
$content = http_get_lwp($url, $ims, $dir);
- $out_fh->print($content) or die "Error writing to $out_fname: $!";
+ if (!defined $content) {
+ dbg("http: (lwp) no content downloaded from %s", $url);
+ } else {
+ $out_fh->print($content) or die "Error writing to $out_fname: $!";
+ }
$out_fh->close or die "Error closing file $out_fname: $!";
return ($content, $out_fname);
} else {
die "http: no downloading tool available";
}
+
+ # only reached if invoking an external program is needed (not lwp)
if ($opt{'force_pf'}) {
if ($opt{'force_pf'} eq 'inet') { push(@args, '-4') }
elsif ($opt{'force_pf'} eq 'inet6') { push(@args, '-6') }