wired
libc-free QUIC/HTTP3 SDK in C for x86_64-linux
Loading...
Searching...
No Matches
wired_moqtrun_relay Struct Reference

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...

#include <moqtrun.h>

Data Fields

int in_use
 1 while this relay follows a publisher stream.
u64 pub_stream_id
 The publisher-side stream this relay follows (its key).
u8 hdr [WIRED_MOQTRUN_RELAY_HDR_MAX]
 The stream's opening SUBGROUP_HEADER, as received.
usz hdr_len
 Bytes of hdr in use.
u8 default_pub_prio
 The track's DEFAULT_PUBLISHER_PRIORITY when this relay started: the Publisher Priority of a header that omits it (12.4).
i32 frag_idx
 Index of the hub's frag_pool buffer holding the fragment, -1 when none is held (frag_len 0).
usz frag_len
 Bytes of the held fragment; 0 when none is held.
u64 sub_stream_id [WIRED_MOQTRUN_MAX_SUBS]
 Per sub slot i of the track's subs[]: the subscriber-side uni stream this relay forwards on, valid while sub_stream_set[i].
int sub_stream_set [WIRED_MOQTRUN_MAX_SUBS]
 Per sub slot i: 1 once sub_stream_id[i] is open.
u8 sub_busy_streak [WIRED_MOQTRUN_MAX_SUBS]
 Consecutive rounds sub slot i's stream_send was refused (saturates at 255): reaching WIRED_MOQTRUN_RESET_AFTER_BUSY sheds the stream (io.stream_reset) so the next round re-opens fresh at the newest frame instead of replaying the stale backlog.
i32 rel_idx
 Index into the hub's rel_pool while this relay runs reliably (its bytes ride a moqtrel ring instead of the drop-on-refusal path); -1 is the default: the lossy relay above, untouched.
moqdata_objseq seq
 Object-ID chaining state after the last whole Object relayed, and the stream's Group ID: lets header-less later deliveries resolve each Object's Location (11.4.2) for the track's Largest Object.
u64 group_id
 The stream's Group ID, from its SUBGROUP_HEADER.
u64 frag_ms
 Clock (wired_moqt_tick) at which the held fragment's first byte arrived: the age of the torn Object it starts (draft 8).
u32 sub_expired
 Bit i: sub slot i's stream was reset for OBJECT_DELIVERY_TIMEOUT and is not reopened for this Subgroup (draft 8).
u32 sub_reframe
 Bit i: sub slot i's stream was late-opened header-only; the first Object it is sent gets its Object ID Delta rewritten to the absolute Object ID (the first Object of a stream, draft-22 11.3.1).
u64 subgroup_id
 The stream's Subgroup ID (a mode-0b01 header's first Object ID, spelled out in a late-opened stream's header): SUBGROUP_FILTER's input.
u8 pub_prio
 The stream's Publisher Priority (the header's, else the track's default): PRIORITY_FILTER's input.

Detailed Description

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.

Keyed by the PUBLISHER's stream id, never per-track or per-sub alone: several publisher streams can be in flight at once on one track (a real browser delivers a chat message's bytes and its FIN as two separate calls, so message N's still-open relay overlaps message N+1's data – a single per-track/per-sub binding made N+1 append onto N's subscriber stream and N's late FIN unresolvable, wedging the subscriber's read-to-EOF forever).

hdr/hdr_len keep a copy of the stream's opening SUBGROUP_HEADER bytes for subscribers that join AFTER the relay started (the audio track's one long-lived stream typically opens before any peer has subscribed): a late joiner's stream is opened carrying the saved header alone, so its decoder sees a well-formed stream head even though it missed the original opening round (moqtrun_relay_late_open). On a ring-backed (reliable) relay whose ring still holds everything past the header, the late joiner then reads the whole stream from there (moqtrun_rel_late_attach_all).

frag_idx/frag_len hold the bytes past the LAST COMPLETE Object boundary of the most recent delivery, prepended to the next one before relaying (moqtrun_relay_normalize): deliveries slice the publisher's stream at arbitrary byte positions, but a relay round that gets dropped for one subscriber (stream_send refusing while its previous round is unACKed) vanishes WHOLE from that subscriber's stream – if the round ended mid-Object, the subscriber's decoder read the next round's bytes as the torn Object's continuation and mis-framed everything after it, forever (observed live: voice went permanently silent minutes into every call while rx bytes kept arriving). Forwarding only whole Objects makes every droppable round self-delimiting.

Field Documentation

◆ sub_busy_streak

u8 wired_moqtrun_relay::sub_busy_streak[WIRED_MOQTRUN_MAX_SUBS]

Consecutive rounds sub slot i's stream_send was refused (saturates at 255): reaching WIRED_MOQTRUN_RESET_AFTER_BUSY sheds the stream (io.stream_reset) so the next round re-opens fresh at the newest frame instead of replaying the stale backlog.

Any accepted round zeroes it.


The documentation for this struct was generated from the following file: