[MINOR] tcp: add support for dynamic MSS setting

By passing a negative value to the "mss" argument of "bind" lines, it
becomes possible to subtract this value to the MSS advertised by the
client, which results in segments smaller than advertised. The effect
is useful with some TCP stacks which ACK less often when segments are
not full, because they only ACK every other full segment as suggested
by RFC1122.

NOTE: currently this has no effect on Linux kernel 2.6, a kernel patch
is still required to change the MSS of established connections.
diff --git a/src/cfgparse.c b/src/cfgparse.c
index ddfbe42..a67b348 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -1683,9 +1683,9 @@
 					goto out;
 				}
 
-				mss = str2uic(args[cur_arg + 1]);
-				if (mss < 1 || mss > 65535) {
-					Alert("parsing [%s:%d]: %s expects an MSS value between 1 and 65535.\n",
+				mss = atoi(args[cur_arg + 1]);
+				if (!mss || abs(mss) > 65535) {
+					Alert("parsing [%s:%d]: %s expects an MSS with and absolute value between 1 and 65535.\n",
 					      file, linenum, args[0]);
 					err_code |= ERR_ALERT | ERR_FATAL;
 					goto out;
diff --git a/src/frontend.c b/src/frontend.c
index 4fc4460..8842e28 100644
--- a/src/frontend.c
+++ b/src/frontend.c
@@ -20,6 +20,8 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 
+#include <netinet/tcp.h>
+
 #include <common/compat.h>
 #include <common/config.h>
 #include <common/debug.h>
@@ -100,6 +102,17 @@
 		if (s->fe->options & PR_O_TCP_NOLING)
 			setsockopt(cfd, SOL_SOCKET, SO_LINGER,
 				   (struct linger *) &nolinger, sizeof(struct linger));
+#if defined(TCP_MAXSEG)
+		if (s->listener->maxseg < 0) {
+			/* we just want to reduce the current MSS by that value */
+			int mss;
+			int mss_len = sizeof(mss);
+			if (getsockopt(cfd, IPPROTO_TCP, TCP_MAXSEG, &mss, &mss_len) == 0) {
+				mss += s->listener->maxseg; /* remember, it's < 0 */
+				setsockopt(cfd, IPPROTO_TCP, TCP_MAXSEG, &mss, sizeof(mss));
+			}
+		}
+#endif
 	}
 
 	if (global.tune.client_sndbuf)
diff --git a/src/proto_tcp.c b/src/proto_tcp.c
index 5039db8..6328d0a 100644
--- a/src/proto_tcp.c
+++ b/src/proto_tcp.c
@@ -509,7 +509,7 @@
 	}
 #endif
 #if defined(TCP_MAXSEG)
-	if (listener->maxseg) {
+	if (listener->maxseg > 0) {
 		if (setsockopt(fd, IPPROTO_TCP, TCP_MAXSEG,
 			       &listener->maxseg, sizeof(listener->maxseg)) == -1) {
 			msg = "cannot set MSS";