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