1 /* 2 * Copyright (c) Facebook, Inc. and its affiliates. 3 * 4 * This source code is licensed under the MIT license found in the 5 * LICENSE file in the root directory of this source tree. 6 * 7 */ 8 9 #pragma once 10 11 #include <folly/io/async/AsyncSocketException.h> 12 #include <quic/client/handshake/ClientHandshake.h> 13 #include <quic/client/handshake/ClientHandshakeFactory.h> 14 #include <quic/congestion_control/QuicCubic.h> 15 #include <quic/flowcontrol/QuicFlowController.h> 16 #include <quic/handshake/TransportParameters.h> 17 #include <quic/state/QuicStateFunctions.h> 18 #include <quic/state/StateData.h> 19 20 namespace quic { 21 22 struct CachedServerTransportParameters; 23 24 struct PendingClientData { 25 NetworkDataSingle networkData; 26 folly::SocketAddress peer; 27 PendingClientDataPendingClientData28 PendingClientData( 29 NetworkDataSingle networkDataIn, 30 folly::SocketAddress peerIn) 31 : networkData(std::move(networkDataIn)), peer(std::move(peerIn)) {} 32 }; 33 34 struct QuicClientConnectionState : public QuicConnectionStateBase { 35 ~QuicClientConnectionState() override = default; 36 37 // Zero rtt write header cipher. 38 std::unique_ptr<PacketNumberCipher> zeroRttWriteHeaderCipher; 39 // Write cipher for 0-RTT data 40 std::unique_ptr<Aead> zeroRttWriteCipher; 41 42 // The stateless reset token sent by the server. 43 folly::Optional<StatelessResetToken> statelessResetToken; 44 45 // The retry token sent by the server. 46 std::string retryToken; 47 48 // This is the destination connection id that will be sent in the outgoing 49 // client initial packet. It is modified in the event of a retry. 50 folly::Optional<ConnectionId> initialDestinationConnectionId; 51 52 // This is the original destination connection id. It is the same as the 53 // initialDestinationConnectionId when there is no retry involved. When 54 // there is retry involved, this is the value of the destination connection 55 // id sent in the very first initial packet. 56 folly::Optional<ConnectionId> originalDestinationConnectionId; 57 58 std::shared_ptr<ClientHandshakeFactory> handshakeFactory; 59 ClientHandshake* clientHandshakeLayer; 60 61 folly::Optional<TimePoint> lastCloseSentTime; 62 63 // Save the server transport params here so that client can access the value 64 // when it wants to write the values to psk cache 65 // TODO Save TicketTransportParams here instead of in QuicClientTransport 66 bool serverInitialParamsSet_{false}; 67 uint64_t peerAdvertisedInitialMaxData{0}; 68 uint64_t peerAdvertisedInitialMaxStreamDataBidiLocal{0}; 69 uint64_t peerAdvertisedInitialMaxStreamDataBidiRemote{0}; 70 uint64_t peerAdvertisedInitialMaxStreamDataUni{0}; 71 uint64_t peerAdvertisedInitialMaxStreamsBidi{0}; 72 uint64_t peerAdvertisedInitialMaxStreamsUni{0}; 73 74 struct HappyEyeballsState { 75 // Delay timer 76 folly::HHWheelTimer::Callback* connAttemptDelayTimeout{nullptr}; 77 78 // IPv6 peer address 79 folly::SocketAddress v6PeerAddress; 80 81 // IPv4 peer address 82 folly::SocketAddress v4PeerAddress; 83 84 // The address that this socket will try to connect to after connection 85 // attempt delay timeout fires 86 folly::SocketAddress secondPeerAddress; 87 88 // The UDP socket that will be used for the second connection attempt 89 std::unique_ptr<folly::AsyncUDPSocket> secondSocket; 90 91 // Whether should write to the first UDP socket 92 bool shouldWriteToFirstSocket{true}; 93 94 // Whether should write to the second UDP socket 95 bool shouldWriteToSecondSocket{false}; 96 97 // Whether HappyEyeballs has finished 98 // The signal of finishing is first successful decryption of a packet 99 bool finished{false}; 100 }; 101 102 HappyEyeballsState happyEyeballsState; 103 104 // Short header packets we received but couldn't yet decrypt. 105 std::vector<PendingClientData> pendingOneRttData; 106 // Handshake packets we received but couldn't yet decrypt. 107 std::vector<PendingClientData> pendingHandshakeData; 108 QuicClientConnectionStateQuicClientConnectionState109 explicit QuicClientConnectionState( 110 std::shared_ptr<ClientHandshakeFactory> handshakeFactoryIn) 111 : QuicConnectionStateBase(QuicNodeType::Client), 112 handshakeFactory(std::move(handshakeFactoryIn)) { 113 cryptoState = std::make_unique<QuicCryptoState>(); 114 congestionController = std::make_unique<Cubic>(*this); 115 connectionTime = Clock::now(); 116 originalVersion = QuicVersion::MVFST; 117 DCHECK(handshakeFactory); 118 auto tmpClientHandshake = 119 std::move(*handshakeFactory).makeClientHandshake(this); 120 clientHandshakeLayer = tmpClientHandshake.get(); 121 handshakeLayer = std::move(tmpClientHandshake); 122 // We shouldn't normally need to set this until we're starting the 123 // transport, however writing unit tests is much easier if we set this here. 124 updateFlowControlStateWithSettings(flowControlState, transportSettings); 125 streamManager = std::make_unique<QuicStreamManager>( 126 *this, this->nodeType, transportSettings); 127 transportSettings.selfActiveConnectionIdLimit = 128 kDefaultActiveConnectionIdLimit; 129 } 130 }; 131 132 /** 133 * Undos the clients state to be the original state of the client. 134 */ 135 std::unique_ptr<QuicClientConnectionState> undoAllClientStateForRetry( 136 std::unique_ptr<QuicClientConnectionState> conn); 137 138 void processServerInitialParams( 139 QuicClientConnectionState& conn, 140 ServerTransportParameters serverParams, 141 PacketNum packetNum); 142 143 void cacheServerInitialParams( 144 QuicClientConnectionState& conn, 145 uint64_t peerAdvertisedInitialMaxData, 146 uint64_t peerAdvertisedInitialMaxStreamDataBidiLocal, 147 uint64_t peerAdvertisedInitialMaxStreamDataBidiRemote, 148 uint64_t peerAdvertisedInitialMaxStreamDataUni, 149 uint64_t peerAdvertisedInitialMaxStreamsBidi, 150 uint64_t peerAdvertisedInitialMaxStreamUni); 151 152 CachedServerTransportParameters getServerCachedTransportParameters( 153 const QuicClientConnectionState& conn); 154 155 void updateTransportParamsFromCachedEarlyParams( 156 QuicClientConnectionState& conn, 157 const CachedServerTransportParameters& transportParams); 158 159 } // namespace quic 160