Skip Menu |
 

This queue is for tickets about the IO-Socket-IP CPAN distribution.

Report information
The Basics
Id: 132760
Status: open
Priority: 0/
Queue: IO-Socket-IP

People
Owner: Nobody in particular
Requestors: dom [...] earth.li
Cc: gregoa [...] cpan.org
AdminCc:

Bug Information
Severity: Normal
Broken in: 0.39
Fixed in: (no value)

Attachments
0001-Disable-getaddrinfo-3-AI_ADDRCONFIG-for-localhost-an.patch
0001-Fix-test-failures-with-an-IPv6-only-host.patch



Subject: Test failures with ipv6-only host
Download (untitled) / with headers
text/plain 213b
As seen on the Debian buildd network (see https://bugs.debian.org/962047) many tests fail when run on a machine with only IPv6 networking. The attached patch fixes them by forcing no address lookups to take place.
Subject: 0001-Fix-test-failures-with-an-IPv6-only-host.patch
From c710a8aa2d8f7ee14bb811fd89f34d45fd56e2fe Mon Sep 17 00:00:00 2001 From: Dominic Hargreaves <dom@earth.li> Date: Tue, 2 Jun 2020 20:56:42 +0100 Subject: [PATCH] Fix test failures with an IPv6-only host This can be tested with: # unshare -n # ip li set lo up # ip li add dummy0 type dummy # ip li set dummy0 up Bug-Debian: https://bugs.debian.org/962047 --- t/01local-client-v4.t | 4 +++- t/02local-server-v4.t | 3 ++- t/03local-cross-v4.t | 3 +++ t/11sockopts.t | 6 +++++- t/18fdopen.t | 3 ++- t/20subclass.t | 3 +++ t/21as-inet.t | 3 +++ t/22timeout.t | 3 +++ t/30nonblocking-connect.t | 4 +++- 9 files changed, 27 insertions(+), 5 deletions(-) diff --git a/t/01local-client-v4.t b/t/01local-client-v4.t index 7ab7156..f6aeac4 100644 --- a/t/01local-client-v4.t +++ b/t/01local-client-v4.t @@ -8,7 +8,7 @@ use Test::More; use IO::Socket::IP; use IO::Socket::INET; -use Socket qw( inet_aton inet_ntoa pack_sockaddr_in unpack_sockaddr_in ); +use Socket qw( inet_aton inet_ntoa pack_sockaddr_in unpack_sockaddr_in AI_NUMERICHOST ); # Some odd locations like BSD jails might not like INADDR_LOOPBACK. We'll # establish a baseline first to test against @@ -29,12 +29,14 @@ foreach my $socktype (qw( SOCK_STREAM SOCK_DGRAM )) { LocalHost => "127.0.0.1", Type => Socket->$socktype, Proto => ( $socktype eq "SOCK_STREAM" ? "tcp" : "udp" ), # Because IO::Socket::INET is stupid and always presumes tcp + GetAddrInfoFlags => AI_NUMERICHOST, ) or die "Cannot listen on PF_INET - $@"; my $socket = IO::Socket::IP->new( PeerHost => "127.0.0.1", PeerService => $testserver->sockport, Type => Socket->$socktype, + GetAddrInfoFlags => AI_NUMERICHOST, ); ok( defined $socket, "IO::Socket::IP->new constructs a $socktype socket" ) or diff --git a/t/02local-server-v4.t b/t/02local-server-v4.t index c0d349f..fb711f0 100644 --- a/t/02local-server-v4.t +++ b/t/02local-server-v4.t @@ -8,7 +8,7 @@ use Test::More; use IO::Socket::IP; use IO::Socket::INET; -use Socket qw( inet_aton inet_ntoa pack_sockaddr_in unpack_sockaddr_in ); +use Socket qw( inet_aton inet_ntoa pack_sockaddr_in unpack_sockaddr_in AI_NUMERICHOST ); # Some odd locations like BSD jails might not like INADDR_LOOPBACK. We'll # establish a baseline first to test against @@ -29,6 +29,7 @@ foreach my $socktype (qw( SOCK_STREAM SOCK_DGRAM )) { LocalHost => "127.0.0.1", LocalPort => "0", Type => Socket->$socktype, + GetAddrInfoFlags => AI_NUMERICHOST, ); ok( defined $testserver, "IO::Socket::IP->new constructs a $socktype socket" ) or diff --git a/t/03local-cross-v4.t b/t/03local-cross-v4.t index 8cac72a..3e8174e 100644 --- a/t/03local-cross-v4.t +++ b/t/03local-cross-v4.t @@ -6,6 +6,7 @@ use warnings; use Test::More; use IO::Socket::IP; +use Socket qw(AI_NUMERICHOST); foreach my $socktype (qw( SOCK_STREAM SOCK_DGRAM )) { my $testserver = IO::Socket::IP->new( @@ -13,12 +14,14 @@ foreach my $socktype (qw( SOCK_STREAM SOCK_DGRAM )) { LocalHost => "127.0.0.1", LocalPort => "0", Type => Socket->$socktype, + GetAddrInfoFlags => AI_NUMERICHOST, ) or die "Cannot listen on PF_INET - $@"; my $socket = IO::Socket::IP->new( PeerHost => "127.0.0.1", PeerService => $testserver->sockport, Type => Socket->$socktype, + GetAddrInfoFlags => AI_NUMERICHOST, ) or die "Cannot connect on PF_INET - $@"; my $testclient = ( $socktype eq "SOCK_STREAM" ) ? diff --git a/t/11sockopts.t b/t/11sockopts.t index 5b85092..28daada 100644 --- a/t/11sockopts.t +++ b/t/11sockopts.t @@ -8,7 +8,7 @@ use Test::More; use IO::Socket::IP; use Errno qw( EACCES ); -use Socket qw( SOL_SOCKET SO_REUSEADDR SO_REUSEPORT SO_BROADCAST ); +use Socket qw( SOL_SOCKET SO_REUSEADDR SO_REUSEPORT SO_BROADCAST AI_NUMERICHOST); TODO: { local $TODO = "SO_REUSEADDR doesn't appear to work on cygwin smokers" if $^O eq "cygwin"; @@ -21,6 +21,7 @@ TODO: { Type => SOCK_STREAM, Listen => 1, ReuseAddr => 1, + GetAddrInfoFlags => AI_NUMERICHOST, ) or die "Cannot socket() - $@"; ok( $sock->getsockopt( SOL_SOCKET, SO_REUSEADDR ), 'SO_REUSEADDR set' ); @@ -32,6 +33,7 @@ TODO: { Sockopts => [ [ SOL_SOCKET, SO_REUSEADDR ], ], + GetAddrInfoFlags => AI_NUMERICHOST, ) or die "Cannot socket() - $@"; ok( $sock->getsockopt( SOL_SOCKET, SO_REUSEADDR ), 'SO_REUSEADDR set via Sockopts' ); @@ -50,6 +52,7 @@ SKIP: { Type => SOCK_STREAM, Listen => 1, ReusePort => 1, + GetAddrInfoFlags => AI_NUMERICHOST, ) or die "Cannot socket() - $@"; ok( $sock->getsockopt( SOL_SOCKET, SO_REUSEPORT ), 'SO_REUSEPORT set' ); @@ -62,6 +65,7 @@ SKIP: { LocalHost => "127.0.0.1", Type => SOCK_DGRAM, Broadcast => 1, + GetAddrInfoFlags => AI_NUMERICHOST, ); skip "Privileges required to set broadcast on datagram socket", 1 if !$sock and $! == EACCES; die "Cannot socket() - $@" unless $sock; diff --git a/t/18fdopen.t b/t/18fdopen.t index 20cbe46..6843a2c 100644 --- a/t/18fdopen.t +++ b/t/18fdopen.t @@ -6,12 +6,13 @@ use warnings; use Test::More; use IO::Socket::IP; -use Socket qw( SOCK_STREAM ); +use Socket qw( SOCK_STREAM AI_NUMERICHOST ); my $s1 = IO::Socket::IP->new( LocalHost => "127.0.0.1", Type => SOCK_STREAM, Listen => 1, + GetAddrInfoFlags => AI_NUMERICHOST, ) or die "Cannot listen on AF_INET - $@"; my $s2 = IO::Socket::IP->new; diff --git a/t/20subclass.t b/t/20subclass.t index 231bd52..fbc9cff 100644 --- a/t/20subclass.t +++ b/t/20subclass.t @@ -6,16 +6,19 @@ use warnings; use Test::More; use IO::Socket::IP; +use Socket qw( AI_NUMERICHOST ); my $server = IO::Socket::IP->new( Listen => 1, LocalHost => "127.0.0.1", LocalPort => 0, + GetAddrInfoFlags => AI_NUMERICHOST, ) or die "Cannot listen on PF_INET - $!"; my $client = IO::Socket::IP->new( PeerHost => $server->sockhost, PeerPort => $server->sockport, + GetAddrInfoFlags => AI_NUMERICHOST, ) or die "Cannot connect on PF_INET - $!"; my $accepted = $server->accept( 'MySubclass' ) diff --git a/t/21as-inet.t b/t/21as-inet.t index 2b8713d..fedb8be 100644 --- a/t/21as-inet.t +++ b/t/21as-inet.t @@ -6,16 +6,19 @@ use warnings; use Test::More; use IO::Socket::IP; +use Socket qw( AI_NUMERICHOST ); my $server = IO::Socket::IP->new( Listen => 1, LocalHost => "127.0.0.1", LocalPort => 0, + GetAddrInfoFlags => AI_NUMERICHOST, ) or die "Cannot listen on PF_INET - $!"; my $client = IO::Socket::IP->new( PeerHost => $server->sockhost, PeerPort => $server->sockport, + GetAddrInfoFlags => AI_NUMERICHOST, ) or die "Cannot connect on PF_INET - $!"; my $accepted = $server->accept diff --git a/t/22timeout.t b/t/22timeout.t index a4c28b3..c4a08f5 100644 --- a/t/22timeout.t +++ b/t/22timeout.t @@ -6,17 +6,20 @@ use warnings; use Test::More; use IO::Socket::IP; +use Socket qw( AI_NUMERICHOST ); my $server = IO::Socket::IP->new( Listen => 1, LocalHost => "127.0.0.1", LocalPort => 0, + GetAddrInfoFlags => AI_NUMERICHOST, ) or die "Cannot listen on PF_INET - $!"; my $client = IO::Socket::IP->new( PeerHost => $server->sockhost, PeerPort => $server->sockport, Timeout => 0.1, + GetAddrInfoFlags => AI_NUMERICHOST, ) or die "Cannot connect on PF_INET - $!"; ok( defined $client, 'client constructed with Timeout' ); diff --git a/t/30nonblocking-connect.t b/t/30nonblocking-connect.t index 518bd2e..ade8349 100644 --- a/t/30nonblocking-connect.t +++ b/t/30nonblocking-connect.t @@ -8,7 +8,7 @@ use Test::More; use IO::Socket::IP; use IO::Socket::INET; -use Socket qw( inet_aton inet_ntoa pack_sockaddr_in unpack_sockaddr_in ); +use Socket qw( inet_aton inet_ntoa pack_sockaddr_in unpack_sockaddr_in AI_NUMERICHOST ); use Errno qw( EINPROGRESS EWOULDBLOCK ); # Some odd locations like BSD jails might not like INADDR_LOOPBACK. We'll @@ -27,6 +27,7 @@ my $testserver = IO::Socket::INET->new( Listen => 1, LocalHost => "127.0.0.1", Type => SOCK_STREAM, + GetAddrInfoFlags => AI_NUMERICHOST, ) or die "Cannot listen on PF_INET - $@"; my $socket = IO::Socket::IP->new( @@ -34,6 +35,7 @@ my $socket = IO::Socket::IP->new( PeerService => $testserver->sockport, Type => SOCK_STREAM, Blocking => 0, + GetAddrInfoFlags => AI_NUMERICHOST, ); ok( defined $socket, 'IO::Socket::IP->new( Blocking => 0 ) constructs a socket' ) or -- 2.20.1
Download (untitled) / with headers
text/plain 234b
Niko Tyni did more investigation and tests: https://bugs.debian.org/964902 and came up with a new patch (replacing the one attached here earlier), available in the Debian bug report and also attached for convenience. Cheers, gregor
Subject: 0001-Disable-getaddrinfo-3-AI_ADDRCONFIG-for-localhost-an.patch
From fbed100b2501f9ba1537acd65f160353fc3acd73 Mon Sep 17 00:00:00 2001 From: Niko Tyni <ntyni@debian.org> Date: Sat, 4 Jul 2020 22:17:41 +0100 Subject: [PATCH] Disable getaddrinfo(3) AI_ADDRCONFIG for localhost and IPv4 numeric addresses AI_ADDRCONFIG can be a bad default for systems with a dual protocol loopback device but just IPv6 connectivity. In such a case, getaddrinfo(3) on 127.0.0.1 or 0.0.0.0 will fail with EAI_ADDRFAMILY even though the loopback device is able to handle them. --- lib/IO/Socket/IP.pm | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/lib/IO/Socket/IP.pm b/lib/IO/Socket/IP.pm index 5a5ee7d..2481c63 100755 --- a/lib/IO/Socket/IP.pm +++ b/lib/IO/Socket/IP.pm @@ -30,6 +30,7 @@ use Socket 1.97 qw( ); my $AF_INET6 = eval { Socket::AF_INET6() }; # may not be defined my $AI_ADDRCONFIG = eval { Socket::AI_ADDRCONFIG() } || 0; +my $AI_NUMERICHOST = eval { Socket::AI_NUMERICHOST() } || 0; use POSIX qw( dup2 ); use Errno qw( EINVAL EINPROGRESS EISCONN ENOTCONN ETIMEDOUT EWOULDBLOCK EOPNOTSUPP ); @@ -409,6 +410,8 @@ sub _io_socket_ip__configure my ( $arg ) = @_; my %hints; + my $localflags; + my $peerflags; my @localinfos; my @peerinfos; @@ -420,9 +423,20 @@ sub _io_socket_ip__configure if( defined $arg->{GetAddrInfoFlags} ) { $hints{flags} = $arg->{GetAddrInfoFlags}; + $localflags = $arg->{GetAddrInfoFlags}; + $peerflags = $arg->{GetAddrInfoFlags}; } else { - $hints{flags} = $AI_ADDRCONFIG; + if (defined $arg->{LocalHost} and $arg->{LocalHost} =~ /^\d+\.\d+\.\d+\.\d+$/) { + $localflags = $AI_NUMERICHOST; + } else { + $localflags = $AI_ADDRCONFIG; + } + if (defined $arg->{PeerHost} and $arg->{PeerHost} =~ /^\d+\.\d+\.\d+\.\d+$/) { + $peerflags = $AI_NUMERICHOST; + } elsif (defined $arg->{PeerHost} and $arg->{PeerHost} ne 'localhost') { + $peerflags = $AI_ADDRCONFIG; + } } if( defined( my $family = $arg->{Family} ) ) { @@ -479,6 +493,7 @@ sub _io_socket_ip__configure my $fallback_port = $1; my %localhints = %hints; + $localhints{flags} = $localflags; $localhints{flags} |= AI_PASSIVE; ( my $err, @localinfos ) = getaddrinfo( $host, $service, \%localhints ); @@ -507,10 +522,12 @@ sub _io_socket_ip__configure defined $service and $service =~ s/\((\d+)\)$// and my $fallback_port = $1; - ( my $err, @peerinfos ) = getaddrinfo( $host, $service, \%hints ); + my %peerhints = %hints; + $peerhints{flags} = $peerflags; + ( my $err, @peerinfos ) = getaddrinfo( $host, $service, \%peerhints ); if( $err and defined $fallback_port ) { - ( $err, @peerinfos ) = getaddrinfo( $host, $fallback_port, \%hints ); + ( $err, @peerinfos ) = getaddrinfo( $host, $fallback_port, \%peerhints ); } if( $err ) { @@ -590,6 +607,7 @@ sub _io_socket_ip__configure # If there wasn't, use getaddrinfo()'s AI_ADDRCONFIG side-effect to guess a # suitable family first. else { + $hints{flags} |= $AI_ADDRCONFIG; ( my $err, @infos ) = getaddrinfo( "", "0", \%hints ); if( $err ) { $@ = "$err"; -- 2.26.2
Download (untitled) / with headers
text/plain 441b
As a heads up, there was some discussion on debian-devel about how this is something which should be fixed in libc. This is the Debian bug about the issue from this perspective: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=952740 There doesn't seem any prospect of this being fixed in the near future, so we're planning to apply the last patch gregoa forwarded to IO-Socket-IP in Debian to solve the immediate issues of failing tests.


This service is sponsored and maintained by Best Practical Solutions and runs on Perl.org infrastructure.

Please report any issues with rt.cpan.org to rt-cpan-admin@bestpractical.com.