Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Protocol GClasses

Message framing and protocol parsing. Protocol GClasses sit between a transport (C_TCP) and the application logic, translating raw bytes into structured events.

Source: kernel/c/root-linux/src/c_prot_http_cl.c, c_prot_http_sr.c, c_prot_tcp4h.c, c_prot_raw.c, c_websocket.c


C_PROT_HTTP_CL

HTTP client protocol — sends requests and parses responses. Can deliver the body incrementally (raw_body_data) or as a complete message.

PropertyValue
StatesST_STOPPED, ST_DISCONNECTED, ST_WAIT_CONNECTED, ST_CONNECTED
Input eventsEV_SEND_MESSAGE, EV_CONNECTED, EV_DISCONNECTED, EV_RX_DATA, EV_TX_READY, EV_TIMEOUT
Output eventsEV_ON_MESSAGE, EV_ON_HEADER, EV_ON_OPEN, EV_ON_CLOSE

Key attributes

AttributeTypeDescription
urlstringHTTP endpoint URL.
timeout_inactivityintegerInactivity timeout in milliseconds (60000).
cert_pemstringTLS certificate (PEM).
cryptojsonTLS config forwarded to the bottom C_TCP for https:// URLs. Default {"ssl_use_system_ca": true, "ssl_verify_mode": "required"} — verifies the server cert against the system CA. Override with ssl_trusted_certificate for a private CA, or ssl_allow_insecure_client: true to skip verification (MITM risk).
raw_body_databoolTRUE to deliver body chunks incrementally.
subscriberpointerGobj receiving output events.

C_PROT_HTTP_SR

HTTP server protocol — parses incoming HTTP requests and produces structured events for the application.

PropertyValue
StatesST_STOPPED, ST_DISCONNECTED, ST_CONNECTED
Input eventsEV_SEND_MESSAGE, EV_CONNECTED, EV_DISCONNECTED, EV_RX_DATA, EV_TX_READY
Output eventsEV_ON_MESSAGE, EV_ON_HEADER, EV_ON_OPEN, EV_ON_CLOSE

Key attributes

AttributeTypeDescription
timeout_inactivityintegerInactivity timeout in seconds.
subscriberpointerGobj receiving output events.

C_PROT_TCP4H

Frame protocol with a 4-byte binary header containing the payload length. Works in both client and server modes.

PropertyValue
StatesST_DISCONNECTED, ST_WAIT_HANDSHAKE, ST_WAIT_FRAME_HEADER, ST_WAIT_PAYLOAD
Input eventsEV_SEND_MESSAGE, EV_CONNECTED, EV_DISCONNECTED, EV_RX_DATA, EV_TX_READY, EV_DROP, EV_TIMEOUT
Output eventsEV_ON_MESSAGE, EV_ON_OPEN, EV_ON_CLOSE

Key attributes

AttributeTypeDescription
urlstringConnection URL.
iamServerboolTRUE for server mode.
max_pkt_sizeintegerLargest payload of a frame, in bytes (default 0: what a gbuffer holds, the max block of the yuno less one byte; a bigger value is capped to that). A frame announced bigger closes the connection, with a warning (“tcp4h head too long”, with len and max). Up to 7.25.22 the default was the max block itself, and a frame of exactly that length never ended.
timeout_handshakeintegerHandshake timeout in milliseconds (default 30000).
timeout_payloadintegerMilliseconds to receive the rest of a frame whose header came (default 5000); when it runs out the connection is closed.
timeout_closeintegerMilliseconds a closing client waits for the server to drop the connection before it drops it itself (default 3000).
cert_pemstringTLS certificate (PEM).

The length of a frame is the peer’s word, in the 4-byte header (big-endian, counting the header itself) before any of its payload. The payload buffer starts at 4 KB and grows with what arrives, up to what the frame needs; up to 7.25.21 the whole length was reserved at the header, so a peer that wrote only headers announcing the max block reserved it each time, with no payload sent.

uint32_t len = htonl(payload_len + 4);      // the header counts itself
gbuffer_append(gbuf, &len, sizeof(len));
gbuffer_append(gbuf, payload, payload_len);

tests/c/c_prot_tcp4h (test1): a frame of 60000 bytes in three parts arrives whole, and the header of a frame of 10 MB with no payload does not grow the yuno’s memory.


C_PROT_RAW

Raw pass-through protocol — forwards data without adding or removing headers. Useful for transparent proxying.

PropertyValue
StatesST_STOPPED, ST_DISCONNECTED, ST_CONNECTED
Input eventsEV_SEND_MESSAGE, EV_CONNECTED, EV_DISCONNECTED, EV_RX_DATA, EV_TX_READY
Output eventsEV_ON_MESSAGE, EV_ON_OPEN, EV_ON_CLOSE

Key attributes

AttributeTypeDescription
subscriberpointerGobj receiving output events.

C_WEBSOCKET

WebSocket protocol (RFC 6455) — supports both client and server roles with frame masking, ping/pong, and graceful close handshake.

PropertyValue
StatesST_DISCONNECTED, ST_WAIT_HANDSHAKE, ST_WAIT_FRAME_HEADER, ST_WAIT_PAYLOAD
Input eventsEV_SEND_MESSAGE, EV_CONNECTED, EV_DISCONNECTED, EV_RX_DATA, EV_TX_READY, EV_DROP, EV_TIMEOUT
Output eventsEV_ON_MESSAGE, EV_ON_OPEN, EV_ON_CLOSE

Key attributes

AttributeTypeDescription
urlstringWebSocket URL (ws:// or wss://).
iamServerboolTRUE for server mode.
cert_pemstringTLS certificate (PEM).
timeout_handshakeintegerHandshake timeout in milliseconds (default 30000).
timeout_payloadintegerMilliseconds to receive the rest of a frame whose header came (default 5000); when it runs out the connection is closed.
timeout_closeintegerMilliseconds a closing client waits for the server to drop the connection before it drops it itself (default 3000).
pingTintegerPing interval in milliseconds (0 = disabled).
max_payload_sizeintegerLargest payload of a frame, in bytes (default 0: what a gbuffer holds, the max block of the yuno less one byte; a bigger value is capped to that -- up to 7.25.22 the default was the max block itself, and a frame of exactly that length never ended). A frame announced bigger is refused: a warning (“Websocket frame bigger than the max payload, connection closed”, with frame_length) and the connection closed with 1009.

The length of a frame is the peer’s word, written in its header before any of its payload. The payload buffer starts at 4 KB and grows with what arrives, up to what the frame needs (a frame of exactly max_payload_size included: up to 7.25.21 it never ended, a gbuffer holding one byte less than its max); up to 7.25.21 the whole length was reserved at the header, so a few connections that each announced the max block reserved it each with a few bytes sent.

{
    "name": "input",
    "gclass": "C_WEBSOCKET",
    "kw": {
        "iamServer": true,
        "max_payload_size": 1048576
    }
}

Closing

ws_close() -- a timeout, a protocol error, a received Close -- moves the gobj to ST_DISCONNECTED at once and sends its Close frame. A server drops the TCP connection there and then. A client keeps it, as RFC 6455 asks: the server closes the TCP connection (7.1.1), and an endpoint that sent a Close may go on receiving (5.5.1). The client drops it itself when timeout_close runs out (warning “Timeout waiting websocket disconnected”).

What arrives in between -- the rest of the frame the client gave up on, the server’s own Close -- belongs to a session that is over: it is discarded, and nothing is published (the debug trace level logs it). Up to 7.25.10 ST_DISCONNECTED did not declare EV_RX_DATA, and each such read logged “Event NOT DEFINED in state”; a controller too busy to read a frame in time showed it. A client configured to give a slow peer more time:

{
    "name": "output",
    "gclass": "C_WEBSOCKET",
    "kw": {
        "timeout_payload": 10000,
        "timeout_close": 5000
    }
}

Test: tests/c/c_websocket (test_websocket_test1).