IRCd daemon written in Rust
Find a file
2026-08-24 20:38:58 +00:00
deploy deploy: Let's Encrypt deploy-hook — installs the renewed cert into echoircd's tls/ (readable by the daemon user) and restarts only when it changed; symlink into certbot renewal-hooks 2026-08-15 01:12:37 +00:00
docs docs: document the block config format + mkpasswd/checkconfig/rehash CLIs in README and configuration.md 2026-08-24 19:13:45 +00:00
proptest-regressions message: parse on space (0x20) only per RFC — trim_start() also ate tabs, so a param containing a tab (e.g. a trailing ':\t') didn't round-trip through to_wire/parse; the parser fuzz proptest found it. trim_start_matches(' ') makes tabs ordinary param content; regression case pinned 2026-08-19 01:41:22 +00:00
scripts perf: mimalloc global allocator + aHash maps + memchr line framer + LTO/codegen-units=1 — ~29% faster channel fanout; and drop the bogus openssl+mio dependency whitelist from the guard (any perf crate is welcome now) 2026-08-18 19:45:33 +00:00
src tls: openssl backend offers TLS 1.3 via mozilla_intermediate_v5 (was capped at 1.2) 2026-08-24 20:38:58 +00:00
tests tls: add opt-in pure-Rust rustls backend behind the TlsBackend trait (tls_backend = rustls; default stays openssl) — TLS1.3, CertFP via handshake-sig verify, SNI, REHASH reload; bump integration timeouts for loaded-host robustness 2026-08-18 20:20:21 +00:00
.gitignore rehash: 'echoircd rehash' CLI + SIGHUP reload the running config in place via a pidfile 2026-08-23 02:10:41 +00:00
build.rs version: show echoircd-<major> (5) in 002/004/351 and enrich RPL_VERSION with build/toolchain provenance 2026-08-23 01:24:45 +00:00
Cargo.toml rehash: 'echoircd rehash' CLI + SIGHUP reload the running config in place via a pidfile 2026-08-23 02:10:41 +00:00
echoircd.conf.bak-20260816-114429 remove some stupid text. 2026-08-18 19:26:22 +00:00
echoircd.conf.example config: block-format example documenting every option; cloak/uline block fields + example parse guard 2026-08-23 12:28:19 +00:00
echoircd.conf.permchannels remove some stupid text. 2026-08-18 19:26:22 +00:00
README.md docs: add Community section (irc.devtronic.pro #echoiRCd support channel) to README 2026-08-24 19:47:06 +00:00

echoIRCd

A memory-safe IRCv3 server written in Rust.

License: MIT Language: Rust IRCv3

About

echoIRCd is a full IRC + IRCv3 server. A single lock-free core thread owns all state; a pool of epoll reactor threads (one per core) drives the connections around it — TLS crypto and all — with no async runtime. It ships 100+ commands, the complete channel & user mode set, 30+ IRCv3 capabilities, server-to-server linking, a services interface, TLS, WebSocket, GeoIP, layered anti-spam, a Prometheus metrics endpoint, and a JSON-RPC control plane — with every operational limit exposed as a config key.

Features

  • Full IRC core — registration, channels (JOIN/PART/KICK/INVITE/ KNOCK/CYCLE/REMOVE/TOPIC), messaging (PRIVMSG/NOTICE/TAGMSG, CTCP), and info (WHO/WHOIS/WHOWAS/LIST/STATS/MAP/LUSERS/MOTD).
  • Complete mode set — prefixes qaohv (plus a network-staff ! prefix), list modes beIgXw, keyed/limit/flood/redirect/history/anticaps params, the full flag set, all the standard user modes, and matching + acting extbans.
  • IRCv3 — message-tags (+msgid), server-time, labeled-response, batch, echo-message, account-tag, CHATHISTORY, multiline, message-redaction, read-marker, relaymsg, SASL, standard-replies, and WATCH/MONITOR/ SILENCE/caller-id.
  • OperatorsOPER/KILL/WALLOPS/GLOBOPS, the SA*/CHG*/SET* override toolbox, x-lines (K/G/Z/E/SHUN/QLINE/CBAN/RLINE) persisted to disk, staff prefix (operprefix/OJOIN), oper levels, rank-gated hidelist/hidemode, and a reload-safe REHASH.
  • Services & accounts — SASL PLAIN/EXTERNAL relayed over the link, the SVS* / ENCAP / METADATA interface, account-gated modes, and optional ircd-side account registration (REGISTER/VERIFY).
  • Server-to-server linkingUID/FJOIN netburst, cross-server users and channels, multi-hop routing, TS-based nick-collision handling, and clean netsplit/rejoin.
  • Security & anti-spam — TLS with client-cert fingerprints, keyed host cloaking, DNSBL, per-IP connection/message flood limits, mixed-script & random (drone) detection, CAPTCHA / PONG-cookie / arithmetic gates, and DCC filtering.
  • Transports — plaintext, TLS (OpenSSL or rustls backend), a native WebSocket layer (ws:// / wss://), and the PROXY protocol (v1/v2) behind a load balancer.
  • GeoIP — a MaxMind .mmdb reader with a G:<cc> geoban, GEOIP command, and a WHOIS country line.
  • Control & observability — a token-authenticated JSON-RPC plane over HTTP, and an optional OpenMetrics/Prometheus endpoint.

Quick start

git clone https://git.devtronic.pro/fedserv/echoIRCd
cd echoIRCd
cargo build --release
cp echoircd.conf.example echoircd.conf     # edit: servername, cloak_key, TLS paths
printf '%s' 'my-oper-pass' | ./target/release/echoircd mkpasswd   # → bcrypt hash for the oper block
./target/release/echoircd                  # start (reads ./echoircd.conf)

Then point a client at it: /server 127.0.0.1 6667 (or 6697 for TLS once a certificate is configured).

Documentation

The full manual lives in docs/:

Configuration

Configuration is a single file (default ./echoircd.conf) in a brace/block format — or the original flat key = value form; both are accepted and the parser auto-detects which one a file uses:

server { name "irc.example.net"; network "ExampleNet"; }
listen { ip "*"; port 6697; tls yes; }
oper   { name "admin"; password "$2b$…"; type netadmin; }

See echoircd.conf.example for the full, annotated set of keys — every operational limit is a config key with a built-in default, and most settings apply on REHASH without a restart. Three helper subcommands round it out:

  • echoircd mkpasswd — read a password from stdin, print a bcrypt hash for an oper block.
  • echoircd checkconfig [file] — parse a config and dump its keys, to validate one or diff two.
  • echoircd rehash — signal the running server to reload its config in place.

Your live echoircd.conf is gitignored — it holds secrets (oper password, cloak key, link password), so never commit it. Generate a TLS certificate into tls/ with the one-liner in the example config.

Architecture

A single core thread owns every User and Channel, so command and module code is ordinary single-threaded logic over &mut Server — no Arc<Mutex<…>> anywhere. The I/O edge feeds it events over channels:

  • A pool of mio epoll reactors drives client sockets — an acceptor round-robins each connection onto a worker (one per core by default), and each worker frames lines and runs TLS handshakes and record crypto non-blocking in-thread. Socket work and crypto spread across cores while the state core stays single-threaded and lock-free. (Proxied TLS and server links keep a thread each; there are few of them.)
  • Resilience is built in. Slow work (KDF hashing, DNS, disk snapshots) runs off the core so a flood can't freeze it; each event and each connection's I/O is panic-isolated so one bad client can't crash the server; a watchdog flags a stuck core; and half-open/stalled connections are reaped on a timer.

Why a raw reactor and not async? IRC is one large shared mutable graph, and almost every command mutates it and then broadcasts. With one thread owning all of it, handlers are plain synchronous 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 for parallelism the workload can't use. mio is the same readiness layer async runtimes build on, so you keep the scaling without the runtime. What does parallelize — the socket syscalls and TLS crypto — runs in the reactor pool; scaling past one machine is done by linking servers, not threading one harder.

Memory safety is structural: Uid handles instead of raw pointers, an Extensible typemap instead of void* module data (freed on drop), and compiled-in trait objects instead of a fragile plugin ABI. Full design notes: docs/architecture.md.

Extending

Three small extension points, each one file + one table line — full reference and a tutorial in docs/api/:

  • Commands (src/command.rs, src/coremods/) — a handler with name, min_params, before_reg, handle(&mut Server, uid, params).
  • Modes (src/mode.rs) — channel/user modes as ChanMode / UserMode handler objects; adding one never touches the parser.
  • Modules (src/module.rs, src/modules/) — lifecycle hooks; pre-hooks can Deny a register/command/message, notify-hooks fire after.

Community

echoIRCd's support network runs on echoIRCd itself — come say hi:

  • Serverirc.devtronic.pro (TLS 6697, plaintext 6667)
  • #echoiRCd — the official support & development channel
  • #devs — general developer chat

Quick connect: ircs://irc.devtronic.pro:6697/%23echoiRCd

License

echoIRCd is released under the MIT License.