示例#1
0
文件: dname.c 项目: chigumaya/unbound
uint8_t* dname_get_shared_topdomain(uint8_t* d1, uint8_t* d2)
{
    int labs1, labs2, m;
    size_t len = LDNS_MAX_DOMAINLEN;
    labs1 = dname_count_labels(d1);
    labs2 = dname_count_labels(d2);
    (void)dname_lab_cmp(d1, labs1, d2, labs2, &m);
    dname_remove_labels(&d1, &len, labs1-m);
    return d1;
}
示例#2
0
/**
 * Given a qname and its proven closest encloser, calculate the "next
 * closest" name. Basically, this is the name that is one label longer than
 * the closest encloser that is still a subdomain of qname.
 *
 * @param qname: query name.
 * @param qnamelen: length of qname.
 * @param ce: closest encloser
 * @param nm: result name.
 * @param nmlen: length of nm.
 */
static void
next_closer(uint8_t* qname, size_t qnamelen, uint8_t* ce, 
	uint8_t** nm, size_t* nmlen)
{
	int strip = dname_count_labels(qname) - dname_count_labels(ce) -1;
	*nm = qname;
	*nmlen = qnamelen;
	if(strip>0)
		dname_remove_labels(nm, nmlen, strip);
}
示例#3
0
int 
val_rrset_wildcard(struct ub_packed_rrset_key* rrset, uint8_t** wc)
{
	struct packed_rrset_data* d = (struct packed_rrset_data*)rrset->
		entry.data;
	uint8_t labcount;
	int labdiff;
	uint8_t* wn;
	size_t i, wl;
	if(d->rrsig_count == 0) {
		return 1;
	}
	labcount = rrsig_get_labcount(d, d->count + 0);
	/* check rest of signatures identical */
	for(i=1; i<d->rrsig_count; i++) {
		if(labcount != rrsig_get_labcount(d, d->count + i)) {
			return 0;
		}
	}
	/* OK the rrsigs check out */
	/* if the RRSIG label count is shorter than the number of actual 
	 * labels, then this rrset was synthesized from a wildcard.
	 * Note that the RRSIG label count doesn't count the root label. */
	wn = rrset->rk.dname;
	wl = rrset->rk.dname_len;
	/* skip a leading wildcard label in the dname (RFC4035 2.2) */
	if(dname_is_wild(wn)) {
		wn += 2;
		wl -= 2;
	}
	labdiff = (dname_count_labels(wn) - 1) - (int)labcount;
	if(labdiff > 0) {
		*wc = wn;
		dname_remove_labels(wc, &wl, labdiff);
		return 1;
	}
	return 1;
}
示例#4
0
/** enter implicit transparent zone for local-data: without local-zone: */
static int
lz_setup_implicit(struct local_zones* zones, struct config_file* cfg)
{
	/* walk over all items that have no parent zone and find
	 * the name that covers them all (could be the root) and
	 * add that as a transparent zone */
	struct config_strlist* p;
	int have_name = 0;
	int have_other_classes = 0;
	uint16_t dclass = 0;
	uint8_t* nm = 0;
	size_t nmlen = 0;
	int nmlabs = 0;
	int match = 0; /* number of labels match count */

	init_parents(zones); /* to enable local_zones_lookup() */
	for(p = cfg->local_data; p; p = p->next) {
		uint8_t* rr_name;
		uint16_t rr_class;
		size_t len;
		int labs;
		if(!get_rr_nameclass(p->str, &rr_name, &rr_class)) {
			log_err("Bad local-data RR %s", p->str);
			return 0;
		}
		labs = dname_count_size_labels(rr_name, &len);
		lock_rw_rdlock(&zones->lock);
		if(!local_zones_lookup(zones, rr_name, len, labs, rr_class)) {
			if(!have_name) {
				dclass = rr_class;
				nm = rr_name;
				nmlen = len;
				nmlabs = labs;
				match = labs;
				have_name = 1;
			} else {
				int m;
				if(rr_class != dclass) {
					/* process other classes later */
					free(rr_name);
					have_other_classes = 1;
					lock_rw_unlock(&zones->lock);
					continue;
				}
				/* find smallest shared topdomain */
				(void)dname_lab_cmp(nm, nmlabs, 
					rr_name, labs, &m);
				free(rr_name);
				if(m < match)
					match = m;
			}
		} else free(rr_name);
		lock_rw_unlock(&zones->lock);
	}
	if(have_name) {
		uint8_t* n2;
		struct local_zone* z;
		/* allocate zone of smallest shared topdomain to contain em */
		n2 = nm;
		dname_remove_labels(&n2, &nmlen, nmlabs - match);
		n2 = memdup(n2, nmlen);
		free(nm);
		if(!n2) {
			log_err("out of memory");
			return 0;
		}
		log_nametypeclass(VERB_ALGO, "implicit transparent local-zone", 
			n2, 0, dclass);
		if(!(z=lz_enter_zone_dname(zones, n2, nmlen, match, 
			local_zone_transparent, dclass))) {
			return 0;
		}
		lock_rw_unlock(&z->lock);
	}
	if(have_other_classes) { 
		/* restart to setup other class */
		return lz_setup_implicit(zones, cfg);
	}
	return 1;
}