#include <u.h>
#include <libc.h>
#include <ip.h>
#include <bio.h>
#include <ndb.h>
#include "dns.h"

enum
{
	Maxdest=	24,	/* maximum destinations for a request message */
	Maxtrans=	3	/* maximum transmissions to a server */
};

static int	netquery(DN*, int, RR*, Request*, int);
static RR*	dnresolve1(char*, int, int, Request*, int, int);

char *LOG = "dns";

/*
 *  lookup 'type' info for domain name 'name'.  If it doesn't exist, try
 *  looking it up as a canonical name.
 */
RR*
dnresolve(char *name, int class, int type, Request *req, RR **cn, int depth, int recurse, int rooted, int *status)
{
	RR *rp, *nrp, *drp;
	DN *dp;
	int loops;
	char nname[Domlen];

	if(status)
		*status = 0;

	/*
	 *  hack for systems that don't have resolve search
	 *  lists.  Just look up the simple name in the database.
	 */
	if(!rooted && strchr(name, '.') == 0){
		rp = nil;
		drp = domainlist(class);
		for(nrp = drp; nrp != nil; nrp = nrp->next){
			snprint(nname, sizeof(nname), "%s.%s", name, nrp->ptr->name);
			rp = dnresolve(nname, class, type, req,cn, depth, recurse, rooted, status);
			rrfreelist(rrremneg(&rp));
			if(rp != nil)
				break;
		}
		if(drp != nil)
			rrfree(drp);
		return rp;
	}

	/*
	 *  try the name directly
	 */
	rp = dnresolve1(name, class, type, req, depth, recurse);
	if(rp)
		return randomize(rp);

	/* try it as a canonical name if we weren't told the name didn't exist */
	dp = dnlookup(name, class, 0);
	if(type != Tptr && dp->nonexistent != Rname){
		for(loops=0; rp == nil && loops < 32; loops++){
			rp = dnresolve1(name, class, Tcname, req, depth, recurse);
			if(rp == nil)
				break;

			if(rp->negative){
				rrfreelist(rp);
				rp = nil;
				break;
			}
	
			name = rp->host->name;
			if(cn)
				rrcat(cn, rp);
			else
				rrfreelist(rp);
	
			rp = dnresolve1(name, class, type, req, depth, recurse);
		}
	}

	/* distinction between not found and not good */
	if(rp == 0 && status != 0 && dp->nonexistent != 0)
		*status = dp->nonexistent;

	return randomize(rp);
}

static RR*
dnresolve1(char *name, int class, int type, Request *req, int depth, int recurse)
{
	DN *dp, *nsdp;
	RR *rp, *nsrp, *dbnsrp;
	char *cp;

	if(debug)
		syslog(0, LOG, "dnresolve1 %s %d %d", name, type, class);

	/* only class Cin implemented so far */
	if(class != Cin)
		return 0;

	dp = dnlookup(name, class, 1);

	/*
	 *  Try the cache first
	 */
	rp = rrlookup(dp, type, OKneg);
	if(rp){
		if(rp->db){
			/* unauthenticated db entries are hints */
			if(rp->auth)
				return rp;
		} else {
			/* cached entry must still be valid */
			if(rp->ttl > now){
				/* but Tall entries are special */
				if(type != Tall || rp->query == Tall)
					return rp;
			}
		}
	}
	rrfreelist(rp);

	/*
	 * try the cache for a canonical name. if found punt 
	 * since we'll find it during the canonical name search
	 * in dnresolve().
	 */
	if(type != Tcname){
		rp = rrlookup(dp, Tcname, NOneg);
		rrfreelist(rp);
		if(rp)
			return 0;
	}

	/*
	 *  if we're running as just a resolver, go to our
	 *  designated name servers
	 */
	if(resolver){
		nsrp = randomize(getdnsservers(class));
		if(nsrp != nil) {
			if(netquery(dp, type, nsrp, req, depth+1)){
				rrfreelist(nsrp);
				return rrlookup(dp, type, OKneg);
			}
			rrfreelist(nsrp);
		}
	}

	/*
 	 *  walk up the domain name looking for
	 *  a name server for the domain.
	 */
	for(cp = name; cp; cp = walkup(cp)){
		/*
		 *  if this is a local (served by us) domain,
		 *  return answer
		 */
		dbnsrp = randomize(dblookup(cp, class, Tns, 0, 0));
		if(dbnsrp && dbnsrp->local){
			rp = dblookup(name, class, type, 1, dbnsrp->ttl);
			rrfreelist(dbnsrp);
			return rp;
		}

		/*
		 *  if recursion isn't set, just accept local
		 *  entries
		 */
		if(recurse == Dontrecurse){
			if(dbnsrp)
				rrfreelist(dbnsrp);
			continue;
		}

		/* look for ns in cache */
		nsdp = dnlookup(cp, class, 0);
		nsrp = nil;
		if(nsdp)
			nsrp = randomize(rrlookup(nsdp, Tns, NOneg));

		/* if the entry timed out, ignore it */
		if(nsrp && nsrp->ttl < now){
			rrfreelist(nsrp);
			nsrp = nil;
		}

		if(nsrp){
			rrfreelist(dbnsrp);

			/* try the name servers found in cache */
			if(netquery(dp, type, nsrp, req, depth+1)){
				rrfreelist(nsrp);
				return rrlookup(dp, type, OKneg);
			}
			rrfreelist(nsrp);
			continue;
		}

		/* use ns from db */
		if(dbnsrp){
			/* try the name servers found in db */
			if(netquery(dp, type, dbnsrp, req, depth+1)){
				/* we got an answer */
				rrfreelist(dbnsrp);
				return rrlookup(dp, type, NOneg);
			}
			rrfreelist(dbnsrp);
		}
	}

	/* settle for a non-authoritative answer */
	rp = rrlookup(dp, type, OKneg);
	if(rp)
		return rp;

	/* noone answered.  try the database, we might have a chance. */
	return dblookup(name, class, type, 0, 0);
}

/*
 *  walk a domain name one element to the right.  return a pointer to that element.
 *  in other words, return a pointer to the parent domain name.
 */
char*
walkup(char *name)
{
	char *cp;

	cp = strchr(name, '.');
	if(cp)
		return cp+1;
	else if(*name)
		return "";
	else
		return 0;
}

/*
 *  Get a udpport for requests and replies. 
 */
int
udpport(void)
{
	int fd;

	if((fd = dial("udp!0!53", nil, nil, nil)) < 0)
		warning("can't get udp port");
	return fd;
}

int
mkreq(DN *dp, int type, uchar *buf, int flags, ushort reqno)
{
	DNSmsg m;
	int len;
	Udphdr *uh = (Udphdr*)buf;

	/* stuff port number into output buffer */
	memset(uh, 0, sizeof(*uh));
	hnputs(uh->rport, 53);

	/* make request and convert it to output format */
	memset(&m, 0, sizeof(m));
	m.flags = flags;
	m.id = reqno;
	m.qd = rralloc(type);
	m.qd->owner = dp;
	m.qd->type = type;
	len = convDNS2M(&m, &buf[Udphdrsize], Maxudp);
	if(len < 0)
		abort(); /* "can't convert" */;
	rrfree(m.qd);
	return len;
}

static void
freeanswers(DNSmsg *mp)
{
	rrfreelist(mp->qd);
	rrfreelist(mp->an);
	rrfreelist(mp->ns);
	rrfreelist(mp->ar);
}

/*
 *  read replies to a request.  ignore any of the wrong type.  wait at most 5 seconds.
 */
static int udpreadtimeout(int, Udphdr*, void*, int, int);
static int
readreply(int fd, DN *dp, int type, ushort req,
	  uchar *ibuf, DNSmsg *mp, ulong endtime, Request *reqp)
{
	char *err;
	int len;
	ulong now;
	RR *rp;

	for(; ; freeanswers(mp)){
		now = time(0);
		if(now >= endtime)
			return -1;	/* timed out */

		/* timed read */
		len = udpreadtimeout(fd, (Udphdr*)ibuf, ibuf+Udphdrsize, Maxudpin, (endtime-now)*1000);
		if(len < 0)
			return -1;	/* timed out */
		
		/* convert into internal format  */
		memset(mp, 0, sizeof(*mp));
		err = convM2DNS(&ibuf[Udphdrsize], len, mp);
		if(err){
			syslog(0, LOG, "input err %s: %I", err, ibuf);
			continue;
		}
		if(debug)
			logreply(reqp->id, ibuf, mp);

		/* answering the right question? */
		if(mp->id != req){
			syslog(0, LOG, "%d: id %d instead of %d: %I", reqp->id,
					mp->id, req, ibuf);
			continue;
		}
		if(mp->qd == 0){
			syslog(0, LOG, "%d: no question RR: %I", reqp->id, ibuf);
			continue;
		}
		if(mp->qd->owner != dp){
			syslog(0, LOG, "%d: owner %s instead of %s: %I", reqp->id,
				mp->qd->owner->name, dp->name, ibuf);
			continue;
		}
		if(mp->qd->type != type){
			syslog(0, LOG, "%d: type %d instead of %d: %I", reqp->id,
				mp->qd->type, type, ibuf);
			continue;
		}

		/* remember what request this is in answer to */
		for(rp = mp->an; rp; rp = rp->next)
			rp->query = type;

		return 0;
	}

	return 0;	/* never reached */
}

static int
udpreadtimeout(int fd, Udphdr *h, void *data, int n, int ms)
{
	fd_set rd;
	struct timeval tv;
	
	FD_ZERO(&rd);
	FD_SET(fd, &rd);
	
	tv.tv_sec = ms/1000;
	tv.tv_usec = (ms%1000)*1000;
	
	if(select(fd+1, &rd, 0, 0, &tv) != 1)
		return -1;
	return udpread(fd, h, data, n);
}

/*
 *	return non-0 if first list includes second list
 */
int
contains(RR *rp1, RR *rp2)
{
	RR *trp1, *trp2;

	for(trp2 = rp2; trp2; trp2 = trp2->next){
		for(trp1 = rp1; trp1; trp1 = trp1->next){
			if(trp1->type == trp2->type)
			if(trp1->host == trp2->host)
			if(trp1->owner == trp2->owner)
				break;
		}
		if(trp1 == 0)
			return 0;
	}

	return 1;
}


typedef struct Dest	Dest;
struct Dest
{
	uchar	a[IPaddrlen];	/* ip address */
	DN	*s;		/* name server */
	int	nx;		/* number of transmissions */
	int	code;
};


/*
 *  return multicast version if any
 */
int
ipisbm(uchar *ip)
{
	if(isv4(ip)){
		if(ip[IPv4off] >= 0xe0 && ip[IPv4off] < 0xf0)
			return 4;
		if(ipcmp(ip, IPv4bcast) == 0)
			return 4;
	} else {
		if(ip[0] == 0xff)
			return 6;
	}
	return 0;
}

/*
 *  Get next server address
 */
static int
serveraddrs(RR *nsrp, Dest *dest, int nd, int depth, Request *reqp)
{
	RR *rp, *arp, *trp;
	Dest *cur;

	if(nd >= Maxdest)
		return 0;

	/*
	 *  look for a server whose address we already know.
	 *  if we find one, mark it so we ignore this on
	 *  subsequent passes.
	 */
	arp = 0;
	for(rp = nsrp; rp; rp = rp->next){
		assert(rp->magic == RRmagic);
		if(rp->marker)
			continue;
		arp = rrlookup(rp->host, Ta, NOneg);
		if(arp){
			rp->marker = 1;
			break;
		}
		arp = dblookup(rp->host->name, Cin, Ta, 0, 0);
		if(arp){
			rp->marker = 1;
			break;
		}
	}

	/*
	 *  if the cache and database lookup didn't find any new
	 *  server addresses, try resolving one via the network.
	 *  Mark any we try to resolve so we don't try a second time.
	 */
	if(arp == 0){
		for(rp = nsrp; rp; rp = rp->next){
			if(rp->marker)
				continue;
			rp->marker = 1;

			/*
			 *  avoid loops looking up a server under itself
			 */
			if(subsume(rp->owner->name, rp->host->name))
				continue;

			arp = dnresolve(rp->host->name, Cin, Ta, reqp, 0, depth+1, Recurse, 1, 0);
			rrfreelist(rrremneg(&arp));
			if(arp)
				break;
		}
	}

	/* use any addresses that we found */
	for(trp = arp; trp; trp = trp->next){
		if(nd >= Maxdest)
			break;
		cur = &dest[nd];
		parseip(cur->a, trp->ip->name);
		if(ipisbm(cur->a))
			continue;
		cur->nx = 0;
		cur->s = trp->owner;
		cur->code = Rtimeout;
		nd++;
	}
	rrfreelist(arp);
	return nd;
}

/*
 *  cache negative responses
 */
static void
cacheneg(DN *dp, int type, int rcode, RR *soarr)
{
	RR *rp;
	DN *soaowner;
	ulong ttl;

	/* no cache time specified, don' make anything up */
	if(soarr != nil){
		if(soarr->next != nil){
			rrfreelist(soarr->next);
			soarr->next = nil;
		}
		soaowner = soarr->owner;
	} else 
		soaowner = nil;

	/* the attach can cause soarr to be freed so mine it now */
	if(soarr != nil && soarr->soa != nil)
		ttl = soarr->soa->minttl+now;
	else
		ttl = 5*Min;

	/* add soa and negative RR to the database */
	rrattach(soarr, 1);

	rp = rralloc(type);
	rp->owner = dp;
	rp->negative = 1;
	rp->negsoaowner = soaowner;
	rp->negrcode = rcode;
	rp->ttl = ttl;
	rrattach(rp, 1);
}

/*
 *  query name servers.  If the name server returns a pointer to another
 *  name server, recurse.
 */
static int
netquery1(int fd, DN *dp, int type, RR *nsrp, Request *reqp, int depth, uchar *ibuf, uchar *obuf)
{
	int ndest, j, len, replywaits, rv;
	ushort req;
	RR *tp, *soarr;
	Dest *p, *l, *np;
	DN *ndp;
	Dest dest[Maxdest];
	DNSmsg m;
	ulong endtime;
	Udphdr *uh;

	/* pack request into a message */
	req = rand();
	len = mkreq(dp, type, obuf, Frecurse|Oquery, req);

	/* no server addresses yet */
	l = dest;

	/*
	 *  transmit requests and wait for answers.
	 *  at most Maxtrans attempts to each address.
	 *  each cycle send one more message than the previous.
	 */
	for(ndest = 1; ndest < Maxdest; ndest++){
		p = dest;

		endtime = time(0);
		if(endtime >= reqp->aborttime)
			break;

		/* get a server address if we need one */
		if(ndest > l - p){
			j = serveraddrs(nsrp, dest, l - p, depth, reqp);
			l = &dest[j];
		}

		/* no servers, punt */
		if(l == dest)
			break;

		/* send to first 'ndest' destinations */
		j = 0;
		for(; p < &dest[ndest] && p < l; p++){
			/* skip destinations we've finished with */
			if(p->nx >= Maxtrans)
				continue;

			j++;

			/* exponential backoff of requests */
			if((1<<p->nx) > ndest)
				continue;

			memmove(obuf, p->a, sizeof(p->a));
			if(debug)
				logsend(reqp->id, depth, obuf, p->s->name,
					dp->name, type);
			uh = (Udphdr*)obuf;
			fprint(2, "send %I %I %d %d\n", uh->raddr, uh->laddr, nhgets(uh->rport), nhgets(uh->lport));
			if(udpwrite(fd, uh, obuf+Udphdrsize, len) < 0)
				warning("sending udp msg %r");
			p->nx++;
		}
		if(j == 0)
			break;		/* no destinations left */

		/* wait up to 5 seconds for replies */
		endtime = time(0) + 5;
		if(endtime > reqp->aborttime)
			endtime = reqp->aborttime;

		for(replywaits = 0; replywaits < ndest; replywaits++){
			if(readreply(fd, dp, type, req, ibuf, &m, endtime, reqp) < 0)
				break;		/* timed out */

			/* find responder */
			for(p = dest; p < l; p++)
				if(memcmp(p->a, ibuf, sizeof(p->a)) == 0)
					break;

			/* remove all addrs of responding server from list */
			for(np = dest; np < l; np++)
				if(np->s == p->s)
					p->nx = Maxtrans;

			/* ignore any error replies */
			if((m.flags & Rmask) == Rserver){
				rrfreelist(m.qd);
				rrfreelist(m.an);
				rrfreelist(m.ar);
				rrfreelist(m.ns);
				if(p != l)
					p->code = Rserver;
				continue;
			}

			/* ignore any bad delegations */
			if(m.ns && baddelegation(m.ns, nsrp, ibuf)){
				rrfreelist(m.ns);
				m.ns = nil;
				if(m.an == nil){
					rrfreelist(m.qd);
					rrfreelist(m.ar);
					if(p != l)
						p->code = Rserver;
					continue;
				}
			}


			/* remove any soa's from the authority section */
			soarr = rrremtype(&m.ns, Tsoa);

			/* incorporate answers */
			if(m.an)
				rrattach(m.an, (m.flags & Fauth) ? 1 : 0);
			if(m.ar)
				rrattach(m.ar, 0);
			if(m.ns){
				ndp = m.ns->owner;
				rrattach(m.ns, 0);
			} else
				ndp = 0;

			/* free the question */
			if(m.qd)
				rrfreelist(m.qd);

			/*
			 *  Any reply from an authoritative server,
			 *  or a positive reply terminates the search
			 */
			if(m.an != nil || (m.flags & Fauth)){
				if(m.an == nil && (m.flags & Rmask) == Rname)
					dp->nonexistent = Rname;
				else
					dp->nonexistent = 0;

				/*
				 *  cache any negative responses, free soarr
				 */
				if((m.flags & Fauth) && m.an == nil)
					cacheneg(dp, type, (m.flags & Rmask), soarr);
				else
					rrfreelist(soarr);
				return 1;
			}
			rrfreelist(soarr);

			/*
			 *  if we've been given better name servers
			 *  recurse
			 */
			if(m.ns){
				tp = rrlookup(ndp, Tns, NOneg);
				if(!contains(nsrp, tp)){
					rv = netquery(dp, type, tp, reqp, depth+1);
					rrfreelist(tp);
					return rv;
				} else
					rrfreelist(tp);
			}
		}
	}

	/* if all servers returned failure, propogate it */
	dp->nonexistent = Rserver;
	for(p = dest; p < l; p++)
		if(p->code != Rserver)
			dp->nonexistent = 0;

	return 0;
}

typedef struct Qarg Qarg;
struct Qarg
{
	DN *dp;
	int type;
	RR *nsrp;
	Request *reqp;
	int depth;
};


static int
netquery(DN *dp, int type, RR *nsrp, Request *reqp, int depth)
{
	uchar *obuf;
	uchar *ibuf;
	RR *rp;
	int fd, rv;

	if(depth > 12)
		return 0;

	/* use alloced buffers rather than ones from the stack */
	ibuf = emalloc(Maxudpin+Udphdrsize);
	obuf = emalloc(Maxudp+Udphdrsize);

	/* prepare server RR's for incremental lookup */
	for(rp = nsrp; rp; rp = rp->next)
		rp->marker = 0;

	fd = udpport();
	if(fd < 0)
		return 0;
	rv = netquery1(fd, dp, type, nsrp, reqp, depth, ibuf, obuf);
	close(fd);
	free(ibuf);
	free(obuf);

	return rv;
}
