feat: initial IRC bouncer implementation
Async Python IRC bouncer with SOCKS5 proxy support, multi-network connections, password auth, and persistent SQLite backlog with replay. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
53
docs/CHEATSHEET.md
Normal file
53
docs/CHEATSHEET.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# Cheatsheet
|
||||
|
||||
## Commands
|
||||
|
||||
```bash
|
||||
bouncer -c config/bouncer.toml # Start with config
|
||||
bouncer -c config/bouncer.toml -v # Start with debug output
|
||||
bouncer --version # Show version
|
||||
bouncer --help # Show help
|
||||
```
|
||||
|
||||
## Development
|
||||
|
||||
```bash
|
||||
make dev # Install with dev deps
|
||||
make test # Run pytest
|
||||
make lint # Run ruff
|
||||
make fmt # Format with black + ruff
|
||||
make run # Run with default config
|
||||
make clean # Remove .venv and build artifacts
|
||||
```
|
||||
|
||||
## Client Connection
|
||||
|
||||
```
|
||||
PASS <network>:<password> # Authenticate + select network
|
||||
PASS <password> # Authenticate, use first network
|
||||
```
|
||||
|
||||
## Config Structure
|
||||
|
||||
```toml
|
||||
[bouncer] # Listener settings
|
||||
bind / port / password
|
||||
[bouncer.backlog] # Backlog settings
|
||||
max_messages / replay_on_connect
|
||||
|
||||
[proxy] # SOCKS5 proxy
|
||||
host / port
|
||||
|
||||
[networks.<name>] # IRC server (repeatable)
|
||||
host / port / tls
|
||||
nick / user / realname
|
||||
channels / autojoin / password
|
||||
```
|
||||
|
||||
## Files
|
||||
|
||||
| Path | Purpose |
|
||||
|------|---------|
|
||||
| `config/bouncer.toml` | Active configuration |
|
||||
| `config/bouncer.db` | SQLite backlog database |
|
||||
| `config/bouncer.example.toml` | Example config template |
|
||||
75
docs/DEBUG.md
Normal file
75
docs/DEBUG.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# Debugging
|
||||
|
||||
## Verbose Mode
|
||||
|
||||
```bash
|
||||
bouncer -c config/bouncer.toml -v
|
||||
```
|
||||
|
||||
Debug logging shows:
|
||||
- SOCKS5 proxy connection attempts
|
||||
- IRC server registration
|
||||
- Client connect/disconnect events
|
||||
- Message routing
|
||||
- Backlog replay counts
|
||||
|
||||
## Common Issues
|
||||
|
||||
### "config not found"
|
||||
|
||||
Ensure the config path is correct:
|
||||
|
||||
```bash
|
||||
bouncer -c /full/path/to/bouncer.toml
|
||||
```
|
||||
|
||||
### Connection refused (SOCKS5 proxy)
|
||||
|
||||
Verify the proxy is running:
|
||||
|
||||
```bash
|
||||
ss -tlnp | grep 1080
|
||||
```
|
||||
|
||||
### Connection timeout to IRC server
|
||||
|
||||
Check the SOCKS5 proxy can reach the IRC server:
|
||||
|
||||
```bash
|
||||
curl --socks5 127.0.0.1:1080 -v telnet://irc.libera.chat:6697
|
||||
```
|
||||
|
||||
### Nick already in use
|
||||
|
||||
The bouncer appends `_` to the nick and retries. Check logs for:
|
||||
|
||||
```
|
||||
WARNING bouncer.network [libera] nick in use, trying mynick_
|
||||
```
|
||||
|
||||
### TLS certificate errors
|
||||
|
||||
If connecting to a server with a self-signed cert, this is currently not supported. All TLS connections use the system CA store.
|
||||
|
||||
## Inspecting the Backlog Database
|
||||
|
||||
```bash
|
||||
sqlite3 config/bouncer.db
|
||||
|
||||
-- Recent messages
|
||||
SELECT * FROM messages ORDER BY id DESC LIMIT 20;
|
||||
|
||||
-- Messages per network
|
||||
SELECT network, COUNT(*) FROM messages GROUP BY network;
|
||||
|
||||
-- Client state
|
||||
SELECT * FROM client_state;
|
||||
```
|
||||
|
||||
## Log Format
|
||||
|
||||
```
|
||||
HH:MM:SS LEVEL module message
|
||||
```
|
||||
|
||||
Levels: `DEBUG`, `INFO`, `WARNING`, `ERROR`
|
||||
42
docs/INSTALL.md
Normal file
42
docs/INSTALL.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# Installation
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Python 3.10+
|
||||
- SOCKS5 proxy running on `127.0.0.1:1080`
|
||||
|
||||
## Setup
|
||||
|
||||
```bash
|
||||
cd ~/git/bouncer
|
||||
make dev
|
||||
```
|
||||
|
||||
This creates `.venv/`, installs dependencies, and registers the `bouncer` command.
|
||||
|
||||
## Verify
|
||||
|
||||
```bash
|
||||
bouncer --version
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
```bash
|
||||
cp config/bouncer.example.toml config/bouncer.toml
|
||||
```
|
||||
|
||||
Edit `config/bouncer.toml` with your network details. At minimum, set:
|
||||
|
||||
- `bouncer.password` -- client authentication password
|
||||
- `networks.<name>.host` -- IRC server hostname
|
||||
- `networks.<name>.nick` -- your IRC nickname
|
||||
- `networks.<name>.channels` -- channels to auto-join
|
||||
|
||||
## Symlink
|
||||
|
||||
The `make dev` editable install registers `bouncer` in `.venv/bin/`. To make it available system-wide:
|
||||
|
||||
```bash
|
||||
ln -sf ~/git/bouncer/.venv/bin/bouncer ~/.local/bin/bouncer
|
||||
```
|
||||
77
docs/USAGE.md
Normal file
77
docs/USAGE.md
Normal file
@@ -0,0 +1,77 @@
|
||||
# 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 |
|
||||
|
||||
## 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 | `networkname:yourpassword` |
|
||||
|
||||
### Password Format
|
||||
|
||||
```
|
||||
PASS <network>:<password>
|
||||
```
|
||||
|
||||
- `network` -- matches a `[networks.NAME]` section in config
|
||||
- `password` -- the `bouncer.password` value from config
|
||||
|
||||
If you omit the network prefix (`PASS yourpassword`), the first configured network is used.
|
||||
|
||||
### Client Examples
|
||||
|
||||
**irssi:**
|
||||
```
|
||||
/connect -password libera:mypassword 127.0.0.1 6667
|
||||
```
|
||||
|
||||
**weechat:**
|
||||
```
|
||||
/server add bouncer 127.0.0.1/6667 -password=libera:mypassword
|
||||
/connect bouncer
|
||||
```
|
||||
|
||||
**hexchat:**
|
||||
Set server password to `libera:mypassword` in the network settings.
|
||||
|
||||
## Multiple Networks
|
||||
|
||||
Define multiple `[networks.*]` sections in the config. Connect with different passwords to access each:
|
||||
|
||||
```
|
||||
PASS libera:mypassword # connects to libera
|
||||
PASS oftc:mypassword # connects to oftc
|
||||
```
|
||||
|
||||
Multiple clients can attach to the same network simultaneously.
|
||||
|
||||
## Backlog
|
||||
|
||||
Messages are stored in `bouncer.db` (SQLite) next to the config file. When you reconnect, missed messages are automatically replayed.
|
||||
|
||||
Configure backlog in `bouncer.toml`:
|
||||
|
||||
```toml
|
||||
[bouncer.backlog]
|
||||
max_messages = 10000 # per network, 0 = unlimited
|
||||
replay_on_connect = true # set false to disable replay
|
||||
```
|
||||
|
||||
## Stopping
|
||||
|
||||
Press `Ctrl+C` or send `SIGTERM`. The bouncer shuts down gracefully.
|
||||
Reference in New Issue
Block a user