]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: tcp: enable TCP Fast Open on systems which support it
authorWilly Tarreau <w@1wt.eu>
Fri, 5 Oct 2012 14:21:00 +0000 (16:21 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 5 Oct 2012 14:22:35 +0000 (16:22 +0200)
If TCP_FASTOPEN is defined, then the "tfo" option is supported on
"bind" lines to enable TCP Fast Open (linux >= 3.6).

doc/configuration.txt
include/types/listener.h
src/proto_tcp.c

index 8c3132b3a3707368be4895400a2a83ef970e7eae..3d8bbfdb65916d0783b00a6d2b9363c6f90b1da4 100644 (file)
@@ -6937,6 +6937,17 @@ ssl
   appear in clear text, so that ACLs and HTTP processing will only have access
   to deciphered contents.
 
+tfo
+  Is an optional keyword which is supported only on Linux kernels >= 3.6. It
+  enables TCP Fast Open on the listening socket, which means that clients which
+  support this feature will be able to send a request and receive a response
+  during the 3-way handshake starting from second connection, thus saving one
+  round-trip after the first connection. This only makes sense with protocols
+  that use high connection rates and where each round trip matters. This can
+  possibly cause issues with many firewalls which do not accept data on SYN
+  packets, so this option should only be enabled once well tested. This option
+  is only supported on TCPv4/TCPv6 sockets and ignored by other ones.
+
 transparent
   Is an optional keyword which is supported only on certain Linux kernels. It
   indicates that the addresses will be bound even if they do not belong to the
index 935a00370ededbc60b010de502ed9ee20ebbc893..6fe21ab888122b7bb6d29005f4728a4caddf1116 100644 (file)
@@ -88,6 +88,7 @@ enum {
 #define LI_O_CHK_MONNET 0x0020  /* check the source against a monitor-net rule */
 #define LI_O_ACC_PROXY  0x0040  /* find the proxied address in the first request line */
 #define LI_O_UNLIMITED  0x0080  /* listener not subject to global limits (peers & stats socket) */
+#define LI_O_TCP_FO     0x0100  /* enable TCP Fast Open (linux >= 3.6) */
 
 /* Note: if a listener uses LI_O_UNLIMITED, it is highly recommended that it adds its own
  * maxconn setting to the global.maxsock value so that its resources are reserved.
index ea6f94326dc8131d4e351a39231ed6900d9f4697..8b0792baa3e96107690f190b69fd9233eb35e456 100644 (file)
@@ -674,6 +674,16 @@ int tcp_bind_listener(struct listener *listener, char *errmsg, int errlen)
                        err |= ERR_WARN;
                }
        }
+#endif
+#if defined(TCP_FASTOPEN)
+       if (listener->options & LI_O_TCP_FO) {
+               /* TFO needs a queue length, let's use the configured backlog */
+               int qlen = listener->backlog ? listener->backlog : listener->maxconn;
+               if (setsockopt(fd, IPPROTO_TCP, TCP_FASTOPEN, &qlen, sizeof(qlen)) == -1) {
+                       msg = "cannot enable TCP_FASTOPEN";
+                       err |= ERR_WARN;
+               }
+       }
 #endif
        if (bind(fd, (struct sockaddr *)&listener->addr, listener->proto->sock_addrlen) == -1) {
                err |= ERR_RETRYABLE | ERR_ALERT;
@@ -1726,6 +1736,21 @@ static int bind_parse_defer_accept(char **args, int cur_arg, struct proxy *px, s
 }
 #endif
 
+#ifdef TCP_FASTOPEN
+/* parse the "defer-accept" bind keyword */
+static int bind_parse_tfo(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
+{
+       struct listener *l;
+
+       list_for_each_entry(l, &conf->listeners, by_bind) {
+               if (l->addr.ss_family == AF_INET || l->addr.ss_family == AF_INET6)
+                       l->options |= LI_O_TCP_FO;
+       }
+
+       return 0;
+}
+#endif
+
 #ifdef TCP_MAXSEG
 /* parse the "mss" bind keyword */
 static int bind_parse_mss(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
@@ -1832,6 +1857,9 @@ static struct bind_kw_list bind_kws = { "TCP", { }, {
 #ifdef TCP_MAXSEG
        { "mss",           bind_parse_mss,          1 }, /* set MSS of listening socket */
 #endif
+#ifdef TCP_FASTOPEN
+       { "tfo",           bind_parse_tfo,          0 }, /* enable TCP_FASTOPEN of listening socket */
+#endif
 #ifdef CONFIG_HAP_LINUX_TPROXY
        { "transparent",   bind_parse_transparent,  0 }, /* transparently bind to the specified addresses */
 #endif