aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/BUILD.gn14
-rw-r--r--examples/relayserver/relayserver_main.cc66
-rw-r--r--p2p/BUILD.gn7
-rw-r--r--p2p/base/p2p_transport_channel_unittest.cc7
-rw-r--r--p2p/base/port.h5
-rw-r--r--p2p/base/port_allocator.cc4
-rw-r--r--p2p/base/port_allocator.h5
-rw-r--r--p2p/base/port_unittest.cc190
-rw-r--r--p2p/base/regathering_controller_unittest.cc2
-rw-r--r--p2p/base/relay_port.cc860
-rw-r--r--p2p/base/relay_port.h118
-rw-r--r--p2p/base/relay_port_unittest.cc272
-rw-r--r--p2p/base/relay_server.cc741
-rw-r--r--p2p/base/relay_server.h235
-rw-r--r--p2p/base/relay_server_unittest.cc511
-rw-r--r--p2p/base/test_relay_server.h101
-rw-r--r--p2p/client/basic_port_allocator.cc48
-rw-r--r--p2p/client/basic_port_allocator.h6
-rw-r--r--p2p/client/basic_port_allocator_unittest.cc5
19 files changed, 52 insertions, 3145 deletions
diff --git a/examples/BUILD.gn b/examples/BUILD.gn
index 7b69c2b85c..6c3c6581f1 100644
--- a/examples/BUILD.gn
+++ b/examples/BUILD.gn
@@ -47,7 +47,6 @@ group("examples") {
if (is_linux || is_win) {
deps += [
":peerconnection_server",
- ":relayserver",
":stunserver",
":turnserver",
]
@@ -740,19 +739,6 @@ if (is_linux || is_win) {
"//third_party/abseil-cpp/absl/flags:usage",
]
}
- rtc_executable("relayserver") {
- testonly = true
- sources = [
- "relayserver/relayserver_main.cc",
- ]
- deps = [
- "../p2p:p2p_server_utils",
- "../p2p:rtc_p2p",
- "../pc:rtc_pc",
- "../rtc_base",
- "../rtc_base:rtc_base_approved",
- ]
- }
rtc_executable("turnserver") {
testonly = true
sources = [
diff --git a/examples/relayserver/relayserver_main.cc b/examples/relayserver/relayserver_main.cc
deleted file mode 100644
index 2045cb4031..0000000000
--- a/examples/relayserver/relayserver_main.cc
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright 2004 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 <iostream> // NOLINT
-#include <memory>
-
-#include "p2p/base/relay_server.h"
-#include "rtc_base/async_udp_socket.h"
-#include "rtc_base/socket_address.h"
-#include "rtc_base/socket_server.h"
-#include "rtc_base/thread.h"
-
-int main(int argc, char** argv) {
- if (argc != 3) {
- std::cerr << "usage: relayserver internal-address external-address"
- << std::endl;
- return 1;
- }
-
- rtc::SocketAddress int_addr;
- if (!int_addr.FromString(argv[1])) {
- std::cerr << "Unable to parse IP address: " << argv[1];
- return 1;
- }
-
- rtc::SocketAddress ext_addr;
- if (!ext_addr.FromString(argv[2])) {
- std::cerr << "Unable to parse IP address: " << argv[2];
- return 1;
- }
-
- rtc::Thread* pthMain = rtc::Thread::Current();
-
- std::unique_ptr<rtc::AsyncUDPSocket> int_socket(
- rtc::AsyncUDPSocket::Create(pthMain->socketserver(), int_addr));
- if (!int_socket) {
- std::cerr << "Failed to create a UDP socket bound at" << int_addr.ToString()
- << std::endl;
- return 1;
- }
-
- std::unique_ptr<rtc::AsyncUDPSocket> ext_socket(
- rtc::AsyncUDPSocket::Create(pthMain->socketserver(), ext_addr));
- if (!ext_socket) {
- std::cerr << "Failed to create a UDP socket bound at" << ext_addr.ToString()
- << std::endl;
- return 1;
- }
-
- cricket::RelayServer server(pthMain);
- server.AddInternalSocket(int_socket.get());
- server.AddExternalSocket(ext_socket.get());
-
- std::cout << "Listening internally at " << int_addr.ToString() << std::endl;
- std::cout << "Listening externally at " << ext_addr.ToString() << std::endl;
-
- pthMain->Run();
- return 0;
-}
diff --git a/p2p/BUILD.gn b/p2p/BUILD.gn
index 0b3d28c404..8c4b6f636b 100644
--- a/p2p/BUILD.gn
+++ b/p2p/BUILD.gn
@@ -70,8 +70,6 @@ rtc_library("rtc_p2p") {
"base/pseudo_tcp.h",
"base/regathering_controller.cc",
"base/regathering_controller.h",
- "base/relay_port.cc",
- "base/relay_port.h",
"base/stun_port.cc",
"base/stun_port.h",
"base/stun_request.cc",
@@ -160,7 +158,6 @@ if (rtc_include_tests) {
"base/fake_packet_transport.h",
"base/mock_async_resolver.h",
"base/mock_ice_transport.h",
- "base/test_relay_server.h",
"base/test_stun_server.cc",
"base/test_stun_server.h",
"base/test_turn_customizer.h",
@@ -200,8 +197,6 @@ if (rtc_include_tests) {
"base/port_unittest.cc",
"base/pseudo_tcp_unittest.cc",
"base/regathering_controller_unittest.cc",
- "base/relay_port_unittest.cc",
- "base/relay_server_unittest.cc",
"base/stun_port_unittest.cc",
"base/stun_request_unittest.cc",
"base/stun_server_unittest.cc",
@@ -244,8 +239,6 @@ if (rtc_include_tests) {
rtc_library("p2p_server_utils") {
testonly = true
sources = [
- "base/relay_server.cc",
- "base/relay_server.h",
"base/stun_server.cc",
"base/stun_server.h",
"base/turn_server.cc",
diff --git a/p2p/base/p2p_transport_channel_unittest.cc b/p2p/base/p2p_transport_channel_unittest.cc
index 3919b3f068..76030189ff 100644
--- a/p2p/base/p2p_transport_channel_unittest.cc
+++ b/p2p/base/p2p_transport_channel_unittest.cc
@@ -19,7 +19,6 @@
#include "p2p/base/ice_transport_internal.h"
#include "p2p/base/mock_async_resolver.h"
#include "p2p/base/packet_transport_internal.h"
-#include "p2p/base/test_relay_server.h"
#include "p2p/base/test_stun_server.h"
#include "p2p/base/test_turn_server.h"
#include "p2p/client/basic_port_allocator.h"
@@ -156,7 +155,7 @@ cricket::BasicPortAllocator* CreateBasicPortAllocator(
const cricket::ServerAddresses& stun_servers,
const rtc::SocketAddress& turn_server_udp,
const rtc::SocketAddress& turn_server_tcp) {
- cricket::RelayServerConfig turn_server(cricket::RELAY_TURN);
+ cricket::RelayServerConfig turn_server;
turn_server.credentials = kRelayCredentials;
if (!turn_server_udp.IsNil()) {
turn_server.ports.push_back(
@@ -2578,7 +2577,7 @@ TEST_F(P2PTransportChannelMultihomedTest, TestFailoverControllingSide) {
TEST_F(P2PTransportChannelMultihomedTest, TestFailoverWithManyConnections) {
rtc::ScopedFakeClock clock;
test_turn_server()->AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
- RelayServerConfig turn_server(RELAY_TURN);
+ RelayServerConfig turn_server;
turn_server.credentials = kRelayCredentials;
turn_server.ports.push_back(ProtocolAddress(kTurnTcpIntAddr, PROTO_TCP));
GetAllocator(0)->AddTurnServer(turn_server);
@@ -4757,7 +4756,7 @@ TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest,
TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest, TestTcpTurn) {
// Add a Tcp Turn server.
turn_server()->AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
- RelayServerConfig config(RELAY_TURN);
+ RelayServerConfig config;
config.credentials = kRelayCredentials;
config.ports.push_back(ProtocolAddress(kTurnTcpIntAddr, PROTO_TCP));
allocator()->AddTurnServer(config);
diff --git a/p2p/base/port.h b/p2p/base/port.h
index dde991aa98..5bd59d0e4d 100644
--- a/p2p/base/port.h
+++ b/p2p/base/port.h
@@ -57,11 +57,6 @@ extern const char TCPTYPE_ACTIVE_STR[];
extern const char TCPTYPE_PASSIVE_STR[];
extern const char TCPTYPE_SIMOPEN_STR[];
-enum RelayType {
- RELAY_GTURN, // Legacy google relay service.
- RELAY_TURN // Standard (TURN) relay service.
-};
-
enum IcePriorityValue {
ICE_TYPE_PREFERENCE_RELAY_TLS = 0,
ICE_TYPE_PREFERENCE_RELAY_TCP = 1,
diff --git a/p2p/base/port_allocator.cc b/p2p/base/port_allocator.cc
index b30416fdd3..b13896c4bc 100644
--- a/p2p/base/port_allocator.cc
+++ b/p2p/base/port_allocator.cc
@@ -20,13 +20,13 @@
namespace cricket {
-RelayServerConfig::RelayServerConfig(RelayType type) : type(type) {}
+RelayServerConfig::RelayServerConfig() {}
RelayServerConfig::RelayServerConfig(const rtc::SocketAddress& address,
const std::string& username,
const std::string& password,
ProtocolType proto)
- : type(RELAY_TURN), credentials(username, password) {
+ : credentials(username, password) {
ports.push_back(ProtocolAddress(address, proto));
}
diff --git a/p2p/base/port_allocator.h b/p2p/base/port_allocator.h
index eb04cc2a1f..2fe8db2c97 100644
--- a/p2p/base/port_allocator.h
+++ b/p2p/base/port_allocator.h
@@ -149,7 +149,7 @@ struct RelayCredentials {
typedef std::vector<ProtocolAddress> PortList;
// TODO(deadbeef): Rename to TurnServerConfig.
struct RTC_EXPORT RelayServerConfig {
- explicit RelayServerConfig(RelayType type);
+ RelayServerConfig();
RelayServerConfig(const rtc::SocketAddress& address,
const std::string& username,
const std::string& password,
@@ -170,12 +170,11 @@ struct RTC_EXPORT RelayServerConfig {
~RelayServerConfig();
bool operator==(const RelayServerConfig& o) const {
- return type == o.type && ports == o.ports && credentials == o.credentials &&
+ return 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 = 0;
diff --git a/p2p/base/port_unittest.cc b/p2p/base/port_unittest.cc
index 3556e3102a..4103ba41b3 100644
--- a/p2p/base/port_unittest.cc
+++ b/p2p/base/port_unittest.cc
@@ -27,12 +27,10 @@
#include "p2p/base/p2p_constants.h"
#include "p2p/base/port_allocator.h"
#include "p2p/base/port_interface.h"
-#include "p2p/base/relay_port.h"
#include "p2p/base/stun.h"
#include "p2p/base/stun_port.h"
#include "p2p/base/stun_server.h"
#include "p2p/base/tcp_port.h"
-#include "p2p/base/test_relay_server.h"
#include "p2p/base/test_stun_server.h"
#include "p2p/base/test_turn_server.h"
#include "p2p/base/transport_description.h"
@@ -90,12 +88,6 @@ const SocketAddress kLocalAddr2("192.168.1.3", 0);
const SocketAddress kNatAddr1("77.77.77.77", rtc::NAT_SERVER_UDP_PORT);
const SocketAddress kNatAddr2("88.88.88.88", rtc::NAT_SERVER_UDP_PORT);
const SocketAddress kStunAddr("99.99.99.1", STUN_SERVER_PORT);
-const SocketAddress kRelayUdpIntAddr("99.99.99.2", 5000);
-const SocketAddress kRelayUdpExtAddr("99.99.99.3", 5001);
-const SocketAddress kRelayTcpIntAddr("99.99.99.2", 5002);
-const SocketAddress kRelayTcpExtAddr("99.99.99.3", 5003);
-const SocketAddress kRelaySslTcpIntAddr("99.99.99.2", 5004);
-const SocketAddress kRelaySslTcpExtAddr("99.99.99.3", 5005);
const SocketAddress kTurnUdpIntAddr("99.99.99.4", STUN_SERVER_PORT);
const SocketAddress kTurnTcpIntAddr("99.99.99.4", 5010);
const SocketAddress kTurnUdpExtAddr("99.99.99.5", 0);
@@ -112,8 +104,6 @@ constexpr int kTiebreaker2 = 22222;
const char* data = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
-constexpr int kGturnUserNameLength = 16;
-
Candidate GetCandidate(Port* port) {
RTC_DCHECK_GE(port->Candidates().size(), 1);
return port->Candidates()[0];
@@ -410,13 +400,6 @@ class PortTest : public ::testing::Test, public sigslot::has_slots<> {
nat_socket_factory2_(&nat_factory2_),
stun_server_(TestStunServer::Create(&main_, kStunAddr)),
turn_server_(&main_, kTurnUdpIntAddr, kTurnUdpExtAddr),
- relay_server_(&main_,
- kRelayUdpIntAddr,
- kRelayUdpExtAddr,
- kRelayTcpIntAddr,
- kRelayTcpExtAddr,
- kRelaySslTcpIntAddr,
- kRelaySslTcpExtAddr),
username_(rtc::CreateRandomString(ICE_UFRAG_LENGTH)),
password_(rtc::CreateRandomString(ICE_PWD_LENGTH)),
role_conflict_(false),
@@ -441,13 +424,13 @@ class PortTest : public ::testing::Test, public sigslot::has_slots<> {
ntype == NAT_OPEN_CONE, true, ntype != NAT_SYMMETRIC,
true);
}
- void TestLocalToRelay(RelayType rtype, ProtocolType proto) {
+ void TestLocalToRelay(ProtocolType proto) {
auto port1 = CreateUdpPort(kLocalAddr1);
port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
- auto port2 = CreateRelayPort(kLocalAddr2, rtype, proto, PROTO_UDP);
+ auto port2 = CreateRelayPort(kLocalAddr2, proto, PROTO_UDP);
port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
- TestConnectivity("udp", std::move(port1), RelayName(rtype, proto),
- std::move(port2), rtype == RELAY_GTURN, true, true, true);
+ TestConnectivity("udp", std::move(port1), RelayName(proto),
+ std::move(port2), false, true, true, true);
}
void TestStunToLocal(NATType ntype) {
nat_server1_ = CreateNatServer(kNatAddr1, ntype);
@@ -470,15 +453,15 @@ class PortTest : public ::testing::Test, public sigslot::has_slots<> {
ntype1 != NAT_SYMMETRIC, ntype2 != NAT_SYMMETRIC,
ntype1 + ntype2 < (NAT_PORT_RESTRICTED + NAT_SYMMETRIC));
}
- void TestStunToRelay(NATType ntype, RelayType rtype, ProtocolType proto) {
+ void TestStunToRelay(NATType ntype, ProtocolType proto) {
nat_server1_ = CreateNatServer(kNatAddr1, ntype);
auto port1 = CreateStunPort(kLocalAddr1, &nat_socket_factory1_);
port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
- auto port2 = CreateRelayPort(kLocalAddr2, rtype, proto, PROTO_UDP);
+ auto port2 = CreateRelayPort(kLocalAddr2, proto, PROTO_UDP);
port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
- TestConnectivity(StunName(ntype), std::move(port1), RelayName(rtype, proto),
- std::move(port2), rtype == RELAY_GTURN,
- ntype != NAT_SYMMETRIC, true, true);
+ TestConnectivity(StunName(ntype), std::move(port1), RelayName(proto),
+ std::move(port2), false, ntype != NAT_SYMMETRIC, true,
+ true);
}
void TestTcpToTcp() {
auto port1 = CreateTcpPort(kLocalAddr1);
@@ -488,21 +471,21 @@ class PortTest : public ::testing::Test, public sigslot::has_slots<> {
TestConnectivity("tcp", std::move(port1), "tcp", std::move(port2), true,
false, true, true);
}
- void TestTcpToRelay(RelayType rtype, ProtocolType proto) {
+ void TestTcpToRelay(ProtocolType proto) {
auto port1 = CreateTcpPort(kLocalAddr1);
port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
- auto port2 = CreateRelayPort(kLocalAddr2, rtype, proto, PROTO_TCP);
+ auto port2 = CreateRelayPort(kLocalAddr2, proto, PROTO_TCP);
port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
- TestConnectivity("tcp", std::move(port1), RelayName(rtype, proto),
- std::move(port2), rtype == RELAY_GTURN, false, true, true);
+ TestConnectivity("tcp", std::move(port1), RelayName(proto),
+ std::move(port2), false, false, true, true);
}
- void TestSslTcpToRelay(RelayType rtype, ProtocolType proto) {
+ void TestSslTcpToRelay(ProtocolType proto) {
auto port1 = CreateTcpPort(kLocalAddr1);
port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
- auto port2 = CreateRelayPort(kLocalAddr2, rtype, proto, PROTO_SSLTCP);
+ auto port2 = CreateRelayPort(kLocalAddr2, proto, PROTO_SSLTCP);
port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
- TestConnectivity("ssltcp", std::move(port1), RelayName(rtype, proto),
- std::move(port2), rtype == RELAY_GTURN, false, true, true);
+ TestConnectivity("ssltcp", std::move(port1), RelayName(proto),
+ std::move(port2), false, false, true, true);
}
rtc::Network* MakeNetwork(const SocketAddress& addr) {
@@ -538,14 +521,9 @@ class PortTest : public ::testing::Test, public sigslot::has_slots<> {
absl::nullopt);
}
std::unique_ptr<Port> CreateRelayPort(const SocketAddress& addr,
- RelayType rtype,
ProtocolType int_proto,
ProtocolType ext_proto) {
- if (rtype == RELAY_TURN) {
- return CreateTurnPort(addr, &socket_factory_, int_proto, ext_proto);
- } else {
- return CreateGturnPort(addr, int_proto, ext_proto);
- }
+ return CreateTurnPort(addr, &socket_factory_, int_proto, ext_proto);
}
std::unique_ptr<TurnPort> CreateTurnPort(const SocketAddress& addr,
PacketSocketFactory* socket_factory,
@@ -567,24 +545,6 @@ class PortTest : public ::testing::Test, public sigslot::has_slots<> {
ProtocolAddress(server_addr, int_proto),
kRelayCredentials, 0, "", {}, {}, nullptr, nullptr);
}
- std::unique_ptr<RelayPort> CreateGturnPort(const SocketAddress& addr,
- ProtocolType int_proto,
- ProtocolType ext_proto) {
- std::unique_ptr<RelayPort> port = CreateGturnPort(addr);
- SocketAddress addrs[] = {kRelayUdpIntAddr, kRelayTcpIntAddr,
- kRelaySslTcpIntAddr};
- port->AddServerAddress(ProtocolAddress(addrs[int_proto], int_proto));
- return port;
- }
- std::unique_ptr<RelayPort> CreateGturnPort(const SocketAddress& addr) {
- // TODO(pthatcher): Remove GTURN.
- // Generate a username with length of 16 for Gturn only.
- std::string username = rtc::CreateRandomString(kGturnUserNameLength);
- return RelayPort::Create(&main_, &socket_factory_, MakeNetwork(addr), 0, 0,
- username, password_);
- // TODO(?): Add an external address for ext_proto, so that the
- // other side can connect to this port using a non-UDP protocol.
- }
std::unique_ptr<rtc::NATServer> CreateNatServer(const SocketAddress& addr,
rtc::NATType type) {
return std::make_unique<rtc::NATServer>(type, ss_.get(), addr, addr,
@@ -604,33 +564,18 @@ class PortTest : public ::testing::Test, public sigslot::has_slots<> {
return "stun(?)";
}
}
- static const char* RelayName(RelayType type, ProtocolType proto) {
- if (type == RELAY_TURN) {
- switch (proto) {
- case PROTO_UDP:
- return "turn(udp)";
- case PROTO_TCP:
- return "turn(tcp)";
- case PROTO_SSLTCP:
- return "turn(ssltcp)";
- case PROTO_TLS:
- return "turn(tls)";
- default:
- return "turn(?)";
- }
- } else {
- switch (proto) {
- case PROTO_UDP:
- return "gturn(udp)";
- case PROTO_TCP:
- return "gturn(tcp)";
- case PROTO_SSLTCP:
- return "gturn(ssltcp)";
- case PROTO_TLS:
- return "gturn(tls)";
- default:
- return "gturn(?)";
- }
+ static const char* RelayName(ProtocolType proto) {
+ switch (proto) {
+ case PROTO_UDP:
+ return "turn(udp)";
+ case PROTO_TCP:
+ return "turn(tcp)";
+ case PROTO_SSLTCP:
+ return "turn(ssltcp)";
+ case PROTO_TLS:
+ return "turn(tls)";
+ default:
+ return "turn(?)";
}
}
@@ -856,7 +801,6 @@ class PortTest : public ::testing::Test, public sigslot::has_slots<> {
rtc::BasicPacketSocketFactory nat_socket_factory2_;
std::unique_ptr<TestStunServer> stun_server_;
TestTurnServer turn_server_;
- TestRelayServer relay_server_;
std::string username_;
std::string password_;
bool role_conflict_;
@@ -1120,19 +1064,7 @@ TEST_F(PortTest, TestLocalToSymNat) {
// Flaky: https://code.google.com/p/webrtc/issues/detail?id=3316.
TEST_F(PortTest, DISABLED_TestLocalToTurn) {
- TestLocalToRelay(RELAY_TURN, PROTO_UDP);
-}
-
-TEST_F(PortTest, TestLocalToGturn) {
- TestLocalToRelay(RELAY_GTURN, PROTO_UDP);
-}
-
-TEST_F(PortTest, TestLocalToTcpGturn) {
- TestLocalToRelay(RELAY_GTURN, PROTO_TCP);
-}
-
-TEST_F(PortTest, TestLocalToSslTcpGturn) {
- TestLocalToRelay(RELAY_GTURN, PROTO_SSLTCP);
+ TestLocalToRelay(PROTO_UDP);
}
// Cone NAT -> XXXX
@@ -1157,15 +1089,7 @@ TEST_F(PortTest, TestConeNatToSymNat) {
}
TEST_F(PortTest, TestConeNatToTurn) {
- TestStunToRelay(NAT_OPEN_CONE, RELAY_TURN, PROTO_UDP);
-}
-
-TEST_F(PortTest, TestConeNatToGturn) {
- TestStunToRelay(NAT_OPEN_CONE, RELAY_GTURN, PROTO_UDP);
-}
-
-TEST_F(PortTest, TestConeNatToTcpGturn) {
- TestStunToRelay(NAT_OPEN_CONE, RELAY_GTURN, PROTO_TCP);
+ TestStunToRelay(NAT_OPEN_CONE, PROTO_UDP);
}
// Address-restricted NAT -> XXXX
@@ -1190,15 +1114,7 @@ TEST_F(PortTest, TestARNatToSymNat) {
}
TEST_F(PortTest, TestARNatToTurn) {
- TestStunToRelay(NAT_ADDR_RESTRICTED, RELAY_TURN, PROTO_UDP);
-}
-
-TEST_F(PortTest, TestARNatToGturn) {
- TestStunToRelay(NAT_ADDR_RESTRICTED, RELAY_GTURN, PROTO_UDP);
-}
-
-TEST_F(PortTest, TestARNATNatToTcpGturn) {
- TestStunToRelay(NAT_ADDR_RESTRICTED, RELAY_GTURN, PROTO_TCP);
+ TestStunToRelay(NAT_ADDR_RESTRICTED, PROTO_UDP);
}
// Port-restricted NAT -> XXXX
@@ -1224,15 +1140,7 @@ TEST_F(PortTest, TestPRNatToSymNat) {
}
TEST_F(PortTest, TestPRNatToTurn) {
- TestStunToRelay(NAT_PORT_RESTRICTED, RELAY_TURN, PROTO_UDP);
-}
-
-TEST_F(PortTest, TestPRNatToGturn) {
- TestStunToRelay(NAT_PORT_RESTRICTED, RELAY_GTURN, PROTO_UDP);
-}
-
-TEST_F(PortTest, TestPRNatToTcpGturn) {
- TestStunToRelay(NAT_PORT_RESTRICTED, RELAY_GTURN, PROTO_TCP);
+ TestStunToRelay(NAT_PORT_RESTRICTED, PROTO_UDP);
}
// Symmetric NAT -> XXXX
@@ -1259,15 +1167,7 @@ TEST_F(PortTest, TestSymNatToSymNat) {
}
TEST_F(PortTest, TestSymNatToTurn) {
- TestStunToRelay(NAT_SYMMETRIC, RELAY_TURN, PROTO_UDP);
-}
-
-TEST_F(PortTest, TestSymNatToGturn) {
- TestStunToRelay(NAT_SYMMETRIC, RELAY_GTURN, PROTO_UDP);
-}
-
-TEST_F(PortTest, TestSymNatToTcpGturn) {
- TestStunToRelay(NAT_SYMMETRIC, RELAY_GTURN, PROTO_TCP);
+ TestStunToRelay(NAT_SYMMETRIC, PROTO_UDP);
}
// Outbound TCP -> XXXX
@@ -2394,16 +2294,6 @@ TEST_F(PortTest, TestCandidateFoundation) {
stunport->Candidates()[0].foundation());
EXPECT_NE(udpport2->Candidates()[0].foundation(),
stunport->Candidates()[0].foundation());
- // Verify GTURN candidate foundation.
- auto relayport = CreateGturnPort(kLocalAddr1);
- relayport->AddServerAddress(
- cricket::ProtocolAddress(kRelayUdpIntAddr, cricket::PROTO_UDP));
- relayport->PrepareAddress();
- ASSERT_EQ_WAIT(1U, relayport->Candidates().size(), kDefaultTimeout);
- EXPECT_NE(udpport1->Candidates()[0].foundation(),
- relayport->Candidates()[0].foundation());
- EXPECT_NE(udpport2->Candidates()[0].foundation(),
- relayport->Candidates()[0].foundation());
// Verifying TURN candidate foundation.
auto turnport1 =
CreateTurnPort(kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP);
@@ -2465,16 +2355,6 @@ TEST_F(PortTest, TestCandidateRelatedAddress) {
// Check STUN candidate related address.
EXPECT_EQ(stunport->Candidates()[0].related_address(),
stunport->GetLocalAddress());
- // Verifying the related address for the GTURN candidates.
- // NOTE: In case of GTURN related address will be equal to the mapped
- // address, but address(mapped) will not be XOR.
- auto relayport = CreateGturnPort(kLocalAddr1);
- relayport->AddServerAddress(
- cricket::ProtocolAddress(kRelayUdpIntAddr, cricket::PROTO_UDP));
- relayport->PrepareAddress();
- ASSERT_EQ_WAIT(1U, relayport->Candidates().size(), kDefaultTimeout);
- // For Gturn related address is set to "0.0.0.0:0"
- EXPECT_EQ(rtc::SocketAddress(), relayport->Candidates()[0].related_address());
// Verifying the related address for TURN candidate.
// For TURN related address must be equal to the mapped address.
auto turnport =
diff --git a/p2p/base/regathering_controller_unittest.cc b/p2p/base/regathering_controller_unittest.cc
index cee4a67b0a..e9da576667 100644
--- a/p2p/base/regathering_controller_unittest.cc
+++ b/p2p/base/regathering_controller_unittest.cc
@@ -63,7 +63,7 @@ class RegatheringControllerTest : public ::testing::Test,
void InitializeAndGatherOnce() {
cricket::ServerAddresses stun_servers;
stun_servers.insert(kStunAddr);
- cricket::RelayServerConfig turn_server(cricket::RELAY_TURN);
+ cricket::RelayServerConfig turn_server;
turn_server.credentials = kRelayCredentials;
turn_server.ports.push_back(
cricket::ProtocolAddress(kTurnUdpIntAddr, cricket::PROTO_UDP));
diff --git a/p2p/base/relay_port.cc b/p2p/base/relay_port.cc
deleted file mode 100644
index 808d6cec75..0000000000
--- a/p2p/base/relay_port.cc
+++ /dev/null
@@ -1,860 +0,0 @@
-/*
- * Copyright 2004 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 "p2p/base/relay_port.h"
-
-#include <errno.h>
-#include <string.h>
-
-#include <algorithm>
-
-#include "p2p/base/connection.h"
-#include "p2p/base/stun.h"
-#include "p2p/base/stun_request.h"
-#include "rtc_base/async_packet_socket.h"
-#include "rtc_base/byte_buffer.h"
-#include "rtc_base/checks.h"
-#include "rtc_base/dscp.h"
-#include "rtc_base/location.h"
-#include "rtc_base/logging.h"
-#include "rtc_base/message_handler.h"
-#include "rtc_base/message_queue.h"
-#include "rtc_base/net_helper.h"
-#include "rtc_base/proxy_info.h"
-#include "rtc_base/time_utils.h"
-
-namespace cricket {
-
-static const int kMessageConnectTimeout = 1;
-static const int kKeepAliveDelay = 10 * 60 * 1000;
-static const int kRetryTimeout = 50 * 1000; // ICE says 50 secs
-// How long to wait for a socket to connect to remote host in milliseconds
-// before trying another connection.
-static const int kSoftConnectTimeoutMs = 3 * 1000;
-
-// Handles a connection to one address/port/protocol combination for a
-// particular RelayEntry.
-class RelayConnection : public sigslot::has_slots<> {
- public:
- RelayConnection(const ProtocolAddress* protocol_address,
- rtc::AsyncPacketSocket* socket,
- rtc::Thread* thread);
- ~RelayConnection() override;
- rtc::AsyncPacketSocket* socket() const { return socket_; }
-
- const ProtocolAddress* protocol_address() { return protocol_address_; }
-
- rtc::SocketAddress GetAddress() const { return protocol_address_->address; }
-
- ProtocolType GetProtocol() const { return protocol_address_->proto; }
-
- int SetSocketOption(rtc::Socket::Option opt, int value);
-
- // Validates a response to a STUN allocate request.
- bool CheckResponse(StunMessage* msg);
-
- // Sends data to the relay server.
- int Send(const void* pv, size_t cb, const rtc::PacketOptions& options);
-
- // Sends a STUN allocate request message to the relay server.
- void SendAllocateRequest(RelayEntry* entry, int delay);
-
- // Return the latest error generated by the socket.
- int GetError() { return socket_->GetError(); }
-
- // Called on behalf of a StunRequest to write data to the socket. This is
- // already STUN intended for the server, so no wrapping is necessary.
- void OnSendPacket(const void* data, size_t size, StunRequest* req);
-
- private:
- rtc::AsyncPacketSocket* socket_;
- const ProtocolAddress* protocol_address_;
- StunRequestManager* request_manager_;
- rtc::DiffServCodePoint dscp_;
-};
-
-// Manages a number of connections to the relayserver, one for each
-// available protocol. We aim to use each connection for only a
-// specific destination address so that we can avoid wrapping every
-// packet in a STUN send / data indication.
-class RelayEntry : public rtc::MessageHandler, public sigslot::has_slots<> {
- public:
- RelayEntry(RelayPort* port, const rtc::SocketAddress& ext_addr);
- ~RelayEntry() override;
-
- RelayPort* port() { return port_; }
-
- const rtc::SocketAddress& address() const { return ext_addr_; }
- void set_address(const rtc::SocketAddress& addr) { ext_addr_ = addr; }
-
- bool connected() const { return connected_; }
- bool locked() const { return locked_; }
-
- // Returns the last error on the socket of this entry.
- int GetError();
-
- // Returns the most preferred connection of the given
- // ones. Connections are rated based on protocol in the order of:
- // UDP, TCP and SSLTCP, where UDP is the most preferred protocol
- static RelayConnection* GetBestConnection(RelayConnection* conn1,
- RelayConnection* conn2);
-
- // Sends the STUN requests to the server to initiate this connection.
- void Connect();
-
- // Called when this entry becomes connected. The address given is the one
- // exposed to the outside world on the relay server.
- void OnConnect(const rtc::SocketAddress& mapped_addr,
- RelayConnection* socket);
-
- // Sends a packet to the given destination address using the socket of this
- // entry. This will wrap the packet in STUN if necessary.
- int SendTo(const void* data,
- size_t size,
- const rtc::SocketAddress& addr,
- const rtc::PacketOptions& options);
-
- // Schedules a keep-alive allocate request.
- void ScheduleKeepAlive();
-
- void SetServerIndex(size_t sindex) { server_index_ = sindex; }
-
- // Sets this option on the socket of each connection.
- int SetSocketOption(rtc::Socket::Option opt, int value);
-
- size_t ServerIndex() const { return server_index_; }
-
- // Try a different server address
- void HandleConnectFailure(rtc::AsyncPacketSocket* socket);
-
- // Implementation of the MessageHandler Interface.
- void OnMessage(rtc::Message* pmsg) override;
-
- private:
- RelayPort* port_;
- rtc::SocketAddress ext_addr_;
- size_t server_index_;
- bool connected_;
- bool locked_;
- RelayConnection* current_connection_;
-
- // Called when a TCP connection is established or fails
- void OnSocketConnect(rtc::AsyncPacketSocket* socket);
- void OnSocketClose(rtc::AsyncPacketSocket* socket, int error);
-
- // Called when a packet is received on this socket.
- void OnReadPacket(rtc::AsyncPacketSocket* socket,
- const char* data,
- size_t size,
- const rtc::SocketAddress& remote_addr,
- const int64_t& packet_time_us);
-
- void OnSentPacket(rtc::AsyncPacketSocket* socket,
- const rtc::SentPacket& sent_packet);
-
- // Called when the socket is currently able to send.
- void OnReadyToSend(rtc::AsyncPacketSocket* socket);
-
- // Sends the given data on the socket to the server with no wrapping. This
- // returns the number of bytes written or -1 if an error occurred.
- int SendPacket(const void* data,
- size_t size,
- const rtc::PacketOptions& options);
-};
-
-// Handles an allocate request for a particular RelayEntry.
-class AllocateRequest : public StunRequest {
- public:
- AllocateRequest(RelayEntry* entry, RelayConnection* connection);
- ~AllocateRequest() override = default;
-
- void Prepare(StunMessage* request) override;
-
- void OnSent() override;
- int resend_delay() override;
-
- void OnResponse(StunMessage* response) override;
- void OnErrorResponse(StunMessage* response) override;
- void OnTimeout() override;
-
- private:
- RelayEntry* entry_;
- RelayConnection* connection_;
- int64_t start_time_;
-};
-
-RelayPort::RelayPort(rtc::Thread* thread,
- rtc::PacketSocketFactory* factory,
- rtc::Network* network,
- uint16_t min_port,
- uint16_t max_port,
- const std::string& username,
- const std::string& password)
- : Port(thread,
- RELAY_PORT_TYPE,
- factory,
- network,
- min_port,
- max_port,
- username,
- password),
- ready_(false),
- error_(0) {
- entries_.push_back(new RelayEntry(this, rtc::SocketAddress()));
- // TODO(?): set local preference value for TCP based candidates.
-}
-
-RelayPort::~RelayPort() {
- for (size_t i = 0; i < entries_.size(); ++i)
- delete entries_[i];
- thread()->Clear(this);
-}
-
-void RelayPort::AddServerAddress(const ProtocolAddress& addr) {
- // Since HTTP proxies usually only allow 443,
- // let's up the priority on PROTO_SSLTCP
- if (addr.proto == PROTO_SSLTCP && (proxy().type == rtc::PROXY_HTTPS ||
- proxy().type == rtc::PROXY_UNKNOWN)) {
- server_addr_.push_front(addr);
- } else {
- server_addr_.push_back(addr);
- }
-}
-
-void RelayPort::AddExternalAddress(const ProtocolAddress& addr) {
- std::string proto_name = ProtoToString(addr.proto);
- for (std::vector<ProtocolAddress>::iterator it = external_addr_.begin();
- it != external_addr_.end(); ++it) {
- if ((it->address == addr.address) && (it->proto == addr.proto)) {
- RTC_LOG(INFO) << "Redundant relay address: " << proto_name << " @ "
- << addr.address.ToSensitiveString();
- return;
- }
- }
- external_addr_.push_back(addr);
-}
-
-void RelayPort::SetReady() {
- if (!ready_) {
- std::vector<ProtocolAddress>::iterator iter;
- for (iter = external_addr_.begin(); iter != external_addr_.end(); ++iter) {
- std::string proto_name = ProtoToString(iter->proto);
- // In case of Gturn, related address is set to null socket address.
- // This is due to as mapped address stun attribute is used for allocated
- // address.
- AddAddress(iter->address, iter->address, rtc::SocketAddress(), proto_name,
- proto_name, "", RELAY_PORT_TYPE, ICE_TYPE_PREFERENCE_RELAY_UDP,
- 0, "", false);
- }
- ready_ = true;
- SignalPortComplete(this);
- }
-}
-
-const ProtocolAddress* RelayPort::ServerAddress(size_t index) const {
- if (index < server_addr_.size())
- return &server_addr_[index];
- return NULL;
-}
-
-bool RelayPort::HasMagicCookie(const char* data, size_t size) {
- if (size < 24 + sizeof(TURN_MAGIC_COOKIE_VALUE)) {
- return false;
- } else {
- return memcmp(data + 24, TURN_MAGIC_COOKIE_VALUE,
- sizeof(TURN_MAGIC_COOKIE_VALUE)) == 0;
- }
-}
-
-void RelayPort::PrepareAddress() {
- // We initiate a connect on the first entry. If this completes, it will fill
- // in the server address as the address of this port.
- RTC_DCHECK(entries_.size() == 1);
- entries_[0]->Connect();
- ready_ = false;
-}
-
-Connection* RelayPort::CreateConnection(const Candidate& address,
- CandidateOrigin origin) {
- // We only create conns to non-udp sockets if they are incoming on this port
- if ((address.protocol() != UDP_PROTOCOL_NAME) &&
- (origin != ORIGIN_THIS_PORT)) {
- return 0;
- }
-
- // We don't support loopback on relays
- if (address.type() == Type()) {
- return 0;
- }
-
- if (!IsCompatibleAddress(address.address())) {
- return 0;
- }
-
- size_t index = 0;
- for (size_t i = 0; i < Candidates().size(); ++i) {
- const Candidate& local = Candidates()[i];
- if (local.protocol() == address.protocol()) {
- index = i;
- break;
- }
- }
-
- Connection* conn = new ProxyConnection(this, index, address);
- AddOrReplaceConnection(conn);
- return conn;
-}
-
-int RelayPort::SendTo(const void* data,
- size_t size,
- const rtc::SocketAddress& addr,
- const rtc::PacketOptions& options,
- bool payload) {
- // Try to find an entry for this specific address. Note that the first entry
- // created was not given an address initially, so it can be set to the first
- // address that comes along.
- RelayEntry* entry = 0;
-
- for (size_t i = 0; i < entries_.size(); ++i) {
- if (entries_[i]->address().IsNil() && payload) {
- entry = entries_[i];
- entry->set_address(addr);
- break;
- } else if (entries_[i]->address() == addr) {
- entry = entries_[i];
- break;
- }
- }
-
- // If we did not find one, then we make a new one. This will not be useable
- // until it becomes connected, however.
- if (!entry && payload) {
- entry = new RelayEntry(this, addr);
- if (!entries_.empty()) {
- entry->SetServerIndex(entries_[0]->ServerIndex());
- }
- entry->Connect();
- entries_.push_back(entry);
- }
-
- // If the entry is connected, then we can send on it (though wrapping may
- // still be necessary). Otherwise, we can't yet use this connection, so we
- // default to the first one.
- if (!entry || !entry->connected()) {
- RTC_DCHECK(!entries_.empty());
- entry = entries_[0];
- if (!entry->connected()) {
- error_ = ENOTCONN;
- return SOCKET_ERROR;
- }
- }
-
- // Send the actual contents to the server using the usual mechanism.
- rtc::PacketOptions modified_options(options);
- CopyPortInformationToPacketInfo(&modified_options.info_signaled_after_sent);
- int sent = entry->SendTo(data, size, addr, modified_options);
- if (sent <= 0) {
- RTC_DCHECK(sent < 0);
- error_ = entry->GetError();
- return SOCKET_ERROR;
- }
- // The caller of the function is expecting the number of user data bytes,
- // rather than the size of the packet.
- return static_cast<int>(size);
-}
-
-int RelayPort::SetOption(rtc::Socket::Option opt, int value) {
- int result = 0;
- for (size_t i = 0; i < entries_.size(); ++i) {
- if (entries_[i]->SetSocketOption(opt, value) < 0) {
- result = -1;
- error_ = entries_[i]->GetError();
- }
- }
- options_.push_back(OptionValue(opt, value));
- return result;
-}
-
-int RelayPort::GetOption(rtc::Socket::Option opt, int* value) {
- std::vector<OptionValue>::iterator it;
- for (it = options_.begin(); it < options_.end(); ++it) {
- if (it->first == opt) {
- *value = it->second;
- return 0;
- }
- }
- return SOCKET_ERROR;
-}
-
-int RelayPort::GetError() {
- return error_;
-}
-
-bool RelayPort::SupportsProtocol(const std::string& protocol) const {
- // Relay port may create both TCP and UDP connections.
- return true;
-}
-
-ProtocolType RelayPort::GetProtocol() const {
- // We shouldn't be using RelayPort, but we need to provide an implementation
- // here.
- return PROTO_UDP;
-}
-
-void RelayPort::OnReadPacket(const char* data,
- size_t size,
- const rtc::SocketAddress& remote_addr,
- ProtocolType proto,
- int64_t packet_time_us) {
- if (Connection* conn = GetConnection(remote_addr)) {
- conn->OnReadPacket(data, size, packet_time_us);
- } else {
- Port::OnReadPacket(data, size, remote_addr, proto);
- }
-}
-
-RelayConnection::RelayConnection(const ProtocolAddress* protocol_address,
- rtc::AsyncPacketSocket* socket,
- rtc::Thread* thread)
- : socket_(socket),
- protocol_address_(protocol_address),
- dscp_(rtc::DSCP_NO_CHANGE) {
- request_manager_ = new StunRequestManager(thread);
- request_manager_->SignalSendPacket.connect(this,
- &RelayConnection::OnSendPacket);
-}
-
-RelayConnection::~RelayConnection() {
- delete request_manager_;
- delete socket_;
-}
-
-int RelayConnection::SetSocketOption(rtc::Socket::Option opt, int value) {
- if (opt == rtc::Socket::OPT_DSCP) {
- dscp_ = static_cast<rtc::DiffServCodePoint>(value);
- }
- if (socket_) {
- return socket_->SetOption(opt, value);
- }
- return 0;
-}
-
-bool RelayConnection::CheckResponse(StunMessage* msg) {
- return request_manager_->CheckResponse(msg);
-}
-
-void RelayConnection::OnSendPacket(const void* data,
- size_t size,
- StunRequest* req) {
- rtc::PacketOptions options(dscp_);
- int sent = socket_->SendTo(data, size, GetAddress(), options);
- if (sent <= 0) {
- RTC_LOG(LS_VERBOSE) << "OnSendPacket: failed sending to "
- << GetAddress().ToSensitiveString()
- << strerror(socket_->GetError());
- RTC_DCHECK(sent < 0);
- }
-}
-
-int RelayConnection::Send(const void* pv,
- size_t cb,
- const rtc::PacketOptions& options) {
- return socket_->SendTo(pv, cb, GetAddress(), options);
-}
-
-void RelayConnection::SendAllocateRequest(RelayEntry* entry, int delay) {
- request_manager_->SendDelayed(new AllocateRequest(entry, this), delay);
-}
-
-RelayEntry::RelayEntry(RelayPort* port, const rtc::SocketAddress& ext_addr)
- : port_(port),
- ext_addr_(ext_addr),
- server_index_(0),
- connected_(false),
- locked_(false),
- current_connection_(NULL) {}
-
-RelayEntry::~RelayEntry() {
- // Remove all RelayConnections and dispose sockets.
- delete current_connection_;
- current_connection_ = NULL;
-}
-
-void RelayEntry::Connect() {
- // If we're already connected, return.
- if (connected_)
- return;
-
- // If we've exhausted all options, bail out.
- const ProtocolAddress* ra = port()->ServerAddress(server_index_);
- if (!ra) {
- RTC_LOG(LS_WARNING) << "No more relay addresses left to try";
- return;
- }
-
- // Remove any previous connection.
- if (current_connection_) {
- port()->thread()->Dispose(current_connection_);
- current_connection_ = NULL;
- }
-
- // Try to set up our new socket.
- RTC_LOG(LS_INFO) << "Connecting to relay via " << ProtoToString(ra->proto)
- << " @ " << ra->address.ToSensitiveString();
-
- rtc::AsyncPacketSocket* socket = NULL;
-
- if (ra->proto == PROTO_UDP) {
- // UDP sockets are simple.
- socket = port_->socket_factory()->CreateUdpSocket(
- rtc::SocketAddress(port_->Network()->GetBestIP(), 0), port_->min_port(),
- port_->max_port());
- } else if (ra->proto == PROTO_TCP || ra->proto == PROTO_SSLTCP) {
- int opts = (ra->proto == PROTO_SSLTCP)
- ? rtc::PacketSocketFactory::OPT_TLS_FAKE
- : 0;
- rtc::PacketSocketTcpOptions tcp_opts;
- tcp_opts.opts = opts;
- socket = port_->socket_factory()->CreateClientTcpSocket(
- rtc::SocketAddress(port_->Network()->GetBestIP(), 0), ra->address,
- port_->proxy(), port_->user_agent(), tcp_opts);
- } else {
- RTC_LOG(LS_WARNING) << "Unknown protocol: " << ra->proto;
- }
-
- // If we failed to get a socket, move on to the next protocol.
- if (!socket) {
- RTC_LOG(LS_WARNING) << "Socket creation failed";
- port()->thread()->Post(RTC_FROM_HERE, this, kMessageConnectTimeout);
- return;
- }
-
- // Otherwise, create the new connection and configure any socket options.
- socket->SignalReadPacket.connect(this, &RelayEntry::OnReadPacket);
- socket->SignalSentPacket.connect(this, &RelayEntry::OnSentPacket);
- socket->SignalReadyToSend.connect(this, &RelayEntry::OnReadyToSend);
- current_connection_ = new RelayConnection(ra, socket, port()->thread());
- for (size_t i = 0; i < port_->options().size(); ++i) {
- current_connection_->SetSocketOption(port_->options()[i].first,
- port_->options()[i].second);
- }
-
- // If we're trying UDP, start binding requests.
- // If we're trying TCP, wait for connection with a fixed timeout.
- if ((ra->proto == PROTO_TCP) || (ra->proto == PROTO_SSLTCP)) {
- socket->SignalClose.connect(this, &RelayEntry::OnSocketClose);
- socket->SignalConnect.connect(this, &RelayEntry::OnSocketConnect);
- port()->thread()->PostDelayed(RTC_FROM_HERE, kSoftConnectTimeoutMs, this,
- kMessageConnectTimeout);
- } else {
- current_connection_->SendAllocateRequest(this, 0);
- }
-}
-
-int RelayEntry::GetError() {
- if (current_connection_ != NULL) {
- return current_connection_->GetError();
- }
- return 0;
-}
-
-RelayConnection* RelayEntry::GetBestConnection(RelayConnection* conn1,
- RelayConnection* conn2) {
- return conn1->GetProtocol() <= conn2->GetProtocol() ? conn1 : conn2;
-}
-
-void RelayEntry::OnConnect(const rtc::SocketAddress& mapped_addr,
- RelayConnection* connection) {
- // We are connected, notify our parent.
- ProtocolType proto = PROTO_UDP;
- RTC_LOG(INFO) << "Relay allocate succeeded: " << ProtoToString(proto) << " @ "
- << mapped_addr.ToSensitiveString();
- connected_ = true;
-
- port_->AddExternalAddress(ProtocolAddress(mapped_addr, proto));
- port_->SetReady();
-}
-
-int RelayEntry::SendTo(const void* data,
- size_t size,
- const rtc::SocketAddress& addr,
- const rtc::PacketOptions& options) {
- // If this connection is locked to the address given, then we can send the
- // packet with no wrapper.
- if (locked_ && (ext_addr_ == addr))
- return SendPacket(data, size, options);
-
- // Otherwise, we must wrap the given data in a STUN SEND request so that we
- // can communicate the destination address to the server.
- //
- // Note that we do not use a StunRequest here. This is because there is
- // likely no reason to resend this packet. If it is late, we just drop it.
- // The next send to this address will try again.
-
- RelayMessage request;
- request.SetType(STUN_SEND_REQUEST);
-
- auto magic_cookie_attr =
- StunAttribute::CreateByteString(STUN_ATTR_MAGIC_COOKIE);
- magic_cookie_attr->CopyBytes(TURN_MAGIC_COOKIE_VALUE,
- sizeof(TURN_MAGIC_COOKIE_VALUE));
- request.AddAttribute(std::move(magic_cookie_attr));
-
- auto username_attr = StunAttribute::CreateByteString(STUN_ATTR_USERNAME);
- username_attr->CopyBytes(port_->username_fragment().c_str(),
- port_->username_fragment().size());
- request.AddAttribute(std::move(username_attr));
-
- auto addr_attr = StunAttribute::CreateAddress(STUN_ATTR_DESTINATION_ADDRESS);
- addr_attr->SetIP(addr.ipaddr());
- addr_attr->SetPort(addr.port());
- request.AddAttribute(std::move(addr_attr));
-
- // Attempt to lock
- if (ext_addr_ == addr) {
- auto options_attr = StunAttribute::CreateUInt32(STUN_ATTR_OPTIONS);
- options_attr->SetValue(0x1);
- request.AddAttribute(std::move(options_attr));
- }
-
- auto data_attr = StunAttribute::CreateByteString(STUN_ATTR_DATA);
- data_attr->CopyBytes(data, size);
- request.AddAttribute(std::move(data_attr));
-
- // TODO(?): compute the HMAC.
-
- rtc::ByteBufferWriter buf;
- request.Write(&buf);
-
- return SendPacket(buf.Data(), buf.Length(), options);
-}
-
-void RelayEntry::ScheduleKeepAlive() {
- if (current_connection_) {
- current_connection_->SendAllocateRequest(this, kKeepAliveDelay);
- }
-}
-
-int RelayEntry::SetSocketOption(rtc::Socket::Option opt, int value) {
- // Set the option on all available sockets.
- int socket_error = 0;
- if (current_connection_) {
- socket_error = current_connection_->SetSocketOption(opt, value);
- }
- return socket_error;
-}
-
-void RelayEntry::HandleConnectFailure(rtc::AsyncPacketSocket* socket) {
- // Make sure it's the current connection that has failed, it might
- // be an old socked that has not yet been disposed.
- if (!socket ||
- (current_connection_ && socket == current_connection_->socket())) {
- if (current_connection_)
- port()->SignalConnectFailure(current_connection_->protocol_address());
-
- // Try to connect to the next server address.
- server_index_ += 1;
- Connect();
- }
-}
-
-void RelayEntry::OnMessage(rtc::Message* pmsg) {
- RTC_DCHECK(pmsg->message_id == kMessageConnectTimeout);
- if (current_connection_) {
- const ProtocolAddress* ra = current_connection_->protocol_address();
- RTC_LOG(LS_WARNING) << "Relay " << ra->proto << " connection to "
- << ra->address.ToSensitiveString() << " timed out";
-
- // Currently we connect to each server address in sequence. If we
- // have more addresses to try, treat this is an error and move on to
- // the next address, otherwise give this connection more time and
- // await the real timeout.
- //
- // TODO(?): Connect to servers in parallel to speed up connect time
- // and to avoid giving up too early.
- port_->SignalSoftTimeout(ra);
- HandleConnectFailure(current_connection_->socket());
- } else {
- HandleConnectFailure(NULL);
- }
-}
-
-void RelayEntry::OnSocketConnect(rtc::AsyncPacketSocket* socket) {
- RTC_LOG(INFO) << "relay tcp connected to "
- << socket->GetRemoteAddress().ToSensitiveString();
- if (current_connection_ != NULL) {
- current_connection_->SendAllocateRequest(this, 0);
- }
-}
-
-void RelayEntry::OnSocketClose(rtc::AsyncPacketSocket* socket, int error) {
- RTC_LOG_ERR_EX(LERROR, error) << "Relay connection failed: socket closed";
- HandleConnectFailure(socket);
-}
-
-void RelayEntry::OnReadPacket(rtc::AsyncPacketSocket* socket,
- const char* data,
- size_t size,
- const rtc::SocketAddress& remote_addr,
- const int64_t& packet_time_us) {
- // RTC_DCHECK(remote_addr == port_->server_addr());
- // TODO(?): are we worried about this?
-
- if (current_connection_ == NULL || socket != current_connection_->socket()) {
- // This packet comes from an unknown address.
- RTC_LOG(WARNING) << "Dropping packet: unknown address";
- return;
- }
-
- // If the magic cookie is not present, then this is an unwrapped packet sent
- // by the server, The actual remote address is the one we recorded.
- if (!port_->HasMagicCookie(data, size)) {
- if (locked_) {
- port_->OnReadPacket(data, size, ext_addr_, PROTO_UDP, packet_time_us);
- } else {
- RTC_LOG(WARNING) << "Dropping packet: entry not locked";
- }
- return;
- }
-
- rtc::ByteBufferReader buf(data, size);
- RelayMessage msg;
- if (!msg.Read(&buf)) {
- RTC_LOG(INFO) << "Incoming packet was not STUN";
- return;
- }
-
- // The incoming packet should be a STUN ALLOCATE response, SEND response, or
- // DATA indication.
- if (current_connection_->CheckResponse(&msg)) {
- return;
- } else if (msg.type() == STUN_SEND_RESPONSE) {
- if (const StunUInt32Attribute* options_attr =
- msg.GetUInt32(STUN_ATTR_OPTIONS)) {
- if (options_attr->value() & 0x1) {
- locked_ = true;
- }
- }
- return;
- } else if (msg.type() != STUN_DATA_INDICATION) {
- RTC_LOG(INFO) << "Received BAD stun type from server: " << msg.type();
- return;
- }
-
- // This must be a data indication.
-
- const StunAddressAttribute* addr_attr =
- msg.GetAddress(STUN_ATTR_SOURCE_ADDRESS2);
- if (!addr_attr) {
- RTC_LOG(INFO) << "Data indication has no source address";
- return;
- } else if (addr_attr->family() != 1) {
- RTC_LOG(INFO) << "Source address has bad family";
- return;
- }
-
- rtc::SocketAddress remote_addr2(addr_attr->ipaddr(), addr_attr->port());
-
- const StunByteStringAttribute* data_attr = msg.GetByteString(STUN_ATTR_DATA);
- if (!data_attr) {
- RTC_LOG(INFO) << "Data indication has no data";
- return;
- }
-
- // Process the actual data and remote address in the normal manner.
- port_->OnReadPacket(data_attr->bytes(), data_attr->length(), remote_addr2,
- PROTO_UDP, packet_time_us);
-}
-
-void RelayEntry::OnSentPacket(rtc::AsyncPacketSocket* socket,
- const rtc::SentPacket& sent_packet) {
- port_->OnSentPacket(socket, sent_packet);
-}
-
-void RelayEntry::OnReadyToSend(rtc::AsyncPacketSocket* socket) {
- if (connected()) {
- port_->OnReadyToSend();
- }
-}
-
-int RelayEntry::SendPacket(const void* data,
- size_t size,
- const rtc::PacketOptions& options) {
- int sent = 0;
- if (current_connection_) {
- // We are connected, no need to send packets anywere else than to
- // the current connection.
- sent = current_connection_->Send(data, size, options);
- }
- return sent;
-}
-
-AllocateRequest::AllocateRequest(RelayEntry* entry, RelayConnection* connection)
- : StunRequest(new RelayMessage()), entry_(entry), connection_(connection) {
- start_time_ = rtc::TimeMillis();
-}
-
-void AllocateRequest::Prepare(StunMessage* request) {
- request->SetType(STUN_ALLOCATE_REQUEST);
-
- auto username_attr = StunAttribute::CreateByteString(STUN_ATTR_USERNAME);
- username_attr->CopyBytes(entry_->port()->username_fragment().c_str(),
- entry_->port()->username_fragment().size());
- request->AddAttribute(std::move(username_attr));
-}
-
-void AllocateRequest::OnSent() {
- count_ += 1;
- if (count_ == 5)
- timeout_ = true;
-}
-
-int AllocateRequest::resend_delay() {
- if (count_ == 0) {
- return 0;
- }
- return 100 * std::max(1 << (count_ - 1), 2);
-}
-
-void AllocateRequest::OnResponse(StunMessage* response) {
- const StunAddressAttribute* addr_attr =
- response->GetAddress(STUN_ATTR_MAPPED_ADDRESS);
- if (!addr_attr) {
- RTC_LOG(INFO) << "Allocate response missing mapped address.";
- } else if (addr_attr->family() != 1) {
- RTC_LOG(INFO) << "Mapped address has bad family";
- } else {
- rtc::SocketAddress addr(addr_attr->ipaddr(), addr_attr->port());
- entry_->OnConnect(addr, connection_);
- }
-
- // We will do a keep-alive regardless of whether this request suceeds.
- // This should have almost no impact on network usage.
- entry_->ScheduleKeepAlive();
-}
-
-void AllocateRequest::OnErrorResponse(StunMessage* response) {
- const StunErrorCodeAttribute* attr = response->GetErrorCode();
- if (!attr) {
- RTC_LOG(LS_ERROR) << "Missing allocate response error code.";
- } else {
- RTC_LOG(INFO) << "Allocate error response: code=" << attr->code()
- << " reason=" << attr->reason();
- }
-
- if (rtc::TimeMillis() - start_time_ <= kRetryTimeout)
- entry_->ScheduleKeepAlive();
-}
-
-void AllocateRequest::OnTimeout() {
- RTC_LOG(INFO) << "Allocate request timed out";
- entry_->HandleConnectFailure(connection_->socket());
-}
-
-} // namespace cricket
diff --git a/p2p/base/relay_port.h b/p2p/base/relay_port.h
deleted file mode 100644
index f9121ad1d4..0000000000
--- a/p2p/base/relay_port.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright 2004 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.
- */
-
-#ifndef P2P_BASE_RELAY_PORT_H_
-#define P2P_BASE_RELAY_PORT_H_
-
-#include <deque>
-#include <memory>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "absl/memory/memory.h"
-#include "p2p/base/port.h"
-#include "p2p/base/stun_request.h"
-
-namespace cricket {
-
-class RelayEntry;
-class RelayConnection;
-
-// Communicates using an allocated port on the relay server. For each
-// remote candidate that we try to send data to a RelayEntry instance
-// is created. The RelayEntry will try to reach the remote destination
-// by connecting to all available server addresses in a pre defined
-// order with a small delay in between. When a connection is
-// successful all other connection attempts are aborted.
-class RelayPort : public Port {
- public:
- typedef std::pair<rtc::Socket::Option, int> OptionValue;
-
- // RelayPort doesn't yet do anything fancy in the ctor.
- static std::unique_ptr<RelayPort> Create(rtc::Thread* thread,
- rtc::PacketSocketFactory* factory,
- rtc::Network* network,
- uint16_t min_port,
- uint16_t max_port,
- const std::string& username,
- const std::string& password) {
- // Using `new` to access a non-public constructor.
- return absl::WrapUnique(new RelayPort(thread, factory, network, min_port,
- max_port, username, password));
- }
- ~RelayPort() override;
-
- void AddServerAddress(const ProtocolAddress& addr);
- void AddExternalAddress(const ProtocolAddress& addr);
-
- const std::vector<OptionValue>& options() const { return options_; }
- bool HasMagicCookie(const char* data, size_t size);
-
- void PrepareAddress() override;
- Connection* CreateConnection(const Candidate& address,
- CandidateOrigin origin) override;
- int SetOption(rtc::Socket::Option opt, int value) override;
- int GetOption(rtc::Socket::Option opt, int* value) override;
- int GetError() override;
- bool SupportsProtocol(const std::string& protocol) const override;
- ProtocolType GetProtocol() const override;
-
- const ProtocolAddress* ServerAddress(size_t index) const;
- bool IsReady() { return ready_; }
-
- // Used for testing.
- sigslot::signal1<const ProtocolAddress*> SignalConnectFailure;
- sigslot::signal1<const ProtocolAddress*> SignalSoftTimeout;
-
- protected:
- RelayPort(rtc::Thread* thread,
- rtc::PacketSocketFactory* factory,
- rtc::Network*,
- uint16_t min_port,
- uint16_t max_port,
- const std::string& username,
- const std::string& password);
- bool Init();
-
- void SetReady();
-
- int SendTo(const void* data,
- size_t size,
- const rtc::SocketAddress& addr,
- const rtc::PacketOptions& options,
- bool payload) override;
-
- // Dispatches the given packet to the port or connection as appropriate.
- void OnReadPacket(const char* data,
- size_t size,
- const rtc::SocketAddress& remote_addr,
- ProtocolType proto,
- int64_t packet_time_us);
-
- // The OnSentPacket callback is left empty here since they are handled by
- // RelayEntry.
- void OnSentPacket(rtc::AsyncPacketSocket* socket,
- const rtc::SentPacket& sent_packet) override {}
-
- private:
- friend class RelayEntry;
-
- std::deque<ProtocolAddress> server_addr_;
- std::vector<ProtocolAddress> external_addr_;
- bool ready_;
- std::vector<RelayEntry*> entries_;
- std::vector<OptionValue> options_;
- int error_;
-};
-
-} // namespace cricket
-
-#endif // P2P_BASE_RELAY_PORT_H_
diff --git a/p2p/base/relay_port_unittest.cc b/p2p/base/relay_port_unittest.cc
deleted file mode 100644
index 1b2236aae0..0000000000
--- a/p2p/base/relay_port_unittest.cc
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Copyright 2009 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 "p2p/base/relay_port.h"
-
-#include <map>
-#include <memory>
-
-#include "p2p/base/basic_packet_socket_factory.h"
-#include "p2p/base/relay_server.h"
-#include "rtc_base/gunit.h"
-#include "rtc_base/helpers.h"
-#include "rtc_base/logging.h"
-#include "rtc_base/socket_adapters.h"
-#include "rtc_base/socket_address.h"
-#include "rtc_base/ssl_adapter.h"
-#include "rtc_base/thread.h"
-#include "rtc_base/virtual_socket_server.h"
-
-using rtc::SocketAddress;
-
-static const SocketAddress kLocalAddress = SocketAddress("192.168.1.2", 0);
-static const SocketAddress kRelayUdpAddr = SocketAddress("99.99.99.1", 5000);
-static const SocketAddress kRelayTcpAddr = SocketAddress("99.99.99.2", 5001);
-static const SocketAddress kRelaySslAddr = SocketAddress("99.99.99.3", 443);
-static const SocketAddress kRelayExtAddr = SocketAddress("99.99.99.3", 5002);
-
-static const int kTimeoutMs = 1000;
-static const int kMaxTimeoutMs = 5000;
-
-// Tests connecting a RelayPort to a fake relay server
-// (cricket::RelayServer) using all currently available protocols. The
-// network layer is faked out by using a VirtualSocketServer for
-// creating sockets. The test will monitor the current state of the
-// RelayPort and created sockets by listening for signals such as,
-// SignalConnectFailure, SignalConnectTimeout, SignalSocketClosed and
-// SignalReadPacket.
-class RelayPortTest : public ::testing::Test, public sigslot::has_slots<> {
- public:
- RelayPortTest()
- : virtual_socket_server_(new rtc::VirtualSocketServer()),
- main_(virtual_socket_server_.get()),
- network_("unittest", "unittest", kLocalAddress.ipaddr(), 32),
- socket_factory_(rtc::Thread::Current()),
- username_(rtc::CreateRandomString(16)),
- password_(rtc::CreateRandomString(16)),
- relay_port_(cricket::RelayPort::Create(&main_,
- &socket_factory_,
- &network_,
- 0,
- 0,
- username_,
- password_)),
- relay_server_(new cricket::RelayServer(&main_)) {
- network_.AddIP(kLocalAddress.ipaddr());
- }
-
- void OnReadPacket(rtc::AsyncPacketSocket* socket,
- const char* /* data */,
- size_t /* size */,
- const rtc::SocketAddress& /* remote_addr */,
- const int64_t& /* packet_time_us */) {
- received_packet_count_[socket]++;
- }
-
- void OnConnectFailure(const cricket::ProtocolAddress* addr) {
- failed_connections_.push_back(*addr);
- }
-
- void OnSoftTimeout(const cricket::ProtocolAddress* addr) {
- soft_timedout_connections_.push_back(*addr);
- }
-
- protected:
- virtual void SetUp() {
- // The relay server needs an external socket to work properly.
- rtc::AsyncUDPSocket* ext_socket = CreateAsyncUdpSocket(kRelayExtAddr);
- relay_server_->AddExternalSocket(ext_socket);
-
- // Listen for failures.
- relay_port_->SignalConnectFailure.connect(this,
- &RelayPortTest::OnConnectFailure);
-
- // Listen for soft timeouts.
- relay_port_->SignalSoftTimeout.connect(this, &RelayPortTest::OnSoftTimeout);
- }
-
- // Udp has the highest 'goodness' value of the three different
- // protocols used for connecting to the relay server. As soon as
- // PrepareAddress is called, the RelayPort will start trying to
- // connect to the given UDP address. As soon as a response to the
- // sent STUN allocate request message has been received, the
- // RelayPort will consider the connection to be complete and will
- // abort any other connection attempts.
- void TestConnectUdp() {
- // Add a UDP socket to the relay server.
- rtc::AsyncUDPSocket* internal_udp_socket =
- CreateAsyncUdpSocket(kRelayUdpAddr);
- rtc::AsyncSocket* server_socket = CreateServerSocket(kRelayTcpAddr);
-
- relay_server_->AddInternalSocket(internal_udp_socket);
- relay_server_->AddInternalServerSocket(server_socket, cricket::PROTO_TCP);
-
- // Now add our relay addresses to the relay port and let it start.
- relay_port_->AddServerAddress(
- cricket::ProtocolAddress(kRelayUdpAddr, cricket::PROTO_UDP));
- relay_port_->AddServerAddress(
- cricket::ProtocolAddress(kRelayTcpAddr, cricket::PROTO_TCP));
- relay_port_->PrepareAddress();
-
- // Should be connected.
- EXPECT_TRUE_WAIT(relay_port_->IsReady(), kTimeoutMs);
-
- // Make sure that we are happy with UDP, ie. not continuing with
- // TCP, SSLTCP, etc.
- WAIT(relay_server_->HasConnection(kRelayTcpAddr), kTimeoutMs);
-
- // Should have only one connection.
- EXPECT_EQ(1, relay_server_->GetConnectionCount());
-
- // Should be the UDP address.
- EXPECT_TRUE(relay_server_->HasConnection(kRelayUdpAddr));
- }
-
- // TCP has the second best 'goodness' value, and as soon as UDP
- // connection has failed, the RelayPort will attempt to connect via
- // TCP. Here we add a fake UDP address together with a real TCP
- // address to simulate an UDP failure. As soon as UDP has failed the
- // RelayPort will try the TCP adress and succed.
- void TestConnectTcp() {
- // Create a fake UDP address for relay port to simulate a failure.
- cricket::ProtocolAddress fake_protocol_address =
- cricket::ProtocolAddress(kRelayUdpAddr, cricket::PROTO_UDP);
-
- // Create a server socket for the RelayServer.
- rtc::AsyncSocket* server_socket = CreateServerSocket(kRelayTcpAddr);
- relay_server_->AddInternalServerSocket(server_socket, cricket::PROTO_TCP);
-
- // Add server addresses to the relay port and let it start.
- relay_port_->AddServerAddress(
- cricket::ProtocolAddress(fake_protocol_address));
- relay_port_->AddServerAddress(
- cricket::ProtocolAddress(kRelayTcpAddr, cricket::PROTO_TCP));
- relay_port_->PrepareAddress();
-
- EXPECT_FALSE(relay_port_->IsReady());
-
- // Should have timed out in 200 + 200 + 400 + 800 + 1600 ms = 3200ms.
- // Add some margin of error for slow bots.
- // TODO(deadbeef): Use simulated clock instead of just increasing timeouts
- // to fix flaky tests.
- EXPECT_TRUE_WAIT(HasFailed(&fake_protocol_address), 5000);
-
- // Wait until relayport is ready.
- EXPECT_TRUE_WAIT(relay_port_->IsReady(), kMaxTimeoutMs);
-
- // Should have only one connection.
- EXPECT_EQ(1, relay_server_->GetConnectionCount());
-
- // Should be the TCP address.
- EXPECT_TRUE(relay_server_->HasConnection(kRelayTcpAddr));
- }
-
- void TestConnectSslTcp() {
- // Create a fake TCP address for relay port to simulate a failure.
- // We skip UDP here since transition from UDP to TCP has been
- // tested above.
- cricket::ProtocolAddress fake_protocol_address =
- cricket::ProtocolAddress(kRelayTcpAddr, cricket::PROTO_TCP);
-
- // Create a ssl server socket for the RelayServer.
- rtc::AsyncSocket* ssl_server_socket = CreateServerSocket(kRelaySslAddr);
- relay_server_->AddInternalServerSocket(ssl_server_socket,
- cricket::PROTO_SSLTCP);
-
- // Create a tcp server socket that listens on the fake address so
- // the relay port can attempt to connect to it.
- std::unique_ptr<rtc::AsyncSocket> tcp_server_socket(
- CreateServerSocket(kRelayTcpAddr));
-
- // Add server addresses to the relay port and let it start.
- relay_port_->AddServerAddress(fake_protocol_address);
- relay_port_->AddServerAddress(
- cricket::ProtocolAddress(kRelaySslAddr, cricket::PROTO_SSLTCP));
- relay_port_->PrepareAddress();
- EXPECT_FALSE(relay_port_->IsReady());
-
- // Should have timed out in 3000 ms(relayport.cc, kSoftConnectTimeoutMs).
- EXPECT_TRUE_WAIT_MARGIN(HasTimedOut(&fake_protocol_address), 3000, 100);
-
- // Wait until relayport is ready.
- EXPECT_TRUE_WAIT(relay_port_->IsReady(), kMaxTimeoutMs);
-
- // Should have only one connection.
- EXPECT_EQ(1, relay_server_->GetConnectionCount());
-
- // Should be the SSLTCP address.
- EXPECT_TRUE(relay_server_->HasConnection(kRelaySslAddr));
- }
-
- private:
- rtc::AsyncUDPSocket* CreateAsyncUdpSocket(const SocketAddress addr) {
- rtc::AsyncSocket* socket =
- virtual_socket_server_->CreateAsyncSocket(AF_INET, SOCK_DGRAM);
- rtc::AsyncUDPSocket* packet_socket =
- rtc::AsyncUDPSocket::Create(socket, addr);
- EXPECT_TRUE(packet_socket != NULL);
- packet_socket->SignalReadPacket.connect(this, &RelayPortTest::OnReadPacket);
- return packet_socket;
- }
-
- rtc::AsyncSocket* CreateServerSocket(const SocketAddress addr) {
- rtc::AsyncSocket* socket =
- virtual_socket_server_->CreateAsyncSocket(AF_INET, SOCK_STREAM);
- EXPECT_GE(socket->Bind(addr), 0);
- EXPECT_GE(socket->Listen(5), 0);
- return socket;
- }
-
- bool HasFailed(cricket::ProtocolAddress* addr) {
- for (size_t i = 0; i < failed_connections_.size(); i++) {
- if (failed_connections_[i].address == addr->address &&
- failed_connections_[i].proto == addr->proto) {
- return true;
- }
- }
- return false;
- }
-
- bool HasTimedOut(cricket::ProtocolAddress* addr) {
- for (size_t i = 0; i < soft_timedout_connections_.size(); i++) {
- if (soft_timedout_connections_[i].address == addr->address &&
- soft_timedout_connections_[i].proto == addr->proto) {
- return true;
- }
- }
- return false;
- }
-
- typedef std::map<rtc::AsyncPacketSocket*, int> PacketMap;
-
- std::unique_ptr<rtc::VirtualSocketServer> virtual_socket_server_;
- rtc::AutoSocketServerThread main_;
- rtc::Network network_;
- rtc::BasicPacketSocketFactory socket_factory_;
- std::string username_;
- std::string password_;
- std::unique_ptr<cricket::RelayPort> relay_port_;
- std::unique_ptr<cricket::RelayServer> relay_server_;
- std::vector<cricket::ProtocolAddress> failed_connections_;
- std::vector<cricket::ProtocolAddress> soft_timedout_connections_;
- PacketMap received_packet_count_;
-};
-
-TEST_F(RelayPortTest, ConnectUdp) {
- TestConnectUdp();
-}
-
-TEST_F(RelayPortTest, ConnectTcp) {
- TestConnectTcp();
-}
-
-TEST_F(RelayPortTest, ConnectSslTcp) {
- TestConnectSslTcp();
-}
diff --git a/p2p/base/relay_server.cc b/p2p/base/relay_server.cc
deleted file mode 100644
index 7214fa1022..0000000000
--- a/p2p/base/relay_server.cc
+++ /dev/null
@@ -1,741 +0,0 @@
-/*
- * Copyright 2004 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 "p2p/base/relay_server.h"
-
-#ifdef WEBRTC_POSIX
-#include <errno.h>
-#endif // WEBRTC_POSIX
-
-#include <algorithm>
-#include <utility>
-
-#include "absl/algorithm/container.h"
-#include "rtc_base/async_tcp_socket.h"
-#include "rtc_base/checks.h"
-#include "rtc_base/helpers.h"
-#include "rtc_base/logging.h"
-#include "rtc_base/numerics/safe_conversions.h"
-#include "rtc_base/server_socket_adapters.h"
-
-namespace cricket {
-
-// By default, we require a ping every 90 seconds.
-const int MAX_LIFETIME = 15 * 60 * 1000;
-
-// The number of bytes in each of the usernames we use.
-const uint32_t USERNAME_LENGTH = 16;
-
-// Calls SendTo on the given socket and logs any bad results.
-void Send(rtc::AsyncPacketSocket* socket,
- const char* bytes,
- size_t size,
- const rtc::SocketAddress& addr) {
- rtc::PacketOptions options;
- int result = socket->SendTo(bytes, size, addr, options);
- if (result < static_cast<int>(size)) {
- RTC_LOG(LS_ERROR) << "SendTo wrote only " << result << " of " << size
- << " bytes";
- } else if (result < 0) {
- RTC_LOG_ERR(LS_ERROR) << "SendTo";
- }
-}
-
-// Sends the given STUN message on the given socket.
-void SendStun(const StunMessage& msg,
- rtc::AsyncPacketSocket* socket,
- const rtc::SocketAddress& addr) {
- rtc::ByteBufferWriter buf;
- msg.Write(&buf);
- Send(socket, buf.Data(), buf.Length(), addr);
-}
-
-// Constructs a STUN error response and sends it on the given socket.
-void SendStunError(const StunMessage& msg,
- rtc::AsyncPacketSocket* socket,
- const rtc::SocketAddress& remote_addr,
- int error_code,
- const char* error_desc,
- const std::string& magic_cookie) {
- RelayMessage err_msg;
- err_msg.SetType(GetStunErrorResponseType(msg.type()));
- err_msg.SetTransactionID(msg.transaction_id());
-
- auto magic_cookie_attr =
- StunAttribute::CreateByteString(cricket::STUN_ATTR_MAGIC_COOKIE);
- if (magic_cookie.size() == 0) {
- magic_cookie_attr->CopyBytes(cricket::TURN_MAGIC_COOKIE_VALUE,
- sizeof(cricket::TURN_MAGIC_COOKIE_VALUE));
- } else {
- magic_cookie_attr->CopyBytes(magic_cookie.c_str(), magic_cookie.size());
- }
- err_msg.AddAttribute(std::move(magic_cookie_attr));
-
- auto err_code = StunAttribute::CreateErrorCode();
- err_code->SetClass(error_code / 100);
- err_code->SetNumber(error_code % 100);
- err_code->SetReason(error_desc);
- err_msg.AddAttribute(std::move(err_code));
-
- SendStun(err_msg, socket, remote_addr);
-}
-
-RelayServer::RelayServer(rtc::Thread* thread)
- : thread_(thread), random_(rtc::SystemTimeNanos()), log_bindings_(true) {}
-
-RelayServer::~RelayServer() {
- // Deleting the binding will cause it to be removed from the map.
- while (!bindings_.empty())
- delete bindings_.begin()->second;
- for (size_t i = 0; i < internal_sockets_.size(); ++i)
- delete internal_sockets_[i];
- for (size_t i = 0; i < external_sockets_.size(); ++i)
- delete external_sockets_[i];
- for (size_t i = 0; i < removed_sockets_.size(); ++i)
- delete removed_sockets_[i];
- while (!server_sockets_.empty()) {
- rtc::AsyncSocket* socket = server_sockets_.begin()->first;
- server_sockets_.erase(server_sockets_.begin()->first);
- delete socket;
- }
-}
-
-void RelayServer::AddInternalSocket(rtc::AsyncPacketSocket* socket) {
- RTC_DCHECK(!absl::c_linear_search(internal_sockets_, socket));
- internal_sockets_.push_back(socket);
- socket->SignalReadPacket.connect(this, &RelayServer::OnInternalPacket);
-}
-
-void RelayServer::RemoveInternalSocket(rtc::AsyncPacketSocket* socket) {
- auto iter = absl::c_find(internal_sockets_, socket);
- RTC_DCHECK(iter != internal_sockets_.end());
- internal_sockets_.erase(iter);
- removed_sockets_.push_back(socket);
- socket->SignalReadPacket.disconnect(this);
-}
-
-void RelayServer::AddExternalSocket(rtc::AsyncPacketSocket* socket) {
- RTC_DCHECK(!absl::c_linear_search(external_sockets_, socket));
- external_sockets_.push_back(socket);
- socket->SignalReadPacket.connect(this, &RelayServer::OnExternalPacket);
-}
-
-void RelayServer::RemoveExternalSocket(rtc::AsyncPacketSocket* socket) {
- auto iter = absl::c_find(external_sockets_, socket);
- RTC_DCHECK(iter != external_sockets_.end());
- external_sockets_.erase(iter);
- removed_sockets_.push_back(socket);
- socket->SignalReadPacket.disconnect(this);
-}
-
-void RelayServer::AddInternalServerSocket(rtc::AsyncSocket* socket,
- cricket::ProtocolType proto) {
- RTC_DCHECK(server_sockets_.end() == server_sockets_.find(socket));
- server_sockets_[socket] = proto;
- socket->SignalReadEvent.connect(this, &RelayServer::OnReadEvent);
-}
-
-void RelayServer::RemoveInternalServerSocket(rtc::AsyncSocket* socket) {
- auto iter = server_sockets_.find(socket);
- RTC_DCHECK(iter != server_sockets_.end());
- server_sockets_.erase(iter);
- socket->SignalReadEvent.disconnect(this);
-}
-
-int RelayServer::GetConnectionCount() const {
- return static_cast<int>(connections_.size());
-}
-
-rtc::SocketAddressPair RelayServer::GetConnection(int connection) const {
- int i = 0;
- for (const auto& entry : connections_) {
- if (i == connection) {
- return entry.second->addr_pair();
- }
- ++i;
- }
- return rtc::SocketAddressPair();
-}
-
-bool RelayServer::HasConnection(const rtc::SocketAddress& address) const {
- for (const auto& entry : connections_) {
- if (entry.second->addr_pair().destination() == address) {
- return true;
- }
- }
- return false;
-}
-
-void RelayServer::OnReadEvent(rtc::AsyncSocket* socket) {
- RTC_DCHECK(server_sockets_.find(socket) != server_sockets_.end());
- AcceptConnection(socket);
-}
-
-void RelayServer::OnInternalPacket(rtc::AsyncPacketSocket* socket,
- const char* bytes,
- size_t size,
- const rtc::SocketAddress& remote_addr,
- const int64_t& /* packet_time_us */) {
- // Get the address of the connection we just received on.
- rtc::SocketAddressPair ap(remote_addr, socket->GetLocalAddress());
- RTC_DCHECK(!ap.destination().IsNil());
-
- // If this did not come from an existing connection, it should be a STUN
- // allocate request.
- auto piter = connections_.find(ap);
- if (piter == connections_.end()) {
- HandleStunAllocate(bytes, size, ap, socket);
- return;
- }
-
- RelayServerConnection* int_conn = piter->second;
-
- // Handle STUN requests to the server itself.
- if (int_conn->binding()->HasMagicCookie(bytes, size)) {
- HandleStun(int_conn, bytes, size);
- return;
- }
-
- // Otherwise, this is a non-wrapped packet that we are to forward. Make sure
- // that this connection has been locked. (Otherwise, we would not know what
- // address to forward to.)
- if (!int_conn->locked()) {
- RTC_LOG(LS_WARNING) << "Dropping packet: connection not locked";
- return;
- }
-
- // Forward this to the destination address into the connection.
- RelayServerConnection* ext_conn = int_conn->binding()->GetExternalConnection(
- int_conn->default_destination());
- if (ext_conn && ext_conn->locked()) {
- // TODO(?): Check the HMAC.
- ext_conn->Send(bytes, size);
- } else {
- // This happens very often and is not an error.
- RTC_LOG(LS_INFO) << "Dropping packet: no external connection";
- }
-}
-
-void RelayServer::OnExternalPacket(rtc::AsyncPacketSocket* socket,
- const char* bytes,
- size_t size,
- const rtc::SocketAddress& remote_addr,
- const int64_t& /* packet_time_us */) {
- // Get the address of the connection we just received on.
- rtc::SocketAddressPair ap(remote_addr, socket->GetLocalAddress());
- RTC_DCHECK(!ap.destination().IsNil());
-
- // If this connection already exists, then forward the traffic.
- auto piter = connections_.find(ap);
- if (piter != connections_.end()) {
- // TODO(?): Check the HMAC.
- RelayServerConnection* ext_conn = piter->second;
- RelayServerConnection* int_conn =
- ext_conn->binding()->GetInternalConnection(
- ext_conn->addr_pair().source());
- RTC_DCHECK(int_conn != NULL);
- int_conn->Send(bytes, size, ext_conn->addr_pair().source());
- ext_conn->Lock(); // allow outgoing packets
- return;
- }
-
- // The first packet should always be a STUN / TURN packet. If it isn't, then
- // we should just ignore this packet.
- RelayMessage msg;
- rtc::ByteBufferReader buf(bytes, size);
- if (!msg.Read(&buf)) {
- RTC_LOG(LS_WARNING) << "Dropping packet: first packet not STUN";
- return;
- }
-
- // The initial packet should have a username (which identifies the binding).
- const StunByteStringAttribute* username_attr =
- msg.GetByteString(STUN_ATTR_USERNAME);
- if (!username_attr) {
- RTC_LOG(LS_WARNING) << "Dropping packet: no username";
- return;
- }
-
- uint32_t length =
- std::min(static_cast<uint32_t>(username_attr->length()), USERNAME_LENGTH);
- std::string username(username_attr->bytes(), length);
- // TODO(?): Check the HMAC.
-
- // The binding should already be present.
- auto biter = bindings_.find(username);
- if (biter == bindings_.end()) {
- RTC_LOG(LS_WARNING) << "Dropping packet: no binding with username";
- return;
- }
-
- // Add this authenticted connection to the binding.
- RelayServerConnection* ext_conn =
- new RelayServerConnection(biter->second, ap, socket);
- ext_conn->binding()->AddExternalConnection(ext_conn);
- AddConnection(ext_conn);
-
- // We always know where external packets should be forwarded, so we can lock
- // them from the beginning.
- ext_conn->Lock();
-
- // Send this message on the appropriate internal connection.
- RelayServerConnection* int_conn = ext_conn->binding()->GetInternalConnection(
- ext_conn->addr_pair().source());
- RTC_DCHECK(int_conn != NULL);
- int_conn->Send(bytes, size, ext_conn->addr_pair().source());
-}
-
-bool RelayServer::HandleStun(const char* bytes,
- size_t size,
- const rtc::SocketAddress& remote_addr,
- rtc::AsyncPacketSocket* socket,
- std::string* username,
- StunMessage* msg) {
- // Parse this into a stun message. Eat the message if this fails.
- rtc::ByteBufferReader buf(bytes, size);
- if (!msg->Read(&buf)) {
- return false;
- }
-
- // The initial packet should have a username (which identifies the binding).
- const StunByteStringAttribute* username_attr =
- msg->GetByteString(STUN_ATTR_USERNAME);
- if (!username_attr) {
- SendStunError(*msg, socket, remote_addr, 432, "Missing Username", "");
- return false;
- }
-
- // Record the username if requested.
- if (username)
- username->append(username_attr->bytes(), username_attr->length());
-
- // TODO(?): Check for unknown attributes (<= 0x7fff)
-
- return true;
-}
-
-void RelayServer::HandleStunAllocate(const char* bytes,
- size_t size,
- const rtc::SocketAddressPair& ap,
- rtc::AsyncPacketSocket* socket) {
- // Make sure this is a valid STUN request.
- RelayMessage request;
- std::string username;
- if (!HandleStun(bytes, size, ap.source(), socket, &username, &request))
- return;
-
- // Make sure this is a an allocate request.
- if (request.type() != STUN_ALLOCATE_REQUEST) {
- SendStunError(request, socket, ap.source(), 600, "Operation Not Supported",
- "");
- return;
- }
-
- // TODO(?): Check the HMAC.
-
- // Find or create the binding for this username.
-
- RelayServerBinding* binding;
-
- auto biter = bindings_.find(username);
- if (biter != bindings_.end()) {
- binding = biter->second;
- } else {
- // NOTE: In the future, bindings will be created by the bot only. This
- // else-branch will then disappear.
-
- // Compute the appropriate lifetime for this binding.
- int lifetime = MAX_LIFETIME;
- const StunUInt32Attribute* lifetime_attr =
- request.GetUInt32(STUN_ATTR_LIFETIME);
- if (lifetime_attr)
- lifetime =
- std::min(lifetime, static_cast<int>(lifetime_attr->value() * 1000));
-
- binding = new RelayServerBinding(this, username, "0", lifetime);
- binding->SignalTimeout.connect(this, &RelayServer::OnTimeout);
- bindings_[username] = binding;
-
- if (log_bindings_) {
- RTC_LOG(LS_INFO) << "Added new binding " << username << ", "
- << bindings_.size() << " total";
- }
- }
-
- // Add this connection to the binding. It starts out unlocked.
- RelayServerConnection* int_conn =
- new RelayServerConnection(binding, ap, socket);
- binding->AddInternalConnection(int_conn);
- AddConnection(int_conn);
-
- // Now that we have a connection, this other method takes over.
- HandleStunAllocate(int_conn, request);
-}
-
-void RelayServer::HandleStun(RelayServerConnection* int_conn,
- const char* bytes,
- size_t size) {
- // Make sure this is a valid STUN request.
- RelayMessage request;
- std::string username;
- if (!HandleStun(bytes, size, int_conn->addr_pair().source(),
- int_conn->socket(), &username, &request))
- return;
-
- // Make sure the username is the one were were expecting.
- if (username != int_conn->binding()->username()) {
- int_conn->SendStunError(request, 430, "Stale Credentials");
- return;
- }
-
- // TODO(?): Check the HMAC.
-
- // Send this request to the appropriate handler.
- if (request.type() == STUN_SEND_REQUEST)
- HandleStunSend(int_conn, request);
- else if (request.type() == STUN_ALLOCATE_REQUEST)
- HandleStunAllocate(int_conn, request);
- else
- int_conn->SendStunError(request, 600, "Operation Not Supported");
-}
-
-void RelayServer::HandleStunAllocate(RelayServerConnection* int_conn,
- const StunMessage& request) {
- // Create a response message that includes an address with which external
- // clients can communicate.
-
- RelayMessage response;
- response.SetType(STUN_ALLOCATE_RESPONSE);
- response.SetTransactionID(request.transaction_id());
-
- auto magic_cookie_attr =
- StunAttribute::CreateByteString(cricket::STUN_ATTR_MAGIC_COOKIE);
- magic_cookie_attr->CopyBytes(int_conn->binding()->magic_cookie().c_str(),
- int_conn->binding()->magic_cookie().size());
- response.AddAttribute(std::move(magic_cookie_attr));
-
- RTC_DCHECK_GT(external_sockets_.size(), 0);
- size_t index =
- random_.Rand(rtc::dchecked_cast<uint32_t>(external_sockets_.size() - 1));
- rtc::SocketAddress ext_addr = external_sockets_[index]->GetLocalAddress();
-
- auto addr_attr = StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
- addr_attr->SetIP(ext_addr.ipaddr());
- addr_attr->SetPort(ext_addr.port());
- response.AddAttribute(std::move(addr_attr));
-
- auto res_lifetime_attr = StunAttribute::CreateUInt32(STUN_ATTR_LIFETIME);
- res_lifetime_attr->SetValue(int_conn->binding()->lifetime() / 1000);
- response.AddAttribute(std::move(res_lifetime_attr));
-
- // TODO(?): Support transport-prefs (preallocate RTCP port).
- // TODO(?): Support bandwidth restrictions.
- // TODO(?): Add message integrity check.
-
- // Send a response to the caller.
- int_conn->SendStun(response);
-}
-
-void RelayServer::HandleStunSend(RelayServerConnection* int_conn,
- const StunMessage& request) {
- const StunAddressAttribute* addr_attr =
- request.GetAddress(STUN_ATTR_DESTINATION_ADDRESS);
- if (!addr_attr) {
- int_conn->SendStunError(request, 400, "Bad Request");
- return;
- }
-
- const StunByteStringAttribute* data_attr =
- request.GetByteString(STUN_ATTR_DATA);
- if (!data_attr) {
- int_conn->SendStunError(request, 400, "Bad Request");
- return;
- }
-
- rtc::SocketAddress ext_addr(addr_attr->ipaddr(), addr_attr->port());
- RelayServerConnection* ext_conn =
- int_conn->binding()->GetExternalConnection(ext_addr);
- if (!ext_conn) {
- // Create a new connection to establish the relationship with this binding.
- RTC_DCHECK(external_sockets_.size() == 1);
- rtc::AsyncPacketSocket* socket = external_sockets_[0];
- rtc::SocketAddressPair ap(ext_addr, socket->GetLocalAddress());
- ext_conn = new RelayServerConnection(int_conn->binding(), ap, socket);
- ext_conn->binding()->AddExternalConnection(ext_conn);
- AddConnection(ext_conn);
- }
-
- // If this connection has pinged us, then allow outgoing traffic.
- if (ext_conn->locked())
- ext_conn->Send(data_attr->bytes(), data_attr->length());
-
- const StunUInt32Attribute* options_attr =
- request.GetUInt32(STUN_ATTR_OPTIONS);
- if (options_attr && (options_attr->value() & 0x01)) {
- int_conn->set_default_destination(ext_addr);
- int_conn->Lock();
-
- RelayMessage response;
- response.SetType(STUN_SEND_RESPONSE);
- response.SetTransactionID(request.transaction_id());
-
- auto magic_cookie_attr =
- StunAttribute::CreateByteString(cricket::STUN_ATTR_MAGIC_COOKIE);
- magic_cookie_attr->CopyBytes(int_conn->binding()->magic_cookie().c_str(),
- int_conn->binding()->magic_cookie().size());
- response.AddAttribute(std::move(magic_cookie_attr));
-
- auto options2_attr =
- StunAttribute::CreateUInt32(cricket::STUN_ATTR_OPTIONS);
- options2_attr->SetValue(0x01);
- response.AddAttribute(std::move(options2_attr));
-
- int_conn->SendStun(response);
- }
-}
-
-void RelayServer::AddConnection(RelayServerConnection* conn) {
- RTC_DCHECK(connections_.find(conn->addr_pair()) == connections_.end());
- connections_[conn->addr_pair()] = conn;
-}
-
-void RelayServer::RemoveConnection(RelayServerConnection* conn) {
- auto iter = connections_.find(conn->addr_pair());
- RTC_DCHECK(iter != connections_.end());
- connections_.erase(iter);
-}
-
-void RelayServer::RemoveBinding(RelayServerBinding* binding) {
- auto iter = bindings_.find(binding->username());
- RTC_DCHECK(iter != bindings_.end());
- bindings_.erase(iter);
-
- if (log_bindings_) {
- RTC_LOG(LS_INFO) << "Removed binding " << binding->username() << ", "
- << bindings_.size() << " remaining";
- }
-}
-
-void RelayServer::OnMessage(rtc::Message* pmsg) {
- static const uint32_t kMessageAcceptConnection = 1;
- RTC_DCHECK(pmsg->message_id == kMessageAcceptConnection);
-
- rtc::MessageData* data = pmsg->pdata;
- rtc::AsyncSocket* socket =
- static_cast<rtc::TypedMessageData<rtc::AsyncSocket*>*>(data)->data();
- AcceptConnection(socket);
- delete data;
-}
-
-void RelayServer::OnTimeout(RelayServerBinding* binding) {
- // This call will result in all of the necessary clean-up. We can't call
- // delete here, because you can't delete an object that is signaling you.
- thread_->Dispose(binding);
-}
-
-void RelayServer::AcceptConnection(rtc::AsyncSocket* server_socket) {
- // Check if someone is trying to connect to us.
- rtc::SocketAddress accept_addr;
- rtc::AsyncSocket* accepted_socket = server_socket->Accept(&accept_addr);
- if (accepted_socket != NULL) {
- // We had someone trying to connect, now check which protocol to
- // use and create a packet socket.
- RTC_DCHECK(server_sockets_[server_socket] == cricket::PROTO_TCP ||
- server_sockets_[server_socket] == cricket::PROTO_SSLTCP);
- if (server_sockets_[server_socket] == cricket::PROTO_SSLTCP) {
- accepted_socket = new rtc::AsyncSSLServerSocket(accepted_socket);
- }
- rtc::AsyncTCPSocket* tcp_socket =
- new rtc::AsyncTCPSocket(accepted_socket, false);
-
- // Finally add the socket so it can start communicating with the client.
- AddInternalSocket(tcp_socket);
- }
-}
-
-RelayServerConnection::RelayServerConnection(
- RelayServerBinding* binding,
- const rtc::SocketAddressPair& addrs,
- rtc::AsyncPacketSocket* socket)
- : binding_(binding), addr_pair_(addrs), socket_(socket), locked_(false) {
- // The creation of a new connection constitutes a use of the binding.
- binding_->NoteUsed();
-}
-
-RelayServerConnection::~RelayServerConnection() {
- // Remove this connection from the server's map (if it exists there).
- binding_->server()->RemoveConnection(this);
-}
-
-void RelayServerConnection::Send(const char* data, size_t size) {
- // Note that the binding has been used again.
- binding_->NoteUsed();
-
- cricket::Send(socket_, data, size, addr_pair_.source());
-}
-
-void RelayServerConnection::Send(const char* data,
- size_t size,
- const rtc::SocketAddress& from_addr) {
- // If the from address is known to the client, we don't need to send it.
- if (locked() && (from_addr == default_dest_)) {
- Send(data, size);
- return;
- }
-
- // Wrap the given data in a data-indication packet.
-
- RelayMessage msg;
- msg.SetType(STUN_DATA_INDICATION);
-
- auto magic_cookie_attr =
- StunAttribute::CreateByteString(cricket::STUN_ATTR_MAGIC_COOKIE);
- magic_cookie_attr->CopyBytes(binding_->magic_cookie().c_str(),
- binding_->magic_cookie().size());
- msg.AddAttribute(std::move(magic_cookie_attr));
-
- auto addr_attr = StunAttribute::CreateAddress(STUN_ATTR_SOURCE_ADDRESS2);
- addr_attr->SetIP(from_addr.ipaddr());
- addr_attr->SetPort(from_addr.port());
- msg.AddAttribute(std::move(addr_attr));
-
- auto data_attr = StunAttribute::CreateByteString(STUN_ATTR_DATA);
- RTC_DCHECK(size <= 65536);
- data_attr->CopyBytes(data, uint16_t(size));
- msg.AddAttribute(std::move(data_attr));
-
- SendStun(msg);
-}
-
-void RelayServerConnection::SendStun(const StunMessage& msg) {
- // Note that the binding has been used again.
- binding_->NoteUsed();
-
- cricket::SendStun(msg, socket_, addr_pair_.source());
-}
-
-void RelayServerConnection::SendStunError(const StunMessage& request,
- int error_code,
- const char* error_desc) {
- // An error does not indicate use. If no legitimate use off the binding
- // occurs, we want it to be cleaned up even if errors are still occuring.
-
- cricket::SendStunError(request, socket_, addr_pair_.source(), error_code,
- error_desc, binding_->magic_cookie());
-}
-
-void RelayServerConnection::Lock() {
- locked_ = true;
-}
-
-void RelayServerConnection::Unlock() {
- locked_ = false;
-}
-
-// IDs used for posted messages:
-const uint32_t MSG_LIFETIME_TIMER = 1;
-
-RelayServerBinding::RelayServerBinding(RelayServer* server,
- const std::string& username,
- const std::string& password,
- int lifetime)
- : server_(server),
- username_(username),
- password_(password),
- lifetime_(lifetime) {
- // For now, every connection uses the standard magic cookie value.
- magic_cookie_.append(reinterpret_cast<const char*>(TURN_MAGIC_COOKIE_VALUE),
- sizeof(TURN_MAGIC_COOKIE_VALUE));
-
- // Initialize the last-used time to now.
- NoteUsed();
-
- // Set the first timeout check.
- server_->thread()->PostDelayed(RTC_FROM_HERE, lifetime_, this,
- MSG_LIFETIME_TIMER);
-}
-
-RelayServerBinding::~RelayServerBinding() {
- // Clear the outstanding timeout check.
- server_->thread()->Clear(this);
-
- // Clean up all of the connections.
- for (size_t i = 0; i < internal_connections_.size(); ++i)
- delete internal_connections_[i];
- for (size_t i = 0; i < external_connections_.size(); ++i)
- delete external_connections_[i];
-
- // Remove this binding from the server's map.
- server_->RemoveBinding(this);
-}
-
-void RelayServerBinding::AddInternalConnection(RelayServerConnection* conn) {
- internal_connections_.push_back(conn);
-}
-
-void RelayServerBinding::AddExternalConnection(RelayServerConnection* conn) {
- external_connections_.push_back(conn);
-}
-
-void RelayServerBinding::NoteUsed() {
- last_used_ = rtc::TimeMillis();
-}
-
-bool RelayServerBinding::HasMagicCookie(const char* bytes, size_t size) const {
- if (size < 24 + magic_cookie_.size()) {
- return false;
- } else {
- return memcmp(bytes + 24, magic_cookie_.c_str(), magic_cookie_.size()) == 0;
- }
-}
-
-RelayServerConnection* RelayServerBinding::GetInternalConnection(
- const rtc::SocketAddress& ext_addr) {
- // Look for an internal connection that is locked to this address.
- for (size_t i = 0; i < internal_connections_.size(); ++i) {
- if (internal_connections_[i]->locked() &&
- (ext_addr == internal_connections_[i]->default_destination()))
- return internal_connections_[i];
- }
-
- // If one was not found, we send to the first connection.
- RTC_DCHECK(internal_connections_.size() > 0);
- return internal_connections_[0];
-}
-
-RelayServerConnection* RelayServerBinding::GetExternalConnection(
- const rtc::SocketAddress& ext_addr) {
- for (size_t i = 0; i < external_connections_.size(); ++i) {
- if (ext_addr == external_connections_[i]->addr_pair().source())
- return external_connections_[i];
- }
- return 0;
-}
-
-void RelayServerBinding::OnMessage(rtc::Message* pmsg) {
- if (pmsg->message_id == MSG_LIFETIME_TIMER) {
- RTC_DCHECK(!pmsg->pdata);
-
- // If the lifetime timeout has been exceeded, then send a signal.
- // Otherwise, just keep waiting.
- if (rtc::TimeMillis() >= last_used_ + lifetime_) {
- RTC_LOG(LS_INFO) << "Expiring binding " << username_;
- SignalTimeout(this);
- } else {
- server_->thread()->PostDelayed(RTC_FROM_HERE, lifetime_, this,
- MSG_LIFETIME_TIMER);
- }
-
- } else {
- RTC_NOTREACHED();
- }
-}
-
-} // namespace cricket
diff --git a/p2p/base/relay_server.h b/p2p/base/relay_server.h
deleted file mode 100644
index 3b9e9be1cb..0000000000
--- a/p2p/base/relay_server.h
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * Copyright 2004 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.
- */
-
-#ifndef P2P_BASE_RELAY_SERVER_H_
-#define P2P_BASE_RELAY_SERVER_H_
-
-#include <map>
-#include <string>
-#include <vector>
-
-#include "p2p/base/port.h"
-#include "p2p/base/stun.h"
-#include "rtc_base/async_udp_socket.h"
-#include "rtc_base/random.h"
-#include "rtc_base/socket_address_pair.h"
-#include "rtc_base/thread.h"
-#include "rtc_base/time_utils.h"
-
-namespace cricket {
-
-class RelayServerBinding;
-class RelayServerConnection;
-
-// Relays traffic between connections to the server that are "bound" together.
-// All connections created with the same username/password are bound together.
-class RelayServer : public rtc::MessageHandler, public sigslot::has_slots<> {
- public:
- // Creates a server, which will use this thread to post messages to itself.
- explicit RelayServer(rtc::Thread* thread);
- ~RelayServer() override;
-
- rtc::Thread* thread() { return thread_; }
-
- // Indicates whether we will print updates of the number of bindings.
- bool log_bindings() const { return log_bindings_; }
- void set_log_bindings(bool log_bindings) { log_bindings_ = log_bindings; }
-
- // Updates the set of sockets that the server uses to talk to "internal"
- // clients. These are clients that do the "port allocations".
- void AddInternalSocket(rtc::AsyncPacketSocket* socket);
- void RemoveInternalSocket(rtc::AsyncPacketSocket* socket);
-
- // Updates the set of sockets that the server uses to talk to "external"
- // clients. These are the clients that do not do allocations. They do not
- // know that these addresses represent a relay server.
- void AddExternalSocket(rtc::AsyncPacketSocket* socket);
- void RemoveExternalSocket(rtc::AsyncPacketSocket* socket);
-
- // Starts listening for connections on this sockets. When someone
- // tries to connect, the connection will be accepted and a new
- // internal socket will be added.
- void AddInternalServerSocket(rtc::AsyncSocket* socket,
- cricket::ProtocolType proto);
-
- // Removes this server socket from the list.
- void RemoveInternalServerSocket(rtc::AsyncSocket* socket);
-
- // Methods for testing and debuging.
- int GetConnectionCount() const;
- rtc::SocketAddressPair GetConnection(int connection) const;
- bool HasConnection(const rtc::SocketAddress& address) const;
-
- private:
- rtc::Thread* thread_;
- webrtc::Random random_;
- bool log_bindings_;
- std::vector<rtc::AsyncPacketSocket*> internal_sockets_;
- std::vector<rtc::AsyncPacketSocket*> external_sockets_;
- std::vector<rtc::AsyncPacketSocket*> removed_sockets_;
- std::map<rtc::AsyncSocket*, cricket::ProtocolType> server_sockets_;
- std::map<std::string, RelayServerBinding*> bindings_;
- std::map<rtc::SocketAddressPair, RelayServerConnection*> connections_;
-
- // Called when a packet is received by the server on one of its sockets.
- void OnInternalPacket(rtc::AsyncPacketSocket* socket,
- const char* bytes,
- size_t size,
- const rtc::SocketAddress& remote_addr,
- const int64_t& packet_time_us);
- void OnExternalPacket(rtc::AsyncPacketSocket* socket,
- const char* bytes,
- size_t size,
- const rtc::SocketAddress& remote_addr,
- const int64_t& packet_time_us);
-
- void OnReadEvent(rtc::AsyncSocket* socket);
-
- // Processes the relevant STUN request types from the client.
- bool HandleStun(const char* bytes,
- size_t size,
- const rtc::SocketAddress& remote_addr,
- rtc::AsyncPacketSocket* socket,
- std::string* username,
- StunMessage* msg);
- void HandleStunAllocate(const char* bytes,
- size_t size,
- const rtc::SocketAddressPair& ap,
- rtc::AsyncPacketSocket* socket);
- void HandleStun(RelayServerConnection* int_conn,
- const char* bytes,
- size_t size);
- void HandleStunAllocate(RelayServerConnection* int_conn,
- const StunMessage& msg);
- void HandleStunSend(RelayServerConnection* int_conn, const StunMessage& msg);
-
- // Adds/Removes the a connection or binding.
- void AddConnection(RelayServerConnection* conn);
- void RemoveConnection(RelayServerConnection* conn);
- void RemoveBinding(RelayServerBinding* binding);
-
- // Handle messages in our thread.
- void OnMessage(rtc::Message* pmsg) override;
-
- // Called when the timer for checking lifetime times out.
- void OnTimeout(RelayServerBinding* binding);
-
- // Accept connections on this server socket.
- void AcceptConnection(rtc::AsyncSocket* server_socket);
-
- friend class RelayServerConnection;
- friend class RelayServerBinding;
-};
-
-// Maintains information about a connection to the server. Each connection is
-// part of one and only one binding.
-class RelayServerConnection {
- public:
- RelayServerConnection(RelayServerBinding* binding,
- const rtc::SocketAddressPair& addrs,
- rtc::AsyncPacketSocket* socket);
- ~RelayServerConnection();
-
- RelayServerBinding* binding() { return binding_; }
- rtc::AsyncPacketSocket* socket() { return socket_; }
-
- // Returns a pair where the source is the remote address and the destination
- // is the local address.
- const rtc::SocketAddressPair& addr_pair() { return addr_pair_; }
-
- // Sends a packet to the connected client. If an address is provided, then
- // we make sure the internal client receives it, wrapping if necessary.
- void Send(const char* data, size_t size);
- void Send(const char* data, size_t size, const rtc::SocketAddress& ext_addr);
-
- // Sends a STUN message to the connected client with no wrapping.
- void SendStun(const StunMessage& msg);
- void SendStunError(const StunMessage& request, int code, const char* desc);
-
- // A locked connection is one for which we know the intended destination of
- // any raw packet received.
- bool locked() const { return locked_; }
- void Lock();
- void Unlock();
-
- // Records the address that raw packets should be forwarded to (for internal
- // packets only; for external, we already know where they go).
- const rtc::SocketAddress& default_destination() const {
- return default_dest_;
- }
- void set_default_destination(const rtc::SocketAddress& addr) {
- default_dest_ = addr;
- }
-
- private:
- RelayServerBinding* binding_;
- rtc::SocketAddressPair addr_pair_;
- rtc::AsyncPacketSocket* socket_;
- bool locked_;
- rtc::SocketAddress default_dest_;
-};
-
-// Records a set of internal and external connections that we relay between,
-// or in other words, that are "bound" together.
-class RelayServerBinding : public rtc::MessageHandler {
- public:
- RelayServerBinding(RelayServer* server,
- const std::string& username,
- const std::string& password,
- int lifetime);
- ~RelayServerBinding() override;
-
- RelayServer* server() { return server_; }
- int lifetime() { return lifetime_; }
- const std::string& username() { return username_; }
- const std::string& password() { return password_; }
- const std::string& magic_cookie() { return magic_cookie_; }
-
- // Adds/Removes a connection into the binding.
- void AddInternalConnection(RelayServerConnection* conn);
- void AddExternalConnection(RelayServerConnection* conn);
-
- // We keep track of the use of each binding. If we detect that it was not
- // used for longer than the lifetime, then we send a signal.
- void NoteUsed();
- sigslot::signal1<RelayServerBinding*> SignalTimeout;
-
- // Determines whether the given packet has the magic cookie present (in the
- // right place).
- bool HasMagicCookie(const char* bytes, size_t size) const;
-
- // Determines the connection to use to send packets to or from the given
- // external address.
- RelayServerConnection* GetInternalConnection(
- const rtc::SocketAddress& ext_addr);
- RelayServerConnection* GetExternalConnection(
- const rtc::SocketAddress& ext_addr);
-
- // MessageHandler:
- void OnMessage(rtc::Message* pmsg) override;
-
- private:
- RelayServer* server_;
-
- std::string username_;
- std::string password_;
- std::string magic_cookie_;
-
- std::vector<RelayServerConnection*> internal_connections_;
- std::vector<RelayServerConnection*> external_connections_;
-
- int lifetime_;
- int64_t last_used_;
- // TODO(?): bandwidth
-};
-
-} // namespace cricket
-
-#endif // P2P_BASE_RELAY_SERVER_H_
diff --git a/p2p/base/relay_server_unittest.cc b/p2p/base/relay_server_unittest.cc
deleted file mode 100644
index 3debc5feb5..0000000000
--- a/p2p/base/relay_server_unittest.cc
+++ /dev/null
@@ -1,511 +0,0 @@
-/*
- * Copyright 2004 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 "p2p/base/relay_server.h"
-
-#include <string.h>
-
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "absl/memory/memory.h"
-#include "rtc_base/async_udp_socket.h"
-#include "rtc_base/byte_buffer.h"
-#include "rtc_base/helpers.h"
-#include "rtc_base/socket_address.h"
-#include "rtc_base/test_client.h"
-#include "rtc_base/thread.h"
-#include "rtc_base/virtual_socket_server.h"
-#include "test/gtest.h"
-
-using rtc::SocketAddress;
-
-namespace cricket {
-namespace {
-
-constexpr uint32_t LIFETIME = 4; // seconds
-const SocketAddress server_int_addr("127.0.0.1", 5000);
-const SocketAddress server_ext_addr("127.0.0.1", 5001);
-const SocketAddress client1_addr("127.0.0.1", 6111);
-const SocketAddress client2_addr("127.0.0.1", 7222);
-const char* bad =
- "this is a completely nonsensical message whose only "
- "purpose is to make the parser go 'ack'. it doesn't "
- "look anything like a normal stun message";
-const char* msg1 = "spamspamspamspamspamspamspambakedbeansspam";
-const char* msg2 = "Lobster Thermidor a Crevette with a mornay sauce...";
-
-} // namespace
-
-class RelayServerTest : public ::testing::Test {
- public:
- RelayServerTest()
- : ss_(new rtc::VirtualSocketServer()),
- thread_(ss_.get()),
- username_(rtc::CreateRandomString(12)),
- password_(rtc::CreateRandomString(12)) {}
-
- protected:
- virtual void SetUp() {
- server_.reset(new RelayServer(rtc::Thread::Current()));
-
- server_->AddInternalSocket(
- rtc::AsyncUDPSocket::Create(ss_.get(), server_int_addr));
- server_->AddExternalSocket(
- rtc::AsyncUDPSocket::Create(ss_.get(), server_ext_addr));
-
- client1_.reset(new rtc::TestClient(absl::WrapUnique(
- rtc::AsyncUDPSocket::Create(ss_.get(), client1_addr))));
- client2_.reset(new rtc::TestClient(absl::WrapUnique(
- rtc::AsyncUDPSocket::Create(ss_.get(), client2_addr))));
- }
-
- void Allocate() {
- std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_ALLOCATE_REQUEST));
- AddUsernameAttr(req.get(), username_);
- AddLifetimeAttr(req.get(), LIFETIME);
- Send1(req.get());
- delete Receive1();
- }
- void Bind() {
- std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_BINDING_REQUEST));
- AddUsernameAttr(req.get(), username_);
- Send2(req.get());
- delete Receive1();
- }
-
- void Send1(const StunMessage* msg) {
- rtc::ByteBufferWriter buf;
- msg->Write(&buf);
- SendRaw1(buf.Data(), static_cast<int>(buf.Length()));
- }
- void Send2(const StunMessage* msg) {
- rtc::ByteBufferWriter buf;
- msg->Write(&buf);
- SendRaw2(buf.Data(), static_cast<int>(buf.Length()));
- }
- void SendRaw1(const char* data, int len) {
- return Send(client1_.get(), data, len, server_int_addr);
- }
- void SendRaw2(const char* data, int len) {
- return Send(client2_.get(), data, len, server_ext_addr);
- }
- void Send(rtc::TestClient* client,
- const char* data,
- int len,
- const SocketAddress& addr) {
- client->SendTo(data, len, addr);
- }
-
- bool Receive1Fails() { return client1_.get()->CheckNoPacket(); }
- bool Receive2Fails() { return client2_.get()->CheckNoPacket(); }
-
- StunMessage* Receive1() { return Receive(client1_.get()); }
- StunMessage* Receive2() { return Receive(client2_.get()); }
- std::string ReceiveRaw1() { return ReceiveRaw(client1_.get()); }
- std::string ReceiveRaw2() { return ReceiveRaw(client2_.get()); }
- StunMessage* Receive(rtc::TestClient* client) {
- StunMessage* msg = NULL;
- std::unique_ptr<rtc::TestClient::Packet> packet =
- client->NextPacket(rtc::TestClient::kTimeoutMs);
- if (packet) {
- rtc::ByteBufferWriter buf(packet->buf, packet->size);
- rtc::ByteBufferReader read_buf(buf);
- msg = new RelayMessage();
- msg->Read(&read_buf);
- }
- return msg;
- }
- std::string ReceiveRaw(rtc::TestClient* client) {
- std::string raw;
- std::unique_ptr<rtc::TestClient::Packet> packet =
- client->NextPacket(rtc::TestClient::kTimeoutMs);
- if (packet) {
- raw = std::string(packet->buf, packet->size);
- }
- return raw;
- }
-
- static StunMessage* CreateStunMessage(int type) {
- StunMessage* msg = new RelayMessage();
- msg->SetType(type);
- msg->SetTransactionID(rtc::CreateRandomString(kStunTransactionIdLength));
- return msg;
- }
- static void AddMagicCookieAttr(StunMessage* msg) {
- auto attr = StunAttribute::CreateByteString(STUN_ATTR_MAGIC_COOKIE);
- attr->CopyBytes(TURN_MAGIC_COOKIE_VALUE, sizeof(TURN_MAGIC_COOKIE_VALUE));
- msg->AddAttribute(std::move(attr));
- }
- static void AddUsernameAttr(StunMessage* msg, const std::string& val) {
- auto attr = StunAttribute::CreateByteString(STUN_ATTR_USERNAME);
- attr->CopyBytes(val.c_str(), val.size());
- msg->AddAttribute(std::move(attr));
- }
- static void AddLifetimeAttr(StunMessage* msg, int val) {
- auto attr = StunAttribute::CreateUInt32(STUN_ATTR_LIFETIME);
- attr->SetValue(val);
- msg->AddAttribute(std::move(attr));
- }
- static void AddDestinationAttr(StunMessage* msg, const SocketAddress& addr) {
- auto attr = StunAttribute::CreateAddress(STUN_ATTR_DESTINATION_ADDRESS);
- attr->SetIP(addr.ipaddr());
- attr->SetPort(addr.port());
- msg->AddAttribute(std::move(attr));
- }
-
- std::unique_ptr<rtc::VirtualSocketServer> ss_;
- rtc::AutoSocketServerThread thread_;
- std::unique_ptr<RelayServer> server_;
- std::unique_ptr<rtc::TestClient> client1_;
- std::unique_ptr<rtc::TestClient> client2_;
- std::string username_;
- std::string password_;
-};
-
-// Send a complete nonsense message and verify that it is eaten.
-TEST_F(RelayServerTest, TestBadRequest) {
- SendRaw1(bad, static_cast<int>(strlen(bad)));
- ASSERT_TRUE(Receive1Fails());
-}
-
-// Send an allocate request without a username and verify it is rejected.
-TEST_F(RelayServerTest, TestAllocateNoUsername) {
- std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_ALLOCATE_REQUEST)),
- res;
-
- Send1(req.get());
- res.reset(Receive1());
-
- ASSERT_TRUE(res);
- EXPECT_EQ(STUN_ALLOCATE_ERROR_RESPONSE, res->type());
- EXPECT_EQ(req->transaction_id(), res->transaction_id());
-
- const StunErrorCodeAttribute* err = res->GetErrorCode();
- ASSERT_TRUE(err != NULL);
- EXPECT_EQ(4, err->eclass());
- EXPECT_EQ(32, err->number());
- EXPECT_EQ("Missing Username", err->reason());
-}
-
-// Send a binding request and verify that it is rejected.
-TEST_F(RelayServerTest, TestBindingRequest) {
- std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_BINDING_REQUEST)),
- res;
- AddUsernameAttr(req.get(), username_);
-
- Send1(req.get());
- res.reset(Receive1());
-
- ASSERT_TRUE(res);
- EXPECT_EQ(STUN_BINDING_ERROR_RESPONSE, res->type());
- EXPECT_EQ(req->transaction_id(), res->transaction_id());
-
- const StunErrorCodeAttribute* err = res->GetErrorCode();
- ASSERT_TRUE(err != NULL);
- EXPECT_EQ(6, err->eclass());
- EXPECT_EQ(0, err->number());
- EXPECT_EQ("Operation Not Supported", err->reason());
-}
-
-// Send an allocate request and verify that it is accepted.
-TEST_F(RelayServerTest, TestAllocate) {
- std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_ALLOCATE_REQUEST)),
- res;
- AddUsernameAttr(req.get(), username_);
- AddLifetimeAttr(req.get(), LIFETIME);
-
- Send1(req.get());
- res.reset(Receive1());
-
- ASSERT_TRUE(res);
- EXPECT_EQ(STUN_ALLOCATE_RESPONSE, res->type());
- EXPECT_EQ(req->transaction_id(), res->transaction_id());
-
- const StunAddressAttribute* mapped_addr =
- res->GetAddress(STUN_ATTR_MAPPED_ADDRESS);
- ASSERT_TRUE(mapped_addr != NULL);
- EXPECT_EQ(1, mapped_addr->family());
- EXPECT_EQ(server_ext_addr.port(), mapped_addr->port());
- EXPECT_EQ(server_ext_addr.ipaddr(), mapped_addr->ipaddr());
-
- const StunUInt32Attribute* res_lifetime_attr =
- res->GetUInt32(STUN_ATTR_LIFETIME);
- ASSERT_TRUE(res_lifetime_attr != NULL);
- EXPECT_EQ(LIFETIME, res_lifetime_attr->value());
-}
-
-// Send a second allocate request and verify that it is also accepted, though
-// the lifetime should be ignored.
-TEST_F(RelayServerTest, TestReallocate) {
- Allocate();
-
- std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_ALLOCATE_REQUEST)),
- res;
- AddMagicCookieAttr(req.get());
- AddUsernameAttr(req.get(), username_);
-
- Send1(req.get());
- res.reset(Receive1());
-
- ASSERT_TRUE(res);
- EXPECT_EQ(STUN_ALLOCATE_RESPONSE, res->type());
- EXPECT_EQ(req->transaction_id(), res->transaction_id());
-
- const StunAddressAttribute* mapped_addr =
- res->GetAddress(STUN_ATTR_MAPPED_ADDRESS);
- ASSERT_TRUE(mapped_addr != NULL);
- EXPECT_EQ(1, mapped_addr->family());
- EXPECT_EQ(server_ext_addr.port(), mapped_addr->port());
- EXPECT_EQ(server_ext_addr.ipaddr(), mapped_addr->ipaddr());
-
- const StunUInt32Attribute* lifetime_attr = res->GetUInt32(STUN_ATTR_LIFETIME);
- ASSERT_TRUE(lifetime_attr != NULL);
- EXPECT_EQ(LIFETIME, lifetime_attr->value());
-}
-
-// Send a request from another client and see that it arrives at the first
-// client in the binding.
-TEST_F(RelayServerTest, TestRemoteBind) {
- Allocate();
-
- std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_BINDING_REQUEST)),
- res;
- AddUsernameAttr(req.get(), username_);
-
- Send2(req.get());
- res.reset(Receive1());
-
- ASSERT_TRUE(res);
- EXPECT_EQ(STUN_DATA_INDICATION, res->type());
-
- const StunByteStringAttribute* recv_data = res->GetByteString(STUN_ATTR_DATA);
- ASSERT_TRUE(recv_data != NULL);
-
- rtc::ByteBufferReader buf(recv_data->bytes(), recv_data->length());
- std::unique_ptr<StunMessage> res2(new StunMessage());
- EXPECT_TRUE(res2->Read(&buf));
- EXPECT_EQ(STUN_BINDING_REQUEST, res2->type());
- EXPECT_EQ(req->transaction_id(), res2->transaction_id());
-
- const StunAddressAttribute* src_addr =
- res->GetAddress(STUN_ATTR_SOURCE_ADDRESS2);
- ASSERT_TRUE(src_addr != NULL);
- EXPECT_EQ(1, src_addr->family());
- EXPECT_EQ(client2_addr.ipaddr(), src_addr->ipaddr());
- EXPECT_EQ(client2_addr.port(), src_addr->port());
-
- EXPECT_TRUE(Receive2Fails());
-}
-
-// Send a complete nonsense message to the established connection and verify
-// that it is dropped by the server.
-TEST_F(RelayServerTest, TestRemoteBadRequest) {
- Allocate();
- Bind();
-
- SendRaw1(bad, static_cast<int>(strlen(bad)));
- EXPECT_TRUE(Receive1Fails());
- EXPECT_TRUE(Receive2Fails());
-}
-
-// Send a send request without a username and verify it is rejected.
-TEST_F(RelayServerTest, TestSendRequestMissingUsername) {
- Allocate();
- Bind();
-
- std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_SEND_REQUEST)), res;
- AddMagicCookieAttr(req.get());
-
- Send1(req.get());
- res.reset(Receive1());
-
- ASSERT_TRUE(res);
- EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
- EXPECT_EQ(req->transaction_id(), res->transaction_id());
-
- const StunErrorCodeAttribute* err = res->GetErrorCode();
- ASSERT_TRUE(err != NULL);
- EXPECT_EQ(4, err->eclass());
- EXPECT_EQ(32, err->number());
- EXPECT_EQ("Missing Username", err->reason());
-}
-
-// Send a send request with the wrong username and verify it is rejected.
-TEST_F(RelayServerTest, TestSendRequestBadUsername) {
- Allocate();
- Bind();
-
- std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_SEND_REQUEST)), res;
- AddMagicCookieAttr(req.get());
- AddUsernameAttr(req.get(), "foobarbizbaz");
-
- Send1(req.get());
- res.reset(Receive1());
-
- ASSERT_TRUE(res);
- EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
- EXPECT_EQ(req->transaction_id(), res->transaction_id());
-
- const StunErrorCodeAttribute* err = res->GetErrorCode();
- ASSERT_TRUE(err != NULL);
- EXPECT_EQ(4, err->eclass());
- EXPECT_EQ(30, err->number());
- EXPECT_EQ("Stale Credentials", err->reason());
-}
-
-// Send a send request without a destination address and verify that it is
-// rejected.
-TEST_F(RelayServerTest, TestSendRequestNoDestinationAddress) {
- Allocate();
- Bind();
-
- std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_SEND_REQUEST)), res;
- AddMagicCookieAttr(req.get());
- AddUsernameAttr(req.get(), username_);
-
- Send1(req.get());
- res.reset(Receive1());
-
- ASSERT_TRUE(res);
- EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
- EXPECT_EQ(req->transaction_id(), res->transaction_id());
-
- const StunErrorCodeAttribute* err = res->GetErrorCode();
- ASSERT_TRUE(err != NULL);
- EXPECT_EQ(4, err->eclass());
- EXPECT_EQ(0, err->number());
- EXPECT_EQ("Bad Request", err->reason());
-}
-
-// Send a send request without data and verify that it is rejected.
-TEST_F(RelayServerTest, TestSendRequestNoData) {
- Allocate();
- Bind();
-
- std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_SEND_REQUEST)), res;
- AddMagicCookieAttr(req.get());
- AddUsernameAttr(req.get(), username_);
- AddDestinationAttr(req.get(), client2_addr);
-
- Send1(req.get());
- res.reset(Receive1());
-
- ASSERT_TRUE(res);
- EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
- EXPECT_EQ(req->transaction_id(), res->transaction_id());
-
- const StunErrorCodeAttribute* err = res->GetErrorCode();
- ASSERT_TRUE(err != NULL);
- EXPECT_EQ(4, err->eclass());
- EXPECT_EQ(00, err->number());
- EXPECT_EQ("Bad Request", err->reason());
-}
-
-// Send a binding request after an allocate and verify that it is rejected.
-TEST_F(RelayServerTest, TestSendRequestWrongType) {
- Allocate();
- Bind();
-
- std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_BINDING_REQUEST)),
- res;
- AddMagicCookieAttr(req.get());
- AddUsernameAttr(req.get(), username_);
-
- Send1(req.get());
- res.reset(Receive1());
-
- ASSERT_TRUE(res);
- EXPECT_EQ(STUN_BINDING_ERROR_RESPONSE, res->type());
- EXPECT_EQ(req->transaction_id(), res->transaction_id());
-
- const StunErrorCodeAttribute* err = res->GetErrorCode();
- ASSERT_TRUE(err != NULL);
- EXPECT_EQ(6, err->eclass());
- EXPECT_EQ(0, err->number());
- EXPECT_EQ("Operation Not Supported", err->reason());
-}
-
-// Verify that we can send traffic back and forth between the clients after a
-// successful allocate and bind.
-TEST_F(RelayServerTest, TestSendRaw) {
- Allocate();
- Bind();
-
- for (int i = 0; i < 10; i++) {
- std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_SEND_REQUEST)), res;
- AddMagicCookieAttr(req.get());
- AddUsernameAttr(req.get(), username_);
- AddDestinationAttr(req.get(), client2_addr);
-
- auto send_data = StunAttribute::CreateByteString(STUN_ATTR_DATA);
- send_data->CopyBytes(msg1);
- req->AddAttribute(std::move(send_data));
-
- Send1(req.get());
- EXPECT_EQ(msg1, ReceiveRaw2());
- SendRaw2(msg2, static_cast<int>(strlen(msg2)));
- res.reset(Receive1());
-
- ASSERT_TRUE(res);
- EXPECT_EQ(STUN_DATA_INDICATION, res->type());
-
- const StunAddressAttribute* src_addr =
- res->GetAddress(STUN_ATTR_SOURCE_ADDRESS2);
- ASSERT_TRUE(src_addr != NULL);
- EXPECT_EQ(1, src_addr->family());
- EXPECT_EQ(client2_addr.ipaddr(), src_addr->ipaddr());
- EXPECT_EQ(client2_addr.port(), src_addr->port());
-
- const StunByteStringAttribute* recv_data =
- res->GetByteString(STUN_ATTR_DATA);
- ASSERT_TRUE(recv_data != NULL);
- EXPECT_EQ(strlen(msg2), recv_data->length());
- EXPECT_EQ(0, memcmp(msg2, recv_data->bytes(), recv_data->length()));
- }
-}
-
-// Verify that a binding expires properly, and rejects send requests.
-// Flaky, see https://code.google.com/p/webrtc/issues/detail?id=4134
-TEST_F(RelayServerTest, DISABLED_TestExpiration) {
- Allocate();
- Bind();
-
- // Wait twice the lifetime to make sure the server has expired the binding.
- rtc::Thread::Current()->ProcessMessages((LIFETIME * 2) * 1000);
-
- std::unique_ptr<StunMessage> req(CreateStunMessage(STUN_SEND_REQUEST)), res;
- AddMagicCookieAttr(req.get());
- AddUsernameAttr(req.get(), username_);
- AddDestinationAttr(req.get(), client2_addr);
-
- auto data_attr = StunAttribute::CreateByteString(STUN_ATTR_DATA);
- data_attr->CopyBytes(msg1);
- req->AddAttribute(std::move(data_attr));
-
- Send1(req.get());
- res.reset(Receive1());
-
- ASSERT_TRUE(res.get() != NULL);
- EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
-
- const StunErrorCodeAttribute* err = res->GetErrorCode();
- ASSERT_TRUE(err != NULL);
- EXPECT_EQ(6, err->eclass());
- EXPECT_EQ(0, err->number());
- EXPECT_EQ("Operation Not Supported", err->reason());
-
- // Also verify that traffic from the external client is ignored.
- SendRaw2(msg2, static_cast<int>(strlen(msg2)));
- EXPECT_TRUE(ReceiveRaw1().empty());
-}
-
-} // namespace cricket
diff --git a/p2p/base/test_relay_server.h b/p2p/base/test_relay_server.h
deleted file mode 100644
index be58251cd6..0000000000
--- a/p2p/base/test_relay_server.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright 2008 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.
- */
-
-#ifndef P2P_BASE_TEST_RELAY_SERVER_H_
-#define P2P_BASE_TEST_RELAY_SERVER_H_
-
-#include <memory>
-
-#include "p2p/base/relay_server.h"
-#include "rtc_base/async_tcp_socket.h"
-#include "rtc_base/server_socket_adapters.h"
-#include "rtc_base/third_party/sigslot/sigslot.h"
-#include "rtc_base/thread.h"
-
-namespace cricket {
-
-// A test relay server. Useful for unit tests.
-class TestRelayServer : public sigslot::has_slots<> {
- public:
- TestRelayServer(rtc::Thread* thread,
- const rtc::SocketAddress& udp_int_addr,
- const rtc::SocketAddress& udp_ext_addr,
- const rtc::SocketAddress& tcp_int_addr,
- const rtc::SocketAddress& tcp_ext_addr,
- const rtc::SocketAddress& ssl_int_addr,
- const rtc::SocketAddress& ssl_ext_addr)
- : server_(thread) {
- server_.AddInternalSocket(
- rtc::AsyncUDPSocket::Create(thread->socketserver(), udp_int_addr));
- server_.AddExternalSocket(
- rtc::AsyncUDPSocket::Create(thread->socketserver(), udp_ext_addr));
-
- tcp_int_socket_.reset(CreateListenSocket(thread, tcp_int_addr));
- tcp_ext_socket_.reset(CreateListenSocket(thread, tcp_ext_addr));
- ssl_int_socket_.reset(CreateListenSocket(thread, ssl_int_addr));
- ssl_ext_socket_.reset(CreateListenSocket(thread, ssl_ext_addr));
- }
- int GetConnectionCount() const { return server_.GetConnectionCount(); }
- rtc::SocketAddressPair GetConnection(int connection) const {
- return server_.GetConnection(connection);
- }
- bool HasConnection(const rtc::SocketAddress& address) const {
- return server_.HasConnection(address);
- }
-
- private:
- rtc::AsyncSocket* CreateListenSocket(rtc::Thread* thread,
- const rtc::SocketAddress& addr) {
- rtc::AsyncSocket* socket =
- thread->socketserver()->CreateAsyncSocket(addr.family(), SOCK_STREAM);
- socket->Bind(addr);
- socket->Listen(5);
- socket->SignalReadEvent.connect(this, &TestRelayServer::OnAccept);
- return socket;
- }
- void OnAccept(rtc::AsyncSocket* socket) {
- bool external =
- (socket == tcp_ext_socket_.get() || socket == ssl_ext_socket_.get());
- bool ssl =
- (socket == ssl_int_socket_.get() || socket == ssl_ext_socket_.get());
- rtc::AsyncSocket* raw_socket = socket->Accept(NULL);
- if (raw_socket) {
- rtc::AsyncTCPSocket* packet_socket = new rtc::AsyncTCPSocket(
- (!ssl) ? raw_socket : new rtc::AsyncSSLServerSocket(raw_socket),
- false);
- if (!external) {
- packet_socket->SignalClose.connect(this,
- &TestRelayServer::OnInternalClose);
- server_.AddInternalSocket(packet_socket);
- } else {
- packet_socket->SignalClose.connect(this,
- &TestRelayServer::OnExternalClose);
- server_.AddExternalSocket(packet_socket);
- }
- }
- }
- void OnInternalClose(rtc::AsyncPacketSocket* socket, int error) {
- server_.RemoveInternalSocket(socket);
- }
- void OnExternalClose(rtc::AsyncPacketSocket* socket, int error) {
- server_.RemoveExternalSocket(socket);
- }
-
- private:
- cricket::RelayServer server_;
- std::unique_ptr<rtc::AsyncSocket> tcp_int_socket_;
- std::unique_ptr<rtc::AsyncSocket> tcp_ext_socket_;
- std::unique_ptr<rtc::AsyncSocket> ssl_int_socket_;
- std::unique_ptr<rtc::AsyncSocket> ssl_ext_socket_;
-};
-
-} // namespace cricket
-
-#endif // P2P_BASE_TEST_RELAY_SERVER_H_
diff --git a/p2p/client/basic_port_allocator.cc b/p2p/client/basic_port_allocator.cc
index b2cc99a2b7..216e737ffb 100644
--- a/p2p/client/basic_port_allocator.cc
+++ b/p2p/client/basic_port_allocator.cc
@@ -20,7 +20,6 @@
#include "absl/algorithm/container.h"
#include "p2p/base/basic_packet_socket_factory.h"
#include "p2p/base/port.h"
-#include "p2p/base/relay_port.h"
#include "p2p/base/stun_port.h"
#include "p2p/base/tcp_port.h"
#include "p2p/base/turn_port.h"
@@ -1522,42 +1521,7 @@ void AllocationSequence::CreateRelayPorts() {
}
for (RelayServerConfig& relay : config_->relays) {
- if (relay.type == RELAY_GTURN) {
- CreateGturnPort(relay);
- } else if (relay.type == RELAY_TURN) {
- CreateTurnPort(relay);
- } else {
- RTC_NOTREACHED();
- }
- }
-}
-
-void AllocationSequence::CreateGturnPort(const RelayServerConfig& config) {
- // TODO(mallinath) - Rename RelayPort to GTurnPort.
- std::unique_ptr<RelayPort> port = RelayPort::Create(
- session_->network_thread(), session_->socket_factory(), network_,
- session_->allocator()->min_port(), session_->allocator()->max_port(),
- config_->username, config_->password);
- if (port) {
- RelayPort* port_ptr = port.release();
- // Since RelayPort is not created using shared socket, |port| will not be
- // added to the dequeue.
- // Note: We must add the allocated port before we add addresses because
- // the latter will create candidates that need name and preference
- // settings. However, we also can't prepare the address (normally
- // done by AddAllocatedPort) until we have these addresses. So we
- // wait to do that until below.
- session_->AddAllocatedPort(port_ptr, this, false);
-
- // Add the addresses of this protocol.
- PortList::const_iterator relay_port;
- for (relay_port = config.ports.begin(); relay_port != config.ports.end();
- ++relay_port) {
- port_ptr->AddServerAddress(*relay_port);
- port_ptr->AddExternalAddress(*relay_port);
- }
- // Start fetching an address for this port.
- port_ptr->PrepareAddress();
+ CreateTurnPort(relay);
}
}
@@ -1720,7 +1684,7 @@ ServerAddresses PortConfiguration::StunServers() {
// Every UDP TURN server should also be used as a STUN server if
// use_turn_server_as_stun_server is not disabled or the stun servers are
// empty.
- ServerAddresses turn_servers = GetRelayServerAddresses(RELAY_TURN, PROTO_UDP);
+ ServerAddresses turn_servers = GetRelayServerAddresses(PROTO_UDP);
for (const rtc::SocketAddress& turn_server : turn_servers) {
if (stun_servers.find(turn_server) == stun_servers.end()) {
stun_servers.insert(turn_server);
@@ -1744,21 +1708,19 @@ bool PortConfiguration::SupportsProtocol(const RelayServerConfig& relay,
return false;
}
-bool PortConfiguration::SupportsProtocol(RelayType turn_type,
- ProtocolType type) const {
+bool PortConfiguration::SupportsProtocol(ProtocolType type) const {
for (size_t i = 0; i < relays.size(); ++i) {
- if (relays[i].type == turn_type && SupportsProtocol(relays[i], type))
+ if (SupportsProtocol(relays[i], type))
return true;
}
return false;
}
ServerAddresses PortConfiguration::GetRelayServerAddresses(
- RelayType turn_type,
ProtocolType type) const {
ServerAddresses servers;
for (size_t i = 0; i < relays.size(); ++i) {
- if (relays[i].type == turn_type && SupportsProtocol(relays[i], type)) {
+ if (SupportsProtocol(relays[i], type)) {
servers.insert(relays[i].ports.front().address);
}
}
diff --git a/p2p/client/basic_port_allocator.h b/p2p/client/basic_port_allocator.h
index 274b89da48..ab47ce1030 100644
--- a/p2p/client/basic_port_allocator.h
+++ b/p2p/client/basic_port_allocator.h
@@ -316,11 +316,10 @@ struct RTC_EXPORT PortConfiguration : public rtc::MessageData {
// Determines whether the given relay server supports the given protocol.
bool SupportsProtocol(const RelayServerConfig& relay,
ProtocolType type) const;
- bool SupportsProtocol(RelayType turn_type, ProtocolType type) const;
+ bool SupportsProtocol(ProtocolType type) const;
// Helper method returns the server addresses for the matching RelayType and
// Protocol type.
- ServerAddresses GetRelayServerAddresses(RelayType turn_type,
- ProtocolType type) const;
+ ServerAddresses GetRelayServerAddresses(ProtocolType type) const;
};
class UDPPort;
@@ -388,7 +387,6 @@ class AllocationSequence : public rtc::MessageHandler,
void CreateTCPPorts();
void CreateStunPorts();
void CreateRelayPorts();
- void CreateGturnPort(const RelayServerConfig& config);
void OnReadPacket(rtc::AsyncPacketSocket* socket,
const char* data,
diff --git a/p2p/client/basic_port_allocator_unittest.cc b/p2p/client/basic_port_allocator_unittest.cc
index 1822432686..797778c73c 100644
--- a/p2p/client/basic_port_allocator_unittest.cc
+++ b/p2p/client/basic_port_allocator_unittest.cc
@@ -19,7 +19,6 @@
#include "p2p/base/stun_port.h"
#include "p2p/base/stun_request.h"
#include "p2p/base/stun_server.h"
-#include "p2p/base/test_relay_server.h"
#include "p2p/base/test_stun_server.h"
#include "p2p/base/test_turn_server.h"
#include "rtc_base/fake_clock.h"
@@ -218,7 +217,7 @@ class BasicPortAllocatorTestBase : public ::testing::Test,
RelayServerConfig CreateTurnServers(const rtc::SocketAddress& udp_turn,
const rtc::SocketAddress& tcp_turn) {
- RelayServerConfig turn_server(RELAY_TURN);
+ RelayServerConfig turn_server;
RelayCredentials credentials(kTurnUsername, kTurnPassword);
turn_server.credentials = credentials;
@@ -1778,7 +1777,7 @@ TEST_F(BasicPortAllocatorTestWithRealClock,
AddInterface(kClientAddr);
allocator_.reset(new BasicPortAllocator(&network_manager_));
allocator_->Initialize();
- RelayServerConfig turn_server(RELAY_TURN);
+ RelayServerConfig turn_server;
RelayCredentials credentials(kTurnUsername, kTurnPassword);
turn_server.credentials = credentials;
turn_server.ports.push_back(