Keep RTCTransportStats on P2PTransportChannel.

This cl/ changes so that the RTCTransportStats bytes/packets
sent/recevied is computed in P2PTransportChannel. Previously
they were computed by aggregating over the Connections, but that
does not work when Connections are created and destroyed.

Bug: webrtc:13769
Change-Id: Ia97dfae70b5aced897d4813ec007ba61bc032f87
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/253100
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Jonas Oreland <jonaso@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#36103}
This commit is contained in:
Jonas Oreland 2022-03-01 13:55:37 +01:00 committed by WebRTC LUCI CQ
parent 4d278e2caf
commit 42da5a9a10
6 changed files with 123 additions and 18 deletions

View file

@ -38,6 +38,15 @@ struct IceTransportStats {
// Initially 0 and 1 once the first candidate pair has been selected.
// The counter is increase also when "unselecting" a connection.
uint32_t selected_candidate_pair_changes = 0;
// Bytes/packets sent/received.
// note: Is not the same as sum(connection_infos.bytes_sent)
// as connections are created and destroyed while the ICE transport
// is alive.
uint64_t bytes_sent = 0;
uint64_t bytes_received = 0;
uint64_t packets_sent = 0;
uint64_t packets_received = 0;
};
typedef std::vector<Candidate> Candidates;

View file

@ -1608,6 +1608,7 @@ int P2PTransportChannel::SendPacket(const char* data,
return -1;
}
packets_sent_++;
last_sent_packet_id_ = options.packet_id;
rtc::PacketOptions modified_options(options);
modified_options.info_signaled_after_sent.packet_type =
@ -1616,7 +1617,10 @@ int P2PTransportChannel::SendPacket(const char* data,
if (sent <= 0) {
RTC_DCHECK(sent < 0);
error_ = selected_connection_->GetError();
return sent;
}
bytes_sent_ += sent;
return sent;
}
@ -1643,6 +1647,11 @@ bool P2PTransportChannel::GetStats(IceTransportStats* ice_transport_stats) {
ice_transport_stats->selected_candidate_pair_changes =
selected_candidate_pair_changes_;
ice_transport_stats->bytes_sent = bytes_sent_;
ice_transport_stats->bytes_received = bytes_received_;
ice_transport_stats->packets_sent = packets_sent_;
ice_transport_stats->packets_received = packets_received_;
return true;
}
@ -2238,6 +2247,8 @@ void P2PTransportChannel::OnReadPacket(Connection* connection,
if (connection == selected_connection_) {
// Let the client know of an incoming packet
packets_received_++;
bytes_received_ += len;
RTC_DCHECK(connection->last_data_received() >= last_data_received_ms_);
last_data_received_ms_ =
std::max(last_data_received_ms_, connection->last_data_received());
@ -2249,6 +2260,8 @@ void P2PTransportChannel::OnReadPacket(Connection* connection,
if (!FindConnection(connection))
return;
packets_received_++;
bytes_received_ += len;
RTC_DCHECK(connection->last_data_received() >= last_data_received_ms_);
last_data_received_ms_ =
std::max(last_data_received_ms_, connection->last_data_received());

View file

@ -490,6 +490,12 @@ class RTC_EXPORT P2PTransportChannel : public IceTransportInternal {
Candidate candidate,
const webrtc::AsyncDnsResolverResult& result);
// Bytes/packets sent/received on this channel.
uint64_t bytes_sent_ = 0;
uint64_t bytes_received_ = 0;
uint64_t packets_sent_ = 0;
uint64_t packets_received_ = 0;
// Number of times the selected_connection_ has been modified.
uint32_t selected_candidate_pair_changes_ = 0;

View file

@ -1373,6 +1373,81 @@ TEST_F(P2PTransportChannelTest, GetStats) {
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);
EXPECT_EQ(10 * 36U, ice_transport_stats.bytes_sent);
EXPECT_EQ(10 * 36U, ice_transport_stats.bytes_received);
DestroyChannels();
}
TEST_F(P2PTransportChannelTest, GetStatsSwitchConnection) {
rtc::ScopedFakeClock clock;
IceConfig continual_gathering_config =
CreateIceConfig(1000, GATHER_CONTINUALLY);
ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
kDefaultPortAllocatorFlags);
AddAddress(0, kAlternateAddrs[1], "rmnet0", rtc::ADAPTER_TYPE_CELLULAR);
CreateChannels(continual_gathering_config, continual_gathering_config);
EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
ep2_ch1()->receiving() &&
ep2_ch1()->writable(),
kMediumTimeout, clock);
// Sends and receives 10 packets.
TestSendRecv(&clock);
IceTransportStats ice_transport_stats;
ASSERT_TRUE(ep1_ch1()->GetStats(&ice_transport_stats));
ASSERT_GE(ice_transport_stats.connection_infos.size(), 2u);
ASSERT_GE(ice_transport_stats.candidate_stats_list.size(), 2u);
EXPECT_EQ(ice_transport_stats.selected_candidate_pair_changes, 1u);
ConnectionInfo* best_conn_info = nullptr;
for (ConnectionInfo& info : ice_transport_stats.connection_infos) {
if (info.best_connection) {
best_conn_info = &info;
break;
}
}
ASSERT_TRUE(best_conn_info != nullptr);
EXPECT_TRUE(best_conn_info->new_connection);
EXPECT_TRUE(best_conn_info->receiving);
EXPECT_TRUE(best_conn_info->writable);
EXPECT_FALSE(best_conn_info->timeout);
EXPECT_EQ(10 * 36U, best_conn_info->sent_total_bytes);
EXPECT_EQ(10 * 36U, best_conn_info->recv_total_bytes);
EXPECT_EQ(10 * 36U, ice_transport_stats.bytes_sent);
EXPECT_EQ(10 * 36U, ice_transport_stats.bytes_received);
auto old_selected_connection = ep1_ch1()->selected_connection();
ep1_ch1()->RemoveConnectionForTest(
const_cast<Connection*>(old_selected_connection));
EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection() != nullptr,
kMediumTimeout, clock);
// Sends and receives 10 packets.
TestSendRecv(&clock);
IceTransportStats ice_transport_stats2;
ASSERT_TRUE(ep1_ch1()->GetStats(&ice_transport_stats2));
int64_t sum_bytes_sent = 0;
int64_t sum_bytes_received = 0;
for (ConnectionInfo& info : ice_transport_stats.connection_infos) {
sum_bytes_sent += info.sent_total_bytes;
sum_bytes_received += info.recv_total_bytes;
}
EXPECT_EQ(10 * 36U, sum_bytes_sent);
EXPECT_EQ(10 * 36U, sum_bytes_received);
EXPECT_EQ(20 * 36U, ice_transport_stats2.bytes_sent);
EXPECT_EQ(20 * 36U, ice_transport_stats2.bytes_received);
DestroyChannels();
}

View file

@ -2042,21 +2042,20 @@ void RTCStatsCollector::ProduceTransportStats_n(
new RTCTransportStats(RTCTransportStatsIDFromTransportChannel(
transport_name, channel_stats.component),
timestamp_us));
transport_stats->bytes_sent = 0;
transport_stats->packets_sent = 0;
transport_stats->bytes_received = 0;
transport_stats->packets_received = 0;
transport_stats->packets_sent =
channel_stats.ice_transport_stats.packets_sent;
transport_stats->packets_received =
channel_stats.ice_transport_stats.packets_received;
transport_stats->bytes_sent =
channel_stats.ice_transport_stats.bytes_sent;
transport_stats->bytes_received =
channel_stats.ice_transport_stats.bytes_received;
transport_stats->dtls_state =
DtlsTransportStateToRTCDtlsTransportState(channel_stats.dtls_state);
transport_stats->selected_candidate_pair_changes =
channel_stats.ice_transport_stats.selected_candidate_pair_changes;
for (const cricket::ConnectionInfo& info :
channel_stats.ice_transport_stats.connection_infos) {
*transport_stats->bytes_sent += info.sent_total_bytes;
*transport_stats->packets_sent +=
info.sent_total_packets - info.sent_discarded_packets;
*transport_stats->bytes_received += info.recv_total_bytes;
*transport_stats->packets_received += info.packets_received;
if (info.best_connection) {
transport_stats->selected_candidate_pair_id =
RTCIceCandidatePairStatsIDFromConnectionInfo(info);

View file

@ -2419,6 +2419,10 @@ TEST_F(RTCStatsCollectorTest, CollectRTCTransportStats) {
rtp_transport_channel_stats.ice_transport_stats.connection_infos.push_back(
rtp_connection_info);
rtp_transport_channel_stats.dtls_state = DtlsTransportState::kNew;
rtp_transport_channel_stats.ice_transport_stats.bytes_sent = 42;
rtp_transport_channel_stats.ice_transport_stats.packets_sent = 1;
rtp_transport_channel_stats.ice_transport_stats.bytes_received = 1337;
rtp_transport_channel_stats.ice_transport_stats.packets_received = 4;
rtp_transport_channel_stats.ice_transport_stats
.selected_candidate_pair_changes = 1;
pc_->SetTransportStats(kTransportName, {rtp_transport_channel_stats});
@ -2457,6 +2461,10 @@ TEST_F(RTCStatsCollectorTest, CollectRTCTransportStats) {
rtcp_transport_channel_stats.ice_transport_stats.connection_infos.push_back(
rtcp_connection_info);
rtcp_transport_channel_stats.dtls_state = DtlsTransportState::kConnecting;
rtcp_transport_channel_stats.ice_transport_stats.bytes_sent = 1337;
rtcp_transport_channel_stats.ice_transport_stats.packets_sent = 1;
rtcp_transport_channel_stats.ice_transport_stats.bytes_received = 42;
rtcp_transport_channel_stats.ice_transport_stats.packets_received = 4;
pc_->SetTransportStats(kTransportName, {rtp_transport_channel_stats,
rtcp_transport_channel_stats});
@ -2562,11 +2570,6 @@ TEST_F(RTCStatsCollectorTest, CollectRTCTransportStatsWithCrypto) {
rtp_connection_info.best_connection = false;
rtp_connection_info.local_candidate = *rtp_local_candidate.get();
rtp_connection_info.remote_candidate = *rtp_remote_candidate.get();
rtp_connection_info.sent_total_bytes = 42;
rtp_connection_info.recv_total_bytes = 1337;
rtp_connection_info.sent_total_packets = 3;
rtp_connection_info.sent_discarded_packets = 2;
rtp_connection_info.packets_received = 4;
cricket::TransportChannelStats rtp_transport_channel_stats;
rtp_transport_channel_stats.component = cricket::ICE_CANDIDATE_COMPONENT_RTP;
rtp_transport_channel_stats.ice_transport_stats.connection_infos.push_back(
@ -2588,12 +2591,12 @@ TEST_F(RTCStatsCollectorTest, CollectRTCTransportStatsWithCrypto) {
"RTCTransport_transport_" +
rtc::ToString(cricket::ICE_CANDIDATE_COMPONENT_RTP),
report->timestamp_us());
expected_rtp_transport.bytes_sent = 42;
expected_rtp_transport.packets_sent = 1;
expected_rtp_transport.bytes_received = 1337;
expected_rtp_transport.packets_received = 4;
expected_rtp_transport.dtls_state = RTCDtlsTransportState::kConnected;
expected_rtp_transport.selected_candidate_pair_changes = 1;
expected_rtp_transport.bytes_sent = 0;
expected_rtp_transport.bytes_received = 0;
expected_rtp_transport.packets_sent = 0;
expected_rtp_transport.packets_received = 0;
// Crypto parameters
expected_rtp_transport.tls_version = "0203";
expected_rtp_transport.dtls_cipher = "TLS_RSA_WITH_AES_128_CBC_SHA";