1 // 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/quic/quic_config.h"
6
7 #include "net/quic/crypto/crypto_handshake_message.h"
8 #include "net/quic/crypto/crypto_protocol.h"
9 #include "net/quic/quic_flags.h"
10 #include "net/quic/quic_protocol.h"
11 #include "net/quic/quic_time.h"
12 #include "net/quic/quic_utils.h"
13 #include "net/quic/test_tools/quic_test_utils.h"
14 #include "net/test/gtest_util.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16
17 using std::string;
18
19 namespace net {
20 namespace test {
21 namespace {
22
23 class QuicConfigTest : public ::testing::Test {
24 protected:
QuicConfigTest()25 QuicConfigTest() {
26 config_.SetDefaults();
27 }
28
29 QuicConfig config_;
30 };
31
TEST_F(QuicConfigTest,ToHandshakeMessage)32 TEST_F(QuicConfigTest, ToHandshakeMessage) {
33 config_.SetDefaults();
34 config_.SetInitialFlowControlWindowToSend(
35 kInitialSessionFlowControlWindowForTest);
36 config_.SetInitialStreamFlowControlWindowToSend(
37 kInitialStreamFlowControlWindowForTest);
38 config_.SetInitialSessionFlowControlWindowToSend(
39 kInitialSessionFlowControlWindowForTest);
40 config_.set_idle_connection_state_lifetime(QuicTime::Delta::FromSeconds(5),
41 QuicTime::Delta::FromSeconds(2));
42 config_.set_max_streams_per_connection(4, 2);
43 config_.SetSocketReceiveBufferToSend(kDefaultSocketReceiveBuffer);
44 CryptoHandshakeMessage msg;
45 config_.ToHandshakeMessage(&msg);
46
47 uint32 value;
48 QuicErrorCode error = msg.GetUint32(kICSL, &value);
49 EXPECT_EQ(QUIC_NO_ERROR, error);
50 EXPECT_EQ(5u, value);
51
52 error = msg.GetUint32(kMSPC, &value);
53 EXPECT_EQ(QUIC_NO_ERROR, error);
54 EXPECT_EQ(4u, value);
55
56 error = msg.GetUint32(kIFCW, &value);
57 EXPECT_EQ(QUIC_NO_ERROR, error);
58 EXPECT_EQ(kInitialSessionFlowControlWindowForTest, value);
59
60 error = msg.GetUint32(kSFCW, &value);
61 EXPECT_EQ(QUIC_NO_ERROR, error);
62 EXPECT_EQ(kInitialStreamFlowControlWindowForTest, value);
63
64 error = msg.GetUint32(kCFCW, &value);
65 EXPECT_EQ(QUIC_NO_ERROR, error);
66 EXPECT_EQ(kInitialSessionFlowControlWindowForTest, value);
67
68 error = msg.GetUint32(kSRBF, &value);
69 EXPECT_EQ(QUIC_NO_ERROR, error);
70 EXPECT_EQ(kDefaultSocketReceiveBuffer, value);
71
72 const QuicTag* out;
73 size_t out_len;
74 error = msg.GetTaglist(kCGST, &out, &out_len);
75 EXPECT_EQ(1u, out_len);
76 EXPECT_EQ(kQBIC, *out);
77 }
78
TEST_F(QuicConfigTest,ProcessClientHello)79 TEST_F(QuicConfigTest, ProcessClientHello) {
80 QuicConfig client_config;
81 QuicTagVector cgst;
82 cgst.push_back(kQBIC);
83 client_config.set_congestion_feedback(cgst, kQBIC);
84 client_config.set_idle_connection_state_lifetime(
85 QuicTime::Delta::FromSeconds(2 * kMaximumIdleTimeoutSecs),
86 QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs));
87 client_config.set_max_streams_per_connection(
88 2 * kDefaultMaxStreamsPerConnection, kDefaultMaxStreamsPerConnection);
89 client_config.SetInitialRoundTripTimeUsToSend(
90 10 * base::Time::kMicrosecondsPerMillisecond);
91 client_config.SetInitialFlowControlWindowToSend(
92 2 * kInitialSessionFlowControlWindowForTest);
93 client_config.SetInitialStreamFlowControlWindowToSend(
94 2 * kInitialStreamFlowControlWindowForTest);
95 client_config.SetInitialSessionFlowControlWindowToSend(
96 2 * kInitialSessionFlowControlWindowForTest);
97 client_config.SetSocketReceiveBufferToSend(kDefaultSocketReceiveBuffer);
98 QuicTagVector copt;
99 copt.push_back(kTBBR);
100 copt.push_back(kFHDR);
101 client_config.SetConnectionOptionsToSend(copt);
102 CryptoHandshakeMessage msg;
103 client_config.ToHandshakeMessage(&msg);
104 string error_details;
105 const QuicErrorCode error =
106 config_.ProcessPeerHello(msg, CLIENT, &error_details);
107 EXPECT_EQ(QUIC_NO_ERROR, error);
108 EXPECT_TRUE(config_.negotiated());
109 EXPECT_EQ(kQBIC, config_.congestion_feedback());
110 EXPECT_EQ(QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs),
111 config_.idle_connection_state_lifetime());
112 EXPECT_EQ(kDefaultMaxStreamsPerConnection,
113 config_.max_streams_per_connection());
114 EXPECT_EQ(QuicTime::Delta::FromSeconds(0), config_.keepalive_timeout());
115 EXPECT_EQ(10 * base::Time::kMicrosecondsPerMillisecond,
116 config_.ReceivedInitialRoundTripTimeUs());
117 EXPECT_FALSE(config_.HasReceivedLossDetection());
118 EXPECT_TRUE(config_.HasReceivedConnectionOptions());
119 EXPECT_EQ(2u, config_.ReceivedConnectionOptions().size());
120 EXPECT_EQ(config_.ReceivedConnectionOptions()[0], kTBBR);
121 EXPECT_EQ(config_.ReceivedConnectionOptions()[1], kFHDR);
122 EXPECT_EQ(config_.ReceivedInitialFlowControlWindowBytes(),
123 2 * kInitialSessionFlowControlWindowForTest);
124 EXPECT_EQ(config_.ReceivedInitialStreamFlowControlWindowBytes(),
125 2 * kInitialStreamFlowControlWindowForTest);
126 EXPECT_EQ(config_.ReceivedInitialSessionFlowControlWindowBytes(),
127 2 * kInitialSessionFlowControlWindowForTest);
128 EXPECT_EQ(config_.ReceivedSocketReceiveBuffer(),
129 kDefaultSocketReceiveBuffer);
130 }
131
TEST_F(QuicConfigTest,ProcessServerHello)132 TEST_F(QuicConfigTest, ProcessServerHello) {
133 QuicConfig server_config;
134 QuicTagVector cgst;
135 cgst.push_back(kQBIC);
136 server_config.set_congestion_feedback(cgst, kQBIC);
137 server_config.set_idle_connection_state_lifetime(
138 QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs / 2),
139 QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs / 2));
140 server_config.set_max_streams_per_connection(
141 kDefaultMaxStreamsPerConnection / 2,
142 kDefaultMaxStreamsPerConnection / 2);
143 server_config.SetInitialCongestionWindowToSend(kDefaultInitialWindow / 2);
144 server_config.SetInitialRoundTripTimeUsToSend(
145 10 * base::Time::kMicrosecondsPerMillisecond);
146 server_config.SetInitialFlowControlWindowToSend(
147 2 * kInitialSessionFlowControlWindowForTest);
148 server_config.SetInitialStreamFlowControlWindowToSend(
149 2 * kInitialStreamFlowControlWindowForTest);
150 server_config.SetInitialSessionFlowControlWindowToSend(
151 2 * kInitialSessionFlowControlWindowForTest);
152 server_config.SetSocketReceiveBufferToSend(kDefaultSocketReceiveBuffer);
153 CryptoHandshakeMessage msg;
154 server_config.ToHandshakeMessage(&msg);
155 string error_details;
156 const QuicErrorCode error =
157 config_.ProcessPeerHello(msg, SERVER, &error_details);
158 EXPECT_EQ(QUIC_NO_ERROR, error);
159 EXPECT_TRUE(config_.negotiated());
160 EXPECT_EQ(kQBIC, config_.congestion_feedback());
161 EXPECT_EQ(QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs / 2),
162 config_.idle_connection_state_lifetime());
163 EXPECT_EQ(kDefaultMaxStreamsPerConnection / 2,
164 config_.max_streams_per_connection());
165 EXPECT_EQ(kDefaultInitialWindow / 2,
166 config_.ReceivedInitialCongestionWindow());
167 EXPECT_EQ(QuicTime::Delta::FromSeconds(0), config_.keepalive_timeout());
168 EXPECT_EQ(10 * base::Time::kMicrosecondsPerMillisecond,
169 config_.ReceivedInitialRoundTripTimeUs());
170 EXPECT_FALSE(config_.HasReceivedLossDetection());
171 EXPECT_EQ(config_.ReceivedInitialFlowControlWindowBytes(),
172 2 * kInitialSessionFlowControlWindowForTest);
173 EXPECT_EQ(config_.ReceivedInitialStreamFlowControlWindowBytes(),
174 2 * kInitialStreamFlowControlWindowForTest);
175 EXPECT_EQ(config_.ReceivedInitialSessionFlowControlWindowBytes(),
176 2 * kInitialSessionFlowControlWindowForTest);
177 EXPECT_EQ(config_.ReceivedSocketReceiveBuffer(),
178 kDefaultSocketReceiveBuffer);
179 }
180
TEST_F(QuicConfigTest,MissingOptionalValuesInCHLO)181 TEST_F(QuicConfigTest, MissingOptionalValuesInCHLO) {
182 CryptoHandshakeMessage msg;
183 msg.SetValue(kICSL, 1);
184 msg.SetVector(kCGST, QuicTagVector(1, kQBIC));
185
186 // Set all REQUIRED tags.
187 msg.SetValue(kICSL, 1);
188 msg.SetVector(kCGST, QuicTagVector(1, kQBIC));
189 msg.SetValue(kMSPC, 1);
190
191 // No error, as rest are optional.
192 string error_details;
193 const QuicErrorCode error =
194 config_.ProcessPeerHello(msg, CLIENT, &error_details);
195 EXPECT_EQ(QUIC_NO_ERROR, error);
196
197 EXPECT_FALSE(config_.HasReceivedInitialFlowControlWindowBytes());
198 }
199
TEST_F(QuicConfigTest,MissingOptionalValuesInSHLO)200 TEST_F(QuicConfigTest, MissingOptionalValuesInSHLO) {
201 CryptoHandshakeMessage msg;
202
203 // Set all REQUIRED tags.
204 msg.SetValue(kICSL, 1);
205 msg.SetVector(kCGST, QuicTagVector(1, kQBIC));
206 msg.SetValue(kMSPC, 1);
207
208 // No error, as rest are optional.
209 string error_details;
210 const QuicErrorCode error =
211 config_.ProcessPeerHello(msg, SERVER, &error_details);
212 EXPECT_EQ(QUIC_NO_ERROR, error);
213
214 EXPECT_FALSE(config_.HasReceivedInitialFlowControlWindowBytes());
215 }
216
TEST_F(QuicConfigTest,MissingValueInCHLO)217 TEST_F(QuicConfigTest, MissingValueInCHLO) {
218 CryptoHandshakeMessage msg;
219 msg.SetValue(kICSL, 1);
220 msg.SetVector(kCGST, QuicTagVector(1, kQBIC));
221 // Missing kMSPC. KATO is optional.
222 string error_details;
223 const QuicErrorCode error =
224 config_.ProcessPeerHello(msg, CLIENT, &error_details);
225 EXPECT_EQ(QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND, error);
226 }
227
TEST_F(QuicConfigTest,MissingValueInSHLO)228 TEST_F(QuicConfigTest, MissingValueInSHLO) {
229 CryptoHandshakeMessage msg;
230 msg.SetValue(kICSL, 1);
231 msg.SetValue(kMSPC, 3);
232 // Missing CGST. KATO is optional.
233 string error_details;
234 const QuicErrorCode error =
235 config_.ProcessPeerHello(msg, SERVER, &error_details);
236 EXPECT_EQ(QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND, error);
237 }
238
TEST_F(QuicConfigTest,OutOfBoundSHLO)239 TEST_F(QuicConfigTest, OutOfBoundSHLO) {
240 QuicConfig server_config;
241 server_config.set_idle_connection_state_lifetime(
242 QuicTime::Delta::FromSeconds(2 * kMaximumIdleTimeoutSecs),
243 QuicTime::Delta::FromSeconds(2 * kMaximumIdleTimeoutSecs));
244
245 CryptoHandshakeMessage msg;
246 server_config.ToHandshakeMessage(&msg);
247 string error_details;
248 const QuicErrorCode error =
249 config_.ProcessPeerHello(msg, SERVER, &error_details);
250 EXPECT_EQ(QUIC_INVALID_NEGOTIATED_VALUE, error);
251 }
252
TEST_F(QuicConfigTest,MultipleNegotiatedValuesInVectorTag)253 TEST_F(QuicConfigTest, MultipleNegotiatedValuesInVectorTag) {
254 QuicConfig server_config;
255 QuicTagVector cgst;
256 cgst.push_back(kQBIC);
257 cgst.push_back(kTBBR);
258 server_config.set_congestion_feedback(cgst, kQBIC);
259
260 CryptoHandshakeMessage msg;
261 server_config.ToHandshakeMessage(&msg);
262 string error_details;
263 const QuicErrorCode error =
264 config_.ProcessPeerHello(msg, SERVER, &error_details);
265 EXPECT_EQ(QUIC_INVALID_NEGOTIATED_VALUE, error);
266 }
267
TEST_F(QuicConfigTest,NoOverLapInCGST)268 TEST_F(QuicConfigTest, NoOverLapInCGST) {
269 QuicConfig server_config;
270 server_config.SetDefaults();
271 QuicTagVector cgst;
272 cgst.push_back(kTBBR);
273 server_config.set_congestion_feedback(cgst, kTBBR);
274
275 CryptoHandshakeMessage msg;
276 string error_details;
277 server_config.ToHandshakeMessage(&msg);
278 const QuicErrorCode error =
279 config_.ProcessPeerHello(msg, CLIENT, &error_details);
280 DVLOG(1) << QuicUtils::ErrorToString(error);
281 EXPECT_EQ(QUIC_CRYPTO_MESSAGE_PARAMETER_NO_OVERLAP, error);
282 }
283
TEST_F(QuicConfigTest,InvalidFlowControlWindow)284 TEST_F(QuicConfigTest, InvalidFlowControlWindow) {
285 // QuicConfig should not accept an invalid flow control window to send to the
286 // peer: the receive window must be at least the default of 16 Kb.
287 QuicConfig config;
288 const uint64 kInvalidWindow = kDefaultFlowControlSendWindow - 1;
289 EXPECT_DFATAL(config.SetInitialFlowControlWindowToSend(kInvalidWindow),
290 "Initial flow control receive window");
291
292 EXPECT_EQ(kDefaultFlowControlSendWindow,
293 config.GetInitialFlowControlWindowToSend());
294 }
295
296 } // namespace
297 } // namespace test
298 } // namespace net
299