[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 12a7eb7..86f3f33 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 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 d18f59a..09d311e 100644
--- a/doc/haproxy-en.txt
+++ b/doc/haproxy-en.txt
@@ -1525,6 +1525,17 @@
 	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 eafe436..d29259f 100644
--- a/doc/haproxy-fr.txt
+++ b/doc/haproxy-fr.txt
@@ -1562,6 +1562,17 @@
 	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 57a8cb0..921eaed 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 b259954..f2de0d9 100644
--- a/include/types/global.h
+++ b/include/types/global.h
@@ -73,6 +73,7 @@
 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 da8b8ac..91c0b34 100644
--- a/src/backend.c
+++ b/src/backend.c
@@ -408,6 +408,9 @@
 	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 e361356..19b2ee7 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -92,6 +92,7 @@
 	{ "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 87495a4..1f58154 100644
--- a/src/client.c
+++ b/src/client.c
@@ -165,6 +165,9 @@
 		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 fc0cda1..4437d45 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -135,6 +135,7 @@
 
 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 7d4b2ec..bd33c84 100644
--- a/src/proxy.c
+++ b/src/proxy.c
@@ -26,6 +26,7 @@
 #include <types/polling.h>
 
 #include <proto/client.h>
+#include <proto/backend.h>
 #include <proto/fd.h>
 #include <proto/log.h>
 #include <proto/proxy.h>
@@ -113,6 +114,9 @@
 				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,