|
wired
libc-free QUIC/HTTP3 SDK in C for x86_64-linux
|
Per-connection state of the server wire loop, re-armed by wired_srvloop_init and driven by wired_srvloop_step. More...
#include <srvloop.h>
Data Fields | |
| wired_h3srv_state | h3 |
| HTTP/3 server response-layer state. | |
| u8 | cli_scid [20] |
| the client's source id; DCID the server writes | |
| u8 | cli_scid_len |
| cli_scid length in octets | |
| u64 | tx_pn |
| monotone packet number for sealed 1-RTT output | |
| u64 | hs_tx_pn |
| monotone packet number for sealed Handshake output | |
| u64 | app_rx_pn |
| last received 1-RTT (application) packet number to ACK | |
| int | app_rx_seen |
| 1 once a 1-RTT packet has been received (app_rx_pn valid) | |
| u64 | hs_rx_pn |
| last received Handshake packet number to ACK (the client Finished's actual PN, which is not always 0) | |
| int | hs_rx_seen |
| 1 once a Handshake packet has been received | |
| quic_pnspaces_recv | ack_recv |
| RFC 9000 12.3/13.2.1/13.2.2/19.3: every packet number space's received-pn window (quic_pnspaces_recv, independent per space – Initial is out of this loop's scope, srvboot's own layer) plus whether/when each space owes an ACK (quic_ackpolicy, one instance per space since App and Handshake ack independently). | |
| quic_ackpolicy | app_ack_policy |
| App space's delayed-ACK timer. | |
| quic_ackpolicy | hs_ack_policy |
| Handshake space's delayed-ACK timer. | |
| u64 | now_ms |
| Monotonic ms this step is being driven at – the time source quic_ackpolicy's delayed-ACK timer measures against. | |
| int | hs_done_sent |
| 1 once the confirmation (HANDSHAKE_DONE) has been emitted | |
| int | ticket_sent |
| 1 once the post-confirmation session ticket (NewSessionTicket, RFC 8446 4.6.1) has been emitted | |
| u8 | confirm_frames [320] |
| The confirmation packet's frame payload (SETTINGS + session ticket + HANDSHAKE_DONE), captured at its one-time emit so a lost confirmation can be replayed verbatim under a fresh pn (wired_srvloop_reconfirm, RFC 9000 19.20). | |
| u16 | confirm_frames_len |
| Bytes cached in confirm_frames; 0 until the confirmation was emitted (or when it did not fit, leaving no replay available). | |
| wired_srvloop_handler | on_request |
| app response-body builder, 0 if unset | |
| void * | req_ctx |
| opaque ctx passed to on_request | |
| wired_srvloop_stream_slot | streams [WIRED_SRVLOOP_MAX_STREAMS] |
| RFC 9000 2.2: one reassembly slot per concurrent client bidi (request) stream, looked up/allocated by stream id (see stream_slot_find/alloc in srvloop.c). | |
| wired_srvloop_wt_stream_slot | wt_streams [WIRED_SRVLOOP_MAX_WT_STREAMS] |
| draft-ietf-webtrans-http3-15 4.3: one reassembly slot per concurrent WT bidi stream, separate from streams[] above (see wired_srvloop_wt_stream_slot's doc for why). | |
| wired_srvloop_wt_uni_stream_slot | wt_uni_streams [WIRED_SRVLOOP_MAX_WT_UNI_STREAMS] |
| draft-ietf-webtrans-http3-15 4.3: one reassembly slot per concurrent WT uni stream, separate from wt_streams[] above (different directionality, see wired_srvloop_wt_uni_stream_slot's doc). | |
| int | got_request |
| Mirrors the most recently completed request this step, across whichever slot decoded it — the pre-existing single-stream API surface (got_request/ req), kept so existing callers reading these two fields directly need no change. | |
| wired_h3reqdrive_req | req |
| the mirrored most-recently-completed request; valid only when got_request is set | |
| u64 | req_stream_id |
| the client bidi stream id req was decoded from; valid only when got_request is set (mirrors req from whichever slot completed, same rule) | |
| u8 | done_slots [WIRED_SRVLOOP_MAX_STREAMS] |
| Every slot whose request completed THIS step, in completion order – the multi-request counterpart of the single got_request/req mirror above (which only carries the last one). | |
| usz | done_n |
| entries valid in done_slots this step | |
| u8 | incomplete_slots [WIRED_SRVLOOP_MAX_STREAMS] |
| RFC 9114 4.1: every slot whose request stream terminated (FIN) THIS step WITHOUT producing a request (streams[i].req_incomplete) – the H3_REQUEST_INCOMPLETE counterpart of done_slots above. | |
| usz | incomplete_n |
| entries valid in incomplete_slots this step | |
| u8 | frame_unexpected_slots [WIRED_SRVLOOP_MAX_STREAMS] |
| RFC 9114 7.2.5/7.2.8 (9114-067/9114-073): every slot whose request stream carried a PUSH_PROMISE or HTTP/2-only reserved frame type this step (streams[i].req.frame_unexpected) – the H3_FRAME_UNEXPECTED counterpart of incomplete_slots above. | |
| usz | frame_unexpected_n |
| entries valid in frame_unexpected_slots this step | |
| int | peer_closed |
| 1 once a peer CONNECTION_CLOSE frame was seen | |
| int | resp_external |
| 1: the caller answers requests, not the loop | |
| u64 | ack_lo [32] |
| ACK ranges (RFC 9000 19.3) seen in payloads opened this step, reset at the start of every wired_srvloop_step; overflow past the cap is dropped. | |
| u64 | ack_hi [32] |
| range highs, ack_hi[0] from the frame's largest | |
| usz | ack_n |
| ranges recorded this step | |
| wired_srvloop_rx_datagram | rx_datagrams [WIRED_SRVLOOP_MAX_RX_DATAGRAMS] |
| RFC 9221 5: received QUIC DATAGRAM frame payloads queued for a future consumer to drain (Phase 7b Slice 2), oldest first. | |
| usz | rx_datagram_n |
| count of entries valid in rx_datagrams, 0..WIRED_SRVLOOP_MAX_RX_DATAGRAMS. | |
| u64 | we_advertised_max_datagram |
| RFC 9221 3: this connection's own advertised max_datagram_frame_size transport parameter value, 0 = not advertised (same sentinel convention as wired_srvboot_id.max_datagram_frame_size, which this is populated from at connection boot — see srvrun_boot_finish). | |
| int | datagram_violation |
| 1 once a received DATAGRAM frame violated RFC 9221 3 (exceeded we_advertised_max_datagram, or arrived when it was never advertised) — mirrors peer_closed's shape: dispatch.c only marks this, the caller driving the loop (srvrun.c's srvrun_on_step) checks it after the step and closes the connection. | |
| u64 | closed_stream_id |
| RFC 9000 19.4/19.5 (draft-ietf-webtrans-http3-15 SS4.4): the client bidi stream id a FIN, RESET_STREAM, or STOP_SENDING closed THIS step, valid only when closed_stream_seen is set. | |
| int | closed_stream_seen |
| 1 once closed_stream_id was set this step | |
| u64 | max_data_seen |
| RFC 9000 19.9: highest MAX_DATA value seen across every 1-RTT payload opened this step (gather_max_data in dispatch.c) – the connection-level send credit ceiling this endpoint may now use. | |
| int | max_data_seen_flag |
| 1 once max_data_seen was set this step | |
| u64 | max_stream_data_stream_id [WIRED_SRVLOOP_MAX_STREAMS] |
| RFC 9000 19.10: every distinct MAX_STREAM_DATA (stream id, value) seen this step, one slot per distinct stream id named (up to WIRED_SRVLOOP_MAX_STREAMS – a single step coalescing a MAX_STREAM_DATA per in-flight response, e.g. | |
| u64 | max_stream_data_value [WIRED_SRVLOOP_MAX_STREAMS] |
| RFC 9000 19.10: the value carried by the same-indexed max_stream_data_stream_id slot. | |
| usz | max_stream_data_n |
| Slots in max_stream_data_stream_id/_value actually used this step (0 to WIRED_SRVLOOP_MAX_STREAMS). | |
| u64 | wt_released_watermark |
| RFC 9000 2.1: the highest WT bidi stream id ever released (wired_srvloop_wt_slot_release), 0 before any release. | |
| u64 | wt_uni_released_watermark |
| Same as wt_released_watermark, for the separate wt_uni_streams table. | |
| int | streams_blocked_seen_flag |
| RFC 9000 19.14: 1 once a client bidi STREAMS_BLOCKED frame was seen in any 1-RTT payload opened this step (gather_streams_blocked in dispatch.c) – the peer's own reported limit value is not latched (srvrun.c computes the re-grant from its own receive-side slot state, RFC 9000 4.6/19.11, rather than trusting the peer's claim). | |
| u8 | path_response_data [QUIC_PATH_DATA] |
| RFC 9000 8.2.2/19.18: the 8-byte data of a PATH_RESPONSE frame seen in any 1-RTT payload opened this step (gather_path_response in dispatch.c), valid only when path_response_seen_flag is set. | |
| int | path_response_seen_flag |
| 1 once path_response_data was set this step; not reset across steps by this loop itself, same convention as max_data_seen_ flag and streams_blocked_seen_flag. | |
| u64 | ecn_ect0 |
| RFC 9000 13.4 / RFC 9002 19.3.2: this connection's cumulative count of received datagrams marked ECT(0)/ECT(1)/CE (RFC 3168), monotonically increasing across the connection's whole lifetime – an ACK frame reports this running total, not one step's delta (see app_ack_encode_ranges in respond.c). | |
| u64 | ecn_ect1 |
| ECT(1) running total (same lifecycle as ecn_ect0's doc above). | |
| u64 | ecn_ce |
| CE running total (same lifecycle as ecn_ect0's doc above). | |
| wired_srvloop_pending_priority | pending_priority [WIRED_SRVLOOP_MAX_PENDING_PRIORITY] |
| RFC 9218 10 / 9218-010: PRIORITY_UPDATE frames naming a request stream not yet open, buffered until wired_srvloop_slot_for claims that stream id (see wired_srvloop_priority_apply). | |
| wired_srvloop_ctrl_stream | ctrl |
| RFC 9114 6.2.1: the peer's single control stream, reassembled so its frames (SETTINGS/GOAWAY/PRIORITY_UPDATE) can be walked once complete – see wired_srvloop_ctrl_stream's own doc. | |
| quic_h3_control | peer_ctrl |
| RFC 9114 7.2.4 / draft-ietf-webtrans-http3-15 SS3.1 (WTH3-009/042): the client control stream's own SETTINGS-ordering state, latched as each control-stream frame is walked (priority_ctrl.c's ctrl_note_generic) – peer_ctrl.settings_seen is 1 once the client's SETTINGS has actually arrived, gating WebTransport CONNECT dispatch (srvrun.c) until it has. | |
| u16 | priupdate_violation |
| RFC 9218 7.1 / RFC 9114 8.1: the H3 connection error code of the most recent rejected PRIORITY_UPDATE this step (H3_FRAME_UNEXPECTED / H3_ID_ERROR), 0 when none was rejected. | |
| u16 | qpack_stream_violation |
| RFC 9204 4.2 (9204-028): the H3 connection error code of a second QPACK encoder or decoder unidirectional stream seen this step (H3_STREAM_CREATION_ERROR), 0 when none was rejected. | |
| int | wt_signal_mid_stream_violation |
| draft-ietf-webtrans-http3-15 4.3: 1 once a STREAM frame this step carried the WT_STREAM signal varint (0x41) as its own leading bytes at a NON-zero stream offset – "Endpoints MUST NOT send WT_STREAM as a frame type on HTTP/3 streams other than the very first bytes of a request stream. | |
| u64 | wt_reset_stream_id |
| draft-ietf-webtrans-http3-15 4.4 (WTH3-040): the stream id and wire error code of a RESET_STREAM/STOP_SENDING this step latched on a client bidi (request/WT) stream id, valid only when wt_reset_seen is set – mirrors closed_stream_id's own shape (last one wins if more than one arrives this step) but ALSO records the error code, which closed_stream_id's own gather (gather_stream_closes, for the CONNECT- stream-close case) does not need and therefore does not latch. | |
| u64 | wt_reset_error_code |
| its wire error code | |
| int | wt_reset_is_stop |
| 1 for STOP_SENDING, 0 for RESET_STREAM | |
| int | wt_reset_seen |
| 1 once the three fields above were set this step | |
Per-connection state of the server wire loop, re-armed by wired_srvloop_init and driven by wired_srvloop_step.
Field order follows the doc grouping (related fields stay next to their shared comment) rather than the padding-optimal order clang-tidy's Padding check would prefer – reordering ~60 densely-commented fields purely to shave padding risks silently misattributing a comment to the wrong field, for a struct that is never allocated in bulk.
| u64 wired_srvloop::ack_lo[32] |
ACK ranges (RFC 9000 19.3) seen in payloads opened this step, reset at the start of every wired_srvloop_step; overflow past the cap is dropped.
32 matches quic_ack_decode's own max range count (ack.h), so a single ACK frame's ranges are never truncated here before the caller (multiple per-stream send sessions, each keyed by pn) gets to consume them. range lows, parallel with ack_hi
| quic_pnspaces_recv wired_srvloop::ack_recv |
RFC 9000 12.3/13.2.1/13.2.2/19.3: every packet number space's received-pn window (quic_pnspaces_recv, independent per space – Initial is out of this loop's scope, srvboot's own layer) plus whether/when each space owes an ACK (quic_ackpolicy, one instance per space since App and Handshake ack independently).
Indexed by QUIC_PNS_APP/QUIC_PNS_HANDSHAKE (transport/conn/lifecycle/conn/pnspace.h).
| u64 wired_srvloop::closed_stream_id |
RFC 9000 19.4/19.5 (draft-ietf-webtrans-http3-15 SS4.4): the client bidi stream id a FIN, RESET_STREAM, or STOP_SENDING closed THIS step, valid only when closed_stream_seen is set.
Mirrors peer_closed's shape: dispatch.c only records it, the caller (srvrun.c) decides what a closed id means for whatever session it may belong to (e.g. a WebTransport CONNECT stream closing independently of the rest of the connection) — this loop has no notion of a WT session and does not interpret the id.
| u8 wired_srvloop::confirm_frames[320] |
The confirmation packet's frame payload (SETTINGS + session ticket + HANDSHAKE_DONE), captured at its one-time emit so a lost confirmation can be replayed verbatim under a fresh pn (wired_srvloop_reconfirm, RFC 9000 19.20).
Replaying from this cache, not rebuilding, keeps the ticket's random sealing nonce – and so the CRYPTO bytes at offset 0 – identical across copies (RFC 9000 2.2).
| wired_srvloop_ctrl_stream wired_srvloop::ctrl |
RFC 9114 6.2.1: the peer's single control stream, reassembled so its frames (SETTINGS/GOAWAY/PRIORITY_UPDATE) can be walked once complete – see wired_srvloop_ctrl_stream's own doc.
Not reset across steps by this loop itself (mirrors the streams[] reassembly convention).
| u8 wired_srvloop::done_slots[WIRED_SRVLOOP_MAX_STREAMS] |
Every slot whose request completed THIS step, in completion order – the multi-request counterpart of the single got_request/req mirror above (which only carries the last one).
Reset at the start of every wired_srvloop_step; each entry indexes streams[], whose slot holds its own decoded req (views valid until that slot's next request begins).
| u64 wired_srvloop::ecn_ect0 |
RFC 9000 13.4 / RFC 9002 19.3.2: this connection's cumulative count of received datagrams marked ECT(0)/ECT(1)/CE (RFC 3168), monotonically increasing across the connection's whole lifetime – an ACK frame reports this running total, not one step's delta (see app_ack_encode_ranges in respond.c).
Advanced by wired_srvloop_ecn_note, called once per received datagram with the ECN codepoint the UDP layer read from its IP_TOS cmsg (quic_mmsg_buf.ecn in udp.h). 0 for all three until any ECN-marked datagram arrives.
| u8 wired_srvloop::frame_unexpected_slots[WIRED_SRVLOOP_MAX_STREAMS] |
RFC 9114 7.2.5/7.2.8 (9114-067/9114-073): every slot whose request stream carried a PUSH_PROMISE or HTTP/2-only reserved frame type this step (streams[i].req.frame_unexpected) – the H3_FRAME_UNEXPECTED counterpart of incomplete_slots above.
A slot never appears in both lists: the decoder rejects the frame before FIN/completion accounting runs, so this takes priority. Reset at the start of every wired_srvloop_step.
| int wired_srvloop::got_request |
Mirrors the most recently completed request this step, across whichever slot decoded it — the pre-existing single-stream API surface (got_request/ req), kept so existing callers reading these two fields directly need no change.
For the single-request-stream (id 0) case this is exactly the old behavior; wired_srvloop_step also updates it for whichever slot completed last if more than one did.
| u8 wired_srvloop::incomplete_slots[WIRED_SRVLOOP_MAX_STREAMS] |
RFC 9114 4.1: every slot whose request stream terminated (FIN) THIS step WITHOUT producing a request (streams[i].req_incomplete) – the H3_REQUEST_INCOMPLETE counterpart of done_slots above.
A slot never appears in both lists: request_complete decodes at most once, so a completion is either a request (done_slots) or an incomplete stream (incomplete_slots). Reset at the start of every wired_srvloop_step.
| u64 wired_srvloop::max_data_seen |
RFC 9000 19.9: highest MAX_DATA value seen across every 1-RTT payload opened this step (gather_max_data in dispatch.c) – the connection-level send credit ceiling this endpoint may now use.
0 = none seen this step (the caller, srvrun.c, only raises its own running credit when this is higher than what it already holds; a lower or absent value here is a no-op per RFC 9000 4.1's "never decreases"). Not reset across steps by this loop itself – srvrun.c's own credit state is the only thing that persists across steps; this field is this step's observation only.
| usz wired_srvloop::max_stream_data_n |
Slots in max_stream_data_stream_id/_value actually used this step (0 to WIRED_SRVLOOP_MAX_STREAMS).
0 = none seen.
| u64 wired_srvloop::max_stream_data_stream_id[WIRED_SRVLOOP_MAX_STREAMS] |
RFC 9000 19.10: every distinct MAX_STREAM_DATA (stream id, value) seen this step, one slot per distinct stream id named (up to WIRED_SRVLOOP_MAX_STREAMS – a single step coalescing a MAX_STREAM_DATA per in-flight response, e.g.
3 parallel GETs each raised by the peer at once, must not lose all but the last one the way a single-slot latch would: srvrun.c only checks ONE resp[] slot's credit per raise, so a dropped update leaves that stream's send credit stuck at its initial value forever, and a large streamed response silently stalls at that ceiling). A repeat stream id this step overwrites its own slot instead of consuming a second one (only the newest value matters, same as the old single-latch behavior for a given stream). srvrun.c drains every used slot once per step.
| u64 wired_srvloop::max_stream_data_value[WIRED_SRVLOOP_MAX_STREAMS] |
RFC 9000 19.10: the value carried by the same-indexed max_stream_data_stream_id slot.
Valid only for i < max_stream_data_n.
| u64 wired_srvloop::now_ms |
Monotonic ms this step is being driven at – the time source quic_ackpolicy's delayed-ACK timer measures against.
The caller (e.g. srvrun.c) sets this once per step, sharing its own PTO/RTT time source (srvrun_step_ctx.now_ms) rather than adding a second clock; a caller that never sets it (0) simply never ages a pending ACK past the delay window via elapsed time alone (the two-eliciting-packets immediate-ack path still fires). Living on wired_srvloop rather than wired_srvloop_conn keeps wired_srvloop_step's existing signature and every current struct-literal call site unchanged.
| u8 wired_srvloop::path_response_data[QUIC_PATH_DATA] |
RFC 9000 8.2.2/19.18: the 8-byte data of a PATH_RESPONSE frame seen in any 1-RTT payload opened this step (gather_path_response in dispatch.c), valid only when path_response_seen_flag is set.
This loop has no notion of path validation (that lives in srvrun_conn.migrate, srvrun.c) – it only latches the raw bytes, mirroring max_data_seen's split of responsibility (gather here, interpret in the caller).
| wired_srvloop_pending_priority wired_srvloop::pending_priority[WIRED_SRVLOOP_MAX_PENDING_PRIORITY] |
RFC 9218 10 / 9218-010: PRIORITY_UPDATE frames naming a request stream not yet open, buffered until wired_srvloop_slot_for claims that stream id (see wired_srvloop_priority_apply).
Not reset across steps by this loop itself – a pending entry lives until its stream opens or the table is re-armed by wired_srvloop_init.
| u16 wired_srvloop::priupdate_violation |
RFC 9218 7.1 / RFC 9114 8.1: the H3 connection error code of the most recent rejected PRIORITY_UPDATE this step (H3_FRAME_UNEXPECTED / H3_ID_ERROR), 0 when none was rejected.
Mirrors datagram_violation's shape: dispatch.c only latches it, the caller driving the loop decides how to close the connection over it.
| u16 wired_srvloop::qpack_stream_violation |
RFC 9204 4.2 (9204-028): the H3 connection error code of a second QPACK encoder or decoder unidirectional stream seen this step (H3_STREAM_CREATION_ERROR), 0 when none was rejected.
Mirrors priupdate_violation's shape: dispatch.c only latches it via wired_h3srv_on_peer_qpack, the caller driving the loop decides how to close the connection over it.
| usz wired_srvloop::rx_datagram_n |
count of entries valid in rx_datagrams, 0..WIRED_SRVLOOP_MAX_RX_DATAGRAMS.
Once the queue is full, a newly arrived datagram is dropped (matching RFC 9221's unreliable-delivery semantics) rather than overwriting an already-queued one — this is the receive-side counterpart of the send side's single-slot "last write wins", chosen because losing an already-arrived datagram to a same-step overwrite is worse.
| wired_srvloop_rx_datagram wired_srvloop::rx_datagrams[WIRED_SRVLOOP_MAX_RX_DATAGRAMS] |
RFC 9221 5: received QUIC DATAGRAM frame payloads queued for a future consumer to drain (Phase 7b Slice 2), oldest first.
Filled by gather_rx_datagrams in dispatch.c alongside the request/WT-stream gathering above — a single 1-RTT packet may coalesce a DATAGRAM frame with a request or WT stream frame, so this runs independently of both.
| wired_srvloop_stream_slot wired_srvloop::streams[WIRED_SRVLOOP_MAX_STREAMS] |
RFC 9000 2.2: one reassembly slot per concurrent client bidi (request) stream, looked up/allocated by stream id (see stream_slot_find/alloc in srvloop.c).
streams[0] is claimed for stream id 0 on the connection's first request, exactly as the old single-slot fields were — so a connection that only ever uses stream 0 behaves identically to before.
| int wired_srvloop::streams_blocked_seen_flag |
RFC 9000 19.14: 1 once a client bidi STREAMS_BLOCKED frame was seen in any 1-RTT payload opened this step (gather_streams_blocked in dispatch.c) – the peer's own reported limit value is not latched (srvrun.c computes the re-grant from its own receive-side slot state, RFC 9000 4.6/19.11, rather than trusting the peer's claim).
Not reset across steps by this loop itself, same convention as max_data_seen_ flag: this step's observation only.
| u64 wired_srvloop::we_advertised_max_datagram |
RFC 9221 3: this connection's own advertised max_datagram_frame_size transport parameter value, 0 = not advertised (same sentinel convention as wired_srvboot_id.max_datagram_frame_size, which this is populated from at connection boot — see srvrun_boot_finish).
Used by dispatch.c's DATAGRAM gathering to reject a frame the peer had no right to send (quic_datagram_recv_ok).
| u64 wired_srvloop::wt_released_watermark |
RFC 9000 2.1: the highest WT bidi stream id ever released (wired_srvloop_wt_slot_release), 0 before any release.
Since a peer's stream ids of one type are strictly increasing (RFC 9000 2.1), a claim attempt naming an id at or below this watermark is necessarily a stale/ reordered frame for an already-finished stream, not a fresh one – wired_srvloop_wt_slot_claim rejects it rather than re-claiming a slot a delayed duplicate could otherwise reopen after the app already saw FIN.
| u64 wired_srvloop::wt_reset_stream_id |
draft-ietf-webtrans-http3-15 4.4 (WTH3-040): the stream id and wire error code of a RESET_STREAM/STOP_SENDING this step latched on a client bidi (request/WT) stream id, valid only when wt_reset_seen is set – mirrors closed_stream_id's own shape (last one wins if more than one arrives this step) but ALSO records the error code, which closed_stream_id's own gather (gather_stream_closes, for the CONNECT- stream-close case) does not need and therefore does not latch.
This loop has no notion of which stream id is a WT data stream vs. a plain request stream, nor of the WT_APPLICATION_ERROR mapping – the caller (srvrun.c) resolves both. wt_reset_is_stop is 1 for a STOP_SENDING, 0 for a RESET_STREAM (both matter equally here; distinguished only so a caller that needs it can tell them apart). stream id the RESET_STREAM/STOP_SENDING named
| int wired_srvloop::wt_signal_mid_stream_violation |
draft-ietf-webtrans-http3-15 4.3: 1 once a STREAM frame this step carried the WT_STREAM signal varint (0x41) as its own leading bytes at a NON-zero stream offset – "Endpoints MUST NOT send WT_STREAM as a frame type on HTTP/3 streams other than the very first bytes of a request stream.
Receiving this frame type in any other circumstances MUST be treated as a connection error of type H3_FRAME_ERROR." Mirrors datagram_violation's shape: dispatch.c only latches it, the caller driving the loop (srvrun.c) closes the connection over it. Not reset across steps by this loop itself, same convention as max_data_seen_flag (the caller consumes and clears it every step).
| wired_srvloop_wt_stream_slot wired_srvloop::wt_streams[WIRED_SRVLOOP_MAX_WT_STREAMS] |
draft-ietf-webtrans-http3-15 4.3: one reassembly slot per concurrent WT bidi stream, separate from streams[] above (see wired_srvloop_wt_stream_slot's doc for why).
Reachable here so a future slice can wire an app-facing callback over it; this slice only reassembles and associates with the connection's WT session, it does not deliver.