daemon: Set SO_REUSEADDR on listening sockets.
authorMark Wooding <mdw@distorted.org.uk>
Fri, 3 Feb 2006 20:27:04 +0000 (20:27 +0000)
committerJunio C Hamano <junkio@cox.net>
Mon, 6 Feb 2006 00:51:01 +0000 (16:51 -0800)
Without this, you can silently lose the ability to receive IPv4
connections if you stop and restart the daemon.

[jc: tweaked code organization a bit and made this controllable
 from a command line option.]

Signed-off-by: Mark Wooding <mdw@distorted.org.uk>
Signed-off-by: Junio C Hamano <junkio@cox.net>
daemon.c

index 324bb04..dab8c2c 100644 (file)
--- a/daemon.c
+++ b/daemon.c
 
 static int log_syslog;
 static int verbose;
+static int reuseaddr;
 
 static const char daemon_usage[] =
 "git-daemon [--verbose] [--syslog] [--inetd | --port=n] [--export-all]\n"
 "           [--timeout=n] [--init-timeout=n] [--strict-paths]\n"
-"           [--base-path=path] [directory...]";
+"           [--base-path=path] [--reuseaddr] [directory...]";
 
 /* List of acceptable pathname prefixes */
 static char **ok_paths = NULL;
@@ -451,6 +452,16 @@ static void child_handler(int signo)
        }
 }
 
+static int set_reuse_addr(int sockfd)
+{
+       int on = 1;
+
+       if (!reuseaddr)
+               return 0;
+       return setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR,
+                         &on, sizeof(on));
+}
+
 #ifndef NO_IPV6
 
 static int socksetup(int port, int **socklist_p)
@@ -495,6 +506,11 @@ static int socksetup(int port, int **socklist_p)
                }
 #endif
 
+               if (set_reuse_addr(sockfd)) {
+                       close(sockfd);
+                       return 0;       /* not fatal */
+               }
+
                if (bind(sockfd, ai->ai_addr, ai->ai_addrlen) < 0) {
                        close(sockfd);
                        continue;       /* not fatal */
@@ -537,6 +553,11 @@ static int socksetup(int port, int **socklist_p)
        sin.sin_addr.s_addr = htonl(INADDR_ANY);
        sin.sin_port = htons(port);
 
+       if (set_reuse_addr(sockfd)) {
+               close(sockfd);
+               return 0;
+       }
+
        if ( bind(sockfd, (struct sockaddr *)&sin, sizeof sin) < 0 ) {
                close(sockfd);
                return 0;
@@ -663,6 +684,10 @@ int main(int argc, char **argv)
                        base_path = arg+12;
                        continue;
                }
+               if (!strcmp(arg, "--reuseaddr")) {
+                       reuseaddr = 1;
+                       continue;
+               }
                if (!strcmp(arg, "--")) {
                        ok_paths = &argv[i+1];
                        break;