This commit is contained in:
2025-12-12 14:32:09 -03:00
commit 48f222a5d1

157
README.md Normal file
View File

@@ -0,0 +1,157 @@
# UDPGW (NapsterV framing) — `udpgw.go`
A lightweight TCP↔UDP gateway that speaks the “NapsterV” UDPGW framing:
- Listens on TCP (default `0.0.0.0:7400`).
- For each TCP client, opens **one UDP socket** (stable source port) and forwards framed payloads to UDP targets.
- Tracks a short-lived mapping so UDP replies are routed back to the correct `connID` + `X` byte.
- **IPv4 only** (UDP replies are dropped if theyre not IPv4).
## Build
Single-file build:
```bash
# Linux static-ish build (recommended)
CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o udpgw ./udpgw.go
```
Run help:
```bash
./udpgw -h
```
## Minimal RAM/CPU start command (recommended profile)
This profile is tuned to **minimize per-client kernel buffer memory** and reduce background CPU (slower map reaping), while keeping behavior safe for most traffic:
```bash
GOMAXPROCS=1 ./udpgw -listen 0.0.0.0:7400 -debug=false -write-chan 256 -udp-rbuf $((256*1024)) -udp-wbuf $((256*1024)) -map-ttl 60s -reap-every 30s
```
Notes:
- `GOMAXPROCS=1` limits Gos scheduler to one OS thread for CPU predictability.
- `-udp-rbuf/-udp-wbuf` are the biggest memory knobs because they are applied **per TCP client UDP socket**.
- If you see packet loss under load, raise `-udp-rbuf/-udp-wbuf` to `524288` (512 KiB) or `1048576` (1 MiB) first.
## How framing works
Each TCP frame is:
- `LEN` (2 bytes, little-endian)
- `PAYLOAD` (`LEN` bytes)
`PAYLOAD` format for both directions:
- `connID` (2 bytes, big-endian)
- `X` (1 byte)
- `IPv4` (4 bytes)
- `port` (2 bytes, big-endian)
- `data` (remaining bytes)
(See `readPayload()` and `buildFrame()` in the source.)
## Configuration flags
All runtime knobs are flags (defaults shown):
- `-listen 0.0.0.0:7400`
TCP listen address.
- `-max-frame 65536`
Max frame payload length (DoS protection). Frames larger than this are rejected.
- `-debug=false`
Verbose logs.
- `-hexdump 64`
When `-debug=true`, hex-dump the first N bytes of payload.
- `-write-chan 4096`
TCP write queue depth. Larger can help bursty traffic (e.g., games) but increases worst-case RAM.
- `-udp-bind ""`
Bind the per-client UDP socket to a specific local IP (optional).
- `-udp-rbuf 8388608`
UDP read buffer bytes (socket option). **Applied per TCP client**.
- `-udp-wbuf 8388608`
UDP write buffer bytes (socket option). **Applied per TCP client**.
- `-map-ttl 90s`
Destination→`connID` mapping TTL.
- `-reap-every 10s`
How often to delete expired mappings.
## Tuning guide (what affects RAM/CPU the most)
### RAM hotspots
1. **Kernel UDP buffers per TCP client**
Roughly proportional to: `udp-rbuf + udp-wbuf` *per connected client*.
Defaults are high (8 MiB + 8 MiB). If you expect many concurrent TCP clients, reduce these.
2. **TCP write queue (`-write-chan`)**
Each queued element is a `[]byte` frame. Bigger `-write-chan` allows more buffering but can grow memory.
3. **Per-client TCP reader buffer (fixed)**
The code uses `bufio.NewReaderSize(conn, 256*1024)` per client (256 KiB). This is not configurable via flags.
### CPU hotspots
1. `-debug=true` (logging)
Turn off for production.
2. Reaper frequency (`-reap-every`)
A longer interval reduces wakeups/CPU at the cost of keeping expired mappings a bit longer.
## Recommended profiles
### 1) Ultra-low memory (many clients, light traffic)
```bash
GOMAXPROCS=1 ./udpgw -listen 0.0.0.0:7400 -write-chan 128 -udp-rbuf $((128*1024)) -udp-wbuf $((128*1024)) -map-ttl 45s -reap-every 45s
```
### 2) Balanced (good default for most servers)
```bash
./udpgw -listen 0.0.0.0:7400 -write-chan 512 -udp-rbuf $((1024*1024)) -udp-wbuf $((1024*1024)) -map-ttl 90s -reap-every 15s
```
### 3) Low-latency / games (avoid drops under bursts)
```bash
./udpgw -listen 0.0.0.0:7400 -write-chan 4096 -udp-rbuf $((4*1024*1024)) -udp-wbuf $((4*1024*1024)) -map-ttl 120s -reap-every 10s
```
## Operational notes
- Run behind a firewall; expose only the TCP listen port you need.
- If you bind `-udp-bind`, ensure that IP is present on the host.
- The program will drop UDP replies that are not IPv4.
## systemd (optional)
Example unit (adjust paths/flags):
```ini
[Unit]
Description=udpgw (NapsterV)
After=network.target
[Service]
Type=simple
WorkingDirectory=/opt/udpgw
Environment=GOMAXPROCS=1
ExecStart=/opt/udpgw/udpgw -listen 0.0.0.0:7400 -write-chan 256 -udp-rbuf 262144 -udp-wbuf 262144 -map-ttl 60s -reap-every 30s
Restart=on-failure
NoNewPrivileges=true
PrivateTmp=true
[Install]
WantedBy=multi-user.target
```