/*
 *  Copyright 2019 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/connection.h"

#include <math.h>

#include <algorithm>
#include <memory>
#include <utility>
#include <vector>

#include "absl/algorithm/container.h"
#include "absl/strings/match.h"
#include "absl/strings/string_view.h"
#include "p2p/base/port_allocator.h"
#include "rtc_base/checks.h"
#include "rtc_base/crc32.h"
#include "rtc_base/helpers.h"
#include "rtc_base/logging.h"
#include "rtc_base/mdns_responder_interface.h"
#include "rtc_base/message_digest.h"
#include "rtc_base/network.h"
#include "rtc_base/numerics/safe_minmax.h"
#include "rtc_base/string_encode.h"
#include "rtc_base/string_utils.h"
#include "rtc_base/strings/string_builder.h"
#include "rtc_base/third_party/base64/base64.h"

namespace cricket {
namespace {

// Determines whether we have seen at least the given maximum number of
// pings fail to have a response.
inline bool TooManyFailures(
    const std::vector<Connection::SentPing>& pings_since_last_response,
    uint32_t maximum_failures,
    int rtt_estimate,
    int64_t now) {
  // If we haven't sent that many pings, then we can't have failed that many.
  if (pings_since_last_response.size() < maximum_failures)
    return false;

  // Check if the window in which we would expect a response to the ping has
  // already elapsed.
  int64_t expected_response_time =
      pings_since_last_response[maximum_failures - 1].sent_time + rtt_estimate;
  return now > expected_response_time;
}

// Determines whether we have gone too long without seeing any response.
inline bool TooLongWithoutResponse(
    const std::vector<Connection::SentPing>& pings_since_last_response,
    int64_t maximum_time,
    int64_t now) {
  if (pings_since_last_response.size() == 0)
    return false;

  auto first = pings_since_last_response[0];
  return now > (first.sent_time + maximum_time);
}

// Helper methods for converting string values of log description fields to
// enum.
webrtc::IceCandidateType GetCandidateTypeByString(absl::string_view type) {
  if (type == LOCAL_PORT_TYPE) {
    return webrtc::IceCandidateType::kLocal;
  } else if (type == STUN_PORT_TYPE) {
    return webrtc::IceCandidateType::kStun;
  } else if (type == PRFLX_PORT_TYPE) {
    return webrtc::IceCandidateType::kPrflx;
  } else if (type == RELAY_PORT_TYPE) {
    return webrtc::IceCandidateType::kRelay;
  }
  return webrtc::IceCandidateType::kUnknown;
}

webrtc::IceCandidatePairProtocol GetProtocolByString(
    absl::string_view protocol) {
  if (protocol == UDP_PROTOCOL_NAME) {
    return webrtc::IceCandidatePairProtocol::kUdp;
  } else if (protocol == TCP_PROTOCOL_NAME) {
    return webrtc::IceCandidatePairProtocol::kTcp;
  } else if (protocol == SSLTCP_PROTOCOL_NAME) {
    return webrtc::IceCandidatePairProtocol::kSsltcp;
  } else if (protocol == TLS_PROTOCOL_NAME) {
    return webrtc::IceCandidatePairProtocol::kTls;
  }
  return webrtc::IceCandidatePairProtocol::kUnknown;
}

webrtc::IceCandidatePairAddressFamily GetAddressFamilyByInt(
    int address_family) {
  if (address_family == AF_INET) {
    return webrtc::IceCandidatePairAddressFamily::kIpv4;
  } else if (address_family == AF_INET6) {
    return webrtc::IceCandidatePairAddressFamily::kIpv6;
  }
  return webrtc::IceCandidatePairAddressFamily::kUnknown;
}

webrtc::IceCandidateNetworkType ConvertNetworkType(rtc::AdapterType type) {
  switch (type) {
    case rtc::ADAPTER_TYPE_ETHERNET:
      return webrtc::IceCandidateNetworkType::kEthernet;
    case rtc::ADAPTER_TYPE_LOOPBACK:
      return webrtc::IceCandidateNetworkType::kLoopback;
    case rtc::ADAPTER_TYPE_WIFI:
      return webrtc::IceCandidateNetworkType::kWifi;
    case rtc::ADAPTER_TYPE_VPN:
      return webrtc::IceCandidateNetworkType::kVpn;
    case rtc::ADAPTER_TYPE_CELLULAR:
    case rtc::ADAPTER_TYPE_CELLULAR_2G:
    case rtc::ADAPTER_TYPE_CELLULAR_3G:
    case rtc::ADAPTER_TYPE_CELLULAR_4G:
    case rtc::ADAPTER_TYPE_CELLULAR_5G:
      return webrtc::IceCandidateNetworkType::kCellular;
    default:
      return webrtc::IceCandidateNetworkType::kUnknown;
  }
}

// When we don't have any RTT data, we have to pick something reasonable.  We
// use a large value just in case the connection is really slow.
const int DEFAULT_RTT = 3000;  // 3 seconds

// We will restrict RTT estimates (when used for determining state) to be
// within a reasonable range.
const int MINIMUM_RTT = 100;    // 0.1 seconds
const int MAXIMUM_RTT = 60000;  // 60 seconds

const int DEFAULT_RTT_ESTIMATE_HALF_TIME_MS = 500;

// Computes our estimate of the RTT given the current estimate.
inline int ConservativeRTTEstimate(int rtt) {
  return rtc::SafeClamp(2 * rtt, MINIMUM_RTT, MAXIMUM_RTT);
}

// Weighting of the old rtt value to new data.
const int RTT_RATIO = 3;  // 3 : 1

constexpr int64_t kMinExtraPingDelayMs = 100;

// Default field trials.
const IceFieldTrials kDefaultFieldTrials;

constexpr int kSupportGoogPingVersionRequestIndex = static_cast<int>(
    IceGoogMiscInfoBindingRequestAttributeIndex::SUPPORT_GOOG_PING_VERSION);

constexpr int kSupportGoogPingVersionResponseIndex = static_cast<int>(
    IceGoogMiscInfoBindingResponseAttributeIndex::SUPPORT_GOOG_PING_VERSION);

}  // namespace

// A ConnectionRequest is a STUN binding used to determine writability.
class Connection::ConnectionRequest : public StunRequest {
 public:
  ConnectionRequest(StunRequestManager& manager,
                    Connection* connection,
                    std::unique_ptr<IceMessage> message);
  void OnResponse(StunMessage* response) override;
  void OnErrorResponse(StunMessage* response) override;
  void OnTimeout() override;
  void OnSent() override;
  int resend_delay() override;

 private:
  Connection* const connection_;
};

Connection::ConnectionRequest::ConnectionRequest(
    StunRequestManager& manager,
    Connection* connection,
    std::unique_ptr<IceMessage> message)
    : StunRequest(manager, std::move(message)), connection_(connection) {}

void Connection::ConnectionRequest::OnResponse(StunMessage* response) {
  RTC_DCHECK_RUN_ON(connection_->network_thread_);
  connection_->OnConnectionRequestResponse(this, response);
}

void Connection::ConnectionRequest::OnErrorResponse(StunMessage* response) {
  RTC_DCHECK_RUN_ON(connection_->network_thread_);
  connection_->OnConnectionRequestErrorResponse(this, response);
}

void Connection::ConnectionRequest::OnTimeout() {
  RTC_DCHECK_RUN_ON(connection_->network_thread_);
  connection_->OnConnectionRequestTimeout(this);
}

void Connection::ConnectionRequest::OnSent() {
  RTC_DCHECK_RUN_ON(connection_->network_thread_);
  connection_->OnConnectionRequestSent(this);
  // Each request is sent only once.  After a single delay , the request will
  // time out.
  set_timed_out();
}

int Connection::ConnectionRequest::resend_delay() {
  return CONNECTION_RESPONSE_TIMEOUT;
}

Connection::Connection(rtc::WeakPtr<Port> port,
                       size_t index,
                       const Candidate& remote_candidate)
    : network_thread_(port->thread()),
      id_(rtc::CreateRandomId()),
      port_(std::move(port)),
      local_candidate_(port_->Candidates()[index]),
      remote_candidate_(remote_candidate),
      recv_rate_tracker_(100, 10u),
      send_rate_tracker_(100, 10u),
      write_state_(STATE_WRITE_INIT),
      receiving_(false),
      connected_(true),
      pruned_(false),
      use_candidate_attr_(false),
      requests_(port_->thread(),
                [this](const void* data, size_t size, StunRequest* request) {
                  OnSendStunPacket(data, size, request);
                }),
      rtt_(DEFAULT_RTT),
      last_ping_sent_(0),
      last_ping_received_(0),
      last_data_received_(0),
      last_ping_response_received_(0),
      state_(IceCandidatePairState::WAITING),
      time_created_ms_(rtc::TimeMillis()),
      field_trials_(&kDefaultFieldTrials),
      rtt_estimate_(DEFAULT_RTT_ESTIMATE_HALF_TIME_MS) {
  RTC_DCHECK_RUN_ON(network_thread_);
  RTC_DCHECK(port_);
  RTC_LOG(LS_INFO) << ToString() << ": Connection created";
}

Connection::~Connection() {
  RTC_DCHECK_RUN_ON(network_thread_);
  RTC_DCHECK(!port_);
}

webrtc::TaskQueueBase* Connection::network_thread() const {
  return network_thread_;
}

const Candidate& Connection::local_candidate() const {
  RTC_DCHECK_RUN_ON(network_thread_);
  return local_candidate_;
}

const Candidate& Connection::remote_candidate() const {
  return remote_candidate_;
}

const rtc::Network* Connection::network() const {
  return port()->Network();
}

int Connection::generation() const {
  return port()->generation();
}

uint64_t Connection::priority() const {
  if (!port_)
    return 0;

  uint64_t priority = 0;
  // RFC 5245 - 5.7.2.  Computing Pair Priority and Ordering Pairs
  // Let G be the priority for the candidate provided by the controlling
  // agent.  Let D be the priority for the candidate provided by the
  // controlled agent.
  // pair priority = 2^32*MIN(G,D) + 2*MAX(G,D) + (G>D?1:0)
  IceRole role = port_->GetIceRole();
  if (role != ICEROLE_UNKNOWN) {
    uint32_t g = 0;
    uint32_t d = 0;
    if (role == ICEROLE_CONTROLLING) {
      g = local_candidate().priority();
      d = remote_candidate_.priority();
    } else {
      g = remote_candidate_.priority();
      d = local_candidate().priority();
    }
    priority = std::min(g, d);
    priority = priority << 32;
    priority += 2 * std::max(g, d) + (g > d ? 1 : 0);
  }
  return priority;
}

void Connection::set_write_state(WriteState value) {
  RTC_DCHECK_RUN_ON(network_thread_);
  WriteState old_value = write_state_;
  write_state_ = value;
  if (value != old_value) {
    RTC_LOG(LS_VERBOSE) << ToString() << ": set_write_state from: " << old_value
                        << " to " << value;
    SignalStateChange(this);
  }
}

void Connection::UpdateReceiving(int64_t now) {
  RTC_DCHECK_RUN_ON(network_thread_);
  bool receiving;
  if (last_ping_sent() < last_ping_response_received()) {
    // We consider any candidate pair that has its last connectivity check
    // acknowledged by a response as receiving, particularly for backup
    // candidate pairs that send checks at a much slower pace than the selected
    // one. Otherwise, a backup candidate pair constantly becomes not receiving
    // as a side effect of a long ping interval, since we do not have a separate
    // receiving timeout for backup candidate pairs. See
    // IceConfig.ice_backup_candidate_pair_ping_interval,
    // IceConfig.ice_connection_receiving_timeout and their default value.
    receiving = true;
  } else {
    receiving =
        last_received() > 0 && now <= last_received() + receiving_timeout();
  }
  if (receiving_ == receiving) {
    return;
  }
  RTC_LOG(LS_VERBOSE) << ToString() << ": set_receiving to " << receiving;
  receiving_ = receiving;
  receiving_unchanged_since_ = now;
  SignalStateChange(this);
}

void Connection::set_state(IceCandidatePairState state) {
  RTC_DCHECK_RUN_ON(network_thread_);
  IceCandidatePairState old_state = state_;
  state_ = state;
  if (state != old_state) {
    RTC_LOG(LS_VERBOSE) << ToString() << ": set_state";
  }
}

void Connection::set_connected(bool value) {
  RTC_DCHECK_RUN_ON(network_thread_);
  bool old_value = connected_;
  connected_ = value;
  if (value != old_value) {
    RTC_LOG(LS_VERBOSE) << ToString() << ": Change connected_ to " << value;
    SignalStateChange(this);
  }
}

bool Connection::use_candidate_attr() const {
  RTC_DCHECK_RUN_ON(network_thread_);
  return use_candidate_attr_;
}

void Connection::set_use_candidate_attr(bool enable) {
  RTC_DCHECK_RUN_ON(network_thread_);
  use_candidate_attr_ = enable;
}

void Connection::set_nomination(uint32_t value) {
  RTC_DCHECK_RUN_ON(network_thread_);
  nomination_ = value;
}

uint32_t Connection::remote_nomination() const {
  RTC_DCHECK_RUN_ON(network_thread_);
  return remote_nomination_;
}

bool Connection::nominated() const {
  RTC_DCHECK_RUN_ON(network_thread_);
  return acked_nomination_ || remote_nomination_;
}

int Connection::unwritable_timeout() const {
  RTC_DCHECK_RUN_ON(network_thread_);
  return unwritable_timeout_.value_or(CONNECTION_WRITE_CONNECT_TIMEOUT);
}

void Connection::set_unwritable_timeout(const absl::optional<int>& value_ms) {
  RTC_DCHECK_RUN_ON(network_thread_);
  unwritable_timeout_ = value_ms;
}

int Connection::unwritable_min_checks() const {
  RTC_DCHECK_RUN_ON(network_thread_);
  return unwritable_min_checks_.value_or(CONNECTION_WRITE_CONNECT_FAILURES);
}

void Connection::set_unwritable_min_checks(const absl::optional<int>& value) {
  RTC_DCHECK_RUN_ON(network_thread_);
  unwritable_min_checks_ = value;
}

int Connection::inactive_timeout() const {
  RTC_DCHECK_RUN_ON(network_thread_);
  return inactive_timeout_.value_or(CONNECTION_WRITE_TIMEOUT);
}

void Connection::set_inactive_timeout(const absl::optional<int>& value) {
  RTC_DCHECK_RUN_ON(network_thread_);
  inactive_timeout_ = value;
}

int Connection::receiving_timeout() const {
  RTC_DCHECK_RUN_ON(network_thread_);
  return receiving_timeout_.value_or(WEAK_CONNECTION_RECEIVE_TIMEOUT);
}

void Connection::set_receiving_timeout(
    absl::optional<int> receiving_timeout_ms) {
  RTC_DCHECK_RUN_ON(network_thread_);
  receiving_timeout_ = receiving_timeout_ms;
}

void Connection::SetIceFieldTrials(const IceFieldTrials* field_trials) {
  RTC_DCHECK_RUN_ON(network_thread_);
  field_trials_ = field_trials;
  rtt_estimate_.SetHalfTime(field_trials->rtt_estimate_halftime_ms);
}

void Connection::OnSendStunPacket(const void* data,
                                  size_t size,
                                  StunRequest* req) {
  RTC_DCHECK_RUN_ON(network_thread_);
  rtc::PacketOptions options(port_->StunDscpValue());
  options.info_signaled_after_sent.packet_type =
      rtc::PacketType::kIceConnectivityCheck;
  auto err =
      port_->SendTo(data, size, remote_candidate_.address(), options, false);
  if (err < 0) {
    RTC_LOG(LS_WARNING) << ToString()
                        << ": Failed to send STUN ping "
                           " err="
                        << err << " id=" << rtc::hex_encode(req->id());
  }
}

void Connection::OnReadPacket(const char* data,
                              size_t size,
                              int64_t packet_time_us) {
  RTC_DCHECK_RUN_ON(network_thread_);
  std::unique_ptr<IceMessage> msg;
  std::string remote_ufrag;
  const rtc::SocketAddress& addr(remote_candidate_.address());
  if (!port_->GetStunMessage(data, size, addr, &msg, &remote_ufrag)) {
    // The packet did not parse as a valid STUN message
    // This is a data packet, pass it along.
    last_data_received_ = rtc::TimeMillis();
    UpdateReceiving(last_data_received_);
    recv_rate_tracker_.AddSamples(size);
    stats_.packets_received++;
    SignalReadPacket(this, data, size, packet_time_us);

    // If timed out sending writability checks, start up again
    if (!pruned_ && (write_state_ == STATE_WRITE_TIMEOUT)) {
      RTC_LOG(LS_WARNING)
          << "Received a data packet on a timed-out Connection. "
             "Resetting state to STATE_WRITE_INIT.";
      set_write_state(STATE_WRITE_INIT);
    }
  } else if (!msg) {
    // The packet was STUN, but failed a check and was handled internally.
  } else {
    // The packet is STUN and passed the Port checks.
    // Perform our own checks to ensure this packet is valid.
    // If this is a STUN request, then update the receiving bit and respond.
    // If this is a STUN response, then update the writable bit.
    // Log at LS_INFO if we receive a ping on an unwritable connection.
    rtc::LoggingSeverity sev = (!writable() ? rtc::LS_INFO : rtc::LS_VERBOSE);
    msg->ValidateMessageIntegrity(remote_candidate().password());
    switch (msg->type()) {
      case STUN_BINDING_REQUEST:
        RTC_LOG_V(sev) << ToString() << ": Received "
                       << StunMethodToString(msg->type())
                       << ", id=" << rtc::hex_encode(msg->transaction_id());
        if (remote_ufrag == remote_candidate_.username()) {
          HandleStunBindingOrGoogPingRequest(msg.get());
        } else {
          // The packet had the right local username, but the remote username
          // was not the right one for the remote address.
          RTC_LOG(LS_ERROR)
              << ToString()
              << ": Received STUN request with bad remote username "
              << remote_ufrag;
          port_->SendBindingErrorResponse(msg.get(), addr,
                                          STUN_ERROR_UNAUTHORIZED,
                                          STUN_ERROR_REASON_UNAUTHORIZED);
        }
        break;

      // Response from remote peer. Does it match request sent?
      // This doesn't just check, it makes callbacks if transaction
      // id's match.
      case STUN_BINDING_RESPONSE:
      case STUN_BINDING_ERROR_RESPONSE:
        if (msg->IntegrityOk()) {
          requests_.CheckResponse(msg.get());
        }
        // Otherwise silently discard the response.
        break;

      // Remote end point sent an STUN indication instead of regular binding
      // request. In this case `last_ping_received_` will be updated but no
      // response will be sent.
      case STUN_BINDING_INDICATION:
        ReceivedPing(msg->transaction_id());
        break;
      case GOOG_PING_REQUEST:
        HandleStunBindingOrGoogPingRequest(msg.get());
        break;
      case GOOG_PING_RESPONSE:
      case GOOG_PING_ERROR_RESPONSE:
        if (msg->IntegrityOk()) {
          requests_.CheckResponse(msg.get());
        }
        break;
      default:
        RTC_DCHECK_NOTREACHED();
        break;
    }
  }
}

void Connection::HandleStunBindingOrGoogPingRequest(IceMessage* msg) {
  RTC_DCHECK_RUN_ON(network_thread_);
  // This connection should now be receiving.
  ReceivedPing(msg->transaction_id());
  if (field_trials_->extra_ice_ping && last_ping_response_received_ == 0) {
    if (local_candidate().type() == RELAY_PORT_TYPE ||
        local_candidate().type() == PRFLX_PORT_TYPE ||
        remote_candidate().type() == RELAY_PORT_TYPE ||
        remote_candidate().type() == PRFLX_PORT_TYPE) {
      const int64_t now = rtc::TimeMillis();
      if (last_ping_sent_ + kMinExtraPingDelayMs <= now) {
        RTC_LOG(LS_INFO) << ToString()
                         << "WebRTC-ExtraICEPing/Sending extra ping"
                            " last_ping_sent_: "
                         << last_ping_sent_ << " now: " << now
                         << " (diff: " << (now - last_ping_sent_) << ")";
        Ping(now);
      } else {
        RTC_LOG(LS_INFO) << ToString()
                         << "WebRTC-ExtraICEPing/Not sending extra ping"
                            " last_ping_sent_: "
                         << last_ping_sent_ << " now: " << now
                         << " (diff: " << (now - last_ping_sent_) << ")";
      }
    }
  }

  const rtc::SocketAddress& remote_addr = remote_candidate_.address();
  if (msg->type() == STUN_BINDING_REQUEST) {
    // Check for role conflicts.
    const std::string& remote_ufrag = remote_candidate_.username();
    if (!port_->MaybeIceRoleConflict(remote_addr, msg, remote_ufrag)) {
      // Received conflicting role from the peer.
      RTC_LOG(LS_INFO) << "Received conflicting role from the peer.";
      return;
    }
  }

  stats_.recv_ping_requests++;
  LogCandidatePairEvent(webrtc::IceCandidatePairEventType::kCheckReceived,
                        msg->reduced_transaction_id());

  // This is a validated stun request from remote peer.
  if (msg->type() == STUN_BINDING_REQUEST) {
    SendStunBindingResponse(msg);
  } else {
    RTC_DCHECK(msg->type() == GOOG_PING_REQUEST);
    SendGoogPingResponse(msg);
  }

  // If it timed out on writing check, start up again
  if (!pruned_ && write_state_ == STATE_WRITE_TIMEOUT) {
    set_write_state(STATE_WRITE_INIT);
  }

  if (port_->GetIceRole() == ICEROLE_CONTROLLED) {
    const StunUInt32Attribute* nomination_attr =
        msg->GetUInt32(STUN_ATTR_NOMINATION);
    uint32_t nomination = 0;
    if (nomination_attr) {
      nomination = nomination_attr->value();
      if (nomination == 0) {
        RTC_LOG(LS_ERROR) << "Invalid nomination: " << nomination;
      }
    } else {
      const StunByteStringAttribute* use_candidate_attr =
          msg->GetByteString(STUN_ATTR_USE_CANDIDATE);
      if (use_candidate_attr) {
        nomination = 1;
      }
    }
    // We don't un-nominate a connection, so we only keep a larger nomination.
    if (nomination > remote_nomination_) {
      set_remote_nomination(nomination);
      SignalNominated(this);
    }
  }
  // Set the remote cost if the network_info attribute is available.
  // Note: If packets are re-ordered, we may get incorrect network cost
  // temporarily, but it should get the correct value shortly after that.
  const StunUInt32Attribute* network_attr =
      msg->GetUInt32(STUN_ATTR_GOOG_NETWORK_INFO);
  if (network_attr) {
    uint32_t network_info = network_attr->value();
    uint16_t network_cost = static_cast<uint16_t>(network_info);
    if (network_cost != remote_candidate_.network_cost()) {
      remote_candidate_.set_network_cost(network_cost);
      // Network cost change will affect the connection ranking, so signal
      // state change to force a re-sort in P2PTransportChannel.
      SignalStateChange(this);
    }
  }

  if (field_trials_->piggyback_ice_check_acknowledgement) {
    HandlePiggybackCheckAcknowledgementIfAny(msg);
  }
}

void Connection::SendStunBindingResponse(const StunMessage* message) {
  RTC_DCHECK_RUN_ON(network_thread_);
  RTC_DCHECK_EQ(message->type(), STUN_BINDING_REQUEST);

  // Retrieve the username from the `message`.
  const StunByteStringAttribute* username_attr =
      message->GetByteString(STUN_ATTR_USERNAME);
  RTC_DCHECK(username_attr != NULL);
  if (username_attr == NULL) {
    // No valid username, skip the response.
    return;
  }

  // Fill in the response.
  StunMessage response(STUN_BINDING_RESPONSE, message->transaction_id());
  const StunUInt32Attribute* retransmit_attr =
      message->GetUInt32(STUN_ATTR_RETRANSMIT_COUNT);
  if (retransmit_attr) {
    // Inherit the incoming retransmit value in the response so the other side
    // can see our view of lost pings.
    response.AddAttribute(std::make_unique<StunUInt32Attribute>(
        STUN_ATTR_RETRANSMIT_COUNT, retransmit_attr->value()));

    if (retransmit_attr->value() > CONNECTION_WRITE_CONNECT_FAILURES) {
      RTC_LOG(LS_INFO)
          << ToString()
          << ": Received a remote ping with high retransmit count: "
          << retransmit_attr->value();
    }
  }

  response.AddAttribute(std::make_unique<StunXorAddressAttribute>(
      STUN_ATTR_XOR_MAPPED_ADDRESS, remote_candidate_.address()));

  if (field_trials_->announce_goog_ping) {
    // Check if message contains a announce-request.
    auto goog_misc = message->GetUInt16List(STUN_ATTR_GOOG_MISC_INFO);
    if (goog_misc != nullptr &&
        goog_misc->Size() >= kSupportGoogPingVersionRequestIndex &&
        // Which version can we handle...currently any >= 1
        goog_misc->GetType(kSupportGoogPingVersionRequestIndex) >= 1) {
      auto list =
          StunAttribute::CreateUInt16ListAttribute(STUN_ATTR_GOOG_MISC_INFO);
      list->AddTypeAtIndex(kSupportGoogPingVersionResponseIndex,
                           kGoogPingVersion);
      response.AddAttribute(std::move(list));
    }
  }

  response.AddMessageIntegrity(local_candidate().password());
  response.AddFingerprint();

  SendResponseMessage(response);
}

void Connection::SendGoogPingResponse(const StunMessage* message) {
  RTC_DCHECK_RUN_ON(network_thread_);
  RTC_DCHECK(message->type() == GOOG_PING_REQUEST);

  // Fill in the response.
  StunMessage response(GOOG_PING_RESPONSE, message->transaction_id());
  response.AddMessageIntegrity32(local_candidate().password());
  SendResponseMessage(response);
}

void Connection::SendResponseMessage(const StunMessage& response) {
  RTC_DCHECK_RUN_ON(network_thread_);
  // Where I send the response.
  const rtc::SocketAddress& addr = remote_candidate_.address();

  // Send the response.
  rtc::ByteBufferWriter buf;
  response.Write(&buf);
  rtc::PacketOptions options(port_->StunDscpValue());
  options.info_signaled_after_sent.packet_type =
      rtc::PacketType::kIceConnectivityCheckResponse;
  auto err = port_->SendTo(buf.Data(), buf.Length(), addr, options, false);
  if (err < 0) {
    RTC_LOG(LS_ERROR) << ToString() << ": Failed to send "
                      << StunMethodToString(response.type())
                      << ", to=" << addr.ToSensitiveString() << ", err=" << err
                      << ", id=" << rtc::hex_encode(response.transaction_id());
  } else {
    // Log at LS_INFO if we send a stun ping response on an unwritable
    // connection.
    rtc::LoggingSeverity sev = (!writable()) ? rtc::LS_INFO : rtc::LS_VERBOSE;
    RTC_LOG_V(sev) << ToString() << ": Sent "
                   << StunMethodToString(response.type())
                   << ", to=" << addr.ToSensitiveString()
                   << ", id=" << rtc::hex_encode(response.transaction_id());

    stats_.sent_ping_responses++;
    LogCandidatePairEvent(webrtc::IceCandidatePairEventType::kCheckResponseSent,
                          response.reduced_transaction_id());
  }
}

uint32_t Connection::acked_nomination() const {
  RTC_DCHECK_RUN_ON(network_thread_);
  return acked_nomination_;
}

void Connection::set_remote_nomination(uint32_t remote_nomination) {
  RTC_DCHECK_RUN_ON(network_thread_);
  remote_nomination_ = remote_nomination;
}

void Connection::OnReadyToSend() {
  RTC_DCHECK_RUN_ON(network_thread_);
  SignalReadyToSend(this);
}

bool Connection::pruned() const {
  RTC_DCHECK_RUN_ON(network_thread_);
  return pruned_;
}

void Connection::Prune() {
  RTC_DCHECK_RUN_ON(network_thread_);
  if (!pruned_ || active()) {
    RTC_LOG(LS_INFO) << ToString() << ": Connection pruned";
    pruned_ = true;
    requests_.Clear();
    set_write_state(STATE_WRITE_TIMEOUT);
  }
}

void Connection::Destroy() {
  RTC_DCHECK_RUN_ON(network_thread_);
  RTC_DCHECK(port_) << "Calling Destroy() twice?";
  if (port_)
    port_->DestroyConnection(this);
}

bool Connection::Shutdown() {
  RTC_DCHECK_RUN_ON(network_thread_);
  if (!port_)
    return false;  // already shut down.

  RTC_DLOG(LS_VERBOSE) << ToString() << ": Connection destroyed";

  // Fire the 'destroyed' event before deleting the object. This is done
  // intentionally to avoid a situation whereby the signal might have dangling
  // pointers to objects that have been deleted by the time the async task
  // that deletes the connection object runs.
  auto destroyed_signals = SignalDestroyed;
  SignalDestroyed.disconnect_all();
  destroyed_signals(this);

  LogCandidatePairConfig(webrtc::IceCandidatePairConfigType::kDestroyed);

  // Reset the `port_` after logging and firing the destroyed signal since
  // information required for logging needs access to `port_`.
  port_.reset();

  return true;
}

void Connection::FailAndPrune() {
  RTC_DCHECK_RUN_ON(network_thread_);

  // TODO(bugs.webrtc.org/13865): There's a circular dependency between Port
  // and Connection. In some cases (Port dtor), a Connection object is deleted
  // without using the `Destroy` method (port_ won't be nulled and some
  // functionality won't run as expected), while in other cases
  // the Connection object is deleted asynchronously and in that case `port_`
  // will be nulled.
  // In such a case, there's a chance that the Port object gets
  // deleted before the Connection object ends up being deleted.
  if (!port_)
    return;

  set_state(IceCandidatePairState::FAILED);
  Prune();
}

void Connection::PrintPingsSinceLastResponse(std::string* s, size_t max) {
  RTC_DCHECK_RUN_ON(network_thread_);
  rtc::StringBuilder oss;
  if (pings_since_last_response_.size() > max) {
    for (size_t i = 0; i < max; i++) {
      const SentPing& ping = pings_since_last_response_[i];
      oss << rtc::hex_encode(ping.id) << " ";
    }
    oss << "... " << (pings_since_last_response_.size() - max) << " more";
  } else {
    for (const SentPing& ping : pings_since_last_response_) {
      oss << rtc::hex_encode(ping.id) << " ";
    }
  }
  *s = oss.str();
}

bool Connection::selected() const {
  RTC_DCHECK_RUN_ON(network_thread_);
  return selected_;
}

void Connection::set_selected(bool selected) {
  RTC_DCHECK_RUN_ON(network_thread_);
  selected_ = selected;
}

void Connection::UpdateState(int64_t now) {
  RTC_DCHECK_RUN_ON(network_thread_);
  if (!port_)
    return;

  int rtt = ConservativeRTTEstimate(rtt_);

  if (RTC_LOG_CHECK_LEVEL(LS_VERBOSE)) {
    std::string pings;
    PrintPingsSinceLastResponse(&pings, 5);
    RTC_LOG(LS_VERBOSE) << ToString()
                        << ": UpdateState()"
                           ", ms since last received response="
                        << now - last_ping_response_received_
                        << ", ms since last received data="
                        << now - last_data_received_ << ", rtt=" << rtt
                        << ", pings_since_last_response=" << pings;
  }

  // Check the writable state.  (The order of these checks is important.)
  //
  // Before becoming unwritable, we allow for a fixed number of pings to fail
  // (i.e., receive no response).  We also have to give the response time to
  // get back, so we include a conservative estimate of this.
  //
  // Before timing out writability, we give a fixed amount of time.  This is to
  // allow for changes in network conditions.

  if ((write_state_ == STATE_WRITABLE) &&
      TooManyFailures(pings_since_last_response_, unwritable_min_checks(), rtt,
                      now) &&
      TooLongWithoutResponse(pings_since_last_response_, unwritable_timeout(),
                             now)) {
    uint32_t max_pings = unwritable_min_checks();
    RTC_LOG(LS_INFO) << ToString() << ": Unwritable after " << max_pings
                     << " ping failures and "
                     << now - pings_since_last_response_[0].sent_time
                     << " ms without a response,"
                        " ms since last received ping="
                     << now - last_ping_received_
                     << " ms since last received data="
                     << now - last_data_received_ << " rtt=" << rtt;
    set_write_state(STATE_WRITE_UNRELIABLE);
  }
  if ((write_state_ == STATE_WRITE_UNRELIABLE ||
       write_state_ == STATE_WRITE_INIT) &&
      TooLongWithoutResponse(pings_since_last_response_, inactive_timeout(),
                             now)) {
    RTC_LOG(LS_INFO) << ToString() << ": Timed out after "
                     << now - pings_since_last_response_[0].sent_time
                     << " ms without a response, rtt=" << rtt;
    set_write_state(STATE_WRITE_TIMEOUT);
  }

  // Update the receiving state.
  UpdateReceiving(now);
  if (dead(now)) {
    port_->DestroyConnectionAsync(this);
  }
}

void Connection::UpdateLocalIceParameters(int component,
                                          absl::string_view username_fragment,
                                          absl::string_view password) {
  RTC_DCHECK_RUN_ON(network_thread_);
  local_candidate_.set_component(component);
  local_candidate_.set_username(username_fragment);
  local_candidate_.set_password(password);
}

int64_t Connection::last_ping_sent() const {
  RTC_DCHECK_RUN_ON(network_thread_);
  return last_ping_sent_;
}

void Connection::Ping(int64_t now) {
  RTC_DCHECK_RUN_ON(network_thread_);
  if (!port_)
    return;

  last_ping_sent_ = now;

  // If not using renomination, we use "1" to mean "nominated" and "0" to mean
  // "not nominated". If using renomination, values greater than 1 are used for
  // re-nominated pairs.
  int nomination = use_candidate_attr_ ? 1 : 0;
  if (nomination_ > 0) {
    nomination = nomination_;
  }

  auto req =
      std::make_unique<ConnectionRequest>(requests_, this, BuildPingRequest());

  if (ShouldSendGoogPing(req->msg())) {
    auto message = std::make_unique<IceMessage>(GOOG_PING_REQUEST, req->id());
    message->AddMessageIntegrity32(remote_candidate_.password());
    req.reset(new ConnectionRequest(requests_, this, std::move(message)));
  }

  pings_since_last_response_.push_back(SentPing(req->id(), now, nomination));
  RTC_LOG(LS_VERBOSE) << ToString() << ": Sending STUN ping, id="
                      << rtc::hex_encode(req->id())
                      << ", nomination=" << nomination_;
  requests_.Send(req.release());
  state_ = IceCandidatePairState::IN_PROGRESS;
  num_pings_sent_++;
}

std::unique_ptr<IceMessage> Connection::BuildPingRequest() {
  auto message = std::make_unique<IceMessage>(STUN_BINDING_REQUEST);
  // Note that the order of attributes does not impact the parsing on the
  // receiver side. The attribute is retrieved then by iterating and matching
  // over all parsed attributes. See StunMessage::GetAttribute.
  message->AddAttribute(std::make_unique<StunByteStringAttribute>(
      STUN_ATTR_USERNAME,
      port()->CreateStunUsername(remote_candidate_.username())));
  message->AddAttribute(std::make_unique<StunUInt32Attribute>(
      STUN_ATTR_GOOG_NETWORK_INFO,
      (port_->Network()->id() << 16) | port_->network_cost()));

  if (field_trials_->piggyback_ice_check_acknowledgement &&
      last_ping_id_received_) {
    message->AddAttribute(std::make_unique<StunByteStringAttribute>(
        STUN_ATTR_GOOG_LAST_ICE_CHECK_RECEIVED, *last_ping_id_received_));
  }

  // Adding ICE_CONTROLLED or ICE_CONTROLLING attribute based on the role.
  IceRole ice_role = port_->GetIceRole();
  RTC_DCHECK(ice_role == ICEROLE_CONTROLLING || ice_role == ICEROLE_CONTROLLED);
  message->AddAttribute(std::make_unique<StunUInt64Attribute>(
      ice_role == ICEROLE_CONTROLLING ? STUN_ATTR_ICE_CONTROLLING
                                      : STUN_ATTR_ICE_CONTROLLED,
      port_->IceTiebreaker()));

  if (ice_role == ICEROLE_CONTROLLING) {
    // We should have either USE_CANDIDATE attribute or ICE_NOMINATION
    // attribute but not both. That was enforced in p2ptransportchannel.
    if (use_candidate_attr()) {
      message->AddAttribute(
          std::make_unique<StunByteStringAttribute>(STUN_ATTR_USE_CANDIDATE));
    }
    if (nomination_ && nomination_ != acked_nomination()) {
      message->AddAttribute(std::make_unique<StunUInt32Attribute>(
          STUN_ATTR_NOMINATION, nomination_));
    }
  }

  message->AddAttribute(std::make_unique<StunUInt32Attribute>(
      STUN_ATTR_PRIORITY, prflx_priority()));

  if (port()->send_retransmit_count_attribute()) {
    message->AddAttribute(std::make_unique<StunUInt32Attribute>(
        STUN_ATTR_RETRANSMIT_COUNT, pings_since_last_response_.size()));
  }
  if (field_trials_->enable_goog_ping &&
      !remote_support_goog_ping_.has_value()) {
    // Check if remote supports GOOG PING by announcing which version we
    // support. This is sent on all STUN_BINDING_REQUEST until we get a
    // STUN_BINDING_RESPONSE.
    auto list =
        StunAttribute::CreateUInt16ListAttribute(STUN_ATTR_GOOG_MISC_INFO);
    list->AddTypeAtIndex(kSupportGoogPingVersionRequestIndex, kGoogPingVersion);
    message->AddAttribute(std::move(list));
  }
  message->AddMessageIntegrity(remote_candidate_.password());
  message->AddFingerprint();

  return message;
}

int64_t Connection::last_ping_response_received() const {
  RTC_DCHECK_RUN_ON(network_thread_);
  return last_ping_response_received_;
}

const absl::optional<std::string>& Connection::last_ping_id_received() const {
  RTC_DCHECK_RUN_ON(network_thread_);
  return last_ping_id_received_;
}

// Used to check if any STUN ping response has been received.
int Connection::rtt_samples() const {
  RTC_DCHECK_RUN_ON(network_thread_);
  return rtt_samples_;
}

// Called whenever a valid ping is received on this connection.  This is
// public because the connection intercepts the first ping for us.
int64_t Connection::last_ping_received() const {
  RTC_DCHECK_RUN_ON(network_thread_);
  return last_ping_received_;
}

void Connection::ReceivedPing(const absl::optional<std::string>& request_id) {
  RTC_DCHECK_RUN_ON(network_thread_);
  last_ping_received_ = rtc::TimeMillis();
  last_ping_id_received_ = request_id;
  UpdateReceiving(last_ping_received_);
}

void Connection::HandlePiggybackCheckAcknowledgementIfAny(StunMessage* msg) {
  RTC_DCHECK_RUN_ON(network_thread_);
  RTC_DCHECK(msg->type() == STUN_BINDING_REQUEST ||
             msg->type() == GOOG_PING_REQUEST);
  const StunByteStringAttribute* last_ice_check_received_attr =
      msg->GetByteString(STUN_ATTR_GOOG_LAST_ICE_CHECK_RECEIVED);
  if (last_ice_check_received_attr) {
    const absl::string_view request_id =
        last_ice_check_received_attr->string_view();
    auto iter = absl::c_find_if(
        pings_since_last_response_,
        [&request_id](const SentPing& ping) { return ping.id == request_id; });
    if (iter != pings_since_last_response_.end()) {
      rtc::LoggingSeverity sev = !writable() ? rtc::LS_INFO : rtc::LS_VERBOSE;
      RTC_LOG_V(sev) << ToString()
                     << ": Received piggyback STUN ping response, id="
                     << rtc::hex_encode(request_id);
      const int64_t rtt = rtc::TimeMillis() - iter->sent_time;
      ReceivedPingResponse(rtt, request_id, iter->nomination);
    }
  }
}

int64_t Connection::last_send_data() const {
  RTC_DCHECK_RUN_ON(network_thread_);
  return last_send_data_;
}

int64_t Connection::last_data_received() const {
  RTC_DCHECK_RUN_ON(network_thread_);
  return last_data_received_;
}

void Connection::ReceivedPingResponse(
    int rtt,
    absl::string_view request_id,
    const absl::optional<uint32_t>& nomination) {
  RTC_DCHECK_RUN_ON(network_thread_);
  RTC_DCHECK_GE(rtt, 0);
  // We've already validated that this is a STUN binding response with
  // the correct local and remote username for this connection.
  // So if we're not already, become writable. We may be bringing a pruned
  // connection back to life, but if we don't really want it, we can always
  // prune it again.
  if (nomination && nomination.value() > acked_nomination_) {
    acked_nomination_ = nomination.value();
  }

  int64_t now = rtc::TimeMillis();
  total_round_trip_time_ms_ += rtt;
  current_round_trip_time_ms_ = static_cast<uint32_t>(rtt);
  rtt_estimate_.AddSample(now, rtt);

  pings_since_last_response_.clear();
  last_ping_response_received_ = now;
  UpdateReceiving(last_ping_response_received_);
  set_write_state(STATE_WRITABLE);
  set_state(IceCandidatePairState::SUCCEEDED);
  if (rtt_samples_ > 0) {
    rtt_ = rtc::GetNextMovingAverage(rtt_, rtt, RTT_RATIO);
  } else {
    rtt_ = rtt;
  }
  rtt_samples_++;
}

Connection::WriteState Connection::write_state() const {
  RTC_DCHECK_RUN_ON(network_thread_);
  return write_state_;
}

bool Connection::writable() const {
  RTC_DCHECK_RUN_ON(network_thread_);
  return write_state_ == STATE_WRITABLE;
}

bool Connection::receiving() const {
  RTC_DCHECK_RUN_ON(network_thread_);
  return receiving_;
}

// Determines whether the connection has finished connecting.  This can only
// be false for TCP connections.
bool Connection::connected() const {
  RTC_DCHECK_RUN_ON(network_thread_);
  return connected_;
}

bool Connection::weak() const {
  return !(writable() && receiving() && connected());
}

bool Connection::active() const {
  RTC_DCHECK_RUN_ON(network_thread_);
  return write_state_ != STATE_WRITE_TIMEOUT;
}

bool Connection::dead(int64_t now) const {
  RTC_DCHECK_RUN_ON(network_thread_);
  if (last_received() > 0) {
    // If it has ever received anything, we keep it alive
    // - if it has recevied last DEAD_CONNECTION_RECEIVE_TIMEOUT (30s)
    // - if it has a ping outstanding shorter than
    // DEAD_CONNECTION_RECEIVE_TIMEOUT (30s)
    // - else if IDLE let it live field_trials_->dead_connection_timeout_ms
    //
    // This covers the normal case of a successfully used connection that stops
    // working. This also allows a remote peer to continue pinging over a
    // locally inactive (pruned) connection. This also allows the local agent to
    // ping with longer interval than 30s as long as it shorter than
    // `dead_connection_timeout_ms`.
    if (now <= (last_received() + DEAD_CONNECTION_RECEIVE_TIMEOUT)) {
      // Not dead since we have received the last 30s.
      return false;
    }
    if (!pings_since_last_response_.empty()) {
      // Outstanding pings: let it live until the ping is unreplied for
      // DEAD_CONNECTION_RECEIVE_TIMEOUT.
      return now > (pings_since_last_response_[0].sent_time +
                    DEAD_CONNECTION_RECEIVE_TIMEOUT);
    }

    // No outstanding pings: let it live until
    // field_trials_->dead_connection_timeout_ms has passed.
    return now > (last_received() + field_trials_->dead_connection_timeout_ms);
  }

  if (active()) {
    // If it has never received anything, keep it alive as long as it is
    // actively pinging and not pruned. Otherwise, the connection might be
    // deleted before it has a chance to ping. This is the normal case for a
    // new connection that is pinging but hasn't received anything yet.
    return false;
  }

  // If it has never received anything and is not actively pinging (pruned), we
  // keep it around for at least MIN_CONNECTION_LIFETIME to prevent connections
  // from being pruned too quickly during a network change event when two
  // networks would be up simultaneously but only for a brief period.
  return now > (time_created_ms_ + MIN_CONNECTION_LIFETIME);
}

int Connection::rtt() const {
  RTC_DCHECK_RUN_ON(network_thread_);
  return rtt_;
}

bool Connection::stable(int64_t now) const {
  // A connection is stable if it's RTT has converged and it isn't missing any
  // responses.  We should send pings at a higher rate until the RTT converges
  // and whenever a ping response is missing (so that we can detect
  // unwritability faster)
  return rtt_converged() && !missing_responses(now);
}

std::string Connection::ToDebugId() const {
  return rtc::ToHex(reinterpret_cast<uintptr_t>(this));
}

uint32_t Connection::ComputeNetworkCost() const {
  // TODO(honghaiz): Will add rtt as part of the network cost.
  return port()->network_cost() + remote_candidate_.network_cost();
}

std::string Connection::ToString() const {
  RTC_DCHECK_RUN_ON(network_thread_);
  constexpr absl::string_view CONNECT_STATE_ABBREV[2] = {
      "-",  // not connected (false)
      "C",  // connected (true)
  };
  constexpr absl::string_view RECEIVE_STATE_ABBREV[2] = {
      "-",  // not receiving (false)
      "R",  // receiving (true)
  };
  constexpr absl::string_view WRITE_STATE_ABBREV[4] = {
      "W",  // STATE_WRITABLE
      "w",  // STATE_WRITE_UNRELIABLE
      "-",  // STATE_WRITE_INIT
      "x",  // STATE_WRITE_TIMEOUT
  };
  constexpr absl::string_view ICESTATE[4] = {
      "W",  // STATE_WAITING
      "I",  // STATE_INPROGRESS
      "S",  // STATE_SUCCEEDED
      "F"   // STATE_FAILED
  };
  constexpr absl::string_view SELECTED_STATE_ABBREV[2] = {
      "-",  // candidate pair not selected (false)
      "S",  // selected (true)
  };
  rtc::StringBuilder ss;
  ss << "Conn[" << ToDebugId();

  if (!port_) {
    // No content or network names for pending delete. Temporarily substitute
    // the names with a hash (rhyming with trash).
    ss << ":#:#:";
  } else {
    ss << ":" << port_->content_name() << ":" << port_->Network()->ToString()
       << ":";
  }

  const Candidate& local = local_candidate();
  const Candidate& remote = remote_candidate();
  ss << local.id() << ":" << local.component() << ":" << local.generation()
     << ":" << local.type() << ":" << local.protocol() << ":"
     << local.address().ToSensitiveString() << "->" << remote.id() << ":"
     << remote.component() << ":" << remote.priority() << ":" << remote.type()
     << ":" << remote.protocol() << ":" << remote.address().ToSensitiveString()
     << "|";

  ss << CONNECT_STATE_ABBREV[connected_] << RECEIVE_STATE_ABBREV[receiving_]
     << WRITE_STATE_ABBREV[write_state_] << ICESTATE[static_cast<int>(state_)]
     << "|" << SELECTED_STATE_ABBREV[selected_] << "|" << remote_nomination_
     << "|" << nomination_ << "|";

  if (port_)
    ss << priority() << "|";

  if (rtt_ < DEFAULT_RTT) {
    ss << rtt_ << "]";
  } else {
    ss << "-]";
  }

  return ss.Release();
}

std::string Connection::ToSensitiveString() const {
  return ToString();
}

const webrtc::IceCandidatePairDescription& Connection::ToLogDescription() {
  RTC_DCHECK_RUN_ON(network_thread_);
  if (log_description_.has_value()) {
    return log_description_.value();
  }
  const Candidate& local = local_candidate();
  const Candidate& remote = remote_candidate();
  const rtc::Network* network = port()->Network();
  log_description_ = webrtc::IceCandidatePairDescription();
  log_description_->local_candidate_type =
      GetCandidateTypeByString(local.type());
  log_description_->local_relay_protocol =
      GetProtocolByString(local.relay_protocol());
  log_description_->local_network_type = ConvertNetworkType(network->type());
  log_description_->local_address_family =
      GetAddressFamilyByInt(local.address().family());
  log_description_->remote_candidate_type =
      GetCandidateTypeByString(remote.type());
  log_description_->remote_address_family =
      GetAddressFamilyByInt(remote.address().family());
  log_description_->candidate_pair_protocol =
      GetProtocolByString(local.protocol());
  return log_description_.value();
}

void Connection::set_ice_event_log(webrtc::IceEventLog* ice_event_log) {
  RTC_DCHECK_RUN_ON(network_thread_);
  ice_event_log_ = ice_event_log;
}

void Connection::LogCandidatePairConfig(
    webrtc::IceCandidatePairConfigType type) {
  RTC_DCHECK_RUN_ON(network_thread_);
  if (ice_event_log_ == nullptr) {
    return;
  }
  ice_event_log_->LogCandidatePairConfig(type, id(), ToLogDescription());
}

void Connection::LogCandidatePairEvent(webrtc::IceCandidatePairEventType type,
                                       uint32_t transaction_id) {
  RTC_DCHECK_RUN_ON(network_thread_);
  if (ice_event_log_ == nullptr) {
    return;
  }
  ice_event_log_->LogCandidatePairEvent(type, id(), transaction_id);
}

void Connection::OnConnectionRequestResponse(StunRequest* request,
                                             StunMessage* response) {
  RTC_DCHECK_RUN_ON(network_thread_);
  // Log at LS_INFO if we receive a ping response on an unwritable
  // connection.
  rtc::LoggingSeverity sev = !writable() ? rtc::LS_INFO : rtc::LS_VERBOSE;

  int rtt = request->Elapsed();

  if (RTC_LOG_CHECK_LEVEL_V(sev)) {
    std::string pings;
    PrintPingsSinceLastResponse(&pings, 5);
    RTC_LOG_V(sev) << ToString() << ": Received "
                   << StunMethodToString(response->type())
                   << ", id=" << rtc::hex_encode(request->id())
                   << ", code=0"  // Makes logging easier to parse.
                      ", rtt="
                   << rtt << ", pings_since_last_response=" << pings;
  }
  absl::optional<uint32_t> nomination;
  const std::string request_id = request->id();
  auto iter = absl::c_find_if(
      pings_since_last_response_,
      [&request_id](const SentPing& ping) { return ping.id == request_id; });
  if (iter != pings_since_last_response_.end()) {
    nomination.emplace(iter->nomination);
  }
  ReceivedPingResponse(rtt, request_id, nomination);

  stats_.recv_ping_responses++;
  LogCandidatePairEvent(
      webrtc::IceCandidatePairEventType::kCheckResponseReceived,
      response->reduced_transaction_id());

  if (request->msg()->type() == STUN_BINDING_REQUEST) {
    if (!remote_support_goog_ping_.has_value()) {
      auto goog_misc = response->GetUInt16List(STUN_ATTR_GOOG_MISC_INFO);
      if (goog_misc != nullptr &&
          goog_misc->Size() >= kSupportGoogPingVersionResponseIndex) {
        // The remote peer has indicated that it {does/does not} supports
        // GOOG_PING.
        remote_support_goog_ping_ =
            goog_misc->GetType(kSupportGoogPingVersionResponseIndex) >=
            kGoogPingVersion;
      } else {
        remote_support_goog_ping_ = false;
      }
    }

    MaybeUpdateLocalCandidate(request, response);

    if (field_trials_->enable_goog_ping && remote_support_goog_ping_) {
      cached_stun_binding_ = request->msg()->Clone();
    }
  }
}

void Connection::OnConnectionRequestErrorResponse(ConnectionRequest* request,
                                                  StunMessage* response) {
  if (!port_)
    return;

  int error_code = response->GetErrorCodeValue();
  RTC_LOG(LS_WARNING) << ToString() << ": Received "
                      << StunMethodToString(response->type())
                      << " id=" << rtc::hex_encode(request->id())
                      << " code=" << error_code
                      << " rtt=" << request->Elapsed();

  cached_stun_binding_.reset();
  if (error_code == STUN_ERROR_UNKNOWN_ATTRIBUTE ||
      error_code == STUN_ERROR_SERVER_ERROR ||
      error_code == STUN_ERROR_UNAUTHORIZED) {
    // Recoverable error, retry
  } else if (error_code == STUN_ERROR_ROLE_CONFLICT) {
    port_->SignalRoleConflict(port_.get());
  } else if (request->msg()->type() == GOOG_PING_REQUEST) {
    // Race, retry.
  } else {
    // This is not a valid connection.
    RTC_LOG(LS_ERROR) << ToString()
                      << ": Received STUN error response, code=" << error_code
                      << "; killing connection";
    set_state(IceCandidatePairState::FAILED);
    port_->DestroyConnectionAsync(this);
  }
}

void Connection::OnConnectionRequestTimeout(ConnectionRequest* request) {
  // Log at LS_INFO if we miss a ping on a writable connection.
  rtc::LoggingSeverity sev = writable() ? rtc::LS_INFO : rtc::LS_VERBOSE;
  RTC_LOG_V(sev) << ToString() << ": Timing-out STUN ping "
                 << rtc::hex_encode(request->id()) << " after "
                 << request->Elapsed() << " ms";
}

void Connection::OnConnectionRequestSent(ConnectionRequest* request) {
  RTC_DCHECK_RUN_ON(network_thread_);
  // Log at LS_INFO if we send a ping on an unwritable connection.
  rtc::LoggingSeverity sev = !writable() ? rtc::LS_INFO : rtc::LS_VERBOSE;
  RTC_LOG_V(sev) << ToString() << ": Sent "
                 << StunMethodToString(request->msg()->type())
                 << ", id=" << rtc::hex_encode(request->id())
                 << ", use_candidate=" << use_candidate_attr()
                 << ", nomination=" << nomination_;
  stats_.sent_ping_requests_total++;
  LogCandidatePairEvent(webrtc::IceCandidatePairEventType::kCheckSent,
                        request->reduced_transaction_id());
  if (stats_.recv_ping_responses == 0) {
    stats_.sent_ping_requests_before_first_response++;
  }
}

IceCandidatePairState Connection::state() const {
  RTC_DCHECK_RUN_ON(network_thread_);
  return state_;
}

int Connection::num_pings_sent() const {
  RTC_DCHECK_RUN_ON(network_thread_);
  return num_pings_sent_;
}

void Connection::MaybeSetRemoteIceParametersAndGeneration(
    const IceParameters& ice_params,
    int generation) {
  if (remote_candidate_.username() == ice_params.ufrag &&
      remote_candidate_.password().empty()) {
    remote_candidate_.set_password(ice_params.pwd);
  }
  // TODO(deadbeef): A value of '0' for the generation is used for both
  // generation 0 and "generation unknown". It should be changed to an
  // absl::optional to fix this.
  if (remote_candidate_.username() == ice_params.ufrag &&
      remote_candidate_.password() == ice_params.pwd &&
      remote_candidate_.generation() == 0) {
    remote_candidate_.set_generation(generation);
  }
}

void Connection::MaybeUpdatePeerReflexiveCandidate(
    const Candidate& new_candidate) {
  if (remote_candidate_.type() == PRFLX_PORT_TYPE &&
      new_candidate.type() != PRFLX_PORT_TYPE &&
      remote_candidate_.protocol() == new_candidate.protocol() &&
      remote_candidate_.address() == new_candidate.address() &&
      remote_candidate_.username() == new_candidate.username() &&
      remote_candidate_.password() == new_candidate.password() &&
      remote_candidate_.generation() == new_candidate.generation()) {
    remote_candidate_ = new_candidate;
  }
}

int64_t Connection::last_received() const {
  RTC_DCHECK_RUN_ON(network_thread_);
  return std::max(last_data_received_,
                  std::max(last_ping_received_, last_ping_response_received_));
}

int64_t Connection::receiving_unchanged_since() const {
  RTC_DCHECK_RUN_ON(network_thread_);
  return receiving_unchanged_since_;
}

uint32_t Connection::prflx_priority() const {
  RTC_DCHECK_RUN_ON(network_thread_);
  // PRIORITY Attribute.
  // Changing the type preference to Peer Reflexive and local preference
  // and component id information is unchanged from the original priority.
  // priority = (2^24)*(type preference) +
  //           (2^8)*(local preference) +
  //           (2^0)*(256 - component ID)
  IcePriorityValue type_preference =
      (local_candidate_.protocol() == TCP_PROTOCOL_NAME)
          ? ICE_TYPE_PREFERENCE_PRFLX_TCP
          : ICE_TYPE_PREFERENCE_PRFLX;
  return type_preference << 24 | (local_candidate_.priority() & 0x00FFFFFF);
}

ConnectionInfo Connection::stats() {
  RTC_DCHECK_RUN_ON(network_thread_);
  stats_.recv_bytes_second = round(recv_rate_tracker_.ComputeRate());
  stats_.recv_total_bytes = recv_rate_tracker_.TotalSampleCount();
  stats_.sent_bytes_second = round(send_rate_tracker_.ComputeRate());
  stats_.sent_total_bytes = send_rate_tracker_.TotalSampleCount();
  stats_.receiving = receiving_;
  stats_.writable = write_state_ == STATE_WRITABLE;
  stats_.timeout = write_state_ == STATE_WRITE_TIMEOUT;
  stats_.rtt = rtt_;
  stats_.key = this;
  stats_.state = state_;
  if (port_) {
    stats_.priority = priority();
    stats_.local_candidate = local_candidate();
  }
  stats_.nominated = nominated();
  stats_.total_round_trip_time_ms = total_round_trip_time_ms_;
  stats_.current_round_trip_time_ms = current_round_trip_time_ms_;
  stats_.remote_candidate = remote_candidate();
  return stats_;
}

void Connection::MaybeUpdateLocalCandidate(StunRequest* request,
                                           StunMessage* response) {
  if (!port_)
    return;

  // RFC 5245
  // The agent checks the mapped address from the STUN response.  If the
  // transport address does not match any of the local candidates that the
  // agent knows about, the mapped address represents a new candidate -- a
  // peer reflexive candidate.
  const StunAddressAttribute* addr =
      response->GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
  if (!addr) {
    RTC_LOG(LS_WARNING)
        << "Connection::OnConnectionRequestResponse - "
           "No MAPPED-ADDRESS or XOR-MAPPED-ADDRESS found in the "
           "stun response message";
    return;
  }

  for (const Candidate& candidate : port_->Candidates()) {
    if (candidate.address() == addr->GetAddress()) {
      if (local_candidate_ != candidate) {
        RTC_LOG(LS_INFO) << ToString()
                         << ": Updating local candidate type to srflx.";
        local_candidate_ = candidate;
        // SignalStateChange to force a re-sort in P2PTransportChannel as this
        // Connection's local candidate has changed.
        SignalStateChange(this);
      }
      return;
    }
  }

  // RFC 5245
  // Its priority is set equal to the value of the PRIORITY attribute
  // in the Binding request.
  const StunUInt32Attribute* priority_attr =
      request->msg()->GetUInt32(STUN_ATTR_PRIORITY);
  if (!priority_attr) {
    RTC_LOG(LS_WARNING) << "Connection::OnConnectionRequestResponse - "
                           "No STUN_ATTR_PRIORITY found in the "
                           "stun response message";
    return;
  }
  const uint32_t priority = priority_attr->value();
  std::string id = rtc::CreateRandomString(8);

  // Create a peer-reflexive candidate based on the local candidate.
  local_candidate_.set_id(id);
  local_candidate_.set_type(PRFLX_PORT_TYPE);
  // Set the related address and foundation attributes before changing the
  // address.
  local_candidate_.set_related_address(local_candidate_.address());
  local_candidate_.set_foundation(Port::ComputeFoundation(
      PRFLX_PORT_TYPE, local_candidate_.protocol(),
      local_candidate_.relay_protocol(), local_candidate_.address()));
  local_candidate_.set_priority(priority);
  local_candidate_.set_address(addr->GetAddress());

  // Change the local candidate of this Connection to the new prflx candidate.
  RTC_LOG(LS_INFO) << ToString() << ": Updating local candidate type to prflx.";
  port_->AddPrflxCandidate(local_candidate_);

  // SignalStateChange to force a re-sort in P2PTransportChannel as this
  // Connection's local candidate has changed.
  SignalStateChange(this);
}

bool Connection::rtt_converged() const {
  RTC_DCHECK_RUN_ON(network_thread_);
  return rtt_samples_ > (RTT_RATIO + 1);
}

bool Connection::missing_responses(int64_t now) const {
  RTC_DCHECK_RUN_ON(network_thread_);
  if (pings_since_last_response_.empty()) {
    return false;
  }

  int64_t waiting = now - pings_since_last_response_[0].sent_time;
  return waiting > 2 * rtt();
}

bool Connection::TooManyOutstandingPings(
    const absl::optional<int>& max_outstanding_pings) const {
  RTC_DCHECK_RUN_ON(network_thread_);
  if (!max_outstanding_pings.has_value()) {
    return false;
  }
  if (static_cast<int>(pings_since_last_response_.size()) <
      *max_outstanding_pings) {
    return false;
  }
  return true;
}

void Connection::SetLocalCandidateNetworkCost(uint16_t cost) {
  RTC_DCHECK_RUN_ON(network_thread_);

  if (cost == local_candidate_.network_cost())
    return;

  local_candidate_.set_network_cost(cost);

  // Network cost change will affect the connection selection criteria.
  // Signal the connection state change to force a re-sort in
  // P2PTransportChannel.
  SignalStateChange(this);
}

bool Connection::ShouldSendGoogPing(const StunMessage* message) {
  RTC_DCHECK_RUN_ON(network_thread_);
  if (remote_support_goog_ping_ == true && cached_stun_binding_ &&
      cached_stun_binding_->EqualAttributes(message, [](int type) {
        // Ignore these attributes.
        // NOTE: Consider what to do if adding more content to
        // STUN_ATTR_GOOG_MISC_INFO
        return type != STUN_ATTR_FINGERPRINT &&
               type != STUN_ATTR_MESSAGE_INTEGRITY &&
               type != STUN_ATTR_RETRANSMIT_COUNT &&
               type != STUN_ATTR_GOOG_MISC_INFO;
      })) {
    return true;
  }
  return false;
}

void Connection::ForgetLearnedState() {
  RTC_DCHECK_RUN_ON(network_thread_);
  RTC_LOG(LS_INFO) << ToString() << ": Connection forget learned state";
  requests_.Clear();
  receiving_ = false;
  write_state_ = STATE_WRITE_INIT;
  rtt_estimate_.Reset();
  pings_since_last_response_.clear();
}

ProxyConnection::ProxyConnection(rtc::WeakPtr<Port> port,
                                 size_t index,
                                 const Candidate& remote_candidate)
    : Connection(std::move(port), index, remote_candidate) {}

int ProxyConnection::Send(const void* data,
                          size_t size,
                          const rtc::PacketOptions& options) {
  if (!port_)
    return SOCKET_ERROR;

  stats_.sent_total_packets++;
  int sent =
      port_->SendTo(data, size, remote_candidate_.address(), options, true);
  int64_t now = rtc::TimeMillis();
  if (sent <= 0) {
    RTC_DCHECK(sent < 0);
    error_ = port_->GetError();
    stats_.sent_discarded_packets++;
    stats_.sent_discarded_bytes += size;
  } else {
    send_rate_tracker_.AddSamplesAtTime(now, sent);
  }
  last_send_data_ = now;
  return sent;
}

int ProxyConnection::GetError() {
  return error_;
}

}  // namespace cricket
