Subject: | IPv6 fails if _update_peer is called |
The internal routine _update_peer tries to determine the peer address
and port when a socket is upgraded.
Unfortunately, it only knows how to do this for IPV4 sockets. The eval
catches the fact that things go badly wrong, but the symptoms just pop
up elsewhere when the unset values get used.
The attached patch improves matters, though I'm not sure if the
scope/flow ids should be added to the output. Since these aren't the
common case, I'll leave that to the maintainter.
It would be great if this could get into a public kit so I don't have
to distribute a private patch...
Thanks!
Subject: | IO-Socket-SSL-peer.patch |
--- /usr/local/share/perl5/IO/Socket/SSL.pm~ 2012-06-18 02:15:42.000000000 -0400
+++ /usr/local/share/perl5/IO/Socket/SSL.pm 2012-09-27 19:06:22.043984608 -0400
@@ -67,15 +67,15 @@
# try to load inet_pton from Socket or Socket6
my $ip6 = eval {
require Socket;
Socket->VERSION(1.95);
- Socket->import( 'inet_pton' );
+ Socket->import( qw/inet_pton inet_ntop/ );
1;
} || eval {
require Socket6;
- Socket6->import( 'inet_pton' );
+ Socket6->import( qw/inet_pton inet_ntop/ );
1;
};
# try IO::Socket::IP or IO::Socket::INET6 for IPv6 support
if ( $ip6 ) {
@@ -523,13 +523,21 @@
# so that PeerAddr|PeerPort are not set from args
sub _update_peer {
my $self = shift;
my $arg_hash = ${*$self}{'_SSL_arguments'};
eval {
- my ($port,$addr) = sockaddr_in( getpeername( $self ));
- $arg_hash->{PeerAddr} = inet_ntoa( $addr );
- $arg_hash->{PeerPort} = $port;
+ my $sockaddr = getpeername( $self );
+ my $af = sockaddr_family($sockaddr);
+ if( $af == AF_INET6 ) {
+ my ($port, $addr, $scope, $flow ) = unpack_sockaddr_in6( $sockaddr );
+ $arg_hash->{PeerAddr} = inet_ntop( $af, $addr );
+ $arg_hash->{PeerPort} = $port;
+ } else {
+ my ($port,$addr) = sockaddr_in( $sockaddr);
+ $arg_hash->{PeerAddr} = inet_ntoa( $addr );
+ $arg_hash->{PeerPort} = $port;
+ }
}
}
#Call to accept occurs when a new client connects to a server using
#IO::Socket::SSL