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
17using std::string;
18
19namespace net {
20namespace test {
21namespace {
22
23class QuicConfigTest : public ::testing::Test {
24 protected:
25  QuicConfigTest() {
26    config_.SetDefaults();
27  }
28
29  QuicConfig config_;
30};
31
32TEST_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
79TEST_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
132TEST_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
181TEST_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
200TEST_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
217TEST_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
228TEST_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
239TEST_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
253TEST_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
268TEST_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
284TEST_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