mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 10:18:25 +00:00
Cache SOAs and return them with cached NXDOMAIN/NODATA replies.
Now we can cache arbirary RRs, give more correct answers when replying negative answers from cache. To implement this needed the DNS-doctor code to be untangled from find_soa(), so it should be under suspicion for any regresssions in that department.
This commit is contained in:
@@ -131,19 +131,11 @@ int main (int argc, char **argv)
|
||||
'.' or NAME_ESCAPE then all would have to be escaped, so the
|
||||
presentation format would be twice as long as the spec. */
|
||||
daemon->keyname = safe_malloc((MAXDNAME * 2) + 1);
|
||||
daemon->workspacename = safe_malloc((MAXDNAME * 2) + 1);
|
||||
/* one char flag per possible RR in answer section (may get extended). */
|
||||
daemon->rr_status_sz = 64;
|
||||
daemon->rr_status = safe_malloc(sizeof(*daemon->rr_status) * daemon->rr_status_sz);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_CONNTRACK) && defined(HAVE_UBUS)
|
||||
/* CONNTRACK UBUS code uses this buffer, so if not allocated above,
|
||||
we need to allocate it here. */
|
||||
if (option_bool(OPT_CMARK_ALST_EN) && !daemon->workspacename)
|
||||
daemon->workspacename = safe_malloc((MAXDNAME * 2) + 1);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DHCP
|
||||
if (!daemon->lease_file)
|
||||
|
||||
@@ -341,7 +341,7 @@ union all_addr {
|
||||
in the cache flags. */
|
||||
struct datablock {
|
||||
unsigned short rrtype;
|
||||
unsigned char datalen;
|
||||
unsigned char datalen; /* also length of SOA in negative records. */
|
||||
char data[];
|
||||
} rrdata;
|
||||
};
|
||||
@@ -1233,10 +1233,7 @@ extern struct daemon {
|
||||
char *packet; /* packet buffer */
|
||||
int packet_buff_sz; /* size of above */
|
||||
char *namebuff; /* MAXDNAME size buffer */
|
||||
#if (defined(HAVE_CONNTRACK) && defined(HAVE_UBUS)) || defined(HAVE_DNSSEC)
|
||||
/* CONNTRACK UBUS code uses this buffer, as well as DNSSEC code. */
|
||||
char *workspacename;
|
||||
#endif
|
||||
#ifdef HAVE_DNSSEC
|
||||
char *keyname; /* MAXDNAME size buffer */
|
||||
unsigned long *rr_status; /* ceiling in TTL from DNSSEC or zero for insecure */
|
||||
@@ -1376,6 +1373,7 @@ int is_name_synthetic(int flags, char *name, union all_addr *addr);
|
||||
int is_rev_synth(int flag, union all_addr *addr, char *name);
|
||||
|
||||
/* rfc1035.c */
|
||||
int do_doctor(struct dns_header *header, size_t qlen);
|
||||
int extract_name(struct dns_header *header, size_t plen, unsigned char **pp,
|
||||
char *name, int isExtract, int extrabytes);
|
||||
unsigned char *skip_name(unsigned char *ansp, struct dns_header *header, size_t plen, int extrabytes);
|
||||
@@ -1386,7 +1384,7 @@ unsigned int extract_request(struct dns_header *header, size_t qlen,
|
||||
void setup_reply(struct dns_header *header, unsigned int flags, int ede);
|
||||
int extract_addresses(struct dns_header *header, size_t qlen, char *name,
|
||||
time_t now, struct ipsets *ipsets, struct ipsets *nftsets, int is_sign,
|
||||
int check_rebind, int no_cache_dnssec, int secure, int *doctored);
|
||||
int check_rebind, int no_cache_dnssec, int secure);
|
||||
#if defined(HAVE_CONNTRACK) && defined(HAVE_UBUS)
|
||||
void report_addresses(struct dns_header *header, size_t len, u32 mark);
|
||||
#endif
|
||||
|
||||
@@ -782,8 +782,13 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
|
||||
server->flags |= SERV_WARNED_RECURSIVE;
|
||||
}
|
||||
|
||||
if (daemon->bogus_addr && rcode != NXDOMAIN &&
|
||||
check_for_bogus_wildcard(header, n, daemon->namebuff, now))
|
||||
if (header->hb3 & HB3_TC)
|
||||
{
|
||||
log_query(F_UPSTREAM, NULL, NULL, "truncated", 0);
|
||||
munged = 1;
|
||||
}
|
||||
else if (daemon->bogus_addr && rcode != NXDOMAIN &&
|
||||
check_for_bogus_wildcard(header, n, daemon->namebuff, now))
|
||||
{
|
||||
munged = 1;
|
||||
SET_RCODE(header, NXDOMAIN);
|
||||
@@ -793,8 +798,6 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
|
||||
}
|
||||
else
|
||||
{
|
||||
int doctored = 0;
|
||||
|
||||
if (rcode == NXDOMAIN &&
|
||||
extract_request(header, n, daemon->namebuff, NULL))
|
||||
{
|
||||
@@ -810,8 +813,11 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
|
||||
cache_secure = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (do_doctor(header, n))
|
||||
cache_secure = 0;
|
||||
|
||||
switch (extract_addresses(header, n, daemon->namebuff, now, ipsets, nftsets, is_sign, check_rebind, no_cache, cache_secure, &doctored))
|
||||
switch (extract_addresses(header, n, daemon->namebuff, now, ipsets, nftsets, is_sign, check_rebind, no_cache, cache_secure))
|
||||
{
|
||||
case 1:
|
||||
my_syslog(LOG_WARNING, _("possible DNS-rebind attack detected: %s"), daemon->namebuff);
|
||||
@@ -831,9 +837,6 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
|
||||
|
||||
if (rcode == NOERROR && rrfilter(header, &n, RRFILTER_CONF) > 0)
|
||||
ede = EDE_FILTERED;
|
||||
|
||||
if (doctored)
|
||||
cache_secure = 0;
|
||||
}
|
||||
|
||||
#ifdef HAVE_DNSSEC
|
||||
@@ -864,7 +867,6 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
|
||||
header->ancount = htons(0);
|
||||
header->nscount = htons(0);
|
||||
header->arcount = htons(0);
|
||||
header->hb3 &= ~HB3_TC;
|
||||
}
|
||||
|
||||
/* the bogus-nxdomain stuff, doctor and NXDOMAIN->NODATA munging can all elide
|
||||
|
||||
@@ -5844,6 +5844,7 @@ void read_opts(int argc, char **argv, char *compile_opts)
|
||||
daemon = opt_malloc(sizeof(struct daemon));
|
||||
memset(daemon, 0, sizeof(struct daemon));
|
||||
daemon->namebuff = buff;
|
||||
daemon->workspacename = safe_malloc((MAXDNAME * 2) + 1);
|
||||
daemon->addrbuff = safe_malloc(ADDRSTRLEN);
|
||||
|
||||
/* Set defaults - everything else is zero or NULL */
|
||||
|
||||
1515
src/rfc1035.c
1515
src/rfc1035.c
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user