37static void ensure_init()
54static void ssh_emit(uint8_t i,
const uint8_t *payload,
size_t len)
66 if (!pc_conn_active(conn->
id))
80 if (
ssh_pkt_send(i, payload, len, wire, &wlen, wire_cap) != 0)
89static void ssh_msg_handler(uint8_t i, uint8_t msg_type,
const uint8_t *payload,
size_t len)
93 s_sshc.
close[i] =
true;
114 return &s_ssh_handler;
124 if (!pc_conn_active(conn->
id))
137 if (!payload || !wire)
147 if (
ssh_pkt_send(ssh_slot, payload, plen, wire, &wlen, wire_cap) != 0)
163 if (!pc_conn_active(conn->
id))
168 uint8_t close_msgs[10];
188 for (
size_t off = 0; off < 10; off += 5)
191 if (
ssh_pkt_send(ssh_slot, close_msgs + off, 5, wire, &wlen, wire_cap) != 0)
209 if (!pc_conn_active(conn->
id))
220 if (!payload || !wire)
232 if (
ssh_pkt_send(ssh_slot, payload, plen, wire, &wlen, wire_cap) != 0)
246 if (!pc_conn_active(conn_slot))
279#if PC_SSH_PORT_FORWARD
280 pc_ssh_forward_pump(j);
312 s_sshc.
close[j] =
false;
317#if PC_ENABLE_SSH_ZLIB
334static void close_conn(uint8_t conn_slot)
351 size_t n = pc_conn_read(conn_slot, buf,
sizeof(buf));
364 close_conn(conn_slot);
380 pc_secure_wipe(buf, n);
384 close_conn(conn_slot);
394#if PC_SSH_PORT_FORWARD
395 pc_ssh_forward_reset(j);
RAII scope guard for transient scratch borrows.
Pluggable monotonic clock for all library timing.
uint32_t pc_millis(void)
The library's monotonic time at 1000 Hz (milliseconds).
Layer 5 (Session) - per-protocol connection handler dispatch table.
#define SSH_REKEY_TIME_MS
Elapsed-time re-key trigger in milliseconds (RFC 4253 §9: "after each hour"). Default 1 hour.
#define SSH_REKEY_PACKET_THRESHOLD
Re-key when either packet sequence number reaches this value.
#define SSH_PKT_BUF_SIZE
Packet assembly buffer per SSH connection (bytes).
void * scratch_alloc(size_t n, size_t align)
Borrow n bytes of scratch, aligned to align.
Shared per-dispatch scratch arena (Layer 5, session-scoped memory).
Secure pool accessor - borrows that hold key material.
int pc_ssh_channel_build_close(uint8_t i, uint32_t channel, uint8_t *out, size_t *out_len, size_t cap)
Build SSH_MSG_CHANNEL_EOF + SSH_MSG_CHANNEL_CLOSE for channel channel and mark it closed.
int pc_ssh_channel_open_forwarded(uint8_t i, const char *conn_addr, uint16_t conn_port, const char *orig_addr, uint16_t orig_port, uint8_t *out, size_t *out_len, size_t cap)
Open a server-initiated "forwarded-tcpip" channel (RFC 4254 §7.2, ssh -R).
void pc_ssh_channel_init(uint8_t i)
Reset channel state for slot i.
int pc_ssh_channel_build_data(uint8_t i, uint32_t channel, const uint8_t *data, size_t len, uint8_t *out, size_t *out_len, size_t cap)
Build an SSH_MSG_CHANNEL_DATA message carrying data to the client on channel channel (a local channel...
SSH connection protocol - multiplexed "session" channels (RFC 4254).
SSH per-connection compression owner (server-to-client zlib / zlib@openssh.com).
void pc_ssh_conn_accept(uint8_t conn_slot)
Handle a new ConnProto::PROTO_SSH connection on conn_slot.
void pc_ssh_conn_setup()
One-time setup: install the dispatcher's binary-packet emit callback.
void pc_ssh_conn_close(uint8_t conn_slot)
Tear down SSH state for conn_slot (disconnect / error).
int pc_ssh_conn_send(uint8_t ssh_slot, uint32_t channel, const uint8_t *data, size_t len)
Send application data to the client over an SSH channel.
void pc_ssh_conn_rx(uint8_t conn_slot)
Drain conn_slot's receive ring buffer through the SSH stack.
int pc_ssh_conn_open_forwarded(uint8_t ssh_slot, const char *conn_addr, uint16_t conn_port, const char *orig_addr, uint16_t orig_port)
Open a server-initiated "forwarded-tcpip" channel to the client (ssh -R): build the CHANNEL_OPEN (RFC...
const ProtoHandler * ssh_proto_handler(void)
void pc_ssh_conn_poll(uint8_t conn_slot)
Per-loop poll hook for an SSH connection (registered as the SSH protocol handler's on_poll)....
int pc_ssh_conn_close_channel(uint8_t ssh_slot, uint32_t channel)
Close an SSH channel from the server side: frame CHANNEL_EOF and CHANNEL_CLOSE as two binary packets ...
Glue between the TCP transport (conn_pool) and the SSH protocol stack.
SSH direct-tcpip port-forwarding owner (the ssh -L target side).
SSH session key material - types, pools, and security model.
SshPacketState ssh_pkt[MAX_SSH_CONNS]
Static packet state pool (BSS). One entry per SSH slot.
int ssh_pkt_send(uint8_t i, const uint8_t *payload, size_t payload_len, uint8_t *out, size_t *out_len, size_t out_cap)
Build and send one SSH binary packet.
void ssh_pkt_init(uint8_t i)
Initialize the packet state for SSH connection slot i.
int ssh_pkt_recv(uint8_t i, const uint8_t *data, size_t len, ssh_msg_handler_t handler)
Receive and process one or more SSH binary packets from data.
SSH binary packet protocol: framing, AES-256-CTR encryption, HMAC-SHA2-256 integrity,...
void pc_ssh_server_set_emit_cb(SshEmitCb cb)
Install the outbound-message callback.
int pc_ssh_server_dispatch(uint8_t i, uint8_t msg_type, const uint8_t *payload, size_t len)
Dispatch one decrypted inbound SSH message for slot i.
SSH message dispatcher - ties the transport, auth, and channel layers into one server state machine.
int ssh_transport_recv_banner(uint8_t i, const uint8_t *data, size_t len, size_t *consumed)
Feed raw bytes while awaiting the client identification string.
int ssh_transport_begin_rekey(uint8_t i, uint8_t *out, size_t *out_len, size_t cap)
Begin a server-initiated re-key by emitting a fresh KEXINIT.
bool ssh_rekey_due(uint32_t seq_send, uint32_t seq_recv, uint32_t elapsed_ms, uint32_t pkt_threshold, uint32_t time_threshold_ms)
Pure re-key decision (RFC 4253 §9: "after each gigabyte ... or after each hour").
SshSession ssh_sess[MAX_SSH_CONNS]
Static pool of SSH session state (BSS), one per SSH slot.
void ssh_transport_init(uint8_t i)
Reset transport state for slot i to the start of a handshake.
int ssh_transport_server_banner(uint8_t *out, size_t *out_len, size_t cap)
Write the server identification string ("SSH-2.0-…\r\n") to out.
SSH transport-layer protocol state machine (RFC 4253).
@ SSH_PHASE_KEXINIT
Awaiting the client KEXINIT.
@ SSH_PHASE_OPEN
Authenticated; connection/channel protocol active.
@ SSH_PHASE_BANNER
Awaiting the client identification string.
Per-protocol connection event/poll callbacks (Layer 5 dispatch vtable).
volatile bool close[MAX_SSH_CONNS]
uint8_t conn_for_ssh[MAX_SSH_CONNS]
bool kex_active
True while KEX is in progress (no user data).
SshPhase phase
Current handshake phase.
uint32_t last_kex_ms
pc_millis() when the last KEX completed (server-initiated re-key timer).
A single TCP connection context.
uint8_t id
Fixed slot index (0 … MAX_CONNS-1).
uint8_t proto_slot
Per-protocol session/pool index (0xFF = none): the SSH session, an MQTT/Modbus session,...
TcpConn conn_pool[CONN_POOL_SLOTS]
Static pool of connection contexts. Defined in tcp.cpp. Sized CONN_POOL_SLOTS: MAX_CONNS TCP slots pl...
void pc_conn_flush(uint8_t slot)
Flush queued bytes / finish the send on slot (TLS-aware).
void pc_conn_close(uint8_t slot)
Close connection slot gracefully (tcp_close), aborting if the FIN cannot be queued....
bool pc_conn_send(uint8_t slot, const void *data, u16_t len)
Send len bytes on connection slot (copies data; TLS-aware).
Layer 4 (Transport) - TCP connection pool, ring buffers, and lwIP integration.
#define PC_PROTO_SLOT_NONE
Sentinel for TcpConn::proto_slot meaning "no per-protocol session bound".