Add counting of PCs with private IP addresses exposed
Bug: chromium:718508
Change-Id: I37f166808297c565cbb4b4393a23f7a18ab2862d
Reviewed-on: https://webrtc-review.googlesource.com/88640
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Commit-Queue: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#23990}
diff --git a/pc/peerconnection.cc b/pc/peerconnection.cc
index a137f05..4d6244a 100644
--- a/pc/peerconnection.cc
+++ b/pc/peerconnection.cc
@@ -3525,6 +3525,10 @@
return;
}
NoteUsageEvent(UsageEvent::CANDIDATE_COLLECTED);
+ if (candidate->candidate().type() == LOCAL_PORT_TYPE &&
+ candidate->candidate().address().IsPrivateIP()) {
+ NoteUsageEvent(UsageEvent::PRIVATE_CANDIDATE_COLLECTED);
+ }
observer_->OnIceCandidate(candidate.get());
}
diff --git a/pc/peerconnection.h b/pc/peerconnection.h
index 33abbc7..0efe8b5 100644
--- a/pc/peerconnection.h
+++ b/pc/peerconnection.h
@@ -67,7 +67,8 @@
REMOTE_CANDIDATE_ADDED = 0x100,
ICE_STATE_CONNECTED = 0x200,
CLOSE_CALLED = 0x400,
- MAX_VALUE = 0x800,
+ PRIVATE_CANDIDATE_COLLECTED = 0x800,
+ MAX_VALUE = 0x1000,
};
explicit PeerConnection(PeerConnectionFactory* factory,
diff --git a/pc/peerconnection_histogram_unittest.cc b/pc/peerconnection_histogram_unittest.cc
index 049d4c5..0067cd6 100644
--- a/pc/peerconnection_histogram_unittest.cc
+++ b/pc/peerconnection_histogram_unittest.cc
@@ -14,12 +14,14 @@
#include "api/jsep.h"
#include "api/peerconnectionproxy.h"
#include "media/base/fakemediaengine.h"
+#include "p2p/client/basicportallocator.h"
#include "pc/mediasession.h"
#include "pc/peerconnection.h"
#include "pc/peerconnectionfactory.h"
#include "pc/peerconnectionwrapper.h"
#include "pc/sdputils.h"
#include "pc/test/fakesctptransport.h"
+#include "rtc_base/fakenetwork.h"
#include "rtc_base/gunit.h"
#include "rtc_base/virtualsocketserver.h"
#include "system_wrappers/include/metrics_default.h"
@@ -31,6 +33,8 @@
using ::testing::Values;
static constexpr int kDefaultTimeout = 10000;
+static const rtc::SocketAddress kDefaultLocalAddress("1.1.1.1", 0);
+static const rtc::SocketAddress kPrivateLocalAddress("10.1.1.1", 0);
int MakeUsageFingerprint(std::set<PeerConnection::UsageEvent> events) {
int signature = 0;
@@ -74,7 +78,6 @@
void PrepareToExchangeCandidates(RawWrapperPtr other) {
candidate_target_ = other;
}
-
bool HaveDataChannel() { return last_datachannel_; }
private:
@@ -122,22 +125,41 @@
buffered_candidates_.push_back(std::move(candidate_copy));
}
}
+
void AddBufferedIceCandidates() {
for (const auto& candidate : buffered_candidates_) {
EXPECT_TRUE(pc()->AddIceCandidate(candidate.get()));
}
buffered_candidates_.clear();
}
+
bool ConnectTo(PeerConnectionWrapperForUsageHistogramTest* callee) {
PrepareToExchangeCandidates(callee);
- EXPECT_TRUE(ExchangeOfferAnswerWith(callee));
+ if (!ExchangeOfferAnswerWith(callee)) {
+ return false;
+ }
AddBufferedIceCandidates();
callee->AddBufferedIceCandidates();
- EXPECT_TRUE_WAIT(IsConnected(), kDefaultTimeout);
- EXPECT_TRUE_WAIT(callee->IsConnected(), kDefaultTimeout);
+ WAIT(IsConnected(), kDefaultTimeout);
+ WAIT(callee->IsConnected(), kDefaultTimeout);
return IsConnected() && callee->IsConnected();
}
+ bool GenerateOfferAndCollectCandidates() {
+ auto offer = CreateOffer(RTCOfferAnswerOptions());
+ if (!offer) {
+ return false;
+ }
+ bool set_local_offer =
+ SetLocalDescription(CloneSessionDescription(offer.get()));
+ EXPECT_TRUE(set_local_offer);
+ if (!set_local_offer) {
+ return false;
+ }
+ EXPECT_TRUE_WAIT(observer()->ice_gathering_complete_, kDefaultTimeout);
+ return true;
+ }
+
private:
// Candidates that have been sent but not yet configured
std::vector<std::unique_ptr<webrtc::IceCandidateInterface>>
@@ -148,9 +170,8 @@
const webrtc::IceCandidateInterface* candidate) {
if (candidate_target_) {
this->candidate_target_->AddOrBufferIceCandidate(candidate);
- } else {
- FAIL() << "Early candidate detected";
}
+ // If target is not set, ignore. This happens in one-ended unit tests.
}
class PeerConnectionUsageHistogramTest : public ::testing::Test {
@@ -164,23 +185,37 @@
}
WrapperPtr CreatePeerConnection() {
- return CreatePeerConnection(
- RTCConfiguration(), PeerConnectionFactoryInterface::Options(), false);
+ return CreatePeerConnection(RTCConfiguration(),
+ PeerConnectionFactoryInterface::Options(),
+ nullptr, false);
}
WrapperPtr CreatePeerConnection(const RTCConfiguration& config) {
return CreatePeerConnection(
- config, PeerConnectionFactoryInterface::Options(), false);
+ config, PeerConnectionFactoryInterface::Options(), nullptr, false);
}
WrapperPtr CreatePeerConnectionWithImmediateReport() {
- return CreatePeerConnection(
- RTCConfiguration(), PeerConnectionFactoryInterface::Options(), true);
+ return CreatePeerConnection(RTCConfiguration(),
+ PeerConnectionFactoryInterface::Options(),
+ nullptr, true);
+ }
+
+ WrapperPtr CreatePeerConnectionWithPrivateLocalAddresses() {
+ fake_network_manager_.reset(new rtc::FakeNetworkManager());
+ fake_network_manager_->AddInterface(kDefaultLocalAddress);
+ fake_network_manager_->AddInterface(kPrivateLocalAddress);
+ std::unique_ptr<cricket::BasicPortAllocator> port_allocator(
+ new cricket::BasicPortAllocator(fake_network_manager_.get()));
+ return CreatePeerConnection(RTCConfiguration(),
+ PeerConnectionFactoryInterface::Options(),
+ std::move(port_allocator), false);
}
WrapperPtr CreatePeerConnection(
const RTCConfiguration& config,
const PeerConnectionFactoryInterface::Options factory_options,
+ std::unique_ptr<cricket::PortAllocator> allocator,
bool immediate_report) {
rtc::scoped_refptr<PeerConnectionFactoryForUsageHistogramTest> pc_factory(
new PeerConnectionFactoryForUsageHistogramTest());
@@ -190,8 +225,8 @@
pc_factory->ReturnHistogramVeryQuickly();
}
auto observer = absl::make_unique<ObserverForUsageHistogramTest>();
- auto pc = pc_factory->CreatePeerConnection(config, nullptr, nullptr,
- observer.get());
+ auto pc = pc_factory->CreatePeerConnection(config, std::move(allocator),
+ nullptr, observer.get());
if (!pc) {
return nullptr;
}
@@ -202,6 +237,7 @@
return wrapper;
}
+ std::unique_ptr<rtc::FakeNetworkManager> fake_network_manager_;
std::unique_ptr<rtc::VirtualSocketServer> vss_;
rtc::AutoSocketServerThread main_;
};
@@ -239,6 +275,46 @@
PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
PeerConnection::UsageEvent::CLOSE_CALLED});
+ // In this case, we may or may not have PRIVATE_CANDIDATE_COLLECTED,
+ // depending on the machine configuration.
+ EXPECT_EQ(2,
+ webrtc::metrics::NumSamples("WebRTC.PeerConnection.UsagePattern"));
+ EXPECT_TRUE(
+ webrtc::metrics::NumEvents("WebRTC.PeerConnection.UsagePattern",
+ expected_fingerprint) == 2 ||
+ webrtc::metrics::NumEvents(
+ "WebRTC.PeerConnection.UsagePattern",
+ expected_fingerprint |
+ static_cast<int>(
+ PeerConnection::UsageEvent::PRIVATE_CANDIDATE_COLLECTED)) ==
+ 2);
+}
+
+// Test getting the usage fingerprint when there are no host candidates.
+TEST_F(PeerConnectionUsageHistogramTest, FingerprintWithNoHostCandidates) {
+ RTCConfiguration config;
+ config.type = PeerConnectionInterface::kNoHost;
+ auto caller = CreatePeerConnection(config);
+ auto callee = CreatePeerConnection(config);
+ caller->AddAudioTrack("audio");
+ caller->AddVideoTrack("video");
+ // Under some bot configurations, this will fail - presumably bots where
+ // no working non-host addresses exist.
+ if (!caller->ConnectTo(callee.get())) {
+ return;
+ }
+ // If we manage to connect, we should get this precise fingerprint.
+ caller->pc()->Close();
+ callee->pc()->Close();
+ int expected_fingerprint = MakeUsageFingerprint(
+ {PeerConnection::UsageEvent::AUDIO_ADDED,
+ PeerConnection::UsageEvent::VIDEO_ADDED,
+ PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
+ PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_CALLED,
+ PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
+ PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
+ PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
+ PeerConnection::UsageEvent::CLOSE_CALLED});
EXPECT_EQ(2,
webrtc::metrics::NumSamples("WebRTC.PeerConnection.UsagePattern"));
EXPECT_EQ(2, webrtc::metrics::NumEvents("WebRTC.PeerConnection.UsagePattern",
@@ -264,8 +340,15 @@
PeerConnection::UsageEvent::CLOSE_CALLED});
EXPECT_EQ(2,
webrtc::metrics::NumSamples("WebRTC.PeerConnection.UsagePattern"));
- EXPECT_EQ(2, webrtc::metrics::NumEvents("WebRTC.PeerConnection.UsagePattern",
- expected_fingerprint));
+ EXPECT_TRUE(
+ webrtc::metrics::NumEvents("WebRTC.PeerConnection.UsagePattern",
+ expected_fingerprint) == 2 ||
+ webrtc::metrics::NumEvents(
+ "WebRTC.PeerConnection.UsagePattern",
+ expected_fingerprint |
+ static_cast<int>(
+ PeerConnection::UsageEvent::PRIVATE_CANDIDATE_COLLECTED)) ==
+ 2);
}
#endif // HAVE_SCTP
#endif // WEBRTC_ANDROID
@@ -317,4 +400,21 @@
expected_fingerprint));
}
+TEST_F(PeerConnectionUsageHistogramTest, FingerprintWithPrivateIP) {
+ auto caller = CreatePeerConnectionWithPrivateLocalAddresses();
+ caller->AddAudioTrack("audio");
+ ASSERT_TRUE(caller->GenerateOfferAndCollectCandidates());
+ caller->pc()->Close();
+ int expected_fingerprint = MakeUsageFingerprint(
+ {PeerConnection::UsageEvent::AUDIO_ADDED,
+ PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
+ PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
+ PeerConnection::UsageEvent::CLOSE_CALLED,
+ PeerConnection::UsageEvent::PRIVATE_CANDIDATE_COLLECTED});
+ EXPECT_EQ(1,
+ webrtc::metrics::NumSamples("WebRTC.PeerConnection.UsagePattern"));
+ EXPECT_EQ(1, webrtc::metrics::NumEvents("WebRTC.PeerConnection.UsagePattern",
+ expected_fingerprint));
+}
+
} // namespace webrtc