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 "p2p/base/port_interface.h" 23 #include "rtc_base/async_invoker.h" 24 #include "rtc_base/async_packet_socket.h" 25 #include "rtc_base/socket_address.h" 26 #include "rtc_base/third_party/sigslot/sigslot.h" 27 #include "rtc_base/thread.h" 28 #include "rtc_base/thread_checker.h" 29 30 namespace rtc { 31 class ByteBufferWriter; 32 class PacketSocketFactory; 33 } // namespace rtc 34 35 namespace cricket { 36 37 class StunMessage; 38 class TurnMessage; 39 class TurnServer; 40 41 // The default server port for TURN, as specified in RFC5766. 42 const int TURN_SERVER_PORT = 3478; 43 44 // Encapsulates the client's connection to the server. 45 class TurnServerConnection { 46 public: TurnServerConnection()47 TurnServerConnection() : proto_(PROTO_UDP), socket_(NULL) {} 48 TurnServerConnection(const rtc::SocketAddress& src, 49 ProtocolType proto, 50 rtc::AsyncPacketSocket* socket); src()51 const rtc::SocketAddress& src() const { return src_; } socket()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. 69 class 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); 77 ~TurnServerAllocation() override; 78 conn()79 TurnServerConnection* conn() { return &conn_; } key()80 const std::string& key() const { return key_; } transaction_id()81 const std::string& transaction_id() const { return transaction_id_; } username()82 const std::string& username() const { return username_; } origin()83 const std::string& origin() const { return origin_; } last_nonce()84 const std::string& last_nonce() const { return last_nonce_; } set_last_nonce(const std::string & 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, 108 size_t size, 109 const rtc::SocketAddress& addr, 110 const int64_t& packet_time_us); 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, 122 int code, 123 const std::string& reason); 124 void SendExternal(const void* data, 125 size_t size, 126 const rtc::SocketAddress& peer); 127 128 void OnPermissionDestroyed(Permission* perm); 129 void OnChannelDestroyed(Channel* channel); 130 void OnMessage(rtc::Message* msg) override; 131 132 TurnServer* server_; 133 rtc::Thread* thread_; 134 TurnServerConnection conn_; 135 std::unique_ptr<rtc::AsyncPacketSocket> external_socket_; 136 std::string key_; 137 std::string transaction_id_; 138 std::string username_; 139 std::string origin_; 140 std::string last_nonce_; 141 PermissionList perms_; 142 ChannelList channels_; 143 }; 144 145 // An interface through which the MD5 credential hash can be retrieved. 146 class TurnAuthInterface { 147 public: 148 // Gets HA1 for the specified user and realm. 149 // HA1 = MD5(A1) = MD5(username:realm:password). 150 // Return true if the given username and realm are valid, or false if not. 151 virtual bool GetKey(const std::string& username, 152 const std::string& realm, 153 std::string* key) = 0; 154 virtual ~TurnAuthInterface() = default; 155 }; 156 157 // An interface enables Turn Server to control redirection behavior. 158 class TurnRedirectInterface { 159 public: 160 virtual bool ShouldRedirect(const rtc::SocketAddress& address, 161 rtc::SocketAddress* out) = 0; ~TurnRedirectInterface()162 virtual ~TurnRedirectInterface() {} 163 }; 164 165 class StunMessageObserver { 166 public: 167 virtual void ReceivedMessage(const TurnMessage* msg) = 0; 168 virtual void ReceivedChannelData(const char* data, size_t size) = 0; ~StunMessageObserver()169 virtual ~StunMessageObserver() {} 170 }; 171 172 // The core TURN server class. Give it a socket to listen on via 173 // AddInternalServerSocket, and a factory to create external sockets via 174 // SetExternalSocketFactory, and it's ready to go. 175 // Not yet wired up: TCP support. 176 class TurnServer : public sigslot::has_slots<> { 177 public: 178 typedef std::map<TurnServerConnection, std::unique_ptr<TurnServerAllocation>> 179 AllocationMap; 180 181 explicit TurnServer(rtc::Thread* thread); 182 ~TurnServer() override; 183 184 // Gets/sets the realm value to use for the server. realm()185 const std::string& realm() const { 186 RTC_DCHECK(thread_checker_.IsCurrent()); 187 return realm_; 188 } set_realm(const std::string & realm)189 void set_realm(const std::string& realm) { 190 RTC_DCHECK(thread_checker_.IsCurrent()); 191 realm_ = realm; 192 } 193 194 // Gets/sets the value for the SOFTWARE attribute for TURN messages. software()195 const std::string& software() const { 196 RTC_DCHECK(thread_checker_.IsCurrent()); 197 return software_; 198 } set_software(const std::string & software)199 void set_software(const std::string& software) { 200 RTC_DCHECK(thread_checker_.IsCurrent()); 201 software_ = software; 202 } 203 allocations()204 const AllocationMap& allocations() const { 205 RTC_DCHECK(thread_checker_.IsCurrent()); 206 return allocations_; 207 } 208 209 // Sets the authentication callback; does not take ownership. set_auth_hook(TurnAuthInterface * auth_hook)210 void set_auth_hook(TurnAuthInterface* auth_hook) { 211 RTC_DCHECK(thread_checker_.IsCurrent()); 212 auth_hook_ = auth_hook; 213 } 214 set_redirect_hook(TurnRedirectInterface * redirect_hook)215 void set_redirect_hook(TurnRedirectInterface* redirect_hook) { 216 RTC_DCHECK(thread_checker_.IsCurrent()); 217 redirect_hook_ = redirect_hook; 218 } 219 set_enable_otu_nonce(bool enable)220 void set_enable_otu_nonce(bool enable) { 221 RTC_DCHECK(thread_checker_.IsCurrent()); 222 enable_otu_nonce_ = enable; 223 } 224 225 // If set to true, reject CreatePermission requests to RFC1918 addresses. set_reject_private_addresses(bool filter)226 void set_reject_private_addresses(bool filter) { 227 RTC_DCHECK(thread_checker_.IsCurrent()); 228 reject_private_addresses_ = filter; 229 } 230 set_enable_permission_checks(bool enable)231 void set_enable_permission_checks(bool enable) { 232 RTC_DCHECK(thread_checker_.IsCurrent()); 233 enable_permission_checks_ = enable; 234 } 235 236 // Starts listening for packets from internal clients. 237 void AddInternalSocket(rtc::AsyncPacketSocket* socket, ProtocolType proto); 238 // Starts listening for the connections on this socket. When someone tries 239 // to connect, the connection will be accepted and a new internal socket 240 // will be added. 241 void AddInternalServerSocket(rtc::AsyncSocket* socket, ProtocolType proto); 242 // Specifies the factory to use for creating external sockets. 243 void SetExternalSocketFactory(rtc::PacketSocketFactory* factory, 244 const rtc::SocketAddress& address); 245 // For testing only. SetTimestampForNextNonce(int64_t timestamp)246 std::string SetTimestampForNextNonce(int64_t timestamp) { 247 RTC_DCHECK(thread_checker_.IsCurrent()); 248 ts_for_next_nonce_ = timestamp; 249 return GenerateNonce(timestamp); 250 } 251 SetStunMessageObserver(std::unique_ptr<StunMessageObserver> observer)252 void SetStunMessageObserver(std::unique_ptr<StunMessageObserver> observer) { 253 RTC_DCHECK(thread_checker_.IsCurrent()); 254 stun_message_observer_ = std::move(observer); 255 } 256 257 private: 258 std::string GenerateNonce(int64_t now) const; 259 void OnInternalPacket(rtc::AsyncPacketSocket* socket, 260 const char* data, 261 size_t size, 262 const rtc::SocketAddress& address, 263 const int64_t& packet_time_us); 264 265 void OnNewInternalConnection(rtc::AsyncSocket* socket); 266 267 // Accept connections on this server socket. 268 void AcceptConnection(rtc::AsyncSocket* server_socket); 269 void OnInternalSocketClose(rtc::AsyncPacketSocket* socket, int err); 270 271 void HandleStunMessage(TurnServerConnection* conn, 272 const char* data, 273 size_t size); 274 void HandleBindingRequest(TurnServerConnection* conn, const StunMessage* msg); 275 void HandleAllocateRequest(TurnServerConnection* conn, 276 const TurnMessage* msg, 277 const std::string& key); 278 279 bool GetKey(const StunMessage* msg, std::string* key); 280 bool CheckAuthorization(TurnServerConnection* conn, 281 const StunMessage* msg, 282 const char* data, 283 size_t size, 284 const std::string& key); 285 bool ValidateNonce(const std::string& nonce) const; 286 287 TurnServerAllocation* FindAllocation(TurnServerConnection* conn); 288 TurnServerAllocation* CreateAllocation(TurnServerConnection* conn, 289 int proto, 290 const std::string& key); 291 292 void SendErrorResponse(TurnServerConnection* conn, 293 const StunMessage* req, 294 int code, 295 const std::string& reason); 296 297 void SendErrorResponseWithRealmAndNonce(TurnServerConnection* conn, 298 const StunMessage* req, 299 int code, 300 const std::string& reason); 301 302 void SendErrorResponseWithAlternateServer(TurnServerConnection* conn, 303 const StunMessage* req, 304 const rtc::SocketAddress& addr); 305 306 void SendStun(TurnServerConnection* conn, StunMessage* msg); 307 void Send(TurnServerConnection* conn, const rtc::ByteBufferWriter& buf); 308 309 void OnAllocationDestroyed(TurnServerAllocation* allocation); 310 void DestroyInternalSocket(rtc::AsyncPacketSocket* socket); 311 312 // Just clears |sockets_to_delete_|; called asynchronously. 313 void FreeSockets(); 314 315 typedef std::map<rtc::AsyncPacketSocket*, ProtocolType> InternalSocketMap; 316 typedef std::map<rtc::AsyncSocket*, ProtocolType> ServerSocketMap; 317 318 rtc::Thread* thread_; 319 rtc::ThreadChecker thread_checker_; 320 std::string nonce_key_; 321 std::string realm_; 322 std::string software_; 323 TurnAuthInterface* auth_hook_; 324 TurnRedirectInterface* redirect_hook_; 325 // otu - one-time-use. Server will respond with 438 if it's 326 // sees the same nonce in next transaction. 327 bool enable_otu_nonce_; 328 bool reject_private_addresses_ = false; 329 // Check for permission when receiving an external packet. 330 bool enable_permission_checks_ = true; 331 332 InternalSocketMap server_sockets_; 333 ServerSocketMap server_listen_sockets_; 334 // Used when we need to delete a socket asynchronously. 335 std::vector<std::unique_ptr<rtc::AsyncPacketSocket>> sockets_to_delete_; 336 std::unique_ptr<rtc::PacketSocketFactory> external_socket_factory_; 337 rtc::SocketAddress external_addr_; 338 339 AllocationMap allocations_; 340 341 rtc::AsyncInvoker invoker_; 342 343 // For testing only. If this is non-zero, the next NONCE will be generated 344 // from this value, and it will be reset to 0 after generating the NONCE. 345 int64_t ts_for_next_nonce_ = 0; 346 347 // For testing only. Used to observe STUN messages received. 348 std::unique_ptr<StunMessageObserver> stun_message_observer_; 349 350 friend class TurnServerAllocation; 351 }; 352 353 } // namespace cricket 354 355 #endif // P2P_BASE_TURN_SERVER_H_ 356