1*d9f75844SAndroid Build Coastguard Worker /* 2*d9f75844SAndroid Build Coastguard Worker * Copyright 2012 The WebRTC Project Authors. All rights reserved. 3*d9f75844SAndroid Build Coastguard Worker * 4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license 5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source 6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found 7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may 8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree. 9*d9f75844SAndroid Build Coastguard Worker */ 10*d9f75844SAndroid Build Coastguard Worker 11*d9f75844SAndroid Build Coastguard Worker #ifndef P2P_BASE_TEST_TURN_SERVER_H_ 12*d9f75844SAndroid Build Coastguard Worker #define P2P_BASE_TEST_TURN_SERVER_H_ 13*d9f75844SAndroid Build Coastguard Worker 14*d9f75844SAndroid Build Coastguard Worker #include <memory> 15*d9f75844SAndroid Build Coastguard Worker #include <string> 16*d9f75844SAndroid Build Coastguard Worker #include <utility> 17*d9f75844SAndroid Build Coastguard Worker #include <vector> 18*d9f75844SAndroid Build Coastguard Worker 19*d9f75844SAndroid Build Coastguard Worker #include "absl/strings/string_view.h" 20*d9f75844SAndroid Build Coastguard Worker #include "api/sequence_checker.h" 21*d9f75844SAndroid Build Coastguard Worker #include "api/transport/stun.h" 22*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/basic_packet_socket_factory.h" 23*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/turn_server.h" 24*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/async_udp_socket.h" 25*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/ssl_adapter.h" 26*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/ssl_identity.h" 27*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/thread.h" 28*d9f75844SAndroid Build Coastguard Worker 29*d9f75844SAndroid Build Coastguard Worker namespace cricket { 30*d9f75844SAndroid Build Coastguard Worker 31*d9f75844SAndroid Build Coastguard Worker static const char kTestRealm[] = "example.org"; 32*d9f75844SAndroid Build Coastguard Worker static const char kTestSoftware[] = "TestTurnServer"; 33*d9f75844SAndroid Build Coastguard Worker 34*d9f75844SAndroid Build Coastguard Worker class TestTurnRedirector : public TurnRedirectInterface { 35*d9f75844SAndroid Build Coastguard Worker public: TestTurnRedirector(const std::vector<rtc::SocketAddress> & addresses)36*d9f75844SAndroid Build Coastguard Worker explicit TestTurnRedirector(const std::vector<rtc::SocketAddress>& addresses) 37*d9f75844SAndroid Build Coastguard Worker : alternate_server_addresses_(addresses), 38*d9f75844SAndroid Build Coastguard Worker iter_(alternate_server_addresses_.begin()) {} 39*d9f75844SAndroid Build Coastguard Worker ShouldRedirect(const rtc::SocketAddress &,rtc::SocketAddress * out)40*d9f75844SAndroid Build Coastguard Worker virtual bool ShouldRedirect(const rtc::SocketAddress&, 41*d9f75844SAndroid Build Coastguard Worker rtc::SocketAddress* out) { 42*d9f75844SAndroid Build Coastguard Worker if (!out || iter_ == alternate_server_addresses_.end()) { 43*d9f75844SAndroid Build Coastguard Worker return false; 44*d9f75844SAndroid Build Coastguard Worker } 45*d9f75844SAndroid Build Coastguard Worker *out = *iter_++; 46*d9f75844SAndroid Build Coastguard Worker return true; 47*d9f75844SAndroid Build Coastguard Worker } 48*d9f75844SAndroid Build Coastguard Worker 49*d9f75844SAndroid Build Coastguard Worker private: 50*d9f75844SAndroid Build Coastguard Worker const std::vector<rtc::SocketAddress>& alternate_server_addresses_; 51*d9f75844SAndroid Build Coastguard Worker std::vector<rtc::SocketAddress>::const_iterator iter_; 52*d9f75844SAndroid Build Coastguard Worker }; 53*d9f75844SAndroid Build Coastguard Worker 54*d9f75844SAndroid Build Coastguard Worker class TestTurnServer : public TurnAuthInterface { 55*d9f75844SAndroid Build Coastguard Worker public: 56*d9f75844SAndroid Build Coastguard Worker TestTurnServer(rtc::Thread* thread, 57*d9f75844SAndroid Build Coastguard Worker rtc::SocketFactory* socket_factory, 58*d9f75844SAndroid Build Coastguard Worker const rtc::SocketAddress& int_addr, 59*d9f75844SAndroid Build Coastguard Worker const rtc::SocketAddress& udp_ext_addr, 60*d9f75844SAndroid Build Coastguard Worker ProtocolType int_protocol = PROTO_UDP, 61*d9f75844SAndroid Build Coastguard Worker bool ignore_bad_cert = true, 62*d9f75844SAndroid Build Coastguard Worker absl::string_view common_name = "test turn server") server_(thread)63*d9f75844SAndroid Build Coastguard Worker : server_(thread), socket_factory_(socket_factory) { 64*d9f75844SAndroid Build Coastguard Worker AddInternalSocket(int_addr, int_protocol, ignore_bad_cert, common_name); 65*d9f75844SAndroid Build Coastguard Worker server_.SetExternalSocketFactory( 66*d9f75844SAndroid Build Coastguard Worker new rtc::BasicPacketSocketFactory(socket_factory), udp_ext_addr); 67*d9f75844SAndroid Build Coastguard Worker server_.set_realm(kTestRealm); 68*d9f75844SAndroid Build Coastguard Worker server_.set_software(kTestSoftware); 69*d9f75844SAndroid Build Coastguard Worker server_.set_auth_hook(this); 70*d9f75844SAndroid Build Coastguard Worker } 71*d9f75844SAndroid Build Coastguard Worker ~TestTurnServer()72*d9f75844SAndroid Build Coastguard Worker ~TestTurnServer() { RTC_DCHECK(thread_checker_.IsCurrent()); } 73*d9f75844SAndroid Build Coastguard Worker set_enable_otu_nonce(bool enable)74*d9f75844SAndroid Build Coastguard Worker void set_enable_otu_nonce(bool enable) { 75*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(thread_checker_.IsCurrent()); 76*d9f75844SAndroid Build Coastguard Worker server_.set_enable_otu_nonce(enable); 77*d9f75844SAndroid Build Coastguard Worker } 78*d9f75844SAndroid Build Coastguard Worker server()79*d9f75844SAndroid Build Coastguard Worker TurnServer* server() { 80*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(thread_checker_.IsCurrent()); 81*d9f75844SAndroid Build Coastguard Worker return &server_; 82*d9f75844SAndroid Build Coastguard Worker } 83*d9f75844SAndroid Build Coastguard Worker set_redirect_hook(TurnRedirectInterface * redirect_hook)84*d9f75844SAndroid Build Coastguard Worker void set_redirect_hook(TurnRedirectInterface* redirect_hook) { 85*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(thread_checker_.IsCurrent()); 86*d9f75844SAndroid Build Coastguard Worker server_.set_redirect_hook(redirect_hook); 87*d9f75844SAndroid Build Coastguard Worker } 88*d9f75844SAndroid Build Coastguard Worker set_enable_permission_checks(bool enable)89*d9f75844SAndroid Build Coastguard Worker void set_enable_permission_checks(bool enable) { 90*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(thread_checker_.IsCurrent()); 91*d9f75844SAndroid Build Coastguard Worker server_.set_enable_permission_checks(enable); 92*d9f75844SAndroid Build Coastguard Worker } 93*d9f75844SAndroid Build Coastguard Worker 94*d9f75844SAndroid Build Coastguard Worker void AddInternalSocket(const rtc::SocketAddress& int_addr, 95*d9f75844SAndroid Build Coastguard Worker ProtocolType proto, 96*d9f75844SAndroid Build Coastguard Worker bool ignore_bad_cert = true, 97*d9f75844SAndroid Build Coastguard Worker absl::string_view common_name = "test turn server") { 98*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(thread_checker_.IsCurrent()); 99*d9f75844SAndroid Build Coastguard Worker if (proto == cricket::PROTO_UDP) { 100*d9f75844SAndroid Build Coastguard Worker server_.AddInternalSocket( 101*d9f75844SAndroid Build Coastguard Worker rtc::AsyncUDPSocket::Create(socket_factory_, int_addr), proto); 102*d9f75844SAndroid Build Coastguard Worker } else if (proto == cricket::PROTO_TCP || proto == cricket::PROTO_TLS) { 103*d9f75844SAndroid Build Coastguard Worker // For TCP we need to create a server socket which can listen for incoming 104*d9f75844SAndroid Build Coastguard Worker // new connections. 105*d9f75844SAndroid Build Coastguard Worker rtc::Socket* socket = socket_factory_->CreateSocket(AF_INET, SOCK_STREAM); 106*d9f75844SAndroid Build Coastguard Worker socket->Bind(int_addr); 107*d9f75844SAndroid Build Coastguard Worker socket->Listen(5); 108*d9f75844SAndroid Build Coastguard Worker if (proto == cricket::PROTO_TLS) { 109*d9f75844SAndroid Build Coastguard Worker // For TLS, wrap the TCP socket with an SSL adapter. The adapter must 110*d9f75844SAndroid Build Coastguard Worker // be configured with a self-signed certificate for testing. 111*d9f75844SAndroid Build Coastguard Worker // Additionally, the client will not present a valid certificate, so we 112*d9f75844SAndroid Build Coastguard Worker // must not fail when checking the peer's identity. 113*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<rtc::SSLAdapterFactory> ssl_adapter_factory = 114*d9f75844SAndroid Build Coastguard Worker rtc::SSLAdapterFactory::Create(); 115*d9f75844SAndroid Build Coastguard Worker ssl_adapter_factory->SetRole(rtc::SSL_SERVER); 116*d9f75844SAndroid Build Coastguard Worker ssl_adapter_factory->SetIdentity( 117*d9f75844SAndroid Build Coastguard Worker rtc::SSLIdentity::Create(common_name, rtc::KeyParams())); 118*d9f75844SAndroid Build Coastguard Worker ssl_adapter_factory->SetIgnoreBadCert(ignore_bad_cert); 119*d9f75844SAndroid Build Coastguard Worker server_.AddInternalServerSocket(socket, proto, 120*d9f75844SAndroid Build Coastguard Worker std::move(ssl_adapter_factory)); 121*d9f75844SAndroid Build Coastguard Worker } else { 122*d9f75844SAndroid Build Coastguard Worker server_.AddInternalServerSocket(socket, proto); 123*d9f75844SAndroid Build Coastguard Worker } 124*d9f75844SAndroid Build Coastguard Worker } else { 125*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_NOTREACHED() << "Unknown protocol type: " << proto; 126*d9f75844SAndroid Build Coastguard Worker } 127*d9f75844SAndroid Build Coastguard Worker } 128*d9f75844SAndroid Build Coastguard Worker 129*d9f75844SAndroid Build Coastguard Worker // Finds the first allocation in the server allocation map with a source 130*d9f75844SAndroid Build Coastguard Worker // ip and port matching the socket address provided. FindAllocation(const rtc::SocketAddress & src)131*d9f75844SAndroid Build Coastguard Worker TurnServerAllocation* FindAllocation(const rtc::SocketAddress& src) { 132*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(thread_checker_.IsCurrent()); 133*d9f75844SAndroid Build Coastguard Worker const TurnServer::AllocationMap& map = server_.allocations(); 134*d9f75844SAndroid Build Coastguard Worker for (TurnServer::AllocationMap::const_iterator it = map.begin(); 135*d9f75844SAndroid Build Coastguard Worker it != map.end(); ++it) { 136*d9f75844SAndroid Build Coastguard Worker if (src == it->first.src()) { 137*d9f75844SAndroid Build Coastguard Worker return it->second.get(); 138*d9f75844SAndroid Build Coastguard Worker } 139*d9f75844SAndroid Build Coastguard Worker } 140*d9f75844SAndroid Build Coastguard Worker return NULL; 141*d9f75844SAndroid Build Coastguard Worker } 142*d9f75844SAndroid Build Coastguard Worker 143*d9f75844SAndroid Build Coastguard Worker private: 144*d9f75844SAndroid Build Coastguard Worker // For this test server, succeed if the password is the same as the username. 145*d9f75844SAndroid Build Coastguard Worker // Obviously, do not use this in a production environment. GetKey(absl::string_view username,absl::string_view realm,std::string * key)146*d9f75844SAndroid Build Coastguard Worker virtual bool GetKey(absl::string_view username, 147*d9f75844SAndroid Build Coastguard Worker absl::string_view realm, 148*d9f75844SAndroid Build Coastguard Worker std::string* key) { 149*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(thread_checker_.IsCurrent()); 150*d9f75844SAndroid Build Coastguard Worker return ComputeStunCredentialHash(std::string(username), std::string(realm), 151*d9f75844SAndroid Build Coastguard Worker std::string(username), key); 152*d9f75844SAndroid Build Coastguard Worker } 153*d9f75844SAndroid Build Coastguard Worker 154*d9f75844SAndroid Build Coastguard Worker TurnServer server_; 155*d9f75844SAndroid Build Coastguard Worker rtc::SocketFactory* socket_factory_; 156*d9f75844SAndroid Build Coastguard Worker webrtc::SequenceChecker thread_checker_; 157*d9f75844SAndroid Build Coastguard Worker }; 158*d9f75844SAndroid Build Coastguard Worker 159*d9f75844SAndroid Build Coastguard Worker } // namespace cricket 160*d9f75844SAndroid Build Coastguard Worker 161*d9f75844SAndroid Build Coastguard Worker #endif // P2P_BASE_TEST_TURN_SERVER_H_ 162