Maintained by: NLnet Labs

Problems about forward zone for subdomain

Newell Zhu
Thu Sep 14 13:52:51 CEST 2017


I do some research from the source code. And find some interesting.

The forward zones will be build into a Red-Black tree. And the compare function is: int dname_lab_cmp(uint8_t* d1, int labs1, uint8_t* d2, int labs2, int* mlabs)(source code attached last).

In my option, the compare function is about this rules:

1. Compare same No. label from left to right.
2. For Same No. label, longer is bigger
3. Else If label has same length, later character is bigger
4. Else, have more labels is bigger

e.g.
1. www.example.com <http://www.example.com/>
2. example.com <http://example.com/>
3. ab.example.com <http://ab.example.com/>
4. www.zxample.com <http://www.zxample.com/>
5. zxample.com
6. longexample.com <http://longexample.com/>


the sorted order muse be: 6 > 4 > 5 > 1 > 3 > 2.

Now suppose we build the Red-Black tree without 1. the right order is: 6 > 4 > 5 > 3 > 2.

And Let’s lookup www.example.com <http://www.example.com/> from the tree. The Search function is below:

int
rbtree_find_less_equal(rbtree_type *rbtree, const void *key,
	rbnode_type **result)
{
	int r;
	rbnode_type *node;

	log_assert(result);
	
	/* We start at root... */
	node = rbtree->root;

	*result = NULL;
	fptr_ok(fptr_whitelist_rbtree_cmp(rbtree->cmp));

	/* While there are children... */
	while (node != RBTREE_NULL) {
		r = rbtree->cmp(key, node->key);
		if (r == 0) {
			/* Exact match */
			*result = node;
			return 1;
		} 
		if (r < 0) {
			node = node->left;
		} else {
			/* Temporary match */
			*result = node;
			node = node->right;
		}
	}
	return 0;
}


It’s clear, It will find the exact or closest but bigger result. according our original order, the result must be 3: ab.example.com <http://ab.example.com/>

What does it mean?

I want to find NS for www.example.com <http://www.example.com/>, It it result to ab.example.com <http://ab.example.com/> instead of example.com <http://example.com/>.


Am I make mistakes or it’s designed to?


int 
dname_lab_cmp(uint8_t* d1, int labs1, uint8_t* d2, int labs2, int* mlabs)
{
	uint8_t len1, len2;
	int atlabel = labs1;
	int lastmlabs;
	int lastdiff = 0;
	/* first skip so that we compare same label. */
	if(labs1 > labs2) {
		while(atlabel > labs2) {
			len1 = *d1++;
			d1 += len1;
			atlabel--;
		}
		log_assert(atlabel == labs2);
	} else if(labs1 < labs2) {
		atlabel = labs2;
		while(atlabel > labs1) {
			len2 = *d2++;
			d2 += len2;
			atlabel--;
		}
		log_assert(atlabel == labs1);
	}
	lastmlabs = atlabel+1;
	/* now at same label in d1 and d2, atlabel */
	/* www.example.com.                  */
	/* 4   3       2  1   atlabel number */
	/* repeat until at root label (which is always the same) */
	while(atlabel > 1) {
		len1 = *d1++;
		len2 = *d2++;
		if(len1 != len2) {
			log_assert(len1 != 0 && len2 != 0);
			if(len1<len2)
				lastdiff = -1;
			else	lastdiff = 1;
			lastmlabs = atlabel;
			d1 += len1;
			d2 += len2;
		} else {
			/* memlowercmp is inlined here; or just like
			 * if((c=memlowercmp(d1, d2, len1)) != 0) { 
			 *	lastdiff = c;
			 *	lastmlabs = atlabel; } apart from d1++,d2++ */
			while(len1) {
				if(*d1 != *d2 && tolower((unsigned char)*d1) 
					!= tolower((unsigned char)*d2)) {
					if(tolower((unsigned char)*d1) < 
						tolower((unsigned char)*d2)) {
						lastdiff = -1;
						lastmlabs = atlabel;
						d1 += len1;
						d2 += len1;
						break;
					}
					lastdiff = 1;
					lastmlabs = atlabel;
					d1 += len1;
					d2 += len1;
					break; /* out of memlowercmp */
				}
				d1++;
				d2++;
				len1--;
			}
		}
		atlabel--;
	}
	/* last difference atlabel number, so number of labels matching,
	 * at the right side, is one less. */
	*mlabs = lastmlabs-1;
	if(lastdiff == 0) {
		/* all labels compared were equal, check if one has more
		 * labels, so that example.com. > com. */
		if(labs1 > labs2)
			return 1;
		else if(labs1 < labs2)
			return -1;
	}
	return lastdiff;
}




Thanks

-- 
Newell Zhu
Blog: http://zlxstar.me/ <http://blog.zlxstar.me/>
Github: http://github.com/zlx
 <http://github.com/zlx>
> On 8 Sep 2017, at 22:12, Newell Zhu <zlx.star at gmail.com> wrote:
> 
> Hello
> 
> System is windows 7 and unbound 1.6.5.
> 
> I have below forward zone in server.conf
> 
> forward-zone:
>       name: 'taobao.com <http://taobao.com/>.'
>       forward-addr: 114.114.114.114
> 
> to forward all domain like *.taobao.com <http://taobao.com/> to 114 dns server.
> 
> But it seems except taobao.com <http://taobao.com/>, other subdomains, e.g..www.taobao.com <http://www.taobao.com/> do not forward to 114.114.114.114
> 
> I test it on ubuntu, and it’s OK.
> 
> So am I missing something in my config?
> 
> My whole server.conf:
> 
> server:
>    access-control: 127.0.0.0/8 allow
>    access-control: 192.168.0.0/16 allow
>    cache-max-ttl: 14400
>    cache-min-ttl: 900
>    hide-identity: yes
>    hide-version: yes
>    interface: 0.0.0.0
>    minimal-responses: yes
>    prefetch: yes
>    qname-minimisation: yes
>    rrset-roundrobin: yes
>    use-caps-for-id: yes
>    verbosity: 4
>    use-syslog: yes
>    log-time-ascii: yes
> 
> forward-zone:
>       name: 'taobao.com <http://taobao.com/>.'
>       forward-addr: 114.114.114.114
> 
> forward-zone:
>       name: 'qq.com <http://qq.com/>'
>       forward-addr: 114.114.114.114
> 
> forward-zone:
>       name: 'baidu.com <http://baidu.com/>'
>       forward-addr: 114.114.114.114
> 
> forward-zone:
>       name: 'cn.'
>       forward-addr: 114.114.114.114
> 
> forward-zone:
>       name: "."
>       forward-addr: 8.8.4.4        # Google
>       forward-addr: 8.8.8.8        # Google
>       forward-addr: 37.235.1.174   # FreeDNS
>       forward-addr: 37.235.1.177   # FreeDNS
>       forward-addr: 50.116.23.211  # OpenNIC
>       forward-addr: 64.6.64.6      # Verisign
>       forward-addr: 64.6.65.6      # Verisign
>       forward-addr: 74.82.42.42    # Hurricane Electric
>       forward-addr: 84.200.69.80   # DNS Watch
>       forward-addr: 84.200.70.40   # DNS Watch
>       forward-addr: 91.239.100.100 # censurfridns.dk <http://censurfridns.dk/>
>       forward-addr: 109.69.8.51    # puntCAT
>       forward-addr: 208.67.222.220 # OpenDNS
>       forward-addr: 208.67.222.222 # OpenDNS
>       forward-addr: 216.146.35.35  # Dyn Public
>       forward-addr: 216.146.36.36  # Dyn Public   

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://unbound.nlnetlabs.nl/pipermail/unbound-users/attachments/20170914/926ffac6/attachment-0001.html>