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 
25 namespace rtc {
26 class ByteBuffer;
27 class PacketSocketFactory;
28 class Thread;
29 }
30 
31 namespace cricket {
32 
33 class StunMessage;
34 class TurnMessage;
35 class TurnServer;
36 
37 // The default server port for TURN, as specified in RFC5766.
38 const int TURN_SERVER_PORT = 3478;
39 
40 // Encapsulates the client's connection to the server.
41 class TurnServerConnection {
42  public:
TurnServerConnection()43   TurnServerConnection() : proto_(PROTO_UDP), socket_(NULL) {}
44   TurnServerConnection(const rtc::SocketAddress& src,
45                        ProtocolType proto,
46                        rtc::AsyncPacketSocket* socket);
src()47   const rtc::SocketAddress& src() const { return src_; }
socket()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.
65 class 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 
conn()75   TurnServerConnection* conn() { return &conn_; }
key()76   const std::string& key() const { return key_; }
transaction_id()77   const std::string& transaction_id() const { return transaction_id_; }
username()78   const std::string& username() const { return username_; }
origin()79   const std::string& origin() const { return origin_; }
last_nonce()80   const std::string& last_nonce() const { return last_nonce_; }
set_last_nonce(const std::string & 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.
139 class 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.
149 class TurnRedirectInterface {
150  public:
151   virtual bool ShouldRedirect(const rtc::SocketAddress& address,
152                               rtc::SocketAddress* out) = 0;
~TurnRedirectInterface()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.
160 class 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.
realm()168   const std::string& realm() const { return realm_; }
set_realm(const std::string & realm)169   void set_realm(const std::string& realm) { realm_ = realm; }
170 
171   // Gets/sets the value for the SOFTWARE attribute for TURN messages.
software()172   const std::string& software() const { return software_; }
set_software(const std::string & software)173   void set_software(const std::string& software) { software_ = software; }
174 
allocations()175   const AllocationMap& allocations() const { return allocations_; }
176 
177   // Sets the authentication callback; does not take ownership.
set_auth_hook(TurnAuthInterface * auth_hook)178   void set_auth_hook(TurnAuthInterface* auth_hook) { auth_hook_ = auth_hook; }
179 
set_redirect_hook(TurnRedirectInterface * redirect_hook)180   void set_redirect_hook(TurnRedirectInterface* redirect_hook) {
181     redirect_hook_ = redirect_hook;
182   }
183 
set_enable_otu_nonce(bool enable)184   void set_enable_otu_nonce(bool enable) { enable_otu_nonce_ = enable; }
185 
186   // Starts listening for packets from internal clients.
187   void AddInternalSocket(rtc::AsyncPacketSocket* socket,
188                          ProtocolType proto);
189   // Starts listening for the connections on this socket. When someone tries
190   // to connect, the connection will be accepted and a new internal socket
191   // will be added.
192   void AddInternalServerSocket(rtc::AsyncSocket* socket,
193                                ProtocolType proto);
194   // Specifies the factory to use for creating external sockets.
195   void SetExternalSocketFactory(rtc::PacketSocketFactory* factory,
196                                 const rtc::SocketAddress& address);
197 
198  private:
199   void OnInternalPacket(rtc::AsyncPacketSocket* socket, const char* data,
200                         size_t size, const rtc::SocketAddress& address,
201                         const rtc::PacketTime& packet_time);
202 
203   void OnNewInternalConnection(rtc::AsyncSocket* socket);
204 
205   // Accept connections on this server socket.
206   void AcceptConnection(rtc::AsyncSocket* server_socket);
207   void OnInternalSocketClose(rtc::AsyncPacketSocket* socket, int err);
208 
209   void HandleStunMessage(
210       TurnServerConnection* conn, const char* data, size_t size);
211   void HandleBindingRequest(TurnServerConnection* conn, const StunMessage* msg);
212   void HandleAllocateRequest(TurnServerConnection* conn, const TurnMessage* msg,
213                              const std::string& key);
214 
215   bool GetKey(const StunMessage* msg, std::string* key);
216   bool CheckAuthorization(TurnServerConnection* conn, const StunMessage* msg,
217                           const char* data, size_t size,
218                           const std::string& key);
219   std::string GenerateNonce() const;
220   bool ValidateNonce(const std::string& nonce) const;
221 
222   TurnServerAllocation* FindAllocation(TurnServerConnection* conn);
223   TurnServerAllocation* CreateAllocation(
224       TurnServerConnection* conn, int proto, const std::string& key);
225 
226   void SendErrorResponse(TurnServerConnection* conn, const StunMessage* req,
227                          int code, const std::string& reason);
228 
229   void SendErrorResponseWithRealmAndNonce(TurnServerConnection* conn,
230                                           const StunMessage* req,
231                                           int code,
232                                           const std::string& reason);
233 
234   void SendErrorResponseWithAlternateServer(TurnServerConnection* conn,
235                                             const StunMessage* req,
236                                             const rtc::SocketAddress& addr);
237 
238   void SendStun(TurnServerConnection* conn, StunMessage* msg);
239   void Send(TurnServerConnection* conn, const rtc::ByteBuffer& buf);
240 
241   void OnAllocationDestroyed(TurnServerAllocation* allocation);
242   void DestroyInternalSocket(rtc::AsyncPacketSocket* socket);
243 
244   typedef std::map<rtc::AsyncPacketSocket*,
245                    ProtocolType> InternalSocketMap;
246   typedef std::map<rtc::AsyncSocket*,
247                    ProtocolType> ServerSocketMap;
248 
249   rtc::Thread* thread_;
250   std::string nonce_key_;
251   std::string realm_;
252   std::string software_;
253   TurnAuthInterface* auth_hook_;
254   TurnRedirectInterface* redirect_hook_;
255   // otu - one-time-use. Server will respond with 438 if it's
256   // sees the same nonce in next transaction.
257   bool enable_otu_nonce_;
258 
259   InternalSocketMap server_sockets_;
260   ServerSocketMap server_listen_sockets_;
261   rtc::scoped_ptr<rtc::PacketSocketFactory>
262       external_socket_factory_;
263   rtc::SocketAddress external_addr_;
264 
265   AllocationMap allocations_;
266 
267   friend class TurnServerAllocation;
268 };
269 
270 }  // namespace cricket
271 
272 #endif  // WEBRTC_P2P_BASE_TURNSERVER_H_
273