Extending UsagePattern and private IP addresses.
Adding additional usage bits to the UsagePattern to:
- Track whether a mDNS candidate was collected
- Track whether a mDNS candidate was received from the remote peer
- Track whether a private IP address was received from the remote peer
The definition of a private IP address is extended to include 100.64/10 addresses.
Bug: None
Change-Id: I77182685120413d5c13c5f67e480d33fdcaefc6a
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/134000
Commit-Queue: Jeroen de Borst <jeroendb@webrtc.org>
Reviewed-by: Justin Uberti <juberti@google.com>
Reviewed-by: Steve Anton <steveanton@webrtc.org>
Reviewed-by: Qingsi Wang <qingsi@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#27747}
diff --git a/pc/peer_connection.cc b/pc/peer_connection.cc
index 1b011a3..f7cfc9a 100644
--- a/pc/peer_connection.cc
+++ b/pc/peer_connection.cc
@@ -76,9 +76,9 @@
using cricket::TransportInfo;
using cricket::LOCAL_PORT_TYPE;
-using cricket::STUN_PORT_TYPE;
-using cricket::RELAY_PORT_TYPE;
using cricket::PRFLX_PORT_TYPE;
+using cricket::RELAY_PORT_TYPE;
+using cricket::STUN_PORT_TYPE;
namespace webrtc {
@@ -3584,6 +3584,12 @@
bool result = UseCandidate(ice_candidate);
if (result) {
NoteUsageEvent(UsageEvent::REMOTE_CANDIDATE_ADDED);
+ if (ice_candidate->candidate().address().IsUnresolvedIP()) {
+ NoteUsageEvent(UsageEvent::REMOTE_MDNS_CANDIDATE_ADDED);
+ }
+ if (ice_candidate->candidate().address().IsPrivateIP()) {
+ NoteUsageEvent(UsageEvent::REMOTE_PRIVATE_CANDIDATE_ADDED);
+ }
NoteAddIceCandidateResult(kAddIceCandidateSuccess);
} else {
NoteAddIceCandidateResult(kAddIceCandidateFailNotUsable);
@@ -4154,6 +4160,10 @@
candidate->candidate().address().IsPrivateIP()) {
NoteUsageEvent(UsageEvent::PRIVATE_CANDIDATE_COLLECTED);
}
+ if (candidate->candidate().type() == LOCAL_PORT_TYPE &&
+ candidate->candidate().address().IsUnresolvedIP()) {
+ NoteUsageEvent(UsageEvent::MDNS_CANDIDATE_COLLECTED);
+ }
Observer()->OnIceCandidate(candidate.get());
}
diff --git a/pc/peer_connection.h b/pc/peer_connection.h
index c21261c..39cb867 100644
--- a/pc/peer_connection.h
+++ b/pc/peer_connection.h
@@ -73,7 +73,10 @@
ICE_STATE_CONNECTED = 0x200,
CLOSE_CALLED = 0x400,
PRIVATE_CANDIDATE_COLLECTED = 0x800,
- MAX_VALUE = 0x1000,
+ REMOTE_PRIVATE_CANDIDATE_ADDED = 0x1000,
+ MDNS_CANDIDATE_COLLECTED = 0x2000,
+ REMOTE_MDNS_CANDIDATE_ADDED = 0x4000,
+ MAX_VALUE = 0x8000,
};
explicit PeerConnection(PeerConnectionFactory* factory,
diff --git a/pc/peer_connection_histogram_unittest.cc b/pc/peer_connection_histogram_unittest.cc
index 78b41d5..97555a9 100644
--- a/pc/peer_connection_histogram_unittest.cc
+++ b/pc/peer_connection_histogram_unittest.cc
@@ -23,6 +23,7 @@
#include "api/rtc_error.h"
#include "api/scoped_refptr.h"
#include "media/base/fake_media_engine.h"
+#include "p2p/base/mock_async_resolver.h"
#include "p2p/base/port_allocator.h"
#include "p2p/client/basic_port_allocator.h"
#include "pc/peer_connection.h"
@@ -30,6 +31,7 @@
#include "pc/peer_connection_wrapper.h"
#include "pc/sdp_utils.h"
#include "pc/test/mock_peer_connection_observers.h"
+#include "rtc_base/arraysize.h"
#include "rtc_base/checks.h"
#include "rtc_base/fake_network.h"
#include "rtc_base/gunit.h"
@@ -39,17 +41,19 @@
#include "rtc_base/thread.h"
#include "rtc_base/virtual_socket_server.h"
#include "system_wrappers/include/metrics.h"
-#include "test/gtest.h"
+#include "test/gmock.h"
namespace webrtc {
using RTCConfiguration = PeerConnectionInterface::RTCConfiguration;
using RTCOfferAnswerOptions = PeerConnectionInterface::RTCOfferAnswerOptions;
+using ::testing::NiceMock;
using ::testing::Values;
static const char kUsagePatternMetric[] = "WebRTC.PeerConnection.UsagePattern";
static constexpr int kDefaultTimeout = 10000;
-static const rtc::SocketAddress kDefaultLocalAddress("1.1.1.1", 0);
+static const rtc::SocketAddress kLocalAddrs[2] = {
+ rtc::SocketAddress("1.1.1.1", 0), rtc::SocketAddress("2.2.2.2", 0)};
static const rtc::SocketAddress kPrivateLocalAddress("10.1.1.1", 0);
int MakeUsageFingerprint(std::set<PeerConnection::UsageEvent> events) {
@@ -234,6 +238,27 @@
config, PeerConnectionFactoryInterface::Options(), nullptr, false);
}
+ WrapperPtr CreatePeerConnectionWithMdns(const RTCConfiguration& config) {
+ auto resolver_factory =
+ absl::make_unique<NiceMock<webrtc::MockAsyncResolverFactory>>();
+
+ webrtc::PeerConnectionDependencies deps(nullptr /* observer_in */);
+
+ auto fake_network = NewFakeNetwork();
+ fake_network->CreateMdnsResponder(rtc::Thread::Current());
+ fake_network->AddInterface(NextLocalAddress());
+
+ std::unique_ptr<cricket::BasicPortAllocator> port_allocator(
+ new cricket::BasicPortAllocator(fake_network));
+
+ deps.async_resolver_factory = std::move(resolver_factory);
+ deps.allocator = std::move(port_allocator);
+
+ return CreatePeerConnection(config,
+ PeerConnectionFactoryInterface::Options(),
+ std::move(deps), false);
+ }
+
WrapperPtr CreatePeerConnectionWithImmediateReport() {
return CreatePeerConnection(RTCConfiguration(),
PeerConnectionFactoryInterface::Options(),
@@ -241,11 +266,13 @@
}
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()));
+ auto* fake_network = NewFakeNetwork();
+ fake_network->AddInterface(NextLocalAddress());
+ fake_network->AddInterface(kPrivateLocalAddress);
+
+ auto port_allocator =
+ absl::make_unique<cricket::BasicPortAllocator>(fake_network);
+
return CreatePeerConnection(RTCConfiguration(),
PeerConnectionFactoryInterface::Options(),
std::move(port_allocator), false);
@@ -256,6 +283,18 @@
const PeerConnectionFactoryInterface::Options factory_options,
std::unique_ptr<cricket::PortAllocator> allocator,
bool immediate_report) {
+ PeerConnectionDependencies deps(nullptr);
+ deps.allocator = std::move(allocator);
+
+ return CreatePeerConnection(config, factory_options, std::move(deps),
+ immediate_report);
+ }
+
+ WrapperPtr CreatePeerConnection(
+ const RTCConfiguration& config,
+ const PeerConnectionFactoryInterface::Options factory_options,
+ PeerConnectionDependencies deps,
+ bool immediate_report) {
rtc::scoped_refptr<PeerConnectionFactoryForUsageHistogramTest> pc_factory(
new PeerConnectionFactoryForUsageHistogramTest());
pc_factory->SetOptions(factory_options);
@@ -263,9 +302,20 @@
if (immediate_report) {
pc_factory->ReturnHistogramVeryQuickly();
}
+
+ // If no allocator is provided, one will be created using a network manager
+ // that uses the host network. This doesn't work on all trybots.
+ if (!deps.allocator) {
+ auto fake_network = NewFakeNetwork();
+ fake_network->AddInterface(NextLocalAddress());
+ deps.allocator =
+ absl::make_unique<cricket::BasicPortAllocator>(fake_network);
+ }
+
auto observer = absl::make_unique<ObserverForUsageHistogramTest>();
- auto pc = pc_factory->CreatePeerConnection(config, std::move(allocator),
- nullptr, observer.get());
+ deps.observer = observer.get();
+
+ auto pc = pc_factory->CreatePeerConnection(config, std::move(deps));
if (!pc) {
return nullptr;
}
@@ -284,7 +334,23 @@
return webrtc::metrics::MinSample(kUsagePatternMetric);
}
- std::unique_ptr<rtc::FakeNetworkManager> fake_network_manager_;
+ // The PeerConnection's port allocator is tied to the PeerConnection's
+ // lifetime and expects the underlying NetworkManager to outlive it. That
+ // prevents us from having the PeerConnectionWrapper own the fake network.
+ // Therefore, the test fixture will own all the fake networks even though
+ // tests should access the fake network through the PeerConnectionWrapper.
+ rtc::FakeNetworkManager* NewFakeNetwork() {
+ fake_networks_.emplace_back(absl::make_unique<rtc::FakeNetworkManager>());
+ return fake_networks_.back().get();
+ }
+
+ rtc::SocketAddress NextLocalAddress() {
+ RTC_DCHECK(next_local_address_ < (int)arraysize(kLocalAddrs));
+ return kLocalAddrs[next_local_address_++];
+ }
+
+ std::vector<std::unique_ptr<rtc::FakeNetworkManager>> fake_networks_;
+ int next_local_address_ = 0;
std::unique_ptr<rtc::VirtualSocketServer> vss_;
rtc::AutoSocketServerThread main_;
};
@@ -343,12 +409,7 @@
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.
+ ASSERT_TRUE(caller->ConnectTo(callee.get()));
caller->pc()->Close();
callee->pc()->Close();
int expected_fingerprint = MakeUsageFingerprint(
@@ -365,6 +426,91 @@
2, webrtc::metrics::NumEvents(kUsagePatternMetric, expected_fingerprint));
}
+// Test getting the usage fingerprint when there are no host candidates.
+TEST_F(PeerConnectionUsageHistogramTest, FingerprintWithMdnsCaller) {
+ RTCConfiguration config;
+
+ // Enable hostname candidates with mDNS names.
+ auto caller = CreatePeerConnectionWithMdns(config);
+ auto callee = CreatePeerConnection(config);
+
+ caller->AddAudioTrack("audio");
+ caller->AddVideoTrack("video");
+ ASSERT_TRUE(caller->ConnectTo(callee.get()));
+ caller->pc()->Close();
+ callee->pc()->Close();
+
+ int expected_fingerprint_caller = 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::MDNS_CANDIDATE_COLLECTED,
+ PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
+ PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
+ PeerConnection::UsageEvent::CLOSE_CALLED});
+
+ int expected_fingerprint_callee = 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::REMOTE_MDNS_CANDIDATE_ADDED,
+ PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
+ PeerConnection::UsageEvent::CLOSE_CALLED});
+
+ EXPECT_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric));
+ EXPECT_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric,
+ expected_fingerprint_caller));
+ EXPECT_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric,
+ expected_fingerprint_callee));
+}
+
+TEST_F(PeerConnectionUsageHistogramTest, FingerprintWithMdnsCallee) {
+ RTCConfiguration config;
+
+ // Enable hostname candidates with mDNS names.
+ auto caller = CreatePeerConnection(config);
+ auto callee = CreatePeerConnectionWithMdns(config);
+
+ caller->AddAudioTrack("audio");
+ caller->AddVideoTrack("video");
+ ASSERT_TRUE(caller->ConnectTo(callee.get()));
+ caller->pc()->Close();
+ callee->pc()->Close();
+
+ int expected_fingerprint_caller = 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::REMOTE_MDNS_CANDIDATE_ADDED,
+ PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
+ PeerConnection::UsageEvent::CLOSE_CALLED});
+
+ int expected_fingerprint_callee = 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::MDNS_CANDIDATE_COLLECTED,
+ PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
+ PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
+ PeerConnection::UsageEvent::CLOSE_CALLED});
+
+ EXPECT_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric));
+ EXPECT_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric,
+ expected_fingerprint_caller));
+ EXPECT_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric,
+ expected_fingerprint_callee));
+}
+
#ifdef HAVE_SCTP
TEST_F(PeerConnectionUsageHistogramTest, FingerprintDataOnly) {
auto caller = CreatePeerConnection();
@@ -441,20 +587,74 @@
1, webrtc::metrics::NumEvents(kUsagePatternMetric, expected_fingerprint));
}
-TEST_F(PeerConnectionUsageHistogramTest, FingerprintWithPrivateIP) {
+TEST_F(PeerConnectionUsageHistogramTest, FingerprintWithPrivateIPCaller) {
auto caller = CreatePeerConnectionWithPrivateLocalAddresses();
+ auto callee = CreatePeerConnection();
caller->AddAudioTrack("audio");
- ASSERT_TRUE(caller->GenerateOfferAndCollectCandidates());
+ ASSERT_TRUE(caller->ConnectTo(callee.get()));
caller->pc()->Close();
- int expected_fingerprint = MakeUsageFingerprint(
+ callee->pc()->Close();
+
+ int expected_fingerprint_caller = MakeUsageFingerprint(
{PeerConnection::UsageEvent::AUDIO_ADDED,
PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
+ PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_CALLED,
PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
- PeerConnection::UsageEvent::CLOSE_CALLED,
- PeerConnection::UsageEvent::PRIVATE_CANDIDATE_COLLECTED});
- EXPECT_EQ(1, webrtc::metrics::NumSamples(kUsagePatternMetric));
- EXPECT_EQ(
- 1, webrtc::metrics::NumEvents(kUsagePatternMetric, expected_fingerprint));
+ PeerConnection::UsageEvent::PRIVATE_CANDIDATE_COLLECTED,
+ PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
+ PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
+ PeerConnection::UsageEvent::CLOSE_CALLED});
+
+ int expected_fingerprint_callee = MakeUsageFingerprint(
+ {PeerConnection::UsageEvent::AUDIO_ADDED,
+ PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
+ PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_CALLED,
+ PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
+ PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
+ PeerConnection::UsageEvent::REMOTE_PRIVATE_CANDIDATE_ADDED,
+ PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
+ PeerConnection::UsageEvent::CLOSE_CALLED});
+
+ EXPECT_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric));
+ EXPECT_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric,
+ expected_fingerprint_caller));
+ EXPECT_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric,
+ expected_fingerprint_callee));
+}
+
+TEST_F(PeerConnectionUsageHistogramTest, FingerprintWithPrivateIPCallee) {
+ auto caller = CreatePeerConnection();
+ auto callee = CreatePeerConnectionWithPrivateLocalAddresses();
+ caller->AddAudioTrack("audio");
+ ASSERT_TRUE(caller->ConnectTo(callee.get()));
+ caller->pc()->Close();
+ callee->pc()->Close();
+
+ int expected_fingerprint_caller = MakeUsageFingerprint(
+ {PeerConnection::UsageEvent::AUDIO_ADDED,
+ PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
+ PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_CALLED,
+ PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
+ PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
+ PeerConnection::UsageEvent::REMOTE_PRIVATE_CANDIDATE_ADDED,
+ PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
+ PeerConnection::UsageEvent::CLOSE_CALLED});
+
+ int expected_fingerprint_callee = MakeUsageFingerprint(
+ {PeerConnection::UsageEvent::AUDIO_ADDED,
+ PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_CALLED,
+ PeerConnection::UsageEvent::SET_REMOTE_DESCRIPTION_CALLED,
+ PeerConnection::UsageEvent::CANDIDATE_COLLECTED,
+ PeerConnection::UsageEvent::PRIVATE_CANDIDATE_COLLECTED,
+ PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
+ PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
+ PeerConnection::UsageEvent::CLOSE_CALLED});
+
+ EXPECT_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric));
+ EXPECT_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric,
+ expected_fingerprint_caller));
+ EXPECT_EQ(1, webrtc::metrics::NumEvents(kUsagePatternMetric,
+ expected_fingerprint_callee));
}
#ifndef WEBRTC_ANDROID
diff --git a/rtc_base/ip_address.cc b/rtc_base/ip_address.cc
index ff0be13..96d1001 100644
--- a/rtc_base/ip_address.cc
+++ b/rtc_base/ip_address.cc
@@ -235,6 +235,18 @@
return false;
}
+static bool IPIsSharedNetworkV4(const IPAddress& ip) {
+ uint32_t ip_in_host_order = ip.v4AddressAsHostOrderInteger();
+ return (ip_in_host_order >> 22) == ((100 << 2) | 1);
+}
+
+bool IPIsSharedNetwork(const IPAddress& ip) {
+ if (ip.family() == AF_INET) {
+ return IPIsSharedNetworkV4(ip);
+ }
+ return false;
+}
+
in_addr ExtractMappedAddress(const in6_addr& in6) {
in_addr ipv4;
::memcpy(&ipv4.s_addr, &in6.s6_addr[12], sizeof(ipv4.s_addr));
@@ -319,7 +331,8 @@
}
bool IPIsPrivate(const IPAddress& ip) {
- return IPIsLinkLocal(ip) || IPIsLoopback(ip) || IPIsPrivateNetwork(ip);
+ return IPIsLinkLocal(ip) || IPIsLoopback(ip) || IPIsPrivateNetwork(ip) ||
+ IPIsSharedNetwork(ip);
}
bool IPIsUnspec(const IPAddress& ip) {
@@ -407,7 +420,9 @@
bits = (i * 32);
break;
}
- default: { return 0; }
+ default: {
+ return 0;
+ }
}
if (word_to_count == 0) {
return bits;
diff --git a/rtc_base/ip_address.h b/rtc_base/ip_address.h
index 49dea68..2a52e1a 100644
--- a/rtc_base/ip_address.h
+++ b/rtc_base/ip_address.h
@@ -22,6 +22,7 @@
#include <ws2tcpip.h>
#endif
#include <string.h>
+
#include <string>
#include "rtc_base/byte_order.h"
@@ -157,8 +158,12 @@
// Identify a private network address like "192.168.111.222"
// (see https://en.wikipedia.org/wiki/Private_network )
bool IPIsPrivateNetwork(const IPAddress& ip);
+// Identify a shared network address like "100.72.16.122"
+// (see RFC6598)
+bool IPIsSharedNetwork(const IPAddress& ip);
// Identify if an IP is "private", that is a loopback
-// or an address belonging to a link-local or a private network.
+// or an address belonging to a link-local, a private network or a shared
+// network.
bool IPIsPrivate(const IPAddress& ip);
bool IPIsUnspec(const IPAddress& ip);
size_t HashIP(const IPAddress& ip);
diff --git a/rtc_base/ip_address_unittest.cc b/rtc_base/ip_address_unittest.cc
index c93244d..d79a7b4 100644
--- a/rtc_base/ip_address_unittest.cc
+++ b/rtc_base/ip_address_unittest.cc
@@ -18,6 +18,7 @@
static const unsigned int kIPv6AddrSize = 16;
static const unsigned int kIPv4RFC1918Addr = 0xC0A80701;
static const unsigned int kIPv4PublicAddr = 0x01020304;
+static const unsigned int kIPv4RFC6598Addr = 0x64410801;
static const unsigned int kIPv4LinkLocalAddr = 0xA9FE10C1; // 169.254.16.193
static const in6_addr kIPv6LinkLocalAddr = {
{{0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x30, 0x5b, 0xff,
@@ -41,6 +42,7 @@
static const std::string kIPv4AnyAddrString = "0.0.0.0";
static const std::string kIPv4LoopbackAddrString = "127.0.0.1";
static const std::string kIPv4RFC1918AddrString = "192.168.7.1";
+static const std::string kIPv4RFC6598AddrString = "100.65.8.1";
static const std::string kIPv4PublicAddrString = "1.2.3.4";
static const std::string kIPv4PublicAddrAnonymizedString = "1.2.3.x";
static const std::string kIPv6AnyAddrString = "::";
@@ -179,6 +181,7 @@
addr = IPAddress(v4addr);
EXPECT_FALSE(IPIsAny(addr));
EXPECT_TRUE(IPIsLoopback(addr));
+ EXPECT_FALSE(IPIsSharedNetwork(addr));
EXPECT_TRUE(IPIsPrivate(addr));
EXPECT_EQ(kIPv4AddrSize, addr.Size());
EXPECT_EQ(kIPv4LoopbackAddrString, addr.ToString());
@@ -188,10 +191,21 @@
addr = IPAddress(v4addr);
EXPECT_FALSE(IPIsAny(addr));
EXPECT_FALSE(IPIsLoopback(addr));
+ EXPECT_FALSE(IPIsSharedNetwork(addr));
EXPECT_TRUE(IPIsPrivate(addr));
EXPECT_EQ(kIPv4AddrSize, addr.Size());
EXPECT_EQ(kIPv4RFC1918AddrString, addr.ToString());
+ // Test an shared (RFC6598) address.
+ v4addr.s_addr = htonl(kIPv4RFC6598Addr);
+ addr = IPAddress(v4addr);
+ EXPECT_FALSE(IPIsAny(addr));
+ EXPECT_FALSE(IPIsLoopback(addr));
+ EXPECT_TRUE(IPIsPrivate(addr));
+ EXPECT_TRUE(IPIsSharedNetwork(addr));
+ EXPECT_EQ(kIPv4AddrSize, addr.Size());
+ EXPECT_EQ(kIPv4RFC6598AddrString, addr.ToString());
+
// Test a 'normal' v4 address.
v4addr.s_addr = htonl(kIPv4PublicAddr);
addr = IPAddress(v4addr);
@@ -215,6 +229,7 @@
addr = IPAddress(in6addr_loopback);
EXPECT_FALSE(IPIsAny(addr));
EXPECT_TRUE(IPIsLoopback(addr));
+ EXPECT_FALSE(IPIsSharedNetwork(addr));
EXPECT_TRUE(IPIsPrivate(addr));
EXPECT_EQ(kIPv6AddrSize, addr.Size());
EXPECT_EQ(kIPv6LoopbackAddrString, addr.ToString());
@@ -223,6 +238,7 @@
addr = IPAddress(kIPv6LinkLocalAddr);
EXPECT_FALSE(IPIsAny(addr));
EXPECT_FALSE(IPIsLoopback(addr));
+ EXPECT_FALSE(IPIsSharedNetwork(addr));
EXPECT_TRUE(IPIsPrivate(addr));
EXPECT_EQ(kIPv6AddrSize, addr.Size());
EXPECT_EQ(kIPv6LinkLocalAddrString, addr.ToString());
@@ -249,6 +265,7 @@
addr = IPAddress(INADDR_LOOPBACK);
EXPECT_FALSE(IPIsAny(addr));
EXPECT_TRUE(IPIsLoopback(addr));
+ EXPECT_FALSE(IPIsSharedNetwork(addr));
EXPECT_TRUE(IPIsPrivate(addr));
EXPECT_EQ(kIPv4AddrSize, addr.Size());
EXPECT_EQ(kIPv4LoopbackAddrString, addr.ToString());
@@ -257,6 +274,7 @@
addr = IPAddress(kIPv4RFC1918Addr);
EXPECT_FALSE(IPIsAny(addr));
EXPECT_FALSE(IPIsLoopback(addr));
+ EXPECT_FALSE(IPIsSharedNetwork(addr));
EXPECT_TRUE(IPIsPrivate(addr));
EXPECT_EQ(kIPv4AddrSize, addr.Size());
EXPECT_EQ(kIPv4RFC1918AddrString, addr.ToString());
@@ -537,6 +555,7 @@
EXPECT_FALSE(IPIsPrivate(IPAddress(kIPv4MappedPublicAddr)));
EXPECT_TRUE(IPIsPrivate(IPAddress(kIPv4RFC1918Addr)));
+ EXPECT_TRUE(IPIsPrivate(IPAddress(kIPv4RFC6598Addr)));
EXPECT_TRUE(IPIsPrivate(IPAddress(INADDR_LOOPBACK)));
EXPECT_TRUE(IPIsPrivate(IPAddress(in6addr_loopback)));
EXPECT_TRUE(IPIsPrivate(IPAddress(kIPv6LinkLocalAddr)));
@@ -559,6 +578,7 @@
EXPECT_FALSE(IPIsLoopback(IPAddress(INADDR_ANY)));
EXPECT_FALSE(IPIsLoopback(IPAddress(kIPv4PublicAddr)));
EXPECT_FALSE(IPIsLoopback(IPAddress(in6addr_any)));
+ EXPECT_FALSE(IPIsLoopback(IPAddress(kIPv4RFC6598Addr)));
EXPECT_FALSE(IPIsLoopback(IPAddress(kIPv6PublicAddr)));
EXPECT_FALSE(IPIsLoopback(IPAddress(kIPv4MappedAnyAddr)));
EXPECT_FALSE(IPIsLoopback(IPAddress(kIPv4MappedPublicAddr)));
@@ -577,6 +597,8 @@
// loopback addresses
EXPECT_FALSE(IPIsLinkLocal(IPAddress(INADDR_LOOPBACK)));
EXPECT_FALSE(IPIsLinkLocal(IPAddress(in6addr_loopback)));
+ // shared addresses
+ EXPECT_FALSE(IPIsLinkLocal(IPAddress(kIPv4RFC6598Addr)));
// public addresses
EXPECT_FALSE(IPIsLinkLocal(IPAddress(kIPv4PublicAddr)));
EXPECT_FALSE(IPIsLinkLocal(IPAddress(kIPv6PublicAddr)));