Recent Linux Kernels implements a new TCP feature
called TCP_FASTOPEN. This feature reduces the TCP
handshake roundtrip improving performance for new
connections. For more details refer to the following
articles:
- http://lwn.net/Articles/508865/
- http://kernelnewbies.org/Linux_3.7#head-
cd32b65674184083465d349ad6d772c828fbbd8b
Requirements:
- the client side must be running Kernel >= 3.6.
- the server side must be running Kernel >= 3.7.
- Besides the Kernel version, the client and the server
must request to use TCP_FASTOPEN/MSG_FASTOPEN in their
respective calls.
- the tcp_fastopen flag must be enabled:
# echo 1 > /proc/sys/net/ipv4/tcp_fastopen
The good thing of this feature is that no matters if
the client implements TFO or not, the server will work
anyways.
This patch enable TCP_FASTOPEN by default in Liana plugin
and also export a new function mk_socket_set_tcp_fastopen()
for generic purposes.
Signed-off-by: Eduardo Silva <edsiper@gmail.com>
int ret;
ret = bind(socket_fd, addr, addrlen);
-
if( ret == -1 ) {
mk_warn("Error binding socket");
return ret;
}
- ret = listen(socket_fd, backlog);
+ /*
+ * Enable TCP_FASTOPEN by default: if for some reason this call fail,
+ * it will not affect the behavior of the server, in order to succeed,
+ * Monkey must be running in a Linux system with Kernel >= 3.7 and the
+ * tcp_fastopen flag enabled here:
+ *
+ * # cat /proc/sys/net/ipv4/tcp_fastopen
+ *
+ * To enable this feature just do:
+ *
+ * # echo 1 > /proc/sys/net/ipv4/tcp_fastopen
+ */
+ ret = mk_api->socket_set_tcp_fastopen(socket_fd);
+ if (ret != -1) {
+ mk_info("Linux TCP_FASTOPEN");
+ }
+ ret = listen(socket_fd, backlog);
if(ret == -1 ) {
mk_warn("Error setting up the listener");
return -1;
/* socket functions */
int (*socket_cork_flag) (int, int);
int (*socket_reset) (int);
+ int (*socket_set_tcp_fastopen) (int);
int (*socket_set_tcp_nodelay) (int);
int (*socket_connect) (char *, int);
int (*socket_set_nonblocking) (int);
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
/* Monkey HTTP Daemon
* ------------------
* Copyright (C) 2001-2012, Eduardo Silva P. <edsiper@gmail.com>
#define MK_SOCKET_H
#include <sys/uio.h>
-#include <netinet/in.h>
#include <sys/socket.h>
+#include <netinet/in.h>
#include "mk_iov.h"
#define SOCK_NONBLOCK 04000
#endif
+/*
+ * TCP_FASTOPEN: as this is a very new option in the Linux Kernel, the value is
+ * not yet exported and can be missing, lets make sure is available for all
+ * cases:
+ *
+ * http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=1046716368979dee857a2b8a91c4a8833f21b9cb
+ */
+#ifndef TCP_FASTOPEN
+#define TCP_FASTOPEN 23
+#endif
+
#define TCP_CORK_ON 1
#define TCP_CORK_OFF 0
int mk_socket_set_cork_flag(int fd, int state);
+int mk_socket_set_tcp_fastopen(int sockfd);
int mk_socket_set_tcp_nodelay(int sockfd);
int mk_socket_set_tcp_defer_accept(int sockfd);
int mk_socket_set_nonblocking(int sockfd);
int mk_socket_sendv(int socket_fd, struct mk_iov *mk_io);
int mk_socket_send(int socket_fd, const void *buf, size_t count);
int mk_socket_read(int socket_fd, void *buf, int count);
-int mk_socket_send_file(int socket_fd, int file_fd, off_t *file_offset,
+int mk_socket_send_file(int socket_fd, int file_fd, off_t *file_offset,
size_t file_count);
int mk_socket_ip_str(int socket_fd, char **buf, int size, unsigned long *len);
#endif
api->socket_cork_flag = mk_socket_set_cork_flag;
api->socket_connect = mk_socket_connect;
api->socket_reset = mk_socket_reset;
+ api->socket_set_tcp_fastopen = mk_socket_set_tcp_fastopen;
api->socket_set_tcp_nodelay = mk_socket_set_tcp_nodelay;
api->socket_set_nonblocking = mk_socket_set_nonblocking;
api->socket_create = mk_socket_create;
return 0;
}
+/*
+ * Enable the TCP_FASTOPEN feature for server side implemented in Linux Kernel >= 3.7,
+ * for more details read here:
+ *
+ * TCP Fast Open: expediting web services: http://lwn.net/Articles/508865/
+ */
+
+int mk_socket_set_tcp_fastopen(int sockfd)
+{
+ int qlen = 5;
+ return setsockopt(sockfd, SOL_TCP, TCP_FASTOPEN, &qlen, sizeof(qlen));
+}
+
int mk_socket_set_tcp_nodelay(int sockfd)
{
int on = 1;