mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-02-28 16:40:37 +00:00
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().
This commit is contained in:
parent
3c5efa2b32
commit
092d865c53
@ -30,6 +30,7 @@
|
||||
int tcp_bind_socket(int fd, int flags, struct sockaddr_storage *local, struct sockaddr_storage *remote);
|
||||
void tcpv4_add_listener(struct listener *listener);
|
||||
void tcpv6_add_listener(struct listener *listener);
|
||||
int tcp_pause_listener(struct listener *l);
|
||||
int tcp_connect_server(struct connection *conn, int data, int delack);
|
||||
int tcp_connect_probe(struct connection *conn);
|
||||
int tcp_get_src(int fd, struct sockaddr *sa, socklen_t salen, int dir);
|
||||
|
@ -60,6 +60,7 @@ struct protocol {
|
||||
int (*get_src)(int fd, struct sockaddr *, socklen_t, int dir); /* syscall used to retrieve src addr */
|
||||
int (*get_dst)(int fd, struct sockaddr *, socklen_t, int dir); /* syscall used to retrieve dst addr */
|
||||
int (*drain)(int fd); /* indicates whether we can safely close the fd */
|
||||
int (*pause)(struct listener *l); /* temporarily pause this listener for a soft restart */
|
||||
|
||||
struct list listeners; /* list of listeners using this protocol */
|
||||
int nb_listeners; /* number of listeners */
|
||||
|
@ -95,15 +95,16 @@ int pause_listener(struct listener *l)
|
||||
if (l->state <= LI_PAUSED)
|
||||
return 1;
|
||||
|
||||
if (l->proto->sock_prot == IPPROTO_TCP) {
|
||||
if (shutdown(l->fd, SHUT_WR) != 0)
|
||||
return 0; /* Solaris dies here */
|
||||
if (l->proto->pause) {
|
||||
/* Returns < 0 in case of failure, 0 if the listener
|
||||
* was totally stopped, or > 0 if correctly paused.
|
||||
*/
|
||||
int ret = l->proto->pause(l);
|
||||
|
||||
if (listen(l->fd, l->backlog ? l->backlog : l->maxconn) != 0)
|
||||
return 0; /* OpenBSD dies here */
|
||||
|
||||
if (shutdown(l->fd, SHUT_RD) != 0)
|
||||
return 0; /* should always be OK */
|
||||
if (ret < 0)
|
||||
return 0;
|
||||
else if (ret == 0)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (l->state == LI_LIMITED)
|
||||
|
@ -80,6 +80,7 @@ static struct protocol proto_tcpv4 = {
|
||||
.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 @@ static struct protocol proto_tcpv6 = {
|
||||
.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 @@ void tcpv6_add_listener(struct listener *listener)
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user