Implement RTCConfiguration.iceCandidatePoolSize.
It works by creating pooled PortAllocatorSessions which can be picked up
by a P2PTransportChannel when needed (after a local description is set).
This can optimize candidate gathering time when there is some time between
creating a PeerConnection and setting a local description.
R=pthatcher@webrtc.org
Review URL: https://codereview.webrtc.org/1956453003 .
Cr-Commit-Position: refs/heads/master@{#12708}
diff --git a/webrtc/api/peerconnection.cc b/webrtc/api/peerconnection.cc
index 506a215..5284db3 100644
--- a/webrtc/api/peerconnection.cc
+++ b/webrtc/api/peerconnection.cc
@@ -376,6 +376,23 @@
}
}
+uint32_t ConvertIceTransportTypeToCandidateFilter(
+ PeerConnectionInterface::IceTransportsType type) {
+ switch (type) {
+ case PeerConnectionInterface::kNone:
+ return cricket::CF_NONE;
+ case PeerConnectionInterface::kRelay:
+ return cricket::CF_RELAY;
+ case PeerConnectionInterface::kNoHost:
+ return (cricket::CF_ALL & ~cricket::CF_HOST);
+ case PeerConnectionInterface::kAll:
+ return cricket::CF_ALL;
+ default:
+ ASSERT(false);
+ }
+ return cricket::CF_NONE;
+}
+
} // namespace
namespace webrtc {
@@ -536,6 +553,14 @@
for (const auto& receiver : receivers_) {
receiver->Stop();
}
+ // Destroy stats_ because it depends on session_.
+ stats_.reset(nullptr);
+ // Now destroy session_ before destroying other members,
+ // because its destruction fires signals (such as VoiceChannelDestroyed)
+ // which will trigger some final actions in PeerConnection...
+ session_.reset(nullptr);
+ // port_allocator_ lives on the worker thread and should be destroyed there.
+ worker_thread()->Invoke<void>([this] { port_allocator_.reset(nullptr); });
}
bool PeerConnection::Initialize(
@@ -552,35 +577,12 @@
port_allocator_ = std::move(allocator);
- cricket::ServerAddresses stun_servers;
- std::vector<cricket::RelayServerConfig> turn_servers;
- if (!ParseIceServers(configuration.servers, &stun_servers, &turn_servers)) {
+ // The port allocator lives on the worker thread and should be initialized
+ // there.
+ if (!worker_thread()->Invoke<bool>(rtc::Bind(
+ &PeerConnection::InitializePortAllocator_w, this, configuration))) {
return false;
}
- port_allocator_->SetIceServers(stun_servers, turn_servers);
-
- // To handle both internal and externally created port allocator, we will
- // enable BUNDLE here.
- int portallocator_flags = port_allocator_->flags();
- portallocator_flags |= cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET |
- cricket::PORTALLOCATOR_ENABLE_IPV6;
- // If the disable-IPv6 flag was specified, we'll not override it
- // by experiment.
- if (configuration.disable_ipv6) {
- portallocator_flags &= ~(cricket::PORTALLOCATOR_ENABLE_IPV6);
- } else if (webrtc::field_trial::FindFullName("WebRTC-IPv6Default") ==
- "Disabled") {
- portallocator_flags &= ~(cricket::PORTALLOCATOR_ENABLE_IPV6);
- }
-
- if (configuration.tcp_candidate_policy == kTcpCandidatePolicyDisabled) {
- portallocator_flags |= cricket::PORTALLOCATOR_DISABLE_TCP;
- LOG(LS_INFO) << "TCP candidates are disabled.";
- }
-
- port_allocator_->set_flags(portallocator_flags);
- // No step delay is used while allocating ports.
- port_allocator_->set_step_delay(cricket::kMinimumStepDelay);
media_controller_.reset(
factory_->CreateMediaController(configuration.media_config));
@@ -1158,18 +1160,19 @@
signaling_thread()->Post(this, MSG_SET_SESSIONDESCRIPTION_SUCCESS, msg);
}
-bool PeerConnection::SetConfiguration(const RTCConfiguration& config) {
+bool PeerConnection::SetConfiguration(const RTCConfiguration& configuration) {
TRACE_EVENT0("webrtc", "PeerConnection::SetConfiguration");
if (port_allocator_) {
- cricket::ServerAddresses stun_servers;
- std::vector<cricket::RelayServerConfig> turn_servers;
- if (!ParseIceServers(config.servers, &stun_servers, &turn_servers)) {
+ if (!worker_thread()->Invoke<bool>(
+ rtc::Bind(&PeerConnection::ReconfigurePortAllocator_w, this,
+ configuration))) {
return false;
}
- port_allocator_->SetIceServers(stun_servers, turn_servers);
}
- session_->SetIceConfig(session_->ParseIceConfig(config));
- return session_->SetIceTransports(config.type);
+
+ // TODO(deadbeef): Shouldn't have to hop to the worker thread twice...
+ session_->SetIceConfig(session_->ParseIceConfig(configuration));
+ return true;
}
bool PeerConnection::AddIceCandidate(
@@ -2084,4 +2087,60 @@
return nullptr;
}
+bool PeerConnection::InitializePortAllocator_w(
+ const RTCConfiguration& configuration) {
+ cricket::ServerAddresses stun_servers;
+ std::vector<cricket::RelayServerConfig> turn_servers;
+ if (!ParseIceServers(configuration.servers, &stun_servers, &turn_servers)) {
+ return false;
+ }
+
+ // To handle both internal and externally created port allocator, we will
+ // enable BUNDLE here.
+ int portallocator_flags = port_allocator_->flags();
+ portallocator_flags |= cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET |
+ cricket::PORTALLOCATOR_ENABLE_IPV6;
+ // If the disable-IPv6 flag was specified, we'll not override it
+ // by experiment.
+ if (configuration.disable_ipv6) {
+ portallocator_flags &= ~(cricket::PORTALLOCATOR_ENABLE_IPV6);
+ } else if (webrtc::field_trial::FindFullName("WebRTC-IPv6Default") ==
+ "Disabled") {
+ portallocator_flags &= ~(cricket::PORTALLOCATOR_ENABLE_IPV6);
+ }
+
+ if (configuration.tcp_candidate_policy == kTcpCandidatePolicyDisabled) {
+ portallocator_flags |= cricket::PORTALLOCATOR_DISABLE_TCP;
+ LOG(LS_INFO) << "TCP candidates are disabled.";
+ }
+
+ port_allocator_->set_flags(portallocator_flags);
+ // No step delay is used while allocating ports.
+ port_allocator_->set_step_delay(cricket::kMinimumStepDelay);
+ port_allocator_->set_candidate_filter(
+ ConvertIceTransportTypeToCandidateFilter(configuration.type));
+
+ // Call this last since it may create pooled allocator sessions using the
+ // properties set above.
+ port_allocator_->SetConfiguration(stun_servers, turn_servers,
+ configuration.ice_candidate_pool_size);
+ return true;
+}
+
+bool PeerConnection::ReconfigurePortAllocator_w(
+ const RTCConfiguration& configuration) {
+ cricket::ServerAddresses stun_servers;
+ std::vector<cricket::RelayServerConfig> turn_servers;
+ if (!ParseIceServers(configuration.servers, &stun_servers, &turn_servers)) {
+ return false;
+ }
+ port_allocator_->set_candidate_filter(
+ ConvertIceTransportTypeToCandidateFilter(configuration.type));
+ // Call this last since it may create pooled allocator sessions using the
+ // candidate filter set above.
+ port_allocator_->SetConfiguration(stun_servers, turn_servers,
+ configuration.ice_candidate_pool_size);
+ return true;
+}
+
} // namespace webrtc
diff --git a/webrtc/api/peerconnection.h b/webrtc/api/peerconnection.h
index 862c6fb..15ecc3f 100644
--- a/webrtc/api/peerconnection.h
+++ b/webrtc/api/peerconnection.h
@@ -131,7 +131,7 @@
void SetRemoteDescription(SetSessionDescriptionObserver* observer,
SessionDescriptionInterface* desc) override;
bool SetConfiguration(
- const PeerConnectionInterface::RTCConfiguration& config) override;
+ const PeerConnectionInterface::RTCConfiguration& configuration) override;
bool AddIceCandidate(const IceCandidateInterface* candidate) override;
bool RemoveIceCandidates(
const std::vector<cricket::Candidate>& candidates) override;
@@ -210,6 +210,8 @@
return factory_->signaling_thread();
}
+ rtc::Thread* worker_thread() const { return factory_->worker_thread(); }
+
void PostSetSessionDescriptionFailure(SetSessionDescriptionObserver* observer,
const std::string& error);
void PostCreateSessionDescriptionFailure(
@@ -351,6 +353,12 @@
// or nullptr if not found.
DataChannel* FindDataChannelBySid(int sid) const;
+ // Called when first configuring the port allocator.
+ bool InitializePortAllocator_w(const RTCConfiguration& configuration);
+ // Called when SetConfiguration is called. Only a subset of the configuration
+ // is applied.
+ bool ReconfigurePortAllocator_w(const RTCConfiguration& configuration);
+
// Storing the factory as a scoped reference pointer ensures that the memory
// in the PeerConnectionFactoryImpl remains available as long as the
// PeerConnection is running. It is passed to PeerConnection as a raw pointer.
@@ -397,11 +405,7 @@
std::vector<rtc::scoped_refptr<RtpSenderInterface>> senders_;
std::vector<rtc::scoped_refptr<RtpReceiverInterface>> receivers_;
- // The session_ unique_ptr is declared at the bottom of PeerConnection
- // because its destruction fires signals (such as VoiceChannelDestroyed)
- // which will trigger some final actions in PeerConnection...
std::unique_ptr<WebRtcSession> session_;
- // ... But stats_ depends on session_ so it should be destroyed even earlier.
std::unique_ptr<StatsCollector> stats_;
};
diff --git a/webrtc/api/peerconnection_unittest.cc b/webrtc/api/peerconnection_unittest.cc
index 521486f..1c3d073 100644
--- a/webrtc/api/peerconnection_unittest.cc
+++ b/webrtc/api/peerconnection_unittest.cc
@@ -37,9 +37,9 @@
#include "webrtc/base/thread.h"
#include "webrtc/base/virtualsocketserver.h"
#include "webrtc/media/engine/fakewebrtcvideoengine.h"
+#include "webrtc/p2p/base/fakeportallocator.h"
#include "webrtc/p2p/base/p2pconstants.h"
#include "webrtc/p2p/base/sessiondescription.h"
-#include "webrtc/p2p/client/fakeportallocator.h"
#include "webrtc/pc/mediasession.h"
#define MAYBE_SKIP_TEST(feature) \
diff --git a/webrtc/api/peerconnectionfactory.cc b/webrtc/api/peerconnectionfactory.cc
index 8c8fb6f..5d8f79c 100644
--- a/webrtc/api/peerconnectionfactory.cc
+++ b/webrtc/api/peerconnectionfactory.cc
@@ -283,7 +283,9 @@
allocator.reset(new cricket::BasicPortAllocator(
default_network_manager_.get(), default_socket_factory_.get()));
}
- allocator->SetNetworkIgnoreMask(options_.network_ignore_mask);
+ worker_thread_->Invoke<void>(
+ rtc::Bind(&cricket::PortAllocator::SetNetworkIgnoreMask, allocator.get(),
+ options_.network_ignore_mask));
rtc::scoped_refptr<PeerConnection> pc(
new rtc::RefCountedObject<PeerConnection>(this));
diff --git a/webrtc/api/peerconnectionfactory_unittest.cc b/webrtc/api/peerconnectionfactory_unittest.cc
index 833242a..963f1fe 100644
--- a/webrtc/api/peerconnectionfactory_unittest.cc
+++ b/webrtc/api/peerconnectionfactory_unittest.cc
@@ -24,7 +24,7 @@
#include "webrtc/media/base/fakevideocapturer.h"
#include "webrtc/media/engine/webrtccommon.h"
#include "webrtc/media/engine/webrtcvoe.h"
-#include "webrtc/p2p/client/fakeportallocator.h"
+#include "webrtc/p2p/base/fakeportallocator.h"
using webrtc::DataChannelInterface;
using webrtc::DtlsIdentityStoreInterface;
diff --git a/webrtc/api/peerconnectioninterface.h b/webrtc/api/peerconnectioninterface.h
index 94d2c00..fe0dc1d 100644
--- a/webrtc/api/peerconnectioninterface.h
+++ b/webrtc/api/peerconnectioninterface.h
@@ -270,42 +270,30 @@
static const int kAudioJitterBufferMaxPackets = 50;
// TODO(pthatcher): Rename this ice_transport_type, but update
// Chromium at the same time.
- IceTransportsType type;
+ IceTransportsType type = kAll;
// TODO(pthatcher): Rename this ice_servers, but update Chromium
// at the same time.
IceServers servers;
- BundlePolicy bundle_policy;
- RtcpMuxPolicy rtcp_mux_policy;
- TcpCandidatePolicy tcp_candidate_policy;
- int audio_jitter_buffer_max_packets;
- bool audio_jitter_buffer_fast_accelerate;
- int ice_connection_receiving_timeout; // ms
- int ice_backup_candidate_pair_ping_interval; // ms
- ContinualGatheringPolicy continual_gathering_policy;
+ BundlePolicy bundle_policy = kBundlePolicyBalanced;
+ RtcpMuxPolicy rtcp_mux_policy = kRtcpMuxPolicyNegotiate;
+ TcpCandidatePolicy tcp_candidate_policy = kTcpCandidatePolicyEnabled;
+ int audio_jitter_buffer_max_packets = kAudioJitterBufferMaxPackets;
+ bool audio_jitter_buffer_fast_accelerate = false;
+ int ice_connection_receiving_timeout = kUndefined; // ms
+ int ice_backup_candidate_pair_ping_interval = kUndefined; // ms
+ ContinualGatheringPolicy continual_gathering_policy = GATHER_ONCE;
std::vector<rtc::scoped_refptr<rtc::RTCCertificate>> certificates;
- bool prioritize_most_likely_ice_candidate_pairs;
+ bool prioritize_most_likely_ice_candidate_pairs = false;
struct cricket::MediaConfig media_config;
// Flags corresponding to values set by constraint flags.
// rtc::Optional flags can be "missing", in which case the webrtc
// default applies.
- bool disable_ipv6;
- bool enable_rtp_data_channel;
+ bool disable_ipv6 = false;
+ bool enable_rtp_data_channel = false;
rtc::Optional<int> screencast_min_bitrate;
rtc::Optional<bool> combined_audio_video_bwe;
rtc::Optional<bool> enable_dtls_srtp;
- RTCConfiguration()
- : type(kAll),
- bundle_policy(kBundlePolicyBalanced),
- rtcp_mux_policy(kRtcpMuxPolicyNegotiate),
- tcp_candidate_policy(kTcpCandidatePolicyEnabled),
- audio_jitter_buffer_max_packets(kAudioJitterBufferMaxPackets),
- audio_jitter_buffer_fast_accelerate(false),
- ice_connection_receiving_timeout(kUndefined),
- ice_backup_candidate_pair_ping_interval(kUndefined),
- continual_gathering_policy(GATHER_ONCE),
- prioritize_most_likely_ice_candidate_pairs(false),
- disable_ipv6(false),
- enable_rtp_data_channel(false) {}
+ int ice_candidate_pool_size = 0;
};
struct RTCOfferAnswerOptions {
diff --git a/webrtc/api/peerconnectioninterface_unittest.cc b/webrtc/api/peerconnectioninterface_unittest.cc
index 795a66d..68c932b 100644
--- a/webrtc/api/peerconnectioninterface_unittest.cc
+++ b/webrtc/api/peerconnectioninterface_unittest.cc
@@ -39,7 +39,7 @@
#include "webrtc/base/thread.h"
#include "webrtc/media/base/fakevideocapturer.h"
#include "webrtc/media/sctp/sctpdataengine.h"
-#include "webrtc/p2p/client/fakeportallocator.h"
+#include "webrtc/p2p/base/fakeportallocator.h"
#include "webrtc/pc/mediasession.h"
static const char kStreamLabel1[] = "local_stream_1";
@@ -551,24 +551,33 @@
}
void CreatePeerConnection() {
- CreatePeerConnection("", "", NULL);
+ CreatePeerConnection(PeerConnectionInterface::RTCConfiguration(), nullptr);
}
void CreatePeerConnection(webrtc::MediaConstraintsInterface* constraints) {
- CreatePeerConnection("", "", constraints);
+ CreatePeerConnection(PeerConnectionInterface::RTCConfiguration(),
+ constraints);
}
- void CreatePeerConnection(const std::string& uri,
- const std::string& password,
- webrtc::MediaConstraintsInterface* constraints) {
+ void CreatePeerConnectionWithIceTransportsType(
+ PeerConnectionInterface::IceTransportsType type) {
+ PeerConnectionInterface::RTCConfiguration config;
+ config.type = type;
+ return CreatePeerConnection(config, nullptr);
+ }
+
+ void CreatePeerConnectionWithIceServer(const std::string& uri,
+ const std::string& password) {
PeerConnectionInterface::RTCConfiguration config;
PeerConnectionInterface::IceServer server;
- if (!uri.empty()) {
- server.uri = uri;
- server.password = password;
- config.servers.push_back(server);
- }
+ server.uri = uri;
+ server.password = password;
+ config.servers.push_back(server);
+ CreatePeerConnection(config, nullptr);
+ }
+ void CreatePeerConnection(PeerConnectionInterface::RTCConfiguration config,
+ webrtc::MediaConstraintsInterface* constraints) {
std::unique_ptr<cricket::FakePortAllocator> port_allocator(
new cricket::FakePortAllocator(rtc::Thread::Current(), nullptr));
port_allocator_ = port_allocator.get();
@@ -613,7 +622,7 @@
}
void CreatePeerConnectionWithDifferentConfigurations() {
- CreatePeerConnection(kStunAddressOnly, "", NULL);
+ CreatePeerConnectionWithIceServer(kStunAddressOnly, "");
EXPECT_EQ(1u, port_allocator_->stun_servers().size());
EXPECT_EQ(0u, port_allocator_->turn_servers().size());
EXPECT_EQ("address", port_allocator_->stun_servers().begin()->hostname());
@@ -624,7 +633,7 @@
CreatePeerConnectionExpectFail(kStunAddressPortAndMore1);
CreatePeerConnectionExpectFail(kStunAddressPortAndMore2);
- CreatePeerConnection(kTurnIceServerUri, kTurnPassword, NULL);
+ CreatePeerConnectionWithIceServer(kTurnIceServerUri, kTurnPassword);
EXPECT_EQ(0u, port_allocator_->stun_servers().size());
EXPECT_EQ(1u, port_allocator_->turn_servers().size());
EXPECT_EQ(kTurnUsername,
@@ -1014,6 +1023,44 @@
CreatePeerConnectionWithDifferentConfigurations();
}
+TEST_F(PeerConnectionInterfaceTest,
+ CreatePeerConnectionWithDifferentIceTransportsTypes) {
+ CreatePeerConnectionWithIceTransportsType(PeerConnectionInterface::kNone);
+ EXPECT_EQ(cricket::CF_NONE, port_allocator_->candidate_filter());
+ CreatePeerConnectionWithIceTransportsType(PeerConnectionInterface::kRelay);
+ EXPECT_EQ(cricket::CF_RELAY, port_allocator_->candidate_filter());
+ CreatePeerConnectionWithIceTransportsType(PeerConnectionInterface::kNoHost);
+ EXPECT_EQ(cricket::CF_ALL & ~cricket::CF_HOST,
+ port_allocator_->candidate_filter());
+ CreatePeerConnectionWithIceTransportsType(PeerConnectionInterface::kAll);
+ EXPECT_EQ(cricket::CF_ALL, port_allocator_->candidate_filter());
+}
+
+// Test that when a PeerConnection is created with a nonzero candidate pool
+// size, the pooled PortAllocatorSession is created with all the attributes
+// in the RTCConfiguration.
+TEST_F(PeerConnectionInterfaceTest, CreatePeerConnectionWithPooledCandidates) {
+ PeerConnectionInterface::RTCConfiguration config;
+ PeerConnectionInterface::IceServer server;
+ server.uri = kStunAddressOnly;
+ config.servers.push_back(server);
+ config.type = PeerConnectionInterface::kRelay;
+ config.disable_ipv6 = true;
+ config.tcp_candidate_policy =
+ PeerConnectionInterface::kTcpCandidatePolicyDisabled;
+ config.ice_candidate_pool_size = 1;
+ CreatePeerConnection(config, nullptr);
+
+ const cricket::FakePortAllocatorSession* session =
+ static_cast<const cricket::FakePortAllocatorSession*>(
+ port_allocator_->GetPooledSession());
+ ASSERT_NE(nullptr, session);
+ EXPECT_EQ(1UL, session->stun_servers().size());
+ EXPECT_EQ(0U, session->flags() & cricket::PORTALLOCATOR_ENABLE_IPV6);
+ EXPECT_LT(0U, session->flags() & cricket::PORTALLOCATOR_DISABLE_TCP);
+ EXPECT_EQ(cricket::CF_RELAY, session->candidate_filter());
+}
+
TEST_F(PeerConnectionInterfaceTest, AddStreams) {
CreatePeerConnection();
AddVideoStream(kStreamLabel1);
@@ -1907,6 +1954,35 @@
port_allocator_->stun_servers().begin()->hostname());
}
+TEST_F(PeerConnectionInterfaceTest, SetConfigurationChangesCandidateFilter) {
+ CreatePeerConnection();
+ PeerConnectionInterface::RTCConfiguration config;
+ config.type = PeerConnectionInterface::kRelay;
+ EXPECT_TRUE(pc_->SetConfiguration(config));
+ EXPECT_EQ(cricket::CF_RELAY, port_allocator_->candidate_filter());
+}
+
+// Test that when SetConfiguration changes both the pool size and other
+// attributes, the pooled session is created with the updated attributes.
+TEST_F(PeerConnectionInterfaceTest,
+ SetConfigurationCreatesPooledSessionCorrectly) {
+ CreatePeerConnection();
+ PeerConnectionInterface::RTCConfiguration config;
+ config.ice_candidate_pool_size = 1;
+ PeerConnectionInterface::IceServer server;
+ server.uri = kStunAddressOnly;
+ config.servers.push_back(server);
+ config.type = PeerConnectionInterface::kRelay;
+ CreatePeerConnection(config, nullptr);
+
+ const cricket::FakePortAllocatorSession* session =
+ static_cast<const cricket::FakePortAllocatorSession*>(
+ port_allocator_->GetPooledSession());
+ ASSERT_NE(nullptr, session);
+ EXPECT_EQ(1UL, session->stun_servers().size());
+ EXPECT_EQ(cricket::CF_RELAY, session->candidate_filter());
+}
+
// Test that PeerConnection::Close changes the states to closed and all remote
// tracks change state to ended.
TEST_F(PeerConnectionInterfaceTest, CloseAndTestStreamsAndStates) {
diff --git a/webrtc/api/test/peerconnectiontestwrapper.cc b/webrtc/api/test/peerconnectiontestwrapper.cc
index 717c48a..1ec2b47 100644
--- a/webrtc/api/test/peerconnectiontestwrapper.cc
+++ b/webrtc/api/test/peerconnectiontestwrapper.cc
@@ -15,7 +15,7 @@
#include "webrtc/api/test/mockpeerconnectionobservers.h"
#include "webrtc/api/test/peerconnectiontestwrapper.h"
#include "webrtc/base/gunit.h"
-#include "webrtc/p2p/client/fakeportallocator.h"
+#include "webrtc/p2p/base/fakeportallocator.h"
static const char kStreamLabelBase[] = "stream_label";
static const char kVideoTrackLabelBase[] = "video_track";
diff --git a/webrtc/api/webrtcsession.cc b/webrtc/api/webrtcsession.cc
index c3ea1c8..2b146c6 100644
--- a/webrtc/api/webrtcsession.cc
+++ b/webrtc/api/webrtcsession.cc
@@ -421,22 +421,6 @@
return MakeErrorString(kPushDownTDFailed, desc);
}
-uint32_t ConvertIceTransportTypeToCandidateFilter(
- PeerConnectionInterface::IceTransportsType type) {
- switch (type) {
- case PeerConnectionInterface::kNone:
- return cricket::CF_NONE;
- case PeerConnectionInterface::kRelay:
- return cricket::CF_RELAY;
- case PeerConnectionInterface::kNoHost:
- return (cricket::CF_ALL & ~cricket::CF_HOST);
- case PeerConnectionInterface::kAll:
- return cricket::CF_ALL;
- default: ASSERT(false);
- }
- return cricket::CF_NONE;
-}
-
// Returns true if |new_desc| requests an ICE restart (i.e., new ufrag/pwd).
bool CheckForRemoteIceRestart(const SessionDescriptionInterface* old_desc,
const SessionDescriptionInterface* new_desc,
@@ -475,7 +459,6 @@
cricket::PortAllocator* port_allocator)
: signaling_thread_(signaling_thread),
worker_thread_(worker_thread),
- port_allocator_(port_allocator),
// RFC 3264: The numeric value of the session id and version in the
// o line MUST be representable with a "64 bit signed integer".
// Due to this constraint session id |sid_| is max limited to LLONG_MAX.
@@ -604,8 +587,6 @@
if (options.disable_encryption) {
webrtc_session_desc_factory_->SetSdesPolicy(cricket::SEC_DISABLED);
}
- port_allocator()->set_candidate_filter(
- ConvertIceTransportTypeToCandidateFilter(rtc_configuration.type));
return true;
}
@@ -1145,12 +1126,6 @@
return true;
}
-bool WebRtcSession::SetIceTransports(
- PeerConnectionInterface::IceTransportsType type) {
- return port_allocator()->set_candidate_filter(
- ConvertIceTransportTypeToCandidateFilter(type));
-}
-
cricket::IceConfig WebRtcSession::ParseIceConfig(
const PeerConnectionInterface::RTCConfiguration& config) const {
cricket::IceConfig ice_config;
diff --git a/webrtc/api/webrtcsession.h b/webrtc/api/webrtcsession.h
index 1408b22..8a32d78f 100644
--- a/webrtc/api/webrtcsession.h
+++ b/webrtc/api/webrtcsession.h
@@ -146,7 +146,6 @@
// These are const to allow them to be called from const methods.
rtc::Thread* signaling_thread() const { return signaling_thread_; }
rtc::Thread* worker_thread() const { return worker_thread_; }
- cricket::PortAllocator* port_allocator() const { return port_allocator_; }
// The ID of this session.
const std::string& id() const { return sid_; }
@@ -214,8 +213,6 @@
bool RemoveRemoteIceCandidates(
const std::vector<cricket::Candidate>& candidates);
- bool SetIceTransports(PeerConnectionInterface::IceTransportsType type);
-
cricket::IceConfig ParseIceConfig(
const PeerConnectionInterface::RTCConfiguration& config) const;
@@ -469,7 +466,6 @@
rtc::Thread* const signaling_thread_;
rtc::Thread* const worker_thread_;
- cricket::PortAllocator* const port_allocator_;
State state_ = STATE_INIT;
Error error_ = ERROR_NONE;
diff --git a/webrtc/api/webrtcsession_unittest.cc b/webrtc/api/webrtcsession_unittest.cc
index 45ffc36..cd5e784 100644
--- a/webrtc/api/webrtcsession_unittest.cc
+++ b/webrtc/api/webrtcsession_unittest.cc
@@ -407,12 +407,6 @@
void Init() { Init(nullptr); }
- void InitWithIceTransport(
- PeerConnectionInterface::IceTransportsType ice_transport_type) {
- configuration_.type = ice_transport_type;
- Init();
- }
-
void InitWithBundlePolicy(
PeerConnectionInterface::BundlePolicy bundle_policy) {
configuration_.bundle_policy = bundle_policy;
@@ -1529,50 +1523,6 @@
EXPECT_EQ(6u, observer_.mline_1_candidates_.size());
}
-// Test session delivers no candidates gathered when constraint set to "none".
-TEST_F(WebRtcSessionTest, TestIceTransportsNone) {
- AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
- InitWithIceTransport(PeerConnectionInterface::kNone);
- SendAudioVideoStream1();
- InitiateCall();
- EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
- EXPECT_EQ(0u, observer_.mline_0_candidates_.size());
- EXPECT_EQ(0u, observer_.mline_1_candidates_.size());
-}
-
-// Test session delivers only relay candidates gathered when constaint set to
-// "relay".
-TEST_F(WebRtcSessionTest, TestIceTransportsRelay) {
- AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
- ConfigureAllocatorWithTurn();
- InitWithIceTransport(PeerConnectionInterface::kRelay);
- SendAudioVideoStream1();
- InitiateCall();
- EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
- EXPECT_EQ(2u, observer_.mline_0_candidates_.size());
- EXPECT_EQ(2u, observer_.mline_1_candidates_.size());
- for (size_t i = 0; i < observer_.mline_0_candidates_.size(); ++i) {
- EXPECT_EQ(cricket::RELAY_PORT_TYPE,
- observer_.mline_0_candidates_[i].type());
- }
- for (size_t i = 0; i < observer_.mline_1_candidates_.size(); ++i) {
- EXPECT_EQ(cricket::RELAY_PORT_TYPE,
- observer_.mline_1_candidates_[i].type());
- }
-}
-
-// Test session delivers all candidates gathered when constaint set to "all".
-TEST_F(WebRtcSessionTest, TestIceTransportsAll) {
- AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
- InitWithIceTransport(PeerConnectionInterface::kAll);
- SendAudioVideoStream1();
- InitiateCall();
- EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
- // Host + STUN. By default allocator is disabled to gather relay candidates.
- EXPECT_EQ(4u, observer_.mline_0_candidates_.size());
- EXPECT_EQ(4u, observer_.mline_1_candidates_.size());
-}
-
TEST_F(WebRtcSessionTest, SetSdpFailedOnInvalidSdp) {
Init();
SessionDescriptionInterface* offer = NULL;
diff --git a/webrtc/p2p/base/candidate.h b/webrtc/p2p/base/candidate.h
index ec758d2..b918344 100644
--- a/webrtc/p2p/base/candidate.h
+++ b/webrtc/p2p/base/candidate.h
@@ -241,6 +241,19 @@
(256 - component_);
}
+ bool operator==(const Candidate& o) const {
+ return id_ == o.id_ && component_ == o.component_ &&
+ protocol_ == o.protocol_ && relay_protocol_ == o.relay_protocol_ &&
+ address_ == o.address_ && priority_ == o.priority_ &&
+ username_ == o.username_ && password_ == o.password_ &&
+ type_ == o.type_ && network_name_ == o.network_name_ &&
+ network_type_ == o.network_type_ && generation_ == o.generation_ &&
+ foundation_ == o.foundation_ &&
+ related_address_ == o.related_address_ && tcptype_ == o.tcptype_ &&
+ transport_name_ == o.transport_name_ && network_id_ == o.network_id_;
+ }
+ bool operator!=(const Candidate& o) const { return !(*this == o); }
+
private:
std::string ToStringInternal(bool sensitive) const {
std::ostringstream ost;
diff --git a/webrtc/p2p/client/fakeportallocator.h b/webrtc/p2p/base/fakeportallocator.h
similarity index 65%
rename from webrtc/p2p/client/fakeportallocator.h
rename to webrtc/p2p/base/fakeportallocator.h
index 76357a5..b125dfd 100644
--- a/webrtc/p2p/client/fakeportallocator.h
+++ b/webrtc/p2p/base/fakeportallocator.h
@@ -8,11 +8,12 @@
* be found in the AUTHORS file in the root of the source tree.
*/
-#ifndef WEBRTC_P2P_CLIENT_FAKEPORTALLOCATOR_H_
-#define WEBRTC_P2P_CLIENT_FAKEPORTALLOCATOR_H_
+#ifndef WEBRTC_P2P_BASE_FAKEPORTALLOCATOR_H_
+#define WEBRTC_P2P_BASE_FAKEPORTALLOCATOR_H_
#include <memory>
#include <string>
+#include <vector>
#include "webrtc/p2p/base/basicpacketsocketfactory.h"
#include "webrtc/p2p/base/portallocator.h"
@@ -84,24 +85,31 @@
class FakePortAllocatorSession : public PortAllocatorSession {
public:
- FakePortAllocatorSession(rtc::Thread* worker_thread,
+ FakePortAllocatorSession(PortAllocator* allocator,
+ rtc::Thread* worker_thread,
rtc::PacketSocketFactory* factory,
const std::string& content_name,
int component,
const std::string& ice_ufrag,
const std::string& ice_pwd)
- : PortAllocatorSession(content_name, component, ice_ufrag, ice_pwd,
- cricket::kDefaultPortAllocatorFlags),
+ : PortAllocatorSession(content_name,
+ component,
+ ice_ufrag,
+ ice_pwd,
+ allocator->flags()),
worker_thread_(worker_thread),
factory_(factory),
- network_("network", "unittest",
- rtc::IPAddress(INADDR_LOOPBACK), 8),
- port_(), running_(false),
- port_config_count_(0) {
+ network_("network", "unittest", rtc::IPAddress(INADDR_LOOPBACK), 8),
+ port_(),
+ running_(false),
+ port_config_count_(0),
+ stun_servers_(allocator->stun_servers()),
+ turn_servers_(allocator->turn_servers()),
+ candidate_filter_(allocator->candidate_filter()) {
network_.AddIP(rtc::IPAddress(INADDR_LOOPBACK));
}
- virtual void StartGettingPorts() {
+ void StartGettingPorts() override {
if (!port_) {
port_.reset(TestUDPPort::Create(worker_thread_, factory_, &network_,
network_.GetBestIP(), 0, 0, username(),
@@ -112,25 +120,56 @@
running_ = true;
}
- virtual void StopGettingPorts() { running_ = false; }
- virtual bool IsGettingPorts() { return running_; }
- virtual void ClearGettingPorts() {}
+ void StopGettingPorts() override { running_ = false; }
+ bool IsGettingPorts() override { return running_; }
+ void ClearGettingPorts() override {}
+ std::vector<PortInterface*> ReadyPorts() const override {
+ return ready_ports_;
+ }
+ std::vector<Candidate> ReadyCandidates() const override {
+ return candidates_;
+ }
+ bool CandidatesAllocationDone() const override { return allocation_done_; }
int port_config_count() { return port_config_count_; }
+ const ServerAddresses& stun_servers() const { return stun_servers_; }
+
+ const std::vector<RelayServerConfig>& turn_servers() const {
+ return turn_servers_;
+ }
+
+ uint32_t candidate_filter() const { return candidate_filter_; }
+
void AddPort(cricket::Port* port) {
- port->set_component(component_);
+ port->set_component(component());
port->set_generation(generation());
- port->SignalPortComplete.connect(
- this, &FakePortAllocatorSession::OnPortComplete);
+ port->SignalPortComplete.connect(this,
+ &FakePortAllocatorSession::OnPortComplete);
port->PrepareAddress();
+ ready_ports_.push_back(port);
SignalPortReady(this, port);
}
void OnPortComplete(cricket::Port* port) {
- SignalCandidatesReady(this, port->Candidates());
+ const std::vector<Candidate>& candidates = port->Candidates();
+ candidates_.insert(candidates_.end(), candidates.begin(), candidates.end());
+ SignalCandidatesReady(this, candidates);
+
+ allocation_done_ = true;
SignalCandidatesAllocationDone(this);
}
+ int transport_info_update_count() const {
+ return transport_info_update_count_;
+ }
+
+ protected:
+ void UpdateIceParametersInternal() override {
+ // Since this class is a fake and this method only is overridden for tests,
+ // we don't need to actually update the transport info.
+ ++transport_info_update_count_;
+ }
+
private:
rtc::Thread* worker_thread_;
rtc::PacketSocketFactory* factory_;
@@ -138,6 +177,13 @@
std::unique_ptr<cricket::Port> port_;
bool running_;
int port_config_count_;
+ std::vector<Candidate> candidates_;
+ std::vector<PortInterface*> ready_ports_;
+ bool allocation_done_ = false;
+ ServerAddresses stun_servers_;
+ std::vector<RelayServerConfig> turn_servers_;
+ uint32_t candidate_filter_;
+ int transport_info_update_count_ = 0;
};
class FakePortAllocator : public cricket::PortAllocator {
@@ -146,44 +192,29 @@
rtc::PacketSocketFactory* factory)
: worker_thread_(worker_thread), factory_(factory) {
if (factory_ == NULL) {
- owned_factory_.reset(new rtc::BasicPacketSocketFactory(
- worker_thread_));
+ owned_factory_.reset(new rtc::BasicPacketSocketFactory(worker_thread_));
factory_ = owned_factory_.get();
}
}
- void SetIceServers(
- const ServerAddresses& stun_servers,
- const std::vector<RelayServerConfig>& turn_servers) override {
- stun_servers_ = stun_servers;
- turn_servers_ = turn_servers;
- }
-
void SetNetworkIgnoreMask(int network_ignore_mask) override {}
- const ServerAddresses& stun_servers() const { return stun_servers_; }
-
- const std::vector<RelayServerConfig>& turn_servers() const {
- return turn_servers_;
- }
-
- virtual cricket::PortAllocatorSession* CreateSessionInternal(
+ cricket::PortAllocatorSession* CreateSessionInternal(
const std::string& content_name,
int component,
const std::string& ice_ufrag,
const std::string& ice_pwd) override {
- return new FakePortAllocatorSession(
- worker_thread_, factory_, content_name, component, ice_ufrag, ice_pwd);
+ return new FakePortAllocatorSession(this, worker_thread_, factory_,
+ content_name, component, ice_ufrag,
+ ice_pwd);
}
private:
rtc::Thread* worker_thread_;
rtc::PacketSocketFactory* factory_;
std::unique_ptr<rtc::BasicPacketSocketFactory> owned_factory_;
- ServerAddresses stun_servers_;
- std::vector<RelayServerConfig> turn_servers_;
};
} // namespace cricket
-#endif // WEBRTC_P2P_CLIENT_FAKEPORTALLOCATOR_H_
+#endif // WEBRTC_P2P_BASE_FAKEPORTALLOCATOR_H_
diff --git a/webrtc/p2p/base/p2ptransportchannel.cc b/webrtc/p2p/base/p2ptransportchannel.cc
index 206113c..2801c44 100644
--- a/webrtc/p2p/base/p2ptransportchannel.cc
+++ b/webrtc/p2p/base/p2ptransportchannel.cc
@@ -261,30 +261,27 @@
P2PTransportChannel::~P2PTransportChannel() {
ASSERT(worker_thread_ == rtc::Thread::Current());
-
- for (size_t i = 0; i < allocator_sessions_.size(); ++i)
- delete allocator_sessions_[i];
}
// Add the allocator session to our list so that we know which sessions
// are still active.
-void P2PTransportChannel::AddAllocatorSession(PortAllocatorSession* session) {
+void P2PTransportChannel::AddAllocatorSession(
+ std::unique_ptr<PortAllocatorSession> session) {
ASSERT(worker_thread_ == rtc::Thread::Current());
session->set_generation(static_cast<uint32_t>(allocator_sessions_.size()));
- allocator_sessions_.push_back(session);
+ session->SignalPortReady.connect(this, &P2PTransportChannel::OnPortReady);
+ session->SignalCandidatesReady.connect(
+ this, &P2PTransportChannel::OnCandidatesReady);
+ session->SignalCandidatesAllocationDone.connect(
+ this, &P2PTransportChannel::OnCandidatesAllocationDone);
// We now only want to apply new candidates that we receive to the ports
// created by this new session because these are replacing those of the
// previous sessions.
ports_.clear();
- session->SignalPortReady.connect(this, &P2PTransportChannel::OnPortReady);
- session->SignalCandidatesReady.connect(
- this, &P2PTransportChannel::OnCandidatesReady);
- session->SignalCandidatesAllocationDone.connect(
- this, &P2PTransportChannel::OnCandidatesAllocationDone);
- session->StartGettingPorts();
+ allocator_sessions_.push_back(std::move(session));
}
void P2PTransportChannel::AddConnection(Connection* connection) {
@@ -472,9 +469,28 @@
gathering_state_ = kIceGatheringGathering;
SignalGatheringState(this);
}
- // Time for a new allocator
- AddAllocatorSession(allocator_->CreateSession(
- SessionId(), transport_name(), component(), ice_ufrag_, ice_pwd_));
+ // Time for a new allocator.
+ std::unique_ptr<PortAllocatorSession> pooled_session =
+ allocator_->TakePooledSession(transport_name(), component(), ice_ufrag_,
+ ice_pwd_);
+ if (pooled_session) {
+ AddAllocatorSession(std::move(pooled_session));
+ PortAllocatorSession* raw_pooled_session =
+ allocator_sessions_.back().get();
+ // Process the pooled session's existing candidates/ports, if they exist.
+ OnCandidatesReady(raw_pooled_session,
+ raw_pooled_session->ReadyCandidates());
+ for (PortInterface* port : allocator_sessions_.back()->ReadyPorts()) {
+ OnPortReady(raw_pooled_session, port);
+ }
+ if (allocator_sessions_.back()->CandidatesAllocationDone()) {
+ OnCandidatesAllocationDone(raw_pooled_session);
+ }
+ } else {
+ AddAllocatorSession(allocator_->CreateSession(
+ SessionId(), transport_name(), component(), ice_ufrag_, ice_pwd_));
+ allocator_sessions_.back()->StartGettingPorts();
+ }
}
}
@@ -1213,7 +1229,7 @@
return;
}
- for (PortAllocatorSession* session : allocator_sessions_) {
+ for (const auto& session : allocator_sessions_) {
if (!session->IsGettingPorts()) {
continue;
}
diff --git a/webrtc/p2p/base/p2ptransportchannel.h b/webrtc/p2p/base/p2ptransportchannel.h
index 2afe03e..b002c8b 100644
--- a/webrtc/p2p/base/p2ptransportchannel.h
+++ b/webrtc/p2p/base/p2ptransportchannel.h
@@ -189,7 +189,7 @@
// Public for unit tests.
PortAllocatorSession* allocator_session() {
- return allocator_sessions_.back();
+ return allocator_sessions_.back().get();
}
// Public for unit tests.
@@ -227,7 +227,7 @@
PortInterface* origin_port);
bool IsPingable(Connection* conn, int64_t now);
void PingConnection(Connection* conn);
- void AddAllocatorSession(PortAllocatorSession* session);
+ void AddAllocatorSession(std::unique_ptr<PortAllocatorSession> session);
void AddConnection(Connection* connection);
void OnPortReady(PortAllocatorSession *session, PortInterface* port);
@@ -295,7 +295,7 @@
rtc::Thread* worker_thread_;
bool incoming_only_;
int error_;
- std::vector<PortAllocatorSession*> allocator_sessions_;
+ std::vector<std::unique_ptr<PortAllocatorSession>> allocator_sessions_;
std::vector<PortInterface *> ports_;
// |connections_| is a sorted list with the first one always be the
diff --git a/webrtc/p2p/base/p2ptransportchannel_unittest.cc b/webrtc/p2p/base/p2ptransportchannel_unittest.cc
index 21564e6..54ab319 100644
--- a/webrtc/p2p/base/p2ptransportchannel_unittest.cc
+++ b/webrtc/p2p/base/p2ptransportchannel_unittest.cc
@@ -8,14 +8,15 @@
* be found in the AUTHORS file in the root of the source tree.
*/
+#include <algorithm>
#include <memory>
+#include "webrtc/p2p/base/fakeportallocator.h"
#include "webrtc/p2p/base/p2ptransportchannel.h"
#include "webrtc/p2p/base/testrelayserver.h"
#include "webrtc/p2p/base/teststunserver.h"
#include "webrtc/p2p/base/testturnserver.h"
#include "webrtc/p2p/client/basicportallocator.h"
-#include "webrtc/p2p/client/fakeportallocator.h"
#include "webrtc/base/dscp.h"
#include "webrtc/base/fakenetwork.h"
#include "webrtc/base/firewallsocketserver.h"
@@ -287,6 +288,8 @@
1, cricket::ICE_CANDIDATE_COMPONENT_DEFAULT,
ice_ufrag_ep2_cd1_ch, ice_pwd_ep2_cd1_ch,
ice_ufrag_ep1_cd1_ch, ice_pwd_ep1_cd1_ch));
+ ep1_.cd1_.ch_->MaybeStartGathering();
+ ep2_.cd1_.ch_->MaybeStartGathering();
if (num == 2) {
std::string ice_ufrag_ep1_cd2_ch = kIceUfrag[2];
std::string ice_pwd_ep1_cd2_ch = kIcePwd[2];
@@ -300,6 +303,8 @@
1, cricket::ICE_CANDIDATE_COMPONENT_DEFAULT,
ice_ufrag_ep2_cd2_ch, ice_pwd_ep2_cd2_ch,
ice_ufrag_ep1_cd2_ch, ice_pwd_ep1_cd2_ch));
+ ep1_.cd2_.ch_->MaybeStartGathering();
+ ep2_.cd2_.ch_->MaybeStartGathering();
}
}
cricket::P2PTransportChannel* CreateChannel(
@@ -328,7 +333,6 @@
channel->SetIceRole(GetEndpoint(endpoint)->ice_role());
channel->SetIceTiebreaker(GetEndpoint(endpoint)->GetIceTiebreaker());
channel->Connect();
- channel->MaybeStartGathering();
return channel;
}
void DestroyChannels() {
@@ -1547,6 +1551,92 @@
DestroyChannels();
}
+// Test that a connection succeeds when the P2PTransportChannel uses a pooled
+// PortAllocatorSession that has not yet finished gathering candidates.
+TEST_F(P2PTransportChannelTest, TestUsingPooledSessionBeforeDoneGathering) {
+ ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
+ kDefaultPortAllocatorFlags);
+ // First create a pooled session for each endpoint.
+ auto& allocator_1 = GetEndpoint(0)->allocator_;
+ auto& allocator_2 = GetEndpoint(1)->allocator_;
+ int pool_size = 1;
+ allocator_1->SetConfiguration(allocator_1->stun_servers(),
+ allocator_1->turn_servers(), pool_size);
+ allocator_2->SetConfiguration(allocator_2->stun_servers(),
+ allocator_2->turn_servers(), pool_size);
+ const cricket::PortAllocatorSession* pooled_session_1 =
+ allocator_1->GetPooledSession();
+ const cricket::PortAllocatorSession* pooled_session_2 =
+ allocator_2->GetPooledSession();
+ ASSERT_NE(nullptr, pooled_session_1);
+ ASSERT_NE(nullptr, pooled_session_2);
+ // Sanity check that pooled sessions haven't gathered anything yet.
+ EXPECT_TRUE(pooled_session_1->ReadyPorts().empty());
+ EXPECT_TRUE(pooled_session_1->ReadyCandidates().empty());
+ EXPECT_TRUE(pooled_session_2->ReadyPorts().empty());
+ EXPECT_TRUE(pooled_session_2->ReadyCandidates().empty());
+ // Now let the endpoints connect and try exchanging some data.
+ CreateChannels(1);
+ EXPECT_TRUE_WAIT_MARGIN(ep1_ch1() != NULL && ep2_ch1() != NULL &&
+ ep1_ch1()->receiving() && ep1_ch1()->writable() &&
+ ep2_ch1()->receiving() && ep2_ch1()->writable(),
+ 1000, 1000);
+ TestSendRecv(1);
+ // Make sure the P2PTransportChannels are actually using ports from the
+ // pooled sessions.
+ auto pooled_ports_1 = pooled_session_1->ReadyPorts();
+ auto pooled_ports_2 = pooled_session_2->ReadyPorts();
+ EXPECT_NE(pooled_ports_1.end(),
+ std::find(pooled_ports_1.begin(), pooled_ports_1.end(),
+ ep1_ch1()->best_connection()->port()));
+ EXPECT_NE(pooled_ports_2.end(),
+ std::find(pooled_ports_2.begin(), pooled_ports_2.end(),
+ ep2_ch1()->best_connection()->port()));
+}
+
+// Test that a connection succeeds when the P2PTransportChannel uses a pooled
+// PortAllocatorSession that already finished gathering candidates.
+TEST_F(P2PTransportChannelTest, TestUsingPooledSessionAfterDoneGathering) {
+ ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
+ kDefaultPortAllocatorFlags);
+ // First create a pooled session for each endpoint.
+ auto& allocator_1 = GetEndpoint(0)->allocator_;
+ auto& allocator_2 = GetEndpoint(1)->allocator_;
+ int pool_size = 1;
+ allocator_1->SetConfiguration(allocator_1->stun_servers(),
+ allocator_1->turn_servers(), pool_size);
+ allocator_2->SetConfiguration(allocator_2->stun_servers(),
+ allocator_2->turn_servers(), pool_size);
+ const cricket::PortAllocatorSession* pooled_session_1 =
+ allocator_1->GetPooledSession();
+ const cricket::PortAllocatorSession* pooled_session_2 =
+ allocator_2->GetPooledSession();
+ ASSERT_NE(nullptr, pooled_session_1);
+ ASSERT_NE(nullptr, pooled_session_2);
+ // Wait for the pooled sessions to finish gathering before the
+ // P2PTransportChannels try to use them.
+ EXPECT_TRUE_WAIT(pooled_session_1->CandidatesAllocationDone() &&
+ pooled_session_2->CandidatesAllocationDone(),
+ kDefaultTimeout);
+ // Now let the endpoints connect and try exchanging some data.
+ CreateChannels(1);
+ EXPECT_TRUE_WAIT_MARGIN(ep1_ch1() != NULL && ep2_ch1() != NULL &&
+ ep1_ch1()->receiving() && ep1_ch1()->writable() &&
+ ep2_ch1()->receiving() && ep2_ch1()->writable(),
+ 1000, 1000);
+ TestSendRecv(1);
+ // Make sure the P2PTransportChannels are actually using ports from the
+ // pooled sessions.
+ auto pooled_ports_1 = pooled_session_1->ReadyPorts();
+ auto pooled_ports_2 = pooled_session_2->ReadyPorts();
+ EXPECT_NE(pooled_ports_1.end(),
+ std::find(pooled_ports_1.begin(), pooled_ports_1.end(),
+ ep1_ch1()->best_connection()->port()));
+ EXPECT_NE(pooled_ports_2.end(),
+ std::find(pooled_ports_2.begin(), pooled_ports_2.end(),
+ ep2_ch1()->best_connection()->port()));
+}
+
// Test what happens when we have 2 users behind the same NAT. This can lead
// to interesting behavior because the STUN server will only give out the
// address of the outermost NAT.
diff --git a/webrtc/p2p/base/port.cc b/webrtc/p2p/base/port.cc
index a353dc2..fbc64f2 100644
--- a/webrtc/p2p/base/port.cc
+++ b/webrtc/p2p/base/port.cc
@@ -219,6 +219,19 @@
delete list[i];
}
+void Port::SetIceParameters(int component,
+ const std::string& username_fragment,
+ const std::string& password) {
+ component_ = component;
+ ice_username_fragment_ = username_fragment;
+ password_ = password;
+ for (Candidate& c : candidates_) {
+ c.set_component(component);
+ c.set_username(username_fragment);
+ c.set_password(password);
+ }
+}
+
Connection* Port::GetConnection(const rtc::SocketAddress& remote_addr) {
AddressMap::const_iterator iter = connections_.find(remote_addr);
if (iter != connections_.end())
diff --git a/webrtc/p2p/base/port.h b/webrtc/p2p/base/port.h
index 7ec33bc..937f3cd 100644
--- a/webrtc/p2p/base/port.h
+++ b/webrtc/p2p/base/port.h
@@ -107,6 +107,11 @@
: address(a), proto(p), secure(false) { }
ProtocolAddress(const rtc::SocketAddress& a, ProtocolType p, bool sec)
: address(a), proto(p), secure(sec) { }
+
+ bool operator==(const ProtocolAddress& o) const {
+ return address == o.address && proto == o.proto && secure == o.secure;
+ }
+ bool operator!=(const ProtocolAddress& o) const { return !(*this == o); }
};
typedef std::set<rtc::SocketAddress> ServerAddresses;
@@ -176,23 +181,16 @@
uint32_t generation() { return generation_; }
void set_generation(uint32_t generation) { generation_ = generation; }
- // ICE requires a single username/password per content/media line. So the
- // |ice_username_fragment_| of the ports that belongs to the same content will
- // be the same. However this causes a small complication with our relay
- // server, which expects different username for RTP and RTCP.
- //
- // To resolve this problem, we implemented the username_fragment(),
- // which returns a different username (calculated from
- // |ice_username_fragment_|) for RTCP in the case of ICEPROTO_GOOGLE. And the
- // username_fragment() simply returns |ice_username_fragment_| when running
- // in ICEPROTO_RFC5245.
- //
- // As a result the ICEPROTO_GOOGLE will use different usernames for RTP and
- // RTCP. And the ICEPROTO_RFC5245 will use same username for both RTP and
- // RTCP.
const std::string username_fragment() const;
const std::string& password() const { return password_; }
+ // May be called when this port was initially created by a pooled
+ // PortAllocatorSession, and is now being assigned to an ICE transport.
+ // Updates the information for candidates as well.
+ void SetIceParameters(int component,
+ const std::string& username_fragment,
+ const std::string& password);
+
// Fired when candidates are discovered by the port. When all candidates
// are discovered that belong to port SignalAddressReady is fired.
sigslot::signal2<Port*, const Candidate&> SignalCandidateReady;
diff --git a/webrtc/p2p/base/port_unittest.cc b/webrtc/p2p/base/port_unittest.cc
index ab48ec9..efc2609 100644
--- a/webrtc/p2p/base/port_unittest.cc
+++ b/webrtc/p2p/base/port_unittest.cc
@@ -2586,3 +2586,20 @@
EXPECT_TRUE(turn_port->SupportsProtocol(UDP_PROTOCOL_NAME));
EXPECT_FALSE(turn_port->SupportsProtocol(TCP_PROTOCOL_NAME));
}
+
+// Test that SetIceParameters updates the component, ufrag and password
+// on both the port itself and its candidates.
+TEST_F(PortTest, TestSetIceParameters) {
+ std::unique_ptr<TestPort> port(
+ CreateTestPort(kLocalAddr1, "ufrag1", "password1"));
+ port->PrepareAddress();
+ EXPECT_EQ(1UL, port->Candidates().size());
+ port->SetIceParameters(1, "ufrag2", "password2");
+ EXPECT_EQ(1, port->component());
+ EXPECT_EQ("ufrag2", port->username_fragment());
+ EXPECT_EQ("password2", port->password());
+ const Candidate& candidate = port->Candidates()[0];
+ EXPECT_EQ(1, candidate.component());
+ EXPECT_EQ("ufrag2", candidate.username());
+ EXPECT_EQ("password2", candidate.password());
+}
diff --git a/webrtc/p2p/base/portallocator.cc b/webrtc/p2p/base/portallocator.cc
index 5c4243a..fdf213b 100644
--- a/webrtc/p2p/base/portallocator.cc
+++ b/webrtc/p2p/base/portallocator.cc
@@ -18,23 +18,85 @@
const std::string& ice_ufrag,
const std::string& ice_pwd,
uint32_t flags)
- : content_name_(content_name),
- component_(component),
- flags_(flags),
+ : flags_(flags),
generation_(0),
+ content_name_(content_name),
+ component_(component),
ice_ufrag_(ice_ufrag),
ice_pwd_(ice_pwd) {
- RTC_DCHECK(!ice_ufrag.empty());
- RTC_DCHECK(!ice_pwd.empty());
+ // Pooled sessions are allowed to be created with empty content name,
+ // component, ufrag and password.
+ RTC_DCHECK(ice_ufrag.empty() == ice_pwd.empty());
}
-PortAllocatorSession* PortAllocator::CreateSession(
+void PortAllocator::SetConfiguration(
+ const ServerAddresses& stun_servers,
+ const std::vector<RelayServerConfig>& turn_servers,
+ int candidate_pool_size) {
+ bool ice_servers_changed =
+ (stun_servers != stun_servers_ || turn_servers != turn_servers_);
+ stun_servers_ = stun_servers;
+ turn_servers_ = turn_servers;
+
+ // If ICE servers changed, throw away any existing pooled sessions and create
+ // new ones.
+ if (ice_servers_changed) {
+ pooled_sessions_.clear();
+ allocated_pooled_session_count_ = 0;
+ }
+
+ // If |size| is less than the number of allocated sessions, get rid of the
+ // extras.
+ while (allocated_pooled_session_count_ > candidate_pool_size &&
+ !pooled_sessions_.empty()) {
+ pooled_sessions_.front().reset(nullptr);
+ pooled_sessions_.pop_front();
+ --allocated_pooled_session_count_;
+ }
+ // If |size| is greater than the number of allocated sessions, create new
+ // sessions.
+ while (allocated_pooled_session_count_ < candidate_pool_size) {
+ PortAllocatorSession* pooled_session = CreateSessionInternal("", 0, "", "");
+ pooled_session->StartGettingPorts();
+ pooled_sessions_.push_back(
+ std::unique_ptr<PortAllocatorSession>(pooled_session));
+ ++allocated_pooled_session_count_;
+ }
+ target_pooled_session_count_ = candidate_pool_size;
+}
+
+std::unique_ptr<PortAllocatorSession> PortAllocator::CreateSession(
const std::string& sid,
const std::string& content_name,
int component,
const std::string& ice_ufrag,
const std::string& ice_pwd) {
- return CreateSessionInternal(content_name, component, ice_ufrag, ice_pwd);
+ return std::unique_ptr<PortAllocatorSession>(
+ CreateSessionInternal(content_name, component, ice_ufrag, ice_pwd));
+}
+
+std::unique_ptr<PortAllocatorSession> PortAllocator::TakePooledSession(
+ const std::string& content_name,
+ int component,
+ const std::string& ice_ufrag,
+ const std::string& ice_pwd) {
+ RTC_DCHECK(!ice_ufrag.empty());
+ RTC_DCHECK(!ice_pwd.empty());
+ if (pooled_sessions_.empty()) {
+ return nullptr;
+ }
+ std::unique_ptr<PortAllocatorSession> ret =
+ std::move(pooled_sessions_.front());
+ ret->SetIceParameters(content_name, component, ice_ufrag, ice_pwd);
+ pooled_sessions_.pop_front();
+ return ret;
+}
+
+const PortAllocatorSession* PortAllocator::GetPooledSession() const {
+ if (pooled_sessions_.empty()) {
+ return nullptr;
+ }
+ return pooled_sessions_.front().get();
}
} // namespace cricket
diff --git a/webrtc/p2p/base/portallocator.h b/webrtc/p2p/base/portallocator.h
index 6fb79b0..8796570 100644
--- a/webrtc/p2p/base/portallocator.h
+++ b/webrtc/p2p/base/portallocator.h
@@ -11,6 +11,8 @@
#ifndef WEBRTC_P2P_BASE_PORTALLOCATOR_H_
#define WEBRTC_P2P_BASE_PORTALLOCATOR_H_
+#include <deque>
+#include <memory>
#include <string>
#include <vector>
@@ -19,6 +21,7 @@
#include "webrtc/base/helpers.h"
#include "webrtc/base/proxyinfo.h"
#include "webrtc/base/sigslot.h"
+#include "webrtc/base/thread.h"
namespace cricket {
@@ -82,6 +85,11 @@
RelayCredentials(const std::string& username, const std::string& password)
: username(username), password(password) {}
+ bool operator==(const RelayCredentials& o) const {
+ return username == o.username && password == o.password;
+ }
+ bool operator!=(const RelayCredentials& o) const { return !(*this == o); }
+
std::string username;
std::string password;
};
@@ -89,7 +97,7 @@
typedef std::vector<ProtocolAddress> PortList;
// TODO(deadbeef): Rename to TurnServerConfig.
struct RelayServerConfig {
- RelayServerConfig(RelayType type) : type(type), priority(0) {}
+ RelayServerConfig(RelayType type) : type(type) {}
RelayServerConfig(const std::string& address,
int port,
@@ -102,10 +110,16 @@
ProtocolAddress(rtc::SocketAddress(address, port), proto, secure));
}
+ bool operator==(const RelayServerConfig& o) const {
+ return type == o.type && ports == o.ports && credentials == o.credentials &&
+ priority == o.priority;
+ }
+ bool operator!=(const RelayServerConfig& o) const { return !(*this == o); }
+
RelayType type;
PortList ports;
RelayCredentials credentials;
- int priority;
+ int priority = 0;
};
class PortAllocatorSession : public sigslot::has_slots<> {
@@ -124,6 +138,9 @@
void set_flags(uint32_t flags) { flags_ = flags; }
std::string content_name() const { return content_name_; }
int component() const { return component_; }
+ const std::string& ice_ufrag() const { return ice_ufrag_; }
+ const std::string& ice_pwd() const { return ice_pwd_; }
+ bool pooled() const { return ice_ufrag_.empty(); }
// Starts gathering STUN and Relay configurations.
virtual void StartGettingPorts() = 0;
@@ -133,6 +150,14 @@
// Whether the process of getting ports has been stopped.
virtual bool IsGettingPorts() = 0;
+ // Another way of getting the information provided by the signals below.
+ //
+ // Ports and candidates are not guaranteed to be in the same order as the
+ // signals were emitted in.
+ virtual std::vector<PortInterface*> ReadyPorts() const = 0;
+ virtual std::vector<Candidate> ReadyCandidates() const = 0;
+ virtual bool CandidatesAllocationDone() const = 0;
+
sigslot::signal2<PortAllocatorSession*, PortInterface*> SignalPortReady;
sigslot::signal2<PortAllocatorSession*,
const std::vector<Candidate>&> SignalCandidatesReady;
@@ -142,25 +167,46 @@
virtual void set_generation(uint32_t generation) { generation_ = generation; }
sigslot::signal1<PortAllocatorSession*> SignalDestroyed;
- const std::string& ice_ufrag() const { return ice_ufrag_; }
- const std::string& ice_pwd() const { return ice_pwd_; }
-
protected:
+ // This method is called when a pooled session (which doesn't have these
+ // properties initially) is returned by PortAllocator::TakePooledSession,
+ // and the content name, component, and ICE ufrag/pwd are updated.
+ //
+ // A subclass may need to override this method to perform additional actions,
+ // such as applying the updated information to ports and candidates.
+ virtual void UpdateIceParametersInternal() {}
+
// TODO(deadbeef): Get rid of these when everyone switches to ice_ufrag and
// ice_pwd.
const std::string& username() const { return ice_ufrag_; }
const std::string& password() const { return ice_pwd_; }
- std::string content_name_;
- int component_;
-
private:
+ void SetIceParameters(const std::string& content_name,
+ int component,
+ const std::string& ice_ufrag,
+ const std::string& ice_pwd) {
+ content_name_ = content_name;
+ component_ = component;
+ ice_ufrag_ = ice_ufrag;
+ ice_pwd_ = ice_pwd;
+ UpdateIceParametersInternal();
+ }
+
uint32_t flags_;
uint32_t generation_;
+ std::string content_name_;
+ int component_;
std::string ice_ufrag_;
std::string ice_pwd_;
+
+ // SetIceParameters is an implementation detail which only PortAllocator
+ // should be able to call.
+ friend class PortAllocator;
};
+// Note that this class should only be used on one thread.
+// This includes calling the destructor.
class PortAllocator : public sigslot::has_slots<> {
public:
PortAllocator() :
@@ -174,10 +220,25 @@
}
virtual ~PortAllocator() {}
- // Set STUN and TURN servers to be used in future sessions.
- virtual void SetIceServers(
- const ServerAddresses& stun_servers,
- const std::vector<RelayServerConfig>& turn_servers) = 0;
+ // Set STUN and TURN servers to be used in future sessions, and set
+ // candidate pool size, as described in JSEP.
+ //
+ // If the servers are changing and the candidate pool size is nonzero,
+ // existing pooled sessions will be destroyed and new ones created.
+ //
+ // If the servers are not changing but the candidate pool size is,
+ // pooled sessions will be either created or destroyed as necessary.
+ void SetConfiguration(const ServerAddresses& stun_servers,
+ const std::vector<RelayServerConfig>& turn_servers,
+ int candidate_pool_size);
+
+ const ServerAddresses& stun_servers() const { return stun_servers_; }
+
+ const std::vector<RelayServerConfig>& turn_servers() const {
+ return turn_servers_;
+ }
+
+ int candidate_pool_size() const { return target_pooled_session_count_; }
// Sets the network types to ignore.
// Values are defined by the AdapterType enum.
@@ -186,13 +247,27 @@
// loopback interfaces.
virtual void SetNetworkIgnoreMask(int network_ignore_mask) = 0;
- PortAllocatorSession* CreateSession(
+ std::unique_ptr<PortAllocatorSession> CreateSession(
const std::string& sid,
const std::string& content_name,
int component,
const std::string& ice_ufrag,
const std::string& ice_pwd);
+ // Get an available pooled session and set the transport information on it.
+ //
+ // Caller takes ownership of the returned session.
+ //
+ // If no pooled sessions are available, returns null.
+ std::unique_ptr<PortAllocatorSession> TakePooledSession(
+ const std::string& content_name,
+ int component,
+ const std::string& ice_ufrag,
+ const std::string& ice_pwd);
+
+ // Returns the next session that would be returned by TakePooledSession.
+ const PortAllocatorSession* GetPooledSession() const;
+
uint32_t flags() const { return flags_; }
void set_flags(uint32_t flags) { flags_ = flags; }
@@ -225,10 +300,9 @@
}
uint32_t candidate_filter() { return candidate_filter_; }
- bool set_candidate_filter(uint32_t filter) {
+ void set_candidate_filter(uint32_t filter) {
// TODO(mallinath) - Do transition check?
candidate_filter_ = filter;
- return true;
}
// Gets/Sets the Origin value used for WebRTC STUN requests.
@@ -251,6 +325,16 @@
bool allow_tcp_listen_;
uint32_t candidate_filter_;
std::string origin_;
+
+ private:
+ ServerAddresses stun_servers_;
+ std::vector<RelayServerConfig> turn_servers_;
+ // The last size passed into SetConfiguration.
+ int target_pooled_session_count_ = 0;
+ // This variable represents the total number of pooled sessions
+ // both owned by this class and taken by TakePooledSession.
+ int allocated_pooled_session_count_ = 0;
+ std::deque<std::unique_ptr<PortAllocatorSession>> pooled_sessions_;
};
} // namespace cricket
diff --git a/webrtc/p2p/base/portallocator_unittest.cc b/webrtc/p2p/base/portallocator_unittest.cc
new file mode 100644
index 0000000..2e16725
--- /dev/null
+++ b/webrtc/p2p/base/portallocator_unittest.cc
@@ -0,0 +1,205 @@
+/*
+ * Copyright 2016 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include <memory>
+
+#include "webrtc/base/gunit.h"
+#include "webrtc/base/thread.h"
+#include "webrtc/p2p/base/fakeportallocator.h"
+#include "webrtc/p2p/base/portallocator.h"
+
+static const char kContentName[] = "test content";
+// Based on ICE_UFRAG_LENGTH
+static const char kIceUfrag[] = "TESTICEUFRAG0000";
+// Based on ICE_PWD_LENGTH
+static const char kIcePwd[] = "TESTICEPWD00000000000000";
+static const char kTurnUsername[] = "test";
+static const char kTurnPassword[] = "test";
+
+class PortAllocatorTest : public testing::Test, public sigslot::has_slots<> {
+ public:
+ PortAllocatorTest() {
+ allocator_.reset(
+ new cricket::FakePortAllocator(rtc::Thread::Current(), nullptr));
+ }
+
+ protected:
+ void SetConfigurationWithPoolSize(int candidate_pool_size) {
+ allocator_->SetConfiguration(cricket::ServerAddresses(),
+ std::vector<cricket::RelayServerConfig>(),
+ candidate_pool_size);
+ }
+
+ const cricket::FakePortAllocatorSession* GetPooledSession() const {
+ return static_cast<const cricket::FakePortAllocatorSession*>(
+ allocator_->GetPooledSession());
+ }
+
+ std::unique_ptr<cricket::FakePortAllocatorSession> TakePooledSession() {
+ return std::unique_ptr<cricket::FakePortAllocatorSession>(
+ static_cast<cricket::FakePortAllocatorSession*>(
+ allocator_->TakePooledSession(kContentName, 0, kIceUfrag, kIcePwd)
+ .release()));
+ }
+
+ int GetAllPooledSessionsReturnCount() {
+ int count = 0;
+ while (GetPooledSession()) {
+ TakePooledSession();
+ ++count;
+ }
+ return count;
+ }
+
+ std::unique_ptr<cricket::FakePortAllocator> allocator_;
+ rtc::SocketAddress stun_server_1{"11.11.11.11", 3478};
+ rtc::SocketAddress stun_server_2{"22.22.22.22", 3478};
+ cricket::RelayServerConfig turn_server_1{"11.11.11.11", 3478,
+ kTurnUsername, kTurnPassword,
+ cricket::PROTO_UDP, false};
+ cricket::RelayServerConfig turn_server_2{"22.22.22.22", 3478,
+ kTurnUsername, kTurnPassword,
+ cricket::PROTO_UDP, false};
+};
+
+TEST_F(PortAllocatorTest, TestDefaults) {
+ EXPECT_EQ(0UL, allocator_->stun_servers().size());
+ EXPECT_EQ(0UL, allocator_->turn_servers().size());
+ EXPECT_EQ(0, allocator_->candidate_pool_size());
+ EXPECT_EQ(0, GetAllPooledSessionsReturnCount());
+}
+
+TEST_F(PortAllocatorTest, SetConfigurationUpdatesIceServers) {
+ cricket::ServerAddresses stun_servers_1 = {stun_server_1};
+ std::vector<cricket::RelayServerConfig> turn_servers_1 = {turn_server_1};
+ allocator_->SetConfiguration(stun_servers_1, turn_servers_1, 0);
+ EXPECT_EQ(stun_servers_1, allocator_->stun_servers());
+ EXPECT_EQ(turn_servers_1, allocator_->turn_servers());
+
+ // Update with a different set of servers.
+ cricket::ServerAddresses stun_servers_2 = {stun_server_2};
+ std::vector<cricket::RelayServerConfig> turn_servers_2 = {turn_server_2};
+ allocator_->SetConfiguration(stun_servers_2, turn_servers_2, 0);
+ EXPECT_EQ(stun_servers_2, allocator_->stun_servers());
+ EXPECT_EQ(turn_servers_2, allocator_->turn_servers());
+}
+
+TEST_F(PortAllocatorTest, SetConfigurationUpdatesCandidatePoolSize) {
+ SetConfigurationWithPoolSize(2);
+ EXPECT_EQ(2, allocator_->candidate_pool_size());
+ SetConfigurationWithPoolSize(3);
+ EXPECT_EQ(3, allocator_->candidate_pool_size());
+ SetConfigurationWithPoolSize(1);
+ EXPECT_EQ(1, allocator_->candidate_pool_size());
+ SetConfigurationWithPoolSize(4);
+ EXPECT_EQ(4, allocator_->candidate_pool_size());
+}
+
+// A negative pool size should just be treated as zero.
+TEST_F(PortAllocatorTest, SetConfigurationWithNegativePoolSizeDoesntCrash) {
+ SetConfigurationWithPoolSize(-1);
+ // No asserts; we're just testing that this doesn't crash.
+}
+
+// Test that if the candidate pool size is nonzero, pooled sessions are
+// created, and StartGettingPorts is called on them.
+TEST_F(PortAllocatorTest, SetConfigurationCreatesPooledSessions) {
+ SetConfigurationWithPoolSize(2);
+ auto session_1 = TakePooledSession();
+ auto session_2 = TakePooledSession();
+ ASSERT_NE(nullptr, session_1.get());
+ ASSERT_NE(nullptr, session_2.get());
+ EXPECT_EQ(1, session_1->port_config_count());
+ EXPECT_EQ(1, session_2->port_config_count());
+ EXPECT_EQ(0, GetAllPooledSessionsReturnCount());
+}
+
+// Test that if the candidate pool size is increased, pooled sessions are
+// created as necessary.
+TEST_F(PortAllocatorTest, SetConfigurationCreatesMorePooledSessions) {
+ SetConfigurationWithPoolSize(1);
+ SetConfigurationWithPoolSize(2);
+ EXPECT_EQ(2, GetAllPooledSessionsReturnCount());
+}
+
+// Test that if the candidate pool size is reduced, extra sessions are
+// destroyed.
+TEST_F(PortAllocatorTest, SetConfigurationDestroysPooledSessions) {
+ SetConfigurationWithPoolSize(2);
+ SetConfigurationWithPoolSize(1);
+ EXPECT_EQ(1, GetAllPooledSessionsReturnCount());
+}
+
+// Test that if the candidate pool size is reduced and increased, but reducing
+// didn't actually destroy any sessions (because they were already given away),
+// increasing the size to its initial value doesn't create a new session.
+TEST_F(PortAllocatorTest, SetConfigurationDoesntCreateExtraSessions) {
+ SetConfigurationWithPoolSize(1);
+ TakePooledSession();
+ SetConfigurationWithPoolSize(0);
+ SetConfigurationWithPoolSize(1);
+ EXPECT_EQ(0, GetAllPooledSessionsReturnCount());
+}
+
+// According to JSEP, exising pooled sessions should be destroyed and new
+// ones created when the ICE servers change.
+TEST_F(PortAllocatorTest,
+ SetConfigurationRecreatesPooledSessionsWhenIceServersChange) {
+ cricket::ServerAddresses stun_servers_1 = {stun_server_1};
+ std::vector<cricket::RelayServerConfig> turn_servers_1 = {turn_server_1};
+ allocator_->SetConfiguration(stun_servers_1, turn_servers_1, 1);
+ EXPECT_EQ(stun_servers_1, allocator_->stun_servers());
+ EXPECT_EQ(turn_servers_1, allocator_->turn_servers());
+
+ // Update with a different set of servers (and also change pool size).
+ cricket::ServerAddresses stun_servers_2 = {stun_server_2};
+ std::vector<cricket::RelayServerConfig> turn_servers_2 = {turn_server_2};
+ allocator_->SetConfiguration(stun_servers_2, turn_servers_2, 2);
+ EXPECT_EQ(stun_servers_2, allocator_->stun_servers());
+ EXPECT_EQ(turn_servers_2, allocator_->turn_servers());
+ auto session_1 = TakePooledSession();
+ auto session_2 = TakePooledSession();
+ ASSERT_NE(nullptr, session_1.get());
+ ASSERT_NE(nullptr, session_2.get());
+ EXPECT_EQ(stun_servers_2, session_1->stun_servers());
+ EXPECT_EQ(turn_servers_2, session_1->turn_servers());
+ EXPECT_EQ(stun_servers_2, session_2->stun_servers());
+ EXPECT_EQ(turn_servers_2, session_2->turn_servers());
+ EXPECT_EQ(0, GetAllPooledSessionsReturnCount());
+}
+
+TEST_F(PortAllocatorTest, GetPooledSessionReturnsNextSession) {
+ SetConfigurationWithPoolSize(2);
+ auto peeked_session_1 = GetPooledSession();
+ auto session_1 = TakePooledSession();
+ EXPECT_EQ(session_1.get(), peeked_session_1);
+ auto peeked_session_2 = GetPooledSession();
+ auto session_2 = TakePooledSession();
+ EXPECT_EQ(session_2.get(), peeked_session_2);
+}
+
+// Verify that subclasses of PortAllocatorSession are given a chance to update
+// ICE parameters when TakePooledSession is called, and the base class updates
+// the info itself.
+TEST_F(PortAllocatorTest, TakePooledSessionUpdatesIceParameters) {
+ SetConfigurationWithPoolSize(1);
+ auto peeked_session = GetPooledSession();
+ ASSERT_NE(nullptr, peeked_session);
+ EXPECT_EQ(0, peeked_session->transport_info_update_count());
+ std::unique_ptr<cricket::FakePortAllocatorSession> session(
+ static_cast<cricket::FakePortAllocatorSession*>(
+ allocator_->TakePooledSession(kContentName, 1, kIceUfrag, kIcePwd)
+ .release()));
+ EXPECT_EQ(1, session->transport_info_update_count());
+ EXPECT_EQ(kContentName, session->content_name());
+ EXPECT_EQ(1, session->component());
+ EXPECT_EQ(kIceUfrag, session->ice_ufrag());
+ EXPECT_EQ(kIcePwd, session->ice_pwd());
+}
diff --git a/webrtc/p2p/base/transportcontroller_unittest.cc b/webrtc/p2p/base/transportcontroller_unittest.cc
index 6b64912..627975c 100644
--- a/webrtc/p2p/base/transportcontroller_unittest.cc
+++ b/webrtc/p2p/base/transportcontroller_unittest.cc
@@ -17,11 +17,11 @@
#include "webrtc/base/sslidentity.h"
#include "webrtc/base/thread.h"
#include "webrtc/p2p/base/dtlstransportchannel.h"
+#include "webrtc/p2p/base/fakeportallocator.h"
#include "webrtc/p2p/base/faketransportcontroller.h"
#include "webrtc/p2p/base/p2ptransportchannel.h"
#include "webrtc/p2p/base/portallocator.h"
#include "webrtc/p2p/base/transportcontroller.h"
-#include "webrtc/p2p/client/fakeportallocator.h"
static const int kTimeout = 100;
static const char kIceUfrag1[] = "TESTICEUFRAG0001";
diff --git a/webrtc/p2p/client/basicportallocator.cc b/webrtc/p2p/client/basicportallocator.cc
index edfd021..143b036 100644
--- a/webrtc/p2p/client/basicportallocator.cc
+++ b/webrtc/p2p/client/basicportallocator.cc
@@ -64,33 +64,26 @@
PORTALLOCATOR_DISABLE_STUN | PORTALLOCATOR_DISABLE_RELAY;
// BasicPortAllocator
-BasicPortAllocator::BasicPortAllocator(
- rtc::NetworkManager* network_manager,
- rtc::PacketSocketFactory* socket_factory)
- : network_manager_(network_manager),
- socket_factory_(socket_factory),
- stun_servers_() {
+BasicPortAllocator::BasicPortAllocator(rtc::NetworkManager* network_manager,
+ rtc::PacketSocketFactory* socket_factory)
+ : network_manager_(network_manager), socket_factory_(socket_factory) {
ASSERT(network_manager_ != nullptr);
ASSERT(socket_factory_ != nullptr);
Construct();
}
BasicPortAllocator::BasicPortAllocator(rtc::NetworkManager* network_manager)
- : network_manager_(network_manager),
- socket_factory_(nullptr),
- stun_servers_() {
+ : network_manager_(network_manager), socket_factory_(nullptr) {
ASSERT(network_manager_ != nullptr);
Construct();
}
-BasicPortAllocator::BasicPortAllocator(
- rtc::NetworkManager* network_manager,
- rtc::PacketSocketFactory* socket_factory,
- const ServerAddresses& stun_servers)
- : network_manager_(network_manager),
- socket_factory_(socket_factory),
- stun_servers_(stun_servers) {
+BasicPortAllocator::BasicPortAllocator(rtc::NetworkManager* network_manager,
+ rtc::PacketSocketFactory* socket_factory,
+ const ServerAddresses& stun_servers)
+ : network_manager_(network_manager), socket_factory_(socket_factory) {
ASSERT(socket_factory_ != NULL);
+ SetConfiguration(stun_servers, std::vector<RelayServerConfig>(), 0);
Construct();
}
@@ -100,10 +93,8 @@
const rtc::SocketAddress& relay_address_udp,
const rtc::SocketAddress& relay_address_tcp,
const rtc::SocketAddress& relay_address_ssl)
- : network_manager_(network_manager),
- socket_factory_(NULL),
- stun_servers_(stun_servers) {
-
+ : network_manager_(network_manager), socket_factory_(NULL) {
+ std::vector<RelayServerConfig> turn_servers;
RelayServerConfig config(RELAY_GTURN);
if (!relay_address_udp.IsNil()) {
config.ports.push_back(ProtocolAddress(relay_address_udp, PROTO_UDP));
@@ -116,9 +107,10 @@
}
if (!config.ports.empty()) {
- AddTurnServer(config);
+ turn_servers.push_back(config);
}
+ SetConfiguration(stun_servers, turn_servers, 0);
Construct();
}
@@ -136,6 +128,11 @@
this, content_name, component, ice_ufrag, ice_pwd);
}
+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());
+}
// BasicPortAllocatorSession
BasicPortAllocatorSession::BasicPortAllocatorSession(
@@ -207,6 +204,61 @@
sequences_[i]->Stop();
}
+std::vector<PortInterface*> BasicPortAllocatorSession::ReadyPorts() const {
+ std::vector<PortInterface*> ret;
+ for (const PortData& port : ports_) {
+ if (port.ready() || port.complete()) {
+ ret.push_back(port.port());
+ }
+ }
+ return ret;
+}
+
+std::vector<Candidate> BasicPortAllocatorSession::ReadyCandidates() const {
+ std::vector<Candidate> candidates;
+ for (const PortData& data : ports_) {
+ 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(candidate);
+ }
+ }
+ return candidates;
+}
+
+bool BasicPortAllocatorSession::CandidatesAllocationDone() const {
+ // Done only if all required AllocationSequence objects
+ // are created.
+ if (!allocation_sequences_created_) {
+ return false;
+ }
+
+ // Check that all port allocation sequences are complete (not running).
+ if (std::any_of(sequences_.begin(), sequences_.end(),
+ [](const AllocationSequence* sequence) {
+ return sequence->state() == AllocationSequence::kRunning;
+ })) {
+ return false;
+ }
+
+ // If all allocated ports are in complete state, 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;
+}
+
void BasicPortAllocatorSession::OnMessage(rtc::Message *message) {
switch (message->message_id) {
case MSG_CONFIG_START:
@@ -241,6 +293,13 @@
}
}
+void BasicPortAllocatorSession::UpdateIceParametersInternal() {
+ for (PortData& port : ports_) {
+ port.port()->set_content_name(content_name());
+ port.port()->SetIceParameters(component(), ice_ufrag(), ice_pwd());
+ }
+}
+
void BasicPortAllocatorSession::GetPortConfigurations() {
PortConfiguration* config = new PortConfiguration(allocator_->stun_servers(),
username(),
@@ -274,7 +333,7 @@
bool send_signal = false;
for (std::vector<PortData>::iterator it = ports_.begin();
it != ports_.end(); ++it) {
- if (!it->complete()) {
+ if (!it->complete() && !it->error()) {
// Updating port state to error, which didn't finish allocating candidates
// yet.
it->set_error();
@@ -436,12 +495,12 @@
LOG(LS_INFO) << "Adding allocated port for " << content_name();
port->set_content_name(content_name());
- port->set_component(component_);
+ port->set_component(component());
port->set_generation(generation());
if (allocator_->proxy().type != rtc::PROXY_NONE)
port->set_proxy(allocator_->user_agent(), allocator_->proxy());
- port->set_send_retransmit_count_attribute((allocator_->flags() &
- PORTALLOCATOR_ENABLE_STUN_RETRANSMIT_ATTRIBUTE) != 0);
+ port->set_send_retransmit_count_attribute(
+ (flags() & PORTALLOCATOR_ENABLE_STUN_RETRANSMIT_ATTRIBUTE) != 0);
// Push down the candidate_filter to individual port.
uint32_t candidate_filter = allocator_->candidate_filter();
@@ -484,8 +543,9 @@
ASSERT(data != NULL);
// Discarding any candidate signal if port allocation status is
// already in completed state.
- if (data->complete())
+ if (data->complete() || data->error()) {
return;
+ }
ProtocolType pvalue;
bool candidate_signalable = CheckCandidateFilter(c);
@@ -536,8 +596,9 @@
ASSERT(data != NULL);
// Ignore any late signals.
- if (data->complete())
+ if (data->complete() || data->error()) {
return;
+ }
// Moving to COMPLETE state.
data->set_complete();
@@ -550,8 +611,9 @@
PortData* data = FindPort(port);
ASSERT(data != NULL);
// We might have already given up on this port and stopped it.
- if (data->complete())
+ if (data->complete() || data->error()) {
return;
+ }
// SignalAddressError is currently sent from StunPort/TurnPort.
// But this signal itself is generic.
@@ -587,7 +649,7 @@
}
}
-bool BasicPortAllocatorSession::CheckCandidateFilter(const Candidate& c) {
+bool BasicPortAllocatorSession::CheckCandidateFilter(const Candidate& c) const {
uint32_t filter = allocator_->candidate_filter();
// When binding to any address, before sending packets out, the getsockname
@@ -625,29 +687,15 @@
}
void BasicPortAllocatorSession::MaybeSignalCandidatesAllocationDone() {
- // Send signal only if all required AllocationSequence objects
- // are created.
- if (!allocation_sequences_created_)
- return;
-
- // Check that all port allocation sequences are complete.
- for (std::vector<AllocationSequence*>::iterator it = sequences_.begin();
- it != sequences_.end(); ++it) {
- if ((*it)->state() == AllocationSequence::kRunning)
- return;
+ if (CandidatesAllocationDone()) {
+ if (pooled()) {
+ LOG(LS_INFO) << "All candidates gathered for pooled session.";
+ } else {
+ LOG(LS_INFO) << "All candidates gathered for " << content_name() << ":"
+ << component() << ":" << generation();
+ }
+ SignalCandidatesAllocationDone(this);
}
-
- // If all allocated ports are in complete state, session must have got all
- // expected candidates. Session will trigger candidates allocation complete
- // signal.
- for (std::vector<PortData>::iterator it = ports_.begin();
- it != ports_.end(); ++it) {
- if (!it->complete())
- return;
- }
- LOG(LS_INFO) << "All candidates gathered for " << content_name_ << ":"
- << component_ << ":" << generation();
- SignalCandidatesAllocationDone(this);
}
void BasicPortAllocatorSession::OnPortDestroyed(
diff --git a/webrtc/p2p/client/basicportallocator.h b/webrtc/p2p/client/basicportallocator.h
index c66ae59..ec1fcb5 100644
--- a/webrtc/p2p/client/basicportallocator.h
+++ b/webrtc/p2p/client/basicportallocator.h
@@ -38,13 +38,6 @@
const rtc::SocketAddress& relay_server_ssl);
virtual ~BasicPortAllocator();
- void SetIceServers(
- const ServerAddresses& stun_servers,
- const std::vector<RelayServerConfig>& turn_servers) override {
- stun_servers_ = stun_servers;
- turn_servers_ = turn_servers;
- }
-
// Set to kDefaultNetworkIgnoreMask by default.
void SetNetworkIgnoreMask(int network_ignore_mask) override {
// TODO(phoglund): implement support for other types than loopback.
@@ -61,30 +54,20 @@
// creates its own socket factory.
rtc::PacketSocketFactory* socket_factory() { return socket_factory_; }
- const ServerAddresses& stun_servers() const {
- return stun_servers_;
- }
-
- const std::vector<RelayServerConfig>& turn_servers() const {
- return turn_servers_;
- }
- virtual void AddTurnServer(const RelayServerConfig& turn_server) {
- turn_servers_.push_back(turn_server);
- }
-
PortAllocatorSession* CreateSessionInternal(
const std::string& content_name,
int component,
const std::string& ice_ufrag,
const std::string& ice_pwd) override;
+ // Convenience method that adds a TURN server to the configuration.
+ void AddTurnServer(const RelayServerConfig& turn_server);
+
private:
void Construct();
rtc::NetworkManager* network_manager_;
rtc::PacketSocketFactory* socket_factory_;
- ServerAddresses stun_servers_;
- std::vector<RelayServerConfig> turn_servers_;
bool allow_tcp_listen_;
int network_ignore_mask_ = rtc::kDefaultNetworkIgnoreMask;
};
@@ -110,8 +93,14 @@
void StopGettingPorts() override;
void ClearGettingPorts() override;
bool IsGettingPorts() override { return running_; }
+ // These will all be cricket::Ports.
+ std::vector<PortInterface*> ReadyPorts() const override;
+ std::vector<Candidate> ReadyCandidates() const override;
+ bool CandidatesAllocationDone() const override;
protected:
+ void UpdateIceParametersInternal() override;
+
// Starts the process of getting the port configurations.
virtual void GetPortConfigurations();
@@ -130,13 +119,11 @@
: port_(port), sequence_(seq), state_(STATE_INIT) {
}
- Port* port() { return port_; }
- AllocationSequence* sequence() { return sequence_; }
+ Port* port() const { return port_; }
+ AllocationSequence* sequence() const { return sequence_; }
bool ready() const { return state_ == STATE_READY; }
- bool complete() const {
- // Returns true if candidate allocation has completed one way or another.
- return ((state_ == STATE_COMPLETE) || (state_ == STATE_ERROR));
- }
+ bool complete() const { return state_ == STATE_COMPLETE; }
+ bool error() const { return state_ == STATE_ERROR; }
void set_ready() { ASSERT(state_ == STATE_INIT); state_ = STATE_READY; }
void set_complete() {
@@ -182,7 +169,7 @@
PortData* FindPort(Port* port);
void GetNetworks(std::vector<rtc::Network*>* networks);
- bool CheckCandidateFilter(const Candidate& c);
+ bool CheckCandidateFilter(const Candidate& c) const;
BasicPortAllocator* allocator_;
rtc::Thread* network_thread_;
diff --git a/webrtc/p2p/client/portallocator_unittest.cc b/webrtc/p2p/client/basicportallocator_unittest.cc
similarity index 79%
rename from webrtc/p2p/client/portallocator_unittest.cc
rename to webrtc/p2p/client/basicportallocator_unittest.cc
index 2181903..83d904f 100644
--- a/webrtc/p2p/client/portallocator_unittest.cc
+++ b/webrtc/p2p/client/basicportallocator_unittest.cc
@@ -8,6 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
+#include <algorithm>
#include <memory>
#include "webrtc/p2p/base/basicpacketsocketfactory.h"
@@ -42,8 +43,8 @@
static const SocketAddress kLoopbackAddr("127.0.0.1", 0);
static const SocketAddress kPrivateAddr("192.168.1.11", 0);
static const SocketAddress kPrivateAddr2("192.168.1.12", 0);
-static const SocketAddress kClientIPv6Addr(
- "2401:fa00:4:1000:be30:5bff:fee5:c3", 0);
+static const SocketAddress kClientIPv6Addr("2401:fa00:4:1000:be30:5bff:fee5:c3",
+ 0);
static const SocketAddress kClientAddr2("22.22.22.22", 0);
static const SocketAddress kNatUdpAddr("77.77.77.77", rtc::NAT_SERVER_UDP_PORT);
static const SocketAddress kNatTcpAddr("77.77.77.77", rtc::NAT_SERVER_TCP_PORT);
@@ -84,20 +85,25 @@
} // namespace cricket
-class PortAllocatorTest : public testing::Test, public sigslot::has_slots<> {
+class BasicPortAllocatorTest : public testing::Test,
+ public sigslot::has_slots<> {
public:
- PortAllocatorTest()
+ BasicPortAllocatorTest()
: pss_(new rtc::PhysicalSocketServer),
vss_(new rtc::VirtualSocketServer(pss_.get())),
fss_(new rtc::FirewallSocketServer(vss_.get())),
ss_scope_(fss_.get()),
nat_factory_(vss_.get(), kNatUdpAddr, kNatTcpAddr),
nat_socket_factory_(new rtc::BasicPacketSocketFactory(&nat_factory_)),
- stun_server_(cricket::TestStunServer::Create(Thread::Current(),
- kStunAddr)),
- relay_server_(Thread::Current(), kRelayUdpIntAddr, kRelayUdpExtAddr,
- kRelayTcpIntAddr, kRelayTcpExtAddr,
- kRelaySslTcpIntAddr, kRelaySslTcpExtAddr),
+ stun_server_(
+ cricket::TestStunServer::Create(Thread::Current(), kStunAddr)),
+ relay_server_(Thread::Current(),
+ kRelayUdpIntAddr,
+ kRelayUdpExtAddr,
+ kRelayTcpIntAddr,
+ kRelayTcpExtAddr,
+ kRelaySslTcpIntAddr,
+ kRelaySslTcpExtAddr),
turn_server_(Thread::Current(), kTurnUdpIntAddr, kTurnUdpExtAddr),
candidate_allocation_done_(false) {
cricket::ServerAddresses stun_servers;
@@ -105,9 +111,8 @@
// Passing the addresses of GTURN servers will enable GTURN in
// Basicportallocator.
allocator_.reset(new cricket::BasicPortAllocator(
- &network_manager_,
- stun_servers,
- kRelayUdpIntAddr, kRelayTcpIntAddr, kRelaySslTcpIntAddr));
+ &network_manager_, stun_servers, kRelayUdpIntAddr, kRelayTcpIntAddr,
+ kRelaySslTcpIntAddr));
allocator_->set_step_delay(cricket::kMinimumStepDelay);
}
@@ -178,55 +183,65 @@
}
bool CreateSession(int component) {
- session_.reset(CreateSession("session", component));
- if (!session_)
+ session_ = CreateSession("session", component);
+ if (!session_) {
return false;
+ }
return true;
}
bool CreateSession(int component, const std::string& content_name) {
- session_.reset(CreateSession("session", content_name, component));
- if (!session_)
+ session_ = CreateSession("session", content_name, component);
+ if (!session_) {
return false;
+ }
return true;
}
- cricket::PortAllocatorSession* CreateSession(
- const std::string& sid, int component) {
+ std::unique_ptr<cricket::PortAllocatorSession> CreateSession(
+ const std::string& sid,
+ int component) {
return CreateSession(sid, kContentName, component);
}
- cricket::PortAllocatorSession* CreateSession(
- const std::string& sid, const std::string& content_name, int component) {
+ std::unique_ptr<cricket::PortAllocatorSession> CreateSession(
+ const std::string& sid,
+ const std::string& content_name,
+ int component) {
return CreateSession(sid, content_name, component, kIceUfrag0, kIcePwd0);
}
- cricket::PortAllocatorSession* CreateSession(
- const std::string& sid, const std::string& content_name, int component,
- const std::string& ice_ufrag, const std::string& ice_pwd) {
- cricket::PortAllocatorSession* session =
- allocator_->CreateSession(
- sid, content_name, component, ice_ufrag, ice_pwd);
+ std::unique_ptr<cricket::PortAllocatorSession> CreateSession(
+ const std::string& sid,
+ const std::string& content_name,
+ int component,
+ const std::string& ice_ufrag,
+ const std::string& ice_pwd) {
+ std::unique_ptr<cricket::PortAllocatorSession> session =
+ allocator_->CreateSession(sid, content_name, component, ice_ufrag,
+ ice_pwd);
session->SignalPortReady.connect(this,
- &PortAllocatorTest::OnPortReady);
- session->SignalCandidatesReady.connect(this,
- &PortAllocatorTest::OnCandidatesReady);
- session->SignalCandidatesAllocationDone.connect(this,
- &PortAllocatorTest::OnCandidatesAllocationDone);
+ &BasicPortAllocatorTest::OnPortReady);
+ session->SignalCandidatesReady.connect(
+ this, &BasicPortAllocatorTest::OnCandidatesReady);
+ session->SignalCandidatesAllocationDone.connect(
+ this, &BasicPortAllocatorTest::OnCandidatesAllocationDone);
return session;
}
static bool CheckCandidate(const cricket::Candidate& c,
- int component, const std::string& type,
+ int component,
+ const std::string& type,
const std::string& proto,
const SocketAddress& addr) {
return (c.component() == component && c.type() == type &&
- c.protocol() == proto && c.address().ipaddr() == addr.ipaddr() &&
- ((addr.port() == 0 && (c.address().port() != 0)) ||
- (c.address().port() == addr.port())));
+ c.protocol() == proto && c.address().ipaddr() == addr.ipaddr() &&
+ ((addr.port() == 0 && (c.address().port() != 0)) ||
+ (c.address().port() == addr.port())));
}
static bool CheckPort(const rtc::SocketAddress& addr,
- int min_port, int max_port) {
+ int min_port,
+ int max_port) {
return (addr.port() >= min_port && addr.port() <= max_port);
}
@@ -237,6 +252,7 @@
ASSERT_FALSE(candidate_allocation_done_);
candidate_allocation_done_ = true;
}
+ EXPECT_TRUE(session->CandidatesAllocationDone());
}
// Check if all ports allocated have send-buffer size |expected|. If
@@ -247,11 +263,10 @@
int send_buffer_size;
if (expected == -1) {
EXPECT_EQ(SOCKET_ERROR,
- (*it)->GetOption(rtc::Socket::OPT_SNDBUF,
- &send_buffer_size));
+ (*it)->GetOption(rtc::Socket::OPT_SNDBUF, &send_buffer_size));
} else {
- EXPECT_EQ(0, (*it)->GetOption(rtc::Socket::OPT_SNDBUF,
- &send_buffer_size));
+ EXPECT_EQ(0,
+ (*it)->GetOption(rtc::Socket::OPT_SNDBUF, &send_buffer_size));
ASSERT_EQ(expected, send_buffer_size);
}
}
@@ -322,14 +337,16 @@
}
protected:
- cricket::BasicPortAllocator& allocator() {
- return *allocator_;
- }
+ cricket::BasicPortAllocator& allocator() { return *allocator_; }
void OnPortReady(cricket::PortAllocatorSession* ses,
cricket::PortInterface* port) {
LOG(LS_INFO) << "OnPortReady: " << port->ToString();
ports_.push_back(port);
+ // Make sure the new port is added to ReadyPorts.
+ auto ready_ports = ses->ReadyPorts();
+ EXPECT_NE(ready_ports.end(),
+ std::find(ready_ports.begin(), ready_ports.end(), port));
}
void OnCandidatesReady(cricket::PortAllocatorSession* ses,
const std::vector<cricket::Candidate>& candidates) {
@@ -337,6 +354,13 @@
LOG(LS_INFO) << "OnCandidatesReady: " << candidates[i].ToString();
candidates_.push_back(candidates[i]);
}
+ // Make sure the new candidates are added to Candidates.
+ auto ses_candidates = ses->ReadyCandidates();
+ for (const cricket::Candidate& candidate : candidates) {
+ EXPECT_NE(
+ ses_candidates.end(),
+ std::find(ses_candidates.begin(), ses_candidates.end(), candidate));
+ }
}
bool HasRelayAddress(const cricket::ProtocolAddress& proto_addr) {
@@ -344,7 +368,7 @@
cricket::RelayServerConfig server_config = allocator_->turn_servers()[i];
cricket::PortList::const_iterator relay_port;
for (relay_port = server_config.ports.begin();
- relay_port != server_config.ports.end(); ++relay_port) {
+ relay_port != server_config.ports.end(); ++relay_port) {
if (proto_addr.address == relay_port->address &&
proto_addr.proto == relay_port->proto)
return true;
@@ -391,7 +415,7 @@
};
// Tests that we can init the port allocator and create a session.
-TEST_F(PortAllocatorTest, TestBasic) {
+TEST_F(BasicPortAllocatorTest, TestBasic) {
EXPECT_EQ(&network_manager_, allocator().network_manager());
EXPECT_EQ(kStunAddr, *allocator().stun_servers().begin());
ASSERT_EQ(1u, allocator().turn_servers().size());
@@ -399,17 +423,18 @@
// Empty relay credentials are used for GTURN.
EXPECT_TRUE(allocator().turn_servers()[0].credentials.username.empty());
EXPECT_TRUE(allocator().turn_servers()[0].credentials.password.empty());
- EXPECT_TRUE(HasRelayAddress(cricket::ProtocolAddress(
- kRelayUdpIntAddr, cricket::PROTO_UDP)));
- EXPECT_TRUE(HasRelayAddress(cricket::ProtocolAddress(
- kRelayTcpIntAddr, cricket::PROTO_TCP)));
- EXPECT_TRUE(HasRelayAddress(cricket::ProtocolAddress(
- kRelaySslTcpIntAddr, cricket::PROTO_SSLTCP)));
+ EXPECT_TRUE(HasRelayAddress(
+ cricket::ProtocolAddress(kRelayUdpIntAddr, cricket::PROTO_UDP)));
+ EXPECT_TRUE(HasRelayAddress(
+ cricket::ProtocolAddress(kRelayTcpIntAddr, cricket::PROTO_TCP)));
+ EXPECT_TRUE(HasRelayAddress(
+ cricket::ProtocolAddress(kRelaySslTcpIntAddr, cricket::PROTO_SSLTCP)));
EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
+ EXPECT_FALSE(session_->CandidatesAllocationDone());
}
// Tests that our network filtering works properly.
-TEST_F(PortAllocatorTest, TestIgnoreOnlyLoopbackNetworkByDefault) {
+TEST_F(BasicPortAllocatorTest, TestIgnoreOnlyLoopbackNetworkByDefault) {
AddInterface(SocketAddress(IPAddress(0x12345600U), 0), "test_eth0",
rtc::ADAPTER_TYPE_ETHERNET);
AddInterface(SocketAddress(IPAddress(0x12345601U), 0), "test_wlan0",
@@ -432,7 +457,7 @@
}
}
-TEST_F(PortAllocatorTest, TestIgnoreNetworksAccordingToIgnoreMask) {
+TEST_F(BasicPortAllocatorTest, TestIgnoreNetworksAccordingToIgnoreMask) {
AddInterface(SocketAddress(IPAddress(0x12345600U), 0), "test_eth0",
rtc::ADAPTER_TYPE_ETHERNET);
AddInterface(SocketAddress(IPAddress(0x12345601U), 0), "test_wlan0",
@@ -453,7 +478,7 @@
}
// Tests that we allocator session not trying to allocate ports for every 250ms.
-TEST_F(PortAllocatorTest, TestNoNetworkInterface) {
+TEST_F(BasicPortAllocatorTest, TestNoNetworkInterface) {
EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
session_->StartGettingPorts();
// Waiting for one second to make sure BasicPortAllocatorSession has not
@@ -466,7 +491,7 @@
}
// Test that we could use loopback interface as host candidate.
-TEST_F(PortAllocatorTest, TestLoopbackNetworkInterface) {
+TEST_F(BasicPortAllocatorTest, TestLoopbackNetworkInterface) {
AddInterface(kLoopbackAddr, "test_loopback", rtc::ADAPTER_TYPE_LOOPBACK);
allocator_->SetNetworkIgnoreMask(0);
EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
@@ -479,34 +504,40 @@
}
// Tests that we can get all the desired addresses successfully.
-TEST_F(PortAllocatorTest, TestGetAllPortsWithMinimumStepDelay) {
+TEST_F(BasicPortAllocatorTest, TestGetAllPortsWithMinimumStepDelay) {
AddInterface(kClientAddr);
EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
session_->StartGettingPorts();
ASSERT_EQ_WAIT(7U, candidates_.size(), kDefaultAllocationTimeout);
EXPECT_EQ(4U, ports_.size());
EXPECT_PRED5(CheckCandidate, candidates_[0],
- cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "udp", kClientAddr);
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "udp",
+ kClientAddr);
EXPECT_PRED5(CheckCandidate, candidates_[1],
- cricket::ICE_CANDIDATE_COMPONENT_RTP, "stun", "udp", kClientAddr);
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "stun", "udp",
+ kClientAddr);
EXPECT_PRED5(CheckCandidate, candidates_[2],
- cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp", kRelayUdpIntAddr);
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp",
+ kRelayUdpIntAddr);
EXPECT_PRED5(CheckCandidate, candidates_[3],
- cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp", kRelayUdpExtAddr);
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp",
+ kRelayUdpExtAddr);
EXPECT_PRED5(CheckCandidate, candidates_[4],
- cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "tcp", kRelayTcpIntAddr);
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "tcp",
+ kRelayTcpIntAddr);
EXPECT_PRED5(CheckCandidate, candidates_[5],
- cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "tcp", kClientAddr);
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "tcp",
+ kClientAddr);
EXPECT_PRED5(CheckCandidate, candidates_[6],
- cricket::ICE_CANDIDATE_COMPONENT_RTP,
- "relay", "ssltcp", kRelaySslTcpIntAddr);
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "ssltcp",
+ kRelaySslTcpIntAddr);
EXPECT_TRUE(candidate_allocation_done_);
}
// Test that when the same network interface is brought down and up, the
// port allocator session will restart a new allocation sequence if
// it is not stopped.
-TEST_F(PortAllocatorTest, TestSameNetworkDownAndUpWhenSessionNotStopped) {
+TEST_F(BasicPortAllocatorTest, TestSameNetworkDownAndUpWhenSessionNotStopped) {
std::string if_name("test_net0");
AddInterface(kClientAddr, if_name);
EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
@@ -534,7 +565,7 @@
// Test that when the same network interface is brought down and up, the
// port allocator session will not restart a new allocation sequence if
// it is stopped.
-TEST_F(PortAllocatorTest, TestSameNetworkDownAndUpWhenSessionStopped) {
+TEST_F(BasicPortAllocatorTest, TestSameNetworkDownAndUpWhenSessionStopped) {
std::string if_name("test_net0");
AddInterface(kClientAddr, if_name);
EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
@@ -559,7 +590,7 @@
}
// Verify candidates with default step delay of 1sec.
-TEST_F(PortAllocatorTest, TestGetAllPortsWithOneSecondStepDelay) {
+TEST_F(BasicPortAllocatorTest, TestGetAllPortsWithOneSecondStepDelay) {
AddInterface(kClientAddr);
allocator_->set_step_delay(cricket::kDefaultStepDelay);
EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
@@ -569,29 +600,33 @@
ASSERT_EQ_WAIT(4U, candidates_.size(), 2000);
EXPECT_EQ(3U, ports_.size());
EXPECT_PRED5(CheckCandidate, candidates_[2],
- cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp", kRelayUdpIntAddr);
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp",
+ kRelayUdpIntAddr);
EXPECT_PRED5(CheckCandidate, candidates_[3],
- cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp", kRelayUdpExtAddr);
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp",
+ kRelayUdpExtAddr);
ASSERT_EQ_WAIT(6U, candidates_.size(), 1500);
EXPECT_PRED5(CheckCandidate, candidates_[4],
- cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "tcp", kRelayTcpIntAddr);
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "tcp",
+ kRelayTcpIntAddr);
EXPECT_PRED5(CheckCandidate, candidates_[5],
- cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "tcp", kClientAddr);
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "tcp",
+ kClientAddr);
EXPECT_EQ(4U, ports_.size());
ASSERT_EQ_WAIT(7U, candidates_.size(), 2000);
EXPECT_PRED5(CheckCandidate, candidates_[6],
- cricket::ICE_CANDIDATE_COMPONENT_RTP,
- "relay", "ssltcp", kRelaySslTcpIntAddr);
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "ssltcp",
+ kRelaySslTcpIntAddr);
EXPECT_EQ(4U, ports_.size());
EXPECT_TRUE(candidate_allocation_done_);
// If we Stop gathering now, we shouldn't get a second "done" callback.
session_->StopGettingPorts();
}
-TEST_F(PortAllocatorTest, TestSetupVideoRtpPortsWithNormalSendBuffers) {
+TEST_F(BasicPortAllocatorTest, TestSetupVideoRtpPortsWithNormalSendBuffers) {
AddInterface(kClientAddr);
- EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP,
- cricket::CN_VIDEO));
+ EXPECT_TRUE(
+ CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP, cricket::CN_VIDEO));
session_->StartGettingPorts();
ASSERT_EQ_WAIT(7U, candidates_.size(), kDefaultAllocationTimeout);
EXPECT_TRUE(candidate_allocation_done_);
@@ -603,7 +638,7 @@
}
// Tests that we can get callback after StopGetAllPorts.
-TEST_F(PortAllocatorTest, TestStopGetAllPorts) {
+TEST_F(BasicPortAllocatorTest, TestStopGetAllPorts) {
AddInterface(kClientAddr);
EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
session_->StartGettingPorts();
@@ -616,7 +651,7 @@
// Test that we restrict client ports appropriately when a port range is set.
// We check the candidates for udp/stun/tcp ports, and the from address
// for relay ports.
-TEST_F(PortAllocatorTest, TestGetAllPortsPortRange) {
+TEST_F(BasicPortAllocatorTest, TestGetAllPortsPortRange) {
AddInterface(kClientAddr);
// Check that an invalid port range fails.
EXPECT_FALSE(SetPortRange(kMaxPort, kMinPort));
@@ -633,15 +668,15 @@
// Check the port number for the STUN port object.
EXPECT_PRED3(CheckPort, candidates_[1].address(), kMinPort, kMaxPort);
// Check the port number used to connect to the relay server.
- EXPECT_PRED3(CheckPort, relay_server_.GetConnection(0).source(),
- kMinPort, kMaxPort);
+ EXPECT_PRED3(CheckPort, relay_server_.GetConnection(0).source(), kMinPort,
+ kMaxPort);
// Check the port number for the TCP port object.
EXPECT_PRED3(CheckPort, candidates_[5].address(), kMinPort, kMaxPort);
EXPECT_TRUE(candidate_allocation_done_);
}
// Test that we don't crash or malfunction if we have no network adapters.
-TEST_F(PortAllocatorTest, TestGetAllPortsNoAdapters) {
+TEST_F(BasicPortAllocatorTest, TestGetAllPortsNoAdapters) {
EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
session_->StartGettingPorts();
rtc::Thread::Current()->ProcessMessages(100);
@@ -652,7 +687,7 @@
// Test that when enumeration is disabled, we should not have any ports when
// candidate_filter() is set to CF_RELAY and no relay is specified.
-TEST_F(PortAllocatorTest,
+TEST_F(BasicPortAllocatorTest,
TestDisableAdapterEnumerationWithoutNatRelayTransportOnly) {
ResetWithStunServerNoNat(kStunAddr);
allocator().set_candidate_filter(cricket::CF_RELAY);
@@ -664,7 +699,7 @@
// Test that even with multiple interfaces, the result should still be a single
// default private, one STUN and one TURN candidate since we bind to any address
// (i.e. all 0s).
-TEST_F(PortAllocatorTest,
+TEST_F(BasicPortAllocatorTest,
TestDisableAdapterEnumerationBehindNatMultipleInterfaces) {
AddInterface(kPrivateAddr);
AddInterface(kPrivateAddr2);
@@ -687,7 +722,7 @@
// Test that we should get a default private, STUN, TURN/UDP and TURN/TCP
// candidates when both TURN/UDP and TURN/TCP servers are specified.
-TEST_F(PortAllocatorTest, TestDisableAdapterEnumerationBehindNatWithTcp) {
+TEST_F(BasicPortAllocatorTest, TestDisableAdapterEnumerationBehindNatWithTcp) {
turn_server_.AddInternalSocket(kTurnTcpIntAddr, cricket::PROTO_TCP);
AddInterface(kPrivateAddr);
ResetWithStunServerAndNat(kStunAddr);
@@ -701,7 +736,8 @@
// Test that when adapter enumeration is disabled, for endpoints without
// STUN/TURN specified, a default private candidate is still generated.
-TEST_F(PortAllocatorTest, TestDisableAdapterEnumerationWithoutNatOrServers) {
+TEST_F(BasicPortAllocatorTest,
+ TestDisableAdapterEnumerationWithoutNatOrServers) {
ResetWithNoServersOrNat();
// Expect to see 2 ports: STUN and TCP ports, one default private candidate.
CheckDisableAdapterEnumeration(2U, kPrivateAddr.ipaddr(), rtc::IPAddress(),
@@ -711,7 +747,7 @@
// Test that when adapter enumeration is disabled, with
// PORTALLOCATOR_DISABLE_LOCALHOST_CANDIDATE specified, for endpoints not behind
// a NAT, there is no local candidate.
-TEST_F(PortAllocatorTest,
+TEST_F(BasicPortAllocatorTest,
TestDisableAdapterEnumerationWithoutNatLocalhostCandidateDisabled) {
ResetWithStunServerNoNat(kStunAddr);
EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
@@ -728,7 +764,7 @@
// (kClientAddr) which was discovered when sending STUN requests, will become
// the srflx addresses.
TEST_F(
- PortAllocatorTest,
+ BasicPortAllocatorTest,
TestDisableAdapterEnumerationWithoutNatLocalhostCandidateDisabledWithDifferentDefaultRoute) {
ResetWithStunServerNoNat(kStunAddr);
AddInterfaceAsDefaultRoute(kClientAddr);
@@ -743,7 +779,7 @@
// Test that when adapter enumeration is disabled, with
// PORTALLOCATOR_DISABLE_LOCALHOST_CANDIDATE specified, for endpoints behind a
// NAT, there is only one STUN candidate.
-TEST_F(PortAllocatorTest,
+TEST_F(BasicPortAllocatorTest,
TestDisableAdapterEnumerationWithNatLocalhostCandidateDisabled) {
ResetWithStunServerAndNat(kStunAddr);
EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
@@ -755,7 +791,7 @@
// Test that we disable relay over UDP, and only TCP is used when connecting to
// the relay server.
-TEST_F(PortAllocatorTest, TestDisableUdpTurn) {
+TEST_F(BasicPortAllocatorTest, TestDisableUdpTurn) {
turn_server_.AddInternalSocket(kTurnTcpIntAddr, cricket::PROTO_TCP);
AddInterface(kClientAddr);
ResetWithStunServerAndNat(kStunAddr);
@@ -789,7 +825,7 @@
// Test that we can get OnCandidatesAllocationDone callback when all the ports
// are disabled.
-TEST_F(PortAllocatorTest, TestDisableAllPorts) {
+TEST_F(BasicPortAllocatorTest, TestDisableAllPorts) {
AddInterface(kClientAddr);
EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
session_->set_flags(cricket::PORTALLOCATOR_DISABLE_UDP |
@@ -803,7 +839,7 @@
}
// Test that we don't crash or malfunction if we can't create UDP sockets.
-TEST_F(PortAllocatorTest, TestGetAllPortsNoUdpSockets) {
+TEST_F(BasicPortAllocatorTest, TestGetAllPortsNoUdpSockets) {
AddInterface(kClientAddr);
fss_->set_udp_sockets_enabled(false);
EXPECT_TRUE(CreateSession(1));
@@ -811,25 +847,29 @@
ASSERT_EQ_WAIT(5U, candidates_.size(), kDefaultAllocationTimeout);
EXPECT_EQ(2U, ports_.size());
EXPECT_PRED5(CheckCandidate, candidates_[0],
- cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp", kRelayUdpIntAddr);
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp",
+ kRelayUdpIntAddr);
EXPECT_PRED5(CheckCandidate, candidates_[1],
- cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp", kRelayUdpExtAddr);
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp",
+ kRelayUdpExtAddr);
EXPECT_PRED5(CheckCandidate, candidates_[2],
- cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "tcp", kRelayTcpIntAddr);
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "tcp",
+ kRelayTcpIntAddr);
EXPECT_PRED5(CheckCandidate, candidates_[3],
- cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "tcp", kClientAddr);
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "tcp",
+ kClientAddr);
EXPECT_PRED5(CheckCandidate, candidates_[4],
- cricket::ICE_CANDIDATE_COMPONENT_RTP,
- "relay", "ssltcp", kRelaySslTcpIntAddr);
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "ssltcp",
+ kRelaySslTcpIntAddr);
EXPECT_TRUE(candidate_allocation_done_);
}
-#endif // if !defined(ADDRESS_SANITIZER)
+#endif // if !defined(ADDRESS_SANITIZER)
// Test that we don't crash or malfunction if we can't create UDP sockets or
// listen on TCP sockets. We still give out a local TCP address, since
// apparently this is needed for the remote side to accept our connection.
-TEST_F(PortAllocatorTest, TestGetAllPortsNoUdpSocketsNoTcpListen) {
+TEST_F(BasicPortAllocatorTest, TestGetAllPortsNoUdpSocketsNoTcpListen) {
AddInterface(kClientAddr);
fss_->set_udp_sockets_enabled(false);
fss_->set_tcp_listen_enabled(false);
@@ -837,35 +877,34 @@
session_->StartGettingPorts();
ASSERT_EQ_WAIT(5U, candidates_.size(), kDefaultAllocationTimeout);
EXPECT_EQ(2U, ports_.size());
- EXPECT_PRED5(CheckCandidate, candidates_[0],
- 1, "relay", "udp", kRelayUdpIntAddr);
- EXPECT_PRED5(CheckCandidate, candidates_[1],
- 1, "relay", "udp", kRelayUdpExtAddr);
- EXPECT_PRED5(CheckCandidate, candidates_[2],
- 1, "relay", "tcp", kRelayTcpIntAddr);
- EXPECT_PRED5(CheckCandidate, candidates_[3],
- 1, "local", "tcp", kClientAddr);
- EXPECT_PRED5(CheckCandidate, candidates_[4],
- 1, "relay", "ssltcp", kRelaySslTcpIntAddr);
+ EXPECT_PRED5(CheckCandidate, candidates_[0], 1, "relay", "udp",
+ kRelayUdpIntAddr);
+ EXPECT_PRED5(CheckCandidate, candidates_[1], 1, "relay", "udp",
+ kRelayUdpExtAddr);
+ EXPECT_PRED5(CheckCandidate, candidates_[2], 1, "relay", "tcp",
+ kRelayTcpIntAddr);
+ EXPECT_PRED5(CheckCandidate, candidates_[3], 1, "local", "tcp", kClientAddr);
+ EXPECT_PRED5(CheckCandidate, candidates_[4], 1, "relay", "ssltcp",
+ kRelaySslTcpIntAddr);
EXPECT_TRUE(candidate_allocation_done_);
}
// Test that we don't crash or malfunction if we can't create any sockets.
-// TODO: Find a way to exit early here.
-TEST_F(PortAllocatorTest, TestGetAllPortsNoSockets) {
+// TODO(deadbeef): Find a way to exit early here.
+TEST_F(BasicPortAllocatorTest, TestGetAllPortsNoSockets) {
AddInterface(kClientAddr);
fss_->set_tcp_sockets_enabled(false);
fss_->set_udp_sockets_enabled(false);
EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
session_->StartGettingPorts();
WAIT(candidates_.size() > 0, 2000);
- // TODO - Check candidate_allocation_done signal.
+ // TODO(deadbeef): Check candidate_allocation_done signal.
// In case of Relay, ports creation will succeed but sockets will fail.
// There is no error reporting from RelayEntry to handle this failure.
}
// Testing STUN timeout.
-TEST_F(PortAllocatorTest, TestGetAllPortsNoUdpAllowed) {
+TEST_F(BasicPortAllocatorTest, TestGetAllPortsNoUdpAllowed) {
fss_->AddRule(false, rtc::FP_UDP, rtc::FD_ANY, kClientAddr);
AddInterface(kClientAddr);
EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
@@ -873,27 +912,32 @@
EXPECT_EQ_WAIT(2U, candidates_.size(), kDefaultAllocationTimeout);
EXPECT_EQ(2U, ports_.size());
EXPECT_PRED5(CheckCandidate, candidates_[0],
- cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "udp", kClientAddr);
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "udp",
+ kClientAddr);
EXPECT_PRED5(CheckCandidate, candidates_[1],
- cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "tcp", kClientAddr);
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "tcp",
+ kClientAddr);
// RelayPort connection timeout is 3sec. TCP connection with RelayServer
// will be tried after 3 seconds.
EXPECT_EQ_WAIT(6U, candidates_.size(), 4000);
EXPECT_EQ(3U, ports_.size());
EXPECT_PRED5(CheckCandidate, candidates_[2],
- cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp", kRelayUdpIntAddr);
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp",
+ kRelayUdpIntAddr);
EXPECT_PRED5(CheckCandidate, candidates_[3],
- cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "tcp", kRelayTcpIntAddr);
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "tcp",
+ kRelayTcpIntAddr);
EXPECT_PRED5(CheckCandidate, candidates_[4],
- cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "ssltcp",
- kRelaySslTcpIntAddr);
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "ssltcp",
+ kRelaySslTcpIntAddr);
EXPECT_PRED5(CheckCandidate, candidates_[5],
- cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp", kRelayUdpExtAddr);
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp",
+ kRelayUdpExtAddr);
// Stun Timeout is 9sec.
EXPECT_TRUE_WAIT(candidate_allocation_done_, 9000);
}
-TEST_F(PortAllocatorTest, TestCandidatePriorityOfMultipleInterfaces) {
+TEST_F(BasicPortAllocatorTest, TestCandidatePriorityOfMultipleInterfaces) {
AddInterface(kClientAddr);
AddInterface(kClientAddr2);
// Allocating only host UDP ports. This is done purely for testing
@@ -911,14 +955,14 @@
}
// Test to verify ICE restart process.
-TEST_F(PortAllocatorTest, TestGetAllPortsRestarts) {
+TEST_F(BasicPortAllocatorTest, TestGetAllPortsRestarts) {
AddInterface(kClientAddr);
EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
session_->StartGettingPorts();
EXPECT_EQ_WAIT(7U, candidates_.size(), kDefaultAllocationTimeout);
EXPECT_EQ(4U, ports_.size());
EXPECT_TRUE(candidate_allocation_done_);
- // TODO - Extend this to verify ICE restart.
+ // TODO(deadbeef): Extend this to verify ICE restart.
}
// Test ICE candidate filter mechanism with options Relay/Host/Reflexive.
@@ -926,7 +970,7 @@
// relay (i.e. IceTransportsType is relay), the raddr is an empty
// address with the correct family. This is to prevent any local
// reflective address leakage in the sdp line.
-TEST_F(PortAllocatorTest, TestCandidateFilterWithRelayOnly) {
+TEST_F(BasicPortAllocatorTest, TestCandidateFilterWithRelayOnly) {
AddInterface(kClientAddr);
// GTURN is not configured here.
ResetWithTurnServersNoNat(kTurnUdpIntAddr, rtc::SocketAddress());
@@ -934,11 +978,8 @@
EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
session_->StartGettingPorts();
EXPECT_TRUE_WAIT(candidate_allocation_done_, kDefaultAllocationTimeout);
- EXPECT_PRED5(CheckCandidate,
- candidates_[0],
- cricket::ICE_CANDIDATE_COMPONENT_RTP,
- "relay",
- "udp",
+ EXPECT_PRED5(CheckCandidate, candidates_[0],
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp",
rtc::SocketAddress(kTurnUdpExtAddr.ipaddr(), 0));
EXPECT_EQ(1U, candidates_.size());
@@ -951,22 +992,22 @@
}
}
-TEST_F(PortAllocatorTest, TestCandidateFilterWithHostOnly) {
+TEST_F(BasicPortAllocatorTest, TestCandidateFilterWithHostOnly) {
AddInterface(kClientAddr);
allocator().set_flags(cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET);
allocator().set_candidate_filter(cricket::CF_HOST);
EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
session_->StartGettingPorts();
EXPECT_TRUE_WAIT(candidate_allocation_done_, kDefaultAllocationTimeout);
- EXPECT_EQ(2U, candidates_.size()); // Host UDP/TCP candidates only.
- EXPECT_EQ(2U, ports_.size()); // UDP/TCP ports only.
+ EXPECT_EQ(2U, candidates_.size()); // Host UDP/TCP candidates only.
+ EXPECT_EQ(2U, ports_.size()); // UDP/TCP ports only.
for (size_t i = 0; i < candidates_.size(); ++i) {
EXPECT_EQ(std::string(cricket::LOCAL_PORT_TYPE), candidates_[i].type());
}
}
// Host is behind the NAT.
-TEST_F(PortAllocatorTest, TestCandidateFilterWithReflexiveOnly) {
+TEST_F(BasicPortAllocatorTest, TestCandidateFilterWithReflexiveOnly) {
AddInterface(kPrivateAddr);
ResetWithStunServerAndNat(kStunAddr);
@@ -977,8 +1018,8 @@
EXPECT_TRUE_WAIT(candidate_allocation_done_, kDefaultAllocationTimeout);
// Host is behind NAT, no private address will be exposed. Hence only UDP
// port with STUN candidate will be sent outside.
- EXPECT_EQ(1U, candidates_.size()); // Only STUN candidate.
- EXPECT_EQ(1U, ports_.size()); // Only UDP port will be in ready state.
+ EXPECT_EQ(1U, candidates_.size()); // Only STUN candidate.
+ EXPECT_EQ(1U, ports_.size()); // Only UDP port will be in ready state.
for (size_t i = 0; i < candidates_.size(); ++i) {
EXPECT_EQ(std::string(cricket::STUN_PORT_TYPE), candidates_[i].type());
EXPECT_EQ(
@@ -988,7 +1029,7 @@
}
// Host is not behind the NAT.
-TEST_F(PortAllocatorTest, TestCandidateFilterWithReflexiveOnlyAndNoNAT) {
+TEST_F(BasicPortAllocatorTest, TestCandidateFilterWithReflexiveOnlyAndNoNAT) {
AddInterface(kClientAddr);
allocator().set_flags(cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET);
allocator().set_candidate_filter(cricket::CF_REFLEXIVE);
@@ -996,7 +1037,7 @@
session_->StartGettingPorts();
EXPECT_TRUE_WAIT(candidate_allocation_done_, kDefaultAllocationTimeout);
// Host has a public address, both UDP and TCP candidates will be exposed.
- EXPECT_EQ(2U, candidates_.size()); // Local UDP + TCP candidate.
+ EXPECT_EQ(2U, candidates_.size()); // Local UDP + TCP candidate.
EXPECT_EQ(2U, ports_.size()); // UDP and TCP ports will be in ready state.
for (size_t i = 0; i < candidates_.size(); ++i) {
EXPECT_EQ(std::string(cricket::LOCAL_PORT_TYPE), candidates_[i].type());
@@ -1004,17 +1045,20 @@
}
// Test that we get the same ufrag and pwd for all candidates.
-TEST_F(PortAllocatorTest, TestEnableSharedUfrag) {
+TEST_F(BasicPortAllocatorTest, TestEnableSharedUfrag) {
AddInterface(kClientAddr);
EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
session_->StartGettingPorts();
ASSERT_EQ_WAIT(7U, candidates_.size(), kDefaultAllocationTimeout);
EXPECT_PRED5(CheckCandidate, candidates_[0],
- cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "udp", kClientAddr);
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "udp",
+ kClientAddr);
EXPECT_PRED5(CheckCandidate, candidates_[1],
- cricket::ICE_CANDIDATE_COMPONENT_RTP, "stun", "udp", kClientAddr);
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "stun", "udp",
+ kClientAddr);
EXPECT_PRED5(CheckCandidate, candidates_[5],
- cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "tcp", kClientAddr);
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "tcp",
+ kClientAddr);
EXPECT_EQ(4U, ports_.size());
EXPECT_EQ(kIceUfrag0, candidates_[0].username());
EXPECT_EQ(kIceUfrag0, candidates_[1].username());
@@ -1028,7 +1072,7 @@
// is allocated for udp and stun. Also verify there is only one candidate
// (local) if stun candidate is same as local candidate, which will be the case
// in a public network like the below test.
-TEST_F(PortAllocatorTest, TestSharedSocketWithoutNat) {
+TEST_F(BasicPortAllocatorTest, TestSharedSocketWithoutNat) {
AddInterface(kClientAddr);
allocator_->set_flags(allocator().flags() |
cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET);
@@ -1037,14 +1081,15 @@
ASSERT_EQ_WAIT(6U, candidates_.size(), kDefaultAllocationTimeout);
EXPECT_EQ(3U, ports_.size());
EXPECT_PRED5(CheckCandidate, candidates_[0],
- cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "udp", kClientAddr);
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "udp",
+ kClientAddr);
EXPECT_TRUE_WAIT(candidate_allocation_done_, kDefaultAllocationTimeout);
}
// Test that when PORTALLOCATOR_ENABLE_SHARED_SOCKET is enabled only one port
// is allocated for udp and stun. In this test we should expect both stun and
// local candidates as client behind a nat.
-TEST_F(PortAllocatorTest, TestSharedSocketWithNat) {
+TEST_F(BasicPortAllocatorTest, TestSharedSocketWithNat) {
AddInterface(kClientAddr);
ResetWithStunServerAndNat(kStunAddr);
@@ -1055,16 +1100,17 @@
ASSERT_EQ_WAIT(3U, candidates_.size(), kDefaultAllocationTimeout);
ASSERT_EQ(2U, ports_.size());
EXPECT_PRED5(CheckCandidate, candidates_[0],
- cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "udp", kClientAddr);
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "udp",
+ kClientAddr);
EXPECT_PRED5(CheckCandidate, candidates_[1],
- cricket::ICE_CANDIDATE_COMPONENT_RTP, "stun", "udp",
- rtc::SocketAddress(kNatUdpAddr.ipaddr(), 0));
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "stun", "udp",
+ rtc::SocketAddress(kNatUdpAddr.ipaddr(), 0));
EXPECT_TRUE_WAIT(candidate_allocation_done_, kDefaultAllocationTimeout);
EXPECT_EQ(3U, candidates_.size());
}
// Test TURN port in shared socket mode with UDP and TCP TURN server addresses.
-TEST_F(PortAllocatorTest, TestSharedSocketWithoutNatUsingTurn) {
+TEST_F(BasicPortAllocatorTest, TestSharedSocketWithoutNatUsingTurn) {
turn_server_.AddInternalSocket(kTurnTcpIntAddr, cricket::PROTO_TCP);
AddInterface(kClientAddr);
allocator_.reset(new cricket::BasicPortAllocator(&network_manager_));
@@ -1082,20 +1128,21 @@
ASSERT_EQ_WAIT(3U, candidates_.size(), kDefaultAllocationTimeout);
ASSERT_EQ(3U, ports_.size());
EXPECT_PRED5(CheckCandidate, candidates_[0],
- cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "udp", kClientAddr);
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "udp",
+ kClientAddr);
EXPECT_PRED5(CheckCandidate, candidates_[1],
- cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp",
- rtc::SocketAddress(kTurnUdpExtAddr.ipaddr(), 0));
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp",
+ rtc::SocketAddress(kTurnUdpExtAddr.ipaddr(), 0));
EXPECT_PRED5(CheckCandidate, candidates_[2],
- cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp",
- rtc::SocketAddress(kTurnUdpExtAddr.ipaddr(), 0));
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp",
+ rtc::SocketAddress(kTurnUdpExtAddr.ipaddr(), 0));
EXPECT_TRUE_WAIT(candidate_allocation_done_, kDefaultAllocationTimeout);
EXPECT_EQ(3U, candidates_.size());
}
// Testing DNS resolve for the TURN server, this will test AllocationSequence
// handling the unresolved address signal from TurnPort.
-TEST_F(PortAllocatorTest, TestSharedSocketWithServerAddressResolve) {
+TEST_F(BasicPortAllocatorTest, TestSharedSocketWithServerAddressResolve) {
turn_server_.AddInternalSocket(rtc::SocketAddress("127.0.0.1", 3478),
cricket::PROTO_UDP);
AddInterface(kClientAddr);
@@ -1121,7 +1168,7 @@
// Test that when PORTALLOCATOR_ENABLE_SHARED_SOCKET is enabled only one port
// is allocated for udp/stun/turn. In this test we should expect all local,
// stun and turn candidates.
-TEST_F(PortAllocatorTest, TestSharedSocketWithNatUsingTurn) {
+TEST_F(BasicPortAllocatorTest, TestSharedSocketWithNatUsingTurn) {
AddInterface(kClientAddr);
ResetWithStunServerAndNat(kStunAddr);
@@ -1137,13 +1184,14 @@
ASSERT_EQ_WAIT(3U, candidates_.size(), kDefaultAllocationTimeout);
ASSERT_EQ(2U, ports_.size());
EXPECT_PRED5(CheckCandidate, candidates_[0],
- cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "udp", kClientAddr);
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "udp",
+ kClientAddr);
EXPECT_PRED5(CheckCandidate, candidates_[1],
- cricket::ICE_CANDIDATE_COMPONENT_RTP, "stun", "udp",
- rtc::SocketAddress(kNatUdpAddr.ipaddr(), 0));
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "stun", "udp",
+ rtc::SocketAddress(kNatUdpAddr.ipaddr(), 0));
EXPECT_PRED5(CheckCandidate, candidates_[2],
- cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp",
- rtc::SocketAddress(kTurnUdpExtAddr.ipaddr(), 0));
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp",
+ rtc::SocketAddress(kTurnUdpExtAddr.ipaddr(), 0));
EXPECT_TRUE_WAIT(candidate_allocation_done_, kDefaultAllocationTimeout);
EXPECT_EQ(3U, candidates_.size());
// Local port will be created first and then TURN port.
@@ -1154,7 +1202,7 @@
// Test that when PORTALLOCATOR_ENABLE_SHARED_SOCKET is enabled and the TURN
// server is also used as the STUN server, we should get 'local', 'stun', and
// 'relay' candidates.
-TEST_F(PortAllocatorTest, TestSharedSocketWithNatUsingTurnAsStun) {
+TEST_F(BasicPortAllocatorTest, TestSharedSocketWithNatUsingTurnAsStun) {
AddInterface(kClientAddr);
// Use an empty SocketAddress to add a NAT without STUN server.
ResetWithStunServerAndNat(SocketAddress());
@@ -1174,13 +1222,14 @@
ASSERT_EQ_WAIT(3U, candidates_.size(), kDefaultAllocationTimeout);
EXPECT_PRED5(CheckCandidate, candidates_[0],
- cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "udp", kClientAddr);
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "udp",
+ kClientAddr);
EXPECT_PRED5(CheckCandidate, candidates_[1],
- cricket::ICE_CANDIDATE_COMPONENT_RTP, "stun", "udp",
- rtc::SocketAddress(kNatUdpAddr.ipaddr(), 0));
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "stun", "udp",
+ rtc::SocketAddress(kNatUdpAddr.ipaddr(), 0));
EXPECT_PRED5(CheckCandidate, candidates_[2],
- cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp",
- rtc::SocketAddress(kTurnUdpExtAddr.ipaddr(), 0));
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp",
+ rtc::SocketAddress(kTurnUdpExtAddr.ipaddr(), 0));
EXPECT_EQ(candidates_[2].related_address(), candidates_[1].address());
EXPECT_TRUE_WAIT(candidate_allocation_done_, kDefaultAllocationTimeout);
@@ -1193,7 +1242,7 @@
// Test that when only a TCP TURN server is available, we do NOT use it as
// a UDP STUN server, as this could leak our IP address. Thus we should only
// expect two ports, a UDPPort and TurnPort.
-TEST_F(PortAllocatorTest, TestSharedSocketWithNatUsingTurnTcpOnly) {
+TEST_F(BasicPortAllocatorTest, TestSharedSocketWithNatUsingTurnTcpOnly) {
turn_server_.AddInternalSocket(kTurnTcpIntAddr, cricket::PROTO_TCP);
AddInterface(kClientAddr);
ResetWithStunServerAndNat(rtc::SocketAddress());
@@ -1225,7 +1274,7 @@
// 'relay' candidates.
// TODO(deadbeef): Remove this test when support for non-shared socket mode
// is removed.
-TEST_F(PortAllocatorTest, TestNonSharedSocketWithNatUsingTurnAsStun) {
+TEST_F(BasicPortAllocatorTest, TestNonSharedSocketWithNatUsingTurnAsStun) {
AddInterface(kClientAddr);
// Use an empty SocketAddress to add a NAT without STUN server.
ResetWithStunServerAndNat(SocketAddress());
@@ -1261,7 +1310,7 @@
// Test that even when both a STUN and TURN server are configured, the TURN
// server is used as a STUN server and we get a 'stun' candidate.
-TEST_F(PortAllocatorTest, TestSharedSocketWithNatUsingTurnAndStun) {
+TEST_F(BasicPortAllocatorTest, TestSharedSocketWithNatUsingTurnAndStun) {
AddInterface(kClientAddr);
// Configure with STUN server but destroy it, so we can ensure that it's
// the TURN server actually being used as a STUN server.
@@ -1295,7 +1344,7 @@
// This test verifies when PORTALLOCATOR_ENABLE_SHARED_SOCKET flag is enabled
// and fail to generate STUN candidate, local UDP candidate is generated
// properly.
-TEST_F(PortAllocatorTest, TestSharedSocketNoUdpAllowed) {
+TEST_F(BasicPortAllocatorTest, TestSharedSocketNoUdpAllowed) {
allocator().set_flags(allocator().flags() |
cricket::PORTALLOCATOR_DISABLE_RELAY |
cricket::PORTALLOCATOR_DISABLE_TCP |
@@ -1307,7 +1356,8 @@
ASSERT_EQ_WAIT(1U, ports_.size(), kDefaultAllocationTimeout);
EXPECT_EQ(1U, candidates_.size());
EXPECT_PRED5(CheckCandidate, candidates_[0],
- cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "udp", kClientAddr);
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "udp",
+ kClientAddr);
// STUN timeout is 9sec. We need to wait to get candidate done signal.
EXPECT_TRUE_WAIT(candidate_allocation_done_, 10000);
EXPECT_EQ(1U, candidates_.size());
@@ -1316,7 +1366,7 @@
// Test that when the NetworkManager doesn't have permission to enumerate
// adapters, the PORTALLOCATOR_DISABLE_ADAPTER_ENUMERATION is specified
// automatically.
-TEST_F(PortAllocatorTest, TestNetworkPermissionBlocked) {
+TEST_F(BasicPortAllocatorTest, TestNetworkPermissionBlocked) {
network_manager_.set_default_local_addresses(kPrivateAddr.ipaddr(),
rtc::IPAddress());
network_manager_.set_enumeration_permission(
@@ -1336,12 +1386,12 @@
EXPECT_PRED5(CheckCandidate, candidates_[0],
cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "udp",
kPrivateAddr);
- EXPECT_TRUE((session_->flags() &
- cricket::PORTALLOCATOR_DISABLE_ADAPTER_ENUMERATION) != 0);
+ EXPECT_NE(0U, session_->flags() &
+ cricket::PORTALLOCATOR_DISABLE_ADAPTER_ENUMERATION);
}
// This test verifies allocator can use IPv6 addresses along with IPv4.
-TEST_F(PortAllocatorTest, TestEnableIPv6Addresses) {
+TEST_F(BasicPortAllocatorTest, TestEnableIPv6Addresses) {
allocator().set_flags(allocator().flags() |
cricket::PORTALLOCATOR_DISABLE_RELAY |
cricket::PORTALLOCATOR_ENABLE_IPV6 |
@@ -1355,21 +1405,21 @@
EXPECT_EQ(4U, candidates_.size());
EXPECT_TRUE_WAIT(candidate_allocation_done_, kDefaultAllocationTimeout);
EXPECT_PRED5(CheckCandidate, candidates_[0],
- cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "udp",
- kClientIPv6Addr);
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "udp",
+ kClientIPv6Addr);
EXPECT_PRED5(CheckCandidate, candidates_[1],
- cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "udp",
- kClientAddr);
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "udp",
+ kClientAddr);
EXPECT_PRED5(CheckCandidate, candidates_[2],
- cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "tcp",
- kClientIPv6Addr);
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "tcp",
+ kClientIPv6Addr);
EXPECT_PRED5(CheckCandidate, candidates_[3],
- cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "tcp",
- kClientAddr);
+ cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "tcp",
+ kClientAddr);
EXPECT_EQ(4U, candidates_.size());
}
-TEST_F(PortAllocatorTest, TestStopGettingPorts) {
+TEST_F(BasicPortAllocatorTest, TestStopGettingPorts) {
AddInterface(kClientAddr);
allocator_->set_step_delay(cricket::kDefaultStepDelay);
EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
@@ -1390,7 +1440,7 @@
EXPECT_EQ(0U, ports_.size());
}
-TEST_F(PortAllocatorTest, TestClearGettingPorts) {
+TEST_F(BasicPortAllocatorTest, TestClearGettingPorts) {
AddInterface(kClientAddr);
allocator_->set_step_delay(cricket::kDefaultStepDelay);
EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
@@ -1410,3 +1460,41 @@
ASSERT_EQ_WAIT(2U, candidates_.size(), 1000);
EXPECT_EQ(2U, ports_.size());
}
+
+// Test that the ports and candidates are updated with new ufrag/pwd/etc. when
+// a pooled session is taken out of the pool.
+TEST_F(BasicPortAllocatorTest, TestTransportInformationUpdated) {
+ AddInterface(kClientAddr);
+ int pool_size = 1;
+ allocator_->SetConfiguration(allocator_->stun_servers(),
+ allocator_->turn_servers(), pool_size);
+ const cricket::PortAllocatorSession* peeked_session =
+ allocator_->GetPooledSession();
+ ASSERT_NE(nullptr, peeked_session);
+ EXPECT_EQ_WAIT(true, peeked_session->CandidatesAllocationDone(),
+ kDefaultAllocationTimeout);
+ // Expect that when TakePooledSession is called,
+ // UpdateTransportInformationInternal will be called and the
+ // BasicPortAllocatorSession will update the ufrag/pwd of ports and
+ // candidates.
+ session_ =
+ allocator_->TakePooledSession(kContentName, 1, kIceUfrag0, kIcePwd0);
+ ASSERT_NE(nullptr, session_.get());
+ auto ready_ports = session_->ReadyPorts();
+ auto candidates = session_->ReadyCandidates();
+ EXPECT_FALSE(ready_ports.empty());
+ EXPECT_FALSE(candidates.empty());
+ for (const cricket::PortInterface* port_interface : ready_ports) {
+ const cricket::Port* port =
+ static_cast<const cricket::Port*>(port_interface);
+ EXPECT_EQ(kContentName, port->content_name());
+ EXPECT_EQ(1, port->component());
+ EXPECT_EQ(kIceUfrag0, port->username_fragment());
+ EXPECT_EQ(kIcePwd0, port->password());
+ }
+ for (const cricket::Candidate& candidate : candidates) {
+ EXPECT_EQ(1, candidate.component());
+ EXPECT_EQ(kIceUfrag0, candidate.username());
+ EXPECT_EQ(kIcePwd0, candidate.password());
+ }
+}
diff --git a/webrtc/p2p/p2p.gyp b/webrtc/p2p/p2p.gyp
index 08fac69..7ec1814 100644
--- a/webrtc/p2p/p2p.gyp
+++ b/webrtc/p2p/p2p.gyp
@@ -146,9 +146,11 @@
'direct_dependent_settings': {
'sources': [
'base/dtlstransportchannel_unittest.cc',
+ 'base/fakeportallocator.h',
'base/faketransportcontroller.h',
'base/p2ptransportchannel_unittest.cc',
'base/port_unittest.cc',
+ 'base/portallocator_unittest.cc',
'base/pseudotcp_unittest.cc',
'base/relayport_unittest.cc',
'base/relayserver_unittest.cc',
@@ -164,8 +166,7 @@
'base/transportdescriptionfactory_unittest.cc',
'base/tcpport_unittest.cc',
'base/turnport_unittest.cc',
- 'client/fakeportallocator.h',
- 'client/portallocator_unittest.cc',
+ 'client/basicportallocator_unittest.cc',
'stunprober/stunprober_unittest.cc',
],
'conditions': [