Documentation
¶
Overview ¶
Package message implements MoQT control- and request-stream message types per draft-ietf-moq-transport-19. Each Message exposes a wire Type and Append/Parse methods over wire.Writer/Reader.
Marshal writes a complete control-message frame (Type + Length + Payload). Parse reads the payload only; the caller is expected to have already read the frame header via wire.ReadFrame and dispatched on Type.
Index ¶
- Constants
- Variables
- func AppendTrackProperties(pairs []wire.KVPair) []byte
- func AuthorityOption(authority string) wire.KVPair
- func FetchEndBeforeStart(start, end Location) bool
- func FillTimeoutFromParam(ps Parameters) time.Duration
- func GreaseSetupOption() wire.KVPair
- func GreaseValue() uint64
- func IsFetchHeaderType(typ uint64) bool
- func IsMandatoryTrackProperty(t PropertyType) bool
- func IsRangeFilterParam(t ParamID) bool
- func IsReservedSubgroupHeaderType(t uint64) bool
- func IsSubgroupHeaderType(t uint64) bool
- func IsValidDatagramType(typ uint64) bool
- func MOQTImplementationOption(nameAndVersion string) wire.KVPair
- func Marshal(dst io.Writer, m Message) error
- func MaxAuthTokenCacheSizeOption(maxBytes uint64) wire.KVPair
- func MaxFilterRangesOption(maxRanges uint64) wire.KVPair
- func MaxRequestUpdatesOption(maxUpdates uint64) wire.KVPair
- func MillisecondTimeout(ms uint64) time.Duration
- func ObjectDeliveryTimeoutFromParam(ps Parameters) time.Duration
- func ParseTrackProperties(raw []byte) ([]wire.KVPair, error)
- func PathOption(pathAndQuery string) wire.KVPair
- func ReadDataStreamType(r io.Reader) (uint64, error)
- func SubgroupDeliveryTimeoutFromParam(ps Parameters) time.Duration
- func WriteFetchHeader(w io.Writer, h FetchHeader) error
- func WriteSubgroupHeader(w io.Writer, h SubgroupHeader) error
- type AliasType
- type DeliveryTimeouts
- type ErrUnknownType
- type Fetch
- type FetchHeader
- type FetchOK
- type FetchObject
- func (o *FetchObject) Append(w *wire.Writer)
- func (o *FetchObject) IsDatagram() bool
- func (o *FetchObject) IsEndOfRangeGroup() bool
- func (o *FetchObject) IsEndOfRangeObject() bool
- func (o *FetchObject) Parse(r wire.Decoder) error
- func (o *FetchObject) SubgroupMode() FetchSubgroupIDMode
- func (o *FetchObject) Validate() error
- type FetchSubgroupIDMode
- type FetchType
- type FilterType
- type Goaway
- type GroupOrder
- type JoiningFetch
- type Location
- type LocationFilter
- func (f *LocationFilter) Append(w *wire.Writer)
- func (f *LocationFilter) Bytes() []byte
- func (f *LocationFilter) EndGroup() uint64
- func (f *LocationFilter) Matches(group, object uint64, largestGroup, largestObject uint64, hasLargest bool) bool
- func (f *LocationFilter) Parse(r *wire.Reader) error
- func (f *LocationFilter) Validate() error
- type Message
- type Namespace
- type NamespaceDone
- type ObjectDatagram
- func (d *ObjectDatagram) Append(w *wire.Writer)
- func (d *ObjectDatagram) HasDefaultPriority() bool
- func (d *ObjectDatagram) HasEndOfGroup() bool
- func (d *ObjectDatagram) HasProperties() bool
- func (d *ObjectDatagram) HasStatus() bool
- func (d *ObjectDatagram) HasZeroObjectID() bool
- func (d *ObjectDatagram) Parse(r *wire.Reader) error
- func (d *ObjectDatagram) Validate() error
- type ParamID
- type ParamKind
- type Parameter
- func AbsoluteRangeFilter(start Location, endGroupDelta uint64) Parameter
- func AbsoluteStartFilter(start Location) Parameter
- func AuthorizationTokenParam(t Token) Parameter
- func ByteParam(t ParamID, v uint8) Parameter
- func BytesParam(t ParamID, v []byte) Parameter
- func ExpiresParam(d time.Duration) Parameter
- func FillTimeoutParam(d time.Duration) Parameter
- func ForwardParam(forward bool) Parameter
- func GroupOrderParam(order GroupOrder) Parameter
- func LargestObjectFilter() Parameter
- func LargestObjectParam(group, object uint64) Parameter
- func LocationFilterParam(f *LocationFilter) Parameter
- func LocationParam(t ParamID, g, o uint64) Parameter
- func NewGroupRequestParam(largestGroupPlusOne uint64) Parameter
- func NextGroupStartFilter() Parameter
- func ObjectDeliveryTimeoutParam(d time.Duration) Parameter
- func RangeFilterParam(f *RangeFilter) Parameter
- func RendezvousTimeoutParam(d time.Duration) Parameter
- func SubgroupDeliveryTimeoutParam(d time.Duration) Parameter
- func SubscriberPriorityParam(priority uint8) Parameter
- func TrackNamespacePrefixParam(prefix wire.TrackNamespace) Parameter
- func VarintParam(t ParamID, v uint64) Parameter
- type Parameters
- type PropertyType
- type Publish
- type PublishDone
- type PublishNamespace
- type PublishSkipped
- type Range
- type RangeFilter
- type RangeFilterSet
- func (s *RangeFilterSet) MatchesObject(subgroupID, objectID uint64, priority uint8, objProps []byte) bool
- func (s *RangeFilterSet) MatchesObjectInSets(subgroupID, objectID uint64, priority uint8, objProps []byte, trackPass []bool) bool
- func (s *RangeFilterSet) MatchesTrack(trackProps []byte) bool
- func (s *RangeFilterSet) TrackPassPerGroup(trackProps []byte) []bool
- func (s *RangeFilterSet) Validate(maxFilterRanges uint64) error
- type Redirect
- type RequestError
- type RequestOK
- type RequestUpdate
- type ReservedSubgroupIDModeError
- type Setup
- type SetupOption
- type StandaloneFetch
- type SubgroupHeader
- type SubgroupIDMode
- type SubgroupObject
- func (o *SubgroupObject) Append(w *wire.Writer, hasProperties bool)
- func (o *SubgroupObject) IsEndOfGroup() bool
- func (o *SubgroupObject) IsEndOfTrack() bool
- func (o *SubgroupObject) IsTerminal() bool
- func (o *SubgroupObject) Parse(r wire.Decoder, hasProperties bool) error
- func (o *SubgroupObject) Validate() error
- type Subscribe
- type SubscribeNamespace
- type SubscribeOK
- type SubscribeTracks
- type Token
- type TrackStatus
- type TrackStatusOK
- type Type
- type UnknownDataStreamTypeError
- type WithRequestID
Constants ¶
const ( DatagramPropertiesBit = 0x01 // Properties field present DatagramEndOfGroupBit = 0x02 // End of group marker DatagramZeroObjectIDBit = 0x04 // Object ID omitted (treated as 0) DatagramDefaultPriorityBit = 0x08 // Priority omitted (use subscription default) DatagramStatusBit = 0x20 // Object Status present instead of payload )
Datagram type field bit constants (§11.3).
const ( DatagramTypeMin = 0x00 DatagramTypeMax = 0x0F DatagramTypeStatusMin = 0x20 DatagramTypeStatusMax = 0x2F )
Valid datagram type ranges.
const ( FetchFlagSubgroupIDMode uint64 = 0x03 // bits 0–1: subgroup encoding mode FetchFlagObjectIDDelta uint64 = 0x04 // bit 2: Object ID Delta present FetchFlagGroupIDDelta uint64 = 0x08 // bit 3: Group ID Delta present FetchFlagPriority uint64 = 0x10 // bit 4: Priority present FetchFlagProperties uint64 = 0x20 // bit 5: Properties present FetchFlagDatagram uint64 = 0x40 // bit 6: Datagram — ignore subgroup bits )
Serialization flag bits per §11.4.4.1 (Table 8 & 9).
Bits 0–1 (mask 0x03): Subgroup ID mode — see FetchSubgroupIDMode. Bit 2 (0x04): Object ID Delta present. Bit 3 (0x08): Group ID Delta present. Bit 4 (0x10): Priority field present. Bit 5 (0x20): Properties field present. Bit 6 (0x40): Datagram — no Subgroup ID; the subgroup-mode LSBs are ignored. Bit 7+ : reserved / end-of-range special values.
const ( FetchEndOfRangeObject = 0x8C // End of Non-Existent Range FetchEndOfRangeGroup = 0x10C // End of Unknown Range )
End of range markers per §11.4.4.2.
const ( ObjectStatusNormal uint64 = 0x0 // a normal object (carries a payload) ObjectStatusEndOfGroup uint64 = 0x3 // last object in the Group ObjectStatusEndOfTrack uint64 = 0x4 // last object in the Track )
Object Status values for objects with an empty payload (§11.2.1.1).
const MaxGoawayURIBytes = 8192
MaxGoawayURIBytes is the maximum New Session URI length per §10.4.
const PaddingStreamType uint64 = 0x132B3E28
PaddingStreamType is the leading Type varint of a padding uni-stream (§11.5.1). Receivers MUST silently discard padding streams.
Variables ¶
var ErrInvalidFilter = errors.New("moqt/message: invalid range filter (INVALID_FILTER §5.1.3)")
ErrInvalidFilter marks a malformed Range Filter (§5.1.3). The session/relay layer maps it to REQUEST_ERROR with code INVALID_FILTER (§10.6, 0x36). It is returned for a delta that overflows 2^64-1, an out-of-range PRIORITY value (§10.2.12), an odd Property Type on the Object/Track Property filters (§10.2.13/§10.2.14), and — at the session layer — a duplicate (Type, SetID, Property Type) combination or a total range count exceeding the negotiated MAX_FILTER_RANGES (§10.3.1.6).
var ErrUnknownFetchType = errors.New("moqt/message: unknown FETCH type")
ErrUnknownFetchType is returned for an unknown FETCH type.
Functions ¶
func AppendTrackProperties ¶
AppendTrackProperties serialises a slice of KV pairs as raw Track Properties bytes (no length prefix). The result is suitable for appending directly to a message writer via w.FixedBytes().
func AuthorityOption ¶
AuthorityOption builds an AUTHORITY setup option (§10.3.1.1). Client-only, native-QUIC only: a server-sent or WebTransport-sent AUTHORITY triggers INVALID_AUTHORITY. authority is the authority portion of the moqt URI.
func FetchEndBeforeStart ¶
FetchEndBeforeStart reports whether a standalone-FETCH range violates the §10.12 rule "End Location MUST specify the same or a larger Location than Start Location", interpreting the wire encoding: End is the last Object plus 1, and an End Object of 0 means "the entire group" (§10.12.1) — it only constrains the Group, so Start={G,5}, End={G,0} (the rest of group G) is valid. Equal Start/End denotes an EMPTY range (last = Start-1) and is also valid.
func FillTimeoutFromParam ¶
func FillTimeoutFromParam(ps Parameters) time.Duration
FillTimeoutFromParam extracts the FILL_TIMEOUT parameter (§10.2.5) from ps and converts it from milliseconds to time.Duration. Returns 0 if the parameter is absent. FILL_TIMEOUT MAY appear in a FETCH message; it is the maximum total duration a relay should spend waiting for upstream sources to provide objects that are not immediately available.
func GreaseSetupOption ¶
GreaseSetupOption returns a KVPair with a random GREASE type suitable for inclusion in a SETUP message's option list. Per §1.4.3, even types carry a varint value and odd types carry bytes; the GREASE pattern produces both parities, so the helper picks a value and fills the appropriate field with a small random payload.
func GreaseValue ¶
func GreaseValue() uint64
GreaseValue returns a random GREASE value from the reserved range. The returned value is suitable for use as a Setup Option type, Property type, or error code. Each call returns a fresh random value.
func IsFetchHeaderType ¶
IsFetchHeaderType reports whether typ is a FETCH_HEADER stream type (0x05).
func IsMandatoryTrackProperty ¶
func IsMandatoryTrackProperty(t PropertyType) bool
IsMandatoryTrackProperty reports whether t is in the mandatory range [0x4000, 0x7FFF] per §2.5.1.
func IsRangeFilterParam ¶
IsRangeFilterParam reports whether t is one of the five Range Filter parameter types (§5.1.3, 0x25-0x29).
func IsReservedSubgroupHeaderType ¶
IsReservedSubgroupHeaderType reports whether t looks like a SUBGROUP_HEADER type byte (bit 4 set, bit 7 clear) but has the reserved SUBGROUP_ID_MODE value 0b11 in bits 1-2. Per §11.4.2, receiving such a value MUST be treated as a session-level PROTOCOL_VIOLATION — unlike a truly unknown stream type, which may be ignorable (GREASE).
func IsSubgroupHeaderType ¶
IsSubgroupHeaderType reports whether t is one of the valid SUBGROUP_HEADER type values per §11.4.2: the four ranges 0x10..0x1F, 0x30..0x3F, 0x50..0x5F, 0x70..0x7F, excluding values where SUBGROUP_ID_MODE (bits 1-2) is 0b11.
func IsValidDatagramType ¶
IsValidDatagramType checks if a datagram type value is valid per §11.3.1 Figure 23: 0x00..0x0F / 0x20..0x21 / 0x24..0x25 / 0x28..0x29 / 0x2C..0x2D.
The two invalid classes MUST cause a session PROTOCOL_VIOLATION:
- values outside the 0b00X0XXXX form (i.e. not 0x00..0x0F / 0x20..0x2F);
- STATUS+END_OF_GROUP (0x22,0x23,0x26,0x27,0x2A,0x2B,0x2E,0x2F) — "an object status message cannot signal end of group".
Note STATUS+PROPERTIES (0x21,0x25,0x29,0x2D) IS a valid type: it only becomes an error when the Object Status is not Normal (0x0) — a per-value rule enforced by ObjectDatagram.Validate, not a type-level one.
func MOQTImplementationOption ¶
MOQTImplementationOption builds a MOQT_IMPLEMENTATION setup option (§10.3.1.5). Optional; intended for debugging and interop tracking. nameAndVersion SHOULD be the implementation name plus version (e.g. "mediamesh/0.1.0").
func MaxAuthTokenCacheSizeOption ¶
MaxAuthTokenCacheSizeOption builds a MAX_AUTH_TOKEN_CACHE_SIZE option (§10.3.1.3). maxBytes is the peer-allowed total size in bytes of registered authorization tokens. The default if omitted is 0, which prohibits the use of token Aliases.
func MaxFilterRangesOption ¶
MaxFilterRangesOption builds a MAX_FILTER_RANGES option (§10.3.1.6). maxRanges is the maximum total number of Ranges (Start/End pairs) the peer may send across all Range Filter parameters (§5.1.3) for a single subscription or fetch. The default if omitted is 0, which prohibits the peer from sending any Range Filter parameters.
func MaxRequestUpdatesOption ¶
MaxRequestUpdatesOption builds a MAX_REQUEST_UPDATES option (§10.3.1.7). maxUpdates is the maximum number of unacknowledged REQUEST_UPDATE messages the peer may have outstanding on any single request stream; the receiver of a REQUEST_UPDATE that exceeds it MUST close the session with TOO_MANY_REQUEST_UPDATES. The default if omitted is 0, which means the endpoint does not limit REQUEST_UPDATE concurrency.
func MillisecondTimeout ¶
MillisecondTimeout converts a varint millisecond count — the form every §8 timeout takes on the wire, whether it arrives as a Message Parameter (§10.2.3 / §10.2.4 / §10.2.5) or a Track/Object Property (§12.1 / §12.2) — to a time.Duration. Exported so every decoder of these values agrees by construction rather than by copies of the same multiplication.
func ObjectDeliveryTimeoutFromParam ¶
func ObjectDeliveryTimeoutFromParam(ps Parameters) time.Duration
ObjectDeliveryTimeoutFromParam extracts OBJECT_DELIVERY_TIMEOUT (§10.2.4) from ps, converting from milliseconds. Returns 0 when absent (§8: 0 disables the timeout).
func ParseTrackProperties ¶
ParseTrackProperties parses raw Track Properties bytes (the trailing field in PUBLISH, SUBSCRIBE_OK, FETCH_OK, etc.) as a sequence of KV pairs. Track Properties have no explicit length prefix — they are bounded by the outer message frame (§2.5). The raw bytes are typically obtained via wire.Reader.RemainingBytes().
Returns an error if any pair cannot be parsed. Mandatory Track Property screening (§2.5.1) is the caller's job — see FirstUnknownMandatoryTrackProperty.
func PathOption ¶
PathOption builds a PATH setup option (§10.3.1.2). Client-only, native-QUIC only: a PATH option received by a server, on a WebTransport session, or with an unsupported path triggers an INVALID_PATH session close. pathAndQuery is the path-abempty portion of the moqt URI, optionally followed by "?" and the query.
func ReadDataStreamType ¶
ReadDataStreamType reads the leading Type varint that prefixes every MoQT uni-stream data header (SUBGROUP_HEADER §11.4.2, FETCH_HEADER §11.4.4, padding §11.5.1, ...). A dispatcher uses this together with type predicates such as IsSubgroupHeaderType to decide how to consume the remainder of the stream.
func SubgroupDeliveryTimeoutFromParam ¶
func SubgroupDeliveryTimeoutFromParam(ps Parameters) time.Duration
SubgroupDeliveryTimeoutFromParam extracts SUBGROUP_DELIVERY_TIMEOUT (§10.2.3) from ps, converting from milliseconds. Returns 0 when absent.
func WriteFetchHeader ¶
func WriteFetchHeader(w io.Writer, h FetchHeader) error
WriteFetchHeader writes the FETCH_HEADER wire Type and Request ID.
func WriteSubgroupHeader ¶
func WriteSubgroupHeader(w io.Writer, h SubgroupHeader) error
WriteSubgroupHeader writes the full SUBGROUP_HEADER wire encoding (§11.4.2): Type, Track Alias, Group ID, optional Subgroup ID (when SubgroupIDMode == SubgroupIDExplicit), and optional Publisher Priority (when InlinePriority == true).
Types ¶
type AliasType ¶
type AliasType uint64
AliasType identifies the serialization and processing behavior of a Token per §10.2.2.
const ( // AliasTypeDelete (0x0): Alias only. Retire the alias and its associated // token from the cache. AliasTypeDelete AliasType = 0x0 // AliasTypeRegister (0x1): Alias + Type + Value. Register the alias in // the token cache for the duration of the session (or until deleted). AliasTypeRegister AliasType = 0x1 // AliasTypeUseAlias (0x2): Alias only. Resolve to the (Type, Value) // previously registered under this alias. AliasTypeUseAlias AliasType = 0x2 // AliasTypeUseValue (0x3): Type + Value only. Use the token directly; // no alias is stored. AliasTypeUseValue AliasType = 0x3 )
type DeliveryTimeouts ¶
type DeliveryTimeouts struct {
Object time.Duration // OBJECT_DELIVERY_TIMEOUT (§10.2.4)
Subgroup time.Duration // SUBGROUP_DELIVERY_TIMEOUT (§10.2.3)
}
DeliveryTimeouts holds the effective delivery timeout pair for one subscription per §8. Zero values mean "no timeout".
Both values are expressed as time.Duration (internally milliseconds on the wire). A value of 0 means the timeout is disabled for that dimension.
func DeliveryTimeoutsFromParams ¶
func DeliveryTimeoutsFromParams(ps Parameters) DeliveryTimeouts
DeliveryTimeoutsFromParams extracts both delivery timeouts (§10.2.3/§10.2.4) from ps — the form a subscriber communicates them in (§8).
func (DeliveryTimeouts) ApplyObjectProperties ¶
func (d DeliveryTimeouts) ApplyObjectProperties(rawProps []byte) DeliveryTimeouts
ApplyObjectProperties returns d with any OBJECT_DELIVERY_TIMEOUT (§12.2) or SUBGROUP_DELIVERY_TIMEOUT (§12.1) present in rawProps overriding the corresponding dimension. rawProps is the Object-Properties blob of the FIRST object in a subgroup (§12.1/§12.2: on the first object these override the Track-level value for that subgroup; on any other object they are ignored, so callers must invoke this only for the first object). A property present with value 0 overrides to "disabled"; an absent property leaves d's dimension unchanged. Malformed props leave d unchanged.
func (DeliveryTimeouts) Effective ¶
func (d DeliveryTimeouts) Effective(sub DeliveryTimeouts) DeliveryTimeouts
Effective resolves the timeouts a publisher enforces for a subscription per §8: the receiver holds the publisher's values (Track Property, or the first-object Object Property override — see DeliveryTimeouts.ApplyObjectProperties), sub holds the subscriber's Message-Parameter values, and each dimension is the smaller of the two non-zero values.
type ErrUnknownType ¶
type ErrUnknownType Type
ErrUnknownType is returned for a message type not implemented by this package. Per §10 the receiver MUST close the session with PROTOCOL_VIOLATION; callers translate accordingly.
func (ErrUnknownType) Error ¶
func (e ErrUnknownType) Error() string
type Fetch ¶
type Fetch struct {
RequestID uint64
FetchType FetchType
Standalone *StandaloneFetch // Present when FetchType == FetchTypeStandalone
Joining *JoiningFetch // Present when FetchType == FetchTypeRelativeJoining or FetchTypeAbsoluteJoining
Parameters Parameters
}
Fetch is a FETCH message per §10.12.
func (*Fetch) GetRequestID ¶
func (*Fetch) SetRequestID ¶
func (*Fetch) Validate ¶
Validate enforces the FETCH invariants the wire decoder cannot: the sub-message selected by FetchType must be present, and a Standalone FETCH's range must satisfy FetchEndBeforeStart's §10.12 rule. ParsePayload invokes this automatically after decoding a FETCH frame.
type FetchHeader ¶
type FetchHeader struct {
RequestID uint64
}
FetchHeader is the header of a FETCH_HEADER stream (§11.4.4). It identifies which FETCH request this stream responds to.
func ReadFetchHeader ¶
func ReadFetchHeader(r io.Reader) (FetchHeader, error)
ReadFetchHeader reads a FETCH_HEADER from r. The caller must have already read the stream type (0x05) via ReadDataStreamType.
func (FetchHeader) RawType ¶
func (h FetchHeader) RawType() uint64
RawType returns the leading Type varint as it appeared on the wire.
type FetchOK ¶
type FetchOK struct {
EndOfTrack bool
EndLocation Location
Parameters Parameters
TrackProperties []byte
}
FetchOK is a FETCH_OK message per §10.13.
type FetchObject ¶
type FetchObject struct {
// SerializationFlags control which fields are present and how they're encoded.
SerializationFlags uint64
// GroupIDDelta is the delta from the previous Group ID. Present when
// FetchFlagGroupIDDelta bit (0x08) is set.
GroupIDDelta uint64
// SubgroupID is encoded based on the two LSBs of SerializationFlags (mask 0x03).
// Only present on the wire when the mode is FetchSubgroupIDExplicit (0x03).
SubgroupID uint64
// ObjectIDDelta is the delta from the previous Object ID. Present when
// FetchFlagObjectIDDelta bit (0x04) is set.
ObjectIDDelta uint64
// PublisherPriority is present when FetchFlagPriority (0x10) is set.
PublisherPriority uint8
// Properties are present when FetchFlagProperties (0x20) is set.
Properties []byte
// ObjectPayload is always present, encoded on the wire with a varint
// length prefix (§11.4.4 Figure 27). FETCH objects carry no Object
// Status field (§11.2.1.1); absent ranges are expressed with the
// end-of-range markers instead.
ObjectPayload []byte
}
FetchObject represents a single object in a FETCH response stream per §11.4.4.
func (*FetchObject) Append ¶
func (o *FetchObject) Append(w *wire.Writer)
Append serializes a FetchObject to w.
For end-of-range markers (SerializationFlags == 0x8C or 0x10C), the spec requires Group ID and Object ID fields to follow the flags varint. For normal objects, the payload is length-prefixed (varint + bytes).
func (*FetchObject) IsDatagram ¶
func (o *FetchObject) IsDatagram() bool
IsDatagram reports whether the Datagram bit (0x40) is set: the object was published with Forwarding Preference "Datagram" and carries no Subgroup ID.
func (*FetchObject) IsEndOfRangeGroup ¶
func (o *FetchObject) IsEndOfRangeGroup() bool
IsEndOfRangeGroup reports whether this is an end-of-range unknown marker (0x10C).
func (*FetchObject) IsEndOfRangeObject ¶
func (o *FetchObject) IsEndOfRangeObject() bool
IsEndOfRangeObject reports whether this is an end-of-range non-existent marker (0x8C).
func (*FetchObject) Parse ¶
func (o *FetchObject) Parse(r wire.Decoder) error
Parse deserializes a FetchObject from r. r may be a *wire.Reader (in-memory) or a *wire.StreamReader (streaming).
func (*FetchObject) SubgroupMode ¶
func (o *FetchObject) SubgroupMode() FetchSubgroupIDMode
SubgroupMode returns the subgroup ID encoding mode from the two LSBs.
func (*FetchObject) Validate ¶
func (o *FetchObject) Validate() error
Validate checks the fetch object for protocol violations.
type FetchSubgroupIDMode ¶
type FetchSubgroupIDMode uint8
FetchSubgroupIDMode encodes how the Subgroup ID is determined (bits 0–1).
const ( FetchSubgroupIDZero FetchSubgroupIDMode = 0x00 // Subgroup ID is zero FetchSubgroupIDPrior FetchSubgroupIDMode = 0x01 // Subgroup ID = prior object's Subgroup ID FetchSubgroupIDPriorPlusOne FetchSubgroupIDMode = 0x02 // Subgroup ID = prior + 1 FetchSubgroupIDExplicit FetchSubgroupIDMode = 0x03 // Subgroup ID field is present )
type FilterType ¶
type FilterType uint64
FilterType identifies the type of a Location Filter per §5.1.2.
const ( // FilterNextGroupStart (0x1): start at {LargestObject.Group + 1, 0}. // Open-ended (no End Group). If no content delivered yet, start at {0, 0}. FilterNextGroupStart FilterType = 0x1 // FilterLargestObject (0x2): start at {LargestObject.Group, LargestObject.Object + 1}. // Open-ended (no End Group). If no content delivered yet, start at {0, 0}. FilterLargestObject FilterType = 0x2 // FilterAbsoluteStart (0x3): start at an explicitly specified Location. // Open-ended (no End Group). Start = {0, 0} is equivalent to unfiltered. FilterAbsoluteStart FilterType = 0x3 // FilterAbsoluteRange (0x4): start and end are explicitly specified. // End Group = StartLocation.Group + EndGroupDelta. // If EndGroupDelta == 0, the remainder of the start group passes. FilterAbsoluteRange FilterType = 0x4 )
func (FilterType) String ¶
func (f FilterType) String() string
String returns a human-readable name for the filter type.
type GroupOrder ¶
type GroupOrder uint8
GroupOrder is the value of the GROUP_ORDER parameter (§10.2.8). The spec restricts the wire value to Ascending or Descending; anything else is a session-level PROTOCOL_VIOLATION.
const ( GroupOrderAscending GroupOrder = 0x1 GroupOrderDescending GroupOrder = 0x2 )
type JoiningFetch ¶
type JoiningFetch struct {
JoiningRequestID uint64
JoiningStart uint64 // Relative or absolute start
}
JoiningFetch contains fields for a joining FETCH request per §10.12.2.
type Location ¶
Location represents a track location per §10.12.1.
func (Location) Compare ¶
Compare returns -1, 0, or +1 according to whether l sorts before, equal to, or after other in the (Group, Object) lexicographic order. This is the total order MoQT uses for §10.2.16 (LARGEST_OBJECT monotonicity), §11.2 (intra-track Object ordering), and Fetch/Cache range scans (§10.12.1).
The signature matches cmp.Compare so callers can pass Location.Compare directly to slices.SortFunc and slices.BinarySearchFunc.
type LocationFilter ¶
type LocationFilter struct {
Type FilterType
StartLocation Location // used by AbsoluteStart and AbsoluteRange
EndGroupDelta uint64 // used by AbsoluteRange; 0 means rest of start group
}
LocationFilter is the Location Filter structure from §5.1.2.
Wire format:
Location Filter {
Filter Type (vi64),
[Start Location (Location),] -- present for AbsoluteStart, AbsoluteRange
[End Group Delta (vi64),] -- present for AbsoluteRange only
}
For LargestObject and NextGroupStart the Start Location is implicit (derived from the Largest Object at the publisher) and is NOT on the wire.
func LocationFilterFromParam ¶
func LocationFilterFromParam(ps Parameters) (*LocationFilter, error)
LocationFilterFromParam extracts and parses a LOCATION_FILTER parameter from a Parameters list. Returns nil, nil if the parameter is absent (unfiltered subscription). Returns an error if the parameter is present but malformed.
func ParseLocationFilter ¶
func ParseLocationFilter(raw []byte) (*LocationFilter, error)
ParseLocationFilter deserialises a LocationFilter from raw bytes (e.g. the Bytes field of a LOCATION_FILTER parameter).
func (*LocationFilter) Append ¶
func (f *LocationFilter) Append(w *wire.Writer)
Append serialises the LocationFilter to w.
func (*LocationFilter) Bytes ¶
func (f *LocationFilter) Bytes() []byte
Bytes serialises the filter to a fresh byte slice. Useful for building the LOCATION_FILTER parameter value.
func (*LocationFilter) EndGroup ¶
func (f *LocationFilter) EndGroup() uint64
EndGroup returns the last Group ID that passes the filter for AbsoluteRange. For other filter types it returns 0 (not meaningful). Panics if called on an AbsoluteRange filter that would overflow (call Validate first).
func (*LocationFilter) Matches ¶
func (f *LocationFilter) Matches(group, object uint64, largestGroup, largestObject uint64, hasLargest bool) bool
Matches reports whether the object at {group, object} passes this filter, given the current largestGroup and largestObject at the publisher.
For LargestObject and NextGroupStart the effective start is computed from the provided largest values. If no objects have been published yet (both largest values are 0 and hasLargest is false), the effective start is {0,0}.
Per §5.1.2: "Only objects published or received via a subscription having Locations greater than or equal to Start Location and strictly less than or equal to the End Group (when present) pass the filter.".
func (*LocationFilter) Parse ¶
func (f *LocationFilter) Parse(r *wire.Reader) error
Parse deserialises a LocationFilter from r. Returns an error (PROTOCOL_VIOLATION) for unknown filter types.
func (*LocationFilter) Validate ¶
func (f *LocationFilter) Validate() error
Validate checks that the filter is well-formed per §5.1.2. Returns an error that the caller should map to PROTOCOL_VIOLATION when:
- The filter type is unknown.
- AbsoluteRange: StartLocation.Group + EndGroupDelta would overflow uint64 (per §5.1.2: "If the resulting Group ID would be greater than 2^64 - 1, the endpoint MUST close the session with a PROTOCOL_VIOLATION").
type Message ¶
type Message interface {
// Type returns the wire type ID.
Type() Type
// Append serializes the message payload to w.
Append(w *wire.Writer)
// Parse deserializes the message payload from r. r is expected to be
// bounded to the payload length (i.e. the wire-level frame length).
Parse(r *wire.Reader) error
}
Message is the interface implemented by all in-scope MoQT control- and request-stream messages.
type Namespace ¶
type Namespace struct {
TrackNamespaceSuffix wire.TrackNamespace
}
Namespace is the NAMESPACE message (§10.16). It announces a track namespace suffix on a PUBLISH_NAMESPACE or SUBSCRIBE_NAMESPACE request stream.
type NamespaceDone ¶
type NamespaceDone struct {
TrackNamespaceSuffix wire.TrackNamespace
}
NamespaceDone is the NAMESPACE_DONE message (§10.17). It signals that no more tracks will be published within a namespace.
func (*NamespaceDone) Append ¶
func (m *NamespaceDone) Append(w *wire.Writer)
Append serializes the NAMESPACE_DONE message to w.
func (*NamespaceDone) Parse ¶
func (m *NamespaceDone) Parse(r *wire.Reader) error
Parse deserializes the NAMESPACE_DONE message from r.
func (*NamespaceDone) Type ¶
func (m *NamespaceDone) Type() Type
Type returns the wire type ID for NAMESPACE_DONE.
type ObjectDatagram ¶
type ObjectDatagram struct {
Type uint64 // Complex bit field
TrackAlias uint64
GroupID uint64
ObjectID uint64 // Optional based on ZERO_OBJECT_ID bit
PublisherPriority uint8 // Optional based on DEFAULT_PRIORITY bit
Properties []byte // Optional based on PROPERTIES bit
ObjectStatus uint64 // Optional based on STATUS bit
ObjectPayload []byte // Present when STATUS bit is 0
}
ObjectDatagram represents a MoQT object sent via QUIC datagram (§11.3).
func (*ObjectDatagram) Append ¶
func (d *ObjectDatagram) Append(w *wire.Writer)
Append serializes the datagram to a wire.Writer.
func (*ObjectDatagram) HasDefaultPriority ¶
func (d *ObjectDatagram) HasDefaultPriority() bool
HasDefaultPriority returns true if the DEFAULT_PRIORITY bit is set.
func (*ObjectDatagram) HasEndOfGroup ¶
func (d *ObjectDatagram) HasEndOfGroup() bool
HasEndOfGroup returns true if the END_OF_GROUP bit is set.
func (*ObjectDatagram) HasProperties ¶
func (d *ObjectDatagram) HasProperties() bool
HasProperties returns true if the PROPERTIES bit is set.
func (*ObjectDatagram) HasStatus ¶
func (d *ObjectDatagram) HasStatus() bool
HasStatus returns true if the STATUS bit is set.
func (*ObjectDatagram) HasZeroObjectID ¶
func (d *ObjectDatagram) HasZeroObjectID() bool
HasZeroObjectID returns true if the ZERO_OBJECT_ID bit is set.
func (*ObjectDatagram) Parse ¶
func (d *ObjectDatagram) Parse(r *wire.Reader) error
Parse deserializes a datagram from a wire.Reader into d.
func (*ObjectDatagram) Validate ¶
func (d *ObjectDatagram) Validate() error
Validate checks if the datagram is valid according to MoQT spec §11.3.1. Every violation below is a session-level PROTOCOL_VIOLATION at the receiver.
type ParamID ¶
type ParamID uint64
ParamID is a MoQT Message Parameter type ID (§10.2). Distinct from SetupOption because the two code spaces overlap (parameter 0x03 vs option 0x03 are both AUTHORIZATION_TOKEN but in different contexts with different parse rules) and from session/request error codes which overlap numerically.
const ( ParamObjectDeliveryTimeout ParamID = 0x02 ParamAuthorizationToken ParamID = 0x03 ParamRendezvousTimeout ParamID = 0x04 ParamSubgroupDeliveryTimeout ParamID = 0x06 ParamExpires ParamID = 0x08 ParamLargestObject ParamID = 0x09 ParamFillTimeout ParamID = 0x0A ParamForward ParamID = 0x10 ParamSubscriberPriority ParamID = 0x20 ParamLocationFilter ParamID = 0x21 ParamGroupOrder ParamID = 0x22 // Range Filter parameters (§5.1.3, §10.2.10-14). All five carry a // length-prefixed blob (SetID, optional Property Type, delta-encoded // Ranges) — see rangefilter.go. NOTE: 0x26/0x28 are even, so under the // §1.4.3 KV-pair rule they would carry a bare varint with no Length; but // §5.1.3's figure shows a Length on all five, and this codebase encodes // parameters by a per-type Kind (paramKinds), not by §1.4.3 parity — so all // five register as KindBytes (length-prefixed). ParamSubgroupFilter ParamID = 0x25 ParamObjectIDFilter ParamID = 0x26 ParamPriorityFilter ParamID = 0x27 ParamObjectPropertyFilter ParamID = 0x28 ParamTrackPropertyFilter ParamID = 0x29 ParamNewGroupRequest ParamID = 0x32 ParamTrackNamespacePrefix ParamID = 0x34 )
Parameter wire type IDs from §10.2.
type ParamKind ¶
type ParamKind uint8
ParamKind describes a parameter's value encoding (§10.2).
const ( KindVarint ParamKind // single varint KindByte // single byte (uint8) KindBytes // varint-length-prefixed bytes KindLocation // two varints: Group, Object )
type Parameter ¶
type Parameter struct {
Type ParamID
Varint uint64
Byte uint8
Bytes []byte
Group uint64 // KindLocation: Group ID
Object uint64 // KindLocation: Object ID
// contains filtered or unexported fields
}
Parameter is a single MoQT message parameter (§10.2). Exactly one of the value fields holds data, determined by the value kind the Parameter was constructed with (see ParamKind and the constructors below).
func AbsoluteRangeFilter ¶
AbsoluteRangeFilter returns a LOCATION_FILTER parameter (§5.1.2, FilterAbsoluteRange): deliver objects from start through the end of group (start.Group + endGroupDelta). endGroupDelta == 0 passes the remainder of the start group only.
func AbsoluteStartFilter ¶
AbsoluteStartFilter returns a LOCATION_FILTER parameter (§5.1.2, FilterAbsoluteStart): deliver every object at or after start, open-ended. A start of {0, 0} is equivalent to an unfiltered subscription.
func AuthorizationTokenParam ¶
AuthorizationTokenParam builds a typed AUTHORIZATION_TOKEN parameter (§10.2.2) from a Token. The Token is serialised to bytes and stored as a KindBytes parameter.
func BytesParam ¶
func ExpiresParam ¶
ExpiresParam builds EXPIRES (§10.2.15): the time after which the sender will terminate the subscription. Zero means the subscription does not expire (or expires at an unknown time).
func FillTimeoutParam ¶
FillTimeoutParam builds FILL_TIMEOUT (§10.2.5): the maximum total duration a relay should spend waiting for upstream sources to provide objects that are not immediately available. A zero duration means the subscriber only wants objects that are immediately available.
func ForwardParam ¶
ForwardParam builds FORWARD (§10.2.17). The wire value is restricted to 0/1 per the spec, so the helper takes a bool.
func GroupOrderParam ¶
func GroupOrderParam(order GroupOrder) Parameter
GroupOrderParam builds GROUP_ORDER (§10.2.8).
func LargestObjectFilter ¶
func LargestObjectFilter() Parameter
LargestObjectFilter returns a LOCATION_FILTER parameter (§5.1.2, FilterLargestObject): deliver objects strictly after the publisher's current largest object — the live edge. This is the common "subscribe to live" filter; pair it with a Joining FETCH to also backfill the current group.
func LargestObjectParam ¶
LargestObjectParam builds LARGEST_OBJECT (§10.2.16): the largest Location {Group, Object} observed in the track by the sender.
func LocationFilterParam ¶
func LocationFilterParam(f *LocationFilter) Parameter
LocationFilterParam builds LOCATION_FILTER (§10.2.9) from a typed LocationFilter. The filter is serialised to bytes and stored as a length-prefixed KindBytes parameter per §10.2.9.
func LocationParam ¶
func NewGroupRequestParam ¶
NewGroupRequestParam builds NEW_GROUP_REQUEST (§10.2.18): the largest known Group ID plus 1, or 0 if the subscriber has no Group information.
func NextGroupStartFilter ¶
func NextGroupStartFilter() Parameter
NextGroupStartFilter returns a LOCATION_FILTER parameter (§5.1.2, FilterNextGroupStart): deliver from the start of the group after the current largest, skipping the remainder of the in-progress group.
func ObjectDeliveryTimeoutParam ¶
ObjectDeliveryTimeoutParam builds OBJECT_DELIVERY_TIMEOUT (§10.2.4): the maximum duration the publisher holds a single object before declaring failure.
func RangeFilterParam ¶
func RangeFilterParam(f *RangeFilter) Parameter
RangeFilterParam builds the message Parameter (§10.2) carrying f. The value is a length-prefixed blob (KindBytes) for all five filter types — see the paramKinds note in params.go on the §1.4.3-vs-§5.1.3 parity tension.
func RendezvousTimeoutParam ¶
RendezvousTimeoutParam builds RENDEZVOUS_TIMEOUT (§10.2.6): how long the subscriber is willing to wait for a publisher to become available. A zero duration tells the relay to respond immediately with DOES_NOT_EXIST when no publisher exists.
func SubgroupDeliveryTimeoutParam ¶
SubgroupDeliveryTimeoutParam builds SUBGROUP_DELIVERY_TIMEOUT (§10.2.3).
func SubscriberPriorityParam ¶
SubscriberPriorityParam builds SUBSCRIBER_PRIORITY (§10.2.7). Lower numbers get higher priority; the implicit default when omitted is 128.
func TrackNamespacePrefixParam ¶
func TrackNamespacePrefixParam(prefix wire.TrackNamespace) Parameter
TrackNamespacePrefixParam builds TRACK_NAMESPACE_PREFIX (§10.2.19): a namespace prefix used for namespace subscription updates. The value is a TrackNamespace structure serialized per §2.4.1.
func VarintParam ¶
type Parameters ¶
type Parameters []Parameter
Parameters is a list of message parameters.
func (Parameters) Find ¶
func (ps Parameters) Find(t ParamID) (Parameter, bool)
Find returns the first parameter with the given type, plus a bool indicating presence.
func (Parameters) FindAll ¶
func (ps Parameters) FindAll(t ParamID) []Parameter
FindAll returns every parameter with the given type, in list order. Range Filter parameters (§5.1.3) legitimately repeat within one message (multiple SetIDs / Property Types), so callers that handle them must iterate all occurrences rather than rely on Parameters.Find's first-only result.
type PropertyType ¶
type PropertyType = uint64
PropertyType identifies a MoQT property per §12 and the IANA 'MOQ Properties' registry. Types are used as absolute values in the KVPair.Type field; the delta encoding is handled by the wire layer.
const ( // PropertySubgroupDeliveryTimeout (0x06) is a Track or Object Property // (§12.1). Value: varint (milliseconds). Semantics defined in §8. As an // Object Property on the first object in a subgroup it overrides the // Track-level value for that subgroup; it is ignored on any other object. PropertySubgroupDeliveryTimeout PropertyType = 0x06 // PropertyObjectDeliveryTimeout (0x02) is a Track or Object Property // (§12.2). Value: varint (milliseconds). Semantics defined in §8. As an // Object Property on the first object in a subgroup it overrides the // Track-level value for that subgroup; it is ignored on any other object. PropertyObjectDeliveryTimeout PropertyType = 0x02 // PropertyMaxCacheDuration (0x04) is a Track Property (§12.3). // Value: varint (milliseconds). PropertyMaxCacheDuration PropertyType = 0x04 // PropertyDefaultPublisherPriority (0x0E) is a Track Property (§12.4). // Value: varint 0–255. Default: 128. PropertyDefaultPublisherPriority PropertyType = 0x0E // PropertyDefaultPublisherGroupOrder (0x22) is a Track Property (§12.5). // Value: varint; 0x1 = Ascending (default), 0x2 = Descending. PropertyDefaultPublisherGroupOrder PropertyType = 0x22 // PropertyDynamicGroups (0x30) is a Track Property (§12.6). // Value: varint 0 or 1. PropertyDynamicGroups PropertyType = 0x30 // PropertyImmutableProperties (0x0B) is a Track or Object Property (§12.7). // Value: bytes containing a nested sequence of KV pairs. PropertyImmutableProperties PropertyType = 0x0B // PropertyPriorGroupIDGap (0x3C) is an Object Property (§12.8). // Value: varint. PropertyPriorGroupIDGap PropertyType = 0x3C // PropertyPriorObjectIDGap (0x3E) is an Object Property (§12.9). // Value: varint. PropertyPriorObjectIDGap PropertyType = 0x3E )
Property type constants from §12 and the IANA registry (Table 14). All types listed here are from draft-ietf-moq-transport-19.
const ( MandatoryTrackPropertyMin PropertyType = 0x4000 MandatoryTrackPropertyMax PropertyType = 0x7FFF )
MandatoryTrackPropertyMin and MandatoryTrackPropertyMax define the range of Mandatory Track Property types per §2.5.1. Properties in [0x4000, 0x7FFF] MUST have Track scope; receiving one as an Object Property is malformed. An endpoint that does not understand a Mandatory Track Property in PUBLISH, SUBSCRIBE_OK, or FETCH_OK MUST NOT process or forward that track.
func FirstUnknownMandatoryTrackProperty ¶
func FirstUnknownMandatoryTrackProperty( pairs []wire.KVPair, knownTypes map[PropertyType]struct{}, ) (PropertyType, bool)
FirstUnknownMandatoryTrackProperty returns the first Mandatory Track Property (range 0x4000–0x7FFF) in pairs whose type is not in knownTypes, and whether one was found — the offending type is what callers need to build their rejection error. A nil knownTypes treats every mandatory property as unknown.
Per §2.5.1, an endpoint that receives Track Properties containing an unknown Mandatory Track Property MUST NOT process or forward that track.
type Publish ¶
type Publish struct {
RequestID uint64
Namespace wire.TrackNamespace
Name []byte
TrackAlias uint64
Parameters Parameters
TrackProperties []byte
}
Publish is the PUBLISH message (§10.10).
func (*Publish) GetRequestID ¶
func (*Publish) SetRequestID ¶
type PublishDone ¶
type PublishDone struct {
StatusCode moqt.PublishDoneCode
StreamCount uint64
ErrorReason string
}
PublishDone is the PUBLISH_DONE message (§10.11).
func (*PublishDone) Append ¶
func (m *PublishDone) Append(w *wire.Writer)
func (*PublishDone) Type ¶
func (m *PublishDone) Type() Type
type PublishNamespace ¶
type PublishNamespace struct {
RequestID uint64
Namespace wire.TrackNamespace
Parameters Parameters
}
PublishNamespace is the PUBLISH_NAMESPACE message (§10.15). It announces that the publisher will publish tracks within a namespace.
func (*PublishNamespace) Append ¶
func (m *PublishNamespace) Append(w *wire.Writer)
Append serializes the PUBLISH_NAMESPACE message to w.
func (*PublishNamespace) GetRequestID ¶
func (m *PublishNamespace) GetRequestID() uint64
func (*PublishNamespace) Parse ¶
func (m *PublishNamespace) Parse(r *wire.Reader) error
Parse deserializes the PUBLISH_NAMESPACE message from r.
func (*PublishNamespace) SetRequestID ¶
func (m *PublishNamespace) SetRequestID(id uint64)
func (*PublishNamespace) Type ¶
func (m *PublishNamespace) Type() Type
Type returns the wire type ID for PUBLISH_NAMESPACE.
type PublishSkipped ¶
type PublishSkipped struct {
TrackNamespaceSuffix wire.TrackNamespace
TrackName []byte
}
PublishSkipped is the PUBLISH_SKIPPED message (§10.20). It signals that a specific track's Subscription was not created for this SUBSCRIBE_TRACKS.
func (*PublishSkipped) Append ¶
func (m *PublishSkipped) Append(w *wire.Writer)
Append serializes the PUBLISH_SKIPPED message to w.
func (*PublishSkipped) Parse ¶
func (m *PublishSkipped) Parse(r *wire.Reader) error
Parse deserializes the PUBLISH_SKIPPED message from r.
func (*PublishSkipped) Type ¶
func (m *PublishSkipped) Type() Type
Type returns the wire type ID for PUBLISH_SKIPPED.
type Range ¶
Range is one inclusive [Start, End] band of a Range Filter (§5.1.3). Open marks the final, open-ended range — its End is omitted on the wire and it matches any value >= Start. End is ignored when Open is set.
type RangeFilter ¶
type RangeFilter struct {
Type ParamID
SetID uint8
PropertyType PropertyType // only for ParamObjectPropertyFilter / ParamTrackPropertyFilter
Ranges []Range
}
RangeFilter is one Range Filter parameter (§5.1.3): SUBGROUP_FILTER (0x25), OBJECTID_FILTER (0x26), PRIORITY_FILTER (0x27), OBJECT_PROPERTY_FILTER (0x28), or TRACK_PROPERTY_FILTER (0x29). Type is the parameter ID; SetID groups filters for AND/OR combination (§5.1.3); PropertyType is meaningful only for the Object/Track Property filters (0x28/0x29) and is 0 otherwise. Ranges is the ordered, non-overlapping set of value bands the filter selects.
func ParseRangeFilter ¶
func ParseRangeFilter(t ParamID, raw []byte) (*RangeFilter, error)
ParseRangeFilter decodes a Range Filter parameter's value blob (raw) for parameter type t (§5.1.3), resolving the delta-encoded Ranges to absolute [Start, End] bands. The open-ended final range is detected when the blob is exhausted immediately after a Start. Any delta that overflows 2^64-1 is rejected with ErrInvalidFilter. Per-type value checks (PRIORITY bound, odd Property Type) are applied by RangeFilter.Validate, not here.
func (*RangeFilter) Append ¶
func (f *RangeFilter) Append(w *wire.Writer)
Append serialises the filter's value blob to w: SetID, optional Property Type, then the delta-encoded Ranges (§5.1.3 — Start delta from the prior Range's End or 0, End delta from the current Start; the final End is omitted for an Open range). It assumes a validated filter; a mid-list Open range would truncate the blob, so call RangeFilter.Validate first.
func (*RangeFilter) Bytes ¶
func (f *RangeFilter) Bytes() []byte
Bytes serialises the filter to a fresh byte slice — the value of the RangeFilterParam parameter.
func (*RangeFilter) Validate ¶
func (f *RangeFilter) Validate() error
Validate applies the §5.1.3 per-filter value checks that need no session state: the Object/Track Property filters require an even Property Type (§10.2.13/§10.2.14), PRIORITY_FILTER values must fit 8 bits (§10.2.12), and only the final Range may be open-ended (a mid-list Open cannot round-trip). Duplicate-combination and MAX_FILTER_RANGES checks need session state and live in RangeFiltersFromParams / RangeFilterSet.Validate.
type RangeFilterSet ¶
type RangeFilterSet struct {
// contains filtered or unexported fields
}
RangeFilterSet is the collection of Range Filters (§5.1.3) on one request, grouped by SetID. A value passes a group when it satisfies every filter in that group (AND); it passes the set when it passes any group (OR) — §5.1.3's "SetID=0 OR SetID=1 OR ...". A nil or empty set imposes no restriction. Build it with RangeFiltersFromParams.
func RangeFiltersFromParams ¶
func RangeFiltersFromParams(ps Parameters) (*RangeFilterSet, error)
RangeFiltersFromParams extracts every Range Filter parameter (§5.1.3) from ps, validates each, rejects a duplicate (Type, SetID, Property Type) combination (§5.1.3), and groups them by SetID. Returns (nil, nil) when ps carries no range filters — the "no filter" default, matching LocationFilterFromParam. The MAX_FILTER_RANGES limit needs the negotiated cap and is enforced separately by RangeFilterSet.Validate.
func (*RangeFilterSet) MatchesObject ¶
func (s *RangeFilterSet) MatchesObject(subgroupID, objectID uint64, priority uint8, objProps []byte) bool
MatchesObject reports whether an object with the given Subgroup ID, Object ID, Publisher Priority, and Object-Properties blob passes the set's object-scoped filters (§5.1.3): OR over SetID of (AND of the group's SUBGROUP/OBJECTID/ PRIORITY/OBJECT_PROPERTY filters). A nil/empty set matches everything.
This ignores TRACK_PROPERTY filters, so it is exact for SUBSCRIBE/FETCH (which carry no track filters). When a SetID mixes object and track filters (possible in SUBSCRIBE_TRACKS), use RangeFilterSet.MatchesObjectInSets with a RangeFilterSet.TrackPassPerGroup vector instead.
func (*RangeFilterSet) MatchesObjectInSets ¶
func (s *RangeFilterSet) MatchesObjectInSets( subgroupID, objectID uint64, priority uint8, objProps []byte, trackPass []bool, ) bool
MatchesObjectInSets is RangeFilterSet.MatchesObject with per-SetID track gating: group i is eligible only when trackPass[i] is true (nil trackPass = all groups eligible). This implements the exact §5.1.3 semantics OR_i(trackPass[i] AND objectFilters_i) for the mixed object+track-in-one-SetID case, where a naive MatchesTrack() && MatchesObject() would be wrong.
func (*RangeFilterSet) MatchesTrack ¶
func (s *RangeFilterSet) MatchesTrack(trackProps []byte) bool
MatchesTrack reports whether a track with the given Track Properties passes the set's TRACK_PROPERTY filters (§5.1.3 / §10.2.14) — the PUBLISH-forwarding gate for SUBSCRIBE_TRACKS: OR over SetID of (AND of the group's track-property filters). A group with no track filter passes vacuously, so a set with only object filters matches every track; a nil set matches everything.
func (*RangeFilterSet) TrackPassPerGroup ¶
func (s *RangeFilterSet) TrackPassPerGroup(trackProps []byte) []bool
TrackPassPerGroup returns, for each SetID group (in the same order as RangeFilterSet.MatchesObjectInSets evaluates), whether the group's TRACK_PROPERTY filters all pass for a track with the given Track Properties. Computed once per (track, subscription) and reused across that track's objects. Returns nil for a nil set.
func (*RangeFilterSet) Validate ¶
func (s *RangeFilterSet) Validate(maxFilterRanges uint64) error
Validate enforces the MAX_FILTER_RANGES setup option (§10.3.1.6): a limit of 0 prohibits range filters entirely, and the total number of Ranges across all filters must not exceed maxFilterRanges. Returns ErrInvalidFilter on breach. A nil set (no filters) is always valid.
type Redirect ¶
type Redirect struct {
ConnectURI []byte
Namespace wire.TrackNamespace
TrackName []byte
}
Redirect carries the optional redirect payload of REQUEST_ERROR (§10.6.1).
type RequestError ¶
type RequestError struct {
ErrorCode moqt.RequestErrorCode
RetryInterval uint64
ErrorReason string
Redirect *Redirect
}
RequestError is the REQUEST_ERROR message (§10.6.2). Redirect is non-nil when ErrorCode is REDIRECT.
func (*RequestError) Append ¶
func (m *RequestError) Append(w *wire.Writer)
func (*RequestError) Type ¶
func (m *RequestError) Type() Type
func (*RequestError) Validate ¶
func (m *RequestError) Validate() error
Validate enforces the §10.6.2 REQUEST_ERROR invariants. It is invoked automatically by ParsePayload after decode, so a malformed REQUEST_ERROR (REDIRECT code without a Redirect block, or vice versa) is rejected at the parse boundary rather than reaching the session layer.
func (*RequestError) ValidateRedirect ¶
func (m *RequestError) ValidateRedirect() error
ValidateRedirect enforces the §10.6.2 constraints: the Redirect block MUST be present when ErrorCode is REDIRECT, and MUST NOT be present otherwise. It is the implementation behind RequestError.Validate; callers may also invoke it directly.
type RequestOK ¶
type RequestOK struct {
Parameters Parameters
TrackProperties []byte
}
RequestOK is the REQUEST_OK message (§10.5). Track Properties are populated when used as a TRACK_STATUS_OK response and empty otherwise (PUBLISH, REQUEST_UPDATE).
type RequestUpdate ¶
type RequestUpdate struct {
RequestID uint64
Parameters Parameters
}
RequestUpdate is the REQUEST_UPDATE message (§10.9).
func (*RequestUpdate) Append ¶
func (m *RequestUpdate) Append(w *wire.Writer)
func (*RequestUpdate) GetRequestID ¶
func (m *RequestUpdate) GetRequestID() uint64
func (*RequestUpdate) SetRequestID ¶
func (m *RequestUpdate) SetRequestID(id uint64)
func (*RequestUpdate) Type ¶
func (m *RequestUpdate) Type() Type
type ReservedSubgroupIDModeError ¶
type ReservedSubgroupIDModeError struct {
Type uint64
}
ReservedSubgroupIDModeError is returned when the leading Type of an inbound data uni-stream matches the SUBGROUP_HEADER pattern (bit 4 set, bit 7 clear) but carries the reserved SUBGROUP_ID_MODE value 0b11 in bits 1-2. Per §11.4.2, this MUST be treated as a session-level PROTOCOL_VIOLATION — unlike a truly unknown stream type, which may be ignorable (GREASE).
func (*ReservedSubgroupIDModeError) Error ¶
func (e *ReservedSubgroupIDModeError) Error() string
type Setup ¶
Setup carries the SETUP message payload (§10.3). Setup Options span the remainder of the message payload as a delta-encoded sequence of KVPairs.
type SetupOption ¶
type SetupOption uint64
SetupOption is a MoQT SETUP option type ID (§10.3.1). Distinct from ParamID because the two code spaces overlap: option 0x03 is AUTHORIZATION_TOKEN at the session level and parameter 0x03 is AUTHORIZATION_TOKEN at the request level — different message contexts, different parsing rules. The underlying wire field (wire.KVPair.Type) stays uint64 because KVPair is wire-generic.
const ( SetupOptionPath SetupOption = 0x01 SetupOptionAuthorizationToken SetupOption = 0x03 SetupOptionMaxAuthTokenCache SetupOption = 0x04 SetupOptionAuthority SetupOption = 0x05 SetupOptionMaxFilterRanges SetupOption = 0x06 SetupOptionMOQTImplementation SetupOption = 0x07 SetupOptionMaxRequestUpdates SetupOption = 0x08 )
type StandaloneFetch ¶
type StandaloneFetch struct {
Namespace wire.TrackNamespace
Name []byte
StartLocation Location
EndLocation Location
}
StandaloneFetch contains fields for a standalone FETCH request per §10.12.1.
type SubgroupHeader ¶
type SubgroupHeader struct {
// Properties: when true, every Object on this stream carries an
// Object Properties structure (§11.2.1.2). Wire bit 0.
Properties bool
// SubgroupIDMode controls how the Subgroup ID is conveyed (wire
// bits 1-2).
SubgroupIDMode SubgroupIDMode
// EndOfGroup: when true, this subgroup contains the largest Object
// in the Group. Wire bit 3.
EndOfGroup bool
// InlinePriority: when true, the subgroup body begins with a one-byte
// Publisher Priority value that overrides the subscription default.
// When false (zero value, common case), the body starts directly with
// the first Object and the subgroup inherits the Publisher Priority
// from the SUBSCRIBE/PUBLISH control message. Wire bit 5 (the spec's
// DEFAULT_PRIORITY bit) — set on the wire when this field is false.
InlinePriority bool
// ReplayingSubgroup: when true, the first Object on this stream is
// NOT the first object the original publisher pushed for this
// subgroup — i.e. the stream is a partial replay from a relay or
// cache. When false (zero value, common case), the first Object on
// the stream is the first Object of the subgroup. Wire bit 6 (the
// spec's FIRST_OBJECT bit) — set on the wire when this field is
// false.
ReplayingSubgroup bool
// TrackAlias identifies the track this subgroup belongs to within
// the publisher → subscriber direction of the session (§11.1).
TrackAlias uint64
// GroupID is the Group ID of this subgroup (§11.4.2). Always present
// on the wire after TrackAlias.
GroupID uint64
// SubgroupID is the Subgroup ID of this subgroup. Present on the wire
// only when SubgroupIDMode == SubgroupIDExplicit (0b10). When the mode
// is SubgroupIDImplicitZero the receiver treats it as 0; when the mode
// is SubgroupIDImplicitFirstObject the receiver treats it as equal to
// the first Object ID on the stream.
SubgroupID uint64
// PublisherPriority is the per-subgroup publisher priority byte.
// Present on the wire only when InlinePriority == true. When
// InlinePriority is false the subgroup inherits the priority from the
// enclosing SUBSCRIBE/PUBLISH control message.
PublisherPriority uint8
}
SubgroupHeader is the alias-bearing prefix of a SUBGROUP_HEADER stream (§11.4.2). The flag fields correspond directly to the bits of the wire Type byte; Type() encodes them and DecodeSubgroupHeaderType parses them back.
func DecodeSubgroupHeaderType ¶
func DecodeSubgroupHeaderType(t uint64) (SubgroupHeader, error)
DecodeSubgroupHeaderType parses a wire Type byte (§11.4.2) into the flag fields of a SubgroupHeader. TrackAlias is left zero — the header parser reads it from the following varint. Returns an error if t is not a valid SUBGROUP_HEADER Type (i.e. IsSubgroupHeaderType(t) is false).
func ReadSubgroupHeader ¶
func ReadSubgroupHeader(r io.Reader, typ uint64) (SubgroupHeader, error)
ReadSubgroupHeader reads a complete SUBGROUP_HEADER from r (§11.4.2). The caller must have already read the leading Type varint via ReadDataStreamType and verified it with IsSubgroupHeaderType; pass that raw type value as typ. ReadSubgroupHeader decodes the flag fields from typ and then reads Track Alias, Group ID, optional Subgroup ID (when SubgroupIDMode == SubgroupIDExplicit), and optional Publisher Priority (when InlinePriority is set).
func (SubgroupHeader) Type ¶
func (h SubgroupHeader) Type() uint64
Type returns the wire Type byte encoding the flag fields (§11.4.2). The mandatory bit-4 sanity bit is always set. SubgroupIDMode is masked to 2 bits — callers that pass an out-of-range value get the bottom two bits.
Note that InlinePriority and ReplayingSubgroup are inverted relative to the wire bits: a false (zero) field sets the corresponding wire bit. This makes the zero value of SubgroupHeader produce the typical "inherit priority, original publish" Type byte (0x70).
type SubgroupIDMode ¶
type SubgroupIDMode uint8
SubgroupIDMode is the 2-bit SUBGROUP_ID_MODE sub-field of the SUBGROUP_HEADER Type byte (bits 1-2, §11.4.2). It controls whether and how the Subgroup ID is transmitted in the header.
const ( // SubgroupIDImplicitZero: Subgroup ID is omitted; receiver MUST treat // it as 0. SubgroupIDImplicitZero SubgroupIDMode = 0b00 // SubgroupIDImplicitFirstObject: Subgroup ID is omitted; receiver MUST // treat it as equal to the first Object ID transmitted in this // subgroup. SubgroupIDImplicitFirstObject SubgroupIDMode = 0b01 // SubgroupIDExplicit: Subgroup ID is present in the header. SubgroupIDExplicit SubgroupIDMode = 0b10 )
type SubgroupObject ¶
type SubgroupObject struct {
// ObjectIDDelta is always present on the wire. For the first object in
// the stream it is the absolute Object ID; for subsequent objects it is
// (currentID - previousID - 1), so sequential IDs all encode as 0.
ObjectIDDelta uint64
// Properties is present when SubgroupHeader.Properties == true.
// Encoded as a length-prefixed blob (§11.2.1.2).
// Must be non-nil (even if empty) when the header has Properties == true.
Properties []byte
// Payload is the object body. When non-empty, ObjectStatus is ignored.
// Encoded on the wire as: Object Payload Length (vi64) + bytes.
Payload []byte
// ObjectStatus is only written when len(Payload) == 0.
// Values: 0x0 Normal, 0x3 EndOfGroup, 0x4 EndOfTrack (§11.2.1.1).
ObjectStatus uint64
}
SubgroupObject represents a single object serialized on a SUBGROUP_HEADER stream after the SubgroupHeader (§11.4.2, Figure 25).
func (*SubgroupObject) Append ¶
func (o *SubgroupObject) Append(w *wire.Writer, hasProperties bool)
Append serializes the SubgroupObject to the wire writer. The hasProperties parameter indicates whether the parent SubgroupHeader had the Properties bit set, which determines if Properties are included.
func (*SubgroupObject) IsEndOfGroup ¶
func (o *SubgroupObject) IsEndOfGroup() bool
IsEndOfGroup reports whether this object signals End of Group (status 0x3).
func (*SubgroupObject) IsEndOfTrack ¶
func (o *SubgroupObject) IsEndOfTrack() bool
IsEndOfTrack reports whether this object signals End of Track (status 0x4).
func (*SubgroupObject) IsTerminal ¶
func (o *SubgroupObject) IsTerminal() bool
IsTerminal reports whether this object is a terminal status object (EndOfGroup or EndOfTrack) after which no further objects may appear on the same Subgroup stream (§11.4.3); a later object is a malformed track (§2.4.2).
func (*SubgroupObject) Parse ¶
func (o *SubgroupObject) Parse(r wire.Decoder, hasProperties bool) error
Parse deserializes a SubgroupObject from r. r may be a *wire.Reader (in-memory) or a *wire.StreamReader (streaming). The hasProperties parameter indicates whether the parent SubgroupHeader had the Properties bit set, which determines if Properties are included.
func (*SubgroupObject) Validate ¶
func (o *SubgroupObject) Validate() error
Validate checks the SubgroupObject for protocol violations.
type Subscribe ¶
type Subscribe struct {
RequestID uint64
Namespace wire.TrackNamespace
Name []byte
Parameters Parameters
}
Subscribe is the SUBSCRIBE message (§10.7).
func (*Subscribe) GetRequestID ¶
func (*Subscribe) SetRequestID ¶
type SubscribeNamespace ¶
type SubscribeNamespace struct {
RequestID uint64
TrackNamespacePrefix wire.TrackNamespace
Parameters Parameters
}
SubscribeNamespace is the SUBSCRIBE_NAMESPACE message (§10.18). It subscribes to all tracks within a namespace prefix.
func (*SubscribeNamespace) Append ¶
func (m *SubscribeNamespace) Append(w *wire.Writer)
Append serializes the SUBSCRIBE_NAMESPACE message to w.
func (*SubscribeNamespace) GetRequestID ¶
func (m *SubscribeNamespace) GetRequestID() uint64
func (*SubscribeNamespace) Parse ¶
func (m *SubscribeNamespace) Parse(r *wire.Reader) error
Parse deserializes the SUBSCRIBE_NAMESPACE message from r.
func (*SubscribeNamespace) SetRequestID ¶
func (m *SubscribeNamespace) SetRequestID(id uint64)
func (*SubscribeNamespace) Type ¶
func (m *SubscribeNamespace) Type() Type
Type returns the wire type ID for SUBSCRIBE_NAMESPACE.
type SubscribeOK ¶
type SubscribeOK struct {
TrackAlias uint64
Parameters Parameters
TrackProperties []byte
}
SubscribeOK is the SUBSCRIBE_OK message (§10.8). Track Properties span the remaining bytes; we currently treat them as opaque.
func (*SubscribeOK) Append ¶
func (m *SubscribeOK) Append(w *wire.Writer)
func (*SubscribeOK) Type ¶
func (m *SubscribeOK) Type() Type
type SubscribeTracks ¶
type SubscribeTracks struct {
RequestID uint64
TrackNamespacePrefix wire.TrackNamespace
Parameters Parameters
}
SubscribeTracks is the SUBSCRIBE_TRACKS message (§10.19). It subscribes to all tracks within a namespace prefix.
func (*SubscribeTracks) Append ¶
func (m *SubscribeTracks) Append(w *wire.Writer)
Append serializes the SUBSCRIBE_TRACKS message to w.
func (*SubscribeTracks) GetRequestID ¶
func (m *SubscribeTracks) GetRequestID() uint64
func (*SubscribeTracks) Parse ¶
func (m *SubscribeTracks) Parse(r *wire.Reader) error
Parse deserializes the SUBSCRIBE_TRACKS message from r.
func (*SubscribeTracks) SetRequestID ¶
func (m *SubscribeTracks) SetRequestID(id uint64)
func (*SubscribeTracks) Type ¶
func (m *SubscribeTracks) Type() Type
Type returns the wire type ID for SUBSCRIBE_TRACKS.
type Token ¶
type Token struct {
AliasType AliasType
TokenAlias uint64 // present for DELETE, REGISTER, USE_ALIAS
TokenType uint64 // present for REGISTER, USE_VALUE
TokenValue []byte // present for REGISTER, USE_VALUE
}
Token is the Token structure from §10.2.2.
Wire format (within the outer KindBytes length-prefixed parameter value):
Token {
Alias Type (vi64),
[Token Alias (vi64),] -- DELETE, REGISTER, USE_ALIAS
[Token Type (vi64),] -- REGISTER, USE_VALUE
[Token Value (..)] -- REGISTER, USE_VALUE; raw bytes to end of value
}
TokenValue has no inner length prefix; it occupies the remainder of the outer KindBytes parameter value.
func TokensFromParam ¶
func TokensFromParam(ps Parameters) ([]Token, error)
TokensFromParam extracts and parses all AUTHORIZATION_TOKEN parameters from ps. The spec allows the parameter to be repeated within a message (§10.2.2: "The AUTHORIZATION TOKEN parameter MAY be repeated within a message as long as the combination of Token Type and Token Value are unique after resolving any aliases"). Returns an error if any Token is malformed.
func (*Token) Append ¶
Append serialises t into w. The caller is responsible for the outer KindBytes length prefix (handled by params.go via VarintBytes).
type TrackStatus ¶
type TrackStatus struct {
RequestID uint64
Namespace wire.TrackNamespace
Name []byte
Parameters Parameters
}
TrackStatus is the TRACK_STATUS message (§10.14). It queries the status of a track without creating a subscription. The message format is identical to SUBSCRIBE, but subscriber-specific parameters (like SUBSCRIBER_PRIORITY) must not be included.
func (*TrackStatus) Append ¶
func (m *TrackStatus) Append(w *wire.Writer)
Append serializes the TRACK_STATUS message to w.
func (*TrackStatus) GetRequestID ¶
func (m *TrackStatus) GetRequestID() uint64
func (*TrackStatus) Parse ¶
func (m *TrackStatus) Parse(r *wire.Reader) error
Parse deserializes the TRACK_STATUS message from r.
func (*TrackStatus) SetRequestID ¶
func (m *TrackStatus) SetRequestID(id uint64)
func (*TrackStatus) Type ¶
func (m *TrackStatus) Type() Type
Type returns the wire type ID for TRACK_STATUS.
func (*TrackStatus) Validate ¶
func (m *TrackStatus) Validate() error
Validate enforces the §2.4.1 Full Track Name size limit; ParsePayload invokes it automatically after decoding a TRACK_STATUS frame.
type TrackStatusOK ¶
type TrackStatusOK = RequestOK
TrackStatusOK is the TRACK_STATUS_OK response (§10.14). Per the spec, TRACK_STATUS_OK is a REQUEST_OK (type 0x07) sent in response to TRACK_STATUS. It carries the same parameters and Track Properties as SUBSCRIBE_OK, but without a Track Alias since no subscription is created.
Use RequestOK directly when sending; TrackStatusOK is a convenience alias that wraps RequestOK for clarity at call sites.
type Type ¶
type Type uint64
Type is the wire type ID for a MoQT message (§10, table 5).
const ( TypeSetup Type = 0x2F00 TypeGoaway Type = 0x10 TypeSubscribe Type = 0x03 TypeSubscribeOK Type = 0x04 TypePublish Type = 0x1D TypePublishDone Type = 0x0B TypeRequestUpdate Type = 0x02 TypeRequestOK Type = 0x07 TypeRequestError Type = 0x05 TypeFetch Type = 0x16 TypeFetchOK Type = 0x18 TypeTrackStatus Type = 0x0D TypePublishNamespace Type = 0x06 TypeNamespace Type = 0x08 TypeNamespaceDone Type = 0x0E TypeSubscribeNamespace Type = 0x50 TypeSubscribeTracks Type = 0x51 TypePublishSkipped Type = 0x0F )
type UnknownDataStreamTypeError ¶
type UnknownDataStreamTypeError struct {
Type uint64
}
UnknownDataStreamTypeError is returned when the leading Type of an inbound data uni-stream is not one of the recognized data-stream types. The caller (typically session.AcceptDataStream) resets the underlying stream before surfacing this error so the accept loop can continue.
func (*UnknownDataStreamTypeError) Error ¶
func (e *UnknownDataStreamTypeError) Error() string
type WithRequestID ¶
type WithRequestID interface {
Message
// GetRequestID returns the Request ID carried by this message.
GetRequestID() uint64
// SetRequestID overwrites the Request ID carried by this message. The
// session uses it to assign a freshly allocated ID (§10.1) after a
// request stream is opened, so a failed open consumes no ID.
SetRequestID(uint64)
}
WithRequestID is implemented by messages that carry a Request ID as their first field (§10.1). These are the messages that can appear as the first message on a request stream: SUBSCRIBE, PUBLISH, FETCH, TRACK_STATUS, PUBLISH_NAMESPACE, SUBSCRIBE_NAMESPACE, SUBSCRIBE_TRACKS, and REQUEST_UPDATE.