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

#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#endif

#include "nacl_io/host_resolver.h"

#include <assert.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#include "nacl_io/kernel_proxy.h"
#include "nacl_io/log.h"
#include "nacl_io/ossocket.h"
#include "nacl_io/pepper_interface.h"

#ifdef PROVIDES_SOCKET_API

namespace {

void HintsToPPHints(const addrinfo* hints, PP_HostResolver_Hint* pp_hints) {
  memset(pp_hints, 0, sizeof(*pp_hints));

  if (hints->ai_family == AF_INET)
    pp_hints->family = PP_NETADDRESS_FAMILY_IPV4;
  else if (hints->ai_family == AF_INET6)
    pp_hints->family = PP_NETADDRESS_FAMILY_IPV6;

  if (hints->ai_flags & AI_CANONNAME)
    pp_hints->flags = PP_HOSTRESOLVER_FLAG_CANONNAME;
}

void CreateAddrInfo(const addrinfo* hints,
                    struct sockaddr* addr,
                    const char* name,
                    addrinfo** list_start,
                    addrinfo** list_end) {
  addrinfo* ai = static_cast<addrinfo*>(malloc(sizeof(addrinfo)));
  memset(ai, 0, sizeof(*ai));

  if (hints && hints->ai_socktype)
    ai->ai_socktype = hints->ai_socktype;
  else
    ai->ai_socktype = SOCK_STREAM;

  if (hints && hints->ai_protocol)
    ai->ai_protocol = hints->ai_protocol;

  if (name)
    ai->ai_canonname = strdup(name);

  switch (addr->sa_family) {
    case AF_INET6: {
      sockaddr_in6* in =
          static_cast<sockaddr_in6*>(malloc(sizeof(sockaddr_in6)));
      *in = *(sockaddr_in6*)addr;
      ai->ai_family = AF_INET6;
      ai->ai_addr = reinterpret_cast<sockaddr*>(in);
      ai->ai_addrlen = sizeof(*in);
      break;
    }
    case AF_INET: {
      sockaddr_in* in = static_cast<sockaddr_in*>(malloc(sizeof(sockaddr_in)));
      *in = *(sockaddr_in*)addr;
      ai->ai_family = AF_INET;
      ai->ai_addr = reinterpret_cast<sockaddr*>(in);
      ai->ai_addrlen = sizeof(*in);
      break;
    }
    default:
      assert(0);
      return;
  }

  if (*list_start == NULL) {
    *list_start = ai;
    *list_end = ai;
    return;
  }

  (*list_end)->ai_next = ai;
  *list_end = ai;
}

}  // namespace

namespace nacl_io {

HostResolver::HostResolver() : hostent_(), ppapi_(NULL) {
}

HostResolver::~HostResolver() {
  hostent_cleanup();
}

void HostResolver::Init(PepperInterface* ppapi) {
  ppapi_ = ppapi;
}

struct hostent* HostResolver::gethostbyname(const char* name) {
  h_errno = NETDB_INTERNAL;

  struct addrinfo* ai;
  struct addrinfo hints;
  memset(&hints, 0, sizeof(hints));
  hints.ai_flags = AI_CANONNAME;
  hints.ai_family = AF_INET;
  int err = getaddrinfo(name, NULL, &hints, &ai);
  if (err) {
    switch (err) {
      case EAI_SYSTEM:
        h_errno = NO_RECOVERY;
        break;
      case EAI_NONAME:
        h_errno = HOST_NOT_FOUND;
        break;
      default:
        h_errno = NETDB_INTERNAL;
        break;
    }
    return NULL;
  }

  // We use a single hostent struct for all calls to to gethostbyname
  // (as explicitly permitted by the spec - gethostbyname is NOT supposed to
  // be threadsafe!).  However by using a lock around all the global data
  // manipulation we can at least ensure that the call doesn't crash.
  AUTO_LOCK(gethostbyname_lock_);

  // The first thing we do is free any malloced data left over from
  // the last call.
  hostent_cleanup();

  switch (ai->ai_family) {
    case AF_INET:
      hostent_.h_addrtype = AF_INET;
      hostent_.h_length = sizeof(in_addr);
      break;
    case AF_INET6:
      hostent_.h_addrtype = AF_INET6;
      hostent_.h_length = sizeof(in6_addr);
      break;
    default:
      return NULL;
  }

  if (ai->ai_canonname != NULL)
    hostent_.h_name = strdup(ai->ai_canonname);
  else
    hostent_.h_name = strdup(name);

  // Aliases aren't supported at the moment, so we just make an empty list.
  hostent_.h_aliases = static_cast<char**>(malloc(sizeof(char*)));
  if (NULL == hostent_.h_aliases)
    return NULL;
  hostent_.h_aliases[0] = NULL;

  // Count number of address in list
  int num_addresses = 0;
  struct addrinfo* current = ai;
  while (current != NULL) {
    // Only count address that have the same type as first address
    if (current->ai_family == hostent_.h_addrtype)
      num_addresses++;
    current = current->ai_next;
  }

  // Allocate address list
  hostent_.h_addr_list = static_cast<char**>(calloc(num_addresses + 1,
                                                    sizeof(char*)));
  if (NULL == hostent_.h_addr_list)
    return NULL;

  // Copy all addresses of the relevant family.
  current = ai;
  char** hostent_addr = hostent_.h_addr_list;
  while (current != NULL) {
    if (current->ai_family != hostent_.h_addrtype) {
      current = current->ai_next;
      continue;
    }
    *hostent_addr = static_cast<char*>(malloc(hostent_.h_length));
    switch (current->ai_family) {
      case AF_INET: {
        sockaddr_in* in = reinterpret_cast<sockaddr_in*>(current->ai_addr);
        memcpy(*hostent_addr, &in->sin_addr.s_addr, hostent_.h_length);
        break;
      }
      case AF_INET6: {
        sockaddr_in6* in6 = reinterpret_cast<sockaddr_in6*>(current->ai_addr);
        memcpy(*hostent_addr, &in6->sin6_addr.s6_addr, hostent_.h_length);
        break;
      }
    }
    current = current->ai_next;
    hostent_addr++;
  }

  freeaddrinfo(ai);

#if !defined(h_addr)
  // Copy element zero of h_addr_list to h_addr when h_addr is not defined
  // as in some libc's h_addr may be a separate member instead of a macro.
  hostent_.h_addr = hostent_.h_addr_list[0];
#endif

  return &hostent_;
}

void HostResolver::freeaddrinfo(struct addrinfo* res) {
  while (res) {
    struct addrinfo* cur = res;
    res = res->ai_next;
    free(cur->ai_addr);
    free(cur->ai_canonname);
    free(cur);
  }
}

int HostResolver::getnameinfo(const struct sockaddr *sa,
                              socklen_t salen,
                              char *host,
                              size_t hostlen,
                              char *serv,
                              size_t servlen,
                              int flags) {
  return ENOSYS;
}

int HostResolver::getaddrinfo(const char* node,
                              const char* service,
                              const struct addrinfo* hints_in,
                              struct addrinfo** result) {
  *result = NULL;
  struct addrinfo* end = NULL;

  if (node == NULL && service == NULL) {
    LOG_TRACE("node and service are NULL.");
    return EAI_NONAME;
  }

  // Check the service name (port).  Currently we only handle numeric
  // services.
  long port = 0;
  if (service != NULL) {
    char* cp;
    port = strtol(service, &cp, 10);
    if (port >= 0 && port <= UINT16_MAX && *cp == '\0') {
      port = htons(port);
    } else {
      LOG_TRACE("Service \"%s\" not supported.", service);
      return EAI_SERVICE;
    }
  }

  struct addrinfo default_hints;
  memset(&default_hints, 0, sizeof(default_hints));
  const struct addrinfo* hints = hints_in ? hints_in : &default_hints;

  // Verify values passed in hints structure
  switch (hints->ai_family) {
    case AF_INET6:
    case AF_INET:
    case AF_UNSPEC:
      break;
    default:
      LOG_TRACE("Unknown family: %d.", hints->ai_family);
      return EAI_FAMILY;
  }

  struct sockaddr_in addr_in;
  memset(&addr_in, 0, sizeof(addr_in));
  addr_in.sin_family = AF_INET;
  addr_in.sin_port = port;

  struct sockaddr_in6 addr_in6;
  memset(&addr_in6, 0, sizeof(addr_in6));
  addr_in6.sin6_family = AF_INET6;
  addr_in6.sin6_port = port;

  if (node) {
    // Handle numeric node name.
    if (hints->ai_family == AF_INET || hints->ai_family == AF_UNSPEC) {
      in_addr in;
      if (inet_pton(AF_INET, node, &in)) {
        addr_in.sin_addr = in;
        CreateAddrInfo(hints, (sockaddr*)&addr_in, node, result, &end);
        return 0;
      }
    }

    if (hints->ai_family == AF_INET6 || hints->ai_family == AF_UNSPEC) {
      in6_addr in6;
      if (inet_pton(AF_INET6, node, &in6)) {
        addr_in6.sin6_addr = in6;
        CreateAddrInfo(hints, (sockaddr*)&addr_in6, node, result, &end);
        return 0;
      }
    }
  }

  // Handle AI_PASSIVE (used for listening sockets, e.g. INADDR_ANY)
  if (node == NULL && (hints->ai_flags & AI_PASSIVE)) {
    if (hints->ai_family == AF_INET6 || hints->ai_family == AF_UNSPEC) {
      const in6_addr in6addr_any = IN6ADDR_ANY_INIT;
      memcpy(&addr_in6.sin6_addr.s6_addr, &in6addr_any, sizeof(in6addr_any));
      CreateAddrInfo(hints, (sockaddr*)&addr_in6, NULL, result, &end);
    }

    if (hints->ai_family == AF_INET || hints->ai_family == AF_UNSPEC) {
      addr_in.sin_addr.s_addr = INADDR_ANY;
      CreateAddrInfo(hints, (sockaddr*)&addr_in, NULL, result, &end);
    }
    return 0;
  }

  if (NULL == ppapi_) {
    LOG_ERROR("ppapi_ is NULL.");
    return EAI_SYSTEM;
  }

  // Use PPAPI interface to resolve nodename
  HostResolverInterface* resolver_iface = ppapi_->GetHostResolverInterface();
  VarInterface* var_iface = ppapi_->GetVarInterface();
  NetAddressInterface* netaddr_iface = ppapi_->GetNetAddressInterface();

  if (!(resolver_iface && var_iface && netaddr_iface)) {
    LOG_ERROR("Got NULL interface(s): %s%s%s",
              resolver_iface ? "" : "HostResolver ",
              var_iface ? "" : "Var ",
              netaddr_iface ? "" : "NetAddress");
    return EAI_SYSTEM;
  }

  ScopedResource scoped_resolver(ppapi_,
                                 resolver_iface->Create(ppapi_->GetInstance()));
  PP_Resource resolver = scoped_resolver.pp_resource();

  struct PP_HostResolver_Hint pp_hints;
  HintsToPPHints(hints, &pp_hints);

  int err = resolver_iface->Resolve(resolver,
                                    node,
                                    0,
                                    &pp_hints,
                                    PP_BlockUntilComplete());
  if (err) {
    switch (err) {
      case PP_ERROR_NOACCESS:
        return EAI_SYSTEM;
      case PP_ERROR_NAME_NOT_RESOLVED:
        return EAI_NONAME;
      default:
        return EAI_SYSTEM;
    }
  }

  char* canon_name = NULL;
  if (hints->ai_flags & AI_CANONNAME) {
    PP_Var name_var = resolver_iface->GetCanonicalName(resolver);
    if (PP_VARTYPE_STRING == name_var.type) {
      uint32_t len = 0;
      const char* tmp = var_iface->VarToUtf8(name_var, &len);
      // For some reason GetCanonicalName alway returns an empty
      // string so this condition is never true.
      // TODO(sbc): investigate this issue with PPAPI team.
      if (len > 0) {
        // Copy and NULL-terminate the UTF8 string var.
        canon_name = static_cast<char*>(malloc(len + 1));
        strncpy(canon_name, tmp, len);
        canon_name[len] = '\0';
      }
    }
    if (!canon_name)
      canon_name = strdup(node);
    var_iface->Release(name_var);
  }

  int num_addresses = resolver_iface->GetNetAddressCount(resolver);
  if (0 == num_addresses)
    return EAI_NODATA;

  // Convert address to sockaddr struct.
  for (int i = 0; i < num_addresses; i++) {
    ScopedResource addr(ppapi_, resolver_iface->GetNetAddress(resolver, i));
    PP_Resource resource = addr.pp_resource();
    assert(resource != 0);
    assert(PP_ToBool(netaddr_iface->IsNetAddress(resource)));
    struct sockaddr* sockaddr = NULL;
    switch (netaddr_iface->GetFamily(resource)) {
      case PP_NETADDRESS_FAMILY_IPV4: {
        struct PP_NetAddress_IPv4 pp_addr;
        if (!netaddr_iface->DescribeAsIPv4Address(resource, &pp_addr)) {
          assert(false);
          break;
        }
        memcpy(&addr_in.sin_addr.s_addr, pp_addr.addr, sizeof(in_addr_t));
        sockaddr = (struct sockaddr*)&addr_in;
        break;
      }
      case PP_NETADDRESS_FAMILY_IPV6: {
        struct PP_NetAddress_IPv6 pp_addr;
        if (!netaddr_iface->DescribeAsIPv6Address(resource, &pp_addr)) {
          assert(false);
          break;
        }
        memcpy(&addr_in6.sin6_addr.s6_addr, pp_addr.addr, sizeof(in6_addr));
        sockaddr = (struct sockaddr*)&addr_in6;
        break;
      }
      default:
        return EAI_SYSTEM;
    }

    if (sockaddr != NULL)
      CreateAddrInfo(hints, sockaddr, canon_name, result, &end);

    if (canon_name) {
      free(canon_name);
      canon_name = NULL;
    }
  }

  return 0;
}

// Frees all of the deep pointers in a hostent struct. Called between uses of
// gethostbyname, and when the kernel_proxy object is destroyed.
void HostResolver::hostent_cleanup() {
  if (NULL != hostent_.h_name) {
    free(hostent_.h_name);
  }
  if (NULL != hostent_.h_aliases) {
    for (int i = 0; NULL != hostent_.h_aliases[i]; i++) {
      free(hostent_.h_aliases[i]);
    }
    free(hostent_.h_aliases);
  }
  if (NULL != hostent_.h_addr_list) {
    for (int i = 0; NULL != hostent_.h_addr_list[i]; i++) {
      free(hostent_.h_addr_list[i]);
    }
    free(hostent_.h_addr_list);
  }
  hostent_.h_name = NULL;
  hostent_.h_aliases = NULL;
  hostent_.h_addr_list = NULL;
#if !defined(h_addr)
  // Initialize h_addr separately in the case where it is not a macro.
  hostent_.h_addr = NULL;
#endif
}

}  // namespace nacl_io

#endif  // PROVIDES_SOCKET_API
