docs(arch): client-dial SOCKS5 proxy seam — ADR-090, OQ-67

AlknetClient gains an optional SOCKS5 proxy (with_socks5_proxy) so a
native client can hide its real IP from the hub. dial_quic routes QUIC
through SOCKS5 UDP ASSOCIATE (validated by the /workspace/quinn-proxy-poc
PoC — quinn's AsyncUdpSocket + new_with_abstract_socket is the extension
point, 5/5 runs clean); dial_tcp_tls routes through SOCKS5 CONNECT. The
proxy is invisible above the dial (Connection, dispatch, credentials,
TLS config all proxy-unaware) and the no-proxy path is the zero-cost
default (socks5 feature + fast-socks5 dep are opt-in).

SOCKS5 is the sole proxy protocol (covers both TCP and UDP, so no HTTP
CONNECT variant needed). The two distinct SOCKS5 concepts — the
client-dial proxy (ADR-090, transport-layer privacy) and the planned
alknet-socks5 channels data-channel handler (ADR-085 scope, a service
one side offers the other) — compose at the SOCKS5 protocol level
without alknet-type-level coupling.

iroh is the exception: dial_iroh does not consume Socks5ProxyConfig —
iroh's proxy_url covers the relay-exposure surface, but the
direct-connection peer-exposure case is OQ-67 (deferred(unclear) — the
pieces exist but the iroh socket-stack composition isn't clear; does
not block the first hub deployment, which uses QUIC/TCP+TLS).

- ADR-090: Client-Dial SOCKS5 Proxy Seam
- OQ-67: iroh Proxy Support (Direct-Connection Peer Exposure)
- client README: proxy section, struct/builder, Proxy error variant,
  socks5 feature gate, deps, assembly example, decisions/open-questions
- README/open-questions: index entries, Current State, OQ count 67/20
This commit is contained in:
glm-5.2 committed 2026-07-16 08:42:33 +00:00
1 parent ed40f95d96
commit b7d67e5a5f
5 files changed
+775 -11

No files matched your search

+25 -1
View File
@@ -1,6 +1,6 @@
---
status: draft
last_updated: 2026-07-15
last_updated: 2026-07-16
---
# Open Questions
@@ -208,6 +208,7 @@ Door type is separate from whether a decision is made. A two-way door is a decis
| OQ | Title | Status | Door | Pri |
|----|-------|--------|------|-----|
| [OQ-66](questions/066-alknet-register-wire-protocol.md) | `alknet/register` Wire Protocol | deferred(scope) | one | med |
| [OQ-67](questions/067-iroh-proxy-support.md) | iroh Proxy Support (Direct-Connection Peer Exposure) | deferred(unclear) | two | med |
## Deferred / Blocked
@@ -303,6 +304,29 @@ filtering the tables above.
for worker provisioning per OQ-58).
- **Full file**: [OQ-66](questions/066-alknet-register-wire-protocol.md)
### OQ-67: iroh Proxy Support (Direct-Connection Peer Exposure)
- **Investigation**: Work through the iroh socket stack to determine
whether iroh exposes a socket abstraction analogous to quinn's
`AsyncUdpSocket` + `new_with_abstract_socket` (the hook the quinn
POC uses). If it does, a `Socks5UdpSocket`-equivalent for iroh is
the same shape as the quinn integration. If it does not, the
alternatives are: (a) force relay-only when a proxy is configured
(the conservative default — the peer always sees the relay's IP,
never the client's), or (b) accept the gap (document that iroh direct
connections expose the client's IP). The investigation needs a
concrete iroh-direct-with-proxy use case to drive the choice —
without one, "force relay-only" is the conservative default.
- **Priority**: medium
- **Impacts**: A client that dials over iroh direct (hole-punched)
connections and wants to hide its real IP from the peer. Does NOT
block the first hub deployment — hub outbound dials use QUIC/TCP+TLS
(both honor the proxy, ADR-090). Does NOT block the relay-mediated
iroh path — iroh's relay hides the client's IP from the peer, and
iroh's `proxy_url` hides it from the relay. The gap is the iroh
*direct* path only.
- **Full file**: [OQ-67](questions/067-iroh-proxy-support.md)
### OQ-56: Full Channel-Level Flow-Control Windowing
- **Blocked on**: a real deployment observes head-of-line blocking on a