1 // Copyright (c) 2023 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Structured data for message types in draft-ietf-moq-transport-01.
6
7 #ifndef QUICHE_QUIC_MOQT_MOQT_MESSAGES_H_
8 #define QUICHE_QUIC_MOQT_MOQT_MESSAGES_H_
9
10 #include <cstddef>
11 #include <cstdint>
12 #include <optional>
13 #include <string>
14 #include <vector>
15
16 #include "absl/strings/string_view.h"
17 #include "quiche/quic/core/quic_time.h"
18 #include "quiche/quic/core/quic_types.h"
19 #include "quiche/quic/core/quic_versions.h"
20 #include "quiche/common/platform/api/quiche_export.h"
21
22 namespace moqt {
23
GetMoqtSupportedQuicVersions()24 inline constexpr quic::ParsedQuicVersionVector GetMoqtSupportedQuicVersions() {
25 return quic::ParsedQuicVersionVector{quic::ParsedQuicVersion::RFCv1()};
26 }
27
28 enum class MoqtVersion : uint64_t {
29 kDraft01 = 0xff000001,
30 kUnrecognizedVersionForTests = 0xfe0000ff,
31 };
32
33 struct QUICHE_EXPORT MoqtSessionParameters {
34 // TODO: support multiple versions.
35 MoqtVersion version;
36 quic::Perspective perspective;
37 bool using_webtrans;
38 std::string path;
39 };
40
41 // The maximum length of a message, excluding any OBJECT payload. This prevents
42 // DoS attack via forcing the parser to buffer a large message (OBJECT payloads
43 // are not buffered by the parser).
44 inline constexpr size_t kMaxMessageHeaderSize = 2048;
45
46 enum class QUICHE_EXPORT MoqtMessageType : uint64_t {
47 kObjectWithPayloadLength = 0x00,
48 kObjectWithoutPayloadLength = 0x02,
49 kSubscribeRequest = 0x03,
50 kSubscribeOk = 0x04,
51 kSubscribeError = 0x05,
52 kAnnounce = 0x06,
53 kAnnounceOk = 0x7,
54 kAnnounceError = 0x08,
55 kUnannounce = 0x09,
56 kUnsubscribe = 0x0a,
57 kSubscribeFin = 0x0b,
58 kSubscribeRst = 0x0c,
59 kGoAway = 0x10,
60 kClientSetup = 0x40,
61 kServerSetup = 0x41,
62 };
63
64 enum class QUICHE_EXPORT MoqtRole : uint64_t {
65 kIngestion = 0x1,
66 kDelivery = 0x2,
67 kBoth = 0x3,
68 };
69
70 enum class QUICHE_EXPORT MoqtSetupParameter : uint64_t {
71 kRole = 0x0,
72 kPath = 0x1,
73 };
74
75 enum class QUICHE_EXPORT MoqtTrackRequestParameter : uint64_t {
76 // These two should have been deleted in draft-01.
77 // kGroupSequence = 0x0,
78 // kObjectSequence = 0x1,
79 kAuthorizationInfo = 0x2,
80 };
81
82 struct QUICHE_EXPORT MoqtClientSetup {
83 std::vector<MoqtVersion> supported_versions;
84 std::optional<MoqtRole> role;
85 std::optional<absl::string_view> path;
86 };
87
88 struct QUICHE_EXPORT MoqtServerSetup {
89 MoqtVersion selected_version;
90 std::optional<MoqtRole> role;
91 };
92
93 struct QUICHE_EXPORT MoqtObject {
94 uint64_t track_id;
95 uint64_t group_sequence;
96 uint64_t object_sequence;
97 uint64_t object_send_order;
98 std::optional<uint64_t> payload_length;
99 // Message also includes the object payload.
100 };
101
102 enum class QUICHE_EXPORT MoqtSubscribeLocationMode : uint64_t {
103 kNone = 0x0,
104 kAbsolute = 0x1,
105 kRelativePrevious = 0x2,
106 kRelativeNext = 0x3,
107 };
108
109 // kNone: std::optional<MoqtSubscribeLocation> is nullopt.
110 // kAbsolute: absolute = true
111 // kRelativePrevious: absolute is false; relative_value is negative
112 // kRelativeNext: absolute is true; relative_value is positive
113 struct QUICHE_EXPORT MoqtSubscribeLocation {
MoqtSubscribeLocationMoqtSubscribeLocation114 MoqtSubscribeLocation(bool is_absolute, uint64_t abs)
115 : absolute(is_absolute), absolute_value(abs) {}
MoqtSubscribeLocationMoqtSubscribeLocation116 MoqtSubscribeLocation(bool is_absolute, int64_t rel)
117 : absolute(is_absolute), relative_value(rel) {}
118 bool absolute;
119 union {
120 uint64_t absolute_value;
121 int64_t relative_value;
122 };
123 bool operator==(const MoqtSubscribeLocation& other) const {
124 return absolute == other.absolute &&
125 ((absolute && absolute_value == other.absolute_value) ||
126 (!absolute && relative_value == other.relative_value));
127 }
128 };
129
130 struct QUICHE_EXPORT MoqtSubscribeRequest {
131 absl::string_view track_namespace;
132 absl::string_view track_name;
133 // If the mode is kNone, the these are std::nullopt.
134 std::optional<MoqtSubscribeLocation> start_group;
135 std::optional<MoqtSubscribeLocation> start_object;
136 std::optional<MoqtSubscribeLocation> end_group;
137 std::optional<MoqtSubscribeLocation> end_object;
138 std::optional<absl::string_view> authorization_info;
139 };
140
141 struct QUICHE_EXPORT MoqtSubscribeOk {
142 absl::string_view track_namespace;
143 absl::string_view track_name;
144 uint64_t track_id;
145 // The message uses ms, but expires is in us.
146 quic::QuicTimeDelta expires = quic::QuicTimeDelta::FromMilliseconds(0);
147 };
148
149 struct QUICHE_EXPORT MoqtSubscribeError {
150 absl::string_view track_namespace;
151 absl::string_view track_name;
152 uint64_t error_code;
153 absl::string_view reason_phrase;
154 };
155
156 struct QUICHE_EXPORT MoqtUnsubscribe {
157 absl::string_view track_namespace;
158 absl::string_view track_name;
159 };
160
161 struct QUICHE_EXPORT MoqtSubscribeFin {
162 absl::string_view track_namespace;
163 absl::string_view track_name;
164 uint64_t final_group;
165 uint64_t final_object;
166 };
167
168 struct QUICHE_EXPORT MoqtSubscribeRst {
169 absl::string_view track_namespace;
170 absl::string_view track_name;
171 uint64_t error_code;
172 absl::string_view reason_phrase;
173 uint64_t final_group;
174 uint64_t final_object;
175 };
176
177 struct QUICHE_EXPORT MoqtAnnounce {
178 absl::string_view track_namespace;
179 std::optional<absl::string_view> authorization_info;
180 };
181
182 struct QUICHE_EXPORT MoqtAnnounceOk {
183 absl::string_view track_namespace;
184 };
185
186 struct QUICHE_EXPORT MoqtAnnounceError {
187 absl::string_view track_namespace;
188 uint64_t error_code;
189 absl::string_view reason_phrase;
190 };
191
192 struct QUICHE_EXPORT MoqtUnannounce {
193 absl::string_view track_namespace;
194 };
195
196 struct QUICHE_EXPORT MoqtGoAway {
197 absl::string_view new_session_uri;
198 };
199
200 std::string MoqtMessageTypeToString(MoqtMessageType message_type);
201
202 } // namespace moqt
203
204 #endif // QUICHE_QUIC_MOQT_MOQT_MESSAGES_H_
205