1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
//! The `SessionTransport` byte-pipe abstraction — the boundary between
//! `PhantomSession`'s background data pump and a concrete physical transport
//! (`TcpSessionTransport`, `WebSocketLeg`, `EmbeddedLeg`, ...).
//!
//! Defined with **native async fn in trait** (AFIT, stable since Rust 1.75)
//! rather than the `#[async_trait]` macro: method calls do not allocate a
//! boxed future, and `Send`-ness of the returned futures is checked at the
//! *use* site (the concrete impl type), not at the trait-impl site. The
//! latter is what allows `EmbeddedLeg<R, W, ...>` to compose with
//! `embedded-io-async`, whose async-fn-in-trait futures are not `Send`-
//! bounded — `#[async_trait]` here would have failed to prove `Send`-ness
//! at the generic impl site.
//!
//! Dependency-light (only `bytes` + `CoreError`) so it can compile in a
//! future `no_std + alloc` build ahead of the rest of the crate.
//! Re-exported from [`crate::api::session`] so the historical import path
//! stays stable.
//!
//! Phase 3.6 (no-std foundation): module compiles without `std` because the
//! implementation uses only `core::future::Future` and pulls nothing from
//! `std::*`. The crate-level `#![cfg_attr(not(feature = "std"), no_std)]` in
//! `lib.rs` drives the no_std switch; this module needs no extra attribute.
use crateCoreError;
use Bytes;
// `String` is in the std prelude on std builds; under `no_std` it comes from `alloc`
// (the migration address crosses this boundary as a `String` to keep the trait
// `SocketAddr`-free — `std::net::SocketAddr` does not exist in `core`/`alloc`).
use String;
/// Lifecycle phase of a [`SessionTransport`], used to bound the receive frame
/// size differently before vs. after the handshake (WIRE-001). During the
/// unauthenticated handshake a peer can open a connection and declare a large
/// frame; capping the receive size tightly there bounds the memory a single
/// unauthenticated peer can make the server buffer. After establishment the cap
/// rises to the steady-state application limit.
/// Async transport trait for PhantomSession.
///
/// Abstractions over UDP, TCP, FakeTLS, etc.
/// Used by the background handshake task for I/O.
///
/// `recv_bytes` returns `Bytes` (Phase 2.8) so the recv pipeline can
/// fan out the same buffer to multiple consumers via cheap refcount
/// clones — no `Vec → Bytes` conversion at the trait boundary.
/// `send_bytes` keeps `&[u8]` because the caller routinely sends a
/// borrowed slice of an already-allocated send buffer.
///
/// **Wrapper contract (audit EPS-04):** every method below the two I/O methods
/// has a *silently-succeeding* default (`{}` / `false` / `Ok(())`). Those are
/// correct for transports without migration, but they make a **partial wrapper**
/// (a newtype that forwards only `send_bytes` / `recv_bytes`) compile with no
/// warning while every control call no-ops on the default — the exact bug that
/// made the pre-ε FFI `migrate()` vacuous through `ObservedTransport`. Any wrapper
/// over a `SessionTransport` **MUST forward the full surface** (all the control
/// methods, not just I/O); the `observed_transport_forwards_all_control_methods`
/// tripwire test guards this for the in-crate wrappers.