/*
 *  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; }
  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.
  [[deprecated]] void SubscribeCandidatesRemoved(
      absl::AnyInvocable<void(PortAllocatorSession*,
                              const std::vector<Candidate>&)> callback) {
    candidates_removed_callbacks_.AddReceiver(std::move(callback));
  }
  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);
  }

  [[deprecated]] void SubscribeCandidatesAllocationDone(
      absl::AnyInvocable<void(PortAllocatorSession*)> callback) {
    candidates_allocation_done_callbacks_.AddReceiver(std::move(callback));
  }
  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);
  }

  [[deprecated("Use SubscribeIceRegathering(void* tag, ...)")]]
  void SubscribeIceRegathering(
      absl::AnyInvocable<void(PortAllocatorSession*, IceRegatheringReason)>
          callback) {
    ice_regathering_callbacks_.AddReceiver(std::move(callback));
  }
  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_
