- params.rs: OP_TUNNEL_DIRECT / TUNNEL_DIRECT_SCOPE constants;
SubstrateAddr (untagged {host,port} | {path}; also the ADR-008 §3
peer shape); TunnelDirectParams with render_target();
tunnel_direct_spec() — Sub-typed, External, alk/tunnel ALPN
marker, scope ["tunnel:direct"] (never implied by tunnel:open),
per-substrate if/then target sub-schema (malformed targets fail
the registry's schema gate as INVALID_INPUT before the
establisher). 7 unit tests.
- producer.rs: direct_establisher (+ witness variant) — parse,
render the target to the registry backing-string form, dial via
the SAME injected DialFn; no registry lookup (unknown_resource
can never fire); typed errors per ADR-007 §4 minus the registry
row; CF-006 witness seam. register_tunnel_direct_openable reuses
the base pump handler (plan-flow unchanged).
- consumer.rs: TunnelSession::open_direct — separate constructor
(two scopes are two capabilities), plain open_channel (dial
establishers never bind), identical session/data-planes/teardown.
- tests/producer_direct_op.rs: 15 integration tests — tcp + udp e2e
round-trips, malformed-target rejection (no phantom session),
dial-failure pass-through, NOT_FOUND posture, scope separation
both ways (FORBIDDEN, raw-call + session-level), CF-006 witness
(raw + session paths), parse backstop, target-rendering pin.
Harness: Direct registration mode, wire_direct* topologies,
direct_identity/both_scopes_identity.
- CHANGELOG: Unreleased → Added.
Verified: cargo test green (93 native, 94 --all-features); clippy
-D warnings clean (native + wasm32); fmt clean; wasm32 check passes
(default crate stays wasm-clean); cargo doc clean.
Task: tasks/tunnels/direct-op.md (status: completed)
44 lines
1.9 KiB
Rust
44 lines
1.9 KiB
Rust
//! alktunnels — arbitrary bidirectional tunnels over alkcall channels.
|
|
//!
|
|
//! TCP, UDP, unix-socket, and other stream/datagram substrates, in the
|
|
//! `ssh -L` / `ssh -D` / `ssh -R` sense. A producer/consumer protocol
|
|
//! crate riding alkcall channels the same way alktty does (`alk/tty`
|
|
//! is the sibling precedent): the producer half registers the
|
|
//! `alk/tunnel` open op and pumps bytes between the channel and the
|
|
//! substrate; the consumer half is the typed session
|
|
//! ([`TunnelSession`]) that opens tunnel channels and owns teardown.
|
|
//!
|
|
//! A tunnel is a resource, not an address: the open-op params identify
|
|
//! a produced resource + substrate ([`TunnelParams`], ADR-001); the
|
|
//! producer owns the backing. The protocol layer is substrate-agnostic
|
|
//! by construction — socket/platform I/O is confined to the
|
|
//! feature-gated `local` backend (the default crate is wasm-clean).
|
|
//!
|
|
//! - Wire format: `docs/architecture/wire.md` (+ BAST at `bast.md`)
|
|
//! - Open-op params: ADR-001; codec: ADR-003; ALPN: ADR-002
|
|
//! - Producer shapes: ADR-004; consumer session: ADR-005; ACL: ADR-006
|
|
|
|
pub mod consumer;
|
|
pub mod error;
|
|
pub mod params;
|
|
pub mod producer;
|
|
pub mod wire;
|
|
|
|
#[cfg(feature = "local")]
|
|
pub mod local;
|
|
|
|
pub use consumer::{open_reverse_channel, TakenHalves, TunnelSession};
|
|
pub use error::{ReverseOpenError, TunnelError, TunnelIoError, TunnelOpenError};
|
|
pub use params::{
|
|
establishment_reason, tunnel_direct_spec, SubstrateAddr, TunnelDirectParams, OP_TUNNEL_DIRECT,
|
|
TUNNEL_DIRECT_SCOPE,
|
|
};
|
|
pub use params::{tunnel_open_spec, ChannelOpenError, Substrate, TunnelParams, OP_TUNNEL_OPEN};
|
|
pub use params::{TUNNEL_ALPN, TUNNEL_OPEN_SCOPE};
|
|
pub use producer::{
|
|
direct_establisher, direct_establisher_with_witness, register_tunnel_direct_openable,
|
|
register_tunnel_listen_openable, AcceptFn, AcceptQueue, DialFn, ResourceRegistry, TargetHandle,
|
|
TunnelEstablishError,
|
|
};
|
|
pub use wire::MAX_DATAGRAM_LEN;
|