From b91d0f513049b398e662c0ed98ddafe6d2e6ded2 Mon Sep 17 00:00:00 2001 From: "guoweis@webrtc.org" Date: Tue, 17 Mar 2015 14:43:20 +0000 Subject: [PATCH] 1. Have IPIsPrivate calling IPIsLinkLocal 2. Also check the Mac based IPv6 3. move the ip filtering into createnetwork. It shouldn't be done in IsIgnoredNetwork as the IP inside that could change later. BUG= R=juberti@webrtc.org Review URL: https://webrtc-codereview.appspot.com/48509004 Cr-Commit-Position: refs/heads/master@{#8758} git-svn-id: http://webrtc.googlecode.com/svn/trunk@8758 4adac7df-926f-26a2-2b94-8c16560cd09d --- webrtc/base/ipaddress.cc | 15 +++++++++---- webrtc/base/ipaddress.h | 1 + webrtc/base/ipaddress_unittest.cc | 22 ++++++++++++++++++ webrtc/base/network.cc | 37 +++++++++++++++++++++++++------ webrtc/base/network.h | 3 ++- 5 files changed, 66 insertions(+), 12 deletions(-) diff --git a/webrtc/base/ipaddress.cc b/webrtc/base/ipaddress.cc index be709c834..ae3b38da8 100644 --- a/webrtc/base/ipaddress.cc +++ b/webrtc/base/ipaddress.cc @@ -300,9 +300,7 @@ bool IPIsPrivate(const IPAddress& ip) { return IsPrivateV4(ip.v4AddressAsHostOrderInteger()); } case AF_INET6: { - in6_addr v6 = ip.ipv6_address(); - return (v6.s6_addr[0] == 0xFE && v6.s6_addr[1] == 0x80) || - IPIsLoopback(ip); + return IPIsLinkLocal(ip) || IPIsLoopback(ip); } } return false; @@ -435,7 +433,16 @@ bool IPIs6To4(const IPAddress& ip) { bool IPIsLinkLocal(const IPAddress& ip) { // Can't use the helper because the prefix is 10 bits. in6_addr addr = ip.ipv6_address(); - return addr.s6_addr[0] == 0xFE && (addr.s6_addr[1] & 0x80) == 0x80; + return addr.s6_addr[0] == 0xFE && addr.s6_addr[1] == 0x80; +} + +// According to http://www.ietf.org/rfc/rfc2373.txt, Appendix A, page 19. An +// address which contains MAC will have its 11th and 12th bytes as FF:FE as well +// as the U/L bit as 1. +bool IPIsMacBased(const IPAddress& ip) { + in6_addr addr = ip.ipv6_address(); + return ((addr.s6_addr[8] & 0x02) && addr.s6_addr[11] == 0xFF && + addr.s6_addr[12] == 0xFE); } bool IPIsSiteLocal(const IPAddress& ip) { diff --git a/webrtc/base/ipaddress.h b/webrtc/base/ipaddress.h index 3d77c28b2..fb222eeba 100644 --- a/webrtc/base/ipaddress.h +++ b/webrtc/base/ipaddress.h @@ -163,6 +163,7 @@ size_t HashIP(const IPAddress& ip); bool IPIs6Bone(const IPAddress& ip); bool IPIs6To4(const IPAddress& ip); bool IPIsLinkLocal(const IPAddress& ip); +bool IPIsMacBased(const IPAddress& ip); bool IPIsSiteLocal(const IPAddress& ip); bool IPIsTeredo(const IPAddress& ip); bool IPIsULA(const IPAddress& ip); diff --git a/webrtc/base/ipaddress_unittest.cc b/webrtc/base/ipaddress_unittest.cc index 7ff6c095f..3a8087a5d 100644 --- a/webrtc/base/ipaddress_unittest.cc +++ b/webrtc/base/ipaddress_unittest.cc @@ -46,6 +46,10 @@ static const std::string kIPv4PublicAddrAnonymizedString = "1.2.3.x"; static const std::string kIPv6AnyAddrString = "::"; static const std::string kIPv6LoopbackAddrString = "::1"; static const std::string kIPv6LinkLocalAddrString = "fe80::be30:5bff:fee5:c3"; +static const std::string kIPv6EuiAddrString = + "2620:0:1008:1201:a248:1cff:fe98:360"; +static const std::string kIPv6TemporaryAddrString = + "2620:0:1008:1201:2089:6dda:385e:80c0"; static const std::string kIPv6PublicAddrString = "2401:fa00:4:1000:be30:5bff:fee5:c3"; static const std::string kIPv6PublicAddrAnonymizedString = "2401:fa00:4::"; @@ -565,6 +569,24 @@ TEST(IPAddressTest, TestIsAny) { EXPECT_TRUE(IPIsAny(IPAddress(kIPv4MappedAnyAddr))); } +TEST(IPAddressTest, TestIsEui64) { + IPAddress addr; + EXPECT_TRUE(IPFromString(kIPv6EuiAddrString, &addr)); + EXPECT_TRUE(IPIsMacBased(addr)); + + EXPECT_TRUE(IPFromString(kIPv6TemporaryAddrString, &addr)); + EXPECT_FALSE(IPIsMacBased(addr)); + + EXPECT_TRUE(IPFromString(kIPv6LinkLocalAddrString, &addr)); + EXPECT_TRUE(IPIsMacBased(addr)); + + EXPECT_TRUE(IPFromString(kIPv6AnyAddrString, &addr)); + EXPECT_FALSE(IPIsMacBased(addr)); + + EXPECT_TRUE(IPFromString(kIPv6LoopbackAddrString, &addr)); + EXPECT_FALSE(IPIsMacBased(addr)); +} + TEST(IPAddressTest, TestNormalized) { // Check normalizing a ::ffff:a.b.c.d address. IPAddress addr; diff --git a/webrtc/base/network.cc b/webrtc/base/network.cc index 9ed1c87e3..ff092366f 100644 --- a/webrtc/base/network.cc +++ b/webrtc/base/network.cc @@ -128,6 +128,26 @@ std::string AdapterTypeToString(AdapterType type) { } } +bool IsIgnoredIPv6(const IPAddress& ip) { + if (ip.family() != AF_INET6) { + return false; + } + + // Link-local addresses require scope id to be bound successfully. + // However, our IPAddress structure doesn't carry that so the + // information is lost and causes binding failure. + if (IPIsLinkLocal(ip)) { + return true; + } + + // Any MAC based IPv6 should be avoided to prevent the MAC tracking. + if (IPIsMacBased(ip)) { + return true; + } + + return false; +} + } // namespace std::string MakeNetworkKey(const std::string& name, const IPAddress& prefix, @@ -334,6 +354,11 @@ void BasicNetworkManager::ConvertIfAddrs(struct ifaddrs* interfaces, if (ipv6_enabled()) { ip = IPAddress( reinterpret_cast(cursor->ifa_addr)->sin6_addr); + + if (IsIgnoredIPv6(ip)) { + continue; + } + mask = IPAddress( reinterpret_cast(cursor->ifa_netmask)->sin6_addr); scope_id = @@ -489,6 +514,11 @@ bool BasicNetworkManager::CreateNetworks(bool include_ignored, reinterpret_cast(address->Address.lpSockaddr); scope_id = v6_addr->sin6_scope_id; ip = IPAddress(v6_addr->sin6_addr); + + if (IsIgnoredIPv6(ip)) { + continue; + } + break; } else { continue; @@ -602,13 +632,6 @@ bool BasicNetworkManager::IsIgnoredNetwork(const Network& network) const { return (network.prefix().v4AddressAsHostOrderInteger() < 0x01000000); } - // Linklocal addresses require scope id to be bound successfully. However, our - // IPAddress structure doesn't carry that so the information is lost and - // causes binding failure. - if (network.prefix().family() == AF_INET6 && - IPIsLinkLocal(network.GetBestIP())) { - return true; - } return false; } diff --git a/webrtc/base/network.h b/webrtc/base/network.h index 69108fe01..8e5c8f0fb 100644 --- a/webrtc/base/network.h +++ b/webrtc/base/network.h @@ -195,7 +195,8 @@ class BasicNetworkManager : public NetworkManagerBase, // Creates a network object for each network available on the machine. bool CreateNetworks(bool include_ignored, NetworkList* networks) const; - // Determines if a network should be ignored. + // Determines if a network should be ignored. This should only be determined + // based on the network's property instead of any individual IP. bool IsIgnoredNetwork(const Network& network) const; private: