//===-- RNBSocket.cpp -------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
//  Created by Greg Clayton on 12/12/07.
//
//===----------------------------------------------------------------------===//

#include "RNBSocket.h"
#include "DNBError.h"
#include "DNBLog.h"
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include <map>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <sys/event.h>
#include <termios.h>
#include <vector>

#include "lldb/Host/SocketAddress.h"

#ifdef WITH_LOCKDOWN
#include "lockdown.h"
#endif

/* Once we have a RNBSocket object with a port # specified,
   this function is called to wait for an incoming connection.
   This function blocks while waiting for that connection.  */

bool ResolveIPV4HostName(const char *hostname, in_addr_t &addr) {
  if (hostname == NULL || hostname[0] == '\0' ||
      strcmp(hostname, "localhost") == 0 ||
      strcmp(hostname, "127.0.0.1") == 0) {
    addr = htonl(INADDR_LOOPBACK);
    return true;
  } else if (strcmp(hostname, "*") == 0) {
    addr = htonl(INADDR_ANY);
    return true;
  } else {
    // See if an IP address was specified as numbers
    int inet_pton_result = ::inet_pton(AF_INET, hostname, &addr);

    if (inet_pton_result == 1)
      return true;

    struct hostent *host_entry = gethostbyname(hostname);
    if (host_entry) {
      std::string ip_str(
          ::inet_ntoa(*(struct in_addr *)*host_entry->h_addr_list));
      inet_pton_result = ::inet_pton(AF_INET, ip_str.c_str(), &addr);
      if (inet_pton_result == 1)
        return true;
    }
  }
  return false;
}

rnb_err_t RNBSocket::Listen(const char *listen_host, uint16_t port,
                            PortBoundCallback callback,
                            const void *callback_baton) {
  // DNBLogThreadedIf(LOG_RNB_COMM, "%8u RNBSocket::%s called",
  // (uint32_t)m_timer.ElapsedMicroSeconds(true), __FUNCTION__);
  // Disconnect without saving errno
  Disconnect(false);

  DNBError err;
  int queue_id = kqueue();
  if (queue_id < 0) {
    err.SetError(errno, DNBError::MachKernel);
    err.LogThreaded("error: failed to create kqueue.");
    return rnb_err;
  }

  bool any_addr = (strcmp(listen_host, "*") == 0);

  // If the user wants to allow connections from any address we should create
  // sockets on all families that can resolve localhost. This will allow us to
  // listen for IPv6 and IPv4 connections from all addresses if those interfaces
  // are available.
  const char *local_addr = any_addr ? "localhost" : listen_host;

  std::map<int, lldb_private::SocketAddress> sockets;
  auto addresses = lldb_private::SocketAddress::GetAddressInfo(
      local_addr, NULL, AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP);

  for (auto address : addresses) {
    int sock_fd = ::socket(address.GetFamily(), SOCK_STREAM, IPPROTO_TCP);
    if (sock_fd == -1)
      continue;

    SetSocketOption(sock_fd, SOL_SOCKET, SO_REUSEADDR, 1);

    lldb_private::SocketAddress bind_address = address;

    if(any_addr || !bind_address.IsLocalhost())
      bind_address.SetToAnyAddress(bind_address.GetFamily(), port);
    else
      bind_address.SetPort(port);

    int error =
        ::bind(sock_fd, &bind_address.sockaddr(), bind_address.GetLength());
    if (error == -1) {
      ClosePort(sock_fd, false);
      continue;
    }

    error = ::listen(sock_fd, 5);
    if (error == -1) {
      ClosePort(sock_fd, false);
      continue;
    }

    // We were asked to listen on port zero which means we must now read the
    // actual port that was given to us as port zero is a special code for "find
    // an open port for me". This will only execute on the first socket created,
    // subesquent sockets will reuse this port number.
    if (port == 0) {
      socklen_t sa_len = address.GetLength();
      if (getsockname(sock_fd, &address.sockaddr(), &sa_len) == 0)
        port = address.GetPort();
    }

    sockets[sock_fd] = address;
  }

  if (sockets.size() == 0) {
    err.SetError(errno, DNBError::POSIX);
    err.LogThreaded("::listen or ::bind failed");
    return rnb_err;
  }

  if (callback)
    callback(callback_baton, port);

  std::vector<struct kevent> events;
  events.resize(sockets.size());
  int i = 0;
  for (auto socket : sockets) {
    EV_SET(&events[i++], socket.first, EVFILT_READ, EV_ADD, 0, 0, 0);
  }

  bool accept_connection = false;

  // Loop until we are happy with our connection
  while (!accept_connection) {

    struct kevent event_list[4];
    int num_events =
        kevent(queue_id, events.data(), events.size(), event_list, 4, NULL);

    if (num_events < 0) {
      err.SetError(errno, DNBError::MachKernel);
      err.LogThreaded("error: kevent() failed.");
    }

    for (int i = 0; i < num_events; ++i) {
      auto sock_fd = event_list[i].ident;
      auto socket_pair = sockets.find(sock_fd);
      if (socket_pair == sockets.end())
        continue;

      lldb_private::SocketAddress &addr_in = socket_pair->second;
      lldb_private::SocketAddress accept_addr;
      socklen_t sa_len = accept_addr.GetMaxLength();
      m_fd = ::accept(sock_fd, &accept_addr.sockaddr(), &sa_len);

      if (m_fd == -1) {
        err.SetError(errno, DNBError::POSIX);
        err.LogThreaded("error: Socket accept failed.");
      }

      if (addr_in.IsAnyAddr())
        accept_connection = true;
      else {
        if (accept_addr == addr_in)
          accept_connection = true;
        else {
          ::close(m_fd);
          m_fd = -1;
          ::fprintf(
              stderr,
              "error: rejecting incoming connection from %s (expecting %s)\n",
              accept_addr.GetIPAddress().c_str(),
              addr_in.GetIPAddress().c_str());
          DNBLogThreaded("error: rejecting connection from %s (expecting %s)\n",
                         accept_addr.GetIPAddress().c_str(),
                         addr_in.GetIPAddress().c_str());
          err.Clear();
        }
      }
    }
    if (err.Fail())
      break;
  }
  for (auto socket : sockets) {
    int ListenFd = socket.first;
    ClosePort(ListenFd, false);
  }

  if (err.Fail())
    return rnb_err;

  // Keep our TCP packets coming without any delays.
  SetSocketOption(m_fd, IPPROTO_TCP, TCP_NODELAY, 1);

  return rnb_success;
}

rnb_err_t RNBSocket::Connect(const char *host, uint16_t port) {
  auto result = rnb_err;
  Disconnect(false);

  auto addresses = lldb_private::SocketAddress::GetAddressInfo(
      host, NULL, AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP);

  for (auto address : addresses) {
    m_fd = ::socket(address.GetFamily(), SOCK_STREAM, IPPROTO_TCP);
    if (m_fd == -1)
      continue;

    // Enable local address reuse
    SetSocketOption(m_fd, SOL_SOCKET, SO_REUSEADDR, 1);

    address.SetPort(port);

    if (-1 == ::connect(m_fd, &address.sockaddr(), address.GetLength())) {
      Disconnect(false);
      continue;
    }
    SetSocketOption(m_fd, IPPROTO_TCP, TCP_NODELAY, 1);

    result = rnb_success;
    break;
  }
  return result;
}

rnb_err_t RNBSocket::useFD(int fd) {
  if (fd < 0) {
    DNBLogThreadedIf(LOG_RNB_COMM, "Bad file descriptor passed in.");
    return rnb_err;
  }

  m_fd = fd;
  return rnb_success;
}

#ifdef WITH_LOCKDOWN
rnb_err_t RNBSocket::ConnectToService() {
  DNBLog("Connecting to com.apple.%s service...", DEBUGSERVER_PROGRAM_NAME);
  // Disconnect from any previous connections
  Disconnect(false);
  if (::secure_lockdown_checkin(&m_ld_conn, NULL, NULL) != kLDESuccess) {
    DNBLogThreadedIf(LOG_RNB_COMM,
                     "::secure_lockdown_checkin(&m_fd, NULL, NULL) failed");
    m_fd = -1;
    return rnb_not_connected;
  }
  m_fd = ::lockdown_get_socket(m_ld_conn);
  if (m_fd == -1) {
    DNBLogThreadedIf(LOG_RNB_COMM, "::lockdown_get_socket() failed");
    return rnb_not_connected;
  }
  m_fd_from_lockdown = true;
  return rnb_success;
}
#endif

rnb_err_t RNBSocket::OpenFile(const char *path) {
  DNBError err;
  m_fd = open(path, O_RDWR);
  if (m_fd == -1) {
    err.SetError(errno, DNBError::POSIX);
    err.LogThreaded("can't open file '%s'", path);
    return rnb_not_connected;
  } else {
    struct termios stdin_termios;

    if (::tcgetattr(m_fd, &stdin_termios) == 0) {
      stdin_termios.c_lflag &= ~ECHO;   // Turn off echoing
      stdin_termios.c_lflag &= ~ICANON; // Get one char at a time
      ::tcsetattr(m_fd, TCSANOW, &stdin_termios);
    }
  }
  return rnb_success;
}

int RNBSocket::SetSocketOption(int fd, int level, int option_name,
                               int option_value) {
  return ::setsockopt(fd, level, option_name, &option_value,
                      sizeof(option_value));
}

rnb_err_t RNBSocket::Disconnect(bool save_errno) {
#ifdef WITH_LOCKDOWN
  if (m_fd_from_lockdown) {
    m_fd_from_lockdown = false;
    m_fd = -1;
    lockdown_disconnect(m_ld_conn);
    return rnb_success;
  }
#endif
  return ClosePort(m_fd, save_errno);
}

rnb_err_t RNBSocket::Read(std::string &p) {
  char buf[1024];
  p.clear();

  // Note that BUF is on the stack so we must be careful to keep any
  // writes to BUF from overflowing or we'll have security issues.

  if (m_fd == -1)
    return rnb_err;

  // DNBLogThreadedIf(LOG_RNB_COMM, "%8u RNBSocket::%s calling read()",
  // (uint32_t)m_timer.ElapsedMicroSeconds(true), __FUNCTION__);
  DNBError err;
  ssize_t bytesread = read(m_fd, buf, sizeof(buf));
  if (bytesread <= 0)
    err.SetError(errno, DNBError::POSIX);
  else
    p.append(buf, bytesread);

  if (err.Fail() || DNBLogCheckLogBit(LOG_RNB_COMM))
    err.LogThreaded("::read ( %i, %p, %llu ) => %i", m_fd, buf, sizeof(buf),
                    (uint64_t)bytesread);

  // Our port went away - we have to mark this so IsConnected will return the
  // truth.
  if (bytesread == 0) {
    m_fd = -1;
    return rnb_not_connected;
  } else if (bytesread == -1) {
    m_fd = -1;
    return rnb_err;
  }
  // Strip spaces from the end of the buffer
  while (!p.empty() && isspace(p[p.size() - 1]))
    p.erase(p.size() - 1);

  // Most data in the debugserver packets valid printable characters...
  DNBLogThreadedIf(LOG_RNB_COMM, "read: %s", p.c_str());
  return rnb_success;
}

rnb_err_t RNBSocket::Write(const void *buffer, size_t length) {
  if (m_fd == -1)
    return rnb_err;

  DNBError err;
  ssize_t bytessent = write(m_fd, buffer, length);
  if (bytessent < 0)
    err.SetError(errno, DNBError::POSIX);

  if (err.Fail() || DNBLogCheckLogBit(LOG_RNB_COMM))
    err.LogThreaded("::write ( socket = %i, buffer = %p, length = %llu) => %i",
                    m_fd, buffer, length, (uint64_t)bytessent);

  if (bytessent < 0)
    return rnb_err;

  if ((size_t)bytessent != length)
    return rnb_err;

  DNBLogThreadedIf(
      LOG_RNB_PACKETS, "putpkt: %*s", (int)length,
      (const char *)
          buffer); // All data is string based in debugserver, so this is safe
  DNBLogThreadedIf(LOG_RNB_COMM, "sent: %*s", (int)length,
                   (const char *)buffer);

  return rnb_success;
}

rnb_err_t RNBSocket::ClosePort(int &fd, bool save_errno) {
  int close_err = 0;
  if (fd > 0) {
    errno = 0;
    close_err = close(fd);
    fd = -1;
  }
  return close_err != 0 ? rnb_err : rnb_success;
}
