Subject: | Problem with local IPv6 and remote IPv4 address |
Date: | Fri, 8 Aug 2014 14:04:35 +0200 |
To: | bug-IO-Socket-INET6 [...] rt.cpan.org |
From: | torsten.werner [...] assyst.de |
Hi,
I'm watching problems with activated IPv6 in my LAN and IPv4 connection to
remote side.
I use Windows7 with active IPv6.
When I install IO::Socket::IPv6 I've no chance to connect CPAN by "perl
-MCPAN -e shell", to use "Email::Sender" to connect external mail servers
and I've lots of other restrictions.
What happens is the following:
IO::Socket::INET6::configure is called with LocalAddr => undef inside the
args argument. $arg->{Domain} is not existent
The remote host has an IPv4 address only.
In the following code the local address is set to '::':
if ($^O eq 'MSWin32') {
if ((!$laddr) && (!$lport)) {
$laddr = ($family == AF_INET) ? '0.0.0.0' : '::';
$lport = '';
} elsif (!$lport) {
$lport = '';
}
}
This is not so nice, because later on is the local address used for
getaddrinfo, and this will return an array with IPv6 family only.
The loop to find local and remote pairs with the same family will never
get a matching pair. The configure function returns a object which is not
connected. Unfortunately there is no error/warning message when we have no
getaddrinfo results with the same family.
I made a small fix for me in version 2.72;
1) delete lines 187 and 188 with content:
my @lres =
getaddrinfo($laddr,$lport,$family,$type,$proto,AI_PASSIVE);
return _error($sock, $EINVAL, "getaddrinfo: $lres[0]") if @lres<5;
2) replace lines 164 until 174 with content:
if ($^O eq 'MSWin32') {
if ((!$laddr) && (!$lport)) {
$laddr = ($family == AF_INET) ? '0.0.0.0' : '::';
$lport = '';
} elsif (!$lport) {
$lport = '';
}
}
my $type = $arg->{Type} ||
$socket_type{(getprotobynumber($proto))[0]};
by the following code:
if ($^O eq 'MSWin32') {
if ((!$laddr) && (!$lport)) {
$lport = '';
if ($family == AF_INET) {
$laddr="0.0.0.0";
@lres =
getaddrinfo($laddr,$lport,$family,$type,$proto,AI_PASSIVE);
return _error($sock, $EINVAL, "getaddrinfo:
@lres[0]") if @lres<5;
} elsif ($family == AF_INET6) {
$laddr="::";
@lres =
getaddrinfo($laddr,$lport,$family,$type,$proto,AI_PASSIVE);
return _error($sock, $EINVAL, "getaddrinfo:
@lres[0]") if @lres<5;
} else {
my @lres_v4 =
getaddrinfo("0.0.0.0",$lport,$family,$type,$proto,AI_PASSIVE);
my @lres_v6 =
getaddrinfo("::",$lport,$family,$type,$proto,AI_PASSIVE);
push @lres, @lres_v4 if @lres_v4 > 4;
push @lres, @lres_v6 if @lres_v6 > 4;
return _error($sock, $EINVAL, "getaddrinfo:
@lres_v4[0], @lres_v6[0]") if @lres<5;
}
} elsif (!$lport) {
$lport = '';
}
} else {
@lres =
getaddrinfo($laddr,$lport,$family,$type,$proto,AI_PASSIVE);
return _error($sock, $EINVAL, "getaddrinfo: @lres[0]") if
@lres<5;
}
Bye
Torsten