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
);
64 error
= msg
.GetTaglist(kCGST
, &out
, &out_len
);
65 EXPECT_EQ(1u, out_len
);
66 EXPECT_EQ(kQBIC
, *out
);
69 TEST_F(QuicConfigTest
, ProcessClientHello
) {
70 QuicConfig client_config
;
72 cgst
.push_back(kQBIC
);
73 client_config
.SetIdleConnectionStateLifetime(
74 QuicTime::Delta::FromSeconds(2 * kMaximumIdleTimeoutSecs
),
75 QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs
));
76 client_config
.SetMaxStreamsPerConnection(
77 2 * kDefaultMaxStreamsPerConnection
, kDefaultMaxStreamsPerConnection
);
78 client_config
.SetInitialRoundTripTimeUsToSend(10 * kNumMicrosPerMilli
);
79 client_config
.SetInitialStreamFlowControlWindowToSend(
80 2 * kInitialStreamFlowControlWindowForTest
);
81 client_config
.SetInitialSessionFlowControlWindowToSend(
82 2 * kInitialSessionFlowControlWindowForTest
);
83 client_config
.SetSocketReceiveBufferToSend(kDefaultSocketReceiveBuffer
);
85 copt
.push_back(kTBBR
);
86 copt
.push_back(kFHDR
);
87 client_config
.SetConnectionOptionsToSend(copt
);
88 CryptoHandshakeMessage msg
;
89 client_config
.ToHandshakeMessage(&msg
);
92 const QuicErrorCode error
=
93 config_
.ProcessPeerHello(msg
, CLIENT
, &error_details
);
94 EXPECT_EQ(QUIC_NO_ERROR
, error
);
95 EXPECT_TRUE(config_
.negotiated());
96 EXPECT_EQ(QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs
),
97 config_
.IdleConnectionStateLifetime());
98 EXPECT_EQ(kDefaultMaxStreamsPerConnection
,
99 config_
.MaxStreamsPerConnection());
100 EXPECT_EQ(10 * kNumMicrosPerMilli
, config_
.ReceivedInitialRoundTripTimeUs());
101 EXPECT_TRUE(config_
.HasReceivedConnectionOptions());
102 EXPECT_EQ(2u, config_
.ReceivedConnectionOptions().size());
103 EXPECT_EQ(config_
.ReceivedConnectionOptions()[0], kTBBR
);
104 EXPECT_EQ(config_
.ReceivedConnectionOptions()[1], kFHDR
);
105 EXPECT_EQ(config_
.ReceivedInitialStreamFlowControlWindowBytes(),
106 2 * kInitialStreamFlowControlWindowForTest
);
107 EXPECT_EQ(config_
.ReceivedInitialSessionFlowControlWindowBytes(),
108 2 * kInitialSessionFlowControlWindowForTest
);
109 EXPECT_EQ(config_
.ReceivedSocketReceiveBuffer(),
110 kDefaultSocketReceiveBuffer
);
113 TEST_F(QuicConfigTest
, ProcessServerHello
) {
114 QuicConfig server_config
;
116 cgst
.push_back(kQBIC
);
117 server_config
.SetIdleConnectionStateLifetime(
118 QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs
/ 2),
119 QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs
/ 2));
120 server_config
.SetMaxStreamsPerConnection(
121 kDefaultMaxStreamsPerConnection
/ 2,
122 kDefaultMaxStreamsPerConnection
/ 2);
123 server_config
.SetInitialRoundTripTimeUsToSend(10 * kNumMicrosPerMilli
);
124 server_config
.SetInitialStreamFlowControlWindowToSend(
125 2 * kInitialStreamFlowControlWindowForTest
);
126 server_config
.SetInitialSessionFlowControlWindowToSend(
127 2 * kInitialSessionFlowControlWindowForTest
);
128 server_config
.SetSocketReceiveBufferToSend(kDefaultSocketReceiveBuffer
);
129 CryptoHandshakeMessage msg
;
130 server_config
.ToHandshakeMessage(&msg
);
131 string error_details
;
132 const QuicErrorCode error
=
133 config_
.ProcessPeerHello(msg
, SERVER
, &error_details
);
134 EXPECT_EQ(QUIC_NO_ERROR
, error
);
135 EXPECT_TRUE(config_
.negotiated());
136 EXPECT_EQ(QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs
/ 2),
137 config_
.IdleConnectionStateLifetime());
138 EXPECT_EQ(kDefaultMaxStreamsPerConnection
/ 2,
139 config_
.MaxStreamsPerConnection());
140 EXPECT_EQ(10 * kNumMicrosPerMilli
, config_
.ReceivedInitialRoundTripTimeUs());
141 EXPECT_EQ(config_
.ReceivedInitialStreamFlowControlWindowBytes(),
142 2 * kInitialStreamFlowControlWindowForTest
);
143 EXPECT_EQ(config_
.ReceivedInitialSessionFlowControlWindowBytes(),
144 2 * kInitialSessionFlowControlWindowForTest
);
145 EXPECT_EQ(config_
.ReceivedSocketReceiveBuffer(),
146 kDefaultSocketReceiveBuffer
);
149 TEST_F(QuicConfigTest
, MissingOptionalValuesInCHLO
) {
150 CryptoHandshakeMessage msg
;
151 msg
.SetValue(kICSL
, 1);
152 msg
.SetVector(kCGST
, QuicTagVector(1, kQBIC
));
154 // Set all REQUIRED tags.
155 msg
.SetValue(kICSL
, 1);
156 msg
.SetVector(kCGST
, QuicTagVector(1, kQBIC
));
157 msg
.SetValue(kMSPC
, 1);
159 // No error, as rest are optional.
160 string error_details
;
161 const QuicErrorCode error
=
162 config_
.ProcessPeerHello(msg
, CLIENT
, &error_details
);
163 EXPECT_EQ(QUIC_NO_ERROR
, error
);
164 EXPECT_TRUE(config_
.negotiated());
167 TEST_F(QuicConfigTest
, MissingOptionalValuesInSHLO
) {
168 CryptoHandshakeMessage msg
;
170 // Set all REQUIRED tags.
171 msg
.SetValue(kICSL
, 1);
172 msg
.SetVector(kCGST
, QuicTagVector(1, kQBIC
));
173 msg
.SetValue(kMSPC
, 1);
175 // No error, as rest are optional.
176 string error_details
;
177 const QuicErrorCode error
=
178 config_
.ProcessPeerHello(msg
, SERVER
, &error_details
);
179 EXPECT_EQ(QUIC_NO_ERROR
, error
);
180 EXPECT_TRUE(config_
.negotiated());
183 TEST_F(QuicConfigTest
, MissingValueInCHLO
) {
184 CryptoHandshakeMessage msg
;
185 msg
.SetValue(kICSL
, 1);
186 msg
.SetVector(kCGST
, QuicTagVector(1, kQBIC
));
187 // Missing kMSPC. KATO is optional.
188 string error_details
;
189 const QuicErrorCode error
=
190 config_
.ProcessPeerHello(msg
, CLIENT
, &error_details
);
191 EXPECT_EQ(QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND
, error
);
194 TEST_F(QuicConfigTest
, MissingValueInSHLO
) {
195 CryptoHandshakeMessage msg
;
196 msg
.SetValue(kMSPC
, 3);
197 // Missing ICSL. KATO is optional.
198 string error_details
;
199 const QuicErrorCode error
=
200 config_
.ProcessPeerHello(msg
, SERVER
, &error_details
);
201 EXPECT_EQ(QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND
, error
);
204 TEST_F(QuicConfigTest
, OutOfBoundSHLO
) {
205 QuicConfig server_config
;
206 server_config
.SetIdleConnectionStateLifetime(
207 QuicTime::Delta::FromSeconds(2 * kMaximumIdleTimeoutSecs
),
208 QuicTime::Delta::FromSeconds(2 * kMaximumIdleTimeoutSecs
));
210 CryptoHandshakeMessage msg
;
211 server_config
.ToHandshakeMessage(&msg
);
212 string error_details
;
213 const QuicErrorCode error
=
214 config_
.ProcessPeerHello(msg
, SERVER
, &error_details
);
215 EXPECT_EQ(QUIC_INVALID_NEGOTIATED_VALUE
, error
);
218 TEST_F(QuicConfigTest
, InvalidFlowControlWindow
) {
219 // QuicConfig should not accept an invalid flow control window to send to the
220 // peer: the receive window must be at least the default of 16 Kb.
222 const uint64 kInvalidWindow
= kMinimumFlowControlSendWindow
- 1;
223 EXPECT_DFATAL(config
.SetInitialStreamFlowControlWindowToSend(kInvalidWindow
),
224 "Initial stream flow control receive window");
226 EXPECT_EQ(kMinimumFlowControlSendWindow
,
227 config
.GetInitialStreamFlowControlWindowToSend());