docs: add a full docs/ manual (architecture, configuration, modes, operators, linking, ircv3, anti-abuse, deployment, building) and refresh the README for the reactor pool + TLS-in-reactor + resilience

This commit is contained in:
Jean Chevronnet 2026-08-13 01:00:39 +00:00
parent d8a963d0f9
commit bd054f7721
11 changed files with 1182 additions and 11 deletions

111
docs/linking.md Normal file
View file

@ -0,0 +1,111 @@
# Server linking & services
Multiple echoIRCd servers form one network by **linking**. Users and channels are
shared across all servers, and a services package (accounts, nick/channel
registration) attaches as just another linked server.
## Setting up a link
Each server needs a unique **SID** (3 characters, first a digit) and a link
listener:
```text
sid = 0AA
bind_server = 0.0.0.0:7000
```
Then declare each peer, with a shared-secret password on both sides:
```text
# link = <name> <ip> <port> <password> [autoconnect]
link = peer.example.net 203.0.113.5 7000 SHARED_LINK_SECRET autoconnect
```
`autoconnect` dials the peer on startup; otherwise an oper runs
`/CONNECT peer.example.net`. Link connections use the thread-per-connection I/O
model (there are only a handful of them) — see [architecture](architecture.md).
## The netburst
When two servers link, they exchange a **burst** that synchronizes state:
- **Servers** — every server the peer knows, so the topology is complete.
- **Users** — each as a `UID` introduction carrying nick, ident, host, real name,
modes, account, and cloak.
- **Channels** — each as an `FJOIN` carrying the member list with their status
prefixes, plus the channel's modes, topic, and ban lists.
After the burst both sides have identical state and stay in sync by propagating
every subsequent change.
## Routing, collisions & netsplits
- **Multi-hop routing** — a message for a remote user is forwarded hop-by-hop
toward the server that owns them; the ircd tracks which direction each SID lies.
- **Nick collisions** — if the same nick appears on both sides of a new link, the
collision is resolved deterministically (by sign-on time / UID) so the network
converges to one owner.
- **Netsplits** — when a link drops, every user and channel behind it is cleanly
removed locally and re-introduced on reconnect via a fresh burst.
## Services & accounts
echoIRCd stays a **pure ircd**: it does not implement NickServ/ChanServ itself.
Instead it carries the *interface* a services package uses, and services run as a
linked server. That interface is:
### SASL
Client authentication is relayed to the configured services server:
```text
sasl_server = services.example.net
```
- **PLAIN** — the client's credentials are forwarded to services over the link.
- **EXTERNAL** — the client must be on TLS with a client certificate; its
fingerprint (CertFP) is forwarded, so services can match it to an account with
no password.
With `sasl_server` unset, SASL is disabled.
### Account state & gated modes
A logged-in user carries an **account** name (advertised via `account-tag` /
`extended-join` / WHOIS, and user mode `+r`). Modes and channel policies can be
gated on being logged in — e.g. channel `+R` (registered users only may join),
`+M` (only registered may speak), and the `g:<group>` / account-based extbans.
### The services command set
Services drive the network through the `SVS*` family and generic transports:
- `SVSNICK`, `SVSJOIN`, `SVSPART`, `SVSMODE` — act on a user's nick/membership/modes.
- `SVSLOGIN` / `SVSLOGOUT` — set or clear a user's account.
- `SVSHOLD`, `SVSTOPIC`, `SVSOPER`, `SVSCMODE` — hold a nick, set a topic, grant
oper, set channel modes with service authority.
- `ENCAP` — an encapsulated command routed to a specific server.
- `METADATA` — attach arbitrary key/value data to users and channels.
### Optional ircd-side registration
Independently of a services package, the server can offer IRCv3
`draft/account-registration` directly: a client uses `REGISTER` / `VERIFY` to
create and confirm an account.
## Web gateways (WEBIRC)
A trusted web-based client gateway (the browser-to-IRC kind) can declare the real
client's host and IP so users don't all appear to come from the gateway:
```text
# webirc = <password> [gateway-name] [ip-mask]
webirc = WEBIRC_SECRET mygateway 203.0.113.9
```
The `ip-mask` restricts which source IP may use the password — always set it. The
gateway sends a `WEBIRC` line at connect with the password and the real client
details.
> For browser clients connecting *directly* (no gateway), use the native
> [WebSocket transport](configuration.md#transports) instead.