djbdns/330-fix-dnscache-cname-handling.patch

60 lines
1.9 KiB
Diff

--- djbdns-1.05/query.c 2012-08-30 22:14:28.885825918 +0800
+++ djbdns-1.05-new/query.c 2012-08-30 22:22:23.887727783 +0800
@@ -220,7 +217,7 @@
NEWNAME:
- if (++z->loop == 100) goto DIE;
+ if (++z->loop == 150) goto DIE;
d = z->name[z->level];
dtype = z->level ? DNS_T_A : z->type;
dlen = dns_domain_length(d);
@@ -489,7 +486,7 @@
HAVEPACKET:
- if (++z->loop == 100) goto DIE;
+ if (++z->loop == 150) goto DIE;
buf = z->qm->dt.packet;
len = z->qm->dt.packetlen;
@@ -722,6 +716,7 @@
alloc_free(records); records = 0;
if (byte_diff(DNS_T_CNAME,2,dtype)) {
+ int flagcname = 0;
/* This code assumes that the CNAME chain is presented in the correct
** order. The example algorithm in RFC 1034 will actually result in this
** being the case, but the words do not require it to be so.
@@ -734,20 +729,29 @@
if (dns_domain_equal(t1,d))
if (byte_equal(header + 2,2,DNS_C_IN)) { /* should always be true */
if (typematch(header,DNS_T_CNAME)) {
+ flagcname = 1;
ttl = ttlget(header + 4);
if (z->level == 0) {
if (!move_name_to_alias(z,ttl)) goto DIE ;
}
+ if (!dns_domain_copy(&owner_name, control)) goto DIE ;
if (!dns_packet_getname(buf,len,pos,&z->name[z->level])) goto DIE;
d = z->name[z->level];
- if (!dns_domain_suffix(d,control) || !roots_same(d,control))
+ if (!dns_domain_suffix(d,owner_name) || !roots_same(d,owner_name)) {
+ dns_domain_free(&owner_name);
goto NEWNAME ; /* Cannot trust the chain further - restart using current name */
}
+ control = d + dns_domain_suffixpos(d,owner_name);
+ z->control[z->level] = control;
+ dns_domain_free(&owner_name);
+ }
}
uint16_unpack_big(header + 8,&datalen);
pos += datalen;
}
+ if (flagcname != 0)
+ goto HAVENS;
}
/* A "no such name" error applies to the end of any CNAME chain, not to the start. */