blob: e6559052f2ddec2d1c83f290bc966f7b20990bb4 [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// 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 "net/third_party/quiche/src/quic/core/quic_data_writer.h"
6
7#include <cstdint>
dschinazicf5b1e22019-07-17 18:35:17 -07008#include <cstring>
QUICHE teama6ef0a62019-03-07 20:34:33 -05009
10#include "net/third_party/quiche/src/quic/core/quic_connection_id.h"
11#include "net/third_party/quiche/src/quic/core/quic_data_reader.h"
12#include "net/third_party/quiche/src/quic/core/quic_utils.h"
QUICHE team0131a5b2019-03-20 15:23:27 -070013#include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050014#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
15#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
16#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
bnc4e9283d2019-12-17 07:08:57 -080017#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h"
QUICHE team173c48f2019-11-19 16:34:44 -080018#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h"
dmcardlecf0bfcf2019-12-13 08:08:21 -080019#include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h"
20#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
dmcardle8f7df532020-01-07 13:28:57 -080021#include "net/third_party/quiche/src/common/test_tools/quiche_test_utils.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050022
23namespace quic {
24namespace test {
25namespace {
26
27char* AsChars(unsigned char* data) {
28 return reinterpret_cast<char*>(data);
29}
30
31struct TestParams {
QUICHE team173c48f2019-11-19 16:34:44 -080032 explicit TestParams(quiche::Endianness endianness) : endianness(endianness) {}
QUICHE teama6ef0a62019-03-07 20:34:33 -050033
QUICHE team173c48f2019-11-19 16:34:44 -080034 quiche::Endianness endianness;
QUICHE teama6ef0a62019-03-07 20:34:33 -050035};
36
dschinazi142051a2019-09-18 18:17:29 -070037// Used by ::testing::PrintToStringParamName().
38std::string PrintToString(const TestParams& p) {
dmcardlecf0bfcf2019-12-13 08:08:21 -080039 return quiche::QuicheStrCat(
QUICHE team173c48f2019-11-19 16:34:44 -080040 (p.endianness == quiche::NETWORK_BYTE_ORDER ? "Network" : "Host"),
41 "ByteOrder");
dschinazi142051a2019-09-18 18:17:29 -070042}
43
QUICHE teama6ef0a62019-03-07 20:34:33 -050044std::vector<TestParams> GetTestParams() {
45 std::vector<TestParams> params;
QUICHE team173c48f2019-11-19 16:34:44 -080046 for (quiche::Endianness endianness :
47 {quiche::NETWORK_BYTE_ORDER, quiche::HOST_BYTE_ORDER}) {
QUICHE teama6ef0a62019-03-07 20:34:33 -050048 params.push_back(TestParams(endianness));
49 }
50 return params;
51}
52
53class QuicDataWriterTest : public QuicTestWithParam<TestParams> {};
54
QUICHE team0131a5b2019-03-20 15:23:27 -070055INSTANTIATE_TEST_SUITE_P(QuicDataWriterTests,
56 QuicDataWriterTest,
dschinazi142051a2019-09-18 18:17:29 -070057 ::testing::ValuesIn(GetTestParams()),
58 ::testing::PrintToStringParamName());
QUICHE teama6ef0a62019-03-07 20:34:33 -050059
60TEST_P(QuicDataWriterTest, SanityCheckUFloat16Consts) {
61 // Check the arithmetic on the constants - otherwise the values below make
62 // no sense.
63 EXPECT_EQ(30, kUFloat16MaxExponent);
64 EXPECT_EQ(11, kUFloat16MantissaBits);
65 EXPECT_EQ(12, kUFloat16MantissaEffectiveBits);
66 EXPECT_EQ(UINT64_C(0x3FFC0000000), kUFloat16MaxValue);
67}
68
69TEST_P(QuicDataWriterTest, WriteUFloat16) {
70 struct TestCase {
71 uint64_t decoded;
72 uint16_t encoded;
73 };
74 TestCase test_cases[] = {
75 // Small numbers represent themselves.
76 {0, 0},
77 {1, 1},
78 {2, 2},
79 {3, 3},
80 {4, 4},
81 {5, 5},
82 {6, 6},
83 {7, 7},
84 {15, 15},
85 {31, 31},
86 {42, 42},
87 {123, 123},
88 {1234, 1234},
89 // Check transition through 2^11.
90 {2046, 2046},
91 {2047, 2047},
92 {2048, 2048},
93 {2049, 2049},
94 // Running out of mantissa at 2^12.
95 {4094, 4094},
96 {4095, 4095},
97 {4096, 4096},
98 {4097, 4096},
99 {4098, 4097},
100 {4099, 4097},
101 {4100, 4098},
102 {4101, 4098},
103 // Check transition through 2^13.
104 {8190, 6143},
105 {8191, 6143},
106 {8192, 6144},
107 {8193, 6144},
108 {8194, 6144},
109 {8195, 6144},
110 {8196, 6145},
111 {8197, 6145},
112 // Half-way through the exponents.
113 {0x7FF8000, 0x87FF},
114 {0x7FFFFFF, 0x87FF},
115 {0x8000000, 0x8800},
116 {0xFFF0000, 0x8FFF},
117 {0xFFFFFFF, 0x8FFF},
118 {0x10000000, 0x9000},
119 // Transition into the largest exponent.
120 {0x1FFFFFFFFFE, 0xF7FF},
121 {0x1FFFFFFFFFF, 0xF7FF},
122 {0x20000000000, 0xF800},
123 {0x20000000001, 0xF800},
124 {0x2003FFFFFFE, 0xF800},
125 {0x2003FFFFFFF, 0xF800},
126 {0x20040000000, 0xF801},
127 {0x20040000001, 0xF801},
128 // Transition into the max value and clamping.
129 {0x3FF80000000, 0xFFFE},
130 {0x3FFBFFFFFFF, 0xFFFE},
131 {0x3FFC0000000, 0xFFFF},
132 {0x3FFC0000001, 0xFFFF},
133 {0x3FFFFFFFFFF, 0xFFFF},
134 {0x40000000000, 0xFFFF},
135 {0xFFFFFFFFFFFFFFFF, 0xFFFF},
136 };
137 int num_test_cases = sizeof(test_cases) / sizeof(test_cases[0]);
138
139 for (int i = 0; i < num_test_cases; ++i) {
140 char buffer[2];
141 QuicDataWriter writer(2, buffer, GetParam().endianness);
142 EXPECT_TRUE(writer.WriteUFloat16(test_cases[i].decoded));
143 uint16_t result = *reinterpret_cast<uint16_t*>(writer.data());
QUICHE team173c48f2019-11-19 16:34:44 -0800144 if (GetParam().endianness == quiche::NETWORK_BYTE_ORDER) {
145 result = quiche::QuicheEndian::HostToNet16(result);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500146 }
147 EXPECT_EQ(test_cases[i].encoded, result);
148 }
149}
150
151TEST_P(QuicDataWriterTest, ReadUFloat16) {
152 struct TestCase {
153 uint64_t decoded;
154 uint16_t encoded;
155 };
156 TestCase test_cases[] = {
157 // There are fewer decoding test cases because encoding truncates, and
158 // decoding returns the smallest expansion.
159 // Small numbers represent themselves.
160 {0, 0},
161 {1, 1},
162 {2, 2},
163 {3, 3},
164 {4, 4},
165 {5, 5},
166 {6, 6},
167 {7, 7},
168 {15, 15},
169 {31, 31},
170 {42, 42},
171 {123, 123},
172 {1234, 1234},
173 // Check transition through 2^11.
174 {2046, 2046},
175 {2047, 2047},
176 {2048, 2048},
177 {2049, 2049},
178 // Running out of mantissa at 2^12.
179 {4094, 4094},
180 {4095, 4095},
181 {4096, 4096},
182 {4098, 4097},
183 {4100, 4098},
184 // Check transition through 2^13.
185 {8190, 6143},
186 {8192, 6144},
187 {8196, 6145},
188 // Half-way through the exponents.
189 {0x7FF8000, 0x87FF},
190 {0x8000000, 0x8800},
191 {0xFFF0000, 0x8FFF},
192 {0x10000000, 0x9000},
193 // Transition into the largest exponent.
194 {0x1FFE0000000, 0xF7FF},
195 {0x20000000000, 0xF800},
196 {0x20040000000, 0xF801},
197 // Transition into the max value.
198 {0x3FF80000000, 0xFFFE},
199 {0x3FFC0000000, 0xFFFF},
200 };
201 int num_test_cases = sizeof(test_cases) / sizeof(test_cases[0]);
202
203 for (int i = 0; i < num_test_cases; ++i) {
204 uint16_t encoded_ufloat = test_cases[i].encoded;
QUICHE team173c48f2019-11-19 16:34:44 -0800205 if (GetParam().endianness == quiche::NETWORK_BYTE_ORDER) {
206 encoded_ufloat = quiche::QuicheEndian::HostToNet16(encoded_ufloat);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500207 }
208 QuicDataReader reader(reinterpret_cast<char*>(&encoded_ufloat), 2,
209 GetParam().endianness);
210 uint64_t value;
211 EXPECT_TRUE(reader.ReadUFloat16(&value));
212 EXPECT_EQ(test_cases[i].decoded, value);
213 }
214}
215
216TEST_P(QuicDataWriterTest, RoundTripUFloat16) {
217 // Just test all 16-bit encoded values. 0 and max already tested above.
218 uint64_t previous_value = 0;
219 for (uint16_t i = 1; i < 0xFFFF; ++i) {
220 // Read the two bytes.
221 uint16_t read_number = i;
QUICHE team173c48f2019-11-19 16:34:44 -0800222 if (GetParam().endianness == quiche::NETWORK_BYTE_ORDER) {
223 read_number = quiche::QuicheEndian::HostToNet16(read_number);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500224 }
225 QuicDataReader reader(reinterpret_cast<char*>(&read_number), 2,
226 GetParam().endianness);
227 uint64_t value;
228 // All values must be decodable.
229 EXPECT_TRUE(reader.ReadUFloat16(&value));
230 // Check that small numbers represent themselves
231 if (i < 4097) {
232 EXPECT_EQ(i, value);
233 }
234 // Check there's monotonic growth.
235 EXPECT_LT(previous_value, value);
236 // Check that precision is within 0.5% away from the denormals.
237 if (i > 2000) {
238 EXPECT_GT(previous_value * 1005, value * 1000);
239 }
240 // Check we're always within the promised range.
241 EXPECT_LT(value, UINT64_C(0x3FFC0000000));
242 previous_value = value;
243 char buffer[6];
244 QuicDataWriter writer(6, buffer, GetParam().endianness);
245 EXPECT_TRUE(writer.WriteUFloat16(value - 1));
246 EXPECT_TRUE(writer.WriteUFloat16(value));
247 EXPECT_TRUE(writer.WriteUFloat16(value + 1));
248 // Check minimal decoding (previous decoding has previous encoding).
249 uint16_t encoded1 = *reinterpret_cast<uint16_t*>(writer.data());
250 uint16_t encoded2 = *reinterpret_cast<uint16_t*>(writer.data() + 2);
251 uint16_t encoded3 = *reinterpret_cast<uint16_t*>(writer.data() + 4);
QUICHE team173c48f2019-11-19 16:34:44 -0800252 if (GetParam().endianness == quiche::NETWORK_BYTE_ORDER) {
253 encoded1 = quiche::QuicheEndian::NetToHost16(encoded1);
254 encoded2 = quiche::QuicheEndian::NetToHost16(encoded2);
255 encoded3 = quiche::QuicheEndian::NetToHost16(encoded3);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500256 }
257 EXPECT_EQ(i - 1, encoded1);
258 // Check roundtrip.
259 EXPECT_EQ(i, encoded2);
260 // Check next decoding.
261 EXPECT_EQ(i < 4096 ? i + 1 : i, encoded3);
262 }
263}
264
265TEST_P(QuicDataWriterTest, WriteConnectionId) {
266 QuicConnectionId connection_id =
267 TestConnectionId(UINT64_C(0x0011223344556677));
268 char big_endian[] = {
269 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
270 };
bnc4e9283d2019-12-17 07:08:57 -0800271 EXPECT_EQ(connection_id.length(), QUICHE_ARRAYSIZE(big_endian));
dschinazib012d212019-08-01 18:07:26 -0700272 ASSERT_LE(connection_id.length(), 255);
273 char buffer[255];
QUICHE teama6ef0a62019-03-07 20:34:33 -0500274 QuicDataWriter writer(connection_id.length(), buffer, GetParam().endianness);
275 EXPECT_TRUE(writer.WriteConnectionId(connection_id));
dmcardle8f7df532020-01-07 13:28:57 -0800276 quiche::test::CompareCharArraysWithHexError(
277 "connection_id", buffer, connection_id.length(), big_endian,
278 connection_id.length());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500279
280 QuicConnectionId read_connection_id;
281 QuicDataReader reader(buffer, connection_id.length(), GetParam().endianness);
bnc4e9283d2019-12-17 07:08:57 -0800282 EXPECT_TRUE(reader.ReadConnectionId(&read_connection_id,
283 QUICHE_ARRAYSIZE(big_endian)));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500284 EXPECT_EQ(connection_id, read_connection_id);
285}
286
dschinazicf5b1e22019-07-17 18:35:17 -0700287TEST_P(QuicDataWriterTest, LengthPrefixedConnectionId) {
288 QuicConnectionId connection_id =
289 TestConnectionId(UINT64_C(0x0011223344556677));
290 char length_prefixed_connection_id[] = {
291 0x08, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
292 };
bnc4e9283d2019-12-17 07:08:57 -0800293 EXPECT_EQ(QUICHE_ARRAYSIZE(length_prefixed_connection_id),
dschinazicf5b1e22019-07-17 18:35:17 -0700294 kConnectionIdLengthSize + connection_id.length());
dschinazib012d212019-08-01 18:07:26 -0700295 char buffer[kConnectionIdLengthSize + 255] = {};
bnc4e9283d2019-12-17 07:08:57 -0800296 QuicDataWriter writer(QUICHE_ARRAYSIZE(buffer), buffer);
dschinazicf5b1e22019-07-17 18:35:17 -0700297 EXPECT_TRUE(writer.WriteLengthPrefixedConnectionId(connection_id));
dmcardle8f7df532020-01-07 13:28:57 -0800298 quiche::test::CompareCharArraysWithHexError(
dschinazicf5b1e22019-07-17 18:35:17 -0700299 "WriteLengthPrefixedConnectionId", buffer, writer.length(),
300 length_prefixed_connection_id,
bnc4e9283d2019-12-17 07:08:57 -0800301 QUICHE_ARRAYSIZE(length_prefixed_connection_id));
dschinazicf5b1e22019-07-17 18:35:17 -0700302
303 // Verify that writing length then connection ID produces the same output.
bnc4e9283d2019-12-17 07:08:57 -0800304 memset(buffer, 0, QUICHE_ARRAYSIZE(buffer));
305 QuicDataWriter writer2(QUICHE_ARRAYSIZE(buffer), buffer);
dschinazicf5b1e22019-07-17 18:35:17 -0700306 EXPECT_TRUE(writer2.WriteUInt8(connection_id.length()));
307 EXPECT_TRUE(writer2.WriteConnectionId(connection_id));
dmcardle8f7df532020-01-07 13:28:57 -0800308 quiche::test::CompareCharArraysWithHexError(
dschinazicf5b1e22019-07-17 18:35:17 -0700309 "Write length then ConnectionId", buffer, writer2.length(),
310 length_prefixed_connection_id,
bnc4e9283d2019-12-17 07:08:57 -0800311 QUICHE_ARRAYSIZE(length_prefixed_connection_id));
dschinazicf5b1e22019-07-17 18:35:17 -0700312
313 QuicConnectionId read_connection_id;
bnc4e9283d2019-12-17 07:08:57 -0800314 QuicDataReader reader(buffer, QUICHE_ARRAYSIZE(buffer));
dschinazicf5b1e22019-07-17 18:35:17 -0700315 EXPECT_TRUE(reader.ReadLengthPrefixedConnectionId(&read_connection_id));
316 EXPECT_EQ(connection_id, read_connection_id);
317
318 // Verify that reading length then connection ID produces the same output.
319 uint8_t read_connection_id_length2 = 33;
320 QuicConnectionId read_connection_id2;
bnc4e9283d2019-12-17 07:08:57 -0800321 QuicDataReader reader2(buffer, QUICHE_ARRAYSIZE(buffer));
dschinazicf5b1e22019-07-17 18:35:17 -0700322 ASSERT_TRUE(reader2.ReadUInt8(&read_connection_id_length2));
323 EXPECT_EQ(connection_id.length(), read_connection_id_length2);
324 EXPECT_TRUE(reader2.ReadConnectionId(&read_connection_id2,
325 read_connection_id_length2));
326 EXPECT_EQ(connection_id, read_connection_id2);
327}
328
QUICHE teama6ef0a62019-03-07 20:34:33 -0500329TEST_P(QuicDataWriterTest, EmptyConnectionIds) {
330 QuicConnectionId empty_connection_id = EmptyQuicConnectionId();
331 char buffer[2];
bnc4e9283d2019-12-17 07:08:57 -0800332 QuicDataWriter writer(QUICHE_ARRAYSIZE(buffer), buffer,
333 GetParam().endianness);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500334 EXPECT_TRUE(writer.WriteConnectionId(empty_connection_id));
335 EXPECT_TRUE(writer.WriteUInt8(1));
336 EXPECT_TRUE(writer.WriteConnectionId(empty_connection_id));
337 EXPECT_TRUE(writer.WriteUInt8(2));
338 EXPECT_TRUE(writer.WriteConnectionId(empty_connection_id));
339 EXPECT_FALSE(writer.WriteUInt8(3));
340
341 EXPECT_EQ(buffer[0], 1);
342 EXPECT_EQ(buffer[1], 2);
343
344 QuicConnectionId read_connection_id = TestConnectionId();
345 uint8_t read_byte;
bnc4e9283d2019-12-17 07:08:57 -0800346 QuicDataReader reader(buffer, QUICHE_ARRAYSIZE(buffer),
347 GetParam().endianness);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500348 EXPECT_TRUE(reader.ReadConnectionId(&read_connection_id, 0));
349 EXPECT_EQ(read_connection_id, empty_connection_id);
350 EXPECT_TRUE(reader.ReadUInt8(&read_byte));
351 EXPECT_EQ(read_byte, 1);
352 // Reset read_connection_id to something else to verify that
353 // ReadConnectionId properly sets it back to empty.
354 read_connection_id = TestConnectionId();
355 EXPECT_TRUE(reader.ReadConnectionId(&read_connection_id, 0));
356 EXPECT_EQ(read_connection_id, empty_connection_id);
357 EXPECT_TRUE(reader.ReadUInt8(&read_byte));
358 EXPECT_EQ(read_byte, 2);
359 read_connection_id = TestConnectionId();
360 EXPECT_TRUE(reader.ReadConnectionId(&read_connection_id, 0));
361 EXPECT_EQ(read_connection_id, empty_connection_id);
362 EXPECT_FALSE(reader.ReadUInt8(&read_byte));
363}
364
365TEST_P(QuicDataWriterTest, WriteTag) {
366 char CHLO[] = {
367 'C',
368 'H',
369 'L',
370 'O',
371 };
372 const int kBufferLength = sizeof(QuicTag);
373 char buffer[kBufferLength];
374 QuicDataWriter writer(kBufferLength, buffer, GetParam().endianness);
375 writer.WriteTag(kCHLO);
dmcardle8f7df532020-01-07 13:28:57 -0800376 quiche::test::CompareCharArraysWithHexError("CHLO", buffer, kBufferLength,
377 CHLO, kBufferLength);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500378
379 QuicTag read_chlo;
380 QuicDataReader reader(buffer, kBufferLength, GetParam().endianness);
381 reader.ReadTag(&read_chlo);
382 EXPECT_EQ(kCHLO, read_chlo);
383}
384
385TEST_P(QuicDataWriterTest, Write16BitUnsignedIntegers) {
386 char little_endian16[] = {0x22, 0x11};
387 char big_endian16[] = {0x11, 0x22};
388 char buffer16[2];
389 {
390 uint16_t in_memory16 = 0x1122;
391 QuicDataWriter writer(2, buffer16, GetParam().endianness);
392 writer.WriteUInt16(in_memory16);
dmcardle8f7df532020-01-07 13:28:57 -0800393 quiche::test::CompareCharArraysWithHexError(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500394 "uint16_t", buffer16, 2,
QUICHE team173c48f2019-11-19 16:34:44 -0800395 GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian16
396 : little_endian16,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500397 2);
398
399 uint16_t read_number16;
400 QuicDataReader reader(buffer16, 2, GetParam().endianness);
401 reader.ReadUInt16(&read_number16);
402 EXPECT_EQ(in_memory16, read_number16);
403 }
404
405 {
406 uint64_t in_memory16 = 0x0000000000001122;
407 QuicDataWriter writer(2, buffer16, GetParam().endianness);
408 writer.WriteBytesToUInt64(2, in_memory16);
dmcardle8f7df532020-01-07 13:28:57 -0800409 quiche::test::CompareCharArraysWithHexError(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500410 "uint16_t", buffer16, 2,
QUICHE team173c48f2019-11-19 16:34:44 -0800411 GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian16
412 : little_endian16,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500413 2);
414
415 uint64_t read_number16;
416 QuicDataReader reader(buffer16, 2, GetParam().endianness);
417 reader.ReadBytesToUInt64(2, &read_number16);
418 EXPECT_EQ(in_memory16, read_number16);
419 }
420}
421
422TEST_P(QuicDataWriterTest, Write24BitUnsignedIntegers) {
423 char little_endian24[] = {0x33, 0x22, 0x11};
424 char big_endian24[] = {0x11, 0x22, 0x33};
425 char buffer24[3];
426 uint64_t in_memory24 = 0x0000000000112233;
427 QuicDataWriter writer(3, buffer24, GetParam().endianness);
428 writer.WriteBytesToUInt64(3, in_memory24);
dmcardle8f7df532020-01-07 13:28:57 -0800429 quiche::test::CompareCharArraysWithHexError(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500430 "uint24", buffer24, 3,
QUICHE team173c48f2019-11-19 16:34:44 -0800431 GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian24
432 : little_endian24,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500433 3);
434
435 uint64_t read_number24;
436 QuicDataReader reader(buffer24, 3, GetParam().endianness);
437 reader.ReadBytesToUInt64(3, &read_number24);
438 EXPECT_EQ(in_memory24, read_number24);
439}
440
441TEST_P(QuicDataWriterTest, Write32BitUnsignedIntegers) {
442 char little_endian32[] = {0x44, 0x33, 0x22, 0x11};
443 char big_endian32[] = {0x11, 0x22, 0x33, 0x44};
444 char buffer32[4];
445 {
446 uint32_t in_memory32 = 0x11223344;
447 QuicDataWriter writer(4, buffer32, GetParam().endianness);
448 writer.WriteUInt32(in_memory32);
dmcardle8f7df532020-01-07 13:28:57 -0800449 quiche::test::CompareCharArraysWithHexError(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500450 "uint32_t", buffer32, 4,
QUICHE team173c48f2019-11-19 16:34:44 -0800451 GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian32
452 : little_endian32,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500453 4);
454
455 uint32_t read_number32;
456 QuicDataReader reader(buffer32, 4, GetParam().endianness);
457 reader.ReadUInt32(&read_number32);
458 EXPECT_EQ(in_memory32, read_number32);
459 }
460
461 {
462 uint64_t in_memory32 = 0x11223344;
463 QuicDataWriter writer(4, buffer32, GetParam().endianness);
464 writer.WriteBytesToUInt64(4, in_memory32);
dmcardle8f7df532020-01-07 13:28:57 -0800465 quiche::test::CompareCharArraysWithHexError(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500466 "uint32_t", buffer32, 4,
QUICHE team173c48f2019-11-19 16:34:44 -0800467 GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian32
468 : little_endian32,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500469 4);
470
471 uint64_t read_number32;
472 QuicDataReader reader(buffer32, 4, GetParam().endianness);
473 reader.ReadBytesToUInt64(4, &read_number32);
474 EXPECT_EQ(in_memory32, read_number32);
475 }
476}
477
478TEST_P(QuicDataWriterTest, Write40BitUnsignedIntegers) {
479 uint64_t in_memory40 = 0x0000001122334455;
480 char little_endian40[] = {0x55, 0x44, 0x33, 0x22, 0x11};
481 char big_endian40[] = {0x11, 0x22, 0x33, 0x44, 0x55};
482 char buffer40[5];
483 QuicDataWriter writer(5, buffer40, GetParam().endianness);
484 writer.WriteBytesToUInt64(5, in_memory40);
dmcardle8f7df532020-01-07 13:28:57 -0800485 quiche::test::CompareCharArraysWithHexError(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500486 "uint40", buffer40, 5,
QUICHE team173c48f2019-11-19 16:34:44 -0800487 GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian40
488 : little_endian40,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500489 5);
490
491 uint64_t read_number40;
492 QuicDataReader reader(buffer40, 5, GetParam().endianness);
493 reader.ReadBytesToUInt64(5, &read_number40);
494 EXPECT_EQ(in_memory40, read_number40);
495}
496
497TEST_P(QuicDataWriterTest, Write48BitUnsignedIntegers) {
498 uint64_t in_memory48 = 0x0000112233445566;
499 char little_endian48[] = {0x66, 0x55, 0x44, 0x33, 0x22, 0x11};
500 char big_endian48[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
501 char buffer48[6];
502 QuicDataWriter writer(6, buffer48, GetParam().endianness);
503 writer.WriteBytesToUInt64(6, in_memory48);
dmcardle8f7df532020-01-07 13:28:57 -0800504 quiche::test::CompareCharArraysWithHexError(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500505 "uint48", buffer48, 6,
QUICHE team173c48f2019-11-19 16:34:44 -0800506 GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian48
507 : little_endian48,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500508 6);
509
510 uint64_t read_number48;
511 QuicDataReader reader(buffer48, 6, GetParam().endianness);
512 reader.ReadBytesToUInt64(6., &read_number48);
513 EXPECT_EQ(in_memory48, read_number48);
514}
515
516TEST_P(QuicDataWriterTest, Write56BitUnsignedIntegers) {
517 uint64_t in_memory56 = 0x0011223344556677;
518 char little_endian56[] = {0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11};
519 char big_endian56[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
520 char buffer56[7];
521 QuicDataWriter writer(7, buffer56, GetParam().endianness);
522 writer.WriteBytesToUInt64(7, in_memory56);
dmcardle8f7df532020-01-07 13:28:57 -0800523 quiche::test::CompareCharArraysWithHexError(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500524 "uint56", buffer56, 7,
QUICHE team173c48f2019-11-19 16:34:44 -0800525 GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian56
526 : little_endian56,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500527 7);
528
529 uint64_t read_number56;
530 QuicDataReader reader(buffer56, 7, GetParam().endianness);
531 reader.ReadBytesToUInt64(7, &read_number56);
532 EXPECT_EQ(in_memory56, read_number56);
533}
534
535TEST_P(QuicDataWriterTest, Write64BitUnsignedIntegers) {
536 uint64_t in_memory64 = 0x1122334455667788;
537 unsigned char little_endian64[] = {0x88, 0x77, 0x66, 0x55,
538 0x44, 0x33, 0x22, 0x11};
539 unsigned char big_endian64[] = {0x11, 0x22, 0x33, 0x44,
540 0x55, 0x66, 0x77, 0x88};
541 char buffer64[8];
542 QuicDataWriter writer(8, buffer64, GetParam().endianness);
543 writer.WriteBytesToUInt64(8, in_memory64);
dmcardle8f7df532020-01-07 13:28:57 -0800544 quiche::test::CompareCharArraysWithHexError(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500545 "uint64_t", buffer64, 8,
QUICHE team173c48f2019-11-19 16:34:44 -0800546 GetParam().endianness == quiche::NETWORK_BYTE_ORDER
547 ? AsChars(big_endian64)
548 : AsChars(little_endian64),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500549 8);
550
551 uint64_t read_number64;
552 QuicDataReader reader(buffer64, 8, GetParam().endianness);
553 reader.ReadBytesToUInt64(8, &read_number64);
554 EXPECT_EQ(in_memory64, read_number64);
555
556 QuicDataWriter writer2(8, buffer64, GetParam().endianness);
557 writer2.WriteUInt64(in_memory64);
dmcardle8f7df532020-01-07 13:28:57 -0800558 quiche::test::CompareCharArraysWithHexError(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500559 "uint64_t", buffer64, 8,
QUICHE team173c48f2019-11-19 16:34:44 -0800560 GetParam().endianness == quiche::NETWORK_BYTE_ORDER
561 ? AsChars(big_endian64)
562 : AsChars(little_endian64),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500563 8);
564 read_number64 = 0u;
565 QuicDataReader reader2(buffer64, 8, GetParam().endianness);
566 reader2.ReadUInt64(&read_number64);
567 EXPECT_EQ(in_memory64, read_number64);
568}
569
570TEST_P(QuicDataWriterTest, WriteIntegers) {
571 char buf[43];
572 uint8_t i8 = 0x01;
573 uint16_t i16 = 0x0123;
574 uint32_t i32 = 0x01234567;
575 uint64_t i64 = 0x0123456789ABCDEF;
576 QuicDataWriter writer(46, buf, GetParam().endianness);
577 for (size_t i = 0; i < 10; ++i) {
578 switch (i) {
579 case 0u:
580 EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
581 break;
582 case 1u:
583 EXPECT_TRUE(writer.WriteUInt8(i8));
584 EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
585 break;
586 case 2u:
587 EXPECT_TRUE(writer.WriteUInt16(i16));
588 EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
589 break;
590 case 3u:
591 EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
592 break;
593 case 4u:
594 EXPECT_TRUE(writer.WriteUInt32(i32));
595 EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
596 break;
597 case 5u:
598 case 6u:
599 case 7u:
600 case 8u:
601 EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64));
602 break;
603 default:
604 EXPECT_FALSE(writer.WriteBytesToUInt64(i, i64));
605 }
606 }
607
608 QuicDataReader reader(buf, 46, GetParam().endianness);
609 for (size_t i = 0; i < 10; ++i) {
610 uint8_t read8;
611 uint16_t read16;
612 uint32_t read32;
613 uint64_t read64;
614 switch (i) {
615 case 0u:
616 EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
617 EXPECT_EQ(0u, read64);
618 break;
619 case 1u:
620 EXPECT_TRUE(reader.ReadUInt8(&read8));
621 EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
622 EXPECT_EQ(i8, read8);
623 EXPECT_EQ(0xEFu, read64);
624 break;
625 case 2u:
626 EXPECT_TRUE(reader.ReadUInt16(&read16));
627 EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
628 EXPECT_EQ(i16, read16);
629 EXPECT_EQ(0xCDEFu, read64);
630 break;
631 case 3u:
632 EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
633 EXPECT_EQ(0xABCDEFu, read64);
634 break;
635 case 4u:
636 EXPECT_TRUE(reader.ReadUInt32(&read32));
637 EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
638 EXPECT_EQ(i32, read32);
639 EXPECT_EQ(0x89ABCDEFu, read64);
640 break;
641 case 5u:
642 EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
643 EXPECT_EQ(0x6789ABCDEFu, read64);
644 break;
645 case 6u:
646 EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
647 EXPECT_EQ(0x456789ABCDEFu, read64);
648 break;
649 case 7u:
650 EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
651 EXPECT_EQ(0x23456789ABCDEFu, read64);
652 break;
653 case 8u:
654 EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64));
655 EXPECT_EQ(0x0123456789ABCDEFu, read64);
656 break;
657 default:
658 EXPECT_FALSE(reader.ReadBytesToUInt64(i, &read64));
659 }
660 }
661}
662
663TEST_P(QuicDataWriterTest, WriteBytes) {
664 char bytes[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
bnc4e9283d2019-12-17 07:08:57 -0800665 char buf[QUICHE_ARRAYSIZE(bytes)];
666 QuicDataWriter writer(QUICHE_ARRAYSIZE(buf), buf, GetParam().endianness);
667 EXPECT_TRUE(writer.WriteBytes(bytes, QUICHE_ARRAYSIZE(bytes)));
668 for (unsigned int i = 0; i < QUICHE_ARRAYSIZE(bytes); ++i) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500669 EXPECT_EQ(bytes[i], buf[i]);
670 }
671}
672
673const int kVarIntBufferLength = 1024;
674
675// Encodes and then decodes a specified value, checks that the
676// value that was encoded is the same as the decoded value, the length
677// is correct, and that after decoding, all data in the buffer has
678// been consumed..
679// Returns true if everything works, false if not.
680bool EncodeDecodeValue(uint64_t value_in, char* buffer, size_t size_of_buffer) {
681 // Init the buffer to all 0, just for cleanliness. Makes for better
682 // output if, in debugging, we need to dump out the buffer.
683 memset(buffer, 0, size_of_buffer);
684 // make a writer. Note that for IETF encoding
685 // we do not care about endianness... It's always big-endian,
686 // but the c'tor expects to be told what endianness is in force...
QUICHE team173c48f2019-11-19 16:34:44 -0800687 QuicDataWriter writer(size_of_buffer, buffer,
688 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500689
690 // Try to write the value.
691 if (writer.WriteVarInt62(value_in) != true) {
692 return false;
693 }
694 // Look at the value we encoded. Determine how much should have been
695 // used based on the value, and then check the state of the writer
696 // to see that it matches.
697 size_t expected_length = 0;
698 if (value_in <= 0x3f) {
699 expected_length = 1;
700 } else if (value_in <= 0x3fff) {
701 expected_length = 2;
702 } else if (value_in <= 0x3fffffff) {
703 expected_length = 4;
704 } else {
705 expected_length = 8;
706 }
707 if (writer.length() != expected_length) {
708 return false;
709 }
710
711 // set up a reader, just the length we've used, no more, no less.
712 QuicDataReader reader(buffer, expected_length,
QUICHE team173c48f2019-11-19 16:34:44 -0800713 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500714 uint64_t value_out;
715
716 if (reader.ReadVarInt62(&value_out) == false) {
717 return false;
718 }
719 if (value_in != value_out) {
720 return false;
721 }
722 // We only write one value so there had better be nothing left to read
723 return reader.IsDoneReading();
724}
725
726// Test that 8-byte-encoded Variable Length Integers are properly laid
727// out in the buffer.
728TEST_P(QuicDataWriterTest, VarInt8Layout) {
729 char buffer[1024];
730
731 // Check that the layout of bytes in the buffer is correct. Bytes
732 // are always encoded big endian...
733 memset(buffer, 0, sizeof(buffer));
734 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
QUICHE team173c48f2019-11-19 16:34:44 -0800735 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500736 EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x3142f3e4d5c6b7a8)));
737 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 0)),
738 (0x31 + 0xc0)); // 0xc0 for encoding
739 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 1)), 0x42);
740 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 2)), 0xf3);
741 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 3)), 0xe4);
742 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 4)), 0xd5);
743 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 5)), 0xc6);
744 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 6)), 0xb7);
745 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 7)), 0xa8);
746}
747
748// Test that 4-byte-encoded Variable Length Integers are properly laid
749// out in the buffer.
750TEST_P(QuicDataWriterTest, VarInt4Layout) {
751 char buffer[1024];
752
753 // Check that the layout of bytes in the buffer is correct. Bytes
754 // are always encoded big endian...
755 memset(buffer, 0, sizeof(buffer));
756 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
QUICHE team173c48f2019-11-19 16:34:44 -0800757 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500758 EXPECT_TRUE(writer.WriteVarInt62(0x3243f4e5));
759 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 0)),
760 (0x32 + 0x80)); // 0x80 for encoding
761 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 1)), 0x43);
762 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 2)), 0xf4);
763 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 3)), 0xe5);
764}
765
766// Test that 2-byte-encoded Variable Length Integers are properly laid
767// out in the buffer.
768TEST_P(QuicDataWriterTest, VarInt2Layout) {
769 char buffer[1024];
770
771 // Check that the layout of bytes in the buffer is correct. Bytes
772 // are always encoded big endian...
773 memset(buffer, 0, sizeof(buffer));
774 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
QUICHE team173c48f2019-11-19 16:34:44 -0800775 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500776 EXPECT_TRUE(writer.WriteVarInt62(0x3647));
777 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 0)),
778 (0x36 + 0x40)); // 0x40 for encoding
779 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 1)), 0x47);
780}
781
782// Test that 1-byte-encoded Variable Length Integers are properly laid
783// out in the buffer.
784TEST_P(QuicDataWriterTest, VarInt1Layout) {
785 char buffer[1024];
786
787 // Check that the layout of bytes in the buffer
788 // is correct. Bytes are always encoded big endian...
789 memset(buffer, 0, sizeof(buffer));
790 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
QUICHE team173c48f2019-11-19 16:34:44 -0800791 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500792 EXPECT_TRUE(writer.WriteVarInt62(0x3f));
793 EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 0)), 0x3f);
794}
795
796// Test certain, targeted, values that are expected to succeed:
797// 0, 1,
798// 0x3e, 0x3f, 0x40, 0x41 (around the 1-2 byte transitions)
799// 0x3ffe, 0x3fff, 0x4000, 0x4001 (the 2-4 byte transition)
800// 0x3ffffffe, 0x3fffffff, 0x40000000, 0x40000001 (the 4-8 byte
801// transition)
802// 0x3ffffffffffffffe, 0x3fffffffffffffff, (the highest valid values)
803// 0xfe, 0xff, 0x100, 0x101,
804// 0xfffe, 0xffff, 0x10000, 0x10001,
805// 0xfffffe, 0xffffff, 0x1000000, 0x1000001,
806// 0xfffffffe, 0xffffffff, 0x100000000, 0x100000001,
807// 0xfffffffffe, 0xffffffffff, 0x10000000000, 0x10000000001,
808// 0xfffffffffffe, 0xffffffffffff, 0x1000000000000, 0x1000000000001,
809// 0xfffffffffffffe, 0xffffffffffffff, 0x100000000000000, 0x100000000000001,
810TEST_P(QuicDataWriterTest, VarIntGoodTargetedValues) {
811 char buffer[kVarIntBufferLength];
812 uint64_t passing_values[] = {
813 0,
814 1,
815 0x3e,
816 0x3f,
817 0x40,
818 0x41,
819 0x3ffe,
820 0x3fff,
821 0x4000,
822 0x4001,
823 0x3ffffffe,
824 0x3fffffff,
825 0x40000000,
826 0x40000001,
827 0x3ffffffffffffffe,
828 0x3fffffffffffffff,
829 0xfe,
830 0xff,
831 0x100,
832 0x101,
833 0xfffe,
834 0xffff,
835 0x10000,
836 0x10001,
837 0xfffffe,
838 0xffffff,
839 0x1000000,
840 0x1000001,
841 0xfffffffe,
842 0xffffffff,
843 0x100000000,
844 0x100000001,
845 0xfffffffffe,
846 0xffffffffff,
847 0x10000000000,
848 0x10000000001,
849 0xfffffffffffe,
850 0xffffffffffff,
851 0x1000000000000,
852 0x1000000000001,
853 0xfffffffffffffe,
854 0xffffffffffffff,
855 0x100000000000000,
856 0x100000000000001,
857 };
858 for (uint64_t test_val : passing_values) {
859 EXPECT_TRUE(
860 EncodeDecodeValue(test_val, static_cast<char*>(buffer), sizeof(buffer)))
861 << " encode/decode of " << test_val << " failed";
862 }
863}
864//
865// Test certain, targeted, values where failure is expected (the
866// values are invalid w.r.t. IETF VarInt encoding):
867// 0x4000000000000000, 0x4000000000000001, ( Just above max allowed value)
868// 0xfffffffffffffffe, 0xffffffffffffffff, (should fail)
869TEST_P(QuicDataWriterTest, VarIntBadTargetedValues) {
870 char buffer[kVarIntBufferLength];
871 uint64_t failing_values[] = {
872 0x4000000000000000,
873 0x4000000000000001,
874 0xfffffffffffffffe,
875 0xffffffffffffffff,
876 };
877 for (uint64_t test_val : failing_values) {
878 EXPECT_FALSE(
879 EncodeDecodeValue(test_val, static_cast<char*>(buffer), sizeof(buffer)))
880 << " encode/decode of " << test_val << " succeeded, but was an "
881 << "invalid value";
882 }
883}
884
885// Following tests all try to fill the buffer with multiple values,
886// go one value more than the buffer can accommodate, then read
887// the successfully encoded values, and try to read the unsuccessfully
888// encoded value. The following is the number of values to encode.
889const int kMultiVarCount = 1000;
890
891// Test writing & reading multiple 8-byte-encoded varints
892TEST_P(QuicDataWriterTest, MultiVarInt8) {
893 uint64_t test_val;
894 char buffer[8 * kMultiVarCount];
895 memset(buffer, 0, sizeof(buffer));
896 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
QUICHE team173c48f2019-11-19 16:34:44 -0800897 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500898 // Put N values into the buffer. Adding i to the value ensures that
899 // each value is different so we can detect if we overwrite values,
900 // or read the same value over and over.
901 for (int i = 0; i < kMultiVarCount; i++) {
902 EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x3142f3e4d5c6b7a8) + i));
903 }
904 EXPECT_EQ(writer.length(), 8u * kMultiVarCount);
905
906 // N+1st should fail, the buffer is full.
907 EXPECT_FALSE(writer.WriteVarInt62(UINT64_C(0x3142f3e4d5c6b7a8)));
908
909 // Now we should be able to read out the N values that were
910 // successfully encoded.
QUICHE team173c48f2019-11-19 16:34:44 -0800911 QuicDataReader reader(buffer, sizeof(buffer),
912 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500913 for (int i = 0; i < kMultiVarCount; i++) {
914 EXPECT_TRUE(reader.ReadVarInt62(&test_val));
915 EXPECT_EQ(test_val, (UINT64_C(0x3142f3e4d5c6b7a8) + i));
916 }
917 // And the N+1st should fail.
918 EXPECT_FALSE(reader.ReadVarInt62(&test_val));
919}
920
921// Test writing & reading multiple 4-byte-encoded varints
922TEST_P(QuicDataWriterTest, MultiVarInt4) {
923 uint64_t test_val;
924 char buffer[4 * kMultiVarCount];
925 memset(buffer, 0, sizeof(buffer));
926 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
QUICHE team173c48f2019-11-19 16:34:44 -0800927 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500928 // Put N values into the buffer. Adding i to the value ensures that
929 // each value is different so we can detect if we overwrite values,
930 // or read the same value over and over.
931 for (int i = 0; i < kMultiVarCount; i++) {
932 EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x3142f3e4) + i));
933 }
934 EXPECT_EQ(writer.length(), 4u * kMultiVarCount);
935
936 // N+1st should fail, the buffer is full.
937 EXPECT_FALSE(writer.WriteVarInt62(UINT64_C(0x3142f3e4)));
938
939 // Now we should be able to read out the N values that were
940 // successfully encoded.
QUICHE team173c48f2019-11-19 16:34:44 -0800941 QuicDataReader reader(buffer, sizeof(buffer),
942 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500943 for (int i = 0; i < kMultiVarCount; i++) {
944 EXPECT_TRUE(reader.ReadVarInt62(&test_val));
945 EXPECT_EQ(test_val, (UINT64_C(0x3142f3e4) + i));
946 }
947 // And the N+1st should fail.
948 EXPECT_FALSE(reader.ReadVarInt62(&test_val));
949}
950
951// Test writing & reading multiple 2-byte-encoded varints
952TEST_P(QuicDataWriterTest, MultiVarInt2) {
953 uint64_t test_val;
954 char buffer[2 * kMultiVarCount];
955 memset(buffer, 0, sizeof(buffer));
956 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
QUICHE team173c48f2019-11-19 16:34:44 -0800957 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500958 // Put N values into the buffer. Adding i to the value ensures that
959 // each value is different so we can detect if we overwrite values,
960 // or read the same value over and over.
961 for (int i = 0; i < kMultiVarCount; i++) {
962 EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x3142) + i));
963 }
964 EXPECT_EQ(writer.length(), 2u * kMultiVarCount);
965
966 // N+1st should fail, the buffer is full.
967 EXPECT_FALSE(writer.WriteVarInt62(UINT64_C(0x3142)));
968
969 // Now we should be able to read out the N values that were
970 // successfully encoded.
QUICHE team173c48f2019-11-19 16:34:44 -0800971 QuicDataReader reader(buffer, sizeof(buffer),
972 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500973 for (int i = 0; i < kMultiVarCount; i++) {
974 EXPECT_TRUE(reader.ReadVarInt62(&test_val));
975 EXPECT_EQ(test_val, (UINT64_C(0x3142) + i));
976 }
977 // And the N+1st should fail.
978 EXPECT_FALSE(reader.ReadVarInt62(&test_val));
979}
980
981// Test writing & reading multiple 1-byte-encoded varints
982TEST_P(QuicDataWriterTest, MultiVarInt1) {
983 uint64_t test_val;
984 char buffer[1 * kMultiVarCount];
985 memset(buffer, 0, sizeof(buffer));
986 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
QUICHE team173c48f2019-11-19 16:34:44 -0800987 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500988 // Put N values into the buffer. Adding i to the value ensures that
989 // each value is different so we can detect if we overwrite values,
990 // or read the same value over and over. &0xf ensures we do not
991 // overflow the max value for single-byte encoding.
992 for (int i = 0; i < kMultiVarCount; i++) {
993 EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x30) + (i & 0xf)));
994 }
995 EXPECT_EQ(writer.length(), 1u * kMultiVarCount);
996
997 // N+1st should fail, the buffer is full.
998 EXPECT_FALSE(writer.WriteVarInt62(UINT64_C(0x31)));
999
1000 // Now we should be able to read out the N values that were
1001 // successfully encoded.
QUICHE team173c48f2019-11-19 16:34:44 -08001002 QuicDataReader reader(buffer, sizeof(buffer),
1003 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001004 for (int i = 0; i < kMultiVarCount; i++) {
1005 EXPECT_TRUE(reader.ReadVarInt62(&test_val));
1006 EXPECT_EQ(test_val, (UINT64_C(0x30) + (i & 0xf)));
1007 }
1008 // And the N+1st should fail.
1009 EXPECT_FALSE(reader.ReadVarInt62(&test_val));
1010}
1011
1012// Test writing varints with a forced length.
1013TEST_P(QuicDataWriterTest, VarIntFixedLength) {
1014 char buffer[90];
1015 memset(buffer, 0, sizeof(buffer));
1016 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
QUICHE team173c48f2019-11-19 16:34:44 -08001017 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001018
1019 writer.WriteVarInt62(1, VARIABLE_LENGTH_INTEGER_LENGTH_1);
1020 writer.WriteVarInt62(1, VARIABLE_LENGTH_INTEGER_LENGTH_2);
1021 writer.WriteVarInt62(1, VARIABLE_LENGTH_INTEGER_LENGTH_4);
1022 writer.WriteVarInt62(1, VARIABLE_LENGTH_INTEGER_LENGTH_8);
1023
1024 writer.WriteVarInt62(63, VARIABLE_LENGTH_INTEGER_LENGTH_1);
1025 writer.WriteVarInt62(63, VARIABLE_LENGTH_INTEGER_LENGTH_2);
1026 writer.WriteVarInt62(63, VARIABLE_LENGTH_INTEGER_LENGTH_4);
1027 writer.WriteVarInt62(63, VARIABLE_LENGTH_INTEGER_LENGTH_8);
1028
1029 writer.WriteVarInt62(64, VARIABLE_LENGTH_INTEGER_LENGTH_2);
1030 writer.WriteVarInt62(64, VARIABLE_LENGTH_INTEGER_LENGTH_4);
1031 writer.WriteVarInt62(64, VARIABLE_LENGTH_INTEGER_LENGTH_8);
1032
1033 writer.WriteVarInt62(16383, VARIABLE_LENGTH_INTEGER_LENGTH_2);
1034 writer.WriteVarInt62(16383, VARIABLE_LENGTH_INTEGER_LENGTH_4);
1035 writer.WriteVarInt62(16383, VARIABLE_LENGTH_INTEGER_LENGTH_8);
1036
1037 writer.WriteVarInt62(16384, VARIABLE_LENGTH_INTEGER_LENGTH_4);
1038 writer.WriteVarInt62(16384, VARIABLE_LENGTH_INTEGER_LENGTH_8);
1039
1040 writer.WriteVarInt62(1073741823, VARIABLE_LENGTH_INTEGER_LENGTH_4);
1041 writer.WriteVarInt62(1073741823, VARIABLE_LENGTH_INTEGER_LENGTH_8);
1042
1043 writer.WriteVarInt62(1073741824, VARIABLE_LENGTH_INTEGER_LENGTH_8);
1044
QUICHE team173c48f2019-11-19 16:34:44 -08001045 QuicDataReader reader(buffer, sizeof(buffer),
1046 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001047
1048 uint64_t test_val = 0;
1049 for (int i = 0; i < 4; ++i) {
1050 EXPECT_TRUE(reader.ReadVarInt62(&test_val));
1051 EXPECT_EQ(test_val, 1u);
1052 }
1053 for (int i = 0; i < 4; ++i) {
1054 EXPECT_TRUE(reader.ReadVarInt62(&test_val));
1055 EXPECT_EQ(test_val, 63u);
1056 }
1057
1058 for (int i = 0; i < 3; ++i) {
1059 EXPECT_TRUE(reader.ReadVarInt62(&test_val));
1060 EXPECT_EQ(test_val, 64u);
1061 }
1062 for (int i = 0; i < 3; ++i) {
1063 EXPECT_TRUE(reader.ReadVarInt62(&test_val));
1064 EXPECT_EQ(test_val, 16383u);
1065 }
1066
1067 for (int i = 0; i < 2; ++i) {
1068 EXPECT_TRUE(reader.ReadVarInt62(&test_val));
1069 EXPECT_EQ(test_val, 16384u);
1070 }
1071 for (int i = 0; i < 2; ++i) {
1072 EXPECT_TRUE(reader.ReadVarInt62(&test_val));
1073 EXPECT_EQ(test_val, 1073741823u);
1074 }
1075
1076 EXPECT_TRUE(reader.ReadVarInt62(&test_val));
1077 EXPECT_EQ(test_val, 1073741824u);
1078
1079 // We are at the end of the buffer so this should fail.
1080 EXPECT_FALSE(reader.ReadVarInt62(&test_val));
1081}
1082
1083// Test encoding/decoding stream-id values.
1084void EncodeDecodeStreamId(uint64_t value_in, bool expected_decode_result) {
1085 char buffer[1 * kMultiVarCount];
1086 memset(buffer, 0, sizeof(buffer));
1087
1088 // Encode the given Stream ID.
1089 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
QUICHE team173c48f2019-11-19 16:34:44 -08001090 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001091 EXPECT_TRUE(writer.WriteVarInt62(value_in));
1092
QUICHE team173c48f2019-11-19 16:34:44 -08001093 QuicDataReader reader(buffer, sizeof(buffer),
1094 quiche::Endianness::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001095 QuicStreamId received_stream_id;
fkastenholz3c4eabf2019-04-22 07:49:59 -07001096 bool read_result = reader.ReadVarIntU32(&received_stream_id);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001097 EXPECT_EQ(expected_decode_result, read_result);
1098 if (read_result) {
1099 EXPECT_EQ(value_in, received_stream_id);
1100 }
1101}
1102
1103// Test writing & reading stream-ids of various value.
1104TEST_P(QuicDataWriterTest, StreamId1) {
1105 // Check a 1-byte QuicStreamId, should work
1106 EncodeDecodeStreamId(UINT64_C(0x15), true);
1107
1108 // Check a 2-byte QuicStream ID. It should work.
1109 EncodeDecodeStreamId(UINT64_C(0x1567), true);
1110
1111 // Check a QuicStreamId that requires 4 bytes of encoding
1112 // This should work.
1113 EncodeDecodeStreamId(UINT64_C(0x34567890), true);
1114
1115 // Check a QuicStreamId that requires 8 bytes of encoding
1116 // but whose value is in the acceptable range.
1117 // This should work.
1118 EncodeDecodeStreamId(UINT64_C(0xf4567890), true);
1119
1120 // Check QuicStreamIds that require 8 bytes of encoding
1121 // and whose value is not acceptable.
1122 // This should fail.
1123 EncodeDecodeStreamId(UINT64_C(0x100000000), false);
1124 EncodeDecodeStreamId(UINT64_C(0x3fffffffffffffff), false);
1125}
1126
1127TEST_P(QuicDataWriterTest, WriteRandomBytes) {
1128 char buffer[20];
1129 char expected[20];
1130 for (size_t i = 0; i < 20; ++i) {
1131 expected[i] = 'r';
1132 }
1133 MockRandom random;
1134 QuicDataWriter writer(20, buffer, GetParam().endianness);
1135 EXPECT_FALSE(writer.WriteRandomBytes(&random, 30));
1136
1137 EXPECT_TRUE(writer.WriteRandomBytes(&random, 20));
dmcardle8f7df532020-01-07 13:28:57 -08001138 quiche::test::CompareCharArraysWithHexError("random", buffer, 20, expected,
1139 20);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001140}
1141
1142TEST_P(QuicDataWriterTest, PeekVarInt62Length) {
1143 // In range [0, 63], variable length should be 1 byte.
1144 char buffer[20];
QUICHE team173c48f2019-11-19 16:34:44 -08001145 QuicDataWriter writer(20, buffer, quiche::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001146 EXPECT_TRUE(writer.WriteVarInt62(50));
QUICHE team173c48f2019-11-19 16:34:44 -08001147 QuicDataReader reader(buffer, 20, quiche::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001148 EXPECT_EQ(1, reader.PeekVarInt62Length());
1149 // In range (63-16383], variable length should be 2 byte2.
1150 char buffer2[20];
QUICHE team173c48f2019-11-19 16:34:44 -08001151 QuicDataWriter writer2(20, buffer2, quiche::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001152 EXPECT_TRUE(writer2.WriteVarInt62(100));
QUICHE team173c48f2019-11-19 16:34:44 -08001153 QuicDataReader reader2(buffer2, 20, quiche::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001154 EXPECT_EQ(2, reader2.PeekVarInt62Length());
1155 // In range (16383, 1073741823], variable length should be 4 bytes.
1156 char buffer3[20];
QUICHE team173c48f2019-11-19 16:34:44 -08001157 QuicDataWriter writer3(20, buffer3, quiche::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001158 EXPECT_TRUE(writer3.WriteVarInt62(20000));
QUICHE team173c48f2019-11-19 16:34:44 -08001159 QuicDataReader reader3(buffer3, 20, quiche::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001160 EXPECT_EQ(4, reader3.PeekVarInt62Length());
1161 // In range (1073741823, 4611686018427387903], variable length should be 8
1162 // bytes.
1163 char buffer4[20];
QUICHE team173c48f2019-11-19 16:34:44 -08001164 QuicDataWriter writer4(20, buffer4, quiche::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001165 EXPECT_TRUE(writer4.WriteVarInt62(2000000000));
QUICHE team173c48f2019-11-19 16:34:44 -08001166 QuicDataReader reader4(buffer4, 20, quiche::NETWORK_BYTE_ORDER);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001167 EXPECT_EQ(8, reader4.PeekVarInt62Length());
1168}
1169
QUICHE team0131a5b2019-03-20 15:23:27 -07001170TEST_P(QuicDataWriterTest, InvalidConnectionIdLengthRead) {
dschinaziffa83552019-12-17 11:00:23 -08001171 SetQuicRestartFlag(quic_allow_very_long_connection_ids, false);
1172 // TODO(dschinazi) delete this test when we deprecate
1173 // quic_allow_very_long_connection_ids.
dschinazib953d022019-08-01 18:05:58 -07001174 static const uint8_t bad_connection_id_length = 200;
dschinazib012d212019-08-01 18:07:26 -07001175 static_assert(
1176 bad_connection_id_length > kQuicMaxConnectionIdAllVersionsLength,
1177 "bad lengths");
dschinazib953d022019-08-01 18:05:58 -07001178 char buffer[255] = {};
1179 QuicDataReader reader(buffer, sizeof(buffer));
QUICHE team0131a5b2019-03-20 15:23:27 -07001180 QuicConnectionId connection_id;
1181 bool ok;
1182 EXPECT_QUIC_BUG(
1183 ok = reader.ReadConnectionId(&connection_id, bad_connection_id_length),
dmcardlecf0bfcf2019-12-13 08:08:21 -08001184 quiche::QuicheStrCat(
1185 "Attempted to read connection ID with length too high ",
1186 static_cast<int>(bad_connection_id_length)));
QUICHE team0131a5b2019-03-20 15:23:27 -07001187 EXPECT_FALSE(ok);
1188}
1189
fkastenholz3c4eabf2019-04-22 07:49:59 -07001190// Test that ReadVarIntU32 works properly. Tests a valid stream count
1191// (a 32 bit number) and an invalid one (a >32 bit number)
1192TEST_P(QuicDataWriterTest, ValidU32) {
1193 char buffer[1024];
1194 memset(buffer, 0, sizeof(buffer));
1195 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
QUICHE team173c48f2019-11-19 16:34:44 -08001196 quiche::Endianness::NETWORK_BYTE_ORDER);
fkastenholz3c4eabf2019-04-22 07:49:59 -07001197 QuicDataReader reader(buffer, sizeof(buffer));
1198 const QuicStreamCount write_stream_count = 0xffeeddcc;
1199 EXPECT_TRUE(writer.WriteVarInt62(write_stream_count));
1200 QuicStreamCount read_stream_count;
1201 EXPECT_TRUE(reader.ReadVarIntU32(&read_stream_count));
1202 EXPECT_EQ(write_stream_count, read_stream_count);
1203}
1204
1205TEST_P(QuicDataWriterTest, InvalidU32) {
1206 char buffer[1024];
1207 memset(buffer, 0, sizeof(buffer));
1208 QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
QUICHE team173c48f2019-11-19 16:34:44 -08001209 quiche::Endianness::NETWORK_BYTE_ORDER);
fkastenholz3c4eabf2019-04-22 07:49:59 -07001210 QuicDataReader reader(buffer, sizeof(buffer));
1211 EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x1ffeeddcc)));
1212 QuicStreamCount read_stream_count = 123456;
1213 EXPECT_FALSE(reader.ReadVarIntU32(&read_stream_count));
1214 // If the value is bad, read_stream_count ought not change.
1215 EXPECT_EQ(123456u, read_stream_count);
1216}
1217
nharper55fa6132019-05-07 19:37:21 -07001218TEST_P(QuicDataWriterTest, Seek) {
1219 char buffer[3] = {};
bnc4e9283d2019-12-17 07:08:57 -08001220 QuicDataWriter writer(QUICHE_ARRAYSIZE(buffer), buffer,
1221 GetParam().endianness);
nharper55fa6132019-05-07 19:37:21 -07001222 EXPECT_TRUE(writer.WriteUInt8(42));
1223 EXPECT_TRUE(writer.Seek(1));
1224 EXPECT_TRUE(writer.WriteUInt8(3));
1225
1226 char expected[] = {42, 0, 3};
bnc4e9283d2019-12-17 07:08:57 -08001227 for (size_t i = 0; i < QUICHE_ARRAYSIZE(expected); ++i) {
nharper55fa6132019-05-07 19:37:21 -07001228 EXPECT_EQ(buffer[i], expected[i]);
1229 }
1230}
1231
1232TEST_P(QuicDataWriterTest, SeekTooFarFails) {
1233 char buffer[20];
1234
1235 // Check that one can seek to the end of the writer, but not past.
1236 {
bnc4e9283d2019-12-17 07:08:57 -08001237 QuicDataWriter writer(QUICHE_ARRAYSIZE(buffer), buffer,
nharper55fa6132019-05-07 19:37:21 -07001238 GetParam().endianness);
1239 EXPECT_TRUE(writer.Seek(20));
1240 EXPECT_FALSE(writer.Seek(1));
1241 }
1242
1243 // Seeking several bytes past the end fails.
1244 {
bnc4e9283d2019-12-17 07:08:57 -08001245 QuicDataWriter writer(QUICHE_ARRAYSIZE(buffer), buffer,
nharper55fa6132019-05-07 19:37:21 -07001246 GetParam().endianness);
1247 EXPECT_FALSE(writer.Seek(100));
1248 }
1249
1250 // Seeking so far that arithmetic overflow could occur also fails.
1251 {
bnc4e9283d2019-12-17 07:08:57 -08001252 QuicDataWriter writer(QUICHE_ARRAYSIZE(buffer), buffer,
nharper55fa6132019-05-07 19:37:21 -07001253 GetParam().endianness);
1254 EXPECT_TRUE(writer.Seek(10));
1255 EXPECT_FALSE(writer.Seek(std::numeric_limits<size_t>::max()));
1256 }
1257}
1258
dschinazi4b5a68a2019-08-15 15:45:36 -07001259TEST_P(QuicDataWriterTest, PayloadReads) {
1260 char buffer[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
1261 char expected_first_read[4] = {1, 2, 3, 4};
1262 char expected_remaining[12] = {5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
1263 QuicDataReader reader(buffer, sizeof(buffer));
1264 char first_read_buffer[4] = {};
1265 EXPECT_TRUE(reader.ReadBytes(first_read_buffer, sizeof(first_read_buffer)));
dmcardle8f7df532020-01-07 13:28:57 -08001266 quiche::test::CompareCharArraysWithHexError(
dschinazi4b5a68a2019-08-15 15:45:36 -07001267 "first read", first_read_buffer, sizeof(first_read_buffer),
1268 expected_first_read, sizeof(expected_first_read));
dmcardlecf0bfcf2019-12-13 08:08:21 -08001269 quiche::QuicheStringPiece peeked_remaining_payload =
1270 reader.PeekRemainingPayload();
dmcardle8f7df532020-01-07 13:28:57 -08001271 quiche::test::CompareCharArraysWithHexError(
dschinazi4b5a68a2019-08-15 15:45:36 -07001272 "peeked_remaining_payload", peeked_remaining_payload.data(),
1273 peeked_remaining_payload.length(), expected_remaining,
1274 sizeof(expected_remaining));
dmcardlecf0bfcf2019-12-13 08:08:21 -08001275 quiche::QuicheStringPiece full_payload = reader.FullPayload();
dmcardle8f7df532020-01-07 13:28:57 -08001276 quiche::test::CompareCharArraysWithHexError(
1277 "full_payload", full_payload.data(), full_payload.length(), buffer,
1278 sizeof(buffer));
dmcardlecf0bfcf2019-12-13 08:08:21 -08001279 quiche::QuicheStringPiece read_remaining_payload =
1280 reader.ReadRemainingPayload();
dmcardle8f7df532020-01-07 13:28:57 -08001281 quiche::test::CompareCharArraysWithHexError(
dschinazi4b5a68a2019-08-15 15:45:36 -07001282 "read_remaining_payload", read_remaining_payload.data(),
1283 read_remaining_payload.length(), expected_remaining,
1284 sizeof(expected_remaining));
1285 EXPECT_TRUE(reader.IsDoneReading());
dmcardlecf0bfcf2019-12-13 08:08:21 -08001286 quiche::QuicheStringPiece full_payload2 = reader.FullPayload();
dmcardle8f7df532020-01-07 13:28:57 -08001287 quiche::test::CompareCharArraysWithHexError(
1288 "full_payload2", full_payload2.data(), full_payload2.length(), buffer,
1289 sizeof(buffer));
dschinazi4b5a68a2019-08-15 15:45:36 -07001290}
1291
QUICHE teama6ef0a62019-03-07 20:34:33 -05001292} // namespace
1293} // namespace test
1294} // namespace quic