QuicR - Media Delivery Protocol over QUIC
Internet-Draft draft-jennings-moq-quicr-proto-01
Cullen Jennings
cisco
Canada
fluffy@iii.ca
Suhas Nandakumar
Cisco
snandaku@cisco.com
Christian Huitema
Private Octopus Inc.
huitema@huitema.net
transport
realtime
quicr
Recently new use cases have emerged requiring higher scalability of media delivery for interactive realtime applications and much lower latency for streaming applications and a combination thereof.
draft-jennings-moq-arch specifies architectural aspects of QuicR, a media delivery protocol based on publish/subscribe metaphor and Relay based delivery tree, that enables a wide range of realtime applications with different resiliency and latency needs.
This specification defines the protocol aspects of the QuicR media delivery architecture.
Introduction
This specification defines QuicR, a publish and subscribe based media delivery protocol over QUIC.
Recently new use cases have emerged requiring higher scalability of media delivery for interactive realtime applications and much lower latency for streaming applications and a combination thereof.
On one side are use cases such as normal web conferences wanting to distribute out to millions of viewers and allow viewers to instantly move to being a presenter (a.k.a active participant). On the other side are use cases such as streaming a soccer game to millions of people including people in the stadium watching the game live. Viewers watching an e-sports event want to be able to comment with low latency to ensure the interactivity aspects between what different viewers are preserved. All of these use cases push towards latencies that are in the order of 100ms over the natural latency the network causes.
The architecture for this specification is outlined in draft-jennings-moq-arch, where the principal idea is client endpoints publish and subscribe to named objects that is sent to, and received from relays, that forms an overlay delivery network similar to what CDN provides today.
The architecture specification, draft-jennings-moq-arch, is a perquisite to read this specification.
This specification defines the protocol specifics of the QuicR Media Delivery Architecture.
Contributing
All significant discussion of development of this protocol is in the GitHub issue tracker at: https://github.com/Quicr/quicr-protocol-spec
Terminology
- Relay Function: Functionality of the QuicR architecture, that implements store and forward behavior at the minimum. Such a function typically receives subscriptions and publishes data to the other endpoints that have subscribed to the named data. Such functions may cache the data as well for optimizing the delivery experience.
- Relay: Server component (physical/logical) in the cloud that implements the Relay Function.
- Publisher: An endpoint that sends named objects to a Relay. [ also referred to as producer of the named object]
- Subscriber: An endpoint that subscribes and receives the named objects. Relays can act as subscribers to other relays. Subscribers can also be referred to as consumers.
- Client/QuicR Client: An endpoint that acts as a Publisher, Subscriber, or both. May also implement a Relay Function in certain contexts.
- Named Object: Application level chunk of Data that has a unique Name, a limited lifetime, priority and is transported via the protocol defined in this specification.
- Origin server: Component managing/authoring the names scoped under a domain for a specific application and is responsible for establishing trust between clients and relays for delivering media. Origin servers MAY implement other QuicR functions, such as Relay function, as necessary.
Overview
At a high level, entities within QuicR architecture publish named media objects that are end-to-end encrypted and consume media by subscribing to the named objects. The published data carry metadata identifying relative priority, time-to-live and other useful metadata that's authenticated for components implementing Relay functions to make drop/forwarding decisions. Entities that perform "Relay" function provide the store and forward behavior to serve the subscription requests, they optimize media delivery latencies through local delivery and improved media quality via local repairs, wherever applicable. The names (Section 5) used in the QuicR protocol are scoped and authorized to a domain by the Origin serving that domain.
Typical Publish/Subscribe Message Exchange
A QuicR "Control Channel", based on QUIC streams, is used to setup properties for media delivery over a "Media Channel" which in turn can be over QUIC streams or QUIC datagrams. The Control channel is typically used to setup QuicR names to be used, control media properties during setup and mid-session, start/stop media delivery and so on. The media data itself is sent over the "Media Channel" and carry enough metadata to enable Relays and end-points to make a forward/drop decisions under congestion, for example. Further details on the messages can be found in Section 7.
Below is an high-level exchange capturing publish/subscribe flow between Alice, the publisher and Bob, Carl, the subscribers and the interactions that occur between Relays on-path and the origin server. The details on how the trust setup happens between these entities are skipped, however.
In the exchange depicted following sequence happen
- Alice sets up a control channel (QUIC Stream) to the relay indicating its intent to publish media with name (video1/1) as the representation id. It does so by sending publish_intent. video1/1 might represent video stream camera-1, quality-id 1 (HD), for example. QuicR manifests (Section 6) are used to setup and consume the names being published.
- On receiving the publish_intent from Alice, the Relay sets up another control channel to the authorized Origin server and forwards Alice's publish_intent message.
- Once publish_intent_ok is received from the Origin, Relay forwards the same to Alice to enable publishing the media over the media channel [QUIC Stream or QUIC Datagram]
- In the meanwhile, Bob and Carl subscribe to receiving media corresponding to the wildcard'ed name (video1/*). They each send subscribe messages to the Relay on the control channel and the same is forwarded by the Relay to the Origin. Successful subscribe responses are sent back to Bob and via the relay. Relay makes note of Bob and Carl's interest in the name (video1/*). The details of knowing the name via manifest is skipped in the callflow.
- Eventually, Alice publishes media on the name (video1/1) towards the relay on the media channel, which could be over QUIC Streams or QUIC Datagram as chosen by Alice.
- Media from Alice gets cached at the relay and is forwarded to the Origin server (optionally). On noting about interested subscribers, the media received from Alice is forwarded to both Bob and Carl from the local cache by the Relay.
┌───────┐     ┌───────┐    ┌───────┐        ┌───────┐         ┌───────┐
│ Alice │     │  Bob  │    │ Carl  │        │ Relay │         │Origin │
└───┬───┘     └───┬───┘    └───┬───┘        └───┬───┘         └───┬───┘
    │                          │                │                 │
    │          ctrl: pub_intent│                │                 │
    │             (video1/1)   │                │ ctrl:pub_intent │
    │                          │                │   (video1/1)    │
    ├─────────────┼────────────┼───────────────▶│                 │
    │             │            │                ├─────────────────▶
    │             │            │                │
    │                          │                │ ctrl:pub_intent_ok
    │           ctrl: pub_inten│_ok             │
    │                          │                │◀────────────────┤
    ◀─────────────┼────────────┼────────────────┤                 │
    │             │                             │                 │
    │             │  ctrl: subscribe (video1/*) │                 │
    │             │                             │                 │
    │             ├────────────┼────────────────▶ ctrl: subscribe │
    │             │            │                │   (video1/*)    │
    │             │            │                │─────────────────▶
    │             │            │                │                 │
    │             │            │                │     ctrl:       │
    │             │            │                │  subscribe_ok   │
    │             │            │                │   (video1/*)    │
    │             │            │                │                 │
    │             │            │                ◀─────────────────┤
    │             │            │                │                 │
    │             │                             │─────┐  add bob: │
    │             │ ctrl: subscribe_ok          │ ◀───┘  video1/* │
    │             │                             │                 │
    │             │◀───────────┼────────────────┤                 │
    │             │            │                │                 │
    │             │            │  ctrl:sub:     │                 │
    │             │            │  (video1/*)    │                 │
    │             │            │                │                 │
    │             │            ├────────────────▶ ctrl: subscribe │
    │             │            │                │   (video1/*)    │
    │             │            │                │─────────────────▶
    │             │            │                │     ctrl:       │
    │             │            │                │  subscribe_ok   │
    │             │            │                │   (video1/*)    │
    │             │            │                │                 │
    │             │            │                ◀─────────────────┤
    │             │            │                │                 │
    │             │                             ├────┐  add carl: │
    │             │   ctrl: subscribe_ok        │◀───┘  video1/*  │
    │             │                             │                 │
    │             │◀───────────┼────────────────┤                 │
    │                          │                │                 │
    │    media:pub:video1/1    │                │                 │
    │                          │                │     cache       │
    ├─────────────┼────────────┼───────────────▶│                 │
    │             │            │                │─────┐           │
    │             │            │                │ ◀───┘    [pub]  │
    │             │            │                │                 │
    │                          │  media:pub:    ├─────────────────▶
    │  media:pub:              │  (video1/1)    │                 │
    │  (video1/1)              │                │                 │
    │                          │◀───────────────┤                 │
    │◀────────────┼────────────┼────────────────┤                 │
    │             │            │                │                 │
    │             │            │                                  │

{: title="Pub/Sub flow between Alice(publisher), Bob, Carl (subscribers), Relay and Origin"}
Origin Server
The Origin serves as the authorization authority for the named resources, in the manner similar to an HTTP origin. QuicR names to be used under a given domain and the application are authorized by the Origin server. It is also responsible for establishing necessary trust relationship between the clients, the relay and itself.
Relays
The Relays play an important role within the QuicR architecture. They receive subscriptions and intent to publish and forwards them towards the origin. This may involve sending messages directly to the Origin Relay or possibly traverse another Relay on the path. Replies to theses message follow the reverse direction of the request and when the Origin gives the OK to a subscription or intent to publish, the Relay allows the subscription or future publishes to the Names in the request. In this role, the Relays perform the role of subscribers (consumers) as well as publishers (producers).
Subscriptions received are aggregated. When a relay receives a publish request with data, it will forward it both towards the Origin and to any clients or relays that have a matching subscriptions. This "short circuit" of distribution by a relay before the data has even reached the Origin servers provides significant latency reduction for clients closer to the relay.
The Relay keeps an outgoing queue of objects to be sent to the each subscriber and objects are sent in strict priority order. Relays MAY cache some of the information for short period of time and the time cached may depend on the origin and local cache policies.
Section 8 covers further details on the Relay functionality.
Names and Named Objects
Names are basic elements with in the QuicR architecture and they uniquely identify objects. For publishers of the media, the names identify application defined data objects being contributed and for the subscribers/receivers, the names correspond to application data objects to be consumed.
The scope and granularity of the names and the data objects they represent are application defined and controlled.
However, a given QuicR name must maintain certain properties as given below
- Each published name must be unique and is scoped to a given domain and an application under that domain.
- Names should support a way for the subscribers to request for the associated data either by specifying the full or partial names. The latter is supported via wildcarding.
- Named objects should enable caching in relays in a way CDNs cache resources and thus can obtain similar benefits such caching mechanisms would offer.
Named Objects
The names of each object in QuicR is composed of the following components:
1. Domain Identifier
2. Application Identifier
3. Data Identifier
Domain component uniquely identifies a given application domain. This is like a HTTP Origin or an standardized identifier that uniquely identifies the application and a root relay function.
Application component is scoped under a given Domain. This component identifies aspects specific to a given application instance hosted under a given domain (e.g. which movie or meeting identifier).
Data identifier identifies aspects of application, for example representation_id in a CMAF segment or video stream from a conference user. In cases where media being delivered is naturally grouped into independently consumable groups (video group of picture or audio synchronization points for example), this component is futher composed into set of such groups, which are in turn made up of set of objects (video frames idr, p-frame within a given gop). Each such group is identified by a monotonically increasing integer and objects within the group are also identified by another set of monotonically increasing integers. The groupID and objectID start at 0.
Example: In the example below the domain component identifies acme.meeting.com domain, the application component identifies an instance of a meeting under this domain, say "meeting123", and the data component captures high resolution camera stream from the user "alice" being published as object 17 under group 15.
Example 1
quicr://acme.meeting.com/meeting123/alice/cam5/HiRes/15/17

Example 2
quicr://twitch.com/channel-fluffy/video-quality-id/group12/object0

Once a named object is created, the content inside the named object can never be changed. Objects have an expiry time after which they should be discarded by caches. Objects have an priority that the relays and clients can use to make drop decisions or sequencing the sending order. The data inside an object is end-to-end encrypted whose keys are not available to Relay(s).
Wildcarding with Names
QuicR allows subscribers to request for media based on wildcard'ed names. Wildcarding enables subscribes/requests for media to be made as aggregates instead of at the object level granularity. Wildcard names are formed by skipping the right most segments of the "Data Identifier" component of the names.
For example, in an web conferencing use case, the client may subscribe to just the origin, meeting_id and one of the publishers so as to get all the media from that user in a particular. The example matches all the named objects published by the user alice in the meeting123.
quicr://acme.meeting.com/meeting123/alice/*
When subscribing, there is an option to tell the relay to one of:
A. Deliver any new objects it receives that match the name
B. Deliver any new objects it receives and in addition send any previous objects it has received that are in the same group that matches the name.
C. Wait until an object that has a objectId that matches the name is received then start sending any objects that match the name.
QuicR Manifest
QuicR Manifests provides a light-weight declarative way for the publishers to advertise their capabilities for publishing media. Publisher manifest advertisement captures supported codecs, encoding rates and also use case specific media properties such as languages supported. Publisher advertisements are intend to declare publisher's capabilities and a publisher is free to choose a subset of those advertised in the manifest as part of the session and thus does not require a manifest update. This could be, for example - to change encoding bitrate or the codec used. However, in the case where a new capability needs to be advertised, a manifest update MAY be necessary.
Publishers advertise their capabilities via QuicR Control channel, as and when its deemed necessary, under a well-known name. Manifest objects are also scoped to a domain and the application under a given Origin server.
Subscribers can retrieve the manifest for a given session by subscribing to the well-known manifest QuicR name. On retrieving the manifest, Subscribers/Receivers of the media can discover names being published and proceed to request media for the corresponding names by sending appropriate subscriptions (with wildcarding as necessary).
A representative well-known name for subscribing to manifest updates for channel-2, twitch live session jon.doe.music.live.tv, can be represented as
quicr://jon.doe.music.live.tv/channel-2/manifest/*

At any point in the session, updated manifest is pushed to the subscribers like any media objects are delivered to the subscribers of the manifest QuicR name.
Scope of the manifest
The role of the manifest is to identify the names as well as aspects pertaining to the associated data in a given usage context of the application.
- Typically a manifest identifies the domain and application aspects for the set of names that can be published.
- The content of Manifest is application defined and end-to-end encrypted.
- The manifest is owned by the application's origin server and are accessed as a protected resources by the authorized QuicR clients.
- The QuicR protocol treats Manifests as a named object, thus allowing for clients to subscribe for the purposes of bootstrapping into the session as well as to follow manifest changes during a session [ new members joining a conference for example].
- The manifest has well known name on the Origin server.
Also to note, a given application might provide non QuicR mechanisms to retrieve the manifest.
Below is a sample manifest for streaming application where a media presentation server describes media streams available for distribution. For downstream distribution of media data to clients with varying requirements, the central server (along with the source) generate different quality media representations. Each such quality is represented with a unique name and subscribers are made know of the same via the Manifest.
Note: Below json representation is provided as an example and need not be the only way to encode the manifest.
{
  "liveSessionID" : "jon.doe.music.live.tv",
  "streams: [
      {
      "id": "1234",
      "codec": "av1",
      "quality": "1280x720_30fps",
      "bitrate": "1200kbps",
      "crypto": "aes128-gcm",
      },
      {
      "id": "5678",
      "codec": "av1",
      "quality": "3840x2160_30fps",
      "bitrate": "4000kbps",
      "crypto": "aes256-gcm",
      },
      {
      "id": "9999",
      "codec": "av1",
      "quality": "640x480_30fps",
      "crypto": "aes128-gcm",
      },
  ]
}

Given the above manifest, if a publisher wants to send a 4k stream, it does so by publishing objects following the below pattern
//4K Stream
publish: quicr://jon.doe.music.live.tv/video/5678/[groupN/objectM ...]

If at any point, the producer intends to move to a lower quality stream due to underlying network conditions, it can do so by switching the published stream as below
//480p Stream
publish: quicr://jon.doe.music.live.tv/video/9999/[groupN/objectM ...]

and subscriber who is capable of receiving any of the qualities can do so by
// Receiving any of the published streams and use its name
// to know more information about media properties via manifest and
// object data
subscribe: quicr://jon.doe.music.live.tv/video/*

QuicR Protocol Design
QuicR supports delivering media over QUIC Streams as well as over QUIC Datagrams as chosen by the application.
Media delivery in QuicR is started by the publisher/subscriber setting up a "Control Channel" for a given QuicR name. The control channel, which is based on QUIC stream, is used to configure and setup properties for the "Media Channel". Media data is delivered over the Media Channel over QUIC streams or QUIC datagrams based on the application settings. The Control Channel can also be used to configure in-session parameters.
Control Channel
When a client or relay begins a transaction with the relay/origin, the client starts by opening a new bilateral stream. This stream will act as the "control channel" for the exchange of data, carrying a series of control messages in both directions. The same channel can be used for carrying media "fragment" messages if the media data is sent in "stream" mode.
The control stream will remain open as long as the peers are still sending or receiving the media. If either peer closes the control stream, the other peer will close its end of the stream and discard the state associated with the media transfer.
Streams are "one way". If a peer both sends and receive media, there will be different control streams for sending and receiving.
QuicR Control Messages
The control channel carry series of messages, encoded as a length followed by a message value:
quicr_message {
    length(16),
    value(...)
}

The length is encoded as a 16 bit number in big endian network order.
Subscribe Message
Entities that intend to receive named objects will do so via subscriptions to the named objects. Subscriptions are sent from the QuicR clients to the origin server(s) (via relays, if present) and are typically processed by the relays. See {#relay_behavior} for further details. All the subscriptions MUST be authorized at the Origin server.
Subscriptions are typically long-lived transactions and they stay active until one of the following happens
- a client local policy dictates expiration of a subscription.
- optionally, a server policy dictates subscription expiration.
- the underlying transport is disconnected.
When an explicit indication is preferred to indicate the expiry of subscription, it is indicated via SUBSCRIPTION_EXPIRY message.
While the subscription is active for a given name, the Relay(s) must send named objects it receives to all the matching subscribers. A QuicR client can renew its subscriptions at any point by sending a new quicr_subscribe_message. Such subscriptions MUST refresh the existing subscriptions for that name. A renewal period of 5 seconds is RECOMMENDED.
enum subscribe_intent
{
  immediate(0),
  catch_up(1),
  wait_up(2),
}

quicr_subscribe_message {
 *     message_type(i),
 *     name_length(i),
 *     name(...),
 *     mask(7)
 *     subscribe_intent intent,
 *     [datagram_stream_id(i)]
 * }

The message type will be set to SUBSCRIBE_STREAM (1) if the client wants to receive the media in stream mode (via QUIC streams), or SUBSCRIBE_DATAGRAM (2) if receiving in datagram mode. If in datagram mode, the client must select a datagram stream id that is not yet used for any other media stream.
The origin field in the name identifies the Origin server for which this subscription is targeted. name identified the fully formed name or wildcard name along with the appropriate bitmask length.
The intent field specifies how the Relay Function should provided the named objects to the client. Following options are defined for the intent
- immediate: Deliver any new objects it receives that match the name
- catch_up: Deliver any new objects it receives and in addition send any previous objects it has received that matches the name.
- wait_up: Wait until an object that has a objectId that matches the name is received then start sending any objects that match the name.
Aggregating Subscriptions
Subscriptions are aggregated at entities that perform Relay Function. Aggregating subscriptions helps reduce the number of subscriptions for a given named object in transit and also enables efficient distribution of published media with minimal copies between the client and the origin server/ or other relays, as well as reduce the latencies when there are multiple subscribers for a given named object behind a given cloud server.
Wildcard Names
The names used in quicr_subscribe_message can be truncated by skipping the right most segments of the name that is application specific, in which case it will act as a wildcard subscription to all names that match the provided part of the name. The same is indicated via bitmask associated with the name in quicr_subscribe_message. Wildcard search on Relay(s) thus turns into a bitmask at the appropriate bit location of the hashed name.
SUBSCRIBE_REPLY Message
A quicr_subscribe_reply provides result of the subscription.
enum response
{
  ok(0),
  expired(1)
  fail(2),
  redirect(2)
}

quicr_subscribe_reply
{
    Response response
    [Reason Phrase Length (i),
    [Reason Phrase (..)],
}

A response of ok indicates successful subscription, for failed or expired responses, "Reason Phrase" shall be populated with appropriate reason. An response of redirect informs the client that relay is no longer serving the subscriptions and client should retry to the alternate relay provided in the redirect message.
PUBLISH_INTENT Message.
The quicr_publish_intent_message indicates the names chosen by a Publisher for transmitting named objects within a session. This message is sent to the Origin Server whenever a given publisher intends to publish on a new name (which can be at the beginning of the session or during mid session). This message is authorized at the Origin server and thus requires a mechanism to setup the initial trust (via out of band) between the publisher and the origin server.
quicr_publish_intent_message {
 *     message_type(i),
 *     name_length(i),
 *     name(...)
 *     datagram_capable(i)
 * }

The message type will be set to PUBLISH_INTENT (6). The datagram_capable flag is set to 0 if the client can only publish/post data in stream mode, to 1 if the client is also capable of posting media fragments as datagrams.
On a successful validation at the Origin server, a publish_intent_ok message is returned by the Origin server. The publish_intent_ok message is sent in response to the quicr_publish_intent_message, on the server side of the QUIC control stream. This message indicates the publisher is authorized for using the intended name provided in quicr_publish_intent_message.
quicr_publish_intent_ok_message {
  *     message_type(i),
  *     use_datagram(i),
  *     [datagram_stream_id(i)]
}

The message id is set to PUBLISH_INTENT_OK (7). The use_datagram flag is set to 0 if the server wants to receive data in stream mode, and to 1 if the server selects to receive data fragments as datagrams. In that case, the server must select a datagram stream id that is not yet used to receive any other media stream.
This message enables cloud relays to know the authorized names from a given Publisher. This helps to make caching decisions, deal with collisions and so on.
A>A cloud relay could start caching the data associated with the names that has not been validated yet by the origin server and decide to flush its cache if no PUBLISH\_INTENT\_OK is received within a given implementation defined timeout. This is an optimization that would allow publishers to start transmitting the data without needing to wait a RTT.
Start Point Message
The Start Point message indicates the begin of message to be sent for the media. They correspond to Group ID and Object ID of the first object that will be sent for the media. It may be sent by the server that received a quicr_subscribe_message, or by the client that sent a quicr_publish_intent_message. This message is optional: by default, media streams start with Group ID and Object ID set to 0.
 * quicr_start_point_message {
 *     message_type(i),
 *     start_group_id(i),
 *     start_object_id(i),
 *     flags(i)
 * }

The message id is set to START_POINT (8).
Fragment Message
The quicr_fragment_message message is used to convey the content of a media stream as a series of fragments:
quicr_fragment_message {
 *     message_type(i),
 *     group_id(i),
 *     object_id(i),
 *     best_before(i),
 *     flags(i),
 *     offset_and_fin(i),
 *     length(i),
 *     data(...)
 }

 flags := Reserved (3) | IsDiscardable (1) | Priority (3)

The message type will be set to FRAGMENT (5). The offset_and_fin field encodes two values, as in:
offset_and_fin = 2 * offset + is_last_fragment

The flag is_last_fragment is set to 1 if this fragment is the last one of an object. The offset value indicates where the fragment data starts in the object designated by group_id and object_id. Successive messages are sent in order, which means one of the following three conditions must be verified:
- The group id and object id match the group id and object id of the previous fragment, the previous fragment is not a last fragment, and the offset matches the previous offset plus the previous length.
- The group id matches the group id of the previous message, the object id is equal to the object id of the previous fragment plus 1, the offset is 0, and the previous message is a last fragment.
- The group id matches the group id of the previous message plus 1, the object id is 0, the offset is 0, and the previous message is a last fragment.
Fin Message
The Fin message indicates the final point of a media stream.
 * quicr_fin_message {
 *     message_type(i),
 *     final_group_id(i),
 *     final_object_id(i)
 * }

The message type will be set to FIN (3). The final group_id is set to the group_id of the last fragment sent. The final object_id is set to the object_id of the last fragment sent, plus 1. This message is not sent when fragments are sent on stream.
SUBSCRIBE_CANCEL Message
A quicr_subscribe_cancel_message indicates a given subscription is no longer valid. This message is an optional message and is sent to indicate the peer about discontinued interest in a given named data.
 * quicr_subscribe_cancel_message {
 *     message_type(i),
 *     name_length(i),
 *     name(...)
 *     Reason Phrase Length (i),
 *     Reason Phrase (..),
 * }

RELAY_REDIRECT MESSAGE
quicr_relay_redirect_message enables relay failover scenarios that is sent in response to PUBLISH, PUBLISH_INTENT and SUBSCRIBE messages indicating the new relay to the clients.
quicr_relay_redirect_message
{
  relay_address_length(i),
  relay_address(...)
}

Sending Media as Datagrams
If transmission as datagram is negotiated, the media fragments are sent as QUIC Datagram frames.
Datagram Header
The datagram frames are encoded as a datagram header, followed by the bytes in the fragment:
datagram_frame_content {
    datagram_header,
    datagram_content
}

The datagram header is defined as:
 * quicr_datagram_header {
 *     datagram_stream_id (i),
 *     group_id (i),
 *     object_id (i),
 *     offset_and_fin (i),
 *     best_before(i),
 *     flags (8),
 *     [nb_objects_previous_group (i)]
 * }

 flags := Reserved (3) | IsDiscardable (1) | Priority (3)

The datagramstreamid identifies a specific media stream. The ID is chosen by the receiver of the media stream, and conveyed by the Request or Accept messages.
The offset_and_fin field encodes two values, as in:
offset_and_fin = 2*offset + is_last_fragment

The flags identifies the relative priority of this object and if the object can be discarded. This can help Relay to make dropping/caching decisions. best_before identifies the time upto when the data for the given object valid. This aids in caches dropping the data after best_before and also cease any error recovery mechanisms that might be in progress for the corresponding data. best_before can also be used by clients to make send/drop decisions.
The nb_objects_previous_group is present if and only if this is the first fragment of the first object in a group, i.e., object_id and offset are both zero. The number indicates how many objects were sent in the previous groups. It enables receiver to check whether all these objects have been received.
Relay Function and Relays
Clients may be configured to connect to a local relay which then does a Publish/Subscribe for the appropriate named data towards the origin or towards another Relay. These relays can aggregate the subscriptions of multiple clients. This allows a relay in the LAN to aggregate request from multiple clients in subscription to the same data such that only one copy of the data flows across the WAN. In the case where there is only one client, this may still provides benefit in that a client that is experiencing loss on WIFI WAN has a very short RTT to the local relay so can recover the lost data much faster, and with less impact on end user QoE, than having to go across the LAN to recover the data.
Relays can also be deployed in classic CDN cache style for large scale streaming applications yet still provide much lower latency than traditional CDNs using Dash or HLS. Moving these relays into the 5G network close to clients may provide additional increase in QoE.
At a high level, Relay Function within QuicR architecture support store and forward behavior. Relay function can be realized in any component of the QuicR architecture depending on the application. Typical use-cases might require the intermediate servers (caches) and the origin server to implement the relay function. However the endpoint themselves can implement the Relay function in a Isomorphic deployment, if needed.
The relays are capable of receiving data in stream mode or in datagram mode. In both modes, relays will cache fragments as they arrive.
In all modes, the relays maintain a list of connections that will receive new fragments when they are ready: connections from clients that have subscribed to the stream through this relay; and, if the media was received from a client, a connection to the origin to pass the content of the client-posted media to the origin. When new fragments are received, they are posted on the relevant connections as soon as the flow control and congestion control of the underlying QUIC connections allow.
Cache and Relaying
The prototype relays maintain a separate cache of received fragments for each media stream that it is processing. If fragments are received in stream mode, they will arrive in order. If fragments are received in datagram mode, fragments may arrive out of order.
The cache is created the first time a client connection refers to the media URL. This might be:
- A client connection requesting the name, in which case the relay will ask a copy of the media from the origin or the next hop relay towards the origin.
- A client connection publishing named data, in which case the relay will post a copy of the media towards the origin.
Once the media is available, the relay will learn the starting group ID and object ID.
Fragments are received from the "incoming" connection. If fragments are received in stream mode, they will arrive in order. If fragments are received in datagram mode, fragments may arrive out of order. When receiving in datagram mode, the media order is used to remove incoming duplicate fragments. When a non duplicate fragment is received, it is added to the cache and posted to corresponding subscribers over streams or datagrams, when flow and congestion control allow transmissions
In stream mode, the transmission may be delayed until fragments are received in order. If the last fragment received "fills a hole", that fragment and the next available fragments in media order will be forwarded.
Out of order relaying
As noted in Section 8.1, fragments that arrive out of order are relayed immediately.
This design has better properties compared to the following alternatives:
- insisting on full order before relaying, as is done for stream mode; OR
- insisting on full reception of all fragments making an object.
Full order would introduce the same head-of-line blocking also visible in stream-based relays. In theory, relaying full objects without requiring that objects be ordered would avoid some of the head-of-line blocking, but in practice it is observed when some streams contain large and small objects, and that losses affecting fragments of large objects cause almost the same head of line blocking delays as full ordering. Moreover, if losses happen at several places in the relay graph, the delays will accumulate. Out of order relaying avoids these delays.
Relay or Cache or Drop Decisions
Relays makes use of priority, time-to-live, is_discardable metadata properties from the published data to make forward or drop decisions when reacting to congestion as indicated by the underlying QUIC stack. The same can be used to make caching decisions.
Cache cleanup
Relays store objects no more than best_before time associated with the object. Congestion/Rate control feedback can further influence what gets cached based on the relative priority and rate at which data can be delivered. Local cache policies can also limit the amount and duration of data that can be cached.
Relay fail over
A relay that wants to shutdown shall use the redirect message to move traffic to a new relay. If a relay has failed and restarted or been load balanced to a different relay, the client will need to resubscribe to the new relay after setting up the connection.
TODO: Cluster so high reliable relays should share subscription info and publication to minimize of loss of data during a full over.
Relay Discovery
Local relays can be discovered via MDNS query to TODO. Cloud relays are discovered via application defined ways that is out of scope of this document. A Relay can send a message to client with the address of new relay. Client moves to the new relay with all of its Subscriptions and then Client unsubscribes from old relay and closes connection to it.
This allows for make before break transfer from one relay to another so that no data is lost during transition. One of the uses of this is upgrade of the Relay software during operation.
Acknowledgments
Thanks to TODO for contributions and suggestions to this specification.
TODO Items
- Authorization and Authentication Considerations for control and media messages
- End to End Security of named objects
- Manifest Encoding