blob: c18c5200708b5f91fba1b44fdcf65e790f5b266f [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
24class QuicConfigTest : public QuicTest {
25 protected:
26 QuicConfig config_;
27};
28
29TEST_F(QuicConfigTest, ToHandshakeMessage) {
30 config_.SetInitialStreamFlowControlWindowToSend(
31 kInitialStreamFlowControlWindowForTest);
32 config_.SetInitialSessionFlowControlWindowToSend(
33 kInitialSessionFlowControlWindowForTest);
34 config_.SetIdleNetworkTimeout(QuicTime::Delta::FromSeconds(5),
35 QuicTime::Delta::FromSeconds(2));
36 CryptoHandshakeMessage msg;
37 config_.ToHandshakeMessage(&msg);
38
39 uint32_t value;
40 QuicErrorCode error = msg.GetUint32(kICSL, &value);
41 EXPECT_EQ(QUIC_NO_ERROR, error);
42 EXPECT_EQ(5u, value);
43
44 error = msg.GetUint32(kSFCW, &value);
45 EXPECT_EQ(QUIC_NO_ERROR, error);
46 EXPECT_EQ(kInitialStreamFlowControlWindowForTest, value);
47
48 error = msg.GetUint32(kCFCW, &value);
49 EXPECT_EQ(QUIC_NO_ERROR, error);
50 EXPECT_EQ(kInitialSessionFlowControlWindowForTest, value);
51}
52
53TEST_F(QuicConfigTest, ProcessClientHello) {
54 QuicConfig client_config;
55 QuicTagVector cgst;
56 cgst.push_back(kQBIC);
57 client_config.SetIdleNetworkTimeout(
58 QuicTime::Delta::FromSeconds(2 * kMaximumIdleTimeoutSecs),
59 QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs));
60 client_config.SetInitialRoundTripTimeUsToSend(10 * kNumMicrosPerMilli);
61 client_config.SetInitialStreamFlowControlWindowToSend(
62 2 * kInitialStreamFlowControlWindowForTest);
63 client_config.SetInitialSessionFlowControlWindowToSend(
64 2 * kInitialSessionFlowControlWindowForTest);
65 QuicTagVector copt;
66 copt.push_back(kTBBR);
67 client_config.SetConnectionOptionsToSend(copt);
68 CryptoHandshakeMessage msg;
69 client_config.ToHandshakeMessage(&msg);
70
vasilvvc48c8712019-03-11 13:38:16 -070071 std::string error_details;
QUICHE teama6ef0a62019-03-07 20:34:33 -050072 QuicTagVector initial_received_options;
73 initial_received_options.push_back(kIW50);
74 EXPECT_TRUE(
75 config_.SetInitialReceivedConnectionOptions(initial_received_options));
76 EXPECT_FALSE(
77 config_.SetInitialReceivedConnectionOptions(initial_received_options))
78 << "You can only set initial options once.";
79 const QuicErrorCode error =
80 config_.ProcessPeerHello(msg, CLIENT, &error_details);
81 EXPECT_FALSE(
82 config_.SetInitialReceivedConnectionOptions(initial_received_options))
83 << "You cannot set initial options after the hello.";
84 EXPECT_EQ(QUIC_NO_ERROR, error);
85 EXPECT_TRUE(config_.negotiated());
86 EXPECT_EQ(QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs),
87 config_.IdleNetworkTimeout());
88 EXPECT_EQ(10 * kNumMicrosPerMilli, config_.ReceivedInitialRoundTripTimeUs());
89 EXPECT_TRUE(config_.HasReceivedConnectionOptions());
90 EXPECT_EQ(2u, config_.ReceivedConnectionOptions().size());
91 EXPECT_EQ(config_.ReceivedConnectionOptions()[0], kIW50);
92 EXPECT_EQ(config_.ReceivedConnectionOptions()[1], kTBBR);
93 EXPECT_EQ(config_.ReceivedInitialStreamFlowControlWindowBytes(),
94 2 * kInitialStreamFlowControlWindowForTest);
95 EXPECT_EQ(config_.ReceivedInitialSessionFlowControlWindowBytes(),
96 2 * kInitialSessionFlowControlWindowForTest);
97}
98
99TEST_F(QuicConfigTest, ProcessServerHello) {
100 QuicIpAddress host;
101 host.FromString("127.0.3.1");
102 const QuicSocketAddress kTestServerAddress = QuicSocketAddress(host, 1234);
103 const QuicUint128 kTestResetToken = MakeQuicUint128(0, 10111100001);
104 QuicConfig server_config;
105 QuicTagVector cgst;
106 cgst.push_back(kQBIC);
107 server_config.SetIdleNetworkTimeout(
108 QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs / 2),
109 QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs / 2));
110 server_config.SetInitialRoundTripTimeUsToSend(10 * kNumMicrosPerMilli);
111 server_config.SetInitialStreamFlowControlWindowToSend(
112 2 * kInitialStreamFlowControlWindowForTest);
113 server_config.SetInitialSessionFlowControlWindowToSend(
114 2 * kInitialSessionFlowControlWindowForTest);
115 server_config.SetAlternateServerAddressToSend(kTestServerAddress);
116 server_config.SetStatelessResetTokenToSend(kTestResetToken);
117 CryptoHandshakeMessage msg;
118 server_config.ToHandshakeMessage(&msg);
vasilvvc48c8712019-03-11 13:38:16 -0700119 std::string error_details;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500120 const QuicErrorCode error =
121 config_.ProcessPeerHello(msg, SERVER, &error_details);
122 EXPECT_EQ(QUIC_NO_ERROR, error);
123 EXPECT_TRUE(config_.negotiated());
124 EXPECT_EQ(QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs / 2),
125 config_.IdleNetworkTimeout());
126 EXPECT_EQ(10 * kNumMicrosPerMilli, config_.ReceivedInitialRoundTripTimeUs());
127 EXPECT_EQ(config_.ReceivedInitialStreamFlowControlWindowBytes(),
128 2 * kInitialStreamFlowControlWindowForTest);
129 EXPECT_EQ(config_.ReceivedInitialSessionFlowControlWindowBytes(),
130 2 * kInitialSessionFlowControlWindowForTest);
131 EXPECT_TRUE(config_.HasReceivedAlternateServerAddress());
132 EXPECT_EQ(kTestServerAddress, config_.ReceivedAlternateServerAddress());
133 EXPECT_TRUE(config_.HasReceivedStatelessResetToken());
134 EXPECT_EQ(kTestResetToken, config_.ReceivedStatelessResetToken());
135}
136
137TEST_F(QuicConfigTest, MissingOptionalValuesInCHLO) {
138 CryptoHandshakeMessage msg;
139 msg.SetValue(kICSL, 1);
140
141 // Set all REQUIRED tags.
142 msg.SetValue(kICSL, 1);
143 msg.SetValue(kMIDS, 1);
144
145 // No error, as rest are optional.
vasilvvc48c8712019-03-11 13:38:16 -0700146 std::string error_details;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500147 const QuicErrorCode error =
148 config_.ProcessPeerHello(msg, CLIENT, &error_details);
149 EXPECT_EQ(QUIC_NO_ERROR, error);
150 EXPECT_TRUE(config_.negotiated());
151}
152
153TEST_F(QuicConfigTest, MissingOptionalValuesInSHLO) {
154 CryptoHandshakeMessage msg;
155
156 // Set all REQUIRED tags.
157 msg.SetValue(kICSL, 1);
158 msg.SetValue(kMIDS, 1);
159
160 // No error, as rest are optional.
vasilvvc48c8712019-03-11 13:38:16 -0700161 std::string error_details;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500162 const QuicErrorCode error =
163 config_.ProcessPeerHello(msg, SERVER, &error_details);
164 EXPECT_EQ(QUIC_NO_ERROR, error);
165 EXPECT_TRUE(config_.negotiated());
166}
167
168TEST_F(QuicConfigTest, MissingValueInCHLO) {
169 // Server receives CHLO with missing kICSL.
170 CryptoHandshakeMessage msg;
vasilvvc48c8712019-03-11 13:38:16 -0700171 std::string error_details;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500172 const QuicErrorCode error =
173 config_.ProcessPeerHello(msg, CLIENT, &error_details);
174 EXPECT_EQ(QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND, error);
175}
176
177TEST_F(QuicConfigTest, MissingValueInSHLO) {
178 // Client receives SHLO with missing kICSL.
179 CryptoHandshakeMessage msg;
vasilvvc48c8712019-03-11 13:38:16 -0700180 std::string error_details;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500181 const QuicErrorCode error =
182 config_.ProcessPeerHello(msg, SERVER, &error_details);
183 EXPECT_EQ(QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND, error);
184}
185
186TEST_F(QuicConfigTest, OutOfBoundSHLO) {
187 QuicConfig server_config;
188 server_config.SetIdleNetworkTimeout(
189 QuicTime::Delta::FromSeconds(2 * kMaximumIdleTimeoutSecs),
190 QuicTime::Delta::FromSeconds(2 * kMaximumIdleTimeoutSecs));
191
192 CryptoHandshakeMessage msg;
193 server_config.ToHandshakeMessage(&msg);
vasilvvc48c8712019-03-11 13:38:16 -0700194 std::string error_details;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500195 const QuicErrorCode error =
196 config_.ProcessPeerHello(msg, SERVER, &error_details);
197 EXPECT_EQ(QUIC_INVALID_NEGOTIATED_VALUE, error);
198}
199
200TEST_F(QuicConfigTest, InvalidFlowControlWindow) {
201 // QuicConfig should not accept an invalid flow control window to send to the
202 // peer: the receive window must be at least the default of 16 Kb.
203 QuicConfig config;
204 const uint64_t kInvalidWindow = kMinimumFlowControlSendWindow - 1;
205 EXPECT_QUIC_BUG(
206 config.SetInitialStreamFlowControlWindowToSend(kInvalidWindow),
207 "Initial stream flow control receive window");
208
209 EXPECT_EQ(kMinimumFlowControlSendWindow,
210 config.GetInitialStreamFlowControlWindowToSend());
211}
212
213TEST_F(QuicConfigTest, HasClientSentConnectionOption) {
214 QuicConfig client_config;
215 QuicTagVector copt;
216 copt.push_back(kTBBR);
217 client_config.SetConnectionOptionsToSend(copt);
218 EXPECT_TRUE(client_config.HasClientSentConnectionOption(
219 kTBBR, Perspective::IS_CLIENT));
220
221 CryptoHandshakeMessage msg;
222 client_config.ToHandshakeMessage(&msg);
223
vasilvvc48c8712019-03-11 13:38:16 -0700224 std::string error_details;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500225 const QuicErrorCode error =
226 config_.ProcessPeerHello(msg, CLIENT, &error_details);
227 EXPECT_EQ(QUIC_NO_ERROR, error);
228 EXPECT_TRUE(config_.negotiated());
229
230 EXPECT_TRUE(config_.HasReceivedConnectionOptions());
231 EXPECT_EQ(1u, config_.ReceivedConnectionOptions().size());
232 EXPECT_TRUE(
233 config_.HasClientSentConnectionOption(kTBBR, Perspective::IS_SERVER));
234}
235
236TEST_F(QuicConfigTest, DontSendClientConnectionOptions) {
237 QuicConfig client_config;
238 QuicTagVector copt;
239 copt.push_back(kTBBR);
240 client_config.SetClientConnectionOptions(copt);
241
242 CryptoHandshakeMessage msg;
243 client_config.ToHandshakeMessage(&msg);
244
vasilvvc48c8712019-03-11 13:38:16 -0700245 std::string error_details;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500246 const QuicErrorCode error =
247 config_.ProcessPeerHello(msg, CLIENT, &error_details);
248 EXPECT_EQ(QUIC_NO_ERROR, error);
249 EXPECT_TRUE(config_.negotiated());
250
251 EXPECT_FALSE(config_.HasReceivedConnectionOptions());
252}
253
254TEST_F(QuicConfigTest, HasClientRequestedIndependentOption) {
255 QuicConfig client_config;
256 QuicTagVector client_opt;
257 client_opt.push_back(kRENO);
258 QuicTagVector copt;
259 copt.push_back(kTBBR);
260 client_config.SetClientConnectionOptions(client_opt);
261 client_config.SetConnectionOptionsToSend(copt);
262 EXPECT_TRUE(client_config.HasClientSentConnectionOption(
263 kTBBR, Perspective::IS_CLIENT));
264 EXPECT_TRUE(client_config.HasClientRequestedIndependentOption(
265 kRENO, Perspective::IS_CLIENT));
266 EXPECT_FALSE(client_config.HasClientRequestedIndependentOption(
267 kTBBR, Perspective::IS_CLIENT));
268
269 CryptoHandshakeMessage msg;
270 client_config.ToHandshakeMessage(&msg);
271
vasilvvc48c8712019-03-11 13:38:16 -0700272 std::string error_details;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500273 const QuicErrorCode error =
274 config_.ProcessPeerHello(msg, CLIENT, &error_details);
275 EXPECT_EQ(QUIC_NO_ERROR, error);
276 EXPECT_TRUE(config_.negotiated());
277
278 EXPECT_TRUE(config_.HasReceivedConnectionOptions());
279 EXPECT_EQ(1u, config_.ReceivedConnectionOptions().size());
280 EXPECT_FALSE(config_.HasClientRequestedIndependentOption(
281 kRENO, Perspective::IS_SERVER));
282 EXPECT_TRUE(config_.HasClientRequestedIndependentOption(
283 kTBBR, Perspective::IS_SERVER));
284}
285
286} // namespace
287} // namespace test
288} // namespace quic