--- /dev/null
+#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 */
#include <haproxy/api-t.h>
#include <haproxy/namespace-t.h>
+#include <haproxy/proto_reverse_connect-t.h>
#include <haproxy/thread.h>
/* Bit values for receiver->flags */
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 */
#include <haproxy/errors.h>
#include <haproxy/list.h>
#include <haproxy/listener.h>
+#include <haproxy/log.h>
#include <haproxy/proto_tcp.h>
#include <haproxy/protocol.h>
#include <haproxy/proxy.h>
/* 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);
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.
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)