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

static RR*	doextquery(DNSmsg*, Request*, int);
static void	hint(RR**, RR*);

extern char *logfile;

/*
 *  answer a dns request
 */
void
dnserver(DNSmsg *reqp, DNSmsg *repp, Request *req)
{
	RR *tp, *neg;
	char *cp;
	DN *nsdp, *dp;
	Area *myarea;
	char tname[32];

	dncheck(nil, 1);

	memset(repp, 0, sizeof(*repp));
	repp->id = reqp->id;
	repp->flags = Fresp | Fcanrec | Oquery;

	/* move one question from reqp to repp */
	tp = reqp->qd;
	reqp->qd = tp->next;
	tp->next = 0;
	repp->qd = tp;

	if(!rrsupported(repp->qd->type)){
		syslog(0, logfile, "server: request %s", rrname(repp->qd->type, tname, sizeof tname));
		repp->flags = Runimplimented | Fresp | Fcanrec | Oquery;
		return;
	}

	if(repp->qd->owner->class != Cin){
		syslog(0, logfile, "server: class %d", repp->qd->owner->class);
		repp->flags = Runimplimented | Fresp | Fcanrec | Oquery;
		return;
	}

	myarea = inmyarea(repp->qd->owner->name);
	if(myarea != nil && (repp->qd->type == Tixfr || repp->qd->type == Taxfr)){
		syslog(0, logfile, "server: request %s", rrname(repp->qd->type, tname, sizeof tname));
		repp->flags = Runimplimented | Fresp | Fcanrec | Oquery;
		return;
	}

	/*
	 *  get the answer if we can
	 */
	if(reqp->flags & Frecurse)
		neg = doextquery(repp, req, Recurse);
	else
		neg = doextquery(repp, req, Dontrecurse);

	/* authority is transitive */
	if(myarea != nil || (repp->an && repp->an->auth))
		repp->flags |= Fauth;

	/* pass on error codes */
	if(repp->an == 0){
		dp = dnlookup(repp->qd->owner->name, repp->qd->owner->class, 0);
		if(dp->rr == 0)
			if(reqp->flags & Frecurse)
				repp->flags |= dp->nonexistent|Fauth;
	}

	if(myarea == nil){
		/*
		 *  add name server if we know
		 */
		for(cp = repp->qd->owner->name; cp; cp = walkup(cp)){
			nsdp = dnlookup(cp, repp->qd->owner->class, 0);
			if(nsdp == 0)
				continue;
	
			repp->ns = rrlookup(nsdp, Tns, OKneg);
			if(repp->ns){
				/* don't pass on anything we know is wrong */
				if(repp->ns->negative){
					rrfreelist(repp->ns);
					repp->ns = nil;
				}
				break;
			}
	
			repp->ns = dblookup(cp, repp->qd->owner->class, Tns, 0, 0);
			if(repp->ns)
				break;
		}
	}

	/*
	 *  add ip addresses as hints
	 */
	if(repp->qd->type != Taxfr && repp->qd->type != Tixfr){
		for(tp = repp->ns; tp; tp = tp->next)
			hint(&repp->ar, tp);
		for(tp = repp->an; tp; tp = tp->next)
			hint(&repp->ar, tp);
	}

	/*
	 *  add an soa to the authority section to help client with negative caching
	 */
	if(repp->an == nil){
		if(myarea != nil){
			rrcopy(myarea->soarr, &tp);
			rrcat(&repp->ns, tp);
		} else if(neg != nil) {
			if(neg->negsoaowner != nil)
				rrcat(&repp->ns, rrlookup(neg->negsoaowner, Tsoa, NOneg));
			repp->flags |= neg->negrcode;
		}
	}

	/*
	 *  get rid of duplicates
	 */
	unique(repp->an);
	unique(repp->ns);
	unique(repp->ar);

	rrfreelist(neg);

	dncheck(nil, 1);
}

/*
 *  satisfy a recursive request.  dnlookup will handle cnames.
 */
static RR*
doextquery(DNSmsg *mp, Request *req, int recurse)
{
	int type;
	char *name;
	RR *rp, *neg;

	name = mp->qd->owner->name;
	type = mp->qd->type;
	rp = dnresolve(name, Cin, type, req, &mp->an, 0, recurse, 1, 0);

	/* don't return soa hints as answers, it's wrong */
	if(rp && rp->db && !rp->auth && rp->type == Tsoa)
		rrfreelist(rp);

	/* don't let negative cached entries escape */
	neg = rrremneg(&rp);
	rrcat(&mp->an, rp);
	return neg;
}

static void
hint(RR **last, RR *rp)
{
	RR *hp;

	switch(rp->type){
	case Tns:
	case Tmx:
	case Tmb:
	case Tmf:
	case Tmd:
		hp = rrlookup(rp->host, Ta, NOneg);
		if(hp == nil)
			hp = dblookup(rp->host->name, Cin, Ta, 0, 0);
		rrcat(last, hp);
		break;
	}
}
