Viktor Dukhovni:
> > The Postfix master creates as many sockets as needed for an inet
> > service, and sets the socket option SO_REUSEADDR on each socket,
> > and bind()s them to the desired addresses.
> > 
> > With that, it may be possible for the Postfix master to create new
> > sockets, set SO_REUSEADDR on each socket, and bind() them to the
> > new addresses; if successful, close() the old sockets, otherwise
> > close() the new sockets.
> 
> Yes, typically doable, by determining which bindings are unchanged,
> which new, and which old.
> 
> > Am I missing something? This will have to work on all supported
> > systems, though. Not just Linux, not just *BSD.
> 
> The tricky case is changing a wildcard binding to a set of non-wildcard
> bindings.  When a wildcard binding is active, it is AFAIK not generally
> possible to bind non-wildcard listeners for the same port, and
> presumably the converse.
> 
> Changes in explicit lists of IPs should be viable as you noted.

The configurations of interest are:

    inet_interfaces = all (wildcard binding)
    inet_interfaces = enumeration (non-wildcard binding)

Changes of type wildcard->wildcard are noops.

Changes of type enumeration->enumeration are partial noops if one
only touches the sockets whose addresses have changed.

That leaves wildcard->enumeration and enumeration->wildcard.  Both
*should* be safe on BSD-ish (and Solaris, HP-UX) systems, given how
SO_REUSEADDR was originally implemented. See the "BSD SO_REUSEADDR"
discussion with a nice table in:
https://stackoverflow.com/questions/14388706/how-do-so-reuseaddr-and-so-reuseport-differ
This also comes with a nice test program.

With Linux the changes of type wildcard->enum and enum->wildcard
require code that is kernel version dependent.  If we consider only
kernels >= 3.9 then we can keep it simple with SO_REUSEPORT.

All of this needs to be evaluated not only on an idle server where
'listen' sockets are open only in the master, but also with child
process that hold a reference to a master's listen socket as well
as connected sockets. And then it needs to deal with sockets that
are in the TIME_WAIT state.

        Wietse

Reply via email to