Chromium Code Reviews| 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 |