add support for dynamic PTR record
This commit is contained in:
@@ -8,8 +8,11 @@ AM_CPPFLAGS += \
|
||||
|
||||
pkglib_LTLIBRARIES = filter-aaaa.la
|
||||
pkglib_LTLIBRARIES += filter-a.la
|
||||
pkglib_LTLIBRARIES += dynptrr.la
|
||||
|
||||
filter_aaaa_la_SOURCES = filter-aaaa.c
|
||||
filter_a_la_SOURCES = filter-a.c
|
||||
filter_aaaa_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
|
||||
filter_a_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
|
||||
dynptrr_la_SOURCES = dynptrr.c
|
||||
dynptrr_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
|
||||
|
||||
167
bin/plugins/dynptrr.c
Normal file
167
bin/plugins/dynptrr.c
Normal file
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <ns/hooks.h>
|
||||
#include <dns/view.h>
|
||||
#include <dns/rdatalist.h>
|
||||
#include <dns/byaddr.h>
|
||||
|
||||
typedef struct dynptrr dynptrr_t;
|
||||
struct dynptrr {
|
||||
isc_mem_t *mctx;
|
||||
};
|
||||
|
||||
static ns_hookresult_t
|
||||
dynptrr_nxdomain_begin(void *arg, void *cbdata, isc_result_t *resp) {
|
||||
query_ctx_t *qctx = (query_ctx_t *)arg;
|
||||
isc_mem_t *mctx = qctx->client->view->mctx;
|
||||
dynptrr_t *inst = (dynptrr_t *)cbdata;
|
||||
UNUSED(inst);
|
||||
|
||||
*resp = ISC_R_UNSET;
|
||||
if (qctx->type != dns_rdatatype_ptr) {
|
||||
return NS_HOOK_CONTINUE;
|
||||
}
|
||||
isc_log_write(NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_HOOKS,
|
||||
ISC_LOG_DEBUG(1), "dynptrr nxdomain begin");
|
||||
|
||||
dns_message_t *message = qctx->client->message;
|
||||
|
||||
dns_name_t *name = isc_mem_get(mctx, sizeof(*name));
|
||||
dns_rdataset_t *synth = NULL;
|
||||
dns_rdatalist_t *synthlist = NULL;
|
||||
dns_rdata_t *synthdata = NULL;
|
||||
|
||||
dns_name_init(name);
|
||||
dns_name_dup(qctx->client->query.qname, mctx, name);
|
||||
char n[512];
|
||||
dns_name_format(name, n, 512);
|
||||
isc_log_write(NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_HOOKS,
|
||||
ISC_LOG_DEBUG(1), "dynptrr %s", n);
|
||||
|
||||
dns_message_gettemprdataset(message, &synth);
|
||||
dns_rdataset_init(synth);
|
||||
synth->ttl = 60;
|
||||
synth->rdclass = dns_rdataclass_in;
|
||||
synth->type = dns_rdatatype_ptr;
|
||||
|
||||
dns_message_gettemprdatalist(message, &synthlist);
|
||||
dns_rdatalist_init(synthlist);
|
||||
synthlist->ttl = 60;
|
||||
synthlist->rdclass = dns_rdataclass_in;
|
||||
synthlist->type = dns_rdatatype_ptr;
|
||||
|
||||
dns_message_gettemprdata(message, &synthdata);
|
||||
dns_rdata_init(synthdata);
|
||||
synthdata->rdclass = dns_rdataclass_in;
|
||||
synthdata->type = dns_rdatatype_ptr;
|
||||
|
||||
/*
|
||||
* It seems that for a ptr type, the data must be the ndata pointer of a
|
||||
* dns_name_t. (I attempted putting a raw string instead, and it was a
|
||||
* crash)
|
||||
*/
|
||||
synthdata->data = name->ndata;
|
||||
synthdata->length = name->length;
|
||||
|
||||
ISC_LIST_APPEND(synthlist->rdata, synthdata, link);
|
||||
|
||||
dns_rdatalist_tordataset(synthlist, synth);
|
||||
dns_rdataset_setownercase(synth, name);
|
||||
dns_message_addname(message, name, DNS_SECTION_ANSWER);
|
||||
ISC_LIST_APPEND(name->list, synth, link);
|
||||
|
||||
isc_result_t result = ns_query_done(qctx);
|
||||
*resp = result;
|
||||
|
||||
/* ------------------------------------------------- */
|
||||
|
||||
// isc_netaddr_t peeraddr;
|
||||
// isc_netaddr_fromsockaddr(&peeraddr, &qctx->client->peeraddr);
|
||||
//
|
||||
// char createdptrnamed[512];
|
||||
// isc_buffer_t createdptrnameb;
|
||||
// isc_buffer_init(&createdptrnameb, createdptrnamed, 512);
|
||||
//
|
||||
// dns_name_t *createdptrname = isc_mem_get(mctx, sizeof(*createdptrname));
|
||||
// dns_name_init(createdptrname);
|
||||
// dns_name_setbuffer(createdptrname, &createdptrnameb);
|
||||
// isc_result_t r = dns_byaddr_createptrname(&peeraddr, createdptrname);
|
||||
// isc_log_write(NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_HOOKS,
|
||||
// ISC_LOG_DEBUG(1), "dynptrr %s", isc_result_totext(r));
|
||||
// dns_name_format(createdptrname, n, 512);
|
||||
// isc_log_write(NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_HOOKS,
|
||||
// ISC_LOG_DEBUG(1), "dynptrr ptr %s", n);
|
||||
// isc_mem_put(mctx, createdptrname, sizeof(*createdptrname));
|
||||
//
|
||||
/* ------------------------------------------------- */
|
||||
|
||||
return NS_HOOK_RETURN;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
plugin_destroy(void **instp) {
|
||||
REQUIRE(instp && *instp);
|
||||
|
||||
dynptrr_t *inst = *instp;
|
||||
isc_mem_t *mctx = inst->mctx;
|
||||
isc_mem_put(mctx, inst, sizeof(*inst));
|
||||
*instp = NULL;
|
||||
|
||||
printf("dynptrr plugin_destroy\n");
|
||||
}
|
||||
|
||||
int
|
||||
plugin_version(void) {
|
||||
printf("dynptrr plugin_version\n");
|
||||
return NS_PLUGIN_VERSION;
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
plugin_register(const char *parameters, const void *cfg, const char *cfg_file,
|
||||
unsigned long cfg_line, isc_mem_t *mctx, void *actx,
|
||||
ns_hooktable_t *hooktable, void **instp) {
|
||||
REQUIRE(cfg);
|
||||
REQUIRE(mctx);
|
||||
REQUIRE(actx);
|
||||
REQUIRE(hooktable);
|
||||
REQUIRE(instp && *instp == NULL);
|
||||
|
||||
printf("dynptrr plugin_register %s %s %ld\n", parameters, cfg_file,
|
||||
cfg_line);
|
||||
|
||||
dynptrr_t *inst = isc_mem_get(mctx, sizeof(*inst));
|
||||
*inst = (dynptrr_t){ .mctx = mctx };
|
||||
*instp = inst;
|
||||
|
||||
const ns_hook_t testhook = {
|
||||
.action = dynptrr_nxdomain_begin,
|
||||
.action_data = inst
|
||||
};
|
||||
ns_hook_add(hooktable, mctx, NS_QUERY_NXDOMAIN_BEGIN, &testhook);
|
||||
|
||||
return ISC_R_SUCCESS;
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
plugin_check(const char *parameters, const void *cfg, const char *cfg_file,
|
||||
unsigned long cfg_line, isc_mem_t *mctx, void *actx) {
|
||||
REQUIRE(cfg);
|
||||
REQUIRE(mctx);
|
||||
REQUIRE(actx);
|
||||
|
||||
printf("dynptrr plugin_check %s %s %ld\n", parameters, cfg_file,
|
||||
cfg_line);
|
||||
return ISC_R_SUCCESS;
|
||||
}
|
||||
3
bin/tests/system/dynptrr/.gitignore
vendored
Normal file
3
bin/tests/system/dynptrr/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
named.conf
|
||||
named.memstats
|
||||
named.run
|
||||
25
bin/tests/system/dynptrr/ns1/example.db
Normal file
25
bin/tests/system/dynptrr/ns1/example.db
Normal file
@@ -0,0 +1,25 @@
|
||||
; 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.
|
||||
|
||||
$TTL 120
|
||||
@ SOA ns.example. hostmaster.ns.example. ( 1 3600 1200 604800 60 )
|
||||
@ NS ns
|
||||
@ MX 10 mx
|
||||
|
||||
ns A 10.53.0.1
|
||||
AAAA fd92:7065:b8e:ffff::1
|
||||
|
||||
a-only NS 1.0.0.4
|
||||
aaaa-only AAAA 2001:db8::5
|
||||
dual A 1.0.0.6
|
||||
dual AAAA 2001:db8::6
|
||||
mx A 1.0.0.3
|
||||
mx AAAA 2001:db8::3
|
||||
37
bin/tests/system/dynptrr/ns1/named.conf.in
Normal file
37
bin/tests/system/dynptrr/ns1/named.conf.in
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
options {
|
||||
query-source address 10.53.0.1;
|
||||
port @PORT@;
|
||||
pid-file "named.pid";
|
||||
listen-on { 10.53.0.1; };
|
||||
listen-on-v6 { fd92:7065:b8e:ffff::1; };
|
||||
recursion no;
|
||||
};
|
||||
|
||||
plugin query "../../../../plugins/.libs/dynptrr.so" {
|
||||
};
|
||||
|
||||
key rndc_key {
|
||||
secret "1234abcd8765";
|
||||
algorithm @DEFAULT_HMAC@;
|
||||
};
|
||||
|
||||
controls {
|
||||
inet 10.53.0.1 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
|
||||
};
|
||||
|
||||
|
||||
zone "." { type primary; file "root.db"; };
|
||||
zone "example" { type primary; file "example.db"; };
|
||||
23
bin/tests/system/dynptrr/ns1/root.db
Normal file
23
bin/tests/system/dynptrr/ns1/root.db
Normal file
@@ -0,0 +1,23 @@
|
||||
; 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.
|
||||
|
||||
$TTL 120
|
||||
@ SOA ns.utld hostmaster.ns.utld ( 1 3600 1200 604800 60 )
|
||||
@ NS ns.utld
|
||||
ns.utld A 10.53.0.1
|
||||
ns.utld AAAA fd92:7065:b8e:ffff::1
|
||||
;
|
||||
|
||||
example NS ns.example
|
||||
ns.example A 10.53.0.1
|
||||
ns.example AAAA fd92:7065:b8e:ffff::1
|
||||
|
||||
10.53.0.1 PTR ns.example
|
||||
16
bin/tests/system/dynptrr/setup.sh
Normal file
16
bin/tests/system/dynptrr/setup.sh
Normal file
@@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
|
||||
# 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.
|
||||
|
||||
. ../conf.sh
|
||||
|
||||
copy_setports ns1/named.conf.in ns1/named.conf
|
||||
49
bin/tests/system/dynptrr/tests.sh
Normal file
49
bin/tests/system/dynptrr/tests.sh
Normal file
@@ -0,0 +1,49 @@
|
||||
#!/bin/sh
|
||||
|
||||
# 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.
|
||||
|
||||
set -e
|
||||
|
||||
. ../conf.sh
|
||||
|
||||
status=0
|
||||
n=0
|
||||
|
||||
rm -f dig.out.*
|
||||
|
||||
dig_with_opts() {
|
||||
"${DIG}" -p "${PORT}" "${@}"
|
||||
}
|
||||
|
||||
|
||||
n=$((n + 1))
|
||||
echo_i "PTR exists, dynptrr hook is not run ($n)"
|
||||
ret=0
|
||||
dig_with_opts ptr 10.53.0.1 @10.53.0.1 >dig.out.ns1.test$n || ret=1
|
||||
grep "status: NOERROR" dig.out.ns1.test${n} >/dev/null || ret=1
|
||||
grep "ns.example" dig.out.ns1.test$n >/dev/null || ret=1
|
||||
grep "dynptrr nxdomain begin" ns1/named.run && ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=$((status + ret))
|
||||
|
||||
n=$((n + 1))
|
||||
echo_i "PTR does not exists, dynptrr hook is run ($n)"
|
||||
ret=0
|
||||
dig_with_opts ptr 10.53.0.2 @10.53.0.1 >dig.out.ns1.test$n || ret=1
|
||||
grep "status: NXDOMAIN" dig.out.ns1.test${n} >/dev/null || ret=1
|
||||
grep "dynptrr nxdomain begin" ns1/named.run || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=$((status + ret))
|
||||
|
||||
exit 1
|
||||
echo_i "exit status: $status"
|
||||
[ $status -eq 0 ] || exit 1
|
||||
23
bin/tests/system/dynptrr/tests_sh_dynptrr.py
Normal file
23
bin/tests/system/dynptrr/tests_sh_dynptrr.py
Normal file
@@ -0,0 +1,23 @@
|
||||
# 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.
|
||||
|
||||
import pytest
|
||||
|
||||
pytestmark = pytest.mark.extra_artifacts(
|
||||
[
|
||||
"managed-keys.bind.jnl",
|
||||
"dig.out.*",
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
def test_dynptrr(run_tests_sh):
|
||||
run_tests_sh()
|
||||
Reference in New Issue
Block a user