daemon: enable SO_KEEPALIVE for all sockets

While --init-timeout and --timeout options exist and I've never run git-daemon without them, some users may forget to set them and encounter hung daemon processes when connections fail. Enable socket-level timeouts so the kernel can send keepalive probes as necessary to detect failed connections. Signed-off-by: Eric Wong <e@80x24.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Eric Wong committed May 25, 2016 at 03:15 UTC a43b68a196652a0c6b054ee4905ac98d1cdcbbb9
1 file changed +14
daemon.c
+14
@@ -669,6 +669,15 @@ static void hostinfo_clear(struct hostinfo *hi)
669 strbuf_release(&hi->tcp_port);
670 }
671
672 +static void set_keep_alive(int sockfd)
673 +{
674 + int ka = 1;
675 +
676 + if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &ka, sizeof(ka)) < 0)
677 + logerror("unable to set SO_KEEPALIVE on socket: %s",
678 + strerror(errno));
679 +}
680 +
681 static int execute(void)
682 {
683 char *line = packet_buffer;
@@ -681,6 +690,7 @@ static int execute(void)
690 if (addr)
691 loginfo("Connection from %s:%s", addr, port);
692
693 + set_keep_alive(0);
694 alarm(init_timeout ? init_timeout : timeout);
695 pktlen = packet_read(0, NULL, NULL, packet_buffer, sizeof(packet_buffer), 0);
696 alarm(0);
@@ -951,6 +961,8 @@ static int setup_named_sock(char *listen_addr, int listen_port, struct socketlis
961 continue;
962 }
963
964 + set_keep_alive(sockfd);
965 +
966 if (bind(sockfd, ai->ai_addr, ai->ai_addrlen) < 0) {
967 logerror("Could not bind to %s: %s",
968 ip2str(ai->ai_family, ai->ai_addr, ai->ai_addrlen),
@@ -1010,6 +1022,8 @@ static int setup_named_sock(char *listen_addr, int listen_port, struct socketlis
1022 return 0;
1023 }
1024
1025 + set_keep_alive(sockfd);
1026 +
1027 if ( bind(sockfd, (struct sockaddr *)&sin, sizeof sin) < 0 ) {
1028 logerror("Could not bind to %s: %s",
1029 ip2str(AF_INET, (struct sockaddr *)&sin, sizeof(sin)),