ProtoCore v0.0.1
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
derived_sizing.h
Go to the documentation of this file.
1// Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4/**
5 * @file derived_sizing.h
6 * @brief Feature-driven sizing resolution - the per-variant sizing layer's final pass.
7 *
8 * Some buffer sizes have a hard lower bound set by which features are compiled in, not by the
9 * board. A ring smaller than that bound does not just waste a little RAM - it breaks the feature
10 * (a handshake resets, a streamed upload deadlocks). That coupling is sizing logic, so it lives
11 * here in the board-profile layer rather than inline in protocore_config.h, and it runs LAST: after
12 * the chip/PSRAM/flash profiles, the base `#ifndef` defaults, and every `PC_ENABLE_*` feature
13 * flag are resolved, so it can see the final values.
14 *
15 * The floor is enforced against whatever set the value - a chip profile, a `-D` build flag, or the
16 * base default - by raising it to the feature minimum when it falls short (a monotone max, never a
17 * lower). This is deliberately NOT gated on "was it a default?": a profile that pins RX_BUF_SIZE to
18 * fit its DRAM must still be lifted to the streaming floor when streaming is built, or the pin
19 * silently deadlocks large uploads. A value already at or above the floor is left untouched, so an
20 * intentionally roomy ring is preserved.
21 */
22
23#ifndef PROTOCORE_DERIVED_SIZING_H
24#define PROTOCORE_DERIVED_SIZING_H
25
26// --- RX ring (RX_BUF_SIZE): hold the largest first-flight / window any enabled feature needs ---
27
28// Streamed uploads need the RX ring to hold a full TCP receive window or the peer overruns it and
29// the transfer deadlocks (ack-on-consume reopens the window only as the ring drains). The window is
30// ~5.7 KB, so the ring must comfortably exceed it.
31#if PC_ENABLE_STREAM_BODY && RX_BUF_SIZE < 8192
32#undef RX_BUF_SIZE
33#define RX_BUF_SIZE 8192
34#endif
35
36// A modern SSH client's first flight (identification banner + KEXINIT) is ~1.5 KB: post-quantum /
37// curve kex names, cert host-key algs, EtM MACs, ext-info-c. The RX ring must hold it or the
38// handshake resets at key exchange.
39#if PC_ENABLE_SSH && RX_BUF_SIZE < 2048
40#undef RX_BUF_SIZE
41#define RX_BUF_SIZE 2048
42#endif
43
44// A modern TLS ClientHello (TLS 1.3 key shares + cipher/sig-alg lists + the RFC 7685 padding real
45// clients send) is ~1.5 KB and arrives as one TCP segment. The recv callback refuses a whole segment
46// that will not fit the ring (ERR_MEM, lossless backpressure), so a ClientHello bigger than the ring
47// is refused forever and the handshake stalls to an idle-timeout RST - every 1.3-leading client
48// (curl, browsers, Python) then fails to connect while a 1.2-only client squeaks in. The ring must
49// hold a full segment.
50#if PC_ENABLE_TLS && RX_BUF_SIZE < 2048
51#undef RX_BUF_SIZE
52#define RX_BUF_SIZE 2048
53#endif
54
55#endif // PROTOCORE_DERIVED_SIZING_H