Restore 2.1.8-beta9 admin default filtering when compact mode is off; keep compact mode focused on self.
6.3 KiB
GOST UDP vs Realm UDP Analysis
Goal: Compare GOST UDP forwarding through tunnels with Realm's UDP implementation to understand why users report GOST UDP forwarding has problems while Realm works correctly.
Task Checklist
- Analyze GOST UDP tunnel architecture
- Analyze Realm UDP relay architecture
- Identify architectural differences
- Identify potential issues in GOST implementation
- Document findings and recommendations
GOST UDP Architecture
Core Components
-
UDP Relay (
x/internal/net/udp/relay.go)- Simple bidirectional packet copying between two
net.PacketConninterfaces - Uses two goroutines: one for each direction
- Sequential packet processing (no batching)
- No idle timeout or association tracking
- Simple bidirectional packet copying between two
-
UDP over Tunnel (
x/handler/relay/bind.go,x/handler/socks/v5/udp_tun.go)- Wraps UDP data with SOCKS5-style framing via
UDPTunServerConn() - Adds address headers to each packet
- Uses smux multiplexing for tunnel connections
- Wraps UDP data with SOCKS5-style framing via
-
SOCKS5 UDP Framing (
x/internal/util/socks/conn.go,x/internal/util/relay/conn.go)udpTunConn.ReadFrom(): Parses SOCKS5 UDP header to extract target addressudpTunConn.WriteTo(): Wraps data with SOCKS5 UDP header including:- RSV (data length, 2 bytes)
- Frag (0xff for tunnel relay, 1 byte)
- Address (4/16/1+n bytes for IPv4/IPv6/domain)
-
Multiplexing (
x/internal/util/mux/mux.go)- Uses smux v1.5.31 for connection multiplexing
- Adds stream framing and flow control overhead
Data Flow (UDP over Tunnel)
Client UDP packet
↓
[Local GOST] SOCKS5 UDP framing (add ~10-26 bytes)
↓
smux stream (add framing, flow control)
↓
TCP tunnel to remote
↓
[Remote GOST] smux demux
↓
SOCKS5 UDP deframing
↓
Forward to target
Realm UDP Architecture
Core Components
-
Association Model (
realm_core/src/udp/middle.rs)- Per-client socket associations stored in
SockMap - Creates dedicated remote socket per client address
- Spawns
send_backtask for return path - Association timeout for cleanup
- Per-client socket associations stored in
-
Batched I/O (
realm_core/src/udp/batched.rs)- Uses
recvmmsg/sendmmsgon Linux - Up to 128 packets per batch
- Significantly higher throughput for high-PPS traffic
- Uses
-
No Protocol Overhead
- Plain UDP forwarding without adding protocol headers
- No SOCKS5 framing or mux layer
Data Flow
Client UDP packet
↓
[Realm] Direct relay via association socket
↓
Target server
Key Architectural Differences
| Aspect | GOST | Realm |
|---|---|---|
| UDP over Tunnel | SOCKS5 framing + smux multiplexing | N/A (direct relay only) |
| Protocol Overhead | Extra ~10-26 bytes per packet | None |
| I/O Model | Standard Go net.PacketConn | Batched I/O (recvmmsg/sendmmsg) |
| Connection Tracking | Via mux session | SockMap with timeout |
| Association Model | None (bidirectional copy only) | Per-client socket association |
| Idle Timeout | None on UDP relay | Association timeout |
| Throughput | Single packet per syscall | Up to 128 packets per syscall |
Identified Potential Issues in GOST
1. No Batch I/O Support
- Impact: High PPS (packets per second) traffic incurs syscall overhead
- Realm advantage:
recvmmsg/sendmmsgbatches up to 128 packets - Evidence: Realm's
batched.rsimplements this; GOST uses standardReadFrom/WriteTo
2. Protocol Overhead Per Packet
- Impact: Bandwidth waste, extra processing for framing/deframing
- Overhead: SOCKS5 UDP header adds ~10 bytes (IPv4) to ~26 bytes (IPv6) per packet
- Evidence:
x/internal/util/socks/conn.go:63-78shows framing overhead
3. Mux Layer Overhead
- Impact: Latency and throughput degradation
- smux adds: Stream framing, flow control, potential backpressure
- Evidence:
x/internal/util/mux/mux.gowraps all tunnel connections
4. No Association Tracking
- Impact: Cannot properly handle NAT translation for return traffic
- Realm approach:
SockMaptracks client→remote socket mapping - Evidence: GOST's
udp.Relayjust copies packets bidirectionally
5. No Idle Timeout on UDP Relay
- Impact: Stale connections may persist indefinitely
- Evidence:
udp.Relay.Run()blocks until error or context cancel - Contrast: Realm has association timeout for cleanup
6. Sequential Packet Processing
- Impact: Cannot pipeline multiple packets
- Evidence:
relay.go:44-77shows sequentialReadFrom→WriteToloop - Contrast: Realm's batched I/O handles multiple packets concurrently
7. Read Deadline on Underlying TCP
- Impact: Could cause unexpected connection termination
- Default: 15-second read timeout set on connections
- Evidence:
x/handler/relay/metadata.go:readTimeoutdefaults to 15s - Issue: UDP relay may not handle deadline properly
Recommendations
-
Consider Direct UDP Mode: For scenarios where tunnel is not required, use direct UDP relay (no SOCKS5 framing)
-
Add Association Tracking: Implement client→remote socket mapping with timeout
-
Investigate Batch I/O: Consider using
recvmmsg/sendmmsgequivalent in Go (viax/netor raw syscalls) -
Add Idle Timeout: Implement timeout-based cleanup for UDP associations
-
Reduce Framing Overhead: Consider more compact framing for tunnel UDP
Files Analyzed
GOST Files
go-gost/x/internal/net/udp/relay.go- Core UDP relay logicgo-gost/x/internal/util/mux/mux.go- smux multiplexinggo-gost/x/internal/util/socks/conn.go- SOCKS5 UDP framinggo-gost/x/internal/util/relay/conn.go- Relay UDP framinggo-gost/x/handler/relay/bind.go- Relay BIND handlergo-gost/x/handler/socks/v5/udp_tun.go- SOCKS5 UDP tunnel handlergo-gost/x/handler/tunnel/bind.go- Tunnel BIND handlergo-gost/x/connector/tunnel/bind.go- Tunnel connector BINDgo-gost/x/connector/tunnel/conn.go- Tunnel connection typesgo-gost/x/connector/tunnel/listener.go- Tunnel bind listener
Realm Files (fetched from GitHub)
realm_core/src/udp/mod.rs- UDP relay entry pointrealm_core/src/udp/middle.rs- Association and relay logic with SockMaprealm_core/src/udp/socket.rs- UDP socket binding and associationrealm_core/src/udp/batched.rs- Batched I/O implementation