Enable shared socket for TurnPort.
In AllocationSequence::OnReadPacket, we now hand the packet to both the TurnPort and StunPort if the remote address matches the server address. TESTED=AppRtc loopback call generates both turn and stun candidates. BUG=1746 R=juberti@webrtc.org Review URL: https://webrtc-codereview.appspot.com/19189004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@7138 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
@ -55,7 +55,6 @@ enum {
|
|||||||
PORTALLOCATOR_ENABLE_SHARED_UFRAG = 0x80,
|
PORTALLOCATOR_ENABLE_SHARED_UFRAG = 0x80,
|
||||||
PORTALLOCATOR_ENABLE_SHARED_SOCKET = 0x100,
|
PORTALLOCATOR_ENABLE_SHARED_SOCKET = 0x100,
|
||||||
PORTALLOCATOR_ENABLE_STUN_RETRANSMIT_ATTRIBUTE = 0x200,
|
PORTALLOCATOR_ENABLE_STUN_RETRANSMIT_ATTRIBUTE = 0x200,
|
||||||
PORTALLOCATOR_ENABLE_TURN_SHARED_SOCKET = 0x400,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint32 kDefaultPortAllocatorFlags = 0;
|
const uint32 kDefaultPortAllocatorFlags = 0;
|
||||||
@ -170,7 +169,6 @@ class PortAllocator : public sigslot::has_slots<> {
|
|||||||
|
|
||||||
uint32 step_delay() const { return step_delay_; }
|
uint32 step_delay() const { return step_delay_; }
|
||||||
void set_step_delay(uint32 delay) {
|
void set_step_delay(uint32 delay) {
|
||||||
ASSERT(delay >= kMinimumStepDelay);
|
|
||||||
step_delay_ = delay;
|
step_delay_ = delay;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ class UDPPort : public Port {
|
|||||||
return socket_->GetLocalAddress();
|
return socket_->GetLocalAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
const ServerAddresses server_addresses() const {
|
const ServerAddresses& server_addresses() const {
|
||||||
return server_addresses_;
|
return server_addresses_;
|
||||||
}
|
}
|
||||||
void
|
void
|
||||||
|
@ -149,9 +149,6 @@ class AllocationSequence : public rtc::MessageHandler,
|
|||||||
const rtc::PacketTime& packet_time);
|
const rtc::PacketTime& packet_time);
|
||||||
|
|
||||||
void OnPortDestroyed(PortInterface* port);
|
void OnPortDestroyed(PortInterface* port);
|
||||||
void OnResolvedTurnServerAddress(
|
|
||||||
TurnPort* port, const rtc::SocketAddress& server_address,
|
|
||||||
const rtc::SocketAddress& resolved_server_address);
|
|
||||||
|
|
||||||
BasicPortAllocatorSession* session_;
|
BasicPortAllocatorSession* session_;
|
||||||
rtc::Network* network_;
|
rtc::Network* network_;
|
||||||
@ -163,8 +160,7 @@ class AllocationSequence : public rtc::MessageHandler,
|
|||||||
rtc::scoped_ptr<rtc::AsyncPacketSocket> udp_socket_;
|
rtc::scoped_ptr<rtc::AsyncPacketSocket> udp_socket_;
|
||||||
// There will be only one udp port per AllocationSequence.
|
// There will be only one udp port per AllocationSequence.
|
||||||
UDPPort* udp_port_;
|
UDPPort* udp_port_;
|
||||||
// Keeping a map for turn ports keyed with server addresses.
|
std::vector<TurnPort*> turn_ports_;
|
||||||
std::map<rtc::SocketAddress, Port*> turn_ports_;
|
|
||||||
int phase_;
|
int phase_;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1054,26 +1050,15 @@ void AllocationSequence::CreateTurnPort(const RelayServerConfig& config) {
|
|||||||
// don't pass shared socket for ports which will create TCP sockets.
|
// don't pass shared socket for ports which will create TCP sockets.
|
||||||
// TODO(mallinath) - Enable shared socket mode for TURN ports. Disabled
|
// TODO(mallinath) - Enable shared socket mode for TURN ports. Disabled
|
||||||
// due to webrtc bug https://code.google.com/p/webrtc/issues/detail?id=3537
|
// due to webrtc bug https://code.google.com/p/webrtc/issues/detail?id=3537
|
||||||
if (IsFlagSet(PORTALLOCATOR_ENABLE_TURN_SHARED_SOCKET) &&
|
if (IsFlagSet(PORTALLOCATOR_ENABLE_SHARED_SOCKET) &&
|
||||||
relay_port->proto == PROTO_UDP) {
|
relay_port->proto == PROTO_UDP) {
|
||||||
port = TurnPort::Create(session_->network_thread(),
|
port = TurnPort::Create(session_->network_thread(),
|
||||||
session_->socket_factory(),
|
session_->socket_factory(),
|
||||||
network_, udp_socket_.get(),
|
network_, udp_socket_.get(),
|
||||||
session_->username(), session_->password(),
|
session_->username(), session_->password(),
|
||||||
*relay_port, config.credentials, config.priority);
|
*relay_port, config.credentials, config.priority);
|
||||||
// If we are using shared socket for TURN and udp ports, we need to
|
|
||||||
// find a way to demux the packets to the correct port when received.
|
turn_ports_.push_back(port);
|
||||||
// Mapping against server_address is one way of doing this. When packet
|
|
||||||
// is received the remote_address will be checked against the map.
|
|
||||||
// If server address is not resolved, a signal will be sent from the port
|
|
||||||
// after the address is resolved. The map entry will updated with the
|
|
||||||
// resolved address when the signal is received from the port.
|
|
||||||
if ((*relay_port).address.IsUnresolved()) {
|
|
||||||
// If server address is not resolved then listen for signal from port.
|
|
||||||
port->SignalResolvedServerAddress.connect(
|
|
||||||
this, &AllocationSequence::OnResolvedTurnServerAddress);
|
|
||||||
}
|
|
||||||
turn_ports_[(*relay_port).address] = port;
|
|
||||||
// Listen to the port destroyed signal, to allow AllocationSequence to
|
// Listen to the port destroyed signal, to allow AllocationSequence to
|
||||||
// remove entrt from it's map.
|
// remove entrt from it's map.
|
||||||
port->SignalDestroyed.connect(this, &AllocationSequence::OnPortDestroyed);
|
port->SignalDestroyed.connect(this, &AllocationSequence::OnPortDestroyed);
|
||||||
@ -1097,51 +1082,45 @@ void AllocationSequence::OnReadPacket(
|
|||||||
const rtc::SocketAddress& remote_addr,
|
const rtc::SocketAddress& remote_addr,
|
||||||
const rtc::PacketTime& packet_time) {
|
const rtc::PacketTime& packet_time) {
|
||||||
ASSERT(socket == udp_socket_.get());
|
ASSERT(socket == udp_socket_.get());
|
||||||
// If the packet is received from one of the TURN server in the config, then
|
|
||||||
// pass down the packet to that port, otherwise it will be handed down to
|
bool turn_port_found = false;
|
||||||
// the local udp port.
|
|
||||||
Port* port = NULL;
|
// Try to find the TurnPort that matches the remote address. Note that the
|
||||||
std::map<rtc::SocketAddress, Port*>::iterator iter =
|
// message could be a STUN binding response if the TURN server is also used as
|
||||||
turn_ports_.find(remote_addr);
|
// a STUN server. We don't want to parse every message here to check if it is
|
||||||
if (iter != turn_ports_.end()) {
|
// a STUN binding response, so we pass the message to TurnPort regardless of
|
||||||
port = iter->second;
|
// the message type. The TurnPort will just ignore the message since it will
|
||||||
} else if (udp_port_) {
|
// not find any request by transaction ID.
|
||||||
port = udp_port_;
|
for (std::vector<TurnPort*>::const_iterator it = turn_ports_.begin();
|
||||||
|
it != turn_ports_.end(); ++it) {
|
||||||
|
TurnPort* port = *it;
|
||||||
|
if (port->server_address().address == remote_addr) {
|
||||||
|
port->HandleIncomingPacket(socket, data, size, remote_addr, packet_time);
|
||||||
|
turn_port_found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ASSERT(port != NULL);
|
|
||||||
if (port) {
|
if (udp_port_) {
|
||||||
port->HandleIncomingPacket(socket, data, size, remote_addr, packet_time);
|
const ServerAddresses& stun_servers = udp_port_->server_addresses();
|
||||||
|
|
||||||
|
// Pass the packet to the UdpPort if there is no matching TurnPort, or if
|
||||||
|
// the TURN server is also a STUN server.
|
||||||
|
if (!turn_port_found ||
|
||||||
|
stun_servers.find(remote_addr) != stun_servers.end()) {
|
||||||
|
udp_port_->HandleIncomingPacket(
|
||||||
|
socket, data, size, remote_addr, packet_time);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AllocationSequence::OnPortDestroyed(PortInterface* port) {
|
void AllocationSequence::OnPortDestroyed(PortInterface* port) {
|
||||||
if (udp_port_ == port) {
|
if (udp_port_ == port) {
|
||||||
udp_port_ = NULL;
|
udp_port_ = NULL;
|
||||||
} else {
|
|
||||||
std::map<rtc::SocketAddress, Port*>::iterator iter;
|
|
||||||
for (iter = turn_ports_.begin(); iter != turn_ports_.end(); ++iter) {
|
|
||||||
if (iter->second == port) {
|
|
||||||
turn_ports_.erase(iter);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AllocationSequence::OnResolvedTurnServerAddress(
|
|
||||||
TurnPort* port, const rtc::SocketAddress& server_address,
|
|
||||||
const rtc::SocketAddress& resolved_server_address) {
|
|
||||||
std::map<rtc::SocketAddress, Port*>::iterator iter;
|
|
||||||
iter = turn_ports_.find(server_address);
|
|
||||||
if (iter == turn_ports_.end()) {
|
|
||||||
LOG(LS_INFO) << "TurnPort entry is not found in the map.";
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(iter->second == port);
|
turn_ports_.erase(std::find(turn_ports_.begin(), turn_ports_.end(), port));
|
||||||
// Remove old entry and then insert using the resolved address as key.
|
|
||||||
turn_ports_.erase(iter);
|
|
||||||
turn_ports_[resolved_server_address] = port;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// PortConfiguration
|
// PortConfiguration
|
||||||
|
@ -133,9 +133,32 @@ class PortAllocatorTest : public testing::Test, public sigslot::has_slots<> {
|
|||||||
bool SetPortRange(int min_port, int max_port) {
|
bool SetPortRange(int min_port, int max_port) {
|
||||||
return allocator_->SetPortRange(min_port, max_port);
|
return allocator_->SetPortRange(min_port, max_port);
|
||||||
}
|
}
|
||||||
rtc::NATServer* CreateNatServer(const SocketAddress& addr,
|
void ResetWithNatServer(const rtc::SocketAddress& stun_server) {
|
||||||
rtc::NATType type) {
|
nat_server_.reset(new rtc::NATServer(
|
||||||
return new rtc::NATServer(type, vss_.get(), addr, vss_.get(), addr);
|
rtc::NAT_OPEN_CONE, vss_.get(), kNatAddr, vss_.get(), kNatAddr));
|
||||||
|
|
||||||
|
ServerAddresses stun_servers;
|
||||||
|
stun_servers.insert(stun_server);
|
||||||
|
allocator_.reset(new cricket::BasicPortAllocator(
|
||||||
|
&network_manager_, &nat_socket_factory_, stun_servers));
|
||||||
|
allocator().set_step_delay(cricket::kMinimumStepDelay);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddTurnServers(const rtc::SocketAddress& udp_turn,
|
||||||
|
const rtc::SocketAddress& tcp_turn) {
|
||||||
|
cricket::RelayServerConfig relay_server(cricket::RELAY_TURN);
|
||||||
|
cricket::RelayCredentials credentials(kTurnUsername, kTurnPassword);
|
||||||
|
relay_server.credentials = credentials;
|
||||||
|
|
||||||
|
if (!udp_turn.IsNil()) {
|
||||||
|
relay_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));
|
||||||
|
}
|
||||||
|
allocator_->AddRelay(relay_server);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CreateSession(int component) {
|
bool CreateSession(int component) {
|
||||||
@ -254,6 +277,7 @@ class PortAllocatorTest : public testing::Test, public sigslot::has_slots<> {
|
|||||||
rtc::scoped_ptr<rtc::VirtualSocketServer> vss_;
|
rtc::scoped_ptr<rtc::VirtualSocketServer> vss_;
|
||||||
rtc::scoped_ptr<rtc::FirewallSocketServer> fss_;
|
rtc::scoped_ptr<rtc::FirewallSocketServer> fss_;
|
||||||
rtc::SocketServerScope ss_scope_;
|
rtc::SocketServerScope ss_scope_;
|
||||||
|
rtc::scoped_ptr<rtc::NATServer> nat_server_;
|
||||||
rtc::NATSocketFactory nat_factory_;
|
rtc::NATSocketFactory nat_factory_;
|
||||||
rtc::BasicPacketSocketFactory nat_socket_factory_;
|
rtc::BasicPacketSocketFactory nat_socket_factory_;
|
||||||
cricket::TestStunServer stun_server_;
|
cricket::TestStunServer stun_server_;
|
||||||
@ -580,13 +604,8 @@ TEST_F(PortAllocatorTest, TestCandidateFilterWithHostOnly) {
|
|||||||
// Host is behind the NAT.
|
// Host is behind the NAT.
|
||||||
TEST_F(PortAllocatorTest, TestCandidateFilterWithReflexiveOnly) {
|
TEST_F(PortAllocatorTest, TestCandidateFilterWithReflexiveOnly) {
|
||||||
AddInterface(kPrivateAddr);
|
AddInterface(kPrivateAddr);
|
||||||
rtc::scoped_ptr<rtc::NATServer> nat_server(
|
ResetWithNatServer(kStunAddr);
|
||||||
CreateNatServer(kNatAddr, rtc::NAT_OPEN_CONE));
|
|
||||||
ServerAddresses stun_servers;
|
|
||||||
stun_servers.insert(kStunAddr);
|
|
||||||
allocator_.reset(new cricket::BasicPortAllocator(
|
|
||||||
&network_manager_, &nat_socket_factory_, stun_servers));
|
|
||||||
allocator().set_step_delay(cricket::kMinimumStepDelay);
|
|
||||||
allocator().set_flags(cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG |
|
allocator().set_flags(cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG |
|
||||||
cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET);
|
cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET);
|
||||||
allocator().set_candidate_filter(cricket::CF_REFLEXIVE);
|
allocator().set_candidate_filter(cricket::CF_REFLEXIVE);
|
||||||
@ -771,13 +790,8 @@ TEST_F(PortAllocatorTest, TestSharedSocketWithoutNat) {
|
|||||||
// local candidates as client behind a nat.
|
// local candidates as client behind a nat.
|
||||||
TEST_F(PortAllocatorTest, TestSharedSocketWithNat) {
|
TEST_F(PortAllocatorTest, TestSharedSocketWithNat) {
|
||||||
AddInterface(kClientAddr);
|
AddInterface(kClientAddr);
|
||||||
rtc::scoped_ptr<rtc::NATServer> nat_server(
|
ResetWithNatServer(kStunAddr);
|
||||||
CreateNatServer(kNatAddr, rtc::NAT_OPEN_CONE));
|
|
||||||
ServerAddresses stun_servers;
|
|
||||||
stun_servers.insert(kStunAddr);
|
|
||||||
allocator_.reset(new cricket::BasicPortAllocator(
|
|
||||||
&network_manager_, &nat_socket_factory_, stun_servers));
|
|
||||||
allocator_->set_step_delay(cricket::kMinimumStepDelay);
|
|
||||||
allocator_->set_flags(allocator().flags() |
|
allocator_->set_flags(allocator().flags() |
|
||||||
cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG |
|
cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG |
|
||||||
cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET);
|
cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET);
|
||||||
@ -799,14 +813,8 @@ TEST_F(PortAllocatorTest, TestSharedSocketWithoutNatUsingTurn) {
|
|||||||
turn_server_.AddInternalSocket(kTurnTcpIntAddr, cricket::PROTO_TCP);
|
turn_server_.AddInternalSocket(kTurnTcpIntAddr, cricket::PROTO_TCP);
|
||||||
AddInterface(kClientAddr);
|
AddInterface(kClientAddr);
|
||||||
allocator_.reset(new cricket::BasicPortAllocator(&network_manager_));
|
allocator_.reset(new cricket::BasicPortAllocator(&network_manager_));
|
||||||
cricket::RelayServerConfig relay_server(cricket::RELAY_TURN);
|
|
||||||
cricket::RelayCredentials credentials(kTurnUsername, kTurnPassword);
|
AddTurnServers(kTurnUdpIntAddr, kTurnTcpIntAddr);
|
||||||
relay_server.credentials = credentials;
|
|
||||||
relay_server.ports.push_back(cricket::ProtocolAddress(
|
|
||||||
kTurnUdpIntAddr, cricket::PROTO_UDP, false));
|
|
||||||
relay_server.ports.push_back(cricket::ProtocolAddress(
|
|
||||||
kTurnTcpIntAddr, cricket::PROTO_TCP, false));
|
|
||||||
allocator_->AddRelay(relay_server);
|
|
||||||
|
|
||||||
allocator_->set_step_delay(cricket::kMinimumStepDelay);
|
allocator_->set_step_delay(cricket::kMinimumStepDelay);
|
||||||
allocator_->set_flags(allocator().flags() |
|
allocator_->set_flags(allocator().flags() |
|
||||||
@ -863,20 +871,10 @@ TEST_F(PortAllocatorTest, TestSharedSocketWithServerAddressResolve) {
|
|||||||
// stun and turn candidates.
|
// stun and turn candidates.
|
||||||
TEST_F(PortAllocatorTest, TestSharedSocketWithNatUsingTurn) {
|
TEST_F(PortAllocatorTest, TestSharedSocketWithNatUsingTurn) {
|
||||||
AddInterface(kClientAddr);
|
AddInterface(kClientAddr);
|
||||||
rtc::scoped_ptr<rtc::NATServer> nat_server(
|
ResetWithNatServer(kStunAddr);
|
||||||
CreateNatServer(kNatAddr, rtc::NAT_OPEN_CONE));
|
|
||||||
ServerAddresses stun_servers;
|
AddTurnServers(kTurnUdpIntAddr, rtc::SocketAddress());
|
||||||
stun_servers.insert(kStunAddr);
|
|
||||||
allocator_.reset(new cricket::BasicPortAllocator(
|
|
||||||
&network_manager_, &nat_socket_factory_, stun_servers));
|
|
||||||
cricket::RelayServerConfig relay_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);
|
|
||||||
|
|
||||||
allocator_->set_step_delay(cricket::kMinimumStepDelay);
|
|
||||||
allocator_->set_flags(allocator().flags() |
|
allocator_->set_flags(allocator().flags() |
|
||||||
cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG |
|
cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG |
|
||||||
cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET |
|
cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET |
|
||||||
@ -902,6 +900,45 @@ TEST_F(PortAllocatorTest, TestSharedSocketWithNatUsingTurn) {
|
|||||||
EXPECT_EQ(1U, ports_[1]->Candidates().size());
|
EXPECT_EQ(1U, ports_[1]->Candidates().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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) {
|
||||||
|
AddInterface(kClientAddr);
|
||||||
|
ResetWithNatServer(kTurnUdpIntAddr);
|
||||||
|
AddTurnServers(kTurnUdpIntAddr, rtc::SocketAddress());
|
||||||
|
|
||||||
|
// Must set the step delay to 0 to make sure the relay allocation phase is
|
||||||
|
// started before the STUN candidates are obtained, so that the STUN binding
|
||||||
|
// response is processed when both StunPort and TurnPort exist to reproduce
|
||||||
|
// webrtc issue 3537.
|
||||||
|
allocator_->set_step_delay(0);
|
||||||
|
allocator_->set_flags(allocator().flags() |
|
||||||
|
cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG |
|
||||||
|
cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET |
|
||||||
|
cricket::PORTALLOCATOR_DISABLE_TCP);
|
||||||
|
|
||||||
|
EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP));
|
||||||
|
session_->StartGettingPorts();
|
||||||
|
|
||||||
|
ASSERT_EQ_WAIT(3U, candidates_.size(), kDefaultAllocationTimeout);
|
||||||
|
EXPECT_PRED5(CheckCandidate, candidates_[0],
|
||||||
|
cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "udp", kClientAddr);
|
||||||
|
EXPECT_PRED5(CheckCandidate, candidates_[1],
|
||||||
|
cricket::ICE_CANDIDATE_COMPONENT_RTP, "stun", "udp",
|
||||||
|
rtc::SocketAddress(kNatAddr.ipaddr(), 0));
|
||||||
|
EXPECT_PRED5(CheckCandidate, candidates_[2],
|
||||||
|
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);
|
||||||
|
EXPECT_EQ(3U, candidates_.size());
|
||||||
|
// Local port will be created first and then TURN port.
|
||||||
|
EXPECT_EQ(2U, ports_[0]->Candidates().size());
|
||||||
|
EXPECT_EQ(1U, ports_[1]->Candidates().size());
|
||||||
|
}
|
||||||
|
|
||||||
// This test verifies when PORTALLOCATOR_ENABLE_SHARED_SOCKET flag is enabled
|
// This test verifies when PORTALLOCATOR_ENABLE_SHARED_SOCKET flag is enabled
|
||||||
// and fail to generate STUN candidate, local UDP candidate is generated
|
// and fail to generate STUN candidate, local UDP candidate is generated
|
||||||
// properly.
|
// properly.
|
||||||
|
Reference in New Issue
Block a user