chromium/net/spdy/spdy_session.h

// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef NET_SPDY_SPDY_SESSION_H_
#define NET_SPDY_SPDY_SESSION_H_

#include <stddef.h>
#include <stdint.h>

#include <map>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <string_view>
#include <vector>

#include "base/containers/circular_deque.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "base/values.h"
#include "net/base/completion_once_callback.h"
#include "net/base/host_port_pair.h"
#include "net/base/io_buffer.h"
#include "net/base/load_states.h"
#include "net/base/load_timing_info.h"
#include "net/base/net_errors.h"
#include "net/base/net_export.h"
#include "net/base/network_change_notifier.h"
#include "net/base/request_priority.h"
#include "net/log/net_log_source.h"
#include "net/socket/client_socket_pool.h"
#include "net/socket/next_proto.h"
#include "net/socket/ssl_client_socket.h"
#include "net/socket/stream_socket.h"
#include "net/socket/stream_socket_handle.h"
#include "net/spdy/buffered_spdy_framer.h"
#include "net/spdy/http2_priority_dependencies.h"
#include "net/spdy/multiplexed_session.h"
#include "net/spdy/spdy_buffer.h"
#include "net/spdy/spdy_session_pool.h"
#include "net/spdy/spdy_stream.h"
#include "net/spdy/spdy_write_queue.h"
#include "net/ssl/ssl_config_service.h"
#include "net/third_party/quiche/src/quiche/common/http/http_header_block.h"
#include "net/third_party/quiche/src/quiche/spdy/core/spdy_alt_svc_wire_format.h"
#include "net/third_party/quiche/src/quiche/spdy/core/spdy_framer.h"
#include "net/third_party/quiche/src/quiche/spdy/core/spdy_protocol.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "url/gurl.h"
#include "url/origin.h"
#include "url/scheme_host_port.h"

namespace net {

namespace test {
class SpdyStreamTest;
}

// TLS and other layers will chunk data at 16KB. Making the max frame size too
// small will lead to increased CPU/byte cost and overhead on both client/server
// due to excessive frames to process. Making this larger has diminishing
// returns as the data will be chunked elsewhere. We also want to ensure we are
// >= 2860B (~2* MSS => 2 packets) to avoid delayed ACKs. We will also account
// for the frame header size of 9B to prevent fragmentation when this is added.
// As a result we will use a 16KB - 9B max data frame size.
const int kMaxSpdyFrameChunkSize =;

// Default value of spdy::SETTINGS_INITIAL_WINDOW_SIZE per protocol
// specification. A session is always created with this initial window size.
const int32_t kDefaultInitialWindowSize =;

// Maximum number of concurrent streams we will create, unless the server
// sends a SETTINGS frame with a different value.
const size_t kInitialMaxConcurrentStreams =;

// If more than this many bytes have been read or more than that many
// milliseconds have passed, return ERR_IO_PENDING from ReadLoop.
const int kYieldAfterBytesRead =;
const int kYieldAfterDurationMilliseconds =;

// First and last valid stream IDs. As we always act as the client,
// start at 1 for the first stream id.
const spdy::SpdyStreamId kFirstStreamId =;
const spdy::SpdyStreamId kLastStreamId =;

// Maximum number of capped frames that can be queued at any time.
// We measured how many queued capped frames were ever in the
// SpdyWriteQueue at one given time between 2019-08 and 2020-02.
// The numbers showed that in 99.94% of cases it would always
// stay below 10, and that it would exceed 1000 only in
// 10^-8 of cases. Therefore we picked 10000 as a number that will
// virtually never be hit in practice, while still preventing an
// attacker from growing this queue unboundedly.
const int kSpdySessionMaxQueuedCappedFrames =;

// Default time to delay sending small receive window updates (can be
// configured through SetTimeToBufferSmallWindowUpdates()). Usually window
// updates are sent when half of the receive window has been processed by
// the client but in the case of a client that consumes the data slowly,
// this strategy alone would make servers consider the connection or stream
// idle.
constexpr base::TimeDelta kDefaultTimeToBufferSmallWindowUpdates =;

class NetLog;
class NetworkQualityEstimator;
class SpdyStream;
class SSLInfo;
class TransportSecurityState;

// NOTE: There is an enum called SpdyProtocolErrorDetails2 (also with numeric
// suffixes) in tools/metrics/histograms/enums.xml. Be sure to add new values
// there also.
enum SpdyProtocolErrorDetails {};
SpdyProtocolErrorDetails NET_EXPORT_PRIVATE MapFramerErrorToProtocolError(
    http2::Http2DecoderAdapter::SpdyFramerError error);
Error NET_EXPORT_PRIVATE
MapFramerErrorToNetError(http2::Http2DecoderAdapter::SpdyFramerError error);
SpdyProtocolErrorDetails NET_EXPORT_PRIVATE
MapRstStreamStatusToProtocolError(spdy::SpdyErrorCode error_code);
spdy::SpdyErrorCode NET_EXPORT_PRIVATE MapNetErrorToGoAwayStatus(Error err);

// If these compile asserts fail then SpdyProtocolErrorDetails needs
// to be updated with new values, as do the mapping functions above.
static_assert;
static_assert;

// A helper class used to manage a request to create a stream.
class NET_EXPORT_PRIVATE SpdyStreamRequest {};

class NET_EXPORT SpdySession
    : public BufferedSpdyFramerVisitorInterface,
      public spdy::SpdyFramerDebugVisitorInterface,
      public MultiplexedSession,
      public HigherLayeredPool,
      public NetworkChangeNotifier::DefaultNetworkActiveObserver {};

}  // namespace net

#endif  // NET_SPDY_SPDY_SESSION_H_