Merge branch '3842-delv-ns' into 'main'

implement "delv +ns"

Closes #3842

See merge request isc-projects/bind9!7477
This commit is contained in:
Evan Hunt 2023-03-28 20:08:34 +00:00
commit bd7f85c7e1
29 changed files with 756 additions and 171 deletions

10
CHANGES
View file

@ -1,3 +1,13 @@
6130. [func] The new "delv +ns" option activates name server mode,
in which delv sets up an internal recursive
resolver and uses that, rather than an external
server, to look up the requested data. All messages
sent and received during the resolution and
validation process are logged. This can be used in
place of "dig +trace"; it more accurately
replicates the behavior of named when resolving
a query. [GL #3842]
6129. [cleanup] Value stored to 'source' during its initialization is
never read. [GL #3965]

View file

@ -4,6 +4,7 @@ AM_CPPFLAGS += \
-I$(top_builddir)/include \
$(LIBISC_CFLAGS) \
$(LIBDNS_CFLAGS) \
$(LIBNS_CFLAGS) \
$(LIBISCCFG_CFLAGS)
AM_CPPFLAGS += \
@ -17,4 +18,5 @@ delv_SOURCES = \
delv_LDADD = \
$(LIBISC_LIBS) \
$(LIBDNS_LIBS) \
$(LIBNS_LIBS) \
$(LIBISCCFG_LIBS)

View file

@ -35,6 +35,7 @@
#include <isc/mem.h>
#include <isc/netmgr.h>
#include <isc/parseint.h>
#include <isc/random.h>
#include <isc/result.h>
#include <isc/sockaddr.h>
#include <isc/string.h>
@ -42,20 +43,28 @@
#include <isc/tls.h>
#include <isc/util.h>
#include <dns/acl.h>
#include <dns/byaddr.h>
#include <dns/cache.h>
#include <dns/client.h>
#include <dns/dispatch.h>
#include <dns/fixedname.h>
#include <dns/keytable.h>
#include <dns/keyvalues.h>
#include <dns/log.h>
#include <dns/masterdump.h>
#include <dns/message.h>
#include <dns/name.h>
#include <dns/rdata.h>
#include <dns/rdataclass.h>
#include <dns/rdataset.h>
#include <dns/rdatastruct.h>
#include <dns/rdatatype.h>
#include <dns/request.h>
#include <dns/result.h>
#include <dns/rootns.h>
#include <dns/secalg.h>
#include <dns/stats.h>
#include <dns/view.h>
#include <dst/dst.h>
@ -63,6 +72,10 @@
#include <isccfg/log.h>
#include <isccfg/namedconf.h>
#include <ns/client.h>
#include <ns/interfacemgr.h>
#include <ns/server.h>
#include <irs/resconf.h>
#define CHECK(r) \
@ -75,13 +88,24 @@
#define MAXNAME (DNS_NAME_MAXTEXT + 1)
/* Variables used internally by delv. */
char *progname;
char *progname = NULL;
static isc_mem_t *mctx = NULL;
static isc_log_t *lctx = NULL;
static dns_view_t *view = NULL;
static ns_server_t *sctx = NULL;
static ns_interface_t *ifp = NULL;
static dns_dispatch_t *dispatch = NULL;
static dns_db_t *roothints = NULL;
static isc_stats_t *resstats = NULL;
static dns_stats_t *resquerystats = NULL;
static FILE *logfp = NULL;
/* Managers */
static isc_nm_t *netmgr = NULL;
static isc_loopmgr_t *loopmgr = NULL;
static dns_dispatchmgr_t *dispatchmgr = NULL;
static dns_requestmgr_t *requestmgr = NULL;
static ns_interfacemgr_t *interfacemgr = NULL;
/* TLS */
static isc_tlsctx_cache_t *tlsctx_client_cache = NULL;
@ -89,26 +113,29 @@ static isc_tlsctx_cache_t *tlsctx_client_cache = NULL;
/* Configurables */
static char *server = NULL;
static const char *port = "53";
static uint32_t destport = 53;
static isc_sockaddr_t *srcaddr4 = NULL, *srcaddr6 = NULL;
static isc_sockaddr_t a4, a6;
static char *curqname = NULL, *qname = NULL;
static bool classset = false;
static dns_rdatatype_t qtype = dns_rdatatype_none;
static bool typeset = false;
static const char *hintfile = NULL;
static unsigned int styleflags = 0;
static uint32_t splitwidth = 0xffffffff;
static bool showcomments = true, showdnssec = true, showtrust = true,
rrcomments = true, noclass = false, nocrypto = false, nottl = false,
multiline = false, short_form = false, print_unknown_format = false,
yaml = false;
yaml = false, fulltrace = false;
static bool resolve_trace = false, validator_trace = false,
message_trace = false;
message_trace = false, send_trace = false;
static bool use_ipv4 = true, use_ipv6 = true;
static bool cdflag = false, no_sigs = false, root_validation = true;
static bool qmin = false, qmin_strict = false;
static bool use_tcp = false;
@ -189,8 +216,12 @@ usage(void) {
"records)\n"
" +[no]mtrace (Trace messages "
"received)\n"
" +[no]ns (Run internal name "
"server)\n"
" +[no]multiline (Print records in an "
"expanded format)\n"
" +[no]qmin[=mode] (QNAME minimization: "
"relaxed or strict)\n"
" +[no]root (DNSSEC validation trust "
"anchor)\n"
" +[no]rrcomments (Control display of "
@ -201,6 +232,8 @@ usage(void) {
" +[no]short (Short form answer)\n"
" +[no]split=## (Split hex/base64 fields "
"into chunks)\n"
" +[no]strace (Trace messages "
"sent)\n"
" +[no]tcp (TCP mode)\n"
" +[no]ttl (Control display of ttls "
"in records)\n"
@ -280,6 +313,7 @@ setup_logging(FILE *errout) {
isc_result_t result;
isc_logdestination_t destination;
isc_logconfig_t *logconfig = NULL;
int packetlevel = 10;
isc_log_create(mctx, &lctx, &logconfig);
isc_log_registercategories(lctx, categories);
@ -332,9 +366,12 @@ setup_logging(FILE *errout) {
}
}
if (message_trace && loglevel < 10) {
if (send_trace) {
packetlevel = 11;
}
if ((message_trace || send_trace) && loglevel < packetlevel) {
isc_log_createchannel(logconfig, "messages", ISC_LOG_TOFILEDESC,
ISC_LOG_DEBUG(10), &destination,
ISC_LOG_DEBUG(packetlevel), &destination,
ISC_LOG_PRINTPREFIX);
result = isc_log_usechannel(logconfig, "messages",
@ -424,7 +461,7 @@ print_status(dns_rdataset_t *rdataset) {
}
}
static isc_result_t
static void
printdata(dns_rdataset_t *rdataset, dns_name_t *owner) {
isc_result_t result = ISC_R_SUCCESS;
static dns_trust_t trust;
@ -437,12 +474,13 @@ printdata(dns_rdataset_t *rdataset, dns_name_t *owner) {
if (!dns_rdataset_isassociated(rdataset)) {
char namebuf[DNS_NAME_FORMATSIZE];
dns_name_format(owner, namebuf, sizeof(namebuf));
delv_log(ISC_LOG_DEBUG(4), "WARN: empty rdataset %s", namebuf);
return (ISC_R_SUCCESS);
delv_log(ISC_LOG_DEBUG(4), "warning: empty rdataset %s",
namebuf);
return;
}
if (!showdnssec && rdataset->type == dns_rdatatype_rrsig) {
return (ISC_R_SUCCESS);
return;
}
if (first || rdataset->trust != trust) {
@ -516,8 +554,6 @@ cleanup:
if (t != NULL) {
isc_mem_put(mctx, t, len);
}
return (ISC_R_SUCCESS);
}
static isc_result_t
@ -570,7 +606,7 @@ static isc_result_t
convert_name(dns_fixedname_t *fn, dns_name_t **name, const char *text) {
isc_result_t result;
isc_buffer_t b;
dns_name_t *n;
dns_name_t *n = NULL;
unsigned int len;
REQUIRE(fn != NULL && name != NULL && text != NULL);
@ -582,7 +618,7 @@ convert_name(dns_fixedname_t *fn, dns_name_t **name, const char *text) {
result = dns_name_fromtext(n, &b, dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS) {
delv_log(ISC_LOG_ERROR, "failed to convert QNAME %s: %s", text,
delv_log(ISC_LOG_ERROR, "failed to convert name %s: %s", text,
isc_result_totext(result));
return (result);
}
@ -592,7 +628,7 @@ convert_name(dns_fixedname_t *fn, dns_name_t **name, const char *text) {
}
static isc_result_t
key_fromconfig(const cfg_obj_t *key, dns_client_t *client) {
key_fromconfig(const cfg_obj_t *key, dns_client_t *client, dns_view_t *toview) {
dns_rdata_dnskey_t dnskey;
dns_rdata_ds_t ds;
uint32_t rdata1, rdata2, rdata3;
@ -615,6 +651,8 @@ key_fromconfig(const cfg_obj_t *key, dns_client_t *client) {
} anchortype;
const cfg_obj_t *obj;
REQUIRE(client != NULL || toview != NULL);
keynamestr = cfg_obj_asstring(cfg_tuple_get(key, "name"));
CHECK(convert_name(&fkeyname, &keyname, keynamestr));
@ -708,9 +746,15 @@ key_fromconfig(const cfg_obj_t *key, dns_client_t *client) {
CHECK(dns_rdata_fromstruct(NULL, dnskey.common.rdclass,
dnskey.common.rdtype, &dnskey,
&rrdatabuf));
CHECK(dns_client_addtrustedkey(client, dns_rdataclass_in,
dns_rdatatype_dnskey, keyname,
&rrdatabuf));
if (client != NULL) {
CHECK(dns_client_addtrustedkey(
client, dns_rdataclass_in, dns_rdatatype_dnskey,
keyname, &rrdatabuf));
} else if (toview != NULL) {
CHECK(dns_view_addtrustedkey(toview,
dns_rdatatype_dnskey,
keyname, &rrdatabuf));
}
break;
case INITIAL_DS:
case STATIC_DS:
@ -751,9 +795,14 @@ key_fromconfig(const cfg_obj_t *key, dns_client_t *client) {
CHECK(dns_rdata_fromstruct(NULL, ds.common.rdclass,
ds.common.rdtype, &ds, &rrdatabuf));
CHECK(dns_client_addtrustedkey(client, dns_rdataclass_in,
dns_rdatatype_ds, keyname,
&rrdatabuf));
if (client != NULL) {
CHECK(dns_client_addtrustedkey(
client, dns_rdataclass_in, dns_rdatatype_ds,
keyname, &rrdatabuf));
} else if (toview != NULL) {
CHECK(dns_view_addtrustedkey(toview, dns_rdatatype_ds,
keyname, &rrdatabuf));
}
}
num_keys++;
@ -777,7 +826,7 @@ cleanup:
}
static isc_result_t
load_keys(const cfg_obj_t *keys, dns_client_t *client) {
load_keys(const cfg_obj_t *keys, dns_client_t *client, dns_view_t *toview) {
const cfg_listelt_t *elt, *elt2;
const cfg_obj_t *key, *keylist;
isc_result_t result = ISC_R_SUCCESS;
@ -790,7 +839,7 @@ load_keys(const cfg_obj_t *keys, dns_client_t *client) {
elt2 = cfg_list_next(elt2))
{
key = cfg_listelt_value(elt2);
CHECK(key_fromconfig(key, client));
CHECK(key_fromconfig(key, client, toview));
}
}
@ -802,7 +851,7 @@ cleanup:
}
static isc_result_t
setup_dnsseckeys(dns_client_t *client) {
setup_dnsseckeys(dns_client_t *client, dns_view_t *toview) {
isc_result_t result;
cfg_parser_t *parser = NULL;
const cfg_obj_t *trusted_keys = NULL;
@ -853,13 +902,13 @@ setup_dnsseckeys(dns_client_t *client) {
cfg_map_get(bindkeys, "trust-anchors", &trust_anchors);
if (trusted_keys != NULL) {
CHECK(load_keys(trusted_keys, client));
CHECK(load_keys(trusted_keys, client, toview));
}
if (managed_keys != NULL) {
CHECK(load_keys(managed_keys, client));
CHECK(load_keys(managed_keys, client, toview));
}
if (trust_anchors != NULL) {
CHECK(load_keys(trust_anchors, client));
CHECK(load_keys(trust_anchors, client, toview));
}
result = ISC_R_SUCCESS;
@ -883,21 +932,15 @@ cleanup:
static isc_result_t
addserver(dns_client_t *client) {
struct addrinfo hints, *res, *cur;
struct addrinfo hints, *res = NULL, *cur = NULL;
int gaierror;
struct in_addr in4;
struct in6_addr in6;
isc_sockaddr_t *sa;
isc_sockaddr_t *sa = NULL;
isc_sockaddrlist_t servers;
uint32_t destport;
isc_result_t result;
dns_name_t *name = NULL;
result = parse_uint(&destport, port, 0xffff, "port");
if (result != ISC_R_SUCCESS) {
fatal("Couldn't parse port number");
}
ISC_LIST_INIT(servers);
if (inet_pton(AF_INET, server, &in4) == 1) {
@ -975,13 +1018,7 @@ findserver(dns_client_t *client) {
isc_result_t result;
irs_resconf_t *resconf = NULL;
isc_sockaddrlist_t *nameservers;
isc_sockaddr_t *sa, *next;
uint32_t destport;
result = parse_uint(&destport, port, 0xffff, "port");
if (result != ISC_R_SUCCESS) {
fatal("Couldn't parse port number");
}
isc_sockaddr_t *sa = NULL, *next = NULL;
result = irs_resconf_load(mctx, "/etc/resolv.conf", &resconf);
if (result != ISC_R_SUCCESS && result != ISC_R_FILENOTFOUND) {
@ -1135,9 +1172,26 @@ plus_option(char *option) {
goto invalid_option;
}
break;
case 'h':
switch (cmd[1]) {
case 'i': /* hint */
if (state) {
if (value == NULL) {
fatal("+hint: must specify hint file");
}
hintfile = value;
} else {
hintfile = NULL;
}
break;
default:
goto invalid_option;
}
break;
case 'm':
switch (cmd[1]) {
case 't': /* mtrace */
FULLCHECK("mtrace");
message_trace = state;
if (state) {
resolve_trace = state;
@ -1151,6 +1205,41 @@ plus_option(char *option) {
goto invalid_option;
}
break;
case 'n':
switch (cmd[1]) {
case 's': /* ns */
FULLCHECK("ns");
fulltrace = state;
if (state) {
message_trace = state;
send_trace = state;
resolve_trace = state;
logfp = stdout;
}
break;
default:
goto invalid_option;
}
break;
case 'q': /* qmin */
FULLCHECK("qmin");
if (state) {
if (value == NULL || strcasecmp(value, "relaxed") == 0)
{
qmin = true;
} else if (strcasecmp(value, "strict") == 0) {
qmin = true;
qmin_strict = true;
} else {
fatal("Invalid qmin option '%s': "
"use 'relaxed' or 'strict'\n",
value);
}
} else {
qmin = false;
qmin_strict = false;
}
break;
case 'r':
switch (cmd[1]) {
case 'o': /* root */
@ -1220,6 +1309,13 @@ plus_option(char *option) {
fatal("Couldn't parse split");
}
break;
case 't': /* strace */
FULLCHECK("strace");
send_trace = state;
if (state) {
message_trace = state;
}
break;
default:
goto invalid_option;
}
@ -1234,9 +1330,20 @@ plus_option(char *option) {
FULLCHECK("tcp");
use_tcp = state;
break;
case 'r': /* trust */
FULLCHECK("trust");
showtrust = state;
case 'r':
switch (cmd[2]) {
case 'a': /* trace */
FULLCHECK("trace");
fatal("Invalid argument +trace. For "
"delegation path tracing, use +ns.");
break;
case 'u': /* trust */
FULLCHECK("trust");
showtrust = state;
break;
default:
goto invalid_option;
}
break;
case 't': /* ttl */
FULLCHECK("ttl");
@ -1269,6 +1376,10 @@ plus_option(char *option) {
fprintf(stderr, "Invalid option: +%s\n", option);
usage();
}
if (qmin && !fulltrace) {
fatal("'+qmin' cannot be used without '+ns'");
}
return;
}
@ -1420,6 +1531,10 @@ dash_option(char *option, char *next, bool *open_type_class) {
return (value_from_next);
case 'p':
port = value;
result = parse_uint(&destport, port, 0xffff, "port");
if (result != ISC_R_SUCCESS) {
fatal("Couldn't parse port number");
}
return (value_from_next);
case 'q':
if (curqname != NULL) {
@ -1735,10 +1850,7 @@ resolve_cb(dns_client_t *client, const dns_name_t *query_name,
for (rdataset = ISC_LIST_HEAD(response_name->list);
rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link))
{
result = printdata(rdataset, response_name);
if (result != ISC_R_SUCCESS) {
delv_log(ISC_LOG_ERROR, "print data failed");
}
printdata(rdataset, response_name);
}
}
@ -1751,12 +1863,14 @@ resolve_cb(dns_client_t *client, const dns_name_t *query_name,
}
static void
resolve(void *arg) {
dns_client_t *client = arg;
dns_namelist_t *namelist;
run_resolve(void *arg) {
dns_client_t *client = NULL;
dns_namelist_t *namelist = NULL;
unsigned int resopt;
isc_result_t result;
dns_name_t *query_name;
dns_name_t *query_name = NULL;
UNUSED(arg);
namelist = isc_mem_get(mctx, sizeof(*namelist));
ISC_LIST_INIT(*namelist);
@ -1779,14 +1893,22 @@ resolve(void *arg) {
resopt |= DNS_CLIENTRESOPT_TCP;
}
/* Perform resolution */
result = dns_client_resolve(client, query_name, dns_rdataclass_in,
qtype, resopt, namelist, resolve_cb);
/* Create client */
CHECK(dns_client_create(mctx, loopmgr, netmgr, 0, tlsctx_client_cache,
&client, srcaddr4, srcaddr6));
if (result != ISC_R_SUCCESS) {
goto cleanup;
/* Set the nameserver */
if (server != NULL) {
addserver(client);
} else {
findserver(client);
}
CHECK(setup_dnsseckeys(client, NULL));
/* Perform resolution */
CHECK(dns_client_resolve(client, query_name, dns_rdataclass_in, qtype,
resopt, namelist, resolve_cb));
return;
cleanup:
if (!yaml) {
@ -1800,18 +1922,278 @@ cleanup:
dns_client_detach(&client);
}
static void
shutdown_server(void) {
if (requestmgr != NULL) {
dns_requestmgr_detach(&requestmgr);
}
if (interfacemgr != NULL) {
ns_interfacemgr_shutdown(interfacemgr);
ns_interfacemgr_detach(&interfacemgr);
}
if (dispatch != NULL) {
dns_dispatch_detach(&dispatch);
}
if (dispatchmgr != NULL) {
dns_dispatchmgr_detach(&dispatchmgr);
}
if (sctx != NULL) {
ns_server_detach(&sctx);
}
isc_loopmgr_shutdown(loopmgr);
}
static void
recvresponse(void *arg) {
dns_request_t *request = (dns_request_t *)arg;
dns_message_t *query = dns_request_getarg(request);
isc_result_t result = dns_request_getresult(request);
dns_message_t *response = NULL;
if (result != ISC_R_SUCCESS) {
fatal("request event result: %s", isc_result_totext(result));
}
dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &response);
result = dns_request_getresponse(request, response,
DNS_MESSAGEPARSE_PRESERVEORDER);
if (result != ISC_R_SUCCESS) {
fatal("request response failed: %s", isc_result_totext(result));
}
if (response->rcode != dns_rcode_noerror) {
result = dns_result_fromrcode(response->rcode);
delv_log(ISC_LOG_INFO, "response code: %s",
isc_result_totext(result));
goto cleanup;
}
for (result = dns_message_firstname(response, DNS_SECTION_ANSWER);
result == ISC_R_SUCCESS;
result = dns_message_nextname(response, DNS_SECTION_ANSWER))
{
dns_name_t *name = NULL;
dns_rdataset_t *rdataset = NULL;
dns_message_currentname(response, DNS_SECTION_ANSWER, &name);
for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL;
rdataset = ISC_LIST_NEXT(rdataset, link))
{
dns_rdataset_t rds, sigs;
int options = 0;
/*
* The response message contains the answer the
* resolver found, but it doesn't contain the
* trust status; so if we're displaying that, we
* need to look up each rdataset in the cache and
* print that version instead. but if not, we
* can just print the rdatasets from the message.
*/
if (!showtrust) {
printdata(rdataset, name);
continue;
}
/* do the cache lookup */
if (rdataset->type == dns_rdatatype_rrsig) {
continue;
}
dns_rdataset_init(&rds);
dns_rdataset_init(&sigs);
if (cdflag) {
options |= DNS_DBFIND_PENDINGOK;
}
result = dns_view_simplefind(view, name, rdataset->type,
0, options, false, &rds,
&sigs);
if (result == ISC_R_SUCCESS) {
printdata(&rds, name);
dns_rdataset_disassociate(&rds);
if (dns_rdataset_isassociated(&sigs)) {
printdata(&sigs, name);
dns_rdataset_disassociate(&sigs);
}
}
}
}
cleanup:
dns_message_detach(&query);
dns_message_detach(&response);
dns_request_destroy(&request);
dns_view_detach(&view);
shutdown_server();
}
static isc_result_t
accept_cb(isc_nmhandle_t *handle, isc_result_t result, void *arg) {
UNUSED(handle);
UNUSED(arg);
return (result);
}
static void
sendquery(void *arg) {
isc_nmsocket_t *sock = (isc_nmsocket_t *)arg;
isc_sockaddr_t peer = isc_nmsocket_getaddr(sock);
isc_result_t result;
dns_message_t *message = NULL;
dns_name_t *query_name = NULL, *mname = NULL;
dns_rdataset_t *mrdataset = NULL;
dns_rdataset_t *opt = NULL;
dns_request_t *request = NULL;
/* Construct query message */
CHECK(convert_name(&qfn, &query_name, qname));
dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &message);
message->opcode = dns_opcode_query;
message->flags = DNS_MESSAGEFLAG_RD | DNS_MESSAGEFLAG_AD;
if (cdflag) {
message->flags |= DNS_MESSAGEFLAG_CD;
}
message->rdclass = dns_rdataclass_in;
message->id = (dns_messageid_t)isc_random16();
dns_message_gettempname(message, &mname);
dns_message_gettemprdataset(message, &mrdataset);
dns_name_clone(query_name, mname);
dns_rdataset_makequestion(mrdataset, dns_rdataclass_in, qtype);
ISC_LIST_APPEND(mname->list, mrdataset, link);
dns_message_addname(message, mname, DNS_SECTION_QUESTION);
mrdataset = NULL;
mname = NULL;
CHECK(dns_message_buildopt(message, &opt, 0, 0, DNS_MESSAGEEXTFLAG_DO,
NULL, 0));
CHECK(dns_message_setopt(message, opt));
CHECK(dns_requestmgr_create(mctx, dispatchmgr, NULL, NULL,
&requestmgr));
dns_view_attach(view, &(dns_view_t *){ NULL });
CHECK(dns_request_create(requestmgr, message, NULL, &peer, NULL, NULL,
DNS_REQUESTOPT_TCP, NULL, 1, 0, 0,
isc_loop_current(loopmgr), recvresponse,
message, &request));
return;
cleanup:
if (message != NULL) {
if (mname != NULL) {
dns_message_puttempname(message, &mname);
}
if (mrdataset != NULL) {
dns_message_puttemprdataset(message, &mrdataset);
}
dns_message_detach(&message);
}
shutdown_server();
}
static isc_result_t
matchview(isc_netaddr_t *srcaddr, isc_netaddr_t *destaddr,
dns_message_t *message, dns_aclenv_t *env, isc_result_t *sigresultp,
dns_view_t **viewp) {
UNUSED(srcaddr);
UNUSED(destaddr);
UNUSED(message);
UNUSED(env);
UNUSED(sigresultp);
*viewp = view;
return (ISC_R_SUCCESS);
}
static void
run_server(void *arg) {
isc_result_t result;
dns_cache_t *cache = NULL;
isc_sockaddr_t addr, any;
struct in_addr in;
UNUSED(arg);
inet_pton(AF_INET, "127.0.0.1", &in);
isc_sockaddr_fromin(&addr, &in, 0);
CHECK(ns_server_create(mctx, matchview, &sctx));
CHECK(dns_dispatchmgr_create(mctx, netmgr, &dispatchmgr));
isc_sockaddr_any(&any);
CHECK(dns_dispatch_createudp(dispatchmgr, &any, &dispatch));
CHECK(ns_interfacemgr_create(mctx, sctx, loopmgr, netmgr, dispatchmgr,
NULL, false, &interfacemgr));
CHECK(dns_view_create(mctx, dns_rdataclass_in, "_default", &view));
CHECK(dns_cache_create(loopmgr, dns_rdataclass_in, "", &cache));
dns_view_setcache(view, cache, false);
dns_cache_detach(&cache);
dns_view_setdstport(view, destport);
CHECK(dns_rootns_create(mctx, dns_rdataclass_in, hintfile, &roothints));
dns_view_sethints(view, roothints);
dns_db_detach(&roothints);
view->qminimization = qmin;
view->qmin_strict = qmin_strict;
CHECK(dns_view_initsecroots(view, mctx));
CHECK(setup_dnsseckeys(NULL, view));
dns_view_setdispatchmgr(view, dispatchmgr);
CHECK(dns_view_createresolver(view, loopmgr, 1, netmgr, 0,
tlsctx_client_cache, dispatch, NULL));
CHECK(isc_stats_create(mctx, &resstats, dns_resstatscounter_max));
dns_resolver_setstats(view->resolver, resstats);
isc_stats_detach(&resstats);
CHECK(dns_rdatatypestats_create(mctx, &resquerystats));
dns_resolver_setquerystats(view->resolver, resquerystats);
dns_stats_detach(&resquerystats);
dns_view_freeze(view);
ns_interface_create(interfacemgr, &addr, NULL, &ifp);
CHECK(isc_nm_listenstreamdns(netmgr, ISC_NM_LISTEN_ONE, &addr,
ns_client_request, ifp, accept_cb, ifp, 10,
NULL, NULL, &ifp->tcplistensocket));
ifp->flags |= NS_INTERFACEFLAG_LISTENING;
isc_job_run(loopmgr, sendquery, ifp->tcplistensocket);
return;
cleanup:
if (view != NULL) {
dns_view_detach(&view);
}
shutdown_server();
}
int
main(int argc, char *argv[]) {
dns_client_t *client = NULL;
isc_result_t result;
isc_loop_t *loop = NULL;
progname = argv[0];
logfp = stderr;
preparse_args(argc, argv);
argc--;
argv++;
isc_managers_create(&mctx, 1, &loopmgr, &netmgr);
loop = isc_loop_main(loopmgr);
result = dst_lib_init(mctx, NULL);
if (result != ISC_R_SUCCESS) {
@ -1822,33 +2204,30 @@ main(int argc, char *argv[]) {
CHECK(setup_style());
setup_logging(stderr);
setup_logging(logfp);
if (!fulltrace && hintfile != NULL) {
delv_log(ISC_LOG_WARNING,
"WARNING: not using internal name server mode, "
"hint file will be ignored");
}
if (fulltrace && server != NULL) {
delv_log(ISC_LOG_WARNING,
"WARNING: using internal name server mode: "
"'@%s' will be ignored",
server);
}
/* Create client */
isc_tlsctx_cache_create(mctx, &tlsctx_client_cache);
result = dns_client_create(mctx, loopmgr, netmgr, 0,
tlsctx_client_cache, &client, srcaddr4,
srcaddr6);
if (result != ISC_R_SUCCESS) {
delv_log(ISC_LOG_ERROR, "dns_client_create: %s",
isc_result_totext(result));
goto cleanup;
}
/* Set the nameserver */
if (server != NULL) {
addserver(client);
} else {
findserver(client);
}
CHECK(setup_dnsseckeys(client));
isc_loop_setup(isc_loop_main(loopmgr), resolve, client);
isc_loop_setup(loop, fulltrace ? run_server : run_resolve, NULL);
isc_loopmgr_run(loopmgr);
cleanup:
if (tlsctx_client_cache != NULL) {
isc_tlsctx_cache_detach(&tlsctx_client_cache);
}
if (trust_anchor != NULL) {
isc_mem_free(mctx, trust_anchor);
}
@ -1861,12 +2240,8 @@ cleanup:
if (style != NULL) {
dns_master_styledestroy(&style, mctx);
}
if (tlsctx_client_cache != NULL) {
isc_tlsctx_cache_detach(&tlsctx_client_cache);
}
isc_log_destroy(&lctx);
dst_lib_destroy();
isc_managers_destroy(&mctx, &loopmgr, &netmgr);

View file

@ -230,6 +230,36 @@ assign values to options like the timeout interval. They have the form
This option controls whether to display the CLASS when printing a record. The
default is to display the CLASS.
.. option:: +hint=FILE, +nohint
This option specifies a filename from which to load root hints;
this will be used to find the root name servers when name server
mode (``delv +ns``) is in use. If the option is not specified,
built-in root hints will be used.
.. option:: +ns, +nons
This option toggles name server mode. When this option is in use,
the ``delv`` process instantiates a full recursive resolver, and uses
that to look up the requested query name and type. Turning on this
option also activates ``+mtrace``, ``+strace`` and ``+rtrace``, so that
every iterative query will be logged, including the full response messages
from each authoritatve server. These logged messages will be written
to ``stdout`` rather than ``stderr`` as usual, so that the full trace
can be captured more easily.
This is intended to be similar to the behavior of ``dig +trace``, but
because it uses the same code as ``named``, it much more accurately
replicates the behavior of a recursive name server with a cold cache
that is processing a recursive query.
.. option:: +qmin[=MODE], +noqmin
When used with ``+ns``, this option enables QNAME minimization mode.
Valid options of MODE are ``relaxed`` and ``strict``. By default,
QNAME minimization is disabled. If ``+qmin`` is specified but MODE
is omitted, then ``relaxed`` mode will be used.
.. option:: +ttl, +nottl
This option controls whether to display the TTL when printing a record. The
@ -237,11 +267,11 @@ assign values to options like the timeout interval. They have the form
.. option:: +rtrace, +nortrace
This option toggles resolver fetch logging. This reports the name and type of each
query sent by :program:`delv` in the process of carrying out the resolution
and validation process, including the original query
and all subsequent queries to follow CNAMEs and to establish a chain
of trust for DNSSEC validation.
This option toggles resolver fetch logging. This reports the name and
type of each query sent by :program:`delv` in the process of carrying
out the resolution and validation process, including the original query
and all subsequent queries to follow CNAMEs and to establish a chain of
trust for DNSSEC validation.
This is equivalent to setting the debug level to 1 in the "resolver"
logging category. Setting the systemwide debug level to 1 using the
@ -250,15 +280,27 @@ assign values to options like the timeout interval. They have the form
.. option:: +mtrace, +nomtrace
This option toggles message logging. This produces a detailed dump of the
responses received by :program:`delv` in the process of carrying out the
resolution and validation process.
This option toggles logging of messages received. This produces
a detailed dump of the responses received by :program:`delv` in the
process of carrying out the resolution and validation process.
This is equivalent to setting the debug level to 10 for the "packets"
module of the "resolver" logging category. Setting the systemwide
debug level to 10 using the :option:`-d` option produces the same
output, but affects other logging categories as well.
.. option:: +strace, +nostrace
This option toggles logging of messages sent. This produces a detailed
dump of the queries sent by :program:`delv` in the process of carrying
out the resolution and validation process. Turning on this option
also activates ``+mtrace``.
This is equivalent to setting the debug level to 11 for the "packets"
module of the "resolver" logging category. Setting the systemwide
debug level to 11 using the :option:`-d` option produces the same
output, but affects other logging categories as well.
.. option:: +vtrace, +novtrace
This option toggles validation logging. This shows the internal process of the

View file

@ -13,7 +13,7 @@
set -e
rm -f ./*/anchor.*
rm -f ./anchor.* ./*/anchor.*
rm -f ./*/named.conf
rm -f ./*/named.memstats
rm -f ./*/named.run
@ -28,9 +28,10 @@ rm -f ./dig.out.nn.*
rm -f ./host.out.test*
rm -f ./ns*/managed-keys.bind*
rm -f ./ns*/named.lock
rm -f ./ns2/dsset-example.
rm -f ./ns2/dsset-example.tld.
rm -f ./ns2/example.db ./ns2/K* ./ns2/keyid ./ns2/keydata
rm -f ./ns*/K* ./ns*/keyid ./ns*/keydata
rm -f ./ns1/root.db
rm -f ./ns*/dsset-*
rm -f ./ns2/example.db
rm -f ./ns2/example.tld.db
rm -f ./nslookup.out.test*
rm -f ./nsupdate.out.test*

View file

@ -0,0 +1,31 @@
#!/bin/sh -e
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# SPDX-License-Identifier: MPL-2.0
#
# 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 https://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
# shellcheck source=conf.sh
. ../../conf.sh
set -e
(cd ../ns2 && $SHELL sign.sh )
cp "../ns2/dsset-example." .
ksk=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone .)
cp root.db.in root.db
"$SIGNER" -Sgz -f root.db -o . root.db.in > /dev/null 2>&1
keyfile_to_key_id "$ksk" > keyid
grep -Ev '^;' < "$ksk.key" | cut -f 7- -d ' ' > keydata
keyfile_to_initial_keys "$ksk" > anchor.dnskey

View file

@ -20,4 +20,4 @@ copy_setports ns1/named.conf.in ns1/named.conf
copy_setports ns2/named.conf.in ns2/named.conf
copy_setports ns3/named.conf.in ns3/named.conf
cd ns2 && $SHELL sign.sh
cd ns1 && $SHELL sign.sh

View file

@ -54,7 +54,7 @@ check_ttl_range() {
return $result
}
# using delv insecure mode as not testing dnssec here
# use delv insecure mode by default, as we're mostly not testing dnssec
delv_with_opts() {
"$DELV" +noroot -p "$PORT" "$@"
}
@ -1404,6 +1404,42 @@ if [ -x "$DELV" ] ; then
if [ $ret -ne 0 ]; then echo_i "failed"; fi
status=$((status+ret))
n=$((n+1))
echo_i "checking delv +ns (no validation) ($n)"
ret=0
delv_with_opts -i +ns +hint=../common/root.hint a a.example > delv.out.test$n || ret=1
grep -q '; authoritative' delv.out.test$n || ret=1
grep -q '_.example' delv.out.test$n && ret=1
if [ $ret -ne 0 ]; then echo_i "failed"; fi
status=$((status+ret))
n=$((n+1))
echo_i "checking delv +ns +qmin (no validation) ($n)"
ret=0
delv_with_opts -i +ns +qmin +hint=../common/root.hint a a.example > delv.out.test$n || ret=1
grep -q '; authoritative' delv.out.test$n || ret=1
grep -q '_.example' delv.out.test$n || ret=1
if [ $ret -ne 0 ]; then echo_i "failed"; fi
status=$((status+ret))
n=$((n+1))
echo_i "checking delv +ns (with validation) ($n)"
ret=0
delv_with_opts -a ns1/anchor.dnskey +root +ns +hint=../common/root.hint a a.example > delv.out.test$n || ret=1
grep -q '; fully validated' delv.out.test$n || ret=1
grep -q '_.example' delv.out.test$n && ret=1
if [ $ret -ne 0 ]; then echo_i "failed"; fi
status=$((status+ret))
n=$((n+1))
echo_i "checking delv +ns +qmin (with validation) ($n)"
ret=0
delv_with_opts -a ns1/anchor.dnskey +root +ns +qmin +hint=../common/root.hint a a.example > delv.out.test$n || ret=1
grep -q '; fully validated' delv.out.test$n || ret=1
grep -q '_.example' delv.out.test$n || ret=1
if [ $ret -ne 0 ]; then echo_i "failed"; fi
status=$((status+ret))
else
echo_i "$DELV is needed, so skipping these delv tests"
fi

View file

@ -23,6 +23,17 @@ New Features
- BIND now depends on ``liburcu``, Userspace RCU, for lock-free data
structures. :gl:`#3934`
- The new ``delv +ns`` option activates name server mode, in which ``delv``
sets up an internal recursive resolver and uses that, rather than an
external server, to look up the requested query name and type. All messages
sent and received during the resolution and validation process are logged.
This can be used in place of ``dig +trace``: it more accurately
reproduces the behavior of ``named`` when resolving a query.
The log message ``resolver priming query complete`` was moved from the
INFO log level to the DEBUG(1) log level, to prevent ``delv`` from
emitting that message when setting up its internal resolver. :gl:`#3842`
Removed Features
~~~~~~~~~~~~~~~~

View file

@ -1074,45 +1074,8 @@ isc_result_t
dns_client_addtrustedkey(dns_client_t *client, dns_rdataclass_t rdclass,
dns_rdatatype_t rdtype, const dns_name_t *keyname,
isc_buffer_t *databuf) {
isc_result_t result;
dns_keytable_t *secroots = NULL;
dns_name_t *name = NULL;
char rdatabuf[DST_KEY_MAXSIZE];
unsigned char digest[ISC_MAX_MD_SIZE];
dns_rdata_ds_t ds;
dns_rdata_t rdata;
isc_buffer_t b;
REQUIRE(DNS_CLIENT_VALID(client));
REQUIRE(rdclass == dns_rdataclass_in);
CHECK(dns_view_getsecroots(client->view, &secroots));
DE_CONST(keyname, name);
if (rdtype != dns_rdatatype_dnskey && rdtype != dns_rdatatype_ds) {
result = ISC_R_NOTIMPLEMENTED;
goto cleanup;
}
isc_buffer_init(&b, rdatabuf, sizeof(rdatabuf));
dns_rdata_init(&rdata);
isc_buffer_setactive(databuf, isc_buffer_usedlength(databuf));
CHECK(dns_rdata_fromwire(&rdata, rdclass, rdtype, databuf,
DNS_DECOMPRESS_NEVER, &b));
if (rdtype == dns_rdatatype_ds) {
CHECK(dns_rdata_tostruct(&rdata, &ds, NULL));
} else {
CHECK(dns_ds_fromkeyrdata(name, &rdata, DNS_DSDIGEST_SHA256,
digest, &ds));
}
CHECK(dns_keytable_add(secroots, false, false, name, &ds, NULL, NULL));
cleanup:
if (secroots != NULL) {
dns_keytable_detach(&secroots);
}
return (result);
return (dns_view_addtrustedkey(client->view, rdtype, keyname, databuf));
}

View file

@ -279,10 +279,11 @@ dns_client_addtrustedkey(dns_client_t *client, dns_rdataclass_t rdclass,
dns_rdatatype_t rdtype, const dns_name_t *keyname,
isc_buffer_t *keydatabuf);
/*%<
* Add a DNSSEC trusted key for the 'rdclass' class. A view for the 'rdclass'
* class must be created beforehand. 'rdtype' is the type of the RR data
* for the key, either DNSKEY or DS. 'keyname' is the DNS name of the key,
* and 'keydatabuf' stores the RR data.
* Add a DNSSEC trusted key for the 'rdclass' class (only class 'IN' is
* currently supported). A view for the 'rdclass' class must be created
* beforehand. 'rdtype' is the type of the RR data for the key, either
* DNSKEY or DS. 'keyname' is the DNS name of the key, and 'keydatabuf'
* stores the RR data.
*
* Requires:
*

View file

@ -1262,4 +1262,29 @@ dns_view_getdispatchmgr(dns_view_t *view);
* by the resolver and request managers to send and receive DNS
* messages.
*/
isc_result_t
dns_view_addtrustedkey(dns_view_t *view, dns_rdatatype_t rdtype,
const dns_name_t *keyname, isc_buffer_t *databuf);
/*%<
* Add a DNSSEC trusted key to a view of class 'IN'. 'rdtype' is the type
* of the RR data for the key, either DNSKEY or DS. 'keyname' is the DNS
* name of the key, and 'databuf' stores the RR data.
* Requires:
*
*\li 'view' is a valid view.
*\li 'view' is class 'IN'.
*
*\li 'keyname' is a valid name.
*
*\li 'keydatabuf' is a valid buffer.
*
* Returns:
*
*\li #ISC_R_SUCCESS On success.
*
*\li Anything else Failure.
*/
ISC_LANG_ENDDECLS

View file

@ -921,7 +921,7 @@ req_connected(isc_result_t eresult, isc_region_t *region, void *arg) {
req_send(request);
} else {
request_cancel(request);
req_sendevent(request, ISC_R_CANCELED);
req_sendevent(request, eresult);
}
UNLOCK(&request->requestmgr->locks[request->hash]);

View file

@ -9974,7 +9974,7 @@ prime_done(void *arg) {
REQUIRE(VALID_RESOLVER(res));
isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO,
DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(1),
"resolver priming query complete: %s",
isc_result_totext(resp->result));

View file

@ -26,6 +26,7 @@
#include <isc/file.h>
#include <isc/hash.h>
#include <isc/lex.h>
#include <isc/md.h>
#include <isc/result.h>
#include <isc/stats.h>
#include <isc/string.h>
@ -2323,3 +2324,44 @@ dns_view_getdispatchmgr(dns_view_t *view) {
REQUIRE(DNS_VIEW_VALID(view));
return (view->dispatchmgr);
}
isc_result_t
dns_view_addtrustedkey(dns_view_t *view, dns_rdatatype_t rdtype,
const dns_name_t *keyname, isc_buffer_t *databuf) {
isc_result_t result;
dns_name_t *name = NULL;
char rdatabuf[DST_KEY_MAXSIZE];
unsigned char digest[ISC_MAX_MD_SIZE];
dns_rdata_ds_t ds;
dns_rdata_t rdata;
isc_buffer_t b;
REQUIRE(DNS_VIEW_VALID(view));
REQUIRE(view->rdclass == dns_rdataclass_in);
DE_CONST(keyname, name);
if (rdtype != dns_rdatatype_dnskey && rdtype != dns_rdatatype_ds) {
result = ISC_R_NOTIMPLEMENTED;
goto cleanup;
}
isc_buffer_init(&b, rdatabuf, sizeof(rdatabuf));
dns_rdata_init(&rdata);
isc_buffer_setactive(databuf, isc_buffer_usedlength(databuf));
CHECK(dns_rdata_fromwire(&rdata, view->rdclass, rdtype, databuf,
DNS_DECOMPRESS_NEVER, &b));
if (rdtype == dns_rdatatype_ds) {
CHECK(dns_rdata_tostruct(&rdata, &ds, NULL));
} else {
CHECK(dns_ds_fromkeyrdata(name, &rdata, DNS_DSDIGEST_SHA256,
digest, &ds));
}
CHECK(dns_keytable_add(view->secroots_priv, false, false, name, &ds,
NULL, NULL));
cleanup:
return (result);
}

View file

@ -729,3 +729,9 @@ isc_nmhandle_set_tcp_nodelay(isc_nmhandle_t *handle, const bool value);
*
* \li 'handle' is a valid netmgr handle object.
*/
isc_sockaddr_t
isc_nmsocket_getaddr(isc_nmsocket_t *sock);
/*%<
* Return the local address of 'sock'.
*/

View file

@ -479,7 +479,6 @@ struct isc_nmsocket {
isc_nmsocket_type type;
isc__networker_t *worker;
isc_mutex_t lock;
isc_barrier_t listen_barrier;
isc_barrier_t stop_barrier;

View file

@ -2538,6 +2538,12 @@ isc_nmhandle_set_tcp_nodelay(isc_nmhandle_t *handle, const bool value) {
return (result);
}
isc_sockaddr_t
isc_nmsocket_getaddr(isc_nmsocket_t *sock) {
REQUIRE(VALID_NMSOCK(sock));
return (sock->iface);
}
#if ISC_NETMGR_TRACE
/*
* Dump all active sockets in netmgr. We output to stderr

View file

@ -748,6 +748,11 @@ isc_nm_listenstreamdns(isc_nm_t *mgr, uint32_t workers, isc_sockaddr_t *iface,
return (result);
}
/* copy the actual port we're listening on into sock->iface */
if (isc_sockaddr_getport(iface) == 0) {
listener->iface = listener->outer->iface;
}
listener->result = result;
atomic_store(&listener->active, true);
atomic_store(&listener->listening, true);

View file

@ -350,10 +350,10 @@ start_tcp_child_job(void *arg) {
REQUIRE(sock->tid == isc_tid());
sa_family_t sa_family = sock->iface.type.sa.sa_family;
int r;
int flags = 0;
int r, flags = 0;
isc_result_t result = ISC_R_UNSET;
isc_loop_t *loop = sock->worker->loop;
struct sockaddr_storage ss;
(void)isc__nm_socket_min_mtu(sock->fd, sa_family);
(void)isc__nm_socket_tcp_maxseg(sock->fd, NM_MAXSEG);
@ -418,8 +418,25 @@ start_tcp_child_job(void *arg) {
atomic_store(&sock->listening, true);
if (sock->tid == 0) {
r = uv_tcp_getsockname(&sock->uv_handle.tcp,
(struct sockaddr *)&ss,
&(int){ sizeof(ss) });
if (r != 0) {
goto done;
}
result = isc_sockaddr_fromsockaddr(&sock->parent->iface,
(struct sockaddr *)&ss);
if (result != ISC_R_SUCCESS) {
goto done_result;
}
}
done:
result = isc_uverr2result(r);
done_result:
atomic_fetch_add(&sock->parent->rchildren, 1);
if (result != ISC_R_SUCCESS) {

View file

@ -937,6 +937,11 @@ isc_nm_listentls(isc_nm_t *mgr, uint32_t workers, isc_sockaddr_t *iface,
return (result);
}
/* copy the actual port we're listening on into sock->iface */
if (isc_sockaddr_getport(iface) == 0) {
tlssock->iface = tlssock->outer->iface;
}
/* wait for listen result */
isc__nmsocket_attach(tlssock->outer, &tsock);
tlssock->result = result;

View file

@ -491,9 +491,9 @@ isc_sockaddr_fromsockaddr(isc_sockaddr_t *isa, const struct sockaddr *sa) {
return (ISC_R_NOTIMPLEMENTED);
}
memset(isa, 0, sizeof(isc_sockaddr_t));
*isa = (isc_sockaddr_t){ .length = length,
.link = ISC_LINK_INITIALIZER };
memmove(isa, sa, length);
isa->length = length;
return (ISC_R_SUCCESS);
}

View file

@ -1680,8 +1680,8 @@ ns__client_put_cb(void *client0) {
* or tcpmsg (TCP case).
*/
void
ns__client_request(isc_nmhandle_t *handle, isc_result_t eresult,
isc_region_t *region, void *arg) {
ns_client_request(isc_nmhandle_t *handle, isc_result_t eresult,
isc_region_t *region, void *arg) {
ns_client_t *client = NULL;
isc_result_t result;
isc_result_t sigresult = ISC_R_SUCCESS;

View file

@ -445,8 +445,8 @@ ns_client_addopt(ns_client_t *client, dns_message_t *message,
*/
void
ns__client_request(isc_nmhandle_t *handle, isc_result_t eresult,
isc_region_t *region, void *arg);
ns_client_request(isc_nmhandle_t *handle, isc_result_t eresult,
isc_region_t *region, void *arg);
/*%<
* Handle client requests.

View file

@ -193,3 +193,11 @@ ns_interfacemgr_dynamic_updates_are_reliable(void);
* disabled. That is the case on the platforms where kernel-based
* mechanisms for tracking networking interface states is reliable enough.
*/
void
ns_interface_create(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr,
const char *name, ns_interface_t **ifpret);
/*%<
* Create an interface 'name' associated with address 'addr'. If
* 'name' is NULL then it is set to "default".
*/

View file

@ -443,16 +443,20 @@ ns_interfacemgr_shutdown(ns_interfacemgr_t *mgr) {
}
}
static void
interface_create(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr, const char *name,
ns_interface_t **ifpret) {
void
ns_interface_create(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr,
const char *name, ns_interface_t **ifpret) {
ns_interface_t *ifp = NULL;
const char *default_name = "default";
REQUIRE(NS_INTERFACEMGR_VALID(mgr));
ifp = isc_mem_get(mgr->mctx, sizeof(*ifp));
*ifp = (ns_interface_t){ .generation = mgr->generation, .addr = *addr };
if (name == NULL) {
name = default_name;
}
strlcpy(ifp->name, name, sizeof(ifp->name));
isc_mutex_init(&ifp->lock);
@ -478,7 +482,7 @@ ns_interface_listenudp(ns_interface_t *ifp) {
/* Reserve space for an ns_client_t with the netmgr handle */
result = isc_nm_listenudp(ifp->mgr->nm, ISC_NM_LISTEN_ALL, &ifp->addr,
ns__client_request, ifp,
ns_client_request, ifp,
&ifp->udplistensocket);
return (result);
}
@ -488,7 +492,7 @@ ns_interface_listentcp(ns_interface_t *ifp) {
isc_result_t result;
result = isc_nm_listenstreamdns(
ifp->mgr->nm, ISC_NM_LISTEN_ALL, &ifp->addr, ns__client_request,
ifp->mgr->nm, ISC_NM_LISTEN_ALL, &ifp->addr, ns_client_request,
ifp, ns__client_tcpconn, ifp, ifp->mgr->backlog,
&ifp->mgr->sctx->tcpquota, NULL, &ifp->tcplistensocket);
if (result != ISC_R_SUCCESS) {
@ -521,7 +525,7 @@ ns_interface_listentls(ns_interface_t *ifp, isc_tlsctx_t *sslctx) {
isc_result_t result;
result = isc_nm_listenstreamdns(
ifp->mgr->nm, ISC_NM_LISTEN_ALL, &ifp->addr, ns__client_request,
ifp->mgr->nm, ISC_NM_LISTEN_ALL, &ifp->addr, ns_client_request,
ifp, ns__client_tcpconn, ifp, ifp->mgr->backlog,
&ifp->mgr->sctx->tcpquota, sslctx, &ifp->tcplistensocket);
@ -555,7 +559,7 @@ load_http_endpoints(isc_nm_http_endpoints_t *epset, ns_interface_t *ifp,
for (size_t i = 0; i < neps; i++) {
result = isc_nm_http_endpoints_add(epset, eps[i],
ns__client_request, ifp);
ns_client_request, ifp);
if (result != ISC_R_SUCCESS) {
break;
}
@ -651,7 +655,7 @@ interface_setup(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr, const char *name,
ifp = *ifpret;
if (ifp == NULL) {
interface_create(mgr, addr, name, &ifp);
ns_interface_create(mgr, addr, name, &ifp);
} else {
REQUIRE(!LISTENING(ifp));
}
@ -1193,8 +1197,8 @@ do_scan(ns_interfacemgr_t *mgr, bool verbose, bool config) {
mgr->aclenv, &match, NULL);
if (match <= 0) {
ns_interface_t *new = NULL;
interface_create(mgr, &listen_sockaddr,
interface.name, &new);
ns_interface_create(mgr, &listen_sockaddr,
interface.name, &new);
continue;
}

View file

@ -456,7 +456,7 @@ ns_test_qctx_create(const ns_test_qctx_create_params_t *params,
/*
* Allow recursion for the client. As NS_CLIENTATTR_RA normally gets
* set in ns__client_request(), i.e. earlier than the unit tests hook
* set in ns_client_request(), i.e. earlier than the unit tests hook
* into the call chain, just set it manually.
*/
client->attributes |= NS_CLIENTATTR_RA;

View file

@ -247,19 +247,15 @@ typedef struct {
dns_rdatatype_t qtype; /* QTYPE */
unsigned int qflags; /* query flags */
bool disable_name_checks; /* if set to true, owner
* name
* checks will
* name checks will
* be disabled for the
* view created
* */
* view created
*/
bool recursive_service; /* if set to true, the view
* created will
* have a cache
* database
* attached */
* created will have a cache
* database attached */
const char *auth_zone_origin; /* origin name of the zone
* the
* created view will be
* the created view will be
* authoritative for */
const char *auth_zone_path; /* path to load the
* authoritative