Home | History | Annotate | Download | only in base
      1 /*
      2  *  Copyright 2008 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_TESTRELAYSERVER_H_
     12 #define WEBRTC_P2P_BASE_TESTRELAYSERVER_H_
     13 
     14 #include "webrtc/p2p/base/relayserver.h"
     15 #include "webrtc/base/asynctcpsocket.h"
     16 #include "webrtc/base/scoped_ptr.h"
     17 #include "webrtc/base/sigslot.h"
     18 #include "webrtc/base/socketadapters.h"
     19 #include "webrtc/base/thread.h"
     20 
     21 namespace cricket {
     22 
     23 // A test relay server. Useful for unit tests.
     24 class TestRelayServer : public sigslot::has_slots<> {
     25  public:
     26   TestRelayServer(rtc::Thread* thread,
     27                   const rtc::SocketAddress& udp_int_addr,
     28                   const rtc::SocketAddress& udp_ext_addr,
     29                   const rtc::SocketAddress& tcp_int_addr,
     30                   const rtc::SocketAddress& tcp_ext_addr,
     31                   const rtc::SocketAddress& ssl_int_addr,
     32                   const rtc::SocketAddress& ssl_ext_addr)
     33       : server_(thread) {
     34     server_.AddInternalSocket(rtc::AsyncUDPSocket::Create(
     35         thread->socketserver(), udp_int_addr));
     36     server_.AddExternalSocket(rtc::AsyncUDPSocket::Create(
     37         thread->socketserver(), udp_ext_addr));
     38 
     39     tcp_int_socket_.reset(CreateListenSocket(thread, tcp_int_addr));
     40     tcp_ext_socket_.reset(CreateListenSocket(thread, tcp_ext_addr));
     41     ssl_int_socket_.reset(CreateListenSocket(thread, ssl_int_addr));
     42     ssl_ext_socket_.reset(CreateListenSocket(thread, ssl_ext_addr));
     43   }
     44   int GetConnectionCount() const {
     45     return server_.GetConnectionCount();
     46   }
     47   rtc::SocketAddressPair GetConnection(int connection) const {
     48     return server_.GetConnection(connection);
     49   }
     50   bool HasConnection(const rtc::SocketAddress& address) const {
     51     return server_.HasConnection(address);
     52   }
     53 
     54  private:
     55   rtc::AsyncSocket* CreateListenSocket(rtc::Thread* thread,
     56       const rtc::SocketAddress& addr) {
     57     rtc::AsyncSocket* socket =
     58         thread->socketserver()->CreateAsyncSocket(addr.family(), SOCK_STREAM);
     59     socket->Bind(addr);
     60     socket->Listen(5);
     61     socket->SignalReadEvent.connect(this, &TestRelayServer::OnAccept);
     62     return socket;
     63   }
     64   void OnAccept(rtc::AsyncSocket* socket) {
     65     bool external = (socket == tcp_ext_socket_.get() ||
     66                      socket == ssl_ext_socket_.get());
     67     bool ssl = (socket == ssl_int_socket_.get() ||
     68                 socket == ssl_ext_socket_.get());
     69     rtc::AsyncSocket* raw_socket = socket->Accept(NULL);
     70     if (raw_socket) {
     71       rtc::AsyncTCPSocket* packet_socket = new rtc::AsyncTCPSocket(
     72           (!ssl) ? raw_socket :
     73           new rtc::AsyncSSLServerSocket(raw_socket), false);
     74       if (!external) {
     75         packet_socket->SignalClose.connect(this,
     76             &TestRelayServer::OnInternalClose);
     77         server_.AddInternalSocket(packet_socket);
     78       } else {
     79         packet_socket->SignalClose.connect(this,
     80             &TestRelayServer::OnExternalClose);
     81         server_.AddExternalSocket(packet_socket);
     82       }
     83     }
     84   }
     85   void OnInternalClose(rtc::AsyncPacketSocket* socket, int error) {
     86     server_.RemoveInternalSocket(socket);
     87   }
     88   void OnExternalClose(rtc::AsyncPacketSocket* socket, int error) {
     89     server_.RemoveExternalSocket(socket);
     90   }
     91  private:
     92   cricket::RelayServer server_;
     93   rtc::scoped_ptr<rtc::AsyncSocket> tcp_int_socket_;
     94   rtc::scoped_ptr<rtc::AsyncSocket> tcp_ext_socket_;
     95   rtc::scoped_ptr<rtc::AsyncSocket> ssl_int_socket_;
     96   rtc::scoped_ptr<rtc::AsyncSocket> ssl_ext_socket_;
     97 };
     98 
     99 }  // namespace cricket
    100 
    101 #endif  // WEBRTC_P2P_BASE_TESTRELAYSERVER_H_
    102