# Usage ## Starting the Bouncer ```bash 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: - `ERROR` messages (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: 1. Bouncer switches to your configured nick (`NICK mynick`) 2. Joins configured channels (if `autojoin = true`) 3. 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 ``` 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/network` in client, `#channel` on wire - **Foreign nicks**: `nick/network` in client, `nick` on wire - **Own nicks**: shown without suffix (prevents client confusion) - **Sending messages**: include the `/network` suffix 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: 1. **Backlog replay** -- missed messages (namespaced) from all networks 2. **Synthetic welcome** -- 001-004 numeric replies listing all networks 3. **Channel state** -- synthetic JOIN, TOPIC, and NAMES for every joined channel across all networks (all namespaced with `/network` suffix) ## 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`: ```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 ```toml [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) ``` ## Stopping Press `Ctrl+C` or send `SIGTERM`. The bouncer shuts down gracefully, closing all network connections and the backlog database.