2010/09/06

Module name suggestions: A proper IO::Socket for IPv4/IPv6 duallity

I currently don't have a good name for a module I'd like to write, because I think it is very much required right now.

We have IO::Socket::INET. It wraps PF_INET, thus making it IPv4 only.

We have IO::Socket::INET6. It wraps either PF_INET or PF_INET6, despite its name. It also uses Socket6, thus restricting it to only working on machines capable of supporting IPv6.

Thus any author wanting to write code to communicate to the internet (apparently that's some new fad everyone's talking about this week) is presented a moral dilema: Support IPv6 at the cost of not working on older v4-only machines, or support older machines but be incapable of using IPv6.

I originally partially solved this problem some years ago by the creation of Socket::GetAddrInfo, a module that presents the interface of RFC2553's getaddrinfo(3) and getnameinfo(3) functions. This however is not enough for actually connecting and using sockets.

I'd therefore like to propose a new IO::Socket subclass that uses these and only these functions, for converting between addresses and name/service pairs.
use IO::Socket::YourNameHere;

my $sock = IO::Socket::YourNameHere->new(
PeerHost => "www.google.com",
PeerService => "www",
);

printf "Now connected to %s:%s\n", $sock->peerhost, $sock->peerservice;

...
Since it would use Socket::GetAddrInfo, it can transparently support IPv4 or IPv6. Since it would only use Socket::GetAddrInfo, it will work in a v4-only mode on machines incapable of supporting IPv6, and will not be restricted to only IPv4 or IPv6 if and when some new addressing family comes along to replace IPv6 one day; as v6 is now trying to do with v4.

In order to provide an easy transition period, I'd also support additional IO::Socket::INET options where they still make sense; e.g. accepting {Local/Peer}Port as a synonym for {Local/Peer}Service. The upshot here ought to be that you can simply
sed -i s/IO::Socket::INET/IO::Socket::YourNameHere/
and suddenly your code will JustWork on IPv6 in a good >90% of cases.

Can anyone suggest me a better module name for this?


Edit 2010/09/07: We seem to be settling on IO::Socket::IP for this currently.


Edit 2010/09/23: We did indeed settle on IO::Socket::IP; this is now up on CPAN, and will be the subject of a future posting...


This cross-posted from module-authors@perl.

7 comments:

  1. I support the idea of either IO::Socket::IP or IO::Socket::Net.

    ReplyDelete
  2. I guess IO::Socket::IP sounds reasonable for a mixed IPv4/IPv6 use case, until you consider perhaps that getaddrinfo doesn't necessarily have to remain just IP; it could support something non-IP if a need ever arose.

    IO::Socket::Net sounds fairly reasonable, if entirely and utterly generic, and somewhat devoid of all meaning, requiring you to read down into it and really discover what it's actually about. More accurate name, but less discoverable.

    Perhaps maybe IO::Socket::IP actually wins for a name; technically less accurate but it does declare atleast its current intentions, if not its possible future abilities.

    ReplyDelete
  3. The trend in CPAN naming seems to be to attach ::Any to modules the figure it out and dispatch to the right thing. Maybe IO::Socket::INET::Any.

    ::Net isn't what you want. Other protocols than IP use the network, so it's a bit too broad.

    ReplyDelete
  4. Oh, it's not that this will dispatch to either of ::INET or ::INET6; rather, it will completely reimplement the same functionallity by using getaddrinfo/getnameinfo instead of gethostbyname/-byaddr and friends. The ::Any suffix modules really do strongly indicate they'll just trampoline you off to a more appropriate specialisation based on the arguments/etc..

    ReplyDelete
  5. Why not extend IO::Socket::INET to also support IPv6 instead of have everybody replace it with your new module?

    ReplyDelete
  6. Because IO::Socket::INET is very tied to AF_INET, as well its name would imply. The same is true of all the one-family IO::Socket subclasses. This is the point of them.

    IO::Socket::IP does not replace -every- feature of IO::Socket::INET, because some are very IPv4-specific. The intent is that it will cover the 80% of portable features which covers well over 99% of the actual use cases. There'll still be a requirement for AF_INET or AF_INET6-specific modules to cover those rare cornercases. For example, IO::Socket::IP cannot cover flow labels because IPv4 doesn't have them; whereas IO::Socket::INET6 can do that.

    ReplyDelete
  7. Thanks for the explanation!
    Count me in on IO::Socket::IP, I'm abraxxa on irc.

    ReplyDelete