1 // Copyright (c) 2012 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 #include "quiche/quic/core/quic_versions.h"
6
7 #include <cstddef>
8 #include <sstream>
9
10 #include "absl/algorithm/container.h"
11 #include "absl/base/macros.h"
12 #include "quiche/quic/platform/api/quic_expect_bug.h"
13 #include "quiche/quic/platform/api/quic_flags.h"
14 #include "quiche/quic/platform/api/quic_test.h"
15
16 namespace quic {
17 namespace test {
18 namespace {
19
20 using ::testing::ElementsAre;
21 using ::testing::IsEmpty;
22
TEST(QuicVersionsTest,CreateQuicVersionLabelUnsupported)23 TEST(QuicVersionsTest, CreateQuicVersionLabelUnsupported) {
24 EXPECT_QUIC_BUG(
25 CreateQuicVersionLabel(UnsupportedQuicVersion()),
26 "Unsupported version QUIC_VERSION_UNSUPPORTED PROTOCOL_UNSUPPORTED");
27 }
28
TEST(QuicVersionsTest,KnownAndValid)29 TEST(QuicVersionsTest, KnownAndValid) {
30 for (const ParsedQuicVersion& version : AllSupportedVersions()) {
31 EXPECT_TRUE(version.IsKnown());
32 EXPECT_TRUE(ParsedQuicVersionIsValid(version.handshake_protocol,
33 version.transport_version));
34 }
35 ParsedQuicVersion unsupported = UnsupportedQuicVersion();
36 EXPECT_FALSE(unsupported.IsKnown());
37 EXPECT_TRUE(ParsedQuicVersionIsValid(unsupported.handshake_protocol,
38 unsupported.transport_version));
39 ParsedQuicVersion reserved = QuicVersionReservedForNegotiation();
40 EXPECT_TRUE(reserved.IsKnown());
41 EXPECT_TRUE(ParsedQuicVersionIsValid(reserved.handshake_protocol,
42 reserved.transport_version));
43 // Check that invalid combinations are not valid.
44 EXPECT_FALSE(ParsedQuicVersionIsValid(PROTOCOL_TLS1_3, QUIC_VERSION_46));
45 EXPECT_FALSE(ParsedQuicVersionIsValid(PROTOCOL_QUIC_CRYPTO,
46 QUIC_VERSION_IETF_DRAFT_29));
47 // Check that deprecated versions are not valid.
48 EXPECT_FALSE(ParsedQuicVersionIsValid(PROTOCOL_QUIC_CRYPTO,
49 static_cast<QuicTransportVersion>(33)));
50 EXPECT_FALSE(ParsedQuicVersionIsValid(PROTOCOL_QUIC_CRYPTO,
51 static_cast<QuicTransportVersion>(99)));
52 EXPECT_FALSE(ParsedQuicVersionIsValid(PROTOCOL_TLS1_3,
53 static_cast<QuicTransportVersion>(99)));
54 }
55
TEST(QuicVersionsTest,Features)56 TEST(QuicVersionsTest, Features) {
57 ParsedQuicVersion parsed_version_q046 = ParsedQuicVersion::Q046();
58 ParsedQuicVersion parsed_version_draft_29 = ParsedQuicVersion::Draft29();
59
60 EXPECT_TRUE(parsed_version_q046.IsKnown());
61 EXPECT_FALSE(parsed_version_q046.KnowsWhichDecrypterToUse());
62 EXPECT_FALSE(parsed_version_q046.UsesInitialObfuscators());
63 EXPECT_FALSE(parsed_version_q046.AllowsLowFlowControlLimits());
64 EXPECT_FALSE(parsed_version_q046.HasHeaderProtection());
65 EXPECT_FALSE(parsed_version_q046.SupportsRetry());
66 EXPECT_FALSE(
67 parsed_version_q046.SendsVariableLengthPacketNumberInLongHeader());
68 EXPECT_FALSE(parsed_version_q046.AllowsVariableLengthConnectionIds());
69 EXPECT_FALSE(parsed_version_q046.SupportsClientConnectionIds());
70 EXPECT_FALSE(parsed_version_q046.HasLengthPrefixedConnectionIds());
71 EXPECT_FALSE(parsed_version_q046.SupportsAntiAmplificationLimit());
72 EXPECT_FALSE(parsed_version_q046.CanSendCoalescedPackets());
73 EXPECT_TRUE(parsed_version_q046.SupportsGoogleAltSvcFormat());
74 EXPECT_FALSE(parsed_version_q046.UsesHttp3());
75 EXPECT_FALSE(parsed_version_q046.HasLongHeaderLengths());
76 EXPECT_FALSE(parsed_version_q046.UsesCryptoFrames());
77 EXPECT_FALSE(parsed_version_q046.HasIetfQuicFrames());
78 EXPECT_FALSE(parsed_version_q046.UsesTls());
79 EXPECT_TRUE(parsed_version_q046.UsesQuicCrypto());
80
81 EXPECT_TRUE(parsed_version_draft_29.IsKnown());
82 EXPECT_TRUE(parsed_version_draft_29.KnowsWhichDecrypterToUse());
83 EXPECT_TRUE(parsed_version_draft_29.UsesInitialObfuscators());
84 EXPECT_TRUE(parsed_version_draft_29.AllowsLowFlowControlLimits());
85 EXPECT_TRUE(parsed_version_draft_29.HasHeaderProtection());
86 EXPECT_TRUE(parsed_version_draft_29.SupportsRetry());
87 EXPECT_TRUE(
88 parsed_version_draft_29.SendsVariableLengthPacketNumberInLongHeader());
89 EXPECT_TRUE(parsed_version_draft_29.AllowsVariableLengthConnectionIds());
90 EXPECT_TRUE(parsed_version_draft_29.SupportsClientConnectionIds());
91 EXPECT_TRUE(parsed_version_draft_29.HasLengthPrefixedConnectionIds());
92 EXPECT_TRUE(parsed_version_draft_29.SupportsAntiAmplificationLimit());
93 EXPECT_TRUE(parsed_version_draft_29.CanSendCoalescedPackets());
94 EXPECT_FALSE(parsed_version_draft_29.SupportsGoogleAltSvcFormat());
95 EXPECT_TRUE(parsed_version_draft_29.UsesHttp3());
96 EXPECT_TRUE(parsed_version_draft_29.HasLongHeaderLengths());
97 EXPECT_TRUE(parsed_version_draft_29.UsesCryptoFrames());
98 EXPECT_TRUE(parsed_version_draft_29.HasIetfQuicFrames());
99 EXPECT_TRUE(parsed_version_draft_29.UsesTls());
100 EXPECT_FALSE(parsed_version_draft_29.UsesQuicCrypto());
101 }
102
TEST(QuicVersionsTest,ParseQuicVersionLabel)103 TEST(QuicVersionsTest, ParseQuicVersionLabel) {
104 static_assert(SupportedVersions().size() == 5u,
105 "Supported versions out of sync");
106 EXPECT_EQ(ParsedQuicVersion::Q046(),
107 ParseQuicVersionLabel(MakeVersionLabel('Q', '0', '4', '6')));
108 EXPECT_EQ(ParsedQuicVersion::Q050(),
109 ParseQuicVersionLabel(MakeVersionLabel('Q', '0', '5', '0')));
110 EXPECT_EQ(ParsedQuicVersion::Draft29(),
111 ParseQuicVersionLabel(MakeVersionLabel(0xff, 0x00, 0x00, 0x1d)));
112 EXPECT_EQ(ParsedQuicVersion::RFCv1(),
113 ParseQuicVersionLabel(MakeVersionLabel(0x00, 0x00, 0x00, 0x01)));
114 EXPECT_EQ(ParsedQuicVersion::RFCv2(),
115 ParseQuicVersionLabel(MakeVersionLabel(0x6b, 0x33, 0x43, 0xcf)));
116 EXPECT_EQ((ParsedQuicVersionVector{ParsedQuicVersion::RFCv2(),
117 ParsedQuicVersion::RFCv1(),
118 ParsedQuicVersion::Draft29()}),
119 ParseQuicVersionLabelVector(QuicVersionLabelVector{
120 MakeVersionLabel(0x6b, 0x33, 0x43, 0xcf),
121 MakeVersionLabel(0x00, 0x00, 0x00, 0x01),
122 MakeVersionLabel(0xaa, 0xaa, 0xaa, 0xaa),
123 MakeVersionLabel(0xff, 0x00, 0x00, 0x1d)}));
124
125 for (const ParsedQuicVersion& version : AllSupportedVersions()) {
126 EXPECT_EQ(version, ParseQuicVersionLabel(CreateQuicVersionLabel(version)));
127 }
128 }
129
TEST(QuicVersionsTest,ParseQuicVersionString)130 TEST(QuicVersionsTest, ParseQuicVersionString) {
131 static_assert(SupportedVersions().size() == 5u,
132 "Supported versions out of sync");
133 EXPECT_EQ(ParsedQuicVersion::Q046(),
134 ParseQuicVersionString("QUIC_VERSION_46"));
135 EXPECT_EQ(ParsedQuicVersion::Q046(), ParseQuicVersionString("46"));
136 EXPECT_EQ(ParsedQuicVersion::Q046(), ParseQuicVersionString("Q046"));
137 EXPECT_EQ(ParsedQuicVersion::Q050(), ParseQuicVersionString("Q050"));
138 EXPECT_EQ(ParsedQuicVersion::Q050(), ParseQuicVersionString("50"));
139 EXPECT_EQ(ParsedQuicVersion::Q050(), ParseQuicVersionString("h3-Q050"));
140
141 EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionString(""));
142 EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionString("Q 46"));
143 EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionString("Q046 "));
144 EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionString("99"));
145 EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionString("70"));
146
147 EXPECT_EQ(ParsedQuicVersion::Draft29(), ParseQuicVersionString("ff00001d"));
148 EXPECT_EQ(ParsedQuicVersion::Draft29(), ParseQuicVersionString("draft29"));
149 EXPECT_EQ(ParsedQuicVersion::Draft29(), ParseQuicVersionString("h3-29"));
150
151 EXPECT_EQ(ParsedQuicVersion::RFCv1(), ParseQuicVersionString("00000001"));
152 EXPECT_EQ(ParsedQuicVersion::RFCv1(), ParseQuicVersionString("h3"));
153
154 // QUICv2 will never be the result for "h3".
155
156 for (const ParsedQuicVersion& version : AllSupportedVersions()) {
157 EXPECT_EQ(version,
158 ParseQuicVersionString(ParsedQuicVersionToString(version)));
159 EXPECT_EQ(version, ParseQuicVersionString(QuicVersionLabelToString(
160 CreateQuicVersionLabel(version))));
161 if (!version.AlpnDeferToRFCv1()) {
162 EXPECT_EQ(version, ParseQuicVersionString(AlpnForVersion(version)));
163 }
164 }
165 }
166
TEST(QuicVersionsTest,ParseQuicVersionVectorString)167 TEST(QuicVersionsTest, ParseQuicVersionVectorString) {
168 ParsedQuicVersion version_q046 = ParsedQuicVersion::Q046();
169 ParsedQuicVersion version_q050 = ParsedQuicVersion::Q050();
170 ParsedQuicVersion version_draft_29 = ParsedQuicVersion::Draft29();
171
172 EXPECT_THAT(ParseQuicVersionVectorString(""), IsEmpty());
173
174 EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_50"),
175 ElementsAre(version_q050));
176 EXPECT_THAT(ParseQuicVersionVectorString("h3-Q050"),
177 ElementsAre(version_q050));
178 EXPECT_THAT(ParseQuicVersionVectorString("h3-Q050, h3-29"),
179 ElementsAre(version_q050, version_draft_29));
180 EXPECT_THAT(ParseQuicVersionVectorString("h3-29,h3-Q050,h3-29"),
181 ElementsAre(version_draft_29, version_q050));
182 EXPECT_THAT(ParseQuicVersionVectorString("h3-29,h3-Q050, h3-29"),
183 ElementsAre(version_draft_29, version_q050));
184 EXPECT_THAT(ParseQuicVersionVectorString("h3-29, h3-Q050"),
185 ElementsAre(version_draft_29, version_q050));
186 EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_50,h3-29"),
187 ElementsAre(version_q050, version_draft_29));
188 EXPECT_THAT(ParseQuicVersionVectorString("h3-29,QUIC_VERSION_50"),
189 ElementsAre(version_draft_29, version_q050));
190 EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_50, h3-29"),
191 ElementsAre(version_q050, version_draft_29));
192 EXPECT_THAT(ParseQuicVersionVectorString("h3-29, QUIC_VERSION_50"),
193 ElementsAre(version_draft_29, version_q050));
194 EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_50,QUIC_VERSION_46"),
195 ElementsAre(version_q050, version_q046));
196 EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_46,QUIC_VERSION_50"),
197 ElementsAre(version_q046, version_q050));
198
199 // Regression test for https://crbug.com/1044952.
200 EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_50, QUIC_VERSION_50"),
201 ElementsAre(version_q050));
202 EXPECT_THAT(ParseQuicVersionVectorString("h3-Q050, h3-Q050"),
203 ElementsAre(version_q050));
204 EXPECT_THAT(ParseQuicVersionVectorString("h3-Q050, QUIC_VERSION_50"),
205 ElementsAre(version_q050));
206 EXPECT_THAT(ParseQuicVersionVectorString(
207 "QUIC_VERSION_50, h3-Q050, QUIC_VERSION_50, h3-Q050"),
208 ElementsAre(version_q050));
209 EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_50, h3-29, h3-Q050"),
210 ElementsAre(version_q050, version_draft_29));
211
212 EXPECT_THAT(ParseQuicVersionVectorString("99"), IsEmpty());
213 EXPECT_THAT(ParseQuicVersionVectorString("70"), IsEmpty());
214 EXPECT_THAT(ParseQuicVersionVectorString("h3-01"), IsEmpty());
215 EXPECT_THAT(ParseQuicVersionVectorString("h3-01,h3-29"),
216 ElementsAre(version_draft_29));
217 }
218
219 // Do not use MakeVersionLabel() to generate expectations, because
220 // CreateQuicVersionLabel() uses MakeVersionLabel() internally,
221 // in case it has a bug.
TEST(QuicVersionsTest,CreateQuicVersionLabel)222 TEST(QuicVersionsTest, CreateQuicVersionLabel) {
223 static_assert(SupportedVersions().size() == 5u,
224 "Supported versions out of sync");
225 EXPECT_EQ(0x51303436u, CreateQuicVersionLabel(ParsedQuicVersion::Q046()));
226 EXPECT_EQ(0x51303530u, CreateQuicVersionLabel(ParsedQuicVersion::Q050()));
227 EXPECT_EQ(0xff00001du, CreateQuicVersionLabel(ParsedQuicVersion::Draft29()));
228 EXPECT_EQ(0x00000001u, CreateQuicVersionLabel(ParsedQuicVersion::RFCv1()));
229 EXPECT_EQ(0x6b3343cfu, CreateQuicVersionLabel(ParsedQuicVersion::RFCv2()));
230
231 // Make sure the negotiation reserved version is in the IETF reserved space.
232 EXPECT_EQ(
233 0xda5a3a3au & 0x0f0f0f0f,
234 CreateQuicVersionLabel(ParsedQuicVersion::ReservedForNegotiation()) &
235 0x0f0f0f0f);
236
237 // Make sure that disabling randomness works.
238 SetQuicFlag(quic_disable_version_negotiation_grease_randomness, true);
239 EXPECT_EQ(0xda5a3a3au, CreateQuicVersionLabel(
240 ParsedQuicVersion::ReservedForNegotiation()));
241 }
242
TEST(QuicVersionsTest,QuicVersionLabelToString)243 TEST(QuicVersionsTest, QuicVersionLabelToString) {
244 static_assert(SupportedVersions().size() == 5u,
245 "Supported versions out of sync");
246 EXPECT_EQ("Q046", QuicVersionLabelToString(
247 CreateQuicVersionLabel(ParsedQuicVersion::Q046())));
248 EXPECT_EQ("Q050", QuicVersionLabelToString(
249 CreateQuicVersionLabel(ParsedQuicVersion::Q050())));
250 EXPECT_EQ("ff00001d", QuicVersionLabelToString(CreateQuicVersionLabel(
251 ParsedQuicVersion::Draft29())));
252 EXPECT_EQ("00000001", QuicVersionLabelToString(CreateQuicVersionLabel(
253 ParsedQuicVersion::RFCv1())));
254 EXPECT_EQ("6b3343cf", QuicVersionLabelToString(CreateQuicVersionLabel(
255 ParsedQuicVersion::RFCv2())));
256
257 QuicVersionLabelVector version_labels = {
258 MakeVersionLabel('Q', '0', '3', '5'),
259 MakeVersionLabel('T', '0', '3', '8'),
260 MakeVersionLabel(0xff, 0, 0, 7),
261 };
262
263 EXPECT_EQ("Q035", QuicVersionLabelToString(version_labels[0]));
264 EXPECT_EQ("T038", QuicVersionLabelToString(version_labels[1]));
265 EXPECT_EQ("ff000007", QuicVersionLabelToString(version_labels[2]));
266
267 EXPECT_EQ("Q035,T038,ff000007",
268 QuicVersionLabelVectorToString(version_labels));
269 EXPECT_EQ("Q035:T038:ff000007",
270 QuicVersionLabelVectorToString(version_labels, ":", 2));
271 EXPECT_EQ("Q035|T038|...",
272 QuicVersionLabelVectorToString(version_labels, "|", 1));
273
274 std::ostringstream os;
275 os << version_labels;
276 EXPECT_EQ("Q035,T038,ff000007", os.str());
277 }
278
TEST(QuicVersionsTest,ParseQuicVersionLabelString)279 TEST(QuicVersionsTest, ParseQuicVersionLabelString) {
280 static_assert(SupportedVersions().size() == 5u,
281 "Supported versions out of sync");
282 // Explicitly test known QUIC version label strings.
283 EXPECT_EQ(ParsedQuicVersion::Q046(), ParseQuicVersionLabelString("Q046"));
284 EXPECT_EQ(ParsedQuicVersion::Q050(), ParseQuicVersionLabelString("Q050"));
285 EXPECT_EQ(ParsedQuicVersion::Draft29(),
286 ParseQuicVersionLabelString("ff00001d"));
287 EXPECT_EQ(ParsedQuicVersion::RFCv1(),
288 ParseQuicVersionLabelString("00000001"));
289 EXPECT_EQ(ParsedQuicVersion::RFCv2(),
290 ParseQuicVersionLabelString("6b3343cf"));
291
292 // Sanity check that a variety of other serialization formats are ignored.
293 EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionLabelString("1"));
294 EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionLabelString("46"));
295 EXPECT_EQ(UnsupportedQuicVersion(),
296 ParseQuicVersionLabelString("QUIC_VERSION_46"));
297 EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionLabelString("h3"));
298 EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionLabelString("h3-29"));
299
300 // Test round-trips between QuicVersionLabelToString and
301 // ParseQuicVersionLabelString.
302 for (const ParsedQuicVersion& version : AllSupportedVersions()) {
303 EXPECT_EQ(version, ParseQuicVersionLabelString(QuicVersionLabelToString(
304 CreateQuicVersionLabel(version))));
305 }
306 }
307
TEST(QuicVersionsTest,QuicVersionToString)308 TEST(QuicVersionsTest, QuicVersionToString) {
309 EXPECT_EQ("QUIC_VERSION_UNSUPPORTED",
310 QuicVersionToString(QUIC_VERSION_UNSUPPORTED));
311
312 QuicTransportVersion single_version[] = {QUIC_VERSION_46};
313 QuicTransportVersionVector versions_vector;
314 for (size_t i = 0; i < ABSL_ARRAYSIZE(single_version); ++i) {
315 versions_vector.push_back(single_version[i]);
316 }
317 EXPECT_EQ("QUIC_VERSION_46",
318 QuicTransportVersionVectorToString(versions_vector));
319
320 QuicTransportVersion multiple_versions[] = {QUIC_VERSION_UNSUPPORTED,
321 QUIC_VERSION_46};
322 versions_vector.clear();
323 for (size_t i = 0; i < ABSL_ARRAYSIZE(multiple_versions); ++i) {
324 versions_vector.push_back(multiple_versions[i]);
325 }
326 EXPECT_EQ("QUIC_VERSION_UNSUPPORTED,QUIC_VERSION_46",
327 QuicTransportVersionVectorToString(versions_vector));
328
329 // Make sure that all supported versions are present in QuicVersionToString.
330 for (const ParsedQuicVersion& version : AllSupportedVersions()) {
331 EXPECT_NE("QUIC_VERSION_UNSUPPORTED",
332 QuicVersionToString(version.transport_version));
333 }
334
335 std::ostringstream os;
336 os << versions_vector;
337 EXPECT_EQ("QUIC_VERSION_UNSUPPORTED,QUIC_VERSION_46", os.str());
338 }
339
TEST(QuicVersionsTest,ParsedQuicVersionToString)340 TEST(QuicVersionsTest, ParsedQuicVersionToString) {
341 EXPECT_EQ("0", ParsedQuicVersionToString(ParsedQuicVersion::Unsupported()));
342 EXPECT_EQ("Q046", ParsedQuicVersionToString(ParsedQuicVersion::Q046()));
343 EXPECT_EQ("Q050", ParsedQuicVersionToString(ParsedQuicVersion::Q050()));
344 EXPECT_EQ("draft29", ParsedQuicVersionToString(ParsedQuicVersion::Draft29()));
345 EXPECT_EQ("RFCv1", ParsedQuicVersionToString(ParsedQuicVersion::RFCv1()));
346 EXPECT_EQ("RFCv2", ParsedQuicVersionToString(ParsedQuicVersion::RFCv2()));
347
348 ParsedQuicVersionVector versions_vector = {ParsedQuicVersion::Q046()};
349 EXPECT_EQ("Q046", ParsedQuicVersionVectorToString(versions_vector));
350
351 versions_vector = {ParsedQuicVersion::Unsupported(),
352 ParsedQuicVersion::Q046()};
353 EXPECT_EQ("0,Q046", ParsedQuicVersionVectorToString(versions_vector));
354 EXPECT_EQ("0:Q046", ParsedQuicVersionVectorToString(versions_vector, ":",
355 versions_vector.size()));
356 EXPECT_EQ("0|...", ParsedQuicVersionVectorToString(versions_vector, "|", 0));
357
358 // Make sure that all supported versions are present in
359 // ParsedQuicVersionToString.
360 for (const ParsedQuicVersion& version : AllSupportedVersions()) {
361 EXPECT_NE("0", ParsedQuicVersionToString(version));
362 }
363
364 std::ostringstream os;
365 os << versions_vector;
366 EXPECT_EQ("0,Q046", os.str());
367 }
368
TEST(QuicVersionsTest,FilterSupportedVersionsAllVersions)369 TEST(QuicVersionsTest, FilterSupportedVersionsAllVersions) {
370 for (const ParsedQuicVersion& version : AllSupportedVersions()) {
371 QuicEnableVersion(version);
372 }
373 ParsedQuicVersionVector expected_parsed_versions;
374 for (const ParsedQuicVersion& version : SupportedVersions()) {
375 expected_parsed_versions.push_back(version);
376 }
377 EXPECT_EQ(expected_parsed_versions,
378 FilterSupportedVersions(AllSupportedVersions()));
379 EXPECT_EQ(expected_parsed_versions, AllSupportedVersions());
380 }
381
TEST(QuicVersionsTest,FilterSupportedVersionsWithoutFirstVersion)382 TEST(QuicVersionsTest, FilterSupportedVersionsWithoutFirstVersion) {
383 for (const ParsedQuicVersion& version : AllSupportedVersions()) {
384 QuicEnableVersion(version);
385 }
386 QuicDisableVersion(AllSupportedVersions().front());
387 ParsedQuicVersionVector expected_parsed_versions;
388 for (const ParsedQuicVersion& version : SupportedVersions()) {
389 expected_parsed_versions.push_back(version);
390 }
391 expected_parsed_versions.erase(expected_parsed_versions.begin());
392 EXPECT_EQ(expected_parsed_versions,
393 FilterSupportedVersions(AllSupportedVersions()));
394 }
395
TEST(QuicVersionsTest,LookUpParsedVersionByIndex)396 TEST(QuicVersionsTest, LookUpParsedVersionByIndex) {
397 ParsedQuicVersionVector all_versions = AllSupportedVersions();
398 int version_count = all_versions.size();
399 for (int i = -5; i <= version_count + 1; ++i) {
400 ParsedQuicVersionVector index = ParsedVersionOfIndex(all_versions, i);
401 if (i >= 0 && i < version_count) {
402 EXPECT_EQ(all_versions[i], index[0]);
403 } else {
404 EXPECT_EQ(UnsupportedQuicVersion(), index[0]);
405 }
406 }
407 }
408
409 // This test may appear to be so simplistic as to be unnecessary,
410 // yet a typo was made in doing the #defines and it was caught
411 // only in some test far removed from here... Better safe than sorry.
TEST(QuicVersionsTest,CheckTransportVersionNumbersForTypos)412 TEST(QuicVersionsTest, CheckTransportVersionNumbersForTypos) {
413 static_assert(SupportedVersions().size() == 5u,
414 "Supported versions out of sync");
415 EXPECT_EQ(QUIC_VERSION_46, 46);
416 EXPECT_EQ(QUIC_VERSION_50, 50);
417 EXPECT_EQ(QUIC_VERSION_IETF_DRAFT_29, 73);
418 EXPECT_EQ(QUIC_VERSION_IETF_RFC_V1, 80);
419 EXPECT_EQ(QUIC_VERSION_IETF_RFC_V2, 82);
420 }
421
TEST(QuicVersionsTest,AlpnForVersion)422 TEST(QuicVersionsTest, AlpnForVersion) {
423 static_assert(SupportedVersions().size() == 5u,
424 "Supported versions out of sync");
425 EXPECT_EQ("h3-Q046", AlpnForVersion(ParsedQuicVersion::Q046()));
426 EXPECT_EQ("h3-Q050", AlpnForVersion(ParsedQuicVersion::Q050()));
427 EXPECT_EQ("h3-29", AlpnForVersion(ParsedQuicVersion::Draft29()));
428 EXPECT_EQ("h3", AlpnForVersion(ParsedQuicVersion::RFCv1()));
429 EXPECT_EQ("h3", AlpnForVersion(ParsedQuicVersion::RFCv2()));
430 }
431
TEST(QuicVersionsTest,QuicVersionEnabling)432 TEST(QuicVersionsTest, QuicVersionEnabling) {
433 for (const ParsedQuicVersion& version : AllSupportedVersions()) {
434 QuicFlagSaver flag_saver;
435 QuicDisableVersion(version);
436 EXPECT_FALSE(QuicVersionIsEnabled(version));
437 QuicEnableVersion(version);
438 EXPECT_TRUE(QuicVersionIsEnabled(version));
439 }
440 }
441
TEST(QuicVersionsTest,ReservedForNegotiation)442 TEST(QuicVersionsTest, ReservedForNegotiation) {
443 EXPECT_EQ(QUIC_VERSION_RESERVED_FOR_NEGOTIATION,
444 QuicVersionReservedForNegotiation().transport_version);
445 // QUIC_VERSION_RESERVED_FOR_NEGOTIATION MUST NOT be supported.
446 for (const ParsedQuicVersion& version : AllSupportedVersions()) {
447 EXPECT_NE(QUIC_VERSION_RESERVED_FOR_NEGOTIATION, version.transport_version);
448 }
449 }
450
TEST(QuicVersionsTest,SupportedVersionsHasCorrectList)451 TEST(QuicVersionsTest, SupportedVersionsHasCorrectList) {
452 size_t index = 0;
453 for (HandshakeProtocol handshake_protocol : SupportedHandshakeProtocols()) {
454 for (int trans_vers = 255; trans_vers > 0; trans_vers--) {
455 QuicTransportVersion transport_version =
456 static_cast<QuicTransportVersion>(trans_vers);
457 SCOPED_TRACE(index);
458 if (ParsedQuicVersionIsValid(handshake_protocol, transport_version)) {
459 ParsedQuicVersion version = SupportedVersions()[index];
460 EXPECT_EQ(version,
461 ParsedQuicVersion(handshake_protocol, transport_version));
462 index++;
463 }
464 }
465 }
466 EXPECT_EQ(SupportedVersions().size(), index);
467 }
468
TEST(QuicVersionsTest,SupportedVersionsAllDistinct)469 TEST(QuicVersionsTest, SupportedVersionsAllDistinct) {
470 for (size_t index1 = 0; index1 < SupportedVersions().size(); ++index1) {
471 ParsedQuicVersion version1 = SupportedVersions()[index1];
472 for (size_t index2 = index1 + 1; index2 < SupportedVersions().size();
473 ++index2) {
474 ParsedQuicVersion version2 = SupportedVersions()[index2];
475 EXPECT_NE(version1, version2) << version1 << " " << version2;
476 EXPECT_NE(CreateQuicVersionLabel(version1),
477 CreateQuicVersionLabel(version2))
478 << version1 << " " << version2;
479 // The one pair where ALPNs are the same.
480 if ((version1 != ParsedQuicVersion::RFCv2()) &&
481 (version2 != ParsedQuicVersion::RFCv1())) {
482 EXPECT_NE(AlpnForVersion(version1), AlpnForVersion(version2))
483 << version1 << " " << version2;
484 }
485 }
486 }
487 }
488
TEST(QuicVersionsTest,CurrentSupportedHttp3Versions)489 TEST(QuicVersionsTest, CurrentSupportedHttp3Versions) {
490 ParsedQuicVersionVector h3_versions = CurrentSupportedHttp3Versions();
491 ParsedQuicVersionVector all_current_supported_versions =
492 CurrentSupportedVersions();
493 for (auto& version : all_current_supported_versions) {
494 bool version_is_h3 = false;
495 for (auto& h3_version : h3_versions) {
496 if (version == h3_version) {
497 EXPECT_TRUE(version.UsesHttp3());
498 version_is_h3 = true;
499 break;
500 }
501 }
502 if (!version_is_h3) {
503 EXPECT_FALSE(version.UsesHttp3());
504 }
505 }
506 }
507
TEST(QuicVersionsTest,ObsoleteSupportedVersions)508 TEST(QuicVersionsTest, ObsoleteSupportedVersions) {
509 ParsedQuicVersionVector obsolete_versions = ObsoleteSupportedVersions();
510 EXPECT_EQ(quic::ParsedQuicVersion::Q046(), obsolete_versions[0]);
511 EXPECT_EQ(quic::ParsedQuicVersion::Q050(), obsolete_versions[1]);
512 EXPECT_EQ(quic::ParsedQuicVersion::Draft29(), obsolete_versions[2]);
513 }
514
TEST(QuicVersionsTest,IsObsoleteSupportedVersion)515 TEST(QuicVersionsTest, IsObsoleteSupportedVersion) {
516 for (const ParsedQuicVersion& version : AllSupportedVersions()) {
517 bool is_obsolete = version.handshake_protocol != PROTOCOL_TLS1_3 ||
518 version.transport_version < QUIC_VERSION_IETF_RFC_V1;
519 EXPECT_EQ(is_obsolete, IsObsoleteSupportedVersion(version));
520 }
521 }
522
TEST(QuicVersionsTest,CurrentSupportedVersionsForClients)523 TEST(QuicVersionsTest, CurrentSupportedVersionsForClients) {
524 ParsedQuicVersionVector supported_versions = CurrentSupportedVersions();
525 ParsedQuicVersionVector client_versions =
526 CurrentSupportedVersionsForClients();
527 for (auto& version : supported_versions) {
528 const bool is_obsolete = IsObsoleteSupportedVersion(version);
529 const bool is_supported =
530 absl::c_find(client_versions, version) != client_versions.end();
531 // Every supported version which is not obsolete should be a supported
532 // client version.
533 EXPECT_EQ(!is_obsolete, is_supported);
534 }
535 // Every client version should be a supported version, of course.
536 for (auto& version : client_versions) {
537 EXPECT_TRUE(absl::c_find(supported_versions, version) !=
538 supported_versions.end());
539 }
540 }
541
542 } // namespace
543 } // namespace test
544 } // namespace quic
545