Skip to content

Add UoT support to egress SOCKS5 server#335

Merged
noahlevenson merged 5 commits intomainfrom
adam/egress-uot-support
Mar 1, 2026
Merged

Add UoT support to egress SOCKS5 server#335
noahlevenson merged 5 commits intomainfrom
adam/egress-uot-support

Conversation

@myleshorton
Copy link
Contributor

Summary

  • Adds UDP-over-TCP (UoT) support to the egress SOCKS5 server, enabling sing-box clients to tunnel UDP traffic through unbounded
  • Implements UoTResolver to bypass go-socks5's default DNS resolution for UoT magic addresses (sp.v2.udp-over-tcp.arpa)
  • Implements UoTDialer that intercepts UoT connections and relays framed UDP packets to real UDP sockets

Test plan

  • End-to-end tested with lantern-box TUN inbound → unbounded → egress, verified no more SOCKS error code 4
  • HTTPS traffic (google.com, httpbin.org, wikipedia.org) all returning 200
  • DNS resolution working through tunnel
  • 1MB download at ~3.4 MB/s throughput

🤖 Generated with Claude Code

The sing-box UoT protocol tunnels UDP packets over TCP using a magic
FQDN (sp.v2.udp-over-tcp.arpa). The egress SOCKS5 server now intercepts
these addresses and relays framed UDP packets between the TCP stream and
a real UDP socket.

Key components:
- UoTResolver: passes UoT magic addresses through without DNS resolution,
  fixing go-socks5's default behavior of resolving FQDNs before Dial
- UoTDialer: intercepts UoT addresses in the SOCKS5 Dial function and
  sets up the UDP relay via net.Pipe
- tcpPipeConn: wraps net.Pipe to return *net.TCPAddr for go-socks5
  compatibility

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds UDP-over-TCP (UoT) handling to the egress SOCKS5 server so sing-box clients can tunnel UDP traffic through the existing TCP-based egress flow.

Changes:

  • Introduces egress/uot.go implementing UoTResolver (magic address pass-through) and UoTDialer (UoT TCP interception + UDP relay).
  • Wires the new dialer and resolver into the standalone egress SOCKS5 server config.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
egress/uot.go Implements UoT request parsing and bidirectional TCP↔UDP framing/relay, plus resolver/dialer hooks for go-socks5.
egress/cmd/socks5/egress_socks5.go Configures go-socks5 to use UoTDialer and UoTResolver.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- Use net.DefaultResolver.LookupIPAddr with context for cancellation-aware DNS
- Normalize UoT magic address matching (case-insensitive, trailing dot)
- Add max UDP payload size check (65507) with oversized frame discard
- Tie UoT pipe lifecycle to dialing context via ctx.Done() goroutine

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 10 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

myleshorton and others added 3 commits February 27, 2026 12:20
- Log errors in relay goroutines instead of silently discarding
- Close both TCP and UDP connections when either relay direction exits,
  preventing goroutine leaks
- Use maxUDPPayload-sized buffers instead of 65535 for consistency
- Validate UDP read size fits uint16 before casting
- Block loopback destinations to prevent local network access
- Use context-aware DNS with 10s timeout in readSocksAddr
- Fix context cancellation goroutine leak by selecting on connDone
  channel so the goroutine exits when handleUoT completes naturally
- Log CopyN errors when discarding oversized frames

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@noahlevenson noahlevenson merged commit 04f5afa into main Mar 1, 2026
1 check passed
@noahlevenson noahlevenson deleted the adam/egress-uot-support branch March 1, 2026 20:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants