From 54345cbee08c0c8b593a5396c3e8a5d92b658de9 Mon Sep 17 00:00:00 2001 From: Liu Qishuai Date: Thu, 16 Oct 2014 05:12:57 +0000 Subject: [PATCH] add TCP-fast-open support from server to remote --- src/server.c | 26 +++++++++++++++++++++----- src/server.h | 2 +- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/server.c b/src/server.c index f92bb6c3..910876e0 100644 --- a/src/server.c +++ b/src/server.c @@ -64,9 +64,7 @@ int verbose = 0; int udprelay = 0; -#ifdef TCP_FASTOPEN static int fast_open = 0; -#endif #ifdef HAVE_SETRLIMIT static int nofile = 0; #endif @@ -165,10 +163,11 @@ int create_and_bind(const char *host, const char *port) return listen_sock; } -struct remote *connect_to_remote(struct addrinfo *res, const char *iface) +struct remote *connect_to_remote(struct addrinfo *res, struct server *server) { int sockfd; int opt = 1; + const char *iface = server->listen_ctx->iface; // initilize remote socks sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); @@ -192,7 +191,24 @@ struct remote *connect_to_remote(struct addrinfo *res, const char *iface) if (iface) setinterface(sockfd, iface); #endif - connect(sockfd, res->ai_addr, res->ai_addrlen); + if (fast_open) { + ssize_t s = sendto(sockfd, server->buf + server->buf_idx, server->buf_len, MSG_FASTOPEN, res->ai_addr, res->ai_addrlen); + if (s == -1) { + if (errno == EAGAIN || errno == EWOULDBLOCK) { + // data not sent in SYN + } + } + else if (s < server->buf_len) { + server->buf_idx += s; + server->buf_len -= s; + } + else { + server->buf_idx = 0; + server->buf_len = 0; + } + } else { + connect(sockfd, res->ai_addr, res->ai_addrlen); + } return remote; } @@ -547,7 +563,7 @@ static void server_resolve_cb(EV_P_ ev_io *w, int revents) rp = result; } - struct remote *remote = connect_to_remote(rp, server->listen_ctx->iface); + struct remote *remote = connect_to_remote(rp, server); if (remote == NULL) { diff --git a/src/server.h b/src/server.h index 44769055..d56204a9 100644 --- a/src/server.h +++ b/src/server.h @@ -95,7 +95,7 @@ static void server_resolve_cb(EV_P_ ev_io *w, int revents); static void server_timeout_cb(EV_P_ ev_timer *watcher, int revents); struct remote* new_remote(int fd); -struct remote *connect_to_remote(struct addrinfo *res, const char *iface); +struct remote *connect_to_remote(struct addrinfo *res, struct server *server); void free_remote(struct remote *remote); void close_and_free_remote(EV_P_ struct remote *remote); struct server* new_server(int fd, struct listen_ctx *listener);