1 /* 2 * Copyright 2012 The WebRTC Project Authors. All rights reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #ifndef WEBRTC_P2P_BASE_TESTTURNSERVER_H_ 12 #define WEBRTC_P2P_BASE_TESTTURNSERVER_H_ 13 14 #include <string> 15 #include <vector> 16 17 #include "webrtc/p2p/base/basicpacketsocketfactory.h" 18 #include "webrtc/p2p/base/stun.h" 19 #include "webrtc/p2p/base/turnserver.h" 20 #include "webrtc/base/asyncudpsocket.h" 21 #include "webrtc/base/thread.h" 22 23 namespace cricket { 24 25 static const char kTestRealm[] = "example.org"; 26 static const char kTestSoftware[] = "TestTurnServer"; 27 28 class TestTurnRedirector : public TurnRedirectInterface { 29 public: TestTurnRedirector(const std::vector<rtc::SocketAddress> & addresses)30 explicit TestTurnRedirector(const std::vector<rtc::SocketAddress>& addresses) 31 : alternate_server_addresses_(addresses), 32 iter_(alternate_server_addresses_.begin()) { 33 } 34 ShouldRedirect(const rtc::SocketAddress &,rtc::SocketAddress * out)35 virtual bool ShouldRedirect(const rtc::SocketAddress&, 36 rtc::SocketAddress* out) { 37 if (!out || iter_ == alternate_server_addresses_.end()) { 38 return false; 39 } 40 *out = *iter_++; 41 return true; 42 } 43 44 private: 45 const std::vector<rtc::SocketAddress>& alternate_server_addresses_; 46 std::vector<rtc::SocketAddress>::const_iterator iter_; 47 }; 48 49 class TestTurnServer : public TurnAuthInterface { 50 public: TestTurnServer(rtc::Thread * thread,const rtc::SocketAddress & udp_int_addr,const rtc::SocketAddress & udp_ext_addr)51 TestTurnServer(rtc::Thread* thread, 52 const rtc::SocketAddress& udp_int_addr, 53 const rtc::SocketAddress& udp_ext_addr) 54 : server_(thread) { 55 AddInternalSocket(udp_int_addr, cricket::PROTO_UDP); 56 server_.SetExternalSocketFactory(new rtc::BasicPacketSocketFactory(), 57 udp_ext_addr); 58 server_.set_realm(kTestRealm); 59 server_.set_software(kTestSoftware); 60 server_.set_auth_hook(this); 61 } 62 set_enable_otu_nonce(bool enable)63 void set_enable_otu_nonce(bool enable) { 64 server_.set_enable_otu_nonce(enable); 65 } 66 server()67 TurnServer* server() { return &server_; } 68 set_redirect_hook(TurnRedirectInterface * redirect_hook)69 void set_redirect_hook(TurnRedirectInterface* redirect_hook) { 70 server_.set_redirect_hook(redirect_hook); 71 } 72 AddInternalSocket(const rtc::SocketAddress & int_addr,ProtocolType proto)73 void AddInternalSocket(const rtc::SocketAddress& int_addr, 74 ProtocolType proto) { 75 rtc::Thread* thread = rtc::Thread::Current(); 76 if (proto == cricket::PROTO_UDP) { 77 server_.AddInternalSocket(rtc::AsyncUDPSocket::Create( 78 thread->socketserver(), int_addr), proto); 79 } else if (proto == cricket::PROTO_TCP) { 80 // For TCP we need to create a server socket which can listen for incoming 81 // new connections. 82 rtc::AsyncSocket* socket = 83 thread->socketserver()->CreateAsyncSocket(SOCK_STREAM); 84 socket->Bind(int_addr); 85 socket->Listen(5); 86 server_.AddInternalServerSocket(socket, proto); 87 } 88 } 89 90 // Finds the first allocation in the server allocation map with a source 91 // ip and port matching the socket address provided. FindAllocation(const rtc::SocketAddress & src)92 TurnServerAllocation* FindAllocation(const rtc::SocketAddress& src) { 93 const TurnServer::AllocationMap& map = server_.allocations(); 94 for (TurnServer::AllocationMap::const_iterator it = map.begin(); 95 it != map.end(); ++it) { 96 if (src == it->first.src()) { 97 return it->second; 98 } 99 } 100 return NULL; 101 } 102 103 private: 104 // For this test server, succeed if the password is the same as the username. 105 // Obviously, do not use this in a production environment. GetKey(const std::string & username,const std::string & realm,std::string * key)106 virtual bool GetKey(const std::string& username, const std::string& realm, 107 std::string* key) { 108 return ComputeStunCredentialHash(username, realm, username, key); 109 } 110 111 TurnServer server_; 112 }; 113 114 } // namespace cricket 115 116 #endif // WEBRTC_P2P_BASE_TESTTURNSERVER_H_ 117