mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-08-17 21:25:50 +02:00
Compare commits
167
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6e7717986b | ||
|
|
b770699319 | ||
|
|
fe5370a98a | ||
|
|
4b354d38c1 | ||
|
|
a9b7638f4b | ||
|
|
42fdfd8121 | ||
|
|
2665ae0414 | ||
|
|
77bdbc6e98 | ||
|
|
00d622bed7 | ||
|
|
9e193be648 | ||
|
|
7dcfe531e4 | ||
|
|
e965775064 | ||
|
|
6e13c6f401 | ||
|
|
2916cfb3b0 | ||
|
|
da2bda6f4d | ||
|
|
adda4f6ace | ||
|
|
c316b1d7d5 | ||
|
|
aee3706f66 | ||
|
|
8e135d5f59 | ||
|
|
5d6358b66d | ||
|
|
4089147351 | ||
|
|
18ea62e369 | ||
|
|
d000523b00 | ||
|
|
0758d29324 | ||
|
|
af7abd4dfd | ||
|
|
7e061e4d5f | ||
|
|
f7fe95ad7b | ||
|
|
5980d9c389 | ||
|
|
4fc622031d | ||
|
|
dde8631600 | ||
|
|
8c88ab4747 | ||
|
|
a4a9fbdb8f | ||
|
|
7495b25f94 | ||
|
|
810862dc65 | ||
|
|
a4244e79ca | ||
|
|
833021d84d | ||
|
|
2c459443da | ||
|
|
1646b26369 | ||
|
|
056176ec9a | ||
|
|
d69ba6f39f | ||
|
|
882741bf55 | ||
|
|
5dc6798e75 | ||
|
|
4f5b934688 | ||
|
|
b9c9fc066f | ||
|
|
833c4b1300 | ||
|
|
a5f133ef2f | ||
|
|
de5c0d4228 | ||
|
|
e4e00db42e | ||
|
|
3609287344 | ||
|
|
20a2574da1 | ||
|
|
bf13191b87 | ||
|
|
5fcae2f0e0 | ||
|
|
4326b10169 | ||
|
|
d82de651c6 | ||
|
|
61c2333174 | ||
|
|
88a706acf8 | ||
|
|
7da16febc4 | ||
|
|
079de39b46 | ||
|
|
1d9185229e | ||
|
|
ef120738c0 | ||
|
|
396d4223d9 | ||
|
|
9aa4b5a7a6 | ||
|
|
939cf38576 | ||
|
|
9df07b4036 | ||
|
|
6c0a863584 | ||
|
|
a930b94658 | ||
|
|
13a7783d7b | ||
|
|
f6287fc718 | ||
|
|
c0789a8785 | ||
|
|
c3fac2550f | ||
|
|
0feee99055 | ||
|
|
1d0fc2d179 | ||
|
|
41621fb1df | ||
|
|
6b3df091fe | ||
|
|
7e200ce90e | ||
|
|
cfce0a5e60 | ||
|
|
72bfa5a48c | ||
|
|
1464bedce2 | ||
|
|
68ff1730ac | ||
|
|
82a6a2f8cc | ||
|
|
0ae684830a | ||
|
|
ec9e4eb406 | ||
|
|
394f9403df | ||
|
|
36b5d74fc4 | ||
|
|
f6b4f2a149 | ||
|
|
61456ff81d | ||
|
|
ff92edcd41 | ||
|
|
c3f6f0a332 | ||
|
|
016f742f16 | ||
|
|
05cb07093d | ||
|
|
e00ce7e02e | ||
|
|
bda4c4a375 | ||
|
|
b78373216d | ||
|
|
24131ca29e | ||
|
|
72c4c6b30c | ||
|
|
fd6456dd56 | ||
|
|
53d85f903c | ||
|
|
9877e52161 | ||
|
|
627285af23 | ||
|
|
16543731f5 | ||
|
|
344f12dd99 | ||
|
|
14913d75c0 | ||
|
|
e098285892 | ||
|
|
1e0c957dcd | ||
|
|
ea26e5038e | ||
|
|
2c4be0c201 | ||
|
|
9b3f3101e3 | ||
|
|
e149bc7046 | ||
|
|
a8db52120b | ||
|
|
92a525225b | ||
|
|
1e8d20de0d | ||
|
|
89d98564c3 | ||
|
|
c4e199ecca | ||
|
|
5ae1544583 | ||
|
|
05a5dc2d0d | ||
|
|
19473d95eb | ||
|
|
8686b0abbf | ||
|
|
d68ece28c4 | ||
|
|
453c84b237 | ||
|
|
20a3d3be5f | ||
|
|
d982dff464 | ||
|
|
2abaca7a49 | ||
|
|
ae4f6a259b | ||
|
|
da6ac0c4ff | ||
|
|
1d45b4a1e0 | ||
|
|
40787a06d8 | ||
|
|
90b42b56b6 | ||
|
|
13a76ba0a6 | ||
|
|
f1d5d5d682 | ||
|
|
0a499ec2ee | ||
|
|
41d3e2027c | ||
|
|
bbb737ca5a | ||
|
|
f3dfb4d537 | ||
|
|
9843b836ee | ||
|
|
4ac33aa104 | ||
|
|
2b5cd8e9b4 | ||
|
|
bc39217070 | ||
|
|
ccb576f95e | ||
|
|
a16111d471 | ||
|
|
965f16cc89 | ||
|
|
4cbf4f4996 | ||
|
|
88fce791df | ||
|
|
7180284d82 | ||
|
|
401fc15443 | ||
|
|
4eb7771f97 | ||
|
|
abbb5c0f6d | ||
|
|
0987a82877 | ||
|
|
1c5d081853 | ||
|
|
9ce7045413 | ||
|
|
a8d6147ae4 | ||
|
|
395d83cfc8 | ||
|
|
3021e320dd | ||
|
|
a77c35ef50 | ||
|
|
bc83e0b016 | ||
|
|
268580f348 | ||
|
|
b0b69321f9 | ||
|
|
a7f68865e4 | ||
|
|
8dac8c00ce | ||
|
|
83bf2fd253 | ||
|
|
46acf0f99d | ||
|
|
ba67920f9a | ||
|
|
186c9e8e82 | ||
|
|
74f11b852c | ||
|
|
edcf2ddd12 | ||
|
|
c66e47c372 | ||
|
|
9274d2630e | ||
|
|
b43b8d47f8 |
@@ -0,0 +1,12 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||
patreon: # Replace with a single Patreon username
|
||||
open_collective: # Replace with a single Open Collective username
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
liberapay: # Replace with a single Liberapay username
|
||||
issuehunt: # Replace with a single IssueHunt username
|
||||
otechie: # Replace with a single Otechie username
|
||||
custom: ['https://nlnetlabs.nl/funding/']
|
||||
@@ -42,6 +42,7 @@
|
||||
/contrib/libunbound.pc
|
||||
/contrib/unbound.service
|
||||
/contrib/unbound.socket
|
||||
/contrib/unbound_portable.service
|
||||
/dnstap/dnstap.pb-c.c
|
||||
/dnstap/dnstap.pb-c.h
|
||||
/libunbound/python/libunbound_wrap.c
|
||||
|
||||
+409
-375
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@ Unbound is a validating, recursive, caching DNS resolver. It is designed to be
|
||||
fast and lean and incorporates modern features based on open standards. If you
|
||||
have any feedback, we would love to hear from you. Don’t hesitate to
|
||||
[create an issue on Github](https://github.com/NLnetLabs/unbound/issues/new)
|
||||
or post a message on the [Unbound mailing list](https://nlnetlabs.nl/mailman/listinfo/unbound-users).
|
||||
or post a message on the [Unbound mailing list](https://lists.nlnetlabs.nl/mailman/listinfo/unbound-users).
|
||||
You can lean more about Unbound by reading our
|
||||
[documentation](https://nlnetlabs.nl/documentation/unbound/).
|
||||
|
||||
|
||||
+60
-34
@@ -64,26 +64,26 @@
|
||||
#ifdef HAVE_SYS_ENDIAN_H
|
||||
# include <sys/endian.h>
|
||||
#endif
|
||||
#ifdef HAVE_LIBKERN_OSBYTEORDER_H
|
||||
/* In practice this is specific to MacOS X. We assume it doesn't have
|
||||
* htobe64/be64toh but has alternatives with a different name. */
|
||||
# include <libkern/OSByteOrder.h>
|
||||
# define htobe64(x) OSSwapHostToBigInt64(x)
|
||||
# define be64toh(x) OSSwapBigToHostInt64(x)
|
||||
#endif
|
||||
|
||||
/* Some compilers do not define __BYTE_ORDER__, like IBM XLC on AIX */
|
||||
#ifndef be64toh
|
||||
#if defined(__sun) || defined(_AIX)
|
||||
# if __BIG_ENDIAN__
|
||||
# define be64toh(n) (n)
|
||||
# define htobe64(n) (n)
|
||||
#ifndef HAVE_HTOBE64
|
||||
# ifdef HAVE_LIBKERN_OSBYTEORDER_H
|
||||
/* In practice this is specific to MacOS X. We assume it doesn't have
|
||||
* htobe64/be64toh but has alternatives with a different name. */
|
||||
# include <libkern/OSByteOrder.h>
|
||||
# define htobe64(x) OSSwapHostToBigInt64(x)
|
||||
# define be64toh(x) OSSwapBigToHostInt64(x)
|
||||
# else
|
||||
# define be64toh(n) (((uint64_t)htonl((n) & 0xFFFFFFFF) << 32) | htonl((n) >> 32))
|
||||
# define htobe64(n) (((uint64_t)htonl((n) & 0xFFFFFFFF) << 32) | htonl((n) >> 32))
|
||||
# endif
|
||||
#endif
|
||||
#endif /* be64toh */
|
||||
/* not OSX */
|
||||
/* Some compilers do not define __BYTE_ORDER__, like IBM XLC on AIX */
|
||||
# if __BIG_ENDIAN__
|
||||
# define be64toh(n) (n)
|
||||
# define htobe64(n) (n)
|
||||
# else
|
||||
# define be64toh(n) (((uint64_t)htonl((n) & 0xFFFFFFFF) << 32) | htonl((n) >> 32))
|
||||
# define htobe64(n) (((uint64_t)htonl((n) & 0xFFFFFFFF) << 32) | htonl((n) >> 32))
|
||||
# endif /* _ENDIAN */
|
||||
# endif /* HAVE_LIBKERN_OSBYTEORDER_H */
|
||||
#endif /* HAVE_BE64TOH */
|
||||
|
||||
/** the unit test testframe for cachedb, its module state contains
|
||||
* a cache for a couple queries (in memory). */
|
||||
@@ -218,10 +218,6 @@ static int
|
||||
cachedb_apply_cfg(struct cachedb_env* cachedb_env, struct config_file* cfg)
|
||||
{
|
||||
const char* backend_str = cfg->cachedb_backend;
|
||||
|
||||
/* If unspecified we use the in-memory test DB. */
|
||||
if(!backend_str)
|
||||
backend_str = "testframe";
|
||||
cachedb_env->backend = cachedb_find_backend(backend_str);
|
||||
if(!cachedb_env->backend) {
|
||||
log_err("cachedb: cannot find backend name '%s'", backend_str);
|
||||
@@ -259,6 +255,15 @@ cachedb_init(struct module_env* env, int id)
|
||||
return 0;
|
||||
}
|
||||
cachedb_env->enabled = 1;
|
||||
if(env->cfg->serve_expired_reply_ttl)
|
||||
log_warn(
|
||||
"cachedb: serve-expired-reply-ttl is set but not working for data "
|
||||
"originating from the external cache; 0 TLL is used for those.");
|
||||
if(env->cfg->serve_expired_client_timeout)
|
||||
log_warn(
|
||||
"cachedb: serve-expired-client-timeout is set but not working for "
|
||||
"data originating from the external cache; expired data are used "
|
||||
"in the reply without first trying to refresh the data.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -329,8 +334,7 @@ calc_hash(struct module_qstate* qstate, char* buf, size_t len)
|
||||
size_t clen = 0;
|
||||
uint8_t hash[CACHEDB_HASHSIZE/8];
|
||||
const char* hex = "0123456789ABCDEF";
|
||||
const char* secret = qstate->env->cfg->cachedb_secret ?
|
||||
qstate->env->cfg->cachedb_secret : "default";
|
||||
const char* secret = qstate->env->cfg->cachedb_secret;
|
||||
size_t i;
|
||||
|
||||
/* copy the hash info into the clear buffer */
|
||||
@@ -433,8 +437,14 @@ good_expiry_and_qinfo(struct module_qstate* qstate, struct sldns_buffer* buf)
|
||||
&expiry, sizeof(expiry));
|
||||
expiry = be64toh(expiry);
|
||||
|
||||
/* Check if we are allowed to return expired entries:
|
||||
* - serve_expired needs to be set
|
||||
* - if SERVE_EXPIRED_TTL is set make sure that the record is not older
|
||||
* than that. */
|
||||
if((time_t)expiry < *qstate->env->now &&
|
||||
!qstate->env->cfg->serve_expired)
|
||||
(!qstate->env->cfg->serve_expired ||
|
||||
(SERVE_EXPIRED_TTL &&
|
||||
*qstate->env->now - (time_t)expiry > SERVE_EXPIRED_TTL)))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
@@ -445,15 +455,15 @@ good_expiry_and_qinfo(struct module_qstate* qstate, struct sldns_buffer* buf)
|
||||
static void
|
||||
packed_rrset_ttl_subtract(struct packed_rrset_data* data, time_t subtract)
|
||||
{
|
||||
size_t i;
|
||||
size_t total = data->count + data->rrsig_count;
|
||||
size_t i;
|
||||
size_t total = data->count + data->rrsig_count;
|
||||
if(subtract >= 0 && data->ttl > subtract)
|
||||
data->ttl -= subtract;
|
||||
else data->ttl = 0;
|
||||
for(i=0; i<total; i++) {
|
||||
for(i=0; i<total; i++) {
|
||||
if(subtract >= 0 && data->rr_ttl[i] > subtract)
|
||||
data->rr_ttl[i] -= subtract;
|
||||
else data->rr_ttl[i] = 0;
|
||||
data->rr_ttl[i] -= subtract;
|
||||
else data->rr_ttl[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -465,7 +475,8 @@ adjust_msg_ttl(struct dns_msg* msg, time_t adjust)
|
||||
size_t i;
|
||||
if(adjust >= 0 && msg->rep->ttl > adjust)
|
||||
msg->rep->ttl -= adjust;
|
||||
else msg->rep->ttl = 0;
|
||||
else
|
||||
msg->rep->ttl = 0;
|
||||
msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl);
|
||||
msg->rep->serve_expired_ttl = msg->rep->ttl + SERVE_EXPIRED_TTL;
|
||||
|
||||
@@ -673,7 +684,8 @@ cachedb_handle_query(struct module_qstate* qstate,
|
||||
return;
|
||||
}
|
||||
|
||||
/* lookup inside unbound's internal cache */
|
||||
/* lookup inside unbound's internal cache.
|
||||
* This does not look for expired entries. */
|
||||
if(cachedb_intcache_lookup(qstate)) {
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
if(qstate->return_msg->rep)
|
||||
@@ -681,8 +693,9 @@ cachedb_handle_query(struct module_qstate* qstate,
|
||||
&qstate->return_msg->qinfo,
|
||||
qstate->return_msg->rep);
|
||||
else log_info("cachedb internal cache lookup: rcode %s",
|
||||
sldns_lookup_by_id(sldns_rcodes, qstate->return_rcode)?
|
||||
sldns_lookup_by_id(sldns_rcodes, qstate->return_rcode)->name:"??");
|
||||
sldns_lookup_by_id(sldns_rcodes, qstate->return_rcode)
|
||||
?sldns_lookup_by_id(sldns_rcodes, qstate->return_rcode)->name
|
||||
:"??");
|
||||
}
|
||||
/* we are done with the query */
|
||||
qstate->ext_state[id] = module_finished;
|
||||
@@ -697,6 +710,19 @@ cachedb_handle_query(struct module_qstate* qstate,
|
||||
qstate->return_msg->rep);
|
||||
/* store this result in internal cache */
|
||||
cachedb_intcache_store(qstate);
|
||||
/* In case we have expired data but there is a client timer for expired
|
||||
* answers, pass execution to next module in order to try updating the
|
||||
* data first.
|
||||
* TODO: this needs revisit. The expired data stored from cachedb has
|
||||
* 0 TTL which is picked up by iterator later when looking in the cache.
|
||||
* Document that ext cachedb does not work properly with
|
||||
* serve_stale_reply_ttl yet. */
|
||||
if(qstate->need_refetch && qstate->serve_expired_data &&
|
||||
qstate->serve_expired_data->timer) {
|
||||
qstate->return_msg = NULL;
|
||||
qstate->ext_state[id] = module_wait_module;
|
||||
return;
|
||||
}
|
||||
/* we are done with the query */
|
||||
qstate->ext_state[id] = module_finished;
|
||||
return;
|
||||
|
||||
+39
-27
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: getentropy_solaris.c,v 1.13 2018/11/20 08:04:28 deraadt Exp $ */
|
||||
/* $OpenBSD: getentropy_solaris.c,v 1.4 2014/07/12 20:41:47 wouter Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014 Theo de Raadt <deraadt@openbsd.org>
|
||||
@@ -15,12 +15,9 @@
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Emulation of getentropy(2) as documented at:
|
||||
* http://man.openbsd.org/getentropy.2
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
@@ -37,7 +34,6 @@
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <link.h>
|
||||
#include <termios.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
@@ -71,14 +67,17 @@
|
||||
|
||||
#define HR(x, l) (SHA512_Update(&ctx, (char *)(x), (l)))
|
||||
#define HD(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (x)))
|
||||
#define HF(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (void*)))
|
||||
#define HF(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (void*)))
|
||||
|
||||
int getentropy(void *buf, size_t len);
|
||||
|
||||
#ifdef CAN_REFERENCE_MAIN
|
||||
extern int main(int, char *argv[]);
|
||||
#endif
|
||||
static int gotdata(char *buf, size_t len);
|
||||
static int getentropy_urandom(void *buf, size_t len, const char *path,
|
||||
int devfscheck);
|
||||
static int getentropy_fallback(void *buf, size_t len);
|
||||
static int getentropy_phdr(struct dl_phdr_info *info, size_t size, void *data);
|
||||
|
||||
int
|
||||
getentropy(void *buf, size_t len)
|
||||
@@ -87,7 +86,7 @@ getentropy(void *buf, size_t len)
|
||||
|
||||
if (len > 256) {
|
||||
errno = EIO;
|
||||
return (-1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -154,6 +153,22 @@ getentropy(void *buf, size_t len)
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Basic sanity checking; wish we could do better.
|
||||
*/
|
||||
static int
|
||||
gotdata(char *buf, size_t len)
|
||||
{
|
||||
char any_set = 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
any_set |= buf[i];
|
||||
if (any_set == 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
getentropy_urandom(void *buf, size_t len, const char *path, int devfscheck)
|
||||
{
|
||||
@@ -200,11 +215,13 @@ start:
|
||||
i += ret;
|
||||
}
|
||||
close(fd);
|
||||
errno = save_errno;
|
||||
return (0); /* satisfied */
|
||||
if (gotdata(buf, len) == 0) {
|
||||
errno = save_errno;
|
||||
return 0; /* satisfied */
|
||||
}
|
||||
nodevrandom:
|
||||
errno = EIO;
|
||||
return (-1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const int cl[] = {
|
||||
@@ -232,15 +249,6 @@ static const int cl[] = {
|
||||
#endif
|
||||
};
|
||||
|
||||
static int
|
||||
getentropy_phdr(struct dl_phdr_info *info, size_t size, void *data)
|
||||
{
|
||||
SHA512_CTX *ctx = data;
|
||||
|
||||
SHA512_Update(ctx, &info->dlpi_addr, sizeof (info->dlpi_addr));
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
getentropy_fallback(void *buf, size_t len)
|
||||
{
|
||||
@@ -278,8 +286,6 @@ getentropy_fallback(void *buf, size_t len)
|
||||
cnt += (int)tv.tv_usec;
|
||||
}
|
||||
|
||||
dl_iterate_phdr(getentropy_phdr, &ctx);
|
||||
|
||||
for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]); ii++)
|
||||
HX(clock_gettime(cl[ii], &ts) == -1, ts);
|
||||
|
||||
@@ -300,6 +306,9 @@ getentropy_fallback(void *buf, size_t len)
|
||||
HX(sigprocmask(SIG_BLOCK, NULL, &sigset) == -1,
|
||||
sigset);
|
||||
|
||||
#ifdef CAN_REFERENCE_MAIN
|
||||
HF(main); /* an addr in program */
|
||||
#endif
|
||||
HF(getentropy); /* an addr in this library */
|
||||
HF(printf); /* an addr in libc */
|
||||
p = (char *)&p;
|
||||
@@ -422,8 +431,11 @@ getentropy_fallback(void *buf, size_t len)
|
||||
memcpy((char *)buf + i, results, min(sizeof(results), len - i));
|
||||
i += min(sizeof(results), len - i);
|
||||
}
|
||||
explicit_bzero(&ctx, sizeof ctx);
|
||||
explicit_bzero(results, sizeof results);
|
||||
errno = save_errno;
|
||||
return (0); /* satisfied */
|
||||
memset(results, 0, sizeof results);
|
||||
if (gotdata(buf, len) == 0) {
|
||||
errno = save_errno;
|
||||
return 0; /* satisfied */
|
||||
}
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
+20
@@ -63,6 +63,15 @@
|
||||
/* Whether the C compiler accepts the "weak" attribute */
|
||||
#undef HAVE_ATTR_WEAK
|
||||
|
||||
/* If we have be64toh */
|
||||
#undef HAVE_BE64TOH
|
||||
|
||||
/* Define to 1 if you have the <bsd/stdlib.h> header file. */
|
||||
#undef HAVE_BSD_STDLIB_H
|
||||
|
||||
/* Define to 1 if you have the <bsd/string.h> header file. */
|
||||
#undef HAVE_BSD_STRING_H
|
||||
|
||||
/* Define to 1 if you have the `chown' function. */
|
||||
#undef HAVE_CHOWN
|
||||
|
||||
@@ -284,6 +293,9 @@
|
||||
/* If you have HMAC_Update */
|
||||
#undef HAVE_HMAC_UPDATE
|
||||
|
||||
/* If we have htobe64 */
|
||||
#undef HAVE_HTOBE64
|
||||
|
||||
/* Define to 1 if you have the `inet_aton' function. */
|
||||
#undef HAVE_INET_ATON
|
||||
|
||||
@@ -311,6 +323,9 @@
|
||||
/* Define to 1 if you have the `kill' function. */
|
||||
#undef HAVE_KILL
|
||||
|
||||
/* Use portable libbsd functions */
|
||||
#undef HAVE_LIBBSD
|
||||
|
||||
/* Define to 1 if you have the <libkern/OSByteOrder.h> header file. */
|
||||
#undef HAVE_LIBKERN_OSBYTEORDER_H
|
||||
|
||||
@@ -1231,6 +1246,11 @@ char *strptime(const char *s, const char *format, struct tm *tm);
|
||||
void *reallocarray(void *ptr, size_t nmemb, size_t size);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBBSD
|
||||
#include <bsd/string.h>
|
||||
#include <bsd/stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBRESSL
|
||||
# if !HAVE_DECL_STRLCPY
|
||||
size_t strlcpy(char *dst, const char *src, size_t siz);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.69 for unbound 1.9.6.
|
||||
# Generated by GNU Autoconf 2.69 for unbound 1.10.0.
|
||||
#
|
||||
# Report bugs to <unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues>.
|
||||
#
|
||||
@@ -591,8 +591,8 @@ MAKEFLAGS=
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='unbound'
|
||||
PACKAGE_TARNAME='unbound'
|
||||
PACKAGE_VERSION='1.9.6'
|
||||
PACKAGE_STRING='unbound 1.9.6'
|
||||
PACKAGE_VERSION='1.10.0'
|
||||
PACKAGE_STRING='unbound 1.10.0'
|
||||
PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues'
|
||||
PACKAGE_URL=''
|
||||
|
||||
@@ -673,8 +673,10 @@ UNBOUND_EVENT_UNINSTALL
|
||||
UNBOUND_EVENT_INSTALL
|
||||
SUBNET_HEADER
|
||||
SUBNET_OBJ
|
||||
PC_LIBBSD_DEPENDENCY
|
||||
SSLLIB
|
||||
HAVE_SSL
|
||||
PC_CRYPTO_DEPENDENCY
|
||||
CONFIG_DATE
|
||||
NETBSD_LINTFLAGS
|
||||
PYUNBOUND_UNINSTALL
|
||||
@@ -859,6 +861,7 @@ enable_swig_version_check
|
||||
with_nss
|
||||
with_nettle
|
||||
with_ssl
|
||||
with_libbsd
|
||||
enable_sha1
|
||||
enable_sha2
|
||||
enable_subnet
|
||||
@@ -1449,7 +1452,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.9.6 to adapt to many kinds of systems.
|
||||
\`configure' configures unbound 1.10.0 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@@ -1514,7 +1517,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of unbound 1.9.6:";;
|
||||
short | recursive ) echo "Configuration of unbound 1.10.0:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@@ -1620,6 +1623,7 @@ Optional Packages:
|
||||
--with-ssl=pathname enable SSL (will check /usr/local/ssl /usr/lib/ssl
|
||||
/usr/ssl /usr/pkg /usr/local /opt/local /usr/sfw
|
||||
/usr)
|
||||
--with-libbsd Use portable libbsd functions
|
||||
--with-libevent=pathname
|
||||
use libevent (will check /usr/local /opt/local
|
||||
/usr/lib /usr/pkg /usr/sfw /usr or you can specify
|
||||
@@ -1736,7 +1740,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
unbound configure 1.9.6
|
||||
unbound configure 1.10.0
|
||||
generated by GNU Autoconf 2.69
|
||||
|
||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
@@ -2445,7 +2449,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.9.6, which was
|
||||
It was created by unbound $as_me 1.10.0, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
@@ -2795,13 +2799,13 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
||||
|
||||
UNBOUND_VERSION_MAJOR=1
|
||||
|
||||
UNBOUND_VERSION_MINOR=9
|
||||
UNBOUND_VERSION_MINOR=10
|
||||
|
||||
UNBOUND_VERSION_MICRO=6
|
||||
UNBOUND_VERSION_MICRO=0
|
||||
|
||||
|
||||
LIBUNBOUND_CURRENT=9
|
||||
LIBUNBOUND_REVISION=6
|
||||
LIBUNBOUND_REVISION=7
|
||||
LIBUNBOUND_AGE=1
|
||||
# 1.0.0 had 0:12:0
|
||||
# 1.0.1 had 0:13:0
|
||||
@@ -2875,6 +2879,7 @@ LIBUNBOUND_AGE=1
|
||||
# 1.9.4 had 9:4:1
|
||||
# 1.9.5 had 9:5:1
|
||||
# 1.9.6 had 9:6:1
|
||||
# 1.10.0 had 9:7:1
|
||||
|
||||
# Current -- the number of the binary API that we're implementing
|
||||
# Revision -- which iteration of the implementation of the binary
|
||||
@@ -17758,6 +17763,8 @@ $as_echo "#define HAVE_NSS 1" >>confdefs.h
|
||||
fi
|
||||
LIBS="$LIBS -lnss3 -lnspr4"
|
||||
SSLLIB=""
|
||||
PC_CRYPTO_DEPENDENCY="nss nspr"
|
||||
|
||||
|
||||
|
||||
fi
|
||||
@@ -17801,6 +17808,8 @@ done
|
||||
fi
|
||||
LIBS="$LIBS -lhogweed -lnettle -lgmp"
|
||||
SSLLIB=""
|
||||
PC_CRYPTO_DEPENDENCY="hogweed nettle"
|
||||
|
||||
|
||||
|
||||
fi
|
||||
@@ -18151,6 +18160,9 @@ rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
SSLLIB="-lssl"
|
||||
|
||||
PC_CRYPTO_DEPENDENCY="libcrypto libssl"
|
||||
|
||||
|
||||
# check if -lcrypt32 is needed because CAPIENG needs that. (on windows)
|
||||
BAKLIBS="$LIBS"
|
||||
LIBS="-lssl $LIBS"
|
||||
@@ -18441,6 +18453,96 @@ fi
|
||||
fi
|
||||
|
||||
|
||||
# libbsd
|
||||
|
||||
# Check whether --with-libbsd was given.
|
||||
if test "${with_libbsd+set}" = set; then :
|
||||
withval=$with_libbsd;
|
||||
for ac_header in bsd/string.h bsd/stdlib.h
|
||||
do :
|
||||
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
|
||||
ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
|
||||
"
|
||||
if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
if test "x$ac_cv_header_bsd_string_h" = xyes -a "x$ac_cv_header_bsd_stdlib_h" = xyes; then
|
||||
for func in strlcpy strlcat arc4random arc4random_uniform reallocarray; do
|
||||
as_ac_Search=`$as_echo "ac_cv_search_$func" | $as_tr_sh`
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing $func" >&5
|
||||
$as_echo_n "checking for library containing $func... " >&6; }
|
||||
if eval \${$as_ac_Search+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
ac_func_search_save_LIBS=$LIBS
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char $func ();
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return $func ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
for ac_lib in '' bsd; do
|
||||
if test -z "$ac_lib"; then
|
||||
ac_res="none required"
|
||||
else
|
||||
ac_res=-l$ac_lib
|
||||
LIBS="-l$ac_lib $ac_func_search_save_LIBS"
|
||||
fi
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
eval "$as_ac_Search=\$ac_res"
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext
|
||||
if eval \${$as_ac_Search+:} false; then :
|
||||
break
|
||||
fi
|
||||
done
|
||||
if eval \${$as_ac_Search+:} false; then :
|
||||
|
||||
else
|
||||
eval "$as_ac_Search=no"
|
||||
fi
|
||||
rm conftest.$ac_ext
|
||||
LIBS=$ac_func_search_save_LIBS
|
||||
fi
|
||||
eval ac_res=\$$as_ac_Search
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
|
||||
$as_echo "$ac_res" >&6; }
|
||||
eval ac_res=\$$as_ac_Search
|
||||
if test "$ac_res" != no; then :
|
||||
test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
|
||||
|
||||
|
||||
$as_echo "#define HAVE_LIBBSD 1" >>confdefs.h
|
||||
|
||||
PC_LIBBSD_DEPENDENCY=libbsd
|
||||
|
||||
|
||||
fi
|
||||
|
||||
done
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
|
||||
# Check whether --enable-sha1 was given.
|
||||
if test "${enable_sha1+set}" = set; then :
|
||||
@@ -18744,9 +18846,7 @@ fi
|
||||
|
||||
use_dsa="no"
|
||||
case "$enable_dsa" in
|
||||
no)
|
||||
;;
|
||||
*)
|
||||
yes)
|
||||
# detect if DSA is supported, and turn it off if not.
|
||||
if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
|
||||
ac_fn_c_check_func "$LINENO" "DSA_SIG_new" "ac_cv_func_DSA_SIG_new"
|
||||
@@ -18799,6 +18899,10 @@ _ACEOF
|
||||
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
# disable dsa by default, RFC 8624 section 3.1, validators MUST NOT
|
||||
# support DSA for DNSSEC Validation.
|
||||
;;
|
||||
esac
|
||||
|
||||
# Check whether --enable-ed25519 was given.
|
||||
@@ -19923,6 +20027,75 @@ _ACEOF
|
||||
|
||||
fi
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for htobe64" >&5
|
||||
$as_echo_n "checking for htobe64... " >&6; }
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_ENDIAN_H
|
||||
# include <endian.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_ENDIAN_H
|
||||
# include <sys/endian.h>
|
||||
#endif
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
unsigned long long x = htobe64(0); printf("%u", (unsigned)x);
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
|
||||
$as_echo "#define HAVE_HTOBE64 1" >>confdefs.h
|
||||
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for be64toh" >&5
|
||||
$as_echo_n "checking for be64toh... " >&6; }
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_ENDIAN_H
|
||||
# include <endian.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_ENDIAN_H
|
||||
# include <sys/endian.h>
|
||||
#endif
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
unsigned long long x = be64toh(0); printf("%u", (unsigned)x);
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
|
||||
$as_echo "#define HAVE_BE64TOH 1" >>confdefs.h
|
||||
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing setusercontext" >&5
|
||||
$as_echo_n "checking for library containing setusercontext... " >&6; }
|
||||
if ${ac_cv_search_setusercontext+:} false; then :
|
||||
@@ -21425,12 +21598,12 @@ _ACEOF
|
||||
|
||||
|
||||
|
||||
version=1.9.6
|
||||
version=1.10.0
|
||||
|
||||
date=`date +'%b %e, %Y'`
|
||||
|
||||
|
||||
ac_config_files="$ac_config_files Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound.conf.5 doc/unbound-control.8 doc/unbound-host.1 smallapp/unbound-control-setup.sh dnstap/dnstap_config.h dnscrypt/dnscrypt_config.h contrib/libunbound.pc contrib/unbound.socket contrib/unbound.service"
|
||||
ac_config_files="$ac_config_files Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound.conf.5 doc/unbound-control.8 doc/unbound-host.1 smallapp/unbound-control-setup.sh dnstap/dnstap_config.h dnscrypt/dnscrypt_config.h contrib/libunbound.pc contrib/unbound.socket contrib/unbound.service contrib/unbound_portable.service"
|
||||
|
||||
ac_config_headers="$ac_config_headers config.h"
|
||||
|
||||
@@ -21944,7 +22117,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.9.6, which was
|
||||
This file was extended by unbound $as_me 1.10.0, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@@ -22010,7 +22183,7 @@ _ACEOF
|
||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
||||
ac_cs_version="\\
|
||||
unbound config.status 1.9.6
|
||||
unbound config.status 1.10.0
|
||||
configured by $0, generated by GNU Autoconf 2.69,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
@@ -22436,6 +22609,7 @@ do
|
||||
"contrib/libunbound.pc") CONFIG_FILES="$CONFIG_FILES contrib/libunbound.pc" ;;
|
||||
"contrib/unbound.socket") CONFIG_FILES="$CONFIG_FILES contrib/unbound.socket" ;;
|
||||
"contrib/unbound.service") CONFIG_FILES="$CONFIG_FILES contrib/unbound.service" ;;
|
||||
"contrib/unbound_portable.service") CONFIG_FILES="$CONFIG_FILES contrib/unbound_portable.service" ;;
|
||||
"config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
|
||||
|
||||
*) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
|
||||
|
||||
+64
-7
@@ -10,15 +10,15 @@ sinclude(dnscrypt/dnscrypt.m4)
|
||||
|
||||
# must be numbers. ac_defun because of later processing
|
||||
m4_define([VERSION_MAJOR],[1])
|
||||
m4_define([VERSION_MINOR],[9])
|
||||
m4_define([VERSION_MICRO],[6])
|
||||
m4_define([VERSION_MINOR],[10])
|
||||
m4_define([VERSION_MICRO],[0])
|
||||
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=6
|
||||
LIBUNBOUND_REVISION=7
|
||||
LIBUNBOUND_AGE=1
|
||||
# 1.0.0 had 0:12:0
|
||||
# 1.0.1 had 0:13:0
|
||||
@@ -92,6 +92,7 @@ LIBUNBOUND_AGE=1
|
||||
# 1.9.4 had 9:4:1
|
||||
# 1.9.5 had 9:5:1
|
||||
# 1.9.6 had 9:6:1
|
||||
# 1.10.0 had 9:7:1
|
||||
|
||||
# Current -- the number of the binary API that we're implementing
|
||||
# Revision -- which iteration of the implementation of the binary
|
||||
@@ -760,6 +761,8 @@ AC_ARG_WITH([nss], AC_HELP_STRING([--with-nss=path],
|
||||
fi
|
||||
LIBS="$LIBS -lnss3 -lnspr4"
|
||||
SSLLIB=""
|
||||
PC_CRYPTO_DEPENDENCY="nss nspr"
|
||||
AC_SUBST(PC_CRYPTO_DEPENDENCY)
|
||||
]
|
||||
)
|
||||
|
||||
@@ -780,6 +783,8 @@ AC_ARG_WITH([nettle], AC_HELP_STRING([--with-nettle=path],
|
||||
fi
|
||||
LIBS="$LIBS -lhogweed -lnettle -lgmp"
|
||||
SSLLIB=""
|
||||
PC_CRYPTO_DEPENDENCY="hogweed nettle"
|
||||
AC_SUBST(PC_CRYPTO_DEPENDENCY)
|
||||
]
|
||||
)
|
||||
|
||||
@@ -789,6 +794,9 @@ ACX_WITH_SSL
|
||||
ACX_LIB_SSL
|
||||
SSLLIB="-lssl"
|
||||
|
||||
PC_CRYPTO_DEPENDENCY="libcrypto libssl"
|
||||
AC_SUBST(PC_CRYPTO_DEPENDENCY)
|
||||
|
||||
# check if -lcrypt32 is needed because CAPIENG needs that. (on windows)
|
||||
BAKLIBS="$LIBS"
|
||||
LIBS="-lssl $LIBS"
|
||||
@@ -880,6 +888,19 @@ fi
|
||||
fi
|
||||
AC_SUBST(SSLLIB)
|
||||
|
||||
# libbsd
|
||||
AC_ARG_WITH([libbsd], AC_HELP_STRING([--with-libbsd], [Use portable libbsd functions]), [
|
||||
AC_CHECK_HEADERS([bsd/string.h bsd/stdlib.h],,, [AC_INCLUDES_DEFAULT])
|
||||
if test "x$ac_cv_header_bsd_string_h" = xyes -a "x$ac_cv_header_bsd_stdlib_h" = xyes; then
|
||||
for func in strlcpy strlcat arc4random arc4random_uniform reallocarray; do
|
||||
AC_SEARCH_LIBS([$func], [bsd], [
|
||||
AC_DEFINE(HAVE_LIBBSD, 1, [Use portable libbsd functions])
|
||||
PC_LIBBSD_DEPENDENCY=libbsd
|
||||
AC_SUBST(PC_LIBBSD_DEPENDENCY)
|
||||
])
|
||||
done
|
||||
fi
|
||||
])
|
||||
|
||||
AC_ARG_ENABLE(sha1, AC_HELP_STRING([--disable-sha1], [Disable SHA1 RRSIG support, does not disable nsec3 support]))
|
||||
case "$enable_sha1" in
|
||||
@@ -1064,9 +1085,7 @@ esac
|
||||
AC_ARG_ENABLE(dsa, AC_HELP_STRING([--disable-dsa], [Disable DSA support]))
|
||||
use_dsa="no"
|
||||
case "$enable_dsa" in
|
||||
no)
|
||||
;;
|
||||
*)
|
||||
yes)
|
||||
# detect if DSA is supported, and turn it off if not.
|
||||
if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
|
||||
AC_CHECK_FUNC(DSA_SIG_new, [
|
||||
@@ -1097,6 +1116,10 @@ AC_INCLUDES_DEFAULT
|
||||
AC_DEFINE_UNQUOTED([USE_DSA], [1], [Define this to enable DSA support.])
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
# disable dsa by default, RFC 8624 section 3.1, validators MUST NOT
|
||||
# support DSA for DNSSEC Validation.
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_ARG_ENABLE(ed25519, AC_HELP_STRING([--disable-ed25519], [Disable ED25519 support]))
|
||||
@@ -1467,6 +1490,35 @@ AC_INCLUDES_DEFAULT
|
||||
#include <ws2tcpip.h>
|
||||
#endif
|
||||
])
|
||||
|
||||
AC_MSG_CHECKING([for htobe64])
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_ENDIAN_H
|
||||
# include <endian.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_ENDIAN_H
|
||||
# include <sys/endian.h>
|
||||
#endif
|
||||
], [unsigned long long x = htobe64(0); printf("%u", (unsigned)x);])],
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_HTOBE64, 1, [If we have htobe64]),
|
||||
AC_MSG_RESULT(no))
|
||||
|
||||
AC_MSG_CHECKING([for be64toh])
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_ENDIAN_H
|
||||
# include <endian.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_ENDIAN_H
|
||||
# include <sys/endian.h>
|
||||
#endif
|
||||
], [unsigned long long x = be64toh(0); printf("%u", (unsigned)x);])],
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_BE64TOH, 1, [If we have be64toh]),
|
||||
AC_MSG_RESULT(no))
|
||||
|
||||
AC_SEARCH_LIBS([setusercontext], [util])
|
||||
AC_CHECK_FUNCS([tzset sigprocmask fcntl getpwnam endpwent getrlimit setrlimit setsid chroot kill chown sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent fsync shmget accept4])
|
||||
AC_CHECK_FUNCS([setresuid],,[AC_CHECK_FUNCS([setreuid])])
|
||||
@@ -1945,6 +1997,11 @@ char *strptime(const char *s, const char *format, struct tm *tm);
|
||||
void *reallocarray(void *ptr, size_t nmemb, size_t size);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBBSD
|
||||
#include <bsd/string.h>
|
||||
#include <bsd/stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBRESSL
|
||||
# if !HAVE_DECL_STRLCPY
|
||||
size_t strlcpy(char *dst, const char *src, size_t siz);
|
||||
@@ -2046,6 +2103,6 @@ dnl if this is a distro tarball, that was already done by makedist.sh
|
||||
AC_SUBST(version, [VERSION_MAJOR.VERSION_MINOR.VERSION_MICRO])
|
||||
AC_SUBST(date, [`date +'%b %e, %Y'`])
|
||||
|
||||
AC_CONFIG_FILES([Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound.conf.5 doc/unbound-control.8 doc/unbound-host.1 smallapp/unbound-control-setup.sh dnstap/dnstap_config.h dnscrypt/dnscrypt_config.h contrib/libunbound.pc contrib/unbound.socket contrib/unbound.service])
|
||||
AC_CONFIG_FILES([Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound.conf.5 doc/unbound-control.8 doc/unbound-host.1 smallapp/unbound-control-setup.sh dnstap/dnstap_config.h dnscrypt/dnscrypt_config.h contrib/libunbound.pc contrib/unbound.socket contrib/unbound.service contrib/unbound_portable.service])
|
||||
AC_CONFIG_HEADER([config.h])
|
||||
AC_OUTPUT
|
||||
|
||||
+5
-1
@@ -27,10 +27,12 @@ distribution but may be helpful.
|
||||
works like the BIND feature (removes AAAA records unless AAAA-only domain).
|
||||
Useful for certain 'broken IPv6 default route' scenarios.
|
||||
Patch from Stephane Lapie for ASAHI Net.
|
||||
* unbound_smf22.tar.gz: Solaris SMF installation/removal scripts.
|
||||
* unbound_smf23.tar.gz: Solaris SMF installation/removal scripts.
|
||||
Contributed by Yuri Voinov.
|
||||
* unbound.socket and unbound.service: systemd files for unbound, install them
|
||||
in /usr/lib/systemd/system. Contributed by Sami Kerola and Pavel Odintsov.
|
||||
* unbound_portable.service.in: systemd file for use unbound as portable service,
|
||||
see comments in the file. Contributed by Frzk.
|
||||
* redirect-bogus.patch: Return configured address for bogus A and AAAA answers,
|
||||
instead of SERVFAIL. Contributed by SIDN.
|
||||
* fastrpz.patch: fastrpz support from Farsight Security.
|
||||
@@ -49,3 +51,5 @@ distribution but may be helpful.
|
||||
compile. From Saksham Manchanda (Secure64). Please note that we think
|
||||
this will drop DNSKEY and DS lookups for tlds and hence break DNSSEC
|
||||
lookups for downstream clients.
|
||||
* drop2rpz: perl script that converts the Spamhaus DROP-List in RPZ-Format,
|
||||
contributed by Andreas Schulze.
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
# usage: curl --silent https://www.spamhaus.org/drop/drop.txt | $0 > /path/to/spamhaus-drop.rpz.local
|
||||
#
|
||||
# unbound.conf:
|
||||
# rpz:
|
||||
# name: "spamhaus-drop.rpz.local."
|
||||
# zonefile: "/path/tp/spamhaus-drop.rpz.local"
|
||||
# rpz-log: yes
|
||||
# rpz-log-name: "spamhaus-drop"
|
||||
#
|
||||
|
||||
use strict;
|
||||
use vars qw{$o1 $o2 $o3 $o4 $m};
|
||||
|
||||
# trailing dots required
|
||||
my $origin = 'drop.spamhaus.org.rpz.local.';
|
||||
my $mname = 'localhost.';
|
||||
my $rname = 'root.localhost.';
|
||||
my $ns = $mname;
|
||||
|
||||
my $rpz_action = '.'; # return NXDOMAIN
|
||||
#my $rpz_action = '*.'; # return NODATA
|
||||
#my $rpz_action = 'rpz-drop.'; # drop the query
|
||||
|
||||
print "$origin SOA $mname $rname 1 43200 7200 2419200 3600\n";
|
||||
print "$origin NS $ns\n";
|
||||
while(<>) {
|
||||
if(($o1, $o2, $o3, $o4, $m) = m{(\d+)\.(\d+)\.(\d+)\.(\d+)/(\d+)}) {
|
||||
print "$m.$o4.$o3.$o2.$o1.rpz-ip.$origin CNAME $rpz_action\n";
|
||||
} else {
|
||||
print "$_";
|
||||
}
|
||||
}
|
||||
|
||||
# add a testpoint: ask for "dns.google"
|
||||
# print "32.8.8.8.8.rpz-ip.$origin CNAME $rpz_action\n";
|
||||
|
||||
exit;
|
||||
+54
-54
@@ -2,7 +2,7 @@ Description: based on the included patch contrib/fastrpz.patch
|
||||
Author: fastrpz@farsightsecurity.com
|
||||
---
|
||||
diff --git a/Makefile.in b/Makefile.in
|
||||
index 721c01b6..56bfb560 100644
|
||||
index a20058cc..495779cc 100644
|
||||
--- a/Makefile.in
|
||||
+++ b/Makefile.in
|
||||
@@ -23,6 +23,8 @@ CHECKLOCK_SRC=testcode/checklocks.c
|
||||
@@ -14,7 +14,7 @@ index 721c01b6..56bfb560 100644
|
||||
DNSCRYPT_SRC=@DNSCRYPT_SRC@
|
||||
DNSCRYPT_OBJ=@DNSCRYPT_OBJ@
|
||||
WITH_PYTHONMODULE=@WITH_PYTHONMODULE@
|
||||
@@ -126,7 +128,7 @@ validator/val_sigcrypt.c validator/val_utils.c dns64/dns64.c \
|
||||
@@ -127,7 +129,7 @@ validator/val_sigcrypt.c validator/val_utils.c dns64/dns64.c \
|
||||
edns-subnet/edns-subnet.c edns-subnet/subnetmod.c \
|
||||
edns-subnet/addrtree.c edns-subnet/subnet-whitelist.c \
|
||||
cachedb/cachedb.c cachedb/redis.c respip/respip.c $(CHECKLOCK_SRC) \
|
||||
@@ -23,7 +23,7 @@ index 721c01b6..56bfb560 100644
|
||||
COMMON_OBJ_WITHOUT_NETCALL=dns.lo infra.lo rrset.lo dname.lo msgencode.lo \
|
||||
as112.lo msgparse.lo msgreply.lo packed_rrset.lo iterator.lo iter_delegpt.lo \
|
||||
iter_donotq.lo iter_fwd.lo iter_hints.lo iter_priv.lo iter_resptype.lo \
|
||||
@@ -139,7 +141,7 @@ autotrust.lo val_anchor.lo \
|
||||
@@ -140,7 +142,7 @@ autotrust.lo val_anchor.lo rpz.lo \
|
||||
validator.lo val_kcache.lo val_kentry.lo val_neg.lo val_nsec3.lo val_nsec.lo \
|
||||
val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo cachedb.lo redis.lo authzone.lo \
|
||||
$(SUBNET_OBJ) $(PYTHONMOD_OBJ) $(CHECKLOCK_OBJ) $(DNSTAP_OBJ) $(DNSCRYPT_OBJ) \
|
||||
@@ -32,7 +32,7 @@ index 721c01b6..56bfb560 100644
|
||||
COMMON_OBJ_WITHOUT_UB_EVENT=$(COMMON_OBJ_WITHOUT_NETCALL) netevent.lo listen_dnsport.lo \
|
||||
outside_network.lo
|
||||
COMMON_OBJ=$(COMMON_OBJ_WITHOUT_UB_EVENT) ub_event.lo
|
||||
@@ -409,6 +411,11 @@ dnscrypt.lo dnscrypt.o: $(srcdir)/dnscrypt/dnscrypt.c config.h \
|
||||
@@ -410,6 +412,11 @@ dnscrypt.lo dnscrypt.o: $(srcdir)/dnscrypt/dnscrypt.c config.h \
|
||||
$(srcdir)/util/config_file.h $(srcdir)/util/log.h \
|
||||
$(srcdir)/util/netevent.h
|
||||
|
||||
@@ -45,10 +45,10 @@ index 721c01b6..56bfb560 100644
|
||||
pythonmod.lo pythonmod.o: $(srcdir)/pythonmod/pythonmod.c config.h \
|
||||
pythonmod/interface.h \
|
||||
diff --git a/config.h.in b/config.h.in
|
||||
index 8c2aa3b9..efaf6450 100644
|
||||
index 78d47fed..e33073e4 100644
|
||||
--- a/config.h.in
|
||||
+++ b/config.h.in
|
||||
@@ -1325,4 +1325,11 @@ void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
|
||||
@@ -1345,4 +1345,11 @@ void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
|
||||
/** the version of unbound-control that this software implements */
|
||||
#define UNBOUND_CONTROL_VERSION 1
|
||||
|
||||
@@ -62,7 +62,7 @@ index 8c2aa3b9..efaf6450 100644
|
||||
+/** turn on fastrpz response policy zones */
|
||||
+#undef ENABLE_FASTRPZ
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 5276d441..9d74592e 100644
|
||||
index 2b91dd3c..e6063d17 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -6,6 +6,7 @@ sinclude(ax_pthread.m4)
|
||||
@@ -73,7 +73,7 @@ index 5276d441..9d74592e 100644
|
||||
sinclude(dnscrypt/dnscrypt.m4)
|
||||
|
||||
# must be numbers. ac_defun because of later processing
|
||||
@@ -1726,6 +1727,9 @@ case "$enable_ipset" in
|
||||
@@ -1778,6 +1779,9 @@ case "$enable_ipset" in
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -84,7 +84,7 @@ index 5276d441..9d74592e 100644
|
||||
# on openBSD, the implicit rule make $< work.
|
||||
# on Solaris, it does not work ($? is changed sources, $^ lists dependencies).
|
||||
diff --git a/daemon/daemon.c b/daemon/daemon.c
|
||||
index 0b1200a2..5857c18b 100644
|
||||
index 8b0fc348..7ffb9221 100644
|
||||
--- a/daemon/daemon.c
|
||||
+++ b/daemon/daemon.c
|
||||
@@ -91,6 +91,9 @@
|
||||
@@ -112,7 +112,7 @@ index 0b1200a2..5857c18b 100644
|
||||
#endif
|
||||
}
|
||||
for(i=0; i<daemon->num; i++) {
|
||||
@@ -724,6 +735,9 @@ daemon_cleanup(struct daemon* daemon)
|
||||
@@ -731,6 +742,9 @@ daemon_cleanup(struct daemon* daemon)
|
||||
#ifdef USE_DNSCRYPT
|
||||
dnsc_delete(daemon->dnscenv);
|
||||
daemon->dnscenv = NULL;
|
||||
@@ -123,10 +123,10 @@ index 0b1200a2..5857c18b 100644
|
||||
daemon->cfg = NULL;
|
||||
}
|
||||
diff --git a/daemon/daemon.h b/daemon/daemon.h
|
||||
index 5749dbef..64ce230f 100644
|
||||
index 3effbafb..4d4c34da 100644
|
||||
--- a/daemon/daemon.h
|
||||
+++ b/daemon/daemon.h
|
||||
@@ -136,6 +136,11 @@ struct daemon {
|
||||
@@ -138,6 +138,11 @@ struct daemon {
|
||||
/** the dnscrypt environment */
|
||||
struct dnsc_env* dnscenv;
|
||||
#endif
|
||||
@@ -139,10 +139,10 @@ index 5749dbef..64ce230f 100644
|
||||
|
||||
/**
|
||||
diff --git a/daemon/worker.c b/daemon/worker.c
|
||||
index e2ce0e87..f031c656 100644
|
||||
index eb7fdf2f..1982228d 100644
|
||||
--- a/daemon/worker.c
|
||||
+++ b/daemon/worker.c
|
||||
@@ -75,6 +75,9 @@
|
||||
@@ -76,6 +76,9 @@
|
||||
#include "libunbound/context.h"
|
||||
#include "libunbound/libworker.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
@@ -152,7 +152,7 @@ index e2ce0e87..f031c656 100644
|
||||
#include "sldns/wire2str.h"
|
||||
#include "util/shm_side/shm_main.h"
|
||||
#include "dnscrypt/dnscrypt.h"
|
||||
@@ -533,8 +536,27 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
@@ -534,8 +537,27 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
/* not secure */
|
||||
secure = 0;
|
||||
break;
|
||||
@@ -180,10 +180,10 @@ index e2ce0e87..f031c656 100644
|
||||
/* return this delegation from the cache */
|
||||
edns_bak = *edns;
|
||||
edns->edns_version = EDNS_ADVERTISED_VERSION;
|
||||
@@ -699,6 +721,23 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
secure = 0;
|
||||
@@ -710,6 +732,23 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
*is_secure_answer = 0;
|
||||
}
|
||||
} else secure = 0;
|
||||
} else *is_secure_answer = 0;
|
||||
+#ifdef ENABLE_FASTRPZ
|
||||
+ if(repinfo->rpz) {
|
||||
+ /* Scan the cached answer for RPZ hits.
|
||||
@@ -204,7 +204,7 @@ index e2ce0e87..f031c656 100644
|
||||
|
||||
edns_bak = *edns;
|
||||
edns->edns_version = EDNS_ADVERTISED_VERSION;
|
||||
@@ -1410,6 +1449,15 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
@@ -1435,6 +1474,15 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
log_addr(VERB_ALGO, "refused nonrec (cache snoop) query from",
|
||||
&repinfo->addr, repinfo->addrlen);
|
||||
goto send_reply;
|
||||
@@ -220,14 +220,14 @@ index e2ce0e87..f031c656 100644
|
||||
}
|
||||
|
||||
/* If we've found a local alias, replace the qname with the alias
|
||||
@@ -1458,12 +1506,21 @@ lookup_cache:
|
||||
@@ -1485,12 +1533,21 @@ lookup_cache:
|
||||
h = query_info_hash(lookup_qinfo, sldns_buffer_read_u16_at(c->buffer, 2));
|
||||
if((e=slabhash_lookup(worker->env.msg_cache, h, lookup_qinfo, 0))) {
|
||||
/* answer from cache - we have acquired a readlock on it */
|
||||
- if(answer_from_cache(worker, &qinfo,
|
||||
+ ret = answer_from_cache(worker, &qinfo,
|
||||
cinfo, &need_drop, &alias_rrset, &partial_rep,
|
||||
(struct reply_info*)e->data,
|
||||
cinfo, &need_drop, &is_expired_answer, &is_secure_answer,
|
||||
&alias_rrset, &partial_rep, (struct reply_info*)e->data,
|
||||
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
|
||||
sldns_buffer_read_u16_at(c->buffer, 2), repinfo,
|
||||
- &edns)) {
|
||||
@@ -244,7 +244,7 @@ index e2ce0e87..f031c656 100644
|
||||
/* prefetch it if the prefetch TTL expired.
|
||||
* Note that if there is more than one pass
|
||||
* its qname must be that used for cache
|
||||
@@ -1518,11 +1575,19 @@ lookup_cache:
|
||||
@@ -1547,11 +1604,19 @@ lookup_cache:
|
||||
lock_rw_unlock(&e->lock);
|
||||
}
|
||||
if(!LDNS_RD_WIRE(sldns_buffer_begin(c->buffer))) {
|
||||
@@ -267,10 +267,10 @@ index e2ce0e87..f031c656 100644
|
||||
}
|
||||
verbose(VERB_ALGO, "answer norec from cache -- "
|
||||
diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in
|
||||
index 4bdfcd56..69e70627 100644
|
||||
index 38c2d298..3b07f392 100644
|
||||
--- a/doc/unbound.conf.5.in
|
||||
+++ b/doc/unbound.conf.5.in
|
||||
@@ -1801,6 +1801,81 @@ List domain for which the AAAA records are ignored and the A record is
|
||||
@@ -1828,6 +1828,81 @@ List domain for which the AAAA records are ignored and the A record is
|
||||
used by dns64 processing instead. Can be entered multiple times, list a
|
||||
new domain for which it applies, one per line. Applies also to names
|
||||
underneath the name given.
|
||||
@@ -3106,10 +3106,10 @@ index a2f1b570..e1e4a738 100644
|
||||
* Count number of time-outs. Used to prevent resolving failures when
|
||||
* the QNAME minimisation QTYPE is blocked. */
|
||||
diff --git a/services/cache/dns.c b/services/cache/dns.c
|
||||
index aa4efec7..5dd3412e 100644
|
||||
index 2a5bca4a..6de8863a 100644
|
||||
--- a/services/cache/dns.c
|
||||
+++ b/services/cache/dns.c
|
||||
@@ -945,6 +945,14 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf,
|
||||
@@ -967,6 +967,14 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf,
|
||||
struct regional* region, uint32_t flags)
|
||||
{
|
||||
struct reply_info* rep = NULL;
|
||||
@@ -3125,10 +3125,10 @@ index aa4efec7..5dd3412e 100644
|
||||
rep = reply_info_copy(msgrep, env->alloc, NULL);
|
||||
if(!rep)
|
||||
diff --git a/services/mesh.c b/services/mesh.c
|
||||
index d4f814d5..624a9d95 100644
|
||||
index 9114ef4c..3dc518e5 100644
|
||||
--- a/services/mesh.c
|
||||
+++ b/services/mesh.c
|
||||
@@ -60,6 +60,9 @@
|
||||
@@ -61,6 +61,9 @@
|
||||
#include "sldns/wire2str.h"
|
||||
#include "services/localzone.h"
|
||||
#include "util/data/dname.h"
|
||||
@@ -3138,7 +3138,7 @@ index d4f814d5..624a9d95 100644
|
||||
#include "respip/respip.h"
|
||||
#include "services/listen_dnsport.h"
|
||||
|
||||
@@ -1076,6 +1079,13 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
|
||||
@@ -1195,6 +1198,13 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
|
||||
else secure = 0;
|
||||
if(!rep && rcode == LDNS_RCODE_NOERROR)
|
||||
rcode = LDNS_RCODE_SERVFAIL;
|
||||
@@ -3152,7 +3152,7 @@ index d4f814d5..624a9d95 100644
|
||||
/* send the reply */
|
||||
/* We don't reuse the encoded answer if either the previous or current
|
||||
* response has a local alias. We could compare the alias records
|
||||
@@ -1255,6 +1265,7 @@ struct mesh_state* mesh_area_find(struct mesh_area* mesh,
|
||||
@@ -1415,6 +1425,7 @@ struct mesh_state* mesh_area_find(struct mesh_area* mesh,
|
||||
key.s.is_valrec = valrec;
|
||||
key.s.qinfo = *qinfo;
|
||||
key.s.query_flags = qflags;
|
||||
@@ -3160,7 +3160,7 @@ index d4f814d5..624a9d95 100644
|
||||
/* We are searching for a similar mesh state when we DO want to
|
||||
* aggregate the state. Thus unique is set to NULL. (default when we
|
||||
* desire aggregation).*/
|
||||
@@ -1301,6 +1312,10 @@ int mesh_state_add_reply(struct mesh_state* s, struct edns_data* edns,
|
||||
@@ -1461,6 +1472,10 @@ int mesh_state_add_reply(struct mesh_state* s, struct edns_data* edns,
|
||||
if(!r)
|
||||
return 0;
|
||||
r->query_reply = *rep;
|
||||
@@ -3172,10 +3172,10 @@ index d4f814d5..624a9d95 100644
|
||||
if(edns->opt_list) {
|
||||
r->edns.opt_list = edns_opt_copy_region(edns->opt_list,
|
||||
diff --git a/util/config_file.c b/util/config_file.c
|
||||
index 119b2223..ce43a234 100644
|
||||
index 52ca5a18..0660248f 100644
|
||||
--- a/util/config_file.c
|
||||
+++ b/util/config_file.c
|
||||
@@ -1434,6 +1434,8 @@ config_delete(struct config_file* cfg)
|
||||
@@ -1460,6 +1460,8 @@ config_delete(struct config_file* cfg)
|
||||
free(cfg->dnstap_socket_path);
|
||||
free(cfg->dnstap_identity);
|
||||
free(cfg->dnstap_version);
|
||||
@@ -3185,10 +3185,10 @@ index 119b2223..ce43a234 100644
|
||||
config_deldblstrlist(cfg->ratelimit_below_domain);
|
||||
config_delstrlist(cfg->python_script);
|
||||
diff --git a/util/config_file.h b/util/config_file.h
|
||||
index b3ef930a..56173b80 100644
|
||||
index 8739ca2a..a2dcf215 100644
|
||||
--- a/util/config_file.h
|
||||
+++ b/util/config_file.h
|
||||
@@ -494,6 +494,11 @@ struct config_file {
|
||||
@@ -499,6 +499,11 @@ struct config_file {
|
||||
/** true to disable DNSSEC lameness check in iterator */
|
||||
int disable_dnssec_lame_check;
|
||||
|
||||
@@ -3201,10 +3201,10 @@ index b3ef930a..56173b80 100644
|
||||
int ip_ratelimit;
|
||||
/** number of slabs for ip_ratelimit cache */
|
||||
diff --git a/util/configlexer.lex b/util/configlexer.lex
|
||||
index a86ddf55..b56bcfb4 100644
|
||||
index deedffa5..301458a3 100644
|
||||
--- a/util/configlexer.lex
|
||||
+++ b/util/configlexer.lex
|
||||
@@ -438,6 +438,10 @@ dnstap-log-forwarder-query-messages{COLON} {
|
||||
@@ -446,6 +446,10 @@ dnstap-log-forwarder-query-messages{COLON} {
|
||||
YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES) }
|
||||
dnstap-log-forwarder-response-messages{COLON} {
|
||||
YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES) }
|
||||
@@ -3216,7 +3216,7 @@ index a86ddf55..b56bcfb4 100644
|
||||
ip-ratelimit{COLON} { YDVAR(1, VAR_IP_RATELIMIT) }
|
||||
ratelimit{COLON} { YDVAR(1, VAR_RATELIMIT) }
|
||||
diff --git a/util/configparser.y b/util/configparser.y
|
||||
index 10227a2f..cdbcf7cd 100644
|
||||
index d471babe..cb6b1d63 100644
|
||||
--- a/util/configparser.y
|
||||
+++ b/util/configparser.y
|
||||
@@ -125,6 +125,7 @@ extern struct config_parser_state* cfg_parser;
|
||||
@@ -3227,7 +3227,7 @@ index 10227a2f..cdbcf7cd 100644
|
||||
%token VAR_RESPONSE_IP_TAG VAR_RESPONSE_IP VAR_RESPONSE_IP_DATA
|
||||
%token VAR_HARDEN_ALGO_DOWNGRADE VAR_IP_TRANSPARENT
|
||||
%token VAR_DISABLE_DNSSEC_LAME_CHECK
|
||||
@@ -171,7 +172,7 @@ extern struct config_parser_state* cfg_parser;
|
||||
@@ -173,7 +174,7 @@ extern struct config_parser_state* cfg_parser;
|
||||
|
||||
%%
|
||||
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
|
||||
@@ -3236,7 +3236,7 @@ index 10227a2f..cdbcf7cd 100644
|
||||
forwardstart contents_forward | pythonstart contents_py |
|
||||
rcstart contents_rc | dtstart contents_dt | viewstart contents_view |
|
||||
dnscstart contents_dnsc | cachedbstart contents_cachedb |
|
||||
@@ -2726,6 +2727,50 @@ dt_dnstap_log_forwarder_response_messages: VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MES
|
||||
@@ -2837,6 +2838,50 @@ dt_dnstap_log_forwarder_response_messages: VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MES
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
@@ -3288,10 +3288,10 @@ index 10227a2f..cdbcf7cd 100644
|
||||
{
|
||||
OUTYY(("\nP(python:)\n"));
|
||||
diff --git a/util/data/msgencode.c b/util/data/msgencode.c
|
||||
index a51a4b9b..475dfce9 100644
|
||||
index be69f628..f10773aa 100644
|
||||
--- a/util/data/msgencode.c
|
||||
+++ b/util/data/msgencode.c
|
||||
@@ -590,6 +590,35 @@ insert_section(struct reply_info* rep, size_t num_rrsets, uint16_t* num_rrs,
|
||||
@@ -592,6 +592,35 @@ insert_section(struct reply_info* rep, size_t num_rrsets, uint16_t* num_rrs,
|
||||
return RETVAL_OK;
|
||||
}
|
||||
|
||||
@@ -3327,7 +3327,7 @@ index a51a4b9b..475dfce9 100644
|
||||
/** store query section in wireformat buffer, return RETVAL */
|
||||
static int
|
||||
insert_query(struct query_info* qinfo, struct compress_tree_node** tree,
|
||||
@@ -777,6 +806,19 @@ reply_info_encode(struct query_info* qinfo, struct reply_info* rep,
|
||||
@@ -779,6 +808,19 @@ reply_info_encode(struct query_info* qinfo, struct reply_info* rep,
|
||||
}
|
||||
sldns_buffer_write_u16_at(buffer, 10, arcount);
|
||||
}
|
||||
@@ -3348,10 +3348,10 @@ index a51a4b9b..475dfce9 100644
|
||||
sldns_buffer_flip(buffer);
|
||||
return 1;
|
||||
diff --git a/util/data/packed_rrset.c b/util/data/packed_rrset.c
|
||||
index 7b9d5494..e44b2ce5 100644
|
||||
index 4b0294f9..3b3838f6 100644
|
||||
--- a/util/data/packed_rrset.c
|
||||
+++ b/util/data/packed_rrset.c
|
||||
@@ -255,6 +255,10 @@ sec_status_to_string(enum sec_status s)
|
||||
@@ -256,6 +256,10 @@ sec_status_to_string(enum sec_status s)
|
||||
case sec_status_insecure: return "sec_status_insecure";
|
||||
case sec_status_secure_sentinel_fail: return "sec_status_secure_sentinel_fail";
|
||||
case sec_status_secure: return "sec_status_secure";
|
||||
@@ -3363,7 +3363,7 @@ index 7b9d5494..e44b2ce5 100644
|
||||
return "unknown_sec_status_value";
|
||||
}
|
||||
diff --git a/util/data/packed_rrset.h b/util/data/packed_rrset.h
|
||||
index 3a5335dd..20113217 100644
|
||||
index 729877ba..ccd1a0c2 100644
|
||||
--- a/util/data/packed_rrset.h
|
||||
+++ b/util/data/packed_rrset.h
|
||||
@@ -193,7 +193,15 @@ enum sec_status {
|
||||
@@ -3384,7 +3384,7 @@ index 3a5335dd..20113217 100644
|
||||
|
||||
/**
|
||||
diff --git a/util/netevent.c b/util/netevent.c
|
||||
index 980bb8be..d537d288 100644
|
||||
index 9fe5da2d..037e70d1 100644
|
||||
--- a/util/netevent.c
|
||||
+++ b/util/netevent.c
|
||||
@@ -57,6 +57,9 @@
|
||||
@@ -3427,7 +3427,7 @@ index 980bb8be..d537d288 100644
|
||||
if(!rep.c || rep.c->fd != fd) /* commpoint closed to -1 or reused for
|
||||
another UDP port. Note rep.c cannot be reused with TCP fd. */
|
||||
break;
|
||||
@@ -3184,6 +3196,9 @@ comm_point_send_reply(struct comm_reply *repinfo)
|
||||
@@ -3192,6 +3204,9 @@ comm_point_send_reply(struct comm_reply *repinfo)
|
||||
repinfo->c->tcp_timeout_msec);
|
||||
}
|
||||
}
|
||||
@@ -3437,7 +3437,7 @@ index 980bb8be..d537d288 100644
|
||||
}
|
||||
|
||||
void
|
||||
@@ -3193,6 +3208,9 @@ comm_point_drop_reply(struct comm_reply* repinfo)
|
||||
@@ -3201,6 +3216,9 @@ comm_point_drop_reply(struct comm_reply* repinfo)
|
||||
return;
|
||||
log_assert(repinfo->c);
|
||||
log_assert(repinfo->c->type != comm_tcp_accept);
|
||||
@@ -3447,7 +3447,7 @@ index 980bb8be..d537d288 100644
|
||||
if(repinfo->c->type == comm_udp)
|
||||
return;
|
||||
if(repinfo->c->tcp_req_info)
|
||||
@@ -3214,6 +3232,9 @@ comm_point_start_listening(struct comm_point* c, int newfd, int msec)
|
||||
@@ -3222,6 +3240,9 @@ comm_point_start_listening(struct comm_point* c, int newfd, int msec)
|
||||
{
|
||||
verbose(VERB_ALGO, "comm point start listening %d (%d msec)",
|
||||
c->fd==-1?newfd:c->fd, msec);
|
||||
@@ -3473,10 +3473,10 @@ index d80c72b3..0233292f 100644
|
||||
uint8_t client_nonce[crypto_box_HALF_NONCEBYTES];
|
||||
uint8_t nmkey[crypto_box_BEFORENMBYTES];
|
||||
diff --git a/validator/validator.c b/validator/validator.c
|
||||
index 4c560a8e..71de3760 100644
|
||||
index c3ca0a27..15251988 100644
|
||||
--- a/validator/validator.c
|
||||
+++ b/validator/validator.c
|
||||
@@ -2755,6 +2755,12 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
@@ -2761,6 +2761,12 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
default:
|
||||
/* NSEC proof did not work, try next */
|
||||
break;
|
||||
@@ -3489,7 +3489,7 @@ index 4c560a8e..71de3760 100644
|
||||
}
|
||||
|
||||
sec = nsec3_prove_nods(qstate->env, ve,
|
||||
@@ -2788,6 +2794,12 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
@@ -2794,6 +2800,12 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
default:
|
||||
/* NSEC3 proof did not work */
|
||||
break;
|
||||
|
||||
@@ -7,8 +7,8 @@ Name: unbound
|
||||
Description: Library with validating, recursive, and caching DNS resolver
|
||||
URL: http://www.unbound.net
|
||||
Version: @PACKAGE_VERSION@
|
||||
Requires: libcrypto libssl @PC_LIBEVENT_DEPENDENCY@
|
||||
Requires.private: @PC_PY_DEPENDENCY@
|
||||
Libs: -L${libdir} -lunbound -lssl -lcrypto
|
||||
Requires: @PC_CRYPTO_DEPENDENCY@ @PC_LIBEVENT_DEPENDENCY@
|
||||
Requires.private: @PC_PY_DEPENDENCY@ @PC_LIBBSD_DEPENDENCY@
|
||||
Libs: -L${libdir} -lunbound
|
||||
Libs.private: @SSLLIB@ @LIBS@
|
||||
Cflags: -I${includedir}
|
||||
Cflags: -I${includedir}
|
||||
|
||||
@@ -1,3 +1,44 @@
|
||||
; For further details about the directives used in this unit file, including
|
||||
; the below, please refer to systemd's official documentation, available at
|
||||
; https://www.freedesktop.org/software/systemd/man/systemd.exec.html.
|
||||
;
|
||||
;
|
||||
; - `ProtectSystem=strict` implies we mount the entire file system hierarchy
|
||||
; read-only for the processes invoked by the unit except for the API file
|
||||
; system subtrees /dev, /proc and /sys (which are protected by
|
||||
; PrivateDevices=, ProtectKernelTunables=, ProtectControlGroups=).
|
||||
;
|
||||
; - `PrivateTmp=yes` secures access to temporary files of the process, and
|
||||
; makes sharing between processes via /tmp or /var/tmp impossible.
|
||||
;
|
||||
; - `ProtectHome=yes` makes the directories /home, /root, and /run/user
|
||||
; inaccessible and empty for processes invoked by the unit.
|
||||
;
|
||||
; - `ProtectControlGroups=yes` makes the Linux Control Groups hierarchies
|
||||
; (accessible through /sys/fs/cgroup) read-only to all processes invoked by
|
||||
; the unit. It also implies `MountAPIVFS=yes`.
|
||||
;
|
||||
; - `RuntimeDirectory=unbound` creates a /run/unbound directory, owned by the
|
||||
; unit User and Group with read-write permissions (0755) as soon as the
|
||||
; unit starts. This allows unbound to store its pidfile. The directory and
|
||||
; its content are automatically removed by systemd when the unit stops.
|
||||
;
|
||||
; - `NoNewPrivileges=yes` ensures that the service process and all its
|
||||
; children can never gain new privileges through execve().
|
||||
;
|
||||
; - `RestrictSUIDSGID=yes` ensures that any attempts to set the set-user-ID
|
||||
; (SUID) or set-group-ID (SGID) bits on files or directories will be denied.
|
||||
;
|
||||
; - `RestrictRealTime=yes` ensures that any attempts to enable realtime
|
||||
; scheduling in a process invoked by the unit will be denied.
|
||||
;
|
||||
; - `RestrictNamespaces=yes` ensures that access to any kind of namespacing
|
||||
; is prohibited.
|
||||
;
|
||||
; - `LockPersonality=yes` locks down the personality system call so that the
|
||||
; kernel execution domain may not be changed from the default.
|
||||
;
|
||||
;
|
||||
[Unit]
|
||||
Description=Validating, recursive, and caching DNS resolver
|
||||
Documentation=man:unbound(8)
|
||||
@@ -10,10 +51,10 @@ WantedBy=multi-user.target
|
||||
|
||||
[Service]
|
||||
ExecReload=+/bin/kill -HUP $MAINPID
|
||||
ExecStart=@UNBOUND_SBIN_DIR@/unbound -d
|
||||
ExecStart=@UNBOUND_SBIN_DIR@/unbound -d -p
|
||||
NotifyAccess=main
|
||||
Type=notify
|
||||
CapabilityBoundingSet=CAP_IPC_LOCK CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_SYS_RESOURCE CAP_NET_RAW
|
||||
CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_SYS_RESOURCE CAP_NET_RAW
|
||||
MemoryDenyWriteExecute=true
|
||||
NoNewPrivileges=true
|
||||
PrivateDevices=true
|
||||
@@ -22,13 +63,9 @@ ProtectHome=true
|
||||
ProtectControlGroups=true
|
||||
ProtectKernelModules=true
|
||||
ProtectSystem=strict
|
||||
ReadWritePaths=/run @UNBOUND_RUN_DIR@ @UNBOUND_CHROOT_DIR@
|
||||
TemporaryFileSystem=@UNBOUND_CHROOT_DIR@/dev:ro
|
||||
TemporaryFileSystem=@UNBOUND_CHROOT_DIR@/run:ro
|
||||
BindReadOnlyPaths=-/run/systemd/notify:@UNBOUND_CHROOT_DIR@/run/systemd/notify
|
||||
BindPaths=-@UNBOUND_PIDFILE@:@UNBOUND_CHROOT_DIR@@UNBOUND_PIDFILE@
|
||||
BindReadOnlyPaths=-/dev/urandom:@UNBOUND_CHROOT_DIR@/dev/urandom
|
||||
BindPaths=-/dev/log:@UNBOUND_CHROOT_DIR@/dev/log
|
||||
RuntimeDirectory=unbound
|
||||
ConfigurationDirectory=unbound
|
||||
StateDirectory=unbound
|
||||
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
|
||||
RestrictRealtime=true
|
||||
SystemCallArchitectures=native
|
||||
@@ -36,3 +73,12 @@ SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module mount @obsolete
|
||||
RestrictNamespaces=yes
|
||||
LockPersonality=yes
|
||||
RestrictSUIDSGID=yes
|
||||
ReadWritePaths=@UNBOUND_RUN_DIR@ @UNBOUND_CHROOT_DIR@
|
||||
|
||||
# Below rules are needed when chroot is enabled (usually it's enabled by default).
|
||||
# If chroot is disabled like chrooot: "" then they may be safely removed.
|
||||
TemporaryFileSystem=@UNBOUND_CHROOT_DIR@/dev:ro
|
||||
TemporaryFileSystem=@UNBOUND_CHROOT_DIR@/run:ro
|
||||
BindReadOnlyPaths=-/run/systemd/notify:@UNBOUND_CHROOT_DIR@/run/systemd/notify
|
||||
BindReadOnlyPaths=-/dev/urandom:@UNBOUND_CHROOT_DIR@/dev/urandom
|
||||
BindPaths=-/dev/log:@UNBOUND_CHROOT_DIR@/dev/log
|
||||
|
||||
@@ -242,6 +242,8 @@ if test "$1" = "config" ; then
|
||||
p_config "total.num.prefetch" "cache prefetch" "ABSOLUTE"
|
||||
p_config "num.query.tcp" "TCP queries" "ABSOLUTE"
|
||||
p_config "num.query.tcpout" "TCP out queries" "ABSOLUTE"
|
||||
p_config "num.query.tls" "TLS queries" "ABSOLUTE"
|
||||
p_config "num.query.tls.resume" "TLS resumes" "ABSOLUTE"
|
||||
p_config "num.query.ipv6" "IPv6 queries" "ABSOLUTE"
|
||||
p_config "unwanted.queries" "queries that failed acl" "ABSOLUTE"
|
||||
p_config "unwanted.replies" "unwanted or unsolicited replies" "ABSOLUTE"
|
||||
@@ -443,7 +445,8 @@ hits)
|
||||
for x in `grep "^thread[0-9][0-9]*\.num\.queries=" $state |
|
||||
sed -e 's/=.*//'` total.num.queries \
|
||||
total.num.cachehits total.num.prefetch num.query.tcp \
|
||||
num.query.tcpout num.query.ipv6 unwanted.queries \
|
||||
num.query.tcpout num.query.tls num.query.tls.resume \
|
||||
num.query.ipv6 unwanted.queries \
|
||||
unwanted.replies; do
|
||||
if grep "^"$x"=" $state >/dev/null 2>&1; then
|
||||
print_value $x
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
; This unit file is provided to run unbound as portable service.
|
||||
; https://systemd.io/PORTABLE_SERVICES/
|
||||
;
|
||||
; To use this unit file, please make sure you either compile unbound with the
|
||||
; following options:
|
||||
;
|
||||
; - --with-chroot-dir=""
|
||||
;
|
||||
; Or put the following options in your unbound configuration file:
|
||||
;
|
||||
; - chroot: ""
|
||||
;
|
||||
;
|
||||
[Unit]
|
||||
Description=Validating, recursive, and caching DNS resolver
|
||||
Documentation=man:unbound(8)
|
||||
After=network.target
|
||||
Before=network-online.target nss-lookup.target
|
||||
Wants=nss-lookup.target
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
[Service]
|
||||
ExecReload=+/bin/kill -HUP $MAINPID
|
||||
ExecStart=@UNBOUND_SBIN_DIR@/unbound -d -p
|
||||
NotifyAccess=main
|
||||
Type=notify
|
||||
CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_SYS_RESOURCE CAP_NET_RAW
|
||||
MemoryDenyWriteExecute=true
|
||||
NoNewPrivileges=true
|
||||
PrivateDevices=true
|
||||
PrivateTmp=true
|
||||
ProtectHome=true
|
||||
ProtectControlGroups=true
|
||||
ProtectKernelModules=true
|
||||
ProtectSystem=strict
|
||||
RuntimeDirectory=unbound
|
||||
ConfigurationDirectory=unbound
|
||||
StateDirectory=unbound
|
||||
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
|
||||
RestrictRealtime=true
|
||||
SystemCallArchitectures=native
|
||||
SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module mount @obsolete @resources
|
||||
RestrictNamespaces=yes
|
||||
LockPersonality=yes
|
||||
RestrictSUIDSGID=yes
|
||||
BindPaths=/run/systemd/notify
|
||||
BindReadOnlyPaths=/dev/log /run/systemd/journal/socket /run/systemd/journal/stdout
|
||||
Binary file not shown.
Binary file not shown.
+8
-1
@@ -617,7 +617,8 @@ daemon_fork(struct daemon* daemon)
|
||||
have_view_respip_cfg;
|
||||
|
||||
/* read auth zonefiles */
|
||||
if(!auth_zones_apply_cfg(daemon->env->auth_zones, daemon->cfg, 1))
|
||||
if(!auth_zones_apply_cfg(daemon->env->auth_zones, daemon->cfg, 1,
|
||||
&daemon->use_rpz))
|
||||
fatal_exit("auth_zones could not be setup");
|
||||
|
||||
/* setup modules */
|
||||
@@ -629,6 +630,12 @@ daemon_fork(struct daemon* daemon)
|
||||
if(daemon->use_response_ip &&
|
||||
modstack_find(&daemon->mods, "respip") < 0)
|
||||
fatal_exit("response-ip options require respip module");
|
||||
/* RPZ response ip triggers don't work as expected without the respip
|
||||
* module. To avoid run-time operational surprise we reject such
|
||||
* configuration. */
|
||||
if(daemon->use_rpz &&
|
||||
modstack_find(&daemon->mods, "respip") < 0)
|
||||
fatal_exit("RPZ requires the respip module");
|
||||
|
||||
/* first create all the worker structures, so we can pass
|
||||
* them to the newly created threads.
|
||||
|
||||
@@ -132,6 +132,8 @@ struct daemon {
|
||||
struct respip_set* respip_set;
|
||||
/** some response-ip tags or actions are configured if true */
|
||||
int use_response_ip;
|
||||
/** some RPZ policies are configured */
|
||||
int use_rpz;
|
||||
#ifdef USE_DNSCRYPT
|
||||
/** the dnscrypt environment */
|
||||
struct dnsc_env* dnscenv;
|
||||
|
||||
+38
-2
@@ -69,6 +69,7 @@
|
||||
#include "services/mesh.h"
|
||||
#include "services/localzone.h"
|
||||
#include "services/authzone.h"
|
||||
#include "services/rpz.h"
|
||||
#include "util/storage/slabhash.h"
|
||||
#include "util/fptr_wlist.h"
|
||||
#include "util/data/dname.h"
|
||||
@@ -719,8 +720,8 @@ print_stats(RES* ssl, const char* nm, struct ub_stats_info* s)
|
||||
(unsigned long)s->svr.num_queries_missed_cache)) return 0;
|
||||
if(!ssl_printf(ssl, "%s.num.prefetch"SQ"%lu\n", nm,
|
||||
(unsigned long)s->svr.num_queries_prefetch)) return 0;
|
||||
if(!ssl_printf(ssl, "%s.num.zero_ttl"SQ"%lu\n", nm,
|
||||
(unsigned long)s->svr.zero_ttl_responses)) return 0;
|
||||
if(!ssl_printf(ssl, "%s.num.expired"SQ"%lu\n", nm,
|
||||
(unsigned long)s->svr.ans_expired)) return 0;
|
||||
if(!ssl_printf(ssl, "%s.num.recursivereplies"SQ"%lu\n", nm,
|
||||
(unsigned long)s->mesh_replies_sent)) return 0;
|
||||
#ifdef USE_DNSCRYPT
|
||||
@@ -1045,6 +1046,16 @@ print_ext(RES* ssl, struct ub_stats_info* s)
|
||||
(unsigned)s->svr.infra_cache_count)) return 0;
|
||||
if(!ssl_printf(ssl, "key.cache.count"SQ"%u\n",
|
||||
(unsigned)s->svr.key_cache_count)) return 0;
|
||||
/* applied RPZ actions */
|
||||
for(i=0; i<UB_STATS_RPZ_ACTION_NUM; i++) {
|
||||
if(i == RPZ_NO_OVERRIDE_ACTION)
|
||||
continue;
|
||||
if(inhibit_zero && s->svr.rpz_action[i] == 0)
|
||||
continue;
|
||||
if(!ssl_printf(ssl, "num.rpz.action.%s"SQ"%lu\n",
|
||||
rpz_action_to_string(i),
|
||||
(unsigned long)s->svr.rpz_action[i])) return 0;
|
||||
}
|
||||
#ifdef USE_DNSCRYPT
|
||||
if(!ssl_printf(ssl, "dnscrypt_shared_secret.cache.count"SQ"%u\n",
|
||||
(unsigned)s->svr.shared_secret_cache_count)) return 0;
|
||||
@@ -1479,6 +1490,27 @@ do_view_data_remove(RES* ssl, struct worker* worker, char* arg)
|
||||
lock_rw_unlock(&v->lock);
|
||||
}
|
||||
|
||||
/** Remove RR data from stdin from view */
|
||||
static void
|
||||
do_view_datas_remove(RES* ssl, struct worker* worker, char* arg)
|
||||
{
|
||||
struct view* v;
|
||||
v = views_find_view(worker->daemon->views,
|
||||
arg, 1 /* get write lock*/);
|
||||
if(!v) {
|
||||
ssl_printf(ssl,"no view with name: %s\n", arg);
|
||||
return;
|
||||
}
|
||||
if(!v->local_zones){
|
||||
lock_rw_unlock(&v->lock);
|
||||
ssl_printf(ssl, "removed 0 datas\n");
|
||||
return;
|
||||
}
|
||||
|
||||
do_datas_remove(ssl, v->local_zones);
|
||||
lock_rw_unlock(&v->lock);
|
||||
}
|
||||
|
||||
/** cache lookup of nameservers */
|
||||
static void
|
||||
do_lookup(RES* ssl, struct worker* worker, char* arg)
|
||||
@@ -2506,8 +2538,10 @@ do_auth_zone_transfer(RES* ssl, struct worker* worker, char* arg)
|
||||
if(!az || !auth_zones_startprobesequence(az, &worker->env, nm, nmlen,
|
||||
LDNS_RR_CLASS_IN)) {
|
||||
(void)ssl_printf(ssl, "error zone xfr task not found %s\n", arg);
|
||||
free(nm);
|
||||
return;
|
||||
}
|
||||
free(nm);
|
||||
send_ok(ssl);
|
||||
}
|
||||
|
||||
@@ -2989,6 +3023,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)) {
|
||||
|
||||
+6
-2
@@ -271,8 +271,10 @@ server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset)
|
||||
s->svr.ans_secure += (long long)worker->env.mesh->ans_secure;
|
||||
s->svr.ans_bogus += (long long)worker->env.mesh->ans_bogus;
|
||||
s->svr.ans_rcode_nodata += (long long)worker->env.mesh->ans_nodata;
|
||||
for(i=0; i<16; i++)
|
||||
for(i=0; i<UB_STATS_RCODE_NUM; i++)
|
||||
s->svr.ans_rcode[i] += (long long)worker->env.mesh->ans_rcode[i];
|
||||
for(i=0; i<UB_STATS_RPZ_ACTION_NUM; i++)
|
||||
s->svr.rpz_action[i] += (long long)worker->env.mesh->rpz_action[i];
|
||||
timehist_export(worker->env.mesh->histogram, s->svr.hist,
|
||||
NUM_BUCKETS_HIST);
|
||||
/* values from outside network */
|
||||
@@ -398,6 +400,7 @@ void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a)
|
||||
total->svr.num_queries_missed_cache += a->svr.num_queries_missed_cache;
|
||||
total->svr.num_queries_prefetch += a->svr.num_queries_prefetch;
|
||||
total->svr.sum_query_list_size += a->svr.sum_query_list_size;
|
||||
total->svr.ans_expired += a->svr.ans_expired;
|
||||
#ifdef USE_DNSCRYPT
|
||||
total->svr.num_query_dnscrypt_crypted += a->svr.num_query_dnscrypt_crypted;
|
||||
total->svr.num_query_dnscrypt_cert += a->svr.num_query_dnscrypt_cert;
|
||||
@@ -430,7 +433,6 @@ void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a)
|
||||
total->svr.qEDNS += a->svr.qEDNS;
|
||||
total->svr.qEDNS_DO += a->svr.qEDNS_DO;
|
||||
total->svr.ans_rcode_nodata += a->svr.ans_rcode_nodata;
|
||||
total->svr.zero_ttl_responses += a->svr.zero_ttl_responses;
|
||||
total->svr.ans_secure += a->svr.ans_secure;
|
||||
total->svr.ans_bogus += a->svr.ans_bogus;
|
||||
total->svr.unwanted_replies += a->svr.unwanted_replies;
|
||||
@@ -446,6 +448,8 @@ void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a)
|
||||
total->svr.ans_rcode[i] += a->svr.ans_rcode[i];
|
||||
for(i=0; i<NUM_BUCKETS_HIST; i++)
|
||||
total->svr.hist[i] += a->svr.hist[i];
|
||||
for(i=0; i<UB_STATS_RPZ_ACTION_NUM; i++)
|
||||
total->svr.rpz_action[i] += a->svr.rpz_action[i];
|
||||
}
|
||||
|
||||
total->mesh_num_states += a->mesh_num_states;
|
||||
|
||||
+7
-18
@@ -259,21 +259,10 @@ checkrlimits(struct config_file* cfg)
|
||||
#endif /* S_SPLINT_S */
|
||||
}
|
||||
|
||||
/** set default logfile identity based on value from argv[0] at startup **/
|
||||
static void
|
||||
log_ident_set_fromdefault(struct config_file* cfg,
|
||||
const char *log_default_identity)
|
||||
{
|
||||
if(cfg->log_identity == NULL || cfg->log_identity[0] == 0)
|
||||
log_ident_set(log_default_identity);
|
||||
else
|
||||
log_ident_set(cfg->log_identity);
|
||||
}
|
||||
|
||||
/** set verbosity, check rlimits, cache settings */
|
||||
static void
|
||||
apply_settings(struct daemon* daemon, struct config_file* cfg,
|
||||
int cmdline_verbose, int debug_mode, const char* log_default_identity)
|
||||
apply_settings(struct daemon* daemon, struct config_file* cfg,
|
||||
int cmdline_verbose, int debug_mode)
|
||||
{
|
||||
/* apply if they have changed */
|
||||
verbosity = cmdline_verbose + cfg->verbosity;
|
||||
@@ -289,7 +278,7 @@ apply_settings(struct daemon* daemon, struct config_file* cfg,
|
||||
log_warn("use-systemd and do-daemonize should not be enabled at the same time");
|
||||
}
|
||||
|
||||
log_ident_set_fromdefault(cfg, log_default_identity);
|
||||
log_ident_set_or_default(cfg->log_identity);
|
||||
}
|
||||
|
||||
#ifdef HAVE_KILL
|
||||
@@ -639,11 +628,10 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
|
||||
* @param cmdline_verbose: verbosity resulting from commandline -v.
|
||||
* These increase verbosity as specified in the config file.
|
||||
* @param debug_mode: if set, do not daemonize.
|
||||
* @param log_default_identity: Default identity to report in logs
|
||||
* @param need_pidfile: if false, no pidfile is checked or created.
|
||||
*/
|
||||
static void
|
||||
run_daemon(const char* cfgfile, int cmdline_verbose, int debug_mode, const char* log_default_identity, int need_pidfile)
|
||||
run_daemon(const char* cfgfile, int cmdline_verbose, int debug_mode, int need_pidfile)
|
||||
{
|
||||
struct config_file* cfg = NULL;
|
||||
struct daemon* daemon = NULL;
|
||||
@@ -667,7 +655,7 @@ run_daemon(const char* cfgfile, int cmdline_verbose, int debug_mode, const char*
|
||||
"or unbound-checkconf", cfgfile);
|
||||
log_warn("Continuing with default config settings");
|
||||
}
|
||||
apply_settings(daemon, cfg, cmdline_verbose, debug_mode, log_default_identity);
|
||||
apply_settings(daemon, cfg, cmdline_verbose, debug_mode);
|
||||
if(!done_setup)
|
||||
config_lookup_uid(cfg);
|
||||
|
||||
@@ -733,6 +721,7 @@ main(int argc, char* argv[])
|
||||
|
||||
log_init(NULL, 0, NULL);
|
||||
log_ident_default = strrchr(argv[0],'/')?strrchr(argv[0],'/')+1:argv[0];
|
||||
log_ident_set_default(log_ident_default);
|
||||
log_ident_set(log_ident_default);
|
||||
/* parse the options */
|
||||
while( (c=getopt(argc, argv, "c:dhpvw:V")) != -1) {
|
||||
@@ -783,7 +772,7 @@ main(int argc, char* argv[])
|
||||
return 1;
|
||||
}
|
||||
|
||||
run_daemon(cfgfile, cmdline_verbose, debug_mode, log_ident_default, need_pidfile);
|
||||
run_daemon(cfgfile, cmdline_verbose, debug_mode, need_pidfile);
|
||||
log_init(NULL, 0, NULL); /* close logfile */
|
||||
#ifndef unbound_testbound
|
||||
if(log_get_lock()) {
|
||||
|
||||
+93
-53
@@ -61,6 +61,7 @@
|
||||
#include "services/authzone.h"
|
||||
#include "services/mesh.h"
|
||||
#include "services/localzone.h"
|
||||
#include "services/rpz.h"
|
||||
#include "util/data/msgparse.h"
|
||||
#include "util/data/msgencode.h"
|
||||
#include "util/data/dname.h"
|
||||
@@ -572,9 +573,10 @@ static int
|
||||
apply_respip_action(struct worker* worker, const struct query_info* qinfo,
|
||||
struct respip_client_info* cinfo, struct reply_info* rep,
|
||||
struct comm_reply* repinfo, struct ub_packed_rrset_key** alias_rrset,
|
||||
struct reply_info** encode_repp)
|
||||
struct reply_info** encode_repp, struct auth_zones* az)
|
||||
{
|
||||
struct respip_action_info actinfo = {respip_none, NULL};
|
||||
struct respip_action_info actinfo = {0};
|
||||
actinfo.action = respip_none;
|
||||
|
||||
if(qinfo->qtype != LDNS_RR_TYPE_A &&
|
||||
qinfo->qtype != LDNS_RR_TYPE_AAAA &&
|
||||
@@ -582,7 +584,7 @@ apply_respip_action(struct worker* worker, const struct query_info* qinfo,
|
||||
return 1;
|
||||
|
||||
if(!respip_rewrite_reply(qinfo, cinfo, rep, encode_repp, &actinfo,
|
||||
alias_rrset, 0, worker->scratchpad))
|
||||
alias_rrset, 0, worker->scratchpad, az))
|
||||
return 0;
|
||||
|
||||
/* xxx_deny actions mean dropping the reply, unless the original reply
|
||||
@@ -595,9 +597,19 @@ apply_respip_action(struct worker* worker, const struct query_info* qinfo,
|
||||
/* If address info is returned, it means the action should be an
|
||||
* 'inform' variant and the information should be logged. */
|
||||
if(actinfo.addrinfo) {
|
||||
respip_inform_print(actinfo.addrinfo, qinfo->qname,
|
||||
respip_inform_print(&actinfo, qinfo->qname,
|
||||
qinfo->qtype, qinfo->qclass, qinfo->local_alias,
|
||||
repinfo);
|
||||
|
||||
if(worker->stats.extended && actinfo.rpz_used) {
|
||||
if(actinfo.rpz_disabled)
|
||||
worker->stats.rpz_action[RPZ_DISABLED_ACTION]++;
|
||||
if(actinfo.rpz_cname_override)
|
||||
worker->stats.rpz_action[RPZ_CNAME_OVERRIDE_ACTION]++;
|
||||
else
|
||||
worker->stats.rpz_action[
|
||||
respip_action_to_rpz_action(actinfo.action)]++;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
@@ -613,10 +625,10 @@ apply_respip_action(struct worker* worker, const struct query_info* qinfo,
|
||||
* be completely dropped, '*need_drop' will be set to 1. */
|
||||
static int
|
||||
answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
struct respip_client_info* cinfo, int* need_drop,
|
||||
struct ub_packed_rrset_key** alias_rrset,
|
||||
struct respip_client_info* cinfo, int* need_drop, int* is_expired_answer,
|
||||
int* is_secure_answer, struct ub_packed_rrset_key** alias_rrset,
|
||||
struct reply_info** partial_repp,
|
||||
struct reply_info* rep, uint16_t id, uint16_t flags,
|
||||
struct reply_info* rep, uint16_t id, uint16_t flags,
|
||||
struct comm_reply* repinfo, struct edns_data* edns)
|
||||
{
|
||||
struct edns_data edns_bak;
|
||||
@@ -624,38 +636,37 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
uint16_t udpsize = edns->udp_size;
|
||||
struct reply_info* encode_rep = rep;
|
||||
struct reply_info* partial_rep = *partial_repp;
|
||||
int secure;
|
||||
int must_validate = (!(flags&BIT_CD) || worker->env.cfg->ignore_cd)
|
||||
&& worker->env.need_to_validate;
|
||||
*partial_repp = NULL; /* avoid accidental further pass */
|
||||
if(worker->env.cfg->serve_expired) {
|
||||
if(worker->env.cfg->serve_expired_ttl &&
|
||||
rep->serve_expired_ttl < timenow)
|
||||
return 0;
|
||||
if(!rrset_array_lock(rep->ref, rep->rrset_count, 0))
|
||||
return 0;
|
||||
/* below, rrsets with ttl before timenow become TTL 0 in
|
||||
* the response */
|
||||
/* This response was served with zero TTL */
|
||||
if (timenow >= rep->ttl) {
|
||||
worker->stats.zero_ttl_responses++;
|
||||
}
|
||||
} else {
|
||||
/* see if it is possible */
|
||||
if(rep->ttl < timenow) {
|
||||
*partial_repp = NULL; /* avoid accidental further pass */
|
||||
|
||||
/* Check TTL */
|
||||
if(rep->ttl < timenow) {
|
||||
/* Check if we need to serve expired now */
|
||||
if(worker->env.cfg->serve_expired &&
|
||||
!worker->env.cfg->serve_expired_client_timeout) {
|
||||
if(worker->env.cfg->serve_expired_ttl &&
|
||||
rep->serve_expired_ttl < timenow)
|
||||
return 0;
|
||||
if(!rrset_array_lock(rep->ref, rep->rrset_count, 0))
|
||||
return 0;
|
||||
*is_expired_answer = 1;
|
||||
} else {
|
||||
/* the rrsets may have been updated in the meantime.
|
||||
* we will refetch the message format from the
|
||||
* authoritative server
|
||||
* authoritative server
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if(!rrset_array_lock(rep->ref, rep->rrset_count, timenow))
|
||||
return 0;
|
||||
/* locked and ids and ttls are OK. */
|
||||
}
|
||||
/* locked and ids and ttls are OK. */
|
||||
|
||||
/* check CNAME chain (if any) */
|
||||
if(rep->an_numrrsets > 0 && (rep->rrsets[0]->rk.type ==
|
||||
htons(LDNS_RR_TYPE_CNAME) || rep->rrsets[0]->rk.type ==
|
||||
if(rep->an_numrrsets > 0 && (rep->rrsets[0]->rk.type ==
|
||||
htons(LDNS_RR_TYPE_CNAME) || rep->rrsets[0]->rk.type ==
|
||||
htons(LDNS_RR_TYPE_DNAME))) {
|
||||
if(!reply_check_cname_chain(qinfo, rep)) {
|
||||
/* cname chain invalid, redo iterator steps */
|
||||
@@ -674,31 +685,31 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, rep,
|
||||
LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad))
|
||||
goto bail_out;
|
||||
error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
|
||||
error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
|
||||
qinfo, id, flags, edns);
|
||||
rrset_array_unlock_touch(worker->env.rrset_cache,
|
||||
rrset_array_unlock_touch(worker->env.rrset_cache,
|
||||
worker->scratchpad, rep->ref, rep->rrset_count);
|
||||
if(worker->stats.extended) {
|
||||
worker->stats.ans_bogus ++;
|
||||
worker->stats.ans_rcode[LDNS_RCODE_SERVFAIL] ++;
|
||||
}
|
||||
return 1;
|
||||
} else if( rep->security == sec_status_unchecked && must_validate) {
|
||||
} else if(rep->security == sec_status_unchecked && must_validate) {
|
||||
verbose(VERB_ALGO, "Cache reply: unchecked entry needs "
|
||||
"validation");
|
||||
goto bail_out; /* need to validate cache entry first */
|
||||
} else if(rep->security == sec_status_secure) {
|
||||
if(reply_all_rrsets_secure(rep))
|
||||
secure = 1;
|
||||
else {
|
||||
if(reply_all_rrsets_secure(rep)) {
|
||||
*is_secure_answer = 1;
|
||||
} else {
|
||||
if(must_validate) {
|
||||
verbose(VERB_ALGO, "Cache reply: secure entry"
|
||||
" changed status");
|
||||
goto bail_out; /* rrset changed, re-verify */
|
||||
}
|
||||
secure = 0;
|
||||
*is_secure_answer = 0;
|
||||
}
|
||||
} else secure = 0;
|
||||
} else *is_secure_answer = 0;
|
||||
|
||||
edns_bak = *edns;
|
||||
edns->edns_version = EDNS_ADVERTISED_VERSION;
|
||||
@@ -709,17 +720,21 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
(int)(flags&LDNS_RCODE_MASK), edns, repinfo, worker->scratchpad))
|
||||
goto bail_out;
|
||||
*alias_rrset = NULL; /* avoid confusion if caller set it to non-NULL */
|
||||
if(worker->daemon->use_response_ip && !partial_rep &&
|
||||
!apply_respip_action(worker, qinfo, cinfo, rep, repinfo, alias_rrset,
|
||||
&encode_rep)) {
|
||||
if((worker->daemon->use_response_ip || worker->daemon->use_rpz) &&
|
||||
!partial_rep && !apply_respip_action(worker, qinfo, cinfo, rep,
|
||||
repinfo, alias_rrset,
|
||||
&encode_rep, worker->env.auth_zones)) {
|
||||
goto bail_out;
|
||||
} else if(partial_rep &&
|
||||
!respip_merge_cname(partial_rep, qinfo, rep, cinfo,
|
||||
must_validate, &encode_rep, worker->scratchpad)) {
|
||||
must_validate, &encode_rep, worker->scratchpad,
|
||||
worker->env.auth_zones)) {
|
||||
goto bail_out;
|
||||
}
|
||||
if(encode_rep != rep)
|
||||
secure = 0; /* if rewritten, it can't be considered "secure" */
|
||||
if(encode_rep != rep) {
|
||||
/* if rewritten, it can't be considered "secure" */
|
||||
*is_secure_answer = 0;
|
||||
}
|
||||
if(!encode_rep || *alias_rrset) {
|
||||
if(!encode_rep)
|
||||
*need_drop = 1;
|
||||
@@ -736,7 +751,7 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
repinfo->c, worker->scratchpad) ||
|
||||
!reply_info_answer_encode(qinfo, encode_rep, id, flags,
|
||||
repinfo->c->buffer, timenow, 1, worker->scratchpad,
|
||||
udpsize, edns, (int)(edns->bits & EDNS_DO), secure)) {
|
||||
udpsize, edns, (int)(edns->bits & EDNS_DO), *is_secure_answer)) {
|
||||
if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, NULL,
|
||||
LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad))
|
||||
edns->opt_list = NULL;
|
||||
@@ -747,10 +762,6 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
* is bad while holding locks. */
|
||||
rrset_array_unlock_touch(worker->env.rrset_cache, worker->scratchpad,
|
||||
rep->ref, rep->rrset_count);
|
||||
if(worker->stats.extended) {
|
||||
if(secure) worker->stats.ans_secure++;
|
||||
server_stats_insrcode(&worker->stats, repinfo->c->buffer);
|
||||
}
|
||||
/* go and return this buffer to the client */
|
||||
return 1;
|
||||
|
||||
@@ -1085,6 +1096,8 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
struct acl_addr* acladdr;
|
||||
int rc = 0;
|
||||
int need_drop = 0;
|
||||
int is_expired_answer = 0;
|
||||
int is_secure_answer = 0;
|
||||
/* We might have to chase a CNAME chain internally, in which case
|
||||
* we'll have up to two replies and combine them to build a complete
|
||||
* answer. These variables control this case. */
|
||||
@@ -1364,6 +1377,18 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
server_stats_insrcode(&worker->stats, c->buffer);
|
||||
goto send_reply;
|
||||
}
|
||||
if(worker->env.auth_zones &&
|
||||
rpz_apply_qname_trigger(worker->env.auth_zones,
|
||||
&worker->env, &qinfo, &edns, c->buffer, worker->scratchpad,
|
||||
repinfo, acladdr->taglist, acladdr->taglen, &worker->stats)) {
|
||||
regional_free_all(worker->scratchpad);
|
||||
if(sldns_buffer_limit(c->buffer) == 0) {
|
||||
comm_point_drop_reply(repinfo);
|
||||
return 0;
|
||||
}
|
||||
server_stats_insrcode(&worker->stats, c->buffer);
|
||||
goto send_reply;
|
||||
}
|
||||
if(worker->env.auth_zones &&
|
||||
auth_zones_answer(worker->env.auth_zones, &worker->env,
|
||||
&qinfo, &edns, repinfo, c->buffer, worker->scratchpad)) {
|
||||
@@ -1434,7 +1459,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
/* If we may apply IP-based actions to the answer, build the client
|
||||
* information. As this can be expensive, skip it if there is
|
||||
* absolutely no possibility of it. */
|
||||
if(worker->daemon->use_response_ip &&
|
||||
if((worker->daemon->use_response_ip || worker->daemon->use_rpz) &&
|
||||
(qinfo.qtype == LDNS_RR_TYPE_A ||
|
||||
qinfo.qtype == LDNS_RR_TYPE_AAAA ||
|
||||
qinfo.qtype == LDNS_RR_TYPE_ANY)) {
|
||||
@@ -1455,12 +1480,14 @@ lookup_cache:
|
||||
* each pass. We should still pass the original qinfo to
|
||||
* answer_from_cache(), however, since it's used to build the reply. */
|
||||
if(!edns_bypass_cache_stage(edns.opt_list, &worker->env)) {
|
||||
is_expired_answer = 0;
|
||||
is_secure_answer = 0;
|
||||
h = query_info_hash(lookup_qinfo, sldns_buffer_read_u16_at(c->buffer, 2));
|
||||
if((e=slabhash_lookup(worker->env.msg_cache, h, lookup_qinfo, 0))) {
|
||||
/* answer from cache - we have acquired a readlock on it */
|
||||
if(answer_from_cache(worker, &qinfo,
|
||||
cinfo, &need_drop, &alias_rrset, &partial_rep,
|
||||
(struct reply_info*)e->data,
|
||||
cinfo, &need_drop, &is_expired_answer, &is_secure_answer,
|
||||
&alias_rrset, &partial_rep, (struct reply_info*)e->data,
|
||||
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
|
||||
sldns_buffer_read_u16_at(c->buffer, 2), repinfo,
|
||||
&edns)) {
|
||||
@@ -1468,9 +1495,11 @@ lookup_cache:
|
||||
* Note that if there is more than one pass
|
||||
* its qname must be that used for cache
|
||||
* lookup. */
|
||||
if((worker->env.cfg->prefetch || worker->env.cfg->serve_expired)
|
||||
&& *worker->env.now >=
|
||||
((struct reply_info*)e->data)->prefetch_ttl) {
|
||||
if((worker->env.cfg->prefetch && *worker->env.now >=
|
||||
((struct reply_info*)e->data)->prefetch_ttl) ||
|
||||
(worker->env.cfg->serve_expired &&
|
||||
*worker->env.now >= ((struct reply_info*)e->data)->ttl)) {
|
||||
|
||||
time_t leeway = ((struct reply_info*)e->
|
||||
data)->ttl - *worker->env.now;
|
||||
if(((struct reply_info*)e->data)->ttl
|
||||
@@ -1555,6 +1584,13 @@ send_reply_rc:
|
||||
comm_point_drop_reply(repinfo);
|
||||
return 0;
|
||||
}
|
||||
if(is_expired_answer) {
|
||||
worker->stats.ans_expired++;
|
||||
}
|
||||
if(worker->stats.extended) {
|
||||
if(is_secure_answer) worker->stats.ans_secure++;
|
||||
server_stats_insrcode(&worker->stats, repinfo->c->buffer);
|
||||
}
|
||||
#ifdef USE_DNSTAP
|
||||
if(worker->dtenv.log_client_response_messages)
|
||||
dt_msg_send_client_response(&worker->dtenv, &repinfo->addr,
|
||||
@@ -1830,6 +1866,10 @@ worker_init(struct worker* worker, struct config_file *cfg,
|
||||
return 0;
|
||||
}
|
||||
worker->env.mesh = mesh_create(&worker->daemon->mods, &worker->env);
|
||||
/* Pass on daemon variables that we would need in the mesh area */
|
||||
worker->env.mesh->use_response_ip = worker->daemon->use_response_ip;
|
||||
worker->env.mesh->use_rpz = worker->daemon->use_rpz;
|
||||
|
||||
worker->env.detach_subs = &mesh_detach_subs;
|
||||
worker->env.attach_sub = &mesh_attach_sub;
|
||||
worker->env.add_sub = &mesh_add_sub;
|
||||
|
||||
+169
@@ -1,6 +1,175 @@
|
||||
20 February 2020: Wouter
|
||||
- Updated contrib/unbound_smf23.tar.gz with Solaris SMF service for
|
||||
Unbound from Yuri Voinov.
|
||||
|
||||
17 February 2020: Ralph
|
||||
- Add respip to supported module-config options in unbound-checkconf.
|
||||
|
||||
17 February 2020: George
|
||||
- Remove unused variable.
|
||||
|
||||
17 February 2020: Wouter
|
||||
- contrib/drop2rpz: perl script that converts the Spamhaus DROP-List
|
||||
in RPZ-Format, contributed by Andreas Schulze.
|
||||
|
||||
14 February 2020: Wouter
|
||||
- Fix spelling in unbound.conf.5.in.
|
||||
- Stop unbound-checkconf from insisting that auth-zone and rpz
|
||||
zonefiles have to exist. They can not exist, and download later.
|
||||
|
||||
13 February 2020: Wouter
|
||||
- tag for 1.10.0rc1 release.
|
||||
|
||||
12 February 2020: Wouter
|
||||
- Fix with libnettle make test with dsa disabled.
|
||||
- Fix contrib/fastrpz.patch to apply cleanly. Fix for serve-stale
|
||||
fixes, but it does not compile, conflicts with new rpz code.
|
||||
- Fix to clean memory leak of respip_addr.lock when ip_tree deleted.
|
||||
- Fix compile warning when threads disabled.
|
||||
- updated version number to 1.10.0.
|
||||
|
||||
10 February 2020: George
|
||||
- Document 'ub_result.was_ratelimited' in libunbound.
|
||||
- Fix use after free on log-identity after a reload; Fixes #163.
|
||||
|
||||
6 February 2020: George
|
||||
- Fix num_reply_states and num_detached_states counting with
|
||||
serve_expired_callback.
|
||||
- Cleaner code in mesh_serve_expired_lookup.
|
||||
- Document in unbound.conf manpage that configuration clauses can be
|
||||
repeated in the configuration file.
|
||||
|
||||
6 February 2020: Wouter
|
||||
- Fix num_reply_addr counting in mesh and tcp drop due to size
|
||||
after serve_stale commit.
|
||||
- Fix to create and destroy rpz_lock in auth_zones structure.
|
||||
- Fix to lock zone before adding rpz qname trigger.
|
||||
- Fix to lock and release once in mesh_serve_expired_lookup.
|
||||
- Fix to put braces around empty if body when threading is disabled.
|
||||
|
||||
5 February 2020: George
|
||||
- Added serve-stale functionality as described in
|
||||
draft-ietf-dnsop-serve-stale-10. `serve-expired-*` options can be used
|
||||
to configure the behavior.
|
||||
- Updated cachedb to honor `serve-expired-ttl`; Fixes #107.
|
||||
- Renamed statistic `num.zero_ttl` to `num.expired` as expired replies
|
||||
come with a configurable TTL value (`serve-expired-reply-ttl`).
|
||||
- Fixed stats when replying with cached, cname-aliased records.
|
||||
- Added missing default values for redis cachedb backend.
|
||||
|
||||
3 February 2020: Ralph
|
||||
- Add assertion to please static analyzer
|
||||
|
||||
31 January 2020: Wouter
|
||||
- Fix fclose on error in TLS session ticket code.
|
||||
|
||||
30 January 2020: Ralph
|
||||
- Fix memory leak in error condition remote.c
|
||||
- Fix double free in error condition view.c
|
||||
- Fix memory leak in do_auth_zone_transfer on success
|
||||
- Merge RPZ support into master. Only QNAME and Response IP triggers are
|
||||
supported.
|
||||
- Stop working on socket when socket() call returns an error.
|
||||
- Check malloc return values in TLS session ticket code
|
||||
|
||||
30 January 2020: Wouter
|
||||
- Fix subnet tests for disabled DSA algorithm by default.
|
||||
- Update contrib/fastrpz.patch for clean diff with current code.
|
||||
- Merge PR#151: Fixes for systemd units, by Maryse47, Edmonds
|
||||
and Frzk. Updates the unbound.service systemd file and adds
|
||||
a portable systemd service file.
|
||||
- updated .gitignore for added contrib file.
|
||||
- Add build rule for ipset to Makefile
|
||||
- Add getentropy_freebsd.o to Makefile dependencies.
|
||||
|
||||
29 January 2020: Ralph
|
||||
- Merge PR#156 from Alexander Berkes; Added unbound-control
|
||||
view_local_datas_remove command.
|
||||
|
||||
29 January 2020: Wouter
|
||||
- Fix #157: undefined reference to `htobe64'.
|
||||
|
||||
28 January 2020: Ralph
|
||||
- Merge PR#147; change rfc reference for reserved top level dns names.
|
||||
|
||||
28 January 2020: Wouter
|
||||
- iana portlist updated.
|
||||
- Fix to silence the tls handshake errors for broken pipe and reset
|
||||
by peer, unless verbosity is set to 2 or higher.
|
||||
|
||||
27 January 2020: Ralph
|
||||
- Merge PR#154; Allow use of libbsd functions with configure option
|
||||
--with-libbsd. By Robert Edmonds and Steven Chamberlain.
|
||||
- Merge PR#148; Add some TLS stats to unbound_munin_. By Fredrik Pettai.
|
||||
|
||||
27 January 2020: Wouter
|
||||
- Merge PR#155 from Robert Edmonds: contrib/libunbound.pc.in: Fixes
|
||||
to Libs/Requires for crypto library dependencies.
|
||||
- Fix #153: Disable validation for DSA algorithms. RFC 8624
|
||||
compliance.
|
||||
|
||||
23 January 2020: Wouter
|
||||
- Merge PR#150 from Frzk: Systemd unit without chroot. It add
|
||||
contrib/unbound_nochroot.service.in, a systemd file for use with
|
||||
chroot: "", see comments in the file, it uses systemd protections
|
||||
instead.
|
||||
|
||||
14 January 2020: Wouter
|
||||
- Removed the dnscrypt_queries and dnscrypt_queries_chacha tests,
|
||||
because dnscrypt-proxy (2.0.36) does not support the test setup
|
||||
any more, and also the config file format does not seem to have
|
||||
the appropriate keys to recreate that setup.
|
||||
- Fix crash after reload where a stats lookup could reference old key
|
||||
cache and neg cache structures.
|
||||
- Fix for memory leak when edns subnet config options are read when
|
||||
compiled without edns subnet support.
|
||||
- Fix auth zone support for NSEC3 records without salt.
|
||||
|
||||
10 January 2020: Wouter
|
||||
- Fix the relationship between serve-expired and prefetch options,
|
||||
patch from Saksham Manchanda from Secure64.
|
||||
- Fix unreachable code in ssl set options code.
|
||||
|
||||
8 January 2020: Ralph
|
||||
- Fix #138: stop binding pidfile inside chroot dir in systemd service
|
||||
file.
|
||||
|
||||
8 January 2020: Wouter
|
||||
- Fix 'make test' to work for --disable-sha1 configure option.
|
||||
- Fix out-of-bounds null-byte write in sldns_bget_token_par while
|
||||
parsing type WKS, reported by Luis Merino from X41 D-Sec.
|
||||
- Updated sldns_bget_token_par fix for also space for the zero
|
||||
delimiter after the character. And update for more spare space.
|
||||
|
||||
6 January 2020: George
|
||||
- Downgrade compat/getentropy_solaris.c to version 1.4 from OpenBSD.
|
||||
The dl_iterate_phdr() function introduced in newer versions raises
|
||||
compilation errors on solaris 10.
|
||||
- Changes to compat/getentropy_solaris.c for,
|
||||
ifdef stdint.h inclusion for older systems.
|
||||
ifdef sha2.h inclusion for older systems.
|
||||
|
||||
6 January 2020: Wouter
|
||||
- Merge #135 from Florian Obser: Use passed in neg and key cache
|
||||
if non-NULL.
|
||||
- Fix #140: Document slave not downloading new zonefile upon update.
|
||||
|
||||
16 December 2019: George
|
||||
- Update mailing list URL.
|
||||
|
||||
12 December 2019: Ralph
|
||||
- Master is 1.9.7 in development.
|
||||
- Fix typo to let serve-expired-ttl work with ub_ctx_set_option(), by
|
||||
Florian Obser
|
||||
|
||||
10 December 2019: Wouter
|
||||
- Fix to make auth zone IXFR to fallback to AXFR if a single
|
||||
response RR is received over TCP with the SOA in it.
|
||||
|
||||
6 December 2019: Wouter
|
||||
- Fix ipsecmod compile.
|
||||
- Fix Makefile.in for ipset module compile, from Adi Prasaja.
|
||||
- release-1.9.6 tag, which became the 1.9.6 release
|
||||
|
||||
5 December 2019: Wouter
|
||||
- unbound-fuzzers.tar.bz2: three programs for fuzzing, that are 1:1
|
||||
|
||||
+29
-2
@@ -558,8 +558,8 @@ server:
|
||||
# that set CD but cannot validate themselves.
|
||||
# ignore-cd-flag: no
|
||||
|
||||
# Serve expired responses from cache, with TTL 0 in the response,
|
||||
# and then attempt to fetch the data afresh.
|
||||
# Serve expired responses from cache, with serve-expired-reply-ttl in
|
||||
# the response, and then attempt to fetch the data afresh.
|
||||
# serve-expired: no
|
||||
#
|
||||
# Limit serving of expired responses to configured seconds after
|
||||
@@ -571,6 +571,16 @@ server:
|
||||
# that the expired records will be served as long as there are queries
|
||||
# for it.
|
||||
# serve-expired-ttl-reset: no
|
||||
#
|
||||
# TTL value to use when replying with expired data.
|
||||
# serve-expired-reply-ttl: 30
|
||||
#
|
||||
# Time in milliseconds before replying to the client with expired data.
|
||||
# This essentially enables the serve-stale behavior as specified in
|
||||
# draft-ietf-dnsop-serve-stale-10 that first tries to resolve before
|
||||
# immediately responding with expired data. 0 disables this behavior.
|
||||
# A recommended value is 1800.
|
||||
# serve-expired-client-timeout: 0
|
||||
|
||||
# Have the validator log failed validations for your diagnosis.
|
||||
# 0: off. 1: A line per failed user query. 2: With reason and bad IP.
|
||||
@@ -1006,3 +1016,20 @@ remote-control:
|
||||
# name-v6: "list-v6"
|
||||
#
|
||||
|
||||
# Response Policy Zones
|
||||
# RPZ policies. Applied in order of configuration. QNAME and Response IP
|
||||
# Address trigger are the only supported triggers. Supported actions are:
|
||||
# NXDOMAIN, NODATA, PASSTHRU, DROP and Local Data. Policies can be loaded from
|
||||
# file, using zone transfer, or using HTTP. The respip module needs to be added
|
||||
# to the module-config, e.g.: module-config: "respip validator iterator".
|
||||
# rpz:
|
||||
# name: "rpz.example.com"
|
||||
# zonefile: "rpz.example.com"
|
||||
# master: 192.0.2.0
|
||||
# allow-notify: 192.0.2.0/32
|
||||
# url: http://www.example.com/rpz.example.org.zone
|
||||
# rpz-action-override: cname
|
||||
# rpz-cname-override: www.example.org
|
||||
# rpz-log: yes
|
||||
# rpz-log-name: "example policy"
|
||||
# tags: "example"
|
||||
|
||||
+4
-3
@@ -396,12 +396,13 @@ The result of the DNS resolution and validation is returned as
|
||||
char* canonname; /* canonical name of result */
|
||||
int rcode; /* additional error code in case of no data */
|
||||
void* answer_packet; /* full network format answer packet */
|
||||
int answer_len; /* length of packet in octets */
|
||||
int answer_len; /* length of packet in octets */
|
||||
int havedata; /* true if there is data */
|
||||
int nxdomain; /* true if nodata because name does not exist */
|
||||
int secure; /* true if result is secure */
|
||||
int bogus; /* true if a security failure happened */
|
||||
int secure; /* true if result is secure */
|
||||
int bogus; /* true if a security failure happened */
|
||||
char* why_bogus; /* string with error if bogus */
|
||||
int was_ratelimited; /* true if the query was ratelimited (SERVFAIL) by unbound */
|
||||
int ttl; /* number of seconds the result is valid */
|
||||
};
|
||||
.fi
|
||||
|
||||
@@ -323,6 +323,9 @@ serial check). And then the zone is transferred for a newer zone version.
|
||||
.B view_local_data_remove \fIview\fR \fIname
|
||||
\fIlocal_data_remove\fR for given view.
|
||||
.TP
|
||||
.B view_local_datas_remove \fIview\fR
|
||||
Remove a list of \fIlocal_data\fR for given view from stdin. Like local_datas_remove.
|
||||
.TP
|
||||
.B view_local_datas \fIview\fR
|
||||
Add a list of \fIlocal_data\fR for given view from stdin. Like local_datas.
|
||||
.SH "EXIT CODE"
|
||||
@@ -379,8 +382,8 @@ and resulted in recursive processing, taking a slot in the requestlist.
|
||||
Not part of the recursivereplies (or the histogram thereof) or cachemiss,
|
||||
as a cache response was sent.
|
||||
.TP
|
||||
.I threadX.num.zero_ttl
|
||||
number of replies with ttl zero, because they served an expired cache entry.
|
||||
.I threadX.num.expired
|
||||
number of replies that served an expired cache entry.
|
||||
.TP
|
||||
.I threadX.num.recursivereplies
|
||||
The number of replies sent to queries that needed recursive processing. Could be smaller than threadX.num.cachemiss if due to timeouts no replies were sent for some queries.
|
||||
@@ -443,7 +446,7 @@ summed over threads.
|
||||
.I total.num.prefetch
|
||||
summed over threads.
|
||||
.TP
|
||||
.I total.num.zero_ttl
|
||||
.I total.num.expired
|
||||
summed over threads.
|
||||
.TP
|
||||
.I total.num.recursivereplies
|
||||
@@ -660,6 +663,11 @@ Number of queries that got an answer that contained EDNS client subnet data.
|
||||
Number of queries answered from the edns client subnet cache. These are
|
||||
counted as cachemiss by the main counters, but hit the client subnet
|
||||
specific cache, after getting processed by the edns client subnet module.
|
||||
.TP
|
||||
.I num.rpz.action.<rpz_action>
|
||||
Number of queries answered using configured RPZ policy, per RPZ action type.
|
||||
Possible actions are: nxdomain, nodata, passthru, drop, local_data, disabled,
|
||||
and cname_override.
|
||||
.SH "FILES"
|
||||
.TP
|
||||
.I @ub_conf_file@
|
||||
|
||||
+108
-10
@@ -63,8 +63,10 @@ server:
|
||||
access\-control: 2001:DB8::/64 allow
|
||||
.fi
|
||||
.SH "FILE FORMAT"
|
||||
There must be whitespace between keywords. Attribute keywords end with a colon ':'.
|
||||
An attribute is followed by its containing attributes, or a value.
|
||||
There must be whitespace between keywords. Attribute keywords end with a
|
||||
colon ':'. An attribute is followed by a value, or its containing attributes
|
||||
in which case it is referred to as a clause. Clauses can be repeated throughout
|
||||
the file (or included files) to group attributes under the same clause.
|
||||
.P
|
||||
Files can be included using the
|
||||
.B include:
|
||||
@@ -1070,20 +1072,35 @@ The default value is "no".
|
||||
.TP
|
||||
.B serve\-expired: \fI<yes or no>
|
||||
If enabled, unbound attempts to serve old responses from cache with a
|
||||
TTL of 0 in the response without waiting for the actual resolution to finish.
|
||||
The actual resolution answer ends up in the cache later on. Default is "no".
|
||||
TTL of \fBserve\-expired\-reply\-ttl\fR in the response without waiting for the
|
||||
actual resolution to finish. The actual resolution answer ends up in the cache
|
||||
later on. Default is "no".
|
||||
.TP
|
||||
.B serve\-expired\-ttl: \fI<seconds>
|
||||
Limit serving of expired responses to configured seconds after expiration. 0
|
||||
disables the limit. This option only applies when \fBserve\-expired\fR is
|
||||
enabled. The default is 0.
|
||||
disables the limit. This option only applies when \fBserve\-expired\fR is
|
||||
enabled. A suggested value per draft-ietf-dnsop-serve-stale-10 is between
|
||||
86400 (1 day) and 259200 (3 days). The default is 0.
|
||||
.TP
|
||||
.B serve\-expired\-ttl\-reset: \fI<yes or no>
|
||||
Set the TTL of expired records to the \fBserve\-expired\-ttl\fR value after a
|
||||
failed attempt to retrieve the record from upstream. This makes sure that the
|
||||
expired records will be served as long as there are queries for it. Default is
|
||||
failed attempt to retrieve the record from upstream. This makes sure that the
|
||||
expired records will be served as long as there are queries for it. Default is
|
||||
"no".
|
||||
.TP
|
||||
.B serve\-expired\-reply\-ttl: \fI<seconds>
|
||||
TTL value to use when replying with expired data. If
|
||||
\fBserve\-expired\-client\-timeout\fR is also used then it is RECOMMENDED to
|
||||
use 30 as the value (draft-ietf-dnsop-serve-stale-10). The default is 30.
|
||||
.TP
|
||||
.B serve\-expired\-client\-timeout: \fI<msec>
|
||||
Time in milliseconds before replying to the client with expired data. This
|
||||
essentially enables the serve-stale behavior as specified in
|
||||
draft-ietf-dnsop-serve-stale-10 that first tries to resolve before immediately
|
||||
responding with expired data. A recommended value per
|
||||
draft-ietf-dnsop-serve-stale-10 is 1800. Setting this to 0 will disable this
|
||||
behavior. Default is 0.
|
||||
.TP
|
||||
.B val\-nsec3\-keysize\-iterations: \fI<"list of values">
|
||||
List of keysize and iteration count values, separated by spaces, surrounded
|
||||
by quotes. Default is "1024 150 2048 500 4096 2500". This determines the
|
||||
@@ -1296,7 +1313,7 @@ local\-data: "onion. 10800 IN
|
||||
SOA localhost. nobody.invalid. 1 3600 1200 604800 10800"
|
||||
.fi
|
||||
.TP 10
|
||||
\h'5'\fItest (RFC 2606)\fR
|
||||
\h'5'\fItest (RFC 6761)\fR
|
||||
Default content:
|
||||
.nf
|
||||
local\-zone: "test." static
|
||||
@@ -1305,7 +1322,7 @@ local\-data: "test. 10800 IN
|
||||
SOA localhost. nobody.invalid. 1 3600 1200 604800 10800"
|
||||
.fi
|
||||
.TP 10
|
||||
\h'5'\fIinvalid (RFC 2606)\fR
|
||||
\h'5'\fIinvalid (RFC 6761)\fR
|
||||
Default content:
|
||||
.nf
|
||||
local\-zone: "invalid." static
|
||||
@@ -1680,6 +1697,12 @@ Name of the authority zone.
|
||||
Where to download a copy of the zone from, with AXFR and IXFR. Multiple
|
||||
masters can be specified. They are all tried if one fails.
|
||||
With the "ip#name" notation a AXFR over TLS can be used.
|
||||
If you point it at another Unbound instance, it would not work because
|
||||
that does not support AXFR/IXFR for the zone, but if you used \fBurl:\fR to download
|
||||
the zonefile as a text file from a webserver that would work.
|
||||
If you specify the hostname, you cannot use the domain from the zonefile,
|
||||
because it may not have that when retrieving that data, instead use a plain
|
||||
IP address to avoid a circular dependency on retrieving that IP address.
|
||||
.TP
|
||||
.B url: \fI<url to zonefile>
|
||||
Where to download a zonefile for the zone. With http or https. An example
|
||||
@@ -1691,6 +1714,10 @@ see if the SOA serial number has changed, reducing the number of downloads.
|
||||
If none of the urls work, the masters are tried with IXFR and AXFR.
|
||||
For https, the \fBtls\-cert\-bundle\fR and the hostname from the url are used
|
||||
to authenticate the connection.
|
||||
If you specify a hostname in the URL, you cannot use the domain from the
|
||||
zonefile, because it may not have that when retrieving that data, instead
|
||||
use a plain IP address to avoid a circular dependency on retrieving that IP
|
||||
address. Avoid dependencies on name lookups by using a notation like "http://192.0.2.1/unbound-master/example.com.zone", with an explicit IP address.
|
||||
.TP
|
||||
.B allow\-notify: \fI<IP address or host name or netblockIP/prefix>
|
||||
With allow\-notify you can specify additional sources of notifies.
|
||||
@@ -2014,6 +2041,13 @@ to the query without performing iterative DNS resolution.
|
||||
If Unbound cannot even find an answer in the backend, it resolves the
|
||||
query as usual, and stores the answer in the backend.
|
||||
.P
|
||||
This module interacts with the \fBserve\-expired\-*\fR options and will reply
|
||||
with expired data if unbound is configured for that. Currently the use
|
||||
of \fBserve\-expired\-client\-timeout:\fR and
|
||||
\fBserve\-expired\-reply\-ttl:\fR is not consistent for data originating from
|
||||
the external cache as these will result in a reply with 0 TTL without trying to
|
||||
update the data first, ignoring the configured values.
|
||||
.P
|
||||
If Unbound was built with
|
||||
\fB\-\-with\-libhiredis\fR
|
||||
on a system that has installed the hiredis C client library of Redis,
|
||||
@@ -2080,6 +2114,70 @@ If this timeout expires Unbound closes the connection, treats it as
|
||||
if the Redis server does not have the requested data, and will try to
|
||||
re-establish a new connection later.
|
||||
This option defaults to 100 milliseconds.
|
||||
.SS Response Policy Zone Options
|
||||
.LP
|
||||
Response Policy Zones are configured with \fBrpz:\fR, and each one must have a
|
||||
\fBname:\fR. There can be multiple ones, by listing multiple rpz clauses, each
|
||||
with a different name. RPZ clauses are applied in order of configuration. The
|
||||
\fBrespip\fR module needs to be added to the \fBmodule-config\fR, e.g.:
|
||||
\fBmodule-config: "respip validator iterator"\fR.
|
||||
.P
|
||||
Only the QNAME and Response IP Address triggers are supported. The supported RPZ
|
||||
actions are: NXDOMAIN, NODATA, PASSTHRU, DROP and Local Data. RPZ QNAME triggers
|
||||
are applied after
|
||||
\fBlocal-zones\fR and before \fBauth-zones\fR.
|
||||
.TP
|
||||
.B name: \fI<zone name>
|
||||
Name of the authority zone.
|
||||
.TP
|
||||
.B master: \fI<IP address or host name>
|
||||
Where to download a copy of the zone from, with AXFR and IXFR. Multiple
|
||||
masters can be specified. They are all tried if one fails.
|
||||
.TP
|
||||
.B url: \fI<url to zonefile>
|
||||
Where to download a zonefile for the zone. With http or https. An example
|
||||
for the url is "http://www.example.com/example.org.zone". Multiple url
|
||||
statements can be given, they are tried in turn. If only urls are given
|
||||
the SOA refresh timer is used to wait for making new downloads. If also
|
||||
masters are listed, the masters are first probed with UDP SOA queries to
|
||||
see if the SOA serial number has changed, reducing the number of downloads.
|
||||
If none of the urls work, the masters are tried with IXFR and AXFR.
|
||||
For https, the \fBtls\-cert\-bundle\fR and the hostname from the url are used
|
||||
to authenticate the connection.
|
||||
.TP
|
||||
.B allow\-notify: \fI<IP address or host name or netblockIP/prefix>
|
||||
With allow\-notify you can specify additional sources of notifies.
|
||||
When notified, the server attempts to first probe and then zone transfer.
|
||||
If the notify is from a master, it first attempts that master. Otherwise
|
||||
other masters are attempted. If there are no masters, but only urls, the
|
||||
file is downloaded when notified. The masters from master: statements are
|
||||
allowed notify by default.
|
||||
.TP
|
||||
.B zonefile: \fI<filename>
|
||||
The filename where the zone is stored. If not given then no zonefile is used.
|
||||
If the file does not exist or is empty, unbound will attempt to fetch zone
|
||||
data (eg. from the master servers).
|
||||
.TP
|
||||
.B rpz\-action\-override: \fI<action>
|
||||
Always use this RPZ action for matching triggers from this zone. Possible action
|
||||
are: nxdomain, nodata, passthru, drop, disabled and cname.
|
||||
.TP
|
||||
.B rpz\-cname\-override: \fI<domain>
|
||||
The CNAME target domain to use if the cname action is configured for
|
||||
\fBrpz\-action\-override\fR.
|
||||
.TP
|
||||
.B rpz\-log: \fI<yes or no>
|
||||
Log all applied RPZ actions for this RPZ zone. Default is no.
|
||||
.TP
|
||||
.B rpz\-log\-name: \fI<name>
|
||||
Specify a string to be part of the log line, for easy referencing.
|
||||
.TP
|
||||
.B tags: \fI<list of tags>
|
||||
Limit the policies from this RPZ clause to clients with a matching tag. Tags
|
||||
need to be defined in \fBdefine\-tag\fR and can be assigned to client addresses
|
||||
using \fBaccess\-control\-tag\fR. Enclose list of tags in quotes ("") and put
|
||||
spaces between tags. If no tags are specified the policies from this clause will
|
||||
be applied for all clients.
|
||||
.SH "MEMORY CONTROL EXAMPLE"
|
||||
In the example config settings below memory usage is reduced. Some service
|
||||
levels are lower, notable very large data and a high TCP load are no longer
|
||||
|
||||
@@ -431,7 +431,7 @@ lookup_and_reply(struct module_qstate *qstate, int id, struct subnet_qstate *sq)
|
||||
}
|
||||
|
||||
qstate->return_msg = tomsg(NULL, &qstate->qinfo,
|
||||
(struct reply_info *)node->elem, qstate->region, *env->now,
|
||||
(struct reply_info *)node->elem, qstate->region, *env->now, 0,
|
||||
env->scratch);
|
||||
scope = (uint8_t)node->scope;
|
||||
lock_rw_unlock(&e->lock);
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
int
|
||||
context_finalize(struct ub_ctx* ctx)
|
||||
{
|
||||
int is_rpz = 0;
|
||||
struct config_file* cfg = ctx->env->cfg;
|
||||
verbosity = cfg->verbosity;
|
||||
if(ctx_logfile_overridden && !ctx->logfile_override) {
|
||||
@@ -76,7 +77,7 @@ context_finalize(struct ub_ctx* ctx)
|
||||
return UB_NOMEM;
|
||||
if(!local_zones_apply_cfg(ctx->local_zones, cfg))
|
||||
return UB_INITFAIL;
|
||||
if(!auth_zones_apply_cfg(ctx->env->auth_zones, cfg, 1))
|
||||
if(!auth_zones_apply_cfg(ctx->env->auth_zones, cfg, 1, &is_rpz))
|
||||
return UB_INITFAIL;
|
||||
if(!slabhash_is_size(ctx->env->msg_cache, cfg->msg_cache_size,
|
||||
cfg->msg_cache_slabs)) {
|
||||
|
||||
@@ -561,7 +561,6 @@ setup_qinfo_edns(struct libworker* w, struct ctx_query* q,
|
||||
if(!qinfo->qname) {
|
||||
return 0;
|
||||
}
|
||||
qinfo->local_alias = NULL;
|
||||
edns->edns_present = 1;
|
||||
edns->ext_rcode = 0;
|
||||
edns->edns_version = 0;
|
||||
|
||||
@@ -204,8 +204,9 @@ struct ub_result {
|
||||
char* why_bogus;
|
||||
|
||||
/**
|
||||
* If the query or one of its subqueries was ratelimited. Useful if
|
||||
* ratelimiting is enabled and answer is SERVFAIL.
|
||||
* If the query or one of its subqueries was ratelimited. Useful if
|
||||
* ratelimiting is enabled and answer to the client is SERVFAIL as a
|
||||
* result.
|
||||
*/
|
||||
int was_ratelimited;
|
||||
|
||||
@@ -654,6 +655,8 @@ struct ub_shm_stat_info {
|
||||
#define UB_STATS_OPCODE_NUM 16
|
||||
/** number of histogram buckets */
|
||||
#define UB_STATS_BUCKET_NUM 40
|
||||
/** number of RPZ actions */
|
||||
#define UB_STATS_RPZ_ACTION_NUM 10
|
||||
|
||||
/** per worker statistics. */
|
||||
struct ub_server_stats {
|
||||
@@ -733,8 +736,8 @@ struct ub_server_stats {
|
||||
long long unwanted_queries;
|
||||
/** usage of tcp accept list */
|
||||
long long tcp_accept_usage;
|
||||
/** answers served from expired cache */
|
||||
long long zero_ttl_responses;
|
||||
/** expired answers served from cache */
|
||||
long long ans_expired;
|
||||
/** histogram data exported to array
|
||||
* if the array is the same size, no data is lost, and
|
||||
* if all histograms are same size (is so by default) then
|
||||
@@ -785,6 +788,8 @@ struct ub_server_stats {
|
||||
long long mem_stream_wait;
|
||||
/** number of TLS connection resume */
|
||||
long long qtls_resume;
|
||||
/** RPZ action stats */
|
||||
long long rpz_action[UB_STATS_RPZ_ACTION_NUM];
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
+230
-101
@@ -12,6 +12,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "services/localzone.h"
|
||||
#include "services/authzone.h"
|
||||
#include "services/cache/dns.h"
|
||||
#include "sldns/str2wire.h"
|
||||
#include "util/config_file.h"
|
||||
@@ -25,30 +26,6 @@
|
||||
#include "services/view.h"
|
||||
#include "sldns/rrdef.h"
|
||||
|
||||
/**
|
||||
* Conceptual set of IP addresses for response AAAA or A records that should
|
||||
* trigger special actions.
|
||||
*/
|
||||
struct respip_set {
|
||||
struct regional* region;
|
||||
struct rbtree_type ip_tree;
|
||||
char* const* tagname; /* shallow copy of tag names, for logging */
|
||||
int num_tags; /* number of tagname entries */
|
||||
};
|
||||
|
||||
/** An address span with response control information */
|
||||
struct resp_addr {
|
||||
/** node in address tree */
|
||||
struct addr_tree_node node;
|
||||
/** tag bitlist */
|
||||
uint8_t* taglist;
|
||||
/** length of the taglist (in bytes) */
|
||||
size_t taglen;
|
||||
/** action for this address span */
|
||||
enum respip_action action;
|
||||
/** "local data" for this node */
|
||||
struct ub_packed_rrset_key* data;
|
||||
};
|
||||
|
||||
/** Subset of resp_addr.node, used for inform-variant logging */
|
||||
struct respip_addr_info {
|
||||
@@ -88,14 +65,28 @@ respip_set_create(void)
|
||||
return NULL;
|
||||
}
|
||||
addr_tree_init(&set->ip_tree);
|
||||
lock_rw_init(&set->lock);
|
||||
return set;
|
||||
}
|
||||
|
||||
/** helper traverse to delete resp_addr nodes */
|
||||
static void
|
||||
resp_addr_del(rbnode_type* n, void* ATTR_UNUSED(arg))
|
||||
{
|
||||
struct resp_addr* r = (struct resp_addr*)n->key;
|
||||
lock_rw_destroy(&r->lock);
|
||||
#ifdef THREADS_DISABLED
|
||||
(void)r;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
respip_set_delete(struct respip_set* set)
|
||||
{
|
||||
if(!set)
|
||||
return;
|
||||
lock_rw_destroy(&set->lock);
|
||||
traverse_postorder(&set->ip_tree, resp_addr_del, NULL);
|
||||
regional_destroy(set->region);
|
||||
free(set);
|
||||
}
|
||||
@@ -108,12 +99,49 @@ respip_set_get_tree(struct respip_set* set)
|
||||
return &set->ip_tree;
|
||||
}
|
||||
|
||||
struct resp_addr*
|
||||
respip_sockaddr_find_or_create(struct respip_set* set, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, int net, int create, const char* ipstr)
|
||||
{
|
||||
struct resp_addr* node;
|
||||
node = (struct resp_addr*)addr_tree_find(&set->ip_tree, addr, addrlen, net);
|
||||
if(!node && create) {
|
||||
node = regional_alloc_zero(set->region, sizeof(*node));
|
||||
if(!node) {
|
||||
log_err("out of memory");
|
||||
return NULL;
|
||||
}
|
||||
lock_rw_init(&node->lock);
|
||||
node->action = respip_none;
|
||||
if(!addr_tree_insert(&set->ip_tree, &node->node, addr,
|
||||
addrlen, net)) {
|
||||
/* We know we didn't find it, so this should be
|
||||
* impossible. */
|
||||
log_warn("unexpected: duplicate address: %s", ipstr);
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
void
|
||||
respip_sockaddr_delete(struct respip_set* set, struct resp_addr* node)
|
||||
{
|
||||
struct resp_addr* prev;
|
||||
prev = (struct resp_addr*)rbtree_previous((struct rbnode_type*)node);
|
||||
lock_rw_destroy(&node->lock);
|
||||
rbtree_delete(&set->ip_tree, node);
|
||||
/* no free'ing, all allocated in region */
|
||||
if(!prev)
|
||||
addr_tree_init_parents((rbtree_type*)set);
|
||||
else
|
||||
addr_tree_init_parents_node(&prev->node);
|
||||
}
|
||||
|
||||
/** returns the node in the address tree for the specified netblock string;
|
||||
* non-existent node will be created if 'create' is true */
|
||||
static struct resp_addr*
|
||||
respip_find_or_create(struct respip_set* set, const char* ipstr, int create)
|
||||
{
|
||||
struct resp_addr* node;
|
||||
struct sockaddr_storage addr;
|
||||
int net;
|
||||
socklen_t addrlen;
|
||||
@@ -122,22 +150,8 @@ respip_find_or_create(struct respip_set* set, const char* ipstr, int create)
|
||||
log_err("cannot parse netblock: '%s'", ipstr);
|
||||
return NULL;
|
||||
}
|
||||
node = (struct resp_addr*)addr_tree_find(&set->ip_tree, &addr, addrlen, net);
|
||||
if(!node && create) {
|
||||
node = regional_alloc_zero(set->region, sizeof(*node));
|
||||
if(!node) {
|
||||
log_err("out of memory");
|
||||
return NULL;
|
||||
}
|
||||
node->action = respip_none;
|
||||
if(!addr_tree_insert(&set->ip_tree, &node->node, &addr,
|
||||
addrlen, net)) {
|
||||
/* We know we didn't find it, so this should be
|
||||
* impossible. */
|
||||
log_warn("unexpected: duplicate address: %s", ipstr);
|
||||
}
|
||||
}
|
||||
return node;
|
||||
return respip_sockaddr_find_or_create(set, &addr, addrlen, net, create,
|
||||
ipstr);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -191,6 +205,10 @@ respip_action_cfg(struct respip_set* set, const char* ipstr,
|
||||
action = respip_always_refuse;
|
||||
else if(strcmp(actnstr, "always_nxdomain") == 0)
|
||||
action = respip_always_nxdomain;
|
||||
else if(strcmp(actnstr, "always_nodata") == 0)
|
||||
action = respip_always_nodata;
|
||||
else if(strcmp(actnstr, "always_deny") == 0)
|
||||
action = respip_always_deny;
|
||||
else {
|
||||
log_err("unknown response-ip action %s", actnstr);
|
||||
return 0;
|
||||
@@ -232,8 +250,43 @@ new_rrset(struct regional* region, uint16_t rrtype, uint16_t rrclass)
|
||||
}
|
||||
|
||||
/** enter local data as resource records into a response-ip node */
|
||||
static int
|
||||
|
||||
int
|
||||
respip_enter_rr(struct regional* region, struct resp_addr* raddr,
|
||||
uint16_t rrtype, uint16_t rrclass, time_t ttl, uint8_t* rdata,
|
||||
size_t rdata_len, const char* rrstr, const char* netblockstr)
|
||||
{
|
||||
struct packed_rrset_data* pd;
|
||||
struct sockaddr* sa;
|
||||
sa = (struct sockaddr*)&raddr->node.addr;
|
||||
if (rrtype == LDNS_RR_TYPE_CNAME && raddr->data) {
|
||||
log_err("CNAME response-ip data (%s) can not co-exist with other "
|
||||
"response-ip data for netblock %s", rrstr, netblockstr);
|
||||
return 0;
|
||||
} else if (raddr->data &&
|
||||
raddr->data->rk.type == htons(LDNS_RR_TYPE_CNAME)) {
|
||||
log_err("response-ip data (%s) can not be added; CNAME response-ip "
|
||||
"data already in place for netblock %s", rrstr, netblockstr);
|
||||
return 0;
|
||||
} else if((rrtype != LDNS_RR_TYPE_CNAME) &&
|
||||
((sa->sa_family == AF_INET && rrtype != LDNS_RR_TYPE_A) ||
|
||||
(sa->sa_family == AF_INET6 && rrtype != LDNS_RR_TYPE_AAAA))) {
|
||||
log_err("response-ip data %s record type does not correspond "
|
||||
"to netblock %s address family", rrstr, netblockstr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(!raddr->data) {
|
||||
raddr->data = new_rrset(region, rrtype, rrclass);
|
||||
if(!raddr->data)
|
||||
return 0;
|
||||
}
|
||||
pd = raddr->data->entry.data;
|
||||
return rrset_insert_rr(region, pd, rdata, rdata_len, ttl, rrstr);
|
||||
}
|
||||
|
||||
static int
|
||||
respip_enter_rrstr(struct regional* region, struct resp_addr* raddr,
|
||||
const char* rrstr, const char* netblock)
|
||||
{
|
||||
uint8_t* nm;
|
||||
@@ -244,8 +297,6 @@ respip_enter_rr(struct regional* region, struct resp_addr* raddr,
|
||||
size_t rdata_len = 0;
|
||||
char buf[65536];
|
||||
char bufshort[64];
|
||||
struct packed_rrset_data* pd;
|
||||
struct sockaddr* sa;
|
||||
int ret;
|
||||
if(raddr->action != respip_redirect
|
||||
&& raddr->action != respip_inform_redirect) {
|
||||
@@ -265,31 +316,8 @@ respip_enter_rr(struct regional* region, struct resp_addr* raddr,
|
||||
return 0;
|
||||
}
|
||||
free(nm);
|
||||
sa = (struct sockaddr*)&raddr->node.addr;
|
||||
if (rrtype == LDNS_RR_TYPE_CNAME && raddr->data) {
|
||||
log_err("CNAME response-ip data (%s) can not co-exist with other "
|
||||
"response-ip data for netblock %s", rrstr, netblock);
|
||||
return 0;
|
||||
} else if (raddr->data &&
|
||||
raddr->data->rk.type == htons(LDNS_RR_TYPE_CNAME)) {
|
||||
log_err("response-ip data (%s) can not be added; CNAME response-ip "
|
||||
"data already in place for netblock %s", rrstr, netblock);
|
||||
return 0;
|
||||
} else if((rrtype != LDNS_RR_TYPE_CNAME) &&
|
||||
((sa->sa_family == AF_INET && rrtype != LDNS_RR_TYPE_A) ||
|
||||
(sa->sa_family == AF_INET6 && rrtype != LDNS_RR_TYPE_AAAA))) {
|
||||
log_err("response-ip data %s record type does not correspond "
|
||||
"to netblock %s address family", rrstr, netblock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(!raddr->data) {
|
||||
raddr->data = new_rrset(region, rrtype, rrclass);
|
||||
if(!raddr->data)
|
||||
return 0;
|
||||
}
|
||||
pd = raddr->data->entry.data;
|
||||
return rrset_insert_rr(region, pd, rdata, rdata_len, ttl, rrstr);
|
||||
return respip_enter_rr(region, raddr, rrtype, rrclass, ttl, rdata,
|
||||
rdata_len, rrstr, netblock);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -303,7 +331,7 @@ respip_data_cfg(struct respip_set* set, const char* ipstr, const char* rrstr)
|
||||
"response-ip node for %s not found", rrstr, ipstr);
|
||||
return 0;
|
||||
}
|
||||
return respip_enter_rr(set->region, node, rrstr, ipstr);
|
||||
return respip_enter_rrstr(set->region, node, rrstr, ipstr);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -564,9 +592,10 @@ rdata2sockaddr(const struct packed_rrset_data* rd, uint16_t rtype, size_t i,
|
||||
* rep->rrsets for the RRset that contains the matching IP address record
|
||||
* (the index is normally 0, but can be larger than that if this is a CNAME
|
||||
* chain or type-ANY response).
|
||||
* Returns resp_addr holding read lock.
|
||||
*/
|
||||
static const struct resp_addr*
|
||||
respip_addr_lookup(const struct reply_info *rep, struct rbtree_type* iptree,
|
||||
static struct resp_addr*
|
||||
respip_addr_lookup(const struct reply_info *rep, struct respip_set* rs,
|
||||
size_t* rrset_id)
|
||||
{
|
||||
size_t i;
|
||||
@@ -574,6 +603,7 @@ respip_addr_lookup(const struct reply_info *rep, struct rbtree_type* iptree,
|
||||
struct sockaddr_storage ss;
|
||||
socklen_t addrlen;
|
||||
|
||||
lock_rw_rdlock(&rs->lock);
|
||||
for(i=0; i<rep->an_numrrsets; i++) {
|
||||
size_t j;
|
||||
const struct packed_rrset_data* rd;
|
||||
@@ -585,15 +615,17 @@ respip_addr_lookup(const struct reply_info *rep, struct rbtree_type* iptree,
|
||||
for(j = 0; j < rd->count; j++) {
|
||||
if(!rdata2sockaddr(rd, rtype, j, &ss, &addrlen))
|
||||
continue;
|
||||
ra = (struct resp_addr*)addr_tree_lookup(iptree, &ss,
|
||||
addrlen);
|
||||
ra = (struct resp_addr*)addr_tree_lookup(&rs->ip_tree,
|
||||
&ss, addrlen);
|
||||
if(ra) {
|
||||
*rrset_id = i;
|
||||
lock_rw_rdlock(&ra->lock);
|
||||
lock_rw_unlock(&rs->lock);
|
||||
return ra;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lock_rw_unlock(&rs->lock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -642,8 +674,8 @@ make_new_reply_info(const struct reply_info* rep, struct regional* region,
|
||||
* Note that this function distinguishes error conditions from "success but
|
||||
* not overridden". This is because we want to avoid accidentally applying
|
||||
* the "no data" action in case of error.
|
||||
* @param raddr: address span that requires an action
|
||||
* @param action: action to apply
|
||||
* @param data: RRset to use for override
|
||||
* @param qtype: original query type
|
||||
* @param rep: original reply message
|
||||
* @param rrset_id: the rrset ID in 'rep' to which the action should apply
|
||||
@@ -658,14 +690,15 @@ make_new_reply_info(const struct reply_info* rep, struct regional* region,
|
||||
* @return 1 if overridden, 0 if not overridden, -1 on error.
|
||||
*/
|
||||
static int
|
||||
respip_data_answer(const struct resp_addr* raddr, enum respip_action action,
|
||||
respip_data_answer(enum respip_action action,
|
||||
struct ub_packed_rrset_key* data,
|
||||
uint16_t qtype, const struct reply_info* rep,
|
||||
size_t rrset_id, struct reply_info** new_repp, int tag,
|
||||
struct config_strlist** tag_datas, size_t tag_datas_size,
|
||||
char* const* tagname, int num_tags,
|
||||
struct ub_packed_rrset_key** redirect_rrsetp, struct regional* region)
|
||||
{
|
||||
struct ub_packed_rrset_key* rp = raddr->data;
|
||||
struct ub_packed_rrset_key* rp = data;
|
||||
struct reply_info* new_rep;
|
||||
*redirect_rrsetp = NULL;
|
||||
|
||||
@@ -703,7 +736,7 @@ respip_data_answer(const struct resp_addr* raddr, enum respip_action action,
|
||||
* to replace the rrset's dname. Note that, unlike local data, we
|
||||
* rename the dname for other actions than redirect. This is because
|
||||
* response-ip-data isn't associated to any specific name. */
|
||||
if(rp == raddr->data) {
|
||||
if(rp == data) {
|
||||
rp = copy_rrset(rp, region);
|
||||
if(!rp)
|
||||
return -1;
|
||||
@@ -761,6 +794,7 @@ respip_nodata_answer(uint16_t qtype, enum respip_action action,
|
||||
return 1;
|
||||
} else if(action == respip_static || action == respip_redirect ||
|
||||
action == respip_always_nxdomain ||
|
||||
action == respip_always_nodata ||
|
||||
action == respip_inform_redirect) {
|
||||
/* Since we don't know about other types of the owner name,
|
||||
* we generally return NOERROR/NODATA unless an NXDOMAIN action
|
||||
@@ -794,16 +828,22 @@ populate_action_info(struct respip_action_info* actinfo,
|
||||
enum respip_action action, const struct resp_addr* raddr,
|
||||
const struct ub_packed_rrset_key* ATTR_UNUSED(rrset),
|
||||
int ATTR_UNUSED(tag), const struct respip_set* ATTR_UNUSED(ipset),
|
||||
int ATTR_UNUSED(action_only), struct regional* region)
|
||||
int ATTR_UNUSED(action_only), struct regional* region, int rpz_used,
|
||||
int rpz_log, char* log_name, int rpz_cname_override)
|
||||
{
|
||||
if(action == respip_none || !raddr)
|
||||
return 1;
|
||||
actinfo->action = action;
|
||||
actinfo->rpz_used = rpz_used;
|
||||
actinfo->rpz_log = rpz_log;
|
||||
actinfo->log_name = log_name;
|
||||
actinfo->rpz_cname_override = rpz_cname_override;
|
||||
|
||||
/* for inform variants, make a copy of the matched address block for
|
||||
* later logging. We make a copy to proactively avoid disruption if
|
||||
* and when we allow a dynamic update to the respip tree. */
|
||||
if(action == respip_inform || action == respip_inform_deny) {
|
||||
if(action == respip_inform || action == respip_inform_deny ||
|
||||
rpz_used) {
|
||||
struct respip_addr_info* a =
|
||||
regional_alloc_zero(region, sizeof(*a));
|
||||
if(!a) {
|
||||
@@ -819,12 +859,39 @@ populate_action_info(struct respip_action_info* actinfo,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
respip_use_rpz(struct resp_addr* raddr, struct rpz* r,
|
||||
enum respip_action* action,
|
||||
struct ub_packed_rrset_key** data, int* rpz_log, char** log_name,
|
||||
int* rpz_cname_override, struct regional* region, int* is_rpz)
|
||||
{
|
||||
if(r->action_override == RPZ_DISABLED_ACTION) {
|
||||
*is_rpz = 0;
|
||||
return 1;
|
||||
}
|
||||
else if(r->action_override == RPZ_NO_OVERRIDE_ACTION)
|
||||
*action = raddr->action;
|
||||
else
|
||||
*action = rpz_action_to_respip_action(r->action_override);
|
||||
if(r->action_override == RPZ_CNAME_OVERRIDE_ACTION &&
|
||||
r->cname_override) {
|
||||
*data = r->cname_override;
|
||||
*rpz_cname_override = 1;
|
||||
}
|
||||
*rpz_log = r->log;
|
||||
if(r->log_name)
|
||||
if(!(*log_name = regional_strdup(region, r->log_name)))
|
||||
return 0;
|
||||
*is_rpz = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
respip_rewrite_reply(const struct query_info* qinfo,
|
||||
const struct respip_client_info* cinfo, const struct reply_info* rep,
|
||||
struct reply_info** new_repp, struct respip_action_info* actinfo,
|
||||
struct ub_packed_rrset_key** alias_rrset, int search_only,
|
||||
struct regional* region)
|
||||
struct regional* region, struct auth_zones* az)
|
||||
{
|
||||
const uint8_t* ctaglist;
|
||||
size_t ctaglen;
|
||||
@@ -837,9 +904,15 @@ respip_rewrite_reply(const struct query_info* qinfo,
|
||||
size_t rrset_id = 0;
|
||||
enum respip_action action = respip_none;
|
||||
int tag = -1;
|
||||
const struct resp_addr* raddr = NULL;
|
||||
struct resp_addr* raddr = NULL;
|
||||
int ret = 1;
|
||||
struct ub_packed_rrset_key* redirect_rrset = NULL;
|
||||
struct rpz* r;
|
||||
struct ub_packed_rrset_key* data = NULL;
|
||||
int rpz_used = 0;
|
||||
int rpz_log = 0;
|
||||
int rpz_cname_override = 0;
|
||||
char* log_name = NULL;
|
||||
|
||||
if(!cinfo)
|
||||
goto done;
|
||||
@@ -852,6 +925,8 @@ respip_rewrite_reply(const struct query_info* qinfo,
|
||||
view = cinfo->view;
|
||||
ipset = cinfo->respip_set;
|
||||
|
||||
log_assert(ipset);
|
||||
|
||||
/** Try to use response-ip config from the view first; use
|
||||
* global response-ip config if we don't have the view or we don't
|
||||
* have the matching per-view config (and the view allows the use
|
||||
@@ -866,7 +941,7 @@ respip_rewrite_reply(const struct query_info* qinfo,
|
||||
lock_rw_rdlock(&view->lock);
|
||||
if(view->respip_set) {
|
||||
if((raddr = respip_addr_lookup(rep,
|
||||
&view->respip_set->ip_tree, &rrset_id))) {
|
||||
view->respip_set, &rrset_id))) {
|
||||
/** for per-view respip directives the action
|
||||
* can only be direct (i.e. not tag-based) */
|
||||
action = raddr->action;
|
||||
@@ -875,7 +950,7 @@ respip_rewrite_reply(const struct query_info* qinfo,
|
||||
if(!raddr && !view->isfirst)
|
||||
goto done;
|
||||
}
|
||||
if(!raddr && ipset && (raddr = respip_addr_lookup(rep, &ipset->ip_tree,
|
||||
if(!raddr && (raddr = respip_addr_lookup(rep, ipset,
|
||||
&rrset_id))) {
|
||||
action = (enum respip_action)local_data_find_tag_action(
|
||||
raddr->taglist, raddr->taglen, ctaglist, ctaglen,
|
||||
@@ -883,6 +958,29 @@ respip_rewrite_reply(const struct query_info* qinfo,
|
||||
(enum localzone_type)raddr->action, &tag,
|
||||
ipset->tagname, ipset->num_tags);
|
||||
}
|
||||
lock_rw_rdlock(&az->rpz_lock);
|
||||
for(r = az->rpz_first; r && !raddr; r = r->next) {
|
||||
if(!r->taglist || taglist_intersect(r->taglist,
|
||||
r->taglistlen, ctaglist, ctaglen)) {
|
||||
if((raddr = respip_addr_lookup(rep,
|
||||
r->respip_set, &rrset_id))) {
|
||||
if(!respip_use_rpz(raddr, r, &action, &data,
|
||||
&rpz_log, &log_name, &rpz_cname_override,
|
||||
region, &rpz_used)) {
|
||||
log_err("out of memory");
|
||||
lock_rw_unlock(&raddr->lock);
|
||||
lock_rw_unlock(&az->rpz_lock);
|
||||
return 0;
|
||||
}
|
||||
if(!rpz_used) {
|
||||
lock_rw_unlock(&raddr->lock);
|
||||
raddr = NULL;
|
||||
actinfo->rpz_disabled++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
lock_rw_unlock(&az->rpz_lock);
|
||||
if(raddr && !search_only) {
|
||||
int result = 0;
|
||||
|
||||
@@ -891,10 +989,13 @@ respip_rewrite_reply(const struct query_info* qinfo,
|
||||
if(action != respip_always_refuse
|
||||
&& action != respip_always_transparent
|
||||
&& action != respip_always_nxdomain
|
||||
&& (result = respip_data_answer(raddr, action,
|
||||
qinfo->qtype, rep, rrset_id, new_repp, tag, tag_datas,
|
||||
tag_datas_size, ipset->tagname, ipset->num_tags,
|
||||
&redirect_rrset, region)) < 0) {
|
||||
&& action != respip_always_nodata
|
||||
&& action != respip_always_deny
|
||||
&& (result = respip_data_answer(action,
|
||||
(data) ? data : raddr->data, qinfo->qtype, rep,
|
||||
rrset_id, new_repp, tag, tag_datas, tag_datas_size,
|
||||
ipset->tagname, ipset->num_tags, &redirect_rrset,
|
||||
region)) < 0) {
|
||||
ret = 0;
|
||||
goto done;
|
||||
}
|
||||
@@ -925,7 +1026,11 @@ respip_rewrite_reply(const struct query_info* qinfo,
|
||||
*alias_rrset = redirect_rrset;
|
||||
/* on success, populate respip result structure */
|
||||
ret = populate_action_info(actinfo, action, raddr,
|
||||
redirect_rrset, tag, ipset, search_only, region);
|
||||
redirect_rrset, tag, ipset, search_only, region,
|
||||
rpz_used, rpz_log, log_name, rpz_cname_override);
|
||||
}
|
||||
if(raddr) {
|
||||
lock_rw_unlock(&raddr->lock);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -981,14 +1086,15 @@ respip_operate(struct module_qstate* qstate, enum module_ev event, int id,
|
||||
qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA ||
|
||||
qstate->qinfo.qtype == LDNS_RR_TYPE_ANY) &&
|
||||
qstate->return_msg && qstate->return_msg->rep) {
|
||||
struct respip_action_info actinfo = {respip_none, NULL};
|
||||
struct reply_info* new_rep = qstate->return_msg->rep;
|
||||
struct ub_packed_rrset_key* alias_rrset = NULL;
|
||||
struct respip_action_info actinfo = {0};
|
||||
actinfo.action = respip_none;
|
||||
|
||||
if(!respip_rewrite_reply(&qstate->qinfo,
|
||||
qstate->client_info, qstate->return_msg->rep,
|
||||
&new_rep, &actinfo, &alias_rrset, 0,
|
||||
qstate->region)) {
|
||||
qstate->region, qstate->env->auth_zones)) {
|
||||
goto servfail;
|
||||
}
|
||||
if(actinfo.action != respip_none) {
|
||||
@@ -1004,9 +1110,10 @@ respip_operate(struct module_qstate* qstate, enum module_ev event, int id,
|
||||
} else {
|
||||
qstate->respip_action_info = NULL;
|
||||
}
|
||||
if (new_rep == qstate->return_msg->rep &&
|
||||
if (actinfo.action == respip_always_deny ||
|
||||
(new_rep == qstate->return_msg->rep &&
|
||||
(actinfo.action == respip_deny ||
|
||||
actinfo.action == respip_inform_deny)) {
|
||||
actinfo.action == respip_inform_deny))) {
|
||||
/* for deny-variant actions (unless response-ip
|
||||
* data is applied), mark the query state so
|
||||
* the response will be dropped for all
|
||||
@@ -1034,14 +1141,16 @@ int
|
||||
respip_merge_cname(struct reply_info* base_rep,
|
||||
const struct query_info* qinfo, const struct reply_info* tgt_rep,
|
||||
const struct respip_client_info* cinfo, int must_validate,
|
||||
struct reply_info** new_repp, struct regional* region)
|
||||
struct reply_info** new_repp, struct regional* region,
|
||||
struct auth_zones* az)
|
||||
{
|
||||
struct reply_info* new_rep;
|
||||
struct reply_info* tmp_rep = NULL; /* just a placeholder */
|
||||
struct ub_packed_rrset_key* alias_rrset = NULL; /* ditto */
|
||||
uint16_t tgt_rcode;
|
||||
size_t i, j;
|
||||
struct respip_action_info actinfo = {respip_none, NULL};
|
||||
struct respip_action_info actinfo = {0};
|
||||
actinfo.action = respip_none;
|
||||
|
||||
/* If the query for the CNAME target would result in an unusual rcode,
|
||||
* we generally translate it as a failure for the base query
|
||||
@@ -1060,7 +1169,7 @@ respip_merge_cname(struct reply_info* base_rep,
|
||||
|
||||
/* see if the target reply would be subject to a response-ip action. */
|
||||
if(!respip_rewrite_reply(qinfo, cinfo, tgt_rep, &tmp_rep, &actinfo,
|
||||
&alias_rrset, 1, region))
|
||||
&alias_rrset, 1, region, az))
|
||||
return 0;
|
||||
if(actinfo.action != respip_none) {
|
||||
log_info("CNAME target of redirect response-ip action would "
|
||||
@@ -1112,7 +1221,8 @@ respip_inform_super(struct module_qstate* qstate, int id,
|
||||
|
||||
if(!respip_merge_cname(super->return_msg->rep, &qstate->qinfo,
|
||||
qstate->return_msg->rep, super->client_info,
|
||||
super->env->need_to_validate, &new_rep, super->region))
|
||||
super->env->need_to_validate, &new_rep, super->region,
|
||||
qstate->env->auth_zones))
|
||||
goto fail;
|
||||
super->return_msg->rep = new_rep;
|
||||
return;
|
||||
@@ -1171,12 +1281,15 @@ respip_set_is_empty(const struct respip_set* set)
|
||||
}
|
||||
|
||||
void
|
||||
respip_inform_print(struct respip_addr_info* respip_addr, uint8_t* qname,
|
||||
respip_inform_print(struct respip_action_info* respip_actinfo, uint8_t* qname,
|
||||
uint16_t qtype, uint16_t qclass, struct local_rrset* local_alias,
|
||||
struct comm_reply* repinfo)
|
||||
{
|
||||
char srcip[128], respip[128], txt[512];
|
||||
unsigned port;
|
||||
struct respip_addr_info* respip_addr = respip_actinfo->addrinfo;
|
||||
size_t txtlen = 0;
|
||||
const char* actionstr = NULL;
|
||||
|
||||
if(local_alias)
|
||||
qname = local_alias->rrset->rk.dname;
|
||||
@@ -1186,7 +1299,23 @@ respip_inform_print(struct respip_addr_info* respip_addr, uint8_t* qname,
|
||||
addr_to_str(&repinfo->addr, repinfo->addrlen, srcip, sizeof(srcip));
|
||||
addr_to_str(&respip_addr->addr, respip_addr->addrlen,
|
||||
respip, sizeof(respip));
|
||||
snprintf(txt, sizeof(txt), "%s/%d inform %s@%u", respip,
|
||||
respip_addr->net, srcip, port);
|
||||
if(respip_actinfo->rpz_log) {
|
||||
txtlen += snprintf(txt+txtlen, sizeof(txt)-txtlen, "%s",
|
||||
"RPZ applied ");
|
||||
if(respip_actinfo->rpz_cname_override)
|
||||
actionstr = rpz_action_to_string(
|
||||
RPZ_CNAME_OVERRIDE_ACTION);
|
||||
else
|
||||
actionstr = rpz_action_to_string(
|
||||
respip_action_to_rpz_action(
|
||||
respip_actinfo->action));
|
||||
}
|
||||
if(respip_actinfo->log_name) {
|
||||
txtlen += snprintf(txt+txtlen, sizeof(txt)-txtlen,
|
||||
"[%s] ", respip_actinfo->log_name);
|
||||
}
|
||||
snprintf(txt+txtlen, sizeof(txt)-txtlen,
|
||||
"%s/%d %s %s@%u", respip, respip_addr->net,
|
||||
(actionstr) ? actionstr : "inform", srcip, port);
|
||||
log_nametypeclass(NO_VERBOSE, txt, qname, qtype, qclass);
|
||||
}
|
||||
|
||||
+82
-15
@@ -14,23 +14,42 @@
|
||||
|
||||
#include "util/module.h"
|
||||
#include "services/localzone.h"
|
||||
#include "util/locks.h"
|
||||
|
||||
/**
|
||||
* Set of response IP addresses with associated actions and tags.
|
||||
* Forward declaration only here. Actual definition is hidden within the
|
||||
* module.
|
||||
* Conceptual set of IP addresses for response AAAA or A records that should
|
||||
* trigger special actions.
|
||||
*/
|
||||
struct respip_set;
|
||||
struct respip_set {
|
||||
struct regional* region;
|
||||
struct rbtree_type ip_tree;
|
||||
lock_rw_type lock; /* lock on the respip tree */
|
||||
char* const* tagname; /* shallow copy of tag names, for logging */
|
||||
int num_tags; /* number of tagname entries */
|
||||
};
|
||||
|
||||
|
||||
/** An address span with response control information */
|
||||
struct resp_addr {
|
||||
/** node in address tree */
|
||||
struct addr_tree_node node;
|
||||
/** lock on the node item */
|
||||
lock_rw_type lock;
|
||||
/** tag bitlist */
|
||||
uint8_t* taglist;
|
||||
/** length of the taglist (in bytes) */
|
||||
size_t taglen;
|
||||
/** action for this address span */
|
||||
enum respip_action action;
|
||||
/** "local data" for this node */
|
||||
struct ub_packed_rrset_key* data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Forward declaration for the structure that represents a node in the
|
||||
* respip_set address tree
|
||||
*/
|
||||
struct resp_addr;
|
||||
|
||||
/**
|
||||
* Forward declaration for the structure that represents a tree of view data.
|
||||
*/
|
||||
|
||||
struct views;
|
||||
|
||||
struct respip_addr_info;
|
||||
@@ -60,6 +79,11 @@ struct respip_client_info {
|
||||
*/
|
||||
struct respip_action_info {
|
||||
enum respip_action action;
|
||||
int rpz_used;
|
||||
int rpz_log;
|
||||
int rpz_disabled;
|
||||
char* log_name;
|
||||
int rpz_cname_override;
|
||||
struct respip_addr_info* addrinfo; /* set only for inform variants */
|
||||
};
|
||||
|
||||
@@ -124,12 +148,14 @@ int respip_views_apply_cfg(struct views* vs, struct config_file* cfg,
|
||||
* @param new_repp: pointer placeholder for the merged reply. will be intact
|
||||
* on error.
|
||||
* @param region: allocator to build *new_repp.
|
||||
* @param az: auth zones containing RPZ information.
|
||||
* @return 1 on success, 0 on error.
|
||||
*/
|
||||
int respip_merge_cname(struct reply_info* base_rep,
|
||||
const struct query_info* qinfo, const struct reply_info* tgt_rep,
|
||||
const struct respip_client_info* cinfo, int must_validate,
|
||||
struct reply_info** new_repp, struct regional* region);
|
||||
struct reply_info** new_repp, struct regional* region,
|
||||
struct auth_zones* az);
|
||||
|
||||
/**
|
||||
* See if any IP-based action should apply to any IP address of AAAA/A answer
|
||||
@@ -148,6 +174,7 @@ int respip_merge_cname(struct reply_info* base_rep,
|
||||
* @param alias_rrset: must not be NULL.
|
||||
* @param search_only: if true, only check if an action would apply. actionp
|
||||
* will be set (or intact) accordingly but the modified reply won't be built.
|
||||
* @param az: auth zones containing RPZ information.
|
||||
* @param region: allocator to build *new_repp.
|
||||
* @return 1 on success, 0 on error.
|
||||
*/
|
||||
@@ -156,7 +183,7 @@ int respip_rewrite_reply(const struct query_info* qinfo,
|
||||
const struct reply_info *rep, struct reply_info** new_repp,
|
||||
struct respip_action_info* actinfo,
|
||||
struct ub_packed_rrset_key** alias_rrset,
|
||||
int search_only, struct regional* region);
|
||||
int search_only, struct regional* region, struct auth_zones* az);
|
||||
|
||||
/**
|
||||
* Get the response-ip function block.
|
||||
@@ -213,7 +240,7 @@ int respip_set_is_empty(const struct respip_set* set);
|
||||
/**
|
||||
* print log information for a query subject to an inform or inform-deny
|
||||
* response-ip action.
|
||||
* @param respip_addr: response-ip information that causes the action
|
||||
* @param respip_actinfo: response-ip information that causes the action
|
||||
* @param qname: query name in the context, will be ignored if local_alias is
|
||||
* non-NULL.
|
||||
* @param qtype: query type, in host byte order.
|
||||
@@ -223,8 +250,48 @@ int respip_set_is_empty(const struct respip_set* set);
|
||||
* query name.
|
||||
* @param repinfo: reply info containing the client's source address and port.
|
||||
*/
|
||||
void respip_inform_print(struct respip_addr_info* respip_addr, uint8_t* qname,
|
||||
uint16_t qtype, uint16_t qclass, struct local_rrset* local_alias,
|
||||
struct comm_reply* repinfo);
|
||||
void respip_inform_print(struct respip_action_info* respip_actinfo,
|
||||
uint8_t* qname, uint16_t qtype, uint16_t qclass,
|
||||
struct local_rrset* local_alias, struct comm_reply* repinfo);
|
||||
|
||||
/**
|
||||
* Find resp_addr in tree, create and add to tree if it does not exist.
|
||||
* @param set: struct containing the tree and region to alloc new node on.
|
||||
* should hold write lock.
|
||||
* @param addr: address to look up.
|
||||
* @param addrlen: length of addr.
|
||||
* @param net: netblock to lookup.
|
||||
* @param create: create node if it does not exist when 1.
|
||||
* @param ipstr: human redable ip string, for logging.
|
||||
* @return newly created of found node, not holding lock.
|
||||
*/
|
||||
struct resp_addr*
|
||||
respip_sockaddr_find_or_create(struct respip_set* set, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, int net, int create, const char* ipstr);
|
||||
|
||||
/**
|
||||
* Add RR to resp_addr's RRset. Create RRset if not existing.
|
||||
* @param region: region to alloc RR(set).
|
||||
* @param raddr: resp_addr containing RRset. Must hold write lock.
|
||||
* @param rrtype: RR type.
|
||||
* @param rrclass: RR class.
|
||||
* @param ttl: TTL.
|
||||
* @param rdata: RDATA.
|
||||
* @param rdata_len: length of rdata.
|
||||
* @param rrstr: RR as string, for logging
|
||||
* @param netblockstr: netblock as string, for logging
|
||||
* @return 0 on error
|
||||
*/
|
||||
int
|
||||
respip_enter_rr(struct regional* region, struct resp_addr* raddr,
|
||||
uint16_t rrtype, uint16_t rrclass, time_t ttl, uint8_t* rdata,
|
||||
size_t rdata_len, const char* rrstr, const char* netblockstr);
|
||||
|
||||
/**
|
||||
* Delete resp_addr node from tree.
|
||||
* @param set: struct containing tree. Must hold write lock.
|
||||
* @param node: node to delete. Not locked.
|
||||
*/
|
||||
void
|
||||
respip_sockaddr_delete(struct respip_set* set, struct resp_addr* node);
|
||||
#endif /* RESPIP_RESPIP_H */
|
||||
|
||||
+71
-26
@@ -299,6 +299,8 @@ struct auth_zones* auth_zones_create(void)
|
||||
lock_protect(&az->lock, &az->ztree, sizeof(az->ztree));
|
||||
lock_protect(&az->lock, &az->xtree, sizeof(az->xtree));
|
||||
/* also lock protects the rbnode's in struct auth_zone, auth_xfer */
|
||||
lock_rw_init(&az->rpz_lock);
|
||||
lock_protect(&az->rpz_lock, &az->rpz_first, sizeof(az->rpz_first));
|
||||
return az;
|
||||
}
|
||||
|
||||
@@ -381,11 +383,25 @@ auth_data_del(rbnode_type* n, void* ATTR_UNUSED(arg))
|
||||
|
||||
/** delete an auth zone structure (tree remove must be done elsewhere) */
|
||||
static void
|
||||
auth_zone_delete(struct auth_zone* z)
|
||||
auth_zone_delete(struct auth_zone* z, struct auth_zones* az)
|
||||
{
|
||||
if(!z) return;
|
||||
lock_rw_destroy(&z->lock);
|
||||
traverse_postorder(&z->data, auth_data_del, NULL);
|
||||
|
||||
if(az && z->rpz) {
|
||||
/* keep RPZ linked list intact */
|
||||
lock_rw_wrlock(&az->rpz_lock);
|
||||
if(z->rpz->prev)
|
||||
z->rpz->prev->next = z->rpz->next;
|
||||
else
|
||||
az->rpz_first = z->rpz->next;
|
||||
if(z->rpz->next)
|
||||
z->rpz->next->prev = z->rpz->prev;
|
||||
lock_rw_unlock(&az->rpz_lock);
|
||||
}
|
||||
if(z->rpz)
|
||||
rpz_delete(z->rpz);
|
||||
free(z->name);
|
||||
free(z->zonefile);
|
||||
free(z);
|
||||
@@ -415,7 +431,7 @@ auth_zone_create(struct auth_zones* az, uint8_t* nm, size_t nmlen,
|
||||
/* z lock protects all, except rbtree itself, which is az->lock */
|
||||
if(!rbtree_insert(&az->ztree, &z->node)) {
|
||||
lock_rw_unlock(&z->lock);
|
||||
auth_zone_delete(z);
|
||||
auth_zone_delete(z, NULL);
|
||||
log_warn("duplicate auth zone");
|
||||
return NULL;
|
||||
}
|
||||
@@ -660,23 +676,6 @@ domain_remove_rrset(struct auth_data* node, uint16_t rr_type)
|
||||
}
|
||||
}
|
||||
|
||||
/** find an rr index in the rrset. returns true if found */
|
||||
static int
|
||||
az_rrset_find_rr(struct packed_rrset_data* d, uint8_t* rdata, size_t len,
|
||||
size_t* index)
|
||||
{
|
||||
size_t i;
|
||||
for(i=0; i<d->count; i++) {
|
||||
if(d->rr_len[i] != len)
|
||||
continue;
|
||||
if(memcmp(d->rr_data[i], rdata, len) == 0) {
|
||||
*index = i;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** find an rrsig index in the rrset. returns true if found */
|
||||
static int
|
||||
az_rrset_find_rrsig(struct packed_rrset_data* d, uint8_t* rdata, size_t len,
|
||||
@@ -1178,6 +1177,12 @@ az_insert_rr(struct auth_zone* z, uint8_t* rr, size_t rr_len,
|
||||
log_err("cannot add RR to domain");
|
||||
return 0;
|
||||
}
|
||||
if(z->rpz) {
|
||||
if(!(rpz_insert_rr(z->rpz, z->namelen, dname, dname_len,
|
||||
rr_type, rr_class, rr_ttl, rdata, rdatalen, rr,
|
||||
rr_len)))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1192,7 +1197,7 @@ az_domain_remove_rr(struct auth_data* node, uint16_t rr_type,
|
||||
|
||||
/* find the plain RR of the given type */
|
||||
if((rrset=az_domain_rrset(node, rr_type))!= NULL) {
|
||||
if(az_rrset_find_rr(rrset->data, rdata, rdatalen, &index)) {
|
||||
if(packed_rrset_find_rr(rrset->data, rdata, rdatalen, &index)) {
|
||||
if(rrset->data->count == 1 &&
|
||||
rrset->data->rrsig_count == 0) {
|
||||
/* last RR, delete the rrset */
|
||||
@@ -1293,6 +1298,10 @@ az_remove_rr(struct auth_zone* z, uint8_t* rr, size_t rr_len,
|
||||
(void)rbtree_delete(&z->data, node);
|
||||
auth_data_delete(node);
|
||||
}
|
||||
if(z->rpz) {
|
||||
rpz_remove_rr(z->rpz, z->namelen, dname, dname_len, rr_type,
|
||||
rr_class, rdata, rdatalen);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1585,6 +1594,9 @@ auth_zone_read_zonefile(struct auth_zone* z, struct config_file* cfg)
|
||||
/* clear the data tree */
|
||||
traverse_postorder(&z->data, auth_data_del, NULL);
|
||||
rbtree_init(&z->data, &auth_data_cmp);
|
||||
/* clear the RPZ policies */
|
||||
if(z->rpz)
|
||||
rpz_clear(z->rpz);
|
||||
|
||||
memset(&state, 0, sizeof(state));
|
||||
/* default TTL to 3600 */
|
||||
@@ -1604,6 +1616,9 @@ auth_zone_read_zonefile(struct auth_zone* z, struct config_file* cfg)
|
||||
return 0;
|
||||
}
|
||||
fclose(in);
|
||||
|
||||
if(z->rpz)
|
||||
rpz_finish_config(z->rpz);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1877,6 +1892,18 @@ auth_zones_cfg(struct auth_zones* az, struct config_auth* c)
|
||||
z->for_downstream = c->for_downstream;
|
||||
z->for_upstream = c->for_upstream;
|
||||
z->fallback_enabled = c->fallback_enabled;
|
||||
if(c->isrpz && !z->rpz){
|
||||
if(!(z->rpz = rpz_create(c))){
|
||||
fatal_exit("Could not setup RPZ zones");
|
||||
return 0;
|
||||
}
|
||||
lock_rw_wrlock(&az->rpz_lock);
|
||||
z->rpz->next = az->rpz_first;
|
||||
if(az->rpz_first)
|
||||
az->rpz_first->prev = z->rpz;
|
||||
az->rpz_first = z->rpz;
|
||||
lock_rw_unlock(&az->rpz_lock);
|
||||
}
|
||||
|
||||
/* xfer zone */
|
||||
if(x) {
|
||||
@@ -1947,14 +1974,14 @@ az_delete_deleted_zones(struct auth_zones* az)
|
||||
auth_xfer_delete(xfr);
|
||||
}
|
||||
(void)rbtree_delete(&az->ztree, &z->node);
|
||||
auth_zone_delete(z);
|
||||
auth_zone_delete(z, az);
|
||||
z = next;
|
||||
}
|
||||
lock_rw_unlock(&az->lock);
|
||||
}
|
||||
|
||||
int auth_zones_apply_cfg(struct auth_zones* az, struct config_file* cfg,
|
||||
int setup)
|
||||
int setup, int* is_rpz)
|
||||
{
|
||||
struct config_auth* p;
|
||||
az_setall_deleted(az);
|
||||
@@ -1963,6 +1990,7 @@ int auth_zones_apply_cfg(struct auth_zones* az, struct config_file* cfg,
|
||||
log_warn("auth-zone without a name, skipped");
|
||||
continue;
|
||||
}
|
||||
*is_rpz = (*is_rpz || p->isrpz);
|
||||
if(!auth_zones_cfg(az, p)) {
|
||||
log_err("cannot config auth zone %s", p->name);
|
||||
return 0;
|
||||
@@ -2063,7 +2091,7 @@ static void
|
||||
auth_zone_del(rbnode_type* n, void* ATTR_UNUSED(arg))
|
||||
{
|
||||
struct auth_zone* z = (struct auth_zone*)n->key;
|
||||
auth_zone_delete(z);
|
||||
auth_zone_delete(z, NULL);
|
||||
}
|
||||
|
||||
/** helper traverse to delete xfer zones */
|
||||
@@ -2078,6 +2106,7 @@ void auth_zones_delete(struct auth_zones* az)
|
||||
{
|
||||
if(!az) return;
|
||||
lock_rw_destroy(&az->lock);
|
||||
lock_rw_destroy(&az->rpz_lock);
|
||||
traverse_postorder(&az->ztree, auth_zone_del, NULL);
|
||||
traverse_postorder(&az->xtree, auth_xfer_del, NULL);
|
||||
free(az);
|
||||
@@ -2586,12 +2615,14 @@ az_nsec3_hash(uint8_t* buf, size_t buflen, uint8_t* nm, size_t nmlen,
|
||||
/* hashfunc(name, salt) */
|
||||
memmove(p, nm, nmlen);
|
||||
query_dname_tolower(p);
|
||||
memmove(p+nmlen, salt, saltlen);
|
||||
if(salt && saltlen > 0)
|
||||
memmove(p+nmlen, salt, saltlen);
|
||||
(void)secalgo_nsec3_hash(algo, p, nmlen+saltlen, (unsigned char*)buf);
|
||||
for(i=0; i<iter; i++) {
|
||||
/* hashfunc(hash, salt) */
|
||||
memmove(p, buf, hlen);
|
||||
memmove(p+hlen, salt, saltlen);
|
||||
if(salt && saltlen > 0)
|
||||
memmove(p+hlen, salt, saltlen);
|
||||
(void)secalgo_nsec3_hash(algo, p, hlen+saltlen,
|
||||
(unsigned char*)buf);
|
||||
}
|
||||
@@ -4688,6 +4719,10 @@ apply_axfr(struct auth_xfer* xfr, struct auth_zone* z,
|
||||
/* clear the data tree */
|
||||
traverse_postorder(&z->data, auth_data_del, NULL);
|
||||
rbtree_init(&z->data, &auth_data_cmp);
|
||||
/* clear the RPZ policies */
|
||||
if(z->rpz)
|
||||
rpz_clear(z->rpz);
|
||||
|
||||
xfr->have_zone = 0;
|
||||
xfr->serial = 0;
|
||||
|
||||
@@ -4784,6 +4819,10 @@ apply_http(struct auth_xfer* xfr, struct auth_zone* z,
|
||||
/* clear the data tree */
|
||||
traverse_postorder(&z->data, auth_data_del, NULL);
|
||||
rbtree_init(&z->data, &auth_data_cmp);
|
||||
/* clear the RPZ policies */
|
||||
if(z->rpz)
|
||||
rpz_clear(z->rpz);
|
||||
|
||||
xfr->have_zone = 0;
|
||||
xfr->serial = 0;
|
||||
|
||||
@@ -4969,6 +5008,9 @@ xfr_process_chunk_list(struct auth_xfer* xfr, struct module_env* env,
|
||||
if(xfr->have_zone)
|
||||
xfr->lease_time = *env->now;
|
||||
|
||||
if(z->rpz)
|
||||
rpz_finish_config(z->rpz);
|
||||
|
||||
/* unlock */
|
||||
lock_rw_unlock(&z->lock);
|
||||
|
||||
@@ -5530,9 +5572,12 @@ check_xfer_packet(sldns_buffer* pkt, struct auth_xfer* xfr,
|
||||
xfr->task_transfer->rr_scan_num == 0 &&
|
||||
LDNS_ANCOUNT(wire)==1) {
|
||||
verbose(VERB_ALGO, "xfr to %s ended, "
|
||||
"IXFR reply that zone has serial %u",
|
||||
"IXFR reply that zone has serial %u,"
|
||||
" fallback from IXFR to AXFR",
|
||||
xfr->task_transfer->master->host,
|
||||
(unsigned)serial);
|
||||
xfr->task_transfer->ixfr_fail = 1;
|
||||
*gonextonfail = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+10
-1
@@ -46,6 +46,7 @@
|
||||
#include "util/rbtree.h"
|
||||
#include "util/locks.h"
|
||||
#include "services/mesh.h"
|
||||
#include "services/rpz.h"
|
||||
struct ub_packed_rrset_key;
|
||||
struct regional;
|
||||
struct config_file;
|
||||
@@ -81,6 +82,11 @@ struct auth_zones {
|
||||
size_t num_query_up;
|
||||
/** number of queries downstream */
|
||||
size_t num_query_down;
|
||||
/** first rpz item in linked list */
|
||||
struct rpz* rpz_first;
|
||||
/** rw lock for rpz linked list, needed when iterating or editing linked
|
||||
* list. */
|
||||
lock_rw_type rpz_lock;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -126,6 +132,8 @@ struct auth_zone {
|
||||
/** for upstream: this zone answers queries that unbound intends to
|
||||
* send upstream. */
|
||||
int for_upstream;
|
||||
/** RPZ zones */
|
||||
struct rpz* rpz;
|
||||
/** zone has been deleted */
|
||||
int zone_deleted;
|
||||
/** deletelist pointer, unused normally except during delete */
|
||||
@@ -460,10 +468,11 @@ struct auth_zones* auth_zones_create(void);
|
||||
* @param az: auth zones structure
|
||||
* @param cfg: config to apply.
|
||||
* @param setup: if true, also sets up values in the auth zones structure
|
||||
* @param is_rpz: set to 1 if at least one RPZ zone is configured.
|
||||
* @return false on failure.
|
||||
*/
|
||||
int auth_zones_apply_cfg(struct auth_zones* az, struct config_file* cfg,
|
||||
int setup);
|
||||
int setup, int* is_rpz);
|
||||
|
||||
/** initial pick up of worker timeouts, ties events to worker event loop
|
||||
* @param az: auth zones structure
|
||||
|
||||
Vendored
+71
-49
@@ -45,6 +45,7 @@
|
||||
#include "validator/val_utils.h"
|
||||
#include "services/cache/dns.h"
|
||||
#include "services/cache/rrset.h"
|
||||
#include "util/data/msgparse.h"
|
||||
#include "util/data/msgreply.h"
|
||||
#include "util/data/packed_rrset.h"
|
||||
#include "util/data/dname.h"
|
||||
@@ -73,15 +74,15 @@ store_rrsets(struct module_env* env, struct reply_info* rep, time_t now,
|
||||
time_t leeway, int pside, struct reply_info* qrep,
|
||||
struct regional* region)
|
||||
{
|
||||
size_t i;
|
||||
/* see if rrset already exists in cache, if not insert it. */
|
||||
for(i=0; i<rep->rrset_count; i++) {
|
||||
rep->ref[i].key = rep->rrsets[i];
|
||||
rep->ref[i].id = rep->rrsets[i]->id;
|
||||
/* update ref if it was in the cache */
|
||||
size_t i;
|
||||
/* see if rrset already exists in cache, if not insert it. */
|
||||
for(i=0; i<rep->rrset_count; i++) {
|
||||
rep->ref[i].key = rep->rrsets[i];
|
||||
rep->ref[i].id = rep->rrsets[i]->id;
|
||||
/* update ref if it was in the cache */
|
||||
switch(rrset_cache_update(env->rrset_cache, &rep->ref[i],
|
||||
env->alloc, now + ((ntohs(rep->ref[i].key->rk.type)==
|
||||
LDNS_RR_TYPE_NS && !pside)?0:leeway))) {
|
||||
env->alloc, now + ((ntohs(rep->ref[i].key->rk.type)==
|
||||
LDNS_RR_TYPE_NS && !pside)?0:leeway))) {
|
||||
case 0: /* ref unchanged, item inserted */
|
||||
break;
|
||||
case 2: /* ref updated, cache is superior */
|
||||
@@ -104,9 +105,9 @@ store_rrsets(struct module_env* env, struct reply_info* rep, time_t now,
|
||||
* the fallthrough warning */
|
||||
/* fallthrough */
|
||||
case 1: /* ref updated, item inserted */
|
||||
rep->rrsets[i] = rep->ref[i].key;
|
||||
rep->rrsets[i] = rep->ref[i].key;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** delete message from message cache */
|
||||
@@ -532,31 +533,51 @@ gen_dns_msg(struct regional* region, struct query_info* q, size_t num)
|
||||
}
|
||||
|
||||
struct dns_msg*
|
||||
tomsg(struct module_env* env, struct query_info* q, struct reply_info* r,
|
||||
struct regional* region, time_t now, struct regional* scratch)
|
||||
tomsg(struct module_env* env, struct query_info* q, struct reply_info* r,
|
||||
struct regional* region, time_t now, int allow_expired,
|
||||
struct regional* scratch)
|
||||
{
|
||||
struct dns_msg* msg;
|
||||
size_t i;
|
||||
if(now > r->ttl)
|
||||
return NULL;
|
||||
int is_expired = 0;
|
||||
time_t now_control = now;
|
||||
if(now > r->ttl) {
|
||||
/* Check if we are allowed to serve expired */
|
||||
if(allow_expired) {
|
||||
if(env->cfg->serve_expired_ttl &&
|
||||
r->serve_expired_ttl < now) {
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
/* Change the current time so we can pass the below TTL checks when
|
||||
* serving expired data. */
|
||||
now_control = r->ttl - env->cfg->serve_expired_reply_ttl;
|
||||
is_expired = 1;
|
||||
}
|
||||
|
||||
msg = gen_dns_msg(region, q, r->rrset_count);
|
||||
if(!msg)
|
||||
return NULL;
|
||||
if(!msg) return NULL;
|
||||
msg->rep->flags = r->flags;
|
||||
msg->rep->qdcount = r->qdcount;
|
||||
msg->rep->ttl = r->ttl - now;
|
||||
msg->rep->ttl = is_expired
|
||||
?SERVE_EXPIRED_REPLY_TTL
|
||||
:r->ttl - now;
|
||||
if(r->prefetch_ttl > now)
|
||||
msg->rep->prefetch_ttl = r->prefetch_ttl - now;
|
||||
else msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl);
|
||||
else
|
||||
msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl);
|
||||
msg->rep->serve_expired_ttl = msg->rep->ttl + SERVE_EXPIRED_TTL;
|
||||
msg->rep->security = r->security;
|
||||
msg->rep->an_numrrsets = r->an_numrrsets;
|
||||
msg->rep->ns_numrrsets = r->ns_numrrsets;
|
||||
msg->rep->ar_numrrsets = r->ar_numrrsets;
|
||||
msg->rep->rrset_count = r->rrset_count;
|
||||
msg->rep->authoritative = r->authoritative;
|
||||
if(!rrset_array_lock(r->ref, r->rrset_count, now))
|
||||
msg->rep->authoritative = r->authoritative;
|
||||
if(!rrset_array_lock(r->ref, r->rrset_count, now_control)) {
|
||||
return NULL;
|
||||
}
|
||||
if(r->an_numrrsets > 0 && (r->rrsets[0]->rk.type == htons(
|
||||
LDNS_RR_TYPE_CNAME) || r->rrsets[0]->rk.type == htons(
|
||||
LDNS_RR_TYPE_DNAME)) && !reply_check_cname_chain(q, r)) {
|
||||
@@ -570,7 +591,7 @@ tomsg(struct module_env* env, struct query_info* q, struct reply_info* r,
|
||||
return NULL;
|
||||
}
|
||||
for(i=0; i<msg->rep->rrset_count; i++) {
|
||||
msg->rep->rrsets[i] = packed_rrset_copy_region(r->rrsets[i],
|
||||
msg->rep->rrsets[i] = packed_rrset_copy_region(r->rrsets[i],
|
||||
region, now);
|
||||
if(!msg->rep->rrsets[i]) {
|
||||
rrset_array_unlock(r->ref, r->rrset_count);
|
||||
@@ -797,7 +818,7 @@ dns_cache_lookup(struct module_env* env,
|
||||
if(e) {
|
||||
struct msgreply_entry* key = (struct msgreply_entry*)e->key;
|
||||
struct reply_info* data = (struct reply_info*)e->data;
|
||||
struct dns_msg* msg = tomsg(env, &key->key, data, region, now,
|
||||
struct dns_msg* msg = tomsg(env, &key->key, data, region, now, 0,
|
||||
scratch);
|
||||
if(msg) {
|
||||
lock_rw_unlock(&e->lock);
|
||||
@@ -899,37 +920,38 @@ dns_cache_lookup(struct module_env* env,
|
||||
* Empty nonterminals are NOERROR, so an NXDOMAIN for foo
|
||||
* means bla.foo also does not exist. The DNSSEC proofs are
|
||||
* the same. We search upwards for NXDOMAINs. */
|
||||
if(env->cfg->harden_below_nxdomain)
|
||||
while(!dname_is_root(k.qname)) {
|
||||
dname_remove_label(&k.qname, &k.qname_len);
|
||||
h = query_info_hash(&k, flags);
|
||||
e = slabhash_lookup(env->msg_cache, h, &k, 0);
|
||||
if(!e && k.qtype != LDNS_RR_TYPE_A &&
|
||||
env->cfg->qname_minimisation) {
|
||||
k.qtype = LDNS_RR_TYPE_A;
|
||||
if(env->cfg->harden_below_nxdomain) {
|
||||
while(!dname_is_root(k.qname)) {
|
||||
dname_remove_label(&k.qname, &k.qname_len);
|
||||
h = query_info_hash(&k, flags);
|
||||
e = slabhash_lookup(env->msg_cache, h, &k, 0);
|
||||
}
|
||||
if(e) {
|
||||
struct reply_info* data = (struct reply_info*)e->data;
|
||||
struct dns_msg* msg;
|
||||
if(FLAGS_GET_RCODE(data->flags) == LDNS_RCODE_NXDOMAIN
|
||||
&& data->security == sec_status_secure
|
||||
&& (data->an_numrrsets == 0 ||
|
||||
ntohs(data->rrsets[0]->rk.type) != LDNS_RR_TYPE_CNAME)
|
||||
&& (msg=tomsg(env, &k, data, region, now, scratch))){
|
||||
lock_rw_unlock(&e->lock);
|
||||
msg->qinfo.qname=qname;
|
||||
msg->qinfo.qname_len=qnamelen;
|
||||
/* check that DNSSEC really works out */
|
||||
msg->rep->security = sec_status_unchecked;
|
||||
iter_scrub_nxdomain(msg);
|
||||
return msg;
|
||||
if(!e && k.qtype != LDNS_RR_TYPE_A &&
|
||||
env->cfg->qname_minimisation) {
|
||||
k.qtype = LDNS_RR_TYPE_A;
|
||||
h = query_info_hash(&k, flags);
|
||||
e = slabhash_lookup(env->msg_cache, h, &k, 0);
|
||||
}
|
||||
lock_rw_unlock(&e->lock);
|
||||
if(e) {
|
||||
struct reply_info* data = (struct reply_info*)e->data;
|
||||
struct dns_msg* msg;
|
||||
if(FLAGS_GET_RCODE(data->flags) == LDNS_RCODE_NXDOMAIN
|
||||
&& data->security == sec_status_secure
|
||||
&& (data->an_numrrsets == 0 ||
|
||||
ntohs(data->rrsets[0]->rk.type) != LDNS_RR_TYPE_CNAME)
|
||||
&& (msg=tomsg(env, &k, data, region, now, 0, scratch))) {
|
||||
lock_rw_unlock(&e->lock);
|
||||
msg->qinfo.qname=qname;
|
||||
msg->qinfo.qname_len=qnamelen;
|
||||
/* check that DNSSEC really works out */
|
||||
msg->rep->security = sec_status_unchecked;
|
||||
iter_scrub_nxdomain(msg);
|
||||
return msg;
|
||||
}
|
||||
lock_rw_unlock(&e->lock);
|
||||
}
|
||||
k.qtype = qtype;
|
||||
}
|
||||
k.qtype = qtype;
|
||||
}
|
||||
}
|
||||
|
||||
/* fill common RR types for ANY response to avoid requery */
|
||||
if(qtype == LDNS_RR_TYPE_ANY) {
|
||||
|
||||
Vendored
+5
-2
@@ -143,11 +143,14 @@ struct delegpt* dns_cache_find_delegation(struct module_env* env,
|
||||
* @param r: reply info that, together with qname, will make up the dns message.
|
||||
* @param region: where to allocate dns message.
|
||||
* @param now: the time now, for check if TTL on cache entry is ok.
|
||||
* @param allow_expired: if true and serve-expired is enabled, it will allow
|
||||
* for expired dns_msg to be generated based on the configured serve-expired
|
||||
* logic.
|
||||
* @param scratch: where to allocate temporary data.
|
||||
* */
|
||||
struct dns_msg* tomsg(struct module_env* env, struct query_info* q,
|
||||
struct reply_info* r, struct regional* region, time_t now,
|
||||
struct regional* scratch);
|
||||
int allow_expired, struct regional* scratch);
|
||||
|
||||
/**
|
||||
* Find cached message
|
||||
@@ -160,7 +163,7 @@ struct dns_msg* tomsg(struct module_env* env, struct query_info* q,
|
||||
* @param region: where to allocate result.
|
||||
* @param scratch: where to allocate temporary data.
|
||||
* @param no_partial: if true, only complete messages and not a partial
|
||||
* one (with only the start of the CNAME chain and not the rest).
|
||||
* one (with only the start of the CNAME chain and not the rest).
|
||||
* @return new response message (alloced in region, rrsets do not have IDs).
|
||||
* or NULL on error or if not found in cache.
|
||||
* TTLs are made relative to the current time.
|
||||
|
||||
+159
-61
@@ -41,7 +41,6 @@
|
||||
#include "config.h"
|
||||
#include "services/localzone.h"
|
||||
#include "sldns/str2wire.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
#include "util/regional.h"
|
||||
#include "util/config_file.h"
|
||||
#include "util/data/dname.h"
|
||||
@@ -395,9 +394,30 @@ rrset_insert_rr(struct regional* region, struct packed_rrset_data* pd,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** find a data node by exact name */
|
||||
static struct local_data*
|
||||
lz_find_node(struct local_zone* z, uint8_t* nm, size_t nmlen, int nmlabs)
|
||||
/** Delete RR from local-zone RRset, wastes memory as the deleted RRs cannot be
|
||||
* free'd (regionally alloc'd) */
|
||||
int
|
||||
local_rrset_remove_rr(struct packed_rrset_data* pd, size_t index)
|
||||
{
|
||||
log_assert(pd->count > 0);
|
||||
if(index >= pd->count) {
|
||||
log_warn("Trying to remove RR with out of bound index");
|
||||
return 0;
|
||||
}
|
||||
if(index + 1 < pd->count) {
|
||||
/* not removing last element */
|
||||
size_t nexti = index + 1;
|
||||
size_t num = pd->count - nexti;
|
||||
memmove(pd->rr_len+index, pd->rr_len+nexti, sizeof(*pd->rr_len)*num);
|
||||
memmove(pd->rr_ttl+index, pd->rr_ttl+nexti, sizeof(*pd->rr_ttl)*num);
|
||||
memmove(pd->rr_data+index, pd->rr_data+nexti, sizeof(*pd->rr_data)*num);
|
||||
}
|
||||
pd->count--;
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct local_data*
|
||||
local_zone_find_data(struct local_zone* z, uint8_t* nm, size_t nmlen, int nmlabs)
|
||||
{
|
||||
struct local_data key;
|
||||
key.node.key = &key;
|
||||
@@ -412,7 +432,7 @@ static int
|
||||
lz_find_create_node(struct local_zone* z, uint8_t* nm, size_t nmlen,
|
||||
int nmlabs, struct local_data** res)
|
||||
{
|
||||
struct local_data* ld = lz_find_node(z, nm, nmlen, nmlabs);
|
||||
struct local_data* ld = local_zone_find_data(z, nm, nmlen, nmlabs);
|
||||
if(!ld) {
|
||||
/* create a domain name to store rr. */
|
||||
ld = (struct local_data*)regional_alloc_zero(z->region,
|
||||
@@ -443,42 +463,19 @@ lz_find_create_node(struct local_zone* z, uint8_t* nm, size_t nmlen,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** enter data RR into auth zone */
|
||||
static int
|
||||
lz_enter_rr_into_zone(struct local_zone* z, const char* rrstr)
|
||||
int
|
||||
local_zone_enter_rr(struct local_zone* z, uint8_t* nm, size_t nmlen,
|
||||
int nmlabs, uint16_t rrtype, uint16_t rrclass, time_t ttl,
|
||||
uint8_t* rdata, size_t rdata_len, const char* rrstr)
|
||||
{
|
||||
uint8_t* nm;
|
||||
size_t nmlen;
|
||||
int nmlabs;
|
||||
struct local_data* node;
|
||||
struct local_rrset* rrset;
|
||||
struct packed_rrset_data* pd;
|
||||
uint16_t rrtype = 0, rrclass = 0;
|
||||
time_t ttl = 0;
|
||||
uint8_t rr[LDNS_RR_BUF_SIZE];
|
||||
uint8_t* rdata;
|
||||
size_t rdata_len;
|
||||
if(!rrstr_get_rr_content(rrstr, &nm, &rrtype, &rrclass, &ttl, rr,
|
||||
sizeof(rr), &rdata, &rdata_len)) {
|
||||
log_err("bad local-data: %s", rrstr);
|
||||
return 0;
|
||||
}
|
||||
log_assert(z->dclass == rrclass);
|
||||
if((z->type == local_zone_redirect ||
|
||||
z->type == local_zone_inform_redirect) &&
|
||||
query_dname_compare(z->name, nm) != 0) {
|
||||
log_err("local-data in redirect zone must reside at top of zone"
|
||||
", not at %s", rrstr);
|
||||
free(nm);
|
||||
return 0;
|
||||
}
|
||||
nmlabs = dname_count_size_labels(nm, &nmlen);
|
||||
|
||||
if(!lz_find_create_node(z, nm, nmlen, nmlabs, &node)) {
|
||||
free(nm);
|
||||
return 0;
|
||||
}
|
||||
log_assert(node);
|
||||
free(nm);
|
||||
|
||||
/* Reject it if we would end up having CNAME and other data (including
|
||||
* another CNAME) for a redirect zone. */
|
||||
@@ -520,6 +517,39 @@ lz_enter_rr_into_zone(struct local_zone* z, const char* rrstr)
|
||||
return rrset_insert_rr(z->region, pd, rdata, rdata_len, ttl, rrstr);
|
||||
}
|
||||
|
||||
/** enter data RR into auth zone */
|
||||
int
|
||||
lz_enter_rr_into_zone(struct local_zone* z, const char* rrstr)
|
||||
{
|
||||
uint8_t* nm;
|
||||
size_t nmlen;
|
||||
int nmlabs, ret;
|
||||
uint16_t rrtype = 0, rrclass = 0;
|
||||
time_t ttl = 0;
|
||||
uint8_t rr[LDNS_RR_BUF_SIZE];
|
||||
uint8_t* rdata;
|
||||
size_t rdata_len;
|
||||
if(!rrstr_get_rr_content(rrstr, &nm, &rrtype, &rrclass, &ttl, rr,
|
||||
sizeof(rr), &rdata, &rdata_len)) {
|
||||
log_err("bad local-data: %s", rrstr);
|
||||
return 0;
|
||||
}
|
||||
log_assert(z->dclass == rrclass);
|
||||
if((z->type == local_zone_redirect ||
|
||||
z->type == local_zone_inform_redirect) &&
|
||||
query_dname_compare(z->name, nm) != 0) {
|
||||
log_err("local-data in redirect zone must reside at top of zone"
|
||||
", not at %s", rrstr);
|
||||
free(nm);
|
||||
return 0;
|
||||
}
|
||||
nmlabs = dname_count_size_labels(nm, &nmlen);
|
||||
ret = local_zone_enter_rr(z, nm, nmlen, nmlabs, rrtype, rrclass, ttl,
|
||||
rdata, rdata_len, rrstr);
|
||||
free(nm);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** enter a data RR into auth data; a zone for it must exist */
|
||||
static int
|
||||
lz_enter_rr_str(struct local_zones* zones, const char* rr)
|
||||
@@ -823,12 +853,12 @@ int local_zone_enter_defaults(struct local_zones* zones, struct config_file* cfg
|
||||
log_err("out of memory adding default zone");
|
||||
return 0;
|
||||
}
|
||||
/* test. zone (RFC 7686) */
|
||||
/* test. zone (RFC 6761) */
|
||||
if(!add_empty_default(zones, cfg, "test.")) {
|
||||
log_err("out of memory adding default zone");
|
||||
return 0;
|
||||
}
|
||||
/* invalid. zone (RFC 7686) */
|
||||
/* invalid. zone (RFC 6761) */
|
||||
if(!add_empty_default(zones, cfg, "invalid.")) {
|
||||
log_err("out of memory adding default zone");
|
||||
return 0;
|
||||
@@ -1113,6 +1143,22 @@ local_zones_find(struct local_zones* zones,
|
||||
return (struct local_zone*)rbtree_search(&zones->ztree, &key);
|
||||
}
|
||||
|
||||
struct local_zone*
|
||||
local_zones_find_le(struct local_zones* zones,
|
||||
uint8_t* name, size_t len, int labs, uint16_t dclass,
|
||||
int* exact)
|
||||
{
|
||||
struct local_zone key;
|
||||
rbnode_type *node;
|
||||
key.node.key = &key;
|
||||
key.dclass = dclass;
|
||||
key.name = name;
|
||||
key.namelen = len;
|
||||
key.namelabs = labs;
|
||||
*exact = rbtree_find_less_equal(&zones->ztree, &key, &node);
|
||||
return (struct local_zone*)node;
|
||||
}
|
||||
|
||||
/** print all RRsets in local zone */
|
||||
static void
|
||||
local_zone_out(struct local_zone* z)
|
||||
@@ -1309,8 +1355,7 @@ find_tag_datas(struct query_info* qinfo, struct config_strlist* list,
|
||||
return result;
|
||||
}
|
||||
|
||||
/** answer local data match */
|
||||
static int
|
||||
int
|
||||
local_data_answer(struct local_zone* z, struct module_env* env,
|
||||
struct query_info* qinfo, struct edns_data* edns,
|
||||
struct comm_reply* repinfo, sldns_buffer* buf,
|
||||
@@ -1362,16 +1407,69 @@ local_data_answer(struct local_zone* z, struct module_env* env,
|
||||
lz_type == local_zone_inform_redirect) &&
|
||||
qinfo->qtype != LDNS_RR_TYPE_CNAME &&
|
||||
lr->rrset->rk.type == htons(LDNS_RR_TYPE_CNAME)) {
|
||||
uint8_t* ctarget;
|
||||
size_t ctargetlen = 0;
|
||||
|
||||
qinfo->local_alias =
|
||||
regional_alloc_zero(temp, sizeof(struct local_rrset));
|
||||
if(!qinfo->local_alias)
|
||||
return 0; /* out of memory */
|
||||
qinfo->local_alias->rrset =
|
||||
regional_alloc_init(temp, lr->rrset, sizeof(*lr->rrset));
|
||||
qinfo->local_alias->rrset = regional_alloc_init(
|
||||
temp, lr->rrset, sizeof(*lr->rrset));
|
||||
if(!qinfo->local_alias->rrset)
|
||||
return 0; /* out of memory */
|
||||
qinfo->local_alias->rrset->rk.dname = qinfo->qname;
|
||||
qinfo->local_alias->rrset->rk.dname_len = qinfo->qname_len;
|
||||
get_cname_target(lr->rrset, &ctarget, &ctargetlen);
|
||||
if(!ctargetlen)
|
||||
return 0; /* invalid cname */
|
||||
if(dname_is_wild(ctarget)) {
|
||||
/* synthesize cname target */
|
||||
struct packed_rrset_data* d;
|
||||
/* -3 for wildcard label and root label from qname */
|
||||
size_t newtargetlen = qinfo->qname_len + ctargetlen - 3;
|
||||
|
||||
log_assert(ctargetlen >= 3);
|
||||
log_assert(qinfo->qname_len >= 1);
|
||||
|
||||
if(newtargetlen > LDNS_MAX_DOMAINLEN) {
|
||||
qinfo->local_alias = NULL;
|
||||
local_error_encode(qinfo, env, edns, repinfo,
|
||||
buf, temp, LDNS_RCODE_YXDOMAIN,
|
||||
(LDNS_RCODE_YXDOMAIN|BIT_AA));
|
||||
return 1;
|
||||
}
|
||||
memset(&qinfo->local_alias->rrset->entry, 0,
|
||||
sizeof(qinfo->local_alias->rrset->entry));
|
||||
qinfo->local_alias->rrset->entry.key =
|
||||
qinfo->local_alias->rrset;
|
||||
qinfo->local_alias->rrset->entry.hash =
|
||||
rrset_key_hash(&qinfo->local_alias->rrset->rk);
|
||||
d = (struct packed_rrset_data*)regional_alloc_zero(temp,
|
||||
sizeof(struct packed_rrset_data) + sizeof(size_t) +
|
||||
sizeof(uint8_t*) + sizeof(time_t) + sizeof(uint16_t)
|
||||
+ newtargetlen);
|
||||
if(!d)
|
||||
return 0; /* out of memory */
|
||||
qinfo->local_alias->rrset->entry.data = d;
|
||||
d->ttl = 0; /* 0 for synthesized CNAME TTL */
|
||||
d->count = 1;
|
||||
d->rrsig_count = 0;
|
||||
d->trust = rrset_trust_ans_noAA;
|
||||
d->rr_len = (size_t*)((uint8_t*)d +
|
||||
sizeof(struct packed_rrset_data));
|
||||
d->rr_len[0] = newtargetlen + sizeof(uint16_t);
|
||||
packed_rrset_ptr_fixup(d);
|
||||
d->rr_ttl[0] = d->ttl;
|
||||
sldns_write_uint16(d->rr_data[0], newtargetlen);
|
||||
/* write qname */
|
||||
memmove(d->rr_data[0] + sizeof(uint16_t), qinfo->qname,
|
||||
qinfo->qname_len - 1);
|
||||
/* write cname target wilcard wildcard label */
|
||||
memmove(d->rr_data[0] + sizeof(uint16_t) +
|
||||
qinfo->qname_len - 1, ctarget + 2,
|
||||
ctargetlen - 2);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
if(lz_type == local_zone_redirect ||
|
||||
@@ -1416,26 +1514,15 @@ local_zone_does_not_cover(struct local_zone* z, struct query_info* qinfo,
|
||||
return (lr == NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Answer in case where no exact match is found.
|
||||
* @param z: zone for query.
|
||||
* @param env: module environment.
|
||||
* @param qinfo: query.
|
||||
* @param edns: edns from query.
|
||||
* @param repinfo: source address for checks. may be NULL.
|
||||
* @param buf: buffer for answer.
|
||||
* @param temp: temp region for encoding.
|
||||
* @param ld: local data, if NULL, no such name exists in localdata.
|
||||
* @param lz_type: type of the local zone.
|
||||
* @return 1 if a reply is to be sent, 0 if not.
|
||||
*/
|
||||
static int
|
||||
lz_zone_answer(struct local_zone* z, struct module_env* env,
|
||||
int
|
||||
local_zones_zone_answer(struct local_zone* z, struct module_env* env,
|
||||
struct query_info* qinfo, struct edns_data* edns,
|
||||
struct comm_reply* repinfo, sldns_buffer* buf, struct regional* temp,
|
||||
struct local_data* ld, enum localzone_type lz_type)
|
||||
{
|
||||
if(lz_type == local_zone_deny || lz_type == local_zone_inform_deny) {
|
||||
if(lz_type == local_zone_deny ||
|
||||
lz_type == local_zone_always_deny ||
|
||||
lz_type == local_zone_inform_deny) {
|
||||
/** no reply at all, signal caller by clearing buffer. */
|
||||
sldns_buffer_clear(buf);
|
||||
sldns_buffer_flip(buf);
|
||||
@@ -1448,7 +1535,8 @@ lz_zone_answer(struct local_zone* z, struct module_env* env,
|
||||
} else if(lz_type == local_zone_static ||
|
||||
lz_type == local_zone_redirect ||
|
||||
lz_type == local_zone_inform_redirect ||
|
||||
lz_type == local_zone_always_nxdomain) {
|
||||
lz_type == local_zone_always_nxdomain ||
|
||||
lz_type == local_zone_always_nodata) {
|
||||
/* for static, reply nodata or nxdomain
|
||||
* for redirect, reply nodata */
|
||||
/* no additional section processing,
|
||||
@@ -1457,7 +1545,8 @@ lz_zone_answer(struct local_zone* z, struct module_env* env,
|
||||
* or using closest match for returning delegation downwards
|
||||
*/
|
||||
int rcode = (ld || lz_type == local_zone_redirect ||
|
||||
lz_type == local_zone_inform_redirect)?
|
||||
lz_type == local_zone_inform_redirect ||
|
||||
lz_type == local_zone_always_nodata)?
|
||||
LDNS_RCODE_NOERROR:LDNS_RCODE_NXDOMAIN;
|
||||
if(z->soa)
|
||||
return local_encode(qinfo, env, edns, repinfo, buf, temp,
|
||||
@@ -1640,6 +1729,8 @@ local_zones_answer(struct local_zones* zones, struct module_env* env,
|
||||
if(lzt != local_zone_always_refuse
|
||||
&& lzt != local_zone_always_transparent
|
||||
&& lzt != local_zone_always_nxdomain
|
||||
&& lzt != local_zone_always_nodata
|
||||
&& lzt != local_zone_always_deny
|
||||
&& local_data_answer(z, env, qinfo, edns, repinfo, buf, temp, labs,
|
||||
&ld, lzt, tag, tag_datas, tag_datas_size, tagname, num_tags)) {
|
||||
lock_rw_unlock(&z->lock);
|
||||
@@ -1647,7 +1738,7 @@ local_zones_answer(struct local_zones* zones, struct module_env* env,
|
||||
* a local alias. */
|
||||
return !qinfo->local_alias;
|
||||
}
|
||||
r = lz_zone_answer(z, env, qinfo, edns, repinfo, buf, temp, ld, lzt);
|
||||
r = local_zones_zone_answer(z, env, qinfo, edns, repinfo, buf, temp, ld, lzt);
|
||||
lock_rw_unlock(&z->lock);
|
||||
return r && !qinfo->local_alias; /* see above */
|
||||
}
|
||||
@@ -1669,7 +1760,10 @@ const char* local_zone_type2str(enum localzone_type t)
|
||||
case local_zone_always_transparent: return "always_transparent";
|
||||
case local_zone_always_refuse: return "always_refuse";
|
||||
case local_zone_always_nxdomain: return "always_nxdomain";
|
||||
case local_zone_always_nodata: return "always_nodata";
|
||||
case local_zone_always_deny: return "always_deny";
|
||||
case local_zone_noview: return "noview";
|
||||
case local_zone_invalid: return "invalid";
|
||||
}
|
||||
return "badtyped";
|
||||
}
|
||||
@@ -1700,6 +1794,10 @@ int local_zone_str2type(const char* type, enum localzone_type* t)
|
||||
*t = local_zone_always_refuse;
|
||||
else if(strcmp(type, "always_nxdomain") == 0)
|
||||
*t = local_zone_always_nxdomain;
|
||||
else if(strcmp(type, "always_nodata") == 0)
|
||||
*t = local_zone_always_nodata;
|
||||
else if(strcmp(type, "always_deny") == 0)
|
||||
*t = local_zone_always_deny;
|
||||
else if(strcmp(type, "noview") == 0)
|
||||
*t = local_zone_noview;
|
||||
else if(strcmp(type, "nodefault") == 0)
|
||||
@@ -1843,7 +1941,7 @@ del_empty_term(struct local_zone* z, struct local_data* d,
|
||||
return;
|
||||
dname_remove_label(&name, &len);
|
||||
labs--;
|
||||
d = lz_find_node(z, name, len, labs);
|
||||
d = local_zone_find_data(z, name, len, labs);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1876,7 +1974,7 @@ void local_zones_del_data(struct local_zones* zones,
|
||||
z = local_zones_lookup(zones, name, len, labs, dclass, LDNS_RR_TYPE_DS);
|
||||
if(z) {
|
||||
lock_rw_wrlock(&z->lock);
|
||||
d = lz_find_node(z, name, len, labs);
|
||||
d = local_zone_find_data(z, name, len, labs);
|
||||
if(d) {
|
||||
del_local_rrset(d, LDNS_RR_TYPE_DS);
|
||||
del_empty_term(z, d, name, len, labs);
|
||||
@@ -1897,7 +1995,7 @@ void local_zones_del_data(struct local_zones* zones,
|
||||
lock_rw_unlock(&zones->lock);
|
||||
|
||||
/* find the domain */
|
||||
d = lz_find_node(z, name, len, labs);
|
||||
d = local_zone_find_data(z, name, len, labs);
|
||||
if(d) {
|
||||
/* no memory recycling for zone deletions ... */
|
||||
d->rrsets = NULL;
|
||||
|
||||
+114
-1
@@ -46,6 +46,7 @@
|
||||
#include "util/storage/dnstree.h"
|
||||
#include "util/module.h"
|
||||
#include "services/view.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
struct packed_rrset_data;
|
||||
struct ub_packed_rrset_key;
|
||||
struct regional;
|
||||
@@ -91,8 +92,14 @@ enum localzone_type {
|
||||
local_zone_always_refuse,
|
||||
/** answer with nxdomain, even when there is local data */
|
||||
local_zone_always_nxdomain,
|
||||
/** answer with noerror/nodata, even when there is local data */
|
||||
local_zone_always_nodata,
|
||||
/** drop query, even when there is local data */
|
||||
local_zone_always_deny,
|
||||
/** answer not from the view, but global or no-answer */
|
||||
local_zone_noview
|
||||
local_zone_noview,
|
||||
/** Invalid type, cannot be used to generate answer */
|
||||
local_zone_invalid
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -310,6 +317,25 @@ int local_zones_answer(struct local_zones* zones, struct module_env* env,
|
||||
struct config_strlist** tag_datas, size_t tag_datas_size,
|
||||
char** tagname, int num_tags, struct view* view);
|
||||
|
||||
/**
|
||||
* Answer using the local zone only (not local data used).
|
||||
* @param z: zone for query.
|
||||
* @param env: module environment.
|
||||
* @param qinfo: query.
|
||||
* @param edns: edns from query.
|
||||
* @param repinfo: source address for checks. may be NULL.
|
||||
* @param buf: buffer for answer.
|
||||
* @param temp: temp region for encoding.
|
||||
* @param ld: local data, if NULL, no such name exists in localdata.
|
||||
* @param lz_type: type of the local zone.
|
||||
* @return 1 if a reply is to be sent, 0 if not.
|
||||
*/
|
||||
int
|
||||
local_zones_zone_answer(struct local_zone* z, struct module_env* env,
|
||||
struct query_info* qinfo, struct edns_data* edns,
|
||||
struct comm_reply* repinfo, sldns_buffer* buf, struct regional* temp,
|
||||
struct local_data* ld, enum localzone_type lz_type);
|
||||
|
||||
/**
|
||||
* Parse the string into localzone type.
|
||||
*
|
||||
@@ -340,6 +366,22 @@ const char* local_zone_type2str(enum localzone_type t);
|
||||
struct local_zone* local_zones_find(struct local_zones* zones,
|
||||
uint8_t* name, size_t len, int labs, uint16_t dclass);
|
||||
|
||||
/**
|
||||
* Find zone that with exactly or smaller name/class
|
||||
* User must lock the tree or result zone.
|
||||
* @param zones: the zones tree
|
||||
* @param name: dname to lookup
|
||||
* @param len: length of name.
|
||||
* @param labs: labelcount of name.
|
||||
* @param dclass: class to lookup.
|
||||
* @param exact: 1 on return is this is an exact match.
|
||||
* @return the exact or smaller local_zone or NULL.
|
||||
*/
|
||||
struct local_zone*
|
||||
local_zones_find_le(struct local_zones* zones,
|
||||
uint8_t* name, size_t len, int labs, uint16_t dclass,
|
||||
int* exact);
|
||||
|
||||
/**
|
||||
* Add a new zone. Caller must hold the zones lock.
|
||||
* Adjusts the other zones as well (parent pointers) after insertion.
|
||||
@@ -473,6 +515,15 @@ int rrstr_get_rr_content(const char* str, uint8_t** nm, uint16_t* type,
|
||||
int rrset_insert_rr(struct regional* region, struct packed_rrset_data* pd,
|
||||
uint8_t* rdata, size_t rdata_len, time_t ttl, const char* rrstr);
|
||||
|
||||
/**
|
||||
* Remove RR from rrset that is created using localzone's rrset_insert_rr.
|
||||
* @param pd: the RRset containing the RR to remove
|
||||
* @param index: index of RR to remove
|
||||
* @return: 1 on success; 0 otherwise.
|
||||
*/
|
||||
int
|
||||
local_rrset_remove_rr(struct packed_rrset_data* pd, size_t index);
|
||||
|
||||
/**
|
||||
* Valid response ip actions for the IP-response-driven-action feature;
|
||||
* defined here instead of in the respip module to enable sharing of enum
|
||||
@@ -501,6 +552,10 @@ enum respip_action {
|
||||
respip_always_refuse = local_zone_always_refuse,
|
||||
/** answer with 'no such domain' response */
|
||||
respip_always_nxdomain = local_zone_always_nxdomain,
|
||||
/** answer with nodata response */
|
||||
respip_always_nodata = local_zone_always_nodata,
|
||||
/** answer with nodata response */
|
||||
respip_always_deny = local_zone_always_deny,
|
||||
|
||||
/* The rest of the values are only possible as
|
||||
* access-control-tag-action */
|
||||
@@ -513,6 +568,64 @@ enum respip_action {
|
||||
respip_transparent = local_zone_transparent,
|
||||
/** gives response data (if any), else nodata answer. */
|
||||
respip_typetransparent = local_zone_typetransparent,
|
||||
/** type invalid */
|
||||
respip_invalid = local_zone_invalid,
|
||||
};
|
||||
|
||||
/**
|
||||
* Get local data from local zone and encode answer.
|
||||
* @param z: local zone to use
|
||||
* @param env: module env
|
||||
* @param qinfo: qinfo
|
||||
* @param edns: edns data, for message encoding
|
||||
* @param repinfo: reply info, for message encoding
|
||||
* @param buf: commpoint buffer
|
||||
* @param temp: scratchpad region
|
||||
* @param labs: number of labels in qname
|
||||
* @param ldp: where to store local data
|
||||
* @param lz_type: type of local zone
|
||||
* @param tag: matching tag index
|
||||
* @param tag_datas: alc specific tag data list
|
||||
* @param tag_datas_size: size of tag_datas
|
||||
* @param tagname: list of names of tags, for logging purpose
|
||||
* @param num_tags: number of tags
|
||||
* @return 1 on success
|
||||
*/
|
||||
int
|
||||
local_data_answer(struct local_zone* z, struct module_env* env,
|
||||
struct query_info* qinfo, struct edns_data* edns,
|
||||
struct comm_reply* repinfo, sldns_buffer* buf,
|
||||
struct regional* temp, int labs, struct local_data** ldp,
|
||||
enum localzone_type lz_type, int tag, struct config_strlist** tag_datas,
|
||||
size_t tag_datas_size, char** tagname, int num_tags);
|
||||
|
||||
/**
|
||||
* Add RR to local zone.
|
||||
* @param z: local zone to add RR to
|
||||
* @param nm: dname of RR
|
||||
* @param nmlen: length of nm
|
||||
* @param nmlabs: number of labels of nm
|
||||
* @param rrtype: RR type
|
||||
* @param rrclass: RR class
|
||||
* @param ttl: TTL of RR to add
|
||||
* @param rdata: RDATA of RR to add
|
||||
* @param rdata_len: length of rdata
|
||||
* @param rrstr: RR in string format, for logging
|
||||
* @return: 1 on success
|
||||
*/
|
||||
int
|
||||
local_zone_enter_rr(struct local_zone* z, uint8_t* nm, size_t nmlen,
|
||||
int nmlabs, uint16_t rrtype, uint16_t rrclass, time_t ttl,
|
||||
uint8_t* rdata, size_t rdata_len, const char* rrstr);
|
||||
|
||||
/**
|
||||
* Find a data node by exact name for a local zone
|
||||
* @param z: local_zone containing data tree
|
||||
* @param nm: name of local-data element to find
|
||||
* @param nmlen: length of nm
|
||||
* @param nmlabs: labs of nm
|
||||
* @return local_data on exact match, NULL otherwise.
|
||||
*/
|
||||
struct local_data*
|
||||
local_zone_find_data(struct local_zone* z, uint8_t* nm, size_t nmlen, int nmlabs);
|
||||
#endif /* SERVICES_LOCALZONE_H */
|
||||
|
||||
+381
-45
@@ -46,6 +46,7 @@
|
||||
#include "services/mesh.h"
|
||||
#include "services/outbound_list.h"
|
||||
#include "services/cache/dns.h"
|
||||
#include "services/cache/rrset.h"
|
||||
#include "util/log.h"
|
||||
#include "util/net_help.h"
|
||||
#include "util/module.h"
|
||||
@@ -127,7 +128,7 @@ timeval_smaller(const struct timeval* x, const struct timeval* y)
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* Compare two response-ip client info entries for the purpose of mesh state
|
||||
* compare. It returns 0 if ci_a and ci_b are considered equal; otherwise
|
||||
* 1 or -1 (they mean 'ci_a is larger/smaller than ci_b', respectively, but
|
||||
@@ -250,6 +251,7 @@ mesh_create(struct module_stack* stack, struct module_env* env)
|
||||
mesh->num_forever_states = 0;
|
||||
mesh->stats_jostled = 0;
|
||||
mesh->stats_dropped = 0;
|
||||
mesh->ans_expired = 0;
|
||||
mesh->max_reply_states = env->cfg->num_queries_per_thread;
|
||||
mesh->max_forever_states = (mesh->max_reply_states+1)/2;
|
||||
#ifndef S_SPLINT_S
|
||||
@@ -345,6 +347,97 @@ int mesh_make_new_space(struct mesh_area* mesh, sldns_buffer* qbuf)
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct dns_msg*
|
||||
mesh_serve_expired_lookup(struct module_qstate* qstate,
|
||||
struct query_info* lookup_qinfo)
|
||||
{
|
||||
hashvalue_type h;
|
||||
struct lruhash_entry* e;
|
||||
struct dns_msg* msg;
|
||||
struct reply_info* data;
|
||||
struct msgreply_entry* key;
|
||||
time_t timenow = *qstate->env->now;
|
||||
int must_validate = (!(qstate->query_flags&BIT_CD)
|
||||
|| qstate->env->cfg->ignore_cd) && qstate->env->need_to_validate;
|
||||
/* Lookup cache */
|
||||
h = query_info_hash(lookup_qinfo, qstate->query_flags);
|
||||
e = slabhash_lookup(qstate->env->msg_cache, h, lookup_qinfo, 0);
|
||||
if(!e) return NULL;
|
||||
|
||||
key = (struct msgreply_entry*)e->key;
|
||||
data = (struct reply_info*)e->data;
|
||||
msg = tomsg(qstate->env, &key->key, data, qstate->region, timenow,
|
||||
qstate->env->cfg->serve_expired, qstate->env->scratch);
|
||||
if(!msg)
|
||||
goto bail_out;
|
||||
|
||||
/* Check CNAME chain (if any)
|
||||
* This is part of tomsg above; no need to check now. */
|
||||
|
||||
/* Check security status of the cached answer.
|
||||
* tomsg above has a subset of these checks, so we are leaving
|
||||
* these as is.
|
||||
* In case of bogus or revalidation we don't care to reply here. */
|
||||
if(must_validate && (msg->rep->security == sec_status_bogus ||
|
||||
msg->rep->security == sec_status_secure_sentinel_fail)) {
|
||||
verbose(VERB_ALGO, "Serve expired: bogus answer found in cache");
|
||||
goto bail_out;
|
||||
} else if(msg->rep->security == sec_status_unchecked && must_validate) {
|
||||
verbose(VERB_ALGO, "Serve expired: unchecked entry needs "
|
||||
"validation");
|
||||
goto bail_out; /* need to validate cache entry first */
|
||||
} else if(msg->rep->security == sec_status_secure &&
|
||||
!reply_all_rrsets_secure(msg->rep) && must_validate) {
|
||||
verbose(VERB_ALGO, "Serve expired: secure entry"
|
||||
" changed status");
|
||||
goto bail_out; /* rrset changed, re-verify */
|
||||
}
|
||||
|
||||
lock_rw_unlock(&e->lock);
|
||||
return msg;
|
||||
|
||||
bail_out:
|
||||
lock_rw_unlock(&e->lock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/** Init the serve expired data structure */
|
||||
static int
|
||||
mesh_serve_expired_init(struct mesh_state* mstate, int timeout)
|
||||
{
|
||||
struct timeval t;
|
||||
|
||||
/* Create serve_expired_data if not there yet */
|
||||
if(!mstate->s.serve_expired_data) {
|
||||
mstate->s.serve_expired_data = (struct serve_expired_data*)
|
||||
regional_alloc_zero(
|
||||
mstate->s.region, sizeof(struct serve_expired_data));
|
||||
if(!mstate->s.serve_expired_data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Don't overwrite the function if already set */
|
||||
mstate->s.serve_expired_data->get_cached_answer =
|
||||
mstate->s.serve_expired_data->get_cached_answer?
|
||||
mstate->s.serve_expired_data->get_cached_answer:
|
||||
mesh_serve_expired_lookup;
|
||||
|
||||
/* In case this timer already popped, start it again */
|
||||
if(!mstate->s.serve_expired_data->timer) {
|
||||
mstate->s.serve_expired_data->timer = comm_timer_create(
|
||||
mstate->s.env->worker_base, mesh_serve_expired_callback, mstate);
|
||||
if(!mstate->s.serve_expired_data->timer)
|
||||
return 0;
|
||||
#ifndef S_SPLINT_S
|
||||
t.tv_sec = timeout/1000;
|
||||
t.tv_usec = (timeout%1000)*1000;
|
||||
#endif
|
||||
comm_timer_set(mstate->s.serve_expired_data->timer, &t);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
struct respip_client_info* cinfo, uint16_t qflags,
|
||||
struct edns_data* edns, struct comm_reply* rep, uint16_t qid)
|
||||
@@ -354,6 +447,8 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
int was_detached = 0;
|
||||
int was_noreply = 0;
|
||||
int added = 0;
|
||||
int timeout = mesh->env->cfg->serve_expired?
|
||||
mesh->env->cfg->serve_expired_client_timeout:0;
|
||||
struct sldns_buffer* r_buffer = rep->c->buffer;
|
||||
if(rep->c->tcp_req_info) {
|
||||
r_buffer = rep->c->tcp_req_info->spool_buffer;
|
||||
@@ -366,7 +461,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
verbose(VERB_ALGO, "Too many queries. dropping "
|
||||
"incoming query.");
|
||||
comm_point_drop_reply(rep);
|
||||
mesh->stats_dropped ++;
|
||||
mesh->stats_dropped++;
|
||||
return;
|
||||
}
|
||||
/* for this new reply state, the reply address is free,
|
||||
@@ -376,8 +471,8 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
if(mesh->num_reply_addrs > mesh->max_reply_states*16) {
|
||||
verbose(VERB_ALGO, "Too many requests queued. "
|
||||
"dropping incoming query.");
|
||||
mesh->stats_dropped++;
|
||||
comm_point_drop_reply(rep);
|
||||
mesh->stats_dropped++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -427,23 +522,16 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
mesh->num_detached_states++;
|
||||
added = 1;
|
||||
}
|
||||
if(!s->reply_list && !s->cb_list && s->super_set.count == 0)
|
||||
was_detached = 1;
|
||||
if(!s->reply_list && !s->cb_list)
|
||||
if(!s->reply_list && !s->cb_list) {
|
||||
was_noreply = 1;
|
||||
if(s->super_set.count == 0) {
|
||||
was_detached = 1;
|
||||
}
|
||||
}
|
||||
/* add reply to s */
|
||||
if(!mesh_state_add_reply(s, edns, rep, qid, qflags, qinfo)) {
|
||||
log_err("mesh_new_client: out of memory; SERVFAIL");
|
||||
servfail_mem:
|
||||
if(!inplace_cb_reply_servfail_call(mesh->env, qinfo, &s->s,
|
||||
NULL, LDNS_RCODE_SERVFAIL, edns, rep, mesh->env->scratch))
|
||||
edns->opt_list = NULL;
|
||||
error_encode(r_buffer, LDNS_RCODE_SERVFAIL,
|
||||
qinfo, qid, qflags, edns);
|
||||
comm_point_send_reply(rep);
|
||||
if(added)
|
||||
mesh_state_delete(&s->s);
|
||||
return;
|
||||
log_err("mesh_new_client: out of memory; SERVFAIL");
|
||||
goto servfail_mem;
|
||||
}
|
||||
if(rep->c->tcp_req_info) {
|
||||
if(!tcp_req_info_add_meshstate(rep->c->tcp_req_info, mesh, s)) {
|
||||
@@ -451,6 +539,11 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
goto servfail_mem;
|
||||
}
|
||||
}
|
||||
/* add serve expired timer if required and not already there */
|
||||
if(timeout && !mesh_serve_expired_init(s, timeout)) {
|
||||
log_err("mesh_new_client: out of memory initializing serve expired");
|
||||
goto servfail_mem;
|
||||
}
|
||||
/* update statistics */
|
||||
if(was_detached) {
|
||||
log_assert(mesh->num_detached_states > 0);
|
||||
@@ -475,6 +568,18 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
}
|
||||
if(added)
|
||||
mesh_run(mesh, s, module_event_new, NULL);
|
||||
return;
|
||||
|
||||
servfail_mem:
|
||||
if(!inplace_cb_reply_servfail_call(mesh->env, qinfo, &s->s,
|
||||
NULL, LDNS_RCODE_SERVFAIL, edns, rep, mesh->env->scratch))
|
||||
edns->opt_list = NULL;
|
||||
error_encode(r_buffer, LDNS_RCODE_SERVFAIL,
|
||||
qinfo, qid, qflags, edns);
|
||||
comm_point_send_reply(rep);
|
||||
if(added)
|
||||
mesh_state_delete(&s->s);
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -484,6 +589,8 @@ mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
{
|
||||
struct mesh_state* s = NULL;
|
||||
int unique = unique_mesh_state(edns->opt_list, mesh->env);
|
||||
int timeout = mesh->env->cfg->serve_expired?
|
||||
mesh->env->cfg->serve_expired_client_timeout:0;
|
||||
int was_detached = 0;
|
||||
int was_noreply = 0;
|
||||
int added = 0;
|
||||
@@ -522,15 +629,21 @@ mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
mesh->num_detached_states++;
|
||||
added = 1;
|
||||
}
|
||||
if(!s->reply_list && !s->cb_list && s->super_set.count == 0)
|
||||
was_detached = 1;
|
||||
if(!s->reply_list && !s->cb_list)
|
||||
if(!s->reply_list && !s->cb_list) {
|
||||
was_noreply = 1;
|
||||
if(s->super_set.count == 0) {
|
||||
was_detached = 1;
|
||||
}
|
||||
}
|
||||
/* add reply to s */
|
||||
if(!mesh_state_add_cb(s, edns, buf, cb, cb_arg, qid, qflags)) {
|
||||
if(added)
|
||||
mesh_state_delete(&s->s);
|
||||
return 0;
|
||||
if(added)
|
||||
mesh_state_delete(&s->s);
|
||||
return 0;
|
||||
}
|
||||
/* add serve expired timer if not already there */
|
||||
if(timeout && !mesh_serve_expired_init(s, timeout)) {
|
||||
return 0;
|
||||
}
|
||||
/* update statistics */
|
||||
if(was_detached) {
|
||||
@@ -546,15 +659,6 @@ mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void mesh_schedule_prefetch(struct mesh_area* mesh,
|
||||
struct query_info* qinfo, uint16_t qflags, time_t leeway, int run);
|
||||
|
||||
void mesh_new_prefetch(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
uint16_t qflags, time_t leeway)
|
||||
{
|
||||
mesh_schedule_prefetch(mesh, qinfo, qflags, leeway, 1);
|
||||
}
|
||||
|
||||
/* Internal backend routine of mesh_new_prefetch(). It takes one additional
|
||||
* parameter, 'run', which controls whether to run the prefetch state
|
||||
* immediately. When this function is called internally 'run' could be
|
||||
@@ -631,6 +735,12 @@ static void mesh_schedule_prefetch(struct mesh_area* mesh,
|
||||
mesh_run(mesh, s, module_event_new, NULL);
|
||||
}
|
||||
|
||||
void mesh_new_prefetch(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
uint16_t qflags, time_t leeway)
|
||||
{
|
||||
mesh_schedule_prefetch(mesh, qinfo, qflags, leeway, 1);
|
||||
}
|
||||
|
||||
void mesh_report_reply(struct mesh_area* mesh, struct outbound_entry* e,
|
||||
struct comm_reply* reply, int what)
|
||||
{
|
||||
@@ -703,6 +813,7 @@ mesh_state_create(struct module_env* env, struct query_info* qinfo,
|
||||
mstate->s.env = env;
|
||||
mstate->s.mesh_info = mstate;
|
||||
mstate->s.prefetch_leeway = 0;
|
||||
mstate->s.serve_expired_data = NULL;
|
||||
mstate->s.no_cache_lookup = 0;
|
||||
mstate->s.no_cache_store = 0;
|
||||
mstate->s.need_refetch = 0;
|
||||
@@ -742,6 +853,11 @@ mesh_state_cleanup(struct mesh_state* mstate)
|
||||
if(!mstate)
|
||||
return;
|
||||
mesh = mstate->s.env->mesh;
|
||||
/* Stop and delete the serve expired timer */
|
||||
if(mstate->s.serve_expired_data && mstate->s.serve_expired_data->timer) {
|
||||
comm_timer_delete(mstate->s.serve_expired_data->timer);
|
||||
mstate->s.serve_expired_data->timer = NULL;
|
||||
}
|
||||
/* drop unsent replies */
|
||||
if(!mstate->replies_sent) {
|
||||
struct mesh_reply* rep = mstate->reply_list;
|
||||
@@ -752,6 +868,7 @@ mesh_state_cleanup(struct mesh_state* mstate)
|
||||
mstate->reply_list = NULL;
|
||||
for(; rep; rep=rep->next) {
|
||||
comm_point_drop_reply(&rep->query_reply);
|
||||
log_assert(mesh->num_reply_addrs > 0);
|
||||
mesh->num_reply_addrs--;
|
||||
}
|
||||
while((cb = mstate->cb_list)!=NULL) {
|
||||
@@ -759,6 +876,7 @@ mesh_state_cleanup(struct mesh_state* mstate)
|
||||
fptr_ok(fptr_whitelist_mesh_cb(cb->cb));
|
||||
(*cb->cb)(cb->cb_arg, LDNS_RCODE_SERVFAIL, NULL,
|
||||
sec_status_unchecked, NULL, 0);
|
||||
log_assert(mesh->num_reply_addrs > 0);
|
||||
mesh->num_reply_addrs--;
|
||||
}
|
||||
}
|
||||
@@ -826,7 +944,7 @@ find_in_subsub(struct mesh_state* m, struct mesh_state* tofind, size_t *c)
|
||||
}
|
||||
|
||||
/** find cycle for already looked up mesh_state */
|
||||
static int
|
||||
static int
|
||||
mesh_detect_cycle_found(struct module_qstate* qstate, struct mesh_state* dep_m)
|
||||
{
|
||||
struct mesh_state* cyc_m = qstate->mesh_info;
|
||||
@@ -1038,6 +1156,7 @@ mesh_do_callback(struct mesh_state* m, int rcode, struct reply_info* rep,
|
||||
}
|
||||
}
|
||||
free(reason);
|
||||
log_assert(m->s.env->mesh->num_reply_addrs > 0);
|
||||
m->s.env->mesh->num_reply_addrs--;
|
||||
}
|
||||
|
||||
@@ -1139,6 +1258,7 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
|
||||
comm_point_send_reply(&r->query_reply);
|
||||
}
|
||||
/* account */
|
||||
log_assert(m->s.env->mesh->num_reply_addrs > 0);
|
||||
m->s.env->mesh->num_reply_addrs--;
|
||||
end_time = *m->s.env->now_tv;
|
||||
timeval_subtract(&duration, &end_time, &r->start_time);
|
||||
@@ -1164,37 +1284,76 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
|
||||
|
||||
void mesh_query_done(struct mesh_state* mstate)
|
||||
{
|
||||
struct mesh_reply* r;
|
||||
struct mesh_reply* r, *reply_list = NULL;
|
||||
struct mesh_reply* prev = NULL;
|
||||
struct sldns_buffer* prev_buffer = NULL;
|
||||
struct mesh_cb* c;
|
||||
struct reply_info* rep = (mstate->s.return_msg?
|
||||
mstate->s.return_msg->rep:NULL);
|
||||
if((mstate->s.return_rcode == LDNS_RCODE_SERVFAIL ||
|
||||
(rep && FLAGS_GET_RCODE(rep->flags) == LDNS_RCODE_SERVFAIL))
|
||||
/* No need for the serve expired timer anymore; we are going to reply. */
|
||||
if(mstate->s.serve_expired_data) {
|
||||
comm_timer_delete(mstate->s.serve_expired_data->timer);
|
||||
mstate->s.serve_expired_data->timer = NULL;
|
||||
}
|
||||
if(mstate->s.return_rcode == LDNS_RCODE_SERVFAIL ||
|
||||
(rep && FLAGS_GET_RCODE(rep->flags) == LDNS_RCODE_SERVFAIL)) {
|
||||
/* we are SERVFAILing; check for expired asnwer here */
|
||||
mesh_serve_expired_callback(mstate);
|
||||
if((mstate->reply_list || mstate->cb_list)
|
||||
&& mstate->s.env->cfg->log_servfail
|
||||
&& !mstate->s.env->cfg->val_log_squelch) {
|
||||
char* err = errinf_to_str_servfail(&mstate->s);
|
||||
if(err)
|
||||
log_err("%s", err);
|
||||
free(err);
|
||||
char* err = errinf_to_str_servfail(&mstate->s);
|
||||
if(err)
|
||||
log_err("%s", err);
|
||||
free(err);
|
||||
}
|
||||
}
|
||||
for(r = mstate->reply_list; r; r = r->next) {
|
||||
if(mstate->reply_list) {
|
||||
/* set the reply_list to NULL during the mesh_query_done
|
||||
* processing, so that calls back into the mesh from
|
||||
* tcp_req_info (deciding to drop the reply and thus
|
||||
* unregister the mesh_reply from the mstate) are stopped
|
||||
* because the list is empty.
|
||||
* The mstate is then likely not a reply_state, and maybe
|
||||
* also a detached_state.
|
||||
*/
|
||||
reply_list = mstate->reply_list;
|
||||
mstate->reply_list = NULL;
|
||||
if(!mstate->reply_list && !mstate->cb_list) {
|
||||
/* was a reply state, not anymore */
|
||||
log_assert(mstate->s.env->mesh->num_reply_states > 0);
|
||||
mstate->s.env->mesh->num_reply_states--;
|
||||
}
|
||||
if(!mstate->reply_list && !mstate->cb_list &&
|
||||
mstate->super_set.count == 0)
|
||||
mstate->s.env->mesh->num_detached_states++;
|
||||
}
|
||||
for(r = reply_list; r; r = r->next) {
|
||||
/* if a response-ip address block has been stored the
|
||||
* information should be logged for each client. */
|
||||
if(mstate->s.respip_action_info &&
|
||||
mstate->s.respip_action_info->addrinfo) {
|
||||
respip_inform_print(mstate->s.respip_action_info->addrinfo,
|
||||
respip_inform_print(mstate->s.respip_action_info,
|
||||
r->qname, mstate->s.qinfo.qtype,
|
||||
mstate->s.qinfo.qclass, r->local_alias,
|
||||
&r->query_reply);
|
||||
if(mstate->s.env->cfg->stat_extended &&
|
||||
mstate->s.respip_action_info->rpz_used) {
|
||||
if(mstate->s.respip_action_info->rpz_disabled)
|
||||
mstate->s.env->mesh->rpz_action[RPZ_DISABLED_ACTION]++;
|
||||
if(mstate->s.respip_action_info->rpz_cname_override)
|
||||
mstate->s.env->mesh->rpz_action[RPZ_CNAME_OVERRIDE_ACTION]++;
|
||||
else
|
||||
mstate->s.env->mesh->rpz_action[respip_action_to_rpz_action(
|
||||
mstate->s.respip_action_info->action)]++;
|
||||
}
|
||||
}
|
||||
|
||||
/* if this query is determined to be dropped during the
|
||||
* mesh processing, this is the point to take that action. */
|
||||
if(mstate->s.is_drop)
|
||||
if(mstate->s.is_drop) {
|
||||
comm_point_drop_reply(&r->query_reply);
|
||||
else {
|
||||
} else {
|
||||
struct sldns_buffer* r_buffer = r->query_reply.c->buffer;
|
||||
if(r->query_reply.c->tcp_req_info) {
|
||||
r_buffer = r->query_reply.c->tcp_req_info->spool_buffer;
|
||||
@@ -1216,6 +1375,7 @@ void mesh_query_done(struct mesh_state* mstate)
|
||||
* changed, eg. by adds from the callback routine */
|
||||
if(!mstate->reply_list && mstate->cb_list && !c->next) {
|
||||
/* was a reply state, not anymore */
|
||||
log_assert(mstate->s.env->mesh->num_reply_states > 0);
|
||||
mstate->s.env->mesh->num_reply_states--;
|
||||
}
|
||||
mstate->cb_list = c->next;
|
||||
@@ -1581,7 +1741,9 @@ mesh_stats_clear(struct mesh_area* mesh)
|
||||
timehist_clear(mesh->histogram);
|
||||
mesh->ans_secure = 0;
|
||||
mesh->ans_bogus = 0;
|
||||
memset(&mesh->ans_rcode[0], 0, sizeof(size_t)*16);
|
||||
mesh->ans_expired = 0;
|
||||
memset(&mesh->ans_rcode[0], 0, sizeof(size_t)*UB_STATS_RCODE_NUM);
|
||||
memset(&mesh->rpz_action[0], 0, sizeof(size_t)*UB_STATS_RPZ_ACTION_NUM);
|
||||
mesh->ans_nodata = 0;
|
||||
}
|
||||
|
||||
@@ -1647,6 +1809,7 @@ void mesh_state_remove_reply(struct mesh_area* mesh, struct mesh_state* m,
|
||||
if(prev) prev->next = n->next;
|
||||
else m->reply_list = n->next;
|
||||
/* delete it, but allocated in m region */
|
||||
log_assert(mesh->num_reply_addrs > 0);
|
||||
mesh->num_reply_addrs--;
|
||||
|
||||
/* prev = prev; */
|
||||
@@ -1667,3 +1830,176 @@ void mesh_state_remove_reply(struct mesh_area* mesh, struct mesh_state* m,
|
||||
mesh->num_reply_states--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
apply_respip_action(struct module_qstate* qstate,
|
||||
const struct query_info* qinfo, struct respip_client_info* cinfo,
|
||||
struct respip_action_info* actinfo, struct reply_info* rep,
|
||||
struct ub_packed_rrset_key** alias_rrset,
|
||||
struct reply_info** encode_repp, struct auth_zones* az)
|
||||
{
|
||||
if(qinfo->qtype != LDNS_RR_TYPE_A &&
|
||||
qinfo->qtype != LDNS_RR_TYPE_AAAA &&
|
||||
qinfo->qtype != LDNS_RR_TYPE_ANY)
|
||||
return 1;
|
||||
|
||||
if(!respip_rewrite_reply(qinfo, cinfo, rep, encode_repp, actinfo,
|
||||
alias_rrset, 0, qstate->region, az))
|
||||
return 0;
|
||||
|
||||
/* xxx_deny actions mean dropping the reply, unless the original reply
|
||||
* was redirected to response-ip data. */
|
||||
if((actinfo->action == respip_deny ||
|
||||
actinfo->action == respip_inform_deny) &&
|
||||
*encode_repp == rep)
|
||||
*encode_repp = NULL;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
mesh_serve_expired_callback(void* arg)
|
||||
{
|
||||
struct mesh_state* mstate = (struct mesh_state*) arg;
|
||||
struct module_qstate* qstate = &mstate->s;
|
||||
struct mesh_reply* r;
|
||||
struct mesh_area* mesh = qstate->env->mesh;
|
||||
struct dns_msg* msg;
|
||||
struct mesh_cb* c;
|
||||
struct mesh_reply* prev = NULL;
|
||||
struct sldns_buffer* prev_buffer = NULL;
|
||||
struct sldns_buffer* r_buffer = NULL;
|
||||
struct reply_info* partial_rep = NULL;
|
||||
struct ub_packed_rrset_key* alias_rrset = NULL;
|
||||
struct reply_info* encode_rep = NULL;
|
||||
struct respip_action_info actinfo;
|
||||
struct query_info* lookup_qinfo = &qstate->qinfo;
|
||||
struct query_info qinfo_tmp;
|
||||
int must_validate = (!(qstate->query_flags&BIT_CD)
|
||||
|| qstate->env->cfg->ignore_cd) && qstate->env->need_to_validate;
|
||||
if(!qstate->serve_expired_data) return;
|
||||
verbose(VERB_ALGO, "Serve expired: Trying to reply with expired data");
|
||||
comm_timer_delete(qstate->serve_expired_data->timer);
|
||||
qstate->serve_expired_data->timer = NULL;
|
||||
if(qstate->blacklist || qstate->no_cache_lookup || qstate->is_drop) {
|
||||
verbose(VERB_ALGO,
|
||||
"Serve expired: Not allowed to look into cache for stale");
|
||||
return;
|
||||
}
|
||||
/* The following while is used instead of the `goto lookup_cache`
|
||||
* like in the worker. */
|
||||
while(1) {
|
||||
fptr_ok(fptr_whitelist_serve_expired_lookup(
|
||||
qstate->serve_expired_data->get_cached_answer));
|
||||
msg = qstate->serve_expired_data->get_cached_answer(qstate,
|
||||
lookup_qinfo);
|
||||
if(!msg)
|
||||
return;
|
||||
/* Reset these in case we pass a second time from here. */
|
||||
encode_rep = msg->rep;
|
||||
memset(&actinfo, 0, sizeof(actinfo));
|
||||
actinfo.action = respip_none;
|
||||
alias_rrset = NULL;
|
||||
if((mesh->use_response_ip || mesh->use_rpz) &&
|
||||
!partial_rep && !apply_respip_action(qstate, &qstate->qinfo,
|
||||
qstate->client_info, &actinfo, msg->rep, &alias_rrset, &encode_rep,
|
||||
qstate->env->auth_zones)) {
|
||||
return;
|
||||
} else if(partial_rep &&
|
||||
!respip_merge_cname(partial_rep, &qstate->qinfo, msg->rep,
|
||||
qstate->client_info, must_validate, &encode_rep, qstate->region,
|
||||
qstate->env->auth_zones)) {
|
||||
return;
|
||||
}
|
||||
if(!encode_rep || alias_rrset) {
|
||||
if(!encode_rep) {
|
||||
/* Needs drop */
|
||||
return;
|
||||
} else {
|
||||
/* A partial CNAME chain is found. */
|
||||
partial_rep = encode_rep;
|
||||
}
|
||||
}
|
||||
/* We've found a partial reply ending with an
|
||||
* alias. Replace the lookup qinfo for the
|
||||
* alias target and lookup the cache again to
|
||||
* (possibly) complete the reply. As we're
|
||||
* passing the "base" reply, there will be no
|
||||
* more alias chasing. */
|
||||
if(partial_rep) {
|
||||
memset(&qinfo_tmp, 0, sizeof(qinfo_tmp));
|
||||
get_cname_target(alias_rrset, &qinfo_tmp.qname,
|
||||
&qinfo_tmp.qname_len);
|
||||
if(!qinfo_tmp.qname) {
|
||||
log_err("Serve expired: unexpected: invalid answer alias");
|
||||
return;
|
||||
}
|
||||
qinfo_tmp.qtype = qstate->qinfo.qtype;
|
||||
qinfo_tmp.qclass = qstate->qinfo.qclass;
|
||||
lookup_qinfo = &qinfo_tmp;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if(verbosity >= VERB_ALGO)
|
||||
log_dns_msg("Serve expired lookup", &qstate->qinfo, msg->rep);
|
||||
|
||||
r = mstate->reply_list;
|
||||
mstate->reply_list = NULL;
|
||||
if(!mstate->reply_list && !mstate->cb_list) {
|
||||
log_assert(mesh->num_reply_states > 0);
|
||||
mesh->num_reply_states--;
|
||||
if(mstate->super_set.count == 0) {
|
||||
mesh->num_detached_states++;
|
||||
}
|
||||
}
|
||||
for(; r; r = r->next) {
|
||||
/* If address info is returned, it means the action should be an
|
||||
* 'inform' variant and the information should be logged. */
|
||||
if(actinfo.addrinfo) {
|
||||
respip_inform_print(&actinfo, r->qname,
|
||||
qstate->qinfo.qtype, qstate->qinfo.qclass,
|
||||
r->local_alias, &r->query_reply);
|
||||
|
||||
if(qstate->env->cfg->stat_extended && actinfo.rpz_used) {
|
||||
if(actinfo.rpz_disabled)
|
||||
qstate->env->mesh->rpz_action[RPZ_DISABLED_ACTION]++;
|
||||
if(actinfo.rpz_cname_override)
|
||||
qstate->env->mesh->rpz_action[RPZ_CNAME_OVERRIDE_ACTION]++;
|
||||
else
|
||||
qstate->env->mesh->rpz_action[
|
||||
respip_action_to_rpz_action(actinfo.action)]++;
|
||||
}
|
||||
}
|
||||
|
||||
r_buffer = r->query_reply.c->buffer;
|
||||
if(r->query_reply.c->tcp_req_info)
|
||||
r_buffer = r->query_reply.c->tcp_req_info->spool_buffer;
|
||||
mesh_send_reply(mstate, LDNS_RCODE_NOERROR, msg->rep,
|
||||
r, r_buffer, prev, prev_buffer);
|
||||
if(r->query_reply.c->tcp_req_info)
|
||||
tcp_req_info_remove_mesh_state(r->query_reply.c->tcp_req_info, mstate);
|
||||
prev = r;
|
||||
prev_buffer = r_buffer;
|
||||
|
||||
/* Account for each reply sent. */
|
||||
mesh->ans_expired++;
|
||||
|
||||
}
|
||||
while((c = mstate->cb_list) != NULL) {
|
||||
/* take this cb off the list; so that the list can be
|
||||
* changed, eg. by adds from the callback routine */
|
||||
if(!mstate->reply_list && mstate->cb_list && !c->next) {
|
||||
/* was a reply state, not anymore */
|
||||
log_assert(qstate->env->mesh->num_reply_states > 0);
|
||||
qstate->env->mesh->num_reply_states--;
|
||||
}
|
||||
mstate->cb_list = c->next;
|
||||
if(!mstate->reply_list && !mstate->cb_list &&
|
||||
mstate->super_set.count == 0)
|
||||
qstate->env->mesh->num_detached_states++;
|
||||
mesh_do_callback(mstate, LDNS_RCODE_NOERROR, msg->rep, c);
|
||||
}
|
||||
}
|
||||
|
||||
+30
-1
@@ -51,6 +51,8 @@
|
||||
#include "util/data/msgparse.h"
|
||||
#include "util/module.h"
|
||||
#include "services/modstack.h"
|
||||
#include "services/rpz.h"
|
||||
#include "libunbound/unbound.h"
|
||||
struct sldns_buffer;
|
||||
struct mesh_state;
|
||||
struct mesh_reply;
|
||||
@@ -110,6 +112,8 @@ struct mesh_area {
|
||||
size_t stats_jostled;
|
||||
/** stats, cumulative number of incoming client msgs dropped */
|
||||
size_t stats_dropped;
|
||||
/** stats, number of expired replies sent */
|
||||
size_t ans_expired;
|
||||
/** number of replies sent */
|
||||
size_t replies_sent;
|
||||
/** sum of waiting times for the replies */
|
||||
@@ -121,9 +125,11 @@ struct mesh_area {
|
||||
/** (extended stats) bogus replies */
|
||||
size_t ans_bogus;
|
||||
/** (extended stats) rcodes in replies */
|
||||
size_t ans_rcode[16];
|
||||
size_t ans_rcode[UB_STATS_RCODE_NUM];
|
||||
/** (extended stats) rcode nodata in replies */
|
||||
size_t ans_nodata;
|
||||
/** (extended stats) type of applied RPZ action */
|
||||
size_t rpz_action[UB_STATS_RPZ_ACTION_NUM];
|
||||
|
||||
/** backup of query if other operations recurse and need the
|
||||
* network buffers */
|
||||
@@ -142,6 +148,11 @@ struct mesh_area {
|
||||
struct mesh_state* jostle_last;
|
||||
/** timeout for jostling. if age is lower, it does not get jostled. */
|
||||
struct timeval jostle_max;
|
||||
|
||||
/** If we need to use response ip (value passed from daemon)*/
|
||||
int use_response_ip;
|
||||
/** If we need to use RPZ (value passed from daemon) */
|
||||
int use_rpz;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -643,4 +654,22 @@ void mesh_list_remove(struct mesh_state* m, struct mesh_state** fp,
|
||||
void mesh_state_remove_reply(struct mesh_area* mesh, struct mesh_state* m,
|
||||
struct comm_point* cp);
|
||||
|
||||
/** Callback for when the serve expired client timer has run out. Tries to
|
||||
* find an expired answer in the cache and reply that to the client.
|
||||
* @param arg: the argument passed to the callback.
|
||||
*/
|
||||
void mesh_serve_expired_callback(void* arg);
|
||||
|
||||
/**
|
||||
* Try to get a (expired) cached answer.
|
||||
* This needs to behave like the worker's answer_from_cache() in order to have
|
||||
* the same behavior as when replying from cache.
|
||||
* @param qstate: the module qstate.
|
||||
* @param lookup_qinfo: the query info to look for in the cache.
|
||||
* @return dns_msg if a cached answer was found, otherwise NULL.
|
||||
*/
|
||||
struct dns_msg*
|
||||
mesh_serve_expired_lookup(struct module_qstate* qstate,
|
||||
struct query_info* lookup_qinfo);
|
||||
|
||||
#endif /* SERVICES_MESH_H */
|
||||
|
||||
@@ -293,6 +293,9 @@ outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len)
|
||||
/* open socket */
|
||||
s = outnet_get_tcp_fd(&w->addr, w->addrlen, w->outnet->tcp_mss);
|
||||
|
||||
if(s == -1)
|
||||
return 0;
|
||||
|
||||
if(!pick_outgoing_tcp(w, s))
|
||||
return 0;
|
||||
|
||||
@@ -1971,7 +1974,6 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
|
||||
|
||||
sq->pending = NULL; /* removed after callback */
|
||||
if(error == NETEVENT_TIMEOUT) {
|
||||
int rto = 0;
|
||||
if(sq->status == serviced_query_UDP_EDNS && sq->last_rtt < 5000) {
|
||||
/* fallback to 1480/1280 */
|
||||
sq->status = serviced_query_UDP_EDNS_FRAG;
|
||||
@@ -1987,9 +1989,9 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
|
||||
sq->status = serviced_query_UDP_EDNS;
|
||||
}
|
||||
sq->retry++;
|
||||
if(!(rto=infra_rtt_update(outnet->infra, &sq->addr, sq->addrlen,
|
||||
if(!infra_rtt_update(outnet->infra, &sq->addr, sq->addrlen,
|
||||
sq->zone, sq->zonelen, sq->qtype, -1, sq->last_rtt,
|
||||
(time_t)now.tv_sec)))
|
||||
(time_t)now.tv_sec))
|
||||
log_err("out of memory in UDP exponential backoff");
|
||||
if(sq->retry < OUTBOUND_UDP_RETRY) {
|
||||
log_name_addr(VERB_ALGO, "retry query", sq->qbuf+10,
|
||||
|
||||
+1015
File diff suppressed because it is too large
Load Diff
+201
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
* services/rpz.h - rpz service
|
||||
*
|
||||
* Copyright (c) 2019, NLnet Labs. All rights reserved.
|
||||
*
|
||||
* This software is open source.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of the NLNET LABS nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* This file contains functions to enable RPZ service.
|
||||
*/
|
||||
|
||||
#ifndef SERVICES_RPZ_H
|
||||
#define SERVICES_RPZ_H
|
||||
|
||||
#include "services/localzone.h"
|
||||
#include "util/locks.h"
|
||||
#include "util/log.h"
|
||||
#include "util/config_file.h"
|
||||
#include "services/authzone.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
#include "daemon/stats.h"
|
||||
#include "respip/respip.h"
|
||||
|
||||
/**
|
||||
* RPZ triggers, only the QNAME trigger is currently supported in Unbound.
|
||||
*/
|
||||
enum rpz_trigger {
|
||||
RPZ_QNAME_TRIGGER = 0,
|
||||
/* unsupported triggers */
|
||||
RPZ_CLIENT_IP_TRIGGER, /* rpz-client-ip */
|
||||
RPZ_RESPONSE_IP_TRIGGER, /* rpz-ip */
|
||||
RPZ_NSDNAME_TRIGGER, /* rpz-nsdname */
|
||||
RPZ_NSIP_TRIGGER, /* rpz-nsip */
|
||||
RPZ_INVALID_TRIGGER, /* dname does not contain valid trigger */
|
||||
};
|
||||
|
||||
/**
|
||||
* RPZ actions.
|
||||
*/
|
||||
enum rpz_action {
|
||||
RPZ_NXDOMAIN_ACTION = 0,/* CNAME . */
|
||||
RPZ_NODATA_ACTION, /* CNAME *. */
|
||||
RPZ_PASSTHRU_ACTION, /* CNAME rpz-passthru. */
|
||||
RPZ_DROP_ACTION, /* CNAME rpz-drop. */
|
||||
RPZ_TCP_ONLY_ACTION, /* CNAME rpz-tcp-only. */
|
||||
RPZ_INVALID_ACTION, /* CNAME with (child of) TLD starting with
|
||||
"rpz-" in target, SOA, NS, DNAME and
|
||||
DNSSEC-related records. */
|
||||
RPZ_LOCAL_DATA_ACTION, /* anything else */
|
||||
/* RPZ override actions */
|
||||
RPZ_DISABLED_ACTION, /* RPZ action disabled using override */
|
||||
RPZ_NO_OVERRIDE_ACTION, /* RPZ action no override*/
|
||||
RPZ_CNAME_OVERRIDE_ACTION, /* RPZ CNAME action override*/
|
||||
};
|
||||
|
||||
/**
|
||||
* RPZ containing policies. Pointed to from corresponding auth-zone. Part of a
|
||||
* linked list to keep configuration order. Iterating or changing the linked
|
||||
* list requires the rpz_lock from struct auth_zones.
|
||||
*/
|
||||
struct rpz {
|
||||
struct local_zones* local_zones;
|
||||
struct respip_set* respip_set;
|
||||
uint8_t* taglist;
|
||||
size_t taglistlen;
|
||||
enum rpz_action action_override;
|
||||
struct ub_packed_rrset_key* cname_override;
|
||||
int log;
|
||||
char* log_name;
|
||||
struct rpz* next;
|
||||
struct rpz* prev;
|
||||
struct regional* region;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create policy from RR and add to this RPZ.
|
||||
* @param r: the rpz to add the policy to.
|
||||
* @param aznamelen: the length of the auth-zone name
|
||||
* @param dname: dname of the RR
|
||||
* @param dnamelen: length of the dname
|
||||
* @param rr_type: RR type of the RR
|
||||
* @param rr_class: RR class of the RR
|
||||
* @param rr_ttl: TTL of the RR
|
||||
* @param rdatawl: rdata of the RR, prepended with the rdata size
|
||||
* @param rdatalen: length if the RR, including the prepended rdata size
|
||||
* @param rr: the complete RR, for logging purposes
|
||||
* @param rr_len: the length of the complete RR
|
||||
* @return: 0 on error
|
||||
*/
|
||||
int rpz_insert_rr(struct rpz* r, size_t aznamelen, uint8_t* dname,
|
||||
size_t dnamelen, uint16_t rr_type, uint16_t rr_class, uint32_t rr_ttl,
|
||||
uint8_t* rdatawl, size_t rdatalen, uint8_t* rr, size_t rr_len);
|
||||
|
||||
/**
|
||||
* Delete policy matching RR, used for IXFR.
|
||||
* @param r: the rpz to add the policy to.
|
||||
* @param aznamelen: the length of the auth-zone name
|
||||
* @param dname: dname of the RR
|
||||
* @param dnamelen: length of the dname
|
||||
* @param rr_type: RR type of the RR
|
||||
* @param rr_class: RR class of the RR
|
||||
* @param rdatawl: rdata of the RR, prepended with the rdata size
|
||||
* @param rdatalen: length if the RR, including the prepended rdata size
|
||||
*/
|
||||
void rpz_remove_rr(struct rpz* r, size_t aznamelen, uint8_t* dname,
|
||||
size_t dnamelen, uint16_t rr_type, uint16_t rr_class, uint8_t* rdatawl,
|
||||
size_t rdatalen);
|
||||
|
||||
/**
|
||||
* Walk over the RPZ zones to find and apply a QNAME trigger policy.
|
||||
* @param az: auth_zones struct, containing first RPZ item and RPZ lock
|
||||
* @param env: module env
|
||||
* @param qinfo: qinfo containing qname and qtype
|
||||
* @param edns: edns data
|
||||
* @param buf: buffer to write answer to
|
||||
* @param temp: scratchpad
|
||||
* @param repinfo: reply info
|
||||
* @param taglist: taglist to lookup.
|
||||
* @param taglen: lenth of taglist.
|
||||
* @param stats: worker stats struct
|
||||
* @return: 1 if client answer is ready, 0 to continue resolving
|
||||
*/
|
||||
int rpz_apply_qname_trigger(struct auth_zones* az, struct module_env* env,
|
||||
struct query_info* qinfo, struct edns_data* edns, sldns_buffer* buf,
|
||||
struct regional* temp, struct comm_reply* repinfo,
|
||||
uint8_t* taglist, size_t taglen, struct ub_server_stats* stats);
|
||||
|
||||
/**
|
||||
* Delete RPZ
|
||||
* @param r: RPZ struct to delete
|
||||
*/
|
||||
void rpz_delete(struct rpz* r);
|
||||
|
||||
/**
|
||||
* Clear local-zones and respip data in RPZ, used after reloading file or
|
||||
* AXFR/HTTP transfer.
|
||||
* @param r: RPZ to use
|
||||
*/
|
||||
int rpz_clear(struct rpz* r);
|
||||
|
||||
/**
|
||||
* Create RPZ. RPZ must be added to linked list after creation.
|
||||
* @return: the newly created RPZ
|
||||
*/
|
||||
struct rpz* rpz_create(struct config_auth* p);
|
||||
|
||||
/**
|
||||
* String for RPZ action enum
|
||||
* @param a: RPZ action to get string for
|
||||
* @return: string for RPZ action
|
||||
*/
|
||||
const char* rpz_action_to_string(enum rpz_action a);
|
||||
|
||||
enum rpz_action
|
||||
respip_action_to_rpz_action(enum respip_action a);
|
||||
|
||||
/**
|
||||
* Prepare RPZ after procesing feed content.
|
||||
* @param r: RPZ to use
|
||||
*/
|
||||
void rpz_finish_config(struct rpz* r);
|
||||
|
||||
/**
|
||||
* Classify respip action for RPZ action
|
||||
* @param a: RPZ action
|
||||
* @return: the respip action
|
||||
*/
|
||||
enum respip_action
|
||||
rpz_action_to_respip_action(enum rpz_action a);
|
||||
|
||||
#endif /* SERVICES_RPZ_H */
|
||||
@@ -198,8 +198,6 @@ views_apply_cfg(struct views* vs, struct config_file* cfg)
|
||||
log_err("failed to insert "
|
||||
"default zones into "
|
||||
"local-zone list");
|
||||
free(nd_str);
|
||||
free(nd_type);
|
||||
lock_rw_unlock(&v->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
+6
-5
@@ -120,7 +120,7 @@ sldns_fget_token_l(FILE *f, char *token, const char *delim, size_t limit, int *l
|
||||
if (line_nr) {
|
||||
*line_nr = *line_nr + 1;
|
||||
}
|
||||
if (limit > 0 && (i >= limit || (size_t)(t-token) >= limit)) {
|
||||
if (limit > 0 && (i+1 >= limit || (size_t)(t-token)+1 >= limit)) {
|
||||
*t = '\0';
|
||||
return -1;
|
||||
}
|
||||
@@ -141,7 +141,8 @@ sldns_fget_token_l(FILE *f, char *token, const char *delim, size_t limit, int *l
|
||||
if (c != '\0' && c != '\n') {
|
||||
i++;
|
||||
}
|
||||
if (limit > 0 && (i >= limit || (size_t)(t-token) >= limit)) {
|
||||
/* is there space for the character and the zero after it */
|
||||
if (limit > 0 && (i+1 >= limit || (size_t)(t-token)+1 >= limit)) {
|
||||
*t = '\0';
|
||||
return -1;
|
||||
}
|
||||
@@ -326,8 +327,8 @@ sldns_bget_token_par(sldns_buffer *b, char *token, const char *delim,
|
||||
/* in parentheses */
|
||||
/* do not write ' ' if we want to skip spaces */
|
||||
if(!(skipw && (strchr(skipw, c)||strchr(skipw, ' ')))) {
|
||||
/* check for space for the space character */
|
||||
if (limit > 0 && (i >= limit || (size_t)(t-token) >= limit)) {
|
||||
/* check for space for the space character and a zero delimiter after that. */
|
||||
if (limit > 0 && (i+1 >= limit || (size_t)(t-token)+1 >= limit)) {
|
||||
*t = '\0';
|
||||
return -1;
|
||||
}
|
||||
@@ -354,7 +355,7 @@ sldns_bget_token_par(sldns_buffer *b, char *token, const char *delim,
|
||||
}
|
||||
|
||||
i++;
|
||||
if (limit > 0 && (i >= limit || (size_t)(t-token) >= limit)) {
|
||||
if (limit > 0 && (i+1 >= limit || (size_t)(t-token)+1 >= limit)) {
|
||||
*t = '\0';
|
||||
return -1;
|
||||
}
|
||||
|
||||
+2
-2
@@ -80,7 +80,7 @@ static int sldns_str2wire_dname_buf_rel(const char* str, uint8_t* buf,
|
||||
for (s = str; *s; s++, q++) {
|
||||
if (q >= buf + *olen)
|
||||
return RET_ERR(LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL, q-buf);
|
||||
if (q > buf + LDNS_MAX_DOMAINLEN)
|
||||
if (q >= buf + LDNS_MAX_DOMAINLEN)
|
||||
return RET_ERR(LDNS_WIREPARSE_ERR_DOMAINNAME_OVERFLOW, q-buf);
|
||||
switch (*s) {
|
||||
case '.':
|
||||
@@ -117,7 +117,7 @@ static int sldns_str2wire_dname_buf_rel(const char* str, uint8_t* buf,
|
||||
if(rel) *rel = 1;
|
||||
if (q >= buf + *olen)
|
||||
return RET_ERR(LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL, q-buf);
|
||||
if (q > buf + LDNS_MAX_DOMAINLEN) {
|
||||
if (q >= buf + LDNS_MAX_DOMAINLEN) {
|
||||
return RET_ERR(LDNS_WIREPARSE_ERR_DOMAINNAME_OVERFLOW, q-buf);
|
||||
}
|
||||
if (label_len > LDNS_MAX_LABELLEN) {
|
||||
|
||||
@@ -548,10 +548,7 @@ morechecks(struct config_file* cfg)
|
||||
/* check that the modules listed in module_conf exist */
|
||||
check_modules_exist(cfg->module_conf);
|
||||
|
||||
/* There should be no reason for 'respip' module not to work with
|
||||
* dns64, but it's not explicitly confirmed, so the combination is
|
||||
* excluded below. It's simply unknown yet for the combination of
|
||||
* respip and other modules. */
|
||||
/* Respip is known to *not* work with dns64. */
|
||||
if(strcmp(cfg->module_conf, "iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dns64 validator iterator") != 0
|
||||
@@ -560,7 +557,9 @@ morechecks(struct config_file* cfg)
|
||||
&& strcmp(cfg->module_conf, "respip validator iterator") != 0
|
||||
#ifdef WITH_PYTHONMODULE
|
||||
&& strcmp(cfg->module_conf, "python iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "python respip iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "python validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "python respip validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "validator python iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dns64 python iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dns64 python validator iterator") != 0
|
||||
@@ -570,7 +569,9 @@ morechecks(struct config_file* cfg)
|
||||
#endif
|
||||
#ifdef USE_CACHEDB
|
||||
&& strcmp(cfg->module_conf, "validator cachedb iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "respip validator cachedb iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "cachedb iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "respip cachedb iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dns64 validator cachedb iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dns64 cachedb iterator") != 0
|
||||
#endif
|
||||
@@ -580,39 +581,61 @@ morechecks(struct config_file* cfg)
|
||||
&& strcmp(cfg->module_conf, "dns64 python cachedb iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dns64 python validator cachedb iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "python cachedb iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "python respip cachedb iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "python validator cachedb iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "python respip validator cachedb iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "cachedb python iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "respip cachedb python iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "validator cachedb python iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "respip validator cachedb python iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "validator python cachedb iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "respip validator python cachedb iterator") != 0
|
||||
#endif
|
||||
#ifdef CLIENT_SUBNET
|
||||
&& strcmp(cfg->module_conf, "subnetcache iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "respip subnetcache iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "subnetcache validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "respip subnetcache validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dns64 subnetcache iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dns64 subnetcache validator iterator") != 0
|
||||
#endif
|
||||
#if defined(WITH_PYTHONMODULE) && defined(CLIENT_SUBNET)
|
||||
&& strcmp(cfg->module_conf, "python subnetcache iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "python respip subnetcache iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "subnetcache python iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "respip subnetcache python iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "python subnetcache validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "python respip subnetcache validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "subnetcache python validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "respip subnetcache python validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "subnetcache validator python iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "respip subnetcache validator python iterator") != 0
|
||||
#endif
|
||||
#ifdef USE_IPSECMOD
|
||||
&& strcmp(cfg->module_conf, "ipsecmod iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "ipsecmod respip iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "ipsecmod validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "ipsecmod respip validator iterator") != 0
|
||||
#endif
|
||||
#if defined(WITH_PYTHONMODULE) && defined(USE_IPSECMOD)
|
||||
&& strcmp(cfg->module_conf, "python ipsecmod iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "python ipsecmod respip iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "ipsecmod python iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "ipsecmod python respip iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "ipsecmod validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "ipsecmod respip validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "python ipsecmod validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "python ipsecmod respip validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "ipsecmod python validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "ipsecmod python respip validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "ipsecmod validator python iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "ipsecmod respip validator python iterator") != 0
|
||||
#endif
|
||||
#ifdef USE_IPSET
|
||||
&& strcmp(cfg->module_conf, "validator ipset iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "validator ipset respip iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "ipset iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "ipset respip iterator") != 0
|
||||
#endif
|
||||
) {
|
||||
fatal_exit("module conf '%s' is not known to work",
|
||||
@@ -676,8 +699,9 @@ check_hints(struct config_file* cfg)
|
||||
static void
|
||||
check_auth(struct config_file* cfg)
|
||||
{
|
||||
int is_rpz = 0;
|
||||
struct auth_zones* az = auth_zones_create();
|
||||
if(!az || !auth_zones_apply_cfg(az, cfg, 0)) {
|
||||
if(!az || !auth_zones_apply_cfg(az, cfg, 0i, &is_rpz)) {
|
||||
fatal_exit("Could not setup authority zones");
|
||||
}
|
||||
auth_zones_delete(az);
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
#include "daemon/stats.h"
|
||||
#include "sldns/wire2str.h"
|
||||
#include "sldns/pkthdr.h"
|
||||
#include "services/rpz.h"
|
||||
|
||||
#ifdef HAVE_SYS_IPC_H
|
||||
#include "sys/ipc.h"
|
||||
@@ -157,6 +158,8 @@ usage(void)
|
||||
printf(" view_local_datas view add list of local-data to view\n");
|
||||
printf(" one entry per line read from stdin\n");
|
||||
printf(" view_local_data_remove view name remove local-data in view\n");
|
||||
printf(" view_local_datas_remove view remove list of local-data from view\n");
|
||||
printf(" one entry per line read from stdin\n");
|
||||
printf("Version %s\n", PACKAGE_VERSION);
|
||||
printf("BSD licensed, see LICENSE in source package for details.\n");
|
||||
printf("Report bugs to %s\n", PACKAGE_BUGREPORT);
|
||||
@@ -208,7 +211,7 @@ static void pr_stats(const char* nm, struct ub_stats_info* s)
|
||||
s->svr.num_queries - s->svr.num_queries_missed_cache);
|
||||
PR_UL_NM("num.cachemiss", s->svr.num_queries_missed_cache);
|
||||
PR_UL_NM("num.prefetch", s->svr.num_queries_prefetch);
|
||||
PR_UL_NM("num.zero_ttl", s->svr.zero_ttl_responses);
|
||||
PR_UL_NM("num.expired", s->svr.ans_expired);
|
||||
PR_UL_NM("num.recursivereplies", s->mesh_replies_sent);
|
||||
#ifdef USE_DNSCRYPT
|
||||
PR_UL_NM("num.dnscrypt.crypted", s->svr.num_query_dnscrypt_crypted);
|
||||
@@ -372,6 +375,14 @@ static void print_extended(struct ub_stats_info* s)
|
||||
PR_UL("rrset.cache.count", s->svr.rrset_cache_count);
|
||||
PR_UL("infra.cache.count", s->svr.infra_cache_count);
|
||||
PR_UL("key.cache.count", s->svr.key_cache_count);
|
||||
/* applied RPZ actions */
|
||||
for(i=0; i<UB_STATS_RPZ_ACTION_NUM; i++) {
|
||||
if(i == RPZ_NO_OVERRIDE_ACTION)
|
||||
continue;
|
||||
if(inhibit_zero && s->svr.rpz_action[i] == 0)
|
||||
continue;
|
||||
PR_UL_SUB("num.rpz.action", rpz_action_to_string(i), s->svr.rpz_action[i]);
|
||||
}
|
||||
#ifdef USE_DNSCRYPT
|
||||
PR_UL("dnscrypt_shared_secret.cache.count",
|
||||
s->svr.shared_secret_cache_count);
|
||||
@@ -493,9 +504,11 @@ setup_ctx(struct config_file* cfg)
|
||||
ctx = SSL_CTX_new(SSLv23_client_method());
|
||||
if(!ctx)
|
||||
ssl_err("could not allocate SSL_CTX pointer");
|
||||
#if SSL_OP_NO_SSLv2 != 0
|
||||
if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2)
|
||||
!= SSL_OP_NO_SSLv2)
|
||||
ssl_err("could not set SSL_OP_NO_SSLv2");
|
||||
#endif
|
||||
if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3)
|
||||
!= SSL_OP_NO_SSLv3)
|
||||
ssl_err("could not set SSL_OP_NO_SSLv3");
|
||||
@@ -704,7 +717,8 @@ check_args_for_listcmd(int argc, char* argv[])
|
||||
fatal_exit("too many arguments for command '%s', "
|
||||
"content is piped in from stdin", argv[0]);
|
||||
}
|
||||
if(argc >= 1 && strcmp(argv[0], "view_local_datas") == 0 &&
|
||||
if(argc >= 1 && (strcmp(argv[0], "view_local_datas") == 0 ||
|
||||
strcmp(argv[0], "view_local_datas_remove") == 0) &&
|
||||
argc >= 3) {
|
||||
fatal_exit("too many arguments for command '%s', "
|
||||
"content is piped in from stdin", argv[0]);
|
||||
@@ -753,7 +767,8 @@ go_cmd(SSL* ssl, int fd, int quiet, int argc, char* argv[])
|
||||
strcmp(argv[0], "local_zones_remove") == 0 ||
|
||||
strcmp(argv[0], "local_datas") == 0 ||
|
||||
strcmp(argv[0], "view_local_datas") == 0 ||
|
||||
strcmp(argv[0], "local_datas_remove") == 0)) {
|
||||
strcmp(argv[0], "local_datas_remove") == 0 ||
|
||||
strcmp(argv[0], "view_local_datas_remove") == 0)) {
|
||||
send_file(ssl, fd, stdin, buf, sizeof(buf));
|
||||
send_eof(ssl, fd);
|
||||
}
|
||||
|
||||
@@ -234,7 +234,9 @@ setup_ctx(char* key, char* cert)
|
||||
{
|
||||
SSL_CTX* ctx = SSL_CTX_new(SSLv23_server_method());
|
||||
if(!ctx) print_exit("out of memory");
|
||||
#if SSL_OP_NO_SSLv2 != 0
|
||||
(void)SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
|
||||
#endif
|
||||
(void)SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3);
|
||||
if(!SSL_CTX_use_certificate_chain_file(ctx, cert))
|
||||
print_exit("cannot read cert");
|
||||
|
||||
+10
-10
@@ -74,18 +74,18 @@
|
||||
* o CHECK_ANSWER - followed by entry
|
||||
* o CHECK_OUT_QUERY - followed by entry (if copy-id it is also reply).
|
||||
* o REPLY - followed by entry
|
||||
* o TIMEOUT
|
||||
* o TIME_PASSES ELAPSE [seconds] - increase 'now' time counter, can be
|
||||
* a floating point number.
|
||||
* TIME_PASSES EVAL [macro] - expanded for seconds to move time.
|
||||
* o TRAFFIC - like CHECK_ANSWER, causes traffic to flow.
|
||||
* o TIMEOUT
|
||||
* o TIME_PASSES ELAPSE [seconds] - increase 'now' time counter, can be
|
||||
* a floating point number.
|
||||
* TIME_PASSES EVAL [macro] - expanded for seconds to move time.
|
||||
* o TRAFFIC - like CHECK_ANSWER, causes traffic to flow.
|
||||
* actually the traffic flows before this step is taken.
|
||||
* the step waits for traffic to stop.
|
||||
* o CHECK_AUTOTRUST [id] - followed by FILE_BEGIN [to match] FILE_END.
|
||||
* The file contents is macro expanded before match.
|
||||
* o CHECK_TEMPFILE [fname] - followed by FILE_BEGIN [to match] FILE_END
|
||||
* o INFRA_RTT [ip] [dp] [rtt] - update infra cache entry with rtt.
|
||||
* o ERROR
|
||||
* o CHECK_AUTOTRUST [id] - followed by FILE_BEGIN [to match] FILE_END.
|
||||
* The file contents is macro expanded before match.
|
||||
* o CHECK_TEMPFILE [fname] - followed by FILE_BEGIN [to match] FILE_END
|
||||
* o INFRA_RTT [ip] [dp] [rtt] - update infra cache entry with rtt.
|
||||
* o ERROR
|
||||
* ; following entry starts on the next line, ENTRY_BEGIN.
|
||||
* ; more STEP items
|
||||
* SCENARIO_END
|
||||
|
||||
@@ -794,6 +794,34 @@ dname_test_valid(void)
|
||||
, 4096) == 0);
|
||||
}
|
||||
|
||||
/** Test dname_has_label */
|
||||
static void
|
||||
dname_test_has_label(void)
|
||||
{
|
||||
unit_show_func("util/data/dname.c", "dname_has_label");
|
||||
/* label past root label */
|
||||
unit_assert(dname_has_label((uint8_t*)"\01a\0\01c", 5, (uint8_t*)"\01c") == 0);
|
||||
/* label not found */
|
||||
unit_assert(dname_has_label((uint8_t*)"\02ab\01c\0", 6, (uint8_t*)"\01e") == 0);
|
||||
/* buffer too short */
|
||||
unit_assert(dname_has_label((uint8_t*)"\02ab\01c\0", 5, (uint8_t*)"\0") == 0);
|
||||
unit_assert(dname_has_label((uint8_t*)"\1a\0", 2, (uint8_t*)"\0") == 0);
|
||||
unit_assert(dname_has_label((uint8_t*)"\0", 0, (uint8_t*)"\0") == 0);
|
||||
unit_assert(dname_has_label((uint8_t*)"\02ab\01c", 4, (uint8_t*)"\01c") == 0);
|
||||
unit_assert(dname_has_label((uint8_t*)"\02ab\03qwe\06oqieur\03def\01c\0", 19, (uint8_t*)"\01c") == 0);
|
||||
|
||||
/* positive cases */
|
||||
unit_assert(dname_has_label((uint8_t*)"\0", 1, (uint8_t*)"\0") == 1);
|
||||
unit_assert(dname_has_label((uint8_t*)"\1a\0", 3, (uint8_t*)"\0") == 1);
|
||||
unit_assert(dname_has_label((uint8_t*)"\01a\0\01c", 5, (uint8_t*)"\0") == 1);
|
||||
unit_assert(dname_has_label((uint8_t*)"\02ab\01c", 5, (uint8_t*)"\01c") == 1);
|
||||
unit_assert(dname_has_label((uint8_t*)"\02ab\01c\0", 10, (uint8_t*)"\0") == 1);
|
||||
unit_assert(dname_has_label((uint8_t*)"\02ab\01c\0", 7, (uint8_t*)"\0") == 1);
|
||||
unit_assert(dname_has_label((uint8_t*)"\02ab\03qwe\06oqieur\03def\01c\0", 22, (uint8_t*)"\03def") == 1);
|
||||
unit_assert(dname_has_label((uint8_t*)"\02ab\03qwe\06oqieur\03def\01c\0", 22, (uint8_t*)"\02ab") == 1);
|
||||
unit_assert(dname_has_label((uint8_t*)"\02ab\03qwe\06oqieur\03def\01c\0", 22, (uint8_t*)"\01c") == 1);
|
||||
}
|
||||
|
||||
/** test pkt_dname_tolower */
|
||||
static void
|
||||
dname_test_pdtl(sldns_buffer* loopbuf, sldns_buffer* boundbuf)
|
||||
@@ -855,6 +883,7 @@ void dname_test(void)
|
||||
dname_test_canoncmp();
|
||||
dname_test_topdomain();
|
||||
dname_test_valid();
|
||||
dname_test_has_label();
|
||||
sldns_buffer_free(buff);
|
||||
sldns_buffer_free(loopbuf);
|
||||
sldns_buffer_free(boundbuf);
|
||||
|
||||
+3
-1
@@ -47,7 +47,9 @@ ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752
|
||||
; this RR is edited to create the failure
|
||||
;www.example.com. IN A 10.20.30.40
|
||||
www.example.com. IN A 127.0.0.1
|
||||
www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
|
||||
; also edits the signature to fail, without needing crypto checks.
|
||||
;www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
|
||||
www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 28540 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
|
||||
|
||||
TEMPFILE_END
|
||||
|
||||
|
||||
BIN
Binary file not shown.
Vendored
-1
@@ -1 +0,0 @@
|
||||
®öÝìK¬‡#‘€4ùsŽ pèÖôÁæÀx!¹»AŠ"mM
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Vendored
-1
@@ -1 +0,0 @@
|
||||
m7÷ЯБб┐x;▒%в╦У░И*∙эR╞Дс╞╧mD╙Я
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -1,26 +0,0 @@
|
||||
server:
|
||||
verbosity: 2
|
||||
# num-threads: 1
|
||||
port: @PORT@
|
||||
interface: 0.0.0.0
|
||||
interface: 0.0.0.0@@DNSCRYPT_PORT@
|
||||
use-syslog: no
|
||||
directory: .
|
||||
pidfile: "unbound.pid"
|
||||
chroot: ""
|
||||
username: ""
|
||||
do-not-query-localhost: no
|
||||
|
||||
forward-zone:
|
||||
name: "."
|
||||
forward-addr: "127.0.0.1@@TOPORT@"
|
||||
|
||||
dnscrypt:
|
||||
dnscrypt-enable: yes
|
||||
dnscrypt-port: @DNSCRYPT_PORT@
|
||||
dnscrypt-provider: 2.dnscrypt-cert.example.com.
|
||||
dnscrypt-secret-key: 1.key
|
||||
dnscrypt-secret-key: 2.key
|
||||
dnscrypt-provider-cert: 1_salsa.cert
|
||||
dnscrypt-provider-cert: 2_salsa.cert
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
BaseName: dnscrypt_queries
|
||||
Version: 1.0
|
||||
Description: dnscrypt queries.
|
||||
CreationDate: Fri Mar 03 10:08:08 CEST 2017
|
||||
Maintainer: Emmanuel Bretelle
|
||||
Category:
|
||||
Component:
|
||||
CmdDepends:
|
||||
Depends:
|
||||
Help:
|
||||
Pre: dnscrypt_queries.pre
|
||||
Post: dnscrypt_queries.post
|
||||
Test: dnscrypt_queries.test
|
||||
AuxFiles:
|
||||
Passed:
|
||||
Failure:
|
||||
@@ -1,20 +0,0 @@
|
||||
# #-- dnscrypt_queries.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
|
||||
PRE="../.."
|
||||
. ../common.sh
|
||||
# if no dnscrypt; exit
|
||||
if grep "define USE_DNSCRYPT 1" $PRE/config.h; then
|
||||
echo "have dnscrypt"
|
||||
else
|
||||
echo "no dnscrypt"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
kill_pid $FWD_PID
|
||||
kill_pid $UNBOUND_PID
|
||||
kill_pid $PROXY_PID
|
||||
@@ -1,53 +0,0 @@
|
||||
# #-- dnscrypt_queries.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
|
||||
|
||||
PRE="../.."
|
||||
. ../common.sh
|
||||
# if no dnscrypt; exit
|
||||
if grep "define USE_DNSCRYPT 1" $PRE/config.h; then
|
||||
echo "have dnscrypt"
|
||||
else
|
||||
echo "no dnscrypt"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
get_random_port 4
|
||||
UNBOUND_PORT=$RND_PORT
|
||||
FWD_PORT=$(($RND_PORT + 1))
|
||||
DNSCRYPT_PORT=$(($RND_PORT + 2))
|
||||
PROXY_PORT=$(($RND_PORT + 3))
|
||||
echo "UNBOUND_PORT=$UNBOUND_PORT" >> .tpkg.var.test
|
||||
echo "FWD_PORT=$FWD_PORT" >> .tpkg.var.test
|
||||
echo "DNSCRYPT_PORT=$DNSCRYPT_PORT" >> .tpkg.var.test
|
||||
echo "PROXY_PORT=$PROXY_PORT" >> .tpkg.var.test
|
||||
|
||||
# start forwarder
|
||||
get_ldns_testns
|
||||
$LDNS_TESTNS -p $FWD_PORT dnscrypt_queries.testns >fwd.log 2>&1 &
|
||||
FWD_PID=$!
|
||||
echo "FWD_PID=$FWD_PID" >> .tpkg.var.test
|
||||
|
||||
dnscrypt-proxy --local-address=127.0.0.1:${PROXY_PORT} \
|
||||
--resolver-address=127.0.0.1:${DNSCRYPT_PORT} \
|
||||
--provider-name=2.dnscrypt-cert.example.com \
|
||||
--provider-key=B85F:41A1:4F23:F7DB:C866:F397:CC6F:44B6:5F9D:65C5:B629:7C27:5403:A6E9:DCF2:4F9D \
|
||||
-m 32 \
|
||||
>dnscryptproxy.log 2>&1 &
|
||||
PROXY_PID=$!
|
||||
echo "PROXY_PID=$PROXY_PID" >> .tpkg.var.test
|
||||
|
||||
# make config file
|
||||
sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@TOPORT\@/'$FWD_PORT'/' \
|
||||
-e 's/@DNSCRYPT_PORT\@/'$DNSCRYPT_PORT'/' < dnscrypt_queries.conf > ub.conf
|
||||
# start unbound in the background
|
||||
$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
|
||||
wait_server_up dnscryptproxy.log "Proxying from"
|
||||
@@ -1,107 +0,0 @@
|
||||
# #-- dnscrypt_queries.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="../.."
|
||||
. ../common.sh
|
||||
# if no dnscrypt; exit
|
||||
if grep "define USE_DNSCRYPT 1" $PRE/config.h; then
|
||||
echo "have dnscrypt"
|
||||
else
|
||||
echo "no dnscrypt"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
||||
# do the test
|
||||
for opt in '' '+tcp'
|
||||
do
|
||||
echo "> do queries ${opt}"
|
||||
dig @127.0.0.1 ${opt} -p $PROXY_PORT www1.example.com. >outfile1 &
|
||||
digpid1=$!
|
||||
dig @127.0.0.1 ${opt} -p $PROXY_PORT www2.example.com. >outfile2 &
|
||||
digpid2=$!
|
||||
dig @127.0.0.1 ${opt} -p $PROXY_PORT www3.example.com. >outfile3 &
|
||||
digpid3=$!
|
||||
dig @127.0.0.1 ${opt} -p $PROXY_PORT www4.example.com. >outfile4 &
|
||||
digpid4=$!
|
||||
dig @127.0.0.1 ${opt} -p $PROXY_PORT www5.example.com. >outfile5 &
|
||||
digpid5=$!
|
||||
dig @127.0.0.1 ${opt} -p $PROXY_PORT www6.example.com. >outfile6 &
|
||||
digpid6=$!
|
||||
sleep 1
|
||||
kill -9 $digpid1
|
||||
kill -9 $digpid2
|
||||
kill -9 $digpid3
|
||||
kill -9 $digpid4
|
||||
kill -9 $digpid5
|
||||
kill -9 $digpid6
|
||||
|
||||
echo "> cat outfile1"
|
||||
cat outfile1
|
||||
echo "> cat outfile2"
|
||||
cat outfile2
|
||||
echo "> cat outfile3"
|
||||
cat outfile3
|
||||
echo "> cat outfile4"
|
||||
cat outfile4
|
||||
echo "> cat outfile5"
|
||||
cat outfile5
|
||||
echo "> cat outfile6"
|
||||
cat outfile6
|
||||
echo "> cat logfiles"
|
||||
cat fwd.log
|
||||
cat unbound.log
|
||||
|
||||
echo "> check for ID bit collisions"
|
||||
grep "pending reply" unbound.log > ids
|
||||
numsend=`cat ids | wc -l`
|
||||
cat ids | awk '{print $8};' | sort -u > ids2
|
||||
numuniq=`cat ids2 | wc -l`
|
||||
if test $numuniq -ne $numsend; then
|
||||
echo "got a ID number clash. could not do test, sorry"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "> check answers for queries"
|
||||
if grep "10.20.30.40" outfile1; then
|
||||
echo "1 is OK"
|
||||
else
|
||||
echo "1 is not OK"
|
||||
exit 1
|
||||
fi
|
||||
if grep "10.20.30.50" outfile2; then
|
||||
echo "2 is OK"
|
||||
else
|
||||
echo "2 is not OK"
|
||||
exit 1
|
||||
fi
|
||||
if grep "10.20.30.60" outfile3; then
|
||||
echo "3 is OK"
|
||||
else
|
||||
echo "3 is not OK"
|
||||
exit 1
|
||||
fi
|
||||
if grep "10.20.30.70" outfile4; then
|
||||
echo "4 is OK"
|
||||
else
|
||||
echo "4 is not OK"
|
||||
exit 1
|
||||
fi
|
||||
if grep "10.20.30.80" outfile5; then
|
||||
echo "5 is OK"
|
||||
else
|
||||
echo "5 is not OK"
|
||||
exit 1
|
||||
fi
|
||||
if grep "10.20.30.90" outfile6; then
|
||||
echo "6 is OK"
|
||||
else
|
||||
echo "6 is not OK"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
exit 0
|
||||
@@ -1,63 +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
|
||||
www1 IN A
|
||||
SECTION ANSWER
|
||||
www1 IN A 10.20.30.40
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
REPLY QR AA NOERROR
|
||||
ADJUST copy_id
|
||||
SECTION QUESTION
|
||||
www2 IN A
|
||||
SECTION ANSWER
|
||||
www2 IN A 10.20.30.50
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
REPLY QR AA NOERROR
|
||||
ADJUST copy_id
|
||||
SECTION QUESTION
|
||||
www3 IN A
|
||||
SECTION ANSWER
|
||||
www3 IN A 10.20.30.60
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
REPLY QR AA NOERROR
|
||||
ADJUST copy_id
|
||||
SECTION QUESTION
|
||||
www4 IN A
|
||||
SECTION ANSWER
|
||||
www4 IN A 10.20.30.70
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
REPLY QR AA NOERROR
|
||||
ADJUST copy_id
|
||||
SECTION QUESTION
|
||||
www5 IN A
|
||||
SECTION ANSWER
|
||||
www5 IN A 10.20.30.80
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
REPLY QR AA NOERROR
|
||||
ADJUST copy_id
|
||||
SECTION QUESTION
|
||||
www6 IN A
|
||||
SECTION ANSWER
|
||||
www6 IN A 10.20.30.90
|
||||
ENTRY_END
|
||||
-1
@@ -1 +0,0 @@
|
||||
®öÝìK¬‡#‘€4ùsŽ pèÖôÁæÀx!¹»AŠ"mM
|
||||
Binary file not shown.
Binary file not shown.
-1
@@ -1 +0,0 @@
|
||||
m7÷ЯБб┐x;▒%в╦У░И*∙эR╞Дс╞╧mD╙Я
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,24 +0,0 @@
|
||||
server:
|
||||
verbosity: 2
|
||||
# num-threads: 1
|
||||
port: @PORT@
|
||||
interface: 0.0.0.0
|
||||
interface: 0.0.0.0@@DNSCRYPT_PORT@
|
||||
use-syslog: no
|
||||
directory: .
|
||||
pidfile: "unbound.pid"
|
||||
chroot: ""
|
||||
username: ""
|
||||
do-not-query-localhost: no
|
||||
|
||||
forward-zone:
|
||||
name: "."
|
||||
forward-addr: "127.0.0.1@@TOPORT@"
|
||||
|
||||
dnscrypt:
|
||||
dnscrypt-enable: yes
|
||||
dnscrypt-port: @DNSCRYPT_PORT@
|
||||
dnscrypt-provider: 2.dnscrypt-cert.example.com.
|
||||
dnscrypt-secret-key: 2.key
|
||||
dnscrypt-provider-cert: 2_salsa.cert
|
||||
dnscrypt-provider-cert: 2_chacha.cert
|
||||
@@ -1,16 +0,0 @@
|
||||
BaseName: dnscrypt_queries_chacha
|
||||
Version: 1.0
|
||||
Description: dnscrypt queries using xchacha
|
||||
CreationDate: Thu Jun 01 10:08:08 CEST 2017
|
||||
Maintainer: Emmanuel Bretelle
|
||||
Category:
|
||||
Component:
|
||||
CmdDepends:
|
||||
Depends:
|
||||
Help:
|
||||
Pre: dnscrypt_queries_chacha.pre
|
||||
Post: dnscrypt_queries_chacha.post
|
||||
Test: dnscrypt_queries_chacha.test
|
||||
AuxFiles:
|
||||
Passed:
|
||||
Failure:
|
||||
@@ -1,17 +0,0 @@
|
||||
# #-- dnscrypt_queries_chacha.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
|
||||
PRE="../.."
|
||||
. ../common.sh
|
||||
|
||||
# Check if we can run the test.
|
||||
. ./precheck.sh
|
||||
|
||||
|
||||
kill_pid $FWD_PID
|
||||
kill_pid $UNBOUND_PID
|
||||
kill_pid $PROXY_PID
|
||||
@@ -1,52 +0,0 @@
|
||||
# #-- dnscrypt_queries_chacha.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
|
||||
|
||||
PRE="../.."
|
||||
. ../common.sh
|
||||
# Check if we can run the test.
|
||||
. ./precheck.sh
|
||||
|
||||
get_random_port 4
|
||||
UNBOUND_PORT=$RND_PORT
|
||||
FWD_PORT=$(($RND_PORT + 1))
|
||||
DNSCRYPT_PORT=$(($RND_PORT + 2))
|
||||
PROXY_PORT=$(($RND_PORT + 3))
|
||||
echo "UNBOUND_PORT=$UNBOUND_PORT" >> .tpkg.var.test
|
||||
echo "FWD_PORT=$FWD_PORT" >> .tpkg.var.test
|
||||
echo "DNSCRYPT_PORT=$DNSCRYPT_PORT" >> .tpkg.var.test
|
||||
echo "PROXY_PORT=$PROXY_PORT" >> .tpkg.var.test
|
||||
|
||||
# start forwarder
|
||||
get_ldns_testns
|
||||
$LDNS_TESTNS -p $FWD_PORT dnscrypt_queries_chacha.testns >fwd.log 2>&1 &
|
||||
FWD_PID=$!
|
||||
echo "FWD_PID=$FWD_PID" >> .tpkg.var.test
|
||||
|
||||
dnscrypt-proxy --local-address=127.0.0.1:${PROXY_PORT} \
|
||||
--resolver-address=127.0.0.1:${DNSCRYPT_PORT} \
|
||||
--provider-name=2.dnscrypt-cert.example.com \
|
||||
--provider-key=C352:1F20:F2D2:FD65:B5F4:7BF6:6C1A:88C1:4BCB:80CE:1E3A:3572:5CB1:7D4B:12D3:E783 \
|
||||
-m 32 \
|
||||
>dnscryptproxy.log 2>&1 &
|
||||
PROXY_PID=$!
|
||||
echo "PROXY_PID=$PROXY_PID" >> .tpkg.var.test
|
||||
|
||||
# make config file
|
||||
sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@TOPORT\@/'$FWD_PORT'/' \
|
||||
-e 's/@DNSCRYPT_PORT\@/'$DNSCRYPT_PORT'/' < dnscrypt_queries_chacha.conf > ub.conf
|
||||
# start unbound in the background
|
||||
$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
|
||||
wait_server_up dnscryptproxy.log "Proxying from"
|
||||
if ! grep 'Using version 2.0 of the DNSCrypt protocol' dnscryptproxy.log; then
|
||||
echo "Failed to select xchacha cert"
|
||||
exit 1
|
||||
fi
|
||||
@@ -1,101 +0,0 @@
|
||||
# #-- dnscrypt_queries_chacha.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="../.."
|
||||
. ../common.sh
|
||||
# Check if we can run the test.
|
||||
. ./precheck.sh
|
||||
|
||||
# do the test
|
||||
for opt in '' '+tcp'
|
||||
do
|
||||
echo "> do queries ${opt}"
|
||||
dig @127.0.0.1 ${opt} -p $PROXY_PORT www1.example.com. >outfile1 &
|
||||
digpid1=$!
|
||||
dig @127.0.0.1 ${opt} -p $PROXY_PORT www2.example.com. >outfile2 &
|
||||
digpid2=$!
|
||||
dig @127.0.0.1 ${opt} -p $PROXY_PORT www3.example.com. >outfile3 &
|
||||
digpid3=$!
|
||||
dig @127.0.0.1 ${opt} -p $PROXY_PORT www4.example.com. >outfile4 &
|
||||
digpid4=$!
|
||||
dig @127.0.0.1 ${opt} -p $PROXY_PORT www5.example.com. >outfile5 &
|
||||
digpid5=$!
|
||||
dig @127.0.0.1 ${opt} -p $PROXY_PORT www6.example.com. >outfile6 &
|
||||
digpid6=$!
|
||||
sleep 1
|
||||
kill -9 $digpid1
|
||||
kill -9 $digpid2
|
||||
kill -9 $digpid3
|
||||
kill -9 $digpid4
|
||||
kill -9 $digpid5
|
||||
kill -9 $digpid6
|
||||
|
||||
echo "> cat outfile1"
|
||||
cat outfile1
|
||||
echo "> cat outfile2"
|
||||
cat outfile2
|
||||
echo "> cat outfile3"
|
||||
cat outfile3
|
||||
echo "> cat outfile4"
|
||||
cat outfile4
|
||||
echo "> cat outfile5"
|
||||
cat outfile5
|
||||
echo "> cat outfile6"
|
||||
cat outfile6
|
||||
echo "> cat logfiles"
|
||||
cat fwd.log
|
||||
cat unbound.log
|
||||
|
||||
echo "> check for ID bit collisions"
|
||||
grep "pending reply" unbound.log > ids
|
||||
numsend=`cat ids | wc -l`
|
||||
cat ids | awk '{print $8};' | sort -u > ids2
|
||||
numuniq=`cat ids2 | wc -l`
|
||||
if test $numuniq -ne $numsend; then
|
||||
echo "got a ID number clash. could not do test, sorry"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "> check answers for queries"
|
||||
if grep "10.20.30.40" outfile1; then
|
||||
echo "1 is OK"
|
||||
else
|
||||
echo "1 is not OK"
|
||||
exit 1
|
||||
fi
|
||||
if grep "10.20.30.50" outfile2; then
|
||||
echo "2 is OK"
|
||||
else
|
||||
echo "2 is not OK"
|
||||
exit 1
|
||||
fi
|
||||
if grep "10.20.30.60" outfile3; then
|
||||
echo "3 is OK"
|
||||
else
|
||||
echo "3 is not OK"
|
||||
exit 1
|
||||
fi
|
||||
if grep "10.20.30.70" outfile4; then
|
||||
echo "4 is OK"
|
||||
else
|
||||
echo "4 is not OK"
|
||||
exit 1
|
||||
fi
|
||||
if grep "10.20.30.80" outfile5; then
|
||||
echo "5 is OK"
|
||||
else
|
||||
echo "5 is not OK"
|
||||
exit 1
|
||||
fi
|
||||
if grep "10.20.30.90" outfile6; then
|
||||
echo "6 is OK"
|
||||
else
|
||||
echo "6 is not OK"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
exit 0
|
||||
@@ -1,63 +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
|
||||
www1 IN A
|
||||
SECTION ANSWER
|
||||
www1 IN A 10.20.30.40
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
REPLY QR AA NOERROR
|
||||
ADJUST copy_id
|
||||
SECTION QUESTION
|
||||
www2 IN A
|
||||
SECTION ANSWER
|
||||
www2 IN A 10.20.30.50
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
REPLY QR AA NOERROR
|
||||
ADJUST copy_id
|
||||
SECTION QUESTION
|
||||
www3 IN A
|
||||
SECTION ANSWER
|
||||
www3 IN A 10.20.30.60
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
REPLY QR AA NOERROR
|
||||
ADJUST copy_id
|
||||
SECTION QUESTION
|
||||
www4 IN A
|
||||
SECTION ANSWER
|
||||
www4 IN A 10.20.30.70
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
REPLY QR AA NOERROR
|
||||
ADJUST copy_id
|
||||
SECTION QUESTION
|
||||
www5 IN A
|
||||
SECTION ANSWER
|
||||
www5 IN A 10.20.30.80
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
REPLY QR AA NOERROR
|
||||
ADJUST copy_id
|
||||
SECTION QUESTION
|
||||
www6 IN A
|
||||
SECTION ANSWER
|
||||
www6 IN A 10.20.30.90
|
||||
ENTRY_END
|
||||
@@ -1,27 +0,0 @@
|
||||
# dnscrypt precheck.sh
|
||||
|
||||
# if no dnscrypt; exit
|
||||
if grep "define USE_DNSCRYPT 1" $PRE/config.h; then
|
||||
echo "have dnscrypt"
|
||||
else
|
||||
echo "no dnscrypt"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# if no xchacha20 support in unbound; exit
|
||||
if grep "define USE_DNSCRYPT_XCHACHA20 1" $PRE/config.h; then
|
||||
echo "have xchacha20"
|
||||
xchacha20=1
|
||||
else
|
||||
echo "no xchacha20"
|
||||
xchacha20=0
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# if dnscrypt-proxy does not support xchacha20; exit
|
||||
if (dnscrypt-proxy -h 2>&1 | grep -q 'XChaCha20-Poly1305 cipher: present'); then
|
||||
echo "dnscrypt-proxy has xchacha20"
|
||||
else
|
||||
echo "dnscrypt-proxy does not have xchacha20"
|
||||
exit 0
|
||||
fi
|
||||
+14
-12
@@ -25,7 +25,7 @@ if grep "10.20.30.40" outfile; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "> cat logfiles"
|
||||
cat fwd.log
|
||||
cat fwd.log
|
||||
cat unbound.log
|
||||
echo "Not OK"
|
||||
exit 1
|
||||
@@ -37,7 +37,7 @@ $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 fwd.log
|
||||
cat unbound.log
|
||||
exit 1
|
||||
else
|
||||
@@ -61,7 +61,7 @@ if grep "5.6.7.8" outfile; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "> cat logfiles"
|
||||
cat fwd.log
|
||||
cat fwd.log
|
||||
cat unbound.log
|
||||
echo "Not OK"
|
||||
exit 1
|
||||
@@ -72,6 +72,8 @@ 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
|
||||
@@ -90,7 +92,7 @@ if test $? -ne 0; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# check syntax error in parse
|
||||
# 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
|
||||
@@ -135,7 +137,7 @@ if grep "192.0.2.1" outfile; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "> cat logfiles"
|
||||
cat fwd.log
|
||||
cat fwd.log
|
||||
cat unbound.log
|
||||
echo "Not OK"
|
||||
exit 1
|
||||
@@ -149,7 +151,7 @@ if grep "NXDOMAIN" outfile; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "> cat logfiles"
|
||||
cat fwd.log
|
||||
cat fwd.log
|
||||
cat unbound.log
|
||||
echo "Not OK"
|
||||
exit 1
|
||||
@@ -169,7 +171,7 @@ if grep "NXDOMAIN" outfile; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "> cat logfiles"
|
||||
cat fwd.log
|
||||
cat fwd.log
|
||||
cat unbound.log
|
||||
echo "Not OK"
|
||||
exit 1
|
||||
@@ -189,7 +191,7 @@ if grep "SERVFAIL" outfile; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "> cat logfiles"
|
||||
cat fwd.log
|
||||
cat fwd.log
|
||||
cat unbound.log
|
||||
echo "Not OK"
|
||||
exit 1
|
||||
@@ -216,7 +218,7 @@ else
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# test lookup
|
||||
# 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
|
||||
@@ -282,7 +284,7 @@ done
|
||||
if kill -0 $UNBOUND_PID; then
|
||||
echo "still up!"
|
||||
echo "> cat logfiles"
|
||||
cat fwd.log
|
||||
cat fwd.log
|
||||
cat unbound.log
|
||||
echo "not stopped, failure"
|
||||
exit 1
|
||||
@@ -294,7 +296,7 @@ else
|
||||
echo "lock-verify test worked."
|
||||
else
|
||||
echo "lock-verify test failed."
|
||||
cat fwd.log
|
||||
cat fwd.log
|
||||
cat unbound.log
|
||||
exit 1
|
||||
fi
|
||||
@@ -302,7 +304,7 @@ else
|
||||
fi
|
||||
|
||||
echo "> cat logfiles"
|
||||
cat fwd.log
|
||||
cat fwd.log
|
||||
cat unbound.log
|
||||
echo "> OK"
|
||||
exit 0
|
||||
|
||||
Vendored
+362
@@ -0,0 +1,362 @@
|
||||
; config options
|
||||
server:
|
||||
module-config: "respip validator iterator"
|
||||
target-fetch-policy: "0 0 0 0 0"
|
||||
qname-minimisation: no
|
||||
|
||||
rpz:
|
||||
name: "rpz.example.com."
|
||||
master: 10.20.30.40
|
||||
zonefile:
|
||||
TEMPFILE_NAME rpz.example.com
|
||||
TEMPFILE_CONTENTS rpz.example.com
|
||||
$ORIGIN rpz.example.com.
|
||||
a IN CNAME *.
|
||||
c IN TXT "hello from initial RPZ"
|
||||
c IN TXT "another hello from initial RPZ"
|
||||
d IN CNAME .
|
||||
32.1.123.0.10.rpz-ip CNAME *.
|
||||
32.3.123.0.10.rpz-ip A 10.66.0.3
|
||||
32.3.123.0.10.rpz-ip A 10.66.0.4
|
||||
32.4.123.0.10.rpz-ip CNAME .
|
||||
TEMPFILE_END
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
stub-addr: 10.20.30.40
|
||||
|
||||
CONFIG_END
|
||||
|
||||
SCENARIO_BEGIN Test RPZ QNAME trigger, loaded using AXFR
|
||||
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 10.20.30.40
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qname qtype
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR AA
|
||||
SECTION QUESTION
|
||||
. IN NS
|
||||
SECTION ANSWER
|
||||
. IN NS ns.
|
||||
SECTION ADDITIONAL
|
||||
ns. IN NS 10.20.30.40
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qname qtype
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR AA
|
||||
SECTION QUESTION
|
||||
b. IN TXT
|
||||
SECTION ANSWER
|
||||
b. TXT "hello from upstream"
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qname qtype
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR AA
|
||||
SECTION QUESTION
|
||||
d. IN TXT
|
||||
SECTION ANSWER
|
||||
d. TXT "hello from upstream"
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qname qtype
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR AA
|
||||
SECTION QUESTION
|
||||
a.rpz-ip. IN A
|
||||
SECTION ANSWER
|
||||
a.rpz-ip. IN A 10.0.123.1
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qname qtype
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR AA
|
||||
SECTION QUESTION
|
||||
c.rpz-ip. IN A
|
||||
SECTION ANSWER
|
||||
c.rpz-ip. IN A 10.0.123.3
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qname qtype
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR AA
|
||||
SECTION QUESTION
|
||||
d.rpz-ip. IN A
|
||||
SECTION ANSWER
|
||||
d.rpz-ip. IN A 10.0.123.4
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qname qtype
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
rpz.example.com. IN SOA
|
||||
SECTION ANSWER
|
||||
rpz.example.com. IN SOA ns.rpz.example.com. hostmaster.rpz.example.com. 1 3600 900 86400 3600
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qname qtype
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
rpz.example.com. IN AXFR
|
||||
SECTION ANSWER
|
||||
rpz.example.com. IN SOA ns.rpz.example.com. hostmaster.rpz.example.com. 1 3600 900 86400 3600
|
||||
b.rpz.example.com. TXT "hello from RPZ"
|
||||
c.rpz.example.com. TXT "hello from RPZ"
|
||||
a.rpz.example.com. CNAME .
|
||||
32.1.123.0.10.rpz-ip.rpz.example.com. CNAME .
|
||||
32.3.123.0.10.rpz-ip.rpz.example.com. A 10.66.0.5
|
||||
32.3.123.0.10.rpz-ip.rpz.example.com. A 10.66.0.6
|
||||
rpz.example.com. IN SOA ns.rpz.example.com. hostmaster.rpz.example.com. 1 3600 900 86400 3600
|
||||
ENTRY_END
|
||||
|
||||
RANGE_END
|
||||
|
||||
STEP 1 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
b. IN TXT
|
||||
ENTRY_END
|
||||
|
||||
STEP 2 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
b. IN TXT
|
||||
SECTION ANSWER
|
||||
b. IN TXT "hello from upstream"
|
||||
ENTRY_END
|
||||
|
||||
STEP 3 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
a. IN TXT
|
||||
ENTRY_END
|
||||
|
||||
STEP 4 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA AA NOERROR
|
||||
SECTION QUESTION
|
||||
a. IN TXT
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
|
||||
STEP 5 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
a.rpz-ip. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 6 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
a.rpz-ip. IN A
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
|
||||
STEP 7 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
c. IN TXT
|
||||
ENTRY_END
|
||||
|
||||
STEP 8 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA AA NOERROR
|
||||
SECTION QUESTION
|
||||
c. IN TXT
|
||||
SECTION ANSWER
|
||||
c. IN TXT "another hello from initial RPZ"
|
||||
c. IN TXT "hello from initial RPZ"
|
||||
ENTRY_END
|
||||
|
||||
STEP 9 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
c.rpz-ip. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
c.rpz-ip. IN A
|
||||
SECTION ANSWER
|
||||
c.rpz-ip. IN A 10.66.0.4
|
||||
c.rpz-ip. IN A 10.66.0.3
|
||||
ENTRY_END
|
||||
|
||||
STEP 11 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
d. IN TXT
|
||||
ENTRY_END
|
||||
|
||||
STEP 12 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA AA NXDOMAIN
|
||||
SECTION QUESTION
|
||||
d. IN TXT
|
||||
ENTRY_END
|
||||
|
||||
STEP 13 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
d.rpz-ip. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 14 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NXDOMAIN
|
||||
SECTION QUESTION
|
||||
d.rpz-ip. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 30 TIME_PASSES ELAPSE 10
|
||||
STEP 40 TRAFFIC
|
||||
|
||||
STEP 50 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
b. IN TXT
|
||||
ENTRY_END
|
||||
|
||||
STEP 51 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA AA NOERROR
|
||||
SECTION QUESTION
|
||||
b. IN TXT
|
||||
SECTION ANSWER
|
||||
b. IN TXT "hello from RPZ"
|
||||
ENTRY_END
|
||||
|
||||
STEP 52 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
a. IN TXT
|
||||
ENTRY_END
|
||||
|
||||
STEP 53 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA AA NXDOMAIN
|
||||
SECTION QUESTION
|
||||
a. IN TXT
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
|
||||
STEP 54 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
a.rpz-ip. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 55 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NXDOMAIN
|
||||
SECTION QUESTION
|
||||
a.rpz-ip. IN A
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
|
||||
STEP 56 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
c. IN TXT
|
||||
ENTRY_END
|
||||
|
||||
STEP 57 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA AA NOERROR
|
||||
SECTION QUESTION
|
||||
c. IN TXT
|
||||
SECTION ANSWER
|
||||
c. IN TXT "hello from RPZ"
|
||||
ENTRY_END
|
||||
|
||||
STEP 58 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
c.rpz-ip. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 59 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
c.rpz-ip. IN A
|
||||
SECTION ANSWER
|
||||
c.rpz-ip. IN A 10.66.0.6
|
||||
c.rpz-ip. IN A 10.66.0.5
|
||||
ENTRY_END
|
||||
|
||||
STEP 60 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
d. IN TXT
|
||||
ENTRY_END
|
||||
|
||||
STEP 61 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
d. IN TXT
|
||||
SECTION ANSWER
|
||||
d. IN TXT "hello from upstream"
|
||||
ENTRY_END
|
||||
|
||||
STEP 62 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
d.rpz-ip. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 63 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
d.rpz-ip. IN A
|
||||
SECTION ANSWER
|
||||
d.rpz-ip. IN A 10.0.123.4
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
Vendored
+378
@@ -0,0 +1,378 @@
|
||||
; config options
|
||||
server:
|
||||
module-config: "respip validator iterator"
|
||||
target-fetch-policy: "0 0 0 0 0"
|
||||
qname-minimisation: no
|
||||
|
||||
rpz:
|
||||
name: "rpz.example.com."
|
||||
master: 10.20.30.40
|
||||
zonefile:
|
||||
TEMPFILE_NAME rpz.example.com
|
||||
TEMPFILE_CONTENTS rpz.example.com
|
||||
rpz.example.com. 3600 IN SOA ns.rpz.example.com. hostmaster.rpz.example.com. 1 3600 900 86400 3600
|
||||
rpz.example.com. 3600 IN NS ns.rpz.example.net.
|
||||
a.rpz.example.com. IN CNAME *.
|
||||
c.rpz.example.com. IN TXT "hello from initial RPZ"
|
||||
c.rpz.example.com. IN TXT "another hello from initial RPZ"
|
||||
c.rpz.example.com. IN TXT "yet another hello from initial RPZ"
|
||||
d.rpz.example.com. IN CNAME .
|
||||
32.1.123.0.10.rpz-ip.rpz.example.com. CNAME *.
|
||||
32.3.123.0.10.rpz-ip.rpz.example.com. A 10.66.0.3
|
||||
32.3.123.0.10.rpz-ip.rpz.example.com. A 10.66.0.4
|
||||
32.4.123.0.10.rpz-ip.rpz.example.com. CNAME .
|
||||
TEMPFILE_END
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
stub-addr: 10.20.30.40
|
||||
|
||||
CONFIG_END
|
||||
|
||||
SCENARIO_BEGIN Test RPZ QNAME trigger, loaded using IXFR
|
||||
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 10.20.30.40
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qname qtype
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR AA
|
||||
SECTION QUESTION
|
||||
. IN NS
|
||||
SECTION ANSWER
|
||||
. IN NS ns.
|
||||
SECTION ADDITIONAL
|
||||
ns. IN NS 10.20.30.40
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qname qtype
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR AA
|
||||
SECTION QUESTION
|
||||
b. IN TXT
|
||||
SECTION ANSWER
|
||||
b. TXT "hello from upstream"
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qname qtype
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR AA
|
||||
SECTION QUESTION
|
||||
d. IN TXT
|
||||
SECTION ANSWER
|
||||
d. TXT "hello from upstream"
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qname qtype
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR AA
|
||||
SECTION QUESTION
|
||||
a.rpz-ip. IN A
|
||||
SECTION ANSWER
|
||||
a.rpz-ip. IN A 10.0.123.1
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qname qtype
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR AA
|
||||
SECTION QUESTION
|
||||
c.rpz-ip. IN A
|
||||
SECTION ANSWER
|
||||
c.rpz-ip. IN A 10.0.123.3
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qname qtype
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR AA
|
||||
SECTION QUESTION
|
||||
d.rpz-ip. IN A
|
||||
SECTION ANSWER
|
||||
d.rpz-ip. IN A 10.0.123.4
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qname qtype
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
rpz.example.com. IN SOA
|
||||
SECTION ANSWER
|
||||
rpz.example.com. IN SOA ns.rpz.example.com. hostmaster.rpz.example.com. 2 3600 900 86400 3600
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qname qtype
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
rpz.example.com. IN IXFR
|
||||
SECTION ANSWER
|
||||
rpz.example.com. IN SOA ns.rpz.example.com. hostmaster.rpz.example.com. 2 3600 900 86400 3600
|
||||
rpz.example.com. IN SOA ns.rpz.example.com. hostmaster.rpz.example.com. 1 3600 900 86400 3600
|
||||
a.rpz.example.com. IN CNAME *.
|
||||
c.rpz.example.com. IN TXT "hello from initial RPZ"
|
||||
c.rpz.example.com. IN TXT "another hello from initial RPZ"
|
||||
d.rpz.example.com. IN CNAME .
|
||||
32.1.123.0.10.rpz-ip.rpz.example.com. CNAME *.
|
||||
32.3.123.0.10.rpz-ip.rpz.example.com. A 10.66.0.3
|
||||
32.3.123.0.10.rpz-ip.rpz.example.com. A 10.66.0.4
|
||||
32.4.123.0.10.rpz-ip.rpz.example.com. CNAME .
|
||||
rpz.example.com. IN SOA ns.rpz.example.com. hostmaster.rpz.example.com. 2 3600 900 86400 3600
|
||||
b.rpz.example.com. TXT "hello from RPZ"
|
||||
c.rpz.example.com. TXT "hello from RPZ"
|
||||
a.rpz.example.com. CNAME .
|
||||
32.1.123.0.10.rpz-ip.rpz.example.com. CNAME .
|
||||
32.3.123.0.10.rpz-ip.rpz.example.com. A 10.66.0.5
|
||||
32.3.123.0.10.rpz-ip.rpz.example.com. A 10.66.0.6
|
||||
rpz.example.com. IN SOA ns.rpz.example.com. hostmaster.rpz.example.com. 2 3600 900 86400 3600
|
||||
ENTRY_END
|
||||
|
||||
RANGE_END
|
||||
|
||||
STEP 1 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
b. IN TXT
|
||||
ENTRY_END
|
||||
|
||||
STEP 2 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
b. IN TXT
|
||||
SECTION ANSWER
|
||||
b. IN TXT "hello from upstream"
|
||||
ENTRY_END
|
||||
|
||||
STEP 3 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
a. IN TXT
|
||||
ENTRY_END
|
||||
|
||||
STEP 4 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA AA NOERROR
|
||||
SECTION QUESTION
|
||||
a. IN TXT
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
|
||||
STEP 5 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
a.rpz-ip. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 6 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
a.rpz-ip. IN A
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
|
||||
STEP 7 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
c. IN TXT
|
||||
ENTRY_END
|
||||
|
||||
STEP 8 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA AA NOERROR
|
||||
SECTION QUESTION
|
||||
c. IN TXT
|
||||
SECTION ANSWER
|
||||
c. IN TXT "yet another hello from initial RPZ"
|
||||
c. IN TXT "another hello from initial RPZ"
|
||||
c. IN TXT "hello from initial RPZ"
|
||||
ENTRY_END
|
||||
|
||||
STEP 9 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
c.rpz-ip. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
c.rpz-ip. IN A
|
||||
SECTION ANSWER
|
||||
c.rpz-ip. IN A 10.66.0.4
|
||||
c.rpz-ip. IN A 10.66.0.3
|
||||
ENTRY_END
|
||||
|
||||
STEP 11 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
d. IN TXT
|
||||
ENTRY_END
|
||||
|
||||
STEP 12 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA AA NXDOMAIN
|
||||
SECTION QUESTION
|
||||
d. IN TXT
|
||||
ENTRY_END
|
||||
|
||||
STEP 13 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
d.rpz-ip. IN A
|
||||
ENTRY_END
|
||||
|
||||
|
||||
STEP 15 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NXDOMAIN
|
||||
SECTION QUESTION
|
||||
d.rpz-ip. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 16 TIME_PASSES ELAPSE 1
|
||||
STEP 30 TIME_PASSES ELAPSE 3600
|
||||
STEP 40 TRAFFIC
|
||||
|
||||
STEP 50 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
b. IN TXT
|
||||
ENTRY_END
|
||||
|
||||
STEP 51 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA AA NOERROR
|
||||
SECTION QUESTION
|
||||
b. IN TXT
|
||||
SECTION ANSWER
|
||||
b. IN TXT "hello from RPZ"
|
||||
ENTRY_END
|
||||
|
||||
STEP 52 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
a. IN TXT
|
||||
ENTRY_END
|
||||
|
||||
STEP 53 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA AA NXDOMAIN
|
||||
SECTION QUESTION
|
||||
a. IN TXT
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
|
||||
STEP 54 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
a.rpz-ip. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 55 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NXDOMAIN
|
||||
SECTION QUESTION
|
||||
a.rpz-ip. IN A
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
|
||||
STEP 56 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
c. IN TXT
|
||||
ENTRY_END
|
||||
|
||||
STEP 57 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA AA NOERROR
|
||||
SECTION QUESTION
|
||||
c. IN TXT
|
||||
SECTION ANSWER
|
||||
c. IN TXT "hello from RPZ"
|
||||
c. IN TXT "yet another hello from initial RPZ"
|
||||
ENTRY_END
|
||||
|
||||
STEP 58 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
c.rpz-ip. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 59 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
c.rpz-ip. IN A
|
||||
SECTION ANSWER
|
||||
c.rpz-ip. IN A 10.66.0.6
|
||||
c.rpz-ip. IN A 10.66.0.5
|
||||
ENTRY_END
|
||||
|
||||
STEP 60 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
d. IN TXT
|
||||
ENTRY_END
|
||||
|
||||
STEP 61 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
d. IN TXT
|
||||
SECTION ANSWER
|
||||
d. IN TXT "hello from upstream"
|
||||
ENTRY_END
|
||||
|
||||
STEP 62 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
d.rpz-ip. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 63 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
d.rpz-ip. IN A
|
||||
SECTION ANSWER
|
||||
d.rpz-ip. IN A 10.0.123.4
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
Vendored
+304
@@ -0,0 +1,304 @@
|
||||
; config options
|
||||
server:
|
||||
module-config: "respip validator iterator"
|
||||
target-fetch-policy: "0 0 0 0 0"
|
||||
qname-minimisation: no
|
||||
|
||||
rpz:
|
||||
name: "rpz.example.com."
|
||||
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.
|
||||
a CNAME .
|
||||
a CNAME *. ; duplicate CNAME here on purpose
|
||||
*.a TXT "wildcard local data"
|
||||
b.a CNAME *.
|
||||
c.a CNAME rpz-passthru.
|
||||
TEMPFILE_END
|
||||
|
||||
rpz:
|
||||
name: "rpz2.example.com."
|
||||
zonefile:
|
||||
TEMPFILE_NAME rpz2.example.com
|
||||
TEMPFILE_CONTENTS rpz2.example.com
|
||||
$ORIGIN example.com.
|
||||
rpz2 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 rpz2.example.com.
|
||||
a TXT "local data 2nd zone"
|
||||
d TXT "local data 2nd zone"
|
||||
e CNAME *.a.example.
|
||||
*.e CNAME *.b.example.
|
||||
drop CNAME rpz-drop.
|
||||
TEMPFILE_END
|
||||
|
||||
stub-zone:
|
||||
name: "a."
|
||||
stub-addr: 10.20.30.40
|
||||
stub-zone:
|
||||
name: "example."
|
||||
stub-addr: 10.20.30.50
|
||||
CONFIG_END
|
||||
|
||||
SCENARIO_BEGIN Test all support RPZ action for QNAME trigger
|
||||
|
||||
; a.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 10.20.30.40
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
a. IN NS
|
||||
SECTION ANSWER
|
||||
a. IN NS ns.a.
|
||||
SECTION ADDITIONAL
|
||||
ns.a IN A 10.20.30.40
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
c.a. IN TXT
|
||||
SECTION ANSWER
|
||||
c.a. IN TXT "answer from upstream ns"
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
x.b.a. IN TXT
|
||||
SECTION ANSWER
|
||||
x.b.a. IN TXT "answer from upstream ns"
|
||||
ENTRY_END
|
||||
|
||||
RANGE_END
|
||||
|
||||
; example.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 10.20.30.50
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example. IN NS
|
||||
SECTION ANSWER
|
||||
example. IN NS ns.example.
|
||||
SECTION ADDITIONAL
|
||||
ns.example IN A 10.20.30.50
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
e.a.example. IN TXT
|
||||
SECTION ANSWER
|
||||
e.a.example. IN TXT "e.a.example. answer from upstream ns"
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
something.e.b.example. IN TXT
|
||||
SECTION ANSWER
|
||||
something.e.b.example. IN TXT "*.b.example. answer from upstream ns"
|
||||
ENTRY_END
|
||||
|
||||
RANGE_END
|
||||
|
||||
STEP 10 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
a. IN TXT
|
||||
ENTRY_END
|
||||
|
||||
STEP 11 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA AA NXDOMAIN
|
||||
SECTION QUESTION
|
||||
a. IN TXT
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
|
||||
STEP 20 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
a.a. IN TXT
|
||||
ENTRY_END
|
||||
|
||||
STEP 21 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA AA NOERROR
|
||||
SECTION QUESTION
|
||||
a.a. IN TXT
|
||||
SECTION ANSWER
|
||||
a.a. IN TXT "wildcard local data"
|
||||
ENTRY_END
|
||||
|
||||
STEP 30 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
b.a. IN TXT
|
||||
ENTRY_END
|
||||
|
||||
STEP 31 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA AA NOERROR
|
||||
SECTION QUESTION
|
||||
b.a. IN TXT
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
|
||||
STEP 40 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
x.a. IN TXT
|
||||
ENTRY_END
|
||||
|
||||
STEP 41 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA AA NOERROR
|
||||
SECTION QUESTION
|
||||
x.a. IN TXT
|
||||
SECTION ANSWER
|
||||
x.a. IN TXT "wildcard local data"
|
||||
ENTRY_END
|
||||
|
||||
STEP 50 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
x.a.a. IN TXT
|
||||
ENTRY_END
|
||||
|
||||
STEP 51 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA AA NOERROR
|
||||
SECTION QUESTION
|
||||
x.a.a. IN TXT
|
||||
SECTION ANSWER
|
||||
x.a.a. IN TXT "wildcard local data"
|
||||
ENTRY_END
|
||||
|
||||
STEP 60 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
c.a. IN TXT
|
||||
ENTRY_END
|
||||
|
||||
STEP 61 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
c.a. IN TXT
|
||||
SECTION ANSWER
|
||||
c.a. IN TXT "answer from upstream ns"
|
||||
ENTRY_END
|
||||
|
||||
STEP 70 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
x.b.a. IN TXT
|
||||
ENTRY_END
|
||||
|
||||
STEP 71 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
x.b.a. IN TXT
|
||||
SECTION ANSWER
|
||||
x.b.a. IN TXT "answer from upstream ns"
|
||||
ENTRY_END
|
||||
|
||||
STEP 80 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
d. IN TXT
|
||||
ENTRY_END
|
||||
|
||||
STEP 81 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA AA NOERROR
|
||||
SECTION QUESTION
|
||||
d. IN TXT
|
||||
SECTION ANSWER
|
||||
d. IN TXT "local data 2nd zone"
|
||||
ENTRY_END
|
||||
|
||||
STEP 82 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
e. IN TXT
|
||||
ENTRY_END
|
||||
|
||||
STEP 83 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA AA NOERROR
|
||||
SECTION QUESTION
|
||||
e. IN TXT
|
||||
SECTION ANSWER
|
||||
e. IN CNAME e.a.example.
|
||||
e.a.example. IN TXT "e.a.example. answer from upstream ns"
|
||||
ENTRY_END
|
||||
|
||||
STEP 84 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
something.e. IN TXT
|
||||
ENTRY_END
|
||||
|
||||
STEP 85 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA AA NOERROR
|
||||
SECTION QUESTION
|
||||
something.e. IN TXT
|
||||
SECTION ANSWER
|
||||
something.e. IN CNAME something.e.b.example.
|
||||
something.e.b.example. IN TXT "*.b.example. answer from upstream ns"
|
||||
ENTRY_END
|
||||
|
||||
; deny zone
|
||||
STEP 90 QUERY
|
||||
ENTRY_BEGIN
|
||||
SECTION QUESTION
|
||||
drop. IN TXT
|
||||
ENTRY_END
|
||||
; no answer is checked at exit of testbound.
|
||||
SCENARIO_END
|
||||
Vendored
+197
@@ -0,0 +1,197 @@
|
||||
; config options
|
||||
server:
|
||||
module-config: "respip validator iterator"
|
||||
target-fetch-policy: "0 0 0 0 0"
|
||||
qname-minimisation: no
|
||||
|
||||
rpz:
|
||||
name: "rpz.example.com."
|
||||
rpz-action-override: disabled
|
||||
zonefile:
|
||||
TEMPFILE_NAME rpz.example.com
|
||||
TEMPFILE_CONTENTS rpz.example.com
|
||||
$ORIGIN rpz.example.com.
|
||||
a TXT "record zone rpz.example.com"
|
||||
TEMPFILE_END
|
||||
|
||||
rpz:
|
||||
name: "rpz2.example.com."
|
||||
zonefile:
|
||||
TEMPFILE_NAME rpz2.example.com
|
||||
TEMPFILE_CONTENTS rpz2.example.com
|
||||
$ORIGIN rpz2.example.com.
|
||||
a TXT "record zone rpz2.example.com"
|
||||
TEMPFILE_END
|
||||
|
||||
rpz:
|
||||
name: "rpz3.example.com."
|
||||
rpz-action-override: nodata
|
||||
zonefile:
|
||||
TEMPFILE_NAME rpz3.example.com
|
||||
TEMPFILE_CONTENTS rpz3.example.com
|
||||
$ORIGIN rpz3.example.com.
|
||||
b CNAME .
|
||||
TEMPFILE_END
|
||||
|
||||
rpz:
|
||||
name: "rpz4.example.com."
|
||||
rpz-action-override: nxdomain
|
||||
zonefile:
|
||||
TEMPFILE_NAME rpz4.example.com
|
||||
TEMPFILE_CONTENTS rpz4.example.com
|
||||
$ORIGIN rpz4.example.com.
|
||||
c CNAME *.
|
||||
TEMPFILE_END
|
||||
|
||||
rpz:
|
||||
name: "rpz5.example.com."
|
||||
rpz-action-override: passthru
|
||||
zonefile:
|
||||
TEMPFILE_NAME rpz5.example.com
|
||||
TEMPFILE_CONTENTS rpz5.example.com
|
||||
$ORIGIN rpz5.example.com.
|
||||
d TXT "should be override by passthru"
|
||||
TEMPFILE_END
|
||||
|
||||
rpz:
|
||||
name: "rpz6.example.com."
|
||||
rpz-action-override: cname
|
||||
rpz-cname-override: "d."
|
||||
zonefile:
|
||||
TEMPFILE_NAME rpz6.example.com
|
||||
TEMPFILE_CONTENTS rpz6.example.com
|
||||
$ORIGIN rpz6.example.com.
|
||||
e TXT "should be override by cname"
|
||||
TEMPFILE_END
|
||||
|
||||
rpz:
|
||||
name: "rpz7.example.com."
|
||||
rpz-action-override: drop
|
||||
zonefile:
|
||||
TEMPFILE_NAME rpz7.example.com
|
||||
TEMPFILE_CONTENTS rpz7.example.com
|
||||
$ORIGIN rpz7.example.com.
|
||||
f TXT "should be override by drop policy"
|
||||
TEMPFILE_END
|
||||
|
||||
stub-zone:
|
||||
name: "d."
|
||||
stub-addr: 10.20.30.40
|
||||
CONFIG_END
|
||||
|
||||
SCENARIO_BEGIN Test RPZ action overrides for QNAME trigger
|
||||
|
||||
; d.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 10.20.30.40
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
d. IN TXT
|
||||
SECTION ANSWER
|
||||
d. IN TXT "answer from upstream ns"
|
||||
ENTRY_END
|
||||
|
||||
RANGE_END
|
||||
|
||||
; check disabled override, should be answered using next policy zone
|
||||
STEP 10 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
a. IN TXT
|
||||
ENTRY_END
|
||||
|
||||
STEP 11 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA AA NOERROR
|
||||
SECTION QUESTION
|
||||
a. IN TXT
|
||||
SECTION ANSWER
|
||||
a TXT "record zone rpz2.example.com"
|
||||
ENTRY_END
|
||||
|
||||
; check nodata override, would be NXDOMAIN without override
|
||||
STEP 20 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
b. IN TXT
|
||||
ENTRY_END
|
||||
|
||||
STEP 21 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA AA NOERROR
|
||||
SECTION QUESTION
|
||||
b. IN TXT
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
|
||||
; check nxdomain override, would be NODATA without override
|
||||
STEP 30 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
c. IN TXT
|
||||
ENTRY_END
|
||||
|
||||
STEP 31 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA AA NXDOMAIN
|
||||
SECTION QUESTION
|
||||
c. IN TXT
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
|
||||
; check passthru override, would be localdata without override
|
||||
STEP 40 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
d. IN TXT
|
||||
ENTRY_END
|
||||
|
||||
STEP 41 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
d. IN TXT
|
||||
SECTION ANSWER
|
||||
d. IN TXT "answer from upstream ns"
|
||||
ENTRY_END
|
||||
|
||||
; check cname override, would be localdata without override
|
||||
STEP 50 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
e. IN TXT
|
||||
ENTRY_END
|
||||
|
||||
STEP 51 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA AA NOERROR
|
||||
SECTION QUESTION
|
||||
e. IN TXT
|
||||
SECTION ANSWER
|
||||
e. IN CNAME d.
|
||||
d. IN TXT "answer from upstream ns"
|
||||
ENTRY_END
|
||||
|
||||
; check drop override, would be localdata without override
|
||||
STEP 60 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
f. IN TXT
|
||||
ENTRY_END
|
||||
; no answer is checked at exit of testbound.
|
||||
|
||||
SCENARIO_END
|
||||
Vendored
+449
@@ -0,0 +1,449 @@
|
||||
; config options
|
||||
server:
|
||||
module-config: "respip validator iterator"
|
||||
target-fetch-policy: "0 0 0 0 0"
|
||||
qname-minimisation: no
|
||||
|
||||
|
||||
rpz:
|
||||
name: "rpz.example.com."
|
||||
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.
|
||||
8.0.0.0.10.rpz-ip CNAME *.
|
||||
16.0.0.10.10.rpz-ip CNAME .
|
||||
24.0.10.10.10.rpz-ip CNAME rpz-drop.
|
||||
32.10.10.10.10.rpz-ip CNAME rpz-passthru.
|
||||
32.zz.db8.2001.rpz-ip CNAME *.
|
||||
48.zz.aa.db8.2001.rpz-ip CNAME .
|
||||
64.zz.bb.aa.db8.2001.rpz-ip CNAME rpz-drop.
|
||||
128.1.zz.cc.bb.aa.db8.2001.rpz-ip CNAME rpz-passthru.
|
||||
128.123.zz.cc.bb.aa.db8.2001.rpz-ip AAAA 2001:db8::123
|
||||
128.124.0.0.cc.bb.aa.db8.2001.rpz-ip AAAA 2001:db8::124
|
||||
|
||||
TEMPFILE_END
|
||||
|
||||
rpz:
|
||||
name: "rpz2.example.com."
|
||||
zonefile:
|
||||
TEMPFILE_NAME rpz2.example.com
|
||||
TEMPFILE_CONTENTS rpz2.example.com
|
||||
$ORIGIN example.com.
|
||||
rpz2 3600 IN SOA ns1.rpz2.example.com. hostmaster.rpz2.example.com. (
|
||||
1379078166 28800 7200 604800 7200 )
|
||||
3600 IN NS ns1.rpz2.example.com.
|
||||
3600 IN NS ns2.rpz2.example.com.
|
||||
$ORIGIN rpz2.example.com.
|
||||
32.10.10.10.10.rpz-ip A 203.0.113.123
|
||||
32.123.2.0.192.rpz-ip A 203.0.113.123
|
||||
128.1.zz.cc.bb.aa.db8.2001.rpz-ip AAAA 2001:db1::123
|
||||
TEMPFILE_END
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
stub-addr: 10.20.30.40
|
||||
CONFIG_END
|
||||
|
||||
SCENARIO_BEGIN Test all supported RPZ action for response IP address trigger
|
||||
|
||||
; c.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 10.20.30.40
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
. IN NS
|
||||
SECTION ANSWER
|
||||
. IN NS ns.
|
||||
SECTION ADDITIONAL
|
||||
ns. IN A 10.20.30.40
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
a. IN A
|
||||
SECTION ANSWER
|
||||
a. IN A 10.0.0.123
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
a. IN AAAA
|
||||
SECTION ANSWER
|
||||
a. IN AAAA 2001:db8::123
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
b. IN A
|
||||
SECTION ANSWER
|
||||
b. IN A 10.1.0.123
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
b. IN AAAA
|
||||
SECTION ANSWER
|
||||
b. IN AAAA 2001:db8:1::123
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
c. IN A
|
||||
SECTION ANSWER
|
||||
c. IN A 10.11.0.123
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
c. IN AAAA
|
||||
SECTION ANSWER
|
||||
c. IN AAAA 2001:db8:ff::123
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
d. IN A
|
||||
SECTION ANSWER
|
||||
d. IN A 10.10.0.123
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
d. IN AAAA
|
||||
SECTION ANSWER
|
||||
d. IN AAAA 2001:db8:aa::123
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
e. IN A
|
||||
SECTION ANSWER
|
||||
e. IN A 10.10.10.123
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
e. IN AAAA
|
||||
SECTION ANSWER
|
||||
e. IN AAAA 2001:db8:aa:bb::123
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
f. IN A
|
||||
SECTION ANSWER
|
||||
f. IN A 10.10.10.10
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
f. IN AAAA
|
||||
SECTION ANSWER
|
||||
f. IN AAAA 2001:db8:aa:bb:cc::1
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
g. IN A
|
||||
SECTION ANSWER
|
||||
g. IN A 192.0.2.123
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
g. IN AAAA
|
||||
SECTION ANSWER
|
||||
g. IN AAAA 2001:db8:aa:bb:cc::123
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
h. IN AAAA
|
||||
SECTION ANSWER
|
||||
h. IN AAAA 2001:db8:aa:bb:cc::124
|
||||
ENTRY_END
|
||||
|
||||
RANGE_END
|
||||
|
||||
STEP 1 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
a. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 2 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
a. IN A
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
|
||||
STEP 3 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
a. IN AAAA
|
||||
ENTRY_END
|
||||
|
||||
STEP 4 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
a. IN AAAA
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
|
||||
STEP 5 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
b. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 6 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
b. IN A
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
|
||||
STEP 7 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
b. IN AAAA
|
||||
ENTRY_END
|
||||
|
||||
STEP 8 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
b. IN AAAA
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
|
||||
STEP 9 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
c. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
c. IN A
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
|
||||
STEP 11 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
c. IN AAAA
|
||||
ENTRY_END
|
||||
|
||||
STEP 12 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
c. IN AAAA
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
|
||||
STEP 13 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
d. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 14 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NXDOMAIN
|
||||
SECTION QUESTION
|
||||
d. IN A
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
|
||||
STEP 15 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
d. IN AAAA
|
||||
ENTRY_END
|
||||
|
||||
STEP 16 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NXDOMAIN
|
||||
SECTION QUESTION
|
||||
d. IN AAAA
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
|
||||
STEP 17 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
f. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 18 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
f. IN A
|
||||
SECTION ANSWER
|
||||
f. IN A 10.10.10.10
|
||||
ENTRY_END
|
||||
|
||||
STEP 19 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
f. IN AAAA
|
||||
ENTRY_END
|
||||
|
||||
STEP 20 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
f. IN AAAA
|
||||
SECTION ANSWER
|
||||
f. IN AAAA 2001:db8:aa:bb:cc::1
|
||||
ENTRY_END
|
||||
|
||||
STEP 21 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
g. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 22 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
g. IN A
|
||||
SECTION ANSWER
|
||||
g. IN A 203.0.113.123
|
||||
ENTRY_END
|
||||
|
||||
STEP 23 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
g. IN AAAA
|
||||
ENTRY_END
|
||||
|
||||
STEP 24 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
g. IN AAAA
|
||||
SECTION ANSWER
|
||||
g. IN AAAA 2001:db8::123
|
||||
ENTRY_END
|
||||
|
||||
STEP 25 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
h. IN AAAA
|
||||
ENTRY_END
|
||||
|
||||
STEP 26 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
h. IN AAAA
|
||||
SECTION ANSWER
|
||||
h. IN AAAA 2001:db8::124
|
||||
ENTRY_END
|
||||
|
||||
; should be dropped
|
||||
STEP 27 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
e. IN A
|
||||
ENTRY_END
|
||||
STEP 28 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
e. IN AAAA
|
||||
ENTRY_END
|
||||
STEP 29 TIME_PASSES ELAPSE 12
|
||||
SCENARIO_END
|
||||
Vendored
+265
@@ -0,0 +1,265 @@
|
||||
; config options
|
||||
server:
|
||||
module-config: "respip validator iterator"
|
||||
target-fetch-policy: "0 0 0 0 0"
|
||||
qname-minimisation: no
|
||||
|
||||
rpz:
|
||||
name: "rpz.example.com."
|
||||
rpz-action-override: disabled
|
||||
zonefile:
|
||||
TEMPFILE_NAME rpz.example.com
|
||||
TEMPFILE_CONTENTS rpz.example.com
|
||||
$ORIGIN rpz.example.com.
|
||||
32.1.113.0.203.rpz-ip A 192.0.2.1
|
||||
TEMPFILE_END
|
||||
|
||||
rpz:
|
||||
name: "rpz2.example.com."
|
||||
zonefile:
|
||||
TEMPFILE_NAME rpz2.example.com
|
||||
TEMPFILE_CONTENTS rpz2.example.com
|
||||
$ORIGIN rpz2.example.com.
|
||||
32.1.113.0.203.rpz-ip A 192.0.2.2
|
||||
TEMPFILE_END
|
||||
|
||||
rpz:
|
||||
name: "rpz3.example.com."
|
||||
rpz-action-override: nodata
|
||||
zonefile:
|
||||
TEMPFILE_NAME rpz3.example.com
|
||||
TEMPFILE_CONTENTS rpz3.example.com
|
||||
$ORIGIN rpz3.example.com.
|
||||
32.3.113.0.203.rpz-ip CNAME .
|
||||
TEMPFILE_END
|
||||
|
||||
rpz:
|
||||
name: "rpz4.example.com."
|
||||
rpz-action-override: nxdomain
|
||||
zonefile:
|
||||
TEMPFILE_NAME rpz4.example.com
|
||||
TEMPFILE_CONTENTS rpz4.example.com
|
||||
$ORIGIN rpz4.example.com.
|
||||
32.4.113.0.203.rpz-ip CNAME *.
|
||||
TEMPFILE_END
|
||||
|
||||
rpz:
|
||||
name: "rpz5.example.com."
|
||||
rpz-action-override: passthru
|
||||
zonefile:
|
||||
TEMPFILE_NAME rpz5.example.com
|
||||
TEMPFILE_CONTENTS rpz5.example.com
|
||||
$ORIGIN rpz5.example.com.
|
||||
32.5.113.0.203.rpz-ip A 192.0.2.5
|
||||
TEMPFILE_END
|
||||
|
||||
rpz:
|
||||
name: "rpz6.example.com."
|
||||
rpz-action-override: cname
|
||||
rpz-cname-override: ns.
|
||||
zonefile:
|
||||
TEMPFILE_NAME rpz6.example.com
|
||||
TEMPFILE_CONTENTS rpz6.example.com
|
||||
$ORIGIN rpz6.example.com.
|
||||
32.6.113.0.203.rpz-ip A 192.0.2.6
|
||||
TEMPFILE_END
|
||||
|
||||
rpz:
|
||||
name: "rpz7.example.com."
|
||||
rpz-action-override: drop
|
||||
zonefile:
|
||||
TEMPFILE_NAME rpz7.example.com
|
||||
TEMPFILE_CONTENTS rpz7.example.com
|
||||
$ORIGIN rpz7.example.com.
|
||||
32.7.113.0.203.rpz-ip A 192.0.2.7
|
||||
TEMPFILE_END
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
stub-addr: 10.20.30.40
|
||||
CONFIG_END
|
||||
|
||||
SCENARIO_BEGIN Test all supported RPZ action for response IP address trigger
|
||||
|
||||
; c.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 10.20.30.40
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
. IN NS
|
||||
SECTION ANSWER
|
||||
. IN NS ns.
|
||||
SECTION ADDITIONAL
|
||||
ns. IN A 10.20.30.40
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
ns. IN A
|
||||
SECTION ANSWER
|
||||
ns. IN A 10.20.30.40
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
a. IN A
|
||||
SECTION ANSWER
|
||||
a. IN A 203.0.113.1
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
b. IN A
|
||||
SECTION ANSWER
|
||||
b. IN A 203.0.113.3
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
c. IN A
|
||||
SECTION ANSWER
|
||||
c. IN A 203.0.113.4
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
d. IN A
|
||||
SECTION ANSWER
|
||||
d. IN A 203.0.113.5
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
e. IN A
|
||||
SECTION ANSWER
|
||||
e. IN A 203.0.113.6
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
f. IN A
|
||||
SECTION ANSWER
|
||||
f. IN A 203.0.113.7
|
||||
ENTRY_END
|
||||
|
||||
RANGE_END
|
||||
|
||||
STEP 1 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
a. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 2 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
a. IN A
|
||||
SECTION ANSWER
|
||||
a. IN A 192.0.2.2
|
||||
ENTRY_END
|
||||
|
||||
STEP 3 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
b. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 4 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
b. IN A
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
|
||||
STEP 5 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
c. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 6 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NXDOMAIN
|
||||
SECTION QUESTION
|
||||
c. IN A
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
|
||||
STEP 7 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
d. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 8 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
d. IN A
|
||||
SECTION ANSWER
|
||||
d. IN A 203.0.113.5
|
||||
ENTRY_END
|
||||
|
||||
STEP 9 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
e. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
e. IN A
|
||||
SECTION ANSWER
|
||||
e. IN CNAME ns.
|
||||
ns. IN A 10.20.30.40
|
||||
ENTRY_END
|
||||
|
||||
STEP 11 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
f. IN A
|
||||
ENTRY_END
|
||||
; no answer is checked at exit of testbound.
|
||||
|
||||
STEP 12 TIME_PASSES ELAPSE 10
|
||||
|
||||
SCENARIO_END
|
||||
Vendored
+122
@@ -0,0 +1,122 @@
|
||||
; config options
|
||||
server:
|
||||
module-config: "validator iterator"
|
||||
qname-minimisation: "no"
|
||||
minimal-responses: no
|
||||
serve-expired: yes
|
||||
access-control: 127.0.0.1/32 allow_snoop
|
||||
|
||||
stub-zone:
|
||||
name: "example.com"
|
||||
stub-addr: 1.2.3.4
|
||||
CONFIG_END
|
||||
|
||||
SCENARIO_BEGIN Test serve-expired
|
||||
; Scenario overview:
|
||||
; - query for example.com. IN A
|
||||
; - check that we get an answer for example.com. IN A with the correct TTL
|
||||
; - query again (without the RD bit) right after the TTL expired
|
||||
; - check that we get the expired cached answer (this should trigger prefetching)
|
||||
; - query with RD bit and check that the cached record was updated
|
||||
|
||||
; ns.example.com.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 1.2.3.4
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN NS
|
||||
SECTION ANSWER
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
example.com. 10 IN A 5.6.7.8
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; Query with RD flag
|
||||
STEP 1 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
; Check that we got the correct answer (should be cached)
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
example.com. 10 IN A 5.6.7.8
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; Wait for the TTL to expire
|
||||
STEP 11 TIME_PASSES ELAPSE 3601
|
||||
|
||||
; Query again without RD bit
|
||||
STEP 30 QUERY
|
||||
ENTRY_BEGIN
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
; Check that we got a stale answer
|
||||
STEP 40 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RA NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
example.com. 30 IN A 5.6.7.8
|
||||
SECTION AUTHORITY
|
||||
example.com. 30 IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. 30 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; Query with RD bit (the record should have been prefetched)
|
||||
STEP 50 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 60 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
example.com. 10 IN A 5.6.7.8
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
+127
@@ -0,0 +1,127 @@
|
||||
; config options
|
||||
server:
|
||||
module-config: "validator iterator"
|
||||
qname-minimisation: "no"
|
||||
minimal-responses: no
|
||||
serve-expired: yes
|
||||
serve-expired-client-timeout: 1
|
||||
serve-expired-reply-ttl: 123
|
||||
|
||||
stub-zone:
|
||||
name: "example.com"
|
||||
stub-addr: 1.2.3.4
|
||||
CONFIG_END
|
||||
|
||||
SCENARIO_BEGIN Test serve-expired with client-timeout and reply-ttl
|
||||
; Scenario overview:
|
||||
; - query for example.com. IN A
|
||||
; - check that we get an answer for example.com. IN A with the correct TTL
|
||||
; - query again right after the TTL expired
|
||||
; - check that we get the expired cached answer with the configured reply ttl
|
||||
|
||||
; ns.example.com.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 1.2.3.4
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN NS
|
||||
SECTION ANSWER
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; ns.example.com.
|
||||
RANGE_BEGIN 0 20
|
||||
ADDRESS 1.2.3.4
|
||||
; response to A query
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
example.com. 10 IN A 5.6.7.8
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; Query with RD flag
|
||||
STEP 1 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
; Check that we got the correct answer (should be cached)
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
example.com. 10 IN A 5.6.7.8
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; Wait for the TTL to expire
|
||||
STEP 11 TIME_PASSES ELAPSE 3600
|
||||
|
||||
; Query again
|
||||
STEP 30 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
; Allow the client timer to expire
|
||||
STEP 31 TIME_PASSES ELAPSE 1
|
||||
|
||||
; Check that we got a stale answer
|
||||
STEP 40 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
example.com. 123 IN A 5.6.7.8
|
||||
SECTION AUTHORITY
|
||||
example.com. 123 IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. 123 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; Reply to the outstanding query so that the test doesn't fail with
|
||||
; pending messages.
|
||||
STEP 41 REPLY
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
; authoritative answer
|
||||
REPLY QR AA RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
example.com. 3600 IN A 5.6.7.8
|
||||
SECTION AUTHORITY
|
||||
example.com. 3600 IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. 3600 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
Vendored
+103
@@ -0,0 +1,103 @@
|
||||
; config options
|
||||
server:
|
||||
module-config: "validator iterator"
|
||||
qname-minimisation: "no"
|
||||
minimal-responses: no
|
||||
serve-expired: yes
|
||||
serve-expired-reply-ttl: 123
|
||||
|
||||
stub-zone:
|
||||
name: "example.com"
|
||||
stub-addr: 1.2.3.4
|
||||
CONFIG_END
|
||||
|
||||
SCENARIO_BEGIN Test serve-expired with reply-ttl
|
||||
; Scenario overview:
|
||||
; - query for example.com. IN A
|
||||
; - check that we get an answer for example.com. IN A with the correct TTL
|
||||
; - query again right after the TTL expired
|
||||
; - check that we get the expired cached answer with the configured TTL
|
||||
|
||||
; ns.example.com.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 1.2.3.4
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN NS
|
||||
SECTION ANSWER
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
example.com. 10 IN A 5.6.7.8
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; Query with RD flag
|
||||
STEP 1 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
; Check that we got the correct answer (should be cached)
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
example.com. 10 IN A 5.6.7.8
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; Wait for the TTL to expire
|
||||
STEP 11 TIME_PASSES ELAPSE 3601
|
||||
|
||||
; Query again
|
||||
STEP 30 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
; Check that we got a stale answer
|
||||
STEP 40 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
example.com. 123 A 5.6.7.8
|
||||
SECTION AUTHORITY
|
||||
example.com. 123 NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. 123 A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; Give time for the pending query to get answered
|
||||
STEP 41 TRAFFIC
|
||||
|
||||
SCENARIO_END
|
||||
Vendored
+117
@@ -0,0 +1,117 @@
|
||||
; config options
|
||||
server:
|
||||
module-config: "validator iterator"
|
||||
qname-minimisation: "no"
|
||||
minimal-responses: no
|
||||
serve-expired: yes
|
||||
serve-expired-client-timeout: 1800
|
||||
serve-expired-reply-ttl: 123
|
||||
log-servfail: yes
|
||||
|
||||
|
||||
stub-zone:
|
||||
name: "example.com"
|
||||
stub-addr: 1.2.3.4
|
||||
CONFIG_END
|
||||
|
||||
SCENARIO_BEGIN Test serve-expired with client-timeout and a SERVFAIL upstream reply
|
||||
; Scenario overview:
|
||||
; - query for example.com. IN A
|
||||
; - check that we get an answer for example.com. IN A with the correct TTL
|
||||
; - query again right after the TTL expired
|
||||
; - answer from upstream is servfail
|
||||
; - check that we get the expired cached answer instead
|
||||
|
||||
; ns.example.com.
|
||||
RANGE_BEGIN 0 20
|
||||
ADDRESS 1.2.3.4
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN NS
|
||||
SECTION ANSWER
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
example.com. 10 IN A 5.6.7.8
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; ns.example.com.
|
||||
RANGE_BEGIN 30 100
|
||||
ADDRESS 1.2.3.4
|
||||
; response to A query
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA SERVFAIL
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; Query with RD flag
|
||||
STEP 1 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
; Check that we got the correct answer (should be cached)
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
example.com. 10 IN A 5.6.7.8
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; Wait for the TTL to expire
|
||||
STEP 11 TIME_PASSES ELAPSE 3601
|
||||
|
||||
; Query again
|
||||
STEP 30 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
; Check that we got a stale answer
|
||||
STEP 40 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
example.com. 123 IN A 5.6.7.8
|
||||
SECTION AUTHORITY
|
||||
example.com. 123 IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. 123 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
Vendored
+100
@@ -0,0 +1,100 @@
|
||||
; config options
|
||||
server:
|
||||
module-config: "validator iterator"
|
||||
qname-minimisation: "no"
|
||||
minimal-responses: no
|
||||
serve-expired: yes
|
||||
serve-expired-ttl: 10
|
||||
|
||||
stub-zone:
|
||||
name: "example.com"
|
||||
stub-addr: 1.2.3.4
|
||||
CONFIG_END
|
||||
|
||||
SCENARIO_BEGIN Test serve-expired
|
||||
; Scenario overview:
|
||||
; - query for example.com. IN A
|
||||
; - check that we get an answer for example.com. IN A with the correct TTL
|
||||
; - query again right after the TTL expired + serve-expired-ttl
|
||||
; - check that we get an updated answer and not the cached one
|
||||
|
||||
; ns.example.com.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 1.2.3.4
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN NS
|
||||
SECTION ANSWER
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
example.com. IN A 5.6.7.8
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; Query with RD flag
|
||||
STEP 1 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
; Check that we got the correct answer (should be cached)
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
example.com. IN A 5.6.7.8
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; Wait for the TTL to expire + serve-expired-ttl
|
||||
STEP 11 TIME_PASSES ELAPSE 3611
|
||||
|
||||
; Query again
|
||||
STEP 30 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
; Check that we got an updated answer
|
||||
STEP 40 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
example.com. IN A 5.6.7.8
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
+128
@@ -0,0 +1,128 @@
|
||||
; config options
|
||||
server:
|
||||
module-config: "validator iterator"
|
||||
qname-minimisation: "no"
|
||||
minimal-responses: no
|
||||
serve-expired: yes
|
||||
serve-expired-ttl: 10
|
||||
serve-expired-client-timeout: 1
|
||||
|
||||
stub-zone:
|
||||
name: "example.com"
|
||||
stub-addr: 1.2.3.4
|
||||
CONFIG_END
|
||||
|
||||
SCENARIO_BEGIN Test serve-expired
|
||||
; Scenario overview:
|
||||
; - query for example.com. IN A
|
||||
; - check that we get an answer for example.com. IN A with the correct TTL
|
||||
; - query again right after the TTL expired + serve-expired-ttl
|
||||
; - check that we get an updated answer and not the cached one
|
||||
|
||||
; ns.example.com.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 1.2.3.4
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN NS
|
||||
SECTION ANSWER
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; ns.example.com.
|
||||
RANGE_BEGIN 0 20
|
||||
ADDRESS 1.2.3.4
|
||||
; response to A query
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
example.com. IN A 5.6.7.8
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; Query with RD flag
|
||||
STEP 1 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
; Check that we got the correct answer (should be cached)
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
example.com. IN A 5.6.7.8
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; Wait for the TTL to expire + serve-expired-ttl
|
||||
STEP 11 TIME_PASSES ELAPSE 3611
|
||||
|
||||
; Query again
|
||||
STEP 30 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
; Allow the client timer to expire
|
||||
STEP 31 TIME_PASSES ELAPSE 1
|
||||
|
||||
; We shouldn't get a reply here.
|
||||
; There is cached data but serve-expired-ttl has passed.
|
||||
|
||||
STEP 40 REPLY
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
; authoritative answer
|
||||
REPLY QR AA RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
example.com. 3600 IN A 5.6.7.8
|
||||
SECTION AUTHORITY
|
||||
example.com. 3600 IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. 3600 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; Check that we got the updated answer
|
||||
STEP 41 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
example.com. IN A 5.6.7.8
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
Vendored
+154
@@ -0,0 +1,154 @@
|
||||
; config options
|
||||
server:
|
||||
module-config: "validator iterator"
|
||||
qname-minimisation: "no"
|
||||
minimal-responses: no
|
||||
serve-expired: yes
|
||||
serve-expired-reply-ttl: 123
|
||||
|
||||
stub-zone:
|
||||
name: "example.com"
|
||||
stub-addr: 1.2.3.4
|
||||
CONFIG_END
|
||||
|
||||
SCENARIO_BEGIN Test 0 TLL with serve-expired
|
||||
; Scenario overview:
|
||||
; - query for example.com. IN A
|
||||
; - check that we get an answer for example.com. IN A with the correct 0 TTL
|
||||
; - query again; this time the answer has >0 TTL
|
||||
; - check the answer
|
||||
; - query one last time after expiration
|
||||
; - check that the configured reply ttl is used
|
||||
|
||||
; ns.example.com.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 1.2.3.4
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN NS
|
||||
SECTION ANSWER
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
RANGE_BEGIN 0 10
|
||||
ADDRESS 1.2.3.4
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
example.com. 0 IN A 5.6.7.8
|
||||
SECTION AUTHORITY
|
||||
example.com. 0 IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. 0 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
RANGE_BEGIN 11 100
|
||||
ADDRESS 1.2.3.4
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
example.com. 10 IN A 5.6.7.8
|
||||
SECTION AUTHORITY
|
||||
example.com. 10 IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. 10 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; Let some time to pass so that timenow > 0
|
||||
STEP 1 TIME_PASSES ELAPSE 3600
|
||||
|
||||
; Query with RD flag
|
||||
STEP 2 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
; Check that we got the correct answer with 0 TTL
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
example.com. 0 IN A 5.6.7.8
|
||||
SECTION AUTHORITY
|
||||
example.com. 0 IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. 0 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; Let some time to pass
|
||||
STEP 11 TIME_PASSES ELAPSE 1
|
||||
|
||||
; Query with RD flag
|
||||
STEP 20 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
; Check that we got the correct answer
|
||||
STEP 29 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
example.com. 10 IN A 5.6.7.8
|
||||
SECTION AUTHORITY
|
||||
example.com. 10 IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. 10 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; Wait for the TTL to expire
|
||||
STEP 30 TIME_PASSES ELAPSE 11
|
||||
|
||||
; Query with RD flag
|
||||
STEP 40 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
; Check that we got the correct answer
|
||||
STEP 49 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
example.com. 123 IN A 5.6.7.8
|
||||
SECTION AUTHORITY
|
||||
example.com. 123 IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. 123 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; Give time for the pending query to get answered
|
||||
STEP 50 TRAFFIC
|
||||
|
||||
SCENARIO_END
|
||||
Vendored
+2
@@ -10,6 +10,8 @@ server:
|
||||
max-client-subnet-ipv4: 17
|
||||
module-config: "subnetcache validator iterator"
|
||||
verbosity: 3
|
||||
fake-sha1: yes
|
||||
fake-dsa: yes
|
||||
access-control: 127.0.0.1 allow_snoop
|
||||
qname-minimisation: "no"
|
||||
minimal-responses: no
|
||||
|
||||
Vendored
+2
@@ -9,6 +9,8 @@ server:
|
||||
max-client-subnet-ipv4: 17
|
||||
module-config: "subnetcache validator iterator"
|
||||
verbosity: 3
|
||||
fake-sha1: yes
|
||||
fake-dsa: yes
|
||||
qname-minimisation: "no"
|
||||
minimal-responses: no
|
||||
|
||||
|
||||
+2
@@ -10,6 +10,8 @@ server:
|
||||
max-client-subnet-ipv4: 17
|
||||
module-config: "subnetcache validator iterator"
|
||||
verbosity: 3
|
||||
fake-sha1: yes
|
||||
fake-dsa: yes
|
||||
qname-minimisation: "no"
|
||||
minimal-responses: no
|
||||
|
||||
|
||||
+27
@@ -95,6 +95,33 @@ else
|
||||
echo "result contents not OK"
|
||||
exit 1
|
||||
fi
|
||||
echo "OK"
|
||||
|
||||
# check that the server is still up
|
||||
echo ""
|
||||
echo "> query www1.example.net. (again check if server up)"
|
||||
$PRE/streamtcp -f 127.0.0.1@$UNBOUND_PORT www1.example.net. A IN >outfile 2>&1
|
||||
cat outfile
|
||||
if test "$?" -ne 0; then
|
||||
echo "exit status not OK"
|
||||
echo "> cat logfiles"
|
||||
cat outfile
|
||||
cat fwd.log
|
||||
cat unbound.log
|
||||
echo "Not OK"
|
||||
exit 1
|
||||
fi
|
||||
if grep "www1.example.net" outfile | grep "1.2.3.1"; then
|
||||
echo "content OK"
|
||||
else
|
||||
echo "result contents not OK"
|
||||
echo "> cat logfiles"
|
||||
cat outfile
|
||||
cat fwd.log
|
||||
cat unbound.log
|
||||
echo "result contents not OK"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "OK"
|
||||
exit 0
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user