Compare commits

...
45 Commits
Author SHA1 Message Date
Philip Homburg 4d384333ae Switch from SVCB to IDELEG(65280) 2025-01-17 15:31:51 +01:00
jessevz c3c54f04b4 Cleaned up the code 2024-07-12 15:05:12 +02:00
jessevz fe919666ac Fixed memory error 2024-07-12 10:34:03 +02:00
jessevz 35847e3be1 added _deleg query to apex to check if deleg capable 2024-06-20 16:21:36 +02:00
jessevz 6fe6f673ad Fixed bug where lame delegation was returned 2024-06-20 12:46:03 +02:00
jessevz c6ce5d9652 Works now for every situation 2024-06-19 16:02:38 +02:00
jessevz b8607195b0 Can now query for stuff that is not at apex 2024-06-19 14:35:09 +02:00
jessevz 98b899608e made deleg work with all resource records (not only A records) 2024-06-19 12:28:44 +02:00
jessevz 8f51ec4ce2 made _deleg work when multiple _deleg domains need to be tracked 2024-06-18 15:54:54 +02:00
jessevz d050ff923e rewrote some logic 2024-06-13 11:41:04 +02:00
jessevz 3c347e345c changed malloc to regional allocs 2024-06-13 10:40:03 +02:00
jessevz 42b7ce9c41 Made a first rough working version for _deleg 2024-06-13 10:04:37 +02:00
jessevz 011c5a0e0f Made it possible to change queries into _deleg queries 2024-06-12 09:26:32 +02:00
W.C.A. Wijngaards 86fe9cbce5 - Fix to squelch connection reset by peer errors from log. And fix
that the tcp read errors are labeled as initial for the first calls.
2024-06-03 12:14:51 +02:00
W.C.A. Wijngaards 4b30e88eec - Fix for #1079: fix RPZ taglist in iterator callback that no client
info is like no taglist intersection.
2024-05-30 12:44:26 +02:00
W.C.A. Wijngaards b6c7ea563f - Fix #1079: tags from tagged rpz zones are no longer honored after
upgrade from 1.19.3 to 1.20.0.
2024-05-30 12:11:30 +02:00
W.C.A. Wijngaards 910d7cf446 Changelog note for #1078.
- Merge #1078: Only check old pid if no username.
2024-05-29 14:45:01 +02:00
Wouter WijngaardsandGitHub cd485f2036 Merge pull request #1078 from vopatek/master
Only check old pid if no username
2024-05-29 14:44:31 +02:00
Martin Vopatek 8ff1baf585 Only check old pid if no username
Do as the comment says and only check old pid if there is no username
configured.
2024-05-29 14:16:18 +02:00
Yorgos Thessalonikefs 5fc4673901 - Update patch to remove 'command' shell builtin and update error
text.
2024-05-27 17:17:48 +02:00
Michael TokarevandYorgos Thessalonikefs faf3d358dc unbound-control-setup: check openssl
Before doing anything, check if openssl binary (which we will use)
is available, and print a useful error message if it is not found.
2024-05-27 16:35:34 +02:00
Yorgos Thessalonikefs f5a2160ba3 - Fix unused variable warning on compilation with no thread support. 2024-05-27 14:56:52 +02:00
W.C.A. Wijngaards 0c0c36f015 - Fix spelling of tcp-idle-timeout docs, from Michael Tokarev. 2024-05-27 14:36:35 +02:00
W.C.A. Wijngaards 47956de897 - Fix to enable that SERVFAIL is cached, for a short period, for more
cases. In the cases where limits are exceeded.
2024-05-27 13:53:16 +02:00
Yorgos Thessalonikefs b30c869a59 Changelog entry for #1059:
- Fix #1059: Intermittent DNS blocking failure with local-zone and
  always_nxdomain. Addition of local_zones dynamically via
  unbound-control was not finding the zone's parent correctly.
2024-05-24 15:24:52 +02:00
Yorgos ThessalonikefsandGitHub 6f030e9672 Proper parent identification for dynamically entered local zones (#1076)
- Fix #1059: Intermittent DNS blocking failure with local-zone and
  always_nxdomain. Addition of local_zones dynamically via
  unbound-control was not finding the zone's parent correctly.
2024-05-24 15:21:40 +02:00
W.C.A. Wijngaards 7107d3c9e7 - Fix #1064: Unbound 1.20 Cachedb broken?
Add unit test for validation status commit.
2024-05-24 09:06:48 +02:00
W.C.A. Wijngaards fbdc06ebc4 - Fix for #1064: Fix that cachedb expired messages are considered
insecure, and thus can be served to clients when dnssec is enabled.
2024-05-21 17:06:18 +02:00
W.C.A. Wijngaards d149e755fd - Fix for parse end of forward-zone, stub-zone and view. 2024-05-21 12:04:57 +02:00
W.C.A. Wijngaards 86ee8ccd12 - Fix to print a parse error when config is read with no name for
a forward-zone, stub-zone or view.
2024-05-21 11:54:18 +02:00
W.C.A. Wijngaards 8d6a1ba811 Changelog note for #1073.
- Merge #1073: fix null pointer dereference issue in function
  ub_ctx_set_fwd.
2024-05-21 11:52:47 +02:00
Wouter WijngaardsandGitHub 9ccb8d5f20 Merge pull request #1073 from xiaoxiaoafeifei/master
fix null pointer dereference issue in function ub_ctx_set_fwd
2024-05-21 11:51:52 +02:00
zhailiangliang 8e43e2574c fix null pointer dereference issue in function ub_ctx_set_fwd of file libunbound/libunbound.c 2024-05-21 08:40:35 +00:00
Yorgos Thessalonikefs 2e70506763 Changelog entry for #1069:
- Merge #1069: Fix unbound-control stdin commands for multi-process
  Unbounds.
2024-05-17 10:31:20 +02:00
7f184c8ca8 Fix unbound-control stdin commands for multi-process Unbounds (#1069)
- Fix unbound-control commands that read stdin in multi-process
  operation (local_zones_remove, local_zones, local_datas_remove,
  local_datas, view_local_datas_remove, view_local_datas). They will
  be properly distributed to all processes. dump_cache and load_cache
  are no longer supported in multi-process operation.

 - Remove testdata/remote-threaded.tdir. testdata/09-unbound-control.tdir
  now checks both single and multi process/thread operation.

---------

Co-authored-by: Wouter Wijngaards <wcawijngaards@users.noreply.github.com>
2024-05-17 10:25:24 +02:00
W.C.A. Wijngaards da2b307aa3 - Fix #1071: [FR] Clear both in-memory and cachedb module cache with
`unbound-control flush*` commands.
2024-05-16 16:56:58 +02:00
Yorgos Thessalonikefs 739a88ceed Changelog entry for #1070:
- Merge #1070: Fix rtt assignement for low values of
  infra-cache-max-rtt.
2024-05-16 13:43:24 +02:00
Yorgos ThessalonikefsandGitHub 3ff5c7a74d Fix rtt assignement for low values of infra-cache-max-rtt (#1070)
* Fix rtt assignement for still useful servers when a low value for
  infra-cache-max-rtt is configured.
2024-05-16 13:42:32 +02:00
Yorgos Thessalonikefs 1048c4a28c - Add missing common functions to tdir tests. 2024-05-15 11:20:36 +02:00
W.C.A. Wijngaards 7de009f99a - Fix when the mesh jostle is exceeded that nameserver targets are
marked as resolved, so that the lookup is not stuck on the
  requestlist.
2024-05-10 09:50:35 +02:00
W.C.A. Wijngaards 95669855fb - Fix to squelch udp connect errors in the log at low verbosity about
invalid argument for IPv6 link local addresses.
2024-05-08 16:40:41 +02:00
W.C.A. Wijngaards 56e7cade28 The code repository continues with version 1.20.1. 2024-05-08 11:10:53 +02:00
W.C.A. Wijngaards c085a53268 - Fix for #1062: declaration before statement, avoid print of null,
and redundant check for array size.
And changelog note for merge of #1062.
2024-05-07 14:05:21 +02:00
Wouter WijngaardsandGitHub 49569b81aa Merge pull request #1062 from xiaoxiaoafeifei/master
Fix potential overflow bug while parsing port in function cfg_mark_ports
2024-05-07 14:02:21 +02:00
zhailiangliang 4497e8a154 Fix potential overflow bug while parsing port in function cfg_mark_ports 2024-05-07 11:35:52 +00:00
59 changed files with 1899 additions and 951 deletions
+32 -23
View File
@@ -322,30 +322,30 @@ error_response(struct module_qstate* qstate, int id, int rcode)
/**
* Hash the query name, type, class and dbacess-secret into lookup buffer.
* @param qstate: query state with query info
* and env->cfg with secret.
* @param qinfo: query info
* @param env: with env->cfg with secret.
* @param buf: returned buffer with hash to lookup
* @param len: length of the buffer.
*/
static void
calc_hash(struct module_qstate* qstate, char* buf, size_t len)
calc_hash(struct query_info* qinfo, struct module_env* env, char* buf,
size_t len)
{
uint8_t clear[1024];
size_t clen = 0;
uint8_t hash[CACHEDB_HASHSIZE/8];
const char* hex = "0123456789ABCDEF";
const char* secret = qstate->env->cfg->cachedb_secret;
const char* secret = env->cfg->cachedb_secret;
size_t i;
/* copy the hash info into the clear buffer */
if(clen + qstate->qinfo.qname_len < sizeof(clear)) {
memmove(clear+clen, qstate->qinfo.qname,
qstate->qinfo.qname_len);
clen += qstate->qinfo.qname_len;
if(clen + qinfo->qname_len < sizeof(clear)) {
memmove(clear+clen, qinfo->qname, qinfo->qname_len);
clen += qinfo->qname_len;
}
if(clen + 4 < sizeof(clear)) {
uint16_t t = htons(qstate->qinfo.qtype);
uint16_t c = htons(qstate->qinfo.qclass);
uint16_t t = htons(qinfo->qtype);
uint16_t c = htons(qinfo->qclass);
memmove(clear+clen, &t, 2);
memmove(clear+clen+2, &c, 2);
clen += 4;
@@ -645,7 +645,7 @@ cachedb_extcache_lookup(struct module_qstate* qstate, struct cachedb_env* ie,
int* msg_expired)
{
char key[(CACHEDB_HASHSIZE/8)*2+1];
calc_hash(qstate, key, sizeof(key));
calc_hash(&qstate->qinfo, qstate->env, key, sizeof(key));
/* call backend to fetch data for key into scratch buffer */
if( !(*ie->backend->lookup)(qstate->env, ie, key,
@@ -672,7 +672,7 @@ static void
cachedb_extcache_store(struct module_qstate* qstate, struct cachedb_env* ie)
{
char key[(CACHEDB_HASHSIZE/8)*2+1];
calc_hash(qstate, key, sizeof(key));
calc_hash(&qstate->qinfo, qstate->env, key, sizeof(key));
/* prepare data in scratch buffer */
if(!prep_data(qstate, qstate->env->scratch_buffer))
@@ -745,6 +745,10 @@ cachedb_intcache_store(struct module_qstate* qstate, int msg_expired)
* going to be now-3 seconds. Making it expired
* in the cache. */
set_msg_ttl(qstate->return_msg, (time_t)-3);
/* The expired entry does not get checked by the validator
* and we need a validation value for it. */
if(qstate->env->cfg->cachedb_check_when_serve_expired)
qstate->return_msg->rep->security = sec_status_insecure;
}
(void)dns_cache_store(qstate->env, &qstate->qinfo,
qstate->return_msg->rep, 0, qstate->prefetch_leeway, 0,
@@ -1004,20 +1008,25 @@ cachedb_is_enabled(struct module_stack* mods, struct module_env* env)
void cachedb_msg_remove(struct module_qstate* qstate)
{
char key[(CACHEDB_HASHSIZE/8)*2+1];
int id = modstack_find(qstate->env->modstack, "cachedb");
struct cachedb_env* ie = (struct cachedb_env*)qstate->env->modinfo[id];
cachedb_msg_remove_qinfo(qstate->env, &qstate->qinfo);
}
log_query_info(VERB_ALGO, "cachedb msg remove", &qstate->qinfo);
calc_hash(qstate, key, sizeof(key));
sldns_buffer_clear(qstate->env->scratch_buffer);
sldns_buffer_write_u32(qstate->env->scratch_buffer, 0);
sldns_buffer_flip(qstate->env->scratch_buffer);
void cachedb_msg_remove_qinfo(struct module_env* env, struct query_info* qinfo)
{
char key[(CACHEDB_HASHSIZE/8)*2+1];
int id = modstack_find(env->modstack, "cachedb");
struct cachedb_env* ie = (struct cachedb_env*)env->modinfo[id];
log_query_info(VERB_ALGO, "cachedb msg remove", qinfo);
calc_hash(qinfo, env, key, sizeof(key));
sldns_buffer_clear(env->scratch_buffer);
sldns_buffer_write_u32(env->scratch_buffer, 0);
sldns_buffer_flip(env->scratch_buffer);
/* call backend */
(*ie->backend->store)(qstate->env, ie, key,
sldns_buffer_begin(qstate->env->scratch_buffer),
sldns_buffer_limit(qstate->env->scratch_buffer),
(*ie->backend->store)(env, ie, key,
sldns_buffer_begin(env->scratch_buffer),
sldns_buffer_limit(env->scratch_buffer),
0);
}
#endif /* USE_CACHEDB */
+8
View File
@@ -126,3 +126,11 @@ int cachedb_is_enabled(struct module_stack* mods, struct module_env* env);
* @param qstate: query state.
*/
void cachedb_msg_remove(struct module_qstate* qstate);
/**
* Remove message from the cachedb cache, by query info.
* @param env: module environment to look up cachedb state.
* @param qinfo: the message to remove.
*/
void cachedb_msg_remove_qinfo(struct module_env* env,
struct query_info* qinfo);
Vendored
+13 -12
View File
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.71 for unbound 1.20.0.
# Generated by GNU Autoconf 2.71 for unbound 1.20.1.
#
# Report bugs to <unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues>.
#
@@ -622,8 +622,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='unbound'
PACKAGE_TARNAME='unbound'
PACKAGE_VERSION='1.20.0'
PACKAGE_STRING='unbound 1.20.0'
PACKAGE_VERSION='1.20.1'
PACKAGE_STRING='unbound 1.20.1'
PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues'
PACKAGE_URL=''
@@ -1508,7 +1508,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures unbound 1.20.0 to adapt to many kinds of systems.
\`configure' configures unbound 1.20.1 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1574,7 +1574,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of unbound 1.20.0:";;
short | recursive ) echo "Configuration of unbound 1.20.1:";;
esac
cat <<\_ACEOF
@@ -1821,7 +1821,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
unbound configure 1.20.0
unbound configure 1.20.1
generated by GNU Autoconf 2.71
Copyright (C) 2021 Free Software Foundation, Inc.
@@ -2478,7 +2478,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by unbound $as_me 1.20.0, which was
It was created by unbound $as_me 1.20.1, which was
generated by GNU Autoconf 2.71. Invocation command line was
$ $0$ac_configure_args_raw
@@ -3242,11 +3242,11 @@ UNBOUND_VERSION_MAJOR=1
UNBOUND_VERSION_MINOR=20
UNBOUND_VERSION_MICRO=0
UNBOUND_VERSION_MICRO=1
LIBUNBOUND_CURRENT=9
LIBUNBOUND_REVISION=27
LIBUNBOUND_REVISION=28
LIBUNBOUND_AGE=1
# 1.0.0 had 0:12:0
# 1.0.1 had 0:13:0
@@ -3341,6 +3341,7 @@ LIBUNBOUND_AGE=1
# 1.19.2 had 9:25:1
# 1.19.3 had 9:26:1
# 1.20.0 had 9:27:1
# 1.20.1 had 9:28:1
# Current -- the number of the binary API that we're implementing
# Revision -- which iteration of the implementation of the binary
@@ -24466,7 +24467,7 @@ printf "%s\n" "#define MAXSYSLOGMSGLEN 10240" >>confdefs.h
version=1.20.0
version=1.20.1
date=`date +'%b %e, %Y'`
@@ -24978,7 +24979,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by unbound $as_me 1.20.0, which was
This file was extended by unbound $as_me 1.20.1, which was
generated by GNU Autoconf 2.71. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -25046,7 +25047,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config='$ac_cs_config_escaped'
ac_cs_version="\\
unbound config.status 1.20.0
unbound config.status 1.20.1
configured by $0, generated by GNU Autoconf 2.71,
with options \\"\$ac_cs_config\\"
+3 -2
View File
@@ -11,14 +11,14 @@ sinclude(dnscrypt/dnscrypt.m4)
# must be numbers. ac_defun because of later processing
m4_define([VERSION_MAJOR],[1])
m4_define([VERSION_MINOR],[20])
m4_define([VERSION_MICRO],[0])
m4_define([VERSION_MICRO],[1])
AC_INIT([unbound],m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]),[unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues],[unbound])
AC_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR])
AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR])
AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO])
LIBUNBOUND_CURRENT=9
LIBUNBOUND_REVISION=27
LIBUNBOUND_REVISION=28
LIBUNBOUND_AGE=1
# 1.0.0 had 0:12:0
# 1.0.1 had 0:13:0
@@ -113,6 +113,7 @@ LIBUNBOUND_AGE=1
# 1.19.2 had 9:25:1
# 1.19.3 had 9:26:1
# 1.20.0 had 9:27:1
# 1.20.1 had 9:28:1
# Current -- the number of the binary API that we're implementing
# Revision -- which iteration of the implementation of the binary
+253 -85
View File
@@ -88,6 +88,9 @@
#include "sldns/wire2str.h"
#include "sldns/sbuffer.h"
#include "util/timeval_func.h"
#ifdef USE_CACHEDB
#include "cachedb/cachedb.h"
#endif
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
@@ -107,6 +110,10 @@
/** what to put on statistics lines between var and value, ": " or "=" */
#define SQ "="
/** Acceptable lengths of str lines */
#define MAX_CMD_STRLINE 1024
#define MAX_STDIN_STRLINE 2048
static int
remote_setup_ctx(struct daemon_remote* rc, struct config_file* cfg)
{
@@ -633,6 +640,25 @@ static void send_ok(RES* ssl)
(void)ssl_printf(ssl, "ok\n");
}
/** tell other processes to execute the command */
static void
distribute_cmd(struct daemon_remote* rc, RES* ssl, char* cmd)
{
int i;
if(!cmd || !ssl)
return;
/* skip i=0 which is me */
for(i=1; i<rc->worker->daemon->num; i++) {
worker_send_cmd(rc->worker->daemon->workers[i],
worker_cmd_remote);
if(!tube_write_msg(rc->worker->daemon->workers[i]->cmd,
(uint8_t*)cmd, strlen(cmd)+1, 0)) {
(void)ssl_printf(ssl, "error could not distribute cmd\n");
return;
}
}
}
/** do the stop command */
static void
do_stop(RES* ssl, struct worker* worker)
@@ -1220,19 +1246,28 @@ do_zone_add(RES* ssl, struct local_zones* zones, char* arg)
/** Do the local_zones command */
static void
do_zones_add(RES* ssl, struct local_zones* zones)
do_zones_add(struct daemon_remote* rc, RES* ssl, struct worker* worker)
{
char buf[2048];
char buf[MAX_CMD_STRLINE + MAX_STDIN_STRLINE] = "local_zone ";
int num = 0;
while(ssl_read_line(ssl, buf, sizeof(buf))) {
if(buf[0] == 0 || (buf[0] == 0x04 && buf[1] == 0))
size_t cmd_len = strlen(buf);
while(ssl_read_line(ssl, buf+cmd_len, MAX_STDIN_STRLINE)) {
if(buf[0+cmd_len] == 0 ||
(buf[0+cmd_len] == 0x04 && buf[1+cmd_len] == 0))
break; /* zero byte line or end of transmission */
if(!perform_zone_add(ssl, zones, buf)) {
if(!ssl_printf(ssl, "error for input line: %s\n", buf))
#ifdef THREADS_DISABLED
/* distribute single item command */
if(rc) distribute_cmd(rc, ssl, buf);
#else
(void)rc; /* unused */
#endif
if(!perform_zone_add(ssl, worker->daemon->local_zones,
buf+cmd_len)) {
if(!ssl_printf(ssl, "error for input line: %s\n",
buf+cmd_len))
return;
}
else
num++;
else num++;
}
(void)ssl_printf(ssl, "added %d zones\n", num);
}
@@ -1269,19 +1304,28 @@ do_zone_remove(RES* ssl, struct local_zones* zones, char* arg)
/** Do the local_zones_remove command */
static void
do_zones_remove(RES* ssl, struct local_zones* zones)
do_zones_remove(struct daemon_remote* rc, RES* ssl, struct worker* worker)
{
char buf[2048];
char buf[MAX_CMD_STRLINE + MAX_STDIN_STRLINE] = "local_zone_remove ";
int num = 0;
while(ssl_read_line(ssl, buf, sizeof(buf))) {
if(buf[0] == 0 || (buf[0] == 0x04 && buf[1] == 0))
size_t cmd_len = strlen(buf);
while(ssl_read_line(ssl, buf+cmd_len, MAX_STDIN_STRLINE)) {
if(buf[0+cmd_len] == 0 ||
(buf[0+cmd_len] == 0x04 && buf[1+cmd_len] == 0))
break; /* zero byte line or end of transmission */
if(!perform_zone_remove(ssl, zones, buf)) {
if(!ssl_printf(ssl, "error for input line: %s\n", buf))
#ifdef THREADS_DISABLED
/* distribute single item command */
if(rc) distribute_cmd(rc, ssl, buf);
#else
(void)rc; /* unused */
#endif
if(!perform_zone_remove(ssl, worker->daemon->local_zones,
buf+cmd_len)) {
if(!ssl_printf(ssl, "error for input line: %s\n",
buf+cmd_len))
return;
}
else
num++;
else num++;
}
(void)ssl_printf(ssl, "removed %d zones\n", num);
}
@@ -1333,15 +1377,24 @@ do_data_add(RES* ssl, struct local_zones* zones, char* arg)
/** Do the local_datas command */
static void
do_datas_add(RES* ssl, struct local_zones* zones)
do_datas_add(struct daemon_remote* rc, RES* ssl, struct worker* worker)
{
char buf[2048];
char buf[MAX_CMD_STRLINE + MAX_STDIN_STRLINE] = "local_data ";
int num = 0, line = 0;
while(ssl_read_line(ssl, buf, sizeof(buf))) {
if(buf[0] == 0 || (buf[0] == 0x04 && buf[1] == 0))
size_t cmd_len = strlen(buf);
while(ssl_read_line(ssl, buf+cmd_len, MAX_STDIN_STRLINE)) {
if(buf[0+cmd_len] == 0 ||
(buf[0+cmd_len] == 0x04 && buf[1+cmd_len] == 0))
break; /* zero byte line or end of transmission */
#ifdef THREADS_DISABLED
/* distribute single item command */
if(rc) distribute_cmd(rc, ssl, buf);
#else
(void)rc; /* unused */
#endif
line++;
if(perform_data_add(ssl, zones, buf, line))
if(perform_data_add(ssl, worker->daemon->local_zones,
buf+cmd_len, line))
num++;
}
(void)ssl_printf(ssl, "added %d datas\n", num);
@@ -1373,19 +1426,28 @@ do_data_remove(RES* ssl, struct local_zones* zones, char* arg)
/** Do the local_datas_remove command */
static void
do_datas_remove(RES* ssl, struct local_zones* zones)
do_datas_remove(struct daemon_remote* rc, RES* ssl, struct worker* worker)
{
char buf[2048];
char buf[MAX_CMD_STRLINE + MAX_STDIN_STRLINE] = "local_data_remove ";
int num = 0;
while(ssl_read_line(ssl, buf, sizeof(buf))) {
if(buf[0] == 0 || (buf[0] == 0x04 && buf[1] == 0))
size_t cmd_len = strlen(buf);
while(ssl_read_line(ssl, buf+cmd_len, MAX_STDIN_STRLINE)) {
if(buf[0+cmd_len] == 0 ||
(buf[0+cmd_len] == 0x04 && buf[1+cmd_len] == 0))
break; /* zero byte line or end of transmission */
if(!perform_data_remove(ssl, zones, buf)) {
if(!ssl_printf(ssl, "error for input line: %s\n", buf))
#ifdef THREADS_DISABLED
/* distribute single item command */
if(rc) distribute_cmd(rc, ssl, buf);
#else
(void)rc; /* unused */
#endif
if(!perform_data_remove(ssl, worker->daemon->local_zones,
buf+cmd_len)) {
if(!ssl_printf(ssl, "error for input line: %s\n",
buf+cmd_len))
return;
}
else
num++;
else num++;
}
(void)ssl_printf(ssl, "removed %d datas\n", num);
}
@@ -1473,9 +1535,13 @@ do_view_data_add(RES* ssl, struct worker* worker, char* arg)
/** Add new RR data from stdin to view */
static void
do_view_datas_add(RES* ssl, struct worker* worker, char* arg)
do_view_datas_add(struct daemon_remote* rc, RES* ssl, struct worker* worker,
char* arg)
{
struct view* v;
char buf[MAX_CMD_STRLINE + MAX_STDIN_STRLINE] = "view_local_data ";
size_t cmd_len;
int num = 0, line = 0;
v = views_find_view(worker->daemon->views,
arg, 1 /* get write lock*/);
if(!v) {
@@ -1489,8 +1555,25 @@ do_view_datas_add(RES* ssl, struct worker* worker, char* arg)
return;
}
}
do_datas_add(ssl, v->local_zones);
/* put the view name in the command buf */
(void)snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), "%s ", arg);
cmd_len = strlen(buf);
while(ssl_read_line(ssl, buf+cmd_len, MAX_STDIN_STRLINE)) {
if(buf[0+cmd_len] == 0 ||
(buf[0+cmd_len] == 0x04 && buf[1+cmd_len] == 0))
break; /* zero byte line or end of transmission */
#ifdef THREADS_DISABLED
/* distribute single item command */
if(rc) distribute_cmd(rc, ssl, buf);
#else
(void)rc; /* unused */
#endif
line++;
if(perform_data_add(ssl, v->local_zones, buf+cmd_len, line))
num++;
}
lock_rw_unlock(&v->lock);
(void)ssl_printf(ssl, "added %d datas\n", num);
}
/** Remove RR data from view */
@@ -1518,9 +1601,13 @@ do_view_data_remove(RES* ssl, struct worker* worker, char* arg)
/** Remove RR data from stdin from view */
static void
do_view_datas_remove(RES* ssl, struct worker* worker, char* arg)
do_view_datas_remove(struct daemon_remote* rc, RES* ssl, struct worker* worker,
char* arg)
{
struct view* v;
char buf[MAX_CMD_STRLINE + MAX_STDIN_STRLINE] = "view_local_data_remove ";
int num = 0;
size_t cmd_len;
v = views_find_view(worker->daemon->views,
arg, 1 /* get write lock*/);
if(!v) {
@@ -1532,9 +1619,28 @@ do_view_datas_remove(RES* ssl, struct worker* worker, char* arg)
ssl_printf(ssl, "removed 0 datas\n");
return;
}
do_datas_remove(ssl, v->local_zones);
/* put the view name in the command buf */
(void)snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), "%s ", arg);
cmd_len = strlen(buf);
while(ssl_read_line(ssl, buf+cmd_len, MAX_STDIN_STRLINE)) {
if(buf[0+cmd_len] == 0 ||
(buf[0+cmd_len] == 0x04 && buf[1+cmd_len] == 0))
break; /* zero byte line or end of transmission */
#ifdef THREADS_DISABLED
/* distribute single item command */
if(rc) distribute_cmd(rc, ssl, buf);
#else
(void)rc; /* unused */
#endif
if(!perform_data_remove(ssl, v->local_zones, buf+cmd_len)) {
if(!ssl_printf(ssl, "error for input line: %s\n",
buf+cmd_len))
return;
}
else num++;
}
lock_rw_unlock(&v->lock);
(void)ssl_printf(ssl, "removed %d datas\n", num);
}
/** cache lookup of nameservers */
@@ -1553,7 +1659,7 @@ do_lookup(RES* ssl, struct worker* worker, char* arg)
/** flush something from rrset and msg caches */
static void
do_cache_remove(struct worker* worker, uint8_t* nm, size_t nmlen,
uint16_t t, uint16_t c)
uint16_t t, uint16_t c, int remcachedb)
{
hashvalue_type h;
struct query_info k;
@@ -1573,6 +1679,27 @@ do_cache_remove(struct worker* worker, uint8_t* nm, size_t nmlen,
h = query_info_hash(&k, BIT_CD);
slabhash_remove(worker->env.msg_cache, h, &k);
}
#ifdef USE_CACHEDB
if(remcachedb && worker->env.cachedb_enabled)
cachedb_msg_remove_qinfo(&worker->env, &k);
#endif
}
/** parse '+c' option, modifies string to return remainder. */
static int
parse_remcachedb(RES* ssl, char** arg, int* pc)
{
*arg = skipwhite(*arg);
if((*arg)[0] == '+' && (*arg)[1] == 'c') {
char* arg2;
*pc = 1;
if(!find_arg2(ssl, *arg, &arg2))
return 0;
*arg = arg2;
return 1;
}
/* The option was not found, no problem */
return 1;
}
/** flush a type */
@@ -1584,15 +1711,20 @@ do_flush_type(RES* ssl, struct worker* worker, char* arg)
size_t nmlen;
char* arg2;
uint16_t t;
int pc = 0; /* '+c' option */
if(!parse_remcachedb(ssl, &arg, &pc))
return;
if(!find_arg2(ssl, arg, &arg2))
return;
if(!parse_arg_name(ssl, arg, &nm, &nmlen, &nmlabs))
return;
t = sldns_get_rr_type_by_name(arg2);
if(t == 0 && strcmp(arg2, "TYPE0") != 0) {
(void)ssl_printf(ssl, "error parsing RRset type: '%s'\n", arg2);
free(nm);
return;
}
do_cache_remove(worker, nm, nmlen, t, LDNS_RR_CLASS_IN);
do_cache_remove(worker, nm, nmlen, t, LDNS_RR_CLASS_IN, pc);
free(nm);
send_ok(ssl);
@@ -1630,6 +1762,8 @@ struct del_info {
socklen_t addrlen;
/** socket address for host deletion */
struct sockaddr_storage addr;
/** if cachedb information should be flushed too */
int remcachedb;
};
/** callback to delete hosts in infra cache */
@@ -1681,6 +1815,7 @@ do_flush_infra(RES* ssl, struct worker* worker, char* arg)
inf.num_msgs = 0;
inf.num_keys = 0;
inf.addrlen = len;
inf.remcachedb = 0;
memmove(&inf.addr, &addr, len);
slabhash_traverse(worker->env.infra_cache->hosts, 1, &infra_del_host,
&inf);
@@ -1727,6 +1862,10 @@ zone_del_msg(struct lruhash_entry* e, void* arg)
d->serve_expired_ttl = inf->expired;
inf->num_msgs++;
}
#ifdef USE_CACHEDB
if(inf->remcachedb && inf->worker->env.cachedb_enabled)
cachedb_msg_remove_qinfo(&inf->worker->env, &k->key);
#endif
}
}
@@ -1754,6 +1893,9 @@ do_flush_zone(RES* ssl, struct worker* worker, char* arg)
int nmlabs;
size_t nmlen;
struct del_info inf;
int pc = 0; /* '+c' option */
if(!parse_remcachedb(ssl, &arg, &pc))
return;
if(!parse_arg_name(ssl, arg, &nm, &nmlen, &nmlabs))
return;
/* delete all RRs and key entries from zone */
@@ -1767,6 +1909,7 @@ do_flush_zone(RES* ssl, struct worker* worker, char* arg)
inf.num_rrsets = 0;
inf.num_msgs = 0;
inf.num_keys = 0;
inf.remcachedb = pc;
slabhash_traverse(&worker->env.rrset_cache->table, 1,
&zone_del_rrset, &inf);
@@ -1808,6 +1951,11 @@ bogus_del_msg(struct lruhash_entry* e, void* arg)
if(d->security == sec_status_bogus) {
d->ttl = inf->expired;
inf->num_msgs++;
#ifdef USE_CACHEDB
if(inf->remcachedb && inf->worker->env.cachedb_enabled)
cachedb_msg_remove_qinfo(&inf->worker->env,
&((struct msgreply_entry*)e->key)->key);
#endif
}
}
@@ -1826,9 +1974,12 @@ bogus_del_kcache(struct lruhash_entry* e, void* arg)
/** remove all bogus rrsets, msgs and keys from cache */
static void
do_flush_bogus(RES* ssl, struct worker* worker)
do_flush_bogus(RES* ssl, struct worker* worker, char* arg)
{
struct del_info inf;
int pc = 0; /* '+c' option */
if(!parse_remcachedb(ssl, &arg, &pc))
return;
/* what we do is to set them all expired */
inf.worker = worker;
inf.expired = *worker->env.now;
@@ -1836,6 +1987,7 @@ do_flush_bogus(RES* ssl, struct worker* worker)
inf.num_rrsets = 0;
inf.num_msgs = 0;
inf.num_keys = 0;
inf.remcachedb = pc;
slabhash_traverse(&worker->env.rrset_cache->table, 1,
&bogus_del_rrset, &inf);
@@ -1881,6 +2033,11 @@ negative_del_msg(struct lruhash_entry* e, void* arg)
if(FLAGS_GET_RCODE(d->flags) != 0 || d->an_numrrsets == 0) {
d->ttl = inf->expired;
inf->num_msgs++;
#ifdef USE_CACHEDB
if(inf->remcachedb && inf->worker->env.cachedb_enabled)
cachedb_msg_remove_qinfo(&inf->worker->env,
&((struct msgreply_entry*)e->key)->key);
#endif
}
}
@@ -1901,9 +2058,12 @@ negative_del_kcache(struct lruhash_entry* e, void* arg)
/** remove all negative(NODATA,NXDOMAIN), and servfail messages from cache */
static void
do_flush_negative(RES* ssl, struct worker* worker)
do_flush_negative(RES* ssl, struct worker* worker, char* arg)
{
struct del_info inf;
int pc = 0; /* '+c' option */
if(!parse_remcachedb(ssl, &arg, &pc))
return;
/* what we do is to set them all expired */
inf.worker = worker;
inf.expired = *worker->env.now;
@@ -1911,6 +2071,7 @@ do_flush_negative(RES* ssl, struct worker* worker)
inf.num_rrsets = 0;
inf.num_msgs = 0;
inf.num_keys = 0;
inf.remcachedb = pc;
slabhash_traverse(&worker->env.rrset_cache->table, 1,
&negative_del_rrset, &inf);
@@ -1934,20 +2095,23 @@ do_flush_name(RES* ssl, struct worker* w, char* arg)
uint8_t* nm;
int nmlabs;
size_t nmlen;
int pc = 0; /* '+c' option */
if(!parse_remcachedb(ssl, &arg, &pc))
return;
if(!parse_arg_name(ssl, arg, &nm, &nmlen, &nmlabs))
return;
do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_A, LDNS_RR_CLASS_IN);
do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_AAAA, LDNS_RR_CLASS_IN);
do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_NS, LDNS_RR_CLASS_IN);
do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_SOA, LDNS_RR_CLASS_IN);
do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_CNAME, LDNS_RR_CLASS_IN);
do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_DNAME, LDNS_RR_CLASS_IN);
do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_MX, LDNS_RR_CLASS_IN);
do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_PTR, LDNS_RR_CLASS_IN);
do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_SRV, LDNS_RR_CLASS_IN);
do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_NAPTR, LDNS_RR_CLASS_IN);
do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_SVCB, LDNS_RR_CLASS_IN);
do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_HTTPS, LDNS_RR_CLASS_IN);
do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_A, LDNS_RR_CLASS_IN, pc);
do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_AAAA, LDNS_RR_CLASS_IN, pc);
do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_NS, LDNS_RR_CLASS_IN, pc);
do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_SOA, LDNS_RR_CLASS_IN, pc);
do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_CNAME, LDNS_RR_CLASS_IN, pc);
do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_DNAME, LDNS_RR_CLASS_IN, pc);
do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_MX, LDNS_RR_CLASS_IN, pc);
do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_PTR, LDNS_RR_CLASS_IN, pc);
do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_SRV, LDNS_RR_CLASS_IN, pc);
do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_NAPTR, LDNS_RR_CLASS_IN, pc);
do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_SVCB, LDNS_RR_CLASS_IN, pc);
do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_HTTPS, LDNS_RR_CLASS_IN, pc);
free(nm);
send_ok(ssl);
@@ -2070,7 +2234,7 @@ parse_delegpt(RES* ssl, char* args, uint8_t* nm)
return dp;
}
/** do the status command */
/** do the forward command */
static void
do_forward(RES* ssl, struct worker* worker, char* args)
{
@@ -3029,25 +3193,6 @@ do_rpz_disable(RES* ssl, struct worker* worker, char* arg)
do_rpz_enable_disable(ssl, worker, arg, 0);
}
/** tell other processes to execute the command */
static void
distribute_cmd(struct daemon_remote* rc, RES* ssl, char* cmd)
{
int i;
if(!cmd || !ssl)
return;
/* skip i=0 which is me */
for(i=1; i<rc->worker->daemon->num; i++) {
worker_send_cmd(rc->worker->daemon->workers[i],
worker_cmd_remote);
if(!tube_write_msg(rc->worker->daemon->workers[i]->cmd,
(uint8_t*)cmd, strlen(cmd)+1, 0)) {
ssl_printf(ssl, "error could not distribute cmd\n");
return;
}
}
}
/** check for name with end-of-string, space or tab after it */
static int
cmdcmp(char* p, const char* cmd, size_t len)
@@ -3081,9 +3226,23 @@ execute_cmd(struct daemon_remote* rc, RES* ssl, char* cmd,
do_status(ssl, worker);
return;
} else if(cmdcmp(p, "dump_cache", 10)) {
#ifdef THREADS_DISABLED
if(worker->daemon->num > 1) {
(void)ssl_printf(ssl, "dump_cache/load_cache is not "
"supported in multi-process operation\n");
return;
}
#endif
(void)dump_cache(ssl, worker);
return;
} else if(cmdcmp(p, "load_cache", 10)) {
#ifdef THREADS_DISABLED
if(worker->daemon->num > 1) {
/* The warning can't be printed when stdin is sending
* data; just return */
return;
}
#endif
if(load_cache(ssl, worker)) send_ok(ssl);
return;
} else if(cmdcmp(p, "list_forwards", 13)) {
@@ -3145,6 +3304,27 @@ execute_cmd(struct daemon_remote* rc, RES* ssl, char* cmd,
} else if(cmdcmp(p, "lookup", 6)) {
do_lookup(ssl, worker, skipwhite(p+6));
return;
/* The following are commands that read stdin.
* Each line needs to be distributed if THREADS_DISABLED.
*/
} else if(cmdcmp(p, "local_zones_remove", 18)) {
do_zones_remove(rc, ssl, worker);
return;
} else if(cmdcmp(p, "local_zones", 11)) {
do_zones_add(rc, ssl, worker);
return;
} else if(cmdcmp(p, "local_datas_remove", 18)) {
do_datas_remove(rc, ssl, worker);
return;
} else if(cmdcmp(p, "local_datas", 11)) {
do_datas_add(rc, ssl, worker);
return;
} else if(cmdcmp(p, "view_local_datas_remove", 23)){
do_view_datas_remove(rc, ssl, worker, skipwhite(p+23));
return;
} else if(cmdcmp(p, "view_local_datas", 16)) {
do_view_datas_add(rc, ssl, worker, skipwhite(p+16));
return;
}
#ifdef THREADS_DISABLED
@@ -3159,20 +3339,12 @@ execute_cmd(struct daemon_remote* rc, RES* ssl, char* cmd,
do_verbosity(ssl, skipwhite(p+9));
} else if(cmdcmp(p, "local_zone_remove", 17)) {
do_zone_remove(ssl, worker->daemon->local_zones, skipwhite(p+17));
} else if(cmdcmp(p, "local_zones_remove", 18)) {
do_zones_remove(ssl, worker->daemon->local_zones);
} else if(cmdcmp(p, "local_zone", 10)) {
do_zone_add(ssl, worker->daemon->local_zones, skipwhite(p+10));
} else if(cmdcmp(p, "local_zones", 11)) {
do_zones_add(ssl, worker->daemon->local_zones);
} else if(cmdcmp(p, "local_data_remove", 17)) {
do_data_remove(ssl, worker->daemon->local_zones, skipwhite(p+17));
} else if(cmdcmp(p, "local_datas_remove", 18)) {
do_datas_remove(ssl, worker->daemon->local_zones);
} else if(cmdcmp(p, "local_data", 10)) {
do_data_add(ssl, worker->daemon->local_zones, skipwhite(p+10));
} else if(cmdcmp(p, "local_datas", 11)) {
do_datas_add(ssl, worker->daemon->local_zones);
} else if(cmdcmp(p, "forward_add", 11)) {
do_forward_add(ssl, worker, skipwhite(p+11));
} else if(cmdcmp(p, "forward_remove", 14)) {
@@ -3189,12 +3361,8 @@ execute_cmd(struct daemon_remote* rc, RES* ssl, char* cmd,
do_view_zone_add(ssl, worker, skipwhite(p+15));
} else if(cmdcmp(p, "view_local_data_remove", 22)) {
do_view_data_remove(ssl, worker, skipwhite(p+22));
} else if(cmdcmp(p, "view_local_datas_remove", 23)){
do_view_datas_remove(ssl, worker, skipwhite(p+23));
} else if(cmdcmp(p, "view_local_data", 15)) {
do_view_data_add(ssl, worker, skipwhite(p+15));
} else if(cmdcmp(p, "view_local_datas", 16)) {
do_view_datas_add(ssl, worker, skipwhite(p+16));
} else if(cmdcmp(p, "flush_zone", 10)) {
do_flush_zone(ssl, worker, skipwhite(p+10));
} else if(cmdcmp(p, "flush_type", 10)) {
@@ -3214,9 +3382,9 @@ execute_cmd(struct daemon_remote* rc, RES* ssl, char* cmd,
} else if(cmdcmp(p, "get_option", 10)) {
do_get_option(ssl, worker, skipwhite(p+10));
} else if(cmdcmp(p, "flush_bogus", 11)) {
do_flush_bogus(ssl, worker);
do_flush_bogus(ssl, worker, skipwhite(p+11));
} else if(cmdcmp(p, "flush_negative", 14)) {
do_flush_negative(ssl, worker);
do_flush_negative(ssl, worker, skipwhite(p+14));
} else if(cmdcmp(p, "rpz_enable", 10)) {
do_rpz_enable(ssl, worker, skipwhite(p+10));
} else if(cmdcmp(p, "rpz_disable", 11)) {
@@ -3248,7 +3416,7 @@ handle_req(struct daemon_remote* rc, struct rc_state* s, RES* res)
int r;
char pre[10];
char magic[7];
char buf[1024];
char buf[MAX_CMD_STRLINE];
#ifdef USE_WINSOCK
/* makes it possible to set the socket blocking again. */
/* basically removes it from winsock_event ... */
+1 -1
View File
@@ -550,7 +550,7 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
* because that creates privilege escape problems, with the
* pidfile writable by unprivileged users, but used by
* privileged users. */
if(cfg->username && cfg->username[0])
if(!(cfg->username && cfg->username[0]))
checkoldpid(daemon->pidfile, pidinchroot);
}
#endif
+81 -1
View File
@@ -1,8 +1,88 @@
3 June 2024: Wouter
- Fix to squelch connection reset by peer errors from log. And fix
that the tcp read errors are labeled as initial for the first calls.
30 May 2024: Wouter
- Fix #1079: tags from tagged rpz zones are no longer honored after
upgrade from 1.19.3 to 1.20.0.
- Fix for #1079: fix RPZ taglist in iterator callback that no client
info is like no taglist intersection.
29 May 2024: Wouter
- Merge #1078: Only check old pid if no username.
27 May 2024: Wouter
- Fix to enable that SERVFAIL is cached, for a short period, for more
cases. In the cases where limits are exceeded.
- Fix spelling of tcp-idle-timeout docs, from Michael Tokarev.
27 May 2024: Yorgos
- Fix unused variable warning on compilation with no thread support.
- unbound-control-setup: check openssl availability before doing
anything, patch from Michael Tokarev.
- Update patch to remove 'command' shell builtin and update error
text.
24 May 2024: Wouter
- Fix #1064: Unbound 1.20 Cachedb broken?
24 May 2024: Yorgos
- Fix #1059: Intermittent DNS blocking failure with local-zone and
always_nxdomain. Addition of local_zones dynamically via
unbound-control was not finding the zone's parent correctly.
21 May 2024: Wouter
- Merge #1073: fix null pointer dereference issue in function
ub_ctx_set_fwd.
- Fix to print a parse error when config is read with no name for
a forward-zone, stub-zone or view.
- Fix for parse end of forward-zone, stub-zone and view.
- Fix for #1064: Fix that cachedb expired messages are considered
insecure, and thus can be served to clients when dnssec is enabled.
17 May 2024: Yorgos
- Merge #1069: Fix unbound-control stdin commands for multi-process
Unbounds.
- Fix unbound-control commands that read stdin in multi-process
operation (local_zones_remove, local_zones, local_datas_remove,
local_datas, view_local_datas_remove, view_local_datas). They will
be properly distributed to all processes. dump_cache and load_cache
are no longer supported in multi-process operation.
- Remove testdata/remote-threaded.tdir. testdata/09-unbound-control.tdir
now checks both single and multi process/thread operation.
16 May 2024: Yorgos
- Merge #1070: Fix rtt assignement for low values of
infra-cache-max-rtt.
16 May 2024: Wouter
- Fix #1071: [FR] Clear both in-memory and cachedb module cache with
`unbound-control flush*` commands.
15 May 2024: Yorgos
- Add missing common functions to tdir tests.
10 May 2024: Wouter
- Fix when the mesh jostle is exceeded that nameserver targets are
marked as resolved, so that the lookup is not stuck on the
requestlist.
8 May 2024: Wouter
- Fix to squelch udp connect errors in the log at low verbosity about
invalid argument for IPv6 link local addresses.
7 May 2024: Wouter
- Merge #1062: Fix potential overflow bug while parsing port in
function cfg_mark_ports.
- Fix for #1062: declaration before statement, avoid print of null,
and redundant check for array size.
1 May 2024: Wouter
- Fix for the DNSBomb vulnerability CVE-2024-33655. Thanks to Xiang Li
from the Network and Information Security Lab of Tsinghua University
for reporting it.
- Set version number to 1.20.0 for release.
- Set version number to 1.20.0 for release. This became the release
on 8 may 2024, the repository continues with version 1.20.1.
29 April 2024: Yorgos
- Cleanup unnecessary strdup calls for EDE strings.
+18 -11
View File
@@ -121,31 +121,38 @@ Remove local data RRs read from stdin of unbound\-control. Input is one name per
line. For bulk removals.
.TP
.B dump_cache
The contents of the cache is printed in a text format to stdout. You can
redirect it to a file to store the cache in a file.
The content of the cache is printed in a text format to stdout.
You can redirect it to a file to store the cache in a file.
Not supported in remote Unbounds in multi-process operation.
.TP
.B load_cache
The contents of the cache is loaded from stdin. Uses the same format as
dump_cache uses. Loading the cache with old, or wrong data can result
in old or wrong data returned to clients. Loading data into the cache
in this way is supported in order to aid with debugging.
The content of the cache is loaded from stdin.
Uses the same format as dump_cache uses.
Loading the cache with old, or wrong data can result in old or wrong data
returned to clients.
Loading data into the cache in this way is supported in order to aid with
debugging.
Not supported in remote Unbounds in multi-process operation.
.TP
.B lookup \fIname
Print to stdout the name servers that would be used to look up the
name specified.
.TP
.B flush \fIname
.B flush \fR[\fI+c\fR] \fIname
Remove the name from the cache. Removes the types
A, AAAA, NS, SOA, CNAME, DNAME, MX, PTR, SRV, NAPTR, SVCB and HTTPS.
Because that is fast to do. Other record types can be removed using
.B flush_type
or
.B flush_zone\fR.
.IP
The '+c' option removes the items also from the cachedb cache. If
cachedb is in use.
.TP
.B flush_type \fIname\fR \fItype
.B flush_type \fR[\fI+c\fR] \fIname\fR \fItype
Remove the name, type information from the cache.
.TP
.B flush_zone \fIname
.B flush_zone \fR[\fI+c\fR] \fIname
Remove all information at or below the name from the cache.
The rrsets and key entries are removed so that new lookups will be performed.
This needs to walk and inspect the entire cache, and is a slow operation.
@@ -153,10 +160,10 @@ The entries are set to expired in the implementation of this command (so,
with serve\-expired enabled, it'll serve that information but schedule a
prefetch for new information).
.TP
.B flush_bogus
.B flush_bogus \fR[\fI+c\fR]
Remove all bogus data from the cache.
.TP
.B flush_negative
.B flush_negative \fR[\fI+c\fR]
Remove all negative data from the cache. This is nxdomain answers,
nodata answers and servfail answers. Also removes bad key entries
(which could be due to failed lookups) from the dnssec key cache, and
+1 -1
View File
@@ -511,7 +511,7 @@ configured value if the number of free buffers falls below 35% of the
total number configured, and finally to 0 if the number of free buffers
falls below 20% of the total number configured. A minimum timeout of
200 milliseconds is observed regardless of the option value used.
It will be overriden by \fBedns\-tcp\-keepalive\-timeout\fR if
It will be overridden by \fBedns\-tcp\-keepalive\-timeout\fR if
\fBedns\-tcp\-keepalive\fR is enabled.
.TP
.B tcp-reuse-timeout: \fI<msec>\fR
+28
View File
@@ -408,6 +408,34 @@ find_NS(struct reply_info* rep, size_t from, size_t to)
return NULL;
}
struct delegpt* delegpt_from_deleg(struct dns_msg*, struct regional* region, uint8_t* ipv4, uint8_t* ipv6, uint8_t* ns_name, size_t ns_name_len) {
struct delegpt* dp;
dp = delegpt_create(region);
delegpt_set_name(dp, region, ns_name);
delegpt_add_ns(dp, region, ns_name, 0, NULL, 53);
// delegpt_rrset_add_ns(dp, region, ns_rrset, 0);
if (ipv4 != NULL) {
struct sockaddr_in sa4;
socklen_t lenv4 = (socklen_t)sizeof(sa4);
memset(&sa4, 0, lenv4);
sa4.sin_family = AF_INET;
memmove(&sa4.sin_addr, ipv4, INET_SIZE);
delegpt_add_target(dp, region, ns_name, ns_name_len, (struct sockaddr_storage*)&sa4, lenv4, 0, 0, NULL);
}
if (ipv6 != NULL) {
struct sockaddr_in6 sa6;
socklen_t lenv6 = (socklen_t)sizeof(sa6);
memset(&sa6, 0, lenv6);
sa6.sin6_family = AF_INET6;
memmove(&sa6.sin6_addr, ipv6, INET6_SIZE);
delegpt_add_target(dp, region, ns_name, ns_name_len, (struct sockaddr_storage*)&sa6, lenv6, 0, 0, NULL);
}
return dp;
// delegpt_add_addr(struct delegpt* dp, struct regional* region,
// struct sockaddr_storage* addr, socklen_t addrlen, uint8_t bogus,
// uint8_t lame, char* tls_auth_name, int port, int* additions)
}
struct delegpt*
delegpt_from_message(struct dns_msg* msg, struct regional* region)
{
+1
View File
@@ -361,6 +361,7 @@ size_t delegpt_count_targets(struct delegpt* dp);
struct delegpt* delegpt_from_message(struct dns_msg* msg,
struct regional* regional);
struct delegpt* delegpt_from_deleg(struct dns_msg*, struct regional* region, uint8_t* ipv4, uint8_t* pv6, uint8_t* ns_name, size_t ns_name_len);
/**
* Mark negative return in delegation point for specific nameserver.
* sets the got4 or got6 to negative, updates the ns->resolved.
+2 -1
View File
@@ -279,9 +279,10 @@ iter_filter_unsuitable(struct iter_env* iter_env, struct module_env* env,
name, namelen, qtype, &lame, &dnsseclame, &reclame,
&rtt, now)) {
log_addr(VERB_ALGO, "servselect", &a->addr, a->addrlen);
verbose(VERB_ALGO, " rtt=%d%s%s%s%s", rtt,
verbose(VERB_ALGO, " rtt=%d%s%s%s%s%s", rtt,
lame?" LAME":"",
dnsseclame?" DNSSEC_LAME":"",
a->dnsseclame?" ADDR_DNSSEC_LAME":"",
reclame?" REC_LAME":"",
a->lame?" ADDR_LAME":"");
if(lame)
+323 -41
View File
@@ -32,7 +32,33 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// @JESSE: Iterator (this file) is the module that does all the needed DNS
// iterations and walking the DNS tree to try and find an answer.
// It includes but not limited to:
// 1. Finding the closest known delegation point
// (root at startup, or configured zones)
// 2. Sends a query (the original query if no qname-minimisation)
// to that and gets either an answer or a referral answer.
// 3. In case of referral answer goes back to 1.
//
// A lot more is happening here, like fallbacks and retries. Don't try
// to understand everything at once, it's better to go with the flow
// and see what is relevant for you.
// @JESSE: We do not use '//' comments in the Unbound code base. I explicitly
// use them to identify non-relevant parts or WIP comments.
// @JESSE: Some tips:
// - For printf kind of debug logging it's easier to use log_err();
// these are printed on all verbosity levels.
// - For domain name manipulation methods you can have a look at
// dname.c/h.
// - If you need to do allocations; for your case everything should
// have the lifetime of the query state (qstate); you can use
// qstate->region as your arena allocator and pass that region to
// functions that require one. You can then alloc items there and
// forget about them. The whole region is freed when the qstate is
// no more.
/**
* \file
*
@@ -70,6 +96,7 @@
#include "sldns/parseutil.h"
#include "sldns/sbuffer.h"
/* in msec */
int UNKNOWN_SERVER_NICENESS = 376;
/* in msec */
@@ -136,6 +163,8 @@ iter_deinit(struct module_env* env, int id)
static int
iter_new(struct module_qstate* qstate, int id)
{
// @JESSE: each module can have its own query state. The iter_qstate
// struct below is the state for the iterator.
struct iter_qstate* iq = (struct iter_qstate*)regional_alloc(
qstate->region, sizeof(struct iter_qstate));
qstate->minfo[id] = iq;
@@ -164,7 +193,13 @@ iter_new(struct module_qstate* qstate, int id)
iq->dnssec_lame_query = 0;
iq->chase_flags = qstate->query_flags;
/* Start with the (current) qname. */
// @JESSE: iq->qchase will be the qinfo iterator will be working on and
// updating through the iteration process. It is set here to
// the initial query (qstate->qinfo) that started all this.
iq->qchase = qstate->qinfo;
iq->deleg_state = 2;
iq->deleg_original_qname_len = 0;
iq->deleg_original_qname = NULL;
outbound_list_init(&iq->outlist);
iq->minimise_count = 0;
iq->timeout_count = 0;
@@ -172,7 +207,7 @@ iter_new(struct module_qstate* qstate, int id)
iq->minimisation_state = INIT_MINIMISE_STATE;
else
iq->minimisation_state = DONOT_MINIMISE_STATE;
// @JESSE: iq->qinfo_out is the qinfo that will be sent out.
memset(&iq->qinfo_out, 0, sizeof(struct query_info));
return 1;
}
@@ -1378,7 +1413,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
"restarts (eg. indirections)");
if(iq->qchase.qname)
errinf_dname(qstate, "stop at", iq->qchase.qname);
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
}
/* We enforce a maximum recursion/dependency depth -- in general,
@@ -1596,8 +1631,10 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
delname = iq->dp->name;
delnamelen = iq->dp->namelen;
} else {
delname = iq->qchase.qname;
delnamelen = iq->qchase.qname_len;
// @JESSE: Here we set the delegation name to be the original
// one ...
delname = iq->qchase.qname;
delnamelen = iq->qchase.qname_len;
}
if(iq->qchase.qtype == LDNS_RR_TYPE_DS || iq->refetch_glue ||
(iq->qchase.qtype == LDNS_RR_TYPE_NS && qstate->prefetch_leeway
@@ -1618,8 +1655,10 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
/* Lookup the delegation in the cache. If null, then the
* cache needs to be primed for the qclass. */
// @JESSE: ... and here we'll try to get the closest delegation
// from cache.
if(delname)
iq->dp = dns_cache_find_delegation(qstate->env, delname,
iq->dp = dns_cache_find_delegation(qstate->env, delname,
delnamelen, iq->qchase.qtype, iq->qchase.qclass,
qstate->region, &iq->deleg_msg,
*qstate->env->now+qstate->prefetch_leeway, 1,
@@ -1654,7 +1693,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
if(!iq->dp) {
log_err("internal error: no hints dp");
errinf(qstate, "no hints for this class");
return error_response(qstate, id,
return error_response_cache(qstate, id,
LDNS_RCODE_SERVFAIL);
}
iq->dp = delegpt_copy(iq->dp, qstate->region);
@@ -1974,7 +2013,8 @@ generate_target_query(struct module_qstate* qstate, struct iter_qstate* iq,
* if it is negative, there is no maximum number of targets.
* @param num: returns the number of queries generated and processed,
* which may be zero if there were no missing targets.
* @return false on error.
* @return 0 on success, nonzero on error. 1 means temporary failure and
* 2 means the failure can be cached.
*/
static int
query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq,
@@ -1997,13 +2037,13 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq,
else toget = maxtargets;
if(toget == 0) {
*num = 0;
return 1;
return 0;
}
/* now that we are sure that a target query is going to be made,
* check the limits. */
if(iq->depth == ie->max_dependency_depth)
return 0;
return 1;
if(iq->depth > 0 && iq->target_count &&
iq->target_count[TARGET_COUNT_QUERIES] > MAX_TARGET_COUNT) {
char s[LDNS_MAX_DOMAINLEN+1];
@@ -2011,7 +2051,7 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq,
verbose(VERB_QUERY, "request %s has exceeded the maximum "
"number of glue fetches %d", s,
iq->target_count[TARGET_COUNT_QUERIES]);
return 0;
return 2;
}
if(iq->dp_target_count > MAX_DP_TARGET_COUNT) {
char s[LDNS_MAX_DOMAINLEN+1];
@@ -2019,7 +2059,7 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq,
verbose(VERB_QUERY, "request %s has exceeded the maximum "
"number of glue fetches %d to a single delegation point",
s, iq->dp_target_count);
return 0;
return 2;
}
/* select 'toget' items from the total of 'missing' items */
@@ -2048,7 +2088,7 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq,
*num = query_count;
if(query_count > 0)
qstate->ext_state[id] = module_wait_subquery;
return 0;
return 1;
}
query_count++;
/* If the mesh query list is full, exit the loop here.
@@ -2057,8 +2097,16 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq,
* increase, because the spawned state uses cpu and a
* socket while this state waits for that spawned
* state. Next time we can look up further targets */
if(mesh_jostle_exceeded(qstate->env->mesh))
if(mesh_jostle_exceeded(qstate->env->mesh)) {
/* If no ip4 query is possible, that makes
* this ns resolved. */
if(!((ie->supports_ipv4 || ie->use_nat64) &&
((ns->lame && !ns->done_pside4) ||
(!ns->lame && !ns->got4)))) {
ns->resolved = 1;
}
break;
}
}
/* Send the A request. */
if((ie->supports_ipv4 || ie->use_nat64) &&
@@ -2070,12 +2118,17 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq,
*num = query_count;
if(query_count > 0)
qstate->ext_state[id] = module_wait_subquery;
return 0;
return 1;
}
query_count++;
/* If the mesh query list is full, exit the loop. */
if(mesh_jostle_exceeded(qstate->env->mesh))
if(mesh_jostle_exceeded(qstate->env->mesh)) {
/* With the ip6 query already checked for,
* this makes the ns resolved. It is no longer
* a missing target. */
ns->resolved = 1;
break;
}
}
/* mark this target as in progress. */
@@ -2089,7 +2142,7 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq,
if(query_count > 0)
qstate->ext_state[id] = module_wait_subquery;
return 1;
return 0;
}
/**
@@ -2180,12 +2233,14 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
}
/* query for an extra name added by the parent-NS record */
if(delegpt_count_missing_targets(iq->dp, NULL) > 0) {
int qs = 0;
int qs = 0, ret;
verbose(VERB_ALGO, "try parent-side target name");
if(!query_for_targets(qstate, iq, ie, id, 1, &qs)) {
if((ret=query_for_targets(qstate, iq, ie, id, 1, &qs))!=0) {
errinf(qstate, "could not fetch nameserver");
errinf_dname(qstate, "at zone", iq->dp->name);
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
if(ret == 1)
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
}
iq->num_target_queries += qs;
target_count_increase(iq, qs);
@@ -2368,6 +2423,7 @@ check_waiting_queries(struct iter_qstate* iq, struct module_qstate* qstate,
}
}
// @JESSE: This is where most of the iteration time will be spent.
/**
* This is the request event state where the request will be sent to one of
* its current query targets. This state also handles issuing target lookup
@@ -2414,13 +2470,13 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
verbose(VERB_QUERY, "request has exceeded the maximum "
"number of referrrals with %d", iq->referral_count);
errinf(qstate, "exceeded the maximum of referrals");
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
}
if(iq->sent_count > ie->max_sent_count) {
verbose(VERB_QUERY, "request has exceeded the maximum "
"number of sends with %d", iq->sent_count);
errinf(qstate, "exceeded the maximum number of sends");
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
}
/* Check if we reached MAX_TARGET_NX limit without a fallback activation. */
@@ -2450,7 +2506,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
"already present for the delegation point, no "
"fallback possible");
errinf(qstate, "exceeded the maximum nameserver nxdomains");
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
}
verbose(VERB_ALGO, "initiating parent-side fallback for "
"nxdomain nameserver lookups");
@@ -2493,7 +2549,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
"lookups (%d) with %d", MAX_TARGET_NX_FALLBACK,
iq->target_count[TARGET_COUNT_NX]);
errinf(qstate, "exceeded the maximum nameserver nxdomains");
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
}
if(!iq->dp->has_parent_side_NS) {
@@ -2521,6 +2577,77 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
if(!ie->supports_ipv4 && !ie->use_nat64)
delegpt_no_ipv4(iq->dp);
delegpt_log(VERB_ALGO, iq->dp);
log_err("Tes Test jesse jess", iq->deleg_original_qname);
uint8_t root_len = iq->qchase.qname[0];
//todo have to remove this from iq when query has been resolved
if (iq->deleg_original_qname == NULL) {
iq->deleg_original_qname = (uint8_t *)regional_alloc(qstate->region, iq->qchase.qname_len + 1);
memcpy(iq->deleg_original_qname, qstate->qinfo.qname, iq->qchase.qname_len);
iq->deleg_original_qname_len = iq->qchase.qname_len;
iq->original_query = iq->qchase.qtype;
} else {
//restore qname to original to put _deleg in correct point
memcpy(qstate->qinfo.qname, iq->deleg_original_qname, iq->deleg_original_qname_len);
memcpy(iq->qchase.qname, iq->deleg_original_qname, iq->deleg_original_qname_len);
iq->qchase.qname_len = iq->deleg_original_qname_len;
iq->qchase.qtype = iq->original_query;
iq->qinfo_out.qtype = iq->original_query;
}
if (iq->deleg_state == 0 && root_len > 0) {
iq->deleg_original_qname_len = iq->qchase.qname_len;
iq->deleg_state = 1;
int qchase_label_len = dname_count_labels(iq->qchase.qname);
size_t labdiff = qchase_label_len - iq->dp->namelabs - 1;
dname_remove_labels(&iq->qchase.qname, &iq->qchase.qname_len, labdiff);
//we have to add _deleg after the first label
//for ex. jesse.nlnetlabs.nl becomes jesse._deleg.nlnetlabs.nl
uint8_t deleg_wireformat[] = {6, 95, 100, 101, 108, 101, 103}; //{06}_deleg
size_t delnamelen = iq->qchase.qname_len + sizeof(deleg_wireformat);
uint8_t *delname = (uint8_t *)regional_alloc(qstate->region, delnamelen);
//put first label of original qname
uint8_t first_label_len = iq->qchase.qname[0];
uint8_t *qname_minus_first_label = iq->qchase.qname + first_label_len + 1;
uint8_t leftover_len = iq->qchase.qname_len - first_label_len - 1;
memcpy(delname, iq->qchase.qname, first_label_len + 1); //memcpy 1st label into delname
memcpy(delname + first_label_len + 1, deleg_wireformat, sizeof(deleg_wireformat)); //memcpy _deleg label in delname
memcpy(delname + first_label_len + sizeof(deleg_wireformat) + 1, qname_minus_first_label, leftover_len); //memcpy other labels in delname
iq->dp->namelen = delnamelen;
iq->qchase.qtype = LDNS_RR_TYPE_IDELEG;
iq->qchase.qname = delname;
iq->qchase.qname_len = delnamelen;
iq->qinfo_out.qtype = LDNS_RR_TYPE_IDELEG;
iq->qinfo_out.qname = delname;
iq->qinfo_out.qname_len = delnamelen;
} else if (root_len > 0 && iq->deleg_state == 2) { //in this state create deleg prime query
int qchase_label_len = dname_count_labels(iq->qchase.qname);
size_t labdiff = qchase_label_len - iq->dp->namelabs;
dname_remove_labels(&iq->qchase.qname, &iq->qchase.qname_len, labdiff);
uint8_t deleg_wireformat[] = {6, 95, 100, 101, 108, 101, 103}; //{06}_deleg
size_t deleg_len = sizeof(deleg_wireformat);
size_t delnamelen = iq->qchase.qname_len + deleg_len;
uint8_t *delname = (uint8_t *)regional_alloc(qstate->region, delnamelen);
memcpy(delname, deleg_wireformat, deleg_len);
memcpy(delname+deleg_len, iq->qchase.qname, iq->qchase.qname_len);
iq->qchase.qtype = LDNS_RR_TYPE_IDELEG;
iq->qchase.qname = delname;
iq->qchase.qname_len = delnamelen;
iq->qinfo_out.qtype = LDNS_RR_TYPE_IDELEG;
iq->qinfo_out.qname = delname;
iq->qinfo_out.qname_len = delnamelen;
}
if(iq->num_current_queries>0) {
/* already busy answering a query, this restart is because
@@ -2531,6 +2658,13 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
return 0;
}
//DELEG first check if _deleg in delegation point
//if no _deleg let unbound handle it
// @JESSE: The following ifs is where most qname-minimisation happens.
// We need something similar (adding a label at a time) but
// without the best-effort nature of qname-minimisation and its
// fallback. You can take inspiration from here on how to
// correctly set iq->qinfo_out.
if(iq->minimisation_state == INIT_MINIMISE_STATE
&& !(iq->chase_flags & BIT_RD)) {
/* (Re)set qinfo_out to (new) delegation point, except when
@@ -2707,7 +2841,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
verbose(VERB_ALGO, "auth zone lookup failed, no fallback,"
" servfail");
errinf(qstate, "auth zone lookup failed, fallback is off");
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
}
if(iq->dp->auth_dp) {
/* we wanted to fallback, but had no delegpt, only the
@@ -2736,11 +2870,13 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
/* if in 0x20 fallback get as many targets as possible */
if(iq->caps_fallback) {
int extra = 0;
int extra = 0, ret;
size_t naddr, nres, navail;
if(!query_for_targets(qstate, iq, ie, id, -1, &extra)) {
if((ret=query_for_targets(qstate, iq, ie, id, -1, &extra))!=0) {
errinf(qstate, "could not fetch nameservers for 0x20 fallback");
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
if(ret == 1)
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
}
iq->num_target_queries += extra;
target_count_increase(iq, extra);
@@ -2883,14 +3019,17 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
* to distinguish between generating (a) new target
* query, or failing. */
if(delegpt_count_missing_targets(iq->dp, NULL) > 0) {
int qs = 0;
int qs = 0, ret;
verbose(VERB_ALGO, "querying for next "
"missing target");
if(!query_for_targets(qstate, iq, ie, id,
1, &qs)) {
if((ret=query_for_targets(qstate, iq, ie, id,
1, &qs))!=0) {
errinf(qstate, "could not fetch nameserver");
errinf_dname(qstate, "at zone", iq->dp->name);
return error_response(qstate, id,
if(ret == 1)
return error_response(qstate, id,
LDNS_RCODE_SERVFAIL);
return error_response_cache(qstate, id,
LDNS_RCODE_SERVFAIL);
}
if(qs == 0 &&
@@ -2902,6 +3041,17 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
* so this is not a loop. */
return 1;
}
if(qs == 0) {
/* There should be targets now, and
* if there are not, it should not
* wait for no targets. Stop it from
* waiting forever, or looping to
* here, as a safeguard. */
errinf(qstate, "could not generate nameserver lookups");
errinf_dname(qstate, "at zone", iq->dp->name);
return error_response(qstate, id,
LDNS_RCODE_SERVFAIL);
}
iq->num_target_queries += qs;
target_count_increase(iq, qs);
}
@@ -2999,7 +3149,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
log_name_addr(VERB_QUERY, "applied NAT64:",
iq->dp->name, &real_addr, real_addrlen);
}
// @JESSE: This is where a query is finally going out, hopefully.
fptr_ok(fptr_whitelist_modenv_send_query(qstate->env->send_query));
outq = (*qstate->env->send_query)(&iq->qinfo_out,
iq->chase_flags | (iq->chase_to_rd?BIT_RD:0),
@@ -3025,7 +3175,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
qstate->was_ratelimited = 1;
errinf_dname(qstate, "exceeded ratelimit for zone",
iq->dp->name);
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
}
log_addr(VERB_QUERY, "error sending query to auth server",
&real_addr, real_addrlen);
@@ -3053,7 +3203,7 @@ find_NS(struct reply_info* rep, size_t from, size_t to)
return NULL;
}
// @JESSE: This is where responses are read.
/**
* Process the query response. All queries end up at this state first. This
* process generally consists of analyzing the response and routing the
@@ -3148,8 +3298,114 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
dnsseclame = 1;
}
} else iq->dnssec_lame_query = 0;
// @JESSE: Answers to _deleg queries would end up here. You need to
// make sure you identify those answers correclty and treat
// them the same way as referrals below.
/* handle each of the type cases */
// uint16_t SVCB_QTYPE = LDNS_RR_TYPE_IDELEG;
//check wether it was a deleg query
uint8_t deleg_wireformat[] = {6, 95, 100, 101, 108, 101, 103}; //{06}_deleg
uint8_t first_label_len = iq->qchase.qname[0];
int is_deleg_query = memcmp(iq->qchase.qname + first_label_len + 1, deleg_wireformat, 7);
int is_deleg_prime_query = memcmp(iq->qchase.qname, deleg_wireformat, 7);
if (iq->deleg_state == 1 && type == RESPONSE_TYPE_ANSWER && iq->qchase.qtype == 64 && is_deleg_query == 0) {
//result of a deleg refferal
if (FLAGS_GET_RCODE(iq->response->rep->flags) == LDNS_RCODE_NXDOMAIN) {
//whem _deleg return NXDOMAIN
//turns all values back to normal when no _deleg (NXDOMAIN)
iq->qchase.qname = iq->deleg_original_qname;
iq->qchase.qtype = iq->original_query;
iq->qchase.qname_len = iq->deleg_original_qname_len;
iq->qinfo_out.qtype = iq->original_query;
iq->qinfo_out.qname = iq->deleg_original_qname;
iq->qinfo_out.qname_len = iq->deleg_original_qname_len;
return next_state(iq, QUERYTARGETS_STATE);
}
//In this scenario _deleg exists
iq->deleg_state = 2;
struct ub_packed_rrset_key* rrset_key;
rrset_key = reply_find_answer_rrset(&iq->qchase, iq->response->rep);
if(rrset_key) {
struct packed_rrset_data* rrset_data = (struct packed_rrset_data*) rrset_key->entry.data;
size_t data_len = rrset_data->rr_len[0];
uint8_t* svcb_data = rrset_data->rr_data[0];
size_t index = 4; //index of 4 to start at first label (skip message length(2 octet) and priority(2 octet))
while(svcb_data[index] != 0) { //loop through dns labels, label length 0 means root so stop looping though labels
index = index + svcb_data[index] + 1;
}
index = index + 1;//add 1 for the root label
//Reference https://datatracker.ietf.org/doc/rfc9460/ section 2.2
uint8_t *ipv4 = NULL;
uint8_t *ipv6 = NULL;
while(index < data_len && (ipv4 == NULL || ipv6 == NULL)) {
uint16_t svcParamkey = (svcb_data[index] << 8) | svcb_data[index+1];
uint16_t svcParamValLen = (svcb_data[index+2] << 8) | svcb_data[index+3];
index = index + 4;
if (svcParamkey == 4) { //parse IPv4
ipv4 = (uint8_t *)regional_alloc(qstate->region, 4 * sizeof(uint8_t));
memcpy(ipv4, svcb_data + index, 4);
} else if (svcParamkey == 6) { //parse ipv6
ipv6 = (uint8_t *)regional_alloc(qstate->region, 16 * sizeof(uint8_t));
memcpy(ipv6, svcb_data + index, 16);
}
index = index + svcParamValLen;
}
//to get the new delegation name, we have to remove the second label, which is the _deleg label
//count labels with dname_count_labels()
size_t new_delegation_label_count = dname_count_labels(rrset_key->rk.dname);
size_t old_label_count = dname_count_labels(iq->deleg_original_qname);
size_t diff_label_len = old_label_count - new_delegation_label_count + 1;
uint8_t *new_delegation_name = (uint8_t *)regional_alloc(qstate->region, iq->deleg_original_qname_len);
size_t new_delegation_name_len = iq->deleg_original_qname_len;
memcpy(new_delegation_name, iq->deleg_original_qname, iq->deleg_original_qname_len);
dname_remove_labels(&new_delegation_name, &new_delegation_name_len, diff_label_len);
iq->dp = delegpt_from_deleg(iq->response, qstate->region, ipv4, ipv6, new_delegation_name, new_delegation_name_len);
iq->referral_count++;
iq->sent_count = 0;
iq->dp_target_count = 0;
if(qstate->env->cfg->harden_referral_path)
generate_ns_check(qstate, iq, id);
/* stop current outstanding queries.
* FIXME: should the outstanding queries be waited for and
* handled? Say by a subquery that inherits the outbound_entry.
*/
outbound_list_clear(&iq->outlist);
iq->num_current_queries = 0;
fptr_ok(fptr_whitelist_modenv_detach_subs(
qstate->env->detach_subs));
(*qstate->env->detach_subs)(qstate);
iq->num_target_queries = 0;
iq->response = NULL;
iq->fail_addr_type = 0;
verbose(VERB_ALGO, "cleared outbound list for next round");
return next_state(iq, QUERYTARGETS_STATE);
}
} else if (is_deleg_prime_query == 0) {
if (FLAGS_GET_RCODE(iq->response->rep->flags) == LDNS_RCODE_NXDOMAIN) {
//NX DOMAIN mean deleg not supported (no error and answer count = 0)
iq->deleg_state = 1;
return next_state(iq, QUERYTARGETS_STATE);
} else if (FLAGS_GET_RCODE(iq->response->rep->flags) == LDNS_RCODE_NOERROR && iq->response->rep->an_numrrsets == 0) {
//no data means _deleg supported
iq->deleg_state = 0;
return next_state(iq, QUERYTARGETS_STATE);
}
}
/* see if referral brings us close to the target */
if(type == RESPONSE_TYPE_REFERRAL) {
if(type == RESPONSE_TYPE_REFERRAL){
//deleg: go to state 2 when normal refferal found, to try deleg again for child
iq->deleg_state = 2;
struct ub_packed_rrset_key* ns = find_NS(
iq->response->rep, iq->response->rep->an_numrrsets,
iq->response->rep->an_numrrsets
@@ -3192,8 +3448,14 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
type = RESPONSE_TYPE_ANSWER;
}
/* handle each of the type cases */
if(type == RESPONSE_TYPE_ANSWER) {
if(type == RESPONSE_TYPE_ANSWER ){
//set original qname to NULL after query has been resolved, to handle new queries
if (iq->deleg_original_qname != NULL) {
iq->deleg_original_qname = NULL;
iq->deleg_original_qname_len = 0;
iq->original_query = 0;
log_err("en hier ook nog wel??");
}
/* ANSWER type responses terminate the query algorithm,
* so they sent on their */
if(verbosity >= VERB_DETAIL) {
@@ -3203,6 +3465,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
(iq->response->rep->an_numrrsets?"ANSWER":
"nodata ANSWER"));
}
/* if qtype is DS, check we have the right level of answer,
* like grandchild answer but we need the middle, reject it */
if(iq->qchase.qtype == LDNS_RR_TYPE_DS && !iq->dsns_point
@@ -3247,7 +3510,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
iter_scrub_nxdomain(iq->response);
return final_state(iq);
}
return error_response(qstate, id,
return error_response_cache(qstate, id,
LDNS_RCODE_SERVFAIL);
}
/* Best effort qname-minimisation.
@@ -3291,8 +3554,13 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
return next_state(iq, QUERYTARGETS_STATE);
}
return final_state(iq);
// @JESSE: I guess for the test environemnt we mostly don't care about
// referrals; these are traditional DNS referral responses.
} else if(type == RESPONSE_TYPE_REFERRAL) {
//added code
// iq->deleg_state = 0;
struct delegpt* old_dp = NULL;
/* REFERRAL type responses get a reset of the
* delegation point, and back to the QUERYTARGETS_STATE. */
verbose(VERB_DETAIL, "query response was REFERRAL");
@@ -3561,6 +3829,14 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
* In this case, the event is just sent directly back to
* the QUERYTARGETS_STATE without resetting anything,
* because, clearly, the next target must be tried. */
iq->qchase.qname = iq->deleg_original_qname;
iq->qchase.qtype = iq->original_query;
iq->qchase.qname_len = iq->deleg_original_qname_len;
iq->qinfo_out.qtype = iq->original_query;
iq->qinfo_out.qname = iq->deleg_original_qname;
iq->qinfo_out.qname_len = iq->deleg_original_qname_len;
verbose(VERB_DETAIL, "query response was THROWAWAY");
} else {
log_warn("A query response came back with an unknown type: %d",
@@ -3582,7 +3858,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
" fallback possible, servfail");
errinf_dname(qstate, "response is bad, no fallback, "
"for auth zone", iq->dp->name);
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
}
verbose(VERB_ALGO, "auth zone response was bad, "
"fallback enabled");
@@ -3990,7 +4266,7 @@ processCollectClass(struct module_qstate* qstate, int id)
if(iq->num_current_queries == 0) {
verbose(VERB_ALGO, "No root hints or fwds, giving up "
"on qclass ANY");
return error_response(qstate, id, LDNS_RCODE_REFUSED);
return error_response_cache(qstate, id, LDNS_RCODE_REFUSED);
}
/* return false, wait for queries to return */
}
@@ -4108,6 +4384,12 @@ iter_inform_super(struct module_qstate* qstate, int id,
else processTargetResponse(qstate, id, super);
}
// @JESSE: These are all the available states the iterator could be for a given
// query. You should not worry about the following cases:
// - COLLECT_CLASS_STATE (it has to do with ANY queries)
// - DSNS_FIND_STATE (it tries to find the correct parent for a DS
// query; I think it is not relevant since the
// _deleg stuff always live at the parent)
/**
* Handle iterator state.
* Handle events. This is the real processing loop for events, responsible
@@ -4357,7 +4639,7 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
"getting different replies, failed");
outbound_list_remove(&iq->outlist, outbound);
errinf(qstate, "0x20 failed, then got different replies in fallback");
(void)error_response(qstate, id,
(void)error_response_cache(qstate, id,
LDNS_RCODE_SERVFAIL);
return;
}
+6
View File
@@ -431,6 +431,12 @@ struct iter_qstate {
/** State for capsfail: QNAME minimisation state for comparisons. */
enum minimisation_state caps_minimisation_state;
//DELEG added code
int deleg_state;
uint8_t* deleg_original_qname;
size_t deleg_original_qname_len;
uint16_t original_query;
/**
* The query info that is sent upstream. Will be a subset of qchase
* when qname minimisation is enabled.
+5 -2
View File
@@ -981,7 +981,8 @@ ub_ctx_set_fwd(struct ub_ctx* ctx, const char* addr)
if(!addr) {
/* disable fwd mode - the root stub should be first. */
if(ctx->env->cfg->forwards &&
strcmp(ctx->env->cfg->forwards->name, ".") == 0) {
(ctx->env->cfg->forwards->name &&
strcmp(ctx->env->cfg->forwards->name, ".") == 0)) {
s = ctx->env->cfg->forwards;
ctx->env->cfg->forwards = s->next;
s->next = NULL;
@@ -1001,7 +1002,8 @@ ub_ctx_set_fwd(struct ub_ctx* ctx, const char* addr)
/* it parses, add root stub in front of list */
lock_basic_lock(&ctx->cfglock);
if(!ctx->env->cfg->forwards ||
strcmp(ctx->env->cfg->forwards->name, ".") != 0) {
(ctx->env->cfg->forwards->name &&
strcmp(ctx->env->cfg->forwards->name, ".") != 0)) {
s = calloc(1, sizeof(*s));
if(!s) {
lock_basic_unlock(&ctx->cfglock);
@@ -1019,6 +1021,7 @@ ub_ctx_set_fwd(struct ub_ctx* ctx, const char* addr)
ctx->env->cfg->forwards = s;
} else {
log_assert(ctx->env->cfg->forwards);
log_assert(ctx->env->cfg->forwards->name);
s = ctx->env->cfg->forwards;
}
dupl = strdup(addr);
+16 -9
View File
@@ -60,6 +60,16 @@
* can do this number of packets (until those all timeout too) */
#define TIMEOUT_COUNT_MAX 3
/** Minus 1000 because that is outside of the RTTBAND, so
* blacklisted servers stay blacklisted if this is chosen.
* If USEFUL_SERVER_TOP_TIMEOUT is below 1000 (configured via RTT_MAX_TIMEOUT,
* infra-cache-max-rtt) change it to just above the RTT_BAND. */
#define STILL_USEFUL_TIMEOUT ( \
USEFUL_SERVER_TOP_TIMEOUT < 1000 || \
USEFUL_SERVER_TOP_TIMEOUT - 1000 <= RTT_BAND \
?RTT_BAND + 1 \
:USEFUL_SERVER_TOP_TIMEOUT - 1000)
/** ratelimit value for delegation point */
int infra_dp_ratelimit = 0;
@@ -656,7 +666,7 @@ infra_update_tcp_works(struct infra_cache* infra,
if(data->rtt.rto >= RTT_MAX_TIMEOUT)
/* do not disqualify this server altogether, it is better
* than nothing */
data->rtt.rto = RTT_MAX_TIMEOUT-1000;
data->rtt.rto = STILL_USEFUL_TIMEOUT;
lock_rw_unlock(&e->lock);
}
@@ -796,7 +806,7 @@ infra_get_lame_rtt(struct infra_cache* infra,
&& infra->infra_keep_probing) {
/* single probe, keep probing */
if(*rtt >= USEFUL_SERVER_TOP_TIMEOUT)
*rtt = USEFUL_SERVER_TOP_TIMEOUT-1000;
*rtt = STILL_USEFUL_TIMEOUT;
} else if(host->rtt.rto >= PROBE_MAXRTO && timenow < host->probedelay
&& rtt_notimeout(&host->rtt)*4 <= host->rtt.rto) {
/* single probe for this domain, and we are not probing */
@@ -804,26 +814,23 @@ infra_get_lame_rtt(struct infra_cache* infra,
if(qtype == LDNS_RR_TYPE_A) {
if(host->timeout_A >= TIMEOUT_COUNT_MAX)
*rtt = USEFUL_SERVER_TOP_TIMEOUT;
else *rtt = USEFUL_SERVER_TOP_TIMEOUT-1000;
else *rtt = STILL_USEFUL_TIMEOUT;
} else if(qtype == LDNS_RR_TYPE_AAAA) {
if(host->timeout_AAAA >= TIMEOUT_COUNT_MAX)
*rtt = USEFUL_SERVER_TOP_TIMEOUT;
else *rtt = USEFUL_SERVER_TOP_TIMEOUT-1000;
else *rtt = STILL_USEFUL_TIMEOUT;
} else {
if(host->timeout_other >= TIMEOUT_COUNT_MAX)
*rtt = USEFUL_SERVER_TOP_TIMEOUT;
else *rtt = USEFUL_SERVER_TOP_TIMEOUT-1000;
else *rtt = STILL_USEFUL_TIMEOUT;
}
}
/* expired entry */
if(timenow > host->ttl) {
/* see if this can be a re-probe of an unresponsive server */
/* minus 1000 because that is outside of the RTTBAND, so
* blacklisted servers stay blacklisted if this is chosen */
if(host->rtt.rto >= USEFUL_SERVER_TOP_TIMEOUT) {
lock_rw_unlock(&e->lock);
*rtt = USEFUL_SERVER_TOP_TIMEOUT-1000;
*rtt = STILL_USEFUL_TIMEOUT;
*lame = 0;
*dnsseclame = 0;
*reclame = 0;
+41 -34
View File
@@ -242,7 +242,7 @@ lz_enter_zone_dname(struct local_zones* zones, uint8_t* nm, size_t len,
}
/** enter a new zone */
static struct local_zone*
struct local_zone*
lz_enter_zone(struct local_zones* zones, const char* name, const char* type,
uint16_t dclass)
{
@@ -983,40 +983,43 @@ lz_enter_overrides(struct local_zones* zones, struct config_file* cfg)
return 1;
}
/** setup parent pointers, so that a lookup can be done for closest match */
static void
init_parents(struct local_zones* zones)
/* return closest parent in the tree, NULL if none */
static struct local_zone* find_closest_parent(struct local_zone* curr,
struct local_zone* prev)
{
struct local_zone* node, *prev = NULL, *p;
int m;
lock_rw_wrlock(&zones->lock);
RBTREE_FOR(node, struct local_zone*, &zones->ztree) {
lock_rw_wrlock(&node->lock);
node->parent = NULL;
if(!prev || prev->dclass != node->dclass) {
prev = node;
lock_rw_unlock(&node->lock);
continue;
}
(void)dname_lab_cmp(prev->name, prev->namelabs, node->name,
node->namelabs, &m); /* we know prev is smaller */
/* sort order like: . com. bla.com. zwb.com. net. */
/* find the previous, or parent-parent-parent */
for(p = prev; p; p = p->parent)
/* looking for name with few labels, a parent */
if(p->namelabs <= m) {
/* ==: since prev matched m, this is closest*/
/* <: prev matches more, but is not a parent,
* this one is a (grand)parent */
node->parent = p;
break;
}
prev = node;
struct local_zone* p;
int m;
if(!prev || prev->dclass != curr->dclass) return NULL;
(void)dname_lab_cmp(prev->name, prev->namelabs, curr->name,
curr->namelabs, &m); /* we know prev is smaller */
/* sort order like: . com. bla.com. zwb.com. net. */
/* find the previous, or parent-parent-parent */
for(p = prev; p; p = p->parent) {
/* looking for name with few labels, a parent */
if(p->namelabs <= m) {
/* ==: since prev matched m, this is closest*/
/* <: prev matches more, but is not a parent,
* this one is a (grand)parent */
return p;
}
}
return NULL;
}
/** setup parent pointers, so that a lookup can be done for closest match */
void
lz_init_parents(struct local_zones* zones)
{
struct local_zone* node, *prev = NULL;
lock_rw_wrlock(&zones->lock);
RBTREE_FOR(node, struct local_zone*, &zones->ztree) {
lock_rw_wrlock(&node->lock);
node->parent = find_closest_parent(node, prev);
prev = node;
if(node->override_tree)
addr_tree_init_parents(node->override_tree);
lock_rw_unlock(&node->lock);
}
}
lock_rw_unlock(&zones->lock);
}
@@ -1036,7 +1039,7 @@ lz_setup_implicit(struct local_zones* zones, struct config_file* cfg)
int nmlabs = 0;
int match = 0; /* number of labels match count */
init_parents(zones); /* to enable local_zones_lookup() */
lz_init_parents(zones); /* to enable local_zones_lookup() */
for(p = cfg->local_data; p; p = p->next) {
uint8_t* rr_name;
uint16_t rr_class, rr_type;
@@ -1202,7 +1205,7 @@ local_zones_apply_cfg(struct local_zones* zones, struct config_file* cfg)
}
/* setup parent ptrs for lookup during data entry */
init_parents(zones);
lz_init_parents(zones);
/* insert local zone tags */
if(!lz_enter_zone_tags(zones, cfg)) {
return 0;
@@ -2028,7 +2031,9 @@ struct local_zone* local_zones_add_zone(struct local_zones* zones,
uint8_t* name, size_t len, int labs, uint16_t dclass,
enum localzone_type tp)
{
int exact;
/* create */
struct local_zone *prev;
struct local_zone* z = local_zone_create(name, len, labs, tp, dclass);
if(!z) {
free(name);
@@ -2037,10 +2042,12 @@ struct local_zone* local_zones_add_zone(struct local_zones* zones,
lock_rw_wrlock(&z->lock);
/* find the closest parent */
z->parent = local_zones_find(zones, name, len, labs, dclass);
prev = local_zones_find_le(zones, name, len, labs, dclass, &exact);
if(!exact)
z->parent = find_closest_parent(z, prev);
/* insert into the tree */
if(!rbtree_insert(&zones->ztree, &z->node)) {
if(exact||!rbtree_insert(&zones->ztree, &z->node)) {
/* duplicate entry! */
lock_rw_unlock(&z->lock);
local_zone_delete(z);
+19
View File
@@ -641,4 +641,23 @@ local_zone_enter_rr(struct local_zone* z, uint8_t* nm, size_t nmlen,
*/
struct local_data*
local_zone_find_data(struct local_zone* z, uint8_t* nm, size_t nmlen, int nmlabs);
/** Enter a new zone; returns with WRlock
* Made public for unit testing
* @param zones: the local zones tree
* @param name: name of the zone
* @param type: type of the zone
* @param dclass: class of the zone
* @return local_zone (or duplicate), NULL on parse and malloc failures
*/
struct local_zone*
lz_enter_zone(struct local_zones* zones, const char* name, const char* type,
uint16_t dclass);
/** Setup parent pointers, so that a lookup can be done for closest match
* Made public for unit testing
* @param zones: the local zones tree
*/
void
lz_init_parents(struct local_zones* zones);
#endif /* SERVICES_LOCALZONE_H */
+13 -2
View File
@@ -2051,7 +2051,8 @@ select_id(struct outside_network* outnet, struct pending* pend,
}
/** return true is UDP connect error needs to be logged */
static int udp_connect_needs_log(int err)
static int udp_connect_needs_log(int err, struct sockaddr_storage* addr,
socklen_t addrlen)
{
switch(err) {
case ECONNREFUSED:
@@ -2075,6 +2076,15 @@ static int udp_connect_needs_log(int err)
if(verbosity >= VERB_ALGO)
return 1;
return 0;
case EINVAL:
/* Stop 'Invalid argument for fe80::/10' addresses appearing
* in the logs, at low verbosity. They cannot be sent to. */
if(addr_is_ip6linklocal(addr, addrlen)) {
if(verbosity >= VERB_ALGO)
return 1;
return 0;
}
break;
default:
break;
}
@@ -2141,7 +2151,8 @@ select_ifport(struct outside_network* outnet, struct pending* pend,
/* connect() to the destination */
if(connect(fd, (struct sockaddr*)&pend->addr,
pend->addrlen) < 0) {
if(udp_connect_needs_log(errno)) {
if(udp_connect_needs_log(errno,
&pend->addr, pend->addrlen)) {
log_err_addr("udp connect failed",
strerror(errno), &pend->addr,
pend->addrlen);
+15 -2
View File
@@ -2435,11 +2435,10 @@ rpz_callback_from_iterator_module(struct module_qstate* ms, struct iter_qstate*
if(ms->env == NULL || ms->env->auth_zones == NULL) { return 0; }
az = ms->env->auth_zones;
lock_rw_rdlock(&az->rpz_lock);
verbose(VERB_ALGO, "rpz: iterator module callback: have_rpz=%d", az->rpz_first != NULL);
lock_rw_rdlock(&az->rpz_lock);
/* precedence of RPZ works, loosely, like this:
* CNAMEs in order of the CNAME chain. rpzs in the order they are
* configured. In an RPZ: first client-IP addr, then QNAME, then
@@ -2454,6 +2453,13 @@ rpz_callback_from_iterator_module(struct module_qstate* ms, struct iter_qstate*
lock_rw_unlock(&a->lock);
continue;
}
if(r->taglist && (!ms->client_info ||
!taglist_intersect(r->taglist, r->taglistlen,
ms->client_info->taglist,
ms->client_info->taglen))) {
lock_rw_unlock(&a->lock);
continue;
}
/* the nsdname has precedence over the nsip triggers */
z = rpz_delegation_point_zone_lookup(is->dp, r->nsdname_zones,
@@ -2512,6 +2518,13 @@ struct dns_msg* rpz_callback_from_iterator_cname(struct module_qstate* ms,
lock_rw_unlock(&a->lock);
continue;
}
if(r->taglist && (!ms->client_info ||
!taglist_intersect(r->taglist, r->taglistlen,
ms->client_info->taglist,
ms->client_info->taglen))) {
lock_rw_unlock(&a->lock);
continue;
}
z = rpz_find_zone(r->local_zones, is->qchase.qname,
is->qchase.qname_len, is->qchase.qclass, 0, 0, 0);
if(z && r->action_override == RPZ_DISABLED_ACTION) {
+3
View File
@@ -234,6 +234,9 @@ enum sldns_enum_rr_type
/* RFC 4431, 5074, DNSSEC Lookaside Validation */
LDNS_RR_TYPE_DLV = 32769,
/* draft-homburg-deleg-inctremental-deleg */
LDNS_RR_TYPE_IDELEG = 65280,
/* type codes from nsec3 experimental phase
LDNS_RR_TYPE_NSEC3 = 65324,
LDNS_RR_TYPE_NSEC3PARAMS = 65325, */
+4
View File
@@ -104,6 +104,10 @@ while getopts 'd:hr' arg; do
done
shift $((OPTIND - 1))
if ! openssl >/dev/null 2>&1; then
echo "$0 requires openssl to be installed for keys/certificates generation." >&2
exit 1
fi
echo "setup in directory $DESTDIR"
cd "$DESTDIR"
+14 -7
View File
@@ -122,20 +122,27 @@ usage(void)
printf(" local_data <RR data...> add local data, for example\n");
printf(" local_data www.example.com A 192.0.2.1\n");
printf(" local_data_remove <name> remove local RR data from name\n");
printf(" local_zones, local_zones_remove, local_datas, local_datas_remove\n");
printf(" same, but read list from stdin\n");
printf(" local_zones,\n");
printf(" local_zones_remove,\n");
printf(" local_datas,\n");
printf(" local_datas_remove same, but read list from stdin\n");
printf(" (one entry per line).\n");
printf(" dump_cache print cache to stdout\n");
printf(" (not supported in remote unbounds in\n");
printf(" multi-process operation)\n");
printf(" load_cache load cache from stdin\n");
printf(" (not supported in remote unbounds in\n");
printf(" multi-process operation)\n");
printf(" lookup <name> print nameservers for name\n");
printf(" flush <name> flushes common types for name from cache\n");
printf(" flush [+c] <name> flushes common types for name from cache\n");
printf(" types: A, AAAA, MX, PTR, NS,\n");
printf(" SOA, CNAME, DNAME, SRV, NAPTR\n");
printf(" flush_type <name> <type> flush name, type from cache\n");
printf(" flush_zone <name> flush everything at or under name\n");
printf(" flush_type [+c] <name> <type> flush name, type from cache\n");
printf(" +c remove from cachedb too\n");
printf(" flush_zone [+c] <name> flush everything at or under name\n");
printf(" from rr and dnssec caches\n");
printf(" flush_bogus flush all bogus data\n");
printf(" flush_negative flush all negative data\n");
printf(" flush_bogus [+c] flush all bogus data\n");
printf(" flush_negative [+c] flush all negative data\n");
printf(" flush_stats flush statistics, make zero\n");
printf(" flush_requestlist drop queries that are worked on\n");
printf(" dump_requestlist show what is worked on by first thread\n");
+104
View File
@@ -1252,6 +1252,109 @@ static void edns_ede_answer_encode_test(void)
regional_destroy(region);
}
#include "services/localzone.h"
/* Utility function that compares two localzone trees */
static void compare_localzone_trees(struct local_zones* z1,
struct local_zones* z2)
{
struct local_zone *node1, *node2;
lock_rw_rdlock(&z1->lock);
lock_rw_rdlock(&z2->lock);
/* size should be the same */
unit_assert(z1->ztree.count == z2->ztree.count);
for(node1=(struct local_zone*)rbtree_first(&z1->ztree),
node2=(struct local_zone*)rbtree_first(&z2->ztree);
(rbnode_type*)node1 != RBTREE_NULL &&
(rbnode_type*)node2 != RBTREE_NULL;
node1=(struct local_zone*)rbtree_next((rbnode_type*)node1),
node2=(struct local_zone*)rbtree_next((rbnode_type*)node2)) {
int labs;
/* the same zone should be at the same nodes */
unit_assert(!dname_lab_cmp(
node1->name, node1->namelabs,
node2->name, node2->namelabs,
&labs));
/* the zone's parent should be the same on both nodes */
unit_assert(
(node1->parent == NULL && node2->parent == NULL) ||
(node1->parent != NULL && node2->parent != NULL));
if(node1->parent) {
unit_assert(!dname_lab_cmp(
node1->parent->name, node1->parent->namelabs,
node2->parent->name, node2->parent->namelabs,
&labs));
}
}
lock_rw_unlock(&z1->lock);
lock_rw_unlock(&z2->lock);
}
/* test that zone addition results in the same tree from both the configuration
* file and the unbound-control commands */
static void localzone_parents_test(void)
{
struct local_zones *z1, *z2;
size_t i;
char* zone_data[] = {
"one",
"a.b.c.one",
"b.c.one",
"c.one",
"two",
"c.two",
"b.c.two",
"a.b.c.two",
"a.b.c.three",
"b.c.three",
"c.three",
"three",
"c.four",
"b.c.four",
"a.b.c.four",
"four",
"."
};
unit_show_feature("localzones parent calculation");
z1 = local_zones_create();
z2 = local_zones_create();
/* parse test data */
for(i=0; i<sizeof(zone_data)/sizeof(zone_data[0]); i++) {
uint8_t* nm;
int nmlabs;
size_t nmlen;
struct local_zone* z;
/* This is the config way */
z = lz_enter_zone(z1, zone_data[i], "always_nxdomain",
LDNS_RR_CLASS_IN);
(void)z; /* please compiler when no threading and no lock
code; the following line disappears and z stays unused */
lock_rw_unlock(&z->lock);
lz_init_parents(z1);
/* This is the unbound-control way */
nm = sldns_str2wire_dname(zone_data[i], &nmlen);
if(!nm) unit_assert(0);
nmlabs = dname_count_size_labels(nm, &nmlen);
lock_rw_wrlock(&z2->lock);
local_zones_add_zone(z2, nm, nmlen, nmlabs, LDNS_RR_CLASS_IN,
local_zone_always_nxdomain);
lock_rw_unlock(&z2->lock);
}
/* The trees should be the same, iterate and check the nodes */
compare_localzone_trees(z1, z2);
/* cleanup */
local_zones_delete(z1);
local_zones_delete(z2);
}
/** localzone unit tests */
static void localzone_test(void)
{
localzone_parents_test();
}
void unit_show_func(const char* file, const char* func)
{
printf("test %s:%s\n", file, func);
@@ -1325,6 +1428,7 @@ main(int argc, char* argv[])
tcpreuse_test();
msgparse_test();
edns_ede_answer_encode_test();
localzone_test();
#ifdef CLIENT_SUBNET
ecs_test();
#endif /* CLIENT_SUBNET */
+1
View File
@@ -4,6 +4,7 @@
# use .tpkg.var.test for in test variable passing
[ -f .tpkg.var.test ] && source .tpkg.var.test
. ../common.sh
PRE="../.."
if uname | grep "MINGW" >/dev/null; then
+7 -4
View File
@@ -1,8 +1,7 @@
server:
verbosity: 2
num-threads: 1
interface: 127.0.0.1
port: @PORT@
verbosity: 5
num-threads: 1 # This is dynamically handled by the test when needed
interface: 127.0.0.1@@PORT@
use-syslog: no
directory: ""
pidfile: "unbound.pid"
@@ -10,9 +9,13 @@ server:
username: ""
do-not-query-localhost: no
access-control: 127.0.0.1 allow_snoop
access-control-view: 127.0.0.1 testview
msg-cache-size: 4m
rrset-cache-size: 4m
minimal-responses: yes
view:
name: testview
view-first: yes # Allow falling back to global local data
remote-control:
control-enable: yes
control-interface: 127.0.0.1
@@ -30,4 +30,3 @@ echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test
cat .tpkg.var.test
wait_ldns_testns_up fwd.log
wait_unbound_up unbound.log
+151 -79
View File
@@ -73,6 +73,29 @@ control_command () {
$PRE/unbound-control $@ > outfile
}
# Reload the server for a clean state
clean_reload () {
echo "> Reloading the server for a clean state"
cp main.conf ub.conf
control_command -c ub.conf reload
expect_exit_value 0
}
# Reload the server for a clean state and populate the cache
clean_reload_and_fill_cache () {
clean_reload
echo "> Populating the cache"
query www.example.com
expect_answer "10.20.30.40"
if test "$have_threads" = "no"; then
# Try to get the answer in all processes' cache.
for (( try=0 ; try < num_threads * 2 * 2 ; try++ )) ; do
query www.example.com
expect_answer "10.20.30.40"
done
fi
}
# Dump the cache contents
# $@: optional options to unbound-control
cache_dump () {
@@ -111,8 +134,28 @@ fail_in_cache_dump () {
fi
}
# start the test
# Check if multi-threading or multi-process environment
have_threads="no"
if grep "define HAVE_PTHREAD 1" $PRE/config.h; then have_threads="yes"; fi
if grep "define HAVE_SOLARIS_THREADS 1" $PRE/config.h; then have_threads="yes"; fi
if grep "define HAVE_WINDOWS_THREADS 1" $PRE/config.h; then have_threads="yes"; fi
# start the test; keep the original conf file around
cp ub.conf orig.conf
# START - thread configuration
# Do both single thread/process and multi thread/process runs.
# The number of threads can only go up from the initial configuration between
# reloads so starting with 1.
for num_threads in 1 4; do
cp orig.conf ub.conf
echo "> setting num-threads: $num_threads"
echo "server: num-threads: $num_threads" >> ub.conf
cp ub.conf main.conf
clean_reload
teststep "exit value is 1 on usage"
control_command -h
@@ -163,6 +206,9 @@ cat conf.spoofed_credentials >> bad.conf
control_command -c bad.conf verbosity 2
expect_exit_value 1
teststep "clean reload"
clean_reload
teststep "create a new local zone"
control_command -c ub.conf local_zone example.net static
expect_exit_value 0
@@ -194,6 +240,76 @@ expect_exit_value 0
query www.example.net.
expect_answer "SERVFAIL"
teststep "load local-zones from file"
control_command -c ub.conf local_zones < local_zones
expect_exit_value 0
query localzonefromfile
expect_answer "REFUSED"
if test "$have_threads" = "no"; then
# Try to see if a process other than the first one
# has updated data from stdin.
for (( try=0 ; try < num_threads * 2 ; try++ )) ; do
query localzonefromfile
expect_answer "REFUSED"
done
fi
teststep "load local-data from file"
control_command -c ub.conf local_datas < local_data
expect_exit_value 0
query -t txt localdatafromfile
expect_answer "local data from file OK"
if test "$have_threads" = "no"; then
# Try to see if a process other than the first one
# has updated data from stdin.
for (( try=0 ; try < num_threads * 2 ; try++ )) ; do
query -t txt localdatafromfile
expect_answer "local data from file OK"
done
fi
teststep "load view-local-data from file"
control_command -c ub.conf view_local_datas testview < view_local_data
expect_exit_value 0
control_command -c ub.conf view_list_local_zones testview
query -t txt viewlocaldatafromfile
expect_answer "view local data from file OK"
if test "$have_threads" = "no"; then
# Try to see if a process other than the first one
# has updated data from stdin.
for (( try=0 ; try < num_threads * 2 ; try++ )) ; do
query -t txt viewlocaldatafromfile
expect_answer "view local data from file OK"
done
fi
teststep "remove local-zone, local-data and view-local-data from file"
control_command -c ub.conf local_zones_remove < local_zones_remove
expect_exit_value 0
control_command -c ub.conf local_datas_remove < local_data_remove
expect_exit_value 0
control_command -c ub.conf view_local_datas_remove testview < view_local_data_remove
expect_exit_value 0
control_command -c ub.conf list_local_zones
fail_answer "localzonefromfile"
fail_answer "local data from file OK"
expect_answer "otherlocalzone"
control_command -c ub.conf view_list_local_data testview
fail_answer "viewlocaldatafromfile"
teststep "flushing"
control_command -c ub.conf flush www.example.net
expect_exit_value 0
control_command -c ub.conf flush_type www.example.net TXT
expect_exit_value 0
control_command -c ub.conf flush_zone example.net
expect_exit_value 0
# START - single thread/process tests only
if test $num_threads -le 1; then
clean_reload_and_fill_cache
teststep "dump the cache"
query www.example.com.
cache_dump -c ub.conf
@@ -208,123 +324,79 @@ expect_exit_value 0
teststep "load the cache dump"
cache_load -c ub.conf
expect_exit_value 0
query www.example.com.
query www.example.com. +nordflag
expect_answer "10.20.30.40"
teststep "load local-zones from file"
control_command -c ub.conf local_zones < local_zones
expect_exit_value 0
query localzonefromfile
expect_answer "REFUSED"
else
echo ""
echo "> skip test parts that need single thread/process"
fi
# END - single thread/process tests only
teststep "load local-data from file"
control_command -c ub.conf local_datas < local_data
expect_exit_value 0
query -t txt localdatafromfile
expect_answer "local data from file OK"
clean_reload_and_fill_cache
teststep "remove local-zone and local-data from file"
control_command -c ub.conf local_zones_remove < local_zones_remove
expect_exit_value 0
control_command -c ub.conf local_datas_remove < local_data_remove
expect_exit_value 0
control_command -c ub.conf list_local_zones
fail_answer "localzonefromfile"
fail_answer "local data from file OK"
expect_answer "otherlocalzone"
teststep "flushing"
control_command -c ub.conf flush www.example.net
expect_exit_value 0
control_command -c ub.conf flush_type www.example.net TXT
expect_exit_value 0
control_command -c ub.conf flush_zone example.net
expect_exit_value 0
teststep "reload the server for a clean state and populate the cache"
cp main.conf ub.conf
teststep "reload and check cache - should be empty"
control_command -c ub.conf reload
expect_exit_value 0
query www.example.com
expect_answer "10.20.30.40"
query www.example.com +nordflag
fail_answer "10.20.30.40"
teststep "reload and check cache dump - should be empty"
control_command -c ub.conf reload
expect_exit_value 0
cache_dump -c ub.conf
expect_exit_value 0
fail_in_cache_dump "www.example.com.*10.20.30.40"
fail_in_cache_dump "msg www.example.com. IN A"
clean_reload_and_fill_cache
query www.example.com
expect_answer "10.20.30.40"
teststep "reload_keep_cache and check cache dump - should not be empty"
teststep "reload_keep_cache and check cache - should not be empty"
control_command -c ub.conf reload_keep_cache
expect_exit_value 0
cache_dump -c ub.conf
expect_exit_value 0
cat cache.dump
expect_in_cache_dump "www.example.com.*10.20.30.40"
expect_in_cache_dump "msg www.example.com. IN A"
query www.example.com +nordflag
expect_answer "10.20.30.40"
clean_reload_and_fill_cache
teststep "change msg-cache-size and reload_keep_cache - should be empty"
echo "server: msg-cache-size: 2m" >> ub.conf
control_command -c ub.conf reload_keep_cache
expect_exit_value 0
cache_dump -c ub.conf
expect_exit_value 0
fail_in_cache_dump "www.example.com.*10.20.30.40"
fail_in_cache_dump "msg www.example.com. IN A"
query www.example.com
expect_answer "10.20.30.40"
query www.example.com +nordflag
fail_answer "10.20.30.40"
clean_reload_and_fill_cache
teststep "change rrset-cache-size and reload_keep_cache - should be empty"
echo "server: rrset-cache-size: 2m" >> ub.conf
control_command -c ub.conf reload_keep_cache
expect_exit_value 0
cache_dump -c ub.conf
expect_exit_value 0
fail_in_cache_dump "www.example.com.*10.20.30.40"
fail_in_cache_dump "msg www.example.com. IN A"
query www.example.com
expect_answer "10.20.30.40"
query www.example.com +nordflag
fail_answer "10.20.30.40"
# See if this part of the test can be enabled, it needs threads for combined
# output.
have_threads="no"
if grep "define HAVE_PTHREAD 1" $PRE/config.h; then have_threads="yes"; fi
if grep "define HAVE_SOLARIS_THREADS 1" $PRE/config.h; then have_threads="yes"; fi
if grep "define HAVE_WINDOWS_THREADS 1" $PRE/config.h; then have_threads="yes"; fi
# START - have_threads tests
# This part of the test needs threads for combined output.
if test "$have_threads" = "yes"; then
clean_reload_and_fill_cache
teststep "change num-threads and reload_keep_cache - should be empty"
echo "server: num-threads: 2" >> ub.conf
control_command -c ub.conf reload_keep_cache
expect_exit_value 0
cache_dump -c ub.conf
expect_exit_value 0
fail_in_cache_dump "www.example.com.*10.20.30.40"
fail_in_cache_dump "msg www.example.com. IN A"
query www.example.com
expect_answer "10.20.30.40"
query www.example.com +nordflag
fail_answer "10.20.30.40"
clean_reload_and_fill_cache
teststep "change minimal-responses and reload_keep_cache - should not be empty"
echo "server: minimal-responses: no" >> ub.conf
control_command -c ub.conf reload_keep_cache
expect_exit_value 0
cache_dump -c ub.conf
expect_exit_value 0
expect_in_cache_dump "www.example.com.*10.20.30.40"
expect_in_cache_dump "msg www.example.com. IN A"
query www.example.com +nordflag
expect_answer "10.20.30.40"
else
echo ""
echo "> skip test parts that need threads, have_threads=no"
# end of check for have_threads
fi
# END - have_threads tests
done
# END - thread configuration
teststep "now stop the server"
control_command -c ub.conf stop
@@ -19,4 +19,3 @@ ADJUST copy_id
SECTION QUESTION
www.example.net. IN A
ENTRY_END
+3
View File
@@ -1 +1,4 @@
localdatafromfile 3600 TXT "local data from file OK"
localdatafromfile1 3600 A 1.1.1.1
localdatafromfile2 3600 A 2.2.2.2
localdatafromfile3 3600 A 3.3.3.3
+3
View File
@@ -1 +1,4 @@
localdatafromfile
localdatafromfile1
localdatafromfile2
localdatafromfile3
+3
View File
@@ -1,2 +1,5 @@
localzonefromfile refuse
otherlocalzone static
localzonefromfile1 static
localzonefromfile2 static
localzonefromfile3 static
+3
View File
@@ -1 +1,4 @@
localzonefromfile
localzonefromfile1
localzonefromfile2
localzonefromfile3
+4
View File
@@ -0,0 +1,4 @@
viewlocaldatafromfile 3600 TXT "view local data from file OK"
viewlocaldatafromfile1 3600 A 1.1.1.1
viewlocaldatafromfile2 3600 A 2.2.2.2
viewlocaldatafromfile3 3600 A 3.3.3.3
@@ -0,0 +1,4 @@
viewlocaldatafromfile
viewlocaldatafromfile1
viewlocaldatafromfile2
viewlocaldatafromfile3
+327
View File
@@ -0,0 +1,327 @@
; config options
server:
target-fetch-policy: "0 0 0 0 0"
qname-minimisation: no
minimal-responses: yes
serve-expired: yes
;module-config: "subnetcache validator cachedb iterator"
module-config: "validator cachedb iterator"
cachedb:
backend: "testframe"
secret-seed: "testvalue"
cachedb-check-when-serve-expired: yes
stub-zone:
name: "."
stub-addr: 193.0.14.129
CONFIG_END
SCENARIO_BEGIN Test cachedb, validator and serve expired.
; K.ROOT-SERVERS.NET.
RANGE_BEGIN 0 400
ADDRESS 193.0.14.129
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
. IN NS
SECTION ANSWER
. IN NS K.ROOT-SERVERS.NET.
SECTION ADDITIONAL
K.ROOT-SERVERS.NET. IN A 193.0.14.129
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
com. IN NS
SECTION AUTHORITY
com. IN NS a.gtld-servers.net.
SECTION ADDITIONAL
a.gtld-servers.net. IN A 192.5.6.30
ENTRY_END
RANGE_END
; a.gtld-servers.net.
RANGE_BEGIN 0 400
ADDRESS 192.5.6.30
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
example.com. IN NS
SECTION AUTHORITY
example.com. IN NS ns2.example.com.
SECTION ADDITIONAL
ns2.example.com. IN A 1.2.3.5
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
foo.com. IN NS
SECTION AUTHORITY
foo.com. IN NS ns.example.com.
ENTRY_END
RANGE_END
; ns2.example.com.
RANGE_BEGIN 0 400
ADDRESS 1.2.3.5
ENTRY_BEGIN
MATCH opcode qname qtype
REPLY QR AA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN A 1.2.3.4
ENTRY_END
ENTRY_BEGIN
MATCH opcode qname qtype
REPLY QR AA NOERROR
SECTION QUESTION
www2.example.com. IN A
SECTION ANSWER
www2.example.com. 10 IN A 1.2.3.5
ENTRY_END
RANGE_END
; Get an entry in cache, to make it expired.
STEP 1 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.example.com. IN A
ENTRY_END
; get the answer for it
STEP 10 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN A 1.2.3.4
ENTRY_END
; Get another query in cache to make it expired.
STEP 20 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www2.example.com. IN A
ENTRY_END
; get the answer for it
STEP 30 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
www2.example.com. IN A
SECTION ANSWER
www2.example.com. 10 IN A 1.2.3.5
ENTRY_END
; it is now expired
STEP 40 TIME_PASSES ELAPSE 20
; cache is expired, and cachedb is expired.
; The expired reply, from cachedb, needs a validation status,
; because the validator module set that validation is needed.
STEP 50 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www2.example.com. IN A
ENTRY_END
STEP 60 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA NOERROR
SECTION QUESTION
www2.example.com. IN A
SECTION ANSWER
www2.example.com. 30 IN A 1.2.3.5
ENTRY_END
; cache is expired, cachedb has no answer
STEP 70 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.example.com. IN A
ENTRY_END
STEP 80 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 30 IN A 1.2.3.4
ENTRY_END
STEP 90 TRAFFIC
; the entry should be refreshed in cache now.
; cache is valid and cachedb is valid.
STEP 100 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.example.com. IN A
ENTRY_END
STEP 110 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN A 1.2.3.4
ENTRY_END
; flush the entry from cache
STEP 120 FLUSH_MESSAGE www.example.com. IN A
; cache has no answer, cachedb valid
STEP 130 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.example.com. IN A
ENTRY_END
STEP 140 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN A 1.2.3.4
ENTRY_END
; it is now expired
STEP 150 TIME_PASSES ELAPSE 20
; flush the entry from cache
STEP 160 FLUSH_MESSAGE www.example.com. IN A
; cache has no answer, cachedb is expired
STEP 170 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.example.com. IN A
ENTRY_END
STEP 180 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 30 IN A 1.2.3.4
ENTRY_END
STEP 190 TRAFFIC
; the expired message is updated.
; cache is valid, cachedb is valid
STEP 200 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.example.com. IN A
ENTRY_END
STEP 210 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN A 1.2.3.4
ENTRY_END
; expire the entry in cache
STEP 220 EXPIRE_MESSAGE www.example.com. IN A
; cache is expired, cachedb valid
STEP 230 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.example.com. IN A
ENTRY_END
STEP 240 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN A 1.2.3.4
ENTRY_END
; it is now expired
STEP 250 TIME_PASSES ELAPSE 20
; expire the entry in cache
STEP 260 EXPIRE_MESSAGE www.example.com. IN A
; cache is expired, cachedb is expired
STEP 270 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.example.com. IN A
ENTRY_END
STEP 280 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 30 IN A 1.2.3.4
ENTRY_END
STEP 290 TRAFFIC
; the expired message is updated.
; cache is valid, cachedb is valid
STEP 300 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.example.com. IN A
ENTRY_END
STEP 310 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN A 1.2.3.4
ENTRY_END
SCENARIO_END
-15
View File
@@ -1,15 +0,0 @@
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQDti51Z6qASvAjPFFhLLlq8BwtsnmfqMPMn57dKAghb4OifeL4G
SLOE02/hKDkdkOvaUG2UqDNh2OoPTuJk4A+mG2LJoziFhHKlIebo9v2YiFWOBVtO
DWc3tXPT1IlSEN0xnAGelMmeLcPeCPe+A5IDlIHzF/+YiDgS38S9dL17owIDAQAB
AoGAG3w/DatfMCu/nS5OdQx9BSqPgNbnUSqux9xA0fhgPTlN0T3oRtPcqa7JUDUW
PryI/a62ry+zGkw98N2AxolCZg3N7Z3vuRx2FMcKKNwpTzDmcZW7TmMk5FPof6gE
PnYl/ff0w+kxqA+L2EexH3Xi6ApLSZcjyzKWj+dL2AuT9gkCQQD3dPitwITxgCAD
IaHw23e3FRkM/hw1Gp8bt6nbuxitVxxpO96q1EQ+fCy/mf0bMEJDp3xzMEIfP3r4
GmNbaxa1AkEA9b8LeBLbQ2cm2+UMeUgygBsRirdUQ786auqH38Jbvi/j6S9sDl2x
q1vRtikEBZJWfkhsOzrzwFDKe1bI/EEn9wJAAzOwRA9JqRZPU7sLrWIpmmTbfh+L
neRKSsGFoSI6n4ORCouLxgoZF/XjXldPvxpQwS9ZnOPy9xSLMsqknno0QQJAeDtA
IT8Yh6GwIWWu9KeeDY8wxe1sDLlCm4yjbZZpzGMh3rSU6XJtuqjxsW3fydoO9zn3
ugLdvvnIFxAexUwbgQJBANyM13xcObfUJOj9rjlGCh0CDh/04ONl8SH8HBnM8guA
RJI5S6vBHweVRopEZcF1sQm6wMf3ej/sGkyyNvJxRkY=
-----END RSA PRIVATE KEY-----
-11
View File
@@ -1,11 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIBozCCAQwCCQDd5/rocjG5vDANBgkqhkiG9w0BAQUFADASMRAwDgYDVQQDEwd1
bmJvdW5kMB4XDTA4MDkyNjEyMjQ0NFoXDTI4MDYxMzEyMjQ0NFowGjEYMBYGA1UE
AxMPdW5ib3VuZC1jb250cm9sMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDt
i51Z6qASvAjPFFhLLlq8BwtsnmfqMPMn57dKAghb4OifeL4GSLOE02/hKDkdkOva
UG2UqDNh2OoPTuJk4A+mG2LJoziFhHKlIebo9v2YiFWOBVtODWc3tXPT1IlSEN0x
nAGelMmeLcPeCPe+A5IDlIHzF/+YiDgS38S9dL17owIDAQABMA0GCSqGSIb3DQEB
BQUAA4GBAHpvcKqY48X9WsqogV16L+zT7iXhZ4tySA9EBk1a+0gud/iDPKSBi7mK
4rzphVfb4S207dVmTG+1WNpa6l3pTGML6XLElxqIu/kr7w4cF0rKvZxWPsBRqYjH
5HrK8CrQ0+YvUHXiu7IaACLGvKXY4Tqa3HQyvEtzLWJ4HhOrGx8F
-----END CERTIFICATE-----
-15
View File
@@ -1,15 +0,0 @@
-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQC9hurNHBtB7QFEuPJOnCylUWUF2/US3v9yQQQXnstuXMQXRaq1
1uviLmwaGurV9tngX59HITsBT74NQrtFKfEDLViLrm2arAM9Ozsn4tnv30HXPRDj
UOc1M05Q7UzjaSrOv+TkPEqyhtUyaP1DYo0bcmbxtSkYc2ZEWCwhPklUwQIDAQAB
AoGATjzZxN4ramWaNnJapJTX4U7eczK/0pB3xwSL2exVcjOdRzYdKH+WVIJxYb1m
3/jNLFCNAeH356yxeevoPr73nG75YJ9I1ZWQWTnS3SDK6JD1+3pmAD0bQWFoitpf
FoSH9H4X5gFB5vCZ99YVoYH1UXWPcgvUHwxz0voImt6lCKECQQD4YQ4A3M0+Ki8v
Hl+5FKULnS0UtBkweCvkF/X1zZRjjYr6hLnqldFkkgTBKWe17pUXX0nwRMbP1YZX
i+vDq5JNAkEAw1eYsmC0nVAMawo57N6LYavGv/n5u1cvpTpKDtn4cXH0Uqq13Kyu
2FUTzan2NhCEK78UzbWaeewBJmxYda1+RQJAdShKk6uTAEyjnwUjv8h2JWlJN2fQ
LeWxRlDrCruiz+aW9J4gl/99GoQpy/c83TshhjnDRZsbcDNWv/rXBZ/rTQJAFQva
CtX6f7yBKgM3DHtJvyM3zbVMH9Ab9QxbsE/xwZ9KeKGl6Hm+eNZpxM3cFiUfaGs0
/ZjkZOB1m0MvILaplQJAXC3PJ/E+87banGZRJl5qtS6/HoX5lH9TPkL8Essy7ANO
2BT2OTQawD1A+VKIrQHXs085Of8tQUfrfHHt7s3Kqg==
-----END RSA PRIVATE KEY-----
-11
View File
@@ -1,11 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIBmzCCAQQCCQCDugnhq8B6LzANBgkqhkiG9w0BAQUFADASMRAwDgYDVQQDEwd1
bmJvdW5kMB4XDTA4MDkyNjEyMjQ0M1oXDTI4MDYxMzEyMjQ0M1owEjEQMA4GA1UE
AxMHdW5ib3VuZDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAvYbqzRwbQe0B
RLjyTpwspVFlBdv1Et7/ckEEF57LblzEF0Wqtdbr4i5sGhrq1fbZ4F+fRyE7AU++
DUK7RSnxAy1Yi65tmqwDPTs7J+LZ799B1z0Q41DnNTNOUO1M42kqzr/k5DxKsobV
Mmj9Q2KNG3Jm8bUpGHNmRFgsIT5JVMECAwEAATANBgkqhkiG9w0BAQUFAAOBgQCy
zGMW35/9xXoEWsuLFWUOaEKVq5DXuXtXbcMpDW6k2ELoraa305vh7Zwhj5JSqfcm
O0xyqIzXvz/cYdyOTgEkdMDZ/EvQsxKTwvj6eA4614yB1r3Ju5eZd4Gpo6BHhSpu
oqsrr0duJ+JOANTyaBplIxM1sjHbR4FGtmrFknBYBQ==
-----END CERTIFICATE-----
-25
View File
@@ -1,25 +0,0 @@
server:
verbosity: 2
num-threads: 4
outgoing-range: 16
interface: 127.0.0.1
port: @PORT@
use-syslog: no
directory: ""
pidfile: "unbound.pid"
chroot: ""
username: ""
do-not-query-localhost: no
remote-control:
control-enable: yes
control-interface: 127.0.0.1
# control-interface: ::1
control-port: @CONTROL_PORT@
server-key-file: "unbound_server.key"
server-cert-file: "unbound_server.pem"
control-key-file: "unbound_control.key"
control-cert-file: "unbound_control.pem"
forward-zone:
name: "."
forward-addr: "127.0.0.1@@TOPORT@"
-16
View File
@@ -1,16 +0,0 @@
BaseName: remote-threaded
Version: 1.0
Description: remote control test with thread communication
CreationDate: Wed Dec 3 15:00:38 CET 2008
Maintainer: dr. W.C.A. Wijngaards
Category:
Component:
CmdDepends:
Depends:
Help:
Pre: remote-threaded.pre
Post: remote-threaded.post
Test: remote-threaded.test
AuxFiles:
Passed:
Failure:
-13
View File
@@ -1,13 +0,0 @@
# #-- remote-threaded.post --#
# source the master var file when it's there
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
# source the test var file when it's there
[ -f .tpkg.var.test ] && source .tpkg.var.test
#
# do your teardown here
. ../common.sh
kill_pid $FWD_PID
# unbound stopped by test (if successful)
kill $UNBOUND_PID >/dev/null 2>&1
kill $UNBOUND_PID >/dev/null 2>&1
exit 0
-33
View File
@@ -1,33 +0,0 @@
# #-- remote-threaded.pre--#
# source the master var file when it's there
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
# use .tpkg.var.test for in test variable passing
[ -f .tpkg.var.test ] && source .tpkg.var.test
. ../common.sh
get_random_port 3
UNBOUND_PORT=$RND_PORT
FWD_PORT=$(($RND_PORT + 1))
CONTROL_PORT=$(($RND_PORT + 2))
echo "UNBOUND_PORT=$UNBOUND_PORT" >> .tpkg.var.test
echo "FWD_PORT=$FWD_PORT" >> .tpkg.var.test
echo "CONTROL_PORT=$CONTROL_PORT" >> .tpkg.var.test
# start forwarder
get_ldns_testns
$LDNS_TESTNS -p $FWD_PORT remote-threaded.testns >fwd.log 2>&1 &
FWD_PID=$!
echo "FWD_PID=$FWD_PID" >> .tpkg.var.test
# make config file
sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@TOPORT\@/'$FWD_PORT'/' -e 's/@CONTROL_PORT\@/'$CONTROL_PORT'/' < remote-threaded.conf > ub.conf
# start unbound in the background
PRE="../.."
$PRE/unbound -d -c ub.conf >unbound.log 2>&1 &
UNBOUND_PID=$!
echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test
cat .tpkg.var.test
wait_ldns_testns_up fwd.log
wait_unbound_up unbound.log
-310
View File
@@ -1,310 +0,0 @@
# #-- remote-threaded.test --#
# source the master var file when it's there
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
# use .tpkg.var.test for in test variable passing
[ -f .tpkg.var.test ] && source .tpkg.var.test
PRE="../.."
# exit value is 1 on usage
$PRE/unbound-control -h
if test $? -ne 1; then
echo "wrong exit value for usage."
exit 1
else
echo "exit value for usage: OK"
fi
# use lock-verify if possible
# test if the server is up.
echo "> dig www.example.com."
dig @127.0.0.1 -p $UNBOUND_PORT www.example.com. | tee outfile
echo "> check answer"
if grep "10.20.30.40" outfile; then
echo "OK"
else
echo "> cat logfiles"
cat fwd.log
cat unbound.log
echo "Not OK"
exit 1
fi
# exit value is 1 when a bad command is given.
echo "$PRE/unbound-control -c ub.conf blablargh"
$PRE/unbound-control -c ub.conf blablargh
if test $? -ne 1; then
echo "wrong exit value on error."
echo "> cat logfiles"
cat fwd.log
cat unbound.log
exit 1
else
echo "correct exit value on error"
fi
# reload the server. test if the server came up by putting a new
# local-data element in the server.
echo "server: local-data: 'afterreload. IN A 5.6.7.8'" >> ub.conf
echo "$PRE/unbound-control -c ub.conf reload"
$PRE/unbound-control -c ub.conf reload
if test $? -ne 0; then
echo "wrong exit value after success"
exit 1
fi
echo "> dig afterreload."
dig @127.0.0.1 -p $UNBOUND_PORT afterreload. | tee outfile
echo "> check answer"
if grep "5.6.7.8" outfile; then
echo "OK"
else
echo "> cat logfiles"
cat fwd.log
cat unbound.log
echo "Not OK"
exit 1
fi
# must have had queries now. 1 since reload.
echo "$PRE/unbound-control -c ub.conf stats"
$PRE/unbound-control -c ub.conf stats > tmp.$$
if test $? -ne 0; then
echo "wrong exit value after success"
cat fwd.log
cat unbound.log
exit 1
fi
if grep "^total.num.queries=[1-9][0-9]*$" tmp.$$; then
echo "OK"
else
echo "bad stats"
cat tmp.$$
exit 1
fi
# verbosity
echo "$PRE/unbound-control -c ub.conf verbosity 4"
$PRE/unbound-control -c ub.conf verbosity 4
if test $? -ne 0; then
echo "wrong exit value after success"
exit 1
fi
# check syntax error in parse
echo "$PRE/unbound-control -c ub.conf verbosity jkdf"
$PRE/unbound-control -c ub.conf verbosity jkdf
if test $? -ne 1; then
echo "wrong exit value after failure"
exit 1
fi
# check bad credentials
cp ub.conf bad.conf
echo "remote-control:" >> bad.conf
echo " server-key-file: bad_server.key" >> bad.conf
echo " server-cert-file: bad_server.pem" >> bad.conf
echo " control-key-file: bad_control.key" >> bad.conf
echo " control-cert-file: bad_control.pem" >> bad.conf
echo "$PRE/unbound-control -c bad.conf verbosity 2"
$PRE/unbound-control -c bad.conf verbosity 2
if test $? -ne 1; then
echo "wrong exit value after failure"
exit 1
fi
# create a new local zone
echo "> test of local zone"
echo "$PRE/unbound-control -c ub.conf local_zone example.net static"
$PRE/unbound-control -c ub.conf local_zone example.net static
if test $? -ne 0; then
echo "wrong exit value after success"
exit 1
fi
echo "$PRE/unbound-control -c ub.conf local_data www.example.net A 192.0.2.1"
$PRE/unbound-control -c ub.conf local_data www.example.net A 192.0.2.1
if test $? -ne 0; then
echo "wrong exit value after success"
exit 1
fi
# check that www.example.net exists
echo "> dig www.example.net."
dig @127.0.0.1 -p $UNBOUND_PORT www.example.net. | tee outfile
echo "> check answer"
if grep "192.0.2.1" outfile; then
echo "OK"
else
echo "> cat logfiles"
cat fwd.log
cat unbound.log
echo "Not OK"
exit 1
fi
# check that mail.example.net has nxdomain
echo "> dig mail.example.net."
dig @127.0.0.1 -p $UNBOUND_PORT mail.example.net. | tee outfile
echo "> check answer"
if grep "NXDOMAIN" outfile; then
echo "OK"
else
echo "> cat logfiles"
cat fwd.log
cat unbound.log
echo "Not OK"
exit 1
fi
# remove www.example.net - check it gets nxdomain
echo "$PRE/unbound-control -c ub.conf local_data_remove www.example.net"
$PRE/unbound-control -c ub.conf local_data_remove www.example.net
if test $? -ne 0; then
echo "wrong exit value after success"
exit 1
fi
echo "> dig www.example.net."
dig @127.0.0.1 -p $UNBOUND_PORT www.example.net. | tee outfile
echo "> check answer"
if grep "NXDOMAIN" outfile; then
echo "OK"
else
echo "> cat logfiles"
cat fwd.log
cat unbound.log
echo "Not OK"
exit 1
fi
# remove example.net - check its gone.
echo "$PRE/unbound-control -c ub.conf local_zone_remove example.net"
$PRE/unbound-control -c ub.conf local_zone_remove example.net
if test $? -ne 0; then
echo "wrong exit value after success"
exit 1
fi
echo "> dig www.example.net."
dig @127.0.0.1 -p $UNBOUND_PORT www.example.net. | tee outfile
echo "> check answer"
if grep "SERVFAIL" outfile; then
echo "OK"
else
echo "> cat logfiles"
cat fwd.log
cat unbound.log
echo "Not OK"
exit 1
fi
# dump the cache
echo "> test cache dump"
# fillup cache
echo "dig www.example.com"
dig @127.0.0.1 -p $UNBOUND_PORT www.example.com.
echo "$PRE/unbound-control -c ub.conf dump_cache"
$PRE/unbound-control -c ub.conf dump_cache > tmp.$$
if test $? -ne 0; then
echo "wrong exit value after success"
exit 1
fi
cat tmp.$$
# we do not look at content. Only thread 0 content.
# because it may not be there when it is compiled with processes only.
if grep MSG_CACHE tmp.$$; then
echo "OK this is a cache dump"
else
echo "Not OK cache dump"
exit 1
fi
# test lookup
echo "$PRE/unbound-control -c ub.conf lookup www.example.com"
$PRE/unbound-control -c ub.conf lookup www.example.com
if test $? -ne 0; then
echo "wrong exit value after success"
exit 1
fi
# answer to lookup is meaningless because of use a forwarder, oh well.
# load the cache dump.
echo "$PRE/unbound-control -c ub.conf load_cache < tmp.$$"
$PRE/unbound-control -c ub.conf load_cache < tmp.$$
if test $? -ne 0; then
echo "wrong exit value after success"
exit 1
fi
# do not check if cache dump contents are present ; other threads
# may not have gotten it when it is compiled with processes only.
# flushing
echo "$PRE/unbound-control -c ub.conf flush www.example.net"
$PRE/unbound-control -c ub.conf flush www.example.net
if test $? -ne 0; then
echo "wrong exit value after success"
exit 1
fi
echo "$PRE/unbound-control -c ub.conf flush_type www.example.net TXT"
$PRE/unbound-control -c ub.conf flush_type www.example.net TXT
if test $? -ne 0; then
echo "wrong exit value after success"
exit 1
fi
echo "$PRE/unbound-control -c ub.conf flush_zone example.net"
$PRE/unbound-control -c ub.conf flush_zone example.net
if test $? -ne 0; then
echo "wrong exit value after success"
exit 1
fi
# now stop the server
echo "$PRE/unbound-control -c ub.conf stop"
$PRE/unbound-control -c ub.conf stop
if test $? -ne 0; then
echo "wrong exit value after success"
exit 1
fi
# see if the server has really exited.
TRY_MAX=20
for (( try=0 ; try <= $TRY_MAX ; try++ )) ; do
if kill -0 $UNBOUND_PID 2>&1 | tee tmp.$$; then
echo "not stopped yet, waiting"
sleep 1
else
echo "stopped OK; break"
break;
fi
if grep "No such process" tmp.$$; then
echo "stopped OK; break"
break;
fi
done
if kill -0 $UNBOUND_PID; then
echo "still up!"
echo "> cat logfiles"
cat fwd.log
cat unbound.log
echo "not stopped, failure"
exit 1
else
echo "stopped OK"
if test -f ublocktrace.0; then
if $PRE/lock-verify ublocktrace.*; then
echo "lock-verify test worked."
else
echo "lock-verify test failed."
cat fwd.log
cat unbound.log
exit 1
fi
fi
fi
echo "> cat logfiles"
cat fwd.log
cat unbound.log
echo "> OK"
exit 0
-22
View File
@@ -1,22 +0,0 @@
; nameserver test file
$ORIGIN example.com.
$TTL 3600
ENTRY_BEGIN
MATCH opcode qtype qname
REPLY QR AA NOERROR
ADJUST copy_id
SECTION QUESTION
www IN A
SECTION ANSWER
www IN A 10.20.30.40
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
REPLY QR AA SERVFAIL
ADJUST copy_id
SECTION QUESTION
www.example.net. IN A
ENTRY_END
-39
View File
@@ -1,39 +0,0 @@
-----BEGIN RSA PRIVATE KEY-----
MIIG4gIBAAKCAYEAstEp+Pyh8XGrtZ77A4FhYjvbeB3dMa7Q2rGWxobzlA9przhA
1aChAvUtCOAuM+rB6NTNB8YWfZJbQHawyMNpmC77cg6vXLYCGUQHZyAqidN049RJ
F5T7j4N8Vniv17LiRdr0S6swy4PRvEnIPPV43EQHZqC5jVvHsKkhIfmBF/Dj5TXR
ypeawWV/m5jeU6/4HRYMfytBZdO1mPXuWLh0lgbQ4SCbgrOUVD3rniMk1yZIbQOm
vlDHYqekjDb/vOW2KxUQLG04aZMJ1mWfdbwG0CKQkSjISEDZ1l76vhM6mTM0fwXb
IvyFZ9yPPCle1mF5aSlxS2cmGuGVSRQaw8XF9fe3a9ACJJTr33HdSpyaZkKRAUzL
cKqLCl323daKv3NwwAT03Tj4iQM416ASMoiyfFa/2GWTKQVjddu8Crar7tGaf5xr
lig4DBmrBvdYA3njy72/RD71hLwmlRoCGU7dRuDr9O6KASUm1Ri91ONZ/qdjMvov
15l2vj4GV+KXR00dAgMBAAECggGAHepIL1N0dEQkCdpy+/8lH54L9WhpnOo2HqAf
LU9eaKK7d4jdr9+TkD8cLaPzltPrZNxVALvu/0sA4SP6J1wpyj/x6P7z73qzly5+
Xo5PD4fEwmi9YaiW/UduAblnEZrnp/AddptJKoL/D5T4XtpiQddPtael4zQ7kB57
YIexRSQTvEDovA/o3/nvA0TrzOxfgd4ycQP3iOWGN/TMzyLsvjydrUwbOB567iz9
whL3Etdgvnwh5Sz2blbFfH+nAR8ctvFFz+osPvuIVR21VMEI6wm7kTpSNnQ6sh/c
lrLb/bTADn4g7z/LpIZJ+MrLvyEcoqValrLYeFBhM9CV8woPxvkO2P3pU47HVGax
tC7GV6a/kt5RoKFd/TNdiA3OC7NGZtaeXv9VkPf4fVwBtSO9d5ZZXTGEynDD/rUQ
U4KFJe6OD23APjse08HiiKqTPhsOneOONU67iqoaTdIkT2R4EdlkVEDpXVtWb+G9
Q+IqYzVljlzuyHrhWXLJw/FMa2aBAoHBAOnZbi4gGpH+P6886WDWVgIlTccuXoyc
Mg9QQYk9UDeXxL0AizR5bZy49Sduegz9vkHpAiZARQsUnizHjZ8YlRcrmn4t6tx3
ahTIKAjdprnxJfYINM580j8CGbXvX5LhIlm3O267D0Op+co3+7Ujy+cjsIuFQrP+
1MqMgXSeBjzC1APivmps7HeFE+4w0k2PfN5wSMDNCzLo99PZuUG5XZ93OVOS5dpN
b+WskdcD8NOoJy/X/5A08veEI/jYO/DyqQKBwQDDwUQCOWf41ecvJLtBHKmEnHDz
ftzHino9DRKG8a9XaN4rmetnoWEaM2vHGX3pf3mwH+dAe8vJdAQueDhBKYeEpm6C
TYNOpou1+Zs5s99BilCTNYo8fkMOAyqwRwmz9zgHS6QxXuPwsghKefLJGt6o6RFF
tfWVTfLlYJ+I3GQe3ySsk3wjVz4oUTKiyiq5+KzD+HhEkS7u+RQ7Z0ZI2xd2cF8Y
aN2hjKDpcOiFf3CDoqka5D1qMNLgIHO52AHww1UCgcA1h7o7AMpURRka6hyaODY0
A4oMYEbwdQjYjIyT998W+rzkbu1us6UtzQEBZ760npkgyU/epbOoV63lnkCC/MOU
LD0PST+L/CHiY/cWIHb79YG1EifUZKpUFg0Aoq0EGFkepF0MefGCkbRGYA5UZr9U
R80wAu9D+L+JJiS0J0BSRF74DL196zUuHt5zFeXuLzxsRtPAnq9DliS08BACRYZy
7H3I7cWD9Vn5/0jbKWHFcaaWwyETR6uekTcSzZzbCRECgcBeoE3/xUA9SSk34Mmj
7/cB4522Ft0imA3+9RK/qJTZ7Bd5fC4PKjOGNtUiqW/0L2rjeIiQ40bfWvWqgPKw
jSK1PL6uvkl6+4cNsFsYyZpiVDoe7wKju2UuoNlB3RUTqa2r2STFuNj2wRjA57I1
BIgdnox65jqQsd14g/yaa+75/WP9CE45xzKEyrtvdcqxm0Pod3OrsYK+gikFjiar
kT0GQ8u0QPzh2tjt/2ZnIfOBrl+QYERP0MofDZDjhUdq2wECgcB0Lu841+yP5cdR
qbJhXO4zJNh7oWNcJlOuQp3ZMNFrA1oHpe9pmLukiROOy01k9WxIMQDzU5GSqRv3
VLkYOIcbhJ3kClKAcM3j95SkKbU2H5/RENb3Ck52xtl4pNU1x/3PnVFZfDVuuHO9
MZ9YBcIeK98MyP2jr5JtFKnOyPE7xKq0IHIhXadpbc2wjje5FtZ1cUtMyEECCXNa
C1TpXebHGyXGpY9WdWXhjdE/1jPvfS+uO5WyuDpYPr339gsdq1g=
-----END RSA PRIVATE KEY-----
-22
View File
@@ -1,22 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIDszCCAhsCFGD5193whHQ2bVdzbaQfdf1gc4SkMA0GCSqGSIb3DQEBCwUAMBIx
EDAOBgNVBAMMB3VuYm91bmQwHhcNMjAwNzA4MTMzMjMwWhcNNDAwMzI1MTMzMjMw
WjAaMRgwFgYDVQQDDA91bmJvdW5kLWNvbnRyb2wwggGiMA0GCSqGSIb3DQEBAQUA
A4IBjwAwggGKAoIBgQCy0Sn4/KHxcau1nvsDgWFiO9t4Hd0xrtDasZbGhvOUD2mv
OEDVoKEC9S0I4C4z6sHo1M0HxhZ9kltAdrDIw2mYLvtyDq9ctgIZRAdnICqJ03Tj
1EkXlPuPg3xWeK/XsuJF2vRLqzDLg9G8Scg89XjcRAdmoLmNW8ewqSEh+YEX8OPl
NdHKl5rBZX+bmN5Tr/gdFgx/K0Fl07WY9e5YuHSWBtDhIJuCs5RUPeueIyTXJkht
A6a+UMdip6SMNv+85bYrFRAsbThpkwnWZZ91vAbQIpCRKMhIQNnWXvq+EzqZMzR/
Bdsi/IVn3I88KV7WYXlpKXFLZyYa4ZVJFBrDxcX197dr0AIklOvfcd1KnJpmQpEB
TMtwqosKXfbd1oq/c3DABPTdOPiJAzjXoBIyiLJ8Vr/YZZMpBWN127wKtqvu0Zp/
nGuWKDgMGasG91gDeePLvb9EPvWEvCaVGgIZTt1G4Ov07ooBJSbVGL3U41n+p2My
+i/XmXa+PgZX4pdHTR0CAwEAATANBgkqhkiG9w0BAQsFAAOCAYEAd++Wen6l8Ifj
4h3p/y16PhSsWJWuJ4wdNYy3/GM84S26wGjzlEEwiW76HpH6VJzPOiBAeWnFKE83
hFyetEIxgJeIPbcs9ZP/Uoh8GZH9tRISBSN9Hgk2Slr9llo4t1H0g/XTgA5HqMQU
9YydlBh43G7Vw3FVwh09OM6poNOGQKNc/tq2/QdKeUMtyBbLWpRmjH5XcCT35fbn
ZiVOUldqSHD4kKrFO4nJYXZyipRbcXybsLiX9GP0GLemc3IgIvOXyJ2RPp06o/SJ
pzlMlkcAfLJaSuEW57xRakhuNK7m051TKKzJzIEX+NFYOVdafFHS8VwGrYsdrFvD
72tMfu+Fu55y3awdWWGc6YlaGogZiuMnJkvQphwgn+5qE/7CGEckoKEsH601rqIZ
muaIc85+nEcHJeijd/ZlBN9zeltjFoMuqTUENgmv8+tUAdVm/UMY9Vjme6b43ydP
uv6DS02+k9z8toxXworLiPr94BGaiGV1NxgwZKLZigYJt/Fi2Qte
-----END CERTIFICATE-----
-39
View File
@@ -1,39 +0,0 @@
-----BEGIN RSA PRIVATE KEY-----
MIIG5AIBAAKCAYEAvjSVSN2QMXudpzukdLCqgg/IOhCX8KYkD0FFFfWcQjgKq5wI
0x41iG32a6wbGanre4IX7VxaSPu9kkHfnGgynCk5nwDRedE/FLFhAU78PoT0+Nqq
GRS7XVQ24vLmIz9Hqc2Ozx1um1BXBTmIT0UfN2e22I0LWQ6a3seZlEDRj45gnk7Z
uh9MDgotaBdm+v1JAbupSf6Zis4VEH3JNdvVGE3O1DHEIeuuz/3BDhpf6WBDH+8K
WaBe1ca4TZHr9ThL2gEMEfAQl0wXDwRWRoi3NjNMH+mw0L1rjwThI5GXqNIee7o5
FzUReSXZuTdFMyGe3Owcx+XoYnwi6cplSNoGsDBu4B9bKKglR9YleJVw4L4Xi8xP
q6O9UPj4+nypHk/DOoC7DIM3ufN0yxPBsFo5TVowxfhdjZXJbbftd2TZv7AH8+XL
A5UoZgRzXgzECelXSCTBFlMTnT48LfA9pMLydyjAz2UdPHs5Iv+TK5nnI+aJoeaP
7kFZSngxdy1+A/bNAgMBAAECggGBALpTOIqQwVg4CFBylL/a8K1IWJTI/I65sklf
XxYL7G7SB2HlEJ//z+E+F0+S4Vlao1vyLQ5QkgE82pAUB8FoMWvY1qF0Y8A5wtm6
iZSGk4OLK488ZbT8Ii9i+AGKgPe2XbVxsJwj8N4k7Zooqec9hz73Up8ATEWJkRz7
2u7oMGG4z91E0PULA64dOi3l/vOQe5w/Aa+CwVbAWtI05o7kMvQEBMDJn6C7CByo
MB5op9wueJMnz7PM7hns+U7Dy6oE4ljuolJUy51bDzFWwoM54cRoQqLFNHd8JVQj
WxldCkbfF43iyprlsEcUrTyUjtdA+ZeiG39vg/mtdmgNpGmdupHJZQvSuG8IcVlz
O+eMSeQS1QXPD6Ik8UK4SU0h+zOl8xIWtRrsxQuh4fnTN40udm/YUWl/6gOebsBI
IrVLlKGqJSfB3tMjpCRqdTzJ0dA9keVpkqm2ugZkxEf1+/efq/rFIQ2pUBLCqNTN
qpNqruK8y8FphP30I2uI4Ej2UIB8AQKBwQDd2Yptj2FyDyaXCycsyde0wYkNyzGU
dRnzdibfHnMZwjgTjwAwgIUBVIS8H0/z7ZJQKN7osJfddMrtjJtYYUk9g/dCpHXs
bNh2QSoWah3FdzNGuWd0iRf9+LFxhjAAMo/FS8zFJAJKrFsBdCGTfFUMdsLC0bjr
YjiWBuvV72uKf8XIZX5KIZruKdWBBcWukcb21R1UDyFYyXRBsly5XHaIYKZql3km
7pV7MKWO0IYgHbHIqGUqPQlzZ/lkunS1jKECgcEA23wHffD6Ou9/x3okPx2AWpTr
gh8rgqbyo6hQkBW5Y90Wz824cqaYebZDaBR/xlVx/YwjKkohv8Bde2lpH/ZxRZ1Z
5Sk2s6GJ/vU0L9RsJZgCgj4L6Coal1NMxuZtCXAlnOpiCdxSZgfqbshbTVz30KsG
ZJG361Cua1ScdAHxlZBxT52/1Sm0zRC2hnxL7h4qo7Idmtzs40LAJvYOKekR0pPN
oWeJfra7vgx/jVNvMFWoOoSLpidVO4g+ot4ery6tAoHAdW3rCic1C2zdnmH28Iw+
s50l8Lk3mz+I5wgJd1zkzCO0DxZIoWPGA3g7cmCYr6N3KRsZMs4W9NAXgjpFGDkW
zYsG3K21BdpvkdjYcFjnPVjlOXB2RIc0vehf9Jl02wXoeCSxVUDEPcaRvWk9RJYx
ZpGOchUU7vNkxHURbIJ4yCzuAi9G8/Jp0dsu+kaV5tufF5SjG5WOrzKjaQsCbdN1
oqaWMCHRrTvov/Z2C+xwsptFOdN5CSyZzg6hQiI4GMlBAoHAXyb6KINcOEi0YMp3
BFXJ23tMTnEs78tozcKeipigcsbaqORK3omS+NEnj+uzKUzJyl4CsMbKstK2tFYS
mSTCHqgE3PBtIpsZtEqhgUraR8IK9GPpzZDTTl9ynZgwFTNlWw3RyuyVXF56J+T8
kCGJ3hEHCHqT/ZRQyX85BKIDFhA0z4tYKxWVqIFiYBNq56R0X9tMMmMs36mEnF93
7Ht6mowxTZQRa7nU0qOgeKh/P7ki4Zus3y+WJ+T9IqahLtlRAoHBAIhqMrcxSAB8
RpB9jukJlAnidw2jCMPgrFE8tP0khhVvGrXMldxAUsMKntDIo8dGCnG1KTcWDI0O
jepvSPHSsxVLFugL79h0eVIS5z4huW48i9xgU8VlHdgAcgEPIAOFcOw2BCu/s0Vp
O+MM/EyUOdo3NsibB3qc/GJI6iNBYS7AljYEVo6rXo5V/MZvZUF4vClen6Obzsre
MTTb+4sJjfqleWuvr1XNMeu2mBfXBQkWGZP1byBK0MvD/aQ2PWq92A==
-----END RSA PRIVATE KEY-----
-22
View File
@@ -1,22 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIDqzCCAhMCFBHWXeQ6ZIa9QcQbXLFfC6tj+KA+MA0GCSqGSIb3DQEBCwUAMBIx
EDAOBgNVBAMMB3VuYm91bmQwHhcNMjAwNzA4MTMzMjI5WhcNNDAwMzI1MTMzMjI5
WjASMRAwDgYDVQQDDAd1bmJvdW5kMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIB
igKCAYEAvjSVSN2QMXudpzukdLCqgg/IOhCX8KYkD0FFFfWcQjgKq5wI0x41iG32
a6wbGanre4IX7VxaSPu9kkHfnGgynCk5nwDRedE/FLFhAU78PoT0+NqqGRS7XVQ2
4vLmIz9Hqc2Ozx1um1BXBTmIT0UfN2e22I0LWQ6a3seZlEDRj45gnk7Zuh9MDgot
aBdm+v1JAbupSf6Zis4VEH3JNdvVGE3O1DHEIeuuz/3BDhpf6WBDH+8KWaBe1ca4
TZHr9ThL2gEMEfAQl0wXDwRWRoi3NjNMH+mw0L1rjwThI5GXqNIee7o5FzUReSXZ
uTdFMyGe3Owcx+XoYnwi6cplSNoGsDBu4B9bKKglR9YleJVw4L4Xi8xPq6O9UPj4
+nypHk/DOoC7DIM3ufN0yxPBsFo5TVowxfhdjZXJbbftd2TZv7AH8+XLA5UoZgRz
XgzECelXSCTBFlMTnT48LfA9pMLydyjAz2UdPHs5Iv+TK5nnI+aJoeaP7kFZSngx
dy1+A/bNAgMBAAEwDQYJKoZIhvcNAQELBQADggGBABunf93MKaCUHiZgnoOTinsW
84/EgInrgtKzAyH+BhnKkJOhhR0kkIAx5d9BpDlaSiRTACFon9moWCgDIIsK/Ar7
JE0Kln9cV//wiiNoFU0O4mnzyGUIMvlaEX6QHMJJQYvL05+w/3AAcf5XmMJtR5ca
fJ8FqvGC34b2WxX9lTQoyT52sRt+1KnQikiMEnEyAdKktMG+MwKsFDdOwDXyZhZg
XZhRrfX3/NVJolqB6EahjWIGXDeKuSSKZVtCyib6LskyeMzN5lcRfvubKDdlqFVF
qlD7rHBsKhQUWK/IO64mGf7y/de+CgHtED5vDvr/p2uj/9sABATfbrOQR3W/Of25
sLBj4OEfrJ7lX8hQgFaxkMI3x6VFT3W8dTCp7xnQgb6bgROWB5fNEZ9jk/gjSRmD
yIU+r0UbKe5kBk/CmZVFXL2TyJ92V5NYEQh8V4DGy19qZ6u/XKYyNJL4ocs35GGe
CA8SBuyrmdhx38h1RHErR2Skzadi1S7MwGf1y431fQ==
-----END CERTIFICATE-----
+2
View File
@@ -3,6 +3,8 @@
# use .tpkg.var.test for in test variable passing
[ -f .tpkg.var.test ] && source .tpkg.var.test
. ../common.sh
# only do this test if the network is up.
if dig @k.root-servers.net . SOA 2>&1 | grep NOERROR ; then
:
+2
View File
@@ -4,6 +4,8 @@
# use .tpkg.var.test for in test variable passing
[ -f .tpkg.var.test ] && source .tpkg.var.test
. ../common.sh
# dig 9 ?
digv=`dig -v 2>&1 | wc -l`
if test $digv -ne 1; then
+281
View File
@@ -0,0 +1,281 @@
; config options
server:
module-config: "respip validator iterator"
target-fetch-policy: "0 0 0 0 0"
qname-minimisation: no
access-control: 192.0.0.0/8 allow
access-control: 193.0.0.0/8 allow
define-tag: "internal server"
access-control-tag: 192.0.0.0/8 "internal"
access-control-tag: 127.0.0.0/8 "server"
; 193.0.0.0/8 has no tags
rpz:
name: "rpz.example.com."
rpz-log: yes
rpz-log-name: "rpz.example.com"
tags: "internal"
zonefile:
TEMPFILE_NAME rpz.example.com
TEMPFILE_CONTENTS rpz.example.com
$ORIGIN example.com.
rpz 3600 IN SOA ns1.rpz.example.com. hostmaster.rpz.example.com. (
1379078166 28800 7200 604800 7200 )
3600 IN NS ns1.rpz.example.com.
3600 IN NS ns2.rpz.example.com.
$ORIGIN rpz.example.com.
www.gotham.a A 1.2.3.61
www.gotham2.a CNAME g2.target.a.
g2.target.a A 1.2.3.62
www.gotham3.a CNAME g3.target.a.
g3.target.a CNAME g3b.target.a.
g3b.target.a A 1.2.3.63
www.gotham4.a CNAME g4.target.a.
g4.target.a CNAME g4b.target.a.
g4b.target.a CNAME g4c.target.a.
g4c.target.a A 1.2.3.64
; server for a.
32.40.30.20.10.rpz-nsip A 1.2.3.68
www.gotham5.a TXT "txt5"
TEMPFILE_END
stub-zone:
name: "a."
stub-addr: 10.20.30.40
CONFIG_END
SCENARIO_BEGIN Test RPZ handling of CNAMEs and tags.
; a.
RANGE_BEGIN 0 1000
ADDRESS 10.20.30.40
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
target.a. IN A
SECTION ANSWER
target.a. IN A 1.2.3.6
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www.gotham.a. IN A
SECTION ANSWER
www.gotham.a. IN A 1.2.3.5
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www.gotham2.a. IN A
SECTION ANSWER
www.gotham2.a. IN A 1.2.3.52
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www.gotham3.a. IN A
SECTION ANSWER
www.gotham3.a. IN A 1.2.3.53
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www.gotham4.a. IN A
SECTION ANSWER
www.gotham4.a. IN A 1.2.3.54
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www.gotham5.a. IN TXT
SECTION ANSWER
www.gotham5.a. IN TXT "gotham5"
ENTRY_END
RANGE_END
; Test with zero rpz CNAMEs, no tag match for rpz answer.
STEP 10 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.gotham.a. IN A
ENTRY_END
STEP 11 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
www.gotham.a. IN A
SECTION ANSWER
www.gotham.a. A 1.2.3.5
ENTRY_END
; Test with one rpz CNAME, no tag match for rpz answer.
STEP 20 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.gotham2.a. IN A
ENTRY_END
STEP 21 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
www.gotham2.a. IN A
SECTION ANSWER
www.gotham2.a. A 1.2.3.52
ENTRY_END
; Test with two rpz CNAMEs, no tag match for rpz answer.
STEP 30 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.gotham3.a. IN A
ENTRY_END
STEP 31 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
www.gotham3.a. IN A
SECTION ANSWER
www.gotham3.a. A 1.2.3.53
ENTRY_END
; Test with three rpz CNAMEs, no tag match for rpz answer.
STEP 40 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.gotham4.a. IN A
ENTRY_END
STEP 41 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
www.gotham4.a. IN A
SECTION ANSWER
www.gotham4.a. A 1.2.3.54
ENTRY_END
; Test with zero rpz CNAMEs, rpz answer. Tag "internal"
STEP 50 QUERY ADDRESS 192.0.0.1
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.gotham.a. IN A
ENTRY_END
STEP 51 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AA NOERROR
SECTION QUESTION
www.gotham.a. IN A
SECTION ANSWER
www.gotham.a. A 1.2.3.61
ENTRY_END
; Test with one rpz CNAME, rpz answer. Tag "internal"
STEP 60 QUERY ADDRESS 192.0.0.1
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.gotham2.a. IN A
ENTRY_END
STEP 61 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AA NOERROR
SECTION QUESTION
www.gotham2.a. IN A
SECTION ANSWER
www.gotham2.a. CNAME g2.target.a.
g2.target.a. A 1.2.3.62
ENTRY_END
; Test with two rpz CNAMEs, rpz answer. Tag "internal"
STEP 70 QUERY ADDRESS 192.0.0.1
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.gotham3.a. IN A
ENTRY_END
STEP 71 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AA NOERROR
SECTION QUESTION
www.gotham3.a. IN A
SECTION ANSWER
www.gotham3.a. CNAME g3.target.a.
g3.target.a. CNAME g3b.target.a.
g3b.target.a. A 1.2.3.63
ENTRY_END
; Test with three rpz CNAMEs, rpz answer. Tag "internal"
STEP 80 QUERY ADDRESS 192.0.0.1
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.gotham4.a. IN A
ENTRY_END
STEP 81 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AA NOERROR
SECTION QUESTION
www.gotham4.a. IN A
SECTION ANSWER
www.gotham4.a. CNAME g4.target.a.
g4.target.a. CNAME g4b.target.a.
g4b.target.a. CNAME g4c.target.a.
g4c.target.a. A 1.2.3.64
ENTRY_END
; Test with zero rpz CNAMEs, no tags for the query, and so no rpz answer.
STEP 90 QUERY ADDRESS 193.0.0.1
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.gotham5.a. IN TXT
ENTRY_END
STEP 91 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
www.gotham5.a. IN TXT
SECTION ANSWER
www.gotham5.a. IN TXT "gotham5"
ENTRY_END
SCENARIO_END
+50 -24
View File
@@ -42,6 +42,7 @@
#include "config.h"
#include <ctype.h>
#include <stdarg.h>
#include <errno.h>
#ifdef HAVE_TIME_H
#include <time.h>
#endif
@@ -1772,6 +1773,39 @@ init_outgoing_availports(int* a, int num)
}
}
static int
extract_port_from_str(const char* str, int max_port) {
char* endptr;
long int value;
if (str == NULL || *str == '\0') {
log_err("str: '%s' is invalid", (str?str:"NULL"));
return -1;
}
value = strtol(str, &endptr, 10);
if ((endptr == str) || (*endptr != '\0')) {
log_err("cannot parse port number '%s'", str);
return -1;
}
if (errno == ERANGE) {
log_err("overflow occurred when parsing '%s'", str);
return -1;
}
if (value == 0 && strcmp(str, "0") != 0) {
log_err("cannot parse port number '%s'", str);
return -1;
}
if (value < 0 || value >= max_port) {
log_err(" '%s' is out of bounds [0, %d)", str, max_port);
return -1;
}
return (int)value;
}
int
cfg_mark_ports(const char* str, int allow, int* avail, int num)
{
@@ -1782,53 +1816,45 @@ cfg_mark_ports(const char* str, int allow, int* avail, int num)
"options");
#endif
if(!mid) {
int port = atoi(str);
if(port < 0) {
log_err("port number is negative: %d", port);
return 0;
}
if(port == 0 && strcmp(str, "0") != 0) {
log_err("cannot parse port number '%s'", str);
int port = extract_port_from_str(str, num);
if (port < 0) {
log_err("Failed to parse the port number");
return 0;
}
if(port < num)
avail[port] = (allow?port:0);
} else {
int i, low, high = atoi(mid+1);
char buf[16];
if(high < 0) {
log_err("port number is negative: %d", high);
return 0;
}
if(high == 0 && strcmp(mid+1, "0") != 0) {
log_err("cannot parse port number '%s'", mid+1);
int i, low;
int high = extract_port_from_str(mid+1, num);
if (high < 0) {
log_err("Failed to parse the port number");
return 0;
}
if( (int)(mid-str)+1 >= (int)sizeof(buf) ) {
log_err("cannot parse port number '%s'", str);
return 0;
}
if(mid > str)
memcpy(buf, str, (size_t)(mid-str));
buf[mid-str] = 0;
low = atoi(buf);
if(low < 0) {
log_err("port number is negative: %d", low);
low = extract_port_from_str(buf, num);
if (low < 0) {
log_err("Failed to parse the port number");
return 0;
}
if(low == 0 && strcmp(buf, "0") != 0) {
log_err("cannot parse port number '%s'", buf);
if (low > high) {
log_err("Low value is greater than high value");
return 0;
}
if(high > num) {
/* Stop very high values from taking a long time. */
high = num;
}
for(i=low; i<=high; i++) {
if(i < num)
avail[i] = (allow?i:0);
}
return 1;
}
return 1;
}
+24 -8
View File
@@ -357,8 +357,14 @@ stubstart: VAR_STUB_ZONE
}
}
;
contents_stub: contents_stub content_stub
| ;
contents_stub: content_stub contents_stub
|
{
/* stub end */
if(cfg_parser->cfg->stubs &&
!cfg_parser->cfg->stubs->name)
yyerror("stub-zone without name");
};
content_stub: stub_name | stub_host | stub_addr | stub_prime | stub_first |
stub_no_cache | stub_ssl_upstream | stub_tcp_upstream
;
@@ -376,8 +382,14 @@ forwardstart: VAR_FORWARD_ZONE
}
}
;
contents_forward: contents_forward content_forward
| ;
contents_forward: content_forward contents_forward
|
{
/* forward end */
if(cfg_parser->cfg->forwards &&
!cfg_parser->cfg->forwards->name)
yyerror("forward-zone without name");
};
content_forward: forward_name | forward_host | forward_addr | forward_first |
forward_no_cache | forward_ssl_upstream | forward_tcp_upstream
;
@@ -389,16 +401,20 @@ viewstart: VAR_VIEW
s = (struct config_view*)calloc(1, sizeof(struct config_view));
if(s) {
s->next = cfg_parser->cfg->views;
if(s->next && !s->next->name)
yyerror("view without name");
cfg_parser->cfg->views = s;
} else {
yyerror("out of memory");
}
}
;
contents_view: contents_view content_view
| ;
contents_view: content_view contents_view
|
{
/* view end */
if(cfg_parser->cfg->views &&
!cfg_parser->cfg->views->name)
yyerror("view without name");
};
content_view: view_name | view_local_zone | view_local_data | view_first |
view_response_ip | view_response_ip_data | view_local_data_ptr
;
+1 -1
View File
@@ -225,7 +225,7 @@ int dname_strict_subdomain(uint8_t* d1, int labs1, uint8_t* d2, int labs2);
int dname_strict_subdomain_c(uint8_t* d1, uint8_t* d2);
/**
* Counts labels. Tests is d1 is a subdomain of d2.
* Counts labels. Tests if d1 is a subdomain of d2.
* @param d1: domain name, uncompressed wireformat
* @param d2: domain name, uncompressed wireformat
* @return true if d1 is a subdomain of d2.
+14
View File
@@ -862,6 +862,20 @@ addr_is_ip4mapped(struct sockaddr_storage* addr, socklen_t addrlen)
return (memcmp(s, map_prefix, 12) == 0);
}
int addr_is_ip6linklocal(struct sockaddr_storage* addr, socklen_t addrlen)
{
const uint8_t prefix[2] = {0xfe, 0x80};
int af = (int)((struct sockaddr_in6*)addr)->sin6_family;
void* sin6addr = &((struct sockaddr_in6*)addr)->sin6_addr;
uint8_t start[2];
if(af != AF_INET6 || addrlen<(socklen_t)sizeof(struct sockaddr_in6))
return 0;
/* Put the first 10 bits of sin6addr in start, match fe80::/10. */
memmove(start, sin6addr, 2);
start[1] &= 0xc0;
return memcmp(start, prefix, 2) == 0;
}
int addr_is_broadcast(struct sockaddr_storage* addr, socklen_t addrlen)
{
int af = (int)((struct sockaddr_in*)addr)->sin_family;
+8
View File
@@ -362,6 +362,14 @@ void addr_to_nat64(const struct sockaddr_storage* addr,
*/
int addr_is_ip4mapped(struct sockaddr_storage* addr, socklen_t addrlen);
/**
* See if sockaddr is an ipv6 fe80::/10 link local address.
* @param addr: address
* @param addrlen: length of address
* @return true if so
*/
int addr_is_ip6linklocal(struct sockaddr_storage* addr, socklen_t addrlen);
/**
* See if sockaddr is 255.255.255.255.
* @param addr: address
+7 -6
View File
@@ -2365,11 +2365,11 @@ recv_error:
#ifndef USE_WINSOCK
if(errno == EINTR || errno == EAGAIN)
return 1;
if(recv_initial) {
#ifdef ECONNRESET
if(errno == ECONNRESET && verbosity < 2)
return 0; /* silence reset by peer */
if(errno == ECONNRESET && verbosity < 2)
return 0; /* silence reset by peer */
#endif
if(recv_initial) {
#ifdef ECONNREFUSED
if(errno == ECONNREFUSED && verbosity < 2)
return 0; /* silence reset by peer */
@@ -2396,7 +2396,7 @@ recv_error:
#endif
#ifdef ENOTCONN
if(errno == ENOTCONN) {
log_err_addr("read (in tcp s) failed and this "
log_err_addr("read (in tcp initial) failed and this "
"could be because TCP Fast Open is "
"enabled [--disable-tfo-client "
"--disable-tfo-server] but does not "
@@ -2430,8 +2430,9 @@ recv_error:
return 1;
}
#endif
log_err_addr("read (in tcp s)", sock_strerror(errno),
&c->repinfo.remote_addr, c->repinfo.remote_addrlen);
log_err_addr((recv_initial?"read (in tcp initial)":"read (in tcp)"),
sock_strerror(errno), &c->repinfo.remote_addr,
c->repinfo.remote_addrlen);
return 0;
}