Skip Menu |

This queue is for tickets about the libwww-perl CPAN distribution.

Report information
The Basics
Id: 77020
Status: open
Priority: 0/
Queue: libwww-perl

People
Owner: Nobody in particular
Requestors: aaronmdjones [...] gmail.com
Cc:
AdminCc:

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



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.
From: jfesler [...] gigo.com
I humbly offer: https://github.com/libwww-perl/net-http/pull/10 https://github.com/libwww-perl/libwww-perl/pull/58 The combination will use IO::Socket::IP or IO::Socket::INET6 (if found); and uses URI to do host address parsing (in order to correctly parse [2001:db8::1]:80). (I've also updated RT #75618 with this same text)
From: jfesler [...] gigo.com
My patches appear to be accepted, and a new release produced. Please consider updating to these packages: Net::HTTP (6.07) LWP (6.080 URI (1.64)
From: ppisar [...] redhat.com
Dne Pá 25.čec.2014 18:39:19, jfesler napsal(a): Show quoted text
> My patches appear to be accepted, and a new release produced. > > Please consider updating to these packages: > > Net::HTTP (6.07) > LWP (6.080 > URI (1.64)
The change in LWP::Protocol::http is: --- libwww-perl-6.07/lib/LWP/Protocol/http.pm 2014-04-23 07:31:25.000000000 +0200 +++ libwww-perl-6.08/lib/LWP/Protocol/http.pm 2014-07-25 05:13:08.000000000 +0200 @@ -17,6 +17,14 @@ { my($self, $host, $port, $timeout) = @_; + # IPv6 literal IP address should be [bracketed] to remove + # ambiguity between ip address and port number. + # Extra cautious to ensure that $host is _just_ an IPv6 address + # (at least as best as we can tell). + if ( ($host =~ /:/) && ($host =~ /^[0-9a-f:.]+$/i) ) { + $host = "[$host]"; + } + local($^W) = 0; # IO::Socket::INET can be noisy my $sock = $self->socket_class->new(PeerAddr => $host, PeerPort => $port, The regular expression does not count with zone identifiers (e.g "ff08::1%eth0"). See RFC 6874. -- Petr