]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
cname handling improved.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Fri, 7 Dec 2007 10:43:10 +0000 (10:43 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Fri, 7 Dec 2007 10:43:10 +0000 (10:43 +0000)
git-svn-id: file:///svn/unbound/trunk@815 be551aaa-1e26-0410-a405-d3ace91eadb9

doc/Changelog
libunbound/worker.c
smallapp/unbound-host.c
util/data/msgreply.c
util/data/msgreply.h

index 63e7a97120a7135e678a8045b7c75c8243bb5b07..8ade6427a1ea90b9b52eaabd021099ef34240b5d 100644 (file)
@@ -1,6 +1,7 @@
 7 December 2007: Wouter
        - unbound-host has a -d option to show what happens. This can help
          with debugging (why do I get this answer).
+       - fixup CNAME handling, on nodata, sets and display canonname.
 
 6 December 2007: Wouter
        - library resolution works in foreground mode, unbound-host app
index c0294aafda52b0e57728e4bdfd94a8760ac4e520..7be64dd6ad6e1124ea1c95021611cece8ff6a4e9 100644 (file)
@@ -58,6 +58,7 @@
 #include "util/storage/slabhash.h"
 #include "util/net_help.h"
 #include "util/data/dname.h"
+#include "util/data/msgreply.h"
 
 /** size of table used for random numbers. large to be more secure. */
 #define RND_STATE_SIZE 256
@@ -206,24 +207,35 @@ parse_reply(ldns_buffer* pkt, struct regional* region, struct query_info* qi)
        return rep;
 }
 
+/** insert canonname */
+static int
+fill_canon(struct ub_val_result* res, uint8_t* s)
+{
+       char buf[255+2];
+       dname_str(s, buf);
+       res->canonname = strdup(buf);
+       return res->canonname != 0;
+}
+
 /** fill data into result */
 static int
 fill_res(struct ub_val_result* res, struct ub_packed_rrset_key* answer,
-       struct query_info* rq)
+       uint8_t* finalcname, struct query_info* rq)
 {
        size_t i;
        struct packed_rrset_data* data;
        if(!answer) {
+               if(finalcname) {
+                       if(!fill_canon(res, finalcname))
+                               return 0; /* out of memory */
+               }
                res->data = calloc(1, sizeof(char*));
                res->len = calloc(1, sizeof(size_t));
                return (res->data && res->len);
        }
        data = (struct packed_rrset_data*)answer->entry.data;
        if(query_dname_compare(rq->qname, answer->rk.dname) != 0) {
-               char buf[255+2];
-               dname_str(answer->rk.dname, buf);
-               res->canonname = strdup(buf);
-               if(!res->canonname)
+               if(!fill_canon(res, answer->rk.dname))
                        return 0; /* out of memory */
        } else
                res->canonname = res->qname;
@@ -272,8 +284,8 @@ libworker_fg_done_cb(void* arg, int rcode, ldns_buffer* buf, enum sec_status s)
        if(!rep) {
                return; /* error parsing buf, or out of memory */
        }
-       /* log_dns_msg("fg reply", &rq, rep); @@@ DEBUG */
-       if(!fill_res(d->q->res, reply_find_answer_rrset(&rq, rep), &rq))
+       if(!fill_res(d->q->res, reply_find_answer_rrset(&rq, rep), 
+               reply_find_final_cname_target(&rq, rep), &rq))
                return; /* out of memory */
        /* rcode, nxdomain, bogus */
        d->q->res->rcode = (int)LDNS_RCODE_WIRE(d->q->msg);
index fdd16cc4df140378305809687d2b5d8668c16b09..7326c7d678b18358416dced8cff8fbea24c61307 100644 (file)
@@ -288,12 +288,16 @@ pretty_output(char* q, int t, int c, int sec, int haved,
                return;
        }
        if(docname && result->canonname &&
-               result->canonname != result->qname)
-               printf("%s is an alias for %s\n", result->qname, 
+               result->canonname != result->qname) {
+               printf("%s is an alias for %s", result->qname, 
                        result->canonname);
+               if(verb > 0)
+                       printf(" %s", secstatus);
+               printf("\n");
+       }
        if(!haved) {
                if(verb > 0) {
-                       printf("%s", q);
+                       printf("%s", result->canonname?result->canonname:q);
                        if(strcmp(cstr, "IN") != 0)
                                printf(" in class %s", cstr);
                        if(t == LDNS_RR_TYPE_A)
index 7c4dab0608bf0cb93c7a262925acd08dbc3020e2..924ba64e3c04147258efbb616e41006974fc43a1 100644 (file)
@@ -648,6 +648,27 @@ reply_info_copy(struct reply_info* rep, struct alloc_cache* alloc,
        return cp;
 }
 
+uint8_t* 
+reply_find_final_cname_target(struct query_info* qinfo, struct reply_info* rep)
+{
+       uint8_t* sname = qinfo->qname;
+       size_t snamelen = qinfo->qname_len;
+       size_t i;
+       for(i=0; i<rep->an_numrrsets; i++) {
+               struct ub_packed_rrset_key* s = rep->rrsets[i];
+               /* follow CNAME chain (if any) */
+               if(ntohs(s->rk.type) == LDNS_RR_TYPE_CNAME && 
+                       ntohs(s->rk.rrset_class) == qinfo->qclass && 
+                       snamelen == s->rk.dname_len &&
+                       query_dname_compare(sname, s->rk.dname) == 0) {
+                       get_cname_target(s, &sname, &snamelen);
+               }
+       }
+       if(sname != qinfo->qname)
+               return sname;
+       return NULL;
+}
+
 struct ub_packed_rrset_key* 
 reply_find_answer_rrset(struct query_info* qinfo, struct reply_info* rep)
 {
index 23e35e131b33928ef2f2d45b11a358f4eb564ced..3d17cbe4088e4c8904379f4b26830bafefc61796 100644 (file)
@@ -315,6 +315,15 @@ int parse_copy_decompress_rrset(ldns_buffer* pkt, struct msg_parse* msg,
        struct rrset_parse *pset, struct regional* region, 
        struct ub_packed_rrset_key* pk);
 
+/**
+ * Find final cname target in reply, the one matching qinfo. Follows CNAMEs.
+ * @param qinfo: what to start with.
+ * @param rep: looks in answer section of this message.
+ * @return: pointer dname, or NULL if not found.
+ */
+uint8_t* reply_find_final_cname_target(struct query_info* qinfo,
+       struct reply_info* rep);
+
 /**
  * Find answer rrset in reply, the one matching qinfo. Follows CNAMEs, so the
  * result may have a different owner name.