/*
 *
 *  Resolver library with GLib integration
 *
 *  Copyright (C) 2009-2013  Intel Corporation. All rights reserved.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as
 *  published by the Free Software Foundation.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <errno.h>
#include <unistd.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#include <resolv.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
#include <net/if.h>

#include "gresolv.h"

#ifdef ANDROID_COMPILE
#include <resolv_private.h>
#include <res_private.h>
#endif

struct sort_result {
	int precedence;
	int src_scope;
	int dst_scope;
	int src_label;
	int dst_label;
	bool reachable;
	union {
		struct sockaddr sa;
		struct sockaddr_in sin;
		struct sockaddr_in6 sin6;
	} src;
	union {
		struct sockaddr sa;
		struct sockaddr_in sin;
		struct sockaddr_in6 sin6;
	} dst;
};

struct resolv_query;

struct resolv_lookup {
	GResolv *resolv;
	guint id;

	int nr_results;
	struct sort_result *results;

	struct resolv_query *ipv4_query;
	struct resolv_query *ipv6_query;

	guint ipv4_status;
	guint ipv6_status;

	GResolvResultFunc result_func;
	gpointer result_data;
};

struct resolv_query {
	GResolv *resolv;

	int nr_ns;
	guint timeout;

	uint16_t msgid;

	struct resolv_lookup *lookup;
};

struct resolv_nameserver {
	GResolv *resolv;

	char *address;
	uint16_t port;
	unsigned long flags;

	GIOChannel *udp_channel;
	guint udp_watch;
};

struct _GResolv {
	int ref_count;

	int result_family;

	guint next_lookup_id;
	GQueue *lookup_queue;
	GQueue *query_queue;

	int index;
	GList *nameserver_list;

	struct __res_state res;

	GResolvDebugFunc debug_func;
	gpointer debug_data;
};

#define debug(resolv, format, arg...)				\
	_debug(resolv, strrchr("/" __FILE__, '/') + 1, __func__, format, ## arg)

static void _debug(GResolv *resolv, const char *file, const char *caller,
						const char *format, ...)
{
	char str[256];
	va_list ap;
	int len;

	if (!resolv->debug_func)
		return;

	va_start(ap, format);

	if ((len = snprintf(str, sizeof(str), "%s:%s() resolv %p ",
						file, caller, resolv)) > 0) {
		if (vsnprintf(str + len, sizeof(str) - len, format, ap) > 0)
			resolv->debug_func(str, resolv->debug_data);
	}

	va_end(ap);
}

static void destroy_query(struct resolv_query *query)
{
	debug(query->resolv, "query %p timeout handle %d", query, query->timeout);

	if (query->timeout > 0)
		g_source_remove(query->timeout);

	g_free(query);
}

static void destroy_lookup(struct resolv_lookup *lookup)
{
	debug(lookup->resolv, "lookup %p id %d ipv4 %p ipv6 %p",
		lookup, lookup->id, lookup->ipv4_query, lookup->ipv6_query);

	if (lookup->ipv4_query) {
		g_queue_remove(lookup->resolv->query_queue,
						lookup->ipv4_query);
		destroy_query(lookup->ipv4_query);
	}

	if (lookup->ipv6_query) {
		g_queue_remove(lookup->resolv->query_queue,
						lookup->ipv6_query);
		destroy_query(lookup->ipv6_query);
	}

	g_free(lookup->results);
	g_free(lookup);
}

static void find_srcaddr(struct sort_result *res)
{
	socklen_t sl = sizeof(res->src);
	int fd;

	fd = socket(res->dst.sa.sa_family, SOCK_DGRAM | SOCK_CLOEXEC,
			IPPROTO_IP);
	if (fd < 0)
		return;

	if (connect(fd, &res->dst.sa, sizeof(res->dst)) < 0) {
		close(fd);
		return;
	}

	if (getsockname(fd, &res->src.sa, &sl) < 0) {
		close(fd);
		return;
	}

	res->reachable = true;
	close(fd);
}

struct gai_table
{
	unsigned char addr[NS_IN6ADDRSZ];
	int mask;
	int value;
};

static const struct gai_table gai_labels[] = {
	{
		.addr = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
		.mask = 128,
		.value = 0,
	}, {
		.addr = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
		.mask = 16,
		.value = 2,
	}, {
		.addr = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
		.mask = 96,
		.value = 3,
	}, {
		.addr = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			  0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 },
		.mask = 96,
		.value = 4,
	}, {
		/* Variations from RFC 3484, matching glibc behaviour */
		.addr = { 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
		.mask = 10,
		.value = 5,
	}, {
		.addr = { 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
		.mask = 7,
		.value = 6,
	}, {
		.addr = { 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
		.mask = 32,
		.value = 7,
	}, {
		/* catch-all */
		.addr = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
		.mask = 0,
		.value = 1,
	}
};

static const struct gai_table gai_precedences[] = {
	{
		.addr = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
		.mask = 128,
		.value = 50,
	}, {
		.addr = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
		.mask = 16,
		.value = 30,
	}, {
		.addr = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
		.mask = 96,
		.value = 20,
	}, {
		.addr = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			  0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 },
		.mask = 96,
		.value = 10,
	}, {
		.addr = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
		.mask = 0,
		.value = 40,
	}
};

static unsigned char v4mapped[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
				    0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 };

static bool mask_compare(const unsigned char *one,
					const unsigned char *two, int mask)
{
	if (mask > 8) {
		if (memcmp(one, two, mask / 8))
			return false;
		one += mask / 8;
		two += mask / 8;
		mask %= 8;
	}

	if (mask && ((*one ^ *two) >> (8 - mask)))
		return false;

	return true;
}

static int match_gai_table(struct sockaddr *sa, const struct gai_table *tbl)
{
	struct sockaddr_in *sin = (void *)sa;
	struct sockaddr_in6 *sin6 = (void *)sa;
	void *addr;

	if (sa->sa_family == AF_INET) {
		addr = v4mapped;
		memcpy(v4mapped+12, &sin->sin_addr, NS_INADDRSZ);
	} else
		addr = &sin6->sin6_addr;

	while (1) {
		if (mask_compare(addr, tbl->addr, tbl->mask))
			return tbl->value;
		tbl++;
	}
}

#define DQUAD(_a,_b,_c,_d) ( ((_a)<<24) | ((_b)<<16) | ((_c)<<8) | (_d) )
#define V4MATCH(addr, a,b,c,d, m) ( !(((addr) ^ DQUAD(a,b,c,d)) >> (32 - (m))) )

#define RFC3484_SCOPE_LINK	2
#define RFC3484_SCOPE_SITE	5
#define RFC3484_SCOPE_GLOBAL	14

static int addr_scope(struct sockaddr *sa)
{
	if (sa->sa_family == AF_INET) {
		struct sockaddr_in *sin = (void *)sa;
		guint32 addr = ntohl(sin->sin_addr.s_addr);

		if (V4MATCH(addr, 169,254,0,0, 16) ||
					V4MATCH(addr, 127,0,0,0, 8))
			return RFC3484_SCOPE_LINK;

		/* Site-local */
		if (V4MATCH(addr, 10,0,0,0, 8) ||
				V4MATCH(addr, 172,16,0,0, 12) ||
				V4MATCH(addr, 192,168,0,0, 16))
			return RFC3484_SCOPE_SITE;

		/* Global */
		return RFC3484_SCOPE_GLOBAL;
	} else {
		struct sockaddr_in6 *sin6 = (void *)sa;

		/* Multicast addresses have a 4-bit scope field */
		if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))
			return sin6->sin6_addr.s6_addr[1] & 0xf;

		if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) ||
				IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr))
			return RFC3484_SCOPE_LINK;

		if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))
			return RFC3484_SCOPE_SITE;

		return RFC3484_SCOPE_GLOBAL;
	}
}

static int rfc3484_compare(const void *__one, const void *__two)
{
	const struct sort_result *one = __one;
	const struct sort_result *two = __two;

	/* Rule 1: Avoid unusable destinations */
	if (one->reachable && !two->reachable)
		return -1;
	else if (two->reachable && !one->reachable)
		return 1;

	/* Rule 2: Prefer matching scope */
	if (one->dst_scope == one->src_scope &&
				two->dst_scope != two->src_scope)
		return -1;
	else if (two->dst_scope == two->src_scope &&
				one->dst_scope != one->src_scope)
		return 1;

	/* Rule 3: Avoid deprecated addresses */

	/* Rule 4: Prefer home addresses */

	/* Rule 5: Prefer matching label */
	if (one->dst_label == one->src_label &&
				two->dst_label != two->src_label)
		return -1;
	else if (two->dst_label == two->src_label &&
				one->dst_label != one->src_label)
		return 1;

	/* Rule 6: Prefer higher precedence */
	if (one->precedence > two->precedence)
		return -1;
	else if (two->precedence > one->precedence)
		return 1;

	/* Rule 7: Prefer native transport */

	/* Rule 8: Prefer smaller scope */
	if (one->dst_scope != two->dst_scope)
		return one->dst_scope - two->dst_scope;

	/* Rule 9: Use longest matching prefix */
	if (one->dst.sa.sa_family == AF_INET) {
		/*
		 * Rule 9 is meaningless and counterproductive for Legacy IP
		 * unless perhaps we can tell that it's actually on the local
		 * subnet. But we don't (yet) have local interface config
		 * information, so do nothing here for Legacy IP for now.
		 */
	} else {
		int i;

		for (i = 0; i < 4; i++) {
			guint32 cmp_one, cmp_two;

			cmp_one = one->src.sin6.sin6_addr.s6_addr32[i] ^
					one->dst.sin6.sin6_addr.s6_addr32[i];
			cmp_two = two->src.sin6.sin6_addr.s6_addr32[i] ^
					two->dst.sin6.sin6_addr.s6_addr32[i];

			if (!cmp_two && !cmp_one)
				continue;

			if (cmp_one && !cmp_two)
				return 1;
			if (cmp_two && !cmp_one)
				return -1;

			/* g_bit_storage() is effectively fls() */
			cmp_one = g_bit_storage(ntohl(cmp_one));
			cmp_two = g_bit_storage(ntohl(cmp_two));

			if (cmp_one == cmp_two)
				break;

			return cmp_one - cmp_two;
		}
	}


	/* Rule 10: Otherwise, leave the order unchanged */
	if (one < two)
		return -1;
	else
		return 1;
}

static void rfc3484_sort_results(struct resolv_lookup *lookup)
{
	int i;

	for (i = 0; i < lookup->nr_results; i++) {
		struct sort_result *res = &lookup->results[i];
		find_srcaddr(res);
		res->precedence = match_gai_table(&res->dst.sa,
							gai_precedences);
		res->dst_label = match_gai_table(&res->dst.sa, gai_labels);
		res->src_label = match_gai_table(&res->src.sa, gai_labels);
		res->dst_scope = addr_scope(&res->dst.sa);
		res->src_scope = addr_scope(&res->src.sa);
	}

	qsort(lookup->results, lookup->nr_results,
			sizeof(struct sort_result), rfc3484_compare);
}

static void sort_and_return_results(struct resolv_lookup *lookup)
{
	char buf[INET6_ADDRSTRLEN + 1];
	GResolvResultStatus status;
	char **results = g_try_new0(char *, lookup->nr_results + 1);
	GResolvResultFunc result_func = lookup->result_func;
	void *result_data = lookup->result_data;
	int i, n = 0;

	if (!results)
		return;

	memset(buf, 0, INET6_ADDRSTRLEN + 1);

	rfc3484_sort_results(lookup);

	for (i = 0; i < lookup->nr_results; i++) {
		if (lookup->results[i].dst.sa.sa_family == AF_INET) {
			if (!inet_ntop(AF_INET,
					&lookup->results[i].dst.sin.sin_addr,
					buf, sizeof(buf) - 1))
				continue;
		} else if (lookup->results[i].dst.sa.sa_family == AF_INET6) {
			if (!inet_ntop(AF_INET6,
					&lookup->results[i].dst.sin6.sin6_addr,
					buf, sizeof(buf) - 1))
				continue;
		} else
			continue;

		results[n++] = g_strdup(buf);
	}

	results[n++] = NULL;

	if (lookup->resolv->result_family == AF_INET)
		status = lookup->ipv4_status;
	else if (lookup->resolv->result_family == AF_INET6)
		status = lookup->ipv6_status;
	else {
		if (lookup->ipv6_status == G_RESOLV_RESULT_STATUS_SUCCESS)
			status = lookup->ipv6_status;
		else
			status = lookup->ipv4_status;
	}

	debug(lookup->resolv, "lookup %p received %d results", lookup, n);

	g_queue_remove(lookup->resolv->lookup_queue, lookup);
	destroy_lookup(lookup);

	result_func(status, results, result_data);

	g_strfreev(results);
}

static gboolean query_timeout(gpointer user_data)
{
	struct resolv_query *query = user_data;
	struct resolv_lookup *lookup = query->lookup;
	GResolv *resolv = query->resolv;

	debug(resolv, "lookup %p id %d", lookup, lookup->id);

	query->timeout = 0;

	if (query == lookup->ipv4_query) {
		lookup->ipv4_status = G_RESOLV_RESULT_STATUS_NO_RESPONSE;
		lookup->ipv4_query = NULL;
	} else if (query == lookup->ipv6_query) {
		lookup->ipv6_status = G_RESOLV_RESULT_STATUS_NO_RESPONSE;
		lookup->ipv6_query = NULL;
	}

	g_queue_remove(resolv->query_queue, query);
	destroy_query(query);

	if (!lookup->ipv4_query && !lookup->ipv6_query)
		sort_and_return_results(lookup);

	return FALSE;
}

static void free_nameserver(struct resolv_nameserver *nameserver)
{
	if (!nameserver)
		return;

	debug(nameserver->resolv, "free nameserver %s", nameserver->address);

	if (nameserver->udp_watch > 0)
		g_source_remove(nameserver->udp_watch);

	if (nameserver->udp_channel) {
		g_io_channel_shutdown(nameserver->udp_channel, TRUE, NULL);
		g_io_channel_unref(nameserver->udp_channel);
	}

	g_free(nameserver->address);
	g_free(nameserver);
}

static void flush_nameservers(GResolv *resolv)
{
	GList *list;

	for (list = g_list_first(resolv->nameserver_list);
					list; list = g_list_next(list))
		free_nameserver(list->data);

	g_list_free(resolv->nameserver_list);
	resolv->nameserver_list = NULL;
}

static int send_query(GResolv *resolv, const unsigned char *buf, int len)
{
	GList *list;
	int nr_ns;

	if (!resolv->nameserver_list) {
		debug(resolv, "NULL nameserver_list");
		return -ENOENT;
	}

	for (list = g_list_first(resolv->nameserver_list), nr_ns = 0;
				list; list = g_list_next(list), nr_ns++) {
		struct resolv_nameserver *nameserver = list->data;
		int sk, sent;

		if (!nameserver->udp_channel) {
			debug(resolv, "NULL udp_channel for nameserver %s", nameserver->address);
			continue;
		}

		sk = g_io_channel_unix_get_fd(nameserver->udp_channel);

		sent = send(sk, buf, len, 0);
		if (sent < 0) {
			debug(resolv, "send failed to nameserver %s, sent %d, sk %d",
				nameserver->address, sent);
			continue;
		} else if (sent != len) {
			debug(resolv, "sent different size to nameserver %s, sent %d ", nameserver->address, sent);
		} else {
			debug(resolv, "send to nameserver %s sk %d OK", nameserver->address, sk);
		}
	}

	return nr_ns;
}

static gint compare_lookup_id(gconstpointer a, gconstpointer b)
{
	const struct resolv_lookup *lookup = a;
	guint id = GPOINTER_TO_UINT(b);

	if (lookup->id < id)
		return -1;

	if (lookup->id > id)
		return 1;

	return 0;
}

static gint compare_query_msgid(gconstpointer a, gconstpointer b)
{
	const struct resolv_query *query = a;
	uint16_t msgid = GPOINTER_TO_UINT(b);

	if (query->msgid < msgid)
		return -1;

	if (query->msgid > msgid)
		return 1;

	return 0;
}

static void add_result(struct resolv_lookup *lookup, int family,
							const void *data)
{
	int n = lookup->nr_results++;
	lookup->results = g_try_realloc(lookup->results,
					sizeof(struct sort_result) * (n + 1));
	if (!lookup->results)
		return;

	memset(&lookup->results[n], 0, sizeof(struct sort_result));

	lookup->results[n].dst.sa.sa_family = family;
	if (family == AF_INET)
		memcpy(&lookup->results[n].dst.sin.sin_addr,
						data, NS_INADDRSZ);
	else
		memcpy(&lookup->results[n].dst.sin6.sin6_addr,
						data, NS_IN6ADDRSZ);
}

static void parse_response(struct resolv_nameserver *nameserver,
					const unsigned char *buf, int len)
{
	GResolv *resolv = nameserver->resolv;
	GResolvResultStatus status;
	struct resolv_query *query;
	struct resolv_lookup *lookup;
	GList *list;
	ns_msg msg;
	ns_rr rr;
	int i, rcode, count;

	debug(resolv, "response from %s", nameserver->address);

	if (ns_initparse(buf, len, &msg) < 0) {
		debug(resolv, "ns_initparse failed");
		return;
	}

	list = g_queue_find_custom(resolv->query_queue,
			GUINT_TO_POINTER(ns_msg_id(msg)), compare_query_msgid);
	if (!list) {
		debug(resolv, "can't find matching query");
		return;
	}

	rcode = ns_msg_getflag(msg, ns_f_rcode);
	count = ns_msg_count(msg, ns_s_an);

	debug(resolv, "msg id: 0x%04x rcode: %d count: %d",
					ns_msg_id(msg), rcode, count);

	switch (rcode) {
	case ns_r_noerror:
		status = G_RESOLV_RESULT_STATUS_SUCCESS;
		break;
	case ns_r_formerr:
		status = G_RESOLV_RESULT_STATUS_FORMAT_ERROR;
		break;
	case ns_r_servfail:
		status = G_RESOLV_RESULT_STATUS_SERVER_FAILURE;
		break;
	case ns_r_nxdomain:
		status = G_RESOLV_RESULT_STATUS_NAME_ERROR;
		break;
	case ns_r_notimpl:
		status = G_RESOLV_RESULT_STATUS_NOT_IMPLEMENTED;
		break;
	case ns_r_refused:
		status = G_RESOLV_RESULT_STATUS_REFUSED;
		break;
	default:
		status = G_RESOLV_RESULT_STATUS_ERROR;
		break;
	}

	query = list->data;
	query->nr_ns--;

	lookup = query->lookup;

	if (query == lookup->ipv6_query)
		lookup->ipv6_status = status;
	else if (query == lookup->ipv4_query)
		lookup->ipv4_status = status;

	for (i = 0; i < count; i++) {
		if (ns_parserr(&msg, ns_s_an, i, &rr) < 0)
			continue;

		if (ns_rr_class(rr) != ns_c_in)
			continue;

		g_assert(offsetof(struct sockaddr_in, sin_addr) ==
				offsetof(struct sockaddr_in6, sin6_flowinfo));

		if (ns_rr_type(rr) == ns_t_a &&
					ns_rr_rdlen(rr) == NS_INADDRSZ) {
			add_result(lookup, AF_INET, ns_rr_rdata(rr));
		} else if (ns_rr_type(rr) == ns_t_aaaa &&
					ns_rr_rdlen(rr) == NS_IN6ADDRSZ) {
			add_result(lookup, AF_INET6, ns_rr_rdata(rr));
		}
	}

	if (status != G_RESOLV_RESULT_STATUS_SUCCESS && query->nr_ns > 0) {
		debug(resolv, "status %d nr_ns %d", status, query->nr_ns);
		return;
	}

	if (query == lookup->ipv6_query)
		lookup->ipv6_query = NULL;
	else
		lookup->ipv4_query = NULL;

	g_queue_remove(resolv->query_queue, query);
	destroy_query(query);

	if (!lookup->ipv4_query && !lookup->ipv6_query)
		sort_and_return_results(lookup);
}

static gboolean received_udp_data(GIOChannel *channel, GIOCondition cond,
							gpointer user_data)
{
	struct resolv_nameserver *nameserver = user_data;
	unsigned char buf[4096];
	int sk, len;

	if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
		nameserver->udp_watch = 0;
		return FALSE;
	}

	sk = g_io_channel_unix_get_fd(nameserver->udp_channel);

	len = recv(sk, buf, sizeof(buf), 0);
	if (len < 12)
		return TRUE;

	parse_response(nameserver, buf, len);

	return TRUE;
}

static int connect_udp_channel(struct resolv_nameserver *nameserver)
{
	struct addrinfo hints, *rp;
	char portnr[6];
	int err, sk, opt = 1/* boolean */;

	memset(&hints, 0, sizeof(hints));
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_DGRAM;
	hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV | AI_NUMERICHOST;

	sprintf(portnr, "%d", nameserver->port);
	err = getaddrinfo(nameserver->address, portnr, &hints, &rp);
	if (err) {
		debug(nameserver->resolv, "getaddrinfo failed");
		return -EINVAL;
	}

	/*
	 * Do not blindly copy this code elsewhere; it doesn't loop over the
	 * results using ->ai_next as it should. That's OK in *this* case
	 * because it was a numeric lookup; we *know* there's only one.
	 */
	if (!rp) {
		debug(nameserver->resolv, "rp is NULL");
		return -EINVAL;
	}

	sk = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
	if (sk < 0) {
		debug(nameserver->resolv, "create socket failed");
		freeaddrinfo(rp);
		return -EIO;
	}

	debug(nameserver->resolv, "created sk %d for nameserver %s", sk, nameserver->address);

	if (setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
		debug(nameserver->resolv, "set sk option SO_REUSEADDR failed");
		close(sk);
		freeaddrinfo(rp);
		return -EIO;
	}

	/*
	 * If nameserver points to localhost ip, their is no need to
	 * bind the socket on any interface.
	 */
	if (nameserver->resolv->index > 0 &&
			strncmp(nameserver->address, "127.0.0.1", 9) != 0) {
		char interface[IF_NAMESIZE];

		memset(interface, 0, IF_NAMESIZE);
		if (if_indextoname(nameserver->resolv->index, interface)) {
			debug(nameserver->resolv, "binding to interface %s", interface);
			if (setsockopt(sk, SOL_SOCKET, SO_BINDTODEVICE,
						interface, IF_NAMESIZE) < 0) {
				debug(nameserver->resolv, "bind to interface %s failed", interface);
				close(sk);
				freeaddrinfo(rp);
				return -EIO;
			}
		}
	}

	if (connect(sk, rp->ai_addr, rp->ai_addrlen) < 0) {
		debug(nameserver->resolv, "connect sk failed");
		close(sk);
		freeaddrinfo(rp);
		return -EIO;
	}

	freeaddrinfo(rp);

	nameserver->udp_channel = g_io_channel_unix_new(sk);
	if (!nameserver->udp_channel) {
		debug(nameserver->resolv, "allocate udp_channel failed");
		close(sk);
		return -ENOMEM;
	}

	g_io_channel_set_close_on_unref(nameserver->udp_channel, TRUE);

	nameserver->udp_watch = g_io_add_watch(nameserver->udp_channel,
				G_IO_IN | G_IO_NVAL | G_IO_ERR | G_IO_HUP,
				received_udp_data, nameserver);

	return 0;
}

GResolv *g_resolv_new(int index)
{
	GResolv *resolv;

	if (index < 0)
		return NULL;

	resolv = g_try_new0(GResolv, 1);
	if (!resolv)
		return NULL;

	resolv->ref_count = 1;

	resolv->result_family = AF_INET;

	resolv->next_lookup_id = 1;

	resolv->query_queue = g_queue_new();
	if (!resolv->query_queue) {
		g_free(resolv);
		return NULL;
	}

	resolv->lookup_queue = g_queue_new();
	if (!resolv->lookup_queue) {
		g_queue_free(resolv->query_queue);
		g_free(resolv);
		return NULL;
	}

	resolv->index = index;
	resolv->nameserver_list = NULL;

	res_ninit(&resolv->res);

	return resolv;
}

GResolv *g_resolv_ref(GResolv *resolv)
{
	if (!resolv)
		return NULL;

	__sync_fetch_and_add(&resolv->ref_count, 1);

	return resolv;
}

void g_resolv_unref(GResolv *resolv)
{
	struct resolv_query *query;
	struct resolv_lookup *lookup;

	if (!resolv)
		return;

	if (__sync_fetch_and_sub(&resolv->ref_count, 1) != 1)
		return;

	while ((lookup = g_queue_pop_head(resolv->lookup_queue))) {
		debug(resolv, "lookup %p id %d", lookup, lookup->id);
		destroy_lookup(lookup);
	}

	while ((query = g_queue_pop_head(resolv->query_queue))) {
		debug(resolv, "query %p", query);
		destroy_query(query);
	}

	g_queue_free(resolv->query_queue);
	g_queue_free(resolv->lookup_queue);

	flush_nameservers(resolv);

	res_nclose(&resolv->res);

	g_free(resolv);
}

void g_resolv_set_debug(GResolv *resolv, GResolvDebugFunc func,
						gpointer user_data)
{
	if (!resolv)
		return;

	resolv->debug_func = func;
	resolv->debug_data = user_data;
}

bool g_resolv_add_nameserver(GResolv *resolv, const char *address,
					uint16_t port, unsigned long flags)
{
	struct resolv_nameserver *nameserver;

	if (!resolv)
		return false;

	nameserver = g_try_new0(struct resolv_nameserver, 1);
	if (!nameserver) {
		debug(resolv, "allocate nameserver struct failed");
		return false;
	}

	nameserver->address = g_strdup(address);
	nameserver->port = port;
	nameserver->flags = flags;
	nameserver->resolv = resolv;

	if (connect_udp_channel(nameserver) < 0) {
		debug(resolv, "connect_udp_channel nameserver %s failed", address);
		free_nameserver(nameserver);
		return false;
	}

	resolv->nameserver_list = g_list_append(resolv->nameserver_list,
								nameserver);

	debug(resolv, "setting nameserver %s", address);

	return true;
}

void g_resolv_flush_nameservers(GResolv *resolv)
{
	if (!resolv)
		return;

	flush_nameservers(resolv);
}

static gint add_query(struct resolv_lookup *lookup, const char *hostname, int type)
{
	struct resolv_query *query = g_try_new0(struct resolv_query, 1);
	unsigned char buf[4096];
	int len;

	if (!query) {
		debug(lookup->resolv, "allocate query struct failed");
		return -ENOMEM;
	}

	len = res_mkquery(ns_o_query, hostname, ns_c_in, type,
					NULL, 0, NULL, buf, sizeof(buf));

	query->msgid = buf[0] << 8 | buf[1];

	debug(lookup->resolv, "sending %d bytes type %d", len, type);

	query->nr_ns = send_query(lookup->resolv, buf, len);
	if (query->nr_ns <= 0) {
		debug(lookup->resolv, "send_query failed, nr_ns=%d", query->nr_ns);
		g_free(query);
		return -EIO;
	}

	query->resolv = lookup->resolv;
	query->lookup = lookup;

	g_queue_push_tail(lookup->resolv->query_queue, query);

	debug(lookup->resolv, "lookup %p id %d query %p", lookup, lookup->id,
									query);

	query->timeout = g_timeout_add_seconds(5, query_timeout, query);

	if (type == ns_t_aaaa)
		lookup->ipv6_query = query;
	else
		lookup->ipv4_query = query;

	return 0;
}

guint g_resolv_lookup_hostname(GResolv *resolv, const char *hostname,
				GResolvResultFunc func, gpointer user_data)
{
	struct resolv_lookup *lookup;

	if (!resolv)
		return 0;

	debug(resolv, "hostname %s", hostname);

	if (!resolv->nameserver_list) {
		int i;

		for (i = 0; i < resolv->res.nscount; i++) {
			char buf[100];
			int family = resolv->res.nsaddr_list[i].sin_family;
			void *sa_addr = &resolv->res.nsaddr_list[i].sin_addr;

			if (family != AF_INET &&
#ifdef ANDROID_COMPILE
				&resolv->res._u._ext.ext->nsaddrs[i].sin6
#else
				resolv->res._u._ext.nsaddrs[i]
#endif
			   )
			{
				family = AF_INET6;
#ifdef ANDROID_COMPILE
				sa_addr = &resolv->res._u._ext.ext->nsaddrs[i].sin6;
#else
				sa_addr = &resolv->res._u._ext.nsaddrs[i]->sin6_addr;
#endif
			}

			if (family != AF_INET && family != AF_INET6)
				continue;

			if (inet_ntop(family, sa_addr, buf, sizeof(buf)))
				g_resolv_add_nameserver(resolv, buf, 53, 0);
		}

		if (!resolv->nameserver_list)
			g_resolv_add_nameserver(resolv, "127.0.0.1", 53, 0);
	}

	lookup = g_try_new0(struct resolv_lookup, 1);
	if (!lookup)
		return 0;

	lookup->resolv = resolv;
	lookup->result_func = func;
	lookup->result_data = user_data;
	lookup->id = resolv->next_lookup_id++;

	if (resolv->result_family != AF_INET6) {
		if (add_query(lookup, hostname, ns_t_a)) {
			g_free(lookup);
			return -EIO;
		}
	}

	if (resolv->result_family != AF_INET) {
		if (add_query(lookup, hostname, ns_t_aaaa)) {
			if (resolv->result_family != AF_INET6) {
				g_queue_remove(resolv->query_queue,
						lookup->ipv4_query);
				destroy_query(lookup->ipv4_query);
			}

			g_free(lookup);
			return -EIO;
		}
	}

	g_queue_push_tail(resolv->lookup_queue, lookup);

	debug(resolv, "lookup %p id %d", lookup, lookup->id);

	return lookup->id;
}

bool g_resolv_cancel_lookup(GResolv *resolv, guint id)
{
	struct resolv_lookup *lookup;
	GList *list;

	debug(resolv, "lookup id %d", id);

	list = g_queue_find_custom(resolv->lookup_queue,
				GUINT_TO_POINTER(id), compare_lookup_id);

	if (!list)
		return false;

	lookup = list->data;

	debug(resolv, "lookup %p", lookup);

	g_queue_remove(resolv->lookup_queue, lookup);
	destroy_lookup(lookup);

	return true;
}

bool g_resolv_set_address_family(GResolv *resolv, int family)
{
	if (!resolv)
		return false;

	if (family != AF_UNSPEC && family != AF_INET && family != AF_INET6)
		return false;

	resolv->result_family = family;

	return true;
}
