diff --git a/webrtc/p2p/base/portallocator.h b/webrtc/p2p/base/portallocator.h index c89684727b..b754376d89 100644 --- a/webrtc/p2p/base/portallocator.h +++ b/webrtc/p2p/base/portallocator.h @@ -28,9 +28,13 @@ namespace cricket { // what kinds of ports are allocated. enum { + // Disable local UDP ports. This doesn't impact how we connect to relay + // servers. PORTALLOCATOR_DISABLE_UDP = 0x01, PORTALLOCATOR_DISABLE_STUN = 0x02, PORTALLOCATOR_DISABLE_RELAY = 0x04, + // Disable local TCP ports. This doesn't impact how we connect to relay + // servers. PORTALLOCATOR_DISABLE_TCP = 0x08, PORTALLOCATOR_ENABLE_SHAKER = 0x10, PORTALLOCATOR_ENABLE_IPV6 = 0x40, @@ -46,6 +50,9 @@ enum { // When specified, a loopback candidate will be generated if // PORTALLOCATOR_DISABLE_ADAPTER_ENUMERATION is specified. PORTALLOCATOR_ENABLE_LOCALHOST_CANDIDATE = 0x800, + // Disallow use of UDP when connecting to a relay server. Since proxy servers + // usually don't handle UDP, using UDP will leak the IP address. + PORTALLOCATOR_DISABLE_UDP_RELAY = 0x1000, }; const uint32 kDefaultPortAllocatorFlags = 0; diff --git a/webrtc/p2p/client/basicportallocator.cc b/webrtc/p2p/client/basicportallocator.cc index 2a9ee3b8ba..982025279d 100644 --- a/webrtc/p2p/client/basicportallocator.cc +++ b/webrtc/p2p/client/basicportallocator.cc @@ -983,6 +983,13 @@ void AllocationSequence::CreateTurnPort(const RelayServerConfig& config) { for (relay_port = config.ports.begin(); relay_port != config.ports.end(); ++relay_port) { TurnPort* port = NULL; + + // Skip UDP connections to relay servers if it's disallowed. + if (IsFlagSet(PORTALLOCATOR_DISABLE_UDP_RELAY) && + relay_port->proto == PROTO_UDP) { + continue; + } + // Shared socket mode must be enabled only for UDP based ports. Hence // don't pass shared socket for ports which will create TCP sockets. // TODO(mallinath) - Enable shared socket mode for TURN ports. Disabled diff --git a/webrtc/p2p/client/portallocator_unittest.cc b/webrtc/p2p/client/portallocator_unittest.cc index 5614425573..7a52a2eff8 100644 --- a/webrtc/p2p/client/portallocator_unittest.cc +++ b/webrtc/p2p/client/portallocator_unittest.cc @@ -606,6 +606,36 @@ TEST_F(PortAllocatorTest, rtc::IPAddress()); } +// Test that we disable relay over UDP, and only TCP is used when connecting to +// the relay server. +TEST_F(PortAllocatorTest, TestDisableUdpTurn) { + turn_server_.AddInternalSocket(kTurnTcpIntAddr, cricket::PROTO_TCP); + AddInterface(kClientAddr); + ResetWithStunServerAndNat(kStunAddr); + AddTurnServers(kTurnUdpIntAddr, kTurnTcpIntAddr); + EXPECT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP)); + session_->set_flags(cricket::PORTALLOCATOR_DISABLE_UDP_RELAY | + cricket::PORTALLOCATOR_DISABLE_UDP | + cricket::PORTALLOCATOR_DISABLE_STUN | + cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET); + + session_->StartGettingPorts(); + EXPECT_TRUE_WAIT(candidate_allocation_done_, kDefaultAllocationTimeout); + + // Expect to see 2 ports and 2 candidates - TURN/TCP and TCP ports, TCP and + // TURN/TCP candidates. + EXPECT_EQ(2U, ports_.size()); + EXPECT_EQ(2U, candidates_.size()); + EXPECT_PRED5(CheckCandidate, candidates_[0], + cricket::ICE_CANDIDATE_COMPONENT_RTP, "relay", "udp", + kTurnUdpExtAddr); + // The TURN candidate should use TCP to contact the TURN server. + EXPECT_EQ(cricket::TCP_PROTOCOL_NAME, candidates_[0].relay_protocol()); + EXPECT_PRED5(CheckCandidate, candidates_[1], + cricket::ICE_CANDIDATE_COMPONENT_RTP, "local", "tcp", + kClientAddr); +} + // Disable for asan, see // https://code.google.com/p/webrtc/issues/detail?id=4743 for details. #if !defined(ADDRESS_SANITIZER)