• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "quiche/quic/core/http/quic_server_session_base.h"
6 
7 #include <cstdint>
8 #include <memory>
9 #include <string>
10 #include <utility>
11 
12 #include "absl/memory/memory.h"
13 #include "quiche/quic/core/crypto/null_encrypter.h"
14 #include "quiche/quic/core/crypto/quic_crypto_server_config.h"
15 #include "quiche/quic/core/crypto/quic_random.h"
16 #include "quiche/quic/core/proto/cached_network_parameters_proto.h"
17 #include "quiche/quic/core/quic_connection.h"
18 #include "quiche/quic/core/quic_crypto_server_stream.h"
19 #include "quiche/quic/core/quic_crypto_server_stream_base.h"
20 #include "quiche/quic/core/quic_types.h"
21 #include "quiche/quic/core/quic_utils.h"
22 #include "quiche/quic/core/tls_server_handshaker.h"
23 #include "quiche/quic/platform/api/quic_expect_bug.h"
24 #include "quiche/quic/platform/api/quic_flags.h"
25 #include "quiche/quic/platform/api/quic_socket_address.h"
26 #include "quiche/quic/platform/api/quic_test.h"
27 #include "quiche/quic/test_tools/crypto_test_utils.h"
28 #include "quiche/quic/test_tools/fake_proof_source.h"
29 #include "quiche/quic/test_tools/mock_quic_session_visitor.h"
30 #include "quiche/quic/test_tools/quic_config_peer.h"
31 #include "quiche/quic/test_tools/quic_connection_peer.h"
32 #include "quiche/quic/test_tools/quic_crypto_server_config_peer.h"
33 #include "quiche/quic/test_tools/quic_sent_packet_manager_peer.h"
34 #include "quiche/quic/test_tools/quic_server_session_base_peer.h"
35 #include "quiche/quic/test_tools/quic_session_peer.h"
36 #include "quiche/quic/test_tools/quic_spdy_session_peer.h"
37 #include "quiche/quic/test_tools/quic_stream_id_manager_peer.h"
38 #include "quiche/quic/test_tools/quic_stream_peer.h"
39 #include "quiche/quic/test_tools/quic_sustained_bandwidth_recorder_peer.h"
40 #include "quiche/quic/test_tools/quic_test_utils.h"
41 #include "quiche/quic/tools/quic_memory_cache_backend.h"
42 #include "quiche/quic/tools/quic_simple_server_stream.h"
43 
44 using testing::_;
45 using testing::StrictMock;
46 
47 using testing::AtLeast;
48 
49 namespace quic {
50 namespace test {
51 namespace {
52 
53 // Data to be sent on a request stream.  In Google QUIC, this is interpreted as
54 // DATA payload (there is no framing on request streams).  In IETF QUIC, this is
55 // interpreted as HEADERS frame (type 0x1) with payload length 122 ('z').  Since
56 // no payload is included, QPACK decoder will not be invoked.
57 const char* const kStreamData = "\1z";
58 
59 class TestServerSession : public QuicServerSessionBase {
60  public:
TestServerSession(const QuicConfig & config,QuicConnection * connection,QuicSession::Visitor * visitor,QuicCryptoServerStreamBase::Helper * helper,const QuicCryptoServerConfig * crypto_config,QuicCompressedCertsCache * compressed_certs_cache,QuicSimpleServerBackend * quic_simple_server_backend)61   TestServerSession(const QuicConfig& config, QuicConnection* connection,
62                     QuicSession::Visitor* visitor,
63                     QuicCryptoServerStreamBase::Helper* helper,
64                     const QuicCryptoServerConfig* crypto_config,
65                     QuicCompressedCertsCache* compressed_certs_cache,
66                     QuicSimpleServerBackend* quic_simple_server_backend)
67       : QuicServerSessionBase(config, CurrentSupportedVersions(), connection,
68                               visitor, helper, crypto_config,
69                               compressed_certs_cache),
70         quic_simple_server_backend_(quic_simple_server_backend) {}
71 
~TestServerSession()72   ~TestServerSession() override { DeleteConnection(); }
73 
74   MOCK_METHOD(bool, WriteControlFrame,
75               (const QuicFrame& frame, TransmissionType type), (override));
76 
77  protected:
CreateIncomingStream(QuicStreamId id)78   QuicSpdyStream* CreateIncomingStream(QuicStreamId id) override {
79     if (!ShouldCreateIncomingStream(id)) {
80       return nullptr;
81     }
82     QuicSpdyStream* stream = new QuicSimpleServerStream(
83         id, this, BIDIRECTIONAL, quic_simple_server_backend_);
84     ActivateStream(absl::WrapUnique(stream));
85     return stream;
86   }
87 
CreateIncomingStream(PendingStream * pending)88   QuicSpdyStream* CreateIncomingStream(PendingStream* pending) override {
89     QuicSpdyStream* stream =
90         new QuicSimpleServerStream(pending, this, quic_simple_server_backend_);
91     ActivateStream(absl::WrapUnique(stream));
92     return stream;
93   }
94 
CreateOutgoingBidirectionalStream()95   QuicSpdyStream* CreateOutgoingBidirectionalStream() override {
96     QUICHE_DCHECK(false);
97     return nullptr;
98   }
99 
CreateOutgoingUnidirectionalStream()100   QuicSpdyStream* CreateOutgoingUnidirectionalStream() override {
101     if (!ShouldCreateOutgoingUnidirectionalStream()) {
102       return nullptr;
103     }
104 
105     QuicSpdyStream* stream = new QuicSimpleServerStream(
106         GetNextOutgoingUnidirectionalStreamId(), this, WRITE_UNIDIRECTIONAL,
107         quic_simple_server_backend_);
108     ActivateStream(absl::WrapUnique(stream));
109     return stream;
110   }
111 
CreateQuicCryptoServerStream(const QuicCryptoServerConfig * crypto_config,QuicCompressedCertsCache * compressed_certs_cache)112   std::unique_ptr<QuicCryptoServerStreamBase> CreateQuicCryptoServerStream(
113       const QuicCryptoServerConfig* crypto_config,
114       QuicCompressedCertsCache* compressed_certs_cache) override {
115     return CreateCryptoServerStream(crypto_config, compressed_certs_cache, this,
116                                     stream_helper());
117   }
118 
119  private:
120   QuicSimpleServerBackend*
121       quic_simple_server_backend_;  // Owned by QuicServerSessionBaseTest
122 };
123 
124 const size_t kMaxStreamsForTest = 10;
125 
126 class QuicServerSessionBaseTest : public QuicTestWithParam<ParsedQuicVersion> {
127  protected:
QuicServerSessionBaseTest()128   QuicServerSessionBaseTest()
129       : QuicServerSessionBaseTest(crypto_test_utils::ProofSourceForTesting()) {}
130 
QuicServerSessionBaseTest(std::unique_ptr<ProofSource> proof_source)131   explicit QuicServerSessionBaseTest(std::unique_ptr<ProofSource> proof_source)
132       : crypto_config_(QuicCryptoServerConfig::TESTING,
133                        QuicRandom::GetInstance(), std::move(proof_source),
134                        KeyExchangeSource::Default()),
135         compressed_certs_cache_(
136             QuicCompressedCertsCache::kQuicCompressedCertsCacheSize) {
137     config_.SetMaxBidirectionalStreamsToSend(kMaxStreamsForTest);
138     config_.SetMaxUnidirectionalStreamsToSend(kMaxStreamsForTest);
139     QuicConfigPeer::SetReceivedMaxBidirectionalStreams(&config_,
140                                                        kMaxStreamsForTest);
141     QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(&config_,
142                                                         kMaxStreamsForTest);
143     config_.SetInitialStreamFlowControlWindowToSend(
144         kInitialStreamFlowControlWindowForTest);
145     config_.SetInitialSessionFlowControlWindowToSend(
146         kInitialSessionFlowControlWindowForTest);
147 
148     ParsedQuicVersionVector supported_versions = SupportedVersions(version());
149     connection_ = new StrictMock<MockQuicConnection>(
150         &helper_, &alarm_factory_, Perspective::IS_SERVER, supported_versions);
151     connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
152     connection_->SetEncrypter(
153         ENCRYPTION_FORWARD_SECURE,
154         std::make_unique<NullEncrypter>(connection_->perspective()));
155     session_ = std::make_unique<TestServerSession>(
156         config_, connection_, &owner_, &stream_helper_, &crypto_config_,
157         &compressed_certs_cache_, &memory_cache_backend_);
158     MockClock clock;
159     handshake_message_ = crypto_config_.AddDefaultConfig(
160         QuicRandom::GetInstance(), &clock,
161         QuicCryptoServerConfig::ConfigOptions());
162     session_->Initialize();
163     QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
164         session_->config(), kMinimumFlowControlSendWindow);
165     session_->OnConfigNegotiated();
166     if (version().SupportsAntiAmplificationLimit()) {
167       QuicConnectionPeer::SetAddressValidated(connection_);
168     }
169   }
170 
GetNthClientInitiatedBidirectionalId(int n)171   QuicStreamId GetNthClientInitiatedBidirectionalId(int n) {
172     return GetNthClientInitiatedBidirectionalStreamId(transport_version(), n);
173   }
174 
GetNthServerInitiatedUnidirectionalId(int n)175   QuicStreamId GetNthServerInitiatedUnidirectionalId(int n) {
176     return quic::test::GetNthServerInitiatedUnidirectionalStreamId(
177         transport_version(), n);
178   }
179 
version() const180   ParsedQuicVersion version() const { return GetParam(); }
181 
transport_version() const182   QuicTransportVersion transport_version() const {
183     return version().transport_version;
184   }
185 
186   // Create and inject a STOP_SENDING frame. In GOOGLE QUIC, receiving a
187   // RST_STREAM frame causes a two-way close. For IETF QUIC, RST_STREAM causes a
188   // one-way close. This method can be used to inject a STOP_SENDING, which
189   // would cause a close in the opposite direction. This allows tests to do the
190   // extra work to get a two-way (full) close where desired. Also sets up
191   // expects needed to ensure that the STOP_SENDING worked as expected.
InjectStopSendingFrame(QuicStreamId stream_id)192   void InjectStopSendingFrame(QuicStreamId stream_id) {
193     if (!VersionHasIetfQuicFrames(transport_version())) {
194       // Only needed for version 99/IETF QUIC. Noop otherwise.
195       return;
196     }
197     QuicStopSendingFrame stop_sending(kInvalidControlFrameId, stream_id,
198                                       QUIC_ERROR_PROCESSING_STREAM);
199     EXPECT_CALL(owner_, OnStopSendingReceived(_)).Times(1);
200     // Expect the RESET_STREAM that is generated in response to receiving a
201     // STOP_SENDING.
202     EXPECT_CALL(*session_, WriteControlFrame(_, _));
203     EXPECT_CALL(*connection_,
204                 OnStreamReset(stream_id, QUIC_ERROR_PROCESSING_STREAM));
205     session_->OnStopSendingFrame(stop_sending);
206   }
207 
208   StrictMock<MockQuicSessionVisitor> owner_;
209   StrictMock<MockQuicCryptoServerStreamHelper> stream_helper_;
210   MockQuicConnectionHelper helper_;
211   MockAlarmFactory alarm_factory_;
212   StrictMock<MockQuicConnection>* connection_;
213   QuicConfig config_;
214   QuicCryptoServerConfig crypto_config_;
215   QuicCompressedCertsCache compressed_certs_cache_;
216   QuicMemoryCacheBackend memory_cache_backend_;
217   std::unique_ptr<TestServerSession> session_;
218   std::unique_ptr<CryptoHandshakeMessage> handshake_message_;
219 };
220 
221 // Compares CachedNetworkParameters.
222 MATCHER_P(EqualsProto, network_params, "") {
223   CachedNetworkParameters reference(network_params);
224   return (arg->bandwidth_estimate_bytes_per_second() ==
225               reference.bandwidth_estimate_bytes_per_second() &&
226           arg->bandwidth_estimate_bytes_per_second() ==
227               reference.bandwidth_estimate_bytes_per_second() &&
228           arg->max_bandwidth_estimate_bytes_per_second() ==
229               reference.max_bandwidth_estimate_bytes_per_second() &&
230           arg->max_bandwidth_timestamp_seconds() ==
231               reference.max_bandwidth_timestamp_seconds() &&
232           arg->min_rtt_ms() == reference.min_rtt_ms() &&
233           arg->previous_connection_state() ==
234               reference.previous_connection_state());
235 }
236 
237 INSTANTIATE_TEST_SUITE_P(Tests, QuicServerSessionBaseTest,
238                          ::testing::ValuesIn(AllSupportedVersions()),
239                          ::testing::PrintToStringParamName());
240 
TEST_P(QuicServerSessionBaseTest,CloseStreamDueToReset)241 TEST_P(QuicServerSessionBaseTest, CloseStreamDueToReset) {
242   // Send some data open a stream, then reset it.
243   QuicStreamFrame data1(GetNthClientInitiatedBidirectionalId(0), false, 0,
244                         kStreamData);
245   session_->OnStreamFrame(data1);
246   EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
247 
248   // Send a reset (and expect the peer to send a RST in response).
249   QuicRstStreamFrame rst1(kInvalidControlFrameId,
250                           GetNthClientInitiatedBidirectionalId(0),
251                           QUIC_ERROR_PROCESSING_STREAM, 0);
252   EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1);
253   if (!VersionHasIetfQuicFrames(transport_version())) {
254     // For non-version 99, the RESET_STREAM will do the full close.
255     // Set up expects accordingly.
256     EXPECT_CALL(*session_, WriteControlFrame(_, _));
257     EXPECT_CALL(*connection_,
258                 OnStreamReset(GetNthClientInitiatedBidirectionalId(0),
259                               QUIC_RST_ACKNOWLEDGEMENT));
260   }
261   session_->OnRstStream(rst1);
262 
263   // For version-99 will create and receive a stop-sending, completing
264   // the full-close expected by this test.
265   InjectStopSendingFrame(GetNthClientInitiatedBidirectionalId(0));
266 
267   EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
268   // Send the same two bytes of payload in a new packet.
269   session_->OnStreamFrame(data1);
270 
271   // The stream should not be re-opened.
272   EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
273   EXPECT_TRUE(connection_->connected());
274 }
275 
TEST_P(QuicServerSessionBaseTest,NeverOpenStreamDueToReset)276 TEST_P(QuicServerSessionBaseTest, NeverOpenStreamDueToReset) {
277   // Send a reset (and expect the peer to send a RST in response).
278   QuicRstStreamFrame rst1(kInvalidControlFrameId,
279                           GetNthClientInitiatedBidirectionalId(0),
280                           QUIC_ERROR_PROCESSING_STREAM, 0);
281   EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1);
282   if (!VersionHasIetfQuicFrames(transport_version())) {
283     // For non-version 99, the RESET_STREAM will do the full close.
284     // Set up expects accordingly.
285     EXPECT_CALL(*session_, WriteControlFrame(_, _));
286     EXPECT_CALL(*connection_,
287                 OnStreamReset(GetNthClientInitiatedBidirectionalId(0),
288                               QUIC_RST_ACKNOWLEDGEMENT));
289   }
290   session_->OnRstStream(rst1);
291 
292   // For version-99 will create and receive a stop-sending, completing
293   // the full-close expected by this test.
294   InjectStopSendingFrame(GetNthClientInitiatedBidirectionalId(0));
295 
296   EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
297 
298   QuicStreamFrame data1(GetNthClientInitiatedBidirectionalId(0), false, 0,
299                         kStreamData);
300   session_->OnStreamFrame(data1);
301 
302   // The stream should never be opened, now that the reset is received.
303   EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
304   EXPECT_TRUE(connection_->connected());
305 }
306 
TEST_P(QuicServerSessionBaseTest,AcceptClosedStream)307 TEST_P(QuicServerSessionBaseTest, AcceptClosedStream) {
308   // Send some data to open two streams.
309   QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
310                          kStreamData);
311   QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(1), false, 0,
312                          kStreamData);
313   session_->OnStreamFrame(frame1);
314   session_->OnStreamFrame(frame2);
315   EXPECT_EQ(2u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
316 
317   // Send a reset (and expect the peer to send a RST in response).
318   QuicRstStreamFrame rst(kInvalidControlFrameId,
319                          GetNthClientInitiatedBidirectionalId(0),
320                          QUIC_ERROR_PROCESSING_STREAM, 0);
321   EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1);
322   if (!VersionHasIetfQuicFrames(transport_version())) {
323     // For non-version 99, the RESET_STREAM will do the full close.
324     // Set up expects accordingly.
325     EXPECT_CALL(*session_, WriteControlFrame(_, _));
326     EXPECT_CALL(*connection_,
327                 OnStreamReset(GetNthClientInitiatedBidirectionalId(0),
328                               QUIC_RST_ACKNOWLEDGEMENT));
329   }
330   session_->OnRstStream(rst);
331 
332   // For version-99 will create and receive a stop-sending, completing
333   // the full-close expected by this test.
334   InjectStopSendingFrame(GetNthClientInitiatedBidirectionalId(0));
335 
336   // If we were tracking, we'd probably want to reject this because it's data
337   // past the reset point of stream 3.  As it's a closed stream we just drop the
338   // data on the floor, but accept the packet because it has data for stream 5.
339   QuicStreamFrame frame3(GetNthClientInitiatedBidirectionalId(0), false, 2,
340                          kStreamData);
341   QuicStreamFrame frame4(GetNthClientInitiatedBidirectionalId(1), false, 2,
342                          kStreamData);
343   session_->OnStreamFrame(frame3);
344   session_->OnStreamFrame(frame4);
345   // The stream should never be opened, now that the reset is received.
346   EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
347   EXPECT_TRUE(connection_->connected());
348 }
349 
TEST_P(QuicServerSessionBaseTest,MaxOpenStreams)350 TEST_P(QuicServerSessionBaseTest, MaxOpenStreams) {
351   // Test that the server refuses if a client attempts to open too many data
352   // streams.  For versions other than version 99, the server accepts slightly
353   // more than the negotiated stream limit to deal with rare cases where a
354   // client FIN/RST is lost.
355   connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
356   session_->OnConfigNegotiated();
357   if (!VersionHasIetfQuicFrames(transport_version())) {
358     // The slightly increased stream limit is set during config negotiation.  It
359     // is either an increase of 10 over negotiated limit, or a fixed percentage
360     // scaling, whichever is larger. Test both before continuing.
361     EXPECT_LT(kMaxStreamsMultiplier * kMaxStreamsForTest,
362               kMaxStreamsForTest + kMaxStreamsMinimumIncrement);
363     EXPECT_EQ(kMaxStreamsForTest + kMaxStreamsMinimumIncrement,
364               session_->max_open_incoming_bidirectional_streams());
365   }
366   EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
367   QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
368   // Open the max configured number of streams, should be no problem.
369   for (size_t i = 0; i < kMaxStreamsForTest; ++i) {
370     EXPECT_TRUE(QuicServerSessionBasePeer::GetOrCreateStream(session_.get(),
371                                                              stream_id));
372     stream_id += QuicUtils::StreamIdDelta(transport_version());
373   }
374 
375   if (!VersionHasIetfQuicFrames(transport_version())) {
376     // Open more streams: server should accept slightly more than the limit.
377     // Excess streams are for non-version-99 only.
378     for (size_t i = 0; i < kMaxStreamsMinimumIncrement; ++i) {
379       EXPECT_TRUE(QuicServerSessionBasePeer::GetOrCreateStream(session_.get(),
380                                                                stream_id));
381       stream_id += QuicUtils::StreamIdDelta(transport_version());
382     }
383   }
384   // Now violate the server's internal stream limit.
385   stream_id += QuicUtils::StreamIdDelta(transport_version());
386 
387   if (!VersionHasIetfQuicFrames(transport_version())) {
388     // For non-version 99, QUIC responds to an attempt to exceed the stream
389     // limit by resetting the stream.
390     EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
391     EXPECT_CALL(*session_, WriteControlFrame(_, _));
392     EXPECT_CALL(*connection_, OnStreamReset(stream_id, QUIC_REFUSED_STREAM));
393   } else {
394     // In version 99 QUIC responds to an attempt to exceed the stream limit by
395     // closing the connection.
396     EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(1);
397   }
398   // Even if the connection remains open, the stream creation should fail.
399   EXPECT_FALSE(
400       QuicServerSessionBasePeer::GetOrCreateStream(session_.get(), stream_id));
401 }
402 
TEST_P(QuicServerSessionBaseTest,MaxAvailableBidirectionalStreams)403 TEST_P(QuicServerSessionBaseTest, MaxAvailableBidirectionalStreams) {
404   // Test that the server closes the connection if a client makes too many data
405   // streams available.  The server accepts slightly more than the negotiated
406   // stream limit to deal with rare cases where a client FIN/RST is lost.
407   connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
408   session_->OnConfigNegotiated();
409   const size_t kAvailableStreamLimit =
410       session_->MaxAvailableBidirectionalStreams();
411 
412   EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(session_.get()));
413   EXPECT_TRUE(QuicServerSessionBasePeer::GetOrCreateStream(
414       session_.get(), GetNthClientInitiatedBidirectionalId(0)));
415 
416   // Establish available streams up to the server's limit.
417   QuicStreamId next_id = QuicUtils::StreamIdDelta(transport_version());
418   const int kLimitingStreamId =
419       GetNthClientInitiatedBidirectionalId(kAvailableStreamLimit + 1);
420   if (!VersionHasIetfQuicFrames(transport_version())) {
421     // This exceeds the stream limit. In versions other than 99
422     // this is allowed. Version 99 hews to the IETF spec and does
423     // not allow it.
424     EXPECT_TRUE(QuicServerSessionBasePeer::GetOrCreateStream(
425         session_.get(), kLimitingStreamId));
426     // A further available stream will result in connection close.
427     EXPECT_CALL(*connection_,
428                 CloseConnection(QUIC_TOO_MANY_AVAILABLE_STREAMS, _, _));
429   } else {
430     // A further available stream will result in connection close.
431     EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_STREAM_ID, _, _));
432   }
433 
434   // This forces stream kLimitingStreamId + 2 to become available, which
435   // violates the quota.
436   EXPECT_FALSE(QuicServerSessionBasePeer::GetOrCreateStream(
437       session_.get(), kLimitingStreamId + 2 * next_id));
438 }
439 
TEST_P(QuicServerSessionBaseTest,GetEvenIncomingError)440 TEST_P(QuicServerSessionBaseTest, GetEvenIncomingError) {
441   // Incoming streams on the server session must be odd.
442   const QuicErrorCode expected_error =
443       VersionHasIetfQuicFrames(transport_version())
444           ? QUIC_HTTP_STREAM_WRONG_DIRECTION
445           : QUIC_INVALID_STREAM_ID;
446   EXPECT_CALL(*connection_, CloseConnection(expected_error, _, _));
447   EXPECT_EQ(nullptr, QuicServerSessionBasePeer::GetOrCreateStream(
448                          session_.get(),
449                          session_->next_outgoing_unidirectional_stream_id()));
450 }
451 
TEST_P(QuicServerSessionBaseTest,GetStreamDisconnected)452 TEST_P(QuicServerSessionBaseTest, GetStreamDisconnected) {
453   // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
454   if (version() != AllSupportedVersions()[0]) {
455     return;
456   }
457 
458   // Don't create new streams if the connection is disconnected.
459   QuicConnectionPeer::TearDownLocalConnectionState(connection_);
460   EXPECT_QUIC_BUG(QuicServerSessionBasePeer::GetOrCreateStream(
461                       session_.get(), GetNthClientInitiatedBidirectionalId(0)),
462                   "ShouldCreateIncomingStream called when disconnected");
463 }
464 
465 class MockQuicCryptoServerStream : public QuicCryptoServerStream {
466  public:
MockQuicCryptoServerStream(const QuicCryptoServerConfig * crypto_config,QuicCompressedCertsCache * compressed_certs_cache,QuicServerSessionBase * session,QuicCryptoServerStreamBase::Helper * helper)467   explicit MockQuicCryptoServerStream(
468       const QuicCryptoServerConfig* crypto_config,
469       QuicCompressedCertsCache* compressed_certs_cache,
470       QuicServerSessionBase* session,
471       QuicCryptoServerStreamBase::Helper* helper)
472       : QuicCryptoServerStream(crypto_config, compressed_certs_cache, session,
473                                helper) {}
474   MockQuicCryptoServerStream(const MockQuicCryptoServerStream&) = delete;
475   MockQuicCryptoServerStream& operator=(const MockQuicCryptoServerStream&) =
476       delete;
~MockQuicCryptoServerStream()477   ~MockQuicCryptoServerStream() override {}
478 
479   MOCK_METHOD(void, SendServerConfigUpdate, (const CachedNetworkParameters*),
480               (override));
481 };
482 
483 class MockTlsServerHandshaker : public TlsServerHandshaker {
484  public:
MockTlsServerHandshaker(QuicServerSessionBase * session,const QuicCryptoServerConfig * crypto_config)485   explicit MockTlsServerHandshaker(QuicServerSessionBase* session,
486                                    const QuicCryptoServerConfig* crypto_config)
487       : TlsServerHandshaker(session, crypto_config) {}
488   MockTlsServerHandshaker(const MockTlsServerHandshaker&) = delete;
489   MockTlsServerHandshaker& operator=(const MockTlsServerHandshaker&) = delete;
~MockTlsServerHandshaker()490   ~MockTlsServerHandshaker() override {}
491 
492   MOCK_METHOD(void, SendServerConfigUpdate, (const CachedNetworkParameters*),
493               (override));
494 
495   MOCK_METHOD(std::string, GetAddressToken, (const CachedNetworkParameters*),
496               (const, override));
497 };
498 
TEST_P(QuicServerSessionBaseTest,BandwidthEstimates)499 TEST_P(QuicServerSessionBaseTest, BandwidthEstimates) {
500   if (version().UsesTls() && !version().HasIetfQuicFrames()) {
501     // Skip the Txxx versions.
502     return;
503   }
504 
505   // Test that bandwidth estimate updates are sent to the client, only when
506   // bandwidth resumption is enabled, the bandwidth estimate has changed
507   // sufficiently, enough time has passed,
508   // and we don't have any other data to write.
509 
510   // Client has sent kBWRE connection option to trigger bandwidth resumption.
511   QuicTagVector copt;
512   copt.push_back(kBWRE);
513   copt.push_back(kBWID);
514   QuicConfigPeer::SetReceivedConnectionOptions(session_->config(), copt);
515   connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
516   session_->OnConfigNegotiated();
517   EXPECT_TRUE(
518       QuicServerSessionBasePeer::IsBandwidthResumptionEnabled(session_.get()));
519 
520   int32_t bandwidth_estimate_kbytes_per_second = 123;
521   int32_t max_bandwidth_estimate_kbytes_per_second = 134;
522   int32_t max_bandwidth_estimate_timestamp = 1122334455;
523   const std::string serving_region = "not a real region";
524   session_->set_serving_region(serving_region);
525 
526   if (!VersionUsesHttp3(transport_version())) {
527     session_->UnregisterStreamPriority(
528         QuicUtils::GetHeadersStreamId(transport_version()));
529   }
530   QuicServerSessionBasePeer::SetCryptoStream(session_.get(), nullptr);
531   MockQuicCryptoServerStream* quic_crypto_stream = nullptr;
532   MockTlsServerHandshaker* tls_server_stream = nullptr;
533   if (version().handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
534     quic_crypto_stream = new MockQuicCryptoServerStream(
535         &crypto_config_, &compressed_certs_cache_, session_.get(),
536         &stream_helper_);
537     QuicServerSessionBasePeer::SetCryptoStream(session_.get(),
538                                                quic_crypto_stream);
539   } else {
540     tls_server_stream =
541         new MockTlsServerHandshaker(session_.get(), &crypto_config_);
542     QuicServerSessionBasePeer::SetCryptoStream(session_.get(),
543                                                tls_server_stream);
544   }
545   if (!VersionUsesHttp3(transport_version())) {
546     session_->RegisterStreamPriority(
547         QuicUtils::GetHeadersStreamId(transport_version()),
548         /*is_static=*/true,
549         QuicStreamPriority::Default(session_->priority_type()));
550   }
551 
552   // Set some initial bandwidth values.
553   QuicSentPacketManager* sent_packet_manager =
554       QuicConnectionPeer::GetSentPacketManager(session_->connection());
555   QuicSustainedBandwidthRecorder& bandwidth_recorder =
556       QuicSentPacketManagerPeer::GetBandwidthRecorder(sent_packet_manager);
557   // Seed an rtt measurement equal to the initial default rtt.
558   RttStats* rtt_stats =
559       const_cast<RttStats*>(sent_packet_manager->GetRttStats());
560   rtt_stats->UpdateRtt(rtt_stats->initial_rtt(), QuicTime::Delta::Zero(),
561                        QuicTime::Zero());
562   QuicSustainedBandwidthRecorderPeer::SetBandwidthEstimate(
563       &bandwidth_recorder, bandwidth_estimate_kbytes_per_second);
564   QuicSustainedBandwidthRecorderPeer::SetMaxBandwidthEstimate(
565       &bandwidth_recorder, max_bandwidth_estimate_kbytes_per_second,
566       max_bandwidth_estimate_timestamp);
567   // Queue up some pending data.
568   if (!VersionUsesHttp3(transport_version())) {
569     session_->MarkConnectionLevelWriteBlocked(
570         QuicUtils::GetHeadersStreamId(transport_version()));
571   } else {
572     session_->MarkConnectionLevelWriteBlocked(
573         QuicUtils::GetFirstUnidirectionalStreamId(transport_version(),
574                                                   Perspective::IS_SERVER));
575   }
576   EXPECT_TRUE(session_->HasDataToWrite());
577 
578   // There will be no update sent yet - not enough time has passed.
579   QuicTime now = QuicTime::Zero();
580   session_->OnCongestionWindowChange(now);
581 
582   // Bandwidth estimate has now changed sufficiently but not enough time has
583   // passed to send a Server Config Update.
584   bandwidth_estimate_kbytes_per_second =
585       bandwidth_estimate_kbytes_per_second * 1.6;
586   session_->OnCongestionWindowChange(now);
587 
588   // Bandwidth estimate has now changed sufficiently and enough time has passed,
589   // but not enough packets have been sent.
590   int64_t srtt_ms =
591       sent_packet_manager->GetRttStats()->smoothed_rtt().ToMilliseconds();
592   now = now + QuicTime::Delta::FromMilliseconds(
593                   kMinIntervalBetweenServerConfigUpdatesRTTs * srtt_ms);
594   session_->OnCongestionWindowChange(now);
595 
596   // The connection no longer has pending data to be written.
597   session_->OnCanWrite();
598   EXPECT_FALSE(session_->HasDataToWrite());
599   session_->OnCongestionWindowChange(now);
600 
601   // Bandwidth estimate has now changed sufficiently, enough time has passed,
602   // and enough packets have been sent.
603   SerializedPacket packet(
604       QuicPacketNumber(1) + kMinPacketsBetweenServerConfigUpdates,
605       PACKET_4BYTE_PACKET_NUMBER, nullptr, 1000, false, false);
606   sent_packet_manager->OnPacketSent(&packet, now, NOT_RETRANSMISSION,
607                                     HAS_RETRANSMITTABLE_DATA, true,
608                                     ECN_NOT_ECT);
609 
610   // Verify that the proto has exactly the values we expect.
611   CachedNetworkParameters expected_network_params;
612   expected_network_params.set_bandwidth_estimate_bytes_per_second(
613       bandwidth_recorder.BandwidthEstimate().ToBytesPerSecond());
614   expected_network_params.set_max_bandwidth_estimate_bytes_per_second(
615       bandwidth_recorder.MaxBandwidthEstimate().ToBytesPerSecond());
616   expected_network_params.set_max_bandwidth_timestamp_seconds(
617       bandwidth_recorder.MaxBandwidthTimestamp());
618   expected_network_params.set_min_rtt_ms(session_->connection()
619                                              ->sent_packet_manager()
620                                              .GetRttStats()
621                                              ->min_rtt()
622                                              .ToMilliseconds());
623   expected_network_params.set_previous_connection_state(
624       CachedNetworkParameters::CONGESTION_AVOIDANCE);
625   expected_network_params.set_timestamp(
626       session_->connection()->clock()->WallNow().ToUNIXSeconds());
627   expected_network_params.set_serving_region(serving_region);
628 
629   if (quic_crypto_stream) {
630     EXPECT_CALL(*quic_crypto_stream,
631                 SendServerConfigUpdate(EqualsProto(expected_network_params)))
632         .Times(1);
633   } else {
634     EXPECT_CALL(*tls_server_stream,
635                 GetAddressToken(EqualsProto(expected_network_params)))
636         .WillOnce(testing::Return("Test address token"));
637   }
638   EXPECT_CALL(*connection_, OnSendConnectionState(_)).Times(1);
639   session_->OnCongestionWindowChange(now);
640 }
641 
TEST_P(QuicServerSessionBaseTest,BandwidthResumptionExperiment)642 TEST_P(QuicServerSessionBaseTest, BandwidthResumptionExperiment) {
643   if (version().UsesTls()) {
644     if (!version().HasIetfQuicFrames()) {
645       // Skip the Txxx versions.
646       return;
647     }
648     // Avoid a QUIC_BUG in QuicSession::OnConfigNegotiated.
649     connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
650   }
651 
652   // Test that if a client provides a CachedNetworkParameters with the same
653   // serving region as the current server, and which was made within an hour of
654   // now, that this data is passed down to the send algorithm.
655 
656   // Client has sent kBWRE connection option to trigger bandwidth resumption.
657   QuicTagVector copt;
658   copt.push_back(kBWRE);
659   QuicConfigPeer::SetReceivedConnectionOptions(session_->config(), copt);
660 
661   const std::string kTestServingRegion = "a serving region";
662   session_->set_serving_region(kTestServingRegion);
663 
664   // Set the time to be one hour + one second from the 0 baseline.
665   connection_->AdvanceTime(
666       QuicTime::Delta::FromSeconds(kNumSecondsPerHour + 1));
667 
668   QuicCryptoServerStreamBase* crypto_stream =
669       static_cast<QuicCryptoServerStreamBase*>(
670           QuicSessionPeer::GetMutableCryptoStream(session_.get()));
671 
672   // No effect if no CachedNetworkParameters provided.
673   EXPECT_CALL(*connection_, ResumeConnectionState(_, _)).Times(0);
674   session_->OnConfigNegotiated();
675 
676   // No effect if CachedNetworkParameters provided, but different serving
677   // regions.
678   CachedNetworkParameters cached_network_params;
679   cached_network_params.set_bandwidth_estimate_bytes_per_second(1);
680   cached_network_params.set_serving_region("different serving region");
681   crypto_stream->SetPreviousCachedNetworkParams(cached_network_params);
682   EXPECT_CALL(*connection_, ResumeConnectionState(_, _)).Times(0);
683   session_->OnConfigNegotiated();
684 
685   // Same serving region, but timestamp is too old, should have no effect.
686   cached_network_params.set_serving_region(kTestServingRegion);
687   cached_network_params.set_timestamp(0);
688   crypto_stream->SetPreviousCachedNetworkParams(cached_network_params);
689   EXPECT_CALL(*connection_, ResumeConnectionState(_, _)).Times(0);
690   session_->OnConfigNegotiated();
691 
692   // Same serving region, and timestamp is recent: estimate is stored.
693   cached_network_params.set_timestamp(
694       connection_->clock()->WallNow().ToUNIXSeconds());
695   crypto_stream->SetPreviousCachedNetworkParams(cached_network_params);
696   EXPECT_CALL(*connection_, ResumeConnectionState(_, _)).Times(1);
697   session_->OnConfigNegotiated();
698 }
699 
TEST_P(QuicServerSessionBaseTest,BandwidthMaxEnablesResumption)700 TEST_P(QuicServerSessionBaseTest, BandwidthMaxEnablesResumption) {
701   EXPECT_FALSE(
702       QuicServerSessionBasePeer::IsBandwidthResumptionEnabled(session_.get()));
703 
704   // Client has sent kBWMX connection option to trigger bandwidth resumption.
705   QuicTagVector copt;
706   copt.push_back(kBWMX);
707   QuicConfigPeer::SetReceivedConnectionOptions(session_->config(), copt);
708   connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
709   session_->OnConfigNegotiated();
710   EXPECT_TRUE(
711       QuicServerSessionBasePeer::IsBandwidthResumptionEnabled(session_.get()));
712 }
713 
TEST_P(QuicServerSessionBaseTest,NoBandwidthResumptionByDefault)714 TEST_P(QuicServerSessionBaseTest, NoBandwidthResumptionByDefault) {
715   EXPECT_FALSE(
716       QuicServerSessionBasePeer::IsBandwidthResumptionEnabled(session_.get()));
717   connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
718   session_->OnConfigNegotiated();
719   EXPECT_FALSE(
720       QuicServerSessionBasePeer::IsBandwidthResumptionEnabled(session_.get()));
721 }
722 
723 // Tests which check the lifetime management of data members of
724 // QuicCryptoServerStream objects when async GetProof is in use.
725 class StreamMemberLifetimeTest : public QuicServerSessionBaseTest {
726  public:
StreamMemberLifetimeTest()727   StreamMemberLifetimeTest()
728       : QuicServerSessionBaseTest(
729             std::unique_ptr<FakeProofSource>(new FakeProofSource())),
730         crypto_config_peer_(&crypto_config_) {
731     GetFakeProofSource()->Activate();
732   }
733 
GetFakeProofSource() const734   FakeProofSource* GetFakeProofSource() const {
735     return static_cast<FakeProofSource*>(crypto_config_peer_.GetProofSource());
736   }
737 
738  private:
739   QuicCryptoServerConfigPeer crypto_config_peer_;
740 };
741 
742 INSTANTIATE_TEST_SUITE_P(StreamMemberLifetimeTests, StreamMemberLifetimeTest,
743                          ::testing::ValuesIn(AllSupportedVersions()),
744                          ::testing::PrintToStringParamName());
745 
746 // Trigger an operation which causes an async invocation of
747 // ProofSource::GetProof.  Delay the completion of the operation until after the
748 // stream has been destroyed, and verify that there are no memory bugs.
TEST_P(StreamMemberLifetimeTest,Basic)749 TEST_P(StreamMemberLifetimeTest, Basic) {
750   if (version().handshake_protocol == PROTOCOL_TLS1_3) {
751     // This test depends on the QUIC crypto protocol, so it is disabled for the
752     // TLS handshake.
753     // TODO(nharper): Fix this test so it doesn't rely on QUIC crypto.
754     return;
755   }
756 
757   const QuicClock* clock = helper_.GetClock();
758   CryptoHandshakeMessage chlo = crypto_test_utils::GenerateDefaultInchoateCHLO(
759       clock, transport_version(), &crypto_config_);
760   chlo.SetVector(kCOPT, QuicTagVector{kREJ});
761   std::vector<ParsedQuicVersion> packet_version_list = {version()};
762   std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
763       TestConnectionId(1), EmptyQuicConnectionId(), true, false, 1,
764       std::string(chlo.GetSerialized().AsStringPiece()), CONNECTION_ID_PRESENT,
765       CONNECTION_ID_ABSENT, PACKET_4BYTE_PACKET_NUMBER, &packet_version_list));
766 
767   EXPECT_CALL(stream_helper_, CanAcceptClientHello(_, _, _, _, _))
768       .WillOnce(testing::Return(true));
769 
770   // Set the current packet
771   QuicConnectionPeer::SetCurrentPacket(session_->connection(),
772                                        packet->AsStringPiece());
773 
774   // Yes, this is horrible.  But it's the easiest way to trigger the behavior we
775   // need to exercise.
776   QuicCryptoServerStreamBase* crypto_stream =
777       const_cast<QuicCryptoServerStreamBase*>(session_->crypto_stream());
778 
779   // Feed the CHLO into the crypto stream, which will trigger a call to
780   // ProofSource::GetProof
781   crypto_test_utils::SendHandshakeMessageToStream(crypto_stream, chlo,
782                                                   Perspective::IS_CLIENT);
783   ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
784 
785   // Destroy the stream
786   session_.reset();
787 
788   // Allow the async ProofSource::GetProof call to complete.  Verify (under
789   // memory access checkers) that this does not result in accesses to any
790   // freed memory from the session or its subobjects.
791   GetFakeProofSource()->InvokePendingCallback(0);
792 }
793 
794 }  // namespace
795 }  // namespace test
796 }  // namespace quic
797