MINOR: listeners: split do_unbind_listener() in two

The inner part now goes into the protocol and is used to decide how to
unbind a given protocol's listener. The existing code which is able to
also unbind the receiver was provided as a default function that we
currently use everywhere. Some complex listeners like QUIC will use this
to decide how to unbind without impacting existing connections, possibly
by setting up other incoming paths for the traffic.
This commit is contained in:
Willy Tarreau 2020-10-09 17:18:29 +02:00
parent f58b8db47b
commit 7b2febde1d
7 changed files with 34 additions and 11 deletions

View File

@ -124,6 +124,12 @@ int listener_backlog(const struct listener *l);
*/ */
void listener_release(struct listener *l); void listener_release(struct listener *l);
/* default function used to unbind a listener. This is for use by standard
* protocols working on top of accepted sockets. The receiver's rx_unbind()
* will automatically be used after the listener is disabled if the socket is
* still bound. This must be used under the listener's lock.
*/
void default_unbind_listener(struct listener *listener);
/* /*
* Registers the bind keyword list <kwl> as a list of valid keywords for next * Registers the bind keyword list <kwl> as a list of valid keywords for next
* parsing sessions. * parsing sessions.

View File

@ -91,6 +91,7 @@ struct protocol {
int (*listen)(struct listener *l, char *errmsg, int errlen); /* start a listener */ int (*listen)(struct listener *l, char *errmsg, int errlen); /* start a listener */
void (*enable)(struct listener *l); /* enable receipt of new connections */ void (*enable)(struct listener *l); /* enable receipt of new connections */
void (*disable)(struct listener *l); /* disable receipt of new connections */ void (*disable)(struct listener *l); /* disable receipt of new connections */
void (*unbind)(struct listener *l); /* unbind the listener and possibly its receiver */
/* functions acting on the receiver */ /* functions acting on the receiver */
void (*rx_enable)(struct receiver *rx); /* enable receiving on the receiver */ void (*rx_enable)(struct receiver *rx); /* enable receiving on the receiver */

View File

@ -538,18 +538,14 @@ void dequeue_proxy_listeners(struct proxy *px)
} }
} }
/* This function closes the listening socket for the specified listener,
* provided that it's already in a listening state. The listener enters the
* LI_ASSIGNED state, except if the FD is not closed, in which case it may
* remain in LI_LISTEN. Depending on the process' status (master or worker),
* the listener's bind options and the receiver's origin, it may or may not
* close the receiver's FD, according to what is provided at the receiver
* level. Must be called with the lock held.
*/
void do_unbind_listener(struct listener *listener)
{
MT_LIST_DEL(&listener->wait_queue);
/* default function used to unbind a listener. This is for use by standard
* protocols working on top of accepted sockets. The receiver's rx_unbind()
* will automatically be used after the listener is disabled if the socket is
* still bound. This must be used under the listener's lock.
*/
void default_unbind_listener(struct listener *listener)
{
if (listener->state <= LI_ASSIGNED) if (listener->state <= LI_ASSIGNED)
goto out_close; goto out_close;
@ -567,6 +563,20 @@ void do_unbind_listener(struct listener *listener)
out_close: out_close:
if (listener->rx.flags & RX_F_BOUND) if (listener->rx.flags & RX_F_BOUND)
listener->rx.proto->rx_unbind(&listener->rx); listener->rx.proto->rx_unbind(&listener->rx);
}
/* This function closes the listening socket for the specified listener,
* provided that it's already in a listening state. The protocol's unbind()
* is called to put the listener into LI_ASSIGNED or LI_LISTEN and handle
* the unbinding tasks. The listener enters then the LI_ASSIGNED state if
* the receiver is unbound. Must be called with the lock held.
*/
void do_unbind_listener(struct listener *listener)
{
MT_LIST_DEL(&listener->wait_queue);
if (listener->rx.proto->unbind)
listener->rx.proto->unbind(listener);
/* we may have to downgrade the listener if the rx was closed */ /* we may have to downgrade the listener if the rx was closed */
if (!(listener->rx.flags & RX_F_BOUND) && listener->state > LI_ASSIGNED) if (!(listener->rx.flags & RX_F_BOUND) && listener->state > LI_ASSIGNED)

View File

@ -72,6 +72,7 @@ static struct protocol proto_sockpair = {
.listen = sockpair_bind_listener, .listen = sockpair_bind_listener,
.enable = sockpair_enable_listener, .enable = sockpair_enable_listener,
.disable = sockpair_disable_listener, .disable = sockpair_disable_listener,
.unbind = default_unbind_listener,
.rx_unbind = sock_unbind, .rx_unbind = sock_unbind,
.rx_enable = sock_enable, .rx_enable = sock_enable,
.rx_disable = sock_disable, .rx_disable = sock_disable,

View File

@ -64,6 +64,7 @@ static struct protocol proto_tcpv4 = {
.listen = tcp_bind_listener, .listen = tcp_bind_listener,
.enable = tcp_enable_listener, .enable = tcp_enable_listener,
.disable = tcp_disable_listener, .disable = tcp_disable_listener,
.unbind = default_unbind_listener,
.rx_enable = sock_enable, .rx_enable = sock_enable,
.rx_disable = sock_disable, .rx_disable = sock_disable,
.rx_unbind = sock_unbind, .rx_unbind = sock_unbind,
@ -89,6 +90,7 @@ static struct protocol proto_tcpv6 = {
.listen = tcp_bind_listener, .listen = tcp_bind_listener,
.enable = tcp_enable_listener, .enable = tcp_enable_listener,
.disable = tcp_disable_listener, .disable = tcp_disable_listener,
.unbind = default_unbind_listener,
.rx_enable = sock_enable, .rx_enable = sock_enable,
.rx_disable = sock_disable, .rx_disable = sock_disable,
.rx_unbind = sock_unbind, .rx_unbind = sock_unbind,

View File

@ -60,6 +60,7 @@ static struct protocol proto_udp4 = {
.listen = udp_bind_listener, .listen = udp_bind_listener,
.enable = udp_enable_listener, .enable = udp_enable_listener,
.disable = udp_disable_listener, .disable = udp_disable_listener,
.unbind = default_unbind_listener,
.rx_enable = sock_enable, .rx_enable = sock_enable,
.rx_disable = sock_disable, .rx_disable = sock_disable,
.rx_unbind = sock_unbind, .rx_unbind = sock_unbind,
@ -83,6 +84,7 @@ static struct protocol proto_udp6 = {
.listen = udp_bind_listener, .listen = udp_bind_listener,
.enable = udp_enable_listener, .enable = udp_enable_listener,
.disable = udp_disable_listener, .disable = udp_disable_listener,
.unbind = default_unbind_listener,
.rx_enable = sock_enable, .rx_enable = sock_enable,
.rx_disable = sock_disable, .rx_disable = sock_disable,
.rx_unbind = sock_unbind, .rx_unbind = sock_unbind,

View File

@ -59,6 +59,7 @@ static struct protocol proto_unix = {
.listen = uxst_bind_listener, .listen = uxst_bind_listener,
.enable = uxst_enable_listener, .enable = uxst_enable_listener,
.disable = uxst_disable_listener, .disable = uxst_disable_listener,
.unbind = default_unbind_listener,
.rx_enable = sock_enable, .rx_enable = sock_enable,
.rx_disable = sock_disable, .rx_disable = sock_disable,
.rx_unbind = sock_unbind, .rx_unbind = sock_unbind,