From 960c5aec0a92a3716dfb55532eb0f84be0db6f57 Mon Sep 17 00:00:00 2001 From: Luke Bratch Date: Wed, 8 May 2019 13:38:52 +0100 Subject: Close and clear up disconnecting clients promptly --- blabouncer.c | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/blabouncer.c b/blabouncer.c index 489dccf..f0e57dd 100644 --- a/blabouncer.c +++ b/blabouncer.c @@ -7,7 +7,6 @@ // - Get CAP from server and relay to client // - Add blabouncer MOTD (375, 372, 376) // - Need to delete channels from struct when PARTing them -// - Disconnecting a client is slow for the client (Please wait, waiting for servers to close connections.." // - "01:53:47 -!- ServerMode/#test [b] by irc.tghost.co.uk" on existing clients when new client connects // // Example WHOIS reply: @@ -84,6 +83,25 @@ int sendtoclient(int fd, char *str) { return 1; } +// Disconnect the client fd "fd" by close()ing it and remove +// it from the arr_clients array of clients +int disconnectclient(int fd, int arr_clients[]) { + printf("disconnectclient(): disconnecting client fd '%d'\n", fd); + close(fd); // bye! + // Remove the client from the clients array + for (int j = 0; j < MAXCLIENTS; j++) { + if (arr_clients[j] == fd) { + printf("found and clearing fd %d from arr_clients[%d]\n", fd, j); + arr_clients[j] = 0; + return 1; + } + } + + // If we got here, we didn't find and clear the client + // TODO - Do something with a failed return code + return 0; +} + // Relay/send message to all clients (optionally except one) // "except" is used to send to all clients _except_ the fd provided (except = 0 (EXCEPT_NONE) avoids this, i.e. sends to all) // TODO - is passing str_len useful if we're appendcrlfing and then using strlen(str) in the send? I guess not... (As long as we're always null terminated in the correct place.) @@ -518,8 +536,11 @@ int processircmessage(int *serversockfd, int *clientsockfd, char *str, int sourc } // Don't do anything with QUIT, just let the client go - TODO: Let another clients know with a NOTICE or something + // A client has QUIT, so disconnect (close) them and don't do anything else for now - TODO: Let another clients know with a NOTICE or something if (strncmp(tokens[0], "QUIT", strlen(tokens[0])) == 0) { - printf("Client QUITfound and it is: %s with length %zd! Doing nothing at all.\n", tokens[0], strlen(tokens[0])); + printf("Client QUIT found from fd %d and it is: %s with length %zd! Disconnecting that fd.\n", sourcefd, tokens[0], strlen(tokens[0])); + close(sourcefd); + disconnectclient(sourcefd, arr_clients); return 1; } break; @@ -803,16 +824,9 @@ void dochat(int *serversockfd, int *clientsockfd) { } else { perror("recv"); } - close(i); // bye! + // Disconnect the client + disconnectclient(i, arr_clients); FD_CLR(i, &rfds); // remove from master set - TODO is this needed at the moment since we just add everything from *clientsockfd to fdmax to rfds - // Remove the client from the clients array - for (int j = 0; j < MAXCLIENTS; j++) { - if (arr_clients[j] == i) { - printf("found and clearing fd %d from arr_clients[%d]\n", i, j); - arr_clients[j] = 0; - break; - } - } // TODO - Handle the "remove the client" loop not finding the old fd num_clients--; // Track total number of clients printf("bouncer-client: total client connections: %d\n", num_clients); -- cgit v1.2.3