readme: cover the full feature set (modes, ircv3, services, s2s, geoip, rpc, transports)

This commit is contained in:
Jean Chevronnet 2026-08-10 11:36:38 +00:00
parent 1dd7f77ca8
commit 75de56f532

152
README.md
View file

@ -6,9 +6,11 @@ handler objects, and modules hook lifecycle events. Design goals:
for TLS and `mio` for the epoll socket engine), and lock-free (a single core for TLS and `mio` for the epoll socket engine), and lock-free (a single core
thread owns all state). thread owns all state).
> Status: early but capable. It boots, registers clients, speaks a large chunk of > Status: capable and broad. It speaks a large slice of the IRC + IRCv3 protocol
> the IRC + IRCv3 protocol (see **What works**), and one reactor thread has served > — **100+ commands**, the full channel/user mode set, **28 IRCv3 capabilities**,
> 5,000 concurrent connections in testing. Not battle-tested yet. > and **~55 pluggable modules** — with server-to-server linking, a services
> interface, TLS, WebSocket, GeoIP and a JSON-RPC control plane. One reactor thread
> has served 5,000 concurrent connections in testing. Not battle-tested yet.
## Run it ## Run it
@ -46,6 +48,19 @@ no cull list), an `Extensible` typemap instead of `void*` module data (freed
automatically on drop), `&str` slices, and compiled-in trait objects instead of a automatically on drop), `&str` slices, and compiled-in trait objects instead of a
fragile `.so` ABI. fragile `.so` ABI.
### Why a raw reactor, not async?
IRC is one big shared mutable graph (users, channels, the nick index), and almost
every command mutates it and then broadcasts. With one thread owning all of it,
handlers are plain `&mut Server` code — no locks, no `.await`, no `Send + 'static`
bounds. A multi-threaded async runtime would force that shared state behind
mutexes or an actor mailbox, and a channel broadcast is serialized anyway, so
you'd pay locking cost for parallelism the workload can't use. `mio` is the same
readiness layer async runtimes are built on, so you keep the C50k scaling without
the runtime. CPU-heavy or blocking work (DNS, TLS, outbound HTTP) is pushed to its
own threads; the network scales out by **linking servers**, not by adding cores to
one process.
### The two extension points ### The two extension points
- **Commands** (`src/command.rs`, `src/coremods/`) — a handler declares `name`, - **Commands** (`src/command.rs`, `src/coremods/`) — a handler declares `name`,
@ -59,34 +74,109 @@ fragile `.so` ABI.
## What works ## What works
- Registration (`CAP`/`NICK`/`USER`), `PING`/`PONG` with idle + registration ### Registration & session
timeouts, welcome burst (001005) + ISUPPORT. - `CAP` negotiation, `NICK`/`USER`, `PING`/`PONG` with configurable idle +
- `JOIN`/`PART`/`NAMES`/`TOPIC`/`KICK`/`INVITE`, `PRIVMSG`/`NOTICE`/`TAGMSG`, registration timeouts, welcome burst (001005) + ISUPPORT (optionally batched).
`NICK`, `WHO`/`WHOIS`/`WHOWAS`, `LIST`, `AWAY`, `QUIT`, `MOTD`/`LUSERS`. - `WEBIRC` (real client IP from a trusted web gateway), `conn_waitpong` (require a
- **Full mode set** as handler objects: prefixes `+qaohv`, lists `+beI`, and PONG cookie before registering — filters bots), `autodrop` (silently drop
`+klmntispzONCTcSRMGu` plus flood/rate modes `+f/+j/+F`, redirect `+L`, word pre-registration HTTP scanners), configurable nick/channel length limits.
filter `+g`, and acting **extbans** `m:`/`c:`/`n:`.
- **IRC operators**: `OPER`/`KILL`/`WALLOPS`/`GLOBOPS`, `SAJOIN`/`SAPART`/`SANICK`/ ### Channels
`SAMODE`/`SATOPIC`/`SAKICK`, `CHGHOST`/`CHGIDENT`/`SETHOST`/`SETIDENT`, - `JOIN`/`PART`/`NAMES`/`TOPIC`/`KICK`/`INVITE`, plus `KNOCK`, `CYCLE`, `REMOVE`,
`KLINE`/`GLINE`/`ZLINE` + `STATS`, snomasks (`+s`), `DIE`/`RESTART`, and a `UNINVITE`.
reload-safe **`REHASH`** (keeps the running config if the file can't be read, - Bans / excepts / invex, ban **redirect** (`+b mask$#chan`), and matching +
and announces the reload to every connected user). acting **extbans** (below).
- **IRCv3**: `CAP` negotiation, `server-time`, `message-tags` + **`msgid`**,
`multi-prefix`, `away-notify`, `account-notify`, `extended-join`, `chghost`, ### Messaging
`userhost-in-names`, `echo-message`, `invite-notify`, `setname`, - `PRIVMSG`/`NOTICE`/`TAGMSG`, CTCP handling, `echo-message`, per-message `msgid`,
`extended-monitor`, `SASL` (PLAIN, relayed to services), `WATCH`/`MONITOR`, `server-time`, `account-tag`.
`SILENCE`, and `ACCEPT` + user `+g` **callerid** (only accepted users may PM you). - **CHATHISTORY** (`draft/chathistory`: `LATEST`/`BEFORE`/`AFTER`/`AROUND`/`BETWEEN`
- **Reverse-DNS on connect**: the classic `*** Looking up your hostname...` /`TARGETS`) with the `+H` join backlog, **REDACT** (`draft/message-redaction`),
connection notices, backed by a *real* forward-confirmed PTR resolver written **MARKREAD** (`draft/read-marker`), and **multiline** (`draft/multiline`).
from scratch over UDP (no DNS crate) — resolves clients to hostnames, off the - **RELAYMSG** (`draft/relaymsg`) — bridge messages under a spoofed relay nick.
core thread, fail-safe to the IP. Configurable (`resolve_hosts`,
`use_resolved_host`). ### The full mode set
- **TLS** (openssl) with `sslinfo`; keyed-SHA-256 host **cloaking** (`+x`); - **Prefixes** `+qaohv` (`~&@%+`), plus an optional network-staff prefix `+y` (`!`)
**services-ready accounts** (`SVSLOGIN`/`SVSLOGOUT`, account-gated `+r/+R/+M`) above owner (`operprefix` / `OJOIN`).
— the ircd is *ready* for an external services package, it is not one itself. - **List modes** `+b` ban, `+e` except, `+I` invex, `+g` word filter, `+X`
- **Server-to-server linking**: handshake, UID/FJOIN netburst, cross-server exemptchanops, `+w` auto-status.
users and channels, nick-collision handling, netsplit. - **Parametered** `+k` key, `+l` limit, `+f` message-flood, `+j` join-flood, `+F`
- An **antimixedutf8** anti-spam module (blocks mixed-script look-alike spam). nick-flood, `+L` redirect-when-full, `+H` history, `+B` anticaps, `+J`
kick-no-rejoin, `+d` delay-msg, `+K` no-repeat.
- **Flags** `+imnpstz`, `+O` oper-only, `+N` no-nick, `+C` no-CTCP, `+T` no-notice,
`+c` no-colour, `+S` strip-colour, `+R` reg-only, `+M` reg-moderated, `+G` censor,
`+u` auditorium, `+Q` no-kicks, `+A` allow-invite, `+P` permanent, `+U`
op-moderated, `+D` delay-join.
- **User modes** `+i w o x s g` plus `+B` bot, `+D` deaf, `+I` hide-chans, `+H`
hide-oper, `+r` logged-in, `+R` reg-only-PM, `+z` TLS-only-PM, `+W` show-whois,
`+h` helpop, `+c` common-chans-only.
- **Extbans** — matching `g:` security-group, `y:` reputation, `r:` realname,
`j:` in-channel, `s:` server, `G:` country, `b:` other-channel's ban list; acting
`m:` mute, `c:` no-colour, `n:` no-nick.
### Operators
- `OPER`/`KILL`/`WALLOPS`/`GLOBOPS`, snomasks (`+s`) with an optional `chanlog`.
- Overrides: `SAJOIN`/`SAPART`/`SANICK`/`SAMODE`/`SATOPIC`/`SAKICK`/`SAQUIT`,
`CHGHOST`/`CHGIDENT`/`CHGNAME`/`SETHOST`/`SETIDENT`/`SETIDLE`, `NICKLOCK`/
`NICKUNLOCK`, `SWHOIS`, `CHECK`, `CLEARCHAN`, `ALLTIME`, `OPERMOTD`, `VHOST`,
`TITLE`, oper-override-with-accountability, `operprefix`/`OJOIN`, `hidelist`/
`hidemode`.
- **X-lines** `KLINE`/`GLINE`/`ZLINE`/`ELINE`/`SHUN`/`QLINE`/`CBAN`, persisted to
disk and restored on boot; `STATS`; on-demand `CONNECT`; `DIE`/`RESTART`; and a
reload-safe **`REHASH`** (keeps the running config if the file can't be read).
### IRCv3 capabilities
`sasl`, `server-time`, `message-tags` (+ `msgid`), `multi-prefix`, `away-notify`,
`account-notify`, `extended-join`, `chghost`, `userhost-in-names`, `echo-message`,
`invite-notify`, `setname`, `extended-monitor`, `account-tag`, `standard-replies`,
`labeled-response`, `batch`, `cap-notify`, and drafts `chathistory`,
`message-redaction`, `pre-away`, `metadata-2`, `multiline`, `account-registration`,
`json-log`, `extended-isupport`, `relaymsg` — plus `WATCH`/`MONITOR`/`SILENCE` and
`ACCEPT` (+ `+g` callerid).
### Services interface & accounts
- **SASL** PLAIN + EXTERNAL (TLS client-cert), relayed to an external services
server over S2S.
- `SVSNICK`/`SVSJOIN`/`SVSPART`/`SVSMODE`/`SVSLOGIN`/`SVSLOGOUT`, `ENCAP`,
`METADATA`; account-gated modes (`+r`/`+R`/`+M`). The ircd is *ready* for an
external services package — it is not one itself.
- Optional ircd-side account **registration** (`REGISTER`/`VERIFY` over an HTTP
API), CAPTCHA gating, and `EXTJWT` / file-host tokens.
### Server-to-server linking
Handshake, `UID`/`FJOIN` netburst, cross-server users and channels, multi-hop
routing, nick-collision handling, and clean netsplit.
### Anti-abuse
`antimixedutf8` (look-alike script spam), `antirandom` (gibberish nicks), message
flood (`+f`) + global rate limits, `connflood`/`connectban` (connection floods),
`blockamsg`, `securelist`, `dnsbl`, CAPTCHA / challenge gating, `solvemsg`
(arithmetic gate), `dccallow` (DCC filtering), `conn_waitpong`, `autodrop`.
### GeoIP
A **native MaxMind `.mmdb` reader** (no crate): the `G:<cc>` geoban extban, a
`GEOIP` oper command, and a country line in WHOIS.
### TLS, cloaking, transports
- **TLS** (openssl) with `SSLINFO`, cert fingerprints, and `+z` secure-only.
- Keyed-SHA-256 host **cloaking** (`+x`).
- A **native WebSocket transport** (`ws://` and `wss://`) with real-IP / scheme
behind a trusted proxy.
- Reverse-DNS on connect via a from-scratch forward-confirmed PTR resolver over
UDP (no DNS crate), off the core thread, fail-safe to the IP.
### JSON-RPC control plane
A native inbound HTTP server + JSON-RPC interface (no `serde`, no `hyper`) with
token auth and ~30 methods across core/user/channel/server/stats/ban/message.
### Native building blocks
Everything is hand-rolled to stay dependency-light and `unsafe`-free: the DNS
resolver, JWT (HS256), JSON scan/build, the mmdb reader, an HTTP client, and
password hashing (`md5`/`sha1`/`sha256`/`sha512`/`pbkdf2`).
### Everything is configurable
Limits, thresholds, durations, timeouts and list sizes are all config keys — the
literal in code is only the default; nothing operational is hardcoded.
## Originality ## Originality