about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2020-11-20 17:43:51 -0500
committerJune McEnroe <june@causal.agency>2020-11-20 17:43:51 -0500
commitfaebbec64b4b36f608dbb0af20b5763ba1281b9b (patch)
treed15f99eff59f0cd2de23700aa78da3b76a82ee0d
parentOnly allow clients to AUTHENTICATE if using a cert (diff)
downloadpounce-faebbec64b4b36f608dbb0af20b5763ba1281b9b.tar.gz
pounce-faebbec64b4b36f608dbb0af20b5763ba1281b9b.zip
Add lazy client registration timeout
I don't think this is worth adding a configuration option for since real
clients will definitely accomplish registration faster than 10s and it's
long enough to even type out manually for testing.
-rw-r--r--bounce.c20
-rw-r--r--bounce.h1
-rw-r--r--client.c1
3 files changed, 18 insertions, 4 deletions
diff --git a/bounce.c b/bounce.c
index a96f753..5ef255e 100644
--- a/bounce.c
+++ b/bounce.c
@@ -25,7 +25,6 @@
  * covered work.
  */
 
-#include <assert.h>
 #include <err.h>
 #include <errno.h>
 #include <fcntl.h>
@@ -44,6 +43,7 @@
 #include <sys/stat.h>
 #include <sys/time.h>
 #include <sysexits.h>
+#include <time.h>
 #include <tls.h>
 #include <unistd.h>
 
@@ -458,8 +458,9 @@ int main(int argc, char *argv[]) {
 	eventAdd(server, NULL);
 
 	for (;;) {
+		bool need = false;
 		for (size_t i = binds + 1; i < event.len; ++i) {
-			assert(event.clients[i]);
+			if (event.clients[i]->need) need = true;
 			if (clientDiff(event.clients[i])) {
 				event.fds[i].events |= POLLOUT;
 			} else {
@@ -467,9 +468,21 @@ int main(int argc, char *argv[]) {
 			}
 		}
 
-		int nfds = poll(event.fds, event.len, -1);
+		const int Timeout = 10;
+		int nfds = poll(event.fds, event.len, (need ? Timeout * 1000 : -1));
 		if (nfds < 0 && errno != EINTR) err(EX_IOERR, "poll");
 
+		if (need) {
+			time_t now = time(NULL);
+			for (size_t i = event.len - 1; i >= binds + 1; --i) {
+				struct Client *client = event.clients[i];
+				if (client->need && now - client->time >= Timeout) {
+					clientFree(client);
+					eventRemove(i);
+				}
+			}
+		}
+
 		for (size_t i = event.len - 1; nfds > 0 && i < event.len; --i) {
 			short revents = event.fds[i].revents;
 			if (!revents) continue;
@@ -537,7 +550,6 @@ int main(int argc, char *argv[]) {
 
 	serverFormat("QUIT :%s\r\n", quit);
 	for (size_t i = binds + 1; i < event.len; ++i) {
-		assert(event.clients[i]);
 		if (!event.clients[i]->need) {
 			clientFormat(
 				event.clients[i], ":%s QUIT :%s\r\nERROR :Disconnecting\r\n",
diff --git a/bounce.h b/bounce.h
index 5d6c4a2..d08f21f 100644
--- a/bounce.h
+++ b/bounce.h
@@ -195,6 +195,7 @@ struct Client {
 	bool error;
 	int sock;
 	struct tls *tls;
+	time_t time;
 	enum Need need;
 	enum Cap caps;
 	size_t consumer;
diff --git a/client.c b/client.c
index ea28d82..7b0abba 100644
--- a/client.c
+++ b/client.c
@@ -54,6 +54,7 @@ struct Client *clientAlloc(int sock, struct tls *tls) {
 	fcntl(sock, F_SETFL, O_NONBLOCK);
 	client->sock = sock;
 	client->tls = tls;
+	client->time = time(NULL);
 	client->need = NeedHandshake | NeedNick | NeedUser;
 	if (clientPass) client->need |= NeedPass;
 	return client;