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