Subject: | LWP sometimes does not properly parse bracketed IPv6 addresses. |
Gentoo amd64 stable, hardened+nomultilib. Perl 5.12.4, no ithreads.
Linux kernel 3.1.1 with grsecurity.
When using NET::INET6Glue::INET_is_INET6 (to make LWP use
IO::Socket::INET6),
IPv6 requests to hostnames work fine:
aaron@abraxas ~ $ perl -e '
Show quoted text
> use Net::INET6Glue::INET_is_INET6;
> use LWP;
> my $lwp = new LWP::UserAgent( ( 'timeout' => 10 ) );
> my $res = $lwp->get( "http://ipv6.google.com:80/" );
> if ($res->is_error()) { printf("Error: %s.\n", $res->status_line());
exit(1); }
Show quoted text> printf("Got %s bytes of return content.\n", length($res->content()));
> '
Got 11955 bytes of return content.
However, it seems that with a few bracketed IPv6 addresses I throw at it, it
attempts to connect to the wrong port (this is the IPv6 address for the
previous hostname):
aaron@abraxas ~ $ perl -e '
Show quoted text> use Net::INET6Glue::INET_is_INET6;
> use LWP;
> my $lwp = new LWP::UserAgent( ( 'timeout' => 10 ) );
> my $res = $lwp->get( "http://[2a00:1450:4007:802::1014]:80/", ( "Host"
=> "ipv6.google.com" ) );
Show quoted text> if ($res->is_error()) { printf("Error: %s.\n", $res->status_line());
exit(1); }
Show quoted text> printf("Got %s bytes of return content.\n", length($res->content()));
> '
Error: 500 Can't connect to 2a00:1450:4007:802::1014:80 (timeout).
And a tcpdump while that was in progress:
11:15:49.206876 IP6 (hlim 64, next-header TCP (6) payload length: 40)
<redacted_source_address>.43953 > 2a00:1450:4007:802::1014.1014: S,
2186682523:2186682523(0) win 14400
11:15:50.207386 IP6 (hlim 64, next-header TCP (6) payload length: 40)
<redacted_source_address>.43953 > 2a00:1450:4007:802::1014.1014: S,
2186682523:2186682523(0) win 14400
11:15:52.211430 IP6 (hlim 64, next-header TCP (6) payload length: 40)
<redacted_source_address>.43953 > 2a00:1450:4007:802::1014.1014: S,
2186682523:2186682523(0) win 14400
11:15:56.219420 IP6 (hlim 64, next-header TCP (6) payload length: 40)
<redacted_source_address>.43953 > 2a00:1450:4007:802::1014.1014: S,
2186682523:2186682523(0) win 14400
You can see it was trying to connect to port 1014, not port 80.
The confusing thing is, sometimes it works, it seems to depend on the
address:
aaron@abraxas ~ $ perl -e '
Show quoted text> use Net::INET6Glue::INET_is_INET6;
> use LWP;
> my $lwp = new LWP::UserAgent( ( 'timeout' => 10 ) );
> my $res = $lwp->get( "http://[2001:1890:123a::1:1e]:80/", ( "Host" =>
"www.ietf.org" ) );
Show quoted text> if ($res->is_error()) { printf("Error: %s.\n", $res->status_line());
exit(1); }
Show quoted text> printf("Got %s bytes of return content.\n", length($res->content()));
> '
Got 19138 bytes of return content.
I suspect this is a bug deep in the address parsing code in LWP.