Browse Source

add tcp timeout

pull/4/merge
Max Lv 11 years ago
parent
commit
2fd2ee4a00
2 changed files with 30 additions and 28 deletions
  1. 51
      src/server.c
  2. 7
      src/server.h

51
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) {

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

Loading…
Cancel
Save