/*
 *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef P2P_BASE_PORT_ALLOCATOR_H_
#define P2P_BASE_PORT_ALLOCATOR_H_

#include <cstdint>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>

#include "absl/functional/any_invocable.h"
#include "absl/strings/string_view.h"
#include "api/candidate.h"
#include "api/sequence_checker.h"
#include "api/transport/enums.h"
#include "api/units/time_delta.h"
#include "p2p/base/port.h"
#include "p2p/base/port_interface.h"
#include "p2p/base/transport_description.h"
#include "rtc_base/callback_list.h"
#include "rtc_base/checks.h"
#include "rtc_base/net_helper.h"
#include "rtc_base/network.h"
#include "rtc_base/socket_address.h"
#include "rtc_base/ssl_certificate.h"
#include "rtc_base/system/rtc_export.h"

namespace webrtc {

class TurnCustomizer;

// PortAllocator is responsible for allocating Port types for a given
// P2PSocket. It also handles port freeing.
//
// Clients can override this class to control port allocation, including
// what kinds of ports are allocated.

enum {
  // Disable local UDP ports. This doesn't impact how we connect to relay
  // servers.
  PORTALLOCATOR_DISABLE_UDP = 0x01,
  PORTALLOCATOR_DISABLE_STUN = 0x02,
  PORTALLOCATOR_DISABLE_RELAY = 0x04,
  // Disable local TCP ports. This doesn't impact how we connect to relay
  // servers.
  PORTALLOCATOR_DISABLE_TCP = 0x08,
  PORTALLOCATOR_ENABLE_IPV6 = 0x40,
  PORTALLOCATOR_ENABLE_SHARED_SOCKET = 0x100,
  PORTALLOCATOR_ENABLE_STUN_RETRANSMIT_ATTRIBUTE = 0x200,
  // When specified, we'll only allocate the STUN candidate for the public
  // interface as seen by regular http traffic and the HOST candidate associated
  // with the default local interface.
  PORTALLOCATOR_DISABLE_ADAPTER_ENUMERATION = 0x400,
  // When specified along with PORTALLOCATOR_DISABLE_ADAPTER_ENUMERATION, the
  // default local candidate mentioned above will not be allocated. Only the
  // STUN candidate will be.
  PORTALLOCATOR_DISABLE_DEFAULT_LOCAL_CANDIDATE = 0x800,
  // Disallow use of UDP when connecting to a relay server. Since proxy servers
  // usually don't handle UDP, using UDP will leak the IP address.
  PORTALLOCATOR_DISABLE_UDP_RELAY = 0x1000,

  // When multiple networks exist, do not gather candidates on the ones with
  // high cost. So if both Wi-Fi and cellular networks exist, gather only on the
  // Wi-Fi network. If a network type is "unknown", it has a cost lower than
  // cellular but higher than Wi-Fi/Ethernet. So if an unknown network exists,
  // cellular networks will not be used to gather candidates and if a Wi-Fi
  // network is present, "unknown" networks will not be usd to gather
  // candidates. Doing so ensures that even if a cellular network type was not
  // detected initially, it would not be used if a Wi-Fi network is present.
  PORTALLOCATOR_DISABLE_COSTLY_NETWORKS = 0x2000,

  // When specified, do not collect IPv6 ICE candidates on Wi-Fi.
  PORTALLOCATOR_ENABLE_IPV6_ON_WIFI = 0x4000,

  // When this flag is set, ports not bound to any specific network interface
  // will be used, in addition to normal ports bound to the enumerated
  // interfaces. Without this flag, these "any address" ports would only be
  // used when network enumeration fails or is disabled. But under certain
  // conditions, these ports may succeed where others fail, so they may allow
  // the application to work in a wider variety of environments, at the expense
  // of having to allocate additional candidates.
  PORTALLOCATOR_ENABLE_ANY_ADDRESS_PORTS = 0x8000,

  // Exclude link-local network interfaces
  // from considertaion after adapter enumeration.
  PORTALLOCATOR_DISABLE_LINK_LOCAL_NETWORKS = 0x10000,
};

// Defines various reasons that have caused ICE regathering.
enum class IceRegatheringReason {
  NETWORK_CHANGE,      // Network interfaces on the device changed
  NETWORK_FAILURE,     // Regather only on networks that have failed
  OCCASIONAL_REFRESH,  // Periodic regather on all networks
  MAX_VALUE
};

const uint32_t kDefaultPortAllocatorFlags = 0;

const uint32_t kDefaultStepDelay = 1000;  // 1 sec step delay.
// As per RFC 5245 Appendix B.1, STUN transactions need to be paced at certain
// internal. Less than 20ms is not acceptable. We choose 50ms as our default.
const uint32_t kMinimumStepDelay = 50;

// Turning on IPv6 could make many IPv6 interfaces available for connectivity
// check and delay the call setup time. kDefaultMaxIPv6Networks is the default
// upper limit of IPv6 networks but could be changed by
// set_max_ipv6_networks().
constexpr int kDefaultMaxIPv6Networks = 5;

// CF = CANDIDATE FILTER
enum : uint32_t {
  CF_NONE = 0x0,
  CF_HOST = 0x1,
  CF_REFLEXIVE = 0x2,
  CF_RELAY = 0x4,
  CF_ALL = 0x7,
};

// TLS certificate policy.
enum class TlsCertPolicy {
  // For TLS based protocols, ensure the connection is secure by not
  // circumventing certificate validation.
  TLS_CERT_POLICY_SECURE,
  // For TLS based protocols, disregard security completely by skipping
  // certificate validation. This is insecure and should never be used unless
  // security is irrelevant in that particular context.
  TLS_CERT_POLICY_INSECURE_NO_CHECK,
};

// TODO(deadbeef): Rename to TurnCredentials (and username to ufrag).
struct RelayCredentials {
  RelayCredentials() {}
  RelayCredentials(absl::string_view username, absl::string_view password)
      : username(username), password(password) {}

  bool operator==(const RelayCredentials& o) const {
    return username == o.username && password == o.password;
  }
  bool operator!=(const RelayCredentials& o) const { return !(*this == o); }

  std::string username;
  std::string password;
};

typedef std::vector<ProtocolAddress> PortList;
// TODO(deadbeef): Rename to TurnServerConfig.
struct RTC_EXPORT RelayServerConfig {
  RelayServerConfig();
  RelayServerConfig(const SocketAddress& address,
                    absl::string_view username,
                    absl::string_view password,
                    ProtocolType proto);
  RelayServerConfig(absl::string_view address,
                    int port,
                    absl::string_view username,
                    absl::string_view password,
                    ProtocolType proto);
  // Legacy constructor where "secure" and PROTO_TCP implies PROTO_TLS.
  RelayServerConfig(absl::string_view address,
                    int port,
                    absl::string_view username,
                    absl::string_view password,
                    ProtocolType proto,
                    bool secure);
  RelayServerConfig(const RelayServerConfig&);
  ~RelayServerConfig();

  bool operator==(const RelayServerConfig& o) const {
    return ports == o.ports && credentials == o.credentials;
  }
  bool operator!=(const RelayServerConfig& o) const { return !(*this == o); }

  PortList ports;
  RelayCredentials credentials;
  TlsCertPolicy tls_cert_policy = TlsCertPolicy::TLS_CERT_POLICY_SECURE;
  std::vector<std::string> tls_alpn_protocols;
  std::vector<std::string> tls_elliptic_curves;
  SSLCertificateVerifier* tls_cert_verifier = nullptr;
  std::string turn_logging_id;
};

class RTC_EXPORT PortAllocatorSession {
 public:
  // Content name passed in mostly for logging and debugging.
  PortAllocatorSession(absl::string_view content_name,
                       int component,
                       absl::string_view ice_ufrag,
                       absl::string_view ice_pwd,
                       uint32_t flags);

  // Subclasses should clean up any ports created.
  virtual ~PortAllocatorSession();

  uint32_t flags() const { return flags_; }
  void set_flags(uint32_t flags) { flags_ = flags; }
  const std::string& content_name() const { return content_name_; }
  int component() const { return component_; }
  const std::string& ice_ufrag() const { return ice_ufrag_; }
  const std::string& ice_pwd() const { return ice_pwd_; }
  bool pooled() const { return pooled_; }

  // Setting this filter should affect not only candidates gathered in the
  // future, but candidates already gathered and ports already "ready",
  // which would be returned by ReadyCandidates() and ReadyPorts().
  //
  // Default filter should be CF_ALL.
  virtual void SetCandidateFilter(uint32_t filter) = 0;

  // Starts gathering ports and ICE candidates.
  virtual void StartGettingPorts() = 0;
  // Completely stops gathering. Will not gather again unless StartGettingPorts
  // is called again.
  virtual void StopGettingPorts() = 0;
  // Whether the session is actively getting ports.
  virtual bool IsGettingPorts() = 0;

  //
  // NOTE: The group of methods below is only used for continual gathering.
  //

  // ClearGettingPorts should have the same immediate effect as
  // StopGettingPorts, but if the implementation supports continual gathering,
  // ClearGettingPorts allows additional ports/candidates to be gathered if the
  // network conditions change.
  virtual void ClearGettingPorts() = 0;
  // Whether it is in the state where the existing gathering process is stopped,
  // but new ones may be started (basically after calling ClearGettingPorts).
  virtual bool IsCleared() const;
  // Whether the session has completely stopped.
  virtual bool IsStopped() const;
  // Re-gathers candidates on networks that do not have any connections. More
  // precisely, a network interface may have more than one IP addresses (e.g.,
  // IPv4 and IPv6 addresses). Each address subnet will be used to create a
  // network. Only if all networks of an interface have no connection, the
  // implementation should start re-gathering on all networks of that interface.
  virtual void RegatherOnFailedNetworks() {}
  // Get candidate-level stats from all candidates on the ready ports and return
  // the stats to the given list.
  virtual void GetCandidateStatsFromReadyPorts(
      CandidateStatsList* /* candidate_stats_list */) const {}
  // Set the interval at which STUN candidates will resend STUN binding requests
  // on the underlying ports to keep NAT bindings open.
  // The default value of the interval in implementation is restored if a null
  // optional value is passed.
  virtual void SetStunKeepaliveIntervalForReadyPorts(
      const std::optional<TimeDelta>& /* stun_keepalive_interval */) {}
  // Another way of getting the information provided by the signals below.
  //
  // Ports and candidates are not guaranteed to be in the same order as the
  // signals were emitted in.
  virtual std::vector<PortInterface*> ReadyPorts() const = 0;
  virtual std::vector<Candidate> ReadyCandidates() const = 0;
  virtual bool CandidatesAllocationDone() const = 0;
  // Marks all ports in the current session as "pruned" so that they may be
  // destroyed if no connection is using them.
  virtual void PruneAllPorts() {}

  void SubscribePortReady(
      void* tag,
      absl::AnyInvocable<void(PortAllocatorSession*, PortInterface*)> callback);
  void NotifyPortReady(PortAllocatorSession* session, PortInterface* port) {
    port_ready_callbacks_.Send(session, port);
  }

  // Fires this signal when the network of the ports failed (either because the
  // interface is down, or because there is no connection on the interface),
  // or when TURN ports are pruned because a higher-priority TURN port becomes
  // ready(pairable).
  void SubscribePortsPruned(
      void* tag,
      absl::AnyInvocable<void(PortAllocatorSession*,
                              const std::vector<PortInterface*>&)> callback) {
    ports_pruned_callbacks_.AddReceiver(tag, std::move(callback));
  }
  void NotifyPortsPruned(PortAllocatorSession* session,
                         const std::vector<PortInterface*>& ports) {
    ports_pruned_callbacks_.Send(session, ports);
  }

  void SubscribeCandidatesReady(
      void* tag,
      absl::AnyInvocable<void(PortAllocatorSession*,
                              const std::vector<Candidate>&)> callback) {
    candidates_ready_callbacks_.AddReceiver(tag, std::move(callback));
  }
  void NotifyCandidatesReady(PortAllocatorSession* session,
                             const std::vector<Candidate>& candidates) {
    candidates_ready_callbacks_.Send(session, candidates);
  }

  void SubscribeCandidateError(
      void* tag,
      absl::AnyInvocable<void(PortAllocatorSession*,
                              const IceCandidateErrorEvent&)> callback) {
    candidate_error_callbacks_.AddReceiver(tag, std::move(callback));
  }
  void NotifyCandidateError(PortAllocatorSession* session,
                            const IceCandidateErrorEvent& event) {
    candidate_error_callbacks_.Send(session, event);
  }
  // Candidates should be signaled to be removed when the port that generated
  // the candidates is removed.

  void SubscribeCandidatesRemoved(
      void* tag,
      absl::AnyInvocable<void(PortAllocatorSession*,
                              const std::vector<Candidate>&)> callback) {
    candidates_removed_callbacks_.AddReceiver(tag, std::move(callback));
  }
  void NotifyCandidatesRemoved(PortAllocatorSession* session,
                               const std::vector<Candidate>& candidates) {
    candidates_removed_callbacks_.Send(session, candidates);
  }

  void SubscribeCandidatesAllocationDone(
      void* tag,
      absl::AnyInvocable<void(PortAllocatorSession*)> callback) {
    candidates_allocation_done_callbacks_.AddReceiver(tag, std::move(callback));
  }
  void NotifyCandidatesAllocationDone(PortAllocatorSession* session) {
    candidates_allocation_done_callbacks_.Send(session);
  }

  void SubscribeIceRegathering(
      void* tag,
      absl::AnyInvocable<void(PortAllocatorSession*, IceRegatheringReason)>
          callback) {
    ice_regathering_callbacks_.AddReceiver(tag, std::move(callback));
  }
  void NotifyIceRegathering(PortAllocatorSession* session,
                            IceRegatheringReason reason) {
    ice_regathering_callbacks_.Send(session, reason);
  }

  virtual uint32_t generation();
  virtual void set_generation(uint32_t generation);

 protected:
  // This method is called when a pooled session (which doesn't have these
  // properties initially) is returned by PortAllocator::TakePooledSession,
  // and the content name, component, and ICE ufrag/pwd are updated.
  //
  // A subclass may need to override this method to perform additional actions,
  // such as applying the updated information to ports and candidates.
  virtual void UpdateIceParametersInternal() {}

  // TODO(deadbeef): Get rid of these when everyone switches to ice_ufrag and
  // ice_pwd.
  const std::string& username() const { return ice_ufrag_; }
  const std::string& password() const { return ice_pwd_; }

 private:
  void SetIceParameters(absl::string_view content_name,
                        int component,
                        absl::string_view ice_ufrag,
                        absl::string_view ice_pwd) {
    RTC_DCHECK(pooled_);
    RTC_DCHECK(!content_name.empty());
    RTC_DCHECK(content_name_.empty());
    content_name_ = std::string(content_name);
    component_ = component;
    ice_ufrag_ = std::string(ice_ufrag);
    ice_pwd_ = std::string(ice_pwd);
    UpdateIceParametersInternal();
  }

  void set_pooled(bool value) {
    pooled_ = value;
    if (pooled_) {
      content_name_.clear();
    }
  }

  uint32_t flags_;
  uint32_t generation_;
  std::string content_name_;
  int component_;
  std::string ice_ufrag_;
  std::string ice_pwd_;

  bool pooled_ = false;

  // SetIceParameters is an implementation detail which only PortAllocator
  // should be able to call.
  friend class PortAllocator;

  // Callback lists (used to be called signals)
  CallbackList<PortAllocatorSession*, PortInterface*> port_ready_callbacks_;
  CallbackList<PortAllocatorSession*, const std::vector<PortInterface*>&>
      ports_pruned_callbacks_;
  CallbackList<PortAllocatorSession*, const std::vector<Candidate>&>
      candidates_ready_callbacks_;
  CallbackList<PortAllocatorSession*, const IceCandidateErrorEvent&>
      candidate_error_callbacks_;
  CallbackList<PortAllocatorSession*, const std::vector<Candidate>&>
      candidates_removed_callbacks_;
  CallbackList<PortAllocatorSession*> candidates_allocation_done_callbacks_;
  CallbackList<PortAllocatorSession*, IceRegatheringReason>
      ice_regathering_callbacks_;
};

// Every method of PortAllocator (including the destructor) must be called on
// the same thread after Initialize is called.
//
// This allows a PortAllocator subclass to be constructed and configured on one
// thread, and passed into an object that uses it on a different thread.
class RTC_EXPORT PortAllocator {
 public:
  PortAllocator();
  virtual ~PortAllocator();

  // This MUST be called on the PortAllocator's thread after finishing
  // constructing and configuring the PortAllocator subclasses.
  virtual void Initialize();

  // Set to true if some Ports need to know the ICE credentials when they are
  // created. This will ensure that the PortAllocator will only match pooled
  // allocator sessions to the ICE transport with the same credentials.
  virtual void set_restrict_ice_credentials_change(bool value);

  // Set STUN and TURN servers to be used in future sessions, and set
  // candidate pool size, as described in JSEP.
  //
  // If the servers are changing, and the candidate pool size is nonzero, and
  // FreezeCandidatePool hasn't been called, existing pooled sessions will be
  // destroyed and new ones created.
  //
  // If the servers are not changing but the candidate pool size is, and
  // FreezeCandidatePool hasn't been called, pooled sessions will be either
  // created or destroyed as necessary.
  //
  // Returns true if the configuration could successfully be changed.
  // Deprecated
  bool SetConfiguration(const ServerAddresses& stun_servers,
                        const std::vector<RelayServerConfig>& turn_servers,
                        int candidate_pool_size,
                        bool prune_turn_ports,
                        TurnCustomizer* turn_customizer = nullptr,
                        const std::optional<int>&
                            stun_candidate_keepalive_interval = std::nullopt);
  bool SetConfiguration(const ServerAddresses& stun_servers,
                        const std::vector<RelayServerConfig>& turn_servers,
                        int candidate_pool_size,
                        PortPrunePolicy turn_port_prune_policy,
                        TurnCustomizer* turn_customizer = nullptr,
                        const std::optional<int>&
                            stun_candidate_keepalive_interval = std::nullopt);

  const ServerAddresses& stun_servers() const {
    CheckRunOnValidThreadIfInitialized();
    return stun_servers_;
  }

  const std::vector<RelayServerConfig>& turn_servers() const {
    CheckRunOnValidThreadIfInitialized();
    return turn_servers_;
  }

  int candidate_pool_size() const {
    CheckRunOnValidThreadIfInitialized();
    return candidate_pool_size_;
  }

  const std::optional<TimeDelta>& stun_candidate_keepalive_interval() const {
    CheckRunOnValidThreadIfInitialized();
    return stun_candidate_keepalive_interval_;
  }

  // Sets the network types to ignore.
  // Values are defined by the AdapterType enum.
  // For instance, calling this with
  // ADAPTER_TYPE_ETHERNET | ADAPTER_TYPE_LOOPBACK will ignore Ethernet and
  // loopback interfaces.
  virtual void SetNetworkIgnoreMask(int network_ignore_mask) = 0;

  // Set whether VPN connections should be preferred, avoided, mandated or
  // blocked.
  virtual void SetVpnPreference(VpnPreference preference) {
    vpn_preference_ = preference;
  }

  // Set list of <ipaddress, mask> that shall be categorized as VPN.
  // Implemented by BasicPortAllocator.
  virtual void SetVpnList(const std::vector<NetworkMask>& /* vpn_list */) {}

  std::unique_ptr<PortAllocatorSession> CreateSession(
      absl::string_view content_name,
      int component,
      absl::string_view ice_ufrag,
      absl::string_view ice_pwd);

  // Get an available pooled session and set the transport information on it.
  //
  // Caller takes ownership of the returned session.
  //
  // If restrict_ice_credentials_change is TRUE, then it will only
  //   return a pooled session with matching ice credentials.
  // If no pooled sessions are available, returns null.
  std::unique_ptr<PortAllocatorSession> TakePooledSession(
      absl::string_view content_name,
      int component,
      absl::string_view ice_ufrag,
      absl::string_view ice_pwd);

  // Returns the next session that would be returned by TakePooledSession
  // optionally restricting it to sessions with specified ice credentials.
  const PortAllocatorSession* GetPooledSession(
      const IceParameters* ice_credentials = nullptr) const;

  // Discard any remaining pooled sessions.
  virtual void DiscardCandidatePool();

  // Clears the address and the related address fields of a local candidate to
  // avoid IP leakage. This is applicable in several scenarios:
  // 1. Sanitization is configured via the candidate filter.
  // 2. Sanitization is configured via the port allocator flags.
  // 3. mDNS concealment of private IPs is enabled.
  Candidate SanitizeCandidate(const Candidate& c) const;

  uint64_t ice_tiebreaker() const { return tiebreaker_; }

  uint32_t flags() const {
    CheckRunOnValidThreadIfInitialized();
    return flags_;
  }

  void set_flags(uint32_t flags) {
    CheckRunOnValidThreadIfInitialized();
    flags_ = flags;
  }

  // Gets/Sets the port range to use when choosing client ports.
  int min_port() const {
    CheckRunOnValidThreadIfInitialized();
    return min_port_;
  }

  int max_port() const {
    CheckRunOnValidThreadIfInitialized();
    return max_port_;
  }

  bool SetPortRange(int min_port, int max_port) {
    CheckRunOnValidThreadIfInitialized();
    if (min_port > max_port) {
      return false;
    }

    min_port_ = min_port;
    max_port_ = max_port;
    return true;
  }

  // Can be used to change the default numer of IPv6 network interfaces used
  // (5). Can set to INT_MAX to effectively disable the limit.
  //
  // TODO(deadbeef): Applications shouldn't have to arbitrarily limit the
  // number of available IPv6 network interfaces just because they could slow
  // ICE down. We should work on making our ICE logic smarter (for example,
  // prioritizing pinging connections that are most likely to work) so that
  // every network interface can be used without impacting ICE's speed.
  void set_max_ipv6_networks(int networks) {
    CheckRunOnValidThreadIfInitialized();
    max_ipv6_networks_ = networks;
  }

  int max_ipv6_networks() {
    CheckRunOnValidThreadIfInitialized();
    return max_ipv6_networks_;
  }

  // Delay between different candidate gathering phases (UDP, TURN, TCP).
  // Defaults to 1 second, but PeerConnection sets it to 50ms.
  // TODO(deadbeef): Get rid of this. Its purpose is to avoid sending too many
  // STUN transactions at once, but that's already happening if you configure
  // multiple STUN servers or have multiple network interfaces. We should
  // implement some global pacing logic instead if that's our goal.
  uint32_t step_delay() const {
    CheckRunOnValidThreadIfInitialized();
    return step_delay_;
  }

  void set_step_delay(uint32_t delay) {
    CheckRunOnValidThreadIfInitialized();
    step_delay_ = delay;
  }

  bool allow_tcp_listen() const {
    CheckRunOnValidThreadIfInitialized();
    return allow_tcp_listen_;
  }

  void set_allow_tcp_listen(bool allow_tcp_listen) {
    CheckRunOnValidThreadIfInitialized();
    allow_tcp_listen_ = allow_tcp_listen;
  }

  uint32_t candidate_filter() {
    CheckRunOnValidThreadIfInitialized();
    return candidate_filter_;
  }

  // The new filter value will be populated to future allocation sessions, when
  // they are created via CreateSession, and also pooled sessions when one is
  // taken via TakePooledSession.
  //
  // A change in the candidate filter also fires a signal
  // `SignalCandidateFilterChanged`, so that objects subscribed to this signal
  // can, for example, update the candidate filter for sessions created by this
  // allocator and already taken by the object.
  //
  // Specifically for the session taken by the ICE transport, we currently do
  // not support removing candidate pairs formed with local candidates from this
  // session that are disabled by the new candidate filter.
  void SetCandidateFilter(uint32_t filter);
  // Deprecated.
  // TODO(qingsi): Remove this after Chromium migrates to the new method.
  void set_candidate_filter(uint32_t filter) { SetCandidateFilter(filter); }

  // Deprecated (by the next method).
  bool prune_turn_ports() const {
    CheckRunOnValidThreadIfInitialized();
    return turn_port_prune_policy_ == PRUNE_BASED_ON_PRIORITY;
  }

  PortPrunePolicy turn_port_prune_policy() const {
    CheckRunOnValidThreadIfInitialized();
    return turn_port_prune_policy_;
  }

  TurnCustomizer* turn_customizer() {
    CheckRunOnValidThreadIfInitialized();
    return turn_customizer_;
  }

  // Collect candidate stats from pooled allocator sessions. This can be used to
  // collect candidate stats without creating an offer/answer or setting local
  // description. After the local description is set, the ownership of the
  // pooled session is taken by P2PTransportChannel, and the
  // candidate stats can be collected from P2PTransportChannel::GetStats.
  virtual void GetCandidateStatsFromPooledSessions(
      CandidateStatsList* candidate_stats_list);

  // Return IceParameters of the pooled sessions.
  std::vector<IceParameters> GetPooledIceCredentials();

  // Fired when `candidate_filter_` changes.
  void SubscribeCandidateFilterChanged(
      void* tag,
      absl::AnyInvocable<void(uint32_t, uint32_t)> callback) {
    candidate_filter_callbacks_.AddReceiver(tag, std::move(callback));
  }
  void UnsubscribeCandidateFilterChanged(void* tag) {
    candidate_filter_callbacks_.RemoveReceivers(tag);
  }

 protected:
  // TODO(webrtc::13579): Remove std::string version once downstream users have
  // migrated to the absl::string_view version.
  virtual PortAllocatorSession* CreateSessionInternal(
      absl::string_view content_name,
      int component,
      absl::string_view ice_ufrag,
      absl::string_view ice_pwd) = 0;

  const std::vector<std::unique_ptr<PortAllocatorSession>>& pooled_sessions() {
    return pooled_sessions_;
  }

  // Returns true if there is an mDNS responder attached to the network manager.
  virtual bool MdnsObfuscationEnabled() const { return false; }

  // The following thread checks are only done in DCHECK for the consistency
  // with the exsiting thread checks.
  void CheckRunOnValidThreadIfInitialized() const {
    RTC_DCHECK(!initialized_ || thread_checker_.IsCurrent());
  }

  void CheckRunOnValidThreadAndInitialized() const {
    RTC_DCHECK(initialized_ && thread_checker_.IsCurrent());
  }

  bool initialized_ = false;
  uint32_t flags_;
  int min_port_;
  int max_port_;
  int max_ipv6_networks_;
  uint32_t step_delay_;
  bool allow_tcp_listen_;
  uint32_t candidate_filter_;
  std::string origin_;
  SequenceChecker thread_checker_;
  VpnPreference vpn_preference_ = VpnPreference::kDefault;

 private:
  ServerAddresses stun_servers_;
  std::vector<RelayServerConfig> turn_servers_;
  int candidate_pool_size_ = 0;  // Last value passed into SetConfiguration.
  std::vector<std::unique_ptr<PortAllocatorSession>> pooled_sessions_;
  PortPrunePolicy turn_port_prune_policy_ = NO_PRUNE;

  // Customizer for TURN messages.
  // The instance is owned by application and will be shared among
  // all TurnPort(s) created.
  TurnCustomizer* turn_customizer_ = nullptr;

  std::optional<TimeDelta> stun_candidate_keepalive_interval_;

  // If true, TakePooledSession() will only return sessions that has same ice
  // credentials as requested.
  bool restrict_ice_credentials_change_ = false;

  // Returns iterator to pooled session with specified ice_credentials or first
  // if ice_credentials is nullptr.
  std::vector<std::unique_ptr<PortAllocatorSession>>::const_iterator
  FindPooledSession(const IceParameters* ice_credentials = nullptr) const;
  void NotifyCandidateFilterChanged(uint32_t prev_filter, uint32_t cur_filter) {
    candidate_filter_callbacks_.Send(prev_filter, cur_filter);
  }

  CallbackList<uint32_t, uint32_t> candidate_filter_callbacks_;
  // ICE tie breaker.
  uint64_t tiebreaker_;
};

}  //  namespace webrtc

#endif  // P2P_BASE_PORT_ALLOCATOR_H_
