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
//! Message framing / chunking. A message larger than the connection's negotiated
//! `max_message_size` is split into MTU-sized [`Chunk`]s on the sender and reassembled on the
//! receiver.
//!
//! NOTE: this is **whole-message** buffering, not MSRP-style (RFC 4975) streaming. There is no
//! incremental delivery: the receiver yields a payload only once *every* chunk has arrived (or
//! drops it on TTL). The outbound scheduler keeps each message class FIFO, so two chunked messages
//! in the same class do not interleave; a higher-priority class may run between chunks while a
//! delivery is pending. The "split into ordered, id-tagged pieces and reassemble" idea is borrowed
//! from MSRP chunking; MSRP interruption semantics are not implemented.
//!
//! Two halves, deliberately separated:
//!
//! - **Send** - [`ChunkList`] turns a [`bytes::Bytes`] into ordered [`Chunk`]s, where `chunk_size`
//! comes from the connection's negotiated `max_message_size`. The sender uses
//! [`ChunkList::stream`], which yields chunks lazily as zero-copy slices so one chunk is held in
//! flight at a time; [`ChunkList::split`] (eager `Vec`) remains for tests.
//! - **Receive** - [`MessageReassembler`] collects incoming [`Chunk`]s keyed by message id and
//! yields the original payload once every position has arrived.
//!
//! The receiver is robust to the realities of a multi-hop / DHT overlay: out-of-order arrival,
//! **duplicates / retransmits** (first write per position wins), and partial messages (evicted
//! by TTL). It is also bounded against a hostile peer: per-chunk and per-message byte caps, a
//! global buffered-cost ceiling (charging a per-slot overhead so tiny-chunk floods are bounded by
//! count too), an id-count cap, and up-front rejection of already-expired chunks. No single id and
//! no peer-supplied `total` can drive memory without limit. See [`MessageReassembler`].
//!
//! ```text
//! send : Bytes -> [Chunk{ chunk=[i, n], data=data_i, meta } | i in 0..n]
//! receive : a message id is complete iff received positions = 0..total (all n of them);
//! then payload = concat(data_i for i in 0..total)
//! ```
pub use Chunk;
pub use ChunkList;
pub use ChunkMeta;
pub use Framing;
pub use WireReserves;
pub use ReassemblyLimits;
pub use MessageReassembler;
pub use ReassemblyBudget;
pub use ReassemblyOutcome;
pub use ReassemblyRejection;
pub use RetainedReassembly;