summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Bratch <luke@bratch.co.uk>2023-08-01 23:52:31 +0100
committerLuke Bratch <luke@bratch.co.uk>2023-08-01 23:52:31 +0100
commit3b2b776a1f3684429c5014b964db54737e662dda (patch)
treea7afe14cc691d69118b452d2755c72d858f4858c
parentd499630b0aa2f701ada64c59ab20ac5ff12c19c2 (diff)
Correctly handle too many clients by doing accept() and close() immediately rather than trying to add to clients[] struct.
-rw-r--r--TODO4
-rw-r--r--blabouncer.c20
2 files changed, 17 insertions, 7 deletions
diff --git a/TODO b/TODO
index 6c90f83..6bcc8d3 100644
--- a/TODO
+++ b/TODO
@@ -44,4 +44,6 @@ KICK not handled.
Crash when requesting 30 hour replay.
-"too many clients, disconnecting and skipping loop iteration!" has been seen in the real world, e.g. Wed Jul 12 16:44:57 2023
+Users in channel not being populated observed once - 27/07/2023 #pipewire on irc.oftc.net.
+(related to?):
+11/06/2023 01:00:41 "processrawstring(): combined truncated message '2131365056' is too long (1006 out of a maximum of 512 characters), clearing it." seen during long/truncated/recombined 353 RPL_NAMREPLY #winehq on irc.libera.chat.
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) {