IPv6 is the next generation internet protocol. In the last time there were an increased technical and political activity for better support of IPv6.
I'm working in a company which does a lot of networking stuff with Perl so we want to make use of IPv6 from Perl. So I did some research about this topic which resultat in a talk (in german) held at the German Perl Workshop 2009 and some code.
This article is a short summary of this talk in english, in the hope, that the topic will get more publicity and finally result in better IPv6 support in Perl.
According to IPv6 support in programming libraries the support for IPv6 in Perl is bad. Although I really like programming in Perl I think the author of this blog is right:
- There is no support for IPv6 in the Perl CORE.
- But one can program with IPv6 using Socket6 and IO::Socket::INET6 which is mostly the same like using Socket or IO::Socket::INET.
- But because these packages are not in CORE one has to either depend on them or each module has to fallback to IPv4 if these modules are not available.
- The result is, that none of the CORE modules and other famous modules can be used with IPv6, for example Net::SMTP, Net::POP3, Net::FTP, LWP, WWW::Mechanize (which is based on LWP).
If modules have IPv6 support the implementation or usage is more complex, than it would be, if perl had IPv6 support in the CORE. For example:
- AnyEvent does IPv6 but does not like to depend on Socket6 because it's not in CORE, so it has hard coded AF_INET6 for various operating systems, does it's own DNS lookup (slightly different from getaddrinfo), ...See AnyEvent::Socket.
- POE hast IPv4 code which uses inet_aton and gethostbyname, if it can find Socket6 it has similar code for IPv6 which uses inet_pton and getaddrinfo, see POE::Wheel::SocketFactory.
- IO::Socket::SSL depends in IO::Socket::INET6 if it finds it, otherwise it will use IO::Socket::INET (it used to be worse, see Perl considered harmful
- Net::LDAP need to be given a special 'inet6' switch if it should try to connect with IPv6
The usual workaround is to code for IPv4 and have additional support for IPv6 if Socket6 or IO::Socket::INET6 is available. This does not help for existing modules, but there are some modules I've created in preparatation of the German Perl Workshop which might help:
- Net::INET6Glue::INET_is_INET6 simply make IO::Socket::INET6 behave like IO::Socket::INET which helps for modules like Net::SMTP, Net::POP3, LWP (http connections only).
- Net::INET6Glue::FTP adds support for EPRT and EPSV to Net::FTP to make it IPv6 capable. This also helps LWP, because it uses Net::FTP for ftp connections.
- Net::SSLGlue::LWP forces LWP to use IO::Socket::SSL instead of Crypt::SSLeay/Net::SSL for https connections. Contrary to Net::SSL IO::Socket::SSL can do IPv6 (maybe Net::INET6Glue::INET_is_INET6 would make Net::SSL IPv6 capable too, but IO::Socket::SSL is the better choice anyway if you would like to have proper certificate checking)
- Add IPv6 support to the Perl CORE as soon as possible (e.g for perl5.10.X, do not wait for perl5.12 or perl6).
- One way would be to just as Socket6 and IO::Socket::INET6 as they are, but I would prefer to have IO::Socket::INET6 merged into IO::Socket::INET and Socket6 into Socket, to have just one Socket API, and not one API which does only IPv4 and another, which does IPv6+IPv4 (like Socket6 and IO::Socket::INET6 do). This is what other modern languages (Python, Java) do.