summary refs log tree commit diff
diff options
context:
space:
mode:
authorNakidai <nakidai@disroot.org>2026-02-01 18:09:54 +0300
committerNakidai <nakidai@disroot.org>2026-02-01 18:09:54 +0300
commitf47f9d10f8aa3ace1f2d93d0aa6ab090f782328b (patch)
tree44e49c0f2a98e6ba90d7ec79591e51bfd7719a93
parent62869d341d2a4e959b60865076287701694859dd (diff)
downloadlibreircd-f47f9d10f8aa3ace1f2d93d0aa6ab090f782328b.tar.gz
libreircd-f47f9d10f8aa3ace1f2d93d0aa6ab090f782328b.zip
Add ping system
Now users will be kicked for inactivity o.o
-rw-r--r--config.h4
-rw-r--r--handle.c9
-rw-r--r--ircd.h2
-rw-r--r--loop.c39
4 files changed, 45 insertions, 9 deletions
diff --git a/config.h b/config.h
index 19d2958..a1a8c4a 100644
--- a/config.h
+++ b/config.h
@@ -13,3 +13,7 @@
 #define PEER_USER_MAX 16
 #define PEER_REAL_MAX 32
 #define PEER_HOST_MAX 64
+#define PEER_PINGTIMEOUT 120
+#define PEER_PONGTIMEOUT 20
+
+#define POLL_TIMEOUT PEER_PINGTIMEOUT
diff --git a/handle.c b/handle.c
index df36e1f..2f4d0b8 100644
--- a/handle.c
+++ b/handle.c
@@ -167,6 +167,14 @@ ping(struct Message *msg, struct Peer *peer)
 }
 
 static int
+pong(struct Message *msg, struct Peer *peer)
+{
+	peer->ping = 0;
+
+	return 0;
+}
+
+static int
 privmsg(struct Message *msg, struct Peer *peer)
 {
 	size_t i;
@@ -290,6 +298,7 @@ static struct Handler {
 	{ "notice", privmsg },
 	{ "part", part },
 	{ "ping", ping },
+	{ "pong", pong },
 	{ "privmsg", privmsg },
 	{ "quit", quit },
 	{ "user", user },
diff --git a/ircd.h b/ircd.h
index ef8dbc5..fcc6ddc 100644
--- a/ircd.h
+++ b/ircd.h
@@ -18,6 +18,7 @@
 #define __IRCD_H__
 
 #include <stddef.h>
+#include <time.h>
 
 #include "config.h"
 
@@ -55,6 +56,7 @@ struct Peer
 	} modes;
 	char buf[MESSAGE_MAX];
 	size_t recvd, channels_c;
+	time_t last, ping;
 };
 
 struct Channel
diff --git a/loop.c b/loop.c
index fdb2e66..46c585c 100644
--- a/loop.c
+++ b/loop.c
@@ -21,6 +21,7 @@
 #include <err.h>
 #include <poll.h>
 #include <signal.h>
+#include <time.h>
 #include <unistd.h>
 
 #include <arpa/inet.h>
@@ -44,6 +45,7 @@ ircd(void)
 	int res, sfd, client;
 	nfds_t passed;
 	ssize_t recvd;
+	time_t now;
 
 	addr.sin_family = PF_INET;
 	addr.sin_port = htons(port);
@@ -75,7 +77,7 @@ loop:
 			.fd = peers[i].fd,
 			.events = POLLIN,
 		};
-	res = poll(pfd, (passed = peers_c) + 1, -1);
+	res = poll(pfd, (passed = peers_c) + 1, POLL_TIMEOUT);
 	if (res == -1)
 		err(1, "poll()");
 
@@ -95,7 +97,7 @@ loop:
 		}
 		else
 		{
-			peers[peers_c++] = (struct Peer){ .fd = client };
+			peers[peers_c++] = (struct Peer){ .fd = client, .last = time(NULL) };
 			strlcpy(
 				peers[peers_c - 1].host,
 				inet_ntoa(clientaddr.sin_addr),
@@ -109,6 +111,7 @@ loop:
 		if (!(pfd[i].revents & POLLIN))
 			continue;
 
+		time(&peers[i].last);
 		recvd = read(
 			peers[i].fd,
 			peers[i].buf + peers[i].recvd,
@@ -120,13 +123,31 @@ loop:
 	}
 	for (i = 0; i < peers_c; ++i)
 	{
-		if (!(peers[i].flags & DELETE))
-			continue;
-
-		writef(peers[i].fd, "ERROR :Closing Link: %s", peers[i].host);
-		close(peers[i].fd);
-		user_remove(i);
-		--i;
+		time(&now);
+		if (!peers[i].ping && now - peers[i].last > PEER_PINGTIMEOUT)
+		{
+			writef(peers[i].fd, "PING :%s", hostname);
+			peers[i].ping = now;
+		}
+		if (peers[i].ping && now - peers[i].ping > PEER_PONGTIMEOUT)
+		{
+			announce(
+				&peers[i],
+				":%s!%s@%s QUIT :Ping Timeout (%llu seconds)",
+				getnick(&peers[i]),
+				peers[i].user,
+				peers[i].host,
+				now - peers[i].ping
+			);
+			peers[i].flags |= DELETE;
+		}
+		if (peers[i].flags & DELETE)
+		{
+			writef(peers[i].fd, "ERROR :Closing Link: %s", peers[i].host);
+			close(peers[i].fd);
+			user_remove(i);
+			--i;
+		}
 	}
 	goto loop;
 }