- docs/architecture/: README index, overview, wire, producer, consumer, vendor, bast specs + open-questions.md (the OQ-SK-01..09 ledger promoted; new questions as OQ-SK2-06..) - ADRs 001-012: ALPN/op/params, protocol base, the handle swap, the dial-callback shape, auth split by the door, access control (open gate + BIND command gate), BIND in base, provider defaults, feature gates, channel capacity, the inline vendor, target policy - deferred OQs (SK2-06, SK2-07) with tracker tasks in tasks/architecture/ per the sdd_process deferred-OQ protocol - review pass applied: frame-length joint bound (65766 corner), accept_no_auth vs skip_auth corrected against fast-socks5 source, composed-feature wasm posture, cross-reference fixes Verified: cross-references (all ADR/OQ refs resolve), doc sizes under split threshold, Phase 0 fidelity spot-checks
5.8 KiB
status, last_updated
| status | last_updated |
|---|---|
| draft | 2026-09-20 (Phase 1 initial draft) |
alksocks — The Inline Vendor (fast-socks5 subset)
The crate owns its RFC 1928 protocol code in-tree: the inline
vendor of fast-socks5's T-generic subset ([ADR-011](decisions/
011-inline-vendor.md); OQ-SK-04's resolution). This document is the
vendor's scope, the carried changes, and the maintenance posture.
The protocol base decision is ADR-002; the feature gating is
ADR-009.
What is Vendored
From fast-socks5 v1.0.0 (MIT, third-party upstream —
/workspace/fast-socks5 is the read-only reference checkout; the
vendor point is noted in the vendored code):
| Piece | Why it rides | Gating |
|---|---|---|
The server typestate (Socks5ServerProtocol<T, states::*>, negotiate/auth/command-read/reply) |
the producer's conversation driver (ADR-002) | T-generic — ungated |
The auth traits (AuthMethod<T>/AuthMethodSuccessState<T>) |
the negotiation machinery (the crate uses NoAuth in-band; the traits stay for fidelity) | ungated |
transfer (the generic two-pump) |
the interception-point shape (the crate's data plane is pump_bidi, but transfer is the typestate's own seam) |
ungated |
The codecs: new_udp_header/parse_udp_request, TargetAddr/to_be_bytes/read_address, new_reply (published — carried change #4), ReplyError/SocksError/SocksServerError |
the RFC wire vocabulary everywhere (front doors, associate frames, reply#2 reader) | ungated |
The client types: Socks5Stream<S>::use_stream + the AsyncRead/AsyncWrite impls |
the consumer half's stream session (ADR-002; POC #1's fit) — the first-party associate session in consumer.rs was informed by this shape (upstream's Socks5Datagram kernel path is the net-gated row) |
ungated |
Kernel-net pieces (the local-socket default handlers, Socks5Datagram's kernel socket path, the DNS resolve helper, the legacy Socks5Server/Incoming) |
upstream surface kept for fidelity where net is on |
net-gated |
Not vendored: the deprecated Socks5Server/Socks5Socket/Incoming
bind-based API as a default path (it exists upstream and stays
behind net; the crate never routes through it). The vendored subset
is functionally complete without net (POC #4: a full RFC 1928
CONNECT conversation passes --no-default-features).
The Four Carried Changes (ADR-011)
The vendor's diff vs upstream v1.0.0 is deliberate and bounded:
- The
netfeature gate — ~120#[cfg]insertions across 5 files, exactly POC #4's measured shape (poc-connect-wasm-findings.md§The gating change: server.rs ~8 insertions; client.rs 87 diff lines (whitespace-inflated); util/stream.rs, util/target_addr.rs, lib.rs ≤3; Cargo.toml'snet = ["tokio/net", "dep:socket2", "dep:tokio-stream"]). - BIND — absent upstream (every handler refuses
Socks5Command::TCPBind). The crate drives the typestate itself for the BIND shape (ADR-007); the vendor carries the shape in-tree (reply_success'ssock_addras the reply#1 carrier; the reply#2 writer using the publishednew_reply). - The
run_udp_proxy_custombind seam — the seam is narrower than it looks (udp_bind_random_portunconditionally; the reply port derives from that kernel socket). In-tree fix: make the bind optional / accept a caller-supplied socket. (The channels path drives the typestate directly regardless; the fix serves thenet-gated path's embedders.) new_replypublication — the reply encoder becomes public (areply(code, addr)-shaped constructor) so the BIND reply#2 writer doesn't re-encode the 10/22-byte reply form.
Plus the provenance notes: the vendor point (v1.0.0) and the license headers (MIT; preserve per-file headers or a bundled notice — ADR-011's license obligation).
Maintenance Posture
- The vendor is first-class code, not a patch stack: the carried changes live in-tree and co-evolve with the wrapper; the vendored subset's RFC fidelity is the crate's own test suite's job.
- Differential testing:
/workspace/fast-socks5stays the reference for RFC edge cases (reply-code mapping, domain addressing, fragmentation). The crate's test suite covers the edge cases the vendored code must keep passing; when in doubt, diff behavior against the reference checkout. - Upstream posture: fast-socks5 is third-party; nothing waits on
it. Offering the
netgate upstream as a courtesy PR is optional (POC #4: small enough to offer as-is); a future upstream release may be re-based against deliberately, never absorbed silently (the carried changes would need re-verification). - No second codec, ever: the vendored codecs are the only RFC wire vocabulary in the crate (ADR-011's rationale; the alknet anti-prior-art record is in phase-0 §Anti-prior-art).
Design Decisions
| ADR | Decision | Summary |
|---|---|---|
| 002 | Protocol base | the explicit typestate API only |
| 009 | Feature gates | net default-on; wasm builds use default-features = false |
| 011 | The inline vendor | the subset in-tree; the four carried changes; v1.0.0 noted |
Open Questions
Open questions are tracked in open-questions.md. None currently blocking this document.
References
- OQ-SK-04 (the resolved posture), OQ-SK-08 (BIND +
new_reply), OQ-SK-03 (the bind seam) - POC #4 (
poc-connect-wasm-findings.md— the measured gate), POC #5 (poc-bind-findings.md— the BIND driving + thenew_replyfinding), POC #2 (the typestate-driving shape for ASSOCIATE) /workspace/fast-socks5(v1.0.0, MIT — the reference checkout);docs/research/iroh-socks5-eval.md(why not the alternative base)