]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: listener: introduce listener_backlog() to report the backlog value
authorWilly Tarreau <w@1wt.eu>
Wed, 27 Feb 2019 14:39:41 +0000 (15:39 +0100)
committerWilly Tarreau <w@1wt.eu>
Thu, 28 Feb 2019 16:05:29 +0000 (17:05 +0100)
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.

doc/configuration.txt
include/proto/listener.h
src/cfgparse.c
src/cli.c
src/listener.c
src/proto_tcp.c
src/proto_uxst.c

index dd8649309d3ad2f6e71f240d7a5897eac79cc756..85b687eb644651067b789f3550f3b5ae973f37e7 100644 (file)
@@ -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>
index 8ec41af115e1a1830358b877acd5654db0c9ec86..24a01b2ed4e710b7d93d48525c8c66bd5895f0a0 100644 (file)
@@ -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.
index 21b9af5409b9c9d70970ca2e0b244289e4b0b376..4c8b48b1ed4d39b74fbc0c741f1e55627b18b78a 100644 (file)
@@ -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;
 
index 0cace77a716fce8b86c64d93b4a20d97bdf7aa93..9b957186dab9fe5454d008d364b5dfa1f7bb65a1 100644 (file)
--- a/src/cli.c
+++ b/src/cli.c
@@ -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);
index 3ae20e2479b3760cafc522b4db1e3c0d4f39e033..4e22e507e858fafbf5df797ce8df22b9de758a06 100644 (file)
@@ -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;
        }
index 28b77503e52f79acc3b4bef3d021f312c814794a..f1a0e4cf69d0699cb051c8d9f1a25a7b17ade7d4 100644 (file)
@@ -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)
index d454d4ca132074b9be51ec798b23a10a5518ee2a..980a22649b1f19b640de67137b3db1acb8ac9184 100644 (file)
@@ -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;