From 5ebe08c1afaee5b9570899f16c3c79b6832532d2 Mon Sep 17 00:00:00 2001 From: Luke Bratch Date: Sat, 18 May 2019 18:37:43 +0100 Subject: Accurately track the number of connected clients. --- blabouncer.c | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/blabouncer.c b/blabouncer.c index 812f91e..23042c4 100644 --- a/blabouncer.c +++ b/blabouncer.c @@ -5,7 +5,6 @@ // - Might need to change channel struct nicks to be channel struct user struct with its own nick/modes/etc. // - Do we actually need to store the modes in the channel struct? // - Get CAP from server and relay to client -// - "01:53:47 -!- ServerMode/#test [b] by irc.tghost.co.uk" on existing clients when new client connects // - Keep track of changing user modes in channels // - Should replay log do more than PRIVMSGs? // - Check authentication before even getting to the send functions to save unnecessary processing @@ -14,10 +13,6 @@ // - Alert when clients connect/authenticate/disconnect // - Perhaps rename clients.ssl and server_ssl since they may not even be OpenSSL sockets // - Is it possible to replay JOINs/PARTs accurately? -// - Some/all types of disconnect don't decrement num_clients -// -// Example WHOIS reply: -// BOUNCER-SERVER RECEIVED: :irc.tghost.co.uk 307 blabounce l_bratch :is identified for this nick // "server" means the real IRC server // "client" means bouncer clients @@ -551,6 +546,20 @@ int doreplay(int sourcefd, int replayseconds, struct client *clients, struct set return 1; } +// Return a count of the number of connected clients +int numclients(struct client *clients) { + int count = 0; + + for (int i = 0; i < MAXCLIENTS; i++) { + if (clients[i].fd) { + count++; + } + } + + printf("numclients(): '%d' clients connected.\n", count); + return count; +} + // Figure out what to do with each CRLF-split IRC message (if anything) // by splitting out the different components by space character (ASCII 0x20). // @@ -1387,7 +1396,6 @@ void dochat(int *serversockfd, int *clientsockfd, struct settings *settings) { int servernumbytes; // Number of bytes received from remote server char outgoingmsg[MAXDATASIZE]; // String to send to server int outgoingmsgrc; // Return code from getstdin() for outgoing message - int num_clients = 0; // Current number of clients int fdmax; // highest numbered socket fd @@ -1612,7 +1620,7 @@ void dochat(int *serversockfd, int *clientsockfd, struct settings *settings) { if (i == *clientsockfd) { printf("...new connection!\n"); // handle new connections - if (num_clients >= MAXCLIENTS) { + if (numclients(clients) >= MAXCLIENTS) { fprintf(stderr, "too many clients!\n"); exit(1); // TODO - handle cleanly instead of exiting! } @@ -1651,9 +1659,8 @@ void dochat(int *serversockfd, int *clientsockfd, struct settings *settings) { } } // TODO - Handle the "find a free element" loop not finding a free element - num_clients++; // Track total number of clients printf("bouncer-client: new connection from %s on socket %d\n", inet_ntop(remoteaddr.ss_family, get_in_addr((struct sockaddr*)&remoteaddr), remoteIP, INET6_ADDRSTRLEN), newfd); - printf("bouncer-client: total client connections: %d\n", num_clients); + printf("bouncer-client: total client connections: %d\n", numclients(clients)); } } else { printf("...previous connection!\n"); @@ -1670,8 +1677,7 @@ void dochat(int *serversockfd, int *clientsockfd, struct settings *settings) { disconnectclient(i, 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 // 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); + printf("bouncer-client: total client connections: %d\n", numclients(clients)); } else { // we got some data from a client // null terminate that baby @@ -1809,8 +1815,6 @@ int main(int argc, char *argv[]) { // TODO: see if any of this can be shared (i.e. 1. avoid code duplication, and 2. see if variables can be shared between client/server sockets) - // TODO: track fdmax - kind of doing this now with arr_clients and num_clients but might be pointlessly tracking both in some places (?) - // I will try to keep to the notation of "server" meaning the real IRCd, "bouncer" meaning the bouncer, and "client" meaning the real IRC client // BOUNCER-TO-SERVER socket things -- cgit v1.2.3