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

RFC 9001 4 / 5 / RFC 9000 17.2: the socket-free core of the server wire loop. More...

#include "app/http3/core/h3/control.h"
#include "app/http3/core/h3/priority.h"
#include "app/http3/request/h3reqdrive/request_drive.h"
#include "app/http3/server/h3srv/state.h"
#include "common/bytes/span/span.h"
#include "tls/handshake/roles/server/server.h"
#include "transport/conn/pnspace/pnspaces/recv_spaces.h"
#include "transport/packet/frame/frame/connctl.h"
#include "transport/recovery/detect/recovery/ackpolicy.h"

Go to the source code of this file.

Data Structures

struct  wired_srvloop_stream_slot
 One request stream's cross-datagram reassembly state — everything the original single-stream wired_srvloop held, now per stream id. More...
struct  wired_srvloop_pending_priority
 One buffered PRIORITY_UPDATE naming a request stream this connection has not opened yet (RFC 9218 10 / 9218-010). More...
struct  wired_srvloop_ctrl_stream
 The peer's control stream, reassembled across datagrams (RFC 9000 2.2) past its leading type varint, so its HTTP/3 frames (SETTINGS, GOAWAY, PRIORITY_UPDATE, ...) can be walked once fully buffered up to parsed. More...
struct  wired_srvloop_wt_window
 One WT bidi/uni slot's receive-window bookkeeping, shared shape for both tables (see wired_srvloop_wt_stream_slot / _uni_stream_slot below). More...
struct  wired_srvloop_wt_stream_slot
 One WebTransport bidi stream's cross-datagram reassembly state (draft- ietf-webtrans-http3-15 4.3). More...
struct  wired_srvloop_wt_uni_stream_slot
 One WebTransport uni stream's cross-datagram reassembly state (draft-ietf- webtrans-http3-15 4.3). More...
struct  wired_srvloop_rx_datagram
 One queued received QUIC DATAGRAM frame's payload (RFC 9221 5). More...
struct  wired_srvloop
 Per-connection state of the server wire loop, re-armed by wired_srvloop_init and driven by wired_srvloop_step. More...
struct  wired_srvloop_conn
 The loop and its orchestrator, driven together through every wire step (mirrors wired_srvboot_conn, srvboot's cold-start counterpart). More...

Macros

#define WIRED_SRVLOOP_MAX_ACK_DELAY_MS   25
 RFC 9000 18.2's default max_ack_delay when the peer's own transport parameter isn't tracked (this SDK does not parse the client's max_ack_delay yet – YAGNI until a deployment needs a non-default value).
#define WIRED_SRVLOOP_MAX_STREAMS   40
 RFC 9000 2.2: how many client bidi (request) streams one connection can reassemble concurrently.
#define WIRED_SRVLOOP_MAX_PENDING_PRIORITY   8
 RFC 9218 7.1 / 10: how many PRIORITY_UPDATE frames naming a not-yet-open request stream one connection buffers (9218-010) until that stream is claimed.
#define WIRED_SRVLOOP_CTRL_BUF_CAP   512
 Byte capacity of the peer control stream's reassembly buffer (RFC 9114 6.2.1, RFC 9218 7.1).
#define WIRED_SRVLOOP_MAX_WT_STREAMS   6
 RFC 9000 2.2: how many concurrent WebTransport bidi streams (draft-ietf- webtrans-http3-15 4.3) one connection can reassemble.
#define WIRED_SRVLOOP_WT_BUF_CAP   49152
 Byte capacity of one WT bidi/uni reassembly slot's receive window (buf below).
#define WIRED_SRVLOOP_WT_MAX_RANGES   8
 How many disjoint received-but-not-yet-contiguous byte ranges one WT slot's window tracks past its frontier (see wired_srvloop_wt_window).
#define WIRED_SRVLOOP_MAX_WT_UNI_STREAMS   6
 draft-ietf-webtrans-http3-15 4.3: how many concurrent WebTransport uni streams (client-initiated, RFC 9000 2.1 low bits 10) one connection can reassemble.
#define WIRED_SRVLOOP_MAX_RX_DATAGRAMS   4
 RFC 9221 5: how many received QUIC DATAGRAM frames one connection queues before a future consumer (a WebTransport session, Phase 7b Slice 2) drains them.
#define WIRED_SRVLOOP_RX_DATAGRAM_CAP   1200
 Byte capacity of one queued received QUIC DATAGRAM's payload (RFC 9221 5/3).

Typedefs

typedef int(* wired_srvloop_handler) (void *ctx, const wired_h3reqdrive_req *req, u64 offset, quic_obuf *body_out, const char **content_type, int *more, u64 *total_size)
 Build (a round of) the response body for a decoded request.

Functions

void wired_srvloop_set_handler (wired_srvloop *l, wired_srvloop_handler cb, void *ctx)
 Register the app response-body builder; pass 0 to clear (body-less 200).
int wired_srvloop_init (wired_srvloop *l, const u8 *cli_scid, u8 cli_scid_len)
 Record the client's source connection id (the DCID for server-sent packets) and reset the HTTP/3 state.
int wired_srvloop_slot_for (wired_srvloop *l, u64 stream_id)
 RFC 9000 2.2: the streams[] slot reassembling request stream_id, allocating a free one on first sight – dispatch.c routes each request STREAM frame to its own stream's slot through this (a payload may coalesce frames of several request streams).
void wired_srvloop_priority_apply (wired_srvloop *l, u64 stream_id, const quic_h3_priority *p)
 RFC 9218 7.1 / 10: apply a validated PRIORITY_UPDATE (request variant) to stream_id – directly into its streams[] slot if already open, else buffered in pending_priority[] until wired_srvloop_slot_for later claims that stream id (9218-010).
int wired_srvloop_priority_of (const wired_srvloop *l, u64 stream_id, quic_h3_priority *out)
 RFC 9218 10: read stream_id's current priority (its RFC 9218 4.1 default until any PRIORITY_UPDATE or Priority header field changed it) without allocating a streams[] slot – the counterpart read used by a response scheduler (srvrun.c) ordering its send passes, as opposed to wired_srvloop_slot_for's claim-or-allocate used by the receive path.
void wired_srvloop_slot_release (wired_srvloop *l, u64 stream_id)
 RFC 9000 2.2: free the streams[] slot reassembling stream_id, once its response has been fully sent and acknowledged – called by the response driver (srvrun.c) so a stream id's slot becomes reusable for a later request.
int wired_srvloop_wt_slot_find (const wired_srvloop *l, u64 stream_id)
 draft-ietf-webtrans-http3-15 4.3: find the wt_streams slot already reassembling stream_id, so dispatch.c's gather_wt_stream can route a later (offset>0) frame into the same slot its signal frame claimed.
int wired_srvloop_wt_slot_claim (wired_srvloop *l, u64 stream_id)
 draft-ietf-webtrans-http3-15 4.3: claim and reset a free wt_streams slot for stream_id, called the first time a stream's leading 0x41 signal is recognized.
int wired_srvloop_wt_uni_slot_find (const wired_srvloop *l, u64 stream_id)
 draft-ietf-webtrans-http3-15 4.3: find the wt_uni_streams slot already reassembling stream_id, mirroring wired_srvloop_wt_slot_find for the separate uni table.
int wired_srvloop_wt_uni_slot_claim (wired_srvloop *l, u64 stream_id)
 draft-ietf-webtrans-http3-15 4.3: claim and reset a free wt_uni_streams slot for stream_id, called the first time a uni stream's leading type varint is recognized as 0x54, mirroring wired_srvloop_wt_slot_claim.
int wired_srvloop_wt_slot_claim_local (wired_srvloop *l, u64 stream_id)
 RFC 9000 2.1: pre-claim a wt_streams slot for a stream id THIS endpoint itself opened (a server-initiated bidi stream, id bits 01) – unlike wired_srvloop_wt_slot_claim, called before any frame for stream_id has arrived, with sig_len left 0 (no signal prefix: the peer's reply is raw application data from its own offset 0).
void wired_srvloop_wt_slot_release (wired_srvloop *l, u64 stream_id)
 draft-ietf-webtrans-http3-15 4.3: free the wt_streams[] slot reassembling stream_id once its FIN has been fully delivered to the app, mirroring wired_srvloop_slot_release for the WT bidi table.
void wired_srvloop_wt_uni_slot_release (wired_srvloop *l, u64 stream_id)
 Same as wired_srvloop_wt_slot_release, for the separate wt_uni_streams table.
void wired_srvloop_wt_window_accept (wired_srvloop_wt_window *win, u64 abs_off, usz n, usz *rel_off, usz *accepted_n)
 draft-ietf-webtrans-http3-15 4.3: clamp [abs_off, abs_off+n) to win's currently open window (drop the stale prefix already delivered/below win.base, and the part beyond win.base + WIRED_SRVLOOP_WT_BUF_CAP the peer has no granted credit for yet) and record the accepted portion into win's range set, recomputing win.frontier.
void wired_srvloop_wt_window_slide (wired_srvloop_wt_window *win, u8 *buf, usz cap, u64 delivered_to)
 draft-ietf-webtrans-http3-15 4.3 / RFC 9000 4.1: once delivered_to (an absolute offset, srvrun.c's own delivered_len) has consumed the whole current frontier, slide the window forward so buf has room for more – shift any bytes still buffered past the frontier (an out-of-order continuation already written ahead of a since-filled gap) down to buf[0], advance win.base by the delivered frontier, and rebase every range in win.ranges by the same amount.
int wired_srvloop_step (const wired_srvloop_conn *conn, quic_mspan dgram, quic_obuf *out)
 Drive one wire iteration: open dgram, dispatch it, and if the step produced a server-direction packet (HANDSHAKE_DONE once confirmed, or a 200 response to a decoded GET) seal it into out, setting out->len.
void wired_srvloop_ecn_note (wired_srvloop *l, u8 ecn)
 RFC 9000 13.4 / RFC 9002 19.3.2: add one received datagram's ECN codepoint (RFC 3168: 0 Not-ECT, 1 ECT(1), 2 ECT(0), 3 CE, matching quic_mmsg_buf.ecn in udp.h) to l's cumulative counts, which app_ack_encode_ranges (respond.c) later reports in the connection's 1-RTT ACK frames.

Detailed Description

RFC 9001 4 / 5 / RFC 9000 17.2: the socket-free core of the server wire loop.

One step opens an inbound datagram with the peer-direction key, dispatches its frames to the handshake or HTTP/3 layer, and seals the resulting outbound packet with the server's own-direction key for the level the conversation has reached. An example program wraps this in a UDP recv/send.

Macro Definition Documentation

◆ WIRED_SRVLOOP_CTRL_BUF_CAP

#define WIRED_SRVLOOP_CTRL_BUF_CAP   512

Byte capacity of the peer control stream's reassembly buffer (RFC 9114 6.2.1, RFC 9218 7.1).

Holds the stream's bytes AFTER the leading 0x00 type varint – SETTINGS plus any number of PRIORITY_UPDATE frames comfortably fit; a real peer's control stream is a handful of small frames, not a bulk transfer, so this need not match a WT stream's throughput-sized window.

◆ WIRED_SRVLOOP_MAX_ACK_DELAY_MS

#define WIRED_SRVLOOP_MAX_ACK_DELAY_MS   25

RFC 9000 18.2's default max_ack_delay when the peer's own transport parameter isn't tracked (this SDK does not parse the client's max_ack_delay yet – YAGNI until a deployment needs a non-default value).

Matches srvrun.c's own SRVRUN_MAX_ACK_DELAY_US (25000us = 25ms); kept as a separate constant here since srvloop must not depend on srvrun.

◆ WIRED_SRVLOOP_MAX_PENDING_PRIORITY

#define WIRED_SRVLOOP_MAX_PENDING_PRIORITY   8

RFC 9218 7.1 / 10: how many PRIORITY_UPDATE frames naming a not-yet-open request stream one connection buffers (9218-010) until that stream is claimed.

Small and fixed: a client reprioritizing a stream ahead of opening it is a corner case, not a bulk pattern, so this need not track WIRED_SRVLOOP_MAX_STREAMS' own sizing.

◆ WIRED_SRVLOOP_MAX_RX_DATAGRAMS

#define WIRED_SRVLOOP_MAX_RX_DATAGRAMS   4

RFC 9221 5: how many received QUIC DATAGRAM frames one connection queues before a future consumer (a WebTransport session, Phase 7b Slice 2) drains them.

Datagrams are unordered/unreliable per RFC 9221, so — unlike the single-slot send side — the receive side uses a small fixed queue rather than one overwritable slot: losing an already-arrived datagram to a same-step overwrite is a worse user-visible bug than the send side's "last write wins" (see rx_datagram_n's overflow policy below). 4 is an arbitrary small size, not a protocol limit; raise it if a real workload needs deeper queuing.

◆ WIRED_SRVLOOP_MAX_STREAMS

#define WIRED_SRVLOOP_MAX_STREAMS   40

RFC 9000 2.2: how many client bidi (request) streams one connection can reassemble concurrently.

40, not a handful: quic-interop-runner's zerortt testcase (TestCaseZeroRTT.NUM_FILES) opens 40 concurrent request streams in a single 0-RTT/1-RTT burst – a client that fires them all up front (quic-go does) never retries a stream this SDK's own slot table dropped, so anything short of 40 silently loses requests past the cap forever.

◆ WIRED_SRVLOOP_MAX_WT_STREAMS

#define WIRED_SRVLOOP_MAX_WT_STREAMS   6

RFC 9000 2.2: how many concurrent WebTransport bidi streams (draft-ietf- webtrans-http3-15 4.3) one connection can reassemble.

Separate from WIRED_SRVLOOP_MAX_STREAMS/wired_srvloop_stream_slot: a WT bidi stream's bytes past the leading 0x41 signal are raw application data with no HTTP/3 HEADERS/DATA framing, so they need no req_scratch/req_wrap-shaped fields. 6, not 4: quic-interop-runner's WebTransport transfer tests open 5 concurrent streams per session (100KB/250KB/500KB/1MB/2MB files) – 4 slots silently dropped the 5th.

◆ WIRED_SRVLOOP_MAX_WT_UNI_STREAMS

#define WIRED_SRVLOOP_MAX_WT_UNI_STREAMS   6

draft-ietf-webtrans-http3-15 4.3: how many concurrent WebTransport uni streams (client-initiated, RFC 9000 2.1 low bits 10) one connection can reassemble.

Separate table from wt_streams[] (bidi): a uni stream's directionality is structurally different (no response half), even though its post-type-byte bytes are raw application data just like a WT bidi stream's post-signal bytes. Same 6-not-4 sizing as WIRED_SRVLOOP_MAX_WT_ STREAMS, for the same reason (5 concurrent runner transfers).

◆ WIRED_SRVLOOP_RX_DATAGRAM_CAP

#define WIRED_SRVLOOP_RX_DATAGRAM_CAP   1200

Byte capacity of one queued received QUIC DATAGRAM's payload (RFC 9221 5/3).

1200 comfortably covers a max_datagram_frame_size-bounded HTTP Datagram (RFC 9297 2.1: quarter-stream-id varint, up to 8 bytes, plus up to ~998 bytes of application payload under a typical ~1200-byte max_datagram_frame_size) without truncating it on receive.

◆ WIRED_SRVLOOP_WT_BUF_CAP

#define WIRED_SRVLOOP_WT_BUF_CAP   49152

Byte capacity of one WT bidi/uni reassembly slot's receive window (buf below).

Sized past one full BDP for quic-interop-runner's simulated link (10Mbps/30ms RTT is ~37KB) so a single WT stream's throughput is not window-capped – with 5 streams sharing one connection's fair share of that link, a smaller window left several of quic-interop-runner's WebTransport send-mode transfer tests short of finishing inside its fixed per-test timeout (verified against a real webtransport-go run). Used to be kept at 4KB because wired_srvloop is embedded in srvrun_conn (6 bidi + 6 uni slots), and srvrun_test.c's test helpers used to stack-allocate a whole QUIC_CONNTABLE_CAP-sized connection table each – that allocation has since moved to static storage (matching production's own g_srvrun_env singleton, which was never on the stack to begin with), so this can now size for throughput instead of a stack budget it no longer shares.

◆ WIRED_SRVLOOP_WT_MAX_RANGES

#define WIRED_SRVLOOP_WT_MAX_RANGES   8

How many disjoint received-but-not-yet-contiguous byte ranges one WT slot's window tracks past its frontier (see wired_srvloop_wt_window).

RFC 9000 2.2 reassembly is offset-indexed and reordering-tolerant by design, so a lost-then-retransmitted frame routinely lands after a gap; a small fixed set (rather than one high-water mark) is what lets the frontier — and therefore delivery — advance correctly once the gap fills, instead of silently skipping the buffered-but-undelivered bytes past it.

Typedef Documentation

◆ wired_srvloop_handler

typedef int(* wired_srvloop_handler) (void *ctx, const wired_h3reqdrive_req *req, u64 offset, quic_obuf *body_out, const char **content_type, int *more, u64 *total_size)

Build (a round of) the response body for a decoded request.

Copy from req (its body is a view into per-step scratch, not valid past the call) into body_out, setting body_out->len. May set *content_type to a static NUL-terminated string to add a content-type field line; left unchanged (0) omits it.

offset is the count of response body bytes already delivered by prior rounds (0 on the first call for a request). A handler whose whole body fits in one round ignores offset and never touches *more or *total_size (both default to "done"/"unknown"): this is the common case and every existing handler's behavior is unchanged. A handler with more body than fits body_out's capacity writes as much as fits starting at offset, sets *more = 1, and (on the first round only, offset == 0) sets *total_size to the full body length if known – callers that frame the body with an upfront length field (e.g. HTTP/3's DATA frame) need this to write that length before any bytes are available. The caller then invokes this handler again with offset advanced by the bytes it just produced, repeating until *more is left 0.

Parameters
ctxthe opaque context registered with wired_srvloop_set_handler
reqthe decoded request; its views are not valid past the call
offsetresponse body bytes already delivered by prior rounds
body_outreceives this round's response body bytes
content_typereceives the content-type string, or left at its caller-supplied value (0) to omit the field line (only consulted on the first round, offset == 0)
morecaller-zeroed before the call; set to 1 to request another round starting at offset + body_out->len
total_sizecaller-zeroed before the call; on the first round (offset == 0) only, set to the full body length if known up front
Returns
1 to send the body, 0 for a body-less 200.

Function Documentation

◆ wired_srvloop_ecn_note()

void wired_srvloop_ecn_note ( wired_srvloop * l,
u8 ecn )

RFC 9000 13.4 / RFC 9002 19.3.2: add one received datagram's ECN codepoint (RFC 3168: 0 Not-ECT, 1 ECT(1), 2 ECT(0), 3 CE, matching quic_mmsg_buf.ecn in udp.h) to l's cumulative counts, which app_ack_encode_ranges (respond.c) later reports in the connection's 1-RTT ACK frames.

The caller driving the UDP receive loop (e.g. srvrun.c) calls this once per received datagram, ahead of or alongside wired_srvloop_step – the two are independent calls since wired_srvloop_step's dgram argument carries no ECN information itself. A Not-ECT (0) codepoint is a no-op: it advances none of the three counters.

Parameters
lthe loop whose cumulative counts to advance
ecnthe received datagram's ECN codepoint (0..3)

◆ wired_srvloop_init()

int wired_srvloop_init ( wired_srvloop * l,
const u8 * cli_scid,
u8 cli_scid_len )

Record the client's source connection id (the DCID for server-sent packets) and reset the HTTP/3 state.

Parameters
lthe loop to initialize
cli_scidthe client's source connection id
cli_scid_lencli_scid length in octets
Returns
1, or 0 if cli_scid_len exceeds 20.

◆ wired_srvloop_priority_apply()

void wired_srvloop_priority_apply ( wired_srvloop * l,
u64 stream_id,
const quic_h3_priority * p )

RFC 9218 7.1 / 10: apply a validated PRIORITY_UPDATE (request variant) to stream_id – directly into its streams[] slot if already open, else buffered in pending_priority[] until wired_srvloop_slot_for later claims that stream id (9218-010).

A stream id that is neither open nor buffered anywhere is simply added to (or overwrites its own entry in) pending_priority[]; a full pending table drops the update, same truncate-on-overflow policy family as this file's other fixed tables.

Parameters
lthe loop to apply into
stream_idthe client bidi request stream id the update names
pthe priority to apply (already decoded/validated by the caller)

◆ wired_srvloop_priority_of()

int wired_srvloop_priority_of ( const wired_srvloop * l,
u64 stream_id,
quic_h3_priority * out )

RFC 9218 10: read stream_id's current priority (its RFC 9218 4.1 default until any PRIORITY_UPDATE or Priority header field changed it) without allocating a streams[] slot – the counterpart read used by a response scheduler (srvrun.c) ordering its send passes, as opposed to wired_srvloop_slot_for's claim-or-allocate used by the receive path.

Parameters
lthe loop whose streams[] table to search
stream_idthe client bidi request stream id
outreceives the priority, valid only when 1 is returned
Returns
1 if stream_id has an open streams[] slot, 0 otherwise.

◆ wired_srvloop_set_handler()

void wired_srvloop_set_handler ( wired_srvloop * l,
wired_srvloop_handler cb,
void * ctx )

Register the app response-body builder; pass 0 to clear (body-less 200).

Parameters
lthe loop to register on
cbthe response-body builder, 0 to clear
ctxopaque context handed back to cb

◆ wired_srvloop_slot_for()

int wired_srvloop_slot_for ( wired_srvloop * l,
u64 stream_id )

RFC 9000 2.2: the streams[] slot reassembling request stream_id, allocating a free one on first sight – dispatch.c routes each request STREAM frame to its own stream's slot through this (a payload may coalesce frames of several request streams).

Parameters
lthe loop whose streams[] table to search/claim
stream_idthe client bidi request stream id
Returns
the slot index, or -1 when the table is full (the stream's frames are dropped, same as the old fixed capacity of one).

◆ wired_srvloop_slot_release()

void wired_srvloop_slot_release ( wired_srvloop * l,
u64 stream_id )

RFC 9000 2.2: free the streams[] slot reassembling stream_id, once its response has been fully sent and acknowledged – called by the response driver (srvrun.c) so a stream id's slot becomes reusable for a later request.

HTTP/3 never reuses a stream id, so without this the table's WIRED_SRVLOOP_MAX_STREAMS slots exhaust permanently after that many sequential requests on distinct streams.

Parameters
lthe loop whose streams[] table to release from
stream_idthe client bidi request stream id; a no-op if it has no slot.

◆ wired_srvloop_step()

int wired_srvloop_step ( const wired_srvloop_conn * conn,
quic_mspan dgram,
quic_obuf * out )

Drive one wire iteration: open dgram, dispatch it, and if the step produced a server-direction packet (HANDSHAKE_DONE once confirmed, or a 200 response to a decoded GET) seal it into out, setting out->len.

Parameters
connthe loop/orchestrator pair to drive
dgramthe inbound datagram to open and dispatch
outreceives the sealed outbound packet, when one is produced
Returns
1 if an outbound packet was written, 0 if the step produced none (or the input was dropped).

◆ wired_srvloop_wt_slot_claim()

int wired_srvloop_wt_slot_claim ( wired_srvloop * l,
u64 stream_id )

draft-ietf-webtrans-http3-15 4.3: claim and reset a free wt_streams slot for stream_id, called the first time a stream's leading 0x41 signal is recognized.

Parameters
lthe loop to claim a slot on
stream_idthe WT bidi stream id
Returns
the slot index, or -1 if the table is full.

◆ wired_srvloop_wt_slot_claim_local()

int wired_srvloop_wt_slot_claim_local ( wired_srvloop * l,
u64 stream_id )

RFC 9000 2.1: pre-claim a wt_streams slot for a stream id THIS endpoint itself opened (a server-initiated bidi stream, id bits 01) – unlike wired_srvloop_wt_slot_claim, called before any frame for stream_id has arrived, with sig_len left 0 (no signal prefix: the peer's reply is raw application data from its own offset 0).

Idempotent: a stream_id already claimed is returned unchanged rather than re-reset, so calling this once per wired_server_wt_open_bidi is safe even if a frame beat it to the slot in a pathological reordering.

Parameters
lthe loop to claim a slot on
stream_idthe server-initiated bidi stream id
Returns
the slot index, or -1 if the table is full.

◆ wired_srvloop_wt_slot_find()

int wired_srvloop_wt_slot_find ( const wired_srvloop * l,
u64 stream_id )

draft-ietf-webtrans-http3-15 4.3: find the wt_streams slot already reassembling stream_id, so dispatch.c's gather_wt_stream can route a later (offset>0) frame into the same slot its signal frame claimed.

Parameters
lthe loop to search
stream_idthe WT bidi stream id
Returns
the slot index, or -1 if this stream has no slot yet.

◆ wired_srvloop_wt_slot_release()

void wired_srvloop_wt_slot_release ( wired_srvloop * l,
u64 stream_id )

draft-ietf-webtrans-http3-15 4.3: free the wt_streams[] slot reassembling stream_id once its FIN has been fully delivered to the app, mirroring wired_srvloop_slot_release for the WT bidi table.

Also raises the table's released-id watermark (see wired_srvloop_wt_slot_claim's doc) so a late duplicate/reordered frame for this now-freed id is never mistaken for a fresh stream.

Parameters
lthe loop whose wt_streams[] table to release from
stream_idthe WT bidi stream id; a no-op if it has no slot.

◆ wired_srvloop_wt_uni_slot_claim()

int wired_srvloop_wt_uni_slot_claim ( wired_srvloop * l,
u64 stream_id )

draft-ietf-webtrans-http3-15 4.3: claim and reset a free wt_uni_streams slot for stream_id, called the first time a uni stream's leading type varint is recognized as 0x54, mirroring wired_srvloop_wt_slot_claim.

Parameters
lthe loop to claim a slot on
stream_idthe WT uni stream id
Returns
the slot index, or -1 if the table is full.

◆ wired_srvloop_wt_uni_slot_find()

int wired_srvloop_wt_uni_slot_find ( const wired_srvloop * l,
u64 stream_id )

draft-ietf-webtrans-http3-15 4.3: find the wt_uni_streams slot already reassembling stream_id, mirroring wired_srvloop_wt_slot_find for the separate uni table.

Parameters
lthe loop to search
stream_idthe WT uni stream id
Returns
the slot index, or -1 if this stream has no slot yet.

◆ wired_srvloop_wt_window_accept()

void wired_srvloop_wt_window_accept ( wired_srvloop_wt_window * win,
u64 abs_off,
usz n,
usz * rel_off,
usz * accepted_n )

draft-ietf-webtrans-http3-15 4.3: clamp [abs_off, abs_off+n) to win's currently open window (drop the stale prefix already delivered/below win.base, and the part beyond win.base + WIRED_SRVLOOP_WT_BUF_CAP the peer has no granted credit for yet) and record the accepted portion into win's range set, recomputing win.frontier.

The caller (dispatch.c) still owns the actual buf write, at *rel_off for *accepted_n bytes – this only answers "where, and how much".

Parameters
winthe slot's window to accept into
abs_offthe frame's absolute (post-signal) stream offset
nthe frame's byte count
rel_offset to the offset into buf to write the accepted bytes at
accepted_nset to how many trailing bytes of [abs_off, abs_off+n) fall inside the open window (0 if none do – entirely stale or entirely beyond the window)

◆ wired_srvloop_wt_window_slide()

void wired_srvloop_wt_window_slide ( wired_srvloop_wt_window * win,
u8 * buf,
usz cap,
u64 delivered_to )

draft-ietf-webtrans-http3-15 4.3 / RFC 9000 4.1: once delivered_to (an absolute offset, srvrun.c's own delivered_len) has consumed the whole current frontier, slide the window forward so buf has room for more – shift any bytes still buffered past the frontier (an out-of-order continuation already written ahead of a since-filled gap) down to buf[0], advance win.base by the delivered frontier, and rebase every range in win.ranges by the same amount.

A no-op if delivered_to has not yet reached win.base + win.frontier (nothing contiguous left to reclaim room for).

Parameters
winthe slot's window to slide
bufthe slot's own backing buffer (same one window offsets index)
capbuf's capacity (WIRED_SRVLOOP_WT_BUF_CAP)
delivered_tothe absolute offset delivered up to so far