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

Unified Diff: webrtc/p2p/client/basicportallocator.cc

Issue 2093623004: Add config to prune TURN ports (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@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
« no previous file with comments | « webrtc/p2p/client/basicportallocator.h ('k') | webrtc/p2p/client/basicportallocator_unittest.cc » ('j') | 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..cca9f0f53bf60807c5ebf6f94faac1aac555c0be 100644
--- a/webrtc/p2p/client/basicportallocator.cc
+++ b/webrtc/p2p/client/basicportallocator.cc
@@ -47,6 +47,36 @@ const int PHASE_SSLTCP = 3;
const int kNumPhases = 4;
+// Gets address family priority: IPv6 > IPv4 > Unspecified.
+int GetAddressFamilyPriority(int ip_family) {
+ switch (ip_family) {
+ case AF_INET6:
+ return 2;
+ case AF_INET:
+ return 1;
+ default:
+ RTC_DCHECK(false);
+ return 0;
+ }
+}
+
+// Returns positive if a is better, negative if b is better, and 0 otherwise.
+int ComparePort(const cricket::Port* a, const cricket::Port* b) {
+ static constexpr int a_is_better = 1;
+ static constexpr int b_is_better = -1;
+ // Protocol type is defined as UDP = 0, TCP = 1, SSLTCP = 2.
+ if (a->GetProtocol() < b->GetProtocol()) {
+ return a_is_better;
+ }
+ if (a->GetProtocol() > b->GetProtocol()) {
+ return b_is_better;
+ }
+
+ int a_family = GetAddressFamilyPriority(a->Network()->GetBestIP().family());
+ int b_family = GetAddressFamilyPriority(b->Network()->GetBestIP().family());
+ return a_family - b_family;
+}
+
} // namespace
namespace cricket {
@@ -74,7 +104,7 @@ BasicPortAllocator::BasicPortAllocator(rtc::NetworkManager* network_manager,
const ServerAddresses& stun_servers)
: network_manager_(network_manager), socket_factory_(socket_factory) {
ASSERT(socket_factory_ != NULL);
- SetConfiguration(stun_servers, std::vector<RelayServerConfig>(), 0);
+ SetConfiguration(stun_servers, std::vector<RelayServerConfig>(), 0, false);
Construct();
}
@@ -101,7 +131,7 @@ BasicPortAllocator::BasicPortAllocator(
turn_servers.push_back(config);
}
- SetConfiguration(stun_servers, turn_servers, 0);
+ SetConfiguration(stun_servers, turn_servers, 0, false);
Construct();
}
@@ -122,7 +152,8 @@ PortAllocatorSession* BasicPortAllocator::CreateSessionInternal(
void BasicPortAllocator::AddTurnServer(const RelayServerConfig& turn_server) {
std::vector<RelayServerConfig> new_turn_servers = turn_servers();
new_turn_servers.push_back(turn_server);
- SetConfiguration(stun_servers(), new_turn_servers, candidate_pool_size());
+ SetConfiguration(stun_servers(), new_turn_servers, candidate_pool_size(),
+ prune_turn_ports());
}
// BasicPortAllocatorSession
@@ -217,9 +248,9 @@ void BasicPortAllocatorSession::ClearGettingPorts() {
std::vector<PortInterface*> BasicPortAllocatorSession::ReadyPorts() const {
std::vector<PortInterface*> ret;
- for (const PortData& port : ports_) {
- if (port.has_pairable_candidate() && !port.error()) {
- ret.push_back(port.port());
+ for (const PortData& data : ports_) {
+ if (data.ready()) {
+ ret.push_back(data.port());
}
}
return ret;
@@ -228,6 +259,10 @@ std::vector<PortInterface*> BasicPortAllocatorSession::ReadyPorts() const {
std::vector<Candidate> BasicPortAllocatorSession::ReadyCandidates() const {
std::vector<Candidate> candidates;
for (const PortData& data : ports_) {
+ if (!data.ready()) {
+ continue;
+ }
+
for (const Candidate& candidate : data.port()->Candidates()) {
if (!CheckCandidateFilter(candidate)) {
continue;
@@ -278,16 +313,11 @@ bool BasicPortAllocatorSession::CandidatesAllocationDone() const {
return false;
}
- // If all allocated ports are in complete state, session must have got all
+ // If all allocated ports are no longer gathering, session must have got all
// expected candidates. Session will trigger candidates allocation complete
// signal.
- if (!std::all_of(ports_.begin(), ports_.end(), [](const PortData& port) {
- return (port.complete() || port.error());
- })) {
- return false;
- }
-
- return true;
+ return std::none_of(ports_.begin(), ports_.end(),
+ [](const PortData& port) { return port.inprogress(); });
}
void BasicPortAllocatorSession::OnMessage(rtc::Message *message) {
@@ -357,7 +387,7 @@ void BasicPortAllocatorSession::OnConfigStop() {
bool send_signal = false;
for (std::vector<PortData>::iterator it = ports_.begin();
it != ports_.end(); ++it) {
- if (!it->complete() && !it->error()) {
+ if (it->inprogress()) {
// Updating port state to error, which didn't finish allocating candidates
// yet.
it->set_error();
@@ -443,11 +473,8 @@ void BasicPortAllocatorSession::DoAllocate() {
LOG(LS_WARNING) << "Machine has no networks; no ports will be allocated";
done_signal_needed = true;
} else {
+ PortConfiguration* config = configs_.empty() ? nullptr : configs_.back();
for (uint32_t i = 0; i < networks.size(); ++i) {
- PortConfiguration* config = NULL;
- if (configs_.size() > 0)
- config = configs_.back();
-
uint32_t sequence_flags = flags();
if ((sequence_flags & DISABLE_ALL_PHASES) == DISABLE_ALL_PHASES) {
// If all the ports are disabled we should just fire the allocation
@@ -568,37 +595,84 @@ void BasicPortAllocatorSession::OnCandidateReady(
PortData* data = FindPort(port);
ASSERT(data != NULL);
// Discarding any candidate signal if port allocation status is
- // already in completed state.
- if (data->complete() || data->error()) {
+ // already done with gathering.
+ if (!data->inprogress()) {
return;
}
+ // Mark that the port has a pairable candidate, either because we have a
+ // usable candidate from the port, or simply because the port is bound to the
+ // any address and therefore has no host candidate. This will trigger the port
+ // to start creating candidate pairs (connections) and issue connectivity
+ // checks. If port has already been marked as having a pairable candidate,
+ // do nothing here.
+ // Note: We should check whether any candidates may become ready after this
+ // because there we will check whether the candidate is generated by the ready
+ // ports, which may include this port.
+ if (CandidatePairable(c, port) && !data->has_pairable_candidate()) {
+ data->set_has_pairable_candidate(true);
+
+ bool pruned_port = PruneTurnPortsWith(port);
pthatcher1 2016/06/29 17:36:14 Can you move the "if (!allocator_->prune_turn_port
honghaiz3 2016/06/29 18:11:45 Done.
+ // If the current port is not pruned yet, SignalPortReady.
+ if (!data->pruned()) {
+ SignalPortReady(this, port);
+ }
+ // If we have pruned any port, maybe need to signal port allocation done.
+ if (pruned_port) {
+ MaybeSignalCandidatesAllocationDone();
+ }
+ }
+
ProtocolType pvalue;
bool candidate_protocol_enabled =
StringToProto(c.protocol().c_str(), &pvalue) &&
data->sequence()->ProtocolEnabled(pvalue);
- if (CheckCandidateFilter(c) && candidate_protocol_enabled) {
+ if (data->ready() && CheckCandidateFilter(c) && candidate_protocol_enabled) {
std::vector<Candidate> candidates;
candidates.push_back(SanitizeRelatedAddress(c));
SignalCandidatesReady(this, candidates);
}
+}
- // Port has already been marked as having a pairable candidate.
- // Nothing to do here.
- if (data->has_pairable_candidate()) {
- return;
+Port* BasicPortAllocatorSession::GetBestTurnPortForNetwork(
+ const std::string& network_name) const {
+ Port* best_turn_port = nullptr;
+ for (const PortData& data : ports_) {
+ if (data.port()->Network()->name() == network_name &&
+ data.port()->Type() == RELAY_PORT_TYPE && data.ready() &&
+ (!best_turn_port || ComparePort(data.port(), best_turn_port) > 0)) {
+ best_turn_port = data.port();
+ }
}
+ return best_turn_port;
+}
- // Mark that the port has a pairable candidate, either because we have a
- // usable candidate from the port, or simply because the port is bound to the
- // any address and therefore has no host candidate. This will trigger the port
- // to start creating candidate pairs (connections) and issue connectivity
- // checks.
- if (CandidatePairable(c, port)) {
- data->set_has_pairable_candidate(true);
- SignalPortReady(this, port);
+bool BasicPortAllocatorSession::PruneTurnPortsWith(Port* port) {
pthatcher1 2016/06/29 17:36:14 I'd suggest calling this PruneTurnPorts and callin
honghaiz3 2016/06/29 18:11:45 Done.
+ if (!allocator_->prune_turn_ports() || port->Type() != RELAY_PORT_TYPE) {
+ return false;
+ }
+ bool pruned_port = false;
+ // Note: We determine the same network based only on their network names. So
+ // if an IPv4 address and an IPv6 address have the same network name, they
+ // are considered the same network here.
+ const std::string& network_name = port->Network()->name();
+ Port* best_turn_port = GetBestTurnPortForNetwork(network_name);
+ // |port| is already in the list of ports, so the best port cannot be nullptr.
+ RTC_CHECK(best_turn_port != nullptr);
+
+ for (PortData& data : ports_) {
+ if (data.port()->Network()->name() == network_name &&
+ data.port()->Type() == RELAY_PORT_TYPE && !data.pruned() &&
+ ComparePort(data.port(), best_turn_port) < 0) {
+ data.set_pruned();
+ pruned_port = true;
+ if (data.port() != port) {
+ SignalPortPruned(this, data.port());
+ }
+ }
}
+ return pruned_port;
}
void BasicPortAllocatorSession::OnPortComplete(Port* port) {
@@ -607,7 +681,7 @@ void BasicPortAllocatorSession::OnPortComplete(Port* port) {
ASSERT(data != NULL);
// Ignore any late signals.
- if (data->complete() || data->error()) {
+ if (!data->inprogress()) {
return;
}
@@ -622,7 +696,7 @@ void BasicPortAllocatorSession::OnPortError(Port* port) {
PortData* data = FindPort(port);
ASSERT(data != NULL);
// We might have already given up on this port and stopped it.
- if (data->complete() || data->error()) {
+ if (!data->inprogress()) {
return;
}
@@ -1028,13 +1102,11 @@ void AllocationSequence::CreateRelayPorts() {
return;
}
- PortConfiguration::RelayList::const_iterator relay;
- for (relay = config_->relays.begin();
- relay != config_->relays.end(); ++relay) {
- if (relay->type == RELAY_GTURN) {
- CreateGturnPort(*relay);
- } else if (relay->type == RELAY_TURN) {
- CreateTurnPort(*relay);
+ for (RelayServerConfig& relay : config_->relays) {
+ if (relay.type == RELAY_GTURN) {
+ CreateGturnPort(relay);
+ } else if (relay.type == RELAY_TURN) {
+ CreateTurnPort(relay);
} else {
ASSERT(false);
}
« no previous file with comments | « webrtc/p2p/client/basicportallocator.h ('k') | webrtc/p2p/client/basicportallocator_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698