From 7d5fbb2c855ebe7e2a0dc373bfd3943e4728c750 Mon Sep 17 00:00:00 2001 From: Luke Bratch Date: Thu, 18 Apr 2019 01:07:44 +0200 Subject: Move multiple (duplicated) relaying to all clients stuff to a function --- blabouncer.c | 91 ++++++++++++++++++++++++++++-------------------------------- 1 file changed, 43 insertions(+), 48 deletions(-) (limited to 'blabouncer.c') diff --git a/blabouncer.c b/blabouncer.c index 23454cb..07784a9 100644 --- a/blabouncer.c +++ b/blabouncer.c @@ -89,6 +89,7 @@ void *get_in_addr(struct sockaddr *sa) { return &(((struct sockaddr_in6*)sa)->sin6_addr); } +// Create socket to connect to real IRC server int createserversocket(char *host, char *port) { int sockfd; struct addrinfo hints, *servinfo, *p; @@ -133,6 +134,7 @@ int createserversocket(char *host, char *port) { return sockfd; } +// Create listening socket to listen for bouncer client connections int createclientsocket(char *listenport) { listenport = BOUNCERLISTENPORT; @@ -205,6 +207,40 @@ int createclientsocket(char *listenport) { return listener; } +// Relay/send message to all clients (optionally except one) +// "except" is used to send to all clients _except_ the fd provided (except = 0 avoids this, i.e. sends to all) +int sendtoallclients(int *clientsockfd, int fdmax, int arr_clients[], char *str, int str_len, int except) { + + char *sendertype; + + if (except) { + sendertype = "bouncer-client"; + } else { + sendertype = "bouncer-server"; + } + + // relay/send to all clients... + for (int i = *clientsockfd + 1; i <= fdmax; i++) { + // Skip the current client if "except" non-zero (no need to send back to itself) + if (i == except) { + continue; + } + // TODO maybe see if things are in rfds (not sure what this means any more - perhaps it was to do with only sending to connected things which is now solved) + // ...but only if they are connected + for (int j = 0; j < MAXCLIENTS; j++) { + if (arr_clients[j] == i) { + printf("%s: sending %s to client with fd %d.\n", sendertype, str, i); + if (send(i, str, str_len, 0) == -1) { + perror("send"); + } + } + } + } + + return 0; +} + +// Where the big bouncing loop is void dochat(int *serversockfd, int *clientsockfd) { char serverbuf[MAXDATASIZE]; // buffer for receiving data on server socket char clientbuf[MAXDATASIZE]; // buffer for receiving data on client socket(s) @@ -241,11 +277,7 @@ void dochat(int *serversockfd, int *clientsockfd) { // Add all connected clients to monitor (only add ones that are connected (clients[i] > 0)) // TODO - make sure *serversockfd stays at the same value (probably 3?) in all cases - what if the server disconnects/reconnects/etc. - // TODO - only monitor connected clients perhaps? (Keep track of connected clients in some array rather than going x to fdmax each time - there may be gaps of disconnected sockets) -// for (int i = *serversockfd; i <= fdmax; i++) { -// printf("adding fd %d.\n", i); -// FD_SET(i, &rfds); -// } + // TODO - now that only connected clients are monitored, perhaps tracking using both fdmax and num_client loops is unnecessary? for (int i = 0; i < MAXCLIENTS; i++) { if (arr_clients[i] > 0) { printf("monitoring fd %d.\n", arr_clients[i]); @@ -258,9 +290,6 @@ void dochat(int *serversockfd, int *clientsockfd) { if (select(fdmax + 1, &rfds, NULL, NULL, NULL) < 0) { // network socket + 1, rfds, no writes, no exceptions/errors, no timeout printf("receive error, exiting!?\n"); perror("select"); - // TODO exit here? let's try it. -// OK temporarily (?) removed the exit again - surely if there's a problem we just ditch the fd and move on? -// exit(1); } // TODO - switch around the serversockfd and STDIN FD_ISSET if-statements? They feel the wrong way round. Are they like this on purpose? I can't remember. @@ -283,20 +312,8 @@ void dochat(int *serversockfd, int *clientsockfd) { printf("BOUNCER-SERVER RECEIVED: %s\n", serverbuf); printf("bouncer-server: sending it to all clients...\n"); - // relay/send to all clients... - for (int i = *clientsockfd + 1; i <= fdmax; i++) { - // TODO maybe see if things are in rfds - // TODO function this send-to-all baby up (used in approximately two places so far) - // ...but only if they are connected - for (int j = 0; j < MAXCLIENTS; j++) { - if (arr_clients[j] == i) { - printf("bouncer-server: sending to client with fd %d.\n", i); - if (send(i, serverbuf, servernumbytes, 0) == -1) { - perror("send"); - } - } - } - } + // Relay/send to all clients ("except" = 0 because this should send to all clients) + sendtoallclients(clientsockfd, fdmax, arr_clients, serverbuf, servernumbytes, 0); } // see if there's anything from stdin @@ -400,31 +417,9 @@ void dochat(int *serversockfd, int *clientsockfd) { printf("send error, exiting...\n"); perror("send"); } - // send the same thing to all *other* clients - for (int j = *clientsockfd + 1; j <= fdmax; j++) { - // TODO maybe see if things are in rfds - // TODO function this send-to-all baby up (used in approximately two places so far) - // skip the current client (no need to send back to itself) - if (j == i) { - continue; - } - printf("bouncer-client: sending to client with fd %d.\n", j); - if (send(j, clientbuf, strlen(clientbuf), 0) == -1) { - perror("send"); - } - } - //~ // THIS GOOD STUFF FOR THE BOUNCING - //~ for(j = 0; j <= fdmax; j++) { - //~ // send to everyone! - //~ if (FD_ISSET(j, &master)) { - //~ // except the listener and ourselves - //~ if (j != listener && j != i) { - //~ if (send(j, buf, nbytes, 0) == -1) { - //~ perror("send"); - //~ } - //~ } - //~ } - //~ } + + // send the same thing to all *other* clients (all except for fd "i") + sendtoallclients(clientsockfd, fdmax, arr_clients, clientbuf, strlen(clientbuf), i); } } } @@ -447,7 +442,7 @@ 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 + // 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 -- cgit v1.2.3