1
0
mirror of https://github.com/facebookincubator/mvfst.git synced 2025-11-25 15:43:13 +03:00
Files
mvfst/quic/server/state/ServerStateMachine.h
Matt Joras 003f012cb7 TODO comment cleanup.
Summary:
These are either no longer relevant, are unlikely to be done, or are spculative enough that they don't deserve code space.

Hope here is to make our search for TODOs higher signal.

Reviewed By: lnicco

Differential Revision: D29769792

fbshipit-source-id: 7cfa62cdc15e72d8b7b0cd5dbb5913ea3ca3dc5a
2021-07-20 10:27:32 -07:00

226 lines
7.2 KiB
C++

/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
#pragma once
#include <glog/logging.h>
#include <memory>
#include <vector>
#include <quic/QuicException.h>
#include <quic/codec/Types.h>
#include <quic/congestion_control/CongestionControllerFactory.h>
#include <quic/congestion_control/QuicCubic.h>
#include <quic/flowcontrol/QuicFlowController.h>
#include <quic/loss/QuicLossFunctions.h>
#include <quic/server/handshake/ServerHandshake.h>
#include <quic/server/handshake/ServerHandshakeFactory.h>
#include <quic/server/state/ServerConnectionIdRejector.h>
#include <quic/state/AckHandlers.h>
#include <quic/state/QuicStateFunctions.h>
#include <quic/state/QuicStreamFunctions.h>
#include <quic/state/SimpleFrameFunctions.h>
#include <quic/state/StateData.h>
#ifdef CCP_ENABLED
#include <ccp/ccp.h>
#endif
#include <folly/ExceptionWrapper.h>
#include <folly/IPAddress.h>
#include <folly/Overload.h>
#include <folly/Random.h>
#include <folly/io/async/AsyncSocketException.h>
namespace quic {
enum ServerState {
Open,
Closed,
};
struct ServerEvents {
struct ReadData {
folly::SocketAddress peer;
NetworkDataSingle networkData;
};
struct Close {};
};
struct CongestionAndRttState {
// The corresponding peer address
folly::SocketAddress peerAddress;
// Time when this state is recorded, i.e. when migration happens
TimePoint recordTime;
// Congestion controller
std::unique_ptr<CongestionController> congestionController;
// Smooth rtt
std::chrono::microseconds srtt;
// Latest rtt
std::chrono::microseconds lrtt;
// Rtt var
std::chrono::microseconds rttvar;
// Minimum rtt
std::chrono::microseconds mrtt;
};
struct ConnectionMigrationState {
uint32_t numMigrations{0};
// Previous validated peer addresses, not containing current peer address
std::vector<folly::SocketAddress> previousPeerAddresses;
// Congestion state and rtt stats of last validated peer
folly::Optional<CongestionAndRttState> lastCongestionAndRtt;
};
struct QuicServerConnectionState : public QuicConnectionStateBase {
~QuicServerConnectionState() override = default;
ServerState state;
// Data which we cannot read yet, because the handshake has not completed.
// Zero rtt protected packets
std::unique_ptr<std::vector<ServerEvents::ReadData>> pendingZeroRttData;
// One rtt protected packets
std::unique_ptr<std::vector<ServerEvents::ReadData>> pendingOneRttData;
// Current state of connection migration
ConnectionMigrationState migrationState;
// Parameters to generate server chosen connection id
folly::Optional<ServerConnectionIdParams> serverConnIdParams;
// ConnectionIdAlgo implementation to encode and decode ConnectionId with
// various info, such as routing related info.
ConnectionIdAlgo* connIdAlgo{nullptr};
// ServerConnectionIdRejector can reject a ConnectionId from ConnectionIdAlgo
ServerConnectionIdRejector* connIdRejector{nullptr};
// Source address token that can be saved to client via PSK.
// Address with higher index is more recently used.
std::vector<folly::IPAddress> tokenSourceAddresses;
ServerHandshake* serverHandshakeLayer;
// Whether transport parameters from psk match current server parameters.
// A false value indicates 0-rtt is rejected.
folly::Optional<bool> transportParamsMatching;
// Whether source address token matches client ip.
// A false value indicates either 0-rtt is rejected or inflight bytes are
// limited until CFIN depending on matching policy.
folly::Optional<bool> sourceTokenMatching;
// Server address of VIP. Currently used as input for stateless reset token.
folly::SocketAddress serverAddr;
// Whether we've sent the handshake done signal yet.
bool sentHandshakeDone{false};
#ifdef CCP_ENABLED
// Pointer to struct that maintains state needed for interacting with libccp.
// Once instance of this struct is created for each instance of
// QuicServerWorker (but lives in the worker's corresponding CCPReader). We
// need to store a pointer to it here, because it needs to be accessible by
// the QuicCCP congestion control algorithm, which only has access to the
// connection's QuicConnectionStateBase.
struct ccp_datapath* ccpDatapath;
#endif
folly::Optional<ConnectionIdData> createAndAddNewSelfConnId() override;
QuicServerConnectionState(
std::shared_ptr<ServerHandshakeFactory> handshakeFactory)
: QuicConnectionStateBase(QuicNodeType::Server) {
state = ServerState::Open;
// Create the crypto stream.
cryptoState = std::make_unique<QuicCryptoState>();
congestionController = std::make_unique<Cubic>(*this);
connectionTime = Clock::now();
supportedVersions = std::vector<QuicVersion>{
{QuicVersion::MVFST,
QuicVersion::MVFST_D24,
QuicVersion::MVFST_EXPERIMENTAL,
QuicVersion::QUIC_DRAFT,
QuicVersion::QUIC_DRAFT_LEGACY}};
originalVersion = QuicVersion::MVFST;
DCHECK(handshakeFactory);
auto tmpServerHandshake =
std::move(*handshakeFactory).makeServerHandshake(this);
serverHandshakeLayer = tmpServerHandshake.get();
handshakeLayer = std::move(tmpServerHandshake);
// We shouldn't normally need to set this until we're starting the
// transport, however writing unit tests is much easier if we set this here.
updateFlowControlStateWithSettings(flowControlState, transportSettings);
pendingZeroRttData =
std::make_unique<std::vector<ServerEvents::ReadData>>();
pendingOneRttData = std::make_unique<std::vector<ServerEvents::ReadData>>();
streamManager = std::make_unique<QuicStreamManager>(
*this, this->nodeType, transportSettings);
}
};
// Transition to error state on invalid state transition.
void ServerInvalidStateHandler(QuicServerConnectionState& state);
void onServerReadData(
QuicServerConnectionState& conn,
ServerEvents::ReadData& readData);
void onServerReadDataFromOpen(
QuicServerConnectionState& conn,
ServerEvents::ReadData& readData);
void onServerReadDataFromClosed(
QuicServerConnectionState& conn,
ServerEvents::ReadData& readData);
void onServerClose(QuicServerConnectionState& conn);
void onServerCloseOpenState(QuicServerConnectionState& conn);
void processClientInitialParams(
QuicServerConnectionState& conn,
const ClientTransportParameters& clientParams);
void updateHandshakeState(QuicServerConnectionState& conn);
bool validateAndUpdateSourceToken(
QuicServerConnectionState& conn,
std::vector<folly::IPAddress> sourceAddresses);
void updateWritableByteLimitOnRecvPacket(QuicServerConnectionState& conn);
void updateTransportParamsFromTicket(
QuicServerConnectionState& conn,
uint64_t idleTimeout,
uint64_t maxRecvPacketSize,
uint64_t initialMaxData,
uint64_t initialMaxStreamDataBidiLocal,
uint64_t initialMaxStreamDataBidiRemote,
uint64_t initialMaxStreamDataUni,
uint64_t initialMaxStreamsBidi,
uint64_t initialMaxStreamsUni);
void onConnectionMigration(
QuicServerConnectionState& conn,
const folly::SocketAddress& newPeerAddress,
bool isIntentional = false);
std::vector<TransportParameter> setSupportedExtensionTransportParameters(
QuicServerConnectionState& conn);
} // namespace quic