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

Packets inflight, packets sent in OutstandingPacketMetadata

Summary:
- Adds counter of the number of ack-eliciting packets sent; useful for understanding lost / retransmission numbers
- Adds the following to `OutstandingPacketMetadata`
  - # of packets sent and # of ack-eliciting packets sent; this enables indexing of each packet when processed by an observer on loss / RTT event, including understanding its ordering in the flow of sent packets.
  - # of packets in flight; useful during loss analysis to understand if self-induced congestion could be culprit
- Fixes the inflightBytes counter in `OutstandingPacketMetadata`; it was previously _not_ including the packets own bytes, despite saying that it was.

Right now we are passing multiple integers into the `OutstandingPacket` constructor. I've switched to passing in `LossState` to avoid passing in two more integers, although I will need to come back and clean up the existing ones.

Differential Revision: D25861702

fbshipit-source-id: e34c0edcb136bc1a2a6aeb898ecbb4cf11d0aa2c
This commit is contained in:
Brandon Schlinker
2021-01-21 21:10:07 -08:00
committed by Facebook GitHub Bot
parent 4c5874e062
commit f206c5125b
18 changed files with 356 additions and 150 deletions

View File

@@ -133,6 +133,7 @@ class QuicSocket {
std::chrono::microseconds pacingInterval{0us}; std::chrono::microseconds pacingInterval{0us};
uint32_t packetsRetransmitted{0}; uint32_t packetsRetransmitted{0};
uint32_t totalPacketsSent{0}; uint32_t totalPacketsSent{0};
uint32_t totalAckElicitingPacketsSent{0};
uint32_t totalPacketsMarkedLost{0}; uint32_t totalPacketsMarkedLost{0};
uint32_t totalPacketsMarkedLostByPto{0}; uint32_t totalPacketsMarkedLostByPto{0};
uint32_t totalPacketsMarkedLostByReorderingThreshold{0}; uint32_t totalPacketsMarkedLostByReorderingThreshold{0};

View File

@@ -583,6 +583,8 @@ QuicSocket::TransportInfo QuicTransportBase::getTransportInfo() const {
transportInfo.pacingInterval = pacingInterval; transportInfo.pacingInterval = pacingInterval;
transportInfo.packetsRetransmitted = conn_->lossState.rtxCount; transportInfo.packetsRetransmitted = conn_->lossState.rtxCount;
transportInfo.totalPacketsSent = conn_->lossState.totalPacketsSent; transportInfo.totalPacketsSent = conn_->lossState.totalPacketsSent;
transportInfo.totalAckElicitingPacketsSent =
conn_->lossState.totalAckElicitingPacketsSent;
transportInfo.totalPacketsMarkedLost = transportInfo.totalPacketsMarkedLost =
conn_->lossState.totalPacketsMarkedLost; conn_->lossState.totalPacketsMarkedLost;
transportInfo.totalPacketsMarkedLostByPto = transportInfo.totalPacketsMarkedLostByPto =

View File

@@ -667,6 +667,7 @@ void updateConnection(
DCHECK(!packetEvent); DCHECK(!packetEvent);
return; return;
} }
conn.lossState.totalAckElicitingPacketsSent++;
auto packetIt = auto packetIt =
std::find_if( std::find_if(
conn.outstandings.packets.rbegin(), conn.outstandings.packets.rbegin(),
@@ -679,12 +680,18 @@ void updateConnection(
auto& pkt = *conn.outstandings.packets.emplace( auto& pkt = *conn.outstandings.packets.emplace(
packetIt, packetIt,
std::move(packet), std::move(packet),
std::move(sentTime), sentTime,
encodedSize, encodedSize,
isHandshake, isHandshake,
isD6DProbe, isD6DProbe,
// these numbers should all _include_ the current packet
// conn.lossState.inflightBytes isn't updated until below
// conn.outstandings.numOutstanding() + 1 since we're emplacing here
conn.lossState.totalBytesSent, conn.lossState.totalBytesSent,
conn.lossState.inflightBytes); conn.lossState.inflightBytes + encodedSize,
conn.outstandings.numOutstanding() + 1,
conn.lossState);
if (isD6DProbe) { if (isD6DProbe) {
++conn.d6d.outstandingProbes; ++conn.d6d.outstandingProbes;
++conn.d6d.meta.totalTxedProbes; ++conn.d6d.meta.totalTxedProbes;

View File

@@ -40,7 +40,8 @@ PacketNum addInitialOutstandingPacket(QuicConnectionStateBase& conn) {
nextPacketNum, nextPacketNum,
QuicVersion::QUIC_DRAFT); QuicVersion::QUIC_DRAFT);
RegularQuicWritePacket packet(std::move(header)); RegularQuicWritePacket packet(std::move(header));
conn.outstandings.packets.emplace_back(packet, Clock::now(), 0, true, 0, 0); conn.outstandings.packets.emplace_back(
packet, Clock::now(), 0, true, 0, 0, 0, LossState());
conn.outstandings.handshakePacketsCount++; conn.outstandings.handshakePacketsCount++;
increaseNextPacketNum(conn, PacketNumberSpace::Handshake); increaseNextPacketNum(conn, PacketNumberSpace::Handshake);
return nextPacketNum; return nextPacketNum;
@@ -58,7 +59,8 @@ PacketNum addHandshakeOutstandingPacket(QuicConnectionStateBase& conn) {
nextPacketNum, nextPacketNum,
QuicVersion::QUIC_DRAFT); QuicVersion::QUIC_DRAFT);
RegularQuicWritePacket packet(std::move(header)); RegularQuicWritePacket packet(std::move(header));
conn.outstandings.packets.emplace_back(packet, Clock::now(), 0, true, 0, 0); conn.outstandings.packets.emplace_back(
packet, Clock::now(), 0, true, 0, 0, 0, LossState());
conn.outstandings.handshakePacketsCount++; conn.outstandings.handshakePacketsCount++;
increaseNextPacketNum(conn, PacketNumberSpace::Handshake); increaseNextPacketNum(conn, PacketNumberSpace::Handshake);
return nextPacketNum; return nextPacketNum;
@@ -71,7 +73,8 @@ PacketNum addOutstandingPacket(QuicConnectionStateBase& conn) {
conn.clientConnectionId.value_or(quic::test::getTestConnectionId()), conn.clientConnectionId.value_or(quic::test::getTestConnectionId()),
nextPacketNum); nextPacketNum);
RegularQuicWritePacket packet(std::move(header)); RegularQuicWritePacket packet(std::move(header));
conn.outstandings.packets.emplace_back(packet, Clock::now(), 0, false, 0, 0); conn.outstandings.packets.emplace_back(
packet, Clock::now(), 0, false, 0, 0, 0, LossState());
increaseNextPacketNum(conn, PacketNumberSpace::AppData); increaseNextPacketNum(conn, PacketNumberSpace::AppData);
return nextPacketNum; return nextPacketNum;
} }

View File

@@ -908,6 +908,9 @@ TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionWithPureAck) {
std::make_unique<NiceMock<MockCongestionController>>(); std::make_unique<NiceMock<MockCongestionController>>();
auto rawController = mockCongestionController.get(); auto rawController = mockCongestionController.get();
conn->congestionController = std::move(mockCongestionController); conn->congestionController = std::move(mockCongestionController);
EXPECT_EQ(0, conn->lossState.totalPacketsSent);
EXPECT_EQ(0, conn->lossState.totalAckElicitingPacketsSent);
EXPECT_EQ(0, conn->outstandings.packets.size());
ASSERT_EQ(0, conn->lossState.totalBytesAcked); ASSERT_EQ(0, conn->lossState.totalBytesAcked);
WriteAckFrame ackFrame; WriteAckFrame ackFrame;
ackFrame.ackBlocks.emplace_back(0, 10); ackFrame.ackBlocks.emplace_back(0, 10);
@@ -916,6 +919,8 @@ TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionWithPureAck) {
EXPECT_CALL(*rawPacer, onPacketSent()).Times(0); EXPECT_CALL(*rawPacer, onPacketSent()).Times(0);
updateConnection( updateConnection(
*conn, folly::none, packet.packet, TimePoint(), getEncodedSize(packet)); *conn, folly::none, packet.packet, TimePoint(), getEncodedSize(packet));
EXPECT_EQ(1, conn->lossState.totalPacketsSent);
EXPECT_EQ(0, conn->lossState.totalAckElicitingPacketsSent);
EXPECT_EQ(0, conn->outstandings.packets.size()); EXPECT_EQ(0, conn->outstandings.packets.size());
EXPECT_EQ(0, conn->lossState.totalBytesAcked); EXPECT_EQ(0, conn->lossState.totalBytesAcked);
std::shared_ptr<quic::FileQLogger> qLogger = std::shared_ptr<quic::FileQLogger> qLogger =
@@ -947,13 +952,18 @@ TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionWithBytesStats) {
packet.packet.frames.push_back(std::move(writeStreamFrame)); packet.packet.frames.push_back(std::move(writeStreamFrame));
conn->lossState.totalBytesSent = 13579; conn->lossState.totalBytesSent = 13579;
conn->lossState.totalBytesAcked = 8642; conn->lossState.totalBytesAcked = 8642;
conn->lossState.inflightBytes = 16000;
auto currentTime = Clock::now(); auto currentTime = Clock::now();
conn->lossState.lastAckedTime = currentTime - 123s; conn->lossState.lastAckedTime = currentTime - 123s;
conn->lossState.adjustedLastAckedTime = currentTime - 123s; conn->lossState.adjustedLastAckedTime = currentTime - 123s;
conn->lossState.lastAckedPacketSentTime = currentTime - 234s; conn->lossState.lastAckedPacketSentTime = currentTime - 234s;
conn->lossState.totalBytesSentAtLastAck = 10000; conn->lossState.totalBytesSentAtLastAck = 10000;
conn->lossState.totalBytesAckedAtLastAck = 5000; conn->lossState.totalBytesAckedAtLastAck = 5000;
conn->lossState.totalPacketsSent = 20;
conn->lossState.totalAckElicitingPacketsSent = 15;
updateConnection(*conn, folly::none, packet.packet, TimePoint(), 555); updateConnection(*conn, folly::none, packet.packet, TimePoint(), 555);
EXPECT_EQ(21, conn->lossState.totalPacketsSent);
EXPECT_EQ(16, conn->lossState.totalAckElicitingPacketsSent);
// verify QLogger contains correct packet information // verify QLogger contains correct packet information
std::shared_ptr<quic::FileQLogger> qLogger = std::shared_ptr<quic::FileQLogger> qLogger =
@@ -972,6 +982,27 @@ TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionWithBytesStats) {
13579 + 555, 13579 + 555,
getFirstOutstandingPacket(*conn, PacketNumberSpace::Handshake) getFirstOutstandingPacket(*conn, PacketNumberSpace::Handshake)
->metadata.totalBytesSent); ->metadata.totalBytesSent);
EXPECT_EQ(
16000 + 555,
getFirstOutstandingPacket(*conn, PacketNumberSpace::Handshake)
->metadata.inflightBytes);
EXPECT_EQ(
1,
getFirstOutstandingPacket(*conn, PacketNumberSpace::Handshake)
->metadata.packetsInflight);
EXPECT_EQ(
555,
getFirstOutstandingPacket(*conn, PacketNumberSpace::Handshake)
->metadata.encodedSize);
EXPECT_EQ(
20 + 1,
getFirstOutstandingPacket(*conn, PacketNumberSpace::Handshake)
->metadata.totalPacketsSent);
EXPECT_EQ(
15 + 1,
getFirstOutstandingPacket(*conn, PacketNumberSpace::Handshake)
->metadata.totalAckElicitingPacketsSent);
EXPECT_TRUE(getFirstOutstandingPacket(*conn, PacketNumberSpace::Handshake) EXPECT_TRUE(getFirstOutstandingPacket(*conn, PacketNumberSpace::Handshake)
->lastAckedPacketInfo.has_value()); ->lastAckedPacketInfo.has_value());
EXPECT_EQ( EXPECT_EQ(

View File

@@ -29,7 +29,14 @@ OutstandingPacket makeDummyOutstandingPacket(
const RegularQuicWritePacket& writePacket, const RegularQuicWritePacket& writePacket,
uint64_t totalBytesSentOnConnection) { uint64_t totalBytesSentOnConnection) {
OutstandingPacket packet( OutstandingPacket packet(
writePacket, Clock::now(), 1000, false, totalBytesSentOnConnection, 0); writePacket,
Clock::now(),
1000,
false,
totalBytesSentOnConnection,
0,
0,
LossState());
return packet; return packet;
} }

View File

@@ -571,7 +571,14 @@ OutstandingPacket makeTestingWritePacket(
QuicVersion::MVFST); QuicVersion::MVFST);
RegularQuicWritePacket packet(std::move(longHeader)); RegularQuicWritePacket packet(std::move(longHeader));
return OutstandingPacket( return OutstandingPacket(
packet, sentTime, desiredSize, false, totalBytesSent, inflightBytes); packet,
sentTime,
desiredSize,
false,
totalBytesSent,
inflightBytes,
0,
LossState());
} }
CongestionController::AckEvent makeAck( CongestionController::AckEvent makeAck(

View File

@@ -28,7 +28,14 @@ class Copa2Test : public Test {
RegularQuicWritePacket packet( RegularQuicWritePacket packet(
ShortHeader(ProtectionType::KeyPhaseZero, connId, packetNum)); ShortHeader(ProtectionType::KeyPhaseZero, connId, packetNum));
return OutstandingPacket( return OutstandingPacket(
std::move(packet), Clock::now(), size, false, totalSent, inflight); std::move(packet),
Clock::now(),
size,
false,
totalSent,
inflight,
0,
LossState());
} }
CongestionController::AckEvent createAckEvent( CongestionController::AckEvent createAckEvent(

View File

@@ -31,7 +31,14 @@ class CopaTest : public Test {
ShortHeader(ProtectionType::KeyPhaseZero, connId, packetData.first)); ShortHeader(ProtectionType::KeyPhaseZero, connId, packetData.first));
totalSentBytes += 10; totalSentBytes += 10;
loss.addLostPacket(OutstandingPacket( loss.addLostPacket(OutstandingPacket(
std::move(packet), Clock::now(), 10, false, totalSentBytes, 0)); std::move(packet),
Clock::now(),
10,
false,
totalSentBytes,
0,
0,
LossState()));
loss.lostBytes = packetData.second; loss.lostBytes = packetData.second;
} }
loss.lostPackets = lostPackets.size(); loss.lostPackets = lostPackets.size();
@@ -47,7 +54,14 @@ class CopaTest : public Test {
RegularQuicWritePacket packet( RegularQuicWritePacket packet(
ShortHeader(ProtectionType::KeyPhaseZero, connId, packetNum)); ShortHeader(ProtectionType::KeyPhaseZero, connId, packetNum));
return OutstandingPacket( return OutstandingPacket(
std::move(packet), Clock::now(), size, false, totalSent, inflight); std::move(packet),
Clock::now(),
size,
false,
totalSent,
inflight,
0,
LossState());
} }
CongestionController::AckEvent createAckEvent( CongestionController::AckEvent createAckEvent(

View File

@@ -26,8 +26,8 @@ CongestionController::LossEvent createLossEvent(
for (auto packetData : lostPackets) { for (auto packetData : lostPackets) {
RegularQuicWritePacket packet( RegularQuicWritePacket packet(
ShortHeader(ProtectionType::KeyPhaseZero, connId, packetData.first)); ShortHeader(ProtectionType::KeyPhaseZero, connId, packetData.first));
loss.addLostPacket( loss.addLostPacket(OutstandingPacket(
OutstandingPacket(std::move(packet), Clock::now(), 10, false, 10, 0)); std::move(packet), Clock::now(), 10, false, 10, 0, 0, LossState()));
loss.lostBytes = packetData.second; loss.lostBytes = packetData.second;
} }
loss.lostPackets = lostPackets.size(); loss.lostPackets = lostPackets.size();
@@ -46,7 +46,14 @@ CongestionController::AckEvent createAckEvent(
ack.ackedBytes = ackedSize; ack.ackedBytes = ackedSize;
ack.ackedPackets.push_back( ack.ackedPackets.push_back(
makeAckPacketFromOutstandingPacket(OutstandingPacket( makeAckPacketFromOutstandingPacket(OutstandingPacket(
std::move(packet), packetSentTime, ackedSize, false, ackedSize, 0))); std::move(packet),
packetSentTime,
ackedSize,
false,
ackedSize,
0,
0,
LossState())));
return ack; return ack;
} }
@@ -59,7 +66,7 @@ OutstandingPacket createPacket(
RegularQuicWritePacket packet( RegularQuicWritePacket packet(
ShortHeader(ProtectionType::KeyPhaseZero, connId, packetNum)); ShortHeader(ProtectionType::KeyPhaseZero, connId, packetNum));
return OutstandingPacket( return OutstandingPacket(
std::move(packet), sendTime, size, false, size, inflight); std::move(packet), sendTime, size, false, size, inflight, 0, LossState());
} }
TEST_F(NewRenoTest, TestLoss) { TEST_F(NewRenoTest, TestLoss) {

View File

@@ -209,7 +209,9 @@ TEST_F(QuicD6DStateFunctionsTest, D6DProbeAckedInBase) {
false, false,
true, true,
d6d.currentProbeSize, d6d.currentProbeSize,
d6d.currentProbeSize); d6d.currentProbeSize,
0,
LossState());
d6d.lastProbe = D6DProbePacket( d6d.lastProbe = D6DProbePacket(
pkt.packet.header.getPacketSequenceNum(), pkt.metadata.encodedSize); pkt.packet.header.getPacketSequenceNum(), pkt.metadata.encodedSize);
d6d.raiser = std::make_unique<MockProbeSizeRaiser>(); d6d.raiser = std::make_unique<MockProbeSizeRaiser>();
@@ -253,7 +255,9 @@ TEST_F(QuicD6DStateFunctionsTest, D6DProbeAckedInSearchingOne) {
false, false,
true, true,
d6d.currentProbeSize, d6d.currentProbeSize,
d6d.currentProbeSize); d6d.currentProbeSize,
0,
LossState());
d6d.lastProbe = D6DProbePacket( d6d.lastProbe = D6DProbePacket(
pkt.packet.header.getPacketSequenceNum(), pkt.metadata.encodedSize); pkt.packet.header.getPacketSequenceNum(), pkt.metadata.encodedSize);
d6d.raiser = std::make_unique<MockProbeSizeRaiser>(); d6d.raiser = std::make_unique<MockProbeSizeRaiser>();
@@ -298,7 +302,9 @@ TEST_F(QuicD6DStateFunctionsTest, D6DProbeAckedInSearchingMax) {
false, false,
true, true,
d6d.currentProbeSize, d6d.currentProbeSize,
d6d.currentProbeSize); d6d.currentProbeSize,
0,
LossState());
d6d.lastProbe = D6DProbePacket( d6d.lastProbe = D6DProbePacket(
pkt.packet.header.getPacketSequenceNum(), pkt.metadata.encodedSize); pkt.packet.header.getPacketSequenceNum(), pkt.metadata.encodedSize);
d6d.raiser = std::make_unique<MockProbeSizeRaiser>(); d6d.raiser = std::make_unique<MockProbeSizeRaiser>();
@@ -351,7 +357,9 @@ TEST_F(QuicD6DStateFunctionsTest, D6DProbeAckedInError) {
false, false,
true, true,
d6d.currentProbeSize, d6d.currentProbeSize,
d6d.currentProbeSize); d6d.currentProbeSize,
0,
LossState());
d6d.lastProbe = D6DProbePacket( d6d.lastProbe = D6DProbePacket(
pkt.packet.header.getPacketSequenceNum(), pkt.metadata.encodedSize); pkt.packet.header.getPacketSequenceNum(), pkt.metadata.encodedSize);
d6d.raiser = std::make_unique<MockProbeSizeRaiser>(); d6d.raiser = std::make_unique<MockProbeSizeRaiser>();
@@ -394,7 +402,9 @@ TEST_F(QuicD6DStateFunctionsTest, BlackholeInSearching) {
false, false,
true, true,
d6d.currentProbeSize, d6d.currentProbeSize,
d6d.currentProbeSize); d6d.currentProbeSize,
0,
LossState());
d6d.lastProbe = D6DProbePacket( d6d.lastProbe = D6DProbePacket(
pkt.packet.header.getPacketSequenceNum(), pkt.metadata.encodedSize); pkt.packet.header.getPacketSequenceNum(), pkt.metadata.encodedSize);
@@ -404,7 +414,9 @@ TEST_F(QuicD6DStateFunctionsTest, BlackholeInSearching) {
conn.udpSendPacketLen, conn.udpSendPacketLen,
false, false,
conn.udpSendPacketLen + d6d.currentProbeSize, conn.udpSendPacketLen + d6d.currentProbeSize,
conn.udpSendPacketLen + d6d.currentProbeSize); conn.udpSendPacketLen + d6d.currentProbeSize,
0,
LossState());
d6d.thresholdCounter = std::make_unique<WindowedCounter<uint64_t, uint64_t>>( d6d.thresholdCounter = std::make_unique<WindowedCounter<uint64_t, uint64_t>>(
std::chrono::microseconds(kDefaultD6DBlackholeDetectionWindow).count(), std::chrono::microseconds(kDefaultD6DBlackholeDetectionWindow).count(),
@@ -459,7 +471,9 @@ TEST_F(QuicD6DStateFunctionsTest, BlackholeInSearchComplete) {
false, false,
true, true,
d6d.currentProbeSize, d6d.currentProbeSize,
d6d.currentProbeSize); d6d.currentProbeSize,
0,
LossState());
d6d.lastProbe = D6DProbePacket( d6d.lastProbe = D6DProbePacket(
pkt.packet.header.getPacketSequenceNum(), pkt.metadata.encodedSize); pkt.packet.header.getPacketSequenceNum(), pkt.metadata.encodedSize);
@@ -469,7 +483,9 @@ TEST_F(QuicD6DStateFunctionsTest, BlackholeInSearchComplete) {
conn.udpSendPacketLen, conn.udpSendPacketLen,
false, false,
conn.udpSendPacketLen + d6d.currentProbeSize, conn.udpSendPacketLen + d6d.currentProbeSize,
conn.udpSendPacketLen + d6d.currentProbeSize); conn.udpSendPacketLen + d6d.currentProbeSize,
0,
LossState());
d6d.thresholdCounter = std::make_unique<WindowedCounter<uint64_t, uint64_t>>( d6d.thresholdCounter = std::make_unique<WindowedCounter<uint64_t, uint64_t>>(
std::chrono::microseconds(kDefaultD6DBlackholeDetectionWindow).count(), std::chrono::microseconds(kDefaultD6DBlackholeDetectionWindow).count(),
@@ -527,7 +543,9 @@ TEST_F(QuicD6DStateFunctionsTest, ReachMaxPMTU) {
false, false,
true, true,
d6d.currentProbeSize, d6d.currentProbeSize,
d6d.currentProbeSize); d6d.currentProbeSize,
0,
LossState());
d6d.lastProbe = D6DProbePacket( d6d.lastProbe = D6DProbePacket(
pkt.packet.header.getPacketSequenceNum(), pkt.metadata.encodedSize); pkt.packet.header.getPacketSequenceNum(), pkt.metadata.encodedSize);
d6d.raiser = std::make_unique<MockProbeSizeRaiser>(); d6d.raiser = std::make_unique<MockProbeSizeRaiser>();
@@ -564,7 +582,9 @@ TEST_F(
false, false,
true, true,
d6d.currentProbeSize, d6d.currentProbeSize,
d6d.currentProbeSize); d6d.currentProbeSize,
0,
LossState());
d6d.lastProbe = D6DProbePacket( d6d.lastProbe = D6DProbePacket(
pkt.packet.header.getPacketSequenceNum(), pkt.metadata.encodedSize); pkt.packet.header.getPacketSequenceNum(), pkt.metadata.encodedSize);
d6d.raiser = std::make_unique<MockProbeSizeRaiser>(); d6d.raiser = std::make_unique<MockProbeSizeRaiser>();
@@ -583,7 +603,9 @@ TEST_F(
false, false,
false, false,
d6d.currentProbeSize, d6d.currentProbeSize,
d6d.currentProbeSize); d6d.currentProbeSize,
0,
LossState());
// Generate a false positive blackhole signal // Generate a false positive blackhole signal
detectPMTUBlackhole(conn, lostPacket); detectPMTUBlackhole(conn, lostPacket);
EXPECT_EQ(d6d.state, D6DMachineState::BASE); EXPECT_EQ(d6d.state, D6DMachineState::BASE);
@@ -619,7 +641,9 @@ TEST_F(QuicD6DStateFunctionsTest, UpperboundIsBase) {
false, false,
true, true,
d6d.currentProbeSize, d6d.currentProbeSize,
d6d.currentProbeSize); d6d.currentProbeSize,
0,
LossState());
d6d.lastProbe = D6DProbePacket( d6d.lastProbe = D6DProbePacket(
pkt.packet.header.getPacketSequenceNum(), pkt.metadata.encodedSize); pkt.packet.header.getPacketSequenceNum(), pkt.metadata.encodedSize);
d6d.raiser = std::make_unique<MockProbeSizeRaiser>(); d6d.raiser = std::make_unique<MockProbeSizeRaiser>();

View File

@@ -249,7 +249,9 @@ PacketNum QuicLossFunctionsTest::sendPacket(
isHandshake, isHandshake,
isD6DProbe, isD6DProbe,
encodedSize, encodedSize,
0); 0,
0,
LossState());
outstandingPacket.associatedEvent = associatedEvent; outstandingPacket.associatedEvent = associatedEvent;
conn.lossState.lastRetransmittablePacketSentTime = time; conn.lossState.lastRetransmittablePacketSentTime = time;
if (conn.congestionController) { if (conn.congestionController) {
@@ -1066,8 +1068,8 @@ TEST_F(QuicLossFunctionsTest, TestHandleAckForLoss) {
conn->version.value()); conn->version.value());
RegularQuicWritePacket outstandingRegularPacket(std::move(longHeader)); RegularQuicWritePacket outstandingRegularPacket(std::move(longHeader));
auto now = Clock::now(); auto now = Clock::now();
conn->outstandings.packets.emplace_back( conn->outstandings.packets.emplace_back(OutstandingPacket(
OutstandingPacket(outstandingRegularPacket, now, 0, false, 0, 0)); outstandingRegularPacket, now, 0, false, 0, 0, 0, LossState()));
bool testLossMarkFuncCalled = false; bool testLossMarkFuncCalled = false;
auto testLossMarkFunc = [&](auto& /* conn */, auto&, bool) { auto testLossMarkFunc = [&](auto& /* conn */, auto&, bool) {

93
quic/state/LossState.h Normal file
View File

@@ -0,0 +1,93 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
#pragma once
#include <quic/codec/Types.h>
#include <quic/common/EnumArray.h>
namespace quic {
struct LossState {
enum class AlarmMethod { EarlyRetransmitOrReordering, PTO };
// Latest packet number sent
// TODO: this also needs to be 3 numbers now...
folly::Optional<PacketNum> largestSent;
// Timer for time reordering detection or early retransmit alarm.
EnumArray<PacketNumberSpace, folly::Optional<TimePoint>> lossTimes;
// Max ack delay received from peer
std::chrono::microseconds maxAckDelay{0us};
// minimum rtt. AckDelay isn't excluded from this.
std::chrono::microseconds mrtt{kDefaultMinRtt};
// Smooth rtt
std::chrono::microseconds srtt{0us};
// Latest rtt
std::chrono::microseconds lrtt{0us};
// Rtt var
std::chrono::microseconds rttvar{0us};
// The sent time of the latest acked packet
folly::Optional<TimePoint> lastAckedPacketSentTime;
// The latest time a packet is acked
folly::Optional<TimePoint> lastAckedTime;
// The latest time a packet is acked, minus ack delay
folly::Optional<TimePoint> adjustedLastAckedTime;
// The time when last retranmittable packet is sent for every packet number
// space
TimePoint lastRetransmittablePacketSentTime;
// Total number of bytes sent on this connection. This is after encoding.
uint64_t totalBytesSent{0};
// Total number of bytes received on this connection. This is before decoding.
uint64_t totalBytesRecvd{0};
// Total number of stream bytes retransmitted, excluding cloning.
uint64_t totalBytesRetransmitted{0};
// Total number of stream bytes cloned.
uint64_t totalStreamBytesCloned{0};
// Total number of bytes cloned.
uint64_t totalBytesCloned{0};
// Total number of bytes acked on this connection. If a packet is acked twice,
// it won't be count twice. Pure acks packets are NOT included.
uint64_t totalBytesAcked{0};
// The total number of bytes sent on this connection when the last time a
// packet is acked.
uint64_t totalBytesSentAtLastAck{0};
// The total number of bytes acked on this connection when the last time a
// packet is acked.
uint64_t totalBytesAckedAtLastAck{0};
// Total number of packets sent on this connection, including retransmissions.
uint32_t totalPacketsSent{0};
// Total number of ack-eliciting packets sent on this connection.
uint32_t totalAckElicitingPacketsSent{0};
// Total number of packets which were declared lost, including losses that
// we later detected were spurious (see totalPacketsSpuriouslyMarkedLost).
uint32_t totalPacketsMarkedLost{0};
// Total number of packets which were declared lost due to PTO; a packet can
// marked as lost by multiple detection mechanisms.
uint32_t totalPacketsMarkedLostByPto{0};
// Total number of packets which were declared lost based on the reordering
// threshold; a packet can marked as lost by multiple detection mechanisms.
uint32_t totalPacketsMarkedLostByReorderingThreshold{0};
// Total number of packets which were declared lost spuriously, i.e. we
// received an ACK for them later.
uint32_t totalPacketsSpuriouslyMarkedLost{0};
// Inflight bytes
uint64_t inflightBytes{0};
// Reordering threshold used
uint32_t reorderingThreshold{kReorderingThreshold};
// Number of packet loss timer fired before receiving an ack
uint32_t ptoCount{0};
// Total number of packet retransmitted on this connection, including packet
// clones, retransmitted clones, handshake and rejected zero rtt packets.
uint32_t rtxCount{0};
// Total number of retransmission due to PTO
uint32_t timeoutBasedRtxCount{0};
// Total number of PTO count
uint32_t totalPTOCount{0};
// Current method by which the loss detection alarm is set.
AlarmMethod currentAlarmMethod{AlarmMethod::EarlyRetransmitOrReordering};
};
} // namespace quic

View File

@@ -9,6 +9,7 @@
#pragma once #pragma once
#include <quic/codec/Types.h> #include <quic/codec/Types.h>
#include <quic/state/LossState.h>
#include <quic/state/PacketEvent.h> #include <quic/state/PacketEvent.h>
namespace quic { namespace quic {
@@ -28,6 +29,12 @@ struct OutstandingPacketMetadata {
// Bytes in flight on this connection including this packet itself when this // Bytes in flight on this connection including this packet itself when this
// packet is sent. // packet is sent.
uint64_t inflightBytes; uint64_t inflightBytes;
// Packets in flight on this connection including this packet itself.
uint64_t packetsInflight;
// Total number of packets sent on this connection.
uint32_t totalPacketsSent{0};
// Total number of ack-eliciting packets sent on this connection.
uint32_t totalAckElicitingPacketsSent{0};
OutstandingPacketMetadata( OutstandingPacketMetadata(
TimePoint timeIn, TimePoint timeIn,
@@ -35,13 +42,19 @@ struct OutstandingPacketMetadata {
bool isHandshakeIn, bool isHandshakeIn,
bool isD6DProbeIn, bool isD6DProbeIn,
uint64_t totalBytesSentIn, uint64_t totalBytesSentIn,
uint64_t inflightBytesIn) uint64_t inflightBytesIn,
: time(std::move(timeIn)), uint64_t packetsInflightIn,
const LossState& lossStateIn)
: time(timeIn),
encodedSize(encodedSizeIn), encodedSize(encodedSizeIn),
isHandshake(isHandshakeIn), isHandshake(isHandshakeIn),
isD6DProbe(isD6DProbeIn), isD6DProbe(isD6DProbeIn),
totalBytesSent(totalBytesSentIn), totalBytesSent(totalBytesSentIn),
inflightBytes(inflightBytesIn) {} inflightBytes(inflightBytesIn),
packetsInflight(packetsInflightIn),
totalPacketsSent(lossStateIn.totalPacketsSent),
totalAckElicitingPacketsSent(lossStateIn.totalAckElicitingPacketsSent) {
}
}; };
// Data structure to represent outstanding retransmittable packets // Data structure to represent outstanding retransmittable packets
@@ -104,15 +117,19 @@ struct OutstandingPacket {
uint32_t encodedSizeIn, uint32_t encodedSizeIn,
bool isHandshakeIn, bool isHandshakeIn,
uint64_t totalBytesSentIn, uint64_t totalBytesSentIn,
uint64_t inflightBytesIn) uint64_t inflightBytesIn,
uint64_t packetsInflightIn,
const LossState& lossStateIn)
: packet(std::move(packetIn)), : packet(std::move(packetIn)),
metadata(OutstandingPacketMetadata( metadata(OutstandingPacketMetadata(
std::move(timeIn), timeIn,
encodedSizeIn, encodedSizeIn,
isHandshakeIn, isHandshakeIn,
false, false,
totalBytesSentIn, totalBytesSentIn,
inflightBytesIn)) {} inflightBytesIn,
packetsInflightIn,
lossStateIn)) {}
OutstandingPacket( OutstandingPacket(
RegularQuicWritePacket packetIn, RegularQuicWritePacket packetIn,
@@ -121,14 +138,18 @@ struct OutstandingPacket {
bool isHandshakeIn, bool isHandshakeIn,
bool isD6DProbeIn, bool isD6DProbeIn,
uint64_t totalBytesSentIn, uint64_t totalBytesSentIn,
uint64_t inflightBytesIn) uint64_t inflightBytesIn,
uint64_t packetsInflightIn,
const LossState& lossStateIn)
: packet(std::move(packetIn)), : packet(std::move(packetIn)),
metadata(OutstandingPacketMetadata( metadata(OutstandingPacketMetadata(
std::move(timeIn), timeIn,
encodedSizeIn, encodedSizeIn,
isHandshakeIn, isHandshakeIn,
isD6DProbeIn, isD6DProbeIn,
totalBytesSentIn, totalBytesSentIn,
inflightBytesIn)) {} inflightBytesIn,
packetsInflightIn,
lossStateIn)) {}
}; };
} // namespace quic } // namespace quic

View File

@@ -15,12 +15,12 @@
#include <quic/codec/QuicWriteCodec.h> #include <quic/codec/QuicWriteCodec.h>
#include <quic/codec/Types.h> #include <quic/codec/Types.h>
#include <quic/common/BufAccessor.h> #include <quic/common/BufAccessor.h>
#include <quic/common/EnumArray.h>
#include <quic/common/WindowedCounter.h> #include <quic/common/WindowedCounter.h>
#include <quic/d6d/ProbeSizeRaiser.h> #include <quic/d6d/ProbeSizeRaiser.h>
#include <quic/handshake/HandshakeLayer.h> #include <quic/handshake/HandshakeLayer.h>
#include <quic/logging/QLogger.h> #include <quic/logging/QLogger.h>
#include <quic/state/AckStates.h> #include <quic/state/AckStates.h>
#include <quic/state/LossState.h>
#include <quic/state/OutstandingPacket.h> #include <quic/state/OutstandingPacket.h>
#include <quic/state/PacketEvent.h> #include <quic/state/PacketEvent.h>
#include <quic/state/PendingPathRateLimiter.h> #include <quic/state/PendingPathRateLimiter.h>
@@ -407,82 +407,6 @@ using Resets = folly::F14FastMap<StreamId, RstStreamFrame>;
using FrameList = std::vector<QuicSimpleFrame>; using FrameList = std::vector<QuicSimpleFrame>;
struct LossState {
enum class AlarmMethod { EarlyRetransmitOrReordering, PTO };
// Latest packet number sent
// TODO: this also needs to be 3 numbers now...
folly::Optional<PacketNum> largestSent;
// Timer for time reordering detection or early retransmit alarm.
EnumArray<PacketNumberSpace, folly::Optional<TimePoint>> lossTimes;
// Max ack delay received from peer
std::chrono::microseconds maxAckDelay{0us};
// minimum rtt. AckDelay isn't excluded from this.
std::chrono::microseconds mrtt{kDefaultMinRtt};
// Smooth rtt
std::chrono::microseconds srtt{0us};
// Latest rtt
std::chrono::microseconds lrtt{0us};
// Rtt var
std::chrono::microseconds rttvar{0us};
// The sent time of the latest acked packet
folly::Optional<TimePoint> lastAckedPacketSentTime;
// The latest time a packet is acked
folly::Optional<TimePoint> lastAckedTime;
// The latest time a packet is acked, minus ack delay
folly::Optional<TimePoint> adjustedLastAckedTime;
// The time when last retranmittable packet is sent for every packet number
// space
TimePoint lastRetransmittablePacketSentTime;
// Total number of bytes sent on this connection. This is after encoding.
uint64_t totalBytesSent{0};
// Total number of bytes received on this connection. This is before decoding.
uint64_t totalBytesRecvd{0};
// Total number of stream bytes retransmitted, excluding cloning.
uint64_t totalBytesRetransmitted{0};
// Total number of stream bytes cloned.
uint64_t totalStreamBytesCloned{0};
// Total number of bytes cloned.
uint64_t totalBytesCloned{0};
// Total number of bytes acked on this connection. If a packet is acked twice,
// it won't be count twice. Pure acks packets are NOT included.
uint64_t totalBytesAcked{0};
// The total number of bytes sent on this connection when the last time a
// packet is acked.
uint64_t totalBytesSentAtLastAck{0};
// The total number of bytes acked on this connection when the last time a
// packet is acked.
uint64_t totalBytesAckedAtLastAck{0};
// Total number of packets sent on this connection, including retransmissions.
uint32_t totalPacketsSent{0};
// Total number of packets which were declared lost, including losses that
// we later detected were spurious (see totalPacketsSpuriouslyMarkedLost).
uint32_t totalPacketsMarkedLost{0};
// Total number of packets which were declared lost due to PTO; a packet can
// marked as lost by multiple detection mechanisms.
uint32_t totalPacketsMarkedLostByPto{0};
// Total number of packets which were declared lost based on the reordering
// threshold; a packet can marked as lost by multiple detection mechanisms.
uint32_t totalPacketsMarkedLostByReorderingThreshold{0};
// Total number of packets which were declared lost spuriously, i.e. we
// received an ACK for them later.
uint32_t totalPacketsSpuriouslyMarkedLost{0};
// Inflight bytes
uint64_t inflightBytes{0};
// Reordering threshold used
uint32_t reorderingThreshold{kReorderingThreshold};
// Number of packet loss timer fired before receiving an ack
uint32_t ptoCount{0};
// Total number of packet retransmitted on this connection, including packet
// clones, retransmitted clones, handshake and rejected zero rtt packets.
uint32_t rtxCount{0};
// Total number of retransmission due to PTO
uint32_t timeoutBasedRtxCount{0};
// Total number of PTO count
uint32_t totalPTOCount{0};
// Current method by which the loss detection alarm is set.
AlarmMethod currentAlarmMethod{AlarmMethod::EarlyRetransmitOrReordering};
};
class Logger; class Logger;
class CongestionControllerFactory; class CongestionControllerFactory;
class LoopDetectorCallback; class LoopDetectorCallback;

View File

@@ -57,7 +57,9 @@ auto emplacePackets(
1, 1,
false /* handshake */, false /* handshake */,
packetNum, packetNum,
packetNum + 1); packetNum + 1,
packetNum + 1,
quic::LossState());
conn.outstandings.packets.emplace_back(sentPacket); conn.outstandings.packets.emplace_back(sentPacket);
packetNum++; packetNum++;
} }
@@ -81,7 +83,14 @@ TEST_P(AckHandlersTest, TestAckMultipleSequentialBlocks) {
WriteStreamFrame frame(currentStreamId++, 0, 0, true); WriteStreamFrame frame(currentStreamId++, 0, 0, true);
regularPacket.frames.emplace_back(std::move(frame)); regularPacket.frames.emplace_back(std::move(frame));
conn.outstandings.packets.emplace_back(OutstandingPacket( conn.outstandings.packets.emplace_back(OutstandingPacket(
std::move(regularPacket), sentTime, 1, false, packetNum, 0)); std::move(regularPacket),
sentTime,
1,
false,
packetNum,
0,
0,
LossState()));
} }
ReadAckFrame ackFrame; ReadAckFrame ackFrame;
ackFrame.largestAcked = 101; ackFrame.largestAcked = 101;
@@ -152,7 +161,14 @@ TEST_P(AckHandlersTest, TestAckMultipleSequentialBlocksLoss) {
WriteStreamFrame frame(currentStreamId++, 0, 0, true); WriteStreamFrame frame(currentStreamId++, 0, 0, true);
regularPacket.frames.emplace_back(std::move(frame)); regularPacket.frames.emplace_back(std::move(frame));
conn.outstandings.packets.emplace_back(OutstandingPacket( conn.outstandings.packets.emplace_back(OutstandingPacket(
std::move(regularPacket), sentTime, 1, false, packetNum, 0)); std::move(regularPacket),
sentTime,
1,
false,
packetNum,
0,
0,
LossState()));
} }
ReadAckFrame ackFrame; ReadAckFrame ackFrame;
ackFrame.largestAcked = 101; ackFrame.largestAcked = 101;
@@ -287,7 +303,14 @@ TEST_P(AckHandlersTest, TestAckBlocksWithGaps) {
WriteStreamFrame frame(currentStreamId++, 0, 0, true); WriteStreamFrame frame(currentStreamId++, 0, 0, true);
regularPacket.frames.emplace_back(std::move(frame)); regularPacket.frames.emplace_back(std::move(frame));
conn.outstandings.packets.emplace_back(OutstandingPacket( conn.outstandings.packets.emplace_back(OutstandingPacket(
std::move(regularPacket), Clock::now(), 1, false, packetNum, 0)); std::move(regularPacket),
Clock::now(),
1,
false,
packetNum,
0,
0,
LossState()));
} }
ReadAckFrame ackFrame; ReadAckFrame ackFrame;
@@ -385,7 +408,14 @@ TEST_P(AckHandlersTest, TestNonSequentialPacketNumbers) {
WriteStreamFrame frame(current++, 0, 0, true); WriteStreamFrame frame(current++, 0, 0, true);
regularPacket.frames.emplace_back(std::move(frame)); regularPacket.frames.emplace_back(std::move(frame));
conn.outstandings.packets.emplace_back(OutstandingPacket( conn.outstandings.packets.emplace_back(OutstandingPacket(
std::move(regularPacket), Clock::now(), 1, false, packetNum, 0)); std::move(regularPacket),
Clock::now(),
1,
false,
packetNum,
0,
0,
LossState()));
} }
for (PacketNum packetNum = 20; packetNum < 40; packetNum += 3) { for (PacketNum packetNum = 20; packetNum < 40; packetNum += 3) {
@@ -394,7 +424,14 @@ TEST_P(AckHandlersTest, TestNonSequentialPacketNumbers) {
current += 3; current += 3;
regularPacket.frames.emplace_back(std::move(frame)); regularPacket.frames.emplace_back(std::move(frame));
conn.outstandings.packets.emplace_back(OutstandingPacket( conn.outstandings.packets.emplace_back(OutstandingPacket(
std::move(regularPacket), Clock::now(), 1, false, packetNum, 0)); std::move(regularPacket),
Clock::now(),
1,
false,
packetNum,
0,
0,
LossState()));
} }
ReadAckFrame ackFrame; ReadAckFrame ackFrame;
@@ -474,8 +511,8 @@ TEST_P(AckHandlersTest, AckVisitorForAckTest) {
conn.ackStates.appDataAckState.acks.insert(900, 1000); conn.ackStates.appDataAckState.acks.insert(900, 1000);
conn.ackStates.appDataAckState.acks.insert(500, 700); conn.ackStates.appDataAckState.acks.insert(500, 700);
firstPacket.frames.emplace_back(std::move(firstAckFrame)); firstPacket.frames.emplace_back(std::move(firstAckFrame));
conn.outstandings.packets.emplace_back( conn.outstandings.packets.emplace_back(OutstandingPacket(
OutstandingPacket(std::move(firstPacket), Clock::now(), 0, false, 0, 0)); std::move(firstPacket), Clock::now(), 0, false, 0, 0, 0, LossState()));
auto secondPacket = createNewPacket(101 /* packetNum */, GetParam()); auto secondPacket = createNewPacket(101 /* packetNum */, GetParam());
WriteAckFrame secondAckFrame; WriteAckFrame secondAckFrame;
@@ -484,8 +521,8 @@ TEST_P(AckHandlersTest, AckVisitorForAckTest) {
conn.ackStates.appDataAckState.acks.insert(1100, 2000); conn.ackStates.appDataAckState.acks.insert(1100, 2000);
conn.ackStates.appDataAckState.acks.insert(1002, 1090); conn.ackStates.appDataAckState.acks.insert(1002, 1090);
secondPacket.frames.emplace_back(std::move(secondAckFrame)); secondPacket.frames.emplace_back(std::move(secondAckFrame));
conn.outstandings.packets.emplace_back( conn.outstandings.packets.emplace_back(OutstandingPacket(
OutstandingPacket(std::move(secondPacket), Clock::now(), 0, false, 0, 0)); std::move(secondPacket), Clock::now(), 0, false, 0, 0, 0, LossState()));
ReadAckFrame firstReceivedAck; ReadAckFrame firstReceivedAck;
firstReceivedAck.largestAcked = 100; firstReceivedAck.largestAcked = 100;
@@ -546,7 +583,7 @@ TEST_P(AckHandlersTest, NoNewAckedPacket) {
PacketNum packetAfterRtoNum = 10; PacketNum packetAfterRtoNum = 10;
auto packetAfterRto = createNewPacket(packetAfterRtoNum, GetParam()); auto packetAfterRto = createNewPacket(packetAfterRtoNum, GetParam());
conn.outstandings.packets.emplace_back(OutstandingPacket( conn.outstandings.packets.emplace_back(OutstandingPacket(
std::move(packetAfterRto), Clock::now(), 0, false, 0, 0)); std::move(packetAfterRto), Clock::now(), 0, false, 0, 0, 0, LossState()));
ReadAckFrame ackFrame; ReadAckFrame ackFrame;
ackFrame.largestAcked = 5; ackFrame.largestAcked = 5;
@@ -592,12 +629,12 @@ TEST_P(AckHandlersTest, AckPacketNumDoesNotExist) {
PacketNum packetNum1 = 9; PacketNum packetNum1 = 9;
auto regularPacket1 = createNewPacket(packetNum1, GetParam()); auto regularPacket1 = createNewPacket(packetNum1, GetParam());
conn.outstandings.packets.emplace_back( conn.outstandings.packets.emplace_back(
std::move(regularPacket1), Clock::now(), 0, false, 0, 0); std::move(regularPacket1), Clock::now(), 0, false, 0, 0, 0, LossState());
PacketNum packetNum2 = 10; PacketNum packetNum2 = 10;
auto regularPacket2 = createNewPacket(packetNum2, GetParam()); auto regularPacket2 = createNewPacket(packetNum2, GetParam());
conn.outstandings.packets.emplace_back( conn.outstandings.packets.emplace_back(
std::move(regularPacket2), Clock::now(), 0, false, 0, 0); std::move(regularPacket2), Clock::now(), 0, false, 0, 0, 0, LossState());
// Ack a packet one higher than the packet so that we don't trigger reordering // Ack a packet one higher than the packet so that we don't trigger reordering
// threshold. // threshold.
@@ -631,7 +668,9 @@ TEST_P(AckHandlersTest, TestHandshakeCounterUpdate) {
0, 0,
packetNum % 2 && GetParam() != PacketNumberSpace::AppData, packetNum % 2 && GetParam() != PacketNumberSpace::AppData,
packetNum / 2, packetNum / 2,
0); 0,
0,
LossState());
if (GetParam() == PacketNumberSpace::Initial) { if (GetParam() == PacketNumberSpace::Initial) {
conn.outstandings.initialPacketsCount += packetNum % 2; conn.outstandings.initialPacketsCount += packetNum % 2;
} else if (GetParam() == PacketNumberSpace::Handshake) { } else if (GetParam() == PacketNumberSpace::Handshake) {
@@ -714,7 +753,7 @@ TEST_P(AckHandlersTest, NoSkipAckVisitor) {
WriteStreamFrame frame(0, 0, 0, true); WriteStreamFrame frame(0, 0, 0, true);
regularPacket.frames.emplace_back(std::move(frame)); regularPacket.frames.emplace_back(std::move(frame));
conn.outstandings.packets.emplace_back(OutstandingPacket( conn.outstandings.packets.emplace_back(OutstandingPacket(
std::move(regularPacket), Clock::now(), 1, false, 1, 0)); std::move(regularPacket), Clock::now(), 1, false, 1, 0, 0, LossState()));
ReadAckFrame ackFrame; ReadAckFrame ackFrame;
ackFrame.largestAcked = 0; ackFrame.largestAcked = 0;
ackFrame.ackBlocks.emplace_back(0, 0); ackFrame.ackBlocks.emplace_back(0, 0);
@@ -756,7 +795,7 @@ TEST_P(AckHandlersTest, SkipAckVisitor) {
WriteStreamFrame frame(0, 0, 0, true); WriteStreamFrame frame(0, 0, 0, true);
regularPacket.frames.emplace_back(std::move(frame)); regularPacket.frames.emplace_back(std::move(frame));
OutstandingPacket outstandingPacket( OutstandingPacket outstandingPacket(
std::move(regularPacket), Clock::now(), 1, false, 1, 0); std::move(regularPacket), Clock::now(), 1, false, 1, 0, 0, LossState());
// Give this outstandingPacket an associatedEvent that's not in // Give this outstandingPacket an associatedEvent that's not in
// outstandings.packetEvents // outstandings.packetEvents
outstandingPacket.associatedEvent.emplace(PacketNumberSpace::AppData, 0); outstandingPacket.associatedEvent.emplace(PacketNumberSpace::AppData, 0);
@@ -797,12 +836,12 @@ TEST_P(AckHandlersTest, NoDoubleProcess) {
regularPacket2.frames.push_back(frame); regularPacket2.frames.push_back(frame);
OutstandingPacket outstandingPacket1( OutstandingPacket outstandingPacket1(
std::move(regularPacket1), Clock::now(), 1, false, 1, 0); std::move(regularPacket1), Clock::now(), 1, false, 1, 0, 0, LossState());
outstandingPacket1.associatedEvent.emplace( outstandingPacket1.associatedEvent.emplace(
PacketNumberSpace::AppData, packetNum1); PacketNumberSpace::AppData, packetNum1);
OutstandingPacket outstandingPacket2( OutstandingPacket outstandingPacket2(
std::move(regularPacket2), Clock::now(), 1, false, 1, 0); std::move(regularPacket2), Clock::now(), 1, false, 1, 0, 0, LossState());
// The seconds packet has the same PacketEvent // The seconds packet has the same PacketEvent
outstandingPacket2.associatedEvent.emplace( outstandingPacket2.associatedEvent.emplace(
PacketNumberSpace::AppData, packetNum1); PacketNumberSpace::AppData, packetNum1);
@@ -859,7 +898,7 @@ TEST_P(AckHandlersTest, ClonedPacketsCounter) {
auto regularPacket1 = createNewPacket(packetNum1, GetParam()); auto regularPacket1 = createNewPacket(packetNum1, GetParam());
regularPacket1.frames.push_back(frame); regularPacket1.frames.push_back(frame);
OutstandingPacket outstandingPacket1( OutstandingPacket outstandingPacket1(
std::move(regularPacket1), Clock::now(), 1, false, 1, 0); std::move(regularPacket1), Clock::now(), 1, false, 1, 0, 0, LossState());
outstandingPacket1.associatedEvent.emplace( outstandingPacket1.associatedEvent.emplace(
PacketNumberSpace::AppData, packetNum1); PacketNumberSpace::AppData, packetNum1);
@@ -868,7 +907,7 @@ TEST_P(AckHandlersTest, ClonedPacketsCounter) {
auto regularPacket2 = createNewPacket(packetNum2, GetParam()); auto regularPacket2 = createNewPacket(packetNum2, GetParam());
regularPacket2.frames.push_back(frame); regularPacket2.frames.push_back(frame);
OutstandingPacket outstandingPacket2( OutstandingPacket outstandingPacket2(
std::move(regularPacket2), Clock::now(), 1, false, 1, 0); std::move(regularPacket2), Clock::now(), 1, false, 1, 0, 0, LossState());
conn.outstandings.packets.push_back(std::move(outstandingPacket1)); conn.outstandings.packets.push_back(std::move(outstandingPacket1));
conn.outstandings.packets.push_back(std::move(outstandingPacket2)); conn.outstandings.packets.push_back(std::move(outstandingPacket2));
@@ -906,8 +945,8 @@ TEST_P(AckHandlersTest, UpdateMaxAckDelay) {
PacketNum packetNum = 0; PacketNum packetNum = 0;
auto regularPacket = createNewPacket(packetNum, GetParam()); auto regularPacket = createNewPacket(packetNum, GetParam());
auto sentTime = Clock::now(); auto sentTime = Clock::now();
conn.outstandings.packets.emplace_back( conn.outstandings.packets.emplace_back(OutstandingPacket(
OutstandingPacket(std::move(regularPacket), sentTime, 1, false, 1, 0)); std::move(regularPacket), sentTime, 1, false, 1, 0, 0, LossState()));
ReadAckFrame ackFrame; ReadAckFrame ackFrame;
// ackDelay has no effect on mrtt // ackDelay has no effect on mrtt
@@ -964,7 +1003,9 @@ TEST_P(AckHandlersTest, AckNotOutstandingButLoss) {
1, 1,
false, false,
1, 1,
0); 0,
0,
LossState());
conn.outstandings.packets.push_back(std::move(outstandingPacket)); conn.outstandings.packets.push_back(std::move(outstandingPacket));
conn.outstandings.clonedPacketsCount++; conn.outstandings.clonedPacketsCount++;
@@ -1008,7 +1049,9 @@ TEST_P(AckHandlersTest, UpdatePendingAckStates) {
111, 111,
false, false,
conn.lossState.totalBytesSent + 111, conn.lossState.totalBytesSent + 111,
0)); 0,
0,
LossState()));
conn.lossState.totalBytesSent += 111; conn.lossState.totalBytesSent += 111;
ReadAckFrame ackFrame; ReadAckFrame ackFrame;
@@ -1052,7 +1095,9 @@ TEST_P(AckHandlersTest, AckEventCreation) {
1, 1,
false /* handshake */, false /* handshake */,
packetNum, packetNum,
0); 0,
0,
LossState());
sentPacket.isAppLimited = (packetNum % 2); sentPacket.isAppLimited = (packetNum % 2);
conn.outstandings.packets.emplace_back(sentPacket); conn.outstandings.packets.emplace_back(sentPacket);
packetNum++; packetNum++;
@@ -1107,7 +1152,9 @@ TEST_P(AckHandlersTest, ImplictAckEventCreation) {
1, 1,
false /* handshake */, false /* handshake */,
packetNum, packetNum,
packetNum + 1); packetNum + 1,
0,
LossState());
sentPacket.isAppLimited = (packetNum % 2); sentPacket.isAppLimited = (packetNum % 2);
conn.outstandings.packets.emplace_back(sentPacket); conn.outstandings.packets.emplace_back(sentPacket);
packetNum++; packetNum++;
@@ -1172,7 +1219,9 @@ TEST_P(AckHandlersTest, TestRTTPacketObserverCallback) {
1, 1,
false /* handshake */, false /* handshake */,
packetNum, packetNum,
packetNum + 1); packetNum + 1,
0,
LossState());
sentPacket.isAppLimited = false; sentPacket.isAppLimited = false;
conn.outstandings.packets.emplace_back(sentPacket); conn.outstandings.packets.emplace_back(sentPacket);
packetNum++; packetNum++;

View File

@@ -554,25 +554,31 @@ TEST_F(QuicStateFunctionsTest, GetOutstandingPackets) {
135, 135,
false, false,
0, 0,
0); 0,
0,
LossState());
conn.outstandings.packets.emplace_back( conn.outstandings.packets.emplace_back(
makeTestLongPacket(LongHeader::Types::Handshake), makeTestLongPacket(LongHeader::Types::Handshake),
Clock::now(), Clock::now(),
1217, 1217,
false, false,
0, 0,
0); 0,
0,
LossState());
conn.outstandings.packets.emplace_back( conn.outstandings.packets.emplace_back(
makeTestShortPacket(), Clock::now(), 5556, false, 0, 0); makeTestShortPacket(), Clock::now(), 5556, false, 0, 0, 0, LossState());
conn.outstandings.packets.emplace_back( conn.outstandings.packets.emplace_back(
makeTestLongPacket(LongHeader::Types::Initial), makeTestLongPacket(LongHeader::Types::Initial),
Clock::now(), Clock::now(),
56, 56,
false, false,
0, 0,
0); 0,
0,
LossState());
conn.outstandings.packets.emplace_back( conn.outstandings.packets.emplace_back(
makeTestShortPacket(), Clock::now(), 6665, false, 0, 0); makeTestShortPacket(), Clock::now(), 6665, false, 0, 0, 0, LossState());
EXPECT_EQ( EXPECT_EQ(
135, 135,
getFirstOutstandingPacket(conn, PacketNumberSpace::Initial) getFirstOutstandingPacket(conn, PacketNumberSpace::Initial)

View File

@@ -11,6 +11,7 @@
#include <quic/common/test/TestUtils.h> #include <quic/common/test/TestUtils.h>
#include <quic/state/StateData.h> #include <quic/state/StateData.h>
#include "quic/state/LossState.h"
using namespace quic; using namespace quic;
using namespace testing; using namespace testing;
@@ -36,7 +37,7 @@ TEST_F(StateDataTest, SingleLostPacketEvent) {
100, 100,
kVersion)); kVersion));
OutstandingPacket outstandingPacket( OutstandingPacket outstandingPacket(
packet, Clock::now(), 1234, false, 1234, 0); packet, Clock::now(), 1234, false, 1234, 0, 0, LossState());
CongestionController::LossEvent loss; CongestionController::LossEvent loss;
loss.addLostPacket(outstandingPacket); loss.addLostPacket(outstandingPacket);
EXPECT_EQ(1234, loss.lostBytes); EXPECT_EQ(1234, loss.lostBytes);
@@ -51,7 +52,7 @@ TEST_F(StateDataTest, MultipleLostPacketsEvent) {
100, 100,
kVersion)); kVersion));
OutstandingPacket outstandingPacket1( OutstandingPacket outstandingPacket1(
packet1, Clock::now(), 1234, false, 1234, 0); packet1, Clock::now(), 1234, false, 1234, 0, 0, LossState());
RegularQuicWritePacket packet2(LongHeader( RegularQuicWritePacket packet2(LongHeader(
LongHeader::Types::Initial, LongHeader::Types::Initial,
@@ -60,7 +61,7 @@ TEST_F(StateDataTest, MultipleLostPacketsEvent) {
110, 110,
kVersion)); kVersion));
OutstandingPacket outstandingPacket2( OutstandingPacket outstandingPacket2(
packet2, Clock::now(), 1357, false, 1357, 0); packet2, Clock::now(), 1357, false, 1357, 0, 0, LossState());
CongestionController::LossEvent loss; CongestionController::LossEvent loss;
loss.addLostPacket(outstandingPacket1); loss.addLostPacket(outstandingPacket1);