From: Amaury Denoyelle Date: Fri, 22 Sep 2023 13:55:24 +0000 (+0200) Subject: MINOR: proto_reverse_connect: emit log for preconnect X-Git-Tag: v2.9-dev6~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b9bb3b932cefe6e632db699f42bcea61c07471f4;p=thirdparty%2Fhaproxy.git MINOR: proto_reverse_connect: emit log for preconnect Add reporting using send_log() for preconnect operation. This is minimal to ensure we understand the current status of listener in active reverse connect. To limit logging quantity, only important transition are considered. This requires to implement a minimal state machine as a new field in receiver structure. Here are the logs produced : * Initiating : first time preconnect is enabled on a listener * Error : last preconnect attempt interrupted on a connection error * Reaching maxconn : all necessary connections were reversed and are operational on a listener --- diff --git a/include/haproxy/proto_reverse_connect-t.h b/include/haproxy/proto_reverse_connect-t.h new file mode 100644 index 0000000000..4e7a579de9 --- /dev/null +++ b/include/haproxy/proto_reverse_connect-t.h @@ -0,0 +1,14 @@ +#ifndef _HAPROXY_PROTO_REVERSE_CONNECT_H_T +#define _HAPROXY_PROTO_REVERSE_CONNECT_H_T + +/* State for reverse preconnect listener state machine. + * Used to limit log reporting only on state changes. + */ +enum li_preconn_state { + LI_PRECONN_ST_STOP, /* pre-connect task inactive */ + LI_PRECONN_ST_INIT, /* pre-connect task bootstrapped */ + LI_PRECONN_ST_ERR, /* last pre-connect attempt failed */ + LI_PRECONN_ST_FULL, /* pre-connect maxconn reached */ +}; + +#endif /* _HAPROXY_PROTO_REVERSE_CONNECT_H_T */ diff --git a/include/haproxy/receiver-t.h b/include/haproxy/receiver-t.h index 6b1c2c6167..f7c934726e 100644 --- a/include/haproxy/receiver-t.h +++ b/include/haproxy/receiver-t.h @@ -27,6 +27,7 @@ #include #include +#include #include /* Bit values for receiver->flags */ @@ -83,6 +84,7 @@ struct receiver { struct task *task; /* Task used to open connection for reverse. */ struct server *srv; /* Underlying server used to initiate reverse pre-connect. */ struct connection *pend_conn; /* Pending connection waiting to complete reversal before being accepted. */ + enum li_preconn_state state; /* State for transition logging. */ } reverse_connect; /* warning: this struct is huge, keep it at the bottom */ diff --git a/src/connection.c b/src/connection.c index 9c127c0fb1..96e8818e0e 100644 --- a/src/connection.c +++ b/src/connection.c @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/proto_reverse_connect.c b/src/proto_reverse_connect.c index 6b6fc5035a..a419215396 100644 --- a/src/proto_reverse_connect.c +++ b/src/proto_reverse_connect.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -117,6 +118,13 @@ void rev_notify_preconn_err(struct listener *l) /* Remove reference to the freed connection. */ l->rx.reverse_connect.pend_conn = NULL; + if (l->rx.reverse_connect.state != LI_PRECONN_ST_ERR) { + send_log(l->bind_conf->frontend, LOG_ERR, + "preconnect %s::%s: Error encountered.\n", + l->bind_conf->frontend->id, l->bind_conf->reverse_srvname); + l->rx.reverse_connect.state = LI_PRECONN_ST_ERR; + } + /* Rearm a new preconnect attempt. */ l->rx.reverse_connect.task->expire = MS_TO_TICKS(now_ms + 1000); task_queue(l->rx.reverse_connect.task); @@ -182,6 +190,7 @@ int rev_bind_listener(struct listener *listener, char *errmsg, int errlen) task->process = rev_process; task->context = listener; listener->rx.reverse_connect.task = task; + listener->rx.reverse_connect.state = LI_PRECONN_ST_STOP; /* Set a default maxconn to 1. This ensures listener is properly * reenable each time we fall back below it on connection error. @@ -241,11 +250,25 @@ int rev_bind_listener(struct listener *listener, char *errmsg, int errlen) void rev_enable_listener(struct listener *l) { + if (l->rx.reverse_connect.state < LI_PRECONN_ST_INIT) { + send_log(l->bind_conf->frontend, LOG_INFO, + "preconnect %s::%s: Initiating.\n", + l->bind_conf->frontend->id, l->bind_conf->reverse_srvname); + l->rx.reverse_connect.state = LI_PRECONN_ST_INIT; + } + task_wakeup(l->rx.reverse_connect.task, TASK_WOKEN_ANY); } void rev_disable_listener(struct listener *l) { + if (l->rx.reverse_connect.state < LI_PRECONN_ST_FULL) { + send_log(l->bind_conf->frontend, LOG_INFO, + "preconnect %s::%s: Reaching maxconn %d.\n", + l->bind_conf->frontend->id, l->bind_conf->reverse_srvname, + l->bind_conf->maxconn); + l->rx.reverse_connect.state = LI_PRECONN_ST_FULL; + } } struct connection *rev_accept_conn(struct listener *l, int *status)