ProtoCore
v1.0.16
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
derived_sizing.h
Go to the documentation of this file.
1
// ProtoCore v1.0.16 - 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 `PROTOCORE_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 PROTOCORE_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 PROTOCORE_ENABLE_SSH && RX_BUF_SIZE < 2048
40
#undef RX_BUF_SIZE
41
#define RX_BUF_SIZE 2048
42
#endif
43
44
// The SSH client bridges one forwarded-tcpip channel per local TCP connection and pools
45
// PROTOCORE_SSH_CLIENT_MAX_CHANNELS of them, but the channels themselves come from the shared per-
46
// connection table. The table has to hold as many as the client pools or the surplus bridges can
47
// never be allocated a channel.
48
#if PROTOCORE_ENABLE_SSH_CLIENT && PROTOCORE_SSH_MAX_CHANNELS < PROTOCORE_SSH_CLIENT_MAX_CHANNELS
49
#undef PROTOCORE_SSH_MAX_CHANNELS
50
#define PROTOCORE_SSH_MAX_CHANNELS PROTOCORE_SSH_CLIENT_MAX_CHANNELS
51
#endif
52
53
// A modern TLS ClientHello (TLS 1.3 key shares + cipher/sig-alg lists + the RFC 7685 padding real
54
// clients send) is ~1.5 KB and arrives as one TCP segment. The recv callback refuses a whole segment
55
// that will not fit the ring (ERR_MEM, lossless backpressure), so a ClientHello bigger than the ring
56
// is refused forever and the handshake stalls to an idle-timeout RST - every 1.3-leading client
57
// (curl, browsers, Python) then fails to connect while a 1.2-only client squeaks in. The ring must
58
// hold a full segment.
59
#if PROTOCORE_ENABLE_TLS && RX_BUF_SIZE < 2048
60
#undef RX_BUF_SIZE
61
#define RX_BUF_SIZE 2048
62
#endif
63
64
#endif
// PROTOCORE_DERIVED_SIZING_H
src
derived_sizing.h
Generated by
1.9.8