mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-22 18:19:42 +00:00
- qname minimization:
- make qname-minimization option tristate {strict,relaxed,disabled} - go straight for the record if we hit NXDOMAIN in relaxed mode - go straight for the record after 3 labels without new delegation or 7 labels total - use start of fetch (and not time of response) as 'now' time for querying cache for zonecut when following delegation.
This commit is contained in:
parent
0698158eb0
commit
dd7bb617be
@ -185,8 +185,7 @@ options {\n\
|
|||||||
provide-ixfr true;\n\
|
provide-ixfr true;\n\
|
||||||
query-source address *;\n\
|
query-source address *;\n\
|
||||||
query-source-v6 address *;\n\
|
query-source-v6 address *;\n\
|
||||||
qname-minimization no;\n\
|
qname-minimization relaxed;\n\
|
||||||
qname-minimization-strict no;\n\
|
|
||||||
recursion true;\n\
|
recursion true;\n\
|
||||||
request-expire true;\n\
|
request-expire true;\n\
|
||||||
request-ixfr true;\n\
|
request-ixfr true;\n\
|
||||||
|
@ -4642,12 +4642,18 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist,
|
|||||||
obj = NULL;
|
obj = NULL;
|
||||||
result = named_config_get(maps, "qname-minimization", &obj);
|
result = named_config_get(maps, "qname-minimization", &obj);
|
||||||
INSIST(result == ISC_R_SUCCESS);
|
INSIST(result == ISC_R_SUCCESS);
|
||||||
view->qminimization = cfg_obj_asboolean(obj);
|
const char * qminmode = cfg_obj_asstring(obj);
|
||||||
|
INSIST(qminmode != NULL);
|
||||||
obj = NULL;
|
if (!strcmp(qminmode, "strict")) {
|
||||||
result = named_config_get(maps, "qname-minimization-strict", &obj);
|
view->qminimization = ISC_TRUE;
|
||||||
INSIST(result == ISC_R_SUCCESS);
|
view->qmin_strict = ISC_TRUE;
|
||||||
view->qmin_strict = cfg_obj_asboolean(obj);
|
} else if (!strcmp(qminmode, "relaxed")) {
|
||||||
|
view->qminimization = ISC_TRUE;
|
||||||
|
view->qmin_strict = ISC_FALSE;
|
||||||
|
} else {
|
||||||
|
view->qminimization = ISC_FALSE;
|
||||||
|
view->qmin_strict = ISC_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
obj = NULL;
|
obj = NULL;
|
||||||
result = named_config_get(maps, "auth-nxdomain", &obj);
|
result = named_config_get(maps, "auth-nxdomain", &obj);
|
||||||
|
@ -35,7 +35,9 @@ def logquery(type, qname):
|
|||||||
# Respond to a DNS query.
|
# Respond to a DNS query.
|
||||||
# For good. it serves:
|
# For good. it serves:
|
||||||
# ns2.good. IN A 10.53.0.2
|
# ns2.good. IN A 10.53.0.2
|
||||||
# icky.icky.icky.ptang.zoop.boing.good. A 192.0.2.1
|
# zoop.boing.good. NS ns3.good.
|
||||||
|
# ns3.good. IN A 10.53.0.3
|
||||||
|
# too.many.labels.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.good. A 192.0.2.2
|
||||||
# it responds properly (with NODATA empty response) to non-empty terminals
|
# it responds properly (with NODATA empty response) to non-empty terminals
|
||||||
#
|
#
|
||||||
# For slow. it works the same as for good., but each response is delayed by 400 miliseconds
|
# For slow. it works the same as for good., but each response is delayed by 400 miliseconds
|
||||||
@ -111,20 +113,33 @@ def create_response(msg):
|
|||||||
return r
|
return r
|
||||||
|
|
||||||
# Good/bad differs only in how we treat non-empty terminals
|
# Good/bad differs only in how we treat non-empty terminals
|
||||||
if lqname == "icky.icky.icky.ptang.zoop.boing." and rrtype == A:
|
if lqname.endswith("zoop.boing."):
|
||||||
r.answer.append(dns.rrset.from_text(lqname + suffix, 1, IN, A, "192.0.2.1"))
|
r.authority.append(dns.rrset.from_text("zoop.boing." + suffix, 1, IN, NS, "ns3." + suffix))
|
||||||
|
elif lqname == "many.labels.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z." and rrtype == A:
|
||||||
|
r.answer.append(dns.rrset.from_text(lqname + suffix, 1, IN, A, "192.0.2.2"))
|
||||||
elif lqname == "" and rrtype == NS:
|
elif lqname == "" and rrtype == NS:
|
||||||
r.answer.append(dns.rrset.from_text(suffix, 1, IN, NS, "ns2." + suffix))
|
r.answer.append(dns.rrset.from_text(suffix, 1, IN, NS, "ns2." + suffix))
|
||||||
elif lqname == "ns2." and rrtype == A:
|
elif lqname == "ns2." and rrtype == A:
|
||||||
r.answer.append(dns.rrset.from_text("ns2."+suffix, 1, IN, A, "10.53.0.2"))
|
r.answer.append(dns.rrset.from_text("ns2."+suffix, 1, IN, A, "10.53.0.2"))
|
||||||
elif lqname == "ns2." and rrtype == AAAA:
|
elif lqname == "ns2." and rrtype == AAAA:
|
||||||
r.answer.append(dns.rrset.from_text("ns2."+suffix, 1, IN, AAAA, "fd92:7065:b8e:ffff::2"))
|
r.answer.append(dns.rrset.from_text("ns2."+suffix, 1, IN, AAAA, "fd92:7065:b8e:ffff::2"))
|
||||||
|
elif lqname == "ns3." and rrtype == A:
|
||||||
|
r.answer.append(dns.rrset.from_text("ns3."+suffix, 1, IN, A, "10.53.0.3"))
|
||||||
|
elif lqname == "ns3." and rrtype == AAAA:
|
||||||
|
r.answer.append(dns.rrset.from_text("ns3."+suffix, 1, IN, AAAA, "fd92:7065:b8e:ffff::3"))
|
||||||
|
elif lqname == "a.bit.longer.ns.name." and rrtype == A:
|
||||||
|
r.answer.append(dns.rrset.from_text("a.bit.longer.ns.name."+suffix, 1, IN, A, "10.53.0.4"))
|
||||||
|
elif lqname == "a.bit.longer.ns.name." and rrtype == AAAA:
|
||||||
|
r.answer.append(dns.rrset.from_text("a.bit.longer.ns.name."+suffix, 1, IN, AAAA, "fd92:7065:b8e:ffff::4"))
|
||||||
else:
|
else:
|
||||||
r.authority.append(dns.rrset.from_text(suffix, 1, IN, SOA, "ns2." + suffix + " hostmaster.arpa. 2018050100 1 1 1 1"))
|
r.authority.append(dns.rrset.from_text(suffix, 1, IN, SOA, "ns2." + suffix + " hostmaster.arpa. 2018050100 1 1 1 1"))
|
||||||
if bad or not "icky.icky.icky.ptang.zoop.boing.".endswith(lqname):
|
if bad or not \
|
||||||
|
("icky.icky.icky.ptang.zoop.boing.".endswith(lqname) or \
|
||||||
|
"many.labels.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.".endswith(lqname) or \
|
||||||
|
"a.bit.longer.ns.name.".endswith(lqname)):
|
||||||
r.set_rcode(NXDOMAIN)
|
r.set_rcode(NXDOMAIN)
|
||||||
if slow:
|
if slow:
|
||||||
time.sleep(0.4)
|
time.sleep(0.2)
|
||||||
return r
|
return r
|
||||||
|
|
||||||
|
|
||||||
|
175
bin/tests/system/qname-minimization/ans3/ans.py
Executable file
175
bin/tests/system/qname-minimization/ans3/ans.py
Executable file
@ -0,0 +1,175 @@
|
|||||||
|
############################################################################
|
||||||
|
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
#
|
||||||
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
#
|
||||||
|
# See the COPYRIGHT file distributed with this work for additional
|
||||||
|
# information regarding copyright ownership.
|
||||||
|
############################################################################
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import signal
|
||||||
|
import socket
|
||||||
|
import select
|
||||||
|
from datetime import datetime, timedelta
|
||||||
|
import time
|
||||||
|
import functools
|
||||||
|
|
||||||
|
import dns, dns.message, dns.query
|
||||||
|
from dns.rdatatype import *
|
||||||
|
from dns.rdataclass import *
|
||||||
|
from dns.rcode import *
|
||||||
|
from dns.name import *
|
||||||
|
|
||||||
|
|
||||||
|
# Log query to file
|
||||||
|
def logquery(type, qname):
|
||||||
|
with open("qlog", "a") as f:
|
||||||
|
f.write("%s %s\n", type, qname)
|
||||||
|
|
||||||
|
############################################################################
|
||||||
|
# Respond to a DNS query.
|
||||||
|
# For good. it serves:
|
||||||
|
# zoop.boing.good. NS ns3.good.
|
||||||
|
# icky.ptang.zoop.boing.good. NS a.bit.longer.ns.name.good.
|
||||||
|
# it responds properly (with NODATA empty response) to non-empty terminals
|
||||||
|
#
|
||||||
|
# For slow. it works the same as for good., but each response is delayed by 400 miliseconds
|
||||||
|
#
|
||||||
|
# For bad. it works the same as for good., but returns NXDOMAIN to non-empty terminals
|
||||||
|
############################################################################
|
||||||
|
def create_response(msg):
|
||||||
|
m = dns.message.from_wire(msg)
|
||||||
|
qname = m.question[0].name.to_text()
|
||||||
|
lqname = qname.lower()
|
||||||
|
labels = lqname.split('.')
|
||||||
|
|
||||||
|
# get qtype
|
||||||
|
rrtype = m.question[0].rdtype
|
||||||
|
typename = dns.rdatatype.to_text(rrtype)
|
||||||
|
bad = False
|
||||||
|
slow = False
|
||||||
|
|
||||||
|
# log this query
|
||||||
|
with open("query.log", "a") as f:
|
||||||
|
f.write("%s %s\n" % (typename, lqname))
|
||||||
|
print("%s %s" % (typename, lqname), end=" ")
|
||||||
|
|
||||||
|
r = dns.message.make_response(m)
|
||||||
|
r.set_rcode(NOERROR)
|
||||||
|
|
||||||
|
if lqname.endswith("bad."):
|
||||||
|
bad = True
|
||||||
|
suffix = "bad."
|
||||||
|
lqname = lqname[:-4]
|
||||||
|
elif lqname.endswith("good."):
|
||||||
|
suffix = "good."
|
||||||
|
lqname = lqname[:-5]
|
||||||
|
elif lqname.endswith("slow."):
|
||||||
|
slow = True
|
||||||
|
suffix = "slow."
|
||||||
|
lqname = lqname[:-5]
|
||||||
|
else:
|
||||||
|
r.set_rcode(REFUSED)
|
||||||
|
return r
|
||||||
|
|
||||||
|
# Good/bad differs only in how we treat non-empty terminals
|
||||||
|
if lqname == "zoop.boing." and rrtype == NS:
|
||||||
|
r.answer.append(dns.rrset.from_text(lqname + suffix, 1, IN, NS, "ns3."+suffix))
|
||||||
|
elif lqname.endswith("icky.ptang.zoop.boing."):
|
||||||
|
r.authority.append(dns.rrset.from_text("icky.ptang.zoop.boing." + suffix, 1, IN, NS, "a.bit.longer.ns.name." + suffix))
|
||||||
|
elif "icky.ptang.zoop.boing.".endswith(lqname):
|
||||||
|
r.authority.append(dns.rrset.from_text("zoop.boing." + suffix, 1, IN, SOA, "ns3." + suffix + " hostmaster.arpa. 2018050100 1 1 1 1"))
|
||||||
|
if bad:
|
||||||
|
r.set_rcode(NXDOMAIN)
|
||||||
|
elif "zoop.boing.".endswith(lqname):
|
||||||
|
r.authority.append(dns.rrset.from_text("zoop.boing." + suffix, 1, IN, SOA, "ns3." + suffix + " hostmaster.arpa. 2018050100 1 1 1 1"))
|
||||||
|
r.set_rcode(NXDOMAIN)
|
||||||
|
else:
|
||||||
|
r.set_rcode(REFUSED)
|
||||||
|
|
||||||
|
if slow:
|
||||||
|
time.sleep(0.4)
|
||||||
|
return r
|
||||||
|
|
||||||
|
|
||||||
|
def sigterm(signum, frame):
|
||||||
|
print ("Shutting down now...")
|
||||||
|
os.remove('ans.pid')
|
||||||
|
running = False
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
############################################################################
|
||||||
|
# Main
|
||||||
|
#
|
||||||
|
# Set up responder and control channel, open the pid file, and start
|
||||||
|
# the main loop, listening for queries on the query channel or commands
|
||||||
|
# on the control channel and acting on them.
|
||||||
|
############################################################################
|
||||||
|
ip4 = "10.53.0.3"
|
||||||
|
ip6 = "fd92:7065:b8e:ffff::3"
|
||||||
|
|
||||||
|
try: port=int(os.environ['PORT'])
|
||||||
|
except: port=5300
|
||||||
|
|
||||||
|
query4_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||||
|
query4_socket.bind((ip4, port))
|
||||||
|
|
||||||
|
havev6 = True
|
||||||
|
try:
|
||||||
|
query6_socket = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
|
||||||
|
try:
|
||||||
|
query6_socket.bind((ip6, port))
|
||||||
|
except:
|
||||||
|
query6_socket.close()
|
||||||
|
havev6 = False
|
||||||
|
except:
|
||||||
|
havev6 = False
|
||||||
|
|
||||||
|
signal.signal(signal.SIGTERM, sigterm)
|
||||||
|
|
||||||
|
f = open('ans.pid', 'w')
|
||||||
|
pid = os.getpid()
|
||||||
|
print (pid, file=f)
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
running = True
|
||||||
|
|
||||||
|
print ("Listening on %s port %d" % (ip4, port))
|
||||||
|
if havev6:
|
||||||
|
print ("Listening on %s port %d" % (ip6, port))
|
||||||
|
print ("Ctrl-c to quit")
|
||||||
|
|
||||||
|
if havev6:
|
||||||
|
input = [query4_socket, query6_socket]
|
||||||
|
else:
|
||||||
|
input = [query4_socket]
|
||||||
|
|
||||||
|
while running:
|
||||||
|
try:
|
||||||
|
inputready, outputready, exceptready = select.select(input, [], [])
|
||||||
|
except select.error as e:
|
||||||
|
break
|
||||||
|
except socket.error as e:
|
||||||
|
break
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
break
|
||||||
|
|
||||||
|
for s in inputready:
|
||||||
|
if s == query4_socket or s == query6_socket:
|
||||||
|
print ("Query received on %s" %
|
||||||
|
(ip4 if s == query4_socket else ip6), end=" ")
|
||||||
|
# Handle incoming queries
|
||||||
|
msg = s.recvfrom(65535)
|
||||||
|
rsp = create_response(msg[0])
|
||||||
|
if rsp:
|
||||||
|
print(dns.rcode.to_text(rsp.rcode()))
|
||||||
|
s.sendto(rsp.to_wire(), msg[1])
|
||||||
|
else:
|
||||||
|
print("NO RESPONSE")
|
||||||
|
if not running:
|
||||||
|
break
|
175
bin/tests/system/qname-minimization/ans4/ans.py
Executable file
175
bin/tests/system/qname-minimization/ans4/ans.py
Executable file
@ -0,0 +1,175 @@
|
|||||||
|
############################################################################
|
||||||
|
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
#
|
||||||
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
#
|
||||||
|
# See the COPYRIGHT file distributed with this work for additional
|
||||||
|
# information regarding copyright ownership.
|
||||||
|
############################################################################
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import signal
|
||||||
|
import socket
|
||||||
|
import select
|
||||||
|
from datetime import datetime, timedelta
|
||||||
|
import time
|
||||||
|
import functools
|
||||||
|
|
||||||
|
import dns, dns.message, dns.query
|
||||||
|
from dns.rdatatype import *
|
||||||
|
from dns.rdataclass import *
|
||||||
|
from dns.rcode import *
|
||||||
|
from dns.name import *
|
||||||
|
|
||||||
|
|
||||||
|
# Log query to file
|
||||||
|
def logquery(type, qname):
|
||||||
|
with open("qlog", "a") as f:
|
||||||
|
f.write("%s %s\n", type, qname)
|
||||||
|
|
||||||
|
############################################################################
|
||||||
|
# Respond to a DNS query.
|
||||||
|
# For good. it serves:
|
||||||
|
# icky.ptang.zoop.boing.good. NS a.bit.longer.ns.name.
|
||||||
|
# icky.icky.icky.ptang.zoop.boing.good. A 192.0.2.1
|
||||||
|
# more.icky.icky.icky.ptang.zoop.boing.good. A 192.0.2.2
|
||||||
|
# it responds properly (with NODATA empty response) to non-empty terminals
|
||||||
|
#
|
||||||
|
# For slow. it works the same as for good., but each response is delayed by 400 miliseconds
|
||||||
|
#
|
||||||
|
# For bad. it works the same as for good., but returns NXDOMAIN to non-empty terminals
|
||||||
|
############################################################################
|
||||||
|
def create_response(msg):
|
||||||
|
m = dns.message.from_wire(msg)
|
||||||
|
qname = m.question[0].name.to_text()
|
||||||
|
lqname = qname.lower()
|
||||||
|
labels = lqname.split('.')
|
||||||
|
|
||||||
|
# get qtype
|
||||||
|
rrtype = m.question[0].rdtype
|
||||||
|
typename = dns.rdatatype.to_text(rrtype)
|
||||||
|
bad = False
|
||||||
|
slow = False
|
||||||
|
|
||||||
|
# log this query
|
||||||
|
with open("query.log", "a") as f:
|
||||||
|
f.write("%s %s\n" % (typename, lqname))
|
||||||
|
print("%s %s" % (typename, lqname), end=" ")
|
||||||
|
|
||||||
|
r = dns.message.make_response(m)
|
||||||
|
r.set_rcode(NOERROR)
|
||||||
|
|
||||||
|
if lqname.endswith("bad."):
|
||||||
|
bad = True
|
||||||
|
suffix = "bad."
|
||||||
|
lqname = lqname[:-4]
|
||||||
|
elif lqname.endswith("good."):
|
||||||
|
suffix = "good."
|
||||||
|
lqname = lqname[:-5]
|
||||||
|
elif lqname.endswith("slow."):
|
||||||
|
slow = True
|
||||||
|
suffix = "slow."
|
||||||
|
lqname = lqname[:-5]
|
||||||
|
else:
|
||||||
|
r.set_rcode(REFUSED)
|
||||||
|
return r
|
||||||
|
|
||||||
|
# Good/bad differs only in how we treat non-empty terminals
|
||||||
|
if lqname == "icky.icky.icky.ptang.zoop.boing." and rrtype == A:
|
||||||
|
r.answer.append(dns.rrset.from_text(lqname + suffix, 1, IN, A, "192.0.2.1"))
|
||||||
|
elif lqname == "more.icky.icky.icky.ptang.zoop.boing." and rrtype == A:
|
||||||
|
r.answer.append(dns.rrset.from_text(lqname + suffix, 1, IN, A, "192.0.2.2"))
|
||||||
|
elif lqname == "icky.ptang.zoop.boing." and rrtype == NS:
|
||||||
|
r.answer.append(dns.rrset.from_text(lqname + suffix, 1, IN, NS, "a.bit.longer.ns.name."+suffix))
|
||||||
|
elif lqname.endswith("icky.ptang.zoop.boing."):
|
||||||
|
r.authority.append(dns.rrset.from_text("icky.ptang.zoop.boing." + suffix, 1, IN, SOA, "ns2." + suffix + " hostmaster.arpa. 2018050100 1 1 1 1"))
|
||||||
|
if bad or not "more.icky.icky.icky.ptang.zoop.boing.".endswith(lqname):
|
||||||
|
r.set_rcode(NXDOMAIN)
|
||||||
|
else:
|
||||||
|
r.set_rcode(REFUSED)
|
||||||
|
|
||||||
|
if slow:
|
||||||
|
time.sleep(0.4)
|
||||||
|
return r
|
||||||
|
|
||||||
|
|
||||||
|
def sigterm(signum, frame):
|
||||||
|
print ("Shutting down now...")
|
||||||
|
os.remove('ans.pid')
|
||||||
|
running = False
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
############################################################################
|
||||||
|
# Main
|
||||||
|
#
|
||||||
|
# Set up responder and control channel, open the pid file, and start
|
||||||
|
# the main loop, listening for queries on the query channel or commands
|
||||||
|
# on the control channel and acting on them.
|
||||||
|
############################################################################
|
||||||
|
ip4 = "10.53.0.4"
|
||||||
|
ip6 = "fd92:7065:b8e:ffff::4"
|
||||||
|
|
||||||
|
try: port=int(os.environ['PORT'])
|
||||||
|
except: port=5300
|
||||||
|
|
||||||
|
query4_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||||
|
query4_socket.bind((ip4, port))
|
||||||
|
|
||||||
|
havev6 = True
|
||||||
|
try:
|
||||||
|
query6_socket = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
|
||||||
|
try:
|
||||||
|
query6_socket.bind((ip6, port))
|
||||||
|
except:
|
||||||
|
query6_socket.close()
|
||||||
|
havev6 = False
|
||||||
|
except:
|
||||||
|
havev6 = False
|
||||||
|
|
||||||
|
signal.signal(signal.SIGTERM, sigterm)
|
||||||
|
|
||||||
|
f = open('ans.pid', 'w')
|
||||||
|
pid = os.getpid()
|
||||||
|
print (pid, file=f)
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
running = True
|
||||||
|
|
||||||
|
print ("Listening on %s port %d" % (ip4, port))
|
||||||
|
if havev6:
|
||||||
|
print ("Listening on %s port %d" % (ip6, port))
|
||||||
|
print ("Ctrl-c to quit")
|
||||||
|
|
||||||
|
if havev6:
|
||||||
|
input = [query4_socket, query6_socket]
|
||||||
|
else:
|
||||||
|
input = [query4_socket]
|
||||||
|
|
||||||
|
while running:
|
||||||
|
try:
|
||||||
|
inputready, outputready, exceptready = select.select(input, [], [])
|
||||||
|
except select.error as e:
|
||||||
|
break
|
||||||
|
except socket.error as e:
|
||||||
|
break
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
break
|
||||||
|
|
||||||
|
for s in inputready:
|
||||||
|
if s == query4_socket or s == query6_socket:
|
||||||
|
print ("Query received on %s" %
|
||||||
|
(ip4 if s == query4_socket else ip6), end=" ")
|
||||||
|
# Handle incoming queries
|
||||||
|
msg = s.recvfrom(65535)
|
||||||
|
rsp = create_response(msg[0])
|
||||||
|
if rsp:
|
||||||
|
print(dns.rcode.to_text(rsp.rcode()))
|
||||||
|
s.sendto(rsp.to_wire(), msg[1])
|
||||||
|
else:
|
||||||
|
print("NO RESPONSE")
|
||||||
|
if not running:
|
||||||
|
break
|
@ -14,4 +14,4 @@ rm -f */named.memstats
|
|||||||
rm -f */named.run
|
rm -f */named.run
|
||||||
rm -f dig.out.*
|
rm -f dig.out.*
|
||||||
rm -f ns*/named.lock
|
rm -f ns*/named.lock
|
||||||
rm -f ans2/query.log
|
rm -f ans*/query.log
|
||||||
|
@ -20,8 +20,7 @@ options {
|
|||||||
listen-on { 10.53.0.5; };
|
listen-on { 10.53.0.5; };
|
||||||
listen-on-v6 { none; };
|
listen-on-v6 { none; };
|
||||||
recursion yes;
|
recursion yes;
|
||||||
qname-minimization yes;
|
qname-minimization disabled;
|
||||||
qname-minimization-strict no;
|
|
||||||
querylog yes;
|
querylog yes;
|
||||||
resolver-query-timeout 30;
|
resolver-query-timeout 30;
|
||||||
};
|
};
|
||||||
|
@ -9,19 +9,18 @@
|
|||||||
* information regarding copyright ownership.
|
* information regarding copyright ownership.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// NS3
|
// NS6
|
||||||
|
|
||||||
options {
|
options {
|
||||||
query-source address 10.53.0.3;
|
query-source address 10.53.0.6;
|
||||||
notify-source 10.53.0.3;
|
notify-source 10.53.0.6;
|
||||||
transfer-source 10.53.0.3;
|
transfer-source 10.53.0.6;
|
||||||
port @PORT@;
|
port @PORT@;
|
||||||
pid-file "named.pid";
|
pid-file "named.pid";
|
||||||
listen-on { 10.53.0.3; };
|
listen-on { 10.53.0.6; };
|
||||||
listen-on-v6 { none; };
|
listen-on-v6 { none; };
|
||||||
recursion yes;
|
recursion yes;
|
||||||
qname-minimization no;
|
qname-minimization strict;
|
||||||
qname-minimization-strict no;
|
|
||||||
querylog yes;
|
querylog yes;
|
||||||
resolver-query-timeout 30;
|
resolver-query-timeout 30;
|
||||||
};
|
};
|
||||||
@ -32,7 +31,7 @@ key rndc_key {
|
|||||||
};
|
};
|
||||||
|
|
||||||
controls {
|
controls {
|
||||||
inet 10.53.0.3 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
|
inet 10.53.0.6 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
|
||||||
};
|
};
|
||||||
|
|
||||||
zone "." {
|
zone "." {
|
@ -9,19 +9,18 @@
|
|||||||
* information regarding copyright ownership.
|
* information regarding copyright ownership.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// NS4
|
// NS7
|
||||||
|
|
||||||
options {
|
options {
|
||||||
query-source address 10.53.0.4;
|
query-source address 10.53.0.7;
|
||||||
notify-source 10.53.0.4;
|
notify-source 10.53.0.7;
|
||||||
transfer-source 10.53.0.4;
|
transfer-source 10.53.0.7;
|
||||||
port @PORT@;
|
port @PORT@;
|
||||||
pid-file "named.pid";
|
pid-file "named.pid";
|
||||||
listen-on { 10.53.0.4; };
|
listen-on { 10.53.0.7; };
|
||||||
listen-on-v6 { none; };
|
listen-on-v6 { none; };
|
||||||
recursion yes;
|
recursion yes;
|
||||||
qname-minimization yes;
|
qname-minimization relaxed;
|
||||||
qname-minimization-strict yes;
|
|
||||||
querylog yes;
|
querylog yes;
|
||||||
resolver-query-timeout 30;
|
resolver-query-timeout 30;
|
||||||
};
|
};
|
||||||
@ -32,7 +31,7 @@ key rndc_key {
|
|||||||
};
|
};
|
||||||
|
|
||||||
controls {
|
controls {
|
||||||
inet 10.53.0.4 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
|
inet 10.53.0.7 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
|
||||||
};
|
};
|
||||||
|
|
||||||
zone "." {
|
zone "." {
|
@ -15,6 +15,6 @@ SYSTEMTESTTOP=..
|
|||||||
$SHELL clean.sh
|
$SHELL clean.sh
|
||||||
|
|
||||||
copy_setports ns1/named.conf.in ns1/named.conf
|
copy_setports ns1/named.conf.in ns1/named.conf
|
||||||
copy_setports ns3/named.conf.in ns3/named.conf
|
|
||||||
copy_setports ns4/named.conf.in ns4/named.conf
|
|
||||||
copy_setports ns5/named.conf.in ns5/named.conf
|
copy_setports ns5/named.conf.in ns5/named.conf
|
||||||
|
copy_setports ns6/named.conf.in ns6/named.conf
|
||||||
|
copy_setports ns7/named.conf.in ns7/named.conf
|
||||||
|
@ -14,7 +14,7 @@ SYSTEMTESTTOP=..
|
|||||||
|
|
||||||
DIGOPTS="-p ${PORT}"
|
DIGOPTS="-p ${PORT}"
|
||||||
RNDCCMD="$RNDC -c $SYSTEMTESTTOP/common/rndc.conf -p ${CONTROLPORT} -s"
|
RNDCCMD="$RNDC -c $SYSTEMTESTTOP/common/rndc.conf -p ${CONTROLPORT} -s"
|
||||||
CLEANQL="rm -f ans2/query.log"
|
CLEANQL="rm -f ans*/query.log"
|
||||||
status=0
|
status=0
|
||||||
n=0
|
n=0
|
||||||
|
|
||||||
@ -22,10 +22,19 @@ n=`expr $n + 1`
|
|||||||
echo_i "query for .good is not minimized when qname-minimization is off ($n)"
|
echo_i "query for .good is not minimized when qname-minimization is off ($n)"
|
||||||
ret=0
|
ret=0
|
||||||
$CLEANQL
|
$CLEANQL
|
||||||
$RNDCCMD 10.53.0.3 flush
|
$RNDCCMD 10.53.0.5 flush
|
||||||
$DIG $DIGOPTS icky.icky.icky.ptang.zoop.boing.good. @10.53.0.3 > dig.out.test$n
|
$DIG $DIGOPTS icky.icky.icky.ptang.zoop.boing.good. @10.53.0.5 > dig.out.test$n
|
||||||
grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
|
grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
|
||||||
echo "A icky.icky.icky.ptang.zoop.boing.good." | diff ans2/query.log - > /dev/null || ret=1
|
grep "icky.icky.icky.ptang.zoop.boing.good. 1 IN A 192.0.2.1" dig.out.test$n > /dev/null || ret=1
|
||||||
|
cat << __EOF | diff ans2/query.log - > /dev/null || ret=1
|
||||||
|
A icky.icky.icky.ptang.zoop.boing.good.
|
||||||
|
A ns3.good.
|
||||||
|
AAAA ns3.good.
|
||||||
|
A a.bit.longer.ns.name.good.
|
||||||
|
AAAA a.bit.longer.ns.name.good.
|
||||||
|
__EOF
|
||||||
|
echo "A icky.icky.icky.ptang.zoop.boing.good." | diff ans3/query.log - > /dev/null || ret=1
|
||||||
|
echo "A icky.icky.icky.ptang.zoop.boing.good." | diff ans4/query.log - > /dev/null || ret=1
|
||||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||||
status=`expr $status + $ret`
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
@ -33,10 +42,19 @@ n=`expr $n + 1`
|
|||||||
echo_i "query for .bad is not minimized when qname-minimization is off ($n)"
|
echo_i "query for .bad is not minimized when qname-minimization is off ($n)"
|
||||||
ret=0
|
ret=0
|
||||||
$CLEANQL
|
$CLEANQL
|
||||||
$RNDCCMD 10.53.0.3 flush
|
$RNDCCMD 10.53.0.5 flush
|
||||||
$DIG $DIGOPTS icky.icky.icky.ptang.zoop.boing.bad. @10.53.0.3 > dig.out.test$n
|
$DIG $DIGOPTS icky.icky.icky.ptang.zoop.boing.bad. @10.53.0.5 > dig.out.test$n
|
||||||
grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
|
grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
|
||||||
echo "A icky.icky.icky.ptang.zoop.boing.bad." | diff ans2/query.log - > /dev/null || ret=1
|
grep "icky.icky.icky.ptang.zoop.boing.bad. 1 IN A 192.0.2.1" dig.out.test$n > /dev/null || ret=1
|
||||||
|
cat << __EOF | diff ans2/query.log - > /dev/null || ret=1
|
||||||
|
A icky.icky.icky.ptang.zoop.boing.bad.
|
||||||
|
A ns3.bad.
|
||||||
|
AAAA ns3.bad.
|
||||||
|
A a.bit.longer.ns.name.bad.
|
||||||
|
AAAA a.bit.longer.ns.name.bad.
|
||||||
|
__EOF
|
||||||
|
echo "A icky.icky.icky.ptang.zoop.boing.bad." | diff ans3/query.log - > /dev/null || ret=1
|
||||||
|
echo "A icky.icky.icky.ptang.zoop.boing.bad." | diff ans4/query.log - > /dev/null || ret=1
|
||||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||||
status=`expr $status + $ret`
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
@ -44,10 +62,20 @@ n=`expr $n + 1`
|
|||||||
echo_i "query for .slow is not minimized when qname-minimization is off ($n)"
|
echo_i "query for .slow is not minimized when qname-minimization is off ($n)"
|
||||||
ret=0
|
ret=0
|
||||||
$CLEANQL
|
$CLEANQL
|
||||||
$RNDCCMD 10.53.0.3 flush
|
$RNDCCMD 10.53.0.5 flush
|
||||||
$DIG $DIGOPTS icky.icky.icky.ptang.zoop.boing.slow. @10.53.0.3 > dig.out.test$n
|
$DIG $DIGOPTS icky.icky.icky.ptang.zoop.boing.slow. @10.53.0.5 > dig.out.test$n
|
||||||
|
sleep 5
|
||||||
grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
|
grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
|
||||||
echo "A icky.icky.icky.ptang.zoop.boing.slow." | diff ans2/query.log - > /dev/null || ret=1
|
grep "icky.icky.icky.ptang.zoop.boing.slow. 1 IN A 192.0.2.1" dig.out.test$n > /dev/null || ret=1
|
||||||
|
cat << __EOF | diff ans2/query.log - > /dev/null || ret=1
|
||||||
|
A icky.icky.icky.ptang.zoop.boing.slow.
|
||||||
|
A ns3.slow.
|
||||||
|
AAAA ns3.slow.
|
||||||
|
A a.bit.longer.ns.name.slow.
|
||||||
|
AAAA a.bit.longer.ns.name.slow.
|
||||||
|
__EOF
|
||||||
|
echo "A icky.icky.icky.ptang.zoop.boing.slow." | diff ans3/query.log - > /dev/null || ret=1
|
||||||
|
echo "A icky.icky.icky.ptang.zoop.boing.slow." | diff ans4/query.log - > /dev/null || ret=1
|
||||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||||
status=`expr $status + $ret`
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
@ -55,14 +83,35 @@ n=`expr $n + 1`
|
|||||||
echo_i "query for .good is properly minimized when qname-minimization is on ($n)"
|
echo_i "query for .good is properly minimized when qname-minimization is on ($n)"
|
||||||
ret=0
|
ret=0
|
||||||
$CLEANQL
|
$CLEANQL
|
||||||
$RNDCCMD 10.53.0.4 flush
|
$RNDCCMD 10.53.0.6 flush
|
||||||
$DIG $DIGOPTS icky.icky.icky.ptang.zoop.boing.good. @10.53.0.4 > dig.out.test$n
|
$DIG $DIGOPTS icky.icky.icky.ptang.zoop.boing.good. @10.53.0.6 > dig.out.test$n
|
||||||
grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
|
grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
|
||||||
|
grep "icky.icky.icky.ptang.zoop.boing.good. 1 IN A 192.0.2.1" dig.out.test$n > /dev/null || ret=1
|
||||||
|
# Duplicated NS queries are there because we're not creating
|
||||||
|
# a separate fetch when doing qname minimization - so two
|
||||||
|
# queries running for the same name but different RRTYPE
|
||||||
|
# (A and AAAA in this case) will create separate queries
|
||||||
|
# for NSes on the way. Those will be cached though, so it
|
||||||
|
# should not be a problem
|
||||||
cat << __EOF | diff ans2/query.log - > /dev/null || ret=1
|
cat << __EOF | diff ans2/query.log - > /dev/null || ret=1
|
||||||
NS boing.good.
|
NS boing.good.
|
||||||
NS zoop.boing.good.
|
NS zoop.boing.good.
|
||||||
|
A ns3.good.
|
||||||
|
AAAA ns3.good.
|
||||||
|
NS name.good.
|
||||||
|
NS name.good.
|
||||||
|
NS ns.name.good.
|
||||||
|
NS ns.name.good.
|
||||||
|
NS longer.ns.name.good.
|
||||||
|
NS longer.ns.name.good.
|
||||||
|
A a.bit.longer.ns.name.good.
|
||||||
|
AAAA a.bit.longer.ns.name.good.
|
||||||
|
__EOF
|
||||||
|
cat << __EOF | diff ans3/query.log - > /dev/null || ret=1
|
||||||
NS ptang.zoop.boing.good.
|
NS ptang.zoop.boing.good.
|
||||||
NS icky.ptang.zoop.boing.good.
|
NS icky.ptang.zoop.boing.good.
|
||||||
|
__EOF
|
||||||
|
cat << __EOF | diff ans4/query.log - > /dev/null || ret=1
|
||||||
NS icky.icky.ptang.zoop.boing.good.
|
NS icky.icky.ptang.zoop.boing.good.
|
||||||
A icky.icky.icky.ptang.zoop.boing.good.
|
A icky.icky.icky.ptang.zoop.boing.good.
|
||||||
__EOF
|
__EOF
|
||||||
@ -70,31 +119,36 @@ if [ $ret != 0 ]; then echo_i "failed"; fi
|
|||||||
status=`expr $status + $ret`
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
n=`expr $n + 1`
|
n=`expr $n + 1`
|
||||||
echo_i "query for .bad fails when qname-minimization is on and in strict mode ($n)"
|
echo_i "query for .bad fails when qname-minimization is in strict mode ($n)"
|
||||||
ret=0
|
ret=0
|
||||||
$CLEANQL
|
$CLEANQL
|
||||||
$RNDCCMD 10.53.0.4 flush
|
$RNDCCMD 10.53.0.6 flush
|
||||||
$DIG $DIGOPTS icky.icky.icky.ptang.zoop.boing.bad. @10.53.0.4 > dig.out.test$n
|
$DIG $DIGOPTS icky.icky.icky.ptang.zoop.boing.bad. @10.53.0.6 > dig.out.test$n
|
||||||
grep "status: NXDOMAIN" dig.out.test$n > /dev/null || ret=1
|
grep "status: NXDOMAIN" dig.out.test$n > /dev/null || ret=1
|
||||||
echo "NS boing.bad." | diff ans2/query.log - > /dev/null || ret=1
|
echo "NS boing.bad." | diff ans2/query.log - > /dev/null || ret=1
|
||||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||||
status=`expr $status + $ret`
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
n=`expr $n + 1`
|
n=`expr $n + 1`
|
||||||
echo_i "query for .bad succeds when qname-minimization is on and not in strict mode ($n)"
|
echo_i "query for .bad succeds when qname-minimization is in relaxed mode ($n)"
|
||||||
ret=0
|
ret=0
|
||||||
$CLEANQL
|
$CLEANQL
|
||||||
$RNDCCMD 10.53.0.5 flush
|
$RNDCCMD 10.53.0.7 flush
|
||||||
$DIG $DIGOPTS icky.icky.icky.ptang.zoop.boing.bad. @10.53.0.5 > dig.out.test$n
|
$DIG $DIGOPTS icky.icky.icky.ptang.zoop.boing.bad. @10.53.0.7 > dig.out.test$n
|
||||||
grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
|
grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
|
||||||
|
grep "icky.icky.icky.ptang.zoop.boing.bad. 1 IN A 192.0.2.1" dig.out.test$n > /dev/null || ret=1
|
||||||
cat << __EOF | diff ans2/query.log - > /dev/null || ret=1
|
cat << __EOF | diff ans2/query.log - > /dev/null || ret=1
|
||||||
NS boing.bad.
|
NS boing.bad.
|
||||||
NS zoop.boing.bad.
|
|
||||||
NS ptang.zoop.boing.bad.
|
|
||||||
NS icky.ptang.zoop.boing.bad.
|
|
||||||
NS icky.icky.ptang.zoop.boing.bad.
|
|
||||||
A icky.icky.icky.ptang.zoop.boing.bad.
|
A icky.icky.icky.ptang.zoop.boing.bad.
|
||||||
|
A ns3.bad.
|
||||||
|
AAAA ns3.bad.
|
||||||
|
NS name.bad.
|
||||||
|
NS name.bad.
|
||||||
|
A a.bit.longer.ns.name.bad.
|
||||||
|
AAAA a.bit.longer.ns.name.bad.
|
||||||
__EOF
|
__EOF
|
||||||
|
echo "A icky.icky.icky.ptang.zoop.boing.bad." | diff ans3/query.log - > /dev/null || ret=1
|
||||||
|
echo "A icky.icky.icky.ptang.zoop.boing.bad." | diff ans4/query.log - > /dev/null || ret=1
|
||||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||||
status=`expr $status + $ret`
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
@ -102,14 +156,30 @@ n=`expr $n + 1`
|
|||||||
echo_i "query for .slow is properly minimized when qname-minimization is on ($n)"
|
echo_i "query for .slow is properly minimized when qname-minimization is on ($n)"
|
||||||
ret=0
|
ret=0
|
||||||
$CLEANQL
|
$CLEANQL
|
||||||
$RNDCCMD 10.53.0.4 flush
|
$RNDCCMD 10.53.0.6 flush
|
||||||
$DIG $DIGOPTS icky.icky.icky.ptang.zoop.boing.slow. @10.53.0.4 > dig.out.test$n
|
$DIG $DIGOPTS icky.icky.icky.ptang.zoop.boing.slow. @10.53.0.6 > dig.out.test$n
|
||||||
|
sleep 5
|
||||||
grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
|
grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
|
||||||
|
grep "icky.icky.icky.ptang.zoop.boing.slow. 1 IN A 192.0.2.1" dig.out.test$n > /dev/null || ret=1
|
||||||
cat << __EOF | diff ans2/query.log - > /dev/null || ret=1
|
cat << __EOF | diff ans2/query.log - > /dev/null || ret=1
|
||||||
NS boing.slow.
|
NS boing.slow.
|
||||||
NS zoop.boing.slow.
|
NS zoop.boing.slow.
|
||||||
|
A ns3.slow.
|
||||||
|
AAAA ns3.slow.
|
||||||
|
NS name.slow.
|
||||||
|
NS name.slow.
|
||||||
|
NS ns.name.slow.
|
||||||
|
NS ns.name.slow.
|
||||||
|
NS longer.ns.name.slow.
|
||||||
|
NS longer.ns.name.slow.
|
||||||
|
A a.bit.longer.ns.name.slow.
|
||||||
|
AAAA a.bit.longer.ns.name.slow.
|
||||||
|
__EOF
|
||||||
|
cat << __EOF | diff ans3/query.log - > /dev/null || ret=1
|
||||||
NS ptang.zoop.boing.slow.
|
NS ptang.zoop.boing.slow.
|
||||||
NS icky.ptang.zoop.boing.slow.
|
NS icky.ptang.zoop.boing.slow.
|
||||||
|
__EOF
|
||||||
|
cat << __EOF | diff ans4/query.log - > /dev/null || ret=1
|
||||||
NS icky.icky.ptang.zoop.boing.slow.
|
NS icky.icky.ptang.zoop.boing.slow.
|
||||||
A icky.icky.icky.ptang.zoop.boing.slow.
|
A icky.icky.icky.ptang.zoop.boing.slow.
|
||||||
__EOF
|
__EOF
|
||||||
@ -117,12 +187,13 @@ if [ $ret != 0 ]; then echo_i "failed"; fi
|
|||||||
status=`expr $status + $ret`
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
n=`expr $n + 1`
|
n=`expr $n + 1`
|
||||||
echo_i "query for .ip6.arpa succeds and skips on boundaries when qname-minimization is on ($n)"
|
echo_i "query for .ip6.arpa succeds and skips on proper boundaries when qname-minimization is on ($n)"
|
||||||
ret=0
|
ret=0
|
||||||
$CLEANQL
|
$CLEANQL
|
||||||
$RNDCCMD 10.53.0.4 flush
|
$RNDCCMD 10.53.0.6 flush
|
||||||
$DIG $DIGOPTS -x 2001:4f8::1 @10.53.0.4 > dig.out.test$n
|
$DIG $DIGOPTS -x 2001:4f8::1 @10.53.0.6 > dig.out.test$n
|
||||||
grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
|
grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
|
||||||
|
grep "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.f.4.0.1.0.0.2.ip6.arpa. 1 IN PTR nee.com." dig.out.test$n > /dev/null || ret=1
|
||||||
cat << __EOF | diff ans2/query.log - > /dev/null || ret=1
|
cat << __EOF | diff ans2/query.log - > /dev/null || ret=1
|
||||||
NS 1.0.0.2.ip6.arpa.
|
NS 1.0.0.2.ip6.arpa.
|
||||||
NS 8.f.4.0.1.0.0.2.ip6.arpa.
|
NS 8.f.4.0.1.0.0.2.ip6.arpa.
|
||||||
@ -134,5 +205,57 @@ __EOF
|
|||||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||||
status=`expr $status + $ret`
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
|
n=`expr $n + 1`
|
||||||
|
echo_i "query for multiple label name skips after 3rd no-delegation response ($n)"
|
||||||
|
ret=0
|
||||||
|
$CLEANQL
|
||||||
|
$RNDCCMD 10.53.0.6 flush
|
||||||
|
$DIG $DIGOPTS many.labels.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.good. @10.53.0.6 > dig.out.test$n
|
||||||
|
grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
|
||||||
|
grep "many.labels.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.good. 1 IN A 192.0.2.2" dig.out.test$n > /dev/null || ret=1
|
||||||
|
# We skipped after third no-delegation.
|
||||||
|
cat << __EOF | diff ans2/query.log - > /dev/null || ret=1
|
||||||
|
NS z.good.
|
||||||
|
NS y.z.good.
|
||||||
|
NS x.y.z.good.
|
||||||
|
A many.labels.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.good.
|
||||||
|
__EOF
|
||||||
|
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||||
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
|
n=`expr $n + 1`
|
||||||
|
echo_i "query for multiple label name skips after 7th label ($n)"
|
||||||
|
ret=0
|
||||||
|
$CLEANQL
|
||||||
|
$RNDCCMD 10.53.0.6 flush
|
||||||
|
$DIG $DIGOPTS more.icky.icky.icky.ptang.zoop.boing.good. @10.53.0.6 > dig.out.test$n
|
||||||
|
grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
|
||||||
|
grep "more.icky.icky.icky.ptang.zoop.boing.good. 1 IN A 192.0.2.2" dig.out.test$n > /dev/null || ret=1
|
||||||
|
cat << __EOF | diff ans2/query.log - > /dev/null || ret=1
|
||||||
|
NS boing.good.
|
||||||
|
NS zoop.boing.good.
|
||||||
|
A ns3.good.
|
||||||
|
AAAA ns3.good.
|
||||||
|
NS name.good.
|
||||||
|
NS name.good.
|
||||||
|
NS ns.name.good.
|
||||||
|
NS ns.name.good.
|
||||||
|
NS longer.ns.name.good.
|
||||||
|
NS longer.ns.name.good.
|
||||||
|
A a.bit.longer.ns.name.good.
|
||||||
|
AAAA a.bit.longer.ns.name.good.
|
||||||
|
__EOF
|
||||||
|
cat << __EOF | diff ans3/query.log - > /dev/null || ret=1
|
||||||
|
NS ptang.zoop.boing.good.
|
||||||
|
NS icky.ptang.zoop.boing.good.
|
||||||
|
__EOF
|
||||||
|
# There's no NS icky.icky.ptang.zoop.boing.good. query - we skipped it.
|
||||||
|
cat << __EOF | diff ans4/query.log - > /dev/null || ret=1
|
||||||
|
NS icky.icky.ptang.zoop.boing.good.
|
||||||
|
A more.icky.icky.icky.ptang.zoop.boing.good.
|
||||||
|
__EOF
|
||||||
|
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||||
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
echo_i "exit status: $status"
|
echo_i "exit status: $status"
|
||||||
[ $status -eq 0 ] || exit 1
|
[ $status -eq 0 ] || exit 1
|
||||||
|
@ -4029,6 +4029,14 @@ fetch_name(dns_adbname_t *adbname, isc_boolean_t start_at_zone,
|
|||||||
nameservers = &rdataset;
|
nameservers = &rdataset;
|
||||||
options |= DNS_FETCHOPT_UNSHARED;
|
options |= DNS_FETCHOPT_UNSHARED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (adb->view->qminimization) {
|
||||||
|
options |= DNS_FETCHOPT_QMINIMIZE;
|
||||||
|
options |= DNS_FETCHOPT_QMIN_SKIP_ON_IP6A;
|
||||||
|
if (adb->view->qmin_strict) {
|
||||||
|
options |= DNS_FETCHOPT_QMIN_STRICT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fetch = new_adbfetch(adb);
|
fetch = new_adbfetch(adb);
|
||||||
if (fetch == NULL) {
|
if (fetch == NULL) {
|
||||||
|
@ -141,6 +141,10 @@ typedef enum {
|
|||||||
#define DNS_RESOLVER_CHECKNAMES 0x01
|
#define DNS_RESOLVER_CHECKNAMES 0x01
|
||||||
#define DNS_RESOLVER_CHECKNAMESFAIL 0x02
|
#define DNS_RESOLVER_CHECKNAMESFAIL 0x02
|
||||||
|
|
||||||
|
#define DNS_QMIN_MAXLABELS 7
|
||||||
|
#define DNS_QMIN_MAX_NO_DELEGATION 3
|
||||||
|
#define DNS_MAX_LABELS 127
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
dns_resolver_create(dns_view_t *view,
|
dns_resolver_create(dns_view_t *view,
|
||||||
isc_taskmgr_t *taskmgr,
|
isc_taskmgr_t *taskmgr,
|
||||||
|
@ -265,6 +265,7 @@ struct fetchctx {
|
|||||||
unsigned int dbucketnum;
|
unsigned int dbucketnum;
|
||||||
char * info;
|
char * info;
|
||||||
isc_mem_t * mctx;
|
isc_mem_t * mctx;
|
||||||
|
isc_stdtime_t now;
|
||||||
|
|
||||||
/*% Locked by appropriate bucket lock. */
|
/*% Locked by appropriate bucket lock. */
|
||||||
fetchstate state;
|
fetchstate state;
|
||||||
@ -689,7 +690,7 @@ typedef struct respctx {
|
|||||||
isc_boolean_t ns_in_answer; /* NS may be in the answer section */
|
isc_boolean_t ns_in_answer; /* NS may be in the answer section */
|
||||||
isc_boolean_t negative; /* is this a negative response? */
|
isc_boolean_t negative; /* is this a negative response? */
|
||||||
|
|
||||||
isc_stdtime_t now; /* time info */
|
isc_stdtime_t now; /* time info */
|
||||||
isc_time_t tnow;
|
isc_time_t tnow;
|
||||||
isc_time_t *finish;
|
isc_time_t *finish;
|
||||||
|
|
||||||
@ -2542,8 +2543,8 @@ resquery_send(resquery_t *query) {
|
|||||||
fctx->timeout = ISC_FALSE;
|
fctx->timeout = ISC_FALSE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Use EDNS0, unless the caller doesn't want it, or we know that
|
* Use EDNS0, unless the caller doesn't want it, or we know that the
|
||||||
* the remote server doesn't like it.
|
* remote server doesn't like it.
|
||||||
*/
|
*/
|
||||||
if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0) {
|
if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0) {
|
||||||
if ((query->addrinfo->flags & DNS_FETCHOPT_NOEDNS0) == 0) {
|
if ((query->addrinfo->flags & DNS_FETCHOPT_NOEDNS0) == 0) {
|
||||||
@ -4437,7 +4438,7 @@ fctx_join(fetchctx_t *fctx, isc_task_t *task, const isc_sockaddr_t *client,
|
|||||||
return (ISC_R_NOMEMORY);
|
return (ISC_R_NOMEMORY);
|
||||||
}
|
}
|
||||||
event->result = DNS_R_SERVFAIL;
|
event->result = DNS_R_SERVFAIL;
|
||||||
event->qtype = fctx->type;
|
event->qtype = fctx->fulltype;
|
||||||
event->db = NULL;
|
event->db = NULL;
|
||||||
event->node = NULL;
|
event->node = NULL;
|
||||||
event->rdataset = rdataset;
|
event->rdataset = rdataset;
|
||||||
@ -4559,6 +4560,7 @@ fctx_create(dns_resolver_t *res, const dns_name_t *name, dns_rdatatype_t type,
|
|||||||
fctx->minimized = isc_boolean_false;
|
fctx->minimized = isc_boolean_false;
|
||||||
fctx->ip6arpaskip = isc_boolean_false;
|
fctx->ip6arpaskip = isc_boolean_false;
|
||||||
fctx->qmin_labels = 1;
|
fctx->qmin_labels = 1;
|
||||||
|
isc_stdtime_get(&fctx->now);
|
||||||
ISC_LIST_INIT(fctx->queries);
|
ISC_LIST_INIT(fctx->queries);
|
||||||
ISC_LIST_INIT(fctx->finds);
|
ISC_LIST_INIT(fctx->finds);
|
||||||
ISC_LIST_INIT(fctx->altfinds);
|
ISC_LIST_INIT(fctx->altfinds);
|
||||||
@ -7423,7 +7425,6 @@ rctx_respinit(isc_task_t *task, dns_dispatchevent_t *devent,
|
|||||||
TIME_NOW(&rctx->tnow);
|
TIME_NOW(&rctx->tnow);
|
||||||
rctx->finish = &rctx->tnow;
|
rctx->finish = &rctx->tnow;
|
||||||
isc_stdtime_get(&rctx->now);
|
isc_stdtime_get(&rctx->now);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -8497,7 +8498,20 @@ rctx_answer_none(respctx_t *rctx) {
|
|||||||
} else {
|
} else {
|
||||||
log_formerr(fctx, "invalid response");
|
log_formerr(fctx, "invalid response");
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* If we're minimizing in relaxed mode, retry with full name,
|
||||||
|
* just to be safe. The error will be logged.
|
||||||
|
*/
|
||||||
|
isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO, "XXX %d %d", fctx->minimized, fctx->options & DNS_FETCHOPT_QMIN_STRICT);
|
||||||
|
if (fctx->minimized &&
|
||||||
|
!(fctx->options & DNS_FETCHOPT_QMIN_STRICT)) {
|
||||||
|
isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
|
||||||
|
DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO,
|
||||||
|
"disabling qname minimization for '%s'"
|
||||||
|
" due to formerr", fctx->info);
|
||||||
|
fctx->qmin_labels = DNS_MAX_LABELS+1;
|
||||||
|
return rctx_answer_minimized(rctx);
|
||||||
|
}
|
||||||
return (DNS_R_FORMERR);
|
return (DNS_R_FORMERR);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8523,12 +8537,17 @@ rctx_answer_none(respctx_t *rctx) {
|
|||||||
* If we're doing qname minimization this is an empty non-terminal, add
|
* If we're doing qname minimization this is an empty non-terminal, add
|
||||||
* the next label to query and restart it.
|
* the next label to query and restart it.
|
||||||
*/
|
*/
|
||||||
if (fctx->minimized &&
|
if (fctx->minimized && fctx->rmessage->rcode == dns_rcode_noerror) {
|
||||||
(fctx->rmessage->rcode == dns_rcode_noerror ||
|
return rctx_answer_minimized(rctx);
|
||||||
!(fctx->options & DNS_FETCHOPT_QMIN_STRICT))) {
|
}
|
||||||
|
/*
|
||||||
|
* Workaround for broken servers in relaxed mode - if we hit an
|
||||||
|
* NXDOMAIN we go straight to the full query.
|
||||||
|
*/
|
||||||
|
if (fctx->minimized && !(fctx->options & DNS_FETCHOPT_QMIN_STRICT)) {
|
||||||
|
fctx->qmin_labels = DNS_MAX_LABELS+1;
|
||||||
return rctx_answer_minimized(rctx);
|
return rctx_answer_minimized(rctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Since we're not doing a referral, we don't want to cache any
|
* Since we're not doing a referral, we don't want to cache any
|
||||||
* NS RRs we may have found.
|
* NS RRs we may have found.
|
||||||
@ -9079,7 +9098,7 @@ rctx_nextserver(respctx_t *rctx, dns_adbaddrinfo_t *addrinfo,
|
|||||||
}
|
}
|
||||||
result = dns_view_findzonecut(fctx->res->view,
|
result = dns_view_findzonecut(fctx->res->view,
|
||||||
name, fname,
|
name, fname,
|
||||||
rctx->now, findoptions,
|
fctx->now, findoptions,
|
||||||
ISC_TRUE, ISC_TRUE,
|
ISC_TRUE, ISC_TRUE,
|
||||||
&fctx->nameservers,
|
&fctx->nameservers,
|
||||||
NULL);
|
NULL);
|
||||||
@ -10283,6 +10302,10 @@ fctx_minimize_qname(fetchctx_t *fctx) {
|
|||||||
} else if (dlabels + fctx->qmin_labels > 19) {
|
} else if (dlabels + fctx->qmin_labels > 19) {
|
||||||
fctx->qmin_labels = 35 - dlabels;
|
fctx->qmin_labels = 35 - dlabels;
|
||||||
}
|
}
|
||||||
|
} else if (dlabels + fctx->qmin_labels > DNS_QMIN_MAXLABELS) {
|
||||||
|
fctx->qmin_labels = DNS_MAX_LABELS + 1;
|
||||||
|
} else if (fctx->qmin_labels > DNS_QMIN_MAX_NO_DELEGATION) {
|
||||||
|
fctx->qmin_labels = DNS_MAX_LABELS + 1;
|
||||||
}
|
}
|
||||||
if (dlabels + fctx->qmin_labels < nlabels) {
|
if (dlabels + fctx->qmin_labels < nlabels) {
|
||||||
/*
|
/*
|
||||||
|
@ -130,6 +130,7 @@ static cfg_type_t cfg_type_optional_uint32;
|
|||||||
static cfg_type_t cfg_type_options;
|
static cfg_type_t cfg_type_options;
|
||||||
static cfg_type_t cfg_type_portiplist;
|
static cfg_type_t cfg_type_portiplist;
|
||||||
static cfg_type_t cfg_type_printtime;
|
static cfg_type_t cfg_type_printtime;
|
||||||
|
static cfg_type_t cfg_type_qminmethod;
|
||||||
static cfg_type_t cfg_type_querysource4;
|
static cfg_type_t cfg_type_querysource4;
|
||||||
static cfg_type_t cfg_type_querysource6;
|
static cfg_type_t cfg_type_querysource6;
|
||||||
static cfg_type_t cfg_type_querysource;
|
static cfg_type_t cfg_type_querysource;
|
||||||
@ -1937,8 +1938,7 @@ view_clauses[] = {
|
|||||||
{ "preferred-glue", &cfg_type_astring, 0 },
|
{ "preferred-glue", &cfg_type_astring, 0 },
|
||||||
{ "prefetch", &cfg_type_prefetch, 0 },
|
{ "prefetch", &cfg_type_prefetch, 0 },
|
||||||
{ "provide-ixfr", &cfg_type_boolean, 0 },
|
{ "provide-ixfr", &cfg_type_boolean, 0 },
|
||||||
{ "qname-minimization", &cfg_type_boolean, 0 },
|
{ "qname-minimization", &cfg_type_qminmethod, 0 },
|
||||||
{ "qname-minimization-strict", &cfg_type_boolean, 0 },
|
|
||||||
/*
|
/*
|
||||||
* Note that the query-source option syntax is different
|
* Note that the query-source option syntax is different
|
||||||
* from the other -source options.
|
* from the other -source options.
|
||||||
@ -2951,6 +2951,15 @@ static cfg_type_t cfg_type_optional_keyref = {
|
|||||||
doc_optional_keyvalue, &cfg_rep_string, &key_kw
|
doc_optional_keyvalue, &cfg_rep_string, &key_kw
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const char *qminmethod_enums[] = {
|
||||||
|
"strict", "relaxed", "disabled", NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static cfg_type_t cfg_type_qminmethod = {
|
||||||
|
"qminmethod", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum,
|
||||||
|
&cfg_rep_string, qminmethod_enums
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef HAVE_GEOIP
|
#ifdef HAVE_GEOIP
|
||||||
/*
|
/*
|
||||||
* "geoip" ACL element:
|
* "geoip" ACL element:
|
||||||
|
@ -1730,12 +1730,14 @@
|
|||||||
./bin/tests/system/pkcs11ssl/tests.sh SH 2014,2016,2018
|
./bin/tests/system/pkcs11ssl/tests.sh SH 2014,2016,2018
|
||||||
./bin/tests/system/pkcs11ssl/usepkcs11 X 2014,2018
|
./bin/tests/system/pkcs11ssl/usepkcs11 X 2014,2018
|
||||||
./bin/tests/system/qname-minimization/ans2/ans.py PYTHON 2018
|
./bin/tests/system/qname-minimization/ans2/ans.py PYTHON 2018
|
||||||
|
./bin/tests/system/qname-minimization/ans3/ans.py PYTHON 2018
|
||||||
|
./bin/tests/system/qname-minimization/ans4/ans.py PYTHON 2018
|
||||||
./bin/tests/system/qname-minimization/clean.sh SH 2018
|
./bin/tests/system/qname-minimization/clean.sh SH 2018
|
||||||
./bin/tests/system/qname-minimization/ns1/named.conf.in CONF-C 2018
|
./bin/tests/system/qname-minimization/ns1/named.conf.in CONF-C 2018
|
||||||
./bin/tests/system/qname-minimization/ns1/root.db ZONE 2018
|
./bin/tests/system/qname-minimization/ns1/root.db ZONE 2018
|
||||||
./bin/tests/system/qname-minimization/ns3/named.conf.in CONF-C 2018
|
|
||||||
./bin/tests/system/qname-minimization/ns4/named.conf.in CONF-C 2018
|
|
||||||
./bin/tests/system/qname-minimization/ns5/named.conf.in CONF-C 2018
|
./bin/tests/system/qname-minimization/ns5/named.conf.in CONF-C 2018
|
||||||
|
./bin/tests/system/qname-minimization/ns6/named.conf.in CONF-C 2018
|
||||||
|
./bin/tests/system/qname-minimization/ns7/named.conf.in CONF-C 2018
|
||||||
./bin/tests/system/qname-minimization/setup.sh SH 2018
|
./bin/tests/system/qname-minimization/setup.sh SH 2018
|
||||||
./bin/tests/system/qname-minimization/tests.sh SH 2018
|
./bin/tests/system/qname-minimization/tests.sh SH 2018
|
||||||
./bin/tests/system/reclimit/README TXT.BRIEF 2014,2016,2017,2018
|
./bin/tests/system/reclimit/README TXT.BRIEF 2014,2016,2017,2018
|
||||||
|
Loading…
x
Reference in New Issue
Block a user