Problems about forward zone for subdomain

Hello

System is windows 7 and unbound 1.6.5.

I have below forward zone in server.conf

forward-zone:
name: ‘taobao.com.’
forward-addr: 114.114.114.114

to forward all domain like *.taobao.com to 114 dns server.

But it seems except taobao.com, other subdomains, e.g..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.’
forward-addr: 114.114.114.114

forward-zone:
name: ‘qq.com
forward-addr: 114.114.114.114

forward-zone:
name: ‘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
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

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
  2. example.com
  3. ab.example.com
  4. www.zxample.com
  5. zxample.com
  6. 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 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

What does it mean?

I want to find NS for www.example.com, It it result to ab.example.com instead of 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

Hi, guys

I have one typo last post.

I remind rbtree_find_less_equal return the exact or closest but bigger result, but in fact it return the exact or closest but smaller result.

But the example result is correct.

Thanks

Hi Newell,