/*
 *  Copyright (c) 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.
 */

#include "media/base/rtp_utils.h"

#include <string.h>

#include <cstdint>
#include <vector>

// PacketTimeUpdateParams is defined in asyncpacketsocket.h.
// TODO(sergeyu): Find more appropriate place for PacketTimeUpdateParams.
#include "media/base/turn_utils.h"
#include "modules/rtp_rtcp/source/rtp_util.h"
#include "rtc_base/async_packet_socket.h"
#include "rtc_base/byte_order.h"
#include "rtc_base/checks.h"
#include "rtc_base/message_digest.h"

namespace cricket {

static const size_t kRtcpPayloadTypeOffset = 1;
static const size_t kRtpExtensionHeaderLen = 4;
static const size_t kAbsSendTimeExtensionLen = 3;
static const size_t kOneByteExtensionHeaderLen = 1;
static const size_t kTwoByteExtensionHeaderLen = 2;

namespace {

// Fake auth tag written by the sender when external authentication is enabled.
// HMAC in packet will be compared against this value before updating packet
// with actual HMAC value.
static const uint8_t kFakeAuthTag[10] = {0xba, 0xdd, 0xba, 0xdd, 0xba,
                                         0xdd, 0xba, 0xdd, 0xba, 0xdd};

void UpdateAbsSendTimeExtensionValue(uint8_t* extension_data,
                                     size_t length,
                                     uint64_t time_us) {
  // Absolute send time in RTP streams.
  //
  // The absolute send time is signaled to the receiver in-band using the
  // general mechanism for RTP header extensions [RFC5285]. The payload
  // of this extension (the transmitted value) is a 24-bit unsigned integer
  // containing the sender's current time in seconds as a fixed point number
  // with 18 bits fractional part.
  //
  // The form of the absolute send time extension block:
  //
  //    0                   1                   2                   3
  //    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //   |  ID   | len=2 |              absolute send time               |
  //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  if (length != kAbsSendTimeExtensionLen) {
    RTC_DCHECK_NOTREACHED();
    return;
  }

  // Convert microseconds to a 6.18 fixed point value in seconds.
  uint32_t send_time = ((time_us << 18) / 1000000) & 0x00FFFFFF;
  extension_data[0] = static_cast<uint8_t>(send_time >> 16);
  extension_data[1] = static_cast<uint8_t>(send_time >> 8);
  extension_data[2] = static_cast<uint8_t>(send_time);
}

// Assumes `length` is actual packet length + tag length. Updates HMAC at end of
// the RTP packet.
void UpdateRtpAuthTag(uint8_t* rtp,
                      size_t length,
                      const rtc::PacketTimeUpdateParams& packet_time_params) {
  // If there is no key, return.
  if (packet_time_params.srtp_auth_key.empty()) {
    return;
  }

  size_t tag_length = packet_time_params.srtp_auth_tag_len;

  // ROC (rollover counter) is at the beginning of the auth tag.
  const size_t kRocLength = 4;
  if (tag_length < kRocLength || tag_length > length) {
    RTC_DCHECK_NOTREACHED();
    return;
  }

  uint8_t* auth_tag = rtp + (length - tag_length);

  // We should have a fake HMAC value @ auth_tag.
  RTC_DCHECK_EQ(0, memcmp(auth_tag, kFakeAuthTag, tag_length));

  // Copy ROC after end of rtp packet.
  memcpy(auth_tag, &packet_time_params.srtp_packet_index, kRocLength);
  // Authentication of a RTP packet will have RTP packet + ROC size.
  size_t auth_required_length = length - tag_length + kRocLength;

  uint8_t output[64];
  size_t result =
      rtc::ComputeHmac(rtc::DIGEST_SHA_1, &packet_time_params.srtp_auth_key[0],
                       packet_time_params.srtp_auth_key.size(), rtp,
                       auth_required_length, output, sizeof(output));

  if (result < tag_length) {
    RTC_DCHECK_NOTREACHED();
    return;
  }

  // Copy HMAC from output to packet. This is required as auth tag length
  // may not be equal to the actual HMAC length.
  memcpy(auth_tag, output, tag_length);
}

bool GetUint8(const void* data, size_t offset, int* value) {
  if (!data || !value) {
    return false;
  }
  *value = *(static_cast<const uint8_t*>(data) + offset);
  return true;
}

}  // namespace

bool GetRtcpType(const void* data, size_t len, int* value) {
  if (len < kMinRtcpPacketLen) {
    return false;
  }
  return GetUint8(data, kRtcpPayloadTypeOffset, value);
}

// This method returns SSRC first of RTCP packet, except if packet is SDES.
// TODO(mallinath) - Fully implement RFC 5506. This standard doesn't restrict
// to send non-compound packets only to feedback messages.
bool GetRtcpSsrc(const void* data, size_t len, uint32_t* value) {
  // Packet should be at least of 8 bytes, to get SSRC from a RTCP packet.
  if (!data || len < kMinRtcpPacketLen + 4 || !value)
    return false;
  int pl_type;
  if (!GetRtcpType(data, len, &pl_type))
    return false;
  // SDES packet parsing is not supported.
  if (pl_type == kRtcpTypeSDES)
    return false;
  *value = rtc::GetBE32(static_cast<const uint8_t*>(data) + 4);
  return true;
}

bool IsValidRtpPayloadType(int payload_type) {
  return payload_type >= 0 && payload_type <= 127;
}

bool IsValidRtpPacketSize(RtpPacketType packet_type, size_t size) {
  RTC_DCHECK_NE(RtpPacketType::kUnknown, packet_type);
  size_t min_packet_length = packet_type == RtpPacketType::kRtcp
                                 ? kMinRtcpPacketLen
                                 : kMinRtpPacketLen;
  return size >= min_packet_length && size <= kMaxRtpPacketLen;
}

absl::string_view RtpPacketTypeToString(RtpPacketType packet_type) {
  switch (packet_type) {
    case RtpPacketType::kRtp:
      return "RTP";
    case RtpPacketType::kRtcp:
      return "RTCP";
    case RtpPacketType::kUnknown:
      return "Unknown";
  }
  RTC_CHECK_NOTREACHED();
}

RtpPacketType InferRtpPacketType(rtc::ArrayView<const uint8_t> packet) {
  if (webrtc::IsRtcpPacket(packet)) {
    return RtpPacketType::kRtcp;
  }
  if (webrtc::IsRtpPacket(packet)) {
    return RtpPacketType::kRtp;
  }
  return RtpPacketType::kUnknown;
}

bool ValidateRtpHeader(const uint8_t* rtp,
                       size_t length,
                       size_t* header_length) {
  if (header_length) {
    *header_length = 0;
  }

  if (length < kMinRtpPacketLen) {
    return false;
  }

  size_t cc_count = rtp[0] & 0x0F;
  size_t header_length_without_extension = kMinRtpPacketLen + 4 * cc_count;
  if (header_length_without_extension > length) {
    return false;
  }

  // If extension bit is not set, we are done with header processing, as input
  // length is verified above.
  if (!(rtp[0] & 0x10)) {
    if (header_length)
      *header_length = header_length_without_extension;

    return true;
  }

  rtp += header_length_without_extension;

  if (header_length_without_extension + kRtpExtensionHeaderLen > length) {
    return false;
  }

  // Getting extension profile length.
  // Length is in 32 bit words.
  uint16_t extension_length_in_32bits = rtc::GetBE16(rtp + 2);
  size_t extension_length = extension_length_in_32bits * 4;

  size_t rtp_header_length = extension_length +
                             header_length_without_extension +
                             kRtpExtensionHeaderLen;

  // Verify input length against total header size.
  if (rtp_header_length > length) {
    return false;
  }

  if (header_length) {
    *header_length = rtp_header_length;
  }
  return true;
}

// ValidateRtpHeader() must be called before this method to make sure, we have
// a sane rtp packet.
bool UpdateRtpAbsSendTimeExtension(uint8_t* rtp,
                                   size_t /* length */,
                                   int extension_id,
                                   uint64_t time_us) {
  //  0                   1                   2                   3
  //  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  // |V=2|P|X|  CC   |M|     PT      |       sequence number         |
  // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  // |                           timestamp                           |
  // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  // |           synchronization source (SSRC) identifier            |
  // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
  // |            contributing source (CSRC) identifiers             |
  // |                             ....                              |
  // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

  // Return if extension bit is not set.
  if (!(rtp[0] & 0x10)) {
    return true;
  }

  size_t cc_count = rtp[0] & 0x0F;
  size_t header_length_without_extension = kMinRtpPacketLen + 4 * cc_count;

  rtp += header_length_without_extension;

  // Getting extension profile ID and length.
  uint16_t profile_id = rtc::GetBE16(rtp);
  // Length is in 32 bit words.
  uint16_t extension_length_in_32bits = rtc::GetBE16(rtp + 2);
  size_t extension_length = extension_length_in_32bits * 4;

  rtp += kRtpExtensionHeaderLen;  // Moving past extension header.

  constexpr uint16_t kOneByteExtensionProfileId = 0xBEDE;
  constexpr uint16_t kTwoByteExtensionProfileId = 0x1000;

  bool found = false;
  if (profile_id == kOneByteExtensionProfileId ||
      profile_id == kTwoByteExtensionProfileId) {
    // OneByte extension header
    //  0
    //  0 1 2 3 4 5 6 7
    // +-+-+-+-+-+-+-+-+
    // |  ID   |length |
    // +-+-+-+-+-+-+-+-+

    //  0                   1                   2                   3
    //  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    // |       0xBE    |    0xDE       |           length=3            |
    // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    // |  ID   | L=0   |     data      |  ID   |  L=1  |   data...
    // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    //       ...data   |    0 (pad)    |    0 (pad)    |  ID   | L=3   |
    // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    // |                          data                                 |
    // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

    // TwoByte extension header
    //  0
    //  0 1 2 3 4 5 6 7
    // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    // |      ID       |    length     |
    // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

    //  0                   1                   2                   3
    //  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    // |     0x10      |     0x00      |           length=3            |
    // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    // |      ID       |      L=1      |     data      |      ID       |
    // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    // |      L=2      |             data              |    0 (pad)    |
    // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    // |      ID       |      L=2      |             data              |
    // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

    size_t extension_header_length = profile_id == kOneByteExtensionProfileId
                                         ? kOneByteExtensionHeaderLen
                                         : kTwoByteExtensionHeaderLen;

    const uint8_t* extension_start = rtp;
    const uint8_t* extension_end = extension_start + extension_length;

    // rtp + 1 since the minimum size per header extension is two bytes for both
    // one- and two-byte header extensions.
    while (rtp + 1 < extension_end) {
      // See RFC8285 Section 4.2-4.3 for more information about one- and
      // two-byte header extensions.
      const int id =
          profile_id == kOneByteExtensionProfileId ? (*rtp & 0xF0) >> 4 : *rtp;
      const size_t length = profile_id == kOneByteExtensionProfileId
                                ? (*rtp & 0x0F) + 1
                                : *(rtp + 1);
      if (rtp + extension_header_length + length > extension_end) {
        return false;
      }
      if (id == extension_id) {
        UpdateAbsSendTimeExtensionValue(rtp + extension_header_length, length,
                                        time_us);
        found = true;
        break;
      }
      rtp += extension_header_length + length;
      // Counting padding bytes.
      while ((rtp < extension_end) && (*rtp == 0)) {
        ++rtp;
      }
    }
  }
  return found;
}

bool ApplyPacketOptions(uint8_t* data,
                        size_t length,
                        const rtc::PacketTimeUpdateParams& packet_time_params,
                        uint64_t time_us) {
  RTC_DCHECK(data);
  RTC_DCHECK(length);

  // if there is no valid `rtp_sendtime_extension_id` and `srtp_auth_key` in
  // PacketOptions, nothing to be updated in this packet.
  if (packet_time_params.rtp_sendtime_extension_id == -1 &&
      packet_time_params.srtp_auth_key.empty()) {
    return true;
  }

  // If there is a srtp auth key present then the packet must be an RTP packet.
  // RTP packet may have been wrapped in a TURN Channel Data or TURN send
  // indication.
  size_t rtp_start_pos;
  size_t rtp_length;
  if (!UnwrapTurnPacket(data, length, &rtp_start_pos, &rtp_length)) {
    RTC_DCHECK_NOTREACHED();
    return false;
  }

  // Making sure we have a valid RTP packet at the end.
  auto packet = rtc::MakeArrayView(data + rtp_start_pos, rtp_length);
  if (!webrtc::IsRtpPacket(packet) ||
      !ValidateRtpHeader(data + rtp_start_pos, rtp_length, nullptr)) {
    RTC_DCHECK_NOTREACHED();
    return false;
  }

  uint8_t* start = data + rtp_start_pos;
  // If packet option has non default value (-1) for sendtime extension id,
  // then we should parse the rtp packet to update the timestamp. Otherwise
  // just calculate HMAC and update packet with it.
  if (packet_time_params.rtp_sendtime_extension_id != -1) {
    UpdateRtpAbsSendTimeExtension(start, rtp_length,
                                  packet_time_params.rtp_sendtime_extension_id,
                                  time_us);
  }

  UpdateRtpAuthTag(start, rtp_length, packet_time_params);
  return true;
}

}  // namespace cricket
