Files
ty c5ffffc600 feat(service): outbound UDP relay through SOCKS5-only chains
Phase 2 of the outbound proxy refactor. The new
OutboundProxyDatagram type implements DatagramSocket / DatagramSend /
DatagramReceive on top of a freshly-bound local UDP socket plus one
SOCKS5 UDP ASSOCIATE per chain hop. Each datagram on the wire carries
N nested UdpAssociateHeader frames (one per hop), the inner-most one
addressing the ss-server's UDP external endpoint.

Per-hop control connections are built by reusing the existing TCP
chain builder (connect_chain_for_udp_associate) so all of the
shadowsocks DNS resolver / ConnectOpts behaviour still applies.

Integration:

* OutboundProxyClient::associate_udp + supports_udp().
* OutboundProxyClient::supports_udp() returns true iff every hop is
  SOCKS5; HTTP/HTTPS hops cannot transport UDP and downgrade the
  whole chain to 'unsupported'.
* local::net::udp::association::create_proxied_socket dispatches
  based on supports_udp(): when true the per-association socket is
  ProxySocket<OutboundProxyDatagram> wrapping the chained datagram;
  otherwise we keep the previous direct ProxySocket<ShadowUdpSocket>.
* When the chain is configured but unable to relay UDP, sslocal /
  ssserver emit a single startup WARN ('UDP traffic will bypass the
  chain') instead of failing — runtime traffic transparently falls
  back to a direct connection to the ss-server.

OutboundProxyStream gains try_into_tcp() so SOCKS5-only chains can
recover the bare TcpStream as keep-alive control connections —
Sync-friendly storage required because the HTTP CONNECT variant
internally holds a hyper::upgrade::Upgraded which is !Sync.
2026-04-29 19:35:42 +08:00
..
2026-04-26 01:24:30 +08:00