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

Unified 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 Created 4 years, 6 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « webrtc/p2p/client/basicportallocator.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webrtc/p2p/client/basicportallocator.cc
diff --git a/webrtc/p2p/client/basicportallocator.cc b/webrtc/p2p/client/basicportallocator.cc
index edd5fed9cf55843c8e56a7d8089c6ec4a61c4dba..3a7aa5a33340d1118a2b96c2acb33ec88254e094 100644
--- a/webrtc/p2p/client/basicportallocator.cc
+++ b/webrtc/p2p/client/basicportallocator.cc
@@ -184,7 +184,6 @@ BasicPortAllocatorSession::BasicPortAllocatorSession(
socket_factory_(allocator->socket_factory()),
allocation_started_(false),
network_manager_started_(false),
- running_(false),
allocation_sequences_created_(false),
prune_turn_ports_(allocator->prune_turn_ports()) {
allocator_->network_manager()->SignalNetworksChanged.connect(
@@ -239,27 +238,84 @@ void BasicPortAllocatorSession::SetCandidateFilter(uint32_t filter) {
void BasicPortAllocatorSession::StartGettingPorts() {
network_thread_ = rtc::Thread::Current();
+ PortAllocatorSession::StartGettingPorts();
if (!socket_factory_) {
owned_socket_factory_.reset(
new rtc::BasicPacketSocketFactory(network_thread_));
socket_factory_ = owned_socket_factory_.get();
}
- running_ = true;
network_thread_->Post(RTC_FROM_HERE, this, MSG_CONFIG_START);
}
void BasicPortAllocatorSession::StopGettingPorts() {
ASSERT(rtc::Thread::Current() == network_thread_);
- running_ = false;
network_thread_->Post(RTC_FROM_HERE, this, MSG_CONFIG_STOP);
ClearGettingPorts();
+ // Note: this must be called after ClearGettingPorts because both may set the
+ // session state and we should set the state to STOPPED.
+ PortAllocatorSession::StopGettingPorts();
}
void BasicPortAllocatorSession::ClearGettingPorts() {
+ ASSERT(rtc::Thread::Current() == network_thread_);
network_thread_->Clear(this, MSG_ALLOCATE);
- for (uint32_t i = 0; i < sequences_.size(); ++i)
+ for (uint32_t i = 0; i < sequences_.size(); ++i) {
sequences_[i]->Stop();
+ }
+ PortAllocatorSession::ClearGettingPorts();
+}
+
+std::vector<rtc::Network*> BasicPortAllocatorSession::GetFailedNetworks() {
+ std::vector<rtc::Network*> networks = GetNetworks();
+
+ // A network interface may have both IPv4 and IPv6 networks. Only if
+ // neither of the networks has any connections, the network interface
+ // is considered failed and need to be regathered on.
+ std::set<std::string> networks_with_connection;
+ for (const PortData& data : ports_) {
+ Port* port = data.port();
+ if (!port->connections().empty()) {
+ networks_with_connection.insert(port->Network()->name());
+ }
+ }
+
+ networks.erase(
+ std::remove_if(networks.begin(), networks.end(),
+ [networks_with_connection](rtc::Network* network) {
+ // If a network does not have any connection, it is
+ // considered failed.
+ return networks_with_connection.find(network->name()) !=
+ networks_with_connection.end();
+ }),
+ networks.end());
+ return networks;
+}
+
+void BasicPortAllocatorSession::RegatherOnFailedNetworks() {
+ // Find the list of networks that have no connection.
+ std::vector<rtc::Network*> failed_networks = GetFailedNetworks();
+ if (failed_networks.empty()) {
+ return;
+ }
+
+ // Mark a sequence as "network failed" if its network is in the list of failed
+ // networks, so that it won't be considered as equivalent when the session
+ // regathers ports and candidates.
+ for (AllocationSequence* sequence : sequences_) {
+ if (!sequence->network_failed() &&
+ std::find(failed_networks.begin(), failed_networks.end(),
+ sequence->network()) != failed_networks.end()) {
+ sequence->set_network_failed();
+ }
+ }
+ // Remove ports from being used locally and send signaling to remove
+ // the candidates on the remote side.
+ RemovePortsAndCandidates(failed_networks);
+
+ if (allocation_started_ && network_manager_started_) {
+ DoAllocate();
+ }
}
std::vector<PortInterface*> BasicPortAllocatorSession::ReadyPorts() const {
@@ -278,20 +334,26 @@ std::vector<Candidate> BasicPortAllocatorSession::ReadyCandidates() const {
if (!data.ready()) {
continue;
}
+ GetCandidatesFromPort(data, &candidates);
+ }
+ return candidates;
+}
- for (const Candidate& candidate : data.port()->Candidates()) {
- if (!CheckCandidateFilter(candidate)) {
- continue;
- }
- ProtocolType pvalue;
- if (!StringToProto(candidate.protocol().c_str(), &pvalue) ||
- !data.sequence()->ProtocolEnabled(pvalue)) {
- continue;
- }
- candidates.push_back(SanitizeRelatedAddress(candidate));
+void BasicPortAllocatorSession::GetCandidatesFromPort(
+ const PortData& data,
+ std::vector<Candidate>* candidates) const {
+ RTC_CHECK(candidates != nullptr);
+ for (const Candidate& candidate : data.port()->Candidates()) {
+ if (!CheckCandidateFilter(candidate)) {
+ continue;
+ }
+ ProtocolType pvalue;
+ if (!StringToProto(candidate.protocol().c_str(), &pvalue) ||
+ !data.sequence()->ProtocolEnabled(pvalue)) {
+ continue;
}
+ candidates->push_back(SanitizeRelatedAddress(candidate));
}
- return candidates;
}
Candidate BasicPortAllocatorSession::SanitizeRelatedAddress(
@@ -437,9 +499,8 @@ void BasicPortAllocatorSession::OnAllocate() {
allocation_started_ = true;
}
-void BasicPortAllocatorSession::GetNetworks(
- std::vector<rtc::Network*>* networks) {
- networks->clear();
+std::vector<rtc::Network*> BasicPortAllocatorSession::GetNetworks() {
+ std::vector<rtc::Network*> networks;
rtc::NetworkManager* network_manager = allocator_->network_manager();
ASSERT(network_manager != nullptr);
// If the network permission state is BLOCKED, we just act as if the flag has
@@ -453,37 +514,37 @@ void BasicPortAllocatorSession::GetNetworks(
// traffic by OS is also used here to avoid any local or public IP leakage
// during stun process.
if (flags() & PORTALLOCATOR_DISABLE_ADAPTER_ENUMERATION) {
- network_manager->GetAnyAddressNetworks(networks);
+ network_manager->GetAnyAddressNetworks(&networks);
} else {
- network_manager->GetNetworks(networks);
+ network_manager->GetNetworks(&networks);
}
- networks->erase(std::remove_if(networks->begin(), networks->end(),
- [this](rtc::Network* network) {
- return allocator_->network_ignore_mask() &
- network->type();
- }),
- networks->end());
+ networks.erase(std::remove_if(networks.begin(), networks.end(),
+ [this](rtc::Network* network) {
+ return allocator_->network_ignore_mask() &
+ network->type();
+ }),
+ networks.end());
if (flags() & PORTALLOCATOR_DISABLE_COSTLY_NETWORKS) {
uint16_t lowest_cost = rtc::kNetworkCostMax;
- for (rtc::Network* network : *networks) {
+ for (rtc::Network* network : networks) {
lowest_cost = std::min<uint16_t>(lowest_cost, network->GetCost());
}
- networks->erase(std::remove_if(networks->begin(), networks->end(),
- [lowest_cost](rtc::Network* network) {
- return network->GetCost() >
- lowest_cost + rtc::kNetworkCostLow;
- }),
- networks->end());
+ networks.erase(std::remove_if(networks.begin(), networks.end(),
+ [lowest_cost](rtc::Network* network) {
+ return network->GetCost() >
+ lowest_cost + rtc::kNetworkCostLow;
+ }),
+ networks.end());
}
+ return networks;
}
// For each network, see if we have a sequence that covers it already. If not,
// create a new sequence to create the appropriate ports.
void BasicPortAllocatorSession::DoAllocate() {
bool done_signal_needed = false;
- std::vector<rtc::Network*> networks;
- GetNetworks(&networks);
+ std::vector<rtc::Network*> networks = GetNetworks();
if (networks.empty()) {
LOG(LS_WARNING) << "Machine has no networks; no ports will be allocated";
@@ -528,8 +589,9 @@ void BasicPortAllocatorSession::DoAllocate() {
done_signal_needed = true;
sequence->SignalPortAllocationComplete.connect(
this, &BasicPortAllocatorSession::OnPortAllocationComplete);
- if (running_)
+ if (!IsStopped()) {
sequence->Start();
+ }
sequences_.push_back(sequence);
}
}
@@ -539,17 +601,19 @@ void BasicPortAllocatorSession::DoAllocate() {
}
void BasicPortAllocatorSession::OnNetworksChanged() {
- std::vector<rtc::Network*> networks;
- GetNetworks(&networks);
+ std::vector<rtc::Network*> networks = GetNetworks();
+ std::vector<rtc::Network*> failed_networks;
for (AllocationSequence* sequence : sequences_) {
- // Remove the network from the allocation sequence if it is not in
+ // Mark the sequence as "network failed" if its network is not in
// |networks|.
- if (!sequence->network_removed() &&
+ if (!sequence->network_failed() &&
std::find(networks.begin(), networks.end(), sequence->network()) ==
networks.end()) {
- sequence->OnNetworkRemoved();
+ sequence->OnNetworkFailed();
+ failed_networks.push_back(sequence->network());
}
}
+ RemovePortsAndCandidates(failed_networks);
network_manager_started_ = true;
if (allocation_started_)
@@ -847,6 +911,32 @@ BasicPortAllocatorSession::PortData* BasicPortAllocatorSession::FindPort(
return NULL;
}
+// Removes ports and candidates created on a given list of networks.
+void BasicPortAllocatorSession::RemovePortsAndCandidates(
+ const std::vector<rtc::Network*>& networks) {
+ std::vector<PortInterface*> ports_to_remove;
+ std::vector<Candidate> candidates_to_remove;
+ for (PortData& data : ports_) {
+ if (std::find(networks.begin(), networks.end(),
+ data.sequence()->network()) == networks.end()) {
+ continue;
+ }
+ ports_to_remove.push_back(data.port());
+ if (data.has_pairable_candidate()) {
+ GetCandidatesFromPort(data, &candidates_to_remove);
+ // Mark the port as having no pairable candidates so that its candidates
+ // won't be removed multiple times.
+ data.set_has_pairable_candidate(false);
+ }
+ }
+ if (!ports_to_remove.empty()) {
+ SignalPortsRemoved(this, ports_to_remove);
+ }
+ if (!candidates_to_remove.empty()) {
+ SignalCandidatesRemoved(this, candidates_to_remove);
+ }
+}
+
// AllocationSequence
AllocationSequence::AllocationSequence(BasicPortAllocatorSession* session,
@@ -884,10 +974,11 @@ void AllocationSequence::Clear() {
turn_ports_.clear();
}
-void AllocationSequence::OnNetworkRemoved() {
- // Stop the allocation sequence if its network is gone.
+void AllocationSequence::OnNetworkFailed() {
+ RTC_DCHECK(!network_failed_);
+ network_failed_ = true;
+ // Stop the allocation sequence if its network failed.
Stop();
- network_removed_ = true;
}
AllocationSequence::~AllocationSequence() {
@@ -896,8 +987,8 @@ AllocationSequence::~AllocationSequence() {
void AllocationSequence::DisableEquivalentPhases(rtc::Network* network,
PortConfiguration* config, uint32_t* flags) {
- if (network_removed_) {
- // If the network of this allocation sequence has ever gone away,
+ if (network_failed_) {
+ // If the network of this allocation sequence has ever become failed,
// it won't be equivalent to the new network.
return;
}
« no previous file with comments | « webrtc/p2p/client/basicportallocator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698