/*
 *  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 <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 kRtpPayloadTypeOffset = 1;
static const size_t kRtpSeqNumOffset = 2;
static const size_t kRtpTimestampOffset = 4;
static const size_t kRtpSsrcOffset = 8;
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_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_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_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;
}

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

bool GetUint32(const void* data, size_t offset, uint32_t* value) {
  if (!data || !value) {
    return false;
  }
  *value = rtc::GetBE32(static_cast<const uint8_t*>(data) + offset);
  return true;
}

}  // namespace

bool GetRtpPayloadType(const void* data, size_t len, int* value) {
  if (len < kMinRtpPacketLen) {
    return false;
  }
  if (!GetUint8(data, kRtpPayloadTypeOffset, value)) {
    return false;
  }
  *value &= 0x7F;
  return true;
}

bool GetRtpSeqNum(const void* data, size_t len, int* value) {
  if (len < kMinRtpPacketLen) {
    return false;
  }
  return GetUint16(data, kRtpSeqNumOffset, value);
}

bool GetRtpTimestamp(const void* data, size_t len, uint32_t* value) {
  if (len < kMinRtpPacketLen) {
    return false;
  }
  return GetUint32(data, kRtpTimestampOffset, value);
}

bool GetRtpSsrc(const void* data, size_t len, uint32_t* value) {
  if (len < kMinRtpPacketLen) {
    return false;
  }
  return GetUint32(data, kRtpSsrcOffset, value);
}

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 char> packet) {
  if (webrtc::IsRtcpPacket(
          rtc::reinterpret_array_view<const uint8_t>(packet))) {
    return RtpPacketType::kRtcp;
  }
  if (webrtc::IsRtpPacket(rtc::reinterpret_array_view<const uint8_t>(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_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_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
