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

draft-ietf-moq-transport-18/19/22 hub relay (section numbers are draft-19's unless a draft is named; each peer's negotiated draft, its moqver.h capability bits, picks the per-draft behavior): the app-facing layer wiring the other MOQT domains (vi/kvp/ctl/data/dgram/sess/fetch/ns/tstat/cache) onto the WT application API (app/http3/server/srvrun). More...

Go to the source code of this file.

Data Structures

struct  wired_moqt_io
 The send/reset operations this layer needs, as a function-pointer table so it never links wired_server_wt_* directly (kept testable without the QUIC/TLS stack). More...
struct  wired_moqtrun_rngrow
 One flattened Range Filter Range (draft-19 10.2.10-10.2.14): the (ptype, set_id[, prop_type]) triple names the parameter it came from; a parameter with k Ranges takes k rows. More...
struct  wired_moqtrun_sub
 One subscriber recorded against the hub's track: which session, and the Track Alias its SUBSCRIBE_OK named – the alias every SUBGROUP_HEADER and OBJECT_DATAGRAM relayed to that session carries (draft-22 3.1.3: unique per Track within the session; moqtrun_session_alias). More...
struct  wired_moqtrun_relay
 One in-flight relayed publisher stream: which publisher-side stream (pub_stream_id) this relay follows, and – per subscriber slot index in the owning track's subs[] – the subscriber-side uni stream its bytes are forwarded on. More...
struct  wired_moqtrun_ctl_asm
 Reassembly of control messages split across stream deliveries: holds the not-yet-complete tail of one stream. More...
struct  wired_moqtrun_req
 One peer-opened request stream (draft-ietf-moq-transport-19 3.3): its own reassembly and reply queue (the same ARMED/PENDING pair as wired_moqtrun_peer.send_bufs, at request-stream size). More...
struct  wired_moqtrun_rdv
 One SUBSCRIBE held for a publisher. More...
struct  wired_moqtrun_up
 One SUBSCRIBE the hub sent upstream on its own request stream. More...
struct  wired_moqtrun_fetch
 One FETCH response being served from the hub cache: Objects of the track incarnation cache_tag in [cursor, end) go out on one uni stream (FETCH_HEADER, then fetch Objects, 11.4.4), one item per stream round as the transport accepts them. More...
struct  wired_moqtrun_upf_leg
 The bulky part of a fetches[] slot's upstream FETCH, kept beside the slot (wired_moqt_hub.upf_legs, same index) so fetch_waits[] entries, which never run one, do not carry it. More...
struct  wired_moqtrun_track
 One track a peer PUBLISHes (chat or audio), and the subscribers recorded against it. More...
struct  wired_moqtrun_peer
 One connected participant's hub-side state: its WT session, its own control-stream MOQT session machine, and the tracks (chat/audio) it has PUBLISHed. More...
struct  wired_moqtrun_live
 The hub's own clock-paced live track (wired_moqt_publish_live): Group g carries fragment g mod n_frags as its only Object, Groups advancing every group_ms from t0_ms. More...
struct  wired_moqt_hub
 The hub's whole state: fixed peer table plus the io table it sends through. More...

Macros

#define WIRED_MOQTRUN_MAX_SESSIONS   32
 Fixed capacity: concurrent sessions the hub tracks at once.
#define WIRED_MOQTRUN_MAX_SUBS   (WIRED_MOQTRUN_MAX_SESSIONS - 1)
 Fixed capacity: subscribers recorded against the hub's single published track per session slot (every other connected session, at most).
#define WIRED_MOQTRUN_URGENCY(sub_prio, pub_prio)
 RFC 9218 urgency of a subscriber stream from its subscription's Subscriber Priority and the stream's Publisher Priority (both 0..255, lower first, 128 when absent – draft-ietf-moq-transport-19 7.1, 10.2.7).
#define WIRED_MOQTRUN_CLOSE_PROTOCOL_VIOLATION   0x3
 draft-ietf-moq-transport-19 SS3.5 PROTOCOL_VIOLATION session code.
#define WIRED_MOQTRUN_CLOSE_INTERNAL_ERROR   0x1
 draft-ietf-moq-transport-19 SS3.5 INTERNAL_ERROR session code.
#define WIRED_MOQTRUN_CLOSE_NO_ERROR   0x0
 draft-ietf-moq-transport-19 3.5 NO_ERROR session code.
#define WIRED_MOQTRUN_CLOSE_INVALID_REQUEST_ID   0x4
 draft-ietf-moq-transport-18/19 3.5 INVALID_REQUEST_ID session code.
#define WIRED_MOQTRUN_CLOSE_GOAWAY_TIMEOUT   0x10
 draft-ietf-moq-transport-19 3.5 GOAWAY_TIMEOUT session code.
#define WIRED_MOQTRUN_CLOSE_INVALID_PATH   0x8
 draft-ietf-moq-transport-19 3.5 INVALID_PATH session code (a SETUP carried PATH over WebTransport, 10.4).
#define WIRED_MOQTRUN_CLOSE_INVALID_AUTHORITY   0x19
 draft-ietf-moq-transport-19 3.5 INVALID_AUTHORITY session code (a SETUP carried AUTHORITY over WebTransport, 10.4).
#define WIRED_MOQTRUN_CLOSE_MALFORMED_PATH   0x9
 draft-ietf-moq-transport-19 3.5 / -22 12.2 MALFORMED_PATH session code (a raw-QUIC SETUP's PATH is not path-abempty [?query], 10.3.1.2).
#define WIRED_MOQTRUN_CLOSE_MALFORMED_AUTHORITY   0x1A
 draft-ietf-moq-transport-19 3.5 / -22 12.2 MALFORMED_AUTHORITY session code (a raw-QUIC SETUP's AUTHORITY is no RFC 3986 authority, 10.3.1.1).
#define WIRED_MOQTRUN_CLOSE_TOO_MANY_REQUEST_UPDATES   0x1B
 draft-ietf-moq-transport-19 3.5/10.9 TOO_MANY_REQUEST_UPDATES session code: a request stream already holding MAX_REQUEST_UPDATES outstanding REQUEST_UPDATEs received one more.
#define WIRED_MOQTRUN_CLOSE_AUTH_TOKEN_CACHE_OVERFLOW   0x13
 draft-ietf-moq-transport-22 8.9 / 12.2 AUTH_TOKEN_CACHE_OVERFLOW session code: a REGISTER Token exceeded the hub's 0-byte token cache.
#define WIRED_MOQTRUN_CLOSE_UNKNOWN_AUTH_TOKEN_ALIAS   0x17
 draft-ietf-moq-transport-22 8.9 / 12.2 UNKNOWN_AUTH_TOKEN_ALIAS session code: a Token referenced an Alias the hub never registered.
#define WIRED_MOQTRUN_MAX_FILTER_RANGES   4
 MAX_FILTER_RANGES the hub advertises in its SETUP (draft-19 10.4): Ranges accepted concurrently across one subscription's or fetch's Range filter parameters (10.2.10-10.2.14); a request past it is answered REQUEST_ERROR INVALID_FILTER.
#define WIRED_MOQTRUN_MAX_REQ_UPDATES   4
 MAX_REQUEST_UPDATES the hub advertises in its SETUP (draft-19 10.4): outstanding REQUEST_UPDATEs it accepts per request stream before closing with TOO_MANY_REQUEST_UPDATES.
#define WIRED_MOQTRUN_IMPL_MAX   64
 Longest MOQT_IMPLEMENTATION value (10.4) copied from the client's SETUP; longer values are kept truncated.
#define WIRED_MOQTRUN_HOLD_BUF   2048
 Per-peer buffer for request/Object stream deliveries arriving before SETUP completes both directions (draft-19 3.3): a byte log of (stream id, length, fin, bytes) records replayed in arrival order once the session establishes.
#define WIRED_MOQTRUN_EARLY_BUF   2048
 Per-peer buffer for one SUBGROUP stream that reaches the hub before the publisher's SUBSCRIBE_OK to the hub's upstream SUBSCRIBE (draft-22 3.1.3.1 MAY: its Track Alias is not known yet), relayed once the OK claims the track.
#define WIRED_MOQTRUN_GOAWAY_URI_MAX   8192
 Longest New Session URI wired_moqt_goaway sends: the spec maximum (draft-22 9.2, draft-18/19 10.4).
#define WIRED_MOQTRUN_GOAWAY_MSG_MAX   ((usz)WIRED_MOQTRUN_GOAWAY_URI_MAX + 32)
 Largest GOAWAY envelope: the URI plus Type, Length, Request ID and URI Length varints.
#define WIRED_MOQTRUN_DRAIN_TIMEOUT_MS   5000
 GOAWAY Timeout the hub gives a session whose peer sent WT_DRAIN_SESSION (wired_moqt_on_session_draining): the peer asked to go, so a short grace for its subscriptions to wind down.
#define WIRED_MOQTRUN_TRACK_PROPS_MAX   32
 Largest Track Properties block a track keeps to forward in SUBSCRIBE_OK: what still fits a WIRED_MOQTRUN_CTL_REPLY_MAX (64) envelope beside the Type/Length (3), the Track Alias (8) and a LARGEST_OBJECT parameter (19).
#define WIRED_MOQTRUN_RELAY_HDR_MAX   40
 Fixed capacity for a saved SUBGROUP_HEADER (draft SS11.4.2: Type + Track Alias + Group ID + optional Subgroup ID varints + optional 1-byte Publisher Priority = at most 4*9+1 = 37 bytes).
#define WIRED_MOQTRUN_RELAY_FRAG_MAX   16384
 Cap on a held tail: the bytes of an Object split across deliveries (past the last complete Object boundary, kept until the next delivery completes them – wired_moqtrun_relay's frag doc), and the size of one WIRED_MOQTRUN_FRAG_POOL buffer.
#define WIRED_MOQTRUN_FRAG_POOL   8
 Hub-wide buffers for held-back Object fragments, shared by every relay (a relay holds one only while an Object is torn across deliveries).
#define WIRED_MOQTRUN_RESET_AFTER_BUSY   8
 Consecutive refused relay rounds (io.stream_send returning busy) after which a subscriber's relay stream is abandoned via io.stream_reset and re-opened fresh (with the saved SUBGROUP_HEADER) on a later round: live audio wants the newest frame delivered, not a faithful replay of a stale backlog.
#define WIRED_MOQTRUN_MAX_RELAYS   4
 Fixed capacity: publisher streams relayed concurrently per track.
#define WIRED_MOQTRUN_MAX_NAME   64
 Fixed capacity for the copied participant id (Track Name) recorded on PUBLISH, used with the namespace (WIRED_MOQTRUN_MAX_NS) to match a later SUBSCRIBE to the right peer.
#define WIRED_MOQTRUN_MAX_NS   128
 Fixed capacity for a track's encoded Track Namespace (count + each field's length + bytes, draft 1.5): MOQCTL_MAX_NS_FIELDS one-byte fields take 65.
#define WIRED_MOQTRUN_MAX_TRACKS_PER_PEER   4
 Fixed capacity: tracks one peer can PUBLISH at once (chat + audio + screen + the screen's low-rate SSTS variant, screen-lo).
#define WIRED_MOQTRUN_SUB_NAMES   ((usz)WIRED_MOQTRUN_MAX_TRACKS_PER_PEER * 4)
 Fixed capacity: Track Names one peer remembers having SUBSCRIBEd to (wired_moqtrun_peer.sub_names).
#define WIRED_MOQTRUN_CTL_REPLY_MAX   64
 Largest control-message envelope this hub ever sends (SS10 Type+Length+Body), except GOAWAY, whose New Session URI may take up to WIRED_MOQTRUN_GOAWAY_URI_MAX bytes (wired_moqt_goaway sizes its own buffer).
#define WIRED_MOQTRUN_CTL_MSG_MAX   1024
 Largest received control-message Length (body bytes) this hub handles.
#define WIRED_MOQTRUN_CTL_HDR_MAX   11
 Type (vi64, up to 9 bytes) + 16-bit Length.
#define WIRED_MOQTRUN_MAX_REQS   96
 Fixed capacity: peer-opened request streams (draft-ietf-moq-transport-19 3.3) tracked at once, hub-wide.
#define WIRED_MOQTRUN_MAX_REQS_PER_SESSION   (WIRED_MOQTRUN_MAX_REQS / 4)
 Request streams one session may hold at once, so one session cannot take the whole pool: a fair quarter of it.
#define WIRED_MOQTRUN_CTL_REPLIES_MAX
 Replies one control-stream dispatch can queue: the shared control stream can carry several requests per call (moqtrun_dispatch_ctl_stream's own doc), and each can produce one reply – worst case here is one SUBSCRIBE reply per other connected peer's track, WIRED_MOQTRUN_MAX_SUBS * WIRED_MOQTRUN_MAX_TRACKS_PER_PEER of them.
#define WIRED_MOQTRUN_CTL_SEND_BUF
 Largest total this hub ever needs to buffer for one peer within one wired_moqt_on_stream_data dispatch: WIRED_MOQTRUN_CTL_REPLIES_MAX, or one longest GOAWAY (WIRED_MOQTRUN_GOAWAY_MSG_MAX), whichever is larger.
#define WIRED_MOQTRUN_REQ_SEND_BUF   ((usz)WIRED_MOQTRUN_CTL_REPLY_MAX * 4)
 Replies one request-stream delivery can queue: the request's own answer plus a few REQUEST_UPDATE answers arriving with it.
#define WIRED_MOQTRUN_MAX_RDV   16
 Fixed capacity: SUBSCRIBEs held for a publisher (RENDEZVOUS_TIMEOUT, draft-18/19 10.2.6, draft-22 9.20.6), hub-wide.
#define WIRED_MOQTRUN_RDV_PER_SESSION   (WIRED_MOQTRUN_MAX_RDV / 4)
 Holds one session may own, so one session cannot take the whole table (the WIRED_MOQTRUN_MAX_REQS_PER_SESSION pattern).
#define WIRED_MOQTRUN_RDV_MAX_MS   1500
 Longest hold, ms: the relay MAY use a shorter timeout (10.2.6).
#define WIRED_MOQTRUN_RDV_RETRY   1001
 Retry Interval (ms + 1, draft-18 10.6: 1 = immediately) sent with the EXCESSIVE_LOAD refusal of a hold that did not fit.
#define WIRED_MOQTRUN_MAX_UP   WIRED_MOQTRUN_MAX_RDV
 Fixed capacity: upstream SUBSCRIBEs the hub holds toward namespace publishers (draft-18/19 9.5, draft-22 7.6), hub-wide, one per Full Track Name (aggregation, 9.4).
#define WIRED_MOQTRUN_MAX_FETCHES   8
 Fixed capacity: FETCH responses (draft-ietf-moq-transport-19 10.12.3) being served at once, hub-wide.
#define WIRED_MOQTRUN_UPFETCH_BUDGET_MS   2000
 Longest an upstream FETCH may run (draft-ietf-moq-transport-22 3.2.3: a relay fetches what it lacks from upstream; 9.20.5: FILL_TIMEOUT is the total budget, this the implementation default when it is absent, and FILL_TIMEOUT shortens it).
#define WIRED_MOQTRUN_UPF_NONE   0
 wired_moqtrun_fetch.up_state: no upstream FETCH in flight.
#define WIRED_MOQTRUN_UPF_SENT   1
 wired_moqtrun_fetch.up_state: upstream FETCH sent, not yet answered.
#define WIRED_MOQTRUN_UPF_OK   2
 wired_moqtrun_fetch.up_state: upstream FETCH_OK received.
#define WIRED_MOQTRUN_GOAWAY_GRACE_MS   1000
 Minimum wall-clock milliseconds (wired_moqt_tick's own clock) between a drained session's PUBLISH_DONE flush and its GOAWAY_TIMEOUT close (3.6/10.11): long enough for a peer under load to read the flushed PUBLISH_DONE and its relay streams' resets before the session itself is gone, so it never races GOAWAY_TIMEOUT against those deliveries.
#define WIRED_MOQTRUN_PUBDONE_WAIT_MS   2000
 How long a publisher's PUBLISH_DONE may wait for the streams its Stream Count names but the hub has not seen relayed to their end (draft-ietf-moq-transport-19 10.11: PUBLISH_DONE may precede late-opening streams).

Typedefs

typedef int(* wired_moqt_authorize_fn) (void *ctx, const moqctl_ftn *name, const moqctl_token *token)
 draft-ietf-moq-transport-19 SS13.3 authorization hook: as authorize_subscribe the hub calls it once per SUBSCRIBE and per TRACK_STATUS naming a known track, as authorize_publish once per PUBLISH, each with the Full Track Name and the presented AUTHORIZATION TOKEN (Alias Type USE_VALUE; 0 when the message carried none).
typedef int(* wired_moqt_authorize_ns_fn) (void *ctx, u64 msg_type, const moqctl_ns *ns, const moqctl_token *token)
 draft-ietf-moq-transport-19 10.15 / 10.18 namespace authorization hook: the hub calls it once per PUBLISH_NAMESPACE or SUBSCRIBE_NAMESPACE (msg_type MOQNS_T_PUBLISH_NAMESPACE / MOQNS_T_SUBSCRIBE_NAMESPACE) with the Track Namespace or Prefix and the presented AUTHORIZATION TOKEN (Alias Type USE_VALUE; 0 when the message carried none).

Functions

void wired_moqt_init (wired_moqt_hub *hub, wired_moqt_io io)
 Zero-initialize hub and record the io table it will send through.
int wired_moqt_cache_attach (wired_moqt_hub *hub, u8 *arena, usz size)
 Gives the hub an Object cache for FETCH (draft-ietf-moq-transport-19 10.12.3): every whole Object a publisher sends is kept in arena, the oldest whole groups evicted first (app/moqt/cache/moqcache.h).
void wired_moqt_on_session (void *app_ctx, wired_wt_session *s, wired_span path, wired_span protocol)
 wired_wt_on_session-shaped: registers a new peer slot for s and opens its control stream carrying SETUP (draft 3.3).
void wired_moqt_on_session_raw (void *app_ctx, wired_wt_session *s, wired_span alpn)
 wired_rawq_on_session-shaped (srvrun's opt.raw_on_session): registers a raw-QUIC connection's implicit session s.
void wired_moqt_on_stream_data (void *app_ctx, wired_wt_session *s, u64 stream_id, wired_span data, int fin)
 wired_wt_on_stream_data-shaped: dispatches one chunk of a control, request or data stream to the hub's session/subscribe state machines and the relay logic.
void wired_moqt_on_datagram (void *app_ctx, wired_wt_session *s, wired_span data)
 wired_wt_on_datagram-shaped: relays one received OBJECT_DATAGRAM (draft-ietf-moq-transport-19 11.3.1) verbatim to every active subscriber whose Location Filter takes it, on the track its Track Alias names on the sending peer – the datagram twin of the SUBGROUP stream relay, but stateless: no relay entry, no held fragment, and no delivery to late subscribers (a datagram missed is gone; live audio wants the next frame, not a replay).
void wired_moqt_on_session_close (void *app_ctx, wired_wt_session *s)
 wired_wt_on_session_close-shaped: frees the peer slot registered for s and deactivates every subscription other peers' tracks held for it (their relays stop targeting its streams).
void wired_moqt_on_stream_reset (void *app_ctx, wired_wt_session *s, u64 stream_id, int mapped, u32 app_error_code)
 wired_wt_on_stream_reset-shaped: a RESET_STREAM / STOP_SENDING on one of s's request streams cancels that request (draft-ietf-moq-transport-19 3.3.3) – a SUBSCRIBE's subscription is released, a PUBLISH's track withdrawn, a PUBLISH_NAMESPACE withdrawn (NAMESPACE_DONE to its subscribers), a SUBSCRIBE_NAMESPACE's pushes stopped – and frees the stream's slot.
int wired_moqt_goaway (wired_moqt_hub *hub, wired_span new_uri, u64 timeout_ms)
 draft-ietf-moq-transport-19 3.6 / 10.4 graceful drain: sends GOAWAY (new_uri, timeout_ms) once on the control stream of every open session that has not had one.
void wired_moqt_on_session_draining (void *app_ctx, wired_wt_session *s)
 wired_wt_on_session_draining-shaped: the peer of s sent WT_DRAIN_SESSION, so s alone is drained as by wired_moqt_goaway (empty URI, WIRED_MOQTRUN_DRAIN_TIMEOUT_MS).
usz wired_moqt_publish_blob (wired_moqt_hub *hub, wired_span name, u64 track_alias, wired_span blob, wired_mspan wire)
 Publish a hub-owned static track: frames blob into wire (moqdata_blob_build: one SUBGROUP_HEADER carrying track_alias, then 16 KiB Objects) and records name.
int wired_moqt_publish_live (wired_moqt_hub *hub, wired_span name, u64 track_alias, const wired_span *frags, usz n_frags, u64 group_ms, u64 now_ms)
 Publish the hub's own clock-paced live track: Group g carries fragment g mod n_frags as its only Object (framed byte-identically to moqdata_msg_build: one Type-0x70 SUBGROUP_HEADER + one Object), Groups advancing every group_ms from now_ms.
void wired_moqt_tick (wired_moqt_hub *hub, u64 now_ms)
 Clock tick (wire to wired_srvrun_opt.on_step): the current Group is (now_ms - t0_ms) / group_ms; every live subscriber whose last accepted Group is older is sent it via io.send_uni2.

Detailed Description

draft-ietf-moq-transport-18/19/22 hub relay (section numbers are draft-19's unless a draft is named; each peer's negotiated draft, its moqver.h capability bits, picks the per-draft behavior): the app-facing layer wiring the other MOQT domains (vi/kvp/ctl/data/dgram/sess/fetch/ns/tstat/cache) onto the WT application API (app/http3/server/srvrun).

One hub is a central server: clients PUBLISH tracks under namespaces of their choosing, SUBSCRIBE / FETCH / TRACK_STATUS by full track name, and discover each other through PUBLISH_NAMESPACE / SUBSCRIBE_NAMESPACE. All state lives in this one struct, so a hub serves a single process.

The actual WT sends (open/append/reset) are routed through a caller- supplied wired_moqt_io table rather than calling wired_server_wt_* here directly, so this file has no link-time dependency on the QUIC/TLS stack and can be driven by a test harness with stub functions.

Macro Definition Documentation

◆ WIRED_MOQTRUN_CTL_MSG_MAX

#define WIRED_MOQTRUN_CTL_MSG_MAX   1024

Largest received control-message Length (body bytes) this hub handles.

draft-ietf-moq-transport-19 SS10 allows up to 65535; a longer message closes the session like an unknown Type (moqtrun_asm_pop).

◆ WIRED_MOQTRUN_CTL_REPLIES_MAX

#define WIRED_MOQTRUN_CTL_REPLIES_MAX
Value:
#define WIRED_MOQTRUN_CTL_REPLY_MAX
Largest control-message envelope this hub ever sends (SS10 Type+Length+Body), except GOAWAY,...
Definition moqtrun.h:579
#define WIRED_MOQTRUN_MAX_SUBS
Fixed capacity: subscribers recorded against the hub's single published track per session slot (every...
Definition moqtrun.h:41
#define WIRED_MOQTRUN_MAX_TRACKS_PER_PEER
Fixed capacity: tracks one peer can PUBLISH at once (chat + audio + screen + the screen's low-rate SS...
Definition moqtrun.h:566
u64 usz
unsigned size (size_t equivalent)
Definition types.h:20

Replies one control-stream dispatch can queue: the shared control stream can carry several requests per call (moqtrun_dispatch_ctl_stream's own doc), and each can produce one reply – worst case here is one SUBSCRIBE reply per other connected peer's track, WIRED_MOQTRUN_MAX_SUBS * WIRED_MOQTRUN_MAX_TRACKS_PER_PEER of them.

◆ WIRED_MOQTRUN_CTL_SEND_BUF

#define WIRED_MOQTRUN_CTL_SEND_BUF
Value:
#define WIRED_MOQTRUN_GOAWAY_MSG_MAX
Largest GOAWAY envelope: the URI plus Type, Length, Request ID and URI Length varints.
Definition moqtrun.h:275
#define WIRED_MOQTRUN_CTL_REPLIES_MAX
Replies one control-stream dispatch can queue: the shared control stream can carry several requests p...
Definition moqtrun.h:622

Largest total this hub ever needs to buffer for one peer within one wired_moqt_on_stream_data dispatch: WIRED_MOQTRUN_CTL_REPLIES_MAX, or one longest GOAWAY (WIRED_MOQTRUN_GOAWAY_MSG_MAX), whichever is larger.

◆ WIRED_MOQTRUN_EARLY_BUF

#define WIRED_MOQTRUN_EARLY_BUF   2048

Per-peer buffer for one SUBGROUP stream that reaches the hub before the publisher's SUBSCRIBE_OK to the hub's upstream SUBSCRIBE (draft-22 3.1.3.1 MAY: its Track Alias is not known yet), relayed once the OK claims the track.

The race window is ~1 RTT, the same as WIRED_MOQTRUN_HOLD_BUF's; a stream that outgrows it is dropped as before. ponytail: one stream per peer; raise if publishers open several.

◆ WIRED_MOQTRUN_FRAG_POOL

#define WIRED_MOQTRUN_FRAG_POOL   8

Hub-wide buffers for held-back Object fragments, shared by every relay (a relay holds one only while an Object is torn across deliveries).

A torn Object finding none free is dropped like an oversized one (moqtrun_relay_save_frag). 8 covers every concurrently torn stream the chat room produces (a few screen/audio/chat streams in flight at once); past that only the excess stream is dropped (ended at its last whole Object), never another stream's bytes.

◆ WIRED_MOQTRUN_GOAWAY_GRACE_MS

#define WIRED_MOQTRUN_GOAWAY_GRACE_MS   1000

Minimum wall-clock milliseconds (wired_moqt_tick's own clock) between a drained session's PUBLISH_DONE flush and its GOAWAY_TIMEOUT close (3.6/10.11): long enough for a peer under load to read the flushed PUBLISH_DONE and its relay streams' resets before the session itself is gone, so it never races GOAWAY_TIMEOUT against those deliveries.

ponytail: fixed grace, not an ack wait; raise if a slow peer is still seen losing the race.

◆ WIRED_MOQTRUN_HOLD_BUF

#define WIRED_MOQTRUN_HOLD_BUF   2048

Per-peer buffer for request/Object stream deliveries arriving before SETUP completes both directions (draft-19 3.3): a byte log of (stream id, length, fin, bytes) records replayed in arrival order once the session establishes.

The pre-SETUP window is ~1 RTT, so bursts are tiny; a request delivery that does not fit is reset EXCESSIVE_LOAD at arrival, an Object delivery is dropped. ponytail: flat per-peer log; raise if real clients race SETUP with more data.

◆ WIRED_MOQTRUN_IMPL_MAX

#define WIRED_MOQTRUN_IMPL_MAX   64

Longest MOQT_IMPLEMENTATION value (10.4) copied from the client's SETUP; longer values are kept truncated.

ponytail: informational only; widen if an operator needs more.

◆ WIRED_MOQTRUN_MAX_FETCHES

#define WIRED_MOQTRUN_MAX_FETCHES   8

Fixed capacity: FETCH responses (draft-ietf-moq-transport-19 10.12.3) being served at once, hub-wide.

A FETCH past it is answered REQUEST_ERROR INTERNAL_ERROR. ponytail: room-sized; raise when clients fetch in parallel.

◆ WIRED_MOQTRUN_MAX_FILTER_RANGES

#define WIRED_MOQTRUN_MAX_FILTER_RANGES   4

MAX_FILTER_RANGES the hub advertises in its SETUP (draft-19 10.4): Ranges accepted concurrently across one subscription's or fetch's Range filter parameters (10.2.10-10.2.14); a request past it is answered REQUEST_ERROR INVALID_FILTER.

Matches the per-subscription range storage (wired_moqtrun_sub). ponytail: room-sized; raise with the storage if clients filter finer.

◆ WIRED_MOQTRUN_MAX_NS

#define WIRED_MOQTRUN_MAX_NS   128

Fixed capacity for a track's encoded Track Namespace (count + each field's length + bytes, draft 1.5): MOQCTL_MAX_NS_FIELDS one-byte fields take 65.

A longer namespace is refused on PUBLISH, never truncated (truncation would make distinct tracks match).

◆ WIRED_MOQTRUN_MAX_RDV

#define WIRED_MOQTRUN_MAX_RDV   16

Fixed capacity: SUBSCRIBEs held for a publisher (RENDEZVOUS_TIMEOUT, draft-18/19 10.2.6, draft-22 9.20.6), hub-wide.

Each hold already pins one request-stream slot (WIRED_MOQTRUN_MAX_REQS = 96), so 16 lets a sixth of the pool wait at once – interop clients hold one (moq-test-*, rendezvous-timeout) or two (two subscribers of one track). Past it, or past WIRED_MOQTRUN_RDV_PER_SESSION, the SUBSCRIBE is refused EXCESSIVE_LOAD at once, never dropped. Each slot ~1.3 KB of BSS. ponytail: room-sized; raise with WIRED_MOQTRUN_MAX_REQS.

◆ WIRED_MOQTRUN_MAX_RELAYS

#define WIRED_MOQTRUN_MAX_RELAYS   4

Fixed capacity: publisher streams relayed concurrently per track.

The audio track holds ONE for its whole call; chat holds one per in-flight message (open -> data rounds -> FIN, ~2 RTT) – 4 covers a burst without meaningfully growing the peer table. A stream arriving with every slot busy is not relayed (its subscribers miss that one message).

◆ WIRED_MOQTRUN_MAX_REQ_UPDATES

#define WIRED_MOQTRUN_MAX_REQ_UPDATES   4

MAX_REQUEST_UPDATES the hub advertises in its SETUP (draft-19 10.4): outstanding REQUEST_UPDATEs it accepts per request stream before closing with TOO_MANY_REQUEST_UPDATES.

One more than fits a reply buffer's coalesced answers (WIRED_MOQTRUN_REQ_SEND_BUF's sizing).

◆ WIRED_MOQTRUN_MAX_REQS

#define WIRED_MOQTRUN_MAX_REQS   96

Fixed capacity: peer-opened request streams (draft-ietf-moq-transport-19 3.3) tracked at once, hub-wide.

A request stream past it is reset with EXCESSIVE_LOAD; a completed request frees its slot once both sides have ended. Each slot is ~1.9 KB of BSS. Sized for a full moqt_chat room with track switching on (draft-22, one request per stream): each of 4 peers holds 4 PUBLISH + 3 namespace requests + 3x4 SUBSCRIBEs = 19 streams (76 hub-wide), so 96 keeps the per-session quarter (24) above 19 with headroom for a fill or FETCH. ponytail: room-sized; raise when rooms grow.

◆ WIRED_MOQTRUN_MAX_REQS_PER_SESSION

#define WIRED_MOQTRUN_MAX_REQS_PER_SESSION   (WIRED_MOQTRUN_MAX_REQS / 4)

Request streams one session may hold at once, so one session cannot take the whole pool: a fair quarter of it.

Past it a new request stream is reset with EXCESSIVE_LOAD (draft-ietf-moq-transport-19 3.3.4).

◆ WIRED_MOQTRUN_MAX_SESSIONS

#define WIRED_MOQTRUN_MAX_SESSIONS   32

Fixed capacity: concurrent sessions the hub tracks at once.

Small on purpose – a room-sized deployment, not a general server. ponytail: raise if a real deployment needs more concurrent participants.

◆ WIRED_MOQTRUN_MAX_TRACKS_PER_PEER

#define WIRED_MOQTRUN_MAX_TRACKS_PER_PEER   4

Fixed capacity: tracks one peer can PUBLISH at once (chat + audio + screen + the screen's low-rate SSTS variant, screen-lo).

Each track slot is ~13 KB (31 subs + 4 relays), so 3 -> 4 grows the peer table by ~32 slots of that; SUB_NAMES and CTL_SEND_BUF scale with it below.

◆ WIRED_MOQTRUN_MAX_UP

#define WIRED_MOQTRUN_MAX_UP   WIRED_MOQTRUN_MAX_RDV

Fixed capacity: upstream SUBSCRIBEs the hub holds toward namespace publishers (draft-18/19 9.5, draft-22 7.6), hub-wide, one per Full Track Name (aggregation, 9.4).

Every pending one has a waiter in hub->rdv, so WIRED_MOQTRUN_MAX_RDV of them covers every hold going upstream at once; an Established one lives as long as its track, at most one of each publisher's WIRED_MOQTRUN_MAX_TRACKS_PER_PEER slots. Past it a waiter with no deadline is refused EXCESSIVE_LOAD. ~1.3 KB of BSS each. ponytail: room-sized; raise with WIRED_MOQTRUN_MAX_RDV.

◆ WIRED_MOQTRUN_PUBDONE_WAIT_MS

#define WIRED_MOQTRUN_PUBDONE_WAIT_MS   2000

How long a publisher's PUBLISH_DONE may wait for the streams its Stream Count names but the hub has not seen relayed to their end (draft-ietf-moq-transport-19 10.11: PUBLISH_DONE may precede late-opening streams).

Bounds a count the hub never reaches, e.g. 2^62-1 ("unknown"); past it the subscribers' PUBLISH_DONE goes out with the streams still open reset.

◆ WIRED_MOQTRUN_RDV_MAX_MS

#define WIRED_MOQTRUN_RDV_MAX_MS   1500

Longest hold, ms: the relay MAY use a shorter timeout (10.2.6).

Below the 2 s a runner client allots to rendezvous-timeout: imquic asks 500000 for its 500 ms window (microseconds read as ms), so any larger cap misses the REQUEST_ERROR TIMEOUT it waits for. Still above the publisher lag of the moq-rs moq-test scenarios (they ask 5000 ms).

◆ WIRED_MOQTRUN_RELAY_FRAG_MAX

#define WIRED_MOQTRUN_RELAY_FRAG_MAX   16384

Cap on a held tail: the bytes of an Object split across deliveries (past the last complete Object boundary, kept until the next delivery completes them – wired_moqtrun_relay's frag doc), and the size of one WIRED_MOQTRUN_FRAG_POOL buffer.

A held tail is always shorter than its framed Object (Object ID Delta, Properties, Payload Length, payload), so a tail reaching this size belongs to a larger Object: it is dropped and its stream stops relaying (moqtrun_relay_save_frag). An Object that arrives whole in one delivery is never held. 16384 fits a chat attachment chunk or a small media frame. Datagram Objects are bounded by the QUIC datagram size instead.

◆ WIRED_MOQTRUN_RESET_AFTER_BUSY

#define WIRED_MOQTRUN_RESET_AFTER_BUSY   8

Consecutive refused relay rounds (io.stream_send returning busy) after which a subscriber's relay stream is abandoned via io.stream_reset and re-opened fresh (with the saved SUBGROUP_HEADER) on a later round: live audio wants the newest frame delivered, not a faithful replay of a stale backlog.

8 rounds of 20ms voice ~= 160ms of sustained send-slot fullness – the transient one-round busy bursts a healthy call shows (a handful scattered per 10s, measured) never trip it, while true send starvation (server CPU-capped) converts to a fresh stream well under a second, discarding the ~0.5s of backlog the send slot's staging can hold.

◆ WIRED_MOQTRUN_SUB_NAMES

#define WIRED_MOQTRUN_SUB_NAMES   ((usz)WIRED_MOQTRUN_MAX_TRACKS_PER_PEER * 4)

Fixed capacity: Track Names one peer remembers having SUBSCRIBEd to (wired_moqtrun_peer.sub_names).

The chat app subscribes to every track of every other candidate participant, and the sample room has four candidate ids, so a peer can hold 3 others * 4 tracks = 12 names; 16 leaves room without a rejoined publisher's oldest name being evicted.

◆ WIRED_MOQTRUN_TRACK_PROPS_MAX

#define WIRED_MOQTRUN_TRACK_PROPS_MAX   32

Largest Track Properties block a track keeps to forward in SUBSCRIBE_OK: what still fits a WIRED_MOQTRUN_CTL_REPLY_MAX (64) envelope beside the Type/Length (3), the Track Alias (8) and a LARGEST_OBJECT parameter (19).

ponytail: a larger block is forwarded empty; widen together with WIRED_MOQTRUN_CTL_REPLY_MAX if publishers send long properties.

◆ WIRED_MOQTRUN_UPFETCH_BUDGET_MS

#define WIRED_MOQTRUN_UPFETCH_BUDGET_MS   2000

Longest an upstream FETCH may run (draft-ietf-moq-transport-22 3.2.3: a relay fetches what it lacks from upstream; 9.20.5: FILL_TIMEOUT is the total budget, this the implementation default when it is absent, and FILL_TIMEOUT shortens it).

Past it the request is cancelled and the rest served from the cache, so no fetch slot waits on a silent peer. ponytail: fixed; make it a hub setting if rooms need another bound.

◆ WIRED_MOQTRUN_URGENCY

#define WIRED_MOQTRUN_URGENCY ( sub_prio,
pub_prio )
Value:
((u8)(4 + ((sub_prio) >> 7) * 2 + ((pub_prio) >> 7)))
unsigned char u8
unsigned 8-bit integer / byte
Definition types.h:18

RFC 9218 urgency of a subscriber stream from its subscription's Subscriber Priority and the stream's Publisher Priority (both 0..255, lower first, 128 when absent – draft-ietf-moq-transport-19 7.1, 10.2.7).

7.2 orders by subscriber priority, then publisher priority, so the subscriber's half picks the pair and the publisher's half the one within it: 4..7. Control and request streams keep the transport default 3 and so go first (7.2: they SHOULD be prioritized highest). The fallback when wired_moqt_io.stream_sched is 0: Group Order and the full 8-bit priorities need that hook's class; equal urgencies share the send pass in turn.

Typedef Documentation

◆ wired_moqt_authorize_fn

typedef int(* wired_moqt_authorize_fn) (void *ctx, const moqctl_ftn *name, const moqctl_token *token)

draft-ietf-moq-transport-19 SS13.3 authorization hook: as authorize_subscribe the hub calls it once per SUBSCRIBE and per TRACK_STATUS naming a known track, as authorize_publish once per PUBLISH, each with the Full Track Name and the presented AUTHORIZATION TOKEN (Alias Type USE_VALUE; 0 when the message carried none).

Return non-zero to grant, 0 to answer REQUEST_ERROR UNAUTHORIZED. The token scheme (CAT / Privacy Pass) is the deployment's to verify – this SDK carries the bytes, not the policy.

◆ wired_moqt_authorize_ns_fn

typedef int(* wired_moqt_authorize_ns_fn) (void *ctx, u64 msg_type, const moqctl_ns *ns, const moqctl_token *token)

draft-ietf-moq-transport-19 10.15 / 10.18 namespace authorization hook: the hub calls it once per PUBLISH_NAMESPACE or SUBSCRIBE_NAMESPACE (msg_type MOQNS_T_PUBLISH_NAMESPACE / MOQNS_T_SUBSCRIBE_NAMESPACE) with the Track Namespace or Prefix and the presented AUTHORIZATION TOKEN (Alias Type USE_VALUE; 0 when the message carried none).

Return non-zero to grant, 0 to answer REQUEST_ERROR UNAUTHORIZED.

Function Documentation

◆ wired_moqt_cache_attach()

int wired_moqt_cache_attach ( wired_moqt_hub * hub,
u8 * arena,
usz size )

Gives the hub an Object cache for FETCH (draft-ietf-moq-transport-19 10.12.3): every whole Object a publisher sends is kept in arena, the oldest whole groups evicted first (app/moqt/cache/moqcache.h).

Without one the hub caches nothing and a FETCH is answered with its range as unknown. Call once after wired_moqt_init, before any session; arena must outlive the hub.

Parameters
hubthe hub
arenacache storage, owned by the app
sizearena bytes (each Object costs MOQCACHE_HDR on top)
Returns
1 when caching is on, 0 for an empty arena

◆ wired_moqt_goaway()

int wired_moqt_goaway ( wired_moqt_hub * hub,
wired_span new_uri,
u64 timeout_ms )

draft-ietf-moq-transport-19 3.6 / 10.4 graceful drain: sends GOAWAY (new_uri, timeout_ms) once on the control stream of every open session that has not had one.

A session that got GOAWAY answers every later new request REQUEST_ERROR GOING_AWAY (requests already answered stay, and their REQUEST_UPDATEs are served). A session still open timeout_ms after this call is sent PUBLISH_DONE GOING_AWAY for every subscription it holds on a request stream (its relay streams reset GOING_AWAY first) by the next tick, and closed on the tick after: GOAWAY_TIMEOUT while it still has a request stream, a published track or a subscription open, NO_ERROR when nothing is left. The deadline counts from the last wired_moqt_tick's now_ms, so call this once the tick runs (a call before the first tick counts from 0). timeout_ms 0 sets no deadline (10.4: no specific timeout). A publisher's session ending, for any reason, sends its subscribers on other sessions PUBLISH_DONE TRACK_ENDED. Subscriptions made on the control stream get no PUBLISH_DONE (it has no Request ID to name them by).

Parameters
hubthe hub
new_uriwhere clients reconnect, empty to reuse the current URI (copied into the message)
timeout_msgrace before GOAWAY_TIMEOUT, 0 for none
Returns
sessions sent GOAWAY now, or -1 when new_uri is longer than WIRED_MOQTRUN_GOAWAY_URI_MAX (nothing sent)

◆ wired_moqt_on_datagram()

void wired_moqt_on_datagram ( void * app_ctx,
wired_wt_session * s,
wired_span data )

wired_wt_on_datagram-shaped: relays one received OBJECT_DATAGRAM (draft-ietf-moq-transport-19 11.3.1) verbatim to every active subscriber whose Location Filter takes it, on the track its Track Alias names on the sending peer – the datagram twin of the SUBGROUP stream relay, but stateless: no relay entry, no held fragment, and no delivery to late subscribers (a datagram missed is gone; live audio wants the next frame, not a replay).

app_ctx must be the wired_moqt_hub*. Each subscriber copy goes through io.send_datagram (accepted -> stat_dg_sent, refused -> stat_dg_drop); a datagram moqdg_take refuses or whose alias matches no track is dropped whole on stat_dg_bad – draft 11.3.1 says an invalid Type MUST close the session with PROTOCOL_VIOLATION, but this hub's io table has no close operation, so counting-and-dropping is the closest it can do. A session never registered, or an io table whose send_datagram is 0, is a no-op.

◆ wired_moqt_on_session()

void wired_moqt_on_session ( void * app_ctx,
wired_wt_session * s,
wired_span path,
wired_span protocol )

wired_wt_on_session-shaped: registers a new peer slot for s and opens its control stream carrying SETUP (draft 3.3).

app_ctx must be the wired_moqt_hub*. path/protocol are unused (room membership is hub-side fixed, not negotiated).

◆ wired_moqt_on_session_close()

void wired_moqt_on_session_close ( void * app_ctx,
wired_wt_session * s )

wired_wt_on_session_close-shaped: frees the peer slot registered for s and deactivates every subscription other peers' tracks held for it (their relays stop targeting its streams).

app_ctx must be the wired_moqt_hub*. Without this, a dead session's peer slot leaks forever and a reconnecting client whose new session reuses the same slot memory is mistaken for the dead peer – it never receives SETUP and stays mute until the process restarts. A session the hub never registered is a no-op.

◆ wired_moqt_on_session_draining()

void wired_moqt_on_session_draining ( void * app_ctx,
wired_wt_session * s )

wired_wt_on_session_draining-shaped: the peer of s sent WT_DRAIN_SESSION, so s alone is drained as by wired_moqt_goaway (empty URI, WIRED_MOQTRUN_DRAIN_TIMEOUT_MS).

app_ctx must be the wired_moqt_hub*.

◆ wired_moqt_on_session_raw()

void wired_moqt_on_session_raw ( void * app_ctx,
wired_wt_session * s,
wired_span alpn )

wired_rawq_on_session-shaped (srvrun's opt.raw_on_session): registers a raw-QUIC connection's implicit session s.

The MOQT draft comes from the ALPN token (moqt-NN, the same moqver table as the WT subprotocol; an unlisted one falls back to draft-19), and the control streams are the uni pair, as on a WT session with a negotiated token (-22 6.3/6.4). The client's PATH/AUTHORITY Setup Options are then judged by hub->raw_policy (moqraw_setup_verdict), and a GOAWAY to s carries an empty New Session URI (reuse the current one, -22 9.2). With no free peer slot s is closed INTERNAL_ERROR through io.close_session. app_ctx must be the wired_moqt_hub*.

Parameters
app_ctxthe wired_moqt_hub*
sthe connection's implicit session
alpnthe negotiated ALPN protocol id, e.g. "moqt-22"

◆ wired_moqt_on_stream_data()

void wired_moqt_on_stream_data ( void * app_ctx,
wired_wt_session * s,
u64 stream_id,
wired_span data,
int fin )

wired_wt_on_stream_data-shaped: dispatches one chunk of a control, request or data stream to the hub's session/subscribe state machines and the relay logic.

app_ctx must be the wired_moqt_hub*.

A peer-opened bidi stream is a request stream (draft-ietf-moq-transport-19 3.3): its messages go through the same handlers as the control stream's, and their replies go back on it. Its first message must be a request type and every later one must belong to that request, else the session closes with PROTOCOL_VIOLATION. Control and request messages are reassembled across calls; a FIN does not cancel a request (3.3.2). A request answered without establishing a subscription or track is complete: the hub FINs its side after the answer and frees the slot once the peer's side has ended too. With request streams on, a peer-opened bidi stream is never read as Object data.

Namespace discovery (6.1-6.2): a PUBLISH_NAMESPACE held open on its request stream is announced to every SUBSCRIBE_NAMESPACE whose prefix matches – NAMESPACE on the subscriber's stream, NAMESPACE_DONE once it is withdrawn by the last session publishing it (several may; each namespace is announced once). A session republishing its own namespace is refused UNINTERESTED; a session's prefixes overlapping (either empty, or the same first field) are refused PREFIX_OVERLAP. Both requests pass authorize_namespace first. Hub-owned tracks (publish_blob / publish_live) have no namespace and are not announced.

TRACK_STATUS (10.14) is answered like a SUBSCRIBE that creates nothing: REQUEST_OK with the Largest Location, or REQUEST_ERROR. REQUEST_UPDATE (10.9) on a SUBSCRIBE's stream replaces the parameters it carries (FORWARD, SUBSCRIBER_PRIORITY, OBJECT_DELIVERY_TIMEOUT, LOCATION_FILTER) and is answered REQUEST_OK; elsewhere it gets NOT_SUPPORTED. Objects reach a subscription only inside its Location Filter (Group-granular on streams), and one whose first byte arrived longer ago than its OBJECT_DELIVERY_TIMEOUT resets its stream with DELIVERY_TIMEOUT (draft 8).

◆ wired_moqt_on_stream_reset()

void wired_moqt_on_stream_reset ( void * app_ctx,
wired_wt_session * s,
u64 stream_id,
int mapped,
u32 app_error_code )

wired_wt_on_stream_reset-shaped: a RESET_STREAM / STOP_SENDING on one of s's request streams cancels that request (draft-ietf-moq-transport-19 3.3.3) – a SUBSCRIBE's subscription is released, a PUBLISH's track withdrawn, a PUBLISH_NAMESPACE withdrawn (NAMESPACE_DONE to its subscribers), a SUBSCRIBE_NAMESPACE's pushes stopped – and frees the stream's slot.

On a relayed publisher stream it returns the relay's held fragment buffer to the hub's pool; any other stream is a no-op. mapped/app_error_code are unused.

◆ wired_moqt_publish_blob()

usz wired_moqt_publish_blob ( wired_moqt_hub * hub,
wired_span name,
u64 track_alias,
wired_span blob,
wired_mspan wire )

Publish a hub-owned static track: frames blob into wire (moqdata_blob_build: one SUBGROUP_HEADER carrying track_alias, then 16 KiB Objects) and records name.

A later SUBSCRIBE naming name from any peer is answered SUBSCRIBE_OK – carrying track_alias, the alias the framed header itself has, so the subscriber can bind the stream to its subscription – and the framed bytes go to that peer once, on one uni stream (a single io.send_uni call: the SDK paces an oversized payload itself, holding it as a view). A repeat SUBSCRIBE from the same peer gets SUBSCRIBE_OK again but no second copy; a session close forgets the peer, so a reconnect receives it afresh. A refused send_uni answers REQUEST_ERROR (counted on stat_open_drop) and records nothing, so the peer's next SUBSCRIBE tries again. The hub-owned name wins over a peer track of the same name. Call once at boot, before any session; wire must outlive the hub (the framed bytes are held as a view).

Parameters
hubthe hub
nameTrack Name subscribers ask for (copied; at most WIRED_MOQTRUN_MAX_NAME bytes)
track_aliasTrack Alias carried by the framed header and by every SUBSCRIBE_OK for this track
blobthe bytes to publish (copied into wire's framing)
wiredestination for the framed bytes; size it with MOQDATA_BLOB_WIRE_CAP(blob.n)
Returns
framed byte count, or 0 when blob is empty, wire is too small or name is too long (hub state unchanged)

◆ wired_moqt_publish_live()

int wired_moqt_publish_live ( wired_moqt_hub * hub,
wired_span name,
u64 track_alias,
const wired_span * frags,
usz n_frags,
u64 group_ms,
u64 now_ms )

Publish the hub's own clock-paced live track: Group g carries fragment g mod n_frags as its only Object (framed byte-identically to moqdata_msg_build: one Type-0x70 SUBGROUP_HEADER + one Object), Groups advancing every group_ms from now_ms.

A later SUBSCRIBE naming name is answered SUBSCRIBE_OK carrying track_alias and immediately sent the Group current at the most recent wired_moqt_tick; each Group boundary a later tick crosses sends every subscriber the new Group's fragment on its own uni stream via io.send_uni2 (head = framing, body = the fragment, held as a view – frags and their bytes must outlive the hub). A refused send is retried while the clock is still in that Group and abandoned once it passes (counted on stat_live_drop) – a subscriber is never sent a stale Group. Call once at boot; a re-publish resets the track and forgets its subscribers.

Parameters
hubthe hub
nameTrack Name subscribers ask for (copied; at most WIRED_MOQTRUN_MAX_NAME bytes)
track_aliasTrack Alias carried by every framed header and every SUBSCRIBE_OK for this track
fragsper-Group fragment views (caller-owned, must outlive hub; every fragment must be non-empty – an empty Object payload would need the explicit Status varint this framing never carries)
n_fragsentries at frags
group_msGroup duration in milliseconds
now_mscurrent clock: Group 0 starts here
Returns
1, or 0 when n_frags or group_ms is 0, any fragment is empty or name is too long (hub state unchanged)

◆ wired_moqt_tick()

void wired_moqt_tick ( wired_moqt_hub * hub,
u64 now_ms )

Clock tick (wire to wired_srvrun_opt.on_step): the current Group is (now_ms - t0_ms) / group_ms; every live subscriber whose last accepted Group is older is sent it via io.send_uni2.

No live track: no-op.