Home | History | Annotate | Download | only in base
      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:
     30   explicit TestTurnRedirector(const std::vector<rtc::SocketAddress>& addresses)
     31       : alternate_server_addresses_(addresses),
     32         iter_(alternate_server_addresses_.begin()) {
     33   }
     34 
     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:
     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 
     63   void set_enable_otu_nonce(bool enable) {
     64     server_.set_enable_otu_nonce(enable);
     65   }
     66 
     67   TurnServer* server() { return &server_; }
     68 
     69   void set_redirect_hook(TurnRedirectInterface* redirect_hook) {
     70     server_.set_redirect_hook(redirect_hook);
     71   }
     72 
     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.
     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.
    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