Package: git-daemon-run Version: 1:1.7.2.3-2.2 Severity: important Justification: bad behavior, especially re ipv6 support
Hi, Was playing around with git-daemon-run to compare it with the proposed sysvinit support. See [1] for the war story. Okay, finished? The upshot is, 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. Care should be taken when using this flag as it makes TCP less reliable. More precisely: 1. server closes connection, for example by exiting. 2. kernel places connection in TIME-WAIT state. The address is in use. 3. git-daemon gets EADDRINUSE when it tries to use that address, since the SO_REUSEADDR flag is not set. If all (usually meaning "both") addresses to be bound to are "in use", the daemon dies with fatal: unable to allocate any listen sockets on port 9418 and gets launched again by runit when an address is free. If only _some_ of the addresses to be bound to are "in use" in this way, the daemon does not get launched again, and it is bound only to the remaining ones. Analysis: - The ideal would be to disallow connections _from the same client address and port_ until the TIME-WAIT state ends. Is that easy to achieve? - A workaround, even though it violates the spirit of TCP, is to just forget about TIME-WAIT in the case of restarting the daemon. I _suspect_ that this is what the git daemon --reuseaddr flag does but of course it is hard to check. - The fourth best behavior would be to convince git daemon that EADDRINUSE is fatal so runit keeps on trying to relaunch the daemon until all its addresses are available. - Of course better is to run separate daemons for ipv4 and ipv6. Thoughts? Jonathan [1] In one terminal I start the daemon and clear its log: # sv stop git-daemon ok: down: git-daemon: 1s, normally up # sh -c '>/var/log/git-daemon/current' # sv start git-daemon ok: run: git-daemon: (pid 6070) 0s Great. Now in another terminal I start a connection: $ git clone git://localhost/git/git.git Cloning into git... remote: Counting objects: 113028, done. Back in the first terminal, I brutally interrupt the daemon, to see how the supervision copes. # killall -9 git-daemon Great, it seems! The clone continues unhindered (I think the process actually transmitting data is git upload-pack). The log informs me that all is well. # cat /var/log/git-daemon/run 2011-01-09_06:29:43.06660 git-daemon starting. 2011-01-09_06:30:01.26329 [6074] Connection from [::1]:33407 2011-01-09_06:30:01.26340 [6074] Extended attributes (16 bytes) exist <host=localhost> 2011-01-09_06:30:01.26429 [6074] Request upload-pack for '/git/git.git' 2011-01-09_06:30:05.41074 git-daemon starting. Now again. $ rm -fr git; git clone git://localhost/git/git.git Cloning into git... localhost[0: ::1]: errno=Connection refused remote: Counting objects: 19469 Interrupting the daemon: # killall -9 git-daemon The clone continues unhindered. Log: # sudo cat /var/log/git-daemon/current 2011-01-09_06:29:43.06660 git-daemon starting. 2011-01-09_06:30:01.26329 [6074] Connection from [::1]:33407 2011-01-09_06:30:01.26340 [6074] Extended attributes (16 bytes) exist <host=localhost> 2011-01-09_06:30:01.26429 [6074] Request upload-pack for '/git/git.git' 2011-01-09_06:30:05.41074 git-daemon starting. 2011-01-09_06:31:19.83078 [6091] Connection from 127.0.0.1:39196 2011-01-09_06:31:19.83095 [6091] Extended attributes (16 bytes) exist <host=localhost> 2011-01-09_06:31:19.83206 [6091] Request upload-pack for '/git/git.git' 2011-01-09_06:31:29.42557 git-daemon starting. 2011-01-09_06:31:29.43869 fatal: unable to allocate any listen sockets on port 9418 2011-01-09_06:31:30.44277 git-daemon starting. 2011-01-09_06:31:30.44796 fatal: unable to allocate any listen sockets on port 9418 [3 more failures before it succeeds] -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org