// 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.

#include "quiche/quic/core/quic_linux_socket_utils.h"

#include <netinet/in.h>
#include <stdint.h>

#include <cstddef>
#include <sstream>
#include <string>
#include <vector>

#include "quiche/quic/platform/api/quic_test.h"
#include "quiche/quic/test_tools/quic_mock_syscall_wrapper.h"
#include "quiche/common/quiche_circular_deque.h"

using testing::_;
using testing::InSequence;
using testing::Invoke;

namespace quic {
namespace test {
namespace {

class QuicLinuxSocketUtilsTest : public QuicTest {
 protected:
  WriteResult TestWriteMultiplePackets(
      int fd,
      const quiche::QuicheCircularDeque<BufferedWrite>::const_iterator& first,
      const quiche::QuicheCircularDeque<BufferedWrite>::const_iterator& last,
      int* num_packets_sent) {
    QuicMMsgHdr mhdr(
        first, last, kCmsgSpaceForIp,
        [](QuicMMsgHdr* mhdr, int i, const BufferedWrite& buffered_write) {
          mhdr->SetIpInNextCmsg(i, buffered_write.self_address);
        });

    WriteResult res =
        QuicLinuxSocketUtils::WriteMultiplePackets(fd, &mhdr, num_packets_sent);
    return res;
  }

  MockQuicSyscallWrapper mock_syscalls_;
  ScopedGlobalSyscallWrapperOverride syscall_override_{&mock_syscalls_};
};

void CheckIpAndTtlInCbuf(msghdr* hdr, const void* cbuf,
                         const QuicIpAddress& self_addr, int ttl) {
  const bool is_ipv4 = self_addr.IsIPv4();
  const size_t ip_cmsg_space = is_ipv4 ? kCmsgSpaceForIpv4 : kCmsgSpaceForIpv6;

  EXPECT_EQ(cbuf, hdr->msg_control);
  EXPECT_EQ(ip_cmsg_space + CMSG_SPACE(sizeof(uint16_t)), hdr->msg_controllen);

  cmsghdr* cmsg = CMSG_FIRSTHDR(hdr);
  EXPECT_EQ(cmsg->cmsg_len, is_ipv4 ? CMSG_LEN(sizeof(in_pktinfo))
                                    : CMSG_LEN(sizeof(in6_pktinfo)));
  EXPECT_EQ(cmsg->cmsg_level, is_ipv4 ? IPPROTO_IP : IPPROTO_IPV6);
  EXPECT_EQ(cmsg->cmsg_type, is_ipv4 ? IP_PKTINFO : IPV6_PKTINFO);

  const std::string& self_addr_str = self_addr.ToPackedString();
  if (is_ipv4) {
    in_pktinfo* pktinfo = reinterpret_cast<in_pktinfo*>(CMSG_DATA(cmsg));
    EXPECT_EQ(0, memcmp(&pktinfo->ipi_spec_dst, self_addr_str.c_str(),
                        self_addr_str.length()));
  } else {
    in6_pktinfo* pktinfo = reinterpret_cast<in6_pktinfo*>(CMSG_DATA(cmsg));
    EXPECT_EQ(0, memcmp(&pktinfo->ipi6_addr, self_addr_str.c_str(),
                        self_addr_str.length()));
  }

  cmsg = CMSG_NXTHDR(hdr, cmsg);
  EXPECT_EQ(cmsg->cmsg_len, CMSG_LEN(sizeof(int)));
  EXPECT_EQ(cmsg->cmsg_level, is_ipv4 ? IPPROTO_IP : IPPROTO_IPV6);
  EXPECT_EQ(cmsg->cmsg_type, is_ipv4 ? IP_TTL : IPV6_HOPLIMIT);
  EXPECT_EQ(ttl, *reinterpret_cast<int*>(CMSG_DATA(cmsg)));

  EXPECT_EQ(nullptr, CMSG_NXTHDR(hdr, cmsg));
}

void CheckMsghdrWithoutCbuf(const msghdr* hdr, const void* buffer,
                            size_t buf_len,
                            const QuicSocketAddress& peer_addr) {
  EXPECT_EQ(
      peer_addr.host().IsIPv4() ? sizeof(sockaddr_in) : sizeof(sockaddr_in6),
      hdr->msg_namelen);
  sockaddr_storage peer_generic_addr = peer_addr.generic_address();
  EXPECT_EQ(0, memcmp(hdr->msg_name, &peer_generic_addr, hdr->msg_namelen));
  EXPECT_EQ(1u, hdr->msg_iovlen);
  EXPECT_EQ(buffer, hdr->msg_iov->iov_base);
  EXPECT_EQ(buf_len, hdr->msg_iov->iov_len);
  EXPECT_EQ(0, hdr->msg_flags);
  EXPECT_EQ(nullptr, hdr->msg_control);
  EXPECT_EQ(0u, hdr->msg_controllen);
}

void CheckIpAndGsoSizeInCbuf(msghdr* hdr, const void* cbuf,
                             const QuicIpAddress& self_addr,
                             uint16_t gso_size) {
  const bool is_ipv4 = self_addr.IsIPv4();
  const size_t ip_cmsg_space = is_ipv4 ? kCmsgSpaceForIpv4 : kCmsgSpaceForIpv6;

  EXPECT_EQ(cbuf, hdr->msg_control);
  EXPECT_EQ(ip_cmsg_space + CMSG_SPACE(sizeof(uint16_t)), hdr->msg_controllen);

  cmsghdr* cmsg = CMSG_FIRSTHDR(hdr);
  EXPECT_EQ(cmsg->cmsg_len, is_ipv4 ? CMSG_LEN(sizeof(in_pktinfo))
                                    : CMSG_LEN(sizeof(in6_pktinfo)));
  EXPECT_EQ(cmsg->cmsg_level, is_ipv4 ? IPPROTO_IP : IPPROTO_IPV6);
  EXPECT_EQ(cmsg->cmsg_type, is_ipv4 ? IP_PKTINFO : IPV6_PKTINFO);

  const std::string& self_addr_str = self_addr.ToPackedString();
  if (is_ipv4) {
    in_pktinfo* pktinfo = reinterpret_cast<in_pktinfo*>(CMSG_DATA(cmsg));
    EXPECT_EQ(0, memcmp(&pktinfo->ipi_spec_dst, self_addr_str.c_str(),
                        self_addr_str.length()));
  } else {
    in6_pktinfo* pktinfo = reinterpret_cast<in6_pktinfo*>(CMSG_DATA(cmsg));
    EXPECT_EQ(0, memcmp(&pktinfo->ipi6_addr, self_addr_str.c_str(),
                        self_addr_str.length()));
  }

  cmsg = CMSG_NXTHDR(hdr, cmsg);
  EXPECT_EQ(cmsg->cmsg_len, CMSG_LEN(sizeof(uint16_t)));
  EXPECT_EQ(cmsg->cmsg_level, SOL_UDP);
  EXPECT_EQ(cmsg->cmsg_type, UDP_SEGMENT);
  EXPECT_EQ(gso_size, *reinterpret_cast<uint16_t*>(CMSG_DATA(cmsg)));

  EXPECT_EQ(nullptr, CMSG_NXTHDR(hdr, cmsg));
}

TEST_F(QuicLinuxSocketUtilsTest, QuicMsgHdr) {
  QuicSocketAddress peer_addr(QuicIpAddress::Loopback4(), 1234);
  char packet_buf[1024];

  QuicMsgHdr quic_hdr(packet_buf, sizeof(packet_buf), peer_addr, nullptr, 0);
  CheckMsghdrWithoutCbuf(quic_hdr.hdr(), packet_buf, sizeof(packet_buf),
                         peer_addr);

  for (bool is_ipv4 : {true, false}) {
    QuicIpAddress self_addr =
        is_ipv4 ? QuicIpAddress::Loopback4() : QuicIpAddress::Loopback6();
    char cbuf[kCmsgSpaceForIp + kCmsgSpaceForTTL];
    QuicMsgHdr quic_hdr(packet_buf, sizeof(packet_buf), peer_addr, cbuf,
                        sizeof(cbuf));
    msghdr* hdr = const_cast<msghdr*>(quic_hdr.hdr());

    EXPECT_EQ(nullptr, hdr->msg_control);
    EXPECT_EQ(0u, hdr->msg_controllen);

    quic_hdr.SetIpInNextCmsg(self_addr);
    EXPECT_EQ(cbuf, hdr->msg_control);
    const size_t ip_cmsg_space =
        is_ipv4 ? kCmsgSpaceForIpv4 : kCmsgSpaceForIpv6;
    EXPECT_EQ(ip_cmsg_space, hdr->msg_controllen);

    if (is_ipv4) {
      *quic_hdr.GetNextCmsgData<int>(IPPROTO_IP, IP_TTL) = 32;
    } else {
      *quic_hdr.GetNextCmsgData<int>(IPPROTO_IPV6, IPV6_HOPLIMIT) = 32;
    }

    CheckIpAndTtlInCbuf(hdr, cbuf, self_addr, 32);
  }
}

TEST_F(QuicLinuxSocketUtilsTest, QuicMMsgHdr) {
  quiche::QuicheCircularDeque<BufferedWrite> buffered_writes;
  char packet_buf1[1024];
  char packet_buf2[512];
  buffered_writes.emplace_back(
      packet_buf1, sizeof(packet_buf1), QuicIpAddress::Loopback4(),
      QuicSocketAddress(QuicIpAddress::Loopback4(), 4));
  buffered_writes.emplace_back(
      packet_buf2, sizeof(packet_buf2), QuicIpAddress::Loopback6(),
      QuicSocketAddress(QuicIpAddress::Loopback6(), 6));

  QuicMMsgHdr quic_mhdr_without_cbuf(buffered_writes.begin(),
                                     buffered_writes.end(), 0, nullptr);
  for (size_t i = 0; i < buffered_writes.size(); ++i) {
    const BufferedWrite& bw = buffered_writes[i];
    CheckMsghdrWithoutCbuf(&quic_mhdr_without_cbuf.mhdr()[i].msg_hdr, bw.buffer,
                           bw.buf_len, bw.peer_address);
  }

  QuicMMsgHdr quic_mhdr_with_cbuf(
      buffered_writes.begin(), buffered_writes.end(),
      kCmsgSpaceForIp + kCmsgSpaceForSegmentSize,
      [](QuicMMsgHdr* mhdr, int i, const BufferedWrite& buffered_write) {
        mhdr->SetIpInNextCmsg(i, buffered_write.self_address);
        *mhdr->GetNextCmsgData<uint16_t>(i, SOL_UDP, UDP_SEGMENT) = 1300;
      });
  for (size_t i = 0; i < buffered_writes.size(); ++i) {
    const BufferedWrite& bw = buffered_writes[i];
    msghdr* hdr = &quic_mhdr_with_cbuf.mhdr()[i].msg_hdr;
    CheckIpAndGsoSizeInCbuf(hdr, hdr->msg_control, bw.self_address, 1300);
  }
}

TEST_F(QuicLinuxSocketUtilsTest, WriteMultiplePackets_NoPacketsToSend) {
  int num_packets_sent;
  quiche::QuicheCircularDeque<BufferedWrite> buffered_writes;

  EXPECT_CALL(mock_syscalls_, Sendmmsg(_, _, _, _)).Times(0);

  EXPECT_EQ(WriteResult(WRITE_STATUS_ERROR, EINVAL),
            TestWriteMultiplePackets(1, buffered_writes.begin(),
                                     buffered_writes.end(), &num_packets_sent));
}

TEST_F(QuicLinuxSocketUtilsTest, WriteMultiplePackets_WriteBlocked) {
  int num_packets_sent;
  quiche::QuicheCircularDeque<BufferedWrite> buffered_writes;
  buffered_writes.emplace_back(nullptr, 0, QuicIpAddress(),
                               QuicSocketAddress(QuicIpAddress::Any4(), 0));

  EXPECT_CALL(mock_syscalls_, Sendmmsg(_, _, _, _))
      .WillOnce(Invoke([](int /*fd*/, mmsghdr* /*msgvec*/,
                          unsigned int /*vlen*/, int /*flags*/) {
        errno = EWOULDBLOCK;
        return -1;
      }));

  EXPECT_EQ(WriteResult(WRITE_STATUS_BLOCKED, EWOULDBLOCK),
            TestWriteMultiplePackets(1, buffered_writes.begin(),
                                     buffered_writes.end(), &num_packets_sent));
  EXPECT_EQ(0, num_packets_sent);
}

TEST_F(QuicLinuxSocketUtilsTest, WriteMultiplePackets_WriteError) {
  int num_packets_sent;
  quiche::QuicheCircularDeque<BufferedWrite> buffered_writes;
  buffered_writes.emplace_back(nullptr, 0, QuicIpAddress(),
                               QuicSocketAddress(QuicIpAddress::Any4(), 0));

  EXPECT_CALL(mock_syscalls_, Sendmmsg(_, _, _, _))
      .WillOnce(Invoke([](int /*fd*/, mmsghdr* /*msgvec*/,
                          unsigned int /*vlen*/, int /*flags*/) {
        errno = EPERM;
        return -1;
      }));

  EXPECT_EQ(WriteResult(WRITE_STATUS_ERROR, EPERM),
            TestWriteMultiplePackets(1, buffered_writes.begin(),
                                     buffered_writes.end(), &num_packets_sent));
  EXPECT_EQ(0, num_packets_sent);
}

TEST_F(QuicLinuxSocketUtilsTest, WriteMultiplePackets_WriteSuccess) {
  int num_packets_sent;
  quiche::QuicheCircularDeque<BufferedWrite> buffered_writes;
  const int kNumBufferedWrites = 10;
  static_assert(kNumBufferedWrites < 256, "Must be less than 256");
  std::vector<std::string> buffer_holder;
  for (int i = 0; i < kNumBufferedWrites; ++i) {
    size_t buf_len = (i + 1) * 2;
    std::ostringstream buffer_ostream;
    while (buffer_ostream.str().length() < buf_len) {
      buffer_ostream << i;
    }
    buffer_holder.push_back(buffer_ostream.str().substr(0, buf_len - 1) + '$');

    buffered_writes.emplace_back(buffer_holder.back().data(), buf_len,
                                 QuicIpAddress(),
                                 QuicSocketAddress(QuicIpAddress::Any4(), 0));

    // Leave the first self_address uninitialized.
    if (i != 0) {
      ASSERT_TRUE(buffered_writes.back().self_address.FromString("127.0.0.1"));
    }

    std::ostringstream peer_ip_ostream;
    QuicIpAddress peer_ip_address;
    peer_ip_ostream << "127.0.1." << i + 1;
    ASSERT_TRUE(peer_ip_address.FromString(peer_ip_ostream.str()));
    buffered_writes.back().peer_address =
        QuicSocketAddress(peer_ip_address, i + 1);
  }

  InSequence s;

  for (int expected_num_packets_sent : {1, 2, 3, 10}) {
    SCOPED_TRACE(testing::Message()
                 << "expected_num_packets_sent=" << expected_num_packets_sent);
    EXPECT_CALL(mock_syscalls_, Sendmmsg(_, _, _, _))
        .WillOnce(Invoke([&](int /*fd*/, mmsghdr* msgvec, unsigned int vlen,
                             int /*flags*/) {
          EXPECT_LE(static_cast<unsigned int>(expected_num_packets_sent), vlen);
          for (unsigned int i = 0; i < vlen; ++i) {
            const BufferedWrite& buffered_write = buffered_writes[i];
            const msghdr& hdr = msgvec[i].msg_hdr;
            EXPECT_EQ(1u, hdr.msg_iovlen);
            EXPECT_EQ(buffered_write.buffer, hdr.msg_iov->iov_base);
            EXPECT_EQ(buffered_write.buf_len, hdr.msg_iov->iov_len);
            sockaddr_storage expected_peer_address =
                buffered_write.peer_address.generic_address();
            EXPECT_EQ(0, memcmp(&expected_peer_address, hdr.msg_name,
                                sizeof(sockaddr_storage)));
            EXPECT_EQ(buffered_write.self_address.IsInitialized(),
                      hdr.msg_control != nullptr);
          }
          return expected_num_packets_sent;
        }))
        .RetiresOnSaturation();

    int expected_bytes_written = 0;
    for (auto it = buffered_writes.cbegin();
         it != buffered_writes.cbegin() + expected_num_packets_sent; ++it) {
      expected_bytes_written += it->buf_len;
    }

    EXPECT_EQ(
        WriteResult(WRITE_STATUS_OK, expected_bytes_written),
        TestWriteMultiplePackets(1, buffered_writes.cbegin(),
                                 buffered_writes.cend(), &num_packets_sent));
    EXPECT_EQ(expected_num_packets_sent, num_packets_sent);
  }
}

}  // namespace
}  // namespace test
}  // namespace quic
