• 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_ALLOCATOR_H_
12 #define P2P_BASE_PORT_ALLOCATOR_H_
13 
14 #include <deque>
15 #include <memory>
16 #include <string>
17 #include <vector>
18 
19 #include "absl/strings/string_view.h"
20 #include "api/sequence_checker.h"
21 #include "api/transport/enums.h"
22 #include "p2p/base/port.h"
23 #include "p2p/base/port_interface.h"
24 #include "rtc_base/helpers.h"
25 #include "rtc_base/proxy_info.h"
26 #include "rtc_base/ssl_certificate.h"
27 #include "rtc_base/system/rtc_export.h"
28 #include "rtc_base/third_party/sigslot/sigslot.h"
29 #include "rtc_base/thread.h"
30 
31 namespace webrtc {
32 class TurnCustomizer;
33 }  // namespace webrtc
34 
35 namespace cricket {
36 
37 // PortAllocator is responsible for allocating Port types for a given
38 // P2PSocket. It also handles port freeing.
39 //
40 // Clients can override this class to control port allocation, including
41 // what kinds of ports are allocated.
42 
43 enum {
44   // Disable local UDP ports. This doesn't impact how we connect to relay
45   // servers.
46   PORTALLOCATOR_DISABLE_UDP = 0x01,
47   PORTALLOCATOR_DISABLE_STUN = 0x02,
48   PORTALLOCATOR_DISABLE_RELAY = 0x04,
49   // Disable local TCP ports. This doesn't impact how we connect to relay
50   // servers.
51   PORTALLOCATOR_DISABLE_TCP = 0x08,
52   PORTALLOCATOR_ENABLE_IPV6 = 0x40,
53   PORTALLOCATOR_ENABLE_SHARED_SOCKET = 0x100,
54   PORTALLOCATOR_ENABLE_STUN_RETRANSMIT_ATTRIBUTE = 0x200,
55   // When specified, we'll only allocate the STUN candidate for the public
56   // interface as seen by regular http traffic and the HOST candidate associated
57   // with the default local interface.
58   PORTALLOCATOR_DISABLE_ADAPTER_ENUMERATION = 0x400,
59   // When specified along with PORTALLOCATOR_DISABLE_ADAPTER_ENUMERATION, the
60   // default local candidate mentioned above will not be allocated. Only the
61   // STUN candidate will be.
62   PORTALLOCATOR_DISABLE_DEFAULT_LOCAL_CANDIDATE = 0x800,
63   // Disallow use of UDP when connecting to a relay server. Since proxy servers
64   // usually don't handle UDP, using UDP will leak the IP address.
65   PORTALLOCATOR_DISABLE_UDP_RELAY = 0x1000,
66 
67   // When multiple networks exist, do not gather candidates on the ones with
68   // high cost. So if both Wi-Fi and cellular networks exist, gather only on the
69   // Wi-Fi network. If a network type is "unknown", it has a cost lower than
70   // cellular but higher than Wi-Fi/Ethernet. So if an unknown network exists,
71   // cellular networks will not be used to gather candidates and if a Wi-Fi
72   // network is present, "unknown" networks will not be usd to gather
73   // candidates. Doing so ensures that even if a cellular network type was not
74   // detected initially, it would not be used if a Wi-Fi network is present.
75   PORTALLOCATOR_DISABLE_COSTLY_NETWORKS = 0x2000,
76 
77   // When specified, do not collect IPv6 ICE candidates on Wi-Fi.
78   PORTALLOCATOR_ENABLE_IPV6_ON_WIFI = 0x4000,
79 
80   // When this flag is set, ports not bound to any specific network interface
81   // will be used, in addition to normal ports bound to the enumerated
82   // interfaces. Without this flag, these "any address" ports would only be
83   // used when network enumeration fails or is disabled. But under certain
84   // conditions, these ports may succeed where others fail, so they may allow
85   // the application to work in a wider variety of environments, at the expense
86   // of having to allocate additional candidates.
87   PORTALLOCATOR_ENABLE_ANY_ADDRESS_PORTS = 0x8000,
88 
89   // Exclude link-local network interfaces
90   // from considertaion after adapter enumeration.
91   PORTALLOCATOR_DISABLE_LINK_LOCAL_NETWORKS = 0x10000,
92 };
93 
94 // Defines various reasons that have caused ICE regathering.
95 enum class IceRegatheringReason {
96   NETWORK_CHANGE,      // Network interfaces on the device changed
97   NETWORK_FAILURE,     // Regather only on networks that have failed
98   OCCASIONAL_REFRESH,  // Periodic regather on all networks
99   MAX_VALUE
100 };
101 
102 const uint32_t kDefaultPortAllocatorFlags = 0;
103 
104 const uint32_t kDefaultStepDelay = 1000;  // 1 sec step delay.
105 // As per RFC 5245 Appendix B.1, STUN transactions need to be paced at certain
106 // internal. Less than 20ms is not acceptable. We choose 50ms as our default.
107 const uint32_t kMinimumStepDelay = 50;
108 
109 // Turning on IPv6 could make many IPv6 interfaces available for connectivity
110 // check and delay the call setup time. kDefaultMaxIPv6Networks is the default
111 // upper limit of IPv6 networks but could be changed by
112 // set_max_ipv6_networks().
113 constexpr int kDefaultMaxIPv6Networks = 5;
114 
115 // CF = CANDIDATE FILTER
116 enum : uint32_t {
117   CF_NONE = 0x0,
118   CF_HOST = 0x1,
119   CF_REFLEXIVE = 0x2,
120   CF_RELAY = 0x4,
121   CF_ALL = 0x7,
122 };
123 
124 // TLS certificate policy.
125 enum class TlsCertPolicy {
126   // For TLS based protocols, ensure the connection is secure by not
127   // circumventing certificate validation.
128   TLS_CERT_POLICY_SECURE,
129   // For TLS based protocols, disregard security completely by skipping
130   // certificate validation. This is insecure and should never be used unless
131   // security is irrelevant in that particular context.
132   TLS_CERT_POLICY_INSECURE_NO_CHECK,
133 };
134 
135 // TODO(deadbeef): Rename to TurnCredentials (and username to ufrag).
136 struct RelayCredentials {
RelayCredentialsRelayCredentials137   RelayCredentials() {}
RelayCredentialsRelayCredentials138   RelayCredentials(absl::string_view username, absl::string_view password)
139       : username(username), password(password) {}
140 
141   bool operator==(const RelayCredentials& o) const {
142     return username == o.username && password == o.password;
143   }
144   bool operator!=(const RelayCredentials& o) const { return !(*this == o); }
145 
146   std::string username;
147   std::string password;
148 };
149 
150 typedef std::vector<ProtocolAddress> PortList;
151 // TODO(deadbeef): Rename to TurnServerConfig.
152 struct RTC_EXPORT RelayServerConfig {
153   RelayServerConfig();
154   RelayServerConfig(const rtc::SocketAddress& address,
155                     absl::string_view username,
156                     absl::string_view password,
157                     ProtocolType proto);
158   RelayServerConfig(absl::string_view address,
159                     int port,
160                     absl::string_view username,
161                     absl::string_view password,
162                     ProtocolType proto);
163   // Legacy constructor where "secure" and PROTO_TCP implies PROTO_TLS.
164   RelayServerConfig(absl::string_view address,
165                     int port,
166                     absl::string_view username,
167                     absl::string_view password,
168                     ProtocolType proto,
169                     bool secure);
170   RelayServerConfig(const RelayServerConfig&);
171   ~RelayServerConfig();
172 
173   bool operator==(const RelayServerConfig& o) const {
174     return ports == o.ports && credentials == o.credentials;
175   }
176   bool operator!=(const RelayServerConfig& o) const { return !(*this == o); }
177 
178   PortList ports;
179   RelayCredentials credentials;
180   TlsCertPolicy tls_cert_policy = TlsCertPolicy::TLS_CERT_POLICY_SECURE;
181   std::vector<std::string> tls_alpn_protocols;
182   std::vector<std::string> tls_elliptic_curves;
183   rtc::SSLCertificateVerifier* tls_cert_verifier = nullptr;
184   std::string turn_logging_id;
185 };
186 
187 class RTC_EXPORT PortAllocatorSession : public sigslot::has_slots<> {
188  public:
189   // Content name passed in mostly for logging and debugging.
190   PortAllocatorSession(absl::string_view content_name,
191                        int component,
192                        absl::string_view ice_ufrag,
193                        absl::string_view ice_pwd,
194                        uint32_t flags);
195 
196   // Subclasses should clean up any ports created.
197   ~PortAllocatorSession() override;
198 
flags()199   uint32_t flags() const { return flags_; }
set_flags(uint32_t flags)200   void set_flags(uint32_t flags) { flags_ = flags; }
content_name()201   std::string content_name() const { return content_name_; }
component()202   int component() const { return component_; }
ice_ufrag()203   const std::string& ice_ufrag() const { return ice_ufrag_; }
ice_pwd()204   const std::string& ice_pwd() const { return ice_pwd_; }
pooled()205   bool pooled() const { return pooled_; }
206 
207   // TODO(bugs.webrtc.org/14605): move this to the constructor
set_ice_tiebreaker(uint64_t tiebreaker)208   void set_ice_tiebreaker(uint64_t tiebreaker) { tiebreaker_ = tiebreaker; }
ice_tiebreaker()209   uint64_t ice_tiebreaker() const { return tiebreaker_; }
210 
211   // Setting this filter should affect not only candidates gathered in the
212   // future, but candidates already gathered and ports already "ready",
213   // which would be returned by ReadyCandidates() and ReadyPorts().
214   //
215   // Default filter should be CF_ALL.
216   virtual void SetCandidateFilter(uint32_t filter) = 0;
217 
218   // Starts gathering ports and ICE candidates.
219   virtual void StartGettingPorts() = 0;
220   // Completely stops gathering. Will not gather again unless StartGettingPorts
221   // is called again.
222   virtual void StopGettingPorts() = 0;
223   // Whether the session is actively getting ports.
224   virtual bool IsGettingPorts() = 0;
225 
226   //
227   // NOTE: The group of methods below is only used for continual gathering.
228   //
229 
230   // ClearGettingPorts should have the same immediate effect as
231   // StopGettingPorts, but if the implementation supports continual gathering,
232   // ClearGettingPorts allows additional ports/candidates to be gathered if the
233   // network conditions change.
234   virtual void ClearGettingPorts() = 0;
235   // Whether it is in the state where the existing gathering process is stopped,
236   // but new ones may be started (basically after calling ClearGettingPorts).
237   virtual bool IsCleared() const;
238   // Whether the session has completely stopped.
239   virtual bool IsStopped() const;
240   // Re-gathers candidates on networks that do not have any connections. More
241   // precisely, a network interface may have more than one IP addresses (e.g.,
242   // IPv4 and IPv6 addresses). Each address subnet will be used to create a
243   // network. Only if all networks of an interface have no connection, the
244   // implementation should start re-gathering on all networks of that interface.
RegatherOnFailedNetworks()245   virtual void RegatherOnFailedNetworks() {}
246   // Get candidate-level stats from all candidates on the ready ports and return
247   // the stats to the given list.
GetCandidateStatsFromReadyPorts(CandidateStatsList * candidate_stats_list)248   virtual void GetCandidateStatsFromReadyPorts(
249       CandidateStatsList* candidate_stats_list) const {}
250   // Set the interval at which STUN candidates will resend STUN binding requests
251   // on the underlying ports to keep NAT bindings open.
252   // The default value of the interval in implementation is restored if a null
253   // optional value is passed.
SetStunKeepaliveIntervalForReadyPorts(const absl::optional<int> & stun_keepalive_interval)254   virtual void SetStunKeepaliveIntervalForReadyPorts(
255       const absl::optional<int>& stun_keepalive_interval) {}
256   // Another way of getting the information provided by the signals below.
257   //
258   // Ports and candidates are not guaranteed to be in the same order as the
259   // signals were emitted in.
260   virtual std::vector<PortInterface*> ReadyPorts() const = 0;
261   virtual std::vector<Candidate> ReadyCandidates() const = 0;
262   virtual bool CandidatesAllocationDone() const = 0;
263   // Marks all ports in the current session as "pruned" so that they may be
264   // destroyed if no connection is using them.
PruneAllPorts()265   virtual void PruneAllPorts() {}
266 
267   sigslot::signal2<PortAllocatorSession*, PortInterface*> SignalPortReady;
268   // Fires this signal when the network of the ports failed (either because the
269   // interface is down, or because there is no connection on the interface),
270   // or when TURN ports are pruned because a higher-priority TURN port becomes
271   // ready(pairable).
272   sigslot::signal2<PortAllocatorSession*, const std::vector<PortInterface*>&>
273       SignalPortsPruned;
274   sigslot::signal2<PortAllocatorSession*, const std::vector<Candidate>&>
275       SignalCandidatesReady;
276   sigslot::signal2<PortAllocatorSession*, const IceCandidateErrorEvent&>
277       SignalCandidateError;
278   // Candidates should be signaled to be removed when the port that generated
279   // the candidates is removed.
280   sigslot::signal2<PortAllocatorSession*, const std::vector<Candidate>&>
281       SignalCandidatesRemoved;
282   sigslot::signal1<PortAllocatorSession*> SignalCandidatesAllocationDone;
283 
284   sigslot::signal2<PortAllocatorSession*, IceRegatheringReason>
285       SignalIceRegathering;
286 
287   virtual uint32_t generation();
288   virtual void set_generation(uint32_t generation);
289 
290  protected:
291   // This method is called when a pooled session (which doesn't have these
292   // properties initially) is returned by PortAllocator::TakePooledSession,
293   // and the content name, component, and ICE ufrag/pwd are updated.
294   //
295   // A subclass may need to override this method to perform additional actions,
296   // such as applying the updated information to ports and candidates.
UpdateIceParametersInternal()297   virtual void UpdateIceParametersInternal() {}
298 
299   // TODO(deadbeef): Get rid of these when everyone switches to ice_ufrag and
300   // ice_pwd.
username()301   const std::string& username() const { return ice_ufrag_; }
password()302   const std::string& password() const { return ice_pwd_; }
303 
304  private:
SetIceParameters(absl::string_view content_name,int component,absl::string_view ice_ufrag,absl::string_view ice_pwd)305   void SetIceParameters(absl::string_view content_name,
306                         int component,
307                         absl::string_view ice_ufrag,
308                         absl::string_view ice_pwd) {
309     content_name_ = std::string(content_name);
310     component_ = component;
311     ice_ufrag_ = std::string(ice_ufrag);
312     ice_pwd_ = std::string(ice_pwd);
313     UpdateIceParametersInternal();
314   }
315 
set_pooled(bool value)316   void set_pooled(bool value) { pooled_ = value; }
317 
318   uint32_t flags_;
319   uint32_t generation_;
320   std::string content_name_;
321   int component_;
322   std::string ice_ufrag_;
323   std::string ice_pwd_;
324 
325   bool pooled_ = false;
326 
327   // TODO(bugs.webrtc.org/14605): move this to the constructor
328   uint64_t tiebreaker_;
329 
330   // SetIceParameters is an implementation detail which only PortAllocator
331   // should be able to call.
332   friend class PortAllocator;
333 };
334 
335 // Every method of PortAllocator (including the destructor) must be called on
336 // the same thread after Initialize is called.
337 //
338 // This allows a PortAllocator subclass to be constructed and configured on one
339 // thread, and passed into an object that uses it on a different thread.
340 class RTC_EXPORT PortAllocator : public sigslot::has_slots<> {
341  public:
342   PortAllocator();
343   ~PortAllocator() override;
344 
345   // This MUST be called on the PortAllocator's thread after finishing
346   // constructing and configuring the PortAllocator subclasses.
347   virtual void Initialize();
348 
349   // Set to true if some Ports need to know the ICE credentials when they are
350   // created. This will ensure that the PortAllocator will only match pooled
351   // allocator sessions to the ICE transport with the same credentials.
352   virtual void set_restrict_ice_credentials_change(bool value);
353 
354   // Set STUN and TURN servers to be used in future sessions, and set
355   // candidate pool size, as described in JSEP.
356   //
357   // If the servers are changing, and the candidate pool size is nonzero, and
358   // FreezeCandidatePool hasn't been called, existing pooled sessions will be
359   // destroyed and new ones created.
360   //
361   // If the servers are not changing but the candidate pool size is, and
362   // FreezeCandidatePool hasn't been called, pooled sessions will be either
363   // created or destroyed as necessary.
364   //
365   // Returns true if the configuration could successfully be changed.
366   // Deprecated
367   bool SetConfiguration(const ServerAddresses& stun_servers,
368                         const std::vector<RelayServerConfig>& turn_servers,
369                         int candidate_pool_size,
370                         bool prune_turn_ports,
371                         webrtc::TurnCustomizer* turn_customizer = nullptr,
372                         const absl::optional<int>&
373                             stun_candidate_keepalive_interval = absl::nullopt);
374   bool SetConfiguration(const ServerAddresses& stun_servers,
375                         const std::vector<RelayServerConfig>& turn_servers,
376                         int candidate_pool_size,
377                         webrtc::PortPrunePolicy turn_port_prune_policy,
378                         webrtc::TurnCustomizer* turn_customizer = nullptr,
379                         const absl::optional<int>&
380                             stun_candidate_keepalive_interval = absl::nullopt);
381 
382   void SetIceTiebreaker(uint64_t tiebreaker);
IceTiebreaker()383   uint64_t IceTiebreaker() const { return tiebreaker_; }
384 
stun_servers()385   const ServerAddresses& stun_servers() const {
386     CheckRunOnValidThreadIfInitialized();
387     return stun_servers_;
388   }
389 
turn_servers()390   const std::vector<RelayServerConfig>& turn_servers() const {
391     CheckRunOnValidThreadIfInitialized();
392     return turn_servers_;
393   }
394 
candidate_pool_size()395   int candidate_pool_size() const {
396     CheckRunOnValidThreadIfInitialized();
397     return candidate_pool_size_;
398   }
399 
stun_candidate_keepalive_interval()400   const absl::optional<int>& stun_candidate_keepalive_interval() const {
401     CheckRunOnValidThreadIfInitialized();
402     return stun_candidate_keepalive_interval_;
403   }
404 
405   // Sets the network types to ignore.
406   // Values are defined by the AdapterType enum.
407   // For instance, calling this with
408   // ADAPTER_TYPE_ETHERNET | ADAPTER_TYPE_LOOPBACK will ignore Ethernet and
409   // loopback interfaces.
410   virtual void SetNetworkIgnoreMask(int network_ignore_mask) = 0;
411 
412   // Set whether VPN connections should be preferred, avoided, mandated or
413   // blocked.
SetVpnPreference(webrtc::VpnPreference preference)414   virtual void SetVpnPreference(webrtc::VpnPreference preference) {
415     vpn_preference_ = preference;
416   }
417 
418   // Set list of <ipaddress, mask> that shall be categorized as VPN.
419   // Implemented by BasicPortAllocator.
SetVpnList(const std::vector<rtc::NetworkMask> & vpn_list)420   virtual void SetVpnList(const std::vector<rtc::NetworkMask>& vpn_list) {}
421 
422   std::unique_ptr<PortAllocatorSession> CreateSession(
423       absl::string_view content_name,
424       int component,
425       absl::string_view ice_ufrag,
426       absl::string_view ice_pwd);
427 
428   // Get an available pooled session and set the transport information on it.
429   //
430   // Caller takes ownership of the returned session.
431   //
432   // If restrict_ice_credentials_change is TRUE, then it will only
433   //   return a pooled session with matching ice credentials.
434   // If no pooled sessions are available, returns null.
435   std::unique_ptr<PortAllocatorSession> TakePooledSession(
436       absl::string_view content_name,
437       int component,
438       absl::string_view ice_ufrag,
439       absl::string_view ice_pwd);
440 
441   // Returns the next session that would be returned by TakePooledSession
442   // optionally restricting it to sessions with specified ice credentials.
443   const PortAllocatorSession* GetPooledSession(
444       const IceParameters* ice_credentials = nullptr) const;
445 
446   // After FreezeCandidatePool is called, changing the candidate pool size will
447   // no longer be allowed, and changing ICE servers will not cause pooled
448   // sessions to be recreated.
449   //
450   // Expected to be called when SetLocalDescription is called on a
451   // PeerConnection. Can be called safely on any thread as long as not
452   // simultaneously with SetConfiguration.
453   void FreezeCandidatePool();
454 
455   // Discard any remaining pooled sessions.
456   void DiscardCandidatePool();
457 
458   // Clears the address and the related address fields of a local candidate to
459   // avoid IP leakage. This is applicable in several scenarios:
460   // 1. Sanitization is configured via the candidate filter.
461   // 2. Sanitization is configured via the port allocator flags.
462   // 3. mDNS concealment of private IPs is enabled.
463   Candidate SanitizeCandidate(const Candidate& c) const;
464 
flags()465   uint32_t flags() const {
466     CheckRunOnValidThreadIfInitialized();
467     return flags_;
468   }
469 
set_flags(uint32_t flags)470   void set_flags(uint32_t flags) {
471     CheckRunOnValidThreadIfInitialized();
472     flags_ = flags;
473   }
474 
475   // These three methods are deprecated. If connections need to go through a
476   // proxy, the application should create a BasicPortAllocator given a custom
477   // PacketSocketFactory that creates proxy sockets.
user_agent()478   const std::string& user_agent() const {
479     CheckRunOnValidThreadIfInitialized();
480     return agent_;
481   }
482 
proxy()483   const rtc::ProxyInfo& proxy() const {
484     CheckRunOnValidThreadIfInitialized();
485     return proxy_;
486   }
487 
set_proxy(absl::string_view agent,const rtc::ProxyInfo & proxy)488   void set_proxy(absl::string_view agent, const rtc::ProxyInfo& proxy) {
489     CheckRunOnValidThreadIfInitialized();
490     agent_ = std::string(agent);
491     proxy_ = proxy;
492   }
493 
494   // Gets/Sets the port range to use when choosing client ports.
min_port()495   int min_port() const {
496     CheckRunOnValidThreadIfInitialized();
497     return min_port_;
498   }
499 
max_port()500   int max_port() const {
501     CheckRunOnValidThreadIfInitialized();
502     return max_port_;
503   }
504 
SetPortRange(int min_port,int max_port)505   bool SetPortRange(int min_port, int max_port) {
506     CheckRunOnValidThreadIfInitialized();
507     if (min_port > max_port) {
508       return false;
509     }
510 
511     min_port_ = min_port;
512     max_port_ = max_port;
513     return true;
514   }
515 
516   // Can be used to change the default numer of IPv6 network interfaces used
517   // (5). Can set to INT_MAX to effectively disable the limit.
518   //
519   // TODO(deadbeef): Applications shouldn't have to arbitrarily limit the
520   // number of available IPv6 network interfaces just because they could slow
521   // ICE down. We should work on making our ICE logic smarter (for example,
522   // prioritizing pinging connections that are most likely to work) so that
523   // every network interface can be used without impacting ICE's speed.
set_max_ipv6_networks(int networks)524   void set_max_ipv6_networks(int networks) {
525     CheckRunOnValidThreadIfInitialized();
526     max_ipv6_networks_ = networks;
527   }
528 
max_ipv6_networks()529   int max_ipv6_networks() {
530     CheckRunOnValidThreadIfInitialized();
531     return max_ipv6_networks_;
532   }
533 
534   // Delay between different candidate gathering phases (UDP, TURN, TCP).
535   // Defaults to 1 second, but PeerConnection sets it to 50ms.
536   // TODO(deadbeef): Get rid of this. Its purpose is to avoid sending too many
537   // STUN transactions at once, but that's already happening if you configure
538   // multiple STUN servers or have multiple network interfaces. We should
539   // implement some global pacing logic instead if that's our goal.
step_delay()540   uint32_t step_delay() const {
541     CheckRunOnValidThreadIfInitialized();
542     return step_delay_;
543   }
544 
set_step_delay(uint32_t delay)545   void set_step_delay(uint32_t delay) {
546     CheckRunOnValidThreadIfInitialized();
547     step_delay_ = delay;
548   }
549 
allow_tcp_listen()550   bool allow_tcp_listen() const {
551     CheckRunOnValidThreadIfInitialized();
552     return allow_tcp_listen_;
553   }
554 
set_allow_tcp_listen(bool allow_tcp_listen)555   void set_allow_tcp_listen(bool allow_tcp_listen) {
556     CheckRunOnValidThreadIfInitialized();
557     allow_tcp_listen_ = allow_tcp_listen;
558   }
559 
candidate_filter()560   uint32_t candidate_filter() {
561     CheckRunOnValidThreadIfInitialized();
562     return candidate_filter_;
563   }
564 
565   // The new filter value will be populated to future allocation sessions, when
566   // they are created via CreateSession, and also pooled sessions when one is
567   // taken via TakePooledSession.
568   //
569   // A change in the candidate filter also fires a signal
570   // `SignalCandidateFilterChanged`, so that objects subscribed to this signal
571   // can, for example, update the candidate filter for sessions created by this
572   // allocator and already taken by the object.
573   //
574   // Specifically for the session taken by the ICE transport, we currently do
575   // not support removing candidate pairs formed with local candidates from this
576   // session that are disabled by the new candidate filter.
577   void SetCandidateFilter(uint32_t filter);
578   // Deprecated.
579   // TODO(qingsi): Remove this after Chromium migrates to the new method.
set_candidate_filter(uint32_t filter)580   void set_candidate_filter(uint32_t filter) { SetCandidateFilter(filter); }
581 
582   // Deprecated (by the next method).
prune_turn_ports()583   bool prune_turn_ports() const {
584     CheckRunOnValidThreadIfInitialized();
585     return turn_port_prune_policy_ == webrtc::PRUNE_BASED_ON_PRIORITY;
586   }
587 
turn_port_prune_policy()588   webrtc::PortPrunePolicy turn_port_prune_policy() const {
589     CheckRunOnValidThreadIfInitialized();
590     return turn_port_prune_policy_;
591   }
592 
turn_customizer()593   webrtc::TurnCustomizer* turn_customizer() {
594     CheckRunOnValidThreadIfInitialized();
595     return turn_customizer_;
596   }
597 
598   // Collect candidate stats from pooled allocator sessions. This can be used to
599   // collect candidate stats without creating an offer/answer or setting local
600   // description. After the local description is set, the ownership of the
601   // pooled session is taken by P2PTransportChannel, and the
602   // candidate stats can be collected from P2PTransportChannel::GetStats.
603   virtual void GetCandidateStatsFromPooledSessions(
604       CandidateStatsList* candidate_stats_list);
605 
606   // Return IceParameters of the pooled sessions.
607   std::vector<IceParameters> GetPooledIceCredentials();
608 
609   // Fired when `candidate_filter_` changes.
610   sigslot::signal2<uint32_t /* prev_filter */, uint32_t /* cur_filter */>
611       SignalCandidateFilterChanged;
612 
613  protected:
614   // TODO(webrtc::13579): Remove std::string version once downstream users have
615   // migrated to the absl::string_view version.
616   virtual PortAllocatorSession* CreateSessionInternal(
617       absl::string_view content_name,
618       int component,
619       absl::string_view ice_ufrag,
620       absl::string_view ice_pwd) = 0;
621 
pooled_sessions()622   const std::vector<std::unique_ptr<PortAllocatorSession>>& pooled_sessions() {
623     return pooled_sessions_;
624   }
625 
626   // Returns true if there is an mDNS responder attached to the network manager.
MdnsObfuscationEnabled()627   virtual bool MdnsObfuscationEnabled() const { return false; }
628 
629   // The following thread checks are only done in DCHECK for the consistency
630   // with the exsiting thread checks.
CheckRunOnValidThreadIfInitialized()631   void CheckRunOnValidThreadIfInitialized() const {
632     RTC_DCHECK(!initialized_ || thread_checker_.IsCurrent());
633   }
634 
CheckRunOnValidThreadAndInitialized()635   void CheckRunOnValidThreadAndInitialized() const {
636     RTC_DCHECK(initialized_ && thread_checker_.IsCurrent());
637   }
638 
639   bool initialized_ = false;
640   uint32_t flags_;
641   std::string agent_;
642   rtc::ProxyInfo proxy_;
643   int min_port_;
644   int max_port_;
645   int max_ipv6_networks_;
646   uint32_t step_delay_;
647   bool allow_tcp_listen_;
648   uint32_t candidate_filter_;
649   std::string origin_;
650   webrtc::SequenceChecker thread_checker_;
651   webrtc::VpnPreference vpn_preference_ = webrtc::VpnPreference::kDefault;
652 
653  private:
654   ServerAddresses stun_servers_;
655   std::vector<RelayServerConfig> turn_servers_;
656   int candidate_pool_size_ = 0;  // Last value passed into SetConfiguration.
657   std::vector<std::unique_ptr<PortAllocatorSession>> pooled_sessions_;
658   bool candidate_pool_frozen_ = false;
659   webrtc::PortPrunePolicy turn_port_prune_policy_ = webrtc::NO_PRUNE;
660 
661   // Customizer for TURN messages.
662   // The instance is owned by application and will be shared among
663   // all TurnPort(s) created.
664   webrtc::TurnCustomizer* turn_customizer_ = nullptr;
665 
666   absl::optional<int> stun_candidate_keepalive_interval_;
667 
668   // If true, TakePooledSession() will only return sessions that has same ice
669   // credentials as requested.
670   bool restrict_ice_credentials_change_ = false;
671 
672   // Returns iterator to pooled session with specified ice_credentials or first
673   // if ice_credentials is nullptr.
674   std::vector<std::unique_ptr<PortAllocatorSession>>::const_iterator
675   FindPooledSession(const IceParameters* ice_credentials = nullptr) const;
676 
677   // ICE tie breaker.
678   uint64_t tiebreaker_;
679 };
680 
681 }  // namespace cricket
682 
683 #endif  // P2P_BASE_PORT_ALLOCATOR_H_
684