diff options
author | Willy Tarreau <w@1wt.eu> | 2020-09-25 19:40:31 +0200 |
---|---|---|
committer | Willy Tarreau <w@1wt.eu> | 2020-10-07 18:45:03 +0200 |
commit | 4597b6031268ca5940f272023ee4d1e61ff83cb6 (patch) | |
tree | ea3665b7396121d03eb01ffe21f6d4baa5250008 | |
parent | 6b4780d029dfe1ab5709f9efd749df7a634740e1 (diff) | |
download | haproxy-4597b6031268ca5940f272023ee4d1e61ff83cb6.tar.gz |
MINOR: protocol: implement an ->rx_resume() method
This one undoes ->rx_suspend(), it tries to restore an operational socket.
It was only implemented for TCP since it's the only one we support right
now.
-rw-r--r-- | include/haproxy/protocol-t.h | 6 | ||||
-rw-r--r-- | src/proto_tcp.c | 20 |
2 files changed, 24 insertions, 2 deletions
diff --git a/include/haproxy/protocol-t.h b/include/haproxy/protocol-t.h index 75da65b46..3d5ce82cd 100644 --- a/include/haproxy/protocol-t.h +++ b/include/haproxy/protocol-t.h @@ -74,8 +74,9 @@ struct proto_fam { /* This structure contains all information needed to easily handle a protocol. * Its primary goal is to ease listeners maintenance. Specifically, the - * bind() primitive must be used before any fork(). rx_* may be null if the - * protocol doesn't provide direct access to the receiver. + * bind() primitive must be used before any fork(). rx_suspend()/rx_resume() + * return >0 on success, 0 if rx stopped, -1 on failure to proceed. rx_* may + * be null if the protocol doesn't provide direct access to the receiver. */ struct protocol { char name[PROTO_NAME_LEN]; /* protocol name, zero-terminated */ @@ -91,6 +92,7 @@ struct protocol { /* functions acting on the receiver */ int (*rx_suspend)(struct receiver *rx); /* temporarily suspend this receiver for a soft restart */ + int (*rx_resume)(struct receiver *rx); /* try to resume a temporarily suspended receiver */ /* functions acting on connections */ void (*accept)(int fd); /* generic accept function */ diff --git a/src/proto_tcp.c b/src/proto_tcp.c index fdfb2899b..81eda1428 100644 --- a/src/proto_tcp.c +++ b/src/proto_tcp.c @@ -46,6 +46,7 @@ static int tcp_bind_listener(struct listener *listener, char *errmsg, int errlen); static int tcp_suspend_receiver(struct receiver *rx); +static int tcp_resume_receiver(struct receiver *rx); static void tcpv4_add_listener(struct listener *listener, int port); static void tcpv6_add_listener(struct listener *listener, int port); @@ -60,6 +61,7 @@ static struct protocol proto_tcpv4 = { .add = tcpv4_add_listener, .listen = tcp_bind_listener, .rx_suspend = tcp_suspend_receiver, + .rx_resume = tcp_resume_receiver, .accept = &listener_accept, .connect = tcp_connect_server, .receivers = LIST_HEAD_INIT(proto_tcpv4.receivers), @@ -79,6 +81,7 @@ static struct protocol proto_tcpv6 = { .add = tcpv6_add_listener, .listen = tcp_bind_listener, .rx_suspend = tcp_suspend_receiver, + .rx_resume = tcp_resume_receiver, .accept = &listener_accept, .connect = tcp_connect_server, .receivers = LIST_HEAD_INIT(proto_tcpv6.receivers), @@ -746,6 +749,23 @@ static int tcp_suspend_receiver(struct receiver *rx) return 1; } +/* Resume a receiver. Returns < 0 in case of failure, 0 if the receiver + * was totally stopped, or > 0 if correctly suspended. + */ +static int tcp_resume_receiver(struct receiver *rx) +{ + struct listener *l = LIST_ELEM(rx, struct listener *, rx); + + if (rx->fd < 0) + return 0; + + if (listen(rx->fd, listener_backlog(l)) == 0) { + fd_want_recv(l->rx.fd); + return 1; + } + return -1; +} + /* * Local variables: |