Avoid `channel()` in LegacyStatsCollector transport lookup
Refactors ExtractSessionInfo_n to use JsepTransportController for
transport name lookup, avoiding unsafe access to
RtpTransceiver::channel() on the network thread.
Key changes:
- ExtractSessionInfo_n now takes a vector of mids instead of a map.
- Added virtual GetTransportName() to handle transport lookup, allowing
overrides in unit tests where JsepTransportController is absent.
Bug: None
Change-Id: I33afbb7c0f56245e1b332b820fb09cd8e20cebf5
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/436840
Commit-Queue: Tomas Gunnarsson <tommi@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#46544}
diff --git a/pc/BUILD.gn b/pc/BUILD.gn
index bbf173a..6938af7 100644
--- a/pc/BUILD.gn
+++ b/pc/BUILD.gn
@@ -1414,6 +1414,8 @@
":channel",
":channel_interface",
":data_channel_utils",
+ ":jsep_transport",
+ ":jsep_transport_controller",
":legacy_stats_collector_interface",
":peer_connection_internal",
":rtp_receiver",
@@ -1437,6 +1439,7 @@
"../call:call_interfaces",
"../media:media_channel",
"../p2p:connection_info",
+ "../p2p:dtls_transport_internal",
"../p2p:ice_transport_internal",
"../p2p:p2p_constants",
"../p2p:port",
diff --git a/pc/legacy_stats_collector.cc b/pc/legacy_stats_collector.cc
index 06abf6b..6049200 100644
--- a/pc/legacy_stats_collector.cc
+++ b/pc/legacy_stats_collector.cc
@@ -41,9 +41,11 @@
#include "p2p/base/ice_transport_internal.h"
#include "p2p/base/p2p_constants.h"
#include "p2p/base/port.h"
+#include "p2p/dtls/dtls_transport_internal.h"
#include "pc/channel.h"
#include "pc/channel_interface.h"
#include "pc/data_channel_utils.h"
+#include "pc/jsep_transport_controller.h"
#include "pc/peer_connection_internal.h"
#include "pc/rtp_receiver.h"
#include "pc/rtp_receiver_proxy.h"
@@ -886,10 +888,10 @@
StatsCollection::Container data_report_collection;
auto transceivers = pc_->GetTransceiversInternal();
- std::map<RtpTransceiver*, std::string> mids;
+ std::vector<std::string> mids;
for (const auto& transceiver : transceivers) {
if (transceiver->mid()) {
- mids[transceiver->internal()] = *transceiver->mid();
+ mids.push_back(*transceiver->mid());
}
}
@@ -899,22 +901,36 @@
StatsCollection data_reports;
ExtractDataInfo_n(&data_reports);
data_report_collection = data_reports.DetachCollection();
- return ExtractSessionInfo_n(transceivers, mids,
- std::move(sctp_transport_name),
+ return ExtractSessionInfo_n(mids, std::move(sctp_transport_name),
std::move(sctp_mid));
});
reports_.MergeCollection(std::move(data_report_collection));
ExtractSessionInfo_s(stats);
-
return std::move(stats.transport_names_by_mid);
}
+std::optional<std::string> LegacyStatsCollector::GetTransportName(
+ absl::string_view mid) {
+ RTC_DCHECK_RUN_ON(pc_->network_thread());
+ JsepTransportController* controller = pc_->transport_controller_n();
+ if (!controller) {
+ return std::nullopt;
+ }
+ DtlsTransportInternal* dtls_transport = controller->GetDtlsTransport(mid);
+ if (!dtls_transport) {
+ return std::nullopt;
+ }
+ IceTransportInternal* ice_transport = dtls_transport->ice_transport();
+ if (!ice_transport) {
+ return std::nullopt;
+ }
+ return ice_transport->transport_name();
+}
+
LegacyStatsCollector::SessionStats LegacyStatsCollector::ExtractSessionInfo_n(
- const std::vector<scoped_refptr<
- RtpTransceiverProxyWithInternal<RtpTransceiver>>>& transceivers,
- const std::map<RtpTransceiver*, std::string>& mids,
+ const std::vector<std::string>& mids,
std::optional<std::string> sctp_transport_name,
std::optional<std::string> sctp_mid) {
TRACE_EVENT0("webrtc", "LegacyStatsCollector::ExtractSessionInfo_n");
@@ -922,14 +938,9 @@
Thread::ScopedDisallowBlockingCalls no_blocking_calls;
SessionStats stats;
stats.candidate_stats = pc_->GetPooledCandidateStats();
- for (auto& transceiver : transceivers) {
- ChannelInterface* channel = transceiver->internal()->channel();
- if (channel) {
- auto it = mids.find(transceiver->internal());
- if (it != mids.end()) {
- stats.transport_names_by_mid[it->second] =
- std::string(channel->transport_name());
- }
+ for (const std::string& mid : mids) {
+ if (std::optional<std::string> transport_name = GetTransportName(mid)) {
+ stats.transport_names_by_mid[mid] = *transport_name;
}
}
@@ -1240,8 +1251,10 @@
if (transceiver->mid()) {
gatherer->mid = *transceiver->mid();
}
- gatherer->transport_name = transport_names_by_mid.at(gatherer->mid);
-
+ auto it = transport_names_by_mid.find(gatherer->mid);
+ if (it != transport_names_by_mid.end()) {
+ gatherer->transport_name = it->second;
+ }
for (const auto& sender : transceiver->internal()->senders()) {
auto track = sender->track();
std::string track_id = (track ? track->id() : "");
diff --git a/pc/legacy_stats_collector.h b/pc/legacy_stats_collector.h
index 517ba7f..941c657 100644
--- a/pc/legacy_stats_collector.h
+++ b/pc/legacy_stats_collector.h
@@ -24,16 +24,15 @@
#include <utility>
#include <vector>
+#include "absl/strings/string_view.h"
#include "api/candidate.h"
#include "api/legacy_stats_types.h"
#include "api/media_stream_interface.h"
#include "api/peer_connection_interface.h"
-#include "api/scoped_refptr.h"
#include "p2p/base/connection_info.h"
#include "p2p/base/port.h"
#include "pc/legacy_stats_collector_interface.h"
#include "pc/peer_connection_internal.h"
-#include "pc/rtp_transceiver.h"
#include "pc/transport_stats.h"
#include "rtc_base/network_constants.h"
#include "rtc_base/ssl_certificate.h"
@@ -142,6 +141,9 @@
std::map<std::string, std::string> transport_names_by_mid;
};
+ // Overridden in unit tests to fake transport lookup.
+ virtual std::optional<std::string> GetTransportName(absl::string_view mid);
+
// Overridden in unit tests to fake timing.
virtual double GetTimeNow();
@@ -189,9 +191,7 @@
void UpdateTrackReports();
SessionStats ExtractSessionInfo_n(
- const std::vector<scoped_refptr<
- RtpTransceiverProxyWithInternal<RtpTransceiver>>>& transceivers,
- const std::map<RtpTransceiver*, std::string>& mids,
+ const std::vector<std::string>& mids,
std::optional<std::string> sctp_transport_name,
std::optional<std::string> sctp_mid);
void ExtractSessionInfo_s(SessionStats& session_stats);
diff --git a/pc/legacy_stats_collector_unittest.cc b/pc/legacy_stats_collector_unittest.cc
index 4d41052..b21c944 100644
--- a/pc/legacy_stats_collector_unittest.cc
+++ b/pc/legacy_stats_collector_unittest.cc
@@ -20,6 +20,7 @@
#include "absl/algorithm/container.h"
#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
#include "api/audio/audio_processing_statistics.h"
#include "api/audio_codecs/audio_encoder.h"
#include "api/candidate.h"
@@ -585,12 +586,26 @@
class LegacyStatsCollectorForTest : public LegacyStatsCollector {
public:
explicit LegacyStatsCollectorForTest(PeerConnectionInternal* pc, Clock& clock)
- : LegacyStatsCollector(pc, clock), time_now_(19477) {}
+ : LegacyStatsCollector(pc, clock),
+ time_now_(19477),
+ pc_(static_cast<FakePeerConnectionForStats*>(pc)) {}
double GetTimeNow() override { return time_now_; }
+ std::optional<std::string> GetTransportName(absl::string_view mid) override {
+ for (const auto& transceiver : pc_->GetTransceiversInternal()) {
+ if (transceiver->mid() == mid) {
+ if (auto* channel = transceiver->internal()->channel()) {
+ return std::string(channel->transport_name());
+ }
+ }
+ }
+ return std::nullopt;
+ }
+
private:
double time_now_;
+ FakePeerConnectionForStats* pc_;
};
class LegacyStatsCollectorTest : public ::testing::Test {