diff options
author | Luke Bratch <luke@bratch.co.uk> | 2025-08-08 22:15:43 +0100 |
---|---|---|
committer | Luke Bratch <luke@bratch.co.uk> | 2025-08-08 22:15:43 +0100 |
commit | cdc21500174966ecf2ca1eedb73eb5aa4d2f344c (patch) | |
tree | 1e5a0ffc13ed4af4b229c6361b9cdfead5e4e769 | |
parent | 53d4843b8d64b4fb928c3790956ccefb4d9e0756 (diff) |
Disconnect zombie clients after a while (if they haven't authenticated after AUTHTIMEOUT seconds).
-rw-r--r-- | TODO | 12 | ||||
-rw-r--r-- | blabouncer.c | 21 | ||||
-rw-r--r-- | functions.c | 1 | ||||
-rw-r--r-- | structures.h | 2 |
4 files changed, 36 insertions, 0 deletions
@@ -55,3 +55,15 @@ QUIT not logged in all channels a person was in? (e.g. Joey Mon 1 Apr 20:49:14 Ability to check for updates (and optional at startup?). Absurd CPU usage and duration doing "/BLABOUNCER REPLAY 24:0" approx. 14/09/2024 17:35. + +User has quit not always listed in all channel log files? (e.g. lebhome 12/11/2024 22:49:37) + +Custom OpenSSL protocols/ciphers? + +NickServ HELP with SA receiving full message in one go? e.g. oper 05/01/2025 10:06:22. Blabouncer or Anope or UnrealIRCD or something else? + +/NAMES doesn't show names in client. + +Allow specifying time zone for timestamps in config. + +Include error messages in response to failed STDIN in STDOUT/STDERR. diff --git a/blabouncer.c b/blabouncer.c index 00d339e..64b6f36 100644 --- a/blabouncer.c +++ b/blabouncer.c @@ -412,6 +412,7 @@ void dochat(int *serversockfd, int *clientsockfd, struct settings *settings) { clients[i].pendingcap = 0; clients[i].clientcode[0] = '\0'; clients[i].remoteip[0] = '\0'; + clients[i].connecttime = 0; } // Struct of various strings from and for the real IRCd (such as the greeting strings, the real IRCd's name, @@ -502,6 +503,23 @@ void dochat(int *serversockfd, int *clientsockfd, struct settings *settings) { } } + // Always check for client timeouts (clients who have been unauthed for AUTHTIMEOUT seconds) to stop the clients array getting filled up + int disconnected = 0; + for (int i = 0; i < MAXCLIENTS; i++) { + if (clients[i].fd > 0 && !clients[i].authed) { + if (time(NULL) > clients[i].connecttime + AUTHTIMEOUT) { + debugprint(DEBUG_SOME, "dochat(): auth timed out for client fd '%d', disconnecting!\n", clients[i].fd); + disconnectclient(clients[i].fd, clients, &ircdstate, settings, clientcodes); + // We disconnected a client, make a note to continue later... + disconnected = 1; + } + } + } + // If we disconnected someone, active client fds might have changed, start the loop again + if (disconnected) { + continue; + } + debugprint(DEBUG_FULL, "pselect()ing...\n"); // Check to see if any fd in the fd_set is waiting or a signal happened - blocks here until one one of those things happens // (pselect() to do signal handling in addition to fd monitoring) @@ -858,6 +876,9 @@ void dochat(int *serversockfd, int *clientsockfd, struct settings *settings) { // Record the remote IP address of this client in the clients array strncpy(clients[j].remoteip, remoteip, INET6_ADDRSTRLEN); + // Record the connect time + clients[j].connecttime = time(NULL); + // If using TLS then... if (settings->clienttls) { // ...set as OpenSSL FD and SSL_accept it diff --git a/functions.c b/functions.c index c3e9c94..6eddc35 100644 --- a/functions.c +++ b/functions.c @@ -663,6 +663,7 @@ int disconnectclient(int fd, struct client *clients, struct ircdstate *ircdstate clients[i].pendingcap = 0; clients[i].clientcode[0] = '\0'; clients[i].remoteip[0] = '\0'; + clients[i].connecttime = 0; if (settings->clienttls) { // Finish up with OpenSSL if using client TLS SSL_free(clients[i].ssl); diff --git a/structures.h b/structures.h index b2585bd..60292ed 100644 --- a/structures.h +++ b/structures.h @@ -31,6 +31,7 @@ #define MAXCLIENTCODES 64 // Max number of client codes to track #define MAXCONFARR 40 // Max number of entries that a configuration array can have #define MAXCHANNICKS 8192 // Maximum number of nicks to track per channel +#define AUTHTIMEOUT 130 // How many seconds to give clients to authenticate, checked at most every SELECTTIMEOUT seconds struct ircdstate { char greeting001[MAXDATASIZE]; @@ -108,6 +109,7 @@ struct client { int pendingcap; // Whether the client is still negotiating IRCv3 CAPabilities. 0 = no, 1 = yes, -1 = just finished (so register them as if they had just sent USER). char clientcode[CLIENTCODELEN]; // This client's client code char remoteip[INET6_ADDRSTRLEN]; // Client's remote IP address (assume up to IPv6 size) + int connecttime; // The time the client connected }; // Structure of client codes. Used to track the last time a client identifying as a given client connected to handle auto replay for a known client. |