Browse Source

Merge pull request #126 from lqs/tfo

add TCP-fast-open support from server to remote
pull/131/head
Max Lv 10 years ago
parent
commit
dbc78504bd
2 changed files with 31 additions and 4 deletions
  1. 33
      src/server.c
  2. 2
      src/server.h

33
src/server.c

@ -165,10 +165,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 +193,33 @@ 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);
#ifdef TCP_FASTOPEN
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) {
// The remote server doesn't support tfo or it's the first connection to the server.
// It will automatically fall back to conventional TCP.
}
else if (errno == EOPNOTSUPP || errno == EPROTONOSUPPORT || errno == ENOPROTOOPT) {
LOGE("fast open is not supported on this platform");
connect(sockfd, res->ai_addr, res->ai_addrlen);
}
else {
ERROR("sendto");
}
}
else if (s < server->buf_len) {
server->buf_idx += s;
server->buf_len -= s;
}
else {
server->buf_idx = 0;
server->buf_len = 0;
}
} else
#endif
connect(sockfd, res->ai_addr, res->ai_addrlen);
return remote;
}
@ -547,7 +574,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)
{

2
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);

Loading…
Cancel
Save