Users can now inspect bouncer state and manage it from their IRC client by sending PRIVMSG to *bouncer (or bouncer). Supported commands: HELP, STATUS, INFO, UPTIME, NETWORKS, CREDS. Responses arrive as NOTICE messages. All commands are case-insensitive. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
6.5 KiB
Usage
Starting the Bouncer
bouncer -c config/bouncer.toml -v
| Flag | Description |
|---|---|
-c, --config PATH |
Config file (default: config/bouncer.toml) |
-v, --verbose |
Debug logging |
--version |
Show version |
Connection Lifecycle
The bouncer goes through several states when connecting to an IRC server:
DISCONNECTED -> CONNECTING -> REGISTERING -> PROBATION -> READY
| | |
`--------------+--------------'
(failure = reconnect)
1. Stealth Registration
On connect, the bouncer registers with a random identity:
- Nick: pronounceable markov-generated word (e.g.,
heliagu,crewo,midon) - User/Ident: random pronounceable word
- Realname: random capitalized word
No fixed prefix or pattern -- each attempt looks like a different person.
2. Probation (15 seconds)
After registration succeeds (001 RPL_WELCOME), the bouncer enters a 15-second probation window. During this time it watches for:
ERRORmessages (K-line, ban)- Server closing the connection
If the connection drops during probation, the bouncer reconnects with a fresh random identity and tries again.
3. Ready
Once probation passes without incident:
- Bouncer switches to your configured nick (
NICK mynick) - Joins configured channels (if
autojoin = true) - Begins relaying messages to/from connected clients
4. Reconnection
On any disconnection, the bouncer reconnects with exponential backoff:
| Attempt | Delay |
|---|---|
| 1 | 5s |
| 2 | 10s |
| 3 | 30s |
| 4 | 60s |
| 5 | 120s |
| 6+ | 300s |
Each reconnection uses a fresh random identity.
DNS Resolution
Hostnames are resolved locally before being passed to the SOCKS5 proxy. If a hostname resolves to multiple IPs, the bouncer tries each one until a connection succeeds. This handles proxies that don't support remote DNS and avoids IPs that are unreachable through the proxy.
Connecting with an IRC Client
Configure your IRC client to connect to the bouncer:
| Setting | Value |
|---|---|
| Server | 127.0.0.1 |
| Port | 6667 (or as configured) |
| Password | yourpassword |
Password Format
PASS <password>
The password is the bouncer.password value from config. A single connection
automatically attaches to all configured networks.
Client Examples
irssi:
/connect -password mypassword 127.0.0.1 6667
weechat:
/server add bouncer 127.0.0.1/6667 -password=mypassword
/connect bouncer
hexchat:
Set server password to mypassword in the network settings.
Multi-Network Namespacing
All configured networks are multiplexed onto a single client connection. Channels
and nicks carry a /network suffix so you can tell which network they belong to:
Client sees: Server wire:
#libera/libera <-> #libera (on libera network)
#debian/oftc <-> #debian (on oftc network)
user123/libera <-> user123 (on libera network)
Rules
- Channels:
#channel/networkin client,#channelon wire - Foreign nicks:
nick/networkin client,nickon wire - Own nicks: shown without suffix (prevents client confusion)
- Sending messages: include the
/networksuffix in the target
/msg #libera/libera hello -> sends "hello" to #libera on libera network
/join #test/oftc -> joins #test on oftc network
/msg user123/libera hi -> private message to user123 on libera
Comma-Separated JOIN/PART
Targets can span networks:
/join #a/libera,#b/oftc -> joins #a on libera AND #b on oftc
Multiple clients can attach simultaneously. All receive the same namespaced messages in real time.
What Clients Receive on Connect
When a client authenticates:
- Backlog replay -- missed messages (namespaced) from all networks
- Synthetic welcome -- 001-004 numeric replies listing all networks
- Channel state -- synthetic JOIN, TOPIC, and NAMES for every joined
channel across all networks (all namespaced with
/networksuffix)
Backlog
Messages are stored in bouncer.db (SQLite) next to the config file. When
you reconnect, missed messages are automatically replayed.
Configure in bouncer.toml:
[bouncer.backlog]
max_messages = 10000 # per network, 0 = unlimited
replay_on_connect = true # set false to disable replay
Stored commands: PRIVMSG, NOTICE, TOPIC, KICK, MODE.
Configuration Reference
[bouncer]
bind = "127.0.0.1" # listen address
port = 6667 # listen port
password = "changeme" # client authentication password
[bouncer.backlog]
max_messages = 10000 # per network, 0 = unlimited
replay_on_connect = true # replay missed messages on client connect
[proxy]
host = "127.0.0.1" # SOCKS5 proxy address
port = 1080 # SOCKS5 proxy port
[networks.libera]
host = "irc.libera.chat" # IRC server hostname
port = 6697 # server port (default: 6697 if tls, 6667 otherwise)
tls = true # use TLS for server connection
nick = "mynick" # desired IRC nick (set after probation)
channels = ["#test"] # channels to join (after probation)
autojoin = true # auto-join channels on ready (default: true)
password = "" # IRC server password (optional, for PASS command)
Bouncer Commands
Send a PRIVMSG to *bouncer (or bouncer) from your IRC client to inspect
and control the bouncer. All commands are case-insensitive.
/msg *bouncer HELP
/msg *bouncer STATUS
/msg *bouncer INFO libera
/msg *bouncer UPTIME
/msg *bouncer NETWORKS
/msg *bouncer CREDS
/msg *bouncer CREDS libera
| Command | Description |
|---|---|
HELP |
List available commands |
STATUS |
Overview: state, nick, host per network |
INFO <network> |
Detailed info for one network (state, server, channels, creds) |
UPTIME |
Bouncer uptime since process start |
NETWORKS |
List all configured networks with state |
CREDS [network] |
NickServ credential status (all or per-network) |
Responses arrive as NOTICE messages from *bouncer.
Example Output
[STATUS]
libera ready fabesune user/fabesune
oftc ready ceraty cloaked.user
hackint connecting (attempt 3)
quakenet ready spetyo --
Stopping
Press Ctrl+C or send SIGTERM. The bouncer shuts down gracefully, closing
all network connections and the backlog database.