diff --git a/src/server.c b/src/server.c index 093459c3..873917a2 100644 --- a/src/server.c +++ b/src/server.c @@ -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) { diff --git a/src/server.h b/src/server.h index 296c7b30..396953d2 100644 --- a/src/server.h +++ b/src/server.h @@ -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);