Enable IPv6 temporary address filtering on iOS.
We'll only use temporary address for IPv6. However, due to a bug in iOS sdk, the necessary headers are not included. This change copies the minimum necessary definitions such that we could retrieve the ip attributes. BUG=webrtc:4343 Review URL: https://codereview.webrtc.org/1531763006 Cr-Commit-Position: refs/heads/master@{#11114}
This commit is contained in:
@ -221,6 +221,9 @@
|
||||
'httpserver.h',
|
||||
'ifaddrs-android.cc',
|
||||
'ifaddrs-android.h',
|
||||
'ifaddrs_converter.cc',
|
||||
'ifaddrs_converter.h',
|
||||
'macifaddrs_converter.cc',
|
||||
'iosfilesystem.mm',
|
||||
'ipaddress.cc',
|
||||
'ipaddress.h',
|
||||
@ -659,6 +662,9 @@
|
||||
],
|
||||
}],
|
||||
['OS=="win"', {
|
||||
'sources!': [
|
||||
'ifaddrs_converter.cc',
|
||||
],
|
||||
'link_settings': {
|
||||
'libraries': [
|
||||
'-lcrypt32.lib',
|
||||
@ -710,6 +716,7 @@
|
||||
}],
|
||||
['OS!="ios" and OS!="mac"', {
|
||||
'sources!': [
|
||||
'macifaddrs_converter.cc',
|
||||
'scoped_autorelease_pool.mm',
|
||||
],
|
||||
}],
|
||||
|
||||
62
webrtc/base/ifaddrs_converter.cc
Normal file
62
webrtc/base/ifaddrs_converter.cc
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2015 The WebRTC Project Authors. All rights reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "webrtc/base/ifaddrs_converter.h"
|
||||
|
||||
#include "webrtc/base/logging.h"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
IfAddrsConverter::IfAddrsConverter() {}
|
||||
|
||||
IfAddrsConverter::~IfAddrsConverter() {}
|
||||
|
||||
bool IfAddrsConverter::ConvertIfAddrsToIPAddress(
|
||||
const struct ifaddrs* interface,
|
||||
InterfaceAddress* ip,
|
||||
IPAddress* mask) {
|
||||
switch (interface->ifa_addr->sa_family) {
|
||||
case AF_INET: {
|
||||
*ip = IPAddress(
|
||||
reinterpret_cast<sockaddr_in*>(interface->ifa_addr)->sin_addr);
|
||||
*mask = IPAddress(
|
||||
reinterpret_cast<sockaddr_in*>(interface->ifa_netmask)->sin_addr);
|
||||
return true;
|
||||
}
|
||||
case AF_INET6: {
|
||||
int ip_attributes = IPV6_ADDRESS_FLAG_NONE;
|
||||
if (!ConvertNativeAttributesToIPAttributes(interface, &ip_attributes)) {
|
||||
return false;
|
||||
}
|
||||
*ip = InterfaceAddress(
|
||||
reinterpret_cast<sockaddr_in6*>(interface->ifa_addr)->sin6_addr,
|
||||
ip_attributes);
|
||||
*mask = IPAddress(
|
||||
reinterpret_cast<sockaddr_in6*>(interface->ifa_netmask)->sin6_addr);
|
||||
return true;
|
||||
}
|
||||
default: { return false; }
|
||||
}
|
||||
}
|
||||
|
||||
bool IfAddrsConverter::ConvertNativeAttributesToIPAttributes(
|
||||
const struct ifaddrs* interface,
|
||||
int* ip_attributes) {
|
||||
*ip_attributes = IPV6_ADDRESS_FLAG_NONE;
|
||||
return true;
|
||||
}
|
||||
|
||||
#if !defined(WEBRTC_MAC)
|
||||
// For MAC and IOS, it's defined in macifaddrs_converter.cc
|
||||
IfAddrsConverter* CreateIfAddrsConverter() {
|
||||
return new IfAddrsConverter();
|
||||
}
|
||||
#endif
|
||||
} // namespace rtc
|
||||
45
webrtc/base/ifaddrs_converter.h
Normal file
45
webrtc/base/ifaddrs_converter.h
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2015 The WebRTC Project Authors. All rights reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_BASE_IFADDRS_CONVERTER_H_
|
||||
#define WEBRTC_BASE_IFADDRS_CONVERTER_H_
|
||||
|
||||
#if defined(WEBRTC_ANDROID)
|
||||
#include "webrtc/base/ifaddrs-android.h"
|
||||
#else
|
||||
#include <ifaddrs.h>
|
||||
#endif // WEBRTC_ANDROID
|
||||
|
||||
#include "webrtc/base/ipaddress.h"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
// This class converts native interface addresses to our internal IPAddress
|
||||
// class. Subclasses should override ConvertNativeToIPAttributes to implement
|
||||
// the different ways of retrieving IPv6 attributes for various POSIX platforms.
|
||||
class IfAddrsConverter {
|
||||
public:
|
||||
IfAddrsConverter();
|
||||
virtual ~IfAddrsConverter();
|
||||
virtual bool ConvertIfAddrsToIPAddress(const struct ifaddrs* interface,
|
||||
InterfaceAddress* ipaddress,
|
||||
IPAddress* mask);
|
||||
|
||||
protected:
|
||||
virtual bool ConvertNativeAttributesToIPAttributes(
|
||||
const struct ifaddrs* interface,
|
||||
int* ip_attributes);
|
||||
};
|
||||
|
||||
IfAddrsConverter* CreateIfAddrsConverter();
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif // WEBRTC_BASE_IFADDRS_CONVERTER_H_
|
||||
281
webrtc/base/macifaddrs_converter.cc
Normal file
281
webrtc/base/macifaddrs_converter.cc
Normal file
@ -0,0 +1,281 @@
|
||||
/*
|
||||
* Copyright 2015 The WebRTC Project Authors. All rights reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include <net/if.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "webrtc/base/checks.h"
|
||||
#include "webrtc/base/ifaddrs_converter.h"
|
||||
#include "webrtc/base/logging.h"
|
||||
#include "webrtc/base/scoped_ptr.h"
|
||||
|
||||
#if !defined(WEBRTC_IOS)
|
||||
#include <net/if_media.h>
|
||||
#include <netinet/in_var.h>
|
||||
#else // WEBRTC_IOS
|
||||
#define SCOPE6_ID_MAX 16
|
||||
|
||||
struct in6_addrlifetime {
|
||||
time_t ia6t_expire; /* valid lifetime expiration time */
|
||||
time_t ia6t_preferred; /* preferred lifetime expiration time */
|
||||
u_int32_t ia6t_vltime; /* valid lifetime */
|
||||
u_int32_t ia6t_pltime; /* prefix lifetime */
|
||||
};
|
||||
|
||||
struct in6_ifstat {
|
||||
u_quad_t ifs6_in_receive; /* # of total input datagram */
|
||||
u_quad_t ifs6_in_hdrerr; /* # of datagrams with invalid hdr */
|
||||
u_quad_t ifs6_in_toobig; /* # of datagrams exceeded MTU */
|
||||
u_quad_t ifs6_in_noroute; /* # of datagrams with no route */
|
||||
u_quad_t ifs6_in_addrerr; /* # of datagrams with invalid dst */
|
||||
u_quad_t ifs6_in_protounknown; /* # of datagrams with unknown proto */
|
||||
/* NOTE: increment on final dst if */
|
||||
u_quad_t ifs6_in_truncated; /* # of truncated datagrams */
|
||||
u_quad_t ifs6_in_discard; /* # of discarded datagrams */
|
||||
/* NOTE: fragment timeout is not here */
|
||||
u_quad_t ifs6_in_deliver; /* # of datagrams delivered to ULP */
|
||||
/* NOTE: increment on final dst if */
|
||||
u_quad_t ifs6_out_forward; /* # of datagrams forwarded */
|
||||
/* NOTE: increment on outgoing if */
|
||||
u_quad_t ifs6_out_request; /* # of outgoing datagrams from ULP */
|
||||
/* NOTE: does not include forwrads */
|
||||
u_quad_t ifs6_out_discard; /* # of discarded datagrams */
|
||||
u_quad_t ifs6_out_fragok; /* # of datagrams fragmented */
|
||||
u_quad_t ifs6_out_fragfail; /* # of datagrams failed on fragment */
|
||||
u_quad_t ifs6_out_fragcreat; /* # of fragment datagrams */
|
||||
/* NOTE: this is # after fragment */
|
||||
u_quad_t ifs6_reass_reqd; /* # of incoming fragmented packets */
|
||||
/* NOTE: increment on final dst if */
|
||||
u_quad_t ifs6_reass_ok; /* # of reassembled packets */
|
||||
/* NOTE: this is # after reass */
|
||||
/* NOTE: increment on final dst if */
|
||||
u_quad_t ifs6_reass_fail; /* # of reass failures */
|
||||
/* NOTE: may not be packet count */
|
||||
/* NOTE: increment on final dst if */
|
||||
u_quad_t ifs6_in_mcast; /* # of inbound multicast datagrams */
|
||||
u_quad_t ifs6_out_mcast; /* # of outbound multicast datagrams */
|
||||
};
|
||||
struct icmp6_ifstat {
|
||||
/*
|
||||
* Input statistics
|
||||
*/
|
||||
/* ipv6IfIcmpInMsgs, total # of input messages */
|
||||
u_quad_t ifs6_in_msg;
|
||||
/* ipv6IfIcmpInErrors, # of input error messages */
|
||||
u_quad_t ifs6_in_error;
|
||||
/* ipv6IfIcmpInDestUnreachs, # of input dest unreach errors */
|
||||
u_quad_t ifs6_in_dstunreach;
|
||||
/* ipv6IfIcmpInAdminProhibs, # of input admin. prohibited errs */
|
||||
u_quad_t ifs6_in_adminprohib;
|
||||
/* ipv6IfIcmpInTimeExcds, # of input time exceeded errors */
|
||||
u_quad_t ifs6_in_timeexceed;
|
||||
/* ipv6IfIcmpInParmProblems, # of input parameter problem errors */
|
||||
u_quad_t ifs6_in_paramprob;
|
||||
/* ipv6IfIcmpInPktTooBigs, # of input packet too big errors */
|
||||
u_quad_t ifs6_in_pkttoobig;
|
||||
/* ipv6IfIcmpInEchos, # of input echo requests */
|
||||
u_quad_t ifs6_in_echo;
|
||||
/* ipv6IfIcmpInEchoReplies, # of input echo replies */
|
||||
u_quad_t ifs6_in_echoreply;
|
||||
/* ipv6IfIcmpInRouterSolicits, # of input router solicitations */
|
||||
u_quad_t ifs6_in_routersolicit;
|
||||
/* ipv6IfIcmpInRouterAdvertisements, # of input router advertisements */
|
||||
u_quad_t ifs6_in_routeradvert;
|
||||
/* ipv6IfIcmpInNeighborSolicits, # of input neighbor solicitations */
|
||||
u_quad_t ifs6_in_neighborsolicit;
|
||||
/* ipv6IfIcmpInNeighborAdvertisements, # of input neighbor advs. */
|
||||
u_quad_t ifs6_in_neighboradvert;
|
||||
/* ipv6IfIcmpInRedirects, # of input redirects */
|
||||
u_quad_t ifs6_in_redirect;
|
||||
/* ipv6IfIcmpInGroupMembQueries, # of input MLD queries */
|
||||
u_quad_t ifs6_in_mldquery;
|
||||
/* ipv6IfIcmpInGroupMembResponses, # of input MLD reports */
|
||||
u_quad_t ifs6_in_mldreport;
|
||||
/* ipv6IfIcmpInGroupMembReductions, # of input MLD done */
|
||||
u_quad_t ifs6_in_mlddone;
|
||||
|
||||
/*
|
||||
* Output statistics. We should solve unresolved routing problem...
|
||||
*/
|
||||
/* ipv6IfIcmpOutMsgs, total # of output messages */
|
||||
u_quad_t ifs6_out_msg;
|
||||
/* ipv6IfIcmpOutErrors, # of output error messages */
|
||||
u_quad_t ifs6_out_error;
|
||||
/* ipv6IfIcmpOutDestUnreachs, # of output dest unreach errors */
|
||||
u_quad_t ifs6_out_dstunreach;
|
||||
/* ipv6IfIcmpOutAdminProhibs, # of output admin. prohibited errs */
|
||||
u_quad_t ifs6_out_adminprohib;
|
||||
/* ipv6IfIcmpOutTimeExcds, # of output time exceeded errors */
|
||||
u_quad_t ifs6_out_timeexceed;
|
||||
/* ipv6IfIcmpOutParmProblems, # of output parameter problem errors */
|
||||
u_quad_t ifs6_out_paramprob;
|
||||
/* ipv6IfIcmpOutPktTooBigs, # of output packet too big errors */
|
||||
u_quad_t ifs6_out_pkttoobig;
|
||||
/* ipv6IfIcmpOutEchos, # of output echo requests */
|
||||
u_quad_t ifs6_out_echo;
|
||||
/* ipv6IfIcmpOutEchoReplies, # of output echo replies */
|
||||
u_quad_t ifs6_out_echoreply;
|
||||
/* ipv6IfIcmpOutRouterSolicits, # of output router solicitations */
|
||||
u_quad_t ifs6_out_routersolicit;
|
||||
/* ipv6IfIcmpOutRouterAdvertisements, # of output router advs. */
|
||||
u_quad_t ifs6_out_routeradvert;
|
||||
/* ipv6IfIcmpOutNeighborSolicits, # of output neighbor solicitations */
|
||||
u_quad_t ifs6_out_neighborsolicit;
|
||||
/* ipv6IfIcmpOutNeighborAdvertisements, # of output neighbor advs. */
|
||||
u_quad_t ifs6_out_neighboradvert;
|
||||
/* ipv6IfIcmpOutRedirects, # of output redirects */
|
||||
u_quad_t ifs6_out_redirect;
|
||||
/* ipv6IfIcmpOutGroupMembQueries, # of output MLD queries */
|
||||
u_quad_t ifs6_out_mldquery;
|
||||
/* ipv6IfIcmpOutGroupMembResponses, # of output MLD reports */
|
||||
u_quad_t ifs6_out_mldreport;
|
||||
/* ipv6IfIcmpOutGroupMembReductions, # of output MLD done */
|
||||
u_quad_t ifs6_out_mlddone;
|
||||
};
|
||||
|
||||
struct in6_ifreq {
|
||||
char ifr_name[IFNAMSIZ];
|
||||
union {
|
||||
struct sockaddr_in6 ifru_addr;
|
||||
struct sockaddr_in6 ifru_dstaddr;
|
||||
int ifru_flags;
|
||||
int ifru_flags6;
|
||||
int ifru_metric;
|
||||
int ifru_intval;
|
||||
caddr_t ifru_data;
|
||||
struct in6_addrlifetime ifru_lifetime;
|
||||
struct in6_ifstat ifru_stat;
|
||||
struct icmp6_ifstat ifru_icmp6stat;
|
||||
u_int32_t ifru_scope_id[SCOPE6_ID_MAX];
|
||||
} ifr_ifru;
|
||||
};
|
||||
|
||||
#define SIOCGIFAFLAG_IN6 _IOWR('i', 73, struct in6_ifreq)
|
||||
|
||||
#define IN6_IFF_ANYCAST 0x0001 /* anycast address */
|
||||
#define IN6_IFF_TENTATIVE 0x0002 /* tentative address */
|
||||
#define IN6_IFF_DUPLICATED 0x0004 /* DAD detected duplicate */
|
||||
#define IN6_IFF_DETACHED 0x0008 /* may be detached from the link */
|
||||
#define IN6_IFF_DEPRECATED 0x0010 /* deprecated address */
|
||||
#define IN6_IFF_TEMPORARY 0x0080 /* temporary (anonymous) address. */
|
||||
|
||||
#endif // WEBRTC_IOS
|
||||
|
||||
namespace rtc {
|
||||
|
||||
namespace {
|
||||
|
||||
class IPv6AttributesGetter {
|
||||
public:
|
||||
IPv6AttributesGetter();
|
||||
virtual ~IPv6AttributesGetter();
|
||||
bool IsInitialized() const;
|
||||
bool GetIPAttributes(const char* ifname,
|
||||
const sockaddr* sock_addr,
|
||||
int* native_attributes);
|
||||
|
||||
private:
|
||||
// on MAC or IOS, we have to use ioctl with a socket to query an IPv6
|
||||
// interface's attribute.
|
||||
int ioctl_socket_;
|
||||
};
|
||||
|
||||
IPv6AttributesGetter::IPv6AttributesGetter()
|
||||
: ioctl_socket_(
|
||||
socket(AF_INET6, SOCK_DGRAM, 0 /* unspecified protocol */)) {
|
||||
RTC_DCHECK_GE(ioctl_socket_, 0);
|
||||
}
|
||||
|
||||
bool IPv6AttributesGetter::IsInitialized() const {
|
||||
return ioctl_socket_ >= 0;
|
||||
}
|
||||
|
||||
IPv6AttributesGetter::~IPv6AttributesGetter() {
|
||||
if (!IsInitialized()) {
|
||||
return;
|
||||
}
|
||||
close(ioctl_socket_);
|
||||
}
|
||||
|
||||
bool IPv6AttributesGetter::GetIPAttributes(const char* ifname,
|
||||
const sockaddr* sock_addr,
|
||||
int* native_attributes) {
|
||||
if (!IsInitialized()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
struct in6_ifreq ifr = {};
|
||||
strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name) - 1);
|
||||
memcpy(&ifr.ifr_ifru.ifru_addr, sock_addr, sock_addr->sa_len);
|
||||
int rv = ioctl(ioctl_socket_, SIOCGIFAFLAG_IN6, &ifr);
|
||||
if (rv >= 0) {
|
||||
*native_attributes = ifr.ifr_ifru.ifru_flags;
|
||||
} else {
|
||||
LOG(LS_ERROR) << "ioctl returns " << errno;
|
||||
}
|
||||
return (rv >= 0);
|
||||
}
|
||||
|
||||
// Converts native IPv6 address attributes to net IPv6 address attributes. If
|
||||
// it returns false, the IP address isn't suitable for one-to-one communications
|
||||
// applications and should be ignored.
|
||||
bool ConvertNativeToIPAttributes(int native_attributes, int* net_attributes) {
|
||||
// For MacOSX, we disallow addresses with attributes IN6_IFF_ANYCASE,
|
||||
// IN6_IFF_DUPLICATED, IN6_IFF_TENTATIVE, and IN6_IFF_DETACHED as these are
|
||||
// still progressing through duplicated address detection (DAD) or are not
|
||||
// suitable for one-to-one communication applications.
|
||||
if (native_attributes & (IN6_IFF_ANYCAST | IN6_IFF_DUPLICATED |
|
||||
IN6_IFF_TENTATIVE | IN6_IFF_DETACHED)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (native_attributes & IN6_IFF_TEMPORARY) {
|
||||
*net_attributes |= IPV6_ADDRESS_FLAG_TEMPORARY;
|
||||
}
|
||||
|
||||
if (native_attributes & IN6_IFF_DEPRECATED) {
|
||||
*net_attributes |= IPV6_ADDRESS_FLAG_DEPRECATED;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
class MacIfAddrsConverter : public IfAddrsConverter {
|
||||
public:
|
||||
MacIfAddrsConverter() : ip_attribute_getter_(new IPv6AttributesGetter()) {}
|
||||
~MacIfAddrsConverter() override {}
|
||||
|
||||
bool ConvertNativeAttributesToIPAttributes(const struct ifaddrs* interface,
|
||||
int* ip_attributes) override {
|
||||
int native_attributes;
|
||||
if (!ip_attribute_getter_->GetIPAttributes(
|
||||
interface->ifa_name, interface->ifa_addr, &native_attributes)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ConvertNativeToIPAttributes(native_attributes, ip_attributes)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
rtc::scoped_ptr<IPv6AttributesGetter> ip_attribute_getter_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
IfAddrsConverter* CreateIfAddrsConverter() {
|
||||
return new MacIfAddrsConverter();
|
||||
}
|
||||
|
||||
} // namespace rtc
|
||||
@ -24,23 +24,13 @@
|
||||
#elif !defined(__native_client__)
|
||||
#include <net/if.h>
|
||||
#endif
|
||||
#include <sys/socket.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#if defined(WEBRTC_ANDROID)
|
||||
#include "webrtc/base/ifaddrs-android.h"
|
||||
#elif !defined(__native_client__)
|
||||
#include <ifaddrs.h>
|
||||
#endif
|
||||
|
||||
#endif // WEBRTC_POSIX
|
||||
|
||||
#if defined(WEBRTC_WIN)
|
||||
#include "webrtc/base/win32.h"
|
||||
#include <Iphlpapi.h>
|
||||
#else
|
||||
#include "webrtc/base/ifaddrs_converter.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
@ -129,7 +119,7 @@ std::string AdapterTypeToString(AdapterType type) {
|
||||
}
|
||||
}
|
||||
|
||||
bool IsIgnoredIPv6(const IPAddress& ip) {
|
||||
bool IsIgnoredIPv6(const InterfaceAddress& ip) {
|
||||
if (ip.family() != AF_INET6) {
|
||||
return false;
|
||||
}
|
||||
@ -146,6 +136,11 @@ bool IsIgnoredIPv6(const IPAddress& ip) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Ignore deprecated IPv6.
|
||||
if (ip.ipv6_flags() & IPV6_ADDRESS_FLAG_DEPRECATED) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -393,49 +388,47 @@ bool BasicNetworkManager::CreateNetworks(bool include_ignored,
|
||||
|
||||
#elif defined(WEBRTC_POSIX)
|
||||
void BasicNetworkManager::ConvertIfAddrs(struct ifaddrs* interfaces,
|
||||
IfAddrsConverter* ifaddrs_converter,
|
||||
bool include_ignored,
|
||||
NetworkList* networks) const {
|
||||
NetworkMap current_networks;
|
||||
|
||||
for (struct ifaddrs* cursor = interfaces;
|
||||
cursor != NULL; cursor = cursor->ifa_next) {
|
||||
IPAddress prefix;
|
||||
IPAddress mask;
|
||||
IPAddress ip;
|
||||
InterfaceAddress ip;
|
||||
int scope_id = 0;
|
||||
|
||||
// Some interfaces may not have address assigned.
|
||||
if (!cursor->ifa_addr || !cursor->ifa_netmask)
|
||||
if (!cursor->ifa_addr || !cursor->ifa_netmask) {
|
||||
continue;
|
||||
}
|
||||
// Skip ones which are down.
|
||||
if (!(cursor->ifa_flags & IFF_RUNNING)) {
|
||||
continue;
|
||||
}
|
||||
// Skip unknown family.
|
||||
if (cursor->ifa_addr->sa_family != AF_INET &&
|
||||
cursor->ifa_addr->sa_family != AF_INET6) {
|
||||
continue;
|
||||
}
|
||||
// Skip IPv6 if not enabled.
|
||||
if (cursor->ifa_addr->sa_family == AF_INET6 && !ipv6_enabled()) {
|
||||
continue;
|
||||
}
|
||||
// Convert to InterfaceAddress.
|
||||
if (!ifaddrs_converter->ConvertIfAddrsToIPAddress(cursor, &ip, &mask)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (cursor->ifa_addr->sa_family) {
|
||||
case AF_INET: {
|
||||
ip = IPAddress(
|
||||
reinterpret_cast<sockaddr_in*>(cursor->ifa_addr)->sin_addr);
|
||||
mask = IPAddress(
|
||||
reinterpret_cast<sockaddr_in*>(cursor->ifa_netmask)->sin_addr);
|
||||
break;
|
||||
}
|
||||
case AF_INET6: {
|
||||
if (ipv6_enabled()) {
|
||||
ip = IPAddress(
|
||||
reinterpret_cast<sockaddr_in6*>(cursor->ifa_addr)->sin6_addr);
|
||||
|
||||
if (IsIgnoredIPv6(ip)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
mask = IPAddress(
|
||||
reinterpret_cast<sockaddr_in6*>(cursor->ifa_netmask)->sin6_addr);
|
||||
scope_id =
|
||||
reinterpret_cast<sockaddr_in6*>(cursor->ifa_addr)->sin6_scope_id;
|
||||
break;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
default: {
|
||||
// Special case for IPv6 address.
|
||||
if (cursor->ifa_addr->sa_family == AF_INET6) {
|
||||
if (IsIgnoredIPv6(ip)) {
|
||||
continue;
|
||||
}
|
||||
scope_id =
|
||||
reinterpret_cast<sockaddr_in6*>(cursor->ifa_addr)->sin6_scope_id;
|
||||
}
|
||||
|
||||
int prefix_length = CountIPMaskBits(mask);
|
||||
@ -481,7 +474,9 @@ bool BasicNetworkManager::CreateNetworks(bool include_ignored,
|
||||
return false;
|
||||
}
|
||||
|
||||
ConvertIfAddrs(interfaces, include_ignored, networks);
|
||||
rtc::scoped_ptr<IfAddrsConverter> ifaddrs_converter(CreateIfAddrsConverter());
|
||||
ConvertIfAddrs(interfaces, ifaddrs_converter.get(), include_ignored,
|
||||
networks);
|
||||
|
||||
freeifaddrs(interfaces);
|
||||
return true;
|
||||
|
||||
@ -31,6 +31,7 @@ namespace rtc {
|
||||
extern const char kPublicIPv4Host[];
|
||||
extern const char kPublicIPv6Host[];
|
||||
|
||||
class IfAddrsConverter;
|
||||
class Network;
|
||||
class NetworkMonitorInterface;
|
||||
class Thread;
|
||||
@ -229,6 +230,7 @@ class BasicNetworkManager : public NetworkManagerBase,
|
||||
#if defined(WEBRTC_POSIX)
|
||||
// Separated from CreateNetworks for tests.
|
||||
void ConvertIfAddrs(ifaddrs* interfaces,
|
||||
IfAddrsConverter* converter,
|
||||
bool include_ignored,
|
||||
NetworkList* networks) const;
|
||||
#endif // defined(WEBRTC_POSIX)
|
||||
|
||||
@ -15,12 +15,9 @@
|
||||
#include <vector>
|
||||
#if defined(WEBRTC_POSIX)
|
||||
#include <sys/types.h>
|
||||
#if !defined(WEBRTC_ANDROID)
|
||||
#include <ifaddrs.h>
|
||||
#else
|
||||
#include "webrtc/base/ifaddrs-android.h"
|
||||
#endif
|
||||
#endif
|
||||
#include <net/if.h>
|
||||
#include "webrtc/base/ifaddrs_converter.h"
|
||||
#endif // defined(WEBRTC_POSIX)
|
||||
#include "webrtc/base/gunit.h"
|
||||
#if defined(WEBRTC_WIN)
|
||||
#include "webrtc/base/logging.h" // For LOG_GLE
|
||||
@ -28,6 +25,8 @@
|
||||
|
||||
namespace rtc {
|
||||
|
||||
namespace {
|
||||
|
||||
class FakeNetworkMonitor : public NetworkMonitorBase {
|
||||
public:
|
||||
void Start() override {}
|
||||
@ -42,6 +41,8 @@ class FakeNetworkMonitorFactory : public NetworkMonitorFactory {
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
class NetworkTest : public testing::Test, public sigslot::has_slots<> {
|
||||
public:
|
||||
NetworkTest() : callback_called_(false) {}
|
||||
@ -89,7 +90,10 @@ class NetworkTest : public testing::Test, public sigslot::has_slots<> {
|
||||
struct ifaddrs* interfaces,
|
||||
bool include_ignored,
|
||||
NetworkManager::NetworkList* networks) {
|
||||
network_manager.ConvertIfAddrs(interfaces, include_ignored, networks);
|
||||
// Use the base IfAddrsConverter for test cases.
|
||||
rtc::scoped_ptr<IfAddrsConverter> ifaddrs_converter(new IfAddrsConverter());
|
||||
network_manager.ConvertIfAddrs(interfaces, ifaddrs_converter.get(),
|
||||
include_ignored, networks);
|
||||
}
|
||||
|
||||
struct sockaddr_in6* CreateIpv6Addr(const std::string& ip_string,
|
||||
@ -118,6 +122,7 @@ class NetworkTest : public testing::Test, public sigslot::has_slots<> {
|
||||
if_addr->ifa_netmask =
|
||||
reinterpret_cast<struct sockaddr*>(CreateIpv6Addr(ipv6_netmask, 0));
|
||||
if_addr->ifa_next = list;
|
||||
if_addr->ifa_flags = IFF_RUNNING;
|
||||
return if_addr;
|
||||
}
|
||||
|
||||
@ -762,6 +767,21 @@ TEST_F(NetworkTest, TestConvertIfAddrsMultiAddressesOnOneInterface) {
|
||||
MergeNetworkList(manager, result, &changed);
|
||||
ReleaseIfAddrs(list);
|
||||
}
|
||||
|
||||
TEST_F(NetworkTest, TestConvertIfAddrsNotRunning) {
|
||||
ifaddrs list;
|
||||
memset(&list, 0, sizeof(list));
|
||||
list.ifa_name = const_cast<char*>("test_iface");
|
||||
sockaddr ifa_addr;
|
||||
sockaddr ifa_netmask;
|
||||
list.ifa_addr = &ifa_addr;
|
||||
list.ifa_netmask = &ifa_netmask;
|
||||
|
||||
NetworkManager::NetworkList result;
|
||||
BasicNetworkManager manager;
|
||||
CallConvertIfAddrs(manager, &list, true, &result);
|
||||
EXPECT_TRUE(result.empty());
|
||||
}
|
||||
#endif // defined(WEBRTC_POSIX)
|
||||
|
||||
#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
|
||||
|
||||
Reference in New Issue
Block a user