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