mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 10:18:25 +00:00
Improve handling of non-QUERY DNS requests.
We can't answer and shouldn't forward non-QUERY DNS requests. This patch fixes handling such requests from TCP connections; before the connection would be closed without reply. It also changes the RCODE in the answer from REFUSED to NOTIMP and provides clearer logging.
This commit is contained in:
@@ -405,10 +405,18 @@ size_t make_local_answer(int flags, int gotname, size_t size, struct dns_header
|
|||||||
int start;
|
int start;
|
||||||
union all_addr addr;
|
union all_addr addr;
|
||||||
|
|
||||||
|
setup_reply(header, flags, ede);
|
||||||
|
|
||||||
if (flags & (F_NXDOMAIN | F_NOERR))
|
if (flags & (F_NXDOMAIN | F_NOERR))
|
||||||
log_query(flags | gotname | F_NEG | F_CONFIG | F_FORWARD, name, NULL, NULL, 0);
|
log_query(flags | gotname | F_NEG | F_CONFIG | F_FORWARD, name, NULL, NULL, 0);
|
||||||
|
|
||||||
setup_reply(header, flags, ede);
|
if (flags & F_RCODE)
|
||||||
|
{
|
||||||
|
union all_addr a;
|
||||||
|
a.log.rcode = RCODE(header);
|
||||||
|
a.log.ede = ede;
|
||||||
|
log_query(F_UPSTREAM | F_RCODE, "opcode", &a, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
if (!(p = skip_questions(header, size)))
|
if (!(p = skip_questions(header, size)))
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -277,11 +277,16 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
|
|||||||
|
|
||||||
/* new query */
|
/* new query */
|
||||||
if (!forward)
|
if (!forward)
|
||||||
|
{
|
||||||
|
if (OPCODE(header) != QUERY)
|
||||||
|
{
|
||||||
|
flags = F_RCODE;
|
||||||
|
goto reply;
|
||||||
|
}
|
||||||
|
else if (!gotname)
|
||||||
{
|
{
|
||||||
/* If the query is malformed, we can't forward it because
|
/* If the query is malformed, we can't forward it because
|
||||||
we can't recognise the answer. */
|
we can't recognise the answer. */
|
||||||
if (!gotname)
|
|
||||||
{
|
|
||||||
flags = 0;
|
flags = 0;
|
||||||
ede = EDE_INVALID_DATA;
|
ede = EDE_INVALID_DATA;
|
||||||
goto reply;
|
goto reply;
|
||||||
@@ -1686,7 +1691,9 @@ void receive_query(struct listener *listen, time_t now)
|
|||||||
have_mark = get_incoming_mark(&source_addr, &dst_addr, /* istcp: */ 0, &mark);
|
have_mark = get_incoming_mark(&source_addr, &dst_addr, /* istcp: */ 0, &mark);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (extract_request(header, (size_t)n, daemon->namebuff, &type))
|
if (OPCODE(header) != QUERY)
|
||||||
|
log_query_mysockaddr(F_QUERY | F_FORWARD, "opcode", &source_addr, "non-query", 0);
|
||||||
|
else if (extract_request(header, (size_t)n, daemon->namebuff, &type))
|
||||||
{
|
{
|
||||||
#ifdef HAVE_AUTH
|
#ifdef HAVE_AUTH
|
||||||
struct auth_zone *zone;
|
struct auth_zone *zone;
|
||||||
@@ -2292,6 +2299,8 @@ unsigned char *tcp_request(int confd, time_t now,
|
|||||||
{
|
{
|
||||||
int ede = EDE_UNSET;
|
int ede = EDE_UNSET;
|
||||||
|
|
||||||
|
stale = 0;
|
||||||
|
|
||||||
if (!do_stale)
|
if (!do_stale)
|
||||||
{
|
{
|
||||||
if (query_count >= TCP_MAX_QUERIES)
|
if (query_count >= TCP_MAX_QUERIES)
|
||||||
@@ -2322,7 +2331,14 @@ unsigned char *tcp_request(int confd, time_t now,
|
|||||||
if ((checking_disabled = header->hb4 & HB4_CD))
|
if ((checking_disabled = header->hb4 & HB4_CD))
|
||||||
no_cache_dnssec = 1;
|
no_cache_dnssec = 1;
|
||||||
|
|
||||||
if ((gotname = extract_request(header, (unsigned int)size, daemon->namebuff, &qtype)))
|
if (OPCODE(header) != QUERY)
|
||||||
|
{
|
||||||
|
log_query_mysockaddr(F_QUERY | F_FORWARD, "opcode", &peer_addr, "non-query", 0);
|
||||||
|
gotname = 0;
|
||||||
|
m = 0;
|
||||||
|
flags = F_RCODE;
|
||||||
|
}
|
||||||
|
else if ((gotname = extract_request(header, (unsigned int)size, daemon->namebuff, &qtype)))
|
||||||
{
|
{
|
||||||
#ifdef HAVE_AUTH
|
#ifdef HAVE_AUTH
|
||||||
struct auth_zone *zone;
|
struct auth_zone *zone;
|
||||||
@@ -2349,7 +2365,6 @@ unsigned char *tcp_request(int confd, time_t now,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
norebind = domain_no_rebind(daemon->namebuff);
|
norebind = domain_no_rebind(daemon->namebuff);
|
||||||
|
|
||||||
@@ -2427,6 +2442,7 @@ unsigned char *tcp_request(int confd, time_t now,
|
|||||||
m = add_pseudoheader(header, m, ((unsigned char *) header) + 65536,
|
m = add_pseudoheader(header, m, ((unsigned char *) header) + 65536,
|
||||||
0, NULL, 0, do_bit, 0);
|
0, NULL, 0, do_bit, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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(1);
|
check_log_writer(1);
|
||||||
|
|
||||||
@@ -2562,6 +2578,7 @@ unsigned char *tcp_request(int confd, time_t now,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (do_stale)
|
if (do_stale)
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -1240,6 +1240,8 @@ void setup_reply(struct dns_header *header, unsigned int flags, int ede)
|
|||||||
SET_RCODE(header, NOERROR); /* empty domain */
|
SET_RCODE(header, NOERROR); /* empty domain */
|
||||||
else if (flags == F_NXDOMAIN)
|
else if (flags == F_NXDOMAIN)
|
||||||
SET_RCODE(header, NXDOMAIN);
|
SET_RCODE(header, NXDOMAIN);
|
||||||
|
else if (flags == F_RCODE)
|
||||||
|
SET_RCODE(header, NOTIMP);
|
||||||
else if (flags & ( F_IPV4 | F_IPV6))
|
else if (flags & ( F_IPV4 | F_IPV6))
|
||||||
{
|
{
|
||||||
SET_RCODE(header, NOERROR);
|
SET_RCODE(header, NOERROR);
|
||||||
@@ -2210,8 +2212,8 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
|||||||
anscount++;
|
anscount++;
|
||||||
|
|
||||||
/* log after cache insertion as log_txt mangles rrdata */
|
/* log after cache insertion as log_txt mangles rrdata */
|
||||||
if (qtype == T_TXT && !(crecp->flags & F_NEG))
|
if (qtype == T_TXT && !(flags & F_NEG))
|
||||||
log_txt(name, (unsigned char *)rrdata, rrlen, crecp->flags & F_DNSSECOK);
|
log_txt(name, (unsigned char *)rrdata, rrlen, flags & (F_DNSSECOK | F_STALE));
|
||||||
else
|
else
|
||||||
log_query(flags, name, &crecp->addr, NULL, 0);
|
log_query(flags, name, &crecp->addr, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user