mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 10:18:25 +00:00
Add --use-stale-cache option.
This commit is contained in:
@@ -1360,8 +1360,15 @@ int add_resource_record(struct dns_header *header, char *limit, int *truncp, int
|
||||
#undef CHECK_LIMIT
|
||||
}
|
||||
|
||||
static int crec_isstale(struct crec *crecp, time_t now)
|
||||
{
|
||||
return (!(crecp->flags & F_IMMORTAL)) && difftime(crecp->ttd, now) < 0;
|
||||
}
|
||||
|
||||
static unsigned long crec_ttl(struct crec *crecp, time_t now)
|
||||
{
|
||||
signed long ttl = difftime(crecp->ttd, now);
|
||||
|
||||
/* Return 0 ttl for DHCP entries, which might change
|
||||
before the lease expires, unless configured otherwise. */
|
||||
|
||||
@@ -1370,8 +1377,8 @@ static unsigned long crec_ttl(struct crec *crecp, time_t now)
|
||||
int conf_ttl = daemon->use_dhcp_ttl ? daemon->dhcp_ttl : daemon->local_ttl;
|
||||
|
||||
/* Apply ceiling of actual lease length to configured TTL. */
|
||||
if (!(crecp->flags & F_IMMORTAL) && (crecp->ttd - now) < conf_ttl)
|
||||
return crecp->ttd - now;
|
||||
if (!(crecp->flags & F_IMMORTAL) && ttl < conf_ttl)
|
||||
return ttl;
|
||||
|
||||
return conf_ttl;
|
||||
}
|
||||
@@ -1380,9 +1387,13 @@ static unsigned long crec_ttl(struct crec *crecp, time_t now)
|
||||
if (crecp->flags & F_IMMORTAL)
|
||||
return crecp->ttd;
|
||||
|
||||
/* Stale cache entries. */
|
||||
if (ttl < 0)
|
||||
return 0;
|
||||
|
||||
/* Return the Max TTL value if it is lower than the actual TTL */
|
||||
if (daemon->max_ttl == 0 || ((unsigned)(crecp->ttd - now) < daemon->max_ttl))
|
||||
return crecp->ttd - now;
|
||||
if (daemon->max_ttl == 0 || ((unsigned)ttl < daemon->max_ttl))
|
||||
return ttl;
|
||||
else
|
||||
return daemon->max_ttl;
|
||||
}
|
||||
@@ -1395,7 +1406,8 @@ static int cache_validated(const struct crec *crecp)
|
||||
/* return zero if we can't answer from cache, or packet size if we can */
|
||||
size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
||||
struct in_addr local_addr, struct in_addr local_netmask,
|
||||
time_t now, int ad_reqd, int do_bit, int have_pseudoheader)
|
||||
time_t now, int ad_reqd, int do_bit, int have_pseudoheader,
|
||||
int *stale)
|
||||
{
|
||||
char *name = daemon->namebuff;
|
||||
unsigned char *p, *ansp;
|
||||
@@ -1411,6 +1423,9 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
||||
size_t len;
|
||||
int rd_bit = (header->hb3 & HB3_RD);
|
||||
|
||||
if (stale)
|
||||
*stale = 0;
|
||||
|
||||
/* never answer queries with RD unset, to avoid cache snooping. */
|
||||
if (ntohs(header->ancount) != 0 ||
|
||||
ntohs(header->nscount) != 0 ||
|
||||
@@ -1459,13 +1474,22 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
||||
while (--count != 0 && (crecp = cache_find_by_name(NULL, name, now, F_CNAME | F_NXDOMAIN)))
|
||||
{
|
||||
char *cname_target;
|
||||
|
||||
int stale_flag = 0;
|
||||
|
||||
if (crec_isstale(crecp, now))
|
||||
{
|
||||
if (stale)
|
||||
*stale = 1;
|
||||
|
||||
stale_flag = F_STALE;
|
||||
}
|
||||
|
||||
if (crecp->flags & F_NXDOMAIN)
|
||||
{
|
||||
if (qtype == T_CNAME)
|
||||
{
|
||||
if (!dryrun)
|
||||
log_query(crecp->flags, name, NULL, record_source(crecp->uid), 0);
|
||||
log_query(stale_flag | crecp->flags, name, NULL, record_source(crecp->uid), 0);
|
||||
auth = 0;
|
||||
nxdomain = 1;
|
||||
ans = 1;
|
||||
@@ -1487,7 +1511,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
||||
|
||||
if (!dryrun)
|
||||
{
|
||||
log_query(crecp->flags, name, NULL, record_source(crecp->uid), 0);
|
||||
log_query(stale_flag | crecp->flags, name, NULL, record_source(crecp->uid), 0);
|
||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
||||
crec_ttl(crecp, now), &nameoffset,
|
||||
T_CNAME, C_IN, "d", cname_target))
|
||||
@@ -1656,22 +1680,33 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
||||
{
|
||||
do
|
||||
{
|
||||
int stale_flag = 0;
|
||||
|
||||
if (crec_isstale(crecp, now))
|
||||
{
|
||||
if (stale)
|
||||
*stale = 1;
|
||||
|
||||
stale_flag = F_STALE;
|
||||
}
|
||||
|
||||
/* don't answer wildcard queries with data not from /etc/hosts or dhcp leases */
|
||||
if (qtype == T_ANY && !(crecp->flags & (F_HOSTS | F_DHCP)))
|
||||
continue;
|
||||
|
||||
|
||||
if (!(crecp->flags & F_DNSSECOK))
|
||||
sec_data = 0;
|
||||
|
||||
|
||||
ans = 1;
|
||||
|
||||
|
||||
if (crecp->flags & F_NEG)
|
||||
{
|
||||
auth = 0;
|
||||
if (crecp->flags & F_NXDOMAIN)
|
||||
nxdomain = 1;
|
||||
if (!dryrun)
|
||||
log_query(crecp->flags & ~F_FORWARD, name, &addr, NULL, 0);
|
||||
log_query(stale_flag | (crecp->flags & ~F_FORWARD), name, &addr, NULL, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1679,7 +1714,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
||||
auth = 0;
|
||||
if (!dryrun)
|
||||
{
|
||||
log_query(crecp->flags & ~F_FORWARD, cache_get_name(crecp), &addr,
|
||||
log_query(stale_flag | (crecp->flags & ~F_FORWARD), cache_get_name(crecp), &addr,
|
||||
record_source(crecp->uid), 0);
|
||||
|
||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
||||
@@ -1788,7 +1823,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
||||
if ((crecp = cache_find_by_name(NULL, name, now, flag | F_NXDOMAIN | (dryrun ? F_NO_RR : 0))))
|
||||
{
|
||||
int localise = 0;
|
||||
|
||||
|
||||
/* See if a putative address is on the network from which we received
|
||||
the query, is so we'll filter other answers. */
|
||||
if (local_addr.s_addr != 0 && option_bool(OPT_LOCALISE) && flag == F_IPV4)
|
||||
@@ -1810,6 +1845,16 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
||||
(rd_bit && (!do_bit || cache_validated(crecp)) ))
|
||||
do
|
||||
{
|
||||
int stale_flag = 0;
|
||||
|
||||
if (crec_isstale(crecp, now))
|
||||
{
|
||||
if (stale)
|
||||
*stale = 1;
|
||||
|
||||
stale_flag = F_STALE;
|
||||
}
|
||||
|
||||
/* don't answer wildcard queries with data not from /etc/hosts
|
||||
or DHCP leases */
|
||||
if (qtype == T_ANY && !(crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)))
|
||||
@@ -1825,7 +1870,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
||||
if (crecp->flags & F_NXDOMAIN)
|
||||
nxdomain = 1;
|
||||
if (!dryrun)
|
||||
log_query(crecp->flags, name, NULL, NULL, 0);
|
||||
log_query(stale_flag | crecp->flags, name, NULL, NULL, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1842,7 +1887,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
||||
ans = 1;
|
||||
if (!dryrun)
|
||||
{
|
||||
log_query(crecp->flags & ~F_REVERSE, name, &crecp->addr,
|
||||
log_query(stale_flag | (crecp->flags & ~F_REVERSE), name, &crecp->addr,
|
||||
record_source(crecp->uid), 0);
|
||||
|
||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
||||
@@ -1953,6 +1998,15 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
||||
rd_bit && (!do_bit || (option_bool(OPT_DNSSEC_VALID) && !(crecp->flags & F_DNSSECOK))))
|
||||
do
|
||||
{
|
||||
int stale_flag = 0;
|
||||
|
||||
if (crec_isstale(crecp, now))
|
||||
{
|
||||
if (stale)
|
||||
*stale = 1;
|
||||
|
||||
stale_flag = F_STALE;
|
||||
}
|
||||
/* don't answer wildcard queries with data not from /etc/hosts or dhcp leases, except for NXDOMAIN */
|
||||
if (qtype == T_ANY && !(crecp->flags & (F_NXDOMAIN)))
|
||||
break;
|
||||
@@ -1968,12 +2022,12 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
||||
if (crecp->flags & F_NXDOMAIN)
|
||||
nxdomain = 1;
|
||||
if (!dryrun)
|
||||
log_query(crecp->flags, name, NULL, NULL, 0);
|
||||
log_query(stale_flag | crecp->flags, name, NULL, NULL, 0);
|
||||
}
|
||||
else if (!dryrun)
|
||||
{
|
||||
char *target = blockdata_retrieve(crecp->addr.srv.target, crecp->addr.srv.targetlen, NULL);
|
||||
log_query(crecp->flags, name, NULL, NULL, 0);
|
||||
log_query(stale_flag | crecp->flags, name, NULL, NULL, 0);
|
||||
|
||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
||||
crec_ttl(crecp, now), NULL, T_SRV, C_IN, "sssd",
|
||||
|
||||
Reference in New Issue
Block a user