mirror of
https://github.com/facebookincubator/mvfst.git
synced 2025-07-30 14:43:05 +03:00
add stats for quic datagram
Summary: Add stats for quic datagrams Reviewed By: afrind Differential Revision: D32600300 fbshipit-source-id: 79ebcec5bd090dad16f81237b6b2c0fe4c0f2af6
This commit is contained in:
committed by
Facebook GitHub Bot
parent
4a75224cc9
commit
324d819795
@ -630,6 +630,7 @@ bool DatagramFrameScheduler::writeDatagramFrames(
|
|||||||
auto& payload = conn_.datagramState.writeBuffer.front();
|
auto& payload = conn_.datagramState.writeBuffer.front();
|
||||||
auto datagramFrame = DatagramFrame(payload.chainLength(), payload.move());
|
auto datagramFrame = DatagramFrame(payload.chainLength(), payload.move());
|
||||||
if (writeFrame(datagramFrame, builder) > 0) {
|
if (writeFrame(datagramFrame, builder) > 0) {
|
||||||
|
QUIC_STATS(conn_.statsCallback, onDatagramWrite, payload.chainLength());
|
||||||
conn_.datagramState.writeBuffer.pop_front();
|
conn_.datagramState.writeBuffer.pop_front();
|
||||||
sent = true;
|
sent = true;
|
||||||
}
|
}
|
||||||
|
@ -2816,10 +2816,12 @@ folly::Expected<folly::Unit, LocalErrorCode> QuicTransportBase::writeDatagram(
|
|||||||
// https://github.com/quicwg/datagram/issues/3
|
// https://github.com/quicwg/datagram/issues/3
|
||||||
// For now, max_datagram_size > 0 means the peer supports datagram frames
|
// For now, max_datagram_size > 0 means the peer supports datagram frames
|
||||||
if (conn_->datagramState.maxWriteFrameSize == 0) {
|
if (conn_->datagramState.maxWriteFrameSize == 0) {
|
||||||
|
QUIC_STATS(conn_->statsCallback, onDatagramDroppedOnWrite);
|
||||||
return folly::makeUnexpected(LocalErrorCode::INVALID_WRITE_DATA);
|
return folly::makeUnexpected(LocalErrorCode::INVALID_WRITE_DATA);
|
||||||
}
|
}
|
||||||
if (conn_->datagramState.writeBuffer.size() >=
|
if (conn_->datagramState.writeBuffer.size() >=
|
||||||
conn_->datagramState.maxWriteBufferSize) {
|
conn_->datagramState.maxWriteBufferSize) {
|
||||||
|
QUIC_STATS(conn_->statsCallback, onDatagramDroppedOnWrite);
|
||||||
if (!conn_->transportSettings.datagramConfig.sendDropOldDataFirst) {
|
if (!conn_->transportSettings.datagramConfig.sendDropOldDataFirst) {
|
||||||
// TODO(lniccolini) use different return codes to signal the application
|
// TODO(lniccolini) use different return codes to signal the application
|
||||||
// exactly why the datagram got dropped
|
// exactly why the datagram got dropped
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include <quic/fizz/server/handshake/FizzServerQuicHandshakeContext.h>
|
#include <quic/fizz/server/handshake/FizzServerQuicHandshakeContext.h>
|
||||||
#include <quic/server/state/ServerStateMachine.h>
|
#include <quic/server/state/ServerStateMachine.h>
|
||||||
#include <quic/state/QuicStreamFunctions.h>
|
#include <quic/state/QuicStreamFunctions.h>
|
||||||
|
#include <quic/state/test/MockQuicStats.h>
|
||||||
|
|
||||||
using namespace quic;
|
using namespace quic;
|
||||||
using namespace testing;
|
using namespace testing;
|
||||||
@ -1859,6 +1860,9 @@ TEST_F(QuicPacketSchedulerTest, DatagramFrameSchedulerMultipleFramesPerPacket) {
|
|||||||
EXPECT_CALL(builder, appendFrame(_)).WillRepeatedly(Invoke([&](auto f) {
|
EXPECT_CALL(builder, appendFrame(_)).WillRepeatedly(Invoke([&](auto f) {
|
||||||
builder.frames_.push_back(f);
|
builder.frames_.push_back(f);
|
||||||
}));
|
}));
|
||||||
|
NiceMock<MockQuicStats> quicStats;
|
||||||
|
conn.statsCallback = &quicStats;
|
||||||
|
EXPECT_CALL(quicStats, onDatagramWrite(_)).Times(2);
|
||||||
// Call scheduler
|
// Call scheduler
|
||||||
auto& frames = builder.frames_;
|
auto& frames = builder.frames_;
|
||||||
scheduler.writeDatagramFrames(builder);
|
scheduler.writeDatagramFrames(builder);
|
||||||
@ -1882,10 +1886,14 @@ TEST_F(QuicPacketSchedulerTest, DatagramFrameSchedulerOneFramePerPacket) {
|
|||||||
EXPECT_CALL(builder, appendFrame(_)).WillRepeatedly(Invoke([&](auto f) {
|
EXPECT_CALL(builder, appendFrame(_)).WillRepeatedly(Invoke([&](auto f) {
|
||||||
builder.frames_.push_back(f);
|
builder.frames_.push_back(f);
|
||||||
}));
|
}));
|
||||||
|
NiceMock<MockQuicStats> quicStats;
|
||||||
|
conn.statsCallback = &quicStats;
|
||||||
// Call scheduler
|
// Call scheduler
|
||||||
auto& frames = builder.frames_;
|
auto& frames = builder.frames_;
|
||||||
|
EXPECT_CALL(quicStats, onDatagramWrite(_)).Times(1);
|
||||||
scheduler.writeDatagramFrames(builder);
|
scheduler.writeDatagramFrames(builder);
|
||||||
ASSERT_EQ(frames.size(), 1);
|
ASSERT_EQ(frames.size(), 1);
|
||||||
|
EXPECT_CALL(quicStats, onDatagramWrite(_)).Times(1);
|
||||||
scheduler.writeDatagramFrames(builder);
|
scheduler.writeDatagramFrames(builder);
|
||||||
ASSERT_EQ(frames.size(), 2);
|
ASSERT_EQ(frames.size(), 2);
|
||||||
}
|
}
|
||||||
@ -1906,12 +1914,15 @@ TEST_F(QuicPacketSchedulerTest, DatagramFrameWriteWhenRoomAvailable) {
|
|||||||
EXPECT_CALL(builder, appendFrame(_)).WillRepeatedly(Invoke([&](auto f) {
|
EXPECT_CALL(builder, appendFrame(_)).WillRepeatedly(Invoke([&](auto f) {
|
||||||
builder.frames_.push_back(f);
|
builder.frames_.push_back(f);
|
||||||
}));
|
}));
|
||||||
|
NiceMock<MockQuicStats> quicStats;
|
||||||
|
conn.statsCallback = &quicStats;
|
||||||
// Call scheduler
|
// Call scheduler
|
||||||
auto& frames = builder.frames_;
|
auto& frames = builder.frames_;
|
||||||
scheduler.writeDatagramFrames(builder);
|
scheduler.writeDatagramFrames(builder);
|
||||||
ASSERT_EQ(frames.size(), 0);
|
ASSERT_EQ(frames.size(), 0);
|
||||||
EXPECT_CALL(builder, remainingSpaceInPkt())
|
EXPECT_CALL(builder, remainingSpaceInPkt())
|
||||||
.WillRepeatedly(Return(conn.udpSendPacketLen / 2));
|
.WillRepeatedly(Return(conn.udpSendPacketLen / 2));
|
||||||
|
EXPECT_CALL(quicStats, onDatagramWrite(_)).Times(1);
|
||||||
scheduler.writeDatagramFrames(builder);
|
scheduler.writeDatagramFrames(builder);
|
||||||
ASSERT_EQ(frames.size(), 1);
|
ASSERT_EQ(frames.size(), 1);
|
||||||
}
|
}
|
||||||
|
@ -1337,7 +1337,8 @@ class QuicClientTransportTest : public Test {
|
|||||||
client->getConn().selfConnectionIds[0].connId,
|
client->getConn().selfConnectionIds[0].connId,
|
||||||
*client->getConn().clientConnectionId);
|
*client->getConn().clientConnectionId);
|
||||||
EXPECT_EQ(client->getConn().peerConnectionIds.size(), 0);
|
EXPECT_EQ(client->getConn().peerConnectionIds.size(), 0);
|
||||||
|
quicStats_ = std::make_shared<NiceMock<MockQuicStats>>();
|
||||||
|
client->setTransportStatsCallback(quicStats_);
|
||||||
SetUpChild();
|
SetUpChild();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1726,6 +1727,7 @@ class QuicClientTransportTest : public Test {
|
|||||||
folly::Optional<ConnectionId> originalConnId;
|
folly::Optional<ConnectionId> originalConnId;
|
||||||
folly::Optional<ConnectionId> serverChosenConnId;
|
folly::Optional<ConnectionId> serverChosenConnId;
|
||||||
QuicVersion version{QuicVersion::QUIC_V1};
|
QuicVersion version{QuicVersion::QUIC_V1};
|
||||||
|
std::shared_ptr<NiceMock<MockQuicStats>> quicStats_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(QuicClientTransportTest, ReadErrorCloseTransprot) {
|
TEST_F(QuicClientTransportTest, ReadErrorCloseTransprot) {
|
||||||
@ -5447,6 +5449,7 @@ TEST_F(QuicClientTransportAfterStartTest, ReceiveDatagramFrameAndDiscard) {
|
|||||||
0 /* largestAcked */);
|
0 /* largestAcked */);
|
||||||
builder.encodePacketHeader();
|
builder.encodePacketHeader();
|
||||||
|
|
||||||
|
EXPECT_CALL(*quicStats_, onDatagramDroppedOnRead()).Times(1);
|
||||||
StringPiece datagramPayload = "do not rely on me. I am unreliable";
|
StringPiece datagramPayload = "do not rely on me. I am unreliable";
|
||||||
DatagramFrame datagramFrame(
|
DatagramFrame datagramFrame(
|
||||||
datagramPayload.size(), IOBuf::copyBuffer(datagramPayload));
|
datagramPayload.size(), IOBuf::copyBuffer(datagramPayload));
|
||||||
@ -5461,6 +5464,10 @@ TEST_F(QuicClientTransportAfterStartTest, ReceiveDatagramFrameAndStore) {
|
|||||||
conn.datagramState.maxReadFrameSize = std::numeric_limits<uint16_t>::max();
|
conn.datagramState.maxReadFrameSize = std::numeric_limits<uint16_t>::max();
|
||||||
conn.datagramState.maxReadBufferSize = 10;
|
conn.datagramState.maxReadBufferSize = 10;
|
||||||
|
|
||||||
|
EXPECT_CALL(*quicStats_, onDatagramRead(_))
|
||||||
|
.Times(conn.datagramState.maxReadBufferSize);
|
||||||
|
EXPECT_CALL(*quicStats_, onDatagramDroppedOnRead())
|
||||||
|
.Times(conn.datagramState.maxReadBufferSize);
|
||||||
for (uint64_t i = 0; i < conn.datagramState.maxReadBufferSize * 2; i++) {
|
for (uint64_t i = 0; i < conn.datagramState.maxReadBufferSize * 2; i++) {
|
||||||
ShortHeader header(
|
ShortHeader header(
|
||||||
ProtectionType::KeyPhaseZero, *originalConnId, appDataPacketNum++);
|
ProtectionType::KeyPhaseZero, *originalConnId, appDataPacketNum++);
|
||||||
@ -5508,6 +5515,7 @@ TEST_F(
|
|||||||
datagramPayload1.size(), IOBuf::copyBuffer(datagramPayload1));
|
datagramPayload1.size(), IOBuf::copyBuffer(datagramPayload1));
|
||||||
writeFrame(datagramFrame1, builder1);
|
writeFrame(datagramFrame1, builder1);
|
||||||
auto packet1 = packetToBuf(std::move(builder1).buildPacket());
|
auto packet1 = packetToBuf(std::move(builder1).buildPacket());
|
||||||
|
EXPECT_CALL(*quicStats_, onDatagramRead(_)).Times(1);
|
||||||
deliverData(packet1->coalesce());
|
deliverData(packet1->coalesce());
|
||||||
ASSERT_EQ(
|
ASSERT_EQ(
|
||||||
client->getConn().datagramState.readBuffer.size(),
|
client->getConn().datagramState.readBuffer.size(),
|
||||||
@ -5525,6 +5533,8 @@ TEST_F(
|
|||||||
datagramPayload2.size(), IOBuf::copyBuffer(datagramPayload2));
|
datagramPayload2.size(), IOBuf::copyBuffer(datagramPayload2));
|
||||||
writeFrame(datagramFrame2, builder2);
|
writeFrame(datagramFrame2, builder2);
|
||||||
auto packet2 = packetToBuf(std::move(builder2).buildPacket());
|
auto packet2 = packetToBuf(std::move(builder2).buildPacket());
|
||||||
|
EXPECT_CALL(*quicStats_, onDatagramDroppedOnRead()).Times(1);
|
||||||
|
EXPECT_CALL(*quicStats_, onDatagramRead(_)).Times(1);
|
||||||
deliverData(packet2->coalesce());
|
deliverData(packet2->coalesce());
|
||||||
ASSERT_EQ(
|
ASSERT_EQ(
|
||||||
client->getConn().datagramState.readBuffer.size(),
|
client->getConn().datagramState.readBuffer.size(),
|
||||||
|
@ -202,6 +202,22 @@ class LogQuicStats : public quic::QuicTransportStatsCallback {
|
|||||||
VLOG(2) << prefix_ << "onZeroRttRejected";
|
VLOG(2) << prefix_ << "onZeroRttRejected";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void onDatagramRead(size_t datagramSize) override {
|
||||||
|
VLOG(2) << prefix_ << "onDatagramRead size=" << datagramSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void onDatagramWrite(size_t datagramSize) override {
|
||||||
|
VLOG(2) << prefix_ << "onDatagramWrite size=" << datagramSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void onDatagramDroppedOnWrite() override {
|
||||||
|
VLOG(2) << prefix_ << "onDatagramDroppedOnWrite";
|
||||||
|
}
|
||||||
|
|
||||||
|
void onDatagramDroppedOnRead() override {
|
||||||
|
VLOG(2) << prefix_ << "onDatagramDroppedOnRead";
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string prefix_;
|
std::string prefix_;
|
||||||
};
|
};
|
||||||
|
@ -3236,6 +3236,7 @@ TEST_F(QuicServerTransportTest, ReceiveDatagramFrameAndDiscard) {
|
|||||||
datagramPayload.size(), IOBuf::copyBuffer(datagramPayload));
|
datagramPayload.size(), IOBuf::copyBuffer(datagramPayload));
|
||||||
writeFrame(datagramFrame, builder);
|
writeFrame(datagramFrame, builder);
|
||||||
auto packet = std::move(builder).buildPacket();
|
auto packet = std::move(builder).buildPacket();
|
||||||
|
EXPECT_CALL(*transportInfoCb_, onDatagramDroppedOnRead()).Times(1);
|
||||||
deliverData(packetToBuf(packet));
|
deliverData(packetToBuf(packet));
|
||||||
ASSERT_EQ(server->getConn().datagramState.readBuffer.size(), 0);
|
ASSERT_EQ(server->getConn().datagramState.readBuffer.size(), 0);
|
||||||
}
|
}
|
||||||
@ -3245,6 +3246,10 @@ TEST_F(QuicServerTransportTest, ReceiveDatagramFrameAndStore) {
|
|||||||
conn.datagramState.maxReadFrameSize = std::numeric_limits<uint16_t>::max();
|
conn.datagramState.maxReadFrameSize = std::numeric_limits<uint16_t>::max();
|
||||||
conn.datagramState.maxReadBufferSize = 10;
|
conn.datagramState.maxReadBufferSize = 10;
|
||||||
|
|
||||||
|
EXPECT_CALL(*transportInfoCb_, onDatagramRead(_))
|
||||||
|
.Times(conn.datagramState.maxReadBufferSize);
|
||||||
|
EXPECT_CALL(*transportInfoCb_, onDatagramDroppedOnRead())
|
||||||
|
.Times(conn.datagramState.maxReadBufferSize);
|
||||||
for (uint64_t i = 0; i < conn.datagramState.maxReadBufferSize * 2; i++) {
|
for (uint64_t i = 0; i < conn.datagramState.maxReadBufferSize * 2; i++) {
|
||||||
ShortHeader header(
|
ShortHeader header(
|
||||||
ProtectionType::KeyPhaseZero,
|
ProtectionType::KeyPhaseZero,
|
||||||
|
@ -16,10 +16,12 @@ void handleDatagram(QuicConnectionStateBase& conn, DatagramFrame& frame) {
|
|||||||
// For now, max_datagram_size > 0 means the peer supports datagram frames
|
// For now, max_datagram_size > 0 means the peer supports datagram frames
|
||||||
if (conn.datagramState.maxReadFrameSize == 0) {
|
if (conn.datagramState.maxReadFrameSize == 0) {
|
||||||
frame.data.move();
|
frame.data.move();
|
||||||
|
QUIC_STATS(conn.statsCallback, onDatagramDroppedOnRead);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (conn.datagramState.readBuffer.size() >=
|
if (conn.datagramState.readBuffer.size() >=
|
||||||
conn.datagramState.maxReadBufferSize) {
|
conn.datagramState.maxReadBufferSize) {
|
||||||
|
QUIC_STATS(conn.statsCallback, onDatagramDroppedOnRead);
|
||||||
if (!conn.transportSettings.datagramConfig.recvDropOldDataFirst) {
|
if (!conn.transportSettings.datagramConfig.recvDropOldDataFirst) {
|
||||||
frame.data.move();
|
frame.data.move();
|
||||||
return;
|
return;
|
||||||
@ -27,6 +29,7 @@ void handleDatagram(QuicConnectionStateBase& conn, DatagramFrame& frame) {
|
|||||||
conn.datagramState.readBuffer.pop_front();
|
conn.datagramState.readBuffer.pop_front();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
QUIC_STATS(conn.statsCallback, onDatagramRead, frame.data.chainLength());
|
||||||
conn.datagramState.readBuffer.emplace_back(std::move(frame.data));
|
conn.datagramState.readBuffer.emplace_back(std::move(frame.data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,6 +168,14 @@ class QuicTransportStatsCallback {
|
|||||||
|
|
||||||
virtual void onZeroRttRejected() = 0;
|
virtual void onZeroRttRejected() = 0;
|
||||||
|
|
||||||
|
virtual void onDatagramRead(size_t datagramSize) = 0;
|
||||||
|
|
||||||
|
virtual void onDatagramWrite(size_t datagramSize) = 0;
|
||||||
|
|
||||||
|
virtual void onDatagramDroppedOnWrite() = 0;
|
||||||
|
|
||||||
|
virtual void onDatagramDroppedOnRead() = 0;
|
||||||
|
|
||||||
static const char* toString(PacketDropReason reason) {
|
static const char* toString(PacketDropReason reason) {
|
||||||
switch (reason) {
|
switch (reason) {
|
||||||
case PacketDropReason::NONE:
|
case PacketDropReason::NONE:
|
||||||
|
@ -60,6 +60,10 @@ class MockQuicStats : public QuicTransportStatsCallback {
|
|||||||
MOCK_METHOD0(onZeroRttBufferedPruned, void());
|
MOCK_METHOD0(onZeroRttBufferedPruned, void());
|
||||||
MOCK_METHOD0(onZeroRttAccepted, void());
|
MOCK_METHOD0(onZeroRttAccepted, void());
|
||||||
MOCK_METHOD0(onZeroRttRejected, void());
|
MOCK_METHOD0(onZeroRttRejected, void());
|
||||||
|
MOCK_METHOD1(onDatagramRead, void(size_t));
|
||||||
|
MOCK_METHOD1(onDatagramWrite, void(size_t));
|
||||||
|
MOCK_METHOD0(onDatagramDroppedOnWrite, void());
|
||||||
|
MOCK_METHOD0(onDatagramDroppedOnRead, void());
|
||||||
};
|
};
|
||||||
|
|
||||||
class MockQuicStatsFactory : public QuicTransportStatsCallbackFactory {
|
class MockQuicStatsFactory : public QuicTransportStatsCallbackFactory {
|
||||||
|
Reference in New Issue
Block a user