mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-01-28 01:19:19 -05:00
cname handling improved.
git-svn-id: file:///svn/unbound/trunk@815 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
ab4b9aa250
commit
abf85e9270
5 changed files with 57 additions and 10 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Reference in a new issue