Package: libio-socket-ip-perl Version: 0.39-2 Severity: serious Tags: patch ipv6
This is a follow-up for #962047 "fails to build on IPv6-only buildds". The background here is that a while ago new official build daemons were added that only have IPv6 connectivity, and this exposed a new class of build failures, mainly due to getaddrinfo(3) behaviour with the AI_ADDRCONFIG flag. Quoting Julien Cristau there: > FWIW, it seems IO::Socket::IP passes AI_ADDRCONFIG to getaddrinfo, which > then doesn't return ipv4 addresses because the host doesn't have > non-local ones, even though the address we're trying to resolve is > "127.0.0.1". > > Passing either GetAddrInfoFlags => AI_NUMERICHOST or GetAddrInfoFlags => > 0 to both IO::Socket::IP->new calls in the test file lets it pass, by > turning off the smarts in getaddrinfo. We fixed the test suite of libio-socket-ip-perl itself in 0.39-2 by making it pass AI_NUMERICHOST in all the tests. However, it turns out that the problem is much more widespread than this. I've been testing systematically for these issues by test rebuilding the whole archive, and found 1) 138 packages that failed to build on a host with an IPv6 address on a "real" interface, and IPv4 + IPv6 on lo, but no internet connection 2) 8 of those 138 also failed to build on a host with both an IPv6 address and an IPv4 address on a "real interface", still without a real internet connection (these are regular "needs internet" bugs, not IPv6 specific) 3) only 42 of the remaining 130 packages fail to build with the same setup as 1), after applying the patch discussed below to IO::Socket::IP. So it looks like the AI_ADDRCONFIG default of IO-Socket-IP is causing 88 potential build failures on the new IPv6-only buildds. Examples of those can be seen on for instance https://buildd.debian.org/status/logs.php?pkg=libmojolicious-perl https://buildd.debian.org/status/logs.php?pkg=libtest-redisserver-perl https://buildd.debian.org/status/logs.php?pkg=libwww-mechanize-perl The attached patch changes IO-Socket-IP to pass AI_NUMERICHOST to getaddrinfo(3) when the address looks like an IPv4 numeric address (rather than a hostname), and special cases a PeerHost value of "localhost" not to use AI_ADDRCONFIG. I have tried quite a few variants, and this was the best I could do without removing AI_ADDRCONFIG (which is a documented feature) altogether. (TODO: The patch does not currently update the documentation about the new behaviour.) It would be good to get something like this upstream of course, and it will also need to go in src:perl which has a copy of IO::Socket::IP. I've tested that this makes libio-socket-perl pass its own test suite without the modifications in 0.39-2, so this supersedes the current test suite patch. Build logs can currently (but not guaranteed indefinitely) be found at http://perl.debian.net/rebuild-logs/sid-v6only/ http://perl.debian.net/rebuild-logs/experimental-v6only/ where the latter had a patched libio-socket-ip-perl package pre-installed in the chroot. Below is the list of packages detected as fixed by this. I'll bring up the other IPv6-related build failures on the debian-devel list soonish. Bugs have already been filed for the handful of "needs internet" issues. alice_0.19-2 boxbackup_0.13~~git20200326.g8e8b63c-1 gdnsd_2.4.2-1 kgb-bot_1.56-1 libanyevent-connection-perl_0.06-5 libanyevent-connector-perl_0.03-2 libanyevent-memcached-perl_0.08-1 libanyevent-redis-perl_0.24-2 libapache2-authcookie-perl_3.30-1 libapache2-reload-perl_0.13-3 libapache-authenhook-perl_2.00-04+pristine-7 libapache-singleton-perl_0.17-1 libapache-ssllookup-perl_2.00-04-3 libapp-termcast-perl_0.13-3 libaudio-mpd-perl_2.004-2 libcgi-application-plugin-captcha-perl_0.04-2 libcgi-application-server-perl_0.063-2 libcorona-perl_0.1004-4 libcpan-mini-inject-perl_0.35-1 libcrypt-ssleay-perl_0.73.06-1 libdancer-perl_1.3513+dfsg-1 libdanga-socket-perl_1.62-1 libfcgi-engine-perl_0.22-1 libfurl-perl_3.13-2 libgearman-client-perl_2.004.015-1 libhtml-html5-parser-perl_0.301-2 libhttp-async-perl_0.33-1 libhttp-daemon-ssl-perl_1.05-01-2 libhttp-server-simple-mason-perl_0.14-2 libio-socket-ssl-perl_2.067-1 libio-socket-timeout-perl_0.32-1 libjson-validator-perl_3.25+dfsg-1 liblwp-protocol-https-perl_6.07-2 libmime-tools-perl_5.509-1 libmojolicious-perl_8.56+dfsg-1 libmojolicious-plugin-assetpack-perl_2.08-2 libmojolicious-plugin-authentication-perl_1.33-1 libmojolicious-plugin-authorization-perl_1.0302-2 libmojolicious-plugin-basicauth-perl_0.08-1 libmojolicious-plugin-bcrypt-perl_0.14-2 libmojolicious-plugin-cgi-perl_0.40-1 libmojolicious-plugin-i18n-perl_1.60-1 libmojolicious-plugin-mailexception-perl_0.20-1 libmojolicious-plugin-renderfile-perl_0.12-4 libmojo-sqlite-perl_3.003-1 libmonitoring-livestatus-perl_0.80-1 libnanomsg-raw-perl_0.10-1 libnet-facebook-oauth2-perl_0.12-1 libnet-http-perl_6.19-1 libnet-https-nb-perl_0.15-1 libnet-ldap-server-test-perl_0.22-1 libnet-server-mail-perl_0.28-1 libnet-server-perl_2.009-2 libnet-sip-perl_0.822-1 libperlio-via-timeout-perl_0.32-1 libplack-app-proxy-perl_0.29-1 libplack-handler-anyevent-fcgi-perl_0.01-1 libplack-handler-fcgi-ev-perl_0.01-1 libplack-middleware-deflater-perl_0.12-2 libplack-middleware-session-perl_0.33-1 libplack-perl_1.0047-2 libplack-test-agent-perl_1.4-2 libplack-test-externalserver-perl_0.02-1 libpod-webserver-perl_3.11-1 libproc-guard-perl_0.07-1 libprotocol-http2-perl_1.10-1 libredis-fast-perl_0.26+dfsg-2 libredis-perl_1.9950-1 librest-client-perl_273-1 librpc-xml-perl_0.80-2 librt-client-rest-perl_0.60-1 libtest-fake-httpd-perl_0.08-1 libtest-http-server-simple-stashwarnings-perl_0.04-2 libtest-redisserver-perl_0.21-2 libtest-tcp-perl_2.22-1 libtest-www-declare-perl_0.02-4 libtest-www-mechanize-mojo-perl_0.0.20-1 libtest-www-mechanize-perl_1.52-1 libweb-id-perl_1.927-2 libweb-machine-perl_0.17-1 libwiki-toolkit-plugin-ping-perl_0.03-2 mod-gnutls_0.9.0-1.1 perlbal_1.80-3 pinto_0.14000-1 request-tracker4_4.4.4-1 starlet_0.31-1 starman_0.4015-1 twiggy_0.1025+dfsg-1 -- Niko Tyni nt...@debian.org
>From fbed100b2501f9ba1537acd65f160353fc3acd73 Mon Sep 17 00:00:00 2001 From: Niko Tyni <nt...@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