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