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 WEBRTC_P2P_BASE_TURNSERVER_H_ 12 #define WEBRTC_P2P_BASE_TURNSERVER_H_ 13 14 #include <list> 15 #include <map> 16 #include <set> 17 #include <string> 18 19 #include "webrtc/p2p/base/portinterface.h" 20 #include "webrtc/base/asyncpacketsocket.h" 21 #include "webrtc/base/messagequeue.h" 22 #include "webrtc/base/sigslot.h" 23 #include "webrtc/base/socketaddress.h" 24 25 namespace rtc { 26 class ByteBuffer; 27 class PacketSocketFactory; 28 class Thread; 29 } 30 31 namespace cricket { 32 33 class StunMessage; 34 class TurnMessage; 35 class TurnServer; 36 37 // The default server port for TURN, as specified in RFC5766. 38 const int TURN_SERVER_PORT = 3478; 39 40 // Encapsulates the client's connection to the server. 41 class TurnServerConnection { 42 public: TurnServerConnection()43 TurnServerConnection() : proto_(PROTO_UDP), socket_(NULL) {} 44 TurnServerConnection(const rtc::SocketAddress& src, 45 ProtocolType proto, 46 rtc::AsyncPacketSocket* socket); src()47 const rtc::SocketAddress& src() const { return src_; } socket()48 rtc::AsyncPacketSocket* socket() { return socket_; } 49 bool operator==(const TurnServerConnection& t) const; 50 bool operator<(const TurnServerConnection& t) const; 51 std::string ToString() const; 52 53 private: 54 rtc::SocketAddress src_; 55 rtc::SocketAddress dst_; 56 cricket::ProtocolType proto_; 57 rtc::AsyncPacketSocket* socket_; 58 }; 59 60 // Encapsulates a TURN allocation. 61 // The object is created when an allocation request is received, and then 62 // handles TURN messages (via HandleTurnMessage) and channel data messages 63 // (via HandleChannelData) for this allocation when received by the server. 64 // The object self-deletes and informs the server if its lifetime timer expires. 65 class TurnServerAllocation : public rtc::MessageHandler, 66 public sigslot::has_slots<> { 67 public: 68 TurnServerAllocation(TurnServer* server_, 69 rtc::Thread* thread, 70 const TurnServerConnection& conn, 71 rtc::AsyncPacketSocket* server_socket, 72 const std::string& key); 73 virtual ~TurnServerAllocation(); 74 conn()75 TurnServerConnection* conn() { return &conn_; } key()76 const std::string& key() const { return key_; } transaction_id()77 const std::string& transaction_id() const { return transaction_id_; } username()78 const std::string& username() const { return username_; } origin()79 const std::string& origin() const { return origin_; } last_nonce()80 const std::string& last_nonce() const { return last_nonce_; } set_last_nonce(const std::string & nonce)81 void set_last_nonce(const std::string& nonce) { last_nonce_ = nonce; } 82 83 std::string ToString() const; 84 85 void HandleTurnMessage(const TurnMessage* msg); 86 void HandleChannelData(const char* data, size_t size); 87 88 sigslot::signal1<TurnServerAllocation*> SignalDestroyed; 89 90 private: 91 class Channel; 92 class Permission; 93 typedef std::list<Permission*> PermissionList; 94 typedef std::list<Channel*> ChannelList; 95 96 void HandleAllocateRequest(const TurnMessage* msg); 97 void HandleRefreshRequest(const TurnMessage* msg); 98 void HandleSendIndication(const TurnMessage* msg); 99 void HandleCreatePermissionRequest(const TurnMessage* msg); 100 void HandleChannelBindRequest(const TurnMessage* msg); 101 102 void OnExternalPacket(rtc::AsyncPacketSocket* socket, 103 const char* data, size_t size, 104 const rtc::SocketAddress& addr, 105 const rtc::PacketTime& packet_time); 106 107 static int ComputeLifetime(const TurnMessage* msg); 108 bool HasPermission(const rtc::IPAddress& addr); 109 void AddPermission(const rtc::IPAddress& addr); 110 Permission* FindPermission(const rtc::IPAddress& addr) const; 111 Channel* FindChannel(int channel_id) const; 112 Channel* FindChannel(const rtc::SocketAddress& addr) const; 113 114 void SendResponse(TurnMessage* msg); 115 void SendBadRequestResponse(const TurnMessage* req); 116 void SendErrorResponse(const TurnMessage* req, int code, 117 const std::string& reason); 118 void SendExternal(const void* data, size_t size, 119 const rtc::SocketAddress& peer); 120 121 void OnPermissionDestroyed(Permission* perm); 122 void OnChannelDestroyed(Channel* channel); 123 virtual void OnMessage(rtc::Message* msg); 124 125 TurnServer* server_; 126 rtc::Thread* thread_; 127 TurnServerConnection conn_; 128 rtc::scoped_ptr<rtc::AsyncPacketSocket> external_socket_; 129 std::string key_; 130 std::string transaction_id_; 131 std::string username_; 132 std::string origin_; 133 std::string last_nonce_; 134 PermissionList perms_; 135 ChannelList channels_; 136 }; 137 138 // An interface through which the MD5 credential hash can be retrieved. 139 class TurnAuthInterface { 140 public: 141 // Gets HA1 for the specified user and realm. 142 // HA1 = MD5(A1) = MD5(username:realm:password). 143 // Return true if the given username and realm are valid, or false if not. 144 virtual bool GetKey(const std::string& username, const std::string& realm, 145 std::string* key) = 0; 146 }; 147 148 // An interface enables Turn Server to control redirection behavior. 149 class TurnRedirectInterface { 150 public: 151 virtual bool ShouldRedirect(const rtc::SocketAddress& address, 152 rtc::SocketAddress* out) = 0; ~TurnRedirectInterface()153 virtual ~TurnRedirectInterface() {} 154 }; 155 156 // The core TURN server class. Give it a socket to listen on via 157 // AddInternalServerSocket, and a factory to create external sockets via 158 // SetExternalSocketFactory, and it's ready to go. 159 // Not yet wired up: TCP support. 160 class TurnServer : public sigslot::has_slots<> { 161 public: 162 typedef std::map<TurnServerConnection, TurnServerAllocation*> AllocationMap; 163 164 explicit TurnServer(rtc::Thread* thread); 165 ~TurnServer(); 166 167 // Gets/sets the realm value to use for the server. realm()168 const std::string& realm() const { return realm_; } set_realm(const std::string & realm)169 void set_realm(const std::string& realm) { realm_ = realm; } 170 171 // Gets/sets the value for the SOFTWARE attribute for TURN messages. software()172 const std::string& software() const { return software_; } set_software(const std::string & software)173 void set_software(const std::string& software) { software_ = software; } 174 allocations()175 const AllocationMap& allocations() const { return allocations_; } 176 177 // Sets the authentication callback; does not take ownership. set_auth_hook(TurnAuthInterface * auth_hook)178 void set_auth_hook(TurnAuthInterface* auth_hook) { auth_hook_ = auth_hook; } 179 set_redirect_hook(TurnRedirectInterface * redirect_hook)180 void set_redirect_hook(TurnRedirectInterface* redirect_hook) { 181 redirect_hook_ = redirect_hook; 182 } 183 set_enable_otu_nonce(bool enable)184 void set_enable_otu_nonce(bool enable) { enable_otu_nonce_ = enable; } 185 186 // If set to true, reject CreatePermission requests to RFC1918 addresses. set_reject_private_addresses(bool filter)187 void set_reject_private_addresses(bool filter) { 188 reject_private_addresses_ = filter; 189 } 190 191 // Starts listening for packets from internal clients. 192 void AddInternalSocket(rtc::AsyncPacketSocket* socket, 193 ProtocolType proto); 194 // Starts listening for the connections on this socket. When someone tries 195 // to connect, the connection will be accepted and a new internal socket 196 // will be added. 197 void AddInternalServerSocket(rtc::AsyncSocket* socket, 198 ProtocolType proto); 199 // Specifies the factory to use for creating external sockets. 200 void SetExternalSocketFactory(rtc::PacketSocketFactory* factory, 201 const rtc::SocketAddress& address); 202 203 private: 204 void OnInternalPacket(rtc::AsyncPacketSocket* socket, const char* data, 205 size_t size, const rtc::SocketAddress& address, 206 const rtc::PacketTime& packet_time); 207 208 void OnNewInternalConnection(rtc::AsyncSocket* socket); 209 210 // Accept connections on this server socket. 211 void AcceptConnection(rtc::AsyncSocket* server_socket); 212 void OnInternalSocketClose(rtc::AsyncPacketSocket* socket, int err); 213 214 void HandleStunMessage( 215 TurnServerConnection* conn, const char* data, size_t size); 216 void HandleBindingRequest(TurnServerConnection* conn, const StunMessage* msg); 217 void HandleAllocateRequest(TurnServerConnection* conn, const TurnMessage* msg, 218 const std::string& key); 219 220 bool GetKey(const StunMessage* msg, std::string* key); 221 bool CheckAuthorization(TurnServerConnection* conn, const StunMessage* msg, 222 const char* data, size_t size, 223 const std::string& key); 224 std::string GenerateNonce() const; 225 bool ValidateNonce(const std::string& nonce) const; 226 227 TurnServerAllocation* FindAllocation(TurnServerConnection* conn); 228 TurnServerAllocation* CreateAllocation( 229 TurnServerConnection* conn, int proto, const std::string& key); 230 231 void SendErrorResponse(TurnServerConnection* conn, const StunMessage* req, 232 int code, const std::string& reason); 233 234 void SendErrorResponseWithRealmAndNonce(TurnServerConnection* conn, 235 const StunMessage* req, 236 int code, 237 const std::string& reason); 238 239 void SendErrorResponseWithAlternateServer(TurnServerConnection* conn, 240 const StunMessage* req, 241 const rtc::SocketAddress& addr); 242 243 void SendStun(TurnServerConnection* conn, StunMessage* msg); 244 void Send(TurnServerConnection* conn, const rtc::ByteBuffer& buf); 245 246 void OnAllocationDestroyed(TurnServerAllocation* allocation); 247 void DestroyInternalSocket(rtc::AsyncPacketSocket* socket); 248 249 typedef std::map<rtc::AsyncPacketSocket*, 250 ProtocolType> InternalSocketMap; 251 typedef std::map<rtc::AsyncSocket*, 252 ProtocolType> ServerSocketMap; 253 254 rtc::Thread* thread_; 255 std::string nonce_key_; 256 std::string realm_; 257 std::string software_; 258 TurnAuthInterface* auth_hook_; 259 TurnRedirectInterface* redirect_hook_; 260 // otu - one-time-use. Server will respond with 438 if it's 261 // sees the same nonce in next transaction. 262 bool enable_otu_nonce_; 263 bool reject_private_addresses_ = false; 264 265 InternalSocketMap server_sockets_; 266 ServerSocketMap server_listen_sockets_; 267 rtc::scoped_ptr<rtc::PacketSocketFactory> 268 external_socket_factory_; 269 rtc::SocketAddress external_addr_; 270 271 AllocationMap allocations_; 272 273 friend class TurnServerAllocation; 274 }; 275 276 } // namespace cricket 277 278 #endif // WEBRTC_P2P_BASE_TURNSERVER_H_ 279