⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dblookup.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <u.h>#include <libc.h>#include <bio.h>#include <ndb.h>#include <ip.h>#include "dns.h"static Ndb *db;static RR*	dblookup1(char*, int, int, int);static RR*	addrrr(Ndbtuple*, Ndbtuple*);static RR*	nsrr(Ndbtuple*, Ndbtuple*);static RR*	cnamerr(Ndbtuple*, Ndbtuple*);static RR*	mxrr(Ndbtuple*, Ndbtuple*);static RR*	soarr(Ndbtuple*, Ndbtuple*);static RR*	ptrrr(Ndbtuple*, Ndbtuple*);static Ndbtuple* look(Ndbtuple*, Ndbtuple*, char*);static RR*	doaxfr(Ndb*, char*);static RR*	nullrr(Ndbtuple *entry, Ndbtuple *pair);static RR*	txtrr(Ndbtuple *entry, Ndbtuple *pair);static Lock	dblock;static void	createptrs(void);static int	implemented[Tall] ={	[Ta]		1,	[Tns]		1,	[Tsoa]		1,	[Tmx]		1,	[Tptr]		1,	[Tcname]	1,	[Tnull]		1,	[Ttxt]		1,};static voidnstrcpy(char *to, char *from, int len){	strncpy(to, from, len);	to[len-1] = 0;}intopendatabase(void){	char buf[256];	Ndb *xdb;	if(db == nil){		snprint(buf, sizeof(buf), "%s/ndb", mntpt);		xdb = ndbopen(dbfile);		if(xdb != nil)			xdb->nohash = 1;		db = ndbcat(ndbopen(buf), xdb);	}	if(db == nil)		return -1;	else		return 0;}/* *  lookup an RR in the network database, look for matches *  against both the domain name and the wildcarded domain name. * *  the lock makes sure only one process can be accessing the data *  base at a time.  This is important since there's a lot of *  shared state there. * *  e.g. for x.research.bell-labs.com, first look for a match against *       the x.research.bell-labs.com.  If nothing matches, try *.research.bell-labs.com. */RR*dblookup(char *name, int class, int type, int auth, int ttl){	RR *rp, *tp;	char buf[256];	char *wild, *cp;	DN *dp, *ndp;	int err;	static int parallel;	static int parfd[2];	static char token[1];	/* so far only internet lookups are implemented */	if(class != Cin)		return 0;	err = Rname;	if(type == Tall){		rp = 0;		for (type = Ta; type < Tall; type++)			if(implemented[type])				rrcat(&rp, dblookup(name, class, type, auth, ttl));		return rp;	}	lock(&dblock);	dp = dnlookup(name, class, 1);	if(opendatabase() < 0)		goto out;	if(dp->rr)		err = 0;	/* first try the given name */	rp = 0;	if(cachedb)		rp = rrlookup(dp, type, NOneg);	else		rp = dblookup1(name, type, auth, ttl);	if(rp)		goto out;	/* try lower case version */	for(cp = name; *cp; cp++)		*cp = tolower(*cp);	if(cachedb)		rp = rrlookup(dp, type, NOneg);	else		rp = dblookup1(name, type, auth, ttl);	if(rp)		goto out;	/* walk the domain name trying the wildcard '*' at each position */	for(wild = strchr(name, '.'); wild; wild = strchr(wild+1, '.')){		snprint(buf, sizeof(buf), "*%s", wild);		ndp = dnlookup(buf, class, 1);		if(ndp->rr)			err = 0;		if(cachedb)			rp = rrlookup(ndp, type, NOneg);		else			rp = dblookup1(buf, type, auth, ttl);		if(rp)			break;	}out:	/* add owner to uncached records */	if(rp){		for(tp = rp; tp; tp = tp->next)			tp->owner = dp;	} else {		/* don't call it non-existent if it's not ours */		if(err == Rname && !inmyarea(name))			err = Rserver;		dp->nonexistent = err;	}	unlock(&dblock);	return rp;}/* *  lookup an RR in the network database */static RR*dblookup1(char *name, int type, int auth, int ttl){	Ndbtuple *t, *nt;	RR *rp, *list, **l;	Ndbs s;	char dname[Domlen];	char *attr;	DN *dp;	RR *(*f)(Ndbtuple*, Ndbtuple*);	int found, x;	dp = 0;	switch(type){	case Tptr:		attr = "ptr";		f = ptrrr;		break;	case Ta:		attr = "ip";		f = addrrr;		break;	case Tnull:		attr = "nullrr";		f = nullrr;		break;	case Tns:		attr = "ns";		f = nsrr;		break;	case Tsoa:		attr = "soa";		f = soarr;		break;	case Tmx:		attr = "mx";		f = mxrr;		break;	case Tcname:		attr = "cname";		f = cnamerr;		break;	case Taxfr:	case Tixfr:		return doaxfr(db, name);	default:		return nil;	}	/*	 *  find a matching entry in the database	 */	free(ndbgetvalue(db, &s, "dom", name, attr, &t));	/*	 *  hack for local names	 */	if(t == 0 && strchr(name, '.') == 0)		free(ndbgetvalue(db, &s, "sys", name, attr, &t));	if(t == 0)		return nil;	/* search whole entry for default domain name */	strncpy(dname, name, sizeof dname);	for(nt = t; nt; nt = nt->entry)		if(strcmp(nt->attr, "dom") == 0){			nstrcpy(dname, nt->val, sizeof dname);			break;		}	/* ttl is maximum of soa minttl and entry's ttl ala rfc883 */	nt = look(t, s.t, "ttl");	if(nt){		x = atoi(nt->val);		if(x > ttl)			ttl = x;	}	/* default ttl is one day */	if(ttl < 0)		ttl = DEFTTL;	/*	 *  The database has 2 levels of precedence; line and entry.	 *  Pairs on the same line bind tighter than pairs in the	 *  same entry, so we search the line first.	 */	found = 0;	list = 0;	l = &list;	for(nt = s.t;; ){		if(found == 0 && strcmp(nt->attr, "dom") == 0){			nstrcpy(dname, nt->val, sizeof dname);			found = 1;		}		if(cistrcmp(attr, nt->attr) == 0){			rp = (*f)(t, nt);			rp->auth = auth;			rp->db = 1;			if(ttl)				rp->ttl = ttl;			if(dp == 0)				dp = dnlookup(dname, Cin, 1);			rp->owner = dp;			*l = rp;			l = &rp->next;			nt->ptr = 1;		}		nt = nt->line;		if(nt == s.t)			break;	}	/* search whole entry */	for(nt = t; nt; nt = nt->entry)		if(nt->ptr == 0 && cistrcmp(attr, nt->attr) == 0){			rp = (*f)(t, nt);			rp->db = 1;			if(ttl)				rp->ttl = ttl;			rp->auth = auth;			if(dp == 0)				dp = dnlookup(dname, Cin, 1);			rp->owner = dp;			*l = rp;			l = &rp->next;		}	ndbfree(t);	return list;}/* *  make various types of resource records from a database entry */static RR*addrrr(Ndbtuple *entry, Ndbtuple *pair){	RR *rp;	uchar addr[IPaddrlen];	USED(entry);	parseip(addr, pair->val);	if(isv4(addr))		rp = rralloc(Ta);	else		rp = rralloc(Taaaa);	rp->ip = dnlookup(pair->val, Cin, 1);	return rp;}static RR*nullrr(Ndbtuple *entry, Ndbtuple *pair){	RR *rp;	USED(entry);	rp = rralloc(Tnull);	rp->null->data = (uchar*)estrdup(pair->val);	rp->null->dlen = strlen((char*)rp->null->data);	return rp;}/* *  txt rr strings are at most 255 bytes long.  one *  can represent longer strings by multiple concatenated *  <= 255 byte ones. */static RR*txtrr(Ndbtuple *entry, Ndbtuple *pair){	RR *rp;	Txt *t, **l;	int i, len, sofar;	USED(entry);	rp = rralloc(Ttxt);	l = &rp->txt;	rp->txt = nil;	len = strlen(pair->val);	sofar = 0;	while(len > sofar){		t = emalloc(sizeof(*t));		t->next = nil;		i = len-sofar;		if(i > 255)			i = 255;		t->p = emalloc(i+1);		memmove(t->p, pair->val+sofar, i);		t->p[i] = 0;		sofar += i;		*l = t;		l = &t->next;	}	return rp;}static RR*cnamerr(Ndbtuple *entry, Ndbtuple *pair){	RR *rp;	USED(entry);	rp = rralloc(Tcname);	rp->host = dnlookup(pair->val, Cin, 1);	return rp;}static RR*mxrr(Ndbtuple *entry, Ndbtuple *pair){	RR * rp;	rp = rralloc(Tmx);	rp->host = dnlookup(pair->val, Cin, 1);	pair = look(entry, pair, "pref");	if(pair)		rp->pref = atoi(pair->val);	else		rp->pref = 1;	return rp;}static RR*nsrr(Ndbtuple *entry, Ndbtuple *pair){	RR *rp;	Ndbtuple *t;	rp = rralloc(Tns);	rp->host = dnlookup(pair->val, Cin, 1);	t = look(entry, pair, "soa");	if(t && t->val[0] == 0)		rp->local = 1;	return rp;}static RR*ptrrr(Ndbtuple *entry, Ndbtuple *pair){	RR *rp;	USED(entry);	rp = rralloc(Tns);	rp->ptr = dnlookup(pair->val, Cin, 1);	return rp;}static RR*soarr(Ndbtuple *entry, Ndbtuple *pair){	RR *rp;	Ndbtuple *ns, *mb, *t;	char mailbox[Domlen];	Ndb *ndb;	char *p;	rp = rralloc(Tsoa);	rp->soa->serial = 1;	for(ndb = db; ndb; ndb = ndb->next)		if(ndb->mtime > rp->soa->serial)			rp->soa->serial = ndb->mtime;	rp->soa->refresh = Day;	rp->soa->retry = Hour;	rp->soa->expire = Day;	rp->soa->minttl = Day;	t = look(entry, pair, "retry");	if(t)		rp->soa->retry = atoi(t->val);	t = look(entry, pair, "expire");	if(t)		rp->soa->expire = atoi(t->val);	t = look(entry, pair, "ttl");	if(t)		rp->soa->minttl = atoi(t->val);	t = look(entry, pair, "refresh");	if(t)		rp->soa->refresh = atoi(t->val);	t = look(entry, pair, "serial");	if(t)		rp->soa->serial = strtoul(t->val, 0, 10);	ns = look(entry, pair, "ns");	if(ns == 0)		ns = look(entry, pair, "dom");	rp->host = dnlookup(ns->val, Cin, 1);	/* accept all of:	 *  mbox=person	 *  mbox=person@machine.dom	 *  mbox=person.machine.dom	 */	mb = look(entry, pair, "mbox");	if(mb == nil)		mb = look(entry, pair, "mb");	if(mb){		if(strchr(mb->val, '.')) {			p = strchr(mb->val, '@');			if(p != nil)				*p = '.';			rp->rmb = dnlookup(mb->val, Cin, 1);		} else {			snprint(mailbox, sizeof(mailbox), "%s.%s",				mb->val, ns->val);			rp->rmb = dnlookup(mailbox, Cin, 1);		}	} else {		snprint(mailbox, sizeof(mailbox), "postmaster.%s",			ns->val);		rp->rmb = dnlookup(mailbox, Cin, 1);	}	/*  hang dns slaves off of the soa.  this is 	 *  for managing the area.	 */	for(t = entry; t != nil; t = t->entry)		if(strcmp(t->attr, "dnsslave") == 0)			addserver(&rp->soa->slaves, t->val);				return rp;}/*

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -