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/28 16:20:10 UTC
svn commit: r1451230 - /spamassassin/trunk/spamd/spamd.raw
Author: mmartinec
Date: Thu Feb 28 15:20:09 2013
New Revision: 1451230
URL: http://svn.apache.org/r1451230
Log:
related to Bug 6841: testing for PF_INET and PF_INET6 availability in spamd allows automatic choice of default protocol families for listen sockets (like on an IPv6-only host); documentation details; more informative debugging
Modified:
spamassassin/trunk/spamd/spamd.raw
Modified: spamassassin/trunk/spamd/spamd.raw
URL: http://svn.apache.org/viewvc/spamassassin/trunk/spamd/spamd.raw?rev=1451230&r1=1451229&r2=1451230&view=diff
==============================================================================
--- spamassassin/trunk/spamd/spamd.raw (original)
+++ spamassassin/trunk/spamd/spamd.raw Thu Feb 28 15:20:09 2013
@@ -39,7 +39,7 @@ BEGIN {
}
use vars qw($have_getaddrinfo_in_core $have_getaddrinfo_legacy
- $io_socket_module_name);
+ $io_socket_module_name $have_inet4 $have_inet6);
# don't force requirement on IO::Socket::IP or IO::Socket::INET6
BEGIN {
use Socket qw(:DEFAULT IPPROTO_TCP);
@@ -71,6 +71,8 @@ BEGIN {
&NI_NUMERICHOST; &NI_NUMERICSERV; &NI_NAMEREQD; 1;
};
+ &AF_UNSPEC; &AF_INET; &AF_INET6; # enable inlining
+
if ($have_getaddrinfo_in_core) {
# using a modern Socket module
@@ -189,6 +191,24 @@ BEGIN {
*new_io_socket_inetx = sub { IO::Socket::INET->new(@_) };
}
+ $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 = # 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;
+ };
+
}
use IO::Handle;
@@ -703,11 +723,17 @@ $opt{'server-cert'} ||= "$LOCAL_RULES_DI
# ---------------------------------------------------------------------------
# Server (listening) socket setup for the various supported types
-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'
+dbg("spamd: socket module of choice: %s %s, Socket %s".
+ ", %s PF_INET, %s PF_INET6, %s",
+ $io_socket_module_name,
+ $io_socket_module_name->VERSION,
+ Socket->VERSION,
+ $have_inet4 ? 'have' : 'no',
+ $have_inet6 ? 'have' : 'no',
+ $have_getaddrinfo_in_core ? 'using Socket::getaddrinfo'
: $have_getaddrinfo_legacy ? 'using legacy Socket6::getaddrinfo'
- : 'no getaddrinfo, using gethostbyname, IPv4-only');
+ : 'no getaddrinfo, using gethostbyname, IPv4-only',
+);
my $have_ssl_module;
my @listen_sockets; # list of hashrefs, contains info on all listen sockets
@@ -961,11 +987,16 @@ sub server_sock_setup_unix {
sub server_sock_setup_inet {
my($socket_specs, $addr, $port, $ssl) = @_;
- my $ai_family = &AF_UNSPEC;
- if ($opt{'force_ipv6'} && !$opt{'force_ipv4'}) { $ai_family = &AF_INET6 }
- elsif ($opt{'force_ipv4'} && !$opt{'force_ipv6'}) { $ai_family = &AF_INET }
- elsif (!$ssl && $io_socket_module_name eq 'IO::Socket::INET')
- { $ai_family = &AF_INET }
+ $have_inet4 || $have_inet6
+ or warn "spamd: neither the PF_INET (IPv4) nor the PF_INET6 (IPv6) ".
+ "protocol families seem to be available, pushing our luck anyway\n";
+
+ my $ai_family = &AF_UNSPEC; # defaults to any address family (i.e. both)
+ if ($have_inet6 && (!$have_inet4 || $opt{'force_ipv6'})) {
+ $ai_family = &AF_INET6;
+ } elsif ($have_inet4 && (!$have_inet6 || $opt{'force_ipv4'})) {
+ $ai_family = &AF_INET;
+ }
my($error, @addresses);
if (!defined $addr || lc $addr eq 'localhost') { # loopback interface
push(@addresses, '127.0.0.1')
@@ -982,7 +1013,7 @@ sub server_sock_setup_inet {
}
die "spamd: invalid address for a listen socket: \"$socket_specs\": $error\n"
if $error;
- die "spamd: invalid address for a listen socket: \"$socket_specs\"\n"
+ die "spamd: no valid address for a listen socket: \"$socket_specs\"\n"
if !@addresses;
dbg("spamd: attempting to listen on IP addresses: %s, port %d",
@@ -1009,7 +1040,8 @@ sub server_sock_setup_inet {
sort keys %sockopt)));
if ($ssl && !$have_ssl_module) {
eval { require IO::Socket::SSL }
- or die "spamd: SSL encryption requested, but IO::Socket::SSL is unavailable ($@)\n";
+ or die "spamd: SSL encryption requested, ".
+ "but IO::Socket::SSL is unavailable ($@)\n";
$have_ssl_module = 1;
}
my $server_inet = $ssl ? IO::Socket::SSL->new(%sockopt)
@@ -3072,7 +3104,9 @@ to 783. Option --ssl implies a prefix '
enclosed in square brackets, e.g. [::1]:783, an IPv4 address may be but
need not be enclosed in square brackets. An asterisk '*' in place of a
hostname implies an unspecified address, ('0.0.0.0' or '::'), i.e. it
-binds to all interfaces. An empty option value implies '*'.
+binds to all interfaces. An empty option value implies '*'. A default
+is '--listen localhost', which binds to a loopback interface only.
+
=head1 DESCRIPTION
@@ -3155,17 +3189,17 @@ Print version information, then exit wit
=item B<-i> [I<ipaddress>[:<port>]], B<--listen>[=I<ipaddress>[:<port>]]
Additional alias names for this option are --listen-ip and --ip-address.
-Tells spamd to listen on the specified IP address (defaults to a loopback
-address). If no value is specified after the switch, or an asterisk '*'
-stands in place of <ipaddress>, spamd will listen on all interfaces - this
-is equivalent to address '0.0.0.0' for IPv4 and to '::' for IPv6.
-You can also use a valid hostname which will make spamd listen on all
-addresses that a name resolves to. The option may be specified multiple
-times. See also options -4 and -6 for restricting address family to IPv4
-or to IPv6. If a port is specified it overrides the --port (and --ssl-port)
-setting for this socket. An IPv6 addresses should be enclosed in square
-brackets, e.g. [::1]:783. For compatibility the square brackets on an IPv6
-address may be omitted if a port number specification is also omitted.
+Tells spamd to listen on the specified IP address, defaults to a loopback
+interface, i.e. C<--listen localhost>). If no value is specified after the
+switch, or if an asterisk '*' stands in place of an <ipaddress>, spamd will
+listen on all interfaces - this is equivalent to address '0.0.0.0' for IPv4
+and to '::' for IPv6. You can also use a valid hostname which will make spamd
+listen on all addresses that a name resolves to. The option may be specified
+multiple times. See also options -4 and -6 for restricting address family
+to IPv4 or to IPv6. If a port is specified it overrides for this socket the
+global --port (and --ssl-port) setting. An IPv6 addresses should be enclosed
+in square brackets, e.g. [::1]:783. For compatibility square brackets on an
+IPv6 address may be omitted if a port number specification is also omitted.
=item B<-p> I<port>, B<--port>=I<port>