noxxi / p5-io-socket-ssl

IO::Socket::SSL Perl Module
36 stars 59 forks source link

Set socket domain for IO::Socket::INET6. #6

Closed yak1ex closed 11 years ago

yak1ex commented 11 years ago

If IO::Socket::SSL uses IO::Socket::INET6, some method fails for IPv4 hosts because the socket domain is considered as AF_INET6 like "Bad arg length for Socket6::unpack_sockaddr_in6(), length is 16, should be 28". This is because IO::Socket::INET6::{sock,peer}{addr,port,host,flow,scope}() depends on IO::Socket::INET6::sockdomain() to determine INET or INET6 and IO::Socket::INET6::sockdomain() returns AF_INET6 if io_socket_domain is not set. It is forwarded to IO::Socket::sockdomain() and io_socket_domain, undef in this case, is returned then AF_INET6 is used as default.

At least, using LWP::Protocol::https::connect ( https://github.com/benningm/LWP-Protocol-connect ) leads this failure in actual usage.

noxxi commented 11 years ago

from reading the code of IO::Socket::INET6 and IO::Socket I understand the following:

So INET6::sockdomain should only return AF_INET6 if the socket is AF_INET6 or if the family cannot be determined by sockaddr_family, which should not be the case for AF_INET sockets. So frm reading the code I cannot see how the reported problem could happen. But since I'm sure that it somehow happens - would you please provide a small test script which triggers the problem so that I can debug it?

yak1ex commented 11 years ago

would you please provide a small test script which triggers the problem so that I can debug it?

I'll try it. Please wait.

yak1ex commented 11 years ago

Sorry for late feedback.

The following code:

#!/usr/bin/perl

use IO::Socket::INET;
use IO::Socket::SSL;

my $sock = IO::Socket::INET->new(PeerHost => 'www.google.com', PeerPort => 443);
my $sock_ssl = IO::Socket::SSL->new_from_fd($sock, SSL_verify_mode => SSL_VERIFY_NONE);

print $sock_ssl->sockhost;

causes the following error:

Bad arg length for Socket6::unpack_sockaddr_in6, length is 16, should be 28 at /<site-depended-path>/Socket6.pm line 282.

on:

Installing IO::Socket::IP masking the issue, it may be helpful to use Test::Module::Without like perl -MTest::Without::Module=IO::Socket::IP test.pl

noxxi commented 11 years ago

I don't think the bug is in IO::Socket::SSL. IO::Socket::SSL calls uses the handle it gets by calling new_from_fd on the super class. This one is already buggy in IO::Socket::INET6, e.g. the following throws the same problem:

my $sock = IO::Socket::INET->new(PeerHost => 'www.google.com', PeerPort => 443);
my $sock_inet6 = IO::Socket::INET6->new_from_fd($sock,'r');
print $sock_inet6->sockhost;

IO::Socket::IP does it correct and thus causes no problems with IO::Socket::SSL, so please file the bug against IO::Socket::INET6.