enable SO_KEEPALIVE for connected TCP sockets

Sockets may never receive notification of some link errors, causing "git fetch" or similar processes to hang forever. Enabling keepalive messages allows hung processes to error out after a few minutes/hours depending on the keepalive settings of the system. This is a problem noticed when running non-interactive cronjobs to mirror repositories using "git fetch". Signed-off-by: Eric Wong <normalperson@yhbt.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Eric Wong committed Dec 6, 2011 at 04:39 UTC e47a8583a20256851e7fc882233e3bd5bf33dc6e
1 file changed +13
connect.c
+13
@@ -175,6 +175,15 @@ static void get_host_and_port(char **host, const char **port)
175 }
176 }
177
178 +static void enable_keepalive(int sockfd)
179 +{
180 + int ka = 1;
181 +
182 + if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &ka, sizeof(ka)) < 0)
183 + fprintf(stderr, "unable to set SO_KEEPALIVE on socket: %s\n",
184 + strerror(errno));
185 +}
186 +
187 #ifndef NO_IPV6
188
189 static const char *ai_name(const struct addrinfo *ai)
@@ -239,6 +248,8 @@ static int git_tcp_connect_sock(char *host, int flags)
248 if (sockfd < 0)
249 die("unable to connect to %s:\n%s", host, error_message.buf);
250
251 + enable_keepalive(sockfd);
252 +
253 if (flags & CONNECT_VERBOSE)
254 fprintf(stderr, "done.\n");
255
@@ -315,6 +326,8 @@ static int git_tcp_connect_sock(char *host, int flags)
326 if (sockfd < 0)
327 die("unable to connect a socket (%s)", strerror(saved_errno));
328
329 + enable_keepalive(sockfd);
330 +
331 if (flags & CONNECT_VERBOSE)
332 fprintf(stderr, "done.\n");
333