blob: ed7a63c88ef14e78e9d1bd1f970897cfb7d66236 [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// Copyright (c) 2018 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/crypto/transport_parameters.h"
6
dschinazi52127d72019-04-17 15:12:38 -07007#include <cstring>
bnc463f2352019-10-10 04:49:34 -07008#include <utility>
dschinazi52127d72019-04-17 15:12:38 -07009
QUICHE teama6ef0a62019-03-07 20:34:33 -050010#include "third_party/boringssl/src/include/openssl/mem.h"
dschinazi6c84c142019-07-31 09:11:49 -070011#include "net/third_party/quiche/src/quic/core/quic_versions.h"
dschinazi52127d72019-04-17 15:12:38 -070012#include "net/third_party/quiche/src/quic/platform/api/quic_ip_address.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050013#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
dschinazi52127d72019-04-17 15:12:38 -070014#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
bnc4e9283d2019-12-17 07:08:57 -080015#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h"
dmcardle904ef182019-12-13 08:34:33 -080016#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050017
18namespace quic {
19namespace test {
dschinazi52127d72019-04-17 15:12:38 -070020namespace {
vasilvva2ef3012019-09-12 18:32:14 -070021
22using testing::Pair;
23using testing::UnorderedElementsAre;
24
dschinazi6c84c142019-07-31 09:11:49 -070025const ParsedQuicVersion kVersion(PROTOCOL_TLS1_3, QUIC_VERSION_99);
dschinazi52127d72019-04-17 15:12:38 -070026const QuicVersionLabel kFakeVersionLabel = 0x01234567;
27const QuicVersionLabel kFakeVersionLabel2 = 0x89ABCDEF;
dschinazi6cf4d2a2019-04-30 16:20:23 -070028const uint64_t kFakeIdleTimeoutMilliseconds = 12012;
dschinazi52127d72019-04-17 15:12:38 -070029const uint8_t kFakeStatelessResetTokenData[16] = {
30 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
31 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F};
dschinazi52127d72019-04-17 15:12:38 -070032const uint64_t kFakeMaxPacketSize = 9001;
33const uint64_t kFakeInitialMaxData = 101;
34const uint64_t kFakeInitialMaxStreamDataBidiLocal = 2001;
35const uint64_t kFakeInitialMaxStreamDataBidiRemote = 2002;
36const uint64_t kFakeInitialMaxStreamDataUni = 3000;
37const uint64_t kFakeInitialMaxStreamsBidi = 21;
38const uint64_t kFakeInitialMaxStreamsUni = 22;
39const uint64_t kFakeAckDelayExponent = 10;
40const uint64_t kFakeMaxAckDelay = 51;
41const bool kFakeDisableMigration = true;
dschinazie9db63c2019-07-17 16:19:42 -070042const uint64_t kFakeActiveConnectionIdLimit = 52;
dschinazi52127d72019-04-17 15:12:38 -070043const uint8_t kFakePreferredStatelessResetTokenData[16] = {
44 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
45 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F};
dschinazi423adc72019-10-23 09:58:55 -070046
vasilvva2ef3012019-09-12 18:32:14 -070047const auto kCustomParameter1 =
48 static_cast<TransportParameters::TransportParameterId>(0xffcd);
49const char* kCustomParameter1Value = "foo";
50const auto kCustomParameter2 =
51 static_cast<TransportParameters::TransportParameterId>(0xff34);
52const char* kCustomParameter2Value = "bar";
dschinazi52127d72019-04-17 15:12:38 -070053
dschinazi423adc72019-10-23 09:58:55 -070054QuicConnectionId CreateFakeOriginalConnectionId() {
55 return TestConnectionId(0x1337);
56}
57
58QuicConnectionId CreateFakePreferredConnectionId() {
59 return TestConnectionId(0xBEEF);
60}
61
62std::vector<uint8_t> CreateFakeStatelessResetToken() {
63 return std::vector<uint8_t>(
64 kFakeStatelessResetTokenData,
65 kFakeStatelessResetTokenData + sizeof(kFakeStatelessResetTokenData));
66}
67
68std::vector<uint8_t> CreateFakePreferredStatelessResetToken() {
69 return std::vector<uint8_t>(
70 kFakePreferredStatelessResetTokenData,
71 kFakePreferredStatelessResetTokenData +
72 sizeof(kFakePreferredStatelessResetTokenData));
73}
74
dschinazi3f0f6792019-04-18 11:39:54 -070075QuicSocketAddress CreateFakeV4SocketAddress() {
76 QuicIpAddress ipv4_address;
dschinazi3b5dc922019-05-01 20:58:30 -070077 if (!ipv4_address.FromString("65.66.67.68")) { // 0x41, 0x42, 0x43, 0x44
dschinazi3f0f6792019-04-18 11:39:54 -070078 QUIC_LOG(FATAL) << "Failed to create IPv4 address";
79 return QuicSocketAddress();
80 }
81 return QuicSocketAddress(ipv4_address, 0x4884);
82}
83
84QuicSocketAddress CreateFakeV6SocketAddress() {
85 QuicIpAddress ipv6_address;
86 if (!ipv6_address.FromString("6061:6263:6465:6667:6869:6A6B:6C6D:6E6F")) {
87 QUIC_LOG(FATAL) << "Failed to create IPv6 address";
88 return QuicSocketAddress();
89 }
90 return QuicSocketAddress(ipv6_address, 0x6336);
91}
92
dschinazi52127d72019-04-17 15:12:38 -070093std::unique_ptr<TransportParameters::PreferredAddress>
94CreateFakePreferredAddress() {
95 TransportParameters::PreferredAddress preferred_address;
dschinazi3f0f6792019-04-18 11:39:54 -070096 preferred_address.ipv4_socket_address = CreateFakeV4SocketAddress();
97 preferred_address.ipv6_socket_address = CreateFakeV6SocketAddress();
dschinazi423adc72019-10-23 09:58:55 -070098 preferred_address.connection_id = CreateFakePreferredConnectionId();
99 preferred_address.stateless_reset_token =
100 CreateFakePreferredStatelessResetToken();
vasilvv0fc587f2019-09-06 13:33:08 -0700101 return std::make_unique<TransportParameters::PreferredAddress>(
dschinazi52127d72019-04-17 15:12:38 -0700102 preferred_address);
103}
104
105} // namespace
QUICHE teama6ef0a62019-03-07 20:34:33 -0500106
107class TransportParametersTest : public QuicTest {};
108
109TEST_F(TransportParametersTest, RoundTripClient) {
110 TransportParameters orig_params;
111 orig_params.perspective = Perspective::IS_CLIENT;
dschinazi52127d72019-04-17 15:12:38 -0700112 orig_params.version = kFakeVersionLabel;
dschinazi6cf4d2a2019-04-30 16:20:23 -0700113 orig_params.idle_timeout_milliseconds.set_value(kFakeIdleTimeoutMilliseconds);
dschinazi52127d72019-04-17 15:12:38 -0700114 orig_params.max_packet_size.set_value(kFakeMaxPacketSize);
115 orig_params.initial_max_data.set_value(kFakeInitialMaxData);
116 orig_params.initial_max_stream_data_bidi_local.set_value(
117 kFakeInitialMaxStreamDataBidiLocal);
118 orig_params.initial_max_stream_data_bidi_remote.set_value(
119 kFakeInitialMaxStreamDataBidiRemote);
120 orig_params.initial_max_stream_data_uni.set_value(
121 kFakeInitialMaxStreamDataUni);
122 orig_params.initial_max_streams_bidi.set_value(kFakeInitialMaxStreamsBidi);
123 orig_params.initial_max_streams_uni.set_value(kFakeInitialMaxStreamsUni);
124 orig_params.ack_delay_exponent.set_value(kFakeAckDelayExponent);
125 orig_params.max_ack_delay.set_value(kFakeMaxAckDelay);
126 orig_params.disable_migration = kFakeDisableMigration;
dschinazie9db63c2019-07-17 16:19:42 -0700127 orig_params.active_connection_id_limit.set_value(
128 kFakeActiveConnectionIdLimit);
vasilvva2ef3012019-09-12 18:32:14 -0700129 orig_params.custom_parameters[kCustomParameter1] = kCustomParameter1Value;
130 orig_params.custom_parameters[kCustomParameter2] = kCustomParameter2Value;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500131
132 std::vector<uint8_t> serialized;
dschinazi6c84c142019-07-31 09:11:49 -0700133 ASSERT_TRUE(SerializeTransportParameters(kVersion, orig_params, &serialized));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500134
135 TransportParameters new_params;
dschinazi6c84c142019-07-31 09:11:49 -0700136 ASSERT_TRUE(ParseTransportParameters(kVersion, Perspective::IS_CLIENT,
137 serialized.data(), serialized.size(),
138 &new_params));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500139
dschinazi52127d72019-04-17 15:12:38 -0700140 EXPECT_EQ(Perspective::IS_CLIENT, new_params.perspective);
141 EXPECT_EQ(kFakeVersionLabel, new_params.version);
142 EXPECT_TRUE(new_params.supported_versions.empty());
143 EXPECT_EQ(EmptyQuicConnectionId(), new_params.original_connection_id);
dschinazi6cf4d2a2019-04-30 16:20:23 -0700144 EXPECT_EQ(kFakeIdleTimeoutMilliseconds,
145 new_params.idle_timeout_milliseconds.value());
dschinazi52127d72019-04-17 15:12:38 -0700146 EXPECT_TRUE(new_params.stateless_reset_token.empty());
147 EXPECT_EQ(kFakeMaxPacketSize, new_params.max_packet_size.value());
148 EXPECT_EQ(kFakeInitialMaxData, new_params.initial_max_data.value());
149 EXPECT_EQ(kFakeInitialMaxStreamDataBidiLocal,
150 new_params.initial_max_stream_data_bidi_local.value());
151 EXPECT_EQ(kFakeInitialMaxStreamDataBidiRemote,
152 new_params.initial_max_stream_data_bidi_remote.value());
153 EXPECT_EQ(kFakeInitialMaxStreamDataUni,
154 new_params.initial_max_stream_data_uni.value());
155 EXPECT_EQ(kFakeInitialMaxStreamsBidi,
156 new_params.initial_max_streams_bidi.value());
157 EXPECT_EQ(kFakeInitialMaxStreamsUni,
158 new_params.initial_max_streams_uni.value());
159 EXPECT_EQ(kFakeAckDelayExponent, new_params.ack_delay_exponent.value());
160 EXPECT_EQ(kFakeMaxAckDelay, new_params.max_ack_delay.value());
161 EXPECT_EQ(kFakeDisableMigration, new_params.disable_migration);
dschinazie9db63c2019-07-17 16:19:42 -0700162 EXPECT_EQ(kFakeActiveConnectionIdLimit,
163 new_params.active_connection_id_limit.value());
vasilvva2ef3012019-09-12 18:32:14 -0700164 EXPECT_THAT(
165 new_params.custom_parameters,
166 UnorderedElementsAre(Pair(kCustomParameter1, kCustomParameter1Value),
167 Pair(kCustomParameter2, kCustomParameter2Value)));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500168}
169
170TEST_F(TransportParametersTest, RoundTripServer) {
171 TransportParameters orig_params;
172 orig_params.perspective = Perspective::IS_SERVER;
dschinazi52127d72019-04-17 15:12:38 -0700173 orig_params.version = kFakeVersionLabel;
174 orig_params.supported_versions.push_back(kFakeVersionLabel);
175 orig_params.supported_versions.push_back(kFakeVersionLabel2);
dschinazi423adc72019-10-23 09:58:55 -0700176 orig_params.original_connection_id = CreateFakeOriginalConnectionId();
dschinazi6cf4d2a2019-04-30 16:20:23 -0700177 orig_params.idle_timeout_milliseconds.set_value(kFakeIdleTimeoutMilliseconds);
dschinazi423adc72019-10-23 09:58:55 -0700178 orig_params.stateless_reset_token = CreateFakeStatelessResetToken();
dschinazi52127d72019-04-17 15:12:38 -0700179 orig_params.max_packet_size.set_value(kFakeMaxPacketSize);
180 orig_params.initial_max_data.set_value(kFakeInitialMaxData);
181 orig_params.initial_max_stream_data_bidi_local.set_value(
182 kFakeInitialMaxStreamDataBidiLocal);
183 orig_params.initial_max_stream_data_bidi_remote.set_value(
184 kFakeInitialMaxStreamDataBidiRemote);
185 orig_params.initial_max_stream_data_uni.set_value(
186 kFakeInitialMaxStreamDataUni);
187 orig_params.initial_max_streams_bidi.set_value(kFakeInitialMaxStreamsBidi);
188 orig_params.initial_max_streams_uni.set_value(kFakeInitialMaxStreamsUni);
189 orig_params.ack_delay_exponent.set_value(kFakeAckDelayExponent);
190 orig_params.max_ack_delay.set_value(kFakeMaxAckDelay);
191 orig_params.disable_migration = kFakeDisableMigration;
192 orig_params.preferred_address = CreateFakePreferredAddress();
dschinazie9db63c2019-07-17 16:19:42 -0700193 orig_params.active_connection_id_limit.set_value(
194 kFakeActiveConnectionIdLimit);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500195
196 std::vector<uint8_t> serialized;
dschinazi6c84c142019-07-31 09:11:49 -0700197 ASSERT_TRUE(SerializeTransportParameters(kVersion, orig_params, &serialized));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500198
199 TransportParameters new_params;
dschinazi6c84c142019-07-31 09:11:49 -0700200 ASSERT_TRUE(ParseTransportParameters(kVersion, Perspective::IS_SERVER,
201 serialized.data(), serialized.size(),
202 &new_params));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500203
dschinazi52127d72019-04-17 15:12:38 -0700204 EXPECT_EQ(Perspective::IS_SERVER, new_params.perspective);
205 EXPECT_EQ(kFakeVersionLabel, new_params.version);
fkastenholzd3cb19f2019-04-18 06:54:06 -0700206 EXPECT_EQ(2u, new_params.supported_versions.size());
dschinazi52127d72019-04-17 15:12:38 -0700207 EXPECT_EQ(kFakeVersionLabel, new_params.supported_versions[0]);
208 EXPECT_EQ(kFakeVersionLabel2, new_params.supported_versions[1]);
dschinazi423adc72019-10-23 09:58:55 -0700209 EXPECT_EQ(CreateFakeOriginalConnectionId(),
210 new_params.original_connection_id);
dschinazi6cf4d2a2019-04-30 16:20:23 -0700211 EXPECT_EQ(kFakeIdleTimeoutMilliseconds,
212 new_params.idle_timeout_milliseconds.value());
dschinazi423adc72019-10-23 09:58:55 -0700213 EXPECT_EQ(CreateFakeStatelessResetToken(), new_params.stateless_reset_token);
dschinazi52127d72019-04-17 15:12:38 -0700214 EXPECT_EQ(kFakeMaxPacketSize, new_params.max_packet_size.value());
215 EXPECT_EQ(kFakeInitialMaxData, new_params.initial_max_data.value());
216 EXPECT_EQ(kFakeInitialMaxStreamDataBidiLocal,
217 new_params.initial_max_stream_data_bidi_local.value());
218 EXPECT_EQ(kFakeInitialMaxStreamDataBidiRemote,
219 new_params.initial_max_stream_data_bidi_remote.value());
220 EXPECT_EQ(kFakeInitialMaxStreamDataUni,
221 new_params.initial_max_stream_data_uni.value());
222 EXPECT_EQ(kFakeInitialMaxStreamsBidi,
223 new_params.initial_max_streams_bidi.value());
224 EXPECT_EQ(kFakeInitialMaxStreamsUni,
225 new_params.initial_max_streams_uni.value());
226 EXPECT_EQ(kFakeAckDelayExponent, new_params.ack_delay_exponent.value());
227 EXPECT_EQ(kFakeMaxAckDelay, new_params.max_ack_delay.value());
228 EXPECT_EQ(kFakeDisableMigration, new_params.disable_migration);
229 ASSERT_NE(nullptr, new_params.preferred_address.get());
dschinazi3f0f6792019-04-18 11:39:54 -0700230 EXPECT_EQ(CreateFakeV4SocketAddress(),
dschinazi52127d72019-04-17 15:12:38 -0700231 new_params.preferred_address->ipv4_socket_address);
dschinazi3f0f6792019-04-18 11:39:54 -0700232 EXPECT_EQ(CreateFakeV6SocketAddress(),
dschinazi52127d72019-04-17 15:12:38 -0700233 new_params.preferred_address->ipv6_socket_address);
dschinazi423adc72019-10-23 09:58:55 -0700234 EXPECT_EQ(CreateFakePreferredConnectionId(),
dschinazi52127d72019-04-17 15:12:38 -0700235 new_params.preferred_address->connection_id);
dschinazi423adc72019-10-23 09:58:55 -0700236 EXPECT_EQ(CreateFakePreferredStatelessResetToken(),
dschinazi52127d72019-04-17 15:12:38 -0700237 new_params.preferred_address->stateless_reset_token);
dschinazie9db63c2019-07-17 16:19:42 -0700238 EXPECT_EQ(kFakeActiveConnectionIdLimit,
239 new_params.active_connection_id_limit.value());
vasilvva2ef3012019-09-12 18:32:14 -0700240 EXPECT_EQ(0u, new_params.custom_parameters.size());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500241}
242
243TEST_F(TransportParametersTest, IsValid) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500244 {
245 TransportParameters params;
246 params.perspective = Perspective::IS_CLIENT;
dschinazi52127d72019-04-17 15:12:38 -0700247 EXPECT_TRUE(params.AreValid());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500248 }
249 {
250 TransportParameters params;
251 params.perspective = Perspective::IS_CLIENT;
dschinazi52127d72019-04-17 15:12:38 -0700252 EXPECT_TRUE(params.AreValid());
dschinazi6cf4d2a2019-04-30 16:20:23 -0700253 params.idle_timeout_milliseconds.set_value(kFakeIdleTimeoutMilliseconds);
254 EXPECT_TRUE(params.AreValid());
255 params.idle_timeout_milliseconds.set_value(601000);
dschinazi52127d72019-04-17 15:12:38 -0700256 EXPECT_TRUE(params.AreValid());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500257 }
258 {
259 TransportParameters params;
260 params.perspective = Perspective::IS_CLIENT;
dschinazi52127d72019-04-17 15:12:38 -0700261 EXPECT_TRUE(params.AreValid());
262 params.max_packet_size.set_value(0);
263 EXPECT_FALSE(params.AreValid());
264 params.max_packet_size.set_value(1199);
265 EXPECT_FALSE(params.AreValid());
266 params.max_packet_size.set_value(1200);
267 EXPECT_TRUE(params.AreValid());
268 params.max_packet_size.set_value(65535);
269 EXPECT_TRUE(params.AreValid());
270 params.max_packet_size.set_value(9999999);
271 EXPECT_TRUE(params.AreValid());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500272 }
dschinazi52127d72019-04-17 15:12:38 -0700273 {
274 TransportParameters params;
275 params.perspective = Perspective::IS_CLIENT;
276 EXPECT_TRUE(params.AreValid());
277 params.ack_delay_exponent.set_value(0);
278 EXPECT_TRUE(params.AreValid());
279 params.ack_delay_exponent.set_value(20);
280 EXPECT_TRUE(params.AreValid());
281 params.ack_delay_exponent.set_value(21);
282 EXPECT_FALSE(params.AreValid());
283 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500284}
285
286TEST_F(TransportParametersTest, NoClientParamsWithStatelessResetToken) {
287 TransportParameters orig_params;
288 orig_params.perspective = Perspective::IS_CLIENT;
dschinazi52127d72019-04-17 15:12:38 -0700289 orig_params.version = kFakeVersionLabel;
dschinazi6cf4d2a2019-04-30 16:20:23 -0700290 orig_params.idle_timeout_milliseconds.set_value(kFakeIdleTimeoutMilliseconds);
dschinazi423adc72019-10-23 09:58:55 -0700291 orig_params.stateless_reset_token = CreateFakeStatelessResetToken();
dschinazi52127d72019-04-17 15:12:38 -0700292 orig_params.max_packet_size.set_value(kFakeMaxPacketSize);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500293
294 std::vector<uint8_t> out;
dschinazi6c84c142019-07-31 09:11:49 -0700295 EXPECT_FALSE(SerializeTransportParameters(kVersion, orig_params, &out));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500296}
297
298TEST_F(TransportParametersTest, ParseClientParams) {
dschinazi52127d72019-04-17 15:12:38 -0700299 // clang-format off
QUICHE teama6ef0a62019-03-07 20:34:33 -0500300 const uint8_t kClientParams[] = {
dschinazie9db63c2019-07-17 16:19:42 -0700301 0x00, 0x49, // length of the parameters array that follows
dschinazi6cf4d2a2019-04-30 16:20:23 -0700302 // idle_timeout
dschinazi52127d72019-04-17 15:12:38 -0700303 0x00, 0x01, // parameter id
dschinazi6cf4d2a2019-04-30 16:20:23 -0700304 0x00, 0x02, // length
305 0x6e, 0xec, // value
dschinazi52127d72019-04-17 15:12:38 -0700306 // max_packet_size
QUICHE teama6ef0a62019-03-07 20:34:33 -0500307 0x00, 0x03, // parameter id
308 0x00, 0x02, // length
dschinazi52127d72019-04-17 15:12:38 -0700309 0x63, 0x29, // value
310 // initial_max_data
311 0x00, 0x04, // parameter id
312 0x00, 0x02, // length
313 0x40, 0x65, // value
314 // initial_max_stream_data_bidi_local
315 0x00, 0x05, // parameter id
316 0x00, 0x02, // length
317 0x47, 0xD1, // value
318 // initial_max_stream_data_bidi_remote
319 0x00, 0x06, // parameter id
320 0x00, 0x02, // length
321 0x47, 0xD2, // value
322 // initial_max_stream_data_uni
323 0x00, 0x07, // parameter id
324 0x00, 0x02, // length
325 0x4B, 0xB8, // value
326 // initial_max_streams_bidi
327 0x00, 0x08, // parameter id
328 0x00, 0x01, // length
329 0x15, // value
330 // initial_max_streams_uni
331 0x00, 0x09, // parameter id
332 0x00, 0x01, // length
333 0x16, // value
334 // ack_delay_exponent
335 0x00, 0x0a, // parameter id
336 0x00, 0x01, // length
337 0x0a, // value
338 // max_ack_delay
339 0x00, 0x0b, // parameter id
340 0x00, 0x01, // length
341 0x33, // value
342 // disable_migration
343 0x00, 0x0c, // parameter id
344 0x00, 0x00, // length
dschinazie9db63c2019-07-17 16:19:42 -0700345 // active_connection_id_limit
346 0x00, 0x0e, // parameter id
347 0x00, 0x01, // length
348 0x34, // value
dschinazi6cf4d2a2019-04-30 16:20:23 -0700349 // Google version extension
350 0x47, 0x52, // parameter id
351 0x00, 0x04, // length
352 0x01, 0x23, 0x45, 0x67, // initial version
QUICHE teama6ef0a62019-03-07 20:34:33 -0500353 };
dschinazi52127d72019-04-17 15:12:38 -0700354 // clang-format on
QUICHE teama6ef0a62019-03-07 20:34:33 -0500355
dschinazi52127d72019-04-17 15:12:38 -0700356 TransportParameters new_params;
dschinazi6c84c142019-07-31 09:11:49 -0700357 ASSERT_TRUE(
358 ParseTransportParameters(kVersion, Perspective::IS_CLIENT, kClientParams,
bnc4e9283d2019-12-17 07:08:57 -0800359 QUICHE_ARRAYSIZE(kClientParams), &new_params));
dschinazi52127d72019-04-17 15:12:38 -0700360
361 EXPECT_EQ(Perspective::IS_CLIENT, new_params.perspective);
362 EXPECT_EQ(kFakeVersionLabel, new_params.version);
363 EXPECT_TRUE(new_params.supported_versions.empty());
364 EXPECT_EQ(EmptyQuicConnectionId(), new_params.original_connection_id);
dschinazi6cf4d2a2019-04-30 16:20:23 -0700365 EXPECT_EQ(kFakeIdleTimeoutMilliseconds,
366 new_params.idle_timeout_milliseconds.value());
dschinazi52127d72019-04-17 15:12:38 -0700367 EXPECT_TRUE(new_params.stateless_reset_token.empty());
368 EXPECT_EQ(kFakeMaxPacketSize, new_params.max_packet_size.value());
369 EXPECT_EQ(kFakeInitialMaxData, new_params.initial_max_data.value());
370 EXPECT_EQ(kFakeInitialMaxStreamDataBidiLocal,
371 new_params.initial_max_stream_data_bidi_local.value());
372 EXPECT_EQ(kFakeInitialMaxStreamDataBidiRemote,
373 new_params.initial_max_stream_data_bidi_remote.value());
374 EXPECT_EQ(kFakeInitialMaxStreamDataUni,
375 new_params.initial_max_stream_data_uni.value());
376 EXPECT_EQ(kFakeInitialMaxStreamsBidi,
377 new_params.initial_max_streams_bidi.value());
378 EXPECT_EQ(kFakeInitialMaxStreamsUni,
379 new_params.initial_max_streams_uni.value());
380 EXPECT_EQ(kFakeAckDelayExponent, new_params.ack_delay_exponent.value());
381 EXPECT_EQ(kFakeMaxAckDelay, new_params.max_ack_delay.value());
382 EXPECT_EQ(kFakeDisableMigration, new_params.disable_migration);
dschinazie9db63c2019-07-17 16:19:42 -0700383 EXPECT_EQ(kFakeActiveConnectionIdLimit,
384 new_params.active_connection_id_limit.value());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500385}
386
387TEST_F(TransportParametersTest, ParseClientParamsFailsWithStatelessResetToken) {
388 TransportParameters out_params;
389
390 // clang-format off
391 const uint8_t kClientParamsWithFullToken[] = {
dschinazi6cf4d2a2019-04-30 16:20:23 -0700392 0x00, 0x26, // length parameters array that follows
393 // idle_timeout
dschinazi52127d72019-04-17 15:12:38 -0700394 0x00, 0x01, // parameter id
dschinazi6cf4d2a2019-04-30 16:20:23 -0700395 0x00, 0x02, // length
396 0x6e, 0xec, // value
dschinazi52127d72019-04-17 15:12:38 -0700397 // stateless_reset_token
398 0x00, 0x02,
399 0x00, 0x10,
400 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
401 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
402 // max_packet_size
QUICHE teama6ef0a62019-03-07 20:34:33 -0500403 0x00, 0x03, // parameter id
404 0x00, 0x02, // length
dschinazi52127d72019-04-17 15:12:38 -0700405 0x63, 0x29, // value
406 // initial_max_data
407 0x00, 0x04, // parameter id
408 0x00, 0x02, // length
409 0x40, 0x65, // value
QUICHE teama6ef0a62019-03-07 20:34:33 -0500410 };
411 // clang-format on
412
dschinazi52127d72019-04-17 15:12:38 -0700413 EXPECT_FALSE(ParseTransportParameters(
dschinazi6c84c142019-07-31 09:11:49 -0700414 kVersion, Perspective::IS_CLIENT, kClientParamsWithFullToken,
bnc4e9283d2019-12-17 07:08:57 -0800415 QUICHE_ARRAYSIZE(kClientParamsWithFullToken), &out_params));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500416
dschinazi52127d72019-04-17 15:12:38 -0700417 // clang-format off
QUICHE teama6ef0a62019-03-07 20:34:33 -0500418 const uint8_t kClientParamsWithEmptyToken[] = {
dschinazi6cf4d2a2019-04-30 16:20:23 -0700419 0x00, 0x16, // length parameters array that follows
420 // idle_timeout
dschinazi52127d72019-04-17 15:12:38 -0700421 0x00, 0x01, // parameter id
dschinazi6cf4d2a2019-04-30 16:20:23 -0700422 0x00, 0x02, // length
423 0x6e, 0xec, // value
dschinazi52127d72019-04-17 15:12:38 -0700424 // stateless_reset_token
425 0x00, 0x02,
426 0x00, 0x00,
427 // max_packet_size
QUICHE teama6ef0a62019-03-07 20:34:33 -0500428 0x00, 0x03, // parameter id
429 0x00, 0x02, // length
dschinazi52127d72019-04-17 15:12:38 -0700430 0x63, 0x29, // value
431 // initial_max_data
432 0x00, 0x04, // parameter id
433 0x00, 0x02, // length
434 0x40, 0x65, // value
QUICHE teama6ef0a62019-03-07 20:34:33 -0500435 };
dschinazi52127d72019-04-17 15:12:38 -0700436 // clang-format on
QUICHE teama6ef0a62019-03-07 20:34:33 -0500437
dschinazi52127d72019-04-17 15:12:38 -0700438 EXPECT_FALSE(ParseTransportParameters(
dschinazi6c84c142019-07-31 09:11:49 -0700439 kVersion, Perspective::IS_CLIENT, kClientParamsWithEmptyToken,
bnc4e9283d2019-12-17 07:08:57 -0800440 QUICHE_ARRAYSIZE(kClientParamsWithEmptyToken), &out_params));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500441}
442
dschinazi52127d72019-04-17 15:12:38 -0700443TEST_F(TransportParametersTest, ParseClientParametersRepeated) {
444 // clang-format off
QUICHE teama6ef0a62019-03-07 20:34:33 -0500445 const uint8_t kClientParamsRepeated[] = {
dschinazi6cf4d2a2019-04-30 16:20:23 -0700446 0x00, 0x16, // length parameters array that follows
447 // idle_timeout
dschinazi52127d72019-04-17 15:12:38 -0700448 0x00, 0x01, // parameter id
dschinazi6cf4d2a2019-04-30 16:20:23 -0700449 0x00, 0x02, // length
450 0x6e, 0xec, // value
dschinazi52127d72019-04-17 15:12:38 -0700451 // stateless_reset_token
452 0x00, 0x02,
453 0x00, 0x00,
454 // max_packet_size
QUICHE teama6ef0a62019-03-07 20:34:33 -0500455 0x00, 0x03, // parameter id
456 0x00, 0x02, // length
dschinazi52127d72019-04-17 15:12:38 -0700457 0x63, 0x29, // value
dschinazi6cf4d2a2019-04-30 16:20:23 -0700458 // idle_timeout (repeated)
dschinazi52127d72019-04-17 15:12:38 -0700459 0x00, 0x01, // parameter id
dschinazi6cf4d2a2019-04-30 16:20:23 -0700460 0x00, 0x02, // length
461 0x6e, 0xec, // value
QUICHE teama6ef0a62019-03-07 20:34:33 -0500462 };
dschinazi52127d72019-04-17 15:12:38 -0700463 // clang-format on
464 TransportParameters out_params;
dschinazi6c84c142019-07-31 09:11:49 -0700465 EXPECT_FALSE(ParseTransportParameters(
466 kVersion, Perspective::IS_CLIENT, kClientParamsRepeated,
bnc4e9283d2019-12-17 07:08:57 -0800467 QUICHE_ARRAYSIZE(kClientParamsRepeated), &out_params));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500468}
469
470TEST_F(TransportParametersTest, ParseServerParams) {
471 // clang-format off
472 const uint8_t kServerParams[] = {
dschinazie9db63c2019-07-17 16:19:42 -0700473 0x00, 0xa7, // length of parameters array that follows
dschinazi52127d72019-04-17 15:12:38 -0700474 // original_connection_id
475 0x00, 0x00, // parameter id
476 0x00, 0x08, // length
477 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x37,
dschinazi6cf4d2a2019-04-30 16:20:23 -0700478 // idle_timeout
dschinazi52127d72019-04-17 15:12:38 -0700479 0x00, 0x01, // parameter id
dschinazi6cf4d2a2019-04-30 16:20:23 -0700480 0x00, 0x02, // length
481 0x6e, 0xec, // value
QUICHE teama6ef0a62019-03-07 20:34:33 -0500482 // stateless_reset_token
dschinazi52127d72019-04-17 15:12:38 -0700483 0x00, 0x02,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500484 0x00, 0x10,
dschinazi52127d72019-04-17 15:12:38 -0700485 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
486 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
487 // max_packet_size
488 0x00, 0x03, // parameter id
489 0x00, 0x02, // length
490 0x63, 0x29, // value
491 // initial_max_data
492 0x00, 0x04, // parameter id
493 0x00, 0x02, // length
494 0x40, 0x65, // value
495 // initial_max_stream_data_bidi_local
496 0x00, 0x05, // parameter id
497 0x00, 0x02, // length
498 0x47, 0xD1, // value
499 // initial_max_stream_data_bidi_remote
500 0x00, 0x06, // parameter id
501 0x00, 0x02, // length
502 0x47, 0xD2, // value
503 // initial_max_stream_data_uni
504 0x00, 0x07, // parameter id
505 0x00, 0x02, // length
506 0x4B, 0xB8, // value
507 // initial_max_streams_bidi
508 0x00, 0x08, // parameter id
509 0x00, 0x01, // length
510 0x15, // value
511 // initial_max_streams_uni
512 0x00, 0x09, // parameter id
513 0x00, 0x01, // length
514 0x16, // value
515 // ack_delay_exponent
516 0x00, 0x0a, // parameter id
517 0x00, 0x01, // length
518 0x0a, // value
519 // max_ack_delay
520 0x00, 0x0b, // parameter id
521 0x00, 0x01, // length
522 0x33, // value
523 // disable_migration
524 0x00, 0x0c, // parameter id
525 0x00, 0x00, // length
526 // preferred_address
527 0x00, 0x0d, // parameter id
dschinazi3b5dc922019-05-01 20:58:30 -0700528 0x00, 0x31, // length
dschinazi52127d72019-04-17 15:12:38 -0700529 0x41, 0x42, 0x43, 0x44, // IPv4 address
530 0x48, 0x84, // IPv4 port
531 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, // IPv6 address
532 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
533 0x63, 0x36, // IPv6 port
dschinazi3b5dc922019-05-01 20:58:30 -0700534 0x08, // connection ID length
dschinazi52127d72019-04-17 15:12:38 -0700535 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBE, 0xEF, // connection ID
536 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, // stateless reset token
537 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
dschinazie9db63c2019-07-17 16:19:42 -0700538 // active_connection_id_limit
539 0x00, 0x0e, // parameter id
540 0x00, 0x01, // length
541 0x34, // value
dschinazi6cf4d2a2019-04-30 16:20:23 -0700542 // Google version extension
543 0x47, 0x52, // parameter id
544 0x00, 0x0d, // length
545 0x01, 0x23, 0x45, 0x67, // negotiated_version
546 0x08, // length of supported versions array
547 0x01, 0x23, 0x45, 0x67,
548 0x89, 0xab, 0xcd, 0xef,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500549 };
550 // clang-format on
551
dschinazi52127d72019-04-17 15:12:38 -0700552 TransportParameters new_params;
dschinazi6c84c142019-07-31 09:11:49 -0700553 ASSERT_TRUE(
554 ParseTransportParameters(kVersion, Perspective::IS_SERVER, kServerParams,
bnc4e9283d2019-12-17 07:08:57 -0800555 QUICHE_ARRAYSIZE(kServerParams), &new_params));
dschinazi52127d72019-04-17 15:12:38 -0700556
557 EXPECT_EQ(Perspective::IS_SERVER, new_params.perspective);
558 EXPECT_EQ(kFakeVersionLabel, new_params.version);
fkastenholz881af2b2019-04-18 07:21:01 -0700559 EXPECT_EQ(2u, new_params.supported_versions.size());
dschinazi52127d72019-04-17 15:12:38 -0700560 EXPECT_EQ(kFakeVersionLabel, new_params.supported_versions[0]);
561 EXPECT_EQ(kFakeVersionLabel2, new_params.supported_versions[1]);
dschinazi423adc72019-10-23 09:58:55 -0700562 EXPECT_EQ(CreateFakeOriginalConnectionId(),
563 new_params.original_connection_id);
dschinazi6cf4d2a2019-04-30 16:20:23 -0700564 EXPECT_EQ(kFakeIdleTimeoutMilliseconds,
565 new_params.idle_timeout_milliseconds.value());
dschinazi423adc72019-10-23 09:58:55 -0700566 EXPECT_EQ(CreateFakeStatelessResetToken(), new_params.stateless_reset_token);
dschinazi52127d72019-04-17 15:12:38 -0700567 EXPECT_EQ(kFakeMaxPacketSize, new_params.max_packet_size.value());
568 EXPECT_EQ(kFakeInitialMaxData, new_params.initial_max_data.value());
569 EXPECT_EQ(kFakeInitialMaxStreamDataBidiLocal,
570 new_params.initial_max_stream_data_bidi_local.value());
571 EXPECT_EQ(kFakeInitialMaxStreamDataBidiRemote,
572 new_params.initial_max_stream_data_bidi_remote.value());
573 EXPECT_EQ(kFakeInitialMaxStreamDataUni,
574 new_params.initial_max_stream_data_uni.value());
575 EXPECT_EQ(kFakeInitialMaxStreamsBidi,
576 new_params.initial_max_streams_bidi.value());
577 EXPECT_EQ(kFakeInitialMaxStreamsUni,
578 new_params.initial_max_streams_uni.value());
579 EXPECT_EQ(kFakeAckDelayExponent, new_params.ack_delay_exponent.value());
580 EXPECT_EQ(kFakeMaxAckDelay, new_params.max_ack_delay.value());
581 EXPECT_EQ(kFakeDisableMigration, new_params.disable_migration);
582 ASSERT_NE(nullptr, new_params.preferred_address.get());
dschinazi3f0f6792019-04-18 11:39:54 -0700583 EXPECT_EQ(CreateFakeV4SocketAddress(),
dschinazi52127d72019-04-17 15:12:38 -0700584 new_params.preferred_address->ipv4_socket_address);
dschinazi3f0f6792019-04-18 11:39:54 -0700585 EXPECT_EQ(CreateFakeV6SocketAddress(),
dschinazi52127d72019-04-17 15:12:38 -0700586 new_params.preferred_address->ipv6_socket_address);
dschinazi423adc72019-10-23 09:58:55 -0700587 EXPECT_EQ(CreateFakePreferredConnectionId(),
dschinazi52127d72019-04-17 15:12:38 -0700588 new_params.preferred_address->connection_id);
dschinazi423adc72019-10-23 09:58:55 -0700589 EXPECT_EQ(CreateFakePreferredStatelessResetToken(),
dschinazi52127d72019-04-17 15:12:38 -0700590 new_params.preferred_address->stateless_reset_token);
dschinazie9db63c2019-07-17 16:19:42 -0700591 EXPECT_EQ(kFakeActiveConnectionIdLimit,
592 new_params.active_connection_id_limit.value());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500593}
594
dschinazi52127d72019-04-17 15:12:38 -0700595TEST_F(TransportParametersTest, ParseServerParametersRepeated) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500596 // clang-format off
597 const uint8_t kServerParamsRepeated[] = {
dschinazi6cf4d2a2019-04-30 16:20:23 -0700598 0x00, 0x2c, // length of parameters array that follows
dschinazi52127d72019-04-17 15:12:38 -0700599 // original_connection_id
600 0x00, 0x00, // parameter id
601 0x00, 0x08, // length
602 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x37,
dschinazi6cf4d2a2019-04-30 16:20:23 -0700603 // idle_timeout
dschinazi52127d72019-04-17 15:12:38 -0700604 0x00, 0x01, // parameter id
dschinazi6cf4d2a2019-04-30 16:20:23 -0700605 0x00, 0x02, // length
606 0x6e, 0xec, // value
QUICHE teama6ef0a62019-03-07 20:34:33 -0500607 // stateless_reset_token
dschinazi52127d72019-04-17 15:12:38 -0700608 0x00, 0x02,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500609 0x00, 0x10,
dschinazi52127d72019-04-17 15:12:38 -0700610 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
611 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
dschinazi6cf4d2a2019-04-30 16:20:23 -0700612 // idle_timeout (repeated)
dschinazi52127d72019-04-17 15:12:38 -0700613 0x00, 0x01, // parameter id
dschinazi6cf4d2a2019-04-30 16:20:23 -0700614 0x00, 0x02, // length
615 0x6e, 0xec, // value
QUICHE teama6ef0a62019-03-07 20:34:33 -0500616 };
617 // clang-format on
QUICHE teama6ef0a62019-03-07 20:34:33 -0500618
dschinazi52127d72019-04-17 15:12:38 -0700619 TransportParameters out_params;
dschinazi6c84c142019-07-31 09:11:49 -0700620 EXPECT_FALSE(ParseTransportParameters(
621 kVersion, Perspective::IS_SERVER, kServerParamsRepeated,
bnc4e9283d2019-12-17 07:08:57 -0800622 QUICHE_ARRAYSIZE(kServerParamsRepeated), &out_params));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500623}
624
625TEST_F(TransportParametersTest, CryptoHandshakeMessageRoundtrip) {
626 TransportParameters orig_params;
627 orig_params.perspective = Perspective::IS_CLIENT;
dschinazi6cf4d2a2019-04-30 16:20:23 -0700628 orig_params.version = kFakeVersionLabel;
dschinazi52127d72019-04-17 15:12:38 -0700629 orig_params.max_packet_size.set_value(kFakeMaxPacketSize);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500630
vasilvv0fc587f2019-09-06 13:33:08 -0700631 orig_params.google_quic_params = std::make_unique<CryptoHandshakeMessage>();
vasilvvc48c8712019-03-11 13:38:16 -0700632 const std::string kTestString = "test string";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500633 orig_params.google_quic_params->SetStringPiece(42, kTestString);
634 const uint32_t kTestValue = 12;
635 orig_params.google_quic_params->SetValue(1337, kTestValue);
636
637 std::vector<uint8_t> serialized;
dschinazi6c84c142019-07-31 09:11:49 -0700638 ASSERT_TRUE(SerializeTransportParameters(kVersion, orig_params, &serialized));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500639
640 TransportParameters new_params;
dschinazi6c84c142019-07-31 09:11:49 -0700641 ASSERT_TRUE(ParseTransportParameters(kVersion, Perspective::IS_CLIENT,
642 serialized.data(), serialized.size(),
643 &new_params));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500644
645 ASSERT_NE(new_params.google_quic_params.get(), nullptr);
646 EXPECT_EQ(new_params.google_quic_params->tag(),
647 orig_params.google_quic_params->tag());
dmcardle904ef182019-12-13 08:34:33 -0800648 quiche::QuicheStringPiece test_string;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500649 EXPECT_TRUE(new_params.google_quic_params->GetStringPiece(42, &test_string));
650 EXPECT_EQ(test_string, kTestString);
651 uint32_t test_value;
bnc162322c2019-12-05 10:30:04 -0800652 EXPECT_THAT(new_params.google_quic_params->GetUint32(1337, &test_value),
653 IsQuicNoError());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500654 EXPECT_EQ(test_value, kTestValue);
dschinazi6cf4d2a2019-04-30 16:20:23 -0700655 EXPECT_EQ(kFakeVersionLabel, new_params.version);
dschinazi52127d72019-04-17 15:12:38 -0700656 EXPECT_EQ(kFakeMaxPacketSize, new_params.max_packet_size.value());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500657}
658
659} // namespace test
660} // namespace quic