Replacing inndstart

Russ Allbery rra at stanford.edu
Sun Dec 29 08:58:06 UTC 2002


Russ Allbery <rra at Stanford.EDU> writes:

> innbind needs an explicit list of addresses and ports to bind to
> (although the address can be something like 0.0.0.0 in IPv4 if one wants
> to bind to INADDR_ANY).  This means that the current inndstart code
> which loops through getaddrinfo and binds each socket can't be put into
> innbind, since it has no way of creating sockets itself and has no idea
> how many will be needed.

> I'll need some help from IPv6 gurus, since I don't know how IPv6 handles
> this sort of thing.  In IPv4, you just bind to INADDR_ANY, and that
> takes care of binding to all of your interfaces.  Is there not an IPv6
> equivalent?  innd could walk getaddrinfo and generate a command line for
> innbind, but inndstart currently allows any of those binds to fail
> silently as long as at least one of them succeeds, and that's rather
> hard behavior to duplicate using this architecture.  Is that particular
> algorithm important?  Or can we do an INADDR_ANY sort of thing, or just
> walk all addresses and fail if we can't bind any of them if no
> particular bind address is set?

Or I could just spend the day reading.  :)

Okay, with the help of RFC 2553 and a few experiments, I think I have a
better grasp of how this works.

There is an INADDR_ANY equivalent for IPv6.  The current method used by
inndstart, as near as I can tell, just always tries to bind to the
wildcard address for IPv6 and the wildcard address for IPv4, since that's
what calling getaddrinfo with a NULL nodename and a hint of AI_PASSIVE
seems to return (those two addresses).

Given that, we don't really need to do the getaddrinfo thing at all; it's
just sort of future-proofing, maybe, if they introduce another address
type down the road.

The trickier problem is this:  It doesn't appear to be possible to tell
whether the host you're running on actually supports IPv6 without actually
trying the bind.  getaddrinfo returns both IPv6 and IPv4 even if there are
no IPv6 interfaces on the host and the kernel doesn't support IPv6 (at
least under Linux).  This is vaguely annoying with the first pass at
innbind, since it causes innbind to log noise to syslog when the bind
fails.

I'm not sure what the best way to solve this problem is.  Probably add an
option to innbind that says to not report an error if the bind fails, just
return a non-zero exit status, and to use that option only when walking
through the getaddrinfo list when no bind addresses have been specified
and only for the IPv6 address or for IPv4 if IPv6 succeeded.

Other than that, I think this method works.  I've tested it now on Linux
and on Solaris, and while I can't manage to test on Solaris since I can't
figure out how to get telnet to let me telnet to ::1 (keep getting errors
saying I can't assign the requested address, even after I've plumbed the
interface and set a route for it, and when I have a server bound to and
listening on ::1 according to netstat), I think the binding is doing the
right thing.

-- 
Russ Allbery (rra at stanford.edu)             <http://www.eyrie.org/~eagle/>

    Please send questions to the list rather than mailing me directly.
     <http://www.eyrie.org/~eagle/faqs/questions.html> explains why.


More information about the inn-workers mailing list