MEDIUM: listener: implement a per-protocol pause() function
In order to fix the abstact socket pause mechanism during soft restarts,
we'll need to proceed differently depending on the socket protocol. The
pause_listener() function already supports some protocol-specific handling
for the TCP case.
This commit makes this cleaner by adding a new ->pause() function to the
protocol struct, which, if defined, may be used to pause a listener of a
given protocol.
For now, only TCP has been adapted, with the specific code moved from
pause_listener() to tcp_pause_listener().
(cherry picked from commit 092d865c53de80afc847c5ff0a079b414041ce2a)
diff --git a/src/proto_tcp.c b/src/proto_tcp.c
index e9dbc9c..9778856 100644
--- a/src/proto_tcp.c
+++ b/src/proto_tcp.c
@@ -80,6 +80,7 @@
.get_src = tcp_get_src,
.get_dst = tcp_get_dst,
.drain = tcp_drain,
+ .pause = tcp_pause_listener,
.listeners = LIST_HEAD_INIT(proto_tcpv4.listeners),
.nb_listeners = 0,
};
@@ -102,6 +103,7 @@
.get_src = tcp_get_src,
.get_dst = tcp_get_dst,
.drain = tcp_drain,
+ .pause = tcp_pause_listener,
.listeners = LIST_HEAD_INIT(proto_tcpv6.listeners),
.nb_listeners = 0,
};
@@ -947,6 +949,22 @@
proto_tcpv6.nb_listeners++;
}
+/* Pause a listener. Returns < 0 in case of failure, 0 if the listener
+ * was totally stopped, or > 0 if correctly paused.
+ */
+int tcp_pause_listener(struct listener *l)
+{
+ if (shutdown(l->fd, SHUT_WR) != 0)
+ return -1; /* Solaris dies here */
+
+ if (listen(l->fd, l->backlog ? l->backlog : l->maxconn) != 0)
+ return -1; /* OpenBSD dies here */
+
+ if (shutdown(l->fd, SHUT_RD) != 0)
+ return -1; /* should always be OK */
+ return 1;
+}
+
/* This function performs the TCP request analysis on the current request. It
* returns 1 if the processing can continue on next analysers, or zero if it
* needs more data, encounters an error, or wants to immediately abort the