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.h"
8#include "net/quic/crypto/crypto_protocol.h"
9#include "net/quic/quic_protocol.h"
10#include "net/quic/quic_sent_packet_manager.h"
11#include "net/quic/quic_time.h"
12#include "net/quic/test_tools/quic_test_utils.h"
13#include "testing/gtest/include/gtest/gtest.h"
14
15using std::string;
16
17namespace net {
18namespace test {
19namespace {
20
21class QuicConfigTest : public ::testing::Test {
22 protected:
23  QuicConfigTest() {
24    config_.SetDefaults();
25    config_.set_initial_round_trip_time_us(kMaxInitialRoundTripTimeUs, 0);
26  }
27
28  QuicConfig config_;
29};
30
31TEST_F(QuicConfigTest, ToHandshakeMessage) {
32  FLAGS_enable_quic_pacing = false;
33  config_.SetDefaults();
34  config_.set_idle_connection_state_lifetime(QuicTime::Delta::FromSeconds(5),
35                                             QuicTime::Delta::FromSeconds(2));
36  config_.set_max_streams_per_connection(4, 2);
37  CryptoHandshakeMessage msg;
38  config_.ToHandshakeMessage(&msg);
39
40  uint32 value;
41  QuicErrorCode error = msg.GetUint32(kICSL, &value);
42  EXPECT_EQ(QUIC_NO_ERROR, error);
43  EXPECT_EQ(5u, value);
44
45  error = msg.GetUint32(kMSPC, &value);
46  EXPECT_EQ(QUIC_NO_ERROR, error);
47  EXPECT_EQ(4u, value);
48
49  const QuicTag* out;
50  size_t out_len;
51  error = msg.GetTaglist(kCGST, &out, &out_len);
52  EXPECT_EQ(1u, out_len);
53  EXPECT_EQ(kQBIC, *out);
54}
55
56TEST_F(QuicConfigTest, ToHandshakeMessageWithPacing) {
57  ValueRestore<bool> old_flag(&FLAGS_enable_quic_pacing, true);
58
59  config_.SetDefaults();
60  CryptoHandshakeMessage msg;
61  config_.ToHandshakeMessage(&msg);
62
63  const QuicTag* out;
64  size_t out_len;
65  EXPECT_EQ(QUIC_NO_ERROR, msg.GetTaglist(kCGST, &out, &out_len));
66  EXPECT_EQ(2u, out_len);
67  EXPECT_EQ(kPACE, out[0]);
68  EXPECT_EQ(kQBIC, out[1]);
69}
70
71TEST_F(QuicConfigTest, ProcessClientHello) {
72  QuicConfig client_config;
73  QuicTagVector cgst;
74  cgst.push_back(kINAR);
75  cgst.push_back(kQBIC);
76  client_config.set_congestion_control(cgst, kQBIC);
77  client_config.set_idle_connection_state_lifetime(
78      QuicTime::Delta::FromSeconds(2 * kDefaultTimeoutSecs),
79      QuicTime::Delta::FromSeconds(kDefaultTimeoutSecs));
80  client_config.set_max_streams_per_connection(
81      2 * kDefaultMaxStreamsPerConnection, kDefaultMaxStreamsPerConnection);
82  client_config.set_initial_round_trip_time_us(
83      10 * base::Time::kMicrosecondsPerMillisecond,
84      10 * base::Time::kMicrosecondsPerMillisecond);
85
86  CryptoHandshakeMessage msg;
87  client_config.ToHandshakeMessage(&msg);
88  string error_details;
89  const QuicErrorCode error = config_.ProcessClientHello(msg, &error_details);
90  EXPECT_EQ(QUIC_NO_ERROR, error);
91  EXPECT_TRUE(config_.negotiated());
92  EXPECT_EQ(kQBIC, config_.congestion_control());
93  EXPECT_EQ(QuicTime::Delta::FromSeconds(kDefaultTimeoutSecs),
94            config_.idle_connection_state_lifetime());
95  EXPECT_EQ(kDefaultMaxStreamsPerConnection,
96            config_.max_streams_per_connection());
97  EXPECT_EQ(QuicTime::Delta::FromSeconds(0), config_.keepalive_timeout());
98  EXPECT_EQ(10 * base::Time::kMicrosecondsPerMillisecond,
99            config_.initial_round_trip_time_us());
100}
101
102TEST_F(QuicConfigTest, ProcessServerHello) {
103  QuicConfig server_config;
104  QuicTagVector cgst;
105  cgst.push_back(kQBIC);
106  server_config.set_congestion_control(cgst, kQBIC);
107  server_config.set_idle_connection_state_lifetime(
108      QuicTime::Delta::FromSeconds(kDefaultTimeoutSecs / 2),
109      QuicTime::Delta::FromSeconds(kDefaultTimeoutSecs / 2));
110  server_config.set_max_streams_per_connection(
111      kDefaultMaxStreamsPerConnection / 2,
112      kDefaultMaxStreamsPerConnection / 2);
113  server_config.set_server_initial_congestion_window(kDefaultInitialWindow / 2,
114                                                     kDefaultInitialWindow / 2);
115  server_config.set_initial_round_trip_time_us(
116      10 * base::Time::kMicrosecondsPerMillisecond,
117      10 * base::Time::kMicrosecondsPerMillisecond);
118
119  CryptoHandshakeMessage msg;
120  server_config.ToHandshakeMessage(&msg);
121  string error_details;
122  const QuicErrorCode error = config_.ProcessServerHello(msg, &error_details);
123  EXPECT_EQ(QUIC_NO_ERROR, error);
124  EXPECT_TRUE(config_.negotiated());
125  EXPECT_EQ(kQBIC, config_.congestion_control());
126  EXPECT_EQ(QuicTime::Delta::FromSeconds(kDefaultTimeoutSecs / 2),
127            config_.idle_connection_state_lifetime());
128  EXPECT_EQ(kDefaultMaxStreamsPerConnection / 2,
129            config_.max_streams_per_connection());
130  EXPECT_EQ(kDefaultInitialWindow / 2,
131            config_.server_initial_congestion_window());
132  EXPECT_EQ(QuicTime::Delta::FromSeconds(0), config_.keepalive_timeout());
133  EXPECT_EQ(10 * base::Time::kMicrosecondsPerMillisecond,
134            config_.initial_round_trip_time_us());
135}
136
137TEST_F(QuicConfigTest, MissingValueInCHLO) {
138  CryptoHandshakeMessage msg;
139  msg.SetValue(kICSL, 1);
140  msg.SetVector(kCGST, QuicTagVector(1, kQBIC));
141  // Missing kMSPC. KATO is optional.
142  string error_details;
143  const QuicErrorCode error = config_.ProcessClientHello(msg, &error_details);
144  EXPECT_EQ(QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND, error);
145}
146
147TEST_F(QuicConfigTest, MissingValueInSHLO) {
148  CryptoHandshakeMessage msg;
149  msg.SetValue(kICSL, 1);
150  msg.SetValue(kMSPC, 3);
151  // Missing CGST. KATO is optional.
152  string error_details;
153  const QuicErrorCode error = config_.ProcessServerHello(msg, &error_details);
154  EXPECT_EQ(QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND, error);
155}
156
157TEST_F(QuicConfigTest, OutOfBoundSHLO) {
158  QuicConfig server_config;
159  server_config.set_idle_connection_state_lifetime(
160      QuicTime::Delta::FromSeconds(2 * kDefaultTimeoutSecs),
161      QuicTime::Delta::FromSeconds(2 * kDefaultTimeoutSecs));
162
163  CryptoHandshakeMessage msg;
164  server_config.ToHandshakeMessage(&msg);
165  string error_details;
166  const QuicErrorCode error = config_.ProcessServerHello(msg, &error_details);
167  EXPECT_EQ(QUIC_INVALID_NEGOTIATED_VALUE, error);
168}
169
170TEST_F(QuicConfigTest, MultipleNegotiatedValuesInVectorTag) {
171  QuicConfig server_config;
172  QuicTagVector cgst;
173  cgst.push_back(kQBIC);
174  cgst.push_back(kINAR);
175  server_config.set_congestion_control(cgst, kQBIC);
176
177  CryptoHandshakeMessage msg;
178  server_config.ToHandshakeMessage(&msg);
179  string error_details;
180  const QuicErrorCode error = config_.ProcessServerHello(msg, &error_details);
181  EXPECT_EQ(QUIC_INVALID_NEGOTIATED_VALUE, error);
182}
183
184TEST_F(QuicConfigTest, NoOverLapInCGST) {
185  QuicConfig server_config;
186  server_config.SetDefaults();
187  QuicTagVector cgst;
188  cgst.push_back(kINAR);
189  server_config.set_congestion_control(cgst, kINAR);
190
191  CryptoHandshakeMessage msg;
192  string error_details;
193  server_config.ToHandshakeMessage(&msg);
194  const QuicErrorCode error = config_.ProcessClientHello(msg, &error_details);
195  LOG(INFO) << QuicUtils::ErrorToString(error);
196  EXPECT_EQ(QUIC_CRYPTO_MESSAGE_PARAMETER_NO_OVERLAP, error);
197}
198
199}  // namespace
200}  // namespace test
201}  // namespace net
202