wired
libc-free QUIC/HTTP3 SDK in C for x86_64-linux
Loading...
Searching...
No Matches
wtcapsule.h File Reference

draft-ietf-webtrans-http3-15 SS4.2/SS5.6: the WebTransport-specific capsule types layered on top of the generic RFC 9297 Capsule Protocol codec (app/http3/core/capsule/capsule.h). More...

Go to the source code of this file.

Macros

#define WTCAPSULE_CLOSE_MESSAGE_MAX   1024
 Maximum WT_CLOSE_SESSION application error message length, in bytes (draft-ietf-webtrans-http3-15 SS4.2).
#define WTCAPSULE_CLOSE_CODE_LEN   4
 WT_CLOSE_SESSION's fixed Application Error Code field length, in bytes – the message starts right after it within the capsule's decoded value (draft-ietf-webtrans-http3-16 SS6).
#define WTCAPSULE_TYPE_MAX_STREAMS_BIDI   0x190B4D3FULL
 WT_MAX_STREAMS capsule type, bidirectional variant (draft-ietf-webtrans-http3-15 SS5.6.2).
#define WTCAPSULE_TYPE_MAX_STREAMS_UNI   0x190B4D40ULL
 WT_MAX_STREAMS capsule type, unidirectional variant (draft-ietf-webtrans-http3-15 SS5.6.2).
#define WTCAPSULE_TYPE_STREAMS_BLOCKED_BIDI   0x190B4D43ULL
 WT_STREAMS_BLOCKED capsule type, bidirectional variant (draft-ietf-webtrans-http3-16 SS5.6.3).
#define WTCAPSULE_TYPE_STREAMS_BLOCKED_UNI   0x190B4D44ULL
 WT_STREAMS_BLOCKED capsule type, unidirectional variant (draft-ietf-webtrans-http3-16 SS5.6.3).
#define WTCAPSULE_TYPE_MAX_DATA   0x190B4D3DULL
 WT_MAX_DATA capsule type (draft-ietf-webtrans-http3-15 SS5.6.4).
#define WTCAPSULE_TYPE_CLOSE   0x2843ULL
 WT_CLOSE_SESSION capsule type (draft-ietf-webtrans-http3-15 SS6).
#define WTCAPSULE_TYPE_DRAIN   0x78aeULL
 WT_DRAIN_SESSION capsule type (draft-ietf-webtrans-http3-15 SS4.6).

Functions

int wtcapsule_value_varint (wired_span value, u64 *v)
 1 iff value is exactly one well-formed varint (fully consumed, no trailing bytes) – the body shape every session flow-control capsule (SS5.6) requires.
int wired_wtcapsule_encode_close (wired_obuf *out, u32 app_error_code, wired_span message)
 Encode a WT_CLOSE_SESSION capsule (type 0x2843) into out.
int wtcapsule_encode_drain (wired_obuf *out)
 Encode a WT_DRAIN_SESSION capsule (type 0x78ae, empty body) into out.
int wired_wtcapsule_decode_close (wired_span data, usz *at, u32 *app_error_code, wired_span *message)
 Attempt to decode the capsule at *at within data as a WT_CLOSE_SESSION.
int wtcapsule_decode_drain (wired_span data, usz *at)
 Attempt to decode the capsule at *at within data as a WT_DRAIN_SESSION.
int wtcapsule_encode_max_streams (wired_obuf *out, int bidi, u64 max_streams)
 Encode a WT_MAX_STREAMS capsule (draft-ietf-webtrans-http3-15 SS5.6.2) into out: type 0x190B4D3F for bidi, 0x190B4D40 for uni, body a single varint (Maximum Streams).
int wtcapsule_decode_max_streams (wired_span data, usz *at, int bidi, u64 *max_streams)
 Attempt to decode the capsule at *at within data as a WT_MAX_STREAMS capsule of the given direction.
int wtcapsule_encode_streams_blocked (wired_obuf *out, int bidi, u64 max_streams)
 Encode a WT_STREAMS_BLOCKED capsule (SS5.6.3) into out: type 0x190B4D43 for bidi, 0x190B4D44 for uni, body a single varint (Maximum Streams).
int wtcapsule_decode_streams_blocked (wired_span data, usz *at, int bidi, u64 *max_streams)
 Attempt to decode the capsule at *at within data as a WT_STREAMS_BLOCKED capsule of the given direction.
int wtcapsule_encode_max_data (wired_obuf *out, u64 max_data)
 Encode a WT_MAX_DATA capsule (SS5.6.4, type 0x190B4D3D) into out: body a single varint (Maximum Data, in bytes).
int wtcapsule_decode_max_data (wired_span data, usz *at, u64 *max_data)
 Attempt to decode the capsule at *at within data as a WT_MAX_DATA capsule.
int wtcapsule_encode_data_blocked (wired_obuf *out, u64 max_data)
 Encode a WT_DATA_BLOCKED capsule (SS5.6.5, type 0x190B4D41) into out: body a single varint (Maximum Data, the limit in effect when blocking occurred).
int wtcapsule_decode_data_blocked (wired_span data, usz *at, u64 *max_data)
 Attempt to decode the capsule at *at within data as a WT_DATA_BLOCKED capsule.
int wtcapsule_utf8_valid (wired_span msg)
 1 iff msg is structurally valid UTF-8 (RFC 3629): every byte either starts a correctly-shaped 1/2/3/4-byte sequence (lead byte in range, no overlong/surrogate/out-of-Unicode-range lead patterns) whose continuation bytes are all 0x80-0xBF, or is itself out of range.
usz wtcapsule_utf8_truncate_len (wired_span msg, usz cap)
 The largest prefix length of msg, <= cap, that ends on a whole UTF-8 character boundary – for truncating a UTF-8 string to a byte cap without splitting a multi-byte sequence (draft-ietf-webtrans-http3-16 SS6: the WT_CLOSE_SESSION sender's own MUST).

Detailed Description

draft-ietf-webtrans-http3-15 SS4.2/SS5.6: the WebTransport-specific capsule types layered on top of the generic RFC 9297 Capsule Protocol codec (app/http3/core/capsule/capsule.h).

This is the wire-format layer only – it does not call into the session state machine (session/ session.h) itself; a caller decodes a capsule here and then drives the session transition (e.g. wired_wt_session_drain) as a separate step.

WT_CLOSE_SESSION (type 0x2843): Application Error Code (32) Application Error Message (..) – UTF-8, MUST NOT exceed 1024 bytes

WT_DRAIN_SESSION (type 0x78ae): empty body (Length=0), purely a signal.

Session-level flow-control capsules (SS5.6), each body a single varint: WT_MAX_STREAMS (0x190B4D3F bidi, 0x190B4D40 uni): Maximum Streams WT_STREAMS_BLOCKED (0x190B4D43 bidi, 0x190B4D44 uni): Maximum Streams WT_MAX_DATA (0x190B4D3D): Maximum Data WT_DATA_BLOCKED (0x190B4D41): Maximum Data

Per-stream flow-control capsules (e.g. a hypothetical WT_MAX_STREAM_DATA / WT_STREAM_DATA_BLOCKED) are intentionally NOT declared here and never will be: the HTTP/3 WebTransport mapping (this draft) does not define them at all – they exist only in the sibling HTTP/2-based WebTransport mapping, which this SDK does not implement. Per-stream flow control on HTTP/3 is instead covered natively by QUIC's own MAX_STREAM_DATA frame at the transport layer (already implemented outside this file). Do not confuse this with the SESSION-level WT_MAX_DATA/WT_MAX_STREAMS family declared above, which the draft does define and this file implements.

Function Documentation

◆ wired_wtcapsule_decode_close()

int wired_wtcapsule_decode_close ( wired_span data,
usz * at,
u32 * app_error_code,
wired_span * message )

Attempt to decode the capsule at *at within data as a WT_CLOSE_SESSION.

"Wrong type, don't consume" contract: if a complete capsule is present at at but its type is not 0x2843, this returns 0 and *at, *app_error_code, *message are all left UNCHANGED – so a caller can go on to try a different decode_ function (e.g. wtcapsule_decode_drain) at the same, still-unconsumed offset. This differs from capsule_decode itself, which reports "no complete capsule yet" the same way it reports "wrong type" would be reported here: both leave *at untouched, so the two failure causes are indistinguishable to the caller by design (either way, nothing was consumed).

Also returns 0, *at unchanged, if the capsule IS type 0x2843 but malformed: its value is too short to hold the 32-bit error code, or its message exceeds WTCAPSULE_CLOSE_MESSAGE_MAX bytes.

Parameters
datathe buffer to decode from
atin/out cursor offset within data
app_error_codeset to the decoded error code on success
messageset to a view of the error message on success
Returns
1 on success, 0 otherwise (see above)

◆ wired_wtcapsule_encode_close()

int wired_wtcapsule_encode_close ( wired_obuf * out,
u32 app_error_code,
wired_span message )

Encode a WT_CLOSE_SESSION capsule (type 0x2843) into out.

Rejects (returns 0, leaves out unmodified) if message.n exceeds WTCAPSULE_CLOSE_MESSAGE_MAX – this is a WebTransport wire-format constraint, checked independently of whether out happens to have room.

Parameters
outdestination buffer view
app_error_code32-bit application error code
messageUTF-8 error message, message.n <= 1024 (may be empty)
Returns
1 on success, 0 if message is too long or it doesn't fit in out

◆ wtcapsule_decode_data_blocked()

int wtcapsule_decode_data_blocked ( wired_span data,
usz * at,
u64 * max_data )

Attempt to decode the capsule at *at within data as a WT_DATA_BLOCKED capsule.

Same contract as wtcapsule_decode_max_data.

Parameters
datathe buffer to decode from
atin/out cursor offset within data
max_dataset to the decoded Maximum Data value on success
Returns
1 on success, 0 otherwise

◆ wtcapsule_decode_drain()

int wtcapsule_decode_drain ( wired_span data,
usz * at )

Attempt to decode the capsule at *at within data as a WT_DRAIN_SESSION.

Same "wrong type / incomplete, don't consume" contract as wired_wtcapsule_decode_close – *at only advances on a confirmed WT_DRAIN_SESSION capsule.

Parameters
datathe buffer to decode from
atin/out cursor offset within data
Returns
1 if a WT_DRAIN_SESSION capsule was present and consumed, 0 otherwise

◆ wtcapsule_decode_max_data()

int wtcapsule_decode_max_data ( wired_span data,
usz * at,
u64 * max_data )

Attempt to decode the capsule at *at within data as a WT_MAX_DATA capsule.

Same "wrong type/incomplete, don't consume" contract as wired_wtcapsule_decode_close.

Parameters
datathe buffer to decode from
atin/out cursor offset within data
max_dataset to the decoded Maximum Data value on success
Returns
1 on success, 0 otherwise

◆ wtcapsule_decode_max_streams()

int wtcapsule_decode_max_streams ( wired_span data,
usz * at,
int bidi,
u64 * max_streams )

Attempt to decode the capsule at *at within data as a WT_MAX_STREAMS capsule of the given direction.

Same "wrong type/incomplete, don't consume" contract as wired_wtcapsule_decode_close.

Parameters
datathe buffer to decode from
atin/out cursor offset within data
bidinonzero to match the bidi type, 0 to match uni
max_streamsset to the decoded Maximum Streams value on success
Returns
1 on success, 0 otherwise

◆ wtcapsule_decode_streams_blocked()

int wtcapsule_decode_streams_blocked ( wired_span data,
usz * at,
int bidi,
u64 * max_streams )

Attempt to decode the capsule at *at within data as a WT_STREAMS_BLOCKED capsule of the given direction.

Same contract as wtcapsule_decode_max_streams.

Parameters
datathe buffer to decode from
atin/out cursor offset within data
bidinonzero to match the bidi type, 0 to match uni
max_streamsset to the decoded Maximum Streams value on success
Returns
1 on success, 0 otherwise

◆ wtcapsule_encode_data_blocked()

int wtcapsule_encode_data_blocked ( wired_obuf * out,
u64 max_data )

Encode a WT_DATA_BLOCKED capsule (SS5.6.5, type 0x190B4D41) into out: body a single varint (Maximum Data, the limit in effect when blocking occurred).

Parameters
outdestination buffer view
max_datathe session-level data limit in effect when blocked
Returns
1 on success, 0 if it doesn't fit in out or max_data is out of varint range

◆ wtcapsule_encode_drain()

int wtcapsule_encode_drain ( wired_obuf * out)

Encode a WT_DRAIN_SESSION capsule (type 0x78ae, empty body) into out.

Parameters
outdestination buffer view
Returns
1 on success, 0 if it doesn't fit in out

◆ wtcapsule_encode_max_data()

int wtcapsule_encode_max_data ( wired_obuf * out,
u64 max_data )

Encode a WT_MAX_DATA capsule (SS5.6.4, type 0x190B4D3D) into out: body a single varint (Maximum Data, in bytes).

Parameters
outdestination buffer view
max_datacumulative session-level data limit
Returns
1 on success, 0 if it doesn't fit in out or max_data is out of varint range

◆ wtcapsule_encode_max_streams()

int wtcapsule_encode_max_streams ( wired_obuf * out,
int bidi,
u64 max_streams )

Encode a WT_MAX_STREAMS capsule (draft-ietf-webtrans-http3-15 SS5.6.2) into out: type 0x190B4D3F for bidi, 0x190B4D40 for uni, body a single varint (Maximum Streams).

Parameters
outdestination buffer view
bidinonzero for the bidirectional type, 0 for uni
max_streamscumulative stream limit (<= 2^60 per the draft; not independently validated here, wire-range only)
Returns
1 on success, 0 if it doesn't fit in out or max_streams is out of varint range

◆ wtcapsule_encode_streams_blocked()

int wtcapsule_encode_streams_blocked ( wired_obuf * out,
int bidi,
u64 max_streams )

Encode a WT_STREAMS_BLOCKED capsule (SS5.6.3) into out: type 0x190B4D43 for bidi, 0x190B4D44 for uni, body a single varint (Maximum Streams).

Parameters
outdestination buffer view
bidinonzero for the bidirectional type, 0 for uni
max_streamsthe stream limit in effect when blocking occurred
Returns
1 on success, 0 if it doesn't fit in out or max_streams is out of varint range

◆ wtcapsule_utf8_truncate_len()

usz wtcapsule_utf8_truncate_len ( wired_span msg,
usz cap )

The largest prefix length of msg, <= cap, that ends on a whole UTF-8 character boundary – for truncating a UTF-8 string to a byte cap without splitting a multi-byte sequence (draft-ietf-webtrans-http3-16 SS6: the WT_CLOSE_SESSION sender's own MUST).

Walks msg from the start, stopping before any sequence that would cross cap or at the first byte that starts no sequence (an invalid lead byte).

Parameters
msgthe UTF-8 bytes to truncate
capthe byte limit (msg.n itself if no truncation is needed)
Returns
the truncated length, <= cap and <= msg.n

◆ wtcapsule_utf8_valid()

int wtcapsule_utf8_valid ( wired_span msg)

1 iff msg is structurally valid UTF-8 (RFC 3629): every byte either starts a correctly-shaped 1/2/3/4-byte sequence (lead byte in range, no overlong/surrogate/out-of-Unicode-range lead patterns) whose continuation bytes are all 0x80-0xBF, or is itself out of range.

Used to validate the WT_CLOSE_SESSION Application Error Message (draft-ietf-webtrans-http3-16 SS6).

Parameters
msgthe candidate UTF-8 bytes
Returns
1 if valid, 0 otherwise

◆ wtcapsule_value_varint()

int wtcapsule_value_varint ( wired_span value,
u64 * v )

1 iff value is exactly one well-formed varint (fully consumed, no trailing bytes) – the body shape every session flow-control capsule (SS5.6) requires.

A receiver that already generically decoded a capsule (capsule_decode) uses this to validate a known flow-control type's body; failure means the capsule is malformed (RFC 9297 SS3.3), not merely incomplete.

Parameters
valuethe capsule's decoded value bytes
vset to the varint's value on success
Returns
1 on success, 0 if value is not exactly one varint