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 P2P_BASE_STUN_PORT_H_ 12 #define P2P_BASE_STUN_PORT_H_ 13 14 #include <map> 15 #include <memory> 16 #include <string> 17 18 #include "absl/memory/memory.h" 19 #include "p2p/base/port.h" 20 #include "p2p/base/stun_request.h" 21 #include "rtc_base/async_packet_socket.h" 22 23 // TODO(mallinath) - Rename stunport.cc|h to udpport.cc|h. 24 25 namespace cricket { 26 27 // Lifetime chosen for STUN ports on low-cost networks. 28 static const int INFINITE_LIFETIME = -1; 29 // Lifetime for STUN ports on high-cost networks: 2 minutes 30 static const int HIGH_COST_PORT_KEEPALIVE_LIFETIME = 2 * 60 * 1000; 31 32 // Communicates using the address on the outside of a NAT. 33 class UDPPort : public Port { 34 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,bool emit_local_for_anyaddress,absl::optional<int> stun_keepalive_interval)35 static std::unique_ptr<UDPPort> Create( 36 rtc::Thread* thread, 37 rtc::PacketSocketFactory* factory, 38 rtc::Network* network, 39 rtc::AsyncPacketSocket* socket, 40 const std::string& username, 41 const std::string& password, 42 const std::string& origin, 43 bool emit_local_for_anyaddress, 44 absl::optional<int> stun_keepalive_interval) { 45 // Using `new` to access a non-public constructor. 46 auto port = absl::WrapUnique(new UDPPort(thread, factory, network, socket, 47 username, password, origin, 48 emit_local_for_anyaddress)); 49 port->set_stun_keepalive_delay(stun_keepalive_interval); 50 if (!port->Init()) { 51 return nullptr; 52 } 53 return port; 54 } 55 Create(rtc::Thread * thread,rtc::PacketSocketFactory * factory,rtc::Network * network,uint16_t min_port,uint16_t max_port,const std::string & username,const std::string & password,const std::string & origin,bool emit_local_for_anyaddress,absl::optional<int> stun_keepalive_interval)56 static std::unique_ptr<UDPPort> Create( 57 rtc::Thread* thread, 58 rtc::PacketSocketFactory* factory, 59 rtc::Network* network, 60 uint16_t min_port, 61 uint16_t max_port, 62 const std::string& username, 63 const std::string& password, 64 const std::string& origin, 65 bool emit_local_for_anyaddress, 66 absl::optional<int> stun_keepalive_interval) { 67 // Using `new` to access a non-public constructor. 68 auto port = absl::WrapUnique( 69 new UDPPort(thread, factory, network, min_port, max_port, username, 70 password, origin, emit_local_for_anyaddress)); 71 port->set_stun_keepalive_delay(stun_keepalive_interval); 72 if (!port->Init()) { 73 return nullptr; 74 } 75 return port; 76 } 77 78 ~UDPPort() override; 79 GetLocalAddress()80 rtc::SocketAddress GetLocalAddress() const { 81 return socket_->GetLocalAddress(); 82 } 83 server_addresses()84 const ServerAddresses& server_addresses() const { return server_addresses_; } set_server_addresses(const ServerAddresses & addresses)85 void set_server_addresses(const ServerAddresses& addresses) { 86 server_addresses_ = addresses; 87 } 88 89 void PrepareAddress() override; 90 91 Connection* CreateConnection(const Candidate& address, 92 CandidateOrigin origin) override; 93 int SetOption(rtc::Socket::Option opt, int value) override; 94 int GetOption(rtc::Socket::Option opt, int* value) override; 95 int GetError() override; 96 97 bool HandleIncomingPacket(rtc::AsyncPacketSocket* socket, 98 const char* data, 99 size_t size, 100 const rtc::SocketAddress& remote_addr, 101 int64_t packet_time_us) override; 102 103 bool SupportsProtocol(const std::string& protocol) const override; 104 ProtocolType GetProtocol() const override; 105 106 void GetStunStats(absl::optional<StunStats>* stats) override; 107 108 void set_stun_keepalive_delay(const absl::optional<int>& delay); stun_keepalive_delay()109 int stun_keepalive_delay() const { return stun_keepalive_delay_; } 110 111 // Visible for testing. stun_keepalive_lifetime()112 int stun_keepalive_lifetime() const { return stun_keepalive_lifetime_; } set_stun_keepalive_lifetime(int lifetime)113 void set_stun_keepalive_lifetime(int lifetime) { 114 stun_keepalive_lifetime_ = lifetime; 115 } 116 // Returns true if there is a pending request with type |msg_type|. HasPendingRequest(int msg_type)117 bool HasPendingRequest(int msg_type) { 118 return requests_.HasRequest(msg_type); 119 } 120 121 protected: 122 UDPPort(rtc::Thread* thread, 123 rtc::PacketSocketFactory* factory, 124 rtc::Network* network, 125 uint16_t min_port, 126 uint16_t max_port, 127 const std::string& username, 128 const std::string& password, 129 const std::string& origin, 130 bool emit_local_for_anyaddress); 131 132 UDPPort(rtc::Thread* thread, 133 rtc::PacketSocketFactory* factory, 134 rtc::Network* network, 135 rtc::AsyncPacketSocket* socket, 136 const std::string& username, 137 const std::string& password, 138 const std::string& origin, 139 bool emit_local_for_anyaddress); 140 141 bool Init(); 142 143 int SendTo(const void* data, 144 size_t size, 145 const rtc::SocketAddress& addr, 146 const rtc::PacketOptions& options, 147 bool payload) override; 148 149 void UpdateNetworkCost() override; 150 151 rtc::DiffServCodePoint StunDscpValue() const override; 152 153 void OnLocalAddressReady(rtc::AsyncPacketSocket* socket, 154 const rtc::SocketAddress& address); 155 156 void PostAddAddress(bool is_final) override; 157 158 void OnReadPacket(rtc::AsyncPacketSocket* socket, 159 const char* data, 160 size_t size, 161 const rtc::SocketAddress& remote_addr, 162 const int64_t& packet_time_us); 163 164 void OnSentPacket(rtc::AsyncPacketSocket* socket, 165 const rtc::SentPacket& sent_packet) override; 166 167 void OnReadyToSend(rtc::AsyncPacketSocket* socket); 168 169 // This method will send STUN binding request if STUN server address is set. 170 void MaybePrepareStunCandidate(); 171 172 void SendStunBindingRequests(); 173 174 // Helper function which will set |addr|'s IP to the default local address if 175 // |addr| is the "any" address and |emit_local_for_anyaddress_| is true. When 176 // returning false, it indicates that the operation has failed and the 177 // address shouldn't be used by any candidate. 178 bool MaybeSetDefaultLocalAddress(rtc::SocketAddress* addr) const; 179 180 private: 181 // A helper class which can be called repeatedly to resolve multiple 182 // addresses, as opposed to rtc::AsyncResolverInterface, which can only 183 // resolve one address per instance. 184 class AddressResolver : public sigslot::has_slots<> { 185 public: 186 explicit AddressResolver(rtc::PacketSocketFactory* factory); 187 ~AddressResolver() override; 188 189 void Resolve(const rtc::SocketAddress& address); 190 bool GetResolvedAddress(const rtc::SocketAddress& input, 191 int family, 192 rtc::SocketAddress* output) const; 193 194 // The signal is sent when resolving the specified address is finished. The 195 // first argument is the input address, the second argument is the error 196 // or 0 if it succeeded. 197 sigslot::signal2<const rtc::SocketAddress&, int> SignalDone; 198 199 private: 200 typedef std::map<rtc::SocketAddress, rtc::AsyncResolverInterface*> 201 ResolverMap; 202 203 void OnResolveResult(rtc::AsyncResolverInterface* resolver); 204 205 rtc::PacketSocketFactory* socket_factory_; 206 ResolverMap resolvers_; 207 }; 208 209 // DNS resolution of the STUN server. 210 void ResolveStunAddress(const rtc::SocketAddress& stun_addr); 211 void OnResolveResult(const rtc::SocketAddress& input, int error); 212 213 void SendStunBindingRequest(const rtc::SocketAddress& stun_addr); 214 215 // Below methods handles binding request responses. 216 void OnStunBindingRequestSucceeded( 217 int rtt_ms, 218 const rtc::SocketAddress& stun_server_addr, 219 const rtc::SocketAddress& stun_reflected_addr); 220 void OnStunBindingOrResolveRequestFailed( 221 const rtc::SocketAddress& stun_server_addr, 222 int error_code, 223 const std::string& reason); 224 225 // Sends STUN requests to the server. 226 void OnSendPacket(const void* data, size_t size, StunRequest* req); 227 228 // TODO(mallinaht) - Move this up to cricket::Port when SignalAddressReady is 229 // changed to SignalPortReady. 230 void MaybeSetPortCompleteOrError(); 231 232 bool HasCandidateWithAddress(const rtc::SocketAddress& addr) const; 233 234 // If this is a low-cost network, it will keep on sending STUN binding 235 // requests indefinitely to keep the NAT binding alive. Otherwise, stop 236 // sending STUN binding requests after HIGH_COST_PORT_KEEPALIVE_LIFETIME. GetStunKeepaliveLifetime()237 int GetStunKeepaliveLifetime() { 238 return (network_cost() >= rtc::kNetworkCostHigh) 239 ? HIGH_COST_PORT_KEEPALIVE_LIFETIME 240 : INFINITE_LIFETIME; 241 } 242 243 ServerAddresses server_addresses_; 244 ServerAddresses bind_request_succeeded_servers_; 245 ServerAddresses bind_request_failed_servers_; 246 StunRequestManager requests_; 247 rtc::AsyncPacketSocket* socket_; 248 int error_; 249 int send_error_count_ = 0; 250 std::unique_ptr<AddressResolver> resolver_; 251 bool ready_; 252 int stun_keepalive_delay_; 253 int stun_keepalive_lifetime_ = INFINITE_LIFETIME; 254 rtc::DiffServCodePoint dscp_; 255 256 StunStats stats_; 257 258 // This is true by default and false when 259 // PORTALLOCATOR_DISABLE_DEFAULT_LOCAL_CANDIDATE is specified. 260 bool emit_local_for_anyaddress_; 261 262 friend class StunBindingRequest; 263 }; 264 265 class StunPort : public UDPPort { 266 public: 267 static std::unique_ptr<StunPort> Create( 268 rtc::Thread* thread, 269 rtc::PacketSocketFactory* factory, 270 rtc::Network* network, 271 uint16_t min_port, 272 uint16_t max_port, 273 const std::string& username, 274 const std::string& password, 275 const ServerAddresses& servers, 276 const std::string& origin, 277 absl::optional<int> stun_keepalive_interval); 278 279 void PrepareAddress() override; 280 281 protected: 282 StunPort(rtc::Thread* thread, 283 rtc::PacketSocketFactory* factory, 284 rtc::Network* network, 285 uint16_t min_port, 286 uint16_t max_port, 287 const std::string& username, 288 const std::string& password, 289 const ServerAddresses& servers, 290 const std::string& origin); 291 }; 292 293 } // namespace cricket 294 295 #endif // P2P_BASE_STUN_PORT_H_ 296