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 |
11 #include "webrtc/p2p/client/basicportallocator.h" | 11 #include "webrtc/p2p/client/basicportallocator.h" |
12 | 12 |
13 #include <algorithm> | 13 #include <algorithm> |
14 #include <string> | 14 #include <string> |
15 #include <vector> | 15 #include <vector> |
16 | 16 |
17 #include "webrtc/api/peerconnectioninterface.h" | |
17 #include "webrtc/p2p/base/basicpacketsocketfactory.h" | 18 #include "webrtc/p2p/base/basicpacketsocketfactory.h" |
18 #include "webrtc/p2p/base/common.h" | 19 #include "webrtc/p2p/base/common.h" |
19 #include "webrtc/p2p/base/port.h" | 20 #include "webrtc/p2p/base/port.h" |
20 #include "webrtc/p2p/base/relayport.h" | 21 #include "webrtc/p2p/base/relayport.h" |
21 #include "webrtc/p2p/base/stunport.h" | 22 #include "webrtc/p2p/base/stunport.h" |
22 #include "webrtc/p2p/base/tcpport.h" | 23 #include "webrtc/p2p/base/tcpport.h" |
23 #include "webrtc/p2p/base/turnport.h" | 24 #include "webrtc/p2p/base/turnport.h" |
24 #include "webrtc/p2p/base/udpport.h" | 25 #include "webrtc/p2p/base/udpport.h" |
25 #include "webrtc/base/checks.h" | 26 #include "webrtc/base/checks.h" |
26 #include "webrtc/base/common.h" | 27 #include "webrtc/base/common.h" |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
149 void BasicPortAllocator::Construct() { | 150 void BasicPortAllocator::Construct() { |
150 allow_tcp_listen_ = true; | 151 allow_tcp_listen_ = true; |
151 } | 152 } |
152 | 153 |
153 BasicPortAllocator::~BasicPortAllocator() { | 154 BasicPortAllocator::~BasicPortAllocator() { |
154 } | 155 } |
155 | 156 |
156 PortAllocatorSession* BasicPortAllocator::CreateSessionInternal( | 157 PortAllocatorSession* BasicPortAllocator::CreateSessionInternal( |
157 const std::string& content_name, int component, | 158 const std::string& content_name, int component, |
158 const std::string& ice_ufrag, const std::string& ice_pwd) { | 159 const std::string& ice_ufrag, const std::string& ice_pwd) { |
159 return new BasicPortAllocatorSession( | 160 PortAllocatorSession* session = new BasicPortAllocatorSession( |
160 this, content_name, component, ice_ufrag, ice_pwd); | 161 this, content_name, component, ice_ufrag, ice_pwd); |
162 session->SignalIceRegatheringReason.connect( | |
163 this, &BasicPortAllocator::OnIceRegatheringReason); | |
164 return session; | |
161 } | 165 } |
162 | 166 |
163 void BasicPortAllocator::AddTurnServer(const RelayServerConfig& turn_server) { | 167 void BasicPortAllocator::AddTurnServer(const RelayServerConfig& turn_server) { |
164 std::vector<RelayServerConfig> new_turn_servers = turn_servers(); | 168 std::vector<RelayServerConfig> new_turn_servers = turn_servers(); |
165 new_turn_servers.push_back(turn_server); | 169 new_turn_servers.push_back(turn_server); |
166 SetConfiguration(stun_servers(), new_turn_servers, candidate_pool_size(), | 170 SetConfiguration(stun_servers(), new_turn_servers, candidate_pool_size(), |
167 prune_turn_ports()); | 171 prune_turn_ports()); |
168 } | 172 } |
169 | 173 |
174 void BasicPortAllocator::OnIceRegatheringReason(PortAllocatorSession* session, | |
175 IceRegatheringReason reason) { | |
176 if (metrics_observer()) { | |
177 metrics_observer()->IncrementEnumCounter( | |
178 webrtc::kEnumCounterIceRegatheringReason, static_cast<int>(reason), | |
179 static_cast<int>(IceRegatheringReason::MAX_VALUE)); | |
Taylor Brandstetter
2016/10/03 20:33:35
Unless I'm mistaken, pooled BasicPortAllocatorSess
honghaiz3
2016/10/04 01:03:55
It is true but only under the circumstances where
Taylor Brandstetter
2016/10/04 02:42:32
If we do count regathering that occurs for pooled
honghaiz3
2016/10/05 05:01:53
Do not count the regathering for pooled sessions f
| |
180 } | |
181 } | |
182 | |
170 // BasicPortAllocatorSession | 183 // BasicPortAllocatorSession |
171 BasicPortAllocatorSession::BasicPortAllocatorSession( | 184 BasicPortAllocatorSession::BasicPortAllocatorSession( |
172 BasicPortAllocator* allocator, | 185 BasicPortAllocator* allocator, |
173 const std::string& content_name, | 186 const std::string& content_name, |
174 int component, | 187 int component, |
175 const std::string& ice_ufrag, | 188 const std::string& ice_ufrag, |
176 const std::string& ice_pwd) | 189 const std::string& ice_pwd) |
177 : PortAllocatorSession(content_name, | 190 : PortAllocatorSession(content_name, |
178 component, | 191 component, |
179 ice_ufrag, | 192 ice_ufrag, |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
240 network_thread_ = rtc::Thread::Current(); | 253 network_thread_ = rtc::Thread::Current(); |
241 state_ = SessionState::GATHERING; | 254 state_ = SessionState::GATHERING; |
242 if (!socket_factory_) { | 255 if (!socket_factory_) { |
243 owned_socket_factory_.reset( | 256 owned_socket_factory_.reset( |
244 new rtc::BasicPacketSocketFactory(network_thread_)); | 257 new rtc::BasicPacketSocketFactory(network_thread_)); |
245 socket_factory_ = owned_socket_factory_.get(); | 258 socket_factory_ = owned_socket_factory_.get(); |
246 } | 259 } |
247 | 260 |
248 network_thread_->Post(RTC_FROM_HERE, this, MSG_CONFIG_START); | 261 network_thread_->Post(RTC_FROM_HERE, this, MSG_CONFIG_START); |
249 | 262 |
250 LOG(LS_INFO) << "Pruning turn ports " | 263 LOG(LS_INFO) << "Start getting ports with prune_turn_ports " |
251 << (prune_turn_ports_ ? "enabled" : "disabled"); | 264 << (prune_turn_ports_ ? "enabled" : "disabled"); |
252 } | 265 } |
253 | 266 |
254 void BasicPortAllocatorSession::StopGettingPorts() { | 267 void BasicPortAllocatorSession::StopGettingPorts() { |
255 ASSERT(rtc::Thread::Current() == network_thread_); | 268 ASSERT(rtc::Thread::Current() == network_thread_); |
256 ClearGettingPorts(); | 269 ClearGettingPorts(); |
257 // Note: this must be called after ClearGettingPorts because both may set the | 270 // Note: this must be called after ClearGettingPorts because both may set the |
258 // session state and we should set the state to STOPPED. | 271 // session state and we should set the state to STOPPED. |
259 state_ = SessionState::STOPPED; | 272 state_ = SessionState::STOPPED; |
260 } | 273 } |
(...skipping 28 matching lines...) Expand all Loading... | |
289 // If a network does not have any connection, it is | 302 // If a network does not have any connection, it is |
290 // considered failed. | 303 // considered failed. |
291 return networks_with_connection.find(network->name()) != | 304 return networks_with_connection.find(network->name()) != |
292 networks_with_connection.end(); | 305 networks_with_connection.end(); |
293 }), | 306 }), |
294 networks.end()); | 307 networks.end()); |
295 return networks; | 308 return networks; |
296 } | 309 } |
297 | 310 |
298 void BasicPortAllocatorSession::RegatherOnFailedNetworks() { | 311 void BasicPortAllocatorSession::RegatherOnFailedNetworks() { |
312 // Do not regather if the allocations has not started, the network manager has | |
313 // not started, or the session has stopped. | |
314 if (!allocation_started_ || !network_manager_started_ || IsStopped()) { | |
Taylor Brandstetter
2016/10/03 20:33:35
This seems separate to adding stats. Could you put
honghaiz3
2016/10/04 01:03:55
Moved away from this CL.
| |
315 return; | |
316 } | |
317 | |
299 // Find the list of networks that have no connection. | 318 // Find the list of networks that have no connection. |
300 std::vector<rtc::Network*> failed_networks = GetFailedNetworks(); | 319 std::vector<rtc::Network*> failed_networks = GetFailedNetworks(); |
301 if (failed_networks.empty()) { | 320 if (failed_networks.empty()) { |
302 return; | 321 return; |
303 } | 322 } |
304 | 323 |
324 LOG(LS_INFO) << "Regather candidates on failed networks"; | |
325 | |
305 // Mark a sequence as "network failed" if its network is in the list of failed | 326 // Mark a sequence as "network failed" if its network is in the list of failed |
306 // networks, so that it won't be considered as equivalent when the session | 327 // networks, so that it won't be considered as equivalent when the session |
307 // regathers ports and candidates. | 328 // regathers ports and candidates. |
308 for (AllocationSequence* sequence : sequences_) { | 329 for (AllocationSequence* sequence : sequences_) { |
309 if (!sequence->network_failed() && | 330 if (!sequence->network_failed() && |
310 std::find(failed_networks.begin(), failed_networks.end(), | 331 std::find(failed_networks.begin(), failed_networks.end(), |
311 sequence->network()) != failed_networks.end()) { | 332 sequence->network()) != failed_networks.end()) { |
312 sequence->set_network_failed(); | 333 sequence->set_network_failed(); |
313 } | 334 } |
314 } | 335 } |
315 // Remove ports from being used locally and send signaling to remove | 336 // Remove ports from being used locally and send signaling to remove |
316 // the candidates on the remote side. | 337 // the candidates on the remote side. |
317 std::vector<PortData*> ports_to_prune = GetUnprunedPorts(failed_networks); | 338 std::vector<PortData*> ports_to_prune = GetUnprunedPorts(failed_networks); |
318 if (!ports_to_prune.empty()) { | 339 if (!ports_to_prune.empty()) { |
319 LOG(LS_INFO) << "Prune " << ports_to_prune.size() | 340 LOG(LS_INFO) << "Prune " << ports_to_prune.size() |
320 << " ports because their networks failed"; | 341 << " ports because their networks failed"; |
321 PrunePortsAndRemoveCandidates(ports_to_prune); | 342 PrunePortsAndRemoveCandidates(ports_to_prune); |
322 } | 343 } |
323 | 344 |
324 if (allocation_started_ && network_manager_started_) { | 345 SignalIceRegatheringReason( |
325 DoAllocate(); | 346 this, IceRegatheringReason::CONTINUAL_GATHERING_BY_NETWORK_FAILURE); |
326 } | 347 |
348 DoAllocate(); | |
327 } | 349 } |
328 | 350 |
329 std::vector<PortInterface*> BasicPortAllocatorSession::ReadyPorts() const { | 351 std::vector<PortInterface*> BasicPortAllocatorSession::ReadyPorts() const { |
330 std::vector<PortInterface*> ret; | 352 std::vector<PortInterface*> ret; |
331 for (const PortData& data : ports_) { | 353 for (const PortData& data : ports_) { |
332 if (data.ready()) { | 354 if (data.ready()) { |
333 ret.push_back(data.port()); | 355 ret.push_back(data.port()); |
334 } | 356 } |
335 } | 357 } |
336 return ret; | 358 return ret; |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
494 MaybeSignalCandidatesAllocationDone(); | 516 MaybeSignalCandidatesAllocationDone(); |
495 } | 517 } |
496 } | 518 } |
497 | 519 |
498 void BasicPortAllocatorSession::AllocatePorts() { | 520 void BasicPortAllocatorSession::AllocatePorts() { |
499 ASSERT(rtc::Thread::Current() == network_thread_); | 521 ASSERT(rtc::Thread::Current() == network_thread_); |
500 network_thread_->Post(RTC_FROM_HERE, this, MSG_ALLOCATE); | 522 network_thread_->Post(RTC_FROM_HERE, this, MSG_ALLOCATE); |
501 } | 523 } |
502 | 524 |
503 void BasicPortAllocatorSession::OnAllocate() { | 525 void BasicPortAllocatorSession::OnAllocate() { |
504 if (network_manager_started_) | 526 if (network_manager_started_ && !IsStopped()) |
Taylor Brandstetter
2016/10/03 20:33:35
Same here.
honghaiz3
2016/10/04 01:03:55
This is not a behavior change.
I just moved the c
Taylor Brandstetter
2016/10/04 02:42:32
Acknowledged.
honghaiz3
2016/10/05 05:01:53
Acknowledged.
| |
505 DoAllocate(); | 527 DoAllocate(); |
506 | 528 |
507 allocation_started_ = true; | 529 allocation_started_ = true; |
508 } | 530 } |
509 | 531 |
510 std::vector<rtc::Network*> BasicPortAllocatorSession::GetNetworks() { | 532 std::vector<rtc::Network*> BasicPortAllocatorSession::GetNetworks() { |
511 std::vector<rtc::Network*> networks; | 533 std::vector<rtc::Network*> networks; |
512 rtc::NetworkManager* network_manager = allocator_->network_manager(); | 534 rtc::NetworkManager* network_manager = allocator_->network_manager(); |
513 ASSERT(network_manager != nullptr); | 535 ASSERT(network_manager != nullptr); |
514 // If the network permission state is BLOCKED, we just act as if the flag has | 536 // If the network permission state is BLOCKED, we just act as if the flag has |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
546 networks.end()); | 568 networks.end()); |
547 } | 569 } |
548 return networks; | 570 return networks; |
549 } | 571 } |
550 | 572 |
551 // For each network, see if we have a sequence that covers it already. If not, | 573 // For each network, see if we have a sequence that covers it already. If not, |
552 // create a new sequence to create the appropriate ports. | 574 // create a new sequence to create the appropriate ports. |
553 void BasicPortAllocatorSession::DoAllocate() { | 575 void BasicPortAllocatorSession::DoAllocate() { |
554 bool done_signal_needed = false; | 576 bool done_signal_needed = false; |
555 std::vector<rtc::Network*> networks = GetNetworks(); | 577 std::vector<rtc::Network*> networks = GetNetworks(); |
556 | |
557 if (IsStopped()) { | |
558 return; | |
559 } | |
560 if (networks.empty()) { | 578 if (networks.empty()) { |
561 LOG(LS_WARNING) << "Machine has no networks; no ports will be allocated"; | 579 LOG(LS_WARNING) << "Machine has no networks; no ports will be allocated"; |
562 done_signal_needed = true; | 580 done_signal_needed = true; |
563 } else { | 581 } else { |
564 LOG(LS_INFO) << "Allocate ports on "<< networks.size() << " networks"; | 582 LOG(LS_INFO) << "Allocate ports on "<< networks.size() << " networks"; |
565 PortConfiguration* config = configs_.empty() ? nullptr : configs_.back(); | 583 PortConfiguration* config = configs_.empty() ? nullptr : configs_.back(); |
566 for (uint32_t i = 0; i < networks.size(); ++i) { | 584 for (uint32_t i = 0; i < networks.size(); ++i) { |
567 uint32_t sequence_flags = flags(); | 585 uint32_t sequence_flags = flags(); |
568 if ((sequence_flags & DISABLE_ALL_PHASES) == DISABLE_ALL_PHASES) { | 586 if ((sequence_flags & DISABLE_ALL_PHASES) == DISABLE_ALL_PHASES) { |
569 // If all the ports are disabled we should just fire the allocation | 587 // If all the ports are disabled we should just fire the allocation |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
620 failed_networks.push_back(sequence->network()); | 638 failed_networks.push_back(sequence->network()); |
621 } | 639 } |
622 } | 640 } |
623 std::vector<PortData*> ports_to_prune = GetUnprunedPorts(failed_networks); | 641 std::vector<PortData*> ports_to_prune = GetUnprunedPorts(failed_networks); |
624 if (!ports_to_prune.empty()) { | 642 if (!ports_to_prune.empty()) { |
625 LOG(LS_INFO) << "Prune " << ports_to_prune.size() | 643 LOG(LS_INFO) << "Prune " << ports_to_prune.size() |
626 << " ports because their networks were gone"; | 644 << " ports because their networks were gone"; |
627 PrunePortsAndRemoveCandidates(ports_to_prune); | 645 PrunePortsAndRemoveCandidates(ports_to_prune); |
628 } | 646 } |
629 | 647 |
648 if (allocation_started_ && !IsStopped()) { | |
649 if (network_manager_started_) { | |
650 // If the network manager has started, it must be a regathering. | |
651 SignalIceRegatheringReason( | |
652 this, IceRegatheringReason::CONTINUAL_GATHERING_BY_NETWORK_CHANGE); | |
653 } | |
654 DoAllocate(); | |
655 } | |
656 | |
630 if (!network_manager_started_) { | 657 if (!network_manager_started_) { |
631 LOG(LS_INFO) << "Network manager is started"; | 658 LOG(LS_INFO) << "Network manager has started"; |
632 network_manager_started_ = true; | 659 network_manager_started_ = true; |
633 } | 660 } |
634 if (allocation_started_) | |
635 DoAllocate(); | |
636 } | 661 } |
637 | 662 |
638 void BasicPortAllocatorSession::DisableEquivalentPhases( | 663 void BasicPortAllocatorSession::DisableEquivalentPhases( |
639 rtc::Network* network, | 664 rtc::Network* network, |
640 PortConfiguration* config, | 665 PortConfiguration* config, |
641 uint32_t* flags) { | 666 uint32_t* flags) { |
642 for (uint32_t i = 0; i < sequences_.size() && | 667 for (uint32_t i = 0; i < sequences_.size() && |
643 (*flags & DISABLE_ALL_PHASES) != DISABLE_ALL_PHASES; | 668 (*flags & DISABLE_ALL_PHASES) != DISABLE_ALL_PHASES; |
644 ++i) { | 669 ++i) { |
645 sequences_[i]->DisableEquivalentPhases(network, config, flags); | 670 sequences_[i]->DisableEquivalentPhases(network, config, flags); |
(...skipping 837 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1483 ServerAddresses servers; | 1508 ServerAddresses servers; |
1484 for (size_t i = 0; i < relays.size(); ++i) { | 1509 for (size_t i = 0; i < relays.size(); ++i) { |
1485 if (relays[i].type == turn_type && SupportsProtocol(relays[i], type)) { | 1510 if (relays[i].type == turn_type && SupportsProtocol(relays[i], type)) { |
1486 servers.insert(relays[i].ports.front().address); | 1511 servers.insert(relays[i].ports.front().address); |
1487 } | 1512 } |
1488 } | 1513 } |
1489 return servers; | 1514 return servers; |
1490 } | 1515 } |
1491 | 1516 |
1492 } // namespace cricket | 1517 } // namespace cricket |
OLD | NEW |