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_PORT_H_ 12 #define P2P_BASE_PORT_H_ 13 14 #include <map> 15 #include <memory> 16 #include <set> 17 #include <string> 18 #include <utility> 19 #include <vector> 20 21 #include "absl/types/optional.h" 22 #include "api/candidate.h" 23 #include "api/packet_socket_factory.h" 24 #include "api/rtc_error.h" 25 #include "api/transport/stun.h" 26 #include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair.h" 27 #include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h" 28 #include "logging/rtc_event_log/ice_logger.h" 29 #include "p2p/base/candidate_pair_interface.h" 30 #include "p2p/base/connection.h" 31 #include "p2p/base/connection_info.h" 32 #include "p2p/base/p2p_constants.h" 33 #include "p2p/base/port_interface.h" 34 #include "p2p/base/stun_request.h" 35 #include "rtc_base/async_packet_socket.h" 36 #include "rtc_base/checks.h" 37 #include "rtc_base/net_helper.h" 38 #include "rtc_base/network.h" 39 #include "rtc_base/proxy_info.h" 40 #include "rtc_base/rate_tracker.h" 41 #include "rtc_base/socket_address.h" 42 #include "rtc_base/system/rtc_export.h" 43 #include "rtc_base/third_party/sigslot/sigslot.h" 44 #include "rtc_base/thread.h" 45 #include "rtc_base/weak_ptr.h" 46 47 namespace cricket { 48 49 RTC_EXPORT extern const char LOCAL_PORT_TYPE[]; 50 RTC_EXPORT extern const char STUN_PORT_TYPE[]; 51 RTC_EXPORT extern const char PRFLX_PORT_TYPE[]; 52 RTC_EXPORT extern const char RELAY_PORT_TYPE[]; 53 54 // RFC 6544, TCP candidate encoding rules. 55 extern const int DISCARD_PORT; 56 extern const char TCPTYPE_ACTIVE_STR[]; 57 extern const char TCPTYPE_PASSIVE_STR[]; 58 extern const char TCPTYPE_SIMOPEN_STR[]; 59 60 enum IcePriorityValue { 61 ICE_TYPE_PREFERENCE_RELAY_TLS = 0, 62 ICE_TYPE_PREFERENCE_RELAY_TCP = 1, 63 ICE_TYPE_PREFERENCE_RELAY_UDP = 2, 64 ICE_TYPE_PREFERENCE_PRFLX_TCP = 80, 65 ICE_TYPE_PREFERENCE_HOST_TCP = 90, 66 ICE_TYPE_PREFERENCE_SRFLX = 100, 67 ICE_TYPE_PREFERENCE_PRFLX = 110, 68 ICE_TYPE_PREFERENCE_HOST = 126 69 }; 70 71 enum class MdnsNameRegistrationStatus { 72 // IP concealment with mDNS is not enabled or the name registration process is 73 // not started yet. 74 kNotStarted, 75 // A request to create and register an mDNS name for a local IP address of a 76 // host candidate is sent to the mDNS responder. 77 kInProgress, 78 // The name registration is complete and the created name is returned by the 79 // mDNS responder. 80 kCompleted, 81 }; 82 83 // Stats that we can return about the port of a STUN candidate. 84 class StunStats { 85 public: 86 StunStats() = default; 87 StunStats(const StunStats&) = default; 88 ~StunStats() = default; 89 90 StunStats& operator=(const StunStats& other) = default; 91 92 int stun_binding_requests_sent = 0; 93 int stun_binding_responses_received = 0; 94 double stun_binding_rtt_ms_total = 0; 95 double stun_binding_rtt_ms_squared_total = 0; 96 }; 97 98 // Stats that we can return about a candidate. 99 class CandidateStats { 100 public: 101 CandidateStats(); 102 explicit CandidateStats(Candidate candidate); 103 CandidateStats(const CandidateStats&); 104 ~CandidateStats(); 105 106 Candidate candidate; 107 // STUN port stats if this candidate is a STUN candidate. 108 absl::optional<StunStats> stun_stats; 109 }; 110 111 typedef std::vector<CandidateStats> CandidateStatsList; 112 113 const char* ProtoToString(ProtocolType proto); 114 bool StringToProto(const char* value, ProtocolType* proto); 115 116 struct ProtocolAddress { 117 rtc::SocketAddress address; 118 ProtocolType proto; 119 ProtocolAddressProtocolAddress120 ProtocolAddress(const rtc::SocketAddress& a, ProtocolType p) 121 : address(a), proto(p) {} 122 123 bool operator==(const ProtocolAddress& o) const { 124 return address == o.address && proto == o.proto; 125 } 126 bool operator!=(const ProtocolAddress& o) const { return !(*this == o); } 127 }; 128 129 struct IceCandidateErrorEvent { 130 IceCandidateErrorEvent() = default; IceCandidateErrorEventIceCandidateErrorEvent131 IceCandidateErrorEvent(std::string address, 132 int port, 133 std::string url, 134 int error_code, 135 std::string error_text) 136 : address(std::move(address)), 137 port(port), 138 url(std::move(url)), 139 error_code(error_code), 140 error_text(std::move(error_text)) {} 141 142 std::string address; 143 int port = 0; 144 std::string url; 145 int error_code = 0; 146 std::string error_text; 147 }; 148 149 struct CandidatePairChangeEvent { 150 CandidatePair selected_candidate_pair; 151 int64_t last_data_received_ms; 152 std::string reason; 153 }; 154 155 typedef std::set<rtc::SocketAddress> ServerAddresses; 156 157 // Represents a local communication mechanism that can be used to create 158 // connections to similar mechanisms of the other client. Subclasses of this 159 // one add support for specific mechanisms like local UDP ports. 160 class Port : public PortInterface, 161 public rtc::MessageHandler, 162 public sigslot::has_slots<> { 163 public: 164 // INIT: The state when a port is just created. 165 // KEEP_ALIVE_UNTIL_PRUNED: A port should not be destroyed even if no 166 // connection is using it. 167 // PRUNED: It will be destroyed if no connection is using it for a period of 168 // 30 seconds. 169 enum class State { INIT, KEEP_ALIVE_UNTIL_PRUNED, PRUNED }; 170 Port(rtc::Thread* thread, 171 const std::string& type, 172 rtc::PacketSocketFactory* factory, 173 rtc::Network* network, 174 const std::string& username_fragment, 175 const std::string& password); 176 Port(rtc::Thread* thread, 177 const std::string& type, 178 rtc::PacketSocketFactory* factory, 179 rtc::Network* network, 180 uint16_t min_port, 181 uint16_t max_port, 182 const std::string& username_fragment, 183 const std::string& password); 184 ~Port() override; 185 186 // Note that the port type does NOT uniquely identify different subclasses of 187 // Port. Use the 2-tuple of the port type AND the protocol (GetProtocol()) to 188 // uniquely identify subclasses. Whenever a new subclass of Port introduces a 189 // conflit in the value of the 2-tuple, make sure that the implementation that 190 // relies on this 2-tuple for RTTI is properly changed. 191 const std::string& Type() const override; 192 rtc::Network* Network() const override; 193 194 // Methods to set/get ICE role and tiebreaker values. 195 IceRole GetIceRole() const override; 196 void SetIceRole(IceRole role) override; 197 198 void SetIceTiebreaker(uint64_t tiebreaker) override; 199 uint64_t IceTiebreaker() const override; 200 201 bool SharedSocket() const override; ResetSharedSocket()202 void ResetSharedSocket() { shared_socket_ = false; } 203 204 // Should not destroy the port even if no connection is using it. Called when 205 // a port is ready to use. 206 void KeepAliveUntilPruned(); 207 // Allows a port to be destroyed if no connection is using it. 208 void Prune(); 209 210 // The thread on which this port performs its I/O. thread()211 rtc::Thread* thread() { return thread_; } 212 213 // The factory used to create the sockets of this port. socket_factory()214 rtc::PacketSocketFactory* socket_factory() const { return factory_; } set_socket_factory(rtc::PacketSocketFactory * factory)215 void set_socket_factory(rtc::PacketSocketFactory* factory) { 216 factory_ = factory; 217 } 218 219 // For debugging purposes. content_name()220 const std::string& content_name() const { return content_name_; } set_content_name(const std::string & content_name)221 void set_content_name(const std::string& content_name) { 222 content_name_ = content_name; 223 } 224 component()225 int component() const { return component_; } set_component(int component)226 void set_component(int component) { component_ = component; } 227 send_retransmit_count_attribute()228 bool send_retransmit_count_attribute() const { 229 return send_retransmit_count_attribute_; 230 } set_send_retransmit_count_attribute(bool enable)231 void set_send_retransmit_count_attribute(bool enable) { 232 send_retransmit_count_attribute_ = enable; 233 } 234 235 // Identifies the generation that this port was created in. generation()236 uint32_t generation() const { return generation_; } set_generation(uint32_t generation)237 void set_generation(uint32_t generation) { generation_ = generation; } 238 239 const std::string username_fragment() const; password()240 const std::string& password() const { return password_; } 241 242 // May be called when this port was initially created by a pooled 243 // PortAllocatorSession, and is now being assigned to an ICE transport. 244 // Updates the information for candidates as well. 245 void SetIceParameters(int component, 246 const std::string& username_fragment, 247 const std::string& password); 248 249 // Fired when candidates are discovered by the port. When all candidates 250 // are discovered that belong to port SignalAddressReady is fired. 251 sigslot::signal2<Port*, const Candidate&> SignalCandidateReady; 252 // Provides all of the above information in one handy object. 253 const std::vector<Candidate>& Candidates() const override; 254 // Fired when candidate discovery failed using certain server. 255 sigslot::signal2<Port*, const IceCandidateErrorEvent&> SignalCandidateError; 256 257 // SignalPortComplete is sent when port completes the task of candidates 258 // allocation. 259 sigslot::signal1<Port*> SignalPortComplete; 260 // This signal sent when port fails to allocate candidates and this port 261 // can't be used in establishing the connections. When port is in shared mode 262 // and port fails to allocate one of the candidates, port shouldn't send 263 // this signal as other candidates might be usefull in establishing the 264 // connection. 265 sigslot::signal1<Port*> SignalPortError; 266 267 // Returns a map containing all of the connections of this port, keyed by the 268 // remote address. 269 typedef std::map<rtc::SocketAddress, Connection*> AddressMap; connections()270 const AddressMap& connections() { return connections_; } 271 272 // Returns the connection to the given address or NULL if none exists. 273 Connection* GetConnection(const rtc::SocketAddress& remote_addr) override; 274 275 // Called each time a connection is created. 276 sigslot::signal2<Port*, Connection*> SignalConnectionCreated; 277 278 // In a shared socket mode each port which shares the socket will decide 279 // to accept the packet based on the |remote_addr|. Currently only UDP 280 // port implemented this method. 281 // TODO(mallinath) - Make it pure virtual. 282 virtual bool HandleIncomingPacket(rtc::AsyncPacketSocket* socket, 283 const char* data, 284 size_t size, 285 const rtc::SocketAddress& remote_addr, 286 int64_t packet_time_us); 287 288 // Shall the port handle packet from this |remote_addr|. 289 // This method is overridden by TurnPort. 290 virtual bool CanHandleIncomingPacketsFrom( 291 const rtc::SocketAddress& remote_addr) const; 292 293 // Sends a response error to the given request. 294 void SendBindingErrorResponse(StunMessage* request, 295 const rtc::SocketAddress& addr, 296 int error_code, 297 const std::string& reason) override; 298 void SendUnknownAttributesErrorResponse( 299 StunMessage* request, 300 const rtc::SocketAddress& addr, 301 const std::vector<uint16_t>& unknown_types); 302 set_proxy(const std::string & user_agent,const rtc::ProxyInfo & proxy)303 void set_proxy(const std::string& user_agent, const rtc::ProxyInfo& proxy) { 304 user_agent_ = user_agent; 305 proxy_ = proxy; 306 } user_agent()307 const std::string& user_agent() { return user_agent_; } proxy()308 const rtc::ProxyInfo& proxy() { return proxy_; } 309 310 void EnablePortPackets() override; 311 312 // Called if the port has no connections and is no longer useful. 313 void Destroy(); 314 315 void OnMessage(rtc::Message* pmsg) override; 316 317 // Debugging description of this port 318 std::string ToString() const override; min_port()319 uint16_t min_port() { return min_port_; } max_port()320 uint16_t max_port() { return max_port_; } 321 322 // Timeout shortening function to speed up unit tests. set_timeout_delay(int delay)323 void set_timeout_delay(int delay) { timeout_delay_ = delay; } 324 325 // This method will return local and remote username fragements from the 326 // stun username attribute if present. 327 bool ParseStunUsername(const StunMessage* stun_msg, 328 std::string* local_username, 329 std::string* remote_username) const; 330 void CreateStunUsername(const std::string& remote_username, 331 std::string* stun_username_attr_str) const; 332 333 bool MaybeIceRoleConflict(const rtc::SocketAddress& addr, 334 IceMessage* stun_msg, 335 const std::string& remote_ufrag); 336 337 // Called when a packet has been sent to the socket. 338 // This is made pure virtual to notify subclasses of Port that they MUST 339 // listen to AsyncPacketSocket::SignalSentPacket and then call 340 // PortInterface::OnSentPacket. 341 virtual void OnSentPacket(rtc::AsyncPacketSocket* socket, 342 const rtc::SentPacket& sent_packet) = 0; 343 344 // Called when the socket is currently able to send. 345 void OnReadyToSend(); 346 347 // Called when the Connection discovers a local peer reflexive candidate. 348 // Returns the index of the new local candidate. 349 size_t AddPrflxCandidate(const Candidate& local); 350 network_cost()351 int16_t network_cost() const { return network_cost_; } 352 GetStunStats(absl::optional<StunStats> * stats)353 void GetStunStats(absl::optional<StunStats>* stats) override {} 354 355 // Foundation: An arbitrary string that is the same for two candidates 356 // that have the same type, base IP address, protocol (UDP, TCP, 357 // etc.), and STUN or TURN server. If any of these are different, 358 // then the foundation will be different. Two candidate pairs with 359 // the same foundation pairs are likely to have similar network 360 // characteristics. Foundations are used in the frozen algorithm. 361 static std::string ComputeFoundation(const std::string& type, 362 const std::string& protocol, 363 const std::string& relay_protocol, 364 const rtc::SocketAddress& base_address); 365 366 protected: 367 enum { MSG_DESTROY_IF_DEAD = 0, MSG_FIRST_AVAILABLE }; 368 369 virtual void UpdateNetworkCost(); 370 set_type(const std::string & type)371 void set_type(const std::string& type) { type_ = type; } 372 373 void AddAddress(const rtc::SocketAddress& address, 374 const rtc::SocketAddress& base_address, 375 const rtc::SocketAddress& related_address, 376 const std::string& protocol, 377 const std::string& relay_protocol, 378 const std::string& tcptype, 379 const std::string& type, 380 uint32_t type_preference, 381 uint32_t relay_preference, 382 const std::string& url, 383 bool is_final); 384 385 void FinishAddingAddress(const Candidate& c, bool is_final); 386 387 virtual void PostAddAddress(bool is_final); 388 389 // Adds the given connection to the map keyed by the remote candidate address. 390 // If an existing connection has the same address, the existing one will be 391 // replaced and destroyed. 392 void AddOrReplaceConnection(Connection* conn); 393 394 // Called when a packet is received from an unknown address that is not 395 // currently a connection. If this is an authenticated STUN binding request, 396 // then we will signal the client. 397 void OnReadPacket(const char* data, 398 size_t size, 399 const rtc::SocketAddress& addr, 400 ProtocolType proto); 401 402 // If the given data comprises a complete and correct STUN message then the 403 // return value is true, otherwise false. If the message username corresponds 404 // with this port's username fragment, msg will contain the parsed STUN 405 // message. Otherwise, the function may send a STUN response internally. 406 // remote_username contains the remote fragment of the STUN username. 407 bool GetStunMessage(const char* data, 408 size_t size, 409 const rtc::SocketAddress& addr, 410 std::unique_ptr<IceMessage>* out_msg, 411 std::string* out_username); 412 413 // Checks if the address in addr is compatible with the port's ip. 414 bool IsCompatibleAddress(const rtc::SocketAddress& addr); 415 416 // Returns DSCP value packets generated by the port itself should use. 417 virtual rtc::DiffServCodePoint StunDscpValue() const; 418 419 // Extra work to be done in subclasses when a connection is destroyed. HandleConnectionDestroyed(Connection * conn)420 virtual void HandleConnectionDestroyed(Connection* conn) {} 421 422 void CopyPortInformationToPacketInfo(rtc::PacketInfo* info) const; 423 mdns_name_registration_status()424 MdnsNameRegistrationStatus mdns_name_registration_status() const { 425 return mdns_name_registration_status_; 426 } set_mdns_name_registration_status(MdnsNameRegistrationStatus status)427 void set_mdns_name_registration_status(MdnsNameRegistrationStatus status) { 428 mdns_name_registration_status_ = status; 429 } 430 431 private: 432 void Construct(); 433 // Called when one of our connections deletes itself. 434 void OnConnectionDestroyed(Connection* conn); 435 436 void OnNetworkTypeChanged(const rtc::Network* network); 437 438 rtc::Thread* thread_; 439 rtc::PacketSocketFactory* factory_; 440 std::string type_; 441 bool send_retransmit_count_attribute_; 442 rtc::Network* network_; 443 uint16_t min_port_; 444 uint16_t max_port_; 445 std::string content_name_; 446 int component_; 447 uint32_t generation_; 448 // In order to establish a connection to this Port (so that real data can be 449 // sent through), the other side must send us a STUN binding request that is 450 // authenticated with this username_fragment and password. 451 // PortAllocatorSession will provide these username_fragment and password. 452 // 453 // Note: we should always use username_fragment() instead of using 454 // |ice_username_fragment_| directly. For the details see the comment on 455 // username_fragment(). 456 std::string ice_username_fragment_; 457 std::string password_; 458 std::vector<Candidate> candidates_; 459 AddressMap connections_; 460 int timeout_delay_; 461 bool enable_port_packets_; 462 IceRole ice_role_; 463 uint64_t tiebreaker_; 464 bool shared_socket_; 465 // Information to use when going through a proxy. 466 std::string user_agent_; 467 rtc::ProxyInfo proxy_; 468 469 // A virtual cost perceived by the user, usually based on the network type 470 // (WiFi. vs. Cellular). It takes precedence over the priority when 471 // comparing two connections. 472 int16_t network_cost_; 473 State state_ = State::INIT; 474 int64_t last_time_all_connections_removed_ = 0; 475 MdnsNameRegistrationStatus mdns_name_registration_status_ = 476 MdnsNameRegistrationStatus::kNotStarted; 477 478 rtc::WeakPtrFactory<Port> weak_factory_; 479 480 bool MaybeObfuscateAddress(Candidate* c, 481 const std::string& type, 482 bool is_final); 483 484 friend class Connection; 485 }; 486 487 } // namespace cricket 488 489 #endif // P2P_BASE_PORT_H_ 490