OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |