• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 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/quic_session.h"
6 
7 #include <cstdint>
8 #include <string>
9 #include <utility>
10 
11 #include "absl/memory/memory.h"
12 #include "absl/strings/str_cat.h"
13 #include "absl/strings/string_view.h"
14 #include "quiche/quic/core/frames/quic_ack_frequency_frame.h"
15 #include "quiche/quic/core/frames/quic_window_update_frame.h"
16 #include "quiche/quic/core/quic_connection.h"
17 #include "quiche/quic/core/quic_connection_context.h"
18 #include "quiche/quic/core/quic_error_codes.h"
19 #include "quiche/quic/core/quic_flow_controller.h"
20 #include "quiche/quic/core/quic_stream_priority.h"
21 #include "quiche/quic/core/quic_types.h"
22 #include "quiche/quic/core/quic_utils.h"
23 #include "quiche/quic/core/quic_versions.h"
24 #include "quiche/quic/core/quic_write_blocked_list.h"
25 #include "quiche/quic/platform/api/quic_bug_tracker.h"
26 #include "quiche/quic/platform/api/quic_flag_utils.h"
27 #include "quiche/quic/platform/api/quic_flags.h"
28 #include "quiche/quic/platform/api/quic_logging.h"
29 #include "quiche/quic/platform/api/quic_server_stats.h"
30 #include "quiche/quic/platform/api/quic_stack_trace.h"
31 #include "quiche/common/platform/api/quiche_logging.h"
32 #include "quiche/common/quiche_text_utils.h"
33 
34 namespace quic {
35 
36 namespace {
37 
38 class ClosedStreamsCleanUpDelegate : public QuicAlarm::Delegate {
39  public:
ClosedStreamsCleanUpDelegate(QuicSession * session)40   explicit ClosedStreamsCleanUpDelegate(QuicSession* session)
41       : session_(session) {}
42   ClosedStreamsCleanUpDelegate(const ClosedStreamsCleanUpDelegate&) = delete;
43   ClosedStreamsCleanUpDelegate& operator=(const ClosedStreamsCleanUpDelegate&) =
44       delete;
45 
GetConnectionContext()46   QuicConnectionContext* GetConnectionContext() override {
47     return (session_->connection() == nullptr)
48                ? nullptr
49                : session_->connection()->context();
50   }
51 
OnAlarm()52   void OnAlarm() override { session_->CleanUpClosedStreams(); }
53 
54  private:
55   QuicSession* session_;
56 };
57 
58 }  // namespace
59 
60 #define ENDPOINT \
61   (perspective() == Perspective::IS_SERVER ? "Server: " : "Client: ")
62 
QuicSession(QuicConnection * connection,Visitor * owner,const QuicConfig & config,const ParsedQuicVersionVector & supported_versions,QuicStreamCount num_expected_unidirectional_static_streams)63 QuicSession::QuicSession(
64     QuicConnection* connection, Visitor* owner, const QuicConfig& config,
65     const ParsedQuicVersionVector& supported_versions,
66     QuicStreamCount num_expected_unidirectional_static_streams)
67     : QuicSession(connection, owner, config, supported_versions,
68                   num_expected_unidirectional_static_streams, nullptr) {}
69 
QuicSession(QuicConnection * connection,Visitor * owner,const QuicConfig & config,const ParsedQuicVersionVector & supported_versions,QuicStreamCount num_expected_unidirectional_static_streams,std::unique_ptr<QuicDatagramQueue::Observer> datagram_observer)70 QuicSession::QuicSession(
71     QuicConnection* connection, Visitor* owner, const QuicConfig& config,
72     const ParsedQuicVersionVector& supported_versions,
73     QuicStreamCount num_expected_unidirectional_static_streams,
74     std::unique_ptr<QuicDatagramQueue::Observer> datagram_observer)
75     : connection_(connection),
76       perspective_(connection->perspective()),
77       visitor_(owner),
78       write_blocked_streams_(std::make_unique<QuicWriteBlockedList>()),
79       config_(config),
80       stream_id_manager_(perspective(), connection->transport_version(),
81                          kDefaultMaxStreamsPerConnection,
82                          config_.GetMaxBidirectionalStreamsToSend()),
83       ietf_streamid_manager_(perspective(), connection->version(), this, 0,
84                              num_expected_unidirectional_static_streams,
85                              config_.GetMaxBidirectionalStreamsToSend(),
86                              config_.GetMaxUnidirectionalStreamsToSend() +
87                                  num_expected_unidirectional_static_streams),
88       num_draining_streams_(0),
89       num_outgoing_draining_streams_(0),
90       num_static_streams_(0),
91       num_zombie_streams_(0),
92       flow_controller_(
93           this, QuicUtils::GetInvalidStreamId(connection->transport_version()),
94           /*is_connection_flow_controller*/ true,
95           connection->version().AllowsLowFlowControlLimits()
96               ? 0
97               : kMinimumFlowControlSendWindow,
98           config_.GetInitialSessionFlowControlWindowToSend(),
99           kSessionReceiveWindowLimit, perspective() == Perspective::IS_SERVER,
100           nullptr),
101       currently_writing_stream_id_(0),
102       transport_goaway_sent_(false),
103       transport_goaway_received_(false),
104       control_frame_manager_(this),
105       last_message_id_(0),
106       datagram_queue_(this, std::move(datagram_observer)),
107       closed_streams_clean_up_alarm_(nullptr),
108       supported_versions_(supported_versions),
109       is_configured_(false),
110       was_zero_rtt_rejected_(false),
111       liveness_testing_in_progress_(false) {
112   closed_streams_clean_up_alarm_ =
113       absl::WrapUnique<QuicAlarm>(connection_->alarm_factory()->CreateAlarm(
114           new ClosedStreamsCleanUpDelegate(this)));
115   if (VersionHasIetfQuicFrames(transport_version())) {
116     config_.SetMaxUnidirectionalStreamsToSend(
117         config_.GetMaxUnidirectionalStreamsToSend() +
118         num_expected_unidirectional_static_streams);
119   }
120 }
121 
Initialize()122 void QuicSession::Initialize() {
123   connection_->set_visitor(this);
124   connection_->SetSessionNotifier(this);
125   connection_->SetDataProducer(this);
126   connection_->SetUnackedMapInitialCapacity();
127   connection_->SetFromConfig(config_);
128   if (perspective_ == Perspective::IS_CLIENT) {
129     if (config_.HasClientRequestedIndependentOption(kAFFE, perspective_) &&
130         version().HasIetfQuicFrames()) {
131       connection_->set_can_receive_ack_frequency_frame();
132       config_.SetMinAckDelayMs(kDefaultMinAckDelayTimeMs);
133     }
134   }
135   if (perspective() == Perspective::IS_SERVER &&
136       connection_->version().handshake_protocol == PROTOCOL_TLS1_3) {
137     config_.SetStatelessResetTokenToSend(GetStatelessResetToken());
138   }
139 
140   connection_->CreateConnectionIdManager();
141 
142   // On the server side, version negotiation has been done by the dispatcher,
143   // and the server session is created with the right version.
144   if (perspective() == Perspective::IS_SERVER) {
145     connection_->OnSuccessfulVersionNegotiation();
146   }
147 
148   if (QuicVersionUsesCryptoFrames(transport_version())) {
149     return;
150   }
151 
152   QUICHE_DCHECK_EQ(QuicUtils::GetCryptoStreamId(transport_version()),
153                    GetMutableCryptoStream()->id());
154 }
155 
~QuicSession()156 QuicSession::~QuicSession() {
157   if (closed_streams_clean_up_alarm_ != nullptr) {
158     closed_streams_clean_up_alarm_->PermanentCancel();
159   }
160 }
161 
PendingStreamOnStreamFrame(const QuicStreamFrame & frame)162 PendingStream* QuicSession::PendingStreamOnStreamFrame(
163     const QuicStreamFrame& frame) {
164   QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
165   QuicStreamId stream_id = frame.stream_id;
166 
167   PendingStream* pending = GetOrCreatePendingStream(stream_id);
168 
169   if (!pending) {
170     if (frame.fin) {
171       QuicStreamOffset final_byte_offset = frame.offset + frame.data_length;
172       OnFinalByteOffsetReceived(stream_id, final_byte_offset);
173     }
174     return nullptr;
175   }
176 
177   pending->OnStreamFrame(frame);
178   if (!connection()->connected()) {
179     return nullptr;
180   }
181   return pending;
182 }
183 
MaybeProcessPendingStream(PendingStream * pending)184 void QuicSession::MaybeProcessPendingStream(PendingStream* pending) {
185   QUICHE_DCHECK(pending != nullptr);
186   QuicStreamId stream_id = pending->id();
187   absl::optional<QuicResetStreamError> stop_sending_error_code =
188       pending->GetStopSendingErrorCode();
189   QuicStream* stream = ProcessPendingStream(pending);
190   if (stream != nullptr) {
191     // The pending stream should now be in the scope of normal streams.
192     QUICHE_DCHECK(IsClosedStream(stream_id) || IsOpenStream(stream_id))
193         << "Stream " << stream_id << " not created";
194     pending_stream_map_.erase(stream_id);
195     if (stop_sending_error_code) {
196       stream->OnStopSending(*stop_sending_error_code);
197       if (!connection()->connected()) {
198         return;
199       }
200     }
201     stream->OnStreamCreatedFromPendingStream();
202     return;
203   }
204   // At this point, none of the bytes has been successfully consumed by the
205   // application layer. We should close the pending stream even if it is
206   // bidirectionl as no application will be able to write in a bidirectional
207   // stream with zero byte as input.
208   if (pending->sequencer()->IsClosed()) {
209     ClosePendingStream(stream_id);
210   }
211 }
212 
PendingStreamOnWindowUpdateFrame(const QuicWindowUpdateFrame & frame)213 void QuicSession::PendingStreamOnWindowUpdateFrame(
214     const QuicWindowUpdateFrame& frame) {
215   QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
216   PendingStream* pending = GetOrCreatePendingStream(frame.stream_id);
217   if (pending) {
218     pending->OnWindowUpdateFrame(frame);
219   }
220 }
221 
PendingStreamOnStopSendingFrame(const QuicStopSendingFrame & frame)222 void QuicSession::PendingStreamOnStopSendingFrame(
223     const QuicStopSendingFrame& frame) {
224   QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
225   PendingStream* pending = GetOrCreatePendingStream(frame.stream_id);
226   if (pending) {
227     pending->OnStopSending(frame.error());
228   }
229 }
230 
OnStreamFrame(const QuicStreamFrame & frame)231 void QuicSession::OnStreamFrame(const QuicStreamFrame& frame) {
232   QuicStreamId stream_id = frame.stream_id;
233   if (stream_id == QuicUtils::GetInvalidStreamId(transport_version())) {
234     connection()->CloseConnection(
235         QUIC_INVALID_STREAM_ID, "Received data for an invalid stream",
236         ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
237     return;
238   }
239 
240   if (ShouldProcessFrameByPendingStream(STREAM_FRAME, stream_id)) {
241     PendingStream* pending = PendingStreamOnStreamFrame(frame);
242     if (pending != nullptr && ShouldProcessPendingStreamImmediately()) {
243       MaybeProcessPendingStream(pending);
244     }
245     return;
246   }
247 
248   QuicStream* stream = GetOrCreateStream(stream_id);
249 
250   if (!stream) {
251     // The stream no longer exists, but we may still be interested in the
252     // final stream byte offset sent by the peer. A frame with a FIN can give
253     // us this offset.
254     if (frame.fin) {
255       QuicStreamOffset final_byte_offset = frame.offset + frame.data_length;
256       OnFinalByteOffsetReceived(stream_id, final_byte_offset);
257     }
258     return;
259   }
260   stream->OnStreamFrame(frame);
261 }
262 
OnCryptoFrame(const QuicCryptoFrame & frame)263 void QuicSession::OnCryptoFrame(const QuicCryptoFrame& frame) {
264   GetMutableCryptoStream()->OnCryptoFrame(frame);
265 }
266 
OnStopSendingFrame(const QuicStopSendingFrame & frame)267 void QuicSession::OnStopSendingFrame(const QuicStopSendingFrame& frame) {
268   // STOP_SENDING is in IETF QUIC only.
269   QUICHE_DCHECK(VersionHasIetfQuicFrames(transport_version()));
270   QUICHE_DCHECK(QuicVersionUsesCryptoFrames(transport_version()));
271 
272   QuicStreamId stream_id = frame.stream_id;
273   // If Stream ID is invalid then close the connection.
274   // TODO(ianswett): This check is redundant to checks for IsClosedStream,
275   // but removing it requires removing multiple QUICHE_DCHECKs.
276   // TODO(ianswett): Multiple QUIC_DVLOGs could be QUIC_PEER_BUGs.
277   if (stream_id == QuicUtils::GetInvalidStreamId(transport_version())) {
278     QUIC_DVLOG(1) << ENDPOINT
279                   << "Received STOP_SENDING with invalid stream_id: "
280                   << stream_id << " Closing connection";
281     connection()->CloseConnection(
282         QUIC_INVALID_STREAM_ID, "Received STOP_SENDING for an invalid stream",
283         ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
284     return;
285   }
286 
287   // If stream_id is READ_UNIDIRECTIONAL, close the connection.
288   if (QuicUtils::GetStreamType(stream_id, perspective(),
289                                IsIncomingStream(stream_id),
290                                version()) == READ_UNIDIRECTIONAL) {
291     QUIC_DVLOG(1) << ENDPOINT
292                   << "Received STOP_SENDING for a read-only stream_id: "
293                   << stream_id << ".";
294     connection()->CloseConnection(
295         QUIC_INVALID_STREAM_ID, "Received STOP_SENDING for a read-only stream",
296         ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
297     return;
298   }
299 
300   if (visitor_) {
301     visitor_->OnStopSendingReceived(frame);
302   }
303   if (ShouldProcessFrameByPendingStream(STOP_SENDING_FRAME, stream_id)) {
304     PendingStreamOnStopSendingFrame(frame);
305     return;
306   }
307 
308   QuicStream* stream = GetOrCreateStream(stream_id);
309   if (!stream) {
310     // Errors are handled by GetOrCreateStream.
311     return;
312   }
313 
314   stream->OnStopSending(frame.error());
315 }
316 
OnPacketDecrypted(EncryptionLevel level)317 void QuicSession::OnPacketDecrypted(EncryptionLevel level) {
318   GetMutableCryptoStream()->OnPacketDecrypted(level);
319   if (liveness_testing_in_progress_) {
320     liveness_testing_in_progress_ = false;
321     OnCanCreateNewOutgoingStream(/*unidirectional=*/false);
322   }
323 }
324 
OnOneRttPacketAcknowledged()325 void QuicSession::OnOneRttPacketAcknowledged() {
326   GetMutableCryptoStream()->OnOneRttPacketAcknowledged();
327 }
328 
OnHandshakePacketSent()329 void QuicSession::OnHandshakePacketSent() {
330   GetMutableCryptoStream()->OnHandshakePacketSent();
331 }
332 
333 std::unique_ptr<QuicDecrypter>
AdvanceKeysAndCreateCurrentOneRttDecrypter()334 QuicSession::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
335   return GetMutableCryptoStream()->AdvanceKeysAndCreateCurrentOneRttDecrypter();
336 }
337 
CreateCurrentOneRttEncrypter()338 std::unique_ptr<QuicEncrypter> QuicSession::CreateCurrentOneRttEncrypter() {
339   return GetMutableCryptoStream()->CreateCurrentOneRttEncrypter();
340 }
341 
PendingStreamOnRstStream(const QuicRstStreamFrame & frame)342 void QuicSession::PendingStreamOnRstStream(const QuicRstStreamFrame& frame) {
343   QUICHE_DCHECK(VersionUsesHttp3(transport_version()));
344   QuicStreamId stream_id = frame.stream_id;
345 
346   PendingStream* pending = GetOrCreatePendingStream(stream_id);
347 
348   if (!pending) {
349     HandleRstOnValidNonexistentStream(frame);
350     return;
351   }
352 
353   pending->OnRstStreamFrame(frame);
354   // At this point, none of the bytes has been consumed by the application
355   // layer. It is safe to close the pending stream even if it is bidirectionl as
356   // no application will be able to write in a bidirectional stream with zero
357   // byte as input.
358   ClosePendingStream(stream_id);
359 }
360 
OnRstStream(const QuicRstStreamFrame & frame)361 void QuicSession::OnRstStream(const QuicRstStreamFrame& frame) {
362   QuicStreamId stream_id = frame.stream_id;
363   if (stream_id == QuicUtils::GetInvalidStreamId(transport_version())) {
364     connection()->CloseConnection(
365         QUIC_INVALID_STREAM_ID, "Received data for an invalid stream",
366         ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
367     return;
368   }
369 
370   if (VersionHasIetfQuicFrames(transport_version()) &&
371       QuicUtils::GetStreamType(stream_id, perspective(),
372                                IsIncomingStream(stream_id),
373                                version()) == WRITE_UNIDIRECTIONAL) {
374     connection()->CloseConnection(
375         QUIC_INVALID_STREAM_ID, "Received RESET_STREAM for a write-only stream",
376         ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
377     return;
378   }
379 
380   if (visitor_) {
381     visitor_->OnRstStreamReceived(frame);
382   }
383 
384   if (ShouldProcessFrameByPendingStream(RST_STREAM_FRAME, stream_id)) {
385     PendingStreamOnRstStream(frame);
386     return;
387   }
388 
389   QuicStream* stream = GetOrCreateStream(stream_id);
390 
391   if (!stream) {
392     HandleRstOnValidNonexistentStream(frame);
393     return;  // Errors are handled by GetOrCreateStream.
394   }
395   stream->OnStreamReset(frame);
396 }
397 
OnGoAway(const QuicGoAwayFrame &)398 void QuicSession::OnGoAway(const QuicGoAwayFrame& /*frame*/) {
399   QUIC_BUG_IF(quic_bug_12435_1, version().UsesHttp3())
400       << "gQUIC GOAWAY received on version " << version();
401 
402   transport_goaway_received_ = true;
403 }
404 
OnMessageReceived(absl::string_view message)405 void QuicSession::OnMessageReceived(absl::string_view message) {
406   QUIC_DVLOG(1) << ENDPOINT << "Received message of length "
407                 << message.length();
408   QUIC_DVLOG(2) << ENDPOINT << "Contents of message of length "
409                 << message.length() << ":" << std::endl
410                 << quiche::QuicheTextUtils::HexDump(message);
411 }
412 
OnHandshakeDoneReceived()413 void QuicSession::OnHandshakeDoneReceived() {
414   QUIC_DVLOG(1) << ENDPOINT << "OnHandshakeDoneReceived";
415   GetMutableCryptoStream()->OnHandshakeDoneReceived();
416 }
417 
OnNewTokenReceived(absl::string_view token)418 void QuicSession::OnNewTokenReceived(absl::string_view token) {
419   QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
420   GetMutableCryptoStream()->OnNewTokenReceived(token);
421 }
422 
423 // static
RecordConnectionCloseAtServer(QuicErrorCode error,ConnectionCloseSource source)424 void QuicSession::RecordConnectionCloseAtServer(QuicErrorCode error,
425                                                 ConnectionCloseSource source) {
426   if (error != QUIC_NO_ERROR) {
427     if (source == ConnectionCloseSource::FROM_SELF) {
428       QUIC_SERVER_HISTOGRAM_ENUM(
429           "quic_server_connection_close_errors", error, QUIC_LAST_ERROR,
430           "QuicErrorCode for server-closed connections.");
431     } else {
432       QUIC_SERVER_HISTOGRAM_ENUM(
433           "quic_client_connection_close_errors", error, QUIC_LAST_ERROR,
434           "QuicErrorCode for client-closed connections.");
435     }
436   }
437 }
438 
OnConnectionClosed(const QuicConnectionCloseFrame & frame,ConnectionCloseSource source)439 void QuicSession::OnConnectionClosed(const QuicConnectionCloseFrame& frame,
440                                      ConnectionCloseSource source) {
441   QUICHE_DCHECK(!connection_->connected());
442   if (perspective() == Perspective::IS_SERVER) {
443     RecordConnectionCloseAtServer(frame.quic_error_code, source);
444   }
445 
446   if (on_closed_frame_.quic_error_code == QUIC_NO_ERROR) {
447     // Save all of the connection close information
448     on_closed_frame_ = frame;
449     source_ = source;
450   }
451 
452   GetMutableCryptoStream()->OnConnectionClosed(frame.quic_error_code, source);
453 
454   PerformActionOnActiveStreams([this, frame, source](QuicStream* stream) {
455     QuicStreamId id = stream->id();
456     stream->OnConnectionClosed(frame.quic_error_code, source);
457     auto it = stream_map_.find(id);
458     if (it != stream_map_.end()) {
459       QUIC_BUG_IF(quic_bug_12435_2, !it->second->IsZombie())
460           << ENDPOINT << "Non-zombie stream " << id
461           << " failed to close under OnConnectionClosed";
462     }
463     return true;
464   });
465 
466   closed_streams_clean_up_alarm_->Cancel();
467 
468   if (visitor_) {
469     visitor_->OnConnectionClosed(connection_->GetOneActiveServerConnectionId(),
470                                  frame.quic_error_code, frame.error_details,
471                                  source);
472   }
473 }
474 
OnWriteBlocked()475 void QuicSession::OnWriteBlocked() {
476   if (!connection_->connected()) {
477     return;
478   }
479   if (visitor_) {
480     visitor_->OnWriteBlocked(connection_);
481   }
482 }
483 
OnSuccessfulVersionNegotiation(const ParsedQuicVersion &)484 void QuicSession::OnSuccessfulVersionNegotiation(
485     const ParsedQuicVersion& /*version*/) {}
486 
OnPacketReceived(const QuicSocketAddress &,const QuicSocketAddress & peer_address,bool is_connectivity_probe)487 void QuicSession::OnPacketReceived(const QuicSocketAddress& /*self_address*/,
488                                    const QuicSocketAddress& peer_address,
489                                    bool is_connectivity_probe) {
490   if (is_connectivity_probe && perspective() == Perspective::IS_SERVER) {
491     // Server only sends back a connectivity probe after received a
492     // connectivity probe from a new peer address.
493     connection_->SendConnectivityProbingPacket(nullptr, peer_address);
494   }
495 }
496 
OnPathDegrading()497 void QuicSession::OnPathDegrading() {}
498 
OnForwardProgressMadeAfterPathDegrading()499 void QuicSession::OnForwardProgressMadeAfterPathDegrading() {}
500 
AllowSelfAddressChange() const501 bool QuicSession::AllowSelfAddressChange() const { return false; }
502 
OnWindowUpdateFrame(const QuicWindowUpdateFrame & frame)503 void QuicSession::OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) {
504   // Stream may be closed by the time we receive a WINDOW_UPDATE, so we can't
505   // assume that it still exists.
506   QuicStreamId stream_id = frame.stream_id;
507   if (stream_id == QuicUtils::GetInvalidStreamId(transport_version())) {
508     // This is a window update that applies to the connection, rather than an
509     // individual stream.
510     QUIC_DVLOG(1) << ENDPOINT
511                   << "Received connection level flow control window "
512                      "update with max data: "
513                   << frame.max_data;
514     flow_controller_.UpdateSendWindowOffset(frame.max_data);
515     return;
516   }
517 
518   if (VersionHasIetfQuicFrames(transport_version()) &&
519       QuicUtils::GetStreamType(stream_id, perspective(),
520                                IsIncomingStream(stream_id),
521                                version()) == READ_UNIDIRECTIONAL) {
522     connection()->CloseConnection(
523         QUIC_WINDOW_UPDATE_RECEIVED_ON_READ_UNIDIRECTIONAL_STREAM,
524         "WindowUpdateFrame received on READ_UNIDIRECTIONAL stream.",
525         ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
526     return;
527   }
528 
529   if (ShouldProcessFrameByPendingStream(WINDOW_UPDATE_FRAME, stream_id)) {
530     PendingStreamOnWindowUpdateFrame(frame);
531     return;
532   }
533 
534   QuicStream* stream = GetOrCreateStream(stream_id);
535   if (stream != nullptr) {
536     stream->OnWindowUpdateFrame(frame);
537   }
538 }
539 
OnBlockedFrame(const QuicBlockedFrame & frame)540 void QuicSession::OnBlockedFrame(const QuicBlockedFrame& frame) {
541   // TODO(rjshade): Compare our flow control receive windows for specified
542   //                streams: if we have a large window then maybe something
543   //                had gone wrong with the flow control accounting.
544   QUIC_DLOG(INFO) << ENDPOINT << "Received BLOCKED frame with stream id: "
545                   << frame.stream_id << ", offset: " << frame.offset;
546 }
547 
CheckStreamNotBusyLooping(QuicStream * stream,uint64_t previous_bytes_written,bool previous_fin_sent)548 bool QuicSession::CheckStreamNotBusyLooping(QuicStream* stream,
549                                             uint64_t previous_bytes_written,
550                                             bool previous_fin_sent) {
551   if (  // Stream should not be closed.
552       !stream->write_side_closed() &&
553       // Not connection flow control blocked.
554       !flow_controller_.IsBlocked() &&
555       // Detect lack of forward progress.
556       previous_bytes_written == stream->stream_bytes_written() &&
557       previous_fin_sent == stream->fin_sent()) {
558     stream->set_busy_counter(stream->busy_counter() + 1);
559     QUIC_DVLOG(1) << ENDPOINT << "Suspected busy loop on stream id "
560                   << stream->id() << " stream_bytes_written "
561                   << stream->stream_bytes_written() << " fin "
562                   << stream->fin_sent() << " count " << stream->busy_counter();
563     // Wait a few iterations before firing, the exact count is
564     // arbitrary, more than a few to cover a few test-only false
565     // positives.
566     if (stream->busy_counter() > 20) {
567       QUIC_LOG(ERROR) << ENDPOINT << "Detected busy loop on stream id "
568                       << stream->id() << " stream_bytes_written "
569                       << stream->stream_bytes_written() << " fin "
570                       << stream->fin_sent();
571       return false;
572     }
573   } else {
574     stream->set_busy_counter(0);
575   }
576   return true;
577 }
578 
CheckStreamWriteBlocked(QuicStream * stream) const579 bool QuicSession::CheckStreamWriteBlocked(QuicStream* stream) const {
580   if (!stream->write_side_closed() && stream->HasBufferedData() &&
581       !stream->IsFlowControlBlocked() &&
582       !write_blocked_streams_->IsStreamBlocked(stream->id())) {
583     QUIC_DLOG(ERROR) << ENDPOINT << "stream " << stream->id()
584                      << " has buffered " << stream->BufferedDataBytes()
585                      << " bytes, and is not flow control blocked, "
586                         "but it is not in the write block list.";
587     return false;
588   }
589   return true;
590 }
591 
OnCanWrite()592 void QuicSession::OnCanWrite() {
593   if (connection_->framer().is_processing_packet()) {
594     // Do not write data in the middle of packet processing because rest
595     // frames in the packet may change the data to write. For example, lost
596     // data could be acknowledged. Also, connection is going to emit
597     // OnCanWrite signal post packet processing.
598     QUIC_BUG(session_write_mid_packet_processing)
599         << ENDPOINT << "Try to write mid packet processing.";
600     return;
601   }
602   if (!RetransmitLostData()) {
603     // Cannot finish retransmitting lost data, connection is write blocked.
604     QUIC_DVLOG(1) << ENDPOINT
605                   << "Cannot finish retransmitting lost data, connection is "
606                      "write blocked.";
607     return;
608   }
609   // We limit the number of writes to the number of pending streams. If more
610   // streams become pending, WillingAndAbleToWrite will be true, which will
611   // cause the connection to request resumption before yielding to other
612   // connections.
613   // If we are connection level flow control blocked, then only allow the
614   // crypto and headers streams to try writing as all other streams will be
615   // blocked.
616   size_t num_writes = flow_controller_.IsBlocked()
617                           ? write_blocked_streams_->NumBlockedSpecialStreams()
618                           : write_blocked_streams_->NumBlockedStreams();
619   if (num_writes == 0 && !control_frame_manager_.WillingToWrite() &&
620       datagram_queue_.empty() &&
621       (!QuicVersionUsesCryptoFrames(transport_version()) ||
622        !GetCryptoStream()->HasBufferedCryptoFrames())) {
623     return;
624   }
625 
626   QuicConnection::ScopedPacketFlusher flusher(connection_);
627   if (QuicVersionUsesCryptoFrames(transport_version())) {
628     QuicCryptoStream* crypto_stream = GetMutableCryptoStream();
629     if (crypto_stream->HasBufferedCryptoFrames()) {
630       crypto_stream->WriteBufferedCryptoFrames();
631     }
632     if ((GetQuicReloadableFlag(
633              quic_no_write_control_frame_upon_connection_close) &&
634          !connection_->connected()) ||
635         crypto_stream->HasBufferedCryptoFrames()) {
636       // Cannot finish writing buffered crypto frames, connection is either
637       // write blocked or closed.
638       return;
639     }
640   }
641   if (control_frame_manager_.WillingToWrite()) {
642     control_frame_manager_.OnCanWrite();
643   }
644   if (version().UsesTls() && GetHandshakeState() != HANDSHAKE_CONFIRMED &&
645       connection_->in_probe_time_out()) {
646     QUIC_CODE_COUNT(quic_donot_pto_stream_data_before_handshake_confirmed);
647     // Do not PTO stream data before handshake gets confirmed.
648     return;
649   }
650   // TODO(b/147146815): this makes all datagrams go before stream data.  We
651   // should have a better priority scheme for this.
652   if (!datagram_queue_.empty()) {
653     size_t written = datagram_queue_.SendDatagrams();
654     QUIC_DVLOG(1) << ENDPOINT << "Sent " << written << " datagrams";
655     if (!datagram_queue_.empty()) {
656       return;
657     }
658   }
659   std::vector<QuicStreamId> last_writing_stream_ids;
660   for (size_t i = 0; i < num_writes; ++i) {
661     if (!(write_blocked_streams_->HasWriteBlockedSpecialStream() ||
662           write_blocked_streams_->HasWriteBlockedDataStreams())) {
663       // Writing one stream removed another!? Something's broken.
664       QUIC_BUG(quic_bug_10866_1)
665           << "WriteBlockedStream is missing, num_writes: " << num_writes
666           << ", finished_writes: " << i
667           << ", connected: " << connection_->connected()
668           << ", connection level flow control blocked: "
669           << flow_controller_.IsBlocked();
670       for (QuicStreamId id : last_writing_stream_ids) {
671         QUIC_LOG(WARNING) << "last_writing_stream_id: " << id;
672       }
673       connection_->CloseConnection(QUIC_INTERNAL_ERROR,
674                                    "WriteBlockedStream is missing",
675                                    ConnectionCloseBehavior::SILENT_CLOSE);
676       return;
677     }
678     if (!CanWriteStreamData()) {
679       return;
680     }
681     currently_writing_stream_id_ = write_blocked_streams_->PopFront();
682     last_writing_stream_ids.push_back(currently_writing_stream_id_);
683     QUIC_DVLOG(1) << ENDPOINT << "Removing stream "
684                   << currently_writing_stream_id_ << " from write-blocked list";
685     QuicStream* stream = GetOrCreateStream(currently_writing_stream_id_);
686     if (stream != nullptr && !stream->IsFlowControlBlocked()) {
687       // If the stream can't write all bytes it'll re-add itself to the blocked
688       // list.
689       uint64_t previous_bytes_written = stream->stream_bytes_written();
690       bool previous_fin_sent = stream->fin_sent();
691       QUIC_DVLOG(1) << ENDPOINT << "stream " << stream->id()
692                     << " bytes_written " << previous_bytes_written << " fin "
693                     << previous_fin_sent;
694       stream->OnCanWrite();
695       QUICHE_DCHECK(CheckStreamWriteBlocked(stream));
696       QUICHE_DCHECK(CheckStreamNotBusyLooping(stream, previous_bytes_written,
697                                               previous_fin_sent));
698     }
699     currently_writing_stream_id_ = 0;
700   }
701 }
702 
WillingAndAbleToWrite() const703 bool QuicSession::WillingAndAbleToWrite() const {
704   // Schedule a write when:
705   // 1) control frame manager has pending or new control frames, or
706   // 2) any stream has pending retransmissions, or
707   // 3) If the crypto or headers streams are blocked, or
708   // 4) connection is not flow control blocked and there are write blocked
709   // streams.
710   if (QuicVersionUsesCryptoFrames(transport_version())) {
711     if (HasPendingHandshake()) {
712       return true;
713     }
714     if (!IsEncryptionEstablished()) {
715       return false;
716     }
717   }
718   if (control_frame_manager_.WillingToWrite() ||
719       !streams_with_pending_retransmission_.empty()) {
720     return true;
721   }
722   if (flow_controller_.IsBlocked()) {
723     if (VersionUsesHttp3(transport_version())) {
724       return false;
725     }
726     // Crypto and headers streams are not blocked by connection level flow
727     // control.
728     return write_blocked_streams_->HasWriteBlockedSpecialStream();
729   }
730   return write_blocked_streams_->HasWriteBlockedSpecialStream() ||
731          write_blocked_streams_->HasWriteBlockedDataStreams();
732 }
733 
GetStreamsInfoForLogging() const734 std::string QuicSession::GetStreamsInfoForLogging() const {
735   std::string info = absl::StrCat(
736       "num_active_streams: ", GetNumActiveStreams(),
737       ", num_pending_streams: ", pending_streams_size(),
738       ", num_outgoing_draining_streams: ", num_outgoing_draining_streams(),
739       " ");
740   // Log info for up to 5 streams.
741   size_t i = 5;
742   for (const auto& it : stream_map_) {
743     if (it.second->is_static()) {
744       continue;
745     }
746     // Calculate the stream creation delay.
747     const QuicTime::Delta delay =
748         connection_->clock()->ApproximateNow() - it.second->creation_time();
749     absl::StrAppend(
750         &info, "{", it.second->id(), ":", delay.ToDebuggingValue(), ";",
751         it.second->stream_bytes_written(), ",", it.second->fin_sent(), ",",
752         it.second->HasBufferedData(), ",", it.second->fin_buffered(), ";",
753         it.second->stream_bytes_read(), ",", it.second->fin_received(), "}");
754     --i;
755     if (i == 0) {
756       break;
757     }
758   }
759   return info;
760 }
761 
HasPendingHandshake() const762 bool QuicSession::HasPendingHandshake() const {
763   if (QuicVersionUsesCryptoFrames(transport_version())) {
764     return GetCryptoStream()->HasPendingCryptoRetransmission() ||
765            GetCryptoStream()->HasBufferedCryptoFrames();
766   }
767   return streams_with_pending_retransmission_.contains(
768              QuicUtils::GetCryptoStreamId(transport_version())) ||
769          write_blocked_streams_->IsStreamBlocked(
770              QuicUtils::GetCryptoStreamId(transport_version()));
771 }
772 
ProcessUdpPacket(const QuicSocketAddress & self_address,const QuicSocketAddress & peer_address,const QuicReceivedPacket & packet)773 void QuicSession::ProcessUdpPacket(const QuicSocketAddress& self_address,
774                                    const QuicSocketAddress& peer_address,
775                                    const QuicReceivedPacket& packet) {
776   QuicConnectionContextSwitcher cs(connection_->context());
777   connection_->ProcessUdpPacket(self_address, peer_address, packet);
778 }
779 
on_closed_frame_string() const780 std::string QuicSession::on_closed_frame_string() const {
781   std::stringstream ss;
782   ss << on_closed_frame_;
783   if (source_.has_value()) {
784     ss << " " << ConnectionCloseSourceToString(source_.value());
785   }
786   return ss.str();
787 }
788 
WritevData(QuicStreamId id,size_t write_length,QuicStreamOffset offset,StreamSendingState state,TransmissionType type,EncryptionLevel level)789 QuicConsumedData QuicSession::WritevData(QuicStreamId id, size_t write_length,
790                                          QuicStreamOffset offset,
791                                          StreamSendingState state,
792                                          TransmissionType type,
793                                          EncryptionLevel level) {
794   QUIC_BUG_IF(session writevdata when disconnected, !connection()->connected())
795       << ENDPOINT << "Try to write stream data when connection is closed: "
796       << on_closed_frame_string();
797   if (!IsEncryptionEstablished() &&
798       !QuicUtils::IsCryptoStreamId(transport_version(), id)) {
799     // Do not let streams write without encryption. The calling stream will end
800     // up write blocked until OnCanWrite is next called.
801     if (was_zero_rtt_rejected_ && !OneRttKeysAvailable()) {
802       QUICHE_DCHECK(version().UsesTls() &&
803                     perspective() == Perspective::IS_CLIENT);
804       QUIC_DLOG(INFO) << ENDPOINT
805                       << "Suppress the write while 0-RTT gets rejected and "
806                          "1-RTT keys are not available. Version: "
807                       << ParsedQuicVersionToString(version());
808     } else if (version().UsesTls() || perspective() == Perspective::IS_SERVER) {
809       QUIC_BUG(quic_bug_10866_2)
810           << ENDPOINT << "Try to send data of stream " << id
811           << " before encryption is established. Version: "
812           << ParsedQuicVersionToString(version());
813     } else {
814       // In QUIC crypto, this could happen when the client sends full CHLO and
815       // 0-RTT request, then receives an inchoate REJ and sends an inchoate
816       // CHLO. The client then gets the ACK of the inchoate CHLO or the client
817       // gets the full REJ and needs to verify the proof (before it sends the
818       // full CHLO), such that there is no outstanding crypto data.
819       // Retransmission alarm fires in TLP mode which tries to retransmit the
820       // 0-RTT request (without encryption).
821       QUIC_DLOG(INFO) << ENDPOINT << "Try to send data of stream " << id
822                       << " before encryption is established.";
823     }
824     return QuicConsumedData(0, false);
825   }
826 
827   SetTransmissionType(type);
828   QuicConnection::ScopedEncryptionLevelContext context(connection(), level);
829 
830   QuicConsumedData data =
831       connection_->SendStreamData(id, write_length, offset, state);
832   if (type == NOT_RETRANSMISSION) {
833     // This is new stream data.
834     write_blocked_streams_->UpdateBytesForStream(id, data.bytes_consumed);
835   }
836 
837   return data;
838 }
839 
SendCryptoData(EncryptionLevel level,size_t write_length,QuicStreamOffset offset,TransmissionType type)840 size_t QuicSession::SendCryptoData(EncryptionLevel level, size_t write_length,
841                                    QuicStreamOffset offset,
842                                    TransmissionType type) {
843   QUICHE_DCHECK(QuicVersionUsesCryptoFrames(transport_version()));
844   if (!connection()->framer().HasEncrypterOfEncryptionLevel(level)) {
845     const std::string error_details = absl::StrCat(
846         "Try to send crypto data with missing keys of encryption level: ",
847         EncryptionLevelToString(level));
848     QUIC_BUG(quic_bug_10866_3) << ENDPOINT << error_details;
849     connection()->CloseConnection(
850         QUIC_MISSING_WRITE_KEYS, error_details,
851         ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
852     return 0;
853   }
854   SetTransmissionType(type);
855   QuicConnection::ScopedEncryptionLevelContext context(connection(), level);
856   const auto bytes_consumed =
857       connection_->SendCryptoData(level, write_length, offset);
858   return bytes_consumed;
859 }
860 
OnControlFrameManagerError(QuicErrorCode error_code,std::string error_details)861 void QuicSession::OnControlFrameManagerError(QuicErrorCode error_code,
862                                              std::string error_details) {
863   connection_->CloseConnection(
864       error_code, error_details,
865       ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
866 }
867 
WriteControlFrame(const QuicFrame & frame,TransmissionType type)868 bool QuicSession::WriteControlFrame(const QuicFrame& frame,
869                                     TransmissionType type) {
870   QUIC_BUG_IF(quic_bug_12435_11, !connection()->connected())
871       << ENDPOINT
872       << absl::StrCat("Try to write control frame: ", QuicFrameToString(frame),
873                       " when connection is closed: ")
874       << on_closed_frame_string();
875   if (!IsEncryptionEstablished()) {
876     // Suppress the write before encryption gets established.
877     return false;
878   }
879   SetTransmissionType(type);
880   QuicConnection::ScopedEncryptionLevelContext context(
881       connection(), GetEncryptionLevelToSendApplicationData());
882   return connection_->SendControlFrame(frame);
883 }
884 
ResetStream(QuicStreamId id,QuicRstStreamErrorCode error)885 void QuicSession::ResetStream(QuicStreamId id, QuicRstStreamErrorCode error) {
886   QuicStream* stream = GetStream(id);
887   if (stream != nullptr && stream->is_static()) {
888     connection()->CloseConnection(
889         QUIC_INVALID_STREAM_ID, "Try to reset a static stream",
890         ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
891     return;
892   }
893 
894   if (stream != nullptr) {
895     stream->Reset(error);
896     return;
897   }
898 
899   QuicConnection::ScopedPacketFlusher flusher(connection());
900   MaybeSendStopSendingFrame(id, QuicResetStreamError::FromInternal(error));
901   MaybeSendRstStreamFrame(id, QuicResetStreamError::FromInternal(error), 0);
902 }
903 
MaybeSendRstStreamFrame(QuicStreamId id,QuicResetStreamError error,QuicStreamOffset bytes_written)904 void QuicSession::MaybeSendRstStreamFrame(QuicStreamId id,
905                                           QuicResetStreamError error,
906                                           QuicStreamOffset bytes_written) {
907   if (!connection()->connected()) {
908     return;
909   }
910   if (!VersionHasIetfQuicFrames(transport_version()) ||
911       QuicUtils::GetStreamType(id, perspective(), IsIncomingStream(id),
912                                version()) != READ_UNIDIRECTIONAL) {
913     control_frame_manager_.WriteOrBufferRstStream(id, error, bytes_written);
914   }
915 
916   connection_->OnStreamReset(id, error.internal_code());
917 }
918 
MaybeSendStopSendingFrame(QuicStreamId id,QuicResetStreamError error)919 void QuicSession::MaybeSendStopSendingFrame(QuicStreamId id,
920                                             QuicResetStreamError error) {
921   if (!connection()->connected()) {
922     return;
923   }
924   if (VersionHasIetfQuicFrames(transport_version()) &&
925       QuicUtils::GetStreamType(id, perspective(), IsIncomingStream(id),
926                                version()) != WRITE_UNIDIRECTIONAL) {
927     control_frame_manager_.WriteOrBufferStopSending(error, id);
928   }
929 }
930 
SendGoAway(QuicErrorCode error_code,const std::string & reason)931 void QuicSession::SendGoAway(QuicErrorCode error_code,
932                              const std::string& reason) {
933   // GOAWAY frame is not supported in IETF QUIC.
934   QUICHE_DCHECK(!VersionHasIetfQuicFrames(transport_version()));
935   if (!IsEncryptionEstablished()) {
936     QUIC_CODE_COUNT(quic_goaway_before_encryption_established);
937     connection_->CloseConnection(
938         error_code, reason,
939         ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
940     return;
941   }
942   if (transport_goaway_sent_) {
943     return;
944   }
945   transport_goaway_sent_ = true;
946 
947   QUICHE_DCHECK_EQ(perspective(), Perspective::IS_SERVER);
948   control_frame_manager_.WriteOrBufferGoAway(
949       error_code,
950       QuicUtils::GetMaxClientInitiatedBidirectionalStreamId(
951           transport_version()),
952       reason);
953 }
954 
SendBlocked(QuicStreamId id,QuicStreamOffset byte_offset)955 void QuicSession::SendBlocked(QuicStreamId id, QuicStreamOffset byte_offset) {
956   control_frame_manager_.WriteOrBufferBlocked(id, byte_offset);
957 }
958 
SendWindowUpdate(QuicStreamId id,QuicStreamOffset byte_offset)959 void QuicSession::SendWindowUpdate(QuicStreamId id,
960                                    QuicStreamOffset byte_offset) {
961   control_frame_manager_.WriteOrBufferWindowUpdate(id, byte_offset);
962 }
963 
OnStreamError(QuicErrorCode error_code,std::string error_details)964 void QuicSession::OnStreamError(QuicErrorCode error_code,
965                                 std::string error_details) {
966   connection_->CloseConnection(
967       error_code, error_details,
968       ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
969 }
970 
OnStreamError(QuicErrorCode error_code,QuicIetfTransportErrorCodes ietf_error,std::string error_details)971 void QuicSession::OnStreamError(QuicErrorCode error_code,
972                                 QuicIetfTransportErrorCodes ietf_error,
973                                 std::string error_details) {
974   connection_->CloseConnection(
975       error_code, ietf_error, error_details,
976       ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
977 }
978 
SendMaxStreams(QuicStreamCount stream_count,bool unidirectional)979 void QuicSession::SendMaxStreams(QuicStreamCount stream_count,
980                                  bool unidirectional) {
981   if (!is_configured_) {
982     QUIC_BUG(quic_bug_10866_5)
983         << "Try to send max streams before config negotiated.";
984     return;
985   }
986   control_frame_manager_.WriteOrBufferMaxStreams(stream_count, unidirectional);
987 }
988 
InsertLocallyClosedStreamsHighestOffset(const QuicStreamId id,QuicStreamOffset offset)989 void QuicSession::InsertLocallyClosedStreamsHighestOffset(
990     const QuicStreamId id, QuicStreamOffset offset) {
991   locally_closed_streams_highest_offset_[id] = offset;
992 }
993 
OnStreamClosed(QuicStreamId stream_id)994 void QuicSession::OnStreamClosed(QuicStreamId stream_id) {
995   QUIC_DVLOG(1) << ENDPOINT << "Closing stream: " << stream_id;
996   StreamMap::iterator it = stream_map_.find(stream_id);
997   if (it == stream_map_.end()) {
998     QUIC_BUG(quic_bug_10866_6)
999         << ENDPOINT << "Stream is already closed: " << stream_id;
1000     return;
1001   }
1002   QuicStream* stream = it->second.get();
1003   StreamType type = stream->type();
1004 
1005   const bool stream_waiting_for_acks = stream->IsWaitingForAcks();
1006   if (stream_waiting_for_acks) {
1007     // The stream needs to be kept alive because it's waiting for acks.
1008     ++num_zombie_streams_;
1009   } else {
1010     closed_streams_.push_back(std::move(it->second));
1011     stream_map_.erase(it);
1012     // Do not retransmit data of a closed stream.
1013     streams_with_pending_retransmission_.erase(stream_id);
1014     if (!closed_streams_clean_up_alarm_->IsSet()) {
1015       closed_streams_clean_up_alarm_->Set(
1016           connection_->clock()->ApproximateNow());
1017     }
1018     connection_->QuicBugIfHasPendingFrames(stream_id);
1019   }
1020 
1021   if (!stream->HasReceivedFinalOffset()) {
1022     // If we haven't received a FIN or RST for this stream, we need to keep
1023     // track of the how many bytes the stream's flow controller believes it has
1024     // received, for accurate connection level flow control accounting.
1025     // If this is an outgoing stream, it is technically open from peer's
1026     // perspective. Do not inform stream Id manager yet.
1027     QUICHE_DCHECK(!stream->was_draining());
1028     InsertLocallyClosedStreamsHighestOffset(
1029         stream_id, stream->highest_received_byte_offset());
1030     return;
1031   }
1032 
1033   const bool stream_was_draining = stream->was_draining();
1034   QUIC_DVLOG_IF(1, stream_was_draining)
1035       << ENDPOINT << "Stream " << stream_id << " was draining";
1036   if (stream_was_draining) {
1037     QUIC_BUG_IF(quic_bug_12435_4, num_draining_streams_ == 0);
1038     --num_draining_streams_;
1039     if (!IsIncomingStream(stream_id)) {
1040       QUIC_BUG_IF(quic_bug_12435_5, num_outgoing_draining_streams_ == 0);
1041       --num_outgoing_draining_streams_;
1042     }
1043     // Stream Id manager has been informed with draining streams.
1044     return;
1045   }
1046   if (!VersionHasIetfQuicFrames(transport_version())) {
1047     stream_id_manager_.OnStreamClosed(
1048         /*is_incoming=*/IsIncomingStream(stream_id));
1049   }
1050   if (!connection_->connected()) {
1051     return;
1052   }
1053   if (IsIncomingStream(stream_id)) {
1054     // Stream Id manager is only interested in peer initiated stream IDs.
1055     if (VersionHasIetfQuicFrames(transport_version())) {
1056       ietf_streamid_manager_.OnStreamClosed(stream_id);
1057     }
1058     return;
1059   }
1060   if (!VersionHasIetfQuicFrames(transport_version())) {
1061     OnCanCreateNewOutgoingStream(type != BIDIRECTIONAL);
1062   }
1063 }
1064 
ClosePendingStream(QuicStreamId stream_id)1065 void QuicSession::ClosePendingStream(QuicStreamId stream_id) {
1066   QUIC_DVLOG(1) << ENDPOINT << "Closing stream " << stream_id;
1067   QUICHE_DCHECK(VersionHasIetfQuicFrames(transport_version()));
1068   pending_stream_map_.erase(stream_id);
1069   if (connection_->connected()) {
1070     ietf_streamid_manager_.OnStreamClosed(stream_id);
1071   }
1072 }
1073 
ShouldProcessFrameByPendingStream(QuicFrameType type,QuicStreamId id) const1074 bool QuicSession::ShouldProcessFrameByPendingStream(QuicFrameType type,
1075                                                     QuicStreamId id) const {
1076   return UsesPendingStreamForFrame(type, id) &&
1077          stream_map_.find(id) == stream_map_.end();
1078 }
1079 
OnFinalByteOffsetReceived(QuicStreamId stream_id,QuicStreamOffset final_byte_offset)1080 void QuicSession::OnFinalByteOffsetReceived(
1081     QuicStreamId stream_id, QuicStreamOffset final_byte_offset) {
1082   auto it = locally_closed_streams_highest_offset_.find(stream_id);
1083   if (it == locally_closed_streams_highest_offset_.end()) {
1084     return;
1085   }
1086 
1087   QUIC_DVLOG(1) << ENDPOINT << "Received final byte offset "
1088                 << final_byte_offset << " for stream " << stream_id;
1089   QuicByteCount offset_diff = final_byte_offset - it->second;
1090   if (flow_controller_.UpdateHighestReceivedOffset(
1091           flow_controller_.highest_received_byte_offset() + offset_diff)) {
1092     // If the final offset violates flow control, close the connection now.
1093     if (flow_controller_.FlowControlViolation()) {
1094       connection_->CloseConnection(
1095           QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA,
1096           "Connection level flow control violation",
1097           ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
1098       return;
1099     }
1100   }
1101 
1102   flow_controller_.AddBytesConsumed(offset_diff);
1103   locally_closed_streams_highest_offset_.erase(it);
1104   if (!VersionHasIetfQuicFrames(transport_version())) {
1105     stream_id_manager_.OnStreamClosed(
1106         /*is_incoming=*/IsIncomingStream(stream_id));
1107   }
1108   if (IsIncomingStream(stream_id)) {
1109     if (VersionHasIetfQuicFrames(transport_version())) {
1110       ietf_streamid_manager_.OnStreamClosed(stream_id);
1111     }
1112   } else if (!VersionHasIetfQuicFrames(transport_version())) {
1113     OnCanCreateNewOutgoingStream(false);
1114   }
1115 }
1116 
IsEncryptionEstablished() const1117 bool QuicSession::IsEncryptionEstablished() const {
1118   if (GetCryptoStream() == nullptr) {
1119     return false;
1120   }
1121   return GetCryptoStream()->encryption_established();
1122 }
1123 
OneRttKeysAvailable() const1124 bool QuicSession::OneRttKeysAvailable() const {
1125   if (GetCryptoStream() == nullptr) {
1126     return false;
1127   }
1128   return GetCryptoStream()->one_rtt_keys_available();
1129 }
1130 
OnConfigNegotiated()1131 void QuicSession::OnConfigNegotiated() {
1132   // In versions with TLS, the configs will be set twice if 0-RTT is available.
1133   // In the second config setting, 1-RTT keys are guaranteed to be available.
1134   if (version().UsesTls() && is_configured_ &&
1135       connection_->encryption_level() != ENCRYPTION_FORWARD_SECURE) {
1136     QUIC_BUG(quic_bug_12435_6)
1137         << ENDPOINT
1138         << "1-RTT keys missing when config is negotiated for the second time.";
1139     connection_->CloseConnection(
1140         QUIC_INTERNAL_ERROR,
1141         "1-RTT keys missing when config is negotiated for the second time.",
1142         ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
1143     return;
1144   }
1145 
1146   QUIC_DVLOG(1) << ENDPOINT << "OnConfigNegotiated";
1147   connection_->SetFromConfig(config_);
1148 
1149   if (VersionHasIetfQuicFrames(transport_version())) {
1150     uint32_t max_streams = 0;
1151     if (config_.HasReceivedMaxBidirectionalStreams()) {
1152       max_streams = config_.ReceivedMaxBidirectionalStreams();
1153     }
1154     if (was_zero_rtt_rejected_ &&
1155         max_streams <
1156             ietf_streamid_manager_.outgoing_bidirectional_stream_count()) {
1157       connection_->CloseConnection(
1158           QUIC_ZERO_RTT_UNRETRANSMITTABLE,
1159           absl::StrCat(
1160               "Server rejected 0-RTT, aborting because new bidirectional "
1161               "initial stream limit ",
1162               max_streams, " is less than current open streams: ",
1163               ietf_streamid_manager_.outgoing_bidirectional_stream_count()),
1164           ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
1165       return;
1166     }
1167     QUIC_DVLOG(1) << ENDPOINT
1168                   << "Setting Bidirectional outgoing_max_streams_ to "
1169                   << max_streams;
1170     if (perspective_ == Perspective::IS_CLIENT &&
1171         max_streams <
1172             ietf_streamid_manager_.max_outgoing_bidirectional_streams()) {
1173       connection_->CloseConnection(
1174           was_zero_rtt_rejected_ ? QUIC_ZERO_RTT_REJECTION_LIMIT_REDUCED
1175                                  : QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED,
1176           absl::StrCat(
1177               was_zero_rtt_rejected_
1178                   ? "Server rejected 0-RTT, aborting because "
1179                   : "",
1180               "new bidirectional limit ", max_streams,
1181               " decreases the current limit: ",
1182               ietf_streamid_manager_.max_outgoing_bidirectional_streams()),
1183           ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
1184       return;
1185     }
1186     if (ietf_streamid_manager_.MaybeAllowNewOutgoingBidirectionalStreams(
1187             max_streams)) {
1188       OnCanCreateNewOutgoingStream(/*unidirectional = */ false);
1189     }
1190 
1191     max_streams = 0;
1192     if (config_.HasReceivedMaxUnidirectionalStreams()) {
1193       max_streams = config_.ReceivedMaxUnidirectionalStreams();
1194     }
1195 
1196     if (was_zero_rtt_rejected_ &&
1197         max_streams <
1198             ietf_streamid_manager_.outgoing_unidirectional_stream_count()) {
1199       connection_->CloseConnection(
1200           QUIC_ZERO_RTT_UNRETRANSMITTABLE,
1201           absl::StrCat(
1202               "Server rejected 0-RTT, aborting because new unidirectional "
1203               "initial stream limit ",
1204               max_streams, " is less than current open streams: ",
1205               ietf_streamid_manager_.outgoing_unidirectional_stream_count()),
1206           ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
1207       return;
1208     }
1209 
1210     if (max_streams <
1211         ietf_streamid_manager_.max_outgoing_unidirectional_streams()) {
1212       connection_->CloseConnection(
1213           was_zero_rtt_rejected_ ? QUIC_ZERO_RTT_REJECTION_LIMIT_REDUCED
1214                                  : QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED,
1215           absl::StrCat(
1216               was_zero_rtt_rejected_
1217                   ? "Server rejected 0-RTT, aborting because "
1218                   : "",
1219               "new unidirectional limit ", max_streams,
1220               " decreases the current limit: ",
1221               ietf_streamid_manager_.max_outgoing_unidirectional_streams()),
1222           ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
1223       return;
1224     }
1225     QUIC_DVLOG(1) << ENDPOINT
1226                   << "Setting Unidirectional outgoing_max_streams_ to "
1227                   << max_streams;
1228     if (ietf_streamid_manager_.MaybeAllowNewOutgoingUnidirectionalStreams(
1229             max_streams)) {
1230       OnCanCreateNewOutgoingStream(/*unidirectional = */ true);
1231     }
1232   } else {
1233     uint32_t max_streams = 0;
1234     if (config_.HasReceivedMaxBidirectionalStreams()) {
1235       max_streams = config_.ReceivedMaxBidirectionalStreams();
1236     }
1237     QUIC_DVLOG(1) << ENDPOINT << "Setting max_open_outgoing_streams_ to "
1238                   << max_streams;
1239     if (was_zero_rtt_rejected_ &&
1240         max_streams < stream_id_manager_.num_open_outgoing_streams()) {
1241       connection_->CloseConnection(
1242           QUIC_INTERNAL_ERROR,
1243           absl::StrCat(
1244               "Server rejected 0-RTT, aborting because new stream limit ",
1245               max_streams, " is less than current open streams: ",
1246               stream_id_manager_.num_open_outgoing_streams()),
1247           ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
1248       return;
1249     }
1250     stream_id_manager_.set_max_open_outgoing_streams(max_streams);
1251   }
1252 
1253   if (perspective() == Perspective::IS_SERVER) {
1254     if (config_.HasReceivedConnectionOptions()) {
1255       // The following variations change the initial receive flow control
1256       // window sizes.
1257       if (ContainsQuicTag(config_.ReceivedConnectionOptions(), kIFW6)) {
1258         AdjustInitialFlowControlWindows(64 * 1024);
1259       }
1260       if (ContainsQuicTag(config_.ReceivedConnectionOptions(), kIFW7)) {
1261         AdjustInitialFlowControlWindows(128 * 1024);
1262       }
1263       if (ContainsQuicTag(config_.ReceivedConnectionOptions(), kIFW8)) {
1264         AdjustInitialFlowControlWindows(256 * 1024);
1265       }
1266       if (ContainsQuicTag(config_.ReceivedConnectionOptions(), kIFW9)) {
1267         AdjustInitialFlowControlWindows(512 * 1024);
1268       }
1269       if (ContainsQuicTag(config_.ReceivedConnectionOptions(), kIFWA)) {
1270         AdjustInitialFlowControlWindows(1024 * 1024);
1271       }
1272     }
1273 
1274     config_.SetStatelessResetTokenToSend(GetStatelessResetToken());
1275   }
1276 
1277   if (VersionHasIetfQuicFrames(transport_version())) {
1278     ietf_streamid_manager_.SetMaxOpenIncomingBidirectionalStreams(
1279         config_.GetMaxBidirectionalStreamsToSend());
1280     ietf_streamid_manager_.SetMaxOpenIncomingUnidirectionalStreams(
1281         config_.GetMaxUnidirectionalStreamsToSend());
1282   } else {
1283     // A small number of additional incoming streams beyond the limit should be
1284     // allowed. This helps avoid early connection termination when FIN/RSTs for
1285     // old streams are lost or arrive out of order.
1286     // Use a minimum number of additional streams, or a percentage increase,
1287     // whichever is larger.
1288     uint32_t max_incoming_streams_to_send =
1289         config_.GetMaxBidirectionalStreamsToSend();
1290     uint32_t max_incoming_streams =
1291         std::max(max_incoming_streams_to_send + kMaxStreamsMinimumIncrement,
1292                  static_cast<uint32_t>(max_incoming_streams_to_send *
1293                                        kMaxStreamsMultiplier));
1294     stream_id_manager_.set_max_open_incoming_streams(max_incoming_streams);
1295   }
1296 
1297   if (connection_->version().handshake_protocol == PROTOCOL_TLS1_3) {
1298     // When using IETF-style TLS transport parameters, inform existing streams
1299     // of new flow-control limits.
1300     if (config_.HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional()) {
1301       OnNewStreamOutgoingBidirectionalFlowControlWindow(
1302           config_.ReceivedInitialMaxStreamDataBytesOutgoingBidirectional());
1303     }
1304     if (config_.HasReceivedInitialMaxStreamDataBytesIncomingBidirectional()) {
1305       OnNewStreamIncomingBidirectionalFlowControlWindow(
1306           config_.ReceivedInitialMaxStreamDataBytesIncomingBidirectional());
1307     }
1308     if (config_.HasReceivedInitialMaxStreamDataBytesUnidirectional()) {
1309       OnNewStreamUnidirectionalFlowControlWindow(
1310           config_.ReceivedInitialMaxStreamDataBytesUnidirectional());
1311     }
1312   } else {  // The version uses Google QUIC Crypto.
1313     if (config_.HasReceivedInitialStreamFlowControlWindowBytes()) {
1314       // Streams which were created before the SHLO was received (0-RTT
1315       // requests) are now informed of the peer's initial flow control window.
1316       OnNewStreamFlowControlWindow(
1317           config_.ReceivedInitialStreamFlowControlWindowBytes());
1318     }
1319   }
1320 
1321   if (config_.HasReceivedInitialSessionFlowControlWindowBytes()) {
1322     OnNewSessionFlowControlWindow(
1323         config_.ReceivedInitialSessionFlowControlWindowBytes());
1324   }
1325 
1326   if (perspective_ == Perspective::IS_SERVER && version().HasIetfQuicFrames() &&
1327       connection_->effective_peer_address().IsInitialized()) {
1328     if (config_.HasClientSentConnectionOption(kSPAD, perspective_)) {
1329       quiche::IpAddressFamily address_family =
1330           connection_->effective_peer_address()
1331               .Normalized()
1332               .host()
1333               .address_family();
1334       absl::optional<QuicSocketAddress> preferred_address =
1335           config_.GetPreferredAddressToSend(address_family);
1336       if (preferred_address.has_value()) {
1337         // Set connection ID and token if SPAD has received and a preferred
1338         // address of the same address family is configured.
1339         absl::optional<QuicNewConnectionIdFrame> frame =
1340             connection_->MaybeIssueNewConnectionIdForPreferredAddress();
1341         if (frame.has_value()) {
1342           config_.SetPreferredAddressConnectionIdAndTokenToSend(
1343               frame->connection_id, frame->stateless_reset_token);
1344         }
1345         connection_->set_sent_server_preferred_address(
1346             preferred_address.value());
1347       }
1348       // Clear the alternative address of the other address family in the
1349       // config.
1350       config_.ClearAlternateServerAddressToSend(
1351           address_family == quiche::IpAddressFamily::IP_V4
1352               ? quiche::IpAddressFamily::IP_V6
1353               : quiche::IpAddressFamily::IP_V4);
1354     } else {
1355       // Clear alternative IPv(4|6) addresses in config if the server hasn't
1356       // received 'SPAD' connection option.
1357       config_.ClearAlternateServerAddressToSend(quiche::IpAddressFamily::IP_V4);
1358       config_.ClearAlternateServerAddressToSend(quiche::IpAddressFamily::IP_V6);
1359     }
1360   }
1361 
1362   is_configured_ = true;
1363   connection()->OnConfigNegotiated();
1364 
1365   // Ask flow controllers to try again since the config could have unblocked us.
1366   // Or if this session is configured on TLS enabled QUIC versions,
1367   // attempt to retransmit 0-RTT data if there's any.
1368   // TODO(fayang): consider removing this OnCanWrite call.
1369   if (!connection_->framer().is_processing_packet() &&
1370       (connection_->version().AllowsLowFlowControlLimits() ||
1371        version().UsesTls())) {
1372     QUIC_CODE_COUNT(quic_session_on_can_write_on_config_negotiated);
1373     OnCanWrite();
1374   }
1375 }
1376 
OnAlpsData(const uint8_t *,size_t)1377 absl::optional<std::string> QuicSession::OnAlpsData(
1378     const uint8_t* /*alps_data*/, size_t /*alps_length*/) {
1379   return absl::nullopt;
1380 }
1381 
AdjustInitialFlowControlWindows(size_t stream_window)1382 void QuicSession::AdjustInitialFlowControlWindows(size_t stream_window) {
1383   const float session_window_multiplier =
1384       config_.GetInitialStreamFlowControlWindowToSend()
1385           ? static_cast<float>(
1386                 config_.GetInitialSessionFlowControlWindowToSend()) /
1387                 config_.GetInitialStreamFlowControlWindowToSend()
1388           : 1.5;
1389 
1390   QUIC_DVLOG(1) << ENDPOINT << "Set stream receive window to " << stream_window;
1391   config_.SetInitialStreamFlowControlWindowToSend(stream_window);
1392 
1393   size_t session_window = session_window_multiplier * stream_window;
1394   QUIC_DVLOG(1) << ENDPOINT << "Set session receive window to "
1395                 << session_window;
1396   config_.SetInitialSessionFlowControlWindowToSend(session_window);
1397   flow_controller_.UpdateReceiveWindowSize(session_window);
1398   // Inform all existing streams about the new window.
1399   for (auto const& kv : stream_map_) {
1400     kv.second->UpdateReceiveWindowSize(stream_window);
1401   }
1402   if (!QuicVersionUsesCryptoFrames(transport_version())) {
1403     GetMutableCryptoStream()->UpdateReceiveWindowSize(stream_window);
1404   }
1405 }
1406 
HandleFrameOnNonexistentOutgoingStream(QuicStreamId stream_id)1407 void QuicSession::HandleFrameOnNonexistentOutgoingStream(
1408     QuicStreamId stream_id) {
1409   QUICHE_DCHECK(!IsClosedStream(stream_id));
1410   // Received a frame for a locally-created stream that is not currently
1411   // active. This is an error.
1412   if (VersionHasIetfQuicFrames(transport_version())) {
1413     connection()->CloseConnection(
1414         QUIC_HTTP_STREAM_WRONG_DIRECTION, "Data for nonexistent stream",
1415         ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
1416     return;
1417   }
1418   connection()->CloseConnection(
1419       QUIC_INVALID_STREAM_ID, "Data for nonexistent stream",
1420       ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
1421 }
1422 
HandleRstOnValidNonexistentStream(const QuicRstStreamFrame & frame)1423 void QuicSession::HandleRstOnValidNonexistentStream(
1424     const QuicRstStreamFrame& frame) {
1425   // If the stream is neither originally in active streams nor created in
1426   // GetOrCreateStream(), it could be a closed stream in which case its
1427   // final received byte offset need to be updated.
1428   if (IsClosedStream(frame.stream_id)) {
1429     // The RST frame contains the final byte offset for the stream: we can now
1430     // update the connection level flow controller if needed.
1431     OnFinalByteOffsetReceived(frame.stream_id, frame.byte_offset);
1432   }
1433 }
1434 
OnNewStreamFlowControlWindow(QuicStreamOffset new_window)1435 void QuicSession::OnNewStreamFlowControlWindow(QuicStreamOffset new_window) {
1436   QUICHE_DCHECK(version().UsesQuicCrypto());
1437   QUIC_DVLOG(1) << ENDPOINT << "OnNewStreamFlowControlWindow " << new_window;
1438   if (new_window < kMinimumFlowControlSendWindow) {
1439     QUIC_LOG_FIRST_N(ERROR, 1)
1440         << "Peer sent us an invalid stream flow control send window: "
1441         << new_window << ", below minimum: " << kMinimumFlowControlSendWindow;
1442     connection_->CloseConnection(
1443         QUIC_FLOW_CONTROL_INVALID_WINDOW, "New stream window too low",
1444         ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
1445     return;
1446   }
1447 
1448   // Inform all existing streams about the new window.
1449   for (auto const& kv : stream_map_) {
1450     QUIC_DVLOG(1) << ENDPOINT << "Informing stream " << kv.first
1451                   << " of new stream flow control window " << new_window;
1452     if (!kv.second->MaybeConfigSendWindowOffset(
1453             new_window, /* was_zero_rtt_rejected = */ false)) {
1454       return;
1455     }
1456   }
1457   if (!QuicVersionUsesCryptoFrames(transport_version())) {
1458     QUIC_DVLOG(1)
1459         << ENDPOINT
1460         << "Informing crypto stream of new stream flow control window "
1461         << new_window;
1462     GetMutableCryptoStream()->MaybeConfigSendWindowOffset(
1463         new_window, /* was_zero_rtt_rejected = */ false);
1464   }
1465 }
1466 
OnNewStreamUnidirectionalFlowControlWindow(QuicStreamOffset new_window)1467 void QuicSession::OnNewStreamUnidirectionalFlowControlWindow(
1468     QuicStreamOffset new_window) {
1469   QUICHE_DCHECK_EQ(connection_->version().handshake_protocol, PROTOCOL_TLS1_3);
1470   QUIC_DVLOG(1) << ENDPOINT << "OnNewStreamUnidirectionalFlowControlWindow "
1471                 << new_window;
1472   // Inform all existing outgoing unidirectional streams about the new window.
1473   for (auto const& kv : stream_map_) {
1474     const QuicStreamId id = kv.first;
1475     if (!version().HasIetfQuicFrames()) {
1476       if (kv.second->type() == BIDIRECTIONAL) {
1477         continue;
1478       }
1479     } else {
1480       if (QuicUtils::IsBidirectionalStreamId(id, version())) {
1481         continue;
1482       }
1483     }
1484     if (!QuicUtils::IsOutgoingStreamId(connection_->version(), id,
1485                                        perspective())) {
1486       continue;
1487     }
1488     QUIC_DVLOG(1) << ENDPOINT << "Informing unidirectional stream " << id
1489                   << " of new stream flow control window " << new_window;
1490     if (!kv.second->MaybeConfigSendWindowOffset(new_window,
1491                                                 was_zero_rtt_rejected_)) {
1492       return;
1493     }
1494   }
1495 }
1496 
OnNewStreamOutgoingBidirectionalFlowControlWindow(QuicStreamOffset new_window)1497 void QuicSession::OnNewStreamOutgoingBidirectionalFlowControlWindow(
1498     QuicStreamOffset new_window) {
1499   QUICHE_DCHECK_EQ(connection_->version().handshake_protocol, PROTOCOL_TLS1_3);
1500   QUIC_DVLOG(1) << ENDPOINT
1501                 << "OnNewStreamOutgoingBidirectionalFlowControlWindow "
1502                 << new_window;
1503   // Inform all existing outgoing bidirectional streams about the new window.
1504   for (auto const& kv : stream_map_) {
1505     const QuicStreamId id = kv.first;
1506     if (!version().HasIetfQuicFrames()) {
1507       if (kv.second->type() != BIDIRECTIONAL) {
1508         continue;
1509       }
1510     } else {
1511       if (!QuicUtils::IsBidirectionalStreamId(id, version())) {
1512         continue;
1513       }
1514     }
1515     if (!QuicUtils::IsOutgoingStreamId(connection_->version(), id,
1516                                        perspective())) {
1517       continue;
1518     }
1519     QUIC_DVLOG(1) << ENDPOINT << "Informing outgoing bidirectional stream "
1520                   << id << " of new stream flow control window " << new_window;
1521     if (!kv.second->MaybeConfigSendWindowOffset(new_window,
1522                                                 was_zero_rtt_rejected_)) {
1523       return;
1524     }
1525   }
1526 }
1527 
OnNewStreamIncomingBidirectionalFlowControlWindow(QuicStreamOffset new_window)1528 void QuicSession::OnNewStreamIncomingBidirectionalFlowControlWindow(
1529     QuicStreamOffset new_window) {
1530   QUICHE_DCHECK_EQ(connection_->version().handshake_protocol, PROTOCOL_TLS1_3);
1531   QUIC_DVLOG(1) << ENDPOINT
1532                 << "OnNewStreamIncomingBidirectionalFlowControlWindow "
1533                 << new_window;
1534   // Inform all existing incoming bidirectional streams about the new window.
1535   for (auto const& kv : stream_map_) {
1536     const QuicStreamId id = kv.first;
1537     if (!version().HasIetfQuicFrames()) {
1538       if (kv.second->type() != BIDIRECTIONAL) {
1539         continue;
1540       }
1541     } else {
1542       if (!QuicUtils::IsBidirectionalStreamId(id, version())) {
1543         continue;
1544       }
1545     }
1546     if (QuicUtils::IsOutgoingStreamId(connection_->version(), id,
1547                                       perspective())) {
1548       continue;
1549     }
1550     QUIC_DVLOG(1) << ENDPOINT << "Informing incoming bidirectional stream "
1551                   << id << " of new stream flow control window " << new_window;
1552     if (!kv.second->MaybeConfigSendWindowOffset(new_window,
1553                                                 was_zero_rtt_rejected_)) {
1554       return;
1555     }
1556   }
1557 }
1558 
OnNewSessionFlowControlWindow(QuicStreamOffset new_window)1559 void QuicSession::OnNewSessionFlowControlWindow(QuicStreamOffset new_window) {
1560   QUIC_DVLOG(1) << ENDPOINT << "OnNewSessionFlowControlWindow " << new_window;
1561 
1562   if (was_zero_rtt_rejected_ && new_window < flow_controller_.bytes_sent()) {
1563     std::string error_details = absl::StrCat(
1564         "Server rejected 0-RTT. Aborting because the client received session "
1565         "flow control send window: ",
1566         new_window,
1567         ", which is below currently used: ", flow_controller_.bytes_sent());
1568     QUIC_LOG(ERROR) << error_details;
1569     connection_->CloseConnection(
1570         QUIC_ZERO_RTT_UNRETRANSMITTABLE, error_details,
1571         ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
1572     return;
1573   }
1574   if (!connection_->version().AllowsLowFlowControlLimits() &&
1575       new_window < kMinimumFlowControlSendWindow) {
1576     std::string error_details = absl::StrCat(
1577         "Peer sent us an invalid session flow control send window: ",
1578         new_window, ", below minimum: ", kMinimumFlowControlSendWindow);
1579     QUIC_LOG_FIRST_N(ERROR, 1) << error_details;
1580     connection_->CloseConnection(
1581         QUIC_FLOW_CONTROL_INVALID_WINDOW, error_details,
1582         ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
1583     return;
1584   }
1585   if (perspective_ == Perspective::IS_CLIENT &&
1586       new_window < flow_controller_.send_window_offset()) {
1587     // The client receives a lower limit than remembered, violating
1588     // https://tools.ietf.org/html/draft-ietf-quic-transport-27#section-7.3.1
1589     std::string error_details = absl::StrCat(
1590         was_zero_rtt_rejected_ ? "Server rejected 0-RTT, aborting because "
1591                                : "",
1592         "new session max data ", new_window,
1593         " decreases current limit: ", flow_controller_.send_window_offset());
1594     QUIC_LOG(ERROR) << error_details;
1595     connection_->CloseConnection(
1596         was_zero_rtt_rejected_ ? QUIC_ZERO_RTT_REJECTION_LIMIT_REDUCED
1597                                : QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED,
1598         error_details, ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
1599     return;
1600   }
1601 
1602   flow_controller_.UpdateSendWindowOffset(new_window);
1603 }
1604 
OnNewDecryptionKeyAvailable(EncryptionLevel level,std::unique_ptr<QuicDecrypter> decrypter,bool set_alternative_decrypter,bool latch_once_used)1605 bool QuicSession::OnNewDecryptionKeyAvailable(
1606     EncryptionLevel level, std::unique_ptr<QuicDecrypter> decrypter,
1607     bool set_alternative_decrypter, bool latch_once_used) {
1608   if (connection_->version().handshake_protocol == PROTOCOL_TLS1_3 &&
1609       !connection()->framer().HasEncrypterOfEncryptionLevel(
1610           QuicUtils::GetEncryptionLevelToSendAckofSpace(
1611               QuicUtils::GetPacketNumberSpace(level)))) {
1612     // This should never happen because connection should never decrypt a packet
1613     // while an ACK for it cannot be encrypted.
1614     return false;
1615   }
1616   if (connection()->version().KnowsWhichDecrypterToUse()) {
1617     connection()->InstallDecrypter(level, std::move(decrypter));
1618     return true;
1619   }
1620   if (set_alternative_decrypter) {
1621     connection()->SetAlternativeDecrypter(level, std::move(decrypter),
1622                                           latch_once_used);
1623     return true;
1624   }
1625   connection()->SetDecrypter(level, std::move(decrypter));
1626   return true;
1627 }
1628 
OnNewEncryptionKeyAvailable(EncryptionLevel level,std::unique_ptr<QuicEncrypter> encrypter)1629 void QuicSession::OnNewEncryptionKeyAvailable(
1630     EncryptionLevel level, std::unique_ptr<QuicEncrypter> encrypter) {
1631   connection()->SetEncrypter(level, std::move(encrypter));
1632   if (connection_->version().handshake_protocol != PROTOCOL_TLS1_3) {
1633     return;
1634   }
1635 
1636   bool reset_encryption_level = false;
1637   if (IsEncryptionEstablished() && level == ENCRYPTION_HANDSHAKE) {
1638     // ENCRYPTION_HANDSHAKE keys are only used for the handshake. If
1639     // ENCRYPTION_ZERO_RTT keys exist, it is possible for a client to send
1640     // stream data, which must not be sent at the ENCRYPTION_HANDSHAKE level.
1641     // Therefore, we avoid setting the default encryption level to
1642     // ENCRYPTION_HANDSHAKE.
1643     reset_encryption_level = true;
1644   }
1645   QUIC_DVLOG(1) << ENDPOINT << "Set default encryption level to " << level;
1646   connection()->SetDefaultEncryptionLevel(level);
1647   if (reset_encryption_level) {
1648     connection()->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
1649   }
1650   QUIC_BUG_IF(quic_bug_12435_7,
1651               IsEncryptionEstablished() &&
1652                   (connection()->encryption_level() == ENCRYPTION_INITIAL ||
1653                    connection()->encryption_level() == ENCRYPTION_HANDSHAKE))
1654       << "Encryption is established, but the encryption level " << level
1655       << " does not support sending stream data";
1656 }
1657 
SetDefaultEncryptionLevel(EncryptionLevel level)1658 void QuicSession::SetDefaultEncryptionLevel(EncryptionLevel level) {
1659   QUICHE_DCHECK_EQ(PROTOCOL_QUIC_CRYPTO,
1660                    connection_->version().handshake_protocol);
1661   QUIC_DVLOG(1) << ENDPOINT << "Set default encryption level to " << level;
1662   connection()->SetDefaultEncryptionLevel(level);
1663 
1664   switch (level) {
1665     case ENCRYPTION_INITIAL:
1666       break;
1667     case ENCRYPTION_ZERO_RTT:
1668       if (perspective() == Perspective::IS_CLIENT) {
1669         // Retransmit old 0-RTT data (if any) with the new 0-RTT keys, since
1670         // they can't be decrypted by the server.
1671         connection_->MarkZeroRttPacketsForRetransmission(0);
1672         if (!connection_->framer().is_processing_packet()) {
1673           // TODO(fayang): consider removing this OnCanWrite call.
1674           // Given any streams blocked by encryption a chance to write.
1675           QUIC_CODE_COUNT(
1676               quic_session_on_can_write_set_default_encryption_level);
1677           OnCanWrite();
1678         }
1679       }
1680       break;
1681     case ENCRYPTION_HANDSHAKE:
1682       break;
1683     case ENCRYPTION_FORWARD_SECURE:
1684       QUIC_BUG_IF(quic_bug_12435_8, !config_.negotiated())
1685           << ENDPOINT << "Handshake confirmed without parameter negotiation.";
1686       connection()->mutable_stats().handshake_completion_time =
1687           connection()->clock()->ApproximateNow();
1688       break;
1689     default:
1690       QUIC_BUG(quic_bug_10866_7) << "Unknown encryption level: " << level;
1691   }
1692 }
1693 
OnTlsHandshakeComplete()1694 void QuicSession::OnTlsHandshakeComplete() {
1695   QUICHE_DCHECK_EQ(PROTOCOL_TLS1_3, connection_->version().handshake_protocol);
1696   QUIC_BUG_IF(quic_bug_12435_9,
1697               !GetCryptoStream()->crypto_negotiated_params().cipher_suite)
1698       << ENDPOINT << "Handshake completes without cipher suite negotiation.";
1699   QUIC_BUG_IF(quic_bug_12435_10, !config_.negotiated())
1700       << ENDPOINT << "Handshake completes without parameter negotiation.";
1701   connection()->mutable_stats().handshake_completion_time =
1702       connection()->clock()->ApproximateNow();
1703   if (connection()->version().UsesTls() &&
1704       perspective_ == Perspective::IS_SERVER) {
1705     // Server sends HANDSHAKE_DONE to signal confirmation of the handshake
1706     // to the client.
1707     control_frame_manager_.WriteOrBufferHandshakeDone();
1708     if (connection()->version().HasIetfQuicFrames()) {
1709       MaybeSendAddressToken();
1710     }
1711   }
1712 }
1713 
MaybeSendAddressToken()1714 bool QuicSession::MaybeSendAddressToken() {
1715   QUICHE_DCHECK(perspective_ == Perspective::IS_SERVER &&
1716                 connection()->version().HasIetfQuicFrames());
1717   absl::optional<CachedNetworkParameters> cached_network_params =
1718       GenerateCachedNetworkParameters();
1719 
1720   std::string address_token = GetCryptoStream()->GetAddressToken(
1721       cached_network_params.has_value() ? &cached_network_params.value()
1722                                         : nullptr);
1723   if (address_token.empty()) {
1724     return false;
1725   }
1726   const size_t buf_len = address_token.length() + 1;
1727   auto buffer = std::make_unique<char[]>(buf_len);
1728   QuicDataWriter writer(buf_len, buffer.get());
1729   // Add |kAddressTokenPrefix| for token sent in NEW_TOKEN frame.
1730   writer.WriteUInt8(kAddressTokenPrefix);
1731   writer.WriteBytes(address_token.data(), address_token.length());
1732   control_frame_manager_.WriteOrBufferNewToken(
1733       absl::string_view(buffer.get(), buf_len));
1734   if (cached_network_params.has_value()) {
1735     connection()->OnSendConnectionState(*cached_network_params);
1736   }
1737   return true;
1738 }
1739 
DiscardOldDecryptionKey(EncryptionLevel level)1740 void QuicSession::DiscardOldDecryptionKey(EncryptionLevel level) {
1741   if (!connection()->version().KnowsWhichDecrypterToUse()) {
1742     return;
1743   }
1744   connection()->RemoveDecrypter(level);
1745 }
1746 
DiscardOldEncryptionKey(EncryptionLevel level)1747 void QuicSession::DiscardOldEncryptionKey(EncryptionLevel level) {
1748   QUIC_DLOG(INFO) << ENDPOINT << "Discarding " << level << " keys";
1749   if (connection()->version().handshake_protocol == PROTOCOL_TLS1_3) {
1750     connection()->RemoveEncrypter(level);
1751   }
1752   switch (level) {
1753     case ENCRYPTION_INITIAL:
1754       NeuterUnencryptedData();
1755       break;
1756     case ENCRYPTION_HANDSHAKE:
1757       NeuterHandshakeData();
1758       break;
1759     case ENCRYPTION_ZERO_RTT:
1760       break;
1761     case ENCRYPTION_FORWARD_SECURE:
1762       QUIC_BUG(quic_bug_10866_8)
1763           << ENDPOINT << "Discarding 1-RTT keys is not allowed";
1764       break;
1765     default:
1766       QUIC_BUG(quic_bug_10866_9)
1767           << ENDPOINT
1768           << "Cannot discard keys for unknown encryption level: " << level;
1769   }
1770 }
1771 
NeuterHandshakeData()1772 void QuicSession::NeuterHandshakeData() {
1773   GetMutableCryptoStream()->NeuterStreamDataOfEncryptionLevel(
1774       ENCRYPTION_HANDSHAKE);
1775   connection()->OnHandshakeComplete();
1776 }
1777 
OnZeroRttRejected(int reason)1778 void QuicSession::OnZeroRttRejected(int reason) {
1779   was_zero_rtt_rejected_ = true;
1780   connection_->MarkZeroRttPacketsForRetransmission(reason);
1781   if (connection_->encryption_level() == ENCRYPTION_FORWARD_SECURE) {
1782     QUIC_BUG(quic_bug_10866_10)
1783         << "1-RTT keys already available when 0-RTT is rejected.";
1784     connection_->CloseConnection(
1785         QUIC_INTERNAL_ERROR,
1786         "1-RTT keys already available when 0-RTT is rejected.",
1787         ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
1788   }
1789 }
1790 
FillTransportParameters(TransportParameters * params)1791 bool QuicSession::FillTransportParameters(TransportParameters* params) {
1792   if (version().UsesTls()) {
1793     if (perspective() == Perspective::IS_SERVER) {
1794       config_.SetOriginalConnectionIdToSend(
1795           connection_->GetOriginalDestinationConnectionId());
1796       config_.SetInitialSourceConnectionIdToSend(connection_->connection_id());
1797     } else {
1798       config_.SetInitialSourceConnectionIdToSend(
1799           connection_->client_connection_id());
1800     }
1801   }
1802   return config_.FillTransportParameters(params);
1803 }
1804 
ProcessTransportParameters(const TransportParameters & params,bool is_resumption,std::string * error_details)1805 QuicErrorCode QuicSession::ProcessTransportParameters(
1806     const TransportParameters& params, bool is_resumption,
1807     std::string* error_details) {
1808   return config_.ProcessTransportParameters(params, is_resumption,
1809                                             error_details);
1810 }
1811 
OnHandshakeCallbackDone()1812 void QuicSession::OnHandshakeCallbackDone() {
1813   if (!connection_->connected()) {
1814     return;
1815   }
1816 
1817   if (!connection()->is_processing_packet()) {
1818     connection()->MaybeProcessUndecryptablePackets();
1819   }
1820 }
1821 
PacketFlusherAttached() const1822 bool QuicSession::PacketFlusherAttached() const {
1823   QUICHE_DCHECK(connection_->connected());
1824   return connection()->packet_creator().PacketFlusherAttached();
1825 }
1826 
OnCryptoHandshakeMessageSent(const CryptoHandshakeMessage &)1827 void QuicSession::OnCryptoHandshakeMessageSent(
1828     const CryptoHandshakeMessage& /*message*/) {}
1829 
OnCryptoHandshakeMessageReceived(const CryptoHandshakeMessage &)1830 void QuicSession::OnCryptoHandshakeMessageReceived(
1831     const CryptoHandshakeMessage& /*message*/) {}
1832 
RegisterStreamPriority(QuicStreamId id,bool is_static,const QuicStreamPriority & priority)1833 void QuicSession::RegisterStreamPriority(QuicStreamId id, bool is_static,
1834                                          const QuicStreamPriority& priority) {
1835   write_blocked_streams()->RegisterStream(id, is_static, priority);
1836 }
1837 
UnregisterStreamPriority(QuicStreamId id)1838 void QuicSession::UnregisterStreamPriority(QuicStreamId id) {
1839   write_blocked_streams()->UnregisterStream(id);
1840 }
1841 
UpdateStreamPriority(QuicStreamId id,const QuicStreamPriority & new_priority)1842 void QuicSession::UpdateStreamPriority(QuicStreamId id,
1843                                        const QuicStreamPriority& new_priority) {
1844   write_blocked_streams()->UpdateStreamPriority(id, new_priority);
1845 }
1846 
ActivateStream(std::unique_ptr<QuicStream> stream)1847 void QuicSession::ActivateStream(std::unique_ptr<QuicStream> stream) {
1848   const bool should_keep_alive = ShouldKeepConnectionAlive();
1849   QuicStreamId stream_id = stream->id();
1850   bool is_static = stream->is_static();
1851   QUIC_DVLOG(1) << ENDPOINT << "num_streams: " << stream_map_.size()
1852                 << ". activating stream " << stream_id;
1853   QUICHE_DCHECK(!stream_map_.contains(stream_id));
1854   stream_map_[stream_id] = std::move(stream);
1855   if (is_static) {
1856     ++num_static_streams_;
1857     return;
1858   }
1859   if (!VersionHasIetfQuicFrames(transport_version())) {
1860     // Do not inform stream ID manager of static streams.
1861     stream_id_manager_.ActivateStream(
1862         /*is_incoming=*/IsIncomingStream(stream_id));
1863   }
1864   if (perspective() == Perspective::IS_CLIENT &&
1865       connection()->multi_port_stats() != nullptr && !should_keep_alive &&
1866       ShouldKeepConnectionAlive()) {
1867     connection()->MaybeProbeMultiPortPath();
1868   }
1869 }
1870 
GetNextOutgoingBidirectionalStreamId()1871 QuicStreamId QuicSession::GetNextOutgoingBidirectionalStreamId() {
1872   if (VersionHasIetfQuicFrames(transport_version())) {
1873     return ietf_streamid_manager_.GetNextOutgoingBidirectionalStreamId();
1874   }
1875   return stream_id_manager_.GetNextOutgoingStreamId();
1876 }
1877 
GetNextOutgoingUnidirectionalStreamId()1878 QuicStreamId QuicSession::GetNextOutgoingUnidirectionalStreamId() {
1879   if (VersionHasIetfQuicFrames(transport_version())) {
1880     return ietf_streamid_manager_.GetNextOutgoingUnidirectionalStreamId();
1881   }
1882   return stream_id_manager_.GetNextOutgoingStreamId();
1883 }
1884 
CanOpenNextOutgoingBidirectionalStream()1885 bool QuicSession::CanOpenNextOutgoingBidirectionalStream() {
1886   if (liveness_testing_in_progress_) {
1887     QUICHE_DCHECK_EQ(Perspective::IS_CLIENT, perspective());
1888     QUIC_CODE_COUNT(
1889         quic_client_fails_to_create_stream_liveness_testing_in_progress);
1890     return false;
1891   }
1892   if (!VersionHasIetfQuicFrames(transport_version())) {
1893     if (!stream_id_manager_.CanOpenNextOutgoingStream()) {
1894       return false;
1895     }
1896   } else {
1897     if (!ietf_streamid_manager_.CanOpenNextOutgoingBidirectionalStream()) {
1898       QUIC_CODE_COUNT(
1899           quic_fails_to_create_stream_close_too_many_streams_created);
1900       if (is_configured_) {
1901         // Send STREAM_BLOCKED after config negotiated.
1902         control_frame_manager_.WriteOrBufferStreamsBlocked(
1903             ietf_streamid_manager_.max_outgoing_bidirectional_streams(),
1904             /*unidirectional=*/false);
1905       }
1906       return false;
1907     }
1908   }
1909   if (perspective() == Perspective::IS_CLIENT &&
1910       connection_->MaybeTestLiveness()) {
1911     // Now is relatively close to the idle timeout having the risk that requests
1912     // could be discarded at the server.
1913     liveness_testing_in_progress_ = true;
1914     QUIC_CODE_COUNT(quic_client_fails_to_create_stream_close_to_idle_timeout);
1915     return false;
1916   }
1917   return true;
1918 }
1919 
CanOpenNextOutgoingUnidirectionalStream()1920 bool QuicSession::CanOpenNextOutgoingUnidirectionalStream() {
1921   if (!VersionHasIetfQuicFrames(transport_version())) {
1922     return stream_id_manager_.CanOpenNextOutgoingStream();
1923   }
1924   if (ietf_streamid_manager_.CanOpenNextOutgoingUnidirectionalStream()) {
1925     return true;
1926   }
1927   if (is_configured_) {
1928     // Send STREAM_BLOCKED after config negotiated.
1929     control_frame_manager_.WriteOrBufferStreamsBlocked(
1930         ietf_streamid_manager_.max_outgoing_unidirectional_streams(),
1931         /*unidirectional=*/true);
1932   }
1933   return false;
1934 }
1935 
GetAdvertisedMaxIncomingBidirectionalStreams() const1936 QuicStreamCount QuicSession::GetAdvertisedMaxIncomingBidirectionalStreams()
1937     const {
1938   QUICHE_DCHECK(VersionHasIetfQuicFrames(transport_version()));
1939   return ietf_streamid_manager_.advertised_max_incoming_bidirectional_streams();
1940 }
1941 
GetOrCreateStream(const QuicStreamId stream_id)1942 QuicStream* QuicSession::GetOrCreateStream(const QuicStreamId stream_id) {
1943   QUICHE_DCHECK(!pending_stream_map_.contains(stream_id));
1944   if (QuicUtils::IsCryptoStreamId(transport_version(), stream_id)) {
1945     return GetMutableCryptoStream();
1946   }
1947 
1948   StreamMap::iterator it = stream_map_.find(stream_id);
1949   if (it != stream_map_.end()) {
1950     return it->second->IsZombie() ? nullptr : it->second.get();
1951   }
1952 
1953   if (IsClosedStream(stream_id)) {
1954     return nullptr;
1955   }
1956 
1957   if (!IsIncomingStream(stream_id)) {
1958     HandleFrameOnNonexistentOutgoingStream(stream_id);
1959     return nullptr;
1960   }
1961 
1962   // TODO(fkastenholz): If we are creating a new stream and we have sent a
1963   // goaway, we should ignore the stream creation. Need to add code to A) test
1964   // if goaway was sent ("if (transport_goaway_sent_)") and B) reject stream
1965   // creation ("return nullptr")
1966 
1967   if (!MaybeIncreaseLargestPeerStreamId(stream_id)) {
1968     return nullptr;
1969   }
1970 
1971   if (!VersionHasIetfQuicFrames(transport_version()) &&
1972       !stream_id_manager_.CanOpenIncomingStream()) {
1973     // Refuse to open the stream.
1974     ResetStream(stream_id, QUIC_REFUSED_STREAM);
1975     return nullptr;
1976   }
1977 
1978   return CreateIncomingStream(stream_id);
1979 }
1980 
StreamDraining(QuicStreamId stream_id,bool unidirectional)1981 void QuicSession::StreamDraining(QuicStreamId stream_id, bool unidirectional) {
1982   QUICHE_DCHECK(stream_map_.contains(stream_id));
1983   QUIC_DVLOG(1) << ENDPOINT << "Stream " << stream_id << " is draining";
1984   if (VersionHasIetfQuicFrames(transport_version())) {
1985     ietf_streamid_manager_.OnStreamClosed(stream_id);
1986   } else {
1987     stream_id_manager_.OnStreamClosed(
1988         /*is_incoming=*/IsIncomingStream(stream_id));
1989   }
1990   ++num_draining_streams_;
1991   if (!IsIncomingStream(stream_id)) {
1992     ++num_outgoing_draining_streams_;
1993     if (!VersionHasIetfQuicFrames(transport_version())) {
1994       OnCanCreateNewOutgoingStream(unidirectional);
1995     }
1996   }
1997 }
1998 
MaybeIncreaseLargestPeerStreamId(const QuicStreamId stream_id)1999 bool QuicSession::MaybeIncreaseLargestPeerStreamId(
2000     const QuicStreamId stream_id) {
2001   if (VersionHasIetfQuicFrames(transport_version())) {
2002     std::string error_details;
2003     if (ietf_streamid_manager_.MaybeIncreaseLargestPeerStreamId(
2004             stream_id, &error_details)) {
2005       return true;
2006     }
2007     connection()->CloseConnection(
2008         QUIC_INVALID_STREAM_ID, error_details,
2009         ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
2010     return false;
2011   }
2012   if (!stream_id_manager_.MaybeIncreaseLargestPeerStreamId(stream_id)) {
2013     connection()->CloseConnection(
2014         QUIC_TOO_MANY_AVAILABLE_STREAMS,
2015         absl::StrCat(stream_id, " exceeds available streams ",
2016                      stream_id_manager_.MaxAvailableStreams()),
2017         ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
2018     return false;
2019   }
2020   return true;
2021 }
2022 
ShouldYield(QuicStreamId stream_id)2023 bool QuicSession::ShouldYield(QuicStreamId stream_id) {
2024   if (stream_id == currently_writing_stream_id_) {
2025     return false;
2026   }
2027   return write_blocked_streams()->ShouldYield(stream_id);
2028 }
2029 
GetOrCreatePendingStream(QuicStreamId stream_id)2030 PendingStream* QuicSession::GetOrCreatePendingStream(QuicStreamId stream_id) {
2031   auto it = pending_stream_map_.find(stream_id);
2032   if (it != pending_stream_map_.end()) {
2033     return it->second.get();
2034   }
2035 
2036   if (IsClosedStream(stream_id) ||
2037       !MaybeIncreaseLargestPeerStreamId(stream_id)) {
2038     return nullptr;
2039   }
2040 
2041   auto pending = std::make_unique<PendingStream>(stream_id, this);
2042   PendingStream* unowned_pending = pending.get();
2043   pending_stream_map_[stream_id] = std::move(pending);
2044   return unowned_pending;
2045 }
2046 
set_largest_peer_created_stream_id(QuicStreamId largest_peer_created_stream_id)2047 void QuicSession::set_largest_peer_created_stream_id(
2048     QuicStreamId largest_peer_created_stream_id) {
2049   QUICHE_DCHECK(!VersionHasIetfQuicFrames(transport_version()));
2050   stream_id_manager_.set_largest_peer_created_stream_id(
2051       largest_peer_created_stream_id);
2052 }
2053 
GetLargestPeerCreatedStreamId(bool unidirectional) const2054 QuicStreamId QuicSession::GetLargestPeerCreatedStreamId(
2055     bool unidirectional) const {
2056   // This method is only used in IETF QUIC.
2057   QUICHE_DCHECK(VersionHasIetfQuicFrames(transport_version()));
2058   return ietf_streamid_manager_.GetLargestPeerCreatedStreamId(unidirectional);
2059 }
2060 
DeleteConnection()2061 void QuicSession::DeleteConnection() {
2062   if (connection_) {
2063     delete connection_;
2064     connection_ = nullptr;
2065   }
2066 }
2067 
MaybeSetStreamPriority(QuicStreamId stream_id,const QuicStreamPriority & priority)2068 bool QuicSession::MaybeSetStreamPriority(QuicStreamId stream_id,
2069                                          const QuicStreamPriority& priority) {
2070   auto active_stream = stream_map_.find(stream_id);
2071   if (active_stream != stream_map_.end()) {
2072     active_stream->second->SetPriority(priority);
2073     return true;
2074   }
2075 
2076   return false;
2077 }
2078 
IsClosedStream(QuicStreamId id)2079 bool QuicSession::IsClosedStream(QuicStreamId id) {
2080   QUICHE_DCHECK_NE(QuicUtils::GetInvalidStreamId(transport_version()), id);
2081   if (IsOpenStream(id)) {
2082     // Stream is active
2083     return false;
2084   }
2085 
2086   if (VersionHasIetfQuicFrames(transport_version())) {
2087     return !ietf_streamid_manager_.IsAvailableStream(id);
2088   }
2089 
2090   return !stream_id_manager_.IsAvailableStream(id);
2091 }
2092 
IsOpenStream(QuicStreamId id)2093 bool QuicSession::IsOpenStream(QuicStreamId id) {
2094   QUICHE_DCHECK_NE(QuicUtils::GetInvalidStreamId(transport_version()), id);
2095   const StreamMap::iterator it = stream_map_.find(id);
2096   if (it != stream_map_.end()) {
2097     return !it->second->IsZombie();
2098   }
2099   if (pending_stream_map_.contains(id) ||
2100       QuicUtils::IsCryptoStreamId(transport_version(), id)) {
2101     // Stream is active
2102     return true;
2103   }
2104   return false;
2105 }
2106 
IsStaticStream(QuicStreamId id) const2107 bool QuicSession::IsStaticStream(QuicStreamId id) const {
2108   auto it = stream_map_.find(id);
2109   if (it == stream_map_.end()) {
2110     return false;
2111   }
2112   return it->second->is_static();
2113 }
2114 
GetNumActiveStreams() const2115 size_t QuicSession::GetNumActiveStreams() const {
2116   QUICHE_DCHECK_GE(
2117       static_cast<QuicStreamCount>(stream_map_.size()),
2118       num_static_streams_ + num_draining_streams_ + num_zombie_streams_);
2119   return stream_map_.size() - num_draining_streams_ - num_static_streams_ -
2120          num_zombie_streams_;
2121 }
2122 
MarkConnectionLevelWriteBlocked(QuicStreamId id)2123 void QuicSession::MarkConnectionLevelWriteBlocked(QuicStreamId id) {
2124   if (GetOrCreateStream(id) == nullptr) {
2125     QUIC_BUG(quic_bug_10866_11)
2126         << "Marking unknown stream " << id << " blocked.";
2127     QUIC_LOG_FIRST_N(ERROR, 2) << QuicStackTrace();
2128   }
2129 
2130   QUIC_DVLOG(1) << ENDPOINT << "Adding stream " << id
2131                 << " to write-blocked list";
2132 
2133   write_blocked_streams_->AddStream(id);
2134 }
2135 
HasDataToWrite() const2136 bool QuicSession::HasDataToWrite() const {
2137   return write_blocked_streams_->HasWriteBlockedSpecialStream() ||
2138          write_blocked_streams_->HasWriteBlockedDataStreams() ||
2139          connection_->HasQueuedData() ||
2140          !streams_with_pending_retransmission_.empty() ||
2141          control_frame_manager_.WillingToWrite();
2142 }
2143 
OnAckNeedsRetransmittableFrame()2144 void QuicSession::OnAckNeedsRetransmittableFrame() {
2145   flow_controller_.SendWindowUpdate();
2146 }
2147 
SendAckFrequency(const QuicAckFrequencyFrame & frame)2148 void QuicSession::SendAckFrequency(const QuicAckFrequencyFrame& frame) {
2149   control_frame_manager_.WriteOrBufferAckFrequency(frame);
2150 }
2151 
SendNewConnectionId(const QuicNewConnectionIdFrame & frame)2152 void QuicSession::SendNewConnectionId(const QuicNewConnectionIdFrame& frame) {
2153   // Count NEW_CONNECTION_ID frames sent to client.
2154   QUIC_RELOADABLE_FLAG_COUNT_N(quic_connection_migration_use_new_cid_v2, 1, 6);
2155   control_frame_manager_.WriteOrBufferNewConnectionId(
2156       frame.connection_id, frame.sequence_number, frame.retire_prior_to,
2157       frame.stateless_reset_token);
2158 }
2159 
SendRetireConnectionId(uint64_t sequence_number)2160 void QuicSession::SendRetireConnectionId(uint64_t sequence_number) {
2161   // Count RETIRE_CONNECTION_ID frames sent to client.
2162   QUIC_RELOADABLE_FLAG_COUNT_N(quic_connection_migration_use_new_cid_v2, 2, 6);
2163   control_frame_manager_.WriteOrBufferRetireConnectionId(sequence_number);
2164 }
2165 
MaybeReserveConnectionId(const QuicConnectionId & server_connection_id)2166 bool QuicSession::MaybeReserveConnectionId(
2167     const QuicConnectionId& server_connection_id) {
2168   if (visitor_) {
2169     return visitor_->TryAddNewConnectionId(
2170         connection_->GetOneActiveServerConnectionId(), server_connection_id);
2171   }
2172   return true;
2173 }
2174 
OnServerConnectionIdRetired(const QuicConnectionId & server_connection_id)2175 void QuicSession::OnServerConnectionIdRetired(
2176     const QuicConnectionId& server_connection_id) {
2177   if (visitor_) {
2178     visitor_->OnConnectionIdRetired(server_connection_id);
2179   }
2180 }
2181 
IsConnectionFlowControlBlocked() const2182 bool QuicSession::IsConnectionFlowControlBlocked() const {
2183   return flow_controller_.IsBlocked();
2184 }
2185 
IsStreamFlowControlBlocked()2186 bool QuicSession::IsStreamFlowControlBlocked() {
2187   for (auto const& kv : stream_map_) {
2188     if (kv.second->IsFlowControlBlocked()) {
2189       return true;
2190     }
2191   }
2192   if (!QuicVersionUsesCryptoFrames(transport_version()) &&
2193       GetMutableCryptoStream()->IsFlowControlBlocked()) {
2194     return true;
2195   }
2196   return false;
2197 }
2198 
MaxAvailableBidirectionalStreams() const2199 size_t QuicSession::MaxAvailableBidirectionalStreams() const {
2200   if (VersionHasIetfQuicFrames(transport_version())) {
2201     return ietf_streamid_manager_.GetMaxAllowdIncomingBidirectionalStreams();
2202   }
2203   return stream_id_manager_.MaxAvailableStreams();
2204 }
2205 
MaxAvailableUnidirectionalStreams() const2206 size_t QuicSession::MaxAvailableUnidirectionalStreams() const {
2207   if (VersionHasIetfQuicFrames(transport_version())) {
2208     return ietf_streamid_manager_.GetMaxAllowdIncomingUnidirectionalStreams();
2209   }
2210   return stream_id_manager_.MaxAvailableStreams();
2211 }
2212 
IsIncomingStream(QuicStreamId id) const2213 bool QuicSession::IsIncomingStream(QuicStreamId id) const {
2214   if (VersionHasIetfQuicFrames(transport_version())) {
2215     return !QuicUtils::IsOutgoingStreamId(version(), id, perspective_);
2216   }
2217   return stream_id_manager_.IsIncomingStream(id);
2218 }
2219 
MaybeCloseZombieStream(QuicStreamId id)2220 void QuicSession::MaybeCloseZombieStream(QuicStreamId id) {
2221   auto it = stream_map_.find(id);
2222   if (it == stream_map_.end()) {
2223     return;
2224   }
2225   --num_zombie_streams_;
2226   closed_streams_.push_back(std::move(it->second));
2227   stream_map_.erase(it);
2228 
2229   if (!closed_streams_clean_up_alarm_->IsSet()) {
2230     closed_streams_clean_up_alarm_->Set(connection_->clock()->ApproximateNow());
2231   }
2232   // Do not retransmit data of a closed stream.
2233   streams_with_pending_retransmission_.erase(id);
2234   connection_->QuicBugIfHasPendingFrames(id);
2235 }
2236 
GetStream(QuicStreamId id) const2237 QuicStream* QuicSession::GetStream(QuicStreamId id) const {
2238   auto active_stream = stream_map_.find(id);
2239   if (active_stream != stream_map_.end()) {
2240     return active_stream->second.get();
2241   }
2242 
2243   if (QuicUtils::IsCryptoStreamId(transport_version(), id)) {
2244     return const_cast<QuicCryptoStream*>(GetCryptoStream());
2245   }
2246 
2247   return nullptr;
2248 }
2249 
GetActiveStream(QuicStreamId id) const2250 QuicStream* QuicSession::GetActiveStream(QuicStreamId id) const {
2251   auto stream = stream_map_.find(id);
2252   if (stream != stream_map_.end() && !stream->second->is_static()) {
2253     return stream->second.get();
2254   }
2255   return nullptr;
2256 }
2257 
OnFrameAcked(const QuicFrame & frame,QuicTime::Delta ack_delay_time,QuicTime receive_timestamp)2258 bool QuicSession::OnFrameAcked(const QuicFrame& frame,
2259                                QuicTime::Delta ack_delay_time,
2260                                QuicTime receive_timestamp) {
2261   if (frame.type == MESSAGE_FRAME) {
2262     OnMessageAcked(frame.message_frame->message_id, receive_timestamp);
2263     return true;
2264   }
2265   if (frame.type == CRYPTO_FRAME) {
2266     return GetMutableCryptoStream()->OnCryptoFrameAcked(*frame.crypto_frame,
2267                                                         ack_delay_time);
2268   }
2269   if (frame.type != STREAM_FRAME) {
2270     return control_frame_manager_.OnControlFrameAcked(frame);
2271   }
2272   bool new_stream_data_acked = false;
2273   QuicStream* stream = GetStream(frame.stream_frame.stream_id);
2274   // Stream can already be reset when sent frame gets acked.
2275   if (stream != nullptr) {
2276     QuicByteCount newly_acked_length = 0;
2277     new_stream_data_acked = stream->OnStreamFrameAcked(
2278         frame.stream_frame.offset, frame.stream_frame.data_length,
2279         frame.stream_frame.fin, ack_delay_time, receive_timestamp,
2280         &newly_acked_length);
2281     if (!stream->HasPendingRetransmission()) {
2282       streams_with_pending_retransmission_.erase(stream->id());
2283     }
2284   }
2285   return new_stream_data_acked;
2286 }
2287 
OnStreamFrameRetransmitted(const QuicStreamFrame & frame)2288 void QuicSession::OnStreamFrameRetransmitted(const QuicStreamFrame& frame) {
2289   QuicStream* stream = GetStream(frame.stream_id);
2290   if (stream == nullptr) {
2291     QUIC_BUG(quic_bug_10866_12)
2292         << "Stream: " << frame.stream_id << " is closed when " << frame
2293         << " is retransmitted.";
2294     connection()->CloseConnection(
2295         QUIC_INTERNAL_ERROR, "Attempt to retransmit frame of a closed stream",
2296         ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
2297     return;
2298   }
2299   stream->OnStreamFrameRetransmitted(frame.offset, frame.data_length,
2300                                      frame.fin);
2301 }
2302 
OnFrameLost(const QuicFrame & frame)2303 void QuicSession::OnFrameLost(const QuicFrame& frame) {
2304   if (frame.type == MESSAGE_FRAME) {
2305     OnMessageLost(frame.message_frame->message_id);
2306     return;
2307   }
2308   if (frame.type == CRYPTO_FRAME) {
2309     GetMutableCryptoStream()->OnCryptoFrameLost(frame.crypto_frame);
2310     return;
2311   }
2312   if (frame.type != STREAM_FRAME) {
2313     control_frame_manager_.OnControlFrameLost(frame);
2314     return;
2315   }
2316   QuicStream* stream = GetStream(frame.stream_frame.stream_id);
2317   if (stream == nullptr) {
2318     return;
2319   }
2320   stream->OnStreamFrameLost(frame.stream_frame.offset,
2321                             frame.stream_frame.data_length,
2322                             frame.stream_frame.fin);
2323   if (stream->HasPendingRetransmission() &&
2324       !streams_with_pending_retransmission_.contains(
2325           frame.stream_frame.stream_id)) {
2326     streams_with_pending_retransmission_.insert(
2327         std::make_pair(frame.stream_frame.stream_id, true));
2328   }
2329 }
2330 
RetransmitFrames(const QuicFrames & frames,TransmissionType type)2331 bool QuicSession::RetransmitFrames(const QuicFrames& frames,
2332                                    TransmissionType type) {
2333   QuicConnection::ScopedPacketFlusher retransmission_flusher(connection_);
2334   for (const QuicFrame& frame : frames) {
2335     if (frame.type == MESSAGE_FRAME) {
2336       // Do not retransmit MESSAGE frames.
2337       continue;
2338     }
2339     if (frame.type == CRYPTO_FRAME) {
2340       if (!GetMutableCryptoStream()->RetransmitData(frame.crypto_frame, type)) {
2341         return false;
2342       }
2343       continue;
2344     }
2345     if (frame.type != STREAM_FRAME) {
2346       if (!control_frame_manager_.RetransmitControlFrame(frame, type)) {
2347         return false;
2348       }
2349       continue;
2350     }
2351     QuicStream* stream = GetStream(frame.stream_frame.stream_id);
2352     if (stream != nullptr &&
2353         !stream->RetransmitStreamData(frame.stream_frame.offset,
2354                                       frame.stream_frame.data_length,
2355                                       frame.stream_frame.fin, type)) {
2356       return false;
2357     }
2358   }
2359   return true;
2360 }
2361 
IsFrameOutstanding(const QuicFrame & frame) const2362 bool QuicSession::IsFrameOutstanding(const QuicFrame& frame) const {
2363   if (frame.type == MESSAGE_FRAME) {
2364     return false;
2365   }
2366   if (frame.type == CRYPTO_FRAME) {
2367     return GetCryptoStream()->IsFrameOutstanding(
2368         frame.crypto_frame->level, frame.crypto_frame->offset,
2369         frame.crypto_frame->data_length);
2370   }
2371   if (frame.type != STREAM_FRAME) {
2372     return control_frame_manager_.IsControlFrameOutstanding(frame);
2373   }
2374   QuicStream* stream = GetStream(frame.stream_frame.stream_id);
2375   return stream != nullptr &&
2376          stream->IsStreamFrameOutstanding(frame.stream_frame.offset,
2377                                           frame.stream_frame.data_length,
2378                                           frame.stream_frame.fin);
2379 }
2380 
HasUnackedCryptoData() const2381 bool QuicSession::HasUnackedCryptoData() const {
2382   const QuicCryptoStream* crypto_stream = GetCryptoStream();
2383   return crypto_stream->IsWaitingForAcks() || crypto_stream->HasBufferedData();
2384 }
2385 
HasUnackedStreamData() const2386 bool QuicSession::HasUnackedStreamData() const {
2387   for (const auto& it : stream_map_) {
2388     if (it.second->IsWaitingForAcks()) {
2389       return true;
2390     }
2391   }
2392   return false;
2393 }
2394 
GetHandshakeState() const2395 HandshakeState QuicSession::GetHandshakeState() const {
2396   return GetCryptoStream()->GetHandshakeState();
2397 }
2398 
WriteStreamData(QuicStreamId id,QuicStreamOffset offset,QuicByteCount data_length,QuicDataWriter * writer)2399 WriteStreamDataResult QuicSession::WriteStreamData(QuicStreamId id,
2400                                                    QuicStreamOffset offset,
2401                                                    QuicByteCount data_length,
2402                                                    QuicDataWriter* writer) {
2403   QuicStream* stream = GetStream(id);
2404   if (stream == nullptr) {
2405     // This causes the connection to be closed because of failed to serialize
2406     // packet.
2407     QUIC_BUG(quic_bug_10866_13)
2408         << "Stream " << id << " does not exist when trying to write data."
2409         << " version:" << transport_version();
2410     return STREAM_MISSING;
2411   }
2412   if (stream->WriteStreamData(offset, data_length, writer)) {
2413     return WRITE_SUCCESS;
2414   }
2415   return WRITE_FAILED;
2416 }
2417 
WriteCryptoData(EncryptionLevel level,QuicStreamOffset offset,QuicByteCount data_length,QuicDataWriter * writer)2418 bool QuicSession::WriteCryptoData(EncryptionLevel level,
2419                                   QuicStreamOffset offset,
2420                                   QuicByteCount data_length,
2421                                   QuicDataWriter* writer) {
2422   return GetMutableCryptoStream()->WriteCryptoFrame(level, offset, data_length,
2423                                                     writer);
2424 }
2425 
GetStatelessResetToken() const2426 StatelessResetToken QuicSession::GetStatelessResetToken() const {
2427   return QuicUtils::GenerateStatelessResetToken(connection_->connection_id());
2428 }
2429 
CanWriteStreamData() const2430 bool QuicSession::CanWriteStreamData() const {
2431   // Don't write stream data if there are queued data packets.
2432   if (connection_->HasQueuedPackets()) {
2433     return false;
2434   }
2435   // Immediately write handshake data.
2436   if (HasPendingHandshake()) {
2437     return true;
2438   }
2439   return connection_->CanWrite(HAS_RETRANSMITTABLE_DATA);
2440 }
2441 
RetransmitLostData()2442 bool QuicSession::RetransmitLostData() {
2443   QuicConnection::ScopedPacketFlusher retransmission_flusher(connection_);
2444   // Retransmit crypto data first.
2445   bool uses_crypto_frames = QuicVersionUsesCryptoFrames(transport_version());
2446   QuicCryptoStream* crypto_stream = GetMutableCryptoStream();
2447   if (uses_crypto_frames && crypto_stream->HasPendingCryptoRetransmission()) {
2448     crypto_stream->WritePendingCryptoRetransmission();
2449   }
2450   // Retransmit crypto data in stream 1 frames (version < 47).
2451   if (!uses_crypto_frames &&
2452       streams_with_pending_retransmission_.contains(
2453           QuicUtils::GetCryptoStreamId(transport_version()))) {
2454     // Retransmit crypto data first.
2455     QuicStream* crypto_stream =
2456         GetStream(QuicUtils::GetCryptoStreamId(transport_version()));
2457     crypto_stream->OnCanWrite();
2458     QUICHE_DCHECK(CheckStreamWriteBlocked(crypto_stream));
2459     if (crypto_stream->HasPendingRetransmission()) {
2460       // Connection is write blocked.
2461       return false;
2462     } else {
2463       streams_with_pending_retransmission_.erase(
2464           QuicUtils::GetCryptoStreamId(transport_version()));
2465     }
2466   }
2467   if (control_frame_manager_.HasPendingRetransmission()) {
2468     control_frame_manager_.OnCanWrite();
2469     if (control_frame_manager_.HasPendingRetransmission()) {
2470       return false;
2471     }
2472   }
2473   while (!streams_with_pending_retransmission_.empty()) {
2474     if (!CanWriteStreamData()) {
2475       break;
2476     }
2477     // Retransmit lost data on headers and data streams.
2478     const QuicStreamId id = streams_with_pending_retransmission_.begin()->first;
2479     QuicStream* stream = GetStream(id);
2480     if (stream != nullptr) {
2481       stream->OnCanWrite();
2482       QUICHE_DCHECK(CheckStreamWriteBlocked(stream));
2483       if (stream->HasPendingRetransmission()) {
2484         // Connection is write blocked.
2485         break;
2486       } else if (!streams_with_pending_retransmission_.empty() &&
2487                  streams_with_pending_retransmission_.begin()->first == id) {
2488         // Retransmit lost data may cause connection close. If this stream
2489         // has not yet sent fin, a RST_STREAM will be sent and it will be
2490         // removed from streams_with_pending_retransmission_.
2491         streams_with_pending_retransmission_.pop_front();
2492       }
2493     } else {
2494       QUIC_BUG(quic_bug_10866_14)
2495           << "Try to retransmit data of a closed stream";
2496       streams_with_pending_retransmission_.pop_front();
2497     }
2498   }
2499 
2500   return streams_with_pending_retransmission_.empty();
2501 }
2502 
NeuterUnencryptedData()2503 void QuicSession::NeuterUnencryptedData() {
2504   QuicCryptoStream* crypto_stream = GetMutableCryptoStream();
2505   crypto_stream->NeuterUnencryptedStreamData();
2506   if (!crypto_stream->HasPendingRetransmission() &&
2507       !QuicVersionUsesCryptoFrames(transport_version())) {
2508     streams_with_pending_retransmission_.erase(
2509         QuicUtils::GetCryptoStreamId(transport_version()));
2510   }
2511   connection_->NeuterUnencryptedPackets();
2512 }
2513 
SetTransmissionType(TransmissionType type)2514 void QuicSession::SetTransmissionType(TransmissionType type) {
2515   connection_->SetTransmissionType(type);
2516 }
2517 
SendMessage(absl::Span<quiche::QuicheMemSlice> message)2518 MessageResult QuicSession::SendMessage(
2519     absl::Span<quiche::QuicheMemSlice> message) {
2520   return SendMessage(message, /*flush=*/false);
2521 }
2522 
SendMessage(quiche::QuicheMemSlice message)2523 MessageResult QuicSession::SendMessage(quiche::QuicheMemSlice message) {
2524   return SendMessage(absl::MakeSpan(&message, 1), /*flush=*/false);
2525 }
2526 
SendMessage(absl::Span<quiche::QuicheMemSlice> message,bool flush)2527 MessageResult QuicSession::SendMessage(
2528     absl::Span<quiche::QuicheMemSlice> message, bool flush) {
2529   QUICHE_DCHECK(connection_->connected())
2530       << ENDPOINT << "Try to write messages when connection is closed.";
2531   if (!IsEncryptionEstablished()) {
2532     return {MESSAGE_STATUS_ENCRYPTION_NOT_ESTABLISHED, 0};
2533   }
2534   QuicConnection::ScopedEncryptionLevelContext context(
2535       connection(), GetEncryptionLevelToSendApplicationData());
2536   MessageStatus result =
2537       connection_->SendMessage(last_message_id_ + 1, message, flush);
2538   if (result == MESSAGE_STATUS_SUCCESS) {
2539     return {result, ++last_message_id_};
2540   }
2541   return {result, 0};
2542 }
2543 
OnMessageAcked(QuicMessageId message_id,QuicTime)2544 void QuicSession::OnMessageAcked(QuicMessageId message_id,
2545                                  QuicTime /*receive_timestamp*/) {
2546   QUIC_DVLOG(1) << ENDPOINT << "message " << message_id << " gets acked.";
2547 }
2548 
OnMessageLost(QuicMessageId message_id)2549 void QuicSession::OnMessageLost(QuicMessageId message_id) {
2550   QUIC_DVLOG(1) << ENDPOINT << "message " << message_id
2551                 << " is considered lost";
2552 }
2553 
CleanUpClosedStreams()2554 void QuicSession::CleanUpClosedStreams() { closed_streams_.clear(); }
2555 
GetCurrentLargestMessagePayload() const2556 QuicPacketLength QuicSession::GetCurrentLargestMessagePayload() const {
2557   return connection_->GetCurrentLargestMessagePayload();
2558 }
2559 
GetGuaranteedLargestMessagePayload() const2560 QuicPacketLength QuicSession::GetGuaranteedLargestMessagePayload() const {
2561   return connection_->GetGuaranteedLargestMessagePayload();
2562 }
2563 
next_outgoing_bidirectional_stream_id() const2564 QuicStreamId QuicSession::next_outgoing_bidirectional_stream_id() const {
2565   if (VersionHasIetfQuicFrames(transport_version())) {
2566     return ietf_streamid_manager_.next_outgoing_bidirectional_stream_id();
2567   }
2568   return stream_id_manager_.next_outgoing_stream_id();
2569 }
2570 
next_outgoing_unidirectional_stream_id() const2571 QuicStreamId QuicSession::next_outgoing_unidirectional_stream_id() const {
2572   if (VersionHasIetfQuicFrames(transport_version())) {
2573     return ietf_streamid_manager_.next_outgoing_unidirectional_stream_id();
2574   }
2575   return stream_id_manager_.next_outgoing_stream_id();
2576 }
2577 
OnMaxStreamsFrame(const QuicMaxStreamsFrame & frame)2578 bool QuicSession::OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) {
2579   const bool allow_new_streams =
2580       frame.unidirectional
2581           ? ietf_streamid_manager_.MaybeAllowNewOutgoingUnidirectionalStreams(
2582                 frame.stream_count)
2583           : ietf_streamid_manager_.MaybeAllowNewOutgoingBidirectionalStreams(
2584                 frame.stream_count);
2585   if (allow_new_streams) {
2586     OnCanCreateNewOutgoingStream(frame.unidirectional);
2587   }
2588 
2589   return true;
2590 }
2591 
OnStreamsBlockedFrame(const QuicStreamsBlockedFrame & frame)2592 bool QuicSession::OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) {
2593   std::string error_details;
2594   if (ietf_streamid_manager_.OnStreamsBlockedFrame(frame, &error_details)) {
2595     return true;
2596   }
2597   connection_->CloseConnection(
2598       QUIC_STREAMS_BLOCKED_ERROR, error_details,
2599       ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
2600   return false;
2601 }
2602 
max_open_incoming_bidirectional_streams() const2603 size_t QuicSession::max_open_incoming_bidirectional_streams() const {
2604   if (VersionHasIetfQuicFrames(transport_version())) {
2605     return ietf_streamid_manager_.GetMaxAllowdIncomingBidirectionalStreams();
2606   }
2607   return stream_id_manager_.max_open_incoming_streams();
2608 }
2609 
max_open_incoming_unidirectional_streams() const2610 size_t QuicSession::max_open_incoming_unidirectional_streams() const {
2611   if (VersionHasIetfQuicFrames(transport_version())) {
2612     return ietf_streamid_manager_.GetMaxAllowdIncomingUnidirectionalStreams();
2613   }
2614   return stream_id_manager_.max_open_incoming_streams();
2615 }
2616 
SelectAlpn(const std::vector<absl::string_view> & alpns) const2617 std::vector<absl::string_view>::const_iterator QuicSession::SelectAlpn(
2618     const std::vector<absl::string_view>& alpns) const {
2619   const std::string alpn = AlpnForVersion(connection()->version());
2620   return std::find(alpns.cbegin(), alpns.cend(), alpn);
2621 }
2622 
OnAlpnSelected(absl::string_view alpn)2623 void QuicSession::OnAlpnSelected(absl::string_view alpn) {
2624   QUIC_DLOG(INFO) << (perspective() == Perspective::IS_SERVER ? "Server: "
2625                                                               : "Client: ")
2626                   << "ALPN selected: " << alpn;
2627 }
2628 
NeuterCryptoDataOfEncryptionLevel(EncryptionLevel level)2629 void QuicSession::NeuterCryptoDataOfEncryptionLevel(EncryptionLevel level) {
2630   GetMutableCryptoStream()->NeuterStreamDataOfEncryptionLevel(level);
2631 }
2632 
PerformActionOnActiveStreams(std::function<bool (QuicStream *)> action)2633 void QuicSession::PerformActionOnActiveStreams(
2634     std::function<bool(QuicStream*)> action) {
2635   std::vector<QuicStream*> active_streams;
2636   for (const auto& it : stream_map_) {
2637     if (!it.second->is_static() && !it.second->IsZombie()) {
2638       active_streams.push_back(it.second.get());
2639     }
2640   }
2641 
2642   for (QuicStream* stream : active_streams) {
2643     if (!action(stream)) {
2644       return;
2645     }
2646   }
2647 }
2648 
PerformActionOnActiveStreams(std::function<bool (QuicStream *)> action) const2649 void QuicSession::PerformActionOnActiveStreams(
2650     std::function<bool(QuicStream*)> action) const {
2651   for (const auto& it : stream_map_) {
2652     if (!it.second->is_static() && !it.second->IsZombie() &&
2653         !action(it.second.get())) {
2654       return;
2655     }
2656   }
2657 }
2658 
GetEncryptionLevelToSendApplicationData() const2659 EncryptionLevel QuicSession::GetEncryptionLevelToSendApplicationData() const {
2660   return connection_->framer().GetEncryptionLevelToSendApplicationData();
2661 }
2662 
ProcessAllPendingStreams()2663 void QuicSession::ProcessAllPendingStreams() {
2664   std::vector<PendingStream*> pending_streams;
2665   pending_streams.reserve(pending_stream_map_.size());
2666   for (auto it = pending_stream_map_.cbegin(); it != pending_stream_map_.cend();
2667        ++it) {
2668     pending_streams.push_back(it->second.get());
2669   }
2670   for (auto* pending_stream : pending_streams) {
2671     MaybeProcessPendingStream(pending_stream);
2672     if (!connection()->connected()) {
2673       return;
2674     }
2675   }
2676 }
2677 
ValidatePath(std::unique_ptr<QuicPathValidationContext> context,std::unique_ptr<QuicPathValidator::ResultDelegate> result_delegate,PathValidationReason reason)2678 void QuicSession::ValidatePath(
2679     std::unique_ptr<QuicPathValidationContext> context,
2680     std::unique_ptr<QuicPathValidator::ResultDelegate> result_delegate,
2681     PathValidationReason reason) {
2682   connection_->ValidatePath(std::move(context), std::move(result_delegate),
2683                             reason);
2684 }
2685 
HasPendingPathValidation() const2686 bool QuicSession::HasPendingPathValidation() const {
2687   return connection_->HasPendingPathValidation();
2688 }
2689 
MigratePath(const QuicSocketAddress & self_address,const QuicSocketAddress & peer_address,QuicPacketWriter * writer,bool owns_writer)2690 bool QuicSession::MigratePath(const QuicSocketAddress& self_address,
2691                               const QuicSocketAddress& peer_address,
2692                               QuicPacketWriter* writer, bool owns_writer) {
2693   return connection_->MigratePath(self_address, peer_address, writer,
2694                                   owns_writer);
2695 }
2696 
ValidateToken(absl::string_view token)2697 bool QuicSession::ValidateToken(absl::string_view token) {
2698   QUICHE_DCHECK_EQ(perspective_, Perspective::IS_SERVER);
2699   if (GetQuicFlag(quic_reject_retry_token_in_initial_packet)) {
2700     return false;
2701   }
2702   if (token.empty() || token[0] != kAddressTokenPrefix) {
2703     // Validate the prefix for token received in NEW_TOKEN frame.
2704     return false;
2705   }
2706   const bool valid = GetCryptoStream()->ValidateAddressToken(
2707       absl::string_view(token.data() + 1, token.length() - 1));
2708   if (valid) {
2709     const CachedNetworkParameters* cached_network_params =
2710         GetCryptoStream()->PreviousCachedNetworkParams();
2711     if (cached_network_params != nullptr &&
2712         cached_network_params->timestamp() > 0) {
2713       connection()->OnReceiveConnectionState(*cached_network_params);
2714     }
2715   }
2716   return valid;
2717 }
2718 
OnServerPreferredAddressAvailable(const QuicSocketAddress & server_preferred_address)2719 void QuicSession::OnServerPreferredAddressAvailable(
2720     const QuicSocketAddress& server_preferred_address) {
2721   QUICHE_DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
2722   if (visitor_ != nullptr) {
2723     visitor_->OnServerPreferredAddressAvailable(server_preferred_address);
2724   }
2725 }
2726 
2727 #undef ENDPOINT  // undef for jumbo builds
2728 }  // namespace quic
2729