Expand description
Client/ENTRY-side send-window flow control (AIMD send window over the honest delivery clock). Client/ENTRY-side send-window flow control for Session sockets.
A Segmentation-only Session has no end-to-end flow control: the ENTRY writer runs to
completion and floods the return path (data + acknowledgements + SURB replenishments), capped
at the EXIT SURB-reply rate. Unpaced, this deterministically stalls.
This module provides a self-adapting send window that replaces manual pacing. It speeds up only on proven delivery and slows down on congestion/loss, so throughput auto-tracks the drain rate and unpaced send becomes safe.
§Trust model (why the window is asymmetric)
The counterparty is not assumed cooperative. A SURB carries PoRValues, and reply packets
sent with it are paid from the SURB creator’s (our) channels along the return path regardless
of payload (RFC-0005 §3.2). SURBs are therefore prepaid value a greedy EXIT can harvest
without serving us; the SURB balancer is the anti-grief throttle. Consequently:
- The window only opens on HONEST delivery — data proven to have reached us: reliable-mode frame
acknowledgements (the
ack_statemachinery) or application-verified return bytes. Nothing else authorizes speeding up. SeeWindowController::on_delivered. - SURB state may only slow us down, never speed us up.
SupplyConstraintcan shrink or cap the window; it can never grow it. The SURBbuffer_levelis partly counterparty-reported and dead-reckoned, so a hostile or lossy peer must not be able to accelerate us or make us overspend. - A malicious counterparty can only ever make us slower — never faster, never draining our SURBs beyond the client-configured ceiling.
- 1–20 % path loss is expected and recovered (reliable mode retransmits; the window multiplicatively decreases and re-grows on delivery).
- The anti-grief ⇄ throughput trade is the client’s dial (
FlowControlConfig), set explicitly — SURB supply is never silently widened for speed.
Structs§
- Delivered
- Bytes retired from the in-flight window this observation, split by outcome. Produced by a
DeliverySignaland fed toWindowController::apply_delivery. - Delivery
Atomics 🔒 - Delivery
Clock - Delta reader over a shared
DeliveryMeter, implementingDeliverySignal. Each poll returns bytes delivered/lost since the previous poll. One reader serves either clock — impl A (reliable acks viaDeliveryTap) or impl B (return bytes viaDeliveryMeter::record_acked) — because both simply add to the same meter. - Delivery
Meter - Shared, lock-free honest-clock meter. Producers bump it in place with a single atomic add —
the reliable ack machinery on ack / retransmission-exhaustion (impl A), or an
application-return-byte reader (impl B). The window driver reads byte deltas via
DeliveryClock. No channel, no per-frame allocation, no dedup bookkeeping (a duplicate ack merely over-credits by one frame, which the SURB ceiling andcwndstill bound). Modelled on the existing atomicBalancerStateValues. - Delivery
Tap - Frame-granular tap installed into the reliable socket: it pairs a
DeliveryMeterwith a frame’s byte size, so the ack machinery can report deliveries in place without tracking byte counts. Cheap to clone (Arc+usize). - Flow
Control Config - Client-tunable flow-control parameters. Defaults are deliberately conservative (anti-grief-preserving): the window starts at the floor and only grows on proven delivery, and the opt-in robustness knobs are off. This is the clean profile.
- Window
Controller - Pure AIMD send-window controller. Holds no I/O; every state transition is a plain method so the invariants are exhaustively unit-testable. Byte-based (not frame-based) so it is agnostic to frame sizing.
Enums§
- Backoff
- Severity of a SURB-supply backoff request.
- Flow
Control Mode - How the send window learns that data was delivered (its “honest clock”).
Traits§
- Delivery
Signal - The honest clock. Reports how many in-flight bytes were delivered or lost since last polled.
- Supply
Constraint - The SURB-supply ceiling. Down-only: it may cap or shrink the window, never open it.