summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--blabouncer.c91
1 files changed, 43 insertions, 48 deletions
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