mirror of
https://github.com/facebookincubator/mvfst.git
synced 2025-08-06 22:22:38 +03:00
Always send flow control updates again when lost.
Summary: This was probably a premature optimization and introduces complexity for dubious gain. Additionally a sequence of losses could potentially cause multiple updates to be delayed. Reviewed By: yangchi Differential Revision: D23628058 fbshipit-source-id: d6cf70baec8c34f0209ea791dadc724795fe0c21
This commit is contained in:
committed by
Facebook GitHub Bot
parent
ac705d0b71
commit
325a6465ec
@@ -575,8 +575,7 @@ void updateConnection(
|
|||||||
VLOG(10) << nodeToString(conn.nodeType)
|
VLOG(10) << nodeToString(conn.nodeType)
|
||||||
<< " sent conn window update in packetNum=" << packetNum << " "
|
<< " sent conn window update in packetNum=" << packetNum << " "
|
||||||
<< conn;
|
<< conn;
|
||||||
onConnWindowUpdateSent(
|
onConnWindowUpdateSent(conn, maxDataFrame.maximumData, sentTime);
|
||||||
conn, packetNum, maxDataFrame.maximumData, sentTime);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case QuicWriteFrame::Type::DataBlockedFrame_E: {
|
case QuicWriteFrame::Type::DataBlockedFrame_E: {
|
||||||
@@ -597,7 +596,7 @@ void updateConnection(
|
|||||||
<< " sent packet with window update packetNum=" << packetNum
|
<< " sent packet with window update packetNum=" << packetNum
|
||||||
<< " stream=" << maxStreamDataFrame.streamId << " " << conn;
|
<< " stream=" << maxStreamDataFrame.streamId << " " << conn;
|
||||||
onStreamWindowUpdateSent(
|
onStreamWindowUpdateSent(
|
||||||
*stream, packetNum, maxStreamDataFrame.maximumData, sentTime);
|
*stream, maxStreamDataFrame.maximumData, sentTime);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case QuicWriteFrame::Type::StreamDataBlockedFrame_E: {
|
case QuicWriteFrame::Type::StreamDataBlockedFrame_E: {
|
||||||
@@ -1461,7 +1460,7 @@ void implicitAckCryptoStream(
|
|||||||
},
|
},
|
||||||
// We shouldn't mark anything as lost from the implicit ACK, as it should
|
// We shouldn't mark anything as lost from the implicit ACK, as it should
|
||||||
// be ACKing the entire rangee.
|
// be ACKing the entire rangee.
|
||||||
[](auto&, auto&, auto, auto) {
|
[](auto&, auto&, auto) {
|
||||||
LOG(FATAL) << "Got loss from implicit crypto ACK.";
|
LOG(FATAL) << "Got loss from implicit crypto ACK.";
|
||||||
},
|
},
|
||||||
implicitAckTime);
|
implicitAckTime);
|
||||||
|
@@ -2292,17 +2292,14 @@ TEST_F(QuicTransportImplTest, AsyncStreamFlowControlWrite) {
|
|||||||
auto stream = transport->createBidirectionalStream().value();
|
auto stream = transport->createBidirectionalStream().value();
|
||||||
auto streamState = transport->transportConn->streamManager->getStream(stream);
|
auto streamState = transport->transportConn->streamManager->getStream(stream);
|
||||||
transport->setServerConnectionId();
|
transport->setServerConnectionId();
|
||||||
EXPECT_FALSE(streamState->latestMaxStreamDataPacket.has_value());
|
|
||||||
transport->writeLooper()->stop();
|
transport->writeLooper()->stop();
|
||||||
streamState->flowControlState.advertisedMaxOffset = 0; // Easier to calculate
|
streamState->flowControlState.advertisedMaxOffset = 0; // Easier to calculate
|
||||||
transport->setStreamFlowControlWindow(stream, 4000);
|
transport->setStreamFlowControlWindow(stream, 4000);
|
||||||
EXPECT_EQ(0, streamState->flowControlState.advertisedMaxOffset);
|
EXPECT_EQ(0, streamState->flowControlState.advertisedMaxOffset);
|
||||||
EXPECT_FALSE(streamState->latestMaxStreamDataPacket.has_value());
|
|
||||||
// Loop it:
|
// Loop it:
|
||||||
EXPECT_TRUE(transport->writeLooper()->isRunning());
|
EXPECT_TRUE(transport->writeLooper()->isRunning());
|
||||||
transport->writeLooper()->runLoopCallback();
|
transport->writeLooper()->runLoopCallback();
|
||||||
EXPECT_EQ(4000, streamState->flowControlState.advertisedMaxOffset);
|
EXPECT_EQ(4000, streamState->flowControlState.advertisedMaxOffset);
|
||||||
EXPECT_TRUE(streamState->latestMaxStreamDataPacket.has_value());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(QuicTransportImplTest, ExceptionInWriteLooperDoesNotCrash) {
|
TEST_F(QuicTransportImplTest, ExceptionInWriteLooperDoesNotCrash) {
|
||||||
|
@@ -1023,7 +1023,6 @@ TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionStreamWindowUpdate) {
|
|||||||
auto conn = createConn();
|
auto conn = createConn();
|
||||||
conn->qLogger = std::make_shared<quic::FileQLogger>(VantagePoint::Client);
|
conn->qLogger = std::make_shared<quic::FileQLogger>(VantagePoint::Client);
|
||||||
auto packet = buildEmptyPacket(*conn, PacketNumberSpace::Handshake);
|
auto packet = buildEmptyPacket(*conn, PacketNumberSpace::Handshake);
|
||||||
auto packetNum = packet.packet.header.getPacketSequenceNum();
|
|
||||||
auto stream = conn->streamManager->createNextBidirectionalStream().value();
|
auto stream = conn->streamManager->createNextBidirectionalStream().value();
|
||||||
MaxStreamDataFrame streamWindowUpdate(stream->id, 0);
|
MaxStreamDataFrame streamWindowUpdate(stream->id, 0);
|
||||||
conn->streamManager->queueWindowUpdate(stream->id);
|
conn->streamManager->queueWindowUpdate(stream->id);
|
||||||
@@ -1049,18 +1048,13 @@ TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionStreamWindowUpdate) {
|
|||||||
auto frame = static_cast<MaxStreamDataFrameLog*>(event->frames[0].get());
|
auto frame = static_cast<MaxStreamDataFrameLog*>(event->frames[0].get());
|
||||||
EXPECT_EQ(frame->streamId, stream->id);
|
EXPECT_EQ(frame->streamId, stream->id);
|
||||||
EXPECT_EQ(frame->maximumData, 0);
|
EXPECT_EQ(frame->maximumData, 0);
|
||||||
|
|
||||||
EXPECT_EQ(packetNum, *stream->latestMaxStreamDataPacket);
|
|
||||||
EXPECT_FALSE(conn->latestMaxDataPacket.has_value());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionConnWindowUpdate) {
|
TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionConnWindowUpdate) {
|
||||||
auto conn = createConn();
|
auto conn = createConn();
|
||||||
conn->qLogger = std::make_shared<quic::FileQLogger>(VantagePoint::Client);
|
conn->qLogger = std::make_shared<quic::FileQLogger>(VantagePoint::Client);
|
||||||
auto packet = buildEmptyPacket(*conn, PacketNumberSpace::Handshake);
|
auto packet = buildEmptyPacket(*conn, PacketNumberSpace::Handshake);
|
||||||
auto packetNum = packet.packet.header.getPacketSequenceNum();
|
|
||||||
conn->pendingEvents.connWindowUpdate = true;
|
conn->pendingEvents.connWindowUpdate = true;
|
||||||
auto stream = conn->streamManager->createNextBidirectionalStream().value();
|
|
||||||
MaxDataFrame connWindowUpdate(conn->flowControlState.advertisedMaxOffset);
|
MaxDataFrame connWindowUpdate(conn->flowControlState.advertisedMaxOffset);
|
||||||
packet.packet.frames.push_back(std::move(connWindowUpdate));
|
packet.packet.frames.push_back(std::move(connWindowUpdate));
|
||||||
updateConnection(
|
updateConnection(
|
||||||
@@ -1082,9 +1076,6 @@ TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionConnWindowUpdate) {
|
|||||||
EXPECT_EQ(event->frames.size(), 1);
|
EXPECT_EQ(event->frames.size(), 1);
|
||||||
auto frame = static_cast<MaxDataFrameLog*>(event->frames[0].get());
|
auto frame = static_cast<MaxDataFrameLog*>(event->frames[0].get());
|
||||||
EXPECT_EQ(frame->maximumData, conn->flowControlState.advertisedMaxOffset);
|
EXPECT_EQ(frame->maximumData, conn->flowControlState.advertisedMaxOffset);
|
||||||
|
|
||||||
EXPECT_FALSE(stream->latestMaxStreamDataPacket.has_value());
|
|
||||||
EXPECT_EQ(packetNum, *conn->latestMaxDataPacket);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(QuicTransportFunctionsTest, WriteQuicDataToSocketWithCC) {
|
TEST_F(QuicTransportFunctionsTest, WriteQuicDataToSocketWithCC) {
|
||||||
|
@@ -1196,7 +1196,7 @@ TEST_F(QuicTransportTest, ResendPathChallengeOnLoss) {
|
|||||||
->packet;
|
->packet;
|
||||||
|
|
||||||
EXPECT_FALSE(conn.pendingEvents.pathChallenge);
|
EXPECT_FALSE(conn.pendingEvents.pathChallenge);
|
||||||
markPacketLoss(conn, packet, false, 2);
|
markPacketLoss(conn, packet, false);
|
||||||
EXPECT_EQ(*conn.pendingEvents.pathChallenge, pathChallenge);
|
EXPECT_EQ(*conn.pendingEvents.pathChallenge, pathChallenge);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1221,7 +1221,7 @@ TEST_F(QuicTransportTest, DoNotResendLostPathChallengeIfNotOutstanding) {
|
|||||||
transport_->getPathValidationTimeout().timeoutExpired();
|
transport_->getPathValidationTimeout().timeoutExpired();
|
||||||
|
|
||||||
EXPECT_FALSE(conn.pendingEvents.pathChallenge);
|
EXPECT_FALSE(conn.pendingEvents.pathChallenge);
|
||||||
markPacketLoss(conn, packet, false, 2);
|
markPacketLoss(conn, packet, false);
|
||||||
EXPECT_FALSE(conn.pendingEvents.pathChallenge);
|
EXPECT_FALSE(conn.pendingEvents.pathChallenge);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1332,7 +1332,7 @@ TEST_F(QuicTransportTest, DoNotResendPathResponseOnLoss) {
|
|||||||
auto packet =
|
auto packet =
|
||||||
getLastOutstandingPacket(conn, PacketNumberSpace::AppData)->packet;
|
getLastOutstandingPacket(conn, PacketNumberSpace::AppData)->packet;
|
||||||
|
|
||||||
markPacketLoss(conn, packet, false, 2);
|
markPacketLoss(conn, packet, false);
|
||||||
EXPECT_EQ(conn.pendingEvents.frames.size(), 0);
|
EXPECT_EQ(conn.pendingEvents.frames.size(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1469,7 +1469,7 @@ TEST_F(QuicTransportTest, ResendNewConnectionIdOnLoss) {
|
|||||||
->packet;
|
->packet;
|
||||||
|
|
||||||
EXPECT_TRUE(conn.pendingEvents.frames.empty());
|
EXPECT_TRUE(conn.pendingEvents.frames.empty());
|
||||||
markPacketLoss(conn, packet, false, 2);
|
markPacketLoss(conn, packet, false);
|
||||||
EXPECT_EQ(conn.pendingEvents.frames.size(), 1);
|
EXPECT_EQ(conn.pendingEvents.frames.size(), 1);
|
||||||
NewConnectionIdFrame* connIdFrame =
|
NewConnectionIdFrame* connIdFrame =
|
||||||
conn.pendingEvents.frames.front().asNewConnectionIdFrame();
|
conn.pendingEvents.frames.front().asNewConnectionIdFrame();
|
||||||
@@ -1557,7 +1557,7 @@ TEST_F(QuicTransportTest, ResendRetireConnectionIdOnLoss) {
|
|||||||
->packet;
|
->packet;
|
||||||
|
|
||||||
EXPECT_TRUE(conn.pendingEvents.frames.empty());
|
EXPECT_TRUE(conn.pendingEvents.frames.empty());
|
||||||
markPacketLoss(conn, packet, false, 2);
|
markPacketLoss(conn, packet, false);
|
||||||
EXPECT_EQ(conn.pendingEvents.frames.size(), 1);
|
EXPECT_EQ(conn.pendingEvents.frames.size(), 1);
|
||||||
RetireConnectionIdFrame* retireFrame =
|
RetireConnectionIdFrame* retireFrame =
|
||||||
conn.pendingEvents.frames.front().asRetireConnectionIdFrame();
|
conn.pendingEvents.frames.front().asRetireConnectionIdFrame();
|
||||||
|
@@ -553,7 +553,7 @@ TEST_F(BbrTest, BytesCounting) {
|
|||||||
ackFrame.largestAcked = packetNum;
|
ackFrame.largestAcked = packetNum;
|
||||||
ackFrame.ackBlocks.emplace_back(packetNum, packetNum);
|
ackFrame.ackBlocks.emplace_back(packetNum, packetNum);
|
||||||
auto ackVisitor = [&](auto&, auto&, auto&) {};
|
auto ackVisitor = [&](auto&, auto&, auto&) {};
|
||||||
auto lossVisitor = [&](auto&, auto&, bool, PacketNum) {};
|
auto lossVisitor = [&](auto&, auto&, bool) {};
|
||||||
processAckFrame(
|
processAckFrame(
|
||||||
conn,
|
conn,
|
||||||
PacketNumberSpace::AppData,
|
PacketNumberSpace::AppData,
|
||||||
|
@@ -4706,8 +4706,7 @@ TEST_F(QuicClientTransportAfterStartTest, ResetClearsPendingLoss) {
|
|||||||
|
|
||||||
RegularQuicWritePacket* forceLossPacket =
|
RegularQuicWritePacket* forceLossPacket =
|
||||||
CHECK_NOTNULL(findPacketWithStream(client->getNonConstConn(), streamId));
|
CHECK_NOTNULL(findPacketWithStream(client->getNonConstConn(), streamId));
|
||||||
auto packetNum = forceLossPacket->header.getPacketSequenceNum();
|
markPacketLoss(client->getNonConstConn(), *forceLossPacket, false);
|
||||||
markPacketLoss(client->getNonConstConn(), *forceLossPacket, false, packetNum);
|
|
||||||
auto& pendingLossStreams = client->getConn().streamManager->lossStreams();
|
auto& pendingLossStreams = client->getConn().streamManager->lossStreams();
|
||||||
auto it =
|
auto it =
|
||||||
std::find(pendingLossStreams.begin(), pendingLossStreams.end(), streamId);
|
std::find(pendingLossStreams.begin(), pendingLossStreams.end(), streamId);
|
||||||
@@ -4733,8 +4732,7 @@ TEST_F(QuicClientTransportAfterStartTest, LossAfterResetStream) {
|
|||||||
|
|
||||||
RegularQuicWritePacket* forceLossPacket =
|
RegularQuicWritePacket* forceLossPacket =
|
||||||
CHECK_NOTNULL(findPacketWithStream(client->getNonConstConn(), streamId));
|
CHECK_NOTNULL(findPacketWithStream(client->getNonConstConn(), streamId));
|
||||||
auto packetNum = forceLossPacket->header.getPacketSequenceNum();
|
markPacketLoss(client->getNonConstConn(), *forceLossPacket, false);
|
||||||
markPacketLoss(client->getNonConstConn(), *forceLossPacket, false, packetNum);
|
|
||||||
auto stream = CHECK_NOTNULL(
|
auto stream = CHECK_NOTNULL(
|
||||||
client->getNonConstConn().streamManager->getStream(streamId));
|
client->getNonConstConn().streamManager->getStream(streamId));
|
||||||
ASSERT_TRUE(stream->lossBuffer.empty());
|
ASSERT_TRUE(stream->lossBuffer.empty());
|
||||||
|
@@ -362,12 +362,9 @@ uint64_t getRecvConnFlowControlBytes(const QuicConnectionStateBase& conn) {
|
|||||||
|
|
||||||
void onConnWindowUpdateSent(
|
void onConnWindowUpdateSent(
|
||||||
QuicConnectionStateBase& conn,
|
QuicConnectionStateBase& conn,
|
||||||
PacketNum packetNum,
|
|
||||||
uint64_t maximumDataSent,
|
uint64_t maximumDataSent,
|
||||||
TimePoint sentTime) {
|
TimePoint sentTime) {
|
||||||
DCHECK_GE(maximumDataSent, conn.flowControlState.advertisedMaxOffset);
|
DCHECK_GE(maximumDataSent, conn.flowControlState.advertisedMaxOffset);
|
||||||
DCHECK_LE(conn.latestMaxDataPacket.value_or(packetNum), packetNum);
|
|
||||||
conn.latestMaxDataPacket = packetNum;
|
|
||||||
conn.flowControlState.advertisedMaxOffset = maximumDataSent;
|
conn.flowControlState.advertisedMaxOffset = maximumDataSent;
|
||||||
conn.flowControlState.timeOfLastFlowControlUpdate = sentTime;
|
conn.flowControlState.timeOfLastFlowControlUpdate = sentTime;
|
||||||
conn.pendingEvents.connWindowUpdate = false;
|
conn.pendingEvents.connWindowUpdate = false;
|
||||||
@@ -376,11 +373,8 @@ void onConnWindowUpdateSent(
|
|||||||
|
|
||||||
void onStreamWindowUpdateSent(
|
void onStreamWindowUpdateSent(
|
||||||
QuicStreamState& stream,
|
QuicStreamState& stream,
|
||||||
PacketNum packetNum,
|
|
||||||
uint64_t maximumDataSent,
|
uint64_t maximumDataSent,
|
||||||
TimePoint sentTime) {
|
TimePoint sentTime) {
|
||||||
DCHECK_LE(stream.latestMaxStreamDataPacket.value_or(packetNum), packetNum);
|
|
||||||
stream.latestMaxStreamDataPacket = packetNum;
|
|
||||||
stream.flowControlState.advertisedMaxOffset = maximumDataSent;
|
stream.flowControlState.advertisedMaxOffset = maximumDataSent;
|
||||||
stream.flowControlState.timeOfLastFlowControlUpdate = sentTime;
|
stream.flowControlState.timeOfLastFlowControlUpdate = sentTime;
|
||||||
stream.conn.streamManager->removeWindowUpdate(stream.id);
|
stream.conn.streamManager->removeWindowUpdate(stream.id);
|
||||||
|
@@ -60,13 +60,11 @@ void handleConnBlocked(QuicConnectionStateBase& conn);
|
|||||||
|
|
||||||
void onStreamWindowUpdateSent(
|
void onStreamWindowUpdateSent(
|
||||||
QuicStreamState& stream,
|
QuicStreamState& stream,
|
||||||
PacketNum packetNum,
|
|
||||||
uint64_t maximumData,
|
uint64_t maximumData,
|
||||||
TimePoint sentTime);
|
TimePoint sentTime);
|
||||||
|
|
||||||
void onConnWindowUpdateSent(
|
void onConnWindowUpdateSent(
|
||||||
QuicConnectionStateBase& conn,
|
QuicConnectionStateBase& conn,
|
||||||
PacketNum pacektNum,
|
|
||||||
uint64_t maximumData,
|
uint64_t maximumData,
|
||||||
TimePoint sentTime);
|
TimePoint sentTime);
|
||||||
|
|
||||||
|
@@ -157,21 +157,13 @@ TEST_F(QuicFlowControlTest, GenerateMaxDataFrameChangeWindowLarger) {
|
|||||||
conn_.flowControlState.sumCurReadOffset = 301;
|
conn_.flowControlState.sumCurReadOffset = 301;
|
||||||
auto frame = generateMaxDataFrame(conn_);
|
auto frame = generateMaxDataFrame(conn_);
|
||||||
EXPECT_EQ(801, frame.maximumData);
|
EXPECT_EQ(801, frame.maximumData);
|
||||||
onConnWindowUpdateSent(
|
onConnWindowUpdateSent(conn_, frame.maximumData, Clock::now());
|
||||||
conn_,
|
|
||||||
conn_.ackStates.appDataAckState.nextPacketNum,
|
|
||||||
frame.maximumData,
|
|
||||||
Clock::now());
|
|
||||||
EXPECT_EQ(801, conn_.flowControlState.advertisedMaxOffset);
|
EXPECT_EQ(801, conn_.flowControlState.advertisedMaxOffset);
|
||||||
|
|
||||||
conn_.flowControlState.windowSize = 1001;
|
conn_.flowControlState.windowSize = 1001;
|
||||||
auto frame2 = generateMaxDataFrame(conn_);
|
auto frame2 = generateMaxDataFrame(conn_);
|
||||||
EXPECT_EQ(1302, frame2.maximumData);
|
EXPECT_EQ(1302, frame2.maximumData);
|
||||||
onConnWindowUpdateSent(
|
onConnWindowUpdateSent(conn_, frame2.maximumData, Clock::now());
|
||||||
conn_,
|
|
||||||
conn_.ackStates.appDataAckState.nextPacketNum,
|
|
||||||
frame2.maximumData,
|
|
||||||
Clock::now());
|
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
frame2.maximumData,
|
frame2.maximumData,
|
||||||
conn_.flowControlState.sumCurReadOffset +
|
conn_.flowControlState.sumCurReadOffset +
|
||||||
@@ -262,13 +254,7 @@ TEST_F(QuicFlowControlTest, MaybeSendStreamWindowUpdateChangeWindowSmaller) {
|
|||||||
ASSERT_TRUE(conn_.streamManager->pendingWindowUpdate(stream.id));
|
ASSERT_TRUE(conn_.streamManager->pendingWindowUpdate(stream.id));
|
||||||
auto sendTime = Clock::now();
|
auto sendTime = Clock::now();
|
||||||
onStreamWindowUpdateSent(
|
onStreamWindowUpdateSent(
|
||||||
stream,
|
stream, generateMaxStreamDataFrame(stream).maximumData, sendTime);
|
||||||
conn_.ackStates.appDataAckState.nextPacketNum,
|
|
||||||
generateMaxStreamDataFrame(stream).maximumData,
|
|
||||||
sendTime);
|
|
||||||
EXPECT_EQ(
|
|
||||||
conn_.ackStates.appDataAckState.nextPacketNum,
|
|
||||||
*stream.latestMaxStreamDataPacket);
|
|
||||||
|
|
||||||
stream.flowControlState.windowSize = 10;
|
stream.flowControlState.windowSize = 10;
|
||||||
// change the read bytes to be within the maybeSendUpdate size of the previous
|
// change the read bytes to be within the maybeSendUpdate size of the previous
|
||||||
@@ -346,13 +332,7 @@ TEST_F(QuicFlowControlTest, MaybeSendStreamWindowUpdateChangeWindowLarger) {
|
|||||||
maybeSendStreamWindowUpdate(stream, Clock::now());
|
maybeSendStreamWindowUpdate(stream, Clock::now());
|
||||||
EXPECT_TRUE(conn_.streamManager->pendingWindowUpdate(stream.id));
|
EXPECT_TRUE(conn_.streamManager->pendingWindowUpdate(stream.id));
|
||||||
onStreamWindowUpdateSent(
|
onStreamWindowUpdateSent(
|
||||||
stream,
|
stream, generateMaxStreamDataFrame(stream).maximumData, Clock::now());
|
||||||
conn_.ackStates.appDataAckState.nextPacketNum,
|
|
||||||
generateMaxStreamDataFrame(stream).maximumData,
|
|
||||||
Clock::now());
|
|
||||||
EXPECT_EQ(
|
|
||||||
conn_.ackStates.appDataAckState.nextPacketNum,
|
|
||||||
*stream.latestMaxStreamDataPacket);
|
|
||||||
EXPECT_FALSE(conn_.streamManager->pendingWindowUpdate(stream.id));
|
EXPECT_FALSE(conn_.streamManager->pendingWindowUpdate(stream.id));
|
||||||
|
|
||||||
stream.flowControlState.windowSize = 1001;
|
stream.flowControlState.windowSize = 1001;
|
||||||
@@ -378,14 +358,7 @@ TEST_F(QuicFlowControlTest, SendingConnectionWindowUpdate) {
|
|||||||
|
|
||||||
// Clear out the window update.
|
// Clear out the window update.
|
||||||
auto sendTime = Clock::now();
|
auto sendTime = Clock::now();
|
||||||
onConnWindowUpdateSent(
|
onConnWindowUpdateSent(conn_, frameOffset, sendTime);
|
||||||
conn_,
|
|
||||||
conn_.ackStates.appDataAckState.nextPacketNum,
|
|
||||||
frameOffset,
|
|
||||||
sendTime);
|
|
||||||
EXPECT_EQ(
|
|
||||||
conn_.ackStates.appDataAckState.nextPacketNum,
|
|
||||||
*conn_.latestMaxDataPacket);
|
|
||||||
EXPECT_FALSE(conn_.pendingEvents.connWindowUpdate);
|
EXPECT_FALSE(conn_.pendingEvents.connWindowUpdate);
|
||||||
EXPECT_EQ(conn_.flowControlState.advertisedMaxOffset, frameOffset);
|
EXPECT_EQ(conn_.flowControlState.advertisedMaxOffset, frameOffset);
|
||||||
EXPECT_EQ(*conn_.flowControlState.timeOfLastFlowControlUpdate, sendTime);
|
EXPECT_EQ(*conn_.flowControlState.timeOfLastFlowControlUpdate, sendTime);
|
||||||
@@ -406,14 +379,7 @@ TEST_F(QuicFlowControlTest, SendingStreamWindowUpdate) {
|
|||||||
EXPECT_EQ(800, frameOffset);
|
EXPECT_EQ(800, frameOffset);
|
||||||
|
|
||||||
auto sendTime = Clock::now();
|
auto sendTime = Clock::now();
|
||||||
onStreamWindowUpdateSent(
|
onStreamWindowUpdateSent(stream, frameOffset, sendTime);
|
||||||
stream,
|
|
||||||
conn_.ackStates.appDataAckState.nextPacketNum,
|
|
||||||
frameOffset,
|
|
||||||
sendTime);
|
|
||||||
EXPECT_EQ(
|
|
||||||
conn_.ackStates.appDataAckState.nextPacketNum,
|
|
||||||
*stream.latestMaxStreamDataPacket);
|
|
||||||
EXPECT_FALSE(conn_.streamManager->pendingWindowUpdate(stream.id));
|
EXPECT_FALSE(conn_.streamManager->pendingWindowUpdate(stream.id));
|
||||||
EXPECT_EQ(stream.flowControlState.advertisedMaxOffset, frameOffset);
|
EXPECT_EQ(stream.flowControlState.advertisedMaxOffset, frameOffset);
|
||||||
EXPECT_EQ(*stream.flowControlState.timeOfLastFlowControlUpdate, sendTime);
|
EXPECT_EQ(*stream.flowControlState.timeOfLastFlowControlUpdate, sendTime);
|
||||||
@@ -844,11 +810,7 @@ TEST_F(QuicFlowControlTest, OnConnWindowUpdateSentWithoutPendingEvent) {
|
|||||||
conn_.flowControlState.windowSize = 1000;
|
conn_.flowControlState.windowSize = 1000;
|
||||||
conn_.flowControlState.advertisedMaxOffset = 0;
|
conn_.flowControlState.advertisedMaxOffset = 0;
|
||||||
conn_.flowControlState.sumCurReadOffset = 0;
|
conn_.flowControlState.sumCurReadOffset = 0;
|
||||||
onConnWindowUpdateSent(
|
onConnWindowUpdateSent(conn_, 1000, Clock::now());
|
||||||
conn_, conn_.ackStates.appDataAckState.nextPacketNum, 1000, Clock::now());
|
|
||||||
EXPECT_EQ(
|
|
||||||
conn_.ackStates.appDataAckState.nextPacketNum,
|
|
||||||
*conn_.latestMaxDataPacket);
|
|
||||||
EXPECT_EQ(1000, conn_.flowControlState.advertisedMaxOffset);
|
EXPECT_EQ(1000, conn_.flowControlState.advertisedMaxOffset);
|
||||||
EXPECT_FALSE(conn_.pendingEvents.connWindowUpdate);
|
EXPECT_FALSE(conn_.pendingEvents.connWindowUpdate);
|
||||||
}
|
}
|
||||||
@@ -859,14 +821,7 @@ TEST_F(QuicFlowControlTest, OnStreamWindowUpdateSentWithoutPendingEvent) {
|
|||||||
stream.currentReadOffset = 0;
|
stream.currentReadOffset = 0;
|
||||||
stream.flowControlState.advertisedMaxOffset = 0;
|
stream.flowControlState.advertisedMaxOffset = 0;
|
||||||
stream.flowControlState.windowSize = 1000;
|
stream.flowControlState.windowSize = 1000;
|
||||||
onStreamWindowUpdateSent(
|
onStreamWindowUpdateSent(stream, 1000, Clock::now());
|
||||||
stream,
|
|
||||||
conn_.ackStates.appDataAckState.nextPacketNum,
|
|
||||||
1000,
|
|
||||||
Clock::now());
|
|
||||||
EXPECT_EQ(
|
|
||||||
conn_.ackStates.appDataAckState.nextPacketNum,
|
|
||||||
*stream.latestMaxStreamDataPacket);
|
|
||||||
EXPECT_EQ(1000, stream.flowControlState.advertisedMaxOffset);
|
EXPECT_EQ(1000, stream.flowControlState.advertisedMaxOffset);
|
||||||
EXPECT_FALSE(conn_.streamManager->pendingWindowUpdate(id));
|
EXPECT_FALSE(conn_.streamManager->pendingWindowUpdate(id));
|
||||||
}
|
}
|
||||||
|
@@ -63,8 +63,7 @@ void onPTOAlarm(QuicConnectionStateBase& conn) {
|
|||||||
void markPacketLoss(
|
void markPacketLoss(
|
||||||
QuicConnectionStateBase& conn,
|
QuicConnectionStateBase& conn,
|
||||||
RegularQuicWritePacket& packet,
|
RegularQuicWritePacket& packet,
|
||||||
bool processed,
|
bool processed) {
|
||||||
PacketNum currentPacketNum) {
|
|
||||||
QUIC_STATS(conn.statsCallback, onPacketLoss);
|
QUIC_STATS(conn.statsCallback, onPacketLoss);
|
||||||
for (auto& packetFrame : packet.frames) {
|
for (auto& packetFrame : packet.frames) {
|
||||||
switch (packetFrame.type()) {
|
switch (packetFrame.type()) {
|
||||||
@@ -72,26 +71,19 @@ void markPacketLoss(
|
|||||||
MaxStreamDataFrame& frame = *packetFrame.asMaxStreamDataFrame();
|
MaxStreamDataFrame& frame = *packetFrame.asMaxStreamDataFrame();
|
||||||
// For all other frames, we process it if it's not from a clone
|
// For all other frames, we process it if it's not from a clone
|
||||||
// packet, or if the clone and its siblings have never been processed.
|
// packet, or if the clone and its siblings have never been processed.
|
||||||
// But for both MaxData and MaxStreamData, clone and its siblings may
|
// But for both MaxData and MaxStreamData, we opportunistically send
|
||||||
// have different values. So we process it if it matches the
|
// an update to avoid stalling the peer.
|
||||||
// latestMaxDataPacket or latestMaxStreamDataPacket. If an older
|
|
||||||
// packet also has such frames, it's ok to skip process of such loss
|
|
||||||
// since newer value is already sent in later packets.
|
|
||||||
auto stream = conn.streamManager->getStream(frame.streamId);
|
auto stream = conn.streamManager->getStream(frame.streamId);
|
||||||
if (!stream) {
|
if (!stream) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// TODO: check for the stream is in Open or HalfClosedLocal state, the
|
// TODO: check for the stream is in Open or HalfClosedLocal state, the
|
||||||
// peer doesn't need a flow control update in these cases.
|
// peer doesn't need a flow control update in these cases.
|
||||||
if (stream->latestMaxStreamDataPacket == currentPacketNum) {
|
onStreamWindowUpdateLost(*stream);
|
||||||
onStreamWindowUpdateLost(*stream);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case QuicWriteFrame::Type::MaxDataFrame_E: {
|
case QuicWriteFrame::Type::MaxDataFrame_E: {
|
||||||
if (conn.latestMaxDataPacket == currentPacketNum) {
|
onConnWindowUpdateLost(conn);
|
||||||
onConnWindowUpdateLost(conn);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// For other frame types, we only process them if the packet is not a
|
// For other frame types, we only process them if the packet is not a
|
||||||
|
@@ -236,7 +236,7 @@ folly::Optional<CongestionController::LossEvent> detectLossPackets(
|
|||||||
// or if the PacketEvent is present in conn.outstandings.packetEvents.
|
// or if the PacketEvent is present in conn.outstandings.packetEvents.
|
||||||
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, currentPacketNum);
|
lossVisitor(conn, pkt.packet, processed);
|
||||||
// Remove the PacketEvent from the outstandings.packetEvents set
|
// Remove the PacketEvent from the outstandings.packetEvents set
|
||||||
if (pkt.associatedEvent) {
|
if (pkt.associatedEvent) {
|
||||||
conn.outstandings.packetEvents.erase(*pkt.associatedEvent);
|
conn.outstandings.packetEvents.erase(*pkt.associatedEvent);
|
||||||
@@ -354,8 +354,7 @@ void onLossDetectionAlarm(
|
|||||||
void markPacketLoss(
|
void markPacketLoss(
|
||||||
QuicConnectionStateBase& conn,
|
QuicConnectionStateBase& conn,
|
||||||
RegularQuicWritePacket& packet,
|
RegularQuicWritePacket& packet,
|
||||||
bool processed,
|
bool processed);
|
||||||
PacketNum currentPacketNum);
|
|
||||||
|
|
||||||
template <class LossVisitor>
|
template <class LossVisitor>
|
||||||
folly::Optional<CongestionController::LossEvent> handleAckForLoss(
|
folly::Optional<CongestionController::LossEvent> handleAckForLoss(
|
||||||
@@ -408,10 +407,9 @@ void markZeroRttPacketsLost(
|
|||||||
if (isZeroRttPacket) {
|
if (isZeroRttPacket) {
|
||||||
auto& pkt = *iter;
|
auto& pkt = *iter;
|
||||||
DCHECK(!pkt.isHandshake);
|
DCHECK(!pkt.isHandshake);
|
||||||
auto currentPacketNum = pkt.packet.header.getPacketSequenceNum();
|
|
||||||
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, currentPacketNum);
|
lossVisitor(conn, pkt.packet, processed);
|
||||||
// Remove the PacketEvent from the outstandings.packetEvents set
|
// Remove the PacketEvent from the outstandings.packetEvents set
|
||||||
if (pkt.associatedEvent) {
|
if (pkt.associatedEvent) {
|
||||||
conn.outstandings.packetEvents.erase(*pkt.associatedEvent);
|
conn.outstandings.packetEvents.erase(*pkt.associatedEvent);
|
||||||
|
@@ -124,8 +124,7 @@ class QuicLossFunctionsTest : public TestWithParam<PacketNumberSpace> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
auto testingLossMarkFunc(std::vector<PacketNum>& lostPackets) {
|
auto testingLossMarkFunc(std::vector<PacketNum>& lostPackets) {
|
||||||
return [&lostPackets](
|
return [&lostPackets](auto& /* conn */, auto& packet, bool processed) {
|
||||||
auto& /* conn */, auto& packet, bool processed, PacketNum) {
|
|
||||||
if (!processed) {
|
if (!processed) {
|
||||||
auto packetNum = packet.header.getPacketSequenceNum();
|
auto packetNum = packet.header.getPacketSequenceNum();
|
||||||
lostPackets.push_back(packetNum);
|
lostPackets.push_back(packetNum);
|
||||||
@@ -279,7 +278,7 @@ TEST_F(QuicLossFunctionsTest, ClearEarlyRetranTimer) {
|
|||||||
ASSERT_GT(secondPacketNum, firstPacketNum);
|
ASSERT_GT(secondPacketNum, firstPacketNum);
|
||||||
ASSERT_EQ(2, conn->outstandings.packets.size());
|
ASSERT_EQ(2, conn->outstandings.packets.size());
|
||||||
// detectLossPackets will set lossTime on Initial space.
|
// detectLossPackets will set lossTime on Initial space.
|
||||||
auto lossVisitor = [](auto&, auto&, bool, PacketNum) { ASSERT_FALSE(true); };
|
auto lossVisitor = [](auto&, auto&, bool) { ASSERT_FALSE(true); };
|
||||||
detectLossPackets(
|
detectLossPackets(
|
||||||
*conn,
|
*conn,
|
||||||
secondPacketNum,
|
secondPacketNum,
|
||||||
@@ -420,8 +419,7 @@ TEST_F(QuicLossFunctionsTest, TestMarkPacketLoss) {
|
|||||||
EXPECT_EQ(1, conn->outstandings.packets.size());
|
EXPECT_EQ(1, conn->outstandings.packets.size());
|
||||||
auto& packet =
|
auto& packet =
|
||||||
getFirstOutstandingPacket(*conn, PacketNumberSpace::AppData)->packet;
|
getFirstOutstandingPacket(*conn, PacketNumberSpace::AppData)->packet;
|
||||||
auto packetNum = packet.header.getPacketSequenceNum();
|
markPacketLoss(*conn, packet, false);
|
||||||
markPacketLoss(*conn, packet, false, packetNum);
|
|
||||||
EXPECT_EQ(stream1->retransmissionBuffer.size(), 0);
|
EXPECT_EQ(stream1->retransmissionBuffer.size(), 0);
|
||||||
EXPECT_EQ(stream2->retransmissionBuffer.size(), 0);
|
EXPECT_EQ(stream2->retransmissionBuffer.size(), 0);
|
||||||
EXPECT_EQ(stream1->lossBuffer.size(), 1);
|
EXPECT_EQ(stream1->lossBuffer.size(), 1);
|
||||||
@@ -471,13 +469,13 @@ TEST_F(QuicLossFunctionsTest, TestMarkPacketLossMerge) {
|
|||||||
auto& packet1 =
|
auto& packet1 =
|
||||||
getFirstOutstandingPacket(*conn, PacketNumberSpace::AppData)->packet;
|
getFirstOutstandingPacket(*conn, PacketNumberSpace::AppData)->packet;
|
||||||
auto packetNum = packet1.header.getPacketSequenceNum();
|
auto packetNum = packet1.header.getPacketSequenceNum();
|
||||||
markPacketLoss(*conn, packet1, false, packetNum);
|
markPacketLoss(*conn, packet1, false);
|
||||||
EXPECT_EQ(stream1->retransmissionBuffer.size(), 1);
|
EXPECT_EQ(stream1->retransmissionBuffer.size(), 1);
|
||||||
EXPECT_EQ(stream1->lossBuffer.size(), 1);
|
EXPECT_EQ(stream1->lossBuffer.size(), 1);
|
||||||
auto& packet2 =
|
auto& packet2 =
|
||||||
getLastOutstandingPacket(*conn, PacketNumberSpace::AppData)->packet;
|
getLastOutstandingPacket(*conn, PacketNumberSpace::AppData)->packet;
|
||||||
packetNum = packet2.header.getPacketSequenceNum();
|
packetNum = packet2.header.getPacketSequenceNum();
|
||||||
markPacketLoss(*conn, packet2, false, packetNum);
|
markPacketLoss(*conn, packet2, false);
|
||||||
EXPECT_EQ(stream1->retransmissionBuffer.size(), 0);
|
EXPECT_EQ(stream1->retransmissionBuffer.size(), 0);
|
||||||
EXPECT_EQ(stream1->lossBuffer.size(), 1);
|
EXPECT_EQ(stream1->lossBuffer.size(), 1);
|
||||||
|
|
||||||
@@ -540,13 +538,13 @@ TEST_F(QuicLossFunctionsTest, TestMarkPacketLossNoMerge) {
|
|||||||
auto& packet1 =
|
auto& packet1 =
|
||||||
getFirstOutstandingPacket(*conn, PacketNumberSpace::AppData)->packet;
|
getFirstOutstandingPacket(*conn, PacketNumberSpace::AppData)->packet;
|
||||||
auto packetNum = packet1.header.getPacketSequenceNum();
|
auto packetNum = packet1.header.getPacketSequenceNum();
|
||||||
markPacketLoss(*conn, packet1, false, packetNum);
|
markPacketLoss(*conn, packet1, false);
|
||||||
EXPECT_EQ(stream1->retransmissionBuffer.size(), 2);
|
EXPECT_EQ(stream1->retransmissionBuffer.size(), 2);
|
||||||
EXPECT_EQ(stream1->lossBuffer.size(), 1);
|
EXPECT_EQ(stream1->lossBuffer.size(), 1);
|
||||||
auto& packet3 =
|
auto& packet3 =
|
||||||
getLastOutstandingPacket(*conn, PacketNumberSpace::AppData)->packet;
|
getLastOutstandingPacket(*conn, PacketNumberSpace::AppData)->packet;
|
||||||
packetNum = packet3.header.getPacketSequenceNum();
|
packetNum = packet3.header.getPacketSequenceNum();
|
||||||
markPacketLoss(*conn, packet3, false, packetNum);
|
markPacketLoss(*conn, packet3, false);
|
||||||
EXPECT_EQ(stream1->retransmissionBuffer.size(), 1);
|
EXPECT_EQ(stream1->retransmissionBuffer.size(), 1);
|
||||||
EXPECT_EQ(stream1->lossBuffer.size(), 2);
|
EXPECT_EQ(stream1->lossBuffer.size(), 2);
|
||||||
|
|
||||||
@@ -592,8 +590,7 @@ TEST_F(QuicLossFunctionsTest, RetxBufferSortedAfterLoss) {
|
|||||||
EXPECT_EQ(3, stream->retransmissionBuffer.size());
|
EXPECT_EQ(3, stream->retransmissionBuffer.size());
|
||||||
EXPECT_EQ(3, conn->outstandings.packets.size());
|
EXPECT_EQ(3, conn->outstandings.packets.size());
|
||||||
auto packet = conn->outstandings.packets[folly::Random::rand32() % 3];
|
auto packet = conn->outstandings.packets[folly::Random::rand32() % 3];
|
||||||
markPacketLoss(
|
markPacketLoss(*conn, packet.packet, false);
|
||||||
*conn, packet.packet, false, packet.packet.header.getPacketSequenceNum());
|
|
||||||
EXPECT_EQ(2, stream->retransmissionBuffer.size());
|
EXPECT_EQ(2, stream->retransmissionBuffer.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -624,9 +621,8 @@ TEST_F(QuicLossFunctionsTest, TestMarkCryptoLostAfterCancelRetransmission) {
|
|||||||
ASSERT_EQ(conn->outstandings.packets.size(), 1);
|
ASSERT_EQ(conn->outstandings.packets.size(), 1);
|
||||||
EXPECT_GT(conn->cryptoState->handshakeStream.retransmissionBuffer.size(), 0);
|
EXPECT_GT(conn->cryptoState->handshakeStream.retransmissionBuffer.size(), 0);
|
||||||
auto& packet = conn->outstandings.packets.front().packet;
|
auto& packet = conn->outstandings.packets.front().packet;
|
||||||
auto packetNum = packet.header.getPacketSequenceNum();
|
|
||||||
cancelHandshakeCryptoStreamRetransmissions(*conn->cryptoState);
|
cancelHandshakeCryptoStreamRetransmissions(*conn->cryptoState);
|
||||||
markPacketLoss(*conn, packet, false, packetNum);
|
markPacketLoss(*conn, packet, false);
|
||||||
EXPECT_EQ(conn->cryptoState->handshakeStream.retransmissionBuffer.size(), 0);
|
EXPECT_EQ(conn->cryptoState->handshakeStream.retransmissionBuffer.size(), 0);
|
||||||
EXPECT_EQ(conn->cryptoState->handshakeStream.lossBuffer.size(), 0);
|
EXPECT_EQ(conn->cryptoState->handshakeStream.lossBuffer.size(), 0);
|
||||||
}
|
}
|
||||||
@@ -658,8 +654,7 @@ TEST_F(QuicLossFunctionsTest, TestMarkCryptoLostCancel) {
|
|||||||
ASSERT_EQ(conn->outstandings.packets.size(), 1);
|
ASSERT_EQ(conn->outstandings.packets.size(), 1);
|
||||||
EXPECT_GT(conn->cryptoState->handshakeStream.retransmissionBuffer.size(), 0);
|
EXPECT_GT(conn->cryptoState->handshakeStream.retransmissionBuffer.size(), 0);
|
||||||
auto& packet = conn->outstandings.packets.front().packet;
|
auto& packet = conn->outstandings.packets.front().packet;
|
||||||
auto packetNum = packet.header.getPacketSequenceNum();
|
markPacketLoss(*conn, packet, false);
|
||||||
markPacketLoss(*conn, packet, false, packetNum);
|
|
||||||
EXPECT_EQ(conn->cryptoState->handshakeStream.retransmissionBuffer.size(), 0);
|
EXPECT_EQ(conn->cryptoState->handshakeStream.retransmissionBuffer.size(), 0);
|
||||||
EXPECT_EQ(conn->cryptoState->handshakeStream.lossBuffer.size(), 1);
|
EXPECT_EQ(conn->cryptoState->handshakeStream.lossBuffer.size(), 1);
|
||||||
cancelHandshakeCryptoStreamRetransmissions(*conn->cryptoState);
|
cancelHandshakeCryptoStreamRetransmissions(*conn->cryptoState);
|
||||||
@@ -684,7 +679,7 @@ TEST_F(QuicLossFunctionsTest, TestMarkPacketLossAfterStreamReset) {
|
|||||||
true);
|
true);
|
||||||
sendRstSMHandler(*stream1, GenericApplicationErrorCode::UNKNOWN);
|
sendRstSMHandler(*stream1, GenericApplicationErrorCode::UNKNOWN);
|
||||||
|
|
||||||
markPacketLoss(*conn, packet, false, packet.header.getPacketSequenceNum());
|
markPacketLoss(*conn, packet, false);
|
||||||
|
|
||||||
EXPECT_TRUE(stream1->lossBuffer.empty());
|
EXPECT_TRUE(stream1->lossBuffer.empty());
|
||||||
EXPECT_TRUE(stream1->retransmissionBuffer.empty());
|
EXPECT_TRUE(stream1->retransmissionBuffer.empty());
|
||||||
@@ -701,11 +696,10 @@ TEST_F(QuicLossFunctionsTest, TestReorderingThreshold) {
|
|||||||
EXPECT_CALL(*rawCongestionController, onPacketSent(_))
|
EXPECT_CALL(*rawCongestionController, onPacketSent(_))
|
||||||
.WillRepeatedly(Return());
|
.WillRepeatedly(Return());
|
||||||
|
|
||||||
auto testingLossMarkFunc =
|
auto testingLossMarkFunc = [&lostPacket](auto& /*conn*/, auto& packet, bool) {
|
||||||
[&lostPacket](auto& /*conn*/, auto& packet, bool, PacketNum) {
|
auto packetNum = packet.header.getPacketSequenceNum();
|
||||||
auto packetNum = packet.header.getPacketSequenceNum();
|
lostPacket.push_back(packetNum);
|
||||||
lostPacket.push_back(packetNum);
|
};
|
||||||
};
|
|
||||||
for (int i = 0; i < 6; ++i) {
|
for (int i = 0; i < 6; ++i) {
|
||||||
sendPacket(*conn, Clock::now(), folly::none, PacketType::Handshake);
|
sendPacket(*conn, Clock::now(), folly::none, PacketType::Handshake);
|
||||||
}
|
}
|
||||||
@@ -771,7 +765,7 @@ TEST_F(QuicLossFunctionsTest, TestHandleAckForLoss) {
|
|||||||
OutstandingPacket(outstandingRegularPacket, now, 0, false, 0));
|
OutstandingPacket(outstandingRegularPacket, now, 0, false, 0));
|
||||||
|
|
||||||
bool testLossMarkFuncCalled = false;
|
bool testLossMarkFuncCalled = false;
|
||||||
auto testLossMarkFunc = [&](auto& /* conn */, auto&, bool, PacketNum) {
|
auto testLossMarkFunc = [&](auto& /* conn */, auto&, bool) {
|
||||||
testLossMarkFuncCalled = true;
|
testLossMarkFuncCalled = true;
|
||||||
};
|
};
|
||||||
EXPECT_CALL(*mockQLogger, addPacketsLost(1, 0, 1));
|
EXPECT_CALL(*mockQLogger, addPacketsLost(1, 0, 1));
|
||||||
@@ -809,7 +803,7 @@ TEST_F(QuicLossFunctionsTest, TestHandleAckedPacket) {
|
|||||||
conn->lossState.largestSent.value_or(0));
|
conn->lossState.largestSent.value_or(0));
|
||||||
|
|
||||||
bool testLossMarkFuncCalled = false;
|
bool testLossMarkFuncCalled = false;
|
||||||
auto testLossMarkFunc = [&](auto& /* conn */, auto&, bool, PacketNum) {
|
auto testLossMarkFunc = [&](auto& /* conn */, auto&, bool) {
|
||||||
testLossMarkFuncCalled = true;
|
testLossMarkFuncCalled = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -858,7 +852,7 @@ TEST_F(QuicLossFunctionsTest, TestMarkRstLoss) {
|
|||||||
EXPECT_TRUE(conn->pendingEvents.resets.empty());
|
EXPECT_TRUE(conn->pendingEvents.resets.empty());
|
||||||
auto& packet =
|
auto& packet =
|
||||||
getFirstOutstandingPacket(*conn, PacketNumberSpace::AppData)->packet;
|
getFirstOutstandingPacket(*conn, PacketNumberSpace::AppData)->packet;
|
||||||
markPacketLoss(*conn, packet, false, packet.header.getPacketSequenceNum());
|
markPacketLoss(*conn, packet, false);
|
||||||
|
|
||||||
EXPECT_EQ(1, conn->pendingEvents.resets.size());
|
EXPECT_EQ(1, conn->pendingEvents.resets.size());
|
||||||
EXPECT_EQ(1, conn->pendingEvents.resets.count(stream->id));
|
EXPECT_EQ(1, conn->pendingEvents.resets.count(stream->id));
|
||||||
@@ -897,14 +891,12 @@ TEST_F(QuicLossFunctionsTest, TestMarkRstLoss) {
|
|||||||
TEST_F(QuicLossFunctionsTest, ReorderingThresholdChecksSamePacketNumberSpace) {
|
TEST_F(QuicLossFunctionsTest, ReorderingThresholdChecksSamePacketNumberSpace) {
|
||||||
auto conn = createConn();
|
auto conn = createConn();
|
||||||
uint16_t lossVisitorCount = 0;
|
uint16_t lossVisitorCount = 0;
|
||||||
auto countingLossVisitor = [&](auto& /* conn */,
|
auto countingLossVisitor =
|
||||||
auto& /* packet */,
|
[&](auto& /* conn */, auto& /* packet */, bool processed) {
|
||||||
bool processed,
|
if (!processed) {
|
||||||
PacketNum /* currentPacketNum */) {
|
lossVisitorCount++;
|
||||||
if (!processed) {
|
}
|
||||||
lossVisitorCount++;
|
};
|
||||||
}
|
|
||||||
};
|
|
||||||
PacketNum latestSent = 0;
|
PacketNum latestSent = 0;
|
||||||
for (size_t i = 0; i < conn->lossState.reorderingThreshold + 1; i++) {
|
for (size_t i = 0; i < conn->lossState.reorderingThreshold + 1; i++) {
|
||||||
latestSent =
|
latestSent =
|
||||||
@@ -950,8 +942,7 @@ TEST_F(QuicLossFunctionsTest, TestMarkWindowUpdateLoss) {
|
|||||||
auto& packet =
|
auto& packet =
|
||||||
getFirstOutstandingPacket(*conn, PacketNumberSpace::AppData)->packet;
|
getFirstOutstandingPacket(*conn, PacketNumberSpace::AppData)->packet;
|
||||||
|
|
||||||
auto packetNum = packet.header.getPacketSequenceNum();
|
markPacketLoss(*conn, packet, false);
|
||||||
markPacketLoss(*conn, packet, false, packetNum);
|
|
||||||
EXPECT_TRUE(conn->streamManager->pendingWindowUpdate(stream->id));
|
EXPECT_TRUE(conn->streamManager->pendingWindowUpdate(stream->id));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1178,14 +1169,12 @@ TEST_F(QuicLossFunctionsTest, NoSkipLossVisitor) {
|
|||||||
// make srtt large so delayUntilLost won't kick in
|
// make srtt large so delayUntilLost won't kick in
|
||||||
conn->lossState.srtt = 1000000000us;
|
conn->lossState.srtt = 1000000000us;
|
||||||
uint16_t lossVisitorCount = 0;
|
uint16_t lossVisitorCount = 0;
|
||||||
auto countingLossVisitor = [&](auto& /* conn */,
|
auto countingLossVisitor =
|
||||||
auto& /* packet */,
|
[&](auto& /* conn */, auto& /* packet */, bool processed) {
|
||||||
bool processed,
|
if (!processed) {
|
||||||
PacketNum /* currentPacketNum */) {
|
lossVisitorCount++;
|
||||||
if (!processed) {
|
}
|
||||||
lossVisitorCount++;
|
};
|
||||||
}
|
|
||||||
};
|
|
||||||
// Send 5 packets, so when we ack the last one, we mark the first one loss
|
// Send 5 packets, so when we ack the last one, we mark the first one loss
|
||||||
PacketNum lastSent;
|
PacketNum lastSent;
|
||||||
for (size_t i = 0; i < 5; i++) {
|
for (size_t i = 0; i < 5; i++) {
|
||||||
@@ -1206,14 +1195,12 @@ TEST_F(QuicLossFunctionsTest, SkipLossVisitor) {
|
|||||||
// make srtt large so delayUntilLost won't kick in
|
// make srtt large so delayUntilLost won't kick in
|
||||||
conn->lossState.srtt = 1000000000us;
|
conn->lossState.srtt = 1000000000us;
|
||||||
uint16_t lossVisitorCount = 0;
|
uint16_t lossVisitorCount = 0;
|
||||||
auto countingLossVisitor = [&](auto& /* conn */,
|
auto countingLossVisitor =
|
||||||
auto& /* packet */,
|
[&](auto& /* conn */, auto& /* packet */, bool processed) {
|
||||||
bool processed,
|
if (!processed) {
|
||||||
PacketNum /* currentPacketNum */) {
|
lossVisitorCount++;
|
||||||
if (!processed) {
|
}
|
||||||
lossVisitorCount++;
|
};
|
||||||
}
|
|
||||||
};
|
|
||||||
// Send 5 packets, so when we ack the last one, we mark the first one loss
|
// Send 5 packets, so when we ack the last one, we mark the first one loss
|
||||||
PacketNum lastSent;
|
PacketNum lastSent;
|
||||||
for (size_t i = 0; i < 5; i++) {
|
for (size_t i = 0; i < 5; i++) {
|
||||||
@@ -1237,14 +1224,12 @@ TEST_F(QuicLossFunctionsTest, NoDoubleProcess) {
|
|||||||
conn->lossState.srtt = 1000000000us;
|
conn->lossState.srtt = 1000000000us;
|
||||||
|
|
||||||
uint16_t lossVisitorCount = 0;
|
uint16_t lossVisitorCount = 0;
|
||||||
auto countingLossVisitor = [&](auto& /* conn */,
|
auto countingLossVisitor =
|
||||||
auto& /* packet */,
|
[&](auto& /* conn */, auto& /* packet */, bool processed) {
|
||||||
bool processed,
|
if (!processed) {
|
||||||
PacketNum /* currentPacketNum */) {
|
lossVisitorCount++;
|
||||||
if (!processed) {
|
}
|
||||||
lossVisitorCount++;
|
};
|
||||||
}
|
|
||||||
};
|
|
||||||
// Send 6 packets, so when we ack the last one, we mark the first two loss
|
// Send 6 packets, so when we ack the last one, we mark the first two loss
|
||||||
PacketNum lastSent;
|
PacketNum lastSent;
|
||||||
PacketEvent event(PacketNumberSpace::AppData, 0);
|
PacketEvent event(PacketNumberSpace::AppData, 0);
|
||||||
@@ -1283,7 +1268,7 @@ TEST_F(QuicLossFunctionsTest, DetectPacketLossClonedPacketsCounter) {
|
|||||||
sendPacket(*conn, Clock::now(), folly::none, PacketType::OneRtt);
|
sendPacket(*conn, Clock::now(), folly::none, PacketType::OneRtt);
|
||||||
auto ackedPacket =
|
auto ackedPacket =
|
||||||
sendPacket(*conn, Clock::now(), folly::none, PacketType::OneRtt);
|
sendPacket(*conn, Clock::now(), folly::none, PacketType::OneRtt);
|
||||||
auto noopLossMarker = [](auto&, auto&, bool, PacketNum) {};
|
auto noopLossMarker = [](auto&, auto&, bool) {};
|
||||||
detectLossPackets<decltype(noopLossMarker)>(
|
detectLossPackets<decltype(noopLossMarker)>(
|
||||||
*conn,
|
*conn,
|
||||||
ackedPacket,
|
ackedPacket,
|
||||||
@@ -1305,7 +1290,6 @@ TEST_F(QuicLossFunctionsTest, TestMarkPacketLossProcessedPacket) {
|
|||||||
conn->streamManager->createNextBidirectionalStream().value()->id;
|
conn->streamManager->createNextBidirectionalStream().value()->id;
|
||||||
conn->streamManager->queueWindowUpdate(stream2Id);
|
conn->streamManager->queueWindowUpdate(stream2Id);
|
||||||
conn->pendingEvents.connWindowUpdate = true;
|
conn->pendingEvents.connWindowUpdate = true;
|
||||||
auto nextPacketNum = conn->ackStates.appDataAckState.nextPacketNum;
|
|
||||||
// writeQuicPacket will call writeQuicDataToSocket which will also take care
|
// writeQuicPacket will call writeQuicDataToSocket which will also take care
|
||||||
// of sending the MaxStreamDataFrame for stream2
|
// of sending the MaxStreamDataFrame for stream2
|
||||||
auto stream1 = conn->streamManager->findStream(stream1Id);
|
auto stream1 = conn->streamManager->findStream(stream1Id);
|
||||||
@@ -1345,7 +1329,7 @@ TEST_F(QuicLossFunctionsTest, TestMarkPacketLossProcessedPacket) {
|
|||||||
EXPECT_EQ(1, streamWindowUpdateCounter);
|
EXPECT_EQ(1, streamWindowUpdateCounter);
|
||||||
EXPECT_EQ(1, connWindowUpdateCounter);
|
EXPECT_EQ(1, connWindowUpdateCounter);
|
||||||
// Force this packet to be a processed clone
|
// Force this packet to be a processed clone
|
||||||
markPacketLoss(*conn, packet, true, nextPacketNum);
|
markPacketLoss(*conn, packet, true);
|
||||||
EXPECT_EQ(1, stream1->retransmissionBuffer.size());
|
EXPECT_EQ(1, stream1->retransmissionBuffer.size());
|
||||||
EXPECT_TRUE(stream1->lossBuffer.empty());
|
EXPECT_TRUE(stream1->lossBuffer.empty());
|
||||||
|
|
||||||
@@ -1389,14 +1373,12 @@ TEST_F(QuicLossFunctionsTest, TotalLossCount) {
|
|||||||
}
|
}
|
||||||
EXPECT_EQ(10, conn->outstandings.packets.size());
|
EXPECT_EQ(10, conn->outstandings.packets.size());
|
||||||
uint32_t lostPackets = 0;
|
uint32_t lostPackets = 0;
|
||||||
auto countingLossVisitor = [&](auto& /* conn */,
|
auto countingLossVisitor =
|
||||||
auto& /* packet */,
|
[&](auto& /* conn */, auto& /* packet */, bool processed) {
|
||||||
bool processed,
|
if (!processed) {
|
||||||
PacketNum /* currentPacketNum */) {
|
lostPackets++;
|
||||||
if (!processed) {
|
}
|
||||||
lostPackets++;
|
};
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
conn->lossState.rtxCount = 135;
|
conn->lossState.rtxCount = 135;
|
||||||
detectLossPackets(
|
detectLossPackets(
|
||||||
@@ -1423,17 +1405,16 @@ TEST_F(QuicLossFunctionsTest, TestZeroRttRejected) {
|
|||||||
}
|
}
|
||||||
EXPECT_FALSE(conn->outstandings.packets.empty());
|
EXPECT_FALSE(conn->outstandings.packets.empty());
|
||||||
EXPECT_EQ(4, conn->outstandings.packets.size());
|
EXPECT_EQ(4, conn->outstandings.packets.size());
|
||||||
std::vector<std::pair<PacketNum, bool>> lostPackets;
|
std::vector<bool> lostPackets;
|
||||||
// onRemoveBytesFromInflight should still happen
|
// onRemoveBytesFromInflight should still happen
|
||||||
EXPECT_CALL(*rawCongestionController, onRemoveBytesFromInflight(_)).Times(1);
|
EXPECT_CALL(*rawCongestionController, onRemoveBytesFromInflight(_)).Times(1);
|
||||||
markZeroRttPacketsLost(
|
markZeroRttPacketsLost(*conn, [&lostPackets](auto&, auto&, bool processed) {
|
||||||
*conn, [&lostPackets](auto&, auto&, bool processed, PacketNum packetNum) {
|
lostPackets.emplace_back(processed);
|
||||||
lostPackets.emplace_back(packetNum, processed);
|
});
|
||||||
});
|
|
||||||
EXPECT_EQ(2, conn->outstandings.packets.size());
|
EXPECT_EQ(2, conn->outstandings.packets.size());
|
||||||
EXPECT_EQ(lostPackets.size(), 2);
|
EXPECT_EQ(lostPackets.size(), 2);
|
||||||
for (auto lostPacket : lostPackets) {
|
for (auto lostPacket : lostPackets) {
|
||||||
EXPECT_FALSE(lostPacket.second);
|
EXPECT_FALSE(lostPacket);
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < conn->outstandings.packets.size(); ++i) {
|
for (size_t i = 0; i < conn->outstandings.packets.size(); ++i) {
|
||||||
auto longHeader = conn->outstandings.packets[i].packet.header.asLong();
|
auto longHeader = conn->outstandings.packets[i].packet.header.asLong();
|
||||||
@@ -1473,20 +1454,19 @@ TEST_F(QuicLossFunctionsTest, TestZeroRttRejectedWithClones) {
|
|||||||
ASSERT_EQ(conn->outstandings.clonedPacketsCount, 6);
|
ASSERT_EQ(conn->outstandings.clonedPacketsCount, 6);
|
||||||
ASSERT_EQ(conn->outstandings.packetEvents.size(), 2);
|
ASSERT_EQ(conn->outstandings.packetEvents.size(), 2);
|
||||||
|
|
||||||
std::vector<std::pair<PacketNum, bool>> lostPackets;
|
std::vector<bool> lostPackets;
|
||||||
// onRemoveBytesFromInflight should still happen
|
// onRemoveBytesFromInflight should still happen
|
||||||
EXPECT_CALL(*rawCongestionController, onRemoveBytesFromInflight(_)).Times(1);
|
EXPECT_CALL(*rawCongestionController, onRemoveBytesFromInflight(_)).Times(1);
|
||||||
markZeroRttPacketsLost(
|
markZeroRttPacketsLost(*conn, [&lostPackets](auto&, auto&, bool processed) {
|
||||||
*conn, [&lostPackets](auto&, auto&, bool processed, PacketNum packetNum) {
|
lostPackets.emplace_back(processed);
|
||||||
lostPackets.emplace_back(packetNum, processed);
|
});
|
||||||
});
|
|
||||||
ASSERT_EQ(conn->outstandings.packetEvents.size(), 0);
|
ASSERT_EQ(conn->outstandings.packetEvents.size(), 0);
|
||||||
EXPECT_EQ(3, conn->outstandings.packets.size());
|
EXPECT_EQ(3, conn->outstandings.packets.size());
|
||||||
EXPECT_EQ(lostPackets.size(), 3);
|
EXPECT_EQ(lostPackets.size(), 3);
|
||||||
ASSERT_EQ(conn->outstandings.clonedPacketsCount, 3);
|
ASSERT_EQ(conn->outstandings.clonedPacketsCount, 3);
|
||||||
size_t numProcessed = 0;
|
size_t numProcessed = 0;
|
||||||
for (auto lostPacket : lostPackets) {
|
for (auto lostPacket : lostPackets) {
|
||||||
numProcessed += lostPacket.second;
|
numProcessed += lostPacket;
|
||||||
}
|
}
|
||||||
EXPECT_EQ(numProcessed, 1);
|
EXPECT_EQ(numProcessed, 1);
|
||||||
for (size_t i = 0; i < conn->outstandings.packets.size(); ++i) {
|
for (size_t i = 0; i < conn->outstandings.packets.size(); ++i) {
|
||||||
@@ -1521,11 +1501,8 @@ TEST_F(QuicLossFunctionsTest, TimeThreshold) {
|
|||||||
referenceTime + conn->lossState.srtt / 2,
|
referenceTime + conn->lossState.srtt / 2,
|
||||||
folly::none,
|
folly::none,
|
||||||
PacketType::OneRtt);
|
PacketType::OneRtt);
|
||||||
auto lossVisitor = [&](const auto& /*conn*/,
|
auto lossVisitor = [&](const auto& /*conn*/, const auto& packet, bool) {
|
||||||
const auto& /*packet*/,
|
EXPECT_EQ(packet1, packet.header.getPacketSequenceNum());
|
||||||
bool,
|
|
||||||
PacketNum packetNum) {
|
|
||||||
EXPECT_EQ(packet1, packetNum);
|
|
||||||
};
|
};
|
||||||
detectLossPackets<decltype(lossVisitor)>(
|
detectLossPackets<decltype(lossVisitor)>(
|
||||||
*conn,
|
*conn,
|
||||||
@@ -1545,10 +1522,9 @@ TEST_F(QuicLossFunctionsTest, OutstandingInitialCounting) {
|
|||||||
sendPacket(*conn, Clock::now(), folly::none, PacketType::Initial);
|
sendPacket(*conn, Clock::now(), folly::none, PacketType::Initial);
|
||||||
}
|
}
|
||||||
EXPECT_EQ(10, conn->outstandings.initialPacketsCount);
|
EXPECT_EQ(10, conn->outstandings.initialPacketsCount);
|
||||||
auto noopLossVisitor = [&](auto& /* conn */,
|
auto noopLossVisitor =
|
||||||
auto& /* packet */,
|
[&](auto& /* conn */, auto& /* packet */, bool /* processed */
|
||||||
bool /* processed */,
|
) {};
|
||||||
PacketNum /* currentPacketNum */) {};
|
|
||||||
detectLossPackets(
|
detectLossPackets(
|
||||||
*conn,
|
*conn,
|
||||||
largestSent,
|
largestSent,
|
||||||
@@ -1569,10 +1545,9 @@ TEST_F(QuicLossFunctionsTest, OutstandingHandshakeCounting) {
|
|||||||
sendPacket(*conn, Clock::now(), folly::none, PacketType::Handshake);
|
sendPacket(*conn, Clock::now(), folly::none, PacketType::Handshake);
|
||||||
}
|
}
|
||||||
EXPECT_EQ(10, conn->outstandings.handshakePacketsCount);
|
EXPECT_EQ(10, conn->outstandings.handshakePacketsCount);
|
||||||
auto noopLossVisitor = [&](auto& /* conn */,
|
auto noopLossVisitor =
|
||||||
auto& /* packet */,
|
[&](auto& /* conn */, auto& /* packet */, bool /* processed */
|
||||||
bool /* processed */,
|
) {};
|
||||||
PacketNum /* currentPacketNum */) {};
|
|
||||||
detectLossPackets(
|
detectLossPackets(
|
||||||
*conn,
|
*conn,
|
||||||
largestSent,
|
largestSent,
|
||||||
|
@@ -1733,11 +1733,7 @@ TEST_F(QuicServerTransportTest, StopSendingLoss) {
|
|||||||
ASSERT_TRUE(builder.canBuildPacket());
|
ASSERT_TRUE(builder.canBuildPacket());
|
||||||
writeFrame(QuicSimpleFrame(stopSendingFrame), builder);
|
writeFrame(QuicSimpleFrame(stopSendingFrame), builder);
|
||||||
auto packet = std::move(builder).buildPacket();
|
auto packet = std::move(builder).buildPacket();
|
||||||
markPacketLoss(
|
markPacketLoss(server->getNonConstConn(), packet.packet, false);
|
||||||
server->getNonConstConn(),
|
|
||||||
packet.packet,
|
|
||||||
false,
|
|
||||||
clientNextAppDataPacketNum);
|
|
||||||
EXPECT_EQ(server->getNonConstConn().pendingEvents.frames.size(), 1);
|
EXPECT_EQ(server->getNonConstConn().pendingEvents.frames.size(), 1);
|
||||||
StopSendingFrame* stopFrame = server->getNonConstConn()
|
StopSendingFrame* stopFrame = server->getNonConstConn()
|
||||||
.pendingEvents.frames.front()
|
.pendingEvents.frames.front()
|
||||||
@@ -1769,11 +1765,7 @@ TEST_F(QuicServerTransportTest, StopSendingLossAfterStreamClosed) {
|
|||||||
// clear out all the streams, this is not a great way to simulate closed
|
// clear out all the streams, this is not a great way to simulate closed
|
||||||
// streams, but good enough for this test.
|
// streams, but good enough for this test.
|
||||||
server->getNonConstConn().streamManager->clearOpenStreams();
|
server->getNonConstConn().streamManager->clearOpenStreams();
|
||||||
markPacketLoss(
|
markPacketLoss(server->getNonConstConn(), packet.packet, false);
|
||||||
server->getNonConstConn(),
|
|
||||||
packet.packet,
|
|
||||||
false,
|
|
||||||
server->getNonConstConn().ackStates.appDataAckState.nextPacketNum);
|
|
||||||
EXPECT_EQ(server->getNonConstConn().pendingEvents.frames.size(), 0);
|
EXPECT_EQ(server->getNonConstConn().pendingEvents.frames.size(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -19,7 +19,7 @@ using AckVisitor = std::function<
|
|||||||
void(const OutstandingPacket&, const QuicWriteFrame&, const ReadAckFrame&)>;
|
void(const OutstandingPacket&, const QuicWriteFrame&, const ReadAckFrame&)>;
|
||||||
|
|
||||||
using LossVisitor = std::function<
|
using LossVisitor = std::function<
|
||||||
void(QuicConnectionStateBase&, RegularQuicWritePacket&, bool, PacketNum)>;
|
void(QuicConnectionStateBase&, RegularQuicWritePacket&, bool)>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Processes an ack frame and removes any outstanding packets
|
* Processes an ack frame and removes any outstanding packets
|
||||||
|
@@ -757,10 +757,6 @@ struct QuicConnectionStateBase : public folly::DelayedDestruction {
|
|||||||
|
|
||||||
PacketSchedulingState schedulingState;
|
PacketSchedulingState schedulingState;
|
||||||
|
|
||||||
// The packet number of the latest packet that contains a MaxDataFrame sent
|
|
||||||
// out by us.
|
|
||||||
folly::Optional<PacketNum> latestMaxDataPacket;
|
|
||||||
|
|
||||||
// Logger for this connection.
|
// Logger for this connection.
|
||||||
std::shared_ptr<Logger> logger;
|
std::shared_ptr<Logger> logger;
|
||||||
|
|
||||||
|
@@ -193,10 +193,6 @@ struct QuicStreamState : public QuicStreamLike {
|
|||||||
// State machine data
|
// State machine data
|
||||||
StreamRecvState recvState{StreamRecvState::Open_E};
|
StreamRecvState recvState{StreamRecvState::Open_E};
|
||||||
|
|
||||||
// The packet number of the latest packet that contains a MaxStreamDataFrame
|
|
||||||
// sent out by us.
|
|
||||||
folly::Optional<PacketNum> latestMaxStreamDataPacket;
|
|
||||||
|
|
||||||
// Tells whether this stream is a control stream.
|
// Tells whether this stream is a control stream.
|
||||||
// It is set by the app via setControlStream and the transport can use this
|
// It is set by the app via setControlStream and the transport can use this
|
||||||
// knowledge for optimizations e.g. for setting the app limited state on
|
// knowledge for optimizations e.g. for setting the app limited state on
|
||||||
|
@@ -28,11 +28,10 @@ namespace test {
|
|||||||
class AckHandlersTest : public TestWithParam<PacketNumberSpace> {};
|
class AckHandlersTest : public TestWithParam<PacketNumberSpace> {};
|
||||||
|
|
||||||
auto testLossHandler(std::vector<PacketNum>& lostPackets) -> decltype(auto) {
|
auto testLossHandler(std::vector<PacketNum>& lostPackets) -> decltype(auto) {
|
||||||
return
|
return [&lostPackets](QuicConnectionStateBase&, auto& packet, bool) {
|
||||||
[&lostPackets](QuicConnectionStateBase&, auto& packet, bool, PacketNum) {
|
auto packetNum = packet.header.getPacketSequenceNum();
|
||||||
auto packetNum = packet.header.getPacketSequenceNum();
|
lostPackets.push_back(packetNum);
|
||||||
lostPackets.push_back(packetNum);
|
};
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(AckHandlersTest, TestAckMultipleSequentialBlocks) {
|
TEST_P(AckHandlersTest, TestAckMultipleSequentialBlocks) {
|
||||||
@@ -214,7 +213,7 @@ TEST_P(AckHandlersTest, TestAckMultipleSequentialBlocksLoss) {
|
|||||||
GetParam(),
|
GetParam(),
|
||||||
ackFrame,
|
ackFrame,
|
||||||
[](auto, auto, auto) {},
|
[](auto, auto, auto) {},
|
||||||
[](auto&, auto&, auto, auto) {},
|
[](auto&, auto&, auto) {},
|
||||||
Clock::now());
|
Clock::now());
|
||||||
itr = std::find_if(
|
itr = std::find_if(
|
||||||
conn.outstandings.packets.begin(),
|
conn.outstandings.packets.begin(),
|
||||||
@@ -231,7 +230,7 @@ TEST_P(AckHandlersTest, TestAckMultipleSequentialBlocksLoss) {
|
|||||||
GetParam(),
|
GetParam(),
|
||||||
ackFrame,
|
ackFrame,
|
||||||
[](auto, auto, auto) {},
|
[](auto, auto, auto) {},
|
||||||
[](auto&, auto&, auto, auto) {},
|
[](auto&, auto&, auto) {},
|
||||||
Clock::now() + 2 * calculatePTO(conn));
|
Clock::now() + 2 * calculatePTO(conn));
|
||||||
|
|
||||||
numDeclaredLost = std::count_if(
|
numDeclaredLost = std::count_if(
|
||||||
@@ -477,10 +476,8 @@ TEST_P(AckHandlersTest, AckVisitorForAckTest) {
|
|||||||
commonAckVisitorForAckFrame(conn.ackStates.appDataAckState, *frame);
|
commonAckVisitorForAckFrame(conn.ackStates.appDataAckState, *frame);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[](auto& /* conn */,
|
[](auto& /* conn */, auto& /* packet */, bool /* processed */
|
||||||
auto& /* packet */,
|
) {},
|
||||||
bool /* processed */,
|
|
||||||
PacketNum /* currentPacketNum */) {},
|
|
||||||
Clock::now());
|
Clock::now());
|
||||||
EXPECT_EQ(2, conn.ackStates.appDataAckState.acks.size());
|
EXPECT_EQ(2, conn.ackStates.appDataAckState.acks.size());
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
@@ -503,10 +500,8 @@ TEST_P(AckHandlersTest, AckVisitorForAckTest) {
|
|||||||
commonAckVisitorForAckFrame(conn.ackStates.appDataAckState, *frame);
|
commonAckVisitorForAckFrame(conn.ackStates.appDataAckState, *frame);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[](auto& /* conn */,
|
[](auto& /* conn */, auto& /* packet */, bool /* processed */
|
||||||
auto& /* packet */,
|
) {},
|
||||||
bool /* processed */,
|
|
||||||
PacketNum /* currentPacketNum */) {},
|
|
||||||
Clock::now());
|
Clock::now());
|
||||||
EXPECT_TRUE(conn.ackStates.appDataAckState.acks.empty());
|
EXPECT_TRUE(conn.ackStates.appDataAckState.acks.empty());
|
||||||
}
|
}
|
||||||
@@ -532,7 +527,7 @@ TEST_P(AckHandlersTest, NoNewAckedPacket) {
|
|||||||
GetParam(),
|
GetParam(),
|
||||||
ackFrame,
|
ackFrame,
|
||||||
[](const auto&, const auto&, const auto&) {},
|
[](const auto&, const auto&, const auto&) {},
|
||||||
[](auto&, auto&, bool, PacketNum) {},
|
[](auto&, auto&, bool) {},
|
||||||
Clock::now());
|
Clock::now());
|
||||||
EXPECT_TRUE(conn.pendingEvents.setLossDetectionAlarm);
|
EXPECT_TRUE(conn.pendingEvents.setLossDetectionAlarm);
|
||||||
EXPECT_EQ(conn.lossState.ptoCount, 1);
|
EXPECT_EQ(conn.lossState.ptoCount, 1);
|
||||||
@@ -553,7 +548,7 @@ TEST_P(AckHandlersTest, LossByAckedRecovered) {
|
|||||||
GetParam(),
|
GetParam(),
|
||||||
ackFrame,
|
ackFrame,
|
||||||
[](const auto&, const auto&, const auto&) {},
|
[](const auto&, const auto&, const auto&) {},
|
||||||
[](auto&, auto&, bool, PacketNum) {},
|
[](auto&, auto&, bool) {},
|
||||||
Clock::now());
|
Clock::now());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -586,7 +581,7 @@ TEST_P(AckHandlersTest, AckPacketNumDoesNotExist) {
|
|||||||
GetParam(),
|
GetParam(),
|
||||||
ackFrame,
|
ackFrame,
|
||||||
[](const auto&, const auto&, const auto&) {},
|
[](const auto&, const auto&, const auto&) {},
|
||||||
[](auto&, auto&, bool, PacketNum) {},
|
[](auto&, auto&, bool) {},
|
||||||
Clock::now());
|
Clock::now());
|
||||||
EXPECT_EQ(1, conn.outstandings.packets.size());
|
EXPECT_EQ(1, conn.outstandings.packets.size());
|
||||||
}
|
}
|
||||||
@@ -705,10 +700,8 @@ TEST_P(AckHandlersTest, NoSkipAckVisitor) {
|
|||||||
GetParam(),
|
GetParam(),
|
||||||
ackFrame,
|
ackFrame,
|
||||||
countingAckVisitor,
|
countingAckVisitor,
|
||||||
[&](auto& /*conn*/,
|
[&](auto& /*conn*/, auto& /* packet */, bool /* processed */
|
||||||
auto& /* packet */,
|
) { /* no-op lossVisitor */ },
|
||||||
bool /* processed */,
|
|
||||||
PacketNum) { /* no-op lossVisitor */ },
|
|
||||||
Clock::now());
|
Clock::now());
|
||||||
EXPECT_EQ(1, ackVisitorCounter);
|
EXPECT_EQ(1, ackVisitorCounter);
|
||||||
}
|
}
|
||||||
@@ -755,10 +748,8 @@ TEST_P(AckHandlersTest, SkipAckVisitor) {
|
|||||||
GetParam(),
|
GetParam(),
|
||||||
ackFrame,
|
ackFrame,
|
||||||
countingAckVisitor,
|
countingAckVisitor,
|
||||||
[&](auto& /*conn*/,
|
[&](auto& /*conn*/, auto& /* packet */, bool /* processed */
|
||||||
auto& /* packet */,
|
) { /* no-op lossVisitor */ },
|
||||||
bool /* processed */,
|
|
||||||
PacketNum) { /* no-op lossVisitor */ },
|
|
||||||
Clock::now());
|
Clock::now());
|
||||||
EXPECT_EQ(0, ackVisitorCounter);
|
EXPECT_EQ(0, ackVisitorCounter);
|
||||||
}
|
}
|
||||||
@@ -809,10 +800,8 @@ TEST_P(AckHandlersTest, NoDoubleProcess) {
|
|||||||
GetParam(),
|
GetParam(),
|
||||||
ackFrame1,
|
ackFrame1,
|
||||||
countingAckVisitor,
|
countingAckVisitor,
|
||||||
[&](auto& /*conn*/,
|
[&](auto& /*conn*/, auto& /* packet */, bool /* processed */
|
||||||
auto& /* packet */,
|
) { /* no-op lossVisitor */ },
|
||||||
bool /* processed */,
|
|
||||||
PacketNum) { /* no-op lossVisitor */ },
|
|
||||||
Clock::now());
|
Clock::now());
|
||||||
EXPECT_EQ(1, ackVisitorCounter);
|
EXPECT_EQ(1, ackVisitorCounter);
|
||||||
|
|
||||||
@@ -825,10 +814,8 @@ TEST_P(AckHandlersTest, NoDoubleProcess) {
|
|||||||
GetParam(),
|
GetParam(),
|
||||||
ackFrame2,
|
ackFrame2,
|
||||||
countingAckVisitor,
|
countingAckVisitor,
|
||||||
[&](auto& /* conn */,
|
[&](auto& /* conn */, auto& /* packet */, bool /* processed */
|
||||||
auto& /* packet */,
|
) { /* no-op */ },
|
||||||
bool /* processed */,
|
|
||||||
PacketNum) { /* no-op */ },
|
|
||||||
Clock::now());
|
Clock::now());
|
||||||
EXPECT_EQ(1, ackVisitorCounter);
|
EXPECT_EQ(1, ackVisitorCounter);
|
||||||
}
|
}
|
||||||
@@ -874,10 +861,8 @@ TEST_P(AckHandlersTest, ClonedPacketsCounter) {
|
|||||||
GetParam(),
|
GetParam(),
|
||||||
ackFrame,
|
ackFrame,
|
||||||
countingAckVisitor,
|
countingAckVisitor,
|
||||||
[&](auto& /* conn */,
|
[&](auto& /* conn */, auto& /* packet */, bool /* processed */
|
||||||
auto& /* packet */,
|
) { /* no-op */ },
|
||||||
bool /* processed */,
|
|
||||||
PacketNum) { /* no-op */ },
|
|
||||||
Clock::now());
|
Clock::now());
|
||||||
EXPECT_EQ(2, ackVisitorCounter);
|
EXPECT_EQ(2, ackVisitorCounter);
|
||||||
EXPECT_EQ(0, conn.outstandings.clonedPacketsCount);
|
EXPECT_EQ(0, conn.outstandings.clonedPacketsCount);
|
||||||
@@ -906,7 +891,7 @@ TEST_P(AckHandlersTest, UpdateMaxAckDelay) {
|
|||||||
GetParam(),
|
GetParam(),
|
||||||
ackFrame,
|
ackFrame,
|
||||||
[&](const auto&, const auto&, const auto&) { /* ackVisitor */ },
|
[&](const auto&, const auto&, const auto&) { /* ackVisitor */ },
|
||||||
[&](auto&, auto&, bool, PacketNum) { /* lossVisitor */ },
|
[&](auto&, auto&, bool) { /* lossVisitor */ },
|
||||||
receiveTime);
|
receiveTime);
|
||||||
EXPECT_EQ(10us, conn.lossState.mrtt);
|
EXPECT_EQ(10us, conn.lossState.mrtt);
|
||||||
}
|
}
|
||||||
@@ -971,10 +956,8 @@ TEST_P(AckHandlersTest, AckNotOutstandingButLoss) {
|
|||||||
PacketNumberSpace::AppData,
|
PacketNumberSpace::AppData,
|
||||||
ackFrame,
|
ackFrame,
|
||||||
countingAckVisitor,
|
countingAckVisitor,
|
||||||
[&](auto& /*conn*/,
|
[&](auto& /*conn*/, auto& /* packet */, bool /* processed */
|
||||||
auto& /* packet */,
|
) { /* no-op lossVisitor */ },
|
||||||
bool /* processed */,
|
|
||||||
PacketNum) { /* no-op lossVisitor */ },
|
|
||||||
Clock::now());
|
Clock::now());
|
||||||
EXPECT_EQ(0, ackVisitorCounter);
|
EXPECT_EQ(0, ackVisitorCounter);
|
||||||
}
|
}
|
||||||
@@ -1006,7 +989,7 @@ TEST_P(AckHandlersTest, UpdatePendingAckStates) {
|
|||||||
GetParam(),
|
GetParam(),
|
||||||
ackFrame,
|
ackFrame,
|
||||||
[&](auto, auto, auto) { /* ackVisitor */ },
|
[&](auto, auto, auto) { /* ackVisitor */ },
|
||||||
[&](auto&, auto&, auto, auto) { /* lossVisitor */ },
|
[&](auto&, auto&, auto) { /* lossVisitor */ },
|
||||||
receiveTime);
|
receiveTime);
|
||||||
EXPECT_EQ(2468 + 111, conn.lossState.totalBytesSentAtLastAck);
|
EXPECT_EQ(2468 + 111, conn.lossState.totalBytesSentAtLastAck);
|
||||||
EXPECT_EQ(1357 + 111, conn.lossState.totalBytesAckedAtLastAck);
|
EXPECT_EQ(1357 + 111, conn.lossState.totalBytesAckedAtLastAck);
|
||||||
@@ -1065,7 +1048,7 @@ TEST_P(AckHandlersTest, AckEventCreation) {
|
|||||||
GetParam(),
|
GetParam(),
|
||||||
ackFrame,
|
ackFrame,
|
||||||
[](const auto&, const auto&, const auto&) {},
|
[](const auto&, const auto&, const auto&) {},
|
||||||
[](auto&, auto&, bool, PacketNum) {},
|
[](auto&, auto&, bool) {},
|
||||||
ackTime);
|
ackTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user