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_TURNSERVER_H_
12#define WEBRTC_P2P_BASE_TURNSERVER_H_
13
14#include <list>
15#include <map>
16#include <set>
17#include <string>
18
19#include "webrtc/p2p/base/portinterface.h"
20#include "webrtc/base/asyncpacketsocket.h"
21#include "webrtc/base/messagequeue.h"
22#include "webrtc/base/sigslot.h"
23#include "webrtc/base/socketaddress.h"
24
25namespace rtc {
26class ByteBuffer;
27class PacketSocketFactory;
28class Thread;
29}
30
31namespace cricket {
32
33class StunMessage;
34class TurnMessage;
35class TurnServer;
36
37// The default server port for TURN, as specified in RFC5766.
38const int TURN_SERVER_PORT = 3478;
39
40// Encapsulates the client's connection to the server.
41class TurnServerConnection {
42 public:
43  TurnServerConnection() : proto_(PROTO_UDP), socket_(NULL) {}
44  TurnServerConnection(const rtc::SocketAddress& src,
45                       ProtocolType proto,
46                       rtc::AsyncPacketSocket* socket);
47  const rtc::SocketAddress& src() const { return src_; }
48  rtc::AsyncPacketSocket* socket() { return socket_; }
49  bool operator==(const TurnServerConnection& t) const;
50  bool operator<(const TurnServerConnection& t) const;
51  std::string ToString() const;
52
53 private:
54  rtc::SocketAddress src_;
55  rtc::SocketAddress dst_;
56  cricket::ProtocolType proto_;
57  rtc::AsyncPacketSocket* socket_;
58};
59
60// Encapsulates a TURN allocation.
61// The object is created when an allocation request is received, and then
62// handles TURN messages (via HandleTurnMessage) and channel data messages
63// (via HandleChannelData) for this allocation when received by the server.
64// The object self-deletes and informs the server if its lifetime timer expires.
65class TurnServerAllocation : public rtc::MessageHandler,
66                             public sigslot::has_slots<> {
67 public:
68  TurnServerAllocation(TurnServer* server_,
69                       rtc::Thread* thread,
70                       const TurnServerConnection& conn,
71                       rtc::AsyncPacketSocket* server_socket,
72                       const std::string& key);
73  virtual ~TurnServerAllocation();
74
75  TurnServerConnection* conn() { return &conn_; }
76  const std::string& key() const { return key_; }
77  const std::string& transaction_id() const { return transaction_id_; }
78  const std::string& username() const { return username_; }
79  const std::string& origin() const { return origin_; }
80  const std::string& last_nonce() const { return last_nonce_; }
81  void set_last_nonce(const std::string& nonce) { last_nonce_ = nonce; }
82
83  std::string ToString() const;
84
85  void HandleTurnMessage(const TurnMessage* msg);
86  void HandleChannelData(const char* data, size_t size);
87
88  sigslot::signal1<TurnServerAllocation*> SignalDestroyed;
89
90 private:
91  class Channel;
92  class Permission;
93  typedef std::list<Permission*> PermissionList;
94  typedef std::list<Channel*> ChannelList;
95
96  void HandleAllocateRequest(const TurnMessage* msg);
97  void HandleRefreshRequest(const TurnMessage* msg);
98  void HandleSendIndication(const TurnMessage* msg);
99  void HandleCreatePermissionRequest(const TurnMessage* msg);
100  void HandleChannelBindRequest(const TurnMessage* msg);
101
102  void OnExternalPacket(rtc::AsyncPacketSocket* socket,
103                        const char* data, size_t size,
104                        const rtc::SocketAddress& addr,
105                        const rtc::PacketTime& packet_time);
106
107  static int ComputeLifetime(const TurnMessage* msg);
108  bool HasPermission(const rtc::IPAddress& addr);
109  void AddPermission(const rtc::IPAddress& addr);
110  Permission* FindPermission(const rtc::IPAddress& addr) const;
111  Channel* FindChannel(int channel_id) const;
112  Channel* FindChannel(const rtc::SocketAddress& addr) const;
113
114  void SendResponse(TurnMessage* msg);
115  void SendBadRequestResponse(const TurnMessage* req);
116  void SendErrorResponse(const TurnMessage* req, int code,
117                         const std::string& reason);
118  void SendExternal(const void* data, size_t size,
119                    const rtc::SocketAddress& peer);
120
121  void OnPermissionDestroyed(Permission* perm);
122  void OnChannelDestroyed(Channel* channel);
123  virtual void OnMessage(rtc::Message* msg);
124
125  TurnServer* server_;
126  rtc::Thread* thread_;
127  TurnServerConnection conn_;
128  rtc::scoped_ptr<rtc::AsyncPacketSocket> external_socket_;
129  std::string key_;
130  std::string transaction_id_;
131  std::string username_;
132  std::string origin_;
133  std::string last_nonce_;
134  PermissionList perms_;
135  ChannelList channels_;
136};
137
138// An interface through which the MD5 credential hash can be retrieved.
139class TurnAuthInterface {
140 public:
141  // Gets HA1 for the specified user and realm.
142  // HA1 = MD5(A1) = MD5(username:realm:password).
143  // Return true if the given username and realm are valid, or false if not.
144  virtual bool GetKey(const std::string& username, const std::string& realm,
145                      std::string* key) = 0;
146};
147
148// An interface enables Turn Server to control redirection behavior.
149class TurnRedirectInterface {
150 public:
151  virtual bool ShouldRedirect(const rtc::SocketAddress& address,
152                              rtc::SocketAddress* out) = 0;
153  virtual ~TurnRedirectInterface() {}
154};
155
156// The core TURN server class. Give it a socket to listen on via
157// AddInternalServerSocket, and a factory to create external sockets via
158// SetExternalSocketFactory, and it's ready to go.
159// Not yet wired up: TCP support.
160class TurnServer : public sigslot::has_slots<> {
161 public:
162  typedef std::map<TurnServerConnection, TurnServerAllocation*> AllocationMap;
163
164  explicit TurnServer(rtc::Thread* thread);
165  ~TurnServer();
166
167  // Gets/sets the realm value to use for the server.
168  const std::string& realm() const { return realm_; }
169  void set_realm(const std::string& realm) { realm_ = realm; }
170
171  // Gets/sets the value for the SOFTWARE attribute for TURN messages.
172  const std::string& software() const { return software_; }
173  void set_software(const std::string& software) { software_ = software; }
174
175  const AllocationMap& allocations() const { return allocations_; }
176
177  // Sets the authentication callback; does not take ownership.
178  void set_auth_hook(TurnAuthInterface* auth_hook) { auth_hook_ = auth_hook; }
179
180  void set_redirect_hook(TurnRedirectInterface* redirect_hook) {
181    redirect_hook_ = redirect_hook;
182  }
183
184  void set_enable_otu_nonce(bool enable) { enable_otu_nonce_ = enable; }
185
186  // If set to true, reject CreatePermission requests to RFC1918 addresses.
187  void set_reject_private_addresses(bool filter) {
188    reject_private_addresses_ = filter;
189  }
190
191  // Starts listening for packets from internal clients.
192  void AddInternalSocket(rtc::AsyncPacketSocket* socket,
193                         ProtocolType proto);
194  // Starts listening for the connections on this socket. When someone tries
195  // to connect, the connection will be accepted and a new internal socket
196  // will be added.
197  void AddInternalServerSocket(rtc::AsyncSocket* socket,
198                               ProtocolType proto);
199  // Specifies the factory to use for creating external sockets.
200  void SetExternalSocketFactory(rtc::PacketSocketFactory* factory,
201                                const rtc::SocketAddress& address);
202
203 private:
204  void OnInternalPacket(rtc::AsyncPacketSocket* socket, const char* data,
205                        size_t size, const rtc::SocketAddress& address,
206                        const rtc::PacketTime& packet_time);
207
208  void OnNewInternalConnection(rtc::AsyncSocket* socket);
209
210  // Accept connections on this server socket.
211  void AcceptConnection(rtc::AsyncSocket* server_socket);
212  void OnInternalSocketClose(rtc::AsyncPacketSocket* socket, int err);
213
214  void HandleStunMessage(
215      TurnServerConnection* conn, const char* data, size_t size);
216  void HandleBindingRequest(TurnServerConnection* conn, const StunMessage* msg);
217  void HandleAllocateRequest(TurnServerConnection* conn, const TurnMessage* msg,
218                             const std::string& key);
219
220  bool GetKey(const StunMessage* msg, std::string* key);
221  bool CheckAuthorization(TurnServerConnection* conn, const StunMessage* msg,
222                          const char* data, size_t size,
223                          const std::string& key);
224  std::string GenerateNonce() const;
225  bool ValidateNonce(const std::string& nonce) const;
226
227  TurnServerAllocation* FindAllocation(TurnServerConnection* conn);
228  TurnServerAllocation* CreateAllocation(
229      TurnServerConnection* conn, int proto, const std::string& key);
230
231  void SendErrorResponse(TurnServerConnection* conn, const StunMessage* req,
232                         int code, const std::string& reason);
233
234  void SendErrorResponseWithRealmAndNonce(TurnServerConnection* conn,
235                                          const StunMessage* req,
236                                          int code,
237                                          const std::string& reason);
238
239  void SendErrorResponseWithAlternateServer(TurnServerConnection* conn,
240                                            const StunMessage* req,
241                                            const rtc::SocketAddress& addr);
242
243  void SendStun(TurnServerConnection* conn, StunMessage* msg);
244  void Send(TurnServerConnection* conn, const rtc::ByteBuffer& buf);
245
246  void OnAllocationDestroyed(TurnServerAllocation* allocation);
247  void DestroyInternalSocket(rtc::AsyncPacketSocket* socket);
248
249  typedef std::map<rtc::AsyncPacketSocket*,
250                   ProtocolType> InternalSocketMap;
251  typedef std::map<rtc::AsyncSocket*,
252                   ProtocolType> ServerSocketMap;
253
254  rtc::Thread* thread_;
255  std::string nonce_key_;
256  std::string realm_;
257  std::string software_;
258  TurnAuthInterface* auth_hook_;
259  TurnRedirectInterface* redirect_hook_;
260  // otu - one-time-use. Server will respond with 438 if it's
261  // sees the same nonce in next transaction.
262  bool enable_otu_nonce_;
263  bool reject_private_addresses_ = false;
264
265  InternalSocketMap server_sockets_;
266  ServerSocketMap server_listen_sockets_;
267  rtc::scoped_ptr<rtc::PacketSocketFactory>
268      external_socket_factory_;
269  rtc::SocketAddress external_addr_;
270
271  AllocationMap allocations_;
272
273  friend class TurnServerAllocation;
274};
275
276}  // namespace cricket
277
278#endif  // WEBRTC_P2P_BASE_TURNSERVER_H_
279