diff options
author | June McEnroe <june@causal.agency> | 2021-10-03 16:06:51 -0400 |
---|---|---|
committer | June McEnroe <june@causal.agency> | 2021-10-03 16:06:51 -0400 |
commit | d2a4c96a7993fea9c765644bfc2341d5b9209030 (patch) | |
tree | 42ff006bc80aac05d936c75085c74df8b668eb90 | |
parent | Track client idle time (diff) | |
download | pounce-d2a4c96a7993fea9c765644bfc2341d5b9209030.tar.gz pounce-d2a4c96a7993fea9c765644bfc2341d5b9209030.zip |
Send PING to idle clients after 15 minutes
This is to keep TCP connections to clients from being idle for more than 15 minutes, since regular PINGs from the server are answered by pounce and not relayed to clients. Note that there is still no timeout on poll(2) unless there are need clients. We assume that we are receiving (and swallowing) regular PINGs from the server at an interval shorter than 15 minutes, so a poll(2) timeout would be pointless.
-rw-r--r-- | bounce.c | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/bounce.c b/bounce.c index ef256bc..ae75dc6 100644 --- a/bounce.c +++ b/bounce.c @@ -475,19 +475,24 @@ int main(int argc, char *argv[]) { eventAdd(server, NULL); size_t clientIndex = event.len; + enum { + NeedTime = 10, + IdleTime = 15 * 60, + }; for (;;) { enum Need needs = 0; + time_t now = time(NULL); for (size_t i = clientIndex; i < event.len; ++i) { struct Client *client = event.clients[i]; event.fds[i].events = POLLIN; - if (!client->need && ringDiff(client->consumer)) { + needs |= client->need; + if (client->need) continue; + if (ringDiff(client->consumer) || now - client->idle >= IdleTime) { event.fds[i].events |= POLLOUT; } - needs |= client->need; } - int timeout = 10000; - int ready = poll(event.fds, event.len, (needs ? timeout : -1)); + int ready = poll(event.fds, event.len, (needs ? NeedTime * 1000 : -1)); if (ready < 0 && errno != EINTR) err(EX_IOERR, "poll"); if (needs) { @@ -495,7 +500,7 @@ int main(int argc, char *argv[]) { for (size_t i = event.len - 1; i >= clientIndex; --i) { struct Client *client = event.clients[i]; if (!client->need) continue; - if (now - client->time < timeout / 1000) continue; + if (now - client->time < NeedTime) continue; clientFree(client); eventRemove(i); } @@ -507,7 +512,12 @@ int main(int argc, char *argv[]) { struct Client *client = event.clients[i]; if (client) { - if (revents & POLLOUT) clientConsume(client); + if (revents & POLLOUT) { + clientConsume(client); + if (now - client->idle >= IdleTime) { + clientFormat(client, "PING :%s\r\n", ORIGIN); + } + } if (revents & POLLIN) clientRecv(client); if (client->error || revents & (POLLHUP | POLLERR)) { clientFree(client); |