// Copyright (c) 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef QUICHE_QUIC_CORE_QUIC_LINUX_SOCKET_UTILS_H_
#define QUICHE_QUIC_CORE_QUIC_LINUX_SOCKET_UTILS_H_

#include <errno.h>
#include <stddef.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/uio.h>

#include <deque>
#include <functional>
#include <iterator>
#include <memory>
#include <type_traits>
#include <utility>

#include "quiche/quic/core/quic_packet_writer.h"
#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/platform/api/quic_bug_tracker.h"
#include "quiche/quic/platform/api/quic_ip_address.h"
#include "quiche/quic/platform/api/quic_logging.h"
#include "quiche/quic/platform/api/quic_socket_address.h"
#include "quiche/common/quiche_callbacks.h"

#ifndef SOL_UDP
#define SOL_UDP 17
#endif

#ifndef UDP_SEGMENT
#define UDP_SEGMENT 103
#endif

#ifndef UDP_MAX_SEGMENTS
#define UDP_MAX_SEGMENTS (1 << 6UL)
#endif

#ifndef SO_TXTIME
#define SO_TXTIME 61
#endif

namespace quic {

inline constexpr int kCmsgSpaceForIpv4 = CMSG_SPACE(sizeof(in_pktinfo));
inline constexpr int kCmsgSpaceForIpv6 = CMSG_SPACE(sizeof(in6_pktinfo));
// kCmsgSpaceForIp should be big enough to hold both IPv4 and IPv6 packet info.
inline constexpr int kCmsgSpaceForIp = (kCmsgSpaceForIpv4 < kCmsgSpaceForIpv6)
                                           ? kCmsgSpaceForIpv6
                                           : kCmsgSpaceForIpv4;

inline constexpr int kCmsgSpaceForSegmentSize = CMSG_SPACE(sizeof(uint16_t));

inline constexpr int kCmsgSpaceForTxTime = CMSG_SPACE(sizeof(uint64_t));

inline constexpr int kCmsgSpaceForTTL = CMSG_SPACE(sizeof(int));

inline constexpr int kCmsgSpaceForTOS = CMSG_SPACE(sizeof(int));

// QuicMsgHdr is used to build msghdr objects that can be used send packets via
// ::sendmsg.
//
// Example:
//   // cbuf holds control messages(cmsgs). The size is determined from what
//   // cmsgs will be set for this msghdr.
//   char cbuf[kCmsgSpaceForIp + kCmsgSpaceForSegmentSize];
//   QuicMsgHdr hdr(packet_buf, packet_buf_len, peer_addr, cbuf, sizeof(cbuf));
//
//   // Set IP in cmsgs.
//   hdr.SetIpInNextCmsg(self_addr);
//
//   // Set GSO size in cmsgs.
//   *hdr.GetNextCmsgData<uint16_t>(SOL_UDP, UDP_SEGMENT) = 1200;
//
//   QuicLinuxSocketUtils::WritePacket(fd, hdr);
class QUICHE_EXPORT QuicMsgHdr {
 public:
  QuicMsgHdr(const char* buffer, size_t buf_len,
             const QuicSocketAddress& peer_address, char* cbuf,
             size_t cbuf_size);

  // Set IP info in the next cmsg. Both IPv4 and IPv6 are supported.
  void SetIpInNextCmsg(const QuicIpAddress& self_address);

  template <typename DataType>
  DataType* GetNextCmsgData(int cmsg_level, int cmsg_type) {
    return reinterpret_cast<DataType*>(
        GetNextCmsgDataInternal(cmsg_level, cmsg_type, sizeof(DataType)));
  }

  const msghdr* hdr() const { return &hdr_; }

 protected:
  void* GetNextCmsgDataInternal(int cmsg_level, int cmsg_type,
                                size_t data_size);

  msghdr hdr_;
  iovec iov_;
  sockaddr_storage raw_peer_address_;
  char* cbuf_;
  const size_t cbuf_size_;
  // The last cmsg populated so far. nullptr means nothing has been populated.
  cmsghdr* cmsg_;
};

// BufferedWrite holds all information needed to send a packet.
struct QUICHE_EXPORT BufferedWrite {
  BufferedWrite(const char* buffer, size_t buf_len,
                const QuicIpAddress& self_address,
                const QuicSocketAddress& peer_address)
      : BufferedWrite(buffer, buf_len, self_address, peer_address,
                      std::unique_ptr<PerPacketOptions>(),
                      QuicPacketWriterParams(), /*release_time=*/0) {}

  BufferedWrite(const char* buffer, size_t buf_len,
                const QuicIpAddress& self_address,
                const QuicSocketAddress& peer_address,
                std::unique_ptr<PerPacketOptions> options,
                const QuicPacketWriterParams& params, uint64_t release_time)
      : buffer(buffer),
        buf_len(buf_len),
        self_address(self_address),
        peer_address(peer_address),
        options(std::move(options)),
        params(params),
        release_time(release_time) {}

  const char* buffer;  // Not owned.
  size_t buf_len;
  QuicIpAddress self_address;
  QuicSocketAddress peer_address;
  std::unique_ptr<PerPacketOptions> options;
  QuicPacketWriterParams params;

  // The release time according to the owning packet writer's clock, which is
  // often not a QuicClock. Calculated from packet writer's Now() and the
  // release time delay in |options|.
  // 0 means it can be sent at the same time as the previous packet in a batch,
  // or can be sent Now() if this is the first packet of a batch.
  uint64_t release_time;
};

// QuicMMsgHdr is used to build mmsghdr objects that can be used to send
// multiple packets at once via ::sendmmsg.
//
// Example:
//   quiche::QuicheCircularDeque<BufferedWrite> buffered_writes;
//   ... (Populate buffered_writes) ...
//
//   QuicMMsgHdr mhdr(
//       buffered_writes.begin(), buffered_writes.end(), kCmsgSpaceForIp,
//       [](QuicMMsgHdr* mhdr, int i, const BufferedWrite& buffered_write) {
//         mhdr->SetIpInNextCmsg(i, buffered_write.self_address);
//       });
//
//   int num_packets_sent;
//   QuicSocketUtils::WriteMultiplePackets(fd, &mhdr, &num_packets_sent);
class QUICHE_EXPORT QuicMMsgHdr {
 public:
  using ControlBufferInitializer = quiche::UnretainedCallback<void(
      QuicMMsgHdr* mhdr, int i, const BufferedWrite& buffered_write)>;
  template <typename IteratorT>
  QuicMMsgHdr(
      const IteratorT& first, const IteratorT& last, size_t cbuf_size,
      ControlBufferInitializer cbuf_initializer =
          +[](quic::QuicMMsgHdr*, int, const quic::BufferedWrite&) {})
      : num_msgs_(std::distance(first, last)), cbuf_size_(cbuf_size) {
    static_assert(
        std::is_same<typename std::iterator_traits<IteratorT>::value_type,
                     BufferedWrite>::value,
        "Must iterate over a collection of BufferedWrite.");

    QUICHE_DCHECK_LE(0, num_msgs_);
    if (num_msgs_ == 0) {
      return;
    }

    storage_.reset(new char[StorageSize()]);
    memset(&storage_[0], 0, StorageSize());

    int i = -1;
    for (auto it = first; it != last; ++it) {
      ++i;

      InitOneHeader(i, *it);
      cbuf_initializer(this, i, *it);
    }
  }

  void SetIpInNextCmsg(int i, const QuicIpAddress& self_address);

  template <typename DataType>
  DataType* GetNextCmsgData(int i, int cmsg_level, int cmsg_type) {
    return reinterpret_cast<DataType*>(
        GetNextCmsgDataInternal(i, cmsg_level, cmsg_type, sizeof(DataType)));
  }

  mmsghdr* mhdr() { return GetMMsgHdr(0); }

  int num_msgs() const { return num_msgs_; }

  // Get the total number of bytes in the first |num_packets_sent| packets.
  int num_bytes_sent(int num_packets_sent);

 protected:
  void InitOneHeader(int i, const BufferedWrite& buffered_write);

  void* GetNextCmsgDataInternal(int i, int cmsg_level, int cmsg_type,
                                size_t data_size);

  size_t StorageSize() const {
    return num_msgs_ *
           (sizeof(mmsghdr) + sizeof(iovec) + sizeof(sockaddr_storage) +
            sizeof(cmsghdr*) + cbuf_size_);
  }

  mmsghdr* GetMMsgHdr(int i) {
    auto* first = reinterpret_cast<mmsghdr*>(&storage_[0]);
    return &first[i];
  }

  iovec* GetIov(int i) {
    auto* first = reinterpret_cast<iovec*>(GetMMsgHdr(num_msgs_));
    return &first[i];
  }

  sockaddr_storage* GetPeerAddressStorage(int i) {
    auto* first = reinterpret_cast<sockaddr_storage*>(GetIov(num_msgs_));
    return &first[i];
  }

  cmsghdr** GetCmsgHdr(int i) {
    auto* first = reinterpret_cast<cmsghdr**>(GetPeerAddressStorage(num_msgs_));
    return &first[i];
  }

  char* GetCbuf(int i) {
    auto* first = reinterpret_cast<char*>(GetCmsgHdr(num_msgs_));
    return &first[i * cbuf_size_];
  }

  const int num_msgs_;
  // Size of cmsg buffer for each message.
  const size_t cbuf_size_;
  // storage_ holds the memory of
  // |num_msgs_| mmsghdr
  // |num_msgs_| iovec
  // |num_msgs_| sockaddr_storage, for peer addresses
  // |num_msgs_| cmsghdr*
  // |num_msgs_| cbuf, each of size cbuf_size
  std::unique_ptr<char[]> storage_;
};

class QUICHE_EXPORT QuicLinuxSocketUtils {
 public:
  // Return the UDP segment size of |fd|, 0 means segment size has not been set
  // on this socket. If GSO is not supported, return -1.
  static int GetUDPSegmentSize(int fd);

  // Enable release time on |fd|.
  static bool EnableReleaseTime(int fd, clockid_t clockid);

  // If the msghdr contains an IP_TTL entry, this will set ttl to the correct
  // value and return true. Otherwise it will return false.
  static bool GetTtlFromMsghdr(struct msghdr* hdr, int* ttl);

  // Set IP(self_address) in |cmsg_data|. Does not touch other fields in the
  // containing cmsghdr.
  static void SetIpInfoInCmsgData(const QuicIpAddress& self_address,
                                  void* cmsg_data);

  // A helper for WritePacket which fills in the cmsg with the supplied self
  // address.
  // Returns the length of the packet info structure used.
  static size_t SetIpInfoInCmsg(const QuicIpAddress& self_address,
                                cmsghdr* cmsg);

  // Writes the packet in |hdr| to the socket, using ::sendmsg.
  static WriteResult WritePacket(int fd, const QuicMsgHdr& hdr);

  // Writes the packets in |mhdr| to the socket, using ::sendmmsg if available.
  static WriteResult WriteMultiplePackets(int fd, QuicMMsgHdr* mhdr,
                                          int* num_packets_sent);
};

}  // namespace quic

#endif  // QUICHE_QUIC_CORE_QUIC_LINUX_SOCKET_UTILS_H_
