/*
 *  Copyright 2012 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 "p2p/base/turn_port.h"

#include <algorithm>
#include <array>
#include <cstddef>
#include <cstdint>
#include <list>
#include <memory>
#include <optional>
#include <span>
#include <string>
#include <utility>
#include <vector>

#include "absl/functional/any_invocable.h"
#include "absl/strings/string_view.h"
#include "api/candidate.h"
#include "api/environment/environment.h"
#include "api/packet_socket_factory.h"
#include "api/test/mock_async_dns_resolver.h"
#include "api/test/rtc_error_matchers.h"
#include "api/transport/ecn_marking.h"
#include "api/transport/stun.h"
#include "api/units/time_delta.h"
#include "api/units/timestamp.h"
#include "p2p/base/basic_packet_socket_factory.h"
#include "p2p/base/connection.h"
#include "p2p/base/connection_info.h"
#include "p2p/base/p2p_constants.h"
#include "p2p/base/port.h"
#include "p2p/base/port_allocator.h"
#include "p2p/base/port_interface.h"
#include "p2p/base/stun_port.h"
#include "p2p/base/stun_request.h"
#include "p2p/base/transport_description.h"
#include "p2p/client/relay_port_factory_interface.h"
#include "p2p/test/mock_dns_resolving_packet_socket_factory.h"
#include "p2p/test/test_turn_customizer.h"
#include "p2p/test/test_turn_server.h"
#include "p2p/test/turn_server.h"
#include "rtc_base/async_packet_socket.h"
#include "rtc_base/buffer.h"
#include "rtc_base/byte_buffer.h"
#include "rtc_base/checks.h"
#include "rtc_base/ip_address.h"
#include "rtc_base/net_helper.h"
#include "rtc_base/net_helpers.h"
#include "rtc_base/network.h"
#include "rtc_base/network/received_packet.h"
#include "rtc_base/socket.h"
#include "rtc_base/socket_address.h"
#include "rtc_base/thread.h"
#include "rtc_base/virtual_socket_server.h"
#include "system_wrappers/include/metrics.h"
#include "test/create_test_environment.h"
#include "test/gmock.h"
#include "test/gtest.h"
#include "test/time_controller/simulated_time_controller.h"
#include "test/wait_until.h"

#if defined(WEBRTC_POSIX)
#include <dirent.h>  // IWYU pragma: keep
#endif

namespace webrtc {

namespace {
using ::testing::_;
using ::testing::DoAll;
using ::testing::Eq;
using ::testing::IsTrue;
using ::testing::Ne;
using ::testing::Return;
using ::testing::ReturnPointee;
using ::testing::SetArgPointee;

const SocketAddress kLocalAddr1("11.11.11.11", 0);
const SocketAddress kLocalAddr2("22.22.22.22", 0);
const SocketAddress kLocalIPv6Addr("2401:fa00:4:1000:be30:5bff:fee5:c3", 0);
const SocketAddress kLocalIPv6Addr2("2401:fa00:4:2000:be30:5bff:fee5:d4", 0);
const SocketAddress kTurnUdpIntAddr("99.99.99.3", TURN_SERVER_PORT);
const SocketAddress kTurnTcpIntAddr("99.99.99.4", TURN_SERVER_PORT);
const SocketAddress kTurnUdpExtAddr("99.99.99.5", 0);
const SocketAddress kTurnAlternateIntAddr("99.99.99.6", TURN_SERVER_PORT);
// Port for redirecting to a TCP Web server. Should not work.
const SocketAddress kTurnDangerousAddr("99.99.99.7", 81);
// Port 53 (the DNS port); should work.
const SocketAddress kTurnPort53Addr("99.99.99.7", 53);
// Port 80 (the HTTP port); should work.
const SocketAddress kTurnPort80Addr("99.99.99.7", 80);
// Port 443 (the HTTPS port); should work.
const SocketAddress kTurnPort443Addr("99.99.99.7", 443);
// The default TURN server port.
const SocketAddress kTurnIntAddr("99.99.99.7", TURN_SERVER_PORT);
const SocketAddress kTurnIPv6IntAddr("2400:4030:2:2c00:be30:abcd:efab:cdef",
                                     TURN_SERVER_PORT);
const SocketAddress kTurnUdpIPv6IntAddr("2400:4030:1:2c00:be30:abcd:efab:cdef",
                                        TURN_SERVER_PORT);
const SocketAddress kTurnInvalidAddr("www.google.invalid.", 3478);
const SocketAddress kTurnValidAddr("www.google.valid.", 3478);

constexpr char kCandidateFoundation[] = "foundation";
constexpr char kIceUfrag1[] = "TESTICEUFRAG0001";
constexpr char kIceUfrag2[] = "TESTICEUFRAG0002";
constexpr char kIcePwd1[] = "TESTICEPWD00000000000001";
constexpr char kIcePwd2[] = "TESTICEPWD00000000000002";
constexpr char kTurnUsername[] = "test";
constexpr char kTurnPassword[] = "test";
// This test configures the virtual socket server to simulate delay so that we
// can verify operations take no more than the expected number of round trips.
constexpr TimeDelta kSimulatedRtt = TimeDelta::Millis(50);
// Connection destruction may happen asynchronously, but it should only
// take one simulated clock tick.
constexpr TimeDelta kConnectionDestructionDelay = TimeDelta::Millis(1);
// This used to be 1 second, but that's not always enough for getaddrinfo().
// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5191
constexpr TimeDelta kResolverTimeout = TimeDelta::Millis(10000);

constexpr uint64_t kTiebreakerDefault = 44444;

const ProtocolAddress kTurnUdpProtoAddr(kTurnUdpIntAddr, PROTO_UDP);
const ProtocolAddress kTurnTcpProtoAddr(kTurnTcpIntAddr, PROTO_TCP);
const ProtocolAddress kTurnTlsProtoAddr(kTurnTcpIntAddr, PROTO_TLS);
const ProtocolAddress kTurnUdpIPv6ProtoAddr(kTurnUdpIPv6IntAddr, PROTO_UDP);
const ProtocolAddress kTurnDangerousProtoAddr(kTurnDangerousAddr, PROTO_TCP);
const ProtocolAddress kTurnPort53ProtoAddr(kTurnPort53Addr, PROTO_TCP);
const ProtocolAddress kTurnPort80ProtoAddr(kTurnPort80Addr, PROTO_TCP);
const ProtocolAddress kTurnPort443ProtoAddr(kTurnPort443Addr, PROTO_TCP);
const ProtocolAddress kTurnPortInvalidHostnameProtoAddr(kTurnInvalidAddr,
                                                        PROTO_UDP);
const ProtocolAddress kTurnPortValidHostnameProtoAddr(kTurnValidAddr,
                                                      PROTO_UDP);

#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
int GetFDCount() {
  struct dirent* dp;
  int fd_count = 0;
  DIR* dir = opendir("/proc/self/fd/");
  while ((dp = readdir(dir)) != nullptr) {
    if (dp->d_name[0] == '.')
      continue;
    ++fd_count;
  }
  closedir(dir);
  return fd_count;
}
#endif

}  // unnamed namespace

class TurnPortTestVirtualSocketServer : public VirtualSocketServer {
 public:
  TurnPortTestVirtualSocketServer() {
    // This configures the virtual socket server to always add a simulated
    // delay of exactly half of kSimulatedRtt.
    set_delay_mean((kSimulatedRtt / 2).ms());
    UpdateDelayDistribution();
  }

  using VirtualSocketServer::LookupBinding;
};

class TestConnectionWrapper {
 public:
  explicit TestConnectionWrapper(Connection* conn) : connection_(conn) {
    conn->SubscribeDestroyed(this, [this](Connection* connection) {
      OnConnectionDestroyed(connection);
    });
  }

  ~TestConnectionWrapper() {
    if (connection_) {
      connection_->UnsubscribeDestroyed(this);
    }
  }

  Connection* connection() { return connection_; }

 private:
  void OnConnectionDestroyed(Connection* conn) {
    ASSERT_TRUE(conn == connection_);
    connection_ = nullptr;
  }

  Connection* connection_;
};

// Note: This test uses a fake clock with a simulated network round trip
// (between local port and TURN server) of kSimulatedRtt.
class TurnPortTest : public ::testing::Test, public TurnPort::CallbacksForTest {
 public:
  TurnPortTest()
      : ss_(new TurnPortTestVirtualSocketServer()),
        time_controller_(Timestamp::Seconds(1), ss_.get()),
        env_(CreateTestEnvironment({.time = &time_controller_})),
        main_(time_controller_.GetMainThread()),
        turn_server_(env_, main_, ss_.get(), kTurnUdpIntAddr, kTurnUdpExtAddr),
        socket_factory_(ss_.get()) {}

  void OnTurnPortComplete(Port* port) { turn_ready_ = true; }
  void OnTurnPortError(Port* port) { turn_error_ = true; }
  void OnCandidateError(Port* port, const IceCandidateErrorEvent& event) {
    error_event_ = event;
  }
  void OnTurnUnknownAddress(PortInterface* port,
                            const SocketAddress& addr,
                            ProtocolType proto,
                            IceMessage* msg,
                            const std::string& rf,
                            bool /*port_muxed*/) {
    turn_unknown_address_ = true;
  }
  void OnUdpPortComplete(Port* port) { udp_ready_ = true; }
  void OnSocketReadPacket(AsyncPacketSocket* socket,
                          const ReceivedIpPacket& packet) {
    turn_port_->HandleIncomingPacket(socket, packet);
  }
  void OnTurnPortDestroyed(PortInterface* port) { turn_port_destroyed_ = true; }

  // TurnPort::TestCallbacks
  void OnTurnCreatePermissionResult(int code) override {
    turn_create_permission_success_ = (code == 0);
  }
  void OnTurnRefreshResult(int code) override {
    turn_refresh_success_ = (code == 0);
  }
  void OnTurnPortClosed() override { turn_port_closed_ = true; }

  void OnConnectionSignalDestroyed(Connection* connection) {
    connection->DeregisterReceivedPacketCallback();
  }

  Socket* CreateServerSocket(const SocketAddress addr) {
    Socket* socket = ss_->CreateSocket(AF_INET, SOCK_STREAM);
    EXPECT_GE(socket->Bind(addr), 0);
    EXPECT_GE(socket->Listen(5), 0);
    return socket;
  }

  Network* MakeNetwork(const SocketAddress& addr) {
    networks_.emplace_back("unittest", "unittest", addr.ipaddr(), 32);
    networks_.back().AddIP(addr.ipaddr());
    return &networks_.back();
  }

  bool CreateTurnPort(absl::string_view username,
                      absl::string_view password,
                      const ProtocolAddress& server_address) {
    return CreateTurnPortWithAllParams(MakeNetwork(kLocalAddr1), username,
                                       password, server_address);
  }
  bool CreateTurnPort(const SocketAddress& local_address,
                      absl::string_view username,
                      absl::string_view password,
                      const ProtocolAddress& server_address) {
    return CreateTurnPortWithAllParams(MakeNetwork(local_address), username,
                                       password, server_address);
  }

  bool CreateTurnPortWithNetwork(const Network* network,
                                 absl::string_view username,
                                 absl::string_view password,
                                 const ProtocolAddress& server_address) {
    return CreateTurnPortWithAllParams(network, username, password,
                                       server_address);
  }

  // Version of CreateTurnPort that takes all possible parameters; all other
  // helper methods call this, such that "SetIceRole" and "ConnectSignals" (and
  // possibly other things in the future) only happen in one place.
  bool CreateTurnPortWithAllParams(const Network* network,
                                   absl::string_view username,
                                   absl::string_view password,
                                   const ProtocolAddress& server_address) {
    RelayServerConfig config;
    config.credentials = RelayCredentials(username, password);
    CreateRelayPortArgs args = {.env = env_};
    args.network_thread = main_;
    args.socket_factory = socket_factory();
    args.network = network;
    args.username = kIceUfrag1;
    args.password = kIcePwd1;
    args.server_address = &server_address;
    args.config = &config;
    args.turn_customizer = turn_customizer_.get();

    turn_port_ = TurnPort::Create(args, 0, 0);
    if (!turn_port_) {
      return false;
    }
    // This TURN port will be the controlling.
    turn_port_->SetIceRole(ICEROLE_CONTROLLING);
    turn_port_->SetIceTiebreaker(kTiebreakerDefault);
    turn_port_->SetOption(Socket::OPT_RECV_ECN, 1);
    ConnectSignals();

    if (server_address.proto == PROTO_TLS) {
      // The test TURN server has a self-signed certificate so will not pass
      // the normal client validation. Instruct the client to ignore certificate
      // errors for testing only.
      turn_port_->SetTlsCertPolicy(
          TlsCertPolicy::TLS_CERT_POLICY_INSECURE_NO_CHECK);
    }
    return true;
  }

  void CreateSharedTurnPort(absl::string_view username,
                            absl::string_view password,
                            const ProtocolAddress& server_address) {
    RTC_CHECK(server_address.proto == PROTO_UDP);

    if (!socket_) {
      socket_ = socket_factory()->CreateUdpSocket(
          env_, SocketAddress(kLocalAddr1.ipaddr(), 0), 0, 0);
      ASSERT_TRUE(socket_ != nullptr);
      socket_->RegisterReceivedPacketCallback(
          [&](AsyncPacketSocket* socket, const ReceivedIpPacket& packet) {
            OnSocketReadPacket(socket, packet);
          });
    }

    RelayServerConfig config;
    config.credentials = RelayCredentials(username, password);
    CreateRelayPortArgs args = {.env = env_};
    args.network_thread = main_;
    args.socket_factory = socket_factory();
    args.network = MakeNetwork(kLocalAddr1);
    args.username = kIceUfrag1;
    args.password = kIcePwd1;
    args.server_address = &server_address;
    args.config = &config;
    args.turn_customizer = turn_customizer_.get();
    turn_port_ = TurnPort::Create(args, socket_.get());
    // This TURN port will be the controlling.
    turn_port_->SetIceRole(ICEROLE_CONTROLLING);
    turn_port_->SetIceTiebreaker(kTiebreakerDefault);
    ConnectSignals();
  }

  void ConnectSignals() {
    turn_port_->SubscribePortComplete(
        this, [this](Port* port) { OnTurnPortComplete(port); });
    turn_port_->SubscribePortError(
        this, [this](Port* port) { OnTurnPortError(port); });
    turn_port_->SubscribeCandidateError(
        this, [this](Port* port, const IceCandidateErrorEvent& event) {
          OnCandidateError(port, event);
        });
    turn_port_->SubscribeUnknownAddress(
        this, [this](PortInterface* port, const SocketAddress& address,
                     ProtocolType proto, IceMessage* stun_msg,
                     const std::string& rf, bool port_muxed) {
          OnTurnUnknownAddress(port, address, proto, stun_msg, rf, port_muxed);
        });
    turn_port_->SubscribePortDestroyed(
        this, [this](PortInterface* port) { OnTurnPortDestroyed(port); });
    turn_port_->SetCallbacksForTest(this);
  }

  void CreateUdpPort() { CreateUdpPort(kLocalAddr2); }

  void CreateUdpPort(const SocketAddress& address) {
    udp_port_ = UDPPort::Create({.env = env_,
                                 .network_thread = main_,
                                 .socket_factory = socket_factory(),
                                 .network = MakeNetwork(address),
                                 .ice_username_fragment = kIceUfrag2,
                                 .ice_password = kIcePwd2},
                                0, 0, false, std::nullopt);
    // UDP port will be controlled.
    udp_port_->SetIceRole(ICEROLE_CONTROLLED);
    udp_port_->SetIceTiebreaker(kTiebreakerDefault);
    udp_port_->SubscribePortComplete(
        this, [this](Port* port) { OnUdpPortComplete(port); });
    udp_port_->SetOption(Socket::OPT_RECV_ECN, 1);
  }

  void PrepareTurnAndUdpPorts(ProtocolType protocol_type) {
    // turn_port_ should have been created.
    ASSERT_TRUE(turn_port_ != nullptr);
    turn_port_->PrepareAddress();
    ASSERT_THAT(WaitUntil([&] { return turn_ready_; }, IsTrue(),
                          {.timeout = TimeToGetTurnCandidate(protocol_type),
                           .clock = &time_controller_}),
                IsRtcOk());

    CreateUdpPort();
    udp_port_->PrepareAddress();
    ASSERT_THAT(
        WaitUntil([&] { return udp_ready_; }, IsTrue(),
                  {.timeout = kSimulatedRtt, .clock = &time_controller_}),
        IsRtcOk());
  }

  // Returns the fake clock time to establish a connection over the given
  // protocol.
  TimeDelta TimeToConnect(ProtocolType protocol_type) {
    switch (protocol_type) {
      case PROTO_TCP:
        // The virtual socket server will delay by a fixed half a round trip
        // for a TCP connection.
        return kSimulatedRtt / 2;
      case PROTO_TLS:
        // TLS operates over TCP and additionally has a round of HELLO for
        // negotiating ciphers and a round for exchanging certificates.
        return 2 * kSimulatedRtt + TimeToConnect(PROTO_TCP);
      case PROTO_UDP:
      default:
        // UDP requires no round trips to set up the connection.
        return TimeDelta::Zero();
    }
  }

  // Returns the total fake clock time to establish a connection with a TURN
  // server over the given protocol and to allocate a TURN candidate.
  TimeDelta TimeToGetTurnCandidate(ProtocolType protocol_type) {
    // For a simple allocation, the first Allocate message will return with an
    // error asking for credentials and will succeed after the second Allocate
    // message.
    return 2 * kSimulatedRtt + TimeToConnect(protocol_type);
  }

  // Total fake clock time to do the following:
  // 1. Connect to primary TURN server
  // 2. Send Allocate and receive a redirect from the primary TURN server
  // 3. Connect to alternate TURN server
  // 4. Send Allocate and receive a request for credentials
  // 5. Send Allocate with credentials and receive allocation
  TimeDelta TimeToGetAlternateTurnCandidate(ProtocolType protocol_type) {
    return 3 * kSimulatedRtt + 2 * TimeToConnect(protocol_type);
  }

  bool CheckConnectionFailedAndPruned(Connection* conn) {
    return conn && !conn->active() &&
           conn->state() == IceCandidatePairState::FAILED;
  }

  // Checks that `turn_port_` has a nonempty set of connections and they are all
  // failed and pruned.
  bool CheckAllConnectionsFailedAndPruned() {
    auto& connections = turn_port_->connections();
    if (connections.empty()) {
      return false;
    }
    for (const auto& kv : connections) {
      if (!CheckConnectionFailedAndPruned(kv.second)) {
        return false;
      }
    }
    return true;
  }

  void TestTurnAllocateSucceeds(TimeDelta timeout) {
    ASSERT_TRUE(turn_port_);
    turn_port_->PrepareAddress();
    EXPECT_THAT(WaitUntil([&] { return turn_ready_; }, IsTrue(),
                          {.timeout = timeout, .clock = &time_controller_}),
                IsRtcOk());
    ASSERT_EQ(1U, turn_port_->Candidates().size());
    EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
              turn_port_->Candidates()[0].address().ipaddr());
    EXPECT_NE(0, turn_port_->Candidates()[0].address().port());
  }

  void TestReconstructedServerUrl(ProtocolType protocol_type,
                                  absl::string_view expected_url) {
    ASSERT_TRUE(turn_port_);
    turn_port_->PrepareAddress();
    ASSERT_THAT(WaitUntil([&] { return turn_ready_; }, IsTrue(),
                          {.timeout = TimeToGetTurnCandidate(protocol_type),
                           .clock = &time_controller_}),
                IsRtcOk());
    ASSERT_EQ(1U, turn_port_->Candidates().size());
    EXPECT_EQ(turn_port_->Candidates()[0].url(), expected_url);
  }

  void TestTurnAlternateServer(ProtocolType protocol_type) {
    std::vector<SocketAddress> redirect_addresses;
    redirect_addresses.push_back(kTurnAlternateIntAddr);

    TestTurnRedirector redirector(redirect_addresses);

    turn_server_.AddInternalSocket(kTurnIntAddr, protocol_type);
    turn_server_.AddInternalSocket(kTurnAlternateIntAddr, protocol_type);
    turn_server_.set_redirect_hook(&redirector);
    CreateTurnPort(kTurnUsername, kTurnPassword,
                   ProtocolAddress(kTurnIntAddr, protocol_type));

    // Retrieve the address before we run the state machine.
    const SocketAddress old_addr = turn_port_->server_address().address;

    turn_port_->PrepareAddress();
    EXPECT_THAT(
        WaitUntil([&] { return turn_ready_; }, IsTrue(),
                  {.timeout = TimeToGetAlternateTurnCandidate(protocol_type),
                   .clock = &time_controller_}),
        IsRtcOk());
    // Retrieve the address again, the turn port's address should be
    // changed.
    const SocketAddress new_addr = turn_port_->server_address().address;
    EXPECT_NE(old_addr, new_addr);
    ASSERT_EQ(1U, turn_port_->Candidates().size());
    EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
              turn_port_->Candidates()[0].address().ipaddr());
    EXPECT_NE(0, turn_port_->Candidates()[0].address().port());
  }

  void TestTurnAlternateServerV4toV6(ProtocolType protocol_type) {
    std::vector<SocketAddress> redirect_addresses;
    redirect_addresses.push_back(kTurnIPv6IntAddr);

    TestTurnRedirector redirector(redirect_addresses);
    turn_server_.AddInternalSocket(kTurnIntAddr, protocol_type);
    turn_server_.set_redirect_hook(&redirector);
    CreateTurnPort(kTurnUsername, kTurnPassword,
                   ProtocolAddress(kTurnIntAddr, protocol_type));
    turn_port_->PrepareAddress();
    // Need time to connect to TURN server, send Allocate request and receive
    // redirect notice.
    EXPECT_THAT(
        WaitUntil([&] { return turn_error_; }, IsTrue(),
                  {.timeout = kSimulatedRtt + TimeToConnect(protocol_type),
                   .clock = &time_controller_}),
        IsRtcOk());
  }

  void TestTurnAlternateServerPingPong(ProtocolType protocol_type) {
    std::vector<SocketAddress> redirect_addresses;
    redirect_addresses.push_back(kTurnAlternateIntAddr);
    redirect_addresses.push_back(kTurnIntAddr);

    TestTurnRedirector redirector(redirect_addresses);

    turn_server_.AddInternalSocket(kTurnIntAddr, protocol_type);
    turn_server_.AddInternalSocket(kTurnAlternateIntAddr, protocol_type);
    turn_server_.set_redirect_hook(&redirector);
    CreateTurnPort(kTurnUsername, kTurnPassword,
                   ProtocolAddress(kTurnIntAddr, protocol_type));

    turn_port_->PrepareAddress();
    EXPECT_THAT(
        WaitUntil([&] { return turn_error_; }, IsTrue(),
                  {.timeout = TimeToGetAlternateTurnCandidate(protocol_type),
                   .clock = &time_controller_}),
        IsRtcOk());
    ASSERT_EQ(0U, turn_port_->Candidates().size());
    SocketAddress address;
    // Verify that we have exhausted all alternate servers instead of
    // failure caused by other errors.
    EXPECT_FALSE(redirector.ShouldRedirect(address, &address));
  }

  void TestTurnAlternateServerDetectRepetition(ProtocolType protocol_type) {
    std::vector<SocketAddress> redirect_addresses;
    redirect_addresses.push_back(kTurnAlternateIntAddr);
    redirect_addresses.push_back(kTurnAlternateIntAddr);

    TestTurnRedirector redirector(redirect_addresses);

    turn_server_.AddInternalSocket(kTurnIntAddr, protocol_type);
    turn_server_.AddInternalSocket(kTurnAlternateIntAddr, protocol_type);
    turn_server_.set_redirect_hook(&redirector);
    CreateTurnPort(kTurnUsername, kTurnPassword,
                   ProtocolAddress(kTurnIntAddr, protocol_type));

    turn_port_->PrepareAddress();
    EXPECT_THAT(
        WaitUntil([&] { return turn_error_; }, IsTrue(),
                  {.timeout = TimeToGetAlternateTurnCandidate(protocol_type),
                   .clock = &time_controller_}),
        IsRtcOk());
    ASSERT_EQ(0U, turn_port_->Candidates().size());
  }

  // A certain security exploit works by redirecting to a loopback address,
  // which doesn't ever actually make sense. So redirects to loopback should
  // be treated as errors.
  // See: https://bugs.chromium.org/p/chromium/issues/detail?id=649118
  void TestTurnAlternateServerLoopback(ProtocolType protocol_type, bool ipv6) {
    const SocketAddress& local_address = ipv6 ? kLocalIPv6Addr : kLocalAddr1;
    const SocketAddress& server_address =
        ipv6 ? kTurnIPv6IntAddr : kTurnIntAddr;

    std::vector<SocketAddress> redirect_addresses;
    // Pick an unusual address in the 127.0.0.0/8 range to make sure more than
    // 127.0.0.1 is covered.
    SocketAddress loopback_address(ipv6 ? "::1" : "127.1.2.3",
                                   TURN_SERVER_PORT);
    redirect_addresses.push_back(loopback_address);

    // Make a socket and bind it to the local port, to make extra sure no
    // packet is sent to this address.
    std::unique_ptr<Socket> loopback_socket(ss_->CreateSocket(
        AF_INET, protocol_type == PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM));
    ASSERT_NE(nullptr, loopback_socket.get());
    ASSERT_EQ(0, loopback_socket->Bind(loopback_address));
    if (protocol_type == PROTO_TCP) {
      ASSERT_EQ(0, loopback_socket->Listen(1));
    }

    TestTurnRedirector redirector(redirect_addresses);

    turn_server_.AddInternalSocket(server_address, protocol_type);
    turn_server_.set_redirect_hook(&redirector);
    CreateTurnPort(local_address, kTurnUsername, kTurnPassword,
                   ProtocolAddress(server_address, protocol_type));

    turn_port_->PrepareAddress();
    EXPECT_THAT(WaitUntil([&] { return turn_error_; }, IsTrue(),
                          {.timeout = TimeToGetTurnCandidate(protocol_type),
                           .clock = &time_controller_}),
                IsRtcOk());

    // Wait for some extra time, and make sure no packets were received on the
    // loopback port we created (or in the case of TCP, no connection attempt
    // occurred).
    time_controller_.AdvanceTime(kSimulatedRtt);
    if (protocol_type == PROTO_UDP) {
      char buf[1];
      EXPECT_EQ(-1, loopback_socket->Recv(&buf, 1, nullptr));
    } else {
      std::unique_ptr<Socket> accepted_socket(loopback_socket->Accept(nullptr));
      EXPECT_EQ(nullptr, accepted_socket.get());
    }
  }

  void TestTurnConnection(ProtocolType protocol_type) {
    // Create ports and prepare addresses.
    PrepareTurnAndUdpPorts(protocol_type);

    // Send ping from UDP to TURN.
    ASSERT_GE(turn_port_->Candidates().size(), 1U);
    Connection* conn1 = udp_port_->CreateConnection(turn_port_->Candidates()[0],
                                                    Port::ORIGIN_MESSAGE);
    ASSERT_TRUE(conn1 != nullptr);
    conn1->Ping();
    EXPECT_TRUE(
        WaitUntil([&] { return !turn_unknown_address_; },
                  {.timeout = kSimulatedRtt * 2, .clock = &time_controller_}));
    EXPECT_FALSE(turn_unknown_address_);
    EXPECT_FALSE(conn1->receiving());
    EXPECT_EQ(Connection::STATE_WRITE_INIT, conn1->write_state());

    // Send ping from TURN to UDP.
    Connection* conn2 = turn_port_->CreateConnection(udp_port_->Candidates()[0],
                                                     Port::ORIGIN_MESSAGE);
    ASSERT_TRUE(conn2 != nullptr);
    ASSERT_THAT(
        WaitUntil([&] { return turn_create_permission_success_; }, IsTrue(),
                  {.timeout = kSimulatedRtt, .clock = &time_controller_}),
        IsRtcOk());
    conn2->Ping();

    // Two hops from TURN port to UDP port through TURN server, thus two RTTs.
    EXPECT_THAT(
        WaitUntil([&] { return conn2->write_state(); },
                  Eq(Connection::STATE_WRITABLE),
                  {.timeout = kSimulatedRtt * 2, .clock = &time_controller_}),
        IsRtcOk());
    EXPECT_TRUE(conn1->receiving());
    EXPECT_TRUE(conn2->receiving());
    EXPECT_EQ(Connection::STATE_WRITE_INIT, conn1->write_state());

    // Send another ping from UDP to TURN.
    conn1->Ping();
    EXPECT_THAT(
        WaitUntil([&] { return conn1->write_state(); },
                  Eq(Connection::STATE_WRITABLE),
                  {.timeout = kSimulatedRtt * 2, .clock = &time_controller_}),
        IsRtcOk());
    EXPECT_TRUE(conn2->receiving());
  }

  void TestDestroyTurnConnection() {
    PrepareTurnAndUdpPorts(PROTO_UDP);

    // Create connections on both ends.
    Connection* conn1 = udp_port_->CreateConnection(turn_port_->Candidates()[0],
                                                    Port::ORIGIN_MESSAGE);
    Connection* conn2 = turn_port_->CreateConnection(udp_port_->Candidates()[0],
                                                     Port::ORIGIN_MESSAGE);

    // Increased to 10 minutes, to ensure that the TurnEntry times out before
    // the TurnPort.
    turn_port_->set_timeout_delay(10 * 60 * 1000);

    ASSERT_TRUE(conn2 != nullptr);
    ASSERT_THAT(
        WaitUntil([&] { return turn_create_permission_success_; }, IsTrue(),
                  {.timeout = kSimulatedRtt, .clock = &time_controller_}),
        IsRtcOk());
    // Make sure turn connection can receive.
    conn1->Ping();
    EXPECT_THAT(
        WaitUntil([&] { return conn1->write_state(); },
                  Eq(Connection::STATE_WRITABLE),
                  {.timeout = kSimulatedRtt * 2, .clock = &time_controller_}),
        IsRtcOk());
    EXPECT_FALSE(turn_unknown_address_);

    // Destroy the connection on the TURN port. The TurnEntry still exists, so
    // the TURN port should still process a ping from an unknown address.
    turn_port_->DestroyConnection(conn2);

    conn1->Ping();
    EXPECT_THAT(
        WaitUntil([&] { return turn_unknown_address_; }, IsTrue(),
                  {.timeout = kSimulatedRtt, .clock = &time_controller_}),
        IsRtcOk());

    // Wait for TurnEntry to expire. Timeout is 5 minutes.
    // Expect that it still processes an incoming ping and signals the
    // unknown address.
    turn_unknown_address_ = false;
    time_controller_.AdvanceTime(TimeDelta::Seconds(5 * 60));

    // TODO(chromium:1395625): When `TurnPort` doesn't find connection objects
    // for incoming packets, it forwards calls to the parent class, `Port`. This
    // happens inside `TurnPort::DispatchPacket`. The `Port` implementation may
    // need to send a binding error back over a connection which, unless the
    // `TurnPort` implementation handles it, could result in a null deref.
    // This special check tests if dispatching messages via `TurnPort` for which
    // there's no connection, results in a no-op rather than crashing.
    // See `TurnPort::SendBindingErrorResponse` for the check.
    // This should probably be done in a neater way both from a testing pov and
    // how incoming messages are handled in the `Port` class, when an assumption
    // is made about connection objects existing and when those assumptions
    // may not hold.
    std::string pwd = conn1->remote_password_for_test();
    conn1->set_remote_password_for_test("bad");
    auto msg = conn1->BuildPingRequestForTest();

    ByteBufferWriter buf;
    msg->Write(&buf);
    conn1->Send(buf.DataView(), options);

    // Now restore the password before continuing.
    conn1->set_remote_password_for_test(pwd);

    conn1->Ping();
    EXPECT_THAT(
        WaitUntil([&] { return turn_unknown_address_; }, IsTrue(),
                  {.timeout = kSimulatedRtt, .clock = &time_controller_}),
        IsRtcOk());

    // If the connection is created again, it will start to receive pings.
    conn2 = turn_port_->CreateConnection(udp_port_->Candidates()[0],
                                         Port::ORIGIN_MESSAGE);
    conn1->Ping();
    EXPECT_THAT(
        WaitUntil([&] { return conn2->receiving(); }, IsTrue(),
                  {.timeout = kSimulatedRtt, .clock = &time_controller_}),
        IsRtcOk());
  }

  void TestTurnSendData(ProtocolType protocol_type, bool expect_ecn_propagate) {
    PrepareTurnAndUdpPorts(protocol_type);

    // Create connections and send pings.
    Connection* conn1 = turn_port_->CreateConnection(udp_port_->Candidates()[0],
                                                     Port::ORIGIN_MESSAGE);
    Connection* conn2 = udp_port_->CreateConnection(turn_port_->Candidates()[0],
                                                    Port::ORIGIN_MESSAGE);
    ASSERT_TRUE(conn1 != nullptr);
    ASSERT_TRUE(conn2 != nullptr);
    conn1->RegisterReceivedPacketCallback(
        [&](Connection* connection, const ReceivedIpPacket& packet) {
          turn_packets_.emplace_back(packet);
        });

    conn1->SubscribeDestroyed(this, [this](Connection* connection) {
      OnConnectionSignalDestroyed(connection);
    });
    conn2->RegisterReceivedPacketCallback(
        [&](Connection* connection, const ReceivedIpPacket& packet) {
          udp_packets_.emplace_back(packet);
        });
    conn2->SubscribeDestroyed(this, [this](Connection* connection) {
      OnConnectionSignalDestroyed(connection);
    });
    conn1->Ping();
    EXPECT_THAT(
        WaitUntil([&] { return conn1->write_state(); },
                  Eq(Connection::STATE_WRITABLE),
                  {.timeout = kSimulatedRtt * 2, .clock = &time_controller_}),
        IsRtcOk());
    conn2->Ping();
    EXPECT_THAT(
        WaitUntil([&] { return conn2->write_state(); },
                  Eq(Connection::STATE_WRITABLE),
                  {.timeout = kSimulatedRtt * 2, .clock = &time_controller_}),
        IsRtcOk());

    // Send some data.
    size_t num_packets = 256;
    for (size_t i = 0; i < num_packets; ++i) {
      std::array<uint8_t, 256> buf;
      uint8_t val = 0xFF;
      std::generate(buf.begin(), buf.begin() + i + 1, [&val] { return val--; });
      options.ect_1 = (i % 2 == 0);
      conn1->Send(std::span(buf).first(i + 1), options);
      conn2->Send(std::span(buf).first(i + 1), options);
      time_controller_.AdvanceTime(kSimulatedRtt);
    }

    // Check the data.
    ASSERT_EQ(num_packets, turn_packets_.size());
    ASSERT_EQ(num_packets, udp_packets_.size());
    for (size_t i = 0; i < num_packets; ++i) {
      EXPECT_EQ(i + 1, turn_packets_[i].payload.size());
      EXPECT_EQ(i + 1, udp_packets_[i].payload.size());
      EXPECT_EQ(turn_packets_[i].payload, udp_packets_[i].payload);
      EXPECT_EQ(turn_packets_[i].payload, udp_packets_[i].payload);
      if (expect_ecn_propagate && (i % 2 == 0)) {
        EXPECT_EQ(turn_packets_[i].ecn, EcnMarking::kEct1);
        EXPECT_EQ(udp_packets_[i].ecn, EcnMarking::kEct1);
      } else {
        EXPECT_EQ(turn_packets_[i].ecn, EcnMarking::kNotEct);
        EXPECT_EQ(udp_packets_[i].ecn, EcnMarking::kNotEct);
      }
    }
  }

  // Test that a TURN allocation is released when the port is closed.
  void TestTurnReleaseAllocation(ProtocolType protocol_type) {
    PrepareTurnAndUdpPorts(protocol_type);
    turn_port_.reset();
    EXPECT_THAT(
        WaitUntil([&] { return turn_server_.server()->allocations().size(); },
                  Eq(0U),
                  {.timeout = kSimulatedRtt, .clock = &time_controller_}),
        IsRtcOk());
  }

  // Test that the TURN allocation is released by sending a refresh request
  // with lifetime 0 when Release is called.
  void TestTurnGracefulReleaseAllocation(ProtocolType protocol_type) {
    PrepareTurnAndUdpPorts(protocol_type);

    // Create connections and send pings.
    Connection* conn1 = turn_port_->CreateConnection(udp_port_->Candidates()[0],
                                                     Port::ORIGIN_MESSAGE);
    Connection* conn2 = udp_port_->CreateConnection(turn_port_->Candidates()[0],
                                                    Port::ORIGIN_MESSAGE);
    ASSERT_TRUE(conn1 != nullptr);
    ASSERT_TRUE(conn2 != nullptr);
    conn1->RegisterReceivedPacketCallback(
        [&](Connection* connection, const ReceivedIpPacket& packet) {
          turn_packets_.emplace_back(packet);
        });
    conn1->SubscribeDestroyed(this, [this](Connection* connection) {
      OnConnectionSignalDestroyed(connection);
    });

    conn2->SubscribeDestroyed(this, [this](Connection* connection) {
      OnConnectionSignalDestroyed(connection);
    });

    conn1->Ping();
    EXPECT_THAT(
        WaitUntil([&] { return conn1->write_state(); },
                  Eq(Connection::STATE_WRITABLE),
                  {.timeout = kSimulatedRtt * 2, .clock = &time_controller_}),
        IsRtcOk());
    conn2->Ping();
    EXPECT_THAT(
        WaitUntil([&] { return conn2->write_state(); },
                  Eq(Connection::STATE_WRITABLE),
                  {.timeout = kSimulatedRtt * 2, .clock = &time_controller_}),
        IsRtcOk());

    // Send some data from Udp to TurnPort.
    std::array<uint8_t, 256> buf;
    buf.fill(0);
    conn2->Send(buf, options);

    // Now release the TurnPort allocation.
    // This will send a REFRESH with lifetime 0 to server.
    turn_port_->Release();

    // Wait for the TurnPort to signal closed.
    ASSERT_THAT(
        WaitUntil([&] { return turn_port_closed_; }, IsTrue(),
                  {.timeout = kSimulatedRtt, .clock = &time_controller_}),
        IsRtcOk());

    // But the data should have arrived first.
    ASSERT_EQ(1ul, turn_packets_.size());
    EXPECT_EQ(sizeof(buf), turn_packets_[0].payload.size());

    // The allocation is released at server.
    EXPECT_EQ(0U, turn_server_.server()->allocations().size());
  }

 protected:
  struct Packet {
    explicit Packet(const ReceivedIpPacket& packet)
        : arrival_time(packet.arrival_time()),
          ecn(packet.ecn()),
          payload(Buffer(packet.payload().data(), packet.payload().size())) {}

    std::optional<Timestamp> arrival_time;
    EcnMarking ecn = EcnMarking::kNotEct;
    Buffer payload;
  };

  virtual PacketSocketFactory* socket_factory() { return &socket_factory_; }

  std::list<Network> networks_;
  std::unique_ptr<TurnPortTestVirtualSocketServer> ss_;
  GlobalSimulatedTimeController time_controller_;
  const Environment env_;
  Thread* main_;
  std::unique_ptr<AsyncPacketSocket> socket_;
  TestTurnServer turn_server_;
  std::unique_ptr<TurnPort> turn_port_;
  std::unique_ptr<UDPPort> udp_port_;
  bool turn_ready_ = false;
  bool turn_error_ = false;
  bool turn_unknown_address_ = false;
  bool turn_create_permission_success_ = false;
  bool turn_port_closed_ = false;
  bool turn_port_destroyed_ = false;
  bool udp_ready_ = false;
  bool test_finish_ = false;
  bool turn_refresh_success_ = false;
  std::vector<Packet> turn_packets_;
  std::vector<Packet> udp_packets_;
  AsyncSocketPacketOptions options;
  std::unique_ptr<TurnCustomizer> turn_customizer_;
  IceCandidateErrorEvent error_event_;

 private:
  BasicPacketSocketFactory socket_factory_;
};

TEST_F(TurnPortTest, TestTurnPortType) {
  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
  EXPECT_EQ(IceCandidateType::kRelay, turn_port_->Type());
}

// Tests that the URL of the servers can be correctly reconstructed when
// gathering the candidates.
TEST_F(TurnPortTest, TestReconstructedServerUrlForUdpIPv4) {
  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
  TestReconstructedServerUrl(PROTO_UDP, "turn:99.99.99.3:3478?transport=udp");
}

TEST_F(TurnPortTest, TestReconstructedServerUrlForUdpIPv6) {
  turn_server_.AddInternalSocket(kTurnUdpIPv6IntAddr, PROTO_UDP);
  CreateTurnPort(kLocalIPv6Addr, kTurnUsername, kTurnPassword,
                 kTurnUdpIPv6ProtoAddr);
  // Should add [] around the IPv6.
  TestReconstructedServerUrl(
      PROTO_UDP,
      "turn:[2400:4030:1:2c00:be30:abcd:efab:cdef]:3478?transport=udp");
}

TEST_F(TurnPortTest, TestReconstructedServerUrlForTcp) {
  turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
  TestReconstructedServerUrl(PROTO_TCP, "turn:99.99.99.4:3478?transport=tcp");
}

TEST_F(TurnPortTest, TestReconstructedServerUrlForTls) {
  turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TLS);
  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTlsProtoAddr);
  TestReconstructedServerUrl(PROTO_TLS, "turns:99.99.99.4:3478?transport=tcp");
}

TEST_F(TurnPortTest, TestReconstructedServerUrlForHostname) {
  CreateTurnPort(kTurnUsername, kTurnPassword,
                 kTurnPortInvalidHostnameProtoAddr);
  // This test follows the pattern from TestTurnTcpOnAddressResolveFailure.
  // As VSS doesn't provide DNS resolution, name resolve will fail,
  // the error will be set and contain the url.
  turn_port_->PrepareAddress();
  EXPECT_THAT(WaitUntil([&] { return turn_error_; }, IsTrue(),
                        {.timeout = kResolverTimeout}),
              IsRtcOk());
  std::string server_url =
      "turn:" + kTurnInvalidAddr.ToString() + "?transport=udp";
  ASSERT_EQ(error_event_.url, server_url);
}

// Do a normal TURN allocation.
TEST_F(TurnPortTest, TestTurnAllocate) {
  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
  EXPECT_EQ(0, turn_port_->SetOption(Socket::OPT_SNDBUF, 10 * 1024));
  TestTurnAllocateSucceeds(kSimulatedRtt * 2);
}

class TurnLoggingIdValidator : public StunMessageObserver {
 public:
  explicit TurnLoggingIdValidator(const char* expect_val)
      : expect_val_(expect_val) {}
  ~TurnLoggingIdValidator() override {}
  void ReceivedMessage(const TurnMessage* msg) override {
    if (msg->type() == STUN_ALLOCATE_REQUEST) {
      const StunByteStringAttribute* attr =
          msg->GetByteString(STUN_ATTR_TURN_LOGGING_ID);
      if (expect_val_) {
        ASSERT_NE(nullptr, attr);
        ASSERT_EQ(expect_val_, attr->string_view());
      } else {
        EXPECT_EQ(nullptr, attr);
      }
    }
  }
  void ReceivedChannelData(std::span<const uint8_t> packet) override {}

 private:
  const char* expect_val_;
};

TEST_F(TurnPortTest, TestTurnAllocateWithLoggingId) {
  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
  turn_port_->SetTurnLoggingId("KESO");
  turn_server_.server()->SetStunMessageObserver(
      std::make_unique<TurnLoggingIdValidator>("KESO"));
  TestTurnAllocateSucceeds(kSimulatedRtt * 2);
}

TEST_F(TurnPortTest, TestTurnAllocateWithoutLoggingId) {
  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
  turn_server_.server()->SetStunMessageObserver(
      std::make_unique<TurnLoggingIdValidator>(nullptr));
  TestTurnAllocateSucceeds(kSimulatedRtt * 2);
}

// Test bad credentials.
TEST_F(TurnPortTest, TestTurnBadCredentials) {
  CreateTurnPort(kTurnUsername, "bad", kTurnUdpProtoAddr);
  turn_port_->PrepareAddress();
  EXPECT_THAT(
      WaitUntil([&] { return turn_error_; }, IsTrue(),
                {.timeout = kSimulatedRtt * 3, .clock = &time_controller_}),
      IsRtcOk());
  ASSERT_EQ(0U, turn_port_->Candidates().size());
  EXPECT_THAT(
      WaitUntil([&] { return error_event_.error_code; },
                Eq(STUN_ERROR_UNAUTHORIZED),
                {.timeout = kSimulatedRtt * 3, .clock = &time_controller_}),
      IsRtcOk());
  EXPECT_EQ(error_event_.error_text, "Unauthorized.");
}

// Test that we fail without emitting an error if we try to get an address from
// a TURN server with a different address family. IPv4 local, IPv6 TURN.
TEST_F(TurnPortTest, TestServerAddressFamilyMismatch) {
  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpIPv6ProtoAddr);
  turn_port_->PrepareAddress();
  EXPECT_THAT(
      WaitUntil([&] { return turn_error_; }, IsTrue(),
                {.timeout = kSimulatedRtt * 3, .clock = &time_controller_}),
      IsRtcOk());
  ASSERT_EQ(0U, turn_port_->Candidates().size());
  EXPECT_EQ(0, error_event_.error_code);
}

// Test that we fail without emitting an error if we try to get an address from
// a TURN server with a different address family. IPv6 local, IPv4 TURN.
TEST_F(TurnPortTest, TestServerAddressFamilyMismatch6) {
  CreateTurnPort(kLocalIPv6Addr, kTurnUsername, kTurnPassword,
                 kTurnUdpProtoAddr);
  turn_port_->PrepareAddress();
  EXPECT_THAT(
      WaitUntil([&] { return turn_error_; }, IsTrue(),
                {.timeout = kSimulatedRtt * 3, .clock = &time_controller_}),
      IsRtcOk());
  ASSERT_EQ(0U, turn_port_->Candidates().size());
  EXPECT_EQ(0, error_event_.error_code);
}

// Testing a normal UDP allocation using TCP connection.
TEST_F(TurnPortTest, TestTurnTcpAllocate) {
  turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
  EXPECT_EQ(0, turn_port_->SetOption(Socket::OPT_SNDBUF, 10 * 1024));
  TestTurnAllocateSucceeds(kSimulatedRtt * 3);
}

// Test case for WebRTC issue 3927 where a proxy binds to the local host address
// instead the address that TurnPort originally bound to. The candidate pair
// impacted by this behavior should still be used.
TEST_F(TurnPortTest, TestTurnTcpAllocationWhenProxyChangesAddressToLocalHost) {
  SocketAddress local_address("127.0.0.1", 0);
  // After calling this, when TurnPort attempts to get a socket bound to
  // kLocalAddr, it will end up using localhost instead.
  ss_->SetAlternativeLocalAddress(kLocalAddr1.ipaddr(), local_address.ipaddr());

  turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
  CreateTurnPort(kLocalAddr1, kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
  EXPECT_EQ(0, turn_port_->SetOption(Socket::OPT_SNDBUF, 10 * 1024));
  TestTurnAllocateSucceeds(kSimulatedRtt * 3);

  // Verify that the socket actually used localhost, otherwise this test isn't
  // doing what it meant to.
  ASSERT_EQ(local_address.ipaddr(),
            turn_port_->Candidates()[0].related_address().ipaddr());
}

// If the address the socket ends up bound to does not match any address of the
// TurnPort's Network, then the socket should be discarded and no candidates
// should be signaled. In the context of ICE, where one TurnPort is created for
// each Network, when this happens it's likely that the unexpected address is
// associated with some other Network, which another TurnPort is already
// covering.
TEST_F(TurnPortTest,
       TurnTcpAllocationDiscardedIfBoundAddressDoesNotMatchNetwork) {
  // Sockets bound to kLocalAddr1 will actually end up with kLocalAddr2.
  ss_->SetAlternativeLocalAddress(kLocalAddr1.ipaddr(), kLocalAddr2.ipaddr());

  // Set up TURN server to use TCP (this logic only exists for TCP).
  turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);

  // Create TURN port and tell it to start allocation.
  CreateTurnPort(kLocalAddr1, kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
  turn_port_->PrepareAddress();

  // Shouldn't take more than 1 RTT to realize the bound address isn't the one
  // expected.
  EXPECT_THAT(WaitUntil([&] { return turn_error_; }, IsTrue(),
                        {.timeout = kSimulatedRtt, .clock = &time_controller_}),
              IsRtcOk());
  EXPECT_THAT(WaitUntil([&] { return error_event_.error_code; },
                        Eq(STUN_ERROR_SERVER_NOT_REACHABLE),
                        {.timeout = kSimulatedRtt, .clock = &time_controller_}),
              IsRtcOk());
  EXPECT_NE(error_event_.error_text.find('.'), std::string::npos);
  EXPECT_NE(error_event_.address.find(kLocalAddr2.HostAsSensitiveURIString()),
            std::string::npos);
  EXPECT_NE(error_event_.port, 0);
  std::string server_url =
      "turn:" + kTurnTcpIntAddr.ToString() + "?transport=tcp";
  EXPECT_EQ(error_event_.url, server_url);
}

// A caveat for the above logic: if the socket ends up bound to one of the IPs
// associated with the Network, just not the "best" one, this is ok.
TEST_F(TurnPortTest, TurnTcpAllocationNotDiscardedIfNotBoundToBestIP) {
  // Sockets bound to kLocalAddr1 will actually end up with kLocalAddr2.
  ss_->SetAlternativeLocalAddress(kLocalAddr1.ipaddr(), kLocalAddr2.ipaddr());

  // Set up a network with kLocalAddr1 as the "best" IP, and kLocalAddr2 as an
  // alternate.
  Network* network = MakeNetwork(kLocalAddr1);
  network->AddIP(kLocalAddr2.ipaddr());
  ASSERT_EQ(kLocalAddr1.ipaddr(), network->GetBestIP());

  // Set up TURN server to use TCP (this logic only exists for TCP).
  turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);

  // Create TURN port using our special Network, and tell it to start
  // allocation.
  CreateTurnPortWithNetwork(network, kTurnUsername, kTurnPassword,
                            kTurnTcpProtoAddr);
  turn_port_->PrepareAddress();

  // Candidate should be gathered as normally.
  EXPECT_THAT(
      WaitUntil([&] { return turn_ready_; }, IsTrue(),
                {.timeout = kSimulatedRtt * 3, .clock = &time_controller_}),
      IsRtcOk());
  ASSERT_EQ(1U, turn_port_->Candidates().size());

  // Verify that the socket actually used the alternate address, otherwise this
  // test isn't doing what it meant to.
  ASSERT_EQ(kLocalAddr2.ipaddr(),
            turn_port_->Candidates()[0].related_address().ipaddr());
}

// Regression test for crbug.com/webrtc/8972, caused by buggy comparison
// between IPAddress and InterfaceAddress.
TEST_F(TurnPortTest, TCPPortNotDiscardedIfBoundToTemporaryIP) {
  networks_.emplace_back("unittest", "unittest", kLocalIPv6Addr.ipaddr(), 32);
  networks_.back().AddIP(
      InterfaceAddress(kLocalIPv6Addr.ipaddr(), IPV6_ADDRESS_FLAG_TEMPORARY));

  // Set up TURN server to use TCP (this logic only exists for TCP).
  turn_server_.AddInternalSocket(kTurnIPv6IntAddr, PROTO_TCP);

  // Create TURN port using our special Network, and tell it to start
  // allocation.
  CreateTurnPortWithNetwork(&networks_.back(), kTurnUsername, kTurnPassword,
                            ProtocolAddress(kTurnIPv6IntAddr, PROTO_TCP));
  turn_port_->PrepareAddress();

  // Candidate should be gathered as normally.
  EXPECT_THAT(
      WaitUntil([&] { return turn_ready_; }, IsTrue(),
                {.timeout = kSimulatedRtt * 3, .clock = &time_controller_}),
      IsRtcOk());
  ASSERT_EQ(1U, turn_port_->Candidates().size());
}

// Testing turn port will attempt to create TCP socket on address resolution
// failure.
TEST_F(TurnPortTest, TestTurnTcpOnAddressResolveFailure) {
  turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
  CreateTurnPort(kTurnUsername, kTurnPassword,
                 ProtocolAddress(kTurnInvalidAddr, PROTO_TCP));
  turn_port_->PrepareAddress();
  EXPECT_THAT(WaitUntil([&] { return turn_error_; }, IsTrue(),
                        {.timeout = kResolverTimeout}),
              IsRtcOk());
  // As VSS doesn't provide DNS resolution, name resolve will fail. TurnPort
  // will proceed in creating a TCP socket which will fail as there is no
  // server on the above domain and error will be set to SOCKET_ERROR.
  EXPECT_EQ(SOCKET_ERROR, turn_port_->error());
  EXPECT_THAT(WaitUntil([&] { return error_event_.error_code; },
                        Eq(STUN_ERROR_SERVER_NOT_REACHABLE),
                        {.timeout = kSimulatedRtt, .clock = &time_controller_}),
              IsRtcOk());
  std::string server_url =
      "turn:" + kTurnInvalidAddr.ToString() + "?transport=tcp";
  ASSERT_EQ(error_event_.url, server_url);
}

// Testing turn port will attempt to create TLS socket on address resolution
// failure.
TEST_F(TurnPortTest, TestTurnTlsOnAddressResolveFailure) {
  turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TLS);
  CreateTurnPort(kTurnUsername, kTurnPassword,
                 ProtocolAddress(kTurnInvalidAddr, PROTO_TLS));
  turn_port_->PrepareAddress();
  EXPECT_THAT(WaitUntil([&] { return turn_error_; }, IsTrue(),
                        {.timeout = kResolverTimeout}),
              IsRtcOk());
  EXPECT_EQ(SOCKET_ERROR, turn_port_->error());
}

// In case of UDP on address resolve failure, TurnPort will not create socket
// and return allocate failure.
TEST_F(TurnPortTest, TestTurnUdpOnAddressResolveFailure) {
  CreateTurnPort(kTurnUsername, kTurnPassword,
                 ProtocolAddress(kTurnInvalidAddr, PROTO_UDP));
  turn_port_->PrepareAddress();
  EXPECT_THAT(WaitUntil([&] { return turn_error_; }, IsTrue(),
                        {.timeout = kResolverTimeout}),
              IsRtcOk());
  // Error from turn port will not be socket error.
  EXPECT_NE(SOCKET_ERROR, turn_port_->error());
}

// Try to do a TURN allocation with an invalid password.
TEST_F(TurnPortTest, TestTurnAllocateBadPassword) {
  CreateTurnPort(kTurnUsername, "bad", kTurnUdpProtoAddr);
  turn_port_->PrepareAddress();
  EXPECT_THAT(
      WaitUntil([&] { return turn_error_; }, IsTrue(),
                {.timeout = kSimulatedRtt * 2, .clock = &time_controller_}),
      IsRtcOk());
  ASSERT_EQ(0U, turn_port_->Candidates().size());
}

// Tests that TURN port nonce will be reset when receiving an ALLOCATE MISMATCH
// error.
TEST_F(TurnPortTest, TestTurnAllocateNonceResetAfterAllocateMismatch) {
  // Do a normal allocation first.
  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
  turn_port_->PrepareAddress();
  EXPECT_THAT(
      WaitUntil([&] { return turn_ready_; }, IsTrue(),
                {.timeout = kSimulatedRtt * 2, .clock = &time_controller_}),
      IsRtcOk());
  SocketAddress first_addr(turn_port_->socket()->GetLocalAddress());
  // Destroy the turnport while keeping the drop probability to 1 to
  // suppress the release of the allocation at the server.
  ss_->set_drop_probability(1.0);
  turn_port_.reset();
  time_controller_.AdvanceTime(kSimulatedRtt);
  ss_->set_drop_probability(0.0);

  // Force the socket server to assign the same port.
  ss_->SetNextPortForTesting(first_addr.port());
  turn_ready_ = false;
  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);

  // It is expected that the turn port will first get a nonce from the server
  // using timestamp `ts_before` but then get an allocate mismatch error and
  // receive an even newer nonce based on the system clock. `ts_before` is
  // chosen so that the two NONCEs generated by the server will be different.
  int64_t ts_before = env_.clock().TimeInMilliseconds() - 1;
  std::string first_nonce =
      turn_server_.server()->SetTimestampForNextNonce(ts_before);
  turn_port_->PrepareAddress();

  // Four round trips; first we'll get "stale nonce", then
  // "allocate mismatch", then "stale nonce" again, then finally it will
  // succeed.
  EXPECT_THAT(
      WaitUntil([&] { return turn_ready_; }, IsTrue(),
                {.timeout = kSimulatedRtt * 4, .clock = &time_controller_}),
      IsRtcOk());
  EXPECT_NE(first_nonce, turn_port_->nonce());
}

// Tests that a new local address is created after
// STUN_ERROR_ALLOCATION_MISMATCH.
TEST_F(TurnPortTest, TestTurnAllocateMismatch) {
  // Do a normal allocation first.
  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
  turn_port_->PrepareAddress();
  EXPECT_THAT(
      WaitUntil([&] { return turn_ready_; }, IsTrue(),
                {.timeout = kSimulatedRtt * 2, .clock = &time_controller_}),
      IsRtcOk());
  SocketAddress first_addr(turn_port_->socket()->GetLocalAddress());

  // Clear connected_ flag on turnport to suppress the release of
  // the allocation.
  turn_port_->OnSocketClose(turn_port_->socket(), 0);

  // Forces the socket server to assign the same port.
  ss_->SetNextPortForTesting(first_addr.port());

  turn_ready_ = false;
  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
  turn_port_->PrepareAddress();

  // Verifies that the new port has the same address.
  EXPECT_EQ(first_addr, turn_port_->socket()->GetLocalAddress());

  // Four round trips; first we'll get "stale nonce", then
  // "allocate mismatch", then "stale nonce" again, then finally it will
  // succeed.
  EXPECT_THAT(
      WaitUntil([&] { return turn_ready_; }, IsTrue(),
                {.timeout = kSimulatedRtt * 4, .clock = &time_controller_}),
      IsRtcOk());

  // Verifies that the new port has a different address now.
  EXPECT_NE(first_addr, turn_port_->socket()->GetLocalAddress());

  // Verify that all packets received from the shared socket are ignored.
  std::string test_packet = "Test packet";
  EXPECT_FALSE(turn_port_->HandleIncomingPacket(
      socket_.get(), ReceivedIpPacket::CreateFromLegacy(
                         test_packet.data(), test_packet.size(),
                         env_.clock().TimeInMicroseconds(),
                         SocketAddress(kTurnUdpExtAddr.ipaddr(), 0))));
}

// Tests that a shared-socket-TurnPort creates its own socket after
// STUN_ERROR_ALLOCATION_MISMATCH.
TEST_F(TurnPortTest, TestSharedSocketAllocateMismatch) {
  // Do a normal allocation first.
  CreateSharedTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
  turn_port_->PrepareAddress();
  EXPECT_THAT(
      WaitUntil([&] { return turn_ready_; }, IsTrue(),
                {.timeout = kSimulatedRtt * 2, .clock = &time_controller_}),
      IsRtcOk());
  SocketAddress first_addr(turn_port_->socket()->GetLocalAddress());

  // Clear connected_ flag on turnport to suppress the release of
  // the allocation.
  turn_port_->OnSocketClose(turn_port_->socket(), 0);

  turn_ready_ = false;
  CreateSharedTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);

  // Verifies that the new port has the same address.
  EXPECT_EQ(first_addr, turn_port_->socket()->GetLocalAddress());
  EXPECT_TRUE(turn_port_->SharedSocket());

  turn_port_->PrepareAddress();
  // Extra 2 round trips due to allocate mismatch.
  EXPECT_THAT(
      WaitUntil([&] { return turn_ready_; }, IsTrue(),
                {.timeout = kSimulatedRtt * 4, .clock = &time_controller_}),
      IsRtcOk());

  // Verifies that the new port has a different address now.
  EXPECT_NE(first_addr, turn_port_->socket()->GetLocalAddress());
  EXPECT_FALSE(turn_port_->SharedSocket());
}

TEST_F(TurnPortTest, TestTurnTcpAllocateMismatch) {
  turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);

  // Do a normal allocation first.
  turn_port_->PrepareAddress();
  EXPECT_THAT(
      WaitUntil([&] { return turn_ready_; }, IsTrue(),
                {.timeout = kSimulatedRtt * 3, .clock = &time_controller_}),
      IsRtcOk());
  SocketAddress first_addr(turn_port_->socket()->GetLocalAddress());

  // Clear connected_ flag on turnport to suppress the release of
  // the allocation.
  turn_port_->OnSocketClose(turn_port_->socket(), 0);

  // Forces the socket server to assign the same port.
  ss_->SetNextPortForTesting(first_addr.port());

  turn_ready_ = false;
  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
  turn_port_->PrepareAddress();

  // Verifies that the new port has the same address.
  EXPECT_EQ(first_addr, turn_port_->socket()->GetLocalAddress());

  // Extra 2 round trips due to allocate mismatch.
  EXPECT_THAT(
      WaitUntil([&] { return turn_ready_; }, IsTrue(),
                {.timeout = kSimulatedRtt * 5, .clock = &time_controller_}),
      IsRtcOk());

  // Verifies that the new port has a different address now.
  EXPECT_NE(first_addr, turn_port_->socket()->GetLocalAddress());
}

TEST_F(TurnPortTest, TestRefreshRequestGetsErrorResponse) {
  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
  PrepareTurnAndUdpPorts(PROTO_UDP);
  turn_port_->CreateConnection(udp_port_->Candidates()[0],
                               Port::ORIGIN_MESSAGE);
  // Set bad credentials.
  RelayCredentials bad_credentials("bad_user", "bad_pwd");
  turn_port_->set_credentials(bad_credentials);
  turn_refresh_success_ = false;
  // This sends out the first RefreshRequest with correct credentials.
  // When this succeeds, it will schedule a new RefreshRequest with the bad
  // credential.
  turn_port_->request_manager().FlushForTest(TURN_REFRESH_REQUEST);
  EXPECT_THAT(WaitUntil([&] { return turn_refresh_success_; }, IsTrue(),
                        {.timeout = kSimulatedRtt, .clock = &time_controller_}),
              IsRtcOk());
  // Flush it again, it will receive a bad response.
  turn_port_->request_manager().FlushForTest(TURN_REFRESH_REQUEST);
  EXPECT_THAT(WaitUntil([&] { return !turn_refresh_success_; }, IsTrue(),
                        {.timeout = kSimulatedRtt, .clock = &time_controller_}),
              IsRtcOk());
  EXPECT_FALSE(turn_port_->connected());
  EXPECT_TRUE(CheckAllConnectionsFailedAndPruned());
  EXPECT_FALSE(turn_port_->HasRequests());
}

// Test that TurnPort will not handle any incoming packets once it has been
// closed.
TEST_F(TurnPortTest, TestStopProcessingPacketsAfterClosed) {
  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
  PrepareTurnAndUdpPorts(PROTO_UDP);
  Connection* conn1 = turn_port_->CreateConnection(udp_port_->Candidates()[0],
                                                   Port::ORIGIN_MESSAGE);
  Connection* conn2 = udp_port_->CreateConnection(turn_port_->Candidates()[0],
                                                  Port::ORIGIN_MESSAGE);
  ASSERT_TRUE(conn1 != nullptr);
  ASSERT_TRUE(conn2 != nullptr);
  // Make sure conn2 is writable.
  conn2->Ping();
  EXPECT_THAT(
      WaitUntil([&] { return conn2->write_state(); },
                Eq(Connection::STATE_WRITABLE),
                {.timeout = kSimulatedRtt * 2, .clock = &time_controller_}),
      IsRtcOk());

  turn_port_->CloseForTest();
  time_controller_.AdvanceTime(kSimulatedRtt);
  turn_unknown_address_ = false;
  conn2->Ping();
  time_controller_.AdvanceTime(kSimulatedRtt);
  // Since the turn port does not handle packets any more, it should not
  // SignalUnknownAddress.
  EXPECT_FALSE(turn_unknown_address_);
}

// Test that CreateConnection will return null if port becomes disconnected.
TEST_F(TurnPortTest, TestCreateConnectionWhenSocketClosed) {
  turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
  PrepareTurnAndUdpPorts(PROTO_TCP);
  // Create a connection.
  Connection* conn1 = turn_port_->CreateConnection(udp_port_->Candidates()[0],
                                                   Port::ORIGIN_MESSAGE);
  ASSERT_TRUE(conn1 != nullptr);

  // Close the socket and create a connection again.
  turn_port_->OnSocketClose(turn_port_->socket(), 1);
  conn1 = turn_port_->CreateConnection(udp_port_->Candidates()[0],
                                       Port::ORIGIN_MESSAGE);
  ASSERT_TRUE(conn1 == nullptr);
}

// Tests that when a TCP socket is closed, the respective TURN connection will
// be destroyed.
TEST_F(TurnPortTest, TestSocketCloseWillDestroyConnection) {
  turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
  PrepareTurnAndUdpPorts(PROTO_TCP);
  Connection* conn = turn_port_->CreateConnection(udp_port_->Candidates()[0],
                                                  Port::ORIGIN_MESSAGE);
  EXPECT_NE(nullptr, conn);
  EXPECT_TRUE(!turn_port_->connections().empty());
  turn_port_->socket()->NotifyClosedForTest(1);
  EXPECT_THAT(
      WaitUntil(
          [&] { return turn_port_->connections().empty(); }, IsTrue(),
          {.timeout = kConnectionDestructionDelay, .clock = &time_controller_}),
      IsRtcOk());
}

// Test try-alternate-server feature.
TEST_F(TurnPortTest, TestTurnAlternateServerUDP) {
  TestTurnAlternateServer(PROTO_UDP);
}

TEST_F(TurnPortTest, TestTurnAlternateServerTCP) {
  TestTurnAlternateServer(PROTO_TCP);
}

TEST_F(TurnPortTest, TestTurnAlternateServerTLS) {
  TestTurnAlternateServer(PROTO_TLS);
}

// Test that we fail when we redirect to an address different from
// current IP family.
TEST_F(TurnPortTest, TestTurnAlternateServerV4toV6UDP) {
  TestTurnAlternateServerV4toV6(PROTO_UDP);
}

TEST_F(TurnPortTest, TestTurnAlternateServerV4toV6TCP) {
  TestTurnAlternateServerV4toV6(PROTO_TCP);
}

TEST_F(TurnPortTest, TestTurnAlternateServerV4toV6TLS) {
  TestTurnAlternateServerV4toV6(PROTO_TLS);
}

// Test try-alternate-server catches the case of pingpong.
TEST_F(TurnPortTest, TestTurnAlternateServerPingPongUDP) {
  TestTurnAlternateServerPingPong(PROTO_UDP);
}

TEST_F(TurnPortTest, TestTurnAlternateServerPingPongTCP) {
  TestTurnAlternateServerPingPong(PROTO_TCP);
}

TEST_F(TurnPortTest, TestTurnAlternateServerPingPongTLS) {
  TestTurnAlternateServerPingPong(PROTO_TLS);
}

// Test try-alternate-server catch the case of repeated server.
TEST_F(TurnPortTest, TestTurnAlternateServerDetectRepetitionUDP) {
  TestTurnAlternateServerDetectRepetition(PROTO_UDP);
}

TEST_F(TurnPortTest, TestTurnAlternateServerDetectRepetitionTCP) {
  TestTurnAlternateServerDetectRepetition(PROTO_TCP);
}

TEST_F(TurnPortTest, TestTurnAlternateServerDetectRepetitionTLS) {
  TestTurnAlternateServerDetectRepetition(PROTO_TCP);
}

// Test catching the case of a redirect to loopback.
TEST_F(TurnPortTest, TestTurnAlternateServerLoopbackUdpIpv4) {
  TestTurnAlternateServerLoopback(PROTO_UDP, false);
}

TEST_F(TurnPortTest, TestTurnAlternateServerLoopbackUdpIpv6) {
  TestTurnAlternateServerLoopback(PROTO_UDP, true);
}

TEST_F(TurnPortTest, TestTurnAlternateServerLoopbackTcpIpv4) {
  TestTurnAlternateServerLoopback(PROTO_TCP, false);
}

TEST_F(TurnPortTest, TestTurnAlternateServerLoopbackTcpIpv6) {
  TestTurnAlternateServerLoopback(PROTO_TCP, true);
}

TEST_F(TurnPortTest, TestTurnAlternateServerLoopbackTlsIpv4) {
  TestTurnAlternateServerLoopback(PROTO_TLS, false);
}

TEST_F(TurnPortTest, TestTurnAlternateServerLoopbackTlsIpv6) {
  TestTurnAlternateServerLoopback(PROTO_TLS, true);
}

// Do a TURN allocation and try to send a packet to it from the outside.
// The packet should be dropped. Then, try to send a packet from TURN to the
// outside. It should reach its destination. Finally, try again from the
// outside. It should now work as well.
TEST_F(TurnPortTest, TestTurnConnection) {
  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
  TestTurnConnection(PROTO_UDP);
}

// Similar to above, except that this test will use the shared socket.
TEST_F(TurnPortTest, TestTurnConnectionUsingSharedSocket) {
  CreateSharedTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
  TestTurnConnection(PROTO_UDP);
}

// Test that we can establish a TCP connection with TURN server.
TEST_F(TurnPortTest, TestTurnTcpConnection) {
  turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
  TestTurnConnection(PROTO_TCP);
}

// Test that we can establish a TLS connection with TURN server.
TEST_F(TurnPortTest, TestTurnTlsConnection) {
  turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TLS);
  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTlsProtoAddr);
  TestTurnConnection(PROTO_TLS);
}

// Test that if a connection on a TURN port is destroyed, the TURN port can
// still receive ping on that connection as if it is from an unknown address.
// If the connection is created again, it will be used to receive ping.
TEST_F(TurnPortTest, TestDestroyTurnConnection) {
  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
  TestDestroyTurnConnection();
}

// Similar to above, except that this test will use the shared socket.
TEST_F(TurnPortTest, TestDestroyTurnConnectionUsingSharedSocket) {
  CreateSharedTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
  TestDestroyTurnConnection();
}

// Run TurnConnectionTest with one-time-use nonce feature.
// Here server will send a 438 STALE_NONCE error message for
// every TURN transaction.
TEST_F(TurnPortTest, TestTurnConnectionUsingOTUNonce) {
  turn_server_.set_enable_otu_nonce(true);
  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
  TestTurnConnection(PROTO_UDP);
}

// Test that CreatePermissionRequest will be scheduled after the success
// of the first create permission request and the request will get an
// ErrorResponse if the ufrag and pwd are incorrect.
TEST_F(TurnPortTest, TestRefreshCreatePermissionRequest) {
  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
  PrepareTurnAndUdpPorts(PROTO_UDP);

  Connection* conn = turn_port_->CreateConnection(udp_port_->Candidates()[0],
                                                  Port::ORIGIN_MESSAGE);
  ASSERT_TRUE(conn != nullptr);
  EXPECT_THAT(
      WaitUntil([&] { return turn_create_permission_success_; }, IsTrue(),
                {.timeout = kSimulatedRtt, .clock = &time_controller_}),
      IsRtcOk());
  turn_create_permission_success_ = false;
  // A create-permission-request should be pending.
  // After the next create-permission-response is received, it will schedule
  // another request with bad_ufrag and bad_pwd.
  RelayCredentials bad_credentials("bad_user", "bad_pwd");
  turn_port_->set_credentials(bad_credentials);
  turn_port_->request_manager().FlushForTest(kAllRequestsForTest);
  EXPECT_THAT(
      WaitUntil([&] { return turn_create_permission_success_; }, IsTrue(),
                {.timeout = kSimulatedRtt, .clock = &time_controller_}),
      IsRtcOk());
  // Flush the requests again; the create-permission-request will fail.
  turn_port_->request_manager().FlushForTest(kAllRequestsForTest);
  EXPECT_THAT(
      WaitUntil([&] { return !turn_create_permission_success_; }, IsTrue(),
                {.timeout = kSimulatedRtt, .clock = &time_controller_}),
      IsRtcOk());
  EXPECT_TRUE(CheckConnectionFailedAndPruned(conn));
}

TEST_F(TurnPortTest, TestChannelBindGetErrorResponse) {
  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
  PrepareTurnAndUdpPorts(PROTO_UDP);
  Connection* conn1 = turn_port_->CreateConnection(udp_port_->Candidates()[0],
                                                   Port::ORIGIN_MESSAGE);
  ASSERT_TRUE(conn1 != nullptr);
  Connection* conn2 = udp_port_->CreateConnection(turn_port_->Candidates()[0],
                                                  Port::ORIGIN_MESSAGE);

  ASSERT_TRUE(conn2 != nullptr);
  conn1->Ping();
  EXPECT_THAT(
      WaitUntil([&] { return conn1->writable(); }, IsTrue(),
                {.timeout = kSimulatedRtt * 2, .clock = &time_controller_}),
      IsRtcOk());

  // Tell the TURN server to reject all bind requests from now on.
  turn_server_.server()->set_reject_bind_requests(true);

  auto data = std::to_array<uint8_t>({'A', 'B', 'C'});
  conn1->Send(data, options);

  EXPECT_THAT(
      WaitUntil([&] { return CheckConnectionFailedAndPruned(conn1); }, IsTrue(),
                {.timeout = kSimulatedRtt, .clock = &time_controller_}),
      IsRtcOk());
  // Verify that packets are allowed to be sent after a bind request error.
  // They'll just use a send indication instead.
  conn2->RegisterReceivedPacketCallback(
      [&](Connection* connection, const ReceivedIpPacket& packet) {
        // TODO(bugs.webrtc.org/345518625): Verify that the packet was
        // received unchanneled, not channeled.
        udp_packets_.emplace_back(packet);
      });
  conn1->Send(data, options);
  EXPECT_THAT(WaitUntil([&] { return !udp_packets_.empty(); }, IsTrue(),
                        {.timeout = kSimulatedRtt, .clock = &time_controller_}),
              IsRtcOk());
  conn2->DeregisterReceivedPacketCallback();
}

// Do a TURN allocation, establish a UDP connection, and send some data.
TEST_F(TurnPortTest, TestTurnSendDataTurnUdpToUdp) {
  // Create ports and prepare addresses.
  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
  TestTurnSendData(PROTO_UDP, /*expect_ecn_propagate=*/true);
  EXPECT_EQ(UDP_PROTOCOL_NAME, turn_port_->Candidates()[0].relay_protocol());
}

// Do a TURN allocation, establish a TCP connection, and send some data.
TEST_F(TurnPortTest, TestTurnSendDataTurnTcpToUdp) {
  turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
  // Create ports and prepare addresses.
  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
  TestTurnSendData(PROTO_TCP, /*expect_ecn_propagate=*/false);
  EXPECT_EQ(TCP_PROTOCOL_NAME, turn_port_->Candidates()[0].relay_protocol());
}

// Do a TURN allocation, establish a TLS connection, and send some data.
TEST_F(TurnPortTest, TestTurnSendDataTurnTlsToUdp) {
  turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TLS);
  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTlsProtoAddr);
  TestTurnSendData(PROTO_TLS, /*expect_ecn_propagate=*/false);
  EXPECT_EQ(TLS_PROTOCOL_NAME, turn_port_->Candidates()[0].relay_protocol());
}

// Test TURN fails to make a connection from IPv6 address to a server which has
// IPv4 address.
TEST_F(TurnPortTest, TestTurnLocalIPv6AddressServerIPv4) {
  turn_server_.AddInternalSocket(kTurnUdpIPv6IntAddr, PROTO_UDP);
  CreateTurnPort(kLocalIPv6Addr, kTurnUsername, kTurnPassword,
                 kTurnUdpProtoAddr);
  turn_port_->PrepareAddress();
  ASSERT_THAT(WaitUntil([&] { return turn_error_; }, IsTrue(),
                        {.timeout = kSimulatedRtt, .clock = &time_controller_}),
              IsRtcOk());
  EXPECT_TRUE(turn_port_->Candidates().empty());
}

// Test TURN make a connection from IPv6 address to a server which has
// IPv6 intenal address. But in this test external address is a IPv4 address,
// hence allocated address will be a IPv4 address.
TEST_F(TurnPortTest, TestTurnLocalIPv6AddressServerIPv6ExtenalIPv4) {
  turn_server_.AddInternalSocket(kTurnUdpIPv6IntAddr, PROTO_UDP);
  CreateTurnPort(kLocalIPv6Addr, kTurnUsername, kTurnPassword,
                 kTurnUdpIPv6ProtoAddr);
  TestTurnAllocateSucceeds(kSimulatedRtt * 2);
}

// Tests that the local and remote candidate address families should match when
// a connection is created. Specifically, if a TURN port has an IPv6 address,
// its local candidate will still be an IPv4 address and it can only create
// connections with IPv4 remote candidates.
TEST_F(TurnPortTest, TestCandidateAddressFamilyMatch) {
  turn_server_.AddInternalSocket(kTurnUdpIPv6IntAddr, PROTO_UDP);

  CreateTurnPort(kLocalIPv6Addr, kTurnUsername, kTurnPassword,
                 kTurnUdpIPv6ProtoAddr);
  turn_port_->PrepareAddress();
  EXPECT_THAT(
      WaitUntil([&] { return turn_ready_; }, IsTrue(),
                {.timeout = kSimulatedRtt * 2, .clock = &time_controller_}),
      IsRtcOk());
  ASSERT_EQ(1U, turn_port_->Candidates().size());

  // Create an IPv4 candidate. It will match the TURN candidate.
  Candidate remote_candidate(ICE_CANDIDATE_COMPONENT_RTP, "udp", kLocalAddr2, 0,
                             "", "", IceCandidateType::kHost, 0,
                             kCandidateFoundation);
  remote_candidate.set_address(kLocalAddr2);
  Connection* conn =
      turn_port_->CreateConnection(remote_candidate, Port::ORIGIN_MESSAGE);
  EXPECT_NE(nullptr, conn);

  // Set the candidate address family to IPv6. It won't match the TURN
  // candidate.
  remote_candidate.set_address(kLocalIPv6Addr2);
  conn = turn_port_->CreateConnection(remote_candidate, Port::ORIGIN_MESSAGE);
  EXPECT_EQ(nullptr, conn);
}

// Test that a CreatePermission failure will result in the connection being
// pruned and failed.
TEST_F(TurnPortTest, TestConnectionFailedAndPrunedOnCreatePermissionFailure) {
  turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
  turn_server_.server()->set_reject_private_addresses(true);
  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
  turn_port_->PrepareAddress();
  EXPECT_THAT(
      WaitUntil([&] { return turn_ready_; }, IsTrue(),
                {.timeout = kSimulatedRtt * 3, .clock = &time_controller_}),
      IsRtcOk());

  CreateUdpPort(SocketAddress("10.0.0.10", 0));
  udp_port_->PrepareAddress();
  EXPECT_THAT(WaitUntil([&] { return udp_ready_; }, IsTrue(),
                        {.timeout = kSimulatedRtt, .clock = &time_controller_}),
              IsRtcOk());
  // Create a connection.
  TestConnectionWrapper conn(turn_port_->CreateConnection(
      udp_port_->Candidates()[0], Port::ORIGIN_MESSAGE));
  EXPECT_TRUE(conn.connection() != nullptr);

  // Asynchronously, CreatePermission request should be sent and fail, which
  // will make the connection pruned and failed.
  EXPECT_THAT(
      WaitUntil(
          [&] { return CheckConnectionFailedAndPruned(conn.connection()); },
          IsTrue(), {.timeout = kSimulatedRtt, .clock = &time_controller_}),
      IsRtcOk());
  EXPECT_THAT(
      WaitUntil([&] { return !turn_create_permission_success_; }, IsTrue(),
                {.timeout = kSimulatedRtt, .clock = &time_controller_}),
      IsRtcOk());
  // Check that the connection is not deleted asynchronously.
  time_controller_.AdvanceTime(kConnectionDestructionDelay);
  EXPECT_NE(nullptr, conn.connection());
}

// Test that a TURN allocation is released when the port is closed.
TEST_F(TurnPortTest, TestTurnReleaseAllocation) {
  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
  TestTurnReleaseAllocation(PROTO_UDP);
}

// Test that a TURN TCP allocation is released when the port is closed.
TEST_F(TurnPortTest, TestTurnTCPReleaseAllocation) {
  turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
  TestTurnReleaseAllocation(PROTO_TCP);
}

TEST_F(TurnPortTest, TestTurnTLSReleaseAllocation) {
  turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TLS);
  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTlsProtoAddr);
  TestTurnReleaseAllocation(PROTO_TLS);
}

TEST_F(TurnPortTest, TestTurnUDPGracefulReleaseAllocation) {
  turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_UDP);
  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
  TestTurnGracefulReleaseAllocation(PROTO_UDP);
}

TEST_F(TurnPortTest, TestTurnTCPGracefulReleaseAllocation) {
  turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP);
  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
  TestTurnGracefulReleaseAllocation(PROTO_TCP);
}

TEST_F(TurnPortTest, TestTurnTLSGracefulReleaseAllocation) {
  turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TLS);
  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTlsProtoAddr);
  TestTurnGracefulReleaseAllocation(PROTO_TLS);
}

// Test that nothing bad happens if we try to create a connection to the same
// remote address twice. Previously there was a bug that caused this to hit a
// DCHECK.
TEST_F(TurnPortTest, CanCreateTwoConnectionsToSameAddress) {
  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
  PrepareTurnAndUdpPorts(PROTO_UDP);
  Connection* conn1 = turn_port_->CreateConnection(udp_port_->Candidates()[0],
                                                   Port::ORIGIN_MESSAGE);
  Connection* conn2 = turn_port_->CreateConnection(udp_port_->Candidates()[0],
                                                   Port::ORIGIN_MESSAGE);
  EXPECT_NE(conn1, conn2);
}

// This test verifies any FD's are not leaked after TurnPort is destroyed.
// https://code.google.com/p/webrtc/issues/detail?id=2651
#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)

TEST_F(TurnPortTest, TestResolverShutdown) {
  turn_server_.AddInternalSocket(kTurnUdpIPv6IntAddr, PROTO_UDP);
  int last_fd_count = GetFDCount();
  // Need to supply unresolved address to kick off resolver.
  CreateTurnPort(kLocalIPv6Addr, kTurnUsername, kTurnPassword,
                 ProtocolAddress(kTurnInvalidAddr, PROTO_UDP));
  turn_port_->PrepareAddress();
  ASSERT_THAT(WaitUntil([&] { return turn_error_; }, IsTrue(),
                        {.timeout = kResolverTimeout}),
              IsRtcOk());
  EXPECT_TRUE(turn_port_->Candidates().empty());
  turn_port_.reset();
  Thread::Current()->PostTask([this] { test_finish_ = true; });
  // Waiting for above message to be processed.
  ASSERT_THAT(WaitUntil([&] { return test_finish_; }, IsTrue(),
                        {.clock = &time_controller_}),
              IsRtcOk());
  EXPECT_EQ(last_fd_count, GetFDCount());
}
#endif

class MessageObserver : public StunMessageObserver {
 public:
  MessageObserver(unsigned int* message_counter,
                  unsigned int* channel_data_counter,
                  unsigned int* attr_counter)
      : message_counter_(message_counter),
        channel_data_counter_(channel_data_counter),
        attr_counter_(attr_counter) {}
  ~MessageObserver() override {}
  void ReceivedMessage(const TurnMessage* msg) override {
    if (message_counter_ != nullptr) {
      (*message_counter_)++;
    }
    // Implementation defined attributes are returned as ByteString
    const StunByteStringAttribute* attr =
        msg->GetByteString(TestTurnCustomizer::STUN_ATTR_COUNTER);
    if (attr != nullptr && attr_counter_ != nullptr) {
      ByteBufferReader buf(attr->array_view());
      unsigned int val = ~0u;
      buf.ReadUInt32(&val);
      (*attr_counter_)++;
    }
  }

  void ReceivedChannelData(std::span<const uint8_t> payload) override {
    if (channel_data_counter_ != nullptr) {
      (*channel_data_counter_)++;
    }
  }

  // Number of TurnMessages observed.
  unsigned int* message_counter_ = nullptr;

  // Number of channel data observed.
  unsigned int* channel_data_counter_ = nullptr;

  // Number of TurnMessages that had STUN_ATTR_COUNTER.
  unsigned int* attr_counter_ = nullptr;
};

// Test that an unauthenticated TURN ALLOCATE success response is NOT accepted
// if integrity is expected but not present.
// This is a regression test for b/504572664.
TEST_F(TurnPortTest, TestUnauthenticatedAllocateSuccessRejected) {
  SocketAddress fake_server_addr("99.99.99.99", 3478);
  CreateTurnPort(kTurnUsername, kTurnPassword,
                 ProtocolAddress(fake_server_addr, PROTO_UDP));

  std::unique_ptr<AsyncPacketSocket> server_socket =
      socket_factory()->CreateUdpSocket(env_, fake_server_addr, 0, 0);

  std::string transaction_id;
  server_socket->RegisterReceivedPacketCallback(
      [&](AsyncPacketSocket* /* socket */, const ReceivedIpPacket& packet) {
        ByteBufferReader reader(packet.payload());
        TurnMessage msg;
        if (msg.Read(&reader) && msg.type() == STUN_ALLOCATE_REQUEST) {
          transaction_id = msg.transaction_id();
        }
      });

  turn_port_->PrepareAddress();

  // Wait for the request to reach the server.
  ASSERT_TRUE(
      WaitUntil([&] { return !transaction_id.empty(); },
                {.timeout = kSimulatedRtt, .clock = &time_controller_}));

  TurnMessage forged_success(STUN_ALLOCATE_RESPONSE, transaction_id);

  // Add required attributes for ALLOCATE success.
  SocketAddress relayed_addr("198.51.100.99", 6666);
  SocketAddress mapped_addr("203.0.113.77", 5555);

  forged_success.AddAttribute(std::make_unique<StunXorAddressAttribute>(
      STUN_ATTR_XOR_RELAYED_ADDRESS, relayed_addr));
  forged_success.AddAttribute(std::make_unique<StunXorAddressAttribute>(
      STUN_ATTR_XOR_MAPPED_ADDRESS, mapped_addr));
  forged_success.AddAttribute(
      std::make_unique<StunUInt32Attribute>(STUN_ATTR_LIFETIME, 300));

  ByteBufferWriter buf;
  forged_success.Write(&buf);

  // Send the forged response to the TurnPort.
  SocketAddress local_addr = turn_port_->socket()->GetLocalAddress();
  AsyncSocketPacketOptions local_options;
  server_socket->SendTo(buf.Data(), buf.Length(), local_addr, local_options);

  // Wait a bit for the packet to be processed.
  time_controller_.AdvanceTime(kSimulatedRtt);

  // If vulnerable, turn_ready_ would be true because it accepted the forged
  // success. The correct behavior is to reject it and eventually fail or
  // receive the 401.
  EXPECT_FALSE(turn_ready_)
      << "Vulnerability present: Unauthenticated ALLOCATE success accepted!";
}

// Do a TURN allocation, establish a TLS connection, and send some data.
// Add customizer and check that it get called.
TEST_F(TurnPortTest, TestTurnCustomizerCount) {
  unsigned int observer_message_counter = 0;
  unsigned int observer_channel_data_counter = 0;
  unsigned int observer_attr_counter = 0;
  TestTurnCustomizer* customizer = new TestTurnCustomizer();
  std::unique_ptr<MessageObserver> validator(new MessageObserver(
      &observer_message_counter, &observer_channel_data_counter,
      &observer_attr_counter));

  turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TLS);
  turn_customizer_.reset(customizer);
  turn_server_.server()->SetStunMessageObserver(std::move(validator));

  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTlsProtoAddr);
  // Don't expect ECN to be propagated via TCP
  TestTurnSendData(PROTO_TLS, /*expect_ecn_propagate=*/false);
  EXPECT_EQ(TLS_PROTOCOL_NAME, turn_port_->Candidates()[0].relay_protocol());

  // There should have been at least turn_packets_.size() calls to `customizer`.
  EXPECT_GE(customizer->modify_cnt_ + customizer->allow_channel_data_cnt_,
            turn_packets_.size());

  // Some channel data should be received.
  EXPECT_GE(observer_channel_data_counter, 0u);

  // Need to release TURN port before the customizer.
  turn_port_.reset(nullptr);
}

// Do a TURN allocation, establish a TLS connection, and send some data.
// Add customizer and check that it can can prevent usage of channel data.
TEST_F(TurnPortTest, TestTurnCustomizerDisallowChannelData) {
  unsigned int observer_message_counter = 0;
  unsigned int observer_channel_data_counter = 0;
  unsigned int observer_attr_counter = 0;
  TestTurnCustomizer* customizer = new TestTurnCustomizer();
  std::unique_ptr<MessageObserver> validator(new MessageObserver(
      &observer_message_counter, &observer_channel_data_counter,
      &observer_attr_counter));
  customizer->allow_channel_data_ = false;
  turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TLS);
  turn_customizer_.reset(customizer);
  turn_server_.server()->SetStunMessageObserver(std::move(validator));

  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTlsProtoAddr);
  // Don't expect ECN to propagate via TCP.
  TestTurnSendData(PROTO_TLS, /*expect_ecn_propagate=*/false);
  EXPECT_EQ(TLS_PROTOCOL_NAME, turn_port_->Candidates()[0].relay_protocol());

  // There should have been at least turn_packets_.size() calls to `customizer`.
  EXPECT_GE(customizer->modify_cnt_, turn_packets_.size());

  // No channel data should be received.
  EXPECT_EQ(observer_channel_data_counter, 0u);

  // Need to release TURN port before the customizer.
  turn_port_.reset(nullptr);
}

// Do a TURN allocation, establish a TLS connection, and send some data.
// Add customizer and check that it can add attribute to messages.
// This destroys the integrity checks on the message.
// TODO: crbug.com/504567957 - enable once integrity issues have been sorted.
TEST_F(TurnPortTest, DISABLED_TestTurnCustomizerAddAttribute) {
  unsigned int observer_message_counter = 0;
  unsigned int observer_channel_data_counter = 0;
  unsigned int observer_attr_counter = 0;
  TestTurnCustomizer* customizer = new TestTurnCustomizer();
  std::unique_ptr<MessageObserver> validator(new MessageObserver(
      &observer_message_counter, &observer_channel_data_counter,
      &observer_attr_counter));
  customizer->allow_channel_data_ = false;
  customizer->add_counter_ = true;
  turn_server_.AddInternalSocket(kTurnTcpIntAddr, PROTO_TLS);
  turn_customizer_.reset(customizer);
  turn_server_.server()->SetStunMessageObserver(std::move(validator));

  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTlsProtoAddr);
  // Don't expect ECN to be propagated via TCP
  TestTurnSendData(PROTO_TLS, /*expect_ecn_propagate=*/false);
  EXPECT_EQ(TLS_PROTOCOL_NAME, turn_port_->Candidates()[0].relay_protocol());

  // There should have been at least turn_packets_.size() calls to `customizer`.
  EXPECT_GE(customizer->modify_cnt_, turn_packets_.size());

  // Everything will be sent as messages since channel data is disallowed.
  EXPECT_GE(customizer->modify_cnt_, observer_message_counter);

  // All messages should have attribute.
  EXPECT_EQ(observer_message_counter, observer_attr_counter);

  // At least allow_channel_data_cnt_ messages should have been sent.
  EXPECT_GE(customizer->modify_cnt_, customizer->allow_channel_data_cnt_);
  EXPECT_GE(customizer->allow_channel_data_cnt_, 0u);

  // No channel data should be received.
  EXPECT_EQ(observer_channel_data_counter, 0u);

  // Need to release TURN port before the customizer.
  turn_port_.reset(nullptr);
}

TEST_F(TurnPortTest, TestOverlongUsername) {
  std::string overlong_username(513, 'x');
  RelayCredentials credentials(overlong_username, kTurnPassword);
  EXPECT_FALSE(
      CreateTurnPort(overlong_username, kTurnPassword, kTurnTlsProtoAddr));
}

TEST_F(TurnPortTest, TestTurnDangerousServer) {
  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnDangerousProtoAddr);
  ASSERT_FALSE(turn_port_);
}

TEST_F(TurnPortTest, TestTurnDangerousServerPermits53) {
  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnPort53ProtoAddr);
  ASSERT_TRUE(turn_port_);
}

TEST_F(TurnPortTest, TestTurnDangerousServerPermits80) {
  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnPort80ProtoAddr);
  ASSERT_TRUE(turn_port_);
}

TEST_F(TurnPortTest, TestTurnDangerousServerPermits443) {
  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnPort443ProtoAddr);
  ASSERT_TRUE(turn_port_);
}

TEST_F(TurnPortTest, TestTurnDangerousAlternateServer) {
  const ProtocolType protocol_type = PROTO_TCP;
  std::vector<SocketAddress> redirect_addresses;
  redirect_addresses.push_back(kTurnDangerousAddr);

  TestTurnRedirector redirector(redirect_addresses);

  turn_server_.AddInternalSocket(kTurnIntAddr, protocol_type);
  turn_server_.AddInternalSocket(kTurnDangerousAddr, protocol_type);
  turn_server_.set_redirect_hook(&redirector);
  CreateTurnPort(kTurnUsername, kTurnPassword,
                 ProtocolAddress(kTurnIntAddr, protocol_type));

  // Retrieve the address before we run the state machine.
  const SocketAddress old_addr = turn_port_->server_address().address;

  turn_port_->PrepareAddress();
  // This should result in an error event.
  EXPECT_THAT(
      WaitUntil([&] { return error_event_.error_code; }, Ne(0),
                {.timeout = TimeToGetAlternateTurnCandidate(protocol_type),
                 .clock = &time_controller_}),
      IsRtcOk());
  // but should NOT result in the port turning ready, and no candidates
  // should be gathered.
  EXPECT_FALSE(turn_ready_);
  ASSERT_EQ(0U, turn_port_->Candidates().size());
}

class TurnPortWithMockDnsResolverTest : public TurnPortTest {
 public:
  TurnPortWithMockDnsResolverTest()
      : TurnPortTest(), socket_factory_(ss_.get()) {}

  PacketSocketFactory* socket_factory() override { return &socket_factory_; }

  void SetDnsResolverExpectations(
      MockDnsResolvingPacketSocketFactory::Expectations expectations) {
    socket_factory_.SetExpectations(expectations);
  }

 private:
  MockDnsResolvingPacketSocketFactory socket_factory_;
};

// Test an allocation from a TURN server specified by a hostname.
TEST_F(TurnPortWithMockDnsResolverTest, TestHostnameResolved) {
  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnPortValidHostnameProtoAddr);
  SetDnsResolverExpectations([](MockAsyncDnsResolver* resolver,
                                MockAsyncDnsResolverResult* resolver_result) {
    EXPECT_CALL(*resolver, Start(kTurnValidAddr, /*family=*/AF_INET, _))
        .WillOnce([](const SocketAddress& addr, int family,
                     absl::AnyInvocable<void()> callback) { callback(); });
    EXPECT_CALL(*resolver, result)
        .WillRepeatedly(ReturnPointee(resolver_result));
    EXPECT_CALL(*resolver_result, GetError).WillRepeatedly(Return(0));
    EXPECT_CALL(*resolver_result, GetResolvedAddress(AF_INET, _))
        .WillOnce(DoAll(SetArgPointee<1>(kTurnUdpIntAddr), Return(true)));
  });
  TestTurnAllocateSucceeds(kSimulatedRtt * 2);
}

// Test an allocation from a TURN server specified by a hostname on an IPv6
// network.
TEST_F(TurnPortWithMockDnsResolverTest, TestHostnameResolvedIPv6Network) {
  turn_server_.AddInternalSocket(kTurnUdpIPv6IntAddr, PROTO_UDP);
  CreateTurnPort(kLocalIPv6Addr, kTurnUsername, kTurnPassword,
                 kTurnPortValidHostnameProtoAddr);
  SetDnsResolverExpectations([](MockAsyncDnsResolver* resolver,
                                MockAsyncDnsResolverResult* resolver_result) {
    EXPECT_CALL(*resolver, Start(kTurnValidAddr, /*family=*/AF_INET6, _))
        .WillOnce([](const SocketAddress& addr, int family,
                     absl::AnyInvocable<void()> callback) { callback(); });
    EXPECT_CALL(*resolver, result)
        .WillRepeatedly(ReturnPointee(resolver_result));
    EXPECT_CALL(*resolver_result, GetError).WillRepeatedly(Return(0));
    EXPECT_CALL(*resolver_result, GetResolvedAddress(AF_INET6, _))
        .WillOnce(DoAll(SetArgPointee<1>(kTurnUdpIPv6IntAddr), Return(true)));
  });
  TestTurnAllocateSucceeds(kSimulatedRtt * 2);
}

static struct IPAddressTypeTestConfig {
  absl::string_view address;
  IPAddressType address_type;
} kAllIPAddressTypeTestConfigs[] = {
    {.address = "127.0.0.1", .address_type = IPAddressType::kLoopback},
    {.address = "localhost", .address_type = IPAddressType::kLoopback},
    {.address = "::1", .address_type = IPAddressType::kLoopback},
    {.address = "10.0.0.3", .address_type = IPAddressType::kPrivate},
    {.address = "fd00:4860:4860::8844",
     .address_type = IPAddressType::kPrivate},
    {.address = "1.1.1.1", .address_type = IPAddressType::kPublic},
    {.address = "2001:4860:4860::8888", .address_type = IPAddressType::kPublic},
};

// Used by the test framework to print the param value for parameterized tests.
std::string PrintToString(const IPAddressTypeTestConfig& param) {
  return std::string(param.address);
}

class TurnPortIPAddressTypeMetricsTest
    : public TurnPortWithMockDnsResolverTest,
      public ::testing::WithParamInterface<IPAddressTypeTestConfig> {};

TEST_P(TurnPortIPAddressTypeMetricsTest, TestIPAddressTypeMetrics) {
  metrics::Reset();

  SetDnsResolverExpectations(
      [](MockAsyncDnsResolver* resolver,
         MockAsyncDnsResolverResult* resolver_result) {
        EXPECT_CALL(*resolver, Start(SocketAddress("localhost", 5000),
                                     /*family=*/AF_INET, _))
            .WillOnce([](const SocketAddress& /* addr */, int /* family */,
                         absl::AnyInvocable<void()> callback) { callback(); });
        EXPECT_CALL(*resolver, result)
            .WillRepeatedly(ReturnPointee(resolver_result));
        EXPECT_CALL(*resolver_result, GetError).WillRepeatedly(Return(0));
        EXPECT_CALL(*resolver_result, GetResolvedAddress(AF_INET, _))
            .WillOnce(DoAll(SetArgPointee<1>(SocketAddress("127.0.0.1", 5000)),
                            Return(true)));
      });

  ProtocolAddress server_address({GetParam().address, 5000}, PROTO_UDP);
  SocketAddress local_address = server_address.address.family() == AF_INET6
                                    ? kLocalIPv6Addr
                                    : kLocalAddr1;
  CreateTurnPort(local_address, kTurnUsername, kTurnPassword, server_address);
  turn_port_->PrepareAddress();

  ASSERT_THAT(WaitUntil([&] { return turn_port_->HasRequests(); }, IsTrue()),
              IsRtcOk());

  auto samples =
      metrics::Samples("WebRTC.PeerConnection.Turn.ServerAddressType");
  ASSERT_EQ(samples.size(), 1u);
  EXPECT_EQ(samples[static_cast<int>(GetParam().address_type)], 1);
}

INSTANTIATE_TEST_SUITE_P(All,
                         TurnPortIPAddressTypeMetricsTest,
                         ::testing::ValuesIn(kAllIPAddressTypeTestConfigs));

}  // namespace webrtc
