/*
 *  Copyright 2009 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.
 */

#include <algorithm>
#include <list>
#include <memory>

#include "absl/memory/memory.h"
#include "p2p/base/fakeportallocator.h"
#include "p2p/base/icetransportinternal.h"
#include "p2p/base/mockasyncresolver.h"
#include "p2p/base/p2ptransportchannel.h"
#include "p2p/base/packettransportinternal.h"
#include "p2p/base/testrelayserver.h"
#include "p2p/base/teststunserver.h"
#include "p2p/base/testturnserver.h"
#include "p2p/client/basicportallocator.h"
#include "rtc_base/checks.h"
#include "rtc_base/dscp.h"
#include "rtc_base/fakeclock.h"
#include "rtc_base/fakenetwork.h"
#include "rtc_base/firewallsocketserver.h"
#include "rtc_base/gunit.h"
#include "rtc_base/helpers.h"
#include "rtc_base/logging.h"
#include "rtc_base/natserver.h"
#include "rtc_base/natsocketfactory.h"
#include "rtc_base/proxyserver.h"
#include "rtc_base/socketaddress.h"
#include "rtc_base/ssladapter.h"
#include "rtc_base/thread.h"
#include "rtc_base/virtualsocketserver.h"
#include "system_wrappers/include/metrics_default.h"

namespace {

using rtc::SocketAddress;
using ::testing::_;
using ::testing::DoAll;
using ::testing::Return;
using ::testing::SetArgPointee;

// Default timeout for tests in this file.
// Should be large enough for slow buildbots to run the tests reliably.
static const int kDefaultTimeout = 10000;
static const int kMediumTimeout = 3000;
static const int kShortTimeout = 1000;

static const int kOnlyLocalPorts = cricket::PORTALLOCATOR_DISABLE_STUN |
                                   cricket::PORTALLOCATOR_DISABLE_RELAY |
                                   cricket::PORTALLOCATOR_DISABLE_TCP;
static const int LOW_RTT = 20;
// Addresses on the public internet.
static const SocketAddress kPublicAddrs[2] = {SocketAddress("11.11.11.11", 0),
                                              SocketAddress("22.22.22.22", 0)};
// IPv6 Addresses on the public internet.
static const SocketAddress kIPv6PublicAddrs[2] = {
    SocketAddress("2400:4030:1:2c00:be30:abcd:efab:cdef", 0),
    SocketAddress("2600:0:1000:1b03:2e41:38ff:fea6:f2a4", 0)};
// For configuring multihomed clients.
static const SocketAddress kAlternateAddrs[2] = {
    SocketAddress("101.101.101.101", 0), SocketAddress("202.202.202.202", 0)};
static const SocketAddress kIPv6AlternateAddrs[2] = {
    SocketAddress("2401:4030:1:2c00:be30:abcd:efab:cdef", 0),
    SocketAddress("2601:0:1000:1b03:2e41:38ff:fea6:f2a4", 0)};
// Addresses for HTTP proxy servers.
static const SocketAddress kHttpsProxyAddrs[2] = {
    SocketAddress("11.11.11.1", 443), SocketAddress("22.22.22.1", 443)};
// Addresses for SOCKS proxy servers.
static const SocketAddress kSocksProxyAddrs[2] = {
    SocketAddress("11.11.11.1", 1080), SocketAddress("22.22.22.1", 1080)};
// Internal addresses for NAT boxes.
static const SocketAddress kNatAddrs[2] = {SocketAddress("192.168.1.1", 0),
                                           SocketAddress("192.168.2.1", 0)};
// Private addresses inside the NAT private networks.
static const SocketAddress kPrivateAddrs[2] = {
    SocketAddress("192.168.1.11", 0), SocketAddress("192.168.2.22", 0)};
// For cascaded NATs, the internal addresses of the inner NAT boxes.
static const SocketAddress kCascadedNatAddrs[2] = {
    SocketAddress("192.168.10.1", 0), SocketAddress("192.168.20.1", 0)};
// For cascaded NATs, private addresses inside the inner private networks.
static const SocketAddress kCascadedPrivateAddrs[2] = {
    SocketAddress("192.168.10.11", 0), SocketAddress("192.168.20.22", 0)};
// The address of the public STUN server.
static const SocketAddress kStunAddr("99.99.99.1", cricket::STUN_SERVER_PORT);
// The addresses for the public turn server.
static const SocketAddress kTurnUdpIntAddr("99.99.99.3",
                                           cricket::STUN_SERVER_PORT);
static const SocketAddress kTurnTcpIntAddr("99.99.99.4",
                                           cricket::STUN_SERVER_PORT + 1);
static const SocketAddress kTurnUdpExtAddr("99.99.99.5", 0);
static const cricket::RelayCredentials kRelayCredentials("test", "test");

// Based on ICE_UFRAG_LENGTH
const char* kIceUfrag[4] = {"UF00", "UF01", "UF02", "UF03"};
// Based on ICE_PWD_LENGTH
const char* kIcePwd[4] = {
    "TESTICEPWD00000000000000", "TESTICEPWD00000000000001",
    "TESTICEPWD00000000000002", "TESTICEPWD00000000000003"};
const cricket::IceParameters kIceParams[4] = {
    {kIceUfrag[0], kIcePwd[0], false},
    {kIceUfrag[1], kIcePwd[1], false},
    {kIceUfrag[2], kIcePwd[2], false},
    {kIceUfrag[3], kIcePwd[3], false}};

const uint64_t kLowTiebreaker = 11111;
const uint64_t kHighTiebreaker = 22222;

enum { MSG_ADD_CANDIDATES, MSG_REMOVE_CANDIDATES };

cricket::IceConfig CreateIceConfig(
    int receiving_timeout,
    cricket::ContinualGatheringPolicy continual_gathering_policy,
    absl::optional<int> backup_ping_interval = absl::nullopt) {
  cricket::IceConfig config;
  config.receiving_timeout = receiving_timeout;
  config.continual_gathering_policy = continual_gathering_policy;
  config.backup_connection_ping_interval = backup_ping_interval;
  return config;
}

cricket::Candidate CreateUdpCandidate(const std::string& type,
                                      const std::string& ip,
                                      int port,
                                      int priority,
                                      const std::string& ufrag = "") {
  cricket::Candidate c;
  c.set_address(rtc::SocketAddress(ip, port));
  c.set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
  c.set_protocol(cricket::UDP_PROTOCOL_NAME);
  c.set_priority(priority);
  c.set_username(ufrag);
  c.set_type(type);
  return c;
}

cricket::BasicPortAllocator* CreateBasicPortAllocator(
    rtc::NetworkManager* network_manager,
    const cricket::ServerAddresses& stun_servers,
    const rtc::SocketAddress& turn_server_udp,
    const rtc::SocketAddress& turn_server_tcp) {
  cricket::RelayServerConfig turn_server(cricket::RELAY_TURN);
  turn_server.credentials = kRelayCredentials;
  if (!turn_server_udp.IsNil()) {
    turn_server.ports.push_back(
        cricket::ProtocolAddress(turn_server_udp, cricket::PROTO_UDP));
  }
  if (!turn_server_tcp.IsNil()) {
    turn_server.ports.push_back(
        cricket::ProtocolAddress(turn_server_tcp, cricket::PROTO_TCP));
  }
  std::vector<cricket::RelayServerConfig> turn_servers(1, turn_server);

  cricket::BasicPortAllocator* allocator =
      new cricket::BasicPortAllocator(network_manager);
  allocator->Initialize();
  allocator->SetConfiguration(stun_servers, turn_servers, 0, false);
  return allocator;
}
}  // namespace

namespace cricket {

// This test simulates 2 P2P endpoints that want to establish connectivity
// with each other over various network topologies and conditions, which can be
// specified in each individial test.
// A virtual network (via VirtualSocketServer) along with virtual firewalls and
// NATs (via Firewall/NATSocketServer) are used to simulate the various network
// conditions. We can configure the IP addresses of the endpoints,
// block various types of connectivity, or add arbitrary levels of NAT.
// We also run a STUN server and a relay server on the virtual network to allow
// our typical P2P mechanisms to do their thing.
// For each case, we expect the P2P stack to eventually settle on a specific
// form of connectivity to the other side. The test checks that the P2P
// negotiation successfully establishes connectivity within a certain time,
// and that the result is what we expect.
// Note that this class is a base class for use by other tests, who will provide
// specialized test behavior.
class P2PTransportChannelTestBase : public testing::Test,
                                    public rtc::MessageHandler,
                                    public sigslot::has_slots<> {
 public:
  P2PTransportChannelTestBase()
      : vss_(new rtc::VirtualSocketServer()),
        nss_(new rtc::NATSocketServer(vss_.get())),
        ss_(new rtc::FirewallSocketServer(nss_.get())),
        main_(ss_.get()),
        stun_server_(TestStunServer::Create(&main_, kStunAddr)),
        turn_server_(&main_, kTurnUdpIntAddr, kTurnUdpExtAddr),
        socks_server1_(ss_.get(),
                       kSocksProxyAddrs[0],
                       ss_.get(),
                       kSocksProxyAddrs[0]),
        socks_server2_(ss_.get(),
                       kSocksProxyAddrs[1],
                       ss_.get(),
                       kSocksProxyAddrs[1]),
        force_relay_(false) {
    ep1_.role_ = ICEROLE_CONTROLLING;
    ep2_.role_ = ICEROLE_CONTROLLED;

    ServerAddresses stun_servers;
    stun_servers.insert(kStunAddr);
    ep1_.allocator_.reset(
        CreateBasicPortAllocator(&ep1_.network_manager_, stun_servers,
                                 kTurnUdpIntAddr, rtc::SocketAddress()));
    ep2_.allocator_.reset(
        CreateBasicPortAllocator(&ep2_.network_manager_, stun_servers,
                                 kTurnUdpIntAddr, rtc::SocketAddress()));
    webrtc::metrics::Reset();
  }

 protected:
  enum Config {
    OPEN,                         // Open to the Internet
    NAT_FULL_CONE,                // NAT, no filtering
    NAT_ADDR_RESTRICTED,          // NAT, must send to an addr to recv
    NAT_PORT_RESTRICTED,          // NAT, must send to an addr+port to recv
    NAT_SYMMETRIC,                // NAT, endpoint-dependent bindings
    NAT_DOUBLE_CONE,              // Double NAT, both cone
    NAT_SYMMETRIC_THEN_CONE,      // Double NAT, symmetric outer, cone inner
    BLOCK_UDP,                    // Firewall, UDP in/out blocked
    BLOCK_UDP_AND_INCOMING_TCP,   // Firewall, UDP in/out and TCP in blocked
    BLOCK_ALL_BUT_OUTGOING_HTTP,  // Firewall, only TCP out on 80/443
    PROXY_HTTPS,                  // All traffic through HTTPS proxy
    PROXY_SOCKS,                  // All traffic through SOCKS proxy
    NUM_CONFIGS
  };

  struct Result {
    Result(const std::string& controlling_type,
           const std::string& controlling_protocol,
           const std::string& controlled_type,
           const std::string& controlled_protocol,
           int wait)
        : controlling_type(controlling_type),
          controlling_protocol(controlling_protocol),
          controlled_type(controlled_type),
          controlled_protocol(controlled_protocol),
          connect_wait(wait) {}

    // The expected candidate type and protocol of the controlling ICE agent.
    std::string controlling_type;
    std::string controlling_protocol;
    // The expected candidate type and protocol of the controlled ICE agent.
    std::string controlled_type;
    std::string controlled_protocol;
    // How long to wait before the correct candidate pair is selected.
    int connect_wait;
  };

  struct ChannelData {
    bool CheckData(const char* data, int len) {
      bool ret = false;
      if (!ch_packets_.empty()) {
        std::string packet = ch_packets_.front();
        ret = (packet == std::string(data, len));
        ch_packets_.pop_front();
      }
      return ret;
    }

    std::string name_;  // TODO(?) - Currently not used.
    std::list<std::string> ch_packets_;
    std::unique_ptr<P2PTransportChannel> ch_;
  };

  struct CandidatesData : public rtc::MessageData {
    CandidatesData(IceTransportInternal* ch, const Candidate& c)
        : channel(ch), candidates(1, c) {}
    CandidatesData(IceTransportInternal* ch, const std::vector<Candidate>& cc)
        : channel(ch), candidates(cc) {}
    IceTransportInternal* channel;
    Candidates candidates;
  };

  struct Endpoint : public sigslot::has_slots<> {
    Endpoint()
        : role_(ICEROLE_UNKNOWN),
          tiebreaker_(0),
          role_conflict_(false),
          save_candidates_(false) {}
    bool HasTransport(const rtc::PacketTransportInternal* transport) {
      return (transport == cd1_.ch_.get() || transport == cd2_.ch_.get());
    }
    ChannelData* GetChannelData(rtc::PacketTransportInternal* transport) {
      if (!HasTransport(transport))
        return NULL;
      if (cd1_.ch_.get() == transport)
        return &cd1_;
      else
        return &cd2_;
    }

    void SetIceRole(IceRole role) { role_ = role; }
    IceRole ice_role() { return role_; }
    void SetIceTiebreaker(uint64_t tiebreaker) { tiebreaker_ = tiebreaker; }
    uint64_t GetIceTiebreaker() { return tiebreaker_; }
    void OnRoleConflict(bool role_conflict) { role_conflict_ = role_conflict; }
    bool role_conflict() { return role_conflict_; }
    void SetAllocationStepDelay(uint32_t delay) {
      allocator_->set_step_delay(delay);
    }
    void SetAllowTcpListen(bool allow_tcp_listen) {
      allocator_->set_allow_tcp_listen(allow_tcp_listen);
    }

    void OnIceRegathering(PortAllocatorSession*, IceRegatheringReason reason) {
      ++ice_regathering_counter_[reason];
    }

    int GetIceRegatheringCountForReason(IceRegatheringReason reason) {
      return ice_regathering_counter_[reason];
    }

    rtc::FakeNetworkManager network_manager_;
    std::unique_ptr<BasicPortAllocator> allocator_;
    webrtc::AsyncResolverFactory* async_resolver_factory_;
    ChannelData cd1_;
    ChannelData cd2_;
    IceRole role_;
    uint64_t tiebreaker_;
    bool role_conflict_;
    bool save_candidates_;
    std::vector<std::unique_ptr<CandidatesData>> saved_candidates_;
    bool ready_to_send_ = false;
    std::map<IceRegatheringReason, int> ice_regathering_counter_;
  };

  ChannelData* GetChannelData(rtc::PacketTransportInternal* transport) {
    if (ep1_.HasTransport(transport))
      return ep1_.GetChannelData(transport);
    else
      return ep2_.GetChannelData(transport);
  }

  IceParameters IceParamsWithRenomination(const IceParameters& ice,
                                          bool renomination) {
    IceParameters new_ice = ice;
    new_ice.renomination = renomination;
    return new_ice;
  }

  void CreateChannels(const IceConfig& ep1_config,
                      const IceConfig& ep2_config,
                      bool renomination = false) {
    IceParameters ice_ep1_cd1_ch =
        IceParamsWithRenomination(kIceParams[0], renomination);
    IceParameters ice_ep2_cd1_ch =
        IceParamsWithRenomination(kIceParams[1], renomination);
    ep1_.cd1_.ch_.reset(CreateChannel(0, ICE_CANDIDATE_COMPONENT_DEFAULT,
                                      ice_ep1_cd1_ch, ice_ep2_cd1_ch));
    ep2_.cd1_.ch_.reset(CreateChannel(1, ICE_CANDIDATE_COMPONENT_DEFAULT,
                                      ice_ep2_cd1_ch, ice_ep1_cd1_ch));
    ep1_.cd1_.ch_->SetIceConfig(ep1_config);
    ep2_.cd1_.ch_->SetIceConfig(ep2_config);
    ep1_.cd1_.ch_->MaybeStartGathering();
    ep2_.cd1_.ch_->MaybeStartGathering();
    ep1_.cd1_.ch_->allocator_session()->SignalIceRegathering.connect(
        &ep1_, &Endpoint::OnIceRegathering);
    ep2_.cd1_.ch_->allocator_session()->SignalIceRegathering.connect(
        &ep2_, &Endpoint::OnIceRegathering);
  }

  void CreateChannels() {
    IceConfig default_config;
    CreateChannels(default_config, default_config, false);
  }

  P2PTransportChannel* CreateChannel(int endpoint,
                                     int component,
                                     const IceParameters& local_ice,
                                     const IceParameters& remote_ice) {
    P2PTransportChannel* channel = new P2PTransportChannel(
        "test content name", component, GetAllocator(endpoint),
        GetEndpoint(endpoint)->async_resolver_factory_);
    channel->SignalReadyToSend.connect(
        this, &P2PTransportChannelTestBase::OnReadyToSend);
    channel->SignalCandidateGathered.connect(
        this, &P2PTransportChannelTestBase::OnCandidateGathered);
    channel->SignalCandidatesRemoved.connect(
        this, &P2PTransportChannelTestBase::OnCandidatesRemoved);
    channel->SignalReadPacket.connect(
        this, &P2PTransportChannelTestBase::OnReadPacket);
    channel->SignalRoleConflict.connect(
        this, &P2PTransportChannelTestBase::OnRoleConflict);
    channel->SignalNetworkRouteChanged.connect(
        this, &P2PTransportChannelTestBase::OnNetworkRouteChanged);
    channel->SignalSentPacket.connect(
        this, &P2PTransportChannelTestBase::OnSentPacket);
    channel->SetIceParameters(local_ice);
    if (remote_ice_parameter_source_ == FROM_SETICEPARAMETERS) {
      channel->SetRemoteIceParameters(remote_ice);
    }
    channel->SetIceRole(GetEndpoint(endpoint)->ice_role());
    channel->SetIceTiebreaker(GetEndpoint(endpoint)->GetIceTiebreaker());
    return channel;
  }
  void DestroyChannels() {
    main_.Clear(this);
    ep1_.cd1_.ch_.reset();
    ep2_.cd1_.ch_.reset();
    ep1_.cd2_.ch_.reset();
    ep2_.cd2_.ch_.reset();
  }
  P2PTransportChannel* ep1_ch1() { return ep1_.cd1_.ch_.get(); }
  P2PTransportChannel* ep1_ch2() { return ep1_.cd2_.ch_.get(); }
  P2PTransportChannel* ep2_ch1() { return ep2_.cd1_.ch_.get(); }
  P2PTransportChannel* ep2_ch2() { return ep2_.cd2_.ch_.get(); }

  TestTurnServer* test_turn_server() { return &turn_server_; }
  rtc::VirtualSocketServer* virtual_socket_server() { return vss_.get(); }

  // Common results.
  static const Result kLocalUdpToLocalUdp;
  static const Result kLocalUdpToStunUdp;
  static const Result kLocalUdpToPrflxUdp;
  static const Result kPrflxUdpToLocalUdp;
  static const Result kStunUdpToLocalUdp;
  static const Result kStunUdpToStunUdp;
  static const Result kStunUdpToPrflxUdp;
  static const Result kPrflxUdpToStunUdp;
  static const Result kLocalUdpToRelayUdp;
  static const Result kPrflxUdpToRelayUdp;
  static const Result kRelayUdpToPrflxUdp;
  static const Result kLocalTcpToLocalTcp;
  static const Result kLocalTcpToPrflxTcp;
  static const Result kPrflxTcpToLocalTcp;

  rtc::NATSocketServer* nat() { return nss_.get(); }
  rtc::FirewallSocketServer* fw() { return ss_.get(); }

  Endpoint* GetEndpoint(int endpoint) {
    if (endpoint == 0) {
      return &ep1_;
    } else if (endpoint == 1) {
      return &ep2_;
    } else {
      return NULL;
    }
  }
  BasicPortAllocator* GetAllocator(int endpoint) {
    return GetEndpoint(endpoint)->allocator_.get();
  }
  void AddAddress(int endpoint, const SocketAddress& addr) {
    GetEndpoint(endpoint)->network_manager_.AddInterface(addr);
  }
  void AddAddress(int endpoint,
                  const SocketAddress& addr,
                  const std::string& ifname,
                  rtc::AdapterType adapter_type) {
    GetEndpoint(endpoint)->network_manager_.AddInterface(addr, ifname,
                                                         adapter_type);
  }
  void RemoveAddress(int endpoint, const SocketAddress& addr) {
    GetEndpoint(endpoint)->network_manager_.RemoveInterface(addr);
    fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, addr);
  }
  void SetProxy(int endpoint, rtc::ProxyType type) {
    rtc::ProxyInfo info;
    info.type = type;
    info.address = (type == rtc::PROXY_HTTPS) ? kHttpsProxyAddrs[endpoint]
                                              : kSocksProxyAddrs[endpoint];
    GetAllocator(endpoint)->set_proxy("unittest/1.0", info);
  }
  void SetAllocatorFlags(int endpoint, int flags) {
    GetAllocator(endpoint)->set_flags(flags);
  }
  void SetIceRole(int endpoint, IceRole role) {
    GetEndpoint(endpoint)->SetIceRole(role);
  }
  void SetIceTiebreaker(int endpoint, uint64_t tiebreaker) {
    GetEndpoint(endpoint)->SetIceTiebreaker(tiebreaker);
  }
  bool GetRoleConflict(int endpoint) {
    return GetEndpoint(endpoint)->role_conflict();
  }
  void SetAllocationStepDelay(int endpoint, uint32_t delay) {
    return GetEndpoint(endpoint)->SetAllocationStepDelay(delay);
  }
  void SetAllowTcpListen(int endpoint, bool allow_tcp_listen) {
    return GetEndpoint(endpoint)->SetAllowTcpListen(allow_tcp_listen);
  }

  // Return true if the approprite parts of the expected Result, based
  // on the local and remote candidate of ep1_ch1, match.  This can be
  // used in an EXPECT_TRUE_WAIT.
  bool CheckCandidate1(const Result& expected) {
    const std::string& local_type = LocalCandidate(ep1_ch1())->type();
    const std::string& local_protocol = LocalCandidate(ep1_ch1())->protocol();
    const std::string& remote_type = RemoteCandidate(ep1_ch1())->type();
    const std::string& remote_protocol = RemoteCandidate(ep1_ch1())->protocol();
    return (local_protocol == expected.controlling_protocol &&
            remote_protocol == expected.controlled_protocol &&
            local_type == expected.controlling_type &&
            remote_type == expected.controlled_type);
  }

  // EXPECT_EQ on the approprite parts of the expected Result, based
  // on the local and remote candidate of ep1_ch1.  This is like
  // CheckCandidate1, except that it will provide more detail about
  // what didn't match.
  void ExpectCandidate1(const Result& expected) {
    if (CheckCandidate1(expected)) {
      return;
    }

    const std::string& local_type = LocalCandidate(ep1_ch1())->type();
    const std::string& local_protocol = LocalCandidate(ep1_ch1())->protocol();
    const std::string& remote_type = RemoteCandidate(ep1_ch1())->type();
    const std::string& remote_protocol = RemoteCandidate(ep1_ch1())->protocol();
    EXPECT_EQ(expected.controlling_type, local_type);
    EXPECT_EQ(expected.controlled_type, remote_type);
    EXPECT_EQ(expected.controlling_protocol, local_protocol);
    EXPECT_EQ(expected.controlled_protocol, remote_protocol);
  }

  // Return true if the approprite parts of the expected Result, based
  // on the local and remote candidate of ep2_ch1, match.  This can be
  // used in an EXPECT_TRUE_WAIT.
  bool CheckCandidate2(const Result& expected) {
    const std::string& local_type = LocalCandidate(ep2_ch1())->type();
    const std::string& local_protocol = LocalCandidate(ep2_ch1())->protocol();
    const std::string& remote_type = RemoteCandidate(ep2_ch1())->type();
    const std::string& remote_protocol = RemoteCandidate(ep2_ch1())->protocol();
    return (local_protocol == expected.controlled_protocol &&
            remote_protocol == expected.controlling_protocol &&
            local_type == expected.controlled_type &&
            remote_type == expected.controlling_type);
  }

  // EXPECT_EQ on the approprite parts of the expected Result, based
  // on the local and remote candidate of ep2_ch1.  This is like
  // CheckCandidate2, except that it will provide more detail about
  // what didn't match.
  void ExpectCandidate2(const Result& expected) {
    if (CheckCandidate2(expected)) {
      return;
    }

    const std::string& local_type = LocalCandidate(ep2_ch1())->type();
    const std::string& local_protocol = LocalCandidate(ep2_ch1())->protocol();
    const std::string& remote_type = RemoteCandidate(ep2_ch1())->type();
    const std::string& remote_protocol = RemoteCandidate(ep2_ch1())->protocol();
    EXPECT_EQ(expected.controlled_type, local_type);
    EXPECT_EQ(expected.controlling_type, remote_type);
    EXPECT_EQ(expected.controlled_protocol, local_protocol);
    EXPECT_EQ(expected.controlling_protocol, remote_protocol);
  }

  void Test(const Result& expected) {
    rtc::ScopedFakeClock clock;
    int64_t connect_start = rtc::TimeMillis();
    int64_t connect_time;

    // Create the channels and wait for them to connect.
    CreateChannels();
    EXPECT_TRUE_SIMULATED_WAIT(
        ep1_ch1() != NULL && ep2_ch1() != NULL && ep1_ch1()->receiving() &&
            ep1_ch1()->writable() && ep2_ch1()->receiving() &&
            ep2_ch1()->writable(),
        expected.connect_wait + kShortTimeout, clock);
    connect_time = rtc::TimeMillis() - connect_start;
    if (connect_time < expected.connect_wait) {
      RTC_LOG(LS_INFO) << "Connect time: " << connect_time << " ms";
    } else {
      RTC_LOG(LS_INFO) << "Connect time: TIMEOUT (" << expected.connect_wait
                       << " ms)";
    }

    // Allow a few turns of the crank for the selected connections to emerge.
    // This may take up to 2 seconds.
    if (ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection()) {
      int64_t converge_start = rtc::TimeMillis();
      int64_t converge_time;
      // Verifying local and remote channel selected connection information.
      // This is done only for the RFC 5245 as controlled agent will use
      // USE-CANDIDATE from controlling (ep1) agent. We can easily predict from
      // EP1 result matrix.
      EXPECT_TRUE_SIMULATED_WAIT(
          CheckCandidate1(expected) && CheckCandidate2(expected),
          kMediumTimeout, clock);
      // Also do EXPECT_EQ on each part so that failures are more verbose.
      ExpectCandidate1(expected);
      ExpectCandidate2(expected);

      converge_time = rtc::TimeMillis() - converge_start;
      int64_t converge_wait = 2000;
      if (converge_time < converge_wait) {
        RTC_LOG(LS_INFO) << "Converge time: " << converge_time << " ms";
      } else {
        RTC_LOG(LS_INFO) << "Converge time: TIMEOUT (" << converge_wait
                         << " ms)";
      }
    }
    // Try sending some data to other end.
    TestSendRecv(&clock);

    // Destroy the channels, and wait for them to be fully cleaned up.
    DestroyChannels();
  }

  void TestSendRecv(rtc::FakeClock* clock) {
    for (int i = 0; i < 10; ++i) {
      const char* data = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
      int len = static_cast<int>(strlen(data));
      // local_channel1 <==> remote_channel1
      EXPECT_EQ_SIMULATED_WAIT(len, SendData(ep1_ch1(), data, len),
                               kMediumTimeout, *clock);
      EXPECT_TRUE_SIMULATED_WAIT(CheckDataOnChannel(ep2_ch1(), data, len),
                                 kMediumTimeout, *clock);
      EXPECT_EQ_SIMULATED_WAIT(len, SendData(ep2_ch1(), data, len),
                               kMediumTimeout, *clock);
      EXPECT_TRUE_SIMULATED_WAIT(CheckDataOnChannel(ep1_ch1(), data, len),
                                 kMediumTimeout, *clock);
    }
  }

  // This test waits for the transport to become receiving and writable on both
  // end points. Once they are, the end points set new local ice parameters and
  // restart the ice gathering. Finally it waits for the transport to select a
  // new connection using the newly generated ice candidates.
  // Before calling this function the end points must be configured.
  void TestHandleIceUfragPasswordChanged() {
    rtc::ScopedFakeClock clock;
    ep1_ch1()->SetRemoteIceParameters(kIceParams[1]);
    ep2_ch1()->SetRemoteIceParameters(kIceParams[0]);
    EXPECT_TRUE_SIMULATED_WAIT(
        ep1_ch1()->receiving() && ep1_ch1()->writable() &&
            ep2_ch1()->receiving() && ep2_ch1()->writable(),
        kMediumTimeout, clock);

    const Candidate* old_local_candidate1 = LocalCandidate(ep1_ch1());
    const Candidate* old_local_candidate2 = LocalCandidate(ep2_ch1());
    const Candidate* old_remote_candidate1 = RemoteCandidate(ep1_ch1());
    const Candidate* old_remote_candidate2 = RemoteCandidate(ep2_ch1());

    ep1_ch1()->SetIceParameters(kIceParams[2]);
    ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
    ep1_ch1()->MaybeStartGathering();
    ep2_ch1()->SetIceParameters(kIceParams[3]);

    ep2_ch1()->SetRemoteIceParameters(kIceParams[2]);
    ep2_ch1()->MaybeStartGathering();

    EXPECT_TRUE_SIMULATED_WAIT(LocalCandidate(ep1_ch1())->generation() !=
                                   old_local_candidate1->generation(),
                               kMediumTimeout, clock);
    EXPECT_TRUE_SIMULATED_WAIT(LocalCandidate(ep2_ch1())->generation() !=
                                   old_local_candidate2->generation(),
                               kMediumTimeout, clock);
    EXPECT_TRUE_SIMULATED_WAIT(RemoteCandidate(ep1_ch1())->generation() !=
                                   old_remote_candidate1->generation(),
                               kMediumTimeout, clock);
    EXPECT_TRUE_SIMULATED_WAIT(RemoteCandidate(ep2_ch1())->generation() !=
                                   old_remote_candidate2->generation(),
                               kMediumTimeout, clock);
    EXPECT_EQ(1u, RemoteCandidate(ep2_ch1())->generation());
    EXPECT_EQ(1u, RemoteCandidate(ep1_ch1())->generation());
  }

  void TestSignalRoleConflict() {
    rtc::ScopedFakeClock clock;
    // Default EP1 is in controlling state.
    SetIceTiebreaker(0, kLowTiebreaker);

    SetIceRole(1, ICEROLE_CONTROLLING);
    SetIceTiebreaker(1, kHighTiebreaker);

    // Creating channels with both channels role set to CONTROLLING.
    CreateChannels();
    // Since both the channels initiated with controlling state and channel2
    // has higher tiebreaker value, channel1 should receive SignalRoleConflict.
    EXPECT_TRUE_SIMULATED_WAIT(GetRoleConflict(0), kShortTimeout, clock);
    EXPECT_FALSE(GetRoleConflict(1));

    EXPECT_TRUE_SIMULATED_WAIT(
        ep1_ch1()->receiving() && ep1_ch1()->writable() &&
            ep2_ch1()->receiving() && ep2_ch1()->writable(),
        kShortTimeout, clock);

    EXPECT_TRUE(ep1_ch1()->selected_connection() &&
                ep2_ch1()->selected_connection());

    TestSendRecv(&clock);
  }

  void TestPacketInfoIsSet(rtc::PacketInfo info) {
    EXPECT_NE(info.packet_type, rtc::PacketType::kUnknown);
    EXPECT_NE(info.protocol, rtc::PacketInfoProtocolType::kUnknown);
    EXPECT_TRUE(info.network_id.has_value());
    EXPECT_FALSE(info.local_socket_address.IsNil());
  }

  void OnReadyToSend(rtc::PacketTransportInternal* transport) {
    GetEndpoint(transport)->ready_to_send_ = true;
  }

  // We pass the candidates directly to the other side.
  void OnCandidateGathered(IceTransportInternal* ch, const Candidate& c) {
    if (force_relay_ && c.type() != RELAY_PORT_TYPE)
      return;

    if (GetEndpoint(ch)->save_candidates_) {
      GetEndpoint(ch)->saved_candidates_.push_back(
          std::unique_ptr<CandidatesData>(new CandidatesData(ch, c)));
    } else {
      main_.Post(RTC_FROM_HERE, this, MSG_ADD_CANDIDATES,
                 new CandidatesData(ch, c));
    }
  }

  void OnNetworkRouteChanged(absl::optional<rtc::NetworkRoute> network_route) {
    // If the |network_route| is unset, don't count. This is used in the case
    // when the network on remote side is down, the signal will be fired with an
    // unset network route and it shouldn't trigger a connection switch.
    if (network_route) {
      ++selected_candidate_pair_switches_;
    }
  }

  int reset_selected_candidate_pair_switches() {
    int switches = selected_candidate_pair_switches_;
    selected_candidate_pair_switches_ = 0;
    return switches;
  }

  void PauseCandidates(int endpoint) {
    GetEndpoint(endpoint)->save_candidates_ = true;
  }

  void OnCandidatesRemoved(IceTransportInternal* ch,
                           const std::vector<Candidate>& candidates) {
    // Candidate removals are not paused.
    CandidatesData* candidates_data = new CandidatesData(ch, candidates);
    main_.Post(RTC_FROM_HERE, this, MSG_REMOVE_CANDIDATES, candidates_data);
  }

  // Tcp candidate verification has to be done when they are generated.
  void VerifySavedTcpCandidates(int endpoint, const std::string& tcptype) {
    for (auto& data : GetEndpoint(endpoint)->saved_candidates_) {
      for (auto& candidate : data->candidates) {
        EXPECT_EQ(candidate.protocol(), TCP_PROTOCOL_NAME);
        EXPECT_EQ(candidate.tcptype(), tcptype);
        if (candidate.tcptype() == TCPTYPE_ACTIVE_STR) {
          EXPECT_EQ(candidate.address().port(), DISCARD_PORT);
        } else if (candidate.tcptype() == TCPTYPE_PASSIVE_STR) {
          EXPECT_NE(candidate.address().port(), DISCARD_PORT);
        } else {
          FAIL() << "Unknown tcptype: " << candidate.tcptype();
        }
      }
    }
  }

  SocketAddress ReplaceSavedCandidateIpWithHostname(
      int endpoint,
      const SocketAddress& hostname_address) {
    Endpoint* ed = GetEndpoint(endpoint);

    RTC_CHECK(1 == ed->saved_candidates_.size());
    auto& candidates = ed->saved_candidates_[0];
    RTC_CHECK(1 == candidates->candidates.size());
    auto& candidate = candidates->candidates[0];
    SocketAddress ip_address = candidate.address();
    candidate.set_address(hostname_address);
    return ip_address;
  }

  void ResumeCandidates(int endpoint) {
    Endpoint* ed = GetEndpoint(endpoint);
    for (auto& candidate : ed->saved_candidates_) {
      main_.Post(RTC_FROM_HERE, this, MSG_ADD_CANDIDATES, candidate.release());
    }
    ed->saved_candidates_.clear();
    ed->save_candidates_ = false;
  }

  void OnMessage(rtc::Message* msg) {
    switch (msg->message_id) {
      case MSG_ADD_CANDIDATES: {
        std::unique_ptr<CandidatesData> data(
            static_cast<CandidatesData*>(msg->pdata));
        P2PTransportChannel* rch = GetRemoteChannel(data->channel);
        if (!rch) {
          return;
        }
        for (auto& c : data->candidates) {
          if (remote_ice_parameter_source_ != FROM_CANDIDATE) {
            c.set_username("");
            c.set_password("");
          }
          RTC_LOG(LS_INFO) << "Candidate(" << data->channel->component() << "->"
                           << rch->component() << "): " << c.ToString();
          rch->AddRemoteCandidate(c);
        }
        break;
      }
      case MSG_REMOVE_CANDIDATES: {
        std::unique_ptr<CandidatesData> data(
            static_cast<CandidatesData*>(msg->pdata));
        P2PTransportChannel* rch = GetRemoteChannel(data->channel);
        if (!rch) {
          return;
        }
        for (Candidate& c : data->candidates) {
          RTC_LOG(LS_INFO) << "Removed remote candidate " << c.ToString();
          rch->RemoveRemoteCandidate(c);
        }
        break;
      }
    }
  }

  void OnReadPacket(rtc::PacketTransportInternal* transport,
                    const char* data,
                    size_t len,
                    const rtc::PacketTime& packet_time,
                    int flags) {
    std::list<std::string>& packets = GetPacketList(transport);
    packets.push_front(std::string(data, len));
  }

  void OnRoleConflict(IceTransportInternal* channel) {
    GetEndpoint(channel)->OnRoleConflict(true);
    IceRole new_role = GetEndpoint(channel)->ice_role() == ICEROLE_CONTROLLING
                           ? ICEROLE_CONTROLLED
                           : ICEROLE_CONTROLLING;
    channel->SetIceRole(new_role);
  }

  void OnSentPacket(rtc::PacketTransportInternal* transport,
                    const rtc::SentPacket& packet) {
    TestPacketInfoIsSet(packet.info);
  }

  int SendData(IceTransportInternal* channel, const char* data, size_t len) {
    rtc::PacketOptions options;
    return channel->SendPacket(data, len, options, 0);
  }
  bool CheckDataOnChannel(IceTransportInternal* channel,
                          const char* data,
                          int len) {
    return GetChannelData(channel)->CheckData(data, len);
  }
  static const Candidate* LocalCandidate(P2PTransportChannel* ch) {
    return (ch && ch->selected_connection())
               ? &ch->selected_connection()->local_candidate()
               : NULL;
  }
  static const Candidate* RemoteCandidate(P2PTransportChannel* ch) {
    return (ch && ch->selected_connection())
               ? &ch->selected_connection()->remote_candidate()
               : NULL;
  }
  Endpoint* GetEndpoint(rtc::PacketTransportInternal* transport) {
    if (ep1_.HasTransport(transport)) {
      return &ep1_;
    } else if (ep2_.HasTransport(transport)) {
      return &ep2_;
    } else {
      return NULL;
    }
  }
  P2PTransportChannel* GetRemoteChannel(IceTransportInternal* ch) {
    if (ch == ep1_ch1())
      return ep2_ch1();
    else if (ch == ep1_ch2())
      return ep2_ch2();
    else if (ch == ep2_ch1())
      return ep1_ch1();
    else if (ch == ep2_ch2())
      return ep1_ch2();
    else
      return NULL;
  }
  std::list<std::string>& GetPacketList(
      rtc::PacketTransportInternal* transport) {
    return GetChannelData(transport)->ch_packets_;
  }

  enum RemoteIceParameterSource { FROM_CANDIDATE, FROM_SETICEPARAMETERS };

  // How does the test pass ICE parameters to the P2PTransportChannel?
  // On the candidate itself, or through SetRemoteIceParameters?
  // Goes through the candidate itself by default.
  void set_remote_ice_parameter_source(RemoteIceParameterSource source) {
    remote_ice_parameter_source_ = source;
  }

  void set_force_relay(bool relay) { force_relay_ = relay; }

  void ConnectSignalNominated(Connection* conn) {
    conn->SignalNominated.connect(this,
                                  &P2PTransportChannelTestBase::OnNominated);
  }

  void OnNominated(Connection* conn) { nominated_ = true; }
  bool nominated() { return nominated_; }

 private:
  std::unique_ptr<rtc::VirtualSocketServer> vss_;
  std::unique_ptr<rtc::NATSocketServer> nss_;
  std::unique_ptr<rtc::FirewallSocketServer> ss_;
  rtc::AutoSocketServerThread main_;
  std::unique_ptr<TestStunServer> stun_server_;
  TestTurnServer turn_server_;
  rtc::SocksProxyServer socks_server1_;
  rtc::SocksProxyServer socks_server2_;
  Endpoint ep1_;
  Endpoint ep2_;
  RemoteIceParameterSource remote_ice_parameter_source_ = FROM_CANDIDATE;
  bool force_relay_;
  int selected_candidate_pair_switches_ = 0;

  bool nominated_ = false;
};

// The tests have only a few outcomes, which we predefine.
const P2PTransportChannelTestBase::Result
    P2PTransportChannelTestBase::kLocalUdpToLocalUdp("local",
                                                     "udp",
                                                     "local",
                                                     "udp",
                                                     1000);
const P2PTransportChannelTestBase::Result
    P2PTransportChannelTestBase::kLocalUdpToStunUdp("local",
                                                    "udp",
                                                    "stun",
                                                    "udp",
                                                    1000);
const P2PTransportChannelTestBase::Result
    P2PTransportChannelTestBase::kLocalUdpToPrflxUdp("local",
                                                     "udp",
                                                     "prflx",
                                                     "udp",
                                                     1000);
const P2PTransportChannelTestBase::Result
    P2PTransportChannelTestBase::kPrflxUdpToLocalUdp("prflx",
                                                     "udp",
                                                     "local",
                                                     "udp",
                                                     1000);
const P2PTransportChannelTestBase::Result
    P2PTransportChannelTestBase::kStunUdpToLocalUdp("stun",
                                                    "udp",
                                                    "local",
                                                    "udp",
                                                    1000);
const P2PTransportChannelTestBase::Result
    P2PTransportChannelTestBase::kStunUdpToStunUdp("stun",
                                                   "udp",
                                                   "stun",
                                                   "udp",
                                                   1000);
const P2PTransportChannelTestBase::Result
    P2PTransportChannelTestBase::kStunUdpToPrflxUdp("stun",
                                                    "udp",
                                                    "prflx",
                                                    "udp",
                                                    1000);
const P2PTransportChannelTestBase::Result
    P2PTransportChannelTestBase::kPrflxUdpToStunUdp("prflx",
                                                    "udp",
                                                    "stun",
                                                    "udp",
                                                    1000);
const P2PTransportChannelTestBase::Result
    P2PTransportChannelTestBase::kLocalUdpToRelayUdp("local",
                                                     "udp",
                                                     "relay",
                                                     "udp",
                                                     2000);
const P2PTransportChannelTestBase::Result
    P2PTransportChannelTestBase::kPrflxUdpToRelayUdp("prflx",
                                                     "udp",
                                                     "relay",
                                                     "udp",
                                                     2000);
const P2PTransportChannelTestBase::Result
    P2PTransportChannelTestBase::kRelayUdpToPrflxUdp("relay",
                                                     "udp",
                                                     "prflx",
                                                     "udp",
                                                     2000);
const P2PTransportChannelTestBase::Result
    P2PTransportChannelTestBase::kLocalTcpToLocalTcp("local",
                                                     "tcp",
                                                     "local",
                                                     "tcp",
                                                     3000);
const P2PTransportChannelTestBase::Result
    P2PTransportChannelTestBase::kLocalTcpToPrflxTcp("local",
                                                     "tcp",
                                                     "prflx",
                                                     "tcp",
                                                     3000);
const P2PTransportChannelTestBase::Result
    P2PTransportChannelTestBase::kPrflxTcpToLocalTcp("prflx",
                                                     "tcp",
                                                     "local",
                                                     "tcp",
                                                     3000);

// Test the matrix of all the connectivity types we expect to see in the wild.
// Just test every combination of the configs in the Config enum.
class P2PTransportChannelTest : public P2PTransportChannelTestBase {
 protected:
  static const Result* kMatrix[NUM_CONFIGS][NUM_CONFIGS];
  void ConfigureEndpoints(Config config1,
                          Config config2,
                          int allocator_flags1,
                          int allocator_flags2) {
    ConfigureEndpoint(0, config1);
    SetAllocatorFlags(0, allocator_flags1);
    SetAllocationStepDelay(0, kMinimumStepDelay);
    ConfigureEndpoint(1, config2);
    SetAllocatorFlags(1, allocator_flags2);
    SetAllocationStepDelay(1, kMinimumStepDelay);

    set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
  }
  void ConfigureEndpoint(int endpoint, Config config) {
    switch (config) {
      case OPEN:
        AddAddress(endpoint, kPublicAddrs[endpoint]);
        break;
      case NAT_FULL_CONE:
      case NAT_ADDR_RESTRICTED:
      case NAT_PORT_RESTRICTED:
      case NAT_SYMMETRIC:
        AddAddress(endpoint, kPrivateAddrs[endpoint]);
        // Add a single NAT of the desired type
        nat()
            ->AddTranslator(kPublicAddrs[endpoint], kNatAddrs[endpoint],
                            static_cast<rtc::NATType>(config - NAT_FULL_CONE))
            ->AddClient(kPrivateAddrs[endpoint]);
        break;
      case NAT_DOUBLE_CONE:
      case NAT_SYMMETRIC_THEN_CONE:
        AddAddress(endpoint, kCascadedPrivateAddrs[endpoint]);
        // Add a two cascaded NATs of the desired types
        nat()
            ->AddTranslator(kPublicAddrs[endpoint], kNatAddrs[endpoint],
                            (config == NAT_DOUBLE_CONE) ? rtc::NAT_OPEN_CONE
                                                        : rtc::NAT_SYMMETRIC)
            ->AddTranslator(kPrivateAddrs[endpoint],
                            kCascadedNatAddrs[endpoint], rtc::NAT_OPEN_CONE)
            ->AddClient(kCascadedPrivateAddrs[endpoint]);
        break;
      case BLOCK_UDP:
      case BLOCK_UDP_AND_INCOMING_TCP:
      case BLOCK_ALL_BUT_OUTGOING_HTTP:
      case PROXY_HTTPS:
      case PROXY_SOCKS:
        AddAddress(endpoint, kPublicAddrs[endpoint]);
        // Block all UDP
        fw()->AddRule(false, rtc::FP_UDP, rtc::FD_ANY, kPublicAddrs[endpoint]);
        if (config == BLOCK_UDP_AND_INCOMING_TCP) {
          // Block TCP inbound to the endpoint
          fw()->AddRule(false, rtc::FP_TCP, SocketAddress(),
                        kPublicAddrs[endpoint]);
        } else if (config == BLOCK_ALL_BUT_OUTGOING_HTTP) {
          // Block all TCP to/from the endpoint except 80/443 out
          fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint],
                        SocketAddress(rtc::IPAddress(INADDR_ANY), 80));
          fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint],
                        SocketAddress(rtc::IPAddress(INADDR_ANY), 443));
          fw()->AddRule(false, rtc::FP_TCP, rtc::FD_ANY,
                        kPublicAddrs[endpoint]);
        } else if (config == PROXY_HTTPS) {
          // Block all TCP to/from the endpoint except to the proxy server
          fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint],
                        kHttpsProxyAddrs[endpoint]);
          fw()->AddRule(false, rtc::FP_TCP, rtc::FD_ANY,
                        kPublicAddrs[endpoint]);
          SetProxy(endpoint, rtc::PROXY_HTTPS);
        } else if (config == PROXY_SOCKS) {
          // Block all TCP to/from the endpoint except to the proxy server
          fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint],
                        kSocksProxyAddrs[endpoint]);
          fw()->AddRule(false, rtc::FP_TCP, rtc::FD_ANY,
                        kPublicAddrs[endpoint]);
          SetProxy(endpoint, rtc::PROXY_SOCKS5);
        }
        break;
      default:
        RTC_NOTREACHED();
        break;
    }
  }
};

// Shorthands for use in the test matrix.
#define LULU &kLocalUdpToLocalUdp
#define LUSU &kLocalUdpToStunUdp
#define LUPU &kLocalUdpToPrflxUdp
#define PULU &kPrflxUdpToLocalUdp
#define SULU &kStunUdpToLocalUdp
#define SUSU &kStunUdpToStunUdp
#define SUPU &kStunUdpToPrflxUdp
#define PUSU &kPrflxUdpToStunUdp
#define LURU &kLocalUdpToRelayUdp
#define PURU &kPrflxUdpToRelayUdp
#define RUPU &kRelayUdpToPrflxUdp
#define LTLT &kLocalTcpToLocalTcp
#define LTPT &kLocalTcpToPrflxTcp
#define PTLT &kPrflxTcpToLocalTcp
// TODO(?): Enable these once TestRelayServer can accept external TCP.
#define LTRT NULL
#define LSRS NULL

// Test matrix. Originator behavior defined by rows, receiever by columns.

// TODO(?): Fix NULLs caused by lack of TCP support in NATSocket.
// TODO(?): Fix NULLs caused by no HTTP proxy support.
// TODO(?): Rearrange rows/columns from best to worst.
const P2PTransportChannelTest::Result*
    P2PTransportChannelTest::kMatrix[NUM_CONFIGS][NUM_CONFIGS] = {
        //      OPEN  CONE  ADDR  PORT  SYMM  2CON  SCON  !UDP  !TCP  HTTP  PRXH
        //      PRXS
        /*OP*/ {LULU, LUSU, LUSU, LUSU, LUPU, LUSU, LUPU, LTPT, LTPT, LSRS,
                NULL, LTPT},
        /*CO*/
        {SULU, SUSU, SUSU, SUSU, SUPU, SUSU, SUPU, NULL, NULL, LSRS, NULL,
         LTRT},
        /*AD*/
        {SULU, SUSU, SUSU, SUSU, SUPU, SUSU, SUPU, NULL, NULL, LSRS, NULL,
         LTRT},
        /*PO*/
        {SULU, SUSU, SUSU, SUSU, RUPU, SUSU, RUPU, NULL, NULL, LSRS, NULL,
         LTRT},
        /*SY*/
        {PULU, PUSU, PUSU, PURU, PURU, PUSU, PURU, NULL, NULL, LSRS, NULL,
         LTRT},
        /*2C*/
        {SULU, SUSU, SUSU, SUSU, SUPU, SUSU, SUPU, NULL, NULL, LSRS, NULL,
         LTRT},
        /*SC*/
        {PULU, PUSU, PUSU, PURU, PURU, PUSU, PURU, NULL, NULL, LSRS, NULL,
         LTRT},
        /*!U*/
        {LTPT, NULL, NULL, NULL, NULL, NULL, NULL, LTPT, LTPT, LSRS, NULL,
         LTRT},
        /*!T*/
        {PTLT, NULL, NULL, NULL, NULL, NULL, NULL, PTLT, LTRT, LSRS, NULL,
         LTRT},
        /*HT*/
        {LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, NULL,
         LSRS},
        /*PR*/
        {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
         NULL},
        /*PR*/
        {LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LSRS, NULL,
         LTRT},
};

// The actual tests that exercise all the various configurations.
// Test names are of the form P2PTransportChannelTest_TestOPENToNAT_FULL_CONE
#define P2P_TEST_DECLARATION(x, y, z)                            \
  TEST_F(P2PTransportChannelTest, z##Test##x##To##y) {           \
    ConfigureEndpoints(x, y, PORTALLOCATOR_ENABLE_SHARED_SOCKET, \
                       PORTALLOCATOR_ENABLE_SHARED_SOCKET);      \
    if (kMatrix[x][y] != NULL)                                   \
      Test(*kMatrix[x][y]);                                      \
    else                                                         \
      RTC_LOG(LS_WARNING) << "Not yet implemented";              \
  }

#define P2P_TEST(x, y) P2P_TEST_DECLARATION(x, y, /* empty argument */)

#define P2P_TEST_SET(x)                    \
  P2P_TEST(x, OPEN)                        \
  P2P_TEST(x, NAT_FULL_CONE)               \
  P2P_TEST(x, NAT_ADDR_RESTRICTED)         \
  P2P_TEST(x, NAT_PORT_RESTRICTED)         \
  P2P_TEST(x, NAT_SYMMETRIC)               \
  P2P_TEST(x, NAT_DOUBLE_CONE)             \
  P2P_TEST(x, NAT_SYMMETRIC_THEN_CONE)     \
  P2P_TEST(x, BLOCK_UDP)                   \
  P2P_TEST(x, BLOCK_UDP_AND_INCOMING_TCP)  \
  P2P_TEST(x, BLOCK_ALL_BUT_OUTGOING_HTTP) \
  P2P_TEST(x, PROXY_HTTPS)                 \
  P2P_TEST(x, PROXY_SOCKS)

P2P_TEST_SET(OPEN)
P2P_TEST_SET(NAT_FULL_CONE)
P2P_TEST_SET(NAT_ADDR_RESTRICTED)
P2P_TEST_SET(NAT_PORT_RESTRICTED)
P2P_TEST_SET(NAT_SYMMETRIC)
P2P_TEST_SET(NAT_DOUBLE_CONE)
P2P_TEST_SET(NAT_SYMMETRIC_THEN_CONE)
P2P_TEST_SET(BLOCK_UDP)
P2P_TEST_SET(BLOCK_UDP_AND_INCOMING_TCP)
P2P_TEST_SET(BLOCK_ALL_BUT_OUTGOING_HTTP)
P2P_TEST_SET(PROXY_HTTPS)
P2P_TEST_SET(PROXY_SOCKS)

// Test that we restart candidate allocation when local ufrag&pwd changed.
// Standard Ice protocol is used.
TEST_F(P2PTransportChannelTest, HandleUfragPwdChange) {
  ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
                     kDefaultPortAllocatorFlags);
  CreateChannels();
  TestHandleIceUfragPasswordChanged();
  DestroyChannels();
}

// Same as above test, but with a symmetric NAT.
// We should end up with relay<->prflx candidate pairs, with generation "1".
TEST_F(P2PTransportChannelTest, HandleUfragPwdChangeSymmetricNat) {
  ConfigureEndpoints(NAT_SYMMETRIC, NAT_SYMMETRIC, kDefaultPortAllocatorFlags,
                     kDefaultPortAllocatorFlags);
  CreateChannels();
  TestHandleIceUfragPasswordChanged();
  DestroyChannels();
}

// Test the operation of GetStats.
TEST_F(P2PTransportChannelTest, GetStats) {
  rtc::ScopedFakeClock clock;
  ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
                     kDefaultPortAllocatorFlags);
  CreateChannels();
  EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
                                 ep2_ch1()->receiving() &&
                                 ep2_ch1()->writable(),
                             kMediumTimeout, clock);
  TestSendRecv(&clock);
  ConnectionInfos infos;
  CandidateStatsList candidate_stats_list;
  ASSERT_TRUE(ep1_ch1()->GetStats(&infos, &candidate_stats_list));
  ASSERT_GE(infos.size(), 1u);
  ASSERT_GE(candidate_stats_list.size(), 1u);
  ConnectionInfo* best_conn_info = nullptr;
  for (ConnectionInfo& info : infos) {
    if (info.best_connection) {
      best_conn_info = &info;
      break;
    }
  }
  ASSERT_TRUE(best_conn_info != nullptr);
  EXPECT_TRUE(best_conn_info->new_connection);
  EXPECT_TRUE(best_conn_info->receiving);
  EXPECT_TRUE(best_conn_info->writable);
  EXPECT_FALSE(best_conn_info->timeout);
  EXPECT_EQ(10U, best_conn_info->sent_total_packets);
  EXPECT_EQ(0U, best_conn_info->sent_discarded_packets);
  EXPECT_EQ(10 * 36U, best_conn_info->sent_total_bytes);
  EXPECT_EQ(10 * 36U, best_conn_info->recv_total_bytes);
  DestroyChannels();
}

// Tests that UMAs are recorded when ICE restarts while the channel
// is disconnected.
TEST_F(P2PTransportChannelTest, TestUMAIceRestartWhileDisconnected) {
  rtc::ScopedFakeClock clock;
  ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);

  CreateChannels();
  EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
                                 ep2_ch1()->receiving() &&
                                 ep2_ch1()->writable(),
                             kDefaultTimeout, clock);

  // Drop all packets so that both channels become not writable.
  fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
  const int kWriteTimeoutDelay = 8000;
  EXPECT_TRUE_SIMULATED_WAIT(!ep1_ch1()->writable() && !ep2_ch1()->writable(),
                             kWriteTimeoutDelay, clock);

  ep1_ch1()->SetIceParameters(kIceParams[2]);
  ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
  ep1_ch1()->MaybeStartGathering();
  EXPECT_EQ(1, webrtc::metrics::NumEvents(
                   "WebRTC.PeerConnection.IceRestartState",
                   static_cast<int>(IceRestartState::DISCONNECTED)));

  ep2_ch1()->SetIceParameters(kIceParams[3]);
  ep2_ch1()->SetRemoteIceParameters(kIceParams[2]);
  ep2_ch1()->MaybeStartGathering();
  EXPECT_EQ(2, webrtc::metrics::NumEvents(
                   "WebRTC.PeerConnection.IceRestartState",
                   static_cast<int>(IceRestartState::DISCONNECTED)));

  DestroyChannels();
}

// Tests that UMAs are recorded when ICE restarts while the channel
// is connected.
TEST_F(P2PTransportChannelTest, TestUMAIceRestartWhileConnected) {
  rtc::ScopedFakeClock clock;
  ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);

  CreateChannels();
  EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
                                 ep2_ch1()->receiving() &&
                                 ep2_ch1()->writable(),
                             kDefaultTimeout, clock);

  ep1_ch1()->SetIceParameters(kIceParams[2]);
  ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
  ep1_ch1()->MaybeStartGathering();
  EXPECT_EQ(1, webrtc::metrics::NumEvents(
                   "WebRTC.PeerConnection.IceRestartState",
                   static_cast<int>(IceRestartState::CONNECTED)));

  ep2_ch1()->SetIceParameters(kIceParams[3]);
  ep2_ch1()->SetRemoteIceParameters(kIceParams[2]);
  ep2_ch1()->MaybeStartGathering();
  EXPECT_EQ(2, webrtc::metrics::NumEvents(
                   "WebRTC.PeerConnection.IceRestartState",
                   static_cast<int>(IceRestartState::CONNECTED)));

  DestroyChannels();
}

// Tests that UMAs are recorded when ICE restarts while the channel
// is connecting.
TEST_F(P2PTransportChannelTest, TestUMAIceRestartWhileConnecting) {
  rtc::ScopedFakeClock clock;
  ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);

  // Create the channels without waiting for them to become connected.
  CreateChannels();

  ep1_ch1()->SetIceParameters(kIceParams[2]);
  ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
  ep1_ch1()->MaybeStartGathering();
  EXPECT_EQ(1, webrtc::metrics::NumEvents(
                   "WebRTC.PeerConnection.IceRestartState",
                   static_cast<int>(IceRestartState::CONNECTING)));

  ep2_ch1()->SetIceParameters(kIceParams[3]);
  ep2_ch1()->SetRemoteIceParameters(kIceParams[2]);
  ep2_ch1()->MaybeStartGathering();
  EXPECT_EQ(2, webrtc::metrics::NumEvents(
                   "WebRTC.PeerConnection.IceRestartState",
                   static_cast<int>(IceRestartState::CONNECTING)));

  DestroyChannels();
}

// Tests that a UMA on ICE regathering is recorded when there is a network
// change if and only if continual gathering is enabled.
TEST_F(P2PTransportChannelTest,
       TestIceRegatheringReasonContinualGatheringByNetworkChange) {
  rtc::ScopedFakeClock clock;
  ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);

  // ep1 gathers continually but ep2 does not.
  IceConfig continual_gathering_config =
      CreateIceConfig(1000, GATHER_CONTINUALLY);
  IceConfig default_config;
  CreateChannels(continual_gathering_config, default_config);

  EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
                                 ep2_ch1()->receiving() &&
                                 ep2_ch1()->writable(),
                             kDefaultTimeout, clock);

  // Adding address in ep1 will trigger continual gathering.
  AddAddress(0, kAlternateAddrs[0]);
  EXPECT_EQ_SIMULATED_WAIT(1,
                           GetEndpoint(0)->GetIceRegatheringCountForReason(
                               IceRegatheringReason::NETWORK_CHANGE),
                           kDefaultTimeout, clock);

  ep2_ch1()->SetIceParameters(kIceParams[3]);
  ep2_ch1()->SetRemoteIceParameters(kIceParams[2]);
  ep2_ch1()->MaybeStartGathering();

  AddAddress(1, kAlternateAddrs[1]);
  SIMULATED_WAIT(false, kDefaultTimeout, clock);
  // ep2 has not enabled continual gathering.
  EXPECT_EQ(0, GetEndpoint(1)->GetIceRegatheringCountForReason(
                   IceRegatheringReason::NETWORK_CHANGE));

  DestroyChannels();
}

// Tests that a UMA on ICE regathering is recorded when there is a network
// failure if and only if continual gathering is enabled.
TEST_F(P2PTransportChannelTest,
       TestIceRegatheringReasonContinualGatheringByNetworkFailure) {
  rtc::ScopedFakeClock clock;
  ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);

  // ep1 gathers continually but ep2 does not.
  IceConfig config1 = CreateIceConfig(1000, GATHER_CONTINUALLY);
  config1.regather_on_failed_networks_interval = 2000;
  IceConfig config2;
  config2.regather_on_failed_networks_interval = 2000;
  CreateChannels(config1, config2);

  EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
                                 ep2_ch1()->receiving() &&
                                 ep2_ch1()->writable(),
                             kDefaultTimeout, clock);

  fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
  // Timeout value such that all connections are deleted.
  const int kNetworkFailureTimeout = 35000;
  SIMULATED_WAIT(false, kNetworkFailureTimeout, clock);
  EXPECT_LE(1, GetEndpoint(0)->GetIceRegatheringCountForReason(
                   IceRegatheringReason::NETWORK_FAILURE));
  EXPECT_LE(1, webrtc::metrics::NumEvents(
                   "WebRTC.PeerConnection.IceRegatheringReason",
                   static_cast<int>(IceRegatheringReason::NETWORK_FAILURE)));
  EXPECT_EQ(0, GetEndpoint(1)->GetIceRegatheringCountForReason(
                   IceRegatheringReason::NETWORK_FAILURE));

  DestroyChannels();
}

// Tests that ICE regathering occurs regularly when
// regather_all_networks_interval_range configuration value is set.
TEST_F(P2PTransportChannelTest, TestIceRegatherOnAllNetworksContinual) {
  rtc::ScopedFakeClock clock;
  ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);

  // ep1 gathers continually but ep2 does not.
  const int kRegatherInterval = 2000;
  IceConfig config1 = CreateIceConfig(1000, GATHER_CONTINUALLY);
  config1.regather_all_networks_interval_range.emplace(kRegatherInterval,
                                                       kRegatherInterval);
  IceConfig config2;
  CreateChannels(config1, config2);

  EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
                                 ep2_ch1()->receiving() &&
                                 ep2_ch1()->writable(),
                             kDefaultTimeout, clock);

  fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
  // Timeout value such that all connections are deleted.
  const int kNetworkGatherDuration = 11000;
  SIMULATED_WAIT(false, kNetworkGatherDuration, clock);
  // Expect regathering to happen 5 times in 11s with 2s interval.
  EXPECT_LE(5, GetEndpoint(0)->GetIceRegatheringCountForReason(
                   IceRegatheringReason::OCCASIONAL_REFRESH));
  EXPECT_LE(5, webrtc::metrics::NumEvents(
                   "WebRTC.PeerConnection.IceRegatheringReason",
                   static_cast<int>(IceRegatheringReason::OCCASIONAL_REFRESH)));
  // Expect no regathering if continual gathering not configured.
  EXPECT_EQ(0, GetEndpoint(1)->GetIceRegatheringCountForReason(
                   IceRegatheringReason::OCCASIONAL_REFRESH));

  DestroyChannels();
}

// Test that ICE periodic regathering can change the selected connection on the
// specified interval and that the peers can communicate over the new
// connection. The test is parameterized to test that it works when regathering
// is done by the ICE controlling peer and when done by the controlled peer.
class P2PTransportRegatherAllNetworksTest : public P2PTransportChannelTest {
 protected:
  void TestWithRoles(IceRole p1_role, IceRole p2_role) {
    rtc::ScopedFakeClock clock;
    ConfigureEndpoints(NAT_SYMMETRIC, NAT_SYMMETRIC, kDefaultPortAllocatorFlags,
                       kDefaultPortAllocatorFlags);
    set_force_relay(true);

    const int kRegatherInterval = 2000;
    const int kNumRegathers = 2;

    // Set up peer 1 to auto regather every 2s.
    IceConfig config1 = CreateIceConfig(1000, GATHER_CONTINUALLY);
    config1.regather_all_networks_interval_range.emplace(kRegatherInterval,
                                                         kRegatherInterval);
    IceConfig config2 = CreateIceConfig(1000, GATHER_CONTINUALLY);

    // Set peer roles.
    SetIceRole(0, p1_role);
    SetIceRole(1, p2_role);

    CreateChannels(config1, config2);

    // Wait for initial connection to be made.
    EXPECT_TRUE_SIMULATED_WAIT(
        ep1_ch1()->receiving() && ep1_ch1()->writable() &&
            ep2_ch1()->receiving() && ep2_ch1()->writable(),
        kMediumTimeout, clock);

    const Connection* initial_selected = ep1_ch1()->selected_connection();

    // Wait long enough for 2 regathering cycles to happen plus some extra so
    // the new connection has time to settle.
    const int kWaitRegather =
        kRegatherInterval * kNumRegathers + kRegatherInterval / 2;
    SIMULATED_WAIT(false, kWaitRegather, clock);
    EXPECT_EQ(kNumRegathers, GetEndpoint(0)->GetIceRegatheringCountForReason(
                                 IceRegatheringReason::OCCASIONAL_REFRESH));

    const Connection* new_selected = ep1_ch1()->selected_connection();

    // Want the new selected connection to be different.
    ASSERT_NE(initial_selected, new_selected);

    // Make sure we can communicate over the new connection too.
    TestSendRecv(&clock);
  }
};

TEST_F(P2PTransportRegatherAllNetworksTest, TestControlling) {
  TestWithRoles(ICEROLE_CONTROLLING, ICEROLE_CONTROLLED);
}

TEST_F(P2PTransportRegatherAllNetworksTest, TestControlled) {
  TestWithRoles(ICEROLE_CONTROLLED, ICEROLE_CONTROLLING);
}

// Test that we properly create a connection on a STUN ping from unknown address
// when the signaling is slow.
TEST_F(P2PTransportChannelTest, PeerReflexiveCandidateBeforeSignaling) {
  ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
                     kDefaultPortAllocatorFlags);
  // Emulate no remote parameters coming in.
  set_remote_ice_parameter_source(FROM_CANDIDATE);
  CreateChannels();
  // Only have remote parameters come in for ep2, not ep1.
  ep2_ch1()->SetRemoteIceParameters(kIceParams[0]);

  // Pause sending ep2's candidates to ep1 until ep1 receives the peer reflexive
  // candidate.
  PauseCandidates(1);

  // Wait until the callee becomes writable to make sure that a ping request is
  // received by the caller before his remote ICE credentials are set.
  ASSERT_TRUE_WAIT(ep2_ch1()->selected_connection() != nullptr, kMediumTimeout);
  // Add two sets of remote ICE credentials, so that the ones used by the
  // candidate will be generation 1 instead of 0.
  ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
  ep1_ch1()->SetRemoteIceParameters(kIceParams[1]);
  // The caller should have the selected connection connected to the peer
  // reflexive candidate.
  const Connection* selected_connection = nullptr;
  ASSERT_TRUE_WAIT(
      (selected_connection = ep1_ch1()->selected_connection()) != nullptr,
      kMediumTimeout);
  EXPECT_EQ(PRFLX_PORT_TYPE, selected_connection->remote_candidate().type());
  EXPECT_EQ(kIceUfrag[1], selected_connection->remote_candidate().username());
  EXPECT_EQ(kIcePwd[1], selected_connection->remote_candidate().password());
  EXPECT_EQ(1u, selected_connection->remote_candidate().generation());

  ResumeCandidates(1);
  // Verify ep1's selected connection is updated to use the 'local' candidate.
  EXPECT_EQ_WAIT(LOCAL_PORT_TYPE,
                 ep1_ch1()->selected_connection()->remote_candidate().type(),
                 kMediumTimeout);
  EXPECT_EQ(selected_connection, ep1_ch1()->selected_connection());
  DestroyChannels();
}

// Test that we properly create a connection on a STUN ping from unknown address
// when the signaling is slow and the end points are behind NAT.
TEST_F(P2PTransportChannelTest, PeerReflexiveCandidateBeforeSignalingWithNAT) {
  ConfigureEndpoints(OPEN, NAT_SYMMETRIC, kDefaultPortAllocatorFlags,
                     kDefaultPortAllocatorFlags);
  // Emulate no remote parameters coming in.
  set_remote_ice_parameter_source(FROM_CANDIDATE);
  CreateChannels();
  // Only have remote parameters come in for ep2, not ep1.
  ep2_ch1()->SetRemoteIceParameters(kIceParams[0]);
  // Pause sending ep2's candidates to ep1 until ep1 receives the peer reflexive
  // candidate.
  PauseCandidates(1);

  // Wait until the callee becomes writable to make sure that a ping request is
  // received by the caller before his remote ICE credentials are set.
  ASSERT_TRUE_WAIT(ep2_ch1()->selected_connection() != nullptr, kMediumTimeout);
  // Add two sets of remote ICE credentials, so that the ones used by the
  // candidate will be generation 1 instead of 0.
  ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
  ep1_ch1()->SetRemoteIceParameters(kIceParams[1]);

  // The caller's selected connection should be connected to the peer reflexive
  // candidate.
  const Connection* selected_connection = nullptr;
  ASSERT_TRUE_WAIT(
      (selected_connection = ep1_ch1()->selected_connection()) != nullptr,
      kMediumTimeout);
  EXPECT_EQ(PRFLX_PORT_TYPE, selected_connection->remote_candidate().type());
  EXPECT_EQ(kIceUfrag[1], selected_connection->remote_candidate().username());
  EXPECT_EQ(kIcePwd[1], selected_connection->remote_candidate().password());
  EXPECT_EQ(1u, selected_connection->remote_candidate().generation());

  ResumeCandidates(1);

  EXPECT_EQ_WAIT(PRFLX_PORT_TYPE,
                 ep1_ch1()->selected_connection()->remote_candidate().type(),
                 kMediumTimeout);
  EXPECT_EQ(selected_connection, ep1_ch1()->selected_connection());
  DestroyChannels();
}

// Test that we properly create a connection on a STUN ping from unknown address
// when the signaling is slow, even if the new candidate is created due to the
// remote peer doing an ICE restart, pairing this candidate across generations.
//
// Previously this wasn't working due to a bug where the peer reflexive
// candidate was only updated for the newest generation candidate pairs, and
// not older-generation candidate pairs created by pairing candidates across
// generations. This resulted in the old-generation prflx candidate being
// prioritized above new-generation candidate pairs.
TEST_F(P2PTransportChannelTest,
       PeerReflexiveCandidateBeforeSignalingWithIceRestart) {
  ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
                     kDefaultPortAllocatorFlags);
  // Only gather relay candidates, so that when the prflx candidate arrives
  // it's prioritized above the current candidate pair.
  GetEndpoint(0)->allocator_->set_candidate_filter(CF_RELAY);
  GetEndpoint(1)->allocator_->set_candidate_filter(CF_RELAY);
  // Setting this allows us to control when SetRemoteIceParameters is called.
  set_remote_ice_parameter_source(FROM_CANDIDATE);
  CreateChannels();
  // Wait for the initial connection to be made.
  ep1_ch1()->SetRemoteIceParameters(kIceParams[1]);
  ep2_ch1()->SetRemoteIceParameters(kIceParams[0]);
  EXPECT_TRUE_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
                       ep2_ch1()->receiving() && ep2_ch1()->writable(),
                   kDefaultTimeout);

  // Simulate an ICE restart on ep2, but don't signal the candidate or new
  // ICE parameters until after a prflx connection has been made.
  PauseCandidates(1);
  ep2_ch1()->SetIceParameters(kIceParams[3]);

  ep1_ch1()->SetRemoteIceParameters(kIceParams[3]);
  ep2_ch1()->MaybeStartGathering();

  // The caller should have the selected connection connected to the peer
  // reflexive candidate.
  EXPECT_EQ_WAIT(PRFLX_PORT_TYPE,
                 ep1_ch1()->selected_connection()->remote_candidate().type(),
                 kDefaultTimeout);
  const Connection* prflx_selected_connection =
      ep1_ch1()->selected_connection();

  // Now simulate the ICE restart on ep1.
  ep1_ch1()->SetIceParameters(kIceParams[2]);

  ep2_ch1()->SetRemoteIceParameters(kIceParams[2]);
  ep1_ch1()->MaybeStartGathering();

  // Finally send the candidates from ep2's ICE restart and verify that ep1 uses
  // their information to update the peer reflexive candidate.
  ResumeCandidates(1);

  EXPECT_EQ_WAIT(RELAY_PORT_TYPE,
                 ep1_ch1()->selected_connection()->remote_candidate().type(),
                 kDefaultTimeout);
  EXPECT_EQ(prflx_selected_connection, ep1_ch1()->selected_connection());
  DestroyChannels();
}

// Test that if remote candidates don't have ufrag and pwd, we still work.
TEST_F(P2PTransportChannelTest, RemoteCandidatesWithoutUfragPwd) {
  rtc::ScopedFakeClock clock;
  set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
  ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
                     kDefaultPortAllocatorFlags);
  CreateChannels();
  const Connection* selected_connection = NULL;
  // Wait until the callee's connections are created.
  EXPECT_TRUE_SIMULATED_WAIT(
      (selected_connection = ep2_ch1()->selected_connection()) != NULL,
      kMediumTimeout, clock);
  // Wait to make sure the selected connection is not changed.
  SIMULATED_WAIT(ep2_ch1()->selected_connection() != selected_connection,
                 kShortTimeout, clock);
  EXPECT_TRUE(ep2_ch1()->selected_connection() == selected_connection);
  DestroyChannels();
}

// Test that a host behind NAT cannot be reached when incoming_only
// is set to true.
TEST_F(P2PTransportChannelTest, IncomingOnlyBlocked) {
  rtc::ScopedFakeClock clock;
  ConfigureEndpoints(NAT_FULL_CONE, OPEN, kDefaultPortAllocatorFlags,
                     kDefaultPortAllocatorFlags);

  SetAllocatorFlags(0, kOnlyLocalPorts);
  CreateChannels();
  ep1_ch1()->set_incoming_only(true);

  // Pump for 1 second and verify that the channels are not connected.
  SIMULATED_WAIT(false, kShortTimeout, clock);

  EXPECT_FALSE(ep1_ch1()->receiving());
  EXPECT_FALSE(ep1_ch1()->writable());
  EXPECT_FALSE(ep2_ch1()->receiving());
  EXPECT_FALSE(ep2_ch1()->writable());

  DestroyChannels();
}

// Test that a peer behind NAT can connect to a peer that has
// incoming_only flag set.
TEST_F(P2PTransportChannelTest, IncomingOnlyOpen) {
  rtc::ScopedFakeClock clock;
  ConfigureEndpoints(OPEN, NAT_FULL_CONE, kDefaultPortAllocatorFlags,
                     kDefaultPortAllocatorFlags);

  SetAllocatorFlags(0, kOnlyLocalPorts);
  CreateChannels();
  ep1_ch1()->set_incoming_only(true);

  EXPECT_TRUE_SIMULATED_WAIT(
      ep1_ch1() != NULL && ep2_ch1() != NULL && ep1_ch1()->receiving() &&
          ep1_ch1()->writable() && ep2_ch1()->receiving() &&
          ep2_ch1()->writable(),
      kMediumTimeout, clock);

  DestroyChannels();
}

// Test that two peers can connect when one can only make outgoing TCP
// connections. This has been observed in some scenarios involving
// VPNs/firewalls.
TEST_F(P2PTransportChannelTest, CanOnlyMakeOutgoingTcpConnections) {
  // The PORTALLOCATOR_ENABLE_ANY_ADDRESS_PORTS flag is required if the
  // application needs this use case to work, since the application must accept
  // the tradeoff that more candidates need to be allocated.
  //
  // TODO(deadbeef): Later, make this flag the default, and do more elegant
  // things to ensure extra candidates don't waste resources?
  ConfigureEndpoints(
      OPEN, OPEN,
      kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_ANY_ADDRESS_PORTS,
      kDefaultPortAllocatorFlags);
  // In order to simulate nothing working but outgoing TCP connections, prevent
  // the endpoint from binding to its interface's address as well as the
  // "any" addresses. It can then only make a connection by using "Connect()".
  fw()->SetUnbindableIps({rtc::GetAnyIP(AF_INET), rtc::GetAnyIP(AF_INET6),
                          kPublicAddrs[0].ipaddr()});
  CreateChannels();
  // Expect a "prflx" candidate on the side that can only make outgoing
  // connections, endpoint 0.
  Test(kPrflxTcpToLocalTcp);
  DestroyChannels();
}

TEST_F(P2PTransportChannelTest, TestTcpConnectionsFromActiveToPassive) {
  rtc::ScopedFakeClock clock;
  AddAddress(0, kPublicAddrs[0]);
  AddAddress(1, kPublicAddrs[1]);

  SetAllocationStepDelay(0, kMinimumStepDelay);
  SetAllocationStepDelay(1, kMinimumStepDelay);

  int kOnlyLocalTcpPorts = PORTALLOCATOR_DISABLE_UDP |
                           PORTALLOCATOR_DISABLE_STUN |
                           PORTALLOCATOR_DISABLE_RELAY;
  // Disable all protocols except TCP.
  SetAllocatorFlags(0, kOnlyLocalTcpPorts);
  SetAllocatorFlags(1, kOnlyLocalTcpPorts);

  SetAllowTcpListen(0, true);   // actpass.
  SetAllowTcpListen(1, false);  // active.

  // We want SetRemoteIceParameters to be called as it normally would.
  // Otherwise we won't know what parameters to use for the expected
  // prflx TCP candidates.
  set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);

  // Pause candidate so we could verify the candidate properties.
  PauseCandidates(0);
  PauseCandidates(1);
  CreateChannels();

  // Verify tcp candidates.
  VerifySavedTcpCandidates(0, TCPTYPE_PASSIVE_STR);
  VerifySavedTcpCandidates(1, TCPTYPE_ACTIVE_STR);

  // Resume candidates.
  ResumeCandidates(0);
  ResumeCandidates(1);

  EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
                                 ep2_ch1()->receiving() &&
                                 ep2_ch1()->writable(),
                             kShortTimeout, clock);
  EXPECT_TRUE(ep1_ch1()->selected_connection() &&
              ep2_ch1()->selected_connection() &&
              LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
              RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));

  TestSendRecv(&clock);
  DestroyChannels();
}

TEST_F(P2PTransportChannelTest, TestIceRoleConflict) {
  AddAddress(0, kPublicAddrs[0]);
  AddAddress(1, kPublicAddrs[1]);
  TestSignalRoleConflict();
}

// Tests that the ice configs (protocol, tiebreaker and role) can be passed
// down to ports.
TEST_F(P2PTransportChannelTest, TestIceConfigWillPassDownToPort) {
  rtc::ScopedFakeClock clock;
  AddAddress(0, kPublicAddrs[0]);
  AddAddress(1, kPublicAddrs[1]);

  // Give the first connection the higher tiebreaker so its role won't
  // change unless we tell it to.
  SetIceRole(0, ICEROLE_CONTROLLING);
  SetIceTiebreaker(0, kHighTiebreaker);
  SetIceRole(1, ICEROLE_CONTROLLING);
  SetIceTiebreaker(1, kLowTiebreaker);

  CreateChannels();

  EXPECT_EQ_SIMULATED_WAIT(2u, ep1_ch1()->ports().size(), kShortTimeout, clock);

  const std::vector<PortInterface*> ports_before = ep1_ch1()->ports();
  for (size_t i = 0; i < ports_before.size(); ++i) {
    EXPECT_EQ(ICEROLE_CONTROLLING, ports_before[i]->GetIceRole());
    EXPECT_EQ(kHighTiebreaker, ports_before[i]->IceTiebreaker());
  }

  ep1_ch1()->SetIceRole(ICEROLE_CONTROLLED);
  ep1_ch1()->SetIceTiebreaker(kLowTiebreaker);

  const std::vector<PortInterface*> ports_after = ep1_ch1()->ports();
  for (size_t i = 0; i < ports_after.size(); ++i) {
    EXPECT_EQ(ICEROLE_CONTROLLED, ports_before[i]->GetIceRole());
    // SetIceTiebreaker after ports have been created will fail. So expect the
    // original value.
    EXPECT_EQ(kHighTiebreaker, ports_before[i]->IceTiebreaker());
  }

  EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
                                 ep2_ch1()->receiving() &&
                                 ep2_ch1()->writable(),
                             kShortTimeout, clock);

  EXPECT_TRUE(ep1_ch1()->selected_connection() &&
              ep2_ch1()->selected_connection());

  TestSendRecv(&clock);
  DestroyChannels();
}

// Verify that we can set DSCP value and retrieve properly from P2PTC.
TEST_F(P2PTransportChannelTest, TestDefaultDscpValue) {
  AddAddress(0, kPublicAddrs[0]);
  AddAddress(1, kPublicAddrs[1]);

  CreateChannels();
  EXPECT_EQ(rtc::DSCP_NO_CHANGE, GetEndpoint(0)->cd1_.ch_->DefaultDscpValue());
  EXPECT_EQ(rtc::DSCP_NO_CHANGE, GetEndpoint(1)->cd1_.ch_->DefaultDscpValue());
  GetEndpoint(0)->cd1_.ch_->SetOption(rtc::Socket::OPT_DSCP, rtc::DSCP_CS6);
  GetEndpoint(1)->cd1_.ch_->SetOption(rtc::Socket::OPT_DSCP, rtc::DSCP_CS6);
  EXPECT_EQ(rtc::DSCP_CS6, GetEndpoint(0)->cd1_.ch_->DefaultDscpValue());
  EXPECT_EQ(rtc::DSCP_CS6, GetEndpoint(1)->cd1_.ch_->DefaultDscpValue());
  GetEndpoint(0)->cd1_.ch_->SetOption(rtc::Socket::OPT_DSCP, rtc::DSCP_AF41);
  GetEndpoint(1)->cd1_.ch_->SetOption(rtc::Socket::OPT_DSCP, rtc::DSCP_AF41);
  EXPECT_EQ(rtc::DSCP_AF41, GetEndpoint(0)->cd1_.ch_->DefaultDscpValue());
  EXPECT_EQ(rtc::DSCP_AF41, GetEndpoint(1)->cd1_.ch_->DefaultDscpValue());
}

// Verify IPv6 connection is preferred over IPv4.
TEST_F(P2PTransportChannelTest, TestIPv6Connections) {
  rtc::ScopedFakeClock clock;
  AddAddress(0, kIPv6PublicAddrs[0]);
  AddAddress(0, kPublicAddrs[0]);
  AddAddress(1, kIPv6PublicAddrs[1]);
  AddAddress(1, kPublicAddrs[1]);

  SetAllocationStepDelay(0, kMinimumStepDelay);
  SetAllocationStepDelay(1, kMinimumStepDelay);

  // Enable IPv6
  SetAllocatorFlags(
      0, PORTALLOCATOR_ENABLE_IPV6 | PORTALLOCATOR_ENABLE_IPV6_ON_WIFI);
  SetAllocatorFlags(
      1, PORTALLOCATOR_ENABLE_IPV6 | PORTALLOCATOR_ENABLE_IPV6_ON_WIFI);

  CreateChannels();

  EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
                                 ep2_ch1()->receiving() &&
                                 ep2_ch1()->writable(),
                             kShortTimeout, clock);
  EXPECT_TRUE(
      ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection() &&
      LocalCandidate(ep1_ch1())->address().EqualIPs(kIPv6PublicAddrs[0]) &&
      RemoteCandidate(ep1_ch1())->address().EqualIPs(kIPv6PublicAddrs[1]));

  TestSendRecv(&clock);
  DestroyChannels();
}

// Testing forceful TURN connections.
TEST_F(P2PTransportChannelTest, TestForceTurn) {
  rtc::ScopedFakeClock clock;
  ConfigureEndpoints(
      NAT_PORT_RESTRICTED, NAT_SYMMETRIC,
      kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_SHARED_SOCKET,
      kDefaultPortAllocatorFlags | PORTALLOCATOR_ENABLE_SHARED_SOCKET);
  set_force_relay(true);

  SetAllocationStepDelay(0, kMinimumStepDelay);
  SetAllocationStepDelay(1, kMinimumStepDelay);

  CreateChannels();

  EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
                                 ep2_ch1()->receiving() &&
                                 ep2_ch1()->writable(),
                             kMediumTimeout, clock);

  EXPECT_TRUE(ep1_ch1()->selected_connection() &&
              ep2_ch1()->selected_connection());

  EXPECT_EQ(RELAY_PORT_TYPE, RemoteCandidate(ep1_ch1())->type());
  EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type());
  EXPECT_EQ(RELAY_PORT_TYPE, RemoteCandidate(ep2_ch1())->type());
  EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep2_ch1())->type());

  TestSendRecv(&clock);
  DestroyChannels();
}

// Test that if continual gathering is set to true, ICE gathering state will
// not change to "Complete", and vice versa.
TEST_F(P2PTransportChannelTest, TestContinualGathering) {
  rtc::ScopedFakeClock clock;
  ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
                     kDefaultPortAllocatorFlags);
  SetAllocationStepDelay(0, kDefaultStepDelay);
  SetAllocationStepDelay(1, kDefaultStepDelay);
  IceConfig continual_gathering_config =
      CreateIceConfig(1000, GATHER_CONTINUALLY);
  // By default, ep2 does not gather continually.
  IceConfig default_config;
  CreateChannels(continual_gathering_config, default_config);

  EXPECT_TRUE_SIMULATED_WAIT(
      ep1_ch1() != NULL && ep2_ch1() != NULL && ep1_ch1()->receiving() &&
          ep1_ch1()->writable() && ep2_ch1()->receiving() &&
          ep2_ch1()->writable(),
      kMediumTimeout, clock);
  SIMULATED_WAIT(
      IceGatheringState::kIceGatheringComplete == ep1_ch1()->gathering_state(),
      kShortTimeout, clock);
  EXPECT_EQ(IceGatheringState::kIceGatheringGathering,
            ep1_ch1()->gathering_state());
  // By now, ep2 should have completed gathering.
  EXPECT_EQ(IceGatheringState::kIceGatheringComplete,
            ep2_ch1()->gathering_state());

  DestroyChannels();
}

// Test that a connection succeeds when the P2PTransportChannel uses a pooled
// PortAllocatorSession that has not yet finished gathering candidates.
TEST_F(P2PTransportChannelTest, TestUsingPooledSessionBeforeDoneGathering) {
  rtc::ScopedFakeClock clock;
  ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
                     kDefaultPortAllocatorFlags);
  // First create a pooled session for each endpoint.
  auto& allocator_1 = GetEndpoint(0)->allocator_;
  auto& allocator_2 = GetEndpoint(1)->allocator_;
  int pool_size = 1;
  allocator_1->SetConfiguration(allocator_1->stun_servers(),
                                allocator_1->turn_servers(), pool_size, false);
  allocator_2->SetConfiguration(allocator_2->stun_servers(),
                                allocator_2->turn_servers(), pool_size, false);
  const PortAllocatorSession* pooled_session_1 =
      allocator_1->GetPooledSession();
  const PortAllocatorSession* pooled_session_2 =
      allocator_2->GetPooledSession();
  ASSERT_NE(nullptr, pooled_session_1);
  ASSERT_NE(nullptr, pooled_session_2);
  // Sanity check that pooled sessions haven't gathered anything yet.
  EXPECT_TRUE(pooled_session_1->ReadyPorts().empty());
  EXPECT_TRUE(pooled_session_1->ReadyCandidates().empty());
  EXPECT_TRUE(pooled_session_2->ReadyPorts().empty());
  EXPECT_TRUE(pooled_session_2->ReadyCandidates().empty());
  // Now let the endpoints connect and try exchanging some data.
  CreateChannels();
  EXPECT_TRUE_SIMULATED_WAIT(
      ep1_ch1() != NULL && ep2_ch1() != NULL && ep1_ch1()->receiving() &&
          ep1_ch1()->writable() && ep2_ch1()->receiving() &&
          ep2_ch1()->writable(),
      kMediumTimeout, clock);
  TestSendRecv(&clock);
  // Make sure the P2PTransportChannels are actually using ports from the
  // pooled sessions.
  auto pooled_ports_1 = pooled_session_1->ReadyPorts();
  auto pooled_ports_2 = pooled_session_2->ReadyPorts();
  EXPECT_NE(pooled_ports_1.end(),
            std::find(pooled_ports_1.begin(), pooled_ports_1.end(),
                      ep1_ch1()->selected_connection()->port()));
  EXPECT_NE(pooled_ports_2.end(),
            std::find(pooled_ports_2.begin(), pooled_ports_2.end(),
                      ep2_ch1()->selected_connection()->port()));
}

// Test that a connection succeeds when the P2PTransportChannel uses a pooled
// PortAllocatorSession that already finished gathering candidates.
TEST_F(P2PTransportChannelTest, TestUsingPooledSessionAfterDoneGathering) {
  rtc::ScopedFakeClock clock;
  ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
                     kDefaultPortAllocatorFlags);
  // First create a pooled session for each endpoint.
  auto& allocator_1 = GetEndpoint(0)->allocator_;
  auto& allocator_2 = GetEndpoint(1)->allocator_;
  int pool_size = 1;
  allocator_1->SetConfiguration(allocator_1->stun_servers(),
                                allocator_1->turn_servers(), pool_size, false);
  allocator_2->SetConfiguration(allocator_2->stun_servers(),
                                allocator_2->turn_servers(), pool_size, false);
  const PortAllocatorSession* pooled_session_1 =
      allocator_1->GetPooledSession();
  const PortAllocatorSession* pooled_session_2 =
      allocator_2->GetPooledSession();
  ASSERT_NE(nullptr, pooled_session_1);
  ASSERT_NE(nullptr, pooled_session_2);
  // Wait for the pooled sessions to finish gathering before the
  // P2PTransportChannels try to use them.
  EXPECT_TRUE_SIMULATED_WAIT(pooled_session_1->CandidatesAllocationDone() &&
                                 pooled_session_2->CandidatesAllocationDone(),
                             kDefaultTimeout, clock);
  // Now let the endpoints connect and try exchanging some data.
  CreateChannels();
  EXPECT_TRUE_SIMULATED_WAIT(
      ep1_ch1() != NULL && ep2_ch1() != NULL && ep1_ch1()->receiving() &&
          ep1_ch1()->writable() && ep2_ch1()->receiving() &&
          ep2_ch1()->writable(),
      kMediumTimeout, clock);
  TestSendRecv(&clock);
  // Make sure the P2PTransportChannels are actually using ports from the
  // pooled sessions.
  auto pooled_ports_1 = pooled_session_1->ReadyPorts();
  auto pooled_ports_2 = pooled_session_2->ReadyPorts();
  EXPECT_NE(pooled_ports_1.end(),
            std::find(pooled_ports_1.begin(), pooled_ports_1.end(),
                      ep1_ch1()->selected_connection()->port()));
  EXPECT_NE(pooled_ports_2.end(),
            std::find(pooled_ports_2.begin(), pooled_ports_2.end(),
                      ep2_ch1()->selected_connection()->port()));
}

// Test that when the "presume_writable_when_fully_relayed" flag is set to
// true and there's a TURN-TURN candidate pair, it's presumed to be writable
// as soon as it's created.
// TODO(deadbeef): Move this and other "presumed writable" tests into a test
// class that operates on a single P2PTransportChannel, once an appropriate one
// (which supports TURN servers and TURN candidate gathering) is available.
TEST_F(P2PTransportChannelTest, TurnToTurnPresumedWritable) {
  ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
                     kDefaultPortAllocatorFlags);
  // Only configure one channel so we can control when the remote candidate
  // is added.
  GetEndpoint(0)->cd1_.ch_.reset(CreateChannel(
      0, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[0], kIceParams[1]));
  IceConfig config;
  config.presume_writable_when_fully_relayed = true;
  ep1_ch1()->SetIceConfig(config);
  ep1_ch1()->MaybeStartGathering();
  EXPECT_EQ_WAIT(IceGatheringState::kIceGatheringComplete,
                 ep1_ch1()->gathering_state(), kDefaultTimeout);
  // Add two remote candidates; a host candidate (with higher priority)
  // and TURN candidate.
  ep1_ch1()->AddRemoteCandidate(
      CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
  ep1_ch1()->AddRemoteCandidate(
      CreateUdpCandidate(RELAY_PORT_TYPE, "2.2.2.2", 2, 0));
  // Expect that the TURN-TURN candidate pair will be prioritized since it's
  // "probably writable".
  EXPECT_TRUE(ep1_ch1()->selected_connection() != nullptr);
  EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type());
  EXPECT_EQ(RELAY_PORT_TYPE, RemoteCandidate(ep1_ch1())->type());
  // Also expect that the channel instantly indicates that it's writable since
  // it has a TURN-TURN pair.
  EXPECT_TRUE(ep1_ch1()->writable());
  EXPECT_TRUE(GetEndpoint(0)->ready_to_send_);
  // Also make sure we can immediately send packets.
  const char* data = "test";
  int len = static_cast<int>(strlen(data));
  EXPECT_EQ(len, SendData(ep1_ch1(), data, len));
}

// Test that a TURN/peer reflexive candidate pair is also presumed writable.
TEST_F(P2PTransportChannelTest, TurnToPrflxPresumedWritable) {
  rtc::ScopedFakeClock fake_clock;

  // We need to add artificial network delay to verify that the connection
  // is presumed writable before it's actually writable. Without this delay
  // it would become writable instantly.
  virtual_socket_server()->set_delay_mean(50);
  virtual_socket_server()->UpdateDelayDistribution();

  ConfigureEndpoints(NAT_SYMMETRIC, NAT_SYMMETRIC, kDefaultPortAllocatorFlags,
                     kDefaultPortAllocatorFlags);
  // We want the remote TURN candidate to show up as prflx. To do this we need
  // to configure the server to accept packets from an address we haven't
  // explicitly installed permission for.
  test_turn_server()->set_enable_permission_checks(false);
  IceConfig config;
  config.presume_writable_when_fully_relayed = true;
  GetEndpoint(0)->cd1_.ch_.reset(CreateChannel(
      0, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[0], kIceParams[1]));
  GetEndpoint(1)->cd1_.ch_.reset(CreateChannel(
      1, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[1], kIceParams[0]));
  ep1_ch1()->SetIceConfig(config);
  ep2_ch1()->SetIceConfig(config);
  // Don't signal candidates from channel 2, so that channel 1 sees the TURN
  // candidate as peer reflexive.
  PauseCandidates(1);
  ep1_ch1()->MaybeStartGathering();
  ep2_ch1()->MaybeStartGathering();

  // Wait for the TURN<->prflx connection.
  EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable(),
                             kShortTimeout, fake_clock);
  ASSERT_NE(nullptr, ep1_ch1()->selected_connection());
  EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type());
  EXPECT_EQ(PRFLX_PORT_TYPE, RemoteCandidate(ep1_ch1())->type());
  // Make sure that at this point the connection is only presumed writable,
  // not fully writable.
  EXPECT_FALSE(ep1_ch1()->selected_connection()->writable());

  // Now wait for it to actually become writable.
  EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection()->writable(),
                             kShortTimeout, fake_clock);

  // Explitly destroy channels, before fake clock is destroyed.
  DestroyChannels();
}

// Test that a presumed-writable TURN<->TURN connection is preferred above an
// unreliable connection (one that has failed to be pinged for some time).
TEST_F(P2PTransportChannelTest, PresumedWritablePreferredOverUnreliable) {
  rtc::ScopedFakeClock fake_clock;

  ConfigureEndpoints(NAT_SYMMETRIC, NAT_SYMMETRIC, kDefaultPortAllocatorFlags,
                     kDefaultPortAllocatorFlags);
  IceConfig config;
  config.presume_writable_when_fully_relayed = true;
  GetEndpoint(0)->cd1_.ch_.reset(CreateChannel(
      0, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[0], kIceParams[1]));
  GetEndpoint(1)->cd1_.ch_.reset(CreateChannel(
      1, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[1], kIceParams[0]));
  ep1_ch1()->SetIceConfig(config);
  ep2_ch1()->SetIceConfig(config);
  ep1_ch1()->MaybeStartGathering();
  ep2_ch1()->MaybeStartGathering();
  // Wait for initial connection as usual.
  EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
                                 ep1_ch1()->selected_connection()->writable() &&
                                 ep2_ch1()->receiving() &&
                                 ep2_ch1()->writable() &&
                                 ep2_ch1()->selected_connection()->writable(),
                             kShortTimeout, fake_clock);
  const Connection* old_selected_connection = ep1_ch1()->selected_connection();
  // Destroy the second channel and wait for the current connection on the
  // first channel to become "unreliable", making it no longer writable.
  GetEndpoint(1)->cd1_.ch_.reset();
  EXPECT_TRUE_SIMULATED_WAIT(!ep1_ch1()->writable(), kDefaultTimeout,
                             fake_clock);
  EXPECT_NE(nullptr, ep1_ch1()->selected_connection());
  // Add a remote TURN candidate. The first channel should still have a TURN
  // port available to make a TURN<->TURN pair that's presumed writable.
  ep1_ch1()->AddRemoteCandidate(
      CreateUdpCandidate(RELAY_PORT_TYPE, "2.2.2.2", 2, 0));
  EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type());
  EXPECT_EQ(RELAY_PORT_TYPE, RemoteCandidate(ep1_ch1())->type());
  EXPECT_TRUE(ep1_ch1()->writable());
  EXPECT_TRUE(GetEndpoint(0)->ready_to_send_);
  EXPECT_NE(old_selected_connection, ep1_ch1()->selected_connection());
  // Explitly destroy channels, before fake clock is destroyed.
  DestroyChannels();
}

// Ensure that "SignalReadyToSend" is fired as expected with a "presumed
// writable" connection. Previously this did not work.
TEST_F(P2PTransportChannelTest, SignalReadyToSendWithPresumedWritable) {
  ConfigureEndpoints(OPEN, OPEN, kDefaultPortAllocatorFlags,
                     kDefaultPortAllocatorFlags);
  // Only test one endpoint, so we can ensure the connection doesn't receive a
  // binding response and advance beyond being "presumed" writable.
  GetEndpoint(0)->cd1_.ch_.reset(CreateChannel(
      0, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[0], kIceParams[1]));
  IceConfig config;
  config.presume_writable_when_fully_relayed = true;
  ep1_ch1()->SetIceConfig(config);
  ep1_ch1()->MaybeStartGathering();
  EXPECT_EQ_WAIT(IceGatheringState::kIceGatheringComplete,
                 ep1_ch1()->gathering_state(), kDefaultTimeout);
  ep1_ch1()->AddRemoteCandidate(
      CreateUdpCandidate(RELAY_PORT_TYPE, "1.1.1.1", 1, 0));
  // Sanity checking the type of the connection.
  EXPECT_TRUE(ep1_ch1()->selected_connection() != nullptr);
  EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type());
  EXPECT_EQ(RELAY_PORT_TYPE, RemoteCandidate(ep1_ch1())->type());

  // Tell the socket server to block packets (returning EWOULDBLOCK).
  virtual_socket_server()->SetSendingBlocked(true);
  const char* data = "test";
  int len = static_cast<int>(strlen(data));
  EXPECT_EQ(-1, SendData(ep1_ch1(), data, len));

  // Reset |ready_to_send_| flag, which is set to true if the event fires as it
  // should.
  GetEndpoint(0)->ready_to_send_ = false;
  virtual_socket_server()->SetSendingBlocked(false);
  EXPECT_TRUE(GetEndpoint(0)->ready_to_send_);
  EXPECT_EQ(len, SendData(ep1_ch1(), data, len));
}

// Test that role conflict error responses are sent as expected when receiving a
// ping from an unknown address over a TURN connection. Regression test for
// crbug.com/webrtc/9034.
TEST_F(P2PTransportChannelTest,
       TurnToPrflxSelectedAfterResolvingIceControllingRoleConflict) {
  rtc::ScopedFakeClock clock;
  // Gather only relay candidates.
  ConfigureEndpoints(NAT_SYMMETRIC, NAT_SYMMETRIC,
                     kDefaultPortAllocatorFlags | PORTALLOCATOR_DISABLE_UDP |
                         PORTALLOCATOR_DISABLE_STUN | PORTALLOCATOR_DISABLE_TCP,
                     kDefaultPortAllocatorFlags | PORTALLOCATOR_DISABLE_UDP |
                         PORTALLOCATOR_DISABLE_STUN |
                         PORTALLOCATOR_DISABLE_TCP);
  // With conflicting ICE roles, endpoint 1 has the higher tie breaker and will
  // send a binding error response.
  SetIceRole(0, ICEROLE_CONTROLLING);
  SetIceTiebreaker(0, kHighTiebreaker);
  SetIceRole(1, ICEROLE_CONTROLLING);
  SetIceTiebreaker(1, kLowTiebreaker);
  // We want the remote TURN candidate to show up as prflx. To do this we need
  // to configure the server to accept packets from an address we haven't
  // explicitly installed permission for.
  test_turn_server()->set_enable_permission_checks(false);
  GetEndpoint(0)->cd1_.ch_.reset(CreateChannel(
      0, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[0], kIceParams[1]));
  GetEndpoint(1)->cd1_.ch_.reset(CreateChannel(
      1, ICE_CANDIDATE_COMPONENT_DEFAULT, kIceParams[1], kIceParams[0]));
  // Don't signal candidates from channel 2, so that channel 1 sees the TURN
  // candidate as peer reflexive.
  PauseCandidates(1);
  ep1_ch1()->MaybeStartGathering();
  ep2_ch1()->MaybeStartGathering();

  EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable(),
                             kMediumTimeout, clock);

  ASSERT_NE(nullptr, ep1_ch1()->selected_connection());

  EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type());
  EXPECT_EQ(PRFLX_PORT_TYPE, RemoteCandidate(ep1_ch1())->type());

  DestroyChannels();
}

// Test what happens when we have 2 users behind the same NAT. This can lead
// to interesting behavior because the STUN server will only give out the
// address of the outermost NAT.
class P2PTransportChannelSameNatTest : public P2PTransportChannelTestBase {
 protected:
  void ConfigureEndpoints(Config nat_type, Config config1, Config config2) {
    RTC_CHECK_GE(nat_type, NAT_FULL_CONE);
    RTC_CHECK_LE(nat_type, NAT_SYMMETRIC);
    rtc::NATSocketServer::Translator* outer_nat = nat()->AddTranslator(
        kPublicAddrs[0], kNatAddrs[0],
        static_cast<rtc::NATType>(nat_type - NAT_FULL_CONE));
    ConfigureEndpoint(outer_nat, 0, config1);
    ConfigureEndpoint(outer_nat, 1, config2);
    set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
  }
  void ConfigureEndpoint(rtc::NATSocketServer::Translator* nat,
                         int endpoint,
                         Config config) {
    RTC_CHECK(config <= NAT_SYMMETRIC);
    if (config == OPEN) {
      AddAddress(endpoint, kPrivateAddrs[endpoint]);
      nat->AddClient(kPrivateAddrs[endpoint]);
    } else {
      AddAddress(endpoint, kCascadedPrivateAddrs[endpoint]);
      nat->AddTranslator(kPrivateAddrs[endpoint], kCascadedNatAddrs[endpoint],
                         static_cast<rtc::NATType>(config - NAT_FULL_CONE))
          ->AddClient(kCascadedPrivateAddrs[endpoint]);
    }
  }
};

TEST_F(P2PTransportChannelSameNatTest, TestConesBehindSameCone) {
  ConfigureEndpoints(NAT_FULL_CONE, NAT_FULL_CONE, NAT_FULL_CONE);
  Test(
      P2PTransportChannelTestBase::Result("prflx", "udp", "stun", "udp", 1000));
}

// Test what happens when we have multiple available pathways.
// In the future we will try different RTTs and configs for the different
// interfaces, so that we can simulate a user with Ethernet and VPN networks.
class P2PTransportChannelMultihomedTest : public P2PTransportChannelTestBase {
 public:
  const Connection* GetConnectionWithRemoteAddress(
      P2PTransportChannel* channel,
      const SocketAddress& address) {
    for (Connection* conn : channel->connections()) {
      if (conn->remote_candidate().address().EqualIPs(address)) {
        return conn;
      }
    }
    return nullptr;
  }

  Connection* GetConnectionWithLocalAddress(P2PTransportChannel* channel,
                                            const SocketAddress& address) {
    for (Connection* conn : channel->connections()) {
      if (conn->local_candidate().address().EqualIPs(address)) {
        return conn;
      }
    }
    return nullptr;
  }

  Connection* GetConnection(P2PTransportChannel* channel,
                            const SocketAddress& local,
                            const SocketAddress& remote) {
    for (Connection* conn : channel->connections()) {
      if (conn->local_candidate().address().EqualIPs(local) &&
          conn->remote_candidate().address().EqualIPs(remote)) {
        return conn;
      }
    }
    return nullptr;
  }

  void DestroyAllButBestConnection(P2PTransportChannel* channel) {
    const Connection* selected_connection = channel->selected_connection();
    for (Connection* conn : channel->connections()) {
      if (conn != selected_connection) {
        conn->Destroy();
      }
    }
  }
};

// Test that we can establish connectivity when both peers are multihomed.
TEST_F(P2PTransportChannelMultihomedTest, TestBasic) {
  AddAddress(0, kPublicAddrs[0]);
  AddAddress(0, kAlternateAddrs[0]);
  AddAddress(1, kPublicAddrs[1]);
  AddAddress(1, kAlternateAddrs[1]);
  Test(kLocalUdpToLocalUdp);
}

// Test that we can quickly switch links if an interface goes down.
// The controlled side has two interfaces and one will die.
TEST_F(P2PTransportChannelMultihomedTest, TestFailoverControlledSide) {
  rtc::ScopedFakeClock clock;
  AddAddress(0, kPublicAddrs[0]);
  // Simulate failing over from Wi-Fi to cell interface.
  AddAddress(1, kPublicAddrs[1], "eth0", rtc::ADAPTER_TYPE_WIFI);
  AddAddress(1, kAlternateAddrs[1], "wlan0", rtc::ADAPTER_TYPE_CELLULAR);

  // Use only local ports for simplicity.
  SetAllocatorFlags(0, kOnlyLocalPorts);
  SetAllocatorFlags(1, kOnlyLocalPorts);

  // Make the receiving timeout shorter for testing.
  IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
  // Create channels and let them go writable, as usual.
  CreateChannels(config, config);

  EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
                                 ep2_ch1()->receiving() &&
                                 ep2_ch1()->writable(),
                             kMediumTimeout, clock);
  EXPECT_TRUE(ep1_ch1()->selected_connection() &&
              ep2_ch1()->selected_connection() &&
              LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
              RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));

  // Blackhole any traffic to or from the public addrs.
  RTC_LOG(LS_INFO) << "Failing over...";
  fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[1]);
  // The selected connections may switch, so keep references to them.
  const Connection* selected_connection1 = ep1_ch1()->selected_connection();
  const Connection* selected_connection2 = ep2_ch1()->selected_connection();
  // We should detect loss of receiving within 1 second or so.
  EXPECT_TRUE_SIMULATED_WAIT(
      !selected_connection1->receiving() && !selected_connection2->receiving(),
      kMediumTimeout, clock);

  // We should switch over to use the alternate addr on both sides
  // when we are not receiving.
  EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection()->receiving() &&
                                 ep2_ch1()->selected_connection()->receiving(),
                             kMediumTimeout, clock);
  EXPECT_TRUE(LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]));
  EXPECT_TRUE(
      RemoteCandidate(ep1_ch1())->address().EqualIPs(kAlternateAddrs[1]));
  EXPECT_TRUE(
      LocalCandidate(ep2_ch1())->address().EqualIPs(kAlternateAddrs[1]));

  DestroyChannels();
}

// Test that we can quickly switch links if an interface goes down.
// The controlling side has two interfaces and one will die.
TEST_F(P2PTransportChannelMultihomedTest, TestFailoverControllingSide) {
  rtc::ScopedFakeClock clock;
  // Simulate failing over from Wi-Fi to cell interface.
  AddAddress(0, kPublicAddrs[0], "eth0", rtc::ADAPTER_TYPE_WIFI);
  AddAddress(0, kAlternateAddrs[0], "wlan0", rtc::ADAPTER_TYPE_CELLULAR);
  AddAddress(1, kPublicAddrs[1]);

  // Use only local ports for simplicity.
  SetAllocatorFlags(0, kOnlyLocalPorts);
  SetAllocatorFlags(1, kOnlyLocalPorts);

  // Make the receiving timeout shorter for testing.
  IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
  // Create channels and let them go writable, as usual.
  CreateChannels(config, config);
  EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
                                 ep2_ch1()->receiving() &&
                                 ep2_ch1()->writable(),
                             kMediumTimeout, clock);
  EXPECT_TRUE(ep1_ch1()->selected_connection() &&
              ep2_ch1()->selected_connection() &&
              LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
              RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));

  // Blackhole any traffic to or from the public addrs.
  RTC_LOG(LS_INFO) << "Failing over...";
  fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
  // The selected connections will switch, so keep references to them.
  const Connection* selected_connection1 = ep1_ch1()->selected_connection();
  const Connection* selected_connection2 = ep2_ch1()->selected_connection();
  // We should detect loss of receiving within 1 second or so.
  EXPECT_TRUE_SIMULATED_WAIT(
      !selected_connection1->receiving() && !selected_connection2->receiving(),
      kMediumTimeout, clock);

  // We should switch over to use the alternate addr on both sides
  // when we are not receiving.
  EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection()->receiving() &&
                                 ep2_ch1()->selected_connection()->receiving(),
                             kMediumTimeout, clock);
  EXPECT_TRUE(
      LocalCandidate(ep1_ch1())->address().EqualIPs(kAlternateAddrs[0]));
  EXPECT_TRUE(RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
  EXPECT_TRUE(
      RemoteCandidate(ep2_ch1())->address().EqualIPs(kAlternateAddrs[0]));

  DestroyChannels();
}

// Tests that we can quickly switch links if an interface goes down when
// there are many connections.
TEST_F(P2PTransportChannelMultihomedTest, TestFailoverWithManyConnections) {
  rtc::ScopedFakeClock clock;
  test_turn_server()->AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
  RelayServerConfig turn_server(RELAY_TURN);
  turn_server.credentials = kRelayCredentials;
  turn_server.ports.push_back(ProtocolAddress(kTurnTcpIntAddr, PROTO_TCP));
  GetAllocator(0)->AddTurnServer(turn_server);
  GetAllocator(1)->AddTurnServer(turn_server);
  // Enable IPv6
  SetAllocatorFlags(
      0, PORTALLOCATOR_ENABLE_IPV6 | PORTALLOCATOR_ENABLE_IPV6_ON_WIFI);
  SetAllocatorFlags(
      1, PORTALLOCATOR_ENABLE_IPV6 | PORTALLOCATOR_ENABLE_IPV6_ON_WIFI);
  SetAllocationStepDelay(0, kMinimumStepDelay);
  SetAllocationStepDelay(1, kMinimumStepDelay);

  auto& wifi = kPublicAddrs;
  auto& cellular = kAlternateAddrs;
  auto& wifiIpv6 = kIPv6PublicAddrs;
  auto& cellularIpv6 = kIPv6AlternateAddrs;
  AddAddress(0, wifi[0], "wifi0", rtc::ADAPTER_TYPE_WIFI);
  AddAddress(0, wifiIpv6[0], "wifi0", rtc::ADAPTER_TYPE_WIFI);
  AddAddress(0, cellular[0], "cellular0", rtc::ADAPTER_TYPE_CELLULAR);
  AddAddress(0, cellularIpv6[0], "cellular0", rtc::ADAPTER_TYPE_CELLULAR);
  AddAddress(1, wifi[1], "wifi1", rtc::ADAPTER_TYPE_WIFI);
  AddAddress(1, wifiIpv6[1], "wifi1", rtc::ADAPTER_TYPE_WIFI);
  AddAddress(1, cellular[1], "cellular1", rtc::ADAPTER_TYPE_CELLULAR);
  AddAddress(1, cellularIpv6[1], "cellular1", rtc::ADAPTER_TYPE_CELLULAR);

  // Set smaller delay on the TCP TURN server so that TCP TURN candidates
  // will be created in time.
  virtual_socket_server()->SetDelayOnAddress(kTurnTcpIntAddr, 1);
  virtual_socket_server()->SetDelayOnAddress(kTurnUdpExtAddr, 1);
  virtual_socket_server()->set_delay_mean(500);
  virtual_socket_server()->UpdateDelayDistribution();

  // Make the receiving timeout shorter for testing.
  IceConfig config = CreateIceConfig(1000, GATHER_CONTINUALLY);
  // Create channels and let them go writable, as usual.
  CreateChannels(config, config, true /* ice_renomination */);
  EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
                                 ep2_ch1()->receiving() &&
                                 ep2_ch1()->writable(),
                             kMediumTimeout, clock);
  EXPECT_TRUE_SIMULATED_WAIT(
      ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection() &&
          LocalCandidate(ep1_ch1())->address().EqualIPs(wifiIpv6[0]) &&
          RemoteCandidate(ep1_ch1())->address().EqualIPs(wifiIpv6[1]),
      kMediumTimeout, clock);

  // Blackhole any traffic to or from the wifi on endpoint 1.
  RTC_LOG(LS_INFO) << "Failing over...";
  fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, wifi[0]);
  fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, wifiIpv6[0]);

  // The selected connections may switch, so keep references to them.
  const Connection* selected_connection1 = ep1_ch1()->selected_connection();
  const Connection* selected_connection2 = ep2_ch1()->selected_connection();
  EXPECT_TRUE_SIMULATED_WAIT(
      !selected_connection1->receiving() && !selected_connection2->receiving(),
      kMediumTimeout, clock);

  // Per-network best connections will be pinged at relatively higher rate when
  // the selected connection becomes not receiving.
  Connection* per_network_best_connection1 =
      GetConnection(ep1_ch1(), cellularIpv6[0], wifiIpv6[1]);
  ASSERT_NE(nullptr, per_network_best_connection1);
  int64_t last_ping_sent1 = per_network_best_connection1->last_ping_sent();
  int num_pings_sent1 = per_network_best_connection1->num_pings_sent();
  EXPECT_TRUE_SIMULATED_WAIT(
      num_pings_sent1 < per_network_best_connection1->num_pings_sent(),
      kMediumTimeout, clock);
  int64_t ping_interval1 =
      (per_network_best_connection1->last_ping_sent() - last_ping_sent1) /
      (per_network_best_connection1->num_pings_sent() - num_pings_sent1);
  constexpr int SCHEDULING_DELAY = 200;
  EXPECT_LT(
      ping_interval1,
      WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL + SCHEDULING_DELAY);

  // It should switch over to use the cellular IPv6 addr on endpoint 1 before
  // it timed out on writing.
  EXPECT_TRUE_SIMULATED_WAIT(
      ep1_ch1()->selected_connection()->receiving() &&
          ep2_ch1()->selected_connection()->receiving() &&
          RemoteCandidate(ep2_ch1())->address().EqualIPs(cellularIpv6[0]) &&
          LocalCandidate(ep1_ch1())->address().EqualIPs(cellularIpv6[0]),
      kMediumTimeout, clock);

  DestroyChannels();
}

// Test that when the controlling side switches the selected connection,
// the nomination of the selected connection on the controlled side will
// increase.
TEST_F(P2PTransportChannelMultihomedTest, TestIceRenomination) {
  rtc::ScopedFakeClock clock;
  // Simulate failing over from Wi-Fi to cell interface.
  AddAddress(0, kPublicAddrs[0], "eth0", rtc::ADAPTER_TYPE_WIFI);
  AddAddress(0, kAlternateAddrs[0], "wlan0", rtc::ADAPTER_TYPE_CELLULAR);
  AddAddress(1, kPublicAddrs[1]);

  // Use only local ports for simplicity.
  SetAllocatorFlags(0, kOnlyLocalPorts);
  SetAllocatorFlags(1, kOnlyLocalPorts);

  // We want it to set the remote ICE parameters when creating channels.
  set_remote_ice_parameter_source(FROM_SETICEPARAMETERS);
  // Make the receiving timeout shorter for testing.
  IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
  // Create channels with ICE renomination and let them go writable as usual.
  CreateChannels(config, config, true);
  EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
                                 ep2_ch1()->receiving() &&
                                 ep2_ch1()->writable(),
                             kMediumTimeout, clock);
  EXPECT_TRUE_SIMULATED_WAIT(
      ep2_ch1()->selected_connection()->remote_nomination() > 0 &&
          ep1_ch1()->selected_connection()->acked_nomination() > 0,
      kDefaultTimeout, clock);
  const Connection* selected_connection1 = ep1_ch1()->selected_connection();
  Connection* selected_connection2 =
      const_cast<Connection*>(ep2_ch1()->selected_connection());
  uint32_t remote_nomination2 = selected_connection2->remote_nomination();
  // |selected_connection2| should not be nominated any more since the previous
  // nomination has been acknowledged.
  ConnectSignalNominated(selected_connection2);
  SIMULATED_WAIT(nominated(), kMediumTimeout, clock);
  EXPECT_FALSE(nominated());

  // Blackhole any traffic to or from the public addrs.
  RTC_LOG(LS_INFO) << "Failing over...";
  fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);

  // The selected connection on the controlling side should switch.
  EXPECT_TRUE_SIMULATED_WAIT(
      ep1_ch1()->selected_connection() != selected_connection1, kMediumTimeout,
      clock);
  // The connection on the controlled side should be nominated again
  // and have an increased nomination.
  EXPECT_TRUE_SIMULATED_WAIT(
      ep2_ch1()->selected_connection()->remote_nomination() >
          remote_nomination2,
      kDefaultTimeout, clock);

  DestroyChannels();
}

// Test that if an interface fails temporarily and then recovers quickly,
// the selected connection will not switch.
// The case that it will switch over to the backup connection if the selected
// connection does not recover after enough time is covered in
// TestFailoverControlledSide and TestFailoverControllingSide.
TEST_F(P2PTransportChannelMultihomedTest,
       TestConnectionSwitchDampeningControlledSide) {
  rtc::ScopedFakeClock clock;
  AddAddress(0, kPublicAddrs[0]);
  // Simulate failing over from Wi-Fi to cell interface.
  AddAddress(1, kPublicAddrs[1], "eth0", rtc::ADAPTER_TYPE_WIFI);
  AddAddress(1, kAlternateAddrs[1], "wlan0", rtc::ADAPTER_TYPE_CELLULAR);

  // Use only local ports for simplicity.
  SetAllocatorFlags(0, kOnlyLocalPorts);
  SetAllocatorFlags(1, kOnlyLocalPorts);

  // Create channels and let them go writable, as usual.
  CreateChannels();

  EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
                                 ep2_ch1()->receiving() &&
                                 ep2_ch1()->writable(),
                             kMediumTimeout, clock);
  EXPECT_TRUE(ep1_ch1()->selected_connection() &&
              ep2_ch1()->selected_connection() &&
              LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
              RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));

  // Make the receiving timeout shorter for testing.
  IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
  ep1_ch1()->SetIceConfig(config);
  ep2_ch1()->SetIceConfig(config);
  reset_selected_candidate_pair_switches();

  // Blackhole any traffic to or from the public addrs.
  RTC_LOG(LS_INFO) << "Failing over...";
  fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[1]);

  // The selected connections may switch, so keep references to them.
  const Connection* selected_connection1 = ep1_ch1()->selected_connection();
  const Connection* selected_connection2 = ep2_ch1()->selected_connection();
  // We should detect loss of receiving within 1 second or so.
  EXPECT_TRUE_SIMULATED_WAIT(
      !selected_connection1->receiving() && !selected_connection2->receiving(),
      kMediumTimeout, clock);
  // After a short while, the link recovers itself.
  SIMULATED_WAIT(false, 10, clock);
  fw()->ClearRules();

  // We should remain on the public address on both sides and no connection
  // switches should have happened.
  EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection()->receiving() &&
                                 ep2_ch1()->selected_connection()->receiving(),
                             kMediumTimeout, clock);
  EXPECT_TRUE(RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
  EXPECT_TRUE(LocalCandidate(ep2_ch1())->address().EqualIPs(kPublicAddrs[1]));
  EXPECT_EQ(0, reset_selected_candidate_pair_switches());

  DestroyChannels();
}

// Test that if an interface fails temporarily and then recovers quickly,
// the selected connection will not switch.
TEST_F(P2PTransportChannelMultihomedTest,
       TestConnectionSwitchDampeningControllingSide) {
  rtc::ScopedFakeClock clock;
  // Simulate failing over from Wi-Fi to cell interface.
  AddAddress(0, kPublicAddrs[0], "eth0", rtc::ADAPTER_TYPE_WIFI);
  AddAddress(0, kAlternateAddrs[0], "wlan0", rtc::ADAPTER_TYPE_CELLULAR);
  AddAddress(1, kPublicAddrs[1]);

  // Use only local ports for simplicity.
  SetAllocatorFlags(0, kOnlyLocalPorts);
  SetAllocatorFlags(1, kOnlyLocalPorts);

  // Create channels and let them go writable, as usual.
  CreateChannels();
  EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
                                 ep2_ch1()->receiving() &&
                                 ep2_ch1()->writable(),
                             kMediumTimeout, clock);
  EXPECT_TRUE(ep1_ch1()->selected_connection() &&
              ep2_ch1()->selected_connection() &&
              LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
              RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));

  // Make the receiving timeout shorter for testing.
  IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
  ep1_ch1()->SetIceConfig(config);
  ep2_ch1()->SetIceConfig(config);
  reset_selected_candidate_pair_switches();

  // Blackhole any traffic to or from the public addrs.
  RTC_LOG(LS_INFO) << "Failing over...";
  fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
  // The selected connections may switch, so keep references to them.
  const Connection* selected_connection1 = ep1_ch1()->selected_connection();
  const Connection* selected_connection2 = ep2_ch1()->selected_connection();
  // We should detect loss of receiving within 1 second or so.
  EXPECT_TRUE_SIMULATED_WAIT(
      !selected_connection1->receiving() && !selected_connection2->receiving(),
      kMediumTimeout, clock);
  // The link recovers after a short while.
  SIMULATED_WAIT(false, 10, clock);
  fw()->ClearRules();

  // We should not switch to the alternate addr on both sides because of the
  // dampening.
  EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection()->receiving() &&
                                 ep2_ch1()->selected_connection()->receiving(),
                             kMediumTimeout, clock);
  EXPECT_TRUE(LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]));
  EXPECT_TRUE(RemoteCandidate(ep2_ch1())->address().EqualIPs(kPublicAddrs[0]));
  EXPECT_EQ(0, reset_selected_candidate_pair_switches());
  DestroyChannels();
}

// Tests that if the remote side's network failed, it won't cause the local
// side to switch connections and networks.
TEST_F(P2PTransportChannelMultihomedTest, TestRemoteFailover) {
  rtc::ScopedFakeClock clock;
  // The interface names are chosen so that |cellular| would have higher
  // candidate priority and higher cost.
  auto& wifi = kPublicAddrs;
  auto& cellular = kAlternateAddrs;
  AddAddress(0, wifi[0], "wifi0", rtc::ADAPTER_TYPE_WIFI);
  AddAddress(0, cellular[0], "cellular0", rtc::ADAPTER_TYPE_CELLULAR);
  AddAddress(1, wifi[1], "wifi0", rtc::ADAPTER_TYPE_WIFI);

  // Use only local ports for simplicity.
  SetAllocatorFlags(0, kOnlyLocalPorts);
  SetAllocatorFlags(1, kOnlyLocalPorts);
  // Create channels and let them go writable, as usual.
  CreateChannels();
  // Make the receiving timeout shorter for testing.
  // Set the backup connection ping interval to 25s.
  IceConfig config = CreateIceConfig(1000, GATHER_ONCE, 25000);
  // Ping the best connection more frequently since we don't have traffic.
  config.stable_writable_connection_ping_interval = 900;
  ep1_ch1()->SetIceConfig(config);
  ep2_ch1()->SetIceConfig(config);
  // Need to wait to make sure the connections on both networks are writable.
  EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
                                 ep2_ch1()->receiving() &&
                                 ep2_ch1()->writable(),
                             kMediumTimeout, clock);
  EXPECT_TRUE_SIMULATED_WAIT(
      ep1_ch1()->selected_connection() &&
          LocalCandidate(ep1_ch1())->address().EqualIPs(wifi[0]) &&
          RemoteCandidate(ep1_ch1())->address().EqualIPs(wifi[1]),
      kDefaultTimeout, clock);
  Connection* backup_conn =
      GetConnectionWithLocalAddress(ep1_ch1(), cellular[0]);
  ASSERT_NE(nullptr, backup_conn);
  // After a short while, the backup connection will be writable but not
  // receiving because backup connection is pinged at a slower rate.
  EXPECT_TRUE_SIMULATED_WAIT(
      backup_conn->writable() && !backup_conn->receiving(), kDefaultTimeout,
      clock);
  reset_selected_candidate_pair_switches();
  // Blackhole any traffic to or from the remote WiFi networks.
  RTC_LOG(LS_INFO) << "Failing over...";
  fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, wifi[1]);

  int num_switches = 0;
  SIMULATED_WAIT((num_switches = reset_selected_candidate_pair_switches()) > 0,
                 20000, clock);
  EXPECT_EQ(0, num_switches);
  DestroyChannels();
}

// Tests that a Wifi-Wifi connection has the highest precedence.
TEST_F(P2PTransportChannelMultihomedTest, TestPreferWifiToWifiConnection) {
  // The interface names are chosen so that |cellular| would have higher
  // candidate priority if it is not for the network type.
  auto& wifi = kAlternateAddrs;
  auto& cellular = kPublicAddrs;
  AddAddress(0, wifi[0], "test0", rtc::ADAPTER_TYPE_WIFI);
  AddAddress(0, cellular[0], "test1", rtc::ADAPTER_TYPE_CELLULAR);
  AddAddress(1, wifi[1], "test0", rtc::ADAPTER_TYPE_WIFI);
  AddAddress(1, cellular[1], "test1", rtc::ADAPTER_TYPE_CELLULAR);

  // Use only local ports for simplicity.
  SetAllocatorFlags(0, kOnlyLocalPorts);
  SetAllocatorFlags(1, kOnlyLocalPorts);

  // Create channels and let them go writable, as usual.
  CreateChannels();

  EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
                              ep2_ch1()->receiving() && ep2_ch1()->writable(),
                          1000, 1000);
  // Need to wait to make sure the connections on both networks are writable.
  EXPECT_TRUE_WAIT(ep1_ch1()->selected_connection() &&
                       LocalCandidate(ep1_ch1())->address().EqualIPs(wifi[0]) &&
                       RemoteCandidate(ep1_ch1())->address().EqualIPs(wifi[1]),
                   1000);
  EXPECT_TRUE_WAIT(ep2_ch1()->selected_connection() &&
                       LocalCandidate(ep2_ch1())->address().EqualIPs(wifi[1]) &&
                       RemoteCandidate(ep2_ch1())->address().EqualIPs(wifi[0]),
                   1000);
  DestroyChannels();
}

// Tests that a Wifi-Cellular connection has higher precedence than
// a Cellular-Cellular connection.
TEST_F(P2PTransportChannelMultihomedTest, TestPreferWifiOverCellularNetwork) {
  // The interface names are chosen so that |cellular| would have higher
  // candidate priority if it is not for the network type.
  auto& wifi = kAlternateAddrs;
  auto& cellular = kPublicAddrs;
  AddAddress(0, cellular[0], "test1", rtc::ADAPTER_TYPE_CELLULAR);
  AddAddress(1, wifi[1], "test0", rtc::ADAPTER_TYPE_WIFI);
  AddAddress(1, cellular[1], "test1", rtc::ADAPTER_TYPE_CELLULAR);

  // Use only local ports for simplicity.
  SetAllocatorFlags(0, kOnlyLocalPorts);
  SetAllocatorFlags(1, kOnlyLocalPorts);

  // Create channels and let them go writable, as usual.
  CreateChannels();

  EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
                              ep2_ch1()->receiving() && ep2_ch1()->writable(),
                          1000, 1000);
  // Need to wait to make sure the connections on both networks are writable.
  EXPECT_TRUE_WAIT(ep1_ch1()->selected_connection() &&
                       RemoteCandidate(ep1_ch1())->address().EqualIPs(wifi[1]),
                   1000);
  EXPECT_TRUE_WAIT(ep2_ch1()->selected_connection() &&
                       LocalCandidate(ep2_ch1())->address().EqualIPs(wifi[1]),
                   1000);
  DestroyChannels();
}

// Test that the backup connection is pinged at a rate no faster than
// what was configured.
TEST_F(P2PTransportChannelMultihomedTest, TestPingBackupConnectionRate) {
  AddAddress(0, kPublicAddrs[0]);
  // Adding alternate address will make sure |kPublicAddrs| has the higher
  // priority than others. This is due to FakeNetwork::AddInterface method.
  AddAddress(1, kAlternateAddrs[1]);
  AddAddress(1, kPublicAddrs[1]);

  // Use only local ports for simplicity.
  SetAllocatorFlags(0, kOnlyLocalPorts);
  SetAllocatorFlags(1, kOnlyLocalPorts);

  // Create channels and let them go writable, as usual.
  CreateChannels();
  EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
                              ep2_ch1()->receiving() && ep2_ch1()->writable(),
                          1000, 1000);
  int backup_ping_interval = 2000;
  ep2_ch1()->SetIceConfig(
      CreateIceConfig(2000, GATHER_ONCE, backup_ping_interval));
  // After the state becomes COMPLETED, the backup connection will be pinged
  // once every |backup_ping_interval| milliseconds.
  ASSERT_TRUE_WAIT(ep2_ch1()->GetState() == IceTransportState::STATE_COMPLETED,
                   1000);
  const std::vector<Connection*>& connections = ep2_ch1()->connections();
  ASSERT_EQ(2U, connections.size());
  Connection* backup_conn = connections[1];
  EXPECT_TRUE_WAIT(backup_conn->writable(), kMediumTimeout);
  int64_t last_ping_response_ms = backup_conn->last_ping_response_received();
  EXPECT_TRUE_WAIT(
      last_ping_response_ms < backup_conn->last_ping_response_received(),
      kDefaultTimeout);
  int time_elapsed =
      backup_conn->last_ping_response_received() - last_ping_response_ms;
  RTC_LOG(LS_INFO) << "Time elapsed: " << time_elapsed;
  EXPECT_GE(time_elapsed, backup_ping_interval);

  DestroyChannels();
}

TEST_F(P2PTransportChannelMultihomedTest, TestGetState) {
  rtc::ScopedFakeClock clock;
  AddAddress(0, kAlternateAddrs[0]);
  AddAddress(0, kPublicAddrs[0]);
  AddAddress(1, kPublicAddrs[1]);
  // Create channels and let them go writable, as usual.
  CreateChannels();

  // Both transport channels will reach STATE_COMPLETED quickly.
  EXPECT_EQ_SIMULATED_WAIT(IceTransportState::STATE_COMPLETED,
                           ep1_ch1()->GetState(), kShortTimeout, clock);
  EXPECT_EQ_SIMULATED_WAIT(IceTransportState::STATE_COMPLETED,
                           ep2_ch1()->GetState(), kShortTimeout, clock);
}

// Tests that when a network interface becomes inactive, if Continual Gathering
// policy is GATHER_CONTINUALLY, the ports associated with that network
// will be removed from the port list of the channel, and the respective
// remote candidates on the other participant will be removed eventually.
TEST_F(P2PTransportChannelMultihomedTest, TestNetworkBecomesInactive) {
  rtc::ScopedFakeClock clock;
  AddAddress(0, kPublicAddrs[0]);
  AddAddress(1, kPublicAddrs[1]);
  // Create channels and let them go writable, as usual.
  IceConfig ep1_config = CreateIceConfig(2000, GATHER_CONTINUALLY);
  IceConfig ep2_config = CreateIceConfig(2000, GATHER_ONCE);
  CreateChannels(ep1_config, ep2_config);

  SetAllocatorFlags(0, kOnlyLocalPorts);
  SetAllocatorFlags(1, kOnlyLocalPorts);
  EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
                                 ep2_ch1()->receiving() &&
                                 ep2_ch1()->writable(),
                             kDefaultTimeout, clock);
  // More than one port has been created.
  EXPECT_LE(1U, ep1_ch1()->ports().size());
  // Endpoint 1 enabled continual gathering; the port will be removed
  // when the interface is removed.
  RemoveAddress(0, kPublicAddrs[0]);
  EXPECT_TRUE(ep1_ch1()->ports().empty());
  // The remote candidates will be removed eventually.
  EXPECT_TRUE_SIMULATED_WAIT(ep2_ch1()->remote_candidates().empty(), 1000,
                             clock);

  size_t num_ports = ep2_ch1()->ports().size();
  EXPECT_LE(1U, num_ports);
  size_t num_remote_candidates = ep1_ch1()->remote_candidates().size();
  // Endpoint 2 did not enable continual gathering; the local port will still be
  // removed when the interface is removed but the remote candidates on the
  // other participant will not be removed.
  RemoveAddress(1, kPublicAddrs[1]);

  EXPECT_EQ_SIMULATED_WAIT(0U, ep2_ch1()->ports().size(), kDefaultTimeout,
                           clock);
  SIMULATED_WAIT(0U == ep1_ch1()->remote_candidates().size(), 500, clock);
  EXPECT_EQ(num_remote_candidates, ep1_ch1()->remote_candidates().size());

  DestroyChannels();
}

// Tests that continual gathering will create new connections when a new
// interface is added.
TEST_F(P2PTransportChannelMultihomedTest,
       TestContinualGatheringOnNewInterface) {
  auto& wifi = kAlternateAddrs;
  auto& cellular = kPublicAddrs;
  AddAddress(0, wifi[0], "test_wifi0", rtc::ADAPTER_TYPE_WIFI);
  AddAddress(1, cellular[1], "test_cell1", rtc::ADAPTER_TYPE_CELLULAR);
  // Set continual gathering policy.
  IceConfig continual_gathering_config =
      CreateIceConfig(1000, GATHER_CONTINUALLY);
  CreateChannels(continual_gathering_config, continual_gathering_config);
  SetAllocatorFlags(0, kOnlyLocalPorts);
  SetAllocatorFlags(1, kOnlyLocalPorts);
  EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
                              ep2_ch1()->receiving() && ep2_ch1()->writable(),
                          kDefaultTimeout, kDefaultTimeout);

  // Add a new wifi interface on end point 2. We should expect a new connection
  // to be created and the new one will be the best connection.
  AddAddress(1, wifi[1], "test_wifi1", rtc::ADAPTER_TYPE_WIFI);
  const Connection* conn;
  EXPECT_TRUE_WAIT((conn = ep1_ch1()->selected_connection()) != nullptr &&
                       conn->remote_candidate().address().EqualIPs(wifi[1]),
                   kDefaultTimeout);
  EXPECT_TRUE_WAIT((conn = ep2_ch1()->selected_connection()) != nullptr &&
                       conn->local_candidate().address().EqualIPs(wifi[1]),
                   kDefaultTimeout);

  // Add a new cellular interface on end point 1, we should expect a new
  // backup connection created using this new interface.
  AddAddress(0, cellular[0], "test_cellular0", rtc::ADAPTER_TYPE_CELLULAR);
  EXPECT_TRUE_WAIT(
      ep1_ch1()->GetState() == IceTransportState::STATE_COMPLETED &&
          (conn = GetConnectionWithLocalAddress(ep1_ch1(), cellular[0])) !=
              nullptr &&
          conn != ep1_ch1()->selected_connection() && conn->writable(),
      kDefaultTimeout);
  EXPECT_TRUE_WAIT(
      ep2_ch1()->GetState() == IceTransportState::STATE_COMPLETED &&
          (conn = GetConnectionWithRemoteAddress(ep2_ch1(), cellular[0])) !=
              nullptr &&
          conn != ep2_ch1()->selected_connection() && conn->receiving(),
      kDefaultTimeout);

  DestroyChannels();
}

// Tests that we can switch links via continual gathering.
TEST_F(P2PTransportChannelMultihomedTest,
       TestSwitchLinksViaContinualGathering) {
  rtc::ScopedFakeClock clock;
  AddAddress(0, kPublicAddrs[0]);
  AddAddress(1, kPublicAddrs[1]);
  // Use only local ports for simplicity.
  SetAllocatorFlags(0, kOnlyLocalPorts);
  SetAllocatorFlags(1, kOnlyLocalPorts);

  // Set continual gathering policy.
  IceConfig continual_gathering_config =
      CreateIceConfig(1000, GATHER_CONTINUALLY);
  // Create channels and let them go writable, as usual.
  CreateChannels(continual_gathering_config, continual_gathering_config);
  EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
                                 ep2_ch1()->receiving() &&
                                 ep2_ch1()->writable(),
                             kMediumTimeout, clock);
  EXPECT_TRUE(ep1_ch1()->selected_connection() &&
              ep2_ch1()->selected_connection() &&
              LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
              RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));

  // Add the new address first and then remove the other one.
  RTC_LOG(LS_INFO) << "Draining...";
  AddAddress(1, kAlternateAddrs[1]);
  RemoveAddress(1, kPublicAddrs[1]);
  // We should switch to use the alternate address after an exchange of pings.
  EXPECT_TRUE_SIMULATED_WAIT(
      ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection() &&
          LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
          RemoteCandidate(ep1_ch1())->address().EqualIPs(kAlternateAddrs[1]),
      kMediumTimeout, clock);

  // Remove one address first and then add another address.
  RTC_LOG(LS_INFO) << "Draining again...";
  RemoveAddress(1, kAlternateAddrs[1]);
  AddAddress(1, kAlternateAddrs[0]);
  EXPECT_TRUE_SIMULATED_WAIT(
      ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection() &&
          LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
          RemoteCandidate(ep1_ch1())->address().EqualIPs(kAlternateAddrs[0]),
      kMediumTimeout, clock);

  DestroyChannels();
}

// Tests that the backup connection will be restored after it is destroyed.
TEST_F(P2PTransportChannelMultihomedTest, TestRestoreBackupConnection) {
  rtc::ScopedFakeClock clock;
  auto& wifi = kAlternateAddrs;
  auto& cellular = kPublicAddrs;
  AddAddress(0, wifi[0], "test_wifi0", rtc::ADAPTER_TYPE_WIFI);
  AddAddress(0, cellular[0], "test_cell0", rtc::ADAPTER_TYPE_CELLULAR);
  AddAddress(1, wifi[1], "test_wifi1", rtc::ADAPTER_TYPE_WIFI);
  AddAddress(1, cellular[1], "test_cell1", rtc::ADAPTER_TYPE_CELLULAR);
  // Use only local ports for simplicity.
  SetAllocatorFlags(0, kOnlyLocalPorts);
  SetAllocatorFlags(1, kOnlyLocalPorts);

  // Create channels and let them go writable, as usual.
  IceConfig config = CreateIceConfig(1000, GATHER_CONTINUALLY);
  config.regather_on_failed_networks_interval = 2000;
  CreateChannels(config, config);
  EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
                                 ep2_ch1()->receiving() &&
                                 ep2_ch1()->writable(),
                             kMediumTimeout, clock);
  EXPECT_TRUE(ep1_ch1()->selected_connection() &&
              ep2_ch1()->selected_connection() &&
              LocalCandidate(ep1_ch1())->address().EqualIPs(wifi[0]) &&
              RemoteCandidate(ep1_ch1())->address().EqualIPs(wifi[1]));

  // Destroy all backup connections.
  DestroyAllButBestConnection(ep1_ch1());
  // Ensure the backup connection is removed first.
  EXPECT_TRUE_SIMULATED_WAIT(
      GetConnectionWithLocalAddress(ep1_ch1(), cellular[0]) == nullptr,
      kDefaultTimeout, clock);
  const Connection* conn;
  EXPECT_TRUE_SIMULATED_WAIT(
      (conn = GetConnectionWithLocalAddress(ep1_ch1(), cellular[0])) !=
              nullptr &&
          conn != ep1_ch1()->selected_connection() && conn->writable(),
      kDefaultTimeout, clock);

  DestroyChannels();
}

// A collection of tests which tests a single P2PTransportChannel by sending
// pings.
class P2PTransportChannelPingTest : public testing::Test,
                                    public sigslot::has_slots<> {
 public:
  P2PTransportChannelPingTest()
      : vss_(new rtc::VirtualSocketServer()), thread_(vss_.get()) {}

 protected:
  void PrepareChannel(P2PTransportChannel* ch) {
    ch->SetIceRole(ICEROLE_CONTROLLING);
    ch->SetIceParameters(kIceParams[0]);
    ch->SetRemoteIceParameters(kIceParams[1]);
    ch->SignalNetworkRouteChanged.connect(
        this, &P2PTransportChannelPingTest::OnNetworkRouteChanged);
    ch->SignalReadyToSend.connect(this,
                                  &P2PTransportChannelPingTest::OnReadyToSend);
    ch->SignalStateChanged.connect(
        this, &P2PTransportChannelPingTest::OnChannelStateChanged);
  }

  Connection* WaitForConnectionTo(P2PTransportChannel* ch,
                                  const std::string& ip,
                                  int port_num,
                                  rtc::FakeClock* clock = nullptr) {
    if (clock == nullptr) {
      EXPECT_TRUE_WAIT(GetConnectionTo(ch, ip, port_num) != nullptr,
                       kMediumTimeout);
    } else {
      EXPECT_TRUE_SIMULATED_WAIT(GetConnectionTo(ch, ip, port_num) != nullptr,
                                 kMediumTimeout, *clock);
    }
    return GetConnectionTo(ch, ip, port_num);
  }

  Port* GetPort(P2PTransportChannel* ch) {
    if (ch->ports().empty()) {
      return nullptr;
    }
    return static_cast<Port*>(ch->ports()[0]);
  }

  Port* GetPrunedPort(P2PTransportChannel* ch) {
    if (ch->pruned_ports().empty()) {
      return nullptr;
    }
    return static_cast<Port*>(ch->pruned_ports()[0]);
  }

  Connection* GetConnectionTo(P2PTransportChannel* ch,
                              const std::string& ip,
                              int port_num) {
    Port* port = GetPort(ch);
    if (!port) {
      return nullptr;
    }
    return port->GetConnection(rtc::SocketAddress(ip, port_num));
  }

  Connection* FindNextPingableConnectionAndPingIt(P2PTransportChannel* ch) {
    Connection* conn = ch->FindNextPingableConnection();
    if (conn) {
      ch->MarkConnectionPinged(conn);
    }
    return conn;
  }

  int SendData(IceTransportInternal* channel,
               const char* data,
               size_t len,
               int packet_id) {
    rtc::PacketOptions options;
    options.packet_id = packet_id;
    return channel->SendPacket(data, len, options, 0);
  }

  Connection* CreateConnectionWithCandidate(P2PTransportChannel* channel,
                                            rtc::ScopedFakeClock* clock,
                                            const std::string& ip_addr,
                                            int port,
                                            int priority,
                                            bool writable) {
    channel->AddRemoteCandidate(
        CreateUdpCandidate(LOCAL_PORT_TYPE, ip_addr, port, priority));
    EXPECT_TRUE_SIMULATED_WAIT(
        GetConnectionTo(channel, ip_addr, port) != nullptr, kMediumTimeout,
        *clock);
    Connection* conn = GetConnectionTo(channel, ip_addr, port);

    if (conn && writable) {
      conn->ReceivedPingResponse(LOW_RTT, "id");  // make it writable
    }
    return conn;
  }

  void NominateConnection(Connection* conn, uint32_t remote_nomination = 1U) {
    conn->set_remote_nomination(remote_nomination);
    conn->SignalNominated(conn);
  }

  void OnNetworkRouteChanged(absl::optional<rtc::NetworkRoute> network_route) {
    last_network_route_ = network_route;
    if (last_network_route_) {
      last_sent_packet_id_ = last_network_route_->last_sent_packet_id;
    }
    ++selected_candidate_pair_switches_;
  }

  void ReceivePingOnConnection(Connection* conn,
                               const std::string& remote_ufrag,
                               int priority,
                               uint32_t nomination = 0) {
    IceMessage msg;
    msg.SetType(STUN_BINDING_REQUEST);
    msg.AddAttribute(absl::make_unique<StunByteStringAttribute>(
        STUN_ATTR_USERNAME,
        conn->local_candidate().username() + ":" + remote_ufrag));
    msg.AddAttribute(
        absl::make_unique<StunUInt32Attribute>(STUN_ATTR_PRIORITY, priority));
    if (nomination != 0) {
      msg.AddAttribute(absl::make_unique<StunUInt32Attribute>(
          STUN_ATTR_NOMINATION, nomination));
    }
    msg.SetTransactionID(rtc::CreateRandomString(kStunTransactionIdLength));
    msg.AddMessageIntegrity(conn->local_candidate().password());
    msg.AddFingerprint();
    rtc::ByteBufferWriter buf;
    msg.Write(&buf);
    conn->OnReadPacket(buf.Data(), buf.Length(), rtc::CreatePacketTime(0));
  }

  void OnReadyToSend(rtc::PacketTransportInternal* transport) {
    channel_ready_to_send_ = true;
  }
  void OnChannelStateChanged(IceTransportInternal* channel) {
    channel_state_ = channel->GetState();
  }

  int last_sent_packet_id() { return last_sent_packet_id_; }
  bool channel_ready_to_send() { return channel_ready_to_send_; }
  void reset_channel_ready_to_send() { channel_ready_to_send_ = false; }
  IceTransportState channel_state() { return channel_state_; }
  int reset_selected_candidate_pair_switches() {
    int switches = selected_candidate_pair_switches_;
    selected_candidate_pair_switches_ = 0;
    return switches;
  }

  // Return true if the |pair| matches the last network route.
  bool CandidatePairMatchesNetworkRoute(CandidatePairInterface* pair) {
    if (!pair) {
      return !last_network_route_.has_value();
    } else {
      return pair->local_candidate().network_id() ==
                 last_network_route_->local_network_id &&
             pair->remote_candidate().network_id() ==
                 last_network_route_->remote_network_id;
    }
  }

 private:
  std::unique_ptr<rtc::VirtualSocketServer> vss_;
  rtc::AutoSocketServerThread thread_;
  int selected_candidate_pair_switches_ = 0;
  int last_sent_packet_id_ = -1;
  bool channel_ready_to_send_ = false;
  IceTransportState channel_state_ = IceTransportState::STATE_INIT;
  absl::optional<rtc::NetworkRoute> last_network_route_;
};

TEST_F(P2PTransportChannelPingTest, TestTriggeredChecks) {
  FakePortAllocator pa(rtc::Thread::Current(), nullptr);
  P2PTransportChannel ch("trigger checks", 1, &pa);
  PrepareChannel(&ch);
  ch.MaybeStartGathering();
  ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
  ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));

  Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
  Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
  ASSERT_TRUE(conn1 != nullptr);
  ASSERT_TRUE(conn2 != nullptr);

  // Before a triggered check, the first connection to ping is the
  // highest priority one.
  EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch));

  // Receiving a ping causes a triggered check which should make conn1
  // be pinged first instead of conn2, even though conn2 has a higher
  // priority.
  conn1->ReceivedPing();
  EXPECT_EQ(conn1, FindNextPingableConnectionAndPingIt(&ch));
}

TEST_F(P2PTransportChannelPingTest, TestAllConnectionsPingedSufficiently) {
  FakePortAllocator pa(rtc::Thread::Current(), nullptr);
  P2PTransportChannel ch("ping sufficiently", 1, &pa);
  PrepareChannel(&ch);
  ch.MaybeStartGathering();
  ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
  ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));

  Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
  Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
  ASSERT_TRUE(conn1 != nullptr);
  ASSERT_TRUE(conn2 != nullptr);

  // Low-priority connection becomes writable so that the other connection
  // is not pruned.
  conn1->ReceivedPingResponse(LOW_RTT, "id");
  EXPECT_TRUE_WAIT(
      conn1->num_pings_sent() >= MIN_PINGS_AT_WEAK_PING_INTERVAL &&
          conn2->num_pings_sent() >= MIN_PINGS_AT_WEAK_PING_INTERVAL,
      kDefaultTimeout);
}

// Verify that the connections are pinged at the right time.
TEST_F(P2PTransportChannelPingTest, TestStunPingIntervals) {
  rtc::ScopedFakeClock clock;
  int RTT_RATIO = 4;
  int SCHEDULING_RANGE = 200;
  int RTT_RANGE = 10;

  FakePortAllocator pa(rtc::Thread::Current(), nullptr);
  P2PTransportChannel ch("TestChannel", 1, &pa);
  PrepareChannel(&ch);
  ch.MaybeStartGathering();
  ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
  Connection* conn = WaitForConnectionTo(&ch, "1.1.1.1", 1);

  ASSERT_TRUE(conn != nullptr);
  SIMULATED_WAIT(conn->num_pings_sent() == 1, kDefaultTimeout, clock);

  // Initializing.

  int64_t start = clock.TimeNanos();
  SIMULATED_WAIT(conn->num_pings_sent() >= MIN_PINGS_AT_WEAK_PING_INTERVAL,
                 kDefaultTimeout, clock);
  int64_t ping_interval_ms = (clock.TimeNanos() - start) /
                             rtc::kNumNanosecsPerMillisec /
                             (MIN_PINGS_AT_WEAK_PING_INTERVAL - 1);
  EXPECT_EQ(ping_interval_ms, WEAK_PING_INTERVAL);

  // Stabilizing.

  conn->ReceivedPingResponse(LOW_RTT, "id");
  int ping_sent_before = conn->num_pings_sent();
  start = clock.TimeNanos();
  // The connection becomes strong but not stable because we haven't been able
  // to converge the RTT.
  SIMULATED_WAIT(conn->num_pings_sent() == ping_sent_before + 1, kMediumTimeout,
                 clock);
  ping_interval_ms = (clock.TimeNanos() - start) / rtc::kNumNanosecsPerMillisec;
  EXPECT_GE(ping_interval_ms,
            WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL);
  EXPECT_LE(
      ping_interval_ms,
      WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL + SCHEDULING_RANGE);

  // Stabilized.

  // The connection becomes stable after receiving more than RTT_RATIO rtt
  // samples.
  for (int i = 0; i < RTT_RATIO; i++) {
    conn->ReceivedPingResponse(LOW_RTT, "id");
  }
  ping_sent_before = conn->num_pings_sent();
  start = clock.TimeNanos();
  SIMULATED_WAIT(conn->num_pings_sent() == ping_sent_before + 1, kMediumTimeout,
                 clock);
  ping_interval_ms = (clock.TimeNanos() - start) / rtc::kNumNanosecsPerMillisec;
  EXPECT_GE(ping_interval_ms,
            STRONG_AND_STABLE_WRITABLE_CONNECTION_PING_INTERVAL);
  EXPECT_LE(
      ping_interval_ms,
      STRONG_AND_STABLE_WRITABLE_CONNECTION_PING_INTERVAL + SCHEDULING_RANGE);

  // Destabilized.

  conn->ReceivedPingResponse(LOW_RTT, "id");
  // Create a in-flight ping.
  conn->Ping(clock.TimeNanos() / rtc::kNumNanosecsPerMillisec);
  start = clock.TimeNanos();
  // In-flight ping timeout and the connection will be unstable.
  SIMULATED_WAIT(
      !conn->stable(clock.TimeNanos() / rtc::kNumNanosecsPerMillisec),
      kMediumTimeout, clock);
  int64_t duration_ms =
      (clock.TimeNanos() - start) / rtc::kNumNanosecsPerMillisec;
  EXPECT_GE(duration_ms, 2 * conn->rtt() - RTT_RANGE);
  EXPECT_LE(duration_ms, 2 * conn->rtt() + RTT_RANGE);
  // The connection become unstable due to not receiving ping responses.
  ping_sent_before = conn->num_pings_sent();
  SIMULATED_WAIT(conn->num_pings_sent() == ping_sent_before + 1, kMediumTimeout,
                 clock);
  // The interval is expected to be
  // WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL.
  start = clock.TimeNanos();
  ping_sent_before = conn->num_pings_sent();
  SIMULATED_WAIT(conn->num_pings_sent() == ping_sent_before + 1, kMediumTimeout,
                 clock);
  ping_interval_ms = (clock.TimeNanos() - start) / rtc::kNumNanosecsPerMillisec;
  EXPECT_GE(ping_interval_ms,
            WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL);
  EXPECT_LE(
      ping_interval_ms,
      WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL + SCHEDULING_RANGE);
}

// Test that we start pinging as soon as we have a connection and remote ICE
// parameters.
TEST_F(P2PTransportChannelPingTest, PingingStartedAsSoonAsPossible) {
  rtc::ScopedFakeClock clock;

  FakePortAllocator pa(rtc::Thread::Current(), nullptr);
  P2PTransportChannel ch("TestChannel", 1, &pa);
  ch.SetIceRole(ICEROLE_CONTROLLING);
  ch.SetIceParameters(kIceParams[0]);
  ch.MaybeStartGathering();
  EXPECT_EQ_WAIT(IceGatheringState::kIceGatheringComplete, ch.gathering_state(),
                 kDefaultTimeout);

  // Simulate a binding request being received, creating a peer reflexive
  // candidate pair while we still don't have remote ICE parameters.
  IceMessage request;
  request.SetType(STUN_BINDING_REQUEST);
  request.AddAttribute(absl::make_unique<StunByteStringAttribute>(
      STUN_ATTR_USERNAME, kIceUfrag[1]));
  uint32_t prflx_priority = ICE_TYPE_PREFERENCE_PRFLX << 24;
  request.AddAttribute(absl::make_unique<StunUInt32Attribute>(
      STUN_ATTR_PRIORITY, prflx_priority));
  Port* port = GetPort(&ch);
  ASSERT_NE(nullptr, port);
  port->SignalUnknownAddress(port, rtc::SocketAddress("1.1.1.1", 1), PROTO_UDP,
                             &request, kIceUfrag[1], false);
  Connection* conn = GetConnectionTo(&ch, "1.1.1.1", 1);
  ASSERT_NE(nullptr, conn);

  // Simulate waiting for a second (and change) and verify that no pings were
  // sent, since we don't yet have remote ICE parameters.
  SIMULATED_WAIT(conn->num_pings_sent() > 0, 1025, clock);
  EXPECT_EQ(0, conn->num_pings_sent());

  // Set remote ICE parameters. Now we should be able to ping. Ensure that
  // the first ping is sent as soon as possible, within one simulated clock
  // tick.
  ch.SetRemoteIceParameters(kIceParams[1]);
  EXPECT_TRUE_SIMULATED_WAIT(conn->num_pings_sent() > 0, 1, clock);
}

TEST_F(P2PTransportChannelPingTest, TestNoTriggeredChecksWhenWritable) {
  FakePortAllocator pa(rtc::Thread::Current(), nullptr);
  P2PTransportChannel ch("trigger checks", 1, &pa);
  PrepareChannel(&ch);
  ch.MaybeStartGathering();
  ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
  ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));

  Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
  Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
  ASSERT_TRUE(conn1 != nullptr);
  ASSERT_TRUE(conn2 != nullptr);

  EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch));
  EXPECT_EQ(conn1, FindNextPingableConnectionAndPingIt(&ch));
  conn1->ReceivedPingResponse(LOW_RTT, "id");
  ASSERT_TRUE(conn1->writable());
  conn1->ReceivedPing();

  // Ping received, but the connection is already writable, so no
  // "triggered check" and conn2 is pinged before conn1 because it has
  // a higher priority.
  EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch));
}

TEST_F(P2PTransportChannelPingTest, TestFailedConnectionNotPingable) {
  FakePortAllocator pa(rtc::Thread::Current(), nullptr);
  P2PTransportChannel ch("Do not ping failed connections", 1, &pa);
  PrepareChannel(&ch);
  ch.MaybeStartGathering();
  ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));

  Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
  ASSERT_TRUE(conn1 != nullptr);

  EXPECT_EQ(conn1, ch.FindNextPingableConnection());
  conn1->Prune();  // A pruned connection may still be pingable.
  EXPECT_EQ(conn1, ch.FindNextPingableConnection());
  conn1->FailAndPrune();
  EXPECT_TRUE(nullptr == ch.FindNextPingableConnection());
}

TEST_F(P2PTransportChannelPingTest, TestSignalStateChanged) {
  FakePortAllocator pa(rtc::Thread::Current(), nullptr);
  P2PTransportChannel ch("state change", 1, &pa);
  PrepareChannel(&ch);
  ch.MaybeStartGathering();
  ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
  Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
  ASSERT_TRUE(conn1 != nullptr);
  // Pruning the connection reduces the set of active connections and changes
  // the channel state.
  conn1->Prune();
  EXPECT_EQ_WAIT(IceTransportState::STATE_FAILED, channel_state(),
                 kDefaultTimeout);
}

// Test adding remote candidates with different ufrags. If a remote candidate
// is added with an old ufrag, it will be discarded. If it is added with a
// ufrag that was not seen before, it will be used to create connections
// although the ICE pwd in the remote candidate will be set when the ICE
// parameters arrive. If a remote candidate is added with the current ICE
// ufrag, its pwd and generation will be set properly.
TEST_F(P2PTransportChannelPingTest, TestAddRemoteCandidateWithVariousUfrags) {
  FakePortAllocator pa(rtc::Thread::Current(), nullptr);
  P2PTransportChannel ch("add candidate", 1, &pa);
  PrepareChannel(&ch);
  ch.MaybeStartGathering();
  // Add a candidate with a future ufrag.
  ch.AddRemoteCandidate(
      CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1, kIceUfrag[2]));
  Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
  ASSERT_TRUE(conn1 != nullptr);
  const Candidate& candidate = conn1->remote_candidate();
  EXPECT_EQ(kIceUfrag[2], candidate.username());
  EXPECT_TRUE(candidate.password().empty());
  EXPECT_TRUE(FindNextPingableConnectionAndPingIt(&ch) == nullptr);

  // Set the remote ICE parameters with the "future" ufrag.
  // This should set the ICE pwd in the remote candidate of |conn1|, making
  // it pingable.
  ch.SetRemoteIceParameters(kIceParams[2]);
  EXPECT_EQ(kIceUfrag[2], candidate.username());
  EXPECT_EQ(kIcePwd[2], candidate.password());
  EXPECT_EQ(conn1, FindNextPingableConnectionAndPingIt(&ch));

  // Add a candidate with an old ufrag. No connection will be created.
  ch.AddRemoteCandidate(
      CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2, kIceUfrag[1]));
  rtc::Thread::Current()->ProcessMessages(500);
  EXPECT_TRUE(GetConnectionTo(&ch, "2.2.2.2", 2) == nullptr);

  // Add a candidate with the current ufrag, its pwd and generation will be
  // assigned, even if the generation is not set.
  ch.AddRemoteCandidate(
      CreateUdpCandidate(LOCAL_PORT_TYPE, "3.3.3.3", 3, 0, kIceUfrag[2]));
  Connection* conn3 = nullptr;
  ASSERT_TRUE_WAIT((conn3 = GetConnectionTo(&ch, "3.3.3.3", 3)) != nullptr,
                   kMediumTimeout);
  const Candidate& new_candidate = conn3->remote_candidate();
  EXPECT_EQ(kIcePwd[2], new_candidate.password());
  EXPECT_EQ(1U, new_candidate.generation());

  // Check that the pwd of all remote candidates are properly assigned.
  for (const RemoteCandidate& candidate : ch.remote_candidates()) {
    EXPECT_TRUE(candidate.username() == kIceUfrag[1] ||
                candidate.username() == kIceUfrag[2]);
    if (candidate.username() == kIceUfrag[1]) {
      EXPECT_EQ(kIcePwd[1], candidate.password());
    } else if (candidate.username() == kIceUfrag[2]) {
      EXPECT_EQ(kIcePwd[2], candidate.password());
    }
  }
}

TEST_F(P2PTransportChannelPingTest, ConnectionResurrection) {
  FakePortAllocator pa(rtc::Thread::Current(), nullptr);
  P2PTransportChannel ch("connection resurrection", 1, &pa);
  PrepareChannel(&ch);
  ch.MaybeStartGathering();

  // Create conn1 and keep track of original candidate priority.
  ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
  Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
  ASSERT_TRUE(conn1 != nullptr);
  uint32_t remote_priority = conn1->remote_candidate().priority();

  // Create a higher priority candidate and make the connection
  // receiving/writable. This will prune conn1.
  ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
  Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
  ASSERT_TRUE(conn2 != nullptr);
  conn2->ReceivedPing();
  conn2->ReceivedPingResponse(LOW_RTT, "id");

  // Wait for conn1 to be pruned.
  EXPECT_TRUE_WAIT(conn1->pruned(), kMediumTimeout);
  // Destroy the connection to test SignalUnknownAddress.
  conn1->Destroy();
  EXPECT_TRUE_WAIT(GetConnectionTo(&ch, "1.1.1.1", 1) == nullptr,
                   kMediumTimeout);

  // Create a minimal STUN message with prflx priority.
  IceMessage request;
  request.SetType(STUN_BINDING_REQUEST);
  request.AddAttribute(absl::make_unique<StunByteStringAttribute>(
      STUN_ATTR_USERNAME, kIceUfrag[1]));
  uint32_t prflx_priority = ICE_TYPE_PREFERENCE_PRFLX << 24;
  request.AddAttribute(absl::make_unique<StunUInt32Attribute>(
      STUN_ATTR_PRIORITY, prflx_priority));
  EXPECT_NE(prflx_priority, remote_priority);

  Port* port = GetPort(&ch);
  // conn1 should be resurrected with original priority.
  port->SignalUnknownAddress(port, rtc::SocketAddress("1.1.1.1", 1), PROTO_UDP,
                             &request, kIceUfrag[1], false);
  conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
  ASSERT_TRUE(conn1 != nullptr);
  EXPECT_EQ(conn1->remote_candidate().priority(), remote_priority);

  // conn3, a real prflx connection, should have prflx priority.
  port->SignalUnknownAddress(port, rtc::SocketAddress("3.3.3.3", 1), PROTO_UDP,
                             &request, kIceUfrag[1], false);
  Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 1);
  ASSERT_TRUE(conn3 != nullptr);
  EXPECT_EQ(conn3->remote_candidate().priority(), prflx_priority);
}

TEST_F(P2PTransportChannelPingTest, TestReceivingStateChange) {
  rtc::ScopedFakeClock clock;
  FakePortAllocator pa(rtc::Thread::Current(), nullptr);
  P2PTransportChannel ch("receiving state change", 1, &pa);
  PrepareChannel(&ch);
  // Default receiving timeout and checking receiving interval should not be too
  // small.
  EXPECT_LE(1000, ch.config().receiving_timeout_or_default());
  EXPECT_LE(200, ch.check_receiving_interval());
  ch.SetIceConfig(CreateIceConfig(500, GATHER_ONCE));
  EXPECT_EQ(500, ch.config().receiving_timeout_or_default());
  EXPECT_EQ(50, ch.check_receiving_interval());
  ch.MaybeStartGathering();
  ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
  Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1, &clock);
  ASSERT_TRUE(conn1 != nullptr);

  clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
  conn1->ReceivedPing();
  conn1->OnReadPacket("ABC", 3, rtc::CreatePacketTime(0));
  EXPECT_TRUE_SIMULATED_WAIT(ch.receiving(), kShortTimeout, clock);
  EXPECT_TRUE_SIMULATED_WAIT(!ch.receiving(), kShortTimeout, clock);
}

// The controlled side will select a connection as the "selected connection"
// based on priority until the controlling side nominates a connection, at which
// point the controlled side will select that connection as the
// "selected connection". Plus, SignalNetworkRouteChanged will be fired if the
// selected connection changes and SignalReadyToSend will be fired if the new
// selected connection is writable.
TEST_F(P2PTransportChannelPingTest, TestSelectConnectionBeforeNomination) {
  FakePortAllocator pa(rtc::Thread::Current(), nullptr);
  P2PTransportChannel ch("receiving state change", 1, &pa);
  PrepareChannel(&ch);
  ch.SetIceRole(ICEROLE_CONTROLLED);
  ch.MaybeStartGathering();
  ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
  Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
  ASSERT_TRUE(conn1 != nullptr);
  // Channel is not ready to send because it is not writable.
  EXPECT_FALSE(channel_ready_to_send());
  int last_packet_id = 0;
  const char* data = "ABCDEFGH";
  int len = static_cast<int>(strlen(data));
  EXPECT_EQ(-1, SendData(&ch, data, len, ++last_packet_id));
  EXPECT_EQ(-1, last_sent_packet_id());

  // A connection needs to be writable before it is selected for transmission.
  conn1->ReceivedPingResponse(LOW_RTT, "id");
  EXPECT_EQ_WAIT(conn1, ch.selected_connection(), kDefaultTimeout);
  EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn1));
  EXPECT_EQ(len, SendData(&ch, data, len, ++last_packet_id));

  // When a higher priority candidate comes in, the new connection is chosen
  // as the selected connection.
  ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 10));
  Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
  ASSERT_TRUE(conn2 != nullptr);
  conn2->ReceivedPingResponse(LOW_RTT, "id");
  EXPECT_EQ_WAIT(conn2, ch.selected_connection(), kDefaultTimeout);
  EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));
  EXPECT_TRUE(channel_ready_to_send());
  EXPECT_EQ(last_packet_id, last_sent_packet_id());

  // If a stun request with use-candidate attribute arrives, the receiving
  // connection will be set as the selected connection, even though
  // its priority is lower.
  EXPECT_EQ(len, SendData(&ch, data, len, ++last_packet_id));
  ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "3.3.3.3", 3, 1));
  Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3);
  ASSERT_TRUE(conn3 != nullptr);
  // Because it has a lower priority, the selected connection is still conn2.
  EXPECT_EQ(conn2, ch.selected_connection());
  conn3->ReceivedPingResponse(LOW_RTT, "id");  // Become writable.
  // But if it is nominated via use_candidate, it is chosen as the selected
  // connection.
  NominateConnection(conn3);
  EXPECT_EQ(conn3, ch.selected_connection());
  EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn3));
  EXPECT_EQ(last_packet_id, last_sent_packet_id());
  EXPECT_TRUE(channel_ready_to_send());

  // Even if another higher priority candidate arrives, it will not be set as
  // the selected connection because the selected connection is nominated by
  // the controlling side.
  EXPECT_EQ(len, SendData(&ch, data, len, ++last_packet_id));
  ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "4.4.4.4", 4, 100));
  Connection* conn4 = WaitForConnectionTo(&ch, "4.4.4.4", 4);
  ASSERT_TRUE(conn4 != nullptr);
  EXPECT_EQ(conn3, ch.selected_connection());
  // But if it is nominated via use_candidate and writable, it will be set as
  // the selected connection.
  NominateConnection(conn4);
  // Not switched yet because conn4 is not writable.
  EXPECT_EQ(conn3, ch.selected_connection());
  reset_channel_ready_to_send();
  // The selected connection switches after conn4 becomes writable.
  conn4->ReceivedPingResponse(LOW_RTT, "id");
  EXPECT_EQ_WAIT(conn4, ch.selected_connection(), kDefaultTimeout);
  EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn4));
  EXPECT_EQ(last_packet_id, last_sent_packet_id());
  // SignalReadyToSend is fired again because conn4 is writable.
  EXPECT_TRUE(channel_ready_to_send());
}

// The controlled side will select a connection as the "selected connection"
// based on requests from an unknown address before the controlling side
// nominates a connection, and will nominate a connection from an unknown
// address if the request contains the use_candidate attribute. Plus, it will
// also sends back a ping response and set the ICE pwd in the remote candidate
// appropriately.
TEST_F(P2PTransportChannelPingTest, TestSelectConnectionFromUnknownAddress) {
  FakePortAllocator pa(rtc::Thread::Current(), nullptr);
  P2PTransportChannel ch("receiving state change", 1, &pa);
  PrepareChannel(&ch);
  ch.SetIceRole(ICEROLE_CONTROLLED);
  ch.MaybeStartGathering();
  // A minimal STUN message with prflx priority.
  IceMessage request;
  request.SetType(STUN_BINDING_REQUEST);
  request.AddAttribute(absl::make_unique<StunByteStringAttribute>(
      STUN_ATTR_USERNAME, kIceUfrag[1]));
  uint32_t prflx_priority = ICE_TYPE_PREFERENCE_PRFLX << 24;
  request.AddAttribute(absl::make_unique<StunUInt32Attribute>(
      STUN_ATTR_PRIORITY, prflx_priority));
  TestUDPPort* port = static_cast<TestUDPPort*>(GetPort(&ch));
  port->SignalUnknownAddress(port, rtc::SocketAddress("1.1.1.1", 1), PROTO_UDP,
                             &request, kIceUfrag[1], false);
  Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
  ASSERT_TRUE(conn1 != nullptr);
  EXPECT_TRUE(port->sent_binding_response());
  EXPECT_NE(conn1, ch.selected_connection());
  conn1->ReceivedPingResponse(LOW_RTT, "id");
  EXPECT_EQ_WAIT(conn1, ch.selected_connection(), kDefaultTimeout);
  port->set_sent_binding_response(false);

  // Another connection is nominated via use_candidate.
  ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
  Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
  ASSERT_TRUE(conn2 != nullptr);
  // Because it has a lower priority, the selected connection is still conn1.
  EXPECT_EQ(conn1, ch.selected_connection());
  // When it is nominated via use_candidate and writable, it is chosen as the
  // selected connection.
  conn2->ReceivedPingResponse(LOW_RTT, "id");  // Become writable.
  NominateConnection(conn2);
  EXPECT_EQ(conn2, ch.selected_connection());

  // Another request with unknown address, it will not be set as the selected
  // connection because the selected connection was nominated by the controlling
  // side.
  port->SignalUnknownAddress(port, rtc::SocketAddress("3.3.3.3", 3), PROTO_UDP,
                             &request, kIceUfrag[1], false);
  Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3);
  ASSERT_TRUE(conn3 != nullptr);
  EXPECT_TRUE(port->sent_binding_response());
  conn3->ReceivedPingResponse(LOW_RTT, "id");  // Become writable.
  EXPECT_EQ(conn2, ch.selected_connection());
  port->set_sent_binding_response(false);

  // However if the request contains use_candidate attribute, it will be
  // selected as the selected connection.
  request.AddAttribute(
      absl::make_unique<StunByteStringAttribute>(STUN_ATTR_USE_CANDIDATE));
  port->SignalUnknownAddress(port, rtc::SocketAddress("4.4.4.4", 4), PROTO_UDP,
                             &request, kIceUfrag[1], false);
  Connection* conn4 = WaitForConnectionTo(&ch, "4.4.4.4", 4);
  ASSERT_TRUE(conn4 != nullptr);
  EXPECT_TRUE(port->sent_binding_response());
  // conn4 is not the selected connection yet because it is not writable.
  EXPECT_EQ(conn2, ch.selected_connection());
  conn4->ReceivedPingResponse(LOW_RTT, "id");  // Become writable.
  EXPECT_EQ_WAIT(conn4, ch.selected_connection(), kDefaultTimeout);

  // Test that the request from an unknown address contains a ufrag from an old
  // generation.
  port->set_sent_binding_response(false);
  ch.SetRemoteIceParameters(kIceParams[2]);
  ch.SetRemoteIceParameters(kIceParams[3]);
  port->SignalUnknownAddress(port, rtc::SocketAddress("5.5.5.5", 5), PROTO_UDP,
                             &request, kIceUfrag[2], false);
  Connection* conn5 = WaitForConnectionTo(&ch, "5.5.5.5", 5);
  ASSERT_TRUE(conn5 != nullptr);
  EXPECT_TRUE(port->sent_binding_response());
  EXPECT_EQ(kIcePwd[2], conn5->remote_candidate().password());
}

// The controlled side will select a connection as the "selected connection"
// based on media received until the controlling side nominates a connection,
// at which point the controlled side will select that connection as
// the "selected connection".
TEST_F(P2PTransportChannelPingTest, TestSelectConnectionBasedOnMediaReceived) {
  FakePortAllocator pa(rtc::Thread::Current(), nullptr);
  P2PTransportChannel ch("receiving state change", 1, &pa);
  PrepareChannel(&ch);
  ch.SetIceRole(ICEROLE_CONTROLLED);
  ch.MaybeStartGathering();
  ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 10));
  Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
  ASSERT_TRUE(conn1 != nullptr);
  conn1->ReceivedPingResponse(LOW_RTT, "id");
  EXPECT_EQ_WAIT(conn1, ch.selected_connection(), kDefaultTimeout);

  // If a data packet is received on conn2, the selected connection should
  // switch to conn2 because the controlled side must mirror the media path
  // chosen by the controlling side.
  ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
  Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
  ASSERT_TRUE(conn2 != nullptr);
  conn2->ReceivedPingResponse(LOW_RTT, "id");  // Become writable and receiving.
  conn2->OnReadPacket("ABC", 3, rtc::CreatePacketTime(0));
  EXPECT_EQ(conn2, ch.selected_connection());
  conn2->ReceivedPingResponse(LOW_RTT, "id");  // Become writable.

  // Now another STUN message with an unknown address and use_candidate will
  // nominate the selected connection.
  IceMessage request;
  request.SetType(STUN_BINDING_REQUEST);
  request.AddAttribute(absl::make_unique<StunByteStringAttribute>(
      STUN_ATTR_USERNAME, kIceUfrag[1]));
  uint32_t prflx_priority = ICE_TYPE_PREFERENCE_PRFLX << 24;
  request.AddAttribute(absl::make_unique<StunUInt32Attribute>(
      STUN_ATTR_PRIORITY, prflx_priority));
  request.AddAttribute(
      absl::make_unique<StunByteStringAttribute>(STUN_ATTR_USE_CANDIDATE));
  Port* port = GetPort(&ch);
  port->SignalUnknownAddress(port, rtc::SocketAddress("3.3.3.3", 3), PROTO_UDP,
                             &request, kIceUfrag[1], false);
  Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3);
  ASSERT_TRUE(conn3 != nullptr);
  EXPECT_EQ(conn2, ch.selected_connection());  // Not writable yet.
  conn3->ReceivedPingResponse(LOW_RTT, "id");  // Become writable.
  EXPECT_EQ_WAIT(conn3, ch.selected_connection(), kDefaultTimeout);

  // Now another data packet will not switch the selected connection because the
  // selected connection was nominated by the controlling side.
  conn2->ReceivedPing();
  conn2->ReceivedPingResponse(LOW_RTT, "id");
  conn2->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0));
  EXPECT_EQ_WAIT(conn3, ch.selected_connection(), kDefaultTimeout);
}

TEST_F(P2PTransportChannelPingTest,
       TestControlledAgentDataReceivingTakesHigherPrecedenceThanPriority) {
  rtc::ScopedFakeClock clock;
  clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
  FakePortAllocator pa(rtc::Thread::Current(), nullptr);
  P2PTransportChannel ch("SwitchSelectedConnection", 1, &pa);
  PrepareChannel(&ch);
  ch.SetIceRole(ICEROLE_CONTROLLED);
  ch.MaybeStartGathering();
  // The connections have decreasing priority.
  Connection* conn1 =
      CreateConnectionWithCandidate(&ch, &clock, "1.1.1.1", 1, 10, true);
  ASSERT_TRUE(conn1 != nullptr);
  Connection* conn2 =
      CreateConnectionWithCandidate(&ch, &clock, "2.2.2.2", 2, 9, true);
  ASSERT_TRUE(conn2 != nullptr);

  // Initially, connections are selected based on priority.
  EXPECT_EQ(1, reset_selected_candidate_pair_switches());
  EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn1));

  // conn2 receives data; it becomes selected.
  // Advance the clock by 1ms so that the last data receiving timestamp of
  // conn2 is larger.
  SIMULATED_WAIT(false, 1, clock);
  conn2->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0));
  EXPECT_EQ(1, reset_selected_candidate_pair_switches());
  EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));

  // conn1 also receives data; it becomes selected due to priority again.
  conn1->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0));
  EXPECT_EQ(1, reset_selected_candidate_pair_switches());
  EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));

  // conn2 received data more recently; it is selected now because it
  // received data more recently.
  SIMULATED_WAIT(false, 1, clock);
  // Need to become writable again because it was pruned.
  conn2->ReceivedPingResponse(LOW_RTT, "id");
  conn2->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0));
  EXPECT_EQ(1, reset_selected_candidate_pair_switches());
  EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));

  // Make sure sorting won't reselect candidate pair.
  SIMULATED_WAIT(false, 10, clock);
  EXPECT_EQ(0, reset_selected_candidate_pair_switches());
}

TEST_F(P2PTransportChannelPingTest,
       TestControlledAgentNominationTakesHigherPrecedenceThanDataReceiving) {
  rtc::ScopedFakeClock clock;
  clock.AdvanceTime(webrtc::TimeDelta::seconds(1));

  FakePortAllocator pa(rtc::Thread::Current(), nullptr);
  P2PTransportChannel ch("SwitchSelectedConnection", 1, &pa);
  PrepareChannel(&ch);
  ch.SetIceRole(ICEROLE_CONTROLLED);
  ch.MaybeStartGathering();
  // The connections have decreasing priority.
  Connection* conn1 =
      CreateConnectionWithCandidate(&ch, &clock, "1.1.1.1", 1, 10, true);
  ASSERT_TRUE(conn1 != nullptr);
  Connection* conn2 =
      CreateConnectionWithCandidate(&ch, &clock, "2.2.2.2", 2, 9, true);
  ASSERT_TRUE(conn2 != nullptr);

  // conn1 received data; it is the selected connection.
  // Advance the clock to have a non-zero last-data-receiving time.
  SIMULATED_WAIT(false, 1, clock);
  conn1->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0));
  EXPECT_EQ(1, reset_selected_candidate_pair_switches());
  EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn1));

  // conn2 is nominated; it becomes the selected connection.
  NominateConnection(conn2);
  EXPECT_EQ(1, reset_selected_candidate_pair_switches());
  EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));

  // conn1 is selected because it has higher priority and also nominated.
  NominateConnection(conn1);
  EXPECT_EQ(1, reset_selected_candidate_pair_switches());
  EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));

  // Make sure sorting won't reselect candidate pair.
  SIMULATED_WAIT(false, 10, clock);
  EXPECT_EQ(0, reset_selected_candidate_pair_switches());
}

TEST_F(P2PTransportChannelPingTest,
       TestControlledAgentSelectsConnectionWithHigherNomination) {
  rtc::ScopedFakeClock clock;
  clock.AdvanceTime(webrtc::TimeDelta::seconds(1));

  FakePortAllocator pa(rtc::Thread::Current(), nullptr);
  P2PTransportChannel ch("test", 1, &pa);
  PrepareChannel(&ch);
  ch.SetIceRole(ICEROLE_CONTROLLED);
  ch.MaybeStartGathering();
  // The connections have decreasing priority.
  Connection* conn1 =
      CreateConnectionWithCandidate(&ch, &clock, "1.1.1.1", 1, 10, true);
  ASSERT_TRUE(conn1 != nullptr);
  Connection* conn2 =
      CreateConnectionWithCandidate(&ch, &clock, "2.2.2.2", 2, 9, true);
  ASSERT_TRUE(conn2 != nullptr);

  // conn1 is the selected connection because it has a higher priority,
  EXPECT_EQ_SIMULATED_WAIT(conn1, ch.selected_connection(), kDefaultTimeout,
                           clock);
  EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn1));
  reset_selected_candidate_pair_switches();

  // conn2 is nominated; it becomes selected.
  NominateConnection(conn2);
  EXPECT_EQ(1, reset_selected_candidate_pair_switches());
  EXPECT_EQ(conn2, ch.selected_connection());
  EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));

  // conn1 is selected because of its priority.
  NominateConnection(conn1);
  EXPECT_EQ(1, reset_selected_candidate_pair_switches());
  EXPECT_EQ(conn1, ch.selected_connection());
  EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn1));

  // conn2 gets higher remote nomination; it is selected again.
  NominateConnection(conn2, 2U);
  EXPECT_EQ(1, reset_selected_candidate_pair_switches());
  EXPECT_EQ(conn2, ch.selected_connection());
  EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));

  // Make sure sorting won't reselect candidate pair.
  SIMULATED_WAIT(false, 100, clock);
  EXPECT_EQ(0, reset_selected_candidate_pair_switches());
}

TEST_F(P2PTransportChannelPingTest,
       TestControlledAgentIgnoresSmallerNomination) {
  rtc::ScopedFakeClock clock;
  clock.AdvanceTime(webrtc::TimeDelta::seconds(1));

  FakePortAllocator pa(rtc::Thread::Current(), nullptr);
  P2PTransportChannel ch("test", 1, &pa);
  PrepareChannel(&ch);
  ch.SetIceRole(ICEROLE_CONTROLLED);
  ch.MaybeStartGathering();
  Connection* conn =
      CreateConnectionWithCandidate(&ch, &clock, "1.1.1.1", 1, 10, false);
  ReceivePingOnConnection(conn, kIceUfrag[1], 1, 2U);
  EXPECT_EQ(2U, conn->remote_nomination());
  // Smaller nomination is ignored.
  ReceivePingOnConnection(conn, kIceUfrag[1], 1, 1U);
  EXPECT_EQ(2U, conn->remote_nomination());
}

TEST_F(P2PTransportChannelPingTest,
       TestControlledAgentWriteStateTakesHigherPrecedenceThanNomination) {
  rtc::ScopedFakeClock clock;

  FakePortAllocator pa(rtc::Thread::Current(), nullptr);
  P2PTransportChannel ch("SwitchSelectedConnection", 1, &pa);
  PrepareChannel(&ch);
  ch.SetIceRole(ICEROLE_CONTROLLED);
  ch.MaybeStartGathering();
  // The connections have decreasing priority.
  Connection* conn1 =
      CreateConnectionWithCandidate(&ch, &clock, "1.1.1.1", 1, 10, false);
  ASSERT_TRUE(conn1 != nullptr);
  Connection* conn2 =
      CreateConnectionWithCandidate(&ch, &clock, "2.2.2.2", 2, 9, false);
  ASSERT_TRUE(conn2 != nullptr);

  NominateConnection(conn1);
  // There is no selected connection because no connection is writable.
  EXPECT_EQ(0, reset_selected_candidate_pair_switches());

  // conn2 becomes writable; it is selected even though it is not nominated.
  conn2->ReceivedPingResponse(LOW_RTT, "id");
  EXPECT_EQ_SIMULATED_WAIT(1, reset_selected_candidate_pair_switches(),
                           kDefaultTimeout, clock);
  EXPECT_EQ_SIMULATED_WAIT(conn2, ch.selected_connection(), kDefaultTimeout,
                           clock);
  EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn2));

  // If conn1 is also writable, it will become selected.
  conn1->ReceivedPingResponse(LOW_RTT, "id");
  EXPECT_EQ_SIMULATED_WAIT(1, reset_selected_candidate_pair_switches(),
                           kDefaultTimeout, clock);
  EXPECT_EQ_SIMULATED_WAIT(conn1, ch.selected_connection(), kDefaultTimeout,
                           clock);
  EXPECT_TRUE(CandidatePairMatchesNetworkRoute(conn1));

  // Make sure sorting won't reselect candidate pair.
  SIMULATED_WAIT(false, 10, clock);
  EXPECT_EQ(0, reset_selected_candidate_pair_switches());
}

// Test that if a new remote candidate has the same address and port with
// an old one, it will be used to create a new connection.
TEST_F(P2PTransportChannelPingTest, TestAddRemoteCandidateWithAddressReuse) {
  FakePortAllocator pa(rtc::Thread::Current(), nullptr);
  P2PTransportChannel ch("candidate reuse", 1, &pa);
  PrepareChannel(&ch);
  ch.MaybeStartGathering();
  const std::string host_address = "1.1.1.1";
  const int port_num = 1;

  // kIceUfrag[1] is the current generation ufrag.
  Candidate candidate = CreateUdpCandidate(LOCAL_PORT_TYPE, host_address,
                                           port_num, 1, kIceUfrag[1]);
  ch.AddRemoteCandidate(candidate);
  Connection* conn1 = WaitForConnectionTo(&ch, host_address, port_num);
  ASSERT_TRUE(conn1 != nullptr);
  EXPECT_EQ(0u, conn1->remote_candidate().generation());

  // Simply adding the same candidate again won't create a new connection.
  ch.AddRemoteCandidate(candidate);
  Connection* conn2 = GetConnectionTo(&ch, host_address, port_num);
  EXPECT_EQ(conn1, conn2);

  // Update the ufrag of the candidate and add it again.
  candidate.set_username(kIceUfrag[2]);
  ch.AddRemoteCandidate(candidate);
  conn2 = GetConnectionTo(&ch, host_address, port_num);
  EXPECT_NE(conn1, conn2);
  EXPECT_EQ(kIceUfrag[2], conn2->remote_candidate().username());
  EXPECT_EQ(1u, conn2->remote_candidate().generation());

  // Verify that a ping with the new ufrag can be received on the new
  // connection.
  EXPECT_EQ(0, conn2->last_ping_received());
  ReceivePingOnConnection(conn2, kIceUfrag[2], 1 /* priority */);
  EXPECT_GT(conn2->last_ping_received(), 0);
}

// When the current selected connection is strong, lower-priority connections
// will be pruned. Otherwise, lower-priority connections are kept.
TEST_F(P2PTransportChannelPingTest, TestDontPruneWhenWeak) {
  rtc::ScopedFakeClock clock;
  clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
  FakePortAllocator pa(rtc::Thread::Current(), nullptr);
  P2PTransportChannel ch("test channel", 1, &pa);
  PrepareChannel(&ch);
  ch.SetIceRole(ICEROLE_CONTROLLED);
  ch.MaybeStartGathering();
  ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
  Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
  ASSERT_TRUE(conn1 != nullptr);
  EXPECT_EQ(nullptr, ch.selected_connection());
  conn1->ReceivedPingResponse(LOW_RTT, "id");  // Becomes writable and receiving

  // When a higher-priority, nominated candidate comes in, the connections with
  // lower-priority are pruned.
  ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 10));
  Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2, &clock);
  ASSERT_TRUE(conn2 != nullptr);
  conn2->ReceivedPingResponse(LOW_RTT, "id");  // Becomes writable and receiving
  NominateConnection(conn2);
  EXPECT_TRUE_SIMULATED_WAIT(conn1->pruned(), kMediumTimeout, clock);

  ch.SetIceConfig(CreateIceConfig(500, GATHER_ONCE));
  // Wait until conn2 becomes not receiving.
  EXPECT_TRUE_SIMULATED_WAIT(!conn2->receiving(), kMediumTimeout, clock);

  ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "3.3.3.3", 3, 1));
  Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3, &clock);
  ASSERT_TRUE(conn3 != nullptr);
  // The selected connection should still be conn2. Even through conn3 has lower
  // priority and is not receiving/writable, it is not pruned because the
  // selected connection is not receiving.
  SIMULATED_WAIT(conn3->pruned(), kShortTimeout, clock);
  EXPECT_FALSE(conn3->pruned());
}

TEST_F(P2PTransportChannelPingTest, TestDontPruneHighPriorityConnections) {
  rtc::ScopedFakeClock clock;
  FakePortAllocator pa(rtc::Thread::Current(), nullptr);
  P2PTransportChannel ch("test channel", 1, &pa);
  PrepareChannel(&ch);
  ch.SetIceRole(ICEROLE_CONTROLLED);
  ch.MaybeStartGathering();
  Connection* conn1 =
      CreateConnectionWithCandidate(&ch, &clock, "1.1.1.1", 1, 100, true);
  ASSERT_TRUE(conn1 != nullptr);
  Connection* conn2 =
      CreateConnectionWithCandidate(&ch, &clock, "2.2.2.2", 2, 200, false);
  ASSERT_TRUE(conn2 != nullptr);
  // Even if conn1 is writable, nominated, receiving data, it should not prune
  // conn2.
  NominateConnection(conn1);
  SIMULATED_WAIT(false, 1, clock);
  conn1->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0));
  SIMULATED_WAIT(conn2->pruned(), 100, clock);
  EXPECT_FALSE(conn2->pruned());
}

// Test that GetState returns the state correctly.
TEST_F(P2PTransportChannelPingTest, TestGetState) {
  rtc::ScopedFakeClock clock;
  clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
  FakePortAllocator pa(rtc::Thread::Current(), nullptr);
  P2PTransportChannel ch("test channel", 1, &pa);
  PrepareChannel(&ch);
  ch.MaybeStartGathering();
  EXPECT_EQ(IceTransportState::STATE_INIT, ch.GetState());
  ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
  ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
  Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1, &clock);
  Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2, &clock);
  ASSERT_TRUE(conn1 != nullptr);
  ASSERT_TRUE(conn2 != nullptr);
  // Now there are two connections, so the transport channel is connecting.
  EXPECT_EQ(IceTransportState::STATE_CONNECTING, ch.GetState());
  // |conn1| becomes writable and receiving; it then should prune |conn2|.
  conn1->ReceivedPingResponse(LOW_RTT, "id");
  EXPECT_TRUE_SIMULATED_WAIT(conn2->pruned(), kShortTimeout, clock);
  EXPECT_EQ(IceTransportState::STATE_COMPLETED, ch.GetState());
  conn1->Prune();  // All connections are pruned.
  // Need to wait until the channel state is updated.
  EXPECT_EQ_SIMULATED_WAIT(IceTransportState::STATE_FAILED, ch.GetState(),
                           kShortTimeout, clock);
}

// Test that when a low-priority connection is pruned, it is not deleted
// right away, and it can become active and be pruned again.
TEST_F(P2PTransportChannelPingTest, TestConnectionPrunedAgain) {
  rtc::ScopedFakeClock clock;
  clock.AdvanceTime(webrtc::TimeDelta::seconds(1));

  FakePortAllocator pa(rtc::Thread::Current(), nullptr);
  P2PTransportChannel ch("test channel", 1, &pa);
  PrepareChannel(&ch);
  IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
  config.receiving_switching_delay = 800;
  ch.SetIceConfig(config);
  ch.MaybeStartGathering();
  ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
  Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1, &clock);
  ASSERT_TRUE(conn1 != nullptr);
  EXPECT_EQ(nullptr, ch.selected_connection());
  conn1->ReceivedPingResponse(LOW_RTT, "id");  // Becomes writable and receiving
  EXPECT_EQ_SIMULATED_WAIT(conn1, ch.selected_connection(), kDefaultTimeout,
                           clock);

  // Add a low-priority connection |conn2|, which will be pruned, but it will
  // not be deleted right away. Once the current selected connection becomes not
  // receiving, |conn2| will start to ping and upon receiving the ping response,
  // it will become the selected connection.
  ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
  Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2, &clock);
  ASSERT_TRUE(conn2 != nullptr);
  EXPECT_TRUE_SIMULATED_WAIT(!conn2->active(), kDefaultTimeout, clock);
  // |conn2| should not send a ping yet.
  EXPECT_EQ(IceCandidatePairState::WAITING, conn2->state());
  EXPECT_EQ(IceTransportState::STATE_COMPLETED, ch.GetState());
  // Wait for |conn1| becoming not receiving.
  EXPECT_TRUE_SIMULATED_WAIT(!conn1->receiving(), kMediumTimeout, clock);
  // Make sure conn2 is not deleted.
  conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2, &clock);
  ASSERT_TRUE(conn2 != nullptr);
  EXPECT_EQ_SIMULATED_WAIT(IceCandidatePairState::IN_PROGRESS, conn2->state(),
                           kDefaultTimeout, clock);
  conn2->ReceivedPingResponse(LOW_RTT, "id");
  EXPECT_EQ_SIMULATED_WAIT(conn2, ch.selected_connection(), kDefaultTimeout,
                           clock);
  EXPECT_EQ(IceTransportState::STATE_CONNECTING, ch.GetState());

  // When |conn1| comes back again, |conn2| will be pruned again.
  conn1->ReceivedPingResponse(LOW_RTT, "id");
  EXPECT_EQ_SIMULATED_WAIT(conn1, ch.selected_connection(), kDefaultTimeout,
                           clock);
  EXPECT_TRUE_SIMULATED_WAIT(!conn2->active(), kDefaultTimeout, clock);
  EXPECT_EQ(IceTransportState::STATE_COMPLETED, ch.GetState());
}

// Test that if all connections in a channel has timed out on writing, they
// will all be deleted. We use Prune to simulate write_time_out.
TEST_F(P2PTransportChannelPingTest, TestDeleteConnectionsIfAllWriteTimedout) {
  rtc::ScopedFakeClock clock;
  FakePortAllocator pa(rtc::Thread::Current(), nullptr);
  P2PTransportChannel ch("test channel", 1, &pa);
  PrepareChannel(&ch);
  ch.MaybeStartGathering();
  // Have one connection only but later becomes write-time-out.
  ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
  Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1, &clock);
  ASSERT_TRUE(conn1 != nullptr);
  conn1->ReceivedPing();  // Becomes receiving
  conn1->Prune();
  EXPECT_TRUE_SIMULATED_WAIT(ch.connections().empty(), kShortTimeout, clock);

  // Have two connections but both become write-time-out later.
  ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 1));
  Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2, &clock);
  ASSERT_TRUE(conn2 != nullptr);
  conn2->ReceivedPing();  // Becomes receiving
  ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "3.3.3.3", 3, 2));
  Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3, &clock);
  ASSERT_TRUE(conn3 != nullptr);
  conn3->ReceivedPing();  // Becomes receiving
  // Now prune both conn2 and conn3; they will be deleted soon.
  conn2->Prune();
  conn3->Prune();
  EXPECT_TRUE_SIMULATED_WAIT(ch.connections().empty(), kShortTimeout, clock);
}

// Tests that after a port allocator session is started, it will be stopped
// when a new connection becomes writable and receiving. Also tests that if a
// connection belonging to an old session becomes writable, it won't stop
// the current port allocator session.
TEST_F(P2PTransportChannelPingTest, TestStopPortAllocatorSessions) {
  FakePortAllocator pa(rtc::Thread::Current(), nullptr);
  P2PTransportChannel ch("test channel", 1, &pa);
  PrepareChannel(&ch);
  ch.SetIceConfig(CreateIceConfig(2000, GATHER_ONCE));
  ch.MaybeStartGathering();
  ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
  Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
  ASSERT_TRUE(conn1 != nullptr);
  conn1->ReceivedPingResponse(LOW_RTT, "id");  // Becomes writable and receiving
  EXPECT_TRUE(!ch.allocator_session()->IsGettingPorts());

  // Start a new session. Even though conn1, which belongs to an older
  // session, becomes unwritable and writable again, it should not stop the
  // current session.
  ch.SetIceParameters(kIceParams[1]);
  ch.MaybeStartGathering();
  conn1->Prune();
  conn1->ReceivedPingResponse(LOW_RTT, "id");
  EXPECT_TRUE(ch.allocator_session()->IsGettingPorts());

  // But if a new connection created from the new session becomes writable,
  // it will stop the current session.
  ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 100));
  Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
  ASSERT_TRUE(conn2 != nullptr);
  conn2->ReceivedPingResponse(LOW_RTT, "id");  // Becomes writable and receiving
  EXPECT_TRUE(!ch.allocator_session()->IsGettingPorts());
}

// Test that the ICE role is updated even on ports that has been removed.
// These ports may still have connections that need a correct role, in case that
// the connections on it may still receive stun pings.
TEST_F(P2PTransportChannelPingTest, TestIceRoleUpdatedOnRemovedPort) {
  FakePortAllocator pa(rtc::Thread::Current(), nullptr);
  P2PTransportChannel ch("test channel", ICE_CANDIDATE_COMPONENT_DEFAULT, &pa);
  // Starts with ICEROLE_CONTROLLING.
  PrepareChannel(&ch);
  IceConfig config = CreateIceConfig(1000, GATHER_CONTINUALLY);
  ch.SetIceConfig(config);
  ch.MaybeStartGathering();
  ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));

  Connection* conn = WaitForConnectionTo(&ch, "1.1.1.1", 1);
  ASSERT_TRUE(conn != nullptr);

  // Make a fake signal to remove the ports in the p2ptransportchannel. then
  // change the ICE role and expect it to be updated.
  std::vector<PortInterface*> ports(1, conn->port());
  ch.allocator_session()->SignalPortsPruned(ch.allocator_session(), ports);
  ch.SetIceRole(ICEROLE_CONTROLLED);
  EXPECT_EQ(ICEROLE_CONTROLLED, conn->port()->GetIceRole());
}

// Test that the ICE role is updated even on ports with inactive networks.
// These ports may still have connections that need a correct role, for the
// pings sent by those connections until they're replaced by newer-generation
// connections.
TEST_F(P2PTransportChannelPingTest, TestIceRoleUpdatedOnPortAfterIceRestart) {
  FakePortAllocator pa(rtc::Thread::Current(), nullptr);
  P2PTransportChannel ch("test channel", ICE_CANDIDATE_COMPONENT_DEFAULT, &pa);
  // Starts with ICEROLE_CONTROLLING.
  PrepareChannel(&ch);
  ch.MaybeStartGathering();
  ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));

  Connection* conn = WaitForConnectionTo(&ch, "1.1.1.1", 1);
  ASSERT_TRUE(conn != nullptr);

  // Do an ICE restart, change the role, and expect the old port to have its
  // role updated.
  ch.SetIceParameters(kIceParams[1]);
  ch.MaybeStartGathering();
  ch.SetIceRole(ICEROLE_CONTROLLED);
  EXPECT_EQ(ICEROLE_CONTROLLED, conn->port()->GetIceRole());
}

// Test that after some amount of time without receiving data, the connection
// will be destroyed. The port will only be destroyed after it is marked as
// "pruned."
TEST_F(P2PTransportChannelPingTest, TestPortDestroyedAfterTimeoutAndPruned) {
  rtc::ScopedFakeClock fake_clock;

  FakePortAllocator pa(rtc::Thread::Current(), nullptr);
  P2PTransportChannel ch("test channel", ICE_CANDIDATE_COMPONENT_DEFAULT, &pa);
  PrepareChannel(&ch);
  ch.SetIceRole(ICEROLE_CONTROLLED);
  ch.MaybeStartGathering();
  ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));

  Connection* conn = WaitForConnectionTo(&ch, "1.1.1.1", 1);
  ASSERT_TRUE(conn != nullptr);

  // Simulate 2 minutes going by. This should be enough time for the port to
  // time out.
  for (int second = 0; second < 120; ++second) {
    fake_clock.AdvanceTime(webrtc::TimeDelta::seconds(1));
  }
  EXPECT_EQ(nullptr, GetConnectionTo(&ch, "1.1.1.1", 1));
  // Port will not be removed because it is not pruned yet.
  PortInterface* port = GetPort(&ch);
  ASSERT_NE(nullptr, port);

  // If the session prunes all ports, the port will be destroyed.
  ch.allocator_session()->PruneAllPorts();
  EXPECT_EQ_SIMULATED_WAIT(nullptr, GetPort(&ch), 1, fake_clock);
  EXPECT_EQ_SIMULATED_WAIT(nullptr, GetPrunedPort(&ch), 1, fake_clock);
}

class P2PTransportChannelMostLikelyToWorkFirstTest
    : public P2PTransportChannelPingTest {
 public:
  P2PTransportChannelMostLikelyToWorkFirstTest()
      : turn_server_(rtc::Thread::Current(), kTurnUdpIntAddr, kTurnUdpExtAddr) {
    network_manager_.AddInterface(kPublicAddrs[0]);
    allocator_.reset(
        CreateBasicPortAllocator(&network_manager_, ServerAddresses(),
                                 kTurnUdpIntAddr, rtc::SocketAddress()));
    allocator_->set_flags(allocator_->flags() | PORTALLOCATOR_DISABLE_STUN |
                          PORTALLOCATOR_DISABLE_TCP);
    allocator_->set_step_delay(kMinimumStepDelay);
  }

  P2PTransportChannel& StartTransportChannel(
      bool prioritize_most_likely_to_work,
      int stable_writable_connection_ping_interval) {
    channel_.reset(new P2PTransportChannel("checks", 1, allocator()));
    IceConfig config = channel_->config();
    config.prioritize_most_likely_candidate_pairs =
        prioritize_most_likely_to_work;
    config.stable_writable_connection_ping_interval =
        stable_writable_connection_ping_interval;
    channel_->SetIceConfig(config);
    PrepareChannel(channel_.get());
    channel_->MaybeStartGathering();
    return *channel_.get();
  }

  BasicPortAllocator* allocator() { return allocator_.get(); }
  TestTurnServer* turn_server() { return &turn_server_; }

  // This verifies the next pingable connection has the expected candidates'
  // types and, for relay local candidate, the expected relay protocol and ping
  // it.
  void VerifyNextPingableConnection(
      const std::string& local_candidate_type,
      const std::string& remote_candidate_type,
      const std::string& relay_protocol_type = UDP_PROTOCOL_NAME) {
    Connection* conn = FindNextPingableConnectionAndPingIt(channel_.get());
    EXPECT_EQ(conn->local_candidate().type(), local_candidate_type);
    if (conn->local_candidate().type() == RELAY_PORT_TYPE) {
      EXPECT_EQ(conn->local_candidate().relay_protocol(), relay_protocol_type);
    }
    EXPECT_EQ(conn->remote_candidate().type(), remote_candidate_type);
  }

 private:
  std::unique_ptr<BasicPortAllocator> allocator_;
  rtc::FakeNetworkManager network_manager_;
  TestTurnServer turn_server_;
  std::unique_ptr<P2PTransportChannel> channel_;
};

// Test that Relay/Relay connections will be pinged first when no other
// connections have been pinged yet, unless we need to ping a trigger check or
// we have a selected connection.
TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest,
       TestRelayRelayFirstWhenNothingPingedYet) {
  const int max_strong_interval = 500;
  P2PTransportChannel& ch = StartTransportChannel(true, max_strong_interval);
  EXPECT_TRUE_WAIT(ch.ports().size() == 2, kDefaultTimeout);
  EXPECT_EQ(ch.ports()[0]->Type(), LOCAL_PORT_TYPE);
  EXPECT_EQ(ch.ports()[1]->Type(), RELAY_PORT_TYPE);

  ch.AddRemoteCandidate(CreateUdpCandidate(RELAY_PORT_TYPE, "1.1.1.1", 1, 1));
  ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));

  EXPECT_TRUE_WAIT(ch.connections().size() == 4, kDefaultTimeout);

  // Relay/Relay should be the first pingable connection.
  Connection* conn = FindNextPingableConnectionAndPingIt(&ch);
  EXPECT_EQ(conn->local_candidate().type(), RELAY_PORT_TYPE);
  EXPECT_EQ(conn->remote_candidate().type(), RELAY_PORT_TYPE);

  // Unless that we have a trigger check waiting to be pinged.
  Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2);
  EXPECT_EQ(conn2->local_candidate().type(), LOCAL_PORT_TYPE);
  EXPECT_EQ(conn2->remote_candidate().type(), LOCAL_PORT_TYPE);
  conn2->ReceivedPing();
  EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch));

  // Make conn3 the selected connection.
  Connection* conn3 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
  EXPECT_EQ(conn3->local_candidate().type(), LOCAL_PORT_TYPE);
  EXPECT_EQ(conn3->remote_candidate().type(), RELAY_PORT_TYPE);
  conn3->ReceivedPingResponse(LOW_RTT, "id");
  ASSERT_TRUE(conn3->writable());
  conn3->ReceivedPing();

  /*

  TODO(honghaiz): Re-enable this once we use fake clock for this test to fix
  the flakiness. The following test becomes flaky because we now ping the
  connections with fast rates until every connection is pinged at least three
  times. The selected connection may have been pinged before
  |max_strong_interval|, so it may not be the next connection to be pinged as
  expected in the test.

  // Verify that conn3 will be the "selected connection" since it is readable
  // and writable. After |MAX_CURRENT_STRONG_INTERVAL|, it should be the next
  // pingable connection.
  EXPECT_TRUE_WAIT(conn3 == ch.selected_connection(), kDefaultTimeout);
  WAIT(false, max_strong_interval + 100);
  conn3->ReceivedPingResponse(LOW_RTT, "id");
  ASSERT_TRUE(conn3->writable());
  EXPECT_EQ(conn3, FindNextPingableConnectionAndPingIt(&ch));

  */
}

// Test that Relay/Relay connections will be pinged first when everything has
// been pinged even if the Relay/Relay connection wasn't the first to be pinged
// in the first round.
TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest,
       TestRelayRelayFirstWhenEverythingPinged) {
  P2PTransportChannel& ch = StartTransportChannel(true, 500);
  EXPECT_TRUE_WAIT(ch.ports().size() == 2, kDefaultTimeout);
  EXPECT_EQ(ch.ports()[0]->Type(), LOCAL_PORT_TYPE);
  EXPECT_EQ(ch.ports()[1]->Type(), RELAY_PORT_TYPE);

  ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 1));
  EXPECT_TRUE_WAIT(ch.connections().size() == 2, kDefaultTimeout);

  // Initially, only have Local/Local and Local/Relay.
  VerifyNextPingableConnection(LOCAL_PORT_TYPE, LOCAL_PORT_TYPE);
  VerifyNextPingableConnection(RELAY_PORT_TYPE, LOCAL_PORT_TYPE);

  // Remote Relay candidate arrives.
  ch.AddRemoteCandidate(CreateUdpCandidate(RELAY_PORT_TYPE, "2.2.2.2", 2, 2));
  EXPECT_TRUE_WAIT(ch.connections().size() == 4, kDefaultTimeout);

  // Relay/Relay should be the first since it hasn't been pinged before.
  VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);

  // Local/Relay is the final one.
  VerifyNextPingableConnection(LOCAL_PORT_TYPE, RELAY_PORT_TYPE);

  // Now, every connection has been pinged once. The next one should be
  // Relay/Relay.
  VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
}

// Test that when we receive a new remote candidate, they will be tried first
// before we re-ping Relay/Relay connections again.
TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest,
       TestNoStarvationOnNonRelayConnection) {
  P2PTransportChannel& ch = StartTransportChannel(true, 500);
  EXPECT_TRUE_WAIT(ch.ports().size() == 2, kDefaultTimeout);
  EXPECT_EQ(ch.ports()[0]->Type(), LOCAL_PORT_TYPE);
  EXPECT_EQ(ch.ports()[1]->Type(), RELAY_PORT_TYPE);

  ch.AddRemoteCandidate(CreateUdpCandidate(RELAY_PORT_TYPE, "1.1.1.1", 1, 1));
  EXPECT_TRUE_WAIT(ch.connections().size() == 2, kDefaultTimeout);

  // Initially, only have Relay/Relay and Local/Relay. Ping Relay/Relay first.
  VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);

  // Next, ping Local/Relay.
  VerifyNextPingableConnection(LOCAL_PORT_TYPE, RELAY_PORT_TYPE);

  // Remote Local candidate arrives.
  ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "2.2.2.2", 2, 2));
  EXPECT_TRUE_WAIT(ch.connections().size() == 4, kDefaultTimeout);

  // Local/Local should be the first since it hasn't been pinged before.
  VerifyNextPingableConnection(LOCAL_PORT_TYPE, LOCAL_PORT_TYPE);

  // Relay/Local is the final one.
  VerifyNextPingableConnection(RELAY_PORT_TYPE, LOCAL_PORT_TYPE);

  // Now, every connection has been pinged once. The next one should be
  // Relay/Relay.
  VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);
}

// Test the ping sequence is UDP Relay/Relay followed by TCP Relay/Relay,
// followed by the rest.
TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest, TestTcpTurn) {
  // Add a Tcp Turn server.
  turn_server()->AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
  RelayServerConfig config(RELAY_TURN);
  config.credentials = kRelayCredentials;
  config.ports.push_back(ProtocolAddress(kTurnTcpIntAddr, PROTO_TCP));
  allocator()->AddTurnServer(config);

  P2PTransportChannel& ch = StartTransportChannel(true, 500);
  EXPECT_TRUE_WAIT(ch.ports().size() == 3, kDefaultTimeout);
  EXPECT_EQ(ch.ports()[0]->Type(), LOCAL_PORT_TYPE);
  EXPECT_EQ(ch.ports()[1]->Type(), RELAY_PORT_TYPE);
  EXPECT_EQ(ch.ports()[2]->Type(), RELAY_PORT_TYPE);

  // Remote Relay candidate arrives.
  ch.AddRemoteCandidate(CreateUdpCandidate(RELAY_PORT_TYPE, "1.1.1.1", 1, 1));
  EXPECT_TRUE_WAIT(ch.connections().size() == 3, kDefaultTimeout);

  // UDP Relay/Relay should be pinged first.
  VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE);

  // TCP Relay/Relay is the next.
  VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE,
                               TCP_PROTOCOL_NAME);

  // Finally, Local/Relay will be pinged.
  VerifyNextPingableConnection(LOCAL_PORT_TYPE, RELAY_PORT_TYPE);
}

// Test that a resolver is created, asked for a result, and destroyed
// when the address is a hostname.
TEST(P2PTransportChannelResolverTest, HostnameCandidateIsResolved) {
  rtc::MockAsyncResolver mock_async_resolver;
  EXPECT_CALL(mock_async_resolver, GetError()).WillOnce(Return(0));
  EXPECT_CALL(mock_async_resolver, GetResolvedAddress(_, _))
      .WillOnce(Return(true));
  EXPECT_CALL(mock_async_resolver, Destroy(_));
  webrtc::MockAsyncResolverFactory mock_async_resolver_factory;
  EXPECT_CALL(mock_async_resolver_factory, Create())
      .WillOnce(Return(&mock_async_resolver));

  P2PTransportChannel channel("tn", 0, /*allocator*/ nullptr,
                              &mock_async_resolver_factory);
  Candidate hostname_candidate;
  SocketAddress hostname_address("fake.test", 1000);
  hostname_candidate.set_address(hostname_address);
  channel.AddRemoteCandidate(hostname_candidate);

  ASSERT_EQ_WAIT(1u, channel.remote_candidates().size(), kDefaultTimeout);
  const RemoteCandidate& candidate = channel.remote_candidates()[0];
  EXPECT_FALSE(candidate.address().IsUnresolvedIP());
}

TEST_F(P2PTransportChannelTest,
       PeerReflexiveCandidateBeforeSignalingWithHostname) {
  rtc::MockAsyncResolver mock_async_resolver;
  webrtc::MockAsyncResolverFactory mock_async_resolver_factory;
  EXPECT_CALL(mock_async_resolver_factory, Create())
      .WillOnce(Return(&mock_async_resolver));

  ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts);
  // Emulate no remote parameters coming in.
  set_remote_ice_parameter_source(FROM_CANDIDATE);
  GetEndpoint(0)->async_resolver_factory_ = &mock_async_resolver_factory;
  CreateChannels();
  // Only have remote parameters come in for ep2, not ep1.
  ep2_ch1()->SetRemoteIceParameters(kIceParams[0]);

  // Pause sending ep2's candidates to ep1 until ep1 receives the peer reflexive
  // candidate.
  PauseCandidates(1);

  // Wait until the callee becomes writable to make sure that a ping request is
  // received by the caller before his remote ICE credentials are set.
  ASSERT_TRUE_WAIT(ep2_ch1()->selected_connection() != nullptr, kMediumTimeout);
  ep1_ch1()->SetRemoteIceParameters(kIceParams[1]);
  // The caller should have the selected connection connected to the peer
  // reflexive candidate.
  const Connection* selected_connection = nullptr;
  ASSERT_TRUE_WAIT(
      (selected_connection = ep1_ch1()->selected_connection()) != nullptr,
      kMediumTimeout);
  EXPECT_EQ(PRFLX_PORT_TYPE, selected_connection->remote_candidate().type());
  EXPECT_EQ(kIceUfrag[1], selected_connection->remote_candidate().username());
  EXPECT_EQ(kIcePwd[1], selected_connection->remote_candidate().password());

  SocketAddress hostname_address("fake.hostname", 12345);
  SocketAddress ip_address =
      ReplaceSavedCandidateIpWithHostname(1, hostname_address);
  EXPECT_CALL(mock_async_resolver, GetError()).WillOnce(Return(0));
  EXPECT_CALL(mock_async_resolver, GetResolvedAddress(_, _))
      .WillOnce(DoAll(SetArgPointee<1>(ip_address), Return(true)));
  EXPECT_CALL(mock_async_resolver, Destroy(_));

  ResumeCandidates(1);
  // Verify ep1's selected connection is updated to use the 'local' candidate.
  EXPECT_EQ_WAIT(LOCAL_PORT_TYPE,
                 ep1_ch1()->selected_connection()->remote_candidate().type(),
                 kMediumTimeout);
  EXPECT_EQ(selected_connection, ep1_ch1()->selected_connection());
  DestroyChannels();
}

}  // namespace cricket
