mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 18:28:25 +00:00
Fix caching of dangling CNAMEs.
This commit is contained in:
@@ -149,6 +149,9 @@ version 2.67
|
|||||||
no address, and vice-versa. Thanks to Yury Konovalov for
|
no address, and vice-versa. Thanks to Yury Konovalov for
|
||||||
spotting the problem.
|
spotting the problem.
|
||||||
|
|
||||||
|
Do a better job caching dangling CNAMEs. Thanks to Yves
|
||||||
|
Dorfsman for spotting the problem.
|
||||||
|
|
||||||
|
|
||||||
version 2.66
|
version 2.66
|
||||||
Add the ability to act as an authoritative DNS
|
Add the ability to act as an authoritative DNS
|
||||||
|
|||||||
143
src/rfc1035.c
143
src/rfc1035.c
@@ -1011,91 +1011,88 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
|
|||||||
else
|
else
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!(flags & F_NXDOMAIN))
|
cname_loop1:
|
||||||
|
if (!(p1 = skip_questions(header, qlen)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (j = ntohs(header->ancount); j != 0; j--)
|
||||||
{
|
{
|
||||||
cname_loop1:
|
if (!(res = extract_name(header, qlen, &p1, name, 0, 10)))
|
||||||
if (!(p1 = skip_questions(header, qlen)))
|
return 0; /* bad packet */
|
||||||
return 0;
|
|
||||||
|
|
||||||
for (j = ntohs(header->ancount); j != 0; j--)
|
GETSHORT(aqtype, p1);
|
||||||
|
GETSHORT(aqclass, p1);
|
||||||
|
GETLONG(attl, p1);
|
||||||
|
if ((daemon->max_ttl != 0) && (attl > daemon->max_ttl) && !is_sign)
|
||||||
{
|
{
|
||||||
if (!(res = extract_name(header, qlen, &p1, name, 0, 10)))
|
(p1) -= 4;
|
||||||
return 0; /* bad packet */
|
PUTLONG(daemon->max_ttl, p1);
|
||||||
|
}
|
||||||
|
GETSHORT(ardlen, p1);
|
||||||
|
endrr = p1+ardlen;
|
||||||
|
|
||||||
GETSHORT(aqtype, p1);
|
if (aqclass == C_IN && res != 2 && (aqtype == T_CNAME || aqtype == qtype))
|
||||||
GETSHORT(aqclass, p1);
|
{
|
||||||
GETLONG(attl, p1);
|
if (aqtype == T_CNAME)
|
||||||
if ((daemon->max_ttl != 0) && (attl > daemon->max_ttl) && !is_sign)
|
|
||||||
{
|
{
|
||||||
(p1) -= 4;
|
if (!cname_count--)
|
||||||
PUTLONG(daemon->max_ttl, p1);
|
return 0; /* looped CNAMES */
|
||||||
}
|
newc = cache_insert(name, NULL, now, attl, F_CNAME | F_FORWARD);
|
||||||
GETSHORT(ardlen, p1);
|
if (newc)
|
||||||
endrr = p1+ardlen;
|
|
||||||
|
|
||||||
if (aqclass == C_IN && res != 2 && (aqtype == T_CNAME || aqtype == qtype))
|
|
||||||
{
|
|
||||||
if (aqtype == T_CNAME)
|
|
||||||
{
|
{
|
||||||
if (!cname_count--)
|
newc->addr.cname.target.cache = NULL;
|
||||||
return 0; /* looped CNAMES */
|
if (cpp)
|
||||||
newc = cache_insert(name, NULL, now, attl, F_CNAME | F_FORWARD);
|
|
||||||
if (newc)
|
|
||||||
{
|
|
||||||
newc->addr.cname.target.cache = NULL;
|
|
||||||
if (cpp)
|
|
||||||
{
|
|
||||||
cpp->addr.cname.target.cache = newc;
|
|
||||||
cpp->addr.cname.uid = newc->uid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cpp = newc;
|
|
||||||
if (attl < cttl)
|
|
||||||
cttl = attl;
|
|
||||||
|
|
||||||
if (!extract_name(header, qlen, &p1, name, 1, 0))
|
|
||||||
return 0;
|
|
||||||
goto cname_loop1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
found = 1;
|
|
||||||
|
|
||||||
/* copy address into aligned storage */
|
|
||||||
if (!CHECK_LEN(header, p1, qlen, addrlen))
|
|
||||||
return 0; /* bad packet */
|
|
||||||
memcpy(&addr, p1, addrlen);
|
|
||||||
|
|
||||||
/* check for returned address in private space */
|
|
||||||
if (check_rebind &&
|
|
||||||
(flags & F_IPV4) &&
|
|
||||||
private_net(addr.addr.addr4, !option_bool(OPT_LOCAL_REBIND)))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
#ifdef HAVE_IPSET
|
|
||||||
if (ipsets && (flags & (F_IPV4 | F_IPV6)))
|
|
||||||
{
|
|
||||||
ipsets_cur = ipsets;
|
|
||||||
while (*ipsets_cur)
|
|
||||||
add_to_ipset(*ipsets_cur++, &addr, flags, 0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
newc = cache_insert(name, &addr, now, attl, flags | F_FORWARD);
|
|
||||||
if (newc && cpp)
|
|
||||||
{
|
{
|
||||||
cpp->addr.cname.target.cache = newc;
|
cpp->addr.cname.target.cache = newc;
|
||||||
cpp->addr.cname.uid = newc->uid;
|
cpp->addr.cname.uid = newc->uid;
|
||||||
}
|
}
|
||||||
cpp = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
p1 = endrr;
|
cpp = newc;
|
||||||
if (!CHECK_LEN(header, p1, qlen, 0))
|
if (attl < cttl)
|
||||||
return 0; /* bad packet */
|
cttl = attl;
|
||||||
|
|
||||||
|
if (!extract_name(header, qlen, &p1, name, 1, 0))
|
||||||
|
return 0;
|
||||||
|
goto cname_loop1;
|
||||||
|
}
|
||||||
|
else if (!(flags & F_NXDOMAIN))
|
||||||
|
{
|
||||||
|
found = 1;
|
||||||
|
|
||||||
|
/* copy address into aligned storage */
|
||||||
|
if (!CHECK_LEN(header, p1, qlen, addrlen))
|
||||||
|
return 0; /* bad packet */
|
||||||
|
memcpy(&addr, p1, addrlen);
|
||||||
|
|
||||||
|
/* check for returned address in private space */
|
||||||
|
if (check_rebind &&
|
||||||
|
(flags & F_IPV4) &&
|
||||||
|
private_net(addr.addr.addr4, !option_bool(OPT_LOCAL_REBIND)))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
#ifdef HAVE_IPSET
|
||||||
|
if (ipsets && (flags & (F_IPV4 | F_IPV6)))
|
||||||
|
{
|
||||||
|
ipsets_cur = ipsets;
|
||||||
|
while (*ipsets_cur)
|
||||||
|
add_to_ipset(*ipsets_cur++, &addr, flags, 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
newc = cache_insert(name, &addr, now, attl, flags | F_FORWARD);
|
||||||
|
if (newc && cpp)
|
||||||
|
{
|
||||||
|
cpp->addr.cname.target.cache = newc;
|
||||||
|
cpp->addr.cname.uid = newc->uid;
|
||||||
|
}
|
||||||
|
cpp = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p1 = endrr;
|
||||||
|
if (!CHECK_LEN(header, p1, qlen, 0))
|
||||||
|
return 0; /* bad packet */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!found && !option_bool(OPT_NO_NEG))
|
if (!found && !option_bool(OPT_NO_NEG))
|
||||||
@@ -2035,7 +2032,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
|||||||
if (trunc)
|
if (trunc)
|
||||||
header->hb3 |= HB3_TC;
|
header->hb3 |= HB3_TC;
|
||||||
|
|
||||||
if (anscount == 0 && nxdomain)
|
if (nxdomain)
|
||||||
SET_RCODE(header, NXDOMAIN);
|
SET_RCODE(header, NXDOMAIN);
|
||||||
else
|
else
|
||||||
SET_RCODE(header, NOERROR); /* no error */
|
SET_RCODE(header, NOERROR); /* no error */
|
||||||
|
|||||||
Reference in New Issue
Block a user