diff options
Diffstat (limited to 'chromium/third_party/libjingle/source/talk/p2p/client')
6 files changed, 294 insertions, 126 deletions
diff --git a/chromium/third_party/libjingle/source/talk/p2p/client/basicportallocator.cc b/chromium/third_party/libjingle/source/talk/p2p/client/basicportallocator.cc index dbc2e3342ee..762726fbb24 100644 --- a/chromium/third_party/libjingle/source/talk/p2p/client/basicportallocator.cc +++ b/chromium/third_party/libjingle/source/talk/p2p/client/basicportallocator.cc @@ -56,7 +56,6 @@ const uint32 MSG_SEQUENCEOBJECTS_CREATED = 6; const uint32 MSG_CONFIG_STOP = 7; const uint32 ALLOCATE_DELAY = 250; -const uint32 ALLOCATION_STEP_DELAY = 1 * 1000; const int PHASE_UDP = 0; const int PHASE_RELAY = 1; @@ -65,10 +64,6 @@ const int PHASE_SSLTCP = 3; const int kNumPhases = 4; -// Both these values are in bytes. -const int kLargeSocketSendBufferSize = 128 * 1024; -const int kNormalSocketSendBufferSize = 64 * 1024; - const int SHAKE_MIN_DELAY = 45 * 1000; // 45 seconds const int SHAKE_MAX_DELAY = 90 * 1000; // 90 seconds @@ -107,6 +102,7 @@ class AllocationSequence : public talk_base::MessageHandler, uint32 flags); ~AllocationSequence(); bool Init(); + void Clear(); State state() const { return state_; } @@ -153,6 +149,9 @@ class AllocationSequence : public talk_base::MessageHandler, const talk_base::PacketTime& packet_time); void OnPortDestroyed(PortInterface* port); + void OnResolvedTurnServerAddress( + TurnPort* port, const talk_base::SocketAddress& server_address, + const talk_base::SocketAddress& resolved_server_address); BasicPortAllocatorSession* session_; talk_base::Network* network_; @@ -162,8 +161,10 @@ class AllocationSequence : public talk_base::MessageHandler, uint32 flags_; ProtocolList protocols_; talk_base::scoped_ptr<talk_base::AsyncPacketSocket> udp_socket_; - // Keeping a list of all UDP based ports. - std::deque<Port*> ports; + // There will be only one udp port per AllocationSequence. + UDPPort* udp_port_; + // Keeping a map for turn ports keyed with server addresses. + std::map<talk_base::SocketAddress, Port*> turn_ports_; int phase_; }; @@ -206,13 +207,15 @@ BasicPortAllocator::BasicPortAllocator( stun_address_(stun_address) { RelayServerConfig config(RELAY_GTURN); - if (!relay_address_udp.IsAny()) + if (!relay_address_udp.IsNil()) config.ports.push_back(ProtocolAddress(relay_address_udp, PROTO_UDP)); - if (!relay_address_tcp.IsAny()) + if (!relay_address_tcp.IsNil()) config.ports.push_back(ProtocolAddress(relay_address_tcp, PROTO_TCP)); - if (!relay_address_ssl.IsAny()) + if (!relay_address_ssl.IsNil()) config.ports.push_back(ProtocolAddress(relay_address_ssl, PROTO_SSLTCP)); - AddRelay(config); + + if (!config.ports.empty()) + AddRelay(config); Construct(); } @@ -242,7 +245,6 @@ BasicPortAllocatorSession::BasicPortAllocatorSession( ice_ufrag, ice_pwd, allocator->flags()), allocator_(allocator), network_thread_(NULL), socket_factory_(allocator->socket_factory()), - configuration_done_(false), allocation_started_(false), network_manager_started_(false), running_(false), @@ -257,6 +259,12 @@ BasicPortAllocatorSession::~BasicPortAllocatorSession() { if (network_thread_ != NULL) network_thread_->Clear(this); + for (uint32 i = 0; i < sequences_.size(); ++i) { + // AllocationSequence should clear it's map entry for turn ports before + // ports are destroyed. + sequences_[i]->Clear(); + } + std::vector<PortData>::iterator it; for (it = ports_.begin(); it != ports_.end(); it++) delete it->port(); @@ -490,16 +498,6 @@ void BasicPortAllocatorSession::AddAllocatedPort(Port* port, port->set_send_retransmit_count_attribute((allocator_->flags() & PORTALLOCATOR_ENABLE_STUN_RETRANSMIT_ATTRIBUTE) != 0); - if (content_name().compare(CN_VIDEO) == 0 && - component_ == cricket::ICE_CANDIDATE_COMPONENT_RTP) { - // For video RTP alone, we set send-buffer sizes. This used to be set in the - // engines/channels. - int sendBufSize = (flags() & PORTALLOCATOR_USE_LARGE_SOCKET_SEND_BUFFERS) - ? kLargeSocketSendBufferSize - : kNormalSocketSendBufferSize; - port->SetOption(talk_base::Socket::OPT_SNDBUF, sendBufSize); - } - PortData data(port, seq); ports_.push_back(data); @@ -515,8 +513,6 @@ void BasicPortAllocatorSession::AddAllocatedPort(Port* port, if (prepare_address) port->PrepareAddress(); - if (running_) - port->Start(); } void BasicPortAllocatorSession::OnAllocationSequenceObjectsCreated() { @@ -711,6 +707,7 @@ AllocationSequence::AllocationSequence(BasicPortAllocatorSession* session, state_(kInit), flags_(flags), udp_socket_(), + udp_port_(NULL), phase_(0) { } @@ -737,6 +734,11 @@ bool AllocationSequence::Init() { return true; } +void AllocationSequence::Clear() { + udp_port_ = NULL; + turn_ports_.clear(); +} + AllocationSequence::~AllocationSequence() { session_->network_thread()->Clear(this); } @@ -873,18 +875,27 @@ void AllocationSequence::CreateUDPPorts() { } if (port) { - ports.push_back(port); // If shared socket is enabled, STUN candidate will be allocated by the // UDPPort. - if (IsFlagSet(PORTALLOCATOR_ENABLE_SHARED_SOCKET) && - !IsFlagSet(PORTALLOCATOR_DISABLE_STUN)) { - ASSERT(config_ && !config_->stun_address.IsNil()); - if (!(config_ && !config_->stun_address.IsNil())) { - LOG(LS_WARNING) - << "AllocationSequence: No STUN server configured, skipping."; - return; + if (IsFlagSet(PORTALLOCATOR_ENABLE_SHARED_SOCKET)) { + udp_port_ = port; + + // If STUN is not disabled, setting stun server address to port. + if (!IsFlagSet(PORTALLOCATOR_DISABLE_STUN)) { + // If config has stun_address, use it to get server reflexive candidate + // otherwise use first TURN server which supports UDP. + if (config_ && !config_->stun_address.IsNil()) { + LOG(LS_INFO) << "AllocationSequence: UDPPort will be handling the " + << "STUN candidate generation."; + port->set_server_addr(config_->stun_address); + } else if (config_ && + config_->SupportsProtocol(RELAY_TURN, PROTO_UDP)) { + port->set_server_addr(config_->GetFirstRelayServerAddress( + RELAY_TURN, PROTO_UDP)); + LOG(LS_INFO) << "AllocationSequence: TURN Server address will be " + << " used for generating STUN candidate."; + } } - port->set_server_addr(config_->stun_address); } session_->AddAllocatedPort(port, this, true); @@ -919,8 +930,6 @@ void AllocationSequence::CreateStunPorts() { } if (IsFlagSet(PORTALLOCATOR_ENABLE_SHARED_SOCKET)) { - LOG(LS_INFO) << "AllocationSequence: " - << "UDPPort will be handling the STUN candidate generation."; return; } @@ -1010,17 +1019,44 @@ void AllocationSequence::CreateTurnPort(const RelayServerConfig& config) { PortList::const_iterator relay_port; for (relay_port = config.ports.begin(); relay_port != config.ports.end(); ++relay_port) { - TurnPort* port = TurnPort::Create(session_->network_thread(), - session_->socket_factory(), - network_, ip_, - session_->allocator()->min_port(), - session_->allocator()->max_port(), - session_->username(), - session_->password(), - *relay_port, config.credentials); - if (port) { - session_->AddAllocatedPort(port, this, true); + TurnPort* port = NULL; + // Shared socket mode must be enabled only for UDP based ports. Hence + // don't pass shared socket for ports which will create TCP sockets. + if (IsFlagSet(PORTALLOCATOR_ENABLE_SHARED_SOCKET) && + relay_port->proto == PROTO_UDP) { + port = TurnPort::Create(session_->network_thread(), + session_->socket_factory(), + network_, udp_socket_.get(), + session_->username(), session_->password(), + *relay_port, config.credentials); + // 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. + // 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 + // remove entrt from it's map. + port->SignalDestroyed.connect(this, &AllocationSequence::OnPortDestroyed); + } else { + port = TurnPort::Create(session_->network_thread(), + session_->socket_factory(), + network_, ip_, + session_->allocator()->min_port(), + session_->allocator()->max_port(), + session_->username(), + session_->password(), + *relay_port, config.credentials); } + ASSERT(port != NULL); + session_->AddAllocatedPort(port, this, true); } } @@ -1029,22 +1065,51 @@ void AllocationSequence::OnReadPacket( const talk_base::SocketAddress& remote_addr, const talk_base::PacketTime& packet_time) { ASSERT(socket == udp_socket_.get()); - for (std::deque<Port*>::iterator iter = ports.begin(); - iter != ports.end(); ++iter) { - // We have only one port in the queue. - // TODO(mallinath) - Add shared socket support to Relay and Turn ports. - if ((*iter)->HandleIncomingPacket( - socket, data, size, remote_addr, packet_time)) { - break; - } + // 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 + // the local udp port. + Port* port = NULL; + std::map<talk_base::SocketAddress, Port*>::iterator iter = + turn_ports_.find(remote_addr); + if (iter != turn_ports_.end()) { + port = iter->second; + } else if (udp_port_) { + port = udp_port_; + } + ASSERT(port != NULL); + if (port) { + port->HandleIncomingPacket(socket, data, size, remote_addr, packet_time); } } void AllocationSequence::OnPortDestroyed(PortInterface* port) { - std::deque<Port*>::iterator iter = - std::find(ports.begin(), ports.end(), port); - ASSERT(iter != ports.end()); - ports.erase(iter); + if (udp_port_ == port) { + udp_port_ = NULL; + } else { + std::map<talk_base::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 talk_base::SocketAddress& server_address, + const talk_base::SocketAddress& resolved_server_address) { + std::map<talk_base::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; + } + + ASSERT(iter->second == port); + // Remove old entry and then insert using the resolved address as key. + turn_ports_.erase(iter); + turn_ports_[resolved_server_address] = port; } // PortConfiguration @@ -1062,7 +1127,7 @@ void PortConfiguration::AddRelay(const RelayServerConfig& config) { } bool PortConfiguration::SupportsProtocol( - const RelayServerConfig& relay, ProtocolType type) { + const RelayServerConfig& relay, ProtocolType type) const { PortList::const_iterator relay_port; for (relay_port = relay.ports.begin(); relay_port != relay.ports.end(); @@ -1073,4 +1138,24 @@ bool PortConfiguration::SupportsProtocol( return false; } +bool PortConfiguration::SupportsProtocol(RelayType turn_type, + ProtocolType type) const { + for (size_t i = 0; i < relays.size(); ++i) { + if (relays[i].type == turn_type && + SupportsProtocol(relays[i], type)) + return true; + } + return false; +} + +talk_base::SocketAddress PortConfiguration::GetFirstRelayServerAddress( + RelayType turn_type, ProtocolType type) const { + for (size_t i = 0; i < relays.size(); ++i) { + if (relays[i].type == turn_type && SupportsProtocol(relays[i], type)) { + return relays[i].ports.front().address; + } + } + return talk_base::SocketAddress(); +} + } // namespace cricket diff --git a/chromium/third_party/libjingle/source/talk/p2p/client/basicportallocator.h b/chromium/third_party/libjingle/source/talk/p2p/client/basicportallocator.h index 1fc6ebe10fb..8a60c425ca6 100644 --- a/chromium/third_party/libjingle/source/talk/p2p/client/basicportallocator.h +++ b/chromium/third_party/libjingle/source/talk/p2p/client/basicportallocator.h @@ -204,7 +204,6 @@ class BasicPortAllocatorSession : public PortAllocatorSession, talk_base::Thread* network_thread_; talk_base::scoped_ptr<talk_base::PacketSocketFactory> owned_socket_factory_; talk_base::PacketSocketFactory* socket_factory_; - bool configuration_done_; bool allocation_started_; bool network_manager_started_; bool running_; // set when StartGetAllPorts is called @@ -233,8 +232,13 @@ struct PortConfiguration : public talk_base::MessageData { void AddRelay(const RelayServerConfig& config); // Determines whether the given relay server supports the given protocol. - static bool SupportsProtocol(const RelayServerConfig& relay, - ProtocolType type); + bool SupportsProtocol(const RelayServerConfig& relay, + ProtocolType type) const; + bool SupportsProtocol(RelayType turn_type, ProtocolType type) const; + // Helper method returns the first server address for the matching + // RelayType and Protocol type. + talk_base::SocketAddress GetFirstRelayServerAddress( + RelayType turn_type, ProtocolType type) const; }; } // namespace cricket diff --git a/chromium/third_party/libjingle/source/talk/p2p/client/connectivitychecker.cc b/chromium/third_party/libjingle/source/talk/p2p/client/connectivitychecker.cc index 1075bd6947b..1b599430ed1 100644 --- a/chromium/third_party/libjingle/source/talk/p2p/client/connectivitychecker.cc +++ b/chromium/third_party/libjingle/source/talk/p2p/client/connectivitychecker.cc @@ -22,10 +22,6 @@ namespace cricket { -static const char kSessionTypeVideo[] = - "http://www.google.com/session/video"; -static const char kSessionNameRtp[] = "rtp"; - static const char kDefaultStunHostname[] = "stun.l.google.com"; static const int kDefaultStunPort = 19302; diff --git a/chromium/third_party/libjingle/source/talk/p2p/client/connectivitychecker_unittest.cc b/chromium/third_party/libjingle/source/talk/p2p/client/connectivitychecker_unittest.cc index fe1cb9b5391..c62120beeb7 100644 --- a/chromium/third_party/libjingle/source/talk/p2p/client/connectivitychecker_unittest.cc +++ b/chromium/third_party/libjingle/source/talk/p2p/client/connectivitychecker_unittest.cc @@ -23,8 +23,6 @@ static const talk_base::SocketAddress kStunAddr("44.44.44.44", 4444); static const talk_base::SocketAddress kRelayAddr("55.55.55.55", 5555); static const talk_base::SocketAddress kProxyAddr("66.66.66.66", 6666); static const talk_base::ProxyType kProxyType = talk_base::PROXY_HTTPS; -static const char kChannelName[] = "rtp_test"; -static const int kComponent = 1; static const char kRelayHost[] = "relay.google.com"; static const char kRelayToken[] = "CAESFwoOb2phQGdvb2dsZS5jb20Q043h47MmGhBTB1rbfIXkhuarDCZe+xF6"; @@ -75,7 +73,7 @@ class FakeStunPort : public StunPort { // Just set external address and signal that we are done. virtual void PrepareAddress() { - AddAddress(kExternalAddr, kExternalAddr, "udp", + AddAddress(kExternalAddr, kExternalAddr, talk_base::SocketAddress(), "udp", STUN_PORT_TYPE, ICE_TYPE_PREFERENCE_SRFLX, true); SignalPortComplete(this); } diff --git a/chromium/third_party/libjingle/source/talk/p2p/client/httpportallocator.cc b/chromium/third_party/libjingle/source/talk/p2p/client/httpportallocator.cc index e54acba5c4d..b881d439f18 100644 --- a/chromium/third_party/libjingle/source/talk/p2p/client/httpportallocator.cc +++ b/chromium/third_party/libjingle/source/talk/p2p/client/httpportallocator.cc @@ -41,9 +41,6 @@ namespace { -const uint32 MSG_TIMEOUT = 100; // must not conflict - // with BasicPortAllocator.cpp - // Helper routine to remove whitespace from the ends of a string. void Trim(std::string& str) { size_t first = str.find_first_not_of(" \t\r\n"); diff --git a/chromium/third_party/libjingle/source/talk/p2p/client/portallocator_unittest.cc b/chromium/third_party/libjingle/source/talk/p2p/client/portallocator_unittest.cc index 6966e44d04e..44a8f2725d8 100644 --- a/chromium/third_party/libjingle/source/talk/p2p/client/portallocator_unittest.cc +++ b/chromium/third_party/libjingle/source/talk/p2p/client/portallocator_unittest.cc @@ -35,6 +35,7 @@ #include "talk/base/network.h" #include "talk/base/physicalsocketserver.h" #include "talk/base/socketaddress.h" +#include "talk/base/ssladapter.h" #include "talk/base/thread.h" #include "talk/base/virtualsocketserver.h" #include "talk/p2p/base/basicpacketsocketfactory.h" @@ -43,6 +44,7 @@ #include "talk/p2p/base/portallocatorsessionproxy.h" #include "talk/p2p/base/testrelayserver.h" #include "talk/p2p/base/teststunserver.h" +#include "talk/p2p/base/testturnserver.h" #include "talk/p2p/client/basicportallocator.h" #include "talk/p2p/client/httpportallocator.h" @@ -52,6 +54,7 @@ using talk_base::Thread; static const SocketAddress kClientAddr("11.11.11.11", 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 kNatAddr("77.77.77.77", talk_base::NAT_SERVER_PORT); static const SocketAddress kRemoteClientAddr("22.22.22.22", 0); static const SocketAddress kStunAddr("99.99.99.1", cricket::STUN_SERVER_PORT); @@ -61,6 +64,9 @@ static const SocketAddress kRelayTcpIntAddr("99.99.99.2", 5002); static const SocketAddress kRelayTcpExtAddr("99.99.99.3", 5003); static const SocketAddress kRelaySslTcpIntAddr("99.99.99.2", 5004); static const SocketAddress kRelaySslTcpExtAddr("99.99.99.3", 5005); +static const SocketAddress kTurnUdpIntAddr("99.99.99.4", 3478); +static const SocketAddress kTurnTcpIntAddr("99.99.99.5", 3478); +static const SocketAddress kTurnUdpExtAddr("99.99.99.6", 0); // Minimum and maximum port for port range tests. static const int kMinPort = 10000; @@ -74,6 +80,8 @@ static const char kIcePwd0[] = "TESTICEPWD00000000000000"; static const char kContentName[] = "test content"; static const int kDefaultAllocationTimeout = 1000; +static const char kTurnUsername[] = "test"; +static const char kTurnPassword[] = "test"; namespace cricket { @@ -88,9 +96,13 @@ std::ostream& operator<<(std::ostream& os, const cricket::Candidate& c) { class PortAllocatorTest : public testing::Test, public sigslot::has_slots<> { public: static void SetUpTestCase() { - // Ensure the RNG is inited. - talk_base::InitRandom(NULL, 0); + talk_base::InitializeSSL(); } + + static void TearDownTestCase() { + talk_base::CleanupSSL(); + } + PortAllocatorTest() : pss_(new talk_base::PhysicalSocketServer), vss_(new talk_base::VirtualSocketServer(pss_.get())), @@ -102,6 +114,7 @@ class PortAllocatorTest : public testing::Test, public sigslot::has_slots<> { relay_server_(Thread::Current(), kRelayUdpIntAddr, kRelayUdpExtAddr, kRelayTcpIntAddr, kRelayTcpExtAddr, kRelaySslTcpIntAddr, kRelaySslTcpExtAddr), + turn_server_(Thread::Current(), kTurnUdpIntAddr, kTurnUdpExtAddr), allocator_(new cricket::BasicPortAllocator( &network_manager_, kStunAddr, kRelayUdpIntAddr, kRelayTcpIntAddr, kRelaySslTcpIntAddr)), @@ -240,6 +253,7 @@ class PortAllocatorTest : public testing::Test, public sigslot::has_slots<> { talk_base::BasicPacketSocketFactory nat_socket_factory_; cricket::TestStunServer stun_server_; cricket::TestRelayServer relay_server_; + cricket::TestTurnServer turn_server_; talk_base::FakeNetworkManager network_manager_; talk_base::scoped_ptr<cricket::BasicPortAllocator> allocator_; talk_base::scoped_ptr<cricket::PortAllocatorSession> session_; @@ -331,56 +345,7 @@ TEST_F(PortAllocatorTest, TestSetupVideoRtpPortsWithNormalSendBuffers) { // If we Stop gathering now, we shouldn't get a second "done" callback. session_->StopGettingPorts(); - // All ports should have normal send-buffer sizes (64KB). - CheckSendBufferSizesOfAllPorts(64 * 1024); -} - -TEST_F(PortAllocatorTest, TestSetupVideoRtpPortsWithLargeSendBuffers) { - AddInterface(kClientAddr); - allocator_->set_flags(allocator_->flags() | - cricket::PORTALLOCATOR_USE_LARGE_SOCKET_SEND_BUFFERS); - 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_); - // If we Stop gathering now, we shouldn't get a second "done" callback. - session_->StopGettingPorts(); - - // All ports should have large send-buffer sizes (128KB). - CheckSendBufferSizesOfAllPorts(128 * 1024); -} - -TEST_F(PortAllocatorTest, TestSetupVideoRtcpPortsAndCheckSendBuffers) { - AddInterface(kClientAddr); - allocator_->set_flags(allocator_->flags() | - cricket::PORTALLOCATOR_USE_LARGE_SOCKET_SEND_BUFFERS); - EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTCP, - cricket::CN_DATA)); - session_->StartGettingPorts(); - ASSERT_EQ_WAIT(7U, candidates_.size(), kDefaultAllocationTimeout); - EXPECT_TRUE(candidate_allocation_done_); - // If we Stop gathering now, we shouldn't get a second "done" callback. - session_->StopGettingPorts(); - - // No ports should have send-buffer size set. - CheckSendBufferSizesOfAllPorts(-1); -} - - -TEST_F(PortAllocatorTest, TestSetupNonVideoPortsAndCheckSendBuffers) { - AddInterface(kClientAddr); - allocator_->set_flags(allocator_->flags() | - cricket::PORTALLOCATOR_USE_LARGE_SOCKET_SEND_BUFFERS); - EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP, - cricket::CN_DATA)); - session_->StartGettingPorts(); - ASSERT_EQ_WAIT(7U, candidates_.size(), kDefaultAllocationTimeout); - EXPECT_TRUE(candidate_allocation_done_); - // If we Stop gathering now, we shouldn't get a second "done" callback. - session_->StopGettingPorts(); - - // No ports should have send-buffer size set. + // All ports should have unset send-buffer sizes. CheckSendBufferSizesOfAllPorts(-1); } @@ -536,6 +501,23 @@ TEST_F(PortAllocatorTest, TestGetAllPortsNoUdpAllowed) { EXPECT_TRUE_WAIT(candidate_allocation_done_, 9000); } +TEST_F(PortAllocatorTest, TestCandidatePriorityOfMultipleInterfaces) { + AddInterface(kClientAddr); + AddInterface(kClientAddr2); + // Allocating only host UDP ports. This is done purely for testing + // convenience. + allocator().set_flags(cricket::PORTALLOCATOR_DISABLE_TCP | + cricket::PORTALLOCATOR_DISABLE_STUN | + cricket::PORTALLOCATOR_DISABLE_RELAY); + EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP)); + session_->StartGettingPorts(); + EXPECT_TRUE_WAIT(candidate_allocation_done_, kDefaultAllocationTimeout); + ASSERT_EQ(2U, candidates_.size()); + EXPECT_EQ(2U, ports_.size()); + // Candidates priorities should be different. + EXPECT_NE(candidates_[0].priority(), candidates_[1].priority()); +} + // Test to verify ICE restart process. TEST_F(PortAllocatorTest, TestGetAllPortsRestarts) { AddInterface(kClientAddr); @@ -680,7 +662,7 @@ TEST_F(PortAllocatorTest, TestDisableSharedUfrag) { // 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, TestEnableSharedSocketWithoutNat) { +TEST_F(PortAllocatorTest, TestSharedSocketWithoutNat) { AddInterface(kClientAddr); allocator_->set_flags(allocator().flags() | cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG | @@ -697,7 +679,7 @@ TEST_F(PortAllocatorTest, TestEnableSharedSocketWithoutNat) { // 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, TestEnableSharedSocketWithNat) { +TEST_F(PortAllocatorTest, TestSharedSocketWithNat) { AddInterface(kClientAddr); talk_base::scoped_ptr<talk_base::NATServer> nat_server( CreateNatServer(kNatAddr, talk_base::NAT_OPEN_CONE)); @@ -720,10 +702,116 @@ TEST_F(PortAllocatorTest, TestEnableSharedSocketWithNat) { EXPECT_EQ(3U, candidates_.size()); } +// Test TURN port in shared socket mode with UDP and TCP TURN server adderesses. +TEST_F(PortAllocatorTest, TestSharedSocketWithoutNatUsingTurn) { + turn_server_.AddInternalSocket(kTurnTcpIntAddr, cricket::PROTO_TCP); + AddInterface(kClientAddr); + allocator_.reset(new cricket::BasicPortAllocator(&network_manager_)); + 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)); + relay_server.ports.push_back(cricket::ProtocolAddress( + kTurnTcpIntAddr, cricket::PROTO_TCP, false)); + allocator_->AddRelay(relay_server); + + allocator_->set_step_delay(cricket::kMinimumStepDelay); + 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); + ASSERT_EQ(3U, ports_.size()); + EXPECT_PRED5(CheckCandidate, candidates_[0], + cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "udp", kClientAddr); + EXPECT_PRED5(CheckCandidate, candidates_[1], + cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp", + talk_base::SocketAddress(kTurnUdpExtAddr.ipaddr(), 0)); + EXPECT_PRED5(CheckCandidate, candidates_[2], + cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp", + talk_base::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) { + turn_server_.AddInternalSocket(talk_base::SocketAddress("127.0.0.1", 3478), + cricket::PROTO_UDP); + AddInterface(kClientAddr); + allocator_.reset(new cricket::BasicPortAllocator(&network_manager_)); + cricket::RelayServerConfig relay_server(cricket::RELAY_TURN); + cricket::RelayCredentials credentials(kTurnUsername, kTurnPassword); + relay_server.credentials = credentials; + relay_server.ports.push_back(cricket::ProtocolAddress( + talk_base::SocketAddress("localhost", 3478), + cricket::PROTO_UDP, false)); + allocator_->AddRelay(relay_server); + + allocator_->set_step_delay(cricket::kMinimumStepDelay); + 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(); + + EXPECT_EQ_WAIT(2U, ports_.size(), kDefaultAllocationTimeout); +} + +// 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) { + AddInterface(kClientAddr); + talk_base::scoped_ptr<talk_base::NATServer> nat_server( + CreateNatServer(kNatAddr, talk_base::NAT_OPEN_CONE)); + allocator_.reset(new cricket::BasicPortAllocator( + &network_manager_, &nat_socket_factory_, kStunAddr)); + 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() | + 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); + ASSERT_EQ(2U, ports_.size()); + 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", + talk_base::SocketAddress(kNatAddr.ipaddr(), 0)); + EXPECT_PRED5(CheckCandidate, candidates_[2], + cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp", + talk_base::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. + 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 // and fail to generate STUN candidate, local UDP candidate is generated // properly. -TEST_F(PortAllocatorTest, TestEnableSharedSocketNoUdpAllowed) { +TEST_F(PortAllocatorTest, TestSharedSocketNoUdpAllowed) { allocator().set_flags(allocator().flags() | cricket::PORTALLOCATOR_DISABLE_RELAY | cricket::PORTALLOCATOR_DISABLE_TCP | |