Browse code

Merge 2e19bb711453264e063a9e202255c3bc80508d49 into 6ce9c3c897055ff9942634c493caf79780ccf71b

vlitvinov authored on 04/01/2022 10:09:00 • GitHub committed on 04/01/2022 10:09:00
Showing 3 changed files
... ...
@@ -193,12 +193,22 @@ typedef struct tcp_conn_alias {
193 193
 #endif
194 194
 
195 195
 
196
+enum tcp_closed_reason {
197
+	TCP_CLOSED_EOF = 0,
198
+	TCP_CLOSED_TIMEOUT,
199
+	TCP_CLOSED_RESET,
200
+
201
+	_TCP_CLOSED_REASON_MAX /* /!\ keep this one always at the end */
202
+};
203
+
204
+
196 205
 typedef struct tcp_connection {
197 206
 	int s; /*socket, used by "tcp main" */
198 207
 	int fd; /* used only by "children", don't modify it! private data! */
199 208
 	gen_lock_t write_lock;
200 209
 	int id; /* id (unique!) used to retrieve a specific connection when
201 210
 			 * reply-ing */
211
+	enum tcp_closed_reason event; /* connection close reason */
202 212
 	int reader_pid; /* pid of the active reader process */
203 213
 	struct receive_info rcv; /* src & dst ip, ports, proto a.s.o*/
204 214
 	ksr_coninfo_t cinfo; /* connection info (e.g., for haproxy ) */
... ...
@@ -343,14 +353,6 @@ typedef struct tcp_event_info {
343 353
 	struct tcp_connection *con;
344 354
 } tcp_event_info_t;
345 355
 
346
-enum tcp_closed_reason {
347
-	TCP_CLOSED_EOF = 0,
348
-	TCP_CLOSED_TIMEOUT,
349
-	TCP_CLOSED_RESET,
350
-
351
-	_TCP_CLOSED_REASON_MAX /* /!\ keep this one always at the end */
352
-};
353
-
354 356
 typedef struct tcp_closed_event_info {
355 357
 	enum tcp_closed_reason reason;
356 358
 	struct tcp_connection *con;
... ...
@@ -79,6 +79,7 @@
79 79
 #include "tcp_stats.h"
80 80
 #include "tcp_ev.h"
81 81
 #include "tsend.h"
82
+#include "events.h"
82 83
 #include "timer_ticks.h"
83 84
 #include "local_timer.h"
84 85
 #ifdef CORE_TLS
... ...
@@ -3548,6 +3549,33 @@ again:
3548 3549
 }
3549 3550
 
3550 3551
 
3552
+static int tcp_emit_closed_event(struct tcp_connection *con)
3553
+{
3554
+	int ret;
3555
+	tcp_closed_event_info_t tev;
3556
+	sr_event_param_t evp = {0};
3557
+	enum tcp_closed_reason reason;
3558
+
3559
+	if (con->event) {
3560
+		reason = con->event;
3561
+	} else {
3562
+		reason = TCP_CLOSED_EOF;
3563
+	}
3564
+
3565
+	ret = 0;
3566
+	LM_DBG("TCP closed event creation triggered (reason: %d)\n", reason);
3567
+	if(likely(sr_event_enabled(SREV_TCP_CLOSED))) {
3568
+		memset(&tev, 0, sizeof(tcp_closed_event_info_t));
3569
+		tev.reason = reason;
3570
+		tev.con = con;
3571
+		evp.data = (void*)(&tev);
3572
+		ret = sr_event_exec(SREV_TCP_CLOSED, &evp);
3573
+	} else {
3574
+		LM_DBG("no callback registering for handling TCP closed event\n");
3575
+	}
3576
+	return ret;
3577
+}
3578
+
3551 3579
 
3552 3580
 /* handles io from a tcp child process
3553 3581
  * params: tcp_c - pointer in the tcp_children array, to the entry for
... ...
@@ -3628,6 +3656,7 @@ inline static int handle_tcp_child(struct tcp_child* tcp_c, int fd_i)
3628 3656
 				/* if refcnt was 1 => it was used only in the
3629 3657
 				   tcp reader => it's not hashed or watched for IO
3630 3658
 				   anymore => no need to io_watch_del() */
3659
+				tcp_emit_closed_event(tcpconn);
3631 3660
 				tcpconn_destroy(tcpconn);
3632 3661
 				break;
3633 3662
 			}
... ...
@@ -3639,6 +3668,7 @@ inline static int handle_tcp_child(struct tcp_child* tcp_c, int fd_i)
3639 3668
 						tcpconn->flags &= ~F_CONN_WRITE_W;
3640 3669
 					}
3641 3670
 #endif /* TCP_ASYNC */
3671
+					tcp_emit_closed_event(tcpconn);
3642 3672
 					tcpconn_put_destroy(tcpconn);
3643 3673
 				}
3644 3674
 #ifdef TCP_ASYNC
... ...
@@ -3690,6 +3720,8 @@ inline static int handle_tcp_child(struct tcp_child* tcp_c, int fd_i)
3690 3720
 							io_watch_del(&io_h, tcpconn->s, -1, IO_FD_CLOSING);
3691 3721
 							tcpconn->flags&=~F_CONN_WRITE_W;
3692 3722
 						}
3723
+						tcpconn->event = TCP_CLOSED_TIMEOUT;
3724
+						tcp_emit_closed_event(tcpconn);
3693 3725
 						tcpconn_put_destroy(tcpconn);
3694 3726
 					} else if (unlikely(tcpconn->flags & F_CONN_WRITE_W)){
3695 3727
 						BUG("unhashed connection watched for write\n");
... ...
@@ -3726,6 +3758,7 @@ inline static int handle_tcp_child(struct tcp_child* tcp_c, int fd_i)
3726 3758
 						tcpconn->flags&=~F_CONN_WRITE_W;
3727 3759
 					}
3728 3760
 #endif /* TCP_ASYNC */
3761
+					tcp_emit_closed_event(tcpconn);
3729 3762
 					tcpconn_put_destroy(tcpconn);
3730 3763
 				}
3731 3764
 #ifdef TCP_ASYNC
... ...
@@ -3757,6 +3790,7 @@ inline static int handle_tcp_child(struct tcp_child* tcp_c, int fd_i)
3757 3790
 #endif /* TCP_ASYNC */
3758 3791
 				if (tcpconn_try_unhash(tcpconn))
3759 3792
 					tcpconn_put(tcpconn);
3793
+				tcp_emit_closed_event(tcpconn);
3760 3794
 				tcpconn_put_destroy(tcpconn); /* deref & delete if refcnt==0 */
3761 3795
 				break;
3762 3796
 		default:
... ...
@@ -174,26 +174,6 @@ int tcp_http11_continue(struct tcp_connection *c)
174 174
 }
175 175
 #endif /* HTTP11 */
176 176
 
177
-static int tcp_emit_closed_event(struct tcp_connection *con, enum tcp_closed_reason reason)
178
-{
179
-	int ret;
180
-	tcp_closed_event_info_t tev;
181
-	sr_event_param_t evp = {0};
182
-
183
-	ret = 0;
184
-	LM_DBG("TCP closed event creation triggered (reason: %d)\n", reason);
185
-	if(likely(sr_event_enabled(SREV_TCP_CLOSED))) {
186
-		memset(&tev, 0, sizeof(tcp_closed_event_info_t));
187
-		tev.reason = reason;
188
-		tev.con = con;
189
-		evp.data = (void*)(&tev);
190
-		ret = sr_event_exec(SREV_TCP_CLOSED, &evp);
191
-	} else {
192
-		LM_DBG("no callback registering for handling TCP closed event\n");
193
-	}
194
-	return ret;
195
-}
196
-
197 177
 
198 178
 /** reads data from an existing tcp connection.
199 179
  * Side-effects: blocklisting, sets connection state to S_CONN_OK, tcp stats.
... ...
@@ -289,9 +269,9 @@ again:
289 269
 				LOG(cfg_get(core, core_cfg, corelog),"-> [%s]:%u)\n",
290 270
 						ip_addr2a(&c->rcv.dst_ip), c->rcv.dst_port);
291 271
 				if (errno == ETIMEDOUT) {
292
-					tcp_emit_closed_event(c, TCP_CLOSED_TIMEOUT);
272
+					c->event = TCP_CLOSED_TIMEOUT;
293 273
 				} else if (errno == ECONNRESET) {
294
-					tcp_emit_closed_event(c, TCP_CLOSED_RESET);
274
+					c->event = TCP_CLOSED_RESET;
295 275
 				}
296 276
 				return -1;
297 277
 			}
... ...
@@ -304,7 +284,7 @@ again:
304 284
 					ip_addr2a(&c->rcv.dst_ip), c->rcv.dst_port);
305 285
 			c->state=S_CONN_EOF;
306 286
 			*flags|=RD_CONN_EOF;
307
-			tcp_emit_closed_event(c, TCP_CLOSED_EOF);
287
+			c->event=TCP_CLOSED_EOF;
308 288
 		}else{
309 289
 			if (unlikely(c->state==S_CONN_CONNECT || c->state==S_CONN_ACCEPT)){
310 290
 				TCP_STATS_ESTABLISHED(c->state);
... ...
@@ -1696,6 +1676,7 @@ static ticks_t tcpconn_read_timeout(ticks_t t, struct timer_ln* tl, void* data)
1696 1676
 	}
1697 1677
 	if(tcp_conn_lst!=NULL) {
1698 1678
 		tcpconn_listrm(tcp_conn_lst, c, c_next, c_prev);
1679
+		c->event = TCP_CLOSED_TIMEOUT;
1699 1680
 		release_tcpconn(c, (c->state<0)?CONN_ERROR:CONN_RELEASE, tcpmain_sock);
1700 1681
 	}
1701 1682
 	return 0;