// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

#define CARES_STATICLIB
#include "ares.h"
#include "async_wrap-inl.h"
#include "env-inl.h"
#include "memory_tracker-inl.h"
#include "node.h"
#include "req_wrap-inl.h"
#include "util-inl.h"
#include "uv.h"

#include <cerrno>
#include <cstring>
#include <memory>
#include <vector>
#include <unordered_set>

#ifdef __POSIX__
# include <netdb.h>
#endif  // __POSIX__

#if defined(__ANDROID__) || \
    defined(__MINGW32__) || \
    defined(__OpenBSD__) || \
    defined(_MSC_VER)

# include <nameser.h>
#else
# include <arpa/nameser.h>
#endif

#if defined(__OpenBSD__)
# define AI_V4MAPPED 0
#endif

namespace node {
namespace cares_wrap {

using v8::Array;
using v8::Context;
using v8::EscapableHandleScope;
using v8::FunctionCallbackInfo;
using v8::FunctionTemplate;
using v8::HandleScope;
using v8::Int32;
using v8::Integer;
using v8::Isolate;
using v8::Local;
using v8::Null;
using v8::Object;
using v8::String;
using v8::Value;

namespace {

Mutex ares_library_mutex;

inline uint16_t cares_get_16bit(const unsigned char* p) {
  return static_cast<uint32_t>(p[0] << 8U) | (static_cast<uint32_t>(p[1]));
}

inline uint32_t cares_get_32bit(const unsigned char* p) {
  return static_cast<uint32_t>(p[0] << 24U) |
         static_cast<uint32_t>(p[1] << 16U) |
         static_cast<uint32_t>(p[2] << 8U) |
         static_cast<uint32_t>(p[3]);
}

const int ns_t_cname_or_a = -1;

#define DNS_ESETSRVPENDING -1000
inline const char* ToErrorCodeString(int status) {
  switch (status) {
#define V(code) case ARES_##code: return #code;
    V(EADDRGETNETWORKPARAMS)
    V(EBADFAMILY)
    V(EBADFLAGS)
    V(EBADHINTS)
    V(EBADNAME)
    V(EBADQUERY)
    V(EBADRESP)
    V(EBADSTR)
    V(ECANCELLED)
    V(ECONNREFUSED)
    V(EDESTRUCTION)
    V(EFILE)
    V(EFORMERR)
    V(ELOADIPHLPAPI)
    V(ENODATA)
    V(ENOMEM)
    V(ENONAME)
    V(ENOTFOUND)
    V(ENOTIMP)
    V(ENOTINITIALIZED)
    V(EOF)
    V(EREFUSED)
    V(ESERVFAIL)
    V(ETIMEOUT)
#undef V
  }

  return "UNKNOWN_ARES_ERROR";
}

class ChannelWrap;

struct node_ares_task : public MemoryRetainer {
  ChannelWrap* channel;
  ares_socket_t sock;
  uv_poll_t poll_watcher;

  inline void MemoryInfo(MemoryTracker* tracker) const override;
  SET_MEMORY_INFO_NAME(node_ares_task)
  SET_SELF_SIZE(node_ares_task)
};

struct TaskHash {
  size_t operator()(node_ares_task* a) const {
    return std::hash<ares_socket_t>()(a->sock);
  }
};

struct TaskEqual {
  inline bool operator()(node_ares_task* a, node_ares_task* b) const {
    return a->sock == b->sock;
  }
};

using node_ares_task_list =
    std::unordered_set<node_ares_task*, TaskHash, TaskEqual>;

class ChannelWrap : public AsyncWrap {
 public:
  ChannelWrap(Environment* env, Local<Object> object, int timeout);
  ~ChannelWrap() override;

  static void New(const FunctionCallbackInfo<Value>& args);

  void Setup();
  void EnsureServers();
  void StartTimer();
  void CloseTimer();

  void ModifyActivityQueryCount(int count);

  inline uv_timer_t* timer_handle() { return timer_handle_; }
  inline ares_channel cares_channel() { return channel_; }
  inline void set_query_last_ok(bool ok) { query_last_ok_ = ok; }
  inline void set_is_servers_default(bool is_default) {
    is_servers_default_ = is_default;
  }
  inline int active_query_count() { return active_query_count_; }
  inline node_ares_task_list* task_list() { return &task_list_; }

  void MemoryInfo(MemoryTracker* tracker) const override {
    if (timer_handle_ != nullptr)
      tracker->TrackField("timer_handle", *timer_handle_);
    tracker->TrackField("task_list", task_list_, "node_ares_task_list");
  }

  SET_MEMORY_INFO_NAME(ChannelWrap)
  SET_SELF_SIZE(ChannelWrap)

  static void AresTimeout(uv_timer_t* handle);

 private:
  uv_timer_t* timer_handle_;
  ares_channel channel_;
  bool query_last_ok_;
  bool is_servers_default_;
  bool library_inited_;
  int timeout_;
  int active_query_count_;
  node_ares_task_list task_list_;
};

ChannelWrap::ChannelWrap(Environment* env,
                         Local<Object> object,
                         int timeout)
  : AsyncWrap(env, object, PROVIDER_DNSCHANNEL),
    timer_handle_(nullptr),
    channel_(nullptr),
    query_last_ok_(true),
    is_servers_default_(true),
    library_inited_(false),
    timeout_(timeout),
    active_query_count_(0) {
  MakeWeak();

  Setup();
}

void ChannelWrap::New(const FunctionCallbackInfo<Value>& args) {
  CHECK(args.IsConstructCall());
  CHECK_EQ(args.Length(), 1);
  CHECK(args[0]->IsInt32());
  const int timeout = args[0].As<Int32>()->Value();
  Environment* env = Environment::GetCurrent(args);
  new ChannelWrap(env, args.This(), timeout);
}

class GetAddrInfoReqWrap : public ReqWrap<uv_getaddrinfo_t> {
 public:
  GetAddrInfoReqWrap(Environment* env,
                     Local<Object> req_wrap_obj,
                     bool verbatim);

  SET_NO_MEMORY_INFO()
  SET_MEMORY_INFO_NAME(GetAddrInfoReqWrap)
  SET_SELF_SIZE(GetAddrInfoReqWrap)

  bool verbatim() const { return verbatim_; }

 private:
  const bool verbatim_;
};

GetAddrInfoReqWrap::GetAddrInfoReqWrap(Environment* env,
                                       Local<Object> req_wrap_obj,
                                       bool verbatim)
    : ReqWrap(env, req_wrap_obj, AsyncWrap::PROVIDER_GETADDRINFOREQWRAP)
    , verbatim_(verbatim) {
}


class GetNameInfoReqWrap : public ReqWrap<uv_getnameinfo_t> {
 public:
  GetNameInfoReqWrap(Environment* env, Local<Object> req_wrap_obj);

  SET_NO_MEMORY_INFO()
  SET_MEMORY_INFO_NAME(GetNameInfoReqWrap)
  SET_SELF_SIZE(GetNameInfoReqWrap)
};

GetNameInfoReqWrap::GetNameInfoReqWrap(Environment* env,
                                       Local<Object> req_wrap_obj)
    : ReqWrap(env, req_wrap_obj, AsyncWrap::PROVIDER_GETNAMEINFOREQWRAP) {
}


/* This is called once per second by loop->timer. It is used to constantly */
/* call back into c-ares for possibly processing timeouts. */
void ChannelWrap::AresTimeout(uv_timer_t* handle) {
  ChannelWrap* channel = static_cast<ChannelWrap*>(handle->data);
  CHECK_EQ(channel->timer_handle(), handle);
  CHECK_EQ(false, channel->task_list()->empty());
  ares_process_fd(channel->cares_channel(), ARES_SOCKET_BAD, ARES_SOCKET_BAD);
}


void ares_poll_cb(uv_poll_t* watcher, int status, int events) {
  node_ares_task* task = ContainerOf(&node_ares_task::poll_watcher, watcher);
  ChannelWrap* channel = task->channel;

  /* Reset the idle timer */
  uv_timer_again(channel->timer_handle());

  if (status < 0) {
    /* An error happened. Just pretend that the socket is both readable and */
    /* writable. */
    ares_process_fd(channel->cares_channel(), task->sock, task->sock);
    return;
  }

  /* Process DNS responses */
  ares_process_fd(channel->cares_channel(),
                  events & UV_READABLE ? task->sock : ARES_SOCKET_BAD,
                  events & UV_WRITABLE ? task->sock : ARES_SOCKET_BAD);
}


void ares_poll_close_cb(uv_poll_t* watcher) {
  node_ares_task* task = ContainerOf(&node_ares_task::poll_watcher, watcher);
  delete task;
}

void node_ares_task::MemoryInfo(MemoryTracker* tracker) const {
  tracker->TrackField("channel", channel);
}

/* Allocates and returns a new node_ares_task */
node_ares_task* ares_task_create(ChannelWrap* channel, ares_socket_t sock) {
  auto task = new node_ares_task();

  task->channel = channel;
  task->sock = sock;

  if (uv_poll_init_socket(channel->env()->event_loop(),
                          &task->poll_watcher, sock) < 0) {
    /* This should never happen. */
    delete task;
    return nullptr;
  }

  return task;
}


/* Callback from ares when socket operation is started */
void ares_sockstate_cb(void* data,
                       ares_socket_t sock,
                       int read,
                       int write) {
  ChannelWrap* channel = static_cast<ChannelWrap*>(data);
  node_ares_task* task;

  node_ares_task lookup_task;
  lookup_task.sock = sock;
  auto it = channel->task_list()->find(&lookup_task);

  task = (it == channel->task_list()->end()) ? nullptr : *it;

  if (read || write) {
    if (!task) {
      /* New socket */
      channel->StartTimer();

      task = ares_task_create(channel, sock);
      if (task == nullptr) {
        /* This should never happen unless we're out of memory or something */
        /* is seriously wrong. The socket won't be polled, but the query will */
        /* eventually time out. */
        return;
      }

      channel->task_list()->insert(task);
    }

    /* This should never fail. If it fails anyway, the query will eventually */
    /* time out. */
    uv_poll_start(&task->poll_watcher,
                  (read ? UV_READABLE : 0) | (write ? UV_WRITABLE : 0),
                  ares_poll_cb);

  } else {
    /* read == 0 and write == 0 this is c-ares's way of notifying us that */
    /* the socket is now closed. We must free the data associated with */
    /* socket. */
    CHECK(task &&
          "When an ares socket is closed we should have a handle for it");

    channel->task_list()->erase(it);
    channel->env()->CloseHandle(&task->poll_watcher, ares_poll_close_cb);

    if (channel->task_list()->empty()) {
      channel->CloseTimer();
    }
  }
}


Local<Array> HostentToNames(Environment* env,
                            struct hostent* host,
                            Local<Array> append_to = Local<Array>()) {
  EscapableHandleScope scope(env->isolate());
  auto context = env->context();
  bool append = !append_to.IsEmpty();
  Local<Array> names = append ? append_to : Array::New(env->isolate());
  size_t offset = names->Length();

  for (uint32_t i = 0; host->h_aliases[i] != nullptr; ++i) {
    Local<String> address = OneByteString(env->isolate(), host->h_aliases[i]);
    names->Set(context, i + offset, address).Check();
  }

  return append ? names : scope.Escape(names);
}

void safe_free_hostent(struct hostent* host) {
  int idx;

  if (host->h_addr_list != nullptr) {
    idx = 0;
    while (host->h_addr_list[idx]) {
      free(host->h_addr_list[idx++]);
    }
    free(host->h_addr_list);
    host->h_addr_list = nullptr;
  }

  if (host->h_aliases != nullptr) {
    idx = 0;
    while (host->h_aliases[idx]) {
      free(host->h_aliases[idx++]);
    }
    free(host->h_aliases);
    host->h_aliases = nullptr;
  }

  free(host->h_name);
  free(host);
}

void cares_wrap_hostent_cpy(struct hostent* dest, const struct hostent* src) {
  dest->h_addr_list = nullptr;
  dest->h_addrtype = 0;
  dest->h_aliases = nullptr;
  dest->h_length = 0;
  dest->h_name = nullptr;

  /* copy `h_name` */
  size_t name_size = strlen(src->h_name) + 1;
  dest->h_name = node::Malloc<char>(name_size);
  memcpy(dest->h_name, src->h_name, name_size);

  /* copy `h_aliases` */
  size_t alias_count;
  for (alias_count = 0;
      src->h_aliases[alias_count] != nullptr;
      alias_count++) {
  }

  dest->h_aliases = node::Malloc<char*>(alias_count + 1);
  for (size_t i = 0; i < alias_count; i++) {
    const size_t cur_alias_size = strlen(src->h_aliases[i]) + 1;
    dest->h_aliases[i] = node::Malloc(cur_alias_size);
    memcpy(dest->h_aliases[i], src->h_aliases[i], cur_alias_size);
  }
  dest->h_aliases[alias_count] = nullptr;

  /* copy `h_addr_list` */
  size_t list_count;
  for (list_count = 0;
      src->h_addr_list[list_count] != nullptr;
      list_count++) {
  }

  dest->h_addr_list = node::Malloc<char*>(list_count + 1);
  for (size_t i = 0; i < list_count; i++) {
    dest->h_addr_list[i] = node::Malloc(src->h_length);
    memcpy(dest->h_addr_list[i], src->h_addr_list[i], src->h_length);
  }
  dest->h_addr_list[list_count] = nullptr;

  /* work after work */
  dest->h_length = src->h_length;
  dest->h_addrtype = src->h_addrtype;
}

class QueryWrap;

void ChannelWrap::Setup() {
  struct ares_options options;
  memset(&options, 0, sizeof(options));
  options.flags = ARES_FLAG_NOCHECKRESP;
  options.sock_state_cb = ares_sockstate_cb;
  options.sock_state_cb_data = this;
  options.timeout = timeout_;

  int r;
  if (!library_inited_) {
    Mutex::ScopedLock lock(ares_library_mutex);
    // Multiple calls to ares_library_init() increase a reference counter,
    // so this is a no-op except for the first call to it.
    r = ares_library_init(ARES_LIB_INIT_ALL);
    if (r != ARES_SUCCESS)
      return env()->ThrowError(ToErrorCodeString(r));
  }

  /* We do the call to ares_init_option for caller. */
  const int optmask =
      ARES_OPT_FLAGS | ARES_OPT_TIMEOUTMS | ARES_OPT_SOCK_STATE_CB;
  r = ares_init_options(&channel_, &options, optmask);

  if (r != ARES_SUCCESS) {
    Mutex::ScopedLock lock(ares_library_mutex);
    ares_library_cleanup();
    return env()->ThrowError(ToErrorCodeString(r));
  }

  library_inited_ = true;
}

void ChannelWrap::StartTimer() {
  if (timer_handle_ == nullptr) {
    timer_handle_ = new uv_timer_t();
    timer_handle_->data = static_cast<void*>(this);
    uv_timer_init(env()->event_loop(), timer_handle_);
  } else if (uv_is_active(reinterpret_cast<uv_handle_t*>(timer_handle_))) {
    return;
  }
  int timeout = timeout_;
  if (timeout == 0) timeout = 1;
  if (timeout < 0 || timeout > 1000) timeout = 1000;
  uv_timer_start(timer_handle_, AresTimeout, timeout, timeout);
}

void ChannelWrap::CloseTimer() {
  if (timer_handle_ == nullptr)
    return;

  env()->CloseHandle(timer_handle_, [](uv_timer_t* handle) { delete handle; });
  timer_handle_ = nullptr;
}

ChannelWrap::~ChannelWrap() {
  ares_destroy(channel_);

  if (library_inited_) {
    Mutex::ScopedLock lock(ares_library_mutex);
    // This decreases the reference counter increased by ares_library_init().
    ares_library_cleanup();
  }

  CloseTimer();
}


void ChannelWrap::ModifyActivityQueryCount(int count) {
  active_query_count_ += count;
  CHECK_GE(active_query_count_, 0);
}


/**
 * This function is to check whether current servers are fallback servers
 * when cares initialized.
 *
 * The fallback servers of cares is [ "127.0.0.1" ] with no user additional
 * setting.
 */
void ChannelWrap::EnsureServers() {
  /* if last query is OK or servers are set by user self, do not check */
  if (query_last_ok_ || !is_servers_default_) {
    return;
  }

  ares_addr_port_node* servers = nullptr;

  ares_get_servers_ports(channel_, &servers);

  /* if no server or multi-servers, ignore */
  if (servers == nullptr) return;
  if (servers->next != nullptr) {
    ares_free_data(servers);
    is_servers_default_ = false;
    return;
  }

  /* if the only server is not 127.0.0.1, ignore */
  if (servers[0].family != AF_INET ||
      servers[0].addr.addr4.s_addr != htonl(INADDR_LOOPBACK) ||
      servers[0].tcp_port != 0 ||
      servers[0].udp_port != 0) {
    ares_free_data(servers);
    is_servers_default_ = false;
    return;
  }

  ares_free_data(servers);
  servers = nullptr;

  /* destroy channel and reset channel */
  ares_destroy(channel_);

  CloseTimer();
  Setup();
}


class QueryWrap : public AsyncWrap {
 public:
  QueryWrap(ChannelWrap* channel, Local<Object> req_wrap_obj, const char* name)
      : AsyncWrap(channel->env(), req_wrap_obj, AsyncWrap::PROVIDER_QUERYWRAP),
        channel_(channel),
        trace_name_(name) {
  }

  ~QueryWrap() override {
    CHECK_EQ(false, persistent().IsEmpty());

    // Let Callback() know that this object no longer exists.
    if (callback_ptr_ != nullptr)
      *callback_ptr_ = nullptr;
  }

  // Subclasses should implement the appropriate Send method.
  virtual int Send(const char* name) {
    UNREACHABLE();
    return 0;
  }

  virtual int Send(const char* name, int family) {
    UNREACHABLE();
    return 0;
  }

 protected:
  void AresQuery(const char* name,
                 int dnsclass,
                 int type) {
    channel_->EnsureServers();
    TRACE_EVENT_NESTABLE_ASYNC_BEGIN1(
      TRACING_CATEGORY_NODE2(dns, native), trace_name_, this,
      "name", TRACE_STR_COPY(name));
    ares_query(channel_->cares_channel(), name, dnsclass, type, Callback,
               MakeCallbackPointer());
  }

  struct ResponseData {
    int status;
    bool is_host;
    DeleteFnPtr<hostent, safe_free_hostent> host;
    MallocedBuffer<unsigned char> buf;
  };

  void AfterResponse() {
    CHECK(response_data_);

    const int status = response_data_->status;

    if (status != ARES_SUCCESS) {
      ParseError(status);
    } else if (!response_data_->is_host) {
      Parse(response_data_->buf.data, response_data_->buf.size);
    } else {
      Parse(response_data_->host.get());
    }
  }

  void* MakeCallbackPointer() {
    CHECK_NULL(callback_ptr_);
    callback_ptr_ = new QueryWrap*(this);
    return callback_ptr_;
  }

  static QueryWrap* FromCallbackPointer(void* arg) {
    std::unique_ptr<QueryWrap*> wrap_ptr { static_cast<QueryWrap**>(arg) };
    QueryWrap* wrap = *wrap_ptr.get();
    if (wrap == nullptr) return nullptr;
    wrap->callback_ptr_ = nullptr;
    return wrap;
  }

  static void Callback(void* arg, int status, int timeouts,
                       unsigned char* answer_buf, int answer_len) {
    QueryWrap* wrap = FromCallbackPointer(arg);
    if (wrap == nullptr) return;

    unsigned char* buf_copy = nullptr;
    if (status == ARES_SUCCESS) {
      buf_copy = node::Malloc<unsigned char>(answer_len);
      memcpy(buf_copy, answer_buf, answer_len);
    }

    wrap->response_data_ = std::make_unique<ResponseData>();
    ResponseData* data = wrap->response_data_.get();
    data->status = status;
    data->is_host = false;
    data->buf = MallocedBuffer<unsigned char>(buf_copy, answer_len);

    wrap->QueueResponseCallback(status);
  }

  static void Callback(void* arg, int status, int timeouts,
                       struct hostent* host) {
    QueryWrap* wrap = FromCallbackPointer(arg);
    if (wrap == nullptr) return;

    struct hostent* host_copy = nullptr;
    if (status == ARES_SUCCESS) {
      host_copy = node::Malloc<hostent>(1);
      cares_wrap_hostent_cpy(host_copy, host);
    }

    wrap->response_data_ = std::make_unique<ResponseData>();
    ResponseData* data = wrap->response_data_.get();
    data->status = status;
    data->host.reset(host_copy);
    data->is_host = true;

    wrap->QueueResponseCallback(status);
  }

  void QueueResponseCallback(int status) {
    BaseObjectPtr<QueryWrap> strong_ref{this};
    env()->SetImmediate([this, strong_ref](Environment*) {
      AfterResponse();

      // Delete once strong_ref goes out of scope.
      Detach();
    });

    channel_->set_query_last_ok(status != ARES_ECONNREFUSED);
    channel_->ModifyActivityQueryCount(-1);
  }

  void CallOnComplete(Local<Value> answer,
                      Local<Value> extra = Local<Value>()) {
    HandleScope handle_scope(env()->isolate());
    Context::Scope context_scope(env()->context());
    Local<Value> argv[] = {
      Integer::New(env()->isolate(), 0),
      answer,
      extra
    };
    const int argc = arraysize(argv) - extra.IsEmpty();
    TRACE_EVENT_NESTABLE_ASYNC_END0(
        TRACING_CATEGORY_NODE2(dns, native), trace_name_, this);

    MakeCallback(env()->oncomplete_string(), argc, argv);
  }

  void ParseError(int status) {
    CHECK_NE(status, ARES_SUCCESS);
    HandleScope handle_scope(env()->isolate());
    Context::Scope context_scope(env()->context());
    const char* code = ToErrorCodeString(status);
    Local<Value> arg = OneByteString(env()->isolate(), code);
    TRACE_EVENT_NESTABLE_ASYNC_END1(
        TRACING_CATEGORY_NODE2(dns, native), trace_name_, this,
        "error", status);
    MakeCallback(env()->oncomplete_string(), 1, &arg);
  }

  // Subclasses should implement the appropriate Parse method.
  virtual void Parse(unsigned char* buf, int len) {
    UNREACHABLE();
  }

  virtual void Parse(struct hostent* host) {
    UNREACHABLE();
  }

  BaseObjectPtr<ChannelWrap> channel_;

 private:
  std::unique_ptr<ResponseData> response_data_;
  const char* trace_name_;
  // Pointer to pointer to 'this' that can be reset from the destructor,
  // in order to let Callback() know that 'this' no longer exists.
  QueryWrap** callback_ptr_ = nullptr;
};


template <typename T>
Local<Array> AddrTTLToArray(Environment* env,
                            const T* addrttls,
                            size_t naddrttls) {
  auto isolate = env->isolate();

  MaybeStackBuffer<Local<Value>, 8> ttls(naddrttls);
  for (size_t i = 0; i < naddrttls; i++)
    ttls[i] = Integer::NewFromUnsigned(isolate, addrttls[i].ttl);

  return Array::New(isolate, ttls.out(), naddrttls);
}


int ParseGeneralReply(Environment* env,
                      const unsigned char* buf,
                      int len,
                      int* type,
                      Local<Array> ret,
                      void* addrttls = nullptr,
                      int* naddrttls = nullptr) {
  HandleScope handle_scope(env->isolate());
  auto context = env->context();
  hostent* host;

  int status;
  switch (*type) {
    case ns_t_a:
    case ns_t_cname:
    case ns_t_cname_or_a:
      status = ares_parse_a_reply(buf,
                                  len,
                                  &host,
                                  static_cast<ares_addrttl*>(addrttls),
                                  naddrttls);
      break;
    case ns_t_aaaa:
      status = ares_parse_aaaa_reply(buf,
                                     len,
                                     &host,
                                     static_cast<ares_addr6ttl*>(addrttls),
                                     naddrttls);
      break;
    case ns_t_ns:
      status = ares_parse_ns_reply(buf, len, &host);
      break;
    case ns_t_ptr:
      status = ares_parse_ptr_reply(buf, len, nullptr, 0, AF_INET, &host);
      break;
    default:
      CHECK(0 && "Bad NS type");
      break;
  }

  if (status != ARES_SUCCESS)
    return status;

  /* If it's `CNAME`, return the CNAME value;
   * And if it's `CNAME_OR_A` and it has value in `h_name` and `h_aliases[0]`,
   * we consider it's a CNAME record, otherwise we consider it's an A record. */
  if ((*type == ns_t_cname_or_a && host->h_name && host->h_aliases[0]) ||
      *type == ns_t_cname) {
    // A cname lookup always returns a single record but we follow the
    // common API here.
    *type = ns_t_cname;
    ret->Set(context,
             ret->Length(),
             OneByteString(env->isolate(), host->h_name)).Check();
    ares_free_hostent(host);
    return ARES_SUCCESS;
  }

  if (*type == ns_t_cname_or_a)
    *type = ns_t_a;

  if (*type == ns_t_ns) {
    HostentToNames(env, host, ret);
  } else if (*type == ns_t_ptr) {
    uint32_t offset = ret->Length();
    for (uint32_t i = 0; host->h_aliases[i] != nullptr; i++) {
      auto alias = OneByteString(env->isolate(), host->h_aliases[i]);
      ret->Set(context, i + offset, alias).Check();
    }
  } else {
    uint32_t offset = ret->Length();
    char ip[INET6_ADDRSTRLEN];
    for (uint32_t i = 0; host->h_addr_list[i] != nullptr; ++i) {
      uv_inet_ntop(host->h_addrtype, host->h_addr_list[i], ip, sizeof(ip));
      auto address = OneByteString(env->isolate(), ip);
      ret->Set(context, i + offset, address).Check();
    }
  }

  ares_free_hostent(host);

  return ARES_SUCCESS;
}


int ParseMxReply(Environment* env,
                 const unsigned char* buf,
                 int len,
                 Local<Array> ret,
                 bool need_type = false) {
  HandleScope handle_scope(env->isolate());
  auto context = env->context();

  struct ares_mx_reply* mx_start;
  int status = ares_parse_mx_reply(buf, len, &mx_start);
  if (status != ARES_SUCCESS) {
    return status;
  }

  uint32_t offset = ret->Length();
  ares_mx_reply* current = mx_start;
  for (uint32_t i = 0; current != nullptr; ++i, current = current->next) {
    Local<Object> mx_record = Object::New(env->isolate());
    mx_record->Set(context,
                   env->exchange_string(),
                   OneByteString(env->isolate(), current->host)).Check();
    mx_record->Set(context,
                   env->priority_string(),
                   Integer::New(env->isolate(), current->priority)).Check();
    if (need_type)
      mx_record->Set(context,
                     env->type_string(),
                     env->dns_mx_string()).Check();

    ret->Set(context, i + offset, mx_record).Check();
  }

  ares_free_data(mx_start);
  return ARES_SUCCESS;
}

int ParseTxtReply(Environment* env,
                  const unsigned char* buf,
                  int len,
                  Local<Array> ret,
                  bool need_type = false) {
  HandleScope handle_scope(env->isolate());
  auto context = env->context();

  struct ares_txt_ext* txt_out;

  int status = ares_parse_txt_reply_ext(buf, len, &txt_out);
  if (status != ARES_SUCCESS) {
    return status;
  }

  Local<Array> txt_chunk;

  struct ares_txt_ext* current = txt_out;
  uint32_t i = 0, j;
  uint32_t offset = ret->Length();
  for (j = 0; current != nullptr; current = current->next) {
    Local<String> txt =
        OneByteString(env->isolate(), current->txt, current->length);

    // New record found - write out the current chunk
    if (current->record_start) {
      if (!txt_chunk.IsEmpty()) {
        if (need_type) {
          Local<Object> elem = Object::New(env->isolate());
          elem->Set(context, env->entries_string(), txt_chunk).Check();
          elem->Set(context,
                    env->type_string(),
                    env->dns_txt_string()).Check();
          ret->Set(context, offset + i++, elem).Check();
        } else {
          ret->Set(context, offset + i++, txt_chunk).Check();
        }
      }

      txt_chunk = Array::New(env->isolate());
      j = 0;
    }

    txt_chunk->Set(context, j++, txt).Check();
  }

  // Push last chunk if it isn't empty
  if (!txt_chunk.IsEmpty()) {
    if (need_type) {
      Local<Object> elem = Object::New(env->isolate());
      elem->Set(context, env->entries_string(), txt_chunk).Check();
      elem->Set(context,
                env->type_string(),
                env->dns_txt_string()).Check();
      ret->Set(context, offset + i, elem).Check();
    } else {
      ret->Set(context, offset + i, txt_chunk).Check();
    }
  }

  ares_free_data(txt_out);
  return ARES_SUCCESS;
}


int ParseSrvReply(Environment* env,
                  const unsigned char* buf,
                  int len,
                  Local<Array> ret,
                  bool need_type = false) {
  HandleScope handle_scope(env->isolate());
  auto context = env->context();

  struct ares_srv_reply* srv_start;
  int status = ares_parse_srv_reply(buf, len, &srv_start);
  if (status != ARES_SUCCESS) {
    return status;
  }

  ares_srv_reply* current = srv_start;
  int offset = ret->Length();
  for (uint32_t i = 0; current != nullptr; ++i, current = current->next) {
    Local<Object> srv_record = Object::New(env->isolate());
    srv_record->Set(context,
                    env->name_string(),
                    OneByteString(env->isolate(), current->host)).Check();
    srv_record->Set(context,
                    env->port_string(),
                    Integer::New(env->isolate(), current->port)).Check();
    srv_record->Set(context,
                    env->priority_string(),
                    Integer::New(env->isolate(), current->priority)).Check();
    srv_record->Set(context,
                    env->weight_string(),
                    Integer::New(env->isolate(), current->weight)).Check();
    if (need_type)
      srv_record->Set(context,
                      env->type_string(),
                      env->dns_srv_string()).Check();

    ret->Set(context, i + offset, srv_record).Check();
  }

  ares_free_data(srv_start);
  return ARES_SUCCESS;
}


int ParseNaptrReply(Environment* env,
                    const unsigned char* buf,
                    int len,
                    Local<Array> ret,
                    bool need_type = false) {
  HandleScope handle_scope(env->isolate());
  auto context = env->context();

  ares_naptr_reply* naptr_start;
  int status = ares_parse_naptr_reply(buf, len, &naptr_start);

  if (status != ARES_SUCCESS) {
    return status;
  }

  ares_naptr_reply* current = naptr_start;
  int offset = ret->Length();
  for (uint32_t i = 0; current != nullptr; ++i, current = current->next) {
    Local<Object> naptr_record = Object::New(env->isolate());
    naptr_record->Set(context,
                      env->flags_string(),
                      OneByteString(env->isolate(), current->flags)).Check();
    naptr_record->Set(context,
                      env->service_string(),
                      OneByteString(env->isolate(),
                                    current->service)).Check();
    naptr_record->Set(context,
                      env->regexp_string(),
                      OneByteString(env->isolate(),
                                    current->regexp)).Check();
    naptr_record->Set(context,
                      env->replacement_string(),
                      OneByteString(env->isolate(),
                                    current->replacement)).Check();
    naptr_record->Set(context,
                      env->order_string(),
                      Integer::New(env->isolate(), current->order)).Check();
    naptr_record->Set(context,
                      env->preference_string(),
                      Integer::New(env->isolate(),
                                   current->preference)).Check();
    if (need_type)
      naptr_record->Set(context,
                        env->type_string(),
                        env->dns_naptr_string()).Check();

    ret->Set(context, i + offset, naptr_record).Check();
  }

  ares_free_data(naptr_start);
  return ARES_SUCCESS;
}


int ParseSoaReply(Environment* env,
                  unsigned char* buf,
                  int len,
                  Local<Object>* ret) {
  EscapableHandleScope handle_scope(env->isolate());
  auto context = env->context();

  // Manage memory using standardard smart pointer std::unique_tr
  struct AresDeleter {
    void operator()(char* ptr) const noexcept { ares_free_string(ptr); }
  };
  using ares_unique_ptr = std::unique_ptr<char[], AresDeleter>;

  // Can't use ares_parse_soa_reply() here which can only parse single record
  const unsigned int ancount = cares_get_16bit(buf + 6);
  unsigned char* ptr = buf + NS_HFIXEDSZ;
  char* name_temp;
  long temp_len;  // NOLINT(runtime/int)
  int status = ares_expand_name(ptr, buf, len, &name_temp, &temp_len);
  const ares_unique_ptr name(name_temp);
  if (status != ARES_SUCCESS) {
    // returns EBADRESP in case of invalid input
    return status == ARES_EBADNAME ? ARES_EBADRESP : status;
  }

  if (ptr + temp_len + NS_QFIXEDSZ > buf + len) {
    return ARES_EBADRESP;
  }
  ptr += temp_len + NS_QFIXEDSZ;

  for (unsigned int i = 0; i < ancount; i++) {
    char* rr_name_temp;
    long rr_temp_len;  // NOLINT(runtime/int)
    int status2 = ares_expand_name(ptr, buf, len, &rr_name_temp, &rr_temp_len);
    const ares_unique_ptr rr_name(rr_name_temp);

    if (status2 != ARES_SUCCESS)
      return status2 == ARES_EBADNAME ? ARES_EBADRESP : status2;

    ptr += rr_temp_len;
    if (ptr + NS_RRFIXEDSZ > buf + len) {
      return ARES_EBADRESP;
    }

    const int rr_type = cares_get_16bit(ptr);
    const int rr_len = cares_get_16bit(ptr + 8);
    ptr += NS_RRFIXEDSZ;

    // only need SOA
    if (rr_type == ns_t_soa) {
      char* nsname_temp;
      long nsname_temp_len;  // NOLINT(runtime/int)

      int status3 = ares_expand_name(ptr, buf, len,
                                     &nsname_temp,
                                     &nsname_temp_len);
      const ares_unique_ptr nsname(nsname_temp);
      if (status3 != ARES_SUCCESS) {
        return status3 == ARES_EBADNAME ? ARES_EBADRESP : status3;
      }
      ptr += nsname_temp_len;

      char* hostmaster_temp;
      long hostmaster_temp_len;  // NOLINT(runtime/int)
      int status4 = ares_expand_name(ptr, buf, len,
                                     &hostmaster_temp,
                                     &hostmaster_temp_len);
      const ares_unique_ptr hostmaster(hostmaster_temp);
      if (status4 != ARES_SUCCESS) {
        return status4 == ARES_EBADNAME ? ARES_EBADRESP : status4;
      }
      ptr += hostmaster_temp_len;

      if (ptr + 5 * 4 > buf + len) {
        return ARES_EBADRESP;
      }

      const unsigned int serial = cares_get_32bit(ptr + 0 * 4);
      const unsigned int refresh = cares_get_32bit(ptr + 1 * 4);
      const unsigned int retry = cares_get_32bit(ptr + 2 * 4);
      const unsigned int expire = cares_get_32bit(ptr + 3 * 4);
      const unsigned int minttl = cares_get_32bit(ptr + 4 * 4);

      Local<Object> soa_record = Object::New(env->isolate());
      soa_record->Set(context,
                      env->nsname_string(),
                      OneByteString(env->isolate(), nsname.get())).Check();
      soa_record->Set(context,
                      env->hostmaster_string(),
                      OneByteString(env->isolate(),
                                    hostmaster.get())).Check();
      soa_record->Set(context,
                      env->serial_string(),
                      Integer::NewFromUnsigned(env->isolate(), serial)).Check();
      soa_record->Set(context,
                      env->refresh_string(),
                      Integer::New(env->isolate(), refresh)).Check();
      soa_record->Set(context,
                      env->retry_string(),
                      Integer::New(env->isolate(), retry)).Check();
      soa_record->Set(context,
                      env->expire_string(),
                      Integer::New(env->isolate(), expire)).Check();
      soa_record->Set(context,
                      env->minttl_string(),
                      Integer::NewFromUnsigned(env->isolate(), minttl)).Check();
      soa_record->Set(context,
                      env->type_string(),
                      env->dns_soa_string()).Check();


      *ret = handle_scope.Escape(soa_record);
      break;
    }

    ptr += rr_len;
  }

  return ARES_SUCCESS;
}


class QueryAnyWrap: public QueryWrap {
 public:
  QueryAnyWrap(ChannelWrap* channel, Local<Object> req_wrap_obj)
    : QueryWrap(channel, req_wrap_obj, "resolveAny") {
  }

  int Send(const char* name) override {
    AresQuery(name, ns_c_in, ns_t_any);
    return 0;
  }

  SET_NO_MEMORY_INFO()
  SET_MEMORY_INFO_NAME(QueryAnyWrap)
  SET_SELF_SIZE(QueryAnyWrap)

 protected:
  void Parse(unsigned char* buf, int len) override {
    HandleScope handle_scope(env()->isolate());
    auto context = env()->context();
    Context::Scope context_scope(context);

    Local<Array> ret = Array::New(env()->isolate());
    int type, status, old_count;

    /* Parse A records or CNAME records */
    ares_addrttl addrttls[256];
    int naddrttls = arraysize(addrttls);

    type = ns_t_cname_or_a;
    status = ParseGeneralReply(env(),
                               buf,
                               len,
                               &type,
                               ret,
                               addrttls,
                               &naddrttls);
    uint32_t a_count = ret->Length();
    if (status != ARES_SUCCESS && status != ARES_ENODATA) {
      ParseError(status);
      return;
    }

    if (type == ns_t_a) {
      CHECK_EQ(static_cast<uint32_t>(naddrttls), a_count);
      for (uint32_t i = 0; i < a_count; i++) {
        Local<Object> obj = Object::New(env()->isolate());
        obj->Set(context,
                 env()->address_string(),
                 ret->Get(context, i).ToLocalChecked()).Check();
        obj->Set(context,
                 env()->ttl_string(),
                 Integer::NewFromUnsigned(
                   env()->isolate(), addrttls[i].ttl)).Check();
        obj->Set(context,
                 env()->type_string(),
                 env()->dns_a_string()).Check();
        ret->Set(context, i, obj).Check();
      }
    } else {
      for (uint32_t i = 0; i < a_count; i++) {
        Local<Object> obj = Object::New(env()->isolate());
        obj->Set(context,
                 env()->value_string(),
                 ret->Get(context, i).ToLocalChecked()).Check();
        obj->Set(context,
                 env()->type_string(),
                 env()->dns_cname_string()).Check();
        ret->Set(context, i, obj).Check();
      }
    }

    /* Parse AAAA records */
    ares_addr6ttl addr6ttls[256];
    int naddr6ttls = arraysize(addr6ttls);

    type = ns_t_aaaa;
    status = ParseGeneralReply(env(),
                               buf,
                               len,
                               &type,
                               ret,
                               addr6ttls,
                               &naddr6ttls);
    uint32_t aaaa_count = ret->Length() - a_count;
    if (status != ARES_SUCCESS && status != ARES_ENODATA) {
      ParseError(status);
      return;
    }

    CHECK_EQ(aaaa_count, static_cast<uint32_t>(naddr6ttls));
    CHECK_EQ(ret->Length(), a_count + aaaa_count);
    for (uint32_t i = a_count; i < ret->Length(); i++) {
      Local<Object> obj = Object::New(env()->isolate());
      obj->Set(context,
               env()->address_string(),
               ret->Get(context, i).ToLocalChecked()).Check();
      obj->Set(context,
               env()->ttl_string(),
               Integer::NewFromUnsigned(
                 env()->isolate(), addr6ttls[i - a_count].ttl)).Check();
      obj->Set(context,
               env()->type_string(),
               env()->dns_aaaa_string()).Check();
      ret->Set(context, i, obj).Check();
    }

    /* Parse MX records */
    status = ParseMxReply(env(), buf, len, ret, true);
    if (status != ARES_SUCCESS && status != ARES_ENODATA) {
      ParseError(status);
      return;
    }

    /* Parse NS records */
    type = ns_t_ns;
    old_count = ret->Length();
    status = ParseGeneralReply(env(), buf, len, &type, ret);
    if (status != ARES_SUCCESS && status != ARES_ENODATA) {
      ParseError(status);
      return;
    }
    for (uint32_t i = old_count; i < ret->Length(); i++) {
      Local<Object> obj = Object::New(env()->isolate());
      obj->Set(context,
               env()->value_string(),
               ret->Get(context, i).ToLocalChecked()).Check();
      obj->Set(context,
               env()->type_string(),
               env()->dns_ns_string()).Check();
      ret->Set(context, i, obj).Check();
    }

    /* Parse TXT records */
    status = ParseTxtReply(env(), buf, len, ret, true);
    if (status != ARES_SUCCESS && status != ARES_ENODATA) {
      ParseError(status);
      return;
    }

    /* Parse SRV records */
    status = ParseSrvReply(env(), buf, len, ret, true);
    if (status != ARES_SUCCESS && status != ARES_ENODATA) {
      return;
    }

    /* Parse PTR records */
    type = ns_t_ptr;
    old_count = ret->Length();
    status = ParseGeneralReply(env(), buf, len, &type, ret);
    for (uint32_t i = old_count; i < ret->Length(); i++) {
      Local<Object> obj = Object::New(env()->isolate());
      obj->Set(context,
               env()->value_string(),
               ret->Get(context, i).ToLocalChecked()).Check();
      obj->Set(context,
               env()->type_string(),
               env()->dns_ptr_string()).Check();
      ret->Set(context, i, obj).Check();
    }

    /* Parse NAPTR records */
    status = ParseNaptrReply(env(), buf, len, ret, true);
    if (status != ARES_SUCCESS && status != ARES_ENODATA) {
      ParseError(status);
      return;
    }

    /* Parse SOA records */
    Local<Object> soa_record = Local<Object>();
    status = ParseSoaReply(env(), buf, len, &soa_record);
    if (status != ARES_SUCCESS && status != ARES_ENODATA) {
      ParseError(status);
      return;
    }
    if (!soa_record.IsEmpty())
      ret->Set(context, ret->Length(), soa_record).Check();

    CallOnComplete(ret);
  }
};


class QueryAWrap: public QueryWrap {
 public:
  QueryAWrap(ChannelWrap* channel, Local<Object> req_wrap_obj)
      : QueryWrap(channel, req_wrap_obj, "resolve4") {
  }

  int Send(const char* name) override {
    AresQuery(name, ns_c_in, ns_t_a);
    return 0;
  }

  SET_NO_MEMORY_INFO()
  SET_MEMORY_INFO_NAME(QueryAWrap)
  SET_SELF_SIZE(QueryAWrap)

 protected:
  void Parse(unsigned char* buf, int len) override {
    HandleScope handle_scope(env()->isolate());
    Context::Scope context_scope(env()->context());

    ares_addrttl addrttls[256];
    int naddrttls = arraysize(addrttls), status;
    Local<Array> ret = Array::New(env()->isolate());

    int type = ns_t_a;
    status = ParseGeneralReply(env(),
                               buf,
                               len,
                               &type,
                               ret,
                               addrttls,
                               &naddrttls);
    if (status != ARES_SUCCESS) {
      ParseError(status);
      return;
    }

    Local<Array> ttls = AddrTTLToArray<ares_addrttl>(env(),
                                                     addrttls,
                                                     naddrttls);

    CallOnComplete(ret, ttls);
  }
};


class QueryAaaaWrap: public QueryWrap {
 public:
  QueryAaaaWrap(ChannelWrap* channel, Local<Object> req_wrap_obj)
      : QueryWrap(channel, req_wrap_obj, "resolve6") {
  }

  int Send(const char* name) override {
    AresQuery(name, ns_c_in, ns_t_aaaa);
    return 0;
  }

  SET_NO_MEMORY_INFO()
  SET_MEMORY_INFO_NAME(QueryAaaaWrap)
  SET_SELF_SIZE(QueryAaaaWrap)

 protected:
  void Parse(unsigned char* buf, int len) override {
    HandleScope handle_scope(env()->isolate());
    Context::Scope context_scope(env()->context());

    ares_addr6ttl addrttls[256];
    int naddrttls = arraysize(addrttls), status;
    Local<Array> ret = Array::New(env()->isolate());

    int type = ns_t_aaaa;
    status = ParseGeneralReply(env(),
                               buf,
                               len,
                               &type,
                               ret,
                               addrttls,
                               &naddrttls);
    if (status != ARES_SUCCESS) {
      ParseError(status);
      return;
    }

    Local<Array> ttls = AddrTTLToArray<ares_addr6ttl>(env(),
                                                      addrttls,
                                                      naddrttls);

    CallOnComplete(ret, ttls);
  }
};


class QueryCnameWrap: public QueryWrap {
 public:
  QueryCnameWrap(ChannelWrap* channel, Local<Object> req_wrap_obj)
      : QueryWrap(channel, req_wrap_obj, "resolveCname") {
  }

  int Send(const char* name) override {
    AresQuery(name, ns_c_in, ns_t_cname);
    return 0;
  }

  SET_NO_MEMORY_INFO()
  SET_MEMORY_INFO_NAME(QueryCnameWrap)
  SET_SELF_SIZE(QueryCnameWrap)

 protected:
  void Parse(unsigned char* buf, int len) override {
    HandleScope handle_scope(env()->isolate());
    Context::Scope context_scope(env()->context());

    Local<Array> ret = Array::New(env()->isolate());
    int type = ns_t_cname;
    int status = ParseGeneralReply(env(), buf, len, &type, ret);
    if (status != ARES_SUCCESS) {
      ParseError(status);
      return;
    }

    this->CallOnComplete(ret);
  }
};


class QueryMxWrap: public QueryWrap {
 public:
  QueryMxWrap(ChannelWrap* channel, Local<Object> req_wrap_obj)
      : QueryWrap(channel, req_wrap_obj, "resolveMx") {
  }

  int Send(const char* name) override {
    AresQuery(name, ns_c_in, ns_t_mx);
    return 0;
  }

  SET_NO_MEMORY_INFO()
  SET_MEMORY_INFO_NAME(QueryMxWrap)
  SET_SELF_SIZE(QueryMxWrap)

 protected:
  void Parse(unsigned char* buf, int len) override {
    HandleScope handle_scope(env()->isolate());
    Context::Scope context_scope(env()->context());

    Local<Array> mx_records = Array::New(env()->isolate());
    int status = ParseMxReply(env(), buf, len, mx_records);

    if (status != ARES_SUCCESS) {
      ParseError(status);
      return;
    }

    this->CallOnComplete(mx_records);
  }
};


class QueryNsWrap: public QueryWrap {
 public:
  QueryNsWrap(ChannelWrap* channel, Local<Object> req_wrap_obj)
      : QueryWrap(channel, req_wrap_obj, "resolveNs") {
  }

  int Send(const char* name) override {
    AresQuery(name, ns_c_in, ns_t_ns);
    return 0;
  }

  SET_NO_MEMORY_INFO()
  SET_MEMORY_INFO_NAME(QueryNsWrap)
  SET_SELF_SIZE(QueryNsWrap)

 protected:
  void Parse(unsigned char* buf, int len) override {
    HandleScope handle_scope(env()->isolate());
    Context::Scope context_scope(env()->context());

    int type = ns_t_ns;
    Local<Array> names = Array::New(env()->isolate());
    int status = ParseGeneralReply(env(), buf, len, &type, names);
    if (status != ARES_SUCCESS) {
      ParseError(status);
      return;
    }

    this->CallOnComplete(names);
  }
};


class QueryTxtWrap: public QueryWrap {
 public:
  QueryTxtWrap(ChannelWrap* channel, Local<Object> req_wrap_obj)
      : QueryWrap(channel, req_wrap_obj, "resolveTxt") {
  }

  int Send(const char* name) override {
    AresQuery(name, ns_c_in, ns_t_txt);
    return 0;
  }

  SET_NO_MEMORY_INFO()
  SET_MEMORY_INFO_NAME(QueryTxtWrap)
  SET_SELF_SIZE(QueryTxtWrap)

 protected:
  void Parse(unsigned char* buf, int len) override {
    HandleScope handle_scope(env()->isolate());
    Context::Scope context_scope(env()->context());

    Local<Array> txt_records = Array::New(env()->isolate());
    int status = ParseTxtReply(env(), buf, len, txt_records);
    if (status != ARES_SUCCESS) {
      ParseError(status);
      return;
    }

    this->CallOnComplete(txt_records);
  }
};


class QuerySrvWrap: public QueryWrap {
 public:
  explicit QuerySrvWrap(ChannelWrap* channel, Local<Object> req_wrap_obj)
      : QueryWrap(channel, req_wrap_obj, "resolveSrv") {
  }

  int Send(const char* name) override {
    AresQuery(name, ns_c_in, ns_t_srv);
    return 0;
  }

  SET_NO_MEMORY_INFO()
  SET_MEMORY_INFO_NAME(QuerySrvWrap)
  SET_SELF_SIZE(QuerySrvWrap)

 protected:
  void Parse(unsigned char* buf, int len) override {
    HandleScope handle_scope(env()->isolate());
    Context::Scope context_scope(env()->context());

    Local<Array> srv_records = Array::New(env()->isolate());
    int status = ParseSrvReply(env(), buf, len, srv_records);
    if (status != ARES_SUCCESS) {
      ParseError(status);
      return;
    }

    this->CallOnComplete(srv_records);
  }
};

class QueryPtrWrap: public QueryWrap {
 public:
  explicit QueryPtrWrap(ChannelWrap* channel, Local<Object> req_wrap_obj)
      : QueryWrap(channel, req_wrap_obj, "resolvePtr") {
  }

  int Send(const char* name) override {
    AresQuery(name, ns_c_in, ns_t_ptr);
    return 0;
  }

  SET_NO_MEMORY_INFO()
  SET_MEMORY_INFO_NAME(QueryPtrWrap)
  SET_SELF_SIZE(QueryPtrWrap)

 protected:
  void Parse(unsigned char* buf, int len) override {
    HandleScope handle_scope(env()->isolate());
    Context::Scope context_scope(env()->context());

    int type = ns_t_ptr;
    Local<Array> aliases = Array::New(env()->isolate());

    int status = ParseGeneralReply(env(), buf, len, &type, aliases);
    if (status != ARES_SUCCESS) {
      ParseError(status);
      return;
    }

    this->CallOnComplete(aliases);
  }
};

class QueryNaptrWrap: public QueryWrap {
 public:
  explicit QueryNaptrWrap(ChannelWrap* channel, Local<Object> req_wrap_obj)
      : QueryWrap(channel, req_wrap_obj, "resolveNaptr") {
  }

  int Send(const char* name) override {
    AresQuery(name, ns_c_in, ns_t_naptr);
    return 0;
  }

  SET_NO_MEMORY_INFO()
  SET_MEMORY_INFO_NAME(QueryNaptrWrap)
  SET_SELF_SIZE(QueryNaptrWrap)

 protected:
  void Parse(unsigned char* buf, int len) override {
    HandleScope handle_scope(env()->isolate());
    Context::Scope context_scope(env()->context());

    Local<Array> naptr_records = Array::New(env()->isolate());
    int status = ParseNaptrReply(env(), buf, len, naptr_records);
    if (status != ARES_SUCCESS) {
      ParseError(status);
      return;
    }

    this->CallOnComplete(naptr_records);
  }
};


class QuerySoaWrap: public QueryWrap {
 public:
  QuerySoaWrap(ChannelWrap* channel, Local<Object> req_wrap_obj)
      : QueryWrap(channel, req_wrap_obj, "resolveSoa") {
  }

  int Send(const char* name) override {
    AresQuery(name, ns_c_in, ns_t_soa);
    return 0;
  }

  SET_NO_MEMORY_INFO()
  SET_MEMORY_INFO_NAME(QuerySoaWrap)
  SET_SELF_SIZE(QuerySoaWrap)

 protected:
  void Parse(unsigned char* buf, int len) override {
    HandleScope handle_scope(env()->isolate());
    auto context = env()->context();
    Context::Scope context_scope(context);

    ares_soa_reply* soa_out;
    int status = ares_parse_soa_reply(buf, len, &soa_out);

    if (status != ARES_SUCCESS) {
      ParseError(status);
      return;
    }

    Local<Object> soa_record = Object::New(env()->isolate());

    soa_record->Set(context,
                    env()->nsname_string(),
                    OneByteString(env()->isolate(),
                                  soa_out->nsname)).Check();
    soa_record->Set(context,
                    env()->hostmaster_string(),
                    OneByteString(env()->isolate(),
                                  soa_out->hostmaster)).Check();
    soa_record->Set(context,
                    env()->serial_string(),
                    Integer::NewFromUnsigned(
                      env()->isolate(), soa_out->serial)).Check();
    soa_record->Set(context,
                    env()->refresh_string(),
                    Integer::New(env()->isolate(),
                                 soa_out->refresh)).Check();
    soa_record->Set(context,
                    env()->retry_string(),
                    Integer::New(env()->isolate(), soa_out->retry)).Check();
    soa_record->Set(context,
                    env()->expire_string(),
                    Integer::New(env()->isolate(), soa_out->expire)).Check();
    soa_record->Set(context,
                    env()->minttl_string(),
                    Integer::NewFromUnsigned(
                      env()->isolate(), soa_out->minttl)).Check();

    ares_free_data(soa_out);

    this->CallOnComplete(soa_record);
  }
};


class GetHostByAddrWrap: public QueryWrap {
 public:
  explicit GetHostByAddrWrap(ChannelWrap* channel, Local<Object> req_wrap_obj)
      : QueryWrap(channel, req_wrap_obj, "reverse") {
  }

  int Send(const char* name) override {
    int length, family;
    char address_buffer[sizeof(struct in6_addr)];

    if (uv_inet_pton(AF_INET, name, &address_buffer) == 0) {
      length = sizeof(struct in_addr);
      family = AF_INET;
    } else if (uv_inet_pton(AF_INET6, name, &address_buffer) == 0) {
      length = sizeof(struct in6_addr);
      family = AF_INET6;
    } else {
      return UV_EINVAL;  // So errnoException() reports a proper error.
    }

    TRACE_EVENT_NESTABLE_ASYNC_BEGIN2(
        TRACING_CATEGORY_NODE2(dns, native), "reverse", this,
        "name", TRACE_STR_COPY(name),
        "family", family == AF_INET ? "ipv4" : "ipv6");

    ares_gethostbyaddr(channel_->cares_channel(),
                       address_buffer,
                       length,
                       family,
                       Callback,
                       MakeCallbackPointer());
    return 0;
  }

  SET_NO_MEMORY_INFO()
  SET_MEMORY_INFO_NAME(GetHostByAddrWrap)
  SET_SELF_SIZE(GetHostByAddrWrap)

 protected:
  void Parse(struct hostent* host) override {
    HandleScope handle_scope(env()->isolate());
    Context::Scope context_scope(env()->context());
    this->CallOnComplete(HostentToNames(env(), host));
  }
};


template <class Wrap>
static void Query(const FunctionCallbackInfo<Value>& args) {
  Environment* env = Environment::GetCurrent(args);
  ChannelWrap* channel;
  ASSIGN_OR_RETURN_UNWRAP(&channel, args.Holder());

  CHECK_EQ(false, args.IsConstructCall());
  CHECK(args[0]->IsObject());
  CHECK(args[1]->IsString());

  Local<Object> req_wrap_obj = args[0].As<Object>();
  Local<String> string = args[1].As<String>();
  auto wrap = std::make_unique<Wrap>(channel, req_wrap_obj);

  node::Utf8Value name(env->isolate(), string);
  channel->ModifyActivityQueryCount(1);
  int err = wrap->Send(*name);
  if (err) {
    channel->ModifyActivityQueryCount(-1);
  } else {
    // Release ownership of the pointer allowing the ownership to be transferred
    USE(wrap.release());
  }

  args.GetReturnValue().Set(err);
}


void AfterGetAddrInfo(uv_getaddrinfo_t* req, int status, struct addrinfo* res) {
  std::unique_ptr<GetAddrInfoReqWrap> req_wrap {
      static_cast<GetAddrInfoReqWrap*>(req->data)};
  Environment* env = req_wrap->env();

  HandleScope handle_scope(env->isolate());
  Context::Scope context_scope(env->context());

  Local<Value> argv[] = {
    Integer::New(env->isolate(), status),
    Null(env->isolate())
  };

  uint64_t n = 0;
  const bool verbatim = req_wrap->verbatim();

  if (status == 0) {
    Local<Array> results = Array::New(env->isolate());

    auto add = [&] (bool want_ipv4, bool want_ipv6) {
      for (auto p = res; p != nullptr; p = p->ai_next) {
        CHECK_EQ(p->ai_socktype, SOCK_STREAM);

        const char* addr;
        if (want_ipv4 && p->ai_family == AF_INET) {
          addr = reinterpret_cast<char*>(
              &(reinterpret_cast<struct sockaddr_in*>(p->ai_addr)->sin_addr));
        } else if (want_ipv6 && p->ai_family == AF_INET6) {
          addr = reinterpret_cast<char*>(
              &(reinterpret_cast<struct sockaddr_in6*>(p->ai_addr)->sin6_addr));
        } else {
          continue;
        }

        char ip[INET6_ADDRSTRLEN];
        if (uv_inet_ntop(p->ai_family, addr, ip, sizeof(ip)))
          continue;

        Local<String> s = OneByteString(env->isolate(), ip);
        results->Set(env->context(), n, s).Check();
        n++;
      }
    };

    add(true, verbatim);
    if (verbatim == false)
      add(false, true);

    // No responses were found to return
    if (n == 0) {
      argv[0] = Integer::New(env->isolate(), UV_EAI_NODATA);
    }

    argv[1] = results;
  }

  uv_freeaddrinfo(res);

  TRACE_EVENT_NESTABLE_ASYNC_END2(
      TRACING_CATEGORY_NODE2(dns, native), "lookup", req_wrap.get(),
      "count", n, "verbatim", verbatim);

  // Make the callback into JavaScript
  req_wrap->MakeCallback(env->oncomplete_string(), arraysize(argv), argv);
}


void AfterGetNameInfo(uv_getnameinfo_t* req,
                      int status,
                      const char* hostname,
                      const char* service) {
  std::unique_ptr<GetNameInfoReqWrap> req_wrap {
      static_cast<GetNameInfoReqWrap*>(req->data)};
  Environment* env = req_wrap->env();

  HandleScope handle_scope(env->isolate());
  Context::Scope context_scope(env->context());

  Local<Value> argv[] = {
    Integer::New(env->isolate(), status),
    Null(env->isolate()),
    Null(env->isolate())
  };

  if (status == 0) {
    // Success
    Local<String> js_hostname = OneByteString(env->isolate(), hostname);
    Local<String> js_service = OneByteString(env->isolate(), service);
    argv[1] = js_hostname;
    argv[2] = js_service;
  }

  TRACE_EVENT_NESTABLE_ASYNC_END2(
      TRACING_CATEGORY_NODE2(dns, native), "lookupService", req_wrap.get(),
      "hostname", TRACE_STR_COPY(hostname),
      "service", TRACE_STR_COPY(service));

  // Make the callback into JavaScript
  req_wrap->MakeCallback(env->oncomplete_string(), arraysize(argv), argv);
}

using ParseIPResult =
    decltype(static_cast<ares_addr_port_node*>(nullptr)->addr);

int ParseIP(const char* ip, ParseIPResult* result = nullptr) {
  ParseIPResult tmp;
  if (result == nullptr) result = &tmp;
  if (0 == uv_inet_pton(AF_INET, ip, result)) return 4;
  if (0 == uv_inet_pton(AF_INET6, ip, result)) return 6;
  return 0;
}

void CanonicalizeIP(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();
  node::Utf8Value ip(isolate, args[0]);

  ParseIPResult result;
  const int rc = ParseIP(*ip, &result);
  if (rc == 0) return;

  char canonical_ip[INET6_ADDRSTRLEN];
  const int af = (rc == 4 ? AF_INET : AF_INET6);
  CHECK_EQ(0, uv_inet_ntop(af, &result, canonical_ip, sizeof(canonical_ip)));
  Local<String> val = String::NewFromUtf8(isolate, canonical_ip)
      .ToLocalChecked();
  args.GetReturnValue().Set(val);
}

void GetAddrInfo(const FunctionCallbackInfo<Value>& args) {
  Environment* env = Environment::GetCurrent(args);

  CHECK(args[0]->IsObject());
  CHECK(args[1]->IsString());
  CHECK(args[2]->IsInt32());
  CHECK(args[4]->IsBoolean());
  Local<Object> req_wrap_obj = args[0].As<Object>();
  node::Utf8Value hostname(env->isolate(), args[1]);

  int32_t flags = 0;
  if (args[3]->IsInt32()) {
    flags = args[3].As<Int32>()->Value();
  }

  int family;

  switch (args[2].As<Int32>()->Value()) {
    case 0:
      family = AF_UNSPEC;
      break;
    case 4:
      family = AF_INET;
      break;
    case 6:
      family = AF_INET6;
      break;
    default:
      CHECK(0 && "bad address family");
  }

  auto req_wrap = std::make_unique<GetAddrInfoReqWrap>(env,
                                                       req_wrap_obj,
                                                       args[4]->IsTrue());

  struct addrinfo hints;
  memset(&hints, 0, sizeof(hints));
  hints.ai_family = family;
  hints.ai_socktype = SOCK_STREAM;
  hints.ai_flags = flags;

  TRACE_EVENT_NESTABLE_ASYNC_BEGIN2(
      TRACING_CATEGORY_NODE2(dns, native), "lookup", req_wrap.get(),
      "hostname", TRACE_STR_COPY(*hostname),
      "family",
      family == AF_INET ? "ipv4" : family == AF_INET6 ? "ipv6" : "unspec");

  int err = req_wrap->Dispatch(uv_getaddrinfo,
                               AfterGetAddrInfo,
                               *hostname,
                               nullptr,
                               &hints);
  if (err == 0)
    // Release ownership of the pointer allowing the ownership to be transferred
    USE(req_wrap.release());

  args.GetReturnValue().Set(err);
}


void GetNameInfo(const FunctionCallbackInfo<Value>& args) {
  Environment* env = Environment::GetCurrent(args);

  CHECK(args[0]->IsObject());
  CHECK(args[1]->IsString());
  CHECK(args[2]->IsUint32());
  Local<Object> req_wrap_obj = args[0].As<Object>();
  node::Utf8Value ip(env->isolate(), args[1]);
  const unsigned port = args[2]->Uint32Value(env->context()).FromJust();
  struct sockaddr_storage addr;

  CHECK(uv_ip4_addr(*ip, port, reinterpret_cast<sockaddr_in*>(&addr)) == 0 ||
        uv_ip6_addr(*ip, port, reinterpret_cast<sockaddr_in6*>(&addr)) == 0);

  auto req_wrap = std::make_unique<GetNameInfoReqWrap>(env, req_wrap_obj);

  TRACE_EVENT_NESTABLE_ASYNC_BEGIN2(
      TRACING_CATEGORY_NODE2(dns, native), "lookupService", req_wrap.get(),
      "ip", TRACE_STR_COPY(*ip), "port", port);

  int err = req_wrap->Dispatch(uv_getnameinfo,
                               AfterGetNameInfo,
                               reinterpret_cast<struct sockaddr*>(&addr),
                               NI_NAMEREQD);
  if (err == 0)
    // Release ownership of the pointer allowing the ownership to be transferred
    USE(req_wrap.release());

  args.GetReturnValue().Set(err);
}


void GetServers(const FunctionCallbackInfo<Value>& args) {
  Environment* env = Environment::GetCurrent(args);
  ChannelWrap* channel;
  ASSIGN_OR_RETURN_UNWRAP(&channel, args.Holder());

  Local<Array> server_array = Array::New(env->isolate());

  ares_addr_port_node* servers;

  int r = ares_get_servers_ports(channel->cares_channel(), &servers);
  CHECK_EQ(r, ARES_SUCCESS);
  auto cleanup = OnScopeLeave([&]() { ares_free_data(servers); });

  ares_addr_port_node* cur = servers;

  for (uint32_t i = 0; cur != nullptr; ++i, cur = cur->next) {
    char ip[INET6_ADDRSTRLEN];

    const void* caddr = static_cast<const void*>(&cur->addr);
    int err = uv_inet_ntop(cur->family, caddr, ip, sizeof(ip));
    CHECK_EQ(err, 0);

    Local<Value> ret[] = {
      OneByteString(env->isolate(), ip),
      Integer::New(env->isolate(), cur->udp_port)
    };

    if (server_array->Set(env->context(), i,
                          Array::New(env->isolate(), ret, arraysize(ret)))
          .IsNothing()) {
      return;
    }
  }

  args.GetReturnValue().Set(server_array);
}


void SetServers(const FunctionCallbackInfo<Value>& args) {
  Environment* env = Environment::GetCurrent(args);
  ChannelWrap* channel;
  ASSIGN_OR_RETURN_UNWRAP(&channel, args.Holder());

  if (channel->active_query_count()) {
    return args.GetReturnValue().Set(DNS_ESETSRVPENDING);
  }

  CHECK(args[0]->IsArray());

  Local<Array> arr = Local<Array>::Cast(args[0]);

  uint32_t len = arr->Length();

  if (len == 0) {
    int rv = ares_set_servers(channel->cares_channel(), nullptr);
    return args.GetReturnValue().Set(rv);
  }

  std::vector<ares_addr_port_node> servers(len);
  ares_addr_port_node* last = nullptr;

  int err;

  for (uint32_t i = 0; i < len; i++) {
    CHECK(arr->Get(env->context(), i).ToLocalChecked()->IsArray());

    Local<Array> elm =
        Local<Array>::Cast(arr->Get(env->context(), i).ToLocalChecked());

    CHECK(elm->Get(env->context(),
                   0).ToLocalChecked()->Int32Value(env->context()).FromJust());
    CHECK(elm->Get(env->context(), 1).ToLocalChecked()->IsString());
    CHECK(elm->Get(env->context(),
                   2).ToLocalChecked()->Int32Value(env->context()).FromJust());

    int fam = elm->Get(env->context(), 0)
        .ToLocalChecked()->Int32Value(env->context()).FromJust();
    node::Utf8Value ip(env->isolate(),
                       elm->Get(env->context(), 1).ToLocalChecked());
    int port = elm->Get(env->context(), 2)
        .ToLocalChecked()->Int32Value(env->context()).FromJust();

    ares_addr_port_node* cur = &servers[i];

    cur->tcp_port = cur->udp_port = port;
    switch (fam) {
      case 4:
        cur->family = AF_INET;
        err = uv_inet_pton(AF_INET, *ip, &cur->addr);
        break;
      case 6:
        cur->family = AF_INET6;
        err = uv_inet_pton(AF_INET6, *ip, &cur->addr);
        break;
      default:
        CHECK(0 && "Bad address family.");
    }

    if (err)
      break;

    cur->next = nullptr;

    if (last != nullptr)
      last->next = cur;

    last = cur;
  }

  if (err == 0)
    err = ares_set_servers_ports(channel->cares_channel(), &servers[0]);
  else
    err = ARES_EBADSTR;

  if (err == ARES_SUCCESS)
    channel->set_is_servers_default(false);

  args.GetReturnValue().Set(err);
}

void Cancel(const FunctionCallbackInfo<Value>& args) {
  ChannelWrap* channel;
  ASSIGN_OR_RETURN_UNWRAP(&channel, args.Holder());

  TRACE_EVENT_INSTANT0(TRACING_CATEGORY_NODE2(dns, native),
      "cancel", TRACE_EVENT_SCOPE_THREAD);

  ares_cancel(channel->cares_channel());
}

const char EMSG_ESETSRVPENDING[] = "There are pending queries.";
void StrError(const FunctionCallbackInfo<Value>& args) {
  Environment* env = Environment::GetCurrent(args);
  int code = args[0]->Int32Value(env->context()).FromJust();
  const char* errmsg = (code == DNS_ESETSRVPENDING) ?
    EMSG_ESETSRVPENDING :
    ares_strerror(code);
  args.GetReturnValue().Set(OneByteString(env->isolate(), errmsg));
}


void Initialize(Local<Object> target,
                Local<Value> unused,
                Local<Context> context,
                void* priv) {
  Environment* env = Environment::GetCurrent(context);

  env->SetMethod(target, "getaddrinfo", GetAddrInfo);
  env->SetMethod(target, "getnameinfo", GetNameInfo);
  env->SetMethodNoSideEffect(target, "canonicalizeIP", CanonicalizeIP);

  env->SetMethod(target, "strerror", StrError);

  target->Set(env->context(), FIXED_ONE_BYTE_STRING(env->isolate(), "AF_INET"),
              Integer::New(env->isolate(), AF_INET)).Check();
  target->Set(env->context(), FIXED_ONE_BYTE_STRING(env->isolate(), "AF_INET6"),
              Integer::New(env->isolate(), AF_INET6)).Check();
  target->Set(env->context(), FIXED_ONE_BYTE_STRING(env->isolate(),
                                                    "AF_UNSPEC"),
              Integer::New(env->isolate(), AF_UNSPEC)).Check();
  target->Set(env->context(), FIXED_ONE_BYTE_STRING(env->isolate(),
                                                    "AI_ADDRCONFIG"),
              Integer::New(env->isolate(), AI_ADDRCONFIG)).Check();
  target->Set(env->context(), FIXED_ONE_BYTE_STRING(env->isolate(),
                                                    "AI_ALL"),
              Integer::New(env->isolate(), AI_ALL)).Check();
  target->Set(env->context(), FIXED_ONE_BYTE_STRING(env->isolate(),
                                                    "AI_V4MAPPED"),
              Integer::New(env->isolate(), AI_V4MAPPED)).Check();

  Local<FunctionTemplate> aiw =
      BaseObject::MakeLazilyInitializedJSTemplate(env);
  aiw->Inherit(AsyncWrap::GetConstructorTemplate(env));
  Local<String> addrInfoWrapString =
      FIXED_ONE_BYTE_STRING(env->isolate(), "GetAddrInfoReqWrap");
  aiw->SetClassName(addrInfoWrapString);
  target->Set(env->context(),
              addrInfoWrapString,
              aiw->GetFunction(context).ToLocalChecked()).Check();

  Local<FunctionTemplate> niw =
      BaseObject::MakeLazilyInitializedJSTemplate(env);
  niw->Inherit(AsyncWrap::GetConstructorTemplate(env));
  Local<String> nameInfoWrapString =
      FIXED_ONE_BYTE_STRING(env->isolate(), "GetNameInfoReqWrap");
  niw->SetClassName(nameInfoWrapString);
  target->Set(env->context(),
              nameInfoWrapString,
              niw->GetFunction(context).ToLocalChecked()).Check();

  Local<FunctionTemplate> qrw =
      BaseObject::MakeLazilyInitializedJSTemplate(env);
  qrw->Inherit(AsyncWrap::GetConstructorTemplate(env));
  Local<String> queryWrapString =
      FIXED_ONE_BYTE_STRING(env->isolate(), "QueryReqWrap");
  qrw->SetClassName(queryWrapString);
  target->Set(env->context(),
              queryWrapString,
              qrw->GetFunction(context).ToLocalChecked()).Check();

  Local<FunctionTemplate> channel_wrap =
      env->NewFunctionTemplate(ChannelWrap::New);
  channel_wrap->InstanceTemplate()->SetInternalFieldCount(
      ChannelWrap::kInternalFieldCount);
  channel_wrap->Inherit(AsyncWrap::GetConstructorTemplate(env));

  env->SetProtoMethod(channel_wrap, "queryAny", Query<QueryAnyWrap>);
  env->SetProtoMethod(channel_wrap, "queryA", Query<QueryAWrap>);
  env->SetProtoMethod(channel_wrap, "queryAaaa", Query<QueryAaaaWrap>);
  env->SetProtoMethod(channel_wrap, "queryCname", Query<QueryCnameWrap>);
  env->SetProtoMethod(channel_wrap, "queryMx", Query<QueryMxWrap>);
  env->SetProtoMethod(channel_wrap, "queryNs", Query<QueryNsWrap>);
  env->SetProtoMethod(channel_wrap, "queryTxt", Query<QueryTxtWrap>);
  env->SetProtoMethod(channel_wrap, "querySrv", Query<QuerySrvWrap>);
  env->SetProtoMethod(channel_wrap, "queryPtr", Query<QueryPtrWrap>);
  env->SetProtoMethod(channel_wrap, "queryNaptr", Query<QueryNaptrWrap>);
  env->SetProtoMethod(channel_wrap, "querySoa", Query<QuerySoaWrap>);
  env->SetProtoMethod(channel_wrap, "getHostByAddr", Query<GetHostByAddrWrap>);

  env->SetProtoMethodNoSideEffect(channel_wrap, "getServers", GetServers);
  env->SetProtoMethod(channel_wrap, "setServers", SetServers);
  env->SetProtoMethod(channel_wrap, "cancel", Cancel);

  Local<String> channelWrapString =
      FIXED_ONE_BYTE_STRING(env->isolate(), "ChannelWrap");
  channel_wrap->SetClassName(channelWrapString);
  target->Set(env->context(), channelWrapString,
              channel_wrap->GetFunction(context).ToLocalChecked()).Check();
}

}  // anonymous namespace
}  // namespace cares_wrap
}  // namespace node

NODE_MODULE_CONTEXT_AWARE_INTERNAL(cares_wrap, node::cares_wrap::Initialize)
