Files
DocUDPGW/README.md
2025-12-12 14:32:09 -03:00

158 lines
4.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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
```