Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(419)

Side by Side Diff: webrtc/base/network.cc

Issue 1421433003: Fix CreateNetworks to stop it from signaling duplicate networks changed events (Closed) Base URL: https://chromium.googlesource.com/external/webrtc@master
Patch Set: Fix the other half of the bug in network manager Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 223
224 void NetworkManagerBase::MergeNetworkList(const NetworkList& new_networks, 224 void NetworkManagerBase::MergeNetworkList(const NetworkList& new_networks,
225 bool* changed) { 225 bool* changed) {
226 NetworkManager::Stats stats; 226 NetworkManager::Stats stats;
227 MergeNetworkList(new_networks, changed, &stats); 227 MergeNetworkList(new_networks, changed, &stats);
228 } 228 }
229 229
230 void NetworkManagerBase::MergeNetworkList(const NetworkList& new_networks, 230 void NetworkManagerBase::MergeNetworkList(const NetworkList& new_networks,
231 bool* changed, 231 bool* changed,
232 NetworkManager::Stats* stats) { 232 NetworkManager::Stats* stats) {
233 *changed = false;
233 // AddressList in this map will track IP addresses for all Networks 234 // AddressList in this map will track IP addresses for all Networks
234 // with the same key. 235 // with the same key.
235 std::map<std::string, AddressList> consolidated_address_list; 236 std::map<std::string, AddressList> consolidated_address_list;
236 NetworkList list(new_networks); 237 NetworkList list(new_networks);
237
238 // Result of Network merge. Element in this list should have unique key.
239 NetworkList merged_list;
240 std::sort(list.begin(), list.end(), CompareNetworks); 238 std::sort(list.begin(), list.end(), CompareNetworks);
241
242 *changed = false;
243
244 if (networks_.size() != list.size())
245 *changed = true;
246
247 // First, build a set of network-keys to the ipaddresses. 239 // First, build a set of network-keys to the ipaddresses.
248 for (Network* network : list) { 240 for (Network* network : list) {
249 bool might_add_to_merged_list = false; 241 bool might_add_to_merged_list = false;
250 std::string key = MakeNetworkKey(network->name(), 242 std::string key = MakeNetworkKey(network->name(),
251 network->prefix(), 243 network->prefix(),
252 network->prefix_length()); 244 network->prefix_length());
253 if (consolidated_address_list.find(key) == 245 if (consolidated_address_list.find(key) ==
254 consolidated_address_list.end()) { 246 consolidated_address_list.end()) {
255 AddressList addrlist; 247 AddressList addrlist;
256 addrlist.net = network; 248 addrlist.net = network;
(...skipping 11 matching lines...) Expand all
268 if (current_list.ips[0].family() == AF_INET) { 260 if (current_list.ips[0].family() == AF_INET) {
269 stats->ipv4_network_count++; 261 stats->ipv4_network_count++;
270 } else { 262 } else {
271 ASSERT(current_list.ips[0].family() == AF_INET6); 263 ASSERT(current_list.ips[0].family() == AF_INET6);
272 stats->ipv6_network_count++; 264 stats->ipv6_network_count++;
273 } 265 }
274 } 266 }
275 } 267 }
276 268
277 // Next, look for existing network objects to re-use. 269 // Next, look for existing network objects to re-use.
270 // Result of Network merge. Element in this list should have unique key.
271 NetworkList merged_list;
278 for (const auto& kv : consolidated_address_list) { 272 for (const auto& kv : consolidated_address_list) {
279 const std::string& key = kv.first; 273 const std::string& key = kv.first;
280 Network* net = kv.second.net; 274 Network* net = kv.second.net;
281 auto existing = networks_map_.find(key); 275 auto existing = networks_map_.find(key);
282 if (existing == networks_map_.end()) { 276 if (existing == networks_map_.end()) {
283 // This network is new. Place it in the network map. 277 // This network is new. Place it in the network map.
284 merged_list.push_back(net); 278 merged_list.push_back(net);
285 networks_map_[key] = net; 279 networks_map_[key] = net;
286 // Also, we might have accumulated IPAddresses from the first 280 // Also, we might have accumulated IPAddresses from the first
287 // step, set it here. 281 // step, set it here.
288 net->SetIPs(kv.second.ips, true); 282 net->SetIPs(kv.second.ips, true);
289 *changed = true; 283 *changed = true;
290 } else { 284 } else {
291 // This network exists in the map already. Reset its IP addresses. 285 // This network exists in the map already. Reset its IP addresses.
292 *changed = existing->second->SetIPs(kv.second.ips, *changed); 286 Network* existing_net = existing->second;
293 merged_list.push_back(existing->second); 287 *changed = existing_net->SetIPs(kv.second.ips, *changed);
294 if (existing->second != net) { 288 merged_list.push_back(existing_net);
289 if (existing_net != net) {
295 delete net; 290 delete net;
296 } 291 }
292 // If the existing network was not active, networks have changed.
293 if (!existing_net->active()) {
294 *changed = true;
295 }
pthatcher1 2015/12/08 19:40:23 Is kv.second.active() always true? If not, should
honghaiz3 2015/12/10 19:26:18 It should be always active because active_ is true
297 } 296 }
298 } 297 }
299 networks_ = merged_list; 298 // It may still happen that the merged list is a subset of |networks_|.
299 // To detect this change, we compare their sizes.
300 if (merged_list.size() != networks_.size()) {
301 *changed = true;
302 }
300 303
301 // If the network lists changes, we resort it. 304 // If the network list changes, we re-assign and resort it.
pthatcher1 2015/12/08 19:40:23 By re-assign you mean reset the active state? If
honghaiz3 2015/12/10 19:26:18 I meant re-assign networks_ to the merged list. Ch
302 if (*changed) { 305 if (*changed) {
306 networks_ = merged_list;
307 // Reset the active states of all networks.
308 for (const auto& kv : networks_map_) {
309 kv.second->set_active(false);
pthatcher1 2015/12/08 19:40:23 So, we leave it in the map even if it's not active
honghaiz3 2015/12/10 19:26:18 Yes. Previously it keeps all networks in the map
310 }
311 for (Network* network : networks_) {
312 network->set_active(true);
313 }
303 std::sort(networks_.begin(), networks_.end(), SortNetworks); 314 std::sort(networks_.begin(), networks_.end(), SortNetworks);
304 // Now network interfaces are sorted, we should set the preference value 315 // Now network interfaces are sorted, we should set the preference value
305 // for each of the interfaces we are planning to use. 316 // for each of the interfaces we are planning to use.
306 // Preference order of network interfaces might have changed from previous 317 // Preference order of network interfaces might have changed from previous
307 // sorting due to addition of higher preference network interface. 318 // sorting due to addition of higher preference network interface.
308 // Since we have already sorted the network interfaces based on our 319 // Since we have already sorted the network interfaces based on our
309 // requirements, we will just assign a preference value starting with 127, 320 // requirements, we will just assign a preference value starting with 127,
310 // in decreasing order. 321 // in decreasing order.
311 int pref = kHighestNetworkPreference; 322 int pref = kHighestNetworkPreference;
312 for (Network* network : networks_) { 323 for (Network* network : networks_) {
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
410 // TODO(phoglund): Need to recognize other types as well. 421 // TODO(phoglund): Need to recognize other types as well.
411 scoped_ptr<Network> network(new Network(cursor->ifa_name, 422 scoped_ptr<Network> network(new Network(cursor->ifa_name,
412 cursor->ifa_name, 423 cursor->ifa_name,
413 prefix, 424 prefix,
414 prefix_length, 425 prefix_length,
415 adapter_type)); 426 adapter_type));
416 network->set_scope_id(scope_id); 427 network->set_scope_id(scope_id);
417 network->AddIP(ip); 428 network->AddIP(ip);
418 network->set_ignored(IsIgnoredNetwork(*network)); 429 network->set_ignored(IsIgnoredNetwork(*network));
419 if (include_ignored || !network->ignored()) { 430 if (include_ignored || !network->ignored()) {
431 current_networks[key] = network.get();
pthatcher1 2015/12/08 19:40:23 Can you explain why this is necessary, here and be
honghaiz3 2015/12/10 19:26:18 If you look at the if condition one-level outside,
420 networks->push_back(network.release()); 432 networks->push_back(network.release());
421 } 433 }
422 } else { 434 } else {
423 (*existing_network).second->AddIP(ip); 435 (*existing_network).second->AddIP(ip);
424 } 436 }
425 } 437 }
426 } 438 }
427 439
428 bool BasicNetworkManager::CreateNetworks(bool include_ignored, 440 bool BasicNetworkManager::CreateNetworks(bool include_ignored,
429 NetworkList* networks) const { 441 NetworkList* networks) const {
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
566 scoped_ptr<Network> network(new Network(name, 578 scoped_ptr<Network> network(new Network(name,
567 description, 579 description,
568 prefix, 580 prefix,
569 prefix_length, 581 prefix_length,
570 adapter_type)); 582 adapter_type));
571 network->set_scope_id(scope_id); 583 network->set_scope_id(scope_id);
572 network->AddIP(ip); 584 network->AddIP(ip);
573 bool ignored = IsIgnoredNetwork(*network); 585 bool ignored = IsIgnoredNetwork(*network);
574 network->set_ignored(ignored); 586 network->set_ignored(ignored);
575 if (include_ignored || !network->ignored()) { 587 if (include_ignored || !network->ignored()) {
588 current_networks[key] = network.get();
576 networks->push_back(network.release()); 589 networks->push_back(network.release());
577 } 590 }
578 } else { 591 } else {
579 (*existing_network).second->AddIP(ip); 592 (*existing_network).second->AddIP(ip);
580 } 593 }
581 } 594 }
582 // Count is per-adapter - all 'Networks' created from the same 595 // Count is per-adapter - all 'Networks' created from the same
583 // adapter need to have the same name. 596 // adapter need to have the same name.
584 ++count; 597 ++count;
585 } 598 }
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
741 sent_first_update_ = true; 754 sent_first_update_ = true;
742 } 755 }
743 } 756 }
744 } 757 }
745 758
746 void BasicNetworkManager::UpdateNetworksContinually() { 759 void BasicNetworkManager::UpdateNetworksContinually() {
747 UpdateNetworksOnce(); 760 UpdateNetworksOnce();
748 thread_->PostDelayed(kNetworksUpdateIntervalMs, this, kUpdateNetworksMessage); 761 thread_->PostDelayed(kNetworksUpdateIntervalMs, this, kUpdateNetworksMessage);
749 } 762 }
750 763
751 void BasicNetworkManager::DumpNetworks(bool include_ignored) { 764 void BasicNetworkManager::DumpNetworks() {
752 NetworkList list; 765 NetworkList list;
753 CreateNetworks(include_ignored, &list); 766 GetNetworks(&list);
754 LOG(LS_INFO) << "NetworkManager detected " << list.size() << " networks:"; 767 LOG(LS_INFO) << "NetworkManager detected " << list.size() << " networks:";
755 for (const Network* network : list) { 768 for (const Network* network : list) {
756 if (!network->ignored() || include_ignored) { 769 LOG(LS_INFO) << network->ToString() << ": " << network->description()
757 LOG(LS_INFO) << network->ToString() << ": " 770 << ", active ? " << network->active()
758 << network->description() 771 << ((network->ignored()) ? ", Ignored" : "");
759 << ((network->ignored()) ? ", Ignored" : "");
760 }
761 }
762 // Release the network list created previously.
763 // Do this in a seperated for loop for better readability.
764 for (Network* network : list) {
765 delete network;
766 } 772 }
767 } 773 }
768 774
769 Network::Network(const std::string& name, const std::string& desc, 775 Network::Network(const std::string& name, const std::string& desc,
770 const IPAddress& prefix, int prefix_length) 776 const IPAddress& prefix, int prefix_length)
771 : name_(name), description_(desc), prefix_(prefix), 777 : name_(name), description_(desc), prefix_(prefix),
772 prefix_length_(prefix_length), 778 prefix_length_(prefix_length),
773 key_(MakeNetworkKey(name, prefix, prefix_length)), scope_id_(0), 779 key_(MakeNetworkKey(name, prefix, prefix_length)), scope_id_(0),
774 ignored_(false), type_(ADAPTER_TYPE_UNKNOWN), preference_(0) { 780 ignored_(false), type_(ADAPTER_TYPE_UNKNOWN), preference_(0) {
775 } 781 }
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
845 std::stringstream ss; 851 std::stringstream ss;
846 // Print out the first space-terminated token of the network desc, plus 852 // Print out the first space-terminated token of the network desc, plus
847 // the IP address. 853 // the IP address.
848 ss << "Net[" << description_.substr(0, description_.find(' ')) 854 ss << "Net[" << description_.substr(0, description_.find(' '))
849 << ":" << prefix_.ToSensitiveString() << "/" << prefix_length_ 855 << ":" << prefix_.ToSensitiveString() << "/" << prefix_length_
850 << ":" << AdapterTypeToString(type_) << "]"; 856 << ":" << AdapterTypeToString(type_) << "]";
851 return ss.str(); 857 return ss.str();
852 } 858 }
853 859
854 } // namespace rtc 860 } // namespace rtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698