mirror of
https://github.com/facebookincubator/mvfst.git
synced 2025-08-06 22:22:38 +03:00
Adding packet rtt sampling to instrumentationObserver (#178)
Summary: Due to high number of RTT samples I refactored the OutstandingPacket to split the packet data and packet metrics. We know have access to metrics without the need of saving the packet data. Pull Request resolved: https://github.com/facebookincubator/mvfst/pull/178 Reviewed By: mjoras Differential Revision: D23711641 Pulled By: bschlinker fbshipit-source-id: 53791f1f6f6e184f37afca991a873af05909fbd2
This commit is contained in:
committed by
Facebook GitHub Bot
parent
7076092dd9
commit
a8d5c156a1
@@ -29,10 +29,13 @@ class InstrumentationObserver {
|
|||||||
const quic::OutstandingPacket& pkt)
|
const quic::OutstandingPacket& pkt)
|
||||||
: lostByTimeout(lostbytimeout),
|
: lostByTimeout(lostbytimeout),
|
||||||
lostByReorderThreshold(lostbyreorder),
|
lostByReorderThreshold(lostbyreorder),
|
||||||
packet(pkt) {}
|
metadata(pkt.metadata),
|
||||||
|
lastAckedPacketInfo(pkt.lastAckedPacketInfo) {}
|
||||||
bool lostByTimeout{false};
|
bool lostByTimeout{false};
|
||||||
bool lostByReorderThreshold{false};
|
bool lostByReorderThreshold{false};
|
||||||
const quic::OutstandingPacket packet;
|
const quic::OutstandingPacketMetadata metadata;
|
||||||
|
const folly::Optional<OutstandingPacket::LastAckedPacketInfo>
|
||||||
|
lastAckedPacketInfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ObserverLossEvent {
|
struct ObserverLossEvent {
|
||||||
@@ -52,6 +55,26 @@ class InstrumentationObserver {
|
|||||||
const TimePoint lossTime;
|
const TimePoint lossTime;
|
||||||
std::vector<LostPacket> lostPackets;
|
std::vector<LostPacket> lostPackets;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct PacketRTT {
|
||||||
|
explicit PacketRTT(
|
||||||
|
TimePoint rcvTimeIn,
|
||||||
|
std::chrono::microseconds rttSampleIn,
|
||||||
|
std::chrono::microseconds ackDelayIn,
|
||||||
|
const quic::OutstandingPacket& pkt)
|
||||||
|
: rcvTime(rcvTimeIn),
|
||||||
|
rttSample(rttSampleIn),
|
||||||
|
ackDelay(ackDelayIn),
|
||||||
|
metadata(pkt.metadata),
|
||||||
|
lastAckedPacketInfo(pkt.lastAckedPacketInfo) {}
|
||||||
|
TimePoint rcvTime;
|
||||||
|
std::chrono::microseconds rttSample;
|
||||||
|
std::chrono::microseconds ackDelay;
|
||||||
|
const quic::OutstandingPacketMetadata metadata;
|
||||||
|
const folly::Optional<OutstandingPacket::LastAckedPacketInfo>
|
||||||
|
lastAckedPacketInfo;
|
||||||
|
};
|
||||||
|
|
||||||
virtual ~InstrumentationObserver() = default;
|
virtual ~InstrumentationObserver() = default;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -78,6 +101,13 @@ class InstrumentationObserver {
|
|||||||
*/
|
*/
|
||||||
virtual void packetLossDetected(
|
virtual void packetLossDetected(
|
||||||
const struct ObserverLossEvent& /* lossEvent */) {}
|
const struct ObserverLossEvent& /* lossEvent */) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rttSampleGenerated() is invoked when a RTT sample is made.
|
||||||
|
*
|
||||||
|
* @param packet const reference to the packet with the RTT
|
||||||
|
*/
|
||||||
|
virtual void rttSampleGenerated(const PacketRTT& /* RTT sample */) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Container for instrumentation observers.
|
// Container for instrumentation observers.
|
||||||
|
@@ -613,7 +613,8 @@ SchedulingResult CloningScheduler::scheduleFramesForPacket(
|
|||||||
}
|
}
|
||||||
// I think this only fail if udpSendPacketLen somehow shrinks in the middle
|
// I think this only fail if udpSendPacketLen somehow shrinks in the middle
|
||||||
// of a connection.
|
// of a connection.
|
||||||
if (outstandingPacket.encodedSize > writableBytes + cipherOverhead_) {
|
if (outstandingPacket.metadata.encodedSize >
|
||||||
|
writableBytes + cipherOverhead_) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -681,7 +681,8 @@ void updateConnection(
|
|||||||
encodedSize,
|
encodedSize,
|
||||||
isHandshake,
|
isHandshake,
|
||||||
isD6DProbe,
|
isD6DProbe,
|
||||||
conn.lossState.totalBytesSent);
|
conn.lossState.totalBytesSent,
|
||||||
|
conn.lossState.inflightBytes);
|
||||||
if (isD6DProbe) {
|
if (isD6DProbe) {
|
||||||
++conn.d6d.outstandingProbes;
|
++conn.d6d.outstandingProbes;
|
||||||
}
|
}
|
||||||
@@ -722,9 +723,9 @@ void updateConnection(
|
|||||||
}
|
}
|
||||||
if (conn.pathValidationLimiter &&
|
if (conn.pathValidationLimiter &&
|
||||||
(conn.pendingEvents.pathChallenge || conn.outstandingPathValidation)) {
|
(conn.pendingEvents.pathChallenge || conn.outstandingPathValidation)) {
|
||||||
conn.pathValidationLimiter->onPacketSent(pkt.encodedSize);
|
conn.pathValidationLimiter->onPacketSent(pkt.metadata.encodedSize);
|
||||||
}
|
}
|
||||||
if (pkt.isHandshake) {
|
if (pkt.metadata.isHandshake) {
|
||||||
if (!pkt.associatedEvent) {
|
if (!pkt.associatedEvent) {
|
||||||
if (packetNumberSpace == PacketNumberSpace::Initial) {
|
if (packetNumberSpace == PacketNumberSpace::Initial) {
|
||||||
++conn.outstandings.initialPacketsCount;
|
++conn.outstandings.initialPacketsCount;
|
||||||
@@ -733,9 +734,9 @@ void updateConnection(
|
|||||||
++conn.outstandings.handshakePacketsCount;
|
++conn.outstandings.handshakePacketsCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
conn.lossState.lastHandshakePacketSentTime = pkt.time;
|
conn.lossState.lastHandshakePacketSentTime = pkt.metadata.time;
|
||||||
}
|
}
|
||||||
conn.lossState.lastRetransmittablePacketSentTime = pkt.time;
|
conn.lossState.lastRetransmittablePacketSentTime = pkt.metadata.time;
|
||||||
if (pkt.associatedEvent) {
|
if (pkt.associatedEvent) {
|
||||||
++conn.outstandings.clonedPacketsCount;
|
++conn.outstandings.clonedPacketsCount;
|
||||||
++conn.lossState.timeoutBasedRtxCount;
|
++conn.lossState.timeoutBasedRtxCount;
|
||||||
|
@@ -332,6 +332,7 @@ class MockInstrumentationObserver : public InstrumentationObserver {
|
|||||||
,
|
,
|
||||||
packetLossDetected,
|
packetLossDetected,
|
||||||
void(const ObserverLossEvent&));
|
void(const ObserverLossEvent&));
|
||||||
|
GMOCK_METHOD1_(, noexcept, , rttSampleGenerated, void(const PacketRTT&));
|
||||||
|
|
||||||
static auto getLossPacketMatcher(bool reorderLoss, bool timeoutLoss) {
|
static auto getLossPacketMatcher(bool reorderLoss, bool timeoutLoss) {
|
||||||
return AllOf(
|
return AllOf(
|
||||||
|
@@ -40,7 +40,7 @@ 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);
|
conn.outstandings.packets.emplace_back(packet, Clock::now(), 0, true, 0, 0);
|
||||||
conn.outstandings.handshakePacketsCount++;
|
conn.outstandings.handshakePacketsCount++;
|
||||||
increaseNextPacketNum(conn, PacketNumberSpace::Handshake);
|
increaseNextPacketNum(conn, PacketNumberSpace::Handshake);
|
||||||
return nextPacketNum;
|
return nextPacketNum;
|
||||||
@@ -58,7 +58,7 @@ 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);
|
conn.outstandings.packets.emplace_back(packet, Clock::now(), 0, true, 0, 0);
|
||||||
conn.outstandings.handshakePacketsCount++;
|
conn.outstandings.handshakePacketsCount++;
|
||||||
increaseNextPacketNum(conn, PacketNumberSpace::Handshake);
|
increaseNextPacketNum(conn, PacketNumberSpace::Handshake);
|
||||||
return nextPacketNum;
|
return nextPacketNum;
|
||||||
@@ -71,7 +71,7 @@ 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);
|
conn.outstandings.packets.emplace_back(packet, Clock::now(), 0, false, 0, 0);
|
||||||
increaseNextPacketNum(conn, PacketNumberSpace::AppData);
|
increaseNextPacketNum(conn, PacketNumberSpace::AppData);
|
||||||
return nextPacketNum;
|
return nextPacketNum;
|
||||||
}
|
}
|
||||||
@@ -1371,7 +1371,8 @@ TEST_F(
|
|||||||
conn.outstandings.packets.back().packet.frames.push_back(
|
conn.outstandings.packets.back().packet.frames.push_back(
|
||||||
MaxDataFrame(conn.flowControlState.advertisedMaxOffset));
|
MaxDataFrame(conn.flowControlState.advertisedMaxOffset));
|
||||||
// Lie about the encodedSize to let the Cloner skip it:
|
// Lie about the encodedSize to let the Cloner skip it:
|
||||||
conn.outstandings.packets.back().encodedSize = kDefaultUDPSendPacketLen * 2;
|
conn.outstandings.packets.back().metadata.encodedSize =
|
||||||
|
kDefaultUDPSendPacketLen * 2;
|
||||||
EXPECT_TRUE(cloningScheduler.hasData());
|
EXPECT_TRUE(cloningScheduler.hasData());
|
||||||
|
|
||||||
ASSERT_FALSE(noopScheduler.hasData());
|
ASSERT_FALSE(noopScheduler.hasData());
|
||||||
|
@@ -367,7 +367,7 @@ TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionD6DNotConsumeSendPing) {
|
|||||||
conn->d6d.lastProbe = QuicConnectionStateBase::D6DProbePacket(packetNum, 50);
|
conn->d6d.lastProbe = QuicConnectionStateBase::D6DProbePacket(packetNum, 50);
|
||||||
updateConnection(*conn, folly::none, packet.packet, Clock::now(), 50);
|
updateConnection(*conn, folly::none, packet.packet, Clock::now(), 50);
|
||||||
EXPECT_EQ(1, conn->outstandings.packets.size());
|
EXPECT_EQ(1, conn->outstandings.packets.size());
|
||||||
EXPECT_TRUE(conn->outstandings.packets.front().isD6DProbe);
|
EXPECT_TRUE(conn->outstandings.packets.front().metadata.isD6DProbe);
|
||||||
EXPECT_EQ(1, conn->d6d.outstandingProbes);
|
EXPECT_EQ(1, conn->d6d.outstandingProbes);
|
||||||
// sendPing should still be active since d6d probe should be "hidden" from
|
// sendPing should still be active since d6d probe should be "hidden" from
|
||||||
// application
|
// application
|
||||||
@@ -959,7 +959,7 @@ TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionWithBytesStats) {
|
|||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
13579 + 555,
|
13579 + 555,
|
||||||
getFirstOutstandingPacket(*conn, PacketNumberSpace::Handshake)
|
getFirstOutstandingPacket(*conn, PacketNumberSpace::Handshake)
|
||||||
->totalBytesSent);
|
->metadata.totalBytesSent);
|
||||||
EXPECT_TRUE(getFirstOutstandingPacket(*conn, PacketNumberSpace::Handshake)
|
EXPECT_TRUE(getFirstOutstandingPacket(*conn, PacketNumberSpace::Handshake)
|
||||||
->lastAckedPacketInfo.has_value());
|
->lastAckedPacketInfo.has_value());
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
@@ -1025,10 +1025,12 @@ TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionWithCloneResult) {
|
|||||||
EXPECT_EQ(frame->maximumData, maxDataAmt);
|
EXPECT_EQ(frame->maximumData, maxDataAmt);
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
futureMoment,
|
futureMoment,
|
||||||
getLastOutstandingPacket(*conn, PacketNumberSpace::AppData)->time);
|
getLastOutstandingPacket(*conn, PacketNumberSpace::AppData)
|
||||||
|
->metadata.time);
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
1500,
|
1500,
|
||||||
getLastOutstandingPacket(*conn, PacketNumberSpace::AppData)->encodedSize);
|
getLastOutstandingPacket(*conn, PacketNumberSpace::AppData)
|
||||||
|
->metadata.encodedSize);
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
event,
|
event,
|
||||||
*getLastOutstandingPacket(*conn, PacketNumberSpace::AppData)
|
*getLastOutstandingPacket(*conn, PacketNumberSpace::AppData)
|
||||||
@@ -1676,7 +1678,7 @@ TEST_F(QuicTransportFunctionsTest, TestCryptoWritingIsHandshakeInOutstanding) {
|
|||||||
conn->transportSettings.writeConnectionDataPacketsLimit));
|
conn->transportSettings.writeConnectionDataPacketsLimit));
|
||||||
ASSERT_EQ(1, conn->outstandings.packets.size());
|
ASSERT_EQ(1, conn->outstandings.packets.size());
|
||||||
EXPECT_TRUE(getFirstOutstandingPacket(*conn, PacketNumberSpace::Initial)
|
EXPECT_TRUE(getFirstOutstandingPacket(*conn, PacketNumberSpace::Initial)
|
||||||
->isHandshake);
|
->metadata.isHandshake);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(QuicTransportFunctionsTest, NoCryptoProbeWriteIfNoProbeCredit) {
|
TEST_F(QuicTransportFunctionsTest, NoCryptoProbeWriteIfNoProbeCredit) {
|
||||||
@@ -1702,7 +1704,7 @@ TEST_F(QuicTransportFunctionsTest, NoCryptoProbeWriteIfNoProbeCredit) {
|
|||||||
conn->transportSettings.writeConnectionDataPacketsLimit));
|
conn->transportSettings.writeConnectionDataPacketsLimit));
|
||||||
ASSERT_EQ(1, conn->outstandings.packets.size());
|
ASSERT_EQ(1, conn->outstandings.packets.size());
|
||||||
EXPECT_TRUE(getFirstOutstandingPacket(*conn, PacketNumberSpace::Initial)
|
EXPECT_TRUE(getFirstOutstandingPacket(*conn, PacketNumberSpace::Initial)
|
||||||
->isHandshake);
|
->metadata.isHandshake);
|
||||||
ASSERT_EQ(1, cryptoStream->retransmissionBuffer.size());
|
ASSERT_EQ(1, cryptoStream->retransmissionBuffer.size());
|
||||||
ASSERT_TRUE(cryptoStream->writeBuffer.empty());
|
ASSERT_TRUE(cryptoStream->writeBuffer.empty());
|
||||||
|
|
||||||
@@ -2474,7 +2476,8 @@ TEST_F(QuicTransportFunctionsTest, WriteProbingWithInplaceBuilder) {
|
|||||||
ASSERT_FALSE(streamScheduler.hasPendingData());
|
ASSERT_FALSE(streamScheduler.hasPendingData());
|
||||||
|
|
||||||
// The first packet has be a full packet
|
// The first packet has be a full packet
|
||||||
auto firstPacketSize = conn->outstandings.packets.front().encodedSize;
|
auto firstPacketSize =
|
||||||
|
conn->outstandings.packets.front().metadata.encodedSize;
|
||||||
auto outstandingPacketsCount = conn->outstandings.packets.size();
|
auto outstandingPacketsCount = conn->outstandings.packets.size();
|
||||||
ASSERT_EQ(firstPacketSize, conn->udpSendPacketLen);
|
ASSERT_EQ(firstPacketSize, conn->udpSendPacketLen);
|
||||||
EXPECT_CALL(mockSock, write(_, _))
|
EXPECT_CALL(mockSock, write(_, _))
|
||||||
|
@@ -29,7 +29,7 @@ OutstandingPacket makeDummyOutstandingPacket(
|
|||||||
const RegularQuicWritePacket& writePacket,
|
const RegularQuicWritePacket& writePacket,
|
||||||
uint64_t totalBytesSentOnConnection) {
|
uint64_t totalBytesSentOnConnection) {
|
||||||
OutstandingPacket packet(
|
OutstandingPacket packet(
|
||||||
writePacket, Clock::now(), 1000, false, totalBytesSentOnConnection);
|
writePacket, Clock::now(), 1000, false, totalBytesSentOnConnection, 0);
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -547,7 +547,8 @@ OutstandingPacket makeTestingWritePacket(
|
|||||||
PacketNum desiredPacketSeqNum,
|
PacketNum desiredPacketSeqNum,
|
||||||
size_t desiredSize,
|
size_t desiredSize,
|
||||||
uint64_t totalBytesSent,
|
uint64_t totalBytesSent,
|
||||||
TimePoint sentTime) {
|
TimePoint sentTime /* = Clock::now() */,
|
||||||
|
uint64_t inflightBytes /* = 0 */) {
|
||||||
LongHeader longHeader(
|
LongHeader longHeader(
|
||||||
LongHeader::Types::ZeroRtt,
|
LongHeader::Types::ZeroRtt,
|
||||||
getTestConnectionId(1),
|
getTestConnectionId(1),
|
||||||
@@ -556,7 +557,7 @@ 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);
|
packet, sentTime, desiredSize, false, totalBytesSent, inflightBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
CongestionController::AckEvent makeAck(
|
CongestionController::AckEvent makeAck(
|
||||||
@@ -731,10 +732,10 @@ bool matchError(
|
|||||||
CongestionController::AckEvent::AckPacket makeAckPacketFromOutstandingPacket(
|
CongestionController::AckEvent::AckPacket makeAckPacketFromOutstandingPacket(
|
||||||
OutstandingPacket outstandingPacket) {
|
OutstandingPacket outstandingPacket) {
|
||||||
return CongestionController::AckEvent::AckPacket::Builder()
|
return CongestionController::AckEvent::AckPacket::Builder()
|
||||||
.setSentTime(outstandingPacket.time)
|
.setSentTime(outstandingPacket.metadata.time)
|
||||||
.setEncodedSize(outstandingPacket.encodedSize)
|
.setEncodedSize(outstandingPacket.metadata.encodedSize)
|
||||||
.setLastAckedPacketInfo(std::move(outstandingPacket.lastAckedPacketInfo))
|
.setLastAckedPacketInfo(std::move(outstandingPacket.lastAckedPacketInfo))
|
||||||
.setTotalBytesSentThen(outstandingPacket.totalBytesSent)
|
.setTotalBytesSentThen(outstandingPacket.metadata.totalBytesSent)
|
||||||
.setAppLimited(outstandingPacket.isAppLimited)
|
.setAppLimited(outstandingPacket.isAppLimited)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
@@ -217,7 +217,8 @@ OutstandingPacket makeTestingWritePacket(
|
|||||||
PacketNum desiredPacketSeqNum,
|
PacketNum desiredPacketSeqNum,
|
||||||
size_t desiredSize,
|
size_t desiredSize,
|
||||||
uint64_t totalBytesSent,
|
uint64_t totalBytesSent,
|
||||||
TimePoint sentTime = Clock::now());
|
TimePoint sentTime = Clock::now(),
|
||||||
|
uint64_t inflightBytes = 0);
|
||||||
|
|
||||||
// TODO: The way we setup packet sent, ack, loss in test cases can use some
|
// TODO: The way we setup packet sent, ack, loss in test cases can use some
|
||||||
// major refactor.
|
// major refactor.
|
||||||
|
@@ -116,9 +116,10 @@ void BbrCongestionController::onPacketSent(const OutstandingPacket& packet) {
|
|||||||
if (!conn_.lossState.inflightBytes && isAppLimited()) {
|
if (!conn_.lossState.inflightBytes && isAppLimited()) {
|
||||||
exitingQuiescene_ = true;
|
exitingQuiescene_ = true;
|
||||||
}
|
}
|
||||||
addAndCheckOverflow(conn_.lossState.inflightBytes, packet.encodedSize);
|
addAndCheckOverflow(
|
||||||
|
conn_.lossState.inflightBytes, packet.metadata.encodedSize);
|
||||||
if (!ackAggregationStartTime_) {
|
if (!ackAggregationStartTime_) {
|
||||||
ackAggregationStartTime_ = packet.time;
|
ackAggregationStartTime_ = packet.metadata.time;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -46,7 +46,8 @@ void Copa::onRemoveBytesFromInflight(uint64_t bytes) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Copa::onPacketSent(const OutstandingPacket& packet) {
|
void Copa::onPacketSent(const OutstandingPacket& packet) {
|
||||||
addAndCheckOverflow(conn_.lossState.inflightBytes, packet.encodedSize);
|
addAndCheckOverflow(
|
||||||
|
conn_.lossState.inflightBytes, packet.metadata.encodedSize);
|
||||||
|
|
||||||
VLOG(10) << __func__ << " writable=" << getWritableBytes()
|
VLOG(10) << __func__ << " writable=" << getWritableBytes()
|
||||||
<< " cwnd=" << cwndBytes_
|
<< " cwnd=" << cwndBytes_
|
||||||
|
@@ -37,7 +37,8 @@ void NewReno::onRemoveBytesFromInflight(uint64_t bytes) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void NewReno::onPacketSent(const OutstandingPacket& packet) {
|
void NewReno::onPacketSent(const OutstandingPacket& packet) {
|
||||||
addAndCheckOverflow(conn_.lossState.inflightBytes, packet.encodedSize);
|
addAndCheckOverflow(
|
||||||
|
conn_.lossState.inflightBytes, packet.metadata.encodedSize);
|
||||||
VLOG(10) << __func__ << " writable=" << getWritableBytes()
|
VLOG(10) << __func__ << " writable=" << getWritableBytes()
|
||||||
<< " cwnd=" << cwndBytes_
|
<< " cwnd=" << cwndBytes_
|
||||||
<< " inflight=" << conn_.lossState.inflightBytes
|
<< " inflight=" << conn_.lossState.inflightBytes
|
||||||
|
@@ -92,12 +92,12 @@ void Cubic::onPersistentCongestion() {
|
|||||||
|
|
||||||
void Cubic::onPacketSent(const OutstandingPacket& packet) {
|
void Cubic::onPacketSent(const OutstandingPacket& packet) {
|
||||||
if (std::numeric_limits<uint64_t>::max() - conn_.lossState.inflightBytes <
|
if (std::numeric_limits<uint64_t>::max() - conn_.lossState.inflightBytes <
|
||||||
packet.encodedSize) {
|
packet.metadata.encodedSize) {
|
||||||
throw QuicInternalException(
|
throw QuicInternalException(
|
||||||
"Cubic: inflightBytes overflow",
|
"Cubic: inflightBytes overflow",
|
||||||
LocalErrorCode::INFLIGHT_BYTES_OVERFLOW);
|
LocalErrorCode::INFLIGHT_BYTES_OVERFLOW);
|
||||||
}
|
}
|
||||||
conn_.lossState.inflightBytes += packet.encodedSize;
|
conn_.lossState.inflightBytes += packet.metadata.encodedSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cubic::onPacketLoss(const LossEvent& loss) {
|
void Cubic::onPacketLoss(const LossEvent& loss) {
|
||||||
|
@@ -70,7 +70,7 @@ TEST_F(BbrBandwidthSamplerTest, RateCalculation) {
|
|||||||
lastAckedPacketAckTime,
|
lastAckedPacketAckTime,
|
||||||
0,
|
0,
|
||||||
0);
|
0);
|
||||||
packet.time = ackTime - 50us;
|
packet.metadata.time = ackTime - 50us;
|
||||||
ackEvent.ackedPackets.push_back(
|
ackEvent.ackedPackets.push_back(
|
||||||
makeAckPacketFromOutstandingPacket(std::move(packet)));
|
makeAckPacketFromOutstandingPacket(std::move(packet)));
|
||||||
}
|
}
|
||||||
@@ -99,7 +99,7 @@ TEST_F(BbrBandwidthSamplerTest, RateCalculationWithAdjustedAckTime) {
|
|||||||
adjustedAckedPacketAckTime,
|
adjustedAckedPacketAckTime,
|
||||||
0,
|
0,
|
||||||
0);
|
0);
|
||||||
packet.time = ackTime - 50us;
|
packet.metadata.time = ackTime - 50us;
|
||||||
ackEvent.ackedPackets.push_back(
|
ackEvent.ackedPackets.push_back(
|
||||||
makeAckPacketFromOutstandingPacket(std::move(packet)));
|
makeAckPacketFromOutstandingPacket(std::move(packet)));
|
||||||
}
|
}
|
||||||
@@ -126,7 +126,7 @@ TEST_F(BbrBandwidthSamplerTest, SampleExpiration) {
|
|||||||
lastAckedPacketAckTime,
|
lastAckedPacketAckTime,
|
||||||
1000,
|
1000,
|
||||||
1000);
|
1000);
|
||||||
packet.time = ackTime - 50us;
|
packet.metadata.time = ackTime - 50us;
|
||||||
ackEvent.ackedPackets.push_back(makeAckPacketFromOutstandingPacket(packet));
|
ackEvent.ackedPackets.push_back(makeAckPacketFromOutstandingPacket(packet));
|
||||||
sampler.onPacketAcked(ackEvent, 0);
|
sampler.onPacketAcked(ackEvent, 0);
|
||||||
auto firstBandwidthSample = sampler.getBandwidth();
|
auto firstBandwidthSample = sampler.getBandwidth();
|
||||||
@@ -135,11 +135,11 @@ TEST_F(BbrBandwidthSamplerTest, SampleExpiration) {
|
|||||||
conn_.lossState.totalBytesAcked = 2000;
|
conn_.lossState.totalBytesAcked = 2000;
|
||||||
auto packet2 = makeTestingWritePacket(pn, 500, 2500);
|
auto packet2 = makeTestingWritePacket(pn, 500, 2500);
|
||||||
packet2.lastAckedPacketInfo.emplace(
|
packet2.lastAckedPacketInfo.emplace(
|
||||||
packet.time, ackTime, ackTime, 2000, 1000);
|
packet.metadata.time, ackTime, ackTime, 2000, 1000);
|
||||||
auto ackTime2 = ackTime + 150us;
|
auto ackTime2 = ackTime + 150us;
|
||||||
CongestionController::AckEvent ackEvent2;
|
CongestionController::AckEvent ackEvent2;
|
||||||
ackEvent2.ackTime = ackTime2;
|
ackEvent2.ackTime = ackTime2;
|
||||||
packet2.time = ackTime + 110us;
|
packet2.metadata.time = ackTime + 110us;
|
||||||
ackEvent2.ackedPackets.push_back(makeAckPacketFromOutstandingPacket(packet2));
|
ackEvent2.ackedPackets.push_back(makeAckPacketFromOutstandingPacket(packet2));
|
||||||
sampler.onPacketAcked(ackEvent2, kBandwidthWindowLength / 4 + 1);
|
sampler.onPacketAcked(ackEvent2, kBandwidthWindowLength / 4 + 1);
|
||||||
auto secondBandwidthSample = sampler.getBandwidth();
|
auto secondBandwidthSample = sampler.getBandwidth();
|
||||||
@@ -149,11 +149,11 @@ TEST_F(BbrBandwidthSamplerTest, SampleExpiration) {
|
|||||||
conn_.lossState.totalBytesAcked = 2500;
|
conn_.lossState.totalBytesAcked = 2500;
|
||||||
auto packet3 = makeTestingWritePacket(pn, 200, 2700);
|
auto packet3 = makeTestingWritePacket(pn, 200, 2700);
|
||||||
packet3.lastAckedPacketInfo.emplace(
|
packet3.lastAckedPacketInfo.emplace(
|
||||||
packet2.time, ackTime2, ackTime2, 2500, 2000);
|
packet2.metadata.time, ackTime2, ackTime2, 2500, 2000);
|
||||||
auto ackTime3 = ackTime + 250us;
|
auto ackTime3 = ackTime + 250us;
|
||||||
CongestionController::AckEvent ackEvent3;
|
CongestionController::AckEvent ackEvent3;
|
||||||
ackEvent3.ackTime = ackTime3;
|
ackEvent3.ackTime = ackTime3;
|
||||||
packet3.time = ackTime + 210us;
|
packet3.metadata.time = ackTime + 210us;
|
||||||
ackEvent3.ackedPackets.push_back(makeAckPacketFromOutstandingPacket(packet3));
|
ackEvent3.ackedPackets.push_back(makeAckPacketFromOutstandingPacket(packet3));
|
||||||
sampler.onPacketAcked(ackEvent3, kBandwidthWindowLength / 2 + 1);
|
sampler.onPacketAcked(ackEvent3, kBandwidthWindowLength / 2 + 1);
|
||||||
EXPECT_EQ(firstBandwidthSample, sampler.getBandwidth());
|
EXPECT_EQ(firstBandwidthSample, sampler.getBandwidth());
|
||||||
@@ -162,11 +162,11 @@ TEST_F(BbrBandwidthSamplerTest, SampleExpiration) {
|
|||||||
conn_.lossState.totalBytesAcked = 2700;
|
conn_.lossState.totalBytesAcked = 2700;
|
||||||
auto packet4 = makeTestingWritePacket(pn, 100, 2800);
|
auto packet4 = makeTestingWritePacket(pn, 100, 2800);
|
||||||
packet4.lastAckedPacketInfo.emplace(
|
packet4.lastAckedPacketInfo.emplace(
|
||||||
packet3.time, ackTime3, ackTime3, 2700, 2500);
|
packet3.metadata.time, ackTime3, ackTime3, 2700, 2500);
|
||||||
auto ackTime4 = ackTime + 350us;
|
auto ackTime4 = ackTime + 350us;
|
||||||
CongestionController::AckEvent ackEvent4;
|
CongestionController::AckEvent ackEvent4;
|
||||||
ackEvent4.ackTime = ackTime4;
|
ackEvent4.ackTime = ackTime4;
|
||||||
packet4.time = ackTime + 310us;
|
packet4.metadata.time = ackTime + 310us;
|
||||||
ackEvent4.ackedPackets.push_back(makeAckPacketFromOutstandingPacket(packet4));
|
ackEvent4.ackedPackets.push_back(makeAckPacketFromOutstandingPacket(packet4));
|
||||||
sampler.onPacketAcked(ackEvent4, kBandwidthWindowLength + 1);
|
sampler.onPacketAcked(ackEvent4, kBandwidthWindowLength + 1);
|
||||||
// The bandwidth we got from packet1 has expired. Packet2 should have
|
// The bandwidth we got from packet1 has expired. Packet2 should have
|
||||||
@@ -188,7 +188,7 @@ TEST_F(BbrBandwidthSamplerTest, AppLimited) {
|
|||||||
ackEvent.largestAckedPacket = ++conn.lossState.largestSent.value();
|
ackEvent.largestAckedPacket = ++conn.lossState.largestSent.value();
|
||||||
auto packet =
|
auto packet =
|
||||||
makeTestingWritePacket(*ackEvent.largestAckedPacket, 1000, 1000);
|
makeTestingWritePacket(*ackEvent.largestAckedPacket, 1000, 1000);
|
||||||
ackEvent.largestAckedPacketSentTime = packet.time;
|
ackEvent.largestAckedPacketSentTime = packet.metadata.time;
|
||||||
ackEvent.ackedPackets.push_back(
|
ackEvent.ackedPackets.push_back(
|
||||||
makeAckPacketFromOutstandingPacket(std::move(packet)));
|
makeAckPacketFromOutstandingPacket(std::move(packet)));
|
||||||
sampler.onPacketAcked(ackEvent, 0);
|
sampler.onPacketAcked(ackEvent, 0);
|
||||||
@@ -224,7 +224,7 @@ TEST_F(BbrBandwidthSamplerTest, AppLimitedOutstandingPacket) {
|
|||||||
lastAckedPacketAckTime,
|
lastAckedPacketAckTime,
|
||||||
0,
|
0,
|
||||||
0);
|
0);
|
||||||
packet.time = ackTime - 50us;
|
packet.metadata.time = ackTime - 50us;
|
||||||
ackEvent.ackedPackets.push_back(makeAckPacketFromOutstandingPacket(packet));
|
ackEvent.ackedPackets.push_back(makeAckPacketFromOutstandingPacket(packet));
|
||||||
// AppLimited packet, but sample is larger than current best
|
// AppLimited packet, but sample is larger than current best
|
||||||
sampler.onPacketAcked(ackEvent, 0);
|
sampler.onPacketAcked(ackEvent, 0);
|
||||||
@@ -234,8 +234,9 @@ TEST_F(BbrBandwidthSamplerTest, AppLimitedOutstandingPacket) {
|
|||||||
pn++;
|
pn++;
|
||||||
auto packet1 = makeTestingWritePacket(pn, 1000, 1000 + 1000 * pn);
|
auto packet1 = makeTestingWritePacket(pn, 1000, 1000 + 1000 * pn);
|
||||||
packet1.isAppLimited = true;
|
packet1.isAppLimited = true;
|
||||||
packet1.lastAckedPacketInfo.emplace(packet.time, ackTime, ackTime, 1000, 0);
|
packet1.lastAckedPacketInfo.emplace(
|
||||||
packet1.time = ackTime + 500us;
|
packet.metadata.time, ackTime, ackTime, 1000, 0);
|
||||||
|
packet1.metadata.time = ackTime + 500us;
|
||||||
CongestionController::AckEvent ackEvent1;
|
CongestionController::AckEvent ackEvent1;
|
||||||
ackEvent1.ackedBytes = 1000;
|
ackEvent1.ackedBytes = 1000;
|
||||||
ackEvent1.ackTime = ackTime + 2000us;
|
ackEvent1.ackTime = ackTime + 2000us;
|
||||||
|
@@ -141,7 +141,7 @@ TEST_F(BbrTest, StartupCwnd) {
|
|||||||
// Target cwnd will be 100 * 5000 * 2.885 = 1442500, but you haven't finished
|
// Target cwnd will be 100 * 5000 * 2.885 = 1442500, but you haven't finished
|
||||||
// STARTUP, too bad kiddo, you only grow a little today
|
// STARTUP, too bad kiddo, you only grow a little today
|
||||||
bbr.onPacketAckOrLoss(
|
bbr.onPacketAckOrLoss(
|
||||||
makeAck(0, 3000, Clock::now(), packet.time), folly::none);
|
makeAck(0, 3000, Clock::now(), packet.metadata.time), folly::none);
|
||||||
EXPECT_EQ(startingCwnd + 3000, bbr.getCongestionWindow());
|
EXPECT_EQ(startingCwnd + 3000, bbr.getCongestionWindow());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,7 +167,7 @@ TEST_F(BbrTest, StartupCwndImplicit) {
|
|||||||
Bandwidth(5000ULL * 1000 * 1000, std::chrono::microseconds(1))));
|
Bandwidth(5000ULL * 1000 * 1000, std::chrono::microseconds(1))));
|
||||||
// Target cwnd will be 100 * 5000 * 2.885 = 1442500, but you haven't finished
|
// Target cwnd will be 100 * 5000 * 2.885 = 1442500, but you haven't finished
|
||||||
// STARTUP, too bad kiddo, you only grow a little today
|
// STARTUP, too bad kiddo, you only grow a little today
|
||||||
auto ack = makeAck(0, 3000, Clock::now(), packet.time);
|
auto ack = makeAck(0, 3000, Clock::now(), packet.metadata.time);
|
||||||
ack.implicit = true;
|
ack.implicit = true;
|
||||||
bbr.onPacketAckOrLoss(ack, folly::none);
|
bbr.onPacketAckOrLoss(ack, folly::none);
|
||||||
EXPECT_EQ(startingCwnd + 3000, bbr.getCongestionWindow());
|
EXPECT_EQ(startingCwnd + 3000, bbr.getCongestionWindow());
|
||||||
@@ -197,7 +197,8 @@ TEST_F(BbrTest, LeaveStartup) {
|
|||||||
.WillRepeatedly(Return(
|
.WillRepeatedly(Return(
|
||||||
mockedBandwidth * (growFast ? kExpectedStartupGrowth : 1.0)));
|
mockedBandwidth * (growFast ? kExpectedStartupGrowth : 1.0)));
|
||||||
bbr.onPacketAckOrLoss(
|
bbr.onPacketAckOrLoss(
|
||||||
makeAck(currentLatest, 1000, Clock::now(), packet.time), folly::none);
|
makeAck(currentLatest, 1000, Clock::now(), packet.metadata.time),
|
||||||
|
folly::none);
|
||||||
conn.lossState.totalBytesAcked += 1000;
|
conn.lossState.totalBytesAcked += 1000;
|
||||||
if (growFast) {
|
if (growFast) {
|
||||||
mockedBandwidth = mockedBandwidth * kExpectedStartupGrowth;
|
mockedBandwidth = mockedBandwidth * kExpectedStartupGrowth;
|
||||||
@@ -263,7 +264,8 @@ TEST_F(BbrTest, ProbeRtt) {
|
|||||||
conn.udpSendPacketLen,
|
conn.udpSendPacketLen,
|
||||||
totalSent + conn.udpSendPacketLen);
|
totalSent + conn.udpSendPacketLen);
|
||||||
bbr.onPacketSent(packet);
|
bbr.onPacketSent(packet);
|
||||||
inflightPackets.push_back(std::make_pair(currentLatest, packet.time));
|
inflightPackets.push_back(
|
||||||
|
std::make_pair(currentLatest, packet.metadata.time));
|
||||||
inflightBytes += conn.udpSendPacketLen;
|
inflightBytes += conn.udpSendPacketLen;
|
||||||
currentLatest++;
|
currentLatest++;
|
||||||
totalSent += conn.udpSendPacketLen;
|
totalSent += conn.udpSendPacketLen;
|
||||||
@@ -431,7 +433,8 @@ TEST_F(BbrTest, AckAggregation) {
|
|||||||
.WillRepeatedly(Return(
|
.WillRepeatedly(Return(
|
||||||
mockedBandwidth * (growFast ? kExpectedStartupGrowth : 1.0)));
|
mockedBandwidth * (growFast ? kExpectedStartupGrowth : 1.0)));
|
||||||
bbr.onPacketAckOrLoss(
|
bbr.onPacketAckOrLoss(
|
||||||
makeAck(currentLatest, 1000, Clock::now(), packet.time), folly::none);
|
makeAck(currentLatest, 1000, Clock::now(), packet.metadata.time),
|
||||||
|
folly::none);
|
||||||
conn.lossState.totalBytesAcked += 1000;
|
conn.lossState.totalBytesAcked += 1000;
|
||||||
if (growFast) {
|
if (growFast) {
|
||||||
mockedBandwidth = mockedBandwidth * kExpectedStartupGrowth;
|
mockedBandwidth = mockedBandwidth * kExpectedStartupGrowth;
|
||||||
@@ -468,7 +471,8 @@ TEST_F(BbrTest, AckAggregation) {
|
|||||||
conn.lossState.largestSent.value(), 1000, 1000 + totalSent);
|
conn.lossState.largestSent.value(), 1000, 1000 + totalSent);
|
||||||
bbr.onPacketSent(packet);
|
bbr.onPacketSent(packet);
|
||||||
totalSent += 1000;
|
totalSent += 1000;
|
||||||
auto ackEvent = makeAck(currentLatest, 1000, Clock::now(), packet.time);
|
auto ackEvent =
|
||||||
|
makeAck(currentLatest, 1000, Clock::now(), packet.metadata.time);
|
||||||
ackEvent.ackTime = Clock::now();
|
ackEvent.ackTime = Clock::now();
|
||||||
// use a real large bandwidth to clear accumulated ack aggregation during
|
// use a real large bandwidth to clear accumulated ack aggregation during
|
||||||
// startup
|
// startup
|
||||||
@@ -494,7 +498,10 @@ TEST_F(BbrTest, AckAggregation) {
|
|||||||
bbr.onPacketSent(packet1);
|
bbr.onPacketSent(packet1);
|
||||||
totalSent += (currentMaxAckHeight * 2 + 100);
|
totalSent += (currentMaxAckHeight * 2 + 100);
|
||||||
auto ackEvent2 = makeAck(
|
auto ackEvent2 = makeAck(
|
||||||
currentLatest, currentMaxAckHeight * 2 + 100, Clock::now(), packet1.time);
|
currentLatest,
|
||||||
|
currentMaxAckHeight * 2 + 100,
|
||||||
|
Clock::now(),
|
||||||
|
packet1.metadata.time);
|
||||||
// This will make the expected ack arrival rate very low:
|
// This will make the expected ack arrival rate very low:
|
||||||
ackEvent2.ackTime = ackEvent.ackTime + 1us;
|
ackEvent2.ackTime = ackEvent.ackTime + 1us;
|
||||||
bbr.onPacketAckOrLoss(ackEvent2, folly::none);
|
bbr.onPacketAckOrLoss(ackEvent2, folly::none);
|
||||||
@@ -565,7 +572,7 @@ TEST_F(BbrTest, ExtendMinRttExpiration) {
|
|||||||
conn.lossState.largestSent.value_or(0),
|
conn.lossState.largestSent.value_or(0),
|
||||||
1000,
|
1000,
|
||||||
Clock::now(),
|
Clock::now(),
|
||||||
packet.time),
|
packet.metadata.time),
|
||||||
folly::none);
|
folly::none);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -9,14 +9,19 @@ endif()
|
|||||||
|
|
||||||
quic_add_test(TARGET CongestionControllerTests
|
quic_add_test(TARGET CongestionControllerTests
|
||||||
SOURCES
|
SOURCES
|
||||||
|
BandwidthTest.cpp
|
||||||
|
BbrBandwidthSamplerTest.cpp
|
||||||
|
BbrRttSamplerTest.cpp
|
||||||
|
BbrTest.cpp
|
||||||
CongestionControlFunctionsTest.cpp
|
CongestionControlFunctionsTest.cpp
|
||||||
|
CopaTest.cpp
|
||||||
CubicHystartTest.cpp
|
CubicHystartTest.cpp
|
||||||
CubicRecoveryTest.cpp
|
CubicRecoveryTest.cpp
|
||||||
CubicStateTest.cpp
|
CubicStateTest.cpp
|
||||||
CubicSteadyTest.cpp
|
CubicSteadyTest.cpp
|
||||||
CubicTest.cpp
|
CubicTest.cpp
|
||||||
NewRenoTest.cpp
|
NewRenoTest.cpp
|
||||||
CopaTest.cpp
|
PacerTest.cpp
|
||||||
DEPENDS
|
DEPENDS
|
||||||
Folly::folly
|
Folly::folly
|
||||||
mvfst_cc_algo
|
mvfst_cc_algo
|
||||||
|
@@ -31,20 +31,23 @@ 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));
|
std::move(packet), Clock::now(), 10, false, totalSentBytes, 0));
|
||||||
loss.lostBytes = packetData.second;
|
loss.lostBytes = packetData.second;
|
||||||
}
|
}
|
||||||
loss.lostPackets = lostPackets.size();
|
loss.lostPackets = lostPackets.size();
|
||||||
return loss;
|
return loss;
|
||||||
}
|
}
|
||||||
|
|
||||||
OutstandingPacket
|
OutstandingPacket createPacket(
|
||||||
createPacket(PacketNum packetNum, uint32_t size, uint64_t totalSent) {
|
PacketNum packetNum,
|
||||||
|
uint32_t size,
|
||||||
|
uint64_t totalSent,
|
||||||
|
uint64_t inflight = 0) {
|
||||||
auto connId = getTestConnectionId();
|
auto connId = getTestConnectionId();
|
||||||
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);
|
std::move(packet), Clock::now(), size, false, totalSent, inflight);
|
||||||
}
|
}
|
||||||
|
|
||||||
CongestionController::AckEvent createAckEvent(
|
CongestionController::AckEvent createAckEvent(
|
||||||
|
@@ -30,7 +30,7 @@ TEST_F(CubicHystartTest, SendAndAck) {
|
|||||||
auto packet = makeTestingWritePacket(0, 1000, 1000);
|
auto packet = makeTestingWritePacket(0, 1000, 1000);
|
||||||
cubic.onPacketSent(packet);
|
cubic.onPacketSent(packet);
|
||||||
cubic.onPacketAckOrLoss(
|
cubic.onPacketAckOrLoss(
|
||||||
makeAck(0, 1000, Clock::now(), packet.time), folly::none);
|
makeAck(0, 1000, Clock::now(), packet.metadata.time), folly::none);
|
||||||
|
|
||||||
EXPECT_EQ(initCwnd + 1000, cubic.getWritableBytes());
|
EXPECT_EQ(initCwnd + 1000, cubic.getWritableBytes());
|
||||||
EXPECT_EQ(CubicStates::Hystart, cubic.state());
|
EXPECT_EQ(CubicStates::Hystart, cubic.state());
|
||||||
@@ -47,7 +47,7 @@ TEST_F(CubicHystartTest, CwndLargerThanSSThresh) {
|
|||||||
auto packet = makeTestingWritePacket(0, 1000, 1000);
|
auto packet = makeTestingWritePacket(0, 1000, 1000);
|
||||||
cubic.onPacketSent(packet);
|
cubic.onPacketSent(packet);
|
||||||
cubic.onPacketAckOrLoss(
|
cubic.onPacketAckOrLoss(
|
||||||
makeAck(0, 1000, Clock::now(), packet.time), folly::none);
|
makeAck(0, 1000, Clock::now(), packet.metadata.time), folly::none);
|
||||||
EXPECT_EQ(initCwnd + 1000, cubic.getWritableBytes());
|
EXPECT_EQ(initCwnd + 1000, cubic.getWritableBytes());
|
||||||
EXPECT_EQ(CubicStates::Steady, cubic.state());
|
EXPECT_EQ(CubicStates::Steady, cubic.state());
|
||||||
}
|
}
|
||||||
@@ -67,7 +67,7 @@ TEST_F(CubicHystartTest, NoDelayIncrease) {
|
|||||||
auto packet = makeTestingWritePacket(0, 1000, 1000, realNow);
|
auto packet = makeTestingWritePacket(0, 1000, 1000, realNow);
|
||||||
cubic.onPacketSent(packet);
|
cubic.onPacketSent(packet);
|
||||||
cubic.onPacketAckOrLoss(
|
cubic.onPacketAckOrLoss(
|
||||||
makeAck(0, 1000, realNow + 2us, packet.time), folly::none);
|
makeAck(0, 1000, realNow + 2us, packet.metadata.time), folly::none);
|
||||||
EXPECT_EQ(initCwnd + 1000, cubic.getWritableBytes());
|
EXPECT_EQ(initCwnd + 1000, cubic.getWritableBytes());
|
||||||
EXPECT_EQ(CubicStates::Hystart, cubic.state());
|
EXPECT_EQ(CubicStates::Hystart, cubic.state());
|
||||||
}
|
}
|
||||||
@@ -92,7 +92,10 @@ TEST_F(CubicHystartTest, AckTrain) {
|
|||||||
// Packet 0 is acked:
|
// Packet 0 is acked:
|
||||||
cubic.onPacketAckOrLoss(
|
cubic.onPacketAckOrLoss(
|
||||||
makeAck(
|
makeAck(
|
||||||
0, kLowSsthreshInMss * conn.udpSendPacketLen, realNow, packet0.time),
|
0,
|
||||||
|
kLowSsthreshInMss * conn.udpSendPacketLen,
|
||||||
|
realNow,
|
||||||
|
packet0.metadata.time),
|
||||||
folly::none);
|
folly::none);
|
||||||
// Packet 1 is acked:
|
// Packet 1 is acked:
|
||||||
cubic.onPacketAckOrLoss(
|
cubic.onPacketAckOrLoss(
|
||||||
@@ -100,7 +103,7 @@ TEST_F(CubicHystartTest, AckTrain) {
|
|||||||
1,
|
1,
|
||||||
kLowSsthreshInMss * conn.udpSendPacketLen,
|
kLowSsthreshInMss * conn.udpSendPacketLen,
|
||||||
realNow + 2us,
|
realNow + 2us,
|
||||||
packet1.time),
|
packet1.metadata.time),
|
||||||
folly::none);
|
folly::none);
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
initCwnd + kLowSsthreshInMss * conn.udpSendPacketLen * 2,
|
initCwnd + kLowSsthreshInMss * conn.udpSendPacketLen * 2,
|
||||||
@@ -123,7 +126,7 @@ TEST_F(CubicHystartTest, NoAckTrainNoDelayIncrease) {
|
|||||||
auto packet = makeTestingWritePacket(0, 1000, 1000, realNow);
|
auto packet = makeTestingWritePacket(0, 1000, 1000, realNow);
|
||||||
cubic.onPacketSent(packet);
|
cubic.onPacketSent(packet);
|
||||||
cubic.onPacketAckOrLoss(
|
cubic.onPacketAckOrLoss(
|
||||||
makeAck(0, 1000, realNow + kAckCountingGap + 2us, packet.time),
|
makeAck(0, 1000, realNow + kAckCountingGap + 2us, packet.metadata.time),
|
||||||
folly::none);
|
folly::none);
|
||||||
EXPECT_EQ(initCwnd + 1000, cubic.getWritableBytes());
|
EXPECT_EQ(initCwnd + 1000, cubic.getWritableBytes());
|
||||||
EXPECT_EQ(CubicStates::Hystart, cubic.state());
|
EXPECT_EQ(CubicStates::Hystart, cubic.state());
|
||||||
@@ -142,7 +145,8 @@ TEST_F(CubicHystartTest, DelayIncrease) {
|
|||||||
makeTestingWritePacket(packetNum, fullSize, fullSize + totalSent);
|
makeTestingWritePacket(packetNum, fullSize, fullSize + totalSent);
|
||||||
cubic.onPacketSent(packet);
|
cubic.onPacketSent(packet);
|
||||||
cubic.onPacketAckOrLoss(
|
cubic.onPacketAckOrLoss(
|
||||||
makeAck(packetNum++, fullSize, Clock::now(), packet.time), folly::none);
|
makeAck(packetNum++, fullSize, Clock::now(), packet.metadata.time),
|
||||||
|
folly::none);
|
||||||
totalSent += fullSize;
|
totalSent += fullSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,10 +174,12 @@ TEST_F(CubicHystartTest, DelayIncrease) {
|
|||||||
auto ackTimeIncrease = 2us;
|
auto ackTimeIncrease = 2us;
|
||||||
ackTime += ackTimeIncrease;
|
ackTime += ackTimeIncrease;
|
||||||
cubic.onPacketAckOrLoss(
|
cubic.onPacketAckOrLoss(
|
||||||
makeAck(firstPacketNum, 1000, ackTime, packet0.time), folly::none);
|
makeAck(firstPacketNum, 1000, ackTime, packet0.metadata.time),
|
||||||
|
folly::none);
|
||||||
ackTime += ackTimeIncrease;
|
ackTime += ackTimeIncrease;
|
||||||
cubic.onPacketAckOrLoss(
|
cubic.onPacketAckOrLoss(
|
||||||
makeAck(secondPacketNum, 1000, ackTime, packet1.time), folly::none);
|
makeAck(secondPacketNum, 1000, ackTime, packet1.metadata.time),
|
||||||
|
folly::none);
|
||||||
auto estimatedRttEndTarget = Clock::now();
|
auto estimatedRttEndTarget = Clock::now();
|
||||||
|
|
||||||
auto packet2 = makeTestingWritePacket(
|
auto packet2 = makeTestingWritePacket(
|
||||||
@@ -182,9 +188,9 @@ TEST_F(CubicHystartTest, DelayIncrease) {
|
|||||||
conn.lossState.largestSent = packetNum;
|
conn.lossState.largestSent = packetNum;
|
||||||
cubic.onPacketSent(packet2);
|
cubic.onPacketSent(packet2);
|
||||||
// This will end current RTT round and start a new one next time Ack happens:
|
// This will end current RTT round and start a new one next time Ack happens:
|
||||||
ackTime = packet2.time + ackTimeIncrease;
|
ackTime = packet2.metadata.time + ackTimeIncrease;
|
||||||
cubic.onPacketAckOrLoss(
|
cubic.onPacketAckOrLoss(
|
||||||
makeAck(packetNum, 1000, ackTime, packet2.time), folly::none);
|
makeAck(packetNum, 1000, ackTime, packet2.metadata.time), folly::none);
|
||||||
packetNum++;
|
packetNum++;
|
||||||
auto cwndEndRound = cubic.getWritableBytes();
|
auto cwndEndRound = cubic.getWritableBytes();
|
||||||
|
|
||||||
@@ -199,7 +205,8 @@ TEST_F(CubicHystartTest, DelayIncrease) {
|
|||||||
cubic.onPacketSent(packet);
|
cubic.onPacketSent(packet);
|
||||||
totalSent += 1000;
|
totalSent += 1000;
|
||||||
ackTime += ackTimeIncrease;
|
ackTime += ackTimeIncrease;
|
||||||
moreAcks.push_back(makeAck(1 + packetNum, 1000, ackTime, packet.time));
|
moreAcks.push_back(
|
||||||
|
makeAck(1 + packetNum, 1000, ackTime, packet.metadata.time));
|
||||||
packetNum++;
|
packetNum++;
|
||||||
}
|
}
|
||||||
for (auto& ack : moreAcks) {
|
for (auto& ack : moreAcks) {
|
||||||
@@ -214,7 +221,7 @@ TEST_F(CubicHystartTest, DelayIncrease) {
|
|||||||
totalSent += 1000;
|
totalSent += 1000;
|
||||||
ackTime += ackTimeIncrease;
|
ackTime += ackTimeIncrease;
|
||||||
cubic.onPacketAckOrLoss(
|
cubic.onPacketAckOrLoss(
|
||||||
makeAck(packetNum, 1000, ackTime, packetEnd.time), folly::none);
|
makeAck(packetNum, 1000, ackTime, packetEnd.metadata.time), folly::none);
|
||||||
|
|
||||||
EXPECT_EQ(cwndEndRound + 1000 * kAckSampling, cubic.getWritableBytes());
|
EXPECT_EQ(cwndEndRound + 1000 * kAckSampling, cubic.getWritableBytes());
|
||||||
EXPECT_EQ(CubicStates::Steady, cubic.state());
|
EXPECT_EQ(CubicStates::Steady, cubic.state());
|
||||||
@@ -243,16 +250,19 @@ TEST_F(CubicHystartTest, DelayIncreaseCwndTooSmall) {
|
|||||||
auto ackTime = realNow;
|
auto ackTime = realNow;
|
||||||
auto ackTimeIncrease = 2us;
|
auto ackTimeIncrease = 2us;
|
||||||
ackTime += ackTimeIncrease;
|
ackTime += ackTimeIncrease;
|
||||||
cubic.onPacketAckOrLoss(makeAck(0, 1, ackTime, packet0.time), folly::none);
|
cubic.onPacketAckOrLoss(
|
||||||
|
makeAck(0, 1, ackTime, packet0.metadata.time), folly::none);
|
||||||
ackTime += ackTimeIncrease;
|
ackTime += ackTimeIncrease;
|
||||||
cubic.onPacketAckOrLoss(makeAck(1, 1, ackTime, packet1.time), folly::none);
|
cubic.onPacketAckOrLoss(
|
||||||
|
makeAck(1, 1, ackTime, packet1.metadata.time), folly::none);
|
||||||
|
|
||||||
auto packet2 = makeTestingWritePacket(2, 10, 10 + totalSent, realNow);
|
auto packet2 = makeTestingWritePacket(2, 10, 10 + totalSent, realNow);
|
||||||
conn.lossState.largestSent = 2;
|
conn.lossState.largestSent = 2;
|
||||||
cubic.onPacketSent(packet2);
|
cubic.onPacketSent(packet2);
|
||||||
totalSent += 10;
|
totalSent += 10;
|
||||||
ackTime += ackTimeIncrease;
|
ackTime += ackTimeIncrease;
|
||||||
cubic.onPacketAckOrLoss(makeAck(2, 1, ackTime, packet2.time), folly::none);
|
cubic.onPacketAckOrLoss(
|
||||||
|
makeAck(2, 1, ackTime, packet2.metadata.time), folly::none);
|
||||||
auto cwndEndRound = cubic.getWritableBytes();
|
auto cwndEndRound = cubic.getWritableBytes();
|
||||||
|
|
||||||
// New RTT round, give currSampledRtt a value larger than previous RTT:
|
// New RTT round, give currSampledRtt a value larger than previous RTT:
|
||||||
@@ -263,7 +273,7 @@ TEST_F(CubicHystartTest, DelayIncreaseCwndTooSmall) {
|
|||||||
conn.lossState.largestSent = i + 3;
|
conn.lossState.largestSent = i + 3;
|
||||||
auto packet = makeTestingWritePacket(i + 3, 1, 1 + totalSent, realNow);
|
auto packet = makeTestingWritePacket(i + 3, 1, 1 + totalSent, realNow);
|
||||||
ackTime += ackTimeIncrease;
|
ackTime += ackTimeIncrease;
|
||||||
moreAcks.push_back(makeAck(i + 3, 1, ackTime, packet.time));
|
moreAcks.push_back(makeAck(i + 3, 1, ackTime, packet.metadata.time));
|
||||||
cubic.onPacketSent(packet);
|
cubic.onPacketSent(packet);
|
||||||
totalSent += 1;
|
totalSent += 1;
|
||||||
}
|
}
|
||||||
@@ -279,7 +289,7 @@ TEST_F(CubicHystartTest, DelayIncreaseCwndTooSmall) {
|
|||||||
totalSent += 1;
|
totalSent += 1;
|
||||||
ackTime += ackTimeIncrease;
|
ackTime += ackTimeIncrease;
|
||||||
cubic.onPacketAckOrLoss(
|
cubic.onPacketAckOrLoss(
|
||||||
makeAck(kAckSampling, 1, ackTime, packetEnd.time), folly::none);
|
makeAck(kAckSampling, 1, ackTime, packetEnd.metadata.time), folly::none);
|
||||||
auto expectedCwnd = cwndEndRound + 1 * kAckSampling;
|
auto expectedCwnd = cwndEndRound + 1 * kAckSampling;
|
||||||
// Cwnd < kLowSsthresh, won't exit Hystart state:
|
// Cwnd < kLowSsthresh, won't exit Hystart state:
|
||||||
ASSERT_LT(expectedCwnd, kLowSsthreshInMss * conn.udpSendPacketLen);
|
ASSERT_LT(expectedCwnd, kLowSsthreshInMss * conn.udpSendPacketLen);
|
||||||
|
@@ -57,7 +57,7 @@ TEST_F(CubicRecoveryTest, LossBeforeRecovery) {
|
|||||||
cubic.onPacketSent(packet);
|
cubic.onPacketSent(packet);
|
||||||
totalSent += 1000;
|
totalSent += 1000;
|
||||||
cubic.onPacketAckOrLoss(
|
cubic.onPacketAckOrLoss(
|
||||||
makeAck(0, 1000, Clock::now(), packet.time), folly::none);
|
makeAck(0, 1000, Clock::now(), packet.metadata.time), folly::none);
|
||||||
EXPECT_EQ(CubicStates::Hystart, cubic.state());
|
EXPECT_EQ(CubicStates::Hystart, cubic.state());
|
||||||
|
|
||||||
// Send three packets, lose second immediately.
|
// Send three packets, lose second immediately.
|
||||||
@@ -83,9 +83,9 @@ TEST_F(CubicRecoveryTest, LossBeforeRecovery) {
|
|||||||
totalSent += 1000;
|
totalSent += 1000;
|
||||||
conn.lossState.largestSent = 4;
|
conn.lossState.largestSent = 4;
|
||||||
cubic.onPacketAckOrLoss(
|
cubic.onPacketAckOrLoss(
|
||||||
makeAck(3, 1000, Clock::now(), packet3.time), folly::none);
|
makeAck(3, 1000, Clock::now(), packet3.metadata.time), folly::none);
|
||||||
cubic.onPacketAckOrLoss(
|
cubic.onPacketAckOrLoss(
|
||||||
makeAck(4, 1000, Clock::now(), packet4.time), folly::none);
|
makeAck(4, 1000, Clock::now(), packet4.metadata.time), folly::none);
|
||||||
auto cwndAfterRecovery = cubic.getCongestionWindow();
|
auto cwndAfterRecovery = cubic.getCongestionWindow();
|
||||||
EXPECT_EQ(CubicStates::Steady, cubic.state());
|
EXPECT_EQ(CubicStates::Steady, cubic.state());
|
||||||
|
|
||||||
@@ -105,7 +105,7 @@ TEST_F(CubicRecoveryTest, LossAfterRecovery) {
|
|||||||
auto packet = makeTestingWritePacket(0, 1000, 1000);
|
auto packet = makeTestingWritePacket(0, 1000, 1000);
|
||||||
cubic.onPacketSent(packet);
|
cubic.onPacketSent(packet);
|
||||||
cubic.onPacketAckOrLoss(
|
cubic.onPacketAckOrLoss(
|
||||||
makeAck(0, 1000, Clock::now(), packet.time), folly::none);
|
makeAck(0, 1000, Clock::now(), packet.metadata.time), folly::none);
|
||||||
// Lose one packet.
|
// Lose one packet.
|
||||||
auto packet1 = makeTestingWritePacket(1, 1000, 2000);
|
auto packet1 = makeTestingWritePacket(1, 1000, 2000);
|
||||||
cubic.onPacketSent(packet1);
|
cubic.onPacketSent(packet1);
|
||||||
@@ -152,13 +152,13 @@ TEST_F(CubicRecoveryTest, AckNotLargestNotChangeCwnd) {
|
|||||||
|
|
||||||
// the the rest are acked:
|
// the the rest are acked:
|
||||||
cubic.onPacketAckOrLoss(
|
cubic.onPacketAckOrLoss(
|
||||||
makeAck(0, 1000, Clock::now(), packet1.time), folly::none);
|
makeAck(0, 1000, Clock::now(), packet1.metadata.time), folly::none);
|
||||||
cubic.onPacketAckOrLoss(
|
cubic.onPacketAckOrLoss(
|
||||||
makeAck(1, 1000, Clock::now(), packet2.time), folly::none);
|
makeAck(1, 1000, Clock::now(), packet2.metadata.time), folly::none);
|
||||||
cubic.onPacketAckOrLoss(
|
cubic.onPacketAckOrLoss(
|
||||||
makeAck(2, 1000, Clock::now(), packet3.time), folly::none);
|
makeAck(2, 1000, Clock::now(), packet3.metadata.time), folly::none);
|
||||||
cubic.onPacketAckOrLoss(
|
cubic.onPacketAckOrLoss(
|
||||||
makeAck(3, 1000, Clock::now(), packet4.time), folly::none);
|
makeAck(3, 1000, Clock::now(), packet4.metadata.time), folly::none);
|
||||||
|
|
||||||
// Still in recovery:
|
// Still in recovery:
|
||||||
EXPECT_EQ(CubicStates::FastRecovery, cubic.state());
|
EXPECT_EQ(CubicStates::FastRecovery, cubic.state());
|
||||||
|
@@ -35,7 +35,7 @@ TEST_F(CubicStateTest, HystartAck) {
|
|||||||
auto packet = makeTestingWritePacket(0, 0, 0);
|
auto packet = makeTestingWritePacket(0, 0, 0);
|
||||||
cubic.onPacketSent(packet);
|
cubic.onPacketSent(packet);
|
||||||
cubic.onPacketAckOrLoss(
|
cubic.onPacketAckOrLoss(
|
||||||
makeAck(0, 0, Clock::now(), packet.time), folly::none);
|
makeAck(0, 0, Clock::now(), packet.metadata.time), folly::none);
|
||||||
EXPECT_EQ(CubicStates::Hystart, cubic.state());
|
EXPECT_EQ(CubicStates::Hystart, cubic.state());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,7 +54,7 @@ TEST_F(CubicStateTest, FastRecoveryAck) {
|
|||||||
loss.addLostPacket(packet);
|
loss.addLostPacket(packet);
|
||||||
cubic.onPacketAckOrLoss(folly::none, std::move(loss));
|
cubic.onPacketAckOrLoss(folly::none, std::move(loss));
|
||||||
cubic.onPacketAckOrLoss(
|
cubic.onPacketAckOrLoss(
|
||||||
makeAck(2, 1000, Clock::now(), packet1.time), folly::none);
|
makeAck(2, 1000, Clock::now(), packet1.metadata.time), folly::none);
|
||||||
EXPECT_EQ(CubicStates::FastRecovery, cubic.state());
|
EXPECT_EQ(CubicStates::FastRecovery, cubic.state());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,7 +71,7 @@ TEST_F(CubicStateTest, FastRecoveryAckToSteady) {
|
|||||||
auto packet1 = makeTestingWritePacket(1, 1, 2);
|
auto packet1 = makeTestingWritePacket(1, 1, 2);
|
||||||
cubic.onPacketSent(packet1);
|
cubic.onPacketSent(packet1);
|
||||||
cubic.onPacketAckOrLoss(
|
cubic.onPacketAckOrLoss(
|
||||||
makeAck(1, 1, Clock::now(), packet1.time), folly::none);
|
makeAck(1, 1, Clock::now(), packet1.metadata.time), folly::none);
|
||||||
EXPECT_EQ(CubicStates::Steady, cubic.state());
|
EXPECT_EQ(CubicStates::Steady, cubic.state());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,7 +95,7 @@ TEST_F(CubicStateTest, SteadyAck) {
|
|||||||
auto packet = makeTestingWritePacket(0, 0, 0);
|
auto packet = makeTestingWritePacket(0, 0, 0);
|
||||||
cubic.onPacketSent(packet);
|
cubic.onPacketSent(packet);
|
||||||
cubic.onPacketAckOrLoss(
|
cubic.onPacketAckOrLoss(
|
||||||
makeAck(0, 0, Clock::now(), packet.time), folly::none);
|
makeAck(0, 0, Clock::now(), packet.metadata.time), folly::none);
|
||||||
EXPECT_EQ(CubicStates::Steady, cubic.state());
|
EXPECT_EQ(CubicStates::Steady, cubic.state());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -29,7 +29,7 @@ TEST_F(CubicSteadyTest, CubicReduction) {
|
|||||||
conn.lossState.largestSent = 0;
|
conn.lossState.largestSent = 0;
|
||||||
cubic.onPacketSent(packet0);
|
cubic.onPacketSent(packet0);
|
||||||
cubic.onPacketAckOrLoss(
|
cubic.onPacketAckOrLoss(
|
||||||
makeAck(0, 1000, Clock::now(), packet0.time), folly::none);
|
makeAck(0, 1000, Clock::now(), packet0.metadata.time), folly::none);
|
||||||
EXPECT_EQ(3000, cubic.getWritableBytes());
|
EXPECT_EQ(3000, cubic.getWritableBytes());
|
||||||
EXPECT_EQ(CubicStates::Steady, cubic.state());
|
EXPECT_EQ(CubicStates::Steady, cubic.state());
|
||||||
|
|
||||||
|
@@ -36,7 +36,7 @@ TEST_F(CubicTest, AckIncreaseWritable) {
|
|||||||
|
|
||||||
// Acking 50, now inflight become 50. Cwnd is init + 50
|
// Acking 50, now inflight become 50. Cwnd is init + 50
|
||||||
cubic.onPacketAckOrLoss(
|
cubic.onPacketAckOrLoss(
|
||||||
makeAck(0, 50, Clock::now(), packet.time), folly::none);
|
makeAck(0, 50, Clock::now(), packet.metadata.time), folly::none);
|
||||||
EXPECT_EQ(initCwnd, cubic.getWritableBytes());
|
EXPECT_EQ(initCwnd, cubic.getWritableBytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,7 +63,8 @@ TEST_F(CubicTest, PersistentCongestion) {
|
|||||||
auto packet2 = makeTestingWritePacket(1, initCwnd / 2, initCwnd / 2 + 1000);
|
auto packet2 = makeTestingWritePacket(1, initCwnd / 2, initCwnd / 2 + 1000);
|
||||||
cubic.onPacketSent(packet2);
|
cubic.onPacketSent(packet2);
|
||||||
cubic.onPacketAckOrLoss(
|
cubic.onPacketAckOrLoss(
|
||||||
makeAck(1, initCwnd / 2, Clock::now(), packet2.time), folly::none);
|
makeAck(1, initCwnd / 2, Clock::now(), packet2.metadata.time),
|
||||||
|
folly::none);
|
||||||
EXPECT_EQ(CubicStates::Steady, cubic.state());
|
EXPECT_EQ(CubicStates::Steady, cubic.state());
|
||||||
|
|
||||||
// Verify both lastMaxCwndBytes and lastReductionTime are also reset in
|
// Verify both lastMaxCwndBytes and lastReductionTime are also reset in
|
||||||
@@ -74,7 +75,7 @@ TEST_F(CubicTest, PersistentCongestion) {
|
|||||||
auto packet3 = makeTestingWritePacket(2, 3000, initCwnd / 2 + 1000 + 3000);
|
auto packet3 = makeTestingWritePacket(2, 3000, initCwnd / 2 + 1000 + 3000);
|
||||||
cubic.onPacketSent(packet3);
|
cubic.onPacketSent(packet3);
|
||||||
cubic.onPacketAckOrLoss(
|
cubic.onPacketAckOrLoss(
|
||||||
makeAck(2, 3000, Clock::now(), packet3.time), folly::none);
|
makeAck(2, 3000, Clock::now(), packet3.metadata.time), folly::none);
|
||||||
|
|
||||||
std::vector<int> indices =
|
std::vector<int> indices =
|
||||||
getQLogEventIndices(QLogEventType::CongestionMetricUpdate, qLogger);
|
getQLogEventIndices(QLogEventType::CongestionMetricUpdate, qLogger);
|
||||||
@@ -125,7 +126,7 @@ TEST_F(CubicTest, CwndIncreaseAfterReduction) {
|
|||||||
conn.lossState.largestSent = 0;
|
conn.lossState.largestSent = 0;
|
||||||
cubic.onPacketSent(packet0);
|
cubic.onPacketSent(packet0);
|
||||||
cubic.onPacketAckOrLoss(
|
cubic.onPacketAckOrLoss(
|
||||||
makeAck(0, 1000, Clock::now(), packet0.time), folly::none);
|
makeAck(0, 1000, Clock::now(), packet0.metadata.time), folly::none);
|
||||||
// Cwnd increased by 1000, inflight = 0:
|
// Cwnd increased by 1000, inflight = 0:
|
||||||
EXPECT_EQ(3000, cubic.getWritableBytes());
|
EXPECT_EQ(3000, cubic.getWritableBytes());
|
||||||
EXPECT_EQ(CubicStates::Steady, cubic.state());
|
EXPECT_EQ(CubicStates::Steady, cubic.state());
|
||||||
@@ -142,7 +143,7 @@ TEST_F(CubicTest, CwndIncreaseAfterReduction) {
|
|||||||
EXPECT_EQ(0, cubic.getWritableBytes());
|
EXPECT_EQ(0, cubic.getWritableBytes());
|
||||||
|
|
||||||
cubic.onPacketAckOrLoss(
|
cubic.onPacketAckOrLoss(
|
||||||
makeAck(1, 1000, Clock::now(), packet1.time), folly::none);
|
makeAck(1, 1000, Clock::now(), packet1.metadata.time), folly::none);
|
||||||
// Cwnd >= 3000, inflight = 2000:
|
// Cwnd >= 3000, inflight = 2000:
|
||||||
EXPECT_GE(cubic.getWritableBytes(), 1000);
|
EXPECT_GE(cubic.getWritableBytes(), 1000);
|
||||||
CongestionController::LossEvent loss;
|
CongestionController::LossEvent loss;
|
||||||
@@ -152,7 +153,7 @@ TEST_F(CubicTest, CwndIncreaseAfterReduction) {
|
|||||||
EXPECT_GE(cubic.getWritableBytes(), 1400);
|
EXPECT_GE(cubic.getWritableBytes(), 1400);
|
||||||
// This won't bring state machine back to Steady since endOfRecovery = 3
|
// This won't bring state machine back to Steady since endOfRecovery = 3
|
||||||
cubic.onPacketAckOrLoss(
|
cubic.onPacketAckOrLoss(
|
||||||
makeAck(3, 1000, Clock::now(), packet3.time), folly::none);
|
makeAck(3, 1000, Clock::now(), packet3.metadata.time), folly::none);
|
||||||
// Cwnd no change, inflight = 0:
|
// Cwnd no change, inflight = 0:
|
||||||
EXPECT_GE(cubic.getWritableBytes(), 2400);
|
EXPECT_GE(cubic.getWritableBytes(), 2400);
|
||||||
EXPECT_EQ(CubicStates::FastRecovery, cubic.state());
|
EXPECT_EQ(CubicStates::FastRecovery, cubic.state());
|
||||||
@@ -162,7 +163,7 @@ TEST_F(CubicTest, CwndIncreaseAfterReduction) {
|
|||||||
cubic.onPacketSent(packet4);
|
cubic.onPacketSent(packet4);
|
||||||
// This will bring state machine back to steady
|
// This will bring state machine back to steady
|
||||||
cubic.onPacketAckOrLoss(
|
cubic.onPacketAckOrLoss(
|
||||||
makeAck(4, 1000, Clock::now(), packet4.time), folly::none);
|
makeAck(4, 1000, Clock::now(), packet4.metadata.time), folly::none);
|
||||||
EXPECT_GE(cubic.getWritableBytes(), 2400);
|
EXPECT_GE(cubic.getWritableBytes(), 2400);
|
||||||
EXPECT_EQ(CubicStates::Steady, cubic.state());
|
EXPECT_EQ(CubicStates::Steady, cubic.state());
|
||||||
|
|
||||||
@@ -197,7 +198,8 @@ TEST_F(CubicTest, AppIdle) {
|
|||||||
auto packet1 = makeTestingWritePacket(1, 1000, 2000);
|
auto packet1 = makeTestingWritePacket(1, 1000, 2000);
|
||||||
cubic.onPacketSent(packet1);
|
cubic.onPacketSent(packet1);
|
||||||
cubic.onPacketAckOrLoss(
|
cubic.onPacketAckOrLoss(
|
||||||
makeAck(1, 1000, reductionTime + 1000ms, packet1.time), folly::none);
|
makeAck(1, 1000, reductionTime + 1000ms, packet1.metadata.time),
|
||||||
|
folly::none);
|
||||||
EXPECT_EQ(CubicStates::Steady, cubic.state());
|
EXPECT_EQ(CubicStates::Steady, cubic.state());
|
||||||
EXPECT_GT(cubic.getCongestionWindow(), cwnd);
|
EXPECT_GT(cubic.getCongestionWindow(), cwnd);
|
||||||
cwnd = cubic.getCongestionWindow();
|
cwnd = cubic.getCongestionWindow();
|
||||||
@@ -207,7 +209,8 @@ TEST_F(CubicTest, AppIdle) {
|
|||||||
auto packet2 = makeTestingWritePacket(2, 1000, 3000);
|
auto packet2 = makeTestingWritePacket(2, 1000, 3000);
|
||||||
cubic.onPacketSent(packet2);
|
cubic.onPacketSent(packet2);
|
||||||
cubic.onPacketAckOrLoss(
|
cubic.onPacketAckOrLoss(
|
||||||
makeAck(2, 1000, reductionTime + 2000ms, packet2.time), folly::none);
|
makeAck(2, 1000, reductionTime + 2000ms, packet2.metadata.time),
|
||||||
|
folly::none);
|
||||||
EXPECT_EQ(cubic.getCongestionWindow(), cwnd);
|
EXPECT_EQ(cubic.getCongestionWindow(), cwnd);
|
||||||
|
|
||||||
// 1 seconds of quiescence
|
// 1 seconds of quiescence
|
||||||
@@ -216,7 +219,8 @@ TEST_F(CubicTest, AppIdle) {
|
|||||||
auto packet3 = makeTestingWritePacket(3, 1000, 4000);
|
auto packet3 = makeTestingWritePacket(3, 1000, 4000);
|
||||||
cubic.onPacketSent(packet3);
|
cubic.onPacketSent(packet3);
|
||||||
cubic.onPacketAckOrLoss(
|
cubic.onPacketAckOrLoss(
|
||||||
makeAck(3, 1000, reductionTime + 3000ms, packet3.time), folly::none);
|
makeAck(3, 1000, reductionTime + 3000ms, packet3.metadata.time),
|
||||||
|
folly::none);
|
||||||
EXPECT_GT(cubic.getCongestionWindow(), cwnd);
|
EXPECT_GT(cubic.getCongestionWindow(), cwnd);
|
||||||
|
|
||||||
auto expectedDelta = static_cast<int64_t>(std::floor(
|
auto expectedDelta = static_cast<int64_t>(std::floor(
|
||||||
@@ -257,7 +261,7 @@ TEST_F(CubicTest, PacingGain) {
|
|||||||
EXPECT_EQ(cubic.getCongestionWindow() * 2, cwndBytes);
|
EXPECT_EQ(cubic.getCongestionWindow() * 2, cwndBytes);
|
||||||
}));
|
}));
|
||||||
cubic.onPacketAckOrLoss(
|
cubic.onPacketAckOrLoss(
|
||||||
makeAck(0, 1500, Clock::now(), packet.time), folly::none);
|
makeAck(0, 1500, Clock::now(), packet.metadata.time), folly::none);
|
||||||
EXPECT_EQ(CubicStates::Hystart, cubic.state());
|
EXPECT_EQ(CubicStates::Hystart, cubic.state());
|
||||||
|
|
||||||
auto packet1 = makeTestingWritePacket(1, 1500, 3000);
|
auto packet1 = makeTestingWritePacket(1, 1500, 3000);
|
||||||
@@ -285,7 +289,7 @@ TEST_F(CubicTest, PacingGain) {
|
|||||||
EXPECT_EQ(cubic.getCongestionWindow(), cwndBytes);
|
EXPECT_EQ(cubic.getCongestionWindow(), cwndBytes);
|
||||||
}));
|
}));
|
||||||
cubic.onPacketAckOrLoss(
|
cubic.onPacketAckOrLoss(
|
||||||
makeAck(2, 1500, Clock::now(), packet2.time), folly::none);
|
makeAck(2, 1500, Clock::now(), packet2.metadata.time), folly::none);
|
||||||
EXPECT_EQ(CubicStates::Steady, cubic.state());
|
EXPECT_EQ(CubicStates::Steady, cubic.state());
|
||||||
|
|
||||||
std::vector<int> indices =
|
std::vector<int> indices =
|
||||||
|
@@ -27,7 +27,7 @@ CongestionController::LossEvent createLossEvent(
|
|||||||
RegularQuicWritePacket packet(
|
RegularQuicWritePacket packet(
|
||||||
ShortHeader(ProtectionType::KeyPhaseZero, connId, packetData.first));
|
ShortHeader(ProtectionType::KeyPhaseZero, connId, packetData.first));
|
||||||
loss.addLostPacket(
|
loss.addLostPacket(
|
||||||
OutstandingPacket(std::move(packet), Clock::now(), 10, false, 10));
|
OutstandingPacket(std::move(packet), Clock::now(), 10, false, 10, 0));
|
||||||
loss.lostBytes = packetData.second;
|
loss.lostBytes = packetData.second;
|
||||||
}
|
}
|
||||||
loss.lostPackets = lostPackets.size();
|
loss.lostPackets = lostPackets.size();
|
||||||
@@ -46,16 +46,20 @@ 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)));
|
std::move(packet), packetSentTime, ackedSize, false, ackedSize, 0)));
|
||||||
return ack;
|
return ack;
|
||||||
}
|
}
|
||||||
|
|
||||||
OutstandingPacket
|
OutstandingPacket createPacket(
|
||||||
createPacket(PacketNum packetNum, uint32_t size, TimePoint sendTime) {
|
PacketNum packetNum,
|
||||||
|
uint32_t size,
|
||||||
|
TimePoint sendTime,
|
||||||
|
uint64_t inflight = 0) {
|
||||||
auto connId = getTestConnectionId();
|
auto connId = getTestConnectionId();
|
||||||
RegularQuicWritePacket packet(
|
RegularQuicWritePacket packet(
|
||||||
ShortHeader(ProtectionType::KeyPhaseZero, connId, packetNum));
|
ShortHeader(ProtectionType::KeyPhaseZero, connId, packetNum));
|
||||||
return OutstandingPacket(std::move(packet), sendTime, size, false, size);
|
return OutstandingPacket(
|
||||||
|
std::move(packet), sendTime, size, false, size, inflight);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(NewRenoTest, TestLoss) {
|
TEST_F(NewRenoTest, TestLoss) {
|
||||||
@@ -130,7 +134,8 @@ TEST_F(NewRenoTest, TestSlowStartAck) {
|
|||||||
reno.onPacketSent(packet);
|
reno.onPacketSent(packet);
|
||||||
EXPECT_EQ(reno.getBytesInFlight(), ackedSize);
|
EXPECT_EQ(reno.getBytesInFlight(), ackedSize);
|
||||||
reno.onPacketAckOrLoss(
|
reno.onPacketAckOrLoss(
|
||||||
createAckEvent(ackPacketNum1, ackedSize, packet.time), folly::none);
|
createAckEvent(ackPacketNum1, ackedSize, packet.metadata.time),
|
||||||
|
folly::none);
|
||||||
EXPECT_TRUE(reno.inSlowStart());
|
EXPECT_TRUE(reno.inSlowStart());
|
||||||
auto newWritableBytes = reno.getWritableBytes();
|
auto newWritableBytes = reno.getWritableBytes();
|
||||||
|
|
||||||
@@ -159,7 +164,8 @@ TEST_F(NewRenoTest, TestSteadyStateAck) {
|
|||||||
ackPacketNum1, ackedSize, Clock::now() - std::chrono::milliseconds(10));
|
ackPacketNum1, ackedSize, Clock::now() - std::chrono::milliseconds(10));
|
||||||
reno.onPacketSent(packet1);
|
reno.onPacketSent(packet1);
|
||||||
reno.onPacketAckOrLoss(
|
reno.onPacketAckOrLoss(
|
||||||
createAckEvent(ackPacketNum1, ackedSize, packet1.time), folly::none);
|
createAckEvent(ackPacketNum1, ackedSize, packet1.metadata.time),
|
||||||
|
folly::none);
|
||||||
EXPECT_FALSE(reno.inSlowStart());
|
EXPECT_FALSE(reno.inSlowStart());
|
||||||
|
|
||||||
auto newWritableBytes2 = reno.getWritableBytes();
|
auto newWritableBytes2 = reno.getWritableBytes();
|
||||||
@@ -169,7 +175,8 @@ TEST_F(NewRenoTest, TestSteadyStateAck) {
|
|||||||
auto packet2 = createPacket(ackPacketNum2, ackedSize, Clock::now());
|
auto packet2 = createPacket(ackPacketNum2, ackedSize, Clock::now());
|
||||||
reno.onPacketSent(packet2);
|
reno.onPacketSent(packet2);
|
||||||
reno.onPacketAckOrLoss(
|
reno.onPacketAckOrLoss(
|
||||||
createAckEvent(ackPacketNum2, ackedSize, packet2.time), folly::none);
|
createAckEvent(ackPacketNum2, ackedSize, packet2.metadata.time),
|
||||||
|
folly::none);
|
||||||
EXPECT_FALSE(reno.inSlowStart());
|
EXPECT_FALSE(reno.inSlowStart());
|
||||||
|
|
||||||
auto newWritableBytes3 = reno.getWritableBytes();
|
auto newWritableBytes3 = reno.getWritableBytes();
|
||||||
|
@@ -142,8 +142,8 @@ void detectPMTUBlackhole(
|
|||||||
auto& d6d = conn.d6d;
|
auto& d6d = conn.d6d;
|
||||||
// If d6d is not activated, or it's a d6d probe, or that the packet size is
|
// If d6d is not activated, or it's a d6d probe, or that the packet size is
|
||||||
// less than base pmtu, then the loss is not caused by pmtu blackhole
|
// less than base pmtu, then the loss is not caused by pmtu blackhole
|
||||||
if (d6d.state == D6DMachineState::DISABLED || packet.isD6DProbe ||
|
if (d6d.state == D6DMachineState::DISABLED || packet.metadata.isD6DProbe ||
|
||||||
packet.encodedSize <= d6d.basePMTU) {
|
packet.metadata.encodedSize <= d6d.basePMTU) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,7 +152,7 @@ void detectPMTUBlackhole(
|
|||||||
if (d6d.thresholdCounter &&
|
if (d6d.thresholdCounter &&
|
||||||
d6d.thresholdCounter->update(
|
d6d.thresholdCounter->update(
|
||||||
std::chrono::duration_cast<std::chrono::microseconds>(
|
std::chrono::duration_cast<std::chrono::microseconds>(
|
||||||
packet.time.time_since_epoch())
|
packet.metadata.time.time_since_epoch())
|
||||||
.count())) {
|
.count())) {
|
||||||
LOG(ERROR)
|
LOG(ERROR)
|
||||||
<< "PMTU blackhole detected on packet loss, reducing PMTU to base";
|
<< "PMTU blackhole detected on packet loss, reducing PMTU to base";
|
||||||
|
@@ -144,7 +144,7 @@ TEST_F(QuicD6DStateFunctionsTest, D6DProbeAckedInBase) {
|
|||||||
true,
|
true,
|
||||||
d6d.currentProbeSize);
|
d6d.currentProbeSize);
|
||||||
d6d.lastProbe = QuicConnectionStateBase::D6DProbePacket(
|
d6d.lastProbe = QuicConnectionStateBase::D6DProbePacket(
|
||||||
pkt.packet.header.getPacketSequenceNum(), pkt.encodedSize);
|
pkt.packet.header.getPacketSequenceNum(), pkt.metadata.encodedSize);
|
||||||
d6d.raiser = std::make_unique<MockProbeSizeRaiser>();
|
d6d.raiser = std::make_unique<MockProbeSizeRaiser>();
|
||||||
auto mockRaiser = dynamic_cast<MockProbeSizeRaiser*>(d6d.raiser.get());
|
auto mockRaiser = dynamic_cast<MockProbeSizeRaiser*>(d6d.raiser.get());
|
||||||
EXPECT_CALL(*mockRaiser, raiseProbeSize(d6d.currentProbeSize))
|
EXPECT_CALL(*mockRaiser, raiseProbeSize(d6d.currentProbeSize))
|
||||||
@@ -172,7 +172,7 @@ TEST_F(QuicD6DStateFunctionsTest, D6DProbeAckedInSearchingOne) {
|
|||||||
true,
|
true,
|
||||||
d6d.currentProbeSize);
|
d6d.currentProbeSize);
|
||||||
d6d.lastProbe = QuicConnectionStateBase::D6DProbePacket(
|
d6d.lastProbe = QuicConnectionStateBase::D6DProbePacket(
|
||||||
pkt.packet.header.getPacketSequenceNum(), pkt.encodedSize);
|
pkt.packet.header.getPacketSequenceNum(), pkt.metadata.encodedSize);
|
||||||
d6d.raiser = std::make_unique<MockProbeSizeRaiser>();
|
d6d.raiser = std::make_unique<MockProbeSizeRaiser>();
|
||||||
auto mockRaiser = dynamic_cast<MockProbeSizeRaiser*>(d6d.raiser.get());
|
auto mockRaiser = dynamic_cast<MockProbeSizeRaiser*>(d6d.raiser.get());
|
||||||
EXPECT_CALL(*mockRaiser, raiseProbeSize(d6d.currentProbeSize))
|
EXPECT_CALL(*mockRaiser, raiseProbeSize(d6d.currentProbeSize))
|
||||||
@@ -200,7 +200,7 @@ TEST_F(QuicD6DStateFunctionsTest, D6DProbeAckedInSearchingMax) {
|
|||||||
true,
|
true,
|
||||||
d6d.currentProbeSize);
|
d6d.currentProbeSize);
|
||||||
d6d.lastProbe = QuicConnectionStateBase::D6DProbePacket(
|
d6d.lastProbe = QuicConnectionStateBase::D6DProbePacket(
|
||||||
pkt.packet.header.getPacketSequenceNum(), pkt.encodedSize);
|
pkt.packet.header.getPacketSequenceNum(), pkt.metadata.encodedSize);
|
||||||
d6d.raiser = std::make_unique<MockProbeSizeRaiser>();
|
d6d.raiser = std::make_unique<MockProbeSizeRaiser>();
|
||||||
auto mockRaiser = dynamic_cast<MockProbeSizeRaiser*>(d6d.raiser.get());
|
auto mockRaiser = dynamic_cast<MockProbeSizeRaiser*>(d6d.raiser.get());
|
||||||
EXPECT_CALL(*mockRaiser, raiseProbeSize(d6d.currentProbeSize))
|
EXPECT_CALL(*mockRaiser, raiseProbeSize(d6d.currentProbeSize))
|
||||||
@@ -227,7 +227,7 @@ TEST_F(QuicD6DStateFunctionsTest, D6DProbeAckedInError) {
|
|||||||
true,
|
true,
|
||||||
d6d.currentProbeSize);
|
d6d.currentProbeSize);
|
||||||
d6d.lastProbe = QuicConnectionStateBase::D6DProbePacket(
|
d6d.lastProbe = QuicConnectionStateBase::D6DProbePacket(
|
||||||
pkt.packet.header.getPacketSequenceNum(), pkt.encodedSize);
|
pkt.packet.header.getPacketSequenceNum(), pkt.metadata.encodedSize);
|
||||||
d6d.raiser = std::make_unique<MockProbeSizeRaiser>();
|
d6d.raiser = std::make_unique<MockProbeSizeRaiser>();
|
||||||
auto mockRaiser = dynamic_cast<MockProbeSizeRaiser*>(d6d.raiser.get());
|
auto mockRaiser = dynamic_cast<MockProbeSizeRaiser*>(d6d.raiser.get());
|
||||||
EXPECT_CALL(*mockRaiser, raiseProbeSize(d6d.currentProbeSize))
|
EXPECT_CALL(*mockRaiser, raiseProbeSize(d6d.currentProbeSize))
|
||||||
|
@@ -219,11 +219,11 @@ folly::Optional<CongestionController::LossEvent> detectLossPackets(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
auto currentPacketNumberSpace = pkt.packet.header.getPacketNumberSpace();
|
auto currentPacketNumberSpace = pkt.packet.header.getPacketNumberSpace();
|
||||||
if (currentPacketNumberSpace != pnSpace) {
|
if (currentPacketNumberSpace != pnSpace || pkt.metadata.isD6DProbe) {
|
||||||
iter++;
|
iter++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
bool lostByTimeout = (lossTime - pkt.time) > delayUntilLost;
|
bool lostByTimeout = (lossTime - pkt.metadata.time) > delayUntilLost;
|
||||||
bool lostByReorder =
|
bool lostByReorder =
|
||||||
(*largestAcked - currentPacketNum) > conn.lossState.reorderingThreshold;
|
(*largestAcked - currentPacketNum) > conn.lossState.reorderingThreshold;
|
||||||
|
|
||||||
@@ -233,7 +233,7 @@ folly::Optional<CongestionController::LossEvent> detectLossPackets(
|
|||||||
shouldSetTimer = true;
|
shouldSetTimer = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (pkt.isD6DProbe) {
|
if (pkt.metadata.isD6DProbe) {
|
||||||
// It's a D6D probe, we'll mark it as lost to avoid its stale
|
// It's a D6D probe, we'll mark it as lost to avoid its stale
|
||||||
// ack from affecting PMTU. We don't add it to loss event to
|
// ack from affecting PMTU. We don't add it to loss event to
|
||||||
// avoid affecting congestion control when there's probably no
|
// avoid affecting congestion control when there's probably no
|
||||||
@@ -267,7 +267,7 @@ folly::Optional<CongestionController::LossEvent> detectLossPackets(
|
|||||||
if (pkt.associatedEvent) {
|
if (pkt.associatedEvent) {
|
||||||
conn.outstandings.packetEvents.erase(*pkt.associatedEvent);
|
conn.outstandings.packetEvents.erase(*pkt.associatedEvent);
|
||||||
}
|
}
|
||||||
if (pkt.isHandshake && !processed) {
|
if (pkt.metadata.isHandshake && !processed) {
|
||||||
if (currentPacketNumberSpace == PacketNumberSpace::Initial) {
|
if (currentPacketNumberSpace == PacketNumberSpace::Initial) {
|
||||||
CHECK(conn.outstandings.initialPacketsCount);
|
CHECK(conn.outstandings.initialPacketsCount);
|
||||||
--conn.outstandings.initialPacketsCount;
|
--conn.outstandings.initialPacketsCount;
|
||||||
@@ -278,7 +278,7 @@ folly::Optional<CongestionController::LossEvent> detectLossPackets(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
VLOG(10) << __func__ << " lost packetNum=" << currentPacketNum
|
VLOG(10) << __func__ << " lost packetNum=" << currentPacketNum
|
||||||
<< " handshake=" << pkt.isHandshake << " " << conn;
|
<< " handshake=" << pkt.metadata.isHandshake << " " << conn;
|
||||||
// Rather than erasing here, instead mark the packet as lost so we can
|
// Rather than erasing here, instead mark the packet as lost so we can
|
||||||
// determine if this was spurious later.
|
// determine if this was spurious later.
|
||||||
conn.outstandings.declaredLostCount++;
|
conn.outstandings.declaredLostCount++;
|
||||||
@@ -310,7 +310,7 @@ folly::Optional<CongestionController::LossEvent> detectLossPackets(
|
|||||||
<< conn.outstandings.packets.empty() << " delayUntilLost"
|
<< conn.outstandings.packets.empty() << " delayUntilLost"
|
||||||
<< delayUntilLost.count() << "us"
|
<< delayUntilLost.count() << "us"
|
||||||
<< " " << conn;
|
<< " " << conn;
|
||||||
getLossTime(conn, pnSpace) = delayUntilLost + earliest->time;
|
getLossTime(conn, pnSpace) = delayUntilLost + earliest->metadata.time;
|
||||||
}
|
}
|
||||||
if (lossEvent.largestLostPacketNum.hasValue()) {
|
if (lossEvent.largestLostPacketNum.hasValue()) {
|
||||||
DCHECK(lossEvent.largestLostSentTime && lossEvent.smallestLostSentTime);
|
DCHECK(lossEvent.largestLostSentTime && lossEvent.smallestLostSentTime);
|
||||||
@@ -441,7 +441,7 @@ void markZeroRttPacketsLost(
|
|||||||
iter->packet.header.getProtectionType() == ProtectionType::ZeroRtt;
|
iter->packet.header.getProtectionType() == ProtectionType::ZeroRtt;
|
||||||
if (isZeroRttPacket) {
|
if (isZeroRttPacket) {
|
||||||
auto& pkt = *iter;
|
auto& pkt = *iter;
|
||||||
DCHECK(!pkt.isHandshake);
|
DCHECK(!pkt.metadata.isHandshake);
|
||||||
bool processed = pkt.associatedEvent &&
|
bool processed = pkt.associatedEvent &&
|
||||||
!conn.outstandings.packetEvents.count(*pkt.associatedEvent);
|
!conn.outstandings.packetEvents.count(*pkt.associatedEvent);
|
||||||
lossVisitor(conn, pkt.packet, processed);
|
lossVisitor(conn, pkt.packet, processed);
|
||||||
|
@@ -224,7 +224,13 @@ PacketNum QuicLossFunctionsTest::sendPacket(
|
|||||||
encodedSize += packet.body->computeChainDataLength();
|
encodedSize += packet.body->computeChainDataLength();
|
||||||
}
|
}
|
||||||
auto outstandingPacket = OutstandingPacket(
|
auto outstandingPacket = OutstandingPacket(
|
||||||
packet.packet, time, encodedSize, isHandshake, isD6DProbe, encodedSize);
|
packet.packet,
|
||||||
|
time,
|
||||||
|
encodedSize,
|
||||||
|
isHandshake,
|
||||||
|
isD6DProbe,
|
||||||
|
encodedSize,
|
||||||
|
0);
|
||||||
outstandingPacket.associatedEvent = associatedEvent;
|
outstandingPacket.associatedEvent = associatedEvent;
|
||||||
if (isHandshake) {
|
if (isHandshake) {
|
||||||
conn.lossState.lastHandshakePacketSentTime = time;
|
conn.lossState.lastHandshakePacketSentTime = time;
|
||||||
@@ -993,7 +999,7 @@ TEST_F(QuicLossFunctionsTest, TestReorderingThreshold) {
|
|||||||
iter <
|
iter <
|
||||||
getFirstOutstandingPacket(*conn, PacketNumberSpace::Handshake) + 5;
|
getFirstOutstandingPacket(*conn, PacketNumberSpace::Handshake) + 5;
|
||||||
iter++) {
|
iter++) {
|
||||||
if (iter->isHandshake) {
|
if (iter->metadata.isHandshake) {
|
||||||
conn->outstandings.handshakePacketsCount--;
|
conn->outstandings.handshakePacketsCount--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1045,7 +1051,7 @@ TEST_F(QuicLossFunctionsTest, TestHandleAckForLoss) {
|
|||||||
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(outstandingRegularPacket, now, 0, false, 0));
|
OutstandingPacket(outstandingRegularPacket, now, 0, false, 0, 0));
|
||||||
|
|
||||||
bool testLossMarkFuncCalled = false;
|
bool testLossMarkFuncCalled = false;
|
||||||
auto testLossMarkFunc = [&](auto& /* conn */, auto&, bool) {
|
auto testLossMarkFunc = [&](auto& /* conn */, auto&, bool) {
|
||||||
|
@@ -917,7 +917,7 @@ void onServerReadDataFromOpen(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case QuicWriteFrame::Type::PingFrame_E:
|
case QuicWriteFrame::Type::PingFrame_E:
|
||||||
if (!packet.isD6DProbe) {
|
if (!packet.metadata.isD6DProbe) {
|
||||||
conn.pendingEvents.cancelPingTimeout = true;
|
conn.pendingEvents.cancelPingTimeout = true;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@@ -107,8 +107,9 @@ void processAckFrame(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
VLOG(10) << __func__ << " acked packetNum=" << currentPacketNum
|
VLOG(10) << __func__ << " acked packetNum=" << currentPacketNum
|
||||||
<< " space=" << currentPacketNumberSpace
|
<< " space=" << currentPacketNumberSpace << " handshake="
|
||||||
<< " handshake=" << (int)rPacketIt->isHandshake << " " << conn;
|
<< (int)((rPacketIt->metadata.isHandshake) ? 1 : 0) << " "
|
||||||
|
<< conn;
|
||||||
// If we hit a packet which has been lost we need to count the spurious
|
// If we hit a packet which has been lost we need to count the spurious
|
||||||
// loss and ignore all other processing.
|
// loss and ignore all other processing.
|
||||||
// TODO also remove any stream data from the loss buffer.
|
// TODO also remove any stream data from the loss buffer.
|
||||||
@@ -124,7 +125,7 @@ void processAckFrame(
|
|||||||
}
|
}
|
||||||
bool needsProcess = !rPacketIt->associatedEvent ||
|
bool needsProcess = !rPacketIt->associatedEvent ||
|
||||||
conn.outstandings.packetEvents.count(*rPacketIt->associatedEvent);
|
conn.outstandings.packetEvents.count(*rPacketIt->associatedEvent);
|
||||||
if (rPacketIt->isHandshake && needsProcess) {
|
if (rPacketIt->metadata.isHandshake && needsProcess) {
|
||||||
if (currentPacketNumberSpace == PacketNumberSpace::Initial) {
|
if (currentPacketNumberSpace == PacketNumberSpace::Initial) {
|
||||||
++initialPacketAcked;
|
++initialPacketAcked;
|
||||||
} else {
|
} else {
|
||||||
@@ -132,21 +133,29 @@ void processAckFrame(
|
|||||||
++handshakePacketAcked;
|
++handshakePacketAcked;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ack.ackedBytes += rPacketIt->encodedSize;
|
ack.ackedBytes += rPacketIt->metadata.encodedSize;
|
||||||
if (rPacketIt->associatedEvent) {
|
if (rPacketIt->associatedEvent) {
|
||||||
++clonedPacketsAcked;
|
++clonedPacketsAcked;
|
||||||
}
|
}
|
||||||
// Update RTT if current packet is the largestAcked in the frame:
|
// Update RTT if current packet is the largestAcked in the frame:
|
||||||
auto ackReceiveTimeOrNow =
|
auto ackReceiveTimeOrNow = ackReceiveTime > rPacketIt->metadata.time
|
||||||
ackReceiveTime > rPacketIt->time ? ackReceiveTime : Clock::now();
|
? ackReceiveTime
|
||||||
|
: Clock::now();
|
||||||
auto rttSample = std::chrono::duration_cast<std::chrono::microseconds>(
|
auto rttSample = std::chrono::duration_cast<std::chrono::microseconds>(
|
||||||
ackReceiveTimeOrNow - rPacketIt->time);
|
ackReceiveTimeOrNow - rPacketIt->metadata.time);
|
||||||
if (!ack.implicit && currentPacketNum == frame.largestAcked) {
|
if (!ack.implicit && currentPacketNum == frame.largestAcked) {
|
||||||
|
InstrumentationObserver::PacketRTT packetRTT(
|
||||||
|
ackReceiveTimeOrNow, rttSample, frame.ackDelay, *rPacketIt);
|
||||||
|
for (const auto& observer : conn.instrumentationObservers_) {
|
||||||
|
conn.pendingCallbacks.emplace_back([observer, packetRTT] {
|
||||||
|
observer->rttSampleGenerated(packetRTT);
|
||||||
|
});
|
||||||
|
}
|
||||||
updateRtt(conn, rttSample, frame.ackDelay);
|
updateRtt(conn, rttSample, frame.ackDelay);
|
||||||
}
|
}
|
||||||
// D6D probe acked. Only if it's for the last probe do we
|
// D6D probe acked. Only if it's for the last probe do we
|
||||||
// trigger state change
|
// trigger state change
|
||||||
if (rPacketIt->isD6DProbe) {
|
if (rPacketIt->metadata.isD6DProbe) {
|
||||||
CHECK(conn.d6d.lastProbe);
|
CHECK(conn.d6d.lastProbe);
|
||||||
if (!rPacketIt->declaredLost &&
|
if (!rPacketIt->declaredLost &&
|
||||||
currentPacketNum == conn.d6d.lastProbe->packetNum) {
|
currentPacketNum == conn.d6d.lastProbe->packetNum) {
|
||||||
@@ -168,27 +177,27 @@ void processAckFrame(
|
|||||||
if (!ack.largestAckedPacket ||
|
if (!ack.largestAckedPacket ||
|
||||||
*ack.largestAckedPacket < currentPacketNum) {
|
*ack.largestAckedPacket < currentPacketNum) {
|
||||||
ack.largestAckedPacket = currentPacketNum;
|
ack.largestAckedPacket = currentPacketNum;
|
||||||
ack.largestAckedPacketSentTime = rPacketIt->time;
|
ack.largestAckedPacketSentTime = rPacketIt->metadata.time;
|
||||||
ack.largestAckedPacketAppLimited = rPacketIt->isAppLimited;
|
ack.largestAckedPacketAppLimited = rPacketIt->isAppLimited;
|
||||||
}
|
}
|
||||||
if (!ack.implicit && ackReceiveTime > rPacketIt->time) {
|
if (!ack.implicit && ackReceiveTime > rPacketIt->metadata.time) {
|
||||||
ack.mrttSample =
|
ack.mrttSample =
|
||||||
std::min(ack.mrttSample.value_or(rttSample), rttSample);
|
std::min(ack.mrttSample.value_or(rttSample), rttSample);
|
||||||
}
|
}
|
||||||
conn.lossState.totalBytesAcked += rPacketIt->encodedSize;
|
conn.lossState.totalBytesAcked += rPacketIt->metadata.encodedSize;
|
||||||
conn.lossState.totalBytesSentAtLastAck = conn.lossState.totalBytesSent;
|
conn.lossState.totalBytesSentAtLastAck = conn.lossState.totalBytesSent;
|
||||||
conn.lossState.totalBytesAckedAtLastAck = conn.lossState.totalBytesAcked;
|
conn.lossState.totalBytesAckedAtLastAck = conn.lossState.totalBytesAcked;
|
||||||
if (!lastAckedPacketSentTime) {
|
if (!lastAckedPacketSentTime) {
|
||||||
lastAckedPacketSentTime = rPacketIt->time;
|
lastAckedPacketSentTime = rPacketIt->metadata.time;
|
||||||
}
|
}
|
||||||
conn.lossState.lastAckedTime = ackReceiveTime;
|
conn.lossState.lastAckedTime = ackReceiveTime;
|
||||||
conn.lossState.adjustedLastAckedTime = ackReceiveTime - frame.ackDelay;
|
conn.lossState.adjustedLastAckedTime = ackReceiveTime - frame.ackDelay;
|
||||||
ack.ackedPackets.push_back(
|
ack.ackedPackets.push_back(
|
||||||
CongestionController::AckEvent::AckPacket::Builder()
|
CongestionController::AckEvent::AckPacket::Builder()
|
||||||
.setSentTime(rPacketIt->time)
|
.setSentTime(rPacketIt->metadata.time)
|
||||||
.setEncodedSize(rPacketIt->encodedSize)
|
.setEncodedSize(rPacketIt->metadata.encodedSize)
|
||||||
.setLastAckedPacketInfo(std::move(rPacketIt->lastAckedPacketInfo))
|
.setLastAckedPacketInfo(std::move(rPacketIt->lastAckedPacketInfo))
|
||||||
.setTotalBytesSentThen(rPacketIt->totalBytesSent)
|
.setTotalBytesSentThen(rPacketIt->metadata.totalBytesSent)
|
||||||
.setAppLimited(rPacketIt->isAppLimited)
|
.setAppLimited(rPacketIt->isAppLimited)
|
||||||
.build());
|
.build());
|
||||||
rPacketIt++;
|
rPacketIt++;
|
||||||
@@ -256,7 +265,7 @@ void clearOldOutstandingPackets(
|
|||||||
while (opItr != conn.outstandings.packets.end()) {
|
while (opItr != conn.outstandings.packets.end()) {
|
||||||
// This case can happen when we have buffered an undecryptable ACK and
|
// This case can happen when we have buffered an undecryptable ACK and
|
||||||
// are able to decrypt it later.
|
// are able to decrypt it later.
|
||||||
if (time < opItr->time) {
|
if (time < opItr->metadata.time) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (opItr->packet.header.getPacketNumberSpace() != pnSpace) {
|
if (opItr->packet.header.getPacketNumberSpace() != pnSpace) {
|
||||||
@@ -268,7 +277,7 @@ void clearOldOutstandingPackets(
|
|||||||
eraseBegin = opItr;
|
eraseBegin = opItr;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
auto timeSinceSent = time - opItr->time;
|
auto timeSinceSent = time - opItr->metadata.time;
|
||||||
if (opItr->declaredLost && timeSinceSent > threshold) {
|
if (opItr->declaredLost && timeSinceSent > threshold) {
|
||||||
opItr++;
|
opItr++;
|
||||||
conn.outstandings.declaredLostCount--;
|
conn.outstandings.declaredLostCount--;
|
||||||
|
@@ -12,11 +12,8 @@
|
|||||||
#include <quic/state/PacketEvent.h>
|
#include <quic/state/PacketEvent.h>
|
||||||
|
|
||||||
namespace quic {
|
namespace quic {
|
||||||
// Data structure to represent outstanding retransmittable packets
|
|
||||||
struct OutstandingPacket {
|
struct OutstandingPacketMetadata {
|
||||||
// Structure representing the frames that are outstanding including the header
|
|
||||||
// that was sent.
|
|
||||||
RegularQuicWritePacket packet;
|
|
||||||
// Time that the packet was sent.
|
// Time that the packet was sent.
|
||||||
TimePoint time;
|
TimePoint time;
|
||||||
// Size of the packet sent on the wire.
|
// Size of the packet sent on the wire.
|
||||||
@@ -28,6 +25,33 @@ struct OutstandingPacket {
|
|||||||
// Total sent bytes on this connection including this packet itself when this
|
// Total sent bytes on this connection including this packet itself when this
|
||||||
// packet is sent.
|
// packet is sent.
|
||||||
uint64_t totalBytesSent;
|
uint64_t totalBytesSent;
|
||||||
|
// Bytes in flight on this connection including this packet itself when this
|
||||||
|
// packet is sent.
|
||||||
|
uint64_t inflightBytes;
|
||||||
|
|
||||||
|
OutstandingPacketMetadata(
|
||||||
|
TimePoint timeIn,
|
||||||
|
uint32_t encodedSizeIn,
|
||||||
|
bool isHandshakeIn,
|
||||||
|
bool isD6DProbeIn,
|
||||||
|
uint64_t totalBytesSentIn,
|
||||||
|
uint64_t inflightBytesIn)
|
||||||
|
: time(std::move(timeIn)),
|
||||||
|
encodedSize(encodedSizeIn),
|
||||||
|
isHandshake(isHandshakeIn),
|
||||||
|
isD6DProbe(isD6DProbeIn),
|
||||||
|
totalBytesSent(totalBytesSentIn),
|
||||||
|
inflightBytes(inflightBytesIn) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Data structure to represent outstanding retransmittable packets
|
||||||
|
struct OutstandingPacket {
|
||||||
|
// Structure representing the frames that are outstanding including the header
|
||||||
|
// that was sent.
|
||||||
|
RegularQuicWritePacket packet;
|
||||||
|
// Structure representing a collection of metrics and important information
|
||||||
|
// about the packet.
|
||||||
|
OutstandingPacketMetadata metadata;
|
||||||
// Information regarding the last acked packet on this connection when this
|
// Information regarding the last acked packet on this connection when this
|
||||||
// packet is sent.
|
// packet is sent.
|
||||||
struct LastAckedPacketInfo {
|
struct LastAckedPacketInfo {
|
||||||
@@ -73,13 +97,16 @@ struct OutstandingPacket {
|
|||||||
TimePoint timeIn,
|
TimePoint timeIn,
|
||||||
uint32_t encodedSizeIn,
|
uint32_t encodedSizeIn,
|
||||||
bool isHandshakeIn,
|
bool isHandshakeIn,
|
||||||
uint64_t totalBytesSentIn)
|
uint64_t totalBytesSentIn,
|
||||||
|
uint64_t inflightBytesIn)
|
||||||
: packet(std::move(packetIn)),
|
: packet(std::move(packetIn)),
|
||||||
time(std::move(timeIn)),
|
metadata(OutstandingPacketMetadata(
|
||||||
encodedSize(encodedSizeIn),
|
std::move(timeIn),
|
||||||
isHandshake(isHandshakeIn),
|
encodedSizeIn,
|
||||||
isD6DProbe(false),
|
isHandshakeIn,
|
||||||
totalBytesSent(totalBytesSentIn) {}
|
false,
|
||||||
|
totalBytesSentIn,
|
||||||
|
inflightBytesIn)) {}
|
||||||
|
|
||||||
OutstandingPacket(
|
OutstandingPacket(
|
||||||
RegularQuicWritePacket packetIn,
|
RegularQuicWritePacket packetIn,
|
||||||
@@ -87,12 +114,15 @@ struct OutstandingPacket {
|
|||||||
uint32_t encodedSizeIn,
|
uint32_t encodedSizeIn,
|
||||||
bool isHandshakeIn,
|
bool isHandshakeIn,
|
||||||
bool isD6DProbeIn,
|
bool isD6DProbeIn,
|
||||||
uint64_t totalBytesSentIn)
|
uint64_t totalBytesSentIn,
|
||||||
|
uint64_t inflightBytesIn)
|
||||||
: packet(std::move(packetIn)),
|
: packet(std::move(packetIn)),
|
||||||
time(std::move(timeIn)),
|
metadata(OutstandingPacketMetadata(
|
||||||
encodedSize(encodedSizeIn),
|
std::move(timeIn),
|
||||||
isHandshake(isHandshakeIn),
|
encodedSizeIn,
|
||||||
isD6DProbe(isD6DProbeIn),
|
isHandshakeIn,
|
||||||
totalBytesSent(totalBytesSentIn) {}
|
isD6DProbeIn,
|
||||||
|
totalBytesSentIn,
|
||||||
|
inflightBytesIn)) {}
|
||||||
};
|
};
|
||||||
} // namespace quic
|
} // namespace quic
|
||||||
|
@@ -233,7 +233,7 @@ struct CongestionController {
|
|||||||
|
|
||||||
void addLostPacket(const OutstandingPacket& packet) {
|
void addLostPacket(const OutstandingPacket& packet) {
|
||||||
if (std::numeric_limits<uint64_t>::max() - lostBytes <
|
if (std::numeric_limits<uint64_t>::max() - lostBytes <
|
||||||
packet.encodedSize) {
|
packet.metadata.encodedSize) {
|
||||||
throw QuicInternalException(
|
throw QuicInternalException(
|
||||||
"LossEvent: lostBytes overflow",
|
"LossEvent: lostBytes overflow",
|
||||||
LocalErrorCode::LOST_BYTES_OVERFLOW);
|
LocalErrorCode::LOST_BYTES_OVERFLOW);
|
||||||
@@ -241,12 +241,14 @@ struct CongestionController {
|
|||||||
PacketNum packetNum = packet.packet.header.getPacketSequenceNum();
|
PacketNum packetNum = packet.packet.header.getPacketSequenceNum();
|
||||||
largestLostPacketNum =
|
largestLostPacketNum =
|
||||||
std::max(packetNum, largestLostPacketNum.value_or(packetNum));
|
std::max(packetNum, largestLostPacketNum.value_or(packetNum));
|
||||||
lostBytes += packet.encodedSize;
|
lostBytes += packet.metadata.encodedSize;
|
||||||
lostPackets++;
|
lostPackets++;
|
||||||
largestLostSentTime =
|
largestLostSentTime = std::max(
|
||||||
std::max(packet.time, largestLostSentTime.value_or(packet.time));
|
packet.metadata.time,
|
||||||
smallestLostSentTime =
|
largestLostSentTime.value_or(packet.metadata.time));
|
||||||
std::min(packet.time, smallestLostSentTime.value_or(packet.time));
|
smallestLostSentTime = std::min(
|
||||||
|
packet.metadata.time,
|
||||||
|
smallestLostSentTime.value_or(packet.metadata.time));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
#include <quic/common/test/TestUtils.h>
|
#include <quic/common/test/TestUtils.h>
|
||||||
|
|
||||||
|
#include <quic/QuicConstants.h>
|
||||||
|
#include <quic/api/test/Mocks.h>
|
||||||
#include <quic/fizz/server/handshake/FizzServerQuicHandshakeContext.h>
|
#include <quic/fizz/server/handshake/FizzServerQuicHandshakeContext.h>
|
||||||
#include <quic/logging/test/Mocks.h>
|
#include <quic/logging/test/Mocks.h>
|
||||||
#include <quic/server/state/ServerStateMachine.h>
|
#include <quic/server/state/ServerStateMachine.h>
|
||||||
@@ -52,7 +54,7 @@ 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));
|
std::move(regularPacket), sentTime, 1, false, packetNum, 0));
|
||||||
}
|
}
|
||||||
ReadAckFrame ackFrame;
|
ReadAckFrame ackFrame;
|
||||||
ackFrame.largestAcked = 101;
|
ackFrame.largestAcked = 101;
|
||||||
@@ -123,7 +125,7 @@ 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));
|
std::move(regularPacket), sentTime, 1, false, packetNum, 0));
|
||||||
}
|
}
|
||||||
ReadAckFrame ackFrame;
|
ReadAckFrame ackFrame;
|
||||||
ackFrame.largestAcked = 101;
|
ackFrame.largestAcked = 101;
|
||||||
@@ -258,7 +260,7 @@ 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));
|
std::move(regularPacket), Clock::now(), 1, false, packetNum, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
ReadAckFrame ackFrame;
|
ReadAckFrame ackFrame;
|
||||||
@@ -356,7 +358,7 @@ 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));
|
std::move(regularPacket), Clock::now(), 1, false, packetNum, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (PacketNum packetNum = 20; packetNum < 40; packetNum += 3) {
|
for (PacketNum packetNum = 20; packetNum < 40; packetNum += 3) {
|
||||||
@@ -365,7 +367,7 @@ 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));
|
std::move(regularPacket), Clock::now(), 1, false, packetNum, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
ReadAckFrame ackFrame;
|
ReadAckFrame ackFrame;
|
||||||
@@ -446,7 +448,7 @@ TEST_P(AckHandlersTest, AckVisitorForAckTest) {
|
|||||||
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(std::move(firstPacket), Clock::now(), 0, false, 0));
|
OutstandingPacket(std::move(firstPacket), Clock::now(), 0, false, 0, 0));
|
||||||
|
|
||||||
auto secondPacket = createNewPacket(101 /* packetNum */, GetParam());
|
auto secondPacket = createNewPacket(101 /* packetNum */, GetParam());
|
||||||
WriteAckFrame secondAckFrame;
|
WriteAckFrame secondAckFrame;
|
||||||
@@ -456,7 +458,7 @@ TEST_P(AckHandlersTest, AckVisitorForAckTest) {
|
|||||||
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(std::move(secondPacket), Clock::now(), 0, false, 0));
|
OutstandingPacket(std::move(secondPacket), Clock::now(), 0, false, 0, 0));
|
||||||
|
|
||||||
ReadAckFrame firstReceivedAck;
|
ReadAckFrame firstReceivedAck;
|
||||||
firstReceivedAck.largestAcked = 100;
|
firstReceivedAck.largestAcked = 100;
|
||||||
@@ -516,8 +518,8 @@ TEST_P(AckHandlersTest, NoNewAckedPacket) {
|
|||||||
conn.lossState.ptoCount = 1;
|
conn.lossState.ptoCount = 1;
|
||||||
PacketNum packetAfterRtoNum = 10;
|
PacketNum packetAfterRtoNum = 10;
|
||||||
auto packetAfterRto = createNewPacket(packetAfterRtoNum, GetParam());
|
auto packetAfterRto = createNewPacket(packetAfterRtoNum, GetParam());
|
||||||
conn.outstandings.packets.emplace_back(
|
conn.outstandings.packets.emplace_back(OutstandingPacket(
|
||||||
OutstandingPacket(std::move(packetAfterRto), Clock::now(), 0, false, 0));
|
std::move(packetAfterRto), Clock::now(), 0, false, 0, 0));
|
||||||
|
|
||||||
ReadAckFrame ackFrame;
|
ReadAckFrame ackFrame;
|
||||||
ackFrame.largestAcked = 5;
|
ackFrame.largestAcked = 5;
|
||||||
@@ -563,12 +565,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);
|
std::move(regularPacket1), Clock::now(), 0, false, 0, 0);
|
||||||
|
|
||||||
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);
|
std::move(regularPacket2), Clock::now(), 0, false, 0, 0);
|
||||||
|
|
||||||
// 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.
|
||||||
@@ -601,7 +603,8 @@ TEST_P(AckHandlersTest, TestHandshakeCounterUpdate) {
|
|||||||
Clock::now(),
|
Clock::now(),
|
||||||
0,
|
0,
|
||||||
packetNum % 2 && GetParam() != PacketNumberSpace::AppData,
|
packetNum % 2 && GetParam() != PacketNumberSpace::AppData,
|
||||||
packetNum / 2);
|
packetNum / 2,
|
||||||
|
0);
|
||||||
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) {
|
||||||
@@ -683,8 +686,8 @@ TEST_P(AckHandlersTest, NoSkipAckVisitor) {
|
|||||||
// We need to at least have one frame to trigger ackVisitor
|
// We need to at least have one frame to trigger ackVisitor
|
||||||
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(
|
conn.outstandings.packets.emplace_back(OutstandingPacket(
|
||||||
OutstandingPacket(std::move(regularPacket), Clock::now(), 1, false, 1));
|
std::move(regularPacket), Clock::now(), 1, false, 1, 0));
|
||||||
ReadAckFrame ackFrame;
|
ReadAckFrame ackFrame;
|
||||||
ackFrame.largestAcked = 0;
|
ackFrame.largestAcked = 0;
|
||||||
ackFrame.ackBlocks.emplace_back(0, 0);
|
ackFrame.ackBlocks.emplace_back(0, 0);
|
||||||
@@ -726,7 +729,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);
|
std::move(regularPacket), Clock::now(), 1, false, 1, 0);
|
||||||
// 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);
|
||||||
@@ -767,12 +770,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);
|
std::move(regularPacket1), Clock::now(), 1, false, 1, 0);
|
||||||
outstandingPacket1.associatedEvent.emplace(
|
outstandingPacket1.associatedEvent.emplace(
|
||||||
PacketNumberSpace::AppData, packetNum1);
|
PacketNumberSpace::AppData, packetNum1);
|
||||||
|
|
||||||
OutstandingPacket outstandingPacket2(
|
OutstandingPacket outstandingPacket2(
|
||||||
std::move(regularPacket2), Clock::now(), 1, false, 1);
|
std::move(regularPacket2), Clock::now(), 1, false, 1, 0);
|
||||||
// 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);
|
||||||
@@ -829,7 +832,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);
|
std::move(regularPacket1), Clock::now(), 1, false, 1, 0);
|
||||||
outstandingPacket1.associatedEvent.emplace(
|
outstandingPacket1.associatedEvent.emplace(
|
||||||
PacketNumberSpace::AppData, packetNum1);
|
PacketNumberSpace::AppData, packetNum1);
|
||||||
|
|
||||||
@@ -838,7 +841,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);
|
std::move(regularPacket2), Clock::now(), 1, false, 1, 0);
|
||||||
|
|
||||||
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));
|
||||||
@@ -877,7 +880,7 @@ TEST_P(AckHandlersTest, UpdateMaxAckDelay) {
|
|||||||
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(std::move(regularPacket), sentTime, 1, false, 1));
|
OutstandingPacket(std::move(regularPacket), sentTime, 1, false, 1, 0));
|
||||||
|
|
||||||
ReadAckFrame ackFrame;
|
ReadAckFrame ackFrame;
|
||||||
// ackDelay has no effect on mrtt
|
// ackDelay has no effect on mrtt
|
||||||
@@ -933,7 +936,8 @@ TEST_P(AckHandlersTest, AckNotOutstandingButLoss) {
|
|||||||
Clock::now() - delayUntilLost - 20ms,
|
Clock::now() - delayUntilLost - 20ms,
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
1);
|
1,
|
||||||
|
0);
|
||||||
conn.outstandings.packets.push_back(std::move(outstandingPacket));
|
conn.outstandings.packets.push_back(std::move(outstandingPacket));
|
||||||
conn.outstandings.clonedPacketsCount++;
|
conn.outstandings.clonedPacketsCount++;
|
||||||
|
|
||||||
@@ -976,7 +980,8 @@ TEST_P(AckHandlersTest, UpdatePendingAckStates) {
|
|||||||
sentTime,
|
sentTime,
|
||||||
111,
|
111,
|
||||||
false,
|
false,
|
||||||
conn.lossState.totalBytesSent + 111));
|
conn.lossState.totalBytesSent + 111,
|
||||||
|
0));
|
||||||
conn.lossState.totalBytesSent += 111;
|
conn.lossState.totalBytesSent += 111;
|
||||||
|
|
||||||
ReadAckFrame ackFrame;
|
ReadAckFrame ackFrame;
|
||||||
@@ -1019,7 +1024,8 @@ TEST_P(AckHandlersTest, AckEventCreation) {
|
|||||||
largestSentTime,
|
largestSentTime,
|
||||||
1,
|
1,
|
||||||
false /* handshake */,
|
false /* handshake */,
|
||||||
packetNum);
|
packetNum,
|
||||||
|
0);
|
||||||
sentPacket.isAppLimited = (packetNum % 2);
|
sentPacket.isAppLimited = (packetNum % 2);
|
||||||
conn.outstandings.packets.emplace_back(sentPacket);
|
conn.outstandings.packets.emplace_back(sentPacket);
|
||||||
packetNum++;
|
packetNum++;
|
||||||
@@ -1073,7 +1079,8 @@ TEST_P(AckHandlersTest, ImplictAckEventCreation) {
|
|||||||
largestSentTime,
|
largestSentTime,
|
||||||
1,
|
1,
|
||||||
false /* handshake */,
|
false /* handshake */,
|
||||||
packetNum);
|
packetNum,
|
||||||
|
packetNum + 1);
|
||||||
sentPacket.isAppLimited = (packetNum % 2);
|
sentPacket.isAppLimited = (packetNum % 2);
|
||||||
conn.outstandings.packets.emplace_back(sentPacket);
|
conn.outstandings.packets.emplace_back(sentPacket);
|
||||||
packetNum++;
|
packetNum++;
|
||||||
@@ -1107,6 +1114,114 @@ TEST_P(AckHandlersTest, ImplictAckEventCreation) {
|
|||||||
ackTime);
|
ackTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_P(AckHandlersTest, TestRTTPacketObserverCallback) {
|
||||||
|
QuicServerConnectionState conn(
|
||||||
|
FizzServerQuicHandshakeContext::Builder().build());
|
||||||
|
auto mockCongestionController = std::make_unique<MockCongestionController>();
|
||||||
|
conn.congestionController = std::move(mockCongestionController);
|
||||||
|
|
||||||
|
// Register 1 instrumentation observer
|
||||||
|
auto ib = MockInstrumentationObserver();
|
||||||
|
conn.instrumentationObservers_.emplace_back(&ib);
|
||||||
|
|
||||||
|
PacketNum packetNum = 0;
|
||||||
|
StreamId streamid = 0;
|
||||||
|
TimePoint sentTime;
|
||||||
|
std::vector<TimePoint> packetRcvTime;
|
||||||
|
while (packetNum < 30) {
|
||||||
|
auto regularPacket = createNewPacket(packetNum, GetParam());
|
||||||
|
WriteStreamFrame frame(streamid++, 0, 0, true);
|
||||||
|
regularPacket.frames.emplace_back(std::move(frame));
|
||||||
|
sentTime = Clock::now() - 100ms + std::chrono::milliseconds(packetNum);
|
||||||
|
packetRcvTime.emplace_back(sentTime);
|
||||||
|
OutstandingPacket sentPacket(
|
||||||
|
std::move(regularPacket),
|
||||||
|
sentTime,
|
||||||
|
1,
|
||||||
|
false /* handshake */,
|
||||||
|
packetNum,
|
||||||
|
packetNum + 1);
|
||||||
|
sentPacket.isAppLimited = false;
|
||||||
|
conn.outstandings.packets.emplace_back(sentPacket);
|
||||||
|
packetNum++;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ackPacketData {
|
||||||
|
PacketNum startSeq, endSeq;
|
||||||
|
std::chrono::milliseconds ackDelay;
|
||||||
|
TimePoint ackTime;
|
||||||
|
ReadAckFrame ackFrame;
|
||||||
|
|
||||||
|
explicit ackPacketData(
|
||||||
|
PacketNum startSeqIn,
|
||||||
|
PacketNum endSeqIn,
|
||||||
|
std::chrono::milliseconds ackDelayIn)
|
||||||
|
: startSeq(startSeqIn),
|
||||||
|
endSeq(endSeqIn),
|
||||||
|
ackDelay(ackDelayIn),
|
||||||
|
ackTime(Clock::now() + 5ms) {
|
||||||
|
ackFrame.largestAcked = endSeq;
|
||||||
|
ackFrame.ackDelay = ackDelay;
|
||||||
|
ackFrame.ackBlocks.emplace_back(startSeq, endSeq);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// See each emplace as the ACK Block [X, Y] with size (Y-X+1)
|
||||||
|
std::vector<ackPacketData> ackVec;
|
||||||
|
// Sequential test
|
||||||
|
ackVec.emplace_back(0, 5, 4ms); // +1 callback
|
||||||
|
ackVec.emplace_back(6, 10, 5ms); // +1
|
||||||
|
ackVec.emplace_back(11, 15, 6ms); // +1
|
||||||
|
// Out-of-order test
|
||||||
|
//
|
||||||
|
// Its important to check the if
|
||||||
|
// largestAcked - currentPacketNum > reorderingThreshold (currently 3)
|
||||||
|
// else it can trigger InstrumentationObserver::packetLossDetected
|
||||||
|
// and increase the number of callbacks
|
||||||
|
ackVec.emplace_back(18, 18, 0ms); // +1
|
||||||
|
ackVec.emplace_back(16, 17, 2ms); // +1
|
||||||
|
ackVec.emplace_back(19, 29, 12ms); // +1 = 6 callbacks
|
||||||
|
|
||||||
|
// 0 pending callbacks
|
||||||
|
EXPECT_EQ(0, size(conn.pendingCallbacks));
|
||||||
|
|
||||||
|
for (const auto ackData : ackVec) {
|
||||||
|
processAckFrame(
|
||||||
|
conn,
|
||||||
|
GetParam(),
|
||||||
|
ackData.ackFrame,
|
||||||
|
[](const auto&, const auto&, const auto&) {},
|
||||||
|
[](auto&, auto&, bool) {},
|
||||||
|
ackData.ackTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
// see above
|
||||||
|
EXPECT_EQ(6, size(conn.pendingCallbacks));
|
||||||
|
|
||||||
|
for (const auto ackData : ackVec) {
|
||||||
|
auto rttSample = std::chrono::duration_cast<std::chrono::microseconds>(
|
||||||
|
ackData.ackTime - packetRcvTime[ackData.endSeq]);
|
||||||
|
EXPECT_CALL(
|
||||||
|
ib,
|
||||||
|
rttSampleGenerated(AllOf(
|
||||||
|
Field(
|
||||||
|
&InstrumentationObserver::PacketRTT::rcvTime, ackData.ackTime),
|
||||||
|
Field(&InstrumentationObserver::PacketRTT::rttSample, rttSample),
|
||||||
|
Field(
|
||||||
|
&InstrumentationObserver::PacketRTT::ackDelay,
|
||||||
|
ackData.ackDelay),
|
||||||
|
Field(
|
||||||
|
&InstrumentationObserver::PacketRTT::metadata,
|
||||||
|
Field(
|
||||||
|
&quic::OutstandingPacketMetadata::inflightBytes,
|
||||||
|
ackData.endSeq + 1)))));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& callback : conn.pendingCallbacks) {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
AckHandlersTests,
|
AckHandlersTests,
|
||||||
AckHandlersTest,
|
AckHandlersTest,
|
||||||
|
@@ -553,43 +553,50 @@ TEST_F(QuicStateFunctionsTest, GetOutstandingPackets) {
|
|||||||
Clock::now(),
|
Clock::now(),
|
||||||
135,
|
135,
|
||||||
false,
|
false,
|
||||||
|
0,
|
||||||
0);
|
0);
|
||||||
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);
|
||||||
conn.outstandings.packets.emplace_back(
|
conn.outstandings.packets.emplace_back(
|
||||||
makeTestShortPacket(), Clock::now(), 5556, false, 0);
|
makeTestShortPacket(), Clock::now(), 5556, false, 0, 0);
|
||||||
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);
|
||||||
conn.outstandings.packets.emplace_back(
|
conn.outstandings.packets.emplace_back(
|
||||||
makeTestShortPacket(), Clock::now(), 6665, false, 0);
|
makeTestShortPacket(), Clock::now(), 6665, false, 0, 0);
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
135,
|
135,
|
||||||
getFirstOutstandingPacket(conn, PacketNumberSpace::Initial)->encodedSize);
|
getFirstOutstandingPacket(conn, PacketNumberSpace::Initial)
|
||||||
|
->metadata.encodedSize);
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
56,
|
56,
|
||||||
getLastOutstandingPacket(conn, PacketNumberSpace::Initial)->encodedSize);
|
getLastOutstandingPacket(conn, PacketNumberSpace::Initial)
|
||||||
|
->metadata.encodedSize);
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
1217,
|
1217,
|
||||||
getFirstOutstandingPacket(conn, PacketNumberSpace::Handshake)
|
getFirstOutstandingPacket(conn, PacketNumberSpace::Handshake)
|
||||||
->encodedSize);
|
->metadata.encodedSize);
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
1217,
|
1217,
|
||||||
getFirstOutstandingPacket(conn, PacketNumberSpace::Handshake)
|
getFirstOutstandingPacket(conn, PacketNumberSpace::Handshake)
|
||||||
->encodedSize);
|
->metadata.encodedSize);
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
5556,
|
5556,
|
||||||
getFirstOutstandingPacket(conn, PacketNumberSpace::AppData)->encodedSize);
|
getFirstOutstandingPacket(conn, PacketNumberSpace::AppData)
|
||||||
|
->metadata.encodedSize);
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
6665,
|
6665,
|
||||||
getLastOutstandingPacket(conn, PacketNumberSpace::AppData)->encodedSize);
|
getLastOutstandingPacket(conn, PacketNumberSpace::AppData)
|
||||||
|
->metadata.encodedSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(QuicStateFunctionsTest, UpdateLargestReceivePacketsAtLatCloseSent) {
|
TEST_F(QuicStateFunctionsTest, UpdateLargestReceivePacketsAtLatCloseSent) {
|
||||||
|
@@ -35,7 +35,8 @@ TEST_F(StateDataTest, SingleLostPacketEvent) {
|
|||||||
getTestConnectionId(),
|
getTestConnectionId(),
|
||||||
100,
|
100,
|
||||||
kVersion));
|
kVersion));
|
||||||
OutstandingPacket outstandingPacket(packet, Clock::now(), 1234, false, 1234);
|
OutstandingPacket outstandingPacket(
|
||||||
|
packet, Clock::now(), 1234, false, 1234, 0);
|
||||||
CongestionController::LossEvent loss;
|
CongestionController::LossEvent loss;
|
||||||
loss.addLostPacket(outstandingPacket);
|
loss.addLostPacket(outstandingPacket);
|
||||||
EXPECT_EQ(1234, loss.lostBytes);
|
EXPECT_EQ(1234, loss.lostBytes);
|
||||||
@@ -50,7 +51,7 @@ TEST_F(StateDataTest, MultipleLostPacketsEvent) {
|
|||||||
100,
|
100,
|
||||||
kVersion));
|
kVersion));
|
||||||
OutstandingPacket outstandingPacket1(
|
OutstandingPacket outstandingPacket1(
|
||||||
packet1, Clock::now(), 1234, false, 1234);
|
packet1, Clock::now(), 1234, false, 1234, 0);
|
||||||
|
|
||||||
RegularQuicWritePacket packet2(LongHeader(
|
RegularQuicWritePacket packet2(LongHeader(
|
||||||
LongHeader::Types::Initial,
|
LongHeader::Types::Initial,
|
||||||
@@ -59,7 +60,7 @@ TEST_F(StateDataTest, MultipleLostPacketsEvent) {
|
|||||||
110,
|
110,
|
||||||
kVersion));
|
kVersion));
|
||||||
OutstandingPacket outstandingPacket2(
|
OutstandingPacket outstandingPacket2(
|
||||||
packet2, Clock::now(), 1357, false, 1357);
|
packet2, Clock::now(), 1357, false, 1357, 0);
|
||||||
|
|
||||||
CongestionController::LossEvent loss;
|
CongestionController::LossEvent loss;
|
||||||
loss.addLostPacket(outstandingPacket1);
|
loss.addLostPacket(outstandingPacket1);
|
||||||
|
Reference in New Issue
Block a user