debian/git-daemon-run: disable TCP quiet period when restarting
As ip(7) explains, "a TCP local socket address that has been bound is
unavailable for some time after closing, unless the SO_REUSEADDR flag
has been set." As a result, if git-daemon is killed while serving
clients on all interfaces, /var/log/git-daemon/current fills with
messages like this as the process is restarted every second:
fatal: unable to allocate any listen sockets on port 9418
The churn doesn't stop until an address is free, minutes later.
Worse, if only _some_ addresses are in use (e.g., the ipv4 address is
bound but v6 was not serving clients) then the daemon receives
EADDRINUSE for those addresses that were in use and binds only to the
remaining ones, without complaint.
The period of unavailability is supposed to protect against old
segments for the same socket pair remaining in the network arriving
with the same sequence number as new TCP segments. (If the TCP stack
remembered the relevant socket pairs or sequence numbers then it could
just recognize these are reject them, but exiting and closing the
socket means forgetting those details.) In other words, the downside
to using SO_REUSEADDR would be a chance of disrupting connections if
the same client tries to make a new connection from the same port
right after git-daemon is restarted. Luckily, in the case of
git-daemon that chance is almost negligible:
- upload-pack processes serving existing connections remain alive
when the git daemon is killed, so there is no reason for clients to
make a new connection then; and
- the client-side port for connections is random, so it is unlikely
(around 1/60k chance) even if a new connection is established that
it will use the same port.
So it would be beneficial and safe to use SO_REUSEADDR. Do so by
adding --reuseaddr to the command line in /etc/sv/git-daemon/run.
Fixes: http://bugs.debian.org/609405
Encouraged-by: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
Tested-by: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>