Revert "Enable any address ports by default."
This reverts commit f04148c810aad2a0809dc8978650c55308381c47. Reason for revert: Speculative revert. I suspect this is breaking a downstream test (I'll reland if it is not the culprit). Original change's description: > Enable any address ports by default. > > Ports not bound to any specific network interface are allocated by > default. These any address ports are pruned after allocation, > conditional on the allocation results of normal ports that are bound to > the enumerated interfaces. > > Bug: webrtc:9313 > Change-Id: I3ce12eeab0cf3547224e5f8c188d061fc530e145 > Reviewed-on: https://webrtc-review.googlesource.com/78383 > Commit-Queue: Qingsi Wang <qingsi@google.com> > Reviewed-by: Taylor Brandstetter <deadbeef@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#23673} TBR=deadbeef@webrtc.org,pthatcher@webrtc.org,qingsi@google.com Change-Id: I3b3dc42c7de46d198d4b9c270020dcf1100dd907 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: webrtc:9313 Reviewed-on: https://webrtc-review.googlesource.com/84300 Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org> Commit-Queue: Mirko Bonadei <mbonadei@webrtc.org> Cr-Commit-Position: refs/heads/master@{#23678}
This commit is contained in:

committed by
Commit Bot

parent
80c0f06d63
commit
056a68da89
@ -72,8 +72,4 @@ const int CONNECTION_WRITE_TIMEOUT = 15 * 1000; // 15 seconds
|
|||||||
// of increased memory, but in some networks (2G), we observe up to 60s RTTs.
|
// of increased memory, but in some networks (2G), we observe up to 60s RTTs.
|
||||||
const int CONNECTION_RESPONSE_TIMEOUT = 60 * 1000; // 60 seconds
|
const int CONNECTION_RESPONSE_TIMEOUT = 60 * 1000; // 60 seconds
|
||||||
|
|
||||||
// TODO(qingsi): Review and calibrate the value (bugs.webrtc.org/9427).
|
|
||||||
const int kMaxWaitMsBeforeSignalingAnyAddressPortsAndCandidates =
|
|
||||||
2.5 * 1000; // 2.5 seconds
|
|
||||||
|
|
||||||
} // namespace cricket
|
} // namespace cricket
|
||||||
|
@ -102,12 +102,7 @@ extern const int CONNECTION_RESPONSE_TIMEOUT;
|
|||||||
// The minimum time we will wait before destroying a connection after creating
|
// The minimum time we will wait before destroying a connection after creating
|
||||||
// it.
|
// it.
|
||||||
extern const int MIN_CONNECTION_LIFETIME;
|
extern const int MIN_CONNECTION_LIFETIME;
|
||||||
// TODO(qingsi): Rename all constants to kConstant style.
|
|
||||||
//
|
|
||||||
// The maximum time in milliseconds we will wait before signaling any address
|
|
||||||
// ports and candidates gathered from these ports, if the candidate allocation
|
|
||||||
// is not done yet.
|
|
||||||
extern const int kMaxWaitMsBeforeSignalingAnyAddressPortsAndCandidates;
|
|
||||||
} // namespace cricket
|
} // namespace cricket
|
||||||
|
|
||||||
#endif // P2P_BASE_P2PCONSTANTS_H_
|
#endif // P2P_BASE_P2PCONSTANTS_H_
|
||||||
|
@ -52,7 +52,6 @@ static const int kOnlyLocalPorts = cricket::PORTALLOCATOR_DISABLE_STUN |
|
|||||||
cricket::PORTALLOCATOR_DISABLE_RELAY |
|
cricket::PORTALLOCATOR_DISABLE_RELAY |
|
||||||
cricket::PORTALLOCATOR_DISABLE_TCP;
|
cricket::PORTALLOCATOR_DISABLE_TCP;
|
||||||
static const int LOW_RTT = 20;
|
static const int LOW_RTT = 20;
|
||||||
static const SocketAddress kAnyAddr("0.0.0.0", 0);
|
|
||||||
// Addresses on the public internet.
|
// Addresses on the public internet.
|
||||||
static const SocketAddress kPublicAddrs[2] = {SocketAddress("11.11.11.11", 0),
|
static const SocketAddress kPublicAddrs[2] = {SocketAddress("11.11.11.11", 0),
|
||||||
SocketAddress("22.22.22.22", 0)};
|
SocketAddress("22.22.22.22", 0)};
|
||||||
@ -426,7 +425,6 @@ class P2PTransportChannelTestBase : public testing::Test,
|
|||||||
|
|
||||||
rtc::NATSocketServer* nat() { return nss_.get(); }
|
rtc::NATSocketServer* nat() { return nss_.get(); }
|
||||||
rtc::FirewallSocketServer* fw() { return ss_.get(); }
|
rtc::FirewallSocketServer* fw() { return ss_.get(); }
|
||||||
rtc::VirtualSocketServer* vss() { return vss_.get(); }
|
|
||||||
|
|
||||||
Endpoint* GetEndpoint(int endpoint) {
|
Endpoint* GetEndpoint(int endpoint) {
|
||||||
if (endpoint == 0) {
|
if (endpoint == 0) {
|
||||||
@ -1043,12 +1041,10 @@ class P2PTransportChannelTest : public P2PTransportChannelTestBase {
|
|||||||
AddAddress(endpoint, kPublicAddrs[endpoint]);
|
AddAddress(endpoint, kPublicAddrs[endpoint]);
|
||||||
// Block all UDP
|
// Block all UDP
|
||||||
fw()->AddRule(false, rtc::FP_UDP, rtc::FD_ANY, kPublicAddrs[endpoint]);
|
fw()->AddRule(false, rtc::FP_UDP, rtc::FD_ANY, kPublicAddrs[endpoint]);
|
||||||
fw()->AddRule(false, rtc::FP_UDP, rtc::FD_ANY, kAnyAddr);
|
|
||||||
if (config == BLOCK_UDP_AND_INCOMING_TCP) {
|
if (config == BLOCK_UDP_AND_INCOMING_TCP) {
|
||||||
// Block TCP inbound to the endpoint
|
// Block TCP inbound to the endpoint
|
||||||
fw()->AddRule(false, rtc::FP_TCP, SocketAddress(),
|
fw()->AddRule(false, rtc::FP_TCP, SocketAddress(),
|
||||||
kPublicAddrs[endpoint]);
|
kPublicAddrs[endpoint]);
|
||||||
fw()->AddRule(false, rtc::FP_TCP, SocketAddress(), kAnyAddr);
|
|
||||||
} else if (config == BLOCK_ALL_BUT_OUTGOING_HTTP) {
|
} else if (config == BLOCK_ALL_BUT_OUTGOING_HTTP) {
|
||||||
// Block all TCP to/from the endpoint except 80/443 out
|
// Block all TCP to/from the endpoint except 80/443 out
|
||||||
fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint],
|
fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint],
|
||||||
@ -1057,14 +1053,12 @@ class P2PTransportChannelTest : public P2PTransportChannelTestBase {
|
|||||||
SocketAddress(rtc::IPAddress(INADDR_ANY), 443));
|
SocketAddress(rtc::IPAddress(INADDR_ANY), 443));
|
||||||
fw()->AddRule(false, rtc::FP_TCP, rtc::FD_ANY,
|
fw()->AddRule(false, rtc::FP_TCP, rtc::FD_ANY,
|
||||||
kPublicAddrs[endpoint]);
|
kPublicAddrs[endpoint]);
|
||||||
fw()->AddRule(false, rtc::FP_TCP, rtc::FD_ANY, kAnyAddr);
|
|
||||||
} else if (config == PROXY_HTTPS) {
|
} else if (config == PROXY_HTTPS) {
|
||||||
// Block all TCP to/from the endpoint except to the proxy server
|
// Block all TCP to/from the endpoint except to the proxy server
|
||||||
fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint],
|
fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint],
|
||||||
kHttpsProxyAddrs[endpoint]);
|
kHttpsProxyAddrs[endpoint]);
|
||||||
fw()->AddRule(false, rtc::FP_TCP, rtc::FD_ANY,
|
fw()->AddRule(false, rtc::FP_TCP, rtc::FD_ANY,
|
||||||
kPublicAddrs[endpoint]);
|
kPublicAddrs[endpoint]);
|
||||||
fw()->AddRule(false, rtc::FP_TCP, rtc::FD_ANY, kAnyAddr);
|
|
||||||
SetProxy(endpoint, rtc::PROXY_HTTPS);
|
SetProxy(endpoint, rtc::PROXY_HTTPS);
|
||||||
} else if (config == PROXY_SOCKS) {
|
} else if (config == PROXY_SOCKS) {
|
||||||
// Block all TCP to/from the endpoint except to the proxy server
|
// Block all TCP to/from the endpoint except to the proxy server
|
||||||
@ -1072,7 +1066,6 @@ class P2PTransportChannelTest : public P2PTransportChannelTestBase {
|
|||||||
kSocksProxyAddrs[endpoint]);
|
kSocksProxyAddrs[endpoint]);
|
||||||
fw()->AddRule(false, rtc::FP_TCP, rtc::FD_ANY,
|
fw()->AddRule(false, rtc::FP_TCP, rtc::FD_ANY,
|
||||||
kPublicAddrs[endpoint]);
|
kPublicAddrs[endpoint]);
|
||||||
fw()->AddRule(false, rtc::FP_TCP, rtc::FD_ANY, kAnyAddr);
|
|
||||||
SetProxy(endpoint, rtc::PROXY_SOCKS5);
|
SetProxy(endpoint, rtc::PROXY_SOCKS5);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1715,8 +1708,16 @@ TEST_F(P2PTransportChannelTest, IncomingOnlyOpen) {
|
|||||||
// connections. This has been observed in some scenarios involving
|
// connections. This has been observed in some scenarios involving
|
||||||
// VPNs/firewalls.
|
// VPNs/firewalls.
|
||||||
TEST_F(P2PTransportChannelTest, CanOnlyMakeOutgoingTcpConnections) {
|
TEST_F(P2PTransportChannelTest, CanOnlyMakeOutgoingTcpConnections) {
|
||||||
ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
|
// The PORTALLOCATOR_ENABLE_ANY_ADDRESS_PORTS flag is required if the
|
||||||
kDefaultPortAllocatorFlags);
|
// application needs this use case to work, since the application must accept
|
||||||
|
// the tradeoff that more candidates need to be allocated.
|
||||||
|
//
|
||||||
|
// TODO(deadbeef): Later, make this flag the default, and do more elegant
|
||||||
|
// things to ensure extra candidates don't waste resources?
|
||||||
|
ConfigureEndpoints(
|
||||||
|
OPEN, OPEN,
|
||||||
|
kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_ANY_ADDRESS_PORTS,
|
||||||
|
kDefaultPortAllocatorFlags);
|
||||||
// In order to simulate nothing working but outgoing TCP connections, prevent
|
// In order to simulate nothing working but outgoing TCP connections, prevent
|
||||||
// the endpoint from binding to its interface's address as well as the
|
// the endpoint from binding to its interface's address as well as the
|
||||||
// "any" addresses. It can then only make a connection by using "Connect()".
|
// "any" addresses. It can then only make a connection by using "Connect()".
|
||||||
@ -3067,33 +3068,6 @@ TEST_F(P2PTransportChannelMultihomedTest, TestRestoreBackupConnection) {
|
|||||||
DestroyChannels();
|
DestroyChannels();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that when explicit binding to network interfaces is disallowed, we may
|
|
||||||
// still establish a connection by using the any address fallback.
|
|
||||||
TEST_F(P2PTransportChannelMultihomedTest,
|
|
||||||
BindingToAnyAddressRevealsViableRouteWhenExplicitBindingFails) {
|
|
||||||
rtc::ScopedFakeClock clock;
|
|
||||||
AddAddress(0, kPublicAddrs[0]);
|
|
||||||
AddAddress(1, kPublicAddrs[1]);
|
|
||||||
fw()->SetUnbindableIps({kPublicAddrs[0].ipaddr()});
|
|
||||||
// When bound to the any address, the port allocator should discover the
|
|
||||||
// alternative local address.
|
|
||||||
vss()->SetAlternativeLocalAddress(kAnyAddr.ipaddr(),
|
|
||||||
kAlternateAddrs[0].ipaddr());
|
|
||||||
SetAllocatorFlags(0, kOnlyLocalPorts);
|
|
||||||
SetAllocatorFlags(1, kOnlyLocalPorts);
|
|
||||||
IceConfig default_config;
|
|
||||||
CreateChannels(default_config, default_config);
|
|
||||||
EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
|
|
||||||
ep2_ch1()->receiving() &&
|
|
||||||
ep2_ch1()->writable(),
|
|
||||||
kMediumTimeout, clock);
|
|
||||||
EXPECT_TRUE(
|
|
||||||
ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection() &&
|
|
||||||
LocalCandidate(ep1_ch1())->address().EqualIPs(kAlternateAddrs[0]));
|
|
||||||
|
|
||||||
DestroyChannels();
|
|
||||||
}
|
|
||||||
|
|
||||||
// A collection of tests which tests a single P2PTransportChannel by sending
|
// A collection of tests which tests a single P2PTransportChannel by sending
|
||||||
// pings.
|
// pings.
|
||||||
class P2PTransportChannelPingTest : public testing::Test,
|
class P2PTransportChannelPingTest : public testing::Test,
|
||||||
|
@ -75,11 +75,13 @@ enum {
|
|||||||
// When specified, do not collect IPv6 ICE candidates on Wi-Fi.
|
// When specified, do not collect IPv6 ICE candidates on Wi-Fi.
|
||||||
PORTALLOCATOR_ENABLE_IPV6_ON_WIFI = 0x4000,
|
PORTALLOCATOR_ENABLE_IPV6_ON_WIFI = 0x4000,
|
||||||
|
|
||||||
// This flag is deprecated; we now always enable any address ports, only
|
// When this flag is set, ports not bound to any specific network interface
|
||||||
// using them if they end up using interfaces that weren't otherwise
|
// will be used, in addition to normal ports bound to the enumerated
|
||||||
// accessible.
|
// interfaces. Without this flag, these "any address" ports would only be
|
||||||
//
|
// used when network enumeration fails or is disabled. But under certain
|
||||||
// TODO(qingsi): Remove this flag when downstream projects no longer use it.
|
// conditions, these ports may succeed where others fail, so they may allow
|
||||||
|
// the application to work in a wider variety of environments, at the expense
|
||||||
|
// of having to allocate additional candidates.
|
||||||
PORTALLOCATOR_ENABLE_ANY_ADDRESS_PORTS = 0x8000,
|
PORTALLOCATOR_ENABLE_ANY_ADDRESS_PORTS = 0x8000,
|
||||||
|
|
||||||
// Exclude link-local network interfaces
|
// Exclude link-local network interfaces
|
||||||
|
@ -54,7 +54,7 @@ void StunServer::OnPacket(rtc::AsyncPacketSocket* socket,
|
|||||||
void StunServer::OnBindingRequest(StunMessage* msg,
|
void StunServer::OnBindingRequest(StunMessage* msg,
|
||||||
const rtc::SocketAddress& remote_addr) {
|
const rtc::SocketAddress& remote_addr) {
|
||||||
StunMessage response;
|
StunMessage response;
|
||||||
GetStunBindResponse(msg, remote_addr, &response);
|
GetStunBindReqponse(msg, remote_addr, &response);
|
||||||
SendResponse(response, remote_addr);
|
SendResponse(response, remote_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,7 +83,7 @@ void StunServer::SendResponse(const StunMessage& msg,
|
|||||||
RTC_LOG_ERR(LS_ERROR) << "sendto";
|
RTC_LOG_ERR(LS_ERROR) << "sendto";
|
||||||
}
|
}
|
||||||
|
|
||||||
void StunServer::GetStunBindResponse(StunMessage* request,
|
void StunServer::GetStunBindReqponse(StunMessage* request,
|
||||||
const rtc::SocketAddress& remote_addr,
|
const rtc::SocketAddress& remote_addr,
|
||||||
StunMessage* response) const {
|
StunMessage* response) const {
|
||||||
response->SetType(STUN_BINDING_RESPONSE);
|
response->SetType(STUN_BINDING_RESPONSE);
|
||||||
|
@ -52,7 +52,7 @@ class StunServer : public sigslot::has_slots<> {
|
|||||||
void SendResponse(const StunMessage& msg, const rtc::SocketAddress& addr);
|
void SendResponse(const StunMessage& msg, const rtc::SocketAddress& addr);
|
||||||
|
|
||||||
// A helper method to compose a STUN binding response.
|
// A helper method to compose a STUN binding response.
|
||||||
void GetStunBindResponse(StunMessage* request,
|
void GetStunBindReqponse(StunMessage* request,
|
||||||
const rtc::SocketAddress& remote_addr,
|
const rtc::SocketAddress& remote_addr,
|
||||||
StunMessage* response) const;
|
StunMessage* response) const;
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ void TestStunServer::OnBindingRequest(StunMessage* msg,
|
|||||||
StunServer::OnBindingRequest(msg, remote_addr);
|
StunServer::OnBindingRequest(msg, remote_addr);
|
||||||
} else {
|
} else {
|
||||||
StunMessage response;
|
StunMessage response;
|
||||||
GetStunBindResponse(msg, fake_stun_addr_, &response);
|
GetStunBindReqponse(msg, fake_stun_addr_, &response);
|
||||||
SendResponse(response, remote_addr);
|
SendResponse(response, remote_addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,6 @@
|
|||||||
#include "p2p/base/udpport.h"
|
#include "p2p/base/udpport.h"
|
||||||
#include "rtc_base/checks.h"
|
#include "rtc_base/checks.h"
|
||||||
#include "rtc_base/helpers.h"
|
#include "rtc_base/helpers.h"
|
||||||
#include "rtc_base/ipaddress.h"
|
|
||||||
#include "rtc_base/logging.h"
|
#include "rtc_base/logging.h"
|
||||||
|
|
||||||
using rtc::CreateRandomId;
|
using rtc::CreateRandomId;
|
||||||
@ -40,7 +39,6 @@ enum {
|
|||||||
MSG_ALLOCATION_PHASE,
|
MSG_ALLOCATION_PHASE,
|
||||||
MSG_SEQUENCEOBJECTS_CREATED,
|
MSG_SEQUENCEOBJECTS_CREATED,
|
||||||
MSG_CONFIG_STOP,
|
MSG_CONFIG_STOP,
|
||||||
MSG_SIGNAL_ANY_ADDRESS_PORTS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const int PHASE_UDP = 0;
|
const int PHASE_UDP = 0;
|
||||||
@ -113,10 +111,6 @@ void FilterNetworks(NetworkList* networks, NetworkFilter filter) {
|
|||||||
networks->erase(start_to_remove, networks->end());
|
networks->erase(start_to_remove, networks->end());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsAnyAddressPort(const cricket::Port* port) {
|
|
||||||
return rtc::IPIsAny(port->Network()->GetBestIP());
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace cricket {
|
namespace cricket {
|
||||||
@ -154,7 +148,7 @@ BasicPortAllocator::BasicPortAllocator(rtc::NetworkManager* network_manager,
|
|||||||
: network_manager_(network_manager), socket_factory_(socket_factory) {
|
: network_manager_(network_manager), socket_factory_(socket_factory) {
|
||||||
InitRelayPortFactory(nullptr);
|
InitRelayPortFactory(nullptr);
|
||||||
RTC_DCHECK(relay_port_factory_ != nullptr);
|
RTC_DCHECK(relay_port_factory_ != nullptr);
|
||||||
RTC_DCHECK(socket_factory_ != nullptr);
|
RTC_DCHECK(socket_factory_ != NULL);
|
||||||
SetConfiguration(stun_servers, std::vector<RelayServerConfig>(), 0, false,
|
SetConfiguration(stun_servers, std::vector<RelayServerConfig>(), 0, false,
|
||||||
nullptr);
|
nullptr);
|
||||||
Construct();
|
Construct();
|
||||||
@ -166,7 +160,7 @@ BasicPortAllocator::BasicPortAllocator(
|
|||||||
const rtc::SocketAddress& relay_address_udp,
|
const rtc::SocketAddress& relay_address_udp,
|
||||||
const rtc::SocketAddress& relay_address_tcp,
|
const rtc::SocketAddress& relay_address_tcp,
|
||||||
const rtc::SocketAddress& relay_address_ssl)
|
const rtc::SocketAddress& relay_address_ssl)
|
||||||
: network_manager_(network_manager), socket_factory_(nullptr) {
|
: network_manager_(network_manager), socket_factory_(NULL) {
|
||||||
InitRelayPortFactory(nullptr);
|
InitRelayPortFactory(nullptr);
|
||||||
RTC_DCHECK(relay_port_factory_ != nullptr);
|
RTC_DCHECK(relay_port_factory_ != nullptr);
|
||||||
RTC_DCHECK(network_manager_ != nullptr);
|
RTC_DCHECK(network_manager_ != nullptr);
|
||||||
@ -271,7 +265,7 @@ BasicPortAllocatorSession::BasicPortAllocatorSession(
|
|||||||
ice_pwd,
|
ice_pwd,
|
||||||
allocator->flags()),
|
allocator->flags()),
|
||||||
allocator_(allocator),
|
allocator_(allocator),
|
||||||
network_thread_(nullptr),
|
network_thread_(NULL),
|
||||||
socket_factory_(allocator->socket_factory()),
|
socket_factory_(allocator->socket_factory()),
|
||||||
allocation_started_(false),
|
allocation_started_(false),
|
||||||
network_manager_started_(false),
|
network_manager_started_(false),
|
||||||
@ -284,7 +278,7 @@ BasicPortAllocatorSession::BasicPortAllocatorSession(
|
|||||||
|
|
||||||
BasicPortAllocatorSession::~BasicPortAllocatorSession() {
|
BasicPortAllocatorSession::~BasicPortAllocatorSession() {
|
||||||
allocator_->network_manager()->StopUpdating();
|
allocator_->network_manager()->StopUpdating();
|
||||||
if (network_thread_ != nullptr)
|
if (network_thread_ != NULL)
|
||||||
network_thread_->Clear(this);
|
network_thread_->Clear(this);
|
||||||
|
|
||||||
for (uint32_t i = 0; i < sequences_.size(); ++i) {
|
for (uint32_t i = 0; i < sequences_.size(); ++i) {
|
||||||
@ -451,7 +445,7 @@ void BasicPortAllocatorSession::Regather(
|
|||||||
std::vector<PortData*> ports_to_prune = GetUnprunedPorts(networks);
|
std::vector<PortData*> ports_to_prune = GetUnprunedPorts(networks);
|
||||||
if (!ports_to_prune.empty()) {
|
if (!ports_to_prune.empty()) {
|
||||||
RTC_LOG(LS_INFO) << "Prune " << ports_to_prune.size() << " ports";
|
RTC_LOG(LS_INFO) << "Prune " << ports_to_prune.size() << " ports";
|
||||||
PrunePortsAndSignalCandidatesRemoval(ports_to_prune);
|
PrunePortsAndRemoveCandidates(ports_to_prune);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (allocation_started_ && network_manager_started_ && !IsStopped()) {
|
if (allocation_started_ && network_manager_started_ && !IsStopped()) {
|
||||||
@ -573,10 +567,6 @@ void BasicPortAllocatorSession::OnMessage(rtc::Message* message) {
|
|||||||
RTC_DCHECK(rtc::Thread::Current() == network_thread_);
|
RTC_DCHECK(rtc::Thread::Current() == network_thread_);
|
||||||
OnConfigStop();
|
OnConfigStop();
|
||||||
break;
|
break;
|
||||||
case MSG_SIGNAL_ANY_ADDRESS_PORTS:
|
|
||||||
RTC_DCHECK(rtc::Thread::Current() == network_thread_);
|
|
||||||
SignalAnyAddressPortsAndCandidatesReadyIfNotRedundant();
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
RTC_NOTREACHED();
|
RTC_NOTREACHED();
|
||||||
}
|
}
|
||||||
@ -639,7 +629,7 @@ void BasicPortAllocatorSession::OnConfigStop() {
|
|||||||
|
|
||||||
// If we stopped anything that was running, send a done signal now.
|
// If we stopped anything that was running, send a done signal now.
|
||||||
if (send_signal) {
|
if (send_signal) {
|
||||||
FireAllocationStatusSignalsIfNeeded();
|
MaybeSignalCandidatesAllocationDone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -667,24 +657,22 @@ std::vector<rtc::Network*> BasicPortAllocatorSession::GetNetworks() {
|
|||||||
rtc::NetworkManager::ENUMERATION_BLOCKED) {
|
rtc::NetworkManager::ENUMERATION_BLOCKED) {
|
||||||
set_flags(flags() | PORTALLOCATOR_DISABLE_ADAPTER_ENUMERATION);
|
set_flags(flags() | PORTALLOCATOR_DISABLE_ADAPTER_ENUMERATION);
|
||||||
}
|
}
|
||||||
|
// If the adapter enumeration is disabled, we'll just bind to any address
|
||||||
// If adapter enumeration is disabled, we'll just bind to any address
|
// instead of specific NIC. This is to ensure the same routing for http
|
||||||
// instead of a specific NIC. This is to ensure that WebRTC traffic is routed
|
// traffic by OS is also used here to avoid any local or public IP leakage
|
||||||
// by the OS in the same way that HTTP traffic would be, and no additional
|
// during stun process.
|
||||||
// local or public IPs are leaked during ICE processing.
|
if (flags() & PORTALLOCATOR_DISABLE_ADAPTER_ENUMERATION) {
|
||||||
//
|
network_manager->GetAnyAddressNetworks(&networks);
|
||||||
// Even when adapter enumeration is enabled, we still bind to the "any"
|
} else {
|
||||||
// address as a fallback, since this may potentially reveal network
|
|
||||||
// interfaces that weren't otherwise accessible. Note that the candidates
|
|
||||||
// gathered by binding to the "any" address won't be surfaced to the
|
|
||||||
// application if they're determined to be redundant (if they have the same
|
|
||||||
// address as a candidate gathered by binding to an interface explicitly).
|
|
||||||
if (!(flags() & PORTALLOCATOR_DISABLE_ADAPTER_ENUMERATION)) {
|
|
||||||
network_manager->GetNetworks(&networks);
|
network_manager->GetNetworks(&networks);
|
||||||
|
// If network enumeration fails, use the ANY address as a fallback, so we
|
||||||
|
// can at least try gathering candidates using the default route chosen by
|
||||||
|
// the OS. Or, if the PORTALLOCATOR_ENABLE_ANY_ADDRESS_PORTS flag is
|
||||||
|
// set, we'll use ANY address candidates either way.
|
||||||
|
if (networks.empty() || flags() & PORTALLOCATOR_ENABLE_ANY_ADDRESS_PORTS) {
|
||||||
|
network_manager->GetAnyAddressNetworks(&networks);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
network_manager->GetAnyAddressNetworks(&networks);
|
|
||||||
|
|
||||||
// Filter out link-local networks if needed.
|
// Filter out link-local networks if needed.
|
||||||
if (flags() & PORTALLOCATOR_DISABLE_LINK_LOCAL_NETWORKS) {
|
if (flags() & PORTALLOCATOR_DISABLE_LINK_LOCAL_NETWORKS) {
|
||||||
NetworkFilter link_local_filter(
|
NetworkFilter link_local_filter(
|
||||||
@ -703,12 +691,11 @@ std::vector<rtc::Network*> BasicPortAllocatorSession::GetNetworks() {
|
|||||||
if (flags() & PORTALLOCATOR_DISABLE_COSTLY_NETWORKS) {
|
if (flags() & PORTALLOCATOR_DISABLE_COSTLY_NETWORKS) {
|
||||||
uint16_t lowest_cost = rtc::kNetworkCostMax;
|
uint16_t lowest_cost = rtc::kNetworkCostMax;
|
||||||
for (rtc::Network* network : networks) {
|
for (rtc::Network* network : networks) {
|
||||||
// Don't determine the lowest cost from a link-local or any address
|
// Don't determine the lowest cost from a link-local network.
|
||||||
// network. On iOS, a device connected to the computer will get a
|
// On iOS, a device connected to the computer will get a link-local
|
||||||
// link-local network for communicating with the computer, however this
|
// network for communicating with the computer, however this network can't
|
||||||
// network can't be used to connect to a peer outside the network.
|
// be used to connect to a peer outside the network.
|
||||||
if (rtc::IPIsLinkLocal(network->GetBestIP()) ||
|
if (rtc::IPIsLinkLocal(network->GetBestIP())) {
|
||||||
rtc::IPIsAny(network->GetBestIP())) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
lowest_cost = std::min<uint16_t>(lowest_cost, network->GetCost());
|
lowest_cost = std::min<uint16_t>(lowest_cost, network->GetCost());
|
||||||
@ -806,19 +793,6 @@ void BasicPortAllocatorSession::DoAllocate(bool disable_equivalent) {
|
|||||||
if (done_signal_needed) {
|
if (done_signal_needed) {
|
||||||
network_thread_->Post(RTC_FROM_HERE, this, MSG_SEQUENCEOBJECTS_CREATED);
|
network_thread_->Post(RTC_FROM_HERE, this, MSG_SEQUENCEOBJECTS_CREATED);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If adapter enumeration is enabled, then we prefer binding to individual
|
|
||||||
// network adapters, only using ports bound to the "any" address (0.0.0.0) if
|
|
||||||
// they reveal an interface not otherwise accessible. Normally these will be
|
|
||||||
// surfaced when candidate allocation completes, but sometimes candidate
|
|
||||||
// allocation can take a long time, if a STUN transaction times out for
|
|
||||||
// instance. So as a backup, we'll surface these ports/candidates after
|
|
||||||
// |kMaxWaitMsBeforeSignalingAnyAddressPortsAndCandidates| passes.
|
|
||||||
if (!(flags() & PORTALLOCATOR_DISABLE_ADAPTER_ENUMERATION)) {
|
|
||||||
network_thread_->PostDelayed(
|
|
||||||
RTC_FROM_HERE, kMaxWaitMsBeforeSignalingAnyAddressPortsAndCandidates,
|
|
||||||
this, MSG_SIGNAL_ANY_ADDRESS_PORTS);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BasicPortAllocatorSession::OnNetworksChanged() {
|
void BasicPortAllocatorSession::OnNetworksChanged() {
|
||||||
@ -838,7 +812,7 @@ void BasicPortAllocatorSession::OnNetworksChanged() {
|
|||||||
if (!ports_to_prune.empty()) {
|
if (!ports_to_prune.empty()) {
|
||||||
RTC_LOG(LS_INFO) << "Prune " << ports_to_prune.size()
|
RTC_LOG(LS_INFO) << "Prune " << ports_to_prune.size()
|
||||||
<< " ports because their networks were gone";
|
<< " ports because their networks were gone";
|
||||||
PrunePortsAndSignalCandidatesRemoval(ports_to_prune);
|
PrunePortsAndRemoveCandidates(ports_to_prune);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (allocation_started_ && !IsStopped()) {
|
if (allocation_started_ && !IsStopped()) {
|
||||||
@ -901,14 +875,14 @@ void BasicPortAllocatorSession::AddAllocatedPort(Port* port,
|
|||||||
void BasicPortAllocatorSession::OnAllocationSequenceObjectsCreated() {
|
void BasicPortAllocatorSession::OnAllocationSequenceObjectsCreated() {
|
||||||
allocation_sequences_created_ = true;
|
allocation_sequences_created_ = true;
|
||||||
// Send candidate allocation complete signal if we have no sequences.
|
// Send candidate allocation complete signal if we have no sequences.
|
||||||
FireAllocationStatusSignalsIfNeeded();
|
MaybeSignalCandidatesAllocationDone();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BasicPortAllocatorSession::OnCandidateReady(Port* port,
|
void BasicPortAllocatorSession::OnCandidateReady(Port* port,
|
||||||
const Candidate& c) {
|
const Candidate& c) {
|
||||||
RTC_DCHECK(rtc::Thread::Current() == network_thread_);
|
RTC_DCHECK(rtc::Thread::Current() == network_thread_);
|
||||||
PortData* data = FindPort(port);
|
PortData* data = FindPort(port);
|
||||||
RTC_DCHECK(data != nullptr);
|
RTC_DCHECK(data != NULL);
|
||||||
RTC_LOG(LS_INFO) << port->ToString()
|
RTC_LOG(LS_INFO) << port->ToString()
|
||||||
<< ": Gathered candidate: " << c.ToSensitiveString();
|
<< ": Gathered candidate: " << c.ToSensitiveString();
|
||||||
// Discarding any candidate signal if port allocation status is
|
// Discarding any candidate signal if port allocation status is
|
||||||
@ -937,56 +911,23 @@ void BasicPortAllocatorSession::OnCandidateReady(Port* port,
|
|||||||
}
|
}
|
||||||
// If the current port is not pruned yet, SignalPortReady.
|
// If the current port is not pruned yet, SignalPortReady.
|
||||||
if (!data->pruned()) {
|
if (!data->pruned()) {
|
||||||
|
RTC_LOG(LS_INFO) << port->ToString() << ": Port ready.";
|
||||||
|
SignalPortReady(this, port);
|
||||||
port->KeepAliveUntilPruned();
|
port->KeepAliveUntilPruned();
|
||||||
// We postpone the signaling of any address ports to when the candidates
|
|
||||||
// allocation is done or the candidate allocation process has start for
|
|
||||||
// more than kMaxWaitMsBeforeSignalingAnyAddressPortsAndCandidates, and
|
|
||||||
// we check whether they are redundant or not (in
|
|
||||||
// SignalAnyAddressPortsAndCandidatesReadyIfNotRedundant). Otherwise,
|
|
||||||
// connectivity checks will be sent from these possibly redundant ports,
|
|
||||||
// likely also resulting in "prflx" candidate pairs being created on the
|
|
||||||
// other side if not pruned in time. The signaling of any address ports
|
|
||||||
// that are not redundant happens in
|
|
||||||
// SignalAnyAddressPortsAndCandidatesReadyIfNotRedundant.
|
|
||||||
//
|
|
||||||
// If adapter enumeration is disabled, these "any" address ports
|
|
||||||
// are all we'll get, so we can signal them immediately.
|
|
||||||
//
|
|
||||||
// Same logic applies to candidates below.
|
|
||||||
|
|
||||||
if (!IsAnyAddressPort(port) ||
|
|
||||||
(flags() & PORTALLOCATOR_DISABLE_ADAPTER_ENUMERATION)) {
|
|
||||||
RTC_LOG(INFO) << port->ToString() << ": Port ready.";
|
|
||||||
SignalPortReady(this, port);
|
|
||||||
data->set_signaled();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data->ready() && CheckCandidateFilter(c)) {
|
if (data->ready() && CheckCandidateFilter(c)) {
|
||||||
// See comment above about why we delay signaling candidates from "any
|
std::vector<Candidate> candidates;
|
||||||
// address" ports.
|
candidates.push_back(SanitizeRelatedAddress(c));
|
||||||
//
|
SignalCandidatesReady(this, candidates);
|
||||||
// For candidates gathered after the any address port is signaled, we will
|
|
||||||
// not perform the redundancy check anymore. Note that late candiates
|
|
||||||
// gathered from the any address port should be a srflx candidate from a
|
|
||||||
// late STUN binding response.
|
|
||||||
if (data->signaled()) {
|
|
||||||
std::vector<Candidate> candidates;
|
|
||||||
candidates.push_back(SanitizeRelatedAddress(c));
|
|
||||||
SignalCandidatesReady(this, candidates);
|
|
||||||
} else {
|
|
||||||
RTC_LOG(INFO) << "Candidate not signaled yet because it is from the "
|
|
||||||
"any address port: "
|
|
||||||
<< c.ToSensitiveString();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
RTC_LOG(LS_INFO) << "Discarding candidate because it doesn't match filter.";
|
RTC_LOG(LS_INFO) << "Discarding candidate because it doesn't match filter.";
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we have pruned any port, maybe need to signal port allocation done.
|
// If we have pruned any port, maybe need to signal port allocation done.
|
||||||
if (pruned) {
|
if (pruned) {
|
||||||
FireAllocationStatusSignalsIfNeeded();
|
MaybeSignalCandidatesAllocationDone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1020,7 +961,7 @@ bool BasicPortAllocatorSession::PruneTurnPorts(Port* newly_pairable_turn_port) {
|
|||||||
ComparePort(data.port(), best_turn_port) < 0) {
|
ComparePort(data.port(), best_turn_port) < 0) {
|
||||||
pruned = true;
|
pruned = true;
|
||||||
if (data.port() != newly_pairable_turn_port) {
|
if (data.port() != newly_pairable_turn_port) {
|
||||||
// These ports will be pruned in PrunePortsAndSignalCandidatesRemoval.
|
// These ports will be pruned in PrunePortsAndRemoveCandidates.
|
||||||
ports_to_prune.push_back(&data);
|
ports_to_prune.push_back(&data);
|
||||||
} else {
|
} else {
|
||||||
data.Prune();
|
data.Prune();
|
||||||
@ -1031,7 +972,7 @@ bool BasicPortAllocatorSession::PruneTurnPorts(Port* newly_pairable_turn_port) {
|
|||||||
if (!ports_to_prune.empty()) {
|
if (!ports_to_prune.empty()) {
|
||||||
RTC_LOG(LS_INFO) << "Prune " << ports_to_prune.size()
|
RTC_LOG(LS_INFO) << "Prune " << ports_to_prune.size()
|
||||||
<< " low-priority TURN ports";
|
<< " low-priority TURN ports";
|
||||||
PrunePortsAndSignalCandidatesRemoval(ports_to_prune);
|
PrunePortsAndRemoveCandidates(ports_to_prune);
|
||||||
}
|
}
|
||||||
return pruned;
|
return pruned;
|
||||||
}
|
}
|
||||||
@ -1047,7 +988,7 @@ void BasicPortAllocatorSession::OnPortComplete(Port* port) {
|
|||||||
RTC_LOG(LS_INFO) << port->ToString()
|
RTC_LOG(LS_INFO) << port->ToString()
|
||||||
<< ": Port completed gathering candidates.";
|
<< ": Port completed gathering candidates.";
|
||||||
PortData* data = FindPort(port);
|
PortData* data = FindPort(port);
|
||||||
RTC_DCHECK(data != nullptr);
|
RTC_DCHECK(data != NULL);
|
||||||
|
|
||||||
// Ignore any late signals.
|
// Ignore any late signals.
|
||||||
if (!data->inprogress()) {
|
if (!data->inprogress()) {
|
||||||
@ -1057,7 +998,7 @@ void BasicPortAllocatorSession::OnPortComplete(Port* port) {
|
|||||||
// Moving to COMPLETE state.
|
// Moving to COMPLETE state.
|
||||||
data->set_complete();
|
data->set_complete();
|
||||||
// Send candidate allocation complete signal if this was the last port.
|
// Send candidate allocation complete signal if this was the last port.
|
||||||
FireAllocationStatusSignalsIfNeeded();
|
MaybeSignalCandidatesAllocationDone();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BasicPortAllocatorSession::OnPortError(Port* port) {
|
void BasicPortAllocatorSession::OnPortError(Port* port) {
|
||||||
@ -1065,7 +1006,7 @@ void BasicPortAllocatorSession::OnPortError(Port* port) {
|
|||||||
RTC_LOG(LS_INFO) << port->ToString()
|
RTC_LOG(LS_INFO) << port->ToString()
|
||||||
<< ": Port encountered error while gathering candidates.";
|
<< ": Port encountered error while gathering candidates.";
|
||||||
PortData* data = FindPort(port);
|
PortData* data = FindPort(port);
|
||||||
RTC_DCHECK(data != nullptr);
|
RTC_DCHECK(data != NULL);
|
||||||
// We might have already given up on this port and stopped it.
|
// We might have already given up on this port and stopped it.
|
||||||
if (!data->inprogress()) {
|
if (!data->inprogress()) {
|
||||||
return;
|
return;
|
||||||
@ -1075,7 +1016,7 @@ void BasicPortAllocatorSession::OnPortError(Port* port) {
|
|||||||
// But this signal itself is generic.
|
// But this signal itself is generic.
|
||||||
data->set_error();
|
data->set_error();
|
||||||
// Send candidate allocation complete signal if this was the last port.
|
// Send candidate allocation complete signal if this was the last port.
|
||||||
FireAllocationStatusSignalsIfNeeded();
|
MaybeSignalCandidatesAllocationDone();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BasicPortAllocatorSession::CheckCandidateFilter(const Candidate& c) const {
|
bool BasicPortAllocatorSession::CheckCandidateFilter(const Candidate& c) const {
|
||||||
@ -1119,34 +1060,24 @@ bool BasicPortAllocatorSession::CandidatePairable(const Candidate& c,
|
|||||||
// prevent even default IP addresses from leaking), we still don't want to
|
// prevent even default IP addresses from leaking), we still don't want to
|
||||||
// ping from them, even if device enumeration is disabled. Thus, we check for
|
// ping from them, even if device enumeration is disabled. Thus, we check for
|
||||||
// both device enumeration and host candidates being disabled.
|
// both device enumeration and host candidates being disabled.
|
||||||
bool candidate_has_any_address = c.address().IsAnyIP();
|
bool network_enumeration_disabled = c.address().IsAnyIP();
|
||||||
bool can_ping_from_candidate =
|
bool can_ping_from_candidate =
|
||||||
(port->SharedSocket() || c.protocol() == TCP_PROTOCOL_NAME);
|
(port->SharedSocket() || c.protocol() == TCP_PROTOCOL_NAME);
|
||||||
bool host_candidates_disabled = !(candidate_filter_ & CF_HOST);
|
bool host_candidates_disabled = !(candidate_filter_ & CF_HOST);
|
||||||
|
|
||||||
return candidate_signalable ||
|
return candidate_signalable ||
|
||||||
(candidate_has_any_address && can_ping_from_candidate &&
|
(network_enumeration_disabled && can_ping_from_candidate &&
|
||||||
!host_candidates_disabled);
|
!host_candidates_disabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BasicPortAllocatorSession::OnPortAllocationComplete(
|
void BasicPortAllocatorSession::OnPortAllocationComplete(
|
||||||
AllocationSequence* seq) {
|
AllocationSequence* seq) {
|
||||||
// Send candidate allocation complete signal if all ports are done.
|
// Send candidate allocation complete signal if all ports are done.
|
||||||
FireAllocationStatusSignalsIfNeeded();
|
MaybeSignalCandidatesAllocationDone();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BasicPortAllocatorSession::FireAllocationStatusSignalsIfNeeded() {
|
void BasicPortAllocatorSession::MaybeSignalCandidatesAllocationDone() {
|
||||||
if (CandidatesAllocationDone()) {
|
if (CandidatesAllocationDone()) {
|
||||||
// Now that allocation is done, we can surface any ports bound to the "any"
|
|
||||||
// address if they're not redundant (if they don't have the same address as
|
|
||||||
// a port bound to a specific interface). We don't surface them as soon as
|
|
||||||
// they're gathered because we may not know yet whether they're redundant.
|
|
||||||
//
|
|
||||||
// This also happens after a timeout of 2 seconds (see comment in
|
|
||||||
// DoAllocate); if allocation completes first we clear that timer since
|
|
||||||
// it's not needed.
|
|
||||||
network_thread_->Clear(this, MSG_SIGNAL_ANY_ADDRESS_PORTS);
|
|
||||||
SignalAnyAddressPortsAndCandidatesReadyIfNotRedundant();
|
|
||||||
if (pooled()) {
|
if (pooled()) {
|
||||||
RTC_LOG(LS_INFO) << "All candidates gathered for pooled session.";
|
RTC_LOG(LS_INFO) << "All candidates gathered for pooled session.";
|
||||||
} else {
|
} else {
|
||||||
@ -1157,96 +1088,7 @@ void BasicPortAllocatorSession::FireAllocationStatusSignalsIfNeeded() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We detect the redundancy in any address ports as follows:
|
void BasicPortAllocatorSession::OnPortDestroyed(PortInterface* port) {
|
||||||
//
|
|
||||||
// 1. Delay the signaling of all any address ports and candidates gathered from
|
|
||||||
// these ports, which happens in OnCandidateReady.
|
|
||||||
//
|
|
||||||
// 2. For all non-any address ports, collect the IPs of their candidates
|
|
||||||
// (ignoring "active" TCP candidates, since no sockets are created for them
|
|
||||||
// until a connection is made and there's no guarantee they'll work).
|
|
||||||
//
|
|
||||||
// 3. For each any address port, compare their candidates to the existing IPs
|
|
||||||
// collected from step 2, and this port can be signaled if it has candidates
|
|
||||||
// with unseen IPs.
|
|
||||||
void BasicPortAllocatorSession::
|
|
||||||
SignalAnyAddressPortsAndCandidatesReadyIfNotRedundant() {
|
|
||||||
// Note that this is called either when allocation completes, or after a
|
|
||||||
// timeout, so some ports may still be waiting for STUN transactions to
|
|
||||||
// finish.
|
|
||||||
//
|
|
||||||
// First, get a list of all "any address" ports that have not yet been
|
|
||||||
// signaled, and a list of candidate IP addresses from all other ports.
|
|
||||||
std::vector<PortData*> maybe_signalable_any_address_ports;
|
|
||||||
std::set<rtc::IPAddress> ips_from_non_any_address_ports;
|
|
||||||
for (PortData& port_data : ports_) {
|
|
||||||
if (!port_data.ready()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (IsAnyAddressPort(port_data.port())) {
|
|
||||||
if (!port_data.signaled()) {
|
|
||||||
maybe_signalable_any_address_ports.push_back(&port_data);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (const Candidate& c : port_data.port()->Candidates()) {
|
|
||||||
// If the port of the candidate is |DISCARD_PORT| (9), this is an
|
|
||||||
// "active" TCP candidate and it doesn't mean we actually bound a
|
|
||||||
// socket to this address, so ignore it.
|
|
||||||
if (c.address().port() != DISCARD_PORT) {
|
|
||||||
ips_from_non_any_address_ports.insert(c.address().ipaddr());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Now signal "any" address ports that have a unique address, and prune any
|
|
||||||
// that don't.
|
|
||||||
std::vector<PortData*> signalable_any_address_ports;
|
|
||||||
std::vector<PortData*> prunable_any_address_ports;
|
|
||||||
std::vector<Candidate> signalable_candidates_from_any_address_ports;
|
|
||||||
for (PortData* port_data : maybe_signalable_any_address_ports) {
|
|
||||||
bool port_signalable = false;
|
|
||||||
for (const Candidate& c : port_data->port()->Candidates()) {
|
|
||||||
if (!CandidatePairable(c, port_data->port()) ||
|
|
||||||
ips_from_non_any_address_ports.count(c.address().ipaddr())) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// Even when a port is bound to the "any" address, it should normally
|
|
||||||
// still have an associated IP (determined by calling "connect" and then
|
|
||||||
// "getsockaddr"). Though sometimes even this fails (meaning |is_any_ip|
|
|
||||||
// will be true), and thus we have no way of knowing whether the port is
|
|
||||||
// redundant or not. In that case, we'll use the port if we have
|
|
||||||
// *no* ports bound to specific addresses. This is needed for corner
|
|
||||||
// cases such as bugs.webrtc.org/7798.
|
|
||||||
bool is_any_ip = rtc::IPIsAny(c.address().ipaddr());
|
|
||||||
if (is_any_ip && !ips_from_non_any_address_ports.empty()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
port_signalable = true;
|
|
||||||
// Still need to check the candidiate filter and sanitize the related
|
|
||||||
// address before signaling the candidate itself.
|
|
||||||
if (CheckCandidateFilter(c)) {
|
|
||||||
signalable_candidates_from_any_address_ports.push_back(
|
|
||||||
SanitizeRelatedAddress(c));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (port_signalable) {
|
|
||||||
signalable_any_address_ports.push_back(port_data);
|
|
||||||
} else {
|
|
||||||
prunable_any_address_ports.push_back(port_data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PrunePorts(prunable_any_address_ports);
|
|
||||||
for (PortData* port_data : signalable_any_address_ports) {
|
|
||||||
RTC_LOG(INFO) << port_data->port()->ToString() << ": Port ready.";
|
|
||||||
SignalPortReady(this, port_data->port());
|
|
||||||
port_data->set_signaled();
|
|
||||||
}
|
|
||||||
RTC_LOG(INFO) << "Signaling candidates from the any address ports.";
|
|
||||||
SignalCandidatesReady(this, signalable_candidates_from_any_address_ports);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BasicPortAllocatorSession::OnPortDestroyed(
|
|
||||||
PortInterface* port) {
|
|
||||||
RTC_DCHECK(rtc::Thread::Current() == network_thread_);
|
RTC_DCHECK(rtc::Thread::Current() == network_thread_);
|
||||||
for (std::vector<PortData>::iterator iter = ports_.begin();
|
for (std::vector<PortData>::iterator iter = ports_.begin();
|
||||||
iter != ports_.end(); ++iter) {
|
iter != ports_.end(); ++iter) {
|
||||||
@ -1268,7 +1110,7 @@ BasicPortAllocatorSession::PortData* BasicPortAllocatorSession::FindPort(
|
|||||||
return &*it;
|
return &*it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<BasicPortAllocatorSession::PortData*>
|
std::vector<BasicPortAllocatorSession::PortData*>
|
||||||
@ -1285,7 +1127,7 @@ BasicPortAllocatorSession::GetUnprunedPorts(
|
|||||||
return unpruned_ports;
|
return unpruned_ports;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Candidate> BasicPortAllocatorSession::PrunePorts(
|
void BasicPortAllocatorSession::PrunePortsAndRemoveCandidates(
|
||||||
const std::vector<PortData*>& port_data_list) {
|
const std::vector<PortData*>& port_data_list) {
|
||||||
std::vector<PortInterface*> pruned_ports;
|
std::vector<PortInterface*> pruned_ports;
|
||||||
std::vector<Candidate> removed_candidates;
|
std::vector<Candidate> removed_candidates;
|
||||||
@ -1303,12 +1145,6 @@ std::vector<Candidate> BasicPortAllocatorSession::PrunePorts(
|
|||||||
if (!pruned_ports.empty()) {
|
if (!pruned_ports.empty()) {
|
||||||
SignalPortsPruned(this, pruned_ports);
|
SignalPortsPruned(this, pruned_ports);
|
||||||
}
|
}
|
||||||
return removed_candidates;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BasicPortAllocatorSession::PrunePortsAndSignalCandidatesRemoval(
|
|
||||||
const std::vector<PortData*>& port_data_list) {
|
|
||||||
std::vector<Candidate> removed_candidates = PrunePorts(port_data_list);
|
|
||||||
if (!removed_candidates.empty()) {
|
if (!removed_candidates.empty()) {
|
||||||
RTC_LOG(LS_INFO) << "Removed " << removed_candidates.size()
|
RTC_LOG(LS_INFO) << "Removed " << removed_candidates.size()
|
||||||
<< " candidates";
|
<< " candidates";
|
||||||
@ -1328,7 +1164,7 @@ AllocationSequence::AllocationSequence(BasicPortAllocatorSession* session,
|
|||||||
state_(kInit),
|
state_(kInit),
|
||||||
flags_(flags),
|
flags_(flags),
|
||||||
udp_socket_(),
|
udp_socket_(),
|
||||||
udp_port_(nullptr),
|
udp_port_(NULL),
|
||||||
phase_(0) {}
|
phase_(0) {}
|
||||||
|
|
||||||
void AllocationSequence::Init() {
|
void AllocationSequence::Init() {
|
||||||
@ -1340,13 +1176,13 @@ void AllocationSequence::Init() {
|
|||||||
udp_socket_->SignalReadPacket.connect(this,
|
udp_socket_->SignalReadPacket.connect(this,
|
||||||
&AllocationSequence::OnReadPacket);
|
&AllocationSequence::OnReadPacket);
|
||||||
}
|
}
|
||||||
// Continuing if |udp_socket_| is null, as local TCP and RelayPort using
|
// Continuing if |udp_socket_| is NULL, as local TCP and RelayPort using TCP
|
||||||
// TCP are next available options to setup a communication channel.
|
// are next available options to setup a communication channel.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AllocationSequence::Clear() {
|
void AllocationSequence::Clear() {
|
||||||
udp_port_ = nullptr;
|
udp_port_ = NULL;
|
||||||
relay_ports_.clear();
|
relay_ports_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1483,7 +1319,7 @@ void AllocationSequence::CreateUDPPorts() {
|
|||||||
|
|
||||||
// TODO(mallinath) - Remove UDPPort creating socket after shared socket
|
// TODO(mallinath) - Remove UDPPort creating socket after shared socket
|
||||||
// is enabled completely.
|
// is enabled completely.
|
||||||
UDPPort* port = nullptr;
|
UDPPort* port = NULL;
|
||||||
bool emit_local_candidate_for_anyaddress =
|
bool emit_local_candidate_for_anyaddress =
|
||||||
!IsFlagSet(PORTALLOCATOR_DISABLE_DEFAULT_LOCAL_CANDIDATE);
|
!IsFlagSet(PORTALLOCATOR_DISABLE_DEFAULT_LOCAL_CANDIDATE);
|
||||||
if (IsFlagSet(PORTALLOCATOR_ENABLE_SHARED_SOCKET) && udp_socket_) {
|
if (IsFlagSet(PORTALLOCATOR_ENABLE_SHARED_SOCKET) && udp_socket_) {
|
||||||
@ -1691,7 +1527,7 @@ void AllocationSequence::CreateTurnPort(const RelayServerConfig& config) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RTC_DCHECK(port != nullptr);
|
RTC_DCHECK(port != NULL);
|
||||||
session_->AddAllocatedPort(port.release(), this, true);
|
session_->AddAllocatedPort(port.release(), this, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1737,7 +1573,7 @@ void AllocationSequence::OnReadPacket(rtc::AsyncPacketSocket* socket,
|
|||||||
|
|
||||||
void AllocationSequence::OnPortDestroyed(PortInterface* port) {
|
void AllocationSequence::OnPortDestroyed(PortInterface* port) {
|
||||||
if (udp_port_ == port) {
|
if (udp_port_ == port) {
|
||||||
udp_port_ = nullptr;
|
udp_port_ = NULL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,10 +168,6 @@ class BasicPortAllocatorSession : public PortAllocatorSession,
|
|||||||
bool error() const { return state_ == STATE_ERROR; }
|
bool error() const { return state_ == STATE_ERROR; }
|
||||||
bool pruned() const { return state_ == STATE_PRUNED; }
|
bool pruned() const { return state_ == STATE_PRUNED; }
|
||||||
bool inprogress() const { return state_ == STATE_INPROGRESS; }
|
bool inprogress() const { return state_ == STATE_INPROGRESS; }
|
||||||
// True if this port has been fired in SignalPortReady. This may be false
|
|
||||||
// even if ready() is true if the port was bound to the "any" address; see
|
|
||||||
// comment above SignalAnyAddressPortsAndCandidatesReadyIfNotRedundant.
|
|
||||||
bool signaled() const { return signaled_; }
|
|
||||||
// Returns true if this port is ready to be used.
|
// Returns true if this port is ready to be used.
|
||||||
bool ready() const {
|
bool ready() const {
|
||||||
return has_pairable_candidate_ && state_ != STATE_ERROR &&
|
return has_pairable_candidate_ && state_ != STATE_ERROR &&
|
||||||
@ -195,7 +191,6 @@ class BasicPortAllocatorSession : public PortAllocatorSession,
|
|||||||
RTC_DCHECK(state_ == STATE_INPROGRESS);
|
RTC_DCHECK(state_ == STATE_INPROGRESS);
|
||||||
state_ = STATE_ERROR;
|
state_ = STATE_ERROR;
|
||||||
}
|
}
|
||||||
void set_signaled() { signaled_ = true; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum State {
|
enum State {
|
||||||
@ -208,7 +203,6 @@ class BasicPortAllocatorSession : public PortAllocatorSession,
|
|||||||
Port* port_ = nullptr;
|
Port* port_ = nullptr;
|
||||||
AllocationSequence* sequence_ = nullptr;
|
AllocationSequence* sequence_ = nullptr;
|
||||||
bool has_pairable_candidate_ = false;
|
bool has_pairable_candidate_ = false;
|
||||||
bool signaled_ = false;
|
|
||||||
State state_ = STATE_INPROGRESS;
|
State state_ = STATE_INPROGRESS;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -230,6 +224,7 @@ class BasicPortAllocatorSession : public PortAllocatorSession,
|
|||||||
void OnPortError(Port* port);
|
void OnPortError(Port* port);
|
||||||
void OnProtocolEnabled(AllocationSequence* seq, ProtocolType proto);
|
void OnProtocolEnabled(AllocationSequence* seq, ProtocolType proto);
|
||||||
void OnPortDestroyed(PortInterface* port);
|
void OnPortDestroyed(PortInterface* port);
|
||||||
|
void MaybeSignalCandidatesAllocationDone();
|
||||||
void OnPortAllocationComplete(AllocationSequence* seq);
|
void OnPortAllocationComplete(AllocationSequence* seq);
|
||||||
PortData* FindPort(Port* port);
|
PortData* FindPort(Port* port);
|
||||||
std::vector<rtc::Network*> GetNetworks();
|
std::vector<rtc::Network*> GetNetworks();
|
||||||
@ -246,13 +241,9 @@ class BasicPortAllocatorSession : public PortAllocatorSession,
|
|||||||
|
|
||||||
std::vector<PortData*> GetUnprunedPorts(
|
std::vector<PortData*> GetUnprunedPorts(
|
||||||
const std::vector<rtc::Network*>& networks);
|
const std::vector<rtc::Network*>& networks);
|
||||||
// Prunes ports and removes candidates gathered from these ports locally. The
|
|
||||||
// list of the removed candidates are returned.
|
|
||||||
std::vector<Candidate> PrunePorts(
|
|
||||||
const std::vector<PortData*>& port_data_list);
|
|
||||||
// Prunes ports and signal the remote side to remove the candidates that
|
// Prunes ports and signal the remote side to remove the candidates that
|
||||||
// were previously signaled from these ports.
|
// were previously signaled from these ports.
|
||||||
void PrunePortsAndSignalCandidatesRemoval(
|
void PrunePortsAndRemoveCandidates(
|
||||||
const std::vector<PortData*>& port_data_list);
|
const std::vector<PortData*>& port_data_list);
|
||||||
// Gets filtered and sanitized candidates generated from a port and
|
// Gets filtered and sanitized candidates generated from a port and
|
||||||
// append to |candidates|.
|
// append to |candidates|.
|
||||||
@ -261,12 +252,6 @@ class BasicPortAllocatorSession : public PortAllocatorSession,
|
|||||||
Port* GetBestTurnPortForNetwork(const std::string& network_name) const;
|
Port* GetBestTurnPortForNetwork(const std::string& network_name) const;
|
||||||
// Returns true if at least one TURN port is pruned.
|
// Returns true if at least one TURN port is pruned.
|
||||||
bool PruneTurnPorts(Port* newly_pairable_turn_port);
|
bool PruneTurnPorts(Port* newly_pairable_turn_port);
|
||||||
// Fires signals related to aggregate status update in the allocation,
|
|
||||||
// including candidates allocation done, and any address ports and their
|
|
||||||
// candidates ready.
|
|
||||||
void FireAllocationStatusSignalsIfNeeded();
|
|
||||||
// TODO(qingsi): Rename "any address" to "wildcard address" in p2p/.
|
|
||||||
void SignalAnyAddressPortsAndCandidatesReadyIfNotRedundant();
|
|
||||||
|
|
||||||
BasicPortAllocator* allocator_;
|
BasicPortAllocator* allocator_;
|
||||||
rtc::Thread* network_thread_;
|
rtc::Thread* network_thread_;
|
||||||
|
@ -1148,20 +1148,15 @@ TEST_F(BasicPortAllocatorTest, TestGetAllPortsWithOneSecondStepDelay) {
|
|||||||
allocator_->set_step_delay(kDefaultStepDelay);
|
allocator_->set_step_delay(kDefaultStepDelay);
|
||||||
ASSERT_TRUE(CreateSession(ICE_CANDIDATE_COMPONENT_RTP));
|
ASSERT_TRUE(CreateSession(ICE_CANDIDATE_COMPONENT_RTP));
|
||||||
session_->StartGettingPorts();
|
session_->StartGettingPorts();
|
||||||
// Host and STUN candidates from kClientAddr.
|
|
||||||
ASSERT_EQ_SIMULATED_WAIT(2U, candidates_.size(), 1000, fake_clock);
|
ASSERT_EQ_SIMULATED_WAIT(2U, candidates_.size(), 1000, fake_clock);
|
||||||
// UDP and STUN ports on kClientAddr.
|
|
||||||
EXPECT_EQ(2U, ports_.size());
|
EXPECT_EQ(2U, ports_.size());
|
||||||
// Host, STUN and relay candidates from kClientAddr.
|
|
||||||
ASSERT_EQ_SIMULATED_WAIT(6U, candidates_.size(), 2000, fake_clock);
|
ASSERT_EQ_SIMULATED_WAIT(6U, candidates_.size(), 2000, fake_clock);
|
||||||
// UDP, STUN and relay ports on kClientAddr.
|
|
||||||
EXPECT_EQ(3U, ports_.size());
|
EXPECT_EQ(3U, ports_.size());
|
||||||
EXPECT_TRUE(HasCandidate(candidates_, "relay", "udp", kRelayUdpIntAddr));
|
EXPECT_TRUE(HasCandidate(candidates_, "relay", "udp", kRelayUdpIntAddr));
|
||||||
EXPECT_TRUE(HasCandidate(candidates_, "relay", "udp", kRelayUdpExtAddr));
|
EXPECT_TRUE(HasCandidate(candidates_, "relay", "udp", kRelayUdpExtAddr));
|
||||||
EXPECT_TRUE(HasCandidate(candidates_, "relay", "tcp", kRelayTcpIntAddr));
|
EXPECT_TRUE(HasCandidate(candidates_, "relay", "tcp", kRelayTcpIntAddr));
|
||||||
EXPECT_TRUE(
|
EXPECT_TRUE(
|
||||||
HasCandidate(candidates_, "relay", "ssltcp", kRelaySslTcpIntAddr));
|
HasCandidate(candidates_, "relay", "ssltcp", kRelaySslTcpIntAddr));
|
||||||
// One more TCP candidate from kClientAddr.
|
|
||||||
ASSERT_EQ_SIMULATED_WAIT(7U, candidates_.size(), 1500, fake_clock);
|
ASSERT_EQ_SIMULATED_WAIT(7U, candidates_.size(), 1500, fake_clock);
|
||||||
EXPECT_TRUE(HasCandidate(candidates_, "local", "tcp", kClientAddr));
|
EXPECT_TRUE(HasCandidate(candidates_, "local", "tcp", kClientAddr));
|
||||||
EXPECT_EQ(4U, ports_.size());
|
EXPECT_EQ(4U, ports_.size());
|
||||||
@ -1471,20 +1466,17 @@ TEST_F(BasicPortAllocatorTest, TestGetAllPortsNoSockets) {
|
|||||||
// Testing STUN timeout.
|
// Testing STUN timeout.
|
||||||
TEST_F(BasicPortAllocatorTest, TestGetAllPortsNoUdpAllowed) {
|
TEST_F(BasicPortAllocatorTest, TestGetAllPortsNoUdpAllowed) {
|
||||||
fss_->AddRule(false, rtc::FP_UDP, rtc::FD_ANY, kClientAddr);
|
fss_->AddRule(false, rtc::FP_UDP, rtc::FD_ANY, kClientAddr);
|
||||||
fss_->AddRule(false, rtc::FP_UDP, rtc::FD_ANY, kAnyAddr);
|
|
||||||
AddInterface(kClientAddr);
|
AddInterface(kClientAddr);
|
||||||
ASSERT_TRUE(CreateSession(ICE_CANDIDATE_COMPONENT_RTP));
|
ASSERT_TRUE(CreateSession(ICE_CANDIDATE_COMPONENT_RTP));
|
||||||
session_->StartGettingPorts();
|
session_->StartGettingPorts();
|
||||||
EXPECT_EQ_SIMULATED_WAIT(2U, candidates_.size(), kDefaultAllocationTimeout,
|
EXPECT_EQ_SIMULATED_WAIT(2U, candidates_.size(), kDefaultAllocationTimeout,
|
||||||
fake_clock);
|
fake_clock);
|
||||||
// UDP and TCP ports on kClientAddr.
|
|
||||||
EXPECT_EQ(2U, ports_.size());
|
EXPECT_EQ(2U, ports_.size());
|
||||||
EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", kClientAddr));
|
EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", kClientAddr));
|
||||||
EXPECT_TRUE(HasCandidate(candidates_, "local", "tcp", kClientAddr));
|
EXPECT_TRUE(HasCandidate(candidates_, "local", "tcp", kClientAddr));
|
||||||
// RelayPort connection timeout is 3sec. TCP connection with RelayServer
|
// RelayPort connection timeout is 3sec. TCP connection with RelayServer
|
||||||
// will be tried after about 3 seconds.
|
// will be tried after about 3 seconds.
|
||||||
EXPECT_EQ_SIMULATED_WAIT(6U, candidates_.size(), 3500, fake_clock);
|
EXPECT_EQ_SIMULATED_WAIT(6U, candidates_.size(), 3500, fake_clock);
|
||||||
// UDP, TCP and relay ports on kClientAddr.
|
|
||||||
EXPECT_EQ(3U, ports_.size());
|
EXPECT_EQ(3U, ports_.size());
|
||||||
EXPECT_TRUE(HasCandidate(candidates_, "relay", "udp", kRelayUdpIntAddr));
|
EXPECT_TRUE(HasCandidate(candidates_, "relay", "udp", kRelayUdpIntAddr));
|
||||||
EXPECT_TRUE(HasCandidate(candidates_, "relay", "tcp", kRelayTcpIntAddr));
|
EXPECT_TRUE(HasCandidate(candidates_, "relay", "tcp", kRelayTcpIntAddr));
|
||||||
@ -1991,14 +1983,12 @@ TEST_F(BasicPortAllocatorTest, TestSharedSocketNoUdpAllowed) {
|
|||||||
PORTALLOCATOR_DISABLE_TCP |
|
PORTALLOCATOR_DISABLE_TCP |
|
||||||
PORTALLOCATOR_ENABLE_SHARED_SOCKET);
|
PORTALLOCATOR_ENABLE_SHARED_SOCKET);
|
||||||
fss_->AddRule(false, rtc::FP_UDP, rtc::FD_ANY, kClientAddr);
|
fss_->AddRule(false, rtc::FP_UDP, rtc::FD_ANY, kClientAddr);
|
||||||
fss_->AddRule(false, rtc::FP_UDP, rtc::FD_ANY, kAnyAddr);
|
|
||||||
AddInterface(kClientAddr);
|
AddInterface(kClientAddr);
|
||||||
ASSERT_TRUE(CreateSession(ICE_CANDIDATE_COMPONENT_RTP));
|
ASSERT_TRUE(CreateSession(ICE_CANDIDATE_COMPONENT_RTP));
|
||||||
session_->StartGettingPorts();
|
session_->StartGettingPorts();
|
||||||
ASSERT_EQ_SIMULATED_WAIT(1U, candidates_.size(), kDefaultAllocationTimeout,
|
ASSERT_EQ_SIMULATED_WAIT(1U, ports_.size(), kDefaultAllocationTimeout,
|
||||||
fake_clock);
|
fake_clock);
|
||||||
// UDP ports on kClientAddr.
|
EXPECT_EQ(1U, candidates_.size());
|
||||||
EXPECT_EQ(1U, ports_.size());
|
|
||||||
EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", kClientAddr));
|
EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", kClientAddr));
|
||||||
// STUN timeout is 9.5sec. We need to wait to get candidate done signal.
|
// STUN timeout is 9.5sec. We need to wait to get candidate done signal.
|
||||||
EXPECT_TRUE_SIMULATED_WAIT(candidate_allocation_done_, kStunTimeoutMs,
|
EXPECT_TRUE_SIMULATED_WAIT(candidate_allocation_done_, kStunTimeoutMs,
|
||||||
@ -2006,137 +1996,6 @@ TEST_F(BasicPortAllocatorTest, TestSharedSocketNoUdpAllowed) {
|
|||||||
EXPECT_EQ(1U, candidates_.size());
|
EXPECT_EQ(1U, candidates_.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that any address ports that are redundant do not surface.
|
|
||||||
TEST_F(BasicPortAllocatorTest, RedundantAnyAddressPortsDoNotSurface) {
|
|
||||||
allocator().set_flags(allocator().flags() | PORTALLOCATOR_DISABLE_RELAY |
|
|
||||||
PORTALLOCATOR_DISABLE_TCP |
|
|
||||||
PORTALLOCATOR_ENABLE_SHARED_SOCKET);
|
|
||||||
AddInterface(kClientAddr);
|
|
||||||
// The any address ports will be duplicates of kClientAddr.
|
|
||||||
vss_->SetAlternativeLocalAddress(kAnyAddr.ipaddr(), kClientAddr.ipaddr());
|
|
||||||
ASSERT_TRUE(CreateSession(ICE_CANDIDATE_COMPONENT_RTP));
|
|
||||||
session_->StartGettingPorts();
|
|
||||||
EXPECT_TRUE_SIMULATED_WAIT(candidate_allocation_done_, kStunTimeoutMs,
|
|
||||||
fake_clock);
|
|
||||||
EXPECT_EQ(1U, ports_.size());
|
|
||||||
EXPECT_EQ(1, CountPorts(ports_, "local", PROTO_UDP, kClientAddr));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test that candidates from the any address ports are not pruned if the
|
|
||||||
// explicit binding to enumerated networks fails.
|
|
||||||
TEST_F(BasicPortAllocatorTest,
|
|
||||||
CandidatesFromAnyAddressPortsCanSurfaceWhenExplicitBindingFails) {
|
|
||||||
allocator().set_flags(allocator().flags() | PORTALLOCATOR_DISABLE_RELAY |
|
|
||||||
PORTALLOCATOR_DISABLE_TCP |
|
|
||||||
PORTALLOCATOR_ENABLE_SHARED_SOCKET);
|
|
||||||
AddInterface(kClientAddr);
|
|
||||||
fss_->SetUnbindableIps({kClientAddr.ipaddr()});
|
|
||||||
// The any address ports will be duplicates of kClientAddr, but the explict
|
|
||||||
// binding will fail.
|
|
||||||
vss_->SetAlternativeLocalAddress(kAnyAddr.ipaddr(), kClientAddr.ipaddr());
|
|
||||||
ASSERT_TRUE(CreateSession(ICE_CANDIDATE_COMPONENT_RTP));
|
|
||||||
session_->StartGettingPorts();
|
|
||||||
EXPECT_TRUE_SIMULATED_WAIT(candidate_allocation_done_, kStunTimeoutMs,
|
|
||||||
fake_clock);
|
|
||||||
EXPECT_EQ(1, CountPorts(ports_, "local", PROTO_UDP, kAnyAddr));
|
|
||||||
EXPECT_EQ(1U, candidates_.size());
|
|
||||||
EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", kClientAddr));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test that for an endpoint whose network enumeration only reveals one address
|
|
||||||
// (kClientAddr), it can observe a different address when binding to the "any"
|
|
||||||
// address. BasicPortAllocator should detect this and surface candidates for
|
|
||||||
// each address.
|
|
||||||
TEST_F(BasicPortAllocatorTest,
|
|
||||||
CandidatesFromAnyAddressPortsCanSurfaceIfNotRedundant) {
|
|
||||||
allocator().set_flags(allocator().flags() | PORTALLOCATOR_DISABLE_RELAY |
|
|
||||||
PORTALLOCATOR_DISABLE_TCP |
|
|
||||||
PORTALLOCATOR_ENABLE_SHARED_SOCKET);
|
|
||||||
AddInterface(kClientAddr);
|
|
||||||
// When bound to the any address, the port allocator should discover the
|
|
||||||
// alternative local address.
|
|
||||||
vss_->SetAlternativeLocalAddress(kAnyAddr.ipaddr(), kClientAddr2.ipaddr());
|
|
||||||
ASSERT_TRUE(CreateSession(ICE_CANDIDATE_COMPONENT_RTP));
|
|
||||||
session_->StartGettingPorts();
|
|
||||||
EXPECT_TRUE_SIMULATED_WAIT(candidate_allocation_done_, kStunTimeoutMs,
|
|
||||||
fake_clock);
|
|
||||||
EXPECT_EQ(1, CountPorts(ports_, "local", PROTO_UDP, kAnyAddr));
|
|
||||||
EXPECT_EQ(2U, candidates_.size());
|
|
||||||
EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", kClientAddr));
|
|
||||||
EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", kClientAddr2));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test that any address ports and their candidates are eventually signaled
|
|
||||||
// after the maximum wait interval for the completion of candidate allocation,
|
|
||||||
// when the any address ports and candidates are not redundant.
|
|
||||||
TEST_F(BasicPortAllocatorTest,
|
|
||||||
GetAnyAddressPortsAfterMaximumWaitForCandidateAllocationDone) {
|
|
||||||
ResetWithTurnServersNoNat(kTurnUdpIntAddr, rtc::SocketAddress());
|
|
||||||
AddInterface(kClientAddr);
|
|
||||||
vss_->SetAlternativeLocalAddress(kAnyAddr.ipaddr(), kClientAddr2.ipaddr());
|
|
||||||
// STUN binding request and TURN allocation request will time out.
|
|
||||||
fss_->AddRule(false, rtc::FP_UDP, rtc::FD_ANY, kClientAddr);
|
|
||||||
ASSERT_TRUE(CreateSession(ICE_CANDIDATE_COMPONENT_RTP));
|
|
||||||
session_->StartGettingPorts();
|
|
||||||
SIMULATED_WAIT(false, kMaxWaitMsBeforeSignalingAnyAddressPortsAndCandidates,
|
|
||||||
fake_clock);
|
|
||||||
EXPECT_EQ(2U, candidates_.size());
|
|
||||||
EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", kClientAddr));
|
|
||||||
EXPECT_TRUE(HasCandidate(candidates_, "local", "tcp", kClientAddr));
|
|
||||||
SIMULATED_WAIT(false, 1, fake_clock);
|
|
||||||
EXPECT_FALSE(candidate_allocation_done_);
|
|
||||||
// Candidates from the any address ports.
|
|
||||||
EXPECT_EQ(6U, candidates_.size());
|
|
||||||
EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", kClientAddr2));
|
|
||||||
EXPECT_TRUE(HasCandidate(candidates_, "stun", "udp", kClientAddr2));
|
|
||||||
EXPECT_TRUE(HasCandidate(candidates_, "relay", "udp", kTurnUdpExtAddr));
|
|
||||||
EXPECT_TRUE(HasCandidate(candidates_, "local", "tcp", kClientAddr2));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test that the TCP port with the wildcard address is signaled if no ports are
|
|
||||||
// bound to enuemrated networks.
|
|
||||||
TEST_F(BasicPortAllocatorTest,
|
|
||||||
GetAnyAddressTcpPortWhenNoPortsBoundToEnumeratedNetworks) {
|
|
||||||
ResetWithTurnServersNoNat(kTurnUdpIntAddr, rtc::SocketAddress());
|
|
||||||
AddInterface(kClientAddr);
|
|
||||||
fss_->SetUnbindableIps({kClientAddr.ipaddr()});
|
|
||||||
ASSERT_TRUE(CreateSession(ICE_CANDIDATE_COMPONENT_RTP));
|
|
||||||
session_->StartGettingPorts();
|
|
||||||
SIMULATED_WAIT(false,
|
|
||||||
kMaxWaitMsBeforeSignalingAnyAddressPortsAndCandidates + 1,
|
|
||||||
fake_clock);
|
|
||||||
EXPECT_EQ(1, CountPorts(ports_, "local", PROTO_TCP, kAnyAddr));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test that the STUN candidate from the any address port can still surface, if
|
|
||||||
// it is gathered after this port is signaled, .
|
|
||||||
TEST_F(BasicPortAllocatorTest,
|
|
||||||
StunCandidateFromAnyAddressPortsGatheredLateCanBeSignaled) {
|
|
||||||
ResetWithTurnServersNoNat(kTurnUdpIntAddr, rtc::SocketAddress());
|
|
||||||
AddInterface(kClientAddr);
|
|
||||||
vss_->SetAlternativeLocalAddress(kAnyAddr.ipaddr(), kClientAddr2.ipaddr());
|
|
||||||
fss_->AddRule(false, rtc::FP_UDP, rtc::FD_ANY, kClientAddr);
|
|
||||||
fss_->AddRule(false, rtc::FP_UDP, rtc::FD_ANY, kClientAddr2);
|
|
||||||
ASSERT_TRUE(CreateSession(ICE_CANDIDATE_COMPONENT_RTP));
|
|
||||||
session_->StartGettingPorts();
|
|
||||||
SIMULATED_WAIT(false,
|
|
||||||
kMaxWaitMsBeforeSignalingAnyAddressPortsAndCandidates + 1000,
|
|
||||||
fake_clock);
|
|
||||||
EXPECT_FALSE(candidate_allocation_done_);
|
|
||||||
EXPECT_EQ(4U, candidates_.size());
|
|
||||||
EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", kClientAddr));
|
|
||||||
EXPECT_TRUE(HasCandidate(candidates_, "local", "tcp", kClientAddr));
|
|
||||||
EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", kClientAddr2));
|
|
||||||
EXPECT_TRUE(HasCandidate(candidates_, "local", "tcp", kClientAddr2));
|
|
||||||
fss_->ClearRules();
|
|
||||||
EXPECT_TRUE_SIMULATED_WAIT(candidate_allocation_done_,
|
|
||||||
kDefaultAllocationTimeout, fake_clock);
|
|
||||||
EXPECT_EQ(7U, candidates_.size());
|
|
||||||
EXPECT_TRUE(HasCandidate(candidates_, "stun", "udp", kClientAddr));
|
|
||||||
EXPECT_TRUE(HasCandidate(candidates_, "stun", "udp", kClientAddr2));
|
|
||||||
EXPECT_TRUE(HasCandidate(candidates_, "relay", "udp", kTurnUdpExtAddr));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test that when the NetworkManager doesn't have permission to enumerate
|
// Test that when the NetworkManager doesn't have permission to enumerate
|
||||||
// adapters, the PORTALLOCATOR_DISABLE_ADAPTER_ENUMERATION is specified
|
// adapters, the PORTALLOCATOR_DISABLE_ADAPTER_ENUMERATION is specified
|
||||||
// automatically.
|
// automatically.
|
||||||
|
Reference in New Issue
Block a user