[MINOR] add support for the "backlog" parameter
Add the "backlog" parameter to frontends, to give hints to the system about the approximate listen backlog desired size. In order to protect against SYN flood attacks, one solution is to increase the system's SYN backlog size. Depending on the system, sometimes it is just tunable via a system parameter, sometimes it is not adjustable at all, and sometimes the system relies on hints given by the application at the time of the listen() syscall. By default, HAProxy passes the frontend's maxconn value to the listen() syscall. On systems which can make use of this value, it can sometimes be useful to be able to specify a different value, hence this backlog parameter.
This commit is contained in:
parent
c27debfe56
commit
c73ce2b111
|
@ -4,7 +4,7 @@
|
|||
----------------------
|
||||
version 1.3.14.2
|
||||
willy tarreau
|
||||
2007/12/27
|
||||
2008/01/05
|
||||
|
||||
|
||||
This document covers the configuration language as implemented in the version
|
||||
|
@ -502,6 +502,7 @@ keyword defaults frontend listen backend
|
|||
----------------------+----------+----------+---------+---------
|
||||
acl - X X X
|
||||
appsession - - X X
|
||||
backlog X X X -
|
||||
balance X - X X
|
||||
bind - X X -
|
||||
block - X X X
|
||||
|
@ -653,6 +654,31 @@ appsession <cookie> len <length> timeout <holdtime>
|
|||
See also : "cookie", "capture cookie" and "balance".
|
||||
|
||||
|
||||
backlog <conns>
|
||||
Give hints to the system about the approximate listen backlog desired size
|
||||
May be used in sections : defaults | frontend | listen | backend
|
||||
yes | yes | yes | no
|
||||
Arguments :
|
||||
<conns> is the number of pending connections. Depending on the operating
|
||||
system, it may represent the number of already acknowledged
|
||||
connections, of non-acknowledged ones, or both.
|
||||
|
||||
In order to protect against SYN flood attacks, one solution is to increase
|
||||
the system's SYN backlog size. Depending on the system, sometimes it is just
|
||||
tunable via a system parameter, sometimes it is not adjustable at all, and
|
||||
sometimes the system relies on hints given by the application at the time of
|
||||
the listen() syscall. By default, HAProxy passes the frontend's maxconn value
|
||||
to the listen() syscall. On systems which can make use of this value, it can
|
||||
sometimes be useful to be able to specify a different value, hence this
|
||||
backlog parameter.
|
||||
|
||||
On Linux 2.4, the parameter is ignored by the system. On Linux 2.6, it is
|
||||
used as a hint and the system accepts up to the smallest greater power of
|
||||
two, and never more than some limits (usually 32768).
|
||||
|
||||
See also : "maxconn" and the target operating system's tuning guide.
|
||||
|
||||
|
||||
balance <algorithm> [ <arguments> ]
|
||||
Define the load balancing algorithm to be used in a backend.
|
||||
May be used in sections : defaults | frontend | listen | backend
|
||||
|
|
|
@ -78,6 +78,7 @@ struct listener {
|
|||
struct protocol *proto; /* protocol this listener belongs to */
|
||||
int nbconn; /* current number of connections on this listener */
|
||||
int maxconn; /* maximum connections allowed on this listener */
|
||||
unsigned int backlog; /* if set, listen backlog */
|
||||
struct listener *next; /* next address for the same proxy, or NULL */
|
||||
struct list proto_list; /* list in the protocol header */
|
||||
int (*accept)(int fd); /* accept() function passed to fdtab[] */
|
||||
|
|
|
@ -228,6 +228,7 @@ struct proxy {
|
|||
struct chunk errmsg[HTTP_ERR_SIZE]; /* default or customized error messages for known errors */
|
||||
int uuid; /* universally unique proxy ID, used for SNMP */
|
||||
int next_svid; /* next server-id, used for SNMP */
|
||||
unsigned int backlog; /* force the frontend's listen backlog */
|
||||
};
|
||||
|
||||
struct switching_rule {
|
||||
|
|
|
@ -614,6 +614,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int inv)
|
|||
|
||||
if (curproxy->cap & PR_CAP_FE) {
|
||||
curproxy->maxconn = defproxy.maxconn;
|
||||
curproxy->backlog = defproxy.backlog;
|
||||
|
||||
/* initialize error relocations */
|
||||
for (rc = 0; rc < HTTP_ERR_SIZE; rc++) {
|
||||
|
@ -1365,6 +1366,16 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int inv)
|
|||
}
|
||||
curproxy->maxconn = atol(args[1]);
|
||||
}
|
||||
else if (!strcmp(args[0], "backlog")) { /* backlog */
|
||||
if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
|
||||
return 0;
|
||||
|
||||
if (*(args[1]) == 0) {
|
||||
Alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
|
||||
return -1;
|
||||
}
|
||||
curproxy->backlog = atol(args[1]);
|
||||
}
|
||||
else if (!strcmp(args[0], "fullconn")) { /* fullconn */
|
||||
if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], " Maybe you want 'maxconn' instead ?"))
|
||||
return 0;
|
||||
|
@ -2865,6 +2876,7 @@ int readcfgfile(const char *file)
|
|||
if (curproxy->options & PR_O_TCP_NOLING)
|
||||
listener->options |= LI_O_NOLINGER;
|
||||
listener->maxconn = curproxy->maxconn;
|
||||
listener->backlog = curproxy->backlog;
|
||||
listener->timeout = &curproxy->timeout.client;
|
||||
listener->accept = event_accept;
|
||||
listener->private = curproxy;
|
||||
|
|
|
@ -160,7 +160,7 @@ int tcp_bind_listener(struct listener *listener, char *errmsg, int errlen)
|
|||
goto tcp_close_return;
|
||||
}
|
||||
|
||||
if (listen(fd, listener->maxconn) == -1) {
|
||||
if (listen(fd, listener->backlog ? listener->backlog : listener->maxconn) == -1) {
|
||||
err |= ERR_RETRYABLE | ERR_ALERT;
|
||||
msg = "cannot listen to socket";
|
||||
goto tcp_close_return;
|
||||
|
|
|
@ -369,7 +369,7 @@ void pause_proxy(struct proxy *p)
|
|||
struct listener *l;
|
||||
for (l = p->listen; l != NULL; l = l->next) {
|
||||
if (shutdown(l->fd, SHUT_WR) == 0 &&
|
||||
listen(l->fd, p->maxconn) == 0 &&
|
||||
listen(l->fd, p->backlog ? p->backlog : p->maxconn) == 0 &&
|
||||
shutdown(l->fd, SHUT_RD) == 0) {
|
||||
EV_FD_CLR(l->fd, DIR_RD);
|
||||
if (p->state != PR_STERROR)
|
||||
|
@ -435,7 +435,7 @@ void listen_proxies(void)
|
|||
send_log(p, LOG_WARNING, "Enabling proxy %s.\n", p->id);
|
||||
|
||||
for (l = p->listen; l != NULL; l = l->next) {
|
||||
if (listen(l->fd, p->maxconn) == 0) {
|
||||
if (listen(l->fd, p->backlog ? p->backlog : p->maxconn) == 0) {
|
||||
if (actconn < global.maxconn && p->feconn < p->maxconn) {
|
||||
EV_FD_SET(l->fd, DIR_RD);
|
||||
p->state = PR_STRUN;
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
# This is a test configuration.
|
||||
# It is used to check that the backlog queue works as expected.
|
||||
|
||||
global
|
||||
maxconn 200
|
||||
stats timeout 3s
|
||||
|
||||
frontend backlog_def
|
||||
mode http
|
||||
timeout client 15s
|
||||
maxconn 100
|
||||
bind :8000
|
||||
option httpclose
|
||||
|
||||
frontend backlog_max
|
||||
mode http
|
||||
timeout client 15s
|
||||
maxconn 100
|
||||
backlog 100000
|
||||
bind :8001
|
||||
option httpclose
|
||||
|
Loading…
Reference in New Issue