message

package
v0.0.0-...-e37c033 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 21, 2026 License: Apache-2.0, MIT Imports: 10 Imported by: 0

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

View Source
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).

View Source
const (
	DatagramTypeMin       = 0x00
	DatagramTypeMax       = 0x0F
	DatagramTypeStatusMin = 0x20
	DatagramTypeStatusMax = 0x2F
)

Valid datagram type ranges.

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

View Source
const (
	FetchEndOfRangeObject = 0x8C  // End of Non-Existent Range
	FetchEndOfRangeGroup  = 0x10C // End of Unknown Range
)

End of range markers per §11.4.4.2.

View Source
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).

View Source
const MaxGoawayURIBytes = 8192

MaxGoawayURIBytes is the maximum New Session URI length per §10.4.

View Source
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

View Source
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).

View Source
var ErrUnknownFetchType = errors.New("moqt/message: unknown FETCH type")

ErrUnknownFetchType is returned for an unknown FETCH type.

Functions

func AppendTrackProperties

func AppendTrackProperties(pairs []wire.KVPair) []byte

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

func AuthorityOption(authority string) wire.KVPair

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

func FetchEndBeforeStart(start, end Location) bool

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

func GreaseSetupOption() wire.KVPair

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

func IsFetchHeaderType(typ uint64) bool

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

func IsRangeFilterParam(t ParamID) bool

IsRangeFilterParam reports whether t is one of the five Range Filter parameter types (§5.1.3, 0x25-0x29).

func IsReservedSubgroupHeaderType

func IsReservedSubgroupHeaderType(t uint64) bool

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

func IsSubgroupHeaderType(t uint64) bool

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

func IsValidDatagramType(typ uint64) bool

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

func MOQTImplementationOption(nameAndVersion string) wire.KVPair

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 Marshal

func Marshal(dst io.Writer, m Message) error

Marshal writes m as a complete control-message frame to dst.

func MaxAuthTokenCacheSizeOption

func MaxAuthTokenCacheSizeOption(maxBytes uint64) wire.KVPair

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

func MaxFilterRangesOption(maxRanges uint64) wire.KVPair

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

func MaxRequestUpdatesOption(maxUpdates uint64) wire.KVPair

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

func MillisecondTimeout(ms uint64) time.Duration

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

func ParseTrackProperties(raw []byte) ([]wire.KVPair, error)

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

func PathOption(pathAndQuery string) wire.KVPair

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

func ReadDataStreamType(r io.Reader) (uint64, error)

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
)

func (AliasType) String

func (a AliasType) String() string

String returns a human-readable name for the alias type.

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

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) Append

func (m *Fetch) Append(w *wire.Writer)

Append serializes the FETCH message to w.

func (*Fetch) GetRequestID

func (m *Fetch) GetRequestID() uint64

func (*Fetch) Parse

func (m *Fetch) Parse(r *wire.Reader) error

Parse deserializes the FETCH message from r.

func (*Fetch) SetRequestID

func (m *Fetch) SetRequestID(id uint64)

func (*Fetch) Type

func (m *Fetch) Type() Type

Type returns the wire type ID for FETCH.

func (*Fetch) Validate

func (m *Fetch) Validate() error

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.

func (*FetchOK) Append

func (m *FetchOK) Append(w *wire.Writer)

Append serializes the FETCH_OK message to w.

func (*FetchOK) Parse

func (m *FetchOK) Parse(r *wire.Reader) error

Parse deserializes the FETCH_OK message from r.

func (*FetchOK) Type

func (m *FetchOK) Type() Type

Type returns the wire type ID for FETCH_OK.

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 FetchType

type FetchType uint64

FetchType identifies the type of FETCH request per §10.12.

const (
	FetchTypeStandalone      FetchType = 0x1
	FetchTypeRelativeJoining FetchType = 0x2
	FetchTypeAbsoluteJoining FetchType = 0x3
)

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 Goaway

type Goaway struct {
	NewSessionURI []byte
	Timeout       uint64
}

Goaway is the GOAWAY message (§10.4).

func (*Goaway) Append

func (m *Goaway) Append(w *wire.Writer)

func (*Goaway) Parse

func (m *Goaway) Parse(r *wire.Reader) error

func (*Goaway) Type

func (m *Goaway) Type() 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

type Location struct {
	Group  uint64
	Object uint64
}

Location represents a track location per §10.12.1.

func (Location) Compare

func (l Location) Compare(other Location) int

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.

func (Location) Less

func (l Location) Less(other Location) bool

Less reports whether l comes strictly before other in the (Group, Object) order described on Location.Compare.

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.

func Parse

func Parse(src io.Reader) (Message, error)

Parse reads a single control-message frame from src and returns a typed Message. Unknown message types are returned as ErrUnknownType.

func ParsePayload

func ParsePayload(t Type, payload []byte) (Message, error)

ParsePayload constructs a Message of the given Type and parses payload into it. Use when the caller has already read the frame header.

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.

func (*Namespace) Append

func (m *Namespace) Append(w *wire.Writer)

Append serializes the NAMESPACE message to w.

func (*Namespace) Parse

func (m *Namespace) Parse(r *wire.Reader) error

Parse deserializes the NAMESPACE message from r.

func (*Namespace) Type

func (m *Namespace) Type() Type

Type returns the wire type ID for NAMESPACE.

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.

func (ParamID) String

func (p ParamID) String() string

String returns a short name for known parameter types; unknown values render as hex.

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

func AbsoluteRangeFilter(start Location, endGroupDelta uint64) Parameter

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

func AbsoluteStartFilter(start Location) Parameter

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

func AuthorizationTokenParam(t Token) Parameter

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 ByteParam

func ByteParam(t ParamID, v uint8) Parameter

func BytesParam

func BytesParam(t ParamID, v []byte) Parameter

func ExpiresParam

func ExpiresParam(d time.Duration) Parameter

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

func FillTimeoutParam(d time.Duration) Parameter

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

func ForwardParam(forward bool) Parameter

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

func LargestObjectParam(group, object uint64) Parameter

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 LocationParam(t ParamID, g, o uint64) Parameter

func NewGroupRequestParam

func NewGroupRequestParam(largestGroupPlusOne uint64) Parameter

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

func ObjectDeliveryTimeoutParam(d time.Duration) Parameter

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

func RendezvousTimeoutParam(d time.Duration) Parameter

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

func SubgroupDeliveryTimeoutParam(d time.Duration) Parameter

SubgroupDeliveryTimeoutParam builds SUBGROUP_DELIVERY_TIMEOUT (§10.2.3).

func SubscriberPriorityParam

func SubscriberPriorityParam(priority uint8) Parameter

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

func VarintParam(t ParamID, v uint64) Parameter

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) Append

func (m *Publish) Append(w *wire.Writer)

func (*Publish) GetRequestID

func (m *Publish) GetRequestID() uint64

func (*Publish) Parse

func (m *Publish) Parse(r *wire.Reader) error

func (*Publish) SetRequestID

func (m *Publish) SetRequestID(id uint64)

func (*Publish) Type

func (m *Publish) Type() Type

func (*Publish) Validate

func (m *Publish) Validate() error

Validate enforces the §2.4.1 Full Track Name size limit; ParsePayload invokes it automatically after decoding a PUBLISH frame.

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) Parse

func (m *PublishDone) Parse(r *wire.Reader) error

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

type Range struct {
	Start uint64
	End   uint64
	Open  bool
}

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) Parse

func (m *RequestError) Parse(r *wire.Reader) error

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

func (*RequestOK) Append

func (m *RequestOK) Append(w *wire.Writer)

func (*RequestOK) Parse

func (m *RequestOK) Parse(r *wire.Reader) error

func (*RequestOK) Type

func (m *RequestOK) Type() Type

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) Parse

func (m *RequestUpdate) Parse(r *wire.Reader) error

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

type Setup

type Setup struct {
	Options []wire.KVPair
}

Setup carries the SETUP message payload (§10.3). Setup Options span the remainder of the message payload as a delta-encoded sequence of KVPairs.

func (*Setup) Append

func (m *Setup) Append(w *wire.Writer)

func (*Setup) Parse

func (m *Setup) Parse(r *wire.Reader) error

func (*Setup) Type

func (m *Setup) Type() Type

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) Append

func (m *Subscribe) Append(w *wire.Writer)

func (*Subscribe) GetRequestID

func (m *Subscribe) GetRequestID() uint64

func (*Subscribe) Parse

func (m *Subscribe) Parse(r *wire.Reader) error

func (*Subscribe) SetRequestID

func (m *Subscribe) SetRequestID(id uint64)

func (*Subscribe) Type

func (m *Subscribe) Type() Type

func (*Subscribe) Validate

func (m *Subscribe) Validate() error

Validate enforces the §2.4.1 Full Track Name size limit; ParsePayload invokes it automatically after decoding a SUBSCRIBE frame.

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) Parse

func (m *SubscribeOK) Parse(r *wire.Reader) error

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

func (t *Token) Append(w *wire.Writer)

Append serialises t into w. The caller is responsible for the outer KindBytes length prefix (handled by params.go via VarintBytes).

func (*Token) Bytes

func (t *Token) Bytes() []byte

Bytes returns the serialised Token as a byte slice, suitable for use as the value of a KindBytes AUTHORIZATION_TOKEN parameter.

func (*Token) Parse

func (t *Token) Parse(raw []byte) error

Parse deserialises a Token from raw — the raw bytes of a KindBytes parameter value. Returns an error (caller should map to KEY_VALUE_FORMATTING_ERROR) if the bytes are malformed.

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
)

func (Type) String

func (t Type) String() string

String returns a short identifier for the message type.

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

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL