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

Refactor QuicClient and Server transports to process ReceivedUdpPackets with attached metadata

Summary: ReceivedUdpPacket has attached metadata (currently timings and later in the stack, tos values). Rather than passing the metadata separately in the read path for the client and the server, this propagates the ReceivedUdpPacket further up so this metadata is easier to use in the rest of the stack.

Reviewed By: mjoras

Differential Revision: D54912162

fbshipit-source-id: c980d5b276704f5bba780ac16a380bbb4e5bedad
This commit is contained in:
Joseph Beshay
2024-05-09 11:05:32 -07:00
committed by Facebook GitHub Bot
parent fdf1b30412
commit 7f2cb16408
15 changed files with 108 additions and 93 deletions

View File

@@ -1876,7 +1876,7 @@ void QuicTransportBase::onNetworkData(
SocketObserverInterface::PacketsReceivedEvent::ReceivedUdpPacket:: SocketObserverInterface::PacketsReceivedEvent::ReceivedUdpPacket::
Builder() Builder()
.setPacketReceiveTime(packet.timings.receiveTimePoint) .setPacketReceiveTime(packet.timings.receiveTimePoint)
.setPacketNumBytes(packet.buf->computeChainDataLength()) .setPacketNumBytes(packet.buf.chainLength())
.build()); .build());
} }

View File

@@ -273,10 +273,10 @@ class TestQuicTransport
void onReadData(const folly::SocketAddress&, ReceivedUdpPacket&& udpPacket) void onReadData(const folly::SocketAddress&, ReceivedUdpPacket&& udpPacket)
override { override {
if (!udpPacket.buf) { if (udpPacket.buf.empty()) {
return; return;
} }
folly::io::Cursor cursor(udpPacket.buf.get()); folly::io::Cursor cursor(udpPacket.buf.front());
while (!cursor.isAtEnd()) { while (!cursor.isAtEnd()) {
// create server chosen connId with processId = 0 and workerId = 0 // create server chosen connId with processId = 0 and workerId = 0
ServerConnectionIdParams params(0, 0, 0); ServerConnectionIdParams params(0, 0, 0);

View File

@@ -123,8 +123,7 @@ void QuicClientTransport::processUdpPacket(
ReceivedUdpPacket&& udpPacket) { ReceivedUdpPacket&& udpPacket) {
// Process the arriving UDP packet, which may have coalesced QUIC packets. // Process the arriving UDP packet, which may have coalesced QUIC packets.
{ {
BufQueue udpData; BufQueue& udpData = udpPacket.buf;
udpData.append(std::move(udpPacket.buf));
if (!conn_->version) { if (!conn_->version) {
// We only check for version negotiation packets before the version // We only check for version negotiation packets before the version
@@ -145,7 +144,7 @@ void QuicClientTransport::processUdpPacket(
for (uint16_t processedPackets = 0; for (uint16_t processedPackets = 0;
!udpData.empty() && processedPackets < kMaxNumCoalescedPackets; !udpData.empty() && processedPackets < kMaxNumCoalescedPackets;
processedPackets++) { processedPackets++) {
processUdpPacketData(peer, udpPacket.timings, udpData); processUdpPacketData(peer, udpPacket);
} }
VLOG_IF(4, !udpData.empty()) VLOG_IF(4, !udpData.empty())
<< "Leaving " << udpData.chainLength() << "Leaving " << udpData.chainLength()
@@ -156,23 +155,23 @@ void QuicClientTransport::processUdpPacket(
// Process any deferred pending 1RTT and handshake packets if we have keys. // Process any deferred pending 1RTT and handshake packets if we have keys.
if (conn_->readCodec->getOneRttReadCipher() && if (conn_->readCodec->getOneRttReadCipher() &&
!clientConn_->pendingOneRttData.empty()) { !clientConn_->pendingOneRttData.empty()) {
BufQueue pendingPacket; for (auto& pendingPacket : clientConn_->pendingOneRttData) {
for (auto& pendingData : clientConn_->pendingOneRttData) { // The first loop should try to process any leftover data in the incoming
pendingPacket.append(std::move(pendingData.udpPacket.buf)); // buffer.
processUdpPacketData( pendingPacket.udpPacket.buf.append(udpPacket.buf.move());
pendingData.peer, pendingData.udpPacket.timings, pendingPacket);
pendingPacket.move(); processUdpPacketData(pendingPacket.peer, pendingPacket.udpPacket);
} }
clientConn_->pendingOneRttData.clear(); clientConn_->pendingOneRttData.clear();
} }
if (conn_->readCodec->getHandshakeReadCipher() && if (conn_->readCodec->getHandshakeReadCipher() &&
!clientConn_->pendingHandshakeData.empty()) { !clientConn_->pendingHandshakeData.empty()) {
BufQueue pendingPacket; for (auto& pendingPacket : clientConn_->pendingHandshakeData) {
for (auto& pendingData : clientConn_->pendingHandshakeData) { // The first loop should try to process any leftover data in the incoming
pendingPacket.append(std::move(pendingData.udpPacket.buf)); // buffer.
processUdpPacketData( pendingPacket.udpPacket.buf.append(udpPacket.buf.move());
pendingData.peer, pendingData.udpPacket.timings, pendingPacket);
pendingPacket.move(); processUdpPacketData(pendingPacket.peer, pendingPacket.udpPacket);
} }
clientConn_->pendingHandshakeData.clear(); clientConn_->pendingHandshakeData.clear();
} }
@@ -180,14 +179,13 @@ void QuicClientTransport::processUdpPacket(
void QuicClientTransport::processUdpPacketData( void QuicClientTransport::processUdpPacketData(
const folly::SocketAddress& peer, const folly::SocketAddress& peer,
const ReceivedUdpPacket::Timings& udpPacketTimings, ReceivedUdpPacket& udpPacket) {
BufQueue& udpPacketData) { auto packetSize = udpPacket.buf.chainLength();
auto packetSize = udpPacketData.chainLength();
if (packetSize == 0) { if (packetSize == 0) {
return; return;
} }
auto parsedPacket = conn_->readCodec->parsePacket( auto parsedPacket = conn_->readCodec->parsePacket(
udpPacketData, conn_->ackStates, conn_->clientConnectionId->size()); udpPacket.buf, conn_->ackStates, conn_->clientConnectionId->size());
StatelessReset* statelessReset = parsedPacket.statelessReset(); StatelessReset* statelessReset = parsedPacket.statelessReset();
if (statelessReset) { if (statelessReset) {
const auto& token = clientConn_->statelessResetToken; const auto& token = clientConn_->statelessResetToken;
@@ -270,7 +268,7 @@ void QuicClientTransport::processUdpPacketData(
: clientConn_->pendingHandshakeData; : clientConn_->pendingHandshakeData;
pendingData.emplace_back( pendingData.emplace_back(
ReceivedUdpPacket( ReceivedUdpPacket(
std::move(cipherUnavailable->packet), udpPacketTimings), std::move(cipherUnavailable->packet), udpPacket.timings),
peer); peer);
if (conn_->qLogger) { if (conn_->qLogger) {
conn_->qLogger->addPacketBuffered( conn_->qLogger->addPacketBuffered(
@@ -375,7 +373,7 @@ void QuicClientTransport::processUdpPacketData(
// Add the packet to the AckState associated with the packet number space. // Add the packet to the AckState associated with the packet number space.
auto& ackState = getAckState(*conn_, pnSpace); auto& ackState = getAckState(*conn_, pnSpace);
uint64_t distanceFromExpectedPacketNum = uint64_t distanceFromExpectedPacketNum =
addPacketToAckState(*conn_, ackState, packetNum, udpPacketTimings); addPacketToAckState(*conn_, ackState, packetNum, udpPacket.timings);
if (distanceFromExpectedPacketNum > 0) { if (distanceFromExpectedPacketNum > 0) {
QUIC_STATS(conn_->statsCallback, onOutOfOrderPacketReceived); QUIC_STATS(conn_->statsCallback, onOutOfOrderPacketReceived);
} }
@@ -468,7 +466,7 @@ void QuicClientTransport::processUdpPacketData(
ackedPacketVisitor, ackedPacketVisitor,
ackedFrameVisitor, ackedFrameVisitor,
markPacketLoss, markPacketLoss,
udpPacketTimings.receiveTimePoint)); udpPacket.timings.receiveTimePoint));
break; break;
} }
case QuicFrame::Type::RstStreamFrame: { case QuicFrame::Type::RstStreamFrame: {
@@ -623,7 +621,7 @@ void QuicClientTransport::processUdpPacketData(
// Datagram isn't retransmittable. But we would like to ack them early. // Datagram isn't retransmittable. But we would like to ack them early.
// So, make Datagram frames count towards ack policy // So, make Datagram frames count towards ack policy
pktHasRetransmittableData = true; pktHasRetransmittableData = true;
handleDatagram(*conn_, frame, udpPacketTimings.receiveTimePoint); handleDatagram(*conn_, frame, udpPacket.timings.receiveTimePoint);
break; break;
} }
case QuicFrame::Type::ImmediateAckFrame: { case QuicFrame::Type::ImmediateAckFrame: {
@@ -1460,10 +1458,10 @@ void QuicClientTransport::onNotifyDataAvailable(
// track the received packets // track the received packets
for (const auto& packet : networkData.getPackets()) { for (const auto& packet : networkData.getPackets()) {
if (!packet.buf) { if (packet.buf.empty()) {
continue; continue;
} }
auto len = packet.buf->computeChainDataLength(); auto len = packet.buf.chainLength();
maybeQlogDatagram(len); maybeQlogDatagram(len);
totalPackets++; totalPackets++;
totalPacketLen += len; totalPacketLen += len;

View File

@@ -287,8 +287,7 @@ class QuicClientTransport
*/ */
void processUdpPacketData( void processUdpPacketData(
const folly::SocketAddress& peer, const folly::SocketAddress& peer,
const ReceivedUdpPacket::Timings& udpPacketTimings, ReceivedUdpPacket& udpPacket);
BufQueue& udpPacketData);
void startCryptoHandshake(); void startCryptoHandshake();

View File

@@ -134,9 +134,9 @@ mvfst_cpp_library(
"NetworkData.h", "NetworkData.h",
], ],
exported_deps = [ exported_deps = [
":buf_util",
":time_points", ":time_points",
"//folly:optional", "//folly:optional",
"//folly/io:iobuf",
"//quic:constants", "//quic:constants",
], ],
) )

View File

@@ -8,8 +8,8 @@
#pragma once #pragma once
#include <folly/Optional.h> #include <folly/Optional.h>
#include <folly/io/IOBuf.h>
#include <quic/QuicConstants.h> #include <quic/QuicConstants.h>
#include <quic/common/BufUtil.h>
#include <quic/common/TimePoints.h> #include <quic/common/TimePoints.h>
#include <memory> #include <memory>
@@ -59,7 +59,7 @@ struct ReceivedUdpPacket {
ReceivedUdpPacket(Buf&& bufIn, Timings timingsIn) ReceivedUdpPacket(Buf&& bufIn, Timings timingsIn)
: buf(std::move(bufIn)), timings(std::move(timingsIn)) {} : buf(std::move(bufIn)), timings(std::move(timingsIn)) {}
Buf buf; BufQueue buf;
Timings timings; Timings timings;
}; };
@@ -74,6 +74,12 @@ struct NetworkData {
} }
} }
explicit NetworkData(ReceivedUdpPacket&& udpPacket)
: receiveTimePoint_(udpPacket.timings.receiveTimePoint) {
totalData_ = udpPacket.buf.chainLength();
packets_.push_back(std::move(udpPacket));
}
NetworkData( NetworkData(
std::vector<Buf>&& packetBufs, std::vector<Buf>&& packetBufs,
const TimePoint& receiveTimePointIn) const TimePoint& receiveTimePointIn)
@@ -92,7 +98,7 @@ struct NetworkData {
totalData_([this]() { totalData_([this]() {
size_t result = 0; size_t result = 0;
for (const auto& packet : packets_) { for (const auto& packet : packets_) {
result += packet.buf->computeChainDataLength(); result += packet.buf.chainLength();
} }
return result; return result;
}()) {} }()) {}
@@ -104,7 +110,7 @@ struct NetworkData {
void addPacket(ReceivedUdpPacket&& packetIn) { void addPacket(ReceivedUdpPacket&& packetIn) {
packets_.emplace_back(std::move(packetIn)); packets_.emplace_back(std::move(packetIn));
packets_.back().timings.receiveTimePoint = receiveTimePoint_; packets_.back().timings.receiveTimePoint = receiveTimePoint_;
totalData_ += packets_.back().buf->computeChainDataLength(); totalData_ += packets_.back().buf.chainLength();
} }
[[nodiscard]] const std::vector<ReceivedUdpPacket>& getPackets() const { [[nodiscard]] const std::vector<ReceivedUdpPacket>& getPackets() const {
@@ -134,9 +140,9 @@ struct NetworkData {
std::unique_ptr<folly::IOBuf> buf; std::unique_ptr<folly::IOBuf> buf;
for (auto& packet : packets_) { for (auto& packet : packets_) {
if (buf) { if (buf) {
buf->prependChain(std::move(packet.buf)); buf->prependChain(packet.buf.move());
} else { } else {
buf = std::move(packet.buf); buf = packet.buf.move();
} }
} }
return buf; return buf;

View File

@@ -399,6 +399,12 @@ Buf packetToBuf(const RegularQuicPacketBuilder::Packet& packet) {
return packetBuf; return packetBuf;
} }
ReceivedUdpPacket packetToReceivedUdpPacket(
const RegularQuicPacketBuilder::Packet& writePacket) {
ReceivedUdpPacket packet(packetToBuf(writePacket));
return packet;
}
Buf packetToBufCleartext( Buf packetToBufCleartext(
RegularQuicPacketBuilder::Packet& packet, RegularQuicPacketBuilder::Packet& packet,
const Aead& cleartextCipher, const Aead& cleartextCipher,

View File

@@ -117,6 +117,9 @@ RegularQuicPacketBuilder::Packet createCryptoPacket(
Buf packetToBuf(const RegularQuicPacketBuilder::Packet& packet); Buf packetToBuf(const RegularQuicPacketBuilder::Packet& packet);
ReceivedUdpPacket packetToReceivedUdpPacket(
const RegularQuicPacketBuilder::Packet& packetIn);
Buf packetToBufCleartext( Buf packetToBufCleartext(
RegularQuicPacketBuilder::Packet& packet, RegularQuicPacketBuilder::Packet& packet,
const Aead& cleartextCipher, const Aead& cleartextCipher,

View File

@@ -737,7 +737,9 @@ class QuicClientTransportTestBase : public virtual testing::Test {
folly::SocketAddress* peer = nullptr) { folly::SocketAddress* peer = nullptr) {
for (const auto& packet : data.getPackets()) { for (const auto& packet : data.getPackets()) {
deliverDataWithoutErrorCheck( deliverDataWithoutErrorCheck(
peer == nullptr ? serverAddr : *peer, packet.buf->coalesce(), writes); peer == nullptr ? serverAddr : *peer,
packet.buf.clone()->coalesce(),
writes);
} }
} }
@@ -773,7 +775,9 @@ class QuicClientTransportTestBase : public virtual testing::Test {
folly::SocketAddress* peer = nullptr) { folly::SocketAddress* peer = nullptr) {
for (const auto& packet : data.getPackets()) { for (const auto& packet : data.getPackets()) {
deliverData( deliverData(
peer == nullptr ? serverAddr : *peer, packet.buf->coalesce(), writes); peer == nullptr ? serverAddr : *peer,
packet.buf.clone()->coalesce(),
writes);
} }
} }

View File

@@ -242,10 +242,11 @@ void TakeoverPacketHandler::processForwardedPacket(
TimePoint clientPacketReceiveTime(tick); TimePoint clientPacketReceiveTime(tick);
data->trimStart(cursor - data.get()); data->trimStart(cursor - data.get());
QUIC_STATS(worker_->getStatsCallback(), onForwardedPacketProcessed); QUIC_STATS(worker_->getStatsCallback(), onForwardedPacketProcessed);
ReceivedUdpPacket packet(std::move(data));
packet.timings.receiveTimePoint = clientPacketReceiveTime;
worker_->handleNetworkData( worker_->handleNetworkData(
peerAddress, peerAddress,
std::move(data), packet,
clientPacketReceiveTime,
/* isForwardedData */ true); /* isForwardedData */ true);
} }

View File

@@ -519,9 +519,7 @@ void QuicServerTransport::processPendingData(bool async) {
for (auto& pendingPacket : *pendingData) { for (auto& pendingPacket : *pendingData) {
serverPtr->onNetworkData( serverPtr->onNetworkData(
pendingPacket.peer, pendingPacket.peer,
NetworkData( NetworkData(std::move(pendingPacket.udpPacket)));
std::move(pendingPacket.udpPacket.buf),
pendingPacket.udpPacket.timings.receiveTimePoint));
if (serverPtr->closeState_ == CloseState::CLOSED) { if (serverPtr->closeState_ == CloseState::CLOSED) {
// The pending data could potentially contain a connection close, or // The pending data could potentially contain a connection close, or
// the app could have triggered a connection close with an error. It // the app could have triggered a connection close with an error. It

View File

@@ -344,7 +344,9 @@ void QuicServerWorker::onDataAvailable(
data->append(len); data->append(len);
QUIC_STATS(statsCallback_, onPacketReceived); QUIC_STATS(statsCallback_, onPacketReceived);
QUIC_STATS(statsCallback_, onRead, len); QUIC_STATS(statsCallback_, onRead, len);
handleNetworkData(client, std::move(data), packetReceiveTime); ReceivedUdpPacket udpPacket(std::move(data));
udpPacket.timings.receiveTimePoint = packetReceiveTime;
handleNetworkData(client, udpPacket);
} else { } else {
// if we receive a truncated packet // if we receive a truncated packet
// we still need to consider the prev valid ones // we still need to consider the prev valid ones
@@ -353,7 +355,6 @@ void QuicServerWorker::onDataAvailable(
if (truncated) { if (truncated) {
len -= len % params.gro; len -= len % params.gro;
} }
data->append(len); data->append(len);
QUIC_STATS(statsCallback_, onPacketReceived); QUIC_STATS(statsCallback_, onPacketReceived);
QUIC_STATS(statsCallback_, onRead, len); QUIC_STATS(statsCallback_, onRead, len);
@@ -366,7 +367,9 @@ void QuicServerWorker::onDataAvailable(
// start at offset, use all the remaining data // start at offset, use all the remaining data
data->trimStart(offset); data->trimStart(offset);
DCHECK_EQ(data->length(), remaining); DCHECK_EQ(data->length(), remaining);
handleNetworkData(client, std::move(data), packetReceiveTime); ReceivedUdpPacket udpPacket(std::move(data));
udpPacket.timings.receiveTimePoint = packetReceiveTime;
handleNetworkData(client, udpPacket);
break; break;
} }
auto tmp = data->cloneOne(); auto tmp = data->cloneOne();
@@ -378,15 +381,16 @@ void QuicServerWorker::onDataAvailable(
DCHECK_EQ(tmp->length(), params.gro); DCHECK_EQ(tmp->length(), params.gro);
offset += params.gro; offset += params.gro;
remaining -= params.gro; remaining -= params.gro;
handleNetworkData(client, std::move(tmp), packetReceiveTime); ReceivedUdpPacket udpPacket(std::move(tmp));
udpPacket.timings.receiveTimePoint = packetReceiveTime;
handleNetworkData(client, udpPacket);
} }
} }
} }
void QuicServerWorker::handleNetworkData( void QuicServerWorker::handleNetworkData(
const folly::SocketAddress& client, const folly::SocketAddress& client,
Buf data, ReceivedUdpPacket& udpPacket,
const TimePoint& packetReceiveTime,
bool isForwardedData) noexcept { bool isForwardedData) noexcept {
// if packet drop reason is set, invoke stats cb accordingly // if packet drop reason is set, invoke stats cb accordingly
auto packetDropReason = PacketDropReason::NONE; auto packetDropReason = PacketDropReason::NONE;
@@ -398,7 +402,7 @@ void QuicServerWorker::handleNetworkData(
try { try {
// check error conditions for packet drop & early return // check error conditions for packet drop & early return
folly::io::Cursor cursor(data.get()); folly::io::Cursor cursor(udpPacket.buf.front());
if (shutdown_) { if (shutdown_) {
VLOG(4) << "Packet received after shutdown, dropping"; VLOG(4) << "Packet received after shutdown, dropping";
packetDropReason = PacketDropReason::SERVER_SHUTDOWN; packetDropReason = PacketDropReason::SERVER_SHUTDOWN;
@@ -433,7 +437,7 @@ void QuicServerWorker::handleNetworkData(
return forwardNetworkData( return forwardNetworkData(
client, client,
std::move(routingData), std::move(routingData),
NetworkData(std::move(data), packetReceiveTime), NetworkData(std::move(udpPacket)),
folly::none, /* quicVersion */ folly::none, /* quicVersion */
isForwardedData); isForwardedData);
} }
@@ -452,7 +456,7 @@ void QuicServerWorker::handleNetworkData(
} }
if (maybeSendVersionNegotiationPacketOrDrop( if (maybeSendVersionNegotiationPacketOrDrop(
client, isInitial, invariant, data->computeChainDataLength())) { client, isInitial, invariant, udpPacket.buf.chainLength())) {
return; return;
} }
@@ -473,12 +477,12 @@ void QuicServerWorker::handleNetworkData(
return forwardNetworkData( return forwardNetworkData(
client, client,
std::move(routingData), std::move(routingData),
NetworkData(std::move(data), packetReceiveTime), NetworkData(std::move(udpPacket)),
invariant.version, invariant.version,
isForwardedData); isForwardedData);
} }
if (!tryHandlingAsHealthCheck(client, *data)) { if (!tryHandlingAsHealthCheck(client, *udpPacket.buf.front())) {
VLOG(6) << "Failed to parse long header"; VLOG(6) << "Failed to parse long header";
packetDropReason = PacketDropReason::PARSE_ERROR_LONG_HEADER; packetDropReason = PacketDropReason::PARSE_ERROR_LONG_HEADER;
} }
@@ -900,7 +904,7 @@ void QuicServerWorker::dispatchPacketData(
// If there is a token present, decrypt it (could be either a retry // If there is a token present, decrypt it (could be either a retry
// token or a new token) // token or a new token)
folly::io::Cursor cursor(networkData.getPackets().front().buf.get()); folly::io::Cursor cursor(networkData.getPackets().front().buf.front());
auto maybeEncryptedToken = maybeGetEncryptedToken(cursor); auto maybeEncryptedToken = maybeGetEncryptedToken(cursor);
bool hasTokenSecret = transportSettings_.retryTokenSecret.hasValue(); bool hasTokenSecret = transportSettings_.retryTokenSecret.hasValue();

View File

@@ -452,12 +452,11 @@ class QuicServerWorker : public FollyAsyncUDPSocketAlias::ReadCallback,
FollyAsyncUDPSocketAlias::ReadCallback* getTakeoverHandlerCallback() { FollyAsyncUDPSocketAlias::ReadCallback* getTakeoverHandlerCallback() {
return takeoverCB_.get(); return takeoverCB_.get();
} }
// Handle the network data for a udp packet
// public so that it can be called by tests as well. // public so that it can be called by tests as well.
void handleNetworkData( void handleNetworkData(
const folly::SocketAddress& client, const folly::SocketAddress& client,
Buf data, ReceivedUdpPacket& packet,
const TimePoint& receiveTime,
bool isForwardedData = false) noexcept; bool isForwardedData = false) noexcept;
/** /**

View File

@@ -731,15 +731,14 @@ void onServerReadDataFromOpen(
ServerEvents::ReadData& readData) { ServerEvents::ReadData& readData) {
CHECK_EQ(conn.state, ServerState::Open); CHECK_EQ(conn.state, ServerState::Open);
// Don't bother parsing if the data is empty. // Don't bother parsing if the data is empty.
if (!readData.udpPacket.buf || if (readData.udpPacket.buf.empty()) {
readData.udpPacket.buf->computeChainDataLength() == 0) {
return; return;
} }
bool firstPacketFromPeer = false; bool firstPacketFromPeer = false;
if (!conn.readCodec) { if (!conn.readCodec) {
firstPacketFromPeer = true; firstPacketFromPeer = true;
folly::io::Cursor cursor(readData.udpPacket.buf.get()); folly::io::Cursor cursor(readData.udpPacket.buf.front());
auto initialByte = cursor.readBE<uint8_t>(); auto initialByte = cursor.readBE<uint8_t>();
auto parsedLongHeader = parseLongHeaderInvariant(initialByte, cursor); auto parsedLongHeader = parseLongHeaderInvariant(initialByte, cursor);
if (!parsedLongHeader) { if (!parsedLongHeader) {
@@ -848,8 +847,7 @@ void onServerReadDataFromOpen(
initialDestinationConnectionId, version); initialDestinationConnectionId, version);
conn.peerAddress = conn.originalPeerAddress; conn.peerAddress = conn.originalPeerAddress;
} }
BufQueue udpData; BufQueue& udpData = readData.udpPacket.buf;
udpData.append(std::move(readData.udpPacket.buf));
uint64_t processedPacketsTotal = 0; uint64_t processedPacketsTotal = 0;
for (uint16_t processedPackets = 0; for (uint16_t processedPackets = 0;
!udpData.empty() && processedPackets < kMaxNumCoalescedPackets; !udpData.empty() && processedPackets < kMaxNumCoalescedPackets;
@@ -1385,8 +1383,7 @@ void onServerReadDataFromClosed(
QuicServerConnectionState& conn, QuicServerConnectionState& conn,
ServerEvents::ReadData& readData) { ServerEvents::ReadData& readData) {
CHECK_EQ(conn.state, ServerState::Closed); CHECK_EQ(conn.state, ServerState::Closed);
BufQueue udpData; BufQueue& udpData = readData.udpPacket.buf;
udpData.append(std::move(readData.udpPacket.buf));
auto packetSize = udpData.empty() ? 0 : udpData.chainLength(); auto packetSize = udpData.empty() ? 0 : udpData.chainLength();
if (!conn.readCodec) { if (!conn.readCodec) {
// drop data. We closed before we even got the first packet. This is // drop data. We closed before we even got the first packet. This is

View File

@@ -49,7 +49,7 @@ namespace test {
MATCHER_P(NetworkDataMatches, networkData, "") { MATCHER_P(NetworkDataMatches, networkData, "") {
for (size_t i = 0; i < arg.getPackets().size(); ++i) { for (size_t i = 0; i < arg.getPackets().size(); ++i) {
folly::IOBufEqualTo eq; folly::IOBufEqualTo eq;
bool equals = eq(*arg.getPackets()[i].buf, networkData); bool equals = eq(*arg.getPackets()[i].buf.front(), networkData);
if (equals) { if (equals) {
return true; return true;
} }
@@ -988,8 +988,8 @@ TEST_F(QuicServerWorkerTest, BlockedSourcePort) {
while (builder.remainingSpaceInPkt() > 0) { while (builder.remainingSpaceInPkt() > 0) {
writeFrame(PaddingFrame(), builder); writeFrame(PaddingFrame(), builder);
} }
auto packet = packetToBuf(std::move(builder).buildPacket()); auto packet = packetToReceivedUdpPacket(std::move(builder).buildPacket());
worker_->handleNetworkData(blockedSrcPort, std::move(packet), Clock::now()); worker_->handleNetworkData(blockedSrcPort, packet);
eventbase_.loopIgnoreKeepAlive(); eventbase_.loopIgnoreKeepAlive();
} }
@@ -1007,8 +1007,8 @@ TEST_F(QuicServerWorkerTest, ZeroLengthConnectionId) {
while (builder.remainingSpaceInPkt() > 0) { while (builder.remainingSpaceInPkt() > 0) {
writeFrame(PaddingFrame(), builder); writeFrame(PaddingFrame(), builder);
} }
auto packet = packetToBuf(std::move(builder).buildPacket()); auto packet = packetToReceivedUdpPacket(std::move(builder).buildPacket());
worker_->handleNetworkData(kClientAddr, std::move(packet), Clock::now()); worker_->handleNetworkData(kClientAddr, packet);
eventbase_.loopIgnoreKeepAlive(); eventbase_.loopIgnoreKeepAlive();
} }
@@ -1022,11 +1022,11 @@ TEST_F(QuicServerWorkerTest, ClientInitialCounting) {
RegularQuicPacketBuilder initialBuilder( RegularQuicPacketBuilder initialBuilder(
kDefaultUDPSendPacketLen, std::move(initialHeader), 0); kDefaultUDPSendPacketLen, std::move(initialHeader), 0);
initialBuilder.encodePacketHeader(); initialBuilder.encodePacketHeader();
auto initialPacket = packetToBuf(std::move(initialBuilder).buildPacket()); auto initialPacket =
packetToReceivedUdpPacket((std::move(initialBuilder).buildPacket()));
EXPECT_CALL(*quicStats_, onClientInitialReceived(QuicVersion::MVFST)) EXPECT_CALL(*quicStats_, onClientInitialReceived(QuicVersion::MVFST))
.Times(1); .Times(1);
worker_->handleNetworkData( worker_->handleNetworkData(kClientAddr, initialPacket);
kClientAddr, std::move(initialPacket), Clock::now());
eventbase_.loopIgnoreKeepAlive(); eventbase_.loopIgnoreKeepAlive();
// Initial with any packet number should also increate the counting // Initial with any packet number should also increate the counting
@@ -1036,12 +1036,11 @@ TEST_F(QuicServerWorkerTest, ClientInitialCounting) {
RegularQuicPacketBuilder initialBuilderBigNum( RegularQuicPacketBuilder initialBuilderBigNum(
kDefaultUDPSendPacketLen, std::move(initialHeaderBigNum), 0); kDefaultUDPSendPacketLen, std::move(initialHeaderBigNum), 0);
initialBuilderBigNum.encodePacketHeader(); initialBuilderBigNum.encodePacketHeader();
auto initialPacketBigNum = auto initialPacketBigNum = packetToReceivedUdpPacket(
packetToBuf(std::move(initialBuilderBigNum).buildPacket()); (std::move(initialBuilderBigNum).buildPacket()));
EXPECT_CALL(*quicStats_, onClientInitialReceived(QuicVersion::MVFST)) EXPECT_CALL(*quicStats_, onClientInitialReceived(QuicVersion::MVFST))
.Times(1); .Times(1);
worker_->handleNetworkData( worker_->handleNetworkData(kClientAddr, initialPacketBigNum);
kClientAddr, std::move(initialPacketBigNum), Clock::now());
eventbase_.loopIgnoreKeepAlive(); eventbase_.loopIgnoreKeepAlive();
LongHeader handshakeHeader( LongHeader handshakeHeader(
@@ -1049,10 +1048,10 @@ TEST_F(QuicServerWorkerTest, ClientInitialCounting) {
RegularQuicPacketBuilder handshakeBuilder( RegularQuicPacketBuilder handshakeBuilder(
kDefaultUDPSendPacketLen, std::move(handshakeHeader), 0); kDefaultUDPSendPacketLen, std::move(handshakeHeader), 0);
handshakeBuilder.encodePacketHeader(); handshakeBuilder.encodePacketHeader();
auto handshakePacket = packetToBuf(std::move(handshakeBuilder).buildPacket()); auto handshakePacket =
packetToReceivedUdpPacket((std::move(handshakeBuilder).buildPacket()));
EXPECT_CALL(*quicStats_, onClientInitialReceived(_)).Times(0); EXPECT_CALL(*quicStats_, onClientInitialReceived(_)).Times(0);
worker_->handleNetworkData( worker_->handleNetworkData(kClientAddr, handshakePacket);
kClientAddr, std::move(handshakePacket), Clock::now());
eventbase_.loopIgnoreKeepAlive(); eventbase_.loopIgnoreKeepAlive();
} }
@@ -1073,8 +1072,8 @@ TEST_F(QuicServerWorkerTest, ConnectionIdTooShort) {
while (builder.remainingSpaceInPkt() > 0) { while (builder.remainingSpaceInPkt() > 0) {
writeFrame(PaddingFrame(), builder); writeFrame(PaddingFrame(), builder);
} }
auto packet = packetToBuf(std::move(builder).buildPacket()); auto packet = packetToReceivedUdpPacket((std::move(builder).buildPacket()));
worker_->handleNetworkData(kClientAddr, std::move(packet), Clock::now()); worker_->handleNetworkData(kClientAddr, packet);
eventbase_.loopIgnoreKeepAlive(); eventbase_.loopIgnoreKeepAlive();
} }
@@ -1203,8 +1202,8 @@ TEST_F(QuicServerWorkerTest, PacketAfterShutdown) {
RegularQuicPacketBuilder builder( RegularQuicPacketBuilder builder(
kDefaultUDPSendPacketLen, std::move(header), 0 /* largestAcked */); kDefaultUDPSendPacketLen, std::move(header), 0 /* largestAcked */);
builder.encodePacketHeader(); builder.encodePacketHeader();
auto packet = packetToBuf(std::move(builder).buildPacket()); auto packet = packetToReceivedUdpPacket((std::move(builder).buildPacket()));
worker_->handleNetworkData(kClientAddr, std::move(packet), Clock::now()); worker_->handleNetworkData(kClientAddr, packet);
eventbase_.terminateLoopSoon(); eventbase_.terminateLoopSoon();
t.join(); t.join();
} }
@@ -1984,7 +1983,7 @@ TEST_F(QuicServerWorkerTakeoverTest, QuicServerTakeoverProcessForwardedPkt) {
// the original data should be extracted after processing takeover // the original data should be extracted after processing takeover
// protocol related information // protocol related information
EXPECT_EQ(networkData->getPackets().size(), 1); EXPECT_EQ(networkData->getPackets().size(), 1);
EXPECT_TRUE(eq(*data, *(networkData->getPackets()[0].buf))); EXPECT_TRUE(eq(*data, *(networkData->getPackets()[0].buf.front())));
EXPECT_TRUE(isForwardedData); EXPECT_TRUE(isForwardedData);
}; };
EXPECT_CALL(*takeoverWorkerCb_, routeDataToWorkerLong(_, _, _, _, _)) EXPECT_CALL(*takeoverWorkerCb_, routeDataToWorkerLong(_, _, _, _, _))
@@ -2182,7 +2181,7 @@ class QuicServerTest : public Test {
auto, const auto& networkData) mutable { auto, const auto& networkData) mutable {
EXPECT_GT(networkData.getPackets().size(), 0); EXPECT_GT(networkData.getPackets().size(), 0);
EXPECT_TRUE(folly::IOBufEqualTo()( EXPECT_TRUE(folly::IOBufEqualTo()(
*networkData.getPackets()[0].buf, *expected)); *networkData.getPackets()[0].buf.front(), *expected));
std::unique_lock<std::mutex> lg(m); std::unique_lock<std::mutex> lg(m);
calledOnNetworkData = true; calledOnNetworkData = true;
cv.notify_one(); cv.notify_one();
@@ -2349,7 +2348,7 @@ TEST_F(QuicServerTest, RouteDataFromDifferentThread) {
.WillOnce(Invoke([&](auto, const auto& networkData) { .WillOnce(Invoke([&](auto, const auto& networkData) {
EXPECT_GT(networkData.getPackets().size(), 0); EXPECT_GT(networkData.getPackets().size(), 0);
EXPECT_TRUE(folly::IOBufEqualTo()( EXPECT_TRUE(folly::IOBufEqualTo()(
*networkData.getPackets()[0].buf, *initialData)); *networkData.getPackets()[0].buf.front(), *initialData));
})); }));
static_cast<QuicServerWorker::WorkerCallback*>(server_.get()) static_cast<QuicServerWorker::WorkerCallback*>(server_.get())
@@ -2454,7 +2453,7 @@ class QuicServerTakeoverTest : public Test {
[&, expected = data.get()](auto, const auto& networkData) { [&, expected = data.get()](auto, const auto& networkData) {
EXPECT_GT(networkData.getPackets().size(), 0); EXPECT_GT(networkData.getPackets().size(), 0);
EXPECT_TRUE(folly::IOBufEqualTo()( EXPECT_TRUE(folly::IOBufEqualTo()(
*networkData.getPackets()[0].buf, *expected)); *networkData.getPackets()[0].buf.front(), *expected));
baton.post(); baton.post();
})); }));
return transport; return transport;
@@ -2562,7 +2561,7 @@ class QuicServerTakeoverTest : public Test {
Invoke([&, expected = data.get()](auto, const auto& networkData) { Invoke([&, expected = data.get()](auto, const auto& networkData) {
EXPECT_GT(networkData.getPackets().size(), 0); EXPECT_GT(networkData.getPackets().size(), 0);
EXPECT_TRUE(folly::IOBufEqualTo()( EXPECT_TRUE(folly::IOBufEqualTo()(
*networkData.getPackets()[0].buf, *expected)); *networkData.getPackets()[0].buf.front(), *expected));
b1.post(); b1.post();
})); }));
// new quic server receives the packet and forwards it // new quic server receives the packet and forwards it
@@ -3029,7 +3028,7 @@ TEST_F(QuicServerTest, ZeroRttPacketRoute) {
[&, expected = data.get()](auto, const auto& networkData) { [&, expected = data.get()](auto, const auto& networkData) {
EXPECT_GT(networkData.getPackets().size(), 0); EXPECT_GT(networkData.getPackets().size(), 0);
EXPECT_TRUE(folly::IOBufEqualTo()( EXPECT_TRUE(folly::IOBufEqualTo()(
*networkData.getPackets()[0].buf, *expected)); *networkData.getPackets()[0].buf.front(), *expected));
b.post(); b.post();
})); }));
return transport; return transport;
@@ -3072,7 +3071,8 @@ TEST_F(QuicServerTest, ZeroRttPacketRoute) {
const NetworkData& networkData) noexcept { const NetworkData& networkData) noexcept {
EXPECT_GT(networkData.getPackets().size(), 0); EXPECT_GT(networkData.getPackets().size(), 0);
EXPECT_EQ(peer, reader->getSocket().address()); EXPECT_EQ(peer, reader->getSocket().address());
EXPECT_TRUE(folly::IOBufEqualTo()(*data, *networkData.getPackets()[0].buf)); EXPECT_TRUE(
folly::IOBufEqualTo()(*data, *networkData.getPackets()[0].buf.front()));
b1.post(); b1.post();
}; };
EXPECT_CALL(*transport, onNetworkData(_, _)).WillOnce(Invoke(verifyZeroRtt)); EXPECT_CALL(*transport, onNetworkData(_, _)).WillOnce(Invoke(verifyZeroRtt));
@@ -3126,7 +3126,7 @@ TEST_F(QuicServerTest, ZeroRttBeforeInitial) {
.Times(2) .Times(2)
.WillRepeatedly(Invoke([&](auto, auto& networkData) { .WillRepeatedly(Invoke([&](auto, auto& networkData) {
for (const auto& packet : networkData.getPackets()) { for (const auto& packet : networkData.getPackets()) {
receivedData.emplace_back(packet.buf->clone()); receivedData.emplace_back(packet.buf.clone());
} }
if (receivedData.size() == 2) { if (receivedData.size() == 2) {
b.post(); b.post();