]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
auth zone test for host lookup
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Thu, 1 Feb 2018 15:02:38 +0000 (15:02 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Thu, 1 Feb 2018 15:02:38 +0000 (15:02 +0000)
git-svn-id: file:///svn/unbound/trunk@4488 be551aaa-1e26-0410-a405-d3ace91eadb9

services/authzone.c
testdata/auth_xfr_host.rpl [new file with mode: 0644]

index 853de5f34c81dce90ce12ef4506b84bc19987a77..f2baafb31389a29088b0e830a0780049f7e245a5 100644 (file)
@@ -462,13 +462,17 @@ auth_zones_find_zone(struct auth_zones* az, uint8_t* name, size_t name_len,
                 * but not below it. */
                nm = dname_get_shared_topdomain(z->name, name);
                dname_count_size_labels(nm, &nmlen);
+               z = NULL;
        }
+
        /* search up */
-       while(!z && !dname_is_root(nm)) {
-               dname_remove_label(&nm, &nmlen);
+       while(!z) {
                z = auth_zone_find(az, nm, nmlen, dclass);
+               if(z) return z;
+               if(dname_is_root(nm)) break;
+               dname_remove_label(&nm, &nmlen);
        }
-       return z;
+       return NULL;
 }
 
 /** find or create zone with name str. caller must have lock on az. 
@@ -4043,13 +4047,16 @@ xfr_transfer_lookup_host(struct auth_xfer* xfr, struct module_env* env)
                 edns.udp_size = (uint16_t)sldns_buffer_capacity(buf);
         else    edns.udp_size = 65535;
 
+       /* unlock xfr during mesh_new_callback() because the callback can be
+        * called straight away */
+       lock_basic_unlock(&xfr->lock);
        if(!mesh_new_callback(env->mesh, &qinfo, qflags, &edns, buf, 0,
                &auth_xfer_transfer_lookup_callback, xfr)) {
+               lock_basic_lock(&xfr->lock);
                log_err("out of memory lookup up master %s", master->host);
-               free(qinfo.qname);
                return 0;
        }
-       free(qinfo.qname);
+       lock_basic_lock(&xfr->lock);
        return 1;
 }
 
@@ -4069,10 +4076,13 @@ xfr_transfer_init_fetch(struct auth_xfer* xfr, struct module_env* env)
                memmove(&addr, &xfr->task_transfer->scan_addr->addr, addrlen);
        } else {
                if(!extstrtoaddr(master->host, &addr, &addrlen)) {
+                       /* the ones that are not in addr format are supposed
+                        * to be looked up.  The lookup has failed however,
+                        * so skip them */
                        char zname[255+1];
                        dname_str(xfr->name, zname);
-                       log_err("%s: cannot parse master %s", zname,
-                               master->host);
+                       log_err("%s: failed lookup, cannot transfer from master %s",
+                               zname, master->host);
                        return 0;
                }
        }
@@ -4184,6 +4194,12 @@ xfr_master_add_addrs(struct auth_master* m, struct ub_packed_rrset_key* rrset,
                        sa->sin6_port = (in_port_t)htons(UNBOUND_DNS_PORT);
                        memmove(&sa->sin6_addr, rdata, INET6_SIZE);
                }
+               if(verbosity >= VERB_ALGO) {
+                       char s[64];
+                       addr_to_str(&a->addr, a->addrlen, s, sizeof(s));
+                       verbose(VERB_ALGO, "auth host %s lookup %s",
+                               m->host, s);
+               }
                /* append to list */
                a->next = m->list;
                m->list = a;
@@ -4221,6 +4237,9 @@ void auth_xfer_transfer_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
                        }
                }
        }
+       if(xfr->task_transfer->lookup_target->list &&
+               xfr->task_transfer->lookup_target == xfr_transfer_current_master(xfr))
+               xfr->task_transfer->scan_addr = xfr->task_transfer->lookup_target->list;
 
        /* move to lookup AAAA after A lookup, move to next hostname lookup,
         * or move to fetch the zone, or, if nothing to do, end task_transfer */
@@ -4690,10 +4709,13 @@ xfr_probe_send_probe(struct auth_xfer* xfr, struct module_env* env,
                memmove(&addr, &xfr->task_probe->scan_addr->addr, addrlen);
        } else {
                if(!extstrtoaddr(master->host, &addr, &addrlen)) {
+                       /* the ones that are not in addr format are supposed
+                        * to be looked up.  The lookup has failed however,
+                        * so skip them */
                        char zname[255+1];
                        dname_str(xfr->name, zname);
-                       log_err("%s: cannot parse master %s", zname,
-                               master->host);
+                       log_err("%s: failed lookup, cannot probe to master %s",
+                               zname, master->host);
                        return 0;
                }
        }
@@ -4894,13 +4916,16 @@ xfr_probe_lookup_host(struct auth_xfer* xfr, struct module_env* env)
                 edns.udp_size = (uint16_t)sldns_buffer_capacity(buf);
         else    edns.udp_size = 65535;
 
+       /* unlock xfr during mesh_new_callback() because the callback can be
+        * called straight away */
+       lock_basic_unlock(&xfr->lock);
        if(!mesh_new_callback(env->mesh, &qinfo, qflags, &edns, buf, 0,
                &auth_xfer_probe_lookup_callback, xfr)) {
+               lock_basic_lock(&xfr->lock);
                log_err("out of memory lookup up master %s", master->host);
-               free(qinfo.qname);
                return 0;
        }
-       free(qinfo.qname);
+       lock_basic_lock(&xfr->lock);
        return 1;
 }
 
@@ -4916,6 +4941,7 @@ xfr_probe_send_or_end(struct auth_xfer* xfr, struct module_env* env)
                         * and we may then get an instant cache response,
                         * and that calls the callback just like a full
                         * lookup and lookup failures also call callback */
+                       lock_basic_unlock(&xfr->lock);
                        return;
                }
                xfr_probe_move_to_next_lookup(xfr, env);
@@ -4925,6 +4951,7 @@ xfr_probe_send_or_end(struct auth_xfer* xfr, struct module_env* env)
        while(!xfr_probe_end_of_list(xfr)) {
                if(xfr_probe_send_probe(xfr, env, AUTH_PROBE_TIMEOUT)) {
                        /* successfully sent probe, wait for callback */
+                       lock_basic_unlock(&xfr->lock);
                        return;
                }
                /* failed to send probe, next master */
@@ -4947,6 +4974,7 @@ void auth_xfer_probe_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
        struct auth_xfer* xfr = (struct auth_xfer*)arg;
        struct module_env* env;
        log_assert(xfr->task_probe);
+       lock_basic_lock(&xfr->lock);
        env = xfr->task_probe->env;
 
        /* process result */
@@ -4970,6 +4998,9 @@ void auth_xfer_probe_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
                        }
                }
        }
+       if(xfr->task_probe->lookup_target->list &&
+               xfr->task_probe->lookup_target == xfr_probe_current_master(xfr))
+               xfr->task_probe->scan_addr = xfr->task_probe->lookup_target->list;
 
        /* move to lookup AAAA after A lookup, move to next hostname lookup,
         * or move to send the probes, or, if nothing to do, end task_probe */
@@ -5017,7 +5048,6 @@ auth_xfer_timer(void* arg)
                /* pick up the probe task ourselves */
                xfr->task_probe->worker = env->worker;
                xfr->task_probe->env = env;
-               lock_basic_unlock(&xfr->lock);
                xfr->task_probe->cp = NULL;
 
                /* start the task */
diff --git a/testdata/auth_xfr_host.rpl b/testdata/auth_xfr_host.rpl
new file mode 100644 (file)
index 0000000..4b3b187
--- /dev/null
@@ -0,0 +1,247 @@
+; config options
+server:
+       target-fetch-policy: "0 0 0 0 0"
+
+auth-zone:
+       name: "example.com."
+       ## zonefile (or none).
+       ## zonefile: "example.com.zone"
+       ## master by IP address or hostname
+       ## can list multiple masters, each on one line.
+       ## master:
+       master: ns.example.net.
+       #master: 1.2.3.44
+       ## url for http fetch
+       ## url:
+       ## queries from downstream clients get authoritative answers.
+       ## for-downstream: yes
+       for-downstream: yes
+       ## queries are used to fetch authoritative answers from this zone,
+       ## instead of unbound itself sending queries there.
+       ## for-upstream: yes
+       for-upstream: yes
+       ## on failures with for-upstream, fallback to sending queries to
+       ## the authority servers
+       ## fallback-enabled: no
+
+       ## this line generates zonefile: \n"/tmp/xxx.example.com"\n
+       zonefile:
+TEMPFILE_NAME example.com
+       ## this is the inline file /tmp/xxx.example.com
+       ## the tempfiles are deleted when the testrun is over.
+TEMPFILE_CONTENTS example.com
+TEMPFILE_END
+
+stub-zone:
+       name: "."
+       stub-addr: 193.0.14.129         # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test authority zone that needs host name lookup
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+       ADDRESS 193.0.14.129 
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS        K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET.    IN      A       193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION AUTHORITY
+com.   IN NS   a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net.    IN      A       192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.net. IN A
+SECTION ANSWER
+ns.example.net. IN A   1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.net. IN AAAA
+SECTION ANSWER
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+       ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com.   IN NS   a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net.    IN      A       192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION AUTHORITY
+example.com.   IN NS   ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.44
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+       ADDRESS 1.2.3.44
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com.   IN NS   ns.example.com.
+SECTION ADDITIONAL
+ns.example.com.                IN      A       1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN A
+SECTION ANSWER
+ns.example.com. IN A   1.2.3.44
+SECTION AUTHORITY
+example.com.   IN NS   ns.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION AUTHORITY
+example.com.   IN NS   ns.example.com.
+SECTION ADDITIONAL
+www.example.com. IN A  1.2.3.44
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com.   IN NS   ns.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A  10.20.30.40
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN SOA
+SECTION ANSWER
+; serial, refresh, retry, expire, minimum
+example.com. IN SOA ns.example.com. hostmaster.example.com. 1 3600 900 86400 3600
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN AXFR
+SECTION ANSWER
+example.com. IN SOA ns.example.com. hostmaster.example.com. 1 3600 900 86400 3600
+example.com.   IN NS   ns.example.com.
+www.example.com. IN A  1.2.3.4
+example.com. IN SOA ns.example.com. hostmaster.example.com. 1 3600 900 86400 3600
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR AA RD RA SERVFAIL
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+ENTRY_END
+
+STEP 30 TIME_PASSES ELAPSE 10
+STEP 40 TRAFFIC
+
+STEP 50 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 60 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR AA RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A  1.2.3.4
+ENTRY_END
+
+; the zonefile was updated with new contents
+STEP 70 CHECK_TEMPFILE example.com
+FILE_BEGIN
+example.com.   3600    IN      SOA     ns.example.com. hostmaster.example.com. 1 3600 900 86400 3600
+example.com.   3600    IN      NS      ns.example.com.
+www.example.com.       3600    IN      A       1.2.3.4
+FILE_END
+
+SCENARIO_END