// Copyright 2018 The Chromium OS 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 "shill/net/sockets.h"

#include <errno.h>
#include <fcntl.h>
#include <net/if.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <unistd.h>

#include <base/logging.h>
#include <base/posix/eintr_wrapper.h>

namespace shill {

Sockets::Sockets() = default;

Sockets::~Sockets() = default;

// Some system calls can be interrupted and return EINTR, but will succeed on
// retry.  The HANDLE_EINTR macro retries a call if it returns EINTR.  For a
// list of system calls that can return EINTR, see 'man 7 signal' under the
// heading "Interruption of System Calls and Library Functions by Signal
// Handlers".

int Sockets::Accept(int sockfd,
                    struct sockaddr* addr,
                    socklen_t* addrlen) const {
  return HANDLE_EINTR(accept(sockfd, addr, addrlen));
}

int Sockets::AttachFilter(int sockfd, struct sock_fprog* pf) const {
  return setsockopt(sockfd, SOL_SOCKET, SO_ATTACH_FILTER, pf, sizeof(*pf));
}

int Sockets::Bind(int sockfd,
                  const struct sockaddr* addr,
                  socklen_t addrlen) const {
  return bind(sockfd, addr, addrlen);
}

int Sockets::BindToDevice(int sockfd, const std::string& device) const {
  char dev_name[IFNAMSIZ];
  CHECK_GT(sizeof(dev_name), device.length());
  memset(&dev_name, 0, sizeof(dev_name));
  snprintf(dev_name, sizeof(dev_name), "%s", device.c_str());
  return setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, &dev_name,
                    sizeof(dev_name));
}

int Sockets::ReuseAddress(int sockfd) const {
  int value = 1;
  return setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(value));
}

int Sockets::AddMulticastMembership(int sockfd, in_addr_t addr) const {
  ip_mreq mreq;
  mreq.imr_multiaddr.s_addr = addr;
  mreq.imr_interface.s_addr = htonl(INADDR_ANY);
  return setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
}

int Sockets::Close(int fd) const {
  return IGNORE_EINTR(close(fd));
}

int Sockets::Connect(int sockfd,
                     const struct sockaddr* addr,
                     socklen_t addrlen) const {
  return HANDLE_EINTR(connect(sockfd, addr, addrlen));
}

int Sockets::Error() const {
  return errno;
}

std::string Sockets::ErrorString() const {
  return std::string(strerror(Error()));
}

int Sockets::GetSockName(int sockfd,
                         struct sockaddr* addr,
                         socklen_t* addrlen) const {
  return getsockname(sockfd, addr, addrlen);
}

int Sockets::GetSocketError(int sockfd) const {
  int error;
  socklen_t optlen = sizeof(error);
  if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &optlen) == 0) {
    return error;
  }
  return -1;
}

int Sockets::Ioctl(int d, int request, void* argp) const {
  return HANDLE_EINTR(ioctl(d, request, argp));
}

int Sockets::Listen(int sockfd, int backlog) const {
  return listen(sockfd, backlog);
}

ssize_t Sockets::RecvFrom(int sockfd,
                          void* buf,
                          size_t len,
                          int flags,
                          struct sockaddr* src_addr,
                          socklen_t* addrlen) const {
  return HANDLE_EINTR(recvfrom(sockfd, buf, len, flags, src_addr, addrlen));
}

int Sockets::Select(int nfds,
                    fd_set* readfds,
                    fd_set* writefds,
                    fd_set* exceptfds,
                    struct timeval* timeout) const {
  return HANDLE_EINTR(select(nfds, readfds, writefds, exceptfds, timeout));
}

ssize_t Sockets::Send(int sockfd,
                      const void* buf,
                      size_t len,
                      int flags) const {
  return HANDLE_EINTR(send(sockfd, buf, len, flags));
}

ssize_t Sockets::SendTo(int sockfd,
                        const void* buf,
                        size_t len,
                        int flags,
                        const struct sockaddr* dest_addr,
                        socklen_t addrlen) const {
  return HANDLE_EINTR(sendto(sockfd, buf, len, flags, dest_addr, addrlen));
}

int Sockets::SetNonBlocking(int sockfd) const {
  return HANDLE_EINTR(
      fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL) | O_NONBLOCK));
}

int Sockets::SetReceiveBuffer(int sockfd, int size) const {
  // Note: kernel will set buffer to 2*size to allow for struct skbuff overhead
  return setsockopt(sockfd, SOL_SOCKET, SO_RCVBUFFORCE, &size, sizeof(size));
}

int Sockets::ShutDown(int sockfd, int how) const {
  return HANDLE_EINTR(shutdown(sockfd, how));
}

int Sockets::Socket(int domain, int type, int protocol) const {
  return socket(domain, type, protocol);
}

ScopedSocketCloser::ScopedSocketCloser(Sockets* sockets, int fd)
    : sockets_(sockets), fd_(fd) {}

ScopedSocketCloser::~ScopedSocketCloser() {
  sockets_->Close(fd_);
  fd_ = Sockets::kInvalidFileDescriptor;
}

int ScopedSocketCloser::Release() {
  int fd = fd_;
  fd_ = Sockets::kInvalidFileDescriptor;
  return fd;
}

}  // namespace shill
