diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..a2a8e1e --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,30 @@ +[package] +name = "alksocks" +version = "0.1.0" +edition = "2021" +rust-version = "1.88" +license = "MIT OR Apache-2.0" +description = "SOCKS5 (RFC 1928) proxy protocol over alkcall channels: vendored fast-socks5 typestate core plus producer/consumer sessions. Producer/consumer protocol crate." +repository = "https://git.alk.dev/alkdev/alksocks" +keywords = ["socks5", "proxy", "rfc1928", "channels", "alkcall"] +categories = ["network-programming", "asynchronous"] +exclude = [".opencode/", "AGENTS.md", "docs/reviews/", "docs/research/", "docs/plans/", "tasks/", "docs/sdd_process.md"] + +[lib] +name = "alksocks" + +[features] +# Declared empty by design (ADR-009): `local` adds tokio/net + socket2 +# when its modules land, `composed` adds the alktunnels dep. The +# default build is protocol-only and wasm-clean by construction. +default = [] +local = [] +composed = [] + +[dependencies] +tokio = { version = "1", default-features = false, features = ["rt", "sync", "io-util", "macros", "time"] } +tracing = "0.1" +thiserror = "2" + +[dev-dependencies] +tokio = { version = "1", features = ["full", "test-util", "macros"] } \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..4e3b125 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,23 @@ +//! 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 RFC wire vocabulary and the explicit typestate live in +//! [`vendor`]: an extraction 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/vendor.md` and ADR-011. +//! +//! Architecture: `docs/architecture/overview.md` (spec set: +//! wire.md, producer.md, consumer.md, vendor.md). + +#![forbid(unsafe_code)] + +pub mod vendor; diff --git a/src/vendor/LICENSE b/src/vendor/LICENSE new file mode 100644 index 0000000..a80ef1a --- /dev/null +++ b/src/vendor/LICENSE @@ -0,0 +1,35 @@ +The MIT License (MIT) + +https://github.com/dizda/fast-socks5 + +Copyright (c) 2025 Jonathan Dizdarevic + +The files under this `src/vendor/` directory are an extraction of +fast-socks5 v1.0.0 (https://github.com/dizda/fast-socks5), carried +in-tree by alksocks under ADR-011 (docs/architecture/decisions/ +011-inline-vendor.md). Upstream has no per-file license headers; this +bundled notice is the license obligation's carrier. The extraction +cut and the carried changes are recorded in +docs/architecture/vendor.md. + +--- + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/src/vendor/client.rs b/src/vendor/client.rs new file mode 100644 index 0000000..6e52a6a --- /dev/null +++ b/src/vendor/client.rs @@ -0,0 +1,2 @@ +//! Vendored from fast-socks5 v1.0.0 (extraction — see the module doc +//! in `mod.rs`; filled by the client-session extraction task). diff --git a/src/vendor/mod.rs b/src/vendor/mod.rs new file mode 100644 index 0000000..16d7ac6 --- /dev/null +++ b/src/vendor/mod.rs @@ -0,0 +1,27 @@ +//! The inline vendor: an extraction of fast-socks5 v1.0.0's +//! `T`-generic subset (MIT, third-party upstream — +//! github.com/dizda/fast-socks5; `/workspace/fast-socks5` is the +//! read-only reference checkout, kept for differential testing of RFC +//! edge cases). +//! +//! Extracted per ADR-011 §Amendment (docs/architecture/decisions/ +//! 011-inline-vendor.md): only the code already generic over +//! `T: AsyncRead + AsyncWrite + Unpin` rides in-tree — the kernel-net +//! handlers, the `socks4` module, and the legacy `Config`/ +//! `Authentication` layer are **not** copied. The extraction cut, the +//! two carried changes (BIND support, `new_reply` publication), and +//! the extraction-time adjustments (no `anyhow`, no `log`, no +//! `async-trait`) are recorded in `docs/architecture/vendor.md`. +//! +//! License: upstream is MIT with no per-file headers — the bundled +//! notice in [`this module's LICENSE file`](LICENSE) (v1.0.0 +//! attribution) is the license obligation's carrier. +//! +//! Maintenance posture: the vendored code is first-class, co-evolves +//! with the wrapper, and is the crate's only RFC 1928 wire vocabulary +//! ("no second codec, ever" — ADR-011). A future upstream release is +//! re-based against deliberately, never absorbed silently. + +pub mod client; +pub mod server; +pub mod util; diff --git a/src/vendor/server.rs b/src/vendor/server.rs new file mode 100644 index 0000000..3b62b52 --- /dev/null +++ b/src/vendor/server.rs @@ -0,0 +1,2 @@ +//! Vendored from fast-socks5 v1.0.0 (extraction — see the module doc +//! in `mod.rs`; filled by the server-typestate extraction task). diff --git a/src/vendor/util/mod.rs b/src/vendor/util/mod.rs new file mode 100644 index 0000000..2e89445 --- /dev/null +++ b/src/vendor/util/mod.rs @@ -0,0 +1,9 @@ +//! Vendored from fast-socks5 v1.0.0 (extraction — see the module doc +//! in the vendor root's `mod.rs`). +//! +//! Upstream layout: `stream.rs` (the `read_exact!`/`ready!` macros + +//! `ConnectError`) and `target_addr.rs` (`TargetAddr` + the address +//! codec) — filled by the wire-vocabulary extraction task. + +pub mod stream; +pub mod target_addr; diff --git a/src/vendor/util/stream.rs b/src/vendor/util/stream.rs new file mode 100644 index 0000000..9b41463 --- /dev/null +++ b/src/vendor/util/stream.rs @@ -0,0 +1,7 @@ +//! Vendored from fast-socks5 v1.0.0 (extraction — see the module doc +//! in the vendor root's `mod.rs`; filled by the wire-vocabulary +//! extraction task). +//! +//! Upstream carries the `read_exact!`/`ready!` macros, `ConnectError`, +//! and the `tcp_connect*` dialers; only the first two ride the +//! extraction (the dialers are the cut kernel-net region). diff --git a/src/vendor/util/target_addr.rs b/src/vendor/util/target_addr.rs new file mode 100644 index 0000000..b61ef7f --- /dev/null +++ b/src/vendor/util/target_addr.rs @@ -0,0 +1,7 @@ +//! Vendored from fast-socks5 v1.0.0 (extraction — see the module doc +//! in the vendor root's `mod.rs`; filled by the wire-vocabulary +//! extraction task). +//! +//! Upstream carries `TargetAddr`, the address codec (`read_address`), +//! and the `resolve_dns` helper; only the codec rides the extraction +//! (DNS resolution is the cut net region). diff --git a/tasks/implementation/vendor-crate-scaffolding.md b/tasks/implementation/vendor-crate-scaffolding.md index de38df9..a3b273d 100644 --- a/tasks/implementation/vendor-crate-scaffolding.md +++ b/tasks/implementation/vendor-crate-scaffolding.md @@ -1,7 +1,7 @@ --- id: implementation/vendor-crate-scaffolding name: Vendor — crate scaffolding (Cargo.toml, lib.rs, vendor module skeleton, license notice) -status: pending +status: completed depends_on: [] scope: narrow risk: low @@ -60,17 +60,17 @@ Deliverables: ## Acceptance Criteria -- [ ] `cargo test` passes (empty crate compiles and runs) -- [ ] `cargo clippy --all-targets -- -D warnings` clean -- [ ] `cargo fmt --check` clean -- [ ] `cargo check --target wasm32-unknown-unknown` clean (the wasm gate +- [x] `cargo test` passes (empty crate compiles and runs) +- [x] `cargo clippy --all-targets -- -D warnings` clean +- [x] `cargo fmt --check` clean +- [x] `cargo check --target wasm32-unknown-unknown` clean (the wasm gate is green from birth — no `mio`/`socket2`/`tokio::net` in the graph) -- [ ] `cargo clippy --target wasm32-unknown-unknown -- -D warnings` clean -- [ ] `Cargo.toml` has no `alkcall`, no `anyhow`, no `log`, no +- [x] `cargo clippy --target wasm32-unknown-unknown -- -D warnings` clean +- [x] `Cargo.toml` has no `alkcall`, no `anyhow`, no `log`, no `async-trait`, no `tokio-stream`, no `socket2` in `[dependencies]` -- [ ] `src/vendor/LICENSE` exists with the MIT text + v1.0.0 attribution, +- [x] `src/vendor/LICENSE` exists with the MIT text + v1.0.0 attribution, referenced from the vendor module doc -- [ ] `#![forbid(unsafe_code)]` present in `lib.rs` +- [x] `#![forbid(unsafe_code)]` present in `lib.rs` ## References @@ -86,8 +86,55 @@ Deliverables: ## Notes -> To be filled by implementation agent +- **Cargo.toml** follows the alktunnels posture (the closer sibling — + same tokio wasm-clean subset incl. `time`, same dev-dep tokio + shape): `exclude` mirrors alktunnels (docs/research/ + tasks/ + + sdd_process.md); keywords/categories/description point at the + SOCKS5 story; repository is the git.alk.dev remote. `[features]` + declares `default`/`local`/`composed` empty (ADR-009 §Amendment — + populated by their modules' tasks); `[dependencies]` is exactly the + task's trio (tokio wasm-clean subset, tracing, thiserror — no + alkcall, no net-shaped anything). A `[lib]` section pins the crate + name, matching the siblings. +- **lib.rs** — `#![forbid(unsafe_code)]`, crate docs (what the crate + is, the never-binds posture, the vendor provenance pointer, the + overview.md link), `pub mod vendor;`. Nothing else: later tasks add + their own modules + re-exports. +- **src/vendor/** skeleton preserves upstream v1.0.0 file names for + mechanical per-file diffs: `mod.rs` (provenance module doc + + submodule declarations), `server.rs`, `client.rs`, + `util/{mod,stream,target_addr}.rs` — the five files the extraction + tasks fill. Stubs carry one-line module docs naming their filling + task and (for the util files) the cut-region note; `util/mod.rs` + pre-declares `stream` + `target_addr` exactly as upstream does. + `socks4/` is deliberately absent (the cut). +- **src/vendor/LICENSE** — the upstream MIT text verbatim (Copyright + (c) 2025 Jonathan Dizdarevic, per `/workspace/fast-socks5/LICENSE`) + under a provenance header (v1.0.0, github.com/dizda/fast-socks5, + ADR-011 pointer, vendor.md pointer); referenced from the `mod.rs` + module doc via an intra-doc link. The upstream license has no + "MIT License" body-text title line — it opens with "MIT License" + + copyright; the notice keeps that text verbatim after the header. +- Verification ran clean: `cargo test` (0 tests, compiles + runs), + clippy `--all-targets -- -D warnings`, `cargo fmt --check`, + `cargo check --target wasm32-unknown-unknown`, and + `cargo clippy --target wasm32-unknown-unknown -- -D warnings` — + the wasm gate is green from birth (the dep graph is tokio-wasm- + subset + tracing + thiserror only). ## Summary -> To be filled on completion \ No newline at end of file +Created the `alksocks` 0.1.0 crate skeleton per the task: `Cargo.toml` +(sibling posture; empty `local`/`composed` features declared; tokio +wasm-clean subset `rt/sync/io-util/macros/time`, `tracing`, +`thiserror`; no alkcall/net-shaped deps; full tokio dev-deps for +native tests), `src/lib.rs` (`#![forbid(unsafe_code)]`, crate docs +pointing at the architecture spec set, `pub mod vendor;`), the +`src/vendor/` skeleton preserving upstream fast-socks5 v1.0.0 file +names (`mod.rs` with the provenance/extract-not-copy module doc + +`server`/`client`/`util` declarations; five stub files for the +extraction tasks; `socks4/` cut), and `src/vendor/LICENSE` (upstream +MIT text + v1.0.0 attribution header, referenced from the vendor +module doc). All acceptance criteria verified: test/clippy/fmt clean +natively, both wasm checks clean, dep surface clean, license notice +in place, forbid-unsafe present. \ No newline at end of file