/*
 * linux/fs/nfs/dns_resolve.c
 *
 * Copyright (c) 2009 Trond Myklebust <Trond.Myklebust@netapp.com>
 *
 * Resolves DNS hostnames into valid ip addresses
 */

#ifdef CONFIG_NFS_USE_KERNEL_DNS

#include <linux/sunrpc/clnt.h>
#include <linux/dns_resolver.h>

ssize_t nfs_dns_resolve_name(char *name, size_t namelen,
		struct sockaddr *sa, size_t salen)
{
	ssize_t ret;
	char *ip_addr = NULL;
	int ip_len;

	ip_len = dns_query(NULL, name, namelen, NULL, &ip_addr, NULL);
	if (ip_len > 0)
		ret = rpc_pton(ip_addr, ip_len, sa, salen);
	else
		ret = -ESRCH;
	kfree(ip_addr);
	return ret;
}

#else

#include <linux/hash.h>
#include <linux/string.h>
#include <linux/kmod.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/socket.h>
#include <linux/seq_file.h>
#include <linux/inet.h>
#include <linux/sunrpc/clnt.h>
#include <linux/sunrpc/cache.h>
#include <linux/sunrpc/svcauth.h>

#include "dns_resolve.h"
#include "cache_lib.h"

#define NFS_DNS_HASHBITS 4
#define NFS_DNS_HASHTBL_SIZE (1 << NFS_DNS_HASHBITS)

static struct cache_head *nfs_dns_table[NFS_DNS_HASHTBL_SIZE];

struct nfs_dns_ent {
	struct cache_head h;

	char *hostname;
	size_t namelen;

	struct sockaddr_storage addr;
	size_t addrlen;
};


static void nfs_dns_ent_update(struct cache_head *cnew,
		struct cache_head *ckey)
{
	struct nfs_dns_ent *new;
	struct nfs_dns_ent *key;

	new = container_of(cnew, struct nfs_dns_ent, h);
	key = container_of(ckey, struct nfs_dns_ent, h);

	memcpy(&new->addr, &key->addr, key->addrlen);
	new->addrlen = key->addrlen;
}

static void nfs_dns_ent_init(struct cache_head *cnew,
		struct cache_head *ckey)
{
	struct nfs_dns_ent *new;
	struct nfs_dns_ent *key;

	new = container_of(cnew, struct nfs_dns_ent, h);
	key = container_of(ckey, struct nfs_dns_ent, h);

	kfree(new->hostname);
	new->hostname = kstrndup(key->hostname, key->namelen, GFP_KERNEL);
	if (new->hostname) {
		new->namelen = key->namelen;
		nfs_dns_ent_update(cnew, ckey);
	} else {
		new->namelen = 0;
		new->addrlen = 0;
	}
}

static void nfs_dns_ent_put(struct kref *ref)
{
	struct nfs_dns_ent *item;

	item = container_of(ref, struct nfs_dns_ent, h.ref);
	kfree(item->hostname);
	kfree(item);
}

static struct cache_head *nfs_dns_ent_alloc(void)
{
	struct nfs_dns_ent *item = kmalloc(sizeof(*item), GFP_KERNEL);

	if (item != NULL) {
		item->hostname = NULL;
		item->namelen = 0;
		item->addrlen = 0;
		return &item->h;
	}
	return NULL;
};

static unsigned int nfs_dns_hash(const struct nfs_dns_ent *key)
{
	return hash_str(key->hostname, NFS_DNS_HASHBITS);
}

static void nfs_dns_request(struct cache_detail *cd,
		struct cache_head *ch,
		char **bpp, int *blen)
{
	struct nfs_dns_ent *key = container_of(ch, struct nfs_dns_ent, h);

	qword_add(bpp, blen, key->hostname);
	(*bpp)[-1] = '\n';
}

static int nfs_dns_upcall(struct cache_detail *cd,
		struct cache_head *ch)
{
	struct nfs_dns_ent *key = container_of(ch, struct nfs_dns_ent, h);
	int ret;

	ret = nfs_cache_upcall(cd, key->hostname);
	if (ret)
		ret = sunrpc_cache_pipe_upcall(cd, ch, nfs_dns_request);
	return ret;
}

static int nfs_dns_match(struct cache_head *ca,
		struct cache_head *cb)
{
	struct nfs_dns_ent *a;
	struct nfs_dns_ent *b;

	a = container_of(ca, struct nfs_dns_ent, h);
	b = container_of(cb, struct nfs_dns_ent, h);

	if (a->namelen == 0 || a->namelen != b->namelen)
		return 0;
	return memcmp(a->hostname, b->hostname, a->namelen) == 0;
}

static int nfs_dns_show(struct seq_file *m, struct cache_detail *cd,
		struct cache_head *h)
{
	struct nfs_dns_ent *item;
	long ttl;

	if (h == NULL) {
		seq_puts(m, "# ip address      hostname        ttl\n");
		return 0;
	}
	item = container_of(h, struct nfs_dns_ent, h);
	ttl = (long)item->h.expiry_time - (long)get_seconds();
	if (ttl < 0)
		ttl = 0;

	if (!test_bit(CACHE_NEGATIVE, &h->flags)) {
		char buf[INET6_ADDRSTRLEN+IPV6_SCOPE_ID_LEN+1];

		rpc_ntop((struct sockaddr *)&item->addr, buf, sizeof(buf));
		seq_printf(m, "%15s ", buf);
	} else
		seq_puts(m, "<none>          ");
	seq_printf(m, "%15s %ld\n", item->hostname, ttl);
	return 0;
}

static struct nfs_dns_ent *nfs_dns_lookup(struct cache_detail *cd,
		struct nfs_dns_ent *key)
{
	struct cache_head *ch;

	ch = sunrpc_cache_lookup(cd,
			&key->h,
			nfs_dns_hash(key));
	if (!ch)
		return NULL;
	return container_of(ch, struct nfs_dns_ent, h);
}

static struct nfs_dns_ent *nfs_dns_update(struct cache_detail *cd,
		struct nfs_dns_ent *new,
		struct nfs_dns_ent *key)
{
	struct cache_head *ch;

	ch = sunrpc_cache_update(cd,
			&new->h, &key->h,
			nfs_dns_hash(key));
	if (!ch)
		return NULL;
	return container_of(ch, struct nfs_dns_ent, h);
}

static int nfs_dns_parse(struct cache_detail *cd, char *buf, int buflen)
{
	char buf1[NFS_DNS_HOSTNAME_MAXLEN+1];
	struct nfs_dns_ent key, *item;
	unsigned long ttl;
	ssize_t len;
	int ret = -EINVAL;

	if (buf[buflen-1] != '\n')
		goto out;
	buf[buflen-1] = '\0';

	len = qword_get(&buf, buf1, sizeof(buf1));
	if (len <= 0)
		goto out;
	key.addrlen = rpc_pton(buf1, len,
			(struct sockaddr *)&key.addr,
			sizeof(key.addr));

	len = qword_get(&buf, buf1, sizeof(buf1));
	if (len <= 0)
		goto out;

	key.hostname = buf1;
	key.namelen = len;
	memset(&key.h, 0, sizeof(key.h));

	ttl = get_expiry(&buf);
	if (ttl == 0)
		goto out;
	key.h.expiry_time = ttl + get_seconds();

	ret = -ENOMEM;
	item = nfs_dns_lookup(cd, &key);
	if (item == NULL)
		goto out;

	if (key.addrlen == 0)
		set_bit(CACHE_NEGATIVE, &key.h.flags);

	item = nfs_dns_update(cd, &key, item);
	if (item == NULL)
		goto out;

	ret = 0;
	cache_put(&item->h, cd);
out:
	return ret;
}

static struct cache_detail nfs_dns_resolve = {
	.owner = THIS_MODULE,
	.hash_size = NFS_DNS_HASHTBL_SIZE,
	.hash_table = nfs_dns_table,
	.name = "dns_resolve",
	.cache_put = nfs_dns_ent_put,
	.cache_upcall = nfs_dns_upcall,
	.cache_parse = nfs_dns_parse,
	.cache_show = nfs_dns_show,
	.match = nfs_dns_match,
	.init = nfs_dns_ent_init,
	.update = nfs_dns_ent_update,
	.alloc = nfs_dns_ent_alloc,
};

static int do_cache_lookup(struct cache_detail *cd,
		struct nfs_dns_ent *key,
		struct nfs_dns_ent **item,
		struct nfs_cache_defer_req *dreq)
{
	int ret = -ENOMEM;

	*item = nfs_dns_lookup(cd, key);
	if (*item) {
		ret = cache_check(cd, &(*item)->h, &dreq->req);
		if (ret)
			*item = NULL;
	}
	return ret;
}

static int do_cache_lookup_nowait(struct cache_detail *cd,
		struct nfs_dns_ent *key,
		struct nfs_dns_ent **item)
{
	int ret = -ENOMEM;

	*item = nfs_dns_lookup(cd, key);
	if (!*item)
		goto out_err;
	ret = -ETIMEDOUT;
	if (!test_bit(CACHE_VALID, &(*item)->h.flags)
			|| (*item)->h.expiry_time < get_seconds()
			|| cd->flush_time > (*item)->h.last_refresh)
		goto out_put;
	ret = -ENOENT;
	if (test_bit(CACHE_NEGATIVE, &(*item)->h.flags))
		goto out_put;
	return 0;
out_put:
	cache_put(&(*item)->h, cd);
out_err:
	*item = NULL;
	return ret;
}

static int do_cache_lookup_wait(struct cache_detail *cd,
		struct nfs_dns_ent *key,
		struct nfs_dns_ent **item)
{
	struct nfs_cache_defer_req *dreq;
	int ret = -ENOMEM;

	dreq = nfs_cache_defer_req_alloc();
	if (!dreq)
		goto out;
	ret = do_cache_lookup(cd, key, item, dreq);
	if (ret == -EAGAIN) {
		ret = nfs_cache_wait_for_upcall(dreq);
		if (!ret)
			ret = do_cache_lookup_nowait(cd, key, item);
	}
	nfs_cache_defer_req_put(dreq);
out:
	return ret;
}

ssize_t nfs_dns_resolve_name(char *name, size_t namelen,
		struct sockaddr *sa, size_t salen)
{
	struct nfs_dns_ent key = {
		.hostname = name,
		.namelen = namelen,
	};
	struct nfs_dns_ent *item = NULL;
	ssize_t ret;

	ret = do_cache_lookup_wait(&nfs_dns_resolve, &key, &item);
	if (ret == 0) {
		if (salen >= item->addrlen) {
			memcpy(sa, &item->addr, item->addrlen);
			ret = item->addrlen;
		} else
			ret = -EOVERFLOW;
		cache_put(&item->h, &nfs_dns_resolve);
	} else if (ret == -ENOENT)
		ret = -ESRCH;
	return ret;
}

int nfs_dns_resolver_init(void)
{
	return nfs_cache_register(&nfs_dns_resolve);
}

void nfs_dns_resolver_destroy(void)
{
	nfs_cache_unregister(&nfs_dns_resolve);
}

#endif
