diff options
author | Simon Kelley <simon@thekelleys.org.uk> | 2014-04-29 12:30:18 +0100 |
---|---|---|
committer | Simon Kelley <simon@thekelleys.org.uk> | 2014-04-29 12:30:18 +0100 |
commit | 1fc02680afbc5f263321cfa2c0101820246d79cb (patch) | |
tree | 4e89f0158d74e25fe3c277692e6bf7bfd7bdd27c | |
parent | 4872aa747b24238c0859166eaae0ae3d89364244 (diff) | |
download | dnsmasq-1fc02680afbc5f263321cfa2c0101820246d79cb.tar.gz |
Do SERVFAIL, therefore continue when searching for DS in TCP path too.
-rw-r--r-- | src/forward.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/src/forward.c b/src/forward.c index 941f80d..81ae3ee 100644 --- a/src/forward.c +++ b/src/forward.c @@ -1453,8 +1453,13 @@ static int tcp_check_for_unsigned_zone(time_t now, struct dns_header *header, s newhash = hash_questions(header, (unsigned int)m, name); if (newhash && memcmp(hash, newhash, HASH_SIZE) == 0) { - /* Note this trashes all three name workspaces */ - status = tcp_key_recurse(now, STAT_NEED_DS_NEG, header, m, class, name, keyname, server, keycount); + /* In this case only, a SERVFAIL reply allows us to continue up the tree, looking for a + suitable NSEC reply to DS queries. */ + if (RCODE(header) == SERVFAIL) + status = STAT_INSECURE; + else + /* Note this trashes all three name workspaces */ + status = tcp_key_recurse(now, STAT_NEED_DS_NEG, header, m, class, name, keyname, server, keycount); /* We've found a DS which proves the bit of the DNS where the original query is, is unsigned, so the answer is OK, @@ -1830,6 +1835,10 @@ unsigned char *tcp_request(int confd, time_t now, } *length = htons(size); + + /* get query name again for logging - may have been overwritten */ + if (!(gotname = extract_request(header, (unsigned int)size, daemon->namebuff, &qtype))) + strcpy(daemon->namebuff, "query"); if (!read_write(last_server->tcpfd, packet, size + sizeof(u16), 0) || !read_write(last_server->tcpfd, &c1, 1, 1) || @@ -1843,8 +1852,6 @@ unsigned char *tcp_request(int confd, time_t now, m = (c1 << 8) | c2; - if (!gotname) - strcpy(daemon->namebuff, "query"); if (last_server->addr.sa.sa_family == AF_INET) log_query(F_SERVER | F_IPV4 | F_FORWARD, daemon->namebuff, (struct all_addr *)&last_server->addr.in.sin_addr, NULL); |