macula_dist_relay_protocol (macula v12.2.0)
View SourceControl protocol encoder/decoder for dist relay.
Stream 0 carries CBOR control messages. Each frame:
+----------+---------+ | Len (4B) | MsgPack | +----------+---------+
Len is big-endian uint32 of the msgpack payload size.
Message types: identify → identified tunnel_request → tunnel_ok | tunnel_error tunnel_close → (no reply) tunnel_notify → (relay → target, informs of incoming tunnel)
⚠ A reader refuses rather than carries on, on both counts, because what is at the far end of this channel is a relay: a forwarder, and not a thing to be trusted with the reader's memory or with where frames begin.
A LENGTH IS A PROMISE ABOUT BYTES THAT HAVE NOT ARRIVED. Without a cap, a length of 4 GiB is a reader that waits, holding everything that arrives meanwhile, and grows until the node dies. A control frame here carries at most a node name.
A FRAME THAT DOES NOT DECODE MEANS THE TWO ENDS NO LONGER AGREE WHERE FRAMES BEGIN. Skipping it and reading on takes the middle of something else for a length, so one bad frame becomes an endless run of them while the channel looks alive. The connection ends instead.
Summary
Functions
Extract zero or more complete frames from a buffer. {ok, Messages, Remaining} where Remaining is what is left of a frame that has not all arrived, or {error, Reason}, which ends the connection: a frame too large to be one of ours, or one whose bytes do not decode to a frame this protocol knows.
The largest control frame a reader accepts.
Types
-type control_msg() :: identify_msg() | identified_msg() | tunnel_request_msg() | tunnel_ok_msg() | tunnel_error_msg() | tunnel_close_msg() | tunnel_notify_msg().
-type identified_msg() :: #{type := identified, status := ok}.
-type identify_msg() :: #{type := identify, node_name := binary()}.
-type tunnel_close_msg() :: #{type := tunnel_close, tunnel_id := binary()}.
-type tunnel_error_msg() :: #{type := tunnel_error, reason := binary()}.
-type tunnel_ok_msg() :: #{type := tunnel_ok, tunnel_id := binary()}.
-type tunnel_request_msg() :: #{type := tunnel_request, target := binary()}.
Functions
-spec decode_buffer(binary()) -> {ok, [control_msg()], binary()} | {error, term()}.
Extract zero or more complete frames from a buffer. {ok, Messages, Remaining} where Remaining is what is left of a frame that has not all arrived, or {error, Reason}, which ends the connection: a frame too large to be one of ours, or one whose bytes do not decode to a frame this protocol knows.
-spec encode(control_msg()) -> binary().
-spec max_frame_bytes() -> pos_integer().
The largest control frame a reader accepts.