2020-03-29 09:16:53 +00:00
/************************************************************************
* Unreal Internet Relay Chat Daemon , include / struct . h
* Copyright ( C ) 1990 Jarkko Oikarinen and
* University of Oulu , Computing Center
*
* This program 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 ; either version 1 , or ( at your option )
* any later version .
*
* This program 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 this program ; if not , write to the Free Software
* Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*
* $ Id $
*/
# ifndef __struct_include__
# define __struct_include__
# include "config.h"
# include "sys.h"
/* need to include ssl stuff here coz otherwise you get
* conflicting types with isalnum / isalpha / etc @ redhat . - - Syzop
*/
# define OPENSSL_NO_KRB5
# include <openssl/rsa.h> /* SSL stuff */
# include <openssl/crypto.h>
# include <openssl/x509.h>
# include <openssl/pem.h>
# include <openssl/ssl.h>
# include <openssl/err.h>
# include <openssl/evp.h>
# include <openssl/rand.h>
# include <openssl/md5.h>
# include <openssl/ripemd.h>
2022-01-15 05:16:34 +00:00
# include <jansson.h>
2020-03-29 09:16:53 +00:00
# include "common.h"
# include "sys.h"
# include <stdio.h>
# include <sys/types.h>
# ifndef _WIN32
# include <netinet/in.h>
# include <netdb.h>
# include <stddef.h>
# endif
# ifdef HAVE_SYSLOG
# include <syslog.h>
# ifdef SYSSYSLOGH
# include <sys / syslog.h>
# endif
2022-01-15 05:16:34 +00:00
# ifndef UNREAL_LOGGER_CODE
/* undef these as they cause confusion with our ULOG_xxx codes */
# undef LOG_DEBUG
# undef LOG_INFO
# undef LOG_WARNING
# undef LOG_ERROR
# undef LOG_FATAL
# endif
2020-03-29 09:16:53 +00:00
# endif
# define PCRE2_CODE_UNIT_WIDTH 8
# include "pcre2.h"
# include "channel.h"
typedef struct LoopStruct LoopStruct ;
typedef struct TKL TKL ;
typedef struct Spamfilter Spamfilter ;
typedef struct ServerBan ServerBan ;
typedef struct BanException BanException ;
typedef struct NameBan NameBan ;
typedef struct SpamExcept SpamExcept ;
typedef struct ConditionalConfig ConditionalConfig ;
typedef struct ConfigEntry ConfigEntry ;
typedef struct ConfigFile ConfigFile ;
typedef struct ConfigFlag ConfigFlag ;
typedef struct ConfigFlag_except ConfigFlag_except ;
typedef struct ConfigFlag_ban ConfigFlag_ban ;
typedef struct ConfigFlag_tld ConfigFlag_tld ;
typedef struct ConfigItem ConfigItem ;
typedef struct ConfigItem_me ConfigItem_me ;
typedef struct ConfigItem_files ConfigItem_files ;
typedef struct ConfigItem_admin ConfigItem_admin ;
typedef struct ConfigItem_class ConfigItem_class ;
typedef struct ConfigItem_oper ConfigItem_oper ;
typedef struct ConfigItem_operclass ConfigItem_operclass ;
typedef struct ConfigItem_mask ConfigItem_mask ;
typedef struct ConfigItem_drpass ConfigItem_drpass ;
typedef struct ConfigItem_ulines ConfigItem_ulines ;
typedef struct ConfigItem_tld ConfigItem_tld ;
typedef struct ConfigItem_listen ConfigItem_listen ;
typedef struct ConfigItem_sni ConfigItem_sni ;
typedef struct ConfigItem_allow ConfigItem_allow ;
typedef struct ConfigFlag_allow ConfigFlag_allow ;
typedef struct ConfigItem_allow_channel ConfigItem_allow_channel ;
typedef struct ConfigItem_allow_dcc ConfigItem_allow_dcc ;
typedef struct ConfigItem_vhost ConfigItem_vhost ;
typedef struct ConfigItem_link ConfigItem_link ;
typedef struct ConfigItem_ban ConfigItem_ban ;
typedef struct ConfigItem_deny_dcc ConfigItem_deny_dcc ;
typedef struct ConfigItem_deny_link ConfigItem_deny_link ;
typedef struct ConfigItem_deny_channel ConfigItem_deny_channel ;
typedef struct ConfigItem_deny_version ConfigItem_deny_version ;
typedef struct ConfigItem_alias ConfigItem_alias ;
typedef struct ConfigItem_alias_format ConfigItem_alias_format ;
2022-01-15 05:16:34 +00:00
typedef struct ConfigResource ConfigResource ;
2020-03-29 09:16:53 +00:00
typedef struct ConfigItem_blacklist_module ConfigItem_blacklist_module ;
typedef struct ConfigItem_help ConfigItem_help ;
typedef struct ConfigItem_offchans ConfigItem_offchans ;
2021-01-08 23:15:08 +00:00
typedef struct SecurityGroup SecurityGroup ;
2021-06-19 15:52:51 +00:00
typedef struct Secret Secret ;
2020-03-29 09:16:53 +00:00
typedef struct ListStruct ListStruct ;
typedef struct ListStructPrio ListStructPrio ;
# define CFG_TIME 0x0001
# define CFG_SIZE 0x0002
# define CFG_YESNO 0x0004
typedef struct Watch Watch ;
typedef struct Client Client ;
typedef struct LocalClient LocalClient ;
typedef struct Channel Channel ;
2021-06-19 15:52:51 +00:00
typedef struct User User ;
2020-03-29 09:16:53 +00:00
typedef struct Server Server ;
typedef struct Link Link ;
typedef struct Ban Ban ;
typedef struct Mode Mode ;
typedef struct MessageTag MessageTag ;
typedef struct MOTDFile MOTDFile ; /* represents a whole MOTD, including remote MOTD support info */
typedef struct MOTDLine MOTDLine ; /* one line of a MOTD stored as a linked list */
typedef struct RealCommand RealCommand ;
typedef struct CommandOverride CommandOverride ;
typedef struct Member Member ;
typedef struct Membership Membership ;
typedef enum OperClassEntryType { OPERCLASSENTRY_ALLOW = 1 , OPERCLASSENTRY_DENY = 2 } OperClassEntryType ;
typedef enum OperPermission { OPER_ALLOW = 1 , OPER_DENY = 0 } OperPermission ;
2020-05-29 02:06:50 +00:00
typedef enum SendType {
SEND_TYPE_PRIVMSG = 0 ,
SEND_TYPE_NOTICE = 1 ,
SEND_TYPE_TAGMSG = 2
} SendType ;
2020-03-29 09:16:53 +00:00
struct OperClassValidator ;
typedef struct OperClassValidator OperClassValidator ;
typedef struct OperClassACLPath OperClassACLPath ;
typedef struct OperClass OperClass ;
typedef struct OperClassACL OperClassACL ;
typedef struct OperClassACLEntry OperClassACLEntry ;
typedef struct OperClassACLEntryVar OperClassACLEntryVar ;
typedef struct OperClassCheckParams OperClassCheckParams ;
typedef OperPermission ( * OperClassEntryEvalCallback ) ( OperClassACLEntryVar * variables , OperClassCheckParams * params ) ;
# ifndef VMSP
# include "dbuf.h" /* THIS REALLY SHOULDN'T BE HERE!!! --msa */
# endif
2022-01-15 05:16:34 +00:00
# define HOSTLEN 63 /* Length of hostname */
2020-03-29 09:16:53 +00:00
# define NICKLEN 30
# define USERLEN 10
# define REALLEN 50
2022-01-15 05:16:34 +00:00
# define ACCOUNTLEN 30
2020-03-29 09:16:53 +00:00
# define MAXTOPICLEN 360 /* absolute maximum permitted topic length (above this = potential desync) */
# define MAXAWAYLEN 360 /* absolute maximum permitted away length (above this = potential desync) */
# define MAXKICKLEN 360 /* absolute maximum kick length (above this = only cutoff danger) */
# define MAXQUITLEN 395 /* absolute maximum quit length (above this = only cutoff danger) */
# define CHANNELLEN 32
# define PASSWDLEN 256 /* some insane large limit (previously: 20, 32, 48) */
# define KEYLEN 23
# define LINKLEN 32
# define BUFSIZE 512 /* WARNING: *DONT* CHANGE THIS!!!! */
# define READBUFSIZE 8192 /* for the read buffer */
# define MAXRECIPIENTS 20
# define MAXSILELENGTH NICKLEN+USERLEN+HOSTLEN+10
2022-01-15 05:16:34 +00:00
# define IDLEN 12
# define SIDLEN 3
2020-03-29 09:16:53 +00:00
# define SWHOISLEN 256
# define UMODETABLESZ (sizeof(long) * 8)
# define MAXCCUSERS 20 /* Maximum for set::anti-flood::max-concurrent-conversations */
# define BATCHLEN 22
/*
* Watch it - Don ' t change this unless you also change the ERR_TOOMANYWATCH
* and PROTOCOL_SUPPORTED settings .
*/
# define MAXWATCH 128
# define USERHOST_REPLYLEN (NICKLEN+HOSTLEN+USERLEN+5)
/* NOTE: this must be down here so the stuff from struct.h IT uses works */
# include "whowas.h"
/* Logging types */
# define LOG_ERROR 0x0001
# define LOG_KILL 0x0002
# define LOG_SACMDS 0x0080
# define LOG_CHGCMDS 0x0100
# define LOG_OVERRIDE 0x0200
2022-01-15 05:16:34 +00:00
typedef enum LogFieldType {
LOG_FIELD_INTEGER , // and unsigned?
LOG_FIELD_STRING ,
LOG_FIELD_CLIENT ,
LOG_FIELD_CHANNEL ,
LOG_FIELD_OBJECT
} LogFieldType ;
typedef struct LogData {
LogFieldType type ;
char * key ;
union {
int64_t integer ;
char * string ;
Client * client ;
Channel * channel ;
json_t * object ;
} value ;
} LogData ;
/** New log levels for unreal_log() */
/* Note: the reason for these high numbers is so we can easily catch
* if someone makes a mistake to use LOG_INFO ( from syslog . h ) instead
* of the ULOG_xxx levels .
*/
typedef enum LogLevel {
ULOG_INVALID = 0 ,
ULOG_DEBUG = 1000 ,
ULOG_INFO = 2000 ,
ULOG_WARNING = 3000 ,
ULOG_ERROR = 4000 ,
ULOG_FATAL = 5000
} LogLevel ;
/** Logging types (text, json, etc) */
typedef enum LogType {
LOG_TYPE_INVALID = 0 ,
LOG_TYPE_TEXT = 1 ,
LOG_TYPE_JSON = 2 ,
} LogType ;
# define LOG_CATEGORY_LEN 32
# define LOG_EVENT_ID_LEN 64
typedef struct LogSource LogSource ;
struct LogSource {
LogSource * prev , * next ;
LogLevel loglevel ;
char negative ; /**< 1 if negative match (eg !operoverride), 0 if normal */
char subsystem [ LOG_CATEGORY_LEN + 1 ] ;
char event_id [ LOG_EVENT_ID_LEN + 1 ] ;
} ;
typedef struct Log Log ;
struct Log {
Log * prev , * next ;
LogSource * sources ;
2022-04-03 15:09:29 +00:00
int type ;
2022-01-15 05:16:34 +00:00
char destination [ CHANNELLEN + 1 ] ;
2022-04-03 15:09:29 +00:00
int show_event ;
/* for destination::file */
2022-01-15 05:16:34 +00:00
char * file ;
char * filefmt ;
long maxsize ;
int logfd ;
2022-04-03 15:09:29 +00:00
/* for destination::channel */
int color ;
int json_message_tag ;
int oper_only ;
2022-01-15 05:16:34 +00:00
} ;
/** This is used for deciding the <index> in logs[<index>] and temp_logs[<index>] */
typedef enum LogDestination { LOG_DEST_SNOMASK = 0 , LOG_DEST_OPER = 1 , LOG_DEST_REMOTE = 2 , LOG_DEST_CHANNEL = 3 , LOG_DEST_DISK = 4 } LogDestination ;
# define NUM_LOG_DESTINATIONS 5
2020-03-29 09:16:53 +00:00
/*
* * ' offsetof ' is defined in ANSI - C . The following definition
* * is not absolutely portable ( I have been told ) , but so far
* * it has worked on all machines I have needed it . The type
* * should be size_t but . . . - - msa
*/
# ifndef offsetof
# define offsetof(t,m) (int)((&((t *)0L)->m))
# endif
# define elementsof(x) (sizeof(x) / sizeof(x[0]))
/* Calculate the size of an array */
# define ARRAY_SIZEOF(x) (sizeof((x)) / sizeof((x)[0]))
/*
* * flags for bootup options ( command line flags )
*/
# define BOOT_DEBUG 1
# define BOOT_TTY 2
# define BOOT_NOFORK 4
/* Length of the key that you feed into siphash_generate_key()
* DO NOT CHANGE THIS as the siphash code depends on it .
*/
# define SIPHASH_KEY_LENGTH 16
2021-06-19 15:52:51 +00:00
/** The length of a standard 'msgid' tag (note that special
* msgid tags will be longer ) .
* The 22 alphanumeric characters provide slightly more
* than 128 bits of randomness ( 62 ^ 22 > 2 ^ 128 ) .
* See mtag_add_or_inherit_msgid ( ) for more information .
*/
# define MSGIDLEN 22
2020-03-29 09:16:53 +00:00
/** This specifies the current client status or the client type - see @link ClientStatus @endlink in particular.
* You may think " server " or " client " are the only choices here , but there are many more
2022-01-15 05:16:34 +00:00
* such as states where the user is in the middle of an TLS handshake .
2020-03-29 09:16:53 +00:00
* @ defgroup ClientStatuses Client statuses / types
* @ {
*/
typedef enum ClientStatus {
2022-04-03 15:09:29 +00:00
CLIENT_STATUS_CONTROL = - 8 , /**< Client is on the control channel */
2020-03-29 09:16:53 +00:00
CLIENT_STATUS_LOG = - 7 , /**< Client is a log file */
CLIENT_STATUS_TLS_STARTTLS_HANDSHAKE = - 8 , /**< Client is doing a STARTTLS handshake */
CLIENT_STATUS_CONNECTING = - 6 , /**< Client is an outgoing connect */
2022-01-15 05:16:34 +00:00
CLIENT_STATUS_TLS_CONNECT_HANDSHAKE = - 5 , /**< Client is doing an TLS handshake - outgoing connection */
CLIENT_STATUS_TLS_ACCEPT_HANDSHAKE = - 4 , /**< Client is doing an TLS handshake - incoming connection */
2020-03-29 09:16:53 +00:00
CLIENT_STATUS_HANDSHAKE = - 3 , /**< Client is doing a server handshake - outgoing connection */
CLIENT_STATUS_ME = - 2 , /**< Client is &me (this server) */
CLIENT_STATUS_UNKNOWN = - 1 , /**< Client is doing a hanshake. May become a server or user later, we don't know yet */
CLIENT_STATUS_SERVER = 0 , /**< Client is a server (fully authenticated) */
CLIENT_STATUS_USER = 1 , /**< Client is a user (fully authenticated) */
} ClientStatus ;
# define MyConnect(x) ((x)->local) /**< Is a locally connected client (server or user) */
# define MyUser(x) (MyConnect(x) && IsUser(x)) /**< Is a locally connected user */
# define IsUser(x) ((x)->status == CLIENT_STATUS_USER) /**< Is a user that has completed the connection handshake */
# define IsRegistered(x) ((x)->status >= CLIENT_STATUS_SERVER) /**< Client has completed the connection handshake (user or server) */
# define IsConnecting(x) ((x)->status == CLIENT_STATUS_CONNECTING) /**< Is an outgoing connect to another server */
# define IsHandshake(x) ((x)->status == CLIENT_STATUS_HANDSHAKE) /**< Is doing a handshake (while connecting to another server) */
# define IsMe(x) ((x)->status == CLIENT_STATUS_ME) /**< This is true for &me */
/** Client is not fully registered yet. May become a user or a server, we don't know yet. */
# define IsUnknown(x) (((x)->status == CLIENT_STATUS_UNKNOWN) || ((x)->status == CLIENT_STATUS_TLS_STARTTLS_HANDSHAKE))
# define IsServer(x) ((x)->status == CLIENT_STATUS_SERVER) /**< Is a server that has completed the connection handshake */
2022-04-03 15:09:29 +00:00
# define IsControl(x) ((x)->status == CLIENT_STATUS_CONTROL) /**< Is on the control channel (not on IRC) */
2020-03-29 09:16:53 +00:00
# define IsLog(x) ((x)->status == CLIENT_STATUS_LOG) /**< Is a log file, not a user or server */
# define IsStartTLSHandshake(x) ((x)->status == CLIENT_STATUS_TLS_STARTTLS_HANDSHAKE) /**< Currently doing a STARTTLS handshake */
# define IsTLSAcceptHandshake(x) ((x)->status == CLIENT_STATUS_TLS_ACCEPT_HANDSHAKE) /**< Currently doing a TLS handshake - incoming */
# define IsTLSConnectHandshake(x) ((x)->status == CLIENT_STATUS_TLS_CONNECT_HANDSHAKE) /**< Currently doing a TLS handshake - outgoing */
# define IsTLSHandshake(x) (IsTLSAcceptHandshake(x) || IsTLSConnectHandshake(x) | IsStartTLSHandshake(x)) /**< Currently doing a TLS handshake (incoming/outgoing/STARTTLS) */
# define SetStartTLSHandshake(x) ((x)->status = CLIENT_STATUS_TLS_STARTTLS_HANDSHAKE)
# define SetTLSAcceptHandshake(x) ((x)->status = CLIENT_STATUS_TLS_ACCEPT_HANDSHAKE)
# define SetTLSConnectHandshake(x) ((x)->status = CLIENT_STATUS_TLS_CONNECT_HANDSHAKE)
# define SetConnecting(x) ((x)->status = CLIENT_STATUS_CONNECTING)
# define SetHandshake(x) ((x)->status = CLIENT_STATUS_HANDSHAKE)
# define SetMe(x) ((x)->status = CLIENT_STATUS_ME)
# define SetUnknown(x) ((x)->status = CLIENT_STATUS_UNKNOWN)
# define SetServer(x) ((x)->status = CLIENT_STATUS_SERVER)
# define SetUser(x) ((x)->status = CLIENT_STATUS_USER)
# define SetLog(x) ((x)->status = CLIENT_STATUS_LOG)
2022-04-03 15:09:29 +00:00
# define SetControl(x) ((x)->status = CLIENT_STATUS_CONTROL)
# define SetUser(x) ((x)->status = CLIENT_STATUS_USER)
2020-03-29 09:16:53 +00:00
2021-01-08 23:15:08 +00:00
/** @} */
2020-03-29 09:16:53 +00:00
/** Used for checking certain properties of clients, such as IsSecure() and IsULine().
* @ defgroup ClientFlags Client flags
* @ {
*/
# define CLIENT_FLAG_PINGSENT 0x00000001 /**< PING sent, no reply yet */
# define CLIENT_FLAG_DEAD 0x00000002 /**< Client is dead: already quit/exited and removed from all lists -- Remaining part will soon be freed in main loop */
# define CLIENT_FLAG_DEADSOCKET 0x00000004 /**< Local socket is dead but otherwise the client still exists fully -- Will soon exit in main loop */
# define CLIENT_FLAG_KILLED 0x00000008 /**< Prevents "QUIT" from being sent for this */
2022-04-03 15:09:29 +00:00
# define CLIENT_FLAG_MONITOR_REHASH 0x00000010 /**< Client is monitoring rehash output */
2020-03-29 09:16:53 +00:00
# define CLIENT_FLAG_OUTGOING 0x00000020 /**< Outgoing connection (do not touch cptr->listener->clients) */
# define CLIENT_FLAG_CLOSING 0x00000040 /**< Set when closing to suppress errors */
# define CLIENT_FLAG_LISTEN 0x00000080 /**< Used to mark clients which we listen() on */
# define CLIENT_FLAG_DNSLOOKUP 0x00000100 /**< Client is doing a DNS lookup */
# define CLIENT_FLAG_IDENTLOOKUP 0x00000200 /**< Client is doing an Ident lookup (RFC931) */
# define CLIENT_FLAG_IDENTLOOKUPSENT 0x00000400 /**< Set if we havent writen to ident server */
# define CLIENT_FLAG_LOCALHOST 0x00000800 /**< Set for localhost clients */
# define CLIENT_FLAG_IDENTSUCCESS 0x00001000 /**< Successful ident lookup achieved */
# define CLIENT_FLAG_USEIDENT 0x00002000 /**< The allow { } block says we should use the ident (if available) */
# define CLIENT_FLAG_NEXTCALL 0x00004000 /**< Next call (don't ask...) */
# define CLIENT_FLAG_ULINE 0x00008000 /**< User/server is considered U-lined (eg: services) */
# define CLIENT_FLAG_SQUIT 0x00010000 /**< Server has been /SQUIT by an oper */
# define CLIENT_FLAG_PROTOCTL 0x00020000 /**< Received at least 1 PROTOCTL message */
# define CLIENT_FLAG_EAUTH 0x00040000 /**< Server authenticated via PROTOCTL EAUTH */
# define CLIENT_FLAG_NETINFO 0x00080000 /**< Received a NETINFO message */
# define CLIENT_FLAG_QUARANTINE 0x00100000 /**< Quarantined server (don't allow ircops on this server) */
# define CLIENT_FLAG_DCCNOTICE 0x00200000 /**< Has the user seen a notice on how to use DCCALLOW already? */
# define CLIENT_FLAG_SHUNNED 0x00400000 /**< Connection is shunned (user cannot execute any commands) */
# define CLIENT_FLAG_VIRUS 0x00800000 /**< Tagged by spamfilter as a virus */
2022-01-15 05:16:34 +00:00
# define CLIENT_FLAG_TLS 0x01000000 /**< Connection is using TLS */
2020-03-29 09:16:53 +00:00
# define CLIENT_FLAG_NOFAKELAG 0x02000000 /**< Exemption from fake lag */
# define CLIENT_FLAG_DCCBLOCK 0x04000000 /**< Block all DCC send requests */
# define CLIENT_FLAG_MAP 0x08000000 /**< Show this entry in /MAP (only used in map module) */
# define CLIENT_FLAG_PINGWARN 0x10000000 /**< Server ping warning (remote server slow with responding to PINGs) */
2021-03-21 17:05:35 +00:00
# define CLIENT_FLAG_NOHANDSHAKEDELAY 0x20000000 /**< No handshake delay */
2022-01-15 05:16:34 +00:00
# define CLIENT_FLAG_SERVER_DISCONNECT_LOGGED 0x40000000 /**< Server disconnect message is (already) logged */
2020-03-29 09:16:53 +00:00
/** @} */
2022-01-15 05:16:34 +00:00
# define OPER_SNOMASKS "+bBcdfkqsSoO"
2020-03-29 09:16:53 +00:00
# define SEND_UMODES (SendUmodes)
# define ALL_UMODES (AllUmodes)
/* SEND_UMODES and ALL_UMODES are now handled by umode_get/umode_lget/umode_gget -- Syzop. */
# define CLIENT_FLAG_ID (CLIENT_FLAG_USEIDENT|CLIENT_FLAG_IDENTSUCCESS)
/* PROTO_*: Server protocol extensions (acptr->local->proto).
* Note that client protocol extensions have been moved
* to the ClientCapability API which uses acptr - > local - > caps .
*/
2022-01-15 05:16:34 +00:00
# define PROTO_VL 0x000001 /* Negotiated VL protocol */
# define PROTO_VHP 0x000002 /* Send hostnames in NICKv2 even if not sethosted */
# define PROTO_CLK 0x000004 /* Send cloaked host in the NICK command (regardless of +x/-x) */
# define PROTO_MLOCK 0x000008 /* server supports MLOCK */
# define PROTO_EXTSWHOIS 0x000010 /* extended SWHOIS support */
# define PROTO_SJSBY 0x000020 /* SJOIN setby information (TS and nick) */
# define PROTO_MTAGS 0x000040 /* Support message tags and big buffers */
# define PROTO_NEXTBANS 0x000080 /* Server supports named extended bans */
2020-03-29 09:16:53 +00:00
/* For client capabilities: */
2020-05-29 02:06:50 +00:00
# define CAP_INVERT 1L
2020-03-29 09:16:53 +00:00
/** HasCapabilityFast() checks for a token if you know exactly which bit to check */
# define HasCapabilityFast(cptr, val) ((cptr)->local->caps & (val))
/** HasCapability() checks for a token by name and is slightly slower */
# define HasCapability(cptr, token) ((cptr)->local->caps & ClientCapabilityBit(token))
# define SetCapabilityFast(cptr, val) do { (cptr)->local->caps |= (val); } while(0)
# define ClearCapabilityFast(cptr, val) do { (cptr)->local->caps &= ~(val); } while(0)
/* Usermode and snomask macros: */
# define IsDeaf(x) ((x)->umodes & UMODE_DEAF)
# define IsOper(x) ((x)->umodes & UMODE_OPER)
# define IsInvisible(x) ((x)->umodes & UMODE_INVISIBLE)
# define IsRegNick(x) ((x)->umodes & UMODE_REGNICK)
# define IsHidden(x) ((x)->umodes & UMODE_HIDE)
# define IsSetHost(x) ((x)->umodes & UMODE_SETHOST)
# define IsHideOper(x) ((x)->umodes & UMODE_HIDEOPER)
# define SetOper(x) ((x)->umodes |= UMODE_OPER)
# define SetInvisible(x) ((x)->umodes |= UMODE_INVISIBLE)
# define SetRegNick(x) ((x)->umodes & UMODE_REGNICK)
# define SetHidden(x) ((x)->umodes |= UMODE_HIDE)
# define SetHideOper(x) ((x)->umodes |= UMODE_HIDEOPER)
# define IsSecureConnect(x) ((x)->umodes & UMODE_SECURE)
# define ClearOper(x) ((x)->umodes &= ~UMODE_OPER)
# define ClearInvisible(x) ((x)->umodes &= ~UMODE_INVISIBLE)
# define ClearHidden(x) ((x)->umodes &= ~UMODE_HIDE)
# define ClearHideOper(x) ((x)->umodes &= ~UMODE_HIDEOPER)
/* Client flags macros: to check for via IsXX(),
* to set via SetXX ( ) and to clear the flag via ClearXX ( )
*/
/**
* @ addtogroup ClientFlags
* @ {
*/
# define IsIdentLookup(x) ((x)->flags & CLIENT_FLAG_IDENTLOOKUP) /**< Is doing Ident lookups */
# define IsClosing(x) ((x)->flags & CLIENT_FLAG_CLOSING) /**< Is closing the connection */
# define IsDCCBlock(x) ((x)->flags & CLIENT_FLAG_DCCBLOCK)
# define IsDCCNotice(x) ((x)->flags & CLIENT_FLAG_DCCNOTICE)
# define IsDead(x) ((x)->flags & CLIENT_FLAG_DEAD)
# define IsDeadSocket(x) ((x)->flags & CLIENT_FLAG_DEADSOCKET)
2022-01-15 05:16:34 +00:00
# define IsServerDisconnectLogged(x) ((x)->flags & CLIENT_FLAG_SERVER_DISCONNECT_LOGGED)
2020-03-29 09:16:53 +00:00
# define IsUseIdent(x) ((x)->flags & CLIENT_FLAG_USEIDENT)
# define IsDNSLookup(x) ((x)->flags & CLIENT_FLAG_DNSLOOKUP)
# define IsEAuth(x) ((x)->flags & CLIENT_FLAG_EAUTH)
# define IsIdentSuccess(x) ((x)->flags & CLIENT_FLAG_IDENTSUCCESS)
# define IsKilled(x) ((x)->flags & CLIENT_FLAG_KILLED)
2022-04-03 15:09:29 +00:00
# define IsMonitorRehash(x) ((x)->flags & CLIENT_FLAG_MONITOR_REHASH)
2020-03-29 09:16:53 +00:00
# define IsListening(x) ((x)->flags & CLIENT_FLAG_LISTEN)
# define IsLocalhost(x) ((x)->flags & CLIENT_FLAG_LOCALHOST)
# define IsMap(x) ((x)->flags & CLIENT_FLAG_MAP)
# define IsNextCall(x) ((x)->flags & CLIENT_FLAG_NEXTCALL)
# define IsNetInfo(x) ((x)->flags & CLIENT_FLAG_NETINFO)
# define IsNoFakeLag(x) ((x)->flags & CLIENT_FLAG_NOFAKELAG)
# define IsOutgoing(x) ((x)->flags & CLIENT_FLAG_OUTGOING)
# define IsPingSent(x) ((x)->flags & CLIENT_FLAG_PINGSENT)
# define IsPingWarning(x) ((x)->flags & CLIENT_FLAG_PINGWARN)
2021-03-21 17:05:35 +00:00
# define IsNoHandshakeDelay(x) ((x)->flags & CLIENT_FLAG_NOHANDSHAKEDELAY)
2020-03-29 09:16:53 +00:00
# define IsProtoctlReceived(x) ((x)->flags & CLIENT_FLAG_PROTOCTL)
# define IsQuarantined(x) ((x)->flags & CLIENT_FLAG_QUARANTINE)
# define IsShunned(x) ((x)->flags & CLIENT_FLAG_SHUNNED)
# define IsSQuit(x) ((x)->flags & CLIENT_FLAG_SQUIT)
# define IsTLS(x) ((x)->flags & CLIENT_FLAG_TLS)
# define IsSecure(x) ((x)->flags & CLIENT_FLAG_TLS)
# define IsULine(x) ((x)->flags & CLIENT_FLAG_ULINE)
# define IsVirus(x) ((x)->flags & CLIENT_FLAG_VIRUS)
# define IsIdentLookupSent(x) ((x)->flags & CLIENT_FLAG_IDENTLOOKUPSENT)
# define SetIdentLookup(x) do { (x)->flags |= CLIENT_FLAG_IDENTLOOKUP; } while(0)
# define SetClosing(x) do { (x)->flags |= CLIENT_FLAG_CLOSING; } while(0)
# define SetDCCBlock(x) do { (x)->flags |= CLIENT_FLAG_DCCBLOCK; } while(0)
# define SetDCCNotice(x) do { (x)->flags |= CLIENT_FLAG_DCCNOTICE; } while(0)
# define SetDead(x) do { (x)->flags |= CLIENT_FLAG_DEAD; } while(0)
# define SetDeadSocket(x) do { (x)->flags |= CLIENT_FLAG_DEADSOCKET; } while(0)
2022-01-15 05:16:34 +00:00
# define SetServerDisconnectLogged(x) do { (x)->flags |= CLIENT_FLAG_SERVER_DISCONNECT_LOGGED; } while(0)
2020-03-29 09:16:53 +00:00
# define SetUseIdent(x) do { (x)->flags |= CLIENT_FLAG_USEIDENT; } while(0)
# define SetDNSLookup(x) do { (x)->flags |= CLIENT_FLAG_DNSLOOKUP; } while(0)
# define SetEAuth(x) do { (x)->flags |= CLIENT_FLAG_EAUTH; } while(0)
# define SetIdentSuccess(x) do { (x)->flags |= CLIENT_FLAG_IDENTSUCCESS; } while(0)
# define SetKilled(x) do { (x)->flags |= CLIENT_FLAG_KILLED; } while(0)
2022-04-03 15:09:29 +00:00
# define SetMonitorRehash(x) do { (x)->flags |= CLIENT_FLAG_MONITOR_REHASH; } while(0)
2020-03-29 09:16:53 +00:00
# define SetListening(x) do { (x)->flags |= CLIENT_FLAG_LISTEN; } while(0)
# define SetLocalhost(x) do { (x)->flags |= CLIENT_FLAG_LOCALHOST; } while(0)
# define SetMap(x) do { (x)->flags |= CLIENT_FLAG_MAP; } while(0)
# define SetNextCall(x) do { (x)->flags |= CLIENT_FLAG_NEXTCALL; } while(0)
# define SetNetInfo(x) do { (x)->flags |= CLIENT_FLAG_NETINFO; } while(0)
# define SetNoFakeLag(x) do { (x)->flags |= CLIENT_FLAG_NOFAKELAG; } while(0)
# define SetOutgoing(x) do { (x)->flags |= CLIENT_FLAG_OUTGOING; } while(0)
# define SetPingSent(x) do { (x)->flags |= CLIENT_FLAG_PINGSENT; } while(0)
# define SetPingWarning(x) do { (x)->flags |= CLIENT_FLAG_PINGWARN; } while(0)
2021-03-21 17:05:35 +00:00
# define SetNoHandshakeDelay(x) do { (x)->flags |= CLIENT_FLAG_NOHANDSHAKEDELAY; } while(0)
2020-03-29 09:16:53 +00:00
# define SetProtoctlReceived(x) do { (x)->flags |= CLIENT_FLAG_PROTOCTL; } while(0)
# define SetQuarantined(x) do { (x)->flags |= CLIENT_FLAG_QUARANTINE; } while(0)
# define SetShunned(x) do { (x)->flags |= CLIENT_FLAG_SHUNNED; } while(0)
# define SetSQuit(x) do { (x)->flags |= CLIENT_FLAG_SQUIT; } while(0)
# define SetTLS(x) do { (x)->flags |= CLIENT_FLAG_TLS; } while(0)
# define SetULine(x) do { (x)->flags |= CLIENT_FLAG_ULINE; } while(0)
# define SetVirus(x) do { (x)->flags |= CLIENT_FLAG_VIRUS; } while(0)
# define SetIdentLookupSent(x) do { (x)->flags |= CLIENT_FLAG_IDENTLOOKUPSENT; } while(0)
# define ClearIdentLookup(x) do { (x)->flags &= ~CLIENT_FLAG_IDENTLOOKUP; } while(0)
# define ClearClosing(x) do { (x)->flags &= ~CLIENT_FLAG_CLOSING; } while(0)
# define ClearDCCBlock(x) do { (x)->flags &= ~CLIENT_FLAG_DCCBLOCK; } while(0)
# define ClearDCCNotice(x) do { (x)->flags &= ~CLIENT_FLAG_DCCNOTICE; } while(0)
# define ClearDead(x) do { (x)->flags &= ~CLIENT_FLAG_DEAD; } while(0)
# define ClearDeadSocket(x) do { (x)->flags &= ~CLIENT_FLAG_DEADSOCKET; } while(0)
# define ClearUseIdent(x) do { (x)->flags &= ~CLIENT_FLAG_USEIDENT; } while(0)
# define ClearDNSLookup(x) do { (x)->flags &= ~CLIENT_FLAG_DNSLOOKUP; } while(0)
# define ClearEAuth(x) do { (x)->flags &= ~CLIENT_FLAG_EAUTH; } while(0)
# define ClearIdentSuccess(x) do { (x)->flags &= ~CLIENT_FLAG_IDENTSUCCESS; } while(0)
# define ClearKilled(x) do { (x)->flags &= ~CLIENT_FLAG_KILLED; } while(0)
2022-04-03 15:09:29 +00:00
# define ClearMonitorRehash(x) do { (x)->flags &= ~CLIENT_FLAG_MONITOR_REHASH; } while(0)
2020-03-29 09:16:53 +00:00
# define ClearListening(x) do { (x)->flags &= ~CLIENT_FLAG_LISTEN; } while(0)
# define ClearLocalhost(x) do { (x)->flags &= ~CLIENT_FLAG_LOCALHOST; } while(0)
# define ClearMap(x) do { (x)->flags &= ~CLIENT_FLAG_MAP; } while(0)
# define ClearNextCall(x) do { (x)->flags &= ~CLIENT_FLAG_NEXTCALL; } while(0)
# define ClearNetInfo(x) do { (x)->flags &= ~CLIENT_FLAG_NETINFO; } while(0)
# define ClearNoFakeLag(x) do { (x)->flags &= ~CLIENT_FLAG_NOFAKELAG; } while(0)
# define ClearOutgoing(x) do { (x)->flags &= ~CLIENT_FLAG_OUTGOING; } while(0)
# define ClearPingSent(x) do { (x)->flags &= ~CLIENT_FLAG_PINGSENT; } while(0)
# define ClearPingWarning(x) do { (x)->flags &= ~CLIENT_FLAG_PINGWARN; } while(0)
2021-03-21 17:05:35 +00:00
# define ClearNoHandshakeDelay(x) do { (x)->flags &= ~CLIENT_FLAG_NOHANDSHAKEDELAY; } while(0)
2020-03-29 09:16:53 +00:00
# define ClearProtoctlReceived(x) do { (x)->flags &= ~CLIENT_FLAG_PROTOCTL; } while(0)
# define ClearQuarantined(x) do { (x)->flags &= ~CLIENT_FLAG_QUARANTINE; } while(0)
# define ClearShunned(x) do { (x)->flags &= ~CLIENT_FLAG_SHUNNED; } while(0)
# define ClearSQuit(x) do { (x)->flags &= ~CLIENT_FLAG_SQUIT; } while(0)
# define ClearTLS(x) do { (x)->flags &= ~CLIENT_FLAG_TLS; } while(0)
# define ClearULine(x) do { (x)->flags &= ~CLIENT_FLAG_ULINE; } while(0)
# define ClearVirus(x) do { (x)->flags &= ~CLIENT_FLAG_VIRUS; } while(0)
# define ClearIdentLookupSent(x) do { (x)->flags &= ~CLIENT_FLAG_IDENTLOOKUPSENT; } while(0)
2022-04-03 15:09:29 +00:00
# define IsIPV6(x) ((x)->local->socket_type == SOCKET_TYPE_IPV6)
# define IsUnixSocket(x) ((x)->local->socket_type == SOCKET_TYPE_UNIX)
# define SetIPV6(x) do { (x)->local->socket_type = SOCKET_TYPE_IPV6; } while(0)
2022-11-20 04:12:40 +00:00
# define SetUnixSocket(x) do { (x)->local->socket_type = SOCKET_TYPE_UNIX; } while(0)
2021-01-08 23:15:08 +00:00
/** @} */
2020-03-29 09:16:53 +00:00
/* Others that access client structs: */
# define IsNotSpoof(x) ((x)->local->nospoof == 0)
# define GetHost(x) (IsHidden(x) ? (x)->user->virthost : (x)->user->realhost)
# define GetIP(x) (x->ip ? x->ip : "255.255.255.255")
2022-01-15 05:16:34 +00:00
# define IsLoggedIn(x) (x->user && (*x->user->account != '*') && !isdigit(*x->user->account)) /**< Logged into services */
# define IsSynched(x) (x->server->flags.synced)
# define IsServerSent(x) (x->server && x->server->flags.server_sent)
2020-03-29 09:16:53 +00:00
2021-01-08 23:15:08 +00:00
/* And more that access client stuff - but actually modularized */
# define GetReputation(client) (moddata_client_get(client, "reputation") ? atoi(moddata_client_get(client, "reputation")) : 0) /**< Get reputation value for a client */
2020-03-29 09:16:53 +00:00
/* PROTOCTL (Server protocol) stuff */
# ifndef DEBUGMODE
# define CHECKSERVERPROTO(x,y) (((x)->local->proto & y) == y)
# else
# define CHECKSERVERPROTO(x,y) (checkprotoflags(x, y, __FILE__, __LINE__))
# endif
# define SupportVL(x) (CHECKSERVERPROTO(x, PROTO_VL))
# define SupportSJSBY(x) (CHECKSERVERPROTO(x, PROTO_SJSBY))
# define SupportVHP(x) (CHECKSERVERPROTO(x, PROTO_VHP))
# define SupportCLK(x) (CHECKSERVERPROTO(x, PROTO_CLK))
# define SupportMTAGS(x) (CHECKSERVERPROTO(x, PROTO_MTAGS))
2022-01-15 05:16:34 +00:00
# define SupportNEXTBANS(x) (CHECKSERVERPROTO(x, PROTO_NEXTBANS))
2020-03-29 09:16:53 +00:00
# define SetVL(x) ((x)->local->proto |= PROTO_VL)
# define SetSJSBY(x) ((x)->local->proto |= PROTO_SJSBY)
# define SetVHP(x) ((x)->local->proto |= PROTO_VHP)
# define SetCLK(x) ((x)->local->proto |= PROTO_CLK)
# define SetMTAGS(x) ((x)->local->proto |= PROTO_MTAGS)
2022-01-15 05:16:34 +00:00
# define SetNEXTBANS(x) ((x)->local->proto |= PROTO_NEXTBANS)
2020-03-29 09:16:53 +00:00
/* Dcc deny types (see src/s_extra.c) */
# define DCCDENY_HARD 0
# define DCCDENY_SOFT 1
/* Linked list dcc flags */
# define DCC_LINK_ME 1 /* My dcc allow */
# define DCC_LINK_REMOTE 2 /* I need to remove dccallows from these clients when I die */
/** Union for moddata objects */
typedef union ModData ModData ;
union ModData
{
int i ;
long l ;
2022-11-20 04:12:40 +00:00
long long ll ;
2020-03-29 09:16:53 +00:00
char * str ;
void * ptr ;
} ;
# ifndef _WIN32
# define CHECK_LIST_ENTRY(list) if (offsetof(typeof(*list),prev) != offsetof(ListStruct,prev)) \
{ \
2022-01-15 05:16:34 +00:00
unreal_log ( ULOG_FATAL , " main " , " BUG_LIST_OPERATION " , NULL , \
" [BUG] $file:$line: List operation on struct with incorrect order ($error_details) " , \
log_data_string ( " error_details " , " ->prev must be 1st struct member " ) , \
log_data_string ( " file " , __FILE__ ) , \
log_data_integer ( " line " , __LINE__ ) ) ; \
2020-03-29 09:16:53 +00:00
abort ( ) ; \
} \
if ( offsetof ( typeof ( * list ) , next ) ! = offsetof ( ListStruct , next ) ) \
{ \
2022-01-15 05:16:34 +00:00
unreal_log ( ULOG_FATAL , " main " , " BUG_LIST_OPERATION " , NULL , \
" [BUG] $file:$line: List operation on struct with incorrect order ($error_details) " , \
log_data_string ( " error_details " , " ->next must be 2nd struct member " ) , \
log_data_string ( " file " , __FILE__ ) , \
log_data_integer ( " line " , __LINE__ ) ) ; \
2020-03-29 09:16:53 +00:00
abort ( ) ; \
}
# else
# define CHECK_LIST_ENTRY(list) /* not available on Windows, typeof() not reliable */
# endif
# ifndef _WIN32
# define CHECK_PRIO_LIST_ENTRY(list) if (offsetof(typeof(*list),prev) != offsetof(ListStructPrio,prev)) \
{ \
2022-01-15 05:16:34 +00:00
unreal_log ( ULOG_FATAL , " main " , " BUG_LIST_OPERATION " , NULL , \
" [BUG] $file:$line: List operation on struct with incorrect order ($error_details) " , \
log_data_string ( " error_details " , " ->prev must be 1st struct member " ) , \
log_data_string ( " file " , __FILE__ ) , \
log_data_integer ( " line " , __LINE__ ) ) ; \
2020-03-29 09:16:53 +00:00
abort ( ) ; \
} \
if ( offsetof ( typeof ( * list ) , next ) ! = offsetof ( ListStructPrio , next ) ) \
{ \
2022-01-15 05:16:34 +00:00
unreal_log ( ULOG_FATAL , " main " , " BUG_LIST_OPERATION " , NULL , \
" [BUG] $file:$line: List operation on struct with incorrect order ($error_details) " , \
log_data_string ( " error_details " , " ->next must be 2nd struct member " ) , \
log_data_string ( " file " , __FILE__ ) , \
log_data_integer ( " line " , __LINE__ ) ) ; \
2020-03-29 09:16:53 +00:00
abort ( ) ; \
} \
if ( offsetof ( typeof ( * list ) , priority ) ! = offsetof ( ListStructPrio , priority ) ) \
{ \
2022-01-15 05:16:34 +00:00
unreal_log ( ULOG_FATAL , " main " , " BUG_LIST_OPERATION " , NULL , \
" [BUG] $file:$line: List operation on struct with incorrect order ($error_details) " , \
log_data_string ( " error_details " , " ->priority must be 3rd struct member " ) , \
log_data_string ( " file " , __FILE__ ) , \
log_data_integer ( " line " , __LINE__ ) ) ; \
2020-03-29 09:16:53 +00:00
abort ( ) ; \
}
# else
# define CHECK_PRIO_LIST_ENTRY(list) /* not available on Windows, typeof() not reliable */
# endif
# define CHECK_NULL_LIST_ITEM(item) if ((item)->prev || (item)->next) \
{ \
2022-01-15 05:16:34 +00:00
unreal_log ( ULOG_FATAL , " main " , " BUG_LIST_OPERATION_DOUBLE_ADD " , NULL , \
" [BUG] $file:$line: List operation on item with non-NULL 'prev' or 'next' -- are you adding to a list twice? " , \
log_data_string ( " file " , __FILE__ ) , \
log_data_integer ( " line " , __LINE__ ) ) ; \
2020-03-29 09:16:53 +00:00
abort ( ) ; \
}
/** These are the generic list functions that are used all around in UnrealIRCd.
* @ defgroup ListFunctions List functions
* @ {
*/
/** Generic linked list HEAD */
struct ListStruct {
ListStruct * prev , * next ;
} ;
/** Generic linked list HEAD with priority */
struct ListStructPrio {
ListStructPrio * prev , * next ;
int priority ;
} ;
/** Add an item to a standard linked list (in the front)
*/
# define AddListItem(item,list) do { \
CHECK_LIST_ENTRY ( list ) \
CHECK_LIST_ENTRY ( item ) \
CHECK_NULL_LIST_ITEM ( item ) \
add_ListItem ( ( ListStruct * ) item , ( ListStruct * * ) & list ) ; \
} while ( 0 )
/** Append an item to a standard linked list (at the back)
*/
# define AppendListItem(item,list) do { \
CHECK_LIST_ENTRY ( list ) \
CHECK_LIST_ENTRY ( item ) \
CHECK_NULL_LIST_ITEM ( item ) \
append_ListItem ( ( ListStruct * ) item , ( ListStruct * * ) & list ) ; \
} while ( 0 )
/** Delete an item from a standard linked list
*/
# define DelListItem(item,list) do { \
CHECK_LIST_ENTRY ( list ) \
CHECK_LIST_ENTRY ( item ) \
del_ListItem ( ( ListStruct * ) item , ( ListStruct * * ) & list ) ; \
} while ( 0 )
/** Add an item to a standard linked list - UNCHECKED function, only use if absolutely necessary!
*/
# define AddListItemUnchecked(item,list) add_ListItem((ListStruct *)item, (ListStruct **)&list)
/** Append an item to a standard linked list - UNCHECKED function, only use if absolutely necessary!
*/
# define AppendListItemUnchecked(item,list) append_ListItem((ListStruct *)item, (ListStruct **)&list)
/** Delete an item from a standard linked list - UNCHECKED function, only use if absolutely necessary!
*/
# define DelListItemUnchecked(item,list) del_ListItem((ListStruct *)item, (ListStruct **)&list)
# define AddListItemPrio(item,list,prio) do { \
CHECK_PRIO_LIST_ENTRY ( list ) \
CHECK_PRIO_LIST_ENTRY ( item ) \
CHECK_NULL_LIST_ITEM ( item ) \
2021-06-19 15:52:51 +00:00
item - > priority = prio ; \
2020-03-29 09:16:53 +00:00
add_ListItemPrio ( ( ListStructPrio * ) item , ( ListStructPrio * * ) & list , prio ) ; \
} while ( 0 )
# define DelListItemPrio(item,list,prio) do { \
CHECK_PRIO_LIST_ENTRY ( list ) \
CHECK_PRIO_LIST_ENTRY ( item ) \
del_ListItem ( ( ListStruct * ) item , ( ListStruct * * ) & list ) ; \
} while ( 0 )
typedef struct NameList NameList ;
/** Generic linked list where each entry has a name which you can use.
* Use this if you simply want to have a list of entries
* that only have a name and no other properties .
*
* Use the following functions to add , find and delete entries :
* add_name_list ( ) , find_name_list ( ) , del_name_list ( ) , free_entire_name_list ( )
*/
struct NameList {
NameList * prev , * next ;
char name [ 1 ] ;
} ;
/** Free an entire NameList */
# define free_entire_name_list(list) do { _free_entire_name_list(list); list = NULL; } while(0)
/** Add an entry to a NameList */
# define add_name_list(list, str) _add_name_list(&list, str)
/** Delete an entry from a NameList - AND free it */
# define del_name_list(list, str) _del_name_list(&list, str)
2022-11-20 04:12:40 +00:00
extern void unreal_add_names ( NameList * * n , ConfigEntry * ce ) ;
2020-03-29 09:16:53 +00:00
/** @} */
typedef struct MultiLine MultiLine ;
/** Multi-line list.
* @ see addmultiline ( ) , freemultiline ( ) , sendnotice_multiline ( )
*/
struct MultiLine {
MultiLine * prev , * next ;
char * line ;
} ;
struct MOTDFile
{
struct MOTDLine * lines ;
struct tm last_modified ; /* store the last modification time */
} ;
struct MOTDLine {
char * line ;
struct MOTDLine * next ;
} ;
struct LoopStruct {
unsigned do_garbage_collect : 1 ;
unsigned config_test : 1 ;
2022-01-15 05:16:34 +00:00
unsigned booted : 1 ;
unsigned forked : 1 ;
2020-03-29 09:16:53 +00:00
unsigned do_bancheck : 1 ; /* perform *line bancheck? */
unsigned do_bancheck_spamf_user : 1 ; /* perform 'user' spamfilter bancheck */
unsigned do_bancheck_spamf_away : 1 ; /* perform 'away' spamfilter bancheck */
2022-01-15 05:16:34 +00:00
unsigned terminating : 1 ;
unsigned config_load_failed : 1 ;
unsigned rehash_download_busy : 1 ; /* don't return "all downloads complete", needed for race condition */
2020-03-29 09:16:53 +00:00
unsigned tainted : 1 ;
2022-04-03 15:09:29 +00:00
int rehashing ;
2022-01-15 05:16:34 +00:00
Client * rehash_save_client ;
2020-03-29 09:16:53 +00:00
void ( * boot_function ) ( ) ;
} ;
/** Matching types for Match.type */
typedef enum {
MATCH_SIMPLE = 1 , /**< Simple pattern with * and ? */
MATCH_PCRE_REGEX = 2 , /**< PCRE2 Perl-like regex (new) */
} MatchType ;
/** Match struct, which allows various matching styles, see MATCH_* */
typedef struct Match {
char * str ; /**< Text of the glob/regex/whatever. Always set. */
MatchType type ;
union {
pcre2_code * pcre2_expr ; /**< PCRE2 Perl-like Regex */
} ext ;
} Match ;
typedef struct Whowas {
int hashv ;
char * name ;
char * username ;
char * hostname ;
char * virthost ;
char * servername ;
char * realname ;
long umodes ;
time_t logoff ;
struct Client * online ; /* Pointer to new nickname for chasing or NULL */
struct Whowas * next ; /* for hash table... */
struct Whowas * prev ; /* for hash table... */
struct Whowas * cnext ; /* for client struct linked list */
struct Whowas * cprev ; /* for client struct linked list */
2022-01-15 05:16:34 +00:00
} WhoWas ;
2020-03-29 09:16:53 +00:00
typedef struct SWhois SWhois ;
struct SWhois {
SWhois * prev , * next ;
int priority ;
char * line ;
char * setby ;
} ;
2021-01-08 23:15:08 +00:00
/** The command API - used by modules and the core to add commands, overrides, etc.
* See also https : //www.unrealircd.org/docs/Dev:Command_API for a higher level overview and example.
2020-03-29 09:16:53 +00:00
* @ defgroup CommandAPI Command API
* @ {
*/
/** Command can be called by unregistered users (still in handshake) */
# define CMD_UNREGISTERED 0x0001
/** Command can be called by users (either directly connected, or remote) */
# define CMD_USER 0x0002
/** Command can be called by servers */
# define CMD_SERVER 0x0004
/** Command can be used by shunned users (only very few commands need this) */
# define CMD_SHUN 0x0008
/** Command will NOT add fake lag (extremely rare, use with care) */
# define CMD_NOLAG 0x0010
/** Command is actually an alias */
# define CMD_ALIAS 0x0020
/** Command will reset the idle time (only for PRIVMSG) */
# define CMD_RESETIDLE 0x0040
/** Command can be used by virus tagged users (only very few commands) */
# define CMD_VIRUS 0x0080
/** Command requires IRCOp privileges */
# define CMD_OPER 0x0200
2022-04-03 15:09:29 +00:00
/** Command is for control channel only (unrealircd.ctl socket) */
# define CMD_CONTROL 0x0400
2020-03-29 09:16:53 +00:00
/** Command function - used by all command handlers.
* This is used in the code like < pre > CMD_FUNC ( cmd_yourcmd ) < / pre > as a function definition .
* @ param cptr The client direction pointer .
* @ param client The source client pointer ( you usually need this one ) .
* @ param recv_mtags Received message tags for this command .
* @ param parc Parameter count * plus * 1.
* @ param parv Parameter values .
* @ note Slightly confusing , but parc will be 2 if 1 parameter was provided .
* It is two because parv will still have 2 elements , parv [ 1 ] will be your first parameter ,
* and parv [ 2 ] will be NULL .
* Note that reading parv [ parc ] and beyond is OUT OF BOUNDS and will cause a crash .
* E . g . parv [ 3 ] in the above example is out of bounds .
*/
2022-01-15 05:16:34 +00:00
# define CMD_FUNC(x) void (x) (Client *client, MessageTag *recv_mtags, int parc, const char *parv[])
2021-01-08 23:15:08 +00:00
/** @} */
2020-03-29 09:16:53 +00:00
/** Command override function - used by all command override handlers.
* This is used in the code like < pre > CMD_OVERRIDE_FUNC ( ovr_somecmd ) < / pre > as a function definition .
* @ param ovr The command override structure .
* @ param cptr The client direction pointer .
* @ param client The source client pointer ( you usually need this one ) .
* @ param recv_mtags Received message tags for this command .
* @ param parc Parameter count * plus * 1.
* @ param parv Parameter values .
* @ note Slightly confusing , but parc will be 2 if 1 parameter was provided .
* It is two because parv will still have 2 elements , parv [ 1 ] will be your first parameter ,
* and parv [ 2 ] will be NULL .
* Note that reading parv [ parc ] and beyond is OUT OF BOUNDS and will cause a crash .
* E . g . parv [ 3 ] in the above example .
*/
2022-01-15 05:16:34 +00:00
# define CMD_OVERRIDE_FUNC(x) void (x)(CommandOverride *ovr, Client *client, MessageTag *recv_mtags, int parc, const char *parv[])
2020-03-29 09:16:53 +00:00
2022-01-15 05:16:34 +00:00
typedef void ( * CmdFunc ) ( Client * client , MessageTag * mtags , int parc , const char * parv [ ] ) ;
typedef void ( * AliasCmdFunc ) ( Client * client , MessageTag * mtags , int parc , const char * parv [ ] , const char * cmd ) ;
typedef void ( * OverrideCmdFunc ) ( CommandOverride * ovr , Client * client , MessageTag * mtags , int parc , const char * parv [ ] ) ;
2020-03-29 09:16:53 +00:00
2021-06-19 15:52:51 +00:00
# include <sodium.h>
/* This is the 'chunk size', the size of encryption blocks.
* We choose 4 K here since that is a decent amount as of 2021 and
* more would not benefit performance anyway .
* Note that you cannot change this value easily afterwards
* ( you cannot read files with a different chunk size ) .
*/
# define UNREALDB_CRYPT_FILE_CHUNK_SIZE 4096
/** The salt length. Don't change. */
# define UNREALDB_SALT_LEN 16
/** Database modes of operation (read or write)
* @ ingroup UnrealDBFunctions
*/
typedef enum UnrealDBMode {
UNREALDB_MODE_READ = 0 ,
UNREALDB_MODE_WRITE = 1
} UnrealDBMode ;
typedef enum UnrealDBCipher {
UNREALDB_CIPHER_XCHACHA20 = 0x0001
} UnrealDBCipher ;
typedef enum UnrealDBKDF {
UNREALDB_KDF_ARGON2ID = 0x0001
} UnrealDBKDF ;
/** Database configuration for a particular file */
typedef struct UnrealDBConfig {
uint16_t kdf ; /**< Key derivation function (always 0x01) */
uint16_t t_cost ; /**< Time cost (number of rounds) */
uint16_t m_cost ; /**< Memory cost (in number of bitshifts, eg 15 means 1<<15=32M) */
uint16_t p_cost ; /**< Parallel cost (number of concurrent threads) */
uint16_t saltlen ; /**< Length of the salt (normally UNREALDB_SALT_LEN) */
char * salt ; /**< Salt */
uint16_t cipher ; /**< Encryption cipher (always 0x01) */
uint16_t keylen ; /**< Key length */
char * key ; /**< The key used for encryption/decryption */
} UnrealDBConfig ;
/** Error codes returned by @ref UnrealDBFunctions
* @ ingroup UnrealDBFunctions
*/
typedef enum UnrealDBError {
UNREALDB_ERROR_SUCCESS = 0 , /**< Success, not an error */
UNREALDB_ERROR_FILENOTFOUND = 1 , /**< File does not exist */
UNREALDB_ERROR_CRYPTED = 2 , /**< File is crypted but no password provided */
UNREALDB_ERROR_NOTCRYPTED = 3 , /**< File is not crypted and a password was provided */
UNREALDB_ERROR_HEADER = 4 , /**< Header is corrupt, invalid or unknown format */
UNREALDB_ERROR_SECRET = 5 , /**< Invalid secret { } block provided - either does not exist or does not meet requirements */
UNREALDB_ERROR_PASSWORD = 6 , /**< Invalid password provided */
UNREALDB_ERROR_IO = 7 , /**< I/O error */
UNREALDB_ERROR_API = 8 , /**< API call violation, eg requesting to write on a file opened for reading */
UNREALDB_ERROR_INTERNAL = 9 , /**< Internal error, eg crypto routine returned something unexpected */
} UnrealDBError ;
/** Database handle
* This is returned by unrealdb_open ( ) and used by all other @ ref UnrealDBFunctions
* @ ingroup UnrealDBFunctions
*/
typedef struct UnrealDB {
FILE * fd ; /**< File descriptor */
UnrealDBMode mode ; /**< UNREALDB_MODE_READ / UNREALDB_MODE_WRITE */
int crypted ; /**< Are we doing any encryption or just plaintext? */
uint64_t creationtime ; /**< When this file was created/updates */
crypto_secretstream_xchacha20poly1305_state st ; /**< Internal state for crypto engine */
char buf [ UNREALDB_CRYPT_FILE_CHUNK_SIZE ] ; /**< Buffer used for reading/writing */
int buflen ; /**< Length of current data in buffer */
UnrealDBError error_code ; /**< Last error code. Whenever this happens we will set this, never overwrite, and block further I/O */
char * error_string ; /**< Error string upon failure */
UnrealDBConfig * config ; /**< Config */
} UnrealDB ;
/** Used for speeding up reading/writing of DBs (so we don't have to run argon2 repeatedly) */
typedef struct SecretCache SecretCache ;
struct SecretCache {
SecretCache * prev , * next ;
UnrealDBConfig * config ;
time_t cache_hit ;
} ;
/** Used for storing secret { } blocks */
struct Secret {
Secret * prev , * next ;
char * name ;
char * password ;
SecretCache * cache ;
} ;
2020-03-29 09:16:53 +00:00
/* tkl:
* TKL_KILL | TKL_GLOBAL = Global K - Line ( GLINE )
* TKL_ZAP | TKL_GLOBAL = Global Z - Line ( ZLINE )
* TKL_KILL = Local K - Line
* TKL_ZAP = Local Z - Line
*/
# define TKL_KILL 0x00000001
# define TKL_ZAP 0x00000002
# define TKL_GLOBAL 0x00000004
# define TKL_SHUN 0x00000008
# define TKL_SPAMF 0x00000020
# define TKL_NAME 0x00000040
# define TKL_EXCEPTION 0x00000080
/* these are not real tkl types, but only used for exceptions: */
# define TKL_BLACKLIST 0x0001000
# define TKL_CONNECT_FLOOD 0x0002000
# define TKL_MAXPERIP 0x0004000
2021-03-21 17:05:35 +00:00
# define TKL_HANDSHAKE_DATA_FLOOD 0x0008000
2020-03-29 09:16:53 +00:00
# define TKL_ANTIRANDOM 0x0010000
# define TKL_ANTIMIXEDUTF8 0x0020000
# define TKL_BAN_VERSION 0x0040000
# define TKLIsServerBan(tkl) ((tkl)->type & (TKL_KILL|TKL_ZAP|TKL_SHUN))
# define TKLIsServerBanType(tpe) ((tpe) & (TKL_KILL|TKL_ZAP|TKL_SHUN))
# define TKLIsSpamfilter(tkl) ((tkl)->type & TKL_SPAMF)
# define TKLIsSpamfilterType(tpe) ((tpe) & TKL_SPAMF)
# define TKLIsNameBan(tkl) ((tkl)->type & TKL_NAME)
# define TKLIsNameBanType(tpe) ((tpe) & TKL_NAME)
# define TKLIsBanException(tkl) ((tkl)->type & TKL_EXCEPTION)
# define TKLIsBanExceptionType(tpe) ((tpe) & TKL_EXCEPTION)
# define SPAMF_CHANMSG 0x0001 /* c */
# define SPAMF_USERMSG 0x0002 /* p */
# define SPAMF_USERNOTICE 0x0004 /* n */
# define SPAMF_CHANNOTICE 0x0008 /* N */
2021-06-19 15:52:51 +00:00
# define SPAMF_PART 0x0010 /* P */
# define SPAMF_QUIT 0x0020 /* q */
# define SPAMF_DCC 0x0040 /* d */
# define SPAMF_USER 0x0080 /* u */
# define SPAMF_AWAY 0x0100 /* a */
# define SPAMF_TOPIC 0x0200 /* t */
# define SPAMF_MTAG 0x0400 /* m */
2020-03-29 09:16:53 +00:00
/* Other flags only for function calls: */
# define SPAMFLAG_NOWARN 0x0001
/* Ban actions. These must be ordered by severity (!) */
typedef enum BanAction {
BAN_ACT_GZLINE = 1100 ,
BAN_ACT_GLINE = 1000 ,
BAN_ACT_SOFT_GLINE = 950 ,
BAN_ACT_ZLINE = 900 ,
BAN_ACT_KLINE = 800 ,
BAN_ACT_SOFT_KLINE = 850 ,
BAN_ACT_SHUN = 700 ,
BAN_ACT_SOFT_SHUN = 650 ,
BAN_ACT_KILL = 600 ,
BAN_ACT_SOFT_KILL = 550 ,
BAN_ACT_TEMPSHUN = 500 ,
BAN_ACT_SOFT_TEMPSHUN = 450 ,
BAN_ACT_VIRUSCHAN = 400 ,
BAN_ACT_SOFT_VIRUSCHAN = 350 ,
BAN_ACT_DCCBLOCK = 300 ,
BAN_ACT_SOFT_DCCBLOCK = 250 ,
BAN_ACT_BLOCK = 200 ,
BAN_ACT_SOFT_BLOCK = 150 ,
BAN_ACT_WARN = 100 ,
BAN_ACT_SOFT_WARN = 50 ,
} BanAction ;
# define IsSoftBanAction(x) ((x == BAN_ACT_SOFT_GLINE) || (x == BAN_ACT_SOFT_KLINE) || \
( x = = BAN_ACT_SOFT_SHUN ) | | ( x = = BAN_ACT_SOFT_KILL ) | | \
( x = = BAN_ACT_SOFT_TEMPSHUN ) | | ( x = = BAN_ACT_SOFT_VIRUSCHAN ) | | \
( x = = BAN_ACT_SOFT_DCCBLOCK ) | | ( x = = BAN_ACT_SOFT_BLOCK ) | | \
( x = = BAN_ACT_SOFT_WARN ) )
/** Server ban sub-struct of TKL entry (KLINE/GLINE/ZLINE/GZLINE/SHUN) */
struct ServerBan {
char * usermask ; /**< User mask */
char * hostmask ; /**< Host mask */
unsigned short subtype ; /**< See TKL_SUBTYPE_* */
char * reason ; /**< Reason */
} ;
/* Name ban sub-struct of TKL entry (QLINE) */
struct NameBan {
char hold ; /**< nickname hold is used by services */
char * name ; /**< the nick or channel that is banned */
char * reason ; /**< Reason */
} ;
/** Spamfilter sub-struct of TKL entry (Spamfilter) */
struct Spamfilter {
unsigned short target ;
BanAction action ; /**< Ban action, see BAN_ACT* */
Match * match ; /**< Spamfilter matcher */
char * tkl_reason ; /**< Reason to use for bans placed by this spamfilter, escaped by unreal_encodespace(). */
time_t tkl_duration ; /**< Duration of bans placed by this spamfilter */
} ;
/** Ban exception sub-struct of TKL entry (ELINE) */
struct BanException {
char * usermask ; /**< User mask */
char * hostmask ; /**< Host mask */
2022-11-20 04:12:40 +00:00
SecurityGroup * match ; /**< Security group (for config file items only) */
2020-03-29 09:16:53 +00:00
unsigned short subtype ; /**< See TKL_SUBTYPE_* */
char * bantypes ; /**< Exception types */
char * reason ; /**< Reason */
} ;
# define TKL_SUBTYPE_NONE 0x0000
# define TKL_SUBTYPE_SOFT 0x0001 /* (require SASL) */
# define TKL_FLAG_CONFIG 0x0001 /* Entry from configuration file. Cannot be removed by using commands. */
/** A TKL entry, such as a KLINE, GLINE, Spamfilter, QLINE, Exception, .. */
struct TKL {
TKL * prev , * next ;
unsigned int type ; /**< TKL type. One of TKL_*, such as TKL_KILL|TKL_GLOBAL for gline */
unsigned short flags ; /**< One of TKL_FLAG_*, such as TKL_FLAG_CONFIG */
char * set_by ; /**< By who was this entry added */
time_t set_at ; /**< When this entry was added */
time_t expire_at ; /**< When this entry will expire */
union {
Spamfilter * spamfilter ;
ServerBan * serverban ;
NameBan * nameban ;
BanException * banexception ;
} ptr ;
} ;
/** A spamfilter except entry */
struct SpamExcept {
SpamExcept * prev , * next ;
char name [ 1 ] ;
} ;
/** IRC Counts, used for /LUSERS */
typedef struct IRCCounts IRCCounts ;
struct IRCCounts {
2022-01-15 05:16:34 +00:00
int clients ; /* total */
int invisible ; /* invisible */
int servers ; /* servers */
int operators ; /* operators */
int unknown ; /* unknown local connections */
int channels ; /* channels */
int me_clients ; /* my clients */
int me_servers ; /* my servers */
int me_max ; /* local max */
int global_max ; /* global max */
2020-03-29 09:16:53 +00:00
} ;
/** The /LUSERS stats information */
extern MODVAR IRCCounts irccounts ;
2022-01-15 05:16:34 +00:00
typedef struct NameValue NameValue ;
/** Name and value list used in a static array, such as in conf.c */
struct NameValue
{
long value ;
char * name ;
} ;
/** Name and value list used in dynamic linked lists */
2021-03-21 17:05:35 +00:00
typedef struct NameValueList NameValueList ;
struct NameValueList {
NameValueList * prev , * next ;
char * name ;
char * value ;
} ;
typedef struct NameValuePrioList NameValuePrioList ;
struct NameValuePrioList {
NameValuePrioList * prev , * next ;
int priority ;
char * name ;
char * value ;
} ;
2020-03-29 09:16:53 +00:00
# include "modules.h"
/** A "real" command (internal interface, not for modules) */
struct RealCommand {
RealCommand * prev , * next ;
char * cmd ;
CmdFunc func ;
AliasCmdFunc aliasfunc ;
int flags ;
unsigned int count ;
unsigned parameters : 5 ;
unsigned long bytes ;
Module * owner ;
RealCommand * friend ; /* cmd if token, token if cmd */
CommandOverride * overriders ;
# ifdef DEBUGMODE
unsigned long lticks ;
unsigned long rticks ;
# endif
} ;
/** A command override */
struct CommandOverride {
CommandOverride * prev , * next ;
int priority ;
Module * owner ;
RealCommand * command ;
OverrideCmdFunc func ;
} ;
2022-01-15 05:16:34 +00:00
extern MODVAR Umode * usermodes ;
extern MODVAR Cmode * channelmodes ;
2020-03-29 09:16:53 +00:00
extern Umode * UmodeAdd ( Module * module , char ch , int options , int unset_on_deoper , int ( * allowed ) ( Client * client , int what ) , long * mode ) ;
extern void UmodeDel ( Umode * umode ) ;
extern Cmode * CmodeAdd ( Module * reserved , CmodeInfo req , Cmode_t * mode ) ;
extern void CmodeDel ( Cmode * cmode ) ;
extern void moddata_init ( void ) ;
extern ModDataInfo * ModDataAdd ( Module * module , ModDataInfo req ) ;
extern void ModDataDel ( ModDataInfo * md ) ;
extern void unload_all_unused_moddata ( void ) ;
# define LISTENER_NORMAL 0x000001
# define LISTENER_CLIENTSONLY 0x000002
# define LISTENER_SERVERSONLY 0x000004
# define LISTENER_TLS 0x000010
# define LISTENER_BOUND 0x000020
# define LISTENER_DEFER_ACCEPT 0x000040
2022-04-03 15:09:29 +00:00
# define LISTENER_CONTROL 0x000080 /**< Control channel */
2020-03-29 09:16:53 +00:00
# define IsServersOnlyListener(x) ((x) && ((x)->options & LISTENER_SERVERSONLY))
# define CONNECT_TLS 0x000001
2022-01-15 05:16:34 +00:00
# define CONNECT_AUTO 0x000002
# define CONNECT_QUARANTINE 0x000004
# define CONNECT_INSECURE 0x000008
2020-03-29 09:16:53 +00:00
2022-01-15 05:16:34 +00:00
# define TLSFLAG_FAILIFNOCERT 0x0001
# define TLSFLAG_NOSTARTTLS 0x0002
# define TLSFLAG_DISABLECLIENTCERT 0x0004
2020-03-29 09:16:53 +00:00
2021-06-19 15:52:51 +00:00
/** Flood counters for local clients */
typedef struct FloodCounter {
int count ;
long t ;
} FloodCounter ;
/** This is the list of different flood counters that we keep for local clients. */
/* IMPORTANT: If you change this, update floodoption_names[] in src/user.c too !!!!!!!!!!!! */
typedef enum FloodOption {
FLD_NICK = 0 , /**< nick-flood */
FLD_JOIN = 1 , /**< join-flood */
FLD_AWAY = 2 , /**< away-flood */
FLD_INVITE = 3 , /**< invite-flood */
FLD_KNOCK = 4 , /**< knock-flood */
FLD_CONVERSATIONS = 5 , /**< max-concurrent-conversations */
2022-01-15 05:16:34 +00:00
FLD_LAG_PENALTY = 6 , /**< lag-penalty / lag-penalty-bytes */
2022-04-03 15:09:29 +00:00
FLD_VHOST = 7 , /**< vhost-flood */
2021-06-19 15:52:51 +00:00
} FloodOption ;
# define MAXFLOODOPTIONS 10
2022-01-15 05:16:34 +00:00
typedef struct TrafficStats TrafficStats ;
struct TrafficStats {
long long messages_sent ; /* IRC lines sent */
long long messages_received ; /* IRC lines received */
long long bytes_sent ; /* Bytes sent */
long long bytes_received ; /* Received bytes */
} ;
2021-06-19 15:52:51 +00:00
2022-04-03 15:09:29 +00:00
/** Socket type (IPv4, IPv6, UNIX) */
typedef enum {
SOCKET_TYPE_IPV4 = 0 , SOCKET_TYPE_IPV6 = 1 , SOCKET_TYPE_UNIX = 2
} SocketType ;
2020-03-29 09:16:53 +00:00
/** This shows the Client struct (any client), the User struct (a user), Server (a server) that are commonly accessed both in the core and by 3rd party coders.
* @ defgroup CommonStructs Common structs
* @ {
*/
/** A client on this or a remote server - can be a user, server, unknown, etc..
*/
struct Client {
struct list_head client_node ; /**< For global client list (client_list) */
struct list_head lclient_node ; /**< For local client list (lclient_list) */
struct list_head special_node ; /**< For special lists (server || unknown || oper) */
LocalClient * local ; /**< Additional information regarding locally connected clients */
2021-06-19 15:52:51 +00:00
User * user ; /**< Additional information, if this client is a user */
2022-01-15 05:16:34 +00:00
Server * server ; /**< Additional information, if this is a server */
2020-03-29 09:16:53 +00:00
ClientStatus status ; /**< Client status, one of CLIENT_STATUS_* */
struct list_head client_hash ; /**< For name hash table (clientTable) */
char name [ HOSTLEN + 1 ] ; /**< Unique name of the client: nickname for users, hostname for servers */
time_t lastnick ; /**< Timestamp on nick */
long flags ; /**< Client flags (one or more of CLIENT_FLAG_*) */
long umodes ; /**< Client usermodes (if user) */
Client * direction ; /**< Direction from which this client originated.
This always points to a directly connected server or & me .
It is never NULL */
unsigned char hopcount ; /**< Number of servers to this, 0 means local client */
char ident [ USERLEN + 1 ] ; /**< Ident of the user, if available. Otherwise set to "unknown". */
char info [ REALLEN + 1 ] ; /**< Additional client information text. For users this is gecos/realname */
char id [ IDLEN + 1 ] ; /**< Unique ID: SID or UID */
struct list_head id_hash ; /**< For UID/SID hash table (idTable) */
2022-01-15 05:16:34 +00:00
Client * uplink ; /**< Server on where this client is connected to (can be &me) */
2020-03-29 09:16:53 +00:00
char * ip ; /**< IP address of user or server (never NULL) */
ModData moddata [ MODDATA_MAX_CLIENT ] ; /**< Client attached module data, used by the ModData system */
} ;
/** Local client information, use client->local to access these (see also @link Client @endlink).
*/
struct LocalClient {
int fd ; /**< File descriptor, can be <0 if socket has been closed already. */
2022-04-03 15:09:29 +00:00
SocketType socket_type ; /**< Type of socket: IPv4, IPV6, UNIX */
2022-01-15 05:16:34 +00:00
SSL * ssl ; /**< OpenSSL/LibreSSL struct for TLS connection */
time_t fake_lag ; /**< Time when user will next be allowed to send something (actually fake_lag<currenttime+10) */
int fake_lag_msec ; /**< Used for calculating 'fake_lag' penalty (modulo) */
time_t creationtime ; /**< Time user was created (connected on IRC) */
time_t last_msg_received ; /**< Last time any message was received */
2020-03-29 09:16:53 +00:00
dbuf sendQ ; /**< Outgoing send queue (data to be sent) */
dbuf recvQ ; /**< Incoming receive queue (incoming data yet to be parsed) */
ConfigItem_class * class ; /**< The class { } block associated to this client */
int proto ; /**< PROTOCTL options */
long caps ; /**< User: enabled capabilities (via CAP command) */
time_t nexttarget ; /**< Next time that a new target will be allowed (msg/notice/invite) */
u_char targets [ MAXCCUSERS ] ; /**< Hash values of targets for target limiting */
ConfigItem_listen * listener ; /**< If this client IsListening() then this is the listener configuration attached to it */
long serial ; /**< Current serial number for send.c functions (to avoid sending duplicate messages) */
2022-01-15 05:16:34 +00:00
time_t next_nick_allowed ; /**< Time the next nick change will be allowed */
time_t idle_since ; /**< Last time a RESETIDLE message was received (PRIVMSG) */
TrafficStats traffic ; /**< Traffic statistics */
2020-03-29 09:16:53 +00:00
ModData moddata [ MODDATA_MAX_LOCAL_CLIENT ] ; /**< LocalClient attached module data, used by the ModData system */
char * error_str ; /**< Quit reason set by dead_socket() in case of socket/buffer error, later used by exit_client() */
char sasl_agent [ NICKLEN + 1 ] ; /**< SASL: SASL Agent the user is interacting with */
unsigned char sasl_out ; /**< SASL: Number of outgoing sasl messages */
unsigned char sasl_complete ; /**< SASL: >0 if SASL authentication was successful */
time_t sasl_sent_time ; /**< SASL: 0 or the time that the (last) AUTHENTICATE command has been sent */
2022-01-15 05:16:34 +00:00
char * sni_servername ; /**< Servername as sent by client via SNI (Server Name Indication) in TLS, otherwise NULL */
2020-03-29 09:16:53 +00:00
int cap_protocol ; /**< CAP protocol in use. At least 300 for any CAP capable client. 302 for 3.2, etc.. */
uint32_t nospoof ; /**< Anti-spoofing random number (used in user handshake PING/PONG) */
char * passwd ; /**< Password used during connect, if any (freed once connected and set to NULL) */
int authfd ; /**< File descriptor for ident checking (RFC931) */
int identbufcnt ; /**< Counter for 'ident' reading code */
struct hostent * hostp ; /**< Host record for this client (used by DNS code) */
char sockhost [ HOSTLEN + 1 ] ; /**< Hostname from the socket */
u_short port ; /**< Remote TCP port of client */
2021-06-19 15:52:51 +00:00
FloodCounter flood [ MAXFLOODOPTIONS ] ;
2020-03-29 09:16:53 +00:00
} ;
/** User information (persons, not servers), you use client->user to access these (see also @link Client @endlink).
*/
struct User {
Membership * channel ; /**< Channels that the user is in (linked list) */
Link * dccallow ; /**< DCCALLOW list (linked list) */
2022-01-15 05:16:34 +00:00
char account [ ACCOUNTLEN + 1 ] ; /**< Services account name or ID (SVID) - use IsLoggedIn(client) to check if logged in */
int joined ; /**< Number of channels joined */
2020-03-29 09:16:53 +00:00
char username [ USERLEN + 1 ] ; /**< Username, the user portion in nick!user@host. */
char realhost [ HOSTLEN + 1 ] ; /**< Realhost, the real host of the user (IP or hostname) - usually this is not shown to other users */
char cloakedhost [ HOSTLEN + 1 ] ; /**< Cloaked host - generated by cloaking algorithm */
char * virthost ; /**< Virtual host - when user has user mode +x this is the active host */
char * server ; /**< Server name the user is on (?) */
SWhois * swhois ; /**< Special "additional" WHOIS entries such as "a Network Administrator" */
2022-01-15 05:16:34 +00:00
WhoWas * whowas ; /**< Something for whowas :D :D */
char * snomask ; /**< Server Notice Mask (snomask) - only for IRCOps */
char * operlogin ; /**< Which oper { } block was used to oper up, otherwise NULL - used for auditting and by oper::maxlogins */
char * away ; /**< AWAY message, or NULL if not away */
time_t away_since ; /**< Last time the user went AWAY */
2020-03-29 09:16:53 +00:00
} ;
2022-01-15 05:16:34 +00:00
/** Server information (local servers and remote servers), you use client->server to access these (see also @link Client @endlink).
2020-03-29 09:16:53 +00:00
*/
struct Server {
char by [ NICKLEN + 1 ] ; /**< Uhhhh - who activated this connection - AGAIN? */
ConfigItem_link * conf ; /**< link { } block associated with this server, or NULL */
long users ; /**< Number of users on this server */
time_t boottime ; /**< Startup time of server (boot time) */
struct {
unsigned synced : 1 ; /**< Server synchronization finished? (3.2beta18+) */
unsigned server_sent : 1 ; /**< SERVER message sent to this link? (for outgoing links) */
} flags ;
struct {
char * usermodes ; /**< Usermodes that this server knows about */
char * chanmodes [ 4 ] ; /**< Channel modes that this server knows (in 4 groups, like CHANMODES= in ISUPPORT/005) */
int protocol ; /**< Link-protocol version */
char * software ; /**< Name of the software (eg: unrealircd-X.Y.Z) */
char * nickchars ; /**< Nick character sets active on this server) */
} features ;
} ;
2021-01-08 23:15:08 +00:00
/** @} */
2020-03-29 09:16:53 +00:00
struct MessageTag {
MessageTag * prev , * next ;
char * name ;
char * value ;
} ;
/* conf preprocessor */
typedef enum PreprocessorItem {
PREPROCESSOR_ERROR = 0 ,
PREPROCESSOR_DEFINE = 1 ,
PREPROCESSOR_IF = 2 ,
PREPROCESSOR_ENDIF = 3
} PreprocessorItem ;
typedef enum PreprocessorPhase {
PREPROCESSOR_PHASE_INITIAL = 1 ,
PREPROCESSOR_PHASE_MODULE = 2
} PreprocessorPhase ;
typedef enum AuthenticationType {
AUTHTYPE_INVALID = - 1 ,
AUTHTYPE_PLAINTEXT = 0 ,
AUTHTYPE_TLS_CLIENTCERT = 1 ,
AUTHTYPE_TLS_CLIENTCERTFP = 2 ,
AUTHTYPE_SPKIFP = 3 ,
AUTHTYPE_UNIXCRYPT = 4 ,
AUTHTYPE_BCRYPT = 5 ,
AUTHTYPE_ARGON2 = 6 ,
} AuthenticationType ;
typedef struct AuthConfig AuthConfig ;
/** Authentication Configuration - this can be a password or
* other authentication method that was parsed from the
* configuration file .
*/
struct AuthConfig {
AuthenticationType type ; /**< Type of data, one of AUTHTYPE_* */
char * data ; /**< Data associated with this record */
} ;
# ifndef HAVE_CRYPT
# define crypt DES_crypt
# endif
/*
* conf2 stuff - stskeeps
*/
typedef enum ConfigIfCondition { IF_DEFINED = 1 , IF_VALUE = 2 , IF_MODULE = 3 } ConfigIfCondition ;
struct ConditionalConfig
{
ConditionalConfig * prev , * next ;
int priority ; /**< Preprocessor level. Starts with 1, then 2, 3, .. */
ConfigIfCondition condition ; /**< See ConfigIfCondition, one of: IF_* */
int negative ; /**< For ! conditions */
char * name ; /**< Name of the variable or module */
char * opt ; /**< Only for IF_VALUE */
} ;
2022-01-15 05:16:34 +00:00
/** Configuration file (config parser) */
2020-03-29 09:16:53 +00:00
struct ConfigFile
{
2022-01-15 05:16:34 +00:00
char * filename ; /**< Filename of configuration file */
ConfigEntry * items ; /**< All items in the configuration file */
ConfigFile * next ; /**< Next configuration file */
2020-03-29 09:16:53 +00:00
} ;
2022-01-15 05:16:34 +00:00
/** Configuration entry (config parser) */
2020-03-29 09:16:53 +00:00
struct ConfigEntry
{
2022-01-15 05:16:34 +00:00
char * name ; /**< Variable name */
char * value ; /**< Variable value, can be NULL */
ConfigEntry * next ; /**< Next ConfigEntry */
ConfigEntry * items ; /**< Items (children), can be NULL */
ConfigFile * file ; /**< To which configfile does this belong? */
int line_number ; /**< Line number of the variable name (this one is usually used for errors) */
int file_position_start ; /**< Position (byte) within configuration file of the start of the block, rarely used */
int file_position_end ; /**< Position (byte) within configuration file of the end of the block, rarely used */
int section_linenumber ; /**< Line number of the section (only used internally for parse errors) */
ConfigEntry * parent ; /**< Parent item, can be NULL */
ConditionalConfig * conditional_config ; /**< Used for conditional config by the main parser */
unsigned escaped : 1 ;
2020-03-29 09:16:53 +00:00
} ;
struct ConfigFlag
{
unsigned temporary : 1 ;
unsigned permanent : 1 ;
} ;
/* configflag specialized for except socks/ban -Stskeeps */
struct ConfigFlag_except
{
unsigned temporary : 1 ;
unsigned type : 4 ;
} ;
struct ConfigFlag_ban
{
unsigned temporary : 1 ;
unsigned type : 4 ;
unsigned type2 : 2 ;
} ;
struct ConfigFlag_tld
{
unsigned temporary : 1 ;
unsigned motdptr : 1 ;
unsigned ruleclient : 1 ;
} ;
# define CONF_BAN_SERVER 1
# define CONF_BAN_VERSION 2
# define CONF_BAN_REALNAME 3
# define CONF_BAN_TYPE_CONF 0
# define CONF_BAN_TYPE_AKILL 1
# define CONF_BAN_TYPE_TEMPORARY 2
# define CRULE_ALL 0
# define CRULE_AUTO 1
struct ConfigItem {
ConfigItem * prev , * next ;
ConfigFlag flag ;
} ;
struct ConfigItem_me {
char * name , * info , * sid ;
} ;
struct ConfigItem_files {
char * motd_file , * rules_file , * smotd_file ;
char * botmotd_file , * opermotd_file , * svsmotd_file ;
char * pid_file , * tune_file ;
} ;
struct ConfigItem_admin {
ConfigItem_admin * prev , * next ;
ConfigFlag flag ;
char * line ;
} ;
# define CLASS_OPT_NOFAKELAG 0x1
struct ConfigItem_class {
ConfigItem_class * prev , * next ;
ConfigFlag flag ;
char * name ;
int pingfreq , connfreq , maxclients , sendq , recvq , clients ;
int xrefcount ; /* EXTRA reference count, 'clients' also acts as a reference count but
* link blocks also refer to classes so a 2 nd ref . count was needed .
*/
unsigned int options ;
} ;
struct ConfigFlag_allow {
unsigned noident : 1 ;
unsigned useip : 1 ;
unsigned tls : 1 ;
2021-01-08 23:15:08 +00:00
unsigned reject_on_auth_failure : 1 ;
2020-03-29 09:16:53 +00:00
} ;
2021-03-21 17:05:35 +00:00
/** allow { } block settings */
2020-03-29 09:16:53 +00:00
struct ConfigItem_allow {
2021-03-21 17:05:35 +00:00
ConfigItem_allow * prev , * next ;
ConfigFlag flag ;
2022-11-20 04:12:40 +00:00
SecurityGroup * match ;
2021-03-21 17:05:35 +00:00
char * server ;
AuthConfig * auth ;
int maxperip ; /**< Maximum connections permitted per IP address (locally) */
int global_maxperip ; /**< Maximum connections permitted per IP address (globally) */
int port ;
ConfigItem_class * class ;
ConfigFlag_allow flags ;
2022-01-15 05:16:34 +00:00
int ipv6_clone_mask ;
2020-03-29 09:16:53 +00:00
} ;
struct OperClassACLPath
{
OperClassACLPath * prev , * next ;
char * identifier ;
} ;
struct OperClassACLEntryVar
{
OperClassACLEntryVar * prev , * next ;
char * name ;
char * value ;
} ;
struct OperClassACLEntry
{
OperClassACLEntry * prev , * next ;
OperClassACLEntryVar * variables ;
OperClassEntryType type ;
} ;
struct OperClassACL
{
OperClassACL * prev , * next ;
char * name ;
OperClassACLEntry * entries ;
OperClassACL * acls ;
} ;
struct OperClass
{
char * ISA ;
char * name ;
OperClassACL * acls ;
} ;
struct OperClassCheckParams
{
Client * client ;
Client * victim ;
Channel * channel ;
2022-01-15 05:16:34 +00:00
const void * extra ;
2020-03-29 09:16:53 +00:00
} ;
struct ConfigItem_operclass {
ConfigItem_operclass * prev , * next ;
OperClass * classStruct ;
} ;
struct ConfigItem_oper {
ConfigItem_oper * prev , * next ;
ConfigFlag flag ;
char * name , * snomask ;
SWhois * swhois ;
AuthConfig * auth ;
char * operclass ;
ConfigItem_class * class ;
2022-11-20 04:12:40 +00:00
SecurityGroup * match ;
2020-03-29 09:16:53 +00:00
unsigned long modes , require_modes ;
char * vhost ;
int maxlogins ;
2022-01-15 05:16:34 +00:00
int server_notice_colors ;
2022-04-03 15:09:29 +00:00
int server_notice_show_event ;
2022-11-20 04:12:40 +00:00
int auto_login ;
2020-03-29 09:16:53 +00:00
} ;
2022-01-15 05:16:34 +00:00
/** The TLS options that are used in set::tls and otherblocks::tls-options.
2020-03-29 09:16:53 +00:00
* NOTE : If you add something here then you must also update the
* conf_tlsblock ( ) function in s_conf . c to have it inherited
* from set : : tls to the other config blocks !
*/
typedef struct TLSOptions TLSOptions ;
struct TLSOptions {
char * certificate_file ;
char * key_file ;
char * trusted_ca_file ;
unsigned int protocols ;
char * ciphers ;
char * ciphersuites ;
char * ecdh_curves ;
char * outdated_protocols ;
char * outdated_ciphers ;
long options ;
int renegotiate_bytes ;
int renegotiate_timeout ;
int sts_port ;
long sts_duration ;
int sts_preload ;
} ;
struct ConfigItem_mask {
ConfigItem_mask * prev , * next ;
ConfigFlag flag ;
char * mask ;
} ;
struct ConfigItem_drpass {
AuthConfig * restartauth ;
AuthConfig * dieauth ;
} ;
struct ConfigItem_ulines {
ConfigItem_ulines * prev , * next ;
ConfigFlag flag ;
char * servername ;
} ;
# define TLD_TLS 0x1
# define TLD_REMOTE 0x2
struct ConfigItem_tld {
ConfigItem_tld * prev , * next ;
ConfigFlag_tld flag ;
2022-11-20 04:12:40 +00:00
SecurityGroup * match ;
2022-01-15 05:16:34 +00:00
char * channel ;
2020-03-29 09:16:53 +00:00
char * motd_file , * rules_file , * smotd_file ;
char * botmotd_file , * opermotd_file ;
MOTDFile rules , motd , smotd , botmotd , opermotd ;
u_short options ;
} ;
struct ConfigItem_listen {
ConfigItem_listen * prev , * next ;
ConfigFlag flag ;
2022-04-03 15:09:29 +00:00
SocketType socket_type ;
char * file ;
2020-03-29 09:16:53 +00:00
char * ip ;
int port ;
int options , clients ;
int fd ;
SSL_CTX * ssl_ctx ;
TLSOptions * tls_options ;
int websocket_options ; /* should be in module, but lazy */
2022-01-15 05:16:34 +00:00
char * websocket_forward ;
2020-03-29 09:16:53 +00:00
} ;
struct ConfigItem_sni {
ConfigItem_sni * prev , * next ;
ConfigFlag flag ;
char * name ;
SSL_CTX * ssl_ctx ;
TLSOptions * tls_options ;
} ;
struct ConfigItem_vhost {
ConfigItem_vhost * prev , * next ;
ConfigFlag flag ;
2022-11-20 04:12:40 +00:00
SecurityGroup * match ;
2020-03-29 09:16:53 +00:00
char * login , * virthost , * virtuser ;
SWhois * swhois ;
AuthConfig * auth ;
} ;
struct ConfigItem_link {
ConfigItem_link * prev , * next ;
ConfigFlag flag ;
/* config options: */
char * servername ; /**< Name of the server ('link <servername> { }') */
struct {
2022-11-20 04:12:40 +00:00
SecurityGroup * match ; /**< incoming mask(s) to accept */
2020-03-29 09:16:53 +00:00
} incoming ;
struct {
2022-11-20 04:12:40 +00:00
char * file ; /**< UNIX domain socket to connect to */
2020-03-29 09:16:53 +00:00
char * bind_ip ; /**< Our IP to bind to when doing the connect */
char * hostname ; /**< Hostname or IP to connect to */
int port ; /**< Port to connect to */
int options ; /**< Connect options like tls or autoconnect */
} outgoing ;
AuthConfig * auth ; /**< authentication method (eg: password) */
char * hub ; /**< Hub mask */
char * leaf ; /**< Leaf mask */
int leaf_depth ; /**< Leaf depth */
ConfigItem_class * class ; /**< Class the server should use */
int options ; /**< Generic options such as quarantine */
int verify_certificate ;
/* internal: */
int refcount ; /**< Reference counter (used so we know if the struct may be freed) */
time_t hold ; /**< For how long the server is "on hold" for outgoing connects (why?) */
char * connect_ip ; /**< actual IP to use for outgoing connect (filled in after host is resolved) */
SSL_CTX * ssl_ctx ; /**< SSL Context for outgoing connection (optional) */
TLSOptions * tls_options ; /**< SSL Options for outgoing connection (optional) */
} ;
struct ConfigItem_ban {
ConfigItem_ban * prev , * next ;
ConfigFlag_ban flag ;
char * mask , * reason ;
unsigned short action ;
} ;
struct ConfigItem_deny_dcc {
ConfigItem_deny_dcc * prev , * next ;
ConfigFlag_ban flag ;
char * filename , * reason ;
} ;
struct ConfigItem_deny_link {
ConfigItem_deny_link * prev , * next ;
ConfigFlag_except flag ;
2022-01-15 05:16:34 +00:00
ConfigItem_mask * mask ;
char * rule , * prettyrule ;
2020-03-29 09:16:53 +00:00
} ;
struct ConfigItem_deny_version {
ConfigItem_deny_version * prev , * next ;
ConfigFlag flag ;
char * mask , * version , * flags ;
} ;
struct ConfigItem_deny_channel {
ConfigItem_deny_channel * prev , * next ;
ConfigFlag flag ;
char * channel , * reason , * redirect , * class ;
unsigned char warn ;
2022-11-20 04:12:40 +00:00
SecurityGroup * match ;
2020-03-29 09:16:53 +00:00
} ;
struct ConfigItem_allow_channel {
ConfigItem_allow_channel * prev , * next ;
ConfigFlag flag ;
char * channel , * class ;
2022-11-20 04:12:40 +00:00
SecurityGroup * match ;
2020-03-29 09:16:53 +00:00
} ;
struct ConfigItem_allow_dcc {
ConfigItem_allow_dcc * prev , * next ;
ConfigFlag_ban flag ;
char * filename ;
} ;
typedef enum {
ALIAS_SERVICES = 1 , ALIAS_STATS , ALIAS_NORMAL , ALIAS_COMMAND , ALIAS_CHANNEL , ALIAS_REAL
} AliasType ;
struct ConfigItem_alias {
ConfigItem_alias * prev , * next ;
ConfigFlag flag ;
ConfigItem_alias_format * format ;
char * alias , * nick ;
AliasType type ;
unsigned int spamfilter : 1 ;
} ;
struct ConfigItem_alias_format {
ConfigItem_alias_format * prev , * next ;
ConfigFlag flag ;
char * nick ;
AliasType type ;
char * format , * parameters ;
Match * expr ;
} ;
2022-01-15 05:16:34 +00:00
# define RESOURCE_REMOTE 0x1
# define RESOURCE_DLQUEUED 0x2
# define RESOURCE_INCLUDE 0x4
typedef struct ConfigEntryWrapper ConfigEntryWrapper ;
struct ConfigEntryWrapper {
ConfigEntryWrapper * prev , * next ;
ConfigEntry * ce ;
} ;
2020-03-29 09:16:53 +00:00
2022-01-15 05:16:34 +00:00
struct ConfigResource {
ConfigResource * prev , * next ;
int type ;
ConfigEntryWrapper * wce ; /**< The place(s) where this resource is begin used */
char * file ; /**< File to read: can be a conf/something file or a downloaded file */
char * url ; /**< URL, if it is an URL */
char * cache_file ; /**< Set to filename of local cached copy, if it is available */
2020-03-29 09:16:53 +00:00
} ;
struct ConfigItem_blacklist_module {
ConfigItem_blacklist_module * prev , * next ;
char * name ;
} ;
struct ConfigItem_help {
ConfigItem_help * prev , * next ;
ConfigFlag flag ;
char * command ;
MOTDLine * text ;
} ;
struct ConfigItem_offchans {
ConfigItem_offchans * prev , * next ;
2022-01-15 05:16:34 +00:00
char name [ CHANNELLEN + 1 ] ;
2020-03-29 09:16:53 +00:00
char * topic ;
} ;
2021-01-08 23:15:08 +00:00
# define SECURITYGROUPLEN 48
struct SecurityGroup {
SecurityGroup * prev , * next ;
int priority ;
char name [ SECURITYGROUPLEN + 1 ] ;
2022-11-20 04:12:40 +00:00
NameValuePrioList * printable_list ;
int printable_list_counter ;
/* Include */
2021-01-08 23:15:08 +00:00
int identified ;
int reputation_score ;
2022-11-20 04:12:40 +00:00
long connect_time ;
2021-01-08 23:15:08 +00:00
int webirc ;
int tls ;
2022-11-20 04:12:40 +00:00
NameList * ip ;
ConfigItem_mask * mask ;
NameList * security_group ;
NameValuePrioList * extended ;
/* Exclude */
int exclude_identified ;
int exclude_reputation_score ;
long exclude_connect_time ;
int exclude_webirc ;
int exclude_tls ;
NameList * exclude_ip ;
ConfigItem_mask * exclude_mask ;
NameList * exclude_security_group ;
NameValuePrioList * exclude_extended ;
2021-01-08 23:15:08 +00:00
} ;
2020-03-29 09:16:53 +00:00
# define HM_HOST 1
# define HM_IPV4 2
# define HM_IPV6 3
# define SETTER_NICK 0
# define SETTER_NICK_USER_HOST 1
/*
* statistics structures
*/
typedef struct IRCStatistics IRCStatistics ;
struct IRCStatistics {
unsigned int is_cl ; /* number of client connections */
unsigned int is_sv ; /* number of server connections */
unsigned int is_ni ; /* connection but no idea who it was */
time_t is_cti ; /* time spent connected by clients */
time_t is_sti ; /* time spent connected by servers */
unsigned int is_ac ; /* connections accepted */
unsigned int is_ref ; /* accepts refused */
unsigned int is_unco ; /* unknown commands */
unsigned int is_wrdi ; /* command going in wrong direction */
unsigned int is_unpf ; /* unknown prefix */
unsigned int is_empt ; /* empty message */
unsigned int is_num ; /* numeric message */
unsigned int is_kill ; /* number of kills generated on collisions */
unsigned int is_fake ; /* MODE 'fakes' */
unsigned int is_asuc ; /* successful auth requests */
unsigned int is_abad ; /* bad auth requests */
unsigned int is_udp ; /* packets recv'd on udp port */
unsigned int is_loc ; /* local connections made */
} ;
# define EXTCMODETABLESZ 32
/* Number of maximum paramter modes to allow.
* Don ' t set it unnecessarily high . . we only use k , l , L , j and f at the moment .
*/
# define MAXPARAMMODES 16
/** Channel Mode.
* NOTE : you normally don ' t access these struct members directly .
* For simple checking if a mode is set , use has_channel_mode ( )
* Otherwise , see the extended channel modes API , CmodeAdd ( ) , etc .
*/
struct Mode {
2022-01-15 05:16:34 +00:00
Cmode_t mode ; /**< Other ("extended") channel modes set on this channel */
void * mode_params [ MAXPARAMMODES + 1 ] ; /**< Parameters for extended channel modes */
2020-03-29 09:16:53 +00:00
} ;
2022-01-15 05:16:34 +00:00
/* flags for Link if used to contain Watch --k4be */
/* WATCH type */
# define WATCH_FLAG_TYPE_WATCH (1<<0) /* added via /WATCH command */
# define WATCH_FLAG_TYPE_MONITOR (1<<1) /* added via /MONITOR command */
/* behaviour switches */
# define WATCH_FLAG_AWAYNOTIFY (1<<8) /* should send AWAY notifications */
/* watch triggering events */
# define WATCH_EVENT_ONLINE 0
# define WATCH_EVENT_OFFLINE 1
# define WATCH_EVENT_AWAY 2
# define WATCH_EVENT_NOTAWAY 3
# define WATCH_EVENT_REAWAY 4
# define WATCH_EVENT_USERHOST 5
# define WATCH_EVENT_REALNAME 6
# define WATCH_EVENT_LOGGEDIN 7
# define WATCH_EVENT_LOGGEDOUT 8
2020-03-29 09:16:53 +00:00
/* Used for notify-hash buckets... -Donwulff */
struct Watch {
Watch * hnext ;
time_t lasttime ;
Link * watch ;
char nick [ 1 ] ;
} ;
/** General link structure used for certain chains (watch list, invite list, dccallow).
* Note that these always require you to use the make_link ( ) and free_link ( ) functions .
* Do not combine with other alloc / free functions ! !
*/
struct Link {
struct Link * next ;
int flags ;
union {
Client * client ;
Channel * channel ;
Watch * wptr ;
/* there used to be 'char *cp' here too,
* but in such a case you better use NameList
* instead of Link !
*/
} value ;
} ;
2022-01-15 05:16:34 +00:00
# define IsInvalidChannelTS(x) ((x) <= 1000000) /**< Invalid channel creation time */
2020-03-29 09:16:53 +00:00
/**
* @ addtogroup CommonStructs
* @ {
*/
/** A channel on IRC */
struct Channel {
struct Channel * nextch ; /**< Next channel in linked list (channel) */
struct Channel * prevch ; /**< Previous channel in linked list (channel) */
struct Channel * hnextch ; /**< Next channel in hash table */
Mode mode ; /**< Channel Mode set on this channel */
time_t creationtime ; /**< When the channel was first created */
char * topic ; /**< Channel TOPIC */
char * topic_nick ; /**< Person (or server) who set the TOPIC */
time_t topic_time ; /**< Time at which the topic was last set */
int users ; /**< Number of users in the channel */
Member * members ; /**< List of channel members (users in the channel) */
Ban * banlist ; /**< List of bans (+b) */
Ban * exlist ; /**< List of ban exceptions (+e) */
Ban * invexlist ; /**< List of invite exceptions (+I) */
char * mode_lock ; /**< Mode lock (MLOCK) applied to channel - usually by Services */
ModData moddata [ MODDATA_MAX_CHANNEL ] ; /**< Channel attached module data, used by the ModData system */
2022-01-15 05:16:34 +00:00
char name [ CHANNELLEN + 1 ] ; /**< Channel name */
2020-03-29 09:16:53 +00:00
} ;
/** user/channel member struct (channel->members).
* This is Member which is used in the linked list channel - > members for each channel .
* There is also Membership which is used in client - > user - > channels ( see Membership for that ) .
* Both must be kept synchronized 100 % at all times .
*/
struct Member
{
struct Member * next ; /**< Next entry in list */
Client * client ; /**< The client */
2022-01-15 05:16:34 +00:00
char member_modes [ MEMBERMODESLEN ] ; /**< The access of the user on this channel (eg "vhoqa") */
2020-03-29 09:16:53 +00:00
ModData moddata [ MODDATA_MAX_MEMBER ] ; /** Member attached module data, used by the ModData system */
} ;
/** user/channel membership struct (client->user->channels).
* This is Membership which is used in the linked list client - > user - > channels for each user .
* There is also Member which is used in channel - > members ( see Member for that ) .
* Both must be kept synchronized 100 % at all times .
*/
struct Membership
{
struct Membership * next ; /**< Next entry in list */
struct Channel * channel ; /**< The channel */
2022-01-15 05:16:34 +00:00
char member_modes [ MEMBERMODESLEN ] ; /**< The (new) access of the user on this channel (eg "vhoqa") */
2020-03-29 09:16:53 +00:00
ModData moddata [ MODDATA_MAX_MEMBERSHIP ] ; /**< Membership attached module data, used by the ModData system */
} ;
/** @} */
/** A ban, exempt or invite exception entry */
struct Ban {
struct Ban * next ; /**< Next entry in list */
char * banstr ; /**< The string (eg: *!*@*.example.org) */
char * who ; /**< Person or server who set the entry (eg: Nick) */
time_t when ; /**< When the entry was added */
} ;
/* Channel macros */
# define MODE_EXCEPT 0x0200
# define MODE_BAN 0x0400
# define MODE_INVEX 0x8000000
/* name invisible */
2022-01-15 05:16:34 +00:00
# define SecretChannel(x) ((x) && has_channel_mode((x), 's'))
2020-03-29 09:16:53 +00:00
/* channel not shown but names are */
2022-01-15 05:16:34 +00:00
# define HiddenChannel(x) ((x) && has_channel_mode((x), 'p'))
2020-03-29 09:16:53 +00:00
/* channel visible */
# define ShowChannel(v,c) (PubChannel(c) || IsMember((v),(c)))
2022-01-15 05:16:34 +00:00
# define PubChannel(x) (!SecretChannel((x)) && !HiddenChannel((x)))
2020-03-29 09:16:53 +00:00
# define IsChannelName(name) ((name) && (*(name) == '#'))
# define IsMember(blah,chan) ((blah && blah->user && \
find_membership_link ( ( blah - > user ) - > channel , chan ) ) ? 1 : 0 )
/* Misc macros */
# define BadPtr(x) (!(x) || (*(x) == '\0'))
/** Is valid character in nick? [not for external usage, use do_check_nickname instead!] */
# define isvalid(c) (char_atribs[(u_char)(c)]&ALLOWN)
# define TStime() (timeofday)
/* used in SetMode() in channel.c and cmd_umode() in s_msg.c */
# define MODE_NULL 0
# define MODE_ADD 0x40000000
# define MODE_DEL 0x20000000
/* return values for hunt_server() */
# define HUNTED_NOSUCH (-1) /* if the hunted server is not found */
# define HUNTED_ISME 0 /* if this server should execute the command */
# define HUNTED_PASS 1 /* if message passed onwards successfully */
/* used when sending to #mask or $mask */
# define MATCH_SERVER 1
# define MATCH_HOST 2
/* misc variable externs */
extern MODVAR char * version , * infotext [ ] , * dalinfotext [ ] , * unrealcredits [ ] , * unrealinfo [ ] ;
extern MODVAR char * generation , * creation ;
extern MODVAR char * gnulicense [ ] ;
/* misc defines */
# define COMMA ","
# define isexcept void
extern MODVAR SSL_CTX * ctx ;
extern MODVAR SSL_CTX * ctx_server ;
extern MODVAR SSL_CTX * ctx_client ;
# define TLS_PROTOCOL_TLSV1 0x0001
# define TLS_PROTOCOL_TLSV1_1 0x0002
# define TLS_PROTOCOL_TLSV1_2 0x0004
# define TLS_PROTOCOL_TLSV1_3 0x0008
# define TLS_PROTOCOL_ALL 0xffff
struct ThrottlingBucket
{
struct ThrottlingBucket * prev , * next ;
char * ip ;
time_t since ;
char count ;
} ;
typedef struct CoreChannelModeTable CoreChannelModeTable ;
struct CoreChannelModeTable {
long mode ; /**< Mode value (which bit will be set) */
char flag ; /**< Mode letter (eg: 't') */
unsigned halfop : 1 ; /**< May halfop set this mode? 1/0 */
unsigned parameters : 1 ; /**< Mode requires a parameter? 1/0 */
} ;
/** Parse channel mode */
typedef struct ParseMode ParseMode ;
struct ParseMode {
int what ;
char modechar ;
char * param ;
Cmode * extm ;
2022-01-15 05:16:34 +00:00
const char * modebuf ; /* curr pos */
const char * parabuf ; /* curr pos */
2020-03-29 09:16:53 +00:00
char buf [ 512 ] ; /* internal parse buffer */
} ;
2022-01-15 05:16:34 +00:00
# define MAXMULTILINEMODES 3
typedef struct MultiLineMode MultiLineMode ;
struct MultiLineMode {
char * modeline [ MAXMULTILINEMODES + 1 ] ;
char * paramline [ MAXMULTILINEMODES + 1 ] ;
int numlines ;
} ;
2020-03-29 09:16:53 +00:00
typedef struct PendingServer PendingServer ;
struct PendingServer {
PendingServer * prev , * next ;
char sid [ IDLEN + 1 ] ;
} ;
typedef struct PendingNet PendingNet ;
struct PendingNet {
PendingNet * prev , * next ; /* Previous and next in list */
Client * client ; /**< Client to which these servers belong */
PendingServer * servers ; /**< The list of servers connected to the client */
} ;
extern void init_throttling ( ) ;
extern struct ThrottlingBucket * find_throttling_bucket ( Client * ) ;
extern void add_throttling_bucket ( Client * ) ;
extern int throttle_can_connect ( Client * ) ;
typedef struct MaxTarget MaxTarget ;
struct MaxTarget {
MaxTarget * prev , * next ;
char * cmd ;
int limit ;
} ;
# define MAXTARGETS_MAX 1000000 /* used for 'max' */
# define VERIFY_OPERCOUNT(clnt,tag) { if (irccounts.operators < 0) verify_opercount(clnt,tag); } while(0)
# define MARK_AS_OFFICIAL_MODULE(modinf) do { if (modinf && modinf->handle) ModuleSetOptions(modinfo->handle, MOD_OPT_OFFICIAL, 1); } while(0)
# define MARK_AS_GLOBAL_MODULE(modinf) do { if (modinf && modinf->handle) ModuleSetOptions(modinfo->handle, MOD_OPT_GLOBAL, 1); } while(0)
/* used for is_banned type field: */
2022-01-15 05:16:34 +00:00
# define BANCHK_JOIN 0x0001 /* checking if a ban forbids the person from joining */
# define BANCHK_MSG 0x0002 /* checking if a ban forbids the person from sending messages */
# define BANCHK_NICK 0x0004 /* checking if a ban forbids the person from changing his/her nick */
# define BANCHK_LEAVE_MSG 0x0008 /* checking if a ban forbids the person from leaving a message in PART or QUIT */
# define BANCHK_TKL 0x0010 /* called from a server ban routine, or other match_user() usage */
# define BANCHK_ALL (BANCHK_JOIN|BANCHK_MSG|BANCHK_NICK|BANCHK_LEAVE_MSG) /* all events except BANCHK_TKL which is special */
2020-03-29 09:16:53 +00:00
# define TKLISTLEN 26
# define TKLIPHASHLEN1 4
# define TKLIPHASHLEN2 1021
# define MATCH_CHECK_IP 0x0001
# define MATCH_CHECK_REAL_HOST 0x0002
# define MATCH_CHECK_CLOAKED_HOST 0x0004
# define MATCH_CHECK_VISIBLE_HOST 0x0008
# define MATCH_CHECK_EXTENDED 0x0010
# define MATCH_CHECK_ALL (MATCH_CHECK_IP|MATCH_CHECK_REAL_HOST|MATCH_CHECK_CLOAKED_HOST|MATCH_CHECK_VISIBLE_HOST|MATCH_CHECK_EXTENDED)
# define MATCH_CHECK_REAL (MATCH_CHECK_IP|MATCH_CHECK_REAL_HOST|MATCH_CHECK_EXTENDED)
# define MATCH_MASK_IS_UHOST 0x1000
# define MATCH_MASK_IS_HOST 0x2000
typedef enum {
POLICY_ALLOW = 1 ,
POLICY_WARN = 2 ,
POLICY_DENY = 3
} Policy ;
# define NO_EXIT_CLIENT 99
/*-- badwords --*/
# define MAX_MATCH 1
# define MAX_WORDLEN 64
# define PATTERN "\\w*%s\\w*"
# define REPLACEWORD "<censored>"
# define BADW_TYPE_INVALID 0x0
# define BADW_TYPE_FAST 0x1
# define BADW_TYPE_FAST_L 0x2
# define BADW_TYPE_FAST_R 0x4
# define BADW_TYPE_REGEX 0x8
# define BADWORD_REPLACE 1
# define BADWORD_BLOCK 2
typedef struct ConfigItem_badword ConfigItem_badword ;
struct ConfigItem_badword {
ConfigItem_badword * prev , * next ;
ConfigFlag flag ;
char * word , * replace ;
unsigned short type ;
char action ;
pcre2_code * pcre2_expr ;
} ;
/*-- end of badwords --*/
/* Flags for 'sendflags' in 'sendto_channel' */
# define SEND_LOCAL 0x1
# define SEND_REMOTE 0x2
# define SEND_ALL (SEND_LOCAL|SEND_REMOTE)
# define SKIP_DEAF 0x4
# define SKIP_CTCP 0x8
2022-01-15 05:16:34 +00:00
typedef struct GeoIPResult GeoIPResult ;
struct GeoIPResult {
char * country_code ;
char * country_name ;
} ;
typedef enum WhoisConfigDetails {
WHOIS_CONFIG_DETAILS_DEFAULT = 0 ,
WHOIS_CONFIG_DETAILS_NONE = 1 ,
WHOIS_CONFIG_DETAILS_LIMITED = 2 ,
WHOIS_CONFIG_DETAILS_FULL = 3 ,
} WhoisConfigDetails ;
2022-11-20 04:12:40 +00:00
/* Options for StripControlCodesEx() */
# define UNRL_STRIP_LOW_ASCII 0x1 /**< Strip all ASCII < 32 (control codes) */
# define UNRL_STRIP_KEEP_LF 0x2 /**< Do not strip LF (line feed, \n) */
2020-03-29 09:16:53 +00:00
# endif /* __struct_include__ */
# include "dynconf.h"