diff options
author | Simon Kelley <simon@thekelleys.org.uk> | 2013-10-18 22:00:39 +0100 |
---|---|---|
committer | Simon Kelley <simon@thekelleys.org.uk> | 2013-10-18 22:00:39 +0100 |
commit | b485ed97aa5726644d71d3a16ccdd058d6a8d73a (patch) | |
tree | d8a8993dc976dbbbe0817105597a9cc8d6f4c335 | |
parent | 53c4c5c85942d4733f4723531c4d325235448326 (diff) | |
download | dnsmasq-b485ed97aa5726644d71d3a16ccdd058d6a8d73a.tar.gz |
Always answer queries for authoritative zones locally, never forward.
-rw-r--r-- | src/auth.c | 2 | ||||
-rw-r--r-- | src/cache.c | 3 | ||||
-rw-r--r-- | src/dnsmasq.h | 3 | ||||
-rw-r--r-- | src/forward.c | 36 |
4 files changed, 38 insertions, 6 deletions
@@ -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) |