From 3b2b776a1f3684429c5014b964db54737e662dda Mon Sep 17 00:00:00 2001 From: Luke Bratch Date: Tue, 1 Aug 2023 23:52:31 +0100 Subject: Correctly handle too many clients by doing accept() and close() immediately rather than trying to add to clients[] struct. --- blabouncer.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'blabouncer.c') diff --git a/blabouncer.c b/blabouncer.c index 878dbd1..c56fc9d 100644 --- a/blabouncer.c +++ b/blabouncer.c @@ -790,12 +790,6 @@ void dochat(int *serversockfd, int *clientsockfd, struct settings *settings) { if (i == *clientsockfd) { debugprint(DEBUG_SOME, "...new connection!\n"); // handle new connections - if (numclients(clients) >= MAXCLIENTS) { - fprintf(stderr, "too many clients, disconnecting and skipping loop iteration!\n"); - debugprint(DEBUG_CRIT, "too many clients, disconnecting and skipping loop iteration!\n"); - disconnectclient(i, clients, &ircdstate, settings, clientcodes); - continue; - } addrlen = sizeof remoteaddr; newfd = accept(*clientsockfd, (struct sockaddr *)&remoteaddr, &addrlen); if (newfd == -1) { @@ -814,6 +808,20 @@ void dochat(int *serversockfd, int *clientsockfd, struct settings *settings) { char remoteip[INET6_ADDRSTRLEN]; strncpy(remoteip, inet_ntop(remoteaddr.ss_family, get_in_addr((struct sockaddr*)&remoteaddr), remoteIP, INET6_ADDRSTRLEN), INET6_ADDRSTRLEN); + // accept() and close() immediately if there are too many clients + if (numclients(clients) >= MAXCLIENTS) { + fprintf(stderr, "dochat(): clientsockfd loop: too many clients, disconnecting fd '%d' ('%s') and skipping loop iteration!\n", newfd, remoteip); + debugprint(DEBUG_CRIT, "dochat(): clientsockfd loop: too many clients, disconnecting fd '%d' ('%s') and skipping loop iteration!\n", newfd, remoteip); + char outgoingmsg[MAXDATASIZE]; + if (!snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :too many clients, disconnecting fd '%d' ('%s')!", ircdstate.ircnick, newfd, remoteip)) { + debugprint(DEBUG_CRIT, "dochat(): clientsockfd loop: error while preparing too many clients message!\n"); + outgoingmsg[0] = '\0'; + } + sendtoallclients(clients, outgoingmsg, 0, settings); + close(newfd); + continue; + } + // Find a free element in the clients array and set to new fd value (plus start SSL_accept() if using client TLS) for (int j = 0; j < MAXCLIENTS; j++) { if (clients[j].fd == 0) { -- cgit v1.2.3