ProtoCore v1.0.16
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
network.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 network.h
6 * @brief Decoupled stream I/O: ring buffer in, framed bytes out, one SSH slot per socket.
7 */
8
9#ifndef PROTOCORE_NETWORK_NETWORK_H
10#define PROTOCORE_NETWORK_NETWORK_H
11
13
15
16struct ProtoHandler;
17
18/**
19 * @brief Which transport a slot's byte stream belongs to.
20 *
21 * RFC 4253 sec 4: "SSH works over any 8-bit clean, binary-transparent transport", and sec 4 gives
22 * the two ends different ones - the listening role's stream is a socket this end accepted, the
23 * initiating role's is one it dialled. They are separate pools with separate handle spaces, so the
24 * handle alone does not say which array it indexes.
25 */
27{
28 SSH_STREAM_ACCEPTED = 0, ///< inbound: the handle indexes conn_pool[]
29 SSH_STREAM_DIALED ///< outbound: the handle indexes the client transport's own pool
31
32/** @brief RFC 4254 sec 5: which pool a handle indexes, and the channel it carries. */
33typedef struct
34{
35 SshStreamKind kind; ///< which pool that handle indexes
36 uint32_t channel; ///< the channel a bridge call names
38
39/** @brief The message bytes an emit or a write carries. */
40typedef struct
41{
42 const uint8_t *payload; ///< the message bytes an emit or a write carries
43 size_t len; ///< how many
44 size_t plen; ///< the payload length already built in the region
46
47/** @brief RFC 4254 sec 7.2: where a bridged channel dials, and the client slot it takes. */
48typedef struct
49{
50 const char *host; ///< the destination a channel dials
51 uint16_t port; ///< its port
52 uint32_t timeout_ms; ///< what that open is given
53 int cid; ///< the client slot a channel adopts, or the one a lookup names
55
56/** @brief Where a channel read writes. */
57typedef struct
58{
59 uint8_t *out; ///< where a channel read writes
60 size_t cap; ///< how much room it has; a region lookup reports its own here
62
63/**
64 * @brief The binding between an SSH slot and the byte stream underneath it.
65 *
66 * RFC 4253 sec 4: "SSH works over any 8-bit clean, binary-transparent transport." Nothing here is
67 * one of the three components of RFC 4251 sec 1; this is the stream they run on, and the roles that
68 * drive them (server sec 4.1, client sec 4) live above it.
69 *
70 * A caller sets the members a call takes, invokes it through ::SshNetwork, and reads the outcome off
71 * the same handle.
72 *
73 * @var SshNetworkNs::claim bind an SSH slot to a stream: the handle and which pool it indexes
74 * @var SshNetworkNs::release mark an SSH slot unowned
75 * @var SshNetworkNs::slot_free lowest unowned SSH slot, or 0xFF when the pool is full
76 * @var SshNetworkNs::owns true when @c ssh_slot is bound to @c conn_slot
77 * @var SshNetworkNs::tx_drain put the packet the codec flagged on the wire, as the window allows
78 * @var SshNetworkNs::emit frame one SSH message and hand it to the slot's worker
79 * @var SshNetworkNs::write_msg frame one built SSH message and write it now
80 * @var SshNetworkNs::payload_region the span a message may be built in for a frame without a copy
81 * @var SshNetworkNs::write_msg_at frame what is already in that span and write it
82 *
83 * @var SshNetworkNs::ssh_slot the SSH slot a call acts on
84 * @var SshNetworkNs::conn_slot the stream slot it is bound to
85 * @var SshNetworkNs::handle the stream handle a claim binds
86 * @var SshNetworkNs::stream which pool that handle indexes, and the channel it carries
87 * @var SshNetworkNs::msg the message bytes an emit or a write carries
88 * @var SshNetworkNs::dial where a bridged channel dials
89 * @var SshNetworkNs::read_args where a channel read writes
90 * @var SshNetworkNs::ok a call's true/false outcome
91 * @var SshNetworkNs::i32 a call's signed outcome
92 * @var SshNetworkNs::u8 the lowest unowned slot, or 0xFF when the pool is full
93 * @var SshNetworkNs::n a byte count a call reports
94 * @var SshNetworkNs::region the span a message may be built in for a frame without a copy
95 */
96
97typedef struct
98{
99 uint8_t ssh_slot; ///< the SSH slot a call acts on
100 uint8_t conn_slot; ///< the stream slot it is bound to
101 int handle; ///< the stream handle a claim binds
102 SshStreamRef stream; ///< which pool that handle indexes, and the channel it carries
103 SshNetMsgArgs msg; ///< the message bytes an emit or a write carries
104 SshChanDialArgs dial; ///< where a bridged channel dials
105 SshChanReadArgs read_args; ///< where a channel read writes
107 int i32;
108 uint8_t u8;
109 size_t n;
110 uint8_t *region;
111#if PROTOCORE_ENABLE_TCP_CLIENT
112 // Bridging a channel to a socket of our own needs the client half of the transport, so these
113 // exist exactly when TcpClient does.
114#endif // PROTOCORE_ENABLE_TCP_CLIENT
116
117/** @brief The operands and the outcome. */
119
120/** @brief The entries. */
121typedef struct
122{
123 void (*const claim)(uint8_t *work);
124 void (*const release)(uint8_t *work);
125 void (*const slot_free)(uint8_t *work);
126 void (*const owns)(uint8_t *work);
127 void (*const tx_drain)(uint8_t *work);
128 void (*const emit)(uint8_t *work);
129 void (*const write_msg)(uint8_t *work);
130 void (*const payload_region)(uint8_t *work);
131 void (*const write_msg_at)(uint8_t *work);
132 void (*const chan_open)(uint8_t *work);
133 void (*const chan_adopt)(uint8_t *work);
134 void (*const chan_by_cid)(uint8_t *work);
135 void (*const chan_write)(uint8_t *work);
136 void (*const chan_read)(uint8_t *work);
137 void (*const chan_avail)(uint8_t *work);
138 void (*const chan_drained)(uint8_t *work);
139 void (*const chan_close)(uint8_t *work);
140 void (*const chan_close_all)(uint8_t *work);
142
143// What the table binds, defined once in the .c and taking one parameter each: everything
144// else an entry needs is an operand in SshNetworkV or a region of the borrow at a fixed offset.
145void protocore_ssh_network_claim(uint8_t *work);
148void protocore_ssh_network_owns(uint8_t *work);
150void protocore_ssh_network_emit(uint8_t *work);
163
164// `static const`, initialised HERE rather than `extern` against a definition in the .c: a
165// const object whose initializer every translation unit can see is a COMPILE-TIME FACT, so
166// `SshNetwork.claim(work)` resolves to a named function and becomes a DIRECT call. An extern table
167// leaves the call indirect and the symbol live at every level, -O2 -flto included.
168static const SshNetworkNs SshNetwork __attribute__((unused)) = {
176 .payload_region = protocore_ssh_network_payload_region,
186 .chan_close_all = protocore_ssh_network_chan_close_all,
187};
188
189/**
190 * @brief The PROTOCORE_SSH_NETWORK_BORROW bytes this module's state lives in.
191 *
192 * Stated beside the namespace rather than on it: an entry takes a borrow, and this is where
193 * that borrow comes from. Taken once from the end of the pool, which no mark and no release
194 * walks, so the state lasts the life of the program.
195 *
196 * @return the span.
197 */
199
200/** @brief Put the server identification string on the wire, raw, before any binary packet. */
201void ssh_net_version_exchange_send(uint8_t i, uint8_t conn_slot);
202
204
205#endif // PROTOCORE_NETWORK_NETWORK_H
PROTO_ENUM_PACKED
Application protocol spoken on a listener port or connection slot.
Root infrastructure: fixed widths, serializers, opcodes and sizes, for every layer above.
void protocore_ssh_network_chan_avail(uint8_t *work)
void protocore_ssh_network_chan_by_cid(uint8_t *work)
void protocore_ssh_network_chan_write(uint8_t *work)
SshNetworkVars SshNetworkV
The operands and the outcome.
uint8_t * protocore_ssh_network_span(void)
The PROTOCORE_SSH_NETWORK_BORROW bytes this module's state lives in.
void protocore_ssh_network_chan_drained(uint8_t *work)
void protocore_ssh_network_claim(uint8_t *work)
void protocore_ssh_network_chan_close_all(uint8_t *work)
void protocore_ssh_network_tx_drain(uint8_t *work)
void protocore_ssh_network_chan_close(uint8_t *work)
void protocore_ssh_network_write_msg_at(uint8_t *work)
void protocore_ssh_network_release(uint8_t *work)
void ssh_net_version_exchange_send(uint8_t i, uint8_t conn_slot)
Put the server identification string on the wire, raw, before any binary packet.
void protocore_ssh_network_chan_open(uint8_t *work)
void protocore_ssh_network_chan_read(uint8_t *work)
void protocore_ssh_network_chan_adopt(uint8_t *work)
void protocore_ssh_network_slot_free(uint8_t *work)
void protocore_ssh_network_emit(uint8_t *work)
void protocore_ssh_network_write_msg(uint8_t *work)
@ SSH_STREAM_DIALED
outbound: the handle indexes the client transport's own pool
Definition network.h:29
@ SSH_STREAM_ACCEPTED
inbound: the handle indexes conn_pool[]
Definition network.h:28
enum PROTO_ENUM_PACKED SshStreamKind
Which transport a slot's byte stream belongs to.
void protocore_ssh_network_payload_region(uint8_t *work)
void protocore_ssh_network_owns(uint8_t *work)
Per-protocol connection event/poll callbacks (the server's dispatch vtable).
RFC 4254 sec 7.2: where a bridged channel dials, and the client slot it takes.
Definition network.h:49
uint32_t timeout_ms
what that open is given
Definition network.h:52
const char * host
the destination a channel dials
Definition network.h:50
uint16_t port
its port
Definition network.h:51
int cid
the client slot a channel adopts, or the one a lookup names
Definition network.h:53
Where a channel read writes.
Definition network.h:58
size_t cap
how much room it has; a region lookup reports its own here
Definition network.h:60
uint8_t * out
where a channel read writes
Definition network.h:59
The message bytes an emit or a write carries.
Definition network.h:41
size_t len
how many
Definition network.h:43
const uint8_t * payload
the message bytes an emit or a write carries
Definition network.h:42
size_t plen
the payload length already built in the region
Definition network.h:44
The entries.
Definition network.h:122
void(*const claim)(uint8_t *work)
Definition network.h:123
SshChanDialArgs dial
where a bridged channel dials
Definition network.h:104
SshStreamRef stream
which pool that handle indexes, and the channel it carries
Definition network.h:102
proto_bool ok
Definition network.h:106
uint8_t * region
Definition network.h:110
uint8_t conn_slot
the stream slot it is bound to
Definition network.h:100
uint8_t u8
Definition network.h:108
int handle
the stream handle a claim binds
Definition network.h:101
uint8_t ssh_slot
the SSH slot a call acts on
Definition network.h:99
SshNetMsgArgs msg
the message bytes an emit or a write carries
Definition network.h:103
SshChanReadArgs read_args
where a channel read writes
Definition network.h:105
RFC 4254 sec 5: which pool a handle indexes, and the channel it carries.
Definition network.h:34
SshStreamKind kind
which pool that handle indexes
Definition network.h:35
uint32_t channel
the channel a bridge call names
Definition network.h:36
#define PROTOCORE_BEGIN_DECLS
Give a header's declarations C linkage, so their symbol names carry no parameter types.
Definition types.h:96
_Bool proto_bool
The truth value.
Definition types.h:64
#define PROTOCORE_END_DECLS
Definition types.h:97