blob: acba3d28454ec8fa5ba26c6a799f2f73f002a2f4 [file] [log] [blame]
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001/*
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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#ifndef P2P_BASE_TURNSERVER_H_
12#define P2P_BASE_TURNSERVER_H_
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000013
14#include <list>
15#include <map>
kwiberg3ec46792016-04-27 07:22:53 -070016#include <memory>
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000017#include <set>
18#include <string>
Steve Anton6c38cc72017-11-29 10:25:58 -080019#include <utility>
deadbeef824f5862016-08-24 15:06:53 -070020#include <vector>
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000021
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020022#include "p2p/base/portinterface.h"
23#include "rtc_base/asyncinvoker.h"
24#include "rtc_base/asyncpacketsocket.h"
25#include "rtc_base/messagequeue.h"
26#include "rtc_base/sigslot.h"
27#include "rtc_base/socketaddress.h"
Seth Hampsonaed71642018-06-11 07:41:32 -070028#include "rtc_base/thread_checker.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000029
30namespace rtc {
jbauchf1f87202016-03-30 06:43:37 -070031class ByteBufferWriter;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000032class PacketSocketFactory;
33class Thread;
34}
35
36namespace cricket {
37
38class StunMessage;
39class TurnMessage;
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +000040class TurnServer;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000041
42// The default server port for TURN, as specified in RFC5766.
43const int TURN_SERVER_PORT = 3478;
44
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +000045// Encapsulates the client's connection to the server.
46class TurnServerConnection {
47 public:
48 TurnServerConnection() : proto_(PROTO_UDP), socket_(NULL) {}
49 TurnServerConnection(const rtc::SocketAddress& src,
50 ProtocolType proto,
51 rtc::AsyncPacketSocket* socket);
52 const rtc::SocketAddress& src() const { return src_; }
53 rtc::AsyncPacketSocket* socket() { return socket_; }
54 bool operator==(const TurnServerConnection& t) const;
55 bool operator<(const TurnServerConnection& t) const;
56 std::string ToString() const;
57
58 private:
59 rtc::SocketAddress src_;
60 rtc::SocketAddress dst_;
61 cricket::ProtocolType proto_;
62 rtc::AsyncPacketSocket* socket_;
63};
64
65// Encapsulates a TURN allocation.
66// The object is created when an allocation request is received, and then
67// handles TURN messages (via HandleTurnMessage) and channel data messages
68// (via HandleChannelData) for this allocation when received by the server.
69// The object self-deletes and informs the server if its lifetime timer expires.
70class TurnServerAllocation : public rtc::MessageHandler,
71 public sigslot::has_slots<> {
72 public:
73 TurnServerAllocation(TurnServer* server_,
74 rtc::Thread* thread,
75 const TurnServerConnection& conn,
76 rtc::AsyncPacketSocket* server_socket,
77 const std::string& key);
Steve Antonf2737d22017-10-31 16:27:34 -070078 ~TurnServerAllocation() override;
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +000079
80 TurnServerConnection* conn() { return &conn_; }
81 const std::string& key() const { return key_; }
82 const std::string& transaction_id() const { return transaction_id_; }
83 const std::string& username() const { return username_; }
84 const std::string& origin() const { return origin_; }
85 const std::string& last_nonce() const { return last_nonce_; }
86 void set_last_nonce(const std::string& nonce) { last_nonce_ = nonce; }
87
88 std::string ToString() const;
89
90 void HandleTurnMessage(const TurnMessage* msg);
91 void HandleChannelData(const char* data, size_t size);
92
93 sigslot::signal1<TurnServerAllocation*> SignalDestroyed;
94
95 private:
96 class Channel;
97 class Permission;
98 typedef std::list<Permission*> PermissionList;
99 typedef std::list<Channel*> ChannelList;
100
101 void HandleAllocateRequest(const TurnMessage* msg);
102 void HandleRefreshRequest(const TurnMessage* msg);
103 void HandleSendIndication(const TurnMessage* msg);
104 void HandleCreatePermissionRequest(const TurnMessage* msg);
105 void HandleChannelBindRequest(const TurnMessage* msg);
106
107 void OnExternalPacket(rtc::AsyncPacketSocket* socket,
108 const char* data, size_t size,
109 const rtc::SocketAddress& addr,
110 const rtc::PacketTime& packet_time);
111
112 static int ComputeLifetime(const TurnMessage* msg);
113 bool HasPermission(const rtc::IPAddress& addr);
114 void AddPermission(const rtc::IPAddress& addr);
115 Permission* FindPermission(const rtc::IPAddress& addr) const;
116 Channel* FindChannel(int channel_id) const;
117 Channel* FindChannel(const rtc::SocketAddress& addr) const;
118
119 void SendResponse(TurnMessage* msg);
120 void SendBadRequestResponse(const TurnMessage* req);
121 void SendErrorResponse(const TurnMessage* req, int code,
122 const std::string& reason);
123 void SendExternal(const void* data, size_t size,
124 const rtc::SocketAddress& peer);
125
126 void OnPermissionDestroyed(Permission* perm);
127 void OnChannelDestroyed(Channel* channel);
Steve Antonf2737d22017-10-31 16:27:34 -0700128 void OnMessage(rtc::Message* msg) override;
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000129
130 TurnServer* server_;
131 rtc::Thread* thread_;
132 TurnServerConnection conn_;
kwiberg3ec46792016-04-27 07:22:53 -0700133 std::unique_ptr<rtc::AsyncPacketSocket> external_socket_;
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000134 std::string key_;
135 std::string transaction_id_;
136 std::string username_;
137 std::string origin_;
138 std::string last_nonce_;
139 PermissionList perms_;
140 ChannelList channels_;
141};
142
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000143// An interface through which the MD5 credential hash can be retrieved.
144class TurnAuthInterface {
145 public:
146 // Gets HA1 for the specified user and realm.
147 // HA1 = MD5(A1) = MD5(username:realm:password).
148 // Return true if the given username and realm are valid, or false if not.
149 virtual bool GetKey(const std::string& username, const std::string& realm,
150 std::string* key) = 0;
Henrik Kjellander3fe372d2016-05-12 08:10:52 +0200151 virtual ~TurnAuthInterface() = default;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000152};
153
154// An interface enables Turn Server to control redirection behavior.
155class TurnRedirectInterface {
156 public:
157 virtual bool ShouldRedirect(const rtc::SocketAddress& address,
158 rtc::SocketAddress* out) = 0;
159 virtual ~TurnRedirectInterface() {}
160};
161
Jonas Orelandbdcee282017-10-10 14:01:40 +0200162class StunMessageObserver {
163 public:
164 virtual void ReceivedMessage(const TurnMessage* msg) = 0;
165 virtual void ReceivedChannelData(const char* data, size_t size) = 0;
166 virtual ~StunMessageObserver() {}
167};
168
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000169// The core TURN server class. Give it a socket to listen on via
170// AddInternalServerSocket, and a factory to create external sockets via
171// SetExternalSocketFactory, and it's ready to go.
172// Not yet wired up: TCP support.
173class TurnServer : public sigslot::has_slots<> {
174 public:
deadbeef97943662016-07-12 11:04:50 -0700175 typedef std::map<TurnServerConnection, std::unique_ptr<TurnServerAllocation>>
176 AllocationMap;
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000177
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000178 explicit TurnServer(rtc::Thread* thread);
Steve Antonf2737d22017-10-31 16:27:34 -0700179 ~TurnServer() override;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000180
181 // Gets/sets the realm value to use for the server.
Seth Hampsonaed71642018-06-11 07:41:32 -0700182 const std::string& realm() const {
183 RTC_DCHECK(thread_checker_.CalledOnValidThread());
184 return realm_;
185 }
186 void set_realm(const std::string& realm) {
187 RTC_DCHECK(thread_checker_.CalledOnValidThread());
188 realm_ = realm;
189 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000190
191 // Gets/sets the value for the SOFTWARE attribute for TURN messages.
Seth Hampsonaed71642018-06-11 07:41:32 -0700192 const std::string& software() const {
193 RTC_DCHECK(thread_checker_.CalledOnValidThread());
194 return software_;
195 }
196 void set_software(const std::string& software) {
197 RTC_DCHECK(thread_checker_.CalledOnValidThread());
198 software_ = software;
199 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000200
Seth Hampsonaed71642018-06-11 07:41:32 -0700201 const AllocationMap& allocations() const {
202 RTC_DCHECK(thread_checker_.CalledOnValidThread());
203 return allocations_;
204 }
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000205
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000206 // Sets the authentication callback; does not take ownership.
Seth Hampsonaed71642018-06-11 07:41:32 -0700207 void set_auth_hook(TurnAuthInterface* auth_hook) {
208 RTC_DCHECK(thread_checker_.CalledOnValidThread());
209 auth_hook_ = auth_hook;
210 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000211
212 void set_redirect_hook(TurnRedirectInterface* redirect_hook) {
Seth Hampsonaed71642018-06-11 07:41:32 -0700213 RTC_DCHECK(thread_checker_.CalledOnValidThread());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000214 redirect_hook_ = redirect_hook;
215 }
216
Seth Hampsonaed71642018-06-11 07:41:32 -0700217 void set_enable_otu_nonce(bool enable) {
218 RTC_DCHECK(thread_checker_.CalledOnValidThread());
219 enable_otu_nonce_ = enable;
220 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000221
deadbeef376e1232015-11-25 09:00:08 -0800222 // If set to true, reject CreatePermission requests to RFC1918 addresses.
223 void set_reject_private_addresses(bool filter) {
Seth Hampsonaed71642018-06-11 07:41:32 -0700224 RTC_DCHECK(thread_checker_.CalledOnValidThread());
deadbeef376e1232015-11-25 09:00:08 -0800225 reject_private_addresses_ = filter;
226 }
227
Taylor Brandstetteref184702016-06-23 17:35:47 -0700228 void set_enable_permission_checks(bool enable) {
Seth Hampsonaed71642018-06-11 07:41:32 -0700229 RTC_DCHECK(thread_checker_.CalledOnValidThread());
Taylor Brandstetteref184702016-06-23 17:35:47 -0700230 enable_permission_checks_ = enable;
231 }
232
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000233 // Starts listening for packets from internal clients.
234 void AddInternalSocket(rtc::AsyncPacketSocket* socket,
235 ProtocolType proto);
236 // Starts listening for the connections on this socket. When someone tries
237 // to connect, the connection will be accepted and a new internal socket
238 // will be added.
239 void AddInternalServerSocket(rtc::AsyncSocket* socket,
240 ProtocolType proto);
241 // Specifies the factory to use for creating external sockets.
242 void SetExternalSocketFactory(rtc::PacketSocketFactory* factory,
243 const rtc::SocketAddress& address);
honghaizc463e202016-02-01 15:19:08 -0800244 // For testing only.
honghaiz34b11eb2016-03-16 08:55:44 -0700245 std::string SetTimestampForNextNonce(int64_t timestamp) {
Seth Hampsonaed71642018-06-11 07:41:32 -0700246 RTC_DCHECK(thread_checker_.CalledOnValidThread());
honghaizc463e202016-02-01 15:19:08 -0800247 ts_for_next_nonce_ = timestamp;
248 return GenerateNonce(timestamp);
249 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000250
Jonas Orelandbdcee282017-10-10 14:01:40 +0200251 void SetStunMessageObserver(
252 std::unique_ptr<StunMessageObserver> observer) {
Seth Hampsonaed71642018-06-11 07:41:32 -0700253 RTC_DCHECK(thread_checker_.CalledOnValidThread());
Jonas Orelandbdcee282017-10-10 14:01:40 +0200254 stun_message_observer_ = std::move(observer);
255 }
256
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000257 private:
honghaiz34b11eb2016-03-16 08:55:44 -0700258 std::string GenerateNonce(int64_t now) const;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000259 void OnInternalPacket(rtc::AsyncPacketSocket* socket, const char* data,
260 size_t size, const rtc::SocketAddress& address,
261 const rtc::PacketTime& packet_time);
262
263 void OnNewInternalConnection(rtc::AsyncSocket* socket);
264
265 // Accept connections on this server socket.
266 void AcceptConnection(rtc::AsyncSocket* server_socket);
267 void OnInternalSocketClose(rtc::AsyncPacketSocket* socket, int err);
268
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000269 void HandleStunMessage(
270 TurnServerConnection* conn, const char* data, size_t size);
271 void HandleBindingRequest(TurnServerConnection* conn, const StunMessage* msg);
272 void HandleAllocateRequest(TurnServerConnection* conn, const TurnMessage* msg,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000273 const std::string& key);
274
275 bool GetKey(const StunMessage* msg, std::string* key);
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000276 bool CheckAuthorization(TurnServerConnection* conn, const StunMessage* msg,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000277 const char* data, size_t size,
278 const std::string& key);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000279 bool ValidateNonce(const std::string& nonce) const;
280
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000281 TurnServerAllocation* FindAllocation(TurnServerConnection* conn);
282 TurnServerAllocation* CreateAllocation(
283 TurnServerConnection* conn, int proto, const std::string& key);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000284
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000285 void SendErrorResponse(TurnServerConnection* conn, const StunMessage* req,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000286 int code, const std::string& reason);
287
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000288 void SendErrorResponseWithRealmAndNonce(TurnServerConnection* conn,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000289 const StunMessage* req,
290 int code,
291 const std::string& reason);
292
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000293 void SendErrorResponseWithAlternateServer(TurnServerConnection* conn,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000294 const StunMessage* req,
295 const rtc::SocketAddress& addr);
296
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000297 void SendStun(TurnServerConnection* conn, StunMessage* msg);
jbauchf1f87202016-03-30 06:43:37 -0700298 void Send(TurnServerConnection* conn, const rtc::ByteBufferWriter& buf);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000299
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000300 void OnAllocationDestroyed(TurnServerAllocation* allocation);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000301 void DestroyInternalSocket(rtc::AsyncPacketSocket* socket);
302
deadbeef824f5862016-08-24 15:06:53 -0700303 // Just clears |sockets_to_delete_|; called asynchronously.
304 void FreeSockets();
305
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000306 typedef std::map<rtc::AsyncPacketSocket*,
307 ProtocolType> InternalSocketMap;
308 typedef std::map<rtc::AsyncSocket*,
309 ProtocolType> ServerSocketMap;
310
311 rtc::Thread* thread_;
Seth Hampsonaed71642018-06-11 07:41:32 -0700312 rtc::ThreadChecker thread_checker_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000313 std::string nonce_key_;
314 std::string realm_;
315 std::string software_;
316 TurnAuthInterface* auth_hook_;
317 TurnRedirectInterface* redirect_hook_;
318 // otu - one-time-use. Server will respond with 438 if it's
319 // sees the same nonce in next transaction.
320 bool enable_otu_nonce_;
deadbeef376e1232015-11-25 09:00:08 -0800321 bool reject_private_addresses_ = false;
Taylor Brandstetteref184702016-06-23 17:35:47 -0700322 // Check for permission when receiving an external packet.
323 bool enable_permission_checks_ = true;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000324
325 InternalSocketMap server_sockets_;
326 ServerSocketMap server_listen_sockets_;
deadbeef824f5862016-08-24 15:06:53 -0700327 // Used when we need to delete a socket asynchronously.
328 std::vector<std::unique_ptr<rtc::AsyncPacketSocket>> sockets_to_delete_;
kwiberg3ec46792016-04-27 07:22:53 -0700329 std::unique_ptr<rtc::PacketSocketFactory> external_socket_factory_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000330 rtc::SocketAddress external_addr_;
331
332 AllocationMap allocations_;
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000333
deadbeef824f5862016-08-24 15:06:53 -0700334 rtc::AsyncInvoker invoker_;
335
honghaizc463e202016-02-01 15:19:08 -0800336 // For testing only. If this is non-zero, the next NONCE will be generated
337 // from this value, and it will be reset to 0 after generating the NONCE.
honghaiz34b11eb2016-03-16 08:55:44 -0700338 int64_t ts_for_next_nonce_ = 0;
honghaizc463e202016-02-01 15:19:08 -0800339
Jonas Orelandbdcee282017-10-10 14:01:40 +0200340 // For testing only. Used to observe STUN messages received.
341 std::unique_ptr<StunMessageObserver> stun_message_observer_;
342
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000343 friend class TurnServerAllocation;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000344};
345
346} // namespace cricket
347
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200348#endif // P2P_BASE_TURNSERVER_H_