//! alksocks — SOCKS5 (RFC 1928) as a produced resource on alkcall //! channels. //! //! A producer/consumer protocol crate (the alktty/alktunnels shape): //! the producer half registers the `channels/socks5/sub` open op and //! drives the RFC 1928 conversation in-stream over the channel's //! `BiStream`; the consumer half opens SOCKS5 channels and speaks the //! protocol inside them. The defining posture: the protocol never //! binds a port — kernel binds exist only as explicit, feature-gated //! assembly shapes (`local`), never in the protocol layer. //! //! ## The landed surface (the protocol core) //! //! - **The wire vocabulary and the explicit typestate** live in //! [`rfc1928`]: a targeted fork of fast-socks5 v1.0.0's `T`-generic //! subset (MIT, third-party upstream) carrying two deliberate //! changes (BIND support, `new_reply` publication) — see //! `docs/architecture/rfc1928.md`, ADR-013, and ADR-011. //! - **The wire codec** ([`wire`]): the ASSOCIATE datagram frame //! (`[len: u16 BE][addr + data]`, ADR-003) — framing is applied //! exactly once, by this layer; the egress speaks inner bytes. //! - **The wire-stable open-op surface** ([`params`]): the //! `channels/socks5/sub` op id, the `alk/socks5` ALPN, the //! trivial `{}` params (ADR-001), and the two scope constants //! (`socks5:open`, `socks5:bind` — two grants, never implied, //! ADR-006). The typed open-error vocabulary lives in [`error`]. //! - **The three seams** ([`egress`]): `DialFn` / `EgressFactory` / //! `BindAcceptFactory` (ADR-004) — functions, not traits, at the //! three I/O planes; ownership rides the handle structurally; the //! egress readiness contract (`next_reply` `Pending` when nothing //! is ready) is load-bearing API. //! - **The producer half** ([`producer`]): the session-gate //! establisher, the command-dispatch pump (CONNECT pass-through / //! ASSOCIATE datagram stage / BIND phase model), the scope gates //! (the open gate `socks5:open` at the registry; the command gate //! `socks5:bind` at BIND dispatch), and //! [`register_socks5_openable`] — substrate-agnostic over the //! seams; never a bind in the protocol layer. //! - **The consumer half** ([`consumer`]): the typed channels-native //! sessions — [`Socks5ChannelSession`] (CONNECT), //! [`AssociateSession`] (the framed datagram stage), //! [`BindSession`] (the reply#1/reply#2 reader) — each owning its //! channel's teardown; no `Clone`. //! //! `local` (the socket-backed assembly-layer providers — //! [`crate::local::tcp_dial`] / [`crate::local::udp_egress`] / //! [`crate::local::bind_accept`], ADR-008/009) is feature-gated: the //! default crate is protocol-only and wasm-clean by construction, and //! the composed providers ride `composed` //! ([`crate::composed::direct_egress`] — the alktunnels direct-op //! egress, ADR-008/009). //! //! Architecture: `docs/architecture/overview.md` (spec set: //! wire.md, producer.md, consumer.md, rfc1928.md); the cross-cutting //! behavior is pinned end to end by `tests/core-integration.rs` //! (one registration, all three commands; concurrency; the teardown //! matrix; the identity/scope matrix; the readiness contract). #![forbid(unsafe_code)] pub mod rfc1928; pub mod consumer; pub mod egress; pub mod error; pub mod params; pub mod producer; pub mod wire; #[cfg(feature = "local")] pub mod local; #[cfg(feature = "composed")] pub mod composed; #[cfg(feature = "local")] pub mod door; /// The shared test helpers (review 002 N-5): the single-sourced /// harness shapes, compiled into the lib test crate. The file lives /// under `tests/common/` so the integration suite reaches the same /// copy through its own `mod` declaration (`tests/harness.rs` /// re-exports the consumed subset). `#[cfg(test)]` keeps it out of /// the published crate; the `#[path]` resolves relative to `src/`. #[cfg(test)] #[path = "../tests/common/mod.rs"] pub(crate) mod test_common; // The shared module is written once against the extern-crate paths // (`alksocks::`) the integration suite resolves; inside the lib test // crate those same paths resolve via this alias (`extern crate` // self-linkage, the standard `mod common` companion). #[cfg(test)] extern crate self as alksocks; pub use consumer::{ AssociateSession, BindDataPlane, BindReply1, BindSession, Socks5ChannelSession, SpentSessionError, TakenAssociateInner, }; pub use egress::{ egress_factory, BindAccept, BindAcceptError, BindAcceptFactory, BindAcceptFactoryError, BindTargetHandle, DialFn, Egress, EgressError, EgressFactory, SocksDialError, TargetHandle, }; pub use error::{ ReplyError, SocksError, SocksEstablishmentReason, SocksOpenError, SocksServerError, SocksSessionError, }; pub use params::{ establishment_reason, socks5_open_spec, Socks5Params, OP_SOCKS5_OPEN, SOCKS5_ALPN, SOCKS5_BIND_SCOPE, SOCKS5_OPEN_SCOPE, }; pub use producer::{ make_socks5_pump_handler, register_socks5_openable, serve_socks5_over, socks5_session_establisher, IdentityWitness, Socks5Producer, Socks5ProducerBuilder, }; pub use wire::{addr_encoding_len, frame, frame_inner, DatagramReader, WireError, MAX_INNER_LEN}; #[cfg(feature = "local")] pub use local::{bind_accept, tcp_dial, udp_egress, LocalEgress}; #[cfg(feature = "local")] pub use local::{ProducerDoor, ProducerDoorBuilder, ProducerDoorGuard}; #[cfg(feature = "composed")] pub use composed::{ bindfirst_accept, direct_egress, key_of, register_forwarded_serving, substrate_addr_of, ComposedEgress, CorrelationRegistry, ForwardedSession, SessionOwner, DEFAULT_MAX_TUNNELS, }; #[cfg(feature = "local")] pub use consumer::TokenClient; #[cfg(feature = "local")] pub use door::{CredentialTable, DoorCredential, FrontDoor, UdpFrontDoor};