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

Add ToS field to ReceivedUdpPacket

Summary: Adds new field `tosValue` to  ReceivedUdpPacket so it is accessible in the rest of the read path.

Reviewed By: kvtsoy

Differential Revision: D54912161

fbshipit-source-id: ea4714fa2374d38e915fc850387e1094d1fb8adf
This commit is contained in:
Joseph Beshay
2024-05-15 11:51:15 -07:00
committed by Facebook GitHub Bot
parent 9c25029a11
commit 3eef6d0e55
16 changed files with 239 additions and 102 deletions

View File

@@ -1877,6 +1877,7 @@ void QuicTransportBase::onNetworkData(
Builder() Builder()
.setPacketReceiveTime(packet.timings.receiveTimePoint) .setPacketReceiveTime(packet.timings.receiveTimePoint)
.setPacketNumBytes(packet.buf.chainLength()) .setPacketNumBytes(packet.buf.chainLength())
.setPacketTos(packet.tosValue)
.build()); .build());
} }

View File

@@ -404,19 +404,19 @@ class TestQuicTransport
folly::Optional<StreamGroupId> groupId = folly::none) { folly::Optional<StreamGroupId> groupId = folly::none) {
auto buf = encodeStreamBuffer(id, std::move(data), std::move(groupId)); auto buf = encodeStreamBuffer(id, std::move(data), std::move(groupId));
SocketAddress addr("127.0.0.1", 1000); SocketAddress addr("127.0.0.1", 1000);
onNetworkData(addr, NetworkData(std::move(buf), Clock::now())); onNetworkData(addr, NetworkData(std::move(buf), Clock::now(), 0));
} }
void addCryptoData(StreamBuffer data) { void addCryptoData(StreamBuffer data) {
auto buf = encodeCryptoBuffer(std::move(data)); auto buf = encodeCryptoBuffer(std::move(data));
SocketAddress addr("127.0.0.1", 1000); SocketAddress addr("127.0.0.1", 1000);
onNetworkData(addr, NetworkData(std::move(buf), Clock::now())); onNetworkData(addr, NetworkData(std::move(buf), Clock::now(), 0));
} }
void addMaxStreamsFrame(MaxStreamsFrame frame) { void addMaxStreamsFrame(MaxStreamsFrame frame) {
auto buf = encodeMaxStreamsFrame(frame); auto buf = encodeMaxStreamsFrame(frame);
SocketAddress addr("127.0.0.1", 1000); SocketAddress addr("127.0.0.1", 1000);
onNetworkData(addr, NetworkData(std::move(buf), Clock::now())); onNetworkData(addr, NetworkData(std::move(buf), Clock::now(), 0));
} }
void addStreamReadError(StreamId id, QuicErrorCode ex) { void addStreamReadError(StreamId id, QuicErrorCode ex) {
@@ -432,7 +432,7 @@ class TestQuicTransport
void addDatagram(Buf data, TimePoint recvTime = Clock::now()) { void addDatagram(Buf data, TimePoint recvTime = Clock::now()) {
auto buf = encodeDatagramFrame(std::move(data)); auto buf = encodeDatagramFrame(std::move(data));
SocketAddress addr("127.0.0.1", 1000); SocketAddress addr("127.0.0.1", 1000);
onNetworkData(addr, NetworkData(std::move(buf), recvTime)); onNetworkData(addr, NetworkData(std::move(buf), recvTime, 0));
} }
void closeStream(StreamId id) { void closeStream(StreamId id) {
@@ -477,7 +477,7 @@ class TestQuicTransport
auto buf = encodeStreamBuffer( auto buf = encodeStreamBuffer(
id, id,
StreamBuffer(IOBuf::create(0), stream->maxOffsetObserved + 1, true)); StreamBuffer(IOBuf::create(0), stream->maxOffsetObserved + 1, true));
auto networkData = NetworkData(std::move(buf), Clock::now()); auto networkData = NetworkData(std::move(buf), Clock::now(), 0);
onNetworkData(addr, std::move(networkData)); onNetworkData(addr, std::move(networkData));
} }

View File

@@ -1440,7 +1440,7 @@ TEST_F(QuicTransportTest, ObserverStreamEventBidirectionalLocalOpenClose) {
transport_->getConnectionState().streamManager->addClosed(id); transport_->getConnectionState().streamManager->addClosed(id);
transport_->onNetworkData( transport_->onNetworkData(
SocketAddress("::1", 10000), SocketAddress("::1", 10000),
NetworkData(IOBuf::copyBuffer("fake data"), Clock::now())); NetworkData(ReceivedUdpPacket(IOBuf::copyBuffer("fake data"))));
EXPECT_CALL(*cb1, closeStarted(transport_.get(), _)); EXPECT_CALL(*cb1, closeStarted(transport_.get(), _));
EXPECT_CALL(*cb2, closeStarted(transport_.get(), _)); EXPECT_CALL(*cb2, closeStarted(transport_.get(), _));
@@ -1484,7 +1484,7 @@ TEST_F(QuicTransportTest, ObserverStreamEventBidirectionalRemoteOpenClose) {
transport_->getConnectionState().streamManager->addClosed(id); transport_->getConnectionState().streamManager->addClosed(id);
transport_->onNetworkData( transport_->onNetworkData(
SocketAddress("::1", 10000), SocketAddress("::1", 10000),
NetworkData(IOBuf::copyBuffer("fake data"), Clock::now())); NetworkData(ReceivedUdpPacket(IOBuf::copyBuffer("fake data"))));
EXPECT_CALL(*cb1, closeStarted(transport_.get(), _)); EXPECT_CALL(*cb1, closeStarted(transport_.get(), _));
EXPECT_CALL(*cb2, closeStarted(transport_.get(), _)); EXPECT_CALL(*cb2, closeStarted(transport_.get(), _));
@@ -1528,7 +1528,7 @@ TEST_F(QuicTransportTest, ObserverStreamEventUnidirectionalLocalOpenClose) {
transport_->getConnectionState().streamManager->addClosed(id); transport_->getConnectionState().streamManager->addClosed(id);
transport_->onNetworkData( transport_->onNetworkData(
SocketAddress("::1", 10000), SocketAddress("::1", 10000),
NetworkData(IOBuf::copyBuffer("fake data"), Clock::now())); NetworkData(ReceivedUdpPacket(IOBuf::copyBuffer("fake data"))));
EXPECT_CALL(*cb1, closeStarted(transport_.get(), _)); EXPECT_CALL(*cb1, closeStarted(transport_.get(), _));
EXPECT_CALL(*cb2, closeStarted(transport_.get(), _)); EXPECT_CALL(*cb2, closeStarted(transport_.get(), _));
@@ -1571,7 +1571,7 @@ TEST_F(QuicTransportTest, ObserverStreamEventUnidirectionalRemoteOpenClose) {
transport_->getConnectionState().streamManager->addClosed(id); transport_->getConnectionState().streamManager->addClosed(id);
transport_->onNetworkData( transport_->onNetworkData(
SocketAddress("::1", 10000), SocketAddress("::1", 10000),
NetworkData(IOBuf::copyBuffer("fake data"), Clock::now())); NetworkData(ReceivedUdpPacket(IOBuf::copyBuffer("fake data"))));
EXPECT_CALL(*cb1, closeStarted(transport_.get(), _)); EXPECT_CALL(*cb1, closeStarted(transport_.get(), _));
EXPECT_CALL(*cb2, closeStarted(transport_.get(), _)); EXPECT_CALL(*cb2, closeStarted(transport_.get(), _));
@@ -2804,7 +2804,7 @@ TEST_F(QuicTransportTest, NonWritableStreamAPI) {
EXPECT_CALL(writeCallback_, onStreamWriteReady(streamState->id, _)).Times(0); EXPECT_CALL(writeCallback_, onStreamWriteReady(streamState->id, _)).Times(0);
transport_->onNetworkData( transport_->onNetworkData(
SocketAddress("::1", 10000), SocketAddress("::1", 10000),
NetworkData(IOBuf::copyBuffer("fake data"), Clock::now())); NetworkData(ReceivedUdpPacket(IOBuf::copyBuffer("fake data"))));
// Check that write-side APIs return an error // Check that write-side APIs return an error
auto res2 = transport_->notifyPendingWriteOnStream(streamId, &writeCallback_); auto res2 = transport_->notifyPendingWriteOnStream(streamId, &writeCallback_);
@@ -3072,7 +3072,7 @@ TEST_F(QuicTransportTest, FlowControlCallbacks) {
.WillOnce(Invoke([&](auto) { transport_->createBidirectionalStream(); })); .WillOnce(Invoke([&](auto) { transport_->createBidirectionalStream(); }));
transport_->onNetworkData( transport_->onNetworkData(
SocketAddress("::1", 10000), SocketAddress("::1", 10000),
NetworkData(IOBuf::copyBuffer("fake data"), Clock::now())); NetworkData(ReceivedUdpPacket(IOBuf::copyBuffer("fake data"))));
EXPECT_FALSE(conn.streamManager->popFlowControlUpdated().has_value()); EXPECT_FALSE(conn.streamManager->popFlowControlUpdated().has_value());
} }
@@ -3985,7 +3985,7 @@ TEST_F(QuicTransportTest, NotifyPendingWriteConnAsync) {
EXPECT_CALL(writeCallback_, onConnectionWriteReady(_)); EXPECT_CALL(writeCallback_, onConnectionWriteReady(_));
transport_->onNetworkData( transport_->onNetworkData(
SocketAddress("::1", 10000), SocketAddress("::1", 10000),
NetworkData(IOBuf::copyBuffer("fake data"), Clock::now())); NetworkData(ReceivedUdpPacket(IOBuf::copyBuffer("fake data"))));
} }
TEST_F(QuicTransportTest, NotifyPendingWriteConnBufferFreeUpSpace) { TEST_F(QuicTransportTest, NotifyPendingWriteConnBufferFreeUpSpace) {
@@ -4011,7 +4011,7 @@ TEST_F(QuicTransportTest, NotifyPendingWriteConnBufferFreeUpSpace) {
transport_->onNetworkData( transport_->onNetworkData(
SocketAddress("::1", 10000), SocketAddress("::1", 10000),
NetworkData(IOBuf::copyBuffer("fake data"), Clock::now())); NetworkData(ReceivedUdpPacket(IOBuf::copyBuffer("fake data"))));
} }
TEST_F(QuicTransportTest, NoPacingTimerNoPacing) { TEST_F(QuicTransportTest, NoPacingTimerNoPacing) {
@@ -4066,7 +4066,7 @@ TEST_F(QuicTransportTest, NotifyPendingWriteConnBufferUseTotalSpace) {
transport_->onNetworkData( transport_->onNetworkData(
SocketAddress("::1", 10000), SocketAddress("::1", 10000),
NetworkData(IOBuf::copyBuffer("fake data"), Clock::now())); NetworkData(ReceivedUdpPacket(IOBuf::copyBuffer("fake data"))));
} }
TEST_F(QuicTransportTest, NotifyPendingWriteConnBufferOveruseSpace) { TEST_F(QuicTransportTest, NotifyPendingWriteConnBufferOveruseSpace) {
@@ -4090,7 +4090,7 @@ TEST_F(QuicTransportTest, NotifyPendingWriteConnBufferOveruseSpace) {
transport_->onNetworkData( transport_->onNetworkData(
SocketAddress("::1", 10000), SocketAddress("::1", 10000),
NetworkData(IOBuf::copyBuffer("fake data"), Clock::now())); NetworkData(ReceivedUdpPacket(IOBuf::copyBuffer("fake data"))));
} }
TEST_F( TEST_F(
@@ -4125,7 +4125,7 @@ TEST_F(
transport_->onNetworkData( transport_->onNetworkData(
SocketAddress("::1", 10000), SocketAddress("::1", 10000),
NetworkData(IOBuf::copyBuffer("fake data"), Clock::now())); NetworkData(ReceivedUdpPacket(IOBuf::copyBuffer("fake data"))));
} }
TEST_F(QuicTransportTest, NotifyPendingWriteStreamAsyncConnBlocked) { TEST_F(QuicTransportTest, NotifyPendingWriteStreamAsyncConnBlocked) {
@@ -4143,7 +4143,7 @@ TEST_F(QuicTransportTest, NotifyPendingWriteStreamAsyncConnBlocked) {
transport_->onNetworkData( transport_->onNetworkData(
SocketAddress("::1", 10000), SocketAddress("::1", 10000),
NetworkData(IOBuf::copyBuffer("fake data"), Clock::now())); NetworkData(ReceivedUdpPacket(IOBuf::copyBuffer("fake data"))));
EXPECT_CALL(writeCallback_, onStreamWriteReady(stream->id, _)); EXPECT_CALL(writeCallback_, onStreamWriteReady(stream->id, _));
@@ -4155,7 +4155,7 @@ TEST_F(QuicTransportTest, NotifyPendingWriteStreamAsyncConnBlocked) {
num); num);
transport_->onNetworkData( transport_->onNetworkData(
SocketAddress("::1", 10000), SocketAddress("::1", 10000),
NetworkData(IOBuf::copyBuffer("fake data"), Clock::now())); NetworkData(ReceivedUdpPacket(IOBuf::copyBuffer("fake data"))));
} }
TEST_F(QuicTransportTest, NotifyPendingWriteStreamWritableBytesBackpressure) { TEST_F(QuicTransportTest, NotifyPendingWriteStreamWritableBytesBackpressure) {
@@ -4177,7 +4177,7 @@ TEST_F(QuicTransportTest, NotifyPendingWriteStreamWritableBytesBackpressure) {
transport_->onNetworkData( transport_->onNetworkData(
SocketAddress("::1", 10000), SocketAddress("::1", 10000),
NetworkData(IOBuf::copyBuffer("fake data"), Clock::now())); NetworkData(ReceivedUdpPacket(IOBuf::copyBuffer("fake data"))));
auto mockCongestionController = auto mockCongestionController =
std::make_unique<NiceMock<MockCongestionController>>(); std::make_unique<NiceMock<MockCongestionController>>();
@@ -4200,7 +4200,7 @@ TEST_F(QuicTransportTest, NotifyPendingWriteStreamWritableBytesBackpressure) {
num); num);
transport_->onNetworkData( transport_->onNetworkData(
SocketAddress("::1", 10000), SocketAddress("::1", 10000),
NetworkData(IOBuf::copyBuffer("fake data"), Clock::now())); NetworkData(ReceivedUdpPacket(IOBuf::copyBuffer("fake data"))));
} }
TEST_F(QuicTransportTest, NotifyPendingWriteStreamAsyncStreamBlocked) { TEST_F(QuicTransportTest, NotifyPendingWriteStreamAsyncStreamBlocked) {
@@ -4217,7 +4217,7 @@ TEST_F(QuicTransportTest, NotifyPendingWriteStreamAsyncStreamBlocked) {
transport_->onNetworkData( transport_->onNetworkData(
SocketAddress("::1", 10000), SocketAddress("::1", 10000),
NetworkData(IOBuf::copyBuffer("fake data"), Clock::now())); NetworkData(ReceivedUdpPacket(IOBuf::copyBuffer("fake data"))));
PacketNum num = 10; PacketNum num = 10;
handleStreamWindowUpdate( handleStreamWindowUpdate(
@@ -4227,7 +4227,7 @@ TEST_F(QuicTransportTest, NotifyPendingWriteStreamAsyncStreamBlocked) {
transport_->onNetworkData( transport_->onNetworkData(
SocketAddress("::1", 10000), SocketAddress("::1", 10000),
NetworkData(IOBuf::copyBuffer("fake data"), Clock::now())); NetworkData(ReceivedUdpPacket(IOBuf::copyBuffer("fake data"))));
} }
TEST_F(QuicTransportTest, NotifyPendingWriteConnTwice) { TEST_F(QuicTransportTest, NotifyPendingWriteConnTwice) {
@@ -4297,7 +4297,7 @@ TEST_F(QuicTransportTest, NotifyPendingWriteConnDuringClose) {
num); num);
transport_->onNetworkData( transport_->onNetworkData(
SocketAddress("::1", 10000), SocketAddress("::1", 10000),
NetworkData(IOBuf::copyBuffer("fake data"), Clock::now())); NetworkData(ReceivedUdpPacket(IOBuf::copyBuffer("fake data"))));
} }
TEST_F(QuicTransportTest, NotifyPendingWriteStreamDuringClose) { TEST_F(QuicTransportTest, NotifyPendingWriteStreamDuringClose) {
@@ -4326,7 +4326,7 @@ TEST_F(QuicTransportTest, NotifyPendingWriteStreamDuringClose) {
.WillOnce(Invoke([&](auto, auto) { transport_->close(folly::none); })); .WillOnce(Invoke([&](auto, auto) { transport_->close(folly::none); }));
transport_->onNetworkData( transport_->onNetworkData(
SocketAddress("::1", 10000), SocketAddress("::1", 10000),
NetworkData(IOBuf::copyBuffer("fake data"), Clock::now())); NetworkData(ReceivedUdpPacket(IOBuf::copyBuffer("fake data"))));
} }
TEST_F(QuicTransportTest, WriteStreamFromMiddleOfMap) { TEST_F(QuicTransportTest, WriteStreamFromMiddleOfMap) {
@@ -4450,7 +4450,7 @@ TEST_F(QuicTransportTest, CancelAckTimeout) {
transport_->getConnectionState().pendingEvents.scheduleAckTimeout = false; transport_->getConnectionState().pendingEvents.scheduleAckTimeout = false;
transport_->onNetworkData( transport_->onNetworkData(
SocketAddress("::1", 10128), SocketAddress("::1", 10128),
NetworkData(IOBuf::copyBuffer("MTA New York Service"), Clock::now())); NetworkData(ReceivedUdpPacket(IOBuf::copyBuffer("fake data"))));
EXPECT_FALSE(transport_->getAckTimeout()->isTimerCallbackScheduled()); EXPECT_FALSE(transport_->getAckTimeout()->isTimerCallbackScheduled());
} }
@@ -4461,8 +4461,7 @@ TEST_F(QuicTransportTest, ScheduleAckTimeout) {
transport_->getConnectionState().pendingEvents.scheduleAckTimeout = true; transport_->getConnectionState().pendingEvents.scheduleAckTimeout = true;
transport_->onNetworkData( transport_->onNetworkData(
SocketAddress("::1", 10003), SocketAddress("::1", 10003),
NetworkData( NetworkData(ReceivedUdpPacket(IOBuf::copyBuffer("fake data"))));
IOBuf::copyBuffer("Never on time, always timeout"), Clock::now()));
EXPECT_TRUE(transport_->getAckTimeout()->isTimerCallbackScheduled()); EXPECT_TRUE(transport_->getAckTimeout()->isTimerCallbackScheduled());
EXPECT_NEAR( EXPECT_NEAR(
transport_->getAckTimeout()->getTimerCallbackTimeRemaining().count(), transport_->getAckTimeout()->getTimerCallbackTimeRemaining().count(),
@@ -4476,8 +4475,7 @@ TEST_F(QuicTransportTest, ScheduleAckTimeoutSRTTFactor) {
transport_->getConnectionState().pendingEvents.scheduleAckTimeout = true; transport_->getConnectionState().pendingEvents.scheduleAckTimeout = true;
transport_->onNetworkData( transport_->onNetworkData(
SocketAddress("::1", 10003), SocketAddress("::1", 10003),
NetworkData( NetworkData(ReceivedUdpPacket(IOBuf::copyBuffer("fake data"))));
IOBuf::copyBuffer("Never on time, always timeout"), Clock::now()));
EXPECT_TRUE(transport_->getAckTimeout()->isTimerCallbackScheduled()); EXPECT_TRUE(transport_->getAckTimeout()->isTimerCallbackScheduled());
EXPECT_NEAR( EXPECT_NEAR(
transport_->getAckTimeout()->getTimerCallbackTimeRemaining().count(), transport_->getAckTimeout()->getTimerCallbackTimeRemaining().count(),
@@ -4495,8 +4493,7 @@ TEST_F(QuicTransportTest, ScheduleAckTimeoutAckFreq) {
transport_->getConnectionState().pendingEvents.scheduleAckTimeout = true; transport_->getConnectionState().pendingEvents.scheduleAckTimeout = true;
transport_->onNetworkData( transport_->onNetworkData(
SocketAddress("::1", 10003), SocketAddress("::1", 10003),
NetworkData( NetworkData(ReceivedUdpPacket(IOBuf::copyBuffer("fake data"))));
IOBuf::copyBuffer("Never on time, always timeout"), Clock::now()));
EXPECT_TRUE(transport_->getAckTimeout()->isTimerCallbackScheduled()); EXPECT_TRUE(transport_->getAckTimeout()->isTimerCallbackScheduled());
EXPECT_NEAR( EXPECT_NEAR(
transport_->getAckTimeout()->getTimerCallbackTimeRemaining().count(), transport_->getAckTimeout()->getTimerCallbackTimeRemaining().count(),
@@ -4512,8 +4509,7 @@ TEST_F(QuicTransportTest, ScheduleAckTimeoutFromMaxAckDelay) {
transport_->getConnectionState().pendingEvents.scheduleAckTimeout = true; transport_->getConnectionState().pendingEvents.scheduleAckTimeout = true;
transport_->onNetworkData( transport_->onNetworkData(
SocketAddress("::1", 10003), SocketAddress("::1", 10003),
NetworkData( NetworkData(ReceivedUdpPacket(IOBuf::copyBuffer("fake data"))));
IOBuf::copyBuffer("Never on time, always timeout"), Clock::now()));
EXPECT_TRUE(transport_->getAckTimeout()->isTimerCallbackScheduled()); EXPECT_TRUE(transport_->getAckTimeout()->isTimerCallbackScheduled());
EXPECT_NEAR( EXPECT_NEAR(
transport_->getAckTimeout()->getTimerCallbackTimeRemaining().count(), transport_->getAckTimeout()->getTimerCallbackTimeRemaining().count(),
@@ -4527,8 +4523,7 @@ TEST_F(QuicTransportTest, CloseTransportCancelsAckTimeout) {
transport_->getConnectionState().pendingEvents.scheduleAckTimeout = true; transport_->getConnectionState().pendingEvents.scheduleAckTimeout = true;
transport_->onNetworkData( transport_->onNetworkData(
SocketAddress("::1", 10003), SocketAddress("::1", 10003),
NetworkData( NetworkData(ReceivedUdpPacket(IOBuf::copyBuffer("fake data"))));
IOBuf::copyBuffer("Never on time, always timeout"), Clock::now()));
EXPECT_TRUE(transport_->getAckTimeout()->isTimerCallbackScheduled()); EXPECT_TRUE(transport_->getAckTimeout()->isTimerCallbackScheduled());
// We need to send some packets, otherwise loss timer won't be scheduled // We need to send some packets, otherwise loss timer won't be scheduled
auto stream = transport_->createBidirectionalStream().value(); auto stream = transport_->createBidirectionalStream().value();

View File

@@ -1723,6 +1723,11 @@ struct ReceivedUdpPacketMatcherBuilder {
maybeExpectedPacketNumBytes = expectedPacketNumBytes; maybeExpectedPacketNumBytes = expectedPacketNumBytes;
return std::move(*this); return std::move(*this);
} }
Builder&& setExpectedTosValue(const uint8_t expectedTosValue) {
maybeExpectedTosValue = expectedTosValue;
return std::move(*this);
}
auto build() && { auto build() && {
CHECK(maybeExpectedPacketReceiveTime.has_value()); CHECK(maybeExpectedPacketReceiveTime.has_value());
const auto& packetReceiveTime = *maybeExpectedPacketReceiveTime; const auto& packetReceiveTime = *maybeExpectedPacketReceiveTime;
@@ -1730,6 +1735,9 @@ struct ReceivedUdpPacketMatcherBuilder {
CHECK(maybeExpectedPacketNumBytes.has_value()); CHECK(maybeExpectedPacketNumBytes.has_value());
const auto& packetNumBytes = *maybeExpectedPacketNumBytes; const auto& packetNumBytes = *maybeExpectedPacketNumBytes;
CHECK(maybeExpectedTosValue.has_value());
const auto& packetTosValue = *maybeExpectedTosValue;
if constexpr (std::is_base_of_v<T, QuicClientTransportTestBase>) { if constexpr (std::is_base_of_v<T, QuicClientTransportTestBase>) {
return testing::AllOf( return testing::AllOf(
// client does not currently support socket RX timestamps, so we // client does not currently support socket RX timestamps, so we
@@ -1739,12 +1747,20 @@ struct ReceivedUdpPacketMatcherBuilder {
testing::AnyOf( testing::AnyOf(
testing::Eq(packetReceiveTime), testing::Eq(packetReceiveTime),
testing::Ge(TimePoint::clock::now()))), testing::Ge(TimePoint::clock::now()))),
testing::Field(&Obj::packetNumBytes, testing::Eq(packetNumBytes))); testing::Field(&Obj::packetNumBytes, testing::Eq(packetNumBytes)),
testing::Field(&Obj::packetTos, testing::Eq(packetTosValue)));
} else if constexpr (std::is_base_of_v<T, QuicServerTransportTestBase>) { } else if constexpr (std::is_base_of_v<T, QuicServerTransportTestBase>) {
return testing::AllOf( return testing::AllOf(
testing::Field( testing::Field(
&Obj::packetReceiveTime, testing::Eq(packetReceiveTime)), "packetReceiveTime",
testing::Field(&Obj::packetNumBytes, testing::Eq(packetNumBytes))); &Obj::packetReceiveTime,
testing::Eq(packetReceiveTime)),
testing::Field(
"packetNumBytes",
&Obj::packetNumBytes,
testing::Eq(packetNumBytes)),
testing::Field(
"packetTos", &Obj::packetTos, testing::Eq(packetTosValue)));
} else { } else {
FAIL(); // unhandled typed test FAIL(); // unhandled typed test
} }
@@ -1753,6 +1769,7 @@ struct ReceivedUdpPacketMatcherBuilder {
folly::Optional<TimePoint> maybeExpectedPacketReceiveTime; folly::Optional<TimePoint> maybeExpectedPacketReceiveTime;
folly::Optional<uint64_t> maybeExpectedPacketNumBytes; folly::Optional<uint64_t> maybeExpectedPacketNumBytes;
folly::Optional<uint8_t> maybeExpectedTosValue;
}; };
template <typename T> template <typename T>
@@ -4951,6 +4968,7 @@ TYPED_TEST(
this->buildPeerPacketWithStreamData(streamId, buildRandomInputData(100)); this->buildPeerPacketWithStreamData(streamId, buildRandomInputData(100));
const auto pkt1RecvTime = TimePoint::clock::now(); const auto pkt1RecvTime = TimePoint::clock::now();
const auto pkt1NumBytes = pkt1->computeChainDataLength(); const auto pkt1NumBytes = pkt1->computeChainDataLength();
const uint8_t packetTosValue = kEcnECT0;
{ {
const auto matcher = testing::AllOf( const auto matcher = testing::AllOf(
testing::Field( testing::Field(
@@ -4963,13 +4981,14 @@ TYPED_TEST(
testing::ElementsAre(ReceivedUdpPacketMatcherBuilder<TypeParam>() testing::ElementsAre(ReceivedUdpPacketMatcherBuilder<TypeParam>()
.setExpectedPacketReceiveTime(pkt1RecvTime) .setExpectedPacketReceiveTime(pkt1RecvTime)
.setExpectedPacketNumBytes(pkt1NumBytes) .setExpectedPacketNumBytes(pkt1NumBytes)
.setExpectedTosValue(packetTosValue)
.build()))); .build())));
EXPECT_CALL(*obs1, packetsReceived(_, _)).Times(0); EXPECT_CALL(*obs1, packetsReceived(_, _)).Times(0);
EXPECT_CALL(*obs2, packetsReceived(transport, matcher)); EXPECT_CALL(*obs2, packetsReceived(transport, matcher));
EXPECT_CALL(*obs3, packetsReceived(transport, matcher)); EXPECT_CALL(*obs3, packetsReceived(transport, matcher));
} }
this->deliverPacket(std::move(pkt1), pkt1RecvTime); this->deliverPacket(std::move(pkt1), pkt1RecvTime, packetTosValue);
// deliver pkt2 with stream data from the remote // deliver pkt2 with stream data from the remote
auto pkt2 = auto pkt2 =
@@ -4989,13 +5008,14 @@ TYPED_TEST(
testing::ElementsAre(ReceivedUdpPacketMatcherBuilder<TypeParam>() testing::ElementsAre(ReceivedUdpPacketMatcherBuilder<TypeParam>()
.setExpectedPacketReceiveTime(pkt2RecvTime) .setExpectedPacketReceiveTime(pkt2RecvTime)
.setExpectedPacketNumBytes(pkt2NumBytes) .setExpectedPacketNumBytes(pkt2NumBytes)
.setExpectedTosValue(packetTosValue)
.build()))); .build())));
EXPECT_CALL(*obs1, packetsReceived(_, _)).Times(0); EXPECT_CALL(*obs1, packetsReceived(_, _)).Times(0);
EXPECT_CALL(*obs2, packetsReceived(transport, matcher)); EXPECT_CALL(*obs2, packetsReceived(transport, matcher));
EXPECT_CALL(*obs3, packetsReceived(transport, matcher)); EXPECT_CALL(*obs3, packetsReceived(transport, matcher));
} }
this->deliverPacket(std::move(pkt2), pkt2RecvTime); this->deliverPacket(std::move(pkt2), pkt2RecvTime, packetTosValue);
this->destroyTransport(); this->destroyTransport();
} }
@@ -5045,33 +5065,46 @@ TYPED_TEST(
pktBatch1.emplace_back(std::move(pkt2)); pktBatch1.emplace_back(std::move(pkt2));
const auto pktBatch1RecvTime = TimePoint::clock::now(); const auto pktBatch1RecvTime = TimePoint::clock::now();
const auto pktBatch1NumBytes = pkt1NumBytes + pkt2NumBytes; const auto pktBatch1NumBytes = pkt1NumBytes + pkt2NumBytes;
const uint8_t packetTosValue = kEcnECT1;
{ {
const auto matcher = testing::AllOf( const auto matcher = testing::AllOf(
testing::Field( testing::Field(
&Event::receiveLoopTime, testing::Ge(TimePoint::clock::now())), "receiveLoopTime",
testing::Field(&Event::numPacketsReceived, testing::Eq(2)), &Event::receiveLoopTime,
testing::Ge(TimePoint::clock::now())),
testing::Field( testing::Field(
&Event::numBytesReceived, testing::Eq(pktBatch1NumBytes)), "numPacketsReceived", &Event::numPacketsReceived, testing::Eq(2)),
testing::Field(&Event::receivedPackets, testing::SizeIs(2)),
testing::Field( testing::Field(
"numBytesReceived",
&Event::numBytesReceived,
testing::Eq(pktBatch1NumBytes)),
testing::Field(
"receivedPacketsCount",
&Event::receivedPackets,
testing::SizeIs(2)),
testing::Field(
"receivedPacketsElements",
&Event::receivedPackets, &Event::receivedPackets,
testing::ElementsAre( testing::ElementsAre(
// pkt1 // pkt1
ReceivedUdpPacketMatcherBuilder<TypeParam>() ReceivedUdpPacketMatcherBuilder<TypeParam>()
.setExpectedPacketReceiveTime(pktBatch1RecvTime) .setExpectedPacketReceiveTime(pktBatch1RecvTime)
.setExpectedPacketNumBytes(pkt1NumBytes) .setExpectedPacketNumBytes(pkt1NumBytes)
.setExpectedTosValue(packetTosValue)
.build(), .build(),
// pkt2 // pkt2
ReceivedUdpPacketMatcherBuilder<TypeParam>() ReceivedUdpPacketMatcherBuilder<TypeParam>()
.setExpectedPacketReceiveTime(pktBatch1RecvTime) .setExpectedPacketReceiveTime(pktBatch1RecvTime)
.setExpectedPacketNumBytes(pkt2NumBytes) .setExpectedPacketNumBytes(pkt2NumBytes)
.setExpectedTosValue(packetTosValue)
.build()))); .build())));
EXPECT_CALL(*obs1, packetsReceived(_, _)).Times(0); EXPECT_CALL(*obs1, packetsReceived(_, _)).Times(0);
EXPECT_CALL(*obs2, packetsReceived(transport, matcher)); EXPECT_CALL(*obs2, packetsReceived(transport, matcher));
EXPECT_CALL(*obs3, packetsReceived(transport, matcher)); EXPECT_CALL(*obs3, packetsReceived(transport, matcher));
} }
this->deliverPackets(std::move(pktBatch1), pktBatch1RecvTime); this->deliverPackets(std::move(pktBatch1), pktBatch1RecvTime, packetTosValue);
// deliver pkt3 and pkt4 at same time with stream data from the remote // deliver pkt3 and pkt4 at same time with stream data from the remote
auto pkt3 = auto pkt3 =
@@ -5103,18 +5136,20 @@ TYPED_TEST(
ReceivedUdpPacketMatcherBuilder<TypeParam>() ReceivedUdpPacketMatcherBuilder<TypeParam>()
.setExpectedPacketReceiveTime(pktBatch2RecvTime) .setExpectedPacketReceiveTime(pktBatch2RecvTime)
.setExpectedPacketNumBytes(pkt3NumBytes) .setExpectedPacketNumBytes(pkt3NumBytes)
.setExpectedTosValue(packetTosValue)
.build(), .build(),
// pkt2 // pkt2
ReceivedUdpPacketMatcherBuilder<TypeParam>() ReceivedUdpPacketMatcherBuilder<TypeParam>()
.setExpectedPacketReceiveTime(pktBatch2RecvTime) .setExpectedPacketReceiveTime(pktBatch2RecvTime)
.setExpectedPacketNumBytes(pkt4NumBytes) .setExpectedPacketNumBytes(pkt4NumBytes)
.setExpectedTosValue(packetTosValue)
.build()))); .build())));
EXPECT_CALL(*obs1, packetsReceived(_, _)).Times(0); EXPECT_CALL(*obs1, packetsReceived(_, _)).Times(0);
EXPECT_CALL(*obs2, packetsReceived(transport, matcher)); EXPECT_CALL(*obs2, packetsReceived(transport, matcher));
EXPECT_CALL(*obs3, packetsReceived(transport, matcher)); EXPECT_CALL(*obs3, packetsReceived(transport, matcher));
} }
this->deliverPackets(std::move(pktBatch2), pktBatch2RecvTime); this->deliverPackets(std::move(pktBatch2), pktBatch2RecvTime, packetTosValue);
this->destroyTransport(); this->destroyTransport();
} }

View File

@@ -160,7 +160,8 @@ class QuicTypedTransportTestBase : protected QuicTransportTestClass {
pnSpace, pnSpace,
oldestOutstandingPkt->packet.header.getPacketSequenceNum(), oldestOutstandingPkt->packet.header.getPacketSequenceNum(),
newestOutstandingPkt->packet.header.getPacketSequenceNum()), newestOutstandingPkt->packet.header.getPacketSequenceNum()),
recvTime), recvTime,
0),
false /* loopForWrites */); false /* loopForWrites */);
} }
@@ -180,9 +181,10 @@ class QuicTypedTransportTestBase : protected QuicTransportTestClass {
void deliverPacket( void deliverPacket(
Buf&& buf, Buf&& buf,
quic::TimePoint recvTime = TimePoint::clock::now(), quic::TimePoint recvTime = TimePoint::clock::now(),
uint8_t tosValue = 0,
bool loopForWrites = true) { bool loopForWrites = true) {
QuicTransportTestClass::deliverData( QuicTransportTestClass::deliverData(
NetworkData(std::move(buf), recvTime), loopForWrites); NetworkData(std::move(buf), recvTime, tosValue), loopForWrites);
} }
/** /**
@@ -190,8 +192,10 @@ class QuicTypedTransportTestBase : protected QuicTransportTestClass {
*/ */
void deliverPacketNoWrites( void deliverPacketNoWrites(
Buf&& buf, Buf&& buf,
quic::TimePoint recvTime = TimePoint::clock::now()) { quic::TimePoint recvTime = TimePoint::clock::now(),
deliverPacket(std::move(buf), recvTime, false /* loopForWrites */); uint8_t tosValue = 0) {
deliverPacket(
std::move(buf), recvTime, tosValue, false /* loopForWrites */);
} }
/** /**
@@ -200,9 +204,20 @@ class QuicTypedTransportTestBase : protected QuicTransportTestClass {
void deliverPackets( void deliverPackets(
std::vector<Buf>&& bufs, std::vector<Buf>&& bufs,
quic::TimePoint recvTime = TimePoint::clock::now(), quic::TimePoint recvTime = TimePoint::clock::now(),
uint8_t tosValue = 0,
bool loopForWrites = true) { bool loopForWrites = true) {
QuicTransportTestClass::deliverData( auto networkData = NetworkData();
NetworkData(std::move(bufs), recvTime), loopForWrites); // This overrides the timing in added packets.
networkData.setReceiveTimePoint(recvTime);
for (auto& buf : bufs) {
auto udpPacket = ReceivedUdpPacket(
std::move(buf),
ReceivedUdpPacket::Timings{}, // NetworkData receiveTimePoint will
// override this
tosValue);
networkData.addPacket(std::move(udpPacket));
}
QuicTransportTestClass::deliverData(std::move(networkData), loopForWrites);
} }
/** /**

View File

@@ -268,7 +268,9 @@ void QuicClientTransport::processUdpPacketData(
: clientConn_->pendingHandshakeData; : clientConn_->pendingHandshakeData;
pendingData.emplace_back( pendingData.emplace_back(
ReceivedUdpPacket( ReceivedUdpPacket(
std::move(cipherUnavailable->packet), udpPacket.timings), std::move(cipherUnavailable->packet),
udpPacket.timings,
udpPacket.tosValue),
peer); peer);
if (conn_->qLogger) { if (conn_->qLogger) {
conn_->qLogger->addPacketBuffered( conn_->qLogger->addPacketBuffered(
@@ -1190,7 +1192,9 @@ void QuicClientTransport::recvMsg(
msg.msg_iovlen = 1; msg.msg_iovlen = 1;
#ifdef FOLLY_HAVE_MSG_ERRQUEUE #ifdef FOLLY_HAVE_MSG_ERRQUEUE
bool useGRO = sock.getGRO() > 0; bool useGRO = sock.getGRO() > 0;
bool checkCmsgs = useGRO || sock.getTimestamping() > 0 || sock.getRecvTos(); bool useTs = sock.getTimestamping() > 0;
bool recvTos = sock.getRecvTos();
bool checkCmsgs = useGRO || useTs || recvTos;
char control char control
[QuicAsyncUDPSocket::ReadCallback::OnDataAvailableParams::kCmsgSpace] = [QuicAsyncUDPSocket::ReadCallback::OnDataAvailableParams::kCmsgSpace] =
{}; {};
@@ -1266,18 +1270,21 @@ void QuicClientTransport::recvMsg(
offset += params.gro; offset += params.gro;
remaining -= params.gro; remaining -= params.gro;
networkData.addPacket(ReceivedUdpPacket(std::move(tmp))); networkData.addPacket(ReceivedUdpPacket(
std::move(tmp), ReceivedUdpPacket::Timings{}, params.tos));
} else { } else {
// do not clone the last packet // do not clone the last packet
// start at offset, use all the remaining data // start at offset, use all the remaining data
readBuffer->trimStart(offset); readBuffer->trimStart(offset);
DCHECK_EQ(readBuffer->length(), remaining); DCHECK_EQ(readBuffer->length(), remaining);
remaining = 0; remaining = 0;
networkData.addPacket(ReceivedUdpPacket(std::move(readBuffer))); networkData.addPacket(ReceivedUdpPacket(
std::move(readBuffer), ReceivedUdpPacket::Timings{}, params.tos));
} }
} }
} else { } else {
networkData.addPacket(ReceivedUdpPacket(std::move(readBuffer))); networkData.addPacket(ReceivedUdpPacket(
std::move(readBuffer), ReceivedUdpPacket::Timings{}, params.tos));
} }
maybeQlogDatagram(bytesRead); maybeQlogDatagram(bytesRead);
} }
@@ -1296,7 +1303,9 @@ void QuicClientTransport::recvMmsg(
int flags = 0; int flags = 0;
#ifdef FOLLY_HAVE_MSG_ERRQUEUE #ifdef FOLLY_HAVE_MSG_ERRQUEUE
bool useGRO = sock.getGRO() > 0; bool useGRO = sock.getGRO() > 0;
bool checkCmsgs = useGRO || sock.getTimestamping() > 0 || sock.getRecvTos(); bool useTs = sock.getTimestamping() > 0;
bool recvTos = sock.getRecvTos();
bool checkCmsgs = useGRO || useTs || recvTos;
std::vector<std::array< std::vector<std::array<
char, char,
QuicAsyncUDPSocket::ReadCallback::OnDataAvailableParams::kCmsgSpace>> QuicAsyncUDPSocket::ReadCallback::OnDataAvailableParams::kCmsgSpace>>
@@ -1411,18 +1420,21 @@ void QuicClientTransport::recvMmsg(
offset += params.gro; offset += params.gro;
remaining -= params.gro; remaining -= params.gro;
networkData.addPacket(ReceivedUdpPacket(std::move(tmp))); networkData.addPacket(ReceivedUdpPacket(
std::move(tmp), ReceivedUdpPacket::Timings{}, params.tos));
} else { } else {
// do not clone the last packet // do not clone the last packet
// start at offset, use all the remaining data // start at offset, use all the remaining data
readBuffer->trimStart(offset); readBuffer->trimStart(offset);
DCHECK_EQ(readBuffer->length(), remaining); DCHECK_EQ(readBuffer->length(), remaining);
remaining = 0; remaining = 0;
networkData.addPacket(ReceivedUdpPacket(std::move(readBuffer))); networkData.addPacket(ReceivedUdpPacket(
std::move(readBuffer), ReceivedUdpPacket::Timings{}, params.tos));
} }
} }
} else { } else {
networkData.addPacket(ReceivedUdpPacket(std::move(readBuffer))); networkData.addPacket(ReceivedUdpPacket(
std::move(readBuffer), ReceivedUdpPacket::Timings{}, params.tos));
} }
maybeQlogDatagram(bytesRead); maybeQlogDatagram(bytesRead);

View File

@@ -56,21 +56,30 @@ struct ReceivedUdpPacket {
ReceivedUdpPacket() = default; ReceivedUdpPacket() = default;
explicit ReceivedUdpPacket(Buf&& bufIn) : buf(std::move(bufIn)) {} explicit ReceivedUdpPacket(Buf&& bufIn) : buf(std::move(bufIn)) {}
ReceivedUdpPacket(Buf&& bufIn, Timings timingsIn) ReceivedUdpPacket(Buf&& bufIn, Timings timingsIn, uint8_t tosValueIn)
: buf(std::move(bufIn)), timings(std::move(timingsIn)) {} : buf(std::move(bufIn)),
timings(std::move(timingsIn)),
tosValue(tosValueIn) {}
BufQueue buf; BufQueue buf;
Timings timings; Timings timings;
// ToS / TClass value
uint8_t tosValue{0};
}; };
struct NetworkData { struct NetworkData {
NetworkData() = default; NetworkData() = default;
NetworkData(Buf&& buf, const TimePoint& receiveTimePointIn) NetworkData(
Buf&& buf,
const TimePoint& receiveTimePointIn,
uint8_t tosValueIn)
: receiveTimePoint_(receiveTimePointIn) { : receiveTimePoint_(receiveTimePointIn) {
if (buf) { if (buf) {
totalData_ = buf->computeChainDataLength(); totalData_ = buf->computeChainDataLength();
packets_.emplace_back(std::move(buf)); packets_.emplace_back(std::move(buf));
packets_.back().timings.receiveTimePoint = receiveTimePointIn; packets_.back().timings.receiveTimePoint = receiveTimePointIn;
packets_.back().tosValue = tosValueIn;
} }
} }

View File

@@ -167,7 +167,8 @@ QuicAsyncUDPSocket::RecvResult QuicAsyncUDPSocketImpl::recvmmsgNetworkData(
offset += params.gro; offset += params.gro;
remaining -= params.gro; remaining -= params.gro;
networkData.addPacket(ReceivedUdpPacket(std::move(tmp), timings)); networkData.addPacket(
ReceivedUdpPacket(std::move(tmp), timings, params.tos));
} else { } else {
// do not clone the last packet // do not clone the last packet
// start at offset, use all the remaining data // start at offset, use all the remaining data
@@ -175,11 +176,12 @@ QuicAsyncUDPSocket::RecvResult QuicAsyncUDPSocketImpl::recvmmsgNetworkData(
DCHECK_EQ(readBuffer->length(), remaining); DCHECK_EQ(readBuffer->length(), remaining);
remaining = 0; remaining = 0;
networkData.addPacket( networkData.addPacket(
ReceivedUdpPacket(std::move(readBuffer), timings)); ReceivedUdpPacket(std::move(readBuffer), timings, params.tos));
} }
} }
} else { } else {
networkData.addPacket(ReceivedUdpPacket(std::move(readBuffer), timings)); networkData.addPacket(
ReceivedUdpPacket(std::move(readBuffer), timings, params.tos));
} }
} }

View File

@@ -384,12 +384,22 @@ class QuicClientTransportTestBase : public virtual testing::Test {
virtual ~QuicClientTransportTestBase() = default; virtual ~QuicClientTransportTestBase() = default;
struct TestReadData { struct TestReadData {
std::unique_ptr<folly::IOBuf> data; ReceivedUdpPacket udpPacket;
folly::SocketAddress addr; folly::SocketAddress addr;
folly::Optional<int> err; folly::Optional<int> err;
TestReadData(folly::ByteRange dataIn, folly::SocketAddress addrIn) TestReadData(folly::ByteRange dataIn, folly::SocketAddress addrIn)
: data(folly::IOBuf::copyBuffer(dataIn)), addr(std::move(addrIn)) {} : udpPacket(folly::IOBuf::copyBuffer(dataIn)),
addr(std::move(addrIn)) {}
TestReadData(
const ReceivedUdpPacket&& udpPacketIn,
folly::SocketAddress addrIn)
: udpPacket(
udpPacketIn.buf.clone(),
udpPacketIn.timings,
udpPacketIn.tosValue),
addr(std::move(addrIn)) {}
explicit TestReadData(int errIn) : err(errIn) {} explicit TestReadData(int errIn) : err(errIn) {}
}; };
@@ -441,8 +451,8 @@ class QuicClientTransportTestBase : public virtual testing::Test {
errno = *socketReads[0].err; errno = *socketReads[0].err;
return -1; return -1;
} }
auto testData = std::move(socketReads[0].data); auto& udpPacket = socketReads[0].udpPacket;
testData->coalesce(); auto testData = std::move(udpPacket.buf.front());
size_t testDataLen = testData->length(); size_t testDataLen = testData->length();
memcpy( memcpy(
msg->msg_iov[0].iov_base, testData->data(), testData->length()); msg->msg_iov[0].iov_base, testData->data(), testData->length());
@@ -451,9 +461,18 @@ class QuicClientTransportTestBase : public virtual testing::Test {
static_cast<sockaddr_storage*>(msg->msg_name)); static_cast<sockaddr_storage*>(msg->msg_name));
msg->msg_namelen = msg_len; msg->msg_namelen = msg_len;
} }
#ifdef FOLLY_HAVE_MSG_ERRQUEUE
// Populate ToS control message as IPv6 TClass
auto cmsg = CMSG_FIRSTHDR(msg);
cmsg->cmsg_level = SOL_IPV6;
cmsg->cmsg_type = IPV6_TCLASS;
memcpy(
CMSG_DATA(cmsg), &udpPacket.tosValue, sizeof(udpPacket.tosValue));
#endif
socketReads.pop_front(); socketReads.pop_front();
return testDataLen; return testDataLen;
})); }));
ON_CALL(*sock, getRecvTos()).WillByDefault(testing::Return(true));
EXPECT_EQ(client->getConn().selfConnectionIds.size(), 1); EXPECT_EQ(client->getConn().selfConnectionIds.size(), 1);
EXPECT_EQ( EXPECT_EQ(
client->getConn().selfConnectionIds[0].connId, client->getConn().selfConnectionIds[0].connId,
@@ -769,15 +788,44 @@ class QuicClientTransportTestBase : public virtual testing::Test {
deliverData(peer == nullptr ? serverAddr : *peer, data, writes); deliverData(peer == nullptr ? serverAddr : *peer, data, writes);
} }
void deliverDataWithoutErrorCheck(
const folly::SocketAddress& addr,
const ReceivedUdpPacket&& udpPacket,
bool writes = true) {
ASSERT_TRUE(networkReadCallback);
socketReads.emplace_back(std::move(udpPacket), addr);
networkReadCallback->onNotifyDataAvailable(*sock);
if (writes) {
loopForWrites();
}
}
void deliverData(
const folly::SocketAddress& addr,
const ReceivedUdpPacket&& udpPacket,
bool writes = true) {
deliverDataWithoutErrorCheck(addr, std::move(udpPacket), writes);
if (client->getConn().localConnectionError) {
bool idleTimeout = false;
const LocalErrorCode* localError =
client->getConn().localConnectionError->code.asLocalErrorCode();
if (localError) {
idleTimeout = (*localError == LocalErrorCode::IDLE_TIMEOUT);
}
if (!idleTimeout) {
throw std::runtime_error(
toString(client->getConn().localConnectionError->code));
}
}
}
void deliverData( void deliverData(
NetworkData&& data, NetworkData&& data,
bool writes = true, bool writes = true,
folly::SocketAddress* peer = nullptr) { folly::SocketAddress* peer = nullptr) {
for (const auto& packet : data.getPackets()) { for (const auto& packet : data.getPackets()) {
deliverData( deliverData(
peer == nullptr ? serverAddr : *peer, peer == nullptr ? serverAddr : *peer, std::move(packet), writes);
packet.buf.clone()->coalesce(),
writes);
} }
} }

View File

@@ -315,6 +315,13 @@ SocketObserverInterface::PacketsReceivedEvent::ReceivedUdpPacket::Builder::
return std::move(*this); return std::move(*this);
} }
SocketObserverInterface::PacketsReceivedEvent::ReceivedUdpPacket::Builder&&
SocketObserverInterface::PacketsReceivedEvent::ReceivedUdpPacket::Builder::
setPacketTos(const uint8_t tosIn) {
maybePacketTos = tosIn;
return std::move(*this);
}
SocketObserverInterface::PacketsReceivedEvent::ReceivedUdpPacket SocketObserverInterface::PacketsReceivedEvent::ReceivedUdpPacket
SocketObserverInterface::PacketsReceivedEvent::ReceivedUdpPacket::Builder:: SocketObserverInterface::PacketsReceivedEvent::ReceivedUdpPacket::Builder::
build() && { build() && {
@@ -327,7 +334,8 @@ SocketObserverInterface::PacketsReceivedEvent::ReceivedUdpPacket::
: packetReceiveTime( : packetReceiveTime(
*CHECK_NOTNULL(builderFields.maybePacketReceiveTime.get_pointer())), *CHECK_NOTNULL(builderFields.maybePacketReceiveTime.get_pointer())),
packetNumBytes( packetNumBytes(
*CHECK_NOTNULL(builderFields.maybePacketNumBytes.get_pointer())) {} *CHECK_NOTNULL(builderFields.maybePacketNumBytes.get_pointer())),
packetTos(*CHECK_NOTNULL(builderFields.maybePacketTos.get_pointer())) {}
SocketObserverInterface::PacketsReceivedEvent::Builder&& SocketObserverInterface::PacketsReceivedEvent::Builder&&
SocketObserverInterface::PacketsReceivedEvent::Builder::setReceiveLoopTime( SocketObserverInterface::PacketsReceivedEvent::Builder::setReceiveLoopTime(

View File

@@ -232,15 +232,20 @@ class SocketObserverInterface {
// Number of bytes in the received packet. // Number of bytes in the received packet.
const uint64_t packetNumBytes; const uint64_t packetNumBytes;
// TOS value
const uint8_t packetTos;
struct BuilderFields { struct BuilderFields {
folly::Optional<TimePoint> maybePacketReceiveTime; folly::Optional<TimePoint> maybePacketReceiveTime;
folly::Optional<uint64_t> maybePacketNumBytes; folly::Optional<uint64_t> maybePacketNumBytes;
folly::Optional<uint8_t> maybePacketTos;
explicit BuilderFields() = default; explicit BuilderFields() = default;
}; };
struct Builder : public BuilderFields { struct Builder : public BuilderFields {
Builder&& setPacketReceiveTime(const TimePoint packetReceiveTimeIn); Builder&& setPacketReceiveTime(const TimePoint packetReceiveTimeIn);
Builder&& setPacketNumBytes(const uint64_t packetNumBytesIn); Builder&& setPacketNumBytes(const uint64_t packetNumBytesIn);
Builder&& setPacketTos(const uint8_t packettos);
ReceivedUdpPacket build() &&; ReceivedUdpPacket build() &&;
explicit Builder() = default; explicit Builder() = default;
}; };

View File

@@ -89,7 +89,9 @@ class UDPAcceptor : public folly::AsyncUDPSocket::ReadCallback {
transport_->accept(); transport_->accept();
} }
quic::NetworkData networkData(std::move(readBuffer_), packetReceiveTime); ReceivedUdpPacket packet(std::move(readBuffer_));
packet.timings.receiveTimePoint = packetReceiveTime;
quic::NetworkData networkData(std::move(packet));
transport_->onNetworkData(client, std::move(networkData)); transport_->onNetworkData(client, std::move(networkData));
} }

View File

@@ -346,6 +346,7 @@ void QuicServerWorker::onDataAvailable(
QUIC_STATS(statsCallback_, onRead, len); QUIC_STATS(statsCallback_, onRead, len);
ReceivedUdpPacket udpPacket(std::move(data)); ReceivedUdpPacket udpPacket(std::move(data));
udpPacket.timings.receiveTimePoint = packetReceiveTime; udpPacket.timings.receiveTimePoint = packetReceiveTime;
udpPacket.tosValue = params.tos;
handleNetworkData(client, udpPacket); handleNetworkData(client, udpPacket);
} else { } else {
// if we receive a truncated packet // if we receive a truncated packet
@@ -369,6 +370,7 @@ void QuicServerWorker::onDataAvailable(
DCHECK_EQ(data->length(), remaining); DCHECK_EQ(data->length(), remaining);
ReceivedUdpPacket udpPacket(std::move(data)); ReceivedUdpPacket udpPacket(std::move(data));
udpPacket.timings.receiveTimePoint = packetReceiveTime; udpPacket.timings.receiveTimePoint = packetReceiveTime;
udpPacket.tosValue = params.tos;
handleNetworkData(client, udpPacket); handleNetworkData(client, udpPacket);
break; break;
} }
@@ -383,6 +385,7 @@ void QuicServerWorker::onDataAvailable(
remaining -= params.gro; remaining -= params.gro;
ReceivedUdpPacket udpPacket(std::move(tmp)); ReceivedUdpPacket udpPacket(std::move(tmp));
udpPacket.timings.receiveTimePoint = packetReceiveTime; udpPacket.timings.receiveTimePoint = packetReceiveTime;
udpPacket.tosValue = params.tos;
handleNetworkData(client, udpPacket); handleNetworkData(client, udpPacket);
} }
} }

View File

@@ -707,7 +707,9 @@ static void handleCipherUnavailable(
ServerEvents::ReadData pendingReadData; ServerEvents::ReadData pendingReadData;
pendingReadData.peer = readData.peer; pendingReadData.peer = readData.peer;
pendingReadData.udpPacket = ReceivedUdpPacket( pendingReadData.udpPacket = ReceivedUdpPacket(
std::move(originalData->packet), readData.udpPacket.timings); std::move(originalData->packet),
readData.udpPacket.timings,
readData.udpPacket.tosValue);
pendingData->emplace_back(std::move(pendingReadData)); pendingData->emplace_back(std::move(pendingReadData));
VLOG(10) << "Adding pending data to " VLOG(10) << "Adding pending data to "
<< toString(originalData->protectionType) << toString(originalData->protectionType)

View File

@@ -288,7 +288,7 @@ void QuicServerWorkerTest::createQuicConnectionDuringShedding(
worker_->dispatchPacketData( worker_->dispatchPacketData(
addr, addr,
std::move(routingData), std::move(routingData),
NetworkData(data->clone(), Clock::now()), NetworkData(data->clone(), Clock::now(), 0),
version); version);
const auto& addrMap = worker_->getSrcToTransportMap(); const auto& addrMap = worker_->getSrcToTransportMap();
@@ -315,7 +315,7 @@ void QuicServerWorkerTest::createQuicConnection(
worker_->dispatchPacketData( worker_->dispatchPacketData(
addr, addr,
std::move(routingData), std::move(routingData),
NetworkData(data->clone(), Clock::now()), NetworkData(data->clone(), Clock::now(), 0),
version); version);
const auto& addrMap = worker_->getSrcToTransportMap(); const auto& addrMap = worker_->getSrcToTransportMap();
@@ -367,7 +367,7 @@ void QuicServerWorkerTest::testSendReset(
worker_->dispatchPacketData( worker_->dispatchPacketData(
kClientAddr, kClientAddr,
std::move(routingData), std::move(routingData),
NetworkData(packet->clone(), Clock::now()), NetworkData(packet->clone(), Clock::now(), 0),
folly::none); folly::none);
eventbase_.loopIgnoreKeepAlive(); eventbase_.loopIgnoreKeepAlive();
} }
@@ -422,7 +422,7 @@ TEST_F(QuicServerWorkerTest, SmallPacketTestNoReset) {
worker_->dispatchPacketData( worker_->dispatchPacketData(
kClientAddr, kClientAddr,
std::move(routingData), std::move(routingData),
NetworkData(data->clone(), Clock::now()), NetworkData(data->clone(), Clock::now(), 0),
folly::none); folly::none);
eventbase_.loopIgnoreKeepAlive(); eventbase_.loopIgnoreKeepAlive();
} }
@@ -457,7 +457,7 @@ TEST_F(QuicServerWorkerTest, RateLimit) {
worker_->dispatchPacketData( worker_->dispatchPacketData(
kClientAddr, kClientAddr,
std::move(routingData), std::move(routingData),
NetworkData(data->clone(), Clock::now()), NetworkData(data->clone(), Clock::now(), 0),
version); version);
const auto& addrMap = worker_->getSrcToTransportMap(); const auto& addrMap = worker_->getSrcToTransportMap();
@@ -489,7 +489,7 @@ TEST_F(QuicServerWorkerTest, RateLimit) {
worker_->dispatchPacketData( worker_->dispatchPacketData(
caddr2, caddr2,
std::move(routingData2), std::move(routingData2),
NetworkData(data2->clone(), Clock::now()), NetworkData(data2->clone(), Clock::now(), 0),
version); version);
EXPECT_EQ(addrMap.count(std::make_pair(caddr2, connId2)), 1); EXPECT_EQ(addrMap.count(std::make_pair(caddr2, connId2)), 1);
@@ -506,7 +506,7 @@ TEST_F(QuicServerWorkerTest, RateLimit) {
worker_->dispatchPacketData( worker_->dispatchPacketData(
caddr3, caddr3,
std::move(routingData3), std::move(routingData3),
NetworkData(data2->clone(), Clock::now()), NetworkData(data2->clone(), Clock::now(), 0),
version); version);
EXPECT_EQ(addrMap.count(std::make_pair(caddr3, connId3)), 0); EXPECT_EQ(addrMap.count(std::make_pair(caddr3, connId3)), 0);
@@ -543,7 +543,7 @@ TEST_F(QuicServerWorkerTest, UnfinishedHandshakeLimit) {
worker_->dispatchPacketData( worker_->dispatchPacketData(
kClientAddr, kClientAddr,
std::move(routingData), std::move(routingData),
NetworkData(data->clone(), Clock::now()), NetworkData(data->clone(), Clock::now(), 0),
version); version);
const auto& addrMap = worker_->getSrcToTransportMap(); const auto& addrMap = worker_->getSrcToTransportMap();
@@ -575,7 +575,7 @@ TEST_F(QuicServerWorkerTest, UnfinishedHandshakeLimit) {
worker_->dispatchPacketData( worker_->dispatchPacketData(
caddr2, caddr2,
std::move(routingData2), std::move(routingData2),
NetworkData(data2->clone(), Clock::now()), NetworkData(data2->clone(), Clock::now(), 0),
version); version);
EXPECT_EQ(addrMap.count(std::make_pair(caddr2, connId2)), 1); EXPECT_EQ(addrMap.count(std::make_pair(caddr2, connId2)), 1);
@@ -592,7 +592,7 @@ TEST_F(QuicServerWorkerTest, UnfinishedHandshakeLimit) {
worker_->dispatchPacketData( worker_->dispatchPacketData(
caddr3, caddr3,
std::move(routingData3), std::move(routingData3),
NetworkData(data3->clone(), Clock::now()), NetworkData(data3->clone(), Clock::now(), 0),
version); version);
EXPECT_EQ(addrMap.count(std::make_pair(caddr3, connId3)), 0); EXPECT_EQ(addrMap.count(std::make_pair(caddr3, connId3)), 0);
@@ -626,7 +626,7 @@ TEST_F(QuicServerWorkerTest, UnfinishedHandshakeLimit) {
worker_->dispatchPacketData( worker_->dispatchPacketData(
caddr4, caddr4,
std::move(routingData4), std::move(routingData4),
NetworkData(data4->clone(), Clock::now()), NetworkData(data4->clone(), Clock::now(), 0),
version); version);
EXPECT_EQ(addrMap.count(std::make_pair(caddr4, connId4)), 1); EXPECT_EQ(addrMap.count(std::make_pair(caddr4, connId4)), 1);
@@ -709,7 +709,7 @@ TEST_F(QuicServerWorkerTest, QuicServerMultipleConnIdsRouting) {
worker_->dispatchPacketData( worker_->dispatchPacketData(
kClientAddr, kClientAddr,
std::move(routingData2), std::move(routingData2),
NetworkData(data->clone(), Clock::now()), NetworkData(data->clone(), Clock::now(), 0),
folly::none); folly::none);
eventbase_.loopIgnoreKeepAlive(); eventbase_.loopIgnoreKeepAlive();
@@ -727,7 +727,7 @@ TEST_F(QuicServerWorkerTest, QuicServerMultipleConnIdsRouting) {
worker_->dispatchPacketData( worker_->dispatchPacketData(
kClientAddr, kClientAddr,
std::move(routingData3), std::move(routingData3),
NetworkData(data->clone(), Clock::now()), NetworkData(data->clone(), Clock::now(), 0),
folly::none); folly::none);
eventbase_.loopIgnoreKeepAlive(); eventbase_.loopIgnoreKeepAlive();
@@ -827,7 +827,7 @@ TEST_F(QuicServerWorkerTest, QuicServerNewConnection) {
worker_->dispatchPacketData( worker_->dispatchPacketData(
kClientAddr, kClientAddr,
std::move(routingData), std::move(routingData),
NetworkData(data->clone(), Clock::now()), NetworkData(data->clone(), Clock::now(), 0),
folly::none); folly::none);
eventbase_.loopIgnoreKeepAlive(); eventbase_.loopIgnoreKeepAlive();
@@ -861,7 +861,7 @@ TEST_F(QuicServerWorkerTest, QuicServerNewConnection) {
worker_->dispatchPacketData( worker_->dispatchPacketData(
kClientAddr, kClientAddr,
std::move(routingData2), std::move(routingData2),
NetworkData(data->clone(), Clock::now()), NetworkData(data->clone(), Clock::now(), 0),
folly::none); folly::none);
eventbase_.loopIgnoreKeepAlive(); eventbase_.loopIgnoreKeepAlive();
@@ -898,7 +898,7 @@ TEST_F(QuicServerWorkerTest, QuicServerNewConnection) {
worker_->dispatchPacketData( worker_->dispatchPacketData(
clientAddr2, clientAddr2,
std::move(routingData3), std::move(routingData3),
NetworkData(data->clone(), Clock::now()), NetworkData(data->clone(), Clock::now(), 0),
folly::none); folly::none);
eventbase_.loopIgnoreKeepAlive(); eventbase_.loopIgnoreKeepAlive();
@@ -944,7 +944,7 @@ TEST_F(QuicServerWorkerTest, InitialPacketTooSmall) {
worker_->dispatchPacketData( worker_->dispatchPacketData(
kClientAddr, kClientAddr,
std::move(routingData), std::move(routingData),
NetworkData(data->clone(), Clock::now()), NetworkData(data->clone(), Clock::now(), 0),
version); version);
eventbase_.loopIgnoreKeepAlive(); eventbase_.loopIgnoreKeepAlive();
} }
@@ -1099,7 +1099,7 @@ TEST_F(QuicServerWorkerTest, FailToParseConnectionId) {
// To force dropping path, set initial to false // To force dropping path, set initial to false
RoutingData routingData( RoutingData routingData(
HeaderForm::Long, false /* isInitial */, false, dstConnId, srcConnId); HeaderForm::Long, false /* isInitial */, false, dstConnId, srcConnId);
NetworkData networkData(std::move(packet), Clock::now()); NetworkData networkData(std::move(packet), Clock::now(), 0);
EXPECT_CALL(*rawConnIdAlgo, canParseNonConst(_)).WillOnce(Return(true)); EXPECT_CALL(*rawConnIdAlgo, canParseNonConst(_)).WillOnce(Return(true));
EXPECT_CALL(*rawConnIdAlgo, parseConnectionId(dstConnId)) EXPECT_CALL(*rawConnIdAlgo, parseConnectionId(dstConnId))
@@ -1136,7 +1136,7 @@ TEST_F(QuicServerWorkerTest, ConnectionIdTooShortDispatch) {
} }
auto packet = packetToBuf(std::move(builder).buildPacket()); auto packet = packetToBuf(std::move(builder).buildPacket());
RoutingData routingData(HeaderForm::Long, true, false, dstConnId, srcConnId); RoutingData routingData(HeaderForm::Long, true, false, dstConnId, srcConnId);
NetworkData networkData(std::move(packet), Clock::now()); NetworkData networkData(std::move(packet), Clock::now(), 0);
worker_->dispatchPacketData( worker_->dispatchPacketData(
kClientAddr, std::move(routingData), std::move(networkData), version); kClientAddr, std::move(routingData), std::move(networkData), version);
eventbase_.loopIgnoreKeepAlive(); eventbase_.loopIgnoreKeepAlive();
@@ -1164,7 +1164,7 @@ TEST_F(QuicServerWorkerTest, ConnectionIdTooLargeDispatch) {
} }
auto packet = packetToBuf(std::move(builder).buildPacket()); auto packet = packetToBuf(std::move(builder).buildPacket());
RoutingData routingData(HeaderForm::Long, true, false, dstConnId, srcConnId); RoutingData routingData(HeaderForm::Long, true, false, dstConnId, srcConnId);
NetworkData networkData(std::move(packet), Clock::now()); NetworkData networkData(std::move(packet), Clock::now(), 0);
worker_->dispatchPacketData( worker_->dispatchPacketData(
kClientAddr, std::move(routingData), std::move(networkData), version); kClientAddr, std::move(routingData), std::move(networkData), version);
eventbase_.loopIgnoreKeepAlive(); eventbase_.loopIgnoreKeepAlive();
@@ -1510,7 +1510,7 @@ class QuicServerWorkerRetryTest : public QuicServerWorkerTest {
worker_->dispatchPacketData( worker_->dispatchPacketData(
clientAddr, clientAddr,
std::move(routingData), std::move(routingData),
NetworkData(initialPacket->clone(), Clock::now()), NetworkData(initialPacket->clone(), Clock::now(), 0),
version); version);
eventbase_.loopIgnoreKeepAlive(); eventbase_.loopIgnoreKeepAlive();
} }
@@ -2283,7 +2283,7 @@ TEST_F(QuicServerTest, DontRouteDataAfterShutdown) {
EXPECT_CALL( EXPECT_CALL(
*stats, *stats,
onPacketDropped(PacketDropReason(PacketDropReason::SERVER_SHUTDOWN))); onPacketDropped(PacketDropReason(PacketDropReason::SERVER_SHUTDOWN)));
NetworkData networkData(folly::IOBuf::copyBuffer("wat"), Clock::now()); NetworkData networkData(folly::IOBuf::copyBuffer("wat"), Clock::now(), 0);
RoutingData routingData( RoutingData routingData(
HeaderForm::Long, HeaderForm::Long,
true, true,
@@ -2336,7 +2336,7 @@ TEST_F(QuicServerTest, RouteDataFromDifferentThread) {
folly::IOBuf::create(kMinInitialPacketSize)); folly::IOBuf::create(kMinInitialPacketSize));
initialData->append(kMinInitialPacketSize); initialData->append(kMinInitialPacketSize);
memset(initialData->writableData(), 'd', kMinInitialPacketSize); memset(initialData->writableData(), 'd', kMinInitialPacketSize);
NetworkData networkData(initialData->clone(), Clock::now()); NetworkData networkData(initialData->clone(), Clock::now(), 0);
RoutingData routingData( RoutingData routingData(
HeaderForm::Long, HeaderForm::Long,
true, true,

View File

@@ -490,7 +490,7 @@ class QuicServerTransportTestBase : public virtual testing::Test {
folly::SocketAddress* peer = nullptr) { folly::SocketAddress* peer = nullptr) {
data->coalesce(); data->coalesce();
deliverDataWithoutErrorCheck( deliverDataWithoutErrorCheck(
NetworkData(std::move(data), Clock::now()), writes, peer); NetworkData(ReceivedUdpPacket(std::move(data))), writes, peer);
} }
void deliverData( void deliverData(
@@ -517,7 +517,7 @@ class QuicServerTransportTestBase : public virtual testing::Test {
bool writes = true, bool writes = true,
folly::SocketAddress* peer = nullptr) { folly::SocketAddress* peer = nullptr) {
data->coalesce(); data->coalesce();
deliverData(NetworkData(std::move(data), Clock::now()), writes, peer); deliverData(NetworkData(ReceivedUdpPacket(std::move(data))), writes, peer);
} }
void loopForWrites() { void loopForWrites() {