You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The wire codec, all control messages and parameters, data streams/datagrams, the
session lifecycle, and the single-instance relay are implemented and wired end to
end. What remains is intentionally out of scope: behaviour the draft delegates to
the transport (congestion control, 0-RTT, communication/media security) and
global cross-session resource quotas, which sit above this library (per-session
caps and the Authorizer hook are the in-library surface).
How the number is derived. Each trackable feature below is scored
DONE = 1, PARTIAL = 0.5, MISSING = 0. Items the spec explicitly delegates
to QUIC/TLS or to deployment policy (most of §13) are scored on their hook/
surface-area completeness, not as protocol obligations. Legend:
DONE — wire codec + session/relay behaviour both present and wired.
PARTIAL — present but incomplete; see note.
MISSING — not implemented.
N/A (transport) — handled by the underlying QUIC/WebTransport stack.
What's implemented
By package, bottom-up along the dependency stack:
wire — byte-level codec: §1.4.1 leading-ones varints (distinct from
QUIC's RFC 9000 varints), length-prefixed bytes, delta-encoded KV pairs
(§1.4.3), track namespaces, reason phrases; an in-memory Reader and a
streaming Decoder over one control-frame interface.
message — typed control, request-stream, and data-stream messages with
parameter negotiation: SETUP, GOAWAY, SUBSCRIBE, PUBLISH (+DONE/BLOCKED),
FETCH (standalone + relative/absolute joining), TRACK_STATUS, REQUEST_UPDATE,
the namespace messages, §11 object framing (subgroup/fetch/datagram),
subscription filters, GREASE, and a parse-time Validate hook that rejects
structurally-malformed messages.
session — the SETUP handshake with version negotiation, control
multiplexing and request-ID allocation, §3.5 Track-Alias management with
collision detection, the request openers (Publish/Subscribe/Fetch/…) and
the AcceptRequest responder, typed inbound data streams that resolve
§11.4.2/§11.4.4 deltas to absolute IDs, GOAWAY, the §10.20 token cache, and
pluggable transport via the Conn interface (quicconn + wtconn adapters).
loc — Object.Encode/Decode: typed Timestamp/Timescale/VideoConfig/
VideoFrameMarking/AudioLevel properties with Extras passthrough for unknown
IDs, an RFC 6464 audio-level codec, and AVC/HEVC NAL framing detection.
msf — Catalog/Track JSON (independent and delta catalogs, with
Apply replaying delta operations in document order), group-ID sequencing,
the Media and Event Timeline record formats, the BeginBroadcast/
EndBroadcast* workflow helpers, and Catalog.Validate.
relay — routes objects through a track registry with per-subscription
live fanout under a §8 slow-reader policy, merges multiple upstream publishers
per track (§9.5) with §2.1 {Group, Object} dedup and survivor-continues
failover, serves FETCHes from a per-track cache (stitching evicted ranges from
an upstream FETCH), issues on-demand upstream SUBSCRIBEs to every matching
publisher (local and, via a DiscoveryStore + Dialer, remote), reflects
remote namespaces to local subscribers, gates requests through an Authorizer
hook, emits telemetry through a Metrics hook, and drains sessions with
GOAWAY.
§1.4 Foundational structures
§
Feature
Status
Notes
1.4.1
Variable-length integers
DONE
Leading-ones encoding (§1.4.1, NOT QUIC's RFC 9000 varint) in wire.AppendVarint/ParseVarint/ReadVarint; used by wire.Reader/Writer/StreamReader.Varint.
1.4.2
Location structure
DONE
message.Location with Compare/Less; KindLocation param serialization.
pkg/moqt/uri parses/validates moqt:// (scheme, non-empty host, default port 443, well-known, https conversion); msfdemo -addr accepts a URI and feeds AUTHORITY/PATH options.
3.1.2
Fragment identifiers (#type:value)
DONE
uri.Parse validates the type:value grammar (type ∈ [a-z0-9-]); fragment is kept local and dropped from the https URL.
3.1.3
WebTransport
DONE
wtconn adapter (webtransport-go).
3.1.4
Native QUIC
DONE
quicconn adapter (quic-go).
3.1.5
Connection URL
PARTIAL
Present in GOAWAY/REDIRECT; general handling deferred to app.
3.2
Extension negotiation
DONE
SETUP options exchanged as KV pairs; peer options parsed.
3.2.1
Reserved namespaces
DONE
AcceptRequest rejects an exact . first field with DOES_NOT_EXIST; other .-prefixed namespaces pass through to the application per spec.
3.2.2
Session-level tracks/namespaces
DONE
.session requests are rejected with DOES_NOT_EXIST before the application/relay sees them (no session-level extensions implemented), so relays never forward them; covers the empty-track-name rule.
3.3
Session initialization
DONE
Control streams + SETUP exchange; early data-stream buffering.
3.3.2
Request cancellation / rejection
DONE
STOP_SENDING, stream resets, REQUEST_ERROR in request.go.
3.3.3
Stream reset error codes
DONE
All codes in errors.go (StreamReset*).
3.4
Unidirectional stream types
DONE
SUBGROUP / FETCH / PADDING / SETUP type IDs dispatched.
All 4 types (NextGroupStart, LargestObject, AbsoluteStart, AbsoluteRange) + Matches.
5.1.3
Joining an ongoing track
DONE
Relative & absolute joining FETCH in fetch.go.
5.1.3.1
Dynamically starting new groups
DONE
Relay forwards a downstream NEW_GROUP_REQUEST upstream per §10.2.13: included in the on-demand upstream SUBSCRIBE (no established upstream) or sent as an upstream REQUEST_UPDATE, gated on DYNAMIC_GROUPS support, Largest-Group, and outstanding-request bookkeeping.
Subscriber/publisher priority + group order modeled.
7.2
Scheduling algorithm
DONE
EffectiveStreamPriority builds the composite session.StreamPriority (subscriber→publisher→group-order key→subgroup), covering rules 1–4; FETCH ordering is group-order + Object-ID per §10.12.3. Transport knob is currently a no-op (quic-go exposes no per-stream priority API — quic-go#437), so the order is computed and pushed through session.PrioritizedSendStream (propagation is test-covered) but not yet enforced on the wire.
7.3
Considerations for setting
DONE
Relay honours subscriber/publisher priority on fanout.
LRU+TTL object cache (cache/cache.go); updates limited to non-existence/properties.
9.2
Forward handling
DONE
FORWARD flag honoured; Forward=0 pauses delivery.
9.3
Multiple publishers
DONE
Per-track upstreams; dedup by {GroupID, ObjectID}.
9.4
Subscriber interactions
DONE
Upstream subscription established before SUBSCRIBE_OK; aggregation.
9.4.1
Graceful subscriber switchover
DONE
GOAWAY grace period (GoawayTimeout).
9.5
Publisher interactions
DONE
PUBLISH_NAMESPACE / PUBLISH with prefix matching (namespace_registry.go).
9.5.1
Graceful publisher switchover
DONE
Concurrent upstreams + cache dedup.
9.6
Relay track handling
DONE
Properties captured once at track creation, forwarded opaquely.
9.7
Relay object handling
DONE
Objects forwarded verbatim except alias remap + Object-ID delta re-encode.
§10 Control messages
§
Message / option
Type
Status
Notes
10.1
Request-ID parity/monotonicity
—
DONE
Enforced in AcceptRequest (per-role parity + monotonic).
10.2
Message parameters (13 types)
—
DONE
All defined with correct kinds; see §10.2.x below.
10.2.1
Parameter scope
—
DONE
Per-message scope validation.
10.2.2
AUTHORIZATION_TOKEN
0x03
DONE
4 alias types; session token cache resolves inbound.
10.2.3
SUBGROUP_DELIVERY_TIMEOUT
0x06
DONE
10.2.4
OBJECT_DELIVERY_TIMEOUT
0x02
DONE
10.2.5
FILL_TIMEOUT
0x0A
DONE
10.2.6
RENDEZVOUS_TIMEOUT
0x04
DONE
10.2.7
SUBSCRIBER_PRIORITY
0x20
DONE
10.2.8
GROUP_ORDER
0x22
DONE
Ascending/Descending validated.
10.2.9
SUBSCRIPTION_FILTER
0x21
DONE
Overflow-checked.
10.2.10
EXPIRES
0x08
DONE
10.2.11
LARGEST_OBJECT
0x09
DONE
Monotonic constraint applied.
10.2.12
FORWARD
0x10
DONE
10.2.13
NEW_GROUP_REQUEST
0x32
DONE
10.2.14
TRACK_NAMESPACE_PREFIX
0x34
DONE
10.3
SETUP
0x2F00
DONE
Bidirectional handshake; options as KV pairs.
10.3.1.1
AUTHORITY option
0x05
DONE
10.3.1.2
PATH option
0x01
DONE
10.3.1.3
MAX_AUTH_TOKEN_CACHE_SIZE
0x04
DONE
Sizes the token cache.
10.3.1.4
AUTHORIZATION_TOKEN (setup)
0x03
DONE
10.3.1.5
MOQT_IMPLEMENTATION
0x07
DONE
Advisory.
10.4
GOAWAY
0x10
DONE
Control- vs request-stream encoding; callback + watermark.
10.5
REQUEST_OK
0x07
DONE
Shared OK for PUBLISH/UPDATE/TRACK_STATUS/namespace reqs.
10.6
REQUEST_ERROR (+ Redirect)
0x05
DONE
Redirect required only when code==REDIRECT.
10.7
SUBSCRIBE
0x03
DONE
10.8
SUBSCRIBE_OK
0x04
DONE
Registers inbound track alias.
10.9
REQUEST_UPDATE
0x02
DONE
10.10
PUBLISH
0x1D
DONE
10.11
PUBLISH_DONE
0x0B
DONE
10.12
FETCH (standalone + joining)
0x16
DONE
All three fetch types.
10.13
FETCH_OK
0x18
DONE
10.14
TRACK_STATUS
0x0D
DONE
Reply via REQUEST_OK.
10.15
PUBLISH_NAMESPACE
0x06
DONE
10.16
NAMESPACE
0x08
DONE
10.17
NAMESPACE_DONE
0x0E
DONE
10.18
SUBSCRIBE_NAMESPACE
0x50
DONE
10.19
SUBSCRIBE_TRACKS
0x51
DONE
10.20
PUBLISH_BLOCKED
0x0F
DONE
§11 Data streams and datagrams
§
Feature
Status
Notes
11.1
Track alias
DONE
In subgroup header + datagram; validated.
11.2
Objects / object header
DONE
All header fields encoded.
11.2.1.1
Object status
DONE
Normal / EndOfGroup / EndOfTrack.
11.2.1.2
Object properties
DONE
Length-prefixed KV pairs.
11.3
Object datagram
DONE
Type bit-fields + invalid-combo rejection.
11.4
Streams (subgroup / fetch)
DONE
Typed in/out subgroup + fetch streams.
11.4.1
Stream cancellation
DONE
Bidi request-stream termination ends the request (handlers unregister on stream end); the relay sends PUBLISH_DONE on graceful subscription termination rather than abrupt reset.
11.4.2
Subgroup header + delta object IDs
DONE
All subgroup-ID modes; ReadDecoded resolves deltas.
11.4.3
Closing subgroup streams
DONE
Relay forwards only the next object on a stream (gap → reset+reopen), FINs on clean inbound EOF, resets on inbound reset, resets with MALFORMED_TRACK after a terminal EndOfGroup/EndOfTrack object (§2.4.2), marks reliable boundaries for RESET_STREAM_AT (SetReliableBoundary, transport-gated on EnableStreamResetPartialDelivery), and resets (not FINs) in-flight subgroups whose group falls out of range after a narrowing REQUEST_UPDATE.
11.4.4
Fetch header
DONE
11.4.4.1
Fetch flags
DONE
All subgroup modes + delta/priority/properties/status flags.
11.4.4.2
End of range
DONE
Non-existent (0x8C) / unknown (0x10C) handled.
11.5
Padding streams & datagrams
DONE
Recognised type IDs silently discarded.
§12 MOQT properties
§
Property
Type
Status
Notes
12.1
SUBGROUP_DELIVERY_TIMEOUT
0x06
DONE
12.2
OBJECT_DELIVERY_TIMEOUT
0x02
DONE
12.3
MAX_CACHE_DURATION
0x04
DONE
Lazy age-eviction in cache.
12.4
DEFAULT_PUBLISHER_PRIORITY
0x0E
DONE
12.5
DEFAULT_PUBLISHER_GROUP_ORDER
0x22
DONE
Validated.
12.6
DYNAMIC_GROUPS
0x30
DONE
Property defined & scope-validated (flow: see §5.1.3.1).
12.7
Immutable properties
0x0B
DONE
Relays cache & forward verbatim, never add.
12.8
Prior group ID gap
0x3C
DONE
Object-scope; encoder in msf/groupid.go.
12.9
Prior object ID gap
0x3E
DONE
Object-scope.
§13 Security considerations
Most of §13 is advice the draft delegates to the transport or to deployment
policy. This library provides the hooks; enforcement is the operator's.
§
Concern
Status
Notes
13.1
Subscription amplification
DONE
Config.MaxSubscriptionsPerSession caps concurrent subscriptions per session, rejecting excess with EXCESSIVE_LOAD before state mutation (0 = unlimited).
13.2
Communication security
N/A (transport)
TLS 1.3 via QUIC/WebTransport.
13.3
Authorization
DONE
Authorizer hook gates every request once before state mutation.
13.3.1
Replay attacks
PARTIAL
Session-scoped token cache; replay defence delegated to token scheme.
13.4
Media security
N/A
Payloads opaque; E2EE (e.g. SFrame) is external.
13.5
Resource exhaustion
DONE
QUIC flow control + slow-reader reset (fanout.go) + per-session subscription/namespace caps; the publisher cancels lowest-priority streams on overload. Global cross-session quotas remain a deployment concern.
13.6
Timeouts
DONE
Delivery timeouts enforced (§8).
13.6.1
Idle connection handling
PARTIAL
Keep-alive options documented; not enforced in-library.
13.7
Relay security
DONE
§13.7.1: Config.MaxNamespaceRequestsPerSession bounds PUBLISH_NAMESPACE/SUBSCRIBE_NAMESPACE/SUBSCRIBE_TRACKS state per session (EXCESSIVE_LOAD). §13.7.2: the Authorizer hook gates short-prefix subscriptions.
This is a single-instance reference relay, though cross-relay routing works
when wired up: set Config.Discovery + Config.Dialer and the relay follows a
FindNamespace lookup to dial and subscribe upstream on another instance (and
reflects remote namespaces to local subscribers via WatchNamespaces). Out of
scope: multi-hop loop detection (the only guard is skipping the relay's own
RelayAddr), an upstream connection-health / redial policy beyond
dial-on-demand, production DiscoveryStore backends (only the in-process
MemoryStore ships), GOAWAY cascading, and a Dialer for cmd/relay
itself (the binary stays single-instance; cross-relay is library-level).
Known protocol gaps, roughly ordered by how load-bearing they are:
Late publisher pickup (§9.5) — multiple publishers per track are merged
and deduplicated, but a publisher (or remote relay) that begins advertising
after a track's upstream set is established is not retroactively pulled in
until that set drains and a fresh SUBSCRIBE re-establishes it; publishers that
PUBLISH proactively are always merged.
Subscriber-priority scheduling (§7.2 / §10.2.7) — fully plumbed but not
enforced on the wire: the §7.2 composite key is computed
(EffectiveStreamPriority) and pushed through session.PrioritizedSendStream,
but quic-go and webtransport-go expose no per-stream priority API today
(quic-go#437), so the bundled
adapters absorb the knob and quic-go round-robins instead. A REQUEST_UPDATE
that changes priority mid-stream applies only to subsequently opened subgroups.
LOC encryption / SecureObjects and Private Properties — intentionally out
of scope pending a chosen SecureObjects revision. Some property IDs are
draft-tentative (e.g. PropAudioLevel = 0x0A, pending IANA assignment).
MSF — no timeline GZIP compression, content protection (§4.3), token
authorization, or logs/analytics. No built-in ABR helper: every catalog field
a selector needs is surfaced (AltGroup, Width/Height, Bitrate, RenderGroup,
Depends, TemporalID, SpatialID), but variant-selection policy is the
application's job.