Atheme services protocol module for leveva#
This directory ships leveva.c, an atheme protocol
module that lets an atheme services package (NickServ, ChanServ, OperServ,
SaslServ, …) link to a leveva server and operate over it.
Why a custom module#
leveva speaks the IRCnet 2.11 server protocol on the wire — a PASS/SERVER
handshake, SIDs/UIDs as routing prefixes, and UNICK/NJOIN/SAVE/EOB for the
burst — while carrying a small set of charybdis/TS6-style extensions over
ENCAP (account login SU, SASL relay, SVSLOGIN, CHGHOST, K/D/X-line and
RESV propagation, an ENCAP * CAPAB feature list). No stock atheme module is an
exact fit, so this one is a hybrid:
- the handshake / burst / introduction handlers are adapted from atheme's
protocol/ircnet(which already speaks the IRCnet-2.11UNICK/NJOIN/EOBskeleton); - the account / SASL / ban grafts are adapted from
protocol/ts6-generic, because theENCAPwire formats line up with leveva exactly (verified againstdocs/s2s.mdandleveva/src/s2s/).
It is standalone — it does not depend on ts6-generic — because leveva is
not TS6 (no SVINFO, introduction is UNICK not EUID, membership is NJOIN
not SJOIN). UID generation is delegated to protocol/base36uid, whose counter
alphabet (A..Z then 0..9, carrying) is byte-identical to leveva's, so it
mints leveva-compatible 9-character UIDs (SID(4) + 5).
No change to leveva itself is required: every wire format already matches.
Building#
Drop the module into an atheme source tree and build it:
cp leveva.c /path/to/atheme/modules/protocol/leveva.c
# add `leveva` to the SRCS list in modules/protocol/Makefile
make -C /path/to/atheme/modules/protocol leveva.so
Or compile it standalone against atheme's headers (handy for a quick check):
gcc -fPIC -DPIC -shared -Wall \
-I/path/to/atheme/include \
-I/path/to/atheme/libmowgli-2/src/libmowgli \
-o leveva.so leveva.c
Install leveva.so alongside atheme's other protocol modules
(<prefix>/modules/protocol/).
Configuring the link#
The two ends must agree on a port and a cross-matched pair of passwords.
leveva side (see leveva.kdl.example) — a dedicated
server-only listener and a connect{} block named for the services server:
listen { port 6670; server-only #true }
connect "services.test" {
host "127.0.0.1"; port 0 // port 0 = accept-only (no outbound dial)
accept-password "linkpw" // == atheme send_password
send-password "ourpw" // == atheme receive_password
}
atheme side (see atheme-uplink.conf.example):
loadmodule "modules/protocol/leveva";
uplink "leveva.test" { /* must equal leveva's server name */
host = "127.0.0.1";
send_password = "linkpw"; /* == leveva accept-password */
receive_password = "ourpw"; /* == leveva send-password */
port = 6670; /* the server-only listener */
};
serverinfo {
name = "services.test"; /* must equal the connect{} block name */
numeric = "00A"; /* 1-3 chars; base36uid pads the SID to 4 */
};
Password rule: atheme send_password == leveva accept-password, and atheme
receive_password == leveva send-password.
What works#
- Linking + burst — the full handshake, leveva's burst parsed (servers,
users, channels), atheme's services introduced via
UNICK,EOB/EOBACK. - NickServ — register / identify; the login propagates to leveva as
ENCAP * SU, so leveva shows the services account (WHOIS, theaccount-notify/account-tag/extended-joinIRCv3 surface). - ChanServ — channel ops via
NJOIN/MODE/KICK/TOPIC. The full rank set is modelled: official-join+Y/!(as atheme's per-userCSTATUS_IMMUNE, carrying leveva's absolute kick-immunity), owner+q/~, admin+a/&, op+o/@, halfop+h/%, voice+v/+. - OperServ — AKILL →
ENCAP * KLINE, plus XLINE (realname), RESV (nick / channel), DLINE (IP/CIDR), each over the matching levevaENCAPcarrier and propagated network-wide. - SaslServ — SASL (PLAIN, EXTERNAL) relayed via
ENCAP … SASL+SVSLOGIN. atheme advertisessaslin itsENCAP * CAPABso leveva routes clientAUTHENTICATEto it. - HostServ — vhost via
ENCAP * CHGHOST <newuser> <newhost>.
Limitations#
- NickServ ENFORCE falls back to KILL. leveva has no forced-nick-change
(
SVSNICK/RSFNC) or hold-nick mechanism the module can drive, so thefnc_sts/holdnick_stshooks are intentionally unset and atheme enforces a protected nick by KILL rather than by renaming to a guest nick. - Single uplink. leveva flattens topology to one direct link, so the module models one uplink; a multi-hop services mesh is out of scope.
+f/+jparams (forward target, join throttle) are accepted and validated for MLOCK but services do not deeply model their behaviour.- leveva's
ENCAPline carries IRCv3 extras (CERTFP,REDACT,CHANTS,USERTS,METADATA) that services do not need; the module ignores them (they are opaque, exactly as leveva intends for a non-participating peer).
Provenance#
Adapted from atheme's modules/protocol/{ircnet,ts6-generic,charybdis,inspircd}.c
by Midori Yasomi (lead developer of leveva). Every wire format is cited to a
leveva/src/s2s/*.rs source file in the module comments and in the design plan
at docs/superpowers/plans/2026-06-20-atheme-leveva-protocol-module.md.