Subject: Re: accepting both ipv4 and v6 connections
To: None <tech-net@NetBSD.org>
From: Jeff Rizzo <riz@boogers.sf.ca.us>
List: tech-net
Date: 05/12/2004 09:50:58
On Wed, May 12, 2004 at 02:56:25AM -0400, der Mouse wrote:
> > 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.

Yes, I figured as much.  Seems like the (or at least _a_) more correct
thing to do is to loop over all the AI_PASSIVE addresses returned
and open a listening socket for each.   Would an fd_set be appropriate
for carrying around the group of listening fds opened, since
we don't actually know how many sockets we'll open?  Right now, the
code passes around a single "listen_fd", so I'd like to suggest some
changes that have the least impact on the code structure, and changing
it to pass around an fd_set seems (to my untrained eye, anyway) to
be the simplest change to make.

> 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.

I managed to figure this out before seeing your message... yes, it's
the v6only thing.  It works as expected with net.inet6.ip6.v6only=0,
but it seems to me that explicit protocol support is the way to go
whether or not one believes that v4-mapped is bad.

> 
> 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[%]).

Yes, after doing a lot of code reading, I think multiple fds for
multiple protocols is indeed the way to go.  I'm just trying to come
up with a proposal for this that's likely to be accepted by the
original author.


> 
> [%] 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.)

Thanks for your response.

+j
-- 
Jeff Rizzo                                         http://boogers.sf.ca.us/~riz