aboutsummaryrefslogtreecommitdiffstats
Commit message (Expand)AuthorAgeFilesLines
* Unify the preprocessor macro for OpenSSL support•••Commit 9a1ee1b64ed660164197 introduced support for building IRCd with Meson. It defines the "HAVE_OPENSSL" preprocessor macro for both IRCd and librb. While librb does use that macro, IRCd unfortunately uses only the "HAVE_LIBCRYPTO" macro instead, set implicitly by AC_CHECK_LIB from autotools. Make the autotools build system define HAVE_OPENSSL (to unify IRCd with librb) and change IRCd to use that. amdj/unify-openssl-macroGravatar Aaron Jones2026-03-228-19/+21
* Tidy up module loading code•••The existing code had several defects: - Core module file names were hardcoded, while autoloaded non- core module filenames were not. Code that loaded core modules had a different but in some places duplicated structure to the code that loaded autoloaded modules. - Module loading for autoloaded modules happened in dentry order, making it unpredictable from one server to the next, or even across instances of `make install` on the same server. - Module loading for autoloaded modules did not verify that the dentry was a file before trying to load it. - An IRCd start (or a conftest) only printed lines about loading modules mentioned in the configuration file. - The configuration file was parsed before loading core and autoloaded modules, meaning any modules specified in the configuration file would be loaded first. - Once a module was loaded, it was added to the head of the module list, making MODLIST show them in reverse loaded order (newest (re)loaded modules at the top of the list). These are addressed as follows: - We now scan the core and autoload module directories and use this to determine which modules to load. - We now sort the dentries according to their filename before iterating them to load them, making module load order finally deterministic. - We now test if a dentry is actually a file before trying to load it. - We now print a message to the console (if running in foreground or conftest mode) when loading any module, including core and autoloaded modules. - The message printed to the console now has the IRCd module directory prefix stripped from it if it matches. - The configuration file is now parsed after loading core and autoload modules. - The modules are added to the module list in the order that they are loaded. This now makes MODLIST show the order that modules were (re)loaded in. Modifications to two modules are part of this effort: - The autoload module `m_alias` relied upon the alias dict not being NULL when loaded, but this is only the case after the configuration file has been parsed. The module already had a "rehash" hook to destroy all existing aliases and create new ones, so we can just make the module do nothing on load (remove its modinit function) and change it to use the "conf_read_end" hook instead of the "rehash" hook, and it will still create aliases after the configuration file is subsequently parsed. With this modification, there are now no in-tree consumers of the "rehash" hook. - The autoload module `m_services` iterated `service_list` upon loading it, which will now be empty (a no-op) since the module is loaded before configuration file is parsed. This module too handles the configuration file being parsed with a "conf_read_end" hook and takes the appropriate action, so we can just remove this code from its modinit function. All other modules' modinit functions have been audited for behaviour like this; there was nothing of note. Gravatar Aaron Jones2026-03-226-83/+138
* extensions/invite_notify: don't pass string to macro•••The macro does not use this parameter but nevertheless this is the only module in the tree to pass a string to it, and if a future macro were to use it, it could easily stringify the name by using the # preprocessor operator. Gravatar Aaron Jones2026-03-221-1/+1
* Add no-implicit-names client capability•••This has been recently ratified and suppresses NAMES output during channel joins when enabled, providing for a decent chunk of bandwidth savings. Gravatar Ryan Schmidt2026-03-194-2/+7
* build: add Meson buildsystemGravatar Valentin Lorentz2026-03-1718-11/+1095
* modules: drop unnecessary link flagGravatar Valentin Lorentz2026-03-171-1/+0
* build: split help index generation into a scriptGravatar Valentin Lorentz2026-03-172-45/+47
* librb: drop unnecessary configure checksGravatar Valentin Lorentz2026-03-171-2/+0
* librb: drop pkg-config supportGravatar Valentin Lorentz2026-03-173-19/+1
* librb: modernize version.c generationGravatar Valentin Lorentz2026-03-172-62/+56
* build: modernize version.c generationGravatar Valentin Lorentz2026-03-172-61/+66
* build: split serno generation out into a scriptGravatar Valentin Lorentz2026-03-177-18/+35
* README: updateGravatar Valentin Lorentz2026-03-171-12/+3
* build: require OpenSSL 1.1.0 or newerGravatar Valentin Lorentz2026-03-171-3/+3
* CI: prepare for MesonGravatar Valentin Lorentz2026-03-171-2/+2
* Remove channel::kick_on_split_riding•••This feature had numerous pitfalls (such as not checking +beI) and services does it better than we can. Remove it and alert opers that the feature no longer exists if they had it configured. Gravatar Ryan Schmidt2026-03-177-59/+8
* Unconditionally include <stdint.h> in stdinc.h•••Previously we relied on an inclusion from librb-config.h which was generated via the configure script. This seemed unwise, so add it to our list of standard includes. This replaces a superfluous include of stdio.h since we included it twice for some reason (check two lines down from the changed line for the other location) Gravatar Ryan Schmidt2026-03-171-1/+1
* Adjust unsigned int -> uint64_t for all caps•••The previous commit addressed the issue with (most) function signatures, but forgot to update the caps themselves to be 64-bit. This fixes that, and finishes the remaining overlooked function signatures. Gravatar Ryan Schmidt2026-03-1721-94/+92
* Apply review suggestions•••Also made full use of the Set/Clear macros across the codebase so there's fewer places to touch in the future if changes are needed. Gravatar Ryan Schmidt2026-03-178-169/+169
* Separate client vs server caps•••Instead of overloading the same field in a LocalUser, have separate fields for client caps vs server caps. While only one of these will ever be nonzero, it reduces error by making it explicit which set of caps is being checked. IsCapable and friends have been split as well, to IsClientCapable and IsServerCapable. Finally, both fields have been updated to uint64_t (server caps were approaching the current limit) and all APIs that reference caps updated to uint64_t as well (no more signed/unsigned mismatches). Gravatar Ryan Schmidt2026-03-1725-349/+347
* Make TAGMSG behave like NOTICE for errors•••We explicitly do not send error numerics to clients for NOTICE in most cases, instead silently discarding the command. Give this treatment to TAGMSG across the board as well. Previously, this was the case for TAGMSG without tags but was not applied for TAGMSG that had tags but otherwise had issues (e.g. +m channel and the user is not +ov). This prevents spamming users whose clients send automatic TAGMSG with errors they can do nothing about. Gravatar Ryan Schmidt2026-02-121-17/+17
* Create $PREFIX/var/solanum on install with --enable-fhs-paths•••On startup, bandb tries to create $PREFIX/var/solanum/ban.db, which fails if the directory does not exist. Gravatar Valentin Lorentz2026-02-031-0/+2
* Write data files to $PREFIX/var/lib/solanum instead of $PREFIX/var/solanum wi...Gravatar Valentin Lorentz2026-02-031-1/+1
* parse: fix crash•••The incoming_client and incoming_message globals were not properly cleared after processing a numeric command. Ensure they are cleared by not returning early after setting those global values. Fixes: e2a499fGravatar Ryan Schmidt2026-01-271-3/+3
* ircd/newconf.c: conf_set_general_hidden_caps: fix order of operations•••We should increment the number of capabilities to allocate space for after freeing any existing capabilities, in order to prevent the loop that frees them from overwriting the number. Reported-By: Ryan Schmidt Gravatar Aaron Jones2026-01-271-6/+10
* Add doing_version_confopts hook•••This hook allows modification of the confopts portion of a VERSION response (i.e. the set of flags representing how the ircd was configured). Extension modules can use this hook to display additional confopts without needing to edit m_version or add things to core in order to share state with m_version. Gravatar Ryan Schmidt2026-01-222-61/+115
* Pass msgbuf to PART's privmsg_channel hook and propagate PART tags•••The privmsg_channel hook gained a new msgbuf member which was uninitialized in m_part. Properly pass the msgbuf to that parameter and propagate any tags set by the hook to downstream servers. This requires introducing sendto_server_tags(), and I refactored sendto_server() to call the same helper internal method as sendto_server_tags(). I took the opportunity to update the method to use msgbuf instead of linebuf directly (meaning sendto_server() now calls outbound_msgbuf). Fixes #484 Gravatar Ryan Schmidt2026-01-225-37/+93
* Overhaul hooks documentation•••The new hooks documentation is now a comprehensive accounting of every hook that exists in the solanum repo. The document includes changes to hooks present in the (as of now unmerged) PRs #466, #478, and #482. Gravatar Ryan Schmidt2026-01-212-137/+1214
* Add doing_info_conf hook and cleanup unused hooks•••doing_info_conf is called during INFO commands after all conf options have been sent to opers. Modules can use this hook to expose any conf options they define by sending relevant RPL_INFO replies to the oper. This addition removes the final barrier to defining new ircd.conf options inside of extension modules rather than requiring core changes for extension configuration. Additionally, some cleanup has been performed for hook definitions that are not called anywhere inside of solanum. Three hooks were declared in hook.h as extern int but were not defined or referenced in any other file: iosend_id, iorecv_id, and iorecvctrl_id. The doing_admin, doing_info, doing_motd, and doing_trace "spy" hooks were defined in the module headers for those modules, however the modules never actually invoked those hooks. All of the lingering declarations for these hooks have now been removed as they weren't doing anything anyway. Gravatar Ryan Schmidt2026-01-215-22/+7
* Fix msgid tags with echo-message•••msgid generation has been moved to the privmsg_user and privmsg_channel hooks, which are called on every normal PRIVMSG/NOTICE/TAGMSG. They are not called when messaging user@server, opers@server, or mass-messages and as such none of those things will have msgid attached. This seems fine as user@server is rejected by solanum and exists solely for messaging pseudoservers, opers@server is turned into a snote, and mass-messages are oper-only and thus unlikely to need anything that keys off msgid in the future. Moving this solves the interaction with msgid and echo-message. Now, we ensure that an echoed message always has a msgid, and that msgid is always the same as the msgid shown to other clients. This requires expanding the hook_data structures for those two hooks. While a core restart is not needed, attempting to reload tag_message_id before reloading m_message may cause crashes. When updating your servers, please reload m_message first. Gravatar Ryan Schmidt2026-01-213-119/+133
* Batch updates•••The extension example_module was extended to introduce a new client-initiated batch type named test. This is primarily done to ease testing of the client-initiated portions of m_batch, but also serves as a useful sketch for how a module can register its own client-initiated batch types. The definition of struct BatchHandler was slightly modified to use a callback function to determine if nesting is allowed. The callback can additionally set a custom error message if desired when returning false. The len and messages list in struct Batch no longer include the start message, so a len of 0 indicates an empty batch. Because the start message is still allocated and saved off, adjust anything that impacts a client's pending_batch_lines by 1 to account for the implicit additional message. Empty batches now trigger the relevant batch handler. If a handler wants to no-op on empty batches, it can do so but this allows additional flexibility for handlers to still do something upon receiving empty client-initiated batches. Gravatar Ryan Schmidt2026-01-215-50/+85
* Avoid making spurious netjoin batches•••If a server being netjoined to us is introducing additional downstream servers from it, those servers won't themselves be sending us bursts. As such, we can safely suppress sending a BATCH to clients for those additional servers. Gravatar Ryan Schmidt2026-01-211-0/+6
* Include AWAY and status MODEs in netjoin batches•••AWAY is burst to away-notify clients and status MODEs (+o and +v) are burst to all clients on the channel. Excluding these from the batch means that clients may opt to process these before the batch completes, then get confused because they have no records of those nicknames existing or being members of the channel. Including both in the netjoin batch solves these concerns, although the netjoin batch spec is silent on whether we're allowed to put non-JOIN commands in that batch. Gravatar Ryan Schmidt2026-01-212-21/+19
* Add batch support•••- Add "batch" client capability - Support sending netsplit/netjoin batches - Support receiving BATCH from clients and remote servers - Support for modules to define supported batch types for incoming batches - Add "message_handler" hook to override the handler for a particular incoming message - Add technical and user-facing documentation for batches - Add some more sendto_* overloads that support tags which were missing from the initial message-tags implementation but turned out to be needed Gravatar Ryan Schmidt2026-01-2121-115/+1308
* Propagate tags in numerics from linked servers (#477)•••Previously, we handled numerics before running the message_tags hook or setting the incoming_message and incoming_client globals, which meant that tags received from linked servers would never be passed along to clients. Now do both of those things before passing the numeric along so we can propagate message tags in numerics. This will, among other things, mean server-time now works with numerics and solves an issue with implementing labeled-response in the future.Gravatar Ryan Schmidt2026-01-111-20/+18
* Stop sending ERR_NOTEXTTOSEND on empty TAGMSG (#476)•••Per the message-tags spec, clients are allowed to send tags blocked by CLIENTTAGDENY, and some clients make use of this allowance to send tags that are otherwise stripped out (e.g. +typing if that module is not loaded). If a TAGMSG did not have any client tags after processing, we previously returned ERR_NOTEXTTOSEND (412) however this results in a fair amount of spam in the server buffer of such clients. Make the command silently fail instead. An open question remains on how this interacts with echo-message, as the spec is not well-written to cover what happens during failure/error cases. A strict reading of the spec would require an echo-message on every received PRIVMSG/NOTICE/TAGMSG, including cases where we are already sending an error numeric. This does not seem intended, and would complicate labeled-response by requiring a batch in error cases. A looser reading of the spec seems to permit not sending any echo-message in the case that messages are filtered out (as the portion of the spec allowing "fake messages" is a MAY). Since we currently do not send any echo-message for empty NOTICE (and do not send any numerics either), apply the same treatment for empty TAGMSG: the server silently drops the command and does not echo anything back to the client.Gravatar Ryan Schmidt2026-01-111-3/+0
* Replace git log usage with git rev-list (#479)•••This avoids issues with log.showSignature in serno.hGravatar hello-smile62025-12-103-5/+5
* Fix memory leak in sendto_match_servs (#465)•••Free the msgbuf cache after we're done.Gravatar Ryan Schmidt2025-10-231-0/+2
* Remote the `compressed` server flag•••This is a follow-up to 81531536aac9adb585c5a17b448aa0496bf68ebd where the ziplinks feature had been ripped out. Unfortunately the value of the `compressed` flag had been set to `0` instead of `-1`, or removed entirely. This led to resetting a connect blocks flags being reset whenever the `compressed` flag was being set. When you'd set the flags (in this order) `topicburst, compressed, ssl` you'd end up with just the `ssl` flag as setting `compressed` would reset all of the flag back to zero (newconf.c:439) as set_modes_from_table excepts `-1` to be passed as not-found / invalid flag value. With this (trivial) patch the log will contain a helpful line telling operators that the `compressed` flag is unknown. It doesn't fail config parsing/rehashing: > Warning -- unknown flag compressed. Gravatar Andreas Rammhold2025-10-131-1/+0
* Fix CLIENTTAGDENY when there are no allowed tags (#461)•••The buffer was uninitialized and would produce garbage data. Ensure that the buffer is an empty string when there are no allowed client tags.Gravatar Ryan Schmidt2025-10-111-0/+1
* Revert "msgbuf: duplicate the string during partial parse and constify line" ...•••This reverts commit 5b253939da8f6b0a44ce6787ed12e26450ac6a63 to fix a memory leak: ``` ==825564== 818 bytes in 4 blocks are definitely lost in loss record 616 of 648 ==825564== at 0x4844818: malloc (vg_replace_malloc.c:446) ==825564== by 0x49CD7A9: strdup (strdup.c:42) ==825564== by 0x4888A2E: msgbuf_partial_parse (msgbuf.c:143) ==825564== by 0x489DA84: build_msgbuf (send.c:276) ==825564== by 0x489DA84: sendto_one_numeric (send.c:431) ==825564== by 0x48A3CD7: show_isupport (supported.c:181) ==825564== by 0x489A9F2: user_welcome (s_user.c:1433) ==825564== by 0x489B114: register_local_user (s_user.c:718) ==825564== by 0x488FC08: handle_command (parse.c:310) ==825564== by 0x488FC08: parse (parse.c:224) ==825564== by 0x488EEF8: parse_client_queued.part.0 (packet.c:67) ==825564== by 0x488F084: parse_client_queued (packet.c:49) ==825564== by 0x488F084: read_packet (packet.c:306) ==825564== by 0x4B3C47B: rb_select_epoll (epoll.c:199) ==825564== by 0x4B3716F: rb_select (commio.c:2038) ==825564== [...] ==825564== ==825564== 3,012 bytes in 15 blocks are definitely lost in loss record 627 of 648 ==825564== at 0x4844818: malloc (vg_replace_malloc.c:446) ==825564== by 0x49CD7A9: strdup (strdup.c:42) ==825564== by 0x4888A2E: msgbuf_partial_parse (msgbuf.c:143) ==825564== by 0x489D3CE: build_msgbuf (send.c:276) ==825564== by 0x489D3CE: sendto_realops_snomask (send.c:1431) ==825564== by 0x4887C0D: load_a_module (modules.c:712) ==825564== by 0x488801D: load_core_modules (modules.c:257) ==825564== by 0x488124A: solanum_main (ircd.c:664) ==825564== by 0x494DCA7: (below main) (libc_start_call_main.h:58) ```Gravatar Val Lorentz2025-10-113-4/+4
* Remove duplicate definition message-tags CAP•••It is defined in s_serv.c so it doesn't need to additionally be defined in modules/core/m_message.c. Support for receiving client tags is baked into parse.c and other core files, so the definition in s_serv.c is the right place for it. Gravatar Ryan Schmidt2025-10-101-1/+0
* Address review comments•••- Remove static qualifier from a string that didn't need it - Add some tests for trailing params with a leading colon as data to ensure they are parsed/unparsed correctly Gravatar Ryan Schmidt2025-10-103-1/+39
* Ensure duplicate tags only use the final value•••Per spec, individual tag keys MUST only be used once per message, and implementations SHOULD disregard all but the final occurrence of a tag key. As such, iterate over the user-provided tags in reverse order and automatically discard tags that we have already approved. Also, require that a client giving us a +typing tag has negotiated the message-tags capability themselves. Gravatar Ryan Schmidt2025-10-102-2/+10
* Fix typing module decl and send 417 in more cases•••The typing module declaration had a copy/paste error that has now been corrected, and we now send 417 ERR_INPUTTOOLONG in cases where parsing the line into a MsgBuf fails because it overflowed the 8191+512 byte buffer while processing tags or the message origin. Gravatar Ryan Schmidt2025-10-104-6/+18
* Address review comments•••Correctly sent ERR_INPUTTOOLONG if the incoming tags portion from a client is too long. The previous calculation did not take into account the fact we added null terminators after every tag key and value. Since msgbuf_parse is used for both server and client input, we expose the length of the original tags portion of the buffer in the MsgBuf struct rather than abort msgbuf_parse if it is too long, since the only time truncation is explicitly not allowed is for incoming tags from client messages. Additionally, make join_sep functional in format_client_tags(). Gravatar Ryan Schmidt2025-10-104-28/+33
* Documentation updates•••Add user help for the TAGMSG command. Additionally, update reference.conf to include (almost) all extensions. The only extensions excluded were those that are only useful when testing/debugging (m_echotags), example modules (chantype_dummy, example_module), or modules that should probably never be loaded in new networks (ip_cloaking_3.0, ip_cloaking_old, m_mkpasswd). Gravatar Ryan Schmidt2025-10-103-8/+85
* Update tests•••A number of tests needed to be updated to account for the fact that tags are allowed to be up to 8191 bytes (or 4094 bytes for the client-specified portion or server-specified portion individually). The numbers in these tests were updated, and in some cases we now test both server and client tags to ensure consistent behavior between both types. Gravatar Ryan Schmidt2025-10-104-284/+1028
* extensions/tag_typing: Add +typing tag support•••The spec allows for three values: active, paused, and done, so filter to only allow those three. No ratelimiting has been added as part of this module, as the regular ratelimiting that applies to all sent messages is likely sufficient for typing notifications. Gravatar Ryan Schmidt2025-10-102-0/+71
* extensions/tag_message_id: Add msgid support•••Support the @msgid tag to label outgoing PRIVMSG, NOTICE, and TAGMSG with a server-generated ID. Clients can make use of this ID for various purposes, mostly in interaction with other (client-only) tags. The msgid format was chosen so that it encodes enough state within the id itself to be useful for eventual implementations of reply and message-redaction. The format is as follows: 1. The character '1' to indicate this is message id format version 1 2. The timestamp the message was sent (milliseconds since epoch) 3. An incrementing counter value, for when multiple messages are sent within the same second. The counter is seeded to a random number each new second, so that it is not useful as a means of determining the total number of messages sent by this server in a particular period of time 4. The ID of the client sending the message 5. If the message is being sent to a channel, the base64-encoded name of that channel This metadata achieves multiple goals: 1. Message ids are sorted in lexically ascending order based on the time they are sent, with the counter ensuring that earlier messages within the same time increment are sorted before later messages. This could potentially help in any sort of future shared message database to achieve time-based queries, e.g. chathistory 2. When a client replies to a message, the server can partially validate the msgid being replied to, ensuring that replies to a channel message are only sent to that channel or replies to a user private message are only sent to that user 3. The server can validate a client attempting to redact their own message by comparing the client's ID and connection time against the specified message's client ID and timestamp, allowing stateless approval of self-redactions 4. The server can validate a chanop attempting to redact a message sent in their channel by comparing the channel name and creation timestamp against the specified message's channel name and timestamp, allowing stateless approval of chanop-intiated redactions 5. No signing of messages is performed so a msgid cannot be used to prove any particular message was sent by any particular client Gravatar Ryan Schmidt2025-10-102-0/+144