1 /* 2 * libjingle 3 * Copyright 2008 Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #ifndef TALK_P2P_BASE_TESTRELAYSERVER_H_ 29 #define TALK_P2P_BASE_TESTRELAYSERVER_H_ 30 31 #include "talk/p2p/base/relayserver.h" 32 #include "webrtc/base/asynctcpsocket.h" 33 #include "webrtc/base/scoped_ptr.h" 34 #include "webrtc/base/sigslot.h" 35 #include "webrtc/base/socketadapters.h" 36 #include "webrtc/base/thread.h" 37 38 namespace cricket { 39 40 // A test relay server. Useful for unit tests. 41 class TestRelayServer : public sigslot::has_slots<> { 42 public: 43 TestRelayServer(rtc::Thread* thread, 44 const rtc::SocketAddress& udp_int_addr, 45 const rtc::SocketAddress& udp_ext_addr, 46 const rtc::SocketAddress& tcp_int_addr, 47 const rtc::SocketAddress& tcp_ext_addr, 48 const rtc::SocketAddress& ssl_int_addr, 49 const rtc::SocketAddress& ssl_ext_addr) 50 : server_(thread) { 51 server_.AddInternalSocket(rtc::AsyncUDPSocket::Create( 52 thread->socketserver(), udp_int_addr)); 53 server_.AddExternalSocket(rtc::AsyncUDPSocket::Create( 54 thread->socketserver(), udp_ext_addr)); 55 56 tcp_int_socket_.reset(CreateListenSocket(thread, tcp_int_addr)); 57 tcp_ext_socket_.reset(CreateListenSocket(thread, tcp_ext_addr)); 58 ssl_int_socket_.reset(CreateListenSocket(thread, ssl_int_addr)); 59 ssl_ext_socket_.reset(CreateListenSocket(thread, ssl_ext_addr)); 60 } 61 int GetConnectionCount() const { 62 return server_.GetConnectionCount(); 63 } 64 rtc::SocketAddressPair GetConnection(int connection) const { 65 return server_.GetConnection(connection); 66 } 67 bool HasConnection(const rtc::SocketAddress& address) const { 68 return server_.HasConnection(address); 69 } 70 71 private: 72 rtc::AsyncSocket* CreateListenSocket(rtc::Thread* thread, 73 const rtc::SocketAddress& addr) { 74 rtc::AsyncSocket* socket = 75 thread->socketserver()->CreateAsyncSocket(addr.family(), SOCK_STREAM); 76 socket->Bind(addr); 77 socket->Listen(5); 78 socket->SignalReadEvent.connect(this, &TestRelayServer::OnAccept); 79 return socket; 80 } 81 void OnAccept(rtc::AsyncSocket* socket) { 82 bool external = (socket == tcp_ext_socket_.get() || 83 socket == ssl_ext_socket_.get()); 84 bool ssl = (socket == ssl_int_socket_.get() || 85 socket == ssl_ext_socket_.get()); 86 rtc::AsyncSocket* raw_socket = socket->Accept(NULL); 87 if (raw_socket) { 88 rtc::AsyncTCPSocket* packet_socket = new rtc::AsyncTCPSocket( 89 (!ssl) ? raw_socket : 90 new rtc::AsyncSSLServerSocket(raw_socket), false); 91 if (!external) { 92 packet_socket->SignalClose.connect(this, 93 &TestRelayServer::OnInternalClose); 94 server_.AddInternalSocket(packet_socket); 95 } else { 96 packet_socket->SignalClose.connect(this, 97 &TestRelayServer::OnExternalClose); 98 server_.AddExternalSocket(packet_socket); 99 } 100 } 101 } 102 void OnInternalClose(rtc::AsyncPacketSocket* socket, int error) { 103 server_.RemoveInternalSocket(socket); 104 } 105 void OnExternalClose(rtc::AsyncPacketSocket* socket, int error) { 106 server_.RemoveExternalSocket(socket); 107 } 108 private: 109 cricket::RelayServer server_; 110 rtc::scoped_ptr<rtc::AsyncSocket> tcp_int_socket_; 111 rtc::scoped_ptr<rtc::AsyncSocket> tcp_ext_socket_; 112 rtc::scoped_ptr<rtc::AsyncSocket> ssl_int_socket_; 113 rtc::scoped_ptr<rtc::AsyncSocket> ssl_ext_socket_; 114 }; 115 116 } // namespace cricket 117 118 #endif // TALK_P2P_BASE_TESTRELAYSERVER_H_ 119