Files
alksocks/CHANGELOG.md
T
glm-5.3-flash 8af23eeee0 docs: OQ-SK2-09 (the UDP door's peer-pin posture) + OQ-SK2-06's trigger-ownership check
- OQ-SK2-09 recorded: option 2 (the same-IP lock + reply-port
  refresh + the RFC drop rule) landed in 0.1.0 (31fb11c); option 3
  (the control-conn-derived expected peer — the complete fix)
  deferred on a concrete wildcard-bind deployment with address-level
  client mobility (QUIC migration is the likely driver); the
  deferred-index row added
- OQ-SK2-06: the trigger ownership checked (2026-09-28) — genuinely
  external by verified default (no suite-internal surface names a
  sandboxed alksocks consumer; the substrate is complete and
  gate-verified, nothing waits on nothing); the Schrödinger-bind
  check recorded in the OQ + the tracker task
- overview.md: the OQ index updated (SK2-09 added, SK2-06's
  ownership noted); the door bullet in the CHANGELOG carries the
  peer-pin posture + the async resolver note

Verification: cargo test + --all-features (15 suites each), clippy
--all-targets --all-features -D warnings clean, fmt clean, wasm check
clean, doc 0 warnings.
2026-09-28 09:17:04 +00:00

5.6 KiB

Changelog

All notable changes to this crate are documented here. The format is based on Keep a Changelog, and this crate adheres to Semantic Versioning.

Unreleased

0.1.0 - 2026-09-27

The initial release: SOCKS5 (RFC 1928) as a produced resource on alkcall channels — the -D flavor as a first-class protocol crate, over alkcall 0.8.0. The defining posture: the protocol never binds a port; kernel binds exist only as explicit, feature-gated assembly shapes. Composed against by the alktunnels 0.2.0 graduation (the direct op + the bind-first/forwarded flow power the composed providers).

Added

  • The RFC 1928 core (src/rfc1928/, ADR-013) — the targeted fork of fast-socks5 v1.0.0's T-generic subset, extracted in-tree as fully owned code (MIT notice bundled; extraction per ADR-011): the wire consts, codecs, errors, the explicit typestate server API (Socks5ServerProtocol<T, states::*>, generic over T: AsyncRead + AsyncWrite + Unpin), and the client use_stream path. Two deliberate changes carried from the fork point: BIND support in the base (ADR-007) and the new_reply publication. No kernel-net code — the default crate is wasm-clean by construction.
  • The wire codec (wire, ADR-003) — the ASSOCIATE datagram frame ([len: u16 BE][addr + data]), framing applied exactly once at this layer; the DatagramReader incremental parser; the MAX_INNER_LEN oversize guard.
  • The wire-stable open-op surface (params, ADR-001/006) — the alk/socks5 ALPN, the channels/socks5/sub op id, the trivial {} params (the RFC conversation is the data plane; nothing to negotiate at open time), and the two scope constants (socks5:open, socks5:bind — two grants, never implied). The typed open-error vocabulary rides error (the ADR-049 reasons).
  • The three seams (egress, ADR-004) — DialFn / EgressFactory / BindAcceptFactory: functions, not traits, at the three I/O planes; ownership rides the handle structurally (TargetHandle / BindTargetHandle / BindAccept); the egress readiness contract (next_reply Pending when nothing is ready) is load-bearing API.
  • The producer half (producer) — the session-gate establisher (validates the opener identity; the target is unknown at open time), the command-dispatch pump handler (CONNECT pass-through / ASSOCIATE datagram stage / BIND phase model — reply#1 → quiet wait → exactly one accept → reply#2 → pass-through), the command gate (socks5:bind at BIND dispatch), the identity witness, and both wiring shapes: the free functions (register_socks5_openable / socks5_session_establisher / make_socks5_pump_handler / serve_socks5_over) and the builder (Socks5Producer::builder() — dial/egress/accept/bind_policy). Data planes ride alkcall::channels::pump_bidi (ADR-050).
  • The consumer half (consumer) — the typed channels-native sessions, each owning its channel's teardown (Drop aborts + reaps; no Clone): Socks5ChannelSession (CONNECT — raw pass-through, the split/into_inner postures), AssociateSession (the framed datagram stage — send_datagram/recv_datagram/split), BindSession (the reply#1/reply#2 reader + the BindDataPlane pass-through), and the token-carrying surface (TokenClient + the *_with_token constructor twins — the cred-bearing front door's re-origination).
  • The local feature (ADR-008/009) — the socket-backed seam providers (tcp_dial / udp_egress / bind_accept — the explicit bind decisions, resolving via the non-blocking tokio::net::lookup_host resolver), plus both doors: the consumer-side front doors (FrontDoor — the NoAuth raw pipe + the RFC 1929 cred-bearing door with the credential→identity mapping, ADR-005; UdpFrontDoor — one association per bound relay socket, the RFC codec at the door boundary only, the peer-pin posture: the client's source IP pins on the first parsed datagram, replies follow the latest-seen port from that IP, foreign-IP datagrams are dropped per RFC 1928's MUST — OQ-SK2-09) and the producer-side listener (ProducerDoor — vanilla clients dial it, each accepted connection is served via serve_socks5_over; the ADR-014 idle-first-byte window + max-sessions cap knobs).
  • The composed feature (ADR-008/009) — the alktunnels 0.2.0 composed providers: direct_egress (the direct-op egress — a lazy destination→tunnel table, DEFAULT_MAX_TUNNELS bounded), and bindfirst_accept + register_forwarded_serving (the BIND accept whose listener lives on a bind-first listen resource; the CorrelationRegistry correlates the forwarded op's peer metadata into ForwardedSessions).
  • The idle-timeout posture (ADR-014) — every phase teardown-governed, no protocol-layer idle bound; the doors own the accept-path defense.
  • The suites — the differential suite against the upstream reference checkout (tests/rfc1928-differential.rs), the protocol-core integration suite (tests/core-integration.rs), and the assembly-layer integration suite (tests/assembly-integration.rs).