Implement missing candidate pair packets/bytes sent/received stats.
Specifically:
* packetsSent
* packetsReceived
* packetsDiscardedOnSend
* bytesDiscardedOnSend
Bug: webrtc:10569
Change-Id: Id92c20b93dea57637239a6321bd8aa644867f272
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/232961
Commit-Queue: Taylor Brandstetter <deadbeef@webrtc.org>
Reviewed-by: Jonas Oreland <jonaso@webrtc.org>
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#35113}
diff --git a/api/stats/rtcstats_objects.h b/api/stats/rtcstats_objects.h
index 849ef80..7742538 100644
--- a/api/stats/rtcstats_objects.h
+++ b/api/stats/rtcstats_objects.h
@@ -170,6 +170,8 @@
RTCStatsMember<bool> writable;
// TODO(hbos): Collect and populate this value. https://bugs.webrtc.org/7062
RTCStatsMember<bool> readable;
+ RTCStatsMember<uint64_t> packets_sent;
+ RTCStatsMember<uint64_t> packets_received;
RTCStatsMember<uint64_t> bytes_sent;
RTCStatsMember<uint64_t> bytes_received;
RTCStatsMember<double> total_round_trip_time;
@@ -194,6 +196,8 @@
RTCStatsMember<uint64_t> consent_responses_received;
// TODO(hbos): Collect and populate this value. https://bugs.webrtc.org/7062
RTCStatsMember<uint64_t> consent_responses_sent;
+ RTCStatsMember<uint64_t> packets_discarded_on_send;
+ RTCStatsMember<uint64_t> bytes_discarded_on_send;
};
// https://w3c.github.io/webrtc-stats/#icecandidate-dict*
diff --git a/p2p/base/connection.cc b/p2p/base/connection.cc
index ebfe6fd..f7bd47d 100644
--- a/p2p/base/connection.cc
+++ b/p2p/base/connection.cc
@@ -1374,6 +1374,7 @@
RTC_DCHECK(sent < 0);
error_ = port_->GetError();
stats_.sent_discarded_packets++;
+ stats_.sent_discarded_bytes += size;
} else {
send_rate_tracker_.AddSamplesAtTime(now, sent);
}
diff --git a/p2p/base/connection_info.cc b/p2p/base/connection_info.cc
index ebea2ab..d0cd323 100644
--- a/p2p/base/connection_info.cc
+++ b/p2p/base/connection_info.cc
@@ -19,6 +19,7 @@
timeout(false),
new_connection(false),
rtt(0),
+ sent_discarded_bytes(0),
sent_total_bytes(0),
sent_bytes_second(0),
sent_discarded_packets(0),
diff --git a/p2p/base/connection_info.h b/p2p/base/connection_info.h
index b5e1c14..1117595 100644
--- a/p2p/base/connection_info.h
+++ b/p2p/base/connection_info.h
@@ -41,12 +41,15 @@
bool timeout; // Has this connection timed out?
bool new_connection; // Is this a newly created connection?
size_t rtt; // The STUN RTT for this connection.
- size_t sent_total_bytes; // Total bytes sent on this connection.
+ size_t sent_discarded_bytes; // Number of outgoing bytes discarded due to
+ // socket errors.
+ size_t sent_total_bytes; // Total bytes sent on this connection. Does not
+ // include discarded bytes.
size_t sent_bytes_second; // Bps over the last measurement interval.
size_t sent_discarded_packets; // Number of outgoing packets discarded due to
// socket errors.
size_t sent_total_packets; // Number of total outgoing packets attempted for
- // sending.
+ // sending, including discarded packets.
size_t sent_ping_requests_total; // Number of STUN ping request sent.
size_t sent_ping_requests_before_first_response; // Number of STUN ping
// sent before receiving the first response.
diff --git a/p2p/base/p2p_transport_channel_unittest.cc b/p2p/base/p2p_transport_channel_unittest.cc
index 0ddeb2d..dfc3cec 100644
--- a/p2p/base/p2p_transport_channel_unittest.cc
+++ b/p2p/base/p2p_transport_channel_unittest.cc
@@ -1338,6 +1338,13 @@
kMediumTimeout, clock);
// Sends and receives 10 packets.
TestSendRecv(&clock);
+
+ // Try sending a packet which is discarded due to the socket being blocked.
+ virtual_socket_server()->SetSendingBlocked(true);
+ const char* data = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
+ int len = static_cast<int>(strlen(data));
+ EXPECT_EQ(-1, SendData(ep1_ch1(), data, len));
+
IceTransportStats ice_transport_stats;
ASSERT_TRUE(ep1_ch1()->GetStats(&ice_transport_stats));
ASSERT_GE(ice_transport_stats.connection_infos.size(), 1u);
@@ -1355,9 +1362,12 @@
EXPECT_TRUE(best_conn_info->receiving);
EXPECT_TRUE(best_conn_info->writable);
EXPECT_FALSE(best_conn_info->timeout);
- EXPECT_EQ(10U, best_conn_info->sent_total_packets);
- EXPECT_EQ(0U, best_conn_info->sent_discarded_packets);
+ // Note that discarded packets are counted in sent_total_packets but not
+ // sent_total_bytes.
+ EXPECT_EQ(11U, best_conn_info->sent_total_packets);
+ EXPECT_EQ(1U, best_conn_info->sent_discarded_packets);
EXPECT_EQ(10 * 36U, best_conn_info->sent_total_bytes);
+ EXPECT_EQ(36U, best_conn_info->sent_discarded_bytes);
EXPECT_EQ(10 * 36U, best_conn_info->recv_total_bytes);
EXPECT_EQ(10U, best_conn_info->packets_received);
DestroyChannels();
diff --git a/pc/rtc_stats_collector.cc b/pc/rtc_stats_collector.cc
index 1f8b28d..7637c07 100644
--- a/pc/rtc_stats_collector.cc
+++ b/pc/rtc_stats_collector.cc
@@ -1552,8 +1552,18 @@
// false after a certain amount of time without a response passes.
// https://crbug.com/633550
candidate_pair_stats->writable = info.writable;
+ // Note that sent_total_packets includes discarded packets but
+ // sent_total_bytes does not.
+ candidate_pair_stats->packets_sent = static_cast<uint64_t>(
+ info.sent_total_packets - info.sent_discarded_packets);
+ candidate_pair_stats->packets_discarded_on_send =
+ static_cast<uint64_t>(info.sent_discarded_packets);
+ candidate_pair_stats->packets_received =
+ static_cast<uint64_t>(info.packets_received);
candidate_pair_stats->bytes_sent =
static_cast<uint64_t>(info.sent_total_bytes);
+ candidate_pair_stats->bytes_discarded_on_send =
+ static_cast<uint64_t>(info.sent_discarded_bytes);
candidate_pair_stats->bytes_received =
static_cast<uint64_t>(info.recv_total_bytes);
candidate_pair_stats->total_round_trip_time =
diff --git a/pc/rtc_stats_collector_unittest.cc b/pc/rtc_stats_collector_unittest.cc
index 8c4f0a6..5f94d81 100644
--- a/pc/rtc_stats_collector_unittest.cc
+++ b/pc/rtc_stats_collector_unittest.cc
@@ -1421,6 +1421,10 @@
connection_info.local_candidate = *local_candidate.get();
connection_info.remote_candidate = *remote_candidate.get();
connection_info.writable = true;
+ connection_info.sent_discarded_packets = 3;
+ connection_info.sent_total_packets = 10;
+ connection_info.packets_received = 51;
+ connection_info.sent_discarded_bytes = 7;
connection_info.sent_total_bytes = 42;
connection_info.recv_total_bytes = 1234;
connection_info.total_round_trip_time_ms = 0;
@@ -1458,8 +1462,12 @@
expected_pair.priority = 5555;
expected_pair.nominated = false;
expected_pair.writable = true;
+ expected_pair.packets_sent = 7;
+ expected_pair.packets_received = 51;
+ expected_pair.packets_discarded_on_send = 3;
expected_pair.bytes_sent = 42;
expected_pair.bytes_received = 1234;
+ expected_pair.bytes_discarded_on_send = 7;
expected_pair.total_round_trip_time = 0.0;
expected_pair.requests_received = 2020;
expected_pair.requests_sent = 2000;
diff --git a/pc/rtc_stats_integrationtest.cc b/pc/rtc_stats_integrationtest.cc
index afa50d8..81ead00 100644
--- a/pc/rtc_stats_integrationtest.cc
+++ b/pc/rtc_stats_integrationtest.cc
@@ -489,7 +489,13 @@
verifier.TestMemberIsDefined(candidate_pair.nominated);
verifier.TestMemberIsDefined(candidate_pair.writable);
verifier.TestMemberIsUndefined(candidate_pair.readable);
+ verifier.TestMemberIsNonNegative<uint64_t>(candidate_pair.packets_sent);
+ verifier.TestMemberIsNonNegative<uint64_t>(
+ candidate_pair.packets_discarded_on_send);
+ verifier.TestMemberIsNonNegative<uint64_t>(candidate_pair.packets_received);
verifier.TestMemberIsNonNegative<uint64_t>(candidate_pair.bytes_sent);
+ verifier.TestMemberIsNonNegative<uint64_t>(
+ candidate_pair.bytes_discarded_on_send);
verifier.TestMemberIsNonNegative<uint64_t>(candidate_pair.bytes_received);
verifier.TestMemberIsNonNegative<double>(
candidate_pair.total_round_trip_time);
diff --git a/stats/rtcstats_objects.cc b/stats/rtcstats_objects.cc
index 762011d..961d17c 100644
--- a/stats/rtcstats_objects.cc
+++ b/stats/rtcstats_objects.cc
@@ -173,6 +173,8 @@
&nominated,
&writable,
&readable,
+ &packets_sent,
+ &packets_received,
&bytes_sent,
&bytes_received,
&total_round_trip_time,
@@ -188,7 +190,9 @@
&consent_requests_received,
&consent_requests_sent,
&consent_responses_received,
- &consent_responses_sent)
+ &consent_responses_sent,
+ &packets_discarded_on_send,
+ &bytes_discarded_on_send)
// clang-format on
RTCIceCandidatePairStats::RTCIceCandidatePairStats(const std::string& id,
@@ -206,6 +210,8 @@
nominated("nominated"),
writable("writable"),
readable("readable"),
+ packets_sent("packetsSent"),
+ packets_received("packetsReceived"),
bytes_sent("bytesSent"),
bytes_received("bytesReceived"),
total_round_trip_time("totalRoundTripTime"),
@@ -221,7 +227,9 @@
consent_requests_received("consentRequestsReceived"),
consent_requests_sent("consentRequestsSent"),
consent_responses_received("consentResponsesReceived"),
- consent_responses_sent("consentResponsesSent") {}
+ consent_responses_sent("consentResponsesSent"),
+ packets_discarded_on_send("packetsDiscardedOnSend"),
+ bytes_discarded_on_send("bytesDiscardedOnSend") {}
RTCIceCandidatePairStats::RTCIceCandidatePairStats(
const RTCIceCandidatePairStats& other)
@@ -234,6 +242,8 @@
nominated(other.nominated),
writable(other.writable),
readable(other.readable),
+ packets_sent(other.packets_sent),
+ packets_received(other.packets_received),
bytes_sent(other.bytes_sent),
bytes_received(other.bytes_received),
total_round_trip_time(other.total_round_trip_time),
@@ -249,7 +259,9 @@
consent_requests_received(other.consent_requests_received),
consent_requests_sent(other.consent_requests_sent),
consent_responses_received(other.consent_responses_received),
- consent_responses_sent(other.consent_responses_sent) {}
+ consent_responses_sent(other.consent_responses_sent),
+ packets_discarded_on_send(other.packets_discarded_on_send),
+ bytes_discarded_on_send(other.bytes_discarded_on_send) {}
RTCIceCandidatePairStats::~RTCIceCandidatePairStats() {}