From 4f8fdcc1b5d5e6ffe8cc14be447313e5833702f5 Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Sun, 21 Oct 2012 15:08:30 +0100 Subject: [PATCH] yaid.c: Time out idle connections after 30s. --- yaid.c | 28 ++++++++++++++++++++++++++++ yaid.h | 2 ++ 2 files changed, 30 insertions(+) diff --git a/yaid.c b/yaid.c index cde2069..1d45fb8 100644 --- a/yaid.c +++ b/yaid.c @@ -56,6 +56,7 @@ struct client { int fd; /* The connection to the client */ selbuf b; /* Accumulate lines of input */ struct query q; /* The clients query and our reply */ + struct sel_timer t; /* Timeout for idle or doomed conn */ struct listen *l; /* Back to the listener (and ops) */ struct writebuf wb; /* Write buffer for our reply */ struct proxy *px; /* Proxy if conn goes via NAT */ @@ -521,11 +522,34 @@ static void disconnect_client(struct client *c) { close(c->fd); selbuf_destroy(&c->b); + sel_rmtimer(&c->t); free_writebuf(&c->wb); if (c->px) cancel_proxy(c->px); xfree(c); } +/* Time out a client because it's been idle for too long. */ +static void timeout_client(struct timeval *tv, void *p) +{ + struct client *c = p; + logmsg(&c->q, LOG_NOTICE, "timing out idle or stuck client"); + sel_addtimer(&sel, &c->t, tv, timeout_client, 0); + disconnect_client(c); +} + +/* Reset the client idle timer, as a result of activity. Set EXISTP if + * there is an existing timer which needs to be removed. + */ +static void reset_client_timer(struct client *c, int existp) +{ + struct timeval tv; + + gettimeofday(&tv, 0); + tv.tv_sec += 30; + if (existp) sel_rmtimer(&c->t); + sel_addtimer(&sel, &c->t, &tv, timeout_client, c); +} + /* Write a pseudorandom token into the buffer at P, which must have space for * at least TOKENSZ bytes. */ @@ -592,6 +616,9 @@ static void client_line(char *line, size_t len, void *p) return; } + /* Client activity, so update the timer. */ + reset_client_timer(c, 1); + /* See if the policy file has changed since we last looked. If so, try to * read the new version. */ @@ -790,6 +817,7 @@ static void accept_client(int fd, unsigned mode, void *p) /* Set stuff up for reading the query and sending responses. */ selbuf_init(&c->b, &sel, sk, client_line, c); selbuf_setsize(&c->b, 1024); + reset_client_timer(c, 0); c->fd = sk; c->px = 0; init_writebuf(&c->wb, sk, done_client_write, c); diff --git a/yaid.h b/yaid.h index 387f76e..daae4f6 100644 --- a/yaid.h +++ b/yaid.h @@ -43,8 +43,10 @@ #include #include #include +#include #include +#include #include #include -- 2.11.0