• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 P2P_BASE_TURN_SERVER_H_
12 #define P2P_BASE_TURN_SERVER_H_
13 
14 #include <list>
15 #include <map>
16 #include <memory>
17 #include <set>
18 #include <string>
19 #include <utility>
20 #include <vector>
21 
22 #include "absl/strings/string_view.h"
23 #include "api/sequence_checker.h"
24 #include "api/task_queue/pending_task_safety_flag.h"
25 #include "api/task_queue/task_queue_base.h"
26 #include "api/units/time_delta.h"
27 #include "p2p/base/port_interface.h"
28 #include "rtc_base/async_packet_socket.h"
29 #include "rtc_base/socket_address.h"
30 #include "rtc_base/ssl_adapter.h"
31 #include "rtc_base/third_party/sigslot/sigslot.h"
32 
33 namespace rtc {
34 class ByteBufferWriter;
35 class PacketSocketFactory;
36 }  // namespace rtc
37 
38 namespace cricket {
39 
40 class StunMessage;
41 class TurnMessage;
42 class TurnServer;
43 
44 // The default server port for TURN, as specified in RFC5766.
45 const int TURN_SERVER_PORT = 3478;
46 
47 // Encapsulates the client's connection to the server.
48 class TurnServerConnection {
49  public:
TurnServerConnection()50   TurnServerConnection() : proto_(PROTO_UDP), socket_(NULL) {}
51   TurnServerConnection(const rtc::SocketAddress& src,
52                        ProtocolType proto,
53                        rtc::AsyncPacketSocket* socket);
src()54   const rtc::SocketAddress& src() const { return src_; }
socket()55   rtc::AsyncPacketSocket* socket() { return socket_; }
56   bool operator==(const TurnServerConnection& t) const;
57   bool operator<(const TurnServerConnection& t) const;
58   std::string ToString() const;
59 
60  private:
61   rtc::SocketAddress src_;
62   rtc::SocketAddress dst_;
63   cricket::ProtocolType proto_;
64   rtc::AsyncPacketSocket* socket_;
65 };
66 
67 // Encapsulates a TURN allocation.
68 // The object is created when an allocation request is received, and then
69 // handles TURN messages (via HandleTurnMessage) and channel data messages
70 // (via HandleChannelData) for this allocation when received by the server.
71 // The object informs the server when its lifetime timer expires.
72 class TurnServerAllocation : public sigslot::has_slots<> {
73  public:
74   TurnServerAllocation(TurnServer* server_,
75                        webrtc::TaskQueueBase* thread,
76                        const TurnServerConnection& conn,
77                        rtc::AsyncPacketSocket* server_socket,
78                        absl::string_view key);
79   ~TurnServerAllocation() override;
80 
conn()81   TurnServerConnection* conn() { return &conn_; }
key()82   const std::string& key() const { return key_; }
transaction_id()83   const std::string& transaction_id() const { return transaction_id_; }
username()84   const std::string& username() const { return username_; }
last_nonce()85   const std::string& last_nonce() const { return last_nonce_; }
set_last_nonce(absl::string_view nonce)86   void set_last_nonce(absl::string_view nonce) {
87     last_nonce_ = std::string(nonce);
88   }
89 
90   std::string ToString() const;
91 
92   void HandleTurnMessage(const TurnMessage* msg);
93   void HandleChannelData(const char* data, size_t size);
94 
95  private:
96   struct Channel {
97     webrtc::ScopedTaskSafety pending_delete;
98     int id;
99     rtc::SocketAddress peer;
100   };
101   struct Permission {
102     webrtc::ScopedTaskSafety pending_delete;
103     rtc::IPAddress peer;
104   };
105   using PermissionList = std::list<Permission>;
106   using ChannelList = std::list<Channel>;
107 
108   void PostDeleteSelf(webrtc::TimeDelta delay);
109 
110   void HandleAllocateRequest(const TurnMessage* msg);
111   void HandleRefreshRequest(const TurnMessage* msg);
112   void HandleSendIndication(const TurnMessage* msg);
113   void HandleCreatePermissionRequest(const TurnMessage* msg);
114   void HandleChannelBindRequest(const TurnMessage* msg);
115 
116   void OnExternalPacket(rtc::AsyncPacketSocket* socket,
117                         const char* data,
118                         size_t size,
119                         const rtc::SocketAddress& addr,
120                         const int64_t& packet_time_us);
121 
122   static webrtc::TimeDelta ComputeLifetime(const TurnMessage& msg);
123   bool HasPermission(const rtc::IPAddress& addr);
124   void AddPermission(const rtc::IPAddress& addr);
125   PermissionList::iterator FindPermission(const rtc::IPAddress& addr);
126   ChannelList::iterator FindChannel(int channel_id);
127   ChannelList::iterator FindChannel(const rtc::SocketAddress& addr);
128 
129   void SendResponse(TurnMessage* msg);
130   void SendBadRequestResponse(const TurnMessage* req);
131   void SendErrorResponse(const TurnMessage* req,
132                          int code,
133                          absl::string_view reason);
134   void SendExternal(const void* data,
135                     size_t size,
136                     const rtc::SocketAddress& peer);
137 
138   TurnServer* const server_;
139   webrtc::TaskQueueBase* const thread_;
140   TurnServerConnection conn_;
141   std::unique_ptr<rtc::AsyncPacketSocket> external_socket_;
142   std::string key_;
143   std::string transaction_id_;
144   std::string username_;
145   std::string last_nonce_;
146   PermissionList perms_;
147   ChannelList channels_;
148   webrtc::ScopedTaskSafety safety_;
149 };
150 
151 // An interface through which the MD5 credential hash can be retrieved.
152 class TurnAuthInterface {
153  public:
154   // Gets HA1 for the specified user and realm.
155   // HA1 = MD5(A1) = MD5(username:realm:password).
156   // Return true if the given username and realm are valid, or false if not.
157   virtual bool GetKey(absl::string_view username,
158                       absl::string_view realm,
159                       std::string* key) = 0;
160   virtual ~TurnAuthInterface() = default;
161 };
162 
163 // An interface enables Turn Server to control redirection behavior.
164 class TurnRedirectInterface {
165  public:
166   virtual bool ShouldRedirect(const rtc::SocketAddress& address,
167                               rtc::SocketAddress* out) = 0;
~TurnRedirectInterface()168   virtual ~TurnRedirectInterface() {}
169 };
170 
171 class StunMessageObserver {
172  public:
173   virtual void ReceivedMessage(const TurnMessage* msg) = 0;
174   virtual void ReceivedChannelData(const char* data, size_t size) = 0;
~StunMessageObserver()175   virtual ~StunMessageObserver() {}
176 };
177 
178 // The core TURN server class. Give it a socket to listen on via
179 // AddInternalServerSocket, and a factory to create external sockets via
180 // SetExternalSocketFactory, and it's ready to go.
181 // Not yet wired up: TCP support.
182 class TurnServer : public sigslot::has_slots<> {
183  public:
184   typedef std::map<TurnServerConnection, std::unique_ptr<TurnServerAllocation>>
185       AllocationMap;
186 
187   explicit TurnServer(webrtc::TaskQueueBase* thread);
188   ~TurnServer() override;
189 
190   // Gets/sets the realm value to use for the server.
realm()191   const std::string& realm() const {
192     RTC_DCHECK_RUN_ON(thread_);
193     return realm_;
194   }
set_realm(absl::string_view realm)195   void set_realm(absl::string_view realm) {
196     RTC_DCHECK_RUN_ON(thread_);
197     realm_ = std::string(realm);
198   }
199 
200   // Gets/sets the value for the SOFTWARE attribute for TURN messages.
software()201   const std::string& software() const {
202     RTC_DCHECK_RUN_ON(thread_);
203     return software_;
204   }
set_software(absl::string_view software)205   void set_software(absl::string_view software) {
206     RTC_DCHECK_RUN_ON(thread_);
207     software_ = std::string(software);
208   }
209 
allocations()210   const AllocationMap& allocations() const {
211     RTC_DCHECK_RUN_ON(thread_);
212     return allocations_;
213   }
214 
215   // Sets the authentication callback; does not take ownership.
set_auth_hook(TurnAuthInterface * auth_hook)216   void set_auth_hook(TurnAuthInterface* auth_hook) {
217     RTC_DCHECK_RUN_ON(thread_);
218     auth_hook_ = auth_hook;
219   }
220 
set_redirect_hook(TurnRedirectInterface * redirect_hook)221   void set_redirect_hook(TurnRedirectInterface* redirect_hook) {
222     RTC_DCHECK_RUN_ON(thread_);
223     redirect_hook_ = redirect_hook;
224   }
225 
set_enable_otu_nonce(bool enable)226   void set_enable_otu_nonce(bool enable) {
227     RTC_DCHECK_RUN_ON(thread_);
228     enable_otu_nonce_ = enable;
229   }
230 
231   // If set to true, reject CreatePermission requests to RFC1918 addresses.
set_reject_private_addresses(bool filter)232   void set_reject_private_addresses(bool filter) {
233     RTC_DCHECK_RUN_ON(thread_);
234     reject_private_addresses_ = filter;
235   }
236 
set_enable_permission_checks(bool enable)237   void set_enable_permission_checks(bool enable) {
238     RTC_DCHECK_RUN_ON(thread_);
239     enable_permission_checks_ = enable;
240   }
241 
242   // Starts listening for packets from internal clients.
243   void AddInternalSocket(rtc::AsyncPacketSocket* socket, ProtocolType proto);
244   // Starts listening for the connections on this socket. When someone tries
245   // to connect, the connection will be accepted and a new internal socket
246   // will be added.
247   void AddInternalServerSocket(
248       rtc::Socket* socket,
249       ProtocolType proto,
250       std::unique_ptr<rtc::SSLAdapterFactory> ssl_adapter_factory = nullptr);
251   // Specifies the factory to use for creating external sockets.
252   void SetExternalSocketFactory(rtc::PacketSocketFactory* factory,
253                                 const rtc::SocketAddress& address);
254   // For testing only.
SetTimestampForNextNonce(int64_t timestamp)255   std::string SetTimestampForNextNonce(int64_t timestamp) {
256     RTC_DCHECK_RUN_ON(thread_);
257     ts_for_next_nonce_ = timestamp;
258     return GenerateNonce(timestamp);
259   }
260 
SetStunMessageObserver(std::unique_ptr<StunMessageObserver> observer)261   void SetStunMessageObserver(std::unique_ptr<StunMessageObserver> observer) {
262     RTC_DCHECK_RUN_ON(thread_);
263     stun_message_observer_ = std::move(observer);
264   }
265 
266  private:
267   // All private member functions and variables should have access restricted to
268   // thread_. But compile-time annotations are missing for members access from
269   // TurnServerAllocation (via friend declaration), and the On* methods, which
270   // are called via sigslot.
271   std::string GenerateNonce(int64_t now) const RTC_RUN_ON(thread_);
272   void OnInternalPacket(rtc::AsyncPacketSocket* socket,
273                         const char* data,
274                         size_t size,
275                         const rtc::SocketAddress& address,
276                         const int64_t& packet_time_us);
277 
278   void OnNewInternalConnection(rtc::Socket* socket);
279 
280   // Accept connections on this server socket.
281   void AcceptConnection(rtc::Socket* server_socket) RTC_RUN_ON(thread_);
282   void OnInternalSocketClose(rtc::AsyncPacketSocket* socket, int err);
283 
284   void HandleStunMessage(TurnServerConnection* conn,
285                          const char* data,
286                          size_t size) RTC_RUN_ON(thread_);
287   void HandleBindingRequest(TurnServerConnection* conn, const StunMessage* msg)
288       RTC_RUN_ON(thread_);
289   void HandleAllocateRequest(TurnServerConnection* conn,
290                              const TurnMessage* msg,
291                              absl::string_view key) RTC_RUN_ON(thread_);
292 
293   bool GetKey(const StunMessage* msg, std::string* key) RTC_RUN_ON(thread_);
294   bool CheckAuthorization(TurnServerConnection* conn,
295                           StunMessage* msg,
296                           const char* data,
297                           size_t size,
298                           absl::string_view key) RTC_RUN_ON(thread_);
299   bool ValidateNonce(absl::string_view nonce) const RTC_RUN_ON(thread_);
300 
301   TurnServerAllocation* FindAllocation(TurnServerConnection* conn)
302       RTC_RUN_ON(thread_);
303   TurnServerAllocation* CreateAllocation(TurnServerConnection* conn,
304                                          int proto,
305                                          absl::string_view key)
306       RTC_RUN_ON(thread_);
307 
308   void SendErrorResponse(TurnServerConnection* conn,
309                          const StunMessage* req,
310                          int code,
311                          absl::string_view reason);
312 
313   void SendErrorResponseWithRealmAndNonce(TurnServerConnection* conn,
314                                           const StunMessage* req,
315                                           int code,
316                                           absl::string_view reason)
317       RTC_RUN_ON(thread_);
318 
319   void SendErrorResponseWithAlternateServer(TurnServerConnection* conn,
320                                             const StunMessage* req,
321                                             const rtc::SocketAddress& addr)
322       RTC_RUN_ON(thread_);
323 
324   void SendStun(TurnServerConnection* conn, StunMessage* msg);
325   void Send(TurnServerConnection* conn, const rtc::ByteBufferWriter& buf);
326 
327   void DestroyAllocation(TurnServerAllocation* allocation) RTC_RUN_ON(thread_);
328   void DestroyInternalSocket(rtc::AsyncPacketSocket* socket)
329       RTC_RUN_ON(thread_);
330 
331   typedef std::map<rtc::AsyncPacketSocket*, ProtocolType> InternalSocketMap;
332   struct ServerSocketInfo {
333     ProtocolType proto;
334     // If non-null, used to wrap accepted sockets.
335     std::unique_ptr<rtc::SSLAdapterFactory> ssl_adapter_factory;
336   };
337   typedef std::map<rtc::Socket*, ServerSocketInfo> ServerSocketMap;
338 
339   webrtc::TaskQueueBase* const thread_;
340   const std::string nonce_key_;
341   std::string realm_ RTC_GUARDED_BY(thread_);
342   std::string software_ RTC_GUARDED_BY(thread_);
343   TurnAuthInterface* auth_hook_ RTC_GUARDED_BY(thread_);
344   TurnRedirectInterface* redirect_hook_ RTC_GUARDED_BY(thread_);
345   // otu - one-time-use. Server will respond with 438 if it's
346   // sees the same nonce in next transaction.
347   bool enable_otu_nonce_ RTC_GUARDED_BY(thread_);
348   bool reject_private_addresses_ = false;
349   // Check for permission when receiving an external packet.
350   bool enable_permission_checks_ = true;
351 
352   InternalSocketMap server_sockets_ RTC_GUARDED_BY(thread_);
353   ServerSocketMap server_listen_sockets_ RTC_GUARDED_BY(thread_);
354   std::unique_ptr<rtc::PacketSocketFactory> external_socket_factory_
355       RTC_GUARDED_BY(thread_);
356   rtc::SocketAddress external_addr_ RTC_GUARDED_BY(thread_);
357 
358   AllocationMap allocations_ RTC_GUARDED_BY(thread_);
359 
360   // For testing only. If this is non-zero, the next NONCE will be generated
361   // from this value, and it will be reset to 0 after generating the NONCE.
362   int64_t ts_for_next_nonce_ RTC_GUARDED_BY(thread_) = 0;
363 
364   // For testing only. Used to observe STUN messages received.
365   std::unique_ptr<StunMessageObserver> stun_message_observer_
366       RTC_GUARDED_BY(thread_);
367 
368   friend class TurnServerAllocation;
369 };
370 
371 }  // namespace cricket
372 
373 #endif  // P2P_BASE_TURN_SERVER_H_
374