// 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 "net/third_party/quiche/src/quic/core/quic_linux_socket_utils.h"

#include <netinet/in.h>
#include <stdint.h>
#include <cstddef>
#include <sstream>
#include <vector>

#include <string>

#include "net/third_party/quiche/src/quic/core/quic_circular_deque.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
#include "net/third_party/quiche/src/quic/test_tools/quic_mock_syscall_wrapper.h"

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

namespace quic {
namespace test {
namespace {

class QuicLinuxSocketUtilsTest : public QuicTest {
 protected:
  WriteResult TestWriteMultiplePackets(
      int fd,
      const QuicCircularDeque<BufferedWrite>::const_iterator& first,
      const QuicCircularDeque<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) {
  QuicCircularDeque<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;
  QuicCircularDeque<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;
  QuicCircularDeque<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;
  QuicCircularDeque<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;
  QuicCircularDeque<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
