blob: 3ead996c2538b145e16bf98466ccbe4ce0fd2264 [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"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000028
29namespace rtc {
jbauchf1f87202016-03-30 06:43:37 -070030class ByteBufferWriter;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000031class PacketSocketFactory;
32class Thread;
33}
34
35namespace cricket {
36
37class StunMessage;
38class TurnMessage;
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +000039class TurnServer;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000040
41// The default server port for TURN, as specified in RFC5766.
42const int TURN_SERVER_PORT = 3478;
43
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +000044// Encapsulates the client's connection to the server.
45class TurnServerConnection {
46 public:
47 TurnServerConnection() : proto_(PROTO_UDP), socket_(NULL) {}
48 TurnServerConnection(const rtc::SocketAddress& src,
49 ProtocolType proto,
50 rtc::AsyncPacketSocket* socket);
51 const rtc::SocketAddress& src() const { return src_; }
52 rtc::AsyncPacketSocket* socket() { return socket_; }
53 bool operator==(const TurnServerConnection& t) const;
54 bool operator<(const TurnServerConnection& t) const;
55 std::string ToString() const;
56
57 private:
58 rtc::SocketAddress src_;
59 rtc::SocketAddress dst_;
60 cricket::ProtocolType proto_;
61 rtc::AsyncPacketSocket* socket_;
62};
63
64// Encapsulates a TURN allocation.
65// The object is created when an allocation request is received, and then
66// handles TURN messages (via HandleTurnMessage) and channel data messages
67// (via HandleChannelData) for this allocation when received by the server.
68// The object self-deletes and informs the server if its lifetime timer expires.
69class TurnServerAllocation : public rtc::MessageHandler,
70 public sigslot::has_slots<> {
71 public:
72 TurnServerAllocation(TurnServer* server_,
73 rtc::Thread* thread,
74 const TurnServerConnection& conn,
75 rtc::AsyncPacketSocket* server_socket,
76 const std::string& key);
Steve Antonf2737d22017-10-31 16:27:34 -070077 ~TurnServerAllocation() override;
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +000078
79 TurnServerConnection* conn() { return &conn_; }
80 const std::string& key() const { return key_; }
81 const std::string& transaction_id() const { return transaction_id_; }
82 const std::string& username() const { return username_; }
83 const std::string& origin() const { return origin_; }
84 const std::string& last_nonce() const { return last_nonce_; }
85 void set_last_nonce(const std::string& nonce) { last_nonce_ = nonce; }
86
87 std::string ToString() const;
88
89 void HandleTurnMessage(const TurnMessage* msg);
90 void HandleChannelData(const char* data, size_t size);
91
92 sigslot::signal1<TurnServerAllocation*> SignalDestroyed;
93
94 private:
95 class Channel;
96 class Permission;
97 typedef std::list<Permission*> PermissionList;
98 typedef std::list<Channel*> ChannelList;
99
100 void HandleAllocateRequest(const TurnMessage* msg);
101 void HandleRefreshRequest(const TurnMessage* msg);
102 void HandleSendIndication(const TurnMessage* msg);
103 void HandleCreatePermissionRequest(const TurnMessage* msg);
104 void HandleChannelBindRequest(const TurnMessage* msg);
105
106 void OnExternalPacket(rtc::AsyncPacketSocket* socket,
107 const char* data, size_t size,
108 const rtc::SocketAddress& addr,
109 const rtc::PacketTime& packet_time);
110
111 static int ComputeLifetime(const TurnMessage* msg);
112 bool HasPermission(const rtc::IPAddress& addr);
113 void AddPermission(const rtc::IPAddress& addr);
114 Permission* FindPermission(const rtc::IPAddress& addr) const;
115 Channel* FindChannel(int channel_id) const;
116 Channel* FindChannel(const rtc::SocketAddress& addr) const;
117
118 void SendResponse(TurnMessage* msg);
119 void SendBadRequestResponse(const TurnMessage* req);
120 void SendErrorResponse(const TurnMessage* req, int code,
121 const std::string& reason);
122 void SendExternal(const void* data, size_t size,
123 const rtc::SocketAddress& peer);
124
125 void OnPermissionDestroyed(Permission* perm);
126 void OnChannelDestroyed(Channel* channel);
Steve Antonf2737d22017-10-31 16:27:34 -0700127 void OnMessage(rtc::Message* msg) override;
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000128
129 TurnServer* server_;
130 rtc::Thread* thread_;
131 TurnServerConnection conn_;
kwiberg3ec46792016-04-27 07:22:53 -0700132 std::unique_ptr<rtc::AsyncPacketSocket> external_socket_;
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000133 std::string key_;
134 std::string transaction_id_;
135 std::string username_;
136 std::string origin_;
137 std::string last_nonce_;
138 PermissionList perms_;
139 ChannelList channels_;
140};
141
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000142// An interface through which the MD5 credential hash can be retrieved.
143class TurnAuthInterface {
144 public:
145 // Gets HA1 for the specified user and realm.
146 // HA1 = MD5(A1) = MD5(username:realm:password).
147 // Return true if the given username and realm are valid, or false if not.
148 virtual bool GetKey(const std::string& username, const std::string& realm,
149 std::string* key) = 0;
Henrik Kjellander3fe372d2016-05-12 08:10:52 +0200150 virtual ~TurnAuthInterface() = default;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000151};
152
153// An interface enables Turn Server to control redirection behavior.
154class TurnRedirectInterface {
155 public:
156 virtual bool ShouldRedirect(const rtc::SocketAddress& address,
157 rtc::SocketAddress* out) = 0;
158 virtual ~TurnRedirectInterface() {}
159};
160
Jonas Orelandbdcee282017-10-10 14:01:40 +0200161class StunMessageObserver {
162 public:
163 virtual void ReceivedMessage(const TurnMessage* msg) = 0;
164 virtual void ReceivedChannelData(const char* data, size_t size) = 0;
165 virtual ~StunMessageObserver() {}
166};
167
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000168// The core TURN server class. Give it a socket to listen on via
169// AddInternalServerSocket, and a factory to create external sockets via
170// SetExternalSocketFactory, and it's ready to go.
171// Not yet wired up: TCP support.
172class TurnServer : public sigslot::has_slots<> {
173 public:
deadbeef97943662016-07-12 11:04:50 -0700174 typedef std::map<TurnServerConnection, std::unique_ptr<TurnServerAllocation>>
175 AllocationMap;
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000176
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000177 explicit TurnServer(rtc::Thread* thread);
Steve Antonf2737d22017-10-31 16:27:34 -0700178 ~TurnServer() override;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000179
180 // Gets/sets the realm value to use for the server.
181 const std::string& realm() const { return realm_; }
182 void set_realm(const std::string& realm) { realm_ = realm; }
183
184 // Gets/sets the value for the SOFTWARE attribute for TURN messages.
185 const std::string& software() const { return software_; }
186 void set_software(const std::string& software) { software_ = software; }
187
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000188 const AllocationMap& allocations() const { return allocations_; }
189
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000190 // Sets the authentication callback; does not take ownership.
191 void set_auth_hook(TurnAuthInterface* auth_hook) { auth_hook_ = auth_hook; }
192
193 void set_redirect_hook(TurnRedirectInterface* redirect_hook) {
194 redirect_hook_ = redirect_hook;
195 }
196
197 void set_enable_otu_nonce(bool enable) { enable_otu_nonce_ = enable; }
198
deadbeef376e1232015-11-25 09:00:08 -0800199 // If set to true, reject CreatePermission requests to RFC1918 addresses.
200 void set_reject_private_addresses(bool filter) {
201 reject_private_addresses_ = filter;
202 }
203
Taylor Brandstetteref184702016-06-23 17:35:47 -0700204 void set_enable_permission_checks(bool enable) {
205 enable_permission_checks_ = enable;
206 }
207
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000208 // Starts listening for packets from internal clients.
209 void AddInternalSocket(rtc::AsyncPacketSocket* socket,
210 ProtocolType proto);
211 // Starts listening for the connections on this socket. When someone tries
212 // to connect, the connection will be accepted and a new internal socket
213 // will be added.
214 void AddInternalServerSocket(rtc::AsyncSocket* socket,
215 ProtocolType proto);
216 // Specifies the factory to use for creating external sockets.
217 void SetExternalSocketFactory(rtc::PacketSocketFactory* factory,
218 const rtc::SocketAddress& address);
honghaizc463e202016-02-01 15:19:08 -0800219 // For testing only.
honghaiz34b11eb2016-03-16 08:55:44 -0700220 std::string SetTimestampForNextNonce(int64_t timestamp) {
honghaizc463e202016-02-01 15:19:08 -0800221 ts_for_next_nonce_ = timestamp;
222 return GenerateNonce(timestamp);
223 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000224
Jonas Orelandbdcee282017-10-10 14:01:40 +0200225 void SetStunMessageObserver(
226 std::unique_ptr<StunMessageObserver> observer) {
227 stun_message_observer_ = std::move(observer);
228 }
229
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000230 private:
honghaiz34b11eb2016-03-16 08:55:44 -0700231 std::string GenerateNonce(int64_t now) const;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000232 void OnInternalPacket(rtc::AsyncPacketSocket* socket, const char* data,
233 size_t size, const rtc::SocketAddress& address,
234 const rtc::PacketTime& packet_time);
235
236 void OnNewInternalConnection(rtc::AsyncSocket* socket);
237
238 // Accept connections on this server socket.
239 void AcceptConnection(rtc::AsyncSocket* server_socket);
240 void OnInternalSocketClose(rtc::AsyncPacketSocket* socket, int err);
241
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000242 void HandleStunMessage(
243 TurnServerConnection* conn, const char* data, size_t size);
244 void HandleBindingRequest(TurnServerConnection* conn, const StunMessage* msg);
245 void HandleAllocateRequest(TurnServerConnection* conn, const TurnMessage* msg,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000246 const std::string& key);
247
248 bool GetKey(const StunMessage* msg, std::string* key);
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000249 bool CheckAuthorization(TurnServerConnection* conn, const StunMessage* msg,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000250 const char* data, size_t size,
251 const std::string& key);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000252 bool ValidateNonce(const std::string& nonce) const;
253
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000254 TurnServerAllocation* FindAllocation(TurnServerConnection* conn);
255 TurnServerAllocation* CreateAllocation(
256 TurnServerConnection* conn, int proto, const std::string& key);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000257
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000258 void SendErrorResponse(TurnServerConnection* conn, const StunMessage* req,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000259 int code, const std::string& reason);
260
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000261 void SendErrorResponseWithRealmAndNonce(TurnServerConnection* conn,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000262 const StunMessage* req,
263 int code,
264 const std::string& reason);
265
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000266 void SendErrorResponseWithAlternateServer(TurnServerConnection* conn,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000267 const StunMessage* req,
268 const rtc::SocketAddress& addr);
269
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000270 void SendStun(TurnServerConnection* conn, StunMessage* msg);
jbauchf1f87202016-03-30 06:43:37 -0700271 void Send(TurnServerConnection* conn, const rtc::ByteBufferWriter& buf);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000272
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000273 void OnAllocationDestroyed(TurnServerAllocation* allocation);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000274 void DestroyInternalSocket(rtc::AsyncPacketSocket* socket);
275
deadbeef824f5862016-08-24 15:06:53 -0700276 // Just clears |sockets_to_delete_|; called asynchronously.
277 void FreeSockets();
278
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000279 typedef std::map<rtc::AsyncPacketSocket*,
280 ProtocolType> InternalSocketMap;
281 typedef std::map<rtc::AsyncSocket*,
282 ProtocolType> ServerSocketMap;
283
284 rtc::Thread* thread_;
285 std::string nonce_key_;
286 std::string realm_;
287 std::string software_;
288 TurnAuthInterface* auth_hook_;
289 TurnRedirectInterface* redirect_hook_;
290 // otu - one-time-use. Server will respond with 438 if it's
291 // sees the same nonce in next transaction.
292 bool enable_otu_nonce_;
deadbeef376e1232015-11-25 09:00:08 -0800293 bool reject_private_addresses_ = false;
Taylor Brandstetteref184702016-06-23 17:35:47 -0700294 // Check for permission when receiving an external packet.
295 bool enable_permission_checks_ = true;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000296
297 InternalSocketMap server_sockets_;
298 ServerSocketMap server_listen_sockets_;
deadbeef824f5862016-08-24 15:06:53 -0700299 // Used when we need to delete a socket asynchronously.
300 std::vector<std::unique_ptr<rtc::AsyncPacketSocket>> sockets_to_delete_;
kwiberg3ec46792016-04-27 07:22:53 -0700301 std::unique_ptr<rtc::PacketSocketFactory> external_socket_factory_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000302 rtc::SocketAddress external_addr_;
303
304 AllocationMap allocations_;
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000305
deadbeef824f5862016-08-24 15:06:53 -0700306 rtc::AsyncInvoker invoker_;
307
honghaizc463e202016-02-01 15:19:08 -0800308 // For testing only. If this is non-zero, the next NONCE will be generated
309 // from this value, and it will be reset to 0 after generating the NONCE.
honghaiz34b11eb2016-03-16 08:55:44 -0700310 int64_t ts_for_next_nonce_ = 0;
honghaizc463e202016-02-01 15:19:08 -0800311
Jonas Orelandbdcee282017-10-10 14:01:40 +0200312 // For testing only. Used to observe STUN messages received.
313 std::unique_ptr<StunMessageObserver> stun_message_observer_;
314
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000315 friend class TurnServerAllocation;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000316};
317
318} // namespace cricket
319
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200320#endif // P2P_BASE_TURNSERVER_H_