masque_compression_capsule (masque v0.7.0)
View SourceEncode/decode the three Compression Context capsules used by Connect-UDP-Bind (draft-ietf-masque-connect-udp-listen-11 sections 3.1 - 3.3):
COMPRESSION_ASSIGN(0x11) - Context ID + IP Version + (IP Address + UDP Port if Version != 0).COMPRESSION_ACK(0x12) - Context ID only.COMPRESSION_CLOSE(0x13) - Context ID only; zero is malformed.
Pure data: this module never touches state, transports or sessions. It only encodes / decodes wire bytes and validates the structural rules the draft pins on these capsule bodies. Lifecycle invariants (singleton uncompressed, parity, per-tuple uniqueness, post-close prohibition, ACK accounting) live in masque_compression_table.
Summary
Functions
Decode the body bytes of a Compression Context capsule into the matching record. The capsule type is determined by the caller from the capsule frame.
Encode a typed capsule record onto the RFC 9297 capsule frame.
Convenience: encode the body for a given capsule type atom.
Types
-type capsule_record() :: #compression_assign{context_id :: pos_integer(), ip_version :: 0 | 4 | 6, address :: undefined | inet:ip_address(), port :: undefined | inet:port_number()} | #compression_ack{context_id :: pos_integer()} | #compression_close{context_id :: pos_integer()}.
-type decode_error() ::
truncated | malformed_varint | bad_ip_version | zero_context_id | trailing_bytes |
bad_ip_address | bad_udp_port.
Functions
-spec decode_ack(binary()) -> {ok, #compression_ack{context_id :: pos_integer()}} | {error, decode_error()}.
-spec decode_assign(binary()) -> {ok, #compression_assign{context_id :: pos_integer(), ip_version :: 0 | 4 | 6, address :: undefined | inet:ip_address(), port :: undefined | inet:port_number()}} | {error, decode_error()}.
-spec decode_body(non_neg_integer(), binary()) -> {ok, capsule_record()} | {error, decode_error()}.
Decode the body bytes of a Compression Context capsule into the matching record. The capsule type is determined by the caller from the capsule frame.
-spec decode_close(binary()) -> {ok, #compression_close{context_id :: pos_integer()}} | {error, decode_error()}.
-spec encode(capsule_record()) -> iodata().
Encode a typed capsule record onto the RFC 9297 capsule frame.
-spec encode(assign | ack | close, capsule_record()) -> binary().
Convenience: encode the body for a given capsule type atom.
-spec encode_ack(#compression_ack{context_id :: pos_integer()}) -> binary().
-spec encode_assign(#compression_assign{context_id :: pos_integer(), ip_version :: 0 | 4 | 6, address :: undefined | inet:ip_address(), port :: undefined | inet:port_number()}) -> binary().
-spec encode_close(#compression_close{context_id :: pos_integer()}) -> binary().