ProtoCore v1.0.16
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
connection.h File Reference

RFC 4254 connection protocol: channel multiplexing, windows, and port forwarding. More...

Go to the source code of this file.

Classes

struct  SshFlow
 One channel's flow-control state (RFC 4254 sec 5.2). More...
 
struct  SshChannel
 Per-connection channel state. More...
 
struct  SshPtyRequest
 Open a server-initiated "forwarded-tcpip" channel (RFC 4254 §7.2, ssh -R). More...
 
struct  SshFlowArgs
 Dispatch messages 80 to 127 (RFC 4254). More...
 
struct  SshChanArgs
 RFC 4254 sec 5 channels: what a channel call acts on. More...
 
struct  SshPtyArgs
 RFC 4254 sec 6.2 pty-req and sec 6.7 window-change: what a terminal call parses. More...
 
struct  SshFwdArgs
 RFC 4254 sec 7 TCP/IP forwarding: what a forwarding call names. More...
 
struct  SshConnectionVars
 
struct  SshConnectionNs
 The entries. More...
 

Macros

#define SSH_CHANNEL_EOF_LEN   5u
 Install the sec 6.2 handler. Without one a "pty-req" is refused: no terminal exists.
 
#define SSH_CHANNEL_CLOSE_LEN   5u
 Bytes in SSH_MSG_CHANNEL_CLOSE: the message number and the recipient channel.
 

Typedefs

typedef enum PROTO_ENUM_PACKED SshChanType
 Channel type (RFC 4254).
 
typedef enum PROTO_ENUM_PACKED SshChanService
 What a session channel's sec 6 request bound to it, if anything.
 
typedef void(* SshChannelDataCb) (uint8_t slot, uint32_t channel, const uint8_t *data, size_t len)
 Application callback for inbound channel data (raw bytes), tagged with the channel id it arrived on.
 
typedef int(* SshForwardOpenCb) (uint8_t slot, uint32_t channel, const char *host, size_t host_len, uint16_t port)
 Install the inbound-data callback (session channels).
 
typedef void(* SshForwardDataCb) (uint8_t slot, uint32_t channel, const uint8_t *data, size_t len)
 Inbound data on a direct-tcpip channel (the owner writes it to the forwarded TCP socket). Kept separate from the session data callback.
 
typedef int(* SshRemoteForwardOpenCb) (uint8_t slot, const char *bind_addr, size_t addr_len, uint16_t bind_port)
 Install the direct-tcpip forward open-policy callback (opt-in).
 
typedef int(* SshRemoteForwardCancelCb) (uint8_t slot, const char *bind_addr, size_t addr_len, uint16_t bind_port)
 "cancel-tcpip-forward" request (RFC 4254 §7.1): drop a remote forward.
 
typedef void(* SshForwardConfirmCb) (uint8_t slot, uint32_t channel, proto_bool ok)
 Install the remote-forward (ssh -R) open-policy callback (opt-in).
 
typedef void(* SshSftpOpenCb) (uint8_t slot, uint32_t channel)
 Install the forwarded-tcpip open-confirmation callback (opt-in, ssh -R).
 
typedef void(* SshSftpDataCb) (uint8_t slot, uint32_t channel, const uint8_t *data, size_t len)
 Inbound bytes on an SFTP channel (the raw SSH_FXP_* stream) - kept out of the session data cb.
 
typedef void(* SshScpOpenCb) (uint8_t slot, uint32_t channel, const char *cmd, size_t cmd_len)
 An exec "scp …" request was accepted on channel (cmd is cmd_len bytes, not NUL-terminated).
 
typedef void(* SshScpDataCb) (uint8_t slot, uint32_t channel, const uint8_t *data, size_t len)
 Inbound bytes on an SCP channel (the RCP protocol stream).
 
typedef proto_bool(* SshPtyReqCb) (uint8_t i, uint32_t channel, const SshPtyRequest *pty)
 Walk an encoded terminal-mode stream (RFC 4254 sec 8) and report whether it is well formed.
 
typedef void(* SshWindowChangeCb) (uint8_t i, uint32_t channel, uint32_t width_chars, uint32_t height_rows, uint32_t width_px, uint32_t height_px)
 A "window-change" (sec 6.7) on a channel that already has a terminal.
 
typedef proto_bool(* SshForwardPolicyCb) (const char *host, uint16_t port)
 Build SSH_MSG_CHANNEL_DATA for channel and put it on the slot's stream (sec 5.2).
 

Enumerations

enum  PROTO_ENUM_PACKED {
  SSH_CHAN_SESSION = 0 , SSH_CHAN_DIRECT_TCPIP = 1 , SSH_CHAN_FORWARDED_TCPIP = 2 , SSH_CHAN_SERVICE_NONE = 0 ,
  SSH_CHAN_SERVICE_SFTP = 1 , SSH_CHAN_SERVICE_SCP = 2
}
 Channel type (RFC 4254). More...
 
enum  PROTO_ENUM_PACKED {
  SSH_CHAN_SESSION = 0 , SSH_CHAN_DIRECT_TCPIP = 1 , SSH_CHAN_FORWARDED_TCPIP = 2 , SSH_CHAN_SERVICE_NONE = 0 ,
  SSH_CHAN_SERVICE_SFTP = 1 , SSH_CHAN_SERVICE_SCP = 2
}
 What a session channel's sec 6 request bound to it, if anything. More...
 

Functions

int32_t protocore_ssh_sig_build_open_failure (uint8_t *out, size_t cap, uint32_t peer_id, uint32_t reason, size_t *out_len)
 Start a channel's windows: ours at local_window, the peer's at what it advertised.
 
int32_t protocore_ssh_sig_build_open_confirm (const SshFlow *f, uint32_t peer_id, uint32_t local_id, uint8_t *out, size_t cap, size_t *out_len)
 CHANNEL_OPEN_CONFIRMATION, advertising our current window and maximum packet size.
 
int32_t protocore_ssh_sig_build_data (SshFlow *f, uint32_t peer_id, const uint8_t *data, size_t len, uint8_t *out, size_t cap, size_t *out_len)
 CHANNEL_DATA carrying len bytes, and account them against the peer's window.
 
int32_t protocore_ssh_sig_build_window_adjust (uint32_t peer_id, uint32_t add, uint8_t *out, size_t cap, size_t *out_len)
 CHANNEL_WINDOW_ADJUST granting add more bytes. Credit the window only once this is sent.
 
int32_t protocore_ssh_sig_build_eof (uint32_t peer_id, uint8_t *out, size_t cap, size_t *out_len)
 CHANNEL_EOF, as one 5-byte message.
 
int32_t protocore_ssh_sig_build_close (uint32_t peer_id, uint8_t *out, size_t cap, size_t *out_len)
 CHANNEL_CLOSE, as one 5-byte message.
 
void protocore_ssh_connection_flow_init (uint8_t *work)
 
void protocore_ssh_connection_flow_recv_take (uint8_t *work)
 
void protocore_ssh_connection_flow_replenish_due (uint8_t *work)
 
void protocore_ssh_connection_flow_local_credit (uint8_t *work)
 
void protocore_ssh_connection_flow_send_allows (uint8_t *work)
 
void protocore_ssh_connection_flow_send_cap (uint8_t *work)
 
void protocore_ssh_connection_flow_send_take (uint8_t *work)
 
void protocore_ssh_connection_flow_peer_add (uint8_t *work)
 
void protocore_ssh_connection_channel_init (uint8_t *work)
 
void protocore_ssh_connection_chan_alloc (uint8_t *work)
 
void protocore_ssh_connection_chan_by_id (uint8_t *work)
 
void protocore_ssh_connection_channel_bind_service (uint8_t *work)
 
void protocore_ssh_connection_channel_handle_open (uint8_t *work)
 
void protocore_ssh_connection_channel_handle_open_confirm (uint8_t *work)
 
void protocore_ssh_connection_channel_handle_open_failure (uint8_t *work)
 
void protocore_ssh_connection_channel_handle_request (uint8_t *work)
 
void protocore_ssh_connection_channel_handle_data (uint8_t *work)
 
void protocore_ssh_connection_channel_handle_extended_data (uint8_t *work)
 
void protocore_ssh_connection_channel_handle_window_adjust (uint8_t *work)
 
void protocore_ssh_connection_channel_handle_eof (uint8_t *work)
 
void protocore_ssh_connection_channel_handle_close (uint8_t *work)
 
void protocore_ssh_connection_channel_build_data (uint8_t *work)
 
void protocore_ssh_connection_channel_build_eof (uint8_t *work)
 
void protocore_ssh_connection_channel_build_close (uint8_t *work)
 
void protocore_ssh_connection_channel_send_data (uint8_t *work)
 
void protocore_ssh_connection_channel_send_eof (uint8_t *work)
 
void protocore_ssh_connection_channel_send_close (uint8_t *work)
 
void protocore_ssh_connection_channel_send_exit_status (uint8_t *work)
 
void protocore_ssh_connection_channel_send_exit_signal (uint8_t *work)
 
void protocore_ssh_connection_channel_open_forwarded (uint8_t *work)
 
void protocore_ssh_connection_channel_send_open_forwarded (uint8_t *work)
 
void protocore_ssh_connection_channel_pty (uint8_t *work)
 
void protocore_ssh_connection_req_strings_present (uint8_t *work)
 
void protocore_ssh_connection_pty_req_fields_present (uint8_t *work)
 
void protocore_ssh_connection_pty_modes_valid (uint8_t *work)
 
void protocore_ssh_connection_pty_req_parse (uint8_t *work)
 
void protocore_ssh_connection_window_change_parse (uint8_t *work)
 
void protocore_ssh_connection_forward_begin (uint8_t *work)
 
void protocore_ssh_connection_forward_pump (uint8_t *work)
 
void protocore_ssh_connection_forward_binding (uint8_t *work)
 
void protocore_ssh_connection_forward_reset (uint8_t *work)
 
void protocore_ssh_connection_global_request_handle (uint8_t *work)
 
void protocore_ssh_connection_dispatch (uint8_t *work)
 
void protocore_ssh_connection_set_data_cb (uint8_t *work)
 
void protocore_ssh_connection_set_pty_req_cb (uint8_t *work)
 
void protocore_ssh_connection_set_window_change_cb (uint8_t *work)
 
void protocore_ssh_connection_set_forward_open_cb (uint8_t *work)
 
void protocore_ssh_connection_set_forward_data_cb (uint8_t *work)
 
void protocore_ssh_connection_set_forward_confirm_cb (uint8_t *work)
 
void protocore_ssh_connection_set_forward_policy_cb (uint8_t *work)
 
void protocore_ssh_connection_set_rforward_open_cb (uint8_t *work)
 
void protocore_ssh_connection_set_rforward_cancel_cb (uint8_t *work)
 
void protocore_ssh_connection_set_sftp_open_cb (uint8_t *work)
 
void protocore_ssh_connection_set_sftp_data_cb (uint8_t *work)
 
void protocore_ssh_connection_set_scp_open_cb (uint8_t *work)
 
void protocore_ssh_connection_set_scp_data_cb (uint8_t *work)
 
uint8_t * protocore_ssh_connection_span (void)
 The PROTOCORE_SSH_CONNECTION_BORROW bytes this module's state lives in.
 

Variables

SshChannel ssh_chan [MAX_SSH_CONNS][PROTOCORE_SSH_MAX_CHANNELS]
 Channel pool: PROTOCORE_SSH_MAX_CHANNELS channels per SSH connection (BSS). Owned by this layer; src/ code routes through the functions below, never the array (tests inspect it white-box). Index: [connection slot][channel slot].
 
SshConnectionVars SshConnectionV
 The operands and the outcome.
 

Detailed Description

RFC 4254 connection protocol: channel multiplexing, windows, and port forwarding.

Definition in file connection.h.

Macro Definition Documentation

◆ SSH_CHANNEL_EOF_LEN

#define SSH_CHANNEL_EOF_LEN   5u

Install the sec 6.2 handler. Without one a "pty-req" is refused: no terminal exists.

Install the sec 6.7 handler.

The terminal dimensions channel channel carries, or false when it has no pty.

Send "exit-status" for a command that has terminated (RFC 4254 sec 6.10).

"When the command running at the other end terminates, the following message can be sent to return the exit status of the command. Returning the status is RECOMMENDED. No acknowledgement is sent for this message. The channel needs to be closed with SSH_MSG_CHANNEL_CLOSE after this message." want_reply is FALSE, as the section fixes it.

Returns
0 on success, -1 when the channel is closed or the stream is gone.

Send "exit-signal" for a command killed by a signal (RFC 4254 sec 6.10).

Parameters
signal_nameSignal name without the "SIG" prefix, as sec 6.10 lists them.
core_dumpedWhether the command dumped core.
err_msgError message in UTF-8; may be null for an empty one.
Returns
0 on success, -1 when the channel is closed, the stream is gone, or the names do not fit.

Handle SSH_MSG_CHANNEL_REQUEST.

"shell", "exec", "pty-req", and "env" are accepted; anything else is refused - except that when PROTOCORE_ENABLE_SSH_SFTP is set a subsystem "sftp" is accepted (the channel binds SSH_CHAN_SERVICE_SFTP and the sftp-open callback fires), and when PROTOCORE_ENABLE_SSH_SCP is set an exec "scp …" is additionally tagged SSH_CHAN_SERVICE_SCP (the scp-open callback fires with the command). When want_reply is set, CHANNEL_SUCCESS / CHANNEL_FAILURE is written to out and *out_len > 0; otherwise *out_len is 0.

Returns
0 on success, -1 if malformed.

Handle SSH_MSG_CHANNEL_DATA: bounds-check, update the window, and invoke the data callback. If the local window is exhausted a CHANNEL_WINDOW_ADJUST is written to out (*out_len > 0).

Returns
0 on success, -1 if malformed or channel not open.

Handle SSH_MSG_CHANNEL_EXTENDED_DATA (RFC 4254 §5.2): bounds-check, update the window, and discard the payload. The data_type_code selects a stream this end does not surface, so the bytes are accounted for and dropped. If the local window is exhausted a CHANNEL_WINDOW_ADJUST is written to out (*out_len > 0).

Returns
0 on success, -1 if malformed or channel not open.

Build an SSH_MSG_CHANNEL_DATA message carrying data to the client on channel channel (a local channel id from a prior open).

Returns
0 on success, -1 if the channel is closed/unknown, the peer window is too small, or out is too small.

Handle SSH_MSG_CHANNEL_WINDOW_ADJUST (grows the peer window).

Returns
0 on success, -1 if malformed.

Build SSH_MSG_CHANNEL_EOF for channel channel and latch that we sent it. The channel stays open (RFC 4254 sec 5.3).

Returns
0 on success, -1 if the channel is closed/unknown or out is too small.

Build SSH_MSG_CHANNEL_CLOSE for channel channel and mark it closed.

Returns
0 on success, -1 if the channel is closed/unknown or out is too small.

Bytes in SSH_MSG_CHANNEL_EOF: the message number and the recipient channel.

Definition at line 477 of file connection.h.

◆ SSH_CHANNEL_CLOSE_LEN

#define SSH_CHANNEL_CLOSE_LEN   5u

Bytes in SSH_MSG_CHANNEL_CLOSE: the message number and the recipient channel.

Definition at line 480 of file connection.h.

Typedef Documentation

◆ SshChanType

Channel type (RFC 4254).

◆ SshChanService

What a session channel's sec 6 request bound to it, if anything.

These are not channel types: sec 5.1 names the type on the wire, and a file-transfer service is a sec 6.5 "subsystem" or exec request arriving later on a channel already open as "session". The type says how the channel was opened; this says what its data means.

◆ SshChannelDataCb

typedef void(* SshChannelDataCb) (uint8_t slot, uint32_t channel, const uint8_t *data, size_t len)

Application callback for inbound channel data (raw bytes), tagged with the channel id it arrived on.

Definition at line 187 of file connection.h.

◆ SshForwardOpenCb

typedef int(* SshForwardOpenCb) (uint8_t slot, uint32_t channel, const char *host, size_t host_len, uint16_t port)

Install the inbound-data callback (session channels).

"direct-tcpip" forward request: a client asked the server to open a TCP connection to host : port (ssh -L). The forwarding owner (which does the actual TCP I/O - this codec does not) decides whether to allow it; host is not NUL-terminated (host_len bytes).

Returns
0 to accept (the channel is opened and confirmed), < 0 to refuse (CHANNEL_OPEN_FAILURE, administratively prohibited / connect failed).

If no callback is installed, all forward requests are refused - so forwarding is opt-in (no open relay by default).

Definition at line 201 of file connection.h.

◆ SshForwardDataCb

typedef void(* SshForwardDataCb) (uint8_t slot, uint32_t channel, const uint8_t *data, size_t len)

Inbound data on a direct-tcpip channel (the owner writes it to the forwarded TCP socket). Kept separate from the session data callback.

Definition at line 204 of file connection.h.

◆ SshRemoteForwardOpenCb

typedef int(* SshRemoteForwardOpenCb) (uint8_t slot, const char *bind_addr, size_t addr_len, uint16_t bind_port)

Install the direct-tcpip forward open-policy callback (opt-in).

Install the direct-tcpip forward inbound-data callback.

"tcpip-forward" remote-forward request (ssh -R): the client asks the server to listen on bind_addr : bind_port and open a channel back for each accepted connection (RFC 4254 §7.1). bind_addr is addr_len bytes (not NUL-terminated). The forwarding owner (which allocates the real listener - this codec does no I/O) decides.

Returns
the bound port on success (echo bind_port, or the port the owner picked when bind_port == 0), or < 0 to refuse. If no callback is installed every request is refused, so remote forwarding is opt-in (no listener is opened).

Definition at line 219 of file connection.h.

◆ SshRemoteForwardCancelCb

typedef int(* SshRemoteForwardCancelCb) (uint8_t slot, const char *bind_addr, size_t addr_len, uint16_t bind_port)

"cancel-tcpip-forward" request (RFC 4254 §7.1): drop a remote forward.

Returns
0 if a matching forward was cancelled, < 0 if none / unsupported.

Definition at line 222 of file connection.h.

◆ SshForwardConfirmCb

typedef void(* SshForwardConfirmCb) (uint8_t slot, uint32_t channel, proto_bool ok)

Install the remote-forward (ssh -R) open-policy callback (opt-in).

Install the remote-forward (ssh -R) cancel callback (opt-in).

Result of the client's reply to a server-initiated forwarded-tcpip channel: ok = true on CHANNEL_OPEN_CONFIRMATION (the bridge may start), false on CHANNEL_OPEN_FAILURE (the owner tears the bridge down). channel is the local id returned by protocore_ssh_channel_open_forwarded().

Definition at line 233 of file connection.h.

◆ SshSftpOpenCb

typedef void(* SshSftpOpenCb) (uint8_t slot, uint32_t channel)

Install the forwarded-tcpip open-confirmation callback (opt-in, ssh -R).

A subsystem "sftp" request was accepted on channel; the binding starts an SFTP session.

Definition at line 237 of file connection.h.

◆ SshSftpDataCb

typedef void(* SshSftpDataCb) (uint8_t slot, uint32_t channel, const uint8_t *data, size_t len)

Inbound bytes on an SFTP channel (the raw SSH_FXP_* stream) - kept out of the session data cb.

Definition at line 239 of file connection.h.

◆ SshScpOpenCb

typedef void(* SshScpOpenCb) (uint8_t slot, uint32_t channel, const char *cmd, size_t cmd_len)

An exec "scp …" request was accepted on channel (cmd is cmd_len bytes, not NUL-terminated).

Definition at line 247 of file connection.h.

◆ SshScpDataCb

typedef void(* SshScpDataCb) (uint8_t slot, uint32_t channel, const uint8_t *data, size_t len)

Inbound bytes on an SCP channel (the RCP protocol stream).

Definition at line 249 of file connection.h.

◆ SshPtyReqCb

typedef proto_bool(* SshPtyReqCb) (uint8_t i, uint32_t channel, const SshPtyRequest *pty)

Walk an encoded terminal-mode stream (RFC 4254 sec 8) and report whether it is well formed.

"Opcodes 1 to 159 have a single uint32 argument. Opcodes 160 to 255 are not yet defined, and cause parsing to stop... The stream is terminated by opcode TTY_OP_END (0x00)." Only a truncated argument makes a stream malformed. A stream that runs out before its terminator is accepted for what it did carry, and an empty one is well formed: it sets no modes.

Parameters
modesEncoded stream.
lenBytes in modes.
consumedSet to the bytes parsed before TTY_OP_END or an undefined opcode. May be null.

Parse a "pty-req" body (sec 6.2) starting at off.

Returns
true when every field is present and whole and the mode stream parses.

Parse a "window-change" body (sec 6.7): four uint32 dimensions, no reply.

Returns
true when all four are present.

An accepted "pty-req" on channel channel. Return false to refuse the terminal.

Definition at line 379 of file connection.h.

◆ SshWindowChangeCb

typedef void(* SshWindowChangeCb) (uint8_t i, uint32_t channel, uint32_t width_chars, uint32_t height_rows, uint32_t width_px, uint32_t height_px)

A "window-change" (sec 6.7) on a channel that already has a terminal.

Definition at line 382 of file connection.h.

◆ SshForwardPolicyCb

typedef proto_bool(* SshForwardPolicyCb) (const char *host, uint16_t port)

Build SSH_MSG_CHANNEL_DATA for channel and put it on the slot's stream (sec 5.2).

Returns
the bytes accepted from data, -1 when the stream is gone or the build failed.

Build SSH_MSG_CHANNEL_EOF for channel and put it on the slot's stream (sec 5.3).

Returns
0 on success, -1 otherwise.

Build SSH_MSG_CHANNEL_CLOSE for channel and put it on the slot's stream (sec 5.3).

Returns
0 on success, -1 otherwise.

Open a "forwarded-tcpip" channel to the peer and put it on the slot's stream (sec 7.2).

Returns
the local channel number on success, -1 when the pool is full or the stream is gone.

Handle an inbound SSH_MSG_CHANNEL_EOF: mark the peer done sending on the recipient channel. Sends nothing and leaves the channel open, so the other direction keeps carrying data (RFC 4254 sec 5.3).

Returns
0 on success, -1 if malformed or the channel is unknown.

Handle an inbound SSH_MSG_CHANNEL_CLOSE: route to the recipient channel, reply with EOF + CLOSE, and mark it closed.

Returns
0 if a response was produced, -1 if malformed or the channel is unknown.

Allow/deny policy for a forward target. Return true to permit the connect.

host is NUL-terminated. If no policy is installed every post-authentication forward is permitted (an open proxy for authenticated users) - install one to the reachable host:port set.

Definition at line 526 of file connection.h.

Enumeration Type Documentation

◆ PROTO_ENUM_PACKED [1/2]

Channel type (RFC 4254).

Enumerator
SSH_CHAN_SESSION 

"session" - shell / exec / data

SSH_CHAN_DIRECT_TCPIP 

"direct-tcpip" - client-initiated TCP forward (ssh -L)

SSH_CHAN_FORWARDED_TCPIP 

"forwarded-tcpip" - server-initiated TCP forward (ssh -R)

SSH_CHAN_SERVICE_NONE 

shell / exec output, handed to the channel-data callback

SSH_CHAN_SERVICE_SFTP 

subsystem "sftp" (PROTOCORE_ENABLE_SSH_SFTP)

SSH_CHAN_SERVICE_SCP 

exec "scp ..." (PROTOCORE_ENABLE_SSH_SCP)

Definition at line 133 of file connection.h.

◆ PROTO_ENUM_PACKED [2/2]

What a session channel's sec 6 request bound to it, if anything.

These are not channel types: sec 5.1 names the type on the wire, and a file-transfer service is a sec 6.5 "subsystem" or exec request arriving later on a channel already open as "session". The type says how the channel was opened; this says what its data means.

Enumerator
SSH_CHAN_SESSION 

"session" - shell / exec / data

SSH_CHAN_DIRECT_TCPIP 

"direct-tcpip" - client-initiated TCP forward (ssh -L)

SSH_CHAN_FORWARDED_TCPIP 

"forwarded-tcpip" - server-initiated TCP forward (ssh -R)

SSH_CHAN_SERVICE_NONE 

shell / exec output, handed to the channel-data callback

SSH_CHAN_SERVICE_SFTP 

subsystem "sftp" (PROTOCORE_ENABLE_SSH_SFTP)

SSH_CHAN_SERVICE_SCP 

exec "scp ..." (PROTOCORE_ENABLE_SSH_SCP)

Definition at line 147 of file connection.h.

Function Documentation

◆ protocore_ssh_sig_build_open_failure()

int32_t protocore_ssh_sig_build_open_failure ( uint8_t *  out,
size_t  cap,
uint32_t  peer_id,
uint32_t  reason,
size_t *  out_len 
)

Start a channel's windows: ours at local_window, the peer's at what it advertised.

The local window is a parameter rather than a baked-in constant because the server and the client advertise different sizes, and the value we replenish to must be the value we told the peer about. Passing it here keeps the two from drifting apart.

Parameters
local_windowwhat we advertise in CHANNEL_OPEN / CONFIRMATION; also the replenish target.
peer_windowthe peer's initial window from CHANNEL_OPEN / CONFIRMATION.
peer_max_pktthe peer's maximum packet size from the same message.

Account n inbound bytes against our window.

Returns
false if n exceeds what we advertised - the peer overran the window (RFC 4254 sec 5.2) and the caller must fail the channel. The window is left untouched on failure.

Decide whether a WINDOW_ADJUST is due, and for how much. Does not mutate.

Replenishes once the window has drained past half, which keeps a bulk transfer from stalling without emitting an adjust per packet.

Pair it with protocore_ssh_flow_local_credit() only after the adjust has actually gone out. Deciding and crediting are separate because on some paths the send can fail, and crediting first would leave us believing we advertised bytes the peer never heard about - the peer then stops at its smaller window while we wait for data, and the transfer deadlocks.

Returns
true if a WINDOW_ADJUST is due; *add receives the delta to advertise.

Credit our window by add, once that WINDOW_ADJUST has actually been sent.

True if len bytes fit both the peer's remaining window and its maximum packet size.

Clamp a would-be send to what the peer currently permits.

A producer that pulls from a local source sizes its read to this, so it never reads bytes it cannot legally forward. Returns 0 when the window is closed, which the caller treats as "stop pumping until a WINDOW_ADJUST arrives".

Returns
min(want, peer window, peer maximum packet size).

Account n outbound bytes against the peer's window (call only after send_allows()).

Credit the peer's window from an inbound WINDOW_ADJUST.

Saturates at UINT32_MAX rather than wrapping: a peer advertising a total past 2^32 is out of spec, and wrapping would hand us a tiny window and stall the transfer.

CHANNEL_OPEN_FAILURE. reason: 1 admin-prohibited, 2 connect-failed, 3 unknown-type, 4 resource.

◆ protocore_ssh_sig_build_open_confirm()

int32_t protocore_ssh_sig_build_open_confirm ( const SshFlow *  f,
uint32_t  peer_id,
uint32_t  local_id,
uint8_t *  out,
size_t  cap,
size_t *  out_len 
)

CHANNEL_OPEN_CONFIRMATION, advertising our current window and maximum packet size.

◆ protocore_ssh_sig_build_data()

int32_t protocore_ssh_sig_build_data ( SshFlow *  f,
uint32_t  peer_id,
const uint8_t *  data,
size_t  len,
uint8_t *  out,
size_t  cap,
size_t *  out_len 
)

CHANNEL_DATA carrying len bytes, and account them against the peer's window.

Refuses when the send would exceed the peer's window or its maximum packet size, so the RFC 4254 sec 5.2 limit cannot be violated by any caller - the check and the debit are one step here.

◆ protocore_ssh_sig_build_window_adjust()

int32_t protocore_ssh_sig_build_window_adjust ( uint32_t  peer_id,
uint32_t  add,
uint8_t *  out,
size_t  cap,
size_t *  out_len 
)

CHANNEL_WINDOW_ADJUST granting add more bytes. Credit the window only once this is sent.

◆ protocore_ssh_sig_build_eof()

int32_t protocore_ssh_sig_build_eof ( uint32_t  peer_id,
uint8_t *  out,
size_t  cap,
size_t *  out_len 
)

CHANNEL_EOF, as one 5-byte message.

◆ protocore_ssh_sig_build_close()

int32_t protocore_ssh_sig_build_close ( uint32_t  peer_id,
uint8_t *  out,
size_t  cap,
size_t *  out_len 
)

CHANNEL_CLOSE, as one 5-byte message.

◆ protocore_ssh_connection_flow_init()

void protocore_ssh_connection_flow_init ( uint8_t *  work)

◆ protocore_ssh_connection_flow_recv_take()

void protocore_ssh_connection_flow_recv_take ( uint8_t *  work)

◆ protocore_ssh_connection_flow_replenish_due()

void protocore_ssh_connection_flow_replenish_due ( uint8_t *  work)

◆ protocore_ssh_connection_flow_local_credit()

void protocore_ssh_connection_flow_local_credit ( uint8_t *  work)

◆ protocore_ssh_connection_flow_send_allows()

void protocore_ssh_connection_flow_send_allows ( uint8_t *  work)

◆ protocore_ssh_connection_flow_send_cap()

void protocore_ssh_connection_flow_send_cap ( uint8_t *  work)

◆ protocore_ssh_connection_flow_send_take()

void protocore_ssh_connection_flow_send_take ( uint8_t *  work)

◆ protocore_ssh_connection_flow_peer_add()

void protocore_ssh_connection_flow_peer_add ( uint8_t *  work)

◆ protocore_ssh_connection_channel_init()

void protocore_ssh_connection_channel_init ( uint8_t *  work)

◆ protocore_ssh_connection_chan_alloc()

void protocore_ssh_connection_chan_alloc ( uint8_t *  work)

◆ protocore_ssh_connection_chan_by_id()

void protocore_ssh_connection_chan_by_id ( uint8_t *  work)

◆ protocore_ssh_connection_channel_bind_service()

void protocore_ssh_connection_channel_bind_service ( uint8_t *  work)

◆ protocore_ssh_connection_channel_handle_open()

void protocore_ssh_connection_channel_handle_open ( uint8_t *  work)

◆ protocore_ssh_connection_channel_handle_open_confirm()

void protocore_ssh_connection_channel_handle_open_confirm ( uint8_t *  work)

◆ protocore_ssh_connection_channel_handle_open_failure()

void protocore_ssh_connection_channel_handle_open_failure ( uint8_t *  work)

◆ protocore_ssh_connection_channel_handle_request()

void protocore_ssh_connection_channel_handle_request ( uint8_t *  work)

◆ protocore_ssh_connection_channel_handle_data()

void protocore_ssh_connection_channel_handle_data ( uint8_t *  work)

◆ protocore_ssh_connection_channel_handle_extended_data()

void protocore_ssh_connection_channel_handle_extended_data ( uint8_t *  work)

◆ protocore_ssh_connection_channel_handle_window_adjust()

void protocore_ssh_connection_channel_handle_window_adjust ( uint8_t *  work)

◆ protocore_ssh_connection_channel_handle_eof()

void protocore_ssh_connection_channel_handle_eof ( uint8_t *  work)

◆ protocore_ssh_connection_channel_handle_close()

void protocore_ssh_connection_channel_handle_close ( uint8_t *  work)

◆ protocore_ssh_connection_channel_build_data()

void protocore_ssh_connection_channel_build_data ( uint8_t *  work)

◆ protocore_ssh_connection_channel_build_eof()

void protocore_ssh_connection_channel_build_eof ( uint8_t *  work)

◆ protocore_ssh_connection_channel_build_close()

void protocore_ssh_connection_channel_build_close ( uint8_t *  work)

◆ protocore_ssh_connection_channel_send_data()

void protocore_ssh_connection_channel_send_data ( uint8_t *  work)

◆ protocore_ssh_connection_channel_send_eof()

void protocore_ssh_connection_channel_send_eof ( uint8_t *  work)

◆ protocore_ssh_connection_channel_send_close()

void protocore_ssh_connection_channel_send_close ( uint8_t *  work)

◆ protocore_ssh_connection_channel_send_exit_status()

void protocore_ssh_connection_channel_send_exit_status ( uint8_t *  work)

◆ protocore_ssh_connection_channel_send_exit_signal()

void protocore_ssh_connection_channel_send_exit_signal ( uint8_t *  work)

◆ protocore_ssh_connection_channel_open_forwarded()

void protocore_ssh_connection_channel_open_forwarded ( uint8_t *  work)

◆ protocore_ssh_connection_channel_send_open_forwarded()

void protocore_ssh_connection_channel_send_open_forwarded ( uint8_t *  work)

◆ protocore_ssh_connection_channel_pty()

void protocore_ssh_connection_channel_pty ( uint8_t *  work)

◆ protocore_ssh_connection_req_strings_present()

void protocore_ssh_connection_req_strings_present ( uint8_t *  work)

◆ protocore_ssh_connection_pty_req_fields_present()

void protocore_ssh_connection_pty_req_fields_present ( uint8_t *  work)

◆ protocore_ssh_connection_pty_modes_valid()

void protocore_ssh_connection_pty_modes_valid ( uint8_t *  work)

◆ protocore_ssh_connection_pty_req_parse()

void protocore_ssh_connection_pty_req_parse ( uint8_t *  work)

◆ protocore_ssh_connection_window_change_parse()

void protocore_ssh_connection_window_change_parse ( uint8_t *  work)

◆ protocore_ssh_connection_forward_begin()

void protocore_ssh_connection_forward_begin ( uint8_t *  work)

◆ protocore_ssh_connection_forward_pump()

void protocore_ssh_connection_forward_pump ( uint8_t *  work)

◆ protocore_ssh_connection_forward_binding()

void protocore_ssh_connection_forward_binding ( uint8_t *  work)

◆ protocore_ssh_connection_forward_reset()

void protocore_ssh_connection_forward_reset ( uint8_t *  work)

◆ protocore_ssh_connection_global_request_handle()

void protocore_ssh_connection_global_request_handle ( uint8_t *  work)

◆ protocore_ssh_connection_dispatch()

void protocore_ssh_connection_dispatch ( uint8_t *  work)

◆ protocore_ssh_connection_set_data_cb()

void protocore_ssh_connection_set_data_cb ( uint8_t *  work)

◆ protocore_ssh_connection_set_pty_req_cb()

void protocore_ssh_connection_set_pty_req_cb ( uint8_t *  work)

◆ protocore_ssh_connection_set_window_change_cb()

void protocore_ssh_connection_set_window_change_cb ( uint8_t *  work)

◆ protocore_ssh_connection_set_forward_open_cb()

void protocore_ssh_connection_set_forward_open_cb ( uint8_t *  work)

◆ protocore_ssh_connection_set_forward_data_cb()

void protocore_ssh_connection_set_forward_data_cb ( uint8_t *  work)

◆ protocore_ssh_connection_set_forward_confirm_cb()

void protocore_ssh_connection_set_forward_confirm_cb ( uint8_t *  work)

◆ protocore_ssh_connection_set_forward_policy_cb()

void protocore_ssh_connection_set_forward_policy_cb ( uint8_t *  work)

◆ protocore_ssh_connection_set_rforward_open_cb()

void protocore_ssh_connection_set_rforward_open_cb ( uint8_t *  work)

◆ protocore_ssh_connection_set_rforward_cancel_cb()

void protocore_ssh_connection_set_rforward_cancel_cb ( uint8_t *  work)

◆ protocore_ssh_connection_set_sftp_open_cb()

void protocore_ssh_connection_set_sftp_open_cb ( uint8_t *  work)

◆ protocore_ssh_connection_set_sftp_data_cb()

void protocore_ssh_connection_set_sftp_data_cb ( uint8_t *  work)

◆ protocore_ssh_connection_set_scp_open_cb()

void protocore_ssh_connection_set_scp_open_cb ( uint8_t *  work)

◆ protocore_ssh_connection_set_scp_data_cb()

void protocore_ssh_connection_set_scp_data_cb ( uint8_t *  work)

◆ protocore_ssh_connection_span()

uint8_t * protocore_ssh_connection_span ( void  )

The PROTOCORE_SSH_CONNECTION_BORROW bytes this module's state lives in.

Stated beside the namespace rather than on it: an entry takes a borrow, and this is where that borrow comes from. Taken once from the end of the pool, which no mark and no release walks, so the state lasts the life of the program.

Returns
the span.

Variable Documentation

◆ ssh_chan

Channel pool: PROTOCORE_SSH_MAX_CHANNELS channels per SSH connection (BSS). Owned by this layer; src/ code routes through the functions below, never the array (tests inspect it white-box). Index: [connection slot][channel slot].

◆ SshConnectionV

SshConnectionVars SshConnectionV
extern

The operands and the outcome.