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

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: . 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
« webrtc/p2p/base/portallocator.h ('K') | « 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 e39a44013cdcf4f5b4cf627e225c499afb1e1687..c5de5b61f911b36f1d6e901d9d411f65a7cfbb2a 100644
--- a/webrtc/p2p/client/basicportallocator.cc
+++ b/webrtc/p2p/client/basicportallocator.cc
@@ -138,7 +138,6 @@ BasicPortAllocatorSession::BasicPortAllocatorSession(
socket_factory_(allocator->socket_factory()),
allocation_started_(false),
network_manager_started_(false),
- running_(false),
allocation_sequences_created_(false) {
allocator_->network_manager()->SignalNetworksChanged.connect(
this, &BasicPortAllocatorSession::OnNetworksChanged);
@@ -198,23 +197,72 @@ void BasicPortAllocatorSession::StartGettingPorts() {
socket_factory_ = owned_socket_factory_.get();
}
- running_ = true;
+ running_ = STATE_RUNNING;
Taylor Brandstetter 2016/06/21 23:36:12 Should be "state_ = STATE_RUNNING"? Also can "runn
network_thread_->Post(RTC_FROM_HERE, this, MSG_CONFIG_START);
}
void BasicPortAllocatorSession::StopGettingPorts() {
ASSERT(rtc::Thread::Current() == network_thread_);
- running_ = false;
+ state_ = STATE_STOPPED;
network_thread_->Post(RTC_FROM_HERE, this, MSG_CONFIG_STOP);
ClearGettingPorts();
}
void BasicPortAllocatorSession::ClearGettingPorts() {
+ state_ = STATE_CLEARED;
network_thread_->Clear(this, MSG_ALLOCATE);
for (uint32_t i = 0; i < sequences_.size(); ++i)
sequences_[i]->Stop();
}
+std::vector<rtc::Network*> BasicPortAllocatorSession::GetFailedNetworks() {
+ rtc::NetworkManager::NetworkList networks = GetNetworks();
+
+ // Whether a network has at least one connection, keyed by interface name.
+ // So if an adapter interface has both IPv4 and IPv6 networks, they will
+ // be considered as one network.
+ std::map<std::string, bool> network_has_connection;
+ for (const PortData& data : ports_) {
+ PortInterface* port = data.port();
+ if (!port->connections().empty()) {
+ network_has_connection[port->Network()->name()] = true;
+ }
+ }
+
+ networks.erase(
+ std::remove_if(networks.begin(), networks.end(),
+ [network_has_connection](rtc::Network* network) {
+ // If a network does not have any connection, it is
+ // considered failed.
+ return network_has_connection[network->name()];
+ }),
+ networks.end());
+ return networks;
+}
+
+void BasicPortAllocatorSession::RegatherOnFailedNetworks() {
+ // Find the list of networks that have no connection.
+ rtc::NetworkManager::NetworkList networks = GetFailedNetworks();
+ if (networks.empty()) {
+ return;
+ }
+
+ // Inactivate sequences whose networks are in failed |networks|,
+ // so that they won't be considered as duplicates when the session
+ // regathers ports and candidates.
+ for (AllocationSequence* sequence : sequences_) {
+ if (!sequence->network_inactive() &&
+ std::find(networks->begin(), networks->end(), sequence->network()) !=
+ networks->end()) {
+ sequence->set_network_inactive(true);
+ // Close ports and signal candidate removals.
+ sequence->ClosePorts();
+ }
+ }
+
+ StartGettingPorts();
+}
+
std::vector<PortInterface*> BasicPortAllocatorSession::ReadyPorts() const {
std::vector<PortInterface*> ret;
for (const PortData& port : ports_) {
@@ -243,6 +291,18 @@ std::vector<Candidate> BasicPortAllocatorSession::ReadyCandidates() const {
return candidates;
}
+std::vector<Candidate> BasicPortAllocatorSession::ReadyCandidates(
+ PortInterface* port) const {
+ std::vector<Candidate> candidates;
+ for (const Candidate& candidate : port->Candidates()) {
+ if (!CheckCandidateFilter(candidate)) {
+ continue;
+ }
+ candidates.push_back(SanitizeRelatedAddress(candidate));
+ }
+ return candidates;
+}
+
Candidate BasicPortAllocatorSession::SanitizeRelatedAddress(
const Candidate& c) const {
Candidate copy = c;
@@ -391,9 +451,8 @@ void BasicPortAllocatorSession::OnAllocate() {
allocation_started_ = true;
}
-void BasicPortAllocatorSession::GetNetworks(
- std::vector<rtc::Network*>* networks) {
- networks->clear();
+std::vector<rtc::Network*> BasicPortAllocatorSession::GetNetworks() const {
+ 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
@@ -407,9 +466,9 @@ 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) {
@@ -430,14 +489,14 @@ void BasicPortAllocatorSession::GetNetworks(
}),
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";
@@ -485,8 +544,12 @@ void BasicPortAllocatorSession::DoAllocate() {
done_signal_needed = true;
sequence->SignalPortAllocationComplete.connect(
this, &BasicPortAllocatorSession::OnPortAllocationComplete);
- if (running_)
+ // TODO(honghaiz): Move this check at the beginning of the method. I do
+ // not see the point of creating a sequence without starting it. Will
+ // do this in a separate CL.
+ if (CanGetPorts()) {
sequence->Start();
+ }
sequences_.push_back(sequence);
}
}
@@ -496,15 +559,14 @@ void BasicPortAllocatorSession::DoAllocate() {
}
void BasicPortAllocatorSession::OnNetworksChanged() {
- std::vector<rtc::Network*> networks;
- GetNetworks(&networks);
+ std::vector<rtc::Network*> networks = GetNetworks();
for (AllocationSequence* sequence : sequences_) {
// Remove the network from the allocation sequence if it is not in
// |networks|.
- if (!sequence->network_removed() &&
+ if (!sequence->network_inactive() &&
std::find(networks.begin(), networks.end(), sequence->network()) ==
networks.end()) {
- sequence->OnNetworkRemoved();
+ sequence->OnNetworkInactivated();
}
}
@@ -544,6 +606,8 @@ void BasicPortAllocatorSession::AddAllocatedPort(Port* port,
port->SignalCandidateReady.connect(
this, &BasicPortAllocatorSession::OnCandidateReady);
+ port->SignalCandidatesRemoved.connect(
+ this, &BasicPortAllocatorSession::OnCandidatesRemoved);
port->SignalPortComplete.connect(this,
&BasicPortAllocatorSession::OnPortComplete);
port->SignalDestroyed.connect(this,
@@ -601,6 +665,28 @@ void BasicPortAllocatorSession::OnCandidateReady(
}
}
+void BasicPortAllocatorSession::OnCandidatesRemoved(
+ Port* port,
+ const std::vector<Candidate>& candidates) {
+ ASSERT(rtc::Thread::Current() == network_thread_);
+ PortData* data = FindPort(port);
+ ASSERT(data != NULL);
+
+ std::vector<Candidate> filtered_candidates;
+ for (Candidate c : candidates) {
+ ProtocolType pvalue;
+ bool candidate_protocol_enabled =
+ StringToProto(c.protocol().c_str(), &pvalue) &&
+ data->sequence()->ProtocolEnabled(pvalue);
+ if (candidate_protocol_enabled && CheckCandidateFilter(c)) {
+ filtered_candidates.push_back(SanitizeRelatedAddress(c));
+ }
+ }
+ if (!filtered_candidates.empty()) {
+ SignalCandidatesRemoved(this, filtered_candidates);
+ }
+}
+
void BasicPortAllocatorSession::OnPortComplete(Port* port) {
ASSERT(rtc::Thread::Current() == network_thread_);
PortData* data = FindPort(port);
@@ -793,10 +879,10 @@ void AllocationSequence::Clear() {
turn_ports_.clear();
}
-void AllocationSequence::OnNetworkRemoved() {
+void AllocationSequence::OnNetworkInactivated() {
// Stop the allocation sequence if its network is gone.
+ network_inactive_ = true;
Taylor Brandstetter 2016/06/21 23:36:12 nit: Would be better to store this bool as "networ
Stop();
- network_removed_ = true;
}
AllocationSequence::~AllocationSequence() {
@@ -805,8 +891,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_inactive_) {
+ // If the network of this allocation sequence has ever become inactive,
// it won't be equivalent to the new network.
return;
}
@@ -851,6 +937,15 @@ void AllocationSequence::Stop() {
}
}
+void AllocationSequence::ClosePorts() {
+ if (udp_port_) {
+ udp_port_->CloseAndSignalCandidateRemovals();
+ }
+ for (Port& port : turn_ports_) {
+ port.CloseAndSignalCandidateRemovals();
+ }
+}
+
void AllocationSequence::OnMessage(rtc::Message* msg) {
ASSERT(rtc::Thread::Current() == session_->network_thread());
ASSERT(msg->message_id == MSG_ALLOCATION_PHASE);
« webrtc/p2p/base/portallocator.h ('K') | « webrtc/p2p/client/basicportallocator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698