summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Kelley <simon@thekelleys.org.uk>2013-10-18 22:00:39 +0100
committerSimon Kelley <simon@thekelleys.org.uk>2013-10-18 22:00:39 +0100
commitb485ed97aa5726644d71d3a16ccdd058d6a8d73a (patch)
treed8a8993dc976dbbbe0817105597a9cc8d6f4c335
parent53c4c5c85942d4733f4723531c4d325235448326 (diff)
downloaddnsmasq-b485ed97aa5726644d71d3a16ccdd058d6a8d73a.tar.gz
Always answer queries for authoritative zones locally, never forward.
-rw-r--r--src/auth.c2
-rw-r--r--src/cache.c3
-rw-r--r--src/dnsmasq.h3
-rw-r--r--src/forward.c36
4 files changed, 38 insertions, 6 deletions
diff --git a/src/auth.c b/src/auth.c
index af2171c..98934d0 100644
--- a/src/auth.c
+++ b/src/auth.c
@@ -62,7 +62,7 @@ static int filter_constructed_dhcp(struct auth_zone *zone, int flag, struct all_
return filter_zone(zone, flag, addr_u) != NULL;
}
-static int in_zone(struct auth_zone *zone, char *name, char **cut)
+int in_zone(struct auth_zone *zone, char *name, char **cut)
{
size_t namelen = strlen(name);
size_t domainlen = strlen(zone->domain);
diff --git a/src/cache.c b/src/cache.c
index 6247cab..d99aba6 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -1161,6 +1161,9 @@ void dump_cache(time_t now)
daemon->cachesize, cache_live_freed, cache_inserted);
my_syslog(LOG_INFO, _("queries forwarded %u, queries answered locally %u"),
daemon->queries_forwarded, daemon->local_answer);
+#ifdef HAVE_AUTH
+ my_syslog(LOG_INFO, _("queries for authoritative zones %u"), daemon->auth_answer);
+#endif
/* sum counts from different records for same server */
for (serv = daemon->servers; serv; serv = serv->next)
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
index 17a351f..0166a70 100644
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -876,7 +876,7 @@ extern struct daemon {
char *packet; /* packet buffer */
int packet_buff_sz; /* size of above */
char *namebuff; /* MAXDNAME size buffer */
- unsigned int local_answer, queries_forwarded;
+ unsigned int local_answer, queries_forwarded, auth_answer;
struct frec *frec_list;
struct serverfd *sfds;
struct irec *interfaces;
@@ -993,6 +993,7 @@ int private_net(struct in_addr addr, int ban_localhost);
/* auth.c */
#ifdef HAVE_AUTH
size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t now, union mysockaddr *peer_addr);
+int in_zone(struct auth_zone *zone, char *name, char **cut);
#endif
/* util.c */
diff --git a/src/forward.c b/src/forward.c
index adc4a0f..26a7863 100644
--- a/src/forward.c
+++ b/src/forward.c
@@ -848,6 +848,9 @@ void receive_query(struct listener *listen, time_t now)
if (extract_request(header, (size_t)n, daemon->namebuff, &type))
{
char types[20];
+#ifdef HAVE_AUTH
+ struct auth_zone *zone;
+#endif
querystr(auth_dns ? "auth" : "query", types, type);
@@ -859,15 +862,28 @@ void receive_query(struct listener *listen, time_t now)
log_query(F_QUERY | F_IPV6 | F_FORWARD, daemon->namebuff,
(struct all_addr *)&source_addr.in6.sin6_addr, types);
#endif
- }
#ifdef HAVE_AUTH
+ /* find queries for zones we're authoritative for, and answer them directly */
+ for (zone = daemon->auth_zones; zone; zone = zone->next)
+ if (in_zone(zone, daemon->namebuff, NULL))
+ {
+ auth_dns = 1;
+ break;
+ }
+#endif
+ }
+
+#ifdef HAVE_AUTH
if (auth_dns)
{
m = answer_auth(header, ((char *) header) + PACKETSZ, (size_t)n, now, &source_addr);
if (m >= 1)
- send_from(listen->fd, option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND),
- (char *)header, m, &source_addr, &dst_addr, if_index);
+ {
+ send_from(listen->fd, option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND),
+ (char *)header, m, &source_addr, &dst_addr, if_index);
+ daemon->auth_answer++;
+ }
}
else
#endif
@@ -939,7 +955,9 @@ unsigned char *tcp_request(int confd, time_t now,
if ((gotname = extract_request(header, (unsigned int)size, daemon->namebuff, &qtype)))
{
char types[20];
-
+#ifdef HAVE_AUTH
+ struct auth_zone *zone;
+#endif
querystr(auth_dns ? "auth" : "query", types, qtype);
if (peer_addr.sa.sa_family == AF_INET)
@@ -950,6 +968,16 @@ unsigned char *tcp_request(int confd, time_t now,
log_query(F_QUERY | F_IPV6 | F_FORWARD, daemon->namebuff,
(struct all_addr *)&peer_addr.in6.sin6_addr, types);
#endif
+
+#ifdef HAVE_AUTH
+ /* find queries for zones we're authoritative for, and answer them directly */
+ for (zone = daemon->auth_zones; zone; zone = zone->next)
+ if (in_zone(zone, daemon->namebuff, NULL))
+ {
+ auth_dns = 1;
+ break;
+ }
+#endif
}
if (local_addr->sa.sa_family == AF_INET)