// Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "shill/shill_ares.h"

namespace shill {

static base::LazyInstance<Ares> g_ares(base::LINKER_INITIALIZED);

Ares::Ares() { }

Ares::~Ares() { }

Ares* Ares::GetInstance() {
  return g_ares.Pointer();
}

void Ares::Destroy(ares_channel channel) {
  ares_destroy(channel);
}

void Ares::GetHostByName(ares_channel channel,
                         const char *hostname,
                         int family,
                         ares_host_callback callback,
                         void *arg) {
  ares_gethostbyname(channel, hostname, family, callback, arg);
}

int Ares::GetSock(ares_channel channel,
                  ares_socket_t *socks,
                  int numsocks) {
  return ares_getsock(channel, socks, numsocks);
}

int Ares::InitOptions(ares_channel *channelptr,
                      struct ares_options *options,
                      int optmask) {
  return ares_init_options(channelptr, options, optmask);
}


void Ares::ProcessFd(ares_channel channel,
                     ares_socket_t read_fd,
                     ares_socket_t write_fd) {
  return ares_process_fd(channel, read_fd, write_fd);
}

void Ares::SetLocalDev(ares_channel channel, const char *local_dev_name) {
  ares_set_local_dev(channel, local_dev_name);
}

struct timeval *Ares::Timeout(ares_channel channel,
                              struct timeval *maxtv,
                              struct timeval *tv) {
  return ares_timeout(channel, maxtv, tv);
}

}  // namespace shill
