ProtoCore v0.0.1
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
diffserv.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 diffserv.h
6 * @brief Layer 4 (Transport) - DiffServ QoS marking (RFC 2474) for outbound traffic.
7 *
8 * Stamps the 6-bit DSCP into the DS field (the high 6 bits of the IPv4 TOS / IPv6 Traffic-Class byte) of
9 * outbound TCP connections and UDP datagrams so a QoS-aware network - and the Wi-Fi driver's 802.11e WMM
10 * access-category mapping - can prioritize real-time / safety packets over best-effort. The marking is applied
11 * on tcpip_thread where the pcb is created (accept / connect / udp create), so nothing is added to the send
12 * hot path. This module owns the two server-wide DSCP defaults; the per-listener and per-connection overrides
13 * live with their pcb (listener.cpp / tcp.cpp) but read the defaults through here.
14 *
15 * Three levels of control, coarse to fine:
16 * - pc_set_default_dscp(): every outbound TCP connection (accepted + client) gets this DSCP.
17 * - pc_listen_set_dscp(): all connections accepted on one port get a DSCP (overrides the default).
18 * - pc_conn_set_dscp(): tag one live connection with any DSCP - real QoS, or arbitrary network testing.
19 * Plus pc_udp_set_dscp() for outbound datagrams. A DSCP of 0 means best-effort (no marking / TOS left 0).
20 *
21 * @author Douglas Quigg (dstroy0)
22 * @date 2026
23 */
24
25#ifndef PROTOCORE_DIFFSERV_H
26#define PROTOCORE_DIFFSERV_H
27
28#include "protocore_config.h"
29
30#if PC_ENABLE_DIFFSERV
31
32#include <stdint.h>
33
34// Common RFC 2474 / RFC 4594 code points for convenience; any 0-63 value is accepted.
35#define PC_DSCP_CS0 0 ///< default / best effort
36#define PC_DSCP_CS6 48 ///< network control
37#define PC_DSCP_EF 46 ///< expedited forwarding (low-latency real-time)
38#define PC_DSCP_AF41 34 ///< assured forwarding, class 4 low drop (interactive)
39#define PC_DSCP_AF31 26 ///< assured forwarding, class 3 low drop (multimedia streaming)
40#define PC_DSCP_UNSET 0xFF ///< per-listener sentinel: fall back to the server-wide default
41
42/** @brief DSCP (0-63) -> the 8-bit DS field. The low 2 bits are ECN (left 0); TOS = DSCP << 2. */
43static inline uint8_t pc_dscp_to_tos(uint8_t dscp)
44{
45 return (uint8_t)((dscp & 0x3F) << 2);
46}
47
48/**
49 * @brief Set the server-wide default DSCP for every outbound TCP connection (accepted + client).
50 * @param dscp 0-63; 0 means best-effort (no marking). Takes effect for connections opened after the call.
51 */
52void pc_set_default_dscp(uint8_t dscp);
53
54/** @brief The current server-wide TCP default DSCP (read by the accept / connect paths). */
55uint8_t pc_diffserv_default_dscp(void);
56
57/**
58 * @brief Set the default DSCP for outbound UDP datagrams.
59 * @param dscp 0-63; 0 means best-effort. Applied to each UDP pcb as it is created.
60 */
61void pc_udp_set_dscp(uint8_t dscp);
62
63/** @brief The current UDP default DSCP (read when a UDP pcb is created). */
64uint8_t pc_diffserv_udp_dscp(void);
65
66/**
67 * @brief Tag one accepted server connection with a DSCP (per-connection override).
68 *
69 * Marshalled to tcpip_thread. Lets an individual flow carry any DSCP - real per-flow QoS, or arbitrary QoS
70 * tagging for network testing. Also works mid-connection (lwIP reads pcb->tos per outbound segment).
71 * @param slot connection-pool slot.
72 * @param dscp 0-63.
73 * @return false if @p slot is out of range or no longer holds a live pcb.
74 */
75bool pc_conn_set_dscp(uint8_t slot, uint8_t dscp);
76
77/**
78 * @brief Set the DSCP applied to every connection accepted on @p port (per-listener override).
79 * @param port the listening port.
80 * @param dscp 0-63, or PC_DSCP_UNSET to clear the override (fall back to the server default).
81 * @return false if no active listener binds @p port.
82 */
83bool pc_listen_set_dscp(uint16_t port, uint8_t dscp);
84
85#endif // PC_ENABLE_DIFFSERV
86#endif // PROTOCORE_DIFFSERV_H
User-facing configuration for ProtoCore.