summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Bratch <luke@bratch.co.uk>2019-05-08 13:38:52 +0100
committerLuke Bratch <luke@bratch.co.uk>2019-05-08 13:38:52 +0100
commit960c5aec0a92a3716dfb55532eb0f84be0db6f57 (patch)
treed459c0e5d29b940d84bab81d74a3fb95ac2d4106
parent50d73b6938c62a3f5df91dda0fa3a91baee52127 (diff)
Close and clear up disconnecting clients promptly
-rw-r--r--blabouncer.c36
1 files 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);