diff --git a/quic/api/QuicSocket.h b/quic/api/QuicSocket.h index 751512e17..036ba35dd 100644 --- a/quic/api/QuicSocket.h +++ b/quic/api/QuicSocket.h @@ -196,10 +196,10 @@ class QuicSocket { std::chrono::microseconds srtt{0us}; std::chrono::microseconds rttvar{0us}; std::chrono::microseconds lrtt{0us}; - Optional maybeLrtt; - Optional maybeLrttAckDelay; - Optional maybeMinRtt; - Optional maybeMinRttNoAckDelay; + OptionalMicros maybeLrtt; + OptionalMicros maybeLrttAckDelay; + OptionalMicros maybeMinRtt; + OptionalMicros maybeMinRttNoAckDelay; uint64_t mss{kDefaultUDPSendPacketLen}; CongestionControlType congestionControlType{CongestionControlType::None}; uint64_t writableBytes{0}; diff --git a/quic/api/QuicTransportBase.cpp b/quic/api/QuicTransportBase.cpp index f7c50cdf6..7269d0428 100644 --- a/quic/api/QuicTransportBase.cpp +++ b/quic/api/QuicTransportBase.cpp @@ -1995,7 +1995,7 @@ uint64_t QuicTransportBase::getNumOpenableUnidirectionalStreams() const { folly::Expected QuicTransportBase::createStreamInternal( bool bidirectional, - const Optional& streamGroupId) { + const OptionalIntegral& streamGroupId) { if (closeState_ != CloseState::OPEN) { return folly::makeUnexpected(LocalErrorCode::CONNECTION_CLOSED); } diff --git a/quic/api/QuicTransportBase.h b/quic/api/QuicTransportBase.h index 077145624..800b3bc6c 100644 --- a/quic/api/QuicTransportBase.h +++ b/quic/api/QuicTransportBase.h @@ -763,7 +763,7 @@ class QuicTransportBase : public QuicSocket, PeekCallback* cb) noexcept; folly::Expected createStreamInternal( bool bidirectional, - const Optional& streamGroupId = none); + const OptionalIntegral& streamGroupId = std::nullopt); /** * write data to socket diff --git a/quic/api/QuicTransportFunctions.cpp b/quic/api/QuicTransportFunctions.cpp index b085b837a..37aaaf34f 100644 --- a/quic/api/QuicTransportFunctions.cpp +++ b/quic/api/QuicTransportFunctions.cpp @@ -1470,7 +1470,7 @@ WriteQuicDataResult writeConnectionDataToSocket( << " writing data using scheduler=" << scheduler.name() << " " << connection; - if (!connection.gsoSupported.hasValue()) { + if (!connection.gsoSupported.has_value()) { connection.gsoSupported = sock.getGSO() >= 0; if (!*connection.gsoSupported) { if (!useSinglePacketInplaceBatchWriter( @@ -1988,7 +1988,7 @@ void maybeInitiateKeyUpdate(QuicConnectionStateBase& conn) { conn.readCodec->canInitiateKeyUpdate()) { QUIC_STATS(conn.statsCallback, onKeyUpdateAttemptInitiated); conn.readCodec->advanceOneRttReadPhase(); - conn.transportSettings.firstKeyUpdatePacketCount.clear(); + conn.transportSettings.firstKeyUpdatePacketCount.reset(); updateOneRttWriteCipher( conn, @@ -1998,7 +1998,7 @@ void maybeInitiateKeyUpdate(QuicConnectionStateBase& conn) { conn.handshakeLayer->getNextOneRttReadCipher()); // Signal the transport that a key update has been initiated. conn.oneRttWritePendingVerification = true; - conn.oneRttWritePendingVerificationPacketNumber.clear(); + conn.oneRttWritePendingVerificationPacketNumber.reset(); } } } @@ -2021,7 +2021,7 @@ void maybeVerifyPendingKeyUpdate( // the current phase. if (ackPacket.header.getProtectionType() == conn.oneRttWritePhase) { // Key update is verified. - conn.oneRttWritePendingVerificationPacketNumber.clear(); + conn.oneRttWritePendingVerificationPacketNumber.reset(); conn.oneRttWritePendingVerification = false; } else { throw QuicTransportException( diff --git a/quic/api/test/QuicTransportBaseTest.cpp b/quic/api/test/QuicTransportBaseTest.cpp index 92dab361b..b900f70c4 100644 --- a/quic/api/test/QuicTransportBaseTest.cpp +++ b/quic/api/test/QuicTransportBaseTest.cpp @@ -52,7 +52,7 @@ enum class TestFrameType : uint8_t { Buf encodeStreamBuffer( StreamId id, StreamBuffer data, - Optional groupId = none) { + OptionalIntegral groupId = std::nullopt) { auto buf = IOBuf::create(10); folly::io::Appender appender(buf.get(), 10); if (!groupId) { @@ -406,7 +406,7 @@ class TestQuicTransport void addDataToStream( StreamId id, StreamBuffer data, - Optional groupId = none) { + OptionalIntegral groupId = std::nullopt) { auto buf = encodeStreamBuffer(id, std::move(data), std::move(groupId)); SocketAddress addr("127.0.0.1", 1000); onNetworkData(addr, NetworkData(std::move(buf), Clock::now(), 0)); diff --git a/quic/api/test/QuicTransportFunctionsTest.cpp b/quic/api/test/QuicTransportFunctionsTest.cpp index cd0081d0c..e2dc6c3bb 100644 --- a/quic/api/test/QuicTransportFunctionsTest.cpp +++ b/quic/api/test/QuicTransportFunctionsTest.cpp @@ -1750,7 +1750,7 @@ TEST_F(QuicTransportFunctionsTest, StreamDetailsSingleStream) { testing::Field(&PacketStreamDetails::newStreamBytesSent, frameLen), testing::Field( &PacketStreamDetails::maybeFirstNewStreamByteOffset, - Optional(frameOffset)), + OptionalIntegral(frameOffset)), testing::Field( &PacketStreamDetails::streamIntervals, testing::ElementsAre(Interval( @@ -1792,7 +1792,7 @@ TEST_F(QuicTransportFunctionsTest, StreamDetailsSingleStreamMultipleFrames) { testing::Field(&PacketStreamDetails::newStreamBytesSent, 15), testing::Field( &PacketStreamDetails::maybeFirstNewStreamByteOffset, - Optional(0)), + OptionalIntegral(0)), testing::Field( &PacketStreamDetails::streamIntervals, testing::ElementsAre(Interval(0, 14))))); @@ -1836,7 +1836,7 @@ TEST_F(QuicTransportFunctionsTest, StreamDetailsSingleStreamRetransmit) { testing::Field(&PacketStreamDetails::newStreamBytesSent, frame1Len), testing::Field( &PacketStreamDetails::maybeFirstNewStreamByteOffset, - Optional(frame1Offset)), + OptionalIntegral(frame1Offset)), testing::Field( &PacketStreamDetails::streamIntervals, testing::ElementsAre(Interval( @@ -1873,7 +1873,7 @@ TEST_F(QuicTransportFunctionsTest, StreamDetailsSingleStreamRetransmit) { testing::Field(&PacketStreamDetails::newStreamBytesSent, 0), testing::Field( &PacketStreamDetails::maybeFirstNewStreamByteOffset, - Optional(/* empty */)), + OptionalIntegral(/* empty */)), testing::Field( &PacketStreamDetails::streamIntervals, testing::ElementsAre(Interval( @@ -1917,7 +1917,7 @@ TEST_F(QuicTransportFunctionsTest, StreamDetailsSingleStreamRetransmit) { testing::Field(&PacketStreamDetails::newStreamBytesSent, frame2Len), testing::Field( &PacketStreamDetails::maybeFirstNewStreamByteOffset, - Optional(frame2Offset)), + OptionalIntegral(frame2Offset)), testing::Field( &PacketStreamDetails::streamIntervals, testing::ElementsAre(Interval( @@ -1956,7 +1956,7 @@ TEST_F(QuicTransportFunctionsTest, StreamDetailsSingleStreamRetransmit) { testing::Field(&PacketStreamDetails::newStreamBytesSent, 0), testing::Field( &PacketStreamDetails::maybeFirstNewStreamByteOffset, - Optional(/* empty */)), + OptionalIntegral(/* empty */)), testing::Field( &PacketStreamDetails::streamIntervals, testing::ElementsAre(Interval( @@ -2019,7 +2019,7 @@ TEST_F(QuicTransportFunctionsTest, StreamDetailsSingleStreamFinWithRetransmit) { &PacketStreamDetails::newStreamBytesSent, frameLen), testing::Field( &PacketStreamDetails::maybeFirstNewStreamByteOffset, - Optional(frameOffset)), + OptionalIntegral(frameOffset)), testing::Field( &PacketStreamDetails::streamIntervals, testing::ElementsAre(Interval( @@ -2069,7 +2069,7 @@ TEST_F(QuicTransportFunctionsTest, StreamDetailsSingleStreamFinWithRetransmit) { testing::Field(&PacketStreamDetails::newStreamBytesSent, 0), testing::Field( &PacketStreamDetails::maybeFirstNewStreamByteOffset, - Optional(/* empty */)), + OptionalIntegral(/* empty */)), testing::Field( &PacketStreamDetails::streamIntervals, // contains frame1 and frame2 @@ -2151,7 +2151,7 @@ TEST_F( &PacketStreamDetails::newStreamBytesSent, frameLen), testing::Field( &PacketStreamDetails::maybeFirstNewStreamByteOffset, - Optional(frameOffset)), + OptionalIntegral(frameOffset)), testing::Field( &PacketStreamDetails::streamIntervals, testing::ElementsAre(Interval( @@ -2208,7 +2208,7 @@ TEST_F( testing::Field(&PacketStreamDetails::newStreamBytesSent, 0), testing::Field( &PacketStreamDetails::maybeFirstNewStreamByteOffset, - Optional(/* empty */)), + OptionalIntegral(/* empty */)), testing::Field( &PacketStreamDetails::streamIntervals, // contains frame1 and frame 3 @@ -2295,7 +2295,7 @@ TEST_F( &PacketStreamDetails::newStreamBytesSent, frameLen), testing::Field( &PacketStreamDetails::maybeFirstNewStreamByteOffset, - Optional(frameOffset)), + OptionalIntegral(frameOffset)), testing::Field( &PacketStreamDetails::streamIntervals, testing::ElementsAre(Interval( @@ -2352,7 +2352,7 @@ TEST_F( testing::Field(&PacketStreamDetails::newStreamBytesSent, 0), testing::Field( &PacketStreamDetails::maybeFirstNewStreamByteOffset, - Optional(/* empty */)), + OptionalIntegral(/* empty */)), testing::Field( &PacketStreamDetails::streamIntervals, // contains frame1 and frame 3 @@ -2429,7 +2429,7 @@ TEST_F(QuicTransportFunctionsTest, StreamDetailsMultipleStreams) { &PacketStreamDetails::newStreamBytesSent, stream1Len), testing::Field( &PacketStreamDetails::maybeFirstNewStreamByteOffset, - Optional(stream1Offset)), + OptionalIntegral(stream1Offset)), testing::Field( &PacketStreamDetails::streamIntervals, testing::ElementsAre(Interval( @@ -2443,7 +2443,7 @@ TEST_F(QuicTransportFunctionsTest, StreamDetailsMultipleStreams) { &PacketStreamDetails::newStreamBytesSent, stream2Len), testing::Field( &PacketStreamDetails::maybeFirstNewStreamByteOffset, - Optional(stream2Offset)), + OptionalIntegral(stream2Offset)), testing::Field( &PacketStreamDetails::streamIntervals, testing::ElementsAre(Interval( @@ -2456,7 +2456,7 @@ TEST_F(QuicTransportFunctionsTest, StreamDetailsMultipleStreams) { &PacketStreamDetails::newStreamBytesSent, stream3Len), testing::Field( &PacketStreamDetails::maybeFirstNewStreamByteOffset, - Optional(stream3Offset)), + OptionalIntegral(stream3Offset)), testing::Field( &PacketStreamDetails::streamIntervals, testing::ElementsAre(Interval( @@ -2499,7 +2499,7 @@ TEST_F(QuicTransportFunctionsTest, StreamDetailsMultipleStreams) { testing::Field(&PacketStreamDetails::newStreamBytesSent, 0), testing::Field( &PacketStreamDetails::maybeFirstNewStreamByteOffset, - Optional(/* empty */)), + OptionalIntegral(/* empty */)), testing::Field( &PacketStreamDetails::streamIntervals, testing::ElementsAre(Interval( @@ -2511,7 +2511,7 @@ TEST_F(QuicTransportFunctionsTest, StreamDetailsMultipleStreams) { testing::Field(&PacketStreamDetails::newStreamBytesSent, 0), testing::Field( &PacketStreamDetails::maybeFirstNewStreamByteOffset, - Optional(/* empty */)), + OptionalIntegral(/* empty */)), testing::Field( &PacketStreamDetails::streamIntervals, testing::ElementsAre(Interval( @@ -2523,7 +2523,7 @@ TEST_F(QuicTransportFunctionsTest, StreamDetailsMultipleStreams) { testing::Field(&PacketStreamDetails::newStreamBytesSent, 0), testing::Field( &PacketStreamDetails::maybeFirstNewStreamByteOffset, - Optional(/* empty */)), + OptionalIntegral(/* empty */)), testing::Field( &PacketStreamDetails::streamIntervals, testing::ElementsAre(Interval( diff --git a/quic/api/test/QuicTypedTransportTest.cpp b/quic/api/test/QuicTypedTransportTest.cpp index c401ae8e9..562e8fde9 100644 --- a/quic/api/test/QuicTypedTransportTest.cpp +++ b/quic/api/test/QuicTypedTransportTest.cpp @@ -126,9 +126,10 @@ TYPED_TEST(QuicTypedTransportAfterStartTest, TransportInfoRttSignals) { }; // minRTT should not be available in any form - EXPECT_EQ(none, this->getTransport()->getTransportInfo().maybeMinRtt); + EXPECT_EQ(std::nullopt, this->getTransport()->getTransportInfo().maybeMinRtt); EXPECT_EQ( - none, this->getTransport()->getTransportInfo().maybeMinRttNoAckDelay); + std::nullopt, + this->getTransport()->getTransportInfo().maybeMinRttNoAckDelay); // clear any outstanding packets this->getNonConstConn().outstandings.reset(); @@ -326,9 +327,10 @@ TYPED_TEST(QuicTypedTransportAfterStartTest, RttSampleAckDelayEqual) { }; // minRTT should not be available in any form - EXPECT_EQ(none, this->getTransport()->getTransportInfo().maybeMinRtt); + EXPECT_EQ(std::nullopt, this->getTransport()->getTransportInfo().maybeMinRtt); EXPECT_EQ( - none, this->getTransport()->getTransportInfo().maybeMinRttNoAckDelay); + std::nullopt, + this->getTransport()->getTransportInfo().maybeMinRttNoAckDelay); // clear any outstanding packets this->getNonConstConn().outstandings.reset(); @@ -386,9 +388,10 @@ TYPED_TEST(QuicTypedTransportAfterStartTest, RttSampleAckDelayGreater) { }; // minRTT should not be available in any form - EXPECT_EQ(none, this->getTransport()->getTransportInfo().maybeMinRtt); + EXPECT_EQ(std::nullopt, this->getTransport()->getTransportInfo().maybeMinRtt); EXPECT_EQ( - none, this->getTransport()->getTransportInfo().maybeMinRttNoAckDelay); + std::nullopt, + this->getTransport()->getTransportInfo().maybeMinRttNoAckDelay); // clear any outstanding packets this->getNonConstConn().outstandings.reset(); @@ -411,7 +414,7 @@ TYPED_TEST(QuicTypedTransportAfterStartTest, RttSampleAckDelayGreater) { EXPECT_EQ(rtt, tInfo.maybeLrtt); EXPECT_EQ(ackDelay, tInfo.maybeLrttAckDelay); EXPECT_EQ(expectedMinRtt, tInfo.maybeMinRtt); - EXPECT_EQ(none, tInfo.maybeMinRttNoAckDelay); // unavailable + EXPECT_EQ(std::nullopt, tInfo.maybeMinRttNoAckDelay); // unavailable } else { FAIL(); // unhandled typed test } @@ -448,9 +451,10 @@ TYPED_TEST(QuicTypedTransportAfterStartTest, RttSampleZeroTime) { }; // minRTT should not be available in any form - EXPECT_EQ(none, this->getTransport()->getTransportInfo().maybeMinRtt); + EXPECT_EQ(std::nullopt, this->getTransport()->getTransportInfo().maybeMinRtt); EXPECT_EQ( - none, this->getTransport()->getTransportInfo().maybeMinRttNoAckDelay); + std::nullopt, + this->getTransport()->getTransportInfo().maybeMinRttNoAckDelay); // clear any outstanding packets this->getNonConstConn().outstandings.reset(); @@ -1557,13 +1561,12 @@ struct AckEventMatcherBuilder { maybeLargestNewlyAckedPacket = largestNewlyAckedPacketIn; return std::move(*this); } - Builder&& setRtt(const Optional& rttIn) { + Builder&& setRtt(const OptionalMicros& rttIn) { maybeRtt = rttIn; CHECK(!noRtt); return std::move(*this); } - Builder&& setRttNoAckDelay( - const Optional& rttNoAckDelayIn) { + Builder&& setRttNoAckDelay(const OptionalMicros& rttNoAckDelayIn) { maybeRttNoAckDelay = rttNoAckDelayIn; CHECK(!noRtt); CHECK(!noRttWithNoAckDelay); @@ -1677,13 +1680,13 @@ struct AckEventMatcherBuilder { Optional::NewOutstandingPacketInterval>> maybeExpectedAckedIntervals; - Optional maybeExpectedNumAckedPackets; + OptionalIntegral maybeExpectedNumAckedPackets; Optional maybeAckTime; - Optional maybeAckDelay; - Optional maybeLargestAckedPacket; - Optional maybeLargestNewlyAckedPacket; - Optional maybeRtt; - Optional maybeRttNoAckDelay; + OptionalMicros maybeAckDelay; + OptionalIntegral maybeLargestAckedPacket; + OptionalIntegral maybeLargestNewlyAckedPacket; + OptionalMicros maybeRtt; + OptionalMicros maybeRttNoAckDelay; bool noRtt{false}; bool noRttWithNoAckDelay{false}; }; @@ -1747,7 +1750,7 @@ struct ReceivedUdpPacketMatcherBuilder { explicit ReceivedUdpPacketMatcherBuilder() = default; Optional maybeExpectedPacketReceiveTime; - Optional maybeExpectedPacketNumBytes; + OptionalIntegral maybeExpectedPacketNumBytes; Optional maybeExpectedTosValue; }; @@ -4094,7 +4097,7 @@ TYPED_TEST( testing::ElementsAre(testing::AllOf(testing::Field( &quic::AckEvent::rttSampleNoAckDelay, testing::AnyOf( - testing::Eq(0ms), testing::Eq(none))))))))); + testing::Eq(0ms), testing::Eq(std::nullopt))))))))); EXPECT_CALL( *observerWithAcks2, acksProcessed( @@ -4107,7 +4110,7 @@ TYPED_TEST( testing::ElementsAre(testing::AllOf(testing::Field( &quic::AckEvent::rttSampleNoAckDelay, testing::AnyOf( - testing::Eq(0ms), testing::Eq(none))))))))); + testing::Eq(0ms), testing::Eq(std::nullopt))))))))); const quic::AckBlocks ackBlocks = {{firstPacketNum, lastPacketNum}}; auto buf = quic::test::packetToBuf( @@ -4190,7 +4193,7 @@ TYPED_TEST( getAckEvents, testing::ElementsAre(testing::AllOf(testing::Field( &quic::AckEvent::rttSampleNoAckDelay, - testing::Eq(none)))))))); + testing::Eq(std::nullopt)))))))); EXPECT_CALL( *observerWithAcks2, acksProcessed( @@ -4202,7 +4205,7 @@ TYPED_TEST( getAckEvents, testing::ElementsAre(testing::AllOf(testing::Field( &quic::AckEvent::rttSampleNoAckDelay, - testing::Eq(none)))))))); + testing::Eq(std::nullopt)))))))); const quic::AckBlocks ackBlocks = {{firstPacketNum, lastPacketNum}}; auto buf = quic::test::packetToBuf( diff --git a/quic/client/QuicClientTransport.cpp b/quic/client/QuicClientTransport.cpp index bf003f262..c45d80080 100644 --- a/quic/client/QuicClientTransport.cpp +++ b/quic/client/QuicClientTransport.cpp @@ -627,7 +627,7 @@ void QuicClientTransport::processUdpPacketData( break; } case QuicFrame::Type::ImmediateAckFrame: { - if (!conn_->transportSettings.minAckDelay.hasValue()) { + if (!conn_->transportSettings.minAckDelay.has_value()) { // We do not accept IMMEDIATE_ACK frames. This is a protocol // violation. throw QuicTransportException( diff --git a/quic/client/test/ClientStateMachineTest.cpp b/quic/client/test/ClientStateMachineTest.cpp index 7334a0dff..ca8d5acf6 100644 --- a/quic/client/test/ClientStateMachineTest.cpp +++ b/quic/client/test/ClientStateMachineTest.cpp @@ -220,7 +220,7 @@ TEST_F(ClientStateMachineTest, TestProcessKnobFramesSupportedParamDisabled) { struct maxStreamGroupsAdvertizedtestStruct { uint64_t peerMaxGroupsIn; - Optional expectedTransportSettingVal; + OptionalIntegral expectedTransportSettingVal; }; class ClientStateMachineMaxStreamGroupsAdvertizedParamTest : public ClientStateMachineTest, @@ -252,7 +252,7 @@ INSTANTIATE_TEST_SUITE_P( ClientStateMachineMaxStreamGroupsAdvertizedParamTest, ClientStateMachineMaxStreamGroupsAdvertizedParamTest, ::testing::Values( - maxStreamGroupsAdvertizedtestStruct{0, none}, + maxStreamGroupsAdvertizedtestStruct{0, std::nullopt}, maxStreamGroupsAdvertizedtestStruct{16, 16})); } // namespace quic::test diff --git a/quic/codec/Decode.cpp b/quic/codec/Decode.cpp index b1884020f..84a85013e 100644 --- a/quic/codec/Decode.cpp +++ b/quic/codec/Decode.cpp @@ -473,7 +473,7 @@ ReadStreamFrame decodeStreamFrame( frameType); } - Optional groupId; + OptionalIntegral groupId; if (isGroupFrame) { auto gId = decodeQuicInteger(cursor); if (!gId) { diff --git a/quic/codec/QuicWriteCodec.cpp b/quic/codec/QuicWriteCodec.cpp index 2ba25301d..ebf90430a 100644 --- a/quic/codec/QuicWriteCodec.cpp +++ b/quic/codec/QuicWriteCodec.cpp @@ -36,7 +36,7 @@ Optional writeStreamFrameHeader( uint64_t flowControlLen, bool fin, Optional skipLenHint, - Optional streamGroupId, + OptionalIntegral streamGroupId, bool appendFrame) { if (builder.remainingSpaceInPkt() == 0) { return none; diff --git a/quic/codec/QuicWriteCodec.h b/quic/codec/QuicWriteCodec.h index 022f3c7ea..7a2c27aaa 100644 --- a/quic/codec/QuicWriteCodec.h +++ b/quic/codec/QuicWriteCodec.h @@ -57,7 +57,7 @@ Optional writeStreamFrameHeader( uint64_t flowControlLen, bool fin, Optional skipLenHint, - Optional streamGroupId = none, + OptionalIntegral streamGroupId = std::nullopt, bool appendFrame = true); /** diff --git a/quic/codec/Types.h b/quic/codec/Types.h index aa892d476..fe42b2feb 100644 --- a/quic/codec/Types.h +++ b/quic/codec/Types.h @@ -187,8 +187,8 @@ struct ReadAckFrame { using Vec = SmallVec; Vec ackBlocks; FrameType frameType = FrameType::ACK; - Optional maybeLatestRecvdPacketTime; - Optional maybeLatestRecvdPacketNum; + OptionalMicros maybeLatestRecvdPacketTime; + OptionalIntegral maybeLatestRecvdPacketNum; RecvdPacketsTimestampsRangeVec recvdPacketsTimestampRanges; uint32_t ecnECT0Count{0}; uint32_t ecnECT1Count{0}; @@ -202,14 +202,13 @@ struct ReadAckFrame { struct WriteAckFrame { // Since we don't need this to be an IntervalSet, they are stored directly // in a vector, in reverse order. - // TODO should this be a small_vector? using AckBlockVec = std::vector>; AckBlockVec ackBlocks; // Delay in sending ack from time that packet was received. std::chrono::microseconds ackDelay{0us}; FrameType frameType = FrameType::ACK; - Optional maybeLatestRecvdPacketTime; - Optional maybeLatestRecvdPacketNum; + OptionalMicros maybeLatestRecvdPacketTime; + OptionalIntegral maybeLatestRecvdPacketNum; RecvdPacketsTimestampsRangeVec recvdPacketsTimestampRanges; uint32_t ecnECT0Count{0}; uint32_t ecnECT1Count{0}; @@ -438,7 +437,7 @@ struct ReadNewTokenFrame { */ struct WriteStreamFrame { StreamId streamId; - Optional streamGroupId; + OptionalIntegral streamGroupId; uint64_t offset; uint64_t len; bool fin; @@ -455,7 +454,7 @@ struct WriteStreamFrame { uint64_t lenIn, bool finIn, bool fromBufMetaIn = false, - Optional streamGroupIdIn = none, + OptionalIntegral streamGroupIdIn = std::nullopt, uint64_t streamPacketIdxIn = 0) : streamId(streamIdIn), streamGroupId(streamGroupIdIn), @@ -478,7 +477,7 @@ struct WriteStreamFrame { */ struct ReadStreamFrame { StreamId streamId; - Optional streamGroupId; + OptionalIntegral streamGroupId; uint64_t offset; Buf data; bool fin; @@ -488,7 +487,7 @@ struct ReadStreamFrame { uint64_t offsetIn, Buf dataIn, bool finIn, - Optional streamGroupIdIn = none) + OptionalIntegral streamGroupIdIn = std::nullopt) : streamId(streamIdIn), streamGroupId(streamGroupIdIn), offset(offsetIn), @@ -499,7 +498,7 @@ struct ReadStreamFrame { StreamId streamIdIn, uint64_t offsetIn, bool finIn, - Optional streamGroupIdIn = none) + OptionalIntegral streamGroupIdIn = std::nullopt) : streamId(streamIdIn), streamGroupId(streamGroupIdIn), offset(offsetIn), diff --git a/quic/common/BUCK b/quic/common/BUCK index 5ff367713..01e8463c7 100644 --- a/quic/common/BUCK +++ b/quic/common/BUCK @@ -190,5 +190,6 @@ mvfst_cpp_library( ], exported_deps = [ "//folly:optional", + "//quic/common/third-party:tiny_optional", ], ) diff --git a/quic/common/FunctionLooper.cpp b/quic/common/FunctionLooper.cpp index 06b21b173..df0fdbe7a 100644 --- a/quic/common/FunctionLooper.cpp +++ b/quic/common/FunctionLooper.cpp @@ -158,12 +158,11 @@ void FunctionLooper::callbackCanceled() noexcept { return; } -Optional -FunctionLooper::getTimerTickInterval() noexcept { +OptionalMicros FunctionLooper::getTimerTickInterval() noexcept { if (pacingTimer_) { return pacingTimer_->getTickInterval(); } - return none; + return std::nullopt; } std::ostream& operator<<(std::ostream& out, const LooperType& rhs) { diff --git a/quic/common/FunctionLooper.h b/quic/common/FunctionLooper.h index 7c5cf5b97..c7bbe620b 100644 --- a/quic/common/FunctionLooper.h +++ b/quic/common/FunctionLooper.h @@ -95,7 +95,7 @@ class FunctionLooper : public QuicEventBaseLoopCallback, void callbackCanceled() noexcept override; - Optional getTimerTickInterval() noexcept; + OptionalMicros getTimerTickInterval() noexcept; /* * Controls whether to fire a loop early when the pacing timer has been diff --git a/quic/common/Optional.h b/quic/common/Optional.h index 332950919..dfe5eced9 100644 --- a/quic/common/Optional.h +++ b/quic/common/Optional.h @@ -8,9 +8,35 @@ #pragma once #include +#define TINY_OPTIONAL_USE_SEPARATE_BOOL_INSTEAD_OF_UB_TRICKS 1 +#include + +#include + namespace quic { template using Optional = folly::Optional; constexpr folly::None none{folly::None::_secret::_token}; + +template +using OptionalIntegral = tiny::optional_aip; + +struct MicrosecondsFlagManipulator { + static bool is_empty(const std::chrono::microseconds& t) noexcept { + return t == std::chrono::microseconds::min(); + } + + static void init_empty_flag(std::chrono::microseconds& t) noexcept { + ::new (&t) std::chrono::microseconds(std::chrono::microseconds::min()); + } + + static void invalidate_empty_flag(std::chrono::microseconds& t) noexcept { + std::destroy_at(&t); + } +}; + +using OptionalMicros = tiny:: + optional_inplace; + } // namespace quic diff --git a/quic/common/test/TestPacketBuilders.cpp b/quic/common/test/TestPacketBuilders.cpp index 4b3c530f0..7c6fda3f2 100644 --- a/quic/common/test/TestPacketBuilders.cpp +++ b/quic/common/test/TestPacketBuilders.cpp @@ -141,7 +141,7 @@ RegularQuicPacketBuilder::Packet AckPacketBuilder::build() && { ackState.acks = *CHECK_NOTNULL(maybeAckBlocks.get_pointer()); WriteAckFrameMetaData ackData = { ackState, - *CHECK_NOTNULL(maybeAckDelay.get_pointer()), + maybeAckDelay.value(), static_cast( CHECK_NOTNULL(dstConn)->transportSettings.ackDelayExponent), TimePoint()}; @@ -235,7 +235,7 @@ OutstandingPacketWrapper OutstandingPacketBuilder::build() && { *CHECK_NOTNULL(maybeWriteCount.get_pointer()), OutstandingPacketWrapper::Metadata::DetailsPerStream( *CHECK_NOTNULL(maybeDetailsPerStream.get_pointer())), - *CHECK_NOTNULL(maybeTotalAppLimitedTimeUsecs.get_pointer())}; + maybeTotalAppLimitedTimeUsecs.value()}; } } // namespace quic::test diff --git a/quic/common/test/TestPacketBuilders.h b/quic/common/test/TestPacketBuilders.h index eb54f3cee..5c00d76e7 100644 --- a/quic/common/test/TestPacketBuilders.h +++ b/quic/common/test/TestPacketBuilders.h @@ -28,7 +28,7 @@ struct AckPacketBuilderFields { Optional maybeAckPacketNum; PacketNumStore* ackPacketNumStore{nullptr}; Optional maybeAckBlocks; - Optional maybeAckDelay; + OptionalMicros maybeAckDelay; Optional maybeAead; // not required ProtectionType shortHeaderProtectionType{ProtectionType::KeyPhaseZero}; explicit AckPacketBuilderFields() = default; @@ -62,7 +62,7 @@ struct OutstandingPacketBuilderFields { Optional maybeWriteCount; Optional maybeDetailsPerStream; - Optional maybeTotalAppLimitedTimeUsecs; + OptionalMicros maybeTotalAppLimitedTimeUsecs; explicit OutstandingPacketBuilderFields() = default; }; diff --git a/quic/common/third-party/optional.h b/quic/common/third-party/optional.h index 7311a2a69..af62ee32b 100644 --- a/quic/common/third-party/optional.h +++ b/quic/common/third-party/optional.h @@ -1388,7 +1388,7 @@ namespace impl // Actual implementation of optional. template - class TinyOptionalImpl : private CopyAssignmentBase + class TinyOptionalImpl : public CopyAssignmentBase { private: using Base = CopyAssignmentBase; diff --git a/quic/congestion_control/QuicCubic.h b/quic/congestion_control/QuicCubic.h index 96e54b0cb..96dd53f34 100644 --- a/quic/congestion_control/QuicCubic.h +++ b/quic/congestion_control/QuicCubic.h @@ -162,11 +162,11 @@ class Cubic : public CongestionController { TimePoint lastJiffy; // The minimal of sampled RTT in current RTT round. Hystart only samples // first a few RTTs in a round - Optional currSampledRtt; + OptionalMicros currSampledRtt; // End value of currSampledRtt at the end of a RTT round: - Optional lastSampledRtt; + OptionalMicros lastSampledRtt; // Estimated minimal delay of a path - Optional delayMin; + OptionalMicros delayMin; // Ack sampling count uint8_t ackCount{0}; // When a packet with sent time >= rttRoundEndTarget is acked, end the diff --git a/quic/dsr/backend/DSRPacketizer.cpp b/quic/dsr/backend/DSRPacketizer.cpp index 4986b68ee..240f92afd 100644 --- a/quic/dsr/backend/DSRPacketizer.cpp +++ b/quic/dsr/backend/DSRPacketizer.cpp @@ -50,7 +50,7 @@ bool PacketGroupWriter::writeSingleQuicPacket( length /* flow control len*/, eof, true /* skip length field in stream header */, - none, /* stream group id */ + std::nullopt, /* stream group id */ false /* don't append frame to builder */); BufQueue bufQueue(std::move(buf)); writeStreamFrameData(builder, bufQueue, *dataLen); diff --git a/quic/dsr/backend/test/DSRPacketizerTest.cpp b/quic/dsr/backend/test/DSRPacketizerTest.cpp index d71e40a66..bdb019721 100644 --- a/quic/dsr/backend/test/DSRPacketizerTest.cpp +++ b/quic/dsr/backend/test/DSRPacketizerTest.cpp @@ -162,9 +162,9 @@ TEST_F(DSRMultiWriteTest, TwoRequestsWithLoss) { auto& packet2 = conn_.outstandings.packets.back().packet; EXPECT_EQ(1, packet1.frames.size()); WriteStreamFrame expectedFirstFrame( - streamId, bufMetaStartingOffset, 500, false, true, none, 0); + streamId, bufMetaStartingOffset, 500, false, true, std::nullopt, 0); WriteStreamFrame expectedSecondFrame( - streamId, 500 + bufMetaStartingOffset, 500, true, true, none, 1); + streamId, 500 + bufMetaStartingOffset, 500, true, true, std::nullopt, 1); EXPECT_EQ(expectedFirstFrame, *packet1.frames[0].asWriteStreamFrame()); EXPECT_EQ(expectedSecondFrame, *packet2.frames[0].asWriteStreamFrame()); diff --git a/quic/dsr/frontend/test/PacketBuilderTest.cpp b/quic/dsr/frontend/test/PacketBuilderTest.cpp index d5688ccd0..8d7decf34 100644 --- a/quic/dsr/frontend/test/PacketBuilderTest.cpp +++ b/quic/dsr/frontend/test/PacketBuilderTest.cpp @@ -103,8 +103,9 @@ TEST_F(PacketBuilderTest, WriteTwoInstructions) { const auto& writePacket = packet.packet; EXPECT_EQ(2, packet.sendInstructions.size()); EXPECT_EQ(2, writePacket.frames.size()); - WriteStreamFrame expectedFirstFrame(id, 0, 100, false, true, none, 5); - WriteStreamFrame expectedSecondFrame(id, 100, 100, true, true, none, 6); + WriteStreamFrame expectedFirstFrame(id, 0, 100, false, true, std::nullopt, 5); + WriteStreamFrame expectedSecondFrame( + id, 100, 100, true, true, std::nullopt, 6); EXPECT_EQ(expectedFirstFrame, *writePacket.frames[0].asWriteStreamFrame()); EXPECT_EQ(expectedSecondFrame, *writePacket.frames[1].asWriteStreamFrame()); EXPECT_TRUE(expectedFirstFrame == packet.sendInstructions[0]); diff --git a/quic/dsr/frontend/test/WriteFunctionsTest.cpp b/quic/dsr/frontend/test/WriteFunctionsTest.cpp index fa2adfb46..314fe14b0 100644 --- a/quic/dsr/frontend/test/WriteFunctionsTest.cpp +++ b/quic/dsr/frontend/test/WriteFunctionsTest.cpp @@ -307,9 +307,9 @@ TEST_F(WriteFunctionsTest, LossAndFreshTwoInstructionsInTwoPackets) { EXPECT_EQ(1, packet1.frames.size()); EXPECT_EQ(1, packet2.frames.size()); WriteStreamFrame expectedFirstFrame( - streamId, bufMetaStartingOffset, 500, false, true, none, 0); + streamId, bufMetaStartingOffset, 500, false, true, std::nullopt, 0); WriteStreamFrame expectedSecondFrame( - streamId, 500 + bufMetaStartingOffset, 500, true, true, none, 1); + streamId, 500 + bufMetaStartingOffset, 500, true, true, std::nullopt, 1); EXPECT_EQ(expectedFirstFrame, *packet1.frames[0].asWriteStreamFrame()); EXPECT_EQ(expectedSecondFrame, *packet2.frames[0].asWriteStreamFrame()); } diff --git a/quic/logging/QLoggerTypes.h b/quic/logging/QLoggerTypes.h index aadd02913..647f7e871 100644 --- a/quic/logging/QLoggerTypes.h +++ b/quic/logging/QLoggerTypes.h @@ -194,8 +194,8 @@ class ReadAckFrameLog : public QLogFrame { ReadAckFrame::Vec ackBlocks; std::chrono::microseconds ackDelay; FrameType frameType; - Optional maybeLatestRecvdPacketTime; - Optional maybeLatestRecvdPacketNum; + OptionalMicros maybeLatestRecvdPacketTime; + OptionalIntegral maybeLatestRecvdPacketNum; RecvdPacketsTimestampsRangeVec recvdPacketsTimestampRanges; uint32_t ecnECT0Count; uint32_t ecnECT1Count; @@ -205,8 +205,8 @@ class ReadAckFrameLog : public QLogFrame { const ReadAckFrame::Vec& ackBlocksIn, std::chrono::microseconds ackDelayIn, FrameType frameTypeIn = FrameType::ACK, - Optional maybeLatestRecvdPacketTimeIn = none, - Optional maybeLatestRecvdPacketNumIn = none, + OptionalMicros maybeLatestRecvdPacketTimeIn = std::nullopt, + OptionalIntegral maybeLatestRecvdPacketNumIn = std::nullopt, RecvdPacketsTimestampsRangeVec recvdPacketsTimestampRangesIn = {}, uint32_t ecnECT0CountIn = 0, uint32_t ecnECT1CountIn = 0, @@ -229,8 +229,8 @@ class WriteAckFrameLog : public QLogFrame { WriteAckFrame::AckBlockVec ackBlocks; std::chrono::microseconds ackDelay; FrameType frameType; - Optional maybeLatestRecvdPacketTime; - Optional maybeLatestRecvdPacketNum; + OptionalMicros maybeLatestRecvdPacketTime; + OptionalIntegral maybeLatestRecvdPacketNum; RecvdPacketsTimestampsRangeVec recvdPacketsTimestampRanges; uint32_t ecnECT0Count; uint32_t ecnECT1Count; @@ -240,8 +240,8 @@ class WriteAckFrameLog : public QLogFrame { const WriteAckFrame::AckBlockVec& ackBlocksIn, std::chrono::microseconds ackDelayIn, FrameType frameTypeIn = FrameType::ACK, - Optional maybeLatestRecvdPacketTimeIn = none, - Optional maybeLatestRecvdPacketNumIn = none, + OptionalMicros maybeLatestRecvdPacketTimeIn = std::nullopt, + OptionalIntegral maybeLatestRecvdPacketNumIn = std::nullopt, RecvdPacketsTimestampsRangeVec recvdPacketsTimestampRangesIn = {}, uint32_t ecnECT0CountIn = 0, uint32_t ecnECT1CountIn = 0, diff --git a/quic/loss/QuicLossFunctions.cpp b/quic/loss/QuicLossFunctions.cpp index 49ce0d75e..7fa48c449 100644 --- a/quic/loss/QuicLossFunctions.cpp +++ b/quic/loss/QuicLossFunctions.cpp @@ -20,7 +20,7 @@ std::chrono::microseconds calculatePTO(const QuicConnectionStateBase& conn) { } bool isPersistentCongestion( - Optional pto, + OptionalMicros pto, TimePoint lostPeriodStart, TimePoint lostPeriodEnd, const CongestionController::AckEvent& ack) noexcept { diff --git a/quic/loss/QuicLossFunctions.h b/quic/loss/QuicLossFunctions.h index 60f7cf3d4..afda744ca 100644 --- a/quic/loss/QuicLossFunctions.h +++ b/quic/loss/QuicLossFunctions.h @@ -37,7 +37,7 @@ std::chrono::microseconds calculatePTO(const QuicConnectionStateBase& conn); * */ bool isPersistentCongestion( - Optional pto, + OptionalMicros pto, TimePoint lostPeriodStart, TimePoint lostPeriodEnd, const CongestionController::AckEvent& ack) noexcept; diff --git a/quic/loss/test/QuicLossFunctionsTest.cpp b/quic/loss/test/QuicLossFunctionsTest.cpp index bbc756aac..8e78ceb1e 100644 --- a/quic/loss/test/QuicLossFunctionsTest.cpp +++ b/quic/loss/test/QuicLossFunctionsTest.cpp @@ -45,14 +45,14 @@ auto getOutstandingPacketMatcher( testing::Field( &quic::OutstandingPacketMetadata::lossReorderDistance, testing::Property( - &quic::Optional::hasValue, + &quic::OptionalIntegral::has_value, testing::Eq(lostByReorder)))), testing::Field( &quic::OutstandingPacketWrapper::metadata, testing::Field( &quic::OutstandingPacketMetadata::lossTimeoutDividend, testing::Property( - &quic::Optional::hasValue, + &quic::OptionalIntegral::has_value, testing::Eq(lostByTimeout)))), testing::Field( &quic::OutstandingPacketWrapper::packet, @@ -1918,8 +1918,8 @@ TEST_F(QuicLossFunctionsTest, PersistentCongestionNoPTO) { .setDetailsPerStream(AckEvent::AckPacket::DetailsPerStream()) .build()); - EXPECT_FALSE( - isPersistentCongestion(none, currentTime + 1s, currentTime + 8s, ack)); + EXPECT_FALSE(isPersistentCongestion( + std::nullopt, currentTime + 1s, currentTime + 8s, ack)); } TEST_F(QuicLossFunctionsTest, ObserverLossEventReorder) { @@ -2532,7 +2532,7 @@ TEST_F(QuicLossFunctionsTest, TestReorderingThresholdDSRNormal) { 100, false, true, - none, + std::nullopt, op.packet.header.getPacketSequenceNum()}); op.isDSRPacket = true; conn->outstandings.dsrCount++; @@ -2560,7 +2560,7 @@ TEST_F(QuicLossFunctionsTest, TestReorderingThresholdDSRNormal) { .build(); AckEvent::AckPacket::DetailsPerStream detailsPerStream; detailsPerStream.recordFrameDelivered( - WriteStreamFrame{0, 10, 100, false, true, none, 9}); + WriteStreamFrame{0, 10, 100, false, true, std::nullopt, 9}); ack.ackedPackets.emplace_back( CongestionController::AckEvent::AckPacket::Builder() .setPacketNum(9) @@ -2702,7 +2702,7 @@ TEST_F(QuicLossFunctionsTest, TestReorderingThresholdDSRIgnoreReorder) { 100, false, true, - none, + std::nullopt, op.packet.header.getPacketSequenceNum()}); op.isDSRPacket = true; conn->outstandings.dsrCount++; @@ -2960,7 +2960,13 @@ TEST_F(QuicLossFunctionsTest, TestReorderingThresholdDSRIgnoreReorderBurst) { .build(); for (auto& op : conn->outstandings.packets) { WriteStreamFrame f{ - 0, 10, 100, false, true, none, op.packet.header.getPacketSequenceNum()}; + 0, + 10, + 100, + false, + true, + std::nullopt, + op.packet.header.getPacketSequenceNum()}; AckEvent::AckPacket::DetailsPerStream detailsPerStream; if (op.packet.header.getPacketSequenceNum() != 4) { detailsPerStream.recordFrameDelivered(f); @@ -2992,7 +2998,7 @@ TEST_F(QuicLossFunctionsTest, TestReorderingThresholdDSRIgnoreReorderBurst) { // Add one more DSR packet from the same stream, ACKed sendPacket(*conn, Clock::now(), none, PacketType::OneRtt, none, true); auto& op = *getLastOutstandingPacket(*conn, PacketNumberSpace::AppData); - WriteStreamFrame f{0, 10, 100, false, true, none, 5}; + WriteStreamFrame f{0, 10, 100, false, true, std::nullopt, 5}; AckEvent::AckPacket::DetailsPerStream detailsPerStream; detailsPerStream.recordFrameDelivered(f); op.packet.frames.emplace_back(f); @@ -3064,7 +3070,7 @@ TEST_F(QuicLossFunctionsTest, TestReorderingThresholdNonDSRIgnoreReorderBurst) { .setAckDelay(0us) .build(); for (auto& op : conn->outstandings.packets) { - WriteStreamFrame f{0, 10, 100, false, false, none, 0}; + WriteStreamFrame f{0, 10, 100, false, false, std::nullopt, 0}; AckEvent::AckPacket::DetailsPerStream detailsPerStream; if (op.packet.header.getPacketSequenceNum() != 4) { detailsPerStream.recordFrameDelivered(f); @@ -3084,7 +3090,7 @@ TEST_F(QuicLossFunctionsTest, TestReorderingThresholdNonDSRIgnoreReorderBurst) { sendPacket(*conn, Clock::now(), none, PacketType::OneRtt, none, true); auto& op = *getLastOutstandingPacket(*conn, PacketNumberSpace::AppData); WriteStreamFrame f{ - 4, 10, 100, false, true, none, conn->outstandings.dsrCount++}; + 4, 10, 100, false, true, std::nullopt, conn->outstandings.dsrCount++}; AckEvent::AckPacket::DetailsPerStream detailsPerStream; detailsPerStream.recordFrameDelivered(f); ack.ackedPackets.emplace_back( @@ -3100,7 +3106,7 @@ TEST_F(QuicLossFunctionsTest, TestReorderingThresholdNonDSRIgnoreReorderBurst) { // Add one more non-DSR packet from the same stream, ACKed sendPacket(*conn, Clock::now(), none, PacketType::OneRtt); auto& op = *getLastOutstandingPacket(*conn, PacketNumberSpace::AppData); - WriteStreamFrame f{0, 10, 100, false, false, none, 0}; + WriteStreamFrame f{0, 10, 100, false, false, std::nullopt, 0}; AckEvent::AckPacket::DetailsPerStream detailsPerStream; detailsPerStream.recordFrameDelivered(f); op.packet.frames.emplace_back(f); diff --git a/quic/server/state/ServerStateMachine.cpp b/quic/server/state/ServerStateMachine.cpp index a38f46286..c918b00bc 100644 --- a/quic/server/state/ServerStateMachine.cpp +++ b/quic/server/state/ServerStateMachine.cpp @@ -1269,7 +1269,7 @@ void onServerReadDataFromOpen( break; } case QuicFrame::Type::ImmediateAckFrame: { - if (!conn.transportSettings.minAckDelay.hasValue()) { + if (!conn.transportSettings.minAckDelay.has_value()) { // We do not accept IMMEDIATE_ACK frames. This is a protocol // violation. throw QuicTransportException( diff --git a/quic/server/test/QuicServerTransportTest.cpp b/quic/server/test/QuicServerTransportTest.cpp index 522fc217b..9f828e7a7 100644 --- a/quic/server/test/QuicServerTransportTest.cpp +++ b/quic/server/test/QuicServerTransportTest.cpp @@ -3041,7 +3041,7 @@ TEST_F(QuicServerTransportTest, ImmediateAckProtocolViolation) { // packet number spaces to generate ACKs immediately. ImmediateAckFrame immediateAckFrame; // We do not support IMMEDIATE_ACK frames - server->getNonConstConn().transportSettings.minAckDelay.clear(); + server->getNonConstConn().transportSettings.minAckDelay.reset(); auto packetNum = clientNextAppDataPacketNum++; ShortHeader header( @@ -4064,7 +4064,7 @@ TEST_F( EXPECT_CALL(handshakeFinishedCallback, onHandshakeFinished()); recvClientFinished(); loopForWrites(); - EXPECT_EQ(server->getConn().writableBytesLimit, none); + EXPECT_EQ(server->getConn().writableBytesLimit, std::nullopt); std::vector indices = getQLogEventIndices(QLogEventType::TransportStateUpdate, qLogger); diff --git a/quic/server/test/ServerStateMachineTest.cpp b/quic/server/test/ServerStateMachineTest.cpp index 58abad009..8341d496f 100644 --- a/quic/server/test/ServerStateMachineTest.cpp +++ b/quic/server/test/ServerStateMachineTest.cpp @@ -338,7 +338,7 @@ TEST(ServerStateMachineTest, TestEncodeKnobFrameSupportedParamDisabled) { struct advertisedMaxStreamGroupstestStruct { uint64_t peerMaxGroupsIn; - Optional expectedTransportSettingVal; + OptionalIntegral expectedTransportSettingVal; }; class ServerStateMachineAdvertisedMaxStreamGroupsParamTest @@ -371,7 +371,7 @@ INSTANTIATE_TEST_SUITE_P( ServerStateMachineAdvertisedMaxStreamGroupsParamTest, ServerStateMachineAdvertisedMaxStreamGroupsParamTest, ::testing::Values( - advertisedMaxStreamGroupstestStruct{0, none}, + advertisedMaxStreamGroupstestStruct{0, std::nullopt}, advertisedMaxStreamGroupstestStruct{16, 16})); } // namespace test diff --git a/quic/state/AckEvent.cpp b/quic/state/AckEvent.cpp index fc7001374..357223e28 100644 --- a/quic/state/AckEvent.cpp +++ b/quic/state/AckEvent.cpp @@ -53,7 +53,7 @@ AckEvent::AckPacket::AckPacket( Optional lastAckedPacketInfoIn, bool isAppLimitedIn, - Optional&& receiveRelativeTimeStampUsec) + OptionalMicros&& receiveRelativeTimeStampUsec) : packetNum(packetNumIn), nonDsrPacketSequenceNumber(nonDsrPacketSequenceNumberIn), outstandingPacketMetadata(outstandingPacketMetadataIn), // NOLINT @@ -104,7 +104,7 @@ AckEvent::AckPacket::Builder&& AckEvent::AckPacket::Builder::setAppLimited( AckEvent::AckPacket::Builder&& AckEvent::AckPacket::Builder::setReceiveDeltaTimeStamp( - Optional&& receiveTimeStampIn) { + OptionalMicros&& receiveTimeStampIn) { receiveRelativeTimeStampUsec = receiveTimeStampIn; return std::move(*this); } @@ -177,7 +177,7 @@ AckEvent::AckEvent(AckEvent::BuilderFields&& builderFields) : ackTime(*CHECK_NOTNULL(builderFields.maybeAckTime.get_pointer())), adjustedAckTime( *CHECK_NOTNULL(builderFields.maybeAdjustedAckTime.get_pointer())), - ackDelay(*CHECK_NOTNULL(builderFields.maybeAckDelay.get_pointer())), + ackDelay(builderFields.maybeAckDelay.value()), packetNumberSpace( *CHECK_NOTNULL(builderFields.maybePacketNumberSpace.get_pointer())), largestAckedPacket( diff --git a/quic/state/AckEvent.h b/quic/state/AckEvent.h index f9be00ba9..7549ba6c6 100644 --- a/quic/state/AckEvent.h +++ b/quic/state/AckEvent.h @@ -125,12 +125,12 @@ struct AckEvent { // RTT sample with ack delay included. // // not available if largestAckedPacket already acked or declared lost - Optional rttSample; + OptionalMicros rttSample; // RTT sample with ack delay removed. // // not available if largestAckedPacket already acked or declared lost - Optional rttSampleNoAckDelay; + OptionalMicros rttSampleNoAckDelay; // Congestion controller state after processing of AckEvent. // @@ -247,7 +247,7 @@ struct AckEvent { Optional lastAckedPacketInfo; // Delta RX Timestamp of the current packet relative to the previous packet // (or connection start time). - Optional receiveRelativeTimeStampUsec; + OptionalMicros receiveRelativeTimeStampUsec; // Whether this packet was sent when CongestionController is in // app-limited state. @@ -264,7 +264,7 @@ struct AckEvent { OutstandingPacketWrapper::LastAckedPacketInfo* lastAckedPacketInfoIn); Builder&& setAppLimited(bool appLimitedIn); Builder&& setReceiveDeltaTimeStamp( - Optional&& receiveRelativeTimeStampUsec); + OptionalMicros&& receiveRelativeTimeStampUsec); AckPacket build() &&; explicit Builder() = default; @@ -275,7 +275,7 @@ struct AckEvent { Optional detailsPerStream; OutstandingPacketWrapper::LastAckedPacketInfo* lastAckedPacketInfo{ nullptr}; - Optional receiveRelativeTimeStampUsec; + OptionalMicros receiveRelativeTimeStampUsec; bool isAppLimited{false}; }; @@ -288,7 +288,7 @@ struct AckEvent { Optional lastAckedPacketInfoIn, bool isAppLimitedIn, - Optional&& receiveRelativeTimeStampUsec); + OptionalMicros&& receiveRelativeTimeStampUsec); }; // Information about each packet ACKed during this event @@ -297,7 +297,7 @@ struct AckEvent { struct BuilderFields { Optional maybeAckTime; Optional maybeAdjustedAckTime; - Optional maybeAckDelay; + OptionalMicros maybeAckDelay; Optional maybePacketNumberSpace; Optional maybeLargestAckedPacket; bool isImplicitAck{false}; diff --git a/quic/state/AckHandlers.cpp b/quic/state/AckHandlers.cpp index d55dbc233..7ae039a11 100644 --- a/quic/state/AckHandlers.cpp +++ b/quic/state/AckHandlers.cpp @@ -232,7 +232,7 @@ AckEvent processAckFrame( CHECK_GT(conn.outstandings.declaredLostCount, 0); conn.lossState.totalPacketsSpuriouslyMarkedLost++; if (conn.transportSettings.useAdaptiveLossReorderingThresholds) { - if (rPacketIt->metadata.lossReorderDistance.hasValue() && + if (rPacketIt->metadata.lossReorderDistance.has_value() && rPacketIt->metadata.lossReorderDistance.value() > conn.lossState.reorderingThreshold) { conn.lossState.reorderingThreshold = @@ -240,7 +240,7 @@ AckEvent processAckFrame( } } if (conn.transportSettings.useAdaptiveLossTimeThresholds) { - if (rPacketIt->metadata.lossTimeoutDividend.hasValue() && + if (rPacketIt->metadata.lossTimeoutDividend.has_value() && rPacketIt->metadata.lossTimeoutDividend.value() > conn.transportSettings.timeReorderingThreshDividend) { conn.transportSettings.timeReorderingThreshDividend = @@ -335,10 +335,9 @@ AckEvent processAckFrame( CHECK(!ack.rttSampleNoAckDelay.has_value()); ack.rttSample = rttSample; ack.rttSampleNoAckDelay = (rttSample >= frame.ackDelay) - ? folly::make_optional( - std::chrono::ceil( - rttSample - frame.ackDelay)) - : none; + ? OptionalMicros(std::chrono::ceil( + rttSample - frame.ackDelay)) + : std::nullopt; // update transport RTT updateRtt(conn, rttSample, frame.ackDelay); @@ -508,9 +507,9 @@ AckEvent processAckFrame( .setAppLimited(outstandingPacket->isAppLimited) .setReceiveDeltaTimeStamp( maybeRxTimestamp != packetReceiveTimeStamps.end() - ? folly::make_optional( + ? OptionalMicros( std::chrono::microseconds(maybeRxTimestamp->second)) - : none) + : std::nullopt) .build()); } if (lastAckedPacketSentTime) { @@ -550,9 +549,8 @@ AckEvent processAckFrame( // congestion period. Alternatively we could consider every lost block // and check if any of them constitute persistent congestion. lossEvent->persistentCongestion = isPersistentCongestion( - conn.lossState.srtt == 0s - ? none - : Optional(calculatePTO(conn)), + conn.lossState.srtt == 0s ? std::nullopt + : OptionalMicros(calculatePTO(conn)), *lossEvent->smallestLostSentTime, *lossEvent->largestLostSentTime, ack); diff --git a/quic/state/LossState.h b/quic/state/LossState.h index 5b2b299bf..8d5c19b0b 100644 --- a/quic/state/LossState.h +++ b/quic/state/LossState.h @@ -24,11 +24,11 @@ struct LossState { // minimum rtt. AckDelay isn't excluded from this. std::chrono::microseconds mrtt{kDefaultMinRtt}; // minimum rtt measured from samples with AckDelay excluded. - Optional maybeMrttNoAckDelay; + OptionalMicros maybeMrttNoAckDelay; // Last raw RTT value; unlike lrtt, this will always contain any ACK delay. - Optional maybeLrtt; + OptionalMicros maybeLrtt; // Last raw ACK delay value. - Optional maybeLrttAckDelay; + OptionalMicros maybeLrttAckDelay; // Smooth rtt. std::chrono::microseconds srtt{0us}; // Latest rtt. diff --git a/quic/state/OutstandingPacket.h b/quic/state/OutstandingPacket.h index fffa82be0..6f66ec18b 100644 --- a/quic/state/OutstandingPacket.h +++ b/quic/state/OutstandingPacket.h @@ -36,7 +36,7 @@ struct OutstandingPacketMetadata { // Has value if the packet is lost by timeout. The value is the loss timeout // dividend that was used to declare this packet. - Optional lossTimeoutDividend; + OptionalIntegral lossTimeoutDividend; // Has value if the packet is lost by reorder. The value is the distance // between this packet and the acknowleded packet when it was declared lost @@ -49,7 +49,7 @@ struct OutstandingPacketMetadata { uint64_t streamBytesSent{0}; uint64_t newStreamBytesSent{0}; - Optional maybeFirstNewStreamByteOffset; + OptionalIntegral maybeFirstNewStreamByteOffset; }; using MapType = InlineMap; @@ -102,7 +102,7 @@ struct OutstandingPacketMetadata { // was sent. std::chrono::microseconds totalAppLimitedTimeUsecs{0}; - Optional lossReorderDistance; + OptionalIntegral lossReorderDistance; // Bytes in flight on this connection including this packet itself when this // packet is sent. @@ -178,7 +178,7 @@ struct OutstandingPacket { // none if the packet isn't a clone and hasn't been cloned. Optional associatedEvent; - Optional nonDsrPacketSequenceNumber; + OptionalIntegral nonDsrPacketSequenceNumber; // Whether this is a DSR packet. A DSR packet's stream data isn't written // by transport directly. diff --git a/quic/state/QuicStreamManager.cpp b/quic/state/QuicStreamManager.cpp index 170fa9a06..e49abadc6 100644 --- a/quic/state/QuicStreamManager.cpp +++ b/quic/state/QuicStreamManager.cpp @@ -281,7 +281,7 @@ QuicStreamManager::getOrCreateOpenedLocalStream(StreamId streamId) { QuicStreamState* QuicStreamManager::getStream( StreamId streamId, - Optional streamGroupId) { + OptionalIntegral streamGroupId) { if (isRemoteStream(nodeType_, streamId)) { auto stream = getOrCreatePeerStream(streamId, std::move(streamGroupId)); updateAppIdleState(); @@ -306,7 +306,7 @@ QuicStreamState* QuicStreamManager::getStream( folly::Expected QuicStreamManager::createNextBidirectionalStream( - Optional streamGroupId) { + OptionalIntegral streamGroupId) { auto stream = createStream(nextBidirectionalStreamId_, std::move(streamGroupId)); if (stream.hasValue()) { @@ -323,7 +323,7 @@ QuicStreamManager::createNextBidirectionalStreamGroup() { folly::Expected QuicStreamManager::createNextUnidirectionalStream( - Optional streamGroupId) { + OptionalIntegral streamGroupId) { auto stream = createStream(nextUnidirectionalStreamId_, std::move(streamGroupId)); if (stream.hasValue()) { @@ -334,7 +334,7 @@ QuicStreamManager::createNextUnidirectionalStream( QuicStreamState* FOLLY_NULLABLE QuicStreamManager::instantiatePeerStream( StreamId streamId, - Optional groupId) { + OptionalIntegral groupId) { if (groupId) { auto& seenSet = isUnidirectionalStream(streamId) ? peerUnidirectionalStreamGroupsSeen_ @@ -388,7 +388,7 @@ QuicStreamManager::createNextStreamGroup( QuicStreamState* FOLLY_NULLABLE QuicStreamManager::getOrCreatePeerStream( StreamId streamId, - Optional streamGroupId) { + OptionalIntegral streamGroupId) { // This function maintains 3 invariants: // 1. Streams below nextAcceptableStreamId are streams that have been // seen before. Everything above can be opened. @@ -485,7 +485,7 @@ QuicStreamState* FOLLY_NULLABLE QuicStreamManager::getOrCreatePeerStream( folly::Expected QuicStreamManager::createStream( StreamId streamId, - Optional streamGroupId) { + OptionalIntegral streamGroupId) { if (nodeType_ == QuicNodeType::Client && !isClientStream(streamId)) { throw QuicTransportException( "Attempted creating non-client stream on client", diff --git a/quic/state/QuicStreamManager.h b/quic/state/QuicStreamManager.h index 2bd680534..0cfb1d8e5 100644 --- a/quic/state/QuicStreamManager.h +++ b/quic/state/QuicStreamManager.h @@ -236,7 +236,7 @@ class QuicStreamManager { */ folly::Expected createStream( StreamId streamId, - Optional streamGroupId = none); + OptionalIntegral streamGroupId = std::nullopt); /* * Create a new bidirectional stream group. @@ -248,7 +248,8 @@ class QuicStreamManager { * Create and return the state for the next available bidirectional stream. */ folly::Expected - createNextBidirectionalStream(Optional streamGroupId = none); + createNextBidirectionalStream( + OptionalIntegral streamGroupId = std::nullopt); /* * Create a new unidirectional stream group. @@ -260,14 +261,16 @@ class QuicStreamManager { * Create and return the state for the next available unidirectional stream. */ folly::Expected - createNextUnidirectionalStream(Optional streamGroupId = none); + createNextUnidirectionalStream( + OptionalIntegral streamGroupId = std::nullopt); /* * Return the stream state or create it if the state has not yet been created. * Note that this is only valid for streams that are currently open. */ - QuicStreamState* FOLLY_NULLABLE - getStream(StreamId streamId, Optional streamGroupId = none); + QuicStreamState* FOLLY_NULLABLE getStream( + StreamId streamId, + OptionalIntegral streamGroupId = std::nullopt); /* * Remove all the state for a stream that is being closed. @@ -1058,7 +1061,7 @@ class QuicStreamManager { QuicStreamState* FOLLY_NULLABLE getOrCreatePeerStream( StreamId streamId, - Optional streamGroupId = none); + OptionalIntegral streamGroupId = std::nullopt); void setMaxRemoteBidirectionalStreamsInternal( uint64_t maxStreams, @@ -1071,8 +1074,9 @@ class QuicStreamManager { void notifyStreamPriorityChanges(); // helper to create a new peer stream. - QuicStreamState* FOLLY_NULLABLE - instantiatePeerStream(StreamId streamId, Optional groupId); + QuicStreamState* FOLLY_NULLABLE instantiatePeerStream( + StreamId streamId, + OptionalIntegral groupId); folly::Expected createNextStreamGroup( StreamGroupId& groupId, diff --git a/quic/state/SimpleFrameFunctions.cpp b/quic/state/SimpleFrameFunctions.cpp index be89c93ff..7f398d67d 100644 --- a/quic/state/SimpleFrameFunctions.cpp +++ b/quic/state/SimpleFrameFunctions.cpp @@ -282,7 +282,7 @@ bool updateSimpleFrameOnPacketReceived( return true; } case QuicSimpleFrame::Type::AckFrequencyFrame: { - if (!conn.transportSettings.minAckDelay.hasValue()) { + if (!conn.transportSettings.minAckDelay.has_value()) { // We do not accept ACK_FREQUENCY frames. This is a protocol // violation. throw QuicTransportException( diff --git a/quic/state/StateData.cpp b/quic/state/StateData.cpp index cc21098e9..557b2e0f5 100644 --- a/quic/state/StateData.cpp +++ b/quic/state/StateData.cpp @@ -45,7 +45,7 @@ QuicStreamState::QuicStreamState(StreamId idIn, QuicConnectionStateBase& connIn) QuicStreamState::QuicStreamState( StreamId idIn, - const Optional& groupIdIn, + const OptionalIntegral& groupIdIn, QuicConnectionStateBase& connIn) : QuicStreamState(idIn, connIn) { groupId = groupIdIn; diff --git a/quic/state/StateData.h b/quic/state/StateData.h index 2504ee693..720b93344 100644 --- a/quic/state/StateData.h +++ b/quic/state/StateData.h @@ -333,7 +333,7 @@ struct QuicConnectionStateBase : public folly::DelayedDestruction { // When server receives early data attempt without valid source address token, // server will limit bytes in flight to avoid amplification attack. // This limit should be cleared and set back to max after CFIN is received. - Optional writableBytesLimit; + OptionalIntegral writableBytesLimit; std::unique_ptr pathValidationLimiter; @@ -365,7 +365,7 @@ struct QuicConnectionStateBase : public folly::DelayedDestruction { // current (updated) phase. The peer must acknowledge this packet in the same // phase, responding in a different phase is a protocol violation. Once the // packet is acked, this value will be cleared. - Optional oneRttWritePendingVerificationPacketNumber; + OptionalIntegral oneRttWritePendingVerificationPacketNumber; // Write cipher for packets with initial keys. std::unique_ptr initialWriteCipher; @@ -511,7 +511,7 @@ struct QuicConnectionStateBase : public folly::DelayedDestruction { // The sum of length of data in all the stream buffers. uint64_t sumCurStreamBufferLen{0}; // The packet number in which we got the last largest max data. - Optional largestMaxOffsetReceived; + OptionalIntegral largestMaxOffsetReceived; // The following are advertised by the peer, and are set to zero initially // so that we cannot send any data until we know the peer values. // The initial max stream offset for peer-initiated bidirectional streams. @@ -547,7 +547,7 @@ struct QuicConnectionStateBase : public folly::DelayedDestruction { // The value of the peer's min_ack_delay, for creating ACK_FREQUENCY and // IMMEDIATE_ACK frames. - Optional peerMinAckDelay; + OptionalMicros peerMinAckDelay; // Idle timeout advertised by the peer. Initially sets it to the maximum value // until the handshake sets the timeout. @@ -677,7 +677,7 @@ struct QuicConnectionStateBase : public folly::DelayedDestruction { DatagramState datagramState; // Peer max stream groups advertised. - Optional peerAdvertisedMaxStreamGroups; + OptionalIntegral peerAdvertisedMaxStreamGroups; // Sequence number to use for the next ACK_FREQUENCY frame uint64_t nextAckFrequencyFrameSequenceNumber{0}; diff --git a/quic/state/StreamData.h b/quic/state/StreamData.h index 40579ae61..93b0021c8 100644 --- a/quic/state/StreamData.h +++ b/quic/state/StreamData.h @@ -284,7 +284,7 @@ struct QuicStreamState : public QuicStreamLike { QuicStreamState( StreamId idIn, - const Optional& groupIdIn, + const OptionalIntegral& groupIdIn, QuicConnectionStateBase& connIn); QuicStreamState(QuicStreamState&&) = default; @@ -324,7 +324,7 @@ struct QuicStreamState : public QuicStreamLike { StreamId id; // ID of the group the stream belongs to. - Optional groupId; + OptionalIntegral groupId; // Write side eof offset. This represents only the final FIN offset. Optional finalWriteOffset; diff --git a/quic/state/TransportSettings.h b/quic/state/TransportSettings.h index 60b39d296..cbaacfe14 100644 --- a/quic/state/TransportSettings.h +++ b/quic/state/TransportSettings.h @@ -225,7 +225,7 @@ struct TransportSettings { // The minimum amount of time in microseconds by which an ack can be delayed // Setting a value here also indicates to the peer that it can send // ACK_FREQUENCY and IMMEDIATE_ACK frames - Optional minAckDelay; + OptionalMicros minAckDelay; // Limits the amount of data that should be buffered in a QuicSocket. // If the amount of data in the buffer equals or exceeds this amount, then // the callback registered through notifyPendingWriteOnConnection() will @@ -362,7 +362,8 @@ struct TransportSettings { bool initiateKeyUpdate{false}; // How many packets to send before initiating the first key update. // This is reset to none after the first key update is initiated. - Optional firstKeyUpdatePacketCount{kFirstKeyUpdatePacketCount}; + OptionalIntegral firstKeyUpdatePacketCount{ + kFirstKeyUpdatePacketCount}; // How many packets to send before initiating periodic key updates uint64_t keyUpdatePacketCountInterval{kDefaultKeyUpdatePacketCountInterval}; diff --git a/quic/state/test/AckHandlersTest.cpp b/quic/state/test/AckHandlersTest.cpp index 4f6b4e1c1..d4f294d50 100644 --- a/quic/state/test/AckHandlersTest.cpp +++ b/quic/state/test/AckHandlersTest.cpp @@ -3360,7 +3360,7 @@ TEST_P(AckHandlersTest, AckEventCreationInvalidAckDelay) { ackTime - getSentTime(9)), ack->rttSample); EXPECT_EQ( - none, // ack delay > RTT, so not set + std::nullopt, // ack delay > RTT, so not set ack->rttSampleNoAckDelay); })); EXPECT_CALL(*rawCongestionController, getWritableBytes()) @@ -3637,8 +3637,8 @@ TEST_P(AckHandlersTest, AckEventCreationReorderingLargestPacketAcked) { Pointee( getAckPacketMatcher(4, getWriteCount(4), getSentTime(4)))); - EXPECT_EQ(none, ack->rttSample); // no RTT sample - EXPECT_EQ(none, ack->rttSampleNoAckDelay); // no RTT sample + EXPECT_EQ(std::nullopt, ack->rttSample); // no RTT sample + EXPECT_EQ(std::nullopt, ack->rttSampleNoAckDelay); // no RTT sample EXPECT_THAT(ack->ackedPackets, SizeIs(1)); EXPECT_THAT( ack->ackedPackets, @@ -3692,8 +3692,8 @@ TEST_P(AckHandlersTest, AckEventCreationReorderingLargestPacketAcked) { Pointee( getAckPacketMatcher(6, getWriteCount(6), getSentTime(6)))); - EXPECT_EQ(none, ack->rttSample); // no RTT sample - EXPECT_EQ(none, ack->rttSampleNoAckDelay); // no RTT sample + EXPECT_EQ(std::nullopt, ack->rttSample); // no RTT sample + EXPECT_EQ(std::nullopt, ack->rttSampleNoAckDelay); // no RTT sample EXPECT_THAT(ack->ackedPackets, SizeIs(2)); EXPECT_THAT( ack->ackedPackets,