| Commit message (Expand) | Author | Age | Files | Lines |
| * | Clean up include/stdinc.h and librb/include/rb_lib.h•••- Unconditionally require stdbool.h in IRCd
We are a C99 project anyway (configure.ac and meson.build both
require a C99 compiler), so this header will always be present
This removes the awful hack defining bool, true, and false in
its absense, which was creating build errors when using meson,
because meson.build did not set the HAVE_STDBOOL_H macro
- Modernise definition of alloca(3) according to GNU guidance
This was in both librb and IRCd, while it only needs to be in
the former
- Fix missing endianness check in librb/meson.build
IRCd and librb both use the WORDS_BIGENDIAN macro, which was
only being set by their configure.ac (with the AC_C_BIGENDIAN
M4 macro)
Since IRCd's stdinc.h includes librb's rb_lib.h, which then
includes librb's librb-config.h, which would have the macro
defined there, we only need to check for it in librb, so we
can remove the endianness check from IRCd's configure.ac and
don't need to add it to IRCd's meson.build
- Use __has_attribute to detect whether compiler attributes are
available
This is supported by gcc (5+), clang (2.9+), and ICC (17+)
- Add a __noreturn macro for __attribute__((__noreturn__)) and
adjust the codebase to use that
- Remove inclusion of headers that are only used by librb
- Remove inclusion of headers that are included in rb_lib.h
because stdinc.h includes rb_lib.h anyway
- Remove the checks for headers and functions from the IRCd
configure.ac and meson.build that are only used by librb
- Alphabetise checks for headers and functions (by the name of
the macro they define) in the meson.build files
- Use check_header() instead of has_header() in meson to see if
it is actually possible to compile code using the header
- Remove dead code using srand48(3) which has never been
compiled because neither build system has ever set the
HAVE_SRAND48 macro and the surrounding code makes no use of
this libc RNG
- Remove the TLS defines from IRCd's meson.build because librb's
meson.build already defines them and IRCd pulls those in
amdj/fix-buildsys-headers | Aaron Jones | 2026-05-14 | 19 | -276/+132 |
| * | Automatically rehash when modules change conf•••When loading a module that modifies config (add/remove conf items or top
conf sections), we now queue a rehash operation so that new config can
be immediately applied. A new rb_defer_once() function was added to
deduplicate these rehash requests so that at most one rehash will occur
regardless of how many modules change conf.
| Ryan Schmidt | 2026-04-29 | 7 | -5/+36 |
| * | Add m_quarantine•••This extension module provides a new usermode (+q) and two commands that
allow opers to set/unset that mode. The mode can be set either via
ircd.conf (general::default_umodes or auth::umodes) or via the
QUARANTINE command. When using the command, a reason is required which
will be broadcast to all other opers via the snote.
The quarantine will be automatically removed if the target opers up or
logs into a services account, and opers and logged in users cannot be
quarantined. The UNQUARNTINE command may additionally be used to remove
the quarantine status from a user. Users cannot otherwise set or remove
this usermode from themselves.
The QUARANTINE and UNQUARANTINE commands require a new priv
oper:quarantine.
To support this, a new account_change hook was added to m_services and
m_signon. This hook is fired whenever a user's services account changes
(via logging in or logging out) from the SVSLOGIN, SIGNON, LOGIN, or SU
services commands. It is **not** fired for SVSLOGIN on unknown
(pre-registration) users.
Documentation was updated for the new usermode, hook, and commands.
Usermode help was alphabetized for consistency, a missing entry for
helpops was added, and cloaking was moved to +x (since all modern
cloaking modules use that mode instead) since I was touching the file
anyway.
| Ryan Schmidt | 2026-04-29 | 11 | -54/+742 |
| * | OpenSSL backend: Use nicer error strings for system errors | Aaron Jones | 2026-04-09 | 1 | -0/+3 |
| * | Add +reply client tag support•••We validate that the reply looks like a valid message id as generated by
tag_message_id and, for channel messages, that the reply is going to the
same channel as specified in the message id. Since tag values do not
currently go through spamfilter, this is an easy-ish way to ensure that
it cannot be used as a backchannel for spam.
| Ryan Schmidt | 2026-04-09 | 4 | -0/+147 |
| * | Add +channel-context client tag•••The sender must be in the channel mentioned by the tag and must be able
to send messages to that channel. Since this is a hint for clients to
display the received PM in a channel buffer, having the ircd strip the
tag when the sender would otherwise not be able to talk in the channel
will help reduce confusion and make chanop actions more effective in
reducing perceived in-channel issues.
| Ryan Schmidt | 2026-04-09 | 4 | -0/+92 |
| * | Fix logfile checks•••- Initialize hooks before the main log file, because if we send a snote
due to failing to open a logfile, that calls a hook. Attempting to
call a hook before hooks are initialized will cause the ircd to
segfault.
- Skip access() check for the logfile itself and simply check the return
value of fopen(). This fixes a TOCTTOU race where an access check
succeeds but something causes the file to become inaccessible between
access() and fopen(), preventing an appropriate error from being
logged. Also makes my life easier with my custom SELinux policy for
the ircd since access() checks for full-write access whereas my policy
only allows append access for logfiles.
| Ryan Schmidt | 2026-04-05 | 2 | -13/+21 |
| * | Fix copy/paste errors | Ryan Schmidt | 2026-04-05 | 1 | -2/+2 |
| * | Allow all ircd file paths to be customized•••The ban.db file as well as both MOTD files were in hardcoded locations. Add new config options to the main solanum binary to manipulate where these files are looked for. This should make it fully possible to run multiple solanum instances from the same directory side-by-side.
| Ryan Schmidt | 2026-04-05 | 2 | -1/+13 |
| * | doc/: rename ircd.motd{,.example} and unconditionally install•••Fixes #510
| Aaron Jones | 2026-03-25 | 3 | -7/+2 |
| * | 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.
| Aaron Jones | 2026-03-22 | 8 | -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.
| Aaron Jones | 2026-03-22 | 6 | -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.
| Aaron Jones | 2026-03-22 | 1 | -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.
| Ryan Schmidt | 2026-03-19 | 4 | -2/+7 |
| * | build: add Meson buildsystem | Valentin Lorentz | 2026-03-17 | 18 | -11/+1095 |
| * | modules: drop unnecessary link flag | Valentin Lorentz | 2026-03-17 | 1 | -1/+0 |
| * | build: split help index generation into a script | Valentin Lorentz | 2026-03-17 | 2 | -45/+47 |
| * | librb: drop unnecessary configure checks | Valentin Lorentz | 2026-03-17 | 1 | -2/+0 |
| * | librb: drop pkg-config support | Valentin Lorentz | 2026-03-17 | 3 | -19/+1 |
| * | librb: modernize version.c generation | Valentin Lorentz | 2026-03-17 | 2 | -62/+56 |
| * | build: modernize version.c generation | Valentin Lorentz | 2026-03-17 | 2 | -61/+66 |
| * | build: split serno generation out into a script | Valentin Lorentz | 2026-03-17 | 7 | -18/+35 |
| * | README: update | Valentin Lorentz | 2026-03-17 | 1 | -12/+3 |
| * | build: require OpenSSL 1.1.0 or newer | Valentin Lorentz | 2026-03-17 | 1 | -3/+3 |
| * | CI: prepare for Meson | Valentin Lorentz | 2026-03-17 | 1 | -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.
| Ryan Schmidt | 2026-03-17 | 7 | -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)
| Ryan Schmidt | 2026-03-17 | 1 | -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.
| Ryan Schmidt | 2026-03-17 | 21 | -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.
| Ryan Schmidt | 2026-03-17 | 8 | -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).
| Ryan Schmidt | 2026-03-17 | 25 | -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.
| Ryan Schmidt | 2026-02-12 | 1 | -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.
| Valentin Lorentz | 2026-02-03 | 1 | -0/+2 |
| * | Write data files to $PREFIX/var/lib/solanum instead of $PREFIX/var/solanum wi... | Valentin Lorentz | 2026-02-03 | 1 | -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: e2a499f | Ryan Schmidt | 2026-01-27 | 1 | -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
| Aaron Jones | 2026-01-27 | 1 | -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.
| Ryan Schmidt | 2026-01-22 | 2 | -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
| Ryan Schmidt | 2026-01-22 | 5 | -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.
| Ryan Schmidt | 2026-01-21 | 2 | -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.
| Ryan Schmidt | 2026-01-21 | 5 | -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.
| Ryan Schmidt | 2026-01-21 | 3 | -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.
| Ryan Schmidt | 2026-01-21 | 5 | -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.
| Ryan Schmidt | 2026-01-21 | 1 | -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.
| Ryan Schmidt | 2026-01-21 | 2 | -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
| Ryan Schmidt | 2026-01-21 | 21 | -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. | Ryan Schmidt | 2026-01-11 | 1 | -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. | Ryan Schmidt | 2026-01-11 | 1 | -3/+0 |
| * | Replace git log usage with git rev-list (#479)•••This avoids issues with log.showSignature in serno.h | hello-smile6 | 2025-12-10 | 3 | -5/+5 |
| * | Fix memory leak in sendto_match_servs (#465)•••Free the msgbuf cache after we're done. | Ryan Schmidt | 2025-10-23 | 1 | -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.
| Andreas Rammhold | 2025-10-13 | 1 | -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. | Ryan Schmidt | 2025-10-11 | 1 | -0/+1 |