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: 25 QuicConfigTest() { 26 config_.SetDefaults(); 27 } 28 29 QuicConfig config_; 30 }; 31 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 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 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 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 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 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 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 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 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 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 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