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_TURNPORT_H_ 12 #define WEBRTC_P2P_BASE_TURNPORT_H_ 13 14 #include <stdio.h> 15 #include <list> 16 #include <set> 17 #include <string> 18 19 #include "webrtc/base/asyncinvoker.h" 20 #include "webrtc/base/asyncpacketsocket.h" 21 #include "webrtc/p2p/base/port.h" 22 #include "webrtc/p2p/client/basicportallocator.h" 23 24 namespace rtc { 25 class AsyncResolver; 26 class SignalThread; 27 } 28 29 namespace cricket { 30 31 extern const char TURN_PORT_TYPE[]; 32 class TurnAllocateRequest; 33 class TurnEntry; 34 35 class TurnPort : public Port { 36 public: 37 enum PortState { 38 STATE_CONNECTING, // Initial state, cannot send any packets. 39 STATE_CONNECTED, // Socket connected, ready to send stun requests. 40 STATE_READY, // Received allocate success, can send any packets. 41 STATE_DISCONNECTED, // TCP connection died, cannot send any packets. 42 }; Create(rtc::Thread * thread,rtc::PacketSocketFactory * factory,rtc::Network * network,rtc::AsyncPacketSocket * socket,const std::string & username,const std::string & password,const ProtocolAddress & server_address,const RelayCredentials & credentials,int server_priority,const std::string & origin)43 static TurnPort* Create(rtc::Thread* thread, 44 rtc::PacketSocketFactory* factory, 45 rtc::Network* network, 46 rtc::AsyncPacketSocket* socket, 47 const std::string& username, // ice username. 48 const std::string& password, // ice password. 49 const ProtocolAddress& server_address, 50 const RelayCredentials& credentials, 51 int server_priority, 52 const std::string& origin) { 53 return new TurnPort(thread, factory, network, socket, username, password, 54 server_address, credentials, server_priority, origin); 55 } 56 Create(rtc::Thread * thread,rtc::PacketSocketFactory * factory,rtc::Network * network,const rtc::IPAddress & ip,uint16_t min_port,uint16_t max_port,const std::string & username,const std::string & password,const ProtocolAddress & server_address,const RelayCredentials & credentials,int server_priority,const std::string & origin)57 static TurnPort* Create(rtc::Thread* thread, 58 rtc::PacketSocketFactory* factory, 59 rtc::Network* network, 60 const rtc::IPAddress& ip, 61 uint16_t min_port, 62 uint16_t max_port, 63 const std::string& username, // ice username. 64 const std::string& password, // ice password. 65 const ProtocolAddress& server_address, 66 const RelayCredentials& credentials, 67 int server_priority, 68 const std::string& origin) { 69 return new TurnPort(thread, factory, network, ip, min_port, max_port, 70 username, password, server_address, credentials, 71 server_priority, origin); 72 } 73 74 virtual ~TurnPort(); 75 server_address()76 const ProtocolAddress& server_address() const { return server_address_; } 77 // Returns an empty address if the local address has not been assigned. 78 rtc::SocketAddress GetLocalAddress() const; 79 ready()80 bool ready() const { return state_ == STATE_READY; } connected()81 bool connected() const { 82 return state_ == STATE_READY || state_ == STATE_CONNECTED; 83 } credentials()84 const RelayCredentials& credentials() const { return credentials_; } 85 86 virtual void PrepareAddress(); 87 virtual Connection* CreateConnection( 88 const Candidate& c, PortInterface::CandidateOrigin origin); 89 virtual int SendTo(const void* data, size_t size, 90 const rtc::SocketAddress& addr, 91 const rtc::PacketOptions& options, 92 bool payload); 93 virtual int SetOption(rtc::Socket::Option opt, int value); 94 virtual int GetOption(rtc::Socket::Option opt, int* value); 95 virtual int GetError(); 96 HandleIncomingPacket(rtc::AsyncPacketSocket * socket,const char * data,size_t size,const rtc::SocketAddress & remote_addr,const rtc::PacketTime & packet_time)97 virtual bool HandleIncomingPacket( 98 rtc::AsyncPacketSocket* socket, const char* data, size_t size, 99 const rtc::SocketAddress& remote_addr, 100 const rtc::PacketTime& packet_time) { 101 OnReadPacket(socket, data, size, remote_addr, packet_time); 102 return true; 103 } 104 virtual void OnReadPacket(rtc::AsyncPacketSocket* socket, 105 const char* data, size_t size, 106 const rtc::SocketAddress& remote_addr, 107 const rtc::PacketTime& packet_time); 108 109 virtual void OnSentPacket(rtc::AsyncPacketSocket* socket, 110 const rtc::SentPacket& sent_packet); 111 virtual void OnReadyToSend(rtc::AsyncPacketSocket* socket); SupportsProtocol(const std::string & protocol)112 virtual bool SupportsProtocol(const std::string& protocol) const { 113 // Turn port only connects to UDP candidates. 114 return protocol == UDP_PROTOCOL_NAME; 115 } 116 117 void OnSocketConnect(rtc::AsyncPacketSocket* socket); 118 void OnSocketClose(rtc::AsyncPacketSocket* socket, int error); 119 120 hash()121 const std::string& hash() const { return hash_; } nonce()122 const std::string& nonce() const { return nonce_; } 123 error()124 int error() const { return error_; } 125 126 void OnAllocateMismatch(); 127 socket()128 rtc::AsyncPacketSocket* socket() const { 129 return socket_; 130 } 131 132 // For testing only. invoker()133 rtc::AsyncInvoker* invoker() { return &invoker_; } 134 135 // Signal with resolved server address. 136 // Parameters are port, server address and resolved server address. 137 // This signal will be sent only if server address is resolved successfully. 138 sigslot::signal3<TurnPort*, 139 const rtc::SocketAddress&, 140 const rtc::SocketAddress&> SignalResolvedServerAddress; 141 142 // All public methods/signals below are for testing only. 143 sigslot::signal2<TurnPort*, int> SignalTurnRefreshResult; 144 sigslot::signal3<TurnPort*, const rtc::SocketAddress&, int> 145 SignalCreatePermissionResult; FlushRequests(int msg_type)146 void FlushRequests(int msg_type) { request_manager_.Flush(msg_type); } HasRequests()147 bool HasRequests() { return !request_manager_.empty(); } set_credentials(RelayCredentials & credentials)148 void set_credentials(RelayCredentials& credentials) { 149 credentials_ = credentials; 150 } 151 // Finds the turn entry with |address| and sets its channel id. 152 // Returns true if the entry is found. 153 bool SetEntryChannelId(const rtc::SocketAddress& address, int channel_id); 154 155 protected: 156 TurnPort(rtc::Thread* thread, 157 rtc::PacketSocketFactory* factory, 158 rtc::Network* network, 159 rtc::AsyncPacketSocket* socket, 160 const std::string& username, 161 const std::string& password, 162 const ProtocolAddress& server_address, 163 const RelayCredentials& credentials, 164 int server_priority, 165 const std::string& origin); 166 167 TurnPort(rtc::Thread* thread, 168 rtc::PacketSocketFactory* factory, 169 rtc::Network* network, 170 const rtc::IPAddress& ip, 171 uint16_t min_port, 172 uint16_t max_port, 173 const std::string& username, 174 const std::string& password, 175 const ProtocolAddress& server_address, 176 const RelayCredentials& credentials, 177 int server_priority, 178 const std::string& origin); 179 180 private: 181 enum { 182 MSG_ALLOCATE_ERROR = MSG_FIRST_AVAILABLE, 183 MSG_ALLOCATE_MISMATCH, 184 MSG_TRY_ALTERNATE_SERVER, 185 MSG_REFRESH_ERROR 186 }; 187 188 typedef std::list<TurnEntry*> EntryList; 189 typedef std::map<rtc::Socket::Option, int> SocketOptionsMap; 190 typedef std::set<rtc::SocketAddress> AttemptedServerSet; 191 192 virtual void OnMessage(rtc::Message* pmsg); 193 194 bool CreateTurnClientSocket(); 195 set_nonce(const std::string & nonce)196 void set_nonce(const std::string& nonce) { nonce_ = nonce; } set_realm(const std::string & realm)197 void set_realm(const std::string& realm) { 198 if (realm != realm_) { 199 realm_ = realm; 200 UpdateHash(); 201 } 202 } 203 204 // Shuts down the turn port, usually because of some fatal errors. 205 void Close(); 206 void OnTurnRefreshError(); 207 bool SetAlternateServer(const rtc::SocketAddress& address); 208 void ResolveTurnAddress(const rtc::SocketAddress& address); 209 void OnResolveResult(rtc::AsyncResolverInterface* resolver); 210 211 void AddRequestAuthInfo(StunMessage* msg); 212 void OnSendStunPacket(const void* data, size_t size, StunRequest* request); 213 // Stun address from allocate success response. 214 // Currently used only for testing. 215 void OnStunAddress(const rtc::SocketAddress& address); 216 void OnAllocateSuccess(const rtc::SocketAddress& address, 217 const rtc::SocketAddress& stun_address); 218 void OnAllocateError(); 219 void OnAllocateRequestTimeout(); 220 221 void HandleDataIndication(const char* data, size_t size, 222 const rtc::PacketTime& packet_time); 223 void HandleChannelData(int channel_id, const char* data, size_t size, 224 const rtc::PacketTime& packet_time); 225 void DispatchPacket(const char* data, size_t size, 226 const rtc::SocketAddress& remote_addr, 227 ProtocolType proto, const rtc::PacketTime& packet_time); 228 229 bool ScheduleRefresh(int lifetime); 230 void SendRequest(StunRequest* request, int delay); 231 int Send(const void* data, size_t size, 232 const rtc::PacketOptions& options); 233 void UpdateHash(); 234 bool UpdateNonce(StunMessage* response); 235 236 bool HasPermission(const rtc::IPAddress& ipaddr) const; 237 TurnEntry* FindEntry(const rtc::SocketAddress& address) const; 238 TurnEntry* FindEntry(int channel_id) const; 239 bool EntryExists(TurnEntry* e); 240 void CreateOrRefreshEntry(const rtc::SocketAddress& address); 241 void DestroyEntry(TurnEntry* entry); 242 // Destroys the entry only if |timestamp| matches the destruction timestamp 243 // in |entry|. 244 void DestroyEntryIfNotCancelled(TurnEntry* entry, uint32_t timestamp); 245 void ScheduleEntryDestruction(TurnEntry* entry); 246 void CancelEntryDestruction(TurnEntry* entry); 247 void OnConnectionDestroyed(Connection* conn); 248 249 // Destroys the connection with remote address |address|. Returns true if 250 // a connection is found and destroyed. 251 bool DestroyConnection(const rtc::SocketAddress& address); 252 253 ProtocolAddress server_address_; 254 RelayCredentials credentials_; 255 AttemptedServerSet attempted_server_addresses_; 256 257 rtc::AsyncPacketSocket* socket_; 258 SocketOptionsMap socket_options_; 259 rtc::AsyncResolverInterface* resolver_; 260 int error_; 261 262 StunRequestManager request_manager_; 263 std::string realm_; // From 401/438 response message. 264 std::string nonce_; // From 401/438 response message. 265 std::string hash_; // Digest of username:realm:password 266 267 int next_channel_number_; 268 EntryList entries_; 269 270 PortState state_; 271 // By default the value will be set to 0. This value will be used in 272 // calculating the candidate priority. 273 int server_priority_; 274 275 // The number of retries made due to allocate mismatch error. 276 size_t allocate_mismatch_retries_; 277 278 rtc::AsyncInvoker invoker_; 279 280 friend class TurnEntry; 281 friend class TurnAllocateRequest; 282 friend class TurnRefreshRequest; 283 friend class TurnCreatePermissionRequest; 284 friend class TurnChannelBindRequest; 285 }; 286 287 } // namespace cricket 288 289 #endif // WEBRTC_P2P_BASE_TURNPORT_H_ 290