MEDIUM: tcp: enable TCP Fast Open on systems which support it

If TCP_FASTOPEN is defined, then the "tfo" option is supported on
"bind" lines to enable TCP Fast Open (linux >= 3.6).
This commit is contained in:
Willy Tarreau 2012-10-05 16:21:00 +02:00
parent 4c75cca8ba
commit 1c862c5920
3 changed files with 40 additions and 0 deletions

View 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

View 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.

View 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