• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
thread()39   rtc::Thread* thread() { return thread_; }
40 
41   // Indicates whether we will print updates of the number of bindings.
log_bindings()42   bool log_bindings() const { return log_bindings_; }
set_log_bindings(bool 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 
binding()140   RelayServerBinding* binding() { return binding_; }
socket()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.
addr_pair()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.
locked()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).
default_destination()165   const rtc::SocketAddress& default_destination() const {
166     return default_dest_;
167   }
set_default_destination(const rtc::SocketAddress & addr)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 
server()190   RelayServer* server() { return server_; }
lifetime()191   uint32_t lifetime() { return lifetime_; }
username()192   const std::string& username() { return username_; }
password()193   const std::string& password() { return password_; }
magic_cookie()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