blob: 89534846ccde34fd4b2d34597dc97cbbd2442dbd [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>
deadbeef824f5862016-08-24 15:06:53 -070019#include <vector>
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000020
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020021#include "p2p/base/portinterface.h"
22#include "rtc_base/asyncinvoker.h"
23#include "rtc_base/asyncpacketsocket.h"
24#include "rtc_base/messagequeue.h"
25#include "rtc_base/sigslot.h"
26#include "rtc_base/socketaddress.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000027
28namespace rtc {
jbauchf1f87202016-03-30 06:43:37 -070029class ByteBufferWriter;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000030class PacketSocketFactory;
31class Thread;
32}
33
34namespace cricket {
35
36class StunMessage;
37class TurnMessage;
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +000038class TurnServer;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000039
40// The default server port for TURN, as specified in RFC5766.
41const int TURN_SERVER_PORT = 3478;
42
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +000043// Encapsulates the client's connection to the server.
44class TurnServerConnection {
45 public:
46 TurnServerConnection() : proto_(PROTO_UDP), socket_(NULL) {}
47 TurnServerConnection(const rtc::SocketAddress& src,
48 ProtocolType proto,
49 rtc::AsyncPacketSocket* socket);
50 const rtc::SocketAddress& src() const { return src_; }
51 rtc::AsyncPacketSocket* socket() { return socket_; }
52 bool operator==(const TurnServerConnection& t) const;
53 bool operator<(const TurnServerConnection& t) const;
54 std::string ToString() const;
55
56 private:
57 rtc::SocketAddress src_;
58 rtc::SocketAddress dst_;
59 cricket::ProtocolType proto_;
60 rtc::AsyncPacketSocket* socket_;
61};
62
63// Encapsulates a TURN allocation.
64// The object is created when an allocation request is received, and then
65// handles TURN messages (via HandleTurnMessage) and channel data messages
66// (via HandleChannelData) for this allocation when received by the server.
67// The object self-deletes and informs the server if its lifetime timer expires.
68class TurnServerAllocation : public rtc::MessageHandler,
69 public sigslot::has_slots<> {
70 public:
71 TurnServerAllocation(TurnServer* server_,
72 rtc::Thread* thread,
73 const TurnServerConnection& conn,
74 rtc::AsyncPacketSocket* server_socket,
75 const std::string& key);
Steve Antonf2737d22017-10-31 16:27:34 -070076 ~TurnServerAllocation() override;
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +000077
78 TurnServerConnection* conn() { return &conn_; }
79 const std::string& key() const { return key_; }
80 const std::string& transaction_id() const { return transaction_id_; }
81 const std::string& username() const { return username_; }
82 const std::string& origin() const { return origin_; }
83 const std::string& last_nonce() const { return last_nonce_; }
84 void set_last_nonce(const std::string& nonce) { last_nonce_ = nonce; }
85
86 std::string ToString() const;
87
88 void HandleTurnMessage(const TurnMessage* msg);
89 void HandleChannelData(const char* data, size_t size);
90
91 sigslot::signal1<TurnServerAllocation*> SignalDestroyed;
92
93 private:
94 class Channel;
95 class Permission;
96 typedef std::list<Permission*> PermissionList;
97 typedef std::list<Channel*> ChannelList;
98
99 void HandleAllocateRequest(const TurnMessage* msg);
100 void HandleRefreshRequest(const TurnMessage* msg);
101 void HandleSendIndication(const TurnMessage* msg);
102 void HandleCreatePermissionRequest(const TurnMessage* msg);
103 void HandleChannelBindRequest(const TurnMessage* msg);
104
105 void OnExternalPacket(rtc::AsyncPacketSocket* socket,
106 const char* data, size_t size,
107 const rtc::SocketAddress& addr,
108 const rtc::PacketTime& packet_time);
109
110 static int ComputeLifetime(const TurnMessage* msg);
111 bool HasPermission(const rtc::IPAddress& addr);
112 void AddPermission(const rtc::IPAddress& addr);
113 Permission* FindPermission(const rtc::IPAddress& addr) const;
114 Channel* FindChannel(int channel_id) const;
115 Channel* FindChannel(const rtc::SocketAddress& addr) const;
116
117 void SendResponse(TurnMessage* msg);
118 void SendBadRequestResponse(const TurnMessage* req);
119 void SendErrorResponse(const TurnMessage* req, int code,
120 const std::string& reason);
121 void SendExternal(const void* data, size_t size,
122 const rtc::SocketAddress& peer);
123
124 void OnPermissionDestroyed(Permission* perm);
125 void OnChannelDestroyed(Channel* channel);
Steve Antonf2737d22017-10-31 16:27:34 -0700126 void OnMessage(rtc::Message* msg) override;
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000127
128 TurnServer* server_;
129 rtc::Thread* thread_;
130 TurnServerConnection conn_;
kwiberg3ec46792016-04-27 07:22:53 -0700131 std::unique_ptr<rtc::AsyncPacketSocket> external_socket_;
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000132 std::string key_;
133 std::string transaction_id_;
134 std::string username_;
135 std::string origin_;
136 std::string last_nonce_;
137 PermissionList perms_;
138 ChannelList channels_;
139};
140
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000141// An interface through which the MD5 credential hash can be retrieved.
142class TurnAuthInterface {
143 public:
144 // Gets HA1 for the specified user and realm.
145 // HA1 = MD5(A1) = MD5(username:realm:password).
146 // Return true if the given username and realm are valid, or false if not.
147 virtual bool GetKey(const std::string& username, const std::string& realm,
148 std::string* key) = 0;
Henrik Kjellander3fe372d2016-05-12 08:10:52 +0200149 virtual ~TurnAuthInterface() = default;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000150};
151
152// An interface enables Turn Server to control redirection behavior.
153class TurnRedirectInterface {
154 public:
155 virtual bool ShouldRedirect(const rtc::SocketAddress& address,
156 rtc::SocketAddress* out) = 0;
157 virtual ~TurnRedirectInterface() {}
158};
159
Jonas Orelandbdcee282017-10-10 14:01:40 +0200160class StunMessageObserver {
161 public:
162 virtual void ReceivedMessage(const TurnMessage* msg) = 0;
163 virtual void ReceivedChannelData(const char* data, size_t size) = 0;
164 virtual ~StunMessageObserver() {}
165};
166
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000167// The core TURN server class. Give it a socket to listen on via
168// AddInternalServerSocket, and a factory to create external sockets via
169// SetExternalSocketFactory, and it's ready to go.
170// Not yet wired up: TCP support.
171class TurnServer : public sigslot::has_slots<> {
172 public:
deadbeef97943662016-07-12 11:04:50 -0700173 typedef std::map<TurnServerConnection, std::unique_ptr<TurnServerAllocation>>
174 AllocationMap;
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000175
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000176 explicit TurnServer(rtc::Thread* thread);
Steve Antonf2737d22017-10-31 16:27:34 -0700177 ~TurnServer() override;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000178
179 // Gets/sets the realm value to use for the server.
180 const std::string& realm() const { return realm_; }
181 void set_realm(const std::string& realm) { realm_ = realm; }
182
183 // Gets/sets the value for the SOFTWARE attribute for TURN messages.
184 const std::string& software() const { return software_; }
185 void set_software(const std::string& software) { software_ = software; }
186
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000187 const AllocationMap& allocations() const { return allocations_; }
188
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000189 // Sets the authentication callback; does not take ownership.
190 void set_auth_hook(TurnAuthInterface* auth_hook) { auth_hook_ = auth_hook; }
191
192 void set_redirect_hook(TurnRedirectInterface* redirect_hook) {
193 redirect_hook_ = redirect_hook;
194 }
195
196 void set_enable_otu_nonce(bool enable) { enable_otu_nonce_ = enable; }
197
deadbeef376e1232015-11-25 09:00:08 -0800198 // If set to true, reject CreatePermission requests to RFC1918 addresses.
199 void set_reject_private_addresses(bool filter) {
200 reject_private_addresses_ = filter;
201 }
202
Taylor Brandstetteref184702016-06-23 17:35:47 -0700203 void set_enable_permission_checks(bool enable) {
204 enable_permission_checks_ = enable;
205 }
206
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000207 // Starts listening for packets from internal clients.
208 void AddInternalSocket(rtc::AsyncPacketSocket* socket,
209 ProtocolType proto);
210 // Starts listening for the connections on this socket. When someone tries
211 // to connect, the connection will be accepted and a new internal socket
212 // will be added.
213 void AddInternalServerSocket(rtc::AsyncSocket* socket,
214 ProtocolType proto);
215 // Specifies the factory to use for creating external sockets.
216 void SetExternalSocketFactory(rtc::PacketSocketFactory* factory,
217 const rtc::SocketAddress& address);
honghaizc463e202016-02-01 15:19:08 -0800218 // For testing only.
honghaiz34b11eb2016-03-16 08:55:44 -0700219 std::string SetTimestampForNextNonce(int64_t timestamp) {
honghaizc463e202016-02-01 15:19:08 -0800220 ts_for_next_nonce_ = timestamp;
221 return GenerateNonce(timestamp);
222 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000223
Jonas Orelandbdcee282017-10-10 14:01:40 +0200224 void SetStunMessageObserver(
225 std::unique_ptr<StunMessageObserver> observer) {
226 stun_message_observer_ = std::move(observer);
227 }
228
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000229 private:
honghaiz34b11eb2016-03-16 08:55:44 -0700230 std::string GenerateNonce(int64_t now) const;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000231 void OnInternalPacket(rtc::AsyncPacketSocket* socket, const char* data,
232 size_t size, const rtc::SocketAddress& address,
233 const rtc::PacketTime& packet_time);
234
235 void OnNewInternalConnection(rtc::AsyncSocket* socket);
236
237 // Accept connections on this server socket.
238 void AcceptConnection(rtc::AsyncSocket* server_socket);
239 void OnInternalSocketClose(rtc::AsyncPacketSocket* socket, int err);
240
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000241 void HandleStunMessage(
242 TurnServerConnection* conn, const char* data, size_t size);
243 void HandleBindingRequest(TurnServerConnection* conn, const StunMessage* msg);
244 void HandleAllocateRequest(TurnServerConnection* conn, const TurnMessage* msg,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000245 const std::string& key);
246
247 bool GetKey(const StunMessage* msg, std::string* key);
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000248 bool CheckAuthorization(TurnServerConnection* conn, const StunMessage* msg,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000249 const char* data, size_t size,
250 const std::string& key);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000251 bool ValidateNonce(const std::string& nonce) const;
252
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000253 TurnServerAllocation* FindAllocation(TurnServerConnection* conn);
254 TurnServerAllocation* CreateAllocation(
255 TurnServerConnection* conn, int proto, const std::string& key);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000256
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000257 void SendErrorResponse(TurnServerConnection* conn, const StunMessage* req,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000258 int code, const std::string& reason);
259
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000260 void SendErrorResponseWithRealmAndNonce(TurnServerConnection* conn,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000261 const StunMessage* req,
262 int code,
263 const std::string& reason);
264
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000265 void SendErrorResponseWithAlternateServer(TurnServerConnection* conn,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000266 const StunMessage* req,
267 const rtc::SocketAddress& addr);
268
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000269 void SendStun(TurnServerConnection* conn, StunMessage* msg);
jbauchf1f87202016-03-30 06:43:37 -0700270 void Send(TurnServerConnection* conn, const rtc::ByteBufferWriter& buf);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000271
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000272 void OnAllocationDestroyed(TurnServerAllocation* allocation);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000273 void DestroyInternalSocket(rtc::AsyncPacketSocket* socket);
274
deadbeef824f5862016-08-24 15:06:53 -0700275 // Just clears |sockets_to_delete_|; called asynchronously.
276 void FreeSockets();
277
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000278 typedef std::map<rtc::AsyncPacketSocket*,
279 ProtocolType> InternalSocketMap;
280 typedef std::map<rtc::AsyncSocket*,
281 ProtocolType> ServerSocketMap;
282
283 rtc::Thread* thread_;
284 std::string nonce_key_;
285 std::string realm_;
286 std::string software_;
287 TurnAuthInterface* auth_hook_;
288 TurnRedirectInterface* redirect_hook_;
289 // otu - one-time-use. Server will respond with 438 if it's
290 // sees the same nonce in next transaction.
291 bool enable_otu_nonce_;
deadbeef376e1232015-11-25 09:00:08 -0800292 bool reject_private_addresses_ = false;
Taylor Brandstetteref184702016-06-23 17:35:47 -0700293 // Check for permission when receiving an external packet.
294 bool enable_permission_checks_ = true;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000295
296 InternalSocketMap server_sockets_;
297 ServerSocketMap server_listen_sockets_;
deadbeef824f5862016-08-24 15:06:53 -0700298 // Used when we need to delete a socket asynchronously.
299 std::vector<std::unique_ptr<rtc::AsyncPacketSocket>> sockets_to_delete_;
kwiberg3ec46792016-04-27 07:22:53 -0700300 std::unique_ptr<rtc::PacketSocketFactory> external_socket_factory_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000301 rtc::SocketAddress external_addr_;
302
303 AllocationMap allocations_;
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000304
deadbeef824f5862016-08-24 15:06:53 -0700305 rtc::AsyncInvoker invoker_;
306
honghaizc463e202016-02-01 15:19:08 -0800307 // For testing only. If this is non-zero, the next NONCE will be generated
308 // from this value, and it will be reset to 0 after generating the NONCE.
honghaiz34b11eb2016-03-16 08:55:44 -0700309 int64_t ts_for_next_nonce_ = 0;
honghaizc463e202016-02-01 15:19:08 -0800310
Jonas Orelandbdcee282017-10-10 14:01:40 +0200311 // For testing only. Used to observe STUN messages received.
312 std::unique_ptr<StunMessageObserver> stun_message_observer_;
313
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000314 friend class TurnServerAllocation;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000315};
316
317} // namespace cricket
318
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200319#endif // P2P_BASE_TURNSERVER_H_