Skip Menu |

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

Report information
The Basics
Id: 92295
Status: resolved
Priority: 0/
Queue: IO-Socket-IP

People
Owner: Nobody in particular
Requestors: tom [...] eborcom.com
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: 0.26
Fixed in: 0.27



Subject: IPv6 Test Failure in FreeBSD jails
Hi, Paul. Thank you for your work on this useful module. I look forward to seeing IPv6 support in Perl 5.20. Several tests compensate for the IPv4 loopback address containing something other than 127.0.0.1, as happens in a FreeBSD jail. However, none of the IPv6 tests compensate for the IPv6 loopback containing something other than ::1. Consequently, I see the following test failures in a FreeBSD jail with IPv6 enabled: t/04local-client-v6.t (Wstat: 1280 Tests: 23 Failed: 5) Failed tests: 8, 10-11, 20, 22 Non-zero exit status: 5 t/05local-server-v6.t (Wstat: 1280 Tests: 29 Failed: 5) Failed tests: 4, 14-15, 19, 29 Non-zero exit status: 5 These tests all fail as follows: # got: '2a021658000100000000000001230001' # expected: '00000000000000000000000000000001' Where the "got" value represents the jail's IPv6 address of 2a02:1658:1::123:1. Please let me know if you need any more information or if you have a patch you would like me to try. Regards, Tom Hukins
On Mon Jan 20 10:17:59 2014, TOMHUKINS wrote: Show quoted text
> Consequently, I see the following test failures in a FreeBSD jail with > IPv6 enabled: > > t/04local-client-v6.t (Wstat: 1280 Tests: 23 Failed: 5) > Failed tests: 8, 10-11, 20, 22 > Non-zero exit status: 5 > t/05local-server-v6.t (Wstat: 1280 Tests: 29 Failed: 5) > Failed tests: 4, 14-15, 19, 29 > Non-zero exit status: 5 > > These tests all fail as follows: > > # got: '2a021658000100000000000001230001' > # expected: '00000000000000000000000000000001' > > Where the "got" value represents the jail's IPv6 address of > 2a02:1658:1::123:1.
Meh. This is all pretty horrible. The 'v4 cases work by having IO::Socket::INET as an "independent witness" to verify what a bind to 127.0.0.1 actually comes back as. There's nothing else suitable here to rely on other than IO::Socket::IP itself. * I could copy the logic and run it again but at that point it would basically be testing IO::Socket::IP against itself. * I could recreate a basic test using low-level socket(), bind() and getsockaddr() calls correctly * I could delete the comparising test entirely I'm not sure really which one is best... they all seem awkward -- Paul Evans
On Mon Jan 20 11:02:15 2014, PEVANS wrote: Show quoted text
> * I could recreate a basic test using low-level socket(), bind() and > getsockaddr() calls correctly
On further thought this seems the only reasonable option. Find patch attached. -- Paul Evans
Subject: rt92295.patch
=== modified file 't/01local-client-v4.t' --- t/01local-client-v4.t 2013-09-19 13:15:34 +0000 +++ t/01local-client-v4.t 2014-01-20 16:07:50 +0000 @@ -8,13 +8,14 @@ use IO::Socket::IP; use IO::Socket::INET; -use Socket qw( inet_ntoa unpack_sockaddr_in ); +use Socket qw( inet_aton inet_ntoa pack_sockaddr_in unpack_sockaddr_in ); # Some odd locations like BSD jails might not like INADDR_LOOPBACK. We'll # establish a baseline first to test against my $INADDR_LOOPBACK = do { - my $localsock = IO::Socket::INET->new( LocalAddr => "localhost", Listen => 1 ); - $localsock->sockaddr; + socket my $sockh, PF_INET, SOCK_STREAM, 0 or die "Cannot socket(PF_INET) - $!"; + bind $sockh, pack_sockaddr_in( 0, inet_aton( "127.0.0.1" ) ) or die "Cannot bind() - $!"; + ( unpack_sockaddr_in( getsockname $sockh ) )[1]; }; my $INADDR_LOOPBACK_HOST = inet_ntoa( $INADDR_LOOPBACK ); if( $INADDR_LOOPBACK ne INADDR_LOOPBACK ) { === modified file 't/02local-server-v4.t' --- t/02local-server-v4.t 2013-09-19 13:15:34 +0000 +++ t/02local-server-v4.t 2014-01-20 16:07:53 +0000 @@ -8,13 +8,14 @@ use IO::Socket::IP; use IO::Socket::INET; -use Socket qw( inet_ntoa unpack_sockaddr_in ); +use Socket qw( inet_aton inet_ntoa pack_sockaddr_in unpack_sockaddr_in ); # Some odd locations like BSD jails might not like INADDR_LOOPBACK. We'll # establish a baseline first to test against my $INADDR_LOOPBACK = do { - my $localsock = IO::Socket::INET->new( LocalAddr => "localhost", Listen => 1 ); - $localsock->sockaddr; + socket my $sockh, PF_INET, SOCK_STREAM, 0 or die "Cannot socket(PF_INET) - $!"; + bind $sockh, pack_sockaddr_in( 0, inet_aton( "127.0.0.1" ) ) or die "Cannot bind() - $!"; + ( unpack_sockaddr_in( getsockname $sockh ) )[1]; }; my $INADDR_LOOPBACK_HOST = inet_ntoa( $INADDR_LOOPBACK ); if( $INADDR_LOOPBACK ne INADDR_LOOPBACK ) { === modified file 't/04local-client-v6.t' --- t/04local-client-v6.t 2013-07-26 14:07:04 +0000 +++ t/04local-client-v6.t 2014-01-20 16:48:30 +0000 @@ -6,13 +6,23 @@ use Test::More; use IO::Socket::IP; -use Socket; +use Socket qw( inet_pton inet_ntop pack_sockaddr_in6 unpack_sockaddr_in6 IN6ADDR_LOOPBACK ); -my $AF_INET6 = eval { require Socket and Socket::AF_INET6() } or +my $AF_INET6 = eval { Socket::AF_INET6() } or plan skip_all => "No AF_INET6"; -eval { IO::Socket::IP->new( LocalHost => "::1" ) } or - plan skip_all => "Unable to bind to ::1"; +# Some odd locations like BSD jails might not like IN6ADDR_LOOPBACK. We'll +# establish a baseline first to test against +my $IN6ADDR_LOOPBACK = eval { + socket my $sockh, Socket::PF_INET6(), SOCK_STREAM, 0 or die "Cannot socket(PF_INET6) - $!"; + bind $sockh, pack_sockaddr_in6( 0, inet_pton( $AF_INET6, "::1" ) ) or die "Cannot bind() - $!"; + ( unpack_sockaddr_in6( getsockname $sockh ) )[1]; +} or plan skip_all => "Unable to bind to ::1 - $@"; +my $IN6ADDR_LOOPBACK_HOST = inet_ntop( $AF_INET6, $IN6ADDR_LOOPBACK ); +if( $IN6ADDR_LOOPBACK ne IN6ADDR_LOOPBACK ) { + diag( "Testing with IN6ADDR_LOOPBACK=$IN6ADDR_LOOPBACK_HOST; this may be because of odd networking" ); +} +my $IN6ADDR_LOOPBACK_HEX = unpack "H*", $IN6ADDR_LOOPBACK; # Unpack just ip6_addr and port because other fields might not match end to end sub unpack_sockaddr_in6_addrport { @@ -67,10 +77,10 @@ is( $socket->peerport, $testport, "\$socket->peerport for $socktype" ); # Unpack just so it pretty prints without wrecking the terminal if it fails - is( unpack("H*", $socket->peeraddr), "0000"x7 . "0001", "\$socket->peeraddr for $socktype" ); + is( unpack("H*", $socket->peeraddr), $IN6ADDR_LOOPBACK_HEX, "\$testclient->peeraddr for $socktype" ); if( $socktype eq "SOCK_STREAM" ) { # Some OSes don't update sockaddr with a local bind() on SOCK_DGRAM sockets - is( unpack("H*", $socket->sockaddr), "0000"x7 . "0001", "\$socket->sockaddr for $socktype" ); + is( unpack("H*", $socket->sockaddr), $IN6ADDR_LOOPBACK_HEX, "\$testclient->sockaddr for $socktype" ); } # Can't easily test the non-numeric versions without relying on the system's === modified file 't/05local-server-v6.t' --- t/05local-server-v6.t 2013-07-26 14:07:04 +0000 +++ t/05local-server-v6.t 2014-01-20 16:48:30 +0000 @@ -6,13 +6,23 @@ use Test::More; use IO::Socket::IP; -use Socket; +use Socket qw( inet_pton inet_ntop pack_sockaddr_in6 unpack_sockaddr_in6 IN6ADDR_LOOPBACK ); -my $AF_INET6 = eval { require Socket and Socket::AF_INET6() } or +my $AF_INET6 = eval { Socket::AF_INET6() } or plan skip_all => "No AF_INET6"; -eval { IO::Socket::IP->new( LocalHost => "::1" ) } or - plan skip_all => "Unable to bind to ::1"; +# Some odd locations like BSD jails might not like IN6ADDR_LOOPBACK. We'll +# establish a baseline first to test against +my $IN6ADDR_LOOPBACK = eval { + socket my $sockh, Socket::PF_INET6(), SOCK_STREAM, 0 or die "Cannot socket(PF_INET6) - $!"; + bind $sockh, pack_sockaddr_in6( 0, inet_pton( $AF_INET6, "::1" ) ) or die "Cannot bind() - $!"; + ( unpack_sockaddr_in6( getsockname $sockh ) )[1]; +} or plan skip_all => "Unable to bind to ::1 - $@"; +my $IN6ADDR_LOOPBACK_HOST = inet_ntop( $AF_INET6, $IN6ADDR_LOOPBACK ); +if( $IN6ADDR_LOOPBACK ne IN6ADDR_LOOPBACK ) { + diag( "Testing with IN6ADDR_LOOPBACK=$IN6ADDR_LOOPBACK_HOST; this may be because of odd networking" ); +} +my $IN6ADDR_LOOPBACK_HEX = unpack "H*", $IN6ADDR_LOOPBACK; # Unpack just ip6_addr and port because other fields might not match end to end sub unpack_sockaddr_in6_addrport { @@ -69,10 +79,10 @@ is( $testclient->peerport, $sockport, "\$testclient->peerport for $socktype" ); # Unpack just so it pretty prints without wrecking the terminal if it fails - is( unpack("H*", $testclient->peeraddr), "0000"x7 . "0001", "\$testclient->peeraddr for $socktype" ); + is( unpack("H*", $testclient->peeraddr), $IN6ADDR_LOOPBACK_HEX, "\$testclient->peeraddr for $socktype" ); if( $socktype eq "SOCK_STREAM" ) { # Some OSes don't update sockaddr with a local bind() on SOCK_DGRAM sockets - is( unpack("H*", $testclient->sockaddr), "0000"x7 . "0001", "\$testclient->sockaddr for $socktype" ); + is( unpack("H*", $testclient->sockaddr), $IN6ADDR_LOOPBACK_HEX, "\$testclient->sockaddr for $socktype" ); } } === modified file 't/30nonblocking-connect.t' --- t/30nonblocking-connect.t 2013-09-19 13:15:34 +0000 +++ t/30nonblocking-connect.t 2014-01-20 16:07:45 +0000 @@ -8,13 +8,15 @@ use IO::Socket::IP; use IO::Socket::INET; +use Socket qw( inet_aton inet_ntoa pack_sockaddr_in unpack_sockaddr_in ); use Errno qw( EINPROGRESS EWOULDBLOCK ); # Some odd locations like BSD jails might not like INADDR_LOOPBACK. We'll # establish a baseline first to test against my $INADDR_LOOPBACK = do { - my $localsock = IO::Socket::INET->new( LocalAddr => "localhost", Listen => 1 ); - $localsock->sockaddr; + socket my $sockh, PF_INET, SOCK_STREAM, 0 or die "Cannot socket(PF_INET) - $!"; + bind $sockh, pack_sockaddr_in( 0, inet_aton( "127.0.0.1" ) ) or die "Cannot bind() - $!"; + ( unpack_sockaddr_in( getsockname $sockh ) )[1]; }; my $INADDR_LOOPBACK_HOST = inet_ntoa( $INADDR_LOOPBACK ); if( $INADDR_LOOPBACK ne INADDR_LOOPBACK ) {
Subject: Re: [rt.cpan.org #92295] IPv6 Test Failure in FreeBSD jails
Date: Mon, 20 Jan 2014 17:00:18 +0000
To: Paul Evans via RT <bug-IO-Socket-IP [...] rt.cpan.org>
From: Tom Hukins <tom [...] eborcom.com>
On Mon, Jan 20, 2014 at 11:50:55AM -0500, Paul Evans via RT wrote: Show quoted text
> On further thought this seems the only reasonable option. > > Find patch attached.
Thank you for the patch. Unfortunately, the following tests fail: t/05local-server-v6.t (Wstat: 512 Tests: 29 Failed: 2) Failed tests: 4, 19 Non-zero exit status: 2 t/04local-client-v6.t (Wstat: 512 Tests: 23 Failed: 2) Failed tests: 8, 20 Non-zero exit status: 2 All four tests failed with: # got: '2a02:1658:1::123:1' # expected: '::1' Tom
On Mon Jan 20 12:00:29 2014, TOMHUKINS wrote: Show quoted text
> All four tests failed with: > > # got: '2a02:1658:1::123:1' > # expected: '::1'
Oops, missed some literal "::1"s in the tests. Try the attached in addition. -- Paul Evans
Subject: rt92295-pt2.patch
=== modified file 't/04local-client-v6.t' --- t/04local-client-v6.t 2014-01-20 16:49:13 +0000 +++ t/04local-client-v6.t 2014-01-20 17:10:35 +0000 @@ -73,8 +73,8 @@ [ unpack_sockaddr_in6_addrport( $testclient->sockname ) ], "\$socket->peername for $socktype" ); - is( $socket->peerhost, "::1", "\$socket->peerhost for $socktype" ); - is( $socket->peerport, $testport, "\$socket->peerport for $socktype" ); + is( $socket->peerhost, $IN6ADDR_LOOPBACK_HOST, "\$socket->peerhost for $socktype" ); + is( $socket->peerport, $testport, "\$socket->peerport for $socktype" ); # Unpack just so it pretty prints without wrecking the terminal if it fails is( unpack("H*", $socket->peeraddr), $IN6ADDR_LOOPBACK_HEX, "\$testclient->peeraddr for $socktype" ); === modified file 't/05local-server-v6.t' --- t/05local-server-v6.t 2014-01-20 16:49:13 +0000 +++ t/05local-server-v6.t 2014-01-20 17:10:35 +0000 @@ -42,8 +42,8 @@ is( $testserver->sockdomain, $AF_INET6, "\$testserver->sockdomain for $socktype" ); is( $testserver->socktype, Socket->$socktype, "\$testserver->socktype for $socktype" ); - is( $testserver->sockhost, "::1", "\$testserver->sockhost for $socktype" ); - like( $testserver->sockport, qr/^\d+$/, "\$testserver->sockport for $socktype" ); + is( $testserver->sockhost, $IN6ADDR_LOOPBACK_HOST, "\$testserver->sockhost for $socktype" ); + like( $testserver->sockport, qr/^\d+$/, "\$testserver->sockport for $socktype" ); my $socket = IO::Socket->new; $socket->socket( $AF_INET6, Socket->$socktype, 0 )
Subject: Re: [rt.cpan.org #92295] IPv6 Test Failure in FreeBSD jails
Date: Mon, 20 Jan 2014 18:04:01 +0000
To: Paul Evans via RT <bug-IO-Socket-IP [...] rt.cpan.org>
From: Tom Hukins <tom [...] eborcom.com>
On Mon, Jan 20, 2014 at 12:12:09PM -0500, Paul Evans via RT wrote: Show quoted text
> Oops, missed some literal "::1"s in the tests. > > Try the attached in addition.
"All tests successful." :) Tom
Released as 0.27 -- Paul Evans