/*
 *  Copyright 2011 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef P2P_DTLS_DTLS_TRANSPORT_H_
#define P2P_DTLS_DTLS_TRANSPORT_H_

#include <cstddef>
#include <cstdint>
#include <functional>
#include <memory>
#include <optional>
#include <span>
#include <string>
#include <vector>

#include "absl/functional/any_invocable.h"
#include "absl/strings/string_view.h"
#include "api/crypto/crypto_options.h"
#include "api/dtls_transport_interface.h"
#include "api/environment/environment.h"
#include "api/ice_transport_interface.h"
#include "api/rtc_error.h"
#include "api/scoped_refptr.h"
#include "api/sequence_checker.h"
#include "api/task_queue/pending_task_safety_flag.h"
#include "api/units/timestamp.h"
#include "p2p/base/ice_transport_internal.h"
#include "p2p/base/packet_transport_internal.h"
#include "p2p/dtls/dtls_stun_piggyback_controller.h"
#include "p2p/dtls/dtls_transport_internal.h"
#include "p2p/dtls/dtls_utils.h"
#include "rtc_base/async_packet_socket.h"
#include "rtc_base/buffer.h"
#include "rtc_base/buffer_queue.h"
#include "rtc_base/network/received_packet.h"
#include "rtc_base/network/sent_packet.h"
#include "rtc_base/network_route.h"
#include "rtc_base/rtc_certificate.h"
#include "rtc_base/socket.h"
#include "rtc_base/ssl_certificate.h"
#include "rtc_base/ssl_stream_adapter.h"
#include "rtc_base/stream.h"
#include "rtc_base/strings/string_builder.h"
#include "rtc_base/system/no_unique_address.h"
#include "rtc_base/thread_annotations.h"

namespace webrtc {

// Used by histograms. Values of entries should not be changed, except for kMax.
enum class HistogramDtlsVersion {
  kUnknown = 0,
  kDtls10 = 1,
  kDtls12 = 2,
  kDtls13 = 3,
  kMax = 4
};

// A bridge between a packet-oriented/transport-type interface on
// the bottom and a StreamInterface on the top.
class StreamInterfaceChannel : public StreamInterface {
 public:
  explicit StreamInterfaceChannel(IceTransportInternal* ice_transport);

  void SetDtlsStunPiggybackController(
      DtlsStunPiggybackController* dtls_stun_piggyback_controller);

  StreamInterfaceChannel(const StreamInterfaceChannel&) = delete;
  StreamInterfaceChannel& operator=(const StreamInterfaceChannel&) = delete;

  // Push in a packet; this gets pulled out from Read().
  bool OnPacketReceived(std::span<const uint8_t> data);

  // Sets the options for the next packet to be written to ice_transport,
  // corresponding to the next Write() call. Safe since BoringSSL guarantees
  // that "In DTLS ... a single call to |SSL_write| only ever writes a single
  // record in a single packet" - see comment on SSL_write in
  // third_party/boringssl/src/include/openssl/ssl.h.
  void SetNextPacketOptions(const AsyncSocketPacketOptions& options);
  void ClearNextPacketOptions();

  // Implementations of StreamInterface
  StreamState GetState() const override;
  void Close() override;
  StreamResult Read(std::span<uint8_t> buffer,
                    size_t& read,
                    int& error) override;
  StreamResult Write(std::span<const uint8_t> data,
                     size_t& written,
                     int& error) override;
  bool Flush() override;

 private:
  IceTransportInternal* const ice_transport_;  // owned by DtlsTransport
  DtlsStunPiggybackController* dtls_stun_piggyback_controller_ =
      nullptr;  // owned by DtlsTransport
  StreamState state_ RTC_GUARDED_BY(callback_sequence_);
  BufferQueue packets_ RTC_GUARDED_BY(callback_sequence_);
  std::optional<AsyncSocketPacketOptions> next_packet_options_
      RTC_GUARDED_BY(callback_sequence_);
};

// This class provides a DTLS SSLStreamAdapter inside a TransportChannel-style
// packet-based interface, wrapping an existing TransportChannel instance
// (e.g a P2PTransportChannel)
// Here's the way this works:
//
//   DtlsTransport {
//       SSLStreamAdapter* dtls_ {
//           StreamInterfaceChannel downward_ {
//               IceTransportInternal* ice_transport_;
//           }
//       }
//   }
//
//   - Data which comes into DtlsTransport from the underlying
//     ice_transport_ via OnReadPacket() is checked for whether it is DTLS
//     or not, and if it is, is passed to DtlsTransport::HandleDtlsPacket,
//     which pushes it into to downward_. dtls_ is listening for events on
//     downward_, so it immediately calls downward_->Read().
//
//   - Data written to DtlsTransport is passed either to downward_ or directly
//     to ice_transport_, depending on whether DTLS is negotiated and whether
//     the flags include PF_SRTP_BYPASS
//
//   - The SSLStreamAdapter writes to downward_->Write() which translates it
//     into packet writes on ice_transport_.
//
// This class is not thread safe; all methods must be called on the same thread
// as the constructor.
class DtlsTransportInternalImpl : public DtlsTransportInternal {
 public:
  // See https://datatracker.ietf.org/doc/html/rfc9147#section-5.8.2,
  // the RFC specifies 400ms...but in ComputeRetransmissionTimeout
  // the RTT estimate is multiplied by 2, so the first timeout will be 400 ms.
  static constexpr int kDefaultHandshakeEstimateRttMs = 200;

  // For testing purposes only.
  using SslStreamFactory = std::function<std::unique_ptr<SSLStreamAdapter>(
      const Environment&,
      std::unique_ptr<StreamInterface>,
      absl::AnyInvocable<void(SSLHandshakeError)> handshake_error_callback)>;

  // `ice_transport` is the ICE transport this DTLS transport is wrapping.  It
  // must outlive this DTLS transport.
  //
  // `crypto_options` are the options used for the DTLS handshake. This affects
  // whether GCM crypto suites are negotiated.
  DtlsTransportInternalImpl(
      const Environment& env,
      scoped_refptr<IceTransportInterface> ice_transport,
      const CryptoOptions& crypto_options,
      SSLProtocolVersion max_version = SSL_PROTOCOL_DTLS_12,
      SslStreamFactory ssl_stream_factory = nullptr);

  // This is only here while there is code outside of webrtc that calls it.
  [[deprecated("Using internal webrtc code from outside webrtc?")]]
  DtlsTransportInternalImpl(
      const Environment& env,
      IceTransportInternal* ice_transport,
      const CryptoOptions& crypto_options,
      SSLProtocolVersion max_version = SSL_PROTOCOL_DTLS_12,
      SslStreamFactory ssl_stream_factory = nullptr);

  ~DtlsTransportInternalImpl() override;

  DtlsTransportInternalImpl(const DtlsTransportInternalImpl&) = delete;
  DtlsTransportInternalImpl& operator=(const DtlsTransportInternalImpl&) =
      delete;

  DtlsTransportState dtls_state() const override;
  const std::string& transport_name() const override;
  int component() const override;

  // DTLS is active if a local certificate was set. Otherwise this acts in a
  // "passthrough" mode, sending packets directly through the underlying ICE
  // transport.
  // TODO(deadbeef): Remove this weirdness, and handle it in the upper layers.
  bool IsDtlsActive() const override;

  // SetLocalCertificate is what makes DTLS active. It must be called before
  // SetRemoteFinterprint.
  // TODO(deadbeef): Once DtlsTransportInternalImpl no longer has the concept of
  // being "active" or not (acting as a passthrough if not active), just require
  // this certificate on construction or "Start".
  bool SetLocalCertificate(
      const scoped_refptr<RTCCertificate>& certificate) override;
  scoped_refptr<RTCCertificate> GetLocalCertificateForTesting() const;
  // SetRemoteParameters must be called after SetLocalCertificate.
  RTCError SetRemoteParameters(absl::string_view digest_alg,
                               const uint8_t* digest,
                               size_t digest_len,
                               std::optional<SSLRole> role) override;

  // Called to send a packet (via DTLS, if turned on).
  int SendPacket(const char* data,
                 size_t size,
                 const AsyncSocketPacketOptions& options,
                 int flags) override;

  bool GetOption(Socket::Option opt, int* value) override;

  // Find out which TLS version was negotiated
  bool GetSslVersionBytes(int* version) const override;
  // Return the the ID of the group used by the adapters most recently
  // completed handshake, or 0 if not applicable (e.g. before the handshake).
  uint16_t GetSslGroupId() const override;
  // Find out which DTLS-SRTP cipher was negotiated
  bool GetSrtpCryptoSuite(int* cipher) const override;

  // Find out which signature algorithm was used by the peer. Returns values
  // from
  // https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-signaturescheme
  // If not applicable, it returns zero.
  uint16_t GetSslPeerSignatureAlgorithm() const override;

  bool GetDtlsRole(SSLRole* role) const override;
  bool SetDtlsRole(SSLRole role) override;

  // Find out which DTLS cipher was negotiated
  bool GetSslCipherSuite(int* cipher) const override;
  std::optional<absl::string_view> GetTlsCipherSuiteName() const override;

  // Once DTLS has been established, this method retrieves the certificate
  // chain in use by the remote peer, for use in external identity
  // verification.
  std::unique_ptr<SSLCertChain> GetRemoteSSLCertChain() const override;

  // Once DTLS has established (i.e., this ice_transport is writable), this
  // method extracts the keys negotiated during the DTLS handshake, for use in
  // external encryption. DTLS-SRTP uses this to extract the needed SRTP keys.
  [[deprecated]] bool ExportSrtpKeyingMaterial(
      ZeroOnFreeBuffer<uint8_t>& keying_material) override;
  bool AppendSrtpKeyingMaterial(
      ZeroOnFreeBuffer<uint8_t>& keying_material) override;

  IceTransportInternal* ice_transport() override;

  // For informational purposes. Tells if the DTLS handshake has finished.
  // This may be true even if writable() is false, if the remote fingerprint
  // has not yet been verified.
  bool IsDtlsConnected();

  bool receiving() const override;
  bool writable() const override;

  int GetError() override;

  std::optional<NetworkRoute> network_route() const override;

  int SetOption(Socket::Option opt, int value) override;

  std::string ToString() const {
    const absl::string_view RECEIVING_ABBREV[2] = {"_", "R"};
    const absl::string_view WRITABLE_ABBREV[2] = {"_", "W"};
    StringBuilder sb;
    sb << "DtlsTransport[" << transport_name() << "|" << component_ << "|"
       << RECEIVING_ABBREV[receiving()] << WRITABLE_ABBREV[writable()] << "]";
    return sb.Release();
  }

  // Number of times "DTLS retransmission" has been triggered.
  // Currently used for testing but maybe put into stats in the future?
  int GetRetransmissionCount() const;

  // Number of times data has been received from a STUN BINDING.
  int GetStunDataCount() const;

  // Two methods for testing.
  bool IsDtlsPiggybackSupportedByPeer();
  bool WasDtlsCompletedByPiggybacking();
  void SetFakeIceLite() { fake_ice_lite_ = true; }

 private:
  void ConnectToIceTransport();

  void OnWritableState(PacketTransportInternal* transport);
  void OnReadPacket(PacketTransportInternal* transport,
                    const ReceivedIpPacket& packet,
                    bool piggybacked);
  void OnSentPacket(PacketTransportInternal* transport,
                    const SentPacketInfo& sent_packet);
  void OnReadyToSend(PacketTransportInternal* transport);
  void OnReceivingState(PacketTransportInternal* transport);
  void OnDtlsEvent(int sig, int err);
  void OnNetworkRouteChanged(std::optional<NetworkRoute> network_route);
  bool SetupDtls();
  void MaybeStartDtls();
  bool HandleDtlsPacket(std::span<const uint8_t> payload);
  void OnDtlsHandshakeError(SSLHandshakeError error);
  void ConfigureHandshakeTimeout();
  void UpdateHandshakeTimeout();

  void set_receiving(bool receiving);
  void set_writable(bool writable);
  // Sets the DTLS state, signaling if necessary.
  void set_dtls_state(DtlsTransportState state);

  void CompleteDtlsInStun(bool success);
  void SetPiggybackDtlsDataCallback(
      absl::AnyInvocable<void(PacketTransportInternal* transport,
                              const ReceivedIpPacket& packet)> callback);
  void FlushPendingDtlsPacket();

  // SetRemoteFingerprint must be called after SetLocalCertificate, and any
  // other methods like SetDtlsRole. It's what triggers the actual DTLS setup.
  // TODO(deadbeef): Rename to "Start" like in ORTC?
  bool SetRemoteFingerprint(absl::string_view digest_alg,
                            const uint8_t* digest,
                            size_t digest_len);

  SslStreamFactory ssl_stream_factory_;
  const Environment env_;
  RTC_NO_UNIQUE_ADDRESS SequenceChecker thread_checker_;

  const int component_;
  DtlsTransportState dtls_state_ = DtlsTransportState::kNew;
  Timestamp connecting_state_timestamp_ = Timestamp::Micros(0);

  // Underlying ice_transport.
  const scoped_refptr<IceTransportInterface> ice_transport_;
  std::unique_ptr<SSLStreamAdapter> dtls_;  // The DTLS stream
  StreamInterfaceChannel*
      downward_;  // Wrapper for ice_transport_, owned by dtls_.
  const std::vector<int> srtp_ciphers_;  // SRTP ciphers to use with DTLS.
  // Cipher groups used for DTLS handshake to establish ephemeral key.
  const std::vector<uint16_t> ephemeral_key_exchange_cipher_groups_;
  bool dtls_active_ = false;
  scoped_refptr<RTCCertificate> local_certificate_;
  std::optional<SSLRole> dtls_role_;
  const SSLProtocolVersion ssl_max_version_;
  Buffer remote_fingerprint_value_;
  std::string remote_fingerprint_algorithm_;

  // Cached DTLS ClientHello packet that was received before we started the
  // DTLS handshake. This could happen if the hello was received before the
  // ice transport became writable, or before a remote fingerprint was received.
  PacketStash cached_client_hello_;

  bool receiving_ = false;
  bool writable_ = false;

  // Keep track if ICE has ever been writable.
  // This is used to prevent "spurious" Dtls::Writable with DTLS-in-STUN,
  // where DTLS can become writable before ICE. This can confuse other parts
  // of the stack.
  bool ice_has_been_writable_ = false;

  // Initialized in constructor based on WebRTC-IceHandshakeDtls,
  // (so that we return PIGGYBACK_ACK to client if we get STUN_BINDING_REQUEST
  // directly). Maybe disabled in SetupDtls has been called.
  bool dtls_in_stun_ = false;
  // Has DtlsInStun Complete been run?
  // This variable is used to prevent reinitializing after dtls-restart.
  bool dtls_in_stun_complete_ = false;

  // A controller for piggybacking DTLS in STUN.
  DtlsStunPiggybackController dtls_stun_piggyback_controller_;

  absl::AnyInvocable<void(PacketTransportInternal*, const ReceivedIpPacket&)>
      piggybacked_dtls_callback_;

  ScopedTaskSafetyDetached safety_flag_;

  // We reuse this class also in tests that pretend to be ice-lite.
  bool fake_ice_lite_ = false;
};

}  // namespace webrtc


#endif  // P2P_DTLS_DTLS_TRANSPORT_H_
