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

Side by Side Diff: webrtc/p2p/client/basicportallocator.cc

Issue 2025573002: Use continual gathering to restore backup connections (Closed) Base URL: https://chromium.googlesource.com/external/webrtc@master
Patch Set: Merge branch 'master' into enhanced_cg Created 4 years, 5 months 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 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 network_thread_->Post(RTC_FROM_HERE, this, MSG_CONFIG_STOP); 208 network_thread_->Post(RTC_FROM_HERE, this, MSG_CONFIG_STOP);
209 ClearGettingPorts(); 209 ClearGettingPorts();
210 } 210 }
211 211
212 void BasicPortAllocatorSession::ClearGettingPorts() { 212 void BasicPortAllocatorSession::ClearGettingPorts() {
213 network_thread_->Clear(this, MSG_ALLOCATE); 213 network_thread_->Clear(this, MSG_ALLOCATE);
214 for (uint32_t i = 0; i < sequences_.size(); ++i) 214 for (uint32_t i = 0; i < sequences_.size(); ++i)
215 sequences_[i]->Stop(); 215 sequences_[i]->Stop();
216 } 216 }
217 217
218 std::vector<rtc::Network*> BasicPortAllocatorSession::GetFailedNetworks() {
219 std::vector<rtc::Network*> networks = GetNetworks();
220
221 // A network interface may have both Ipv4 and IPv6 networks. Only if
pthatcher1 2016/06/29 18:53:27 Ipv or IPv? Please be consistent.
honghaiz3 2016/06/29 20:19:22 Done.
222 // neither of the networks has any connections, the network interface
223 // is considered failed and need to be regathered on.
224 std::map<std::string, bool> network_has_connection;
pthatcher1 2016/06/29 18:53:27 Wouldn't a std::set work? Then just check if it's
honghaiz3 2016/06/29 20:19:22 Done.
225 for (const PortData& data : ports_) {
226 Port* port = data.port();
227 if (!port->connections().empty()) {
228 network_has_connection[port->Network()->name()] = true;
229 }
230 }
231
232 networks.erase(
233 std::remove_if(networks.begin(), networks.end(),
234 [network_has_connection](rtc::Network* network) {
235 // If a network does not have any connection, it is
236 // considered failed.
237 auto iter = network_has_connection.find(network->name());
238 return iter != network_has_connection.end() &&
239 iter->second;
240 }),
241 networks.end());
242 return networks;
243 }
244
245 void BasicPortAllocatorSession::RegatherOnFailedNetworks() {
246 // Find the list of networks that have no connection.
247 std::vector<rtc::Network*> failed_networks = GetFailedNetworks();
248 if (failed_networks.empty()) {
249 return;
250 }
251
252 // Mark a sequence as "network failed" if its network in the list of failed
253 // networks, so that it won't be considered as equivalent when the session
254 // regathers ports and candidates.
255 for (AllocationSequence* sequence : sequences_) {
256 if (!sequence->network_failed() &&
257 std::find(failed_networks.begin(), failed_networks.end(),
258 sequence->network()) != failed_networks.end()) {
259 sequence->set_network_failed();
260 }
261 }
262 // Remove ports from being used locally and send signaling to remove
263 // the candidates on the remote side.
264 RemovePortsAndCandidates(failed_networks);
265
266 if (allocation_started_ && network_manager_started_) {
267 DoAllocate();
268 }
269 }
270
218 std::vector<PortInterface*> BasicPortAllocatorSession::ReadyPorts() const { 271 std::vector<PortInterface*> BasicPortAllocatorSession::ReadyPorts() const {
219 std::vector<PortInterface*> ret; 272 std::vector<PortInterface*> ret;
220 for (const PortData& port : ports_) { 273 for (const PortData& port : ports_) {
221 if (port.has_pairable_candidate() && !port.error()) { 274 if (port.has_pairable_candidate() && !port.error()) {
222 ret.push_back(port.port()); 275 ret.push_back(port.port());
223 } 276 }
224 } 277 }
225 return ret; 278 return ret;
226 } 279 }
227 280
228 std::vector<Candidate> BasicPortAllocatorSession::ReadyCandidates() const { 281 std::vector<Candidate> BasicPortAllocatorSession::ReadyCandidates() const {
229 std::vector<Candidate> candidates; 282 std::vector<Candidate> candidates;
230 for (const PortData& data : ports_) { 283 for (const PortData& data : ports_) {
231 for (const Candidate& candidate : data.port()->Candidates()) { 284 GetCandidatesFromPort(data, &candidates);
232 if (!CheckCandidateFilter(candidate)) {
233 continue;
234 }
235 ProtocolType pvalue;
236 if (!StringToProto(candidate.protocol().c_str(), &pvalue) ||
237 !data.sequence()->ProtocolEnabled(pvalue)) {
238 continue;
239 }
240 candidates.push_back(SanitizeRelatedAddress(candidate));
241 }
242 } 285 }
243 return candidates; 286 return candidates;
244 } 287 }
245 288
289 void BasicPortAllocatorSession::GetCandidatesFromPort(
290 const PortData& data,
291 std::vector<Candidate>* candidates) const {
292 RTC_CHECK(candidates != nullptr);
293 for (const Candidate& candidate : data.port()->Candidates()) {
294 if (!CheckCandidateFilter(candidate)) {
295 continue;
296 }
297 ProtocolType pvalue;
298 if (!StringToProto(candidate.protocol().c_str(), &pvalue) ||
299 !data.sequence()->ProtocolEnabled(pvalue)) {
300 continue;
301 }
302 candidates->push_back(SanitizeRelatedAddress(candidate));
303 }
304 }
305
246 Candidate BasicPortAllocatorSession::SanitizeRelatedAddress( 306 Candidate BasicPortAllocatorSession::SanitizeRelatedAddress(
247 const Candidate& c) const { 307 const Candidate& c) const {
248 Candidate copy = c; 308 Candidate copy = c;
249 // If adapter enumeration is disabled or host candidates are disabled, 309 // If adapter enumeration is disabled or host candidates are disabled,
250 // clear the raddr of STUN candidates to avoid local address leakage. 310 // clear the raddr of STUN candidates to avoid local address leakage.
251 bool filter_stun_related_address = 311 bool filter_stun_related_address =
252 ((flags() & PORTALLOCATOR_DISABLE_ADAPTER_ENUMERATION) && 312 ((flags() & PORTALLOCATOR_DISABLE_ADAPTER_ENUMERATION) &&
253 (flags() & PORTALLOCATOR_DISABLE_DEFAULT_LOCAL_CANDIDATE)) || 313 (flags() & PORTALLOCATOR_DISABLE_DEFAULT_LOCAL_CANDIDATE)) ||
254 !(candidate_filter_ & CF_HOST); 314 !(candidate_filter_ & CF_HOST);
255 // If the candidate filter doesn't allow reflexive addresses, empty TURN raddr 315 // If the candidate filter doesn't allow reflexive addresses, empty TURN raddr
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
384 network_thread_->Post(RTC_FROM_HERE, this, MSG_ALLOCATE); 444 network_thread_->Post(RTC_FROM_HERE, this, MSG_ALLOCATE);
385 } 445 }
386 446
387 void BasicPortAllocatorSession::OnAllocate() { 447 void BasicPortAllocatorSession::OnAllocate() {
388 if (network_manager_started_) 448 if (network_manager_started_)
389 DoAllocate(); 449 DoAllocate();
390 450
391 allocation_started_ = true; 451 allocation_started_ = true;
392 } 452 }
393 453
394 void BasicPortAllocatorSession::GetNetworks( 454 std::vector<rtc::Network*> BasicPortAllocatorSession::GetNetworks() {
395 std::vector<rtc::Network*>* networks) { 455 std::vector<rtc::Network*> networks;
396 networks->clear();
397 rtc::NetworkManager* network_manager = allocator_->network_manager(); 456 rtc::NetworkManager* network_manager = allocator_->network_manager();
398 ASSERT(network_manager != nullptr); 457 ASSERT(network_manager != nullptr);
399 // If the network permission state is BLOCKED, we just act as if the flag has 458 // If the network permission state is BLOCKED, we just act as if the flag has
400 // been passed in. 459 // been passed in.
401 if (network_manager->enumeration_permission() == 460 if (network_manager->enumeration_permission() ==
402 rtc::NetworkManager::ENUMERATION_BLOCKED) { 461 rtc::NetworkManager::ENUMERATION_BLOCKED) {
403 set_flags(flags() | PORTALLOCATOR_DISABLE_ADAPTER_ENUMERATION); 462 set_flags(flags() | PORTALLOCATOR_DISABLE_ADAPTER_ENUMERATION);
404 } 463 }
405 // If the adapter enumeration is disabled, we'll just bind to any address 464 // If the adapter enumeration is disabled, we'll just bind to any address
406 // instead of specific NIC. This is to ensure the same routing for http 465 // instead of specific NIC. This is to ensure the same routing for http
407 // traffic by OS is also used here to avoid any local or public IP leakage 466 // traffic by OS is also used here to avoid any local or public IP leakage
408 // during stun process. 467 // during stun process.
409 if (flags() & PORTALLOCATOR_DISABLE_ADAPTER_ENUMERATION) { 468 if (flags() & PORTALLOCATOR_DISABLE_ADAPTER_ENUMERATION) {
410 network_manager->GetAnyAddressNetworks(networks); 469 network_manager->GetAnyAddressNetworks(&networks);
411 } else { 470 } else {
412 network_manager->GetNetworks(networks); 471 network_manager->GetNetworks(&networks);
413 } 472 }
414 networks->erase(std::remove_if(networks->begin(), networks->end(), 473 networks.erase(std::remove_if(networks.begin(), networks.end(),
415 [this](rtc::Network* network) { 474 [this](rtc::Network* network) {
416 return allocator_->network_ignore_mask() & 475 return allocator_->network_ignore_mask() &
417 network->type(); 476 network->type();
418 }), 477 }),
419 networks->end()); 478 networks.end());
420 479
421 if (flags() & PORTALLOCATOR_DISABLE_COSTLY_NETWORKS) { 480 if (flags() & PORTALLOCATOR_DISABLE_COSTLY_NETWORKS) {
422 uint16_t lowest_cost = rtc::kNetworkCostMax; 481 uint16_t lowest_cost = rtc::kNetworkCostMax;
423 for (rtc::Network* network : *networks) { 482 for (rtc::Network* network : networks) {
424 lowest_cost = std::min<uint16_t>(lowest_cost, network->GetCost()); 483 lowest_cost = std::min<uint16_t>(lowest_cost, network->GetCost());
425 } 484 }
426 networks->erase(std::remove_if(networks->begin(), networks->end(), 485 networks.erase(std::remove_if(networks.begin(), networks.end(),
427 [lowest_cost](rtc::Network* network) { 486 [lowest_cost](rtc::Network* network) {
428 return network->GetCost() > 487 return network->GetCost() >
429 lowest_cost + rtc::kNetworkCostLow; 488 lowest_cost + rtc::kNetworkCostLow;
430 }), 489 }),
431 networks->end()); 490 networks.end());
432 } 491 }
492 return networks;
433 } 493 }
434 494
435 // For each network, see if we have a sequence that covers it already. If not, 495 // For each network, see if we have a sequence that covers it already. If not,
436 // create a new sequence to create the appropriate ports. 496 // create a new sequence to create the appropriate ports.
437 void BasicPortAllocatorSession::DoAllocate() { 497 void BasicPortAllocatorSession::DoAllocate() {
438 bool done_signal_needed = false; 498 bool done_signal_needed = false;
439 std::vector<rtc::Network*> networks; 499 std::vector<rtc::Network*> networks = GetNetworks();
440 GetNetworks(&networks);
441 500
442 if (networks.empty()) { 501 if (networks.empty()) {
443 LOG(LS_WARNING) << "Machine has no networks; no ports will be allocated"; 502 LOG(LS_WARNING) << "Machine has no networks; no ports will be allocated";
444 done_signal_needed = true; 503 done_signal_needed = true;
445 } else { 504 } else {
446 for (uint32_t i = 0; i < networks.size(); ++i) { 505 for (uint32_t i = 0; i < networks.size(); ++i) {
447 PortConfiguration* config = NULL; 506 PortConfiguration* config = NULL;
448 if (configs_.size() > 0) 507 if (configs_.size() > 0)
449 config = configs_.back(); 508 config = configs_.back();
450 509
(...skipping 27 matching lines...) Expand all
478 537
479 AllocationSequence* sequence = 538 AllocationSequence* sequence =
480 new AllocationSequence(this, networks[i], config, sequence_flags); 539 new AllocationSequence(this, networks[i], config, sequence_flags);
481 if (!sequence->Init()) { 540 if (!sequence->Init()) {
482 delete sequence; 541 delete sequence;
483 continue; 542 continue;
484 } 543 }
485 done_signal_needed = true; 544 done_signal_needed = true;
486 sequence->SignalPortAllocationComplete.connect( 545 sequence->SignalPortAllocationComplete.connect(
487 this, &BasicPortAllocatorSession::OnPortAllocationComplete); 546 this, &BasicPortAllocatorSession::OnPortAllocationComplete);
488 if (running_) 547 if (running_) {
489 sequence->Start(); 548 sequence->Start();
549 }
490 sequences_.push_back(sequence); 550 sequences_.push_back(sequence);
491 } 551 }
492 } 552 }
493 if (done_signal_needed) { 553 if (done_signal_needed) {
494 network_thread_->Post(RTC_FROM_HERE, this, MSG_SEQUENCEOBJECTS_CREATED); 554 network_thread_->Post(RTC_FROM_HERE, this, MSG_SEQUENCEOBJECTS_CREATED);
495 } 555 }
496 } 556 }
497 557
498 void BasicPortAllocatorSession::OnNetworksChanged() { 558 void BasicPortAllocatorSession::OnNetworksChanged() {
499 std::vector<rtc::Network*> networks; 559 std::vector<rtc::Network*> networks = GetNetworks();
500 GetNetworks(&networks); 560 std::vector<rtc::Network*> failed_networks;
501 for (AllocationSequence* sequence : sequences_) { 561 for (AllocationSequence* sequence : sequences_) {
502 // Remove the network from the allocation sequence if it is not in 562 // Remove the network from the allocation sequence if it is not in
503 // |networks|. 563 // |networks|.
504 if (!sequence->network_removed() && 564 if (!sequence->network_failed() &&
505 std::find(networks.begin(), networks.end(), sequence->network()) == 565 std::find(networks.begin(), networks.end(), sequence->network()) ==
506 networks.end()) { 566 networks.end()) {
507 sequence->OnNetworkRemoved(); 567 sequence->OnNetworkFailed();
568 failed_networks.push_back(sequence->network());
508 } 569 }
509 } 570 }
571 RemovePortsAndCandidates(failed_networks);
510 572
511 network_manager_started_ = true; 573 network_manager_started_ = true;
512 if (allocation_started_) 574 if (allocation_started_)
513 DoAllocate(); 575 DoAllocate();
514 } 576 }
515 577
516 void BasicPortAllocatorSession::DisableEquivalentPhases( 578 void BasicPortAllocatorSession::DisableEquivalentPhases(
517 rtc::Network* network, 579 rtc::Network* network,
518 PortConfiguration* config, 580 PortConfiguration* config,
519 uint32_t* flags) { 581 uint32_t* flags) {
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
749 Port* port) { 811 Port* port) {
750 for (std::vector<PortData>::iterator it = ports_.begin(); 812 for (std::vector<PortData>::iterator it = ports_.begin();
751 it != ports_.end(); ++it) { 813 it != ports_.end(); ++it) {
752 if (it->port() == port) { 814 if (it->port() == port) {
753 return &*it; 815 return &*it;
754 } 816 }
755 } 817 }
756 return NULL; 818 return NULL;
757 } 819 }
758 820
821 // Removes ports and candidates created on a given list of networks.
822 void BasicPortAllocatorSession::RemovePortsAndCandidates(
823 const std::vector<rtc::Network*>& networks) {
824 std::vector<PortInterface*> ports_to_remove;
825 std::vector<Candidate> candidates_to_remove;
826 for (const PortData& data : ports_) {
827 if (std::find(networks.begin(), networks.end(),
828 data.sequence()->network()) == networks.end()) {
829 continue;
830 }
831 ports_to_remove.push_back(data.port());
832 GetCandidatesFromPort(data, &candidates_to_remove);
833 }
834 SignalPortsRemoved(this, ports_to_remove);
835 SignalCandidatesRemoved(this, candidates_to_remove);
836 }
837
759 // AllocationSequence 838 // AllocationSequence
760 839
761 AllocationSequence::AllocationSequence(BasicPortAllocatorSession* session, 840 AllocationSequence::AllocationSequence(BasicPortAllocatorSession* session,
762 rtc::Network* network, 841 rtc::Network* network,
763 PortConfiguration* config, 842 PortConfiguration* config,
764 uint32_t flags) 843 uint32_t flags)
765 : session_(session), 844 : session_(session),
766 network_(network), 845 network_(network),
767 ip_(network->GetBestIP()), 846 ip_(network->GetBestIP()),
768 config_(config), 847 config_(config),
(...skipping 17 matching lines...) Expand all
786 // are next available options to setup a communication channel. 865 // are next available options to setup a communication channel.
787 } 866 }
788 return true; 867 return true;
789 } 868 }
790 869
791 void AllocationSequence::Clear() { 870 void AllocationSequence::Clear() {
792 udp_port_ = NULL; 871 udp_port_ = NULL;
793 turn_ports_.clear(); 872 turn_ports_.clear();
794 } 873 }
795 874
796 void AllocationSequence::OnNetworkRemoved() { 875 void AllocationSequence::OnNetworkFailed() {
797 // Stop the allocation sequence if its network is gone. 876 RTC_DCHECK(!network_failed_);
877 network_failed_ = true;
878 // Stop the allocation sequence if its network failed.
798 Stop(); 879 Stop();
799 network_removed_ = true;
800 } 880 }
801 881
802 AllocationSequence::~AllocationSequence() { 882 AllocationSequence::~AllocationSequence() {
803 session_->network_thread()->Clear(this); 883 session_->network_thread()->Clear(this);
804 } 884 }
805 885
806 void AllocationSequence::DisableEquivalentPhases(rtc::Network* network, 886 void AllocationSequence::DisableEquivalentPhases(rtc::Network* network,
807 PortConfiguration* config, uint32_t* flags) { 887 PortConfiguration* config, uint32_t* flags) {
808 if (network_removed_) { 888 if (network_failed_) {
809 // If the network of this allocation sequence has ever gone away, 889 // If the network of this allocation sequence has ever become failed,
810 // it won't be equivalent to the new network. 890 // it won't be equivalent to the new network.
811 return; 891 return;
812 } 892 }
813 893
814 if (!((network == network_) && (ip_ == network->GetBestIP()))) { 894 if (!((network == network_) && (ip_ == network->GetBestIP()))) {
815 // Different network setup; nothing is equivalent. 895 // Different network setup; nothing is equivalent.
816 return; 896 return;
817 } 897 }
818 898
819 // Else turn off the stuff that we've already got covered. 899 // Else turn off the stuff that we've already got covered.
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after
1235 ServerAddresses servers; 1315 ServerAddresses servers;
1236 for (size_t i = 0; i < relays.size(); ++i) { 1316 for (size_t i = 0; i < relays.size(); ++i) {
1237 if (relays[i].type == turn_type && SupportsProtocol(relays[i], type)) { 1317 if (relays[i].type == turn_type && SupportsProtocol(relays[i], type)) {
1238 servers.insert(relays[i].ports.front().address); 1318 servers.insert(relays[i].ports.front().address);
1239 } 1319 }
1240 } 1320 }
1241 return servers; 1321 return servers;
1242 } 1322 }
1243 1323
1244 } // namespace cricket 1324 } // namespace cricket
OLDNEW
« webrtc/p2p/base/port.cc ('K') | « webrtc/p2p/client/basicportallocator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698