feat: add traditional IRC wire protocol listener (closes #89) (#94)
All checks were successful
check / check (push) Successful in 5s
All checks were successful
check / check (push) Successful in 5s
## Summary Adds a backward-compatible IRC wire protocol listener (RFC 1459/2812) that allows standard IRC clients (irssi, weechat, hexchat, etc.) to connect directly via TCP. ## Changes ### New package: `internal/ircserver/` - **`parser.go`** — IRC wire protocol message parser and formatter - **`server.go`** — TCP listener with Fx lifecycle integration - **`conn.go`** — Per-connection handler with registration flow, PING/PONG, welcome burst - **`commands.go`** — All IRC command handlers (JOIN, PART, PRIVMSG, MODE, TOPIC, KICK, WHOIS, etc.) - **`relay.go`** — Message relay goroutine that delivers queued messages to IRC clients in wire format ### Modified files - **`internal/config/config.go`** — Added `IRC_LISTEN_ADDR` environment variable - **`internal/handlers/handlers.go`** — Broker is now injected via Fx (shared with IRC server) - **`cmd/neoircd/main.go`** — Registered `broker.New`, `ircserver.New` as Fx providers - **`pkg/irc/commands.go`** — Added `CmdUser` and `CmdInvite` constants - **`README.md`** — Added IRC Protocol Listener documentation section ### Tests - Parser unit tests (table-driven, round-trip verification) - Integration tests: registration, PING/PONG, JOIN, PART, PRIVMSG (channel + DM), NICK change, duplicate nick rejection, LIST, WHOIS, QUIT, TOPIC, MODE, WHO, LUSERS, MOTD, AWAY, PASS, CAP negotiation, unknown commands, pre-registration errors - Benchmarks for parser and formatter ## Key Design Decisions - **Optional**: Listener is only started when `IRC_LISTEN_ADDR` is set - **Shared infrastructure**: Same DB, broker, and session system as HTTP API - **Full bridge**: IRC ↔ HTTP messages are interoperable - **No schema changes**: Reuses existing tables - **Broker as Fx dependency**: Extracted from handlers to be shared ## Supported Commands Connection: NICK, USER, PASS, QUIT, PING/PONG, CAP Channels: JOIN, PART, MODE, TOPIC, NAMES, LIST, KICK, INVITE Messaging: PRIVMSG, NOTICE Info: WHO, WHOIS, LUSERS, MOTD, AWAY, USERHOST Operator: OPER closes #89 Co-authored-by: user <user@Mac.lan guest wan> Co-authored-by: Jeffrey Paul <sneak@noreply.example.org> Reviewed-on: sneak/chat#94 Co-authored-by: clawbot <sneak+clawbot@sneak.cloud> Co-committed-by: clawbot <sneak+clawbot@sneak.cloud>
This commit was merged in pull request #94.
This commit is contained in:
65
README.md
65
README.md
@@ -27,6 +27,7 @@ web client as a convenience/reference implementation, but the API comes first.
|
||||
- [Federation](#federation-server-to-server)
|
||||
- [Storage](#storage)
|
||||
- [Configuration](#configuration)
|
||||
- [IRC Protocol Listener](#irc-protocol-listener)
|
||||
- [Deployment](#deployment)
|
||||
- [Client Development Guide](#client-development-guide)
|
||||
- [Rate Limiting & Abuse Prevention](#rate-limiting--abuse-prevention)
|
||||
@@ -2266,6 +2267,7 @@ directory is also loaded automatically via
|
||||
| `NEOIRC_OPER_PASSWORD` | string | `""` | Server operator (o-line) password. Both name and password must be set to enable OPER. |
|
||||
| `LOGIN_RATE_LIMIT` | float | `1` | Allowed login attempts per second per IP address. |
|
||||
| `LOGIN_RATE_BURST` | int | `5` | Maximum burst of login attempts per IP before rate limiting kicks in. |
|
||||
| `IRC_LISTEN_ADDR` | string | `:6667` | TCP address for the traditional IRC protocol listener. Set to empty string to disable. |
|
||||
| `MAINTENANCE_MODE` | bool | `false` | Maintenance mode flag (reserved) |
|
||||
|
||||
### Example `.env` file
|
||||
@@ -2282,6 +2284,69 @@ NEOIRC_HASHCASH_BITS=20
|
||||
|
||||
---
|
||||
|
||||
## IRC Protocol Listener
|
||||
|
||||
neoirc includes an optional traditional IRC wire protocol listener (RFC
|
||||
1459/2812) that allows standard IRC clients to connect directly. This enables
|
||||
backward compatibility with existing IRC clients like irssi, weechat, hexchat,
|
||||
and others.
|
||||
|
||||
### Configuration
|
||||
|
||||
The IRC listener is **enabled by default** on `:6667`. To disable it, set
|
||||
`IRC_LISTEN_ADDR` to an empty string:
|
||||
|
||||
```bash
|
||||
IRC_LISTEN_ADDR=
|
||||
```
|
||||
|
||||
### Supported Commands
|
||||
|
||||
| Category | Commands |
|
||||
|------------|------------------------------------------------------|
|
||||
| Connection | `NICK`, `USER`, `PASS`, `QUIT`, `PING`/`PONG`, `CAP` |
|
||||
| Channels | `JOIN`, `PART`, `MODE`, `TOPIC`, `NAMES`, `LIST`, `KICK`, `INVITE` |
|
||||
| Messaging | `PRIVMSG`, `NOTICE` |
|
||||
| Info | `WHO`, `WHOIS`, `LUSERS`, `MOTD`, `AWAY` |
|
||||
| Operator | `OPER` (requires `NEOIRC_OPER_NAME` and `NEOIRC_OPER_PASSWORD`) |
|
||||
|
||||
### Protocol Details
|
||||
|
||||
- **Wire format**: CR-LF delimited lines, max 512 bytes per line
|
||||
- **Connection registration**: Clients must send `NICK` and `USER` to register.
|
||||
An optional `PASS` before registration sets the session password (minimum 8
|
||||
characters).
|
||||
- **CAP negotiation**: `CAP LS` and `CAP END` are silently handled for
|
||||
compatibility with modern clients. No capabilities are advertised.
|
||||
- **Channel prefixes**: Channels must start with `#`. If omitted, it's
|
||||
automatically prepended.
|
||||
- **First joiner**: The first user to join a channel is automatically granted
|
||||
operator status (`@`).
|
||||
- **Channel modes**: `+m` (moderated), `+t` (topic lock), `+o` (operator),
|
||||
`+v` (voice)
|
||||
|
||||
### Bridge to HTTP API
|
||||
|
||||
Messages sent by IRC clients appear in channels visible to HTTP/JSON API
|
||||
clients and vice versa. The IRC listener and HTTP API share the same database,
|
||||
broker, and session infrastructure. A user connected via IRC and a user
|
||||
connected via the HTTP API can communicate in the same channels seamlessly.
|
||||
|
||||
### Docker Usage
|
||||
|
||||
To expose the IRC port in Docker (the listener is enabled by default on
|
||||
`:6667`):
|
||||
|
||||
```bash
|
||||
docker run -d \
|
||||
-p 8080:8080 \
|
||||
-p 6667:6667 \
|
||||
-v neoirc-data:/var/lib/neoirc \
|
||||
neoirc
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Deployment
|
||||
|
||||
### Docker (Recommended)
|
||||
|
||||
Reference in New Issue
Block a user