/*
 *  Copyright 2018 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 "pc/jsep_transport.h"

#include <stddef.h>
#include <stdint.h>

#include <memory>
#include <type_traits>
#include <utility>  // for std::pair

#include "api/array_view.h"
#include "api/candidate.h"
#include "p2p/base/p2p_constants.h"
#include "p2p/base/p2p_transport_channel.h"
#include "pc/sctp_data_channel_transport.h"
#include "rtc_base/checks.h"
#include "rtc_base/copy_on_write_buffer.h"
#include "rtc_base/logging.h"
#include "rtc_base/strings/string_builder.h"

using webrtc::SdpType;

namespace cricket {

JsepTransportDescription::JsepTransportDescription() {}

JsepTransportDescription::JsepTransportDescription(
    bool rtcp_mux_enabled,
    const std::vector<CryptoParams>& cryptos,
    const std::vector<int>& encrypted_header_extension_ids,
    int rtp_abs_sendtime_extn_id,
    const TransportDescription& transport_desc,
    absl::optional<std::string> media_alt_protocol,
    absl::optional<std::string> data_alt_protocol)
    : rtcp_mux_enabled(rtcp_mux_enabled),
      cryptos(cryptos),
      encrypted_header_extension_ids(encrypted_header_extension_ids),
      rtp_abs_sendtime_extn_id(rtp_abs_sendtime_extn_id),
      transport_desc(transport_desc),
      media_alt_protocol(media_alt_protocol),
      data_alt_protocol(data_alt_protocol) {}

JsepTransportDescription::JsepTransportDescription(
    const JsepTransportDescription& from)
    : rtcp_mux_enabled(from.rtcp_mux_enabled),
      cryptos(from.cryptos),
      encrypted_header_extension_ids(from.encrypted_header_extension_ids),
      rtp_abs_sendtime_extn_id(from.rtp_abs_sendtime_extn_id),
      transport_desc(from.transport_desc),
      media_alt_protocol(from.media_alt_protocol),
      data_alt_protocol(from.data_alt_protocol) {}

JsepTransportDescription::~JsepTransportDescription() = default;

JsepTransportDescription& JsepTransportDescription::operator=(
    const JsepTransportDescription& from) {
  if (this == &from) {
    return *this;
  }
  rtcp_mux_enabled = from.rtcp_mux_enabled;
  cryptos = from.cryptos;
  encrypted_header_extension_ids = from.encrypted_header_extension_ids;
  rtp_abs_sendtime_extn_id = from.rtp_abs_sendtime_extn_id;
  transport_desc = from.transport_desc;
  media_alt_protocol = from.media_alt_protocol;
  data_alt_protocol = from.data_alt_protocol;

  return *this;
}

JsepTransport::JsepTransport(
    const std::string& mid,
    const rtc::scoped_refptr<rtc::RTCCertificate>& local_certificate,
    rtc::scoped_refptr<webrtc::IceTransportInterface> ice_transport,
    rtc::scoped_refptr<webrtc::IceTransportInterface> rtcp_ice_transport,
    std::unique_ptr<webrtc::RtpTransport> unencrypted_rtp_transport,
    std::unique_ptr<webrtc::SrtpTransport> sdes_transport,
    std::unique_ptr<webrtc::DtlsSrtpTransport> dtls_srtp_transport,
    std::unique_ptr<webrtc::RtpTransportInternal> datagram_rtp_transport,
    std::unique_ptr<DtlsTransportInternal> rtp_dtls_transport,
    std::unique_ptr<DtlsTransportInternal> rtcp_dtls_transport,
    std::unique_ptr<SctpTransportInternal> sctp_transport,
    std::unique_ptr<webrtc::DatagramTransportInterface> datagram_transport,
    webrtc::DataChannelTransportInterface* data_channel_transport)
    : network_thread_(rtc::Thread::Current()),
      mid_(mid),
      local_certificate_(local_certificate),
      ice_transport_(std::move(ice_transport)),
      rtcp_ice_transport_(std::move(rtcp_ice_transport)),
      unencrypted_rtp_transport_(std::move(unencrypted_rtp_transport)),
      sdes_transport_(std::move(sdes_transport)),
      dtls_srtp_transport_(std::move(dtls_srtp_transport)),
      rtp_dtls_transport_(
          rtp_dtls_transport ? new rtc::RefCountedObject<webrtc::DtlsTransport>(
                                   std::move(rtp_dtls_transport))
                             : nullptr),
      rtcp_dtls_transport_(
          rtcp_dtls_transport
              ? new rtc::RefCountedObject<webrtc::DtlsTransport>(
                    std::move(rtcp_dtls_transport))
              : nullptr),
      sctp_data_channel_transport_(
          sctp_transport ? std::make_unique<webrtc::SctpDataChannelTransport>(
                               sctp_transport.get())
                         : nullptr),
      sctp_transport_(sctp_transport
                          ? new rtc::RefCountedObject<webrtc::SctpTransport>(
                                std::move(sctp_transport))
                          : nullptr),
      datagram_transport_(std::move(datagram_transport)),
      datagram_rtp_transport_(std::move(datagram_rtp_transport)),
      data_channel_transport_(data_channel_transport) {
  RTC_DCHECK(ice_transport_);
  RTC_DCHECK(rtp_dtls_transport_);
  // |rtcp_ice_transport_| must be present iff |rtcp_dtls_transport_| is
  // present.
  RTC_DCHECK_EQ((rtcp_ice_transport_ != nullptr),
                (rtcp_dtls_transport_ != nullptr));
  // Verify the "only one out of these three can be set" invariant.
  if (unencrypted_rtp_transport_) {
    RTC_DCHECK(!sdes_transport);
    RTC_DCHECK(!dtls_srtp_transport);
  } else if (sdes_transport_) {
    RTC_DCHECK(!unencrypted_rtp_transport);
    RTC_DCHECK(!dtls_srtp_transport);
  } else {
    RTC_DCHECK(dtls_srtp_transport_);
    RTC_DCHECK(!unencrypted_rtp_transport);
    RTC_DCHECK(!sdes_transport);
  }

  if (sctp_transport_) {
    sctp_transport_->SetDtlsTransport(rtp_dtls_transport_);
  }

  if (datagram_rtp_transport_ && default_rtp_transport()) {
    composite_rtp_transport_ = std::make_unique<webrtc::CompositeRtpTransport>(
        std::vector<webrtc::RtpTransportInternal*>{
            datagram_rtp_transport_.get(), default_rtp_transport()});
  }

  if (data_channel_transport_ && sctp_data_channel_transport_) {
    composite_data_channel_transport_ =
        std::make_unique<webrtc::CompositeDataChannelTransport>(
            std::vector<webrtc::DataChannelTransportInterface*>{
                data_channel_transport_, sctp_data_channel_transport_.get()});
  }
}

JsepTransport::~JsepTransport() {
  if (sctp_transport_) {
    sctp_transport_->Clear();
  }

  // Clear all DtlsTransports. There may be pointers to these from
  // other places, so we can't assume they'll be deleted by the destructor.
  rtp_dtls_transport_->Clear();
  if (rtcp_dtls_transport_) {
    rtcp_dtls_transport_->Clear();
  }

  // ICE will be the last transport to be deleted.
}

webrtc::RTCError JsepTransport::SetLocalJsepTransportDescription(
    const JsepTransportDescription& jsep_description,
    SdpType type) {
  webrtc::RTCError error;

  RTC_DCHECK_RUN_ON(network_thread_);

  IceParameters ice_parameters =
      jsep_description.transport_desc.GetIceParameters();
  webrtc::RTCError ice_parameters_result = ice_parameters.Validate();
  if (!ice_parameters_result.ok()) {
    rtc::StringBuilder sb;
    sb << "Invalid ICE parameters: " << ice_parameters_result.message();
    return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
                            sb.Release());
  }

  if (!SetRtcpMux(jsep_description.rtcp_mux_enabled, type,
                  ContentSource::CS_LOCAL)) {
    return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
                            "Failed to setup RTCP mux.");
  }

  // If doing SDES, setup the SDES crypto parameters.
  {
    rtc::CritScope scope(&accessor_lock_);
    if (sdes_transport_) {
      RTC_DCHECK(!unencrypted_rtp_transport_);
      RTC_DCHECK(!dtls_srtp_transport_);
      if (!SetSdes(jsep_description.cryptos,
                   jsep_description.encrypted_header_extension_ids, type,
                   ContentSource::CS_LOCAL)) {
        return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
                                "Failed to setup SDES crypto parameters.");
      }
    } else if (dtls_srtp_transport_) {
      RTC_DCHECK(!unencrypted_rtp_transport_);
      RTC_DCHECK(!sdes_transport_);
      dtls_srtp_transport_->UpdateRecvEncryptedHeaderExtensionIds(
          jsep_description.encrypted_header_extension_ids);
    }
  }
  bool ice_restarting =
      local_description_ != nullptr &&
      IceCredentialsChanged(local_description_->transport_desc.ice_ufrag,
                            local_description_->transport_desc.ice_pwd,
                            ice_parameters.ufrag, ice_parameters.pwd);
  local_description_.reset(new JsepTransportDescription(jsep_description));

  rtc::SSLFingerprint* local_fp =
      local_description_->transport_desc.identity_fingerprint.get();

  if (!local_fp) {
    local_certificate_ = nullptr;
  } else {
    error = VerifyCertificateFingerprint(local_certificate_, local_fp);
    if (!error.ok()) {
      local_description_.reset();
      return error;
    }
  }
  {
    rtc::CritScope scope(&accessor_lock_);
    RTC_DCHECK(rtp_dtls_transport_->internal());
    rtp_dtls_transport_->internal()->ice_transport()->SetIceParameters(
        ice_parameters);

    if (rtcp_dtls_transport_) {
      RTC_DCHECK(rtcp_dtls_transport_->internal());
      rtcp_dtls_transport_->internal()->ice_transport()->SetIceParameters(
          ice_parameters);
    }
  }
  // If PRANSWER/ANSWER is set, we should decide transport protocol type.
  if (type == SdpType::kPrAnswer || type == SdpType::kAnswer) {
    error = NegotiateAndSetDtlsParameters(type);
    NegotiateDatagramTransport(type);
  }
  if (!error.ok()) {
    local_description_.reset();
    return error;
  }
  {
    rtc::CritScope scope(&accessor_lock_);
    if (needs_ice_restart_ && ice_restarting) {
      needs_ice_restart_ = false;
      RTC_LOG(LS_VERBOSE) << "needs-ice-restart flag cleared for transport "
                          << mid();
    }
  }

  return webrtc::RTCError::OK();
}

webrtc::RTCError JsepTransport::SetRemoteJsepTransportDescription(
    const JsepTransportDescription& jsep_description,
    webrtc::SdpType type) {
  webrtc::RTCError error;

  RTC_DCHECK_RUN_ON(network_thread_);

  IceParameters ice_parameters =
      jsep_description.transport_desc.GetIceParameters();
  webrtc::RTCError ice_parameters_result = ice_parameters.Validate();
  if (!ice_parameters_result.ok()) {
    remote_description_.reset();
    rtc::StringBuilder sb;
    sb << "Invalid ICE parameters: " << ice_parameters_result.message();
    return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
                            sb.Release());
  }

  if (!SetRtcpMux(jsep_description.rtcp_mux_enabled, type,
                  ContentSource::CS_REMOTE)) {
    return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
                            "Failed to setup RTCP mux.");
  }

  // If doing SDES, setup the SDES crypto parameters.
  {
    rtc::CritScope lock(&accessor_lock_);
    if (sdes_transport_) {
      RTC_DCHECK(!unencrypted_rtp_transport_);
      RTC_DCHECK(!dtls_srtp_transport_);
      if (!SetSdes(jsep_description.cryptos,
                   jsep_description.encrypted_header_extension_ids, type,
                   ContentSource::CS_REMOTE)) {
        return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
                                "Failed to setup SDES crypto parameters.");
      }
      sdes_transport_->CacheRtpAbsSendTimeHeaderExtension(
          jsep_description.rtp_abs_sendtime_extn_id);
    } else if (dtls_srtp_transport_) {
      RTC_DCHECK(!unencrypted_rtp_transport_);
      RTC_DCHECK(!sdes_transport_);
      dtls_srtp_transport_->UpdateSendEncryptedHeaderExtensionIds(
          jsep_description.encrypted_header_extension_ids);
      dtls_srtp_transport_->CacheRtpAbsSendTimeHeaderExtension(
          jsep_description.rtp_abs_sendtime_extn_id);
    }
  }

  remote_description_.reset(new JsepTransportDescription(jsep_description));
  RTC_DCHECK(rtp_dtls_transport());
  SetRemoteIceParameters(ice_parameters, rtp_dtls_transport()->ice_transport());

  if (rtcp_dtls_transport()) {
    SetRemoteIceParameters(ice_parameters,
                           rtcp_dtls_transport()->ice_transport());
  }

  // If PRANSWER/ANSWER is set, we should decide transport protocol type.
  if (type == SdpType::kPrAnswer || type == SdpType::kAnswer) {
    error = NegotiateAndSetDtlsParameters(SdpType::kOffer);
    NegotiateDatagramTransport(type);
  }
  if (!error.ok()) {
    remote_description_.reset();
    return error;
  }
  return webrtc::RTCError::OK();
}

webrtc::RTCError JsepTransport::AddRemoteCandidates(
    const Candidates& candidates) {
  RTC_DCHECK_RUN_ON(network_thread_);
  if (!local_description_ || !remote_description_) {
    return webrtc::RTCError(webrtc::RTCErrorType::INVALID_STATE,
                            mid() +
                                " is not ready to use the remote candidate "
                                "because the local or remote description is "
                                "not set.");
  }

  for (const cricket::Candidate& candidate : candidates) {
    auto transport =
        candidate.component() == cricket::ICE_CANDIDATE_COMPONENT_RTP
            ? rtp_dtls_transport_
            : rtcp_dtls_transport_;
    if (!transport) {
      return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
                              "Candidate has an unknown component: " +
                                  candidate.ToSensitiveString() + " for mid " +
                                  mid());
    }
    RTC_DCHECK(transport->internal() && transport->internal()->ice_transport());
    transport->internal()->ice_transport()->AddRemoteCandidate(candidate);
  }
  return webrtc::RTCError::OK();
}

void JsepTransport::SetNeedsIceRestartFlag() {
  rtc::CritScope scope(&accessor_lock_);
  if (!needs_ice_restart_) {
    needs_ice_restart_ = true;
    RTC_LOG(LS_VERBOSE) << "needs-ice-restart flag set for transport " << mid();
  }
}

absl::optional<rtc::SSLRole> JsepTransport::GetDtlsRole() const {
  RTC_DCHECK_RUN_ON(network_thread_);
  rtc::CritScope scope(&accessor_lock_);
  RTC_DCHECK(rtp_dtls_transport_);
  RTC_DCHECK(rtp_dtls_transport_->internal());
  rtc::SSLRole dtls_role;
  if (!rtp_dtls_transport_->internal()->GetDtlsRole(&dtls_role)) {
    return absl::optional<rtc::SSLRole>();
  }

  return absl::optional<rtc::SSLRole>(dtls_role);
}

absl::optional<OpaqueTransportParameters>
JsepTransport::GetTransportParameters() const {
  rtc::CritScope scope(&accessor_lock_);
  if (!datagram_transport_) {
    return absl::nullopt;
  }

  OpaqueTransportParameters params;
  params.parameters = datagram_transport_->GetTransportParameters();
  return params;
}

bool JsepTransport::GetStats(TransportStats* stats) {
  RTC_DCHECK_RUN_ON(network_thread_);
  rtc::CritScope scope(&accessor_lock_);
  stats->transport_name = mid();
  stats->channel_stats.clear();
  RTC_DCHECK(rtp_dtls_transport_->internal());
  bool ret = GetTransportStats(rtp_dtls_transport_->internal(), stats);
  if (rtcp_dtls_transport_) {
    RTC_DCHECK(rtcp_dtls_transport_->internal());
    ret &= GetTransportStats(rtcp_dtls_transport_->internal(), stats);
  }
  return ret;
}

webrtc::RTCError JsepTransport::VerifyCertificateFingerprint(
    const rtc::RTCCertificate* certificate,
    const rtc::SSLFingerprint* fingerprint) const {
  RTC_DCHECK_RUN_ON(network_thread_);
  if (!fingerprint) {
    return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
                            "No fingerprint");
  }
  if (!certificate) {
    return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
                            "Fingerprint provided but no identity available.");
  }
  std::unique_ptr<rtc::SSLFingerprint> fp_tmp =
      rtc::SSLFingerprint::CreateUnique(fingerprint->algorithm,
                                        *certificate->identity());
  RTC_DCHECK(fp_tmp.get() != NULL);
  if (*fp_tmp == *fingerprint) {
    return webrtc::RTCError::OK();
  }
  char ss_buf[1024];
  rtc::SimpleStringBuilder desc(ss_buf);
  desc << "Local fingerprint does not match identity. Expected: ";
  desc << fp_tmp->ToString();
  desc << " Got: " << fingerprint->ToString();
  return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
                          std::string(desc.str()));
}

void JsepTransport::SetActiveResetSrtpParams(bool active_reset_srtp_params) {
  RTC_DCHECK_RUN_ON(network_thread_);
  rtc::CritScope scope(&accessor_lock_);
  if (dtls_srtp_transport_) {
    RTC_LOG(INFO)
        << "Setting active_reset_srtp_params of DtlsSrtpTransport to: "
        << active_reset_srtp_params;
    dtls_srtp_transport_->SetActiveResetSrtpParams(active_reset_srtp_params);
  }
}

void JsepTransport::SetRemoteIceParameters(
    const IceParameters& ice_parameters,
    IceTransportInternal* ice_transport) {
  RTC_DCHECK_RUN_ON(network_thread_);
  RTC_DCHECK(ice_transport);
  RTC_DCHECK(remote_description_);
  ice_transport->SetRemoteIceParameters(ice_parameters);
  ice_transport->SetRemoteIceMode(remote_description_->transport_desc.ice_mode);
}

webrtc::RTCError JsepTransport::SetNegotiatedDtlsParameters(
    DtlsTransportInternal* dtls_transport,
    absl::optional<rtc::SSLRole> dtls_role,
    rtc::SSLFingerprint* remote_fingerprint) {
  RTC_DCHECK(dtls_transport);
  // Set SSL role. Role must be set before fingerprint is applied, which
  // initiates DTLS setup.
  if (dtls_role && !dtls_transport->SetDtlsRole(*dtls_role)) {
    return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
                            "Failed to set SSL role for the transport.");
  }
  // Apply remote fingerprint.
  if (!remote_fingerprint ||
      !dtls_transport->SetRemoteFingerprint(
          remote_fingerprint->algorithm, remote_fingerprint->digest.cdata(),
          remote_fingerprint->digest.size())) {
    return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
                            "Failed to apply remote fingerprint.");
  }
  return webrtc::RTCError::OK();
}

bool JsepTransport::SetRtcpMux(bool enable,
                               webrtc::SdpType type,
                               ContentSource source) {
  RTC_DCHECK_RUN_ON(network_thread_);
  bool ret = false;
  switch (type) {
    case SdpType::kOffer:
      ret = rtcp_mux_negotiator_.SetOffer(enable, source);
      break;
    case SdpType::kPrAnswer:
      // This may activate RTCP muxing, but we don't yet destroy the transport
      // because the final answer may deactivate it.
      ret = rtcp_mux_negotiator_.SetProvisionalAnswer(enable, source);
      break;
    case SdpType::kAnswer:
      ret = rtcp_mux_negotiator_.SetAnswer(enable, source);
      if (ret && rtcp_mux_negotiator_.IsActive()) {
        ActivateRtcpMux();
      }
      break;
    default:
      RTC_NOTREACHED();
  }

  if (!ret) {
    return false;
  }

  auto transport = rtp_transport();
  transport->SetRtcpMuxEnabled(rtcp_mux_negotiator_.IsActive());
  return ret;
}

void JsepTransport::ActivateRtcpMux() {
  {
    // Don't hold the network_thread_ lock while calling other functions,
    // since they might call other functions that call RTC_DCHECK_RUN_ON.
    // TODO(https://crbug.com/webrtc/10318): Simplify when possible.
    RTC_DCHECK_RUN_ON(network_thread_);
  }
  {
    rtc::CritScope scope(&accessor_lock_);
    if (unencrypted_rtp_transport_) {
      RTC_DCHECK(!sdes_transport_);
      RTC_DCHECK(!dtls_srtp_transport_);
      unencrypted_rtp_transport_->SetRtcpPacketTransport(nullptr);
    } else if (sdes_transport_) {
      RTC_DCHECK(!unencrypted_rtp_transport_);
      RTC_DCHECK(!dtls_srtp_transport_);
      sdes_transport_->SetRtcpPacketTransport(nullptr);
    } else if (dtls_srtp_transport_) {
      RTC_DCHECK(dtls_srtp_transport_);
      RTC_DCHECK(!unencrypted_rtp_transport_);
      RTC_DCHECK(!sdes_transport_);
      dtls_srtp_transport_->SetDtlsTransports(rtp_dtls_transport_locked(),
                                              /*rtcp_dtls_transport=*/nullptr);
    }
    rtcp_dtls_transport_ = nullptr;  // Destroy this reference.
  }
  // Notify the JsepTransportController to update the aggregate states.
  SignalRtcpMuxActive();
}

bool JsepTransport::SetSdes(const std::vector<CryptoParams>& cryptos,
                            const std::vector<int>& encrypted_extension_ids,
                            webrtc::SdpType type,
                            ContentSource source) {
  RTC_DCHECK_RUN_ON(network_thread_);
  bool ret = false;
  ret = sdes_negotiator_.Process(cryptos, type, source);
  if (!ret) {
    return ret;
  }

  if (source == ContentSource::CS_LOCAL) {
    recv_extension_ids_ = encrypted_extension_ids;
  } else {
    send_extension_ids_ = encrypted_extension_ids;
  }

  // If setting an SDES answer succeeded, apply the negotiated parameters
  // to the SRTP transport.
  if ((type == SdpType::kPrAnswer || type == SdpType::kAnswer) && ret) {
    if (sdes_negotiator_.send_cipher_suite() &&
        sdes_negotiator_.recv_cipher_suite()) {
      RTC_DCHECK(send_extension_ids_);
      RTC_DCHECK(recv_extension_ids_);
      ret = sdes_transport_->SetRtpParams(
          *(sdes_negotiator_.send_cipher_suite()),
          sdes_negotiator_.send_key().data(),
          static_cast<int>(sdes_negotiator_.send_key().size()),
          *(send_extension_ids_), *(sdes_negotiator_.recv_cipher_suite()),
          sdes_negotiator_.recv_key().data(),
          static_cast<int>(sdes_negotiator_.recv_key().size()),
          *(recv_extension_ids_));
    } else {
      RTC_LOG(LS_INFO) << "No crypto keys are provided for SDES.";
      if (type == SdpType::kAnswer) {
        // Explicitly reset the |sdes_transport_| if no crypto param is
        // provided in the answer. No need to call |ResetParams()| for
        // |sdes_negotiator_| because it resets the params inside |SetAnswer|.
        sdes_transport_->ResetParams();
      }
    }
  }
  return ret;
}

webrtc::RTCError JsepTransport::NegotiateAndSetDtlsParameters(
    SdpType local_description_type) {
  RTC_DCHECK_RUN_ON(network_thread_);
  if (!local_description_ || !remote_description_) {
    return webrtc::RTCError(webrtc::RTCErrorType::INVALID_STATE,
                            "Applying an answer transport description "
                            "without applying any offer.");
  }
  std::unique_ptr<rtc::SSLFingerprint> remote_fingerprint;
  absl::optional<rtc::SSLRole> negotiated_dtls_role;

  rtc::SSLFingerprint* local_fp =
      local_description_->transport_desc.identity_fingerprint.get();
  rtc::SSLFingerprint* remote_fp =
      remote_description_->transport_desc.identity_fingerprint.get();
  if (remote_fp && local_fp) {
    remote_fingerprint = std::make_unique<rtc::SSLFingerprint>(*remote_fp);
    webrtc::RTCError error =
        NegotiateDtlsRole(local_description_type,
                          local_description_->transport_desc.connection_role,
                          remote_description_->transport_desc.connection_role,
                          &negotiated_dtls_role);
    if (!error.ok()) {
      return error;
    }
  } else if (local_fp && (local_description_type == SdpType::kAnswer)) {
    return webrtc::RTCError(
        webrtc::RTCErrorType::INVALID_PARAMETER,
        "Local fingerprint supplied when caller didn't offer DTLS.");
  } else {
    // We are not doing DTLS
    remote_fingerprint = std::make_unique<rtc::SSLFingerprint>(
        "", rtc::ArrayView<const uint8_t>());
  }
  // Now that we have negotiated everything, push it downward.
  // Note that we cache the result so that if we have race conditions
  // between future SetRemote/SetLocal invocations and new transport
  // creation, we have the negotiation state saved until a new
  // negotiation happens.
  RTC_DCHECK(rtp_dtls_transport());
  webrtc::RTCError error = SetNegotiatedDtlsParameters(
      rtp_dtls_transport(), negotiated_dtls_role, remote_fingerprint.get());
  if (!error.ok()) {
    return error;
  }

  if (rtcp_dtls_transport()) {
    error = SetNegotiatedDtlsParameters(
        rtcp_dtls_transport(), negotiated_dtls_role, remote_fingerprint.get());
  }
  return error;
}

webrtc::RTCError JsepTransport::NegotiateDtlsRole(
    SdpType local_description_type,
    ConnectionRole local_connection_role,
    ConnectionRole remote_connection_role,
    absl::optional<rtc::SSLRole>* negotiated_dtls_role) {
  // From RFC 4145, section-4.1, The following are the values that the
  // 'setup' attribute can take in an offer/answer exchange:
  //       Offer      Answer
  //      ________________
  //      active     passive / holdconn
  //      passive    active / holdconn
  //      actpass    active / passive / holdconn
  //      holdconn   holdconn
  //
  // Set the role that is most conformant with RFC 5763, Section 5, bullet 1
  // The endpoint MUST use the setup attribute defined in [RFC4145].
  // The endpoint that is the offerer MUST use the setup attribute
  // value of setup:actpass and be prepared to receive a client_hello
  // before it receives the answer.  The answerer MUST use either a
  // setup attribute value of setup:active or setup:passive.  Note that
  // if the answerer uses setup:passive, then the DTLS handshake will
  // not begin until the answerer is received, which adds additional
  // latency. setup:active allows the answer and the DTLS handshake to
  // occur in parallel.  Thus, setup:active is RECOMMENDED.  Whichever
  // party is active MUST initiate a DTLS handshake by sending a
  // ClientHello over each flow (host/port quartet).
  // IOW - actpass and passive modes should be treated as server and
  // active as client.
  bool is_remote_server = false;
  if (local_description_type == SdpType::kOffer) {
    if (local_connection_role != CONNECTIONROLE_ACTPASS) {
      return webrtc::RTCError(
          webrtc::RTCErrorType::INVALID_PARAMETER,
          "Offerer must use actpass value for setup attribute.");
    }

    if (remote_connection_role == CONNECTIONROLE_ACTIVE ||
        remote_connection_role == CONNECTIONROLE_PASSIVE ||
        remote_connection_role == CONNECTIONROLE_NONE) {
      is_remote_server = (remote_connection_role == CONNECTIONROLE_PASSIVE);
    } else {
      return webrtc::RTCError(
          webrtc::RTCErrorType::INVALID_PARAMETER,
          "Answerer must use either active or passive value "
          "for setup attribute.");
    }
    // If remote is NONE or ACTIVE it will act as client.
  } else {
    if (remote_connection_role != CONNECTIONROLE_ACTPASS &&
        remote_connection_role != CONNECTIONROLE_NONE) {
      // Accept a remote role attribute that's not "actpass", but matches the
      // current negotiated role. This is allowed by dtls-sdp, though our
      // implementation will never generate such an offer as it's not
      // recommended.
      //
      // See https://datatracker.ietf.org/doc/html/draft-ietf-mmusic-dtls-sdp,
      // section 5.5.
      auto current_dtls_role = GetDtlsRole();
      if (!current_dtls_role ||
          (*current_dtls_role == rtc::SSL_CLIENT &&
           remote_connection_role == CONNECTIONROLE_ACTIVE) ||
          (*current_dtls_role == rtc::SSL_SERVER &&
           remote_connection_role == CONNECTIONROLE_PASSIVE)) {
        return webrtc::RTCError(
            webrtc::RTCErrorType::INVALID_PARAMETER,
            "Offerer must use actpass value or current negotiated role for "
            "setup attribute.");
      }
    }

    if (local_connection_role == CONNECTIONROLE_ACTIVE ||
        local_connection_role == CONNECTIONROLE_PASSIVE) {
      is_remote_server = (local_connection_role == CONNECTIONROLE_ACTIVE);
    } else {
      return webrtc::RTCError(
          webrtc::RTCErrorType::INVALID_PARAMETER,
          "Answerer must use either active or passive value "
          "for setup attribute.");
    }

    // If local is passive, local will act as server.
  }

  *negotiated_dtls_role =
      (is_remote_server ? rtc::SSL_CLIENT : rtc::SSL_SERVER);
  return webrtc::RTCError::OK();
}

bool JsepTransport::GetTransportStats(DtlsTransportInternal* dtls_transport,
                                      TransportStats* stats) {
  RTC_DCHECK_RUN_ON(network_thread_);
  RTC_DCHECK(dtls_transport);
  TransportChannelStats substats;
  if (rtcp_dtls_transport_) {
    substats.component = dtls_transport == rtcp_dtls_transport_->internal()
                             ? ICE_CANDIDATE_COMPONENT_RTCP
                             : ICE_CANDIDATE_COMPONENT_RTP;
  } else {
    substats.component = ICE_CANDIDATE_COMPONENT_RTP;
  }
  dtls_transport->GetSslVersionBytes(&substats.ssl_version_bytes);
  dtls_transport->GetSrtpCryptoSuite(&substats.srtp_crypto_suite);
  dtls_transport->GetSslCipherSuite(&substats.ssl_cipher_suite);
  substats.dtls_state = dtls_transport->dtls_state();
  if (!dtls_transport->ice_transport()->GetStats(
          &substats.ice_transport_stats)) {
    return false;
  }
  stats->channel_stats.push_back(substats);
  return true;
}

void JsepTransport::NegotiateDatagramTransport(SdpType type) {
  RTC_DCHECK(type == SdpType::kAnswer || type == SdpType::kPrAnswer);
  rtc::CritScope lock(&accessor_lock_);
  if (!datagram_transport_) {
    return;  // No need to negotiate the use of datagram transport.
  }

  bool compatible_datagram_transport = false;
  if (datagram_transport_ &&
      local_description_->transport_desc.opaque_parameters &&
      remote_description_->transport_desc.opaque_parameters) {
    // If both descriptions have datagram transport parameters, and the remote
    // parameters are accepted by the datagram transport, then use the datagram
    // transport.  Otherwise, fall back to RTP.
    compatible_datagram_transport =
        datagram_transport_
            ->SetRemoteTransportParameters(remote_description_->transport_desc
                                               .opaque_parameters->parameters)
            .ok();
  }

  bool use_datagram_transport_for_media =
      compatible_datagram_transport &&
      remote_description_->media_alt_protocol ==
          remote_description_->transport_desc.opaque_parameters->protocol &&
      remote_description_->media_alt_protocol ==
          local_description_->media_alt_protocol;

  bool use_datagram_transport_for_data =
      compatible_datagram_transport &&
      remote_description_->data_alt_protocol ==
          remote_description_->transport_desc.opaque_parameters->protocol &&
      remote_description_->data_alt_protocol ==
          local_description_->data_alt_protocol;

  RTC_LOG(LS_INFO)
      << "Negotiating datagram transport, use_datagram_transport_for_media="
      << use_datagram_transport_for_media
      << ", use_datagram_transport_for_data=" << use_datagram_transport_for_data
      << " answer type=" << (type == SdpType::kAnswer ? "answer" : "pr_answer");

  // A provisional or full or answer lets the peer start sending on one of the
  // transports.
  if (composite_rtp_transport_) {
    composite_rtp_transport_->SetSendTransport(
        use_datagram_transport_for_media ? datagram_rtp_transport_.get()
                                         : default_rtp_transport());
  }
  if (composite_data_channel_transport_) {
    composite_data_channel_transport_->SetSendTransport(
        use_datagram_transport_for_data ? data_channel_transport_
                                        : sctp_data_channel_transport_.get());
  }

  if (type != SdpType::kAnswer) {
    return;
  }

  if (composite_rtp_transport_) {
    if (use_datagram_transport_for_media) {
      // Negotiated use of datagram transport for RTP, so remove the
      // non-datagram RTP transport.
      composite_rtp_transport_->RemoveTransport(default_rtp_transport());
      if (unencrypted_rtp_transport_) {
        unencrypted_rtp_transport_ = nullptr;
      } else if (sdes_transport_) {
        sdes_transport_ = nullptr;
      } else {
        dtls_srtp_transport_ = nullptr;
      }
    } else {
      composite_rtp_transport_->RemoveTransport(datagram_rtp_transport_.get());
      datagram_rtp_transport_ = nullptr;
    }
  }

  if (composite_data_channel_transport_) {
    if (use_datagram_transport_for_data) {
      // Negotiated use of datagram transport for data channels, so remove the
      // non-datagram data channel transport.
      composite_data_channel_transport_->RemoveTransport(
          sctp_data_channel_transport_.get());
      sctp_data_channel_transport_ = nullptr;
      sctp_transport_ = nullptr;
    } else {
      composite_data_channel_transport_->RemoveTransport(
          data_channel_transport_);
      data_channel_transport_ = nullptr;
    }
  } else if (data_channel_transport_ && !use_datagram_transport_for_data) {
    // The datagram transport has been rejected without a fallback.  We still
    // need to inform the application and delete it.
    SignalDataChannelTransportNegotiated(this, nullptr);
    data_channel_transport_ = nullptr;
  }

  if (!use_datagram_transport_for_media && !use_datagram_transport_for_data) {
    // Datagram transport is not being used for anything, so clean it up.
    datagram_transport_ = nullptr;
  }
}

}  // namespace cricket
