Add QoS dimension to packet processor result metrics.
PiperOrigin-RevId: 617205961
diff --git a/quiche/quic/qbone/qbone_packet_processor.cc b/quiche/quic/qbone/qbone_packet_processor.cc
index 75cf6d1..7fdfd0f 100644
--- a/quiche/quic/qbone/qbone_packet_processor.cc
+++ b/quiche/quic/qbone/qbone_packet_processor.cc
@@ -8,6 +8,7 @@
#include <netinet/in.h>
#include <netinet/ip6.h>
+#include <cstdint>
#include <cstring>
#include "absl/base/optimization.h"
@@ -68,10 +69,11 @@
void QbonePacketProcessor::ProcessPacket(std::string* packet,
Direction direction) {
+ uint8_t traffic_class = TrafficClassFromHeader(*packet);
if (ABSL_PREDICT_FALSE(!IsValid())) {
QUIC_BUG(quic_bug_11024_1)
<< "QuicPacketProcessor is invoked in an invalid state.";
- stats_->OnPacketDroppedSilently(direction);
+ stats_->OnPacketDroppedSilently(direction, traffic_class);
return;
}
@@ -96,13 +98,13 @@
output_->SendPacketToClient(*packet);
break;
}
- stats_->OnPacketForwarded(direction);
+ stats_->OnPacketForwarded(direction, traffic_class);
break;
case ProcessingResult::SILENT_DROP:
- stats_->OnPacketDroppedSilently(direction);
+ stats_->OnPacketDroppedSilently(direction, traffic_class);
break;
case ProcessingResult::DEFER:
- stats_->OnPacketDeferred(direction);
+ stats_->OnPacketDeferred(direction, traffic_class);
break;
case ProcessingResult::ICMP:
if (icmp_header.icmp6_type == ICMP6_ECHO_REPLY) {
@@ -115,17 +117,17 @@
} else {
SendIcmpResponse(dst, &icmp_header, *packet, direction);
}
- stats_->OnPacketDroppedWithIcmp(direction);
+ stats_->OnPacketDroppedWithIcmp(direction, traffic_class);
break;
case ProcessingResult::ICMP_AND_TCP_RESET:
SendIcmpResponse(dst, &icmp_header, *packet, direction);
- stats_->OnPacketDroppedWithIcmp(direction);
+ stats_->OnPacketDroppedWithIcmp(direction, traffic_class);
SendTcpReset(*packet, direction);
- stats_->OnPacketDroppedWithTcpReset(direction);
+ stats_->OnPacketDroppedWithTcpReset(direction, traffic_class);
break;
case ProcessingResult::TCP_RESET:
SendTcpReset(*packet, direction);
- stats_->OnPacketDroppedWithTcpReset(direction);
+ stats_->OnPacketDroppedWithTcpReset(direction, traffic_class);
break;
}
}
@@ -288,4 +290,15 @@
}
}
+uint8_t QbonePacketProcessor::TrafficClassFromHeader(
+ absl::string_view ipv6_header) {
+ // Packets that reach this function should have already been validated.
+ // However, there are tests that bypass that validation that fail because this
+ // would be out of bounds.
+ if (ipv6_header.length() < 2) {
+ return 0; // Default to BE1
+ }
+
+ return ipv6_header[0] << 4 | ipv6_header[1] >> 4;
+}
} // namespace quic
diff --git a/quiche/quic/qbone/qbone_packet_processor.h b/quiche/quic/qbone/qbone_packet_processor.h
index fed7a8b..b337b19 100644
--- a/quiche/quic/qbone/qbone_packet_processor.h
+++ b/quiche/quic/qbone/qbone_packet_processor.h
@@ -9,6 +9,8 @@
#include <netinet/in.h>
#include <netinet/ip6.h>
+#include <cstdint>
+
#include "absl/strings/string_view.h"
#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/platform/api/quic_ip_address.h"
@@ -63,11 +65,16 @@
public:
virtual ~StatsInterface();
- virtual void OnPacketForwarded(Direction direction) = 0;
- virtual void OnPacketDroppedSilently(Direction direction) = 0;
- virtual void OnPacketDroppedWithIcmp(Direction direction) = 0;
- virtual void OnPacketDroppedWithTcpReset(Direction direction) = 0;
- virtual void OnPacketDeferred(Direction direction) = 0;
+ virtual void OnPacketForwarded(Direction direction,
+ uint8_t traffic_class) = 0;
+ virtual void OnPacketDroppedSilently(Direction direction,
+ uint8_t traffic_class) = 0;
+ virtual void OnPacketDroppedWithIcmp(Direction direction,
+ uint8_t traffic_class) = 0;
+ virtual void OnPacketDroppedWithTcpReset(Direction direction,
+ uint8_t traffic_class) = 0;
+ virtual void OnPacketDeferred(Direction direction,
+ uint8_t traffic_class) = 0;
};
// Allows to implement a custom packet filter on top of the filtering done by
@@ -110,9 +117,6 @@
uint8_t TransportProtocolFromHeader(absl::string_view ipv6_header) {
return ipv6_header[6];
}
- uint8_t TrafficClassFromHeader(absl::string_view ipv6_header) {
- return ipv6_header[0] << 4 | ipv6_header[1] >> 4;
- }
QuicIpAddress SourceIpFromHeader(absl::string_view ipv6_header) {
QuicIpAddress address;
@@ -158,6 +162,9 @@
static const QuicIpAddress kInvalidIpAddress;
+ // This function assumes that the packet is valid.
+ static uint8_t TrafficClassFromHeader(absl::string_view ipv6_header);
+
protected:
// Processes the header and returns what should be done with the packet.
// After that, calls an external packet filter if registered. TTL of the
diff --git a/quiche/quic/qbone/qbone_packet_processor_test.cc b/quiche/quic/qbone/qbone_packet_processor_test.cc
index 85cf0ca..f3361b7 100644
--- a/quiche/quic/qbone/qbone_packet_processor_test.cc
+++ b/quiche/quic/qbone/qbone_packet_processor_test.cc
@@ -355,18 +355,18 @@
};
TEST_F(QbonePacketProcessorTest, EmptyPacket) {
- EXPECT_CALL(stats_, OnPacketDroppedSilently(Direction::FROM_OFF_NETWORK));
+ EXPECT_CALL(stats_, OnPacketDroppedSilently(Direction::FROM_OFF_NETWORK, _));
SendPacketFromClient("");
- EXPECT_CALL(stats_, OnPacketDroppedSilently(Direction::FROM_NETWORK));
+ EXPECT_CALL(stats_, OnPacketDroppedSilently(Direction::FROM_NETWORK, _));
SendPacketFromNetwork("");
}
TEST_F(QbonePacketProcessorTest, RandomGarbage) {
- EXPECT_CALL(stats_, OnPacketDroppedSilently(Direction::FROM_OFF_NETWORK));
+ EXPECT_CALL(stats_, OnPacketDroppedSilently(Direction::FROM_OFF_NETWORK, _));
SendPacketFromClient(std::string(1280, 'a'));
- EXPECT_CALL(stats_, OnPacketDroppedSilently(Direction::FROM_NETWORK));
+ EXPECT_CALL(stats_, OnPacketDroppedSilently(Direction::FROM_NETWORK, _));
SendPacketFromNetwork(std::string(1280, 'a'));
}
@@ -375,31 +375,31 @@
packet[4] = 0;
packet[5] = 0;
- EXPECT_CALL(stats_, OnPacketDroppedWithIcmp(Direction::FROM_OFF_NETWORK));
+ EXPECT_CALL(stats_, OnPacketDroppedWithIcmp(Direction::FROM_OFF_NETWORK, _));
EXPECT_CALL(output_, SendPacketToClient(IsIcmpMessage(ICMP6_DST_UNREACH)));
SendPacketFromClient(packet);
}
TEST_F(QbonePacketProcessorTest, GoodPacketFromClient) {
- EXPECT_CALL(stats_, OnPacketForwarded(Direction::FROM_OFF_NETWORK));
+ EXPECT_CALL(stats_, OnPacketForwarded(Direction::FROM_OFF_NETWORK, _));
EXPECT_CALL(output_, SendPacketToNetwork(_));
SendPacketFromClient(kReferenceClientPacket);
}
TEST_F(QbonePacketProcessorTest, GoodPacketFromClientSubnet) {
- EXPECT_CALL(stats_, OnPacketForwarded(Direction::FROM_OFF_NETWORK));
+ EXPECT_CALL(stats_, OnPacketForwarded(Direction::FROM_OFF_NETWORK, _));
EXPECT_CALL(output_, SendPacketToNetwork(_));
SendPacketFromClient(kReferenceClientSubnetPacket);
}
TEST_F(QbonePacketProcessorTest, GoodPacketFromNetwork) {
- EXPECT_CALL(stats_, OnPacketForwarded(Direction::FROM_NETWORK));
+ EXPECT_CALL(stats_, OnPacketForwarded(Direction::FROM_NETWORK, _));
EXPECT_CALL(output_, SendPacketToClient(_));
SendPacketFromNetwork(kReferenceNetworkPacket);
}
TEST_F(QbonePacketProcessorTest, GoodPacketFromNetworkWrongDirection) {
- EXPECT_CALL(stats_, OnPacketDroppedWithIcmp(Direction::FROM_OFF_NETWORK));
+ EXPECT_CALL(stats_, OnPacketDroppedWithIcmp(Direction::FROM_OFF_NETWORK, _));
EXPECT_CALL(output_, SendPacketToClient(IsIcmpMessage(ICMP6_DST_UNREACH)));
SendPacketFromClient(kReferenceNetworkPacket);
}
@@ -408,7 +408,7 @@
std::string packet(kReferenceNetworkPacket);
packet[7] = 1;
- EXPECT_CALL(stats_, OnPacketDroppedWithIcmp(Direction::FROM_NETWORK));
+ EXPECT_CALL(stats_, OnPacketDroppedWithIcmp(Direction::FROM_NETWORK, _));
EXPECT_CALL(output_, SendPacketToNetwork(IsIcmpMessage(ICMP6_TIME_EXCEEDED)));
SendPacketFromNetwork(packet);
}
@@ -417,7 +417,7 @@
std::string packet(kReferenceNetworkPacket);
packet[6] = IPPROTO_SCTP;
- EXPECT_CALL(stats_, OnPacketDroppedWithIcmp(Direction::FROM_NETWORK));
+ EXPECT_CALL(stats_, OnPacketDroppedWithIcmp(Direction::FROM_NETWORK, _));
EXPECT_CALL(output_, SendPacketToNetwork(IsIcmpMessage(ICMP6_PARAM_PROB)));
SendPacketFromNetwork(packet);
}
@@ -428,7 +428,7 @@
.WillRepeatedly(Return(ProcessingResult::SILENT_DROP));
processor_->set_filter(std::move(filter));
- EXPECT_CALL(stats_, OnPacketDroppedSilently(Direction::FROM_OFF_NETWORK));
+ EXPECT_CALL(stats_, OnPacketDroppedSilently(Direction::FROM_OFF_NETWORK, _));
SendPacketFromClient(kReferenceClientPacket);
}
@@ -446,7 +446,7 @@
EXPECT_EQ(client_ip_, SourceIpFromHeader(full_packet));
EXPECT_EQ(network_ip_, DestinationIpFromHeader(full_packet));
- last_tos_ = TrafficClassFromHeader(full_packet);
+ last_tos_ = QbonePacketProcessor::TrafficClassFromHeader(full_packet);
called_++;
return ProcessingResult::SILENT_DROP;
}
@@ -469,7 +469,7 @@
TestFilter* filter = filter_owned.get();
processor_->set_filter(std::move(filter_owned));
- EXPECT_CALL(stats_, OnPacketDroppedSilently(Direction::FROM_OFF_NETWORK));
+ EXPECT_CALL(stats_, OnPacketDroppedSilently(Direction::FROM_OFF_NETWORK, _));
SendPacketFromClient(kReferenceClientPacket);
ASSERT_EQ(1, filter->called());
}
@@ -479,7 +479,7 @@
TestFilter* filter = filter_owned.get();
processor_->set_filter(std::move(filter_owned));
- EXPECT_CALL(stats_, OnPacketDroppedSilently(Direction::FROM_OFF_NETWORK))
+ EXPECT_CALL(stats_, OnPacketDroppedSilently(Direction::FROM_OFF_NETWORK, _))
.Times(testing::AnyNumber());
SendPacketFromClient(kReferenceClientPacket);
ASSERT_EQ(0, filter->last_tos());
@@ -508,7 +508,7 @@
})));
processor_->set_filter(std::move(filter));
- EXPECT_CALL(stats_, OnPacketDroppedWithIcmp(Direction::FROM_OFF_NETWORK));
+ EXPECT_CALL(stats_, OnPacketDroppedWithIcmp(Direction::FROM_OFF_NETWORK, _));
EXPECT_CALL(output_, SendPacketToClient(_))
.WillOnce(Invoke([](absl::string_view packet) {
// Explicit conversion because otherwise it is treated as a null
diff --git a/quiche/quic/qbone/qbone_packet_processor_test_tools.h b/quiche/quic/qbone/qbone_packet_processor_test_tools.h
index 3d3492d..9b0ff85 100644
--- a/quiche/quic/qbone/qbone_packet_processor_test_tools.h
+++ b/quiche/quic/qbone/qbone_packet_processor_test_tools.h
@@ -5,6 +5,8 @@
#ifndef QUICHE_QUIC_QBONE_QBONE_PACKET_PROCESSOR_TEST_TOOLS_H_
#define QUICHE_QUIC_QBONE_QBONE_PACKET_PROCESSOR_TEST_TOOLS_H_
+#include <cstdint>
+
#include "absl/strings/string_view.h"
#include "quiche/quic/platform/api/quic_test.h"
#include "quiche/quic/qbone/qbone_packet_processor.h"
@@ -23,16 +25,16 @@
public:
MockPacketProcessorStats() {}
- MOCK_METHOD(void, OnPacketForwarded, (QbonePacketProcessor::Direction),
- (override));
- MOCK_METHOD(void, OnPacketDroppedSilently, (QbonePacketProcessor::Direction),
- (override));
- MOCK_METHOD(void, OnPacketDroppedWithIcmp, (QbonePacketProcessor::Direction),
- (override));
+ MOCK_METHOD(void, OnPacketForwarded,
+ (QbonePacketProcessor::Direction, uint8_t), (override));
+ MOCK_METHOD(void, OnPacketDroppedSilently,
+ (QbonePacketProcessor::Direction, uint8_t), (override));
+ MOCK_METHOD(void, OnPacketDroppedWithIcmp,
+ (QbonePacketProcessor::Direction, uint8_t), (override));
MOCK_METHOD(void, OnPacketDroppedWithTcpReset,
- (QbonePacketProcessor::Direction), (override));
- MOCK_METHOD(void, OnPacketDeferred, (QbonePacketProcessor::Direction),
- (override));
+ (QbonePacketProcessor::Direction, uint8_t), (override));
+ MOCK_METHOD(void, OnPacketDeferred,
+ (QbonePacketProcessor::Direction, uint8_t), (override));
};
std::string PrependIPv6HeaderForTest(const std::string& body, int hops);
diff --git a/quiche/quic/qbone/qbone_server_session.h b/quiche/quic/qbone/qbone_server_session.h
index c313816..0f325a6 100644
--- a/quiche/quic/qbone/qbone_server_session.h
+++ b/quiche/quic/qbone/qbone_server_session.h
@@ -5,6 +5,8 @@
#ifndef QUICHE_QUIC_QBONE_QBONE_SERVER_SESSION_H_
#define QUICHE_QUIC_QBONE_QBONE_SERVER_SESSION_H_
+#include <cstdint>
+
#include "absl/strings/string_view.h"
#include "quiche/quic/core/quic_crypto_server_stream_base.h"
#include "quiche/quic/core/quic_crypto_stream.h"
@@ -59,14 +61,16 @@
void SendPacketToNetwork(absl::string_view packet) override;
// QbonePacketProcessor::StatsInterface implementation.
- void OnPacketForwarded(QbonePacketProcessor::Direction direction) override {}
- void OnPacketDroppedSilently(
- QbonePacketProcessor::Direction direction) override {}
- void OnPacketDroppedWithIcmp(
- QbonePacketProcessor::Direction direction) override {}
- void OnPacketDroppedWithTcpReset(
- QbonePacketProcessor::Direction direction) override {}
- void OnPacketDeferred(QbonePacketProcessor::Direction direction) override {}
+ void OnPacketForwarded(QbonePacketProcessor::Direction direction,
+ uint8_t traffic_class) override {}
+ void OnPacketDroppedSilently(QbonePacketProcessor::Direction direction,
+ uint8_t traffic_class) override {}
+ void OnPacketDroppedWithIcmp(QbonePacketProcessor::Direction direction,
+ uint8_t traffic_class) override {}
+ void OnPacketDroppedWithTcpReset(QbonePacketProcessor::Direction direction,
+ uint8_t traffic_class) override {}
+ void OnPacketDeferred(QbonePacketProcessor::Direction direction,
+ uint8_t traffic_class) override {}
protected:
// QboneSessionBase interface implementation.