Reland of Adding the ability to change ICE servers through SetConfiguration. (patchset #1 id:1 of https://codereview.webrtc.org/1424803004/ )

Reason for revert:
Relanding with compile warning fixed.

Original issue's description:
> Revert of Adding the ability to change ICE servers through SetConfiguration. (patchset #7 id:120001 of https://codereview.webrtc.org/1391013007/ )
>
> Reason for revert:
> Caused compiler warning, breaking Chrome FYI bots.
>
> Original issue's description:
> > Adding the ability to change ICE servers through SetConfiguration.
> >
> > Added a SetIceServers method to PortAllocator. Also added a new
> > PeerConnection Initialize method that takes a PortAllocator, in the
> > hope that we can get rid of PortAllocatorFactoryInterface, since the
> > only substantial thing a factory does is convert the webrtc:: ICE
> > servers to cricket:: versions.
> >
> > Committed: https://crrev.com/d3b26d94399ff539db375a9b84010ee75479d4cf
> > Cr-Commit-Position: refs/heads/master@{#10420}
>
> TBR=pthatcher@webrtc.org
> NOPRESUBMIT=true
> NOTREECHECKS=true
> NOTRY=true
>
> Committed: https://crrev.com/18a944bf0ac9eed872dc009bd58e6bc12c946303
> Cr-Commit-Position: refs/heads/master@{#10421}

TBR=pthatcher@webrtc.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true

Review URL: https://codereview.webrtc.org/1414313003

Cr-Commit-Position: refs/heads/master@{#10609}
This commit is contained in:
deadbeef 2015-11-11 12:55:10 -08:00 committed by Commit bot
parent 9b72af94cd
commit 653b8e02f2
12 changed files with 218 additions and 113 deletions

View File

@ -49,7 +49,9 @@ class FakePortAllocatorFactory : public PortAllocatorFactoryInterface {
const std::vector<TurnConfiguration>& turn_configurations) {
stun_configs_ = stun_configurations;
turn_configs_ = turn_configurations;
return new cricket::FakePortAllocator(rtc::Thread::Current(), NULL);
last_created_allocator_ =
new cricket::FakePortAllocator(rtc::Thread::Current(), nullptr);
return last_created_allocator_;
}
const std::vector<StunConfiguration>& stun_configs() const {
@ -62,6 +64,12 @@ class FakePortAllocatorFactory : public PortAllocatorFactoryInterface {
void SetNetworkIgnoreMask(int network_ignore_mask) {}
// Up to caller to ensure this isn't called after the allocator has been
// destroyed.
cricket::FakePortAllocator* last_created_allocator() {
return last_created_allocator_;
}
protected:
FakePortAllocatorFactory() {}
~FakePortAllocatorFactory() {}
@ -69,6 +77,7 @@ class FakePortAllocatorFactory : public PortAllocatorFactoryInterface {
private:
std::vector<PortAllocatorFactoryInterface::StunConfiguration> stun_configs_;
std::vector<PortAllocatorFactoryInterface::TurnConfiguration> turn_configs_;
cricket::FakePortAllocator* last_created_allocator_ = nullptr;
};
} // namespace webrtc

View File

@ -331,6 +331,40 @@ bool ParseIceServerUrl(const PeerConnectionInterface::IceServer& server,
return true;
}
void ConvertToCricketIceServers(
const std::vector<StunConfiguration>& stuns,
const std::vector<TurnConfiguration>& turns,
cricket::ServerAddresses* cricket_stuns,
std::vector<cricket::RelayServerConfig>* cricket_turns) {
RTC_DCHECK(cricket_stuns && cricket_turns);
for (const StunConfiguration& stun : stuns) {
cricket_stuns->insert(stun.server);
}
int priority = static_cast<int>(turns.size() - 1);
for (const TurnConfiguration& turn : turns) {
cricket::RelayCredentials credentials(turn.username, turn.password);
cricket::RelayServerConfig relay_server(cricket::RELAY_TURN);
cricket::ProtocolType protocol;
// Using VERIFY because ParseIceServers should have already caught an
// invalid transport type.
if (!VERIFY(
cricket::StringToProto(turn.transport_type.c_str(), &protocol))) {
LOG(LS_WARNING) << "Ignoring TURN server " << turn.server << ". "
<< "Reason= Incorrect " << turn.transport_type
<< " transport parameter.";
} else {
relay_server.ports.push_back(
cricket::ProtocolAddress(turn.server, protocol, turn.secure));
relay_server.credentials = credentials;
relay_server.priority = priority;
cricket_turns->push_back(relay_server);
}
// First in the list gets highest priority.
--priority;
}
}
// Check if we can send |new_stream| on a PeerConnection.
bool CanAddLocalMediaStream(webrtc::StreamCollectionInterface* current_streams,
webrtc::MediaStreamInterface* new_stream) {
@ -590,15 +624,45 @@ bool PeerConnection::Initialize(
if (!observer) {
return false;
}
// This Initialize function parses ICE servers an extra time, but it will
// be removed once all PortAllocaotrs support SetIceServers.
std::vector<PortAllocatorFactoryInterface::StunConfiguration> stun_config;
std::vector<PortAllocatorFactoryInterface::TurnConfiguration> turn_config;
if (!ParseIceServers(configuration.servers, &stun_config, &turn_config)) {
return false;
}
rtc::scoped_ptr<cricket::PortAllocator> allocator(
allocator_factory->CreatePortAllocator(stun_config, turn_config));
return Initialize(configuration, constraints, allocator.Pass(),
dtls_identity_store.Pass(), observer);
}
bool PeerConnection::Initialize(
const PeerConnectionInterface::RTCConfiguration& configuration,
const MediaConstraintsInterface* constraints,
rtc::scoped_ptr<cricket::PortAllocator> allocator,
rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store,
PeerConnectionObserver* observer) {
RTC_DCHECK(observer != nullptr);
if (!observer) {
return false;
}
observer_ = observer;
port_allocator_ = allocator.Pass();
std::vector<PortAllocatorFactoryInterface::StunConfiguration> stun_config;
std::vector<PortAllocatorFactoryInterface::TurnConfiguration> turn_config;
if (!ParseIceServers(configuration.servers, &stun_config, &turn_config)) {
return false;
}
port_allocator_.reset(
allocator_factory->CreatePortAllocator(stun_config, turn_config));
cricket::ServerAddresses cricket_stuns;
std::vector<cricket::RelayServerConfig> cricket_turns;
ConvertToCricketIceServers(stun_config, turn_config, &cricket_stuns,
&cricket_turns);
port_allocator_->SetIceServers(cricket_stuns, cricket_turns);
// To handle both internal and externally created port allocator, we will
// enable BUNDLE here.
@ -1087,36 +1151,10 @@ bool PeerConnection::SetConfiguration(const RTCConfiguration& config) {
return false;
}
std::vector<rtc::SocketAddress> stun_hosts;
typedef std::vector<StunConfiguration>::const_iterator StunIt;
for (StunIt stun_it = stuns.begin(); stun_it != stuns.end(); ++stun_it) {
stun_hosts.push_back(stun_it->server);
}
rtc::SocketAddress stun_addr;
if (!stun_hosts.empty()) {
stun_addr = stun_hosts.front();
LOG(LS_INFO) << "SetConfiguration: StunServer Address: "
<< stun_addr.ToString();
}
for (size_t i = 0; i < turns.size(); ++i) {
cricket::RelayCredentials credentials(turns[i].username,
turns[i].password);
cricket::RelayServerConfig relay_server(cricket::RELAY_TURN);
cricket::ProtocolType protocol;
if (cricket::StringToProto(turns[i].transport_type.c_str(), &protocol)) {
relay_server.ports.push_back(cricket::ProtocolAddress(
turns[i].server, protocol, turns[i].secure));
relay_server.credentials = credentials;
LOG(LS_INFO) << "SetConfiguration: TurnServer Address: "
<< turns[i].server.ToString();
} else {
LOG(LS_WARNING) << "Ignoring TURN server " << turns[i].server << ". "
<< "Reason= Incorrect " << turns[i].transport_type
<< " transport parameter.";
}
}
cricket::ServerAddresses cricket_stuns;
std::vector<cricket::RelayServerConfig> cricket_turns;
ConvertToCricketIceServers(stuns, turns, &cricket_stuns, &cricket_turns);
port_allocator_->SetIceServers(cricket_stuns, cricket_turns);
}
session_->SetIceConfig(session_->ParseIceConfig(config));
return session_->SetIceTransports(config.type);

View File

@ -75,12 +75,22 @@ class PeerConnection : public PeerConnectionInterface,
public:
explicit PeerConnection(PeerConnectionFactory* factory);
// TODO(deadbeef): Remove this overload of Initialize once everyone is moved
// to the new version.
bool Initialize(
const PeerConnectionInterface::RTCConfiguration& configuration,
const MediaConstraintsInterface* constraints,
PortAllocatorFactoryInterface* allocator_factory,
rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store,
PeerConnectionObserver* observer);
bool Initialize(
const PeerConnectionInterface::RTCConfiguration& configuration,
const MediaConstraintsInterface* constraints,
rtc::scoped_ptr<cricket::PortAllocator> allocator,
rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store,
PeerConnectionObserver* observer);
rtc::scoped_refptr<StreamCollectionInterface> local_streams() override;
rtc::scoped_refptr<StreamCollectionInterface> remote_streams() override;
bool AddStream(MediaStreamInterface* local_stream) override;

View File

@ -1660,6 +1660,23 @@ TEST_F(PeerConnectionInterfaceTest, CreateSubsequentInactiveOffer) {
ASSERT_EQ(cricket::MD_INACTIVE, audio_desc->direction());
}
// Test that we can use SetConfiguration to change the ICE servers of the
// PortAllocator.
TEST_F(PeerConnectionInterfaceTest, SetConfigurationChangesIceServers) {
CreatePeerConnection();
PeerConnectionInterface::RTCConfiguration config;
PeerConnectionInterface::IceServer server;
server.uri = "stun:test_hostname";
config.servers.push_back(server);
EXPECT_TRUE(pc_->SetConfiguration(config));
cricket::FakePortAllocator* allocator =
port_allocator_factory_->last_created_allocator();
EXPECT_EQ(1u, allocator->stun_servers().size());
EXPECT_EQ("test_hostname", allocator->stun_servers().begin()->hostname());
}
// Test that PeerConnection::Close changes the states to closed and all remote
// tracks change state to ended.
TEST_F(PeerConnectionInterfaceTest, CloseAndTestStreamsAndStates) {

View File

@ -71,15 +71,15 @@ cricket::PortAllocator* PortAllocatorFactory::CreatePortAllocator(
for (size_t i = 0; i < turn.size(); ++i) {
cricket::RelayCredentials credentials(turn[i].username, turn[i].password);
cricket::RelayServerConfig relay_server(cricket::RELAY_TURN);
cricket::RelayServerConfig turn_server(cricket::RELAY_TURN);
cricket::ProtocolType protocol;
if (cricket::StringToProto(turn[i].transport_type.c_str(), &protocol)) {
relay_server.ports.push_back(cricket::ProtocolAddress(
turn[i].server, protocol, turn[i].secure));
relay_server.credentials = credentials;
turn_server.ports.push_back(
cricket::ProtocolAddress(turn[i].server, protocol, turn[i].secure));
turn_server.credentials = credentials;
// First in the list gets highest priority.
relay_server.priority = static_cast<int>(turn.size() - i - 1);
allocator->AddRelay(relay_server);
turn_server.priority = static_cast<int>(turn.size() - i - 1);
allocator->AddTurnServer(turn_server);
} else {
LOG(LS_WARNING) << "Ignoring TURN server " << turn[i].server << ". "
<< "Reason= Incorrect " << turn[i].transport_type

View File

@ -1442,12 +1442,12 @@ class WebRtcSessionTest
}
void ConfigureAllocatorWithTurn() {
cricket::RelayServerConfig relay_server(cricket::RELAY_TURN);
cricket::RelayServerConfig turn_server(cricket::RELAY_TURN);
cricket::RelayCredentials credentials(kTurnUsername, kTurnPassword);
relay_server.credentials = credentials;
relay_server.ports.push_back(cricket::ProtocolAddress(
kTurnUdpIntAddr, cricket::PROTO_UDP, false));
allocator_->AddRelay(relay_server);
turn_server.credentials = credentials;
turn_server.ports.push_back(
cricket::ProtocolAddress(kTurnUdpIntAddr, cricket::PROTO_UDP, false));
allocator_->AddTurnServer(turn_server);
allocator_->set_step_delay(cricket::kMinimumStepDelay);
allocator_->set_flags(cricket::PORTALLOCATOR_DISABLE_TCP);
}

View File

@ -825,12 +825,12 @@ class P2PTransportChannelTest : public P2PTransportChannelTestBase {
rtc::SocketAddress(), rtc::SocketAddress(),
rtc::SocketAddress()));
cricket::RelayServerConfig relay_server(cricket::RELAY_TURN);
relay_server.credentials = kRelayCredentials;
relay_server.ports.push_back(
cricket::RelayServerConfig turn_server(cricket::RELAY_TURN);
turn_server.credentials = kRelayCredentials;
turn_server.ports.push_back(
cricket::ProtocolAddress(kTurnUdpIntAddr, cricket::PROTO_UDP, false));
GetEndpoint(0)->allocator_->AddRelay(relay_server);
GetEndpoint(1)->allocator_->AddRelay(relay_server);
GetEndpoint(0)->allocator_->AddTurnServer(turn_server);
GetEndpoint(1)->allocator_->AddTurnServer(turn_server);
int delay = kMinimumStepDelay;
ConfigureEndpoint(0, config1);

View File

@ -14,6 +14,7 @@
#include <string>
#include <vector>
#include "webrtc/p2p/base/port.h"
#include "webrtc/p2p/base/portinterface.h"
#include "webrtc/base/helpers.h"
#include "webrtc/base/proxyinfo.h"
@ -75,6 +76,27 @@ enum {
CF_ALL = 0x7,
};
// TODO(deadbeef): Rename to TurnCredentials (and username to ufrag).
struct RelayCredentials {
RelayCredentials() {}
RelayCredentials(const std::string& username, const std::string& password)
: username(username), password(password) {}
std::string username;
std::string password;
};
typedef std::vector<ProtocolAddress> PortList;
// TODO(deadbeef): Rename to TurnServerConfig.
struct RelayServerConfig {
RelayServerConfig(RelayType type) : type(type), priority(0) {}
RelayType type;
PortList ports;
RelayCredentials credentials;
int priority;
};
class PortAllocatorSession : public sigslot::has_slots<> {
public:
// Content name passed in mostly for logging and debugging.
@ -141,6 +163,11 @@ class PortAllocator : public sigslot::has_slots<> {
}
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;
PortAllocatorSession* CreateSession(
const std::string& sid,
const std::string& content_name,

View File

@ -104,15 +104,19 @@ BasicPortAllocator::BasicPortAllocator(
stun_servers_(stun_servers) {
RelayServerConfig config(RELAY_GTURN);
if (!relay_address_udp.IsNil())
if (!relay_address_udp.IsNil()) {
config.ports.push_back(ProtocolAddress(relay_address_udp, PROTO_UDP));
if (!relay_address_tcp.IsNil())
}
if (!relay_address_tcp.IsNil()) {
config.ports.push_back(ProtocolAddress(relay_address_tcp, PROTO_TCP));
if (!relay_address_ssl.IsNil())
}
if (!relay_address_ssl.IsNil()) {
config.ports.push_back(ProtocolAddress(relay_address_ssl, PROTO_SSLTCP));
}
if (!config.ports.empty())
AddRelay(config);
if (!config.ports.empty()) {
AddTurnServer(config);
}
Construct();
}
@ -241,8 +245,8 @@ void BasicPortAllocatorSession::GetPortConfigurations() {
username(),
password());
for (size_t i = 0; i < allocator_->relays().size(); ++i) {
config->AddRelay(allocator_->relays()[i]);
for (const RelayServerConfig& turn_server : allocator_->turn_servers()) {
config->AddRelay(turn_server);
}
ConfigReady(config);
}
@ -253,8 +257,9 @@ void BasicPortAllocatorSession::ConfigReady(PortConfiguration* config) {
// Adds a configuration to the list.
void BasicPortAllocatorSession::OnConfigReady(PortConfiguration* config) {
if (config)
if (config) {
configs_.push_back(config);
}
AllocatePorts();
}

View File

@ -14,7 +14,6 @@
#include <string>
#include <vector>
#include "webrtc/p2p/base/port.h"
#include "webrtc/p2p/base/portallocator.h"
#include "webrtc/base/messagequeue.h"
#include "webrtc/base/network.h"
@ -23,28 +22,6 @@
namespace cricket {
struct RelayCredentials {
RelayCredentials() {}
RelayCredentials(const std::string& username,
const std::string& password)
: username(username),
password(password) {
}
std::string username;
std::string password;
};
typedef std::vector<ProtocolAddress> PortList;
struct RelayServerConfig {
RelayServerConfig(RelayType type) : type(type), priority(0) {}
RelayType type;
PortList ports;
RelayCredentials credentials;
int priority;
};
class BasicPortAllocator : public PortAllocator {
public:
BasicPortAllocator(rtc::NetworkManager* network_manager,
@ -60,6 +37,13 @@ class BasicPortAllocator : public PortAllocator {
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;
}
rtc::NetworkManager* network_manager() { return network_manager_; }
// If socket_factory() is set to NULL each PortAllocatorSession
@ -70,26 +54,26 @@ class BasicPortAllocator : public PortAllocator {
return stun_servers_;
}
const std::vector<RelayServerConfig>& relays() const {
return relays_;
const std::vector<RelayServerConfig>& turn_servers() const {
return turn_servers_;
}
virtual void AddRelay(const RelayServerConfig& relay) {
relays_.push_back(relay);
virtual void AddTurnServer(const RelayServerConfig& turn_server) {
turn_servers_.push_back(turn_server);
}
virtual PortAllocatorSession* CreateSessionInternal(
PortAllocatorSession* CreateSessionInternal(
const std::string& content_name,
int component,
const std::string& ice_ufrag,
const std::string& ice_pwd);
const std::string& ice_pwd) override;
private:
void Construct();
rtc::NetworkManager* network_manager_;
rtc::PacketSocketFactory* socket_factory_;
const ServerAddresses stun_servers_;
std::vector<RelayServerConfig> relays_;
ServerAddresses stun_servers_;
std::vector<RelayServerConfig> turn_servers_;
bool allow_tcp_listen_;
};
@ -110,10 +94,10 @@ class BasicPortAllocatorSession : public PortAllocatorSession,
rtc::Thread* network_thread() { return network_thread_; }
rtc::PacketSocketFactory* socket_factory() { return socket_factory_; }
virtual void StartGettingPorts();
virtual void StopGettingPorts();
virtual void ClearGettingPorts();
virtual bool IsGettingPorts() { return running_; }
void StartGettingPorts() override;
void StopGettingPorts() override;
void ClearGettingPorts() override;
bool IsGettingPorts() override { return running_; }
protected:
// Starts the process of getting the port configurations.
@ -124,7 +108,7 @@ class BasicPortAllocatorSession : public PortAllocatorSession,
virtual void ConfigReady(PortConfiguration* config);
// MessageHandler. Can be overriden if message IDs do not conflict.
virtual void OnMessage(rtc::Message *message);
void OnMessage(rtc::Message* message) override;
private:
class PortData {
@ -204,6 +188,7 @@ class BasicPortAllocatorSession : public PortAllocatorSession,
};
// Records configuration information useful in creating ports.
// TODO(deadbeef): Rename "relay" to "turn_server" in this struct.
struct PortConfiguration : public rtc::MessageData {
// TODO(jiayl): remove |stun_address| when Chrome is updated.
rtc::SocketAddress stun_address;

View File

@ -101,11 +101,24 @@ class FakePortAllocator : public cricket::PortAllocator {
}
}
void SetIceServers(
const ServerAddresses& stun_servers,
const std::vector<RelayServerConfig>& turn_servers) override {
stun_servers_ = stun_servers;
turn_servers_ = turn_servers;
}
const ServerAddresses& stun_servers() const { return stun_servers_; }
const std::vector<RelayServerConfig>& turn_servers() const {
return turn_servers_;
}
virtual cricket::PortAllocatorSession* CreateSessionInternal(
const std::string& content_name,
int component,
const std::string& ice_ufrag,
const std::string& ice_pwd) {
const std::string& ice_pwd) override {
return new FakePortAllocatorSession(
worker_thread_, factory_, content_name, component, ice_ufrag, ice_pwd);
}
@ -114,6 +127,8 @@ class FakePortAllocator : public cricket::PortAllocator {
rtc::Thread* worker_thread_;
rtc::PacketSocketFactory* factory_;
rtc::scoped_ptr<rtc::BasicPacketSocketFactory> owned_factory_;
ServerAddresses stun_servers_;
std::vector<RelayServerConfig> turn_servers_;
};
} // namespace cricket

View File

@ -154,19 +154,19 @@ class PortAllocatorTest : public testing::Test, public sigslot::has_slots<> {
void AddTurnServers(const rtc::SocketAddress& udp_turn,
const rtc::SocketAddress& tcp_turn) {
cricket::RelayServerConfig relay_server(cricket::RELAY_TURN);
cricket::RelayServerConfig turn_server(cricket::RELAY_TURN);
cricket::RelayCredentials credentials(kTurnUsername, kTurnPassword);
relay_server.credentials = credentials;
turn_server.credentials = credentials;
if (!udp_turn.IsNil()) {
relay_server.ports.push_back(cricket::ProtocolAddress(
kTurnUdpIntAddr, cricket::PROTO_UDP, false));
turn_server.ports.push_back(
cricket::ProtocolAddress(kTurnUdpIntAddr, cricket::PROTO_UDP, false));
}
if (!tcp_turn.IsNil()) {
relay_server.ports.push_back(cricket::ProtocolAddress(
kTurnTcpIntAddr, cricket::PROTO_TCP, false));
turn_server.ports.push_back(
cricket::ProtocolAddress(kTurnTcpIntAddr, cricket::PROTO_TCP, false));
}
allocator_->AddRelay(relay_server);
allocator_->AddTurnServer(turn_server);
}
bool CreateSession(int component) {
@ -332,8 +332,8 @@ class PortAllocatorTest : public testing::Test, public sigslot::has_slots<> {
}
bool HasRelayAddress(const cricket::ProtocolAddress& proto_addr) {
for (size_t i = 0; i < allocator_->relays().size(); ++i) {
cricket::RelayServerConfig server_config = allocator_->relays()[i];
for (size_t i = 0; i < allocator_->turn_servers().size(); ++i) {
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) {
@ -386,11 +386,11 @@ class PortAllocatorTest : public testing::Test, public sigslot::has_slots<> {
TEST_F(PortAllocatorTest, TestBasic) {
EXPECT_EQ(&network_manager_, allocator().network_manager());
EXPECT_EQ(kStunAddr, *allocator().stun_servers().begin());
ASSERT_EQ(1u, allocator().relays().size());
EXPECT_EQ(cricket::RELAY_GTURN, allocator().relays()[0].type);
ASSERT_EQ(1u, allocator().turn_servers().size());
EXPECT_EQ(cricket::RELAY_GTURN, allocator().turn_servers()[0].type);
// Empty relay credentials are used for GTURN.
EXPECT_TRUE(allocator().relays()[0].credentials.username.empty());
EXPECT_TRUE(allocator().relays()[0].credentials.password.empty());
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(
@ -1039,13 +1039,12 @@ TEST_F(PortAllocatorTest, TestSharedSocketWithServerAddressResolve) {
cricket::PROTO_UDP);
AddInterface(kClientAddr);
allocator_.reset(new cricket::BasicPortAllocator(&network_manager_));
cricket::RelayServerConfig relay_server(cricket::RELAY_TURN);
cricket::RelayServerConfig turn_server(cricket::RELAY_TURN);
cricket::RelayCredentials credentials(kTurnUsername, kTurnPassword);
relay_server.credentials = credentials;
relay_server.ports.push_back(cricket::ProtocolAddress(
rtc::SocketAddress("localhost", 3478),
cricket::PROTO_UDP, false));
allocator_->AddRelay(relay_server);
turn_server.credentials = credentials;
turn_server.ports.push_back(cricket::ProtocolAddress(
rtc::SocketAddress("localhost", 3478), cricket::PROTO_UDP, false));
allocator_->AddTurnServer(turn_server);
allocator_->set_step_delay(cricket::kMinimumStepDelay);
allocator_->set_flags(allocator().flags() |