diff --git a/doc/configuration.txt b/doc/configuration.txt
index 04f3900b6..00a5238e1 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -1471,11 +1471,12 @@ balance url_param [check_post []]
bind []: [, ...]
bind []: [, ...] interface
bind []: [, ...] mss
+bind []: [, ...] backlog
+bind []: [, ...] maxconn
bind []: [, ...] transparent
bind []: [, ...] id
bind []: [, ...] name
bind []: [, ...] defer-accept
-bind []: [, ...] accept-proxy
bind / [, ...]
bind / [, ...] mode
bind / [, ...] [ user | uid ]
@@ -1545,6 +1546,17 @@ bind / [, ...] [ group | gid ]
connection's advertised MSS for outgoing segments. This
parameter is only compatible with TCP sockets.
+ sets the socket's backlog to this value. If unspecified, the
+ frontend's backlog is used instead.
+
+ limits the socket to this number of concurrent connections.
+ Extra connections will remain in the system's backlog until a
+ connection is released. If unspecified, the limit will be the
+ same as the frontend's maxconn. Note that in case of port
+ ranges, the same value will be applied to each socket. This
+ setting enables different limitations on expensive sockets,
+ for instance SSL entries which may easily eat all memory.
+
is a persistent value for socket ID. Must be positive and
unique in the proxy. An unused value will automatically be
assigned if unset. Can only be used when defining only a
diff --git a/src/cfgparse.c b/src/cfgparse.c
index 6ff166e99..a15050355 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -1807,6 +1807,58 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
#endif
}
+ if (!strcmp(args[cur_arg], "maxconn")) {
+ struct listener *l;
+ int val;
+
+ if (!*args[cur_arg + 1]) {
+ Alert("parsing [%s:%d] : '%s' : missing maxconn value.\n",
+ file, linenum, args[0]);
+ err_code |= ERR_ALERT | ERR_FATAL;
+ goto out;
+ }
+
+ val = atol(args[cur_arg + 1]);
+ if (val <= 0) {
+ Alert("parsing [%s:%d] : '%s' : invalid maxconn value %d, must be > 0.\n",
+ file, linenum, args[0], val);
+ err_code |= ERR_ALERT | ERR_FATAL;
+ goto out;
+ }
+
+ for (l = curproxy->listen; l != last_listen; l = l->next)
+ l->maxconn = val;
+
+ cur_arg += 2;
+ continue;
+ }
+
+ if (!strcmp(args[cur_arg], "backlog")) {
+ struct listener *l;
+ int val;
+
+ if (!*args[cur_arg + 1]) {
+ Alert("parsing [%s:%d] : '%s' : missing backlog value.\n",
+ file, linenum, args[0]);
+ err_code |= ERR_ALERT | ERR_FATAL;
+ goto out;
+ }
+
+ val = atol(args[cur_arg + 1]);
+ if (val <= 0) {
+ Alert("parsing [%s:%d] : '%s' : invalid backlog value %d, must be > 0.\n",
+ file, linenum, args[0], val);
+ err_code |= ERR_ALERT | ERR_FATAL;
+ goto out;
+ }
+
+ for (l = curproxy->listen; l != last_listen; l = l->next)
+ l->backlog = val;
+
+ cur_arg += 2;
+ continue;
+ }
+
if (!strcmp(args[cur_arg], "ssl")) { /* use ssl certificate */
#ifdef USE_OPENSSL
struct listener *l;
@@ -6888,8 +6940,10 @@ out_uri_auth_compat:
#endif /* USE_OPENSSL */
if (curproxy->options & PR_O_TCP_NOLING)
listener->options |= LI_O_NOLINGER;
- listener->maxconn = curproxy->maxconn;
- listener->backlog = curproxy->backlog;
+ if (!listener->maxconn)
+ listener->maxconn = curproxy->maxconn;
+ if (!listener->backlog)
+ listener->backlog = curproxy->backlog;
listener->timeout = &curproxy->timeout.client;
listener->accept = session_accept;
listener->frontend = curproxy;