1 /* 2 * Copyright 2004 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_STUNPORT_H_ 12 #define WEBRTC_P2P_BASE_STUNPORT_H_ 13 14 #include <string> 15 16 #include "webrtc/p2p/base/port.h" 17 #include "webrtc/p2p/base/stunrequest.h" 18 #include "webrtc/base/asyncpacketsocket.h" 19 20 // TODO(mallinath) - Rename stunport.cc|h to udpport.cc|h. 21 namespace rtc { 22 class AsyncResolver; 23 class SignalThread; 24 } 25 26 namespace cricket { 27 28 // Communicates using the address on the outside of a NAT. 29 class UDPPort : public Port { 30 public: Create(rtc::Thread * thread,rtc::PacketSocketFactory * factory,rtc::Network * network,rtc::AsyncPacketSocket * socket,const std::string & username,const std::string & password,const std::string & origin)31 static UDPPort* Create(rtc::Thread* thread, 32 rtc::PacketSocketFactory* factory, 33 rtc::Network* network, 34 rtc::AsyncPacketSocket* socket, 35 const std::string& username, 36 const std::string& password, 37 const std::string& origin) { 38 UDPPort* port = new UDPPort(thread, factory, network, socket, 39 username, password, origin); 40 if (!port->Init()) { 41 delete port; 42 port = NULL; 43 } 44 return port; 45 } 46 Create(rtc::Thread * thread,rtc::PacketSocketFactory * factory,rtc::Network * network,const rtc::IPAddress & ip,uint16 min_port,uint16 max_port,const std::string & username,const std::string & password,const std::string & origin)47 static UDPPort* Create(rtc::Thread* thread, 48 rtc::PacketSocketFactory* factory, 49 rtc::Network* network, 50 const rtc::IPAddress& ip, 51 uint16 min_port, 52 uint16 max_port, 53 const std::string& username, 54 const std::string& password, 55 const std::string& origin) { 56 UDPPort* port = new UDPPort(thread, factory, network, 57 ip, min_port, max_port, 58 username, password, origin); 59 if (!port->Init()) { 60 delete port; 61 port = NULL; 62 } 63 return port; 64 } 65 66 virtual ~UDPPort(); 67 GetLocalAddress()68 rtc::SocketAddress GetLocalAddress() const { 69 return socket_->GetLocalAddress(); 70 } 71 server_addresses()72 const ServerAddresses& server_addresses() const { 73 return server_addresses_; 74 } 75 void set_server_addresses(const ServerAddresses & addresses)76 set_server_addresses(const ServerAddresses& addresses) { 77 server_addresses_ = addresses; 78 } 79 80 virtual void PrepareAddress(); 81 82 virtual Connection* CreateConnection(const Candidate& address, 83 CandidateOrigin origin); 84 virtual int SetOption(rtc::Socket::Option opt, int value); 85 virtual int GetOption(rtc::Socket::Option opt, int* value); 86 virtual int GetError(); 87 HandleIncomingPacket(rtc::AsyncPacketSocket * socket,const char * data,size_t size,const rtc::SocketAddress & remote_addr,const rtc::PacketTime & packet_time)88 virtual bool HandleIncomingPacket( 89 rtc::AsyncPacketSocket* socket, const char* data, size_t size, 90 const rtc::SocketAddress& remote_addr, 91 const rtc::PacketTime& packet_time) { 92 // All packets given to UDP port will be consumed. 93 OnReadPacket(socket, data, size, remote_addr, packet_time); 94 return true; 95 } 96 set_stun_keepalive_delay(int delay)97 void set_stun_keepalive_delay(int delay) { 98 stun_keepalive_delay_ = delay; 99 } stun_keepalive_delay()100 int stun_keepalive_delay() const { 101 return stun_keepalive_delay_; 102 } 103 104 protected: 105 UDPPort(rtc::Thread* thread, 106 rtc::PacketSocketFactory* factory, 107 rtc::Network* network, 108 const rtc::IPAddress& ip, 109 uint16 min_port, 110 uint16 max_port, 111 const std::string& username, 112 const std::string& password, 113 const std::string& origin); 114 115 UDPPort(rtc::Thread* thread, 116 rtc::PacketSocketFactory* factory, 117 rtc::Network* network, 118 rtc::AsyncPacketSocket* socket, 119 const std::string& username, 120 const std::string& password, 121 const std::string& origin); 122 123 bool Init(); 124 125 virtual int SendTo(const void* data, size_t size, 126 const rtc::SocketAddress& addr, 127 const rtc::PacketOptions& options, 128 bool payload); 129 130 void OnLocalAddressReady(rtc::AsyncPacketSocket* socket, 131 const rtc::SocketAddress& address); 132 void OnReadPacket(rtc::AsyncPacketSocket* socket, 133 const char* data, size_t size, 134 const rtc::SocketAddress& remote_addr, 135 const rtc::PacketTime& packet_time); 136 137 void OnReadyToSend(rtc::AsyncPacketSocket* socket); 138 139 // This method will send STUN binding request if STUN server address is set. 140 void MaybePrepareStunCandidate(); 141 142 void SendStunBindingRequests(); 143 144 private: 145 // A helper class which can be called repeatedly to resolve multiple 146 // addresses, as opposed to rtc::AsyncResolverInterface, which can only 147 // resolve one address per instance. 148 class AddressResolver : public sigslot::has_slots<> { 149 public: 150 explicit AddressResolver(rtc::PacketSocketFactory* factory); 151 ~AddressResolver(); 152 153 void Resolve(const rtc::SocketAddress& address); 154 bool GetResolvedAddress(const rtc::SocketAddress& input, 155 int family, 156 rtc::SocketAddress* output) const; 157 158 // The signal is sent when resolving the specified address is finished. The 159 // first argument is the input address, the second argument is the error 160 // or 0 if it succeeded. 161 sigslot::signal2<const rtc::SocketAddress&, int> SignalDone; 162 163 private: 164 typedef std::map<rtc::SocketAddress, 165 rtc::AsyncResolverInterface*> ResolverMap; 166 167 void OnResolveResult(rtc::AsyncResolverInterface* resolver); 168 169 rtc::PacketSocketFactory* socket_factory_; 170 ResolverMap resolvers_; 171 }; 172 173 // DNS resolution of the STUN server. 174 void ResolveStunAddress(const rtc::SocketAddress& stun_addr); 175 void OnResolveResult(const rtc::SocketAddress& input, int error); 176 177 void SendStunBindingRequest(const rtc::SocketAddress& stun_addr); 178 179 // Below methods handles binding request responses. 180 void OnStunBindingRequestSucceeded( 181 const rtc::SocketAddress& stun_server_addr, 182 const rtc::SocketAddress& stun_reflected_addr); 183 void OnStunBindingOrResolveRequestFailed( 184 const rtc::SocketAddress& stun_server_addr); 185 186 // Sends STUN requests to the server. 187 void OnSendPacket(const void* data, size_t size, StunRequest* req); 188 189 // TODO(mallinaht) - Move this up to cricket::Port when SignalAddressReady is 190 // changed to SignalPortReady. 191 void MaybeSetPortCompleteOrError(); 192 193 bool HasCandidateWithAddress(const rtc::SocketAddress& addr) const; 194 195 ServerAddresses server_addresses_; 196 ServerAddresses bind_request_succeeded_servers_; 197 ServerAddresses bind_request_failed_servers_; 198 StunRequestManager requests_; 199 rtc::AsyncPacketSocket* socket_; 200 int error_; 201 rtc::scoped_ptr<AddressResolver> resolver_; 202 bool ready_; 203 int stun_keepalive_delay_; 204 205 friend class StunBindingRequest; 206 }; 207 208 class StunPort : public UDPPort { 209 public: Create(rtc::Thread * thread,rtc::PacketSocketFactory * factory,rtc::Network * network,const rtc::IPAddress & ip,uint16 min_port,uint16 max_port,const std::string & username,const std::string & password,const ServerAddresses & servers,const std::string & origin)210 static StunPort* Create(rtc::Thread* thread, 211 rtc::PacketSocketFactory* factory, 212 rtc::Network* network, 213 const rtc::IPAddress& ip, 214 uint16 min_port, uint16 max_port, 215 const std::string& username, 216 const std::string& password, 217 const ServerAddresses& servers, 218 const std::string& origin) { 219 StunPort* port = new StunPort(thread, factory, network, 220 ip, min_port, max_port, 221 username, password, servers, 222 origin); 223 if (!port->Init()) { 224 delete port; 225 port = NULL; 226 } 227 return port; 228 } 229 ~StunPort()230 virtual ~StunPort() {} 231 PrepareAddress()232 virtual void PrepareAddress() { 233 SendStunBindingRequests(); 234 } 235 236 protected: StunPort(rtc::Thread * thread,rtc::PacketSocketFactory * factory,rtc::Network * network,const rtc::IPAddress & ip,uint16 min_port,uint16 max_port,const std::string & username,const std::string & password,const ServerAddresses & servers,const std::string & origin)237 StunPort(rtc::Thread* thread, 238 rtc::PacketSocketFactory* factory, 239 rtc::Network* network, 240 const rtc::IPAddress& ip, 241 uint16 min_port, 242 uint16 max_port, 243 const std::string& username, 244 const std::string& password, 245 const ServerAddresses& servers, 246 const std::string& origin) 247 : UDPPort(thread, factory, network, ip, min_port, max_port, username, 248 password, origin) { 249 // UDPPort will set these to local udp, updating these to STUN. 250 set_type(STUN_PORT_TYPE); 251 set_server_addresses(servers); 252 } 253 }; 254 255 } // namespace cricket 256 257 #endif // WEBRTC_P2P_BASE_STUNPORT_H_ 258