blob: 84e89c17d2d3ceb0b19d7639bb635655bf2f0994 [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// Copyright (c) 2013 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_config.h"
6
vasilvv872e7a32019-03-12 16:42:44 -07007#include <string>
8
QUICHE teama6ef0a62019-03-07 20:34:33 -05009#include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message.h"
10#include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h"
11#include "net/third_party/quiche/src/quic/core/quic_packets.h"
12#include "net/third_party/quiche/src/quic/core/quic_time.h"
13#include "net/third_party/quiche/src/quic/core/quic_utils.h"
14#include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050015#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
16#include "net/third_party/quiche/src/quic/platform/api/quic_uint128.h"
17#include "net/third_party/quiche/src/quic/test_tools/quic_config_peer.h"
18#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
19
20namespace quic {
21namespace test {
22namespace {
23
fkastenholzd3a1de92019-05-15 07:00:07 -070024class QuicConfigTest : public QuicTestWithParam<QuicTransportVersion> {
QUICHE teama6ef0a62019-03-07 20:34:33 -050025 protected:
26 QuicConfig config_;
27};
28
fkastenholzd3a1de92019-05-15 07:00:07 -070029// Run all tests with all versions of QUIC.
30INSTANTIATE_TEST_SUITE_P(QuicConfigTests,
31 QuicConfigTest,
32 ::testing::ValuesIn(AllSupportedTransportVersions()));
33
34TEST_P(QuicConfigTest, ToHandshakeMessage) {
QUICHE teama6ef0a62019-03-07 20:34:33 -050035 config_.SetInitialStreamFlowControlWindowToSend(
36 kInitialStreamFlowControlWindowForTest);
37 config_.SetInitialSessionFlowControlWindowToSend(
38 kInitialSessionFlowControlWindowForTest);
39 config_.SetIdleNetworkTimeout(QuicTime::Delta::FromSeconds(5),
40 QuicTime::Delta::FromSeconds(2));
41 CryptoHandshakeMessage msg;
fkastenholzd3a1de92019-05-15 07:00:07 -070042 config_.ToHandshakeMessage(&msg, GetParam());
QUICHE teama6ef0a62019-03-07 20:34:33 -050043
44 uint32_t value;
45 QuicErrorCode error = msg.GetUint32(kICSL, &value);
46 EXPECT_EQ(QUIC_NO_ERROR, error);
47 EXPECT_EQ(5u, value);
48
49 error = msg.GetUint32(kSFCW, &value);
50 EXPECT_EQ(QUIC_NO_ERROR, error);
51 EXPECT_EQ(kInitialStreamFlowControlWindowForTest, value);
52
53 error = msg.GetUint32(kCFCW, &value);
54 EXPECT_EQ(QUIC_NO_ERROR, error);
55 EXPECT_EQ(kInitialSessionFlowControlWindowForTest, value);
56}
57
fkastenholzd3a1de92019-05-15 07:00:07 -070058TEST_P(QuicConfigTest, ProcessClientHello) {
QUICHE teama6ef0a62019-03-07 20:34:33 -050059 QuicConfig client_config;
60 QuicTagVector cgst;
61 cgst.push_back(kQBIC);
62 client_config.SetIdleNetworkTimeout(
63 QuicTime::Delta::FromSeconds(2 * kMaximumIdleTimeoutSecs),
64 QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs));
65 client_config.SetInitialRoundTripTimeUsToSend(10 * kNumMicrosPerMilli);
66 client_config.SetInitialStreamFlowControlWindowToSend(
67 2 * kInitialStreamFlowControlWindowForTest);
68 client_config.SetInitialSessionFlowControlWindowToSend(
69 2 * kInitialSessionFlowControlWindowForTest);
70 QuicTagVector copt;
71 copt.push_back(kTBBR);
72 client_config.SetConnectionOptionsToSend(copt);
73 CryptoHandshakeMessage msg;
fkastenholzd3a1de92019-05-15 07:00:07 -070074 client_config.ToHandshakeMessage(&msg, GetParam());
QUICHE teama6ef0a62019-03-07 20:34:33 -050075
vasilvvc48c8712019-03-11 13:38:16 -070076 std::string error_details;
QUICHE teama6ef0a62019-03-07 20:34:33 -050077 QuicTagVector initial_received_options;
78 initial_received_options.push_back(kIW50);
79 EXPECT_TRUE(
80 config_.SetInitialReceivedConnectionOptions(initial_received_options));
81 EXPECT_FALSE(
82 config_.SetInitialReceivedConnectionOptions(initial_received_options))
83 << "You can only set initial options once.";
84 const QuicErrorCode error =
85 config_.ProcessPeerHello(msg, CLIENT, &error_details);
86 EXPECT_FALSE(
87 config_.SetInitialReceivedConnectionOptions(initial_received_options))
88 << "You cannot set initial options after the hello.";
89 EXPECT_EQ(QUIC_NO_ERROR, error);
90 EXPECT_TRUE(config_.negotiated());
91 EXPECT_EQ(QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs),
92 config_.IdleNetworkTimeout());
93 EXPECT_EQ(10 * kNumMicrosPerMilli, config_.ReceivedInitialRoundTripTimeUs());
94 EXPECT_TRUE(config_.HasReceivedConnectionOptions());
95 EXPECT_EQ(2u, config_.ReceivedConnectionOptions().size());
96 EXPECT_EQ(config_.ReceivedConnectionOptions()[0], kIW50);
97 EXPECT_EQ(config_.ReceivedConnectionOptions()[1], kTBBR);
98 EXPECT_EQ(config_.ReceivedInitialStreamFlowControlWindowBytes(),
99 2 * kInitialStreamFlowControlWindowForTest);
100 EXPECT_EQ(config_.ReceivedInitialSessionFlowControlWindowBytes(),
101 2 * kInitialSessionFlowControlWindowForTest);
102}
103
fkastenholzd3a1de92019-05-15 07:00:07 -0700104TEST_P(QuicConfigTest, ProcessServerHello) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500105 QuicIpAddress host;
106 host.FromString("127.0.3.1");
107 const QuicSocketAddress kTestServerAddress = QuicSocketAddress(host, 1234);
108 const QuicUint128 kTestResetToken = MakeQuicUint128(0, 10111100001);
109 QuicConfig server_config;
110 QuicTagVector cgst;
111 cgst.push_back(kQBIC);
112 server_config.SetIdleNetworkTimeout(
113 QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs / 2),
114 QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs / 2));
115 server_config.SetInitialRoundTripTimeUsToSend(10 * kNumMicrosPerMilli);
116 server_config.SetInitialStreamFlowControlWindowToSend(
117 2 * kInitialStreamFlowControlWindowForTest);
118 server_config.SetInitialSessionFlowControlWindowToSend(
119 2 * kInitialSessionFlowControlWindowForTest);
120 server_config.SetAlternateServerAddressToSend(kTestServerAddress);
121 server_config.SetStatelessResetTokenToSend(kTestResetToken);
122 CryptoHandshakeMessage msg;
fkastenholzd3a1de92019-05-15 07:00:07 -0700123 server_config.ToHandshakeMessage(&msg, GetParam());
vasilvvc48c8712019-03-11 13:38:16 -0700124 std::string error_details;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500125 const QuicErrorCode error =
126 config_.ProcessPeerHello(msg, SERVER, &error_details);
127 EXPECT_EQ(QUIC_NO_ERROR, error);
128 EXPECT_TRUE(config_.negotiated());
129 EXPECT_EQ(QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs / 2),
130 config_.IdleNetworkTimeout());
131 EXPECT_EQ(10 * kNumMicrosPerMilli, config_.ReceivedInitialRoundTripTimeUs());
132 EXPECT_EQ(config_.ReceivedInitialStreamFlowControlWindowBytes(),
133 2 * kInitialStreamFlowControlWindowForTest);
134 EXPECT_EQ(config_.ReceivedInitialSessionFlowControlWindowBytes(),
135 2 * kInitialSessionFlowControlWindowForTest);
136 EXPECT_TRUE(config_.HasReceivedAlternateServerAddress());
137 EXPECT_EQ(kTestServerAddress, config_.ReceivedAlternateServerAddress());
138 EXPECT_TRUE(config_.HasReceivedStatelessResetToken());
139 EXPECT_EQ(kTestResetToken, config_.ReceivedStatelessResetToken());
140}
141
fkastenholzd3a1de92019-05-15 07:00:07 -0700142TEST_P(QuicConfigTest, MissingOptionalValuesInCHLO) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500143 CryptoHandshakeMessage msg;
144 msg.SetValue(kICSL, 1);
145
146 // Set all REQUIRED tags.
147 msg.SetValue(kICSL, 1);
fkastenholzd3a1de92019-05-15 07:00:07 -0700148 msg.SetValue(kMIBS, 1);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500149
150 // No error, as rest are optional.
vasilvvc48c8712019-03-11 13:38:16 -0700151 std::string error_details;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500152 const QuicErrorCode error =
153 config_.ProcessPeerHello(msg, CLIENT, &error_details);
154 EXPECT_EQ(QUIC_NO_ERROR, error);
155 EXPECT_TRUE(config_.negotiated());
156}
157
fkastenholzd3a1de92019-05-15 07:00:07 -0700158TEST_P(QuicConfigTest, MissingOptionalValuesInSHLO) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500159 CryptoHandshakeMessage msg;
160
161 // Set all REQUIRED tags.
162 msg.SetValue(kICSL, 1);
fkastenholzd3a1de92019-05-15 07:00:07 -0700163 msg.SetValue(kMIBS, 1);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500164
165 // No error, as rest are optional.
vasilvvc48c8712019-03-11 13:38:16 -0700166 std::string error_details;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500167 const QuicErrorCode error =
168 config_.ProcessPeerHello(msg, SERVER, &error_details);
169 EXPECT_EQ(QUIC_NO_ERROR, error);
170 EXPECT_TRUE(config_.negotiated());
171}
172
fkastenholzd3a1de92019-05-15 07:00:07 -0700173TEST_P(QuicConfigTest, MissingValueInCHLO) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500174 // Server receives CHLO with missing kICSL.
175 CryptoHandshakeMessage msg;
vasilvvc48c8712019-03-11 13:38:16 -0700176 std::string error_details;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500177 const QuicErrorCode error =
178 config_.ProcessPeerHello(msg, CLIENT, &error_details);
179 EXPECT_EQ(QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND, error);
180}
181
fkastenholzd3a1de92019-05-15 07:00:07 -0700182TEST_P(QuicConfigTest, MissingValueInSHLO) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500183 // Client receives SHLO with missing kICSL.
184 CryptoHandshakeMessage msg;
vasilvvc48c8712019-03-11 13:38:16 -0700185 std::string error_details;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500186 const QuicErrorCode error =
187 config_.ProcessPeerHello(msg, SERVER, &error_details);
188 EXPECT_EQ(QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND, error);
189}
190
fkastenholzd3a1de92019-05-15 07:00:07 -0700191TEST_P(QuicConfigTest, OutOfBoundSHLO) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500192 QuicConfig server_config;
193 server_config.SetIdleNetworkTimeout(
194 QuicTime::Delta::FromSeconds(2 * kMaximumIdleTimeoutSecs),
195 QuicTime::Delta::FromSeconds(2 * kMaximumIdleTimeoutSecs));
196
197 CryptoHandshakeMessage msg;
fkastenholzd3a1de92019-05-15 07:00:07 -0700198 server_config.ToHandshakeMessage(&msg, GetParam());
vasilvvc48c8712019-03-11 13:38:16 -0700199 std::string error_details;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500200 const QuicErrorCode error =
201 config_.ProcessPeerHello(msg, SERVER, &error_details);
202 EXPECT_EQ(QUIC_INVALID_NEGOTIATED_VALUE, error);
203}
204
fkastenholzd3a1de92019-05-15 07:00:07 -0700205TEST_P(QuicConfigTest, InvalidFlowControlWindow) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500206 // QuicConfig should not accept an invalid flow control window to send to the
207 // peer: the receive window must be at least the default of 16 Kb.
208 QuicConfig config;
209 const uint64_t kInvalidWindow = kMinimumFlowControlSendWindow - 1;
210 EXPECT_QUIC_BUG(
211 config.SetInitialStreamFlowControlWindowToSend(kInvalidWindow),
212 "Initial stream flow control receive window");
213
214 EXPECT_EQ(kMinimumFlowControlSendWindow,
215 config.GetInitialStreamFlowControlWindowToSend());
216}
217
fkastenholzd3a1de92019-05-15 07:00:07 -0700218TEST_P(QuicConfigTest, HasClientSentConnectionOption) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500219 QuicConfig client_config;
220 QuicTagVector copt;
221 copt.push_back(kTBBR);
222 client_config.SetConnectionOptionsToSend(copt);
223 EXPECT_TRUE(client_config.HasClientSentConnectionOption(
224 kTBBR, Perspective::IS_CLIENT));
225
226 CryptoHandshakeMessage msg;
fkastenholzd3a1de92019-05-15 07:00:07 -0700227 client_config.ToHandshakeMessage(&msg, GetParam());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500228
vasilvvc48c8712019-03-11 13:38:16 -0700229 std::string error_details;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500230 const QuicErrorCode error =
231 config_.ProcessPeerHello(msg, CLIENT, &error_details);
232 EXPECT_EQ(QUIC_NO_ERROR, error);
233 EXPECT_TRUE(config_.negotiated());
234
235 EXPECT_TRUE(config_.HasReceivedConnectionOptions());
236 EXPECT_EQ(1u, config_.ReceivedConnectionOptions().size());
237 EXPECT_TRUE(
238 config_.HasClientSentConnectionOption(kTBBR, Perspective::IS_SERVER));
239}
240
fkastenholzd3a1de92019-05-15 07:00:07 -0700241TEST_P(QuicConfigTest, DontSendClientConnectionOptions) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500242 QuicConfig client_config;
243 QuicTagVector copt;
244 copt.push_back(kTBBR);
245 client_config.SetClientConnectionOptions(copt);
246
247 CryptoHandshakeMessage msg;
fkastenholzd3a1de92019-05-15 07:00:07 -0700248 client_config.ToHandshakeMessage(&msg, GetParam());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500249
vasilvvc48c8712019-03-11 13:38:16 -0700250 std::string error_details;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500251 const QuicErrorCode error =
252 config_.ProcessPeerHello(msg, CLIENT, &error_details);
253 EXPECT_EQ(QUIC_NO_ERROR, error);
254 EXPECT_TRUE(config_.negotiated());
255
256 EXPECT_FALSE(config_.HasReceivedConnectionOptions());
257}
258
fkastenholzd3a1de92019-05-15 07:00:07 -0700259TEST_P(QuicConfigTest, HasClientRequestedIndependentOption) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500260 QuicConfig client_config;
261 QuicTagVector client_opt;
262 client_opt.push_back(kRENO);
263 QuicTagVector copt;
264 copt.push_back(kTBBR);
265 client_config.SetClientConnectionOptions(client_opt);
266 client_config.SetConnectionOptionsToSend(copt);
267 EXPECT_TRUE(client_config.HasClientSentConnectionOption(
268 kTBBR, Perspective::IS_CLIENT));
269 EXPECT_TRUE(client_config.HasClientRequestedIndependentOption(
270 kRENO, Perspective::IS_CLIENT));
271 EXPECT_FALSE(client_config.HasClientRequestedIndependentOption(
272 kTBBR, Perspective::IS_CLIENT));
273
274 CryptoHandshakeMessage msg;
fkastenholzd3a1de92019-05-15 07:00:07 -0700275 client_config.ToHandshakeMessage(&msg, GetParam());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500276
vasilvvc48c8712019-03-11 13:38:16 -0700277 std::string error_details;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500278 const QuicErrorCode error =
279 config_.ProcessPeerHello(msg, CLIENT, &error_details);
280 EXPECT_EQ(QUIC_NO_ERROR, error);
281 EXPECT_TRUE(config_.negotiated());
282
283 EXPECT_TRUE(config_.HasReceivedConnectionOptions());
284 EXPECT_EQ(1u, config_.ReceivedConnectionOptions().size());
285 EXPECT_FALSE(config_.HasClientRequestedIndependentOption(
286 kRENO, Perspective::IS_SERVER));
287 EXPECT_TRUE(config_.HasClientRequestedIndependentOption(
288 kTBBR, Perspective::IS_SERVER));
289}
290
291} // namespace
292} // namespace test
293} // namespace quic