mirror of
https://github.com/shadowsocks/shadowsocks-libev.git
synced 2026-10-21 22:43:48 +00:00
Merge pull request #126 from lqs/tfo
add TCP-fast-open support from server to remote
This commit is contained in:
+30
-3
@@ -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)
|
||||
{
|
||||
|
||||
+1
-1
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user