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_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"
23 class QuicConfigTest
: public ::testing::Test
{
28 TEST_F(QuicConfigTest
, ToHandshakeMessage
) {
29 config_
.SetInitialFlowControlWindowToSend(
30 kInitialSessionFlowControlWindowForTest
);
31 config_
.SetInitialStreamFlowControlWindowToSend(
32 kInitialStreamFlowControlWindowForTest
);
33 config_
.SetInitialSessionFlowControlWindowToSend(
34 kInitialSessionFlowControlWindowForTest
);
35 config_
.SetIdleConnectionStateLifetime(QuicTime::Delta::FromSeconds(5),
36 QuicTime::Delta::FromSeconds(2));
37 config_
.SetMaxStreamsPerConnection(4, 2);
38 config_
.SetSocketReceiveBufferToSend(kDefaultSocketReceiveBuffer
);
39 CryptoHandshakeMessage msg
;
40 config_
.ToHandshakeMessage(&msg
);
43 QuicErrorCode error
= msg
.GetUint32(kICSL
, &value
);
44 EXPECT_EQ(QUIC_NO_ERROR
, error
);
47 error
= msg
.GetUint32(kMSPC
, &value
);
48 EXPECT_EQ(QUIC_NO_ERROR
, error
);
51 error
= msg
.GetUint32(kIFCW
, &value
);
52 EXPECT_EQ(QUIC_NO_ERROR
, error
);
53 EXPECT_EQ(kInitialSessionFlowControlWindowForTest
, value
);
55 error
= msg
.GetUint32(kSFCW
, &value
);
56 EXPECT_EQ(QUIC_NO_ERROR
, error
);
57 EXPECT_EQ(kInitialStreamFlowControlWindowForTest
, value
);
59 error
= msg
.GetUint32(kCFCW
, &value
);
60 EXPECT_EQ(QUIC_NO_ERROR
, error
);
61 EXPECT_EQ(kInitialSessionFlowControlWindowForTest
, value
);
63 error
= msg
.GetUint32(kSRBF
, &value
);
64 EXPECT_EQ(QUIC_NO_ERROR
, error
);
65 EXPECT_EQ(kDefaultSocketReceiveBuffer
, value
);
69 error
= msg
.GetTaglist(kCGST
, &out
, &out_len
);
70 EXPECT_EQ(1u, out_len
);
71 EXPECT_EQ(kQBIC
, *out
);
74 TEST_F(QuicConfigTest
, ProcessClientHello
) {
75 QuicConfig client_config
;
77 cgst
.push_back(kQBIC
);
78 client_config
.SetCongestionFeedback(cgst
, kQBIC
);
79 client_config
.SetIdleConnectionStateLifetime(
80 QuicTime::Delta::FromSeconds(2 * kMaximumIdleTimeoutSecs
),
81 QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs
));
82 client_config
.SetMaxStreamsPerConnection(
83 2 * kDefaultMaxStreamsPerConnection
, kDefaultMaxStreamsPerConnection
);
84 client_config
.SetInitialRoundTripTimeUsToSend(10 * kNumMicrosPerMilli
);
85 client_config
.SetInitialFlowControlWindowToSend(
86 2 * kInitialSessionFlowControlWindowForTest
);
87 client_config
.SetInitialStreamFlowControlWindowToSend(
88 2 * kInitialStreamFlowControlWindowForTest
);
89 client_config
.SetInitialSessionFlowControlWindowToSend(
90 2 * kInitialSessionFlowControlWindowForTest
);
91 client_config
.SetSocketReceiveBufferToSend(kDefaultSocketReceiveBuffer
);
93 copt
.push_back(kTBBR
);
94 copt
.push_back(kFHDR
);
95 client_config
.SetConnectionOptionsToSend(copt
);
96 CryptoHandshakeMessage msg
;
97 client_config
.ToHandshakeMessage(&msg
);
99 const QuicErrorCode error
=
100 config_
.ProcessPeerHello(msg
, CLIENT
, &error_details
);
101 EXPECT_EQ(QUIC_NO_ERROR
, error
);
102 EXPECT_TRUE(config_
.negotiated());
103 EXPECT_EQ(kQBIC
, config_
.CongestionFeedback());
104 EXPECT_EQ(QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs
),
105 config_
.IdleConnectionStateLifetime());
106 EXPECT_EQ(kDefaultMaxStreamsPerConnection
,
107 config_
.MaxStreamsPerConnection());
108 EXPECT_EQ(QuicTime::Delta::FromSeconds(0), config_
.KeepaliveTimeout());
109 EXPECT_EQ(10 * kNumMicrosPerMilli
, config_
.ReceivedInitialRoundTripTimeUs());
110 EXPECT_TRUE(config_
.HasReceivedConnectionOptions());
111 EXPECT_EQ(2u, config_
.ReceivedConnectionOptions().size());
112 EXPECT_EQ(config_
.ReceivedConnectionOptions()[0], kTBBR
);
113 EXPECT_EQ(config_
.ReceivedConnectionOptions()[1], kFHDR
);
114 EXPECT_EQ(config_
.ReceivedInitialFlowControlWindowBytes(),
115 2 * kInitialSessionFlowControlWindowForTest
);
116 EXPECT_EQ(config_
.ReceivedInitialStreamFlowControlWindowBytes(),
117 2 * kInitialStreamFlowControlWindowForTest
);
118 EXPECT_EQ(config_
.ReceivedInitialSessionFlowControlWindowBytes(),
119 2 * kInitialSessionFlowControlWindowForTest
);
120 EXPECT_EQ(config_
.ReceivedSocketReceiveBuffer(),
121 kDefaultSocketReceiveBuffer
);
124 TEST_F(QuicConfigTest
, ProcessServerHello
) {
125 QuicConfig server_config
;
127 cgst
.push_back(kQBIC
);
128 server_config
.SetCongestionFeedback(cgst
, kQBIC
);
129 server_config
.SetIdleConnectionStateLifetime(
130 QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs
/ 2),
131 QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs
/ 2));
132 server_config
.SetMaxStreamsPerConnection(
133 kDefaultMaxStreamsPerConnection
/ 2,
134 kDefaultMaxStreamsPerConnection
/ 2);
135 server_config
.SetInitialRoundTripTimeUsToSend(10 * kNumMicrosPerMilli
);
136 server_config
.SetInitialFlowControlWindowToSend(
137 2 * kInitialSessionFlowControlWindowForTest
);
138 server_config
.SetInitialStreamFlowControlWindowToSend(
139 2 * kInitialStreamFlowControlWindowForTest
);
140 server_config
.SetInitialSessionFlowControlWindowToSend(
141 2 * kInitialSessionFlowControlWindowForTest
);
142 server_config
.SetSocketReceiveBufferToSend(kDefaultSocketReceiveBuffer
);
143 CryptoHandshakeMessage msg
;
144 server_config
.ToHandshakeMessage(&msg
);
145 string error_details
;
146 const QuicErrorCode error
=
147 config_
.ProcessPeerHello(msg
, SERVER
, &error_details
);
148 EXPECT_EQ(QUIC_NO_ERROR
, error
);
149 EXPECT_TRUE(config_
.negotiated());
150 EXPECT_EQ(kQBIC
, config_
.CongestionFeedback());
151 EXPECT_EQ(QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs
/ 2),
152 config_
.IdleConnectionStateLifetime());
153 EXPECT_EQ(kDefaultMaxStreamsPerConnection
/ 2,
154 config_
.MaxStreamsPerConnection());
155 EXPECT_EQ(QuicTime::Delta::FromSeconds(0), config_
.KeepaliveTimeout());
156 EXPECT_EQ(10 * kNumMicrosPerMilli
, config_
.ReceivedInitialRoundTripTimeUs());
157 EXPECT_EQ(config_
.ReceivedInitialFlowControlWindowBytes(),
158 2 * kInitialSessionFlowControlWindowForTest
);
159 EXPECT_EQ(config_
.ReceivedInitialStreamFlowControlWindowBytes(),
160 2 * kInitialStreamFlowControlWindowForTest
);
161 EXPECT_EQ(config_
.ReceivedInitialSessionFlowControlWindowBytes(),
162 2 * kInitialSessionFlowControlWindowForTest
);
163 EXPECT_EQ(config_
.ReceivedSocketReceiveBuffer(),
164 kDefaultSocketReceiveBuffer
);
167 TEST_F(QuicConfigTest
, MissingOptionalValuesInCHLO
) {
168 CryptoHandshakeMessage msg
;
169 msg
.SetValue(kICSL
, 1);
170 msg
.SetVector(kCGST
, QuicTagVector(1, kQBIC
));
172 // Set all REQUIRED tags.
173 msg
.SetValue(kICSL
, 1);
174 msg
.SetVector(kCGST
, QuicTagVector(1, kQBIC
));
175 msg
.SetValue(kMSPC
, 1);
177 // No error, as rest are optional.
178 string error_details
;
179 const QuicErrorCode error
=
180 config_
.ProcessPeerHello(msg
, CLIENT
, &error_details
);
181 EXPECT_EQ(QUIC_NO_ERROR
, error
);
183 EXPECT_FALSE(config_
.HasReceivedInitialFlowControlWindowBytes());
186 TEST_F(QuicConfigTest
, MissingOptionalValuesInSHLO
) {
187 CryptoHandshakeMessage msg
;
189 // Set all REQUIRED tags.
190 msg
.SetValue(kICSL
, 1);
191 msg
.SetVector(kCGST
, QuicTagVector(1, kQBIC
));
192 msg
.SetValue(kMSPC
, 1);
194 // No error, as rest are optional.
195 string error_details
;
196 const QuicErrorCode error
=
197 config_
.ProcessPeerHello(msg
, SERVER
, &error_details
);
198 EXPECT_EQ(QUIC_NO_ERROR
, error
);
200 EXPECT_FALSE(config_
.HasReceivedInitialFlowControlWindowBytes());
203 TEST_F(QuicConfigTest
, MissingValueInCHLO
) {
204 CryptoHandshakeMessage msg
;
205 msg
.SetValue(kICSL
, 1);
206 msg
.SetVector(kCGST
, QuicTagVector(1, kQBIC
));
207 // Missing kMSPC. KATO is optional.
208 string error_details
;
209 const QuicErrorCode error
=
210 config_
.ProcessPeerHello(msg
, CLIENT
, &error_details
);
211 EXPECT_EQ(QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND
, error
);
214 TEST_F(QuicConfigTest
, MissingValueInSHLO
) {
215 CryptoHandshakeMessage msg
;
216 msg
.SetValue(kICSL
, 1);
217 msg
.SetValue(kMSPC
, 3);
218 // Missing CGST. KATO is optional.
219 string error_details
;
220 const QuicErrorCode error
=
221 config_
.ProcessPeerHello(msg
, SERVER
, &error_details
);
222 EXPECT_EQ(QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND
, error
);
225 TEST_F(QuicConfigTest
, OutOfBoundSHLO
) {
226 QuicConfig server_config
;
227 server_config
.SetIdleConnectionStateLifetime(
228 QuicTime::Delta::FromSeconds(2 * kMaximumIdleTimeoutSecs
),
229 QuicTime::Delta::FromSeconds(2 * kMaximumIdleTimeoutSecs
));
231 CryptoHandshakeMessage msg
;
232 server_config
.ToHandshakeMessage(&msg
);
233 string error_details
;
234 const QuicErrorCode error
=
235 config_
.ProcessPeerHello(msg
, SERVER
, &error_details
);
236 EXPECT_EQ(QUIC_INVALID_NEGOTIATED_VALUE
, error
);
239 TEST_F(QuicConfigTest
, MultipleNegotiatedValuesInVectorTag
) {
240 QuicConfig server_config
;
242 cgst
.push_back(kQBIC
);
243 cgst
.push_back(kTBBR
);
244 server_config
.SetCongestionFeedback(cgst
, kQBIC
);
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
, NoOverLapInCGST
) {
255 QuicConfig server_config
;
257 cgst
.push_back(kTBBR
);
258 server_config
.SetCongestionFeedback(cgst
, kTBBR
);
260 CryptoHandshakeMessage msg
;
261 string error_details
;
262 server_config
.ToHandshakeMessage(&msg
);
263 const QuicErrorCode error
=
264 config_
.ProcessPeerHello(msg
, CLIENT
, &error_details
);
265 DVLOG(1) << QuicUtils::ErrorToString(error
);
266 EXPECT_EQ(QUIC_CRYPTO_MESSAGE_PARAMETER_NO_OVERLAP
, error
);
269 TEST_F(QuicConfigTest
, InvalidFlowControlWindow
) {
270 // QuicConfig should not accept an invalid flow control window to send to the
271 // peer: the receive window must be at least the default of 16 Kb.
273 const uint64 kInvalidWindow
= kDefaultFlowControlSendWindow
- 1;
274 EXPECT_DFATAL(config
.SetInitialFlowControlWindowToSend(kInvalidWindow
),
275 "Initial flow control receive window");
277 EXPECT_EQ(kDefaultFlowControlSendWindow
,
278 config
.GetInitialFlowControlWindowToSend());