Chromium Code Reviews| Index: webrtc/p2p/base/p2ptransportchannel.cc |
| diff --git a/webrtc/p2p/base/p2ptransportchannel.cc b/webrtc/p2p/base/p2ptransportchannel.cc |
| index a4bde05d80cb9cac890e8aeaf81f76e3bd31611f..77e2600a52093b76894a2545b569fa3be08e0565 100644 |
| --- a/webrtc/p2p/base/p2ptransportchannel.cc |
| +++ b/webrtc/p2p/base/p2ptransportchannel.cc |
| @@ -27,10 +27,10 @@ |
| namespace { |
| // messages for queuing up work for ourselves |
| -enum { MSG_SORT = 1, MSG_CHECK_AND_PING }; |
| +enum { MSG_SORT = 1, MSG_CHECK_AND_PING, MSG_REGATHER_ON_FAILED_NETWORKS }; |
| // The minimum improvement in RTT that justifies a switch. |
| -static const double kMinImprovement = 10; |
| +const int kMinImprovement = 10; |
| bool IsRelayRelay(const cricket::Connection* conn) { |
| return conn->local_candidate().type() == cricket::RELAY_PORT_TYPE && |
| @@ -76,6 +76,9 @@ const int STABLE_WRITABLE_CONNECTION_PING_INTERVAL = 2500; // ms |
| static const int MIN_CHECK_RECEIVING_INTERVAL = 50; // ms |
| +// We periodically check if any existing networks do not have any connection |
| +// and regather on those networks. |
| +static const int DEFAULT_REGATHER_ON_FAILED_NETWORKS_INTERVAL = 5 * 60 * 1000; |
| static constexpr int a_is_better = 1; |
| static constexpr int b_is_better = -1; |
| @@ -101,10 +104,11 @@ P2PTransportChannel::P2PTransportChannel(const std::string& transport_name, |
| check_receiving_interval_(MIN_CHECK_RECEIVING_INTERVAL * 5), |
| config_(MIN_CHECK_RECEIVING_INTERVAL * 50 /* receiving_timeout */, |
| 0 /* backup_connection_ping_interval */, |
| - false /* gather_continually */, |
| + GATHER_ONCE /* continual_gathering_policy */, |
| false /* prioritize_most_likely_candidate_pairs */, |
| STABLE_WRITABLE_CONNECTION_PING_INTERVAL, |
| - true /* presume_writable_when_fully_relayed */) { |
| + true /* presume_writable_when_fully_relayed */, |
| + DEFAULT_REGATHER_ON_FAILED_NETWORKS_INTERVAL) { |
| uint32_t weak_ping_interval = ::strtoul( |
| webrtc::field_trial::FindFullName("WebRTC-StunInterPacketDelay").c_str(), |
| nullptr, 10); |
| @@ -125,8 +129,12 @@ void P2PTransportChannel::AddAllocatorSession( |
| session->set_generation(static_cast<uint32_t>(allocator_sessions_.size())); |
| session->SignalPortReady.connect(this, &P2PTransportChannel::OnPortReady); |
| + session->SignalPortsRemoved.connect(this, |
| + &P2PTransportChannel::OnPortsRemoved); |
| session->SignalCandidatesReady.connect( |
| this, &P2PTransportChannel::OnCandidatesReady); |
| + session->SignalCandidatesRemoved.connect( |
| + this, &P2PTransportChannel::OnCandidatesRemoved); |
| session->SignalCandidatesAllocationDone.connect( |
| this, &P2PTransportChannel::OnCandidatesAllocationDone); |
| @@ -295,8 +303,11 @@ void P2PTransportChannel::SetRemoteIceMode(IceMode mode) { |
| } |
| void P2PTransportChannel::SetIceConfig(const IceConfig& config) { |
| - config_.gather_continually = config.gather_continually; |
| - LOG(LS_INFO) << "Set gather_continually to " << config_.gather_continually; |
| + if (config_.continual_gathering_policy != config.continual_gathering_policy) { |
| + LOG(LS_INFO) << "Set continual_gathering_policy to " |
| + << config_.continual_gathering_policy; |
| + config_.continual_gathering_policy = config.continual_gathering_policy; |
| + } |
| if (config.backup_connection_ping_interval >= 0 && |
| config_.backup_connection_ping_interval != |
| @@ -346,6 +357,15 @@ void P2PTransportChannel::SetIceConfig(const IceConfig& config) { |
| << config_.presume_writable_when_fully_relayed; |
| } |
| } |
| + |
| + if (config.regather_on_failed_networks_interval >= 0 && |
| + config.regather_on_failed_networks_interval != |
|
pthatcher1
2016/06/29 18:53:27
Can we use an rtc::optional in config rather than
honghaiz3
2016/06/29 20:19:22
Done.
|
| + config_.regather_on_failed_networks_interval) { |
| + config_.regather_on_failed_networks_interval = |
| + config.regather_on_failed_networks_interval; |
| + LOG(LS_INFO) << "Set regather_on_failed_networks_interval to " |
| + << config_.regather_on_failed_networks_interval; |
| + } |
| } |
| const IceConfig& P2PTransportChannel::config() const { |
| @@ -364,6 +384,9 @@ void P2PTransportChannel::Connect() { |
| // Start checking and pinging as the ports come in. |
| thread()->Post(RTC_FROM_HERE, this, MSG_CHECK_AND_PING); |
| + thread()->PostDelayed(RTC_FROM_HERE, |
| + config_.regather_on_failed_networks_interval, this, |
| + MSG_REGATHER_ON_FAILED_NETWORKS); |
|
pthatcher1
2016/06/29 18:53:27
Taylor just refactored this :)
honghaiz3
2016/06/29 20:19:22
Will merge when his CL is in.
|
| } |
| void P2PTransportChannel::MaybeStartGathering() { |
| @@ -428,8 +451,7 @@ void P2PTransportChannel::OnPortReady(PortAllocatorSession *session, |
| port->SignalUnknownAddress.connect( |
| this, &P2PTransportChannel::OnUnknownAddress); |
| port->SignalDestroyed.connect(this, &P2PTransportChannel::OnPortDestroyed); |
| - port->SignalNetworkInactive.connect( |
| - this, &P2PTransportChannel::OnPortNetworkInactive); |
| + |
| port->SignalRoleConflict.connect( |
| this, &P2PTransportChannel::OnRoleConflict); |
| port->SignalSentPacket.connect(this, &P2PTransportChannel::OnSentPacket); |
| @@ -1303,13 +1325,13 @@ void P2PTransportChannel::MaybeStopPortAllocatorSessions() { |
| if (!session->IsGettingPorts()) { |
| continue; |
| } |
| - // If gathering continually, keep the last session running so that it |
| - // will gather candidates if the networks change. |
| - if (config_.gather_continually && session == allocator_sessions_.back()) { |
| + // If gathering continually, keep the last session running so that |
| + // it can gather candidates if the networks change. |
| + if (config_.gather_continually() && session == allocator_sessions_.back()) { |
| session->ClearGettingPorts(); |
| - break; |
| + } else { |
| + session->StopGettingPorts(); |
| } |
| - session->StopGettingPorts(); |
| } |
| } |
| @@ -1364,6 +1386,9 @@ void P2PTransportChannel::OnMessage(rtc::Message *pmsg) { |
| case MSG_CHECK_AND_PING: |
| OnCheckAndPing(); |
| break; |
| + case MSG_REGATHER_ON_FAILED_NETWORKS: |
| + OnRegatherOnFailedNetworks(); |
| + break; |
| default: |
| ASSERT(false); |
| break; |
| @@ -1594,41 +1619,72 @@ void P2PTransportChannel::OnConnectionDestroyed(Connection* connection) { |
| UpdateState(); |
| } |
| -// When a port is destroyed remove it from our list of ports to use for |
| +// When a port is destroyed, remove it from our list of ports to use for |
| // connection attempts. |
| void P2PTransportChannel::OnPortDestroyed(PortInterface* port) { |
| ASSERT(worker_thread_ == rtc::Thread::Current()); |
| - // Remove this port from the lists (if we didn't drop it already). |
| ports_.erase(std::remove(ports_.begin(), ports_.end(), port), ports_.end()); |
| removed_ports_.erase( |
| std::remove(removed_ports_.begin(), removed_ports_.end(), port), |
| removed_ports_.end()); |
| + LOG(INFO) << "Removed port because it is destroyed: " << ports_.size() |
| + << " remaining"; |
| +} |
| - LOG(INFO) << "Removed port from p2p socket: " |
| - << static_cast<int>(ports_.size()) << " remaining"; |
| +void P2PTransportChannel::OnPortsRemoved( |
| + PortAllocatorSession* session, |
| + const std::vector<PortInterface*>& ports) { |
| + ASSERT(worker_thread_ == rtc::Thread::Current()); |
| + LOG(LS_INFO) << "Remove " << ports.size() << " ports"; |
| + for (PortInterface* port : ports) { |
| + if (RemovePort(port)) { |
| + LOG(INFO) << "Removed port: " << port->ToString() << " " << ports_.size() |
| + << " remaining"; |
| + } |
| + } |
| } |
| -void P2PTransportChannel::OnPortNetworkInactive(PortInterface* port) { |
| - // If it does not gather continually, the port will be removed from the list |
| - // when ICE restarts. |
| - if (!config_.gather_continually) { |
| - return; |
| +bool P2PTransportChannel::RemovePort(PortInterface* port) { |
| + // Move this port from |ports_| to |removed_ports_| (if we haven't done it |
| + // already). |
| + auto new_end = std::remove(ports_.begin(), ports_.end(), port); |
| + if (new_end != ports_.end()) { |
| + ports_.erase(new_end, ports_.end()); |
| + removed_ports_.push_back(port); |
| + return true; |
| } |
| - auto it = std::find(ports_.begin(), ports_.end(), port); |
| - // Don't need to do anything if the port has been deleted from the port list. |
| - if (it == ports_.end()) { |
| + return false; |
| +} |
| + |
| +void P2PTransportChannel::OnCandidatesRemoved( |
| + PortAllocatorSession* session, |
| + const std::vector<Candidate>& candidates) { |
| + ASSERT(worker_thread_ == rtc::Thread::Current()); |
| + // Do not signal candidate removals if continual gathering is not enabled, or |
| + // if this is not the last session because an ICE restart would have signaled |
| + // the remote side to remove all candidates in previous sessions. |
| + if (!config_.gather_continually() || session != allocator_session()) { |
| return; |
| } |
| - removed_ports_.push_back(*it); |
| - ports_.erase(it); |
| - LOG(INFO) << "Removed port due to inactive networks: " << ports_.size() |
| - << " remaining"; |
| - std::vector<Candidate> candidates = port->Candidates(); |
| - for (Candidate& candidate : candidates) { |
| + |
| + std::vector<Candidate> candidates_to_remove; |
| + for (Candidate candidate : candidates) { |
| candidate.set_transport_name(transport_name()); |
| + candidates_to_remove.push_back(candidate); |
| } |
| - SignalCandidatesRemoved(this, candidates); |
| + SignalCandidatesRemoved(this, candidates_to_remove); |
| +} |
| + |
| +void P2PTransportChannel::OnRegatherOnFailedNetworks() { |
| + if (!config_.gather_continually() || allocator_sessions_.empty()) { |
| + return; |
| + } |
| + allocator_session()->RegatherOnFailedNetworks(); |
| + |
| + thread()->PostDelayed(RTC_FROM_HERE, |
| + config_.regather_on_failed_networks_interval, this, |
| + MSG_REGATHER_ON_FAILED_NETWORKS); |
| } |
| // We data is available, let listeners know |