I've been looking into what it would take to get several of our applications IPv6-enabled. In some cases, it's trivial. In others, it's going to be hell. This post is about how several programming languages have added IPv6 support to their standard libraries. Well, it's not really a post. It's more of a rant. Because I'm angry. I'm angry that two of the most popular languages appear to have put no forethought into future-proofing their networking libraries.
PHP and Perl are excellent examples of how not to add IPv6 support to a library. The status of IPv6 in both systems is an utter mess that will take years to fix.
We have many apps written in PHP and Perl, which we will eventually
need to IPv6-enable. Given the abysmal state of IPv6 in these
languages, I'm not optimistic about success. Critically, it not
possible to write applications in PHP or Perl that use a single API and will work on IPv4-only, IPv6-only and IPv4/IPv6 dual-stacked hosts. The inability to do this is dooming.
Non-programmers can skip to the last paragraph. What follows is techy.
Let's look at PHP. It got IPv6 support in version 5, but its gethostbyname
() function still doesn't support IPv6. Of course, the documentation doesn't mention this fact. Instead, users should use dns_get_record
(). (As an aside, why does dns_get_record() still support A6 records, which were deprecated years ago?). Alternatively, developers may use PEAR's Net_DNS
class to resolve names. It appears as if there are cases where Net_DNS_Resolver::query() can fail to use IPv6 to connect to a DNS server, however (if using UDP and the "enhanced sockets library").
Then there are the IP address utility libraries: Net_IPv4
. First question: Why are there two of them? Why is there not a single network address library that can handle both formats? But it gets worse: The two libraries have different APIs. There is considerable functional overlap between them -- there are functions to apply a netmask to an address, parse CIDR-formatted addresses, etc -- but the function prototypes look nothing alike. For example, some of Net_IPv4::parseAddress
()'s abilities are duplicated in Net_IPv6::getNetmask
() and Net_IPv6::removeNetmaskSpec
(). Both Net_IPv4 and Net_IPv6 have functions to verify if a string is a valid address, but they have different names: Net_IPv4::validateIP
() vs Net_IPv6::checkIPv6
(). There are other examples of this sort of mismatch.
I'll only mention briefly that there are two other modules for validating IP(v4) addresses: Net_CheckIP
. Both of them only handle IPv4 and have different function names than the equivalent functions in Net_IPv4 and Net_IPv6. This only serves to increase programmer confusion and encourage the development of non-IPv6-capable code.
And that's just the low-level code. There are still the higher-level libraries for dealing with IMAP, SMTP, HTTP, etc. I haven't begun an audit of PEAR's Networking librar
y to check for IPv4-only code. I'm too afraid.
Perl isn't any better. For reasons that escape me, Perl decided to fork its network libraries into IPv4-only and IPv6 halves. Specifically, there are Socket
(and it's object-oriented cousin, IO::Socket::INET
) and Socket6
). Of course this means that developers have to change their code to get IPv6 support. Almost no OSes bundle Socket6 or IO::Socket::INET6, so developers are loathe to make such changes. (Kudos to Mac OS X 10.5 and Ubuntu 7.10 for supporting them).
Because the modules are separate, you have to write a bunch of ugly code. When your code starts, you check if you have one of the IPv6 socket modules installed. If so, set a flag. Then every single time you need to talk to the network, you check this flag and branch, either to Socket6 or Socket. This is a) ugly b) inefficient c) unlikely to be adopted by virtually all programmers d) all of the above. Check the source to the Net::DNS
module for an example. I am not looking forward to submitting patches that do this. But someone is going to have to.
I contrast this to Java, Python and C which have sane, clean, standardized APIs that support both IPv4 and IPv6. In Java, it's unlikely that developers will have to change code. In Python, the changes are usually two or three lines. In C, it's slightly more lines than that, but generally not much more. I'll elaborate more on these languages in a later post. Readers at Penn State may want to look at my IPv6 programming notes
in the ITS Wiki
(which is IPv6-enabled