Compare commits

...
15 Commits
Author SHA1 Message Date
Simon Kelley d05dd58de1 Fix wrong reply to simple name when --domain-needed set and no servers configured.
Also return REFUSED and not SERVFAIL when out of memory.

Thanks to Allain Legacy for problem report.
2016-01-19 21:23:30 +00:00
Simon Kelley f7443d76f7 Fix problems in last commit when DNSSEC not enabled. 2016-01-19 20:29:57 +00:00
Simon Kelley f344dbc622 Complete DNSSEC server-selection code and set conntrack on DNSSEC queries. 2016-01-18 18:11:54 +00:00
Simon Kelley f4d0c660ca Fix sporadic crash in find_mac() - hwlen must be zero for empty entries. 2016-01-18 12:51:08 +00:00
Simon Kelley 1801a29226 Fix botch in forward.c flags code.
Thanks to Matthias Anfree for spotting this.
2016-01-17 21:53:57 +00:00
Simon Kelley 92be34a407 Complete work to allow DNSSEC validation with private DNS servers. 2016-01-16 18:39:54 +00:00
Simon Kelley bb58f63ce5 arp.c tidy up. 2016-01-14 19:23:10 +00:00
Simon Kelley 367341f745 Disable DNSSEC for server=/domain/.. servers unless trust-anchor provided. 2016-01-12 15:58:23 +00:00
André Glüpker eddf365284 Fix bad cache-size calculation when hosts-file read fails. 2016-01-12 12:54:17 +00:00
Simon Kelley a63b8b89e6 DNSSEC: Handle non-root trust anchors, and check we have a root trust anchor. 2016-01-12 11:28:58 +00:00
Simon Kelley 5757371d43 Inhibit DNSSEC validation when forwarding to private servers for a domain.
server=/example.com/<ip-of-server>

The rationale is that the chain-of-trust will not be complete to
private servers. If it was, it would not be necessary to access the
server direct.
2016-01-11 22:50:00 +00:00
Simon Kelley b633de9413 Fix FTBFS when scripts excluded at compilation time. 2016-01-06 22:51:17 +00:00
Simon Kelley c49778df4a Update copyright notices. Happy new year! 2016-01-06 18:52:33 +00:00
Simon Kelley 53a9173fc0 Handle building with script support enabled and DHCP disabled. 2016-01-06 17:59:13 +00:00
Simon Kelley d917275e48 Fix botch in new arp-cache linked-list code resulting in 100% CPU spin. 2016-01-04 17:17:41 +00:00
44 changed files with 330 additions and 113 deletions

No files matched your search

+13
View File
@@ -18,6 +18,19 @@ version 2.76
that the same name is empty. Thanks to Edwin Török for that the same name is empty. Thanks to Edwin Török for
the patch. the patch.
Fix failure to correctly calculate cache-size when
reading a hosts-file fails. Thanks to André Glüpker
for the patch.
Fix wrong answer to simple name query when --domain-needed
set, but no upstream servers configured. Dnsmasq returned
REFUSED, in this case, when it should be the same as when
upstream servers are configured - NOERROR. Thanks to
Allain Legacy for spotting the problem.
Return REFUSED when running out of forwarding table slots,
not SERVFAIL.
version 2.75 version 2.75
Fix reversion on 2.74 which caused 100% CPU use when a Fix reversion on 2.74 which caused 100% CPU use when a
+1 -1
View File
@@ -1,4 +1,4 @@
# dnsmasq is Copyright (c) 2000-2015 Simon Kelley # dnsmasq is Copyright (c) 2000-2016 Simon Kelley
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
dnsmasq is Copyright (c) 2000-2015 Simon Kelley dnsmasq is Copyright (c) 2000-2016 Simon Kelley
It was downloaded from: http://www.thekelleys.org.uk/dnsmasq/ It was downloaded from: http://www.thekelleys.org.uk/dnsmasq/
+4 -1
View File
@@ -405,7 +405,10 @@ xxx.internal.thekelleys.org.uk at 192.168.1.1 then giving the flag
.B -S /internal.thekelleys.org.uk/192.168.1.1 .B -S /internal.thekelleys.org.uk/192.168.1.1
will send all queries for will send all queries for
internal machines to that nameserver, everything else will go to the internal machines to that nameserver, everything else will go to the
servers in /etc/resolv.conf. An empty domain specification, servers in /etc/resolv.conf. DNSSEC validation is turned off for such
private nameservers, UNLESS a
.B --trust-anchor
is specified for the domain in question. An empty domain specification,
.B // .B //
has the special meaning of "unqualified names only" ie names without any has the special meaning of "unqualified names only" ie names without any
dots in them. A non-standard port may be specified as dots in them. A non-standard port may be specified as
+19 -14
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2015 Simon Kelley /* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@@ -110,7 +110,7 @@ static int filter_mac(int family, char *addrp, char *mac, size_t maclen, void *p
/* If in lazy mode, we cache absence of ARP entries. */ /* If in lazy mode, we cache absence of ARP entries. */
int find_mac(union mysockaddr *addr, unsigned char *mac, int lazy, time_t now) int find_mac(union mysockaddr *addr, unsigned char *mac, int lazy, time_t now)
{ {
struct arp_record *arp, **up; struct arp_record *arp, *tmp, **up;
int updated = 0; int updated = 0;
again: again:
@@ -132,7 +132,7 @@ int find_mac(union mysockaddr *addr, unsigned char *mac, int lazy, time_t now)
} }
#endif #endif
/* Only accept poitive entries unless in lazy mode. */ /* Only accept positive entries unless in lazy mode. */
if (arp->status != ARP_EMPTY || lazy || updated) if (arp->status != ARP_EMPTY || lazy || updated)
{ {
if (mac && arp->hwlen != 0) if (mac && arp->hwlen != 0)
@@ -148,23 +148,27 @@ int find_mac(union mysockaddr *addr, unsigned char *mac, int lazy, time_t now)
last = now; last = now;
/* Mark all non-negative entries */ /* Mark all non-negative entries */
for (arp = arps, up = &arps; arp; arp = arp->next) for (arp = arps; arp; arp = arp->next)
if (arp->status != ARP_EMPTY) if (arp->status != ARP_EMPTY)
arp->status = ARP_MARK; arp->status = ARP_MARK;
iface_enumerate(AF_UNSPEC, NULL, filter_mac); iface_enumerate(AF_UNSPEC, NULL, filter_mac);
/* Remove all unconfirmed entries to old list. */ /* Remove all unconfirmed entries to old list. */
for (arp = arps, up = &arps; arp; arp = arp->next) for (arp = arps, up = &arps; arp; arp = tmp)
if (arp->status == ARP_MARK) {
{ tmp = arp->next;
*up = arp->next;
arp->next = old;
old = arp;
}
else
up = &arp->next;
if (arp->status == ARP_MARK)
{
*up = arp->next;
arp->next = old;
old = arp;
}
else
up = &arp->next;
}
goto again; goto again;
} }
@@ -184,7 +188,8 @@ int find_mac(union mysockaddr *addr, unsigned char *mac, int lazy, time_t now)
arps = arp; arps = arp;
arp->status = ARP_EMPTY; arp->status = ARP_EMPTY;
arp->family = addr->sa.sa_family; arp->family = addr->sa.sa_family;
arp->hwlen = 0;
if (addr->sa.sa_family == AF_INET) if (addr->sa.sa_family == AF_INET)
arp->addr.addr.addr4.s_addr = addr->in.sin_addr.s_addr; arp->addr.addr.addr4.s_addr = addr->in.sin_addr.s_addr;
#ifdef HAVE_IPV6 #ifdef HAVE_IPV6
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2015 Simon Kelley /* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2015 Simon Kelley /* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2015 Simon Kelley /* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+2 -2
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2015 Simon Kelley /* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@@ -919,7 +919,7 @@ int read_hostsfile(char *filename, unsigned int index, int cache_size, struct cr
if (!f) if (!f)
{ {
my_syslog(LOG_ERR, _("failed to load names from %s: %s"), filename, strerror(errno)); my_syslog(LOG_ERR, _("failed to load names from %s: %s"), filename, strerror(errno));
return 0; return cache_size;
} }
eatspace(f); eatspace(f);
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2015 Simon Kelley /* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2015 Simon Kelley /* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2015 Simon Kelley /* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2015 Simon Kelley /* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2015 Simon Kelley /* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2015 Simon Kelley /* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2015 Simon Kelley /* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2015 Simon Kelley /* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2015 Simon Kelley /* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+19 -5
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2015 Simon Kelley /* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@@ -169,8 +169,16 @@ int main (int argc, char **argv)
if (option_bool(OPT_DNSSEC_VALID)) if (option_bool(OPT_DNSSEC_VALID))
{ {
#ifdef HAVE_DNSSEC #ifdef HAVE_DNSSEC
if (!daemon->ds) struct ds_config *ds;
die(_("no trust anchors provided for DNSSEC"), NULL, EC_BADCONF);
/* Must have at least a root trust anchor, or the DNSSEC code
can loop forever. */
for (ds = daemon->ds; ds; ds = ds->next)
if (ds->name[0] == 0)
break;
if (!ds)
die(_("no root trust anchor provided for DNSSEC"), NULL, EC_BADCONF);
if (daemon->cachesize < CACHESIZ) if (daemon->cachesize < CACHESIZ)
die(_("cannot reduce cache size from default when DNSSEC enabled"), NULL, EC_BADCONF); die(_("cannot reduce cache size from default when DNSSEC enabled"), NULL, EC_BADCONF);
@@ -919,7 +927,10 @@ int main (int argc, char **argv)
poll_listen(piperead, POLLIN); poll_listen(piperead, POLLIN);
#ifdef HAVE_SCRIPT #ifdef HAVE_SCRIPT
# ifdef HAVE_DHCP
while (helper_buf_empty() && do_script_run(now)); while (helper_buf_empty() && do_script_run(now));
# endif
while (helper_buf_empty() && do_arp_script_run()); while (helper_buf_empty() && do_arp_script_run());
# ifdef HAVE_TFTP # ifdef HAVE_TFTP
@@ -930,8 +941,11 @@ int main (int argc, char **argv)
poll_listen(daemon->helperfd, POLLOUT); poll_listen(daemon->helperfd, POLLOUT);
#else #else
/* need this for other side-effects */ /* need this for other side-effects */
# ifdef HAVE_DHCP
while (do_script_run(now)); while (do_script_run(now));
while (do_arp_script_run(now)); # endif
while (do_arp_script_run());
# ifdef HAVE_TFTP # ifdef HAVE_TFTP
while (do_tftp_script_run()); while (do_tftp_script_run());
@@ -1312,7 +1326,7 @@ static void async_event(int pipe, time_t now)
if (daemon->tcp_pids[i] != 0) if (daemon->tcp_pids[i] != 0)
kill(daemon->tcp_pids[i], SIGALRM); kill(daemon->tcp_pids[i], SIGALRM);
#if defined(HAVE_SCRIPT) #if defined(HAVE_SCRIPT) && defined(HAVE_DHCP)
/* handle pending lease transitions */ /* handle pending lease transitions */
if (daemon->helperfd != -1) if (daemon->helperfd != -1)
{ {
+3 -2
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2015 Simon Kelley /* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@@ -14,7 +14,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#define COPYRIGHT "Copyright (c) 2000-2015 Simon Kelley" #define COPYRIGHT "Copyright (c) 2000-2016 Simon Kelley"
#ifndef NO_LARGEFILE #ifndef NO_LARGEFILE
/* Ensure we can use files >2GB (log files may grow this big) */ /* Ensure we can use files >2GB (log files may grow this big) */
@@ -477,6 +477,7 @@ union mysockaddr {
#define SERV_NO_REBIND 2048 /* inhibit dns-rebind protection */ #define SERV_NO_REBIND 2048 /* inhibit dns-rebind protection */
#define SERV_FROM_FILE 4096 /* read from --servers-file */ #define SERV_FROM_FILE 4096 /* read from --servers-file */
#define SERV_LOOP 8192 /* server causes forwarding loop */ #define SERV_LOOP 8192 /* server causes forwarding loop */
#define SERV_DO_DNSSEC 16384 /* Validate DNSSEC when using this server */
struct serverfd { struct serverfd {
int fd; int fd;
+20 -3
View File
@@ -1,5 +1,5 @@
/* dnssec.c is Copyright (c) 2012 Giovanni Bajo <rasky@develer.com> /* dnssec.c is Copyright (c) 2012 Giovanni Bajo <rasky@develer.com>
and Copyright (c) 2012-2015 Simon Kelley and Copyright (c) 2012-2016 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@@ -1873,10 +1873,27 @@ static int prove_non_existence(struct dns_header *header, size_t plen, char *key
*/ */
static int zone_status(char *name, int class, char *keyname, time_t now) static int zone_status(char *name, int class, char *keyname, time_t now)
{ {
int name_start = strlen(name); int name_start = strlen(name); /* for when TA is root */
struct crec *crecp; struct crec *crecp;
char *p; char *p;
/* First, work towards the root, looking for a trust anchor.
This can either be one configured, or one previously cached.
We can assume, if we don't find one first, that there is
a trust anchor at the root. */
for (p = name; p; p = strchr(p, '.'))
{
if (*p == '.')
p++;
if (cache_find_by_name(NULL, p, now, F_DS))
{
name_start = p - name;
break;
}
}
/* Now work away from the trust anchor */
while (1) while (1)
{ {
strcpy(keyname, &name[name_start]); strcpy(keyname, &name[name_start]);
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2015 Simon Kelley /* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2015 Simon Kelley /* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+174 -43
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2015 Simon Kelley /* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@@ -106,8 +106,8 @@ int send_from(int fd, int nowild, char *packet, size_t len,
return 1; return 1;
} }
static unsigned int search_servers(time_t now, struct all_addr **addrpp, static unsigned int search_servers(time_t now, struct all_addr **addrpp, unsigned int qtype,
unsigned int qtype, char *qdomain, int *type, char **domain, int *norebind) char *qdomain, int *type, char **domain, int *norebind)
{ {
/* If the query ends in the domain in one of our servers, set /* If the query ends in the domain in one of our servers, set
@@ -151,7 +151,7 @@ static unsigned int search_servers(time_t now, struct all_addr **addrpp,
hostname_isequal(matchstart, serv->domain) && hostname_isequal(matchstart, serv->domain) &&
(domainlen == 0 || namelen == domainlen || *(matchstart-1) == '.' )) (domainlen == 0 || namelen == domainlen || *(matchstart-1) == '.' ))
{ {
if (serv->flags & SERV_NO_REBIND) if ((serv->flags & SERV_NO_REBIND) && norebind)
*norebind = 1; *norebind = 1;
else else
{ {
@@ -175,7 +175,7 @@ static unsigned int search_servers(time_t now, struct all_addr **addrpp,
if (domainlen >= matchlen) if (domainlen >= matchlen)
{ {
*type = serv->flags & (SERV_HAS_DOMAIN | SERV_USE_RESOLV | SERV_NO_REBIND); *type = serv->flags & (SERV_HAS_DOMAIN | SERV_USE_RESOLV | SERV_NO_REBIND | SERV_DO_DNSSEC);
*domain = serv->domain; *domain = serv->domain;
matchlen = domainlen; matchlen = domainlen;
if (serv->flags & SERV_NO_ADDR) if (serv->flags & SERV_NO_ADDR)
@@ -233,12 +233,13 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
struct frec *forward, int ad_reqd, int do_bit) struct frec *forward, int ad_reqd, int do_bit)
{ {
char *domain = NULL; char *domain = NULL;
int type = 0, norebind = 0; int type = SERV_DO_DNSSEC, norebind = 0;
struct all_addr *addrp = NULL; struct all_addr *addrp = NULL;
unsigned int flags = 0; unsigned int flags = 0;
struct server *start = NULL; struct server *start = NULL;
#ifdef HAVE_DNSSEC #ifdef HAVE_DNSSEC
void *hash = hash_questions(header, plen, daemon->namebuff); void *hash = hash_questions(header, plen, daemon->namebuff);
int do_dnssec = 0;
#else #else
unsigned int crc = questions_crc(header, plen, daemon->namebuff); unsigned int crc = questions_crc(header, plen, daemon->namebuff);
void *hash = &crc; void *hash = &crc;
@@ -248,9 +249,7 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
(void)do_bit; (void)do_bit;
/* may be no servers available. */ /* may be no servers available. */
if (!daemon->servers) if (forward || (hash && (forward = lookup_frec_by_sender(ntohs(header->id), udpaddr, hash))))
forward = NULL;
else if (forward || (hash && (forward = lookup_frec_by_sender(ntohs(header->id), udpaddr, hash))))
{ {
/* If we didn't get an answer advertising a maximal packet in EDNS, /* If we didn't get an answer advertising a maximal packet in EDNS,
fall back to 1280, which should work everywhere on IPv6. fall back to 1280, which should work everywhere on IPv6.
@@ -315,6 +314,10 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
daemon->last_server = NULL; daemon->last_server = NULL;
} }
type = forward->sentto->flags & SERV_TYPE; type = forward->sentto->flags & SERV_TYPE;
#ifdef HAVE_DNSSEC
do_dnssec = forward->sentto->flags & SERV_DO_DNSSEC;
#endif
if (!(start = forward->sentto->next)) if (!(start = forward->sentto->next))
start = daemon->servers; /* at end of list, recycle */ start = daemon->servers; /* at end of list, recycle */
header->id = htons(forward->new_id); header->id = htons(forward->new_id);
@@ -324,9 +327,14 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
if (gotname) if (gotname)
flags = search_servers(now, &addrp, gotname, daemon->namebuff, &type, &domain, &norebind); flags = search_servers(now, &addrp, gotname, daemon->namebuff, &type, &domain, &norebind);
if (!flags && !(forward = get_new_frec(now, NULL, 0))) #ifdef HAVE_DNSSEC
/* table full - server failure. */ do_dnssec = type & SERV_DO_DNSSEC;
flags = F_NEG; #endif
type &= ~SERV_DO_DNSSEC;
if (daemon->servers && !flags)
forward = get_new_frec(now, NULL, 0);
/* table full - flags == 0, return REFUSED */
if (forward) if (forward)
{ {
@@ -406,7 +414,7 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
} }
#ifdef HAVE_DNSSEC #ifdef HAVE_DNSSEC
if (option_bool(OPT_DNSSEC_VALID)) if (option_bool(OPT_DNSSEC_VALID) && do_dnssec)
{ {
size_t new = add_do_bit(header, plen, ((unsigned char *) header) + PACKETSZ); size_t new = add_do_bit(header, plen, ((unsigned char *) header) + PACKETSZ);
@@ -634,7 +642,7 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
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 && ntohs(header->ancount) == 0 && if (!(header->hb4 & HB4_RA) && RCODE(header) == 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);
@@ -800,9 +808,9 @@ void reply_query(int fd, int family, time_t now)
{ {
header->hb3 &= ~(HB3_QR | HB3_AA | HB3_TC); header->hb3 &= ~(HB3_QR | HB3_AA | HB3_TC);
header->hb4 &= ~(HB4_RA | HB4_RCODE | HB4_CD | HB4_AD); header->hb4 &= ~(HB4_RA | HB4_RCODE | HB4_CD | HB4_AD);
if (forward->flags |= FREC_CHECKING_DISABLED) if (forward->flags & FREC_CHECKING_DISABLED)
header->hb4 |= HB4_CD; header->hb4 |= HB4_CD;
if (forward->flags |= FREC_AD_QUESTION) if (forward->flags & FREC_AD_QUESTION)
header->hb4 |= HB4_AD; header->hb4 |= HB4_AD;
if (forward->flags & FREC_DO_QUESTION) if (forward->flags & FREC_DO_QUESTION)
add_do_bit(header, nn, (unsigned char *)pheader + plen); add_do_bit(header, nn, (unsigned char *)pheader + plen);
@@ -858,7 +866,8 @@ void reply_query(int fd, int family, time_t now)
no_cache_dnssec = 1; no_cache_dnssec = 1;
#ifdef HAVE_DNSSEC #ifdef HAVE_DNSSEC
if (server && option_bool(OPT_DNSSEC_VALID) && !(forward->flags & FREC_CHECKING_DISABLED)) if (server && (server->flags & SERV_DO_DNSSEC) &&
option_bool(OPT_DNSSEC_VALID) && !(forward->flags & FREC_CHECKING_DISABLED))
{ {
int status = 0; int status = 0;
@@ -912,12 +921,48 @@ void reply_query(int fd, int family, time_t now)
status = STAT_ABANDONED; status = STAT_ABANDONED;
else else
{ {
int fd; int fd, type = SERV_DO_DNSSEC;
struct frec *next = new->next; struct frec *next = new->next;
char *domain;
*new = *forward; /* copy everything, then overwrite */ *new = *forward; /* copy everything, then overwrite */
new->next = next; new->next = next;
new->blocking_query = NULL; new->blocking_query = NULL;
/* Find server to forward to. This will normally be the
same as for the original query, but may be another if
servers for domains are involved. */
if (search_servers(now, NULL, F_QUERY, daemon->keyname, &type, &domain, NULL) == 0)
{
struct server *start = server, *new_server = NULL;
type &= ~SERV_DO_DNSSEC;
while (1)
{
if (type == (start->flags & SERV_TYPE) &&
(type != SERV_HAS_DOMAIN || hostname_isequal(domain, start->domain)) &&
!(start->flags & (SERV_LITERAL_ADDRESS | SERV_LOOP)))
{
new_server = start;
if (server == start)
{
new_server = NULL;
break;
}
}
if (!(start = start->next))
start = daemon->servers;
if (start == server)
break;
}
if (new_server)
server = new_server;
}
new->sentto = server; new->sentto = server;
new->rfd4 = NULL; new->rfd4 = NULL;
#ifdef HAVE_IPV6 #ifdef HAVE_IPV6
new->rfd6 = NULL; new->rfd6 = NULL;
@@ -971,6 +1016,15 @@ void reply_query(int fd, int family, time_t now)
if (fd != -1) if (fd != -1)
{ {
#ifdef HAVE_CONNTRACK
/* Copy connection mark of incoming query to outgoing connection. */
if (option_bool(OPT_CONNTRACK))
{
unsigned int mark;
if (get_incoming_mark(&orig->source, &orig->dest, 0, &mark))
setsockopt(fd, SOL_SOCKET, SO_MARK, &mark, sizeof(unsigned int));
}
#endif
while (retry_send(sendto(fd, (char *)header, nn, 0, while (retry_send(sendto(fd, (char *)header, nn, 0,
&server->addr.sa, &server->addr.sa,
sa_len(&server->addr)))); sa_len(&server->addr))));
@@ -1033,7 +1087,7 @@ void reply_query(int fd, int family, time_t now)
else else
header->hb4 &= ~HB4_CD; header->hb4 &= ~HB4_CD;
if ((nn = process_reply(header, now, server, (size_t)n, check_rebind, no_cache_dnssec, cache_secure, bogusanswer, if ((nn = process_reply(header, now, forward->sentto, (size_t)n, check_rebind, no_cache_dnssec, cache_secure, bogusanswer,
forward->flags & FREC_AD_QUESTION, forward->flags & FREC_DO_QUESTION, forward->flags & FREC_AD_QUESTION, forward->flags & FREC_DO_QUESTION,
forward->flags & FREC_ADDED_PHEADER, forward->flags & FREC_HAS_SUBNET, &forward->source))) forward->flags & FREC_ADDED_PHEADER, forward->flags & FREC_HAS_SUBNET, &forward->source)))
{ {
@@ -1394,20 +1448,24 @@ void receive_query(struct listener *listen, time_t now)
} }
#ifdef HAVE_DNSSEC #ifdef HAVE_DNSSEC
/* Recurse up the key heirarchy */
static int tcp_key_recurse(time_t now, int status, struct dns_header *header, size_t n, static int tcp_key_recurse(time_t now, int status, struct dns_header *header, size_t n,
int class, char *name, char *keyname, struct server *server, int *keycount) int class, char *name, char *keyname, struct server *server,
int have_mark, unsigned int mark, int *keycount)
{ {
/* Recurse up the key heirarchy */
int new_status; int new_status;
unsigned char *packet = NULL; unsigned char *packet = NULL;
size_t m;
unsigned char *payload = NULL; unsigned char *payload = NULL;
struct dns_header *new_header = NULL; struct dns_header *new_header = NULL;
u16 *length = NULL; u16 *length = NULL;
unsigned char c1, c2;
while (1) while (1)
{ {
int type = SERV_DO_DNSSEC;
char *domain;
size_t m;
unsigned char c1, c2;
/* limit the amount of work we do, to avoid cycling forever on loops in the DNS */ /* limit the amount of work we do, to avoid cycling forever on loops in the DNS */
if (--(*keycount) == 0) if (--(*keycount) == 0)
new_status = STAT_ABANDONED; new_status = STAT_ABANDONED;
@@ -1441,6 +1499,67 @@ static int tcp_key_recurse(time_t now, int status, struct dns_header *header, si
new_status == STAT_NEED_KEY ? T_DNSKEY : T_DS, &server->addr, server->edns_pktsz); new_status == STAT_NEED_KEY ? T_DNSKEY : T_DS, &server->addr, server->edns_pktsz);
*length = htons(m); *length = htons(m);
/* Find server to forward to. This will normally be the
same as for the original query, but may be another if
servers for domains are involved. */
if (search_servers(now, NULL, F_QUERY, keyname, &type, &domain, NULL) == 0)
{
struct server *start = server, *new_server = NULL;
type &= ~SERV_DO_DNSSEC;
while (1)
{
if (type == (start->flags & SERV_TYPE) &&
(type != SERV_HAS_DOMAIN || hostname_isequal(domain, start->domain)) &&
!(start->flags & (SERV_LITERAL_ADDRESS | SERV_LOOP)))
{
new_server = start;
if (server == start)
{
new_server = NULL;
break;
}
}
if (!(start = start->next))
start = daemon->servers;
if (start == server)
break;
}
if (new_server)
{
server = new_server;
/* may need to make new connection. */
if (server->tcpfd == -1)
{
if ((server->tcpfd = socket(server->addr.sa.sa_family, SOCK_STREAM, 0)) == -1)
{
new_status = STAT_ABANDONED;
break;
}
#ifdef HAVE_CONNTRACK
/* Copy connection mark of incoming query to outgoing connection. */
if (have_mark)
setsockopt(server->tcpfd, SOL_SOCKET, SO_MARK, &mark, sizeof(unsigned int));
#endif
if (!local_bind(server->tcpfd, &server->source_addr, server->interface, 1) ||
connect(server->tcpfd, &server->addr.sa, sa_len(&server->addr)) == -1)
{
close(server->tcpfd);
server->tcpfd = -1;
new_status = STAT_ABANDONED;
break;
}
}
}
}
if (!read_write(server->tcpfd, packet, m + sizeof(u16), 0) || if (!read_write(server->tcpfd, packet, m + sizeof(u16), 0) ||
!read_write(server->tcpfd, &c1, 1, 1) || !read_write(server->tcpfd, &c1, 1, 1) ||
@@ -1453,7 +1572,7 @@ static int tcp_key_recurse(time_t now, int status, struct dns_header *header, si
m = (c1 << 8) | c2; m = (c1 << 8) | c2;
new_status = tcp_key_recurse(now, new_status, new_header, m, class, name, keyname, server, keycount); new_status = tcp_key_recurse(now, new_status, new_header, m, class, name, keyname, server, have_mark, mark, keycount);
if (new_status != STAT_OK) if (new_status != STAT_OK)
break; break;
@@ -1497,10 +1616,31 @@ unsigned char *tcp_request(int confd, time_t now,
socklen_t peer_len = sizeof(union mysockaddr); socklen_t peer_len = sizeof(union mysockaddr);
int query_count = 0; int query_count = 0;
unsigned char *pheader; unsigned char *pheader;
unsigned int mark = 0;
int have_mark = 0;
(void)mark;
(void)have_mark;
if (getpeername(confd, (struct sockaddr *)&peer_addr, &peer_len) == -1) if (getpeername(confd, (struct sockaddr *)&peer_addr, &peer_len) == -1)
return packet; return packet;
#ifdef HAVE_CONNTRACK
/* Get connection mark of incoming query to set on outgoing connections. */
if (option_bool(OPT_CONNTRACK))
{
struct all_addr local;
#ifdef HAVE_IPV6
if (local_addr->sa.sa_family == AF_INET6)
local.addr.addr6 = local_addr->in6.sin6_addr;
else
#endif
local.addr.addr4 = local_addr->in.sin_addr;
have_mark = get_incoming_mark(&peer_addr, &local, 1, &mark);
}
#endif
/* We can be configured to only accept queries from at-most-one-hop-away addresses. */ /* We can be configured to only accept queries from at-most-one-hop-away addresses. */
if (option_bool(OPT_LOCAL_SERVICE)) if (option_bool(OPT_LOCAL_SERVICE))
{ {
@@ -1626,7 +1766,7 @@ unsigned char *tcp_request(int confd, time_t now,
{ {
unsigned int flags = 0; unsigned int flags = 0;
struct all_addr *addrp = NULL; struct all_addr *addrp = NULL;
int type = 0; int type = SERV_DO_DNSSEC;
char *domain = NULL; char *domain = NULL;
size_t new_size = add_edns0_config(header, size, ((unsigned char *) header) + 65536, &peer_addr, now, &check_subnet); size_t new_size = add_edns0_config(header, size, ((unsigned char *) header) + 65536, &peer_addr, now, &check_subnet);
@@ -1639,6 +1779,8 @@ unsigned char *tcp_request(int confd, time_t now,
if (gotname) if (gotname)
flags = search_servers(now, &addrp, gotname, daemon->namebuff, &type, &domain, &norebind); flags = search_servers(now, &addrp, gotname, daemon->namebuff, &type, &domain, &norebind);
type &= ~SERV_DO_DNSSEC;
if (type != 0 || option_bool(OPT_ORDER) || !daemon->last_server) if (type != 0 || option_bool(OPT_ORDER) || !daemon->last_server)
last_server = daemon->servers; last_server = daemon->servers;
else else
@@ -1685,20 +1827,8 @@ unsigned char *tcp_request(int confd, time_t now,
#ifdef HAVE_CONNTRACK #ifdef HAVE_CONNTRACK
/* Copy connection mark of incoming query to outgoing connection. */ /* Copy connection mark of incoming query to outgoing connection. */
if (option_bool(OPT_CONNTRACK)) if (have_mark)
{ setsockopt(last_server->tcpfd, SOL_SOCKET, SO_MARK, &mark, sizeof(unsigned int));
unsigned int mark;
struct all_addr local;
#ifdef HAVE_IPV6
if (local_addr->sa.sa_family == AF_INET6)
local.addr.addr6 = local_addr->in6.sin6_addr;
else
#endif
local.addr.addr4 = local_addr->in.sin_addr;
if (get_incoming_mark(&peer_addr, &local, 1, &mark))
setsockopt(last_server->tcpfd, SOL_SOCKET, SO_MARK, &mark, sizeof(unsigned int));
}
#endif #endif
if ((!local_bind(last_server->tcpfd, &last_server->source_addr, last_server->interface, 1) || if ((!local_bind(last_server->tcpfd, &last_server->source_addr, last_server->interface, 1) ||
@@ -1710,7 +1840,7 @@ unsigned char *tcp_request(int confd, time_t now,
} }
#ifdef HAVE_DNSSEC #ifdef HAVE_DNSSEC
if (option_bool(OPT_DNSSEC_VALID)) if (option_bool(OPT_DNSSEC_VALID) && (last_server->flags & SERV_DO_DNSSEC))
{ {
new_size = add_do_bit(header, size, ((unsigned char *) header) + 65536); new_size = add_do_bit(header, size, ((unsigned char *) header) + 65536);
@@ -1756,10 +1886,11 @@ unsigned char *tcp_request(int confd, time_t now,
#endif #endif
#ifdef HAVE_DNSSEC #ifdef HAVE_DNSSEC
if (option_bool(OPT_DNSSEC_VALID) && !checking_disabled) if (option_bool(OPT_DNSSEC_VALID) && !checking_disabled && (last_server->flags & SERV_DO_DNSSEC))
{ {
int keycount = DNSSEC_WORK; /* Limit to number of DNSSEC questions, to catch loops and avoid filling cache. */ int keycount = DNSSEC_WORK; /* Limit to number of DNSSEC questions, to catch loops and avoid filling cache. */
int status = tcp_key_recurse(now, STAT_OK, header, m, 0, daemon->namebuff, daemon->keyname, last_server, &keycount); int status = tcp_key_recurse(now, STAT_OK, header, m, 0, daemon->namebuff, daemon->keyname,
last_server, have_mark, mark, &keycount);
char *result, *domain = "result"; char *result, *domain = "result";
if (status == STAT_ABANDONED) if (status == STAT_ABANDONED)
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2015 Simon Kelley /* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2015 Simon Kelley /* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2015 Simon Kelley /* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2015 Simon Kelley /* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2015 Simon Kelley /* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2015 Simon Kelley /* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2015 Simon Kelley /* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+40 -5
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2015 Simon Kelley /* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@@ -1430,12 +1430,43 @@ void check_servers(void)
if (!option_bool(OPT_NOWILD)) if (!option_bool(OPT_NOWILD))
enumerate_interfaces(0); enumerate_interfaces(0);
#ifdef HAVE_DNSSEC
/* Disable DNSSEC validation when using server=/domain/.... servers
unless there's a configured trust anchor. */
for (serv = daemon->servers; serv; serv = serv->next)
serv->flags |= SERV_DO_DNSSEC;
#endif
for (serv = daemon->servers; serv; serv = serv->next) for (serv = daemon->servers; serv; serv = serv->next)
{ {
if (!(serv->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR | SERV_USE_RESOLV | SERV_NO_REBIND))) if (!(serv->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR | SERV_USE_RESOLV | SERV_NO_REBIND)))
{ {
port = prettyprint_addr(&serv->addr, daemon->namebuff); #ifdef HAVE_DNSSEC
if (option_bool(OPT_DNSSEC_VALID))
{
if (serv->flags & SERV_HAS_DOMAIN)
{
struct ds_config *ds;
char *domain = serv->domain;
/* .example.com is valid */
while (*domain == '.')
domain++;
for (ds = daemon->ds; ds; ds = ds->next)
if (ds->name[0] != 0 && hostname_isequal(domain, ds->name))
break;
if (!ds)
serv->flags &= ~SERV_DO_DNSSEC;
}
else if (serv->flags & SERV_FOR_NODOTS)
serv->flags &= ~SERV_DO_DNSSEC;
}
#endif
port = prettyprint_addr(&serv->addr, daemon->namebuff);
/* 0.0.0.0 is nothing, the stack treats it like 127.0.0.1 */ /* 0.0.0.0 is nothing, the stack treats it like 127.0.0.1 */
if (serv->addr.sa.sa_family == AF_INET && if (serv->addr.sa.sa_family == AF_INET &&
serv->addr.in.sin_addr.s_addr == 0) serv->addr.in.sin_addr.s_addr == 0)
@@ -1471,7 +1502,11 @@ void check_servers(void)
{ {
if (serv->flags & (SERV_HAS_DOMAIN | SERV_FOR_NODOTS | SERV_USE_RESOLV)) if (serv->flags & (SERV_HAS_DOMAIN | SERV_FOR_NODOTS | SERV_USE_RESOLV))
{ {
char *s1, *s2; char *s1, *s2, *s3 = "";
#ifdef HAVE_DNSSEC
if (option_bool(OPT_DNSSEC_VALID) && !(serv->flags & SERV_DO_DNSSEC))
s3 = _("(no DNSSEC)");
#endif
if (!(serv->flags & SERV_HAS_DOMAIN)) if (!(serv->flags & SERV_HAS_DOMAIN))
s1 = _("unqualified"), s2 = _("names"); s1 = _("unqualified"), s2 = _("names");
else if (strlen(serv->domain) == 0) else if (strlen(serv->domain) == 0)
@@ -1484,7 +1519,7 @@ void check_servers(void)
else if (serv->flags & SERV_USE_RESOLV) else if (serv->flags & SERV_USE_RESOLV)
my_syslog(LOG_INFO, _("using standard nameservers for %s %s"), s1, s2); my_syslog(LOG_INFO, _("using standard nameservers for %s %s"), s1, s2);
else else
my_syslog(LOG_INFO, _("using nameserver %s#%d for %s %s"), daemon->namebuff, port, s1, s2); my_syslog(LOG_INFO, _("using nameserver %s#%d for %s %s %s"), daemon->namebuff, port, s1, s2, s3);
} }
#ifdef HAVE_LOOP #ifdef HAVE_LOOP
else if (serv->flags & SERV_LOOP) else if (serv->flags & SERV_LOOP)
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2015 Simon Kelley /* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2015 Simon Kelley /* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2015 Simon Kelley /* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2015 Simon Kelley /* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2015 Simon Kelley /* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+2 -4
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2015 Simon Kelley /* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@@ -896,9 +896,7 @@ size_t setup_reply(struct dns_header *header, size_t qlen,
header->nscount = htons(0); header->nscount = htons(0);
header->arcount = htons(0); header->arcount = htons(0);
header->ancount = htons(0); /* no answers unless changed below */ header->ancount = htons(0); /* no answers unless changed below */
if (flags == F_NEG) if (flags == F_NOERR)
SET_RCODE(header, SERVFAIL); /* couldn't get memory */
else if (flags == F_NOERR)
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);
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2015 Simon Kelley /* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2015 Simon Kelley /* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2015 Simon Kelley /* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2015 Simon Kelley /* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2015 Simon Kelley /* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2015 Simon Kelley /* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by