Files
alksocks/docs/architecture/vendor.md
T
glm-5.3-flash 9587670138 docs: Phase 1 architecture — specs, ADRs 001-012, open-questions tracker
- 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
2026-09-20 18:41:56 +00:00

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:

  1. The net feature 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's net = ["tokio/net", "dep:socket2", "dep:tokio-stream"]).
  2. 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's sock_addr as the reply#1 carrier; the reply#2 writer using the published new_reply).
  3. The run_udp_proxy_custom bind seam — the seam is narrower than it looks (udp_bind_random_port unconditionally; 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 the net-gated path's embedders.)
  4. new_reply publication — the reply encoder becomes public (a reply(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-socks5 stays 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 net gate 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 + the new_reply finding), 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)