From: Alexandre Cassen Date: Thu, 11 Oct 2007 18:48:58 +0000 (+0200) Subject: [MINOR] add the "nolinger" option to disable data lingering X-Git-Tag: v1.3.13~24 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=87ea5483138a07b9a731be9f0d3e9868083be052;p=thirdparty%2Fhaproxy.git [MINOR] add the "nolinger" option to disable data lingering The following patch will give the ability to tweak socket linger mode. You can use this option with "option nolinger" inside fronted or backend configuration declaration. This will help in environments where lots of FIN_WAIT sockets are encountered. --- diff --git a/doc/configuration.txt b/doc/configuration.txt index 12a7eb76dc..86f3f3325c 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -2,9 +2,9 @@ HAProxy Configuration Manual ---------------------- - version 1.3.12.1 + version 1.3.12.3 willy tarreau - 2007/07/25 + 2007/09/11 This document covers the configuration language as implemented in the version @@ -247,6 +247,7 @@ option httpchk X - X X option httpclose X X X X option httplog X X X X option logasap X X X - +option nolinger X X X X option persist X - X X option redispatch X - X X option smtpchk X - X X diff --git a/doc/haproxy-en.txt b/doc/haproxy-en.txt index d18f59a0d5..09d311e52e 100644 --- a/doc/haproxy-en.txt +++ b/doc/haproxy-en.txt @@ -1525,6 +1525,17 @@ options to enable TCP keep-alive : option clitcpka # enables keep-alive only on client side option srvtcpka # enables keep-alive only on server side +4.1.4) TCP lingering +-------------------- +It is possible to disable the system's lingering of data unacked by the client +at the end of a session. This is sometimes required when haproxy is used as a +front-end with lots of unreliable clients, and you observe thousands of sockets +in the FIN_WAIT state on the machine. This may be used in a frontend to affect +the client-side connection, as well as in a backend for the server-side +connection : + + option nolinger # disables data lingering + 4.2) Event logging ------------------ diff --git a/doc/haproxy-fr.txt b/doc/haproxy-fr.txt index eafe4365ae..d29259fc7c 100644 --- a/doc/haproxy-fr.txt +++ b/doc/haproxy-fr.txt @@ -1562,6 +1562,17 @@ pour activer le maintien de session TCP : option clitcpka # active le keep-alive côté client option srvtcpka # active le keep-alive côté serveur +4.1.4) Rémanence des données TCP (lingering) +-------------------------------------------- +Il est possible de désactiver la conservation de données non acquittées par un +client à la fin d'une session. Cela peut parfois s'avérer nécessaire lorsque +haproxy est utilisé en face d'un grand nombre de clients non fiables et qu'un +nombre élevé de sockets en état FIN_WAIT est observé sur la machine. L'option +peut être utilisée dans un frontend pour ajuster les connexions vers les +clients, et dans un backend pour ajuster les connexions vers les serveurs : + + option nolinger # désactive la conservation de données + 4.2) Journalisation des connexions ---------------------------------- diff --git a/include/types/backend.h b/include/types/backend.h index 57a8cb053a..921eaed89e 100644 --- a/include/types/backend.h +++ b/include/types/backend.h @@ -60,6 +60,7 @@ #define PR_O_BALANCE_UH 0x10000000 /* balance on URI hash */ #define PR_O_BALANCE (PR_O_BALANCE_RR | PR_O_BALANCE_SH | PR_O_BALANCE_UH) #define PR_O_SMTP_CHK 0x20000000 /* use SMTP EHLO check for server health - pvandijk@vision6.com.au */ +#define PR_O_TCP_NOLING 0x40000000 /* disable lingering on client and server connections */ #endif /* _TYPES_BACKEND_H */ diff --git a/include/types/global.h b/include/types/global.h index b25995491e..f2de0d9468 100644 --- a/include/types/global.h +++ b/include/types/global.h @@ -73,6 +73,7 @@ extern int listeners; extern char trash[BUFSIZE]; extern const int zero; extern const int one; +extern const struct linger nolinger; extern int stopping; /* non zero means stopping in progress */ #endif /* _TYPES_GLOBAL_H */ diff --git a/src/backend.c b/src/backend.c index da8b8ac36a..91c0b34b29 100644 --- a/src/backend.c +++ b/src/backend.c @@ -408,6 +408,9 @@ int connect_server(struct session *s) if (s->be->options & PR_O_TCP_SRV_KA) setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (char *) &one, sizeof(one)); + if (s->be->options & PR_O_TCP_NOLING) + setsockopt(fd, SOL_SOCKET, SO_LINGER, (struct linger *) &nolinger, sizeof(struct linger)); + /* allow specific binding : * - server-specific at first * - proxy-specific next diff --git a/src/cfgparse.c b/src/cfgparse.c index e361356bdf..19b2ee71ad 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -92,6 +92,7 @@ static const struct { { "redispatch", PR_O_REDISP, PR_CAP_BE, 0 }, { "keepalive", PR_O_KEEPALIVE, PR_CAP_NONE, 0 }, { "httpclose", PR_O_HTTP_CLOSE, PR_CAP_FE | PR_CAP_BE, 0 }, + { "nolinger", PR_O_TCP_NOLING, PR_CAP_FE | PR_CAP_BE, 0 }, { "logasap", PR_O_LOGASAP, PR_CAP_FE, 0 }, { "abortonclose", PR_O_ABRT_CLOSE, PR_CAP_BE, 0 }, { "checkcache", PR_O_CHK_CACHE, PR_CAP_BE, 0 }, diff --git a/src/client.c b/src/client.c index 87495a4a59..1f58154c2f 100644 --- a/src/client.c +++ b/src/client.c @@ -165,6 +165,9 @@ int event_accept(int fd) { if (p->options & PR_O_TCP_CLI_KA) setsockopt(cfd, SOL_SOCKET, SO_KEEPALIVE, (char *) &one, sizeof(one)); + if (p->options & PR_O_TCP_NOLING) + setsockopt(cfd, SOL_SOCKET, SO_LINGER, (struct linger *) &nolinger, sizeof(struct linger)); + t->wq = NULL; t->qlist.p = NULL; t->state = TASK_IDLE; diff --git a/src/haproxy.c b/src/haproxy.c index fc0cda14ea..4437d45b01 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -135,6 +135,7 @@ char trash[BUFSIZE]; const int zero = 0; const int one = 1; +const struct linger nolinger = { .l_onoff = 1, .l_linger = 0 }; /* * Syslog facilities and levels. Conforming to RFC3164. diff --git a/src/proxy.c b/src/proxy.c index 7d4b2ec08b..bd33c84e0b 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -113,6 +114,9 @@ int start_proxies(int verbose) Alert("cannot do so_reuseaddr for proxy %s. Continuing.\n", curproxy->id); } + + if (curproxy->options & PR_O_TCP_NOLING) + setsockopt(fd, SOL_SOCKET, SO_LINGER, (struct linger *) &nolinger, sizeof(struct linger)); #ifdef SO_REUSEPORT /* OpenBSD supports this. As it's present in old libc versions of Linux,