cname handling improved.

git-svn-id: file:///svn/unbound/trunk@815 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2007-12-07 10:43:10 +00:00
parent ab4b9aa250
commit abf85e9270
5 changed files with 57 additions and 10 deletions

View 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

View 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);

View 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)

View 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)
{

View 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.