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

Custom variant type for packetheader

Summary:
Make a custom variant type for PacketHeader. By not relying on boost::variant
this reduces the code size of the implementation.

This uses a combination of a union type as well as a enum type to emulate a variant

Reviewed By: yangchi

Differential Revision: D17187589

fbshipit-source-id: 00c2b9b8dd3f3e73af766d84888b13b9d867165a
This commit is contained in:
Subodh Iyengar
2019-09-19 17:30:13 -07:00
committed by Facebook Github Bot
parent c8da36d755
commit 04baa15a04
39 changed files with 593 additions and 641 deletions

View File

@@ -43,10 +43,10 @@ folly::Optional<PacketNum> AckScheduler::writeAcksImpl(
// Use default ack delay for long headers. Usually long headers are sent // Use default ack delay for long headers. Usually long headers are sent
// before crypto negotiation, so the peer might not know about the ack delay // before crypto negotiation, so the peer might not know about the ack delay
// exponent yet, so we use the default. // exponent yet, so we use the default.
uint8_t ackDelayExponentToUse = folly::variant_match( uint8_t ackDelayExponentToUse =
builder.getPacketHeader(), builder.getPacketHeader().getHeaderForm() == HeaderForm::Long
[](const LongHeader&) { return kDefaultAckDelayExponent; }, ? kDefaultAckDelayExponent
[&](const auto&) { return conn_.transportSettings.ackDelayExponent; }); : conn_.transportSettings.ackDelayExponent;
auto largestAckedPacketNum = *largestAckToSend(ackState_); auto largestAckedPacketNum = *largestAckToSend(ackState_);
auto ackingTime = ClockType::now(); auto ackingTime = ClockType::now();
DCHECK(ackState_.largestRecvdPacketTime.hasValue()) DCHECK(ackState_.largestRecvdPacketTime.hasValue())

View File

@@ -444,12 +444,9 @@ bool CryptoStreamScheduler::writeCryptoData(PacketBuilderInterface& builder) {
} }
} }
if (cryptoDataWritten && conn_.nodeType == QuicNodeType::Client) { if (cryptoDataWritten && conn_.nodeType == QuicNodeType::Client) {
bool initialPacket = folly::variant_match( const LongHeader* longHeader = builder.getPacketHeader().asLong();
builder.getPacketHeader(), bool initialPacket =
[](const LongHeader& header) { longHeader && longHeader->getHeaderType() == LongHeader::Types::Initial;
return header.getHeaderType() == LongHeader::Types::Initial;
},
[](const auto&) { return false; });
if (initialPacket) { if (initialPacket) {
// This is the initial packet, we need to fill er up. // This is the initial packet, we need to fill er up.
while (builder.remainingSpaceInPkt() > 0) { while (builder.remainingSpaceInPkt() > 0) {
@@ -521,9 +518,7 @@ CloningScheduler::scheduleFramesForPacket(
for (auto iter = conn_.outstandingPackets.rbegin(); for (auto iter = conn_.outstandingPackets.rbegin();
iter != conn_.outstandingPackets.rend(); iter != conn_.outstandingPackets.rend();
++iter) { ++iter) {
auto opPnSpace = folly::variant_match( auto opPnSpace = iter->packet.header.getPacketNumberSpace();
iter->packet.header,
[](const auto& h) { return h.getPacketNumberSpace(); });
if (opPnSpace != PacketNumberSpace::AppData) { if (opPnSpace != PacketNumberSpace::AppData) {
continue; continue;
} }
@@ -532,9 +527,7 @@ CloningScheduler::scheduleFramesForPacket(
// clone packet. So re-create a RegularQuicPacketBuilder every time. // clone packet. So re-create a RegularQuicPacketBuilder every time.
// TODO: We can avoid the copy & rebuild of the header by creating an // TODO: We can avoid the copy & rebuild of the header by creating an
// independent header builder. // independent header builder.
auto builderPnSpace = folly::variant_match( auto builderPnSpace = builder.getPacketHeader().getPacketNumberSpace();
builder.getPacketHeader(),
[](const auto& h) { return h.getPacketNumberSpace(); });
CHECK_EQ(builderPnSpace, PacketNumberSpace::AppData); CHECK_EQ(builderPnSpace, PacketNumberSpace::AppData);
RegularQuicPacketBuilder regularBuilder( RegularQuicPacketBuilder regularBuilder(
conn_.udpSendPacketLen, conn_.udpSendPacketLen,

View File

@@ -195,14 +195,12 @@ void updateConnection(
RegularQuicWritePacket packet, RegularQuicWritePacket packet,
TimePoint sentTime, TimePoint sentTime,
uint32_t encodedSize) { uint32_t encodedSize) {
auto packetNum = folly::variant_match( auto packetNum = packet.header.getPacketSequenceNum();
packet.header, [](const auto& h) { return h.getPacketSequenceNum(); });
bool retransmittable = false; // AckFrame and PaddingFrame are not retx-able. bool retransmittable = false; // AckFrame and PaddingFrame are not retx-able.
bool isHandshake = false; bool isHandshake = false;
uint32_t connWindowUpdateSent = 0; uint32_t connWindowUpdateSent = 0;
uint32_t ackFrameCounter = 0; uint32_t ackFrameCounter = 0;
auto packetNumberSpace = folly::variant_match( auto packetNumberSpace = packet.header.getPacketNumberSpace();
packet.header, [](const auto& h) { return h.getPacketNumberSpace(); });
VLOG(10) << nodeToString(conn.nodeType) << " sent packetNum=" << packetNum VLOG(10) << nodeToString(conn.nodeType) << " sent packetNum=" << packetNum
<< " in space=" << packetNumberSpace << " size=" << encodedSize << " in space=" << packetNumberSpace << " size=" << encodedSize
<< " " << conn; << " " << conn;
@@ -233,9 +231,7 @@ void updateConnection(
}, },
[&](const WriteCryptoFrame& writeCryptoFrame) { [&](const WriteCryptoFrame& writeCryptoFrame) {
retransmittable = true; retransmittable = true;
auto protectionType = folly::variant_match( auto protectionType = packet.header.getProtectionType();
packet.header,
[](const auto& h) { return h.getProtectionType(); });
// NewSessionTicket is sent in crypto frame encrypted with 1-rtt key, // NewSessionTicket is sent in crypto frame encrypted with 1-rtt key,
// however, it is not part of handshake // however, it is not part of handshake
isHandshake = isHandshake =
@@ -406,9 +402,7 @@ void updateConnection(
conn.outstandingPackets.end(), conn.outstandingPackets.end(),
packetNum, packetNum,
[&](const auto& packetWithTime, const auto& val) { [&](const auto& packetWithTime, const auto& val) {
return folly::variant_match( return packetWithTime.packet.header.getPacketSequenceNum() < val;
packetWithTime.packet.header,
[&val](const auto& h) { return h.getPacketSequenceNum() < val; });
}); });
conn.outstandingPackets.insert(packetIt, std::move(pkt)); conn.outstandingPackets.insert(packetIt, std::move(pkt));
@@ -453,14 +447,9 @@ HeaderBuilder LongHeaderBuilder(LongHeader::Types packetType) {
const ConnectionId& dstConnId, const ConnectionId& dstConnId,
PacketNum packetNum, PacketNum packetNum,
QuicVersion version, QuicVersion version,
Buf token) { const std::string& token) {
return LongHeader( return LongHeader(
packetType, packetType, srcConnId, dstConnId, packetNum, version, token);
srcConnId,
dstConnId,
packetNum,
version,
token ? std::move(token) : nullptr);
}; };
} }
@@ -469,7 +458,7 @@ HeaderBuilder ShortHeaderBuilder() {
const ConnectionId& dstConnId, const ConnectionId& dstConnId,
PacketNum packetNum, PacketNum packetNum,
QuicVersion, QuicVersion,
Buf) { const std::string&) {
return ShortHeader(ProtectionType::KeyPhaseZero, dstConnId, packetNum); return ShortHeader(ProtectionType::KeyPhaseZero, dstConnId, packetNum);
}; };
} }
@@ -557,7 +546,7 @@ uint64_t writeCryptoAndAckDataToSocket(
const PacketNumberCipher& headerCipher, const PacketNumberCipher& headerCipher,
QuicVersion version, QuicVersion version,
uint64_t packetLimit, uint64_t packetLimit,
Buf token) { const std::string& token) {
auto encryptionLevel = protectionTypeToEncryptionLevel( auto encryptionLevel = protectionTypeToEncryptionLevel(
longHeaderTypeToProtectionType(packetType)); longHeaderTypeToProtectionType(packetType));
FrameScheduler scheduler = FrameScheduler scheduler =
@@ -584,7 +573,7 @@ uint64_t writeCryptoAndAckDataToSocket(
cleartextCipher, cleartextCipher,
headerCipher, headerCipher,
version, version,
token ? std::move(token) : nullptr); token);
VLOG_IF(10, written > 0) << nodeToString(connection.nodeType) VLOG_IF(10, written > 0) << nodeToString(connection.nodeType)
<< " written crypto and acks data type=" << " written crypto and acks data type="
<< packetType << " packets=" << written << " " << packetType << " packets=" << written << " "
@@ -718,10 +707,9 @@ void writeCloseCommon(
const PacketNumberCipher& headerCipher) { const PacketNumberCipher& headerCipher) {
// close is special, we're going to bypass all the packet sent logic for all // close is special, we're going to bypass all the packet sent logic for all
// packets we send with a connection close frame. // packets we send with a connection close frame.
auto pnSpace = folly::variant_match( PacketNumberSpace pnSpace = header.getPacketNumberSpace();
header, [](const auto& h) { return h.getPacketNumberSpace(); }); HeaderForm headerForm = header.getHeaderForm();
PacketNum packetNum = folly::variant_match( PacketNum packetNum = header.getPacketSequenceNum();
header, [](const auto& h) { return h.getPacketSequenceNum(); });
RegularQuicPacketBuilder packetBuilder( RegularQuicPacketBuilder packetBuilder(
connection.udpSendPacketLen, connection.udpSendPacketLen,
std::move(header), std::move(header),
@@ -760,10 +748,6 @@ void writeCloseCommon(
auto packet = std::move(packetBuilder).buildPacket(); auto packet = std::move(packetBuilder).buildPacket();
auto body = auto body =
aead.encrypt(std::move(packet.body), packet.header.get(), packetNum); aead.encrypt(std::move(packet.body), packet.header.get(), packetNum);
HeaderForm headerForm = folly::variant_match(
header,
[](const ShortHeader&) { return HeaderForm::Short; },
[](const LongHeader&) { return HeaderForm::Long; });
encryptPacketHeader(headerForm, *packet.header, *body, headerCipher); encryptPacketHeader(headerForm, *packet.header, *body, headerCipher);
auto packetBuf = std::move(packet.header); auto packetBuf = std::move(packet.header);
packetBuf->prependChain(std::move(body)); packetBuf->prependChain(std::move(body));
@@ -891,7 +875,7 @@ uint64_t writeConnectionDataToSocket(
const Aead& aead, const Aead& aead,
const PacketNumberCipher& headerCipher, const PacketNumberCipher& headerCipher,
QuicVersion version, QuicVersion version,
Buf token) { const std::string& token) {
VLOG(10) << nodeToString(connection.nodeType) VLOG(10) << nodeToString(connection.nodeType)
<< " writing data using scheduler=" << scheduler.name() << " " << " writing data using scheduler=" << scheduler.name() << " "
<< connection; << connection;
@@ -917,12 +901,7 @@ uint64_t writeConnectionDataToSocket(
} }
while (scheduler.hasData() && ioBufBatch.getPktSent() < packetLimit) { while (scheduler.hasData() && ioBufBatch.getPktSent() < packetLimit) {
auto packetNum = getNextPacketNum(connection, pnSpace); auto packetNum = getNextPacketNum(connection, pnSpace);
auto header = builder( auto header = builder(srcConnId, dstConnId, packetNum, version, token);
srcConnId,
dstConnId,
packetNum,
version,
token ? token->clone() : nullptr);
uint32_t writableBytes = folly::to<uint32_t>(std::min<uint64_t>( uint32_t writableBytes = folly::to<uint32_t>(std::min<uint64_t>(
connection.udpSendPacketLen, writableBytesFunc(connection))); connection.udpSendPacketLen, writableBytesFunc(connection)));
uint64_t cipherOverhead = aead.getCipherOverhead(); uint64_t cipherOverhead = aead.getCipherOverhead();
@@ -954,10 +933,7 @@ uint64_t writeConnectionDataToSocket(
auto body = auto body =
aead.encrypt(std::move(packet->body), packet->header.get(), packetNum); aead.encrypt(std::move(packet->body), packet->header.get(), packetNum);
HeaderForm headerForm = folly::variant_match( HeaderForm headerForm = packet->packet.header.getHeaderForm();
packet->packet.header,
[](const LongHeader&) { return HeaderForm::Long; },
[](const ShortHeader&) { return HeaderForm::Short; });
encryptPacketHeader(headerForm, *packet->header, *body, headerCipher); encryptPacketHeader(headerForm, *packet->header, *body, headerCipher);
auto packetBuf = std::move(packet->header); auto packetBuf = std::move(packet->header);

View File

@@ -25,7 +25,7 @@ using HeaderBuilder = std::function<PacketHeader(
const ConnectionId& dstConnId, const ConnectionId& dstConnId,
PacketNum packetNum, PacketNum packetNum,
QuicVersion version, QuicVersion version,
Buf token)>; const std::string& token)>;
using WritableBytesFunc = using WritableBytesFunc =
std::function<uint64_t(const QuicConnectionStateBase& conn)>; std::function<uint64_t(const QuicConnectionStateBase& conn)>;
@@ -59,7 +59,7 @@ uint64_t writeCryptoAndAckDataToSocket(
const PacketNumberCipher& headerCipher, const PacketNumberCipher& headerCipher,
QuicVersion version, QuicVersion version,
uint64_t packetLimit, uint64_t packetLimit,
Buf token = nullptr); const std::string& token = std::string());
/** /**
* Writes out all the data streams without writing out crypto streams. * Writes out all the data streams without writing out crypto streams.
@@ -216,7 +216,7 @@ uint64_t writeConnectionDataToSocket(
const Aead& aead, const Aead& aead,
const PacketNumberCipher& headerCipher, const PacketNumberCipher& headerCipher,
QuicVersion version, QuicVersion version,
Buf token = nullptr); const std::string& token = std::string());
uint64_t writeProbingDataToSocket( uint64_t writeProbingDataToSocket(
folly::AsyncUDPSocket& sock, folly::AsyncUDPSocket& sock,

View File

@@ -376,7 +376,7 @@ TEST_F(QuicPacketSchedulerTest, WriteOnlyOutstandingPacketsTest) {
EXPECT_EQ(packetNum, *result.first); EXPECT_EQ(packetNum, *result.first);
// written packet (result.second) should not have any frame in the builder // written packet (result.second) should not have any frame in the builder
auto& writtenPacket = *result.second; auto& writtenPacket = *result.second;
auto shortHeader = boost::get<ShortHeader>(&writtenPacket.packet.header); auto shortHeader = writtenPacket.packet.header.asShort();
CHECK(shortHeader); CHECK(shortHeader);
EXPECT_EQ(ProtectionType::KeyPhaseOne, shortHeader->getProtectionType()); EXPECT_EQ(ProtectionType::KeyPhaseOne, shortHeader->getProtectionType());
EXPECT_EQ( EXPECT_EQ(
@@ -510,10 +510,10 @@ TEST_F(QuicPacketSchedulerTest, CloneSchedulerUseNormalSchedulerFirst) {
EXPECT_CALL(mockScheduler, _scheduleFramesForPacket(_, _)) EXPECT_CALL(mockScheduler, _scheduleFramesForPacket(_, _))
.Times(1) .Times(1)
.WillOnce( .WillOnce(Invoke(
Invoke([&, headerCopy = header]( [&, headerCopy = header](
std::unique_ptr<RegularQuicPacketBuilder>&, uint32_t) { std::unique_ptr<RegularQuicPacketBuilder>&, uint32_t) mutable {
RegularQuicWritePacket packet(headerCopy); RegularQuicWritePacket packet(std::move(headerCopy));
packet.frames.push_back(MaxDataFrame(2832)); packet.frames.push_back(MaxDataFrame(2832));
RegularQuicPacketBuilder::Packet builtPacket( RegularQuicPacketBuilder::Packet builtPacket(
std::move(packet), std::move(packet),
@@ -528,17 +528,12 @@ TEST_F(QuicPacketSchedulerTest, CloneSchedulerUseNormalSchedulerFirst) {
auto result = cloningScheduler.scheduleFramesForPacket( auto result = cloningScheduler.scheduleFramesForPacket(
std::move(builder), kDefaultUDPSendPacketLen); std::move(builder), kDefaultUDPSendPacketLen);
EXPECT_EQ(folly::none, result.first); EXPECT_EQ(folly::none, result.first);
folly::variant_match( EXPECT_EQ(result.second->packet.header.getHeaderForm(), HeaderForm::Short);
result.second->packet.header, ShortHeader& shortHeader = *result.second->packet.header.asShort();
[&](const ShortHeader& shortHeader) { EXPECT_EQ(ProtectionType::KeyPhaseOne, shortHeader.getProtectionType());
EXPECT_EQ(ProtectionType::KeyPhaseOne, shortHeader.getProtectionType()); EXPECT_EQ(
EXPECT_EQ( conn.ackStates.appDataAckState.nextPacketNum,
conn.ackStates.appDataAckState.nextPacketNum, shortHeader.getPacketSequenceNum());
shortHeader.getPacketSequenceNum());
},
[&](const LongHeader&) {
ASSERT_FALSE(true); // should not happen
});
EXPECT_EQ(1, result.second->packet.frames.size()); EXPECT_EQ(1, result.second->packet.frames.size());
folly::variant_match( folly::variant_match(
result.second->packet.frames.front(), result.second->packet.frames.front(),

View File

@@ -385,28 +385,20 @@ TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionPacketSorting) {
EXPECT_EQ(3, conn->outstandingPackets.size()); EXPECT_EQ(3, conn->outstandingPackets.size());
auto& firstHeader = conn->outstandingPackets.front().packet.header; auto& firstHeader = conn->outstandingPackets.front().packet.header;
auto firstPacketNum = folly::variant_match( auto firstPacketNum = firstHeader.getPacketSequenceNum();
firstHeader, [](const auto& h) { return h.getPacketSequenceNum(); });
EXPECT_EQ(0, firstPacketNum); EXPECT_EQ(0, firstPacketNum);
EXPECT_EQ(1, event1->packetNum); EXPECT_EQ(1, event1->packetNum);
EXPECT_EQ( EXPECT_EQ(PacketNumberSpace::Initial, firstHeader.getPacketNumberSpace());
PacketNumberSpace::Initial,
folly::variant_match(
firstHeader, [](const auto& h) { return h.getPacketNumberSpace(); }));
auto& lastHeader = conn->outstandingPackets.back().packet.header; auto& lastHeader = conn->outstandingPackets.back().packet.header;
auto lastPacketNum = folly::variant_match( auto lastPacketNum = lastHeader.getPacketSequenceNum();
lastHeader, [](const auto& h) { return h.getPacketSequenceNum(); });
EXPECT_EQ(2, lastPacketNum); EXPECT_EQ(2, lastPacketNum);
EXPECT_EQ(2, event3->packetNum); EXPECT_EQ(2, event3->packetNum);
EXPECT_EQ( EXPECT_EQ(PacketNumberSpace::AppData, lastHeader.getPacketNumberSpace());
PacketNumberSpace::AppData,
folly::variant_match(
lastHeader, [](const auto& h) { return h.getPacketNumberSpace(); }));
} }
TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionFinOnly) { TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionFinOnly) {
@@ -891,9 +883,7 @@ TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionStreamWindowUpdate) {
auto conn = createConn(); auto conn = createConn();
conn->qLogger = std::make_shared<quic::FileQLogger>(); conn->qLogger = std::make_shared<quic::FileQLogger>();
auto packet = buildEmptyPacket(*conn, PacketNumberSpace::Handshake); auto packet = buildEmptyPacket(*conn, PacketNumberSpace::Handshake);
auto packetNum = folly::variant_match( auto packetNum = packet.packet.header.getPacketSequenceNum();
packet.packet.header,
[](const auto& h) { return h.getPacketSequenceNum(); });
auto stream = conn->streamManager->createNextBidirectionalStream().value(); auto stream = conn->streamManager->createNextBidirectionalStream().value();
MaxStreamDataFrame streamWindowUpdate(stream->id, 0); MaxStreamDataFrame streamWindowUpdate(stream->id, 0);
conn->streamManager->queueWindowUpdate(stream->id); conn->streamManager->queueWindowUpdate(stream->id);
@@ -928,9 +918,7 @@ TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionConnWindowUpdate) {
auto conn = createConn(); auto conn = createConn();
conn->qLogger = std::make_shared<quic::FileQLogger>(); conn->qLogger = std::make_shared<quic::FileQLogger>();
auto packet = buildEmptyPacket(*conn, PacketNumberSpace::Handshake); auto packet = buildEmptyPacket(*conn, PacketNumberSpace::Handshake);
auto packetNum = folly::variant_match( auto packetNum = packet.packet.header.getPacketSequenceNum();
packet.packet.header,
[](const auto& h) { return h.getPacketSequenceNum(); });
conn->pendingEvents.connWindowUpdate = true; conn->pendingEvents.connWindowUpdate = true;
auto stream = conn->streamManager->createNextBidirectionalStream().value(); auto stream = conn->streamManager->createNextBidirectionalStream().value();
MaxDataFrame connWindowUpdate(conn->flowControlState.advertisedMaxOffset); MaxDataFrame connWindowUpdate(conn->flowControlState.advertisedMaxOffset);

View File

@@ -845,8 +845,7 @@ TEST_F(QuicTransportTest, WritePendingAckIfHavingData) {
EXPECT_EQ(conn.ackStates.appDataAckState.largestAckScheduled, end); EXPECT_EQ(conn.ackStates.appDataAckState.largestAckScheduled, end);
// Verify ack state after writing // Verify ack state after writing
auto pnSpace = folly::variant_match( auto pnSpace = packet.header.getPacketNumberSpace();
packet.header, [](const auto& h) { return h.getPacketNumberSpace(); });
auto ackState = getAckState(conn, pnSpace); auto ackState = getAckState(conn, pnSpace);
EXPECT_EQ(ackState.largestAckScheduled, end); EXPECT_EQ(ackState.largestAckScheduled, end);
EXPECT_FALSE(ackState.needsToSendAckImmediately); EXPECT_FALSE(ackState.needsToSendAckImmediately);

View File

@@ -152,15 +152,11 @@ void QuicClientTransport::processPacketData(
return; return;
} }
bool longHeader = folly::variant_match( LongHeader* longHeader = regularOptional->header.asLong();
regularOptional->header, ShortHeader* shortHeader = regularOptional->header.asShort();
[](const LongHeader&) { return true; },
[](const ShortHeader&) { return false; });
if (longHeader && if (longHeader && longHeader->getHeaderType() == LongHeader::Types::Retry) {
boost::get<LongHeader>(regularOptional->header).getHeaderType() == if (!clientConn_->retryToken.empty()) {
LongHeader::Types::Retry) {
if (clientConn_->retryToken_) {
VLOG(4) << "Server sent more than one retry packet"; VLOG(4) << "Server sent more than one retry packet";
return; return;
} }
@@ -175,14 +171,12 @@ void QuicClientTransport::processPacketData(
// better approach, but I don't know if it is a good indicator that we've // better approach, but I don't know if it is a good indicator that we've
// received an initial packet from the server. // received an initial packet from the server.
auto header = boost::get<LongHeader>(regularOptional->header);
const ConnectionId* dstConnId = const ConnectionId* dstConnId =
&(*clientConn_->initialDestinationConnectionId); &(*clientConn_->initialDestinationConnectionId);
if (conn_->serverConnectionId) { if (conn_->serverConnectionId) {
dstConnId = &(*conn_->serverConnectionId); dstConnId = &(*conn_->serverConnectionId);
} }
if (*header.getOriginalDstConnId() != *dstConnId) { if (*longHeader->getOriginalDstConnId() != *dstConnId) {
VLOG(4) << "Original destination connection id field in the retry " VLOG(4) << "Original destination connection id field in the retry "
<< "packet doesn't match the destination connection id from the " << "packet doesn't match the destination connection id from the "
<< "client's initial packet"; << "client's initial packet";
@@ -191,7 +185,7 @@ void QuicClientTransport::processPacketData(
// Set the destination connection ID to be the value from the source // Set the destination connection ID to be the value from the source
// connection id of the retry packet // connection id of the retry packet
clientConn_->initialDestinationConnectionId = header.getSourceConnId(); clientConn_->initialDestinationConnectionId = longHeader->getSourceConnId();
auto released = static_cast<QuicClientConnectionState*>(conn_.release()); auto released = static_cast<QuicClientConnectionState*>(conn_.release());
std::unique_ptr<QuicClientConnectionState> uniqueClient(released); std::unique_ptr<QuicClientConnectionState> uniqueClient(released);
@@ -200,7 +194,7 @@ void QuicClientTransport::processPacketData(
clientConn_ = tempConn.get(); clientConn_ = tempConn.get();
conn_ = std::move(tempConn); conn_ = std::move(tempConn);
clientConn_->retryToken_ = header.getToken()->clone(); clientConn_->retryToken = longHeader->getToken();
if (conn_->qLogger) { if (conn_->qLogger) {
conn_->qLogger->addPacket(*regularOptional, packetSize); conn_->qLogger->addPacket(*regularOptional, packetSize);
@@ -210,18 +204,11 @@ void QuicClientTransport::processPacketData(
return; return;
} }
auto protectionLevel = folly::variant_match( auto protectionLevel = regularOptional->header.getProtectionType();
regularOptional->header,
[](auto& header) { return header.getProtectionType(); });
auto encryptionLevel = protectionTypeToEncryptionLevel(protectionLevel); auto encryptionLevel = protectionTypeToEncryptionLevel(protectionLevel);
auto packetNum = folly::variant_match( auto packetNum = regularOptional->header.getPacketSequenceNum();
regularOptional->header, auto pnSpace = regularOptional->header.getPacketNumberSpace();
[](const auto& h) { return h.getPacketSequenceNum(); });
auto pnSpace = folly::variant_match(
regularOptional->header,
[](auto& header) { return header.getPacketNumberSpace(); });
bool isProtectedPacket = protectionLevel == ProtectionType::KeyPhaseZero || bool isProtectedPacket = protectionLevel == ProtectionType::KeyPhaseZero ||
protectionLevel == ProtectionType::KeyPhaseOne; protectionLevel == ProtectionType::KeyPhaseOne;
@@ -255,31 +242,21 @@ void QuicClientTransport::processPacketData(
} }
if (!conn_->serverConnectionId && longHeader) { if (!conn_->serverConnectionId && longHeader) {
folly::Optional<ConnectionId> receivedSrcConnId(folly::variant_match( conn_->serverConnectionId = longHeader->getSourceConnId();
regularOptional->header,
[&](const LongHeader& h) -> folly::Optional<ConnectionId> {
return h.getSourceConnId();
},
[](const ShortHeader&) -> folly::Optional<ConnectionId> {
return folly::none;
}));
// Assign the conn id to the server chosen connid.
if (!receivedSrcConnId) {
throw QuicTransportException(
"Expected long header with connection-id",
TransportErrorCode::PROTOCOL_VIOLATION);
}
conn_->serverConnectionId = std::move(receivedSrcConnId);
conn_->readCodec->setServerConnectionId(*conn_->serverConnectionId); conn_->readCodec->setServerConnectionId(*conn_->serverConnectionId);
} }
// Error out if the connection id on the packet is not the one that is // Error out if the connection id on the packet is not the one that is
// expected. // expected.
if (folly::variant_match( bool connidMatched = true;
regularOptional->header, if (longHeader && longHeader->getDestinationConnId() != *conn_->clientConnectionId) {
[](const LongHeader& h) { return h.getDestinationConnId(); }, connidMatched = false;
[](const ShortHeader& h) { return h.getConnectionId(); }) != } else if (
*conn_->clientConnectionId) { shortHeader &&
shortHeader->getConnectionId() != *conn_->clientConnectionId) {
connidMatched = false;
}
if (!connidMatched) {
throw QuicTransportException( throw QuicTransportException(
"Invalid connection id", TransportErrorCode::PROTOCOL_VIOLATION); "Invalid connection id", TransportErrorCode::PROTOCOL_VIOLATION);
} }
@@ -303,9 +280,8 @@ void QuicClientTransport::processPacketData(
[&](const OutstandingPacket& outstandingPacket, [&](const OutstandingPacket& outstandingPacket,
const QuicWriteFrame& packetFrame, const QuicWriteFrame& packetFrame,
const ReadAckFrame&) { const ReadAckFrame&) {
auto outstandingProtectionType = folly::variant_match( auto outstandingProtectionType =
outstandingPacket.packet.header, outstandingPacket.packet.header.getProtectionType();
[](const auto& h) { return h.getProtectionType(); });
if (outstandingProtectionType == ProtectionType::KeyPhaseZero) { if (outstandingProtectionType == ProtectionType::KeyPhaseZero) {
// If we received an ack for data that we sent in 1-rtt from // If we received an ack for data that we sent in 1-rtt from
// the server, we can assume that the server had successfully // the server, we can assume that the server had successfully
@@ -734,7 +710,7 @@ void QuicClientTransport::writeData() {
*conn_->initialHeaderCipher, *conn_->initialHeaderCipher,
version, version,
packetLimit, packetLimit,
clientConn_->retryToken_ ? clientConn_->retryToken_->clone() : nullptr); clientConn_->retryToken);
} }
if (!packetLimit) { if (!packetLimit) {
return; return;

View File

@@ -43,7 +43,7 @@ struct QuicClientConnectionState : public QuicConnectionStateBase {
folly::Optional<StatelessResetToken> statelessResetToken; folly::Optional<StatelessResetToken> statelessResetToken;
// The retry token sent by the server. // The retry token sent by the server.
Buf retryToken_{nullptr}; std::string retryToken;
// Initial destination connection id. // Initial destination connection id.
folly::Optional<ConnectionId> initialDestinationConnectionId; folly::Optional<ConnectionId> initialDestinationConnectionId;

View File

@@ -1514,9 +1514,7 @@ class QuicClientTransportTest : public Test {
if (!parsedPacket) { if (!parsedPacket) {
continue; continue;
} }
PacketNum packetNumSent = folly::variant_match( PacketNum packetNumSent = parsedPacket->header.getPacketSequenceNum();
parsedPacket->header,
[](auto& h) { return h.getPacketSequenceNum(); });
sentPackets.insert(packetNumSent); sentPackets.insert(packetNumSent);
verifyShortHeader(*write); verifyShortHeader(*write);
} }
@@ -1533,7 +1531,7 @@ class QuicClientTransportTest : public Test {
if (!parsedPacket) { if (!parsedPacket) {
return false; return false;
} }
auto longHeader = boost::get<LongHeader>(&parsedPacket->header); auto longHeader = parsedPacket->header.asLong();
return longHeader && longHeader->getHeaderType() == headerType; return longHeader && longHeader->getHeaderType() == headerType;
} }
@@ -1546,7 +1544,7 @@ class QuicClientTransportTest : public Test {
if (!parsedPacket) { if (!parsedPacket) {
return false; return false;
} }
return boost::get<ShortHeader>(&parsedPacket->header) != nullptr; return parsedPacket->header.asShort();
} }
std::unique_ptr<QuicReadCodec> makeHandshakeCodec() { std::unique_ptr<QuicReadCodec> makeHandshakeCodec() {
@@ -2716,16 +2714,12 @@ TEST_F(QuicClientTransportAfterStartTest, CloseConnectionWithStreamPending) {
ASSERT_FALSE(client->getConn().outstandingPackets.empty()); ASSERT_FALSE(client->getConn().outstandingPackets.empty());
IntervalSet<quic::PacketNum> acks; IntervalSet<quic::PacketNum> acks;
auto start = folly::variant_match( auto start = getFirstOutstandingPacket(
getFirstOutstandingPacket( client->getNonConstConn(), PacketNumberSpace::AppData)
client->getNonConstConn(), PacketNumberSpace::AppData) ->packet.header.getPacketSequenceNum();
->packet.header, auto end = getLastOutstandingPacket(
[](auto& h) { return h.getPacketSequenceNum(); }); client->getNonConstConn(), PacketNumberSpace::AppData)
auto end = folly::variant_match( ->packet.header.getPacketSequenceNum();
getLastOutstandingPacket(
client->getNonConstConn(), PacketNumberSpace::AppData)
->packet.header,
[](auto& h) { return h.getPacketSequenceNum(); });
acks.insert(start, end); acks.insert(start, end);
auto ackPacket = packetToBuf(createAckPacket( auto ackPacket = packetToBuf(createAckPacket(
@@ -2795,16 +2789,12 @@ TEST_F(QuicClientTransportAfterStartTest, CloseConnectionWithNoStreamPending) {
ASSERT_FALSE(client->getConn().outstandingPackets.empty()); ASSERT_FALSE(client->getConn().outstandingPackets.empty());
IntervalSet<quic::PacketNum> acks; IntervalSet<quic::PacketNum> acks;
auto start = folly::variant_match( auto start = getFirstOutstandingPacket(
getFirstOutstandingPacket( client->getNonConstConn(), PacketNumberSpace::AppData)
client->getNonConstConn(), PacketNumberSpace::AppData) ->packet.header.getPacketSequenceNum();
->packet.header, auto end = getLastOutstandingPacket(
[](auto& h) { return h.getPacketSequenceNum(); }); client->getNonConstConn(), PacketNumberSpace::AppData)
auto end = folly::variant_match( ->packet.header.getPacketSequenceNum();
getLastOutstandingPacket(
client->getNonConstConn(), PacketNumberSpace::AppData)
->packet.header,
[](auto& h) { return h.getPacketSequenceNum(); });
acks.insert(start, end); acks.insert(start, end);
auto ackPacket = packetToBuf(createAckPacket( auto ackPacket = packetToBuf(createAckPacket(
@@ -2925,16 +2915,12 @@ TEST_F(QuicClientTransportAfterStartTest, RecvAckOfCryptoStream) {
// initial // initial
{ {
IntervalSet<quic::PacketNum> acks; IntervalSet<quic::PacketNum> acks;
auto start = folly::variant_match( auto start = getFirstOutstandingPacket(
getFirstOutstandingPacket( client->getNonConstConn(), PacketNumberSpace::Initial)
client->getNonConstConn(), PacketNumberSpace::Initial) ->packet.header.getPacketSequenceNum();
->packet.header, auto end = getLastOutstandingPacket(
[](auto& h) { return h.getPacketSequenceNum(); }); client->getNonConstConn(), PacketNumberSpace::Initial)
auto end = folly::variant_match( ->packet.header.getPacketSequenceNum();
getLastOutstandingPacket(
client->getNonConstConn(), PacketNumberSpace::Initial)
->packet.header,
[](auto& h) { return h.getPacketSequenceNum(); });
acks.insert(start, end); acks.insert(start, end);
auto pn = initialPacketNum++; auto pn = initialPacketNum++;
auto ackPkt = createAckPacket( auto ackPkt = createAckPacket(
@@ -2948,16 +2934,12 @@ TEST_F(QuicClientTransportAfterStartTest, RecvAckOfCryptoStream) {
// handshake // handshake
{ {
IntervalSet<quic::PacketNum> acks; IntervalSet<quic::PacketNum> acks;
auto start = folly::variant_match( auto start = getFirstOutstandingPacket(
getFirstOutstandingPacket( client->getNonConstConn(), PacketNumberSpace::Handshake)
client->getNonConstConn(), PacketNumberSpace::Handshake) ->packet.header.getPacketSequenceNum();
->packet.header, auto end = getLastOutstandingPacket(
[](auto& h) { return h.getPacketSequenceNum(); }); client->getNonConstConn(), PacketNumberSpace::Handshake)
auto end = folly::variant_match( ->packet.header.getPacketSequenceNum();
getLastOutstandingPacket(
client->getNonConstConn(), PacketNumberSpace::Handshake)
->packet.header,
[](auto& h) { return h.getPacketSequenceNum(); });
acks.insert(start, end); acks.insert(start, end);
auto pn = handshakePacketNum++; auto pn = handshakePacketNum++;
auto ackPkt = createAckPacket( auto ackPkt = createAckPacket(
@@ -3209,8 +3191,7 @@ TEST_F(QuicClientTransportAfterStartTest, IdleTimerResetNoOutstandingPackets) {
// This will clear out all the outstanding packets // This will clear out all the outstanding packets
IntervalSet<PacketNum> sentPackets; IntervalSet<PacketNum> sentPackets;
for (auto& packet : client->getNonConstConn().outstandingPackets) { for (auto& packet : client->getNonConstConn().outstandingPackets) {
auto packetNum = folly::variant_match( auto packetNum = packet.packet.header.getPacketSequenceNum();
packet.packet.header, [](auto& h) { return h.getPacketSequenceNum(); });
sentPackets.insert(packetNum); sentPackets.insert(packetNum);
} }
auto ackPacket = packetToBuf(createAckPacket( auto ackPacket = packetToBuf(createAckPacket(
@@ -3659,7 +3640,7 @@ TEST_F(QuicClientTransportVersionAndRetryTest, RetryPacket) {
*originalConnId, *originalConnId,
321, 321,
QuicVersion::MVFST, QuicVersion::MVFST,
IOBuf::copyBuffer("this is a retry token :)"), std::string("this is a retry token :)"),
*client->getConn().initialDestinationConnectionId); *client->getConn().initialDestinationConnectionId);
RegularQuicPacketBuilder builder( RegularQuicPacketBuilder builder(
@@ -3683,7 +3664,7 @@ TEST_F(QuicClientTransportVersionAndRetryTest, RetryPacket) {
auto quicPacket = boost::get<QuicPacket>(&codecResult); auto quicPacket = boost::get<QuicPacket>(&codecResult);
auto regularQuicPacket = boost::get<RegularQuicPacket>(quicPacket); auto regularQuicPacket = boost::get<RegularQuicPacket>(quicPacket);
auto header = boost::get<LongHeader>(regularQuicPacket->header); auto& header = *regularQuicPacket->header.asLong();
std::vector<int> indices = std::vector<int> indices =
getQLogEventIndices(QLogEventType::PacketReceived, qLogger); getQLogEventIndices(QLogEventType::PacketReceived, qLogger);
@@ -3694,10 +3675,7 @@ TEST_F(QuicClientTransportVersionAndRetryTest, RetryPacket) {
EXPECT_EQ(header.getHeaderType(), LongHeader::Types::Initial); EXPECT_EQ(header.getHeaderType(), LongHeader::Types::Initial);
EXPECT_TRUE(header.hasToken()); EXPECT_TRUE(header.hasToken());
folly::IOBufEqualTo eq; EXPECT_EQ(header.getToken(), std::string("this is a retry token :)"));
EXPECT_TRUE(
eq(header.getToken()->clone(),
IOBuf::copyBuffer("this is a retry token :)")));
EXPECT_EQ(header.getDestinationConnId(), serverChosenConnId); EXPECT_EQ(header.getDestinationConnId(), serverChosenConnId);
eventbase_->loopOnce(); eventbase_->loopOnce();
@@ -3903,9 +3881,7 @@ TEST_F(QuicClientTransportAfterStartTest, ResetClearsPendingLoss) {
RegularQuicWritePacket* forceLossPacket = RegularQuicWritePacket* forceLossPacket =
CHECK_NOTNULL(findPacketWithStream(client->getNonConstConn(), streamId)); CHECK_NOTNULL(findPacketWithStream(client->getNonConstConn(), streamId));
auto packetNum = folly::variant_match( auto packetNum = forceLossPacket->header.getPacketSequenceNum();
forceLossPacket->header,
[](const auto& h) { return h.getPacketSequenceNum(); });
markPacketLoss(client->getNonConstConn(), *forceLossPacket, false, packetNum); markPacketLoss(client->getNonConstConn(), *forceLossPacket, false, packetNum);
auto& pendingLossStreams = client->getConn().streamManager->lossStreams(); auto& pendingLossStreams = client->getConn().streamManager->lossStreams();
auto it = auto it =
@@ -3932,9 +3908,7 @@ TEST_F(QuicClientTransportAfterStartTest, LossAfterResetStream) {
RegularQuicWritePacket* forceLossPacket = RegularQuicWritePacket* forceLossPacket =
CHECK_NOTNULL(findPacketWithStream(client->getNonConstConn(), streamId)); CHECK_NOTNULL(findPacketWithStream(client->getNonConstConn(), streamId));
auto packetNum = folly::variant_match( auto packetNum = forceLossPacket->header.getPacketSequenceNum();
forceLossPacket->header,
[](const auto& h) { return h.getPacketSequenceNum(); });
markPacketLoss(client->getNonConstConn(), *forceLossPacket, false, packetNum); markPacketLoss(client->getNonConstConn(), *forceLossPacket, false, packetNum);
auto stream = CHECK_NOTNULL( auto stream = CHECK_NOTNULL(
client->getNonConstConn().streamManager->getStream(streamId)); client->getNonConstConn().streamManager->getStream(streamId));
@@ -4427,12 +4401,8 @@ class QuicZeroRttClientTest : public QuicClientTransportAfterStartTest {
bool zeroRttPacketsOutstanding() { bool zeroRttPacketsOutstanding() {
for (auto& packet : client->getNonConstConn().outstandingPackets) { for (auto& packet : client->getNonConstConn().outstandingPackets) {
bool isZeroRtt = folly::variant_match( bool isZeroRtt =
packet.packet.header, packet.packet.header.getProtectionType() == ProtectionType::ZeroRtt;
[](const LongHeader& h) {
return h.getProtectionType() == ProtectionType::ZeroRtt;
},
[](const ShortHeader&) { return false; });
if (isZeroRtt) { if (isZeroRtt) {
return true; return true;
} }

View File

@@ -104,10 +104,9 @@ ReadAckFrame decodeAckFrame(
// and ack delay, the sender has to use something, so they use the default // and ack delay, the sender has to use something, so they use the default
// ack delay. To keep it consistent the protocol specifies using the same // ack delay. To keep it consistent the protocol specifies using the same
// ack delay for all the long header packets. // ack delay for all the long header packets.
uint8_t ackDelayExponentToUse = folly::variant_match( uint8_t ackDelayExponentToUse = (header.getHeaderForm() == HeaderForm::Long)
header, ? kDefaultAckDelayExponent
[](const LongHeader&) { return kDefaultAckDelayExponent; }, : params.peerAckDelayExponent;
[&params](auto&) { return params.peerAckDelayExponent; });
DCHECK_LT(ackDelayExponentToUse, sizeof(ackDelay->first) * 8); DCHECK_LT(ackDelayExponentToUse, sizeof(ackDelay->first) * 8);
// ackDelayExponentToUse is guaranteed to be less than the size of uint64_t // ackDelayExponentToUse is guaranteed to be less than the size of uint64_t
uint64_t delayOverflowMask = 0xFFFFFFFFFFFFFFFF; uint64_t delayOverflowMask = 0xFFFFFFFFFFFFFFFF;
@@ -986,7 +985,7 @@ folly::Expected<ParsedLongHeader, TransportErrorCode> parseLongHeaderVariants(
LongHeader( LongHeader(
type, type,
std::move(parsedLongHeaderInvariant.invariant), std::move(parsedLongHeaderInvariant.invariant),
std::move(token), token ? token->moveToFbString().toStdString() : std::string(),
std::move(originalDstConnId)), std::move(originalDstConnId)),
PacketLength(0, 0)); PacketLength(0, 0));
} }
@@ -1037,7 +1036,7 @@ folly::Expected<ParsedLongHeader, TransportErrorCode> parseLongHeaderVariants(
LongHeader( LongHeader(
type, type,
std::move(parsedLongHeaderInvariant.invariant), std::move(parsedLongHeaderInvariant.invariant),
std::move(token)), token ? token->moveToFbString().toStdString() : std::string()),
PacketLength(pktLen->first, pktLen->second)); PacketLength(pktLen->first, pktLen->second));
} }

View File

@@ -17,6 +17,7 @@ namespace quic {
struct ParsedHeaderResult { struct ParsedHeaderResult {
bool isVersionNegotiation; bool isVersionNegotiation;
folly::Optional<PacketHeader> parsedHeader; folly::Optional<PacketHeader> parsedHeader;
ParsedHeaderResult( ParsedHeaderResult(
bool isVersionNegotiationIn, bool isVersionNegotiationIn,
folly::Optional<PacketHeader> parsedHeaderIn); folly::Optional<PacketHeader> parsedHeaderIn);

View File

@@ -47,9 +47,9 @@ PacketNumEncodingResult encodeLongHeaderHelper(
appender.writeBE<uint8_t>(initialByte); appender.writeBE<uint8_t>(initialByte);
bool isInitial = longHeader.getHeaderType() == LongHeader::Types::Initial; bool isInitial = longHeader.getHeaderType() == LongHeader::Types::Initial;
uint64_t tokenHeaderLength = 0; uint64_t tokenHeaderLength = 0;
auto token = longHeader.getToken(); const std::string& token = longHeader.getToken();
if (isInitial) { if (isInitial) {
uint64_t tokenLength = token ? token->coalesce().size() : 0; uint64_t tokenLength = token.size();
QuicInteger tokenLengthInt(tokenLength); QuicInteger tokenLengthInt(tokenLength);
tokenHeaderLength = tokenLengthInt.getSize() + tokenLength; tokenHeaderLength = tokenLengthInt.getSize() + tokenLength;
} }
@@ -99,11 +99,11 @@ PacketNumEncodingResult encodeLongHeaderHelper(
} }
if (isInitial) { if (isInitial) {
uint64_t tokenLength = token ? token->coalesce().size() : 0; uint64_t tokenLength = token.size();
QuicInteger tokenLengthInt(tokenLength); QuicInteger tokenLengthInt(tokenLength);
tokenLengthInt.encode(appender); tokenLengthInt.encode(appender);
if (tokenLength > 0) { if (tokenLength > 0) {
appender.push(token->coalesce()); appender.push(folly::StringPiece(token.data(), token.size()));
} }
} }
@@ -113,8 +113,8 @@ PacketNumEncodingResult encodeLongHeaderHelper(
appender.push(originalDstConnId->data(), originalDstConnId->size()); appender.push(originalDstConnId->data(), originalDstConnId->size());
// Write the retry token // Write the retry token
CHECK(token) << "Retry packet must contain a token"; CHECK(!token.empty()) << "Retry packet must contain a token";
appender.insert(*token); appender.push(folly::StringPiece(token.data(), token.size()));
} }
// defer write of the packet num and length till payload has been computed // defer write of the packet num and length till payload has been computed
return encodedPacketNum; return encodedPacketNum;
@@ -188,10 +188,7 @@ void RegularQuicPacketBuilder::appendFrame(QuicWriteFrame frame) {
RegularQuicPacketBuilder::Packet RegularQuicPacketBuilder::buildPacket() && { RegularQuicPacketBuilder::Packet RegularQuicPacketBuilder::buildPacket() && {
// at this point everything should been set in the packet_ // at this point everything should been set in the packet_
bool isLongHeader = folly::variant_match( LongHeader* longHeader = packet_.header.asLong();
packet_.header,
[](const LongHeader&) { return true; },
[](const ShortHeader&) { return false; });
size_t minBodySize = kMaxPacketNumEncodingSize - size_t minBodySize = kMaxPacketNumEncodingSize -
packetNumberEncoding_->length + sizeof(Sample); packetNumberEncoding_->length + sizeof(Sample);
while (outputQueue_.chainLength() + cipherOverhead_ < minBodySize && while (outputQueue_.chainLength() + cipherOverhead_ < minBodySize &&
@@ -201,9 +198,7 @@ RegularQuicPacketBuilder::Packet RegularQuicPacketBuilder::buildPacket() && {
write(paddingType); write(paddingType);
} }
packet_.frames = std::move(quicFrames_); packet_.frames = std::move(quicFrames_);
if (isLongHeader && if (longHeader && longHeader->getHeaderType() != LongHeader::Types::Retry) {
boost::get<LongHeader>(packet_.header).getHeaderType() !=
LongHeader::Types::Retry) {
QuicInteger pktLen( QuicInteger pktLen(
packetNumberEncoding_->length + outputQueue_.chainLength() + packetNumberEncoding_->length + outputQueue_.chainLength() +
cipherOverhead_); cipherOverhead_);
@@ -218,11 +213,11 @@ RegularQuicPacketBuilder::Packet RegularQuicPacketBuilder::buildPacket() && {
void RegularQuicPacketBuilder::writeHeaderBytes( void RegularQuicPacketBuilder::writeHeaderBytes(
PacketNum largestAckedPacketNum) { PacketNum largestAckedPacketNum) {
if (packet_.header.type() == typeid(LongHeader)) { if (packet_.header.getHeaderForm() == HeaderForm::Long) {
LongHeader& longHeader = boost::get<LongHeader>(packet_.header); LongHeader& longHeader = *packet_.header.asLong();
encodeLongHeader(longHeader, largestAckedPacketNum); encodeLongHeader(longHeader, largestAckedPacketNum);
} else { } else {
ShortHeader& shortHeader = boost::get<ShortHeader>(packet_.header); ShortHeader& shortHeader = *packet_.header.asShort();
encodeShortHeader(shortHeader, largestAckedPacketNum); encodeShortHeader(shortHeader, largestAckedPacketNum);
} }
} }

View File

@@ -30,8 +30,7 @@ PacketEvent PacketRebuilder::cloneOutstandingPacket(OutstandingPacket& packet) {
!packet.associatedEvent || !packet.associatedEvent ||
conn_.outstandingPacketEvents.count(*packet.associatedEvent)); conn_.outstandingPacketEvents.count(*packet.associatedEvent));
if (!packet.associatedEvent) { if (!packet.associatedEvent) {
auto packetNum = folly::variant_match( auto packetNum = packet.packet.header.getPacketSequenceNum();
packet.packet.header, [](auto& h) { return h.getPacketSequenceNum(); });
DCHECK(!conn_.outstandingPacketEvents.count(packetNum)); DCHECK(!conn_.outstandingPacketEvents.count(packetNum));
packet.associatedEvent = packetNum; packet.associatedEvent = packetNum;
conn_.outstandingPacketEvents.insert(packetNum); conn_.outstandingPacketEvents.insert(packetNum);
@@ -57,12 +56,11 @@ folly::Optional<PacketEvent> PacketRebuilder::rebuildFromPacket(
writeSuccess = folly::variant_match( writeSuccess = folly::variant_match(
frame, frame,
[&](const WriteAckFrame& ackFrame) { [&](const WriteAckFrame& ackFrame) {
uint64_t ackDelayExponent = folly::variant_match( auto& packetHeader = builder_.getPacketHeader();
builder_.getPacketHeader(), uint64_t ackDelayExponent =
[](const LongHeader&) { return kDefaultAckDelayExponent; }, (packetHeader.getHeaderForm() == HeaderForm::Long)
[&](const auto&) { ? kDefaultAckDelayExponent
return conn_.transportSettings.ackDelayExponent; : conn_.transportSettings.ackDelayExponent;
});
AckFrameMetaData meta( AckFrameMetaData meta(
ackFrame.ackBlocks, ackFrame.ackDelay, ackDelayExponent); ackFrame.ackBlocks, ackFrame.ackDelay, ackDelayExponent);
auto ackWriteResult = writeAckFrame(meta, builder_); auto ackWriteResult = writeAckFrame(meta, builder_);
@@ -99,10 +97,10 @@ folly::Optional<PacketEvent> PacketRebuilder::rebuildFromPacket(
// initialStream and handshakeStream can only be in handshake packet, // initialStream and handshakeStream can only be in handshake packet,
// so they are not clonable // so they are not clonable
CHECK(!packet.isHandshake); CHECK(!packet.isHandshake);
folly::variant_match(packet.packet.header, [](const auto& header) { // key update not supported
// key update not supported DCHECK(
CHECK(header.getProtectionType() == ProtectionType::KeyPhaseZero); packet.packet.header.getProtectionType() ==
}); ProtectionType::KeyPhaseZero);
auto& stream = conn_.cryptoState->oneRttStream; auto& stream = conn_.cryptoState->oneRttStream;
auto buf = cloneCryptoRetransmissionBuffer(cryptoFrame, stream); auto buf = cloneCryptoRetransmissionBuffer(cryptoFrame, stream);

View File

@@ -24,15 +24,158 @@ HeaderForm getHeaderForm(uint8_t headerValue) {
return HeaderForm::Short; return HeaderForm::Short;
} }
PacketHeader::PacketHeader(ShortHeader&& shortHeaderIn)
: headerForm_(HeaderForm::Short) {
new (&shortHeader) ShortHeader(std::move(shortHeaderIn));
}
PacketHeader::PacketHeader(LongHeader&& longHeaderIn)
: headerForm_(HeaderForm::Long) {
new (&longHeader) LongHeader(std::move(longHeaderIn));
}
PacketHeader::PacketHeader(const PacketHeader& other)
: headerForm_(other.headerForm_) {
switch (other.headerForm_) {
case HeaderForm::Long:
new (&longHeader) LongHeader(other.longHeader);
break;
case HeaderForm::Short:
new (&shortHeader) ShortHeader(other.shortHeader);
break;
}
}
PacketHeader::PacketHeader(PacketHeader&& other) noexcept
: headerForm_(other.headerForm_) {
switch (other.headerForm_) {
case HeaderForm::Long:
new (&longHeader) LongHeader(std::move(other.longHeader));
break;
case HeaderForm::Short:
new (&shortHeader) ShortHeader(std::move(other.shortHeader));
break;
}
}
PacketHeader& PacketHeader::operator=(PacketHeader&& other) noexcept {
destroyHeader();
switch (other.headerForm_) {
case HeaderForm::Long:
new (&longHeader) LongHeader(std::move(other.longHeader));
break;
case HeaderForm::Short:
new (&shortHeader) ShortHeader(std::move(other.shortHeader));
break;
}
headerForm_ = other.headerForm_;
return *this;
}
PacketHeader& PacketHeader::operator=(const PacketHeader& other) {
destroyHeader();
switch (other.headerForm_) {
case HeaderForm::Long:
new (&longHeader) LongHeader(other.longHeader);
break;
case HeaderForm::Short:
new (&shortHeader) ShortHeader(other.shortHeader);
break;
}
headerForm_ = other.headerForm_;
return *this;
}
PacketHeader::~PacketHeader() {
destroyHeader();
}
void PacketHeader::destroyHeader() {
switch (headerForm_) {
case HeaderForm::Long:
longHeader.~LongHeader();
break;
case HeaderForm::Short:
shortHeader.~ShortHeader();
break;
}
}
LongHeader* PacketHeader::asLong() {
switch (headerForm_) {
case HeaderForm::Long:
return &longHeader;
case HeaderForm::Short:
return nullptr;
}
}
ShortHeader* PacketHeader::asShort() {
switch (headerForm_) {
case HeaderForm::Long:
return nullptr;
case HeaderForm::Short:
return &shortHeader;
}
}
const LongHeader* PacketHeader::asLong() const {
switch (headerForm_) {
case HeaderForm::Long:
return &longHeader;
case HeaderForm::Short:
return nullptr;
}
}
const ShortHeader* PacketHeader::asShort() const {
switch (headerForm_) {
case HeaderForm::Long:
return nullptr;
case HeaderForm::Short:
return &shortHeader;
}
}
PacketNum PacketHeader::getPacketSequenceNum() const {
switch (headerForm_) {
case HeaderForm::Long:
return longHeader.getPacketSequenceNum();
case HeaderForm::Short:
return shortHeader.getPacketSequenceNum();
}
}
HeaderForm PacketHeader::getHeaderForm() const {
return headerForm_;
}
ProtectionType PacketHeader::getProtectionType() const {
switch (headerForm_) {
case HeaderForm::Long:
return longHeader.getProtectionType();
case HeaderForm::Short:
return shortHeader.getProtectionType();
}
}
PacketNumberSpace PacketHeader::getPacketNumberSpace() const {
switch (headerForm_) {
case HeaderForm::Long:
return longHeader.getPacketNumberSpace();
case HeaderForm::Short:
return shortHeader.getPacketNumberSpace();
}
}
LongHeader::LongHeader( LongHeader::LongHeader(
Types type, Types type,
LongHeaderInvariant invariant, LongHeaderInvariant invariant,
Buf token, const std::string& token,
folly::Optional<ConnectionId> originalDstConnId) folly::Optional<ConnectionId> originalDstConnId)
: headerForm_(HeaderForm::Long), : longHeaderType_(type),
longHeaderType_(type),
invariant_(std::move(invariant)), invariant_(std::move(invariant)),
token_(std::move(token)), token_(token),
originalDstConnId_(originalDstConnId) {} originalDstConnId_(originalDstConnId) {}
LongHeader::LongHeader( LongHeader::LongHeader(
@@ -41,40 +184,13 @@ LongHeader::LongHeader(
const ConnectionId& dstConnId, const ConnectionId& dstConnId,
PacketNum packetNum, PacketNum packetNum,
QuicVersion version, QuicVersion version,
Buf token, const std::string& token,
folly::Optional<ConnectionId> originalDstConnId) folly::Optional<ConnectionId> originalDstConnId)
: headerForm_(HeaderForm::Long), : longHeaderType_(type),
longHeaderType_(type),
invariant_(LongHeaderInvariant(version, srcConnId, dstConnId)), invariant_(LongHeaderInvariant(version, srcConnId, dstConnId)),
packetSequenceNum_(packetNum), token_(token),
token_(token ? std::move(token) : nullptr), originalDstConnId_(originalDstConnId) {
originalDstConnId_(originalDstConnId) {} setPacketNumber(packetNum);
LongHeader::LongHeader(const LongHeader& other)
: headerForm_(other.headerForm_),
longHeaderType_(other.longHeaderType_),
invariant_(other.invariant_),
packetSequenceNum_(other.packetSequenceNum_),
originalDstConnId_(other.originalDstConnId_) {
if (other.token_) {
token_ = other.token_->clone();
}
}
void LongHeader::setPacketNumber(PacketNum packetNum) {
packetSequenceNum_ = packetNum;
}
LongHeader& LongHeader::operator=(const LongHeader& other) {
headerForm_ = other.headerForm_;
longHeaderType_ = other.longHeaderType_;
invariant_ = other.invariant_;
packetSequenceNum_ = other.packetSequenceNum_;
originalDstConnId_ = other.originalDstConnId_;
if (other.token_) {
token_ = other.token_->clone();
}
return *this;
} }
LongHeader::Types LongHeader::getHeaderType() const noexcept { LongHeader::Types LongHeader::getHeaderType() const noexcept {
@@ -93,27 +209,31 @@ const folly::Optional<ConnectionId>& LongHeader::getOriginalDstConnId() const {
return originalDstConnId_; return originalDstConnId_;
} }
PacketNum LongHeader::getPacketSequenceNum() const {
return *packetSequenceNum_;
}
QuicVersion LongHeader::getVersion() const { QuicVersion LongHeader::getVersion() const {
return invariant_.version; return invariant_.version;
} }
bool LongHeader::hasToken() const { bool LongHeader::hasToken() const {
return token_ ? true : false; return !token_.empty();
} }
folly::IOBuf* LongHeader::getToken() const { const std::string& LongHeader::getToken() const {
return token_.get(); return token_;
}
PacketNum LongHeader::getPacketSequenceNum() const {
return packetSequenceNum_;
}
void LongHeader::setPacketNumber(PacketNum packetNum) {
packetSequenceNum_ = packetNum;
} }
ProtectionType LongHeader::getProtectionType() const { ProtectionType LongHeader::getProtectionType() const {
return longHeaderTypeToProtectionType(getHeaderType()); return longHeaderTypeToProtectionType(getHeaderType());
} }
PacketNumberSpace LongHeader::getPacketNumberSpace() const noexcept { PacketNumberSpace LongHeader::getPacketNumberSpace() const {
return longHeaderTypeToPacketNumberSpace(getHeaderType()); return longHeaderTypeToPacketNumberSpace(getHeaderType());
} }
@@ -152,21 +272,17 @@ ShortHeader::ShortHeader(
ProtectionType protectionType, ProtectionType protectionType,
ConnectionId connId, ConnectionId connId,
PacketNum packetNum) PacketNum packetNum)
: headerForm_(HeaderForm::Short), : protectionType_(protectionType), connectionId_(std::move(connId)) {
protectionType_(protectionType),
connectionId_(std::move(connId)),
packetSequenceNum_(packetNum) {
if (protectionType_ != ProtectionType::KeyPhaseZero && if (protectionType_ != ProtectionType::KeyPhaseZero &&
protectionType_ != ProtectionType::KeyPhaseOne) { protectionType_ != ProtectionType::KeyPhaseOne) {
throw QuicInternalException( throw QuicInternalException(
"bad short header protection type", LocalErrorCode::CODEC_ERROR); "bad short header protection type", LocalErrorCode::CODEC_ERROR);
} }
setPacketNumber(packetNum);
} }
ShortHeader::ShortHeader(ProtectionType protectionType, ConnectionId connId) ShortHeader::ShortHeader(ProtectionType protectionType, ConnectionId connId)
: headerForm_(HeaderForm::Short), : protectionType_(protectionType), connectionId_(std::move(connId)) {
protectionType_(protectionType),
connectionId_(std::move(connId)) {
if (protectionType_ != ProtectionType::KeyPhaseZero && if (protectionType_ != ProtectionType::KeyPhaseZero &&
protectionType_ != ProtectionType::KeyPhaseOne) { protectionType_ != ProtectionType::KeyPhaseOne) {
throw QuicInternalException( throw QuicInternalException(
@@ -174,11 +290,11 @@ ShortHeader::ShortHeader(ProtectionType protectionType, ConnectionId connId)
} }
} }
ProtectionType ShortHeader::getProtectionType() const noexcept { ProtectionType ShortHeader::getProtectionType() const {
return protectionType_; return protectionType_;
} }
PacketNumberSpace ShortHeader::getPacketNumberSpace() const noexcept { PacketNumberSpace ShortHeader::getPacketNumberSpace() const {
return PacketNumberSpace::AppData; return PacketNumberSpace::AppData;
} }
@@ -187,7 +303,7 @@ const ConnectionId& ShortHeader::getConnectionId() const {
} }
PacketNum ShortHeader::getPacketSequenceNum() const { PacketNum ShortHeader::getPacketSequenceNum() const {
return *packetSequenceNum_; return packetSequenceNum_;
} }
void ShortHeader::setPacketNumber(PacketNum packetNum) { void ShortHeader::setPacketNumber(PacketNum packetNum) {

View File

@@ -627,6 +627,8 @@ struct LongHeaderInvariant {
// TODO: split this into read and write types. // TODO: split this into read and write types.
struct LongHeader { struct LongHeader {
public: public:
virtual ~LongHeader() = default;
static constexpr uint8_t kFixedBitMask = 0x40; static constexpr uint8_t kFixedBitMask = 0x40;
static constexpr uint8_t kPacketTypeMask = 0x30; static constexpr uint8_t kPacketTypeMask = 0x30;
static constexpr uint8_t kReservedBitsMask = 0x0c; static constexpr uint8_t kReservedBitsMask = 0x0c;
@@ -647,40 +649,33 @@ struct LongHeader {
const ConnectionId& dstConnId, const ConnectionId& dstConnId,
PacketNum packetNum, PacketNum packetNum,
QuicVersion version, QuicVersion version,
Buf token = nullptr, const std::string& token = std::string(),
folly::Optional<ConnectionId> originalDstConnId = folly::none); folly::Optional<ConnectionId> originalDstConnId = folly::none);
LongHeader( LongHeader(
Types type, Types type,
LongHeaderInvariant invariant, LongHeaderInvariant invariant,
Buf token = nullptr, const std::string& token = std::string(),
folly::Optional<ConnectionId> originalDstConnId = folly::none); folly::Optional<ConnectionId> originalDstConnId = folly::none);
void setPacketNumber(PacketNum packetNum);
// Stuff stored in a variant type needs to be copyable.
// TODO: can we make this copyable only by the variant, but not
// by anyone else.
LongHeader(const LongHeader& other);
LongHeader& operator=(const LongHeader& other);
Types getHeaderType() const noexcept; Types getHeaderType() const noexcept;
const ConnectionId& getSourceConnId() const; const ConnectionId& getSourceConnId() const;
const ConnectionId& getDestinationConnId() const; const ConnectionId& getDestinationConnId() const;
const folly::Optional<ConnectionId>& getOriginalDstConnId() const; const folly::Optional<ConnectionId>& getOriginalDstConnId() const;
PacketNum getPacketSequenceNum() const;
QuicVersion getVersion() const; QuicVersion getVersion() const;
PacketNumberSpace getPacketNumberSpace() const;
ProtectionType getProtectionType() const; ProtectionType getProtectionType() const;
PacketNumberSpace getPacketNumberSpace() const noexcept;
bool hasToken() const; bool hasToken() const;
folly::IOBuf* getToken() const; const std::string& getToken() const;
PacketNum getPacketSequenceNum() const;
void setPacketNumber(PacketNum packetNum);
private: private:
HeaderForm headerForm_; PacketNum packetSequenceNum_{0};
Types longHeaderType_; Types longHeaderType_;
LongHeaderInvariant invariant_; LongHeaderInvariant invariant_;
folly::Optional<PacketNum> packetSequenceNum_; // at most 32 bits on wire std::string token_;
Buf token_;
folly::Optional<ConnectionId> originalDstConnId_; folly::Optional<ConnectionId> originalDstConnId_;
}; };
@@ -692,6 +687,8 @@ struct ShortHeaderInvariant {
struct ShortHeader { struct ShortHeader {
public: public:
virtual ~ShortHeader() = default;
// There is also a spin bit which is 0x20 that we don't currently implement. // There is also a spin bit which is 0x20 that we don't currently implement.
static constexpr uint8_t kFixedBitMask = 0x40; static constexpr uint8_t kFixedBitMask = 0x40;
static constexpr uint8_t kReservedBitsMask = 0x18; static constexpr uint8_t kReservedBitsMask = 0x18;
@@ -712,11 +709,10 @@ struct ShortHeader {
ConnectionId connId, ConnectionId connId,
PacketNum packetNum); PacketNum packetNum);
ProtectionType getProtectionType() const noexcept; ProtectionType getProtectionType() const;
PacketNumberSpace getPacketNumberSpace() const noexcept; PacketNumberSpace getPacketNumberSpace() const;
const ConnectionId& getConnectionId() const;
PacketNum getPacketSequenceNum() const; PacketNum getPacketSequenceNum() const;
const ConnectionId& getConnectionId() const;
void setPacketNumber(PacketNum packetNum); void setPacketNumber(PacketNum packetNum);
@@ -729,16 +725,48 @@ struct ShortHeader {
folly::io::Cursor& cursor); folly::io::Cursor& cursor);
private: private:
HeaderForm headerForm_; PacketNum packetSequenceNum_{0};
ProtectionType protectionType_; ProtectionType protectionType_;
ConnectionId connectionId_; ConnectionId connectionId_;
folly::Optional<PacketNum> packetSequenceNum_; // var-size 8/16/24/32 bits };
struct PacketHeader {
~PacketHeader();
/* implicit */ PacketHeader(LongHeader&& longHeader);
/* implicit */ PacketHeader(ShortHeader&& shortHeader);
PacketHeader(PacketHeader&& other) noexcept;
PacketHeader(const PacketHeader& other);
PacketHeader& operator=(PacketHeader&& other) noexcept;
PacketHeader& operator=(const PacketHeader& other);
LongHeader* asLong();
ShortHeader* asShort();
const LongHeader* asLong() const;
const ShortHeader* asShort() const;
PacketNum getPacketSequenceNum() const;
HeaderForm getHeaderForm() const;
ProtectionType getProtectionType() const;
PacketNumberSpace getPacketNumberSpace() const;
private:
void destroyHeader();
union {
LongHeader longHeader;
ShortHeader shortHeader;
};
HeaderForm headerForm_;
}; };
ProtectionType longHeaderTypeToProtectionType(LongHeader::Types type); ProtectionType longHeaderTypeToProtectionType(LongHeader::Types type);
PacketNumberSpace longHeaderTypeToPacketNumberSpace(LongHeader::Types type);
using PacketHeader = boost::variant<LongHeader, ShortHeader>; PacketNumberSpace longHeaderTypeToPacketNumberSpace(LongHeader::Types type);
struct StreamTypeField { struct StreamTypeField {
public: public:
@@ -791,8 +819,7 @@ struct VersionNegotiationPacket {
struct RegularPacket { struct RegularPacket {
PacketHeader header; PacketHeader header;
explicit RegularPacket(PacketHeader&& headerIn) explicit RegularPacket(PacketHeader&& headerIn) : header(std::move(headerIn)) {}
: header(std::move(headerIn)) {}
}; };
/** /**
@@ -842,17 +869,16 @@ inline std::ostream& operator<<(
} }
inline std::ostream& operator<<(std::ostream& os, const PacketHeader& header) { inline std::ostream& operator<<(std::ostream& os, const PacketHeader& header) {
folly::variant_match( auto shortHeader = header.asShort();
header, if (shortHeader) {
[&os](const LongHeader& h) { os << "header=short"
os << "header=long" << " protectionType=" << (int)shortHeader->getProtectionType();
<< " protectionType=" << (int)h.getProtectionType() } else {
<< " type=" << std::hex << (int)h.getHeaderType(); auto longHeader = header.asLong();
}, os << "header=long"
[&os](const ShortHeader& h) { << " protectionType=" << (int)longHeader->getProtectionType()
os << "header=short" << " type=" << std::hex << (int)longHeader->getHeaderType();
<< " protectionType=" << (int)h.getProtectionType(); }
});
return os; return os;
} }

View File

@@ -361,7 +361,6 @@ TEST_F(DecodeTest, AckFrameMissingFields) {
ackBlocks.emplace_back(QuicInteger(10), QuicInteger(10)); ackBlocks.emplace_back(QuicInteger(10), QuicInteger(10));
ackBlocks.emplace_back(QuicInteger(10), QuicInteger(10)); ackBlocks.emplace_back(QuicInteger(10), QuicInteger(10));
auto header = makeHeader();
auto result1 = createAckFrame( auto result1 = createAckFrame(
largestAcked, largestAcked,
folly::none, folly::none,
@@ -373,7 +372,7 @@ TEST_F(DecodeTest, AckFrameMissingFields) {
EXPECT_THROW( EXPECT_THROW(
decodeAckFrame( decodeAckFrame(
cursor1, cursor1,
header, makeHeader(),
CodecParameters(kDefaultAckDelayExponent, QuicVersion::MVFST)), CodecParameters(kDefaultAckDelayExponent, QuicVersion::MVFST)),
QuicTransportException); QuicTransportException);
@@ -383,7 +382,7 @@ TEST_F(DecodeTest, AckFrameMissingFields) {
EXPECT_THROW( EXPECT_THROW(
decodeAckFrame( decodeAckFrame(
cursor2, cursor2,
header, makeHeader(),
CodecParameters(kDefaultAckDelayExponent, QuicVersion::MVFST)), CodecParameters(kDefaultAckDelayExponent, QuicVersion::MVFST)),
QuicTransportException); QuicTransportException);
@@ -393,7 +392,7 @@ TEST_F(DecodeTest, AckFrameMissingFields) {
EXPECT_THROW( EXPECT_THROW(
decodeAckFrame( decodeAckFrame(
cursor3, cursor3,
header, makeHeader(),
CodecParameters(kDefaultAckDelayExponent, QuicVersion::MVFST)), CodecParameters(kDefaultAckDelayExponent, QuicVersion::MVFST)),
QuicTransportException); QuicTransportException);
@@ -403,7 +402,7 @@ TEST_F(DecodeTest, AckFrameMissingFields) {
EXPECT_THROW( EXPECT_THROW(
decodeAckFrame( decodeAckFrame(
cursor4, cursor4,
header, makeHeader(),
CodecParameters(kDefaultAckDelayExponent, QuicVersion::MVFST)), CodecParameters(kDefaultAckDelayExponent, QuicVersion::MVFST)),
QuicTransportException); QuicTransportException);
@@ -413,7 +412,7 @@ TEST_F(DecodeTest, AckFrameMissingFields) {
EXPECT_THROW( EXPECT_THROW(
decodeAckFrame( decodeAckFrame(
cursor5, cursor5,
header, makeHeader(),
CodecParameters(kDefaultAckDelayExponent, QuicVersion::MVFST)), CodecParameters(kDefaultAckDelayExponent, QuicVersion::MVFST)),
QuicTransportException); QuicTransportException);
} }

View File

@@ -56,17 +56,12 @@ TEST_F(QuicHeaderCodecTest, ShortHeaderTest) {
auto packet = std::move(builder).buildPacket(); auto packet = std::move(builder).buildPacket();
auto result = parseHeader(*packet.header); auto result = parseHeader(*packet.header);
auto& header = result->parsedHeader; auto& header = result->parsedHeader;
LongHeader* longHeader = header->asLong();
EXPECT_EQ( if (longHeader) {
getTestConnectionId(), EXPECT_EQ(getTestConnectionId(), longHeader->getDestinationConnId());
folly::variant_match( } else {
header.value(), EXPECT_EQ(getTestConnectionId(), header->asShort()->getConnectionId());
[](const LongHeader& longHeader) { }
return longHeader.getDestinationConnId();
},
[](const ShortHeader& shortHeader) {
return shortHeader.getConnectionId();
}));
} }
} // namespace test } // namespace test
} // namespace quic } // namespace quic

View File

@@ -121,7 +121,7 @@ TEST_F(QuicPacketBuilderTest, SimpleRetryPacket) {
getTestConnectionId(1), getTestConnectionId(1),
321, 321,
QuicVersion::MVFST, QuicVersion::MVFST,
folly::IOBuf::copyBuffer("454358"), std::string("454358"),
getTestConnectionId(2)); getTestConnectionId(2));
RegularQuicPacketBuilder builder( RegularQuicPacketBuilder builder(
@@ -140,16 +140,15 @@ TEST_F(QuicPacketBuilderTest, SimpleRetryPacket) {
EXPECT_NO_THROW(boost::get<RegularQuicPacket>(decodedPacket)); EXPECT_NO_THROW(boost::get<RegularQuicPacket>(decodedPacket));
auto retryPacket = boost::get<RegularQuicPacket>(decodedPacket); auto retryPacket = boost::get<RegularQuicPacket>(decodedPacket);
auto headerOut = boost::get<LongHeader>(retryPacket.header); auto& headerOut = *retryPacket.header.asLong();
EXPECT_EQ(*headerOut.getOriginalDstConnId(), getTestConnectionId(2)); EXPECT_EQ(*headerOut.getOriginalDstConnId(), getTestConnectionId(2));
EXPECT_EQ(headerOut.getVersion(), QuicVersion::MVFST); EXPECT_EQ(headerOut.getVersion(), QuicVersion::MVFST);
EXPECT_EQ(headerOut.getSourceConnId(), getTestConnectionId(0)); EXPECT_EQ(headerOut.getSourceConnId(), getTestConnectionId(0));
EXPECT_EQ(headerOut.getDestinationConnId(), getTestConnectionId(1)); EXPECT_EQ(headerOut.getDestinationConnId(), getTestConnectionId(1));
folly::IOBufEqualTo eq; auto expected = std::string("454358");
auto expectedBuf = folly::IOBuf::copyBuffer("454358"); EXPECT_EQ(headerOut.getToken(), expected);
EXPECT_TRUE(eq(*headerOut.getToken(), *expectedBuf));
} }
TEST_F(QuicPacketBuilderTest, TooManyVersions) { TEST_F(QuicPacketBuilderTest, TooManyVersions) {
@@ -210,8 +209,8 @@ TEST_F(QuicPacketBuilderTest, LongHeaderRegularPacket) {
auto resultBuf = packetToBufCleartext( auto resultBuf = packetToBufCleartext(
resultRegularPacket, *cleartextAead, *headerCipher, pktNum); resultRegularPacket, *cleartextAead, *headerCipher, pktNum);
auto& resultHeader = resultRegularPacket.packet.header; auto& resultHeader = resultRegularPacket.packet.header;
EXPECT_NO_THROW(boost::get<LongHeader>(resultHeader)); EXPECT_NE(resultHeader.asLong(), nullptr);
auto& resultLongHeader = boost::get<LongHeader>(resultHeader); auto& resultLongHeader = *resultHeader.asLong();
EXPECT_EQ(LongHeader::Types::Initial, resultLongHeader.getHeaderType()); EXPECT_EQ(LongHeader::Types::Initial, resultLongHeader.getHeaderType());
EXPECT_EQ(serverConnId, resultLongHeader.getSourceConnId()); EXPECT_EQ(serverConnId, resultLongHeader.getSourceConnId());
EXPECT_EQ(pktNum, resultLongHeader.getPacketSequenceNum()); EXPECT_EQ(pktNum, resultLongHeader.getPacketSequenceNum());
@@ -225,7 +224,7 @@ TEST_F(QuicPacketBuilderTest, LongHeaderRegularPacket) {
auto decodedPacket = boost::get<QuicPacket>(optionalDecodedPacket); auto decodedPacket = boost::get<QuicPacket>(optionalDecodedPacket);
EXPECT_NO_THROW(boost::get<RegularQuicPacket>(decodedPacket)); EXPECT_NO_THROW(boost::get<RegularQuicPacket>(decodedPacket));
auto decodedRegularPacket = boost::get<RegularQuicPacket>(decodedPacket); auto decodedRegularPacket = boost::get<RegularQuicPacket>(decodedPacket);
auto& decodedHeader = boost::get<LongHeader>(decodedRegularPacket.header); auto& decodedHeader = *decodedRegularPacket.header.asLong();
EXPECT_EQ(LongHeader::Types::Initial, decodedHeader.getHeaderType()); EXPECT_EQ(LongHeader::Types::Initial, decodedHeader.getHeaderType());
EXPECT_EQ(clientConnId, decodedHeader.getDestinationConnId()); EXPECT_EQ(clientConnId, decodedHeader.getDestinationConnId());
EXPECT_EQ(pktNum, decodedHeader.getPacketSequenceNum()); EXPECT_EQ(pktNum, decodedHeader.getPacketSequenceNum());
@@ -240,7 +239,7 @@ TEST_F(QuicPacketBuilderTest, ShortHeaderRegularPacket) {
auto encodedPacketNum = encodePacketNumber(pktNum, largestAckedPacketNum); auto encodedPacketNum = encodePacketNumber(pktNum, largestAckedPacketNum);
RegularQuicPacketBuilder builder( RegularQuicPacketBuilder builder(
kDefaultUDPSendPacketLen, kDefaultUDPSendPacketLen,
PacketHeader(ShortHeader(ProtectionType::KeyPhaseZero, connId, pktNum)), ShortHeader(ProtectionType::KeyPhaseZero, connId, pktNum),
largestAckedPacketNum); largestAckedPacketNum);
// write out at least one frame // write out at least one frame
@@ -255,7 +254,7 @@ TEST_F(QuicPacketBuilderTest, ShortHeaderRegularPacket) {
EXPECT_EQ(builtOut.body->computeChainDataLength(), expectedOutputSize); EXPECT_EQ(builtOut.body->computeChainDataLength(), expectedOutputSize);
auto resultBuf = packetToBuf(builtOut); auto resultBuf = packetToBuf(builtOut);
auto resultShortHeader = boost::get<ShortHeader>(resultRegularPacket.header); auto& resultShortHeader = *resultRegularPacket.header.asShort();
EXPECT_EQ( EXPECT_EQ(
ProtectionType::KeyPhaseZero, resultShortHeader.getProtectionType()); ProtectionType::KeyPhaseZero, resultShortHeader.getProtectionType());
EXPECT_EQ(connId, resultShortHeader.getConnectionId()); EXPECT_EQ(connId, resultShortHeader.getConnectionId());
@@ -270,7 +269,7 @@ TEST_F(QuicPacketBuilderTest, ShortHeaderRegularPacket) {
->parsePacket(packetQueue, ackStates); ->parsePacket(packetQueue, ackStates);
auto decodedPacket = boost::get<QuicPacket>(parsedPacket); auto decodedPacket = boost::get<QuicPacket>(parsedPacket);
auto decodedRegularPacket = boost::get<RegularQuicPacket>(decodedPacket); auto decodedRegularPacket = boost::get<RegularQuicPacket>(decodedPacket);
auto decodedHeader = boost::get<ShortHeader>(decodedRegularPacket.header); auto& decodedHeader = *decodedRegularPacket.header.asShort();
EXPECT_EQ(ProtectionType::KeyPhaseZero, decodedHeader.getProtectionType()); EXPECT_EQ(ProtectionType::KeyPhaseZero, decodedHeader.getProtectionType());
EXPECT_EQ(connId, decodedHeader.getConnectionId()); EXPECT_EQ(connId, decodedHeader.getConnectionId());
EXPECT_EQ(pktNum, decodedHeader.getPacketSequenceNum()); EXPECT_EQ(pktNum, decodedHeader.getPacketSequenceNum());
@@ -284,7 +283,7 @@ TEST_F(QuicPacketBuilderTest, ShortHeaderWithNoFrames) {
// frames already and will be too small to parse. // frames already and will be too small to parse.
RegularQuicPacketBuilder builder( RegularQuicPacketBuilder builder(
kDefaultUDPSendPacketLen, kDefaultUDPSendPacketLen,
PacketHeader(ShortHeader(ProtectionType::KeyPhaseZero, connId, pktNum)), ShortHeader(ProtectionType::KeyPhaseZero, connId, pktNum),
0 /* largestAcked */); 0 /* largestAcked */);
EXPECT_TRUE(builder.canBuildPacket()); EXPECT_TRUE(builder.canBuildPacket());
auto builtOut = std::move(builder).buildPacket(); auto builtOut = std::move(builder).buildPacket();
@@ -312,7 +311,7 @@ TEST_F(QuicPacketBuilderTest, TestPaddingAccountsForCipherOverhead) {
size_t cipherOverhead = 2; size_t cipherOverhead = 2;
RegularQuicPacketBuilder builder( RegularQuicPacketBuilder builder(
kDefaultUDPSendPacketLen, kDefaultUDPSendPacketLen,
PacketHeader(ShortHeader(ProtectionType::KeyPhaseZero, connId, pktNum)), ShortHeader(ProtectionType::KeyPhaseZero, connId, pktNum),
largestAckedPacketNum); largestAckedPacketNum);
builder.setCipherOverhead(cipherOverhead); builder.setCipherOverhead(cipherOverhead);
EXPECT_TRUE(builder.canBuildPacket()); EXPECT_TRUE(builder.canBuildPacket());
@@ -337,7 +336,7 @@ TEST_F(QuicPacketBuilderTest, TestPaddingRespectsRemainingBytes) {
size_t totalPacketSize = 20; size_t totalPacketSize = 20;
RegularQuicPacketBuilder builder( RegularQuicPacketBuilder builder(
totalPacketSize, totalPacketSize,
PacketHeader(ShortHeader(ProtectionType::KeyPhaseZero, connId, pktNum)), ShortHeader(ProtectionType::KeyPhaseZero, connId, pktNum),
largestAckedPacketNum); largestAckedPacketNum);
EXPECT_TRUE(builder.canBuildPacket()); EXPECT_TRUE(builder.canBuildPacket());
writeFrame(PaddingFrame(), builder); writeFrame(PaddingFrame(), builder);

View File

@@ -40,8 +40,7 @@ class QuicPacketRebuilderTest : public Test {};
TEST_F(QuicPacketRebuilderTest, RebuildEmpty) { TEST_F(QuicPacketRebuilderTest, RebuildEmpty) {
RegularQuicPacketBuilder regularBuilder( RegularQuicPacketBuilder regularBuilder(
kDefaultUDPSendPacketLen, kDefaultUDPSendPacketLen,
PacketHeader( ShortHeader(ProtectionType::KeyPhaseZero, getTestConnectionId(), 0),
ShortHeader(ProtectionType::KeyPhaseZero, getTestConnectionId(), 0)),
0 /* largestAcked */); 0 /* largestAcked */);
QuicConnectionStateBase conn(QuicNodeType::Client); QuicConnectionStateBase conn(QuicNodeType::Client);
PacketRebuilder rebuilder(regularBuilder, conn); PacketRebuilder rebuilder(regularBuilder, conn);
@@ -52,10 +51,10 @@ TEST_F(QuicPacketRebuilderTest, RebuildEmpty) {
} }
TEST_F(QuicPacketRebuilderTest, RebuildPacket) { TEST_F(QuicPacketRebuilderTest, RebuildPacket) {
ShortHeader shortHeader( ShortHeader shortHeader1(
ProtectionType::KeyPhaseZero, getTestConnectionId(), 0); ProtectionType::KeyPhaseZero, getTestConnectionId(), 0);
RegularQuicPacketBuilder regularBuilder1( RegularQuicPacketBuilder regularBuilder1(
kDefaultUDPSendPacketLen, shortHeader, 0 /* largestAcked */); kDefaultUDPSendPacketLen, std::move(shortHeader1), 0 /* largestAcked */);
// Get a bunch frames // Get a bunch frames
ConnectionCloseFrame connCloseFrame( ConnectionCloseFrame connCloseFrame(
@@ -107,8 +106,10 @@ TEST_F(QuicPacketRebuilderTest, RebuildPacket) {
true); true);
// rebuild a packet from the built out packet // rebuild a packet from the built out packet
ShortHeader shortHeader2(
ProtectionType::KeyPhaseZero, getTestConnectionId(), 0);
RegularQuicPacketBuilder regularBuilder2( RegularQuicPacketBuilder regularBuilder2(
kDefaultUDPSendPacketLen, shortHeader, 0 /* largestAcked */); kDefaultUDPSendPacketLen, std::move(shortHeader2), 0 /* largestAcked */);
PacketRebuilder rebuilder(regularBuilder2, conn); PacketRebuilder rebuilder(regularBuilder2, conn);
auto outstanding = makeDummyOutstandingPacket(packet1.packet, 1000); auto outstanding = makeDummyOutstandingPacket(packet1.packet, 1000);
EXPECT_TRUE(rebuilder.rebuildFromPacket(outstanding).hasValue()); EXPECT_TRUE(rebuilder.rebuildFromPacket(outstanding).hasValue());
@@ -166,10 +167,10 @@ TEST_F(QuicPacketRebuilderTest, RebuildPacket) {
} }
TEST_F(QuicPacketRebuilderTest, RebuildAfterResetStream) { TEST_F(QuicPacketRebuilderTest, RebuildAfterResetStream) {
ShortHeader shortHeader( ShortHeader shortHeader1(
ProtectionType::KeyPhaseZero, getTestConnectionId(), 0); ProtectionType::KeyPhaseZero, getTestConnectionId(), 0);
RegularQuicPacketBuilder regularBuilder1( RegularQuicPacketBuilder regularBuilder1(
kDefaultUDPSendPacketLen, shortHeader, 0 /* largestAcked */); kDefaultUDPSendPacketLen, std::move(shortHeader1), 0 /* largestAcked */);
QuicServerConnectionState conn; QuicServerConnectionState conn;
conn.streamManager->setMaxLocalBidirectionalStreams(10); conn.streamManager->setMaxLocalBidirectionalStreams(10);
auto stream = conn.streamManager->createNextBidirectionalStream().value(); auto stream = conn.streamManager->createNextBidirectionalStream().value();
@@ -192,18 +193,20 @@ TEST_F(QuicPacketRebuilderTest, RebuildAfterResetStream) {
conn, conn,
*stream, *stream,
StreamEvents::SendReset(GenericApplicationErrorCode::UNKNOWN)); StreamEvents::SendReset(GenericApplicationErrorCode::UNKNOWN));
ShortHeader shortHeader2(
ProtectionType::KeyPhaseZero, getTestConnectionId(), 0);
RegularQuicPacketBuilder regularBuilder2( RegularQuicPacketBuilder regularBuilder2(
kDefaultUDPSendPacketLen, shortHeader, 0 /* largestAcked */); kDefaultUDPSendPacketLen, std::move(shortHeader2), 0 /* largestAcked */);
PacketRebuilder rebuilder(regularBuilder2, conn); PacketRebuilder rebuilder(regularBuilder2, conn);
auto outstanding = makeDummyOutstandingPacket(packet1.packet, 1000); auto outstanding = makeDummyOutstandingPacket(packet1.packet, 1000);
EXPECT_FALSE(rebuilder.rebuildFromPacket(outstanding).hasValue()); EXPECT_FALSE(rebuilder.rebuildFromPacket(outstanding).hasValue());
} }
TEST_F(QuicPacketRebuilderTest, FinOnlyStreamRebuild) { TEST_F(QuicPacketRebuilderTest, FinOnlyStreamRebuild) {
ShortHeader shortHeader( ShortHeader shortHeader1(
ProtectionType::KeyPhaseZero, getTestConnectionId(), 0); ProtectionType::KeyPhaseZero, getTestConnectionId(), 0);
RegularQuicPacketBuilder regularBuilder1( RegularQuicPacketBuilder regularBuilder1(
kDefaultUDPSendPacketLen, shortHeader, 0 /* largestAcked */); kDefaultUDPSendPacketLen, std::move(shortHeader1), 0 /* largestAcked */);
QuicServerConnectionState conn; QuicServerConnectionState conn;
conn.streamManager->setMaxLocalBidirectionalStreams(10); conn.streamManager->setMaxLocalBidirectionalStreams(10);
auto stream = conn.streamManager->createNextBidirectionalStream().value(); auto stream = conn.streamManager->createNextBidirectionalStream().value();
@@ -216,8 +219,10 @@ TEST_F(QuicPacketRebuilderTest, FinOnlyStreamRebuild) {
stream->retransmissionBuffer.begin(), nullptr, 0, true); stream->retransmissionBuffer.begin(), nullptr, 0, true);
// rebuild a packet from the built out packet // rebuild a packet from the built out packet
ShortHeader shortHeader2(
ProtectionType::KeyPhaseZero, getTestConnectionId(), 0);
RegularQuicPacketBuilder regularBuilder2( RegularQuicPacketBuilder regularBuilder2(
kDefaultUDPSendPacketLen, shortHeader, 0 /* largestAcked */); kDefaultUDPSendPacketLen, std::move(shortHeader2), 0 /* largestAcked */);
PacketRebuilder rebuilder(regularBuilder2, conn); PacketRebuilder rebuilder(regularBuilder2, conn);
auto outstanding = makeDummyOutstandingPacket(packet1.packet, 2000); auto outstanding = makeDummyOutstandingPacket(packet1.packet, 2000);
EXPECT_TRUE(rebuilder.rebuildFromPacket(outstanding).hasValue()); EXPECT_TRUE(rebuilder.rebuildFromPacket(outstanding).hasValue());
@@ -236,10 +241,10 @@ TEST_F(QuicPacketRebuilderTest, FinOnlyStreamRebuild) {
} }
TEST_F(QuicPacketRebuilderTest, RebuildDataStreamAndEmptyCryptoStream) { TEST_F(QuicPacketRebuilderTest, RebuildDataStreamAndEmptyCryptoStream) {
ShortHeader shortHeader( ShortHeader shortHeader1(
ProtectionType::KeyPhaseZero, getTestConnectionId(), 0); ProtectionType::KeyPhaseZero, getTestConnectionId(), 0);
RegularQuicPacketBuilder regularBuilder1( RegularQuicPacketBuilder regularBuilder1(
kDefaultUDPSendPacketLen, shortHeader, 0 /* largestAcked */); kDefaultUDPSendPacketLen, std::move(shortHeader1), 0 /* largestAcked */);
// Get a bunch frames // Get a bunch frames
QuicServerConnectionState conn; QuicServerConnectionState conn;
@@ -270,8 +275,10 @@ TEST_F(QuicPacketRebuilderTest, RebuildDataStreamAndEmptyCryptoStream) {
// imagine it was cleared // imagine it was cleared
// rebuild a packet from the built out packet // rebuild a packet from the built out packet
ShortHeader shortHeader2(
ProtectionType::KeyPhaseZero, getTestConnectionId(), 0);
RegularQuicPacketBuilder regularBuilder2( RegularQuicPacketBuilder regularBuilder2(
kDefaultUDPSendPacketLen, shortHeader, 0 /* largestAcked */); kDefaultUDPSendPacketLen, std::move(shortHeader2), 0 /* largestAcked */);
PacketRebuilder rebuilder(regularBuilder2, conn); PacketRebuilder rebuilder(regularBuilder2, conn);
auto outstanding = makeDummyOutstandingPacket(packet1.packet, 1000); auto outstanding = makeDummyOutstandingPacket(packet1.packet, 1000);
EXPECT_TRUE(rebuilder.rebuildFromPacket(outstanding).hasValue()); EXPECT_TRUE(rebuilder.rebuildFromPacket(outstanding).hasValue());
@@ -295,10 +302,10 @@ TEST_F(QuicPacketRebuilderTest, RebuildDataStreamAndEmptyCryptoStream) {
} }
TEST_F(QuicPacketRebuilderTest, CannotRebuildEmptyCryptoStream) { TEST_F(QuicPacketRebuilderTest, CannotRebuildEmptyCryptoStream) {
ShortHeader shortHeader( ShortHeader shortHeader1(
ProtectionType::KeyPhaseZero, getTestConnectionId(), 0); ProtectionType::KeyPhaseZero, getTestConnectionId(), 0);
RegularQuicPacketBuilder regularBuilder1( RegularQuicPacketBuilder regularBuilder1(
kDefaultUDPSendPacketLen, shortHeader, 0 /* largestAcked */); kDefaultUDPSendPacketLen, std::move(shortHeader1), 0 /* largestAcked */);
// Get a bunch frames // Get a bunch frames
QuicServerConnectionState conn; QuicServerConnectionState conn;
@@ -313,18 +320,20 @@ TEST_F(QuicPacketRebuilderTest, CannotRebuildEmptyCryptoStream) {
// imagine it was cleared // imagine it was cleared
// rebuild a packet from the built out packet // rebuild a packet from the built out packet
ShortHeader shortHeader2(
ProtectionType::KeyPhaseZero, getTestConnectionId(), 0);
RegularQuicPacketBuilder regularBuilder2( RegularQuicPacketBuilder regularBuilder2(
kDefaultUDPSendPacketLen, shortHeader, 0 /* largestAcked */); kDefaultUDPSendPacketLen, std::move(shortHeader2), 0 /* largestAcked */);
PacketRebuilder rebuilder(regularBuilder2, conn); PacketRebuilder rebuilder(regularBuilder2, conn);
auto outstanding = makeDummyOutstandingPacket(packet1.packet, 1000); auto outstanding = makeDummyOutstandingPacket(packet1.packet, 1000);
EXPECT_FALSE(rebuilder.rebuildFromPacket(outstanding).hasValue()); EXPECT_FALSE(rebuilder.rebuildFromPacket(outstanding).hasValue());
} }
TEST_F(QuicPacketRebuilderTest, CannotRebuild) { TEST_F(QuicPacketRebuilderTest, CannotRebuild) {
ShortHeader shortHeader( ShortHeader shortHeader1(
ProtectionType::KeyPhaseZero, getTestConnectionId(), 0); ProtectionType::KeyPhaseZero, getTestConnectionId(), 0);
RegularQuicPacketBuilder regularBuilder1( RegularQuicPacketBuilder regularBuilder1(
kDefaultUDPSendPacketLen, shortHeader, 0 /* largestAcked */); kDefaultUDPSendPacketLen, std::move(shortHeader1), 0 /* largestAcked */);
// Get a bunch frames // Get a bunch frames
ConnectionCloseFrame connCloseFrame( ConnectionCloseFrame connCloseFrame(
@@ -364,11 +373,13 @@ TEST_F(QuicPacketRebuilderTest, CannotRebuild) {
stream->retransmissionBuffer.begin(), buf->clone(), 0, true); stream->retransmissionBuffer.begin(), buf->clone(), 0, true);
// new builder has a much smaller writable bytes limit // new builder has a much smaller writable bytes limit
ShortHeader shortHeader2(
ProtectionType::KeyPhaseZero, getTestConnectionId(), 0);
RegularQuicPacketBuilder regularBuilder2( RegularQuicPacketBuilder regularBuilder2(
(packet1.header->computeChainDataLength() + (packet1.header->computeChainDataLength() +
packet1.body->computeChainDataLength()) / packet1.body->computeChainDataLength()) /
2, 2,
shortHeader, std::move(shortHeader2),
0 /* largestAcked */); 0 /* largestAcked */);
PacketRebuilder rebuilder(regularBuilder2, conn); PacketRebuilder rebuilder(regularBuilder2, conn);
auto outstanding = makeDummyOutstandingPacket(packet1.packet, 1000); auto outstanding = makeDummyOutstandingPacket(packet1.packet, 1000);
@@ -376,17 +387,19 @@ TEST_F(QuicPacketRebuilderTest, CannotRebuild) {
} }
TEST_F(QuicPacketRebuilderTest, CloneCounter) { TEST_F(QuicPacketRebuilderTest, CloneCounter) {
ShortHeader shortHeader( ShortHeader shortHeader1(
ProtectionType::KeyPhaseZero, getTestConnectionId(), 0); ProtectionType::KeyPhaseZero, getTestConnectionId(), 0);
RegularQuicPacketBuilder regularBuilder( RegularQuicPacketBuilder regularBuilder(
kDefaultUDPSendPacketLen, shortHeader, 0 /* largestAcked */); kDefaultUDPSendPacketLen, std::move(shortHeader1), 0 /* largestAcked */);
PingFrame pingFrame; PingFrame pingFrame;
writeFrame(pingFrame, regularBuilder); writeFrame(pingFrame, regularBuilder);
auto packet = std::move(regularBuilder).buildPacket(); auto packet = std::move(regularBuilder).buildPacket();
auto outstandingPacket = makeDummyOutstandingPacket(packet.packet, 1000); auto outstandingPacket = makeDummyOutstandingPacket(packet.packet, 1000);
QuicServerConnectionState conn; QuicServerConnectionState conn;
ShortHeader shortHeader2(
ProtectionType::KeyPhaseZero, getTestConnectionId(), 0);
RegularQuicPacketBuilder regularBuilder2( RegularQuicPacketBuilder regularBuilder2(
kDefaultUDPSendPacketLen, shortHeader, 0 /* largestAcked */); kDefaultUDPSendPacketLen, std::move(shortHeader2), 0 /* largestAcked */);
PacketRebuilder rebuilder(regularBuilder2, conn); PacketRebuilder rebuilder(regularBuilder2, conn);
rebuilder.rebuildFromPacket(outstandingPacket); rebuilder.rebuildFromPacket(outstandingPacket);
EXPECT_TRUE(outstandingPacket.associatedEvent.hasValue()); EXPECT_TRUE(outstandingPacket.associatedEvent.hasValue());

View File

@@ -109,7 +109,7 @@ TEST_F(QuicReadCodecTest, RetryPacketTest) {
getTestConnectionId(90), getTestConnectionId(90),
321, 321,
static_cast<QuicVersion>(0xffff), static_cast<QuicVersion>(0xffff),
folly::IOBuf::copyBuffer("fluffydog"), std::string("fluffydog"),
getTestConnectionId(110)); getTestConnectionId(110));
RegularQuicPacketBuilder builder( RegularQuicPacketBuilder builder(
@@ -121,16 +121,15 @@ TEST_F(QuicReadCodecTest, RetryPacketTest) {
auto retryPacket = boost::get<RegularQuicPacket>(boost::get<QuicPacket>( auto retryPacket = boost::get<RegularQuicPacket>(boost::get<QuicPacket>(
makeUnencryptedCodec()->parsePacket(packetQueue, ackStates))); makeUnencryptedCodec()->parsePacket(packetQueue, ackStates)));
auto headerOut = boost::get<LongHeader>(retryPacket.header); auto headerOut = *retryPacket.header.asLong();
EXPECT_EQ(*headerOut.getOriginalDstConnId(), getTestConnectionId(110)); EXPECT_EQ(*headerOut.getOriginalDstConnId(), getTestConnectionId(110));
EXPECT_EQ(headerOut.getVersion(), static_cast<QuicVersion>(0xffff)); EXPECT_EQ(headerOut.getVersion(), static_cast<QuicVersion>(0xffff));
EXPECT_EQ(headerOut.getSourceConnId(), getTestConnectionId(70)); EXPECT_EQ(headerOut.getSourceConnId(), getTestConnectionId(70));
EXPECT_EQ(headerOut.getDestinationConnId(), getTestConnectionId(90)); EXPECT_EQ(headerOut.getDestinationConnId(), getTestConnectionId(90));
folly::IOBufEqualTo eq; auto expected = std::string("fluffydog");
auto expectedBuf = folly::IOBuf::copyBuffer("fluffydog"); EXPECT_EQ(headerOut.getToken(), expected);
EXPECT_TRUE(eq(*headerOut.getToken(), *expectedBuf));
} }
TEST_F(QuicReadCodecTest, EmptyVersionNegotiationPacketTest) { TEST_F(QuicReadCodecTest, EmptyVersionNegotiationPacketTest) {
@@ -486,10 +485,10 @@ TEST_F(QuicReadCodecTest, TestInitialPacket) {
EXPECT_NO_THROW(boost::get<RegularQuicPacket>(quicPacket)); EXPECT_NO_THROW(boost::get<RegularQuicPacket>(quicPacket));
auto regularQuicPacket = boost::get<RegularQuicPacket>(quicPacket); auto regularQuicPacket = boost::get<RegularQuicPacket>(quicPacket);
EXPECT_NO_THROW(boost::get<LongHeader>(regularQuicPacket.header)); EXPECT_NE(regularQuicPacket.header.asLong(), nullptr);
auto longPacketHeader = boost::get<LongHeader>(regularQuicPacket.header); auto longPacketHeader = regularQuicPacket.header.asLong();
EXPECT_FALSE(longPacketHeader.hasToken()); EXPECT_FALSE(longPacketHeader->hasToken());
} }
TEST_F(QuicReadCodecTest, TestHandshakeDone) { TEST_F(QuicReadCodecTest, TestHandshakeDone) {

View File

@@ -124,7 +124,7 @@ TEST_F(QuicWriteCodecTest, WriteStreamFrameToEmptyPacket) {
EXPECT_EQ( EXPECT_EQ(
kDefaultUDPSendPacketLen - 3 - 10, pktBuilder.remainingSpaceInPkt()); kDefaultUDPSendPacketLen - 3 - 10, pktBuilder.remainingSpaceInPkt());
auto builtOut = std::move(pktBuilder).buildPacket(); auto builtOut = std::move(pktBuilder).buildPacket();
auto regularPacket = builtOut.first; auto regularPacket = std::move(builtOut.first);
EXPECT_EQ(regularPacket.frames.size(), 1); EXPECT_EQ(regularPacket.frames.size(), 1);
auto resultFrame = boost::get<WriteStreamFrame>(regularPacket.frames.back()); auto resultFrame = boost::get<WriteStreamFrame>(regularPacket.frames.back());
@@ -171,7 +171,7 @@ TEST_F(QuicWriteCodecTest, WriteStreamFrameToPartialPacket) {
pktBuilder.remainingSpaceInPkt()); pktBuilder.remainingSpaceInPkt());
auto builtOut = std::move(pktBuilder).buildPacket(); auto builtOut = std::move(pktBuilder).buildPacket();
auto regularPacket = builtOut.first; auto regularPacket = std::move(builtOut.first);
EXPECT_EQ(regularPacket.frames.size(), 1); EXPECT_EQ(regularPacket.frames.size(), 1);
auto resultFrame = boost::get<WriteStreamFrame>(regularPacket.frames.back()); auto resultFrame = boost::get<WriteStreamFrame>(regularPacket.frames.back());
EXPECT_EQ(resultFrame.streamId, streamId); EXPECT_EQ(resultFrame.streamId, streamId);
@@ -237,7 +237,7 @@ TEST_F(QuicWriteCodecTest, WriteTwoStreamFrames) {
kDefaultUDPSendPacketLen - consumedSize, kDefaultUDPSendPacketLen - consumedSize,
pktBuilder.remainingSpaceInPkt()); pktBuilder.remainingSpaceInPkt());
auto builtOut = std::move(pktBuilder).buildPacket(); auto builtOut = std::move(pktBuilder).buildPacket();
auto regularPacket = builtOut.first; auto regularPacket = std::move(builtOut.first);
EXPECT_EQ(regularPacket.frames.size(), 2); EXPECT_EQ(regularPacket.frames.size(), 2);
auto resultFrame = boost::get<WriteStreamFrame>(regularPacket.frames.front()); auto resultFrame = boost::get<WriteStreamFrame>(regularPacket.frames.front());
EXPECT_EQ(resultFrame.streamId, streamId1); EXPECT_EQ(resultFrame.streamId, streamId1);

View File

@@ -61,7 +61,7 @@ folly::Expected<ParsedLongHeaderResult, TransportErrorCode> makeLongHeader(
getTestConnectionId(), getTestConnectionId(),
321, 321,
QuicVersion::QUIC_DRAFT, QuicVersion::QUIC_DRAFT,
IOBuf::copyBuffer("this is a retry token :)"), std::string("this is a retry token :)"),
getTestConnectionId()); getTestConnectionId());
RegularQuicPacketBuilder builder( RegularQuicPacketBuilder builder(
@@ -261,5 +261,39 @@ TEST_F(TypesTest, LongHeaderPacketNumberSpace) {
PacketNumberSpace::AppData, zeroRttLongHeader.getPacketNumberSpace()); PacketNumberSpace::AppData, zeroRttLongHeader.getPacketNumberSpace());
} }
class PacketHeaderTest : public Test {};
TEST_F(PacketHeaderTest, LongHeader) {
PacketNum packetNumber = 202;
LongHeader handshakeLongHeader(
LongHeader::Types::Handshake,
getTestConnectionId(4),
getTestConnectionId(5),
packetNumber,
QuicVersion::QUIC_DRAFT);
PacketHeader readHeader(std::move(handshakeLongHeader));
EXPECT_NE(readHeader.asLong(), nullptr);
EXPECT_EQ(readHeader.asShort(), nullptr);
EXPECT_EQ(readHeader.getPacketSequenceNum(), packetNumber);
EXPECT_EQ(readHeader.getHeaderForm(), HeaderForm::Long);
EXPECT_EQ(readHeader.getProtectionType(), ProtectionType::Handshake);
EXPECT_EQ(readHeader.getPacketNumberSpace(), PacketNumberSpace::Handshake);
EXPECT_EQ(readHeader.asLong()->getHeaderType(), LongHeader::Types::Handshake);
}
TEST_F(PacketHeaderTest, ShortHeader) {
PacketNum packetNumber = 202;
ConnectionId connid = getTestConnectionId(4);
ShortHeader shortHeader(ProtectionType::KeyPhaseZero, connid, packetNumber);
PacketHeader readHeader(std::move(shortHeader));
EXPECT_EQ(readHeader.asLong(), nullptr);
EXPECT_NE(readHeader.asShort(), nullptr);
EXPECT_EQ(readHeader.getPacketSequenceNum(), packetNumber);
EXPECT_EQ(readHeader.getHeaderForm(), HeaderForm::Short);
EXPECT_EQ(readHeader.getProtectionType(), ProtectionType::KeyPhaseZero);
EXPECT_EQ(readHeader.getPacketNumberSpace(), PacketNumberSpace::AppData);
EXPECT_EQ(readHeader.asShort()->getConnectionId(), connid);
}
} // namespace test } // namespace test
} // namespace quic } // namespace quic

View File

@@ -25,10 +25,7 @@ getPreviousOutstandingPacket(
std::deque<quic::OutstandingPacket>::reverse_iterator from) { std::deque<quic::OutstandingPacket>::reverse_iterator from) {
return std::find_if( return std::find_if(
from, conn.outstandingPackets.rend(), [=](const auto& op) { from, conn.outstandingPackets.rend(), [=](const auto& op) {
return packetNumberSpace == return packetNumberSpace == op.packet.header.getPacketNumberSpace();
folly::variant_match(op.packet.header, [](const auto& h) {
return h.getPacketNumberSpace();
});
}); });
} }
} // namespace } // namespace
@@ -65,11 +62,6 @@ const RegularQuicWritePacket& writeQuicPacket(
return getLastOutstandingPacket(conn, PacketNumberSpace::AppData)->packet; return getLastOutstandingPacket(conn, PacketNumberSpace::AppData)->packet;
} }
PacketNum getPacketSequenceNum(const RegularQuicWritePacket& packet) {
return folly::variant_match(
packet.header, [](const auto& h) { return h.getPacketSequenceNum(); });
}
PacketNum rstStreamAndSendPacket( PacketNum rstStreamAndSendPacket(
QuicServerConnectionState& conn, QuicServerConnectionState& conn,
folly::AsyncUDPSocket& sock, folly::AsyncUDPSocket& sock,
@@ -93,9 +85,7 @@ PacketNum rstStreamAndSendPacket(
for (const auto& packet : conn.outstandingPackets) { for (const auto& packet : conn.outstandingPackets) {
for (const auto& frame : all_frames<RstStreamFrame>(packet.packet.frames)) { for (const auto& frame : all_frames<RstStreamFrame>(packet.packet.frames)) {
if (frame.streamId == stream.id) { if (frame.streamId == stream.id) {
return folly::variant_match(packet.packet.header, [](const auto& h) { return packet.packet.header.getPacketSequenceNum();
return h.getPacketSequenceNum();
});
} }
} }
} }
@@ -394,32 +384,24 @@ RegularQuicPacketBuilder::Packet createCryptoPacket(
folly::Optional<PacketHeader> header; folly::Optional<PacketHeader> header;
switch (protectionType) { switch (protectionType) {
case ProtectionType::Initial: case ProtectionType::Initial:
header = PacketHeader(LongHeader( header = LongHeader(
LongHeader::Types::Initial, LongHeader::Types::Initial, srcConnId, dstConnId, packetNum, version);
srcConnId,
dstConnId,
packetNum,
version));
break; break;
case ProtectionType::Handshake: case ProtectionType::Handshake:
header = PacketHeader(LongHeader( header = LongHeader(
LongHeader::Types::Handshake, LongHeader::Types::Handshake,
srcConnId, srcConnId,
dstConnId, dstConnId,
packetNum, packetNum,
version)); version);
break; break;
case ProtectionType::ZeroRtt: case ProtectionType::ZeroRtt:
header = PacketHeader(LongHeader( header = LongHeader(
LongHeader::Types::ZeroRtt, LongHeader::Types::ZeroRtt, srcConnId, dstConnId, packetNum, version);
srcConnId,
dstConnId,
packetNum,
version));
break; break;
case ProtectionType::KeyPhaseOne: case ProtectionType::KeyPhaseOne:
case ProtectionType::KeyPhaseZero: case ProtectionType::KeyPhaseZero:
header = PacketHeader(ShortHeader(protectionType, dstConnId, packetNum)); header = ShortHeader(protectionType, dstConnId, packetNum);
break; break;
} }
RegularQuicPacketBuilder builder( RegularQuicPacketBuilder builder(
@@ -449,10 +431,7 @@ Buf packetToBufCleartext(
if (packet.body) { if (packet.body) {
body = packet.body->clone(); body = packet.body->clone();
} }
auto headerForm = folly::variant_match( auto headerForm = packet.packet.header.getHeaderForm();
packet.packet.header,
[](const LongHeader&) { return HeaderForm::Long; },
[](const ShortHeader&) { return HeaderForm::Short; });
auto encryptedBody = auto encryptedBody =
cleartextCipher.encrypt(std::move(body), packet.header.get(), packetNum); cleartextCipher.encrypt(std::move(body), packet.header.get(), packetNum);
encryptPacketHeader(headerForm, *packet.header, *encryptedBody, headerCipher); encryptPacketHeader(headerForm, *packet.header, *encryptedBody, headerCipher);

View File

@@ -52,8 +52,6 @@ const RegularQuicWritePacket& writeQuicPacket(
const folly::IOBuf& data, const folly::IOBuf& data,
bool eof = false); bool eof = false);
PacketNum getPacketSequenceNum(const RegularQuicWritePacket& packet);
RegularQuicPacketBuilder::Packet createAckPacket( RegularQuicPacketBuilder::Packet createAckPacket(
QuicConnectionStateBase& dstConn, QuicConnectionStateBase& dstConn,
PacketNum pn, PacketNum pn,

View File

@@ -50,10 +50,7 @@ void Copa::onPacketSent(const OutstandingPacket& packet) {
VLOG(10) << __func__ << " writable=" << getWritableBytes() VLOG(10) << __func__ << " writable=" << getWritableBytes()
<< " cwnd=" << cwndBytes_ << " inflight=" << bytesInFlight_ << " cwnd=" << cwndBytes_ << " inflight=" << bytesInFlight_
<< " bytesBufferred=" << conn_.flowControlState.sumCurStreamBufferLen << " bytesBufferred=" << conn_.flowControlState.sumCurStreamBufferLen
<< " packetNum=" << " packetNum=" << packet.packet.header.getPacketSequenceNum()
<< folly::variant_match(
packet.packet.header,
[](auto& h) { return h.getPacketSequenceNum(); })
<< " " << conn_; << " " << conn_;
if (conn_.qLogger) { if (conn_.qLogger) {
conn_.qLogger->addCongestionMetricUpdate( conn_.qLogger->addCongestionMetricUpdate(

View File

@@ -40,10 +40,7 @@ void NewReno::onPacketSent(const OutstandingPacket& packet) {
addAndCheckOverflow(bytesInFlight_, packet.encodedSize); addAndCheckOverflow(bytesInFlight_, packet.encodedSize);
VLOG(10) << __func__ << " writable=" << getWritableBytes() VLOG(10) << __func__ << " writable=" << getWritableBytes()
<< " cwnd=" << cwndBytes_ << " inflight=" << bytesInFlight_ << " cwnd=" << cwndBytes_ << " inflight=" << bytesInFlight_
<< " packetNum=" << " packetNum=" << packet.packet.header.getPacketSequenceNum()
<< folly::variant_match(
packet.packet.header,
[](auto& h) { return h.getPacketSequenceNum(); })
<< " " << conn_; << " " << conn_;
if (conn_.qLogger) { if (conn_.qLogger) {
conn_.qLogger->addCongestionMetricUpdate( conn_.qLogger->addCongestionMetricUpdate(

View File

@@ -23,17 +23,16 @@ std::unique_ptr<QLogPacketEvent> QLogger::createPacketEvent(
std::chrono::steady_clock::now() - refTimePoint); std::chrono::steady_clock::now() - refTimePoint);
event->packetSize = packetSize; event->packetSize = packetSize;
event->eventType = QLogEventType::PacketReceived; event->eventType = QLogEventType::PacketReceived;
event->packetType = folly::variant_match( const ShortHeader* shortHeader = regularPacket.header.asShort();
regularPacket.header, if (shortHeader) {
[](const LongHeader& header) { return toString(header.getHeaderType()); }, event->packetType = kShortHeaderPacketType.toString();
[](const ShortHeader& /* unused*/) { } else {
return kShortHeaderPacketType.toString(); event->packetType =
}); toString(regularPacket.header.asLong()->getHeaderType());
}
if (event->packetType != toString(LongHeader::Types::Retry)) { if (event->packetType != toString(LongHeader::Types::Retry)) {
// A Retry packet does not include a packet number. // A Retry packet does not include a packet number.
event->packetNum = folly::variant_match( event->packetNum = regularPacket.header.getPacketSequenceNum();
regularPacket.header,
[](const auto& h) { return h.getPacketSequenceNum(); });
} }
uint64_t numPaddingFrames = 0; uint64_t numPaddingFrames = 0;
@@ -149,17 +148,15 @@ std::unique_ptr<QLogPacketEvent> QLogger::createPacketEvent(
auto event = std::make_unique<QLogPacketEvent>(); auto event = std::make_unique<QLogPacketEvent>();
event->refTime = std::chrono::duration_cast<std::chrono::microseconds>( event->refTime = std::chrono::duration_cast<std::chrono::microseconds>(
std::chrono::steady_clock::now() - refTimePoint); std::chrono::steady_clock::now() - refTimePoint);
event->packetNum = folly::variant_match( event->packetNum = writePacket.header.getPacketSequenceNum();
writePacket.header,
[](const auto& h) { return h.getPacketSequenceNum(); });
event->packetSize = packetSize; event->packetSize = packetSize;
event->eventType = QLogEventType::PacketSent; event->eventType = QLogEventType::PacketSent;
event->packetType = folly::variant_match( const ShortHeader* shortHeader = writePacket.header.asShort();
writePacket.header, if (shortHeader) {
[](const LongHeader& header) { return toString(header.getHeaderType()); }, event->packetType = kShortHeaderPacketType.toString();
[](const ShortHeader& /* unused*/) { } else {
return kShortHeaderPacketType.toString(); event->packetType = toString(writePacket.header.asLong()->getHeaderType());
}); }
uint64_t numPaddingFrames = 0; uint64_t numPaddingFrames = 0;
// looping through the packet to store logs created from frames in the packet // looping through the packet to store logs created from frames in the packet

View File

@@ -50,7 +50,7 @@ TEST_F(QLoggerTest, TestRegularWritePacket) {
TEST_F(QLoggerTest, TestRegularPacket) { TEST_F(QLoggerTest, TestRegularPacket) {
auto headerIn = auto headerIn =
ShortHeader(ProtectionType::KeyPhaseZero, getTestConnectionId(1), 1); ShortHeader(ProtectionType::KeyPhaseZero, getTestConnectionId(1), 1);
RegularQuicPacket regularQuicPacket(headerIn); RegularQuicPacket regularQuicPacket(std::move(headerIn));
ReadStreamFrame frame(streamId, offset, fin); ReadStreamFrame frame(streamId, offset, fin);
regularQuicPacket.frames.emplace_back(std::move(frame)); regularQuicPacket.frames.emplace_back(std::move(frame));
@@ -341,7 +341,7 @@ TEST_F(QLoggerTest, QLoggerFollyDynamic) {
auto headerIn = auto headerIn =
ShortHeader(ProtectionType::KeyPhaseZero, getTestConnectionId(1), 1); ShortHeader(ProtectionType::KeyPhaseZero, getTestConnectionId(1), 1);
RegularQuicPacket regularQuicPacket(headerIn); RegularQuicPacket regularQuicPacket(std::move(headerIn));
ReadStreamFrame frame(streamId, offset, fin); ReadStreamFrame frame(streamId, offset, fin);
regularQuicPacket.frames.emplace_back(std::move(frame)); regularQuicPacket.frames.emplace_back(std::move(frame));
@@ -384,7 +384,7 @@ TEST_F(QLoggerTest, RegularPacketFollyDynamic) {
auto headerIn = auto headerIn =
ShortHeader(ProtectionType::KeyPhaseZero, getTestConnectionId(1), 1); ShortHeader(ProtectionType::KeyPhaseZero, getTestConnectionId(1), 1);
RegularQuicPacket regularQuicPacket(headerIn); RegularQuicPacket regularQuicPacket(std::move(headerIn));
ReadStreamFrame frame(streamId, offset, fin); ReadStreamFrame frame(streamId, offset, fin);
regularQuicPacket.frames.emplace_back(std::move(frame)); regularQuicPacket.frames.emplace_back(std::move(frame));

View File

@@ -126,9 +126,7 @@ void markPacketLoss(
if (processed) { if (processed) {
return; return;
} }
auto protectionType = folly::variant_match( auto protectionType = packet.header.getProtectionType();
packet.header,
[](auto& header) { return header.getProtectionType(); });
auto encryptionLevel = auto encryptionLevel =
protectionTypeToEncryptionLevel(protectionType); protectionTypeToEncryptionLevel(protectionType);
auto cryptoStream = auto cryptoStream =

View File

@@ -105,9 +105,8 @@ calculateAlarmDuration(const QuicConnectionStateBase& conn) {
std::chrono::duration_cast<std::chrono::milliseconds>( std::chrono::duration_cast<std::chrono::milliseconds>(
lastSentPacketTime + alarmDuration - now); lastSentPacketTime + alarmDuration - now);
} else { } else {
auto lastSentPacketNum = folly::variant_match( auto lastSentPacketNum =
conn.outstandingPackets.back().packet.header, conn.outstandingPackets.back().packet.header.getPacketSequenceNum();
[](const auto& h) { return h.getPacketSequenceNum(); });
VLOG(10) << __func__ << " alarm already due method=" << *alarmMethod VLOG(10) << __func__ << " alarm already due method=" << *alarmMethod
<< " lastSentPacketNum=" << lastSentPacketNum << " lastSentPacketNum=" << lastSentPacketNum
<< " lastSentPacketTime=" << " lastSentPacketTime="
@@ -224,15 +223,11 @@ folly::Optional<CongestionController::LossEvent> detectLossPackets(
bool shouldSetTimer = false; bool shouldSetTimer = false;
while (iter != conn.outstandingPackets.end()) { while (iter != conn.outstandingPackets.end()) {
auto& pkt = *iter; auto& pkt = *iter;
auto currentPacketNum = folly::variant_match( auto currentPacketNum = pkt.packet.header.getPacketSequenceNum();
pkt.packet.header,
[](const auto& h) { return h.getPacketSequenceNum(); });
if (currentPacketNum >= largestAcked) { if (currentPacketNum >= largestAcked) {
break; break;
} }
auto currentPacketNumberSpace = folly::variant_match( auto currentPacketNumberSpace = pkt.packet.header.getPacketNumberSpace();
pkt.packet.header,
[](const auto& h) { return h.getPacketNumberSpace(); });
if (currentPacketNumberSpace != pnSpace) { if (currentPacketNumberSpace != pnSpace) {
iter++; iter++;
continue; continue;
@@ -347,12 +342,8 @@ void onHandshakeAlarm(
// the word "handshake" in our code base is unfortunately overloaded. // the word "handshake" in our code base is unfortunately overloaded.
if (iter->isHandshake) { if (iter->isHandshake) {
auto& packet = *iter; auto& packet = *iter;
auto currentPacketNum = folly::variant_match( auto currentPacketNum = packet.packet.header.getPacketSequenceNum();
packet.packet.header, auto currentPacketNumSpace = packet.packet.header.getPacketNumberSpace();
[](const auto& h) { return h.getPacketSequenceNum(); });
auto currentPacketNumSpace = folly::variant_match(
packet.packet.header,
[](const auto& h) { return h.getPacketNumberSpace(); });
VLOG(10) << "HandshakeAlarm, removing packetNum=" << currentPacketNum VLOG(10) << "HandshakeAlarm, removing packetNum=" << currentPacketNum
<< " packetNumSpace=" << currentPacketNumSpace << " " << conn; << " packetNumSpace=" << currentPacketNumSpace << " " << conn;
DCHECK(!packet.pureAck); DCHECK(!packet.pureAck);
@@ -478,22 +469,15 @@ void markZeroRttPacketsLost(
CongestionController::LossEvent lossEvent(ClockType::now()); CongestionController::LossEvent lossEvent(ClockType::now());
auto iter = getFirstOutstandingPacket(conn, PacketNumberSpace::AppData); auto iter = getFirstOutstandingPacket(conn, PacketNumberSpace::AppData);
while (iter != conn.outstandingPackets.end()) { while (iter != conn.outstandingPackets.end()) {
DCHECK( DCHECK_EQ(
PacketNumberSpace::AppData == iter->packet.header.getPacketNumberSpace(), PacketNumberSpace::AppData);
folly::variant_match(iter->packet.header, [](const auto& h) {
return h.getPacketNumberSpace();
}));
auto isZeroRttPacket = auto isZeroRttPacket =
folly::variant_match(iter->packet.header, [&](const auto& h) { iter->packet.header.getProtectionType() == ProtectionType::ZeroRtt;
return h.getProtectionType() == ProtectionType::ZeroRtt;
});
if (isZeroRttPacket) { if (isZeroRttPacket) {
auto& pkt = *iter; auto& pkt = *iter;
DCHECK(!pkt.pureAck); DCHECK(!pkt.pureAck);
DCHECK(!pkt.isHandshake); DCHECK(!pkt.isHandshake);
auto currentPacketNum = folly::variant_match( auto currentPacketNum = pkt.packet.header.getPacketSequenceNum();
pkt.packet.header,
[](const auto& h) { return h.getPacketSequenceNum(); });
bool processed = pkt.associatedEvent && bool processed = pkt.associatedEvent &&
!conn.outstandingPacketEvents.count(*pkt.associatedEvent); !conn.outstandingPacketEvents.count(*pkt.associatedEvent);
lossVisitor(conn, pkt.packet, processed, currentPacketNum); lossVisitor(conn, pkt.packet, processed, currentPacketNum);

View File

@@ -120,9 +120,7 @@ auto testingLossMarkFunc(std::vector<PacketNum>& lostPackets) {
return [&lostPackets]( return [&lostPackets](
auto& /* conn */, auto& packet, bool processed, PacketNum) { auto& /* conn */, auto& packet, bool processed, PacketNum) {
if (!processed) { if (!processed) {
auto packetNum = folly::variant_match(packet.header, [](const auto& h) { auto packetNum = packet.header.getPacketSequenceNum();
return h.getPacketSequenceNum();
});
lostPackets.push_back(packetNum); lostPackets.push_back(packetNum);
} }
}; };
@@ -161,9 +159,13 @@ PacketNum QuicLossFunctionsTest::sendPacket(
conn.ackStates.appDataAckState.nextPacketNum); conn.ackStates.appDataAckState.nextPacketNum);
break; break;
} }
auto packetNumberSpace = folly::variant_match( PacketNumberSpace packetNumberSpace;
*header, [](const auto& h) { return h.getPacketNumberSpace(); }); auto shortHeader = header->asShort();
if (shortHeader) {
packetNumberSpace = shortHeader->getPacketNumberSpace();
} else {
packetNumberSpace = header->asLong()->getPacketNumberSpace();
}
RegularQuicPacketBuilder builder( RegularQuicPacketBuilder builder(
conn.udpSendPacketLen, conn.udpSendPacketLen,
std::move(*header), std::move(*header),
@@ -199,9 +201,7 @@ PacketNum QuicLossFunctionsTest::sendPacket(
conn.outstandingPackets.begin(), conn.outstandingPackets.begin(),
conn.outstandingPackets.end(), conn.outstandingPackets.end(),
[&associatedEvent](const auto& packet) { [&associatedEvent](const auto& packet) {
auto packetNum = folly::variant_match( auto packetNum = packet.packet.header.getPacketSequenceNum();
packet.packet.header,
[](const auto& h) { return h.getPacketSequenceNum(); });
return packetNum == *associatedEvent; return packetNum == *associatedEvent;
}); });
if (it != conn.outstandingPackets.end()) { if (it != conn.outstandingPackets.end()) {
@@ -376,8 +376,7 @@ TEST_F(QuicLossFunctionsTest, TestMarkPacketLoss) {
EXPECT_EQ(1, conn->outstandingPackets.size()); EXPECT_EQ(1, conn->outstandingPackets.size());
auto& packet = auto& packet =
getFirstOutstandingPacket(*conn, PacketNumberSpace::AppData)->packet; getFirstOutstandingPacket(*conn, PacketNumberSpace::AppData)->packet;
auto packetNum = folly::variant_match( auto packetNum = packet.header.getPacketSequenceNum();
packet.header, [](const auto& h) { return h.getPacketSequenceNum(); });
markPacketLoss(*conn, packet, false, packetNum); markPacketLoss(*conn, packet, false, packetNum);
EXPECT_EQ(stream1->retransmissionBuffer.size(), 0); EXPECT_EQ(stream1->retransmissionBuffer.size(), 0);
EXPECT_EQ(stream2->retransmissionBuffer.size(), 0); EXPECT_EQ(stream2->retransmissionBuffer.size(), 0);
@@ -417,8 +416,7 @@ TEST_F(QuicLossFunctionsTest, TestMarkCryptoLostAfterCancelRetransmission) {
ASSERT_EQ(conn->outstandingPackets.size(), 1); ASSERT_EQ(conn->outstandingPackets.size(), 1);
EXPECT_GT(conn->cryptoState->handshakeStream.retransmissionBuffer.size(), 0); EXPECT_GT(conn->cryptoState->handshakeStream.retransmissionBuffer.size(), 0);
auto& packet = conn->outstandingPackets.front().packet; auto& packet = conn->outstandingPackets.front().packet;
auto packetNum = folly::variant_match( auto packetNum = packet.header.getPacketSequenceNum();
packet.header, [](const auto& h) { return h.getPacketSequenceNum(); });
cancelHandshakeCryptoStreamRetransmissions(*conn->cryptoState); cancelHandshakeCryptoStreamRetransmissions(*conn->cryptoState);
markPacketLoss(*conn, packet, false, packetNum); markPacketLoss(*conn, packet, false, packetNum);
EXPECT_EQ(conn->cryptoState->handshakeStream.retransmissionBuffer.size(), 0); EXPECT_EQ(conn->cryptoState->handshakeStream.retransmissionBuffer.size(), 0);
@@ -445,13 +443,7 @@ TEST_F(QuicLossFunctionsTest, TestMarkPacketLossAfterStreamReset) {
*stream1, *stream1,
StreamEvents::SendReset(GenericApplicationErrorCode::UNKNOWN)); StreamEvents::SendReset(GenericApplicationErrorCode::UNKNOWN));
markPacketLoss( markPacketLoss(*conn, packet, false, packet.header.getPacketSequenceNum());
*conn,
packet,
false,
folly::variant_match(packet.header, [](const auto& h) {
return h.getPacketSequenceNum();
}));
EXPECT_TRUE(stream1->lossBuffer.empty()); EXPECT_TRUE(stream1->lossBuffer.empty());
EXPECT_TRUE(stream1->retransmissionBuffer.empty()); EXPECT_TRUE(stream1->retransmissionBuffer.empty());
@@ -470,9 +462,7 @@ TEST_F(QuicLossFunctionsTest, TestReorderingThreshold) {
auto testingLossMarkFunc = auto testingLossMarkFunc =
[&lostPacket](auto& /*conn*/, auto& packet, bool, PacketNum) { [&lostPacket](auto& /*conn*/, auto& packet, bool, PacketNum) {
auto packetNum = folly::variant_match(packet.header, [](const auto& h) { auto packetNum = packet.header.getPacketSequenceNum();
return h.getPacketSequenceNum();
});
lostPacket.push_back(packetNum); lostPacket.push_back(packetNum);
}; };
for (int i = 0; i < 6; ++i) { for (int i = 0; i < 6; ++i) {
@@ -518,9 +508,8 @@ TEST_F(QuicLossFunctionsTest, TestReorderingThreshold) {
// Packet 6 should remain in packet as the delta is less than threshold // Packet 6 should remain in packet as the delta is less than threshold
EXPECT_EQ(conn->outstandingPackets.size(), 1); EXPECT_EQ(conn->outstandingPackets.size(), 1);
auto packetNum = folly::variant_match( auto packetNum =
conn->outstandingPackets.front().packet.header, conn->outstandingPackets.front().packet.header.getPacketSequenceNum();
[](const auto& h) { return h.getPacketSequenceNum(); });
EXPECT_EQ(packetNum, 6); EXPECT_EQ(packetNum, 6);
} }
@@ -644,13 +633,7 @@ TEST_F(QuicLossFunctionsTest, TestMarkRstLoss) {
EXPECT_TRUE(conn->pendingEvents.resets.empty()); EXPECT_TRUE(conn->pendingEvents.resets.empty());
auto& packet = auto& packet =
getFirstOutstandingPacket(*conn, PacketNumberSpace::AppData)->packet; getFirstOutstandingPacket(*conn, PacketNumberSpace::AppData)->packet;
markPacketLoss( markPacketLoss(*conn, packet, false, packet.header.getPacketSequenceNum());
*conn,
packet,
false,
folly::variant_match(packet.header, [](const auto& h) {
return h.getPacketSequenceNum();
}));
EXPECT_EQ(1, conn->pendingEvents.resets.size()); EXPECT_EQ(1, conn->pendingEvents.resets.size());
EXPECT_EQ(1, conn->pendingEvents.resets.count(stream->id)); EXPECT_EQ(1, conn->pendingEvents.resets.count(stream->id));
@@ -738,8 +721,7 @@ TEST_F(QuicLossFunctionsTest, TestMarkWindowUpdateLoss) {
auto& packet = auto& packet =
getFirstOutstandingPacket(*conn, PacketNumberSpace::AppData)->packet; getFirstOutstandingPacket(*conn, PacketNumberSpace::AppData)->packet;
auto packetNum = folly::variant_match( auto packetNum = packet.header.getPacketSequenceNum();
packet.header, [](const auto& h) { return h.getPacketSequenceNum(); });
markPacketLoss(*conn, packet, false, packetNum); markPacketLoss(*conn, packet, false, packetNum);
EXPECT_TRUE(conn->streamManager->pendingWindowUpdate(stream->id)); EXPECT_TRUE(conn->streamManager->pendingWindowUpdate(stream->id));
} }
@@ -779,10 +761,8 @@ TEST_F(QuicLossFunctionsTest, TestTimeReordering) {
// Packet 6, 7 should remain in outstanding packet list // Packet 6, 7 should remain in outstanding packet list
EXPECT_EQ(2, conn->outstandingPackets.size()); EXPECT_EQ(2, conn->outstandingPackets.size());
auto packetNum = folly::variant_match( auto packetNum = getFirstOutstandingPacket(*conn, PacketNumberSpace::AppData)
getFirstOutstandingPacket(*conn, PacketNumberSpace::AppData) ->packet.header.getPacketSequenceNum();
->packet.header,
[](const auto& h) { return h.getPacketSequenceNum(); });
EXPECT_EQ(packetNum, 6); EXPECT_EQ(packetNum, 6);
EXPECT_TRUE(conn->lossState.appDataLossTime); EXPECT_TRUE(conn->lossState.appDataLossTime);
} }
@@ -1335,8 +1315,7 @@ TEST_F(QuicLossFunctionsTest, TestZeroRttRejected) {
EXPECT_FALSE(lostPacket.second); EXPECT_FALSE(lostPacket.second);
} }
for (size_t i = 0; i < conn->outstandingPackets.size(); ++i) { for (size_t i = 0; i < conn->outstandingPackets.size(); ++i) {
auto longHeader = auto longHeader = conn->outstandingPackets[i].packet.header.asLong();
boost::get<LongHeader>(&conn->outstandingPackets[i].packet.header);
EXPECT_FALSE( EXPECT_FALSE(
longHeader && longHeader &&
longHeader->getProtectionType() == ProtectionType::ZeroRtt); longHeader->getProtectionType() == ProtectionType::ZeroRtt);
@@ -1388,8 +1367,7 @@ TEST_F(QuicLossFunctionsTest, TestZeroRttRejectedWithClones) {
} }
EXPECT_EQ(numProcessed, 1); EXPECT_EQ(numProcessed, 1);
for (size_t i = 0; i < conn->outstandingPackets.size(); ++i) { for (size_t i = 0; i < conn->outstandingPackets.size(); ++i) {
auto longHeader = auto longHeader = conn->outstandingPackets[i].packet.header.asLong();
boost::get<LongHeader>(&conn->outstandingPackets[i].packet.header);
EXPECT_FALSE( EXPECT_FALSE(
longHeader && longHeader &&
longHeader->getProtectionType() == ProtectionType::ZeroRtt); longHeader->getProtectionType() == ProtectionType::ZeroRtt);

View File

@@ -645,17 +645,11 @@ void onServerReadDataFromOpen(
conn.infoCallback, onPacketDropped, PacketDropReason::INVALID_PACKET); conn.infoCallback, onPacketDropped, PacketDropReason::INVALID_PACKET);
continue; continue;
} }
auto protectionLevel = folly::variant_match( auto protectionLevel = regularOptional->header.getProtectionType();
regularOptional->header,
[](auto& header) { return header.getProtectionType(); });
auto encryptionLevel = protectionTypeToEncryptionLevel(protectionLevel); auto encryptionLevel = protectionTypeToEncryptionLevel(protectionLevel);
auto packetNum = folly::variant_match( auto packetNum = regularOptional->header.getPacketSequenceNum();
regularOptional->header, auto packetNumberSpace = regularOptional->header.getPacketNumberSpace();
[](const auto& h) { return h.getPacketSequenceNum(); });
auto packetNumberSpace = folly::variant_match(
regularOptional->header,
[](auto& header) { return header.getPacketNumberSpace(); });
// TODO: enforce constraints on other protection levels. // TODO: enforce constraints on other protection levels.
auto& regularPacket = *regularOptional; auto& regularPacket = *regularOptional;
@@ -698,7 +692,12 @@ void onServerReadDataFromOpen(
// We assume that the higher layer takes care of validating that the version // We assume that the higher layer takes care of validating that the version
// is supported. // is supported.
if (!conn.version) { if (!conn.version) {
conn.version = boost::get<LongHeader>(regularPacket.header).getVersion(); LongHeader* longHeader = regularPacket.header.asLong();
if (!longHeader) {
throw QuicTransportException(
"Invalid packet type", TransportErrorCode::PROTOCOL_VIOLATION);
}
conn.version = longHeader->getVersion();
} }
if (conn.peerAddress != readData.peer) { if (conn.peerAddress != readData.peer) {
@@ -1096,16 +1095,9 @@ void onServerReadDataFromClosed(
} }
auto& regularPacket = *regularOptional; auto& regularPacket = *regularOptional;
auto protectionLevel = folly::variant_match( auto protectionLevel = regularPacket.header.getProtectionType();
regularPacket.header, auto packetNum = regularPacket.header.getPacketSequenceNum();
[](auto& header) { return header.getProtectionType(); }); auto pnSpace = regularPacket.header.getPacketNumberSpace();
auto packetNum = folly::variant_match(
regularOptional->header,
[](const auto& h) { return h.getPacketSequenceNum(); });
auto pnSpace = folly::variant_match(
regularOptional->header,
[](const auto& h) { return h.getPacketNumberSpace(); });
if (conn.qLogger) { if (conn.qLogger) {
conn.qLogger->addPacket(regularPacket, packetSize); conn.qLogger->addPacket(regularPacket, packetSize);
} }

View File

@@ -448,7 +448,7 @@ TEST_F(QuicServerWorkerTest, ZeroLengthConnectionId) {
EXPECT_CALL(*transportInfoCb_, onPacketDropped(_)).Times(0); EXPECT_CALL(*transportInfoCb_, onPacketDropped(_)).Times(0);
RegularQuicPacketBuilder builder( RegularQuicPacketBuilder builder(
kDefaultUDPSendPacketLen, header, 0 /* largestAcked */); kDefaultUDPSendPacketLen, std::move(header), 0 /* largestAcked */);
auto packet = packetToBuf(std::move(builder).buildPacket()); auto packet = packetToBuf(std::move(builder).buildPacket());
worker_->handleNetworkData(kClientAddr, std::move(packet), Clock::now()); worker_->handleNetworkData(kClientAddr, std::move(packet), Clock::now());
eventbase_.loop(); eventbase_.loop();
@@ -463,7 +463,7 @@ TEST_F(QuicServerWorkerTest, ConnectionIdTooShort) {
EXPECT_CALL(*transportInfoCb_, onPacketDropped(_)); EXPECT_CALL(*transportInfoCb_, onPacketDropped(_));
RegularQuicPacketBuilder builder( RegularQuicPacketBuilder builder(
kDefaultUDPSendPacketLen, header, 0 /* largestAcked */); kDefaultUDPSendPacketLen, std::move(header), 0 /* largestAcked */);
auto packet = packetToBuf(std::move(builder).buildPacket()); auto packet = packetToBuf(std::move(builder).buildPacket());
worker_->handleNetworkData(kClientAddr, std::move(packet), Clock::now()); worker_->handleNetworkData(kClientAddr, std::move(packet), Clock::now());
eventbase_.loop(); eventbase_.loop();
@@ -501,7 +501,7 @@ TEST_F(QuicServerWorkerTest, PacketAfterShutdown) {
EXPECT_CALL(*factory_, _make(_, _, _, _)).Times(0); EXPECT_CALL(*factory_, _make(_, _, _, _)).Times(0);
RegularQuicPacketBuilder builder( RegularQuicPacketBuilder builder(
kDefaultUDPSendPacketLen, header, 0 /* largestAcked */); kDefaultUDPSendPacketLen, std::move(header), 0 /* largestAcked */);
auto packet = packetToBuf(std::move(builder).buildPacket()); auto packet = packetToBuf(std::move(builder).buildPacket());
worker_->handleNetworkData(kClientAddr, std::move(packet), Clock::now()); worker_->handleNetworkData(kClientAddr, std::move(packet), Clock::now());
eventbase_.terminateLoopSoon(); eventbase_.terminateLoopSoon();
@@ -544,7 +544,7 @@ auto createInitialStream(
destConnId, destConnId,
packetNum, packetNum,
version, version,
IOBuf::copyBuffer("this is a retry token :)"), std::string("this is a retry token :)"),
getTestConnectionId()); getTestConnectionId());
RegularQuicPacketBuilder builder( RegularQuicPacketBuilder builder(
kDefaultUDPSendPacketLen, kDefaultUDPSendPacketLen,
@@ -806,15 +806,12 @@ void QuicServerWorkerTakeoverTest::testPacketForwarding(
// parse header and check connId to verify the integrity of the packet // parse header and check connId to verify the integrity of the packet
auto parsedHeader = parseHeader(*writtenData); auto parsedHeader = parseHeader(*writtenData);
auto& header = parsedHeader->parsedHeader; auto& header = parsedHeader->parsedHeader;
const auto& connectionId = folly::variant_match( LongHeader* longHeader = header->asLong();
header.value(), if (longHeader) {
[](const LongHeader& longHeader) { EXPECT_EQ(connId, longHeader->getDestinationConnId());
return longHeader.getDestinationConnId(); } else {
}, EXPECT_EQ(connId, header->asShort()->getConnectionId());
[](const ShortHeader& shortHeader) { }
return shortHeader.getConnectionId();
});
EXPECT_EQ(connId, connectionId);
return data->computeChainDataLength(); return data->computeChainDataLength();
})); }));
takeoverWorker_->startPacketForwarding(folly::SocketAddress("0", 0)); takeoverWorker_->startPacketForwarding(folly::SocketAddress("0", 0));

View File

@@ -494,16 +494,12 @@ class QuicServerTransportTest : public Test {
auto aead = getInitialCipher(); auto aead = getInitialCipher();
auto headerCipher = getInitialHeaderCipher(); auto headerCipher = getInitialHeaderCipher();
IntervalSet<quic::PacketNum> acks; IntervalSet<quic::PacketNum> acks;
auto start = folly::variant_match( auto start = getFirstOutstandingPacket(
getFirstOutstandingPacket( server->getNonConstConn(), PacketNumberSpace::Initial)
server->getNonConstConn(), PacketNumberSpace::Initial) ->packet.header.getPacketSequenceNum();
->packet.header, auto end = getLastOutstandingPacket(
[](auto& h) { return h.getPacketSequenceNum(); }); server->getNonConstConn(), PacketNumberSpace::Initial)
auto end = folly::variant_match( ->packet.header.getPacketSequenceNum();
getLastOutstandingPacket(
server->getNonConstConn(), PacketNumberSpace::Initial)
->packet.header,
[](auto& h) { return h.getPacketSequenceNum(); });
acks.insert(start, end); acks.insert(start, end);
auto pn = clientNextInitialPacketNum++; auto pn = clientNextInitialPacketNum++;
auto ackPkt = createAckPacket( auto ackPkt = createAckPacket(
@@ -879,16 +875,12 @@ TEST_F(QuicServerTransportTest, TestCloseConnectionWithNoErrorPendingStreams) {
loopForWrites(); loopForWrites();
IntervalSet<quic::PacketNum> acks; IntervalSet<quic::PacketNum> acks;
auto start = folly::variant_match( auto start = getFirstOutstandingPacket(
getFirstOutstandingPacket( server->getNonConstConn(), PacketNumberSpace::AppData)
server->getNonConstConn(), PacketNumberSpace::AppData) ->packet.header.getPacketSequenceNum();
->packet.header, auto end = getLastOutstandingPacket(
[](auto& h) { return h.getPacketSequenceNum(); }); server->getNonConstConn(), PacketNumberSpace::AppData)
auto end = folly::variant_match( ->packet.header.getPacketSequenceNum();
getLastOutstandingPacket(
server->getNonConstConn(), PacketNumberSpace::AppData)
->packet.header,
[](auto& h) { return h.getPacketSequenceNum(); });
acks.insert(start, end); acks.insert(start, end);
deliverData(packetToBuf(createAckPacket( deliverData(packetToBuf(createAckPacket(
server->getNonConstConn(), server->getNonConstConn(),
@@ -953,7 +945,9 @@ TEST_F(QuicServerTransportTest, ReceiveCloseAfterLocalError) {
*server->getConn().serverConnectionId, *server->getConn().serverConnectionId,
clientNextAppDataPacketNum++); clientNextAppDataPacketNum++);
RegularQuicPacketBuilder builder( RegularQuicPacketBuilder builder(
server->getConn().udpSendPacketLen, header, 0 /* largestAcked */); server->getConn().udpSendPacketLen,
std::move(header),
0 /* largestAcked */);
ASSERT_TRUE(builder.canBuildPacket()); ASSERT_TRUE(builder.canBuildPacket());
// Deliver a reset to non existent stream to trigger a local conn error // Deliver a reset to non existent stream to trigger a local conn error
@@ -1071,30 +1065,25 @@ TEST_F(QuicServerTransportTest, TestOpenAckStreamFrame) {
// We need more than one packet for this test. // We need more than one packet for this test.
ASSERT_FALSE(server->getConn().outstandingPackets.empty()); ASSERT_FALSE(server->getConn().outstandingPackets.empty());
PacketNum packetNum1 = folly::variant_match( PacketNum packetNum1 =
getFirstOutstandingPacket( getFirstOutstandingPacket(
server->getNonConstConn(), PacketNumberSpace::AppData) server->getNonConstConn(), PacketNumberSpace::AppData)
->packet.header, ->packet.header.getPacketSequenceNum();
[](auto& h) { return h.getPacketSequenceNum(); });
PacketNum lastPacketNum = folly::variant_match( PacketNum lastPacketNum =
getLastOutstandingPacket( getLastOutstandingPacket(
server->getNonConstConn(), PacketNumberSpace::AppData) server->getNonConstConn(), PacketNumberSpace::AppData)
->packet.header, ->packet.header.getPacketSequenceNum();
[](auto& h) { return h.getPacketSequenceNum(); });
uint32_t buffersInPacket1 = 0; uint32_t buffersInPacket1 = 0;
for (size_t i = 0; i < server->getNonConstConn().outstandingPackets.size(); for (size_t i = 0; i < server->getNonConstConn().outstandingPackets.size();
++i) { ++i) {
auto& packet = server->getNonConstConn().outstandingPackets[i]; auto& packet = server->getNonConstConn().outstandingPackets[i];
if (PacketNumberSpace::AppData != if (packet.packet.header.getPacketNumberSpace() !=
folly::variant_match(packet.packet.header, [](auto& h) { PacketNumberSpace::AppData) {
return h.getPacketNumberSpace();
})) {
continue; continue;
} }
PacketNum currentPacket = folly::variant_match( PacketNum currentPacket = packet.packet.header.getPacketSequenceNum();
packet.packet.header, [](auto& h) { return h.getPacketSequenceNum(); });
ASSERT_FALSE(packet.packet.frames.empty()); ASSERT_FALSE(packet.packet.frames.empty());
for (auto& quicFrame : packet.packet.frames) { for (auto& quicFrame : packet.packet.frames) {
auto frame = boost::get<WriteStreamFrame>(&quicFrame); auto frame = boost::get<WriteStreamFrame>(&quicFrame);
@@ -1159,11 +1148,10 @@ TEST_F(QuicServerTransportTest, TestOpenAckStreamFrame) {
loopForWrites(); loopForWrites();
ASSERT_FALSE(server->getConn().outstandingPackets.empty()); ASSERT_FALSE(server->getConn().outstandingPackets.empty());
PacketNum finPacketNum = folly::variant_match( PacketNum finPacketNum =
getFirstOutstandingPacket( getFirstOutstandingPacket(
server->getNonConstConn(), PacketNumberSpace::AppData) server->getNonConstConn(), PacketNumberSpace::AppData)
->packet.header, ->packet.header.getPacketSequenceNum();
[](auto& h) { return h.getPacketSequenceNum(); });
IntervalSet<PacketNum> acks3 = {{lastPacketNum, finPacketNum}}; IntervalSet<PacketNum> acks3 = {{lastPacketNum, finPacketNum}};
auto packet4 = createAckPacket( auto packet4 = createAckPacket(
@@ -1670,9 +1658,7 @@ TEST_F(QuicServerTransportTest, TestAckStopSending) {
}; };
auto op = findOutstandingPacket(server->getNonConstConn(), match); auto op = findOutstandingPacket(server->getNonConstConn(), match);
ASSERT_TRUE(op != nullptr); ASSERT_TRUE(op != nullptr);
PacketNum packetNum = folly::variant_match( PacketNum packetNum = op->packet.header.getPacketSequenceNum();
op->packet.header,
[](const auto& h) { return h.getPacketSequenceNum(); });
IntervalSet<PacketNum> acks = {{packetNum, packetNum}}; IntervalSet<PacketNum> acks = {{packetNum, packetNum}};
auto packet1 = createAckPacket( auto packet1 = createAckPacket(
server->getNonConstConn(), server->getNonConstConn(),
@@ -2986,13 +2972,9 @@ TEST_F(QuicUnencryptedServerTransportTest, TestWriteHandshakeAndZeroRtt) {
auto parsedPacket = boost::get<QuicPacket>(&result); auto parsedPacket = boost::get<QuicPacket>(&result);
CHECK(parsedPacket); CHECK(parsedPacket);
auto& regularPacket = boost::get<RegularQuicPacket>(*parsedPacket); auto& regularPacket = boost::get<RegularQuicPacket>(*parsedPacket);
bool handshakePacket = folly::variant_match( ProtectionType protectionType = regularPacket.header.getProtectionType();
regularPacket.header, bool handshakePacket = protectionType == ProtectionType::Initial ||
[](const LongHeader& h) { protectionType == ProtectionType::Handshake;
return h.getProtectionType() == ProtectionType::Initial ||
h.getProtectionType() == ProtectionType::Handshake;
},
[](const auto&) { return false; });
EXPECT_GE(regularPacket.frames.size(), 1); EXPECT_GE(regularPacket.frames.size(), 1);
bool hasCryptoFrame = false; bool hasCryptoFrame = false;
bool hasNonCryptoStream = false; bool hasNonCryptoStream = false;

View File

@@ -39,9 +39,7 @@ void processAckFrame(
conn.outstandingPackets.end(), conn.outstandingPackets.end(),
ackBlockIt->startPacket, ackBlockIt->startPacket,
[&](const auto& packetWithTime, const auto& val) { [&](const auto& packetWithTime, const auto& val) {
return folly::variant_match( return packetWithTime.packet.header.getPacketSequenceNum() < val;
packetWithTime.packet.header,
[&val](const auto& h) { return h.getPacketSequenceNum() < val; });
}); });
if (packetIt == conn.outstandingPackets.end()) { if (packetIt == conn.outstandingPackets.end()) {
// This means that all the packets are less than the start packet. // This means that all the packets are less than the start packet.
@@ -60,12 +58,9 @@ void processAckFrame(
// or equal to crypto protection level. // or equal to crypto protection level.
auto packetItEnd = packetIt; auto packetItEnd = packetIt;
while (packetItEnd != conn.outstandingPackets.end()) { while (packetItEnd != conn.outstandingPackets.end()) {
auto currentPacketNum = folly::variant_match( auto currentPacketNum = packetItEnd->packet.header.getPacketSequenceNum();
packetItEnd->packet.header, auto currentPacketNumberSpace =
[](const auto& h) { return h.getPacketSequenceNum(); }); packetItEnd->packet.header.getPacketNumberSpace();
auto currentPacketNumberSpace = folly::variant_match(
packetItEnd->packet.header,
[](const auto& h) { return h.getPacketNumberSpace(); });
if (pnSpace != currentPacketNumberSpace) { if (pnSpace != currentPacketNumberSpace) {
packetItEnd++; packetItEnd++;
continue; continue;

View File

@@ -210,10 +210,7 @@ std::deque<OutstandingPacket>::iterator getNextOutstandingPacket(
PacketNumberSpace packetNumberSpace, PacketNumberSpace packetNumberSpace,
std::deque<OutstandingPacket>::iterator from) { std::deque<OutstandingPacket>::iterator from) {
return std::find_if(from, conn.outstandingPackets.end(), [=](const auto& op) { return std::find_if(from, conn.outstandingPackets.end(), [=](const auto& op) {
return packetNumberSpace == return packetNumberSpace == op.packet.header.getPacketNumberSpace();
folly::variant_match(op.packet.header, [](const auto& h) {
return h.getPacketNumberSpace();
});
}); });
} }

View File

@@ -215,9 +215,7 @@ struct CongestionController {
"LossEvent: lostBytes overflow", "LossEvent: lostBytes overflow",
LocalErrorCode::LOST_BYTES_OVERFLOW); LocalErrorCode::LOST_BYTES_OVERFLOW);
} }
auto packetNum = folly::variant_match( PacketNum packetNum = packet.packet.header.getPacketSequenceNum();
packet.packet.header,
[](const auto& header) { return header.getPacketSequenceNum(); });
largestLostPacketNum = largestLostPacketNum =
std::max(packetNum, largestLostPacketNum.value_or(packetNum)); std::max(packetNum, largestLostPacketNum.value_or(packetNum));
lostBytes += packet.encodedSize; lostBytes += packet.encodedSize;

View File

@@ -29,8 +29,7 @@ class AckHandlersTest : public TestWithParam<PacketNumberSpace> {};
auto testLossHandler(std::vector<PacketNum>& lostPackets) -> decltype(auto) { auto testLossHandler(std::vector<PacketNum>& lostPackets) -> decltype(auto) {
return [&lostPackets]( return [&lostPackets](
QuicConnectionStateBase&, auto& packet, bool, PacketNum) { QuicConnectionStateBase&, auto& packet, bool, PacketNum) {
auto packetNum = folly::variant_match( auto packetNum = packet.header.getPacketSequenceNum();
packet.header, [](const auto& h) { return h.getPacketSequenceNum(); });
lostPackets.push_back(packetNum); lostPackets.push_back(packetNum);
}; };
} }
@@ -102,9 +101,7 @@ TEST_P(AckHandlersTest, TestAckMultipleSequentialBlocks) {
} }
PacketNum packetNum = 16; PacketNum packetNum = 16;
for (auto& packet : conn.outstandingPackets) { for (auto& packet : conn.outstandingPackets) {
auto currentPacketNum = folly::variant_match( auto currentPacketNum = packet.packet.header.getPacketSequenceNum();
packet.packet.header,
[](const auto& h) { return h.getPacketSequenceNum(); });
EXPECT_EQ(currentPacketNum, packetNum); EXPECT_EQ(currentPacketNum, packetNum);
packetNum++; packetNum++;
} }
@@ -195,9 +192,7 @@ TEST_P(AckHandlersTest, TestAckBlocksWithGaps) {
std::back_insert_iterator<decltype(actualPacketNumbers)>( std::back_insert_iterator<decltype(actualPacketNumbers)>(
actualPacketNumbers), actualPacketNumbers),
[](const auto& packet) { [](const auto& packet) {
return folly::variant_match(packet.packet.header, [](const auto& h) { return packet.packet.header.getPacketSequenceNum();
return h.getPacketSequenceNum();
});
}); });
EXPECT_TRUE(std::equal( EXPECT_TRUE(std::equal(
@@ -299,9 +294,7 @@ TEST_P(AckHandlersTest, TestNonSequentialPacketNumbers) {
std::back_insert_iterator<decltype(actualPacketNumbers)>( std::back_insert_iterator<decltype(actualPacketNumbers)>(
actualPacketNumbers), actualPacketNumbers),
[](const auto& packet) { [](const auto& packet) {
return folly::variant_match(packet.packet.header, [](const auto& h) { return packet.packet.header.getPacketSequenceNum();
return h.getPacketSequenceNum();
});
}); });
EXPECT_TRUE(std::equal( EXPECT_TRUE(std::equal(
@@ -344,9 +337,8 @@ TEST_P(AckHandlersTest, AckVisitorForAckTest) {
[&](const auto& outstandingPacket, [&](const auto& outstandingPacket,
const auto& packetFrame, const auto& packetFrame,
const ReadAckFrame&) { const ReadAckFrame&) {
auto ackedPacketNum = folly::variant_match( auto ackedPacketNum =
outstandingPacket.packet.header, outstandingPacket.packet.header.getPacketSequenceNum();
[](const auto& h) { return h.getPacketSequenceNum(); });
EXPECT_EQ(ackedPacketNum, firstReceivedAck.largestAcked); EXPECT_EQ(ackedPacketNum, firstReceivedAck.largestAcked);
folly::variant_match( folly::variant_match(
packetFrame, packetFrame,