Chromium Code Reviews| Index: webrtc/base/network.cc |
| diff --git a/webrtc/base/network.cc b/webrtc/base/network.cc |
| index 879c1e4529d9f560e0b550795dc7f4826a5ae9d1..b800cf085a5abd590701270ac10f13890fb27657 100644 |
| --- a/webrtc/base/network.cc |
| +++ b/webrtc/base/network.cc |
| @@ -151,6 +151,12 @@ bool IsIgnoredIPv6(const IPAddress& ip) { |
| } // namespace |
| +// These addresses are used as the targets to find out the default local address |
| +// on a multi-homed endpoint. They are actually DNS servers. |
| +const char kPublicIPv4Host[] = "8.8.8.8"; |
| +const char kPublicIPv6Host[] = "2001:4860:4860::8888"; |
| +const int kPublicPort = 53; // DNS port. |
| + |
| std::string MakeNetworkKey(const std::string& name, const IPAddress& prefix, |
| int prefix_length) { |
| std::ostringstream ost; |
| @@ -169,6 +175,10 @@ NetworkManager::EnumerationPermission NetworkManager::enumeration_permission() |
| return ENUMERATION_ALLOWED; |
| } |
| +bool NetworkManager::GetDefaultLocalAddress(int family, IPAddress* addr) const { |
| + return false; |
| +} |
| + |
| NetworkManagerBase::NetworkManagerBase() |
| : enumeration_permission_(NetworkManager::ENUMERATION_ALLOWED), |
| max_ipv6_networks_(kMaxIPv6Networks), |
| @@ -191,6 +201,7 @@ void NetworkManagerBase::GetAnyAddressNetworks(NetworkList* networks) { |
| const rtc::IPAddress ipv4_any_address(INADDR_ANY); |
| ipv4_any_address_network_.reset( |
| new rtc::Network("any", "any", ipv4_any_address, 0)); |
| + ipv4_any_address_network_->set_default_address_provider(this); |
|
pthatcher1
2015/11/10 18:52:34
Why not just set the provider at the very beginnin
guoweis_webrtc
2015/11/10 20:37:29
Because chromium code calls the constructor as wel
|
| ipv4_any_address_network_->AddIP(ipv4_any_address); |
| } |
| networks->push_back(ipv4_any_address_network_.get()); |
| @@ -200,6 +211,7 @@ void NetworkManagerBase::GetAnyAddressNetworks(NetworkList* networks) { |
| const rtc::IPAddress ipv6_any_address(in6addr_any); |
| ipv6_any_address_network_.reset( |
| new rtc::Network("any", "any", ipv6_any_address, 0)); |
| + ipv6_any_address_network_->set_default_address_provider(this); |
| ipv6_any_address_network_->AddIP(ipv6_any_address); |
| } |
| networks->push_back(ipv6_any_address_network_.get()); |
| @@ -321,6 +333,26 @@ void NetworkManagerBase::MergeNetworkList(const NetworkList& new_networks, |
| } |
| } |
| +void NetworkManagerBase::set_default_local_address(const IPAddress& ip) { |
| + if (ip.family() == AF_INET) { |
| + default_ipv4_address_ = ip; |
| + } else if (ip.family() == AF_INET6) { |
| + default_ipv6_address_ = ip; |
| + } |
| +} |
| + |
| +bool NetworkManagerBase::GetDefaultLocalAddress(int family, |
| + IPAddress* ipaddr) const { |
| + if (family == AF_INET) { |
| + *ipaddr = default_ipv4_address_; |
| + return true; |
| + } else if (family == AF_INET6) { |
| + *ipaddr = default_ipv6_address_; |
| + return true; |
| + } |
| + return false; |
| +} |
| + |
| BasicNetworkManager::BasicNetworkManager() |
| : thread_(NULL), sent_first_update_(false), start_count_(0), |
| network_ignore_mask_(kDefaultNetworkIgnoreMask), |
| @@ -409,10 +441,9 @@ void BasicNetworkManager::ConvertIfAddrs(struct ifaddrs* interfaces, |
| #endif |
| // TODO(phoglund): Need to recognize other types as well. |
| scoped_ptr<Network> network(new Network(cursor->ifa_name, |
| - cursor->ifa_name, |
| - prefix, |
| - prefix_length, |
| - adapter_type)); |
| + cursor->ifa_name, prefix, |
| + prefix_length, adapter_type)); |
| + network->set_default_address_provider(this); |
| network->set_scope_id(scope_id); |
| network->AddIP(ip); |
| network->set_ignored(IsIgnoredNetwork(*network)); |
| @@ -563,11 +594,9 @@ bool BasicNetworkManager::CreateNetworks(bool include_ignored, |
| // TODO(phoglund): Need to recognize other types as well. |
| adapter_type = ADAPTER_TYPE_LOOPBACK; |
| } |
| - scoped_ptr<Network> network(new Network(name, |
| - description, |
| - prefix, |
| - prefix_length, |
| - adapter_type)); |
| + scoped_ptr<Network> network(new Network(name, description, prefix, |
| + prefix_length, adapter_type)); |
| + network->set_default_address_provider(this); |
| network->set_scope_id(scope_id); |
| network->AddIP(ip); |
| bool ignored = IsIgnoredNetwork(*network); |
| @@ -724,6 +753,23 @@ void BasicNetworkManager::OnMessage(Message* msg) { |
| } |
| } |
| +IPAddress BasicNetworkManager::QueryDefaultAddress(int family) const { |
| + ASSERT(thread_ == Thread::Current()); |
| + ASSERT(thread_->socketserver() != nullptr); |
| + ASSERT(family == AF_INET || family == AF_INET6); |
| + |
| + scoped_ptr<AsyncSocket> socket( |
| + thread_->socketserver()->CreateAsyncSocket(family, SOCK_DGRAM)); |
| + if (socket && |
| + socket->Connect( |
| + SocketAddress(family == AF_INET ? kPublicIPv4Host : kPublicIPv6Host, |
| + kPublicPort)) == 0) { |
| + return socket->GetLocalAddress().ipaddr(); |
| + } |
|
pthatcher1
2015/11/10 18:52:34
It might be more clear as:
if (!socket) {
retur
guoweis_webrtc
2015/11/10 20:37:29
Done.
|
| + |
| + return IPAddress(); |
| +} |
| + |
| void BasicNetworkManager::UpdateNetworksOnce() { |
| if (!start_count_) |
| return; |
| @@ -735,7 +781,14 @@ void BasicNetworkManager::UpdateNetworksOnce() { |
| SignalError(); |
| } else { |
| bool changed; |
| - MergeNetworkList(list, &changed); |
| + NetworkManager::Stats stats; |
| + MergeNetworkList(list, &changed, &stats); |
| + if (stats.ipv6_network_count) { |
| + set_default_local_address(QueryDefaultAddress(AF_INET6)); |
|
pthatcher1
2015/11/10 18:52:34
Why bother checking the stats? Why not just query
guoweis_webrtc
2015/11/10 20:37:29
If there is no ipv6 address at all, there is no po
|
| + } |
| + if (stats.ipv4_network_count) { |
| + set_default_local_address(QueryDefaultAddress(AF_INET)); |
| + } |
| if (changed || !sent_first_update_) { |
| SignalNetworksChanged(); |
| sent_first_update_ = true; |
| @@ -766,21 +819,34 @@ void BasicNetworkManager::DumpNetworks(bool include_ignored) { |
| } |
| } |
| -Network::Network(const std::string& name, const std::string& desc, |
| - const IPAddress& prefix, int prefix_length) |
| - : name_(name), description_(desc), prefix_(prefix), |
| +Network::Network(const std::string& name, |
| + const std::string& desc, |
| + const IPAddress& prefix, |
| + int prefix_length) |
| + : name_(name), |
| + description_(desc), |
| + prefix_(prefix), |
| prefix_length_(prefix_length), |
| - key_(MakeNetworkKey(name, prefix, prefix_length)), scope_id_(0), |
| - ignored_(false), type_(ADAPTER_TYPE_UNKNOWN), preference_(0) { |
| -} |
| - |
| -Network::Network(const std::string& name, const std::string& desc, |
| - const IPAddress& prefix, int prefix_length, AdapterType type) |
| - : name_(name), description_(desc), prefix_(prefix), |
| + key_(MakeNetworkKey(name, prefix, prefix_length)), |
| + scope_id_(0), |
| + ignored_(false), |
| + type_(ADAPTER_TYPE_UNKNOWN), |
| + preference_(0) {} |
| + |
| +Network::Network(const std::string& name, |
| + const std::string& desc, |
| + const IPAddress& prefix, |
| + int prefix_length, |
| + AdapterType type) |
| + : name_(name), |
| + description_(desc), |
| + prefix_(prefix), |
| prefix_length_(prefix_length), |
| - key_(MakeNetworkKey(name, prefix, prefix_length)), scope_id_(0), |
| - ignored_(false), type_(type), preference_(0) { |
| -} |
| + key_(MakeNetworkKey(name, prefix, prefix_length)), |
| + scope_id_(0), |
| + ignored_(false), |
| + type_(type), |
| + preference_(0) {} |
| Network::~Network() = default; |