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 <string> 33 #include <list> 34 35 #include "talk/base/asyncpacketsocket.h" 36 #include "talk/p2p/base/port.h" 37 #include "talk/p2p/client/basicportallocator.h" 38 39 namespace talk_base { 40 class AsyncResolver; 41 class SignalThread; 42 } 43 44 namespace cricket { 45 46 extern const char TURN_PORT_TYPE[]; 47 class TurnAllocateRequest; 48 class TurnEntry; 49 50 class TurnPort : public Port { 51 public: 52 static TurnPort* Create(talk_base::Thread* thread, 53 talk_base::PacketSocketFactory* factory, 54 talk_base::Network* network, 55 talk_base::AsyncPacketSocket* socket, 56 const std::string& username, // ice username. 57 const std::string& password, // ice password. 58 const ProtocolAddress& server_address, 59 const RelayCredentials& credentials) { 60 return new TurnPort(thread, factory, network, socket, 61 username, password, server_address, credentials); 62 } 63 64 static TurnPort* Create(talk_base::Thread* thread, 65 talk_base::PacketSocketFactory* factory, 66 talk_base::Network* network, 67 const talk_base::IPAddress& ip, 68 int min_port, int max_port, 69 const std::string& username, // ice username. 70 const std::string& password, // ice password. 71 const ProtocolAddress& server_address, 72 const RelayCredentials& credentials) { 73 return new TurnPort(thread, factory, network, ip, min_port, max_port, 74 username, password, server_address, credentials); 75 } 76 77 virtual ~TurnPort(); 78 79 const ProtocolAddress& server_address() const { return server_address_; } 80 81 bool connected() const { return connected_; } 82 const RelayCredentials& credentials() const { return credentials_; } 83 84 virtual void PrepareAddress(); 85 virtual Connection* CreateConnection( 86 const Candidate& c, PortInterface::CandidateOrigin origin); 87 virtual int SendTo(const void* data, size_t size, 88 const talk_base::SocketAddress& addr, 89 const talk_base::PacketOptions& options, 90 bool payload); 91 virtual int SetOption(talk_base::Socket::Option opt, int value); 92 virtual int GetOption(talk_base::Socket::Option opt, int* value); 93 virtual int GetError(); 94 95 virtual bool HandleIncomingPacket( 96 talk_base::AsyncPacketSocket* socket, const char* data, size_t size, 97 const talk_base::SocketAddress& remote_addr, 98 const talk_base::PacketTime& packet_time) { 99 OnReadPacket(socket, data, size, remote_addr, packet_time); 100 return true; 101 } 102 virtual void OnReadPacket(talk_base::AsyncPacketSocket* socket, 103 const char* data, size_t size, 104 const talk_base::SocketAddress& remote_addr, 105 const talk_base::PacketTime& packet_time); 106 107 virtual void OnReadyToSend(talk_base::AsyncPacketSocket* socket); 108 109 void OnSocketConnect(talk_base::AsyncPacketSocket* socket); 110 void OnSocketClose(talk_base::AsyncPacketSocket* socket, int error); 111 112 113 const std::string& hash() const { return hash_; } 114 const std::string& nonce() const { return nonce_; } 115 116 // Signal with resolved server address. 117 // Parameters are port, server address and resolved server address. 118 // This signal will be sent only if server address is resolved successfully. 119 sigslot::signal3<TurnPort*, 120 const talk_base::SocketAddress&, 121 const talk_base::SocketAddress&> SignalResolvedServerAddress; 122 123 // This signal is only for testing purpose. 124 sigslot::signal3<TurnPort*, const talk_base::SocketAddress&, int> 125 SignalCreatePermissionResult; 126 127 protected: 128 TurnPort(talk_base::Thread* thread, 129 talk_base::PacketSocketFactory* factory, 130 talk_base::Network* network, 131 talk_base::AsyncPacketSocket* socket, 132 const std::string& username, 133 const std::string& password, 134 const ProtocolAddress& server_address, 135 const RelayCredentials& credentials); 136 137 TurnPort(talk_base::Thread* thread, 138 talk_base::PacketSocketFactory* factory, 139 talk_base::Network* network, 140 const talk_base::IPAddress& ip, 141 int min_port, int max_port, 142 const std::string& username, 143 const std::string& password, 144 const ProtocolAddress& server_address, 145 const RelayCredentials& credentials); 146 147 private: 148 enum { MSG_ERROR = MSG_FIRST_AVAILABLE }; 149 150 typedef std::list<TurnEntry*> EntryList; 151 typedef std::map<talk_base::Socket::Option, int> SocketOptionsMap; 152 153 virtual void OnMessage(talk_base::Message* pmsg); 154 155 void set_nonce(const std::string& nonce) { nonce_ = nonce; } 156 void set_realm(const std::string& realm) { 157 if (realm != realm_) { 158 realm_ = realm; 159 UpdateHash(); 160 } 161 } 162 163 void ResolveTurnAddress(const talk_base::SocketAddress& address); 164 void OnResolveResult(talk_base::AsyncResolverInterface* resolver); 165 166 void AddRequestAuthInfo(StunMessage* msg); 167 void OnSendStunPacket(const void* data, size_t size, StunRequest* request); 168 // Stun address from allocate success response. 169 // Currently used only for testing. 170 void OnStunAddress(const talk_base::SocketAddress& address); 171 void OnAllocateSuccess(const talk_base::SocketAddress& address, 172 const talk_base::SocketAddress& stun_address); 173 void OnAllocateError(); 174 void OnAllocateRequestTimeout(); 175 176 void HandleDataIndication(const char* data, size_t size, 177 const talk_base::PacketTime& packet_time); 178 void HandleChannelData(int channel_id, const char* data, size_t size, 179 const talk_base::PacketTime& packet_time); 180 void DispatchPacket(const char* data, size_t size, 181 const talk_base::SocketAddress& remote_addr, 182 ProtocolType proto, const talk_base::PacketTime& packet_time); 183 184 bool ScheduleRefresh(int lifetime); 185 void SendRequest(StunRequest* request, int delay); 186 int Send(const void* data, size_t size, 187 const talk_base::PacketOptions& options); 188 void UpdateHash(); 189 bool UpdateNonce(StunMessage* response); 190 191 bool HasPermission(const talk_base::IPAddress& ipaddr) const; 192 TurnEntry* FindEntry(const talk_base::SocketAddress& address) const; 193 TurnEntry* FindEntry(int channel_id) const; 194 TurnEntry* CreateEntry(const talk_base::SocketAddress& address); 195 void DestroyEntry(const talk_base::SocketAddress& address); 196 void OnConnectionDestroyed(Connection* conn); 197 198 ProtocolAddress server_address_; 199 RelayCredentials credentials_; 200 201 talk_base::AsyncPacketSocket* socket_; 202 SocketOptionsMap socket_options_; 203 talk_base::AsyncResolverInterface* resolver_; 204 int error_; 205 206 StunRequestManager request_manager_; 207 std::string realm_; // From 401/438 response message. 208 std::string nonce_; // From 401/438 response message. 209 std::string hash_; // Digest of username:realm:password 210 211 int next_channel_number_; 212 EntryList entries_; 213 214 bool connected_; 215 216 friend class TurnEntry; 217 friend class TurnAllocateRequest; 218 friend class TurnRefreshRequest; 219 friend class TurnCreatePermissionRequest; 220 friend class TurnChannelBindRequest; 221 }; 222 223 } // namespace cricket 224 225 #endif // TALK_P2P_BASE_TURNPORT_H_ 226