• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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