• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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