#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;
	OUdphdr *uh = (OUdphdr*)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[OUdphdrsize], Maxudp);
	if(len < 0)
		abort(); /* "can't convert" */;
	rrfree(m.qd);
	return len;
}

/* for alarms in readreply */
static void
ding(void *x, char *msg)
{
	USED(x);
	if(strcmp(msg, "alarm") == 0)
		noted(NCONT);
	else
		noted(NDFLT);
}

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
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;

	notify(ding);

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

		/* timed read */
		alarm((endtime - now) * 1000);
		len = udpread(fd, (OUdphdr*)ibuf, ibuf+OUdphdrsize, Maxudpin);
		alarm(0);
		if(len < 0)
			return -1;	/* timed out */
		
		/* convert into internal format  */
		memset(mp, 0, sizeof(*mp));
		err = convM2DNS(&ibuf[OUdphdrsize], 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 */
}

/*
 *	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;

	/* 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);
{Udphdr *uh = (Udphdr*)obuf;
print("send %I %I %d %d\n", uh->raddr, uh->laddr, nhgets(uh->rport), nhgets(uh->lport));
}
			if(udpwrite(fd, (OUdphdr*)obuf, obuf+OUdphdrsize, 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+OUdphdrsize);
	obuf = emalloc(Maxudp+OUdphdrsize);

	slave(reqp);

	/* 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;
}
