1 /* 2 * libjingle 3 * Copyright 2012, Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #ifndef TALK_P2P_BASE_TURNPORT_H_ 29 #define TALK_P2P_BASE_TURNPORT_H_ 30 31 #include <stdio.h> 32 #include <list> 33 #include <set> 34 #include <string> 35 36 #include "talk/p2p/base/port.h" 37 #include "talk/p2p/client/basicportallocator.h" 38 #include "webrtc/base/asyncpacketsocket.h" 39 40 namespace rtc { 41 class AsyncResolver; 42 class SignalThread; 43 } 44 45 namespace cricket { 46 47 extern const char TURN_PORT_TYPE[]; 48 class TurnAllocateRequest; 49 class TurnEntry; 50 51 class TurnPort : public Port { 52 public: 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)53 static TurnPort* Create(rtc::Thread* thread, 54 rtc::PacketSocketFactory* factory, 55 rtc::Network* network, 56 rtc::AsyncPacketSocket* socket, 57 const std::string& username, // ice username. 58 const std::string& password, // ice password. 59 const ProtocolAddress& server_address, 60 const RelayCredentials& credentials, 61 int server_priority) { 62 return new TurnPort(thread, factory, network, socket, 63 username, password, server_address, 64 credentials, server_priority); 65 } 66 Create(rtc::Thread * thread,rtc::PacketSocketFactory * factory,rtc::Network * network,const rtc::IPAddress & ip,int min_port,int max_port,const std::string & username,const std::string & password,const ProtocolAddress & server_address,const RelayCredentials & credentials,int server_priority)67 static TurnPort* Create(rtc::Thread* thread, 68 rtc::PacketSocketFactory* factory, 69 rtc::Network* network, 70 const rtc::IPAddress& ip, 71 int min_port, int max_port, 72 const std::string& username, // ice username. 73 const std::string& password, // ice password. 74 const ProtocolAddress& server_address, 75 const RelayCredentials& credentials, 76 int server_priority) { 77 return new TurnPort(thread, factory, network, ip, min_port, max_port, 78 username, password, server_address, credentials, 79 server_priority); 80 } 81 82 virtual ~TurnPort(); 83 server_address()84 const ProtocolAddress& server_address() const { return server_address_; } 85 connected()86 bool connected() const { return connected_; } credentials()87 const RelayCredentials& credentials() const { return credentials_; } 88 89 virtual void PrepareAddress(); 90 virtual Connection* CreateConnection( 91 const Candidate& c, PortInterface::CandidateOrigin origin); 92 virtual int SendTo(const void* data, size_t size, 93 const rtc::SocketAddress& addr, 94 const rtc::PacketOptions& options, 95 bool payload); 96 virtual int SetOption(rtc::Socket::Option opt, int value); 97 virtual int GetOption(rtc::Socket::Option opt, int* value); 98 virtual int GetError(); 99 HandleIncomingPacket(rtc::AsyncPacketSocket * socket,const char * data,size_t size,const rtc::SocketAddress & remote_addr,const rtc::PacketTime & packet_time)100 virtual bool HandleIncomingPacket( 101 rtc::AsyncPacketSocket* socket, const char* data, size_t size, 102 const rtc::SocketAddress& remote_addr, 103 const rtc::PacketTime& packet_time) { 104 OnReadPacket(socket, data, size, remote_addr, packet_time); 105 return true; 106 } 107 virtual void OnReadPacket(rtc::AsyncPacketSocket* socket, 108 const char* data, size_t size, 109 const rtc::SocketAddress& remote_addr, 110 const rtc::PacketTime& packet_time); 111 112 virtual void OnReadyToSend(rtc::AsyncPacketSocket* socket); 113 114 void OnSocketConnect(rtc::AsyncPacketSocket* socket); 115 void OnSocketClose(rtc::AsyncPacketSocket* socket, int error); 116 117 hash()118 const std::string& hash() const { return hash_; } nonce()119 const std::string& nonce() const { return nonce_; } 120 error()121 int error() const { return error_; } 122 123 void OnAllocateMismatch(); 124 socket()125 rtc::AsyncPacketSocket* socket() const { 126 return socket_; 127 } 128 129 // Signal with resolved server address. 130 // Parameters are port, server address and resolved server address. 131 // This signal will be sent only if server address is resolved successfully. 132 sigslot::signal3<TurnPort*, 133 const rtc::SocketAddress&, 134 const rtc::SocketAddress&> SignalResolvedServerAddress; 135 136 // This signal is only for testing purpose. 137 sigslot::signal3<TurnPort*, const rtc::SocketAddress&, int> 138 SignalCreatePermissionResult; 139 140 protected: 141 TurnPort(rtc::Thread* thread, 142 rtc::PacketSocketFactory* factory, 143 rtc::Network* network, 144 rtc::AsyncPacketSocket* socket, 145 const std::string& username, 146 const std::string& password, 147 const ProtocolAddress& server_address, 148 const RelayCredentials& credentials, 149 int server_priority); 150 151 TurnPort(rtc::Thread* thread, 152 rtc::PacketSocketFactory* factory, 153 rtc::Network* network, 154 const rtc::IPAddress& ip, 155 int min_port, int max_port, 156 const std::string& username, 157 const std::string& password, 158 const ProtocolAddress& server_address, 159 const RelayCredentials& credentials, 160 int server_priority); 161 162 private: 163 enum { 164 MSG_ERROR = MSG_FIRST_AVAILABLE, 165 MSG_ALLOCATE_MISMATCH 166 }; 167 168 typedef std::list<TurnEntry*> EntryList; 169 typedef std::map<rtc::Socket::Option, int> SocketOptionsMap; 170 typedef std::set<rtc::SocketAddress> AttemptedServerSet; 171 172 virtual void OnMessage(rtc::Message* pmsg); 173 174 bool CreateTurnClientSocket(); 175 set_nonce(const std::string & nonce)176 void set_nonce(const std::string& nonce) { nonce_ = nonce; } set_realm(const std::string & realm)177 void set_realm(const std::string& realm) { 178 if (realm != realm_) { 179 realm_ = realm; 180 UpdateHash(); 181 } 182 } 183 184 bool SetAlternateServer(const rtc::SocketAddress& address); 185 void ResolveTurnAddress(const rtc::SocketAddress& address); 186 void OnResolveResult(rtc::AsyncResolverInterface* resolver); 187 188 void AddRequestAuthInfo(StunMessage* msg); 189 void OnSendStunPacket(const void* data, size_t size, StunRequest* request); 190 // Stun address from allocate success response. 191 // Currently used only for testing. 192 void OnStunAddress(const rtc::SocketAddress& address); 193 void OnAllocateSuccess(const rtc::SocketAddress& address, 194 const rtc::SocketAddress& stun_address); 195 void OnAllocateError(); 196 void OnAllocateRequestTimeout(); 197 198 void HandleDataIndication(const char* data, size_t size, 199 const rtc::PacketTime& packet_time); 200 void HandleChannelData(int channel_id, const char* data, size_t size, 201 const rtc::PacketTime& packet_time); 202 void DispatchPacket(const char* data, size_t size, 203 const rtc::SocketAddress& remote_addr, 204 ProtocolType proto, const rtc::PacketTime& packet_time); 205 206 bool ScheduleRefresh(int lifetime); 207 void SendRequest(StunRequest* request, int delay); 208 int Send(const void* data, size_t size, 209 const rtc::PacketOptions& options); 210 void UpdateHash(); 211 bool UpdateNonce(StunMessage* response); 212 213 bool HasPermission(const rtc::IPAddress& ipaddr) const; 214 TurnEntry* FindEntry(const rtc::SocketAddress& address) const; 215 TurnEntry* FindEntry(int channel_id) const; 216 TurnEntry* CreateEntry(const rtc::SocketAddress& address); 217 void DestroyEntry(const rtc::SocketAddress& address); 218 void OnConnectionDestroyed(Connection* conn); 219 220 ProtocolAddress server_address_; 221 RelayCredentials credentials_; 222 AttemptedServerSet attempted_server_addresses_; 223 224 rtc::AsyncPacketSocket* socket_; 225 SocketOptionsMap socket_options_; 226 rtc::AsyncResolverInterface* resolver_; 227 int error_; 228 229 StunRequestManager request_manager_; 230 std::string realm_; // From 401/438 response message. 231 std::string nonce_; // From 401/438 response message. 232 std::string hash_; // Digest of username:realm:password 233 234 int next_channel_number_; 235 EntryList entries_; 236 237 bool connected_; 238 // By default the value will be set to 0. This value will be used in 239 // calculating the candidate priority. 240 int server_priority_; 241 242 // The number of retries made due to allocate mismatch error. 243 size_t allocate_mismatch_retries_; 244 245 friend class TurnEntry; 246 friend class TurnAllocateRequest; 247 friend class TurnRefreshRequest; 248 friend class TurnCreatePermissionRequest; 249 friend class TurnChannelBindRequest; 250 }; 251 252 } // namespace cricket 253 254 #endif // TALK_P2P_BASE_TURNPORT_H_ 255