summaryrefslogtreecommitdiff
path: root/structures.h
blob: d070638d7e5f1362c73794a77abc51e956d4df0a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/*
 * This file is part of blabouncer (https://www.blatech.co.uk/l_bratch/blabouncer).
 * Copyright (C) 2019 Luke Bratch <luke@bratch.co.uk>.
 *
 * Blabouncer is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, version 3.
 *
 * Blabouncer is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with blabouncer. If not, see <http://www.gnu.org/licenses/>.
*/

#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 MAXCHANKEYLEN 24 // Maxium channel key length, 23 determined by testing various clients/servers (plus one for null terminator)
#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 CLIENTCODELEN 17 // Max length of a client code + 1 for null
#define MAXCLIENTCODES 64 // Max number of client codes to track
#define MAXCONFARR 40 // Max number of entries that a configuration array can have
#define MAXCHANNICKS 8192 // Maximum number of nicks to track per channel

struct ircdstate {
  char greeting001[MAXDATASIZE];
  char greeting002[MAXDATASIZE];
  char greeting003[MAXDATASIZE];
  char greeting004[MAXDATASIZE];
  char greeting005a[MAXDATASIZE];
  char greeting005b[MAXDATASIZE];
  char greeting005c[MAXDATASIZE];
  char ircdname[MAXDATASIZE]; // In both settings and ircdstate as settings is from our file whereas server may change ircdstate copy
  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 timeoutcheck; // Whether we're checking to see if we've timed out 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
  int clientchangetime; // The last time a client registered or disconnected
  int clientsnonetime; // The last time there were no clients registered
  int launchtime; // The time blabouncer was launched
  int maxchannelcount; // The maximum number of channels we've ever been in (so we know how much of the channels struct is initialised)
};

// Structure of settings either to be read from the configuration file or set/changed at runtime
struct settings {
  char replaymode[MAXDATASIZE];
  int replayseconds;
  char clientport[MAXPORTLEN];
  char ircnicks[MAXCONFARR][MAXDATASIZE]; // MAXDATASIZE instead of MAXNICKLENGTH so getconfarr() only has one string size to deal with
  char ircusername[MAXUSERNAMELEN]; // (Is this also true for the username?  Can the server change that?)
  char ircrealname[MAXREALNAMELEN];
  char password[MAXDATASIZE];
  char autochannels[MAXCONFARR][MAXDATASIZE]; // MAXDATASIZE instead of MAXCHANLENGTH + 1 + MAXCHANKEYLEN so getconfarr() only has one string size to deal with
  char ircserver[HOST_NAME_MAX];
  char ircserverport[MAXPORTLEN];
  char ircserverpassword[MAXDATASIZE - 5]; // -5 for "PASS "
  char connectcommands[MAXCONFARR][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)
  int replaydates; // Whether or not to include datestamps when replaying the replay log
};

// Structure of a connected client, 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 pendingsslaccept; // Whether the client is still pending SSL_accept() completing (when in client TLS mode only)
  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).
  char clientcode[CLIENTCODELEN]; // This client's client code
  char remoteip[INET6_ADDRSTRLEN]; // Client's remote IP address (assume up to IPv6 size)
};

// Structure of client codes.  Used to track the last time a client identifying as a given client connected to handle auto replay for a known client.
struct clientcodes {
  char code[CLIENTCODELEN]; // The client code string
  int lastdisconnected; // When this client code last disconnected
};

// 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?
  char nicks[MAXCHANNICKS][MAXNICKLENGTH]; // Nicks in the channel to track things like nick changes and quits for log files
};

#endif