Commit 07ed585c authored by Simon Kelley's avatar Simon Kelley

Add logging for DNS error returns from upstream and local configuration.

parent 0669ee7a
...@@ -1598,6 +1598,19 @@ void log_query(unsigned int flags, char *name, struct all_addr *addr, char *arg) ...@@ -1598,6 +1598,19 @@ void log_query(unsigned int flags, char *name, struct all_addr *addr, char *arg)
{ {
if (flags & F_KEYTAG) if (flags & F_KEYTAG)
sprintf(daemon->addrbuff, arg, addr->addr.log.keytag, addr->addr.log.algo, addr->addr.log.digest); sprintf(daemon->addrbuff, arg, addr->addr.log.keytag, addr->addr.log.algo, addr->addr.log.digest);
else if (flags & F_RCODE)
{
unsigned int rcode = addr->addr.rcode.rcode;
if (rcode == SERVFAIL)
dest = "SERVFAIL";
else if (rcode == REFUSED)
dest = "REFUSED";
else if (rcode == NOTIMP)
dest = "not implemented";
else
sprintf(daemon->addrbuff, "%u", rcode);
}
else else
{ {
#ifdef HAVE_IPV6 #ifdef HAVE_IPV6
......
...@@ -269,6 +269,10 @@ struct all_addr { ...@@ -269,6 +269,10 @@ struct all_addr {
struct { struct {
unsigned short keytag, algo, digest; unsigned short keytag, algo, digest;
} log; } log;
/* for log_query */
struct {
unsigned int rcode;
} rcode;
/* for cache_insert of DNSKEY, DS */ /* for cache_insert of DNSKEY, DS */
struct { struct {
unsigned short class, type; unsigned short class, type;
...@@ -459,6 +463,7 @@ struct crec { ...@@ -459,6 +463,7 @@ struct crec {
#define F_IPSET (1u<<26) #define F_IPSET (1u<<26)
#define F_NOEXTRA (1u<<27) #define F_NOEXTRA (1u<<27)
#define F_SERVFAIL (1u<<28) #define F_SERVFAIL (1u<<28)
#define F_RCODE (1u<<29)
/* Values of uid in crecs with F_CONFIG bit set. */ /* Values of uid in crecs with F_CONFIG bit set. */
#define SRC_INTERFACE 0 #define SRC_INTERFACE 0
......
...@@ -563,6 +563,7 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server ...@@ -563,6 +563,7 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
unsigned char *pheader, *sizep; unsigned char *pheader, *sizep;
char **sets = 0; char **sets = 0;
int munged = 0, is_sign; int munged = 0, is_sign;
unsigned int rcode = RCODE(header);
size_t plen; size_t plen;
(void)ad_reqd; (void)ad_reqd;
...@@ -593,6 +594,9 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server ...@@ -593,6 +594,9 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
if ((pheader = find_pseudoheader(header, n, &plen, &sizep, &is_sign, NULL))) if ((pheader = find_pseudoheader(header, n, &plen, &sizep, &is_sign, NULL)))
{ {
/* Get extended RCODE. */
rcode |= sizep[2] << 4;
if (check_subnet && !check_source(header, plen, pheader, query_source)) if (check_subnet && !check_source(header, plen, pheader, query_source))
{ {
my_syslog(LOG_WARNING, _("discarding DNS reply: subnet option mismatch")); my_syslog(LOG_WARNING, _("discarding DNS reply: subnet option mismatch"));
...@@ -641,11 +645,20 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server ...@@ -641,11 +645,20 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
if (!is_sign && !option_bool(OPT_DNSSEC_PROXY)) if (!is_sign && !option_bool(OPT_DNSSEC_PROXY))
header->hb4 &= ~HB4_AD; header->hb4 &= ~HB4_AD;
if (OPCODE(header) != QUERY || (RCODE(header) != NOERROR && RCODE(header) != NXDOMAIN)) if (OPCODE(header) != QUERY)
return resize_packet(header, n, pheader, plen);
if (rcode != NOERROR && rcode != NXDOMAIN)
{
struct all_addr a;
a.addr.rcode.rcode = rcode;
log_query(F_UPSTREAM | F_RCODE, "error", &a, NULL);
return resize_packet(header, n, pheader, plen); return resize_packet(header, n, pheader, plen);
}
/* Complain loudly if the upstream server is non-recursive. */ /* Complain loudly if the upstream server is non-recursive. */
if (!(header->hb4 & HB4_RA) && RCODE(header) == NOERROR && if (!(header->hb4 & HB4_RA) && rcode == NOERROR &&
server && !(server->flags & SERV_WARNED_RECURSIVE)) server && !(server->flags & SERV_WARNED_RECURSIVE))
{ {
prettyprint_addr(&server->addr, daemon->namebuff); prettyprint_addr(&server->addr, daemon->namebuff);
...@@ -654,7 +667,7 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server ...@@ -654,7 +667,7 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
server->flags |= SERV_WARNED_RECURSIVE; server->flags |= SERV_WARNED_RECURSIVE;
} }
if (daemon->bogus_addr && RCODE(header) != NXDOMAIN && if (daemon->bogus_addr && rcode != NXDOMAIN &&
check_for_bogus_wildcard(header, n, daemon->namebuff, daemon->bogus_addr, now)) check_for_bogus_wildcard(header, n, daemon->namebuff, daemon->bogus_addr, now))
{ {
munged = 1; munged = 1;
...@@ -666,7 +679,7 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server ...@@ -666,7 +679,7 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
{ {
int doctored = 0; int doctored = 0;
if (RCODE(header) == NXDOMAIN && if (rcode == NXDOMAIN &&
extract_request(header, n, daemon->namebuff, NULL) && extract_request(header, n, daemon->namebuff, NULL) &&
check_for_local_domain(daemon->namebuff, now)) check_for_local_domain(daemon->namebuff, now))
{ {
...@@ -1090,7 +1103,7 @@ void reply_query(int fd, int family, time_t now) ...@@ -1090,7 +1103,7 @@ void reply_query(int fd, int family, time_t now)
if (status == STAT_BOGUS && extract_request(header, n, daemon->namebuff, NULL)) if (status == STAT_BOGUS && extract_request(header, n, daemon->namebuff, NULL))
domain = daemon->namebuff; domain = daemon->namebuff;
log_query(F_KEYTAG | F_SECSTAT, domain, NULL, result); log_query(F_SECSTAT, domain, NULL, result);
} }
if (status == STAT_SECURE) if (status == STAT_SECURE)
...@@ -1948,7 +1961,7 @@ unsigned char *tcp_request(int confd, time_t now, ...@@ -1948,7 +1961,7 @@ unsigned char *tcp_request(int confd, time_t now,
if (status == STAT_BOGUS && extract_request(header, m, daemon->namebuff, NULL)) if (status == STAT_BOGUS && extract_request(header, m, daemon->namebuff, NULL))
domain = daemon->namebuff; domain = daemon->namebuff;
log_query(F_KEYTAG | F_SECSTAT, domain, NULL, result); log_query(F_SECSTAT, domain, NULL, result);
if (status == STAT_BOGUS) if (status == STAT_BOGUS)
{ {
......
...@@ -926,7 +926,6 @@ unsigned int extract_request(struct dns_header *header, size_t qlen, char *name, ...@@ -926,7 +926,6 @@ unsigned int extract_request(struct dns_header *header, size_t qlen, char *name,
return F_QUERY; return F_QUERY;
} }
size_t setup_reply(struct dns_header *header, size_t qlen, size_t setup_reply(struct dns_header *header, size_t qlen,
struct all_addr *addrp, unsigned int flags, unsigned long ttl) struct all_addr *addrp, unsigned int flags, unsigned long ttl)
{ {
...@@ -948,7 +947,12 @@ size_t setup_reply(struct dns_header *header, size_t qlen, ...@@ -948,7 +947,12 @@ size_t setup_reply(struct dns_header *header, size_t qlen,
else if (flags == F_NXDOMAIN) else if (flags == F_NXDOMAIN)
SET_RCODE(header, NXDOMAIN); SET_RCODE(header, NXDOMAIN);
else if (flags == F_SERVFAIL) else if (flags == F_SERVFAIL)
{
struct all_addr a;
a.addr.rcode.rcode = SERVFAIL;
log_query(F_CONFIG | F_RCODE, "error", &a, NULL);
SET_RCODE(header, SERVFAIL); SET_RCODE(header, SERVFAIL);
}
else if (flags == F_IPV4) else if (flags == F_IPV4)
{ /* we know the address */ { /* we know the address */
SET_RCODE(header, NOERROR); SET_RCODE(header, NOERROR);
...@@ -966,7 +970,12 @@ size_t setup_reply(struct dns_header *header, size_t qlen, ...@@ -966,7 +970,12 @@ size_t setup_reply(struct dns_header *header, size_t qlen,
} }
#endif #endif
else /* nowhere to forward to */ else /* nowhere to forward to */
{
struct all_addr a;
a.addr.rcode.rcode = REFUSED;
log_query(F_CONFIG | F_RCODE, "error", &a, NULL);
SET_RCODE(header, REFUSED); SET_RCODE(header, REFUSED);
}
return p - (unsigned char *)header; return p - (unsigned char *)header;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment