//===-- RNBSocket.cpp -------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  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;
}
