summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--blabouncer.c84
-rw-r--r--structures.h88
2 files changed, 91 insertions, 81 deletions
diff --git a/blabouncer.c b/blabouncer.c
index a421bed..e1f2a96 100644
--- a/blabouncer.c
+++ b/blabouncer.c
@@ -45,6 +45,7 @@
#include "config.h"
#include "replay.h"
#include "logging.h"
+#include "structures.h"
#define SOURCE_SERVER 0
#define SOURCE_CLIENT 1
@@ -61,22 +62,15 @@
#define SIGINT 2 // SIGINT is signal 2
#define SIGTERM 15 // SIGTERM is signal 15
+// Various important limits - note that several related ones are defined in structures.h
+
// It seems to be that *message length* is max 512 bytes, but a socket read from at least UnrealIRCd seems to be up to at least 2416 (+1 for null) bytes.
// 1208 bytes with OpenSSL, 2416 bytes with plain text.
#define MAXRCVSIZE 2417
-#define MAXDATASIZE 513 // max number of bytes we can get at once (RFC2812 says 512, plus one for null terminator)
#define MAXCLIENTS 32 // maximum number of clients that can connect to the bouncer at a time
#define MAXTOKENS 100 // maximum number of (CRLF or space) separated tokens per server response we expect (TODO - check this is reasonable) (CRLF and spaces just grouped here due to laziness)
-#define MAXPONGSIZE 32 // let's assume PING/PONG responses can't be larger than this (TODO - check this [it's totally made up]!)
#define MAXCHANNELS 1024 // let's assume 1024 is reasonable for now (it's configured per IRCd)
-#define MAXCHANLENGTH 50 // 50 according to RFC 2811 and RFC 2822
-#define MAXCHANUSERS 8192 // Randomly picked (TODO - is there an actual maximum number of users per channel?)
-#define MAXNICKLENGTH 64 // Randomly picked (TODO - is there an actual maximum number (ignoring the RFC preference of 9)?)
#define MAXRFCNICKLEN 9 // From RFC 1459
-#define MAXUSERNAMELEN 64 // Randomly picked (TODO - is there an actual maximum username length?)
-#define MAXREALNAMELEN 128 // Randomly picked (TODO - is there an actual maximum real name length?)
-#define MAXPORTLEN 6 // Up to 65535, so 5 characters + 1 for null
-#define MAXAUTOCHANLEN 1024 // Randomly picked maximum length of the auto channel list
#define SERVERTIMEOUT 300 // How many seconds to wait without hearing from the server before assuming a timeout
// Global debug control
@@ -86,78 +80,6 @@ char debugpath[PATH_MAX]; // Path to debug file
// Set if certain signal (just SIGINT and SIGKILL at time of writing) is received
int signum = 0;
-struct channel {
- char name[MAXCHANLENGTH];
- char topic[MAXDATASIZE]; // TODO - Is there a particular maximum topic length?
- char topicwho[MAXNICKLENGTH];
- // TODO - Make this Year 2038 proof
- // TODO - Make this an int? It's just going to arrive and leave as a string every time anyway...
- char topicwhen[11]; // 32-bit unixtime is up to 10 characters (+1 for null char) We use "0" to mean "not set".
- int gotnames; // Have we finished getting the RPL_NAMREPLYs for this channel yet?
-};
-
-// TODO - Rename this or split into multiple structs since it's no longer strictly just IRCd strings
-struct ircdstrings {
- char greeting001[MAXDATASIZE];
- char greeting002[MAXDATASIZE];
- char greeting003[MAXDATASIZE];
- char greeting004[MAXDATASIZE];
- char greeting005a[MAXDATASIZE];
- char greeting005b[MAXDATASIZE];
- char greeting005c[MAXDATASIZE];
- char ircdname[MAXDATASIZE];
- char nickuserhost[MAXDATASIZE];
- char ircnick[MAXNICKLENGTH];
- char ircusername[MAXUSERNAMELEN];
- char currentmsg[MAXDATASIZE]; // Holding area for the current server-received IRC message being processed in case it needs building across multiple reads (i.e. a truncated/split message)
- char mode[MAXDATASIZE];
- int capmultiprefix; // Whether the server approved our CAP multi-prefix request
- int autonicknum; // Number of attempts made at automatically setting a nick if all configured nicks were in use
- int lastmessagetime; // The last time we heard from the server
- int reconnecting; // Whether or not we're reconnecting due to an earlier disconnection
- char oldnick[MAXNICKLENGTH]; // Set temporarily if we end up reconnecting in case we need to tell existing clients about a nick change
-};
-
-// Structure of settings either to be read from the configuration file or set/changed at runtime
-struct settings {
- int replayseconds;
- char clientport[MAXPORTLEN];
- char ircnick[MAXNICKLENGTH]; // In both settings and ircdstrings as settings is from our file whereas server may change ircdstrings copy
- char ircusername[MAXUSERNAMELEN]; // (Is this also true for the username? Can the server change that?)
- char ircrealname[MAXREALNAMELEN];
- char autochannels[MAXAUTOCHANLEN];
- char ircserver[HOST_NAME_MAX];
- char ircserverport[MAXPORTLEN];
- char ircserverpassword[MAXDATASIZE - 5]; // -5 for "PASS "
- char connectcommand[MAXDATASIZE];
- char conffile[PATH_MAX];
- char certfile[PATH_MAX];
- char keyfile[PATH_MAX];
- int clienttls;
- int servertls;
- char basedir[PATH_MAX];
- int logging;
- int replaylogging;
- int debugkeep;
- int background; // Whether or not we're running in the background (detached from the terminal as a daemon)
-};
-
-// Structure of connected clients, their socket/file descriptors, their authentication status, and their OpenSSL structures
-struct client {
- int fd; // Client socket fd - 0 means not connected, greater than 0 means connected and the value is the fd number (so we know which ones to try to read and send to)
- int authed; // Client authentication status - 0 means not authenticated, 1 means authenticated.
- SSL *ssl; // OpenSSL structures when using TLS, or faked by casting fd ints to SSL* if not. - TODO - Can we drop one of either "int fd" or "SSL *ssl" now?
- int registered; // Whether the client has finished registering with the bouncer
- int pendingchannelmode; // Whether the client is waiting to hear back from a "MODE #channel" command
- int pendingban; // Whether the client is waiting to hear back from a "MODE #channel b" command
- int pendingwho; // Whether the client is waiting to hear back from a "MODE #channel" command
- int pendinglist; // Whether the client is waiting to hear back from a "LIST" command
- int pendingwhois; // Whether the client is waiting to hear back from a "WHOIS" command
- int pendingwhowas; // Whether the client is waiting to hear back from a "WHOWAS" command
- int pendingnames; // Count of RPL_NAMREPLYs the client is waiting on.
- int pendingcap; // Whether the client is still negotiating IRCv3 CAPabilities. 0 = no, 1 = yes, -1 = just finished (so register them as if they had just sent USER).
-};
-
// Signal handler
// We don't actually do anything in here, the main pselect() notice signals
void sighandler(int sig) {
diff --git a/structures.h b/structures.h
new file mode 100644
index 0000000..34e8896
--- /dev/null
+++ b/structures.h
@@ -0,0 +1,88 @@
+#ifndef STRUCTURES_H_INCLUDED
+#define STRUCTURES_H_INCLUDED
+
+#include <openssl/ssl.h>
+
+#define MAXDATASIZE 513 // max number of bytes we can get at once (RFC2812 says 512, plus one for null terminator)
+#define MAXCHANLENGTH 50 // 50 according to RFC 2811 and RFC 2822
+#define MAXNICKLENGTH 64 // Randomly picked (TODO - is there an actual maximum number (ignoring the RFC preference of 9)?)
+#define MAXUSERNAMELEN 64 // Randomly picked (TODO - is there an actual maximum username length?)
+#define MAXREALNAMELEN 128 // Randomly picked (TODO - is there an actual maximum real name length?)
+#define MAXPORTLEN 6 // Up to 65535, so 5 characters + 1 for null
+#define MAXAUTOCHANLEN 1024 // Randomly picked maximum length of the auto channel list
+
+// TODO - Rename this or split into multiple structs since it's no longer strictly just IRCd strings
+struct ircdstrings {
+ char greeting001[MAXDATASIZE];
+ char greeting002[MAXDATASIZE];
+ char greeting003[MAXDATASIZE];
+ char greeting004[MAXDATASIZE];
+ char greeting005a[MAXDATASIZE];
+ char greeting005b[MAXDATASIZE];
+ char greeting005c[MAXDATASIZE];
+ char ircdname[MAXDATASIZE];
+ char nickuserhost[MAXDATASIZE];
+ char ircnick[MAXNICKLENGTH];
+ char ircusername[MAXUSERNAMELEN];
+ char currentmsg[MAXDATASIZE]; // Holding area for the current server-received IRC message being processed in case it needs building across multiple reads (i.e. a truncated/split message)
+ char mode[MAXDATASIZE];
+ int capmultiprefix; // Whether the server approved our CAP multi-prefix request
+ int autonicknum; // Number of attempts made at automatically setting a nick if all configured nicks were in use
+ int lastmessagetime; // The last time we heard from the server
+ int reconnecting; // Whether or not we're reconnecting due to an earlier disconnection
+ char oldnick[MAXNICKLENGTH]; // Set temporarily if we end up reconnecting in case we need to tell existing clients about a nick change
+};
+
+// Structure of settings either to be read from the configuration file or set/changed at runtime
+struct settings {
+ int replayseconds;
+ char clientport[MAXPORTLEN];
+ char ircnick[MAXNICKLENGTH]; // In both settings and ircdstrings as settings is from our file whereas server may change ircdstrings copy
+ char ircusername[MAXUSERNAMELEN]; // (Is this also true for the username? Can the server change that?)
+ char ircrealname[MAXREALNAMELEN];
+ char autochannels[MAXAUTOCHANLEN];
+ char ircserver[HOST_NAME_MAX];
+ char ircserverport[MAXPORTLEN];
+ char ircserverpassword[MAXDATASIZE - 5]; // -5 for "PASS "
+ char connectcommand[MAXDATASIZE];
+ char conffile[PATH_MAX];
+ char certfile[PATH_MAX];
+ char keyfile[PATH_MAX];
+ int clienttls;
+ int servertls;
+ char basedir[PATH_MAX];
+ int logging;
+ int replaylogging;
+ int debugkeep;
+ int background; // Whether or not we're running in the background (detached from the terminal as a daemon)
+};
+
+// Structure of a connected clien, their socket/file descriptors, their authentication status, and their OpenSSL structures
+// This struct is expected to be in an array of client structs
+struct client {
+ int fd; // Client socket fd - 0 means not connected, greater than 0 means connected and the value is the fd number (so we know which ones to try to read and send to)
+ int authed; // Client authentication status - 0 means not authenticated, 1 means authenticated.
+ SSL *ssl; // OpenSSL structures when using TLS, or faked by casting fd ints to SSL* if not. - TODO - Can we drop one of either "int fd" or "SSL *ssl" now?
+ int registered; // Whether the client has finished registering with the bouncer
+ int pendingchannelmode; // Whether the client is waiting to hear back from a "MODE #channel" command
+ int pendingban; // Whether the client is waiting to hear back from a "MODE #channel b" command
+ int pendingwho; // Whether the client is waiting to hear back from a "MODE #channel" command
+ int pendinglist; // Whether the client is waiting to hear back from a "LIST" command
+ int pendingwhois; // Whether the client is waiting to hear back from a "WHOIS" command
+ int pendingwhowas; // Whether the client is waiting to hear back from a "WHOWAS" command
+ int pendingnames; // Count of RPL_NAMREPLYs the client is waiting on.
+ int pendingcap; // Whether the client is still negotiating IRCv3 CAPabilities. 0 = no, 1 = yes, -1 = just finished (so register them as if they had just sent USER).
+};
+
+// Structure of a channel - this struct is expected to be in an array of channel structs
+struct channel {
+ char name[MAXCHANLENGTH];
+ char topic[MAXDATASIZE]; // TODO - Is there a particular maximum topic length?
+ char topicwho[MAXNICKLENGTH];
+ // TODO - Make this Year 2038 proof
+ // TODO - Make this an int? It's just going to arrive and leave as a string every time anyway...
+ char topicwhen[11]; // 32-bit unixtime is up to 10 characters (+1 for null char) We use "0" to mean "not set".
+ int gotnames; // Have we finished getting the RPL_NAMREPLYs for this channel yet?
+};
+
+#endif