Home | History | Annotate | Download | only in base
      1 /*
      2  *  Copyright 2004 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_RELAYSERVER_H_
     12 #define WEBRTC_P2P_BASE_RELAYSERVER_H_
     13 
     14 #include <map>
     15 #include <string>
     16 #include <vector>
     17 
     18 #include "webrtc/p2p/base/port.h"
     19 #include "webrtc/p2p/base/stun.h"
     20 #include "webrtc/base/asyncudpsocket.h"
     21 #include "webrtc/base/socketaddresspair.h"
     22 #include "webrtc/base/thread.h"
     23 #include "webrtc/base/timeutils.h"
     24 
     25 namespace cricket {
     26 
     27 class RelayServerBinding;
     28 class RelayServerConnection;
     29 
     30 // Relays traffic between connections to the server that are "bound" together.
     31 // All connections created with the same username/password are bound together.
     32 class RelayServer : public rtc::MessageHandler,
     33                     public sigslot::has_slots<> {
     34  public:
     35   // Creates a server, which will use this thread to post messages to itself.
     36   explicit RelayServer(rtc::Thread* thread);
     37   ~RelayServer();
     38 
     39   rtc::Thread* thread() { return thread_; }
     40 
     41   // Indicates whether we will print updates of the number of bindings.
     42   bool log_bindings() const { return log_bindings_; }
     43   void set_log_bindings(bool log_bindings) { log_bindings_ = log_bindings; }
     44 
     45   // Updates the set of sockets that the server uses to talk to "internal"
     46   // clients.  These are clients that do the "port allocations".
     47   void AddInternalSocket(rtc::AsyncPacketSocket* socket);
     48   void RemoveInternalSocket(rtc::AsyncPacketSocket* socket);
     49 
     50   // Updates the set of sockets that the server uses to talk to "external"
     51   // clients.  These are the clients that do not do allocations.  They do not
     52   // know that these addresses represent a relay server.
     53   void AddExternalSocket(rtc::AsyncPacketSocket* socket);
     54   void RemoveExternalSocket(rtc::AsyncPacketSocket* socket);
     55 
     56   // Starts listening for connections on this sockets. When someone
     57   // tries to connect, the connection will be accepted and a new
     58   // internal socket will be added.
     59   void AddInternalServerSocket(rtc::AsyncSocket* socket,
     60                                cricket::ProtocolType proto);
     61 
     62   // Removes this server socket from the list.
     63   void RemoveInternalServerSocket(rtc::AsyncSocket* socket);
     64 
     65   // Methods for testing and debuging.
     66   int GetConnectionCount() const;
     67   rtc::SocketAddressPair GetConnection(int connection) const;
     68   bool HasConnection(const rtc::SocketAddress& address) const;
     69 
     70  private:
     71   typedef std::vector<rtc::AsyncPacketSocket*> SocketList;
     72   typedef std::map<rtc::AsyncSocket*,
     73                    cricket::ProtocolType> ServerSocketMap;
     74   typedef std::map<std::string, RelayServerBinding*> BindingMap;
     75   typedef std::map<rtc::SocketAddressPair,
     76                    RelayServerConnection*> ConnectionMap;
     77 
     78   rtc::Thread* thread_;
     79   bool log_bindings_;
     80   SocketList internal_sockets_;
     81   SocketList external_sockets_;
     82   SocketList removed_sockets_;
     83   ServerSocketMap server_sockets_;
     84   BindingMap bindings_;
     85   ConnectionMap connections_;
     86 
     87   // Called when a packet is received by the server on one of its sockets.
     88   void OnInternalPacket(rtc::AsyncPacketSocket* socket,
     89                         const char* bytes, size_t size,
     90                         const rtc::SocketAddress& remote_addr,
     91                         const rtc::PacketTime& packet_time);
     92   void OnExternalPacket(rtc::AsyncPacketSocket* socket,
     93                         const char* bytes, size_t size,
     94                         const rtc::SocketAddress& remote_addr,
     95                         const rtc::PacketTime& packet_time);
     96 
     97   void OnReadEvent(rtc::AsyncSocket* socket);
     98 
     99   // Processes the relevant STUN request types from the client.
    100   bool HandleStun(const char* bytes, size_t size,
    101                   const rtc::SocketAddress& remote_addr,
    102                   rtc::AsyncPacketSocket* socket,
    103                   std::string* username, StunMessage* msg);
    104   void HandleStunAllocate(const char* bytes, size_t size,
    105                           const rtc::SocketAddressPair& ap,
    106                           rtc::AsyncPacketSocket* socket);
    107   void HandleStun(RelayServerConnection* int_conn, const char* bytes,
    108                   size_t size);
    109   void HandleStunAllocate(RelayServerConnection* int_conn,
    110                           const StunMessage& msg);
    111   void HandleStunSend(RelayServerConnection* int_conn, const StunMessage& msg);
    112 
    113   // Adds/Removes the a connection or binding.
    114   void AddConnection(RelayServerConnection* conn);
    115   void RemoveConnection(RelayServerConnection* conn);
    116   void RemoveBinding(RelayServerBinding* binding);
    117 
    118   // Handle messages in our worker thread.
    119   void OnMessage(rtc::Message *pmsg);
    120 
    121   // Called when the timer for checking lifetime times out.
    122   void OnTimeout(RelayServerBinding* binding);
    123 
    124   // Accept connections on this server socket.
    125   void AcceptConnection(rtc::AsyncSocket* server_socket);
    126 
    127   friend class RelayServerConnection;
    128   friend class RelayServerBinding;
    129 };
    130 
    131 // Maintains information about a connection to the server.  Each connection is
    132 // part of one and only one binding.
    133 class RelayServerConnection {
    134  public:
    135   RelayServerConnection(RelayServerBinding* binding,
    136                         const rtc::SocketAddressPair& addrs,
    137                         rtc::AsyncPacketSocket* socket);
    138   ~RelayServerConnection();
    139 
    140   RelayServerBinding* binding() { return binding_; }
    141   rtc::AsyncPacketSocket* socket() { return socket_; }
    142 
    143   // Returns a pair where the source is the remote address and the destination
    144   // is the local address.
    145   const rtc::SocketAddressPair& addr_pair() { return addr_pair_; }
    146 
    147   // Sends a packet to the connected client.  If an address is provided, then
    148   // we make sure the internal client receives it, wrapping if necessary.
    149   void Send(const char* data, size_t size);
    150   void Send(const char* data, size_t size,
    151             const rtc::SocketAddress& ext_addr);
    152 
    153   // Sends a STUN message to the connected client with no wrapping.
    154   void SendStun(const StunMessage& msg);
    155   void SendStunError(const StunMessage& request, int code, const char* desc);
    156 
    157   // A locked connection is one for which we know the intended destination of
    158   // any raw packet received.
    159   bool locked() const { return locked_; }
    160   void Lock();
    161   void Unlock();
    162 
    163   // Records the address that raw packets should be forwarded to (for internal
    164   // packets only; for external, we already know where they go).
    165   const rtc::SocketAddress& default_destination() const {
    166     return default_dest_;
    167   }
    168   void set_default_destination(const rtc::SocketAddress& addr) {
    169     default_dest_ = addr;
    170   }
    171 
    172  private:
    173   RelayServerBinding* binding_;
    174   rtc::SocketAddressPair addr_pair_;
    175   rtc::AsyncPacketSocket* socket_;
    176   bool locked_;
    177   rtc::SocketAddress default_dest_;
    178 };
    179 
    180 // Records a set of internal and external connections that we relay between,
    181 // or in other words, that are "bound" together.
    182 class RelayServerBinding : public rtc::MessageHandler {
    183  public:
    184   RelayServerBinding(RelayServer* server,
    185                      const std::string& username,
    186                      const std::string& password,
    187                      uint32_t lifetime);
    188   virtual ~RelayServerBinding();
    189 
    190   RelayServer* server() { return server_; }
    191   uint32_t lifetime() { return lifetime_; }
    192   const std::string& username() { return username_; }
    193   const std::string& password() { return password_; }
    194   const std::string& magic_cookie() { return magic_cookie_; }
    195 
    196   // Adds/Removes a connection into the binding.
    197   void AddInternalConnection(RelayServerConnection* conn);
    198   void AddExternalConnection(RelayServerConnection* conn);
    199 
    200   // We keep track of the use of each binding.  If we detect that it was not
    201   // used for longer than the lifetime, then we send a signal.
    202   void NoteUsed();
    203   sigslot::signal1<RelayServerBinding*> SignalTimeout;
    204 
    205   // Determines whether the given packet has the magic cookie present (in the
    206   // right place).
    207   bool HasMagicCookie(const char* bytes, size_t size) const;
    208 
    209   // Determines the connection to use to send packets to or from the given
    210   // external address.
    211   RelayServerConnection* GetInternalConnection(
    212       const rtc::SocketAddress& ext_addr);
    213   RelayServerConnection* GetExternalConnection(
    214       const rtc::SocketAddress& ext_addr);
    215 
    216   // MessageHandler:
    217   void OnMessage(rtc::Message *pmsg);
    218 
    219  private:
    220   RelayServer* server_;
    221 
    222   std::string username_;
    223   std::string password_;
    224   std::string magic_cookie_;
    225 
    226   std::vector<RelayServerConnection*> internal_connections_;
    227   std::vector<RelayServerConnection*> external_connections_;
    228 
    229   uint32_t lifetime_;
    230   uint32_t last_used_;
    231   // TODO: bandwidth
    232 };
    233 
    234 }  // namespace cricket
    235 
    236 #endif  // WEBRTC_P2P_BASE_RELAYSERVER_H_
    237