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
// before crypto negotiation, so the peer might not know about the ack delay
// exponent yet, so we use the default.
uint8_t ackDelayExponentToUse = folly::variant_match(
builder.getPacketHeader(),
[](const LongHeader&) { return kDefaultAckDelayExponent; },
[&](const auto&) { return conn_.transportSettings.ackDelayExponent; });
uint8_t ackDelayExponentToUse =
builder.getPacketHeader().getHeaderForm() == HeaderForm::Long
? kDefaultAckDelayExponent
: conn_.transportSettings.ackDelayExponent;
auto largestAckedPacketNum = *largestAckToSend(ackState_);
auto ackingTime = ClockType::now();
DCHECK(ackState_.largestRecvdPacketTime.hasValue())

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -104,10 +104,9 @@ ReadAckFrame decodeAckFrame(
// 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 for all the long header packets.
uint8_t ackDelayExponentToUse = folly::variant_match(
header,
[](const LongHeader&) { return kDefaultAckDelayExponent; },
[&params](auto&) { return params.peerAckDelayExponent; });
uint8_t ackDelayExponentToUse = (header.getHeaderForm() == HeaderForm::Long)
? kDefaultAckDelayExponent
: params.peerAckDelayExponent;
DCHECK_LT(ackDelayExponentToUse, sizeof(ackDelay->first) * 8);
// ackDelayExponentToUse is guaranteed to be less than the size of uint64_t
uint64_t delayOverflowMask = 0xFFFFFFFFFFFFFFFF;
@@ -986,7 +985,7 @@ folly::Expected<ParsedLongHeader, TransportErrorCode> parseLongHeaderVariants(
LongHeader(
type,
std::move(parsedLongHeaderInvariant.invariant),
std::move(token),
token ? token->moveToFbString().toStdString() : std::string(),
std::move(originalDstConnId)),
PacketLength(0, 0));
}
@@ -1037,7 +1036,7 @@ folly::Expected<ParsedLongHeader, TransportErrorCode> parseLongHeaderVariants(
LongHeader(
type,
std::move(parsedLongHeaderInvariant.invariant),
std::move(token)),
token ? token->moveToFbString().toStdString() : std::string()),
PacketLength(pktLen->first, pktLen->second));
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -627,6 +627,8 @@ struct LongHeaderInvariant {
// TODO: split this into read and write types.
struct LongHeader {
public:
virtual ~LongHeader() = default;
static constexpr uint8_t kFixedBitMask = 0x40;
static constexpr uint8_t kPacketTypeMask = 0x30;
static constexpr uint8_t kReservedBitsMask = 0x0c;
@@ -647,40 +649,33 @@ struct LongHeader {
const ConnectionId& dstConnId,
PacketNum packetNum,
QuicVersion version,
Buf token = nullptr,
const std::string& token = std::string(),
folly::Optional<ConnectionId> originalDstConnId = folly::none);
LongHeader(
Types type,
LongHeaderInvariant invariant,
Buf token = nullptr,
const std::string& token = std::string(),
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;
const ConnectionId& getSourceConnId() const;
const ConnectionId& getDestinationConnId() const;
const folly::Optional<ConnectionId>& getOriginalDstConnId() const;
PacketNum getPacketSequenceNum() const;
QuicVersion getVersion() const;
PacketNumberSpace getPacketNumberSpace() const;
ProtectionType getProtectionType() const;
PacketNumberSpace getPacketNumberSpace() const noexcept;
bool hasToken() const;
folly::IOBuf* getToken() const;
const std::string& getToken() const;
PacketNum getPacketSequenceNum() const;
void setPacketNumber(PacketNum packetNum);
private:
HeaderForm headerForm_;
PacketNum packetSequenceNum_{0};
Types longHeaderType_;
LongHeaderInvariant invariant_;
folly::Optional<PacketNum> packetSequenceNum_; // at most 32 bits on wire
Buf token_;
std::string token_;
folly::Optional<ConnectionId> originalDstConnId_;
};
@@ -692,6 +687,8 @@ struct ShortHeaderInvariant {
struct ShortHeader {
public:
virtual ~ShortHeader() = default;
// 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 kReservedBitsMask = 0x18;
@@ -712,11 +709,10 @@ struct ShortHeader {
ConnectionId connId,
PacketNum packetNum);
ProtectionType getProtectionType() const noexcept;
PacketNumberSpace getPacketNumberSpace() const noexcept;
const ConnectionId& getConnectionId() const;
ProtectionType getProtectionType() const;
PacketNumberSpace getPacketNumberSpace() const;
PacketNum getPacketSequenceNum() const;
const ConnectionId& getConnectionId() const;
void setPacketNumber(PacketNum packetNum);
@@ -729,16 +725,48 @@ struct ShortHeader {
folly::io::Cursor& cursor);
private:
HeaderForm headerForm_;
PacketNum packetSequenceNum_{0};
ProtectionType protectionType_;
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);
PacketNumberSpace longHeaderTypeToPacketNumberSpace(LongHeader::Types type);
using PacketHeader = boost::variant<LongHeader, ShortHeader>;
PacketNumberSpace longHeaderTypeToPacketNumberSpace(LongHeader::Types type);
struct StreamTypeField {
public:
@@ -791,8 +819,7 @@ struct VersionNegotiationPacket {
struct RegularPacket {
PacketHeader header;
explicit RegularPacket(PacketHeader&& headerIn)
: header(std::move(headerIn)) {}
explicit RegularPacket(PacketHeader&& headerIn) : header(std::move(headerIn)) {}
};
/**
@@ -842,17 +869,16 @@ inline std::ostream& operator<<(
}
inline std::ostream& operator<<(std::ostream& os, const PacketHeader& header) {
folly::variant_match(
header,
[&os](const LongHeader& h) {
os << "header=long"
<< " protectionType=" << (int)h.getProtectionType()
<< " type=" << std::hex << (int)h.getHeaderType();
},
[&os](const ShortHeader& h) {
os << "header=short"
<< " protectionType=" << (int)h.getProtectionType();
});
auto shortHeader = header.asShort();
if (shortHeader) {
os << "header=short"
<< " protectionType=" << (int)shortHeader->getProtectionType();
} else {
auto longHeader = header.asLong();
os << "header=long"
<< " protectionType=" << (int)longHeader->getProtectionType()
<< " type=" << std::hex << (int)longHeader->getHeaderType();
}
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));
auto header = makeHeader();
auto result1 = createAckFrame(
largestAcked,
folly::none,
@@ -373,7 +372,7 @@ TEST_F(DecodeTest, AckFrameMissingFields) {
EXPECT_THROW(
decodeAckFrame(
cursor1,
header,
makeHeader(),
CodecParameters(kDefaultAckDelayExponent, QuicVersion::MVFST)),
QuicTransportException);
@@ -383,7 +382,7 @@ TEST_F(DecodeTest, AckFrameMissingFields) {
EXPECT_THROW(
decodeAckFrame(
cursor2,
header,
makeHeader(),
CodecParameters(kDefaultAckDelayExponent, QuicVersion::MVFST)),
QuicTransportException);
@@ -393,7 +392,7 @@ TEST_F(DecodeTest, AckFrameMissingFields) {
EXPECT_THROW(
decodeAckFrame(
cursor3,
header,
makeHeader(),
CodecParameters(kDefaultAckDelayExponent, QuicVersion::MVFST)),
QuicTransportException);
@@ -403,7 +402,7 @@ TEST_F(DecodeTest, AckFrameMissingFields) {
EXPECT_THROW(
decodeAckFrame(
cursor4,
header,
makeHeader(),
CodecParameters(kDefaultAckDelayExponent, QuicVersion::MVFST)),
QuicTransportException);
@@ -413,7 +412,7 @@ TEST_F(DecodeTest, AckFrameMissingFields) {
EXPECT_THROW(
decodeAckFrame(
cursor5,
header,
makeHeader(),
CodecParameters(kDefaultAckDelayExponent, QuicVersion::MVFST)),
QuicTransportException);
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -61,7 +61,7 @@ folly::Expected<ParsedLongHeaderResult, TransportErrorCode> makeLongHeader(
getTestConnectionId(),
321,
QuicVersion::QUIC_DRAFT,
IOBuf::copyBuffer("this is a retry token :)"),
std::string("this is a retry token :)"),
getTestConnectionId());
RegularQuicPacketBuilder builder(
@@ -261,5 +261,39 @@ TEST_F(TypesTest, LongHeaderPacketNumberSpace) {
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 quic

View File

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

View File

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

View File

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

View File

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

View File

@@ -23,17 +23,16 @@ std::unique_ptr<QLogPacketEvent> QLogger::createPacketEvent(
std::chrono::steady_clock::now() - refTimePoint);
event->packetSize = packetSize;
event->eventType = QLogEventType::PacketReceived;
event->packetType = folly::variant_match(
regularPacket.header,
[](const LongHeader& header) { return toString(header.getHeaderType()); },
[](const ShortHeader& /* unused*/) {
return kShortHeaderPacketType.toString();
});
const ShortHeader* shortHeader = regularPacket.header.asShort();
if (shortHeader) {
event->packetType = kShortHeaderPacketType.toString();
} else {
event->packetType =
toString(regularPacket.header.asLong()->getHeaderType());
}
if (event->packetType != toString(LongHeader::Types::Retry)) {
// A Retry packet does not include a packet number.
event->packetNum = folly::variant_match(
regularPacket.header,
[](const auto& h) { return h.getPacketSequenceNum(); });
event->packetNum = regularPacket.header.getPacketSequenceNum();
}
uint64_t numPaddingFrames = 0;
@@ -149,17 +148,15 @@ std::unique_ptr<QLogPacketEvent> QLogger::createPacketEvent(
auto event = std::make_unique<QLogPacketEvent>();
event->refTime = std::chrono::duration_cast<std::chrono::microseconds>(
std::chrono::steady_clock::now() - refTimePoint);
event->packetNum = folly::variant_match(
writePacket.header,
[](const auto& h) { return h.getPacketSequenceNum(); });
event->packetNum = writePacket.header.getPacketSequenceNum();
event->packetSize = packetSize;
event->eventType = QLogEventType::PacketSent;
event->packetType = folly::variant_match(
writePacket.header,
[](const LongHeader& header) { return toString(header.getHeaderType()); },
[](const ShortHeader& /* unused*/) {
return kShortHeaderPacketType.toString();
});
const ShortHeader* shortHeader = writePacket.header.asShort();
if (shortHeader) {
event->packetType = kShortHeaderPacketType.toString();
} else {
event->packetType = toString(writePacket.header.asLong()->getHeaderType());
}
uint64_t numPaddingFrames = 0;
// 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) {
auto headerIn =
ShortHeader(ProtectionType::KeyPhaseZero, getTestConnectionId(1), 1);
RegularQuicPacket regularQuicPacket(headerIn);
RegularQuicPacket regularQuicPacket(std::move(headerIn));
ReadStreamFrame frame(streamId, offset, fin);
regularQuicPacket.frames.emplace_back(std::move(frame));
@@ -341,7 +341,7 @@ TEST_F(QLoggerTest, QLoggerFollyDynamic) {
auto headerIn =
ShortHeader(ProtectionType::KeyPhaseZero, getTestConnectionId(1), 1);
RegularQuicPacket regularQuicPacket(headerIn);
RegularQuicPacket regularQuicPacket(std::move(headerIn));
ReadStreamFrame frame(streamId, offset, fin);
regularQuicPacket.frames.emplace_back(std::move(frame));
@@ -384,7 +384,7 @@ TEST_F(QLoggerTest, RegularPacketFollyDynamic) {
auto headerIn =
ShortHeader(ProtectionType::KeyPhaseZero, getTestConnectionId(1), 1);
RegularQuicPacket regularQuicPacket(headerIn);
RegularQuicPacket regularQuicPacket(std::move(headerIn));
ReadStreamFrame frame(streamId, offset, fin);
regularQuicPacket.frames.emplace_back(std::move(frame));

View File

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

View File

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

View File

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

View File

@@ -645,17 +645,11 @@ void onServerReadDataFromOpen(
conn.infoCallback, onPacketDropped, PacketDropReason::INVALID_PACKET);
continue;
}
auto protectionLevel = folly::variant_match(
regularOptional->header,
[](auto& header) { return header.getProtectionType(); });
auto protectionLevel = regularOptional->header.getProtectionType();
auto encryptionLevel = protectionTypeToEncryptionLevel(protectionLevel);
auto packetNum = folly::variant_match(
regularOptional->header,
[](const auto& h) { return h.getPacketSequenceNum(); });
auto packetNumberSpace = folly::variant_match(
regularOptional->header,
[](auto& header) { return header.getPacketNumberSpace(); });
auto packetNum = regularOptional->header.getPacketSequenceNum();
auto packetNumberSpace = regularOptional->header.getPacketNumberSpace();
// TODO: enforce constraints on other protection levels.
auto& regularPacket = *regularOptional;
@@ -698,7 +692,12 @@ void onServerReadDataFromOpen(
// We assume that the higher layer takes care of validating that the version
// is supported.
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) {
@@ -1096,16 +1095,9 @@ void onServerReadDataFromClosed(
}
auto& regularPacket = *regularOptional;
auto protectionLevel = folly::variant_match(
regularPacket.header,
[](auto& header) { return header.getProtectionType(); });
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(); });
auto protectionLevel = regularPacket.header.getProtectionType();
auto packetNum = regularPacket.header.getPacketSequenceNum();
auto pnSpace = regularPacket.header.getPacketNumberSpace();
if (conn.qLogger) {
conn.qLogger->addPacket(regularPacket, packetSize);
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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