]> git.ipfire.org Git - thirdparty/ldns.git/commitdiff
finally got a correct function for impl. secure tracing
authorMiek Gieben <miekg@NLnetLabs.nl>
Thu, 9 Feb 2006 13:34:24 +0000 (13:34 +0000)
committerMiek Gieben <miekg@NLnetLabs.nl>
Thu, 9 Feb 2006 13:34:24 +0000 (13:34 +0000)
the normal trace function is used as a base for impl. this.

various other updates were made also

drill/TODO [new file with mode: 0644]
drill/chasetrace.c
drill/drill.c
drill/drill.h.in
drill/securetrace.c
drill/tracelogic-olddrill.c [deleted file]

diff --git a/drill/TODO b/drill/TODO
new file mode 100644 (file)
index 0000000..6ad2e8f
--- /dev/null
@@ -0,0 +1 @@
+o (void) s on trace functions?
index 231c70e31e26ee48a7022bde0f61288270fc1d18..e7e68d7702af8155a9f7880543caf6d28543dd3f 100644 (file)
@@ -2,7 +2,7 @@
  * chasetrace.c
  * Where all the hard work concerning chasing
  * and tracing is done
- * (c) 2005 NLnet Labs
+ * (c) 2005, 2006 NLnet Labs
  *
  * See the file LICENSE for the license
  *
@@ -37,7 +37,20 @@ do_trace(ldns_resolver *local_res, ldns_rdf *name, ldns_rr_type t,
        ldns_status status;
        size_t i;
        
+       loop_count = 0;
+       new_nss_a = NULL;
+       new_nss_aaaa = NULL;
+       new_nss = NULL;
+       ns_addr = NULL;
+       final_answer = NULL;
+       p = ldns_pkt_new();
        res = ldns_resolver_new();
+
+       if (!p || !res) {
+                error("Memory allocation failed");
+                return NULL;
+        }
+
        /* transfer some properties of local_res to res,
         * because they were given on the commandline */
        ldns_resolver_set_ip6(res, 
@@ -54,15 +67,7 @@ do_trace(ldns_resolver *local_res, ldns_rdf *name, ldns_rr_type t,
                        ldns_resolver_usevc(local_res));
        ldns_resolver_set_random(res, 
                        ldns_resolver_random(local_res));
-
-       loop_count = 0;
-       new_nss_a = NULL;
-       new_nss_aaaa = NULL;
-       new_nss = NULL;
-       ns_addr = NULL;
-       final_answer = NULL;
-       p = ldns_pkt_new();
-
+       ldns_resolver_set_recursive(res, false);
 
        /* setup the root nameserver in the new resolver */
        if (ldns_resolver_push_nameserver_rr_list(res, global_dns_root) != LDNS_STATUS_OK) {
@@ -205,97 +210,14 @@ do_trace(ldns_resolver *local_res, ldns_rdf *name, ldns_rr_type t,
 }
 
 
-/* do a secure trace from the root down to the local leaf node 
- * requested.
- *
- * this alg is complicated. We try to do it all in one go, resolving
- * and keeping track of the security information
- *
- * update this some more. Miek; TODO
- */
-ldns_status
-do_secure_trace(ldns_resolver *local_res, ldns_rdf *name, ldns_rr_type t, 
-               ldns_rr_class c, ldns_rr_list *trusted_keys)
-{
-       ldns_resolver *res;
-       ldns_pkt *p;
-
-       ldns_rdf   *cur_zone;
-       uint16_t loop_count;
-       ldns_rr_list *keys;
-       ldns_status status;
-       bool secure;
-
-       /* always as for dnskey records, but when secure is true also
-        * ask for DS
-        */
-       
-       secure = true;
-       cur_zone = ldns_dname_new_frm_data(1, ".");
-       res = ldns_resolver_new();
-
-       /* transfer some properties of local_res to res,
-        * because they were given on the commandline */
-       ldns_resolver_set_ip6(res, 
-                       ldns_resolver_ip6(local_res));
-       ldns_resolver_set_port(res, 
-                       ldns_resolver_port(local_res));
-       ldns_resolver_set_debug(res, 
-                       ldns_resolver_debug(local_res));
-       ldns_resolver_set_dnssec(res, 
-                       ldns_resolver_dnssec(local_res));
-       ldns_resolver_set_fail(res, 
-                       ldns_resolver_fail(local_res));
-       ldns_resolver_set_usevc(res, 
-                       ldns_resolver_usevc(local_res));
-       ldns_resolver_set_random(res, 
-                       ldns_resolver_random(local_res));
-
-       loop_count = 0;
-       p = ldns_pkt_new();
-
-       /* setup the root nameserver in the new resolver */
-       if (ldns_resolver_push_nameserver_rr_list(res, global_dns_root) != LDNS_STATUS_OK) {
-               return LDNS_STATUS_ERR;
-       }
-
-       cur_zone = ldns_dname_new_frm_str(".");
-       
-       /* this must be a real query to local_res */
-       status = ldns_resolver_send(&p, local_res, cur_zone, LDNS_RR_TYPE_NS, c, 0);
-
-       if (status == LDNS_STATUS_OK) {
-               drill_pkt_print(stdout, local_res, p);
-       } else {
-               error("cannot use local resolver\n");
-               return LDNS_STATUS_ERR;
-       }
-       /* next ask the for keys */
-       keys = get_rr(res, cur_zone, LDNS_RR_TYPE_DNSKEY, c);
-       if (keys) {
-               ldns_rr_list_print(stdout, keys);
-       } else {
-               secure = false;
-       }
-       if (secure) {
-               /* if true get the DS for the child zone */
-       }
-
-       /* we can now start our decent to the zone we're looking
-        * and query for ds/dnskey along the way
-        */
-       
-
-       return LDNS_STATUS_ERR; /* need to finish this function */
-}
-
+/* do a secure trace from the root down to the local leaf node */
 /**
  * Chase the given rr to a known key
  *
  * Based on drill 0.9
  * pkt optional?
  * TODO: lots 
      if this is moved to the library, status codes should be added and prints removed
* if this is moved to the library, status codes should be added and prints removed
  */
 ldns_status
 do_chase(ldns_resolver *res, ldns_rdf *name, ldns_rr_type type, ldns_rr_class c,
index 0d8455e7b36ae379af09b42b5017b131cf5d2f4f..6c1a830b257e620532601f19d90fdf3f44d15519 100644 (file)
@@ -496,7 +496,7 @@ main(int argc, char *argv[])
                        init_root();
                        qname = ldns_dname_new_frm_str(name);
                        /* don't care about return packet */
-                       result = do_secure_trace3(res, qname, type, clas, key_list);
+                       (void)do_secure_trace(res, qname, type, clas, key_list);
                        break;
                case DRILL_CHASE:
                        qname = ldns_dname_new_frm_str(name);
index e6804ff5029a4ffe6d3cfaa55219965f518850c5..283ed157efdfebf3fa980ef675cc88466f65ae01 100644 (file)
@@ -38,11 +38,7 @@ ldns_pkt     *do_trace(ldns_resolver *res, ldns_rdf *name, ldns_rr_type type,
 ldns_status     do_chase(ldns_resolver *res, ldns_rdf *name, ldns_rr_type type, 
                ldns_rr_class c, ldns_rr_list *trusted_keys, 
                ldns_pkt *pkt_o, uint16_t qflags);
-ldns_status    do_secure_trace(ldns_resolver *res, ldns_rdf *name, ldns_rr_type type, 
-               ldns_rr_class c, ldns_rr_list *trusted_keys);
-ldns_status    do_secure_trace2(ldns_resolver *res, ldns_rdf *name, ldns_rr_type type, 
-               ldns_rr_class c, ldns_rr_list *trusted_keys);
-ldns_status    do_secure_trace3(ldns_resolver *res, ldns_rdf *name, ldns_rr_type type, 
+ldns_pkt        *do_secure_trace(ldns_resolver *res, ldns_rdf *name, ldns_rr_type type, 
                ldns_rr_class c, ldns_rr_list *trusted_keys);
 /* dnssec.c */
 ldns_rr_list   *get_rr(ldns_resolver *res, ldns_rdf *zname, ldns_rr_type t, ldns_rr_class c);
index 7cc43eb02686bd228b35c543d51155d7e19de1b5..7788ca34b3c6c38b48d09a288ee22e58e8e713a5 100644 (file)
@@ -2,7 +2,7 @@
  * securechasetrace.c
  * Where all the hard work concerning secure tracing is done
  *
- * (c) 2005 NLnet Labs
+ * (c) 2005, 2006 NLnet Labs
  *
  * See the file LICENSE for the license
  *
@@ -104,7 +104,7 @@ get_dnssec_rr(ldns_resolver *r, ldns_rdf *name, ldns_rr_type t, ldns_rr_list **s
  * retrieve keys for this zone
  */
 ldns_rr_list *
-get_keys(ldns_resolver *r, ldns_rdf *apexname, ldns_rr_list **opt_sig)
+get_key(ldns_resolver *r, ldns_rdf *apexname, ldns_rr_list **opt_sig)
 {
        return get_dnssec_rr(r, apexname, LDNS_RR_TYPE_DNSKEY, opt_sig);
 }
@@ -118,164 +118,251 @@ get_ds(ldns_resolver *r, ldns_rdf *ownername, ldns_rr_list **opt_sig)
        return get_dnssec_rr(r, ownername, LDNS_RR_TYPE_DS, opt_sig);
 }
 
-
-/* do a secure trace - local_res has been setup, so try to use that */
-ldns_status
-do_secure_trace2(ldns_resolver *res, ldns_rdf *name, ldns_rr_type t,
-                ldns_rr_class c, ldns_rr_list *trusted_keys)
+ldns_pkt *
+do_secure_trace(ldns_resolver *local_res, ldns_rdf *name, ldns_rr_type t,
+               ldns_rr_class c, ldns_rr_list *trusted_keys)
 {
-       /* problem here is that I don't now if *res is a forwarder/cache
-        * or authoritative NS. If we use a cache we should "leave" that
-        * asap and try to find us a real auth. NS ;) 
-        */
-       ldns_rr_list *dnskey_cache = NULL;
-       ldns_rr_list *rrsig_cache = NULL;
-       ldns_rr_list *ds_cache = NULL;
+       ldns_resolver *res;
+       ldns_pkt *p;
+       ldns_rr_list *new_nss_a;
+       ldns_rr_list *new_nss_aaaa;
+       ldns_rr_list *final_answer;
+       ldns_rr_list *new_nss;
+       ldns_rr_list *hostnames;
+       ldns_rr_list *ns_addr;
+       uint16_t loop_count;
+       ldns_rdf *pop; 
+       ldns_rdf *authname;
+       ldns_status status;
+       size_t i;
+       /* dnssec */
+       bool secure;
+       ldns_rr_list *key_list;
+       ldns_rr_list *sig_list;
+       ldns_rr_list *ds_list;
+
+       secure = true;
+       authname = NULL;
+       loop_count = 0;
+       new_nss_a = NULL;
+       new_nss_aaaa = NULL;
+       new_nss = NULL;
+       ns_addr = NULL;
+       final_answer = NULL;
+       p = ldns_pkt_new();
+       res = ldns_resolver_new();
+       sig_list = ldns_rr_list_new();
+
+       if (!p || !res || !sig_list) {
+               error("Memory allocation failed");
+               return NULL;
+       }
+       
+       /* transfer some properties of local_res to res,
+        * because they were given on the commandline */
+       ldns_resolver_set_ip6(res, 
+                       ldns_resolver_ip6(local_res));
+       ldns_resolver_set_port(res, 
+                       ldns_resolver_port(local_res));
+       ldns_resolver_set_debug(res, 
+                       ldns_resolver_debug(local_res));
+       ldns_resolver_set_fail(res, 
+                       ldns_resolver_fail(local_res));
+       ldns_resolver_set_usevc(res, 
+                       ldns_resolver_usevc(local_res));
+       ldns_resolver_set_random(res, 
+                       ldns_resolver_random(local_res));
+       ldns_resolver_set_recursive(res, false);
+       ldns_resolver_set_dnssec(res, true);
 
-       ldns_rdf *chopped_dname[11]; /* alloc 10 subparts for a dname */
-       ldns_rr_list *ds;
-       int8_t i, dname_labels;
-       uint8_t lab_cnt;
-       ldns_rr_list *validated_ds;
+       /* setup the root nameserver in the new resolver */
+       if (ldns_resolver_push_nameserver_rr_list(res, global_dns_root) != LDNS_STATUS_OK) {
+               return NULL;
+       }
 
-       rrsig_cache = ldns_rr_list_new();
-       dnskey_cache = NULL;
+       /* this must be a real query to local_res */
+       status = ldns_resolver_send(&p, local_res, ldns_dname_new_frm_str("."), LDNS_RR_TYPE_NS, c, 0);
+       if (ldns_pkt_empty(p)) {
+               warning("No root server information received\n");
+       } 
+       
+       if (status == LDNS_STATUS_OK) {
+               if (!ldns_pkt_empty(p)) {
+                       drill_pkt_print(stdout, local_res, p);
+               }
+       } else {
+               error("cannot use local resolver\n");
+               return NULL;
+       }
 
-       ldns_resolver_set_dnssec(res, true);
-       ldns_resolver_set_dnssec_cd(res, true);
+       status = ldns_resolver_send(&p, res, name, t, c, 0);
 
-       /* get a list of chopped dnames: www.nlnetlabs.nl, nlnetlabs.nl, nl, . 
-        * This is used to discover what is the zone that is actually hosted
-        * on the resolver we point to in local_res
-        */
-       chopped_dname[0] = name;
-       for(i = 1; i < 10 && chopped_dname[i - 1]; i++) {
-               chopped_dname[i] = ldns_dname_left_chop(chopped_dname[i - 1]);  
-       }
-       chopped_dname[i] = NULL;
-       dname_labels = i - 2; /* set this also before this last NULL */
+       while(status == LDNS_STATUS_OK && 
+             ldns_pkt_reply_type(p) == LDNS_PACKET_REFERRAL) {
 
-       /* Now we will find out what is the first zone that 
-        * actually has some key+sig configured at the nameserver
-        * we're looking at. We start at the right side of our dname
-        */
-       for(i = dname_labels; i != 0; i--) {
-               ldns_rdf_print(stdout, chopped_dname[i]);
+               if (!p) {
+                       /* some error occurred, bail out */
+                       return NULL;
+               }
+
+               new_nss_a = ldns_pkt_rr_list_by_type(p,
+                               LDNS_RR_TYPE_A, LDNS_SECTION_ADDITIONAL);
+               new_nss_aaaa = ldns_pkt_rr_list_by_type(p,
+                               LDNS_RR_TYPE_AAAA, LDNS_SECTION_ADDITIONAL);
+               new_nss = ldns_pkt_rr_list_by_type(p,
+                               LDNS_RR_TYPE_NS, LDNS_SECTION_AUTHORITY);
+
+               if (qdebug != -1) {
+                       ldns_rr_list_print(stdout, new_nss);
+               }
+               /* checks itself for qdebug */
+               drill_pkt_print_footer(stdout, local_res, p);
+               
+               /* remove the old nameserver from the resolver */
+               while((pop = ldns_resolver_pop_nameserver(res))) { /* do it */ }
+
+               if (!new_nss_aaaa && !new_nss_a) {
+                       /* 
+                        * no nameserver found!!! 
+                        * try to resolve the names we do got 
+                        */
+                       for(i = 0; i < ldns_rr_list_rr_count(new_nss); i++) {
+                               /* get the name of the nameserver */
+                               pop = ldns_rr_rdf(ldns_rr_list_rr(new_nss, i), 0);
+                               if (!pop) {
+                                       break;
+                               }
+
+                               ldns_rr_list_print(stdout, new_nss);
+                               ldns_rdf_print(stdout, pop);
+                               /* retrieve it's addresses */
+                               ns_addr = ldns_rr_list_cat_clone(ns_addr,
+                                       ldns_get_rr_list_addr_by_name(local_res, pop, c, 0));
+                       }
+
+                       if (ns_addr) {
+                               if (ldns_resolver_push_nameserver_rr_list(res, ns_addr) != 
+                                               LDNS_STATUS_OK) {
+                                       error("Error adding new nameservers");
+                                       ldns_pkt_free(p); 
+                                       return NULL;
+                               }
+                               ldns_rr_list_free(ns_addr);
+                       } else {
+                               ldns_rr_list_print(stdout, ns_addr);
+                               error("Could not find the nameserver ip addr; abort");
+                               ldns_pkt_free(p);
+                               return NULL;
+                       }
+               }
+
+               /* add the new ones */
+               if (new_nss_aaaa) {
+                       if (ldns_resolver_push_nameserver_rr_list(res, new_nss_aaaa) != 
+                                       LDNS_STATUS_OK) {
+                               error("adding new nameservers");
+                               ldns_pkt_free(p); 
+                               return NULL;
+                       }
+               }
+               if (new_nss_a) {
+                       if (ldns_resolver_push_nameserver_rr_list(res, new_nss_a) != 
+                                       LDNS_STATUS_OK) {
+                               error("adding new nameservers");
+                               ldns_pkt_free(p); 
+                               return NULL;
+                       }
+               }
+               /* DNSSEC */
+               if (new_nss) {
+                       authname = ldns_rr_owner(ldns_rr_list_rr(new_nss, 0));
+               } 
+
+               ldns_rdf_print(stdout,
+                               ldns_resolver_nameservers(res)[0]);
+               printf("Asking for: ");
+               ldns_rdf_print(stdout, name);
+               printf("\nauthname: ");
+               ldns_rdf_print(stdout, authname);
                printf("\n");
-               dnskey_cache =  get_keys(res, chopped_dname[i], &rrsig_cache);
-               if (dnskey_cache) {
-                       /* aahhh, keys... */
-                       break;
+               key_list = get_key(res, authname, &sig_list);
+
+               if (key_list) {
+                       printf("Got KEYS!\n");
+                       ldns_rr_list_print(stdout, sig_list);
+
+               } else {
+                       printf("NO KEYS\n");
                }
-       }
-       lab_cnt = i;
-
-       /* Print whay we have found until now */
-       printf(" ("); 
-               ldns_rdf_print(stdout, chopped_dname[i]);
-       puts(")");
-       resolver_print_nameservers(res);
-       puts("");
-       print_dnskey(dnskey_cache);
-       puts(" |");
-                       
 
-       /* chopped_dname[i] is the zone which is configured at the
-        * nameserver pointed to by res. This is our starting point
-        * for the secure trace. Hopefully the trusted keys we got
-        * match the keys we see here
-        */
+               /* /DNSSEC */
 
-       if (!rrsig_cache) {
-               /* huh!? the sigs must be sent along with the keys... 
-                * probably are using some lame forwarder... exit as
-                * we cannot do anything in that case
-                */
-               error("Are you using an non DNSSEC-aware forwarder?");
-               return LDNS_STATUS_ERR;
-       }
 
-       /* Next try to find out if there is a DS for this name are
-        * a name under that
-        */
-       i = lab_cnt;
-       for(i = lab_cnt; i >= 0; i--) {
-               ds = get_ds(res, chopped_dname[i], NULL);
-               if (ds) {
-                       /* re-query to get the rrsigs */
-                       ds_cache = get_ds(res, chopped_dname[i], &rrsig_cache);
-                       dnskey_cache = get_keys(res, chopped_dname[i], &rrsig_cache);
-                       break;
+
+               if (loop_count++ > 20) {
+                       /* unlikely that we are doing something usefull */
+                       error("Looks like we are looping");
+                       ldns_pkt_free(p); 
+                       return NULL;
                }
+               
+               status = ldns_resolver_send(&p, res, name, t, c, 0);
+               new_nss_aaaa = NULL;
+               new_nss_a = NULL;
+               ns_addr = NULL;
        }
-       printf(" |\n ("); 
-               ldns_rdf_print(stdout, chopped_dname[i]);
-       puts(")");
-       resolver_print_nameservers(res);
-       puts("");
-       print_dnskey(dnskey_cache);
-       puts("");
-       print_ds(ds_cache);
-       puts("");
-
-       validated_ds = check_ds_key_equiv_rr_list(dnskey_cache, ds_cache); 
-       if (validated_ds) {
-               print_ds(validated_ds);
+
+       status = ldns_resolver_send(&p, res, name, t, c, 0);
+
+       /* 
+        * het kan zijn dat we nog labels over hebben, omdat ze
+        * allemaal gehost worden op de zelfde server, zie
+        * ok.ok.ok.test.jelte.nlnetlabs.nl
+        *
+        * die moeten hier nog afgegaan worden om een chain
+        * of trust te kunnen opbouwen
+        */
+
+       if (!p) {
+               return NULL;
        }
 
-       return LDNS_STATUS_OK;
-}
+       hostnames = ldns_get_rr_list_name_by_addr(local_res, 
+                       ldns_pkt_answerfrom(p), 0, 0);
 
+       new_nss = ldns_pkt_authority(p);
+       final_answer = ldns_pkt_answer(p);
+               /* DNSSEC */
+               if (new_nss) {
+                       authname = ldns_rr_owner(ldns_rr_list_rr(new_nss, 0));
+               } 
 
-/* do a secure trace - ripped from drill < 0.9 */
-ldns_status
-do_secure_trace3(ldns_resolver *res, ldns_rdf *name, ldns_rr_type t,
-                               ldns_rr_class c, ldns_rr_list *trusted_keys)
-{
-       ldns_pkt *p1 = NULL;
-       ldns_pkt *p_keys = NULL;
-       ldns_rr_list *key_list = NULL;
-       ldns_rr_list *good_key_list = NULL;
-       ldns_rr_list *sig_list = NULL;
-       unsigned int secure = 1;
-
-       while (ldns_pkt_reply_type(p1 = ldns_resolver_query(res, name, t, c, 0)) == LDNS_PACKET_REFERRAL) {
-               drill_pkt_print(stdout, res, p1);
-
-               if (secure == 1) {
-                       /* Try to get the keys from the current nameserver */
-                       p_keys = ldns_resolver_query(res, name, LDNS_RR_TYPE_DNSKEY, c, 0);
-                       if (p_keys) {
-                               key_list = ldns_pkt_rr_list_by_type(
-                                               p_keys, LDNS_RR_TYPE_DNSKEY, LDNS_SECTION_ANSWER);
-                               if (key_list) {
-
-                                       ldns_rr_list_print(stdout, key_list);
-                                       
-                                       sig_list = ldns_pkt_rr_list_by_name_and_type(
-                                                       p_keys, 
-                                                       ldns_rr_owner(ldns_rr_list_rr(key_list, 0)),
-                                                       LDNS_RR_TYPE_RRSIG,
-                                                       LDNS_SECTION_ANY_NOQUESTION);
-
-                                       if (sig_list) {
-                                               ldns_rr_list_print(stdout, sig_list);
-
-                                               if (ldns_verify(key_list, sig_list, key_list, 
-                                                                       good_key_list)
-                                                               == LDNS_STATUS_OK) {
-                                                       printf("VALIDATED\n");
-                                               }
-                                       }       
-                               }
+               printf("Asking for: ");
+               ldns_rdf_print(stdout, name);
+               printf("\nauthname: ");
+               ldns_rdf_print(stdout, authname);
+               printf("\n");
+               key_list = get_key(res, authname, &sig_list);
+
+               if (key_list) {
+                       printf("Got KEYS!\n");
+                       ldns_rr_list_print(stdout, sig_list);
+                       ds_list = get_ds(res, authname, &sig_list);
+                       if (ds_list) {
+                               ldns_rr_list_print(stdout, ds_list);
                        }
+               } else {
+                       printf("NO KEYS\n");
                }
-       }
 
-       /* we have our final answer */
-       drill_pkt_print(stdout, res, p1);
+               /* /DNSSEC */
 
-       
-       
-       return LDNS_STATUS_OK;
+       if (qdebug != -1) {
+               ldns_rr_list_print(stdout, final_answer);
+               ldns_rr_list_print(stdout, new_nss);
+
+       }
+       drill_pkt_print_footer(stdout, local_res, p);
+       ldns_pkt_free(p); 
+       return NULL;
 }
diff --git a/drill/tracelogic-olddrill.c b/drill/tracelogic-olddrill.c
deleted file mode 100644 (file)
index a472e43..0000000
+++ /dev/null
@@ -1,211 +0,0 @@
-/* tracelogic.c
- */
-/**
- * Performs a secure lookup - this should be folded into the above one
- */
-ldns_rr *
-do_trace_secure(ldns_rr *q, int protocol, int print)
-{
-       struct t_dpacket *p = NULL;
-       struct t_dpacket *a = NULL;
-       struct t_dpacket *ds = NULL;
-       struct t_dpacket *ds_recv = NULL;
-       struct t_dpacket *pkeys = NULL;
-       struct t_rr *nsrr = NULL;
-       struct t_rr *authsec = NULL;
-       struct t_rr *dsrr = NULL;
-       struct t_rr *keys = NULL;
-       struct t_rr *dss = NULL;
-       struct t_rr *rrsig = NULL;
-       struct t_rr *answer = NULL;
-       struct t_rdata *current_zone;
-       unsigned int secure = 1;
-       uint8_t label_count;
-       
-       /* prepare the query packet */
-       p = dpacket_create();
-       dpacket_add_rr(q, SEC_QUESTION, p);
-       SET_DNSSEC(p);
-       if (protocol == PROTO_UDP)
-               SET_UDPSIZE(p, drill_opt->bufsize);
-
-       if (print) print_packet_dense(p);
-
-       nsrr    = root_servers;
-       current_zone = rdata_create((uint8_t *) "",0);
-
-       while (dpacket_type((a = send_packet(p, nsrr, protocol, NULL))) == PKT_REFERRAL) {
-
-               if (print) { 
-                       print_packet_dense(a);
-                       printf("\n");
-               }
-
-               if (secure == 1) {
-                       /* Try the get a set of keys from the
-                        * current nameserver */
-                       mesg("%s %s", "Asking DNSKEY for", rdata2str(current_zone));
-                       pkeys = do_query(current_zone ,TYPE_DNSKEY, nsrr, protocol);
-                       if (pkeys) {
-                               keys = dpacket_get_rrset(current_zone, TYPE_DNSKEY, pkeys, SEC_ANSWER);
-                               if (keys) {
-                                       prettyprint_rr(keys, FOLLOW, NO_COMMENT, NO_LONG);
-
-                                       rrsig = dpacket_get_rrsig(keys, pkeys);                 
-                                       if (rrsig) {
-                                               prettyprint_rr(rrsig, FOLLOW, NO_COMMENT, NO_LONG);
-                                               /* try to validate */
-                                               if (verify_rrsig(keys, rrsig, keys) == RET_SUC)
-                                                       mesg("The signature of the key validated");
-                                       }
-                                       
-                                       xfree(keys); keys = NULL;
-                               }
-                               xfree(pkeys); pkeys = NULL;
-                       }
-               }
-
-               /* get the a records of the ns in the packet */
-               nsrr = dpacket_get_rrset(NULL, TYPE_A, a, SEC_ADD);
-               
-               /* get the auth servers here - for the referral name
-                * -> to get the DS */
-               /* The can also live the in SEC_ANSWER...... */
-               authsec = dpacket_get_rrset(NULL, TYPE_NS, a, SEC_AUTH);
-
-               /* out of baliwick servers don't need glue 
-                * if there is no glue - we need to fetch the addresses
-                * of the nameserver ourselves */
-               if (!nsrr) {
-                       mesg("%s", "fetching glue!");
-                       nsrr = get_ns_addresses(a, protocol, SEC_AUTH);
-               }
-
-               /* still nothing */
-               if (!nsrr) 
-                       error("%s", "No glue found - giving up");
-               
-               if (secure == 1) {
-                       /* we're are secure, try to lookup DS records */
-                       /* a = received, is delegation, show name */
-                       /* does this delegation have a DS?? */
-                       if (!authsec) {
-                               warning("%s", ";; No auth section found - not doing DNSSEC!");
-                       } else {
-                               /* Try the get the parental DS for the
-                                * child zone */
-                               ds = dpacket_create();
-                               dpacket_add_rr(rr_create(authsec->name, TYPE_DS, DEF_TTL, SEC_QUESTION),
-                                               SEC_QUESTION, ds);
-                               /* ASK the DS to the current nameservers */     
-                               ds_recv = send_packet(ds, nsrr, protocol, NULL);
-
-                               mesg("%s %s\n", "Asking DS for", rdata2str(authsec->name));
-
-                               print_packet_dense(ds_recv);
-                               dsrr = dpacket_get_rrset(authsec->name, TYPE_DS, ds_recv, SEC_ANSWER);
-                               
-                               if (!dsrr) {
-                                       mesg("%s", "No DS found...");
-                               } else {
-                                       mesg("%s", "Yes a DS found...");
-                                       rrsig = dpacket_get_rrsig(dsrr, ds_recv);                       
-                                       print_rr(dsrr, FOLLOW);
-                                       if (rrsig)
-                                               print_rr(rrsig, FOLLOW);
-
-                               }
-                       xfree(dsrr); dsrr = NULL;
-                       }
-               }
-               if (print) printf("\n");
-               xfree(a); a = NULL;
-               xfree(current_zone);
-               current_zone = authsec->name;
-       }
-
-       a = send_packet(p, nsrr, protocol, NULL); /* last step */
-       rrsig = NULL;
-       /* we should now have our answer - could be NXDOMAIN - 
-        * no find the right DS's - we do this by label chopping:
-        * DS sub.sub.nl ; DS sub.nl; DS nl; DS .
-        */
-       dss = rr_create(q->name, TYPE_DS, DEF_TTL, SEC_QUESTION);
-       
-       /* Also ask for DNSKEYs, this is needed if all these zones
-        * are served from 1 server - if so we won't reach this state via
-        * the referrals, but we just "get here"
-        */
-       for (label_count = 0; label_count < label_cnt(q); ++label_count) {
-               
-               mesg("%s %s", "After querying for DS for", 
-                               rdata2str(chop_labels_left(dss, label_count)->name));
-
-               mesg("%s %s", "After querying for DNSKEY for", 
-                               rdata2str(chop_labels_left(dss, label_count)->name));
-
-               ds_recv = do_query_rr(chop_labels_left(dss, label_count),
-                               nsrr, protocol);
-               
-               pkeys   = do_query(chop_labels_left(dss, label_count)->name, TYPE_DNSKEY,
-                               nsrr, protocol);
-
-               if (ds_recv)
-                       dsrr = dpacket_get_rrset((chop_labels_left(dss, label_count)->name), 
-                                       TYPE_DS, ds_recv, SEC_ANSWER);
-               
-               if (pkeys)
-                       keys = dpacket_get_rrset((chop_labels_left(dss, label_count)->name),
-                                       TYPE_DNSKEY, pkeys, SEC_ANSWER);
-               if (keys) {
-                       prettyprint_rr(keys, FOLLOW, NO_COMMENT, NO_LONG);
-                       rrsig = dpacket_get_rrsig(keys, pkeys);
-                       if (rrsig)  {
-                               prettyprint_rr(rrsig, FOLLOW, NO_COMMENT, NO_LONG);
-                               if (verify_rrsig(keys, rrsig, keys) == RET_SUC) 
-                                       mesg("The signature of the key validated");
-                               xfree(rrsig); rrsig = NULL;
-                       }
-                       xfree(keys); keys = NULL;
-               }
-
-               if (dsrr)  {
-                       rrsig = dpacket_get_rrsig(dsrr, ds_recv);                       
-                       prettyprint_rr(dsrr, FOLLOW, NO_COMMENT, NO_LONG);
-                       if (rrsig)  {
-                               prettyprint_rr(rrsig, FOLLOW, NO_COMMENT, NO_LONG);
-                               xfree(rrsig); rrsig = NULL;
-                       }
-                       xfree(dsrr); dsrr = NULL;
-                       printf("\n");
-               }
-               xfree(pkeys); pkeys = NULL;
-               xfree(ds_recv); ds_recv = NULL;
-                       
-       }
-
-       if (a) {
-               if (print) {
-                       print_packet_dense(a);
-                       printf("\n");
-               }
-               /* look in the answer section?? */
-               /* this is dangerous 'cause I don't know what I'm looking
-                * for. Think cname etc.
-                */
-               answer = dpacket_get_rrset(q->name, q->type, a, SEC_ANSWER);
-               if (answer) {
-                       prettyprint_rr(answer, FOLLOW, NO_COMMENT, NO_LONG);
-                       rrsig = dpacket_get_rrsig(answer, a);
-               }
-               if (rrsig) 
-                       prettyprint_rr(rrsig, FOLLOW, NO_COMMENT, NO_LONG);
-               else 
-                       verbose("No signature found");
-               return(answer);
-               /* get the SIG */
-       } else {
-               warning("%s", "Empty response\n");
-               return NULL;
-       }
-}