1
0
mirror of https://github.com/facebookincubator/mvfst.git synced 2025-11-09 10:00:57 +03:00
Files
mvfst/quic/server/state/ServerStateMachine.h
Amaury Séchet 2f8774c921 Only take a QuicServerConnectionState when constructing ServerHandshake (#90)
Summary:
The cryptoState can be derrived from it, so it is redundant to pass it.

This PR depends on https://github.com/facebookincubator/mvfst/issues/88
Pull Request resolved: https://github.com/facebookincubator/mvfst/pull/90

Reviewed By: mjoras

Differential Revision: D19622581

Pulled By: yangchi

fbshipit-source-id: b3c88999199673f69c4422b96fbe7f2b0656bf6c
2020-02-12 09:42:18 -08:00

196 lines
6.4 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/logging/QuicLogger.h>
#include <quic/loss/QuicLossFunctions.h>
#include <quic/server/handshake/ServerHandshake.h>
#include <quic/state/AckHandlers.h>
#include <quic/state/QPRFunctions.h>
#include <quic/state/QuicStateFunctions.h>
#include <quic/state/QuicStreamFunctions.h>
#include <quic/state/SimpleFrameFunctions.h>
#include <quic/state/StateData.h>
#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};
// 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;
folly::Optional<ConnectionIdData> createAndAddNewSelfConnId() override;
QuicServerConnectionState() : QuicConnectionStateBase(QuicNodeType::Server) {
state = ServerState::Open;
// Create the crypto stream.
cryptoState = std::make_unique<QuicCryptoState>();
congestionController = std::make_unique<Cubic>(*this);
// TODO: this is wrong, it should be the handshake finish time. But i need
// a relatively sane time now to make the timestamps all sane.
connectionTime = Clock::now();
supportedVersions = std::vector<QuicVersion>{{QuicVersion::MVFST,
QuicVersion::MVFST_OLD,
QuicVersion::QUIC_DRAFT,
QuicVersion::QUIC_DRAFT_23}};
originalVersion = QuicVersion::MVFST;
serverHandshakeLayer = new ServerHandshake(this);
handshakeLayer.reset(serverHandshakeLayer);
// 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,
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);
} // namespace quic