1 // Copyright 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/tools/quic/quic_server_session.h" 6 7 #include "net/quic/crypto/quic_crypto_server_config.h" 8 #include "net/quic/crypto/quic_random.h" 9 #include "net/quic/crypto/source_address_token.h" 10 #include "net/quic/quic_connection.h" 11 #include "net/quic/quic_crypto_server_stream.h" 12 #include "net/quic/quic_flags.h" 13 #include "net/quic/quic_utils.h" 14 #include "net/quic/test_tools/quic_config_peer.h" 15 #include "net/quic/test_tools/quic_connection_peer.h" 16 #include "net/quic/test_tools/quic_data_stream_peer.h" 17 #include "net/quic/test_tools/quic_sent_packet_manager_peer.h" 18 #include "net/quic/test_tools/quic_session_peer.h" 19 #include "net/quic/test_tools/quic_sustained_bandwidth_recorder_peer.h" 20 #include "net/quic/test_tools/quic_test_utils.h" 21 #include "net/tools/quic/quic_spdy_server_stream.h" 22 #include "net/tools/quic/test_tools/quic_test_utils.h" 23 #include "testing/gmock/include/gmock/gmock.h" 24 #include "testing/gtest/include/gtest/gtest.h" 25 26 using __gnu_cxx::vector; 27 using net::test::MockConnection; 28 using net::test::QuicConfigPeer; 29 using net::test::QuicConnectionPeer; 30 using net::test::QuicDataStreamPeer; 31 using net::test::QuicSentPacketManagerPeer; 32 using net::test::QuicSessionPeer; 33 using net::test::QuicSustainedBandwidthRecorderPeer; 34 using net::test::SupportedVersions; 35 using net::test::ValueRestore; 36 using net::test::kClientDataStreamId1; 37 using net::test::kClientDataStreamId2; 38 using net::test::kClientDataStreamId3; 39 using net::test::kClientDataStreamId4; 40 using testing::StrictMock; 41 using testing::_; 42 43 namespace net { 44 namespace tools { 45 namespace test { 46 47 class QuicServerSessionPeer { 48 public: 49 static QuicDataStream* GetIncomingDataStream( 50 QuicServerSession* s, QuicStreamId id) { 51 return s->GetIncomingDataStream(id); 52 } 53 static QuicDataStream* GetDataStream(QuicServerSession* s, QuicStreamId id) { 54 return s->GetDataStream(id); 55 } 56 static void SetCryptoStream(QuicServerSession* s, 57 QuicCryptoServerStream* crypto_stream) { 58 s->crypto_stream_.reset(crypto_stream); 59 } 60 }; 61 62 namespace { 63 64 const size_t kMaxStreamsForTest = 10; 65 66 class QuicServerSessionTest : public ::testing::TestWithParam<QuicVersion> { 67 protected: 68 QuicServerSessionTest() 69 : crypto_config_(QuicCryptoServerConfig::TESTING, 70 QuicRandom::GetInstance()) { 71 config_.SetDefaults(); 72 config_.set_max_streams_per_connection(kMaxStreamsForTest, 73 kMaxStreamsForTest); 74 config_.SetInitialFlowControlWindowToSend( 75 kInitialSessionFlowControlWindowForTest); 76 config_.SetInitialStreamFlowControlWindowToSend( 77 kInitialStreamFlowControlWindowForTest); 78 config_.SetInitialSessionFlowControlWindowToSend( 79 kInitialSessionFlowControlWindowForTest); 80 81 connection_ = 82 new StrictMock<MockConnection>(true, SupportedVersions(GetParam())); 83 session_.reset(new QuicServerSession(config_, connection_, &owner_)); 84 MockClock clock; 85 handshake_message_.reset(crypto_config_.AddDefaultConfig( 86 QuicRandom::GetInstance(), &clock, 87 QuicCryptoServerConfig::ConfigOptions())); 88 session_->InitializeSession(crypto_config_); 89 visitor_ = QuicConnectionPeer::GetVisitor(connection_); 90 } 91 92 QuicVersion version() const { return connection_->version(); } 93 94 StrictMock<MockQuicServerSessionVisitor> owner_; 95 StrictMock<MockConnection>* connection_; 96 QuicConfig config_; 97 QuicCryptoServerConfig crypto_config_; 98 scoped_ptr<QuicServerSession> session_; 99 scoped_ptr<CryptoHandshakeMessage> handshake_message_; 100 QuicConnectionVisitorInterface* visitor_; 101 }; 102 103 // Compares CachedNetworkParameters. 104 MATCHER_P(EqualsProto, network_params, "") { 105 CachedNetworkParameters reference(network_params); 106 return (arg->bandwidth_estimate_bytes_per_second() == 107 reference.bandwidth_estimate_bytes_per_second() && 108 arg->bandwidth_estimate_bytes_per_second() == 109 reference.bandwidth_estimate_bytes_per_second() && 110 arg->max_bandwidth_estimate_bytes_per_second() == 111 reference.max_bandwidth_estimate_bytes_per_second() && 112 arg->max_bandwidth_timestamp_seconds() == 113 reference.max_bandwidth_timestamp_seconds() && 114 arg->min_rtt_ms() == reference.min_rtt_ms() && 115 arg->previous_connection_state() == 116 reference.previous_connection_state()); 117 } 118 119 INSTANTIATE_TEST_CASE_P(Tests, QuicServerSessionTest, 120 ::testing::ValuesIn(QuicSupportedVersions())); 121 122 TEST_P(QuicServerSessionTest, CloseStreamDueToReset) { 123 // Open a stream, then reset it. 124 // Send two bytes of payload to open it. 125 QuicStreamFrame data1(kClientDataStreamId1, false, 0, MakeIOVector("HT")); 126 vector<QuicStreamFrame> frames; 127 frames.push_back(data1); 128 session_->OnStreamFrames(frames); 129 EXPECT_EQ(1u, session_->GetNumOpenStreams()); 130 131 // Send a reset (and expect the peer to send a RST in response). 132 QuicRstStreamFrame rst1(kClientDataStreamId1, QUIC_STREAM_NO_ERROR, 0); 133 EXPECT_CALL(*connection_, SendRstStream(kClientDataStreamId1, 134 QUIC_RST_FLOW_CONTROL_ACCOUNTING, 0)); 135 visitor_->OnRstStream(rst1); 136 EXPECT_EQ(0u, session_->GetNumOpenStreams()); 137 138 // Send the same two bytes of payload in a new packet. 139 visitor_->OnStreamFrames(frames); 140 141 // The stream should not be re-opened. 142 EXPECT_EQ(0u, session_->GetNumOpenStreams()); 143 EXPECT_TRUE(connection_->connected()); 144 } 145 146 TEST_P(QuicServerSessionTest, NeverOpenStreamDueToReset) { 147 // Send a reset (and expect the peer to send a RST in response). 148 QuicRstStreamFrame rst1(kClientDataStreamId1, QUIC_STREAM_NO_ERROR, 0); 149 EXPECT_CALL(*connection_, SendRstStream(kClientDataStreamId1, 150 QUIC_RST_FLOW_CONTROL_ACCOUNTING, 0)); 151 visitor_->OnRstStream(rst1); 152 EXPECT_EQ(0u, session_->GetNumOpenStreams()); 153 154 // Send two bytes of payload. 155 QuicStreamFrame data1(kClientDataStreamId1, false, 0, MakeIOVector("HT")); 156 vector<QuicStreamFrame> frames; 157 frames.push_back(data1); 158 visitor_->OnStreamFrames(frames); 159 160 // The stream should never be opened, now that the reset is received. 161 EXPECT_EQ(0u, session_->GetNumOpenStreams()); 162 EXPECT_TRUE(connection_->connected()); 163 } 164 165 TEST_P(QuicServerSessionTest, AcceptClosedStream) { 166 vector<QuicStreamFrame> frames; 167 // Send (empty) compressed headers followed by two bytes of data. 168 frames.push_back(QuicStreamFrame(kClientDataStreamId1, false, 0, 169 MakeIOVector("\1\0\0\0\0\0\0\0HT"))); 170 frames.push_back(QuicStreamFrame(kClientDataStreamId2, false, 0, 171 MakeIOVector("\2\0\0\0\0\0\0\0HT"))); 172 visitor_->OnStreamFrames(frames); 173 EXPECT_EQ(2u, session_->GetNumOpenStreams()); 174 175 // Send a reset (and expect the peer to send a RST in response). 176 QuicRstStreamFrame rst(kClientDataStreamId1, QUIC_STREAM_NO_ERROR, 0); 177 EXPECT_CALL(*connection_, SendRstStream(kClientDataStreamId1, 178 QUIC_RST_FLOW_CONTROL_ACCOUNTING, 0)); 179 visitor_->OnRstStream(rst); 180 181 // If we were tracking, we'd probably want to reject this because it's data 182 // past the reset point of stream 3. As it's a closed stream we just drop the 183 // data on the floor, but accept the packet because it has data for stream 5. 184 frames.clear(); 185 frames.push_back( 186 QuicStreamFrame(kClientDataStreamId1, false, 2, MakeIOVector("TP"))); 187 frames.push_back( 188 QuicStreamFrame(kClientDataStreamId2, false, 2, MakeIOVector("TP"))); 189 visitor_->OnStreamFrames(frames); 190 // The stream should never be opened, now that the reset is received. 191 EXPECT_EQ(1u, session_->GetNumOpenStreams()); 192 EXPECT_TRUE(connection_->connected()); 193 } 194 195 TEST_P(QuicServerSessionTest, MaxOpenStreams) { 196 ValueRestore<bool> old_flag(&FLAGS_quic_allow_more_open_streams, true); 197 // Test that the server closes the connection if a client attempts to open too 198 // many data streams. The server accepts slightly more than the negotiated 199 // stream limit to deal with rare cases where a client FIN/RST is lost. 200 201 // The slightly increased stream limit is set during config negotiation. 202 EXPECT_EQ(kMaxStreamsForTest, session_->get_max_open_streams()); 203 session_->OnConfigNegotiated(); 204 EXPECT_EQ(kMaxStreamsMultiplier * kMaxStreamsForTest, 205 session_->get_max_open_streams()); 206 207 EXPECT_EQ(0u, session_->GetNumOpenStreams()); 208 QuicStreamId stream_id = kClientDataStreamId1; 209 // Open the max configured number of streams, should be no problem. 210 for (size_t i = 0; i < kMaxStreamsForTest; ++i) { 211 EXPECT_TRUE(QuicServerSessionPeer::GetIncomingDataStream(session_.get(), 212 stream_id)); 213 stream_id += 2; 214 } 215 216 // Open one more stream: server should accept slightly more than the 217 // configured limit. 218 EXPECT_TRUE( 219 QuicServerSessionPeer::GetIncomingDataStream(session_.get(), stream_id)); 220 221 // Now violate the server's internal stream limit. 222 EXPECT_CALL(*connection_, SendConnectionClose(QUIC_TOO_MANY_OPEN_STREAMS)); 223 stream_id += 2; 224 EXPECT_FALSE( 225 QuicServerSessionPeer::GetIncomingDataStream(session_.get(), stream_id)); 226 } 227 228 TEST_P(QuicServerSessionTest, MaxOpenStreamsImplicit) { 229 ValueRestore<bool> old_flag(&FLAGS_quic_allow_more_open_streams, true); 230 // Test that the server closes the connection if a client attempts to open too 231 // many data streams implicitly. The server accepts slightly more than the 232 // negotiated stream limit to deal with rare cases where a client FIN/RST is 233 // lost. 234 235 // The slightly increased stream limit is set during config negotiation. 236 EXPECT_EQ(kMaxStreamsForTest, session_->get_max_open_streams()); 237 session_->OnConfigNegotiated(); 238 EXPECT_EQ(kMaxStreamsMultiplier * kMaxStreamsForTest, 239 session_->get_max_open_streams()); 240 241 EXPECT_EQ(0u, session_->GetNumOpenStreams()); 242 EXPECT_TRUE(QuicServerSessionPeer::GetIncomingDataStream( 243 session_.get(), kClientDataStreamId1)); 244 // Implicitly open streams up to the server's limit. 245 const int kActualMaxStreams = kMaxStreamsMultiplier * kMaxStreamsForTest; 246 const int kMaxValidStreamId = 247 kClientDataStreamId1 + (kActualMaxStreams - 1) * 2; 248 EXPECT_TRUE(QuicServerSessionPeer::GetIncomingDataStream( 249 session_.get(), kMaxValidStreamId)); 250 251 // Opening a further stream will result in connection close. 252 EXPECT_CALL(*connection_, SendConnectionClose(QUIC_TOO_MANY_OPEN_STREAMS)); 253 EXPECT_FALSE(QuicServerSessionPeer::GetIncomingDataStream( 254 session_.get(), kMaxValidStreamId + 2)); 255 } 256 257 TEST_P(QuicServerSessionTest, GetEvenIncomingError) { 258 // Incoming streams on the server session must be odd. 259 EXPECT_CALL(*connection_, SendConnectionClose(QUIC_INVALID_STREAM_ID)); 260 EXPECT_EQ(NULL, 261 QuicServerSessionPeer::GetIncomingDataStream(session_.get(), 4)); 262 } 263 264 TEST_P(QuicServerSessionTest, SetFecProtectionFromConfig) { 265 ValueRestore<bool> old_flag(&FLAGS_enable_quic_fec, true); 266 267 // Set received config to have FEC connection option. 268 QuicTagVector copt; 269 copt.push_back(kFHDR); 270 QuicConfigPeer::SetReceivedConnectionOptions(session_->config(), copt); 271 session_->OnConfigNegotiated(); 272 273 // Verify that headers stream is always protected and data streams are 274 // optionally protected. 275 EXPECT_EQ(FEC_PROTECT_ALWAYS, 276 QuicSessionPeer::GetHeadersStream(session_.get())->fec_policy()); 277 QuicDataStream* stream = QuicServerSessionPeer::GetIncomingDataStream( 278 session_.get(), kClientDataStreamId1); 279 ASSERT_TRUE(stream); 280 EXPECT_EQ(FEC_PROTECT_OPTIONAL, stream->fec_policy()); 281 } 282 283 class MockQuicCryptoServerStream : public QuicCryptoServerStream { 284 public: 285 explicit MockQuicCryptoServerStream( 286 const QuicCryptoServerConfig& crypto_config, QuicSession* session) 287 : QuicCryptoServerStream(crypto_config, session) {} 288 virtual ~MockQuicCryptoServerStream() {} 289 290 MOCK_METHOD1(SendServerConfigUpdate, 291 void(const CachedNetworkParameters* cached_network_parameters)); 292 private: 293 DISALLOW_COPY_AND_ASSIGN(MockQuicCryptoServerStream); 294 }; 295 296 TEST_P(QuicServerSessionTest, BandwidthEstimates) { 297 if (version() <= QUIC_VERSION_21) { 298 return; 299 } 300 // Test that bandwidth estimate updates are sent to the client, only after the 301 // bandwidth estimate has changes sufficiently, and enough time has passed. 302 303 int32 bandwidth_estimate_kbytes_per_second = 123; 304 int32 max_bandwidth_estimate_kbytes_per_second = 134; 305 int32 max_bandwidth_estimate_timestamp = 1122334455; 306 const string serving_region = "not a real region"; 307 session_->set_serving_region(serving_region); 308 309 MockQuicCryptoServerStream* crypto_stream = 310 new MockQuicCryptoServerStream(crypto_config_, session_.get()); 311 QuicServerSessionPeer::SetCryptoStream(session_.get(), crypto_stream); 312 313 // Set some initial bandwidth values. 314 QuicSentPacketManager* sent_packet_manager = 315 QuicConnectionPeer::GetSentPacketManager(session_->connection()); 316 QuicSustainedBandwidthRecorder& bandwidth_recorder = 317 QuicSentPacketManagerPeer::GetBandwidthRecorder(sent_packet_manager); 318 QuicSustainedBandwidthRecorderPeer::SetBandwidthEstimate( 319 &bandwidth_recorder, bandwidth_estimate_kbytes_per_second); 320 QuicSustainedBandwidthRecorderPeer::SetMaxBandwidthEstimate( 321 &bandwidth_recorder, max_bandwidth_estimate_kbytes_per_second, 322 max_bandwidth_estimate_timestamp); 323 324 // There will be no update sent yet - not enough time has passed. 325 QuicTime now = QuicTime::Zero(); 326 session_->OnCongestionWindowChange(now); 327 328 // Bandwidth estimate has now changed sufficiently but not enough time has 329 // passed to send a Server Config Update. 330 bandwidth_estimate_kbytes_per_second = 331 bandwidth_estimate_kbytes_per_second * 1.6; 332 session_->OnCongestionWindowChange(now); 333 334 // Bandwidth estimate has now changed sufficiently and enough time has passed. 335 int64 srtt_ms = 336 sent_packet_manager->GetRttStats()->SmoothedRtt().ToMilliseconds(); 337 now = now.Add(QuicTime::Delta::FromMilliseconds( 338 kMinIntervalBetweenServerConfigUpdatesRTTs * srtt_ms)); 339 340 // Verify that the proto has exactly the values we expect. 341 CachedNetworkParameters expected_network_params; 342 expected_network_params.set_bandwidth_estimate_bytes_per_second( 343 bandwidth_recorder.BandwidthEstimate().ToBytesPerSecond()); 344 expected_network_params.set_max_bandwidth_estimate_bytes_per_second( 345 bandwidth_recorder.MaxBandwidthEstimate().ToBytesPerSecond()); 346 expected_network_params.set_max_bandwidth_timestamp_seconds( 347 bandwidth_recorder.MaxBandwidthTimestamp()); 348 expected_network_params.set_min_rtt_ms(session_->connection() 349 ->sent_packet_manager() 350 .GetRttStats() 351 ->min_rtt() 352 .ToMilliseconds()); 353 expected_network_params.set_previous_connection_state( 354 CachedNetworkParameters::CONGESTION_AVOIDANCE); 355 expected_network_params.set_serving_region(serving_region); 356 357 EXPECT_CALL(*crypto_stream, 358 SendServerConfigUpdate(EqualsProto(expected_network_params))) 359 .Times(1); 360 session_->OnCongestionWindowChange(now); 361 } 362 363 } // namespace 364 } // namespace test 365 } // namespace tools 366 } // namespace net 367