Browse code

tcpclose event_routes issue

Viktor authored on 23/12/2021 22:18:04 • Daniel-Constantin Mierla committed on 07/01/2022 11:23:41
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;
... ...
@@ -3549,11 +3549,18 @@ again:
3549 3549
 }
3550 3550
 
3551 3551
 
3552
-static int tcp_emit_closed_event(struct tcp_connection *con, enum tcp_closed_reason reason)
3552
+static int tcp_emit_closed_event(struct tcp_connection *con)
3553 3553
 {
3554 3554
 	int ret;
3555 3555
 	tcp_closed_event_info_t tev;
3556 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
+	}
3557 3564
 
3558 3565
 	ret = 0;
3559 3566
 	LM_DBG("TCP closed event creation triggered (reason: %d)\n", reason);
... ...
@@ -3649,7 +3656,7 @@ inline static int handle_tcp_child(struct tcp_child* tcp_c, int fd_i)
3649 3656
 				/* if refcnt was 1 => it was used only in the
3650 3657
 				   tcp reader => it's not hashed or watched for IO
3651 3658
 				   anymore => no need to io_watch_del() */
3652
-				tcp_emit_closed_event(tcpconn, TCP_CLOSED_EOF);
3659
+				tcp_emit_closed_event(tcpconn);
3653 3660
 				tcpconn_destroy(tcpconn);
3654 3661
 				break;
3655 3662
 			}
... ...
@@ -3661,7 +3668,7 @@ inline static int handle_tcp_child(struct tcp_child* tcp_c, int fd_i)
3661 3668
 						tcpconn->flags &= ~F_CONN_WRITE_W;
3662 3669
 					}
3663 3670
 #endif /* TCP_ASYNC */
3664
-					tcp_emit_closed_event(tcpconn, TCP_CLOSED_EOF);
3671
+					tcp_emit_closed_event(tcpconn);
3665 3672
 					tcpconn_put_destroy(tcpconn);
3666 3673
 				}
3667 3674
 #ifdef TCP_ASYNC
... ...
@@ -3713,7 +3720,8 @@ inline static int handle_tcp_child(struct tcp_child* tcp_c, int fd_i)
3713 3720
 							io_watch_del(&io_h, tcpconn->s, -1, IO_FD_CLOSING);
3714 3721
 							tcpconn->flags&=~F_CONN_WRITE_W;
3715 3722
 						}
3716
-						tcp_emit_closed_event(tcpconn, TCP_CLOSED_EOF);
3723
+						tcpconn->event = TCP_CLOSED_TIMEOUT;
3724
+						tcp_emit_closed_event(tcpconn);
3717 3725
 						tcpconn_put_destroy(tcpconn);
3718 3726
 					} else if (unlikely(tcpconn->flags & F_CONN_WRITE_W)){
3719 3727
 						BUG("unhashed connection watched for write\n");
... ...
@@ -3750,7 +3758,7 @@ inline static int handle_tcp_child(struct tcp_child* tcp_c, int fd_i)
3750 3758
 						tcpconn->flags&=~F_CONN_WRITE_W;
3751 3759
 					}
3752 3760
 #endif /* TCP_ASYNC */
3753
-					tcp_emit_closed_event(tcpconn, TCP_CLOSED_EOF);
3761
+					tcp_emit_closed_event(tcpconn);
3754 3762
 					tcpconn_put_destroy(tcpconn);
3755 3763
 				}
3756 3764
 #ifdef TCP_ASYNC
... ...
@@ -3782,7 +3790,7 @@ inline static int handle_tcp_child(struct tcp_child* tcp_c, int fd_i)
3782 3790
 #endif /* TCP_ASYNC */
3783 3791
 				if (tcpconn_try_unhash(tcpconn))
3784 3792
 					tcpconn_put(tcpconn);
3785
-				tcp_emit_closed_event(tcpconn, TCP_CLOSED_EOF);
3793
+				tcp_emit_closed_event(tcpconn);
3786 3794
 				tcpconn_put_destroy(tcpconn); /* deref & delete if refcnt==0 */
3787 3795
 				break;
3788 3796
 		default:
... ...
@@ -268,6 +268,11 @@ again:
268 268
 						ip_addr2a(&c->rcv.src_ip), c->rcv.src_port);
269 269
 				LOG(cfg_get(core, core_cfg, corelog),"-> [%s]:%u)\n",
270 270
 						ip_addr2a(&c->rcv.dst_ip), c->rcv.dst_port);
271
+				if (errno == ETIMEDOUT) {
272
+					c->event = TCP_CLOSED_TIMEOUT;
273
+				} else if (errno == ECONNRESET) {
274
+					c->event = TCP_CLOSED_RESET;
275
+				}
271 276
 				return -1;
272 277
 			}
273 278
 		}else if (unlikely((bytes_read==0) ||
... ...
@@ -279,6 +284,7 @@ again:
279 284
 					ip_addr2a(&c->rcv.dst_ip), c->rcv.dst_port);
280 285
 			c->state=S_CONN_EOF;
281 286
 			*flags|=RD_CONN_EOF;
287
+			c->event=TCP_CLOSED_EOF;
282 288
 		}else{
283 289
 			if (unlikely(c->state==S_CONN_CONNECT || c->state==S_CONN_ACCEPT)){
284 290
 				TCP_STATS_ESTABLISHED(c->state);
... ...
@@ -1670,6 +1676,7 @@ static ticks_t tcpconn_read_timeout(ticks_t t, struct timer_ln* tl, void* data)
1670 1676
 	}
1671 1677
 	if(tcp_conn_lst!=NULL) {
1672 1678
 		tcpconn_listrm(tcp_conn_lst, c, c_next, c_prev);
1679
+		c->event = TCP_CLOSED_TIMEOUT;
1673 1680
 		release_tcpconn(c, (c->state<0)?CONN_ERROR:CONN_RELEASE, tcpmain_sock);
1674 1681
 	}
1675 1682
 	return 0;