... | ... |
@@ -421,6 +421,7 @@ TCP_OPT_CRLF_PING "tcp_crlf_ping" |
421 | 421 |
TCP_OPT_ACCEPT_NO_CL "tcp_accept_no_cl" |
422 | 422 |
TCP_OPT_ACCEPT_HEP3 "tcp_accept_hep3" |
423 | 423 |
TCP_OPT_ACCEPT_HAPROXY "tcp_accept_haproxy" |
424 |
+TCP_OPT_CLOSE_RST "tcp_close_rst" |
|
424 | 425 |
TCP_CLONE_RCVBUF "tcp_clone_rcvbuf" |
425 | 426 |
TCP_REUSE_PORT "tcp_reuse_port" |
426 | 427 |
TCP_WAIT_DATA "tcp_wait_data" |
... | ... |
@@ -917,6 +918,7 @@ IMPORTFILE "import_file" |
917 | 918 |
return TCP_OPT_ACCEPT_HEP3; } |
918 | 919 |
<INITIAL>{TCP_OPT_ACCEPT_HAPROXY} { count(); yylval.strval=yytext; |
919 | 920 |
return TCP_OPT_ACCEPT_HAPROXY; } |
921 |
+<INITIAL>{TCP_OPT_CLOSE_RST} { count(); yylval.strval=yytext; return TCP_OPT_CLOSE_RST; } |
|
920 | 922 |
<INITIAL>{TCP_CLONE_RCVBUF} { count(); yylval.strval=yytext; |
921 | 923 |
return TCP_CLONE_RCVBUF; } |
922 | 924 |
<INITIAL>{TCP_REUSE_PORT} { count(); yylval.strval=yytext; return TCP_REUSE_PORT; } |
... | ... |
@@ -450,6 +450,7 @@ extern char *default_routename; |
450 | 450 |
%token TCP_OPT_ACCEPT_NO_CL |
451 | 451 |
%token TCP_OPT_ACCEPT_HEP3 |
452 | 452 |
%token TCP_OPT_ACCEPT_HAPROXY |
453 |
+%token TCP_OPT_CLOSE_RST |
|
453 | 454 |
%token TCP_CLONE_RCVBUF |
454 | 455 |
%token TCP_REUSE_PORT |
455 | 456 |
%token TCP_WAIT_DATA |
... | ... |
@@ -1301,6 +1302,14 @@ assign_stm: |
1301 | 1302 |
#endif |
1302 | 1303 |
} |
1303 | 1304 |
| TCP_OPT_ACCEPT_HAPROXY EQUAL error { yyerror("boolean value expected"); } |
1305 |
+ | TCP_OPT_CLOSE_RST EQUAL NUMBER { |
|
1306 |
+ #ifdef USE_TCP |
|
1307 |
+ tcp_default_cfg.close_rst=$3; |
|
1308 |
+ #else |
|
1309 |
+ warn("tcp support not compiled in"); |
|
1310 |
+ #endif |
|
1311 |
+ } |
|
1312 |
+ | TCP_OPT_CLOSE_RST EQUAL error { yyerror("boolean value expected"); } |
|
1304 | 1313 |
|
1305 | 1314 |
| TCP_CLONE_RCVBUF EQUAL NUMBER { |
1306 | 1315 |
#ifdef USE_TCP |
... | ... |
@@ -3209,6 +3209,13 @@ inline static void tcpconn_close_main_fd(struct tcp_connection* tcpconn) |
3209 | 3209 |
#ifdef TCP_FD_CACHE |
3210 | 3210 |
if (likely(cfg_get(tcp, tcp_cfg, fd_cache))) shutdown(fd, SHUT_RDWR); |
3211 | 3211 |
#endif /* TCP_FD_CACHE */ |
3212 |
+ if(unlikely(cfg_get(tcp, tcp_cfg, close_rst))) { |
|
3213 |
+ struct linger sl = { |
|
3214 |
+ .l_onoff = 1, /* non-zero value enables linger option in kernel */ |
|
3215 |
+ .l_linger = 0, /* timeout interval in seconds */ |
|
3216 |
+ }; |
|
3217 |
+ setsockopt(fd, SOL_SOCKET, SO_LINGER, &sl, sizeof(sl)); |
|
3218 |
+ } |
|
3212 | 3219 |
if (unlikely(tcp_safe_close(fd)<0)) |
3213 | 3220 |
LM_ERR("(%p): %s close(%d) failed (flags 0x%x): %s (%d)\n", tcpconn, |
3214 | 3221 |
su2a(&tcpconn->rcv.src_su, sizeof(tcpconn->rcv.src_su)), |
... | ... |
@@ -110,6 +110,8 @@ static cfg_def_t tcp_cfg_def[] = { |
110 | 110 |
"reuse TCP ports "}, |
111 | 111 |
{ "wait_data_ms", CFG_VAR_INT | CFG_ATOMIC, 0, 7200000, 0, 0, |
112 | 112 |
"wait for data on new tcp connetions (milliseconds)"}, |
113 |
+ { "close_rst", CFG_VAR_INT | CFG_READONLY, 0, 1, 0, 0, |
|
114 |
+ "trigger an RST on connection close"}, |
|
113 | 115 |
/* internal and/or "fixed" versions of some vars |
114 | 116 |
(not supposed to be writeable, read will provide only debugging value*/ |
115 | 117 |
{ "rd_buf_size", CFG_VAR_INT | CFG_ATOMIC, 512, 16777216, 0, 0, |
... | ... |
@@ -167,6 +169,7 @@ void init_tcp_options() |
167 | 169 |
tcp_default_cfg.wq_blk_size=DEFAULT_TCP_WBUF_SIZE; |
168 | 170 |
tcp_default_cfg.reuse_port=0; |
169 | 171 |
tcp_default_cfg.wait_data_ms=5000; |
172 |
+ tcp_default_cfg.close_rst=0; |
|
170 | 173 |
} |
171 | 174 |
|
172 | 175 |
|
... | ... |
@@ -139,6 +139,7 @@ struct cfg_group_tcp{ |
139 | 139 |
int accept_no_cl; /* on/off - accept messages without content-length */ |
140 | 140 |
int reuse_port; /* enable SO_REUSEPORT */ |
141 | 141 |
int wait_data_ms; /* wait for data in milliseconds */ |
142 |
+ int close_rst; /* on /off trigger an RST on connection close */ |
|
142 | 143 |
|
143 | 144 |
/* internal, "fixed" vars */ |
144 | 145 |
unsigned int rd_buf_size; /* read buffer size (should be > max. datagram)*/ |