docs: POC #5 (channels-native SOCKS5 BIND) findings
POC #5 run 2026-09-15 (alksocks-bind-poc, standalone, 9 tests) — OQ-SK-08 POC-validated; the POC register (OQ-SK-07) is closed. - The BIND phase model extends end to end on one channel: request → reply#1 (BND.ADDR) → quiet wait → one inbound accept → reply#2 (peer) → pump_bidi pass-through (0 B overhead, like CONNECT) - Both accept variants implemented: local (real TcpListener, faithful RFC) + composed (alktunnels listen-tunnel — per-listener ACL for free, hub-relayable) - The address-first-vs-accept-first deadlock resolved in shape: reply#1 first, the tunnel open rides the accept future - The socks5:bind scope gate distinguishes ingress from egress (RFC-faithful ConnectionNotAllowed refusal; CONNECT unaffected) - Vanilla front door re-validated for the BIND conversation (raw pipe, zero translation); CONNECT + ASSOCIATE regression-guarded on the same registration — the RFC 1928 command surface is complete - fast-socks5: zero BIND ask (typestate-driven; reply_success carries reply#1); courtesy ask: publish the private new_reply encoder - alktunnels ask ledger pinned at two items for the one-version bump: (1) listen-addr inspection without consuming an accept, (2) accepted handles carrying peer metadata — both POC-evidenced, both additive Verification: cargo test (9/9), clippy --all-targets -D warnings, fmt --check clean in alksocks-bind-poc.
This commit is contained in:
1 parent
aac63d17fc
commit
cb4d58a2bf
2 files changed
+312
-23
No files matched your search
+56
-23
@@ -1,7 +1,7 @@
|
||||
---
|
||||
status: draft
|
||||
last_updated: 2026-09-15 (consistency pass: POC register in OQ-SK-07,
|
||||
client-wrapper transfer residue cleaned, convergence checklist fixed)
|
||||
last_updated: 2026-09-15 (POC #5 BIND passed — OQ-SK-08 POC-validated,
|
||||
POC register closed, alktunnels ask ledger pinned at two items)
|
||||
---
|
||||
|
||||
# alksocks — Phase 0 (Exploration)
|
||||
@@ -822,7 +822,7 @@ one-place accounting of all numbered POCs:
|
||||
| 2 | UDP ASSOCIATE (handle-swap shape) | **Passed 2026-09-14** | `poc-udp-associate-findings.md` |
|
||||
| 3 | noq `AsyncUdpSocket` impl | **Dropped 2026-09-14** — transferred to alknet with OQ-SK-06 | — |
|
||||
| 4 | fast-socks5 wasm fork-minimality | **Passed 2026-09-13** — folded into #1's worktree, shares #1's findings file | `poc-connect-wasm-findings.md` §POC #4 |
|
||||
| 5 | BIND (accept-side command) | **Added 2026-09-14 with OQ-SK-08 — pending** | (OQ-SK-08) |
|
||||
| 5 | BIND (accept-side command) | **Passed 2026-09-15** | `poc-bind-findings.md` |
|
||||
|
||||
Numbering is historical (do not renumber — findings files and commit
|
||||
messages reference these numbers). Detailed descriptions follow.
|
||||
@@ -909,7 +909,13 @@ Candidates, originally in rough priority order (the order is historical
|
||||
reply#1). Validates: the accept-side data plane (the mirror of the
|
||||
dial callback), reply#1/#2 sequencing on one channel, and the
|
||||
alktunnels listen-addr ask's shape. Completes the RFC 1928 command
|
||||
surface (all three commands) in the crate.
|
||||
surface (all three commands) in the crate. **Run 2026-09-15 —
|
||||
passed** (`alksocks-bind-poc`, 9 tests; findings in
|
||||
`poc-bind-findings.md`: the phase model extends end to end, both
|
||||
accept variants implemented, the scope gate works, the
|
||||
address-first-vs-accept-first deadlock is resolved in shape
|
||||
(reply#1 first, the tunnel open rides the accept future), and the
|
||||
alktunnels ask ledger is pinned at two items).
|
||||
|
||||
POC placement conventions (inherited from alktunnels): a POC that needs
|
||||
code from this repo runs in a worktree/branch (`.worktrees/research/
|
||||
@@ -920,9 +926,12 @@ regardless of where the code lives.
|
||||
|
||||
### OQ-SK-08: BIND — the accept-side command (use case found)
|
||||
|
||||
**Status: new (2026-09-14, post-POC #2).** Both POCs refused BIND as
|
||||
RFC-correct; the findings review surfaced a real use case and a
|
||||
mechanism, so "out of scope until a use case exists" has been met.
|
||||
**Status: POC-validated (2026-09-15, POC #5 —
|
||||
`poc-bind-findings.md`).** The shape space below is written as it
|
||||
stood pre-POC; the POC resolved the design question (variants 1 + 2
|
||||
implemented; the sequencing pinned) and pinned the ask ledger. The
|
||||
remaining decision is Phase 1's ADR (ship in base crate? default
|
||||
accept variant?).
|
||||
|
||||
**The gap, precisely:** fast-socks5 parses `TCPBind`
|
||||
(`Socks5Command::TCPBind`, `lib.rs:91`) but every handler refuses it
|
||||
@@ -931,7 +940,9 @@ bind machinery exists. The typestate flow (`read_command()` returning
|
||||
`cmd` + `TargetAddr`) means the wrapper drives the command dispatch
|
||||
itself — implementing BIND is wrapper-side code, **zero upstream
|
||||
ask** (unlike UDP ASSOCIATE's `run_udp_proxy_custom` bind, which sits
|
||||
inside an upstream handler).
|
||||
inside an upstream handler). **POC-confirmed:** `reply_success`'s
|
||||
`sock_addr` parameter carries reply#1's `BND.ADDR` verbatim; the only
|
||||
courtesy ask is publishing `new_reply` (the reply encoder is private).
|
||||
|
||||
**The shape (convergent precedent: iroh-socks5's channels-native
|
||||
BIND, `docs/research/iroh-socks5-eval.md` §BIND):** one channel per
|
||||
@@ -984,6 +995,19 @@ sketched behind the same accept callback — the composed variant's
|
||||
value (hub story, per-listener ACL) is the reason to measure it, and
|
||||
its blocker is the address-inspection ask.
|
||||
|
||||
**POC #5's resolution (2026-09-15 — `poc-bind-findings.md`):** both
|
||||
variants implemented and passing. The hunch was right, and variant 2's
|
||||
sequencing is now pinned: **reply#1 first, the tunnel open rides the
|
||||
accept future** (the first cut opened the listen-tunnel before
|
||||
reply#1 and deadlocked into the establishment timeout — the app
|
||||
server cannot dial until reply#1 tells it the address; the quiet wait
|
||||
is exactly where the accept-pop block belongs). The ask ledger grew
|
||||
to two items (address inspection; peer metadata on accepted handles —
|
||||
reply#2's fidelity half), both POC-evidenced, both additive. The
|
||||
scope gate (`socks5:bind`, checked at command dispatch from the
|
||||
per-call opener identity) distinguishes ingress from egress and is
|
||||
POC-validated.
|
||||
|
||||
**Security boundary note:** BIND is an *inbound* listener — the
|
||||
accept-side twin of arbitrary egress. Whatever ACL governs the socks5
|
||||
resource now also governs who can mint listeners on the producer's
|
||||
@@ -1144,8 +1168,11 @@ Candidate reading for the research specialist (to be expanded):
|
||||
virtual-subnet proposal (dial-callback translation, no wire
|
||||
change) recorded for Phase 1
|
||||
- [ ] OQ-SK-08 (BIND) — new (2026-09-14): the gap + use case +
|
||||
accept-side mechanism written; resolve via POC #5 + the Phase 1
|
||||
ADR (ship in base crate? default accept variant?)
|
||||
accept-side mechanism written; **POC #5 run 2026-09-15 —
|
||||
passed** (the phase model extends end to end; both accept
|
||||
variants implemented; the scope gate works; the ask ledger is
|
||||
pinned); the Phase 1 ADR (ship in base crate? default accept
|
||||
variant?) has empirical ground under it
|
||||
- [ ] OQ-SK-09 (channel capacity) — new (2026-09-14): the proxy-
|
||||
workload analysis written (wire change rejected; config is the
|
||||
mechanism; in-channel port multiplexing considered and
|
||||
@@ -1160,10 +1187,10 @@ Candidate reading for the research specialist (to be expanded):
|
||||
- [ ] Targeted POC(s) run + summaries in `docs/research/`
|
||||
(the convergence-blocking POCs are complete — see the OQ-SK-07
|
||||
register: #1 + #4 in `poc-connect-wasm-findings.md`, #2 in
|
||||
`poc-udp-associate-findings.md`; #3 dropped with the scope
|
||||
decision. Left unchecked because **#5 (BIND), added 2026-09-14
|
||||
with OQ-SK-08, is still pending** — it gates Phase 1's BIND ADR,
|
||||
not Phase 0's convergence.)
|
||||
`poc-udp-associate-findings.md`, #5 (BIND) in
|
||||
`poc-bind-findings.md`; #3 dropped with the scope decision.
|
||||
The register is closed — no pending POCs remain for this
|
||||
crate's Phase 0.)
|
||||
- [x] Converge: recommended approach written up, ready to hand to the
|
||||
Architect for Phase 1 (§Convergence, 2026-09-14)
|
||||
|
||||
@@ -1229,11 +1256,15 @@ binds except the two explicit, optional, feature-gated assembly shapes
|
||||
the proxy-workload channel-cap recommendation (OQ-SK-09); the
|
||||
virtual-subnet translation-layer shape (OQ-SK-05 addendum).
|
||||
- **Upstream asks (we own both upstreams; file early, land there):**
|
||||
fast-socks5 — the `net` feature gate (POC #4's ~120-line change)
|
||||
and the `run_udp_proxy_custom` unconditional-bind seam. alktunnels —
|
||||
listen-addr inspection without consuming an accept (OQ-SK-08
|
||||
variant 2's blocker). First-real-consumer asks, the alkcall
|
||||
E-01/E-02 precedent.
|
||||
fast-socks5 — the `net` feature gate (POC #4's ~120-line change),
|
||||
the `run_udp_proxy_custom` unconditional-bind seam, and the
|
||||
courtesy `new_reply` publication (the reply encoder is private;
|
||||
POC #5 re-encoded it by hand). alktunnels — the one-version bump
|
||||
ledger (POC #5's evidence, `poc-bind-findings.md` §Upstream-ask
|
||||
ledger): (1) listen-addr inspection without consuming an accept
|
||||
(OQ-SK-08 variant 2's address half), (2) accepted handles carrying
|
||||
peer metadata (reply#2's fidelity half). First-real-consumer asks,
|
||||
the alkcall E-01/E-02 precedent.
|
||||
|
||||
### What Phase 0 could NOT answer (handed to Phase 1)
|
||||
|
||||
@@ -1251,10 +1282,12 @@ binds except the two explicit, optional, feature-gated assembly shapes
|
||||
recommendation stay Phase 1 decisions. In-channel port
|
||||
multiplexing considered and rejected there.
|
||||
- BIND — RFC-refused in both POCs; **a use case and a mechanism were
|
||||
found in the 2026-09-14 findings review** — OQ-SK-08 records the
|
||||
gap, the accept-side-resource shape (mirroring alktunnels' `-R`
|
||||
far-side listener), the address-first-vs-accept-first design
|
||||
question, and POC #5. Deciding whether BIND ships in the base
|
||||
found in the 2026-09-14 findings review, and POC #5 (2026-09-15)
|
||||
validated the shape end to end** — OQ-SK-08 records the gap, the
|
||||
accept-side-resource shape (mirroring alktunnels' `-R` far-side
|
||||
listener), the address-first-vs-accept-first resolution (reply#1
|
||||
first, the tunnel open rides the accept future), the two-item ask
|
||||
ledger, and the scope gate. Deciding whether BIND ships in the base
|
||||
crate (and which accept variant is default) is a Phase 1 ADR —
|
||||
support is additive (old consumers still get the RFC refusal), so
|
||||
nothing here is a one-way door.
|
||||
Reference in new issue
Block a user