Subject: Re: accepting both ipv4 and v6 connections
To: None <tech-net@NetBSD.org>
From: der Mouse <mouse@Rodents.Montreal.QC.CA>
List: tech-net
Date: 05/12/2004 02:56:25
> I've been using distcc from pkgsrc, compiled with the
> --enable-rfc2553 flag, and I'm trying to figure out whether the way
> distccd is trying to listen for both v4 and v6 connections is correct
> for NetBSD or not; [...]

> The code in question uses getaddrinfo() and sets the hints for an
> ai_socktype of SOCK_STREAM and ai_flags to AI_PASSIVE.  It takes the
> first sockaddr returned (which in this case is ::, the v6 wildcard),
> and *only* the first sockaddr returned, calls socket(), bind() and
> listen() on it.

This is rather broken.  There is no excuse for assuming that the v6
address will be the first one in the returned list; getaddrinfo()'s
interface contract makes no promises about what order the returned list
is in.

> The author seems to think this should (and I assume under Linux,
> does, though I have no way of verifying it at the moment) be able to
> accept either v4 or v6 connections,

This is almost certainly the V6ONLY furor at work.  I believe NetBSD
has decided that having v6 listening sockets convert unmatched v4
connection attempts into v4-mapped v6 addresses is a Bad Thing (at
least by default, possibly at all - I haven't checked); presumably
Linux disagrees.

As of 1.6.1, there's a sysctl net.inet6.ip6.v6only which I think
affects this; you don't say what NetBSD version you're using, but it
quite likely has something similar.

> Can someone with a little more network-code savvy enlighten me as to
> how it's *supposed* to work?

How you believe it's supposed to work depends on whether you believe
v4-mapped IPv6 addresses are helpful or harmful.

I'd say that doing multiple listen fds for multiple protocols is
safest.  It should work even on systems that support v4-mapped v6
addresses by default - and it prepares the code for use with systems
that support address families that cannot be collapsed the way IPv4 and
IPv6 can (for example, IP and DECnet - while getaddrinfo()'s definition
is somewhat broken when seen from a broader-than-IP perspective, the
brokenness is easy to fix, at least the brokenness I see[%]).

/~\ The ASCII				der Mouse
\ / Ribbon Campaign
 X  Against HTML	       mouse@rodents.montreal.qc.ca
/ \ Email!	     7D C8 61 52 5D E7 2D 39  4E F1 31 3E E8 B3 27 4B

[%] The brokenness I refer to is the assumption that resolved service
    demultiplexing identifiers (ports, for TCP and UDP) are numbers.
    The AI_NUMERICSERV bit is defined in terms of numeric strings,
    which is not appropriate for protocols that do not use small
    numbers for their demultiplexing namespace.  (DECnet uses short
    strings, at least in the versions I worked with.)