From ceebdfce40d278d17ecfb82afdffc41a8cc1cc94 Mon Sep 17 00:00:00 2001
From: Jonathan Rose <jrose@digium.com>
Date: Thu, 10 Dec 2015 11:44:03 -0600
Subject: [PATCH] chan_sip: Add TCP/TLS keepalive to TCP/TLS server

Adds the TCP Keep Alive option to TCP and TLS server sockets. Previously
this option was only being set on session sockets.
http://www.tldp.org/HOWTO/html_single/TCP-Keepalive-HOWTO/
According to the link above, the SO_KEEPALIVE option is useful for knowing
when a TCP connected endpoint has severed communication without indicating
it or has become unreachable for some reason. Without this patch, keep
alive is not set on the socket listening for incoming TCP sessions and
in Komatsu's report this resulted in the thread listening for TCP becoming
stuck in a waiting state.

ASTERISK-25364 #close
Reported by: Hiroaki Komatsu

Change-Id: I7ed7bcfa982b367dc64b4b73fbd962da49b9af36
---
 channels/chan_sip.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index cc73a15054..378774a92b 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -32289,6 +32289,12 @@ static int reload_config(enum channelreloadreason reason)
 		ast_log(LOG_ERROR, "SIP TCP Server start failed. Not listening on TCP socket.\n");
 	} else {
 		ast_debug(2, "SIP TCP server started\n");
+		if (sip_tcp_desc.accept_fd >= 0) {
+			int flags = 1;
+			if (setsockopt(sip_tcp_desc.accept_fd, SOL_SOCKET, SO_KEEPALIVE, &flags, sizeof(flags))) {
+				ast_log(LOG_ERROR, "Error enabling TCP keep-alive on sip socket: %s\n", strerror(errno));
+			}
+		}
 	}
 
 	/* Start TLS server if needed */
@@ -32309,6 +32315,13 @@ static int reload_config(enum channelreloadreason reason)
 			ast_log(LOG_ERROR, "TLS Server start failed. Not listening on TLS socket.\n");
 			sip_tls_desc.tls_cfg = NULL;
 		}
+		if (sip_tls_desc.accept_fd >= 0) {
+			int flags = 1;
+			if (setsockopt(sip_tls_desc.accept_fd, SOL_SOCKET, SO_KEEPALIVE, &flags, sizeof(flags))) {
+				ast_log(LOG_ERROR, "Error enabling TCP keep-alive on sip socket: %s\n", strerror(errno));
+				sip_tls_desc.tls_cfg = NULL;
+			}
+		}
 	} else if (sip_tls_desc.tls_cfg->enabled) {
 		sip_tls_desc.tls_cfg = NULL;
 		ast_log(LOG_WARNING, "SIP TLS server did not load because of errors.\n");
-- 
GitLab