/*
 *
 *  Connection Manager
 *
 *  Copyright (C) 2007-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

#define _GNU_SOURCE
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
#include <resolv.h>
#include <netdb.h>
#ifdef ANDROID_COMPILE
#include <resolv_params.h>
#endif

#include "connman.h"

#define RESOLVER_FLAG_PUBLIC (1 << 0)

/*
 * Threshold for RDNSS lifetime. Will be used to trigger RS
 * before RDNSS entries actually expire
 */
#define RESOLVER_LIFETIME_REFRESH_THRESHOLD 0.8

struct entry_data {
	int index;
	char *domain;
	char *server;
	int family;
	unsigned int flags;
	unsigned int lifetime;
	guint timeout;
};

static GSList *entry_list = NULL;
static bool dnsproxy_enabled = false;

struct resolvfile_entry {
	int index;
	char *domain;
	char *server;
};

static GList *resolvfile_list = NULL;

static void resolvfile_remove_entries(GList *entries)
{
	GList *list;

	for (list = entries; list; list = list->next) {
		struct resolvfile_entry *entry = list->data;

		resolvfile_list = g_list_remove(resolvfile_list, entry);

		g_free(entry->server);
		g_free(entry->domain);
		g_free(entry);
	}

	g_list_free(entries);
}

static int resolvfile_export(void)
{
	GList *list;
	GString *content;
	int fd, err;
	unsigned int count;
	mode_t old_umask;

	content = g_string_new("# Generated by Connection Manager\n");

	/*
	 * Domains and nameservers are added in reverse so that the most
	 * recently appended entry is the primary one. No more than
	 * MAXDNSRCH/MAXNS entries are used.
	 */

	for (count = 0, list = g_list_last(resolvfile_list);
						list && (count < MAXDNSRCH);
						list = g_list_previous(list)) {
		struct resolvfile_entry *entry = list->data;

		if (!entry->domain)
			continue;

		if (count == 0)
			g_string_append_printf(content, "search ");

		g_string_append_printf(content, "%s ", entry->domain);
		count++;
	}

	if (count)
		g_string_append_printf(content, "\n");

	for (count = 0, list = g_list_last(resolvfile_list);
						list && (count < MAXNS);
						list = g_list_previous(list)) {
		struct resolvfile_entry *entry = list->data;

		if (!entry->server)
			continue;

		g_string_append_printf(content, "nameserver %s\n",
								entry->server);
		count++;
	}

	old_umask = umask(022);

	fd = open("/etc/resolv.conf", O_RDWR | O_CREAT | O_CLOEXEC,
					S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
	if (fd < 0) {
		err = -errno;
		goto done;
	}

	if (ftruncate(fd, 0) < 0) {
		err = -errno;
		goto failed;
	}

	err = 0;

	if (write(fd, content->str, content->len) < 0)
		err = -errno;

failed:
	close(fd);

done:
	g_string_free(content, TRUE);
	umask(old_umask);

	return err;
}

int __connman_resolvfile_append(int index, const char *domain,
							const char *server)
{
	struct resolvfile_entry *entry;

	DBG("index %d server %s", index, server);

	if (index < 0)
		return -ENOENT;

	entry = g_try_new0(struct resolvfile_entry, 1);
	if (!entry)
		return -ENOMEM;

	entry->index = index;
	entry->domain = g_strdup(domain);
	entry->server = g_strdup(server);

	resolvfile_list = g_list_append(resolvfile_list, entry);

	return resolvfile_export();
}

int __connman_resolvfile_remove(int index, const char *domain,
							const char *server)
{
	GList *list, *matches = NULL;

	DBG("index %d server %s", index, server);

	for (list = resolvfile_list; list; list = g_list_next(list)) {
		struct resolvfile_entry *entry = list->data;

		if (index >= 0 && entry->index != index)
			continue;

		if (domain && g_strcmp0(entry->domain, domain) != 0)
			continue;

		if (g_strcmp0(entry->server, server) != 0)
			continue;

		matches = g_list_append(matches, entry);
	}

	resolvfile_remove_entries(matches);

	return resolvfile_export();
}

static void append_fallback_nameservers(void)
{
	GSList *list;

	for (list = entry_list; list; list = list->next) {
		struct entry_data *entry = list->data;

		if (entry->index >= 0 && entry->server)
			return;
	}

	for (list = entry_list; list; list = list->next) {
		struct entry_data *entry = list->data;

		if (entry->index != -1 || !entry->server)
			continue;

		DBG("index %d server %s", entry->index, entry->server);

		if (dnsproxy_enabled) {
			__connman_dnsproxy_append(entry->index, entry->domain,
					entry->server);
		} else {
			__connman_resolvfile_append(entry->index,
					entry->domain, entry->server);
		}
	}
}

static void remove_fallback_nameservers(void)
{
	GSList *list;

	for (list = entry_list; list; list = list->next) {
		struct entry_data *entry = list->data;

		if (entry->index >= 0 || !entry->server)
			continue;

		DBG("index %d server %s", entry->index, entry->server);

		if (dnsproxy_enabled) {
			__connman_dnsproxy_remove(entry->index, entry->domain,
					entry->server);
		} else {
			__connman_resolvfile_remove(entry->index,
					entry->domain, entry->server);
		}
	}
}

static void remove_entries(GSList *entries)
{
	GSList *list;

	for (list = entries; list; list = list->next) {
		struct entry_data *entry = list->data;

		entry_list = g_slist_remove(entry_list, entry);

		if (dnsproxy_enabled) {
			__connman_dnsproxy_remove(entry->index, entry->domain,
							entry->server);
		} else {
			__connman_resolvfile_remove(entry->index, entry->domain,
							entry->server);
		}

		if (entry->timeout)
			g_source_remove(entry->timeout);
		g_free(entry->server);
		g_free(entry->domain);
		g_free(entry);
	}

	g_slist_free(entries);

	append_fallback_nameservers();
}

static gboolean resolver_expire_cb(gpointer user_data)
{
	struct entry_data *entry = user_data;
	GSList *list;

	DBG("index %d domain %s server %s",
			entry->index, entry->domain, entry->server);

	list = g_slist_prepend(NULL, entry);

	if (entry->index >= 0) {
		struct connman_service *service;
		service = __connman_service_lookup_from_index(entry->index);
		if (service)
			__connman_service_nameserver_remove(service,
							entry->server, true);
	}

	remove_entries(list);

	return FALSE;
}

static gboolean resolver_refresh_cb(gpointer user_data)
{
	struct entry_data *entry = user_data;
	unsigned int interval;
	struct connman_service *service = NULL;

	/* Round up what we have left from lifetime */
	interval = entry->lifetime *
		(1 - RESOLVER_LIFETIME_REFRESH_THRESHOLD) + 1.0;

	DBG("RDNSS start index %d domain %s "
			"server %s remaining lifetime %d",
			entry->index, entry->domain,
			entry->server, interval);

	entry->timeout = g_timeout_add_seconds(interval,
			resolver_expire_cb, entry);

	if (entry->index >= 0) {
		service = __connman_service_lookup_from_index(entry->index);
		if (service) {
			/*
			 * Send Router Solicitation to refresh RDNSS entries
			 * before their lifetime expires
			 */
			__connman_network_refresh_rs_ipv6(
					__connman_service_get_network(service),
					entry->index);
		}
	}
	return FALSE;
}

static int append_resolver(int index, const char *domain,
				const char *server, unsigned int lifetime,
							unsigned int flags)
{
	struct entry_data *entry;
	unsigned int interval;

	DBG("index %d domain %s server %s lifetime %d flags %d",
				index, domain, server, lifetime, flags);

	if (!server && !domain)
		return -EINVAL;

	entry = g_try_new0(struct entry_data, 1);
	if (!entry)
		return -ENOMEM;

	entry->index = index;
	entry->domain = g_strdup(domain);
	entry->server = g_strdup(server);
	entry->flags = flags;
	entry->lifetime = lifetime;

	if (server)
		entry->family = connman_inet_check_ipaddress(server);

	if (lifetime) {
		interval = lifetime * RESOLVER_LIFETIME_REFRESH_THRESHOLD;

		DBG("RDNSS start index %d domain %s "
				"server %s lifetime threshold %d",
				index, domain, server, interval);

		if (lifetime != LIFETIME_INFINITY)
			/* RFC5006 (0xffffffff) represents infinity.*/
			entry->timeout = g_timeout_add_seconds(interval,
				resolver_refresh_cb, entry);

		/*
		 * We update the service only for those nameservers
		 * that are automagically added via netlink (lifetime > 0)
		 */
		if (server && entry->index >= 0) {
			struct connman_service *service;
			service = __connman_service_lookup_from_index(entry->index);
			if (service)
				__connman_service_nameserver_append(service,
								server, false);
		}
	}

	if (entry->index >= 0 && entry->server)
		remove_fallback_nameservers();

	entry_list = g_slist_append(entry_list, entry);

	if (dnsproxy_enabled)
		__connman_dnsproxy_append(entry->index, domain, server);
	else
		__connman_resolvfile_append(entry->index, domain, server);

	return 0;
}

/**
 * connman_resolver_append:
 * @index: network interface index
 * @domain: domain limitation
 * @server: server address
 *
 * Append resolver server address to current list
 */
int connman_resolver_append(int index, const char *domain,
						const char *server)
{
	GSList *list;

	DBG("index %d domain %s server %s", index, domain, server);

	if (!server && !domain)
		return -EINVAL;

	for (list = entry_list; list; list = list->next) {
		struct entry_data *entry = list->data;

		if (entry->timeout > 0)
			continue;

		if (entry->index == index &&
				g_strcmp0(entry->domain, domain) == 0 &&
				g_strcmp0(entry->server, server) == 0) {
			if (dnsproxy_enabled)
				__connman_dnsproxy_append(entry->index, domain,
						server);

			return -EEXIST;
		}
	}

	return append_resolver(index, domain, server, 0, 0);
}

/**
 * connman_resolver_append_lifetime:
 * @index: network interface index
 * @domain: domain limitation
 * @server: server address
 * @timeout: server lifetime in seconds
 *
 * Append resolver server address to current list
 */
int connman_resolver_append_lifetime(int index, const char *domain,
				const char *server, unsigned int lifetime)
{
	GSList *list;
	unsigned int interval;

	DBG("index %d domain %s server %s lifetime %d",
				index, domain, server, lifetime);

	if (!server && !domain)
		return -EINVAL;

	for (list = entry_list; list; list = list->next) {
		struct entry_data *entry = list->data;

		if (entry->timeout == 0 ||
				entry->index != index ||
				g_strcmp0(entry->domain, domain) != 0 ||
				g_strcmp0(entry->server, server) != 0)
			continue;

		g_source_remove(entry->timeout);

		if (lifetime == 0) {
			resolver_expire_cb(entry);
			return 0;
		}

		interval = lifetime * RESOLVER_LIFETIME_REFRESH_THRESHOLD;

		DBG("RDNSS start index %d domain %s "
				"server %s lifetime threshold %d",
				index, domain, server, interval);

		if (lifetime != LIFETIME_INFINITY)
			entry->timeout = g_timeout_add_seconds(interval,
				resolver_refresh_cb, entry);
		return 0;
	}

	return append_resolver(index, domain, server, lifetime, 0);
}

/**
 * connman_resolver_remove:
 * @index: network interface index
 * @domain: domain limitation
 * @server: server address
 *
 * Remover resolver server address from current list
 */
int connman_resolver_remove(int index, const char *domain, const char *server)
{
	GSList *list, *matches = NULL;

	DBG("index %d domain %s server %s", index, domain, server);

	for (list = entry_list; list; list = list->next) {
		struct entry_data *entry = list->data;

		if (entry->index != index)
			continue;

		if (g_strcmp0(entry->domain, domain) != 0)
			continue;

		if (g_strcmp0(entry->server, server) != 0)
			continue;

		matches = g_slist_prepend(matches, entry);
		break;
	}

	if (!matches)
		return -ENOENT;

	remove_entries(matches);

	return 0;
}

/**
 * connman_resolver_remove_all:
 * @index: network interface index
 *
 * Remove all resolver server address for the specified interface index
 */
int connman_resolver_remove_all(int index)
{
	GSList *list, *matches = NULL;

	DBG("index %d", index);

	if (index < 0)
		return -EINVAL;

	for (list = entry_list; list; list = list->next) {
		struct entry_data *entry = list->data;

		if (entry->index != index)
			continue;

		matches = g_slist_prepend(matches, entry);
	}

	if (!matches)
		return -ENOENT;

	remove_entries(matches);

	return 0;
}

int __connman_resolver_redo_servers(int index)
{
	GSList *list;

	if (!dnsproxy_enabled)
		return 0;

	DBG("index %d", index);

	if (index < 0)
		return -EINVAL;

	for (list = entry_list; list; list = list->next) {
		struct entry_data *entry = list->data;

		if (entry->timeout == 0 || entry->index != index)
			continue;

		/*
		 * This function must only check IPv6 server addresses so
		 * do not remove IPv4 name servers unnecessarily.
		 */
		if (entry->family != AF_INET6)
			continue;

		/*
		 * We remove the server, and then re-create so that it will
		 * use proper source addresses when sending DNS queries.
		 */
		__connman_dnsproxy_remove(entry->index, entry->domain,
					entry->server);

		__connman_dnsproxy_append(entry->index, entry->domain,
					entry->server);
	}

	return 0;
}

static void free_entry(gpointer data)
{
	struct entry_data *entry = data;
	g_free(entry->domain);
	g_free(entry->server);
	g_free(entry);
}

static void free_resolvfile(gpointer data)
{
	struct resolvfile_entry *entry = data;
	g_free(entry->domain);
	g_free(entry->server);
	g_free(entry);
}

int __connman_resolver_init(gboolean dnsproxy)
{
	int i;
	char **ns;

	DBG("dnsproxy %d", dnsproxy);

	if (!dnsproxy)
		return 0;

	if (__connman_dnsproxy_init() < 0) {
		/* Fall back to resolv.conf */
		return 0;
	}

	dnsproxy_enabled = true;

	ns = connman_setting_get_string_list("FallbackNameservers");
	for (i = 0; ns && ns[i]; i += 1) {
		DBG("server %s", ns[i]);
		append_resolver(-1, NULL, ns[i], 0, RESOLVER_FLAG_PUBLIC);
	}

	return 0;
}

void __connman_resolver_cleanup(void)
{
	DBG("");

	if (dnsproxy_enabled)
		__connman_dnsproxy_cleanup();
	else {
		GList *list;
		GSList *slist;

		for (list = resolvfile_list; list; list = g_list_next(list))
			free_resolvfile(list->data);
		g_list_free(resolvfile_list);
		resolvfile_list = NULL;

		for (slist = entry_list; slist; slist = g_slist_next(slist))
			free_entry(slist->data);
		g_slist_free(entry_list);
		entry_list = NULL;
	}
}
