Skip Menu |

This queue is for tickets about the Net-Server CPAN distribution.

Report information
The Basics
Id: 78449
Status: open
Priority: 0/
Queue: Net-Server

People
Owner: Nobody in particular
Requestors: VKHERA [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: 2.006
Fixed in: (no value)



On a server without IPv6 enabled (FreeBSD 8.2 in this case) Net::Server will not start a server because it attempts to bind to the IPv6 address if it finds the supported modules. The changelog for 2.006 indicates this is a specifically handled case, but it seems not. [mmstaging]~% perl -e 'use base qw(Net::Server); main->run(host => "localhost")' 2012/07/18-10:57:51 main (type Net::Server) starting! pid(36856) Resolved [localhost]:20203 to [::1]:20203, IPv6 Resolved [localhost]:20203 to [127.0.0.1]:20203, IPv4 Binding to TCP port 20203 on host ::1 with IPv6 2012/07/18-10:57:51 Can't connect to TCP port 20203 on ::1 [Protocol not supported] at line 67 in file /usr/local/lib/perl5/site_perl/5.14.2/Net/Server/Proto/TCP.pm 2012/07/18-10:57:51 Server closing! "localhost" resolves to just 127.0.0.1, nothing else. I do not know how it is finding ":;1" above: [mmstaging]~% host localhost localhost.m1e.net has address 127.0.0.1 Workaround is to explicitly request IPv4 for now.
I'm not quite sure what the best behavior is in this case - you have DNS answering for IPv6 for the name "localhost" and you have the Socket6 libraries installed but you don't have IPv6 enabled. Seems like if you don't have IPv6 enabled then DNS shouldn't be resolving that name either - seems a little broken to have one but not the other (they are two different systems DNS vs local protocols - but by using a non-address hostname both systems have to get used). By passing a name instead of an address you are asking Net::Server to resolve the name - which in this case resulted in an IPv4 address and an IPv6 address - which was resolved using IPv6 libraries on the system. You are the first I've heard from with this particular problem (all of the libraries+DNS but IPv6 not actually enabled). About the closest I could see us coming to fixing your particular problem is allowing for a warn without a die if a hostname resolved to both ipv4 and ipv6 and you are on a system (like the bsds) that tend to have sysctl bind-ipv6-only=1, but the ipv6 could not be bound. Do you have a fast way to check if ipv6 is enabled on bsd without actually attempting to bind a port? Up until 2.005, I had adopted the behavior of not binding ipv6 unless asked. However, slow as it may be, the world is migrating towards ipv6 and we have people using Net::Server that only have ipv6 addresses on their hosts. They and others raised very good points that if you are passing in a hostname (not a ipv4 or a ipv6 address), it should bind to what is returned by the hostname lookup - so if your hostname lookup returns ipv6, it should try and bind it. There are plenty of arguments to be had on both sides of the issue. Paul On Wed Jul 18 11:04:43 2012, VKHERA wrote: Show quoted text
> On a server without IPv6 enabled (FreeBSD 8.2 in this case) > Net::Server will not start a > server because it attempts to bind to the IPv6 address if it finds the > supported > modules. The changelog for 2.006 indicates this is a specifically > handled case, but it > seems not. > > > [mmstaging]~% perl -e 'use base qw(Net::Server); main->run(host => > "localhost")' > 2012/07/18-10:57:51 main (type Net::Server) starting! pid(36856) > Resolved [localhost]:20203 to [::1]:20203, IPv6 > Resolved [localhost]:20203 to [127.0.0.1]:20203, IPv4 > Binding to TCP port 20203 on host ::1 with IPv6 > 2012/07/18-10:57:51 Can't connect to TCP port 20203 on ::1 [Protocol > not > supported] > at line 67 in file > /usr/local/lib/perl5/site_perl/5.14.2/Net/Server/Proto/TCP.pm > 2012/07/18-10:57:51 Server closing! > > "localhost" resolves to just 127.0.0.1, nothing else. I do not know > how it is finding > ":;1" above: > > [mmstaging]~% host localhost > localhost.m1e.net has address 127.0.0.1 > > > Workaround is to explicitly request IPv4 for now.
My DNS does *not* return IPv6. There seems to be some shortcut in the perl resolver that is giving back an IPv6 address for localhost. If I run the above perl one-liner using the machines hostname, it does not find any IPv6 address, and thus only binds to the IPv4 it was given by DNS. I will dig further to see why perl gets an IPv6 address when my resolver doesn't give it one. [mmstaging]~% dig localhost ; <<>> DiG 9.6.-ESV-R3 <<>> localhost ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 63943 ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 0 ;; QUESTION SECTION: ;localhost. IN A ;; ANSWER SECTION: localhost. 3600 IN A 127.0.0.1 ;; AUTHORITY SECTION: localhost. 3600 IN NS localhost. ;; Query time: 0 msec ;; SERVER: 192.168.97.97#53(192.168.97.97) ;; WHEN: Wed Jul 18 11:53:50 2012 ;; MSG SIZE rcvd: 57
Well, I figured it out. getaddrinfo(3) references /etc/hosts (as per default nsswitch.conf) and in there is hiding an IPv6 address for localhost. This is on both FreeBSD 8 and 9, and CentOS 6.3. So by default on these systems, you will always get an IPv6 address for localhost regardless of DNS configuration and regardless of whether IPv6 is enabled. I don't know of a good solution other than disabling files for host lookups, or removing the IPv6 localhost from the hosts file. My solution is to just enable IPv6 on my hosts as I update them and since my new ISP offers it.
Though not necessarily resolved for this particular computer setup, it does seem like a rare enough setup and the overhead in trying to determine this is costly, and there are plenty of ways to specify the real ports/ipv combinations, I am going to mark this as resolved.
I hardly would call the default setup of CentOS 6 and FreeBSD 8 and 9 as "rare". But go ahead and leave this closed. I have worked around it.