mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 10:18:25 +00:00
Further tidying of AD and DO bit handling.
This commit is contained in:
@@ -539,6 +539,7 @@ struct hostsfile {
|
|||||||
#define FREC_HAS_SUBNET 4
|
#define FREC_HAS_SUBNET 4
|
||||||
#define FREC_DNSKEY_QUERY 8
|
#define FREC_DNSKEY_QUERY 8
|
||||||
#define FREC_DS_QUERY 16
|
#define FREC_DS_QUERY 16
|
||||||
|
#define FREC_AD_QUESTION 32
|
||||||
|
|
||||||
#ifdef HAVE_DNSSEC
|
#ifdef HAVE_DNSSEC
|
||||||
#define HASH_SIZE 20 /* SHA-1 digest size */
|
#define HASH_SIZE 20 /* SHA-1 digest size */
|
||||||
@@ -1041,7 +1042,8 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *namebuff,
|
|||||||
time_t now, char **ipsets, int is_sign, int checkrebind,
|
time_t now, char **ipsets, int is_sign, int checkrebind,
|
||||||
int no_cache, int secure, int *doctored);
|
int no_cache, int secure, int *doctored);
|
||||||
size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
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);
|
struct in_addr local_addr, struct in_addr local_netmask,
|
||||||
|
time_t now, int *ad_reqd);
|
||||||
int check_for_bogus_wildcard(struct dns_header *header, size_t qlen, char *name,
|
int check_for_bogus_wildcard(struct dns_header *header, size_t qlen, char *name,
|
||||||
struct bogus_addr *addr, time_t now);
|
struct bogus_addr *addr, time_t now);
|
||||||
unsigned char *find_pseudoheader(struct dns_header *header, size_t plen,
|
unsigned char *find_pseudoheader(struct dns_header *header, size_t plen,
|
||||||
|
|||||||
@@ -234,7 +234,8 @@ static unsigned int search_servers(time_t now, struct all_addr **addrpp,
|
|||||||
|
|
||||||
static int forward_query(int udpfd, union mysockaddr *udpaddr,
|
static int forward_query(int udpfd, union mysockaddr *udpaddr,
|
||||||
struct all_addr *dst_addr, unsigned int dst_iface,
|
struct all_addr *dst_addr, unsigned int dst_iface,
|
||||||
struct dns_header *header, size_t plen, time_t now, struct frec *forward)
|
struct dns_header *header, size_t plen, time_t now,
|
||||||
|
struct frec *forward, int ad_reqd)
|
||||||
{
|
{
|
||||||
char *domain = NULL;
|
char *domain = NULL;
|
||||||
int type = 0, norebind = 0;
|
int type = 0, norebind = 0;
|
||||||
@@ -331,6 +332,8 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
|
|||||||
forward->flags |= FREC_NOREBIND;
|
forward->flags |= FREC_NOREBIND;
|
||||||
if (header->hb4 & HB4_CD)
|
if (header->hb4 & HB4_CD)
|
||||||
forward->flags |= FREC_CHECKING_DISABLED;
|
forward->flags |= FREC_CHECKING_DISABLED;
|
||||||
|
if (ad_reqd)
|
||||||
|
forward->flags |= FREC_AD_QUESTION;
|
||||||
#ifdef HAVE_DNSSEC
|
#ifdef HAVE_DNSSEC
|
||||||
forward->work_counter = DNSSEC_WORK;
|
forward->work_counter = DNSSEC_WORK;
|
||||||
#endif
|
#endif
|
||||||
@@ -503,13 +506,15 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static size_t process_reply(struct dns_header *header, time_t now, struct server *server, size_t n, int check_rebind,
|
static size_t process_reply(struct dns_header *header, time_t now, struct server *server, size_t n, int check_rebind,
|
||||||
int no_cache, int cache_secure, int check_subnet, union mysockaddr *query_source)
|
int no_cache, int cache_secure, int ad_reqd, int check_subnet, union mysockaddr *query_source)
|
||||||
{
|
{
|
||||||
unsigned char *pheader, *sizep;
|
unsigned char *pheader, *sizep;
|
||||||
char **sets = 0;
|
char **sets = 0;
|
||||||
int munged = 0, is_sign;
|
int munged = 0, is_sign;
|
||||||
size_t plen;
|
size_t plen;
|
||||||
|
|
||||||
|
(void)ad_reqd;
|
||||||
|
|
||||||
#ifdef HAVE_IPSET
|
#ifdef HAVE_IPSET
|
||||||
/* Similar algorithm to search_servers. */
|
/* Similar algorithm to search_servers. */
|
||||||
struct ipsets *ipset_pos;
|
struct ipsets *ipset_pos;
|
||||||
@@ -535,15 +540,13 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
|
|||||||
|
|
||||||
if ((pheader = find_pseudoheader(header, n, &plen, &sizep, &is_sign)))
|
if ((pheader = find_pseudoheader(header, n, &plen, &sizep, &is_sign)))
|
||||||
{
|
{
|
||||||
if (!is_sign)
|
unsigned short udpsz;
|
||||||
{
|
unsigned char *psave = sizep;
|
||||||
unsigned short udpsz;
|
|
||||||
unsigned char *psave = sizep;
|
GETSHORT(udpsz, sizep);
|
||||||
|
|
||||||
GETSHORT(udpsz, sizep);
|
if (!is_sign && udpsz > daemon->edns_pktsz)
|
||||||
if (udpsz > daemon->edns_pktsz)
|
PUTSHORT(daemon->edns_pktsz, psave);
|
||||||
PUTSHORT(daemon->edns_pktsz, psave);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (check_subnet && !check_source(header, plen, pheader, query_source))
|
if (check_subnet && !check_source(header, plen, pheader, query_source))
|
||||||
{
|
{
|
||||||
@@ -551,7 +554,7 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* RFC 4035 sect 4.6 para 3 */
|
/* RFC 4035 sect 4.6 para 3 */
|
||||||
if (!is_sign && !option_bool(OPT_DNSSEC_PROXY))
|
if (!is_sign && !option_bool(OPT_DNSSEC_PROXY))
|
||||||
header->hb4 &= ~HB4_AD;
|
header->hb4 &= ~HB4_AD;
|
||||||
@@ -619,7 +622,7 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
|
|||||||
if (option_bool(OPT_DNSSEC_VALID))
|
if (option_bool(OPT_DNSSEC_VALID))
|
||||||
header->hb4 &= ~HB4_AD;
|
header->hb4 &= ~HB4_AD;
|
||||||
|
|
||||||
if (!(header->hb4 & HB4_CD) && cache_secure)
|
if (!(header->hb4 & HB4_CD) && ad_reqd && cache_secure)
|
||||||
header->hb4 |= HB4_AD;
|
header->hb4 |= HB4_AD;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -705,7 +708,7 @@ void reply_query(int fd, int family, time_t now)
|
|||||||
if ((nn = resize_packet(header, (size_t)n, pheader, plen)))
|
if ((nn = resize_packet(header, (size_t)n, pheader, plen)))
|
||||||
{
|
{
|
||||||
header->hb3 &= ~(HB3_QR | HB3_TC);
|
header->hb3 &= ~(HB3_QR | HB3_TC);
|
||||||
forward_query(-1, NULL, NULL, 0, header, nn, now, forward);
|
forward_query(-1, NULL, NULL, 0, header, nn, now, forward, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -914,17 +917,17 @@ void reply_query(int fd, int family, time_t now)
|
|||||||
cache_secure = 1;
|
cache_secure = 1;
|
||||||
else if (status == STAT_BOGUS)
|
else if (status == STAT_BOGUS)
|
||||||
no_cache_dnssec = 1;
|
no_cache_dnssec = 1;
|
||||||
|
|
||||||
/* restore CD bit to the value in the query */
|
|
||||||
if (forward->flags & FREC_CHECKING_DISABLED)
|
|
||||||
header->hb4 |= HB4_CD;
|
|
||||||
else
|
|
||||||
header->hb4 &= ~HB4_CD;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* restore CD bit to the value in the query */
|
||||||
|
if (forward->flags & FREC_CHECKING_DISABLED)
|
||||||
|
header->hb4 |= HB4_CD;
|
||||||
|
else
|
||||||
|
header->hb4 &= ~HB4_CD;
|
||||||
|
|
||||||
if ((nn = process_reply(header, now, server, (size_t)n, check_rebind, no_cache_dnssec, cache_secure,
|
if ((nn = process_reply(header, now, server, (size_t)n, check_rebind, no_cache_dnssec, cache_secure,
|
||||||
forward->flags & FREC_HAS_SUBNET, &forward->source)))
|
forward->flags & FREC_AD_QUESTION, forward->flags & FREC_HAS_SUBNET, &forward->source)))
|
||||||
{
|
{
|
||||||
header->id = htons(forward->orig_id);
|
header->id = htons(forward->orig_id);
|
||||||
header->hb4 |= HB4_RA; /* recursion if available */
|
header->hb4 |= HB4_RA; /* recursion if available */
|
||||||
@@ -1166,8 +1169,9 @@ void receive_query(struct listener *listen, time_t now)
|
|||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
int ad_reqd;
|
||||||
m = answer_request(header, ((char *) header) + daemon->packet_buff_sz, (size_t)n,
|
m = answer_request(header, ((char *) header) + daemon->packet_buff_sz, (size_t)n,
|
||||||
dst_addr_4, netmask, now);
|
dst_addr_4, netmask, now, &ad_reqd);
|
||||||
|
|
||||||
if (m >= 1)
|
if (m >= 1)
|
||||||
{
|
{
|
||||||
@@ -1176,7 +1180,7 @@ void receive_query(struct listener *listen, time_t now)
|
|||||||
daemon->local_answer++;
|
daemon->local_answer++;
|
||||||
}
|
}
|
||||||
else if (forward_query(listen->fd, &source_addr, &dst_addr, if_index,
|
else if (forward_query(listen->fd, &source_addr, &dst_addr, if_index,
|
||||||
header, (size_t)n, now, NULL))
|
header, (size_t)n, now, NULL, ad_reqd))
|
||||||
daemon->queries_forwarded++;
|
daemon->queries_forwarded++;
|
||||||
else
|
else
|
||||||
daemon->local_answer++;
|
daemon->local_answer++;
|
||||||
@@ -1268,7 +1272,7 @@ unsigned char *tcp_request(int confd, time_t now,
|
|||||||
#ifdef HAVE_AUTH
|
#ifdef HAVE_AUTH
|
||||||
int local_auth = 0;
|
int local_auth = 0;
|
||||||
#endif
|
#endif
|
||||||
int checking_disabled, check_subnet, no_cache_dnssec = 0, cache_secure = 0;
|
int checking_disabled, ad_question, check_subnet, no_cache_dnssec = 0, cache_secure = 0;
|
||||||
size_t m;
|
size_t m;
|
||||||
unsigned short qtype;
|
unsigned short qtype;
|
||||||
unsigned int gotname;
|
unsigned int gotname;
|
||||||
@@ -1346,7 +1350,7 @@ unsigned char *tcp_request(int confd, time_t now,
|
|||||||
{
|
{
|
||||||
/* m > 0 if answered from cache */
|
/* m > 0 if answered from cache */
|
||||||
m = answer_request(header, ((char *) header) + 65536, (size_t)size,
|
m = answer_request(header, ((char *) header) + 65536, (size_t)size,
|
||||||
dst_addr_4, netmask, now);
|
dst_addr_4, netmask, now, &ad_question);
|
||||||
|
|
||||||
/* Do this by steam now we're not in the select() loop */
|
/* Do this by steam now we're not in the select() loop */
|
||||||
check_log_writer(NULL);
|
check_log_writer(NULL);
|
||||||
@@ -1526,7 +1530,7 @@ unsigned char *tcp_request(int confd, time_t now,
|
|||||||
|
|
||||||
m = process_reply(header, now, last_server, (unsigned int)m,
|
m = process_reply(header, now, last_server, (unsigned int)m,
|
||||||
option_bool(OPT_NO_REBIND) && !norebind, no_cache_dnssec,
|
option_bool(OPT_NO_REBIND) && !norebind, no_cache_dnssec,
|
||||||
cache_secure, check_subnet, &peer_addr);
|
cache_secure, ad_question, check_subnet, &peer_addr);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1452,7 +1452,8 @@ static unsigned long crec_ttl(struct crec *crecp, time_t now)
|
|||||||
|
|
||||||
/* return zero if we can't answer from cache, or packet size if we can */
|
/* 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,
|
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)
|
struct in_addr local_addr, struct in_addr local_netmask,
|
||||||
|
time_t now, int *ad_reqd)
|
||||||
{
|
{
|
||||||
char *name = daemon->namebuff;
|
char *name = daemon->namebuff;
|
||||||
unsigned char *p, *ansp, *pheader;
|
unsigned char *p, *ansp, *pheader;
|
||||||
@@ -1471,7 +1472,10 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
|||||||
/* Don't return AD set if checking disabled. */
|
/* Don't return AD set if checking disabled. */
|
||||||
if (header->hb4 & HB4_CD)
|
if (header->hb4 & HB4_CD)
|
||||||
sec_data = 0;
|
sec_data = 0;
|
||||||
|
|
||||||
|
/* RFC 6840 5.7 */
|
||||||
|
*ad_reqd = header->hb4 & HB4_AD;
|
||||||
|
|
||||||
/* If there is an RFC2671 pseudoheader then it will be overwritten by
|
/* If there is an RFC2671 pseudoheader then it will be overwritten by
|
||||||
partial replies, so we have to do a dry run to see if we can answer
|
partial replies, so we have to do a dry run to see if we can answer
|
||||||
the query. We check to see if the do bit is set, if so we always
|
the query. We check to see if the do bit is set, if so we always
|
||||||
@@ -1490,6 +1494,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
|||||||
GETSHORT(flags, pheader);
|
GETSHORT(flags, pheader);
|
||||||
|
|
||||||
sec_reqd = flags & 0x8000; /* do bit */
|
sec_reqd = flags & 0x8000; /* do bit */
|
||||||
|
*ad_reqd = 1;
|
||||||
|
|
||||||
/* If our client is advertising a larger UDP packet size
|
/* If our client is advertising a larger UDP packet size
|
||||||
than we allow, trim it so that we don't get an overlarge
|
than we allow, trim it so that we don't get an overlarge
|
||||||
@@ -2257,19 +2262,15 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
|||||||
header->nscount = htons(0);
|
header->nscount = htons(0);
|
||||||
header->arcount = htons(addncount);
|
header->arcount = htons(addncount);
|
||||||
|
|
||||||
/* RFC 6840 5.7 */
|
|
||||||
if (header->hb4 & HB4_AD)
|
|
||||||
sec_reqd = 1;
|
|
||||||
|
|
||||||
header->hb4 &= ~HB4_AD;
|
|
||||||
|
|
||||||
len = ansp - (unsigned char *)header;
|
len = ansp - (unsigned char *)header;
|
||||||
|
|
||||||
if (have_pseudoheader)
|
if (have_pseudoheader)
|
||||||
len = add_pseudoheader(header, len, (unsigned char *)limit, 0, NULL, 0, sec_reqd);
|
len = add_pseudoheader(header, len, (unsigned char *)limit, 0, NULL, 0, sec_reqd);
|
||||||
|
|
||||||
if (sec_reqd && sec_data)
|
if (*ad_reqd && sec_data)
|
||||||
header->hb4 |= HB4_AD;
|
header->hb4 |= HB4_AD;
|
||||||
|
else
|
||||||
|
header->hb4 &= ~HB4_AD;
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user