| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/tools/quic/quic_server_session.h" | 5 #include "net/tools/quic/quic_server_session.h" |
| 6 | 6 |
| 7 #include "net/quic/crypto/quic_crypto_server_config.h" | 7 #include "net/quic/crypto/quic_crypto_server_config.h" |
| 8 #include "net/quic/crypto/quic_random.h" | 8 #include "net/quic/crypto/quic_random.h" |
| 9 #include "net/quic/proto/cached_network_parameters.pb.h" | 9 #include "net/quic/proto/cached_network_parameters.pb.h" |
| 10 #include "net/quic/quic_connection.h" | 10 #include "net/quic/quic_connection.h" |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 47 using std::string; | 47 using std::string; |
| 48 using testing::StrictMock; | 48 using testing::StrictMock; |
| 49 using testing::_; | 49 using testing::_; |
| 50 | 50 |
| 51 namespace net { | 51 namespace net { |
| 52 namespace tools { | 52 namespace tools { |
| 53 namespace test { | 53 namespace test { |
| 54 | 54 |
| 55 class QuicServerSessionPeer { | 55 class QuicServerSessionPeer { |
| 56 public: | 56 public: |
| 57 static ReliableQuicStream* GetIncomingDynamicStream(QuicServerSession* s, | 57 static ReliableQuicStream* GetOrCreateDynamicStream(QuicServerSession* s, |
| 58 QuicStreamId id) { | 58 QuicStreamId id) { |
| 59 return s->GetIncomingDynamicStream(id); | 59 return s->GetOrCreateDynamicStream(id); |
| 60 } | 60 } |
| 61 static void SetCryptoStream(QuicServerSession* s, | 61 static void SetCryptoStream(QuicServerSession* s, |
| 62 QuicCryptoServerStream* crypto_stream) { | 62 QuicCryptoServerStream* crypto_stream) { |
| 63 s->crypto_stream_.reset(crypto_stream); | 63 s->crypto_stream_.reset(crypto_stream); |
| 64 s->static_streams()[kCryptoStreamId] = crypto_stream; | 64 s->static_streams()[kCryptoStreamId] = crypto_stream; |
| 65 } | 65 } |
| 66 static bool IsBandwidthResumptionEnabled(QuicServerSession* s) { | 66 static bool IsBandwidthResumptionEnabled(QuicServerSession* s) { |
| 67 return s->bandwidth_resumption_enabled_; | 67 return s->bandwidth_resumption_enabled_; |
| 68 } | 68 } |
| 69 }; | 69 }; |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 206 EXPECT_EQ(kMaxStreamsForTest, session_->get_max_open_streams()); | 206 EXPECT_EQ(kMaxStreamsForTest, session_->get_max_open_streams()); |
| 207 session_->OnConfigNegotiated(); | 207 session_->OnConfigNegotiated(); |
| 208 EXPECT_LT(kMaxStreamsMultiplier * kMaxStreamsForTest, | 208 EXPECT_LT(kMaxStreamsMultiplier * kMaxStreamsForTest, |
| 209 kMaxStreamsForTest + kMaxStreamsMinimumIncrement); | 209 kMaxStreamsForTest + kMaxStreamsMinimumIncrement); |
| 210 EXPECT_EQ(kMaxStreamsForTest + kMaxStreamsMinimumIncrement, | 210 EXPECT_EQ(kMaxStreamsForTest + kMaxStreamsMinimumIncrement, |
| 211 session_->get_max_open_streams()); | 211 session_->get_max_open_streams()); |
| 212 EXPECT_EQ(0u, session_->GetNumOpenStreams()); | 212 EXPECT_EQ(0u, session_->GetNumOpenStreams()); |
| 213 QuicStreamId stream_id = kClientDataStreamId1; | 213 QuicStreamId stream_id = kClientDataStreamId1; |
| 214 // Open the max configured number of streams, should be no problem. | 214 // Open the max configured number of streams, should be no problem. |
| 215 for (size_t i = 0; i < kMaxStreamsForTest; ++i) { | 215 for (size_t i = 0; i < kMaxStreamsForTest; ++i) { |
| 216 EXPECT_TRUE(QuicServerSessionPeer::GetIncomingDynamicStream(session_.get(), | 216 EXPECT_TRUE(QuicServerSessionPeer::GetOrCreateDynamicStream(session_.get(), |
| 217 stream_id)); | 217 stream_id)); |
| 218 stream_id += 2; | 218 stream_id += 2; |
| 219 } | 219 } |
| 220 | 220 |
| 221 // Open more streams: server should accept slightly more than the limit. | 221 // Open more streams: server should accept slightly more than the limit. |
| 222 for (size_t i = 0; i < kMaxStreamsMinimumIncrement; ++i) { | 222 for (size_t i = 0; i < kMaxStreamsMinimumIncrement; ++i) { |
| 223 EXPECT_TRUE(QuicServerSessionPeer::GetIncomingDynamicStream(session_.get(), | 223 EXPECT_TRUE(QuicServerSessionPeer::GetOrCreateDynamicStream(session_.get(), |
| 224 stream_id)); | 224 stream_id)); |
| 225 stream_id += 2; | 225 stream_id += 2; |
| 226 } | 226 } |
| 227 | 227 |
| 228 // Now violate the server's internal stream limit. | 228 // Now violate the server's internal stream limit. |
| 229 stream_id += 2; | 229 stream_id += 2; |
| 230 if (connection_->version() <= QUIC_VERSION_27) { | 230 if (connection_->version() <= QUIC_VERSION_27) { |
| 231 EXPECT_CALL(*connection_, SendConnectionClose(QUIC_TOO_MANY_OPEN_STREAMS)); | 231 EXPECT_CALL(*connection_, SendConnectionClose(QUIC_TOO_MANY_OPEN_STREAMS)); |
| 232 EXPECT_CALL(*connection_, SendRstStream(_, _, _)).Times(0); | 232 EXPECT_CALL(*connection_, SendRstStream(_, _, _)).Times(0); |
| 233 } else { | 233 } else { |
| 234 EXPECT_CALL(*connection_, SendConnectionClose(_)).Times(0); | 234 EXPECT_CALL(*connection_, SendConnectionClose(_)).Times(0); |
| 235 EXPECT_CALL(*connection_, SendRstStream(stream_id, QUIC_REFUSED_STREAM, 0)); | 235 EXPECT_CALL(*connection_, SendRstStream(stream_id, QUIC_REFUSED_STREAM, 0)); |
| 236 } | 236 } |
| 237 // Even if the connection remains open, the stream creation should fail. | 237 // Even if the connection remains open, the stream creation should fail. |
| 238 EXPECT_FALSE(QuicServerSessionPeer::GetIncomingDynamicStream(session_.get(), | 238 EXPECT_FALSE(QuicServerSessionPeer::GetOrCreateDynamicStream(session_.get(), |
| 239 stream_id)); | 239 stream_id)); |
| 240 } | 240 } |
| 241 | 241 |
| 242 TEST_P(QuicServerSessionTest, MaxAvailableStreams) { | 242 TEST_P(QuicServerSessionTest, MaxAvailableStreams) { |
| 243 // Test that the server closes the connection if a client makes too many data | 243 // Test that the server closes the connection if a client makes too many data |
| 244 // streams available. The server accepts slightly more than the negotiated | 244 // streams available. The server accepts slightly more than the negotiated |
| 245 // stream limit to deal with rare cases where a client FIN/RST is lost. | 245 // stream limit to deal with rare cases where a client FIN/RST is lost. |
| 246 | 246 |
| 247 // The slightly increased stream limit is set during config negotiation. | 247 // The slightly increased stream limit is set during config negotiation. |
| 248 EXPECT_EQ(kMaxStreamsForTest, session_->get_max_open_streams()); | 248 EXPECT_EQ(kMaxStreamsForTest, session_->get_max_open_streams()); |
| 249 session_->OnConfigNegotiated(); | 249 session_->OnConfigNegotiated(); |
| 250 const size_t kAvailableStreamLimit = session_->get_max_available_streams(); | 250 const size_t kAvailableStreamLimit = session_->get_max_available_streams(); |
| 251 EXPECT_EQ(session_->get_max_open_streams() * kMaxAvailableStreamsMultiplier, | 251 EXPECT_EQ(session_->get_max_open_streams() * kMaxAvailableStreamsMultiplier, |
| 252 session_->get_max_available_streams()); | 252 session_->get_max_available_streams()); |
| 253 // The protocol specification requires that there can be at least 10 times | 253 // The protocol specification requires that there can be at least 10 times |
| 254 // as many available streams as the connection's maximum open streams. | 254 // as many available streams as the connection's maximum open streams. |
| 255 EXPECT_LE(10 * kMaxStreamsForTest, kAvailableStreamLimit); | 255 EXPECT_LE(10 * kMaxStreamsForTest, kAvailableStreamLimit); |
| 256 | 256 |
| 257 EXPECT_EQ(0u, session_->GetNumOpenStreams()); | 257 EXPECT_EQ(0u, session_->GetNumOpenStreams()); |
| 258 EXPECT_TRUE(QuicServerSessionPeer::GetIncomingDynamicStream( | 258 EXPECT_TRUE(QuicServerSessionPeer::GetOrCreateDynamicStream( |
| 259 session_.get(), kClientDataStreamId1)); | 259 session_.get(), kClientDataStreamId1)); |
| 260 | 260 |
| 261 // Establish available streams up to the server's limit. | 261 // Establish available streams up to the server's limit. |
| 262 const int kLimitingStreamId = | 262 const int kLimitingStreamId = |
| 263 FLAGS_allow_many_available_streams | 263 FLAGS_allow_many_available_streams |
| 264 ? kClientDataStreamId1 + (kAvailableStreamLimit)*2 + 2 | 264 ? kClientDataStreamId1 + (kAvailableStreamLimit)*2 + 2 |
| 265 : kClientDataStreamId1 + (session_->get_max_open_streams() - 1) * 2; | 265 : kClientDataStreamId1 + (session_->get_max_open_streams() - 1) * 2; |
| 266 EXPECT_TRUE(QuicServerSessionPeer::GetIncomingDynamicStream( | 266 EXPECT_TRUE(QuicServerSessionPeer::GetOrCreateDynamicStream( |
| 267 session_.get(), kLimitingStreamId)); | 267 session_.get(), kLimitingStreamId)); |
| 268 | 268 |
| 269 // A further available stream will result in connection close. | 269 // A further available stream will result in connection close. |
| 270 if (FLAGS_allow_many_available_streams) { | 270 if (FLAGS_allow_many_available_streams) { |
| 271 EXPECT_CALL(*connection_, | 271 EXPECT_CALL(*connection_, |
| 272 SendConnectionClose(QUIC_TOO_MANY_AVAILABLE_STREAMS)); | 272 SendConnectionClose(QUIC_TOO_MANY_AVAILABLE_STREAMS)); |
| 273 } else { | 273 } else { |
| 274 EXPECT_CALL(*connection_, SendConnectionClose(QUIC_TOO_MANY_OPEN_STREAMS)); | 274 EXPECT_CALL(*connection_, SendConnectionClose(QUIC_TOO_MANY_OPEN_STREAMS)); |
| 275 } | 275 } |
| 276 // This forces stream kLimitingStreamId + 2 to become available, which | 276 // This forces stream kLimitingStreamId + 2 to become available, which |
| 277 // violates the quota. | 277 // violates the quota. |
| 278 EXPECT_FALSE(QuicServerSessionPeer::GetIncomingDynamicStream( | 278 EXPECT_FALSE(QuicServerSessionPeer::GetOrCreateDynamicStream( |
| 279 session_.get(), kLimitingStreamId + 4)); | 279 session_.get(), kLimitingStreamId + 4)); |
| 280 } | 280 } |
| 281 | 281 |
| 282 TEST_P(QuicServerSessionTest, GetEvenIncomingError) { | 282 TEST_P(QuicServerSessionTest, GetEvenIncomingError) { |
| 283 // Incoming streams on the server session must be odd. | 283 // Incoming streams on the server session must be odd. |
| 284 EXPECT_CALL(*connection_, SendConnectionClose(QUIC_INVALID_STREAM_ID)); | 284 EXPECT_CALL(*connection_, SendConnectionClose(QUIC_INVALID_STREAM_ID)); |
| 285 EXPECT_EQ(nullptr, | 285 EXPECT_EQ(nullptr, |
| 286 QuicServerSessionPeer::GetIncomingDynamicStream(session_.get(), 4)); | 286 QuicServerSessionPeer::GetOrCreateDynamicStream(session_.get(), 4)); |
| 287 } | 287 } |
| 288 | 288 |
| 289 TEST_P(QuicServerSessionTest, GetStreamDisconnected) { | 289 TEST_P(QuicServerSessionTest, GetStreamDisconnected) { |
| 290 // Don't create new streams if the connection is disconnected. | 290 // Don't create new streams if the connection is disconnected. |
| 291 QuicConnectionPeer::CloseConnection(connection_); | 291 QuicConnectionPeer::CloseConnection(connection_); |
| 292 EXPECT_DFATAL( | 292 EXPECT_DFATAL( |
| 293 QuicServerSessionPeer::GetIncomingDynamicStream(session_.get(), 5), | 293 QuicServerSessionPeer::GetOrCreateDynamicStream(session_.get(), 5), |
| 294 "ShouldCreateIncomingDynamicStream called when disconnected"); | 294 "ShouldCreateIncomingDynamicStream called when disconnected"); |
| 295 } | 295 } |
| 296 | 296 |
| 297 TEST_P(QuicServerSessionTest, SetFecProtectionFromConfig) { | 297 TEST_P(QuicServerSessionTest, SetFecProtectionFromConfig) { |
| 298 ValueRestore<bool> old_flag(&FLAGS_enable_quic_fec, true); | 298 ValueRestore<bool> old_flag(&FLAGS_enable_quic_fec, true); |
| 299 | 299 |
| 300 // Set received config to have FEC connection option. | 300 // Set received config to have FEC connection option. |
| 301 QuicTagVector copt; | 301 QuicTagVector copt; |
| 302 copt.push_back(kFHDR); | 302 copt.push_back(kFHDR); |
| 303 QuicConfigPeer::SetReceivedConnectionOptions(session_->config(), copt); | 303 QuicConfigPeer::SetReceivedConnectionOptions(session_->config(), copt); |
| 304 session_->OnConfigNegotiated(); | 304 session_->OnConfigNegotiated(); |
| 305 | 305 |
| 306 // Verify that headers stream is always protected and data streams are | 306 // Verify that headers stream is always protected and data streams are |
| 307 // optionally protected. | 307 // optionally protected. |
| 308 EXPECT_EQ(FEC_PROTECT_ALWAYS, QuicSpdySessionPeer::GetHeadersStream( | 308 EXPECT_EQ(FEC_PROTECT_ALWAYS, QuicSpdySessionPeer::GetHeadersStream( |
| 309 session_.get())->fec_policy()); | 309 session_.get())->fec_policy()); |
| 310 ReliableQuicStream* stream = QuicServerSessionPeer::GetIncomingDynamicStream( | 310 ReliableQuicStream* stream = QuicServerSessionPeer::GetOrCreateDynamicStream( |
| 311 session_.get(), kClientDataStreamId1); | 311 session_.get(), kClientDataStreamId1); |
| 312 ASSERT_TRUE(stream); | 312 ASSERT_TRUE(stream); |
| 313 EXPECT_EQ(FEC_PROTECT_OPTIONAL, stream->fec_policy()); | 313 EXPECT_EQ(FEC_PROTECT_OPTIONAL, stream->fec_policy()); |
| 314 } | 314 } |
| 315 | 315 |
| 316 class MockQuicCryptoServerStream : public QuicCryptoServerStream { | 316 class MockQuicCryptoServerStream : public QuicCryptoServerStream { |
| 317 public: | 317 public: |
| 318 explicit MockQuicCryptoServerStream( | 318 explicit MockQuicCryptoServerStream( |
| 319 const QuicCryptoServerConfig* crypto_config, QuicSession* session) | 319 const QuicCryptoServerConfig* crypto_config, QuicSession* session) |
| 320 : QuicCryptoServerStream(crypto_config, session) {} | 320 : QuicCryptoServerStream(crypto_config, session) {} |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 492 QuicServerSessionPeer::IsBandwidthResumptionEnabled(session_.get())); | 492 QuicServerSessionPeer::IsBandwidthResumptionEnabled(session_.get())); |
| 493 session_->OnConfigNegotiated(); | 493 session_->OnConfigNegotiated(); |
| 494 EXPECT_FALSE( | 494 EXPECT_FALSE( |
| 495 QuicServerSessionPeer::IsBandwidthResumptionEnabled(session_.get())); | 495 QuicServerSessionPeer::IsBandwidthResumptionEnabled(session_.get())); |
| 496 } | 496 } |
| 497 | 497 |
| 498 } // namespace | 498 } // namespace |
| 499 } // namespace test | 499 } // namespace test |
| 500 } // namespace tools | 500 } // namespace tools |
| 501 } // namespace net | 501 } // namespace net |
| OLD | NEW |