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

📄 dblookup.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
 *  Look for a pair with the given attribute.  look first on the same line, *  then in the whole entry. */static Ndbtuple*look(Ndbtuple *entry, Ndbtuple *line, char *attr){	Ndbtuple *nt;	/* first look on same line (closer binding) */	for(nt = line;;){		if(cistrcmp(attr, nt->attr) == 0)			return nt;		nt = nt->line;		if(nt == line)			break;	}	/* search whole tuple */	for(nt = entry; nt; nt = nt->entry)		if(cistrcmp(attr, nt->attr) == 0)			return nt;	return 0;}static RR**linkrr(RR *rp, DN *dp, RR **l){	rp->owner = dp;	rp->auth = 1;	rp->db = 1;	*l = rp;	return &rp->next;}/* these are answered specially by the tcp version */static RR*doaxfr(Ndb *db, char *name){	USED(db, name);	return 0;}/* *  read the all the soa's from the database to determine area's. *  this is only used when we're not caching the database. */static voiddbfile2area(Ndb *db){	Ndbtuple *t;	if(debug)		syslog(0, logfile, "rereading %s", db->file);	Bseek(&db->b, 0, 0);	while(t = ndbparse(db)){		ndbfree(t);	}}/* *  read the database into the cache */static voiddbpair2cache(DN *dp, Ndbtuple *entry, Ndbtuple *pair){	RR *rp;	Ndbtuple *t;	static ulong ord;	rp = 0;	if(cistrcmp(pair->attr, "ip") == 0){		dp->ordinal = ord++;		rp = addrrr(entry, pair);	} else 	if(cistrcmp(pair->attr, "ns") == 0){		rp = nsrr(entry, pair);	} else if(cistrcmp(pair->attr, "soa") == 0){		rp = soarr(entry, pair);		addarea(dp, rp, pair);	} else if(cistrcmp(pair->attr, "mx") == 0){		rp = mxrr(entry, pair);	} else if(cistrcmp(pair->attr, "cname") == 0){		rp = cnamerr(entry, pair);	} else if(cistrcmp(pair->attr, "nullrr") == 0){		rp = nullrr(entry, pair);	} else if(cistrcmp(pair->attr, "txtrr") == 0){		rp = txtrr(entry, pair);	}	if(rp == 0)		return;	rp->owner = dp;	rp->db = 1;	t = look(entry, pair, "ttl");	if(t)		rp->ttl = atoi(t->val);	rrattach(rp, 0);}static voiddbtuple2cache(Ndbtuple *t){	Ndbtuple *et, *nt;	DN *dp;	for(et = t; et; et = et->entry){		if(strcmp(et->attr, "dom") == 0){			dp = dnlookup(et->val, Cin, 1);			/* first same line */			for(nt = et->line; nt != et; nt = nt->line){				dbpair2cache(dp, t, nt);				nt->ptr = 1;			}			/* then rest of entry */			for(nt = t; nt; nt = nt->entry){				if(nt->ptr == 0)					dbpair2cache(dp, t, nt);				nt->ptr = 0;			}		}	}}static voiddbfile2cache(Ndb *db){	Ndbtuple *t;	if(debug)		syslog(0, logfile, "rereading %s", db->file);	Bseek(&db->b, 0, 0);	while(t = ndbparse(db)){		dbtuple2cache(t);		ndbfree(t);	}}voiddb2cache(int doit){	Ndb *ndb;	Dir *d;	ulong youngest, temp;	static ulong lastcheck;	static ulong lastyoungest;	/* no faster than once every 2 minutes */	if(now < lastcheck + 2*Min && !doit)		return;	refresh_areas(owned);	lock(&dblock);	if(opendatabase() < 0){		unlock(&dblock);		return;	}	/*	 *  file may be changing as we are reading it, so loop till	 *  mod times are consistent.	 *	 *  we don't use the times in the ndb records because they may	 *  change outside of refreshing our cached knowledge.	 */	for(;;){		lastcheck = now;		youngest = 0;		for(ndb = db; ndb; ndb = ndb->next){			/* the dirfstat avoids walking the mount table each time */			if((d = dirfstat(Bfildes(&ndb->b))) != nil ||			   (d = dirstat(ndb->file)) != nil){				temp = d->mtime;		/* ulong vs int crap */				if(temp > youngest)					youngest = temp;				free(d);			}		}		if(!doit && youngest == lastyoungest)			break;			/* forget our area definition */		freearea(&owned);		freearea(&delegated);			/* reopen all the files (to get oldest for time stamp) */		for(ndb = db; ndb; ndb = ndb->next)			ndbreopen(ndb);		if(cachedb){			/* mark all db records as timed out */			dnagedb();				/* read in new entries */			for(ndb = db; ndb; ndb = ndb->next)				dbfile2cache(ndb);				/* mark as authentic anything in our domain */			dnauthdb();				/* remove old entries */			dnageall(1);		} else {			/* read all the soa's to get database defaults */			for(ndb = db; ndb; ndb = ndb->next)				dbfile2area(ndb);		}		doit = 0;		lastyoungest = youngest;		createptrs();	}	unlock(&dblock);}extern uchar	ipaddr[IPaddrlen];/* *  get all my xxx */Ndbtuple*lookupinfo(char *attr){	char buf[64];	char *a[2];	static Ndbtuple *t;	snprint(buf, sizeof buf, "%I", ipaddr);	a[0] = attr;		lock(&dblock);	if(opendatabase() < 0){		unlock(&dblock);		return nil;	}	t = ndbipinfo(db, "ip", buf, a, 1);	unlock(&dblock);	return t;}char *localservers = "local#dns#servers";char *localserverprefix = "local#dns#server";/* *  return non-zero is this is a bad delegation */intbaddelegation(RR *rp, RR *nsrp, uchar *addr){	Ndbtuple *nt;	static Ndbtuple *t;	if(t == nil)		t = lookupinfo("dom");	if(t == nil)		return 0;	for(; rp; rp = rp->next){		if(rp->type != Tns)			continue;		/* see if delegation is looping */		if(nsrp)		if(rp->owner != nsrp->owner)		if(subsume(rp->owner->name, nsrp->owner->name) &&		   strcmp(nsrp->owner->name, localservers) != 0){			syslog(0, logfile, "delegation loop %R -> %R from %I", nsrp, rp, addr);			return 1;		}		/* see if delegating to us what we don't own */		for(nt = t; nt != nil; nt = nt->entry)			if(rp->host && cistrcmp(rp->host->name, nt->val) == 0)				break;		if(nt != nil && !inmyarea(rp->owner->name)){			syslog(0, logfile, "bad delegation %R from %I", rp, addr);			return 1;		}	}	return 0;}static voidaddlocaldnsserver(DN *dp, int class, char *ipaddr, int i){	DN *nsdp;	RR *rp;	char buf[32];	/* ns record for name server, make up an impossible name */	rp = rralloc(Tns);	snprint(buf, sizeof(buf), "%s%d", localserverprefix, i);	nsdp = dnlookup(buf, class, 1);	rp->host = nsdp;	rp->owner = dp;	rp->local = 1;	rp->db = 1;	rp->ttl = 10*Min;	rrattach(rp, 1);	/* A record */	rp = rralloc(Ta);	rp->ip = dnlookup(ipaddr, class, 1);	rp->owner = nsdp;	rp->local = 1;	rp->db = 1;	rp->ttl = 10*Min;	rrattach(rp, 1);}/* *  return list of dns server addresses to use when *  acting just as a resolver. */RR*dnsservers(int class){	Ndbtuple *t, *nt;	RR *nsrp;	DN *dp;	char *p;	int i, n;	char *buf, *args[5];	dp = dnlookup(localservers, class, 1);	nsrp = rrlookup(dp, Tns, NOneg);	if(nsrp != nil)		return nsrp;	p = getenv("DNSSERVER");	if(p != nil){		buf = estrdup(p);		n = tokenize(buf, args, nelem(args));		for(i = 0; i < n; i++)			addlocaldnsserver(dp, class, args[i], i);		free(buf);	} else {		t = lookupinfo("@dns");		if(t == nil)			return nil;		i = 0;		for(nt = t; nt != nil; nt = nt->entry){			addlocaldnsserver(dp, class, nt->val, i);			i++;		}		ndbfree(t);	}	return rrlookup(dp, Tns, NOneg);}static voidaddlocaldnsdomain(DN *dp, int class, char *domain){	RR *rp;	/* A record */	rp = rralloc(Tptr);	rp->ptr = dnlookup(domain, class, 1);	rp->owner = dp;	rp->db = 1;	rp->ttl = 10*Min;	rrattach(rp, 1);}/* *  return list of domains to use when resolving names without '.'s */RR*domainlist(int class){	Ndbtuple *t, *nt;	RR *rp;	DN *dp;	dp = dnlookup("local#dns#domains", class, 1);	rp = rrlookup(dp, Tptr, NOneg);	if(rp != nil)		return rp;	t = lookupinfo("dnsdomain");	if(t == nil)		return nil;	for(nt = t; nt != nil; nt = nt->entry)		addlocaldnsdomain(dp, class, nt->val);	ndbfree(t);	return rrlookup(dp, Tptr, NOneg);}char *v4ptrdom = ".in-addr.arpa";char *v6ptrdom = ".ip6.arpa";		/* ip6.int deprecated, rfc 3152 */char *attribs[] = {	"ipmask",	0};/* *  create ptrs that are in our areas */static voidcreateptrs(void){	int len, dlen, n;	Area *s;	char *f[40];	char buf[Domlen+1];	uchar net[IPaddrlen];	uchar mask[IPaddrlen];	char ipa[48];	Ndbtuple *t, *nt;	dlen = strlen(v4ptrdom);	for(s = owned; s; s = s->next){		len = strlen(s->soarr->owner->name);		if(len <= dlen)			continue;		if(cistrcmp(s->soarr->owner->name+len-dlen, v4ptrdom) != 0)			continue;		/* get mask and net value */		strncpy(buf, s->soarr->owner->name, sizeof(buf));		buf[sizeof(buf)-1] = 0;		n = getfields(buf, f, nelem(f), 0, ".");		memset(mask, 0xff, IPaddrlen);		ipmove(net, v4prefix);		switch(n){		case 3: /* /8 */			net[IPv4off] = atoi(f[0]);			mask[IPv4off+1] = 0;			mask[IPv4off+2] = 0;			mask[IPv4off+3] = 0;			break;		case 4: /* /16 */			net[IPv4off] = atoi(f[1]);			net[IPv4off+1] = atoi(f[0]);			mask[IPv4off+2] = 0;			mask[IPv4off+3] = 0;			break;		case 5: /* /24 */			net[IPv4off] = atoi(f[2]);			net[IPv4off+1] = atoi(f[1]);			net[IPv4off+2] = atoi(f[0]);			mask[IPv4off+3] = 0;			break;		case 6:	/* rfc2317 */			net[IPv4off] = atoi(f[3]);			net[IPv4off+1] = atoi(f[2]);			net[IPv4off+2] = atoi(f[1]);			net[IPv4off+3] = atoi(f[0]);			sprint(ipa, "%I", net);			t = ndbipinfo(db, "ip", ipa, attribs, 1);			if(t == nil) /* could be a reverse with no forward */				continue;			nt = look(t, t, "ipmask");			if(nt == nil){	/* we're confused */				ndbfree(t);				continue;			}			parseipmask(mask, nt->val);			n = 5;			break;		default:			continue;		}		/* go through all domain entries looking for RR's in this network and create ptrs */		dnptr(net, mask, s->soarr->owner->name, 6-n, 0);	}}

⌨️ 快捷键说明

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