1
0
mirror of https://github.com/facebookincubator/mvfst.git synced 2025-08-08 09:42:06 +03:00

Move the delayed destruction from Handshake to QuicConnectionStateBase

Summary: Pull Request resolved: https://github.com/facebookincubator/mvfst/pull/88

Test Plan:
Imported from GitHub, without a `Test Plan:` line.

 ---
## Proxygen Canary
Traffic Canary: https://our.intern.facebook.com/intern/traffic/canary?fbid=224323975233396
* elb.prod.ham3c01 - binary_asan - 2020-02-05 02:00 - https://fburl.com/dyndash/u2q12hwq
* elb.prod.mia3c02 - binary - 2020-01-31 09:40 - https://fburl.com/dyndash/vmv34rpa
* elb.prod.otp1c01 - binary - 2020-02-05 02:26 - https://fburl.com/dyndash/0zttm61b
* flb.prod.fath4c02 - binary - 2020-02-05 02:26 - https://fburl.com/dyndash/6o1nqsti
* flb.prod.fgye3c01 - binary - 2020-01-31 09:40 - https://fburl.com/dyndash/nu3i5ahw
* olb.prod.rfrc0c01.p2 - binary - 2020-01-31 09:40 - https://fburl.com/dyndash/c1o6hpqw
* olb.prod.rftw0c01.p2 - binary - 2020-02-05 02:26 - https://fburl.com/dyndash/xg6qbyru
* slb.prod_regional.rcln0c00 - binary - 2020-02-05 02:26 - https://fburl.com/dyndash/e4qkbzcz
* slb.prod_regional.rfrc0c00 - binary - 2020-01-31 09:40 - https://fburl.com/dyndash/j0yxofty
* slb.prod_regional.rrva0c00 - binary_asan - 2020-02-05 02:00 - https://fburl.com/dyndash/4hsg02uj
* slb.regional.rfrc0c01.p2 - binary - 2020-01-31 09:40 - https://fburl.com/dyndash/1njxzbgf
* slb.regional.rvll0c01.p2 - binary - 2020-02-05 02:26 - https://fburl.com/dyndash/056xdmzn
 ---

Reviewed By: lnicco

Differential Revision: D19551142

Pulled By: mjoras

fbshipit-source-id: b0d14146d14384b8c37887b3e9d8fed7d6181d88
This commit is contained in:
Amaury Séchet
2020-02-05 06:11:31 -08:00
committed by Facebook Github Bot
parent 60fc1c7a90
commit e6e6196c86
14 changed files with 62 additions and 49 deletions

View File

@@ -8,9 +8,6 @@
#pragma once #pragma once
#include <folly/ExceptionWrapper.h>
#include <folly/io/async/AsyncUDPSocket.h>
#include <folly/io/async/HHWheelTimer.h>
#include <quic/QuicConstants.h> #include <quic/QuicConstants.h>
#include <quic/QuicException.h> #include <quic/QuicException.h>
#include <quic/api/QuicSocket.h> #include <quic/api/QuicSocket.h>
@@ -22,6 +19,10 @@
#include <quic/congestion_control/QuicCubic.h> #include <quic/congestion_control/QuicCubic.h>
#include <quic/state/StateData.h> #include <quic/state/StateData.h>
#include <folly/ExceptionWrapper.h>
#include <folly/io/async/AsyncUDPSocket.h>
#include <folly/io/async/HHWheelTimer.h>
namespace quic { namespace quic {
enum class CloseState { OPEN, GRACEFUL_CLOSING, CLOSED }; enum class CloseState { OPEN, GRACEFUL_CLOSING, CLOSED };
@@ -561,7 +562,9 @@ class QuicTransportBase : public QuicSocket {
std::unique_ptr<folly::AsyncUDPSocket> socket_; std::unique_ptr<folly::AsyncUDPSocket> socket_;
ConnectionCallback* connCallback_{nullptr}; ConnectionCallback* connCallback_{nullptr};
std::unique_ptr<QuicConnectionStateBase> conn_; std::
unique_ptr<QuicConnectionStateBase, folly::DelayedDestruction::Destructor>
conn_;
struct ReadCallbackData { struct ReadCallbackData {
ReadCallback* readCb; ReadCallback* readCb;

View File

@@ -136,7 +136,7 @@ class TestQuicTransport
conn->clientConnectionId = ConnectionId({10, 9, 8, 7}); conn->clientConnectionId = ConnectionId({10, 9, 8, 7});
conn->version = QuicVersion::MVFST; conn->version = QuicVersion::MVFST;
transportConn = conn.get(); transportConn = conn.get();
conn_ = std::move(conn); conn_.reset(conn.release());
aead = test::createNoOpAead(); aead = test::createNoOpAead();
headerCipher = test::createNoOpHeaderCipher(); headerCipher = test::createNoOpHeaderCipher();
connIdAlgo_ = std::make_unique<DefaultConnectionIdAlgo>(); connIdAlgo_ = std::make_unique<DefaultConnectionIdAlgo>();

View File

@@ -42,7 +42,7 @@ class TestQuicTransport
ConnectionCallback& cb) ConnectionCallback& cb)
: QuicTransportBase(evb, std::move(socket)) { : QuicTransportBase(evb, std::move(socket)) {
setConnectionCallback(&cb); setConnectionCallback(&cb);
conn_ = std::make_unique<QuicServerConnectionState>(); conn_.reset(new QuicServerConnectionState());
conn_->clientConnectionId = ConnectionId({9, 8, 7, 6}); conn_->clientConnectionId = ConnectionId({9, 8, 7, 6});
conn_->serverConnectionId = ConnectionId({1, 2, 3, 4}); conn_->serverConnectionId = ConnectionId({1, 2, 3, 4});
conn_->version = QuicVersion::MVFST; conn_->version = QuicVersion::MVFST;

View File

@@ -54,7 +54,7 @@ QuicClientTransport::QuicClientTransport(
auto tempConn = auto tempConn =
std::make_unique<QuicClientConnectionState>(std::move(handshakeFactory)); std::make_unique<QuicClientConnectionState>(std::move(handshakeFactory));
clientConn_ = tempConn.get(); clientConn_ = tempConn.get();
conn_ = std::move(tempConn); conn_.reset(tempConn.release());
std::vector<uint8_t> connIdData( std::vector<uint8_t> connIdData(
std::max(kMinInitialDestinationConnIdLength, connectionIdSize)); std::max(kMinInitialDestinationConnIdLength, connectionIdSize));
folly::Random::secureRandom(connIdData.data(), connIdData.size()); folly::Random::secureRandom(connIdData.data(), connIdData.size());
@@ -208,7 +208,7 @@ void QuicClientTransport::processPacketData(
auto tempConn = undoAllClientStateForRetry(std::move(uniqueClient)); auto tempConn = undoAllClientStateForRetry(std::move(uniqueClient));
clientConn_ = tempConn.get(); clientConn_ = tempConn.get();
conn_ = std::move(tempConn); conn_.reset(tempConn.release());
clientConn_->retryToken = longHeader->getToken(); clientConn_->retryToken = longHeader->getToken();

View File

@@ -60,7 +60,7 @@ struct QuicClientConnectionState : public QuicConnectionStateBase {
auto tmpClientHandshake = auto tmpClientHandshake =
handshakeFactory->makeClientHandshake(*cryptoState); handshakeFactory->makeClientHandshake(*cryptoState);
clientHandshakeLayer = tmpClientHandshake.get(); clientHandshakeLayer = tmpClientHandshake.get();
handshakeLayer.reset(tmpClientHandshake.release()); handshakeLayer = std::move(tmpClientHandshake);
// We shouldn't normally need to set this until we're starting the // 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. // transport, however writing unit tests is much easier if we set this here.
updateFlowControlStateWithSettings(flowControlState, transportSettings); updateFlowControlStateWithSettings(flowControlState, transportSettings);

View File

@@ -1354,8 +1354,6 @@ class QuicClientTransportTest : public Test {
new FakeOneRttHandshakeLayer(*client->getNonConstConn().cryptoState); new FakeOneRttHandshakeLayer(*client->getNonConstConn().cryptoState);
client->getNonConstConn().clientHandshakeLayer = mockClientHandshake; client->getNonConstConn().clientHandshakeLayer = mockClientHandshake;
client->getNonConstConn().handshakeLayer.reset(mockClientHandshake); client->getNonConstConn().handshakeLayer.reset(mockClientHandshake);
handshakeDG = std::make_unique<DelayedDestruction::DestructorGuard>(
mockClientHandshake);
setFakeHandshakeCiphers(); setFakeHandshakeCiphers();
// Allow ignoring path mtu for testing negotiation. // Allow ignoring path mtu for testing negotiation.
client->getNonConstConn().transportSettings.canIgnorePathMTU = true; client->getNonConstConn().transportSettings.canIgnorePathMTU = true;
@@ -1690,7 +1688,6 @@ class QuicClientTransportTest : public Test {
std::unique_ptr<folly::EventBase> eventbase_; std::unique_ptr<folly::EventBase> eventbase_;
SocketAddress serverAddr{"127.0.0.1", 443}; SocketAddress serverAddr{"127.0.0.1", 443};
AsyncUDPSocket::ReadCallback* networkReadCallback{nullptr}; AsyncUDPSocket::ReadCallback* networkReadCallback{nullptr};
std::unique_ptr<DelayedDestruction::DestructorGuard> handshakeDG;
FakeOneRttHandshakeLayer* mockClientHandshake; FakeOneRttHandshakeLayer* mockClientHandshake;
std::shared_ptr<TestingQuicClientTransport> client; std::shared_ptr<TestingQuicClientTransport> client;
PacketNum initialPacketNum{0}, handshakePacketNum{0}, appDataPacketNum{0}; PacketNum initialPacketNum{0}, handshakePacketNum{0}, appDataPacketNum{0};

View File

@@ -8,8 +8,6 @@
#pragma once #pragma once
#include <folly/io/async/DelayedDestruction.h>
#include <quic/QuicConstants.h> #include <quic/QuicConstants.h>
#include <quic/codec/PacketNumberCipher.h> #include <quic/codec/PacketNumberCipher.h>
#include <quic/codec/Types.h> #include <quic/codec/Types.h>
@@ -20,13 +18,12 @@ constexpr folly::StringPiece kQuicKeyLabel = "quic key";
constexpr folly::StringPiece kQuicIVLabel = "quic iv"; constexpr folly::StringPiece kQuicIVLabel = "quic iv";
constexpr folly::StringPiece kQuicPNLabel = "quic hp"; constexpr folly::StringPiece kQuicPNLabel = "quic hp";
class Handshake : public folly::DelayedDestruction { class Handshake {
public: public:
virtual ~Handshake() = default;
virtual const folly::Optional<std::string>& getApplicationProtocol() virtual const folly::Optional<std::string>& getApplicationProtocol()
const = 0; const = 0;
protected:
virtual ~Handshake() = default;
}; };
constexpr folly::StringPiece kQuicDraft17Salt = constexpr folly::StringPiece kQuicDraft17Salt =

View File

@@ -24,7 +24,7 @@ QuicServerTransport::QuicServerTransport(
auto tempConn = std::make_unique<QuicServerConnectionState>(); auto tempConn = std::make_unique<QuicServerConnectionState>();
tempConn->serverAddr = socket_->address(); tempConn->serverAddr = socket_->address();
serverConn_ = tempConn.get(); serverConn_ = tempConn.get();
conn_ = std::move(tempConn); conn_.reset(tempConn.release());
// TODO: generate this when we can encode the packet sequence number // TODO: generate this when we can encode the packet sequence number
// correctly. // correctly.
// conn_->nextSequenceNum = folly::Random::secureRandom<PacketNum>(); // conn_->nextSequenceNum = folly::Random::secureRandom<PacketNum>();

View File

@@ -8,14 +8,20 @@
#include <quic/server/handshake/ServerHandshake.h> #include <quic/server/handshake/ServerHandshake.h>
#include <fizz/protocol/Protocol.h>
#include <quic/fizz/handshake/FizzBridge.h> #include <quic/fizz/handshake/FizzBridge.h>
#include <quic/fizz/handshake/FizzCryptoFactory.h> #include <quic/fizz/handshake/FizzCryptoFactory.h>
#include <quic/state/QuicStreamFunctions.h> #include <quic/state/QuicStreamFunctions.h>
#include <fizz/protocol/Protocol.h>
namespace quic { namespace quic {
ServerHandshake::ServerHandshake(QuicCryptoState& cryptoState) ServerHandshake::ServerHandshake(
: actionGuard_(nullptr), cryptoState_(cryptoState), visitor_(*this) {} QuicConnectionStateBase* conn,
QuicCryptoState& cryptoState)
: conn_(conn),
actionGuard_(nullptr),
cryptoState_(cryptoState),
visitor_(*this) {}
void ServerHandshake::accept( void ServerHandshake::accept(
std::shared_ptr<ServerTransportParametersExtension> transportParams) { std::shared_ptr<ServerTransportParametersExtension> transportParams) {
@@ -238,7 +244,7 @@ void ServerHandshake::addProcessingActions(fizz::server::AsyncActions actions) {
"Processing action while pending", TransportErrorCode::INTERNAL_ERROR)); "Processing action while pending", TransportErrorCode::INTERNAL_ERROR));
return; return;
} }
actionGuard_ = folly::DelayedDestruction::DestructorGuard(this); actionGuard_ = folly::DelayedDestruction::DestructorGuard(conn_);
startActions(std::move(actions)); startActions(std::move(actions));
} }
@@ -257,7 +263,7 @@ void ServerHandshake::processActions(
fizz::server::ServerStateMachine::CompletedActions actions) { fizz::server::ServerStateMachine::CompletedActions actions) {
// This extra DestructorGuard is needed due to the gap between clearing // This extra DestructorGuard is needed due to the gap between clearing
// actionGuard_ and potentially processing another action. // actionGuard_ and potentially processing another action.
folly::DelayedDestruction::DestructorGuard dg(this); folly::DelayedDestruction::DestructorGuard dg(conn_);
for (auto& action : actions) { for (auto& action : actions) {
switch (action.type()) { switch (action.type()) {
@@ -307,7 +313,7 @@ void ServerHandshake::processPendingEvents() {
return; return;
} }
folly::DelayedDestruction::DestructorGuard dg(this); folly::DelayedDestruction::DestructorGuard dg(conn_);
inProcessPendingEvents_ = true; inProcessPendingEvents_ = true;
SCOPE_EXIT { SCOPE_EXIT {
inProcessPendingEvents_ = false; inProcessPendingEvents_ = false;
@@ -316,7 +322,7 @@ void ServerHandshake::processPendingEvents() {
while (!actionGuard_ && !error_) { while (!actionGuard_ && !error_) {
folly::Optional<fizz::server::ServerStateMachine::ProcessingActions> folly::Optional<fizz::server::ServerStateMachine::ProcessingActions>
actions; actions;
actionGuard_ = folly::DelayedDestruction::DestructorGuard(this); actionGuard_ = folly::DelayedDestruction::DestructorGuard(conn_);
if (!waitForData_) { if (!waitForData_) {
switch (state_.readRecordLayer()->getEncryptionLevel()) { switch (state_.readRecordLayer()->getEncryptionLevel()) {
case fizz::EncryptionLevel::Plaintext: case fizz::EncryptionLevel::Plaintext:

View File

@@ -26,6 +26,8 @@
namespace quic { namespace quic {
// struct QuicConnectionStateBase;
/** /**
* ServerHandshake abstracts details of the TLS 1.3 fizz crypto handshake. The * ServerHandshake abstracts details of the TLS 1.3 fizz crypto handshake. The
* TLS handshake can be async, so ServerHandshake provides an API to deal with * TLS handshake can be async, so ServerHandshake provides an API to deal with
@@ -69,7 +71,9 @@ class ServerHandshake : public Handshake {
*/ */
enum class Phase { Handshake, KeysDerived, Established }; enum class Phase { Handshake, KeysDerived, Established };
explicit ServerHandshake(QuicCryptoState& cryptoState); explicit ServerHandshake(
QuicConnectionStateBase* conn,
QuicCryptoState& cryptoState);
/** /**
* Starts accepting the TLS connection. * Starts accepting the TLS connection.
@@ -247,6 +251,7 @@ class ServerHandshake : public Handshake {
fizz::server::State state_; fizz::server::State state_;
fizz::server::ServerStateMachine machine_; fizz::server::ServerStateMachine machine_;
QuicConnectionStateBase* conn_;
folly::DelayedDestruction::DestructorGuard actionGuard_; folly::DelayedDestruction::DestructorGuard actionGuard_;
folly::Executor* executor_; folly::Executor* executor_;
std::shared_ptr<const fizz::server::FizzServerContext> context_; std::shared_ptr<const fizz::server::FizzServerContext> context_;

View File

@@ -48,10 +48,8 @@ class MockServerHandshakeCallback : public ServerHandshake::HandshakeCallback {
GMOCK_METHOD0_(, noexcept, , onCryptoEventAvailable, void()); GMOCK_METHOD0_(, noexcept, , onCryptoEventAvailable, void());
}; };
class TestingServerHandshake : public ServerHandshake { struct TestingServerConnectionState : public QuicServerConnectionState {
public: explicit TestingServerConnectionState() : QuicServerConnectionState() {}
explicit TestingServerHandshake(QuicCryptoState& cryptoState)
: ServerHandshake(cryptoState) {}
uint32_t getDestructorGuardCount() const { uint32_t getDestructorGuardCount() const {
return folly::DelayedDestruction::getDestructorGuardCount(); return folly::DelayedDestruction::getDestructorGuardCount();
@@ -74,14 +72,15 @@ class ServerHandshakeTest : public Test {
void SetUp() override { void SetUp() override {
folly::ssl::init(); folly::ssl::init();
cryptoState = std::make_unique<QuicCryptoState>(); conn.reset(new TestingServerConnectionState());
cryptoState = conn->cryptoState.get();
clientCtx = std::make_shared<fizz::client::FizzClientContext>(); clientCtx = std::make_shared<fizz::client::FizzClientContext>();
clientCtx->setOmitEarlyRecordLayer(true); clientCtx->setOmitEarlyRecordLayer(true);
clientCtx->setFactory(std::make_shared<QuicFizzFactory>()); clientCtx->setFactory(std::make_shared<QuicFizzFactory>());
clientCtx->setClock(std::make_shared<fizz::test::MockClock>()); clientCtx->setClock(std::make_shared<fizz::test::MockClock>());
serverCtx = quic::test::createServerCtx(); serverCtx = quic::test::createServerCtx();
setupClientAndServerContext(); setupClientAndServerContext();
handshake.reset(new TestingServerHandshake(*cryptoState)); handshake = conn->serverHandshakeLayer;
hostname = kTestHostname.str(); hostname = kTestHostname.str();
verifier = std::make_shared<fizz::test::MockCertificateVerifier>(); verifier = std::make_shared<fizz::test::MockCertificateVerifier>();
@@ -320,8 +319,12 @@ class ServerHandshakeTest : public Test {
std::unique_ptr<DelayedHolder, folly::DelayedDestruction::Destructor> dg; std::unique_ptr<DelayedHolder, folly::DelayedDestruction::Destructor> dg;
folly::EventBase evb; folly::EventBase evb;
std::unique_ptr<TestingServerHandshake> handshake; std::unique_ptr<
std::unique_ptr<QuicCryptoState> cryptoState; TestingServerConnectionState,
folly::DelayedDestruction::Destructor>
conn{nullptr};
ServerHandshake* handshake;
QuicCryptoState* cryptoState;
fizz::client::State clientState; fizz::client::State clientState;
std::unique_ptr<fizz::client::FizzClient< std::unique_ptr<fizz::client::FizzClient<
@@ -612,7 +615,7 @@ TEST_F(ServerHandshakeHRRTest, TestAsyncCancel) {
handshake->cancel(); handshake->cancel();
// Let's destroy the crypto state to make sure it is not referenced. // Let's destroy the crypto state to make sure it is not referenced.
cryptoState.reset(); conn->cryptoState.reset();
promise.setValue(); promise.setValue();
evb.loop(); evb.loop();
@@ -641,12 +644,12 @@ TEST_F(ServerHandshakeAsyncTest, TestAsyncCancel) {
handshake->cancel(); handshake->cancel();
// Let's destroy the crypto state to make sure it is not referenced. // Let's destroy the crypto state to make sure it is not referenced.
cryptoState.reset(); conn->cryptoState.reset();
promise.setValue(); promise.setValue();
evb.loop(); evb.loop();
EXPECT_EQ(handshake->getDestructorGuardCount(), 0); EXPECT_EQ(conn->getDestructorGuardCount(), 0);
} }
class ServerHandshakeAsyncErrorTest : public ServerHandshakePskTest { class ServerHandshakeAsyncErrorTest : public ServerHandshakePskTest {
@@ -685,7 +688,7 @@ TEST_F(ServerHandshakeAsyncErrorTest, TestCancelOnAsyncError) {
.WillRepeatedly(Invoke([&] { .WillRepeatedly(Invoke([&] {
handshake->cancel(); handshake->cancel();
// Let's destroy the crypto state to make sure it is not referenced. // Let's destroy the crypto state to make sure it is not referenced.
cryptoState.reset(); conn->cryptoState.reset();
})); }));
promise.setValue(); promise.setValue();
evb.loop(); evb.loop();
@@ -696,7 +699,7 @@ TEST_F(ServerHandshakeAsyncErrorTest, TestCancelWhileWaitingAsyncError) {
clientServerRound(); clientServerRound();
handshake->cancel(); handshake->cancel();
// Let's destroy the crypto state to make sure it is not referenced. // Let's destroy the crypto state to make sure it is not referenced.
cryptoState.reset(); conn->cryptoState.reset();
promise.setValue(); promise.setValue();
evb.loop(); evb.loop();

View File

@@ -133,7 +133,7 @@ struct QuicServerConnectionState : public QuicConnectionStateBase {
QuicVersion::QUIC_DRAFT, QuicVersion::QUIC_DRAFT,
QuicVersion::QUIC_DRAFT_23}}; QuicVersion::QUIC_DRAFT_23}};
originalVersion = QuicVersion::MVFST; originalVersion = QuicVersion::MVFST;
serverHandshakeLayer = new ServerHandshake(*cryptoState); serverHandshakeLayer = new ServerHandshake(this, *cryptoState);
handshakeLayer.reset(serverHandshakeLayer); handshakeLayer.reset(serverHandshakeLayer);
// We shouldn't normally need to set this until we're starting the // 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. // transport, however writing unit tests is much easier if we set this here.

View File

@@ -44,7 +44,7 @@ class FakeServerHandshake : public ServerHandshake {
bool chloSync = false, bool chloSync = false,
bool cfinSync = false, bool cfinSync = false,
folly::Optional<uint64_t> clientActiveConnectionIdLimit = folly::none) folly::Optional<uint64_t> clientActiveConnectionIdLimit = folly::none)
: ServerHandshake(*conn.cryptoState), : ServerHandshake(&conn, *conn.cryptoState),
conn_(conn), conn_(conn),
chloSync_(chloSync), chloSync_(chloSync),
cfinSync_(cfinSync), cfinSync_(cfinSync),

View File

@@ -8,10 +8,6 @@
#pragma once #pragma once
#include <folly/Optional.h>
#include <folly/io/IOBuf.h>
#include <folly/io/async/AsyncUDPSocket.h>
#include <folly/io/async/HHWheelTimer.h>
#include <quic/QuicConstants.h> #include <quic/QuicConstants.h>
#include <quic/codec/ConnectionIdAlgo.h> #include <quic/codec/ConnectionIdAlgo.h>
#include <quic/codec/QuicReadCodec.h> #include <quic/codec/QuicReadCodec.h>
@@ -25,6 +21,13 @@
#include <quic/state/QuicTransportStatsCallback.h> #include <quic/state/QuicTransportStatsCallback.h>
#include <quic/state/StreamData.h> #include <quic/state/StreamData.h>
#include <quic/state/TransportSettings.h> #include <quic/state/TransportSettings.h>
#include <folly/Optional.h>
#include <folly/io/IOBuf.h>
#include <folly/io/async/AsyncUDPSocket.h>
#include <folly/io/async/DelayedDestruction.h>
#include <folly/io/async/HHWheelTimer.h>
#include <chrono> #include <chrono>
#include <list> #include <list>
#include <numeric> #include <numeric>
@@ -489,7 +492,7 @@ class CongestionControllerFactory;
class LoopDetectorCallback; class LoopDetectorCallback;
class PendingPathRateLimiter; class PendingPathRateLimiter;
struct QuicConnectionStateBase { struct QuicConnectionStateBase : public folly::DelayedDestruction {
virtual ~QuicConnectionStateBase() = default; virtual ~QuicConnectionStateBase() = default;
explicit QuicConnectionStateBase(QuicNodeType type) : nodeType(type) {} explicit QuicConnectionStateBase(QuicNodeType type) : nodeType(type) {}
@@ -497,8 +500,7 @@ struct QuicConnectionStateBase {
// Type of node owning this connection (client or server). // Type of node owning this connection (client or server).
QuicNodeType nodeType; QuicNodeType nodeType;
std::unique_ptr<Handshake, folly::DelayedDestruction::Destructor> std::unique_ptr<Handshake> handshakeLayer;
handshakeLayer;
// Crypto stream // Crypto stream
std::unique_ptr<QuicCryptoState> cryptoState; std::unique_ptr<QuicCryptoState> cryptoState;