MINOR: listener: introduce listener_backlog() to report the backlog value
In an attempt to try to provide automatic maxconn settings, we need to decorrelate a listner's backlog and maxconn so that these values can be independent. This introduces a listener_backlog() function which retrieves the backlog value from the listener's backlog, the frontend's, the listener's maxconn, the frontend's or falls back to 1024. This corresponds to what was done in cfgparse.c to force a value there except the last fallback which was not set since the frontend's maxconn is always known.
This commit is contained in:
parent
4ef6801cd4
commit
e2711c7bd6
@ -10885,7 +10885,7 @@ alpn <protocols>
|
||||
bind :443 ssl crt pub.pem alpn h2,http/1.1
|
||||
|
||||
backlog <backlog>
|
||||
Sets the socket's backlog to this value. If unspecified, the frontend's
|
||||
Sets the socket's backlog to this value. If unspecified or 0, the frontend's
|
||||
backlog is used instead, which generally defaults to the maxconn value.
|
||||
|
||||
curves <curves>
|
||||
|
@ -109,6 +109,12 @@ void delete_listener(struct listener *listener);
|
||||
*/
|
||||
void listener_accept(int fd);
|
||||
|
||||
/* Returns a suitable value for a listener's backlog. It uses the listener's,
|
||||
* otherwise the frontend's backlog, otherwise the listener's maxconn,
|
||||
* otherwise the frontend's maxconn, otherwise 1024.
|
||||
*/
|
||||
int listener_backlog(const struct listener *l);
|
||||
|
||||
/* Notify the listener that a connection initiated from it was released. This
|
||||
* is used to keep the connection count consistent and to possibly re-open
|
||||
* listening when it was limited.
|
||||
|
@ -650,7 +650,6 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
|
||||
l = LIST_ELEM(bind_conf->listeners.n, typeof(l), by_bind);
|
||||
l->maxaccept = 1;
|
||||
l->maxconn = curpeers->peers_fe->maxconn;
|
||||
l->backlog = curpeers->peers_fe->backlog;
|
||||
l->accept = session_accept_fd;
|
||||
l->analysers |= curpeers->peers_fe->fe_req_ana;
|
||||
l->default_target = curpeers->peers_fe->default_target;
|
||||
@ -854,7 +853,6 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
|
||||
l = LIST_ELEM(bind_conf->listeners.n, typeof(l), by_bind);
|
||||
l->maxaccept = 1;
|
||||
l->maxconn = curpeers->peers_fe->maxconn;
|
||||
l->backlog = curpeers->peers_fe->backlog;
|
||||
l->accept = session_accept_fd;
|
||||
l->analysers |= curpeers->peers_fe->fe_req_ana;
|
||||
l->default_target = curpeers->peers_fe->default_target;
|
||||
@ -3743,8 +3741,6 @@ out_uri_auth_compat:
|
||||
listener->options |= LI_O_NOLINGER;
|
||||
if (!listener->maxconn)
|
||||
listener->maxconn = curproxy->maxconn;
|
||||
if (!listener->backlog)
|
||||
listener->backlog = curproxy->backlog;
|
||||
if (!listener->maxaccept)
|
||||
listener->maxaccept = global.tune.maxaccept ? global.tune.maxaccept : 64;
|
||||
|
||||
|
@ -298,7 +298,6 @@ static int stats_parse_global(char **args, int section_type, struct proxy *curpx
|
||||
|
||||
list_for_each_entry(l, &bind_conf->listeners, by_bind) {
|
||||
l->maxconn = global.stats_fe->maxconn;
|
||||
l->backlog = global.stats_fe->backlog;
|
||||
l->accept = session_accept_fd;
|
||||
l->default_target = global.stats_fe->default_target;
|
||||
l->options |= LI_O_UNLIMITED; /* don't make the peers subject to global limits */
|
||||
@ -2522,7 +2521,6 @@ int mworker_cli_proxy_new_listener(char *line)
|
||||
|
||||
list_for_each_entry(l, &bind_conf->listeners, by_bind) {
|
||||
l->maxconn = 10;
|
||||
l->backlog = 10;
|
||||
l->accept = session_accept_fd;
|
||||
l->default_target = mworker_proxy->default_target;
|
||||
/* don't make the peers subject to global limits and don't close it in the master */
|
||||
@ -2592,7 +2590,6 @@ int mworker_cli_sockpair_new(struct mworker_proc *mworker_proc, int proc)
|
||||
|
||||
list_for_each_entry(l, &bind_conf->listeners, by_bind) {
|
||||
l->maxconn = global.stats_fe->maxconn;
|
||||
l->backlog = global.stats_fe->backlog;
|
||||
l->accept = session_accept_fd;
|
||||
l->default_target = global.stats_fe->default_target;
|
||||
l->options |= (LI_O_UNLIMITED | LI_O_NOSTOP);
|
||||
|
@ -350,7 +350,7 @@ int resume_listener(struct listener *l)
|
||||
|
||||
if (l->proto->sock_prot == IPPROTO_TCP &&
|
||||
l->state == LI_PAUSED &&
|
||||
listen(l->fd, l->backlog ? l->backlog : l->maxconn) != 0) {
|
||||
listen(l->fd, listener_backlog(l)) != 0) {
|
||||
ret = 0;
|
||||
goto end;
|
||||
}
|
||||
@ -568,6 +568,27 @@ void delete_listener(struct listener *listener)
|
||||
HA_SPIN_UNLOCK(LISTENER_LOCK, &listener->lock);
|
||||
}
|
||||
|
||||
/* Returns a suitable value for a listener's backlog. It uses the listener's,
|
||||
* otherwise the frontend's backlog, otherwise the listener's maxconn,
|
||||
* otherwise the frontend's maxconn, otherwise 1024.
|
||||
*/
|
||||
int listener_backlog(const struct listener *l)
|
||||
{
|
||||
if (l->backlog)
|
||||
return l->backlog;
|
||||
|
||||
if (l->bind_conf->frontend->backlog)
|
||||
return l->bind_conf->frontend->backlog;
|
||||
|
||||
if (l->maxconn)
|
||||
return l->maxconn;
|
||||
|
||||
if (l->bind_conf->frontend->maxconn)
|
||||
return l->bind_conf->frontend->maxconn;
|
||||
|
||||
return 1024;
|
||||
}
|
||||
|
||||
/* This function is called on a read event from a listening socket, corresponding
|
||||
* to an accept. It tries to accept as many connections as possible, and for each
|
||||
* calls the listener's accept handler (generally the frontend's accept handler).
|
||||
@ -1101,7 +1122,7 @@ static int bind_parse_accept_netscaler_cip(char **args, int cur_arg, struct prox
|
||||
|
||||
val = atol(args[cur_arg + 1]);
|
||||
if (val <= 0) {
|
||||
memprintf(err, "'%s' : invalid value %d, must be > 0", args[cur_arg], val);
|
||||
memprintf(err, "'%s' : invalid value %d, must be >= 0", args[cur_arg], val);
|
||||
return ERR_ALERT | ERR_FATAL;
|
||||
}
|
||||
|
||||
@ -1125,7 +1146,7 @@ static int bind_parse_backlog(char **args, int cur_arg, struct proxy *px, struct
|
||||
}
|
||||
|
||||
val = atol(args[cur_arg + 1]);
|
||||
if (val <= 0) {
|
||||
if (val < 0) {
|
||||
memprintf(err, "'%s' : invalid value %d, must be > 0", args[cur_arg], val);
|
||||
return ERR_ALERT | ERR_FATAL;
|
||||
}
|
||||
|
@ -1017,7 +1017,7 @@ int tcp_bind_listener(struct listener *listener, char *errmsg, int errlen)
|
||||
#if defined(TCP_FASTOPEN)
|
||||
if (listener->options & LI_O_TCP_FO) {
|
||||
/* TFO needs a queue length, let's use the configured backlog */
|
||||
int qlen = listener->backlog ? listener->backlog : listener->maxconn;
|
||||
int qlen = listener_backlog(listener);
|
||||
if (setsockopt(fd, IPPROTO_TCP, TCP_FASTOPEN, &qlen, sizeof(qlen)) == -1) {
|
||||
msg = "cannot enable TCP_FASTOPEN";
|
||||
err |= ERR_WARN;
|
||||
@ -1058,7 +1058,7 @@ int tcp_bind_listener(struct listener *listener, char *errmsg, int errlen)
|
||||
ready = 0;
|
||||
|
||||
if (!(ext && ready) && /* only listen if not already done by external process */
|
||||
listen(fd, listener->backlog ? listener->backlog : listener->maxconn) == -1) {
|
||||
listen(fd, listener_backlog(listener)) == -1) {
|
||||
err |= ERR_RETRYABLE | ERR_ALERT;
|
||||
msg = "cannot listen to socket";
|
||||
goto tcp_close_return;
|
||||
@ -1150,7 +1150,7 @@ 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)
|
||||
if (listen(l->fd, listener_backlog(l)) != 0)
|
||||
return -1; /* OpenBSD dies here */
|
||||
|
||||
if (shutdown(l->fd, SHUT_RD) != 0)
|
||||
|
@ -315,7 +315,7 @@ static int uxst_bind_listener(struct listener *listener, char *errmsg, int errle
|
||||
ready = 0;
|
||||
|
||||
if (!(ext && ready) && /* only listen if not already done by external process */
|
||||
listen(fd, listener->backlog ? listener->backlog : listener->maxconn) < 0) {
|
||||
listen(fd, listener_backlog(listener)) < 0) {
|
||||
err |= ERR_FATAL | ERR_ALERT;
|
||||
msg = "cannot listen to UNIX socket";
|
||||
goto err_unlink_temp;
|
||||
|
Loading…
x
Reference in New Issue
Block a user