[sr-dev] git:master:e46c90c5: core: add an option to trigger also an RST on tcp connection close

Daniel-Constantin Mierla miconda at gmail.com
Mon May 16 08:01:06 CEST 2022


Module: kamailio
Branch: master
Commit: e46c90c5ca98a9fba08382686c25c707efd57bf3
URL: https://github.com/kamailio/kamailio/commit/e46c90c5ca98a9fba08382686c25c707efd57bf3

Author: Rick Barenthin <rick at ng-voice.com>
Committer: Daniel-Constantin Mierla <miconda at gmail.com>
Date: 2022-05-16T08:01:02+02:00

core: add an option to trigger also an RST on tcp connection close

- This gives an option to also send RST in case kamailio closes the
  connection. There are cases where a FIN,ACK back forth leaves
  the connection in the host in TIME_WAIT state, but the ports on both
  sides are fixed. This leads to no request can send until
  the TIME_WAIT state is gone.

---

Modified: src/core/cfg.lex
Modified: src/core/cfg.y
Modified: src/core/tcp_main.c
Modified: src/core/tcp_options.c
Modified: src/core/tcp_options.h

---

Diff:  https://github.com/kamailio/kamailio/commit/e46c90c5ca98a9fba08382686c25c707efd57bf3.diff
Patch: https://github.com/kamailio/kamailio/commit/e46c90c5ca98a9fba08382686c25c707efd57bf3.patch

---

diff --git a/src/core/cfg.lex b/src/core/cfg.lex
index e5e269ebc0..fc259b2147 100644
--- a/src/core/cfg.lex
+++ b/src/core/cfg.lex
@@ -421,6 +421,7 @@ TCP_OPT_CRLF_PING	"tcp_crlf_ping"
 TCP_OPT_ACCEPT_NO_CL	"tcp_accept_no_cl"
 TCP_OPT_ACCEPT_HEP3	"tcp_accept_hep3"
 TCP_OPT_ACCEPT_HAPROXY	"tcp_accept_haproxy"
+TCP_OPT_CLOSE_RST	"tcp_close_rst"
 TCP_CLONE_RCVBUF	"tcp_clone_rcvbuf"
 TCP_REUSE_PORT		"tcp_reuse_port"
 TCP_WAIT_DATA	"tcp_wait_data"
@@ -917,6 +918,7 @@ IMPORTFILE      "import_file"
 									return TCP_OPT_ACCEPT_HEP3; }
 <INITIAL>{TCP_OPT_ACCEPT_HAPROXY}	{ count(); yylval.strval=yytext;
 									return TCP_OPT_ACCEPT_HAPROXY; }
+<INITIAL>{TCP_OPT_CLOSE_RST}	{ count(); yylval.strval=yytext; return TCP_OPT_CLOSE_RST; }
 <INITIAL>{TCP_CLONE_RCVBUF}		{ count(); yylval.strval=yytext;
 									return TCP_CLONE_RCVBUF; }
 <INITIAL>{TCP_REUSE_PORT}	{ count(); yylval.strval=yytext; return TCP_REUSE_PORT; }
diff --git a/src/core/cfg.y b/src/core/cfg.y
index 7db37bbc09..5b5c51258d 100644
--- a/src/core/cfg.y
+++ b/src/core/cfg.y
@@ -450,6 +450,7 @@ extern char *default_routename;
 %token TCP_OPT_ACCEPT_NO_CL
 %token TCP_OPT_ACCEPT_HEP3
 %token TCP_OPT_ACCEPT_HAPROXY
+%token TCP_OPT_CLOSE_RST
 %token TCP_CLONE_RCVBUF
 %token TCP_REUSE_PORT
 %token TCP_WAIT_DATA
@@ -1301,6 +1302,14 @@ assign_stm:
 		#endif
 	}
 	| TCP_OPT_ACCEPT_HAPROXY EQUAL error { yyerror("boolean value expected"); }
+	| TCP_OPT_CLOSE_RST EQUAL NUMBER {
+         #ifdef USE_TCP
+             tcp_default_cfg.close_rst=$3;
+         #else
+             warn("tcp support not compiled in");
+         #endif
+     }
+     | TCP_OPT_CLOSE_RST EQUAL error { yyerror("boolean value expected"); }
 
 	| TCP_CLONE_RCVBUF EQUAL NUMBER {
 		#ifdef USE_TCP
diff --git a/src/core/tcp_main.c b/src/core/tcp_main.c
index c60ce7f2b2..b046d9a848 100644
--- a/src/core/tcp_main.c
+++ b/src/core/tcp_main.c
@@ -3209,6 +3209,13 @@ inline static void tcpconn_close_main_fd(struct tcp_connection* tcpconn)
 #ifdef TCP_FD_CACHE
 	if (likely(cfg_get(tcp, tcp_cfg, fd_cache))) shutdown(fd, SHUT_RDWR);
 #endif /* TCP_FD_CACHE */
+	if(unlikely(cfg_get(tcp, tcp_cfg, close_rst))) {
+		struct linger sl = {
+				.l_onoff = 1,  /* non-zero value enables linger option in kernel */
+				.l_linger = 0, /* timeout interval in seconds */
+		};
+		setsockopt(fd, SOL_SOCKET, SO_LINGER, &sl, sizeof(sl));
+	}
 	if (unlikely(tcp_safe_close(fd)<0))
 		LM_ERR("(%p): %s close(%d) failed (flags 0x%x): %s (%d)\n", tcpconn,
 					su2a(&tcpconn->rcv.src_su, sizeof(tcpconn->rcv.src_su)),
diff --git a/src/core/tcp_options.c b/src/core/tcp_options.c
index 54f23a0cdb..211bcfb1e9 100644
--- a/src/core/tcp_options.c
+++ b/src/core/tcp_options.c
@@ -110,6 +110,8 @@ static cfg_def_t tcp_cfg_def[] = {
 		"reuse TCP ports "},
 	{ "wait_data_ms",  CFG_VAR_INT | CFG_ATOMIC,      0, 7200000, 0,        0,
 		"wait for data on new tcp connetions (milliseconds)"},
+	{ "close_rst",     CFG_VAR_INT | CFG_READONLY,    0,   1,      0,         0,
+			"trigger an RST on connection close"},
 	/* internal and/or "fixed" versions of some vars
 	   (not supposed to be writeable, read will provide only debugging value*/
 	{ "rd_buf_size", CFG_VAR_INT | CFG_ATOMIC,    512,    16777216,  0,         0,
@@ -167,6 +169,7 @@ void init_tcp_options()
 	tcp_default_cfg.wq_blk_size=DEFAULT_TCP_WBUF_SIZE;
 	tcp_default_cfg.reuse_port=0;
 	tcp_default_cfg.wait_data_ms=5000;
+	tcp_default_cfg.close_rst=0;
 }
 
 
diff --git a/src/core/tcp_options.h b/src/core/tcp_options.h
index 284956647b..dd4d8ac20c 100644
--- a/src/core/tcp_options.h
+++ b/src/core/tcp_options.h
@@ -139,6 +139,7 @@ struct cfg_group_tcp{
 	int accept_no_cl;  /* on/off - accept messages without content-length */
 	int reuse_port;  /* enable SO_REUSEPORT */
 	int wait_data_ms;  /* wait for data in milliseconds */
+	int close_rst; /* on /off trigger an RST on connection close */
 
 	/* internal, "fixed" vars */
 	unsigned int rd_buf_size; /* read buffer size (should be > max. datagram)*/




More information about the sr-dev mailing list