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_config_peer.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
{
29 TEST_F(QuicConfigTest
, ToHandshakeMessage
) {
30 config_
.SetInitialStreamFlowControlWindowToSend(
31 kInitialStreamFlowControlWindowForTest
);
32 config_
.SetInitialSessionFlowControlWindowToSend(
33 kInitialSessionFlowControlWindowForTest
);
34 config_
.SetIdleConnectionStateLifetime(QuicTime::Delta::FromSeconds(5),
35 QuicTime::Delta::FromSeconds(2));
36 config_
.SetMaxStreamsPerConnection(4, 2);
37 config_
.SetSocketReceiveBufferToSend(kDefaultSocketReceiveBuffer
);
38 CryptoHandshakeMessage msg
;
39 config_
.ToHandshakeMessage(&msg
);
42 QuicErrorCode error
= msg
.GetUint32(kICSL
, &value
);
43 EXPECT_EQ(QUIC_NO_ERROR
, error
);
46 error
= msg
.GetUint32(kMSPC
, &value
);
47 EXPECT_EQ(QUIC_NO_ERROR
, error
);
50 error
= msg
.GetUint32(kSFCW
, &value
);
51 EXPECT_EQ(QUIC_NO_ERROR
, error
);
52 EXPECT_EQ(kInitialStreamFlowControlWindowForTest
, value
);
54 error
= msg
.GetUint32(kCFCW
, &value
);
55 EXPECT_EQ(QUIC_NO_ERROR
, error
);
56 EXPECT_EQ(kInitialSessionFlowControlWindowForTest
, value
);
58 error
= msg
.GetUint32(kSRBF
, &value
);
59 EXPECT_EQ(QUIC_NO_ERROR
, error
);
60 EXPECT_EQ(kDefaultSocketReceiveBuffer
, value
);
63 TEST_F(QuicConfigTest
, ProcessClientHello
) {
64 QuicConfig client_config
;
66 cgst
.push_back(kQBIC
);
67 client_config
.SetIdleConnectionStateLifetime(
68 QuicTime::Delta::FromSeconds(2 * kMaximumIdleTimeoutSecs
),
69 QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs
));
70 client_config
.SetMaxStreamsPerConnection(
71 2 * kDefaultMaxStreamsPerConnection
, kDefaultMaxStreamsPerConnection
);
72 client_config
.SetInitialRoundTripTimeUsToSend(10 * kNumMicrosPerMilli
);
73 client_config
.SetInitialStreamFlowControlWindowToSend(
74 2 * kInitialStreamFlowControlWindowForTest
);
75 client_config
.SetInitialSessionFlowControlWindowToSend(
76 2 * kInitialSessionFlowControlWindowForTest
);
77 client_config
.SetSocketReceiveBufferToSend(kDefaultSocketReceiveBuffer
);
79 copt
.push_back(kTBBR
);
80 copt
.push_back(kFHDR
);
81 client_config
.SetConnectionOptionsToSend(copt
);
82 CryptoHandshakeMessage msg
;
83 client_config
.ToHandshakeMessage(&msg
);
86 QuicTagVector initial_received_options
;
87 initial_received_options
.push_back(kIW50
);
89 config_
.SetInitialReceivedConnectionOptions(initial_received_options
));
91 config_
.SetInitialReceivedConnectionOptions(initial_received_options
))
92 << "You can only set initial options once.";
93 const QuicErrorCode error
=
94 config_
.ProcessPeerHello(msg
, CLIENT
, &error_details
);
96 config_
.SetInitialReceivedConnectionOptions(initial_received_options
))
97 << "You cannot set initial options after the hello.";
98 EXPECT_EQ(QUIC_NO_ERROR
, error
);
99 EXPECT_TRUE(config_
.negotiated());
100 EXPECT_EQ(QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs
),
101 config_
.IdleConnectionStateLifetime());
102 EXPECT_EQ(kDefaultMaxStreamsPerConnection
,
103 config_
.MaxStreamsPerConnection());
104 EXPECT_EQ(10 * kNumMicrosPerMilli
, config_
.ReceivedInitialRoundTripTimeUs());
105 EXPECT_TRUE(config_
.HasReceivedConnectionOptions());
106 EXPECT_EQ(3u, config_
.ReceivedConnectionOptions().size());
107 EXPECT_EQ(config_
.ReceivedConnectionOptions()[0], kIW50
);
108 EXPECT_EQ(config_
.ReceivedConnectionOptions()[1], kTBBR
);
109 EXPECT_EQ(config_
.ReceivedConnectionOptions()[2], kFHDR
);
110 EXPECT_EQ(config_
.ReceivedInitialStreamFlowControlWindowBytes(),
111 2 * kInitialStreamFlowControlWindowForTest
);
112 EXPECT_EQ(config_
.ReceivedInitialSessionFlowControlWindowBytes(),
113 2 * kInitialSessionFlowControlWindowForTest
);
114 EXPECT_EQ(config_
.ReceivedSocketReceiveBuffer(),
115 kDefaultSocketReceiveBuffer
);
118 TEST_F(QuicConfigTest
, ProcessServerHello
) {
119 QuicConfig server_config
;
121 cgst
.push_back(kQBIC
);
122 server_config
.SetIdleConnectionStateLifetime(
123 QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs
/ 2),
124 QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs
/ 2));
125 server_config
.SetMaxStreamsPerConnection(
126 kDefaultMaxStreamsPerConnection
/ 2,
127 kDefaultMaxStreamsPerConnection
/ 2);
128 server_config
.SetInitialRoundTripTimeUsToSend(10 * kNumMicrosPerMilli
);
129 server_config
.SetInitialStreamFlowControlWindowToSend(
130 2 * kInitialStreamFlowControlWindowForTest
);
131 server_config
.SetInitialSessionFlowControlWindowToSend(
132 2 * kInitialSessionFlowControlWindowForTest
);
133 server_config
.SetSocketReceiveBufferToSend(kDefaultSocketReceiveBuffer
);
134 CryptoHandshakeMessage msg
;
135 server_config
.ToHandshakeMessage(&msg
);
136 string error_details
;
137 const QuicErrorCode error
=
138 config_
.ProcessPeerHello(msg
, SERVER
, &error_details
);
139 EXPECT_EQ(QUIC_NO_ERROR
, error
);
140 EXPECT_TRUE(config_
.negotiated());
141 EXPECT_EQ(QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs
/ 2),
142 config_
.IdleConnectionStateLifetime());
143 EXPECT_EQ(kDefaultMaxStreamsPerConnection
/ 2,
144 config_
.MaxStreamsPerConnection());
145 EXPECT_EQ(10 * kNumMicrosPerMilli
, config_
.ReceivedInitialRoundTripTimeUs());
146 EXPECT_EQ(config_
.ReceivedInitialStreamFlowControlWindowBytes(),
147 2 * kInitialStreamFlowControlWindowForTest
);
148 EXPECT_EQ(config_
.ReceivedInitialSessionFlowControlWindowBytes(),
149 2 * kInitialSessionFlowControlWindowForTest
);
150 EXPECT_EQ(config_
.ReceivedSocketReceiveBuffer(),
151 kDefaultSocketReceiveBuffer
);
154 TEST_F(QuicConfigTest
, MissingOptionalValuesInCHLO
) {
155 CryptoHandshakeMessage msg
;
156 msg
.SetValue(kICSL
, 1);
158 // Set all REQUIRED tags.
159 msg
.SetValue(kICSL
, 1);
160 msg
.SetValue(kMSPC
, 1);
162 // No error, as rest are optional.
163 string error_details
;
164 const QuicErrorCode error
=
165 config_
.ProcessPeerHello(msg
, CLIENT
, &error_details
);
166 EXPECT_EQ(QUIC_NO_ERROR
, error
);
167 EXPECT_TRUE(config_
.negotiated());
170 TEST_F(QuicConfigTest
, MissingOptionalValuesInSHLO
) {
171 CryptoHandshakeMessage msg
;
173 // Set all REQUIRED tags.
174 msg
.SetValue(kICSL
, 1);
175 msg
.SetValue(kMSPC
, 1);
177 // No error, as rest are optional.
178 string error_details
;
179 const QuicErrorCode error
=
180 config_
.ProcessPeerHello(msg
, SERVER
, &error_details
);
181 EXPECT_EQ(QUIC_NO_ERROR
, error
);
182 EXPECT_TRUE(config_
.negotiated());
185 TEST_F(QuicConfigTest
, MissingValueInCHLO
) {
186 CryptoHandshakeMessage msg
;
187 msg
.SetValue(kICSL
, 1);
188 // Missing kMSPC. KATO is optional.
189 string error_details
;
190 const QuicErrorCode error
=
191 config_
.ProcessPeerHello(msg
, CLIENT
, &error_details
);
192 EXPECT_EQ(QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND
, error
);
195 TEST_F(QuicConfigTest
, MissingValueInSHLO
) {
196 CryptoHandshakeMessage msg
;
197 msg
.SetValue(kMSPC
, 3);
198 // Missing ICSL. KATO is optional.
199 string error_details
;
200 const QuicErrorCode error
=
201 config_
.ProcessPeerHello(msg
, SERVER
, &error_details
);
202 EXPECT_EQ(QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND
, error
);
205 TEST_F(QuicConfigTest
, OutOfBoundSHLO
) {
206 QuicConfig server_config
;
207 server_config
.SetIdleConnectionStateLifetime(
208 QuicTime::Delta::FromSeconds(2 * kMaximumIdleTimeoutSecs
),
209 QuicTime::Delta::FromSeconds(2 * kMaximumIdleTimeoutSecs
));
211 CryptoHandshakeMessage msg
;
212 server_config
.ToHandshakeMessage(&msg
);
213 string error_details
;
214 const QuicErrorCode error
=
215 config_
.ProcessPeerHello(msg
, SERVER
, &error_details
);
216 EXPECT_EQ(QUIC_INVALID_NEGOTIATED_VALUE
, error
);
219 TEST_F(QuicConfigTest
, InvalidFlowControlWindow
) {
220 // QuicConfig should not accept an invalid flow control window to send to the
221 // peer: the receive window must be at least the default of 16 Kb.
223 const uint64 kInvalidWindow
= kMinimumFlowControlSendWindow
- 1;
224 EXPECT_DFATAL(config
.SetInitialStreamFlowControlWindowToSend(kInvalidWindow
),
225 "Initial stream flow control receive window");
227 EXPECT_EQ(kMinimumFlowControlSendWindow
,
228 config
.GetInitialStreamFlowControlWindowToSend());
231 TEST_F(QuicConfigTest
, HasClientSentConnectionOption
) {
232 QuicConfig client_config
;
234 copt
.push_back(kTBBR
);
235 copt
.push_back(kFHDR
);
236 client_config
.SetConnectionOptionsToSend(copt
);
237 EXPECT_TRUE(client_config
.HasClientSentConnectionOption(
238 kTBBR
, Perspective::IS_CLIENT
));
239 EXPECT_TRUE(client_config
.HasClientSentConnectionOption(
240 kFHDR
, Perspective::IS_CLIENT
));
242 CryptoHandshakeMessage msg
;
243 client_config
.ToHandshakeMessage(&msg
);
245 string error_details
;
246 const QuicErrorCode error
=
247 config_
.ProcessPeerHello(msg
, CLIENT
, &error_details
);
248 EXPECT_EQ(QUIC_NO_ERROR
, error
);
249 EXPECT_TRUE(config_
.negotiated());
251 EXPECT_TRUE(config_
.HasReceivedConnectionOptions());
252 EXPECT_EQ(2u, config_
.ReceivedConnectionOptions().size());
254 config_
.HasClientSentConnectionOption(kTBBR
, Perspective::IS_SERVER
));
256 config_
.HasClientSentConnectionOption(kFHDR
, Perspective::IS_SERVER
));