mirror of
https://github.com/facebookincubator/mvfst.git
synced 2025-08-08 09:42:06 +03:00
Record stream details in packet metadata
Summary: Introruced a new DetailsPerStream struct inside the outstanding packet metadata so we can easily track all streams carrying app data within a packet and each stream's bytes sent (both new and total). With this, consumers can easily deduce the number of retransmitted bytes per stream using the StreamDetails members: newStreamBytesSent - streamBytesSent. Reviewed By: bschlinker Differential Revision: D28063916 fbshipit-source-id: d915514f85f24f4889cfac2f7a66bfd2d6b0a4af
This commit is contained in:
committed by
Facebook GitHub Bot
parent
488df14977
commit
7246cd5e3c
@@ -602,6 +602,7 @@ void updateConnection(
|
|||||||
uint32_t ackFrameCounter = 0;
|
uint32_t ackFrameCounter = 0;
|
||||||
uint32_t streamBytesSent = 0;
|
uint32_t streamBytesSent = 0;
|
||||||
uint32_t newStreamBytesSent = 0;
|
uint32_t newStreamBytesSent = 0;
|
||||||
|
OutstandingPacket::Metadata::DetailsPerStream detailsPerStream;
|
||||||
auto packetNumberSpace = packet.header.getPacketNumberSpace();
|
auto packetNumberSpace = packet.header.getPacketNumberSpace();
|
||||||
bool isD6DProbe = packetNumberSpace == PacketNumberSpace::AppData &&
|
bool isD6DProbe = packetNumberSpace == PacketNumberSpace::AppData &&
|
||||||
conn.d6d.lastProbe.hasValue() &&
|
conn.d6d.lastProbe.hasValue() &&
|
||||||
@@ -651,6 +652,7 @@ void updateConnection(
|
|||||||
conn.streamManager->updateWritableStreams(*stream);
|
conn.streamManager->updateWritableStreams(*stream);
|
||||||
conn.streamManager->updateLossStreams(*stream);
|
conn.streamManager->updateLossStreams(*stream);
|
||||||
streamBytesSent += writeStreamFrame.len;
|
streamBytesSent += writeStreamFrame.len;
|
||||||
|
detailsPerStream.addFrame(writeStreamFrame, newStreamDataWritten);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case QuicWriteFrame::Type::WriteCryptoFrame: {
|
case QuicWriteFrame::Type::WriteCryptoFrame: {
|
||||||
@@ -833,7 +835,8 @@ void updateConnection(
|
|||||||
conn.lossState.inflightBytes + encodedSize,
|
conn.lossState.inflightBytes + encodedSize,
|
||||||
conn.outstandings.numOutstanding() + 1,
|
conn.outstandings.numOutstanding() + 1,
|
||||||
conn.lossState,
|
conn.lossState,
|
||||||
conn.writeCount);
|
conn.writeCount,
|
||||||
|
std::move(detailsPerStream));
|
||||||
|
|
||||||
if (isD6DProbe) {
|
if (isD6DProbe) {
|
||||||
++conn.d6d.outstandingProbes;
|
++conn.d6d.outstandingProbes;
|
||||||
|
@@ -114,7 +114,7 @@ PacketNum addOutstandingPacket(QuicConnectionStateBase& conn) {
|
|||||||
nextPacketNum);
|
nextPacketNum);
|
||||||
RegularQuicWritePacket packet(std::move(header));
|
RegularQuicWritePacket packet(std::move(header));
|
||||||
conn.outstandings.packets.emplace_back(
|
conn.outstandings.packets.emplace_back(
|
||||||
packet, Clock::now(), 0, 0, false, 0, 0, 0, 0, LossState());
|
packet, Clock::now(), 0, 0, false, 0, 0, 0, 0, LossState(), 0);
|
||||||
increaseNextPacketNum(conn, PacketNumberSpace::AppData);
|
increaseNextPacketNum(conn, PacketNumberSpace::AppData);
|
||||||
return nextPacketNum;
|
return nextPacketNum;
|
||||||
}
|
}
|
||||||
|
@@ -1647,6 +1647,276 @@ TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionConnWindowUpdate) {
|
|||||||
EXPECT_EQ(frame->maximumData, conn->flowControlState.advertisedMaxOffset);
|
EXPECT_EQ(frame->maximumData, conn->flowControlState.advertisedMaxOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(QuicTransportFunctionsTest, TestStreamDetailsEmptyPacket) {
|
||||||
|
auto conn = createConn();
|
||||||
|
auto packet = buildEmptyPacket(*conn, PacketNumberSpace::AppData);
|
||||||
|
updateConnection(
|
||||||
|
*conn,
|
||||||
|
folly::none,
|
||||||
|
packet.packet,
|
||||||
|
TimePoint(),
|
||||||
|
getEncodedSize(packet),
|
||||||
|
getEncodedBodySize(packet),
|
||||||
|
false /* isDSRPacket */);
|
||||||
|
// Since there is no ACK eliciting frame in this packet, it is not included as
|
||||||
|
// an outstanding packet
|
||||||
|
EXPECT_EQ(0, conn->outstandings.packets.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(QuicTransportFunctionsTest, TestStreamDetailsControlPacket) {
|
||||||
|
auto conn = createConn();
|
||||||
|
auto packet = buildEmptyPacket(*conn, PacketNumberSpace::AppData);
|
||||||
|
auto stream = conn->streamManager->createNextBidirectionalStream().value();
|
||||||
|
StreamDataBlockedFrame blockedFrame(stream->id, 1000);
|
||||||
|
packet.packet.frames.push_back(blockedFrame);
|
||||||
|
packet.packet.frames.push_back(PingFrame());
|
||||||
|
updateConnection(
|
||||||
|
*conn,
|
||||||
|
folly::none,
|
||||||
|
packet.packet,
|
||||||
|
TimePoint(),
|
||||||
|
getEncodedSize(packet),
|
||||||
|
getEncodedBodySize(packet),
|
||||||
|
false /* isDSRPacket */);
|
||||||
|
// If we have only control frames sent, there should be no stream data in the
|
||||||
|
// outstanding packet.
|
||||||
|
ASSERT_EQ(1, conn->outstandings.packets.size());
|
||||||
|
auto detailsPerStream =
|
||||||
|
getFirstOutstandingPacket(*conn, PacketNumberSpace::AppData)
|
||||||
|
->metadata.maybeDetailsPerStream;
|
||||||
|
EXPECT_EQ(true, detailsPerStream.has_value());
|
||||||
|
EXPECT_EQ(0, detailsPerStream->getDetails().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(QuicTransportFunctionsTest, TestStreamDetailsAppDataPacketSingleStream) {
|
||||||
|
auto conn = createConn();
|
||||||
|
auto packet = buildEmptyPacket(*conn, PacketNumberSpace::AppData);
|
||||||
|
auto stream = conn->streamManager->createNextBidirectionalStream().value();
|
||||||
|
writeDataToQuicStream(*stream, folly::IOBuf::copyBuffer("abcdefghij"), true);
|
||||||
|
WriteStreamFrame writeStreamFrame(
|
||||||
|
stream->id, 0 /* offset */, 10 /* length */, false /* fin */);
|
||||||
|
packet.packet.frames.push_back(writeStreamFrame);
|
||||||
|
updateConnection(
|
||||||
|
*conn,
|
||||||
|
folly::none,
|
||||||
|
packet.packet,
|
||||||
|
TimePoint(),
|
||||||
|
getEncodedSize(packet),
|
||||||
|
getEncodedBodySize(packet),
|
||||||
|
false /* isDSRPacket */);
|
||||||
|
|
||||||
|
ASSERT_EQ(1, conn->outstandings.packets.size());
|
||||||
|
auto detailsPerStream =
|
||||||
|
getFirstOutstandingPacket(*conn, PacketNumberSpace::AppData)
|
||||||
|
->metadata.maybeDetailsPerStream->getDetails();
|
||||||
|
EXPECT_EQ(1, detailsPerStream.size());
|
||||||
|
auto streamDetail = detailsPerStream[stream->id];
|
||||||
|
EXPECT_EQ(false, streamDetail.finObserved);
|
||||||
|
EXPECT_EQ(10, streamDetail.streamBytesSent);
|
||||||
|
EXPECT_EQ(10, streamDetail.newStreamBytesSent);
|
||||||
|
EXPECT_EQ(0, streamDetail.maybeFirstNewStreamByteOffset.value());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(
|
||||||
|
QuicTransportFunctionsTest,
|
||||||
|
TestStreamDetailsAppDataPacketSingleStreamMultipleFrames) {
|
||||||
|
auto conn = createConn();
|
||||||
|
auto packet = buildEmptyPacket(*conn, PacketNumberSpace::AppData);
|
||||||
|
auto stream = conn->streamManager->createNextBidirectionalStream().value();
|
||||||
|
writeDataToQuicStream(
|
||||||
|
*stream, folly::IOBuf::copyBuffer("abcdefghijklmno"), true);
|
||||||
|
WriteStreamFrame writeStreamFrame1(
|
||||||
|
stream->id, 0 /* offset */, 10 /* length */, false /* fin */);
|
||||||
|
WriteStreamFrame writeStreamFrame2(
|
||||||
|
stream->id, 10 /* offset */, 5 /* length */, true /* fin */);
|
||||||
|
packet.packet.frames.push_back(writeStreamFrame1);
|
||||||
|
packet.packet.frames.push_back(writeStreamFrame2);
|
||||||
|
updateConnection(
|
||||||
|
*conn,
|
||||||
|
folly::none,
|
||||||
|
packet.packet,
|
||||||
|
TimePoint(),
|
||||||
|
getEncodedSize(packet),
|
||||||
|
getEncodedBodySize(packet),
|
||||||
|
false /* isDSRPacket */);
|
||||||
|
|
||||||
|
ASSERT_EQ(1, conn->outstandings.packets.size());
|
||||||
|
auto detailsPerStream =
|
||||||
|
getFirstOutstandingPacket(*conn, PacketNumberSpace::AppData)
|
||||||
|
->metadata.maybeDetailsPerStream->getDetails();
|
||||||
|
EXPECT_EQ(1, detailsPerStream.size());
|
||||||
|
auto streamDetail = detailsPerStream[stream->id];
|
||||||
|
EXPECT_EQ(true, streamDetail.finObserved);
|
||||||
|
EXPECT_EQ(15, streamDetail.streamBytesSent);
|
||||||
|
EXPECT_EQ(15, streamDetail.newStreamBytesSent);
|
||||||
|
EXPECT_EQ(0, streamDetail.maybeFirstNewStreamByteOffset.value());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(
|
||||||
|
QuicTransportFunctionsTest,
|
||||||
|
TestStreamDetailsAppDataPacketSingleStreamRetransmit) {
|
||||||
|
auto conn = createConn();
|
||||||
|
auto stream = conn->streamManager->createNextBidirectionalStream().value();
|
||||||
|
|
||||||
|
writeDataToQuicStream(*stream, folly::IOBuf::copyBuffer("abcdefghij"), true);
|
||||||
|
uint64_t frame1Offset = 0;
|
||||||
|
uint64_t frame1Len = 10;
|
||||||
|
auto packet = buildEmptyPacket(*conn, PacketNumberSpace::AppData);
|
||||||
|
WriteStreamFrame frame1(stream->id, frame1Offset, frame1Len, false /* fin */);
|
||||||
|
packet.packet.frames.push_back(frame1);
|
||||||
|
updateConnection(
|
||||||
|
*conn,
|
||||||
|
folly::none,
|
||||||
|
packet.packet,
|
||||||
|
TimePoint(),
|
||||||
|
getEncodedSize(packet),
|
||||||
|
getEncodedBodySize(packet),
|
||||||
|
false /* isDSRPacket */);
|
||||||
|
|
||||||
|
ASSERT_EQ(1, conn->outstandings.packets.size());
|
||||||
|
|
||||||
|
// The first outstanding packet is the one with new data
|
||||||
|
auto detailsPerStream =
|
||||||
|
getFirstOutstandingPacket(*conn, PacketNumberSpace::AppData)
|
||||||
|
->metadata.maybeDetailsPerStream->getDetails();
|
||||||
|
EXPECT_EQ(1, detailsPerStream.size());
|
||||||
|
auto streamDetail = detailsPerStream[stream->id];
|
||||||
|
EXPECT_EQ(false, streamDetail.finObserved);
|
||||||
|
EXPECT_EQ(frame1Len, streamDetail.streamBytesSent);
|
||||||
|
EXPECT_EQ(frame1Len, streamDetail.newStreamBytesSent);
|
||||||
|
EXPECT_EQ(frame1Offset, streamDetail.maybeFirstNewStreamByteOffset.value());
|
||||||
|
|
||||||
|
// retransmit the same frame1 again.
|
||||||
|
packet = buildEmptyPacket(*conn, PacketNumberSpace::AppData);
|
||||||
|
packet.packet.frames.push_back(frame1);
|
||||||
|
updateConnection(
|
||||||
|
*conn,
|
||||||
|
folly::none,
|
||||||
|
packet.packet,
|
||||||
|
TimePoint(),
|
||||||
|
getEncodedSize(packet),
|
||||||
|
getEncodedBodySize(packet),
|
||||||
|
false /* isDSRPacket */);
|
||||||
|
|
||||||
|
ASSERT_EQ(2, conn->outstandings.packets.size());
|
||||||
|
|
||||||
|
// The second outstanding packet is the one with retransmit data
|
||||||
|
detailsPerStream = getLastOutstandingPacket(*conn, PacketNumberSpace::AppData)
|
||||||
|
->metadata.maybeDetailsPerStream->getDetails();
|
||||||
|
EXPECT_EQ(1, detailsPerStream.size());
|
||||||
|
streamDetail = detailsPerStream[stream->id];
|
||||||
|
EXPECT_EQ(false, streamDetail.finObserved);
|
||||||
|
EXPECT_EQ(frame1Len, streamDetail.streamBytesSent);
|
||||||
|
EXPECT_EQ(0, streamDetail.newStreamBytesSent);
|
||||||
|
EXPECT_FALSE(streamDetail.maybeFirstNewStreamByteOffset.has_value());
|
||||||
|
|
||||||
|
// Retransmit frame1 and send new data in frame2.
|
||||||
|
writeDataToQuicStream(
|
||||||
|
*stream, folly::IOBuf::copyBuffer("klmnopqrstuvwxy"), true);
|
||||||
|
uint64_t frame2Offset = 10;
|
||||||
|
uint64_t frame2Len = 15;
|
||||||
|
packet = buildEmptyPacket(*conn, PacketNumberSpace::AppData);
|
||||||
|
WriteStreamFrame frame2(stream->id, frame2Offset, frame2Len, false /* fin */);
|
||||||
|
packet.packet.frames.push_back(frame1);
|
||||||
|
packet.packet.frames.push_back(frame2);
|
||||||
|
updateConnection(
|
||||||
|
*conn,
|
||||||
|
folly::none,
|
||||||
|
packet.packet,
|
||||||
|
TimePoint(),
|
||||||
|
getEncodedSize(packet),
|
||||||
|
getEncodedBodySize(packet),
|
||||||
|
false /* isDSRPacket */);
|
||||||
|
|
||||||
|
ASSERT_EQ(3, conn->outstandings.packets.size());
|
||||||
|
|
||||||
|
// The third outstanding packet will have both new and retransmitted data.
|
||||||
|
detailsPerStream = getLastOutstandingPacket(*conn, PacketNumberSpace::AppData)
|
||||||
|
->metadata.maybeDetailsPerStream->getDetails();
|
||||||
|
EXPECT_EQ(1, detailsPerStream.size());
|
||||||
|
streamDetail = detailsPerStream[stream->id];
|
||||||
|
EXPECT_EQ(false, streamDetail.finObserved);
|
||||||
|
EXPECT_EQ(frame1Len + frame2Len, streamDetail.streamBytesSent);
|
||||||
|
EXPECT_EQ(frame2Len, streamDetail.newStreamBytesSent);
|
||||||
|
EXPECT_EQ(frame2Offset, streamDetail.maybeFirstNewStreamByteOffset.value());
|
||||||
|
|
||||||
|
// Retransmit frame1 aand frame2.
|
||||||
|
packet = buildEmptyPacket(*conn, PacketNumberSpace::AppData);
|
||||||
|
packet.packet.frames.push_back(frame1);
|
||||||
|
packet.packet.frames.push_back(frame2);
|
||||||
|
updateConnection(
|
||||||
|
*conn,
|
||||||
|
folly::none,
|
||||||
|
packet.packet,
|
||||||
|
TimePoint(),
|
||||||
|
getEncodedSize(packet),
|
||||||
|
getEncodedBodySize(packet),
|
||||||
|
false /* isDSRPacket */);
|
||||||
|
|
||||||
|
ASSERT_EQ(4, conn->outstandings.packets.size());
|
||||||
|
|
||||||
|
// The forth outstanding packet will have only retransmit data.
|
||||||
|
detailsPerStream = getLastOutstandingPacket(*conn, PacketNumberSpace::AppData)
|
||||||
|
->metadata.maybeDetailsPerStream->getDetails();
|
||||||
|
EXPECT_EQ(1, detailsPerStream.size());
|
||||||
|
streamDetail = detailsPerStream[stream->id];
|
||||||
|
EXPECT_EQ(false, streamDetail.finObserved);
|
||||||
|
EXPECT_EQ(frame1Len + frame2Len, streamDetail.streamBytesSent);
|
||||||
|
EXPECT_EQ(0, streamDetail.newStreamBytesSent);
|
||||||
|
EXPECT_FALSE(streamDetail.maybeFirstNewStreamByteOffset.has_value());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(
|
||||||
|
QuicTransportFunctionsTest,
|
||||||
|
TestStreamDetailsAppDataPacketMultipleStreams) {
|
||||||
|
auto conn = createConn();
|
||||||
|
auto packet = buildEmptyPacket(*conn, PacketNumberSpace::AppData);
|
||||||
|
auto stream1Id =
|
||||||
|
conn->streamManager->createNextBidirectionalStream().value()->id;
|
||||||
|
auto stream2Id =
|
||||||
|
conn->streamManager->createNextBidirectionalStream().value()->id;
|
||||||
|
auto stream1 = conn->streamManager->findStream(stream1Id);
|
||||||
|
auto stream2 = conn->streamManager->findStream(stream2Id);
|
||||||
|
EXPECT_NE(nullptr, stream1);
|
||||||
|
EXPECT_NE(nullptr, stream2);
|
||||||
|
|
||||||
|
auto buf = IOBuf::copyBuffer("hey whats up");
|
||||||
|
writeDataToQuicStream(*stream1, buf->clone(), true);
|
||||||
|
writeDataToQuicStream(*stream2, buf->clone(), true);
|
||||||
|
|
||||||
|
WriteStreamFrame writeStreamFrame1(stream1->id, 0, 5, false),
|
||||||
|
writeStreamFrame2(stream2->id, 0, 12, true);
|
||||||
|
packet.packet.frames.push_back(writeStreamFrame1);
|
||||||
|
packet.packet.frames.push_back(writeStreamFrame2);
|
||||||
|
|
||||||
|
updateConnection(
|
||||||
|
*conn,
|
||||||
|
folly::none,
|
||||||
|
packet.packet,
|
||||||
|
TimePoint(),
|
||||||
|
getEncodedSize(packet),
|
||||||
|
getEncodedBodySize(packet),
|
||||||
|
false /* isDSRPacket */);
|
||||||
|
|
||||||
|
ASSERT_EQ(1, conn->outstandings.packets.size());
|
||||||
|
auto detailsPerStream =
|
||||||
|
getFirstOutstandingPacket(*conn, PacketNumberSpace::AppData)
|
||||||
|
->metadata.maybeDetailsPerStream->getDetails();
|
||||||
|
EXPECT_EQ(2, detailsPerStream.size());
|
||||||
|
auto stream1Detail = detailsPerStream[stream1Id];
|
||||||
|
auto stream2Detail = detailsPerStream[stream2Id];
|
||||||
|
|
||||||
|
EXPECT_EQ(false, stream1Detail.finObserved);
|
||||||
|
EXPECT_EQ(5, stream1Detail.streamBytesSent);
|
||||||
|
EXPECT_EQ(5, stream1Detail.newStreamBytesSent);
|
||||||
|
EXPECT_EQ(0, stream1Detail.maybeFirstNewStreamByteOffset.value());
|
||||||
|
|
||||||
|
EXPECT_EQ(true, stream2Detail.finObserved);
|
||||||
|
EXPECT_EQ(12, stream2Detail.streamBytesSent);
|
||||||
|
EXPECT_EQ(12, stream2Detail.newStreamBytesSent);
|
||||||
|
EXPECT_EQ(0, stream2Detail.maybeFirstNewStreamByteOffset.value());
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(QuicTransportFunctionsTest, WriteQuicDataToSocketWithCC) {
|
TEST_F(QuicTransportFunctionsTest, WriteQuicDataToSocketWithCC) {
|
||||||
auto conn = createConn();
|
auto conn = createConn();
|
||||||
conn->udpSendPacketLen = 30;
|
conn->udpSendPacketLen = 30;
|
||||||
@@ -2101,8 +2371,8 @@ TEST_F(QuicTransportFunctionsTest, WriteProbingOldData) {
|
|||||||
1,
|
1,
|
||||||
writeProbingDataToSocketForTest(
|
writeProbingDataToSocketForTest(
|
||||||
*rawSocket, *conn, 1, *aead, *headerCipher, getVersion(*conn)));
|
*rawSocket, *conn, 1, *aead, *headerCipher, getVersion(*conn)));
|
||||||
// Now we have no new data, let's probe again, and verify the same old data is
|
// Now we have no new data, let's probe again, and verify the same old data
|
||||||
// sent.
|
// is sent.
|
||||||
folly::IOBuf secondBodyCaptured;
|
folly::IOBuf secondBodyCaptured;
|
||||||
EXPECT_CALL(*capturingAead, _inplaceEncrypt(_, _, _))
|
EXPECT_CALL(*capturingAead, _inplaceEncrypt(_, _, _))
|
||||||
.WillRepeatedly(Invoke([&](auto& buf, auto, auto) {
|
.WillRepeatedly(Invoke([&](auto& buf, auto, auto) {
|
||||||
@@ -2458,7 +2728,8 @@ TEST_F(QuicTransportFunctionsTest, ShouldWriteDataTestDuringPathValidation) {
|
|||||||
auto buf = IOBuf::copyBuffer("0123456789");
|
auto buf = IOBuf::copyBuffer("0123456789");
|
||||||
writeDataToQuicStream(*stream1, buf->clone(), false);
|
writeDataToQuicStream(*stream1, buf->clone(), false);
|
||||||
|
|
||||||
// Only case that we allow the write; both CC / PathLimiter have writablebytes
|
// Only case that we allow the write; both CC / PathLimiter have
|
||||||
|
// writablebytes
|
||||||
EXPECT_CALL(*rawCongestionController, getWritableBytes()).WillOnce(Return(1));
|
EXPECT_CALL(*rawCongestionController, getWritableBytes()).WillOnce(Return(1));
|
||||||
EXPECT_CALL(*rawLimiter, currentCredit(_, _)).WillOnce(Return(1));
|
EXPECT_CALL(*rawLimiter, currentCredit(_, _)).WillOnce(Return(1));
|
||||||
|
|
||||||
|
@@ -38,7 +38,8 @@ OutstandingPacket makeDummyOutstandingPacket(
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
LossState());
|
LossState(),
|
||||||
|
0);
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -40,7 +40,8 @@ class CopaTest : public Test {
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
LossState()));
|
LossState(),
|
||||||
|
0));
|
||||||
loss.lostBytes = packetData.second;
|
loss.lostBytes = packetData.second;
|
||||||
}
|
}
|
||||||
loss.lostPackets = lostPackets.size();
|
loss.lostPackets = lostPackets.size();
|
||||||
@@ -65,7 +66,8 @@ class CopaTest : public Test {
|
|||||||
0,
|
0,
|
||||||
inflight,
|
inflight,
|
||||||
0,
|
0,
|
||||||
LossState());
|
LossState(),
|
||||||
|
0);
|
||||||
}
|
}
|
||||||
|
|
||||||
CongestionController::AckEvent createAckEvent(
|
CongestionController::AckEvent createAckEvent(
|
||||||
|
@@ -36,7 +36,8 @@ CongestionController::LossEvent createLossEvent(
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
LossState()));
|
LossState(),
|
||||||
|
0));
|
||||||
loss.lostBytes = packetData.second;
|
loss.lostBytes = packetData.second;
|
||||||
}
|
}
|
||||||
loss.lostPackets = lostPackets.size();
|
loss.lostPackets = lostPackets.size();
|
||||||
@@ -64,7 +65,8 @@ CongestionController::AckEvent createAckEvent(
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
LossState())));
|
LossState(),
|
||||||
|
0)));
|
||||||
return ack;
|
return ack;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,7 +88,8 @@ OutstandingPacket createPacket(
|
|||||||
0,
|
0,
|
||||||
inflight,
|
inflight,
|
||||||
0,
|
0,
|
||||||
LossState());
|
LossState(),
|
||||||
|
0);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(NewRenoTest, TestLoss) {
|
TEST_F(NewRenoTest, TestLoss) {
|
||||||
|
@@ -212,7 +212,8 @@ TEST_F(QuicD6DStateFunctionsTest, D6DProbeAckedInBase) {
|
|||||||
d6d.currentProbeSize,
|
d6d.currentProbeSize,
|
||||||
d6d.currentProbeSize,
|
d6d.currentProbeSize,
|
||||||
0,
|
0,
|
||||||
LossState());
|
LossState(),
|
||||||
|
0);
|
||||||
d6d.lastProbe = D6DProbePacket(
|
d6d.lastProbe = D6DProbePacket(
|
||||||
pkt.packet.header.getPacketSequenceNum(), pkt.metadata.encodedSize);
|
pkt.packet.header.getPacketSequenceNum(), pkt.metadata.encodedSize);
|
||||||
d6d.raiser = std::make_unique<MockProbeSizeRaiser>();
|
d6d.raiser = std::make_unique<MockProbeSizeRaiser>();
|
||||||
@@ -259,7 +260,8 @@ TEST_F(QuicD6DStateFunctionsTest, D6DProbeAckedInSearchingOne) {
|
|||||||
d6d.currentProbeSize,
|
d6d.currentProbeSize,
|
||||||
d6d.currentProbeSize,
|
d6d.currentProbeSize,
|
||||||
0,
|
0,
|
||||||
LossState());
|
LossState(),
|
||||||
|
0);
|
||||||
d6d.lastProbe = D6DProbePacket(
|
d6d.lastProbe = D6DProbePacket(
|
||||||
pkt.packet.header.getPacketSequenceNum(), pkt.metadata.encodedSize);
|
pkt.packet.header.getPacketSequenceNum(), pkt.metadata.encodedSize);
|
||||||
d6d.raiser = std::make_unique<MockProbeSizeRaiser>();
|
d6d.raiser = std::make_unique<MockProbeSizeRaiser>();
|
||||||
@@ -307,7 +309,8 @@ TEST_F(QuicD6DStateFunctionsTest, D6DProbeAckedInSearchingMax) {
|
|||||||
d6d.currentProbeSize,
|
d6d.currentProbeSize,
|
||||||
d6d.currentProbeSize,
|
d6d.currentProbeSize,
|
||||||
0,
|
0,
|
||||||
LossState());
|
LossState(),
|
||||||
|
0);
|
||||||
d6d.lastProbe = D6DProbePacket(
|
d6d.lastProbe = D6DProbePacket(
|
||||||
pkt.packet.header.getPacketSequenceNum(), pkt.metadata.encodedSize);
|
pkt.packet.header.getPacketSequenceNum(), pkt.metadata.encodedSize);
|
||||||
d6d.raiser = std::make_unique<MockProbeSizeRaiser>();
|
d6d.raiser = std::make_unique<MockProbeSizeRaiser>();
|
||||||
@@ -363,7 +366,8 @@ TEST_F(QuicD6DStateFunctionsTest, D6DProbeAckedInError) {
|
|||||||
d6d.currentProbeSize,
|
d6d.currentProbeSize,
|
||||||
d6d.currentProbeSize,
|
d6d.currentProbeSize,
|
||||||
0,
|
0,
|
||||||
LossState());
|
LossState(),
|
||||||
|
0);
|
||||||
d6d.lastProbe = D6DProbePacket(
|
d6d.lastProbe = D6DProbePacket(
|
||||||
pkt.packet.header.getPacketSequenceNum(), pkt.metadata.encodedSize);
|
pkt.packet.header.getPacketSequenceNum(), pkt.metadata.encodedSize);
|
||||||
d6d.raiser = std::make_unique<MockProbeSizeRaiser>();
|
d6d.raiser = std::make_unique<MockProbeSizeRaiser>();
|
||||||
@@ -409,7 +413,8 @@ TEST_F(QuicD6DStateFunctionsTest, BlackholeInSearching) {
|
|||||||
d6d.currentProbeSize,
|
d6d.currentProbeSize,
|
||||||
d6d.currentProbeSize,
|
d6d.currentProbeSize,
|
||||||
0,
|
0,
|
||||||
LossState());
|
LossState(),
|
||||||
|
0);
|
||||||
d6d.lastProbe = D6DProbePacket(
|
d6d.lastProbe = D6DProbePacket(
|
||||||
pkt.packet.header.getPacketSequenceNum(), pkt.metadata.encodedSize);
|
pkt.packet.header.getPacketSequenceNum(), pkt.metadata.encodedSize);
|
||||||
|
|
||||||
@@ -423,7 +428,8 @@ TEST_F(QuicD6DStateFunctionsTest, BlackholeInSearching) {
|
|||||||
0,
|
0,
|
||||||
conn.udpSendPacketLen + d6d.currentProbeSize,
|
conn.udpSendPacketLen + d6d.currentProbeSize,
|
||||||
0,
|
0,
|
||||||
LossState());
|
LossState(),
|
||||||
|
0);
|
||||||
|
|
||||||
d6d.thresholdCounter = std::make_unique<WindowedCounter<uint64_t, uint64_t>>(
|
d6d.thresholdCounter = std::make_unique<WindowedCounter<uint64_t, uint64_t>>(
|
||||||
std::chrono::microseconds(kDefaultD6DBlackholeDetectionWindow).count(),
|
std::chrono::microseconds(kDefaultD6DBlackholeDetectionWindow).count(),
|
||||||
@@ -481,7 +487,8 @@ TEST_F(QuicD6DStateFunctionsTest, BlackholeInSearchComplete) {
|
|||||||
d6d.currentProbeSize,
|
d6d.currentProbeSize,
|
||||||
d6d.currentProbeSize,
|
d6d.currentProbeSize,
|
||||||
0,
|
0,
|
||||||
LossState());
|
LossState(),
|
||||||
|
0);
|
||||||
d6d.lastProbe = D6DProbePacket(
|
d6d.lastProbe = D6DProbePacket(
|
||||||
pkt.packet.header.getPacketSequenceNum(), pkt.metadata.encodedSize);
|
pkt.packet.header.getPacketSequenceNum(), pkt.metadata.encodedSize);
|
||||||
|
|
||||||
@@ -495,7 +502,8 @@ TEST_F(QuicD6DStateFunctionsTest, BlackholeInSearchComplete) {
|
|||||||
0,
|
0,
|
||||||
conn.udpSendPacketLen + d6d.currentProbeSize,
|
conn.udpSendPacketLen + d6d.currentProbeSize,
|
||||||
0,
|
0,
|
||||||
LossState());
|
LossState(),
|
||||||
|
0);
|
||||||
|
|
||||||
d6d.thresholdCounter = std::make_unique<WindowedCounter<uint64_t, uint64_t>>(
|
d6d.thresholdCounter = std::make_unique<WindowedCounter<uint64_t, uint64_t>>(
|
||||||
std::chrono::microseconds(kDefaultD6DBlackholeDetectionWindow).count(),
|
std::chrono::microseconds(kDefaultD6DBlackholeDetectionWindow).count(),
|
||||||
@@ -556,7 +564,8 @@ TEST_F(QuicD6DStateFunctionsTest, ReachMaxPMTU) {
|
|||||||
d6d.currentProbeSize,
|
d6d.currentProbeSize,
|
||||||
d6d.currentProbeSize,
|
d6d.currentProbeSize,
|
||||||
0,
|
0,
|
||||||
LossState());
|
LossState(),
|
||||||
|
0);
|
||||||
d6d.lastProbe = D6DProbePacket(
|
d6d.lastProbe = D6DProbePacket(
|
||||||
pkt.packet.header.getPacketSequenceNum(), pkt.metadata.encodedSize);
|
pkt.packet.header.getPacketSequenceNum(), pkt.metadata.encodedSize);
|
||||||
d6d.raiser = std::make_unique<MockProbeSizeRaiser>();
|
d6d.raiser = std::make_unique<MockProbeSizeRaiser>();
|
||||||
@@ -596,7 +605,8 @@ TEST_F(
|
|||||||
d6d.currentProbeSize,
|
d6d.currentProbeSize,
|
||||||
d6d.currentProbeSize,
|
d6d.currentProbeSize,
|
||||||
0,
|
0,
|
||||||
LossState());
|
LossState(),
|
||||||
|
0);
|
||||||
d6d.lastProbe = D6DProbePacket(
|
d6d.lastProbe = D6DProbePacket(
|
||||||
pkt.packet.header.getPacketSequenceNum(), pkt.metadata.encodedSize);
|
pkt.packet.header.getPacketSequenceNum(), pkt.metadata.encodedSize);
|
||||||
d6d.raiser = std::make_unique<MockProbeSizeRaiser>();
|
d6d.raiser = std::make_unique<MockProbeSizeRaiser>();
|
||||||
@@ -618,7 +628,8 @@ TEST_F(
|
|||||||
d6d.currentProbeSize,
|
d6d.currentProbeSize,
|
||||||
d6d.currentProbeSize,
|
d6d.currentProbeSize,
|
||||||
0,
|
0,
|
||||||
LossState());
|
LossState(),
|
||||||
|
0);
|
||||||
// Generate a false positive blackhole signal
|
// Generate a false positive blackhole signal
|
||||||
detectPMTUBlackhole(conn, lostPacket);
|
detectPMTUBlackhole(conn, lostPacket);
|
||||||
EXPECT_EQ(d6d.state, D6DMachineState::BASE);
|
EXPECT_EQ(d6d.state, D6DMachineState::BASE);
|
||||||
@@ -657,7 +668,8 @@ TEST_F(QuicD6DStateFunctionsTest, UpperboundIsBase) {
|
|||||||
d6d.currentProbeSize,
|
d6d.currentProbeSize,
|
||||||
d6d.currentProbeSize,
|
d6d.currentProbeSize,
|
||||||
0,
|
0,
|
||||||
LossState());
|
LossState(),
|
||||||
|
0);
|
||||||
d6d.lastProbe = D6DProbePacket(
|
d6d.lastProbe = D6DProbePacket(
|
||||||
pkt.packet.header.getPacketSequenceNum(), pkt.metadata.encodedSize);
|
pkt.packet.header.getPacketSequenceNum(), pkt.metadata.encodedSize);
|
||||||
d6d.raiser = std::make_unique<MockProbeSizeRaiser>();
|
d6d.raiser = std::make_unique<MockProbeSizeRaiser>();
|
||||||
|
@@ -255,7 +255,8 @@ PacketNum QuicLossFunctionsTest::sendPacket(
|
|||||||
encodedBodySize,
|
encodedBodySize,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
LossState());
|
LossState(),
|
||||||
|
0);
|
||||||
outstandingPacket.associatedEvent = associatedEvent;
|
outstandingPacket.associatedEvent = associatedEvent;
|
||||||
conn.lossState.lastRetransmittablePacketSentTime = time;
|
conn.lossState.lastRetransmittablePacketSentTime = time;
|
||||||
if (conn.congestionController) {
|
if (conn.congestionController) {
|
||||||
@@ -1007,7 +1008,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(OutstandingPacket(
|
conn->outstandings.packets.emplace_back(OutstandingPacket(
|
||||||
outstandingRegularPacket, now, 0, 0, false, 0, 0, 0, 0, LossState()));
|
outstandingRegularPacket, now, 0, 0, false, 0, 0, 0, 0, LossState(), 0));
|
||||||
conn->outstandings.packetCount[PacketNumberSpace::Handshake]++;
|
conn->outstandings.packetCount[PacketNumberSpace::Handshake]++;
|
||||||
|
|
||||||
bool testLossMarkFuncCalled = false;
|
bool testLossMarkFuncCalled = false;
|
||||||
|
@@ -11,6 +11,7 @@
|
|||||||
#include <quic/codec/Types.h>
|
#include <quic/codec/Types.h>
|
||||||
#include <quic/state/LossState.h>
|
#include <quic/state/LossState.h>
|
||||||
#include <quic/state/PacketEvent.h>
|
#include <quic/state/PacketEvent.h>
|
||||||
|
#include "folly/container/F14Map.h"
|
||||||
|
|
||||||
namespace quic {
|
namespace quic {
|
||||||
|
|
||||||
@@ -44,6 +45,50 @@ struct OutstandingPacketMetadata {
|
|||||||
// tracks the number of writes on this socket.
|
// tracks the number of writes on this socket.
|
||||||
uint64_t writeCount{0};
|
uint64_t writeCount{0};
|
||||||
|
|
||||||
|
// Structure used to hold information about each stream with frames in packet
|
||||||
|
class DetailsPerStream {
|
||||||
|
public:
|
||||||
|
struct StreamDetails {
|
||||||
|
bool finObserved{false};
|
||||||
|
uint64_t streamBytesSent{0};
|
||||||
|
uint64_t newStreamBytesSent{0};
|
||||||
|
folly::Optional<uint64_t> maybeFirstNewStreamByteOffset;
|
||||||
|
};
|
||||||
|
|
||||||
|
void addFrame(const WriteStreamFrame& frame, const bool newData) {
|
||||||
|
auto ret = detailsPerStream.emplace(
|
||||||
|
std::piecewise_construct,
|
||||||
|
std::make_tuple(frame.streamId),
|
||||||
|
std::make_tuple());
|
||||||
|
|
||||||
|
auto& streamDetails = ret.first->second;
|
||||||
|
streamDetails.streamBytesSent += frame.len;
|
||||||
|
if (frame.fin) {
|
||||||
|
streamDetails.finObserved = true;
|
||||||
|
}
|
||||||
|
if (newData) {
|
||||||
|
streamDetails.newStreamBytesSent += frame.len;
|
||||||
|
if (streamDetails.maybeFirstNewStreamByteOffset) {
|
||||||
|
streamDetails.maybeFirstNewStreamByteOffset = std::min(
|
||||||
|
frame.offset, *streamDetails.maybeFirstNewStreamByteOffset);
|
||||||
|
} else {
|
||||||
|
streamDetails.maybeFirstNewStreamByteOffset = frame.offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FOLLY_NODISCARD const folly::F14FastMap<StreamId, StreamDetails>
|
||||||
|
getDetails() const {
|
||||||
|
return detailsPerStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
folly::F14FastMap<StreamId, StreamDetails> detailsPerStream;
|
||||||
|
};
|
||||||
|
|
||||||
|
// When enabled, details about each stream with frames in this packet
|
||||||
|
folly::Optional<DetailsPerStream> maybeDetailsPerStream;
|
||||||
|
|
||||||
OutstandingPacketMetadata(
|
OutstandingPacketMetadata(
|
||||||
TimePoint timeIn,
|
TimePoint timeIn,
|
||||||
uint32_t encodedSizeIn,
|
uint32_t encodedSizeIn,
|
||||||
@@ -55,7 +100,8 @@ struct OutstandingPacketMetadata {
|
|||||||
uint64_t inflightBytesIn,
|
uint64_t inflightBytesIn,
|
||||||
uint64_t packetsInflightIn,
|
uint64_t packetsInflightIn,
|
||||||
const LossState& lossStateIn,
|
const LossState& lossStateIn,
|
||||||
uint64_t writeCount)
|
uint64_t writeCount,
|
||||||
|
folly::Optional<DetailsPerStream> maybeDetailsPerStream)
|
||||||
: time(timeIn),
|
: time(timeIn),
|
||||||
encodedSize(encodedSizeIn),
|
encodedSize(encodedSizeIn),
|
||||||
encodedBodySize(encodedBodySizeIn),
|
encodedBodySize(encodedBodySizeIn),
|
||||||
@@ -67,11 +113,14 @@ struct OutstandingPacketMetadata {
|
|||||||
packetsInflight(packetsInflightIn),
|
packetsInflight(packetsInflightIn),
|
||||||
totalPacketsSent(lossStateIn.totalPacketsSent),
|
totalPacketsSent(lossStateIn.totalPacketsSent),
|
||||||
totalAckElicitingPacketsSent(lossStateIn.totalAckElicitingPacketsSent),
|
totalAckElicitingPacketsSent(lossStateIn.totalAckElicitingPacketsSent),
|
||||||
writeCount(writeCount) {}
|
writeCount(writeCount),
|
||||||
|
maybeDetailsPerStream(std::move(maybeDetailsPerStream)) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Data structure to represent outstanding retransmittable packets
|
// Data structure to represent outstanding retransmittable packets
|
||||||
struct OutstandingPacket {
|
struct OutstandingPacket {
|
||||||
|
using Metadata = OutstandingPacketMetadata;
|
||||||
|
|
||||||
// Structure representing the frames that are outstanding including the header
|
// Structure representing the frames that are outstanding including the header
|
||||||
// that was sent.
|
// that was sent.
|
||||||
RegularQuicWritePacket packet;
|
RegularQuicWritePacket packet;
|
||||||
@@ -138,7 +187,9 @@ struct OutstandingPacket {
|
|||||||
uint64_t inflightBytesIn,
|
uint64_t inflightBytesIn,
|
||||||
uint64_t packetsInflightIn,
|
uint64_t packetsInflightIn,
|
||||||
const LossState& lossStateIn,
|
const LossState& lossStateIn,
|
||||||
uint64_t writeCount = 0)
|
uint64_t writeCount,
|
||||||
|
folly::Optional<Metadata::DetailsPerStream> maybeDetailsPerStream =
|
||||||
|
folly::none)
|
||||||
: packet(std::move(packetIn)),
|
: packet(std::move(packetIn)),
|
||||||
metadata(OutstandingPacketMetadata(
|
metadata(OutstandingPacketMetadata(
|
||||||
timeIn,
|
timeIn,
|
||||||
@@ -151,7 +202,8 @@ struct OutstandingPacket {
|
|||||||
inflightBytesIn,
|
inflightBytesIn,
|
||||||
packetsInflightIn,
|
packetsInflightIn,
|
||||||
lossStateIn,
|
lossStateIn,
|
||||||
writeCount)) {}
|
writeCount,
|
||||||
|
std::move(maybeDetailsPerStream))) {}
|
||||||
|
|
||||||
OutstandingPacket(
|
OutstandingPacket(
|
||||||
RegularQuicWritePacket packetIn,
|
RegularQuicWritePacket packetIn,
|
||||||
@@ -165,7 +217,9 @@ struct OutstandingPacket {
|
|||||||
uint64_t inflightBytesIn,
|
uint64_t inflightBytesIn,
|
||||||
uint64_t packetsInflightIn,
|
uint64_t packetsInflightIn,
|
||||||
const LossState& lossStateIn,
|
const LossState& lossStateIn,
|
||||||
uint64_t writeCount = 0)
|
uint64_t writeCount,
|
||||||
|
folly::Optional<Metadata::DetailsPerStream> maybeDetailsPerStream =
|
||||||
|
folly::none)
|
||||||
: packet(std::move(packetIn)),
|
: packet(std::move(packetIn)),
|
||||||
metadata(OutstandingPacketMetadata(
|
metadata(OutstandingPacketMetadata(
|
||||||
timeIn,
|
timeIn,
|
||||||
@@ -178,6 +232,7 @@ struct OutstandingPacket {
|
|||||||
inflightBytesIn,
|
inflightBytesIn,
|
||||||
packetsInflightIn,
|
packetsInflightIn,
|
||||||
lossStateIn,
|
lossStateIn,
|
||||||
writeCount)) {}
|
writeCount,
|
||||||
|
std::move(maybeDetailsPerStream))) {}
|
||||||
};
|
};
|
||||||
} // namespace quic
|
} // namespace quic
|
||||||
|
@@ -63,7 +63,8 @@ auto emplacePackets(
|
|||||||
0,
|
0,
|
||||||
packetNum + 1,
|
packetNum + 1,
|
||||||
packetNum + 1,
|
packetNum + 1,
|
||||||
quic::LossState());
|
quic::LossState(),
|
||||||
|
0);
|
||||||
conn.outstandings.packets.emplace_back(sentPacket);
|
conn.outstandings.packets.emplace_back(sentPacket);
|
||||||
packetNum++;
|
packetNum++;
|
||||||
}
|
}
|
||||||
@@ -98,7 +99,8 @@ TEST_P(AckHandlersTest, TestAckMultipleSequentialBlocks) {
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
LossState()));
|
LossState(),
|
||||||
|
0));
|
||||||
}
|
}
|
||||||
ReadAckFrame ackFrame;
|
ReadAckFrame ackFrame;
|
||||||
ackFrame.largestAcked = 101;
|
ackFrame.largestAcked = 101;
|
||||||
@@ -180,7 +182,8 @@ TEST_P(AckHandlersTest, TestAckMultipleSequentialBlocksLoss) {
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
LossState()));
|
LossState(),
|
||||||
|
0));
|
||||||
}
|
}
|
||||||
ReadAckFrame ackFrame;
|
ReadAckFrame ackFrame;
|
||||||
ackFrame.largestAcked = 101;
|
ackFrame.largestAcked = 101;
|
||||||
@@ -326,7 +329,8 @@ TEST_P(AckHandlersTest, TestAckBlocksWithGaps) {
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
LossState()));
|
LossState(),
|
||||||
|
0));
|
||||||
}
|
}
|
||||||
|
|
||||||
ReadAckFrame ackFrame;
|
ReadAckFrame ackFrame;
|
||||||
@@ -435,7 +439,8 @@ TEST_P(AckHandlersTest, TestNonSequentialPacketNumbers) {
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
LossState()));
|
LossState(),
|
||||||
|
0));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (PacketNum packetNum = 20; packetNum < 40; packetNum += 3) {
|
for (PacketNum packetNum = 20; packetNum < 40; packetNum += 3) {
|
||||||
@@ -455,7 +460,8 @@ TEST_P(AckHandlersTest, TestNonSequentialPacketNumbers) {
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
LossState()));
|
LossState(),
|
||||||
|
0));
|
||||||
}
|
}
|
||||||
|
|
||||||
ReadAckFrame ackFrame;
|
ReadAckFrame ackFrame;
|
||||||
@@ -546,7 +552,8 @@ TEST_P(AckHandlersTest, AckVisitorForAckTest) {
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
LossState()));
|
LossState(),
|
||||||
|
0));
|
||||||
|
|
||||||
auto secondPacket = createNewPacket(101 /* packetNum */, GetParam());
|
auto secondPacket = createNewPacket(101 /* packetNum */, GetParam());
|
||||||
WriteAckFrame secondAckFrame;
|
WriteAckFrame secondAckFrame;
|
||||||
@@ -566,7 +573,8 @@ TEST_P(AckHandlersTest, AckVisitorForAckTest) {
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
LossState()));
|
LossState(),
|
||||||
|
0));
|
||||||
|
|
||||||
ReadAckFrame firstReceivedAck;
|
ReadAckFrame firstReceivedAck;
|
||||||
firstReceivedAck.largestAcked = 100;
|
firstReceivedAck.largestAcked = 100;
|
||||||
@@ -637,7 +645,8 @@ TEST_P(AckHandlersTest, NoNewAckedPacket) {
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
LossState()));
|
LossState(),
|
||||||
|
0));
|
||||||
|
|
||||||
ReadAckFrame ackFrame;
|
ReadAckFrame ackFrame;
|
||||||
ackFrame.largestAcked = 5;
|
ackFrame.largestAcked = 5;
|
||||||
@@ -693,7 +702,8 @@ TEST_P(AckHandlersTest, AckPacketNumDoesNotExist) {
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
LossState());
|
LossState(),
|
||||||
|
0);
|
||||||
|
|
||||||
PacketNum packetNum2 = 10;
|
PacketNum packetNum2 = 10;
|
||||||
auto regularPacket2 = createNewPacket(packetNum2, GetParam());
|
auto regularPacket2 = createNewPacket(packetNum2, GetParam());
|
||||||
@@ -708,7 +718,8 @@ TEST_P(AckHandlersTest, AckPacketNumDoesNotExist) {
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
LossState());
|
LossState(),
|
||||||
|
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.
|
||||||
@@ -748,7 +759,8 @@ TEST_P(AckHandlersTest, TestHandshakeCounterUpdate) {
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
LossState());
|
LossState(),
|
||||||
|
0);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReadAckFrame ackFrame;
|
ReadAckFrame ackFrame;
|
||||||
@@ -836,7 +848,8 @@ TEST_P(AckHandlersTest, NoSkipAckVisitor) {
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
LossState()));
|
LossState(),
|
||||||
|
0));
|
||||||
ReadAckFrame ackFrame;
|
ReadAckFrame ackFrame;
|
||||||
ackFrame.largestAcked = 0;
|
ackFrame.largestAcked = 0;
|
||||||
ackFrame.ackBlocks.emplace_back(0, 0);
|
ackFrame.ackBlocks.emplace_back(0, 0);
|
||||||
@@ -887,7 +900,8 @@ TEST_P(AckHandlersTest, SkipAckVisitor) {
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
LossState());
|
LossState(),
|
||||||
|
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(GetParam(), 0);
|
outstandingPacket.associatedEvent.emplace(GetParam(), 0);
|
||||||
@@ -937,7 +951,8 @@ TEST_P(AckHandlersTest, NoDoubleProcess) {
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
LossState());
|
LossState(),
|
||||||
|
0);
|
||||||
outstandingPacket1.associatedEvent.emplace(GetParam(), packetNum1);
|
outstandingPacket1.associatedEvent.emplace(GetParam(), packetNum1);
|
||||||
|
|
||||||
OutstandingPacket outstandingPacket2(
|
OutstandingPacket outstandingPacket2(
|
||||||
@@ -950,7 +965,8 @@ TEST_P(AckHandlersTest, NoDoubleProcess) {
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
LossState());
|
LossState(),
|
||||||
|
0);
|
||||||
// The seconds packet has the same PacketEvent
|
// The seconds packet has the same PacketEvent
|
||||||
outstandingPacket2.associatedEvent.emplace(GetParam(), packetNum1);
|
outstandingPacket2.associatedEvent.emplace(GetParam(), packetNum1);
|
||||||
|
|
||||||
@@ -1015,7 +1031,8 @@ TEST_P(AckHandlersTest, ClonedPacketsCounter) {
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
LossState());
|
LossState(),
|
||||||
|
0);
|
||||||
outstandingPacket1.associatedEvent.emplace(GetParam(), packetNum1);
|
outstandingPacket1.associatedEvent.emplace(GetParam(), packetNum1);
|
||||||
|
|
||||||
conn.ackStates.appDataAckState.nextPacketNum++;
|
conn.ackStates.appDataAckState.nextPacketNum++;
|
||||||
@@ -1032,7 +1049,8 @@ TEST_P(AckHandlersTest, ClonedPacketsCounter) {
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
LossState());
|
LossState(),
|
||||||
|
0);
|
||||||
|
|
||||||
conn.outstandings
|
conn.outstandings
|
||||||
.packetCount[outstandingPacket1.packet.header.getPacketNumberSpace()]++;
|
.packetCount[outstandingPacket1.packet.header.getPacketNumberSpace()]++;
|
||||||
@@ -1084,7 +1102,8 @@ TEST_P(AckHandlersTest, UpdateMaxAckDelay) {
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
LossState()));
|
LossState(),
|
||||||
|
0));
|
||||||
|
|
||||||
ReadAckFrame ackFrame;
|
ReadAckFrame ackFrame;
|
||||||
// ackDelay has no effect on mrtt
|
// ackDelay has no effect on mrtt
|
||||||
@@ -1151,7 +1170,8 @@ TEST_P(AckHandlersTest, AckNotOutstandingButLoss) {
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
LossState());
|
LossState(),
|
||||||
|
0);
|
||||||
conn.outstandings.packets.push_back(std::move(outstandingPacket));
|
conn.outstandings.packets.push_back(std::move(outstandingPacket));
|
||||||
conn.outstandings.packetCount[GetParam()]++;
|
conn.outstandings.packetCount[GetParam()]++;
|
||||||
|
|
||||||
@@ -1202,7 +1222,8 @@ TEST_P(AckHandlersTest, UpdatePendingAckStates) {
|
|||||||
conn.lossState.totalBodyBytesSent + 100,
|
conn.lossState.totalBodyBytesSent + 100,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
LossState()));
|
LossState(),
|
||||||
|
0));
|
||||||
conn.lossState.totalBytesSent += 111;
|
conn.lossState.totalBytesSent += 111;
|
||||||
conn.lossState.totalBodyBytesSent += 100;
|
conn.lossState.totalBodyBytesSent += 100;
|
||||||
|
|
||||||
@@ -1254,7 +1275,8 @@ TEST_P(AckHandlersTest, AckEventCreation) {
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
LossState());
|
LossState(),
|
||||||
|
0);
|
||||||
sentPacket.isAppLimited = (packetNum % 2);
|
sentPacket.isAppLimited = (packetNum % 2);
|
||||||
conn.outstandings.packets.emplace_back(sentPacket);
|
conn.outstandings.packets.emplace_back(sentPacket);
|
||||||
packetNum++;
|
packetNum++;
|
||||||
@@ -1315,7 +1337,8 @@ TEST_P(AckHandlersTest, ImplictAckEventCreation) {
|
|||||||
0,
|
0,
|
||||||
packetNum + 1,
|
packetNum + 1,
|
||||||
0,
|
0,
|
||||||
LossState());
|
LossState(),
|
||||||
|
0);
|
||||||
sentPacket.isAppLimited = (packetNum % 2);
|
sentPacket.isAppLimited = (packetNum % 2);
|
||||||
conn.outstandings.packets.emplace_back(sentPacket);
|
conn.outstandings.packets.emplace_back(sentPacket);
|
||||||
packetNum++;
|
packetNum++;
|
||||||
@@ -1386,7 +1409,8 @@ TEST_P(AckHandlersTest, TestRTTPacketObserverCallback) {
|
|||||||
0,
|
0,
|
||||||
packetNum + 1,
|
packetNum + 1,
|
||||||
0,
|
0,
|
||||||
LossState());
|
LossState(),
|
||||||
|
0);
|
||||||
sentPacket.isAppLimited = false;
|
sentPacket.isAppLimited = false;
|
||||||
conn.outstandings.packets.emplace_back(sentPacket);
|
conn.outstandings.packets.emplace_back(sentPacket);
|
||||||
packetNum++;
|
packetNum++;
|
||||||
|
@@ -683,7 +683,8 @@ TEST_F(QuicStateFunctionsTest, GetOutstandingPackets) {
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
LossState());
|
LossState(),
|
||||||
|
0);
|
||||||
conn.outstandings.packets.emplace_back(
|
conn.outstandings.packets.emplace_back(
|
||||||
makeTestLongPacket(LongHeader::Types::Handshake),
|
makeTestLongPacket(LongHeader::Types::Handshake),
|
||||||
Clock::now(),
|
Clock::now(),
|
||||||
@@ -694,7 +695,8 @@ TEST_F(QuicStateFunctionsTest, GetOutstandingPackets) {
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
LossState());
|
LossState(),
|
||||||
|
0);
|
||||||
conn.outstandings.packets.emplace_back(
|
conn.outstandings.packets.emplace_back(
|
||||||
makeTestShortPacket(),
|
makeTestShortPacket(),
|
||||||
Clock::now(),
|
Clock::now(),
|
||||||
@@ -705,7 +707,8 @@ TEST_F(QuicStateFunctionsTest, GetOutstandingPackets) {
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
LossState());
|
LossState(),
|
||||||
|
0);
|
||||||
conn.outstandings.packets.emplace_back(
|
conn.outstandings.packets.emplace_back(
|
||||||
makeTestLongPacket(LongHeader::Types::Initial),
|
makeTestLongPacket(LongHeader::Types::Initial),
|
||||||
Clock::now(),
|
Clock::now(),
|
||||||
@@ -716,7 +719,8 @@ TEST_F(QuicStateFunctionsTest, GetOutstandingPackets) {
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
LossState());
|
LossState(),
|
||||||
|
0);
|
||||||
conn.outstandings.packets.emplace_back(
|
conn.outstandings.packets.emplace_back(
|
||||||
makeTestShortPacket(),
|
makeTestShortPacket(),
|
||||||
Clock::now(),
|
Clock::now(),
|
||||||
@@ -727,7 +731,8 @@ TEST_F(QuicStateFunctionsTest, GetOutstandingPackets) {
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
LossState());
|
LossState(),
|
||||||
|
0);
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
135,
|
135,
|
||||||
getFirstOutstandingPacket(conn, PacketNumberSpace::Initial)
|
getFirstOutstandingPacket(conn, PacketNumberSpace::Initial)
|
||||||
|
@@ -37,7 +37,7 @@ TEST_F(StateDataTest, SingleLostPacketEvent) {
|
|||||||
100,
|
100,
|
||||||
kVersion));
|
kVersion));
|
||||||
OutstandingPacket outstandingPacket(
|
OutstandingPacket outstandingPacket(
|
||||||
packet, Clock::now(), 1234, 0, false, 1234, 0, 0, 0, LossState());
|
packet, Clock::now(), 1234, 0, false, 1234, 0, 0, 0, LossState(), 0);
|
||||||
CongestionController::LossEvent loss;
|
CongestionController::LossEvent loss;
|
||||||
loss.addLostPacket(outstandingPacket);
|
loss.addLostPacket(outstandingPacket);
|
||||||
EXPECT_EQ(1234, loss.lostBytes);
|
EXPECT_EQ(1234, loss.lostBytes);
|
||||||
@@ -52,7 +52,7 @@ TEST_F(StateDataTest, MultipleLostPacketsEvent) {
|
|||||||
100,
|
100,
|
||||||
kVersion));
|
kVersion));
|
||||||
OutstandingPacket outstandingPacket1(
|
OutstandingPacket outstandingPacket1(
|
||||||
packet1, Clock::now(), 1234, 0, false, 1234, 0, 0, 0, LossState());
|
packet1, Clock::now(), 1234, 0, false, 1234, 0, 0, 0, LossState(), 0);
|
||||||
|
|
||||||
RegularQuicWritePacket packet2(LongHeader(
|
RegularQuicWritePacket packet2(LongHeader(
|
||||||
LongHeader::Types::Initial,
|
LongHeader::Types::Initial,
|
||||||
@@ -61,7 +61,7 @@ TEST_F(StateDataTest, MultipleLostPacketsEvent) {
|
|||||||
110,
|
110,
|
||||||
kVersion));
|
kVersion));
|
||||||
OutstandingPacket outstandingPacket2(
|
OutstandingPacket outstandingPacket2(
|
||||||
packet2, Clock::now(), 1357, 0, false, 1357, 0, 0, 0, LossState());
|
packet2, Clock::now(), 1357, 0, false, 1357, 0, 0, 0, LossState(), 0);
|
||||||
|
|
||||||
CongestionController::LossEvent loss;
|
CongestionController::LossEvent loss;
|
||||||
loss.addLostPacket(outstandingPacket1);
|
loss.addLostPacket(outstandingPacket1);
|
||||||
|
Reference in New Issue
Block a user