mirror of
https://github.com/shadowsocks/shadowsocks-libev.git
synced 2026-10-22 15:16:58 +00:00
add tcp timeout
This commit is contained in:
+27
-24
@@ -93,7 +93,7 @@ int create_and_bind(const char *host, const char *port) {
|
||||
return listen_sock;
|
||||
}
|
||||
|
||||
struct remote *connect_to_remote(struct addrinfo *res, int timeout) {
|
||||
struct remote *connect_to_remote(struct addrinfo *res) {
|
||||
int sockfd;
|
||||
int opt = 1;
|
||||
|
||||
@@ -110,7 +110,7 @@ struct remote *connect_to_remote(struct addrinfo *res, int timeout) {
|
||||
setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt));
|
||||
#endif
|
||||
|
||||
struct remote *remote = new_remote(sockfd, timeout);
|
||||
struct remote *remote = new_remote(sockfd);
|
||||
|
||||
// setup remote socks
|
||||
setnonblocking(sockfd);
|
||||
@@ -126,6 +126,8 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) {
|
||||
|
||||
char *buf = server->buf;
|
||||
|
||||
ev_timer_again(EV_A_ &server->recv_ctx->watcher);
|
||||
|
||||
if (server->stage != 0) {
|
||||
remote = server->remote;
|
||||
buf = remote->buf;
|
||||
@@ -269,7 +271,7 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) {
|
||||
server->query = query;
|
||||
|
||||
ev_io_stop(EV_A_ &server_recv_ctx->io);
|
||||
ev_timer_start(EV_A_ &server->recv_ctx->watcher);
|
||||
ev_timer_start(EV_A_ &server->send_ctx->watcher);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -330,6 +332,20 @@ static void server_send_cb (EV_P_ ev_io *w, int revents) {
|
||||
}
|
||||
}
|
||||
|
||||
static void server_timeout_cb(EV_P_ ev_timer *watcher, int revents) {
|
||||
struct server_ctx *server_ctx = (struct server_ctx *) (((void*)watcher)
|
||||
- sizeof(ev_io));
|
||||
struct server *server = server_ctx->server;
|
||||
struct remote *remote = server->remote;
|
||||
|
||||
LOGE("TCP connection timeout");
|
||||
|
||||
ev_timer_stop(EV_A_ watcher);
|
||||
|
||||
close_and_free_remote(EV_A_ remote);
|
||||
close_and_free_server(EV_A_ server);
|
||||
}
|
||||
|
||||
static void server_resolve_cb(EV_P_ ev_timer *watcher, int revents) {
|
||||
int err;
|
||||
struct addrinfo *result, *rp;
|
||||
@@ -385,7 +401,7 @@ static void server_resolve_cb(EV_P_ ev_timer *watcher, int revents) {
|
||||
rp = result;
|
||||
}
|
||||
|
||||
struct remote *remote = connect_to_remote(rp, server->listen_ctx->timeout);
|
||||
struct remote *remote = connect_to_remote(rp);
|
||||
|
||||
// release addrinfo
|
||||
asyncns_freeaddrinfo(result);
|
||||
@@ -410,25 +426,10 @@ static void server_resolve_cb(EV_P_ ev_timer *watcher, int revents) {
|
||||
|
||||
// listen to remote connected event
|
||||
ev_io_start(EV_A_ &remote->send_ctx->io);
|
||||
ev_timer_start(EV_A_ &remote->send_ctx->watcher);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void remote_timeout_cb(EV_P_ ev_timer *watcher, int revents) {
|
||||
struct remote_ctx *remote_ctx = (struct remote_ctx *) (((void*)watcher)
|
||||
- sizeof(ev_io));
|
||||
struct remote *remote = remote_ctx->remote;
|
||||
struct server *server = remote->server;
|
||||
|
||||
LOGE("remote timeout");
|
||||
|
||||
ev_timer_stop(EV_A_ watcher);
|
||||
|
||||
close_and_free_remote(EV_A_ remote);
|
||||
close_and_free_server(EV_A_ server);
|
||||
}
|
||||
|
||||
static void remote_recv_cb (EV_P_ ev_io *w, int revents) {
|
||||
struct remote_ctx *remote_recv_ctx = (struct remote_ctx *)w;
|
||||
struct remote *remote = remote_recv_ctx->remote;
|
||||
@@ -440,6 +441,8 @@ static void remote_recv_cb (EV_P_ ev_io *w, int revents) {
|
||||
return;
|
||||
}
|
||||
|
||||
ev_timer_again(EV_A_ &server->recv_ctx->watcher);
|
||||
|
||||
ssize_t r = recv(remote->fd, server->buf, BUF_SIZE, 0);
|
||||
|
||||
if (r == 0) {
|
||||
@@ -509,7 +512,6 @@ static void remote_send_cb (EV_P_ ev_io *w, int revents) {
|
||||
LOGD("remote connected.");
|
||||
}
|
||||
remote_send_ctx->connected = 1;
|
||||
ev_timer_stop(EV_A_ &remote_send_ctx->watcher);
|
||||
|
||||
if (remote->buf_len == 0) {
|
||||
server->stage = 5;
|
||||
@@ -574,7 +576,7 @@ static void remote_send_cb (EV_P_ ev_io *w, int revents) {
|
||||
}
|
||||
}
|
||||
|
||||
struct remote* new_remote(int fd, int timeout) {
|
||||
struct remote* new_remote(int fd) {
|
||||
remote_conn++;
|
||||
struct remote *remote;
|
||||
remote = malloc(sizeof(struct remote));
|
||||
@@ -583,7 +585,6 @@ struct remote* new_remote(int fd, int timeout) {
|
||||
remote->fd = fd;
|
||||
ev_io_init(&remote->recv_ctx->io, remote_recv_cb, fd, EV_READ);
|
||||
ev_io_init(&remote->send_ctx->io, remote_send_cb, fd, EV_WRITE);
|
||||
ev_timer_init(&remote->send_ctx->watcher, remote_timeout_cb, timeout, 0);
|
||||
remote->recv_ctx->remote = remote;
|
||||
remote->recv_ctx->connected = 0;
|
||||
remote->send_ctx->remote = remote;
|
||||
@@ -608,7 +609,6 @@ void free_remote(struct remote *remote) {
|
||||
|
||||
void close_and_free_remote(EV_P_ struct remote *remote) {
|
||||
if (remote != NULL) {
|
||||
ev_timer_stop(EV_A_ &remote->send_ctx->watcher);
|
||||
ev_io_stop(EV_A_ &remote->send_ctx->io);
|
||||
ev_io_stop(EV_A_ &remote->recv_ctx->io);
|
||||
close(remote->fd);
|
||||
@@ -628,7 +628,8 @@ struct server* new_server(int fd, struct listen_ctx *listener) {
|
||||
server->fd = fd;
|
||||
ev_io_init(&server->recv_ctx->io, server_recv_cb, fd, EV_READ);
|
||||
ev_io_init(&server->send_ctx->io, server_send_cb, fd, EV_WRITE);
|
||||
ev_timer_init(&server->recv_ctx->watcher, server_resolve_cb, 0.2, 0.5);
|
||||
ev_timer_init(&server->send_ctx->watcher, server_resolve_cb, 0.2, 0.5);
|
||||
ev_timer_init(&server->recv_ctx->watcher, server_timeout_cb, listener->timeout, listener->timeout * 5);
|
||||
server->recv_ctx->server = server;
|
||||
server->recv_ctx->connected = 0;
|
||||
server->send_ctx->server = server;
|
||||
@@ -671,6 +672,7 @@ void close_and_free_server(EV_P_ struct server *server) {
|
||||
if (server != NULL) {
|
||||
ev_io_stop(EV_A_ &server->send_ctx->io);
|
||||
ev_io_stop(EV_A_ &server->recv_ctx->io);
|
||||
ev_timer_stop(EV_A_ &server->send_ctx->watcher);
|
||||
ev_timer_stop(EV_A_ &server->recv_ctx->watcher);
|
||||
close(server->fd);
|
||||
free_server(server);
|
||||
@@ -701,6 +703,7 @@ static void accept_cb (EV_P_ ev_io *w, int revents) {
|
||||
|
||||
struct server *server = new_server(serverfd, listener);
|
||||
ev_io_start(EV_A_ &server->recv_ctx->io);
|
||||
ev_timer_start(EV_A_ &server->recv_ctx->watcher);
|
||||
}
|
||||
|
||||
int main (int argc, char **argv) {
|
||||
|
||||
+3
-4
@@ -40,7 +40,6 @@ struct server {
|
||||
|
||||
struct remote_ctx {
|
||||
ev_io io;
|
||||
ev_timer watcher;
|
||||
int connected;
|
||||
struct remote *remote;
|
||||
};
|
||||
@@ -61,11 +60,11 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents);
|
||||
static void server_send_cb (EV_P_ ev_io *w, int revents);
|
||||
static void remote_recv_cb (EV_P_ ev_io *w, int revents);
|
||||
static void remote_send_cb (EV_P_ ev_io *w, int revents);
|
||||
static void remote_timeout_cb(EV_P_ ev_timer *watcher, int revents);
|
||||
static void server_timeout_cb(EV_P_ ev_timer *watcher, int revents);
|
||||
static void server_resolve_cb(EV_P_ ev_timer *watcher, int revents);
|
||||
|
||||
struct remote* new_remote(int fd, int timeout);
|
||||
struct remote *connect_to_remote(struct addrinfo *res, int timeout);
|
||||
struct remote* new_remote(int fd);
|
||||
struct remote *connect_to_remote(struct addrinfo *res);
|
||||
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