mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-08-17 21:25:50 +02:00
Compare commits
352
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b06fed6378 | ||
|
|
95ee34bd2b | ||
|
|
5fe503c864 | ||
|
|
b25332e1f4 | ||
|
|
a6ec2c6fc7 | ||
|
|
9cb404ba5f | ||
|
|
12251022ec | ||
|
|
00a0cabf7f | ||
|
|
d6ed0e868f | ||
|
|
700ad78f10 | ||
|
|
d65accbb23 | ||
|
|
78767f2014 | ||
|
|
21af42a281 | ||
|
|
0b0ece9db0 | ||
|
|
23edc18cac | ||
|
|
7153c94bd7 | ||
|
|
4df697b4b7 | ||
|
|
7fd32916e8 | ||
|
|
3f837bc440 | ||
|
|
f0769bed93 | ||
|
|
a1bfc07105 | ||
|
|
beba72d6db | ||
|
|
a4a5bfaa2f | ||
|
|
62ea384d19 | ||
|
|
53b1e11eba | ||
|
|
7fae96eb1e | ||
|
|
d386641820 | ||
|
|
7c5e38294a | ||
|
|
1cadc5d677 | ||
|
|
7509bf208e | ||
|
|
ec34bc9af1 | ||
|
|
8d1af17449 | ||
|
|
0db1573d34 | ||
|
|
b3c45a8edb | ||
|
|
1a0bd1a150 | ||
|
|
5a726fb61f | ||
|
|
6792d2d036 | ||
|
|
d32fb26adb | ||
|
|
d4ba7731ad | ||
|
|
b9607297e9 | ||
|
|
9ed59fdf34 | ||
|
|
8bcb44a019 | ||
|
|
6b28c8ace2 | ||
|
|
55088951c0 | ||
|
|
55a0d89f0d | ||
|
|
d532c9913c | ||
|
|
261bf354b7 | ||
|
|
50b6dc4b81 | ||
|
|
ba29a4a078 | ||
|
|
676644d8e8 | ||
|
|
f64a897cbc | ||
|
|
8b209f8f68 | ||
|
|
16b6619dfa | ||
|
|
a8c8fa6bc6 | ||
|
|
6d7e5df98f | ||
|
|
1d5d95c8cb | ||
|
|
8f886fc6dd | ||
|
|
581f975b38 | ||
|
|
d2c8bcf318 | ||
|
|
ef1ed6365c | ||
|
|
82418e2bf7 | ||
|
|
6fefbb4115 | ||
|
|
85bf0bd994 | ||
|
|
913d4537f4 | ||
|
|
4e2bafafef | ||
|
|
bffb7c52d5 | ||
|
|
38c4d3d09d | ||
|
|
2951f21dab | ||
|
|
d97a635084 | ||
|
|
2c9d9fe211 | ||
|
|
583411768d | ||
|
|
a55df65bc9 | ||
|
|
d6de848e29 | ||
|
|
649a98d855 | ||
|
|
127759b160 | ||
|
|
5b29f1b3ac | ||
|
|
755177fb4c | ||
|
|
ee9c42bee5 | ||
|
|
4d06c36342 | ||
|
|
1508d3708c | ||
|
|
ea6266f736 | ||
|
|
406a9d8350 | ||
|
|
2be0263dfa | ||
|
|
deea985a20 | ||
|
|
0d18256828 | ||
|
|
abe18e41bc | ||
|
|
716282cc1a | ||
|
|
f5a59fea5d | ||
|
|
2e70e3a0d3 | ||
|
|
7ff459af13 | ||
|
|
5bee11a6d3 | ||
|
|
0b21483b17 | ||
|
|
7444b3a8bf | ||
|
|
f39e39ed47 | ||
|
|
1989c52ca0 | ||
|
|
d8df0ddef8 | ||
|
|
7f6e3852b8 | ||
|
|
23656b2b0e | ||
|
|
c16a32d2be | ||
|
|
9d28279475 | ||
|
|
913de80cbc | ||
|
|
e4c8085408 | ||
|
|
1b055c6ca7 | ||
|
|
630600e70d | ||
|
|
4809fe1b95 | ||
|
|
2d6715878d | ||
|
|
4691979679 | ||
|
|
4e5af01354 | ||
|
|
b23b39bcfd | ||
|
|
4f974e3465 | ||
|
|
85994fb61c | ||
|
|
ad9784c5e8 | ||
|
|
c239c3f395 | ||
|
|
8d22d3c13d | ||
|
|
6ef9cafc0e | ||
|
|
471ed1befe | ||
|
|
e822adf725 | ||
|
|
d91f09896d | ||
|
|
d41cdb6ce8 | ||
|
|
fbee729c5b | ||
|
|
89ad258515 | ||
|
|
0e5abca6b7 | ||
|
|
9cd2f836bd | ||
|
|
1f9caf5805 | ||
|
|
c515215eea | ||
|
|
100cc496de | ||
|
|
0a06c5bfa2 | ||
|
|
6f4451b761 | ||
|
|
55b5227431 | ||
|
|
2be98b581a | ||
|
|
4e0128f16a | ||
|
|
3d1f9ae9d3 | ||
|
|
5fabe62e70 | ||
|
|
39f6488471 | ||
|
|
170c03f7db | ||
|
|
e5c14bfd16 | ||
|
|
4a0d32ec53 | ||
|
|
9f0d521b88 | ||
|
|
78031b37fc | ||
|
|
e1e629e592 | ||
|
|
554b8b35ae | ||
|
|
874165904f | ||
|
|
1d2d33d01a | ||
|
|
59935375a3 | ||
|
|
e784758a21 | ||
|
|
f7fe1a1093 | ||
|
|
3a287a70cd | ||
|
|
d111aaf64f | ||
|
|
cc617eadc9 | ||
|
|
54e15f5ace | ||
|
|
d1a76b55bc | ||
|
|
a48abc2f8b | ||
|
|
3a7d4d7c8d | ||
|
|
5e6c2e37ca | ||
|
|
b8c60d092f | ||
|
|
b57c76ed05 | ||
|
|
8da3f91a1d | ||
|
|
fdedd3aa38 | ||
|
|
a5fbb38fe2 | ||
|
|
3b25c475f5 | ||
|
|
babe659a64 | ||
|
|
980711e658 | ||
|
|
3a69cf5c69 | ||
|
|
5c8819f1ac | ||
|
|
f6f2ab1e4a | ||
|
|
1a7540c80a | ||
|
|
5919273709 | ||
|
|
4a3a6d1294 | ||
|
|
9407439587 | ||
|
|
d754cd3de4 | ||
|
|
9f88892190 | ||
|
|
1df2544e07 | ||
|
|
0e390bca00 | ||
|
|
8de66ab4b8 | ||
|
|
8148308cff | ||
|
|
24fc3242fc | ||
|
|
cd955fa34d | ||
|
|
28e9561a94 | ||
|
|
6905e41b57 | ||
|
|
075f470778 | ||
|
|
b8c72d7cbc | ||
|
|
b89db70821 | ||
|
|
a92e9692c1 | ||
|
|
3d57bf0a3b | ||
|
|
ec21a197ac | ||
|
|
ccf1ff8f02 | ||
|
|
76eee77b08 | ||
|
|
5b7942d197 | ||
|
|
a5df3a131e | ||
|
|
a901fc5fe7 | ||
|
|
a554c14f18 | ||
|
|
da06b1c76c | ||
|
|
b32284af57 | ||
|
|
54bd1fdd62 | ||
|
|
da961fd840 | ||
|
|
8449dc1b9d | ||
|
|
0648475a66 | ||
|
|
eff62cecac | ||
|
|
e63a4cd0fd | ||
|
|
dd2ba08f7c | ||
|
|
d19f3c8c07 | ||
|
|
427836884e | ||
|
|
1ad34fe7ae | ||
|
|
77f78152ee | ||
|
|
ad89368b4e | ||
|
|
5b41e86d51 | ||
|
|
48bd83f3b4 | ||
|
|
db766ce064 | ||
|
|
75eb720ab5 | ||
|
|
88c43a1b45 | ||
|
|
0ab8edd170 | ||
|
|
10e165c574 | ||
|
|
18aed94e0c | ||
|
|
3b87862c8a | ||
|
|
6fc79a70a3 | ||
|
|
a1b7abfb9f | ||
|
|
ff6ab04ecd | ||
|
|
bf6f33ceaf | ||
|
|
324d6e7c36 | ||
|
|
7edf4a3e75 | ||
|
|
e6b770b686 | ||
|
|
172b84f7ce | ||
|
|
dfb8fb2986 | ||
|
|
b5739f66a3 | ||
|
|
862b0b568c | ||
|
|
237e796955 | ||
|
|
1931d6e9cf | ||
|
|
b02f855df8 | ||
|
|
632ea0d02e | ||
|
|
a66fd181e5 | ||
|
|
cb28d35bd2 | ||
|
|
004609b5a7 | ||
|
|
fdd1199cb1 | ||
|
|
e95a9ac466 | ||
|
|
30891d6fff | ||
|
|
8605797002 | ||
|
|
cc9a0671f3 | ||
|
|
0b5e37dcee | ||
|
|
abeb60d511 | ||
|
|
4b9df2bae1 | ||
|
|
61d431e44f | ||
|
|
6a0b5aa8e3 | ||
|
|
392be1e787 | ||
|
|
84e819dc31 | ||
|
|
c1047e6a6c | ||
|
|
ca60143bdf | ||
|
|
c834b5eecd | ||
|
|
10cd092a78 | ||
|
|
0c4a702a39 | ||
|
|
ed002df8f5 | ||
|
|
bbcea9d913 | ||
|
|
657753aac2 | ||
|
|
7de2b4e047 | ||
|
|
f6946b9412 | ||
|
|
70f3d25173 | ||
|
|
fdd1a602d5 | ||
|
|
bea3b6b72d | ||
|
|
7d5dc75dc5 | ||
|
|
2e1f4420a8 | ||
|
|
0362614f94 | ||
|
|
208d045cf5 | ||
|
|
47909a6f2d | ||
|
|
f4ff97c297 | ||
|
|
0121427ef1 | ||
|
|
a1e63e8118 | ||
|
|
b9f4ff6e9f | ||
|
|
942ced78ed | ||
|
|
9ae592209f | ||
|
|
dc2e0ec3b6 | ||
|
|
dd77a1fb9a | ||
|
|
2ef71d6def | ||
|
|
414ed74526 | ||
|
|
01eab08c1c | ||
|
|
5fd83a85e8 | ||
|
|
093131438d | ||
|
|
603b62fdb5 | ||
|
|
ec179380f4 | ||
|
|
7eddb38162 | ||
|
|
c54dfcade9 | ||
|
|
859ca7db68 | ||
|
|
df6fbb82be | ||
|
|
4b4b1eec8b | ||
|
|
d759fdd457 | ||
|
|
fa57a0fbac | ||
|
|
2a6250e3fb | ||
|
|
be26349e37 | ||
|
|
b2943670ca | ||
|
|
7e8d3423cd | ||
|
|
0df528cc9e | ||
|
|
21d1989e05 | ||
|
|
fa90bbc07a | ||
|
|
44eb7bfd25 | ||
|
|
6cb75924d9 | ||
|
|
cb98f5896f | ||
|
|
dfba6bf690 | ||
|
|
06b80629bc | ||
|
|
87edf6497d | ||
|
|
6bae276ecb | ||
|
|
b1abc813fc | ||
|
|
1264f8cff8 | ||
|
|
3b393e0e2d | ||
|
|
a7d55a5ad8 | ||
|
|
30da6bde6f | ||
|
|
d918602521 | ||
|
|
e2aef3fa43 | ||
|
|
1ed537dc52 | ||
|
|
072347e594 | ||
|
|
743ea6815b | ||
|
|
2f69cd1765 | ||
|
|
c1e91553b9 | ||
|
|
36a54a9c9d | ||
|
|
d88bb99957 | ||
|
|
6030306d9c | ||
|
|
aeeb123b1e | ||
|
|
019d363dcd | ||
|
|
038303e6a5 | ||
|
|
635c4b5b89 | ||
|
|
975a7b1fc0 | ||
|
|
52aeaf4924 | ||
|
|
6c2fa12f10 | ||
|
|
f3304d408c | ||
|
|
05e3539856 | ||
|
|
ff384cd658 | ||
|
|
62fff935da | ||
|
|
35bd34f8e6 | ||
|
|
02fdb4c879 | ||
|
|
621b1c57a3 | ||
|
|
d905317682 | ||
|
|
9e59d5eb52 | ||
|
|
10b8997cc5 | ||
|
|
d41209512e | ||
|
|
8cf7e424e2 | ||
|
|
cba64aaaa4 | ||
|
|
31b331ca67 | ||
|
|
e13088d911 | ||
|
|
d016f85110 | ||
|
|
bcadc2b45c | ||
|
|
afb2d5f105 | ||
|
|
15d892c62d | ||
|
|
eb0f3256d9 | ||
|
|
f9add77d7b | ||
|
|
4863f45f7e | ||
|
|
6f88df1fc8 | ||
|
|
aa76ed9baf | ||
|
|
bdb6a5501a | ||
|
|
7bf7524d22 | ||
|
|
b37bc47eaa | ||
|
|
c5c2cb13d4 | ||
|
|
8752326d8c | ||
|
|
52e2331dd4 | ||
|
|
5ad3bbb27f | ||
|
|
a253d276d7 |
+549
-480
File diff suppressed because it is too large
Load Diff
Vendored
+4
-4
@@ -1,6 +1,6 @@
|
||||
# generated automatically by aclocal 1.15 -*- Autoconf -*-
|
||||
# generated automatically by aclocal 1.15.1 -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1996-2014 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1996-2017 Free Software Foundation, Inc.
|
||||
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@@ -9390,7 +9390,7 @@ AS_IF([test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"],
|
||||
|
||||
# AM_CONDITIONAL -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1997-2014 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1997-2017 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@@ -9421,7 +9421,7 @@ AC_CONFIG_COMMANDS_PRE(
|
||||
Usually this means the macro was only invoked conditionally.]])
|
||||
fi])])
|
||||
|
||||
# Copyright (C) 2006-2014 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2006-2017 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
|
||||
+26
-4
@@ -43,6 +43,7 @@
|
||||
#include "config.h"
|
||||
#ifdef USE_CACHEDB
|
||||
#include "cachedb/cachedb.h"
|
||||
#include "cachedb/redis.h"
|
||||
#include "util/regional.h"
|
||||
#include "util/net_help.h"
|
||||
#include "util/config_file.h"
|
||||
@@ -56,7 +57,20 @@
|
||||
#include "sldns/wire2str.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
|
||||
#define CACHEDB_HASHSIZE 256 /* bit hash */
|
||||
/* header file for htobe64 */
|
||||
#ifdef HAVE_ENDIAN_H
|
||||
# include <endian.h>
|
||||
#endif
|
||||
#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
|
||||
|
||||
/** the unit test testframe for cachedb, its module state contains
|
||||
* a cache for a couple queries (in memory). */
|
||||
@@ -176,6 +190,10 @@ static struct cachedb_backend testframe_backend = { "testframe",
|
||||
static struct cachedb_backend*
|
||||
cachedb_find_backend(const char* str)
|
||||
{
|
||||
#ifdef USE_REDIS
|
||||
if(strcmp(str, redis_backend.name) == 0)
|
||||
return &redis_backend;
|
||||
#endif
|
||||
if(strcmp(str, testframe_backend.name) == 0)
|
||||
return &testframe_backend;
|
||||
/* TODO add more backends here */
|
||||
@@ -568,14 +586,18 @@ cachedb_intcache_lookup(struct module_qstate* qstate)
|
||||
msg = dns_cache_lookup(qstate->env, qstate->qinfo.qname,
|
||||
qstate->qinfo.qname_len, qstate->qinfo.qtype,
|
||||
qstate->qinfo.qclass, qstate->query_flags,
|
||||
qstate->region, qstate->env->scratch);
|
||||
if(!msg && qstate->env->neg_cache) {
|
||||
qstate->region, qstate->env->scratch,
|
||||
1 /* no partial messages with only a CNAME */
|
||||
);
|
||||
if(!msg && qstate->env->neg_cache &&
|
||||
iter_qname_indicates_dnssec(qstate->env, &qstate->qinfo)) {
|
||||
/* lookup in negative cache; may result in
|
||||
* NOERROR/NODATA or NXDOMAIN answers that need validation */
|
||||
msg = val_neg_getmsg(qstate->env->neg_cache, &qstate->qinfo,
|
||||
qstate->region, qstate->env->rrset_cache,
|
||||
qstate->env->scratch_buffer,
|
||||
*qstate->env->now, 1/*add SOA*/, NULL);
|
||||
*qstate->env->now, 1/*add SOA*/, NULL,
|
||||
qstate->env->cfg);
|
||||
}
|
||||
if(!msg)
|
||||
return 0;
|
||||
|
||||
@@ -87,6 +87,8 @@ struct cachedb_backend {
|
||||
uint8_t*, size_t);
|
||||
};
|
||||
|
||||
#define CACHEDB_HASHSIZE 256 /* bit hash */
|
||||
|
||||
/** Init the cachedb module */
|
||||
int cachedb_init(struct module_env* env, int id);
|
||||
/** Deinit the cachedb module */
|
||||
|
||||
+283
@@ -0,0 +1,283 @@
|
||||
/*
|
||||
* cachedb/redis.c - cachedb redis module
|
||||
*
|
||||
* Copyright (c) 2018, 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 a module that uses the redis database to cache
|
||||
* dns responses.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#ifdef USE_CACHEDB
|
||||
#include "cachedb/redis.h"
|
||||
#include "cachedb/cachedb.h"
|
||||
#include "util/alloc.h"
|
||||
#include "util/config_file.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
|
||||
#ifdef USE_REDIS
|
||||
#include "hiredis/hiredis.h"
|
||||
|
||||
struct redis_moddata {
|
||||
redisContext** ctxs; /* thread-specific redis contexts */
|
||||
int numctxs; /* number of ctx entries */
|
||||
const char* server_host; /* server's IP address or host name */
|
||||
int server_port; /* server's TCP port */
|
||||
struct timeval timeout; /* timeout for connection setup and commands */
|
||||
};
|
||||
|
||||
static redisContext*
|
||||
redis_connect(const struct redis_moddata* moddata)
|
||||
{
|
||||
redisContext* ctx;
|
||||
|
||||
ctx = redisConnectWithTimeout(moddata->server_host,
|
||||
moddata->server_port, moddata->timeout);
|
||||
if(!ctx || ctx->err) {
|
||||
const char *errstr = "out of memory";
|
||||
if(ctx)
|
||||
errstr = ctx->errstr;
|
||||
log_err("failed to connect to redis server: %s", errstr);
|
||||
goto fail;
|
||||
}
|
||||
if(redisSetTimeout(ctx, moddata->timeout) != REDIS_OK) {
|
||||
log_err("failed to set redis timeout");
|
||||
goto fail;
|
||||
}
|
||||
return ctx;
|
||||
|
||||
fail:
|
||||
if(ctx)
|
||||
redisFree(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
redis_init(struct module_env* env, struct cachedb_env* cachedb_env)
|
||||
{
|
||||
int i;
|
||||
struct redis_moddata* moddata = NULL;
|
||||
|
||||
verbose(VERB_ALGO, "redis_init");
|
||||
|
||||
moddata = calloc(1, sizeof(struct redis_moddata));
|
||||
if(!moddata) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
moddata->numctxs = env->cfg->num_threads;
|
||||
moddata->ctxs = calloc(env->cfg->num_threads, sizeof(redisContext*));
|
||||
if(!moddata->ctxs) {
|
||||
log_err("out of memory");
|
||||
free(moddata);
|
||||
return 0;
|
||||
}
|
||||
/* note: server_host is a shallow reference to configured string.
|
||||
* we don't have to free it in this module. */
|
||||
moddata->server_host = env->cfg->redis_server_host;
|
||||
moddata->server_port = env->cfg->redis_server_port;
|
||||
moddata->timeout.tv_sec = env->cfg->redis_timeout / 1000;
|
||||
moddata->timeout.tv_usec = (env->cfg->redis_timeout % 1000) * 1000;
|
||||
for(i = 0; i < moddata->numctxs; i++)
|
||||
moddata->ctxs[i] = redis_connect(moddata);
|
||||
cachedb_env->backend_data = moddata;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
redis_deinit(struct module_env* env, struct cachedb_env* cachedb_env)
|
||||
{
|
||||
struct redis_moddata* moddata = (struct redis_moddata*)
|
||||
cachedb_env->backend_data;
|
||||
(void)env;
|
||||
|
||||
verbose(VERB_ALGO, "redis_deinit");
|
||||
|
||||
if(!moddata)
|
||||
return;
|
||||
if(moddata->ctxs) {
|
||||
int i;
|
||||
for(i = 0; i < moddata->numctxs; i++) {
|
||||
if(moddata->ctxs[i])
|
||||
redisFree(moddata->ctxs[i]);
|
||||
}
|
||||
free(moddata->ctxs);
|
||||
}
|
||||
free(moddata);
|
||||
}
|
||||
|
||||
/*
|
||||
* Send a redis command and get a reply. Unified so that it can be used for
|
||||
* both SET and GET. If 'data' is non-NULL the command is supposed to be
|
||||
* SET and GET otherwise, but the implementation of this function is agnostic
|
||||
* about the semantics (except for logging): 'command', 'data', and 'data_len'
|
||||
* are opaquely passed to redisCommand().
|
||||
* This function first checks whether a connection with a redis server has
|
||||
* been established; if not it tries to set up a new one.
|
||||
* It returns redisReply returned from redisCommand() or NULL if some low
|
||||
* level error happens. The caller is responsible to check the return value,
|
||||
* if it's non-NULL, it has to free it with freeReplyObject().
|
||||
*/
|
||||
static redisReply*
|
||||
redis_command(struct module_env* env, struct cachedb_env* cachedb_env,
|
||||
const char* command, const uint8_t* data, size_t data_len)
|
||||
{
|
||||
redisContext* ctx;
|
||||
redisReply* rep;
|
||||
struct redis_moddata* d = (struct redis_moddata*)
|
||||
cachedb_env->backend_data;
|
||||
|
||||
/* We assume env->alloc->thread_num is a unique ID for each thread
|
||||
* in [0, num-of-threads). We could treat it as an error condition
|
||||
* if the assumption didn't hold, but it seems to be a fundamental
|
||||
* assumption throughout the unbound architecture, so we simply assert
|
||||
* it. */
|
||||
log_assert(env->alloc->thread_num < d->numctxs);
|
||||
ctx = d->ctxs[env->alloc->thread_num];
|
||||
|
||||
/* If we've not established a connection to the server or we've closed
|
||||
* it on a failure, try to re-establish a new one. Failures will be
|
||||
* logged in redis_connect(). */
|
||||
if(!ctx) {
|
||||
ctx = redis_connect(d);
|
||||
d->ctxs[env->alloc->thread_num] = ctx;
|
||||
}
|
||||
if(!ctx)
|
||||
return NULL;
|
||||
|
||||
/* Send the command and get a reply, synchronously. */
|
||||
rep = (redisReply*)redisCommand(ctx, command, data, data_len);
|
||||
if(!rep) {
|
||||
/* Once an error as a NULL-reply is returned the context cannot
|
||||
* be reused and we'll need to set up a new connection. */
|
||||
log_err("redis_command: failed to receive a reply, "
|
||||
"closing connection: %s", ctx->errstr);
|
||||
redisFree(ctx);
|
||||
d->ctxs[env->alloc->thread_num] = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Check error in reply to unify logging in that case.
|
||||
* The caller may perform context-dependent checks and logging. */
|
||||
if(rep->type == REDIS_REPLY_ERROR)
|
||||
log_err("redis: %s resulted in an error: %s",
|
||||
data ? "set" : "get", rep->str);
|
||||
|
||||
return rep;
|
||||
}
|
||||
|
||||
static int
|
||||
redis_lookup(struct module_env* env, struct cachedb_env* cachedb_env,
|
||||
char* key, struct sldns_buffer* result_buffer)
|
||||
{
|
||||
redisReply* rep;
|
||||
char cmdbuf[4+(CACHEDB_HASHSIZE/8)*2+1]; /* "GET " + key */
|
||||
int n;
|
||||
int ret = 0;
|
||||
|
||||
verbose(VERB_ALGO, "redis_lookup of %s", key);
|
||||
|
||||
n = snprintf(cmdbuf, sizeof(cmdbuf), "GET %s", key);
|
||||
if(n < 0 || n >= (int)sizeof(cmdbuf)) {
|
||||
log_err("redis_lookup: unexpected failure to build command");
|
||||
return 0;
|
||||
}
|
||||
|
||||
rep = redis_command(env, cachedb_env, cmdbuf, NULL, 0);
|
||||
if(!rep)
|
||||
return 0;
|
||||
switch (rep->type) {
|
||||
case REDIS_REPLY_NIL:
|
||||
verbose(VERB_ALGO, "redis_lookup: no data cached");
|
||||
break;
|
||||
case REDIS_REPLY_STRING:
|
||||
verbose(VERB_ALGO, "redis_lookup found %d bytes",
|
||||
(int)rep->len);
|
||||
if((size_t)rep->len > sldns_buffer_capacity(result_buffer)) {
|
||||
log_err("redis_lookup: replied data too long: %lu",
|
||||
(size_t)rep->len);
|
||||
break;
|
||||
}
|
||||
sldns_buffer_clear(result_buffer);
|
||||
sldns_buffer_write(result_buffer, rep->str, rep->len);
|
||||
sldns_buffer_flip(result_buffer);
|
||||
ret = 1;
|
||||
break;
|
||||
case REDIS_REPLY_ERROR:
|
||||
break; /* already logged */
|
||||
default:
|
||||
log_err("redis_lookup: unexpected type of reply for (%d)",
|
||||
rep->type);
|
||||
break;
|
||||
}
|
||||
freeReplyObject(rep);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
redis_store(struct module_env* env, struct cachedb_env* cachedb_env,
|
||||
char* key, uint8_t* data, size_t data_len)
|
||||
{
|
||||
redisReply* rep;
|
||||
char cmdbuf[4+(CACHEDB_HASHSIZE/8)*2+3+1]; /* "SET " + key + " %b" */
|
||||
int n;
|
||||
|
||||
verbose(VERB_ALGO, "redis_store %s (%d bytes)", key, (int)data_len);
|
||||
|
||||
/* build command to set to a binary safe string */
|
||||
n = snprintf(cmdbuf, sizeof(cmdbuf), "SET %s %%b", key);
|
||||
if(n < 0 || n >= (int)sizeof(cmdbuf)) {
|
||||
log_err("redis_store: unexpected failure to build command");
|
||||
return;
|
||||
}
|
||||
|
||||
rep = redis_command(env, cachedb_env, cmdbuf, data, data_len);
|
||||
if(rep) {
|
||||
verbose(VERB_ALGO, "redis_store set completed");
|
||||
if(rep->type != REDIS_REPLY_STATUS &&
|
||||
rep->type != REDIS_REPLY_ERROR) {
|
||||
log_err("redis_store: unexpected type of reply (%d)",
|
||||
rep->type);
|
||||
}
|
||||
freeReplyObject(rep);
|
||||
}
|
||||
}
|
||||
|
||||
struct cachedb_backend redis_backend = { "redis",
|
||||
redis_init, redis_deinit, redis_lookup, redis_store
|
||||
};
|
||||
#endif /* USE_REDIS */
|
||||
#endif /* USE_CACHEDB */
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* cachedb/redis.h - cachedb redis module
|
||||
*
|
||||
* Copyright (c) 2018, 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 a module that uses the redis database to cache
|
||||
* dns responses.
|
||||
*/
|
||||
|
||||
/** the redis backend definition, contains callable functions
|
||||
* and name string */
|
||||
extern struct cachedb_backend redis_backend;
|
||||
@@ -33,6 +33,9 @@
|
||||
*/
|
||||
#include "config.h"
|
||||
#define LOCKRET(func) func
|
||||
#ifdef ENABLE_LOCK_CHECKS
|
||||
#undef ENABLE_LOCK_CHECKS
|
||||
#endif
|
||||
#include "util/locks.h"
|
||||
|
||||
void _ARC4_LOCK(void);
|
||||
@@ -46,6 +49,10 @@ void _ARC4_LOCK(void)
|
||||
void _ARC4_UNLOCK(void)
|
||||
{
|
||||
}
|
||||
|
||||
void _ARC4_LOCK_DESTROY(void)
|
||||
{
|
||||
}
|
||||
#else /* !THREADS_DISABLED */
|
||||
|
||||
static lock_quick_type arc4lock;
|
||||
@@ -64,4 +71,12 @@ void _ARC4_UNLOCK(void)
|
||||
{
|
||||
lock_quick_unlock(&arc4lock);
|
||||
}
|
||||
|
||||
void _ARC4_LOCK_DESTROY(void)
|
||||
{
|
||||
if(arc4lockinit) {
|
||||
arc4lockinit = 0;
|
||||
lock_quick_destroy(&arc4lock);
|
||||
}
|
||||
}
|
||||
#endif /* THREADS_DISABLED */
|
||||
|
||||
+71
-2
@@ -71,6 +71,72 @@ static struct {
|
||||
|
||||
static inline void _rs_rekey(u_char *dat, size_t datlen);
|
||||
|
||||
/*
|
||||
* Basic sanity checking; wish we could do better.
|
||||
*/
|
||||
static int
|
||||
fallback_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;
|
||||
}
|
||||
|
||||
/* fallback for getentropy in case libc returns failure */
|
||||
static int
|
||||
fallback_getentropy_urandom(void *buf, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
int fd, flags;
|
||||
int save_errno = errno;
|
||||
|
||||
start:
|
||||
|
||||
flags = O_RDONLY;
|
||||
#ifdef O_NOFOLLOW
|
||||
flags |= O_NOFOLLOW;
|
||||
#endif
|
||||
#ifdef O_CLOEXEC
|
||||
flags |= O_CLOEXEC;
|
||||
#endif
|
||||
fd = open("/dev/urandom", flags, 0);
|
||||
if (fd == -1) {
|
||||
if (errno == EINTR)
|
||||
goto start;
|
||||
goto nodevrandom;
|
||||
}
|
||||
#ifndef O_CLOEXEC
|
||||
# ifdef HAVE_FCNTL
|
||||
fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
|
||||
# endif
|
||||
#endif
|
||||
for (i = 0; i < len; ) {
|
||||
size_t wanted = len - i;
|
||||
ssize_t ret = read(fd, (char*)buf + i, wanted);
|
||||
|
||||
if (ret == -1) {
|
||||
if (errno == EAGAIN || errno == EINTR)
|
||||
continue;
|
||||
close(fd);
|
||||
goto nodevrandom;
|
||||
}
|
||||
i += ret;
|
||||
}
|
||||
close(fd);
|
||||
if (fallback_gotdata(buf, len) == 0) {
|
||||
errno = save_errno;
|
||||
return 0; /* satisfied */
|
||||
}
|
||||
nodevrandom:
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline void
|
||||
_rs_init(u_char *buf, size_t n)
|
||||
{
|
||||
@@ -114,11 +180,14 @@ _rs_stir(void)
|
||||
u_char rnd[KEYSZ + IVSZ];
|
||||
|
||||
if (getentropy(rnd, sizeof rnd) == -1) {
|
||||
if(errno != ENOSYS ||
|
||||
fallback_getentropy_urandom(rnd, sizeof rnd) == -1) {
|
||||
#ifdef SIGKILL
|
||||
raise(SIGKILL);
|
||||
raise(SIGKILL);
|
||||
#else
|
||||
exit(9); /* windows */
|
||||
exit(9); /* windows */
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (!rs)
|
||||
|
||||
+38
@@ -30,6 +30,9 @@
|
||||
internal symbols */
|
||||
#undef EXPORT_ALL_SYMBOLS
|
||||
|
||||
/* Define to 1 if you have the `accept4' function. */
|
||||
#undef HAVE_ACCEPT4
|
||||
|
||||
/* Define to 1 if you have the `arc4random' function. */
|
||||
#undef HAVE_ARC4RANDOM
|
||||
|
||||
@@ -83,6 +86,10 @@
|
||||
don't. */
|
||||
#undef HAVE_DECL_NID_ED25519
|
||||
|
||||
/* Define to 1 if you have the declaration of `NID_ED448', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_NID_ED448
|
||||
|
||||
/* Define to 1 if you have the declaration of `NID_secp384r1', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_NID_SECP384R1
|
||||
@@ -95,6 +102,10 @@
|
||||
don't. */
|
||||
#undef HAVE_DECL_REALLOCARRAY
|
||||
|
||||
/* Define to 1 if you have the declaration of `redisConnect', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_REDISCONNECT
|
||||
|
||||
/* Define to 1 if you have the declaration of `sk_SSL_COMP_pop_free', and to 0
|
||||
if you don't. */
|
||||
#undef HAVE_DECL_SK_SSL_COMP_POP_FREE
|
||||
@@ -233,6 +244,9 @@
|
||||
/* Define to 1 if you have the <grp.h> header file. */
|
||||
#undef HAVE_GRP_H
|
||||
|
||||
/* Define to 1 if you have the <hiredis/hiredis.h> header file. */
|
||||
#undef HAVE_HIREDIS_HIREDIS_H
|
||||
|
||||
/* If you have HMAC_Update */
|
||||
#undef HAVE_HMAC_UPDATE
|
||||
|
||||
@@ -263,6 +277,9 @@
|
||||
/* Define to 1 if you have the `kill' function. */
|
||||
#undef HAVE_KILL
|
||||
|
||||
/* Define to 1 if you have the <libkern/OSByteOrder.h> header file. */
|
||||
#undef HAVE_LIBKERN_OSBYTEORDER_H
|
||||
|
||||
/* Define if we have LibreSSL */
|
||||
#undef HAVE_LIBRESSL
|
||||
|
||||
@@ -425,6 +442,12 @@
|
||||
/* Define to 1 if you have the `SSL_CTX_set_security_level' function. */
|
||||
#undef HAVE_SSL_CTX_SET_SECURITY_LEVEL
|
||||
|
||||
/* Define to 1 if you have the `SSL_get0_peername' function. */
|
||||
#undef HAVE_SSL_GET0_PEERNAME
|
||||
|
||||
/* Define to 1 if you have the `SSL_set1_host' function. */
|
||||
#undef HAVE_SSL_SET1_HOST
|
||||
|
||||
/* Define to 1 if you have the <stdarg.h> header file. */
|
||||
#undef HAVE_STDARG_H
|
||||
|
||||
@@ -473,6 +496,9 @@
|
||||
/* Define to 1 if systemd should be used */
|
||||
#undef HAVE_SYSTEMD
|
||||
|
||||
/* Define to 1 if you have the <sys/endian.h> header file. */
|
||||
#undef HAVE_SYS_ENDIAN_H
|
||||
|
||||
/* Define to 1 if you have the <sys/ipc.h> header file. */
|
||||
#undef HAVE_SYS_IPC_H
|
||||
|
||||
@@ -646,6 +672,9 @@
|
||||
/* define if (v)snprintf does not return length needed, (but length used) */
|
||||
#undef SNPRINTF_RET_BROKEN
|
||||
|
||||
/* Define to 1 if libsodium supports sodium_set_misuse_handler */
|
||||
#undef SODIUM_MISUSE_HANDLER
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
@@ -694,6 +723,9 @@
|
||||
/* Define this to enable ED25519 support. */
|
||||
#undef USE_ED25519
|
||||
|
||||
/* Define this to enable ED448 support. */
|
||||
#undef USE_ED448
|
||||
|
||||
/* Define this to enable GOST support. */
|
||||
#undef USE_GOST
|
||||
|
||||
@@ -709,6 +741,9 @@
|
||||
/* Define this to enable client TCP Fast Open. */
|
||||
#undef USE_OSX_MSG_FASTOPEN
|
||||
|
||||
/* Define this to use hiredis client. */
|
||||
#undef USE_REDIS
|
||||
|
||||
/* Define this to enable SHA1 support. */
|
||||
#undef USE_SHA1
|
||||
|
||||
@@ -1147,6 +1182,7 @@ uint32_t arc4random(void);
|
||||
void arc4random_buf(void* buf, size_t n);
|
||||
void _ARC4_LOCK(void);
|
||||
void _ARC4_UNLOCK(void);
|
||||
void _ARC4_LOCK_DESTROY(void);
|
||||
#endif
|
||||
#ifndef HAVE_ARC4RANDOM_UNIFORM
|
||||
uint32_t arc4random_uniform(uint32_t upper_bound);
|
||||
@@ -1212,6 +1248,8 @@ void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
|
||||
|
||||
/** default port for DNS traffic. */
|
||||
#define UNBOUND_DNS_PORT 53
|
||||
/** default port for DNS over TLS traffic. */
|
||||
#define UNBOUND_DNS_OVER_TLS_PORT 853
|
||||
/** default port for unbound control traffic, registered port with IANA,
|
||||
ub-dns-control 8953/tcp unbound dns nameserver control */
|
||||
#define UNBOUND_CONTROL_PORT 8953
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.69 for unbound 1.6.7.
|
||||
# Generated by GNU Autoconf 2.69 for unbound 1.7.3.
|
||||
#
|
||||
# Report bugs to <unbound-bugs@nlnetlabs.nl>.
|
||||
#
|
||||
@@ -590,8 +590,8 @@ MAKEFLAGS=
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='unbound'
|
||||
PACKAGE_TARNAME='unbound'
|
||||
PACKAGE_VERSION='1.6.7'
|
||||
PACKAGE_STRING='unbound 1.6.7'
|
||||
PACKAGE_VERSION='1.7.3'
|
||||
PACKAGE_STRING='unbound 1.7.3'
|
||||
PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl'
|
||||
PACKAGE_URL=''
|
||||
|
||||
@@ -848,6 +848,7 @@ with_pthreads
|
||||
with_solaris_threads
|
||||
with_pyunbound
|
||||
with_pythonmodule
|
||||
enable_swig_version_check
|
||||
with_nss
|
||||
with_nettle
|
||||
with_ssl
|
||||
@@ -858,11 +859,13 @@ enable_gost
|
||||
enable_ecdsa
|
||||
enable_dsa
|
||||
enable_ed25519
|
||||
enable_ed448
|
||||
enable_event_api
|
||||
enable_tfo_client
|
||||
enable_tfo_server
|
||||
with_libevent
|
||||
with_libexpat
|
||||
with_libhiredis
|
||||
enable_static_exe
|
||||
enable_systemd
|
||||
enable_lock_checks
|
||||
@@ -1437,7 +1440,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.6.7 to adapt to many kinds of systems.
|
||||
\`configure' configures unbound 1.7.3 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@@ -1502,7 +1505,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of unbound 1.6.7:";;
|
||||
short | recursive ) echo "Configuration of unbound 1.7.3:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@@ -1532,6 +1535,9 @@ Optional Features:
|
||||
enable nonregional allocs, slow but exposes regional
|
||||
allocations to other memory purifiers, for debug
|
||||
purposes
|
||||
--disable-swig-version-check
|
||||
Disable swig version check to build python modules
|
||||
with older swig even though that is unreliable
|
||||
--disable-sha1 Disable SHA1 RRSIG support, does not disable nsec3
|
||||
support
|
||||
--disable-sha2 Disable SHA256 and SHA512 RRSIG support
|
||||
@@ -1540,6 +1546,7 @@ Optional Features:
|
||||
--disable-ecdsa Disable ECDSA support
|
||||
--disable-dsa Disable DSA support
|
||||
--disable-ed25519 Disable ED25519 support
|
||||
--disable-ed448 Disable ED448 support
|
||||
--enable-event-api Enable (experimental) pluggable event base
|
||||
libunbound API installed to unbound-event.h
|
||||
--enable-tfo-client Enable TCP Fast Open for client mode
|
||||
@@ -1606,6 +1613,7 @@ Optional Packages:
|
||||
an explicit path). Slower, but allows use of large
|
||||
outgoing port ranges.
|
||||
--with-libexpat=path specify explicit path for libexpat.
|
||||
--with-libhiredis=path specify explicit path for libhiredis.
|
||||
--with-dnstap-socket-path=pathname
|
||||
set default dnstap socket path
|
||||
--with-protobuf-c=path Path where protobuf-c is installed, for dnstap
|
||||
@@ -1714,7 +1722,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
unbound configure 1.6.7
|
||||
unbound configure 1.7.3
|
||||
generated by GNU Autoconf 2.69
|
||||
|
||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
@@ -2423,7 +2431,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.6.7, which was
|
||||
It was created by unbound $as_me 1.7.3, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
@@ -2773,13 +2781,13 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
||||
|
||||
UNBOUND_VERSION_MAJOR=1
|
||||
|
||||
UNBOUND_VERSION_MINOR=6
|
||||
UNBOUND_VERSION_MINOR=7
|
||||
|
||||
UNBOUND_VERSION_MICRO=7
|
||||
UNBOUND_VERSION_MICRO=3
|
||||
|
||||
|
||||
LIBUNBOUND_CURRENT=7
|
||||
LIBUNBOUND_REVISION=6
|
||||
LIBUNBOUND_REVISION=11
|
||||
LIBUNBOUND_AGE=5
|
||||
# 1.0.0 had 0:12:0
|
||||
# 1.0.1 had 0:13:0
|
||||
@@ -2837,6 +2845,11 @@ LIBUNBOUND_AGE=5
|
||||
# 1.6.5 had 7:4:5
|
||||
# 1.6.6 had 7:5:5
|
||||
# 1.6.7 had 7:6:5
|
||||
# 1.6.8 had 7:7:5
|
||||
# 1.7.0 had 7:8:5
|
||||
# 1.7.1 had 7:9:5
|
||||
# 1.7.2 had 7:10:5
|
||||
# 1.7.3 had 7:11:5
|
||||
|
||||
# Current -- the number of the binary API that we're implementing
|
||||
# Revision -- which iteration of the implementation of the binary
|
||||
@@ -4428,6 +4441,7 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
|
||||
ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
||||
|
||||
# allow user to override the -g -O2 flags.
|
||||
default_cflags=no
|
||||
if test "x$CFLAGS" = "x" ; then
|
||||
|
||||
|
||||
@@ -4491,6 +4505,7 @@ $as_echo "no" >&6; }
|
||||
|
||||
fi
|
||||
|
||||
default_cflags=yes
|
||||
fi
|
||||
ac_ext=c
|
||||
ac_cpp='$CPP $CPPFLAGS'
|
||||
@@ -5944,6 +5959,10 @@ $as_echo "#define UNBOUND_DEBUG /**/" >>confdefs.h
|
||||
# nothing to do.
|
||||
;;
|
||||
esac
|
||||
if test "$default_cflags" = "yes"; then
|
||||
# only when CFLAGS was "" at the start, if the users wants to
|
||||
# override we shouldn't add default cflags, because they wouldn't
|
||||
# be able to turn off these options and set the CFLAGS wanted.
|
||||
|
||||
# Check whether --enable-flto was given.
|
||||
if test "${enable_flto+set}" = set; then :
|
||||
@@ -6078,6 +6097,7 @@ rm -f core conftest.err conftest.$ac_objext \
|
||||
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5
|
||||
$as_echo_n "checking for inline... " >&6; }
|
||||
@@ -14464,7 +14484,7 @@ CC=$lt_save_CC
|
||||
|
||||
|
||||
# Checks for header files.
|
||||
for ac_header in stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/ipc.h sys/shm.h
|
||||
for ac_header in stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/endian.h libkern/OSByteOrder.h sys/ipc.h sys/shm.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
|
||||
@@ -16914,6 +16934,12 @@ $as_echo "#define HAVE_PYTHON 1" >>confdefs.h
|
||||
|
||||
# Check for SWIG
|
||||
ub_have_swig=no
|
||||
# Check whether --enable-swig-version-check was given.
|
||||
if test "${enable_swig_version_check+set}" = set; then :
|
||||
enableval=$enable_swig_version_check;
|
||||
fi
|
||||
|
||||
if test "$enable_swig_version_check" = "yes"; then
|
||||
|
||||
# Extract the first word of "swig", so it can be a program name with args.
|
||||
set dummy swig; ac_word=$2
|
||||
@@ -17030,6 +17056,124 @@ $as_echo "$as_me: WARNING: cannot determine SWIG version" >&2;}
|
||||
fi
|
||||
|
||||
|
||||
else
|
||||
|
||||
# Extract the first word of "swig", so it can be a program name with args.
|
||||
set dummy swig; ac_word=$2
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
|
||||
$as_echo_n "checking for $ac_word... " >&6; }
|
||||
if ${ac_cv_path_SWIG+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
case $SWIG in
|
||||
[\\/]* | ?:[\\/]*)
|
||||
ac_cv_path_SWIG="$SWIG" # Let the user override the test with a path.
|
||||
;;
|
||||
*)
|
||||
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
|
||||
for as_dir in $PATH
|
||||
do
|
||||
IFS=$as_save_IFS
|
||||
test -z "$as_dir" && as_dir=.
|
||||
for ac_exec_ext in '' $ac_executable_extensions; do
|
||||
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
|
||||
ac_cv_path_SWIG="$as_dir/$ac_word$ac_exec_ext"
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
done
|
||||
IFS=$as_save_IFS
|
||||
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
SWIG=$ac_cv_path_SWIG
|
||||
if test -n "$SWIG"; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $SWIG" >&5
|
||||
$as_echo "$SWIG" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
|
||||
|
||||
if test -z "$SWIG" ; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cannot find 'swig' program. You should look at http://www.swig.org" >&5
|
||||
$as_echo "$as_me: WARNING: cannot find 'swig' program. You should look at http://www.swig.org" >&2;}
|
||||
SWIG='echo "Error: SWIG is not installed. You should look at http://www.swig.org" ; false'
|
||||
elif test -n "" ; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SWIG version" >&5
|
||||
$as_echo_n "checking for SWIG version... " >&6; }
|
||||
swig_version=`$SWIG -version 2>&1 | grep 'SWIG Version' | sed 's/.*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*/\1/g'`
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $swig_version" >&5
|
||||
$as_echo "$swig_version" >&6; }
|
||||
if test -n "$swig_version" ; then
|
||||
# Calculate the required version number components
|
||||
required=
|
||||
required_major=`echo $required | sed 's/[^0-9].*//'`
|
||||
if test -z "$required_major" ; then
|
||||
required_major=0
|
||||
fi
|
||||
required=`echo $required | sed 's/[0-9]*[^0-9]//'`
|
||||
required_minor=`echo $required | sed 's/[^0-9].*//'`
|
||||
if test -z "$required_minor" ; then
|
||||
required_minor=0
|
||||
fi
|
||||
required=`echo $required | sed 's/[0-9]*[^0-9]//'`
|
||||
required_patch=`echo $required | sed 's/[^0-9].*//'`
|
||||
if test -z "$required_patch" ; then
|
||||
required_patch=0
|
||||
fi
|
||||
# Calculate the available version number components
|
||||
available=$swig_version
|
||||
available_major=`echo $available | sed 's/[^0-9].*//'`
|
||||
if test -z "$available_major" ; then
|
||||
available_major=0
|
||||
fi
|
||||
available=`echo $available | sed 's/[0-9]*[^0-9]//'`
|
||||
available_minor=`echo $available | sed 's/[^0-9].*//'`
|
||||
if test -z "$available_minor" ; then
|
||||
available_minor=0
|
||||
fi
|
||||
available=`echo $available | sed 's/[0-9]*[^0-9]//'`
|
||||
available_patch=`echo $available | sed 's/[^0-9].*//'`
|
||||
if test -z "$available_patch" ; then
|
||||
available_patch=0
|
||||
fi
|
||||
badversion=0
|
||||
if test $available_major -lt $required_major ; then
|
||||
badversion=1
|
||||
fi
|
||||
if test $available_major -eq $required_major \
|
||||
-a $available_minor -lt $required_minor ; then
|
||||
badversion=1
|
||||
fi
|
||||
if test $available_major -eq $required_major \
|
||||
-a $available_minor -eq $required_minor \
|
||||
-a $available_patch -lt $required_patch ; then
|
||||
badversion=1
|
||||
fi
|
||||
if test $badversion -eq 1 ; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: SWIG version >= is required. You have $swig_version. You should look at http://www.swig.org" >&5
|
||||
$as_echo "$as_me: WARNING: SWIG version >= is required. You have $swig_version. You should look at http://www.swig.org" >&2;}
|
||||
SWIG='echo "Error: SWIG version >= is required. You have '"$swig_version"'. You should look at http://www.swig.org" ; false'
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: SWIG executable is '$SWIG'" >&5
|
||||
$as_echo "$as_me: SWIG executable is '$SWIG'" >&6;}
|
||||
SWIG_LIB=`$SWIG -swiglib`
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: SWIG library directory is '$SWIG_LIB'" >&5
|
||||
$as_echo "$as_me: SWIG library directory is '$SWIG_LIB'" >&6;}
|
||||
fi
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cannot determine SWIG version" >&5
|
||||
$as_echo "$as_me: WARNING: cannot determine SWIG version" >&2;}
|
||||
SWIG='echo "Error: Cannot determine SWIG version. You should look at http://www.swig.org" ; false'
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking SWIG" >&5
|
||||
$as_echo_n "checking SWIG... " >&6; }
|
||||
if test ! -x "$SWIG"; then
|
||||
@@ -17650,7 +17794,7 @@ done
|
||||
# these check_funcs need -lssl
|
||||
BAKLIBS="$LIBS"
|
||||
LIBS="-lssl $LIBS"
|
||||
for ac_func in OPENSSL_init_ssl SSL_CTX_set_security_level
|
||||
for ac_func in OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername
|
||||
do :
|
||||
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
|
||||
@@ -18069,12 +18213,40 @@ case "$enable_dsa" in
|
||||
ac_fn_c_check_func "$LINENO" "DSA_SIG_new" "ac_cv_func_DSA_SIG_new"
|
||||
if test "x$ac_cv_func_DSA_SIG_new" = xyes; then :
|
||||
|
||||
as_ac_Type=`$as_echo "ac_cv_type_DSA_SIG*" | $as_tr_sh`
|
||||
ac_fn_c_check_type "$LINENO" "DSA_SIG*" "$as_ac_Type" "
|
||||
$ac_includes_default
|
||||
#ifdef HAVE_OPENSSL_ERR_H
|
||||
#include <openssl/err.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENSSL_RAND_H
|
||||
#include <openssl/rand.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENSSL_CONF_H
|
||||
#include <openssl/conf.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENSSL_ENGINE_H
|
||||
#include <openssl/engine.h>
|
||||
#endif
|
||||
|
||||
"
|
||||
if eval test \"x\$"$as_ac_Type"\" = x"yes"; then :
|
||||
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define USE_DSA 1
|
||||
_ACEOF
|
||||
|
||||
|
||||
else
|
||||
if test "x$enable_dsa" = "xyes"; then as_fn_error $? "OpenSSL does not support DSA and you used --enable-dsa." "$LINENO" 5
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
else
|
||||
if test "x$enable_dsa" = "xyes"; then as_fn_error $? "OpenSSL does not support DSA and you used --enable-dsa." "$LINENO" 5
|
||||
fi
|
||||
@@ -18149,6 +18321,50 @@ _ACEOF
|
||||
;;
|
||||
esac
|
||||
|
||||
# Check whether --enable-ed448 was given.
|
||||
if test "${enable_ed448+set}" = set; then :
|
||||
enableval=$enable_ed448;
|
||||
fi
|
||||
|
||||
use_ed448="no"
|
||||
case "$enable_ed448" in
|
||||
no)
|
||||
;;
|
||||
*)
|
||||
if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
|
||||
ac_fn_c_check_decl "$LINENO" "NID_ED448" "ac_cv_have_decl_NID_ED448" "$ac_includes_default
|
||||
#include <openssl/evp.h>
|
||||
|
||||
"
|
||||
if test "x$ac_cv_have_decl_NID_ED448" = xyes; then :
|
||||
ac_have_decl=1
|
||||
else
|
||||
ac_have_decl=0
|
||||
fi
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_DECL_NID_ED448 $ac_have_decl
|
||||
_ACEOF
|
||||
if test $ac_have_decl = 1; then :
|
||||
|
||||
use_ed448="yes"
|
||||
|
||||
else
|
||||
if test "x$enable_ed448" = "xyes"; then as_fn_error $? "OpenSSL does not support ED448 and you used --enable-ed448." "$LINENO" 5
|
||||
fi
|
||||
fi
|
||||
|
||||
fi
|
||||
if test $use_ed448 = "yes"; then
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define USE_ED448 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
# Check whether --enable-event-api was given.
|
||||
if test "${enable_event_api+set}" = set; then :
|
||||
enableval=$enable_event_api;
|
||||
@@ -18645,6 +18861,70 @@ cat >>confdefs.h <<_ACEOF
|
||||
_ACEOF
|
||||
|
||||
|
||||
# hiredis (redis C client for cachedb)
|
||||
|
||||
# Check whether --with-libhiredis was given.
|
||||
if test "${with_libhiredis+set}" = set; then :
|
||||
withval=$with_libhiredis;
|
||||
else
|
||||
withval="no"
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libhiredis" >&5
|
||||
$as_echo_n "checking for libhiredis... " >&6; }
|
||||
found_libhiredis="no"
|
||||
if test x_$withval = x_yes -o x_$withval != x_no; then
|
||||
if test x_$withval = x_ -o x_$withval = x_yes; then
|
||||
withval="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr"
|
||||
fi
|
||||
for dir in $withval ; do
|
||||
if test -f "$dir/include/hiredis/hiredis.h"; then
|
||||
found_libhiredis="yes"
|
||||
if test "$dir" != "/usr"; then
|
||||
CPPFLAGS="$CPPFLAGS -I$dir/include"
|
||||
LDFLAGS="$LDFLAGS -L$dir/lib"
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: found in $dir" >&5
|
||||
$as_echo "found in $dir" >&6; }
|
||||
|
||||
$as_echo "#define USE_REDIS 1" >>confdefs.h
|
||||
|
||||
LIBS="$LIBS -lhiredis"
|
||||
break;
|
||||
fi
|
||||
done
|
||||
if test x_$found_libhiredis != x_yes; then
|
||||
as_fn_error $? "Could not find libhiredis, hiredis.h" "$LINENO" 5
|
||||
fi
|
||||
for ac_header in hiredis/hiredis.h
|
||||
do :
|
||||
ac_fn_c_check_header_compile "$LINENO" "hiredis/hiredis.h" "ac_cv_header_hiredis_hiredis_h" "$ac_includes_default
|
||||
"
|
||||
if test "x$ac_cv_header_hiredis_hiredis_h" = xyes; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_HIREDIS_HIREDIS_H 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
ac_fn_c_check_decl "$LINENO" "redisConnect" "ac_cv_have_decl_redisConnect" "$ac_includes_default
|
||||
#include <hiredis/hiredis.h>
|
||||
|
||||
"
|
||||
if test "x$ac_cv_have_decl_redisConnect" = xyes; then :
|
||||
ac_have_decl=1
|
||||
else
|
||||
ac_have_decl=0
|
||||
fi
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_DECL_REDISCONNECT $ac_have_decl
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
# set static linking if requested
|
||||
|
||||
staticexe=""
|
||||
@@ -19189,7 +19469,7 @@ else
|
||||
WINDRES="$ac_cv_prog_WINDRES"
|
||||
fi
|
||||
|
||||
LIBS="$LIBS -liphlpapi"
|
||||
LIBS="$LIBS -liphlpapi -lcrypt32"
|
||||
WINAPPS="unbound-service-install.exe unbound-service-remove.exe anchor-update.exe"
|
||||
|
||||
WIN_DAEMON_SRC="winrc/win_svc.c winrc/w_inst.c"
|
||||
@@ -19423,7 +19703,7 @@ if test "$ac_res" != no; then :
|
||||
|
||||
fi
|
||||
|
||||
for ac_func in 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
|
||||
for ac_func in 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
|
||||
do :
|
||||
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
|
||||
@@ -19483,7 +19763,7 @@ done
|
||||
|
||||
|
||||
# check if setreuid en setregid fail, on MacOSX10.4(darwin8).
|
||||
if echo $build_os | grep darwin8 > /dev/null; then
|
||||
if echo $target_os | grep darwin8 > /dev/null; then
|
||||
|
||||
$as_echo "#define DARWIN_BROKEN_SETREUID 1" >>confdefs.h
|
||||
|
||||
@@ -20485,6 +20765,66 @@ else
|
||||
ENABLE_DNSCRYPT_XCHACHA20=0
|
||||
|
||||
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing sodium_set_misuse_handler" >&5
|
||||
$as_echo_n "checking for library containing sodium_set_misuse_handler... " >&6; }
|
||||
if ${ac_cv_search_sodium_set_misuse_handler+:} 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 sodium_set_misuse_handler ();
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return sodium_set_misuse_handler ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
for ac_lib in '' sodium; 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 :
|
||||
ac_cv_search_sodium_set_misuse_handler=$ac_res
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext
|
||||
if ${ac_cv_search_sodium_set_misuse_handler+:} false; then :
|
||||
break
|
||||
fi
|
||||
done
|
||||
if ${ac_cv_search_sodium_set_misuse_handler+:} false; then :
|
||||
|
||||
else
|
||||
ac_cv_search_sodium_set_misuse_handler=no
|
||||
fi
|
||||
rm conftest.$ac_ext
|
||||
LIBS=$ac_func_search_save_LIBS
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_sodium_set_misuse_handler" >&5
|
||||
$as_echo "$ac_cv_search_sodium_set_misuse_handler" >&6; }
|
||||
ac_res=$ac_cv_search_sodium_set_misuse_handler
|
||||
if test "$ac_res" != no; then :
|
||||
test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
|
||||
|
||||
|
||||
$as_echo "#define SODIUM_MISUSE_HANDLER 1" >>confdefs.h
|
||||
|
||||
|
||||
fi
|
||||
|
||||
|
||||
@@ -20516,6 +20856,8 @@ if test "${enable_cachedb+set}" = set; then :
|
||||
enableval=$enable_cachedb;
|
||||
fi
|
||||
|
||||
# turn on cachedb when hiredis support is enabled.
|
||||
if test "$found_libhiredis" = "yes"; then enable_cachedb="yes"; fi
|
||||
case "$enable_cachedb" in
|
||||
yes)
|
||||
|
||||
@@ -20600,6 +20942,15 @@ if test "${with_libunbound_only+set}" = set; then :
|
||||
|
||||
fi
|
||||
|
||||
if test $ALLTARGET = "alltargets"; then
|
||||
if test $USE_NSS = "yes"; then
|
||||
as_fn_error $? "--with-nss can only be used in combination with --with-libunbound-only." "$LINENO" 5
|
||||
fi
|
||||
if test $USE_NETTLE = "yes"; then
|
||||
as_fn_error $? "--with-nettle can only be used in combination with --with-libunbound-only." "$LINENO" 5
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -20694,7 +21045,7 @@ _ACEOF
|
||||
|
||||
|
||||
|
||||
version=1.6.7
|
||||
version=1.7.3
|
||||
|
||||
date=`date +'%b %e, %Y'`
|
||||
|
||||
@@ -21213,7 +21564,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.6.7, which was
|
||||
This file was extended by unbound $as_me 1.7.3, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@@ -21279,7 +21630,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.6.7
|
||||
unbound config.status 1.7.3
|
||||
configured by $0, generated by GNU Autoconf 2.69,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
||||
+116
-12
@@ -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],[6])
|
||||
m4_define([VERSION_MICRO],[7])
|
||||
m4_define([VERSION_MINOR],[7])
|
||||
m4_define([VERSION_MICRO],[3])
|
||||
AC_INIT(unbound, m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]), unbound-bugs@nlnetlabs.nl, unbound)
|
||||
AC_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR])
|
||||
AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR])
|
||||
AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO])
|
||||
|
||||
LIBUNBOUND_CURRENT=7
|
||||
LIBUNBOUND_REVISION=6
|
||||
LIBUNBOUND_REVISION=11
|
||||
LIBUNBOUND_AGE=5
|
||||
# 1.0.0 had 0:12:0
|
||||
# 1.0.1 had 0:13:0
|
||||
@@ -76,6 +76,11 @@ LIBUNBOUND_AGE=5
|
||||
# 1.6.5 had 7:4:5
|
||||
# 1.6.6 had 7:5:5
|
||||
# 1.6.7 had 7:6:5
|
||||
# 1.6.8 had 7:7:5
|
||||
# 1.7.0 had 7:8:5
|
||||
# 1.7.1 had 7:9:5
|
||||
# 1.7.2 had 7:10:5
|
||||
# 1.7.3 had 7:11:5
|
||||
|
||||
# Current -- the number of the binary API that we're implementing
|
||||
# Revision -- which iteration of the implementation of the binary
|
||||
@@ -245,9 +250,11 @@ AC_DEFINE_UNQUOTED(RSRC_PACKAGE_VERSION, [$wnvs], [version number for resource f
|
||||
AC_C_CONST
|
||||
AC_LANG_C
|
||||
# allow user to override the -g -O2 flags.
|
||||
default_cflags=no
|
||||
if test "x$CFLAGS" = "x" ; then
|
||||
ACX_CHECK_COMPILER_FLAG(g, [CFLAGS="$CFLAGS -g"])
|
||||
ACX_CHECK_COMPILER_FLAG(O2, [CFLAGS="$CFLAGS -O2"])
|
||||
default_cflags=yes
|
||||
fi
|
||||
AC_PROG_CC
|
||||
ACX_DEPFLAG
|
||||
@@ -271,9 +278,14 @@ case "$debug_enabled" in
|
||||
# nothing to do.
|
||||
;;
|
||||
esac
|
||||
ACX_CHECK_FLTO
|
||||
ACX_CHECK_PIE
|
||||
ACX_CHECK_RELRO_NOW
|
||||
if test "$default_cflags" = "yes"; then
|
||||
# only when CFLAGS was "" at the start, if the users wants to
|
||||
# override we shouldn't add default cflags, because they wouldn't
|
||||
# be able to turn off these options and set the CFLAGS wanted.
|
||||
ACX_CHECK_FLTO
|
||||
ACX_CHECK_PIE
|
||||
ACX_CHECK_RELRO_NOW
|
||||
fi
|
||||
|
||||
AC_C_INLINE
|
||||
ACX_CHECK_FORMAT_ATTRIBUTE
|
||||
@@ -322,7 +334,7 @@ AC_CHECK_TOOL(STRIP, strip)
|
||||
ACX_LIBTOOL_C_ONLY
|
||||
|
||||
# Checks for header files.
|
||||
AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/ipc.h sys/shm.h],,, [AC_INCLUDES_DEFAULT])
|
||||
AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/endian.h libkern/OSByteOrder.h sys/ipc.h sys/shm.h],,, [AC_INCLUDES_DEFAULT])
|
||||
|
||||
# check for types.
|
||||
# Using own tests for int64* because autoconf builtin only give 32bit.
|
||||
@@ -578,7 +590,12 @@ if test x_$ub_test_python != x_no; then
|
||||
|
||||
# Check for SWIG
|
||||
ub_have_swig=no
|
||||
AC_PROG_SWIG(2.0.1)
|
||||
AC_ARG_ENABLE(swig-version-check, AC_HELP_STRING([--disable-swig-version-check], [Disable swig version check to build python modules with older swig even though that is unreliable]))
|
||||
if test "$enable_swig_version_check" = "yes"; then
|
||||
AC_PROG_SWIG(2.0.1)
|
||||
else
|
||||
AC_PROG_SWIG
|
||||
fi
|
||||
AC_MSG_CHECKING(SWIG)
|
||||
if test ! -x "$SWIG"; then
|
||||
AC_ERROR([failed to find swig tool, install it, or do not build Python module and PyUnbound])
|
||||
@@ -710,7 +727,7 @@ AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_C
|
||||
# these check_funcs need -lssl
|
||||
BAKLIBS="$LIBS"
|
||||
LIBS="-lssl $LIBS"
|
||||
AC_CHECK_FUNCS([OPENSSL_init_ssl SSL_CTX_set_security_level])
|
||||
AC_CHECK_FUNCS([OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername])
|
||||
LIBS="$BAKLIBS"
|
||||
|
||||
AC_CHECK_DECLS([SSL_COMP_get_compression_methods,sk_SSL_COMP_pop_free,SSL_CTX_set_ecdh_auto], [], [], [
|
||||
@@ -926,7 +943,27 @@ case "$enable_dsa" in
|
||||
# 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, [
|
||||
AC_CHECK_TYPE(DSA_SIG*, [
|
||||
AC_DEFINE_UNQUOTED([USE_DSA], [1], [Define this to enable DSA support.])
|
||||
], [if test "x$enable_dsa" = "xyes"; then AC_MSG_ERROR([OpenSSL does not support DSA and you used --enable-dsa.])
|
||||
fi ], [
|
||||
AC_INCLUDES_DEFAULT
|
||||
#ifdef HAVE_OPENSSL_ERR_H
|
||||
#include <openssl/err.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENSSL_RAND_H
|
||||
#include <openssl/rand.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENSSL_CONF_H
|
||||
#include <openssl/conf.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENSSL_ENGINE_H
|
||||
#include <openssl/engine.h>
|
||||
#endif
|
||||
])
|
||||
], [if test "x$enable_dsa" = "xyes"; then AC_MSG_ERROR([OpenSSL does not support DSA and you used --enable-dsa.])
|
||||
fi ])
|
||||
else
|
||||
@@ -958,6 +995,26 @@ case "$enable_ed25519" in
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_ARG_ENABLE(ed448, AC_HELP_STRING([--disable-ed448], [Disable ED448 support]))
|
||||
use_ed448="no"
|
||||
case "$enable_ed448" in
|
||||
no)
|
||||
;;
|
||||
*)
|
||||
if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
|
||||
AC_CHECK_DECLS([NID_ED448], [
|
||||
use_ed448="yes"
|
||||
], [ if test "x$enable_ed448" = "xyes"; then AC_MSG_ERROR([OpenSSL does not support ED448 and you used --enable-ed448.])
|
||||
fi ], [AC_INCLUDES_DEFAULT
|
||||
#include <openssl/evp.h>
|
||||
])
|
||||
fi
|
||||
if test $use_ed448 = "yes"; then
|
||||
AC_DEFINE_UNQUOTED([USE_ED448], [1], [Define this to enable ED448 support.])
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_ARG_ENABLE(event-api, AC_HELP_STRING([--enable-event-api], [Enable (experimental) pluggable event base libunbound API installed to unbound-event.h]))
|
||||
case "$enable_event_api" in
|
||||
yes)
|
||||
@@ -1116,6 +1173,39 @@ AC_CHECK_DECLS([XML_StopParser], [], [], [AC_INCLUDES_DEFAULT
|
||||
#include <expat.h>
|
||||
])
|
||||
|
||||
# hiredis (redis C client for cachedb)
|
||||
AC_ARG_WITH(libhiredis, AC_HELP_STRING([--with-libhiredis=path],
|
||||
[specify explicit path for libhiredis.]),
|
||||
[ ],[ withval="no" ])
|
||||
AC_MSG_CHECKING(for libhiredis)
|
||||
found_libhiredis="no"
|
||||
if test x_$withval = x_yes -o x_$withval != x_no; then
|
||||
if test x_$withval = x_ -o x_$withval = x_yes; then
|
||||
withval="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr"
|
||||
fi
|
||||
for dir in $withval ; do
|
||||
if test -f "$dir/include/hiredis/hiredis.h"; then
|
||||
found_libhiredis="yes"
|
||||
dnl assume /usr is in default path.
|
||||
if test "$dir" != "/usr"; then
|
||||
CPPFLAGS="$CPPFLAGS -I$dir/include"
|
||||
LDFLAGS="$LDFLAGS -L$dir/lib"
|
||||
fi
|
||||
AC_MSG_RESULT(found in $dir)
|
||||
AC_DEFINE([USE_REDIS], [1], [Define this to use hiredis client.])
|
||||
LIBS="$LIBS -lhiredis"
|
||||
break;
|
||||
fi
|
||||
done
|
||||
if test x_$found_libhiredis != x_yes; then
|
||||
AC_ERROR([Could not find libhiredis, hiredis.h])
|
||||
fi
|
||||
AC_CHECK_HEADERS([hiredis/hiredis.h],,, [AC_INCLUDES_DEFAULT])
|
||||
AC_CHECK_DECLS([redisConnect], [], [], [AC_INCLUDES_DEFAULT
|
||||
#include <hiredis/hiredis.h>
|
||||
])
|
||||
fi
|
||||
|
||||
# set static linking if requested
|
||||
AC_SUBST(staticexe)
|
||||
staticexe=""
|
||||
@@ -1157,7 +1247,7 @@ if test "$USE_WINSOCK" = 1; then
|
||||
#include <windows.h>
|
||||
])
|
||||
AC_CHECK_TOOL(WINDRES, windres)
|
||||
LIBS="$LIBS -liphlpapi"
|
||||
LIBS="$LIBS -liphlpapi -lcrypt32"
|
||||
WINAPPS="unbound-service-install.exe unbound-service-remove.exe anchor-update.exe"
|
||||
AC_SUBST(WINAPPS)
|
||||
WIN_DAEMON_SRC="winrc/win_svc.c winrc/w_inst.c"
|
||||
@@ -1230,12 +1320,12 @@ AC_INCLUDES_DEFAULT
|
||||
#endif
|
||||
])
|
||||
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])
|
||||
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])])
|
||||
AC_CHECK_FUNCS([setresgid],,[AC_CHECK_FUNCS([setregid])])
|
||||
|
||||
# check if setreuid en setregid fail, on MacOSX10.4(darwin8).
|
||||
if echo $build_os | grep darwin8 > /dev/null; then
|
||||
if echo $target_os | grep darwin8 > /dev/null; then
|
||||
AC_DEFINE(DARWIN_BROKEN_SETREUID, 1, [Define this if on macOSX10.4-darwin8 and setreuid and setregid do not work])
|
||||
fi
|
||||
AC_CHECK_DECLS([inet_pton,inet_ntop], [], [], [
|
||||
@@ -1400,6 +1490,8 @@ dnsc_DNSCRYPT([
|
||||
|
||||
# check for cachedb if requested
|
||||
AC_ARG_ENABLE(cachedb, AC_HELP_STRING([--enable-cachedb], [enable cachedb module that can use external cache storage]))
|
||||
# turn on cachedb when hiredis support is enabled.
|
||||
if test "$found_libhiredis" = "yes"; then enable_cachedb="yes"; fi
|
||||
case "$enable_cachedb" in
|
||||
yes)
|
||||
AC_DEFINE([USE_CACHEDB], [1], [Define to 1 to use cachedb support])
|
||||
@@ -1470,6 +1562,15 @@ AC_ARG_WITH(libunbound-only, AC_HELP_STRING([--with-libunbound-only],
|
||||
INSTALLTARGET="install-lib"
|
||||
fi
|
||||
])
|
||||
if test $ALLTARGET = "alltargets"; then
|
||||
if test $USE_NSS = "yes"; then
|
||||
AC_ERROR([--with-nss can only be used in combination with --with-libunbound-only.])
|
||||
fi
|
||||
if test $USE_NETTLE = "yes"; then
|
||||
AC_ERROR([--with-nettle can only be used in combination with --with-libunbound-only.])
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_SUBST(ALLTARGET)
|
||||
AC_SUBST(INSTALLTARGET)
|
||||
|
||||
@@ -1643,6 +1744,7 @@ uint32_t arc4random(void);
|
||||
void arc4random_buf(void* buf, size_t n);
|
||||
void _ARC4_LOCK(void);
|
||||
void _ARC4_UNLOCK(void);
|
||||
void _ARC4_LOCK_DESTROY(void);
|
||||
#endif
|
||||
#ifndef HAVE_ARC4RANDOM_UNIFORM
|
||||
uint32_t arc4random_uniform(uint32_t upper_bound);
|
||||
@@ -1708,6 +1810,8 @@ void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
|
||||
|
||||
/** default port for DNS traffic. */
|
||||
#define UNBOUND_DNS_PORT 53
|
||||
/** default port for DNS over TLS traffic. */
|
||||
#define UNBOUND_DNS_OVER_TLS_PORT 853
|
||||
/** default port for unbound control traffic, registered port with IANA,
|
||||
ub-dns-control 8953/tcp unbound dns nameserver control */
|
||||
#define UNBOUND_CONTROL_PORT 8953
|
||||
|
||||
@@ -34,3 +34,7 @@ distribution but may be helpful.
|
||||
* 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.
|
||||
* libunbound.so.conf: ltrace.conf file, see ltrace.conf(5), for libunbound.
|
||||
* unbound-querycachedb.py: utility to show data stored in cachedb backend
|
||||
for a particular query name and type. It requires dnspython and (for
|
||||
redis backend) redis Python modules.
|
||||
|
||||
+156
-198
@@ -1,10 +1,15 @@
|
||||
Description: based on the included patch contrib/fastrpz.patch
|
||||
Author: fastrpz@farsightsecurity.com
|
||||
---
|
||||
This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
|
||||
===================================================================
|
||||
RCS file: ./RCS/Makefile.in,v
|
||||
retrieving revision 1.1
|
||||
diff -u --unidirectional-new-file -r1.1 ./Makefile.in
|
||||
--- ./Makefile.in
|
||||
+++ ./Makefile.in
|
||||
@@ -23,6 +23,8 @@
|
||||
Index: unbound-1.7.0~rc1/Makefile.in
|
||||
===================================================================
|
||||
--- unbound-1.7.0~rc1.orig/Makefile.in
|
||||
+++ unbound-1.7.0~rc1/Makefile.in
|
||||
@@ -23,6 +23,8 @@ CHECKLOCK_SRC=testcode/checklocks.c
|
||||
CHECKLOCK_OBJ=@CHECKLOCK_OBJ@
|
||||
DNSTAP_SRC=@DNSTAP_SRC@
|
||||
DNSTAP_OBJ=@DNSTAP_OBJ@
|
||||
@@ -13,25 +18,25 @@ diff -u --unidirectional-new-file -r1.1 ./Makefile.in
|
||||
DNSCRYPT_SRC=@DNSCRYPT_SRC@
|
||||
DNSCRYPT_OBJ=@DNSCRYPT_OBJ@
|
||||
WITH_PYTHONMODULE=@WITH_PYTHONMODULE@
|
||||
@@ -125,7 +127,7 @@
|
||||
@@ -125,7 +127,7 @@ validator/val_sigcrypt.c validator/val_u
|
||||
edns-subnet/edns-subnet.c edns-subnet/subnetmod.c \
|
||||
edns-subnet/addrtree.c edns-subnet/subnet-whitelist.c \
|
||||
cachedb/cachedb.c respip/respip.c $(CHECKLOCK_SRC) \
|
||||
cachedb/cachedb.c cachedb/redis.c respip/respip.c $(CHECKLOCK_SRC) \
|
||||
-$(DNSTAP_SRC) $(DNSCRYPT_SRC) $(IPSECMOD_SRC)
|
||||
+$(DNSTAP_SRC) $(FASTRPZ_SRC) $(DNSCRYPT_SRC) $(IPSECMOD_SRC)
|
||||
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 \
|
||||
@@ -137,7 +139,7 @@
|
||||
@@ -137,7 +139,7 @@ slabhash.lo timehist.lo tube.lo winsock_
|
||||
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 \
|
||||
val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo cachedb.lo authzone.lo\
|
||||
$(SUBNET_OBJ) $(PYTHONMOD_OBJ) $(CHECKLOCK_OBJ) $(DNSTAP_OBJ) $(DNSCRYPT_OBJ) \
|
||||
-$(IPSECMOD_OBJ)
|
||||
+$(FASTRPZ_OBJ) $(DNSCRYPT_OBJ)
|
||||
COMMON_OBJ_WITHOUT_NETCALL+=respip.lo
|
||||
-$(IPSECMOD_OBJ) respip.lo
|
||||
+$(FASTRPZ_OBJ) $(IPSECMOD_OBJ) respip.lo
|
||||
COMMON_OBJ_WITHOUT_UB_EVENT=$(COMMON_OBJ_WITHOUT_NETCALL) netevent.lo listen_dnsport.lo \
|
||||
outside_network.lo
|
||||
@@ -398,6 +401,11 @@
|
||||
COMMON_OBJ=$(COMMON_OBJ_WITHOUT_UB_EVENT) ub_event.lo
|
||||
@@ -400,6 +402,11 @@ dnscrypt.lo dnscrypt.o: $(srcdir)/dnscry
|
||||
$(srcdir)/util/config_file.h $(srcdir)/util/log.h \
|
||||
$(srcdir)/util/netevent.h
|
||||
|
||||
@@ -43,13 +48,11 @@ diff -u --unidirectional-new-file -r1.1 ./Makefile.in
|
||||
# Python Module
|
||||
pythonmod.lo pythonmod.o: $(srcdir)/pythonmod/pythonmod.c config.h \
|
||||
pythonmod/interface.h \
|
||||
Index: unbound-1.7.0~rc1/config.h.in
|
||||
===================================================================
|
||||
RCS file: ./RCS/config.h.in,v
|
||||
retrieving revision 1.1
|
||||
diff -u --unidirectional-new-file -r1.1 ./config.h.in
|
||||
--- ./config.h.in
|
||||
+++ ./config.h.in
|
||||
@@ -1199,4 +1199,11 @@
|
||||
--- unbound-1.7.0~rc1.orig/config.h.in
|
||||
+++ unbound-1.7.0~rc1/config.h.in
|
||||
@@ -1228,4 +1228,11 @@ void *unbound_stat_realloc_log(void *ptr
|
||||
/** the version of unbound-control that this software implements */
|
||||
#define UNBOUND_CONTROL_VERSION 1
|
||||
|
||||
@@ -62,13 +65,11 @@ diff -u --unidirectional-new-file -r1.1 ./config.h.in
|
||||
+#undef FASTRPZ_LIB_OPEN
|
||||
+/** turn on fastrpz response policy zones */
|
||||
+#undef ENABLE_FASTRPZ
|
||||
Index: unbound-1.7.0~rc1/configure.ac
|
||||
===================================================================
|
||||
RCS file: ./RCS/configure.ac,v
|
||||
retrieving revision 1.1
|
||||
diff -u --unidirectional-new-file -r1.1 ./configure.ac
|
||||
--- ./configure.ac
|
||||
+++ ./configure.ac
|
||||
@@ -6,6 +6,7 @@
|
||||
--- unbound-1.7.0~rc1.orig/configure.ac
|
||||
+++ unbound-1.7.0~rc1/configure.ac
|
||||
@@ -6,6 +6,7 @@ sinclude(ax_pthread.m4)
|
||||
sinclude(acx_python.m4)
|
||||
sinclude(ac_pkg_swig.m4)
|
||||
sinclude(dnstap/dnstap.m4)
|
||||
@@ -76,8 +77,8 @@ diff -u --unidirectional-new-file -r1.1 ./configure.ac
|
||||
sinclude(dnscrypt/dnscrypt.m4)
|
||||
|
||||
# must be numbers. ac_defun because of later processing
|
||||
@@ -1352,6 +1353,9 @@
|
||||
;;
|
||||
@@ -1453,6 +1454,9 @@ case "$enable_ipsecmod" in
|
||||
;;
|
||||
esac
|
||||
|
||||
+# check for Fastrpz with fastrpz/rpz.m4
|
||||
@@ -86,13 +87,11 @@ diff -u --unidirectional-new-file -r1.1 ./configure.ac
|
||||
AC_MSG_CHECKING([if ${MAKE:-make} supports $< with implicit rule in scope])
|
||||
# on openBSD, the implicit rule make $< work.
|
||||
# on Solaris, it does not work ($? is changed sources, $^ lists dependencies).
|
||||
Index: unbound-1.7.0~rc1/daemon/daemon.c
|
||||
===================================================================
|
||||
RCS file: ./daemon/RCS/daemon.c,v
|
||||
retrieving revision 1.1
|
||||
diff -u --unidirectional-new-file -r1.1 ./daemon/daemon.c
|
||||
--- ./daemon/daemon.c
|
||||
+++ ./daemon/daemon.c
|
||||
@@ -89,6 +89,9 @@
|
||||
--- unbound-1.7.0~rc1.orig/daemon/daemon.c
|
||||
+++ unbound-1.7.0~rc1/daemon/daemon.c
|
||||
@@ -90,6 +90,9 @@
|
||||
#include "sldns/keyraw.h"
|
||||
#include "respip/respip.h"
|
||||
#include <signal.h>
|
||||
@@ -102,7 +101,7 @@ diff -u --unidirectional-new-file -r1.1 ./daemon/daemon.c
|
||||
|
||||
#ifdef HAVE_SYSTEMD
|
||||
#include <systemd/sd-daemon.h>
|
||||
@@ -451,6 +454,14 @@
|
||||
@@ -461,6 +464,14 @@ daemon_create_workers(struct daemon* dae
|
||||
fatal_exit("dnstap enabled in config but not built with dnstap support");
|
||||
#endif
|
||||
}
|
||||
@@ -117,9 +116,9 @@ diff -u --unidirectional-new-file -r1.1 ./daemon/daemon.c
|
||||
for(i=0; i<daemon->num; i++) {
|
||||
if(!(daemon->workers[i] = worker_create(daemon, i,
|
||||
shufport+numport*i/daemon->num,
|
||||
@@ -691,6 +702,9 @@
|
||||
#ifdef USE_DNSTAP
|
||||
dt_delete(daemon->dtenv);
|
||||
@@ -710,6 +721,9 @@ daemon_cleanup(struct daemon* daemon)
|
||||
#ifdef USE_DNSCRYPT
|
||||
dnsc_delete(daemon->dnscenv);
|
||||
#endif
|
||||
+#ifdef ENABLE_FASTRPZ
|
||||
+ rpz_delete(&daemon->rpz_clist, &daemon->rpz_client);
|
||||
@@ -127,13 +126,11 @@ diff -u --unidirectional-new-file -r1.1 ./daemon/daemon.c
|
||||
daemon->cfg = NULL;
|
||||
}
|
||||
|
||||
Index: unbound-1.7.0~rc1/daemon/daemon.h
|
||||
===================================================================
|
||||
RCS file: ./daemon/RCS/daemon.h,v
|
||||
retrieving revision 1.1
|
||||
diff -u --unidirectional-new-file -r1.1 ./daemon/daemon.h
|
||||
--- ./daemon/daemon.h
|
||||
+++ ./daemon/daemon.h
|
||||
@@ -134,6 +134,11 @@
|
||||
--- unbound-1.7.0~rc1.orig/daemon/daemon.h
|
||||
+++ unbound-1.7.0~rc1/daemon/daemon.h
|
||||
@@ -134,6 +134,11 @@ struct daemon {
|
||||
/** the dnscrypt environment */
|
||||
struct dnsc_env* dnscenv;
|
||||
#endif
|
||||
@@ -145,13 +142,11 @@ diff -u --unidirectional-new-file -r1.1 ./daemon/daemon.h
|
||||
};
|
||||
|
||||
/**
|
||||
Index: unbound-1.7.0~rc1/daemon/worker.c
|
||||
===================================================================
|
||||
RCS file: ./daemon/RCS/worker.c,v
|
||||
retrieving revision 1.1
|
||||
diff -u --unidirectional-new-file -r1.1 ./daemon/worker.c
|
||||
--- ./daemon/worker.c
|
||||
+++ ./daemon/worker.c
|
||||
@@ -73,6 +73,9 @@
|
||||
--- unbound-1.7.0~rc1.orig/daemon/worker.c
|
||||
+++ unbound-1.7.0~rc1/daemon/worker.c
|
||||
@@ -74,6 +74,9 @@
|
||||
#include "libunbound/context.h"
|
||||
#include "libunbound/libworker.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
@@ -161,7 +156,7 @@ diff -u --unidirectional-new-file -r1.1 ./daemon/worker.c
|
||||
#include "sldns/wire2str.h"
|
||||
#include "util/shm_side/shm_main.h"
|
||||
#include "dnscrypt/dnscrypt.h"
|
||||
@@ -526,8 +529,27 @@
|
||||
@@ -527,8 +530,27 @@ answer_norec_from_cache(struct worker* w
|
||||
/* not secure */
|
||||
secure = 0;
|
||||
break;
|
||||
@@ -189,7 +184,7 @@ diff -u --unidirectional-new-file -r1.1 ./daemon/worker.c
|
||||
/* return this delegation from the cache */
|
||||
edns->edns_version = EDNS_ADVERTISED_VERSION;
|
||||
edns->udp_size = EDNS_ADVERTISED_SIZE;
|
||||
@@ -688,6 +710,23 @@
|
||||
@@ -689,6 +711,23 @@ answer_from_cache(struct worker* worker,
|
||||
secure = 0;
|
||||
}
|
||||
} else secure = 0;
|
||||
@@ -213,7 +208,7 @@ diff -u --unidirectional-new-file -r1.1 ./daemon/worker.c
|
||||
|
||||
edns->edns_version = EDNS_ADVERTISED_VERSION;
|
||||
edns->udp_size = EDNS_ADVERTISED_SIZE;
|
||||
@@ -1267,6 +1306,15 @@
|
||||
@@ -1291,6 +1330,15 @@ worker_handle_request(struct comm_point*
|
||||
log_addr(VERB_ALGO, "refused nonrec (cache snoop) query from",
|
||||
&repinfo->addr, repinfo->addrlen);
|
||||
goto send_reply;
|
||||
@@ -229,16 +224,16 @@ diff -u --unidirectional-new-file -r1.1 ./daemon/worker.c
|
||||
}
|
||||
|
||||
/* If we've found a local alias, replace the qname with the alias
|
||||
@@ -1315,12 +1363,21 @@
|
||||
@@ -1339,12 +1387,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,
|
||||
- if(answer_from_cache(worker, &qinfo,
|
||||
+ ret = answer_from_cache(worker, &qinfo,
|
||||
cinfo, &need_drop, &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,
|
||||
(struct reply_info*)e->data,
|
||||
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
|
||||
sldns_buffer_read_u16_at(c->buffer, 2), repinfo,
|
||||
- &edns)) {
|
||||
+ &edns);
|
||||
+#ifdef ENABLE_FASTRPZ
|
||||
@@ -253,7 +248,7 @@ diff -u --unidirectional-new-file -r1.1 ./daemon/worker.c
|
||||
/* prefetch it if the prefetch TTL expired.
|
||||
* Note that if there is more than one pass
|
||||
* its qname must be that used for cache
|
||||
@@ -1371,11 +1428,19 @@
|
||||
@@ -1398,11 +1455,19 @@ lookup_cache:
|
||||
lock_rw_unlock(&e->lock);
|
||||
}
|
||||
if(!LDNS_RD_WIRE(sldns_buffer_begin(c->buffer))) {
|
||||
@@ -275,13 +270,11 @@ diff -u --unidirectional-new-file -r1.1 ./daemon/worker.c
|
||||
goto send_reply;
|
||||
}
|
||||
verbose(VERB_ALGO, "answer norec from cache -- "
|
||||
Index: unbound-1.7.0~rc1/doc/unbound.conf.5.in
|
||||
===================================================================
|
||||
RCS file: ./doc/RCS/unbound.conf.5.in,v
|
||||
retrieving revision 1.1
|
||||
diff -u --unidirectional-new-file -r1.1 ./doc/unbound.conf.5.in
|
||||
--- ./doc/unbound.conf.5.in
|
||||
+++ ./doc/unbound.conf.5.in
|
||||
@@ -1446,6 +1446,81 @@
|
||||
--- unbound-1.7.0~rc1.orig/doc/unbound.conf.5.in
|
||||
+++ unbound-1.7.0~rc1/doc/unbound.conf.5.in
|
||||
@@ -1581,6 +1581,81 @@ It must be /96 or shorter. The default
|
||||
.B dns64\-synthall: \fI<yes or no>\fR
|
||||
Debug option, default no. If enabled, synthesize all AAAA records
|
||||
despite the presence of actual AAAA records.
|
||||
@@ -363,12 +356,10 @@ diff -u --unidirectional-new-file -r1.1 ./doc/unbound.conf.5.in
|
||||
.SS "DNSCrypt Options"
|
||||
.LP
|
||||
The
|
||||
Index: unbound-1.7.0~rc1/fastrpz/librpz.h
|
||||
===================================================================
|
||||
RCS file: ./fastrpz/RCS/librpz.h,v
|
||||
retrieving revision 1.1
|
||||
diff -u --unidirectional-new-file -r1.1 ./fastrpz/librpz.h
|
||||
--- ./fastrpz/librpz.h
|
||||
+++ ./fastrpz/librpz.h
|
||||
--- /dev/null
|
||||
+++ unbound-1.7.0~rc1/fastrpz/librpz.h
|
||||
@@ -0,0 +1,957 @@
|
||||
+/*
|
||||
+ * Define the interface from a DNS resolver to the Response Policy Zone
|
||||
@@ -1327,12 +1318,10 @@ diff -u --unidirectional-new-file -r1.1 ./fastrpz/librpz.h
|
||||
+#endif /* LIBRPZ_LIB_OPEN */
|
||||
+
|
||||
+#endif /* LIBRPZ_H */
|
||||
Index: unbound-1.7.0~rc1/fastrpz/rpz.c
|
||||
===================================================================
|
||||
RCS file: ./fastrpz/RCS/rpz.c,v
|
||||
retrieving revision 1.1
|
||||
diff -u --unidirectional-new-file -r1.1 ./fastrpz/rpz.c
|
||||
--- ./fastrpz/rpz.c
|
||||
+++ ./fastrpz/rpz.c
|
||||
--- /dev/null
|
||||
+++ unbound-1.7.0~rc1/fastrpz/rpz.c
|
||||
@@ -0,0 +1,1357 @@
|
||||
+/*
|
||||
+ * fastrpz/rpz.c - interface to the fastrpz response policy zone library
|
||||
@@ -2691,12 +2680,10 @@ diff -u --unidirectional-new-file -r1.1 ./fastrpz/rpz.c
|
||||
+}
|
||||
+
|
||||
+#endif /* ENABLE_FASTRPZ */
|
||||
Index: unbound-1.7.0~rc1/fastrpz/rpz.h
|
||||
===================================================================
|
||||
RCS file: ./fastrpz/RCS/rpz.h,v
|
||||
retrieving revision 1.1
|
||||
diff -u --unidirectional-new-file -r1.1 ./fastrpz/rpz.h
|
||||
--- ./fastrpz/rpz.h
|
||||
+++ ./fastrpz/rpz.h
|
||||
--- /dev/null
|
||||
+++ unbound-1.7.0~rc1/fastrpz/rpz.h
|
||||
@@ -0,0 +1,138 @@
|
||||
+/*
|
||||
+ * fastrpz/rpz.h - interface to the fastrpz response policy zone library
|
||||
@@ -2836,12 +2823,10 @@ diff -u --unidirectional-new-file -r1.1 ./fastrpz/rpz.h
|
||||
+
|
||||
+#endif /* ENABLE_FASTRPZ */
|
||||
+#endif /* UNBOUND_FASTRPZ_RPZ_H */
|
||||
Index: unbound-1.7.0~rc1/fastrpz/rpz.m4
|
||||
===================================================================
|
||||
RCS file: ./fastrpz/RCS/rpz.m4,v
|
||||
retrieving revision 1.1
|
||||
diff -u --unidirectional-new-file -r1.1 ./fastrpz/rpz.m4
|
||||
--- ./fastrpz/rpz.m4
|
||||
+++ ./fastrpz/rpz.m4
|
||||
--- /dev/null
|
||||
+++ unbound-1.7.0~rc1/fastrpz/rpz.m4
|
||||
@@ -0,0 +1,64 @@
|
||||
+# fastrpz/rpz.m4
|
||||
+
|
||||
@@ -2907,13 +2892,11 @@ diff -u --unidirectional-new-file -r1.1 ./fastrpz/rpz.m4
|
||||
+ AC_MSG_WARN([[dlopen and librpz.so needed for fastrpz]])
|
||||
+ fi
|
||||
+])
|
||||
Index: unbound-1.7.0~rc1/iterator/iterator.c
|
||||
===================================================================
|
||||
RCS file: ./iterator/RCS/iterator.c,v
|
||||
retrieving revision 1.1
|
||||
diff -u --unidirectional-new-file -r1.1 ./iterator/iterator.c
|
||||
--- ./iterator/iterator.c
|
||||
+++ ./iterator/iterator.c
|
||||
@@ -67,6 +67,9 @@
|
||||
--- unbound-1.7.0~rc1.orig/iterator/iterator.c
|
||||
+++ unbound-1.7.0~rc1/iterator/iterator.c
|
||||
@@ -68,6 +68,9 @@
|
||||
#include "sldns/str2wire.h"
|
||||
#include "sldns/parseutil.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
@@ -2923,7 +2906,7 @@ diff -u --unidirectional-new-file -r1.1 ./iterator/iterator.c
|
||||
|
||||
int
|
||||
iter_init(struct module_env* env, int id)
|
||||
@@ -487,6 +490,23 @@
|
||||
@@ -511,6 +514,23 @@ handle_cname_response(struct module_qsta
|
||||
if(ntohs(r->rk.type) == LDNS_RR_TYPE_CNAME &&
|
||||
query_dname_compare(*mname, r->rk.dname) == 0 &&
|
||||
!iter_find_rrset_in_prepend_answer(iq, r)) {
|
||||
@@ -2947,7 +2930,7 @@ diff -u --unidirectional-new-file -r1.1 ./iterator/iterator.c
|
||||
/* Add this relevant CNAME rrset to the prepend list.*/
|
||||
if(!iter_add_prepend_answer(qstate, iq, r))
|
||||
return 0;
|
||||
@@ -495,6 +515,9 @@
|
||||
@@ -519,6 +539,9 @@ handle_cname_response(struct module_qsta
|
||||
|
||||
/* Other rrsets in the section are ignored. */
|
||||
}
|
||||
@@ -2957,7 +2940,7 @@ diff -u --unidirectional-new-file -r1.1 ./iterator/iterator.c
|
||||
/* add authority rrsets to authority prepend, for wildcarded CNAMEs */
|
||||
for(i=msg->rep->an_numrrsets; i<msg->rep->an_numrrsets +
|
||||
msg->rep->ns_numrrsets; i++) {
|
||||
@@ -996,6 +1019,7 @@
|
||||
@@ -1148,6 +1171,7 @@ processInitRequest(struct module_qstate*
|
||||
uint8_t* delname;
|
||||
size_t delnamelen;
|
||||
struct dns_msg* msg = NULL;
|
||||
@@ -2965,7 +2948,7 @@ diff -u --unidirectional-new-file -r1.1 ./iterator/iterator.c
|
||||
|
||||
log_query_info(VERB_DETAIL, "resolving", &qstate->qinfo);
|
||||
/* check effort */
|
||||
@@ -1056,8 +1080,7 @@
|
||||
@@ -1223,8 +1247,7 @@ processInitRequest(struct module_qstate*
|
||||
}
|
||||
if(msg) {
|
||||
/* handle positive cache response */
|
||||
@@ -2975,7 +2958,7 @@ diff -u --unidirectional-new-file -r1.1 ./iterator/iterator.c
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
log_dns_msg("msg from cache lookup", &msg->qinfo,
|
||||
msg->rep);
|
||||
@@ -1065,7 +1088,22 @@
|
||||
@@ -1232,7 +1255,22 @@ processInitRequest(struct module_qstate*
|
||||
(int)msg->rep->ttl,
|
||||
(int)msg->rep->prefetch_ttl);
|
||||
}
|
||||
@@ -2998,7 +2981,7 @@ diff -u --unidirectional-new-file -r1.1 ./iterator/iterator.c
|
||||
if(type == RESPONSE_TYPE_CNAME) {
|
||||
uint8_t* sname = 0;
|
||||
size_t slen = 0;
|
||||
@@ -2321,6 +2359,62 @@
|
||||
@@ -2552,6 +2590,62 @@ processQueryResponse(struct module_qstat
|
||||
sock_list_insert(&qstate->reply_origin,
|
||||
&qstate->reply->addr, qstate->reply->addrlen,
|
||||
qstate->region);
|
||||
@@ -3061,7 +3044,7 @@ diff -u --unidirectional-new-file -r1.1 ./iterator/iterator.c
|
||||
if(iq->minimisation_state != DONOT_MINIMISE_STATE) {
|
||||
if(FLAGS_GET_RCODE(iq->response->rep->flags) !=
|
||||
LDNS_RCODE_NOERROR) {
|
||||
@@ -3022,12 +3116,44 @@
|
||||
@@ -3273,12 +3367,44 @@ processFinished(struct module_qstate* qs
|
||||
* but only if we did recursion. The nonrecursion referral
|
||||
* from cache does not need to be stored in the msg cache. */
|
||||
if(!qstate->no_cache_store && qstate->query_flags&BIT_RD) {
|
||||
@@ -3106,13 +3089,11 @@ diff -u --unidirectional-new-file -r1.1 ./iterator/iterator.c
|
||||
qstate->return_rcode = LDNS_RCODE_NOERROR;
|
||||
qstate->return_msg = iq->response;
|
||||
return 0;
|
||||
Index: unbound-1.7.0~rc1/iterator/iterator.h
|
||||
===================================================================
|
||||
RCS file: ./iterator/RCS/iterator.h,v
|
||||
retrieving revision 1.1
|
||||
diff -u --unidirectional-new-file -r1.1 ./iterator/iterator.h
|
||||
--- ./iterator/iterator.h
|
||||
+++ ./iterator/iterator.h
|
||||
@@ -381,6 +381,16 @@
|
||||
--- unbound-1.7.0~rc1.orig/iterator/iterator.h
|
||||
+++ unbound-1.7.0~rc1/iterator/iterator.h
|
||||
@@ -383,6 +383,16 @@ struct iter_qstate {
|
||||
*/
|
||||
int minimise_count;
|
||||
|
||||
@@ -3129,17 +3110,15 @@ diff -u --unidirectional-new-file -r1.1 ./iterator/iterator.h
|
||||
/**
|
||||
* Count number of time-outs. Used to prevent resolving failures when
|
||||
* the QNAME minimisation QTYPE is blocked. */
|
||||
Index: unbound-1.7.0~rc1/services/cache/dns.c
|
||||
===================================================================
|
||||
RCS file: ./services/cache/RCS/dns.c,v
|
||||
retrieving revision 1.1
|
||||
diff -u --unidirectional-new-file -r1.1 ./services/cache/dns.c
|
||||
--- ./services/cache/dns.c
|
||||
+++ ./services/cache/dns.c
|
||||
@@ -838,6 +838,14 @@
|
||||
struct regional* region, uint16_t flags)
|
||||
--- unbound-1.7.0~rc1.orig/services/cache/dns.c
|
||||
+++ unbound-1.7.0~rc1/services/cache/dns.c
|
||||
@@ -876,6 +876,14 @@ dns_cache_store(struct module_env* env,
|
||||
struct regional* region, uint32_t flags)
|
||||
{
|
||||
struct reply_info* rep = NULL;
|
||||
+
|
||||
+
|
||||
+#ifdef ENABLE_FASTRPZ
|
||||
+ /* Never save RPZ rewritten data. */
|
||||
+ if (msgrep->security == sec_status_rpz_drop ||
|
||||
@@ -3150,12 +3129,10 @@ diff -u --unidirectional-new-file -r1.1 ./services/cache/dns.c
|
||||
/* alloc, malloc properly (not in region, like msg is) */
|
||||
rep = reply_info_copy(msgrep, env->alloc, NULL);
|
||||
if(!rep)
|
||||
Index: unbound-1.7.0~rc1/services/mesh.c
|
||||
===================================================================
|
||||
RCS file: ./services/RCS/mesh.c,v
|
||||
retrieving revision 1.1
|
||||
diff -u --unidirectional-new-file -r1.1 ./services/mesh.c
|
||||
--- ./services/mesh.c
|
||||
+++ ./services/mesh.c
|
||||
--- unbound-1.7.0~rc1.orig/services/mesh.c
|
||||
+++ unbound-1.7.0~rc1/services/mesh.c
|
||||
@@ -59,6 +59,9 @@
|
||||
#include "sldns/wire2str.h"
|
||||
#include "services/localzone.h"
|
||||
@@ -3166,7 +3143,7 @@ diff -u --unidirectional-new-file -r1.1 ./services/mesh.c
|
||||
#include "respip/respip.h"
|
||||
|
||||
/** subtract timers and the values do not overflow or become negative */
|
||||
@@ -1011,6 +1014,13 @@
|
||||
@@ -1050,6 +1053,13 @@ mesh_send_reply(struct mesh_state* m, in
|
||||
else secure = 0;
|
||||
if(!rep && rcode == LDNS_RCODE_NOERROR)
|
||||
rcode = LDNS_RCODE_SERVFAIL;
|
||||
@@ -3180,7 +3157,7 @@ diff -u --unidirectional-new-file -r1.1 ./services/mesh.c
|
||||
/* 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
|
||||
@@ -1160,6 +1170,7 @@
|
||||
@@ -1199,6 +1209,7 @@ struct mesh_state* mesh_area_find(struct
|
||||
key.s.is_valrec = valrec;
|
||||
key.s.qinfo = *qinfo;
|
||||
key.s.query_flags = qflags;
|
||||
@@ -3188,7 +3165,7 @@ diff -u --unidirectional-new-file -r1.1 ./services/mesh.c
|
||||
/* 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).*/
|
||||
@@ -1206,6 +1217,10 @@
|
||||
@@ -1245,6 +1256,10 @@ int mesh_state_add_reply(struct mesh_sta
|
||||
if(!r)
|
||||
return 0;
|
||||
r->query_reply = *rep;
|
||||
@@ -3199,13 +3176,11 @@ diff -u --unidirectional-new-file -r1.1 ./services/mesh.c
|
||||
r->edns = *edns;
|
||||
if(edns->opt_list) {
|
||||
r->edns.opt_list = edns_opt_copy_region(edns->opt_list,
|
||||
Index: unbound-1.7.0~rc1/util/config_file.c
|
||||
===================================================================
|
||||
RCS file: ./util/RCS/config_file.c,v
|
||||
retrieving revision 1.1
|
||||
diff -u --unidirectional-new-file -r1.1 ./util/config_file.c
|
||||
--- ./util/config_file.c
|
||||
+++ ./util/config_file.c
|
||||
@@ -1167,6 +1167,8 @@
|
||||
--- unbound-1.7.0~rc1.orig/util/config_file.c
|
||||
+++ unbound-1.7.0~rc1/util/config_file.c
|
||||
@@ -1323,6 +1323,8 @@ config_delete(struct config_file* cfg)
|
||||
free(cfg->dnstap_socket_path);
|
||||
free(cfg->dnstap_identity);
|
||||
free(cfg->dnstap_version);
|
||||
@@ -3213,14 +3188,12 @@ diff -u --unidirectional-new-file -r1.1 ./util/config_file.c
|
||||
+ free(cfg->rpz_cstr);
|
||||
config_deldblstrlist(cfg->ratelimit_for_domain);
|
||||
config_deldblstrlist(cfg->ratelimit_below_domain);
|
||||
free(cfg);
|
||||
#ifdef USE_IPSECMOD
|
||||
Index: unbound-1.7.0~rc1/util/config_file.h
|
||||
===================================================================
|
||||
RCS file: ./util/RCS/config_file.h,v
|
||||
retrieving revision 1.1
|
||||
diff -u --unidirectional-new-file -r1.1 ./util/config_file.h
|
||||
--- ./util/config_file.h
|
||||
+++ ./util/config_file.h
|
||||
@@ -416,6 +416,11 @@
|
||||
--- unbound-1.7.0~rc1.orig/util/config_file.h
|
||||
+++ unbound-1.7.0~rc1/util/config_file.h
|
||||
@@ -431,6 +431,11 @@ struct config_file {
|
||||
/** true to disable DNSSEC lameness check in iterator */
|
||||
int disable_dnssec_lame_check;
|
||||
|
||||
@@ -3232,13 +3205,11 @@ diff -u --unidirectional-new-file -r1.1 ./util/config_file.h
|
||||
/** ratelimit for ip addresses. 0 is off, otherwise qps (unless overridden) */
|
||||
int ip_ratelimit;
|
||||
/** number of slabs for ip_ratelimit cache */
|
||||
Index: unbound-1.7.0~rc1/util/configlexer.lex
|
||||
===================================================================
|
||||
RCS file: ./util/RCS/configlexer.lex,v
|
||||
retrieving revision 1.1
|
||||
diff -u --unidirectional-new-file -r1.1 ./util/configlexer.lex
|
||||
--- ./util/configlexer.lex
|
||||
+++ ./util/configlexer.lex
|
||||
@@ -395,6 +395,10 @@
|
||||
--- unbound-1.7.0~rc1.orig/util/configlexer.lex
|
||||
+++ unbound-1.7.0~rc1/util/configlexer.lex
|
||||
@@ -412,6 +412,10 @@ dnstap-log-forwarder-query-messages{COLO
|
||||
YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES) }
|
||||
dnstap-log-forwarder-response-messages{COLON} {
|
||||
YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES) }
|
||||
@@ -3249,13 +3220,11 @@ diff -u --unidirectional-new-file -r1.1 ./util/configlexer.lex
|
||||
disable-dnssec-lame-check{COLON} { YDVAR(1, VAR_DISABLE_DNSSEC_LAME_CHECK) }
|
||||
ip-ratelimit{COLON} { YDVAR(1, VAR_IP_RATELIMIT) }
|
||||
ratelimit{COLON} { YDVAR(1, VAR_RATELIMIT) }
|
||||
Index: unbound-1.7.0~rc1/util/configparser.y
|
||||
===================================================================
|
||||
RCS file: ./util/RCS/configparser.y,v
|
||||
retrieving revision 1.1
|
||||
diff -u --unidirectional-new-file -r1.1 ./util/configparser.y
|
||||
--- ./util/configparser.y
|
||||
+++ ./util/configparser.y
|
||||
@@ -124,6 +124,7 @@
|
||||
--- unbound-1.7.0~rc1.orig/util/configparser.y
|
||||
+++ unbound-1.7.0~rc1/util/configparser.y
|
||||
@@ -124,6 +124,7 @@ extern struct config_parser_state* cfg_p
|
||||
%token VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES
|
||||
%token VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES
|
||||
%token VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES
|
||||
@@ -3263,16 +3232,16 @@ diff -u --unidirectional-new-file -r1.1 ./util/configparser.y
|
||||
%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
|
||||
@@ -153,7 +154,7 @@
|
||||
toplevelvar: serverstart contents_server | stubstart contents_stub |
|
||||
@@ -158,7 +159,7 @@ extern struct config_parser_state* cfg_p
|
||||
|
||||
%%
|
||||
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
|
||||
-toplevelvar: serverstart contents_server | stubstart contents_stub |
|
||||
+toplevelvar: serverstart contents_server | stubstart contents_stub | rpzstart contents_rpz |
|
||||
forwardstart contents_forward | pythonstart contents_py |
|
||||
rcstart contents_rc | dtstart contents_dt | viewstart
|
||||
- contents_view |
|
||||
+ contents_view | rpzstart contents_rpz |
|
||||
dnscstart contents_dnsc |
|
||||
cachedbstart contents_cachedb
|
||||
;
|
||||
@@ -2160,6 +2161,50 @@
|
||||
rcstart contents_rc | dtstart contents_dt | viewstart contents_view |
|
||||
dnscstart contents_dnsc | cachedbstart contents_cachedb |
|
||||
@@ -2384,6 +2385,50 @@ dt_dnstap_log_forwarder_response_message
|
||||
(strcmp($2, "yes")==0);
|
||||
}
|
||||
;
|
||||
@@ -3323,13 +3292,11 @@ diff -u --unidirectional-new-file -r1.1 ./util/configparser.y
|
||||
pythonstart: VAR_PYTHON
|
||||
{
|
||||
OUTYY(("\nP(python:)\n"));
|
||||
Index: unbound-1.7.0~rc1/util/data/msgencode.c
|
||||
===================================================================
|
||||
RCS file: ./util/data/RCS/msgencode.c,v
|
||||
retrieving revision 1.1
|
||||
diff -u --unidirectional-new-file -r1.1 ./util/data/msgencode.c
|
||||
--- ./util/data/msgencode.c
|
||||
+++ ./util/data/msgencode.c
|
||||
@@ -585,6 +585,35 @@
|
||||
--- unbound-1.7.0~rc1.orig/util/data/msgencode.c
|
||||
+++ unbound-1.7.0~rc1/util/data/msgencode.c
|
||||
@@ -585,6 +585,35 @@ insert_section(struct reply_info* rep, s
|
||||
return RETVAL_OK;
|
||||
}
|
||||
|
||||
@@ -3365,7 +3332,7 @@ diff -u --unidirectional-new-file -r1.1 ./util/data/msgencode.c
|
||||
/** store query section in wireformat buffer, return RETVAL */
|
||||
static int
|
||||
insert_query(struct query_info* qinfo, struct compress_tree_node** tree,
|
||||
@@ -748,6 +777,19 @@
|
||||
@@ -750,6 +779,19 @@ reply_info_encode(struct query_info* qin
|
||||
return 0;
|
||||
}
|
||||
sldns_buffer_write_u16_at(buffer, 10, arcount);
|
||||
@@ -3385,13 +3352,11 @@ diff -u --unidirectional-new-file -r1.1 ./util/data/msgencode.c
|
||||
}
|
||||
sldns_buffer_flip(buffer);
|
||||
return 1;
|
||||
Index: unbound-1.7.0~rc1/util/data/packed_rrset.c
|
||||
===================================================================
|
||||
RCS file: ./util/data/RCS/packed_rrset.c,v
|
||||
retrieving revision 1.1
|
||||
diff -u --unidirectional-new-file -r1.1 ./util/data/packed_rrset.c
|
||||
--- ./util/data/packed_rrset.c
|
||||
+++ ./util/data/packed_rrset.c
|
||||
@@ -254,6 +254,10 @@
|
||||
--- unbound-1.7.0~rc1.orig/util/data/packed_rrset.c
|
||||
+++ unbound-1.7.0~rc1/util/data/packed_rrset.c
|
||||
@@ -254,6 +254,10 @@ sec_status_to_string(enum sec_status s)
|
||||
case sec_status_indeterminate: return "sec_status_indeterminate";
|
||||
case sec_status_insecure: return "sec_status_insecure";
|
||||
case sec_status_secure: return "sec_status_secure";
|
||||
@@ -3402,13 +3367,11 @@ diff -u --unidirectional-new-file -r1.1 ./util/data/packed_rrset.c
|
||||
}
|
||||
return "unknown_sec_status_value";
|
||||
}
|
||||
Index: unbound-1.7.0~rc1/util/data/packed_rrset.h
|
||||
===================================================================
|
||||
RCS file: ./util/data/RCS/packed_rrset.h,v
|
||||
retrieving revision 1.1
|
||||
diff -u --unidirectional-new-file -r1.1 ./util/data/packed_rrset.h
|
||||
--- ./util/data/packed_rrset.h
|
||||
+++ ./util/data/packed_rrset.h
|
||||
@@ -189,7 +189,15 @@
|
||||
--- unbound-1.7.0~rc1.orig/util/data/packed_rrset.h
|
||||
+++ unbound-1.7.0~rc1/util/data/packed_rrset.h
|
||||
@@ -189,7 +189,15 @@ enum sec_status {
|
||||
sec_status_insecure,
|
||||
/** SECURE means that the object (RRset or message) validated
|
||||
* according to local policy. */
|
||||
@@ -3425,12 +3388,10 @@ diff -u --unidirectional-new-file -r1.1 ./util/data/packed_rrset.h
|
||||
};
|
||||
|
||||
/**
|
||||
Index: unbound-1.7.0~rc1/util/netevent.c
|
||||
===================================================================
|
||||
RCS file: ./util/RCS/netevent.c,v
|
||||
retrieving revision 1.1
|
||||
diff -u --unidirectional-new-file -r1.1 ./util/netevent.c
|
||||
--- ./util/netevent.c
|
||||
+++ ./util/netevent.c
|
||||
--- unbound-1.7.0~rc1.orig/util/netevent.c
|
||||
+++ unbound-1.7.0~rc1/util/netevent.c
|
||||
@@ -54,6 +54,9 @@
|
||||
#ifdef HAVE_OPENSSL_ERR_H
|
||||
#include <openssl/err.h>
|
||||
@@ -3441,7 +3402,7 @@ diff -u --unidirectional-new-file -r1.1 ./util/netevent.c
|
||||
|
||||
/* -------- Start of local definitions -------- */
|
||||
/** if CMSG_ALIGN is not defined on this platform, a workaround */
|
||||
@@ -579,6 +582,9 @@
|
||||
@@ -585,6 +588,9 @@ comm_point_udp_ancil_callback(int fd, sh
|
||||
struct cmsghdr* cmsg;
|
||||
#endif /* S_SPLINT_S */
|
||||
|
||||
@@ -3451,9 +3412,9 @@ diff -u --unidirectional-new-file -r1.1 ./util/netevent.c
|
||||
rep.c = (struct comm_point*)arg;
|
||||
log_assert(rep.c->type == comm_udp);
|
||||
|
||||
@@ -668,6 +674,9 @@
|
||||
@@ -674,6 +680,9 @@ comm_point_udp_callback(int fd, short ev
|
||||
int i;
|
||||
struct sldns_buffer *buffer;
|
||||
struct sldns_buffer *buffer;
|
||||
|
||||
+#ifdef ENABLE_FASTRPZ
|
||||
+ rep.rpz = NULL;
|
||||
@@ -3461,17 +3422,17 @@ diff -u --unidirectional-new-file -r1.1 ./util/netevent.c
|
||||
rep.c = (struct comm_point*)arg;
|
||||
log_assert(rep.c->type == comm_udp);
|
||||
|
||||
@@ -711,6 +720,9 @@
|
||||
@@ -717,6 +726,9 @@ comm_point_udp_callback(int fd, short ev
|
||||
(void)comm_point_send_udp_msg(rep.c, buffer,
|
||||
(struct sockaddr*)&rep.addr, rep.addrlen);
|
||||
}
|
||||
+#ifdef ENABLE_FASTRPZ
|
||||
+ rpz_end(&rep);
|
||||
+#endif
|
||||
if(rep.c->fd != fd) /* commpoint closed to -1 or reused for
|
||||
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;
|
||||
@@ -2145,6 +2157,9 @@
|
||||
@@ -2956,6 +2968,9 @@ comm_point_send_reply(struct comm_reply
|
||||
comm_point_start_listening(repinfo->c, -1,
|
||||
repinfo->c->tcp_timeout_msec);
|
||||
}
|
||||
@@ -3481,7 +3442,7 @@ diff -u --unidirectional-new-file -r1.1 ./util/netevent.c
|
||||
}
|
||||
|
||||
void
|
||||
@@ -2154,6 +2169,9 @@
|
||||
@@ -2965,6 +2980,9 @@ comm_point_drop_reply(struct comm_reply*
|
||||
return;
|
||||
log_assert(repinfo && repinfo->c);
|
||||
log_assert(repinfo->c->type != comm_tcp_accept);
|
||||
@@ -3491,7 +3452,7 @@ diff -u --unidirectional-new-file -r1.1 ./util/netevent.c
|
||||
if(repinfo->c->type == comm_udp)
|
||||
return;
|
||||
reclaim_tcp_handler(repinfo->c);
|
||||
@@ -2173,6 +2191,9 @@
|
||||
@@ -2984,6 +3002,9 @@ comm_point_start_listening(struct comm_p
|
||||
{
|
||||
verbose(VERB_ALGO, "comm point start listening %d",
|
||||
c->fd==-1?newfd:c->fd);
|
||||
@@ -3501,13 +3462,11 @@ diff -u --unidirectional-new-file -r1.1 ./util/netevent.c
|
||||
if(c->type == comm_tcp_accept && !c->tcp_free) {
|
||||
/* no use to start listening no free slots. */
|
||||
return;
|
||||
Index: unbound-1.7.0~rc1/util/netevent.h
|
||||
===================================================================
|
||||
RCS file: ./util/RCS/netevent.h,v
|
||||
retrieving revision 1.1
|
||||
diff -u --unidirectional-new-file -r1.1 ./util/netevent.h
|
||||
--- ./util/netevent.h
|
||||
+++ ./util/netevent.h
|
||||
@@ -117,6 +117,10 @@
|
||||
--- unbound-1.7.0~rc1.orig/util/netevent.h
|
||||
+++ unbound-1.7.0~rc1/util/netevent.h
|
||||
@@ -119,6 +119,10 @@ struct comm_reply {
|
||||
/** return type 0 (none), 4(IP4), 6(IP6) */
|
||||
int srctype;
|
||||
/* DnsCrypt context */
|
||||
@@ -3518,13 +3477,11 @@ diff -u --unidirectional-new-file -r1.1 ./util/netevent.h
|
||||
#ifdef USE_DNSCRYPT
|
||||
uint8_t client_nonce[crypto_box_HALF_NONCEBYTES];
|
||||
uint8_t nmkey[crypto_box_BEFORENMBYTES];
|
||||
Index: unbound-1.7.0~rc1/validator/validator.c
|
||||
===================================================================
|
||||
RCS file: ./validator/RCS/validator.c,v
|
||||
retrieving revision 1.1
|
||||
diff -u --unidirectional-new-file -r1.1 ./validator/validator.c
|
||||
--- ./validator/validator.c
|
||||
+++ ./validator/validator.c
|
||||
@@ -2552,6 +2552,12 @@
|
||||
--- unbound-1.7.0~rc1.orig/validator/validator.c
|
||||
+++ unbound-1.7.0~rc1/validator/validator.c
|
||||
@@ -2688,6 +2688,12 @@ ds_response_to_ke(struct module_qstate*
|
||||
default:
|
||||
/* NSEC proof did not work, try next */
|
||||
break;
|
||||
@@ -3537,7 +3494,7 @@ diff -u --unidirectional-new-file -r1.1 ./validator/validator.c
|
||||
}
|
||||
|
||||
sec = nsec3_prove_nods(qstate->env, ve,
|
||||
@@ -2584,6 +2590,12 @@
|
||||
@@ -2721,6 +2727,12 @@ ds_response_to_ke(struct module_qstate*
|
||||
default:
|
||||
/* NSEC3 proof did not work */
|
||||
break;
|
||||
@@ -3550,3 +3507,4 @@ diff -u --unidirectional-new-file -r1.1 ./validator/validator.c
|
||||
}
|
||||
|
||||
/* Apparently, no available NSEC/NSEC3 proved NODATA, so
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ 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@ @PC_PY_DEPENDENCY@
|
||||
Libs: -L${libdir} -lunbound
|
||||
Requires: @PC_LIBEVENT_DEPENDENCY@ @PC_PY_DEPENDENCY@
|
||||
Libs: -L${libdir} -lunbound -lssl -lcrypto
|
||||
Libs.private: @SSLLIB@ @LIBS@
|
||||
Cflags: -I${includedir}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
# See ltrace.conf(5) for description of syntax of this file.
|
||||
typedef ub_type = enum(TYPE_A=1,TYPE_NS=2,TYPE_SOA=6,TYPE_MX=15,TYPE_TXT=16,TYPE_AAAA=28,TYPE_DS=43,TYPE_DNSKEY=48,TYPE_TLSA=52,TYPE_ANY=255);
|
||||
typedef ub_class = enum(CLASS_IN=1,CLASS_CH=3,CLASS_NONE=254,CLASS_ANY=255);
|
||||
typedef ub_rcode = enum(RCODE_NOERROR,RCODE_FORMERR,RCODE_SERVFAIL,RCODE_NXDOMAIN,RCODE_NOTIMPL,RCODE_REFUSED,RCODE_YXDOMAIN,RCODE_YXRRSET,RCODE_NXRRSET,RCODE_NOTAUTH,RCODE_NOTZONE);
|
||||
typedef ub_havedata = enum(no_data, have_data);
|
||||
typedef ub_nxdomain = enum(name_exists, nxdomain);
|
||||
typedef ub_secure = enum(not_secure, secure);
|
||||
typedef ub_bogus = enum(not_bogus, bogus);
|
||||
typedef ub_result = struct(string, ub_type, ub_class, array(void*,zero)*, array(int,zero)*, string, ub_rcode, void*, int, ub_havedata, ub_nxdomain, ub_secure, ub_bogus, string, int);
|
||||
typedef ub_ctx = void;
|
||||
ub_ctx* ub_ctx_create(void);
|
||||
void ub_ctx_delete(ub_ctx*);
|
||||
int ub_ctx_set_option(ub_ctx*, string, string);
|
||||
int ub_ctx_get_option(ub_ctx*, string, +string*);
|
||||
int ub_ctx_config(ub_ctx*, string);
|
||||
int ub_ctx_set_fwd(ub_ctx*, string);
|
||||
int ub_ctx_set_stub(ub_ctx*, string, string, bool(int));
|
||||
int ub_ctx_resolvconf(ub_ctx*, string);
|
||||
int ub_ctx_hosts(ub_ctx*, string);
|
||||
int ub_ctx_add_ta(ub_ctx*, string);
|
||||
int ub_ctx_add_ta_file(ub_ctx*, string);
|
||||
int ub_ctx_add_ta_autr(ub_ctx*, string);
|
||||
int ub_ctx_trustedkeys(ub_ctx*, string);
|
||||
int ub_ctx_debugout(ub_ctx*, void*);
|
||||
int ub_ctx_debuglevel(ub_ctx*, int);
|
||||
int ub_ctx_async(ub_ctx*, bool(int));
|
||||
int ub_poll(ub_ctx*);
|
||||
int ub_wait(ub_ctx*);
|
||||
int ub_fd(ub_ctx*);
|
||||
int ub_process(ub_ctx*);
|
||||
int ub_resolve(ub_ctx*, string, ub_type, ub_class, +ub_result**);
|
||||
int ub_resolve_async(ub_ctx*, string, ub_type, ub_class, void*, void*, +int*);
|
||||
int ub_cancel(ub_ctx*, int);
|
||||
void ub_resolve_free(ub_result*);
|
||||
string ub_strerror(int);
|
||||
int ub_ctx_print_local_zones(ub_ctx*);
|
||||
int ub_ctx_zone_add(ub_ctx*, string, string);
|
||||
int ub_ctx_zone_remove(ub_ctx*, string);
|
||||
int ub_ctx_data_add(ub_ctx*, string);
|
||||
int ub_ctx_data_remove(ub_ctx*, string);
|
||||
string ub_version(void);
|
||||
@@ -0,0 +1,77 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import hashlib
|
||||
import sys
|
||||
import struct
|
||||
import socket
|
||||
import time
|
||||
from optparse import OptionParser
|
||||
|
||||
import dns.message
|
||||
import dns.name
|
||||
import dns.rdataclass
|
||||
import dns.rdatatype
|
||||
|
||||
def _calc_hashkey(qname, secret, qtype):
|
||||
qclass = 'IN' # CLASS is fixed for simplicity
|
||||
hobj = hashlib.sha256()
|
||||
hobj.update(dns.name.from_text(qname).to_wire())
|
||||
hobj.update(struct.pack('HH',
|
||||
socket.htons(dns.rdatatype.from_text(qtype)),
|
||||
socket.htons(dns.rdataclass.from_text(qclass))))
|
||||
hobj.update(secret)
|
||||
return hobj.hexdigest().upper()
|
||||
|
||||
def _redis_get(options, key):
|
||||
import redis
|
||||
return redis.Redis(options.address, int(options.port)).get(key)
|
||||
|
||||
def _dump_value(options, qname, key, value):
|
||||
print(';; query=%s/IN/%s' % (qname, options.qtype))
|
||||
print(';; key=%s' % key)
|
||||
if value is None:
|
||||
print(';; no value')
|
||||
return
|
||||
if len(value) < 16:
|
||||
print(';; broken value, short length: %d' % len(value))
|
||||
return
|
||||
now = int(time.time())
|
||||
timestamp = struct.unpack('!Q', value[-16:-8])[0]
|
||||
expire = struct.unpack('!Q', value[-8:])[0]
|
||||
print(';; Now=%d, TimeStamp=%d, Expire=%d, TTL=%d' %
|
||||
(now, timestamp, expire, max(expire - now, 0)))
|
||||
print(dns.message.from_wire(value[:-16]))
|
||||
|
||||
def main():
|
||||
parser = OptionParser(usage='usage: %prog [options] query_name')
|
||||
parser.add_option("-a", "--address", dest="address", action="store",
|
||||
default='127.0.0.1', help="backend-server address",
|
||||
metavar='ADDRESS')
|
||||
parser.add_option("-b", "--backend", dest="backend", action="store",
|
||||
default='redis', help="backend name",
|
||||
metavar='BACKEND')
|
||||
parser.add_option("-p", "--port", dest="port", action="store",
|
||||
default='6379', help="backend-server port",
|
||||
metavar='PORT')
|
||||
parser.add_option("-s", "--secret", dest="secret", action="store",
|
||||
default='default', help="secret seed", metavar='SECRET')
|
||||
parser.add_option("-t", "--qtype", dest="qtype", action="store",
|
||||
default='A', help="query RR type", metavar='QTYPE')
|
||||
|
||||
(options, args) = parser.parse_args()
|
||||
if len(args) < 1:
|
||||
parser.error('qname is missing')
|
||||
if options.backend == 'redis':
|
||||
get_func = _redis_get
|
||||
else:
|
||||
raise Exception('unknown backend name: %s\n' % options.backend)
|
||||
key = _calc_hashkey(args[0], options.secret, options.qtype)
|
||||
value = get_func(options, key)
|
||||
_dump_value(options, args[0], key, value)
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
main()
|
||||
except Exception as e:
|
||||
sys.stderr.write('%s\n' % e)
|
||||
exit(1)
|
||||
@@ -111,6 +111,8 @@ acl_list_str_cfg(struct acl_list* acl, const char* str, const char* s2,
|
||||
control = acl_refuse_non_local;
|
||||
else if(strcmp(s2, "allow_snoop") == 0)
|
||||
control = acl_allow_snoop;
|
||||
else if(strcmp(s2, "allow_setrd") == 0)
|
||||
control = acl_allow_setrd;
|
||||
else {
|
||||
log_err("access control type %s unknown", str);
|
||||
return 0;
|
||||
|
||||
+3
-1
@@ -63,7 +63,9 @@ enum acl_access {
|
||||
/** allow full access for recursion (+RD) queries */
|
||||
acl_allow,
|
||||
/** allow full access for all queries, recursion and cache snooping */
|
||||
acl_allow_snoop
|
||||
acl_allow_snoop,
|
||||
/** allow full access for recursion queries and set RD flag regardless of request */
|
||||
acl_allow_setrd
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
+22
-21
@@ -62,7 +62,7 @@
|
||||
|
||||
/** dump one rrset zonefile line */
|
||||
static int
|
||||
dump_rrset_line(SSL* ssl, struct ub_packed_rrset_key* k, time_t now, size_t i)
|
||||
dump_rrset_line(RES* ssl, struct ub_packed_rrset_key* k, time_t now, size_t i)
|
||||
{
|
||||
char s[65535];
|
||||
if(!packed_rr_to_string(k, i, now, s, sizeof(s))) {
|
||||
@@ -73,12 +73,13 @@ dump_rrset_line(SSL* ssl, struct ub_packed_rrset_key* k, time_t now, size_t i)
|
||||
|
||||
/** dump rrset key and data info */
|
||||
static int
|
||||
dump_rrset(SSL* ssl, struct ub_packed_rrset_key* k,
|
||||
dump_rrset(RES* ssl, struct ub_packed_rrset_key* k,
|
||||
struct packed_rrset_data* d, time_t now)
|
||||
{
|
||||
size_t i;
|
||||
/* rd lock held by caller */
|
||||
if(!k || !d) return 1;
|
||||
if(k->id == 0) return 1; /* deleted */
|
||||
if(d->ttl < now) return 1; /* expired */
|
||||
|
||||
/* meta line */
|
||||
@@ -98,7 +99,7 @@ dump_rrset(SSL* ssl, struct ub_packed_rrset_key* k,
|
||||
|
||||
/** dump lruhash rrset cache */
|
||||
static int
|
||||
dump_rrset_lruhash(SSL* ssl, struct lruhash* h, time_t now)
|
||||
dump_rrset_lruhash(RES* ssl, struct lruhash* h, time_t now)
|
||||
{
|
||||
struct lruhash_entry* e;
|
||||
/* lruhash already locked by caller */
|
||||
@@ -117,7 +118,7 @@ dump_rrset_lruhash(SSL* ssl, struct lruhash* h, time_t now)
|
||||
|
||||
/** dump rrset cache */
|
||||
static int
|
||||
dump_rrset_cache(SSL* ssl, struct worker* worker)
|
||||
dump_rrset_cache(RES* ssl, struct worker* worker)
|
||||
{
|
||||
struct rrset_cache* r = worker->env.rrset_cache;
|
||||
size_t slab;
|
||||
@@ -136,7 +137,7 @@ dump_rrset_cache(SSL* ssl, struct worker* worker)
|
||||
|
||||
/** dump message to rrset reference */
|
||||
static int
|
||||
dump_msg_ref(SSL* ssl, struct ub_packed_rrset_key* k)
|
||||
dump_msg_ref(RES* ssl, struct ub_packed_rrset_key* k)
|
||||
{
|
||||
char* nm, *tp, *cl;
|
||||
nm = sldns_wire2str_dname(k->rk.dname, k->rk.dname_len);
|
||||
@@ -163,7 +164,7 @@ dump_msg_ref(SSL* ssl, struct ub_packed_rrset_key* k)
|
||||
|
||||
/** dump message entry */
|
||||
static int
|
||||
dump_msg(SSL* ssl, struct query_info* k, struct reply_info* d,
|
||||
dump_msg(RES* ssl, struct query_info* k, struct reply_info* d,
|
||||
time_t now)
|
||||
{
|
||||
size_t i;
|
||||
@@ -245,7 +246,7 @@ copy_msg(struct regional* region, struct lruhash_entry* e,
|
||||
|
||||
/** dump lruhash msg cache */
|
||||
static int
|
||||
dump_msg_lruhash(SSL* ssl, struct worker* worker, struct lruhash* h)
|
||||
dump_msg_lruhash(RES* ssl, struct worker* worker, struct lruhash* h)
|
||||
{
|
||||
struct lruhash_entry* e;
|
||||
struct query_info* k;
|
||||
@@ -273,7 +274,7 @@ dump_msg_lruhash(SSL* ssl, struct worker* worker, struct lruhash* h)
|
||||
|
||||
/** dump msg cache */
|
||||
static int
|
||||
dump_msg_cache(SSL* ssl, struct worker* worker)
|
||||
dump_msg_cache(RES* ssl, struct worker* worker)
|
||||
{
|
||||
struct slabhash* sh = worker->env.msg_cache;
|
||||
size_t slab;
|
||||
@@ -290,7 +291,7 @@ dump_msg_cache(SSL* ssl, struct worker* worker)
|
||||
}
|
||||
|
||||
int
|
||||
dump_cache(SSL* ssl, struct worker* worker)
|
||||
dump_cache(RES* ssl, struct worker* worker)
|
||||
{
|
||||
if(!dump_rrset_cache(ssl, worker))
|
||||
return 0;
|
||||
@@ -301,7 +302,7 @@ dump_cache(SSL* ssl, struct worker* worker)
|
||||
|
||||
/** read a line from ssl into buffer */
|
||||
static int
|
||||
ssl_read_buf(SSL* ssl, sldns_buffer* buf)
|
||||
ssl_read_buf(RES* ssl, sldns_buffer* buf)
|
||||
{
|
||||
return ssl_read_line(ssl, (char*)sldns_buffer_begin(buf),
|
||||
sldns_buffer_capacity(buf));
|
||||
@@ -309,7 +310,7 @@ ssl_read_buf(SSL* ssl, sldns_buffer* buf)
|
||||
|
||||
/** check fixed text on line */
|
||||
static int
|
||||
read_fixed(SSL* ssl, sldns_buffer* buf, const char* str)
|
||||
read_fixed(RES* ssl, sldns_buffer* buf, const char* str)
|
||||
{
|
||||
if(!ssl_read_buf(ssl, buf)) return 0;
|
||||
return (strcmp((char*)sldns_buffer_begin(buf), str) == 0);
|
||||
@@ -317,7 +318,7 @@ read_fixed(SSL* ssl, sldns_buffer* buf, const char* str)
|
||||
|
||||
/** load an RR into rrset */
|
||||
static int
|
||||
load_rr(SSL* ssl, sldns_buffer* buf, struct regional* region,
|
||||
load_rr(RES* ssl, sldns_buffer* buf, struct regional* region,
|
||||
struct ub_packed_rrset_key* rk, struct packed_rrset_data* d,
|
||||
unsigned int i, int is_rrsig, int* go_on, time_t now)
|
||||
{
|
||||
@@ -434,7 +435,7 @@ move_into_cache(struct ub_packed_rrset_key* k,
|
||||
|
||||
/** load an rrset entry */
|
||||
static int
|
||||
load_rrset(SSL* ssl, sldns_buffer* buf, struct worker* worker)
|
||||
load_rrset(RES* ssl, sldns_buffer* buf, struct worker* worker)
|
||||
{
|
||||
char* s = (char*)sldns_buffer_begin(buf);
|
||||
struct regional* region = worker->scratchpad;
|
||||
@@ -518,7 +519,7 @@ load_rrset(SSL* ssl, sldns_buffer* buf, struct worker* worker)
|
||||
|
||||
/** load rrset cache */
|
||||
static int
|
||||
load_rrset_cache(SSL* ssl, struct worker* worker)
|
||||
load_rrset_cache(RES* ssl, struct worker* worker)
|
||||
{
|
||||
sldns_buffer* buf = worker->env.scratch_buffer;
|
||||
if(!read_fixed(ssl, buf, "START_RRSET_CACHE")) return 0;
|
||||
@@ -574,7 +575,7 @@ load_qinfo(char* str, struct query_info* qinfo, struct regional* region)
|
||||
|
||||
/** load a msg rrset reference */
|
||||
static int
|
||||
load_ref(SSL* ssl, sldns_buffer* buf, struct worker* worker,
|
||||
load_ref(RES* ssl, sldns_buffer* buf, struct worker* worker,
|
||||
struct regional *region, struct ub_packed_rrset_key** rrset,
|
||||
int* go_on)
|
||||
{
|
||||
@@ -619,7 +620,7 @@ load_ref(SSL* ssl, sldns_buffer* buf, struct worker* worker,
|
||||
|
||||
/** load a msg entry */
|
||||
static int
|
||||
load_msg(SSL* ssl, sldns_buffer* buf, struct worker* worker)
|
||||
load_msg(RES* ssl, sldns_buffer* buf, struct worker* worker)
|
||||
{
|
||||
struct regional* region = worker->scratchpad;
|
||||
struct query_info qinf;
|
||||
@@ -684,7 +685,7 @@ load_msg(SSL* ssl, sldns_buffer* buf, struct worker* worker)
|
||||
|
||||
/** load msg cache */
|
||||
static int
|
||||
load_msg_cache(SSL* ssl, struct worker* worker)
|
||||
load_msg_cache(RES* ssl, struct worker* worker)
|
||||
{
|
||||
sldns_buffer* buf = worker->env.scratch_buffer;
|
||||
if(!read_fixed(ssl, buf, "START_MSG_CACHE")) return 0;
|
||||
@@ -697,7 +698,7 @@ load_msg_cache(SSL* ssl, struct worker* worker)
|
||||
}
|
||||
|
||||
int
|
||||
load_cache(SSL* ssl, struct worker* worker)
|
||||
load_cache(RES* ssl, struct worker* worker)
|
||||
{
|
||||
if(!load_rrset_cache(ssl, worker))
|
||||
return 0;
|
||||
@@ -708,7 +709,7 @@ load_cache(SSL* ssl, struct worker* worker)
|
||||
|
||||
/** print details on a delegation point */
|
||||
static void
|
||||
print_dp_details(SSL* ssl, struct worker* worker, struct delegpt* dp)
|
||||
print_dp_details(RES* ssl, struct worker* worker, struct delegpt* dp)
|
||||
{
|
||||
char buf[257];
|
||||
struct delegpt_addr* a;
|
||||
@@ -784,7 +785,7 @@ print_dp_details(SSL* ssl, struct worker* worker, struct delegpt* dp)
|
||||
|
||||
/** print main dp info */
|
||||
static void
|
||||
print_dp_main(SSL* ssl, struct delegpt* dp, struct dns_msg* msg)
|
||||
print_dp_main(RES* ssl, struct delegpt* dp, struct dns_msg* msg)
|
||||
{
|
||||
size_t i, n_ns, n_miss, n_addr, n_res, n_avail;
|
||||
|
||||
@@ -812,7 +813,7 @@ print_dp_main(SSL* ssl, struct delegpt* dp, struct dns_msg* msg)
|
||||
return;
|
||||
}
|
||||
|
||||
int print_deleg_lookup(SSL* ssl, struct worker* worker, uint8_t* nm,
|
||||
int print_deleg_lookup(RES* ssl, struct worker* worker, uint8_t* nm,
|
||||
size_t nmlen, int ATTR_UNUSED(nmlabs))
|
||||
{
|
||||
/* deep links into the iterator module */
|
||||
|
||||
+4
-3
@@ -72,6 +72,7 @@
|
||||
#ifndef DAEMON_DUMPCACHE_H
|
||||
#define DAEMON_DUMPCACHE_H
|
||||
struct worker;
|
||||
#include "daemon/remote.h"
|
||||
|
||||
/**
|
||||
* Dump cache(s) to text
|
||||
@@ -80,7 +81,7 @@ struct worker;
|
||||
* ptrs to the caches.
|
||||
* @return false on ssl print error.
|
||||
*/
|
||||
int dump_cache(SSL* ssl, struct worker* worker);
|
||||
int dump_cache(RES* ssl, struct worker* worker);
|
||||
|
||||
/**
|
||||
* Load cache(s) from text
|
||||
@@ -89,7 +90,7 @@ int dump_cache(SSL* ssl, struct worker* worker);
|
||||
* ptrs to the caches.
|
||||
* @return false on ssl error.
|
||||
*/
|
||||
int load_cache(SSL* ssl, struct worker* worker);
|
||||
int load_cache(RES* ssl, struct worker* worker);
|
||||
|
||||
/**
|
||||
* Print the delegation used to lookup for this name.
|
||||
@@ -101,7 +102,7 @@ int load_cache(SSL* ssl, struct worker* worker);
|
||||
* @param nmlabs: labels in name.
|
||||
* @return false on ssl error.
|
||||
*/
|
||||
int print_deleg_lookup(SSL* ssl, struct worker* worker, uint8_t* nm,
|
||||
int print_deleg_lookup(RES* ssl, struct worker* worker, uint8_t* nm,
|
||||
size_t nmlen, int nmlabs);
|
||||
|
||||
#endif /* DAEMON_DUMPCACHE_H */
|
||||
|
||||
@@ -82,6 +82,7 @@
|
||||
#include "services/localzone.h"
|
||||
#include "services/view.h"
|
||||
#include "services/modstack.h"
|
||||
#include "services/authzone.h"
|
||||
#include "util/module.h"
|
||||
#include "util/random.h"
|
||||
#include "util/tube.h"
|
||||
@@ -281,6 +282,13 @@ daemon_init(void)
|
||||
if(gettimeofday(&daemon->time_boot, NULL) < 0)
|
||||
log_err("gettimeofday: %s", strerror(errno));
|
||||
daemon->time_last_stat = daemon->time_boot;
|
||||
if((daemon->env->auth_zones = auth_zones_create()) == 0) {
|
||||
acl_list_delete(daemon->acl);
|
||||
edns_known_options_delete(daemon->env);
|
||||
free(daemon->env);
|
||||
free(daemon);
|
||||
return NULL;
|
||||
}
|
||||
return daemon;
|
||||
}
|
||||
|
||||
@@ -603,6 +611,10 @@ daemon_fork(struct daemon* daemon)
|
||||
fatal_exit("Could not set up per-view response IP sets");
|
||||
daemon->use_response_ip = !respip_set_is_empty(daemon->respip_set) ||
|
||||
have_view_respip_cfg;
|
||||
|
||||
/* read auth zonefiles */
|
||||
if(!auth_zones_apply_cfg(daemon->env->auth_zones, daemon->cfg, 1))
|
||||
fatal_exit("auth_zones could not be setup");
|
||||
|
||||
/* setup modules */
|
||||
daemon_setup_modules(daemon);
|
||||
@@ -683,6 +695,8 @@ daemon_cleanup(struct daemon* daemon)
|
||||
daemon->respip_set = NULL;
|
||||
views_delete(daemon->views);
|
||||
daemon->views = NULL;
|
||||
if(daemon->env->auth_zones)
|
||||
auth_zones_cleanup(daemon->env->auth_zones);
|
||||
/* key cache is cleared by module desetup during next daemon_fork() */
|
||||
daemon_remote_clear(daemon->rc);
|
||||
for(i=0; i<daemon->num; i++)
|
||||
@@ -690,11 +704,14 @@ daemon_cleanup(struct daemon* daemon)
|
||||
free(daemon->workers);
|
||||
daemon->workers = NULL;
|
||||
daemon->num = 0;
|
||||
alloc_clear_special(&daemon->superalloc);
|
||||
#ifdef USE_DNSTAP
|
||||
dt_delete(daemon->dtenv);
|
||||
daemon->dtenv = NULL;
|
||||
#endif
|
||||
#ifdef USE_DNSCRYPT
|
||||
dnsc_delete(daemon->dnscenv);
|
||||
daemon->dnscenv = NULL;
|
||||
#endif
|
||||
daemon->cfg = NULL;
|
||||
}
|
||||
@@ -716,6 +733,7 @@ daemon_delete(struct daemon* daemon)
|
||||
rrset_cache_delete(daemon->env->rrset_cache);
|
||||
infra_delete(daemon->env->infra_cache);
|
||||
edns_known_options_delete(daemon->env);
|
||||
auth_zones_delete(daemon->env->auth_zones);
|
||||
}
|
||||
ub_randfree(daemon->rand);
|
||||
alloc_clear(&daemon->superalloc);
|
||||
@@ -763,6 +781,9 @@ daemon_delete(struct daemon* daemon)
|
||||
# if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED)
|
||||
ub_openssl_lock_delete();
|
||||
# endif
|
||||
#ifndef HAVE_ARC4RANDOM
|
||||
_ARC4_LOCK_DESTROY();
|
||||
#endif
|
||||
#elif defined(HAVE_NSS)
|
||||
NSS_Shutdown();
|
||||
#endif /* HAVE_SSL or HAVE_NSS */
|
||||
|
||||
+302
-263
File diff suppressed because it is too large
Load Diff
+21
-6
@@ -73,6 +73,8 @@ struct rc_state {
|
||||
/** the ssl state */
|
||||
SSL* ssl;
|
||||
#endif
|
||||
/** file descriptor */
|
||||
int fd;
|
||||
/** the rc this is part of */
|
||||
struct daemon_remote* rc;
|
||||
};
|
||||
@@ -103,6 +105,19 @@ struct daemon_remote {
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* Connection to print to, either SSL or plain over fd
|
||||
*/
|
||||
struct remote_stream {
|
||||
#ifdef HAVE_SSL
|
||||
/** SSL structure, nonNULL if using SSL */
|
||||
SSL* ssl;
|
||||
#endif
|
||||
/** file descriptor for plain transfer */
|
||||
int fd;
|
||||
};
|
||||
typedef struct remote_stream RES;
|
||||
|
||||
/**
|
||||
* Create new remote control state for the daemon.
|
||||
* @param cfg: config file with key file settings.
|
||||
@@ -166,26 +181,26 @@ void daemon_remote_exec(struct worker* worker);
|
||||
* @param text: the text.
|
||||
* @return false on connection failure.
|
||||
*/
|
||||
int ssl_print_text(SSL* ssl, const char* text);
|
||||
int ssl_print_text(RES* ssl, const char* text);
|
||||
|
||||
/**
|
||||
* printf style printing to the ssl connection
|
||||
* @param ssl: the SSL connection to print to. Blocking.
|
||||
* @param ssl: the RES connection to print to. Blocking.
|
||||
* @param format: printf style format string.
|
||||
* @return success or false on a network failure.
|
||||
*/
|
||||
int ssl_printf(SSL* ssl, const char* format, ...)
|
||||
int ssl_printf(RES* ssl, const char* format, ...)
|
||||
ATTR_FORMAT(printf, 2, 3);
|
||||
|
||||
/**
|
||||
* Read until \n is encountered
|
||||
* If SSL signals EOF, the string up to then is returned (without \n).
|
||||
* @param ssl: the SSL connection to read from. blocking.
|
||||
* If stream signals EOF, the string up to then is returned (without \n).
|
||||
* @param ssl: the RES connection to read from. blocking.
|
||||
* @param buf: buffer to read to.
|
||||
* @param max: size of buffer.
|
||||
* @return false on connection failure.
|
||||
*/
|
||||
int ssl_read_line(SSL* ssl, char* buf, size_t max);
|
||||
int ssl_read_line(RES* ssl, char* buf, size_t max);
|
||||
#endif /* HAVE_SSL */
|
||||
|
||||
#endif /* DAEMON_REMOTE_H */
|
||||
|
||||
@@ -60,7 +60,9 @@
|
||||
#include "sldns/sbuffer.h"
|
||||
#include "services/cache/rrset.h"
|
||||
#include "services/cache/infra.h"
|
||||
#include "services/authzone.h"
|
||||
#include "validator/val_kcache.h"
|
||||
#include "validator/val_neg.h"
|
||||
|
||||
/** add timers and the values do not overflow or become negative */
|
||||
static void
|
||||
@@ -122,6 +124,30 @@ void server_stats_log(struct ub_server_stats* stats, struct worker* worker,
|
||||
(unsigned)worker->env.mesh->stats_jostled);
|
||||
}
|
||||
|
||||
/** Set the neg cache stats. */
|
||||
static void
|
||||
set_neg_cache_stats(struct worker* worker, struct ub_server_stats* svr,
|
||||
int reset)
|
||||
{
|
||||
int m = modstack_find(&worker->env.mesh->mods, "validator");
|
||||
struct val_env* ve;
|
||||
struct val_neg_cache* neg;
|
||||
if(m == -1)
|
||||
return;
|
||||
ve = (struct val_env*)worker->env.modinfo[m];
|
||||
if(!ve->neg_cache)
|
||||
return;
|
||||
neg = ve->neg_cache;
|
||||
lock_basic_lock(&neg->lock);
|
||||
svr->num_neg_cache_noerror = (long long)neg->num_neg_cache_noerror;
|
||||
svr->num_neg_cache_nxdomain = (long long)neg->num_neg_cache_nxdomain;
|
||||
if(reset && !worker->env.cfg->stat_cumulative) {
|
||||
neg->num_neg_cache_noerror = 0;
|
||||
neg->num_neg_cache_nxdomain = 0;
|
||||
}
|
||||
lock_basic_unlock(&neg->lock);
|
||||
}
|
||||
|
||||
/** get rrsets bogus number from validator */
|
||||
static size_t
|
||||
get_rrset_bogus(struct worker* worker, int reset)
|
||||
@@ -256,6 +282,25 @@ server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset)
|
||||
s->svr.nonce_cache_count = 0;
|
||||
s->svr.num_query_dnscrypt_replay = 0;
|
||||
#endif /* USE_DNSCRYPT */
|
||||
if(worker->env.auth_zones) {
|
||||
if(reset && !worker->env.cfg->stat_cumulative) {
|
||||
lock_rw_wrlock(&worker->env.auth_zones->lock);
|
||||
} else {
|
||||
lock_rw_rdlock(&worker->env.auth_zones->lock);
|
||||
}
|
||||
s->svr.num_query_authzone_up = (long long)worker->env.
|
||||
auth_zones->num_query_up;
|
||||
s->svr.num_query_authzone_down = (long long)worker->env.
|
||||
auth_zones->num_query_down;
|
||||
if(reset && !worker->env.cfg->stat_cumulative) {
|
||||
worker->env.auth_zones->num_query_up = 0;
|
||||
worker->env.auth_zones->num_query_down = 0;
|
||||
}
|
||||
lock_rw_unlock(&worker->env.auth_zones->lock);
|
||||
}
|
||||
|
||||
/* Set neg cache usage numbers */
|
||||
set_neg_cache_stats(worker, &s->svr, reset);
|
||||
|
||||
/* get tcp accept usage */
|
||||
s->svr.tcp_accept_usage = 0;
|
||||
|
||||
+19
-13
@@ -421,6 +421,20 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
|
||||
w_config_adjust_directory(cfg);
|
||||
#endif
|
||||
|
||||
/* read ssl keys while superuser and outside chroot */
|
||||
#ifdef HAVE_SSL
|
||||
if(!(daemon->rc = daemon_remote_create(cfg)))
|
||||
fatal_exit("could not set up remote-control");
|
||||
if(cfg->ssl_service_key && cfg->ssl_service_key[0]) {
|
||||
if(!(daemon->listen_sslctx = listen_sslctx_create(
|
||||
cfg->ssl_service_key, cfg->ssl_service_pem, NULL)))
|
||||
fatal_exit("could not set up listen SSL_CTX");
|
||||
}
|
||||
if(!(daemon->connect_sslctx = connect_sslctx_create(NULL, NULL,
|
||||
cfg->tls_cert_bundle, cfg->tls_win_cert)))
|
||||
fatal_exit("could not set up connect SSL_CTX");
|
||||
#endif
|
||||
|
||||
/* init syslog (as root) if needed, before daemonize, otherwise
|
||||
* a fork error could not be printed since daemonize closed stderr.*/
|
||||
if(cfg->use_syslog) {
|
||||
@@ -432,19 +446,6 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
|
||||
* So, using a logfile, the user does not see errors unless -d is
|
||||
* given to unbound on the commandline. */
|
||||
|
||||
/* read ssl keys while superuser and outside chroot */
|
||||
#ifdef HAVE_SSL
|
||||
if(!(daemon->rc = daemon_remote_create(cfg)))
|
||||
fatal_exit("could not set up remote-control");
|
||||
if(cfg->ssl_service_key && cfg->ssl_service_key[0]) {
|
||||
if(!(daemon->listen_sslctx = listen_sslctx_create(
|
||||
cfg->ssl_service_key, cfg->ssl_service_pem, NULL)))
|
||||
fatal_exit("could not set up listen SSL_CTX");
|
||||
}
|
||||
if(!(daemon->connect_sslctx = connect_sslctx_create(NULL, NULL, NULL)))
|
||||
fatal_exit("could not set up connect SSL_CTX");
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_KILL
|
||||
/* true if pidfile is inside chrootdir, or nochroot */
|
||||
pidinchroot = need_pidfile && (!(cfg->chrootdir && cfg->chrootdir[0]) ||
|
||||
@@ -744,5 +745,10 @@ main(int argc, char* argv[])
|
||||
|
||||
run_daemon(cfgfile, cmdline_verbose, debug_mode, log_ident_default, need_pidfile);
|
||||
log_init(NULL, 0, NULL); /* close logfile */
|
||||
#ifndef unbound_testbound
|
||||
if(log_get_lock()) {
|
||||
lock_quick_destroy((lock_quick_type*)log_get_lock());
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
+120
-18
@@ -58,6 +58,7 @@
|
||||
#include "services/cache/rrset.h"
|
||||
#include "services/cache/infra.h"
|
||||
#include "services/cache/dns.h"
|
||||
#include "services/authzone.h"
|
||||
#include "services/mesh.h"
|
||||
#include "services/localzone.h"
|
||||
#include "util/data/msgparse.h"
|
||||
@@ -341,7 +342,8 @@ worker_check_request(sldns_buffer* pkt, struct worker* worker)
|
||||
verbose(VERB_QUERY, "request bad, has TC bit on");
|
||||
return worker_err_ratelimit(worker, LDNS_RCODE_FORMERR);
|
||||
}
|
||||
if(LDNS_OPCODE_WIRE(sldns_buffer_begin(pkt)) != LDNS_PACKET_QUERY) {
|
||||
if(LDNS_OPCODE_WIRE(sldns_buffer_begin(pkt)) != LDNS_PACKET_QUERY &&
|
||||
LDNS_OPCODE_WIRE(sldns_buffer_begin(pkt)) != LDNS_PACKET_NOTIFY) {
|
||||
verbose(VERB_QUERY, "request unknown opcode %d",
|
||||
LDNS_OPCODE_WIRE(sldns_buffer_begin(pkt)));
|
||||
return worker_err_ratelimit(worker, LDNS_RCODE_NOTIMPL);
|
||||
@@ -351,7 +353,9 @@ worker_check_request(sldns_buffer* pkt, struct worker* worker)
|
||||
LDNS_QDCOUNT(sldns_buffer_begin(pkt)));
|
||||
return worker_err_ratelimit(worker, LDNS_RCODE_FORMERR);
|
||||
}
|
||||
if(LDNS_ANCOUNT(sldns_buffer_begin(pkt)) != 0) {
|
||||
if(LDNS_ANCOUNT(sldns_buffer_begin(pkt)) != 0 &&
|
||||
(LDNS_ANCOUNT(sldns_buffer_begin(pkt)) != 1 ||
|
||||
LDNS_OPCODE_WIRE(sldns_buffer_begin(pkt)) != LDNS_PACKET_NOTIFY)) {
|
||||
verbose(VERB_QUERY, "request wrong nr an=%d",
|
||||
LDNS_ANCOUNT(sldns_buffer_begin(pkt)));
|
||||
return worker_err_ratelimit(worker, LDNS_RCODE_FORMERR);
|
||||
@@ -498,6 +502,7 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
* let validator do that */
|
||||
return 0;
|
||||
case sec_status_bogus:
|
||||
case sec_status_secure_sentinel_fail:
|
||||
/* some rrsets are bogus, reply servfail */
|
||||
edns->edns_version = EDNS_ADVERTISED_VERSION;
|
||||
edns->udp_size = EDNS_ADVERTISED_SIZE;
|
||||
@@ -654,7 +659,8 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
}
|
||||
}
|
||||
/* check security status of the cached answer */
|
||||
if( rep->security == sec_status_bogus && must_validate) {
|
||||
if(must_validate && (rep->security == sec_status_bogus ||
|
||||
rep->security == sec_status_secure_sentinel_fail)) {
|
||||
/* BAD cached */
|
||||
edns->edns_version = EDNS_ADVERTISED_VERSION;
|
||||
edns->udp_size = EDNS_ADVERTISED_SIZE;
|
||||
@@ -939,6 +945,66 @@ answer_chaos(struct worker* w, struct query_info* qinfo,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Answer notify queries. These are notifies for authoritative zones,
|
||||
* the reply is an ack that the notify has been received. We need to check
|
||||
* access permission here.
|
||||
* @param w: worker
|
||||
* @param qinfo: query info. Pointer into packet buffer.
|
||||
* @param edns: edns info from query.
|
||||
* @param repinfo: reply info with source address.
|
||||
* @param pkt: packet buffer.
|
||||
*/
|
||||
static void
|
||||
answer_notify(struct worker* w, struct query_info* qinfo,
|
||||
struct edns_data* edns, sldns_buffer* pkt, struct comm_reply* repinfo)
|
||||
{
|
||||
int refused = 0;
|
||||
int rcode = LDNS_RCODE_NOERROR;
|
||||
uint32_t serial = 0;
|
||||
int has_serial;
|
||||
if(!w->env.auth_zones) return;
|
||||
has_serial = auth_zone_parse_notify_serial(pkt, &serial);
|
||||
if(auth_zones_notify(w->env.auth_zones, &w->env, qinfo->qname,
|
||||
qinfo->qname_len, qinfo->qclass, &repinfo->addr,
|
||||
repinfo->addrlen, has_serial, serial, &refused)) {
|
||||
rcode = LDNS_RCODE_NOERROR;
|
||||
} else {
|
||||
if(refused)
|
||||
rcode = LDNS_RCODE_REFUSED;
|
||||
else rcode = LDNS_RCODE_SERVFAIL;
|
||||
}
|
||||
|
||||
if(verbosity >= VERB_DETAIL) {
|
||||
char buf[380];
|
||||
char zname[255+1];
|
||||
char sr[25];
|
||||
dname_str(qinfo->qname, zname);
|
||||
sr[0]=0;
|
||||
if(has_serial)
|
||||
snprintf(sr, sizeof(sr), "serial %u ",
|
||||
(unsigned)serial);
|
||||
if(rcode == LDNS_RCODE_REFUSED)
|
||||
snprintf(buf, sizeof(buf),
|
||||
"refused NOTIFY %sfor %s from", sr, zname);
|
||||
else if(rcode == LDNS_RCODE_SERVFAIL)
|
||||
snprintf(buf, sizeof(buf),
|
||||
"servfail for NOTIFY %sfor %s from", sr, zname);
|
||||
else snprintf(buf, sizeof(buf),
|
||||
"received NOTIFY %sfor %s from", sr, zname);
|
||||
log_addr(VERB_DETAIL, buf, &repinfo->addr, repinfo->addrlen);
|
||||
}
|
||||
edns->edns_version = EDNS_ADVERTISED_VERSION;
|
||||
edns->udp_size = EDNS_ADVERTISED_SIZE;
|
||||
edns->ext_rcode = 0;
|
||||
edns->bits &= EDNS_DO;
|
||||
edns->opt_list = NULL;
|
||||
error_encode(pkt, rcode, qinfo,
|
||||
*(uint16_t*)(void *)sldns_buffer_begin(pkt),
|
||||
sldns_buffer_read_u16_at(pkt, 2), edns);
|
||||
LDNS_OPCODE_SET(sldns_buffer_begin(pkt), LDNS_PACKET_NOTIFY);
|
||||
}
|
||||
|
||||
static int
|
||||
deny_refuse(struct comm_point* c, enum acl_access acl,
|
||||
enum acl_access deny, enum acl_access refuse,
|
||||
@@ -1046,7 +1112,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
strcasecmp(buf,
|
||||
worker->daemon->dnscenv->provider_name) == 0)) {
|
||||
verbose(VERB_ALGO,
|
||||
"dnscrypt: not TXT %s. Receive: %s %s",
|
||||
"dnscrypt: not TXT \"%s\". Received: %s \"%s\"",
|
||||
worker->daemon->dnscenv->provider_name,
|
||||
sldns_rr_descript(qinfo.qtype)->_name,
|
||||
buf);
|
||||
@@ -1237,6 +1303,12 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
regional_free_all(worker->scratchpad);
|
||||
goto send_reply;
|
||||
}
|
||||
if(LDNS_OPCODE_WIRE(sldns_buffer_begin(c->buffer)) ==
|
||||
LDNS_PACKET_NOTIFY) {
|
||||
answer_notify(worker, &qinfo, &edns, c->buffer, repinfo);
|
||||
regional_free_all(worker->scratchpad);
|
||||
goto send_reply;
|
||||
}
|
||||
if(local_zones_answer(worker->daemon->local_zones, &worker->env, &qinfo,
|
||||
&edns, c->buffer, worker->scratchpad, repinfo, acladdr->taglist,
|
||||
acladdr->taglen, acladdr->tag_actions,
|
||||
@@ -1251,6 +1323,22 @@ 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 &&
|
||||
auth_zones_answer(worker->env.auth_zones, &worker->env,
|
||||
&qinfo, &edns, c->buffer, worker->scratchpad)) {
|
||||
regional_free_all(worker->scratchpad);
|
||||
if(sldns_buffer_limit(c->buffer) == 0) {
|
||||
comm_point_drop_reply(repinfo);
|
||||
return 0;
|
||||
}
|
||||
/* set RA for everyone that can have recursion (based on
|
||||
* access control list) */
|
||||
if(LDNS_RD_WIRE(sldns_buffer_begin(c->buffer)) &&
|
||||
acl != acl_deny_non_local && acl != acl_refuse_non_local)
|
||||
LDNS_RA_SET(sldns_buffer_begin(c->buffer));
|
||||
server_stats_insrcode(&worker->stats, c->buffer);
|
||||
goto send_reply;
|
||||
}
|
||||
|
||||
/* We've looked in our local zones. If the answer isn't there, we
|
||||
* might need to bail out based on ACLs now. */
|
||||
@@ -1262,17 +1350,20 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* If this request does not have the recursion bit set, verify
|
||||
* ACLs allow the recursion bit to be treated as set. */
|
||||
if(!(LDNS_RD_WIRE(sldns_buffer_begin(c->buffer))) &&
|
||||
acl == acl_allow_setrd ) {
|
||||
LDNS_RD_SET(sldns_buffer_begin(c->buffer));
|
||||
}
|
||||
|
||||
/* If this request does not have the recursion bit set, verify
|
||||
* ACLs allow the snooping. */
|
||||
if(!(LDNS_RD_WIRE(sldns_buffer_begin(c->buffer))) &&
|
||||
acl != acl_allow_snoop ) {
|
||||
sldns_buffer_set_limit(c->buffer, LDNS_HEADER_SIZE);
|
||||
sldns_buffer_write_at(c->buffer, 4,
|
||||
(uint8_t*)"\0\0\0\0\0\0\0\0", 8);
|
||||
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
|
||||
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
|
||||
LDNS_RCODE_REFUSED);
|
||||
sldns_buffer_flip(c->buffer);
|
||||
error_encode(c->buffer, LDNS_RCODE_REFUSED, &qinfo,
|
||||
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
|
||||
sldns_buffer_read_u16_at(c->buffer, 2), NULL);
|
||||
regional_free_all(worker->scratchpad);
|
||||
server_stats_insrcode(&worker->stats, c->buffer);
|
||||
log_addr(VERB_ALGO, "refused nonrec (cache snoop) query from",
|
||||
@@ -1326,11 +1417,11 @@ 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,
|
||||
if(answer_from_cache(worker, &qinfo,
|
||||
cinfo, &need_drop, &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,
|
||||
(struct reply_info*)e->data,
|
||||
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
|
||||
sldns_buffer_read_u16_at(c->buffer, 2), repinfo,
|
||||
&edns)) {
|
||||
/* prefetch it if the prefetch TTL expired.
|
||||
* Note that if there is more than one pass
|
||||
@@ -1672,8 +1763,10 @@ worker_init(struct worker* worker, struct config_file *cfg,
|
||||
if(worker->thread_num == 0)
|
||||
log_set_time(worker->env.now);
|
||||
worker->env.worker = worker;
|
||||
worker->env.worker_base = worker->base;
|
||||
worker->env.send_query = &worker_send_query;
|
||||
worker->env.alloc = &worker->alloc;
|
||||
worker->env.outnet = worker->back;
|
||||
worker->env.rnd = worker->rndstate;
|
||||
/* If case prefetch is triggered, the corresponding mesh will clear
|
||||
* the scratchpad for the module env in the middle of request handling.
|
||||
@@ -1723,6 +1816,14 @@ worker_init(struct worker* worker, struct config_file *cfg,
|
||||
comm_timer_set(worker->env.probe_timer, &tv);
|
||||
}
|
||||
}
|
||||
/* zone transfer tasks, setup once per process, if any */
|
||||
if(worker->env.auth_zones
|
||||
#ifndef THREADS_DISABLED
|
||||
&& worker->thread_num == 0
|
||||
#endif
|
||||
) {
|
||||
auth_xfer_pickup_initial(worker->env.auth_zones, &worker->env);
|
||||
}
|
||||
if(!worker->env.mesh || !worker->env.scratch_buffer) {
|
||||
worker_delete(worker);
|
||||
return 0;
|
||||
@@ -1783,7 +1884,7 @@ struct outbound_entry*
|
||||
worker_send_query(struct query_info* qinfo, uint16_t flags, int dnssec,
|
||||
int want_dnssec, int nocaps, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, uint8_t* zone, size_t zonelen, int ssl_upstream,
|
||||
struct module_qstate* q)
|
||||
char* tls_auth_name, struct module_qstate* q)
|
||||
{
|
||||
struct worker* worker = q->env->worker;
|
||||
struct outbound_entry* e = (struct outbound_entry*)regional_alloc(
|
||||
@@ -1793,7 +1894,7 @@ worker_send_query(struct query_info* qinfo, uint16_t flags, int dnssec,
|
||||
e->qstate = q;
|
||||
e->qsent = outnet_serviced_query(worker->back, qinfo, flags, dnssec,
|
||||
want_dnssec, nocaps, q->env->cfg->tcp_upstream,
|
||||
ssl_upstream, addr, addrlen, zone, zonelen, q,
|
||||
ssl_upstream, tls_auth_name, addr, addrlen, zone, zonelen, q,
|
||||
worker_handle_service_reply, e, worker->back->udp_buff, q->env);
|
||||
if(!e->qsent) {
|
||||
return NULL;
|
||||
@@ -1840,7 +1941,8 @@ struct outbound_entry* libworker_send_query(
|
||||
int ATTR_UNUSED(want_dnssec), int ATTR_UNUSED(nocaps),
|
||||
struct sockaddr_storage* ATTR_UNUSED(addr), socklen_t ATTR_UNUSED(addrlen),
|
||||
uint8_t* ATTR_UNUSED(zone), size_t ATTR_UNUSED(zonelen),
|
||||
int ATTR_UNUSED(ssl_upstream), struct module_qstate* ATTR_UNUSED(q))
|
||||
int ATTR_UNUSED(ssl_upstream), char* ATTR_UNUSED(tls_auth_name),
|
||||
struct module_qstate* ATTR_UNUSED(q))
|
||||
{
|
||||
log_assert(0);
|
||||
return 0;
|
||||
|
||||
+69
-7
@@ -5,6 +5,7 @@
|
||||
#ifdef HAVE_TIME_H
|
||||
#include <time.h>
|
||||
#endif
|
||||
#include <inttypes.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include "sldns/sbuffer.h"
|
||||
@@ -588,18 +589,26 @@ dnsc_chroot_path(struct config_file *cfg, char *path)
|
||||
static int
|
||||
dnsc_parse_certs(struct dnsc_env *env, struct config_file *cfg)
|
||||
{
|
||||
struct config_strlist *head;
|
||||
struct config_strlist *head, *head2;
|
||||
size_t signed_cert_id;
|
||||
size_t rotated_cert_id;
|
||||
char *nm;
|
||||
|
||||
env->signed_certs_count = 0U;
|
||||
env->rotated_certs_count = 0U;
|
||||
for (head = cfg->dnscrypt_provider_cert; head; head = head->next) {
|
||||
env->signed_certs_count++;
|
||||
}
|
||||
for (head = cfg->dnscrypt_provider_cert_rotated; head; head = head->next) {
|
||||
env->rotated_certs_count++;
|
||||
}
|
||||
env->signed_certs = sodium_allocarray(env->signed_certs_count,
|
||||
sizeof *env->signed_certs);
|
||||
|
||||
env->rotated_certs = sodium_allocarray(env->rotated_certs_count,
|
||||
sizeof env->signed_certs);
|
||||
signed_cert_id = 0U;
|
||||
rotated_cert_id = 0U;
|
||||
for(head = cfg->dnscrypt_provider_cert; head; head = head->next, signed_cert_id++) {
|
||||
nm = dnsc_chroot_path(cfg, head->str);
|
||||
if(dnsc_read_from_file(
|
||||
@@ -608,6 +617,14 @@ dnsc_parse_certs(struct dnsc_env *env, struct config_file *cfg)
|
||||
sizeof(struct SignedCert)) != 0) {
|
||||
fatal_exit("dnsc_parse_certs: failed to load %s: %s", head->str, strerror(errno));
|
||||
}
|
||||
for(head2 = cfg->dnscrypt_provider_cert_rotated; head2; head2 = head2->next) {
|
||||
if(strcmp(head->str, head2->str) == 0) {
|
||||
*(env->rotated_certs + rotated_cert_id) = env->signed_certs + signed_cert_id;
|
||||
rotated_cert_id++;
|
||||
verbose(VERB_OPS, "Cert %s is rotated and will not be distributed via DNS", head->str);
|
||||
break;
|
||||
}
|
||||
}
|
||||
verbose(VERB_OPS, "Loaded cert %s", head->str);
|
||||
}
|
||||
return signed_cert_id;
|
||||
@@ -692,27 +709,54 @@ dnsc_load_local_data(struct dnsc_env* dnscenv, struct config_file *cfg)
|
||||
// 2.dnscrypt-cert.example.com 86400 IN TXT "DNSC......"
|
||||
for(i=0; i<dnscenv->signed_certs_count; i++) {
|
||||
const char *ttl_class_type = " 86400 IN TXT \"";
|
||||
int rotated_cert = 0;
|
||||
uint32_t serial;
|
||||
uint16_t rrlen;
|
||||
char* rr;
|
||||
struct SignedCert *cert = dnscenv->signed_certs + i;
|
||||
uint16_t rrlen = strlen(dnscenv->provider_name) +
|
||||
// Check if the certificate is being rotated and should not be published
|
||||
for(j=0; j<dnscenv->rotated_certs_count; j++){
|
||||
if(cert == dnscenv->rotated_certs[j]) {
|
||||
rotated_cert = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
memcpy(&serial, cert->serial, sizeof serial);
|
||||
serial = htonl(serial);
|
||||
if(rotated_cert) {
|
||||
verbose(VERB_OPS,
|
||||
"DNSCrypt: not adding cert with serial #%"
|
||||
PRIu32
|
||||
" to local-data as it is rotated",
|
||||
serial
|
||||
);
|
||||
continue;
|
||||
}
|
||||
rrlen = strlen(dnscenv->provider_name) +
|
||||
strlen(ttl_class_type) +
|
||||
4 * sizeof(struct SignedCert) + // worst case scenario
|
||||
1 + // trailing double quote
|
||||
1;
|
||||
char *rr = malloc(rrlen);
|
||||
rr = malloc(rrlen);
|
||||
if(!rr) {
|
||||
log_err("Could not allocate memory");
|
||||
return -2;
|
||||
}
|
||||
snprintf(rr, rrlen - 1, "%s 86400 IN TXT \"", dnscenv->provider_name);
|
||||
for(j=0; j<sizeof(struct SignedCert); j++) {
|
||||
int c = (int)*((const uint8_t *) cert + j);
|
||||
int c = (int)*((const uint8_t *) cert + j);
|
||||
if (isprint(c) && c != '"' && c != '\\') {
|
||||
snprintf(rr + strlen(rr), rrlen - 1 - strlen(rr), "%c", c);
|
||||
} else {
|
||||
snprintf(rr + strlen(rr), rrlen - 1 - strlen(rr), "\\%03d", c);
|
||||
}
|
||||
}
|
||||
verbose(VERB_OPS, "DNSCrypt: adding local data to config: %s", rr);
|
||||
verbose(VERB_OPS,
|
||||
"DNSCrypt: adding cert with serial #%"
|
||||
PRIu32
|
||||
" to local-data to config: %s",
|
||||
serial, rr
|
||||
);
|
||||
snprintf(rr + strlen(rr), rrlen - 1 - strlen(rr), "\"");
|
||||
cfg_strlist_insert(&cfg->local_data, strdup(rr));
|
||||
free(rr);
|
||||
@@ -826,6 +870,16 @@ dnsc_parse_keys(struct dnsc_env *env, struct config_file *cfg)
|
||||
return cert_id;
|
||||
}
|
||||
|
||||
static void
|
||||
sodium_misuse_handler(void)
|
||||
{
|
||||
fatal_exit(
|
||||
"dnscrypt: libsodium could not be initialized, this typically"
|
||||
" happens when no good source of entropy is found. If you run"
|
||||
" unbound in a chroot, make sure /dev/random is available. See"
|
||||
" https://www.unbound.net/documentation/unbound.conf.html");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* #########################################################
|
||||
@@ -889,6 +943,9 @@ struct dnsc_env *
|
||||
dnsc_create(void)
|
||||
{
|
||||
struct dnsc_env *env;
|
||||
#ifdef SODIUM_MISUSE_HANDLER
|
||||
sodium_set_misuse_handler(sodium_misuse_handler);
|
||||
#endif
|
||||
if (sodium_init() == -1) {
|
||||
fatal_exit("dnsc_create: could not initialize libsodium.");
|
||||
}
|
||||
@@ -923,6 +980,7 @@ dnsc_apply_cfg(struct dnsc_env *env, struct config_file *cfg)
|
||||
if(dnsc_load_local_data(env, cfg) <= 0) {
|
||||
fatal_exit("dnsc_apply_cfg: could not load local data");
|
||||
}
|
||||
lock_basic_lock(&env->shared_secrets_cache_lock);
|
||||
env->shared_secrets_cache = slabhash_create(
|
||||
cfg->dnscrypt_shared_secret_cache_slabs,
|
||||
HASH_DEFAULT_STARTARRAY,
|
||||
@@ -933,9 +991,11 @@ dnsc_apply_cfg(struct dnsc_env *env, struct config_file *cfg)
|
||||
dnsc_shared_secrets_deldatafunc,
|
||||
NULL
|
||||
);
|
||||
lock_basic_unlock(&env->shared_secrets_cache_lock);
|
||||
if(!env->shared_secrets_cache){
|
||||
fatal_exit("dnsc_apply_cfg: could not create shared secrets cache.");
|
||||
}
|
||||
lock_basic_lock(&env->nonces_cache_lock);
|
||||
env->nonces_cache = slabhash_create(
|
||||
cfg->dnscrypt_nonce_cache_slabs,
|
||||
HASH_DEFAULT_STARTARRAY,
|
||||
@@ -946,6 +1006,7 @@ dnsc_apply_cfg(struct dnsc_env *env, struct config_file *cfg)
|
||||
dnsc_nonces_deldatafunc,
|
||||
NULL
|
||||
);
|
||||
lock_basic_unlock(&env->nonces_cache_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -957,12 +1018,13 @@ dnsc_delete(struct dnsc_env *env)
|
||||
}
|
||||
verbose(VERB_OPS, "DNSCrypt: Freeing environment.");
|
||||
sodium_free(env->signed_certs);
|
||||
sodium_free(env->rotated_certs);
|
||||
sodium_free(env->certs);
|
||||
sodium_free(env->keypairs);
|
||||
slabhash_delete(env->shared_secrets_cache);
|
||||
slabhash_delete(env->nonces_cache);
|
||||
lock_basic_destroy(&env->shared_secrets_cache_lock);
|
||||
lock_basic_destroy(&env->nonces_cache_lock);
|
||||
slabhash_delete(env->shared_secrets_cache);
|
||||
slabhash_delete(env->nonces_cache);
|
||||
free(env);
|
||||
}
|
||||
|
||||
|
||||
@@ -54,8 +54,10 @@ typedef struct cert_ {
|
||||
|
||||
struct dnsc_env {
|
||||
struct SignedCert *signed_certs;
|
||||
struct SignedCert **rotated_certs;
|
||||
dnsccert *certs;
|
||||
size_t signed_certs_count;
|
||||
size_t rotated_certs_count;
|
||||
uint8_t provider_publickey[crypto_sign_ed25519_PUBLICKEYBYTES];
|
||||
uint8_t provider_secretkey[crypto_sign_ed25519_SECRETKEYBYTES];
|
||||
KeyPair *keypairs;
|
||||
|
||||
@@ -28,6 +28,14 @@ AC_DEFUN([dnsc_DNSCRYPT],
|
||||
[
|
||||
AC_SUBST([ENABLE_DNSCRYPT_XCHACHA20], [0])
|
||||
])
|
||||
AC_SEARCH_LIBS([sodium_set_misuse_handler], [sodium],
|
||||
[
|
||||
AC_DEFINE(
|
||||
[SODIUM_MISUSE_HANDLER], [1],
|
||||
[Define to 1 if libsodium supports sodium_set_misuse_handler])
|
||||
],
|
||||
[
|
||||
])
|
||||
$1
|
||||
else
|
||||
AC_SUBST([ENABLE_DNSCRYPT_XCHACHA20], [0])
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
// with this file. If not, see:
|
||||
//
|
||||
// <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
syntax = "proto2";
|
||||
|
||||
package dnstap;
|
||||
|
||||
|
||||
+484
@@ -1,5 +1,489 @@
|
||||
18 June 2018: Wouter
|
||||
- Fix that control-use-cert: no works for 127.0.0.1 to disable certs.
|
||||
|
||||
15 June 2018: Wouter
|
||||
- tag for 1.7.3rc1.
|
||||
|
||||
14 June 2018: Wouter
|
||||
- #4103: Fix that auth-zone does not insist on SOA record first in
|
||||
file for url downloads.
|
||||
- Fix that first control-interface determines if TLS is used. Warn
|
||||
when IP address interfaces are used without TLS.
|
||||
- Fix nettle compile.
|
||||
|
||||
12 June 2018: Ralph
|
||||
- Don't count CNAME response types received during qname minimisation as
|
||||
query restart.
|
||||
|
||||
12 June 2018: Wouter
|
||||
- #4102 for NSD, but for Unbound. Named unix pipes do not use
|
||||
certificate and key files, access can be restricted with file and
|
||||
directory permissions. The option control-use-cert is no longer
|
||||
used, and ignored if found in unbound.conf.
|
||||
- Rename tls-additional-ports to tls-additional-port, because every
|
||||
line adds one port.
|
||||
- Fix buffer size warning in unit test.
|
||||
- remade dependencies in the Makefile.
|
||||
|
||||
6 June 2018: Wouter
|
||||
- Patch to fix openwrt for mac os build darwin detection in configure.
|
||||
|
||||
5 June 2018: Wouter
|
||||
- Fix crash if ratelimit taken into use with unbound-control
|
||||
instead of with unbound.conf.
|
||||
|
||||
4 June 2018: Wouter
|
||||
- Fix deadlock caused by incoming notify for auth-zone.
|
||||
- tag for 1.7.2rc1, became 1.7.2 release on 11 June 2018,
|
||||
trunk is 1.7.3 in development from this point.
|
||||
- #4100: Fix stub reprime when it becomes useless.
|
||||
|
||||
1 June 2018: Wouter
|
||||
- Rename additional-tls-port to tls-additional-ports.
|
||||
The older name is accepted for backwards compatibility.
|
||||
|
||||
30 May 2018: Wouter
|
||||
- Patch from Syzdek: Add ability to ignore RD bit and treat all
|
||||
requests as if the RD bit is set.
|
||||
|
||||
29 May 2018: Wouter
|
||||
- in compat/arc4random call getentropy_urandom when getentropy fails
|
||||
with ENOSYS.
|
||||
- Fix that fallback for windows port.
|
||||
|
||||
28 May 2018: Wouter
|
||||
- Fix windows tcp and tls spin on events.
|
||||
- Add routine from getdns to add windows cert store to the SSL_CTX.
|
||||
- tls-win-cert option that adds the system certificate store for
|
||||
authenticating DNS-over-TLS connections. It can be used instead
|
||||
of the tls-cert-bundle option, or with it to add certificates.
|
||||
|
||||
25 May 2018: Wouter
|
||||
- For TCP and TLS connections that don't establish, perform address
|
||||
update in infra cache, so future selections can exclude them.
|
||||
- Fix that tcp sticky events are removed for closed fd on windows.
|
||||
- Fix close events for tcp only.
|
||||
|
||||
24 May 2018: Wouter
|
||||
- Fix that libunbound can do DNS-over-TLS, when configured.
|
||||
- Fix that windows unbound service can use DNS-over-TLS.
|
||||
- unbound-host initializes ssl (for potential DNS-over-TLS usage
|
||||
inside libunbound), when ssl upstream or a cert-bundle is configured.
|
||||
|
||||
23 May 2018: Wouter
|
||||
- Use accept4 to speed up incoming TCP (and TLS) connections,
|
||||
available on Linux, FreeBSD and OpenBSD.
|
||||
|
||||
17 May 2018: Ralph
|
||||
- Qname minimisation default changed to yes.
|
||||
|
||||
15 May 2018: Wouter
|
||||
- Fix low-rtt-pct to low-rtt-permil, as it is parts in one thousand.
|
||||
|
||||
11 May 2018: Wouter
|
||||
- Fix contrib/libunbound.pc for libssl libcrypto references,
|
||||
from https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=226914
|
||||
|
||||
7 May 2018: Wouter
|
||||
- Fix windows to not have sticky TLS events for TCP.
|
||||
- Fix read of DNS over TLS length and data in one read call.
|
||||
- Fix mesh state assertion failure due to callback removal.
|
||||
|
||||
3 May 2018: Wouter
|
||||
- Fix that configure --with-libhiredis also turns on cachedb.
|
||||
- Fix gcc 8 buffer warning in testcode.
|
||||
- Fix function type cast warning in libunbound context callback type.
|
||||
|
||||
2 May 2018: Wouter
|
||||
- Fix fail to reject dead peers in forward-zone, with ssl-upstream.
|
||||
|
||||
1 May 2018: Wouter
|
||||
- Fix that unbound-control reload frees the rrset keys and returns
|
||||
the memory pages to the system.
|
||||
|
||||
30 April 2018: Wouter
|
||||
- Fix spelling error in man page and note defaults as no instead of
|
||||
off.
|
||||
|
||||
26 April 2018: Wouter
|
||||
- Fix for crash in daemon_cleanup with dnstap during reload,
|
||||
from Saksham Manchanda.
|
||||
- Also that for dnscrypt.
|
||||
- tag for 1.7.1rc1 release. Became 1.7.1 release on 3 May, trunk
|
||||
is from here 1.7.2 in development.
|
||||
|
||||
25 April 2018: Ralph
|
||||
- Fix memory leak when caching wildcard records for aggressive NSEC use
|
||||
|
||||
24 April 2018: Wouter
|
||||
- Fix contrib/fastrpz.patch for this release.
|
||||
- Fix auth https for libev.
|
||||
|
||||
24 April 2018: Ralph
|
||||
- Added root-key-sentinel support
|
||||
|
||||
23 April 2018: Wouter
|
||||
- makedist uses bz2 for expat code, instead of tar.gz.
|
||||
- Fix #4092: libunbound: use-caps-for-id lacks colon in
|
||||
config_set_option.
|
||||
- auth zone http download stores exact copy of downloaded file,
|
||||
including comments in the file.
|
||||
- Fix sldns parse failure for CDS alternate delete syntax empty hex.
|
||||
- Attempt for auth zone fix; add of callback in mesh gets from
|
||||
callback does not skip callback of result.
|
||||
- Fix cname classification with qname minimisation enabled.
|
||||
- list_auth_zones unbound-control command.
|
||||
|
||||
20 April 2018: Wouter
|
||||
- man page documentation for dns-over-tls forward-addr '#' notation.
|
||||
- removed free from failed parse case.
|
||||
- Fix #4091: Fix that reload of auth-zone does not merge the zonefile
|
||||
with the previous contents.
|
||||
- Delete auth zone when removed from config.
|
||||
|
||||
19 April 2018: Wouter
|
||||
- Can set tls authentication with forward-addr: IP#tls.auth.name
|
||||
And put the public cert bundle in tls-cert-bundle: "ca-bundle.pem".
|
||||
such as forward-addr: 9.9.9.9@853#dns.quad9.net or
|
||||
1.1.1.1@853#cloudflare-dns.com
|
||||
- Fix #658: unbound using TLS in a forwarding configuration does not
|
||||
verify the server's certificate (RFC 8310 support).
|
||||
- For addr with #authname and no @port notation, the default is 853.
|
||||
|
||||
18 April 2018: Wouter
|
||||
- Fix auth-zone retry timer to be on schedule with retry timeout,
|
||||
with backoff. Also time a refresh at the zone expiry.
|
||||
|
||||
17 April 2018: Wouter
|
||||
- auth zone notify work.
|
||||
- allow-notify: config statement for auth-zones.
|
||||
- unit test for allow-notify
|
||||
|
||||
16 April 2018: Wouter
|
||||
- Fix auth zone target lookup iterator.
|
||||
- auth zone notify with prefix
|
||||
- auth zone notify work.
|
||||
|
||||
13 April 2018: Wouter
|
||||
- Fix for max include depth for authzones.
|
||||
- Fix memory free on fail for $INCLUDE in authzone.
|
||||
- Fix that an internal error to look up the wrong rr type for
|
||||
auth zone gets stopped, before trying to send there.
|
||||
- auth zone notify work.
|
||||
|
||||
10 April 2018: Ralph
|
||||
- num.query.aggressive.NOERROR and num.query.aggressive.NXDOMAIN
|
||||
statistics counters.
|
||||
|
||||
10 April 2018: Wouter
|
||||
- documentation for low-rtt and low-rtt-pct.
|
||||
- auth zone notify work.
|
||||
|
||||
9 April 2018: Wouter
|
||||
- Fix that flush_zone sets prefetch ttl expired, so that with
|
||||
serve-expired enabled it'll start prefetching those entries.
|
||||
- num.query.authzone.up and num.query.authzone.down statistics counters.
|
||||
- Fix downstream auth zone, only fallback when auth zone fails to
|
||||
answer and fallback is enabled.
|
||||
- Accept both option names with and without colon for get_option
|
||||
and set_option.
|
||||
- low-rtt and low-rtt-pct in unbound.conf enable the server selection
|
||||
of fast servers for some percentage of the time.
|
||||
|
||||
5 April 2018: Wouter
|
||||
- Combine write of tcp length and tcp query for dns over tls.
|
||||
- nitpick fixes in example.conf.
|
||||
- Fix above stub queries for type NS and useless delegation point.
|
||||
- Fix unbound-control over pipe with openssl 1.1.1, the TLSv1.3
|
||||
tls_choose_sigalg routine does not allow the ciphers for the pipe,
|
||||
so use TLSv1.2.
|
||||
- ED448 support.
|
||||
|
||||
3 April 2018: Wouter
|
||||
- Fix #4043: make test fails due to v6 presentation issue in macOS.
|
||||
- Fix unable to resolve after new WLAN connection, due to auth-zone
|
||||
failing with a forwarder set. Now, auth-zone is only used for
|
||||
answers (not referrals) when a forwarder is set.
|
||||
|
||||
29 March 2018: Ralph
|
||||
- Check "result" in dup_all(), by Florian Obser.
|
||||
|
||||
23 March 2018: Ralph
|
||||
- Fix unbound-control get_option aggressive-nsec
|
||||
|
||||
21 March 2018: Ralph
|
||||
- Do not use cached NSEC records to generate negative answers for
|
||||
domains under DNSSEC Negative Trust Anchors.
|
||||
|
||||
19 March 2018: Wouter
|
||||
- iana port update.
|
||||
|
||||
16 March 2018: Wouter
|
||||
- corrected a minor typo in the changelog.
|
||||
- move htobe64/be64toh portability code to cachedb.c.
|
||||
|
||||
15 March 2018: Wouter
|
||||
- Add --with-libhiredis, unbound support for a new cachedb backend
|
||||
that uses a Redis server as the storage. This implementation
|
||||
depends on the hiredis client library (https://redislabs.com/lp/hiredis/).
|
||||
And unbound should be built with both --enable-cachedb and
|
||||
--with-libhiredis[=PATH] (where $PATH/include/hiredis/hiredis.h
|
||||
should exist). Patch from Jinmei Tatuya (Infoblox).
|
||||
- Fix #3817: core dump happens in libunbound delete, when queued
|
||||
servfail hits deleted message queue.
|
||||
- Create additional tls service interfaces by opening them on other
|
||||
portnumbers and listing the portnumbers as additional-tls-port: nr.
|
||||
|
||||
13 March 2018: Wouter
|
||||
- Fix typo in documentation.
|
||||
- Fix #3736: Fix 0 TTL domains stuck on SERVFAIL unless manually
|
||||
flushed with serve-expired on.
|
||||
|
||||
12 March 2018: Wouter
|
||||
- Added documentation for aggressive-nsec: yes.
|
||||
- tag 1.7.0rc3. That became the 1.7.0 release on 15 Mar, trunk
|
||||
now has 1.7.1 in development.
|
||||
- Fix #3727: Protocol name is TLS, options have been renamed but
|
||||
documentation is not consistent.
|
||||
- Check IXFR start serial.
|
||||
|
||||
9 March 2018: Wouter
|
||||
- Fix #3598: Fix swig build issue on rhel6 based system.
|
||||
configure --disable-swig-version-check stops the swig version check.
|
||||
|
||||
8 March 2018: Wouter
|
||||
- tag 1.7.0rc2.
|
||||
|
||||
7 March 2018: Wouter
|
||||
- Fixed contrib/fastrpz.patch, even though this already applied
|
||||
cleanly for me, now also for others.
|
||||
- patch to log creates keytag queries, from A. Schulze.
|
||||
- patch suggested by Debian lintian: allow to -> allow one to, from
|
||||
A. Schulze.
|
||||
- Attempt to remove warning about trailing whitespace.
|
||||
|
||||
6 March 2018: Wouter
|
||||
- Reverted fix for #3512, this may not be the best way forward;
|
||||
although it could be changed at a later time, to stay similar to
|
||||
other implementations.
|
||||
- svn trunk contains 1.7.0, this is the number for the next release.
|
||||
- Fix for windows compile.
|
||||
- tag 1.7.0rc1.
|
||||
|
||||
5 March 2018: Wouter
|
||||
- Fix to check define of DSA for when openssl is without deprecated.
|
||||
- iana port update.
|
||||
- Fix #3582: Squelch address already in use log when reuseaddr option
|
||||
causes same port to be used twice for tcp connections.
|
||||
|
||||
27 February 2018: Wouter
|
||||
- Fixup contrib/fastrpz.patch so that it applies.
|
||||
- Fix compile without threads, and remove unused variable.
|
||||
- Fix compile with staticexe and python module.
|
||||
- Fix nettle compile.
|
||||
|
||||
22 February 2018: Ralph
|
||||
- Save wildcard RRset from answer with original owner for use in
|
||||
aggressive NSEC.
|
||||
|
||||
21 February 2018: Wouter
|
||||
- Fix #3512: unbound incorrectly reports SERVFAIL for CAA query
|
||||
when there is a CNAME loop.
|
||||
- Fix validation for CNAME loops. When it detects a cname loop,
|
||||
by finding the cname, cname in the existing list, it returns
|
||||
the partial result with the validation result up to then.
|
||||
- more robust cachedump rrset routine.
|
||||
|
||||
19 February 2018: Wouter
|
||||
- Fix #3505: Documentation for default local zones references
|
||||
wrong RFC.
|
||||
- Fix #3494: local-zone noview can be used to break out of the view
|
||||
to the global local zone contents, for queries for that zone.
|
||||
- Fix for more maintainable code in localzone.
|
||||
|
||||
16 February 2018: Wouter
|
||||
- Fixes for clang static analyzer, the missing ; in
|
||||
edns-subnet/addrtree.c after the assert made clang analyzer
|
||||
produce a failure to analyze it.
|
||||
|
||||
13 February 2018: Ralph
|
||||
- Aggressive NSEC tests
|
||||
|
||||
13 February 2018: Wouter
|
||||
- tls-cert-bundle option in unbound.conf enables TLS authentication.
|
||||
- iana port update.
|
||||
|
||||
12 February 2018: Wouter
|
||||
- Unit test for auth zone https url download.
|
||||
|
||||
12 February 2018: Ralph
|
||||
- Added tests with wildcard expanded NSEC records (CVE-2017-15105 test)
|
||||
- Processed aggressive NSEC code review remarks Wouter
|
||||
|
||||
8 February 2018: Ralph
|
||||
- Aggressive use of NSEC implementation. Use cached NSEC records to
|
||||
generate NXDOMAIN, NODATA and positive wildcard answers.
|
||||
|
||||
8 February 2018: Wouter
|
||||
- iana port update.
|
||||
- auth zone url config.
|
||||
|
||||
5 February 2018: Wouter
|
||||
- Fix #3451: dnstap not building when you have a separate build dir.
|
||||
And removed protoc warning, set dnstap.proto syntax to proto2.
|
||||
- auth-zone provides a way to configure RFC7706 from unbound.conf,
|
||||
eg. with auth-zone: name: "." for-downstream: no for-upstream: yes
|
||||
fallback-enabled: yes and masters or a zonefile with data.
|
||||
|
||||
2 February 2018: Wouter
|
||||
- Fix unfreed locks in log and arc4random at exit of unbound.
|
||||
- unit test with valgrind
|
||||
- Fix lock race condition in dns cache dname synthesis.
|
||||
- lock subnet new item before insertion to please checklocks,
|
||||
no modification of critical regions outside of lock region.
|
||||
|
||||
1 February 2018: Wouter
|
||||
- fix unaligned structure making a false positive in checklock
|
||||
unitialised memory.
|
||||
|
||||
29 January 2018: Ralph
|
||||
- Use NSEC with longest ce to prove wildcard absence.
|
||||
- Only use *.ce to prove wildcard absence, no longer names.
|
||||
|
||||
25 January 2018: Wouter
|
||||
- ltrace.conf file for libunbound in contrib.
|
||||
|
||||
23 January 2018: Wouter
|
||||
- Fix that unbound-checkconf -f flag works with auto-trust-anchor-file
|
||||
for startup scripts to get the full pathname(s) of anchor file(s).
|
||||
- Print fatal errors about remote control setup before log init,
|
||||
so that it is printed to console.
|
||||
|
||||
22 January 2018: Wouter
|
||||
- Accept tls-upstream in unbound.conf, the ssl-upstream keyword is
|
||||
also recognized and means the same. Also for tls-port,
|
||||
tls-service-key, tls-service-pem, stub-tls-upstream and
|
||||
forward-tls-upstream.
|
||||
- Fix #3397: Fix that cachedb could return a partial CNAME chain.
|
||||
- Fix #3397: Fix that when the cache contains an unsigned DNAME in
|
||||
the middle of a cname chain, a result without the DNAME could
|
||||
be returned.
|
||||
|
||||
19 January 2018: Wouter
|
||||
- tag 1.6.8 for release with CVE fix.
|
||||
- trunk has 1.6.9 with fix and previous commits.
|
||||
- patch for CVE-2017-15105: vulnerability in the processing of
|
||||
wildcard synthesized NSEC records.
|
||||
- iana port update.
|
||||
- make depend: code dependencies updated in Makefile.
|
||||
|
||||
4 January 2018: Ralph
|
||||
- Copy query and correctly set flags on REFUSED answers when cache
|
||||
snooping is not allowed.
|
||||
|
||||
3 January 2018: Ralph
|
||||
- Fix queries being leaked above stub when refetching glue.
|
||||
|
||||
2 January 2017: Wouter
|
||||
- Fix that DS queries with referral replies are answered straight
|
||||
away, without a repeat query picking the DS from cache.
|
||||
The correct reply should have been an answer, the reply is fixed
|
||||
by the scrubber to have the answer in the answer section.
|
||||
- Remove clang optimizer disable,
|
||||
Fix that expiration date checks don't fail with clang -O2.
|
||||
|
||||
15 December 2017: Wouter
|
||||
- Fix timestamp failure because of clang optimizer failure, by
|
||||
disabling -O2 when the compiler --version is clang.
|
||||
- iana port update.
|
||||
- Also disable -flto for clang, to make incep-expi signature check
|
||||
work.
|
||||
|
||||
12 December 2017: Ralph
|
||||
- Fix qname-minimisation documentation (A QTYPE, not NS)
|
||||
|
||||
12 December 2017: Wouter
|
||||
- authzone work, transfer connect.
|
||||
|
||||
7 December 2017: Ralph
|
||||
- Check whether --with-libunbound-only is set when using --with-nettle
|
||||
or --with-nss.
|
||||
|
||||
4 December 2017: Wouter
|
||||
- Fix link failure on OmniOS.
|
||||
|
||||
1 December 2017: Wouter
|
||||
- auth zone work.
|
||||
|
||||
30 November 2017: Wouter
|
||||
- Fix #3299 - forward CNAME daisy chain is not working
|
||||
|
||||
14 November 2017: Wouter
|
||||
- Fix #2882: Unbound behaviour changes (wrong) when domain-insecure is
|
||||
set for stub zone. It no longer searches for DNSSEC information.
|
||||
- auth xfer work on probe timer and lookup.
|
||||
|
||||
13 November 2017: Wouter
|
||||
- Fix #2801: Install libunbound.pc.
|
||||
- Fix qname minimisation to send AAAA queries at zonecut like type A.
|
||||
- reverted AAAA change.
|
||||
|
||||
7 November 2017: Wouter
|
||||
- Fix #2492: Documentation libunbound.
|
||||
|
||||
3 November 2017: Wouter
|
||||
- Fix #2362: TLS1.3/openssl-1.1.1 not working.
|
||||
- Fix #2034 - Autoconf and -flto.
|
||||
- Fix #2141 - for libsodium detect lack of entropy in chroot, print
|
||||
a message and exit.
|
||||
|
||||
2 November 2017: Wouter
|
||||
- Fix #1913: ub_ctx_config is under circumstances thread-safe.
|
||||
- make ip-transparent option work on OpenBSD.
|
||||
|
||||
31 October 2017: Wouter
|
||||
- Document that errno is left informative on libunbound config read
|
||||
fail.
|
||||
- lexer output.
|
||||
- iana port update.
|
||||
|
||||
25 October 2017: Ralph
|
||||
- Fixed libunbound manual typo.
|
||||
- Fix #1949: [dnscrypt] make provider name mismatch more obvious.
|
||||
- Fix #2031: Double included headers
|
||||
|
||||
24 October 2017: Ralph
|
||||
- Update B root ipv4 address.
|
||||
|
||||
19 October 2017: Wouter
|
||||
- authzone work, probe timer setup.
|
||||
|
||||
18 October 2017: Wouter
|
||||
- lint for recent authzone commit.
|
||||
|
||||
17 October 2017: Wouter
|
||||
- Fix #1749: With harden-referral-path: performance drops, due to
|
||||
circular dependency in NS and DS lookups.
|
||||
- [dnscrypt] prevent dnscrypt-secret-key, dnscrypt-provider-cert
|
||||
duplicates
|
||||
- [dnscrypt] introduce dnscrypt-provider-cert-rotated option,
|
||||
from Manu Bretelle.
|
||||
This option allows handling multiple cert/key pairs while only
|
||||
distributing some of them.
|
||||
In order to reliably match a client magic with a given key without
|
||||
strong assumption as to how those were generated, we need both key and
|
||||
cert. Likewise, in order to know which ES version should be used.
|
||||
On the other hand, when rotating a cert, it can be desirable to only
|
||||
serve the new cert but still be able to handle clients that are still
|
||||
using the old certs's public key.
|
||||
The `dnscrypt-provider-cert-rotated` allow to instruct unbound to not
|
||||
publish the cert as part of the DNS's provider_name's TXT answer.
|
||||
- Better documentation for cache-max-negative-ttl.
|
||||
- Work on local root zone code.
|
||||
|
||||
10 October 2017: Wouter
|
||||
- tag 1.6.7
|
||||
- trunk has version 1.6.8.
|
||||
|
||||
6 October 2017: Wouter
|
||||
- Fix spelling in unbound-control man page.
|
||||
|
||||
+80
-20
@@ -199,7 +199,7 @@ server:
|
||||
# upstream connections use TCP only (and no UDP), "yes" or "no"
|
||||
# useful for tunneling scenarios, default no.
|
||||
# tcp-upstream: no
|
||||
|
||||
|
||||
# upstream connections also use UDP (even if do-udp is no).
|
||||
# useful if if you want UDP upstream, but don't provide UDP downstream.
|
||||
# udp-upstream-without-downstream: no
|
||||
@@ -223,7 +223,8 @@ server:
|
||||
# to this server. Specify classless netblocks with /size and action.
|
||||
# By default everything is refused, except for localhost.
|
||||
# Choose deny (drop message), refuse (polite error reply),
|
||||
# allow (recursive ok), allow_snoop (recursive and nonrecursive ok)
|
||||
# allow (recursive ok), allow_setrd (recursive ok, rd bit is forced on),
|
||||
# allow_snoop (recursive and nonrecursive ok)
|
||||
# deny_non_local (drop queries unless can be answered from local-data)
|
||||
# refuse_non_local (like deny_non_local but polite error reply).
|
||||
# access-control: 0.0.0.0/0 refuse
|
||||
@@ -320,7 +321,7 @@ server:
|
||||
|
||||
# enable to not answer version.server and version.bind queries.
|
||||
# hide-version: no
|
||||
|
||||
|
||||
# enable to not answer trustanchor.unbound queries.
|
||||
# hide-trustanchor: no
|
||||
|
||||
@@ -371,8 +372,8 @@ server:
|
||||
|
||||
# Sent minimum amount of information to upstream servers to enhance
|
||||
# privacy. Only sent minimum required labels of the QNAME and set QTYPE
|
||||
# to NS when possible.
|
||||
# qname-minimisation: no
|
||||
# to A when possible.
|
||||
# qname-minimisation: yes
|
||||
|
||||
# QNAME minimisation in strict mode. Do not fall-back to sending full
|
||||
# QNAME to potentially broken nameservers. A lot of domains will not be
|
||||
@@ -380,6 +381,10 @@ server:
|
||||
# This option only has effect when qname-minimisation is enabled.
|
||||
# qname-minimisation-strict: no
|
||||
|
||||
# Aggressive NSEC uses the DNSSEC NSEC chain to synthesize NXDOMAIN
|
||||
# and other denials, using information from previous NXDOMAINs answers.
|
||||
# aggressive-nsec: no
|
||||
|
||||
# Use 0x20-encoded random bits in the query to foil spoof attempts.
|
||||
# This feature is an experimental implementation of draft dns-0x20.
|
||||
# use-caps-for-id: no
|
||||
@@ -454,6 +459,9 @@ server:
|
||||
|
||||
# trust anchor signaling sends a RFC8145 key tag query after priming.
|
||||
# trust-anchor-signaling: yes
|
||||
|
||||
# Root key trust anchor sentinel (draft-ietf-dnsop-kskroll-sentinel)
|
||||
# root-key-sentinel: yes
|
||||
|
||||
# File with DLV trusted keys. Same format as trust-anchor-file.
|
||||
# There can be only one DLV configured, it is trusted from root down.
|
||||
@@ -626,7 +634,8 @@ server:
|
||||
# o inform acts like transparent, but logs client IP address
|
||||
# o inform_deny drops queries and logs client IP address
|
||||
# o always_transparent, always_refuse, always_nxdomain, resolve in
|
||||
# that way but ignore local data for that name.
|
||||
# that way but ignore local data for that name
|
||||
# o noview breaks out of that view towards global local-zones.
|
||||
#
|
||||
# defaults are localhost address, reverse for 127.0.0.1 and ::1
|
||||
# and nxdomain for AS112 zones. If you configure one of these zones
|
||||
@@ -659,16 +668,25 @@ server:
|
||||
# add a netblock specific override to a localzone, with zone type
|
||||
# local-zone-override: "example.com" 192.0.2.0/24 refuse
|
||||
|
||||
# service clients over SSL (on the TCP sockets), with plain DNS inside
|
||||
# the SSL stream. Give the certificate to use and private key.
|
||||
# service clients over TLS (on the TCP sockets), with plain DNS inside
|
||||
# the TLS stream. Give the certificate to use and private key.
|
||||
# default is "" (disabled). requires restart to take effect.
|
||||
# ssl-service-key: "path/to/privatekeyfile.key"
|
||||
# ssl-service-pem: "path/to/publiccertfile.pem"
|
||||
# ssl-port: 853
|
||||
# tls-service-key: "path/to/privatekeyfile.key"
|
||||
# tls-service-pem: "path/to/publiccertfile.pem"
|
||||
# tls-port: 853
|
||||
|
||||
# request upstream over SSL (with plain DNS inside the SSL stream).
|
||||
# request upstream over TLS (with plain DNS inside the TLS stream).
|
||||
# Default is no. Can be turned on and off with unbound-control.
|
||||
# ssl-upstream: no
|
||||
# tls-upstream: no
|
||||
|
||||
# Certificates used to authenticate connections made upstream.
|
||||
# tls-cert-bundle: ""
|
||||
|
||||
# Add system certs to the cert bundle, from the Windows Cert Store
|
||||
# tls-win-cert: no
|
||||
|
||||
# Also serve tls on these port numbers (eg. 443, ...), by listing
|
||||
# tls-additional-port: portno for each of the port numbers.
|
||||
|
||||
# DNS64 prefix. Must be specified when DNS64 is use.
|
||||
# Enable dns64 in module-config. Used to synthesize IPv6 from IPv4.
|
||||
@@ -707,6 +725,12 @@ server:
|
||||
# 0 blocks when ip is ratelimited, otherwise let 1/xth traffic through
|
||||
# ip-ratelimit-factor: 10
|
||||
|
||||
# what is considered a low rtt (ping time for upstream server), in msec
|
||||
# low-rtt: 45
|
||||
# select low rtt this many times out of 1000. 0 means the fast server
|
||||
# select is disabled. prefetches are not sped up.
|
||||
# low-rtt-permil: 0
|
||||
|
||||
# Specific options for ipsecmod. unbound needs to be configured with
|
||||
# --enable-ipsecmod for these to take effect.
|
||||
#
|
||||
@@ -750,18 +774,20 @@ remote-control:
|
||||
# set up the keys and certificates with unbound-control-setup.
|
||||
# control-enable: no
|
||||
|
||||
# Set to no and use an absolute path as control-interface to use
|
||||
# a unix local named pipe for unbound-control.
|
||||
# control-use-cert: yes
|
||||
|
||||
# what interfaces are listened to for remote control.
|
||||
# give 0.0.0.0 and ::0 to listen to all interfaces.
|
||||
# set to an absolute path to use a unix local name pipe, certificates
|
||||
# are not used for that, so key and cert files need not be present.
|
||||
# control-interface: 127.0.0.1
|
||||
# control-interface: ::1
|
||||
|
||||
# port number for remote control operations.
|
||||
# control-port: 8953
|
||||
|
||||
# for localhost, you can disable use of TLS by setting this to "no"
|
||||
# For local sockets this option is ignored, and TLS is not used.
|
||||
# control-use-cert: "yes"
|
||||
|
||||
# unbound server key file.
|
||||
# server-key-file: "@UNBOUND_RUN_DIR@/unbound_server.key"
|
||||
|
||||
@@ -787,7 +813,7 @@ remote-control:
|
||||
# stub-addr: 192.0.2.68
|
||||
# stub-prime: no
|
||||
# stub-first: no
|
||||
# stub-ssl-upstream: no
|
||||
# stub-tls-upstream: no
|
||||
# stub-zone:
|
||||
# name: "example.org"
|
||||
# stub-host: ns.example.com.
|
||||
@@ -803,11 +829,37 @@ remote-control:
|
||||
# forward-addr: 192.0.2.68
|
||||
# forward-addr: 192.0.2.73@5355 # forward to port 5355.
|
||||
# forward-first: no
|
||||
# forward-ssl-upstream: no
|
||||
# forward-tls-upstream: no
|
||||
# forward-zone:
|
||||
# name: "example.org"
|
||||
# forward-host: fwd.example.com
|
||||
|
||||
# Authority zones
|
||||
# The data for these zones is kept locally, from a file or downloaded.
|
||||
# The data can be served to downstream clients, or used instead of the
|
||||
# upstream (which saves a lookup to the upstream). The first example
|
||||
# has a copy of the root for local usage. The second serves example.org
|
||||
# authoritatively. zonefile: reads from file (and writes to it if you also
|
||||
# download it), master: fetches with AXFR and IXFR, or url to zonefile.
|
||||
# With allow-notify: you can give additional (apart from masters) sources of
|
||||
# notifies.
|
||||
# auth-zone:
|
||||
# name: "."
|
||||
# for-downstream: no
|
||||
# for-upstream: yes
|
||||
# fallback-enabled: yes
|
||||
# master: b.root-servers.net
|
||||
# master: c.root-servers.net
|
||||
# master: e.root-servers.net
|
||||
# master: f.root-servers.net
|
||||
# master: g.root-servers.net
|
||||
# master: k.root-servers.net
|
||||
# auth-zone:
|
||||
# name: "example.org"
|
||||
# for-downstream: yes
|
||||
# for-upstream: yes
|
||||
# zonefile: "example.org.zone"
|
||||
|
||||
# Views
|
||||
# Create named views. Name must be unique. Map views to requests using
|
||||
# the access-control-view option. Views can contain zero or more local-zone
|
||||
@@ -819,7 +871,7 @@ remote-control:
|
||||
# name: "viewname"
|
||||
# local-zone: "example.com" redirect
|
||||
# local-data: "example.com A 192.0.2.3"
|
||||
# local-data-ptr: "192.0.2.3 www.example.com"
|
||||
# local-data-ptr: "192.0.2.3 www.example.com"
|
||||
# view-first: no
|
||||
# view:
|
||||
# name: "anotherview"
|
||||
@@ -854,3 +906,11 @@ remote-control:
|
||||
# backend: "testframe"
|
||||
# # secret seed string to calculate hashed keys
|
||||
# secret-seed: "default"
|
||||
#
|
||||
# # For "redis" backend:
|
||||
# # redis server's IP address or host name
|
||||
# redis-server-host: 127.0.0.1
|
||||
# # redis server's TCP port
|
||||
# redis-server-port: 6379
|
||||
# # timeout (in ms) for communication with the redis server
|
||||
# redis-timeout: 100
|
||||
|
||||
+11
-3
@@ -150,7 +150,8 @@
|
||||
is an implementation of a DNS resolver, that does caching and
|
||||
DNSSEC validation. This is the library API, for using the \-lunbound library.
|
||||
The server daemon is described in \fIunbound\fR(8).
|
||||
The library can be used to convert hostnames to ip addresses, and back,
|
||||
The library works independent from a running unbound server, and
|
||||
can be used to convert hostnames to ip addresses, and back,
|
||||
and obtain other information from the DNS. The library performs public\-key
|
||||
validation of results with DNSSEC.
|
||||
.P
|
||||
@@ -162,7 +163,7 @@ and deleting it with
|
||||
It can be created and deleted at any time. Creating it anew removes any
|
||||
previous configuration (such as trusted keys) and clears any cached results.
|
||||
.P
|
||||
The functions are thread\-safe, and a context an be used in a threaded (as
|
||||
The functions are thread\-safe, and a context can be used in a threaded (as
|
||||
well as in a non\-threaded) environment. Also resolution (and validation)
|
||||
can be performed blocking and non\-blocking (also called asynchronous).
|
||||
The async method returns from the call immediately, so that processing
|
||||
@@ -203,7 +204,10 @@ without trailing ':'. The returned value must be free(2)d by the caller.
|
||||
A power\-user interface that lets you specify an unbound config file, see
|
||||
\fIunbound.conf\fR(5), which is read for configuration. Not all options are
|
||||
relevant. For some specific options, such as adding trust anchors, special
|
||||
routines exist.
|
||||
routines exist. This function is thread\-safe only if a single instance of
|
||||
ub_ctx* exists in the application. If several instances exist the
|
||||
application has to ensure that ub_ctx_config is not called in parallel by
|
||||
the different instances.
|
||||
.TP
|
||||
.B ub_ctx_set_fwd
|
||||
Set machine to forward DNS queries to, the caching resolver to use.
|
||||
@@ -407,6 +411,10 @@ returns NULL on an error (a malloc failure).
|
||||
returns true if some information may be available, false otherwise.
|
||||
.B ub_fd
|
||||
returns a file descriptor or \-1 on error.
|
||||
.B ub_ctx_config
|
||||
and
|
||||
.B ub_ctx_resolvconf
|
||||
attempt to leave errno informative on a function return with file read failure.
|
||||
.SH "SEE ALSO"
|
||||
\fIunbound.conf\fR(5),
|
||||
\fIunbound\fR(8).
|
||||
|
||||
@@ -144,6 +144,9 @@ Remove the name, type information from the cache.
|
||||
Remove all information at or below the name from the cache.
|
||||
The rrsets and key entries are removed so that new lookups will be performed.
|
||||
This needs to walk and inspect the entire cache, and is a slow operation.
|
||||
The entries are set to expired in the implementation of this command (so,
|
||||
with serve\-expired enabled, it'll serve that information but schedule a
|
||||
prefetch for new information).
|
||||
.TP
|
||||
.B flush_bogus
|
||||
Remove all bogus data from the cache.
|
||||
@@ -286,6 +289,10 @@ estimated qps and qps limit from config. With +a it prints all ips, not
|
||||
just the ratelimited ips, with their estimated qps. The ratelimited
|
||||
ips are dropped before checking the cache.
|
||||
.TP
|
||||
.B list_auth_zones
|
||||
List the auth zones that are configured. Printed one per line with a
|
||||
status, indicating if the zone is expired and current serial number.
|
||||
.TP
|
||||
.B view_list_local_zones \fIview\fR
|
||||
\fIlist_local_zones\fR for given view.
|
||||
.TP
|
||||
@@ -598,6 +605,26 @@ dnscrypt queries replay. The client nonce must be unique for each client public
|
||||
key/server secret key pair. This cache should be able to host QPS * `replay
|
||||
window` interval keys to prevent replay of a query during `replay window`
|
||||
seconds.
|
||||
.TP
|
||||
.I num.query.authzone.up
|
||||
The number of queries answered from auth\-zone data, upstream queries.
|
||||
These queries would otherwise have been sent (with fallback enabled) to
|
||||
the internet, but are now answered from the auth zone.
|
||||
.TP
|
||||
.I num.query.authzone.down
|
||||
The number of queries for downstream answered from auth\-zone data.
|
||||
These queries are from downstream clients, and have had an answer from
|
||||
the data in the auth zone.
|
||||
.TP
|
||||
.I num.query.aggressive.NOERROR
|
||||
The number of queries answered using cached NSEC records with NODATA RCODE.
|
||||
These queries would otherwise have been sent to the internet, but are now
|
||||
answered using cached data.
|
||||
.TP
|
||||
.I num.query.aggressive.NXDOMAIN
|
||||
The number of queries answered using cached NSEC records with NXDOMAIN RCODE.
|
||||
These queries would otherwise have been sent to the internet, but are now
|
||||
answered using cached data.
|
||||
.SH "FILES"
|
||||
.TP
|
||||
.I @ub_conf_file@
|
||||
|
||||
+270
-35
@@ -288,12 +288,13 @@ silently (unless verbosity 3) without the option.
|
||||
.B ip\-transparent: \fI<yes or no>
|
||||
If yes, then use IP_TRANSPARENT socket option on sockets where unbound
|
||||
is listening for incoming traffic. Default no. Allows you to bind to
|
||||
non\-local interfaces. For example for non\-existant IP addresses that
|
||||
non\-local interfaces. For example for non\-existent IP addresses that
|
||||
are going to exist later on, with host failover configuration. This is
|
||||
a lot like interface\-automatic, but that one services all interfaces
|
||||
and with this option you can select which (future) interfaces unbound
|
||||
provides service on. This option needs unbound to be started with root
|
||||
permissions on some systems. The option uses IP_BINDANY on FreeBSD systems.
|
||||
permissions on some systems. The option uses IP_BINDANY on FreeBSD systems
|
||||
and SO_BINDANY on OpenBSD systems.
|
||||
.TP
|
||||
.B ip\-freebind: \fI<yes or no>
|
||||
If yes, then use IP_FREEBIND socket option on sockets where unbound
|
||||
@@ -330,6 +331,7 @@ the data in the cache does not match up with the actual data any more.
|
||||
.B cache\-max\-negative\-ttl: \fI<seconds>
|
||||
Time to live maximum for negative responses, these have a SOA in the
|
||||
authority section that is limited in time. Default is 3600.
|
||||
This applies to nxdomain and nodata answers.
|
||||
.TP
|
||||
.B infra\-host\-ttl: \fI<seconds>
|
||||
Time to live for entries in the host cache. The host cache contains
|
||||
@@ -396,29 +398,64 @@ Enable udp upstream even if do-udp is no. Default is no, and this does not
|
||||
change anything. Useful for TLS service providers, that want no udp downstream
|
||||
but use udp to fetch data upstream.
|
||||
.TP
|
||||
.B ssl\-upstream: \fI<yes or no>
|
||||
Enabled or disable whether the upstream queries use SSL only for transport.
|
||||
Default is no. Useful in tunneling scenarios. The SSL contains plain DNS in
|
||||
.B tls\-upstream: \fI<yes or no>
|
||||
Enabled or disable whether the upstream queries use TLS only for transport.
|
||||
Default is no. Useful in tunneling scenarios. The TLS contains plain DNS in
|
||||
TCP wireformat. The other server must support this (see
|
||||
\fBssl\-service\-key\fR).
|
||||
\fBtls\-service\-key\fR).
|
||||
If you enable this, also configure a tls\-cert\-bundle or use tls\-win\cert to
|
||||
load CA certs, otherwise the connections cannot be authenticated.
|
||||
.TP
|
||||
.B ssl\-service-key: \fI<file>
|
||||
If enabled, the server provider SSL service on its TCP sockets. The clients
|
||||
have to use ssl\-upstream: yes. The file is the private key for the TLS
|
||||
session. The public certificate is in the ssl\-service\-pem file. Default
|
||||
.B ssl\-upstream: \fI<yes or no>
|
||||
Alternate syntax for \fBtls\-upstream\fR. If both are present in the config
|
||||
file the last is used.
|
||||
.TP
|
||||
.B tls\-service\-key: \fI<file>
|
||||
If enabled, the server provider TLS service on its TCP sockets. The clients
|
||||
have to use tls\-upstream: yes. The file is the private key for the TLS
|
||||
session. The public certificate is in the tls\-service\-pem file. Default
|
||||
is "", turned off. Requires a restart (a reload is not enough) if changed,
|
||||
because the private key is read while root permissions are held and before
|
||||
chroot (if any). Normal DNS TCP service is not provided and gives errors,
|
||||
this service is best run with a different \fBport:\fR config or \fI@port\fR
|
||||
suffixes in the \fBinterface\fR config.
|
||||
.TP
|
||||
.B ssl\-service\-pem: \fI<file>
|
||||
The public key certificate pem file for the ssl service. Default is "",
|
||||
.B ssl\-service\-key: \fI<file>
|
||||
Alternate syntax for \fBtls\-service\-key\fR.
|
||||
.TP
|
||||
.B tls\-service\-pem: \fI<file>
|
||||
The public key certificate pem file for the tls service. Default is "",
|
||||
turned off.
|
||||
.TP
|
||||
.B ssl\-service\-pem: \fI<file>
|
||||
Alternate syntax for \fBtls\-service\-pem\fR.
|
||||
.TP
|
||||
.B tls\-port: \fI<number>
|
||||
The port number on which to provide TCP TLS service, default 853, only
|
||||
interfaces configured with that port number as @number get the TLS service.
|
||||
.TP
|
||||
.B ssl\-port: \fI<number>
|
||||
The port number on which to provide TCP SSL service, default 853, only
|
||||
interfaces configured with that port number as @number get the SSL service.
|
||||
Alternate syntax for \fBtls\-port\fR.
|
||||
.TP
|
||||
.B tls\-cert\-bundle: \fI<file>
|
||||
If null or "", no file is used. Set it to the certificate bundle file,
|
||||
for example "/etc/pki/tls/certs/ca\-bundle.crt". These certificates are used
|
||||
for authenticating connections made to outside peers. For example auth\-zone
|
||||
urls, and also DNS over TLS connections.
|
||||
.TP
|
||||
.B ssl\-cert\-bundle: \fI<file>
|
||||
Alternate syntax for \fBtls\-cert\-bundle\fR.
|
||||
.TP
|
||||
.B tls\-win\-cert: \fI<yes or no>
|
||||
Add the system certificates to the cert bundle certificates for authentication.
|
||||
If no cert bundle, it uses only these certificates. Default is no.
|
||||
On windows this option uses the certificates from the cert store. Use
|
||||
the tls\-cert\-bundle option on other systems.
|
||||
.TP
|
||||
.B tls\-additional\-port: \fI<portnr>
|
||||
List portnumbers as tls\-additional\-port, and when interfaces are defined,
|
||||
eg. with the @port suffix, as this port number, they provide dns over TLS
|
||||
service. Can list multiple, each on a new statement.
|
||||
.TP
|
||||
.B use\-systemd: \fI<yes or no>
|
||||
Enable or disable systemd socket activation.
|
||||
@@ -432,7 +469,8 @@ Default is yes.
|
||||
.B access\-control: \fI<IP netblock> <action>
|
||||
The netblock is given as an IP4 or IP6 address with /size appended for a
|
||||
classless network block. The action can be \fIdeny\fR, \fIrefuse\fR,
|
||||
\fIallow\fR, \fIallow_snoop\fR, \fIdeny_non_local\fR or \fIrefuse_non_local\fR.
|
||||
\fIallow\fR, \fIallow_setrd\fR, \fIallow_snoop\fR, \fIdeny_non_local\fR or
|
||||
\fIrefuse_non_local\fR.
|
||||
The most specific netblock match is used, if none match \fIdeny\fR is used.
|
||||
.IP
|
||||
The action \fIdeny\fR stops queries from hosts from that netblock.
|
||||
@@ -451,6 +489,15 @@ in the reply. This supports normal operations where nonrecursive queries
|
||||
are made for the authoritative data. For nonrecursive queries any replies
|
||||
from the dynamic cache are refused.
|
||||
.IP
|
||||
The \fIallow_setrd\fR action ignores the recursion desired (RD) bit and
|
||||
treats all requests as if the recursion desired bit is set. Note that this
|
||||
behavior violates RFC 1034 which states that a name server should never perform
|
||||
recursive service unless asked via the RD bit since this interferes with
|
||||
trouble shooting of name servers and their databases. This prohibited behavior
|
||||
may be useful if another DNS server must forward requests for specific
|
||||
zones to a resolver DNS server, but only supports stub domains and
|
||||
sends queries to the resolver DNS server with the RD bit cleared.
|
||||
.IP
|
||||
The action \fIallow_snoop\fR gives nonrecursive access too. This give
|
||||
both recursive and non recursive access. The name \fIallow_snoop\fR refers
|
||||
to cache snooping, a technique to use nonrecursive queries to examine
|
||||
@@ -662,7 +709,7 @@ infrastructure data. Validates the replies if trust anchors are configured
|
||||
and the zones are signed. This enforces DNSSEC validation on nameserver
|
||||
NS sets and the nameserver addresses that are encountered on the referral
|
||||
path to the answer.
|
||||
Default off, because it burdens the authority servers, and it is
|
||||
Default no, because it burdens the authority servers, and it is
|
||||
not RFC standard, and could lead to performance problems because of the
|
||||
extra query load that is generated. Experimental option.
|
||||
If you enable it consider adding more numbers after the target\-fetch\-policy
|
||||
@@ -690,10 +737,10 @@ Can be given multiple times, for different domains.
|
||||
.TP
|
||||
.B qname\-minimisation: \fI<yes or no>
|
||||
Send minimum amount of information to upstream servers to enhance privacy.
|
||||
Only sent minimum required labels of the QNAME and set QTYPE to NS when
|
||||
Only sent minimum required labels of the QNAME and set QTYPE to A when
|
||||
possible. Best effort approach; full QNAME and original QTYPE will be sent when
|
||||
upstream replies with a RCODE other than NOERROR, except when receiving
|
||||
NXDOMAIN from a DNSSEC signed zone. Default is off.
|
||||
NXDOMAIN from a DNSSEC signed zone. Default is yes.
|
||||
.TP
|
||||
.B qname\-minimisation\-strict: \fI<yes or no>
|
||||
QNAME minimisation in strict mode. Do not fall-back to sending full QNAME to
|
||||
@@ -701,6 +748,12 @@ potentially broken nameservers. A lot of domains will not be resolvable when
|
||||
this option in enabled. Only use if you know what you are doing.
|
||||
This option only has effect when qname-minimisation is enabled. Default is off.
|
||||
.TP
|
||||
.B aggressive\-nsec: \fI<yes or no>
|
||||
Aggressive NSEC uses the DNSSEC NSEC chain to synthesize NXDOMAIN
|
||||
and other denials, using information from previous NXDOMAINs answers.
|
||||
Default is no. It helps to reduce the query rate towards targets that get
|
||||
a very high nonexistent name lookup rate.
|
||||
.TP
|
||||
.B private\-address: \fI<IP address or subnet>
|
||||
Give IPv4 of IPv6 addresses or classless subnets. These are addresses
|
||||
on your private network, and are not allowed to be returned for
|
||||
@@ -814,6 +867,9 @@ expanded on start and on reload.
|
||||
.B trust\-anchor\-signaling: \fI<yes or no>
|
||||
Send RFC8145 key tag query after trust anchor priming. Default is on.
|
||||
.TP
|
||||
.B root\-key\-sentinel: \fI<yes or no>
|
||||
Root key trust anchor sentinel. Default is on.
|
||||
.TP
|
||||
.B dlv\-anchor\-file: \fI<filename>
|
||||
This option was used during early days DNSSEC deployment when no parent-side
|
||||
DS record registrations were easily available. Nowadays, it is best to have
|
||||
@@ -976,7 +1032,7 @@ address space are not validated. This is usually required whenever
|
||||
Configure a local zone. The type determines the answer to give if
|
||||
there is no match from local\-data. The types are deny, refuse, static,
|
||||
transparent, redirect, nodefault, typetransparent, inform, inform_deny,
|
||||
always_transparent, always_refuse, always_nxdomain,
|
||||
always_transparent, always_refuse, always_nxdomain, noview,
|
||||
and are explained below. After that the default settings are listed. Use
|
||||
local\-data: to enter data into the local zone. Answers for local zones
|
||||
are authoritative DNS answers. By default the zones are class IN.
|
||||
@@ -1046,6 +1102,13 @@ Like refuse, but ignores local data and refuses the query.
|
||||
\h'5'\fIalways_nxdomain\fR
|
||||
Like static, but ignores local data and returns nxdomain for the query.
|
||||
.TP 10
|
||||
\h'5'\fInoview\fR
|
||||
Breaks out of that view and moves towards the global local zones for answer
|
||||
to the query. If the view first is no, it'll resolve normally. If view first
|
||||
is enabled, it'll break perform that step and check the global answers.
|
||||
For when the view has view specific overrides but some zone has to be
|
||||
answered from global local zone contents.
|
||||
.TP 10
|
||||
\h'5'\fInodefault\fR
|
||||
Used to turn off default contents for AS112 zones. The other types
|
||||
also turn off default contents for the zone. The 'nodefault' option
|
||||
@@ -1109,7 +1172,7 @@ local\-data: "onion. 10800 IN
|
||||
SOA localhost. nobody.invalid. 1 3600 1200 604800 10800"
|
||||
.fi
|
||||
.TP 10
|
||||
\h'5'\fItest (RFC 7686)\fR
|
||||
\h'5'\fItest (RFC 2606)\fR
|
||||
Default content:
|
||||
.nf
|
||||
local\-zone: "test." static
|
||||
@@ -1118,7 +1181,7 @@ local\-data: "test. 10800 IN
|
||||
SOA localhost. nobody.invalid. 1 3600 1200 604800 10800"
|
||||
.fi
|
||||
.TP 10
|
||||
\h'5'\fIinvalid (RFC 7686)\fR
|
||||
\h'5'\fIinvalid (RFC 2606)\fR
|
||||
Default content:
|
||||
.nf
|
||||
local\-zone: "invalid." static
|
||||
@@ -1267,13 +1330,30 @@ to complete. Default is 10, allowing 1/10 traffic to flow normally.
|
||||
This can make ordinary queries complete (if repeatedly queried for),
|
||||
and enter the cache, whilst also mitigating the traffic flow by the
|
||||
factor given.
|
||||
.TP 5
|
||||
.B low\-rtt: \fI<msec time>
|
||||
Set the time in millisecond that is considere a low ping time for fast
|
||||
server selection with the low\-rtt\-permil option, that turns this on or off.
|
||||
The default is 45 msec, a number from IPv6 quick response documents.
|
||||
.TP 5
|
||||
.B low\-rtt\-permil: \fI<number>
|
||||
Specify how many times out of 1000 to pick the fast server from the low
|
||||
rtt band. 0 turns the feature off. A value of 900 would pick the fast
|
||||
server when such fast servers are available 90 percent of the time, and
|
||||
the remaining time perform normal exploration of random servers.
|
||||
When prefetch is enabled (or serve\-expired), such prefetches are not
|
||||
sped up, because there is no one waiting for it, and it presents a good
|
||||
moment to perform server exploration. The low\-rtt option can be used
|
||||
to specify which servers are picked for fast server selection, servers
|
||||
with a ping roundtrip time below that value are considered.
|
||||
The default for low\-rtt\-permil is 0.
|
||||
.SS "Remote Control Options"
|
||||
In the
|
||||
.B remote\-control:
|
||||
clause are the declarations for the remote control facility. If this is
|
||||
enabled, the \fIunbound\-control\fR(8) utility can be used to send
|
||||
commands to the running unbound server. The server uses these clauses
|
||||
to setup SSLv3 / TLSv1 security for the connection. The
|
||||
to setup TLSv1 security for the connection. The
|
||||
\fIunbound\-control\fR(8) utility also reads the \fBremote\-control\fR
|
||||
section for options. To setup the correct self\-signed certificates use the
|
||||
\fIunbound\-control\-setup\fR(8) utility.
|
||||
@@ -1289,6 +1369,14 @@ By default localhost (127.0.0.1 and ::1) is listened to.
|
||||
Use 0.0.0.0 and ::0 to listen to all interfaces.
|
||||
If you change this and permissions have been dropped, you must restart
|
||||
the server for the change to take effect.
|
||||
.IP
|
||||
If you set it to an absolute path, a local socket is used. The local socket
|
||||
does not use the certificates and keys, so those files need not be present.
|
||||
To restrict access, unbound sets permissions on the file to the user and
|
||||
group that is configured, the access bits are set to allow the group members
|
||||
to access the control socket file. Put users that need to access the socket
|
||||
in the that group. To restrict access further, create a directory to put
|
||||
the control socket in and restrict access to that directory.
|
||||
.TP 5
|
||||
.B control\-port: \fI<port number>
|
||||
The port number to listen on for IPv4 or IPv6 control interfaces,
|
||||
@@ -1297,11 +1385,9 @@ If you change this and permissions have been dropped, you must restart
|
||||
the server for the change to take effect.
|
||||
.TP 5
|
||||
.B control\-use\-cert: \fI<yes or no>
|
||||
Whether to require certificate authentication of control connections.
|
||||
The default is "yes".
|
||||
This should not be changed unless there are other mechanisms in place
|
||||
to prevent untrusted users from accessing the remote control
|
||||
interface.
|
||||
For localhost control-interface you can disable the use of TLS by setting
|
||||
this option to "no", default is "yes". For local sockets, TLS is disabled
|
||||
and the value of this option is ignored.
|
||||
.TP 5
|
||||
.B server\-key\-file: \fI<private key file>
|
||||
Path to the server private key, by default unbound_server.key.
|
||||
@@ -1367,7 +1453,7 @@ IP address of stub zone nameserver. Can be IP 4 or IP 6.
|
||||
To use a nondefault port for DNS communication append '@' with the port number.
|
||||
.TP
|
||||
.B stub\-prime: \fI<yes or no>
|
||||
This option is by default off. If enabled it performs NS set priming,
|
||||
This option is by default no. If enabled it performs NS set priming,
|
||||
which is similar to root hints, where it starts using the list of nameservers
|
||||
currently published by the zone. Thus, if the hint list is slightly outdated,
|
||||
the resolver picks up a correct list online.
|
||||
@@ -1378,9 +1464,12 @@ The data could not be retrieved and would have caused SERVFAIL because
|
||||
the servers are unreachable, instead it is tried without this clause.
|
||||
The default is no.
|
||||
.TP
|
||||
.B stub\-ssl\-upstream: \fI<yes or no>
|
||||
Enabled or disable whether the queries to this stub use SSL for transport.
|
||||
.B stub\-tls\-upstream: \fI<yes or no>
|
||||
Enabled or disable whether the queries to this stub use TLS for transport.
|
||||
Default is no.
|
||||
.TP
|
||||
.B stub\-ssl\-upstream: \fI<yes or no>
|
||||
Alternate syntax for \fBstub\-tls\-upstream\fR.
|
||||
.SS "Forward Zone Options"
|
||||
.LP
|
||||
There may be multiple
|
||||
@@ -1392,6 +1481,9 @@ forward the queries to. The servers listed as \fBforward\-host:\fR and
|
||||
those servers are not authority servers, but are (just like unbound is)
|
||||
recursive servers too; unbound does not perform recursion itself for the
|
||||
forward zone, it lets the remote server do it. Class IN is assumed.
|
||||
CNAMEs are chased by unbound itself, asking the remote server for every
|
||||
name in the indirection chain, to protect the local cache from illegal
|
||||
indirect referenced items.
|
||||
A forward\-zone entry with name "." and a forward\-addr target will
|
||||
forward all queries to that other server (unless it can answer from
|
||||
the cache).
|
||||
@@ -1405,6 +1497,13 @@ Name of server to forward to. Is itself resolved before it is used.
|
||||
.B forward\-addr: \fI<IP address>
|
||||
IP address of server to forward to. Can be IP 4 or IP 6.
|
||||
To use a nondefault port for DNS communication append '@' with the port number.
|
||||
If tls is enabled, then you can append a '#' and a name, then it'll check
|
||||
the tls authentication certificates with that name. If you combine
|
||||
the '@' and '#', the '@' comes first.
|
||||
.IP
|
||||
At high verbosity it logs the TLS certificate, with TLS enabled.
|
||||
If you leave out the '#' and auth name from the forward\-addr, any
|
||||
name is accepted. The cert must also match a CA from the tls\-cert\-bundle.
|
||||
.TP
|
||||
.B forward\-first: \fI<yes or no>
|
||||
If enabled, a query is attempted without the forward clause if it fails.
|
||||
@@ -1412,9 +1511,83 @@ The data could not be retrieved and would have caused SERVFAIL because
|
||||
the servers are unreachable, instead it is tried without this clause.
|
||||
The default is no.
|
||||
.TP
|
||||
.B forward\-ssl\-upstream: \fI<yes or no>
|
||||
Enabled or disable whether the queries to this forwarder use SSL for transport.
|
||||
.B forward\-tls\-upstream: \fI<yes or no>
|
||||
Enabled or disable whether the queries to this forwarder use TLS for transport.
|
||||
Default is no.
|
||||
If you enable this, also configure a tls\-cert\-bundle or use tls\-win\cert to
|
||||
load CA certs, otherwise the connections cannot be authenticated.
|
||||
.TP
|
||||
.B forward\-ssl\-upstream: \fI<yes or no>
|
||||
Alternate syntax for \fBforward\-tls\-upstream\fR.
|
||||
.SS "Authority Zone Options"
|
||||
.LP
|
||||
Authority zones are configured with \fBauth\-zone:\fR, and each one must
|
||||
have a \fBname:\fR. There can be multiple ones, by listing multiple auth\-zone clauses, each with a different name, pertaining to that part of the namespace.
|
||||
The authority zone with the name closest to the name looked up is used.
|
||||
Authority zones are processed after \fBlocal\-zones\fR and before
|
||||
cache (\fBfor\-downstream:\fR \fIyes\fR), and when used in this manner
|
||||
make unbound respond like an authority server. Authority zones are also
|
||||
processed after cache, just before going to the network to fetch
|
||||
information for recursion (\fBfor\-upstream:\fR \fIyes\fR), and when used
|
||||
in this manner provide a local copy of an authority server that speeds up
|
||||
lookups of that data.
|
||||
.LP
|
||||
Authority zones can be read from zonefile. And can be kept updated via
|
||||
AXFR and IXFR. After update the zonefile is rewritten. The update mechanism
|
||||
uses the SOA timer values and performs SOA UDP queries to detect zone changes.
|
||||
.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 fallback\-enabled: \fI<yes or no>
|
||||
Default no. If enabled, unbound falls back to querying the internet as
|
||||
a resolver for this zone when lookups fail. For example for DNSSEC
|
||||
validation failures.
|
||||
.TP
|
||||
.B for\-downstream: \fI<yes or no>
|
||||
Default yes. If enabled, unbound serves authority responses to
|
||||
downstream clients for this zone. This option makes unbound behave, for
|
||||
the queries with names in this zone, like one of the authority servers for
|
||||
that zone. Turn it off if you want unbound to provide recursion for the
|
||||
zone but have a local copy of zone data. If for\-downstream is no and
|
||||
for\-upstream is yes, then unbound will DNSSEC validate the contents of the
|
||||
zone before serving the zone contents to clients and store validation
|
||||
results in the cache.
|
||||
.TP
|
||||
.B for\-upstream: \fI<yes or no>
|
||||
Default yes. If enabled, unbound fetches data from this data collection
|
||||
for answering recursion queries. Instead of sending queries over the internet
|
||||
to the authority servers for this zone, it'll fetch the data directly from
|
||||
the zone data. Turn it on when you want unbound to provide recursion for
|
||||
downstream clients, and use the zone data as a local copy to speed up lookups.
|
||||
.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).
|
||||
.SS "View Options"
|
||||
.LP
|
||||
There may be multiple
|
||||
@@ -1513,6 +1686,19 @@ times.
|
||||
Path to the certificate related to the \fBdnscrypt\-secret\-key\fRs.
|
||||
This option may be specified multiple times.
|
||||
.TP
|
||||
.B dnscrypt\-provider\-cert\-rotated: \fI<path to cert file>\fR
|
||||
Path to a certificate that we should be able to serve existing connection from
|
||||
but do not want to advertise over \fBdnscrypt\-provider\fR's TXT record certs
|
||||
distribution.
|
||||
A typical use case is when rotating certificates, existing clients may still use
|
||||
the client magic from the old cert in their queries until they fetch and update
|
||||
the new cert. Likewise, it would allow one to prime the new cert/key without
|
||||
distributing the new cert yet, this can be useful when using a network of
|
||||
servers using anycast and on which the configuration may not get updated at the
|
||||
exact same time. By priming the cert, the servers can handle both old and new
|
||||
certs traffic while distributing only one.
|
||||
This option may be specified multiple times.
|
||||
.TP
|
||||
.B dnscrypt\-shared\-secret\-cache\-size: \fI<memory size>
|
||||
Give the size of the data structure in which the shared secret keys are kept
|
||||
in. Default 4m. In bytes or use m(mega), k(kilo), g(giga).
|
||||
@@ -1661,15 +1847,42 @@ If it finds a valid answer in the backend, Unbound uses it to respond
|
||||
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
|
||||
If Unbound was built with
|
||||
\fB\-\-with\-libhiredis\fR
|
||||
on a system that has installed the hiredis C client library of Redis,
|
||||
then the "redis" backend can be used.
|
||||
This backend communicates with the specified Redis server over a TCP
|
||||
connection to store and retrieve cache data.
|
||||
It can be used as a persistent and/or shared cache backend.
|
||||
It should be noted that Unbound never removes data stored in the Redis server,
|
||||
even if some data have expired in terms of DNS TTL or the Redis server has
|
||||
cached too much data;
|
||||
if necessary the Redis server must be configured to limit the cache size,
|
||||
preferably with some kind of least-recently-used eviction policy.
|
||||
This backend uses synchronous communication with the Redis server
|
||||
based on the assumption that the communication is stable and sufficiently
|
||||
fast.
|
||||
The thread waiting for a response from the Redis server cannot handle
|
||||
other DNS queries.
|
||||
Although the backend has the ability to reconnect to the server when
|
||||
the connection is closed unexpectedly and there is a configurable timeout
|
||||
in case the server is overly slow or hangs up, these cases are assumed
|
||||
to be very rare.
|
||||
If connection close or timeout happens too often, Unbound will be
|
||||
effectively unusable with this backend.
|
||||
It's the administrator's responsibility to make the assumption hold.
|
||||
.P
|
||||
The
|
||||
.B cachedb:
|
||||
clause gives custom settings of the cache DB module.
|
||||
.TP
|
||||
.B backend: \fI<backend name>\fR
|
||||
Specify the backend database name.
|
||||
Currently, only the in-memory "testframe" backend is supported.
|
||||
As the name suggests this backend is not of any practical use.
|
||||
This option defaults to "testframe".
|
||||
The default database is the in-memory backend named "testframe", which,
|
||||
as the name suggests, is not of any practical use.
|
||||
Depending on the build-time configuration, "redis" backend may also be
|
||||
used as described above.
|
||||
.TP
|
||||
.B secret-seed: \fI<"secret string">\fR
|
||||
Specify a seed to calculate a hash value from query information.
|
||||
@@ -1679,6 +1892,28 @@ operationally.
|
||||
If the backend database is shared by multiple Unbound instances,
|
||||
all instances must use the same secret seed.
|
||||
This option defaults to "default".
|
||||
.P
|
||||
The following
|
||||
.B cachedb
|
||||
otions are specific to the redis backend.
|
||||
.TP
|
||||
.B redis-server-host: \fI<server address or name>\fR
|
||||
The IP (either v6 or v4) address or domain name of the Redis server.
|
||||
In general an IP address should be specified as otherwise Unbound will have to
|
||||
resolve the name of the server every time it establishes a connection
|
||||
to the server.
|
||||
This option defaults to "127.0.0.1".
|
||||
.TP
|
||||
.B redis-server-port: \fI<port number>\fR
|
||||
The TCP port number of the Redis server.
|
||||
This option defaults to 6379.
|
||||
.TP
|
||||
.B redis-timeout: \fI<msec>\fR
|
||||
The period until when Unbound waits for a response from the Redis sever.
|
||||
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.
|
||||
.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
|
||||
|
||||
@@ -485,7 +485,7 @@ addrtree_find(struct addrtree *tree, const addrkey_t *addr,
|
||||
/* does this node have data? if yes, see if we have a match */
|
||||
if (node->elem && node->ttl >= now) {
|
||||
/* saved at wrong depth */;
|
||||
log_assert(node->scope >= depth)
|
||||
log_assert(node->scope >= depth);
|
||||
if (depth == node->scope ||
|
||||
(node->scope > sourcemask &&
|
||||
depth == sourcemask)) {
|
||||
|
||||
@@ -339,6 +339,7 @@ update_cache(struct module_qstate *qstate, int id)
|
||||
return;
|
||||
}
|
||||
lru_entry = &mrep_entry->entry;
|
||||
lock_rw_wrlock(&lru_entry->lock);
|
||||
lru_entry->data = calloc(1,
|
||||
sizeof(struct subnet_msg_cache_data));
|
||||
if (!lru_entry->data) {
|
||||
@@ -352,7 +353,9 @@ update_cache(struct module_qstate *qstate, int id)
|
||||
log_err("Subnet cache insertion failed");
|
||||
return;
|
||||
}
|
||||
lock_quick_lock(&sne->alloc.lock);
|
||||
rep = reply_info_copy(qstate->return_msg->rep, &sne->alloc, NULL);
|
||||
lock_quick_unlock(&sne->alloc.lock);
|
||||
if (!rep) {
|
||||
if (acquired_lock) lock_rw_unlock(&lru_entry->lock);
|
||||
log_err("Subnet cache insertion failed");
|
||||
@@ -374,6 +377,7 @@ update_cache(struct module_qstate *qstate, int id)
|
||||
if (acquired_lock) {
|
||||
lock_rw_unlock(&lru_entry->lock);
|
||||
} else {
|
||||
lock_rw_unlock(&lru_entry->lock);
|
||||
slabhash_insert(subnet_msg_cache, h, lru_entry, lru_entry->data,
|
||||
NULL);
|
||||
}
|
||||
|
||||
+28
-6
@@ -84,7 +84,7 @@ struct delegpt* delegpt_copy(struct delegpt* dp, struct regional* region)
|
||||
}
|
||||
for(a = dp->target_list; a; a = a->next_target) {
|
||||
if(!delegpt_add_addr(copy, region, &a->addr, a->addrlen,
|
||||
a->bogus, a->lame))
|
||||
a->bogus, a->lame, a->tls_auth_name))
|
||||
return NULL;
|
||||
}
|
||||
return copy;
|
||||
@@ -176,13 +176,13 @@ delegpt_add_target(struct delegpt* dp, struct regional* region,
|
||||
if(ns->got4 && ns->got6)
|
||||
ns->resolved = 1;
|
||||
}
|
||||
return delegpt_add_addr(dp, region, addr, addrlen, bogus, lame);
|
||||
return delegpt_add_addr(dp, region, addr, addrlen, bogus, lame, NULL);
|
||||
}
|
||||
|
||||
int
|
||||
delegpt_add_addr(struct delegpt* dp, struct regional* region,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t bogus,
|
||||
uint8_t lame)
|
||||
uint8_t lame, char* tls_auth_name)
|
||||
{
|
||||
struct delegpt_addr* a;
|
||||
log_assert(!dp->dp_type_mlc);
|
||||
@@ -210,6 +210,13 @@ delegpt_add_addr(struct delegpt* dp, struct regional* region,
|
||||
a->bogus = bogus;
|
||||
a->lame = lame;
|
||||
a->dnsseclame = 0;
|
||||
if(tls_auth_name) {
|
||||
a->tls_auth_name = regional_strdup(region, tls_auth_name);
|
||||
if(!a->tls_auth_name)
|
||||
return 0;
|
||||
} else {
|
||||
a->tls_auth_name = NULL;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -276,11 +283,16 @@ void delegpt_log(enum verbosity_value v, struct delegpt* dp)
|
||||
(ns->done_pside6?" PSIDE_AAAA":""));
|
||||
}
|
||||
for(a = dp->target_list; a; a = a->next_target) {
|
||||
char s[128];
|
||||
const char* str = " ";
|
||||
if(a->bogus && a->lame) str = " BOGUS ADDR_LAME ";
|
||||
else if(a->bogus) str = " BOGUS ";
|
||||
else if(a->lame) str = " ADDR_LAME ";
|
||||
log_addr(VERB_ALGO, str, &a->addr, a->addrlen);
|
||||
if(a->tls_auth_name)
|
||||
snprintf(s, sizeof(s), "%s[%s]", str,
|
||||
a->tls_auth_name);
|
||||
else snprintf(s, sizeof(s), "%s", str);
|
||||
log_addr(VERB_ALGO, s, &a->addr, a->addrlen);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -539,6 +551,7 @@ void delegpt_free_mlc(struct delegpt* dp)
|
||||
a = dp->target_list;
|
||||
while(a) {
|
||||
na = a->next_target;
|
||||
free(a->tls_auth_name);
|
||||
free(a);
|
||||
a = na;
|
||||
}
|
||||
@@ -585,7 +598,7 @@ int delegpt_add_ns_mlc(struct delegpt* dp, uint8_t* name, uint8_t lame)
|
||||
}
|
||||
|
||||
int delegpt_add_addr_mlc(struct delegpt* dp, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, uint8_t bogus, uint8_t lame)
|
||||
socklen_t addrlen, uint8_t bogus, uint8_t lame, char* tls_auth_name)
|
||||
{
|
||||
struct delegpt_addr* a;
|
||||
log_assert(dp->dp_type_mlc);
|
||||
@@ -612,6 +625,15 @@ int delegpt_add_addr_mlc(struct delegpt* dp, struct sockaddr_storage* addr,
|
||||
a->bogus = bogus;
|
||||
a->lame = lame;
|
||||
a->dnsseclame = 0;
|
||||
if(tls_auth_name) {
|
||||
a->tls_auth_name = strdup(tls_auth_name);
|
||||
if(!a->tls_auth_name) {
|
||||
free(a);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
a->tls_auth_name = NULL;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -632,7 +654,7 @@ int delegpt_add_target_mlc(struct delegpt* dp, uint8_t* name, size_t namelen,
|
||||
if(ns->got4 && ns->got6)
|
||||
ns->resolved = 1;
|
||||
}
|
||||
return delegpt_add_addr_mlc(dp, addr, addrlen, bogus, lame);
|
||||
return delegpt_add_addr_mlc(dp, addr, addrlen, bogus, lame, NULL);
|
||||
}
|
||||
|
||||
size_t delegpt_get_mem(struct delegpt* dp)
|
||||
|
||||
@@ -83,6 +83,8 @@ struct delegpt {
|
||||
uint8_t dp_type_mlc;
|
||||
/** use SSL for upstream query */
|
||||
uint8_t ssl_upstream;
|
||||
/** delegpt from authoritative zone that is locally hosted */
|
||||
uint8_t auth_dp;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -149,6 +151,8 @@ struct delegpt_addr {
|
||||
* option is useful to mark the address dnsseclame.
|
||||
* This value is not copied in addr-copy and dp-copy. */
|
||||
uint8_t dnsseclame;
|
||||
/** the TLS authentication name, (if not NULL) to use. */
|
||||
char* tls_auth_name;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -257,11 +261,12 @@ int delegpt_add_rrset(struct delegpt* dp, struct regional* regional,
|
||||
* @param addrlen: the length of addr.
|
||||
* @param bogus: if address is bogus.
|
||||
* @param lame: if address is lame.
|
||||
* @param tls_auth_name: TLS authentication name (or NULL).
|
||||
* @return false on error.
|
||||
*/
|
||||
int delegpt_add_addr(struct delegpt* dp, struct regional* regional,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
uint8_t bogus, uint8_t lame);
|
||||
uint8_t bogus, uint8_t lame, char* tls_auth_name);
|
||||
|
||||
/**
|
||||
* Find NS record in name list of delegation point.
|
||||
@@ -392,10 +397,11 @@ int delegpt_add_ns_mlc(struct delegpt* dp, uint8_t* name, uint8_t lame);
|
||||
* @param addrlen: the length of addr.
|
||||
* @param bogus: if address is bogus.
|
||||
* @param lame: if address is lame.
|
||||
* @param tls_auth_name: TLS authentication name (or NULL).
|
||||
* @return false on error.
|
||||
*/
|
||||
int delegpt_add_addr_mlc(struct delegpt* dp, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, uint8_t bogus, uint8_t lame);
|
||||
socklen_t addrlen, uint8_t bogus, uint8_t lame, char* tls_auth_name);
|
||||
|
||||
/**
|
||||
* Add target address to the delegation point.
|
||||
|
||||
+4
-2
@@ -231,14 +231,16 @@ read_fwds_addr(struct config_stub* s, struct delegpt* dp)
|
||||
struct config_strlist* p;
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addrlen;
|
||||
char* tls_auth_name;
|
||||
for(p = s->addrs; p; p = p->next) {
|
||||
log_assert(p->str);
|
||||
if(!extstrtoaddr(p->str, &addr, &addrlen)) {
|
||||
if(!authextstrtoaddr(p->str, &addr, &addrlen, &tls_auth_name)) {
|
||||
log_err("cannot parse forward %s ip address: '%s'",
|
||||
s->name, p->str);
|
||||
return 0;
|
||||
}
|
||||
if(!delegpt_add_addr_mlc(dp, &addr, addrlen, 0, 0)) {
|
||||
if(!delegpt_add_addr_mlc(dp, &addr, addrlen, 0, 0,
|
||||
tls_auth_name)) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@ compile_time_root_prime(int do_ip4, int do_ip6)
|
||||
dp->has_parent_side_NS = 1;
|
||||
if(do_ip4) {
|
||||
if(!ah(dp, "A.ROOT-SERVERS.NET.", "198.41.0.4")) goto failed;
|
||||
if(!ah(dp, "B.ROOT-SERVERS.NET.", "192.228.79.201")) goto failed;
|
||||
if(!ah(dp, "B.ROOT-SERVERS.NET.", "199.9.14.201")) goto failed;
|
||||
if(!ah(dp, "C.ROOT-SERVERS.NET.", "192.33.4.12")) goto failed;
|
||||
if(!ah(dp, "D.ROOT-SERVERS.NET.", "199.7.91.13")) goto failed;
|
||||
if(!ah(dp, "E.ROOT-SERVERS.NET.", "192.203.230.10")) goto failed;
|
||||
@@ -244,14 +244,16 @@ read_stubs_addr(struct config_stub* s, struct delegpt* dp)
|
||||
struct config_strlist* p;
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addrlen;
|
||||
char* auth_name;
|
||||
for(p = s->addrs; p; p = p->next) {
|
||||
log_assert(p->str);
|
||||
if(!extstrtoaddr(p->str, &addr, &addrlen)) {
|
||||
if(!authextstrtoaddr(p->str, &addr, &addrlen, &auth_name)) {
|
||||
log_err("cannot parse stub %s ip address: '%s'",
|
||||
s->name, p->str);
|
||||
return 0;
|
||||
}
|
||||
if(!delegpt_add_addr_mlc(dp, &addr, addrlen, 0, 0)) {
|
||||
if(!delegpt_add_addr_mlc(dp, &addr, addrlen, 0, 0,
|
||||
auth_name)) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -503,6 +503,24 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
|
||||
continue;
|
||||
}
|
||||
}
|
||||
/* if this is type DS and we query for type DS we just got
|
||||
* a referral answer for our type DS query, fix packet */
|
||||
if(rrset->type==LDNS_RR_TYPE_DS &&
|
||||
qinfo->qtype == LDNS_RR_TYPE_DS &&
|
||||
dname_pkt_compare(pkt, qinfo->qname, rrset->dname) == 0) {
|
||||
rrset->section = LDNS_SECTION_ANSWER;
|
||||
msg->ancount = rrset->rr_count + rrset->rrsig_count;
|
||||
msg->nscount = 0;
|
||||
msg->arcount = 0;
|
||||
msg->an_rrsets = 1;
|
||||
msg->ns_rrsets = 0;
|
||||
msg->ar_rrsets = 0;
|
||||
msg->rrset_count = 1;
|
||||
msg->rrset_first = rrset;
|
||||
msg->rrset_last = rrset;
|
||||
rrset->rrset_all_next = NULL;
|
||||
return 1;
|
||||
}
|
||||
mark_additional_rrset(pkt, msg, rrset);
|
||||
prev = rrset;
|
||||
rrset = rrset->rrset_all_next;
|
||||
|
||||
+23
-7
@@ -312,9 +312,9 @@ static int
|
||||
iter_filter_order(struct iter_env* iter_env, struct module_env* env,
|
||||
uint8_t* name, size_t namelen, uint16_t qtype, time_t now,
|
||||
struct delegpt* dp, int* selected_rtt, int open_target,
|
||||
struct sock_list* blacklist)
|
||||
struct sock_list* blacklist, time_t prefetch)
|
||||
{
|
||||
int got_num = 0, low_rtt = 0, swap_to_front;
|
||||
int got_num = 0, low_rtt = 0, swap_to_front, rtt_band = RTT_BAND;
|
||||
struct delegpt_addr* a, *n, *prev=NULL;
|
||||
|
||||
/* fillup sel_rtt and find best rtt in the bunch */
|
||||
@@ -329,6 +329,16 @@ iter_filter_order(struct iter_env* iter_env, struct module_env* env,
|
||||
return 0 to force the caller to fetch more */
|
||||
}
|
||||
|
||||
if(env->cfg->low_rtt_permil != 0 && prefetch == 0 &&
|
||||
low_rtt < env->cfg->low_rtt &&
|
||||
ub_random_max(env->rnd, 1000) < env->cfg->low_rtt_permil) {
|
||||
/* the query is not prefetch, but for a downstream client,
|
||||
* there is a low_rtt (fast) server. We choose that x% of the
|
||||
* time */
|
||||
/* pick rtt numbers from 0..LOWBAND_RTT */
|
||||
rtt_band = env->cfg->low_rtt - low_rtt;
|
||||
}
|
||||
|
||||
got_num = 0;
|
||||
a = dp->result_list;
|
||||
while(a) {
|
||||
@@ -340,10 +350,10 @@ iter_filter_order(struct iter_env* iter_env, struct module_env* env,
|
||||
}
|
||||
/* classify the server address and determine what to do */
|
||||
swap_to_front = 0;
|
||||
if(a->sel_rtt >= low_rtt && a->sel_rtt - low_rtt <= RTT_BAND) {
|
||||
if(a->sel_rtt >= low_rtt && a->sel_rtt - low_rtt <= rtt_band) {
|
||||
got_num++;
|
||||
swap_to_front = 1;
|
||||
} else if(a->sel_rtt<low_rtt && low_rtt-a->sel_rtt<=RTT_BAND) {
|
||||
} else if(a->sel_rtt<low_rtt && low_rtt-a->sel_rtt<=rtt_band) {
|
||||
got_num++;
|
||||
swap_to_front = 1;
|
||||
}
|
||||
@@ -400,13 +410,14 @@ struct delegpt_addr*
|
||||
iter_server_selection(struct iter_env* iter_env,
|
||||
struct module_env* env, struct delegpt* dp,
|
||||
uint8_t* name, size_t namelen, uint16_t qtype, int* dnssec_lame,
|
||||
int* chase_to_rd, int open_target, struct sock_list* blacklist)
|
||||
int* chase_to_rd, int open_target, struct sock_list* blacklist,
|
||||
time_t prefetch)
|
||||
{
|
||||
int sel;
|
||||
int selrtt;
|
||||
struct delegpt_addr* a, *prev;
|
||||
int num = iter_filter_order(iter_env, env, name, namelen, qtype,
|
||||
*env->now, dp, &selrtt, open_target, blacklist);
|
||||
*env->now, dp, &selrtt, open_target, blacklist, prefetch);
|
||||
|
||||
if(num == 0)
|
||||
return NULL;
|
||||
@@ -625,7 +636,7 @@ iter_dp_is_useless(struct query_info* qinfo, uint16_t qflags,
|
||||
}
|
||||
|
||||
int
|
||||
iter_indicates_dnssec_fwd(struct module_env* env, struct query_info *qinfo)
|
||||
iter_qname_indicates_dnssec(struct module_env* env, struct query_info *qinfo)
|
||||
{
|
||||
struct trust_anchor* a;
|
||||
if(!env || !env->anchors || !qinfo || !qinfo->qname)
|
||||
@@ -656,6 +667,11 @@ iter_indicates_dnssec(struct module_env* env, struct delegpt* dp,
|
||||
/* a trust anchor exists with this name, RRSIGs expected */
|
||||
if((a=anchor_find(env->anchors, dp->name, dp->namelabs, dp->namelen,
|
||||
dclass))) {
|
||||
if(a->numDS == 0 && a->numDNSKEY == 0) {
|
||||
/* insecure trust point */
|
||||
lock_basic_unlock(&a->lock);
|
||||
return 0;
|
||||
}
|
||||
lock_basic_unlock(&a->lock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
+10
-6
@@ -87,13 +87,18 @@ int iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg);
|
||||
* @param open_target: number of currently outstanding target queries.
|
||||
* If we wait for these, perhaps more server addresses become available.
|
||||
* @param blacklist: the IP blacklist to use.
|
||||
* @param prefetch: if not 0, prefetch is in use for this query.
|
||||
* This means the query can have different timing, because prefetch is
|
||||
* not waited upon by the downstream client, and thus a good time to
|
||||
* perform exploration of other targets.
|
||||
* @return best target or NULL if no target.
|
||||
* if not null, that target is removed from the result list in the dp.
|
||||
*/
|
||||
struct delegpt_addr* iter_server_selection(struct iter_env* iter_env,
|
||||
struct module_env* env, struct delegpt* dp, uint8_t* name,
|
||||
size_t namelen, uint16_t qtype, int* dnssec_lame,
|
||||
int* chase_to_rd, int open_target, struct sock_list* blacklist);
|
||||
int* chase_to_rd, int open_target, struct sock_list* blacklist,
|
||||
time_t prefetch);
|
||||
|
||||
/**
|
||||
* Allocate dns_msg from parsed msg, in regional.
|
||||
@@ -174,15 +179,14 @@ int iter_dp_is_useless(struct query_info* qinfo, uint16_t qflags,
|
||||
struct delegpt* dp);
|
||||
|
||||
/**
|
||||
* See if qname has DNSSEC needs in the forwarding case. This is true if
|
||||
* there is a trust anchor above it. Whether there is an insecure delegation
|
||||
* to the data is unknown, but CD-retry is needed.
|
||||
* See if qname has DNSSEC needs. This is true if there is a trust anchor above
|
||||
* it. Whether there is an insecure delegation to the data is unknown.
|
||||
* @param env: environment with anchors.
|
||||
* @param qinfo: query name and class.
|
||||
* @return true if trust anchor above qname, false if no anchor or insecure
|
||||
* point above qname.
|
||||
*/
|
||||
int iter_indicates_dnssec_fwd(struct module_env* env,
|
||||
int iter_qname_indicates_dnssec(struct module_env* env,
|
||||
struct query_info *qinfo);
|
||||
|
||||
/**
|
||||
@@ -193,7 +197,7 @@ int iter_indicates_dnssec_fwd(struct module_env* env,
|
||||
* @param dp: delegation point.
|
||||
* @param msg: delegation message, with DS if a secure referral.
|
||||
* @param dclass: class of query.
|
||||
* @return 1 if dnssec is expected, 0 if not.
|
||||
* @return 1 if dnssec is expected, 0 if not or insecure point above qname.
|
||||
*/
|
||||
int iter_indicates_dnssec(struct module_env* env, struct delegpt* dp,
|
||||
struct dns_msg* msg, uint16_t dclass);
|
||||
|
||||
+353
-128
@@ -53,6 +53,7 @@
|
||||
#include "validator/val_neg.h"
|
||||
#include "services/cache/dns.h"
|
||||
#include "services/cache/infra.h"
|
||||
#include "services/authzone.h"
|
||||
#include "util/module.h"
|
||||
#include "util/netevent.h"
|
||||
#include "util/net_help.h"
|
||||
@@ -535,7 +536,7 @@ handle_cname_response(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
/** see if last resort is possible - does config allow queries to parent */
|
||||
static int
|
||||
can_have_last_resort(struct module_env* env, uint8_t* nm, size_t nmlen,
|
||||
uint16_t qclass)
|
||||
uint16_t qclass, struct delegpt** retdp)
|
||||
{
|
||||
struct delegpt* fwddp;
|
||||
struct iter_hints_stub* stub;
|
||||
@@ -548,12 +549,14 @@ can_have_last_resort(struct module_env* env, uint8_t* nm, size_t nmlen,
|
||||
/* has_parent side is turned off for stub_first, where we
|
||||
* are allowed to go to the parent */
|
||||
stub->dp->has_parent_side_NS) {
|
||||
if(retdp) *retdp = stub->dp;
|
||||
return 0;
|
||||
}
|
||||
if((fwddp = forwards_find(env->fwds, nm, qclass)) &&
|
||||
/* has_parent_side is turned off for forward_first, where
|
||||
* we are allowed to go to the parent */
|
||||
fwddp->has_parent_side_NS) {
|
||||
if(retdp) *retdp = fwddp;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
@@ -771,6 +774,11 @@ prime_stub(struct module_qstate* qstate, struct iter_qstate* iq, int id,
|
||||
if(!stub)
|
||||
return 0;
|
||||
stub_dp = stub->dp;
|
||||
/* if we have an auth_zone dp, and stub is equal, don't prime stub
|
||||
* yet, unless we want to fallback and avoid the auth_zone */
|
||||
if(!iq->auth_zone_avoid && iq->dp && iq->dp->auth_dp &&
|
||||
query_dname_compare(iq->dp->name, stub_dp->name) == 0)
|
||||
return 0;
|
||||
|
||||
/* is it a noprime stub (always use) */
|
||||
if(stub->noprime) {
|
||||
@@ -831,6 +839,96 @@ prime_stub(struct module_qstate* qstate, struct iter_qstate* iq, int id,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a delegation point for an auth zone (unless cached dp is better)
|
||||
* false on alloc failure.
|
||||
*/
|
||||
static int
|
||||
auth_zone_delegpt(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
uint8_t* delname, size_t delnamelen)
|
||||
{
|
||||
struct auth_zone* z;
|
||||
if(iq->auth_zone_avoid)
|
||||
return 1;
|
||||
if(!delname) {
|
||||
delname = iq->qchase.qname;
|
||||
delnamelen = iq->qchase.qname_len;
|
||||
}
|
||||
lock_rw_rdlock(&qstate->env->auth_zones->lock);
|
||||
z = auth_zones_find_zone(qstate->env->auth_zones, delname, delnamelen,
|
||||
qstate->qinfo.qclass);
|
||||
if(!z) {
|
||||
lock_rw_unlock(&qstate->env->auth_zones->lock);
|
||||
return 1;
|
||||
}
|
||||
lock_rw_rdlock(&z->lock);
|
||||
lock_rw_unlock(&qstate->env->auth_zones->lock);
|
||||
if(z->for_upstream) {
|
||||
if(iq->dp && query_dname_compare(z->name, iq->dp->name) == 0
|
||||
&& iq->dp->auth_dp && qstate->blacklist &&
|
||||
z->fallback_enabled) {
|
||||
/* cache is blacklisted and fallback, and we
|
||||
* already have an auth_zone dp */
|
||||
if(verbosity>=VERB_ALGO) {
|
||||
char buf[255+1];
|
||||
dname_str(z->name, buf);
|
||||
verbose(VERB_ALGO, "auth_zone %s "
|
||||
"fallback because cache blacklisted",
|
||||
buf);
|
||||
}
|
||||
lock_rw_unlock(&z->lock);
|
||||
iq->dp = NULL;
|
||||
return 1;
|
||||
}
|
||||
if(iq->dp==NULL || dname_subdomain_c(z->name, iq->dp->name)) {
|
||||
struct delegpt* dp;
|
||||
if(qstate->blacklist && z->fallback_enabled) {
|
||||
/* cache is blacklisted because of a DNSSEC
|
||||
* validation failure, and the zone allows
|
||||
* fallback to the internet, query there. */
|
||||
if(verbosity>=VERB_ALGO) {
|
||||
char buf[255+1];
|
||||
dname_str(z->name, buf);
|
||||
verbose(VERB_ALGO, "auth_zone %s "
|
||||
"fallback because cache blacklisted",
|
||||
buf);
|
||||
}
|
||||
lock_rw_unlock(&z->lock);
|
||||
return 1;
|
||||
}
|
||||
dp = (struct delegpt*)regional_alloc_zero(
|
||||
qstate->region, sizeof(*dp));
|
||||
if(!dp) {
|
||||
log_err("alloc failure");
|
||||
if(z->fallback_enabled) {
|
||||
lock_rw_unlock(&z->lock);
|
||||
return 1; /* just fallback */
|
||||
}
|
||||
lock_rw_unlock(&z->lock);
|
||||
return 0;
|
||||
}
|
||||
dp->name = regional_alloc_init(qstate->region,
|
||||
z->name, z->namelen);
|
||||
if(!dp->name) {
|
||||
log_err("alloc failure");
|
||||
if(z->fallback_enabled) {
|
||||
lock_rw_unlock(&z->lock);
|
||||
return 1; /* just fallback */
|
||||
}
|
||||
lock_rw_unlock(&z->lock);
|
||||
return 0;
|
||||
}
|
||||
dp->namelen = z->namelen;
|
||||
dp->namelabs = z->namelabs;
|
||||
dp->auth_dp = 1;
|
||||
iq->dp = dp;
|
||||
}
|
||||
}
|
||||
|
||||
lock_rw_unlock(&z->lock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate A and AAAA checks for glue that is in-zone for the referral
|
||||
* we just got to obtain authoritative information on the addresses.
|
||||
@@ -904,7 +1002,7 @@ generate_ns_check(struct module_qstate* qstate, struct iter_qstate* iq, int id)
|
||||
if(iq->depth == ie->max_dependency_depth)
|
||||
return;
|
||||
if(!can_have_last_resort(qstate->env, iq->dp->name, iq->dp->namelen,
|
||||
iq->qchase.qclass))
|
||||
iq->qchase.qclass, NULL))
|
||||
return;
|
||||
/* is this query the same as the nscheck? */
|
||||
if(qstate->qinfo.qtype == LDNS_RR_TYPE_NS &&
|
||||
@@ -914,6 +1012,9 @@ generate_ns_check(struct module_qstate* qstate, struct iter_qstate* iq, int id)
|
||||
generate_a_aaaa_check(qstate, iq, id);
|
||||
return;
|
||||
}
|
||||
/* no need to get the NS record for DS, it is above the zonecut */
|
||||
if(qstate->qinfo.qtype == LDNS_RR_TYPE_DS)
|
||||
return;
|
||||
|
||||
log_nametypeclass(VERB_ALGO, "schedule ns fetch",
|
||||
iq->dp->name, LDNS_RR_TYPE_NS, iq->qchase.qclass);
|
||||
@@ -1085,10 +1186,8 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
*/
|
||||
if (iq->refetch_glue &&
|
||||
iq->dp &&
|
||||
!can_have_last_resort(qstate->env,
|
||||
iq->dp->name,
|
||||
iq->dp->namelen,
|
||||
iq->qchase.qclass)) {
|
||||
!can_have_last_resort(qstate->env, iq->dp->name,
|
||||
iq->dp->namelen, iq->qchase.qclass, NULL)) {
|
||||
iq->refetch_glue = 0;
|
||||
}
|
||||
|
||||
@@ -1106,14 +1205,16 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
msg = dns_cache_lookup(qstate->env, iq->qchase.qname,
|
||||
iq->qchase.qname_len, iq->qchase.qtype,
|
||||
iq->qchase.qclass, qstate->query_flags,
|
||||
qstate->region, qstate->env->scratch);
|
||||
if(!msg && qstate->env->neg_cache) {
|
||||
qstate->region, qstate->env->scratch, 0);
|
||||
if(!msg && qstate->env->neg_cache &&
|
||||
iter_qname_indicates_dnssec(qstate->env, &iq->qchase)) {
|
||||
/* lookup in negative cache; may result in
|
||||
* NOERROR/NODATA or NXDOMAIN answers that need validation */
|
||||
msg = val_neg_getmsg(qstate->env->neg_cache, &iq->qchase,
|
||||
qstate->region, qstate->env->rrset_cache,
|
||||
qstate->env->scratch_buffer,
|
||||
*qstate->env->now, 1/*add SOA*/, NULL);
|
||||
*qstate->env->now, 1/*add SOA*/, NULL,
|
||||
qstate->env->cfg);
|
||||
}
|
||||
/* item taken from cache does not match our query name, thus
|
||||
* security needs to be re-examined later */
|
||||
@@ -1164,7 +1265,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
iq->response = msg;
|
||||
return final_state(iq);
|
||||
}
|
||||
|
||||
|
||||
/* attempt to forward the request */
|
||||
if(forward_request(qstate, iq))
|
||||
{
|
||||
@@ -1198,7 +1299,8 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
delnamelen = iq->qchase.qname_len;
|
||||
}
|
||||
if(iq->qchase.qtype == LDNS_RR_TYPE_DS || iq->refetch_glue ||
|
||||
(iq->qchase.qtype == LDNS_RR_TYPE_NS && qstate->prefetch_leeway)) {
|
||||
(iq->qchase.qtype == LDNS_RR_TYPE_NS && qstate->prefetch_leeway
|
||||
&& can_have_last_resort(qstate->env, delname, delnamelen, iq->qchase.qclass, NULL))) {
|
||||
/* remove first label from delname, root goes to hints,
|
||||
* but only to fetch glue, not for qtype=DS. */
|
||||
/* also when prefetching an NS record, fetch it again from
|
||||
@@ -1225,8 +1327,15 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
/* If the cache has returned nothing, then we have a
|
||||
* root priming situation. */
|
||||
if(iq->dp == NULL) {
|
||||
int r;
|
||||
/* if under auth zone, no prime needed */
|
||||
if(!auth_zone_delegpt(qstate, iq, delname, delnamelen))
|
||||
return error_response(qstate, id,
|
||||
LDNS_RCODE_SERVFAIL);
|
||||
if(iq->dp) /* use auth zone dp */
|
||||
return next_state(iq, INIT_REQUEST_2_STATE);
|
||||
/* if there is a stub, then no root prime needed */
|
||||
int r = prime_stub(qstate, iq, id, delname,
|
||||
r = prime_stub(qstate, iq, id, delname,
|
||||
iq->qchase.qclass);
|
||||
if(r == 2)
|
||||
break; /* got noprime-stub-zone, continue */
|
||||
@@ -1307,6 +1416,28 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
*/
|
||||
if(iter_dp_is_useless(&qstate->qinfo, qstate->query_flags,
|
||||
iq->dp)) {
|
||||
struct delegpt* retdp = NULL;
|
||||
if(!can_have_last_resort(qstate->env, iq->dp->name, iq->dp->namelen, iq->qchase.qclass, &retdp)) {
|
||||
if(retdp) {
|
||||
verbose(VERB_QUERY, "cache has stub "
|
||||
"or fwd but no addresses, "
|
||||
"fallback to config");
|
||||
iq->dp = delegpt_copy(retdp,
|
||||
qstate->region);
|
||||
if(!iq->dp) {
|
||||
log_err("out of memory in "
|
||||
"stub/fwd fallback");
|
||||
return error_response(qstate,
|
||||
id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
verbose(VERB_ALGO, "useless dp "
|
||||
"but cannot go up, servfail");
|
||||
delegpt_log(VERB_ALGO, iq->dp);
|
||||
return error_response(qstate, id,
|
||||
LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
if(dname_is_root(iq->dp->name)) {
|
||||
/* use safety belt */
|
||||
verbose(VERB_QUERY, "Cache has root NS but "
|
||||
@@ -1371,22 +1502,36 @@ processInitRequest2(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
log_query_info(VERB_QUERY, "resolving (init part 2): ",
|
||||
&qstate->qinfo);
|
||||
|
||||
delname = iq->qchase.qname;
|
||||
delnamelen = iq->qchase.qname_len;
|
||||
if(iq->refetch_glue) {
|
||||
struct iter_hints_stub* stub;
|
||||
if(!iq->dp) {
|
||||
log_err("internal or malloc fail: no dp for refetch");
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
delname = iq->dp->name;
|
||||
delnamelen = iq->dp->namelen;
|
||||
} else {
|
||||
delname = iq->qchase.qname;
|
||||
delnamelen = iq->qchase.qname_len;
|
||||
/* Do not send queries above stub, do not set delname to dp if
|
||||
* this is above stub without stub-first. */
|
||||
stub = hints_lookup_stub(
|
||||
qstate->env->hints, iq->qchase.qname, iq->qchase.qclass,
|
||||
iq->dp);
|
||||
if(!stub || !stub->dp->has_parent_side_NS ||
|
||||
dname_subdomain_c(iq->dp->name, stub->dp->name)) {
|
||||
delname = iq->dp->name;
|
||||
delnamelen = iq->dp->namelen;
|
||||
}
|
||||
}
|
||||
if(iq->qchase.qtype == LDNS_RR_TYPE_DS || iq->refetch_glue) {
|
||||
if(!dname_is_root(delname))
|
||||
dname_remove_label(&delname, &delnamelen);
|
||||
iq->refetch_glue = 0; /* if CNAME causes restart, no refetch */
|
||||
}
|
||||
|
||||
/* see if we have an auth zone to answer from, improves dp from cache
|
||||
* (if any dp from cache) with auth zone dp, if that is lower */
|
||||
if(!auth_zone_delegpt(qstate, iq, delname, delnamelen))
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
|
||||
/* Check to see if we need to prime a stub zone. */
|
||||
if(prime_stub(qstate, iq, id, delname, iq->qchase.qclass)) {
|
||||
/* A priming sub request was made */
|
||||
@@ -1650,7 +1795,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
log_assert(iq->dp);
|
||||
|
||||
if(!can_have_last_resort(qstate->env, iq->dp->name, iq->dp->namelen,
|
||||
iq->qchase.qclass)) {
|
||||
iq->qchase.qclass, NULL)) {
|
||||
/* fail -- no more targets, no more hope of targets, no hope
|
||||
* of a response. */
|
||||
verbose(VERB_QUERY, "configured stub or forward servers failed -- returning SERVFAIL");
|
||||
@@ -1670,7 +1815,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
for(a = p->target_list; a; a=a->next_target) {
|
||||
(void)delegpt_add_addr(iq->dp, qstate->region,
|
||||
&a->addr, a->addrlen, a->bogus,
|
||||
a->lame);
|
||||
a->lame, a->tls_auth_name);
|
||||
}
|
||||
}
|
||||
iq->dp->has_parent_side_NS = 1;
|
||||
@@ -1743,7 +1888,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
if( ((ie->supports_ipv6 && !ns->done_pside6) ||
|
||||
(ie->supports_ipv4 && !ns->done_pside4)) &&
|
||||
!can_have_last_resort(qstate->env, ns->name, ns->namelen,
|
||||
iq->qchase.qclass)) {
|
||||
iq->qchase.qclass, NULL)) {
|
||||
log_nametypeclass(VERB_ALGO, "cannot pside lookup ns "
|
||||
"because it is also a stub/forward,",
|
||||
ns->name, LDNS_RR_TYPE_NS, iq->qchase.qclass);
|
||||
@@ -1871,6 +2016,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
int tf_policy;
|
||||
struct delegpt_addr* target;
|
||||
struct outbound_entry* outq;
|
||||
int auth_fallback = 0;
|
||||
|
||||
/* NOTE: a request will encounter this state for each target it
|
||||
* needs to send a query to. That is, at least one per referral,
|
||||
@@ -1915,6 +2061,159 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(iq->minimisation_state == INIT_MINIMISE_STATE) {
|
||||
/* (Re)set qinfo_out to (new) delegation point, except when
|
||||
* qinfo_out is already a subdomain of dp. This happens when
|
||||
* increasing by more than one label at once (QNAMEs with more
|
||||
* than MAX_MINIMISE_COUNT labels). */
|
||||
if(!(iq->qinfo_out.qname_len
|
||||
&& dname_subdomain_c(iq->qchase.qname,
|
||||
iq->qinfo_out.qname)
|
||||
&& dname_subdomain_c(iq->qinfo_out.qname,
|
||||
iq->dp->name))) {
|
||||
iq->qinfo_out.qname = iq->dp->name;
|
||||
iq->qinfo_out.qname_len = iq->dp->namelen;
|
||||
iq->qinfo_out.qtype = LDNS_RR_TYPE_A;
|
||||
iq->qinfo_out.qclass = iq->qchase.qclass;
|
||||
iq->qinfo_out.local_alias = NULL;
|
||||
iq->minimise_count = 0;
|
||||
}
|
||||
|
||||
iq->minimisation_state = MINIMISE_STATE;
|
||||
}
|
||||
if(iq->minimisation_state == MINIMISE_STATE) {
|
||||
int qchaselabs = dname_count_labels(iq->qchase.qname);
|
||||
int labdiff = qchaselabs -
|
||||
dname_count_labels(iq->qinfo_out.qname);
|
||||
|
||||
iq->qinfo_out.qname = iq->qchase.qname;
|
||||
iq->qinfo_out.qname_len = iq->qchase.qname_len;
|
||||
iq->minimise_count++;
|
||||
iq->minimise_timeout_count = 0;
|
||||
|
||||
iter_dec_attempts(iq->dp, 1);
|
||||
|
||||
/* Limit number of iterations for QNAMEs with more
|
||||
* than MAX_MINIMISE_COUNT labels. Send first MINIMISE_ONE_LAB
|
||||
* labels of QNAME always individually.
|
||||
*/
|
||||
if(qchaselabs > MAX_MINIMISE_COUNT && labdiff > 1 &&
|
||||
iq->minimise_count > MINIMISE_ONE_LAB) {
|
||||
if(iq->minimise_count < MAX_MINIMISE_COUNT) {
|
||||
int multilabs = qchaselabs - 1 -
|
||||
MINIMISE_ONE_LAB;
|
||||
int extralabs = multilabs /
|
||||
MINIMISE_MULTIPLE_LABS;
|
||||
|
||||
if (MAX_MINIMISE_COUNT - iq->minimise_count >=
|
||||
multilabs % MINIMISE_MULTIPLE_LABS)
|
||||
/* Default behaviour is to add 1 label
|
||||
* every iteration. Therefore, decrement
|
||||
* the extralabs by 1 */
|
||||
extralabs--;
|
||||
if (extralabs < labdiff)
|
||||
labdiff -= extralabs;
|
||||
else
|
||||
labdiff = 1;
|
||||
}
|
||||
/* Last minimised iteration, send all labels with
|
||||
* QTYPE=NS */
|
||||
else
|
||||
labdiff = 1;
|
||||
}
|
||||
|
||||
if(labdiff > 1) {
|
||||
verbose(VERB_QUERY, "removing %d labels", labdiff-1);
|
||||
dname_remove_labels(&iq->qinfo_out.qname,
|
||||
&iq->qinfo_out.qname_len,
|
||||
labdiff-1);
|
||||
}
|
||||
if(labdiff < 1 || (labdiff < 2
|
||||
&& (iq->qchase.qtype == LDNS_RR_TYPE_DS
|
||||
|| iq->qchase.qtype == LDNS_RR_TYPE_A)))
|
||||
/* Stop minimising this query, resolve "as usual" */
|
||||
iq->minimisation_state = DONOT_MINIMISE_STATE;
|
||||
else if(!qstate->no_cache_lookup) {
|
||||
struct dns_msg* msg = dns_cache_lookup(qstate->env,
|
||||
iq->qinfo_out.qname, iq->qinfo_out.qname_len,
|
||||
iq->qinfo_out.qtype, iq->qinfo_out.qclass,
|
||||
qstate->query_flags, qstate->region,
|
||||
qstate->env->scratch, 0);
|
||||
if(msg && msg->rep->an_numrrsets == 0
|
||||
&& FLAGS_GET_RCODE(msg->rep->flags) ==
|
||||
LDNS_RCODE_NOERROR)
|
||||
/* no need to send query if it is already
|
||||
* cached as NOERROR/NODATA */
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if(iq->minimisation_state == SKIP_MINIMISE_STATE) {
|
||||
if(iq->minimise_timeout_count < MAX_MINIMISE_TIMEOUT_COUNT)
|
||||
/* Do not increment qname, continue incrementing next
|
||||
* iteration */
|
||||
iq->minimisation_state = MINIMISE_STATE;
|
||||
else if(!qstate->env->cfg->qname_minimisation_strict)
|
||||
/* Too many time-outs detected for this QNAME and QTYPE.
|
||||
* We give up, disable QNAME minimisation. */
|
||||
iq->minimisation_state = DONOT_MINIMISE_STATE;
|
||||
}
|
||||
if(iq->minimisation_state == DONOT_MINIMISE_STATE)
|
||||
iq->qinfo_out = iq->qchase;
|
||||
|
||||
/* now find an answer to this query */
|
||||
/* see if authority zones have an answer */
|
||||
/* now we know the dp, we can check the auth zone for locally hosted
|
||||
* contents */
|
||||
if(!iq->auth_zone_avoid && qstate->blacklist) {
|
||||
if(auth_zones_can_fallback(qstate->env->auth_zones,
|
||||
iq->dp->name, iq->dp->namelen, iq->qinfo_out.qclass)) {
|
||||
/* if cache is blacklisted and this zone allows us
|
||||
* to fallback to the internet, then do so, and
|
||||
* fetch results from the internet servers */
|
||||
iq->auth_zone_avoid = 1;
|
||||
}
|
||||
}
|
||||
if(iq->auth_zone_avoid) {
|
||||
iq->auth_zone_avoid = 0;
|
||||
auth_fallback = 1;
|
||||
} else if(auth_zones_lookup(qstate->env->auth_zones, &iq->qinfo_out,
|
||||
qstate->region, &iq->response, &auth_fallback, iq->dp->name,
|
||||
iq->dp->namelen)) {
|
||||
/* use this as a response to be processed by the iterator */
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
log_dns_msg("msg from auth zone",
|
||||
&iq->response->qinfo, iq->response->rep);
|
||||
}
|
||||
if((iq->chase_flags&BIT_RD) && !(iq->response->rep->flags&BIT_AA)) {
|
||||
verbose(VERB_ALGO, "forwarder, ignoring referral from auth zone");
|
||||
} else {
|
||||
lock_rw_wrlock(&qstate->env->auth_zones->lock);
|
||||
qstate->env->auth_zones->num_query_up++;
|
||||
lock_rw_unlock(&qstate->env->auth_zones->lock);
|
||||
iq->num_current_queries++;
|
||||
iq->chase_to_rd = 0;
|
||||
iq->dnssec_lame_query = 0;
|
||||
iq->auth_zone_response = 1;
|
||||
return next_state(iq, QUERY_RESP_STATE);
|
||||
}
|
||||
}
|
||||
iq->auth_zone_response = 0;
|
||||
if(auth_fallback == 0) {
|
||||
/* like we got servfail from the auth zone lookup, and
|
||||
* no internet fallback */
|
||||
verbose(VERB_ALGO, "auth zone lookup failed, no fallback,"
|
||||
" servfail");
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
if(iq->dp && iq->dp->auth_dp) {
|
||||
/* we wanted to fallback, but had no delegpt, only the
|
||||
* auth zone generated delegpt, create an actual one */
|
||||
iq->auth_zone_avoid = 1;
|
||||
return next_state(iq, INIT_REQUEST_STATE);
|
||||
}
|
||||
/* but mostly, fallback==1 (like, when no such auth zone exists)
|
||||
* and we continue with lookups */
|
||||
|
||||
tf_policy = 0;
|
||||
/* < not <=, because although the array is large enough for <=, the
|
||||
* generated query will immediately be discarded due to depth and
|
||||
@@ -1985,7 +2284,8 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
target = iter_server_selection(ie, qstate->env, iq->dp,
|
||||
iq->dp->name, iq->dp->namelen, iq->qchase.qtype,
|
||||
&iq->dnssec_lame_query, &iq->chase_to_rd,
|
||||
iq->num_target_queries, qstate->blacklist);
|
||||
iq->num_target_queries, qstate->blacklist,
|
||||
qstate->prefetch_leeway);
|
||||
|
||||
/* If no usable target was selected... */
|
||||
if(!target) {
|
||||
@@ -2082,105 +2382,6 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
}
|
||||
}
|
||||
|
||||
if(iq->minimisation_state == INIT_MINIMISE_STATE) {
|
||||
/* (Re)set qinfo_out to (new) delegation point, except when
|
||||
* qinfo_out is already a subdomain of dp. This happens when
|
||||
* increasing by more than one label at once (QNAMEs with more
|
||||
* than MAX_MINIMISE_COUNT labels). */
|
||||
if(!(iq->qinfo_out.qname_len
|
||||
&& dname_subdomain_c(iq->qchase.qname,
|
||||
iq->qinfo_out.qname)
|
||||
&& dname_subdomain_c(iq->qinfo_out.qname,
|
||||
iq->dp->name))) {
|
||||
iq->qinfo_out.qname = iq->dp->name;
|
||||
iq->qinfo_out.qname_len = iq->dp->namelen;
|
||||
iq->qinfo_out.qtype = LDNS_RR_TYPE_A;
|
||||
iq->qinfo_out.qclass = iq->qchase.qclass;
|
||||
iq->qinfo_out.local_alias = NULL;
|
||||
iq->minimise_count = 0;
|
||||
}
|
||||
|
||||
iq->minimisation_state = MINIMISE_STATE;
|
||||
}
|
||||
if(iq->minimisation_state == MINIMISE_STATE) {
|
||||
int qchaselabs = dname_count_labels(iq->qchase.qname);
|
||||
int labdiff = qchaselabs -
|
||||
dname_count_labels(iq->qinfo_out.qname);
|
||||
|
||||
iq->qinfo_out.qname = iq->qchase.qname;
|
||||
iq->qinfo_out.qname_len = iq->qchase.qname_len;
|
||||
iq->minimise_count++;
|
||||
iq->minimise_timeout_count = 0;
|
||||
|
||||
iter_dec_attempts(iq->dp, 1);
|
||||
|
||||
/* Limit number of iterations for QNAMEs with more
|
||||
* than MAX_MINIMISE_COUNT labels. Send first MINIMISE_ONE_LAB
|
||||
* labels of QNAME always individually.
|
||||
*/
|
||||
if(qchaselabs > MAX_MINIMISE_COUNT && labdiff > 1 &&
|
||||
iq->minimise_count > MINIMISE_ONE_LAB) {
|
||||
if(iq->minimise_count < MAX_MINIMISE_COUNT) {
|
||||
int multilabs = qchaselabs - 1 -
|
||||
MINIMISE_ONE_LAB;
|
||||
int extralabs = multilabs /
|
||||
MINIMISE_MULTIPLE_LABS;
|
||||
|
||||
if (MAX_MINIMISE_COUNT - iq->minimise_count >=
|
||||
multilabs % MINIMISE_MULTIPLE_LABS)
|
||||
/* Default behaviour is to add 1 label
|
||||
* every iteration. Therefore, decrement
|
||||
* the extralabs by 1 */
|
||||
extralabs--;
|
||||
if (extralabs < labdiff)
|
||||
labdiff -= extralabs;
|
||||
else
|
||||
labdiff = 1;
|
||||
}
|
||||
/* Last minimised iteration, send all labels with
|
||||
* QTYPE=NS */
|
||||
else
|
||||
labdiff = 1;
|
||||
}
|
||||
|
||||
if(labdiff > 1) {
|
||||
verbose(VERB_QUERY, "removing %d labels", labdiff-1);
|
||||
dname_remove_labels(&iq->qinfo_out.qname,
|
||||
&iq->qinfo_out.qname_len,
|
||||
labdiff-1);
|
||||
}
|
||||
if(labdiff < 1 || (labdiff < 2
|
||||
&& (iq->qchase.qtype == LDNS_RR_TYPE_DS
|
||||
|| iq->qchase.qtype == LDNS_RR_TYPE_A)))
|
||||
/* Stop minimising this query, resolve "as usual" */
|
||||
iq->minimisation_state = DONOT_MINIMISE_STATE;
|
||||
else if(!qstate->no_cache_lookup) {
|
||||
struct dns_msg* msg = dns_cache_lookup(qstate->env,
|
||||
iq->qinfo_out.qname, iq->qinfo_out.qname_len,
|
||||
iq->qinfo_out.qtype, iq->qinfo_out.qclass,
|
||||
qstate->query_flags, qstate->region,
|
||||
qstate->env->scratch);
|
||||
if(msg && msg->rep->an_numrrsets == 0
|
||||
&& FLAGS_GET_RCODE(msg->rep->flags) ==
|
||||
LDNS_RCODE_NOERROR)
|
||||
/* no need to send query if it is already
|
||||
* cached as NOERROR/NODATA */
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if(iq->minimisation_state == SKIP_MINIMISE_STATE) {
|
||||
if(iq->minimise_timeout_count < MAX_MINIMISE_TIMEOUT_COUNT)
|
||||
/* Do not increment qname, continue incrementing next
|
||||
* iteration */
|
||||
iq->minimisation_state = MINIMISE_STATE;
|
||||
else if(!qstate->env->cfg->qname_minimisation_strict)
|
||||
/* Too many time-outs detected for this QNAME and QTYPE.
|
||||
* We give up, disable QNAME minimisation. */
|
||||
iq->minimisation_state = DONOT_MINIMISE_STATE;
|
||||
}
|
||||
if(iq->minimisation_state == DONOT_MINIMISE_STATE)
|
||||
iq->qinfo_out = iq->qchase;
|
||||
|
||||
/* We have a valid target. */
|
||||
if(verbosity >= VERB_QUERY) {
|
||||
log_query_info(VERB_QUERY, "sending query:", &iq->qinfo_out);
|
||||
@@ -2197,12 +2398,13 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
* (blacklist nonempty) and no trust-anchors are configured
|
||||
* above the qname or on the first attempt when dnssec is on */
|
||||
EDNS_DO| ((iq->chase_to_rd||(iq->chase_flags&BIT_RD)!=0)&&
|
||||
!qstate->blacklist&&(!iter_indicates_dnssec_fwd(qstate->env,
|
||||
!qstate->blacklist&&(!iter_qname_indicates_dnssec(qstate->env,
|
||||
&iq->qinfo_out)||target->attempts==1)?0:BIT_CD),
|
||||
iq->dnssec_expected, iq->caps_fallback || is_caps_whitelisted(
|
||||
ie, iq), &target->addr, target->addrlen,
|
||||
iq->dp->name, iq->dp->namelen,
|
||||
(iq->dp->ssl_upstream || qstate->env->cfg->ssl_upstream), qstate);
|
||||
(iq->dp->ssl_upstream || qstate->env->cfg->ssl_upstream),
|
||||
target->tls_auth_name, qstate);
|
||||
if(!outq) {
|
||||
log_addr(VERB_DETAIL, "error sending query to auth server",
|
||||
&target->addr, target->addrlen);
|
||||
@@ -2271,9 +2473,10 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
}
|
||||
type = response_type_from_server(
|
||||
(int)((iq->chase_flags&BIT_RD) || iq->chase_to_rd),
|
||||
iq->response, &iq->qchase, iq->dp);
|
||||
iq->response, &iq->qinfo_out, iq->dp);
|
||||
iq->chase_to_rd = 0;
|
||||
if(type == RESPONSE_TYPE_REFERRAL && (iq->chase_flags&BIT_RD)) {
|
||||
if(type == RESPONSE_TYPE_REFERRAL && (iq->chase_flags&BIT_RD) &&
|
||||
!iq->auth_zone_response) {
|
||||
/* When forwarding (RD bit is set), we handle referrals
|
||||
* differently. No queries should be sent elsewhere */
|
||||
type = RESPONSE_TYPE_ANSWER;
|
||||
@@ -2567,15 +2770,18 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
/* set the current request's qname to the new value. */
|
||||
iq->qchase.qname = sname;
|
||||
iq->qchase.qname_len = snamelen;
|
||||
if (qstate->env->cfg->qname_minimisation)
|
||||
iq->minimisation_state = INIT_MINIMISE_STATE;
|
||||
/* Clear the query state, since this is a query restart. */
|
||||
iq->deleg_msg = NULL;
|
||||
iq->dp = NULL;
|
||||
iq->dsns_point = NULL;
|
||||
/* Note the query restart. */
|
||||
iq->query_restart_count++;
|
||||
iq->auth_zone_response = 0;
|
||||
iq->sent_count = 0;
|
||||
if(iq->minimisation_state != MINIMISE_STATE)
|
||||
/* Only count as query restart when it is not an extra
|
||||
* query as result of qname minimisation. */
|
||||
iq->query_restart_count++;
|
||||
if(qstate->env->cfg->qname_minimisation)
|
||||
iq->minimisation_state = INIT_MINIMISE_STATE;
|
||||
|
||||
/* stop current outstanding queries.
|
||||
* FIXME: should the outstanding queries be waited for and
|
||||
@@ -2645,6 +2851,25 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
if (qstate->env->cfg->qname_minimisation &&
|
||||
!qstate->env->cfg->qname_minimisation_strict)
|
||||
iq->minimisation_state = DONOT_MINIMISE_STATE;
|
||||
if(iq->auth_zone_response) {
|
||||
/* can we fallback? */
|
||||
iq->auth_zone_response = 0;
|
||||
if(!auth_zones_can_fallback(qstate->env->auth_zones,
|
||||
iq->dp->name, iq->dp->namelen, qstate->qinfo.qclass)) {
|
||||
verbose(VERB_ALGO, "auth zone response bad, and no"
|
||||
" fallback possible, servfail");
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
verbose(VERB_ALGO, "auth zone response was bad, "
|
||||
"fallback enabled");
|
||||
iq->auth_zone_avoid = 1;
|
||||
if(iq->dp->auth_dp) {
|
||||
/* we are using a dp for the auth zone, with no
|
||||
* nameservers, get one first */
|
||||
iq->dp = NULL;
|
||||
return next_state(iq, INIT_REQUEST_STATE);
|
||||
}
|
||||
}
|
||||
return next_state(iq, QUERYTARGETS_STATE);
|
||||
}
|
||||
|
||||
|
||||
@@ -387,6 +387,11 @@ struct iter_qstate {
|
||||
* Count number of time-outs. Used to prevent resolving failures when
|
||||
* the QNAME minimisation QTYPE is blocked. */
|
||||
int minimise_timeout_count;
|
||||
|
||||
/** True if the current response is from auth_zone */
|
||||
int auth_zone_response;
|
||||
/** True if the auth_zones should not be consulted for the query */
|
||||
int auth_zone_avoid;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
#include "services/localzone.h"
|
||||
#include "services/cache/rrset.h"
|
||||
#include "services/cache/infra.h"
|
||||
#include "services/authzone.h"
|
||||
#include "util/data/msgreply.h"
|
||||
#include "util/storage/slabhash.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
@@ -68,6 +69,8 @@ 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))
|
||||
return UB_INITFAIL;
|
||||
if(!ctx->env->msg_cache ||
|
||||
cfg->msg_cache_size != slabhash_get_size(ctx->env->msg_cache) ||
|
||||
cfg->msg_cache_slabs != ctx->env->msg_cache->size) {
|
||||
@@ -127,7 +130,7 @@ find_id(struct ub_ctx* ctx, int* id)
|
||||
|
||||
struct ctx_query*
|
||||
context_new(struct ub_ctx* ctx, const char* name, int rrtype, int rrclass,
|
||||
ub_callback_type cb, void* cbarg)
|
||||
ub_callback_type cb, ub_event_callback_type cb_event, void* cbarg)
|
||||
{
|
||||
struct ctx_query* q = (struct ctx_query*)calloc(1, sizeof(*q));
|
||||
if(!q) return NULL;
|
||||
@@ -139,8 +142,9 @@ context_new(struct ub_ctx* ctx, const char* name, int rrtype, int rrclass,
|
||||
}
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
q->node.key = &q->querynum;
|
||||
q->async = (cb != NULL);
|
||||
q->async = (cb != NULL || cb_event != NULL);
|
||||
q->cb = cb;
|
||||
q->cb_event = cb_event;
|
||||
q->cb_arg = cbarg;
|
||||
q->res = (struct ub_result*)calloc(1, sizeof(*q->res));
|
||||
if(!q->res) {
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#include "util/rbtree.h"
|
||||
#include "services/modstack.h"
|
||||
#include "libunbound/unbound.h"
|
||||
#include "libunbound/unbound-event.h"
|
||||
#include "util/data/packed_rrset.h"
|
||||
struct libworker;
|
||||
struct tube;
|
||||
@@ -148,8 +149,10 @@ struct ctx_query {
|
||||
/** was this query cancelled (for bg worker) */
|
||||
int cancelled;
|
||||
|
||||
/** for async query, the callback function */
|
||||
/** for async query, the callback function of type ub_callback_type */
|
||||
ub_callback_type cb;
|
||||
/** for event callbacks the type is ub_event_callback_type */
|
||||
ub_event_callback_type cb_event;
|
||||
/** for async query, the callback user arg */
|
||||
void* cb_arg;
|
||||
|
||||
@@ -238,11 +241,13 @@ void context_query_delete(struct ctx_query* q);
|
||||
* @param rrtype: type
|
||||
* @param rrclass: class
|
||||
* @param cb: callback for async, or NULL for sync.
|
||||
* @param cb_event: event callback for async, or NULL for sync.
|
||||
* @param cbarg: user arg for async queries.
|
||||
* @return new ctx_query or NULL for malloc failure.
|
||||
*/
|
||||
struct ctx_query* context_new(struct ub_ctx* ctx, const char* name, int rrtype,
|
||||
int rrclass, ub_callback_type cb, void* cbarg);
|
||||
int rrclass, ub_callback_type cb, ub_event_callback_type cb_event,
|
||||
void* cbarg);
|
||||
|
||||
/**
|
||||
* Get a new alloc. Creates a new one or uses a cached one.
|
||||
|
||||
+16
-4
@@ -62,6 +62,7 @@
|
||||
#include "services/localzone.h"
|
||||
#include "services/cache/infra.h"
|
||||
#include "services/cache/rrset.h"
|
||||
#include "services/authzone.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
#ifdef HAVE_PTHREAD
|
||||
#include <signal.h>
|
||||
@@ -88,6 +89,7 @@ static struct ub_ctx* ub_ctx_create_nopipe(void)
|
||||
WSADATA wsa_data;
|
||||
#endif
|
||||
|
||||
checklock_start();
|
||||
log_init(NULL, 0, NULL); /* logs to stderr */
|
||||
log_ident_set("libunbound");
|
||||
#ifdef USE_WINSOCK
|
||||
@@ -141,6 +143,16 @@ static struct ub_ctx* ub_ctx_create_nopipe(void)
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
ctx->env->auth_zones = auth_zones_create();
|
||||
if(!ctx->env->auth_zones) {
|
||||
edns_known_options_delete(ctx->env);
|
||||
config_delete(ctx->env->cfg);
|
||||
free(ctx->env);
|
||||
ub_randfree(ctx->seed_rnd);
|
||||
free(ctx);
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
ctx->env->alloc = &ctx->superalloc;
|
||||
ctx->env->worker = NULL;
|
||||
ctx->env->need_to_validate = 0;
|
||||
@@ -310,6 +322,7 @@ ub_ctx_delete(struct ub_ctx* ctx)
|
||||
infra_delete(ctx->env->infra_cache);
|
||||
config_delete(ctx->env->cfg);
|
||||
edns_known_options_delete(ctx->env);
|
||||
auth_zones_delete(ctx->env->auth_zones);
|
||||
free(ctx->env);
|
||||
}
|
||||
ub_randfree(ctx->seed_rnd);
|
||||
@@ -677,7 +690,7 @@ ub_resolve(struct ub_ctx* ctx, const char* name, int rrtype,
|
||||
}
|
||||
/* create new ctx_query and attempt to add to the list */
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
q = context_new(ctx, name, rrtype, rrclass, NULL, NULL);
|
||||
q = context_new(ctx, name, rrtype, rrclass, NULL, NULL, NULL);
|
||||
if(!q)
|
||||
return UB_NOMEM;
|
||||
/* become a resolver thread for a bit */
|
||||
@@ -734,8 +747,7 @@ ub_resolve_event(struct ub_ctx* ctx, const char* name, int rrtype,
|
||||
ub_comm_base_now(ctx->event_worker->base);
|
||||
|
||||
/* create new ctx_query and attempt to add to the list */
|
||||
q = context_new(ctx, name, rrtype, rrclass, (ub_callback_type)callback,
|
||||
mydata);
|
||||
q = context_new(ctx, name, rrtype, rrclass, NULL, callback, mydata);
|
||||
if(!q)
|
||||
return UB_NOMEM;
|
||||
|
||||
@@ -780,7 +792,7 @@ ub_resolve_async(struct ub_ctx* ctx, const char* name, int rrtype,
|
||||
}
|
||||
|
||||
/* create new ctx_query and attempt to add to the list */
|
||||
q = context_new(ctx, name, rrtype, rrclass, callback, mydata);
|
||||
q = context_new(ctx, name, rrtype, rrclass, callback, NULL, mydata);
|
||||
if(!q)
|
||||
return UB_NOMEM;
|
||||
|
||||
|
||||
+46
-28
@@ -55,6 +55,7 @@
|
||||
#include "services/localzone.h"
|
||||
#include "services/cache/rrset.h"
|
||||
#include "services/outbound_list.h"
|
||||
#include "services/authzone.h"
|
||||
#include "util/fptr_wlist.h"
|
||||
#include "util/module.h"
|
||||
#include "util/regional.h"
|
||||
@@ -157,8 +158,9 @@ libworker_setup(struct ub_ctx* ctx, int is_bg, struct ub_event_base* eb)
|
||||
hints_delete(w->env->hints);
|
||||
w->env->hints = NULL;
|
||||
}
|
||||
if(cfg->ssl_upstream) {
|
||||
w->sslctx = connect_sslctx_create(NULL, NULL, NULL);
|
||||
if(cfg->ssl_upstream || (cfg->tls_cert_bundle && cfg->tls_cert_bundle[0]) || cfg->tls_win_cert) {
|
||||
w->sslctx = connect_sslctx_create(NULL, NULL,
|
||||
cfg->tls_cert_bundle, cfg->tls_win_cert);
|
||||
if(!w->sslctx) {
|
||||
/* to make the setup fail after unlock */
|
||||
hints_delete(w->env->hints);
|
||||
@@ -214,6 +216,7 @@ libworker_setup(struct ub_ctx* ctx, int is_bg, struct ub_event_base* eb)
|
||||
libworker_delete(w);
|
||||
return NULL;
|
||||
}
|
||||
w->env->worker_base = w->base;
|
||||
if(!w->is_bg || w->is_bg_thread) {
|
||||
lock_basic_lock(&ctx->cfglock);
|
||||
}
|
||||
@@ -235,6 +238,7 @@ libworker_setup(struct ub_ctx* ctx, int is_bg, struct ub_event_base* eb)
|
||||
cfg->outgoing_tcp_mss, &libworker_alloc_cleanup, w,
|
||||
cfg->do_udp || cfg->udp_upstream_without_downstream, w->sslctx,
|
||||
cfg->delay_close, NULL);
|
||||
w->env->outnet = w->back;
|
||||
if(!w->is_bg || w->is_bg_thread) {
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
}
|
||||
@@ -361,6 +365,7 @@ libworker_dobg(void* arg)
|
||||
|
||||
/* cleanup */
|
||||
m = UB_LIBCMD_QUIT;
|
||||
w->want_quit = 1;
|
||||
tube_remove_bg_listen(w->ctx->qq_pipe);
|
||||
tube_remove_bg_write(w->ctx->rr_pipe);
|
||||
libworker_delete(w);
|
||||
@@ -419,25 +424,6 @@ int libworker_bg(struct ub_ctx* ctx)
|
||||
return UB_NOERROR;
|
||||
}
|
||||
|
||||
/** get msg reply struct (in temp region) */
|
||||
static struct reply_info*
|
||||
parse_reply(sldns_buffer* pkt, struct regional* region, struct query_info* qi)
|
||||
{
|
||||
struct reply_info* rep;
|
||||
struct msg_parse* msg;
|
||||
if(!(msg = regional_alloc(region, sizeof(*msg)))) {
|
||||
return NULL;
|
||||
}
|
||||
memset(msg, 0, sizeof(*msg));
|
||||
sldns_buffer_set_position(pkt, 0);
|
||||
if(parse_packet(pkt, msg, region) != 0)
|
||||
return 0;
|
||||
if(!parse_create_msg(pkt, msg, NULL, qi, &rep, region)) {
|
||||
return 0;
|
||||
}
|
||||
return rep;
|
||||
}
|
||||
|
||||
/** insert canonname */
|
||||
static int
|
||||
fill_canon(struct ub_result* res, uint8_t* s)
|
||||
@@ -511,7 +497,7 @@ libworker_enter_result(struct ub_result* res, sldns_buffer* buf,
|
||||
struct query_info rq;
|
||||
struct reply_info* rep;
|
||||
res->rcode = LDNS_RCODE_SERVFAIL;
|
||||
rep = parse_reply(buf, temp, &rq);
|
||||
rep = parse_reply_in_temp_region(buf, temp, &rq);
|
||||
if(!rep) {
|
||||
log_err("cannot parse buf");
|
||||
return; /* error parsing buf, or out of memory */
|
||||
@@ -527,7 +513,8 @@ libworker_enter_result(struct ub_result* res, sldns_buffer* buf,
|
||||
res->nxdomain = 1;
|
||||
if(msg_security == sec_status_secure)
|
||||
res->secure = 1;
|
||||
if(msg_security == sec_status_bogus)
|
||||
if(msg_security == sec_status_bogus ||
|
||||
msg_security == sec_status_secure_sentinel_fail)
|
||||
res->bogus = 1;
|
||||
}
|
||||
|
||||
@@ -621,6 +608,15 @@ int libworker_fg(struct ub_ctx* ctx, struct ctx_query* q)
|
||||
free(qinfo.qname);
|
||||
return UB_NOERROR;
|
||||
}
|
||||
if(ctx->env->auth_zones && auth_zones_answer(ctx->env->auth_zones,
|
||||
w->env, &qinfo, &edns, w->back->udp_buff, w->env->scratch)) {
|
||||
regional_free_all(w->env->scratch);
|
||||
libworker_fillup_fg(q, LDNS_RCODE_NOERROR,
|
||||
w->back->udp_buff, sec_status_insecure, NULL);
|
||||
libworker_delete(w);
|
||||
free(qinfo.qname);
|
||||
return UB_NOERROR;
|
||||
}
|
||||
/* process new query */
|
||||
if(!mesh_new_callback(w->env->mesh, &qinfo, qflags, &edns,
|
||||
w->back->udp_buff, qid, libworker_fg_done_cb, q)) {
|
||||
@@ -641,7 +637,7 @@ libworker_event_done_cb(void* arg, int rcode, sldns_buffer* buf,
|
||||
enum sec_status s, char* why_bogus)
|
||||
{
|
||||
struct ctx_query* q = (struct ctx_query*)arg;
|
||||
ub_event_callback_type cb = (ub_event_callback_type)q->cb;
|
||||
ub_event_callback_type cb = q->cb_event;
|
||||
void* cb_arg = q->cb_arg;
|
||||
int cancelled = q->cancelled;
|
||||
|
||||
@@ -691,6 +687,14 @@ int libworker_attach_mesh(struct ub_ctx* ctx, struct ctx_query* q,
|
||||
w->back->udp_buff, sec_status_insecure, NULL);
|
||||
return UB_NOERROR;
|
||||
}
|
||||
if(ctx->env->auth_zones && auth_zones_answer(ctx->env->auth_zones,
|
||||
w->env, &qinfo, &edns, w->back->udp_buff, w->env->scratch)) {
|
||||
regional_free_all(w->env->scratch);
|
||||
free(qinfo.qname);
|
||||
libworker_event_done_cb(q, LDNS_RCODE_NOERROR,
|
||||
w->back->udp_buff, sec_status_insecure, NULL);
|
||||
return UB_NOERROR;
|
||||
}
|
||||
/* process new query */
|
||||
if(async_id)
|
||||
*async_id = q->querynum;
|
||||
@@ -711,6 +715,10 @@ add_bg_result(struct libworker* w, struct ctx_query* q, sldns_buffer* pkt,
|
||||
uint8_t* msg = NULL;
|
||||
uint32_t len = 0;
|
||||
|
||||
if(w->want_quit) {
|
||||
context_query_delete(q);
|
||||
return;
|
||||
}
|
||||
/* serialize and delete unneeded q */
|
||||
if(w->is_bg_thread) {
|
||||
lock_basic_lock(&w->ctx->cfglock);
|
||||
@@ -812,6 +820,14 @@ handle_newq(struct libworker* w, uint8_t* buf, uint32_t len)
|
||||
free(qinfo.qname);
|
||||
return;
|
||||
}
|
||||
if(w->ctx->env->auth_zones && auth_zones_answer(w->ctx->env->auth_zones,
|
||||
w->env, &qinfo, &edns, w->back->udp_buff, w->env->scratch)) {
|
||||
regional_free_all(w->env->scratch);
|
||||
q->msg_security = sec_status_insecure;
|
||||
add_bg_result(w, q, w->back->udp_buff, UB_NOERROR, NULL);
|
||||
free(qinfo.qname);
|
||||
return;
|
||||
}
|
||||
q->w = w;
|
||||
/* process new query */
|
||||
if(!mesh_new_callback(w->env->mesh, &qinfo, qflags, &edns,
|
||||
@@ -831,7 +847,8 @@ void libworker_alloc_cleanup(void* arg)
|
||||
struct outbound_entry* libworker_send_query(struct query_info* qinfo,
|
||||
uint16_t flags, int dnssec, int want_dnssec, int nocaps,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
|
||||
size_t zonelen, int ssl_upstream, struct module_qstate* q)
|
||||
size_t zonelen, int ssl_upstream, char* tls_auth_name,
|
||||
struct module_qstate* q)
|
||||
{
|
||||
struct libworker* w = (struct libworker*)q->env->worker;
|
||||
struct outbound_entry* e = (struct outbound_entry*)regional_alloc(
|
||||
@@ -841,8 +858,8 @@ struct outbound_entry* libworker_send_query(struct query_info* qinfo,
|
||||
e->qstate = q;
|
||||
e->qsent = outnet_serviced_query(w->back, qinfo, flags, dnssec,
|
||||
want_dnssec, nocaps, q->env->cfg->tcp_upstream, ssl_upstream,
|
||||
addr, addrlen, zone, zonelen, q, libworker_handle_service_reply,
|
||||
e, w->back->udp_buff, q->env);
|
||||
tls_auth_name, addr, addrlen, zone, zonelen, q,
|
||||
libworker_handle_service_reply, e, w->back->udp_buff, q->env);
|
||||
if(!e->qsent) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -962,7 +979,8 @@ struct outbound_entry* worker_send_query(struct query_info* ATTR_UNUSED(qinfo),
|
||||
int ATTR_UNUSED(want_dnssec), int ATTR_UNUSED(nocaps),
|
||||
struct sockaddr_storage* ATTR_UNUSED(addr), socklen_t ATTR_UNUSED(addrlen),
|
||||
uint8_t* ATTR_UNUSED(zone), size_t ATTR_UNUSED(zonelen),
|
||||
int ATTR_UNUSED(ssl_upstream), struct module_qstate* ATTR_UNUSED(q))
|
||||
int ATTR_UNUSED(ssl_upstream), char* ATTR_UNUSED(tls_auth_name),
|
||||
struct module_qstate* ATTR_UNUSED(q))
|
||||
{
|
||||
log_assert(0);
|
||||
return 0;
|
||||
|
||||
@@ -75,6 +75,8 @@ struct libworker {
|
||||
int is_bg;
|
||||
/** is this a bg worker that is threaded (not forked)? */
|
||||
int is_bg_thread;
|
||||
/** want to quit, stop handling new content */
|
||||
int want_quit;
|
||||
|
||||
/** copy of the module environment with worker local entries. */
|
||||
struct module_env* env;
|
||||
|
||||
@@ -747,6 +747,16 @@ struct ub_server_stats {
|
||||
long long num_query_dnscrypt_replay;
|
||||
/** number of dnscrypt nonces cache entries */
|
||||
long long nonce_cache_count;
|
||||
/** number of queries for unbound's auth_zones, upstream query */
|
||||
long long num_query_authzone_up;
|
||||
/** number of queries for unbound's auth_zones, downstream answers */
|
||||
long long num_query_authzone_down;
|
||||
/** number of times neg cache records were used to generate NOERROR
|
||||
* responses. */
|
||||
long long num_neg_cache_noerror;
|
||||
/** number of times neg cache records were used to generate NXDOMAIN
|
||||
* responses. */
|
||||
long long num_neg_cache_nxdomain;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
+8
-2
@@ -63,6 +63,8 @@ struct query_info;
|
||||
* @param zone: delegation point name.
|
||||
* @param zonelen: length of zone name wireformat dname.
|
||||
* @param ssl_upstream: use SSL for upstream queries.
|
||||
* @param tls_auth_name: if ssl_upstream, use this name with TLS
|
||||
* authentication.
|
||||
* @param q: wich query state to reactivate upon return.
|
||||
* @return: false on failure (memory or socket related). no query was
|
||||
* sent.
|
||||
@@ -70,7 +72,8 @@ struct query_info;
|
||||
struct outbound_entry* libworker_send_query(struct query_info* qinfo,
|
||||
uint16_t flags, int dnssec, int want_dnssec, int nocaps,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
|
||||
size_t zonelen, int ssl_upstream, struct module_qstate* q);
|
||||
size_t zonelen, int ssl_upstream, char* tls_auth_name,
|
||||
struct module_qstate* q);
|
||||
|
||||
/** process incoming replies from the network */
|
||||
int libworker_handle_reply(struct comm_point* c, void* arg, int error,
|
||||
@@ -115,6 +118,8 @@ void worker_sighandler(int sig, void* arg);
|
||||
* @param zone: wireformat dname of the zone.
|
||||
* @param zonelen: length of zone name.
|
||||
* @param ssl_upstream: use SSL for upstream queries.
|
||||
* @param tls_auth_name: if ssl_upstream, use this name with TLS
|
||||
* authentication.
|
||||
* @param q: wich query state to reactivate upon return.
|
||||
* @return: false on failure (memory or socket related). no query was
|
||||
* sent.
|
||||
@@ -122,7 +127,8 @@ void worker_sighandler(int sig, void* arg);
|
||||
struct outbound_entry* worker_send_query(struct query_info* qinfo,
|
||||
uint16_t flags, int dnssec, int want_dnssec, int nocaps,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
|
||||
size_t zonelen, int ssl_upstream, struct module_qstate* q);
|
||||
size_t zonelen, int ssl_upstream, char* tls_auth_name,
|
||||
struct module_qstate* q);
|
||||
|
||||
/**
|
||||
* process control messages from the main thread. Frees the control
|
||||
|
||||
+1
-1
@@ -272,7 +272,7 @@ if [ "$DOWIN" = "yes" ]; then
|
||||
if test -n "$WINEXPAT"; then
|
||||
info "Cross compile $WINEXPAT"
|
||||
info "wxp: tar unpack"
|
||||
(cd ..; gzip -cd $WINEXPAT) | tar xf - || error_cleanup "tar unpack of $WINEXPAT failed"
|
||||
(cd ..; bzip2 -cd $WINEXPAT) | tar xf - || error_cleanup "tar unpack of $WINEXPAT failed"
|
||||
wxpinstall="`pwd`/wxpinstall"
|
||||
cd expat-* || error_cleanup "no expat-X dir in tarball"
|
||||
info "wxp: configure"
|
||||
|
||||
@@ -574,7 +574,7 @@ struct module_env {
|
||||
struct outbound_entry* (*send_query)(struct query_info* qinfo,
|
||||
uint16_t flags, int dnssec, int want_dnssec, int nocaps,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
uint8_t* zone, size_t zonelen, int ssl_upstream,
|
||||
uint8_t* zone, size_t zonelen, int ssl_upstream, char* tls_auth_name,
|
||||
struct module_qstate* q);
|
||||
void (*detach_subs)(struct module_qstate* qstate);
|
||||
int (*attach_sub)(struct module_qstate* qstate,
|
||||
@@ -883,7 +883,7 @@ struct config_file {
|
||||
struct config_strlist* local_zones_nodefault;
|
||||
struct config_strlist* local_data;
|
||||
int remote_control_enable;
|
||||
struct config_strlist* control_ifs;
|
||||
struct config_strlist_head control_ifs;
|
||||
int control_port;
|
||||
char* server_key_file;
|
||||
char* server_cert_file;
|
||||
|
||||
+4296
-95
File diff suppressed because it is too large
Load Diff
+450
-6
@@ -45,20 +45,42 @@
|
||||
#define SERVICES_AUTHZONE_H
|
||||
#include "util/rbtree.h"
|
||||
#include "util/locks.h"
|
||||
#include "services/mesh.h"
|
||||
struct ub_packed_rrset_key;
|
||||
struct regional;
|
||||
struct config_file;
|
||||
struct config_auth;
|
||||
struct query_info;
|
||||
struct dns_msg;
|
||||
struct edns_data;
|
||||
struct module_env;
|
||||
struct worker;
|
||||
struct comm_point;
|
||||
struct comm_timer;
|
||||
struct comm_reply;
|
||||
struct auth_rrset;
|
||||
struct auth_nextprobe;
|
||||
struct auth_probe;
|
||||
struct auth_transfer;
|
||||
struct auth_master;
|
||||
struct auth_chunk;
|
||||
|
||||
/**
|
||||
* Authoritative zones, shared.
|
||||
*/
|
||||
struct auth_zones {
|
||||
/** lock on the authzone tree */
|
||||
/** lock on the authzone trees */
|
||||
lock_rw_type lock;
|
||||
/** rbtree of struct auth_zone */
|
||||
rbtree_type ztree;
|
||||
/** rbtree of struct auth_xfer */
|
||||
rbtree_type xtree;
|
||||
/** do we have downstream enabled */
|
||||
int have_downstream;
|
||||
/** number of queries upstream */
|
||||
size_t num_query_up;
|
||||
/** number of queries downstream */
|
||||
size_t num_query_down;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -89,10 +111,25 @@ struct auth_zone {
|
||||
* rbtree of struct auth_data */
|
||||
rbtree_type data;
|
||||
|
||||
/* zonefile name (or NULL for no zonefile) */
|
||||
/** zonefile name (or NULL for no zonefile) */
|
||||
char* zonefile;
|
||||
/* fallback to the internet on failure or ttl-expiry of auth zone */
|
||||
/** fallback to the internet on failure or ttl-expiry of auth zone */
|
||||
int fallback_enabled;
|
||||
/** the zone has expired (enabled by the xfer worker), fallback
|
||||
* happens if that option is enabled. */
|
||||
int zone_expired;
|
||||
/** zone is a slave zone (it has masters) */
|
||||
int zone_is_slave;
|
||||
/** for downstream: this zone answers queries towards the downstream
|
||||
* clients */
|
||||
int for_downstream;
|
||||
/** for upstream: this zone answers queries that unbound intends to
|
||||
* send upstream. */
|
||||
int for_upstream;
|
||||
/** zone has been deleted */
|
||||
int zone_deleted;
|
||||
/** deletelist pointer, unused normally except during delete */
|
||||
struct auth_zone* delete_next;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -127,6 +164,282 @@ struct auth_rrset {
|
||||
struct packed_rrset_data* data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Authoritative zone transfer structure.
|
||||
* Create and destroy needs the auth_zones* biglock.
|
||||
* The structure consists of different tasks. Each can be unowned (-1) or
|
||||
* owner by a worker (worker-num). A worker can pick up a task and then do
|
||||
* it. This means the events (timeouts, sockets) are for that worker.
|
||||
*
|
||||
* (move this to tasks).
|
||||
* They don't have locks themselves, the worker (that owns it) uses it,
|
||||
* also as part of callbacks, hence it has separate zonename pointers for
|
||||
* lookup in the main zonetree. If the zone has no transfers, this
|
||||
* structure is not created.
|
||||
*/
|
||||
struct auth_xfer {
|
||||
/** rbtree node, key is name and class */
|
||||
rbnode_type node;
|
||||
|
||||
/** lock on this structure, and on the workernum elements of the
|
||||
* tasks. First hold the tree-lock in auth_zones, find the auth_xfer,
|
||||
* lock this lock. Then a worker can reassign itself to fill up
|
||||
* one of the tasks.
|
||||
* Once it has the task assigned to it, the worker can access the
|
||||
* other elements of the task structure without a lock, because that
|
||||
* is necessary for the eventloop and callbacks from that. */
|
||||
lock_basic_type lock;
|
||||
|
||||
/** zone name, in uncompressed wireformat */
|
||||
uint8_t* name;
|
||||
/** length of zone name */
|
||||
size_t namelen;
|
||||
/** number of labels in zone name */
|
||||
int namelabs;
|
||||
/** the class of this zone, in host byteorder.
|
||||
* uses 'dclass' to not conflict with c++ keyword class. */
|
||||
uint16_t dclass;
|
||||
|
||||
/** task to wait for next-probe-timeout,
|
||||
* once timeouted, see if a SOA probe is needed, or already
|
||||
* in progress */
|
||||
struct auth_nextprobe* task_nextprobe;
|
||||
|
||||
/** task for SOA probe. Check if the zone can be updated */
|
||||
struct auth_probe* task_probe;
|
||||
|
||||
/** Task for transfer. Transferring and updating the zone. This
|
||||
* includes trying (potentially) several upstream masters. Downloading
|
||||
* and storing the zone */
|
||||
struct auth_transfer* task_transfer;
|
||||
|
||||
/** a notify was received, but a zone transfer or probe was already
|
||||
* acted on.
|
||||
* However, the zone transfer could signal a newer serial number.
|
||||
* The serial number of that notify is saved below. The transfer and
|
||||
* probe tasks should check this once done to see if they need to
|
||||
* restart the transfer task for the newer notify serial.
|
||||
* Hold the lock to access this member (and the serial).
|
||||
*/
|
||||
int notify_received;
|
||||
/** true if the notify_received has a serial number */
|
||||
int notify_has_serial;
|
||||
/** serial number of the notify */
|
||||
uint32_t notify_serial;
|
||||
/** the list of masters for checking notifies. This list is
|
||||
* empty on start, and a copy of the list from the probe_task when
|
||||
* it is done looking them up. */
|
||||
struct auth_master* allow_notify_list;
|
||||
|
||||
/* protected by the lock on the structure, information about
|
||||
* the loaded authority zone. */
|
||||
/** is the zone currently considered expired? after expiry also older
|
||||
* serial numbers are allowed (not just newer) */
|
||||
int zone_expired;
|
||||
/** do we have a zone (if 0, no zone data at all) */
|
||||
int have_zone;
|
||||
|
||||
/** current serial (from SOA), if we have no zone, 0 */
|
||||
uint32_t serial;
|
||||
/** retry time (from SOA), time to wait with next_probe
|
||||
* if no master responds */
|
||||
time_t retry;
|
||||
/** refresh time (from SOA), time to wait with next_probe
|
||||
* if everything is fine */
|
||||
time_t refresh;
|
||||
/** expiry time (from SOA), time until zone data is not considered
|
||||
* valid any more, if no master responds within this time, either
|
||||
* with the current zone or a new zone. */
|
||||
time_t expiry;
|
||||
|
||||
/** zone lease start time (start+expiry is expiration time).
|
||||
* this is renewed every SOA probe and transfer. On zone load
|
||||
* from zonefile it is also set (with probe set soon to check) */
|
||||
time_t lease_time;
|
||||
};
|
||||
|
||||
/**
|
||||
* The next probe task.
|
||||
* This task consists of waiting for the probetimeout. It is a task because
|
||||
* it needs an event in the eventtable. Once the timeout has passed, that
|
||||
* worker can (potentially) become the auth_probe worker, or if another worker
|
||||
* is already doing that, do nothing. Tasks becomes unowned.
|
||||
* The probe worker, if it detects nothing has to be done picks up this task,
|
||||
* if unowned.
|
||||
*/
|
||||
struct auth_nextprobe {
|
||||
/* Worker pointer. NULL means unowned. */
|
||||
struct worker* worker;
|
||||
/* module env for this task */
|
||||
struct module_env* env;
|
||||
|
||||
/** increasing backoff for failures */
|
||||
time_t backoff;
|
||||
/** Timeout for next probe (for SOA) */
|
||||
time_t next_probe;
|
||||
/** timeout callback for next_probe or expiry(if that is sooner).
|
||||
* it is on the worker's event_base */
|
||||
struct comm_timer* timer;
|
||||
};
|
||||
|
||||
/**
|
||||
* The probe task.
|
||||
* Send a SOA UDP query to see if the zone needs to be updated (or similar,
|
||||
* potential, HTTP probe query) and check serial number.
|
||||
* If yes, start the auth_transfer task. If no, make sure auth_nextprobe
|
||||
* timeout wait task is running.
|
||||
* Needs to be a task, because the UDP query needs an event entry.
|
||||
* This task could also be started by eg. a NOTIFY being received, even though
|
||||
* another worker is performing the nextprobe task (and that worker keeps
|
||||
* waiting uninterrupted).
|
||||
*/
|
||||
struct auth_probe {
|
||||
/* Worker pointer. NULL means unowned. */
|
||||
struct worker* worker;
|
||||
/* module env for this task */
|
||||
struct module_env* env;
|
||||
|
||||
/** list of upstream masters for this zone, from config */
|
||||
struct auth_master* masters;
|
||||
|
||||
/** for the hostname lookups, which master is current */
|
||||
struct auth_master* lookup_target;
|
||||
/** are we looking up A or AAAA, first A, then AAAA (if ip6 enabled) */
|
||||
int lookup_aaaa;
|
||||
/** we only want to do lookups for making config work (for notify),
|
||||
* don't proceed with UDP SOA probe queries */
|
||||
int only_lookup;
|
||||
|
||||
/** once notified, or the timeout has been reached. a scan starts. */
|
||||
/** the scan specific target (notify source), or NULL if none */
|
||||
struct auth_master* scan_specific;
|
||||
/** scan tries all the upstream masters. the scan current target.
|
||||
* or NULL if not working on sequential scan */
|
||||
struct auth_master* scan_target;
|
||||
/** if not NULL, the specific addr for the current master */
|
||||
struct auth_addr* scan_addr;
|
||||
|
||||
/** dns id of packet in flight */
|
||||
uint16_t id;
|
||||
/** the SOA probe udp event.
|
||||
* on the workers event base. */
|
||||
struct comm_point* cp;
|
||||
/** timeout for packets.
|
||||
* on the workers event base. */
|
||||
struct comm_timer* timer;
|
||||
/** timeout in msec */
|
||||
int timeout;
|
||||
};
|
||||
|
||||
/**
|
||||
* The transfer task.
|
||||
* Once done, make sure the nextprobe waiting task is running, whether done
|
||||
* with failure or success. If failure, use shorter timeout for wait time.
|
||||
*/
|
||||
struct auth_transfer {
|
||||
/* Worker pointer. NULL means unowned. */
|
||||
struct worker* worker;
|
||||
/* module env for this task */
|
||||
struct module_env* env;
|
||||
|
||||
/** xfer data that has been transferred, the data is applied
|
||||
* once the transfer has completed correctly */
|
||||
struct auth_chunk* chunks_first;
|
||||
/** last element in chunks list (to append new data at the end) */
|
||||
struct auth_chunk* chunks_last;
|
||||
|
||||
/** list of upstream masters for this zone, from config */
|
||||
struct auth_master* masters;
|
||||
|
||||
/** for the hostname lookups, which master is current */
|
||||
struct auth_master* lookup_target;
|
||||
/** are we looking up A or AAAA, first A, then AAAA (if ip6 enabled) */
|
||||
int lookup_aaaa;
|
||||
|
||||
/** once notified, or the timeout has been reached. a scan starts. */
|
||||
/** the scan specific target (notify source), or NULL if none */
|
||||
struct auth_master* scan_specific;
|
||||
/** scan tries all the upstream masters. the scan current target.
|
||||
* or NULL if not working on sequential scan */
|
||||
struct auth_master* scan_target;
|
||||
/** what address we are scanning for the master, or NULL if the
|
||||
* master is in IP format itself */
|
||||
struct auth_addr* scan_addr;
|
||||
/** the zone transfer in progress (or NULL if in scan). It is
|
||||
* from this master */
|
||||
struct auth_master* master;
|
||||
|
||||
/** failed ixfr transfer, retry with axfr (to the current master),
|
||||
* the IXFR was 'REFUSED', 'SERVFAIL', 'NOTIMPL' or the contents of
|
||||
* the IXFR did not apply cleanly (out of sync, delete of nonexistent
|
||||
* data or add of duplicate data). Flag is cleared once the retry
|
||||
* with axfr is done. */
|
||||
int ixfr_fail;
|
||||
/** we are doing IXFR right now */
|
||||
int on_ixfr;
|
||||
/** did we detect the current AXFR/IXFR serial number yet, 0 not yet,
|
||||
* 1 we saw the first, 2 we saw the second, 3 must be last SOA in xfr*/
|
||||
int got_xfr_serial;
|
||||
/** number of RRs scanned for AXFR/IXFR detection */
|
||||
size_t rr_scan_num;
|
||||
/** we are doing an IXFR but we detected an AXFR contents */
|
||||
int on_ixfr_is_axfr;
|
||||
/** the serial number for the current AXFR/IXFR incoming reply,
|
||||
* for IXFR, the outermost SOA records serial */
|
||||
uint32_t incoming_xfr_serial;
|
||||
|
||||
/** dns id of AXFR query */
|
||||
uint16_t id;
|
||||
/** the transfer (TCP) to the master.
|
||||
* on the workers event base. */
|
||||
struct comm_point* cp;
|
||||
};
|
||||
|
||||
/** list of addresses */
|
||||
struct auth_addr {
|
||||
/** next in list */
|
||||
struct auth_addr* next;
|
||||
/** IP address */
|
||||
struct sockaddr_storage addr;
|
||||
/** addr length */
|
||||
socklen_t addrlen;
|
||||
};
|
||||
|
||||
/** auth zone master upstream, and the config settings for it */
|
||||
struct auth_master {
|
||||
/** next master in list */
|
||||
struct auth_master* next;
|
||||
/** master IP address (and port), or hostname, string */
|
||||
char* host;
|
||||
/** for http, filename */
|
||||
char* file;
|
||||
/** use HTTP for this master */
|
||||
int http;
|
||||
/** use IXFR for this master */
|
||||
int ixfr;
|
||||
/** this is an allow notify member, the master can send notifies
|
||||
* to us, but we don't send SOA probes, or zone transfer from it */
|
||||
int allow_notify;
|
||||
/** use ssl for channel */
|
||||
int ssl;
|
||||
/** the port number (for urls) */
|
||||
int port;
|
||||
/** if the host is a hostname, the list of resolved addrs, if any*/
|
||||
struct auth_addr* list;
|
||||
};
|
||||
|
||||
/** auth zone master zone transfer data chunk */
|
||||
struct auth_chunk {
|
||||
/** next chunk in list */
|
||||
struct auth_chunk* next;
|
||||
/** the data from this chunk, this is what was received.
|
||||
* for an IXFR that means results from comm_net tcp actions,
|
||||
* packets. also for an AXFR. For HTTP a zonefile chunk. */
|
||||
uint8_t* data;
|
||||
/** length of allocated data */
|
||||
size_t len;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create auth zones structure
|
||||
*/
|
||||
@@ -134,8 +447,27 @@ struct auth_zones* auth_zones_create(void);
|
||||
|
||||
/**
|
||||
* Apply configuration to auth zones. Reads zonefiles.
|
||||
* @param az: auth zones structure
|
||||
* @param cfg: config to apply.
|
||||
* @param setup: if true, also sets up values in the auth zones structure
|
||||
* @return false on failure.
|
||||
*/
|
||||
int auth_zones_apply_config(struct auth_zones* az, struct config_file* cfg);
|
||||
int auth_zones_apply_cfg(struct auth_zones* az, struct config_file* cfg,
|
||||
int setup);
|
||||
|
||||
/** initial pick up of worker timeouts, ties events to worker event loop
|
||||
* @param az: auth zones structure
|
||||
* @param env: worker env, of first worker that receives the events (if any)
|
||||
* in its eventloop.
|
||||
*/
|
||||
void auth_xfer_pickup_initial(struct auth_zones* az, struct module_env* env);
|
||||
|
||||
/**
|
||||
* Cleanup auth zones. This removes all events from event bases.
|
||||
* Stops the xfr tasks. But leaves zone data.
|
||||
* @param az: auth zones structure.
|
||||
*/
|
||||
void auth_zones_cleanup(struct auth_zones* az);
|
||||
|
||||
/**
|
||||
* Delete auth zones structure
|
||||
@@ -170,21 +502,41 @@ int auth_zones_lookup(struct auth_zones* az, struct query_info* qinfo,
|
||||
struct regional* region, struct dns_msg** msg, int* fallback,
|
||||
uint8_t* dp_nm, size_t dp_nmlen);
|
||||
|
||||
/**
|
||||
* Answer query from auth zone. Create authoritative answer.
|
||||
* @param az: auth zones structure.
|
||||
* @param env: the module environment.
|
||||
* @param qinfo: query info (parsed).
|
||||
* @param edns: edns info (parsed).
|
||||
* @param buf: buffer with query ID and flags, also for reply.
|
||||
* @param temp: temporary storage region.
|
||||
* @return false if not answered
|
||||
*/
|
||||
int auth_zones_answer(struct auth_zones* az, struct module_env* env,
|
||||
struct query_info* qinfo, struct edns_data* edns, struct sldns_buffer* buf,
|
||||
struct regional* temp);
|
||||
|
||||
/**
|
||||
* Find the auth zone that is above the given qname.
|
||||
* Return NULL when there is no auth_zone above the give name, otherwise
|
||||
* returns the closest auth_zone above the qname that pertains to it.
|
||||
* @param az: auth zones structure.
|
||||
* @param qinfo: query info to lookup.
|
||||
* @param name: query to look up for.
|
||||
* @param name_len: length of name.
|
||||
* @param dclass: class of zone to find.
|
||||
* @return NULL or auth_zone that pertains to the query.
|
||||
*/
|
||||
struct auth_zone* auth_zones_find_zone(struct auth_zones* az,
|
||||
struct query_info* qinfo);
|
||||
uint8_t* name, size_t name_len, uint16_t dclass);
|
||||
|
||||
/** find an auth zone by name (exact match by name or NULL returned) */
|
||||
struct auth_zone* auth_zone_find(struct auth_zones* az, uint8_t* nm,
|
||||
size_t nmlen, uint16_t dclass);
|
||||
|
||||
/** find an xfer zone by name (exact match by name or NULL returned) */
|
||||
struct auth_xfer* auth_xfer_find(struct auth_zones* az, uint8_t* nm,
|
||||
size_t nmlen, uint16_t dclass);
|
||||
|
||||
/** create an auth zone. returns wrlocked zone. caller must have wrlock
|
||||
* on az. returns NULL on malloc failure */
|
||||
struct auth_zone* auth_zone_create(struct auth_zones* az, uint8_t* nm,
|
||||
@@ -197,13 +549,105 @@ int auth_zone_set_zonefile(struct auth_zone* z, char* zonefile);
|
||||
* fallbackstr is "yes" or "no". false on parse failure. */
|
||||
int auth_zone_set_fallback(struct auth_zone* z, char* fallbackstr);
|
||||
|
||||
/** see if the auth zone for the name can fallback
|
||||
* @param az: auth zones
|
||||
* @param nm: name of delegation point.
|
||||
* @param nmlen: length of nm.
|
||||
* @param dclass: class of zone to look for.
|
||||
* @return true if fallback_enabled is true. false if not.
|
||||
* if the zone does not exist, fallback is true (more lenient)
|
||||
* also true if zone does not do upstream requests.
|
||||
*/
|
||||
int auth_zones_can_fallback(struct auth_zones* az, uint8_t* nm, size_t nmlen,
|
||||
uint16_t dclass);
|
||||
|
||||
/** process notify for auth zones.
|
||||
* first checks the access list. Then processes the notify. This starts
|
||||
* the probe sequence or it notes the serial number (if any)
|
||||
* @param az: auth zones structure.
|
||||
* @param env: module env of the worker that is handling the notify. it will
|
||||
* pick up the task probe (or transfer), unless already in progress by
|
||||
* another worker.
|
||||
* @param nm: name of the zone. Uncompressed. from query.
|
||||
* @param nmlen: length of name.
|
||||
* @param dclass: class of zone.
|
||||
* @param addr: source address of notify
|
||||
* @param addrlen: length of addr.
|
||||
* @param has_serial: if true, the notify has a serial attached.
|
||||
* @param serial: the serial number, if has_serial is true.
|
||||
* @param refused: is set to true on failure to note refused access.
|
||||
* @return fail on failures (refused is false) and when access is
|
||||
* denied (refused is true). True when processed.
|
||||
*/
|
||||
int auth_zones_notify(struct auth_zones* az, struct module_env* env,
|
||||
uint8_t* nm, size_t nmlen, uint16_t dclass,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, int has_serial,
|
||||
uint32_t serial, int* refused);
|
||||
|
||||
/** process notify packet and read serial number from SOA.
|
||||
* returns 0 if no soa record in the notify */
|
||||
int auth_zone_parse_notify_serial(struct sldns_buffer* pkt, uint32_t *serial);
|
||||
|
||||
/** read auth zone from zonefile. caller must lock zone. false on failure */
|
||||
int auth_zone_read_zonefile(struct auth_zone* z);
|
||||
|
||||
/** find serial number of zone or false if none (no SOA record) */
|
||||
int auth_zone_get_serial(struct auth_zone* z, uint32_t* serial);
|
||||
|
||||
/** compare auth_zones for sorted rbtree */
|
||||
int auth_zone_cmp(const void* z1, const void* z2);
|
||||
|
||||
/** compare auth_data for sorted rbtree */
|
||||
int auth_data_cmp(const void* z1, const void* z2);
|
||||
|
||||
/** compare auth_xfer for sorted rbtree */
|
||||
int auth_xfer_cmp(const void* z1, const void* z2);
|
||||
|
||||
/** Create auth_xfer structure.
|
||||
* Caller must have wrlock on az. Returns locked xfer zone.
|
||||
* @param az: zones structure.
|
||||
* @param z: zone with name and class
|
||||
* @return xfer zone or NULL
|
||||
*/
|
||||
struct auth_xfer* auth_xfer_create(struct auth_zones* az, struct auth_zone* z);
|
||||
|
||||
/**
|
||||
* Set masters in auth xfer structure from config.
|
||||
* @param list: pointer to start of list. The malloced list is returned here.
|
||||
* @param c: the config items to copy over.
|
||||
* @param with_http: if true, http urls are also included, before the masters.
|
||||
* @return false on failure.
|
||||
*/
|
||||
int xfer_set_masters(struct auth_master** list, struct config_auth* c,
|
||||
int with_http);
|
||||
|
||||
/** xfer nextprobe timeout callback, this is part of task_nextprobe */
|
||||
void auth_xfer_timer(void* arg);
|
||||
|
||||
/** callback for commpoint udp replies to task_probe */
|
||||
int auth_xfer_probe_udp_callback(struct comm_point* c, void* arg, int err,
|
||||
struct comm_reply* repinfo);
|
||||
/** callback for task_transfer tcp connections */
|
||||
int auth_xfer_transfer_tcp_callback(struct comm_point* c, void* arg, int err,
|
||||
struct comm_reply* repinfo);
|
||||
/** callback for task_transfer http connections */
|
||||
int auth_xfer_transfer_http_callback(struct comm_point* c, void* arg, int err,
|
||||
struct comm_reply* repinfo);
|
||||
/** xfer probe timeout callback, part of task_probe */
|
||||
void auth_xfer_probe_timer_callback(void* arg);
|
||||
/** mesh callback for task_probe on lookup of host names */
|
||||
void auth_xfer_probe_lookup_callback(void* arg, int rcode,
|
||||
struct sldns_buffer* buf, enum sec_status sec, char* why_bogus);
|
||||
/** mesh callback for task_transfer on lookup of host names */
|
||||
void auth_xfer_transfer_lookup_callback(void* arg, int rcode,
|
||||
struct sldns_buffer* buf, enum sec_status sec, char* why_bogus);
|
||||
|
||||
/*
|
||||
* Compares two 32-bit serial numbers as defined in RFC1982. Returns
|
||||
* <0 if a < b, 0 if a == b, and >0 if a > b. The result is undefined
|
||||
* if a != b but neither is greater or smaller (see RFC1982 section
|
||||
* 3.2.).
|
||||
*/
|
||||
int compare_serial(uint32_t a, uint32_t b);
|
||||
|
||||
#endif /* SERVICES_AUTHZONE_H */
|
||||
|
||||
Vendored
+90
-14
@@ -108,6 +108,48 @@ store_rrsets(struct module_env* env, struct reply_info* rep, time_t now,
|
||||
}
|
||||
}
|
||||
|
||||
/** delete message from message cache */
|
||||
static void
|
||||
msg_cache_remove(struct module_env* env, uint8_t* qname, size_t qnamelen,
|
||||
uint16_t qtype, uint16_t qclass, uint16_t flags)
|
||||
{
|
||||
struct query_info k;
|
||||
hashvalue_type h;
|
||||
|
||||
k.qname = qname;
|
||||
k.qname_len = qnamelen;
|
||||
k.qtype = qtype;
|
||||
k.qclass = qclass;
|
||||
k.local_alias = NULL;
|
||||
h = query_info_hash(&k, flags);
|
||||
slabhash_remove(env->msg_cache, h, &k);
|
||||
}
|
||||
|
||||
/** remove servfail msg cache entry */
|
||||
static void
|
||||
msg_del_servfail(struct module_env* env, struct query_info* qinfo,
|
||||
uint32_t flags)
|
||||
{
|
||||
struct msgreply_entry* e;
|
||||
/* see if the entry is servfail, and then remove it, so that
|
||||
* lookups move from the cacheresponse stage to the recursionresponse
|
||||
* stage */
|
||||
e = msg_cache_lookup(env, qinfo->qname, qinfo->qname_len,
|
||||
qinfo->qtype, qinfo->qclass, flags, 0, 0);
|
||||
if(!e) return;
|
||||
/* we don't check for the ttl here, also expired servfail entries
|
||||
* are removed. If the user uses serve-expired, they would still be
|
||||
* used to answer from cache */
|
||||
if(FLAGS_GET_RCODE(((struct reply_info*)e->entry.data)->flags)
|
||||
!= LDNS_RCODE_SERVFAIL) {
|
||||
lock_rw_unlock(&e->entry.lock);
|
||||
return;
|
||||
}
|
||||
lock_rw_unlock(&e->entry.lock);
|
||||
msg_cache_remove(env, qinfo->qname, qinfo->qname_len, qinfo->qtype,
|
||||
qinfo->qclass, flags);
|
||||
}
|
||||
|
||||
void
|
||||
dns_cache_store_msg(struct module_env* env, struct query_info* qinfo,
|
||||
hashvalue_type hash, struct reply_info* rep, time_t leeway, int pside,
|
||||
@@ -132,6 +174,12 @@ dns_cache_store_msg(struct module_env* env, struct query_info* qinfo,
|
||||
* which could be useful for delegation information */
|
||||
verbose(VERB_ALGO, "TTL 0: dropped msg from cache");
|
||||
free(rep);
|
||||
/* if the message is SERVFAIL in cache, remove that SERVFAIL,
|
||||
* so that the TTL 0 response can be returned for future
|
||||
* responses (i.e. don't get answered by the servfail from
|
||||
* cache, but instead go to recursion to get this TTL0
|
||||
* response). */
|
||||
msg_del_servfail(env, qinfo, flags);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -395,8 +443,7 @@ dns_msg_authadd(struct dns_msg* msg, struct regional* region,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** add rrset to answer section */
|
||||
static int
|
||||
int
|
||||
dns_msg_ansadd(struct dns_msg* msg, struct regional* region,
|
||||
struct ub_packed_rrset_key* rrset, time_t now)
|
||||
{
|
||||
@@ -568,7 +615,7 @@ rrset_msg(struct ub_packed_rrset_key* rrset, struct regional* region,
|
||||
/** synthesize DNAME+CNAME response from cached DNAME item */
|
||||
static struct dns_msg*
|
||||
synth_dname_msg(struct ub_packed_rrset_key* rrset, struct regional* region,
|
||||
time_t now, struct query_info* q)
|
||||
time_t now, struct query_info* q, enum sec_status* sec_status)
|
||||
{
|
||||
struct dns_msg* msg;
|
||||
struct ub_packed_rrset_key* ck;
|
||||
@@ -580,8 +627,9 @@ synth_dname_msg(struct ub_packed_rrset_key* rrset, struct regional* region,
|
||||
return NULL;
|
||||
/* only allow validated (with DNSSEC) DNAMEs used from cache
|
||||
* for insecure DNAMEs, query again. */
|
||||
if(d->security != sec_status_secure)
|
||||
return NULL;
|
||||
*sec_status = d->security;
|
||||
/* return sec status, so the status of the CNAME can be checked
|
||||
* by the calling routine. */
|
||||
msg = gen_dns_msg(region, q, 2); /* DNAME + CNAME RRset */
|
||||
if(!msg)
|
||||
return NULL;
|
||||
@@ -711,7 +759,8 @@ fill_any(struct module_env* env,
|
||||
struct dns_msg*
|
||||
dns_cache_lookup(struct module_env* env,
|
||||
uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
|
||||
uint16_t flags, struct regional* region, struct regional* scratch)
|
||||
uint16_t flags, struct regional* region, struct regional* scratch,
|
||||
int no_partial)
|
||||
{
|
||||
struct lruhash_entry* e;
|
||||
struct query_info k;
|
||||
@@ -743,27 +792,54 @@ dns_cache_lookup(struct module_env* env,
|
||||
/* see if a DNAME exists. Checked for first, to enforce that DNAMEs
|
||||
* are more important, the CNAME is resynthesized and thus
|
||||
* consistent with the DNAME */
|
||||
if( (rrset=find_closest_of_type(env, qname, qnamelen, qclass, now,
|
||||
if(!no_partial &&
|
||||
(rrset=find_closest_of_type(env, qname, qnamelen, qclass, now,
|
||||
LDNS_RR_TYPE_DNAME, 1))) {
|
||||
/* synthesize a DNAME+CNAME message based on this */
|
||||
struct dns_msg* msg = synth_dname_msg(rrset, region, now, &k);
|
||||
enum sec_status sec_status = sec_status_unchecked;
|
||||
struct dns_msg* msg = synth_dname_msg(rrset, region, now, &k,
|
||||
&sec_status);
|
||||
if(msg) {
|
||||
struct ub_packed_rrset_key* cname_rrset;
|
||||
lock_rw_unlock(&rrset->entry.lock);
|
||||
/* now, after unlocking the DNAME rrset lock,
|
||||
* check the sec_status, and see if we need to look
|
||||
* up the CNAME record associated before it can
|
||||
* be used */
|
||||
/* normally, only secure DNAMEs allowed from cache*/
|
||||
if(sec_status == sec_status_secure)
|
||||
return msg;
|
||||
/* but if we have a CNAME cached with this name, then we
|
||||
* have previously already allowed this name to pass.
|
||||
* the next cache lookup is going to fetch that CNAME itself,
|
||||
* but it is better to have the (unsigned)DNAME + CNAME in
|
||||
* that case */
|
||||
cname_rrset = rrset_cache_lookup(
|
||||
env->rrset_cache, qname, qnamelen,
|
||||
LDNS_RR_TYPE_CNAME, qclass, 0, now, 0);
|
||||
if(cname_rrset) {
|
||||
/* CNAME already synthesized by
|
||||
* synth_dname_msg routine, so we can
|
||||
* straight up return the msg */
|
||||
lock_rw_unlock(&cname_rrset->entry.lock);
|
||||
return msg;
|
||||
}
|
||||
} else {
|
||||
lock_rw_unlock(&rrset->entry.lock);
|
||||
return msg;
|
||||
}
|
||||
lock_rw_unlock(&rrset->entry.lock);
|
||||
}
|
||||
|
||||
/* see if we have CNAME for this domain,
|
||||
* but not for DS records (which are part of the parent) */
|
||||
if( qtype != LDNS_RR_TYPE_DS &&
|
||||
if(!no_partial && qtype != LDNS_RR_TYPE_DS &&
|
||||
(rrset=rrset_cache_lookup(env->rrset_cache, qname, qnamelen,
|
||||
LDNS_RR_TYPE_CNAME, qclass, 0, now, 0))) {
|
||||
uint8_t* wc = NULL;
|
||||
size_t wl;
|
||||
/* if the rrset is not a wildcard expansion, with wcname */
|
||||
/* because, if we return that CNAME rrset on its own, it is
|
||||
* missing the NSEC or NSEC3 proof */
|
||||
if(!(val_rrset_wildcard(rrset, &wc) && wc != NULL)) {
|
||||
if(!(val_rrset_wildcard(rrset, &wc, &wl) && wc != NULL)) {
|
||||
struct dns_msg* msg = rrset_msg(rrset, region, now, &k);
|
||||
if(msg) {
|
||||
lock_rw_unlock(&rrset->entry.lock);
|
||||
@@ -842,7 +918,7 @@ dns_cache_lookup(struct module_env* env,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
dns_cache_store(struct module_env* env, struct query_info* msgqinf,
|
||||
struct reply_info* msgrep, int is_referral, time_t leeway, int pside,
|
||||
struct regional* region, uint32_t flags)
|
||||
@@ -852,7 +928,7 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf,
|
||||
rep = reply_info_copy(msgrep, env->alloc, NULL);
|
||||
if(!rep)
|
||||
return 0;
|
||||
/* ttl must be relative ;i.e. 0..86400 not time(0)+86400.
|
||||
/* ttl must be relative ;i.e. 0..86400 not time(0)+86400.
|
||||
* the env->now is added to message and RRsets in this routine. */
|
||||
/* the leeway is used to invalidate other rrsets earlier */
|
||||
|
||||
|
||||
Vendored
+16
-1
@@ -159,13 +159,16 @@ struct dns_msg* tomsg(struct module_env* env, struct query_info* q,
|
||||
* @param flags: flags with BIT_CD for AAAA queries in dns64 translation.
|
||||
* @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).
|
||||
* @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.
|
||||
*/
|
||||
struct dns_msg* dns_cache_lookup(struct module_env* env,
|
||||
uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
|
||||
uint16_t flags, struct regional* region, struct regional* scratch);
|
||||
uint16_t flags, struct regional* region, struct regional* scratch,
|
||||
int no_partial);
|
||||
|
||||
/**
|
||||
* find and add A and AAAA records for missing nameservers in delegpt
|
||||
@@ -204,6 +207,18 @@ struct dns_msg* dns_msg_create(uint8_t* qname, size_t qnamelen, uint16_t qtype,
|
||||
int dns_msg_authadd(struct dns_msg* msg, struct regional* region,
|
||||
struct ub_packed_rrset_key* rrset, time_t now);
|
||||
|
||||
/**
|
||||
* Add rrset to authority section in unpacked dns_msg message. Must have enough
|
||||
* space left, does not grow the array.
|
||||
* @param msg: msg to put it in.
|
||||
* @param region: region to alloc in
|
||||
* @param rrset: to add in authority section
|
||||
* @param now: now.
|
||||
* @return true if worked, false on fail
|
||||
*/
|
||||
int dns_msg_ansadd(struct dns_msg* msg, struct regional* region,
|
||||
struct ub_packed_rrset_key* rrset, time_t now);
|
||||
|
||||
/**
|
||||
* Adjust the prefetch_ttl for a cached message. This adds a value to the
|
||||
* prefetch ttl - postponing the time when it will be prefetched for future
|
||||
|
||||
Vendored
+13
-15
@@ -232,22 +232,20 @@ infra_create(struct config_file* cfg)
|
||||
infra->host_ttl = cfg->host_ttl;
|
||||
name_tree_init(&infra->domain_limits);
|
||||
infra_dp_ratelimit = cfg->ratelimit;
|
||||
if(cfg->ratelimit != 0) {
|
||||
infra->domain_rates = slabhash_create(cfg->ratelimit_slabs,
|
||||
INFRA_HOST_STARTSIZE, cfg->ratelimit_size,
|
||||
&rate_sizefunc, &rate_compfunc, &rate_delkeyfunc,
|
||||
&rate_deldatafunc, NULL);
|
||||
if(!infra->domain_rates) {
|
||||
infra_delete(infra);
|
||||
return NULL;
|
||||
}
|
||||
/* insert config data into ratelimits */
|
||||
if(!infra_ratelimit_cfg_insert(infra, cfg)) {
|
||||
infra_delete(infra);
|
||||
return NULL;
|
||||
}
|
||||
name_tree_init_parents(&infra->domain_limits);
|
||||
infra->domain_rates = slabhash_create(cfg->ratelimit_slabs,
|
||||
INFRA_HOST_STARTSIZE, cfg->ratelimit_size,
|
||||
&rate_sizefunc, &rate_compfunc, &rate_delkeyfunc,
|
||||
&rate_deldatafunc, NULL);
|
||||
if(!infra->domain_rates) {
|
||||
infra_delete(infra);
|
||||
return NULL;
|
||||
}
|
||||
/* insert config data into ratelimits */
|
||||
if(!infra_ratelimit_cfg_insert(infra, cfg)) {
|
||||
infra_delete(infra);
|
||||
return NULL;
|
||||
}
|
||||
name_tree_init_parents(&infra->domain_limits);
|
||||
infra_ip_ratelimit = cfg->ip_ratelimit;
|
||||
infra->client_ip_rates = slabhash_create(cfg->ip_ratelimit_slabs,
|
||||
INFRA_HOST_STARTSIZE, cfg->ip_ratelimit_size, &ip_rate_sizefunc,
|
||||
|
||||
Vendored
+34
@@ -47,6 +47,7 @@
|
||||
#include "util/data/msgreply.h"
|
||||
#include "util/regional.h"
|
||||
#include "util/alloc.h"
|
||||
#include "util/net_help.h"
|
||||
|
||||
void
|
||||
rrset_markdel(void* key)
|
||||
@@ -237,6 +238,39 @@ rrset_cache_update(struct rrset_cache* r, struct rrset_ref* ref,
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rrset_cache_update_wildcard(struct rrset_cache* rrset_cache,
|
||||
struct ub_packed_rrset_key* rrset, uint8_t* ce, size_t ce_len,
|
||||
struct alloc_cache* alloc, time_t timenow)
|
||||
{
|
||||
struct rrset_ref ref;
|
||||
uint8_t wc_dname[LDNS_MAX_DOMAINLEN+3];
|
||||
rrset = packed_rrset_copy_alloc(rrset, alloc, timenow);
|
||||
if(!rrset) {
|
||||
log_err("malloc failure in rrset_cache_update_wildcard");
|
||||
return;
|
||||
}
|
||||
/* ce has at least one label less then qname, we can therefore safely
|
||||
* add the wildcard label. */
|
||||
wc_dname[0] = 1;
|
||||
wc_dname[1] = (uint8_t)'*';
|
||||
memmove(wc_dname+2, ce, ce_len);
|
||||
|
||||
free(rrset->rk.dname);
|
||||
rrset->rk.dname_len = ce_len + 2;
|
||||
rrset->rk.dname = (uint8_t*)memdup(wc_dname, rrset->rk.dname_len);
|
||||
if(!rrset->rk.dname) {
|
||||
alloc_special_release(alloc, rrset);
|
||||
log_err("memdup failure in rrset_cache_update_wildcard");
|
||||
return;
|
||||
}
|
||||
|
||||
rrset->entry.hash = rrset_key_hash(&rrset->rk);
|
||||
ref.key = rrset;
|
||||
ref.id = rrset->id;
|
||||
/* ignore ret: if it was in the cache, ref updated */
|
||||
(void)rrset_cache_update(rrset_cache, &ref, alloc, timenow);
|
||||
}
|
||||
|
||||
struct ub_packed_rrset_key*
|
||||
rrset_cache_lookup(struct rrset_cache* r, uint8_t* qname, size_t qnamelen,
|
||||
uint16_t qtype, uint16_t qclass, uint32_t flags, time_t timenow,
|
||||
|
||||
Vendored
+18
@@ -133,6 +133,24 @@ void rrset_cache_touch(struct rrset_cache* r, struct ub_packed_rrset_key* key,
|
||||
int rrset_cache_update(struct rrset_cache* r, struct rrset_ref* ref,
|
||||
struct alloc_cache* alloc, time_t timenow);
|
||||
|
||||
/**
|
||||
* Update or add an rrset in the rrset cache using a wildcard dname.
|
||||
* Generates wildcard dname by prepending the wildcard label to the closest
|
||||
* encloser. Will lookup if the rrset is in the cache and perform an update if
|
||||
* necessary.
|
||||
*
|
||||
* @param rrset_cache: the rrset cache.
|
||||
* @param rrset: which rrset to cache as wildcard. This rrset is left
|
||||
* untouched.
|
||||
* @param ce: the closest encloser, will be uses to generate the wildcard dname.
|
||||
* @param ce_len: the closest encloser lenght.
|
||||
* @param alloc: how to allocate (and deallocate) the special rrset key.
|
||||
* @param timenow: current time (to see if ttl in cache is expired).
|
||||
*/
|
||||
void rrset_cache_update_wildcard(struct rrset_cache* rrset_cache,
|
||||
struct ub_packed_rrset_key* rrset, uint8_t* ce, size_t ce_len,
|
||||
struct alloc_cache* alloc, time_t timenow);
|
||||
|
||||
/**
|
||||
* Lookup rrset. You obtain read/write lock. You must unlock before lookup
|
||||
* anything of else.
|
||||
|
||||
+55
-19
@@ -167,7 +167,7 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
|
||||
int freebind, int use_systemd)
|
||||
{
|
||||
int s;
|
||||
#if defined(SO_REUSEADDR) || defined(SO_REUSEPORT) || defined(IPV6_USE_MIN_MTU) || defined(IP_TRANSPARENT) || defined(IP_BINDANY) || defined(IP_FREEBIND)
|
||||
#if defined(SO_REUSEADDR) || defined(SO_REUSEPORT) || defined(IPV6_USE_MIN_MTU) || defined(IP_TRANSPARENT) || defined(IP_BINDANY) || defined(IP_FREEBIND) || defined (SO_BINDANY)
|
||||
int on=1;
|
||||
#endif
|
||||
#ifdef IPV6_MTU
|
||||
@@ -182,7 +182,7 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
|
||||
#ifndef IPV6_V6ONLY
|
||||
(void)v6only;
|
||||
#endif
|
||||
#if !defined(IP_TRANSPARENT) && !defined(IP_BINDANY)
|
||||
#if !defined(IP_TRANSPARENT) && !defined(IP_BINDANY) && !defined(SO_BINDANY)
|
||||
(void)transparent;
|
||||
#endif
|
||||
#if !defined(IP_FREEBIND)
|
||||
@@ -281,7 +281,14 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
|
||||
log_warn("setsockopt(.. IP%s_BINDANY ..) failed: %s",
|
||||
(family==AF_INET6?"V6":""), strerror(errno));
|
||||
}
|
||||
#endif /* IP_TRANSPARENT || IP_BINDANY */
|
||||
#elif defined(SO_BINDANY)
|
||||
if (transparent &&
|
||||
setsockopt(s, SOL_SOCKET, SO_BINDANY, (void*)&on,
|
||||
(socklen_t)sizeof(on)) < 0) {
|
||||
log_warn("setsockopt(.. SO_BINDANY ..) failed: %s",
|
||||
strerror(errno));
|
||||
}
|
||||
#endif /* IP_TRANSPARENT || IP_BINDANY || SO_BINDANY */
|
||||
}
|
||||
#ifdef IP_FREEBIND
|
||||
if(freebind &&
|
||||
@@ -592,7 +599,7 @@ create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto,
|
||||
int* reuseport, int transparent, int mss, int freebind, int use_systemd)
|
||||
{
|
||||
int s;
|
||||
#if defined(SO_REUSEADDR) || defined(SO_REUSEPORT) || defined(IPV6_V6ONLY) || defined(IP_TRANSPARENT) || defined(IP_BINDANY) || defined(IP_FREEBIND)
|
||||
#if defined(SO_REUSEADDR) || defined(SO_REUSEPORT) || defined(IPV6_V6ONLY) || defined(IP_TRANSPARENT) || defined(IP_BINDANY) || defined(IP_FREEBIND) || defined(SO_BINDANY)
|
||||
int on = 1;
|
||||
#endif
|
||||
#ifdef HAVE_SYSTEMD
|
||||
@@ -601,7 +608,7 @@ create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto,
|
||||
#ifdef USE_TCP_FASTOPEN
|
||||
int qlen;
|
||||
#endif
|
||||
#if !defined(IP_TRANSPARENT) && !defined(IP_BINDANY)
|
||||
#if !defined(IP_TRANSPARENT) && !defined(IP_BINDANY) && !defined(SO_BINDANY)
|
||||
(void)transparent;
|
||||
#endif
|
||||
#if !defined(IP_FREEBIND)
|
||||
@@ -736,7 +743,14 @@ create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto,
|
||||
log_warn("setsockopt(.. IP%s_BINDANY ..) failed: %s",
|
||||
(addr->ai_family==AF_INET6?"V6":""), strerror(errno));
|
||||
}
|
||||
#endif /* IP_TRANSPARENT || IP_BINDANY */
|
||||
#elif defined(SO_BINDANY)
|
||||
if (transparent &&
|
||||
setsockopt(s, SOL_SOCKET, SO_BINDANY, (void*)&on, (socklen_t)
|
||||
sizeof(on)) < 0) {
|
||||
log_warn("setsockopt(.. SO_BINDANY ..) failed: %s",
|
||||
strerror(errno));
|
||||
}
|
||||
#endif /* IP_TRANSPARENT || IP_BINDANY || SO_BINDANY */
|
||||
if(
|
||||
#ifdef HAVE_SYSTEMD
|
||||
!got_fd_from_systemd &&
|
||||
@@ -1042,6 +1056,26 @@ set_recvpktinfo(int s, int family)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** see if interface is ssl, its port number == the ssl port number */
|
||||
static int
|
||||
if_is_ssl(const char* ifname, const char* port, int ssl_port,
|
||||
struct config_strlist* tls_additional_port)
|
||||
{
|
||||
struct config_strlist* s;
|
||||
char* p = strchr(ifname, '@');
|
||||
if(!p && atoi(port) == ssl_port)
|
||||
return 1;
|
||||
if(p && atoi(p+1) == ssl_port)
|
||||
return 1;
|
||||
for(s = tls_additional_port; s; s = s->next) {
|
||||
if(p && atoi(p+1) == atoi(s->str))
|
||||
return 1;
|
||||
if(!p && atoi(port) == atoi(s->str))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for ports_open. Creates one interface (or NULL for default).
|
||||
* @param ifname: The interface ip address.
|
||||
@@ -1055,6 +1089,7 @@ set_recvpktinfo(int s, int family)
|
||||
* @param rcv: receive buffer size for UDP
|
||||
* @param snd: send buffer size for UDP
|
||||
* @param ssl_port: ssl service port number
|
||||
* @param tls_additional_port: list of additional ssl service port numbers.
|
||||
* @param reuseport: try to set SO_REUSEPORT if nonNULL and true.
|
||||
* set to false on exit if reuseport failed due to no kernel support.
|
||||
* @param transparent: set IP_TRANSPARENT socket option.
|
||||
@@ -1067,8 +1102,10 @@ set_recvpktinfo(int s, int family)
|
||||
static int
|
||||
ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
|
||||
struct addrinfo *hints, const char* port, struct listen_port** list,
|
||||
size_t rcv, size_t snd, int ssl_port, int* reuseport, int transparent,
|
||||
int tcp_mss, int freebind, int use_systemd, int dnscrypt_port)
|
||||
size_t rcv, size_t snd, int ssl_port,
|
||||
struct config_strlist* tls_additional_port, int* reuseport,
|
||||
int transparent, int tcp_mss, int freebind, int use_systemd,
|
||||
int dnscrypt_port)
|
||||
{
|
||||
int s, noip6=0;
|
||||
#ifdef USE_DNSCRYPT
|
||||
@@ -1132,9 +1169,8 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
|
||||
}
|
||||
}
|
||||
if(do_tcp) {
|
||||
int is_ssl = ((strchr(ifname, '@') &&
|
||||
atoi(strchr(ifname, '@')+1) == ssl_port) ||
|
||||
(!strchr(ifname, '@') && atoi(port) == ssl_port));
|
||||
int is_ssl = if_is_ssl(ifname, port, ssl_port,
|
||||
tls_additional_port);
|
||||
if((s = make_sock_port(SOCK_STREAM, ifname, port, hints, 1,
|
||||
&noip6, 0, 0, reuseport, transparent, tcp_mss,
|
||||
freebind, use_systemd)) == -1) {
|
||||
@@ -1320,8 +1356,8 @@ listening_ports_open(struct config_file* cfg, int* reuseport)
|
||||
do_auto, cfg->do_udp, do_tcp,
|
||||
&hints, portbuf, &list,
|
||||
cfg->so_rcvbuf, cfg->so_sndbuf,
|
||||
cfg->ssl_port, reuseport,
|
||||
cfg->ip_transparent,
|
||||
cfg->ssl_port, cfg->tls_additional_port,
|
||||
reuseport, cfg->ip_transparent,
|
||||
cfg->tcp_mss, cfg->ip_freebind, cfg->use_systemd,
|
||||
cfg->dnscrypt_port)) {
|
||||
listening_ports_free(list);
|
||||
@@ -1334,8 +1370,8 @@ listening_ports_open(struct config_file* cfg, int* reuseport)
|
||||
do_auto, cfg->do_udp, do_tcp,
|
||||
&hints, portbuf, &list,
|
||||
cfg->so_rcvbuf, cfg->so_sndbuf,
|
||||
cfg->ssl_port, reuseport,
|
||||
cfg->ip_transparent,
|
||||
cfg->ssl_port, cfg->tls_additional_port,
|
||||
reuseport, cfg->ip_transparent,
|
||||
cfg->tcp_mss, cfg->ip_freebind, cfg->use_systemd,
|
||||
cfg->dnscrypt_port)) {
|
||||
listening_ports_free(list);
|
||||
@@ -1350,8 +1386,8 @@ listening_ports_open(struct config_file* cfg, int* reuseport)
|
||||
if(!ports_create_if(cfg->ifs[i], 0, cfg->do_udp,
|
||||
do_tcp, &hints, portbuf, &list,
|
||||
cfg->so_rcvbuf, cfg->so_sndbuf,
|
||||
cfg->ssl_port, reuseport,
|
||||
cfg->ip_transparent,
|
||||
cfg->ssl_port, cfg->tls_additional_port,
|
||||
reuseport, cfg->ip_transparent,
|
||||
cfg->tcp_mss, cfg->ip_freebind, cfg->use_systemd,
|
||||
cfg->dnscrypt_port)) {
|
||||
listening_ports_free(list);
|
||||
@@ -1364,8 +1400,8 @@ listening_ports_open(struct config_file* cfg, int* reuseport)
|
||||
if(!ports_create_if(cfg->ifs[i], 0, cfg->do_udp,
|
||||
do_tcp, &hints, portbuf, &list,
|
||||
cfg->so_rcvbuf, cfg->so_sndbuf,
|
||||
cfg->ssl_port, reuseport,
|
||||
cfg->ip_transparent,
|
||||
cfg->ssl_port, cfg->tls_additional_port,
|
||||
reuseport, cfg->ip_transparent,
|
||||
cfg->tcp_mss, cfg->ip_freebind, cfg->use_systemd,
|
||||
cfg->dnscrypt_port)) {
|
||||
listening_ports_free(list);
|
||||
|
||||
+15
-54
@@ -52,7 +52,6 @@
|
||||
#include "util/data/msgreply.h"
|
||||
#include "util/data/msgparse.h"
|
||||
#include "util/as112.h"
|
||||
#include "util/config_file.h"
|
||||
|
||||
/* maximum RRs in an RRset, to cap possible 'endless' list RRs.
|
||||
* with 16 bytes for an A record, a 64K packet has about 4000 max */
|
||||
@@ -1133,57 +1132,11 @@ void local_zones_print(struct local_zones* zones)
|
||||
lock_rw_rdlock(&zones->lock);
|
||||
log_info("number of auth zones %u", (unsigned)zones->ztree.count);
|
||||
RBTREE_FOR(z, struct local_zone*, &zones->ztree) {
|
||||
char buf[64];
|
||||
lock_rw_rdlock(&z->lock);
|
||||
switch(z->type) {
|
||||
case local_zone_deny:
|
||||
log_nametypeclass(0, "deny zone",
|
||||
z->name, 0, z->dclass);
|
||||
break;
|
||||
case local_zone_refuse:
|
||||
log_nametypeclass(0, "refuse zone",
|
||||
z->name, 0, z->dclass);
|
||||
break;
|
||||
case local_zone_redirect:
|
||||
log_nametypeclass(0, "redirect zone",
|
||||
z->name, 0, z->dclass);
|
||||
break;
|
||||
case local_zone_transparent:
|
||||
log_nametypeclass(0, "transparent zone",
|
||||
z->name, 0, z->dclass);
|
||||
break;
|
||||
case local_zone_typetransparent:
|
||||
log_nametypeclass(0, "typetransparent zone",
|
||||
z->name, 0, z->dclass);
|
||||
break;
|
||||
case local_zone_static:
|
||||
log_nametypeclass(0, "static zone",
|
||||
z->name, 0, z->dclass);
|
||||
break;
|
||||
case local_zone_inform:
|
||||
log_nametypeclass(0, "inform zone",
|
||||
z->name, 0, z->dclass);
|
||||
break;
|
||||
case local_zone_inform_deny:
|
||||
log_nametypeclass(0, "inform_deny zone",
|
||||
z->name, 0, z->dclass);
|
||||
break;
|
||||
case local_zone_always_transparent:
|
||||
log_nametypeclass(0, "always_transparent zone",
|
||||
z->name, 0, z->dclass);
|
||||
break;
|
||||
case local_zone_always_refuse:
|
||||
log_nametypeclass(0, "always_refuse zone",
|
||||
z->name, 0, z->dclass);
|
||||
break;
|
||||
case local_zone_always_nxdomain:
|
||||
log_nametypeclass(0, "always_nxdomain zone",
|
||||
z->name, 0, z->dclass);
|
||||
break;
|
||||
default:
|
||||
log_nametypeclass(0, "badtyped zone",
|
||||
z->name, 0, z->dclass);
|
||||
break;
|
||||
}
|
||||
snprintf(buf, sizeof(buf), "%s zone",
|
||||
local_zone_type2str(z->type));
|
||||
log_nametypeclass(0, buf, z->name, 0, z->dclass);
|
||||
local_zone_out(z);
|
||||
lock_rw_unlock(&z->lock);
|
||||
}
|
||||
@@ -1590,12 +1543,17 @@ local_zones_answer(struct local_zones* zones, struct module_env* env,
|
||||
(z = local_zones_lookup(view->local_zones,
|
||||
qinfo->qname, qinfo->qname_len, labs,
|
||||
qinfo->qclass, qinfo->qtype))) {
|
||||
verbose(VERB_ALGO,
|
||||
"using localzone from view: %s",
|
||||
view->name);
|
||||
if(z->type != local_zone_noview)
|
||||
verbose(VERB_ALGO,
|
||||
"using localzone from view: %s",
|
||||
view->name);
|
||||
lock_rw_rdlock(&z->lock);
|
||||
lzt = z->type;
|
||||
}
|
||||
if(lzt == local_zone_noview) {
|
||||
lock_rw_unlock(&z->lock);
|
||||
z = NULL;
|
||||
}
|
||||
if(view->local_zones && !z && !view->isfirst){
|
||||
lock_rw_unlock(&view->lock);
|
||||
return 0;
|
||||
@@ -1653,6 +1611,7 @@ 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_noview: return "noview";
|
||||
}
|
||||
return "badtyped";
|
||||
}
|
||||
@@ -1681,6 +1640,8 @@ 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, "noview") == 0)
|
||||
*t = local_zone_noview;
|
||||
else if(strcmp(type, "nodefault") == 0)
|
||||
*t = local_zone_nodefault;
|
||||
else return 0;
|
||||
|
||||
@@ -88,7 +88,9 @@ enum localzone_type {
|
||||
/** answer with error, even when there is local data */
|
||||
local_zone_always_refuse,
|
||||
/** answer with nxdomain, even when there is local data */
|
||||
local_zone_always_nxdomain
|
||||
local_zone_always_nxdomain,
|
||||
/** answer not from the view, but global or no-answer */
|
||||
local_zone_noview
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
+17
-4
@@ -736,7 +736,8 @@ mesh_state_cleanup(struct mesh_state* mstate)
|
||||
comm_point_drop_reply(&rep->query_reply);
|
||||
mesh->num_reply_addrs--;
|
||||
}
|
||||
for(cb=mstate->cb_list; cb; cb=cb->next) {
|
||||
while((cb = mstate->cb_list)!=NULL) {
|
||||
mstate->cb_list = cb->next;
|
||||
fptr_ok(fptr_whitelist_mesh_cb(cb->cb));
|
||||
(*cb->cb)(cb->cb_arg, LDNS_RCODE_SERVFAIL, NULL,
|
||||
sec_status_unchecked, NULL);
|
||||
@@ -974,7 +975,8 @@ mesh_do_callback(struct mesh_state* m, int rcode, struct reply_info* rep,
|
||||
else secure = 0;
|
||||
if(!rep && rcode == LDNS_RCODE_NOERROR)
|
||||
rcode = LDNS_RCODE_SERVFAIL;
|
||||
if(!rcode && rep->security == sec_status_bogus) {
|
||||
if(!rcode && (rep->security == sec_status_bogus ||
|
||||
rep->security == sec_status_secure_sentinel_fail)) {
|
||||
if(!(reason = errinf_to_str(&m->s)))
|
||||
rcode = LDNS_RCODE_SERVFAIL;
|
||||
}
|
||||
@@ -1040,7 +1042,8 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
|
||||
/* examine security status */
|
||||
if(m->s.env->need_to_validate && (!(r->qflags&BIT_CD) ||
|
||||
m->s.env->cfg->ignore_cd) && rep &&
|
||||
rep->security <= sec_status_bogus) {
|
||||
(rep->security <= sec_status_bogus ||
|
||||
rep->security == sec_status_secure_sentinel_fail)) {
|
||||
rcode = LDNS_RCODE_SERVFAIL;
|
||||
if(m->s.env->cfg->stat_extended)
|
||||
m->s.env->mesh->ans_bogus++;
|
||||
@@ -1167,7 +1170,17 @@ void mesh_query_done(struct mesh_state* mstate)
|
||||
}
|
||||
}
|
||||
mstate->replies_sent = 1;
|
||||
for(c = mstate->cb_list; c; c = c->next) {
|
||||
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 */
|
||||
mstate->s.env->mesh->num_reply_states--;
|
||||
}
|
||||
mstate->cb_list = c->next;
|
||||
if(!mstate->reply_list && !mstate->cb_list &&
|
||||
mstate->super_set.count == 0)
|
||||
mstate->s.env->mesh->num_detached_states++;
|
||||
mesh_do_callback(mstate, mstate->s.return_rcode, rep, c);
|
||||
}
|
||||
}
|
||||
|
||||
+317
-26
@@ -198,21 +198,17 @@ pick_outgoing_tcp(struct waiting_tcp* w, int s)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** use next free buffer to service a tcp query */
|
||||
static int
|
||||
outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len)
|
||||
/** get TCP file descriptor for address, returns -1 on failure,
|
||||
* tcp_mss is 0 or maxseg size to set for TCP packets. */
|
||||
int
|
||||
outnet_get_tcp_fd(struct sockaddr_storage* addr, socklen_t addrlen, int tcp_mss)
|
||||
{
|
||||
struct pending_tcp* pend = w->outnet->tcp_free;
|
||||
int s;
|
||||
#ifdef SO_REUSEADDR
|
||||
int on = 1;
|
||||
#endif
|
||||
log_assert(pend);
|
||||
log_assert(pkt);
|
||||
log_assert(w->addrlen > 0);
|
||||
/* open socket */
|
||||
#ifdef INET6
|
||||
if(addr_is_ip6(&w->addr, w->addrlen))
|
||||
if(addr_is_ip6(addr, addrlen))
|
||||
s = socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP);
|
||||
else
|
||||
#endif
|
||||
@@ -220,12 +216,12 @@ outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len)
|
||||
if(s == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
log_err_addr("outgoing tcp: socket", strerror(errno),
|
||||
&w->addr, w->addrlen);
|
||||
addr, addrlen);
|
||||
#else
|
||||
log_err_addr("outgoing tcp: socket",
|
||||
wsa_strerror(WSAGetLastError()), &w->addr, w->addrlen);
|
||||
wsa_strerror(WSAGetLastError()), addr, addrlen);
|
||||
#endif
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef SO_REUSEADDR
|
||||
@@ -235,11 +231,11 @@ outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len)
|
||||
" setsockopt(.. SO_REUSEADDR ..) failed");
|
||||
}
|
||||
#endif
|
||||
if (w->outnet->tcp_mss > 0) {
|
||||
|
||||
if(tcp_mss > 0) {
|
||||
#if defined(IPPROTO_TCP) && defined(TCP_MAXSEG)
|
||||
if(setsockopt(s, IPPROTO_TCP, TCP_MAXSEG,
|
||||
(void*)&w->outnet->tcp_mss,
|
||||
(socklen_t)sizeof(w->outnet->tcp_mss)) < 0) {
|
||||
(void*)&tcp_mss, (socklen_t)sizeof(tcp_mss)) < 0) {
|
||||
verbose(VERB_ALGO, "outgoing tcp:"
|
||||
" setsockopt(.. TCP_MAXSEG ..) failed");
|
||||
}
|
||||
@@ -249,6 +245,50 @@ outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len)
|
||||
#endif /* defined(IPPROTO_TCP) && defined(TCP_MAXSEG) */
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/** connect tcp connection to addr, 0 on failure */
|
||||
int
|
||||
outnet_tcp_connect(int s, struct sockaddr_storage* addr, socklen_t addrlen)
|
||||
{
|
||||
if(connect(s, (struct sockaddr*)addr, addrlen) == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
#ifdef EINPROGRESS
|
||||
if(errno != EINPROGRESS) {
|
||||
#endif
|
||||
if(tcp_connect_errno_needs_log(
|
||||
(struct sockaddr*)addr, addrlen))
|
||||
log_err_addr("outgoing tcp: connect",
|
||||
strerror(errno), addr, addrlen);
|
||||
close(s);
|
||||
return 0;
|
||||
#ifdef EINPROGRESS
|
||||
}
|
||||
#endif
|
||||
#else /* USE_WINSOCK */
|
||||
if(WSAGetLastError() != WSAEINPROGRESS &&
|
||||
WSAGetLastError() != WSAEWOULDBLOCK) {
|
||||
closesocket(s);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** use next free buffer to service a tcp query */
|
||||
static int
|
||||
outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len)
|
||||
{
|
||||
struct pending_tcp* pend = w->outnet->tcp_free;
|
||||
int s;
|
||||
log_assert(pend);
|
||||
log_assert(pkt);
|
||||
log_assert(w->addrlen > 0);
|
||||
/* open socket */
|
||||
s = outnet_get_tcp_fd(&w->addr, w->addrlen, w->outnet->tcp_mss);
|
||||
|
||||
if(!pick_outgoing_tcp(w, s))
|
||||
return 0;
|
||||
|
||||
@@ -324,6 +364,20 @@ outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len)
|
||||
comm_point_tcp_win_bio_cb(pend->c, pend->c->ssl);
|
||||
#endif
|
||||
pend->c->ssl_shake_state = comm_ssl_shake_write;
|
||||
#ifdef HAVE_SSL_SET1_HOST
|
||||
if(w->tls_auth_name) {
|
||||
SSL_set_verify(pend->c->ssl, SSL_VERIFY_PEER, NULL);
|
||||
/* setting the hostname makes openssl verify the
|
||||
* host name in the x509 certificate in the
|
||||
* SSL connection*/
|
||||
if(!SSL_set1_host(pend->c->ssl, w->tls_auth_name)) {
|
||||
log_err("SSL_set1_host failed");
|
||||
pend->c->fd = s;
|
||||
comm_point_close(pend->c);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_SSL_SET1_HOST */
|
||||
}
|
||||
w->pkt = NULL;
|
||||
w->next_waiting = (void*)pend;
|
||||
@@ -811,6 +865,7 @@ serviced_node_del(rbnode_type* node, void* ATTR_UNUSED(arg))
|
||||
struct service_callback* p = sq->cblist, *np;
|
||||
free(sq->qbuf);
|
||||
free(sq->zone);
|
||||
free(sq->tls_auth_name);
|
||||
edns_opt_list_free(sq->opt_list);
|
||||
while(p) {
|
||||
np = p->next;
|
||||
@@ -1244,9 +1299,10 @@ pending_tcp_query(struct serviced_query* sq, sldns_buffer* packet,
|
||||
w->cb = callback;
|
||||
w->cb_arg = callback_arg;
|
||||
w->ssl_upstream = sq->ssl_upstream;
|
||||
w->tls_auth_name = sq->tls_auth_name;
|
||||
#ifndef S_SPLINT_S
|
||||
tv.tv_sec = timeout;
|
||||
tv.tv_usec = 0;
|
||||
tv.tv_sec = timeout/1000;
|
||||
tv.tv_usec = (timeout%1000)*1000;
|
||||
#endif
|
||||
comm_timer_set(w->timer, &tv);
|
||||
if(pend) {
|
||||
@@ -1317,8 +1373,8 @@ lookup_serviced(struct outside_network* outnet, sldns_buffer* buff, int dnssec,
|
||||
static struct serviced_query*
|
||||
serviced_create(struct outside_network* outnet, sldns_buffer* buff, int dnssec,
|
||||
int want_dnssec, int nocaps, int tcp_upstream, int ssl_upstream,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
|
||||
size_t zonelen, int qtype, struct edns_option* opt_list)
|
||||
char* tls_auth_name, struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
uint8_t* zone, size_t zonelen, int qtype, struct edns_option* opt_list)
|
||||
{
|
||||
struct serviced_query* sq = (struct serviced_query*)malloc(sizeof(*sq));
|
||||
#ifdef UNBOUND_DEBUG
|
||||
@@ -1346,12 +1402,24 @@ serviced_create(struct outside_network* outnet, sldns_buffer* buff, int dnssec,
|
||||
sq->nocaps = nocaps;
|
||||
sq->tcp_upstream = tcp_upstream;
|
||||
sq->ssl_upstream = ssl_upstream;
|
||||
if(tls_auth_name) {
|
||||
sq->tls_auth_name = strdup(tls_auth_name);
|
||||
if(!sq->tls_auth_name) {
|
||||
free(sq->zone);
|
||||
free(sq->qbuf);
|
||||
free(sq);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
sq->tls_auth_name = NULL;
|
||||
}
|
||||
memcpy(&sq->addr, addr, addrlen);
|
||||
sq->addrlen = addrlen;
|
||||
sq->opt_list = NULL;
|
||||
if(opt_list) {
|
||||
sq->opt_list = edns_opt_copy_alloc(opt_list);
|
||||
if(!sq->opt_list) {
|
||||
free(sq->tls_auth_name);
|
||||
free(sq->zone);
|
||||
free(sq->qbuf);
|
||||
free(sq);
|
||||
@@ -1744,7 +1812,12 @@ serviced_tcp_callback(struct comm_point* c, void* arg, int error,
|
||||
}
|
||||
if(sq->tcp_upstream || sq->ssl_upstream) {
|
||||
struct timeval now = *sq->outnet->now_tv;
|
||||
if(now.tv_sec > sq->last_sent_time.tv_sec ||
|
||||
if(error!=NETEVENT_NOERROR) {
|
||||
if(!infra_rtt_update(sq->outnet->infra, &sq->addr,
|
||||
sq->addrlen, sq->zone, sq->zonelen, sq->qtype,
|
||||
-1, sq->last_rtt, (time_t)now.tv_sec))
|
||||
log_err("out of memory in TCP exponential backoff.");
|
||||
} else if(now.tv_sec > sq->last_sent_time.tv_sec ||
|
||||
(now.tv_sec == sq->last_sent_time.tv_sec &&
|
||||
now.tv_usec > sq->last_sent_time.tv_usec)) {
|
||||
/* convert from microseconds to milliseconds */
|
||||
@@ -1754,7 +1827,7 @@ serviced_tcp_callback(struct comm_point* c, void* arg, int error,
|
||||
log_assert(roundtime >= 0);
|
||||
/* only store if less then AUTH_TIMEOUT seconds, it could be
|
||||
* huge due to system-hibernated and we woke up */
|
||||
if(roundtime < TCP_AUTH_QUERY_TIMEOUT*1000) {
|
||||
if(roundtime < 60000) {
|
||||
if(!infra_rtt_update(sq->outnet->infra, &sq->addr,
|
||||
sq->addrlen, sq->zone, sq->zonelen, sq->qtype,
|
||||
roundtime, sq->last_rtt, (time_t)now.tv_sec))
|
||||
@@ -1795,18 +1868,26 @@ serviced_tcp_initiate(struct serviced_query* sq, sldns_buffer* buff)
|
||||
static int
|
||||
serviced_tcp_send(struct serviced_query* sq, sldns_buffer* buff)
|
||||
{
|
||||
int vs, rtt;
|
||||
int vs, rtt, timeout;
|
||||
uint8_t edns_lame_known;
|
||||
if(!infra_host(sq->outnet->infra, &sq->addr, sq->addrlen, sq->zone,
|
||||
sq->zonelen, *sq->outnet->now_secs, &vs, &edns_lame_known,
|
||||
&rtt))
|
||||
return 0;
|
||||
sq->last_rtt = rtt;
|
||||
if(vs != -1)
|
||||
sq->status = serviced_query_TCP_EDNS;
|
||||
else sq->status = serviced_query_TCP;
|
||||
serviced_encode(sq, buff, sq->status == serviced_query_TCP_EDNS);
|
||||
sq->last_sent_time = *sq->outnet->now_tv;
|
||||
sq->pending = pending_tcp_query(sq, buff, TCP_AUTH_QUERY_TIMEOUT,
|
||||
if(sq->tcp_upstream || sq->ssl_upstream) {
|
||||
timeout = rtt;
|
||||
if(rtt >= 376 && rtt < TCP_AUTH_QUERY_TIMEOUT)
|
||||
timeout = TCP_AUTH_QUERY_TIMEOUT;
|
||||
} else {
|
||||
timeout = TCP_AUTH_QUERY_TIMEOUT;
|
||||
}
|
||||
sq->pending = pending_tcp_query(sq, buff, timeout,
|
||||
serviced_tcp_callback, sq);
|
||||
return sq->pending != NULL;
|
||||
}
|
||||
@@ -2015,7 +2096,7 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
|
||||
struct serviced_query*
|
||||
outnet_serviced_query(struct outside_network* outnet,
|
||||
struct query_info* qinfo, uint16_t flags, int dnssec, int want_dnssec,
|
||||
int nocaps, int tcp_upstream, int ssl_upstream,
|
||||
int nocaps, int tcp_upstream, int ssl_upstream, char* tls_auth_name,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
|
||||
size_t zonelen, struct module_qstate* qstate,
|
||||
comm_point_callback_type* callback, void* callback_arg, sldns_buffer* buff,
|
||||
@@ -2038,8 +2119,9 @@ outnet_serviced_query(struct outside_network* outnet,
|
||||
if(!sq) {
|
||||
/* make new serviced query entry */
|
||||
sq = serviced_create(outnet, buff, dnssec, want_dnssec, nocaps,
|
||||
tcp_upstream, ssl_upstream, addr, addrlen, zone,
|
||||
zonelen, (int)qinfo->qtype, qstate->edns_opts_back_out);
|
||||
tcp_upstream, ssl_upstream, tls_auth_name, addr,
|
||||
addrlen, zone, zonelen, (int)qinfo->qtype,
|
||||
qstate->edns_opts_back_out);
|
||||
if(!sq) {
|
||||
free(cb);
|
||||
return NULL;
|
||||
@@ -2101,6 +2183,215 @@ void outnet_serviced_query_stop(struct serviced_query* sq, void* cb_arg)
|
||||
}
|
||||
}
|
||||
|
||||
/** create fd to send to this destination */
|
||||
static int
|
||||
fd_for_dest(struct outside_network* outnet, struct sockaddr_storage* to_addr,
|
||||
socklen_t to_addrlen)
|
||||
{
|
||||
struct sockaddr_storage* addr;
|
||||
socklen_t addrlen;
|
||||
int i;
|
||||
int try;
|
||||
|
||||
/* select interface */
|
||||
if(addr_is_ip6(to_addr, to_addrlen)) {
|
||||
if(outnet->num_ip6 == 0) {
|
||||
char to[64];
|
||||
addr_to_str(to_addr, to_addrlen, to, sizeof(to));
|
||||
verbose(VERB_QUERY, "need ipv6 to send, but no ipv6 outgoing interfaces, for %s", to);
|
||||
return -1;
|
||||
}
|
||||
i = ub_random_max(outnet->rnd, outnet->num_ip6);
|
||||
addr = &outnet->ip6_ifs[i].addr;
|
||||
addrlen = outnet->ip6_ifs[i].addrlen;
|
||||
} else {
|
||||
if(outnet->num_ip4 == 0) {
|
||||
char to[64];
|
||||
addr_to_str(to_addr, to_addrlen, to, sizeof(to));
|
||||
verbose(VERB_QUERY, "need ipv4 to send, but no ipv4 outgoing interfaces, for %s", to);
|
||||
return -1;
|
||||
}
|
||||
i = ub_random_max(outnet->rnd, outnet->num_ip4);
|
||||
addr = &outnet->ip4_ifs[i].addr;
|
||||
addrlen = outnet->ip4_ifs[i].addrlen;
|
||||
}
|
||||
|
||||
/* create fd */
|
||||
for(try = 0; try<1000; try++) {
|
||||
int freebind = 0;
|
||||
int noproto = 0;
|
||||
int inuse = 0;
|
||||
int port = ub_random(outnet->rnd)&0xffff;
|
||||
int fd = -1;
|
||||
if(addr_is_ip6(to_addr, to_addrlen)) {
|
||||
struct sockaddr_in6 sa = *(struct sockaddr_in6*)addr;
|
||||
sa.sin6_port = (in_port_t)htons((uint16_t)port);
|
||||
fd = create_udp_sock(AF_INET6, SOCK_DGRAM,
|
||||
(struct sockaddr*)&sa, addrlen, 1, &inuse, &noproto,
|
||||
0, 0, 0, NULL, 0, freebind, 0);
|
||||
} else {
|
||||
struct sockaddr_in* sa = (struct sockaddr_in*)addr;
|
||||
sa->sin_port = (in_port_t)htons((uint16_t)port);
|
||||
fd = create_udp_sock(AF_INET, SOCK_DGRAM,
|
||||
(struct sockaddr*)addr, addrlen, 1, &inuse, &noproto,
|
||||
0, 0, 0, NULL, 0, freebind, 0);
|
||||
}
|
||||
if(fd != -1) {
|
||||
return fd;
|
||||
}
|
||||
if(!inuse) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
/* too many tries */
|
||||
log_err("cannot send probe, ports are in use");
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct comm_point*
|
||||
outnet_comm_point_for_udp(struct outside_network* outnet,
|
||||
comm_point_callback_type* cb, void* cb_arg,
|
||||
struct sockaddr_storage* to_addr, socklen_t to_addrlen)
|
||||
{
|
||||
struct comm_point* cp;
|
||||
int fd = fd_for_dest(outnet, to_addr, to_addrlen);
|
||||
if(fd == -1) {
|
||||
return NULL;
|
||||
}
|
||||
cp = comm_point_create_udp(outnet->base, fd, outnet->udp_buff,
|
||||
cb, cb_arg);
|
||||
if(!cp) {
|
||||
log_err("malloc failure");
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
return cp;
|
||||
}
|
||||
|
||||
struct comm_point*
|
||||
outnet_comm_point_for_tcp(struct outside_network* outnet,
|
||||
comm_point_callback_type* cb, void* cb_arg,
|
||||
struct sockaddr_storage* to_addr, socklen_t to_addrlen,
|
||||
sldns_buffer* query, int timeout)
|
||||
{
|
||||
struct comm_point* cp;
|
||||
int fd = outnet_get_tcp_fd(to_addr, to_addrlen, outnet->tcp_mss);
|
||||
if(fd == -1) {
|
||||
return 0;
|
||||
}
|
||||
fd_set_nonblock(fd);
|
||||
if(!outnet_tcp_connect(fd, to_addr, to_addrlen)) {
|
||||
/* outnet_tcp_connect has closed fd on error for us */
|
||||
return 0;
|
||||
}
|
||||
cp = comm_point_create_tcp_out(outnet->base, 65552, cb, cb_arg);
|
||||
if(!cp) {
|
||||
log_err("malloc failure");
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
cp->repinfo.addrlen = to_addrlen;
|
||||
memcpy(&cp->repinfo.addr, to_addr, to_addrlen);
|
||||
/* set timeout on TCP connection */
|
||||
comm_point_start_listening(cp, fd, timeout);
|
||||
/* copy scratch buffer to cp->buffer */
|
||||
sldns_buffer_copy(cp->buffer, query);
|
||||
return cp;
|
||||
}
|
||||
|
||||
/** setup http request headers in buffer for sending query to destination */
|
||||
static int
|
||||
setup_http_request(sldns_buffer* buf, char* host, char* path)
|
||||
{
|
||||
sldns_buffer_clear(buf);
|
||||
sldns_buffer_printf(buf, "GET /%s HTTP/1.1\r\n", path);
|
||||
sldns_buffer_printf(buf, "Host: %s\r\n", host);
|
||||
sldns_buffer_printf(buf, "User-Agent: unbound/%s\r\n",
|
||||
PACKAGE_VERSION);
|
||||
/* We do not really do multiple queries per connection,
|
||||
* but this header setting is also not needed.
|
||||
* sldns_buffer_printf(buf, "Connection: close\r\n") */
|
||||
sldns_buffer_printf(buf, "\r\n");
|
||||
if(sldns_buffer_position(buf)+10 > sldns_buffer_capacity(buf))
|
||||
return 0; /* somehow buffer too short, but it is about 60K
|
||||
and the request is only a couple bytes long. */
|
||||
sldns_buffer_flip(buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct comm_point*
|
||||
outnet_comm_point_for_http(struct outside_network* outnet,
|
||||
comm_point_callback_type* cb, void* cb_arg,
|
||||
struct sockaddr_storage* to_addr, socklen_t to_addrlen, int timeout,
|
||||
int ssl, char* host, char* path)
|
||||
{
|
||||
/* cp calls cb with err=NETEVENT_DONE when transfer is done */
|
||||
struct comm_point* cp;
|
||||
int fd = outnet_get_tcp_fd(to_addr, to_addrlen, outnet->tcp_mss);
|
||||
if(fd == -1) {
|
||||
return 0;
|
||||
}
|
||||
fd_set_nonblock(fd);
|
||||
if(!outnet_tcp_connect(fd, to_addr, to_addrlen)) {
|
||||
/* outnet_tcp_connect has closed fd on error for us */
|
||||
return 0;
|
||||
}
|
||||
cp = comm_point_create_http_out(outnet->base, 65552, cb, cb_arg,
|
||||
outnet->udp_buff);
|
||||
if(!cp) {
|
||||
log_err("malloc failure");
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
cp->repinfo.addrlen = to_addrlen;
|
||||
memcpy(&cp->repinfo.addr, to_addr, to_addrlen);
|
||||
|
||||
/* setup for SSL (if needed) */
|
||||
if(ssl) {
|
||||
cp->ssl = outgoing_ssl_fd(outnet->sslctx, fd);
|
||||
if(!cp->ssl) {
|
||||
log_err("cannot setup https");
|
||||
comm_point_delete(cp);
|
||||
return NULL;
|
||||
}
|
||||
#ifdef USE_WINSOCK
|
||||
comm_point_tcp_win_bio_cb(cp, cp->ssl);
|
||||
#endif
|
||||
cp->ssl_shake_state = comm_ssl_shake_write;
|
||||
/* https verification */
|
||||
#ifdef HAVE_SSL_SET1_HOST
|
||||
if((SSL_CTX_get_verify_mode(outnet->sslctx)&SSL_VERIFY_PEER)) {
|
||||
/* because we set SSL_VERIFY_PEER, in netevent in
|
||||
* ssl_handshake, it'll check if the certificate
|
||||
* verification has succeeded */
|
||||
/* SSL_VERIFY_PEER is set on the sslctx */
|
||||
/* and the certificates to verify with are loaded into
|
||||
* it with SSL_load_verify_locations or
|
||||
* SSL_CTX_set_default_verify_paths */
|
||||
/* setting the hostname makes openssl verify the
|
||||
* host name in the x509 certificate in the
|
||||
* SSL connection*/
|
||||
if(!SSL_set1_host(cp->ssl, host)) {
|
||||
log_err("SSL_set1_host failed");
|
||||
comm_point_delete(cp);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_SSL_SET1_HOST */
|
||||
}
|
||||
|
||||
/* set timeout on TCP connection */
|
||||
comm_point_start_listening(cp, fd, timeout);
|
||||
|
||||
/* setup http request in cp->buffer */
|
||||
if(!setup_http_request(cp->buffer, host, path)) {
|
||||
log_err("error setting up http request");
|
||||
comm_point_delete(cp);
|
||||
return NULL;
|
||||
}
|
||||
return cp;
|
||||
}
|
||||
|
||||
/** get memory used by waiting tcp entry (in use or not) */
|
||||
static size_t
|
||||
waiting_tcp_get_mem(struct waiting_tcp* w)
|
||||
|
||||
@@ -290,6 +290,8 @@ struct waiting_tcp {
|
||||
void* cb_arg;
|
||||
/** if it uses ssl upstream */
|
||||
int ssl_upstream;
|
||||
/** ref to the tls_auth_name from the serviced_query */
|
||||
char* tls_auth_name;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -332,6 +334,9 @@ struct serviced_query {
|
||||
int nocaps;
|
||||
/** tcp upstream used, use tcp, or ssl_upstream for SSL */
|
||||
int tcp_upstream, ssl_upstream;
|
||||
/** the name of the tls authentication name, eg. 'ns.example.com'
|
||||
* or NULL */
|
||||
char* tls_auth_name;
|
||||
/** where to send it */
|
||||
struct sockaddr_storage addr;
|
||||
/** length of addr field in use. */
|
||||
@@ -371,7 +376,7 @@ struct serviced_query {
|
||||
int retry;
|
||||
/** time last UDP was sent */
|
||||
struct timeval last_sent_time;
|
||||
/** rtt of last (UDP) message */
|
||||
/** rtt of last message */
|
||||
int last_rtt;
|
||||
/** do we know edns probe status already, for UDP_EDNS queries */
|
||||
int edns_lame_known;
|
||||
@@ -451,7 +456,7 @@ struct pending* pending_udp_query(struct serviced_query* sq,
|
||||
* checks id.
|
||||
* @param sq: serviced query.
|
||||
* @param packet: wireformat query to send to destination. copied from.
|
||||
* @param timeout: in seconds from now.
|
||||
* @param timeout: in milliseconds from now.
|
||||
* Timer starts running now. Timer may expire if all buffers are used,
|
||||
* without any query been sent to the server yet.
|
||||
* @param callback: function to call on error, timeout or reply.
|
||||
@@ -484,6 +489,8 @@ void pending_delete(struct outside_network* outnet, struct pending* p);
|
||||
* @param nocaps: ignore use_caps_for_id and use unperturbed qname.
|
||||
* @param tcp_upstream: use TCP for upstream queries.
|
||||
* @param ssl_upstream: use SSL for upstream queries.
|
||||
* @param tls_auth_name: when ssl_upstream is true, use this name to check
|
||||
* the server's peer certificate.
|
||||
* @param addr: to which server to send the query.
|
||||
* @param addrlen: length of addr.
|
||||
* @param zone: name of the zone of the delegation point. wireformat dname.
|
||||
@@ -501,7 +508,7 @@ void pending_delete(struct outside_network* outnet, struct pending* p);
|
||||
*/
|
||||
struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
|
||||
struct query_info* qinfo, uint16_t flags, int dnssec, int want_dnssec,
|
||||
int nocaps, int tcp_upstream, int ssl_upstream,
|
||||
int nocaps, int tcp_upstream, int ssl_upstream, char* tls_auth_name,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
|
||||
size_t zonelen, struct module_qstate* qstate,
|
||||
comm_point_callback_type* callback, void* callback_arg,
|
||||
@@ -533,6 +540,70 @@ size_t outnet_get_mem(struct outside_network* outnet);
|
||||
*/
|
||||
size_t serviced_get_mem(struct serviced_query* sq);
|
||||
|
||||
/** get TCP file descriptor for address, returns -1 on failure,
|
||||
* tcp_mss is 0 or maxseg size to set for TCP packets. */
|
||||
int outnet_get_tcp_fd(struct sockaddr_storage* addr, socklen_t addrlen, int tcp_mss);
|
||||
|
||||
/**
|
||||
* Create udp commpoint suitable for sending packets to the destination.
|
||||
* @param outnet: outside_network with the comm_base it is attached to,
|
||||
* with the outgoing interfaces chosen from, and rnd gen for random.
|
||||
* @param cb: callback function for the commpoint.
|
||||
* @param cb_arg: callback argument for cb.
|
||||
* @param to_addr: intended destination.
|
||||
* @param to_addrlen: length of to_addr.
|
||||
* @return commpoint that you can comm_point_send_udp_msg with, or NULL.
|
||||
*/
|
||||
struct comm_point* outnet_comm_point_for_udp(struct outside_network* outnet,
|
||||
comm_point_callback_type* cb, void* cb_arg,
|
||||
struct sockaddr_storage* to_addr, socklen_t to_addrlen);
|
||||
|
||||
/**
|
||||
* Create tcp commpoint suitable for communication to the destination.
|
||||
* It also performs connect() to the to_addr.
|
||||
* @param outnet: outside_network with the comm_base it is attached to,
|
||||
* and the tcp_mss.
|
||||
* @param cb: callback function for the commpoint.
|
||||
* @param cb_arg: callback argument for cb.
|
||||
* @param to_addr: intended destination.
|
||||
* @param to_addrlen: length of to_addr.
|
||||
* @param query: initial packet to send writing, in buffer. It is copied
|
||||
* to the commpoint buffer that is created.
|
||||
* @param timeout: timeout for the TCP connection.
|
||||
* timeout in milliseconds, or -1 for no (change to the) timeout.
|
||||
* So seconds*1000.
|
||||
* @return tcp_out commpoint, or NULL.
|
||||
*/
|
||||
struct comm_point* outnet_comm_point_for_tcp(struct outside_network* outnet,
|
||||
comm_point_callback_type* cb, void* cb_arg,
|
||||
struct sockaddr_storage* to_addr, socklen_t to_addrlen,
|
||||
struct sldns_buffer* query, int timeout);
|
||||
|
||||
/**
|
||||
* Create http commpoint suitable for communication to the destination.
|
||||
* Creates the http request buffer. It also performs connect() to the to_addr.
|
||||
* @param outnet: outside_network with the comm_base it is attached to,
|
||||
* and the tcp_mss.
|
||||
* @param cb: callback function for the commpoint.
|
||||
* @param cb_arg: callback argument for cb.
|
||||
* @param to_addr: intended destination.
|
||||
* @param to_addrlen: length of to_addr.
|
||||
* @param timeout: timeout for the TCP connection.
|
||||
* timeout in milliseconds, or -1 for no (change to the) timeout.
|
||||
* So seconds*1000.
|
||||
* @param ssl: set to true for https.
|
||||
* @param host: hostname to use for the destination. part of http request.
|
||||
* @param path: pathname to lookup, eg. name of the file on the destination.
|
||||
* @return http_out commpoint, or NULL.
|
||||
*/
|
||||
struct comm_point* outnet_comm_point_for_http(struct outside_network* outnet,
|
||||
comm_point_callback_type* cb, void* cb_arg,
|
||||
struct sockaddr_storage* to_addr, socklen_t to_addrlen, int timeout,
|
||||
int ssl, char* host, char* path);
|
||||
|
||||
/** connect tcp connection to addr, 0 on failure */
|
||||
int outnet_tcp_connect(int s, struct sockaddr_storage* addr, socklen_t addrlen);
|
||||
|
||||
/** callback for incoming udp answers from the network */
|
||||
int outnet_udp_cb(struct comm_point* c, void* arg, int error,
|
||||
struct comm_reply *reply_info);
|
||||
|
||||
@@ -89,6 +89,14 @@ sldns_rr_dnskey_key_size_raw(const unsigned char* keydata,
|
||||
return 256;
|
||||
case LDNS_ECDSAP384SHA384:
|
||||
return 384;
|
||||
#endif
|
||||
#ifdef USE_ED25519
|
||||
case LDNS_ED25519:
|
||||
return 256;
|
||||
#endif
|
||||
#ifdef USE_ED448
|
||||
case LDNS_ED448:
|
||||
return 456;
|
||||
#endif
|
||||
default:
|
||||
return 0;
|
||||
@@ -409,6 +417,27 @@ sldns_ed255192pkey_raw(const unsigned char* key, size_t keylen)
|
||||
}
|
||||
#endif /* USE_ED25519 */
|
||||
|
||||
#ifdef USE_ED448
|
||||
EVP_PKEY*
|
||||
sldns_ed4482pkey_raw(const unsigned char* key, size_t keylen)
|
||||
{
|
||||
/* ASN1 for ED448 is 3043300506032b6571033a00 <57byteskey> */
|
||||
uint8_t pre[] = {0x30, 0x43, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65,
|
||||
0x71, 0x03, 0x3a, 0x00};
|
||||
int pre_len = 12;
|
||||
uint8_t buf[256];
|
||||
EVP_PKEY *evp_key;
|
||||
/* pp gets modified by d2i() */
|
||||
const unsigned char* pp = (unsigned char*)buf;
|
||||
if(keylen != 57 || keylen + pre_len > sizeof(buf))
|
||||
return NULL; /* wrong length */
|
||||
memmove(buf, pre, pre_len);
|
||||
memmove(buf+pre_len, key, keylen);
|
||||
evp_key = d2i_PUBKEY(NULL, &pp, (int)(pre_len+keylen));
|
||||
return evp_key;
|
||||
}
|
||||
#endif /* USE_ED448 */
|
||||
|
||||
int
|
||||
sldns_digest_evp(unsigned char* data, unsigned int len, unsigned char* dest,
|
||||
const EVP_MD* md)
|
||||
|
||||
@@ -101,6 +101,15 @@ RSA *sldns_key_buf2rsa_raw(unsigned char* key, size_t len);
|
||||
*/
|
||||
EVP_PKEY* sldns_ed255192pkey_raw(const unsigned char* key, size_t len);
|
||||
|
||||
/**
|
||||
* Converts a holding buffer with key material to EVP PKEY in openssl.
|
||||
* Only available if ldns was compiled with ED448.
|
||||
* \param[in] key the uncompressed wireformat of the key.
|
||||
* \param[in] len length of key data
|
||||
* \return the key or NULL on error.
|
||||
*/
|
||||
EVP_PKEY* sldns_ed4482pkey_raw(const unsigned char* key, size_t len);
|
||||
|
||||
/**
|
||||
* Utility function to calculate hash using generic EVP_MD pointer.
|
||||
* \param[in] data the data to hash.
|
||||
|
||||
+21
-3
@@ -836,7 +836,7 @@ const char* sldns_get_errorstr_parse(int e)
|
||||
}
|
||||
|
||||
/* Strip whitespace from the start and the end of <line>. */
|
||||
static char *
|
||||
char *
|
||||
sldns_strip_ws(char *line)
|
||||
{
|
||||
char *s = line, *e;
|
||||
@@ -906,7 +906,7 @@ int sldns_fp2wire_rr_buf(FILE* in, uint8_t* rr, size_t* len, size_t* dname_len,
|
||||
*dname_len = 0;
|
||||
return LDNS_WIREPARSE_ERR_INCLUDE;
|
||||
} else {
|
||||
return sldns_str2wire_rr_buf(line, rr, len, dname_len,
|
||||
int r = sldns_str2wire_rr_buf(line, rr, len, dname_len,
|
||||
parse_state?parse_state->default_ttl:0,
|
||||
(parse_state&&parse_state->origin_len)?
|
||||
parse_state->origin:NULL,
|
||||
@@ -914,6 +914,13 @@ int sldns_fp2wire_rr_buf(FILE* in, uint8_t* rr, size_t* len, size_t* dname_len,
|
||||
(parse_state&&parse_state->prev_rr_len)?
|
||||
parse_state->prev_rr:NULL,
|
||||
parse_state?parse_state->prev_rr_len:0);
|
||||
if(r == LDNS_WIREPARSE_ERR_OK && (*dname_len) != 0 &&
|
||||
parse_state &&
|
||||
(*dname_len) <= sizeof(parse_state->prev_rr)) {
|
||||
memmove(parse_state->prev_rr, rr, *dname_len);
|
||||
parse_state->prev_rr_len = (*dname_len);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
return LDNS_WIREPARSE_ERR_OK;
|
||||
}
|
||||
@@ -1218,6 +1225,17 @@ int sldns_str2wire_b32_ext_buf(const char* str, uint8_t* rd, size_t* len)
|
||||
return LDNS_WIREPARSE_ERR_OK;
|
||||
}
|
||||
|
||||
/** see if the string ends, or ends in whitespace */
|
||||
static int
|
||||
sldns_is_last_of_string(const char* str)
|
||||
{
|
||||
if(*str == 0) return 1;
|
||||
while(isspace((unsigned char)*str))
|
||||
str++;
|
||||
if(*str == 0) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sldns_str2wire_hex_buf(const char* str, uint8_t* rd, size_t* len)
|
||||
{
|
||||
const char* s = str;
|
||||
@@ -1227,7 +1245,7 @@ int sldns_str2wire_hex_buf(const char* str, uint8_t* rd, size_t* len)
|
||||
s++;
|
||||
continue;
|
||||
}
|
||||
if(dlen == 0 && *s == '0' && *(s+1) == 0) {
|
||||
if(dlen == 0 && *s == '0' && sldns_is_last_of_string(s+1)) {
|
||||
*len = 0;
|
||||
return LDNS_WIREPARSE_ERR_OK;
|
||||
}
|
||||
|
||||
@@ -554,6 +554,12 @@ int sldns_str2wire_hip_buf(const char* str, uint8_t* rd, size_t* len);
|
||||
*/
|
||||
int sldns_str2wire_int16_data_buf(const char* str, uint8_t* rd, size_t* len);
|
||||
|
||||
/**
|
||||
* Strip whitespace from the start and the end of line.
|
||||
* @param line: modified with 0 to shorten it.
|
||||
* @return new start with spaces skipped.
|
||||
*/
|
||||
char * sldns_strip_ws(char *line);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -255,6 +255,12 @@ int sldns_wire2str_rr_buf(uint8_t* d, size_t dlen, char* s, size_t slen)
|
||||
return sldns_wire2str_rr_scan(&d, &dlen, &s, &slen, NULL, 0);
|
||||
}
|
||||
|
||||
int sldns_wire2str_rrquestion_buf(uint8_t* d, size_t dlen, char* s, size_t slen)
|
||||
{
|
||||
/* use arguments as temporary variables */
|
||||
return sldns_wire2str_rrquestion_scan(&d, &dlen, &s, &slen, NULL, 0);
|
||||
}
|
||||
|
||||
int sldns_wire2str_rdata_buf(uint8_t* rdata, size_t rdata_len, char* str,
|
||||
size_t str_len, uint16_t rrtype)
|
||||
{
|
||||
|
||||
@@ -358,6 +358,22 @@ int sldns_wire2str_edns_option_code_print(char** str, size_t* str_len,
|
||||
int sldns_wire2str_rr_buf(uint8_t* rr, size_t rr_len, char* str,
|
||||
size_t str_len);
|
||||
|
||||
/**
|
||||
* Convert question RR to string presentation format, on one line. User buffer.
|
||||
* @param rr: wireformat RR data
|
||||
* @param rr_len: length of the rr wire data.
|
||||
* @param str: the string buffer to write to.
|
||||
* If you pass NULL as the str, the return value of the function is
|
||||
* the str_len you need for the entire packet. It does not include
|
||||
* the 0 byte at the end.
|
||||
* @param str_len: the size of the string buffer. If more is needed, it'll
|
||||
* silently truncate the output to fit in the buffer.
|
||||
* @return the number of characters for this element, excluding zerobyte.
|
||||
* Is larger or equal than str_len if output was truncated.
|
||||
*/
|
||||
int sldns_wire2str_rrquestion_buf(uint8_t* rr, size_t rr_len, char* str,
|
||||
size_t str_len);
|
||||
|
||||
/**
|
||||
* 3597 printout of an RR in unknown rr format.
|
||||
* There are more format and comment options available for printout
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
#include "validator/validator.h"
|
||||
#include "services/localzone.h"
|
||||
#include "services/view.h"
|
||||
#include "services/authzone.h"
|
||||
#include "respip/respip.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
#ifdef HAVE_GETOPT_H
|
||||
@@ -108,6 +109,16 @@ print_option(struct config_file* cfg, const char* opt, int final)
|
||||
free(p);
|
||||
return;
|
||||
}
|
||||
if(strcmp(opt, "auto-trust-anchor-file") == 0 && final) {
|
||||
struct config_strlist* s = cfg->auto_trust_anchor_file_list;
|
||||
for(; s; s=s->next) {
|
||||
char *p = fname_after_chroot(s->str, cfg, 1);
|
||||
if(!p) fatal_exit("out of memory");
|
||||
printf("%s\n", p);
|
||||
free(p);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(!config_get_option(cfg, opt, config_print_func, stdout))
|
||||
fatal_exit("cannot print option '%s'", opt);
|
||||
}
|
||||
@@ -531,7 +542,7 @@ morechecks(struct config_file* cfg, const char* fname)
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
if(cfg->remote_control_enable && cfg->remote_control_use_cert) {
|
||||
if(cfg->remote_control_enable && options_remote_is_address(cfg)) {
|
||||
check_chroot_string("server-key-file", &cfg->server_key_file,
|
||||
cfg->chrootdir, cfg);
|
||||
check_chroot_string("server-cert-file", &cfg->server_cert_file,
|
||||
@@ -573,6 +584,17 @@ check_hints(struct config_file* cfg)
|
||||
hints_delete(hints);
|
||||
}
|
||||
|
||||
/** check auth zones */
|
||||
static void
|
||||
check_auth(struct config_file* cfg)
|
||||
{
|
||||
struct auth_zones* az = auth_zones_create();
|
||||
if(!az || !auth_zones_apply_cfg(az, cfg, 0)) {
|
||||
fatal_exit("Could not setup authority zones");
|
||||
}
|
||||
auth_zones_delete(az);
|
||||
}
|
||||
|
||||
/** check config file */
|
||||
static void
|
||||
checkconf(const char* cfgfile, const char* opt, int final)
|
||||
@@ -607,6 +629,7 @@ checkconf(const char* cfgfile, const char* opt, int final)
|
||||
#endif
|
||||
check_fwd(cfg);
|
||||
check_hints(cfg);
|
||||
check_auth(cfg);
|
||||
printf("unbound-checkconf: no errors in %s\n", cfgfile);
|
||||
config_delete(cfg);
|
||||
}
|
||||
|
||||
+104
-74
@@ -142,6 +142,7 @@ usage(void)
|
||||
printf(" ratelimit_list [+a] list ratelimited domains\n");
|
||||
printf(" ip_ratelimit_list [+a] list ratelimited ip addresses\n");
|
||||
printf(" +a list all, also not ratelimited\n");
|
||||
printf(" list_auth_zones list auth zones\n");
|
||||
printf(" view_list_local_zones view list local-zones in view\n");
|
||||
printf(" view_list_local_data view list local-data RRs in view\n");
|
||||
printf(" view_local_zone view name type add local-zone in view\n");
|
||||
@@ -349,6 +350,8 @@ static void print_extended(struct ub_stats_info* s)
|
||||
PR_UL("num.answer.secure", s->svr.ans_secure);
|
||||
PR_UL("num.answer.bogus", s->svr.ans_bogus);
|
||||
PR_UL("num.rrset.bogus", s->svr.rrset_bogus);
|
||||
PR_UL("num.query.aggressive.NOERROR", s->svr.num_neg_cache_noerror);
|
||||
PR_UL("num.query.aggressive.NXDOMAIN", s->svr.num_neg_cache_nxdomain);
|
||||
/* threat detection */
|
||||
PR_UL("unwanted.queries", s->svr.unwanted_queries);
|
||||
PR_UL("unwanted.replies", s->svr.unwanted_replies);
|
||||
@@ -366,6 +369,8 @@ static void print_extended(struct ub_stats_info* s)
|
||||
PR_UL("num.query.dnscrypt.replay",
|
||||
s->svr.num_query_dnscrypt_replay);
|
||||
#endif /* USE_DNSCRYPT */
|
||||
PR_UL("num.query.authzone.up", s->svr.num_query_authzone_up);
|
||||
PR_UL("num.query.authzone.down", s->svr.num_query_authzone_down);
|
||||
}
|
||||
|
||||
/** print statistics out of memory structures */
|
||||
@@ -446,42 +451,33 @@ setup_ctx(struct config_file* cfg)
|
||||
char* s_cert=NULL, *c_key=NULL, *c_cert=NULL;
|
||||
SSL_CTX* ctx;
|
||||
|
||||
if(cfg->remote_control_use_cert) {
|
||||
s_cert = fname_after_chroot(cfg->server_cert_file, cfg, 1);
|
||||
c_key = fname_after_chroot(cfg->control_key_file, cfg, 1);
|
||||
c_cert = fname_after_chroot(cfg->control_cert_file, cfg, 1);
|
||||
if(!s_cert || !c_key || !c_cert)
|
||||
fatal_exit("out of memory");
|
||||
}
|
||||
if(!(options_remote_is_address(cfg) && cfg->control_use_cert))
|
||||
return NULL;
|
||||
s_cert = fname_after_chroot(cfg->server_cert_file, cfg, 1);
|
||||
c_key = fname_after_chroot(cfg->control_key_file, cfg, 1);
|
||||
c_cert = fname_after_chroot(cfg->control_cert_file, cfg, 1);
|
||||
if(!s_cert || !c_key || !c_cert)
|
||||
fatal_exit("out of memory");
|
||||
ctx = SSL_CTX_new(SSLv23_client_method());
|
||||
if(!ctx)
|
||||
ssl_err("could not allocate SSL_CTX pointer");
|
||||
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");
|
||||
if(cfg->remote_control_use_cert) {
|
||||
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");
|
||||
if(!SSL_CTX_use_certificate_chain_file(ctx,c_cert) ||
|
||||
!SSL_CTX_use_PrivateKey_file(ctx,c_key,SSL_FILETYPE_PEM)
|
||||
|| !SSL_CTX_check_private_key(ctx))
|
||||
ssl_err("Error setting up SSL_CTX client key and cert");
|
||||
if (SSL_CTX_load_verify_locations(ctx, s_cert, NULL) != 1)
|
||||
ssl_err("Error setting up SSL_CTX verify, server cert");
|
||||
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
|
||||
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");
|
||||
if(!SSL_CTX_use_certificate_chain_file(ctx,c_cert) ||
|
||||
!SSL_CTX_use_PrivateKey_file(ctx,c_key,SSL_FILETYPE_PEM)
|
||||
|| !SSL_CTX_check_private_key(ctx))
|
||||
ssl_err("Error setting up SSL_CTX client key and cert");
|
||||
if (SSL_CTX_load_verify_locations(ctx, s_cert, NULL) != 1)
|
||||
ssl_err("Error setting up SSL_CTX verify, server cert");
|
||||
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
|
||||
|
||||
free(s_cert);
|
||||
free(c_key);
|
||||
free(c_cert);
|
||||
} else {
|
||||
/* Use ciphers that don't require authentication */
|
||||
#ifdef HAVE_SSL_CTX_SET_SECURITY_LEVEL
|
||||
SSL_CTX_set_security_level(ctx, 0);
|
||||
#endif
|
||||
if(!SSL_CTX_set_cipher_list(ctx, "aNULL, eNULL"))
|
||||
ssl_err("Error setting NULL cipher!");
|
||||
}
|
||||
free(s_cert);
|
||||
free(c_key);
|
||||
free(c_cert);
|
||||
return ctx;
|
||||
}
|
||||
|
||||
@@ -492,11 +488,11 @@ contact_server(const char* svr, struct config_file* cfg, int statuscmd)
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addrlen;
|
||||
int addrfamily = 0;
|
||||
int fd;
|
||||
int fd, useport = 1;
|
||||
/* use svr or the first config entry */
|
||||
if(!svr) {
|
||||
if(cfg->control_ifs) {
|
||||
svr = cfg->control_ifs->str;
|
||||
if(cfg->control_ifs.first) {
|
||||
svr = cfg->control_ifs.first->str;
|
||||
} else if(cfg->do_ip4) {
|
||||
svr = "127.0.0.1";
|
||||
} else {
|
||||
@@ -524,6 +520,7 @@ contact_server(const char* svr, struct config_file* cfg, int statuscmd)
|
||||
(void)strlcpy(usock->sun_path, svr, sizeof(usock->sun_path));
|
||||
addrlen = (socklen_t)sizeof(struct sockaddr_un);
|
||||
addrfamily = AF_LOCAL;
|
||||
useport = 0;
|
||||
#endif
|
||||
} else {
|
||||
if(!ipstrtoaddr(svr, cfg->control_port, &addr, &addrlen))
|
||||
@@ -542,14 +539,18 @@ contact_server(const char* svr, struct config_file* cfg, int statuscmd)
|
||||
}
|
||||
if(connect(fd, (struct sockaddr*)&addr, addrlen) < 0) {
|
||||
#ifndef USE_WINSOCK
|
||||
log_err_addr("connect", strerror(errno), &addr, addrlen);
|
||||
if(errno == ECONNREFUSED && statuscmd) {
|
||||
int err = errno;
|
||||
if(!useport) log_err("connect: %s for %s", strerror(err), svr);
|
||||
else log_err_addr("connect", strerror(err), &addr, addrlen);
|
||||
if(err == ECONNREFUSED && statuscmd) {
|
||||
printf("unbound is stopped\n");
|
||||
exit(3);
|
||||
}
|
||||
#else
|
||||
log_err_addr("connect", wsa_strerror(WSAGetLastError()), &addr, addrlen);
|
||||
if(WSAGetLastError() == WSAECONNREFUSED && statuscmd) {
|
||||
int wsaerr = WSAGetLastError();
|
||||
if(!useport) log_err("connect: %s for %s", wsa_strerror(wsaerr), svr);
|
||||
else log_err_addr("connect", wsa_strerror(wsaerr), &addr, addrlen);
|
||||
if(wsaerr == WSAECONNREFUSED && statuscmd) {
|
||||
printf("unbound is stopped\n");
|
||||
exit(3);
|
||||
}
|
||||
@@ -561,12 +562,13 @@ contact_server(const char* svr, struct config_file* cfg, int statuscmd)
|
||||
|
||||
/** setup SSL on the connection */
|
||||
static SSL*
|
||||
setup_ssl(SSL_CTX* ctx, int fd, struct config_file* cfg)
|
||||
setup_ssl(SSL_CTX* ctx, int fd)
|
||||
{
|
||||
SSL* ssl;
|
||||
X509* x;
|
||||
int r;
|
||||
|
||||
if(!ctx) return NULL;
|
||||
ssl = SSL_new(ctx);
|
||||
if(!ssl)
|
||||
ssl_err("could not SSL_new");
|
||||
@@ -587,78 +589,106 @@ setup_ssl(SSL_CTX* ctx, int fd, struct config_file* cfg)
|
||||
/* check authenticity of server */
|
||||
if(SSL_get_verify_result(ssl) != X509_V_OK)
|
||||
ssl_err("SSL verification failed");
|
||||
if(cfg->remote_control_use_cert) {
|
||||
x = SSL_get_peer_certificate(ssl);
|
||||
if(!x)
|
||||
ssl_err("Server presented no peer certificate");
|
||||
X509_free(x);
|
||||
}
|
||||
x = SSL_get_peer_certificate(ssl);
|
||||
if(!x)
|
||||
ssl_err("Server presented no peer certificate");
|
||||
X509_free(x);
|
||||
|
||||
return ssl;
|
||||
}
|
||||
|
||||
/** read from ssl or fd, fatalexit on error, 0 EOF, 1 success */
|
||||
static int
|
||||
remote_read(SSL* ssl, int fd, char* buf, size_t len)
|
||||
{
|
||||
if(ssl) {
|
||||
int r;
|
||||
ERR_clear_error();
|
||||
if((r = SSL_read(ssl, buf, (int)len-1)) <= 0) {
|
||||
if(SSL_get_error(ssl, r) == SSL_ERROR_ZERO_RETURN) {
|
||||
/* EOF */
|
||||
return 0;
|
||||
}
|
||||
ssl_err("could not SSL_read");
|
||||
}
|
||||
buf[r] = 0;
|
||||
} else {
|
||||
ssize_t rr = read(fd, buf, len-1);
|
||||
if(rr <= 0) {
|
||||
if(rr == 0) {
|
||||
/* EOF */
|
||||
return 0;
|
||||
}
|
||||
fatal_exit("could not read: %s", strerror(errno));
|
||||
}
|
||||
buf[rr] = 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** write to ssl or fd, fatalexit on error */
|
||||
static void
|
||||
remote_write(SSL* ssl, int fd, const char* buf, size_t len)
|
||||
{
|
||||
if(ssl) {
|
||||
if(SSL_write(ssl, buf, (int)len) <= 0)
|
||||
ssl_err("could not SSL_write");
|
||||
} else {
|
||||
if(write(fd, buf, len) < (ssize_t)len)
|
||||
fatal_exit("could not write: %s", strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
/** send stdin to server */
|
||||
static void
|
||||
send_file(SSL* ssl, FILE* in, char* buf, size_t sz)
|
||||
send_file(SSL* ssl, int fd, FILE* in, char* buf, size_t sz)
|
||||
{
|
||||
while(fgets(buf, (int)sz, in)) {
|
||||
if(SSL_write(ssl, buf, (int)strlen(buf)) <= 0)
|
||||
ssl_err("could not SSL_write contents");
|
||||
remote_write(ssl, fd, buf, strlen(buf));
|
||||
}
|
||||
}
|
||||
|
||||
/** send end-of-file marker to server */
|
||||
static void
|
||||
send_eof(SSL* ssl)
|
||||
send_eof(SSL* ssl, int fd)
|
||||
{
|
||||
char e[] = {0x04, 0x0a};
|
||||
if(SSL_write(ssl, e, (int)sizeof(e)) <= 0)
|
||||
ssl_err("could not SSL_write end-of-file marker");
|
||||
remote_write(ssl, fd, e, sizeof(e));
|
||||
}
|
||||
|
||||
/** send command and display result */
|
||||
static int
|
||||
go_cmd(SSL* ssl, int quiet, int argc, char* argv[])
|
||||
go_cmd(SSL* ssl, int fd, int quiet, int argc, char* argv[])
|
||||
{
|
||||
char pre[10];
|
||||
const char* space=" ";
|
||||
const char* newline="\n";
|
||||
int was_error = 0, first_line = 1;
|
||||
int r, i;
|
||||
int i;
|
||||
char buf[1024];
|
||||
snprintf(pre, sizeof(pre), "UBCT%d ", UNBOUND_CONTROL_VERSION);
|
||||
if(SSL_write(ssl, pre, (int)strlen(pre)) <= 0)
|
||||
ssl_err("could not SSL_write");
|
||||
remote_write(ssl, fd, pre, strlen(pre));
|
||||
for(i=0; i<argc; i++) {
|
||||
if(SSL_write(ssl, space, (int)strlen(space)) <= 0)
|
||||
ssl_err("could not SSL_write");
|
||||
if(SSL_write(ssl, argv[i], (int)strlen(argv[i])) <= 0)
|
||||
ssl_err("could not SSL_write");
|
||||
remote_write(ssl, fd, space, strlen(space));
|
||||
remote_write(ssl, fd, argv[i], strlen(argv[i]));
|
||||
}
|
||||
if(SSL_write(ssl, newline, (int)strlen(newline)) <= 0)
|
||||
ssl_err("could not SSL_write");
|
||||
remote_write(ssl, fd, newline, strlen(newline));
|
||||
|
||||
if(argc == 1 && strcmp(argv[0], "load_cache") == 0) {
|
||||
send_file(ssl, stdin, buf, sizeof(buf));
|
||||
send_file(ssl, fd, stdin, buf, sizeof(buf));
|
||||
}
|
||||
else if(argc == 1 && (strcmp(argv[0], "local_zones") == 0 ||
|
||||
strcmp(argv[0], "local_zones_remove") == 0 ||
|
||||
strcmp(argv[0], "local_datas") == 0 ||
|
||||
strcmp(argv[0], "local_datas_remove") == 0)) {
|
||||
send_file(ssl, stdin, buf, sizeof(buf));
|
||||
send_eof(ssl);
|
||||
send_file(ssl, fd, stdin, buf, sizeof(buf));
|
||||
send_eof(ssl, fd);
|
||||
}
|
||||
|
||||
while(1) {
|
||||
ERR_clear_error();
|
||||
if((r = SSL_read(ssl, buf, (int)sizeof(buf)-1)) <= 0) {
|
||||
if(SSL_get_error(ssl, r) == SSL_ERROR_ZERO_RETURN) {
|
||||
/* EOF */
|
||||
break;
|
||||
}
|
||||
ssl_err("could not SSL_read");
|
||||
if(remote_read(ssl, fd, buf, sizeof(buf)) == 0) {
|
||||
break; /* EOF */
|
||||
}
|
||||
buf[r] = 0;
|
||||
if(first_line && strncmp(buf, "error", 5) == 0) {
|
||||
printf("%s", buf);
|
||||
was_error = 1;
|
||||
@@ -693,18 +723,18 @@ go(const char* cfgfile, char* svr, int quiet, int argc, char* argv[])
|
||||
|
||||
/* contact server */
|
||||
fd = contact_server(svr, cfg, argc>0&&strcmp(argv[0],"status")==0);
|
||||
ssl = setup_ssl(ctx, fd, cfg);
|
||||
ssl = setup_ssl(ctx, fd);
|
||||
|
||||
/* send command */
|
||||
ret = go_cmd(ssl, quiet, argc, argv);
|
||||
ret = go_cmd(ssl, fd, quiet, argc, argv);
|
||||
|
||||
SSL_free(ssl);
|
||||
if(ssl) SSL_free(ssl);
|
||||
#ifndef USE_WINSOCK
|
||||
close(fd);
|
||||
#else
|
||||
closesocket(fd);
|
||||
#endif
|
||||
SSL_CTX_free(ctx);
|
||||
if(ctx) SSL_CTX_free(ctx);
|
||||
config_delete(cfg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -66,6 +66,14 @@
|
||||
/* nss3 */
|
||||
#include "nss.h"
|
||||
#endif
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL_SSL_H
|
||||
#include <openssl/ssl.h>
|
||||
#endif
|
||||
#ifdef HAVE_OPENSSL_ERR_H
|
||||
#include <openssl/err.h>
|
||||
#endif
|
||||
#endif /* HAVE_SSL */
|
||||
|
||||
/** verbosity for unbound-host app */
|
||||
static int verb = 0;
|
||||
@@ -487,6 +495,26 @@ int main(int argc, char* argv[])
|
||||
if(argc != 1)
|
||||
usage();
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_ERR_LOAD_CRYPTO_STRINGS
|
||||
ERR_load_crypto_strings();
|
||||
#endif
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL)
|
||||
ERR_load_SSL_strings();
|
||||
#endif
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_CRYPTO)
|
||||
OpenSSL_add_all_algorithms();
|
||||
#else
|
||||
OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS
|
||||
| OPENSSL_INIT_ADD_ALL_DIGESTS
|
||||
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
|
||||
#endif
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL)
|
||||
(void)SSL_library_init();
|
||||
#else
|
||||
(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL);
|
||||
#endif
|
||||
#endif /* HAVE_SSL */
|
||||
#ifdef HAVE_NSS
|
||||
if(NSS_NoDB_Init(".") != SECSuccess) {
|
||||
fprintf(stderr, "could not init NSS\n");
|
||||
|
||||
@@ -105,7 +105,7 @@ struct outbound_entry* worker_send_query(
|
||||
int ATTR_UNUSED(nocaps), struct sockaddr_storage* ATTR_UNUSED(addr),
|
||||
socklen_t ATTR_UNUSED(addrlen), uint8_t* ATTR_UNUSED(zone),
|
||||
size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(ssl_upstream),
|
||||
struct module_qstate* ATTR_UNUSED(q))
|
||||
char* ATTR_UNUSED(tls_auth_name), struct module_qstate* ATTR_UNUSED(q))
|
||||
{
|
||||
log_assert(0);
|
||||
return 0;
|
||||
@@ -137,7 +137,7 @@ struct outbound_entry* libworker_send_query(
|
||||
int ATTR_UNUSED(nocaps), struct sockaddr_storage* ATTR_UNUSED(addr),
|
||||
socklen_t ATTR_UNUSED(addrlen), uint8_t* ATTR_UNUSED(zone),
|
||||
size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(ssl_upstream),
|
||||
struct module_qstate* ATTR_UNUSED(q))
|
||||
char* ATTR_UNUSED(tls_auth_name), struct module_qstate* ATTR_UNUSED(q))
|
||||
{
|
||||
log_assert(0);
|
||||
return 0;
|
||||
|
||||
@@ -56,6 +56,15 @@
|
||||
#undef free
|
||||
#undef strdup
|
||||
#endif
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL_SSL_H
|
||||
#include <openssl/ssl.h>
|
||||
#endif
|
||||
#ifdef HAVE_OPENSSL_ERR_H
|
||||
#include <openssl/err.h>
|
||||
#endif
|
||||
#endif /* HAVE_SSL */
|
||||
|
||||
|
||||
/** keeping track of the async ids */
|
||||
struct track_id {
|
||||
@@ -459,6 +468,27 @@ int main(int argc, char** argv)
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_ERR_LOAD_CRYPTO_STRINGS
|
||||
ERR_load_crypto_strings();
|
||||
#endif
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL)
|
||||
ERR_load_SSL_strings();
|
||||
#endif
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_CRYPTO)
|
||||
OpenSSL_add_all_algorithms();
|
||||
#else
|
||||
OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS
|
||||
| OPENSSL_INIT_ADD_ALL_DIGESTS
|
||||
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
|
||||
#endif
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL)
|
||||
(void)SSL_library_init();
|
||||
#else
|
||||
(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL);
|
||||
#endif
|
||||
#endif /* HAVE_SSL */
|
||||
|
||||
if(ext)
|
||||
return ext_test(ctx, argc, argv);
|
||||
|
||||
|
||||
+391
-22
@@ -67,6 +67,29 @@
|
||||
struct worker;
|
||||
struct daemon_remote;
|
||||
|
||||
/** unique code to check that fake_commpoint is that structure */
|
||||
#define FAKE_COMMPOINT_TYPECODE 97347923
|
||||
/** fake commpoint, stores information */
|
||||
struct fake_commpoint {
|
||||
/** typecode */
|
||||
int typecode;
|
||||
/** if this is a udp outgoing type of commpoint */
|
||||
int type_udp_out;
|
||||
/** if this is a tcp outgoing type of commpoint */
|
||||
int type_tcp_out;
|
||||
/** if this is a http outgoing type of commpoint. */
|
||||
int type_http_out;
|
||||
|
||||
/** the callback, stored for usage */
|
||||
comm_point_callback_type* cb;
|
||||
/** the callback userarg, stored for usage */
|
||||
void* cb_arg;
|
||||
/** runtime ptr */
|
||||
struct replay_runtime* runtime;
|
||||
/** the pending entry for this commpoint (if any) */
|
||||
struct fake_pending* pending;
|
||||
};
|
||||
|
||||
/** Global variable: the scenario. Saved here for when event_init is done. */
|
||||
static struct replay_scenario* saved_scenario = NULL;
|
||||
|
||||
@@ -137,6 +160,7 @@ repevt_string(enum replay_event_type t)
|
||||
case repevt_back_reply: return "REPLY";
|
||||
case repevt_back_query: return "CHECK_OUT_QUERY";
|
||||
case repevt_autotrust_check: return "CHECK_AUTOTRUST";
|
||||
case repevt_tempfile_check: return "CHECK_TEMPFILE";
|
||||
case repevt_error: return "ERROR";
|
||||
case repevt_assign: return "ASSIGN";
|
||||
case repevt_traffic: return "TRAFFIC";
|
||||
@@ -247,7 +271,11 @@ pending_matches_range(struct replay_runtime* runtime,
|
||||
struct fake_pending* p = runtime->pending_list;
|
||||
/* slow, O(N*N), but it works as advertised with weird matching */
|
||||
while(p) {
|
||||
log_info("check of pending");
|
||||
if(p->tcp_pkt_counter != 0) {
|
||||
/* continue tcp transfer */
|
||||
*pend = p;
|
||||
return 1;
|
||||
}
|
||||
if(pending_find_match(runtime, entry, p)) {
|
||||
*pend = p;
|
||||
return 1;
|
||||
@@ -278,24 +306,46 @@ pending_list_delete(struct replay_runtime* runtime, struct fake_pending* pend)
|
||||
}
|
||||
}
|
||||
|
||||
/** number of replies in entry */
|
||||
static int
|
||||
count_reply_packets(struct entry* entry)
|
||||
{
|
||||
int count = 0;
|
||||
struct reply_packet* reppkt = entry->reply_list;
|
||||
while(reppkt) {
|
||||
count++;
|
||||
reppkt = reppkt->next;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill buffer with reply from the entry.
|
||||
*/
|
||||
static void
|
||||
fill_buffer_with_reply(sldns_buffer* buffer, struct entry* entry, uint8_t* q,
|
||||
size_t qlen)
|
||||
size_t qlen, int tcp_pkt_counter)
|
||||
{
|
||||
struct reply_packet* reppkt;
|
||||
uint8_t* c;
|
||||
size_t clen;
|
||||
log_assert(entry && entry->reply_list);
|
||||
sldns_buffer_clear(buffer);
|
||||
if(entry->reply_list->reply_from_hex) {
|
||||
c = sldns_buffer_begin(entry->reply_list->reply_from_hex);
|
||||
clen = sldns_buffer_limit(entry->reply_list->reply_from_hex);
|
||||
reppkt = entry->reply_list;
|
||||
if(tcp_pkt_counter > 0) {
|
||||
int i = tcp_pkt_counter;
|
||||
while(reppkt && i--)
|
||||
reppkt = reppkt->next;
|
||||
if(!reppkt) fatal_exit("extra packet read from TCP stream but none is available");
|
||||
log_pkt("extra_packet ", reppkt->reply_pkt, reppkt->reply_len);
|
||||
}
|
||||
if(reppkt->reply_from_hex) {
|
||||
c = sldns_buffer_begin(reppkt->reply_from_hex);
|
||||
clen = sldns_buffer_limit(reppkt->reply_from_hex);
|
||||
if(!c) fatal_exit("out of memory");
|
||||
} else {
|
||||
c = entry->reply_list->reply_pkt;
|
||||
clen = entry->reply_list->reply_len;
|
||||
c = reppkt->reply_pkt;
|
||||
clen = reppkt->reply_len;
|
||||
}
|
||||
if(c) {
|
||||
if(q) adjust_packet(entry, &c, &clen, q, qlen);
|
||||
@@ -326,12 +376,20 @@ answer_callback_from_entry(struct replay_runtime* runtime,
|
||||
c.type = comm_udp;
|
||||
if(pend->transport == transport_tcp)
|
||||
c.type = comm_tcp;
|
||||
fill_buffer_with_reply(c.buffer, entry, pend->pkt, pend->pkt_len);
|
||||
fill_buffer_with_reply(c.buffer, entry, pend->pkt, pend->pkt_len,
|
||||
pend->tcp_pkt_counter);
|
||||
repinfo.c = &c;
|
||||
repinfo.addrlen = pend->addrlen;
|
||||
memcpy(&repinfo.addr, &pend->addr, pend->addrlen);
|
||||
if(!pend->serviced)
|
||||
pending_list_delete(runtime, pend);
|
||||
if(!pend->serviced) {
|
||||
if(entry->reply_list->next &&
|
||||
pend->tcp_pkt_counter < count_reply_packets(entry)) {
|
||||
/* go to next packet next time */
|
||||
pend->tcp_pkt_counter++;
|
||||
} else {
|
||||
pending_list_delete(runtime, pend);
|
||||
}
|
||||
}
|
||||
if((*cb)(&c, cb_arg, NETEVENT_NOERROR, &repinfo)) {
|
||||
fatal_exit("testbound: unexpected: callback returned 1");
|
||||
}
|
||||
@@ -397,7 +455,7 @@ fake_front_query(struct replay_runtime* runtime, struct replay_moment *todo)
|
||||
if(todo->match->match_transport == transport_tcp)
|
||||
repinfo.c->type = comm_tcp;
|
||||
else repinfo.c->type = comm_udp;
|
||||
fill_buffer_with_reply(repinfo.c->buffer, todo->match, NULL, 0);
|
||||
fill_buffer_with_reply(repinfo.c->buffer, todo->match, NULL, 0, 0);
|
||||
log_info("testbound: incoming QUERY");
|
||||
log_pkt("query pkt", todo->match->reply_list->reply_pkt,
|
||||
todo->match->reply_list->reply_len);
|
||||
@@ -434,13 +492,20 @@ fake_pending_callback(struct replay_runtime* runtime,
|
||||
c.type = comm_tcp;
|
||||
if(todo->evt_type == repevt_back_reply && todo->match) {
|
||||
fill_buffer_with_reply(c.buffer, todo->match, p->pkt,
|
||||
p->pkt_len);
|
||||
p->pkt_len, p->tcp_pkt_counter);
|
||||
}
|
||||
repinfo.c = &c;
|
||||
repinfo.addrlen = p->addrlen;
|
||||
memcpy(&repinfo.addr, &p->addr, p->addrlen);
|
||||
if(!p->serviced)
|
||||
pending_list_delete(runtime, p);
|
||||
if(!p->serviced) {
|
||||
if(todo->match->reply_list->next && !error &&
|
||||
p->tcp_pkt_counter < count_reply_packets(todo->match)) {
|
||||
/* go to next packet next time */
|
||||
p->tcp_pkt_counter++;
|
||||
} else {
|
||||
pending_list_delete(runtime, p);
|
||||
}
|
||||
}
|
||||
if((*cb)(&c, cb_arg, error, &repinfo)) {
|
||||
fatal_exit("unexpected: pending callback returned 1");
|
||||
}
|
||||
@@ -550,6 +615,59 @@ autotrust_check(struct replay_runtime* runtime, struct replay_moment* mom)
|
||||
log_info("autotrust %s is OK", mom->autotrust_id);
|
||||
}
|
||||
|
||||
/** check tempfile file contents */
|
||||
static void
|
||||
tempfile_check(struct replay_runtime* runtime, struct replay_moment* mom)
|
||||
{
|
||||
char name[1024], line[1024];
|
||||
FILE *in;
|
||||
int lineno = 0, oke=1;
|
||||
char* expanded;
|
||||
struct config_strlist* p;
|
||||
line[sizeof(line)-1] = 0;
|
||||
log_assert(mom->autotrust_id);
|
||||
fake_temp_file("_temp_", mom->autotrust_id, name, sizeof(name));
|
||||
in = fopen(name, "r");
|
||||
if(!in) fatal_exit("could not open %s: %s", name, strerror(errno));
|
||||
for(p=mom->file_content; p; p=p->next) {
|
||||
lineno++;
|
||||
if(!fgets(line, (int)sizeof(line)-1, in)) {
|
||||
log_err("tempfile check failed, could not read line");
|
||||
log_err("file %s, line %d", name, lineno);
|
||||
log_err("should be: %s", p->str);
|
||||
fatal_exit("tempfile_check failed");
|
||||
}
|
||||
if(line[0]) line[strlen(line)-1] = 0; /* remove newline */
|
||||
expanded = macro_process(runtime->vars, runtime, p->str);
|
||||
if(!expanded)
|
||||
fatal_exit("could not expand macro line %d", lineno);
|
||||
if(verbosity >= 7 && strcmp(p->str, expanded) != 0)
|
||||
log_info("expanded '%s' to '%s'", p->str, expanded);
|
||||
if(strcmp(expanded, line) != 0) {
|
||||
log_err("mismatch in file %s, line %d", name, lineno);
|
||||
log_err("file has : %s", line);
|
||||
log_err("should be: %s", expanded);
|
||||
free(expanded);
|
||||
oke = 0;
|
||||
continue;
|
||||
}
|
||||
free(expanded);
|
||||
fprintf(stderr, "%s:%2d ok : %s\n", name, lineno, line);
|
||||
}
|
||||
if(fgets(line, (int)sizeof(line)-1, in)) {
|
||||
log_err("tempfile check failed, extra lines in %s after %d",
|
||||
name, lineno);
|
||||
do {
|
||||
fprintf(stderr, "file has: %s", line);
|
||||
} while(fgets(line, (int)sizeof(line)-1, in));
|
||||
oke = 0;
|
||||
}
|
||||
fclose(in);
|
||||
if(!oke)
|
||||
fatal_exit("tempfile_check STEP %d failed", mom->time_step);
|
||||
log_info("tempfile %s is OK", mom->autotrust_id);
|
||||
}
|
||||
|
||||
/** Store RTT in infra cache */
|
||||
static void
|
||||
do_infra_rtt(struct replay_runtime* runtime)
|
||||
@@ -659,6 +777,10 @@ do_moment_and_advance(struct replay_runtime* runtime)
|
||||
autotrust_check(runtime, runtime->now);
|
||||
advance_moment(runtime);
|
||||
break;
|
||||
case repevt_tempfile_check:
|
||||
tempfile_check(runtime, runtime->now);
|
||||
advance_moment(runtime);
|
||||
break;
|
||||
case repevt_assign:
|
||||
moment_assign(runtime, runtime->now);
|
||||
advance_moment(runtime);
|
||||
@@ -1003,7 +1125,7 @@ pending_tcp_query(struct serviced_query* sq, sldns_buffer* packet,
|
||||
pend->addrlen = sq->addrlen;
|
||||
pend->callback = callback;
|
||||
pend->cb_arg = callback_arg;
|
||||
pend->timeout = timeout;
|
||||
pend->timeout = timeout/1000;
|
||||
pend->transport = transport_tcp;
|
||||
pend->pkt = NULL;
|
||||
pend->zone = NULL;
|
||||
@@ -1039,10 +1161,11 @@ struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
|
||||
struct query_info* qinfo, uint16_t flags, int dnssec,
|
||||
int ATTR_UNUSED(want_dnssec), int ATTR_UNUSED(nocaps),
|
||||
int ATTR_UNUSED(tcp_upstream), int ATTR_UNUSED(ssl_upstream),
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
|
||||
size_t zonelen, struct module_qstate* qstate,
|
||||
comm_point_callback_type* callback, void* callback_arg,
|
||||
sldns_buffer* ATTR_UNUSED(buff), struct module_env* ATTR_UNUSED(env))
|
||||
char* ATTR_UNUSED(tls_auth_name), struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, uint8_t* zone, size_t zonelen,
|
||||
struct module_qstate* qstate, comm_point_callback_type* callback,
|
||||
void* callback_arg, sldns_buffer* ATTR_UNUSED(buff),
|
||||
struct module_env* ATTR_UNUSED(env))
|
||||
{
|
||||
struct replay_runtime* runtime = (struct replay_runtime*)outnet->base;
|
||||
struct fake_pending* pend = (struct fake_pending*)calloc(1,
|
||||
@@ -1095,7 +1218,7 @@ struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
|
||||
log_assert(pend->zone);
|
||||
pend->callback = callback;
|
||||
pend->cb_arg = callback_arg;
|
||||
pend->timeout = UDP_AUTH_QUERY_TIMEOUT;
|
||||
pend->timeout = UDP_AUTH_QUERY_TIMEOUT/1000;
|
||||
pend->transport = transport_udp; /* pretend UDP */
|
||||
pend->pkt = NULL;
|
||||
pend->runtime = runtime;
|
||||
@@ -1168,7 +1291,11 @@ struct comm_point* comm_point_create_local(struct comm_base* ATTR_UNUSED(base),
|
||||
comm_point_callback_type* ATTR_UNUSED(callback),
|
||||
void* ATTR_UNUSED(callback_arg))
|
||||
{
|
||||
return calloc(1, 1);
|
||||
struct fake_commpoint* fc = (struct fake_commpoint*)calloc(1,
|
||||
sizeof(*fc));
|
||||
if(!fc) return NULL;
|
||||
fc->typecode = FAKE_COMMPOINT_TYPECODE;
|
||||
return (struct comm_point*)fc;
|
||||
}
|
||||
|
||||
struct comm_point* comm_point_create_raw(struct comm_base* ATTR_UNUSED(base),
|
||||
@@ -1177,7 +1304,11 @@ struct comm_point* comm_point_create_raw(struct comm_base* ATTR_UNUSED(base),
|
||||
void* ATTR_UNUSED(callback_arg))
|
||||
{
|
||||
/* no pipe comm possible */
|
||||
return calloc(1, 1);
|
||||
struct fake_commpoint* fc = (struct fake_commpoint*)calloc(1,
|
||||
sizeof(*fc));
|
||||
if(!fc) return NULL;
|
||||
fc->typecode = FAKE_COMMPOINT_TYPECODE;
|
||||
return (struct comm_point*)fc;
|
||||
}
|
||||
|
||||
void comm_point_start_listening(struct comm_point* ATTR_UNUSED(c),
|
||||
@@ -1194,6 +1325,13 @@ void comm_point_stop_listening(struct comm_point* ATTR_UNUSED(c))
|
||||
/* only cmd com _local gets deleted */
|
||||
void comm_point_delete(struct comm_point* c)
|
||||
{
|
||||
struct fake_commpoint* fc = (struct fake_commpoint*)c;
|
||||
if(c == NULL) return;
|
||||
log_assert(fc->typecode == FAKE_COMMPOINT_TYPECODE);
|
||||
if(fc->type_tcp_out) {
|
||||
/* remove tcp pending, so no more callbacks to it */
|
||||
pending_list_delete(fc->runtime, fc->pending);
|
||||
}
|
||||
free(c);
|
||||
}
|
||||
|
||||
@@ -1285,6 +1423,12 @@ void comm_signal_callback(int ATTR_UNUSED(fd),
|
||||
log_assert(0);
|
||||
}
|
||||
|
||||
void comm_point_http_handle_callback(int ATTR_UNUSED(fd),
|
||||
short ATTR_UNUSED(event), void* ATTR_UNUSED(arg))
|
||||
{
|
||||
log_assert(0);
|
||||
}
|
||||
|
||||
void comm_point_local_handle_callback(int ATTR_UNUSED(fd),
|
||||
short ATTR_UNUSED(event), void* ATTR_UNUSED(arg))
|
||||
{
|
||||
@@ -1420,4 +1564,229 @@ void daemon_remote_stop_accept(struct daemon_remote* ATTR_UNUSED(rc))
|
||||
{
|
||||
}
|
||||
|
||||
int create_udp_sock(int ATTR_UNUSED(family), int ATTR_UNUSED(socktype),
|
||||
struct sockaddr* ATTR_UNUSED(addr), socklen_t ATTR_UNUSED(addrlen),
|
||||
int ATTR_UNUSED(v6only), int* ATTR_UNUSED(inuse),
|
||||
int* ATTR_UNUSED(noproto), int ATTR_UNUSED(rcv), int ATTR_UNUSED(snd),
|
||||
int ATTR_UNUSED(listen), int* ATTR_UNUSED(reuseport),
|
||||
int ATTR_UNUSED(transparent), int ATTR_UNUSED(freebind),
|
||||
int ATTR_UNUSED(use_systemd))
|
||||
{
|
||||
/* if you actually print to this, it'll be stdout during test */
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct comm_point* comm_point_create_udp(struct comm_base *ATTR_UNUSED(base),
|
||||
int ATTR_UNUSED(fd), sldns_buffer* ATTR_UNUSED(buffer),
|
||||
comm_point_callback_type* ATTR_UNUSED(callback),
|
||||
void* ATTR_UNUSED(callback_arg))
|
||||
{
|
||||
log_assert(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct comm_point* comm_point_create_tcp_out(struct comm_base*
|
||||
ATTR_UNUSED(base), size_t ATTR_UNUSED(bufsize),
|
||||
comm_point_callback_type* ATTR_UNUSED(callback),
|
||||
void* ATTR_UNUSED(callback_arg))
|
||||
{
|
||||
log_assert(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct comm_point* outnet_comm_point_for_udp(struct outside_network* outnet,
|
||||
comm_point_callback_type* cb, void* cb_arg,
|
||||
struct sockaddr_storage* ATTR_UNUSED(to_addr),
|
||||
socklen_t ATTR_UNUSED(to_addrlen))
|
||||
{
|
||||
struct replay_runtime* runtime = (struct replay_runtime*)
|
||||
outnet->base;
|
||||
struct fake_commpoint* fc = (struct fake_commpoint*)calloc(1,
|
||||
sizeof(*fc));
|
||||
if(!fc) return NULL;
|
||||
fc->typecode = FAKE_COMMPOINT_TYPECODE;
|
||||
fc->type_udp_out = 1;
|
||||
fc->cb = cb;
|
||||
fc->cb_arg = cb_arg;
|
||||
fc->runtime = runtime;
|
||||
/* used by authzone transfers */
|
||||
return (struct comm_point*)fc;
|
||||
}
|
||||
|
||||
struct comm_point* outnet_comm_point_for_tcp(struct outside_network* outnet,
|
||||
comm_point_callback_type* cb, void* cb_arg,
|
||||
struct sockaddr_storage* to_addr, socklen_t to_addrlen,
|
||||
struct sldns_buffer* query, int timeout)
|
||||
{
|
||||
struct replay_runtime* runtime = (struct replay_runtime*)
|
||||
outnet->base;
|
||||
struct fake_commpoint* fc = (struct fake_commpoint*)calloc(1,
|
||||
sizeof(*fc));
|
||||
struct fake_pending* pend = (struct fake_pending*)calloc(1,
|
||||
sizeof(struct fake_pending));
|
||||
if(!fc || !pend) {
|
||||
free(fc);
|
||||
free(pend);
|
||||
return NULL;
|
||||
}
|
||||
fc->typecode = FAKE_COMMPOINT_TYPECODE;
|
||||
fc->type_tcp_out = 1;
|
||||
fc->cb = cb;
|
||||
fc->cb_arg = cb_arg;
|
||||
fc->runtime = runtime;
|
||||
fc->pending = pend;
|
||||
|
||||
/* used by authzone transfers */
|
||||
/* create pending item */
|
||||
pend->buffer = sldns_buffer_new(sldns_buffer_limit(query)+10);
|
||||
if(!pend->buffer) {
|
||||
free(fc);
|
||||
free(pend);
|
||||
return NULL;
|
||||
}
|
||||
sldns_buffer_copy(pend->buffer, query);
|
||||
memcpy(&pend->addr, to_addr, to_addrlen);
|
||||
pend->addrlen = to_addrlen;
|
||||
pend->zone = NULL;
|
||||
pend->zonelen = 0;
|
||||
if(LDNS_QDCOUNT(sldns_buffer_begin(query)) > 0) {
|
||||
char buf[512];
|
||||
char addrbuf[128];
|
||||
(void)sldns_wire2str_rrquestion_buf(sldns_buffer_at(query, LDNS_HEADER_SIZE), sldns_buffer_limit(query)-LDNS_HEADER_SIZE, buf, sizeof(buf));
|
||||
addr_to_str((struct sockaddr_storage*)to_addr, to_addrlen,
|
||||
addrbuf, sizeof(addrbuf));
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
if(buf[0] != 0) buf[strlen(buf)-1] = 0; /* del newline*/
|
||||
log_info("tcp to %s: %s", addrbuf, buf);
|
||||
}
|
||||
log_assert(sldns_buffer_limit(query)-LDNS_HEADER_SIZE >= 2);
|
||||
pend->qtype = (int)sldns_buffer_read_u16_at(query,
|
||||
LDNS_HEADER_SIZE+
|
||||
dname_valid(sldns_buffer_at(query, LDNS_HEADER_SIZE),
|
||||
sldns_buffer_limit(query)-LDNS_HEADER_SIZE));
|
||||
}
|
||||
pend->callback = cb;
|
||||
pend->cb_arg = cb_arg;
|
||||
pend->timeout = timeout;
|
||||
pend->transport = transport_tcp;
|
||||
pend->pkt = NULL;
|
||||
pend->runtime = runtime;
|
||||
pend->serviced = 0;
|
||||
pend->pkt_len = sldns_buffer_limit(pend->buffer);
|
||||
pend->pkt = memdup(sldns_buffer_begin(pend->buffer), pend->pkt_len);
|
||||
if(!pend->pkt) fatal_exit("out of memory");
|
||||
|
||||
log_info("testbound: created fake pending for tcp_out");
|
||||
|
||||
/* add to list */
|
||||
pend->next = runtime->pending_list;
|
||||
runtime->pending_list = pend;
|
||||
|
||||
return (struct comm_point*)fc;
|
||||
}
|
||||
|
||||
struct comm_point* outnet_comm_point_for_http(struct outside_network* outnet,
|
||||
comm_point_callback_type* cb, void* cb_arg,
|
||||
struct sockaddr_storage* to_addr, socklen_t to_addrlen, int timeout,
|
||||
int ssl, char* host, char* path)
|
||||
{
|
||||
struct replay_runtime* runtime = (struct replay_runtime*)
|
||||
outnet->base;
|
||||
struct fake_commpoint* fc = (struct fake_commpoint*)calloc(1,
|
||||
sizeof(*fc));
|
||||
if(!fc) {
|
||||
return NULL;
|
||||
}
|
||||
fc->typecode = FAKE_COMMPOINT_TYPECODE;
|
||||
fc->type_http_out = 1;
|
||||
fc->cb = cb;
|
||||
fc->cb_arg = cb_arg;
|
||||
fc->runtime = runtime;
|
||||
|
||||
(void)to_addr;
|
||||
(void)to_addrlen;
|
||||
(void)timeout;
|
||||
|
||||
(void)ssl;
|
||||
(void)host;
|
||||
(void)path;
|
||||
|
||||
/* handle http comm point and return contents from test script */
|
||||
return (struct comm_point*)fc;
|
||||
}
|
||||
|
||||
int comm_point_send_udp_msg(struct comm_point *c, sldns_buffer* packet,
|
||||
struct sockaddr* addr, socklen_t addrlen)
|
||||
{
|
||||
struct fake_commpoint* fc = (struct fake_commpoint*)c;
|
||||
struct replay_runtime* runtime = fc->runtime;
|
||||
struct fake_pending* pend = (struct fake_pending*)calloc(1,
|
||||
sizeof(struct fake_pending));
|
||||
if(!pend) {
|
||||
log_err("malloc failure");
|
||||
return 0;
|
||||
}
|
||||
fc->pending = pend;
|
||||
/* used by authzone transfers */
|
||||
/* create pending item */
|
||||
pend->buffer = sldns_buffer_new(sldns_buffer_limit(packet) + 10);
|
||||
if(!pend->buffer) {
|
||||
free(pend);
|
||||
return 0;
|
||||
}
|
||||
sldns_buffer_copy(pend->buffer, packet);
|
||||
memcpy(&pend->addr, addr, addrlen);
|
||||
pend->addrlen = addrlen;
|
||||
pend->zone = NULL;
|
||||
pend->zonelen = 0;
|
||||
if(LDNS_QDCOUNT(sldns_buffer_begin(packet)) > 0) {
|
||||
char buf[512];
|
||||
char addrbuf[128];
|
||||
(void)sldns_wire2str_rrquestion_buf(sldns_buffer_at(packet, LDNS_HEADER_SIZE), sldns_buffer_limit(packet)-LDNS_HEADER_SIZE, buf, sizeof(buf));
|
||||
addr_to_str((struct sockaddr_storage*)addr, addrlen,
|
||||
addrbuf, sizeof(addrbuf));
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
if(buf[0] != 0) buf[strlen(buf)-1] = 0; /* del newline*/
|
||||
log_info("udp to %s: %s", addrbuf, buf);
|
||||
}
|
||||
log_assert(sldns_buffer_limit(packet)-LDNS_HEADER_SIZE >= 2);
|
||||
pend->qtype = (int)sldns_buffer_read_u16_at(packet,
|
||||
LDNS_HEADER_SIZE+
|
||||
dname_valid(sldns_buffer_at(packet, LDNS_HEADER_SIZE),
|
||||
sldns_buffer_limit(packet)-LDNS_HEADER_SIZE));
|
||||
}
|
||||
pend->callback = fc->cb;
|
||||
pend->cb_arg = fc->cb_arg;
|
||||
pend->timeout = UDP_AUTH_QUERY_TIMEOUT/1000;
|
||||
pend->transport = transport_udp;
|
||||
pend->pkt = NULL;
|
||||
pend->runtime = runtime;
|
||||
pend->serviced = 0;
|
||||
pend->pkt_len = sldns_buffer_limit(pend->buffer);
|
||||
pend->pkt = memdup(sldns_buffer_begin(pend->buffer), pend->pkt_len);
|
||||
if(!pend->pkt) fatal_exit("out of memory");
|
||||
|
||||
log_info("testbound: created fake pending for send_udp_msg");
|
||||
|
||||
/* add to list */
|
||||
pend->next = runtime->pending_list;
|
||||
runtime->pending_list = pend;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int outnet_get_tcp_fd(struct sockaddr_storage* ATTR_UNUSED(addr),
|
||||
socklen_t ATTR_UNUSED(addrlen), int ATTR_UNUSED(tcp_mss))
|
||||
{
|
||||
log_assert(0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int outnet_tcp_connect(int ATTR_UNUSED(s), struct sockaddr_storage* ATTR_UNUSED(addr),
|
||||
socklen_t ATTR_UNUSED(addrlen))
|
||||
{
|
||||
log_assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********** End of Dummy routines ***********/
|
||||
|
||||
@@ -323,6 +323,15 @@ replay_moment_read(char* remain, FILE* in, const char* name,
|
||||
mom->autotrust_id = strdup(remain);
|
||||
if(!mom->autotrust_id) fatal_exit("out of memory");
|
||||
read_file_content(in, &pstate->lineno, mom);
|
||||
} else if(parse_keyword(&remain, "CHECK_TEMPFILE")) {
|
||||
mom->evt_type = repevt_tempfile_check;
|
||||
while(isspace((unsigned char)*remain))
|
||||
remain++;
|
||||
if(strlen(remain)>0 && remain[strlen(remain)-1]=='\n')
|
||||
remain[strlen(remain)-1] = 0;
|
||||
mom->autotrust_id = strdup(remain);
|
||||
if(!mom->autotrust_id) fatal_exit("out of memory");
|
||||
read_file_content(in, &pstate->lineno, mom);
|
||||
} else if(parse_keyword(&remain, "ERROR")) {
|
||||
mom->evt_type = repevt_error;
|
||||
} else if(parse_keyword(&remain, "TRAFFIC")) {
|
||||
|
||||
@@ -49,6 +49,14 @@
|
||||
* AUTOTRUST_FILE id
|
||||
* ; contents of that file
|
||||
* AUTOTRUST_END
|
||||
* ; temp file names are echoed as "tmp/xxx.fname"
|
||||
* TEMPFILE_NAME fname
|
||||
* ; temp file contents, inline, deleted at end of run
|
||||
* TEMPFILE_CONTENTS fname
|
||||
* ; contents of that file
|
||||
* ; this creates $INCLUDE /tmp/xxx.fname
|
||||
* $INCLUDE_TEMPFILE fname
|
||||
* TEMPFILE_END
|
||||
* CONFIG_END
|
||||
* ; comment line.
|
||||
* SCENARIO_BEGIN name_of_scenario
|
||||
@@ -75,6 +83,7 @@
|
||||
* 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
|
||||
* ; following entry starts on the next line, ENTRY_BEGIN.
|
||||
@@ -195,6 +204,8 @@ struct replay_moment {
|
||||
repevt_back_query,
|
||||
/** check autotrust key file */
|
||||
repevt_autotrust_check,
|
||||
/** check a temp file */
|
||||
repevt_tempfile_check,
|
||||
/** an error happens to outbound query */
|
||||
repevt_error,
|
||||
/** assignment to a variable */
|
||||
@@ -340,6 +351,8 @@ struct fake_pending {
|
||||
enum transport_type transport;
|
||||
/** if this is a serviced query */
|
||||
int serviced;
|
||||
/** if we are handling a multi pkt tcp stream, non 0 and the pkt nr*/
|
||||
int tcp_pkt_counter;
|
||||
/** the runtime structure this is part of */
|
||||
struct replay_runtime* runtime;
|
||||
};
|
||||
|
||||
@@ -284,7 +284,7 @@ send_em(const char* svr, int udp, int usessl, int noanswer, int num, char** qs)
|
||||
SSL* ssl = NULL;
|
||||
if(!buf) fatal_exit("out of memory");
|
||||
if(usessl) {
|
||||
ctx = connect_sslctx_create(NULL, NULL, NULL);
|
||||
ctx = connect_sslctx_create(NULL, NULL, NULL, 0);
|
||||
if(!ctx) fatal_exit("cannot create ssl ctx");
|
||||
ssl = outgoing_ssl_fd(ctx, fd);
|
||||
if(!ssl) fatal_exit("cannot create ssl");
|
||||
|
||||
+76
-1
@@ -135,6 +135,66 @@ echo_cmdline(int argc, char* argv[])
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
/** spool temp file name */
|
||||
static void
|
||||
spool_temp_file_name(int* lineno, FILE* cfg, char* id)
|
||||
{
|
||||
char line[MAX_LINE_LEN];
|
||||
/* find filename for new file */
|
||||
while(isspace((unsigned char)*id))
|
||||
id++;
|
||||
if(*id == '\0')
|
||||
fatal_exit("TEMPFILE_NAME must have id, line %d", *lineno);
|
||||
id[strlen(id)-1]=0; /* remove newline */
|
||||
fake_temp_file("_temp_", id, line, sizeof(line));
|
||||
fprintf(cfg, "\"%s\"\n", line);
|
||||
}
|
||||
|
||||
/** spool temp file */
|
||||
static void
|
||||
spool_temp_file(FILE* in, int* lineno, char* id)
|
||||
{
|
||||
char line[MAX_LINE_LEN];
|
||||
char* parse;
|
||||
FILE* spool;
|
||||
/* find filename for new file */
|
||||
while(isspace((unsigned char)*id))
|
||||
id++;
|
||||
if(*id == '\0')
|
||||
fatal_exit("TEMPFILE_CONTENTS must have id, line %d", *lineno);
|
||||
id[strlen(id)-1]=0; /* remove newline */
|
||||
fake_temp_file("_temp_", id, line, sizeof(line));
|
||||
/* open file and spool to it */
|
||||
spool = fopen(line, "w");
|
||||
if(!spool) fatal_exit("could not open %s: %s", line, strerror(errno));
|
||||
fprintf(stderr, "testbound is spooling temp file: %s\n", line);
|
||||
if(!cfg_strlist_insert(&cfgfiles, strdup(line)))
|
||||
fatal_exit("out of memory");
|
||||
line[sizeof(line)-1] = 0;
|
||||
while(fgets(line, MAX_LINE_LEN-1, in)) {
|
||||
parse = line;
|
||||
(*lineno)++;
|
||||
while(isspace((unsigned char)*parse))
|
||||
parse++;
|
||||
if(strncmp(parse, "$INCLUDE_TEMPFILE", 17) == 0) {
|
||||
char l2[MAX_LINE_LEN-30]; /* -30 makes it fit with
|
||||
a preceding $INCLUDE in the buf line[] */
|
||||
char* tid = parse+17;
|
||||
while(isspace((unsigned char)*tid))
|
||||
tid++;
|
||||
tid[strlen(tid)-1]=0; /* remove newline */
|
||||
fake_temp_file("_temp_", tid, l2, sizeof(l2));
|
||||
snprintf(line, sizeof(line), "$INCLUDE %s\n", l2);
|
||||
}
|
||||
if(strncmp(parse, "TEMPFILE_END", 12) == 0) {
|
||||
fclose(spool);
|
||||
return;
|
||||
}
|
||||
fputs(line, spool);
|
||||
}
|
||||
fatal_exit("no TEMPFILE_END in input file");
|
||||
}
|
||||
|
||||
/** spool autotrust file */
|
||||
static void
|
||||
spool_auto_file(FILE* in, int* lineno, FILE* cfg, char* id)
|
||||
@@ -213,6 +273,14 @@ setup_config(FILE* in, int* lineno, int* pass_argc, char* pass_argv[])
|
||||
spool_auto_file(in, lineno, cfg, parse+14);
|
||||
continue;
|
||||
}
|
||||
if(strncmp(parse, "TEMPFILE_NAME", 13) == 0) {
|
||||
spool_temp_file_name(lineno, cfg, parse+13);
|
||||
continue;
|
||||
}
|
||||
if(strncmp(parse, "TEMPFILE_CONTENTS", 17) == 0) {
|
||||
spool_temp_file(in, lineno, parse+17);
|
||||
continue;
|
||||
}
|
||||
if(strncmp(parse, "CONFIG_END", 10) == 0) {
|
||||
fclose(cfg);
|
||||
return;
|
||||
@@ -287,6 +355,10 @@ main(int argc, char* argv[])
|
||||
case 's':
|
||||
free(pass_argv[1]);
|
||||
testbound_selftest();
|
||||
checklock_stop();
|
||||
if(log_get_lock()) {
|
||||
lock_quick_destroy((lock_quick_type*)log_get_lock());
|
||||
}
|
||||
exit(0);
|
||||
case '1':
|
||||
#ifdef USE_SHA1
|
||||
@@ -389,7 +461,10 @@ main(int argc, char* argv[])
|
||||
for(c=1; c<pass_argc; c++)
|
||||
free(pass_argv[c]);
|
||||
if(res == 0) {
|
||||
log_info("Testbound Exit Success");
|
||||
log_info("Testbound Exit Success\n");
|
||||
if(log_get_lock()) {
|
||||
lock_quick_destroy((lock_quick_type*)log_get_lock());
|
||||
}
|
||||
#ifdef HAVE_PTHREAD
|
||||
/* dlopen frees its thread state (dlopen of gost engine) */
|
||||
pthread_exit(NULL);
|
||||
|
||||
+12
-4
@@ -572,7 +572,15 @@ read_entry(FILE* in, const char* name, struct sldns_file_parse_state* pstate,
|
||||
} else if(str_keyword(&parse, "ADJUST")) {
|
||||
adjustline(parse, current, cur_reply);
|
||||
} else if(str_keyword(&parse, "EXTRA_PACKET")) {
|
||||
/* copy current packet into buffer */
|
||||
cur_reply->reply_pkt = memdup(pktbuf, pktlen);
|
||||
cur_reply->reply_len = pktlen;
|
||||
if(!cur_reply->reply_pkt)
|
||||
error("out of memory");
|
||||
cur_reply = entry_add_reply(current);
|
||||
/* clear for next packet */
|
||||
pktlen = LDNS_HEADER_SIZE;
|
||||
memset(pktbuf, 0, pktlen); /* ID = 0, FLAGS="", and rr counts 0 */
|
||||
} else if(str_keyword(&parse, "SECTION")) {
|
||||
if(str_keyword(&parse, "QUESTION"))
|
||||
add_section = LDNS_SECTION_QUESTION;
|
||||
@@ -1558,10 +1566,10 @@ adjust_packet(struct entry* match, uint8_t** answer_pkt, size_t *answer_len,
|
||||
return;
|
||||
}
|
||||
/* copy the ID */
|
||||
if(match->copy_id && reslen >= 2)
|
||||
res[1] = orig[1];
|
||||
if(match->copy_id && reslen >= 1)
|
||||
res[0] = orig[0];
|
||||
if(match->copy_id && reslen >= 2 && query_len >= 2)
|
||||
res[1] = query_pkt[1];
|
||||
if(match->copy_id && reslen >= 1 && query_len >= 1)
|
||||
res[0] = query_pkt[0];
|
||||
|
||||
if(match->copy_ednsdata_assume_clientsubnet) {
|
||||
/** Assume there is only one EDNS option, which is ECS.
|
||||
|
||||
+42
-18
@@ -95,42 +95,42 @@ static const char* zone_example_com =
|
||||
/* and some tests for RRSIGs (rrsig is www.nlnetlabs.nl copy) */
|
||||
/* normal: domain and 1 rrsig */
|
||||
"z1.example.com. 3600 IN A 10.0.0.10\n"
|
||||
"z1.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk= ;{id = 42393}\n"
|
||||
"z1.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
|
||||
/* normal: domain and 2 rrsigs */
|
||||
"z2.example.com. 3600 IN A 10.0.0.10\n"
|
||||
"z2.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk= ;{id = 42393}\n"
|
||||
"z2.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 12345 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk= ;{id = 12345}\n"
|
||||
"z2.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
|
||||
"z2.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 12345 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
|
||||
/* normal: domain and 3 rrsigs */
|
||||
"z3.example.com. 3600 IN A 10.0.0.10\n"
|
||||
"z3.example.com. 3600 IN A 10.0.0.11\n"
|
||||
"z3.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk= ;{id = 42393}\n"
|
||||
"z3.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 12345 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk= ;{id = 12345}\n"
|
||||
"z3.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 12356 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk= ;{id = 12356}\n"
|
||||
"z3.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
|
||||
"z3.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 12345 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
|
||||
"z3.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 12356 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
|
||||
/* just an RRSIG rrset with nothing else */
|
||||
"z4.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk= ;{id = 42393}\n"
|
||||
"z4.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
|
||||
/* just an RRSIG rrset with nothing else, 2 rrsigs */
|
||||
"z5.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk= ;{id = 42393}\n"
|
||||
"z5.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 12345 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk= ;{id = 12345}\n"
|
||||
"z5.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
|
||||
"z5.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 12345 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
|
||||
#if 0 /* comparison of file does not work on this part because duplicates */
|
||||
/* are removed and the rrsets are reordered */
|
||||
/* first rrsig, then A record */
|
||||
"z6.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk= ;{id = 42393}\n"
|
||||
"z6.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
|
||||
"z6.example.com. 3600 IN A 10.0.0.10\n"
|
||||
/* first two rrsigs, then A record */
|
||||
"z7.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk= ;{id = 42393}\n"
|
||||
"z7.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 12345 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk= ;{id = 12345}\n"
|
||||
"z7.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
|
||||
"z7.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 12345 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
|
||||
"z7.example.com. 3600 IN A 10.0.0.10\n"
|
||||
/* first two rrsigs, then two A records */
|
||||
"z8.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk= ;{id = 42393}\n"
|
||||
"z8.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 12345 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk= ;{id = 12345}\n"
|
||||
"z8.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
|
||||
"z8.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 12345 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
|
||||
"z8.example.com. 3600 IN A 10.0.0.10\n"
|
||||
"z8.example.com. 3600 IN A 10.0.0.11\n"
|
||||
/* duplicate RR, duplicate RRsig */
|
||||
"z9.example.com. 3600 IN A 10.0.0.10\n"
|
||||
"z9.example.com. 3600 IN A 10.0.0.11\n"
|
||||
"z9.example.com. 3600 IN A 10.0.0.10\n"
|
||||
"z9.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk= ;{id = 42393}\n"
|
||||
"z9.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk= ;{id = 42393}\n"
|
||||
"z9.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
|
||||
"z9.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
|
||||
#endif /* if0 for duplicates and reordering */
|
||||
;
|
||||
|
||||
@@ -521,6 +521,7 @@ addzone(struct auth_zones* az, const char* name, char* fname)
|
||||
lock_rw_unlock(&az->lock);
|
||||
if(!z) fatal_exit("cannot find zone");
|
||||
auth_zone_set_zonefile(z, fname);
|
||||
z->for_upstream = 1;
|
||||
|
||||
if(!auth_zone_read_zonefile(z)) {
|
||||
fatal_exit("parse failure for auth zone %s", name);
|
||||
@@ -685,8 +686,12 @@ msgtostr(struct dns_msg* msg)
|
||||
char* str;
|
||||
sldns_buffer* buf = sldns_buffer_new(65535);
|
||||
if(!buf) fatal_exit("out of memory");
|
||||
pr_flags(buf, msg->rep->flags);
|
||||
pr_rrs(buf, msg->rep);
|
||||
if(!msg) {
|
||||
sldns_buffer_printf(buf, "null packet\n");
|
||||
} else {
|
||||
pr_flags(buf, msg->rep->flags);
|
||||
pr_rrs(buf, msg->rep);
|
||||
}
|
||||
|
||||
str = strdup((char*)sldns_buffer_begin(buf));
|
||||
if(!str) fatal_exit("out of memory");
|
||||
@@ -831,6 +836,24 @@ check_queries(const char* name, const char* zone, struct q_ans* queries)
|
||||
auth_zones_delete(az);
|
||||
}
|
||||
|
||||
/** Test authzone compare_serial */
|
||||
static void
|
||||
authzone_compare_serial(void)
|
||||
{
|
||||
if(vbmp) printf("Testing compare_serial\n");
|
||||
unit_assert(compare_serial(0, 1) < 0);
|
||||
unit_assert(compare_serial(1, 0) > 0);
|
||||
unit_assert(compare_serial(0, 0) == 0);
|
||||
unit_assert(compare_serial(1, 1) == 0);
|
||||
unit_assert(compare_serial(0xf0000000, 0xf0000000) == 0);
|
||||
unit_assert(compare_serial(0, 0xf0000000) > 0);
|
||||
unit_assert(compare_serial(0xf0000000, 0) < 0);
|
||||
unit_assert(compare_serial(0xf0000000, 0xf0000001) < 0);
|
||||
unit_assert(compare_serial(0xf0000002, 0xf0000001) > 0);
|
||||
unit_assert(compare_serial(0x70000000, 0x80000000) < 0);
|
||||
unit_assert(compare_serial(0x90000000, 0x70000000) > 0);
|
||||
}
|
||||
|
||||
/** Test authzone read from file */
|
||||
static void
|
||||
authzone_read_test(void)
|
||||
@@ -853,6 +876,7 @@ authzone_test(void)
|
||||
{
|
||||
unit_show_feature("authzone");
|
||||
atexit(tmpfilecleanup);
|
||||
authzone_compare_serial();
|
||||
authzone_read_test();
|
||||
authzone_query_test();
|
||||
}
|
||||
|
||||
+3
-1
@@ -433,7 +433,6 @@ rtt_test(void)
|
||||
}
|
||||
|
||||
#include "services/cache/infra.h"
|
||||
#include "util/config_file.h"
|
||||
|
||||
/* lookup and get key and data structs easily */
|
||||
static struct infra_data* infra_lookup_host(struct infra_cache* infra,
|
||||
@@ -906,6 +905,9 @@ main(int argc, char* argv[])
|
||||
#ifdef CLIENT_SUBNET
|
||||
ecs_test();
|
||||
#endif /* CLIENT_SUBNET */
|
||||
if(log_get_lock()) {
|
||||
lock_quick_destroy((lock_quick_type*)log_get_lock());
|
||||
}
|
||||
checklock_stop();
|
||||
printf("%d checks ok.\n", testcount);
|
||||
#ifdef HAVE_SSL
|
||||
|
||||
+3
-3
@@ -94,7 +94,7 @@ static void print_neg_cache(struct val_neg_cache* neg)
|
||||
/** get static pointer to random zone name */
|
||||
static char* get_random_zone(void)
|
||||
{
|
||||
static char zname[256];
|
||||
static char zname[36];
|
||||
int labels = random() % 3;
|
||||
int i;
|
||||
char* p = zname;
|
||||
@@ -102,10 +102,10 @@ static char* get_random_zone(void)
|
||||
|
||||
for(i=0; i<labels; i++) {
|
||||
labnum = random()%10;
|
||||
snprintf(p, 256-(p-zname), "\003%3.3d", labnum);
|
||||
snprintf(p, sizeof(zname)-(p-zname), "\003%3.3d", labnum);
|
||||
p+=4;
|
||||
}
|
||||
snprintf(p, 256-(p-zname), "\007example\003com");
|
||||
snprintf(p, sizeof(zname)-(p-zname), "\007example\003com");
|
||||
return zname;
|
||||
}
|
||||
|
||||
|
||||
@@ -186,7 +186,9 @@ verifytest_rrset(struct module_env* env, struct val_env* ve,
|
||||
ntohs(rrset->rk.rrset_class));
|
||||
}
|
||||
setup_sigalg(dnskey, sigalg); /* check all algorithms in the dnskey */
|
||||
sec = dnskeyset_verify_rrset(env, ve, rrset, dnskey, sigalg, &reason);
|
||||
/* ok to give null as qstate here, won't be used for answer section. */
|
||||
sec = dnskeyset_verify_rrset(env, ve, rrset, dnskey, sigalg, &reason,
|
||||
LDNS_SECTION_ANSWER, NULL);
|
||||
if(vsig) {
|
||||
printf("verify outcome is: %s %s\n", sec_status_to_string(sec),
|
||||
reason?reason:"");
|
||||
@@ -522,6 +524,7 @@ verify_test(void)
|
||||
#endif
|
||||
#if (defined(HAVE_EVP_SHA512) || defined(HAVE_NSS) || defined(HAVE_NETTLE)) && defined(USE_SHA2)
|
||||
verifytest_file("testdata/test_sigs.rsasha512_draft", "20070829144150");
|
||||
verifytest_file("testdata/test_signatures.9", "20171215000000");
|
||||
#endif
|
||||
#ifdef USE_SHA1
|
||||
verifytest_file("testdata/test_sigs.hinfo", "20090107100022");
|
||||
@@ -545,6 +548,11 @@ verify_test(void)
|
||||
verifytest_file("testdata/test_sigs.ed25519", "20170530140439");
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_ED448
|
||||
if(dnskey_algo_id_is_supported(LDNS_ED448)) {
|
||||
verifytest_file("testdata/test_sigs.ed448", "20180408143630");
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_SHA1
|
||||
dstest_file("testdata/test_ds.sha1");
|
||||
#endif
|
||||
|
||||
+41
-4
@@ -9,11 +9,48 @@ PRE="../.."
|
||||
get_make
|
||||
(cd $PRE ; $MAKE unittest; $MAKE lock-verify)
|
||||
|
||||
if (cd $PRE; ./unittest); then
|
||||
echo "unit test worked."
|
||||
if test -f $PRE/unbound_do_valgrind_in_test; then
|
||||
do_valgrind=yes
|
||||
else
|
||||
echo "unit test failed."
|
||||
exit 1
|
||||
do_valgrind=no
|
||||
fi
|
||||
VALGRIND_FLAGS="--leak-check=full --show-leak-kinds=all"
|
||||
|
||||
if test $do_valgrind = "yes"; then
|
||||
echo "valgrind yes"
|
||||
echo
|
||||
tmpout=/tmp/tmpout.$$
|
||||
if (cd $PRE; valgrind $VALGRIND_FLAGS ./unittest >$tmpout 2>&1); then
|
||||
echo "unit test worked."
|
||||
else
|
||||
echo "unit test failed."
|
||||
exit 1
|
||||
fi
|
||||
if grep "All heap blocks were freed -- no leaks are possible" $tmpout; then
|
||||
: # clean
|
||||
else
|
||||
cat $tmpout
|
||||
echo "Memory leaked in unittest"
|
||||
grep "in use at exit" $tmpout
|
||||
exit 1
|
||||
fi
|
||||
if grep "ERROR SUMMARY: 0 errors from 0 contexts" $tmpout; then
|
||||
: # clean
|
||||
else
|
||||
cat $tmpout
|
||||
echo "Errors in unittest"
|
||||
grep "ERROR SUMMARY" $tmpout
|
||||
exit 1
|
||||
fi
|
||||
rm -f $tmpout
|
||||
else
|
||||
# without valgrind
|
||||
if (cd $PRE; ./unittest); then
|
||||
echo "unit test worked."
|
||||
else
|
||||
echo "unit test failed."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
if test -f $PRE/ublocktrace.0; then
|
||||
if (cd $PRE; ./lock-verify ublocktrace.*); then
|
||||
|
||||
+31
-5
@@ -11,7 +11,12 @@ get_make
|
||||
exitval=0
|
||||
# quiet="" to make verbose
|
||||
|
||||
do_valgrind=no
|
||||
if test -f $PRE/unbound_do_valgrind_in_test; then
|
||||
do_valgrind=yes
|
||||
else
|
||||
do_valgrind=no
|
||||
fi
|
||||
VALGRIND_FLAGS="--leak-check=full --show-leak-kinds=all"
|
||||
# valgrind mode for debug
|
||||
#if grep "staticexe=-static" $PRE/Makefile >/dev/null 2>&1; then
|
||||
# if test -x "`which valgrind`"; then
|
||||
@@ -21,19 +26,30 @@ do_valgrind=no
|
||||
|
||||
# self-test (unit test of testbound)
|
||||
if test $do_valgrind = "yes"; then
|
||||
if (valgrind $PRE/testbound -s >tmpout 2>&1;); then
|
||||
echo "valgrind yes"
|
||||
echo
|
||||
if (valgrind $VALGRIND_FLAGS $PRE/testbound -s >tmpout 2>&1;); then
|
||||
echo "selftest OK "
|
||||
else
|
||||
echo "selftest FAILED"
|
||||
exit 1
|
||||
fi
|
||||
if grep "All heap blocks were freed -- no leaks are possible." tmpout >/dev/null 2>&1; then
|
||||
if grep "All heap blocks were freed -- no leaks are possible" tmpout; then
|
||||
: # clean
|
||||
else
|
||||
cat tmpout
|
||||
echo "Memory leaked in selftest"
|
||||
grep "in use at exit" tmpout
|
||||
exit 1
|
||||
fi
|
||||
if grep "ERROR SUMMARY: 0 errors from 0 contexts" tmpout; then
|
||||
: # clean
|
||||
else
|
||||
cat tmpout
|
||||
echo "Errors in selftest"
|
||||
grep "ERROR SUMMARY" tmpout
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
if ($PRE/testbound -s >/dev/null 2>&1;); then
|
||||
echo "selftest OK "
|
||||
@@ -88,19 +104,29 @@ for input in $PRE/testdata/*.rpl $PRE/testdata/*.crpl; do
|
||||
fi
|
||||
|
||||
if test $do_valgrind = "yes"; then
|
||||
if (valgrind $PRE/testbound -p $input >tmpout 2>&1;); then
|
||||
echo
|
||||
if (valgrind $VALGRIND_FLAGS $PRE/testbound -p $input >tmpout 2>&1;); then
|
||||
echo " OK $cleaninput: $header"
|
||||
else
|
||||
echo "FAILED $cleaninput: $header"
|
||||
exitval=1
|
||||
fi
|
||||
if grep "All heap blocks were freed -- no leaks are possible." tmpout >/dev/null 2>&1; then
|
||||
if grep "All heap blocks were freed -- no leaks are possible" tmpout; then
|
||||
: # clean
|
||||
else
|
||||
grep "^==" tmpout
|
||||
echo "Memory leaked in $cleaninput"
|
||||
grep "in use at exit" tmpout
|
||||
exitval=1
|
||||
fi
|
||||
if grep "ERROR SUMMARY: 0 errors from 0 contexts" tmpout; then
|
||||
: # clean
|
||||
else
|
||||
grep "^==" tmpout
|
||||
echo "Errors in $cleaninput"
|
||||
grep "ERROR SUMMARY" tmpout
|
||||
exitval=1
|
||||
fi
|
||||
else
|
||||
# do valgrind=no
|
||||
if ($PRE/testbound -p $input >/dev/null 2>&1;); then
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
server:
|
||||
verbosity: 7
|
||||
# num-threads: 1
|
||||
interface: 127.0.0.1
|
||||
port: @PORT@
|
||||
use-syslog: no
|
||||
directory: ""
|
||||
pidfile: "unbound.pid"
|
||||
chroot: ""
|
||||
username: ""
|
||||
do-not-query-localhost: no
|
||||
use-caps-for-id: yes
|
||||
auth-zone:
|
||||
name: "example.com"
|
||||
for-upstream: yes
|
||||
for-downstream: yes
|
||||
master: "127.0.0.1@@TOPORT@"
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
BaseName: auth_axfr
|
||||
Version: 1.0
|
||||
Description: Perform AXFR for authority zone
|
||||
CreationDate: Tue 13 Jun 09:35:40 CEST 2017
|
||||
Maintainer: dr. W.C.A. Wijngaards
|
||||
Category:
|
||||
Component:
|
||||
CmdDepends:
|
||||
Depends:
|
||||
Help:
|
||||
Pre: auth_axfr.pre
|
||||
Post: auth_axfr.post
|
||||
Test: auth_axfr.test
|
||||
AuxFiles:
|
||||
Passed:
|
||||
Failure:
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
# #-- auth_axfr.post --#
|
||||
# source the master var file when it's there
|
||||
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
|
||||
# source the test var file when it's there
|
||||
[ -f .tpkg.var.test ] && source .tpkg.var.test
|
||||
#
|
||||
# do your teardown here
|
||||
. ../common.sh
|
||||
kill_pid $FWD_PID
|
||||
kill_pid $UNBOUND_PID
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
# #-- auth_axfr.pre--#
|
||||
# source the master var file when it's there
|
||||
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
|
||||
# use .tpkg.var.test for in test variable passing
|
||||
[ -f .tpkg.var.test ] && source .tpkg.var.test
|
||||
|
||||
. ../common.sh
|
||||
get_random_port 2
|
||||
UNBOUND_PORT=$RND_PORT
|
||||
FWD_PORT=$(($RND_PORT + 1))
|
||||
echo "UNBOUND_PORT=$UNBOUND_PORT" >> .tpkg.var.test
|
||||
echo "FWD_PORT=$FWD_PORT" >> .tpkg.var.test
|
||||
|
||||
# start forwarder
|
||||
get_ldns_testns
|
||||
$LDNS_TESTNS -p $FWD_PORT auth_axfr.testns >fwd.log 2>&1 &
|
||||
FWD_PID=$!
|
||||
echo "FWD_PID=$FWD_PID" >> .tpkg.var.test
|
||||
|
||||
# make config file
|
||||
sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@TOPORT\@/'$FWD_PORT'/' < auth_axfr.conf > ub.conf
|
||||
# start unbound in the background
|
||||
PRE="../.."
|
||||
$PRE/unbound -d -c ub.conf >unbound.log 2>&1 &
|
||||
UNBOUND_PID=$!
|
||||
echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test
|
||||
|
||||
cat .tpkg.var.test
|
||||
wait_ldns_testns_up fwd.log
|
||||
wait_unbound_up unbound.log
|
||||
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
# #-- auth_axfr.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="../.."
|
||||
# do the test
|
||||
echo "> dig www.example.com."
|
||||
dig @localhost -p $UNBOUND_PORT www.example.com. | tee outfile
|
||||
if grep SERVFAIL outfile; then
|
||||
echo "> try again"
|
||||
dig @localhost -p $UNBOUND_PORT www.example.com. | tee outfile
|
||||
fi
|
||||
if grep SERVFAIL outfile; then
|
||||
echo "> try again"
|
||||
sleep 1
|
||||
dig @localhost -p $UNBOUND_PORT www.example.com. | tee outfile
|
||||
fi
|
||||
if grep SERVFAIL outfile; then
|
||||
echo "> try again"
|
||||
sleep 1
|
||||
dig @localhost -p $UNBOUND_PORT www.example.com. | tee outfile
|
||||
fi
|
||||
if grep SERVFAIL outfile; then
|
||||
echo "> try again"
|
||||
sleep 1
|
||||
dig @localhost -p $UNBOUND_PORT www.example.com. | tee outfile
|
||||
fi
|
||||
if grep SERVFAIL outfile; then
|
||||
echo "> try again"
|
||||
sleep 10
|
||||
dig @localhost -p $UNBOUND_PORT www.example.com. | tee outfile
|
||||
fi
|
||||
if grep SERVFAIL outfile; then
|
||||
echo "> try again"
|
||||
sleep 10
|
||||
dig @localhost -p $UNBOUND_PORT www.example.com. | tee outfile
|
||||
fi
|
||||
echo "> cat logfiles"
|
||||
cat fwd.log
|
||||
cat unbound.log
|
||||
echo "> check answer"
|
||||
if grep "1.2.3.4" outfile; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "Not OK"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN SOA
|
||||
SECTION ANSWER
|
||||
example.com. IN SOA ns.example.com. hostmaster.example.com. 1 3600 900 86400 3600
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN AXFR
|
||||
SECTION ANSWER
|
||||
example.com. IN SOA ns.example.com. hostmaster.example.com. 1 3600 900 86400 3600
|
||||
example.com. IN NS ns.example.net.
|
||||
EXTRA_PACKET
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN AXFR
|
||||
SECTION ANSWER
|
||||
www.example.com. IN A 1.2.3.4
|
||||
example.com. IN SOA ns.example.com. hostmaster.example.com. 1 3600 900 86400 3600
|
||||
ENTRY_END
|
||||
@@ -0,0 +1,3 @@
|
||||
example.com. IN SOA ns.example.com. hostmaster.example.com. 1 3600 900 86400 3600
|
||||
example.com. IN NS ns.example.net.
|
||||
www.example.com. IN A 1.2.3.4
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
server:
|
||||
verbosity: 7
|
||||
# num-threads: 1
|
||||
interface: 127.0.0.1
|
||||
port: @PORT@
|
||||
use-syslog: no
|
||||
directory: ""
|
||||
pidfile: "unbound.pid"
|
||||
chroot: ""
|
||||
username: ""
|
||||
do-not-query-localhost: no
|
||||
use-caps-for-id: yes
|
||||
auth-zone:
|
||||
name: "example.com"
|
||||
for-upstream: yes
|
||||
for-downstream: yes
|
||||
url: "https://127.0.0.1:@TOPORT@/example.com.zone"
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
BaseName: auth_https
|
||||
Version: 1.0
|
||||
Description: Perform https for authority zone
|
||||
CreationDate: Tue 13 Jun 09:35:40 CEST 2017
|
||||
Maintainer: dr. W.C.A. Wijngaards
|
||||
Category:
|
||||
Component:
|
||||
CmdDepends:
|
||||
Depends:
|
||||
Help:
|
||||
Pre: auth_https.pre
|
||||
Post: auth_https.post
|
||||
Test: auth_https.test
|
||||
AuxFiles:
|
||||
Passed:
|
||||
Failure:
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user