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

/*
 *  Hash table for domain names.  The hash is based only on the
 *  first element of the domain name.
 */
DN	*ht[HTLEN];


static struct
{
	Lock	lk;
	ulong	names;	/* names allocated */
	ulong	oldest;	/* longest we'll leave a name around */
	int	active;
	int	mutex;
	int	id;
} dnvars;

/* names of RR types */
char *rrtname[] =
{
[Ta]		"ip",
[Tns]		"ns",
[Tmd]		"md",
[Tmf]		"mf",
[Tcname]	"cname",
[Tsoa]		"soa",
[Tmb]		"mb",
[Tmg]		"mg",
[Tmr]		"mr",
[Tnull]		"null",
[Twks]		"wks",
[Tptr]		"ptr",
[Thinfo]	"hinfo",
[Tminfo]	"minfo",
[Tmx]		"mx",
[Ttxt]		"txt",
[Trp]		"rp",
[Tkey]		"key",
[Tcert]		"cert",
[Tsig]		"sig",
[Taaaa]		"ipv6",
[Tixfr]		"ixfr",
[Taxfr]		"axfr",
[Tall]		"all",
		0,
};

/* names of response codes */
char *rname[Rmask+1] =
{
[Rok]			"ok",
[Rformat]		"format error",
[Rserver]		"server failure",
[Rname]			"bad name",
[Runimplimented]	"unimplemented",
[Rrefused]		"we don't like you",
};

/* names of op codes */
char *opname[] =
{
[Oquery]	"query",
[Oinverse]	"inverse",
[Ostatus]	"status",
};

Lock	dnlock;

static int sencodefmt(Fmt*);

/*
 *  set up a pipe to use as a lock
 */
void
dninit(void)
{
	fmtinstall('E', eipfmt);
	fmtinstall('I', eipfmt);
	fmtinstall('V', eipfmt);
	fmtinstall('R', rrfmt);
	fmtinstall('Q', rravfmt);
	fmtinstall('H', sencodefmt);

	dnvars.oldest = maxage;
	dnvars.names = 0;
}

/*
 *  hash for a domain name
 */
static ulong
dnhash(char *name)
{
	ulong hash;
	uchar *val = (uchar*)name;

	for(hash = 0; *val; val++)
		hash = (hash*13) + tolower(*val)-'a';
	return hash % HTLEN;
}

/*
 *  lookup a symbol.  if enter is not zero and the name is
 *  not found, create it.
 */
DN*
dnlookup(char *name, int class, int enter)
{
	DN **l;
	DN *dp;

	l = &ht[dnhash(name)];
	lock(&dnlock);
	for(dp = *l; dp; dp = dp->next) {
		assert(dp->magic == DNmagic);
		if(dp->class == class && cistrcmp(dp->name, name) == 0){
			dp->referenced = now;
			unlock(&dnlock);
			return dp;
		}
		l = &dp->next;
	}
	if(enter == 0){
		unlock(&dnlock);
		return 0;
	}
	dnvars.names++;
	dp = emalloc(sizeof(*dp));
	dp->magic = DNmagic;
	dp->name = estrdup(name);
	assert(dp->name != 0);
	dp->class = class;
	dp->rr = 0;
	dp->next = 0;
	dp->referenced = now;
	*l = dp;
	unlock(&dnlock);

	return dp;
}

/*
 *  dump the cache
 */
void
dndump(char *file)
{
	DN *dp;
	int i, fd;
	RR *rp;

	fd = open(file, OWRITE|OTRUNC);
	if(fd < 0)
		return;
	lock(&dnlock);
	for(i = 0; i < HTLEN; i++){
		for(dp = ht[i]; dp; dp = dp->next){
			fprint(fd, "%s\n", dp->name);
			for(rp = dp->rr; rp; rp = rp->next)
				fprint(fd, "	%R %c%c %lud/%lud\n", rp, rp->auth?'A':'U',
					rp->db?'D':'N', rp->expire, rp->ttl);
		}
	}
	unlock(&dnlock);
	close(fd);
}

/*
 *  purge all records
 */
void
dnpurge(void)
{
	DN *dp;
	RR *rp, *srp;
	int i;

	lock(&dnlock);

	for(i = 0; i < HTLEN; i++)
		for(dp = ht[i]; dp; dp = dp->next){
			srp = rp = dp->rr;
			dp->rr = nil;
			for(; rp != nil; rp = rp->next)
				rp->cached = 0;
			rrfreelist(srp);
		}

	unlock(&dnlock);
}

/*
 *  check the age of resource records, free any that have timed out
 */
void
dnage(DN *dp)
{
	RR **l;
	RR *rp, *next;
	ulong diff;

	diff = now - dp->referenced;
	if(diff < Reserved)
		return;

	l = &dp->rr;
	for(rp = dp->rr; rp; rp = next){
		assert(rp->magic == RRmagic && rp->cached);
		next = rp->next;
		if(!rp->db)
		if(rp->expire < now || diff > dnvars.oldest){
			*l = next;
			rp->cached = 0;
			rrfree(rp);
			continue;
		}
		l = &rp->next;
	}
}

#define REF(x) if(x) x->refs++

/*
 *  our target is 4000 names cached, this should be larger on large servers
 */
#define TARGET 4000

/*
 *  periodicly sweep for old records and remove unreferenced domain names
 *
 *  only called when all other threads are locked out
 */
void
dnageall(int doit)
{
	DN *dp, **l;
	int i;
	RR *rp;
	static ulong nextage;

	if(dnvars.names < TARGET && now < nextage && !doit){
		dnvars.oldest = maxage;
		return;
	}

	if(dnvars.names > TARGET)
		dnvars.oldest /= 2;
	nextage = now + maxage;

	lock(&dnlock);

	/* time out all old entries (and set refs to 0) */
	for(i = 0; i < HTLEN; i++)
		for(dp = ht[i]; dp; dp = dp->next){
			dp->refs = 0;
			dnage(dp);
		}

	/* mark all referenced domain names */
	for(i = 0; i < HTLEN; i++)
		for(dp = ht[i]; dp; dp = dp->next)
			for(rp = dp->rr; rp; rp = rp->next){
				REF(rp->owner);
				if(rp->negative){
					REF(rp->negsoaowner);
					continue;
				}
				switch(rp->type){
				case Thinfo:
					REF(rp->cpu);
					REF(rp->os);
					break;
				case Ttxt:
					break;
				case Tcname:
				case Tmb:
				case Tmd:
				case Tmf:
				case Tns:
					REF(rp->host);
					break;
				case Tmg:
				case Tmr:
					REF(rp->mb);
					break;
				case Tminfo:
					REF(rp->rmb);
					REF(rp->mb);
					break;
				case Trp:
					REF(rp->rmb);
					REF(rp->rp);
					break;
				case Tmx:
					REF(rp->host);
					break;
				case Ta:
				case Taaaa:
					REF(rp->ip);
					break;
				case Tptr:
					REF(rp->ptr);
					break;
				case Tsoa:
					REF(rp->host);
					REF(rp->rmb);
					break;
				}
			}

	/* sweep and remove unreferenced domain names */
	for(i = 0; i < HTLEN; i++){
		l = &ht[i];
		for(dp = *l; dp; dp = *l){
			if(dp->rr == 0 && dp->refs == 0){
				assert(dp->magic == DNmagic);
				*l = dp->next;
				if(dp->name)
					free(dp->name);
				dp->magic = ~dp->magic;
				dnvars.names--;
				free(dp);
				continue;
			}
			l = &dp->next;
		}
	}

	unlock(&dnlock);
}

/*
 *  timeout all database records (used when rereading db)
 */
void
dnagedb(void)
{
	DN *dp;
	int i;
	RR *rp;

	lock(&dnlock);

	/* time out all database entries */
	for(i = 0; i < HTLEN; i++)
		for(dp = ht[i]; dp; dp = dp->next)
			for(rp = dp->rr; rp; rp = rp->next)
				if(rp->db)
					rp->expire = 0;

	unlock(&dnlock);
}

/*
 *  mark all local db records about my area as authoritative, time out any others
 */
void
dnauthdb(void)
{
	DN *dp;
	int i;
	Area *area;
	RR *rp;

	lock(&dnlock);

	/* time out all database entries */
	for(i = 0; i < HTLEN; i++)
		for(dp = ht[i]; dp; dp = dp->next){
			area = inmyarea(dp->name);
			for(rp = dp->rr; rp; rp = rp->next)
				if(rp->db){
					if(area){
						if(rp->ttl < area->soarr->soa->minttl)
							rp->ttl = area->soarr->soa->minttl;
						rp->auth = 1;
					}
					if(rp->expire == 0){
						rp->db = 0;
						dp->referenced = now - Reserved - 1;
					}
				}
		}

	unlock(&dnlock);
}

/*
 *  keep track of other processes to know if we can
 *  garbage collect.  block while garbage collecting.
 */
int
getactivity(Request *req)
{
	int rv;

	if(traceactivity) syslog(0, "dns", "get %d by %d.%d", dnvars.active, getpid(), threadid());
	lock(&dnvars.lk);
	while(dnvars.mutex){
		unlock(&dnvars.lk);
		sleep(200);
		lock(&dnvars.lk);
	}
	rv = ++dnvars.active;
	now = time(0);
	req->id = ++dnvars.id;
	unlock(&dnvars.lk);

	return rv;
}
void
putactivity(void)
{
	static ulong lastclean;

	if(traceactivity) syslog(0, "dns", "put %d by %d.%d", dnvars.active, getpid(), threadid());
	lock(&dnvars.lk);
	dnvars.active--;
	assert(dnvars.active >= 0); /* "dnvars.active %d", dnvars.active */;

	/*
	 *  clean out old entries and check for new db periodicly
	 */
	if(dnvars.mutex || (needrefresh == 0 && dnvars.active > 0)){
		unlock(&dnvars.lk);
		return;
	}

	/* wait till we're alone */
	dnvars.mutex = 1;
	while(dnvars.active > 0){
		unlock(&dnvars.lk);
		sleep(100);
		lock(&dnvars.lk);
	}
	unlock(&dnvars.lk);

	db2cache(needrefresh);
	dnageall(0);

	/* let others back in */
	lastclean = now;
	needrefresh = 0;
	dnvars.mutex = 0;
}

/*
 *  Attach a single resource record to a domain name.
 *	- Avoid duplicates with already present RR's
 *	- Chain all RR's of the same type adjacent to one another
 *	- chain authoritative RR's ahead of non-authoritative ones
 */
static void
rrattach1(RR *new, int auth)
{
	RR **l;
	RR *rp;
	DN *dp;

	assert(new->magic == RRmagic && !new->cached);

	if(!new->db)
		new->expire = new->ttl;
	else
		new->expire = now + Year;
	dp = new->owner;
	assert(dp->magic == DNmagic);
	new->auth |= auth;
	new->next = 0;

	/*
	 *  find first rr of the right type
	 */
	l = &dp->rr;
	for(rp = *l; rp; rp = *l){
		assert(rp->magic == RRmagic && rp->cached);
		if(rp->type == new->type)
			break;
		l = &rp->next;
	}

	/*
	 *  negative entries replace positive entries
	 *  positive entries replace negative entries
	 *  newer entries replace older entries with the same fields
	 */
	for(rp = *l; rp; rp = *l){
		assert(rp->magic == RRmagic && rp->cached);
		if(rp->type != new->type)
			break;

		if(rp->db == new->db && rp->auth == new->auth){
			/* negative drives out positive and vice versa */
			if(rp->negative != new->negative){
				*l = rp->next;
				rp->cached = 0;
				rrfree(rp);
				continue;
			}

			/* all things equal, pick the newer one */
			if(rp->arg0 == new->arg0 && rp->arg1 == new->arg1){
				/* new drives out old */
				if(new->ttl > rp->ttl || new->expire > rp->expire){
					*l = rp->next;
					rp->cached = 0;
					rrfree(rp);
					continue;
				} else {
					rrfree(new);
					return;
				}
			}

			/*  Hack for pointer records.  This makes sure
			 *  the ordering in the list reflects the ordering
			 *  received or read from the database
			 */
			if(rp->type == Tptr){
				if(!rp->negative && !new->negative
				&& rp->ptr->ordinal > new->ptr->ordinal)
					break;
			}
		}
		l = &rp->next;
	}

	/*
	 *  add to chain
	 */
	new->cached = 1;
	new->next = *l;
	*l = new;
}

/*
 *  Attach a list of resource records to a domain name.
 *	- Avoid duplicates with already present RR's
 *	- Chain all RR's of the same type adjacent to one another
 *	- chain authoritative RR's ahead of non-authoritative ones
 *	- remove any expired RR's
 */
void
rrattach(RR *rp, int auth)
{
	RR *next;

	lock(&dnlock);
	for(; rp; rp = next){
		next = rp->next;
		rp->next = 0;

		/* avoid any outside spoofing */
		if(cachedb && !rp->db && inmyarea(rp->owner->name))
			rrfree(rp);
		else
			rrattach1(rp, auth);
	}
	unlock(&dnlock);
}

/*
 *  allocate a resource record of a given type
 */
RR*
rralloc(int type)
{
	RR *rp;

	rp = emalloc(sizeof(*rp));
	rp->magic = RRmagic;
	rp->pc = getcallerpc(&type);
	rp->type = type;
	switch(type){
	case Tsoa:
		rp->soa = emalloc(sizeof(*rp->soa));
		rp->soa->slaves = nil;
		break;
	case Tkey:
		rp->key = emalloc(sizeof(*rp->key));
		break;
	case Tcert:
		rp->cert = emalloc(sizeof(*rp->cert));
		break;
	case Tsig:
		rp->sig = emalloc(sizeof(*rp->sig));
		break;
	case Tnull:
		rp->null = emalloc(sizeof(*rp->null));
		break;
	}
	rp->ttl = 0;
	rp->expire = 0;
	rp->next = 0;
	return rp;
}

/*
 *  free a resource record and any related structs
 */
void
rrfree(RR *rp)
{
	DN *dp;
	RR *nrp;
	Txt *t;

	assert(rp->magic = RRmagic);
	assert(!rp->cached);

	dp = rp->owner;
	if(dp){
		assert(dp->magic == DNmagic);
		for(nrp = dp->rr; nrp; nrp = nrp->next)
			assert(nrp != rp); /* "rrfree of live rr" */;
	}

	switch(rp->type){
	case Tsoa:
		freeserverlist(rp->soa->slaves);
		free(rp->soa);
		break;
	case Tkey:
		free(rp->key->data);
		free(rp->key);
		break;
	case Tcert:
		free(rp->cert->data);
		free(rp->cert);
		break;
	case Tsig:
		free(rp->sig->data);
		free(rp->sig);
		break;
	case Tnull:
		free(rp->null->data);
		free(rp->null);
		break;
	case Ttxt:
		while(rp->txt != nil){
			t = rp->txt;
			rp->txt = t->next;
			free(t->p);
			free(t);
		}
		break;
	}

	rp->magic = ~rp->magic;
	free(rp);
}

/*
 *  free a list of resource records and any related structs
 */
void
rrfreelist(RR *rp)
{
	RR *next;

	for(; rp; rp = next){
		next = rp->next;
		rrfree(rp);
	}
}

extern RR**
rrcopy(RR *rp, RR **last)
{
	RR *nrp;
	SOA *soa;
	Key *key;
	Cert *cert;
	Sig *sig;
	Null *null;
	Txt *t, *nt, **l;

	nrp = rralloc(rp->type);
	switch(rp->type){
	case Ttxt:
		*nrp = *rp;
		l = &nrp->txt;
		*l = nil;
		for(t = rp->txt; t != nil; t = t->next){
			nt = emalloc(sizeof(*nt));
			nt->p = estrdup(t->p);
			nt->next = nil;
			*l = nt;
			l = &nt->next;
		}
		break;
	case Tsoa:
		soa = nrp->soa;
		*nrp = *rp;
		nrp->soa = soa;
		*nrp->soa = *rp->soa;
		nrp->soa->slaves = copyserverlist(rp->soa->slaves);
		break;
	case Tkey:
		key = nrp->key;
		*nrp = *rp;
		nrp->key = key;
		*key = *rp->key;
		key->data = emalloc(key->dlen);
		memmove(key->data, rp->key->data, rp->key->dlen);
		break;
	case Tsig:
		sig = nrp->sig;
		*nrp = *rp;
		nrp->sig = sig;
		*sig = *rp->sig;
		sig->data = emalloc(sig->dlen);
		memmove(sig->data, rp->sig->data, rp->sig->dlen);
		break;
	case Tcert:
		cert = nrp->cert;
		*nrp = *rp;
		nrp->cert = cert;
		*cert = *rp->cert;
		cert->data = emalloc(cert->dlen);
		memmove(cert->data, rp->cert->data, rp->cert->dlen);
		break;
	case Tnull:
		null = nrp->null;
		*nrp = *rp;
		nrp->null = null;
		*null = *rp->null;
		null->data = emalloc(null->dlen);
		memmove(null->data, rp->null->data, rp->null->dlen);
		break;
	default:
		*nrp = *rp;
		break;
	}
	nrp->cached = 0;
	nrp->next = 0;
	*last = nrp;
	return &nrp->next;
}

/*
 *  lookup a resource record of a particular type and
 *  class attached to a domain name.  Return copies.
 *
 *  Priority ordering is:
 *	db authoritative
 *	not timed out network authoritative
 *	not timed out network unauthoritative
 *	unauthoritative db
 *
 *  if flag NOneg is set, don't return negative cached entries.
 *  return nothing instead.
 */
RR*
rrlookup(DN *dp, int type, int flag)
{
	RR *rp, *first, **last;

	assert(dp->magic == DNmagic);

	first = 0;
	last = &first;
	lock(&dnlock);

	/* try for an authoritative db entry */
	for(rp = dp->rr; rp; rp = rp->next){
		assert(rp->magic == RRmagic && rp->cached);
		if(rp->db)
		if(rp->auth)
		if(tsame(type, rp->type))
			last = rrcopy(rp, last);
	}
	if(first)
		goto out;

	/* try for an living authoritative network entry */
	for(rp = dp->rr; rp; rp = rp->next){
		if(!rp->db)
		if(rp->auth)
		if(rp->ttl + 60 > now)
		if(tsame(type, rp->type)){
			if(flag == NOneg && rp->negative)
				goto out;
			last = rrcopy(rp, last);
		}
	}
	if(first)
		goto out;

	/* try for an living unauthoritative network entry */
	for(rp = dp->rr; rp; rp = rp->next){
		if(!rp->db)
		if(rp->ttl + 60 > now)
		if(tsame(type, rp->type)){
			if(flag == NOneg && rp->negative)
				goto out;
			last = rrcopy(rp, last);
		}
	}
	if(first)
		goto out;

	/* try for an unauthoritative db entry */
	for(rp = dp->rr; rp; rp = rp->next){
		if(rp->db)
		if(tsame(type, rp->type))
			last = rrcopy(rp, last);
	}
	if(first)
		goto out;

	/* otherwise, settle for anything we got (except for negative caches)  */
	for(rp = dp->rr; rp; rp = rp->next){
		if(tsame(type, rp->type)){
			if(rp->negative)
				goto out;
			last = rrcopy(rp, last);
		}
	}

out:
	unlock(&dnlock);
	unique(first);
	return first;
}

/*
 *  convert an ascii RR type name to its integer representation
 */
int
rrtype(char *atype)
{
	int i;

	for(i = 0; i <= Tall; i++)
		if(rrtname[i] && strcmp(rrtname[i], atype) == 0)
			return i;

	// make any a synonym for all
	if(strcmp(atype, "any") == 0)
		return Tall;
	return atoi(atype);
}

/*
 *  convert an integer RR type to it's ascii name
 */
char*
rrname(int type, char *buf, int len)
{
	char *t;

	t = 0;
	if(type <= Tall)
		t = rrtname[type];
	if(t==0){
		snprint(buf, len, "%d", type);
		t = buf;
	}
	return t;
}

/*
 *  return 0 if not a supported rr type
 */
int
rrsupported(int type)
{
	if(type < 0 || type >Tall)
		return 0;
	return rrtname[type] != 0;
}

/*
 *  compare 2 types
 */
int
tsame(int t1, int t2)
{
	return t1 == t2 || t1 == Tall;
}

/*
 *  Add resource records to a list, duplicate them if they are cached
 *  RR's since these are shared.
 */
RR*
rrcat(RR **start, RR *rp)
{
	RR **last;

	last = start;
	while(*last != 0)
		last = &(*last)->next;

	*last = rp;
	return *start;
}

/*
 *  remove negative cache rr's from an rr list
 */
RR*
rrremneg(RR **l)
{
	RR **nl, *rp;
	RR *first;

	first = nil;
	nl = &first;
	while(*l != nil){
		rp = *l;
		if(rp->negative){
			*l = rp->next;
			*nl = rp;
			nl = &rp->next;
			*nl = nil;
		} else
			l = &rp->next;
	}

	return first;
}

/*
 *  remove rr's of a particular type from an rr list
 */
RR*
rrremtype(RR **l, int type)
{
	RR **nl, *rp;
	RR *first;

	first = nil;
	nl = &first;
	while(*l != nil){
		rp = *l;
		if(rp->type == type){
			*l = rp->next;
			*nl = rp;
			nl = &rp->next;
			*nl = nil;
		} else
			l = &(*l)->next;
	}

	return first;
}

/*
 *  print conversion for rr records
 */
int
rrfmt(Fmt *f)
{
	RR *rp;
	char *strp;
	Fmt fstr;
	int rv;
	char buf[Domlen];
	Server *s;
	Txt *t;

	fmtstrinit(&fstr);

	rp = va_arg(f->args, RR*);
	if(rp == 0){
		fmtprint(&fstr, "<null>");
		goto out;
	}

	fmtprint(&fstr, "%s %s", rp->owner->name,
		rrname(rp->type, buf, sizeof buf));

	if(rp->negative){
		fmtprint(&fstr, "\tnegative - rcode %d", rp->negrcode);
		goto out;
	}

	switch(rp->type){
	case Thinfo:
		fmtprint(&fstr, "\t%s %s", rp->cpu->name, rp->os->name);
		break;
	case Tcname:
	case Tmb:
	case Tmd:
	case Tmf:
	case Tns:
		fmtprint(&fstr, "\t%s", rp->host->name);
		break;
	case Tmg:
	case Tmr:
		fmtprint(&fstr, "\t%s", rp->mb->name);
		break;
	case Tminfo:
		fmtprint(&fstr, "\t%s %s", rp->mb->name, rp->rmb->name);
		break;
	case Tmx:
		fmtprint(&fstr, "\t%lud %s", rp->pref, rp->host->name);
		break;
	case Ta:
	case Taaaa:
		fmtprint(&fstr, "\t%s", rp->ip->name);
		break;
	case Tptr:
//		fmtprint(&fstr, "\t%s(%lud)", rp->ptr->name, rp->ptr->ordinal);
		fmtprint(&fstr, "\t%s", rp->ptr->name);
		break;
	case Tsoa:
		fmtprint(&fstr, "\t%s %s %lud %lud %lud %lud %lud", rp->host->name,
			rp->rmb->name, rp->soa->serial, rp->soa->refresh, rp->soa->retry,
			rp->soa->expire, rp->soa->minttl);
		for(s = rp->soa->slaves; s != nil; s = s->next)
			fmtprint(&fstr, " %s", s->name);
		break;
	case Tnull:
		fmtprint(&fstr, "\t%.*H", rp->null->dlen, rp->null->data);
		break;
	case Ttxt:
		fmtprint(&fstr, "\t");
		for(t = rp->txt; t != nil; t = t->next)
			fmtprint(&fstr, "%s", t->p);
		break;
	case Trp:
		fmtprint(&fstr, "\t%s %s", rp->rmb->name, rp->rp->name);
		break;
	case Tkey:
		fmtprint(&fstr, "\t%d %d %d", rp->key->flags, rp->key->proto,
			rp->key->alg);
		break;
	case Tsig:
		fmtprint(&fstr, "\t%d %d %d %lud %lud %lud %d %s",
			rp->sig->type, rp->sig->alg, rp->sig->labels, rp->sig->ttl,
			rp->sig->exp, rp->sig->incep, rp->sig->tag, rp->sig->signer->name);
		break;
	case Tcert:
		fmtprint(&fstr, "\t%d %d %d",
			rp->sig->type, rp->sig->tag, rp->sig->alg);
		break;
	default:
		break;
	}
out:
	strp = fmtstrflush(&fstr);
	rv = fmtstrcpy(f, strp);
	free(strp);
	return rv;
}

/*
 *  print conversion for rr records in attribute value form
 */
int
rravfmt(Fmt *f)
{
	RR *rp;
	char *strp;
	Fmt fstr;
	int rv;
	Server *s;
	Txt *t;
	int quote;

	fmtstrinit(&fstr);

	rp = va_arg(f->args, RR*);
	if(rp == 0){
		fmtprint(&fstr, "<null>");
		goto out;
	}

	if(rp->type == Tptr)
		fmtprint(&fstr, "ptr=%s", rp->owner->name);
	else
		fmtprint(&fstr, "dom=%s", rp->owner->name);

	switch(rp->type){
	case Thinfo:
		fmtprint(&fstr, " cpu=%s os=%s", rp->cpu->name, rp->os->name);
		break;
	case Tcname:
		fmtprint(&fstr, " cname=%s", rp->host->name);
		break;
	case Tmb:
	case Tmd:
	case Tmf:
		fmtprint(&fstr, " mbox=%s", rp->host->name);
		break;
	case Tns:
		fmtprint(&fstr,  " ns=%s", rp->host->name);
		break;
	case Tmg:
	case Tmr:
		fmtprint(&fstr, " mbox=%s", rp->mb->name);
		break;
	case Tminfo:
		fmtprint(&fstr, " mbox=%s mbox=%s", rp->mb->name, rp->rmb->name);
		break;
	case Tmx:
		fmtprint(&fstr, " pref=%lud mx=%s", rp->pref, rp->host->name);
		break;
	case Ta:
	case Taaaa:
		fmtprint(&fstr, " ip=%s", rp->ip->name);
		break;
	case Tptr:
		fmtprint(&fstr, " dom=%s", rp->ptr->name);
		break;
	case Tsoa:
		fmtprint(&fstr, " ns=%s mbox=%s serial=%lud refresh=%lud retry=%lud expire=%lud ttl=%lud",
			rp->host->name, rp->rmb->name, rp->soa->serial,
			rp->soa->refresh, rp->soa->retry,
			rp->soa->expire, rp->soa->minttl);
		for(s = rp->soa->slaves; s != nil; s = s->next)
			fmtprint(&fstr, " dnsslave=%s", s->name);
		break;
	case Tnull:
		fmtprint(&fstr, " null=%.*H", rp->null->dlen, rp->null->data);
		break;
	case Ttxt:
		fmtprint(&fstr, " txt=");
		quote = 0;
		for(t = rp->txt; t != nil; t = t->next)
			if(strchr(t->p, ' '))
				quote = 1;
		if(quote)
			fmtprint(&fstr, "\"");
		for(t = rp->txt; t != nil; t = t->next)
			fmtprint(&fstr, "%s", t->p);
		if(quote)
			fmtprint(&fstr, "\"");
		break;
	case Trp:
		fmtprint(&fstr, " rp=%s txt=%s", rp->rmb->name, rp->rp->name);
		break;
	case Tkey:
		fmtprint(&fstr, " flags=%d proto=%d alg=%d",
			rp->key->flags, rp->key->proto, rp->key->alg);
		break;
	case Tsig:
		fmtprint(&fstr, " type=%d alg=%d labels=%d ttl=%lud exp=%lud incep=%lud tag=%d signer=%s",
			rp->sig->type, rp->sig->alg, rp->sig->labels, rp->sig->ttl,
			rp->sig->exp, rp->sig->incep, rp->sig->tag, rp->sig->signer->name);
		break;
	case Tcert:
		fmtprint(&fstr, " type=%d tag=%d alg=%d",
			rp->sig->type, rp->sig->tag, rp->sig->alg);
		break;
	default:
		break;
	}
out:
	strp = fmtstrflush(&fstr);
	rv = fmtstrcpy(f, strp);
	free(strp);
	return rv;
}

void
warning(char *fmt, ...)
{
	char dnserr[128];
	va_list arg;

	va_start(arg, fmt);
	vseprint(dnserr, dnserr+sizeof(dnserr), fmt, arg);
	va_end(arg);
	syslog(1, "dns", dnserr);
}

/*
 *  chasing down double free's
 */
void
dncheck(void *p, int dolock)
{
	DN *dp;
	int i;
	RR *rp;

	if(p != nil){
		dp = p;
		assert(dp->magic == DNmagic);
	}

	if(!testing)
		return;

	if(dolock)
		lock(&dnlock);
	for(i = 0; i < HTLEN; i++)
		for(dp = ht[i]; dp; dp = dp->next){
			assert(dp != p);
			assert(dp->magic == DNmagic);
			for(rp = dp->rr; rp; rp = rp->next){
				assert(rp->magic == RRmagic);
				assert(rp->cached);
				assert(rp->owner == dp);
			}
		}
	if(dolock)
		unlock(&dnlock);
}

static int
rrequiv(RR *r1, RR *r2)
{
	return r1->owner == r2->owner
		&& r1->type == r2->type
		&& r1->arg0 == r2->arg0
		&& r1->arg1 == r2->arg1;
}

void
unique(RR *rp)
{
	RR **l, *nrp;

	for(; rp; rp = rp->next){
		l = &rp->next;
		for(nrp = *l; nrp; nrp = *l){
			if(rrequiv(rp, nrp)){
				*l = nrp->next;
				rrfree(nrp);
			} else
				l = &nrp->next;
		}
	}
}

/*
 *  true if second domain is subsumed by the first
 */
int
subsume(char *higher, char *lower)
{
	int hn, ln;

	ln = strlen(lower);
	hn = strlen(higher);
	if(ln < hn)
		return 0;

	if(cistrcmp(lower + ln - hn, higher) != 0)
		return 0;

	if(ln > hn && hn != 0 && lower[ln - hn - 1] != '.')
		return 0;

	return 1;
}

/*
 *  randomize the order we return items to provide some
 *  load balancing for servers.
 *
 *  only randomize the first class of entries
 */
RR*
randomize(RR *rp)
{
	RR *first, *last, *x, *base;
	ulong n;

	if(rp == nil || rp->next == nil)
		return rp;

	/* just randomize addresses and mx's */
	for(x = rp; x; x = x->next)
		if(x->type != Ta && x->type != Tmx && x->type != Tns)
			return rp;

	base = rp; 

	n = rand();
	last = first = nil;
	while(rp != nil){
		/* stop randomizing if we've moved past our class */
		if(base->auth != rp->auth || base->db != rp->db){
			last->next = rp;
			break;
		}

		/* unchain */
		x = rp;
		rp = x->next;
		x->next = nil;

		if(n&1){
			/* add to tail */
			if(last == nil)
				first = x;
			else
				last->next = x;
			last = x;
		} else {
			/* add to head */
			if(last == nil)
				last = x;
			x->next = first;
			first = x;
		}

		/* reroll the dice */
		n >>= 1;
	}
	return first;
}

static int
sencodefmt(Fmt *f)
{
	char *out;
	char *buf;
	int i, len;
	int ilen;
	int rv;
	uchar *b;
	char obuf[64];	// rsc optimization

	if(!(f->flags&FmtPrec) || f->prec < 1)
		goto error;

	b = va_arg(f->args, uchar*);
	if(b == nil)
		goto error;

	/* if it's a printable, go for it */
	len = f->prec;
	for(i = 0; i < len; i++)
		if(!isprint(b[i]))
			break;
	if(i == len){
		if(len >= sizeof obuf)
			len = sizeof(obuf)-1;
		memmove(obuf, b, len);
		obuf[len] = 0;
		fmtstrcpy(f, obuf);
		return 0;
	}

	ilen = f->prec;
	f->prec = 0;
	f->flags &= ~FmtPrec;
	switch(f->r){
	case '<':
		len = (8*ilen+4)/5 + 3;
		break;
	case '[':
		len = (8*ilen+5)/6 + 4;
		break;
	case 'H':
		len = 2*ilen + 1;
		break;
	default:
		goto error;
	}

	if(len > sizeof(obuf)){
		buf = malloc(len);
		if(buf == nil)
			goto error;
	} else
		buf = obuf;

	// convert
	out = buf;
	switch(f->r){
	case '<':
		rv = enc32(out, len, b, ilen);
		break;
	case '[':
		rv = enc64(out, len, b, ilen);
		break;
	case 'H':
		rv = enc16(out, len, b, ilen);
		break;
	default:
		rv = -1;
		break;
	}
	if(rv < 0)
		goto error;

	fmtstrcpy(f, buf);
	if(buf != obuf)
		free(buf);
	return 0;

error:
	return fmtstrcpy(f, "<encodefmt>");

}

void*
emalloc(int size)
{
	char *x;

	x = mallocz(size, 1);
	if(x == nil)
		abort();
	setmalloctag(x, getcallerpc(&size));
	return x;
}

char*
estrdup(char *s)
{
	int size;
	char *p;

	size = strlen(s)+1;
	p = mallocz(size, 0);
	if(p == nil)
		abort();
	memmove(p, s, size);
	setmalloctag(p, getcallerpc(&s));
	return p;
}

/*
 *  create a pointer record
 */
static RR*
mkptr(DN *dp, char *ptr, ulong ttl)
{
	DN *ipdp;
	RR *rp;

	ipdp = dnlookup(ptr, Cin, 1);

	rp = rralloc(Tptr);
	rp->ptr = dp;
	rp->owner = ipdp;
	rp->db = 1;
	if(ttl)
		rp->ttl = ttl;
	return rp;
}

/*
 *  look for all ip addresses in this network and make
 *  pointer records for them.
 */
void
dnptr(uchar *net, uchar *mask, char *dom, int bytes, int ttl)
{
	int i, j;
	DN *dp;
	RR *rp, *nrp, *first, **l;
	uchar ip[IPaddrlen];
	uchar nnet[IPaddrlen];
	char ptr[Domlen];
	char *p, *e;

	l = &first;
	first = nil;
	for(i = 0; i < HTLEN; i++){
		for(dp = ht[i]; dp; dp = dp->next){
			for(rp = dp->rr; rp; rp = rp->next){
				if(rp->type != Ta || rp->negative)
					continue;
				parseip(ip, rp->ip->name);
				maskip(ip, mask, nnet);
				if(ipcmp(net, nnet) != 0)
					continue;
				p = ptr;
				e = ptr+sizeof(ptr);
				for(j = IPaddrlen-1; j >= IPaddrlen-bytes; j--)
					p = seprint(p, e, "%d.", ip[j]);
				seprint(p, e, "%s", dom);
				nrp = mkptr(dp, ptr, ttl);
				*l = nrp;
				l = &nrp->next;
			}
		}
	}

	for(rp = first; rp != nil; rp = nrp){
		nrp = rp->next;
		rp->next = nil;
		rrattach(rp, 1);
	}
}

void
freeserverlist(Server *s)
{
	Server *next;

	for(; s != nil; s = next){
		next = s->next;
		free(s);
	}
}

void
addserver(Server **l, char *name)
{
	Server *s;

	while(*l)
		l = &(*l)->next;
	s = malloc(sizeof(Server)+strlen(name)+1);
	if(s == nil)
		return;
	s->name = (char*)(s+1);
	strcpy(s->name, name);
	s->next = nil;
	*l = s;
}

Server*
copyserverlist(Server *s)
{
	Server *ns;

	
	for(ns = nil; s != nil; s = s->next)
		addserver(&ns, s->name);
	return ns;
}
