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 */
{
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.
*/
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.
*/
/* 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);