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/02/27 18:21:53 UTC
svn commit: r1450858 - in /spamassassin/trunk:
lib/Mail/SpamAssassin/Util/DependencyInfo.pm spamd/spamd.raw
Author: mmartinec
Date: Wed Feb 27 17:21:53 2013
New Revision: 1450858
URL: http://svn.apache.org/r1450858
Log:
related to Bug 6841: decouple choosing a Socket vs. Socket6 module from choosing an IO::Socket::{IP,INET6,INET} module, improve compatibility with old versions of these modules
Modified:
spamassassin/trunk/lib/Mail/SpamAssassin/Util/DependencyInfo.pm
spamassassin/trunk/spamd/spamd.raw
Modified: spamassassin/trunk/lib/Mail/SpamAssassin/Util/DependencyInfo.pm
URL: http://svn.apache.org/viewvc/spamassassin/trunk/lib/Mail/SpamAssassin/Util/DependencyInfo.pm?rev=1450858&r1=1450857&r2=1450858&view=diff
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Util/DependencyInfo.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/Util/DependencyInfo.pm Wed Feb 27 17:21:53 2013
@@ -163,7 +163,7 @@ $have_sha ? {
#},
{
module => 'IO::Socket::IP',
- version => 0,
+ version => 0.09,
desc => 'Installing this module is recommended if spamd is to listen
on IPv6 sockets or if DNS queries should go to an IPv6 name server.
If IO::Socket::IP is not available, using an older module
Modified: spamassassin/trunk/spamd/spamd.raw
URL: http://svn.apache.org/viewvc/spamassassin/trunk/spamd/spamd.raw?rev=1450858&r1=1450857&r2=1450858&view=diff
==============================================================================
--- spamassassin/trunk/spamd/spamd.raw (original)
+++ spamassassin/trunk/spamd/spamd.raw Wed Feb 27 17:21:53 2013
@@ -38,24 +38,42 @@ BEGIN {
} # REMOVEFORINST
}
+use vars qw($have_getaddrinfo_in_core $have_getaddrinfo_legacy
+ $io_socket_module_name);
# don't force requirement on IO::Socket::IP or IO::Socket::INET6
-use vars qw($have_socket_ip $io_socket_module_name);
BEGIN {
use Socket qw(:DEFAULT IPPROTO_TCP);
- &SOCK_STREAM; &IPPROTO_TCP;
- $have_socket_ip = eval {
- require IO::Socket::IP;
- Socket->VERSION(1.97);
+ # AUTOLOADing 'constants' here enables inlining - see Exporter man page
+ &SOCK_STREAM; &IPPROTO_TCP; &SOMAXCONN;
+
+ $have_getaddrinfo_in_core = eval {
+ # The Socket module (1.94) bundled with Perl 5.14.* provides
+ # new affordances for IPv6, including implementations of the
+ # Socket::getaddrinfo() and Socket::getnameinfo() functions,
+ # along with related constants and a handful of new functions.
+ # Perl 5.16.0 upgrades the core Socket module to version 2.001.
+ # Socket->VERSION(1.94); # provides getaddrinfo() and getnameinfo()
+ # Socket->VERSION(1.95); # provides AI_ADDRCONFIG
+ Socket->VERSION(1.96); # provides NIx_NOSERV
+ # Socket->VERSION(1.97); # IO::Socket::IP depends on Socket 1.97
import Socket qw(/^(?:AI|NI|NIx|EAI)_/);
- # see Exporter man page: AUTOLOADing 'constants' here enables inlining
- &AI_ADDRCONFIG; &AI_PASSIVE;
+ &AI_ADDRCONFIG; &AI_PASSIVE; # enable inlining
+ &NI_NUMERICHOST, &NI_NUMERICSERV; &NIx_NOSERV; 1;
+ };
+
+ $have_getaddrinfo_legacy = !$have_getaddrinfo_in_core && eval {
+ require Socket6;
+ # Socket6->VERSION(0.13); # provides NI_NAMEREQD
+ Socket6->VERSION(0.18); # provides AI_NUMERICSERV
+ import Socket6 qw(/^(?:AI|NI|NIx|EAI)_/);
+ &AI_ADDRCONFIG; &AI_PASSIVE; # enable inlining
&NI_NUMERICHOST; &NI_NUMERICSERV; &NI_NAMEREQD; 1;
};
- if ($have_socket_ip) {
- $io_socket_module_name = 'IO::Socket::IP';
- *new_io_socket_inetx = sub { IO::Socket::IP->new(@_) };
+ if ($have_getaddrinfo_in_core) {
+ # using a modern Socket module
+
*ip_or_name_to_ip_addresses = sub {
my($addr, $ai_family) = @_;
# Socket::getaddrinfo returns a list of hashrefs
@@ -67,13 +85,15 @@ BEGIN {
if (!$error) {
for my $a (@res) {
my($err, $ip_addr) =
- Socket::getnameinfo($a->{addr}, &NI_NUMERICHOST, &NIx_NOSERV);
+ Socket::getnameinfo($a->{addr},
+ &NI_NUMERICHOST | &NI_NUMERICSERV, &NIx_NOSERV);
if (!$err) { push(@ip_addrs, $ip_addr) }
elsif (!$error) { $error = $err }
}
}
return ($error, @ip_addrs);
};
+
*peer_info_from_socket = sub {
my $sock = shift;
my $peer_addr = $sock->peerhost;
@@ -82,13 +102,10 @@ BEGIN {
$sock->sockport);
};
- } elsif (eval { require Socket6; import Socket6 qw(/^(?:AI|NI|NIx|EAI)_/);
- require IO::Socket::INET6;
- # see Exporter: AUTOLOADing 'constants' here enables inlining
- &AI_ADDRCONFIG; &AI_PASSIVE;
- &NI_NUMERICHOST; &NI_NUMERICSERV; &NI_NAMEREQD; 1 }) {
- $io_socket_module_name = 'IO::Socket::INET6';
- *new_io_socket_inetx = sub { IO::Socket::INET6->new(@_) };
+ } elsif ($have_getaddrinfo_legacy) {
+ # using a legacy Socket6 module; somewhat different API on getaddrinfo()
+ # and getnameinfo() compared to these functions in a module Socket
+
*ip_or_name_to_ip_addresses = sub {
my($addr, $ai_family) = @_;
# Socket6::getaddrinfo returns a list of quintuples
@@ -110,6 +127,7 @@ BEGIN {
}
return ($error, @ip_addrs);
};
+
*peer_info_from_socket = sub {
my $sock = shift;
my $peer_addr = $sock->peerhost;
@@ -120,10 +138,8 @@ BEGIN {
$sock->sockport);
};
- } else { # legacy, IPv4 only, no getaddrinfo() assumed
- $io_socket_module_name = 'IO::Socket::INET';
- require IO::Socket::INET;
- *new_io_socket_inetx = sub { IO::Socket::INET->new(@_) };
+ } else { # IPv4 only, no getaddrinfo() available
+
*ip_or_name_to_ip_addresses = sub {
my($addr, $ai_family) = @_;
$ai_family == &AF_UNSPEC || $ai_family == &AF_INET
@@ -146,6 +162,7 @@ BEGIN {
}
return ($error, @ip_addrs);
};
+
*peer_info_from_socket = sub {
my $sock = shift;
my ($peer_port, $in_addr) = Socket::sockaddr_in($sock->peername)
@@ -155,6 +172,21 @@ BEGIN {
return ($peer_port, $peer_addr, $peer_hostname||$peer_addr,
$sock->sockport);
};
+
+ }
+
+ if (eval { require IO::Socket::IP }) { # handles IPv6 and IPv4
+ IO::Socket::IP->VERSION(0.09); # implements IPV6_V6ONLY
+ $io_socket_module_name = 'IO::Socket::IP';
+ *new_io_socket_inetx = sub { IO::Socket::IP->new(@_) };
+
+ } elsif (eval { require IO::Socket::INET6 }) { # handles IPv6 and IPv4
+ $io_socket_module_name = 'IO::Socket::INET6';
+ *new_io_socket_inetx = sub { IO::Socket::INET6->new(@_) };
+
+ } elsif (eval { require IO::Socket::INET }) { # IPv4 only
+ $io_socket_module_name = 'IO::Socket::INET';
+ *new_io_socket_inetx = sub { IO::Socket::INET->new(@_) };
}
}
@@ -671,7 +703,11 @@ $opt{'server-cert'} ||= "$LOCAL_RULES_DI
# ---------------------------------------------------------------------------
# Server (listening) socket setup for the various supported types
-dbg("spamd: socket module of choice: $io_socket_module_name");
+dbg("spamd: socket module of choice: %s %s, Socket %s, %s",
+ $io_socket_module_name, $io_socket_module_name->VERSION, Socket->VERSION,
+ $have_getaddrinfo_in_core ? 'using a modern Socket::getaddrinfo'
+ : $have_getaddrinfo_legacy ? 'using legacy Socket6::getaddrinfo'
+ : 'no getaddrinfo, using gethostbyname, IPv4-only');
my $have_ssl_module;
my @listen_sockets; # list of hashrefs, contains info on all listen sockets
@@ -862,7 +898,7 @@ sub server_sock_setup_unix {
my %socket = (
Local => $path,
Type => &SOCK_STREAM,
- Listen => SOMAXCONN,
+ Listen => &SOMAXCONN,
);
dbg("spamd: creating UNIX socket:\n" . join("\n", map { " $_: " . (defined $socket{$_} ? $socket{$_} : "(undef)") } sort keys %socket));
my $server_unix = IO::Socket::UNIX->new(%socket);
@@ -958,8 +994,8 @@ sub server_sock_setup_inet {
Type => &SOCK_STREAM,
Proto => 'tcp',
ReuseAddr => 1,
- Listen => SOMAXCONN,
- V6Only => 1,
+ Listen => &SOMAXCONN,
+ V6Only => 1, # since IO::Socket::IP 0.09
);
%sockopt = (%sockopt, (
SSL_version => $sslversion,