mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-08-17 21:25:50 +02:00
Compare commits
106
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
97581f25a2 | ||
|
|
dff630c788 | ||
|
|
30038d8fa6 | ||
|
|
71e85ee6fb | ||
|
|
b54efa5c69 | ||
|
|
c480290a30 | ||
|
|
c1d79638c4 | ||
|
|
6f6ccee95b | ||
|
|
c44ef11de5 | ||
|
|
9c8ac75026 | ||
|
|
31f071db25 | ||
|
|
b5337c1e05 | ||
|
|
2e26ec2d01 | ||
|
|
cf8ee796c9 | ||
|
|
8b078cc509 | ||
|
|
589924e36c | ||
|
|
fd9aa53370 | ||
|
|
6dd2c0467e | ||
|
|
a7ec2af62a | ||
|
|
bbfb2f2202 | ||
|
|
1238b7979f | ||
|
|
1f29a98366 | ||
|
|
0916e1d0ea | ||
|
|
65ad15da56 | ||
|
|
5ae8bec719 | ||
|
|
e0fd0ef80c | ||
|
|
8e62925ffb | ||
|
|
e7282a291b | ||
|
|
fa909b6cc7 | ||
|
|
5fa08a0be9 | ||
|
|
1cf44b0b5c | ||
|
|
111ef6f862 | ||
|
|
33e6deb675 | ||
|
|
1aa1c1404c | ||
|
|
694f02f1df | ||
|
|
9761d0c6de | ||
|
|
3b35e412f5 | ||
|
|
35172e89f4 | ||
|
|
eb29370697 | ||
|
|
01f3e90871 | ||
|
|
7bdae2d545 | ||
|
|
ae666ea203 | ||
|
|
557aad4b72 | ||
|
|
bbb583e754 | ||
|
|
2824d0ad52 | ||
|
|
6dfa0d643b | ||
|
|
3395637700 | ||
|
|
29ce27f300 | ||
|
|
e3e6246860 | ||
|
|
c8696005a7 | ||
|
|
fc7f057d0b | ||
|
|
1befacc444 | ||
|
|
a1c76554a2 | ||
|
|
cf1d2135e1 | ||
|
|
1cee11cba8 | ||
|
|
ae5d794c47 | ||
|
|
a08cf3c4e5 | ||
|
|
8f5596f643 | ||
|
|
a798dcb5bd | ||
|
|
939c103a73 | ||
|
|
ef4d9a1ecb | ||
|
|
9a0b040403 | ||
|
|
b8b2ce58d0 | ||
|
|
6a918b841f | ||
|
|
115c36a94e | ||
|
|
03c34b695f | ||
|
|
aa0536dcb5 | ||
|
|
28131d5845 | ||
|
|
69aafe3a1c | ||
|
|
2479955f9f | ||
|
|
9b47af529e | ||
|
|
11f5e16932 | ||
|
|
3d5cef932e | ||
|
|
0f825eb283 | ||
|
|
7ea69fe9c2 | ||
|
|
83367411ef | ||
|
|
51810c1408 | ||
|
|
ddddbf284f | ||
|
|
28c9738062 | ||
|
|
cefc027dbc | ||
|
|
d66ff13f9c | ||
|
|
01027a8322 | ||
|
|
086e31e88d | ||
|
|
ce63172a67 | ||
|
|
684429e6c8 | ||
|
|
80424bc16e | ||
|
|
a16c24b4f0 | ||
|
|
52f4247c48 | ||
|
|
dfd769b60c | ||
|
|
680b0d1cce | ||
|
|
bcdd32e7e1 | ||
|
|
b6d88c0b41 | ||
|
|
7cf757596c | ||
|
|
0f57f21ca2 | ||
|
|
68d82e9ce4 | ||
|
|
881f0ad30f | ||
|
|
d9ceec4005 | ||
|
|
f82a0847eb | ||
|
|
c3f5b5f773 | ||
|
|
b72d40f3dd | ||
|
|
c4cac78f10 | ||
|
|
164f86e377 | ||
|
|
c30e90b435 | ||
|
|
365f87a4a4 | ||
|
|
1af30c02fc | ||
|
|
83938e1d3b |
+990
-297
File diff suppressed because it is too large
Load Diff
Vendored
+739
-345
File diff suppressed because it is too large
Load Diff
+49
-7
@@ -2,7 +2,13 @@
|
||||
# Copyright 2009, Wouter Wijngaards, NLnet Labs.
|
||||
# BSD licensed.
|
||||
#
|
||||
# Version 14
|
||||
# Version 20
|
||||
# 2012-01-20 Fix COMPILER_FLAGS_UNBOUND for gcc 4.6.2 assigned-not-used-warns.
|
||||
# 2011-12-05 Fix getaddrinfowithincludes on windows with fedora16 mingw32-gcc.
|
||||
# Fix ACX_MALLOC for redefined malloc error.
|
||||
# Fix GETADDRINFO_WITH_INCLUDES to add -lws2_32
|
||||
# 2011-11-10 Fix FLTO test to not drop a.out in current directory.
|
||||
# 2011-11-01 Fix FLTO test for llvm on Lion.
|
||||
# 2011-08-01 Fix nonblock test (broken at v13).
|
||||
# 2011-08-01 Fix autoconf 2.68 warnings
|
||||
# 2011-06-23 Add ACX_CHECK_FLTO to check -flto.
|
||||
@@ -254,6 +260,8 @@ int test() {
|
||||
a = getopt(2, opts, "a");
|
||||
a = isascii(32);
|
||||
str = gai_strerror(0);
|
||||
if(str && t && tv.tv_usec && msg.msg_control)
|
||||
a = 0;
|
||||
return a;
|
||||
}
|
||||
], [CFLAGS="$CFLAGS $C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_XOPEN_SOURCE_EXTENDED=1 -D_ALL_SOURCE"])
|
||||
@@ -289,6 +297,8 @@ int test() {
|
||||
a = getopt(2, opts, "a");
|
||||
a = isascii(32);
|
||||
str = gai_strerror(0);
|
||||
if(str && t && tv.tv_usec && msg.msg_control)
|
||||
a = 0;
|
||||
return a;
|
||||
}
|
||||
], [CFLAGS="$CFLAGS $C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_ALL_SOURCE"])
|
||||
@@ -355,6 +365,8 @@ int test() {
|
||||
const char* str = NULL;
|
||||
t = ctime_r(&time, buf);
|
||||
str = gai_strerror(0);
|
||||
if(t && str)
|
||||
a = 0;
|
||||
return a;
|
||||
}
|
||||
], [CFLAGS="$CFLAGS -D_POSIX_C_SOURCE=200112"])
|
||||
@@ -381,6 +393,8 @@ int test() {
|
||||
srandom(32);
|
||||
a = getopt(2, opts, "a");
|
||||
a = isascii(32);
|
||||
if(tv.tv_usec)
|
||||
a = 0;
|
||||
return a;
|
||||
}
|
||||
], [CFLAGS="$CFLAGS -D__EXTENSIONS__"])
|
||||
@@ -394,7 +408,15 @@ AC_DEFUN([ACX_CHECK_FLTO],
|
||||
[AC_MSG_CHECKING([if $CC supports -flto])
|
||||
BAKCFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS -flto"
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])], [AC_MSG_RESULT(yes)], [CFLAGS="$BAKCFLAGS" ; AC_MSG_RESULT(no)])
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])], [
|
||||
if $CC $CFLAGS -o conftest conftest.c 2>&1 | grep "warning: no debug symbols in executable" >/dev/null; then
|
||||
CFLAGS="$BAKCFLAGS"
|
||||
AC_MSG_RESULT(no)
|
||||
else
|
||||
AC_MSG_RESULT(yes)
|
||||
fi
|
||||
rm -f conftest conftest.c conftest.o
|
||||
], [CFLAGS="$BAKCFLAGS" ; AC_MSG_RESULT(no)])
|
||||
])
|
||||
|
||||
dnl Check the printf-format attribute (if any)
|
||||
@@ -784,7 +806,14 @@ int main() {
|
||||
}
|
||||
]])],
|
||||
dnl this case on linux, solaris, bsd
|
||||
[ac_cv_func_getaddrinfo="yes"],
|
||||
[ac_cv_func_getaddrinfo="yes"
|
||||
dnl see if on windows
|
||||
if test "$ac_cv_header_windows_h" = "yes"; then
|
||||
AC_DEFINE(USE_WINSOCK, 1, [Whether the windows socket API is used])
|
||||
USE_WINSOCK="1"
|
||||
LIBS="$LIBS -lws2_32"
|
||||
fi
|
||||
],
|
||||
dnl no quick getaddrinfo, try mingw32 and winsock2 library.
|
||||
ORIGLIBS="$LIBS"
|
||||
LIBS="$LIBS -lws2_32"
|
||||
@@ -1040,10 +1069,23 @@ dnl detect malloc and provide malloc compat prototype.
|
||||
dnl $1: unique name for compat code
|
||||
AC_DEFUN([ACX_FUNC_MALLOC],
|
||||
[
|
||||
AC_FUNC_MALLOC
|
||||
if test "$ac_cv_func_malloc_0_nonnull" = no; then
|
||||
AC_DEFINE_UNQUOTED([malloc], [rpl_malloc_$1], [Define if replacement function should be used.])
|
||||
fi
|
||||
AC_MSG_CHECKING([for GNU libc compatible malloc])
|
||||
AC_RUN_IFELSE([AC_LANG_PROGRAM(
|
||||
[[#if defined STDC_HEADERS || defined HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#else
|
||||
char *malloc ();
|
||||
#endif
|
||||
]], [ if(malloc(0) != 0) return 1;])
|
||||
],
|
||||
[AC_MSG_RESULT([no])
|
||||
AC_LIBOBJ(malloc)
|
||||
AC_DEFINE_UNQUOTED([malloc], [rpl_malloc_$1], [Define if replacement function should be used.])] ,
|
||||
[AC_MSG_RESULT([yes])
|
||||
AC_DEFINE([HAVE_MALLOC], 1, [If have GNU libc compatible malloc])],
|
||||
[AC_MSG_RESULT([no (crosscompile)])
|
||||
AC_LIBOBJ(malloc)
|
||||
AC_DEFINE_UNQUOTED([malloc], [rpl_malloc_$1], [Define if replacement function should be used.])] )
|
||||
])
|
||||
|
||||
dnl Define fallback for fseeko and ftello if needed.
|
||||
|
||||
@@ -135,7 +135,9 @@ inet_ntop6(const u_char *src, char *dst, size_t size)
|
||||
for (i = 0; i < IN6ADDRSZ; i++)
|
||||
words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
|
||||
best.base = -1;
|
||||
best.len = 0;
|
||||
cur.base = -1;
|
||||
cur.len = 0;
|
||||
for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
|
||||
if (words[i] == 0) {
|
||||
if (cur.base == -1)
|
||||
|
||||
+1
-3
@@ -106,12 +106,10 @@ str2int(const char **buf, int max)
|
||||
char *
|
||||
unbound_strptime(const char *s, const char *format, struct tm *tm)
|
||||
{
|
||||
int c, alt_format, ret;
|
||||
int c, ret;
|
||||
int split_year = 0;
|
||||
|
||||
while ((c = *format) != '\0') {
|
||||
alt_format = 0;
|
||||
|
||||
/* whitespace, literal or format */
|
||||
if (isspace(c)) { /* whitespace */
|
||||
/** whitespace matches zero or more whitespace characters in the
|
||||
|
||||
+6
-2
@@ -25,6 +25,11 @@
|
||||
/* Define if you want to use debug lock checking (slow). */
|
||||
#undef ENABLE_LOCK_CHECKS
|
||||
|
||||
/* Define this if you enabled-allsymbols from libunbound to link binaries to
|
||||
it for smaller install size, but the libunbound export table is polluted by
|
||||
internal symbols */
|
||||
#undef EXPORT_ALL_SYMBOLS
|
||||
|
||||
/* Define to 1 if you have the <arpa/inet.h> header file. */
|
||||
#undef HAVE_ARPA_INET_H
|
||||
|
||||
@@ -165,8 +170,7 @@
|
||||
/* Define to 1 if you have the <login_cap.h> header file. */
|
||||
#undef HAVE_LOGIN_CAP_H
|
||||
|
||||
/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
|
||||
to 0 otherwise. */
|
||||
/* If have GNU libc compatible malloc */
|
||||
#undef HAVE_MALLOC
|
||||
|
||||
/* Define to 1 if you have the `memmove' function. */
|
||||
|
||||
+262
-61
@@ -6,11 +6,11 @@ sinclude(acx_pthread.m4)
|
||||
sinclude(acx_python.m4)
|
||||
sinclude(ac_pkg_swig.m4)
|
||||
|
||||
AC_INIT(unbound, 1.4.13, unbound-bugs@nlnetlabs.nl, unbound)
|
||||
AC_INIT(unbound, 1.4.16, unbound-bugs@nlnetlabs.nl, unbound)
|
||||
|
||||
LIBUNBOUND_CURRENT=2
|
||||
LIBUNBOUND_REVISION=13
|
||||
LIBUNBOUND_AGE=0
|
||||
LIBUNBOUND_CURRENT=3
|
||||
LIBUNBOUND_REVISION=1
|
||||
LIBUNBOUND_AGE=1
|
||||
# 1.0.0 had 0:12:0
|
||||
# 1.0.1 had 0:13:0
|
||||
# 1.0.2 had 0:14:0
|
||||
@@ -38,6 +38,10 @@ LIBUNBOUND_AGE=0
|
||||
# 1.4.11 had 2:11:0
|
||||
# 1.4.12 had 2:12:0
|
||||
# 1.4.13 had 2:13:0
|
||||
# and 1.4.13p1 and 1.4.13.p2
|
||||
# 1.4.14 had 2:14:0
|
||||
# 1.4.15 had 3:0:1 # adds ub_version()
|
||||
# 1.4.16 had 3:1:1
|
||||
|
||||
# Current -- the number of the binary API that we're implementing
|
||||
# Revision -- which iteration of the implementation of the binary
|
||||
@@ -285,6 +289,31 @@ AC_SUBST(RUNTIME_PATH)
|
||||
AC_SEARCH_LIBS([inet_pton], [nsl])
|
||||
AC_SEARCH_LIBS([socket], [socket])
|
||||
|
||||
# check wether strptime also works
|
||||
AC_DEFUN([AC_CHECK_STRPTIME_WORKS],
|
||||
[AC_REQUIRE([AC_PROG_CC])
|
||||
AC_MSG_CHECKING(whether strptime works)
|
||||
if test c${cross_compiling} = cno; then
|
||||
AC_RUN_IFELSE([AC_LANG_SOURCE([[
|
||||
#define _XOPEN_SOURCE
|
||||
#include <time.h>
|
||||
int main(void) { struct tm tm; char *res;
|
||||
res = strptime("2010-07-15T00:00:00+00:00", "%t%Y%t-%t%m%t-%t%d%tT%t%H%t:%t%M%t:%t%S%t", &tm);
|
||||
if (!res) return 2;
|
||||
res = strptime("20070207111842", "%Y%m%d%H%M%S", &tm);
|
||||
if (!res) return 1; return 0; }
|
||||
]])] , [eval "ac_cv_c_strptime_works=yes"], [eval "ac_cv_c_strptime_works=no"])
|
||||
else
|
||||
eval "ac_cv_c_strptime_works=maybe"
|
||||
fi
|
||||
AC_MSG_RESULT($ac_cv_c_strptime_works)
|
||||
if test $ac_cv_c_strptime_works = no; then
|
||||
AC_LIBOBJ(strptime)
|
||||
else
|
||||
AC_DEFINE_UNQUOTED([STRPTIME_WORKS], 1, [use default strptime.])
|
||||
fi
|
||||
])dnl
|
||||
|
||||
# check some functions of the OS before linking libs (while still runnable).
|
||||
AC_FUNC_CHOWN
|
||||
AC_FUNC_FORK
|
||||
@@ -293,6 +322,30 @@ AC_FUNC_FSEEKO
|
||||
ACX_SYS_LARGEFILE
|
||||
ACX_CHECK_NONBLOCKING_BROKEN
|
||||
ACX_MKDIR_ONE_ARG
|
||||
AC_CHECK_FUNCS([strptime],[AC_CHECK_STRPTIME_WORKS],[AC_LIBOBJ([strptime])])
|
||||
|
||||
# set memory allocation checking if requested
|
||||
AC_ARG_ENABLE(alloc-checks, AC_HELP_STRING([--enable-alloc-checks],
|
||||
[ enable to memory allocation statistics, for debug purposes ]),
|
||||
, )
|
||||
AC_ARG_ENABLE(alloc-lite, AC_HELP_STRING([--enable-alloc-lite],
|
||||
[ enable for lightweight alloc assertions, for debug purposes ]),
|
||||
, )
|
||||
AC_ARG_ENABLE(alloc-nonregional, AC_HELP_STRING([--enable-alloc-nonregional],
|
||||
[ enable nonregional allocs, slow but exposes regional allocations to other memory purifiers, for debug purposes ]),
|
||||
, )
|
||||
if test x_$enable_alloc_nonregional = x_yes; then
|
||||
AC_DEFINE(UNBOUND_ALLOC_NONREGIONAL, 1, [use malloc not regions, for debug use])
|
||||
fi
|
||||
if test x_$enable_alloc_checks = x_yes; then
|
||||
AC_DEFINE(UNBOUND_ALLOC_STATS, 1, [use statistics for allocs and frees, for debug use])
|
||||
else
|
||||
if test x_$enable_alloc_lite = x_yes; then
|
||||
AC_DEFINE(UNBOUND_ALLOC_LITE, 1, [use to enable lightweight alloc assertions, for debug use])
|
||||
else
|
||||
ACX_FUNC_MALLOC([unbound])
|
||||
fi
|
||||
fi
|
||||
|
||||
# check windows threads (we use them, not pthreads, on windows).
|
||||
if test "$on_mingw" = "yes"; then
|
||||
@@ -417,6 +470,12 @@ if test x_$ub_test_python != x_no; then
|
||||
AC_DEFINE(WITH_PYTHONMODULE, 1, [Define if you want Python module.])
|
||||
WITH_PYTHONMODULE=yes
|
||||
AC_SUBST(WITH_PYTHONMODULE)
|
||||
PYTHONMOD_OBJ="pythonmod.lo pythonmod_utils.lo"
|
||||
AC_SUBST(PYTHONMOD_OBJ)
|
||||
PYTHONMOD_INSTALL=pythonmod-install
|
||||
AC_SUBST(PYTHONMOD_INSTALL)
|
||||
PYTHONMOD_UNINSTALL=pythonmod-uninstall
|
||||
AC_SUBST(PYTHONMOD_UNINSTALL)
|
||||
fi
|
||||
|
||||
# Declare PyUnbound
|
||||
@@ -424,6 +483,14 @@ if test x_$ub_test_python != x_no; then
|
||||
AC_DEFINE(WITH_PYUNBOUND, 1, [Define if you want PyUnbound.])
|
||||
WITH_PYUNBOUND=yes
|
||||
AC_SUBST(WITH_PYUNBOUND)
|
||||
PYUNBOUND_OBJ="libunbound_wrap.lo"
|
||||
AC_SUBST(PYUNBOUND_OBJ)
|
||||
PYUNBOUND_TARGET="_unbound.la"
|
||||
AC_SUBST(PYUNBOUND_TARGET)
|
||||
PYUNBOUND_INSTALL=pyunbound-install
|
||||
AC_SUBST(PYUNBOUND_INSTALL)
|
||||
PYUNBOUND_UNINSTALL=pyunbound-uninstall
|
||||
AC_SUBST(PYUNBOUND_UNINSTALL)
|
||||
fi
|
||||
fi
|
||||
else
|
||||
@@ -433,6 +500,13 @@ if test x_$ub_test_python != x_no; then
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "`uname`" = "NetBSD"; then
|
||||
NETBSD_LINTFLAGS='"-D__RENAME(x)=" -D_NETINET_IN_H_'
|
||||
AC_SUBST(NETBSD_LINTFLAGS)
|
||||
fi
|
||||
CONFIG_DATE=`date +%Y%m%d`
|
||||
AC_SUBST(CONFIG_DATE)
|
||||
|
||||
# Checks for libraries.
|
||||
ACX_WITH_SSL
|
||||
ACX_LIB_SSL
|
||||
@@ -469,6 +543,104 @@ case "$enable_sha2" in
|
||||
;;
|
||||
esac
|
||||
|
||||
# check wether gost also works
|
||||
AC_DEFUN([AC_CHECK_GOST_WORKS],
|
||||
[AC_REQUIRE([AC_PROG_CC])
|
||||
AC_MSG_CHECKING([if GOST works])
|
||||
if test c${cross_compiling} = cno; then
|
||||
BAKCFLAGS="$CFLAGS"
|
||||
if test -n "$ssldir"; then
|
||||
CFLAGS="$CFLAGS -Wl,-rpath,$ssldir/lib"
|
||||
fi
|
||||
AC_RUN_IFELSE([AC_LANG_SOURCE([[
|
||||
#include <string.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/engine.h>
|
||||
#include <openssl/conf.h>
|
||||
/* routine to load gost from ldns */
|
||||
int load_gost_id(void)
|
||||
{
|
||||
static int gost_id = 0;
|
||||
const EVP_PKEY_ASN1_METHOD* meth;
|
||||
ENGINE* e;
|
||||
|
||||
if(gost_id) return gost_id;
|
||||
|
||||
/* see if configuration loaded gost implementation from other engine*/
|
||||
meth = EVP_PKEY_asn1_find_str(NULL, "gost2001", -1);
|
||||
if(meth) {
|
||||
EVP_PKEY_asn1_get0_info(&gost_id, NULL, NULL, NULL, NULL, meth);
|
||||
return gost_id;
|
||||
}
|
||||
|
||||
/* see if engine can be loaded already */
|
||||
e = ENGINE_by_id("gost");
|
||||
if(!e) {
|
||||
/* load it ourself, in case statically linked */
|
||||
ENGINE_load_builtin_engines();
|
||||
ENGINE_load_dynamic();
|
||||
e = ENGINE_by_id("gost");
|
||||
}
|
||||
if(!e) {
|
||||
/* no gost engine in openssl */
|
||||
return 0;
|
||||
}
|
||||
if(!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
|
||||
ENGINE_finish(e);
|
||||
ENGINE_free(e);
|
||||
return 0;
|
||||
}
|
||||
|
||||
meth = EVP_PKEY_asn1_find_str(&e, "gost2001", -1);
|
||||
if(!meth) {
|
||||
/* algo not found */
|
||||
ENGINE_finish(e);
|
||||
ENGINE_free(e);
|
||||
return 0;
|
||||
}
|
||||
EVP_PKEY_asn1_get0_info(&gost_id, NULL, NULL, NULL, NULL, meth);
|
||||
return gost_id;
|
||||
}
|
||||
int main(void) {
|
||||
EVP_MD_CTX* ctx;
|
||||
const EVP_MD* md;
|
||||
unsigned char digest[64]; /* its a 256-bit digest, so uses 32 bytes */
|
||||
const char* str = "Hello world";
|
||||
const unsigned char check[] = {
|
||||
0x40 , 0xed , 0xf8 , 0x56 , 0x5a , 0xc5 , 0x36 , 0xe1 ,
|
||||
0x33 , 0x7c , 0x7e , 0x87 , 0x62 , 0x1c , 0x42 , 0xe0 ,
|
||||
0x17 , 0x1b , 0x5e , 0xce , 0xa8 , 0x46 , 0x65 , 0x4d ,
|
||||
0x8d , 0x3e , 0x22 , 0x9b , 0xe1 , 0x30 , 0x19 , 0x9d
|
||||
};
|
||||
OPENSSL_config(NULL);
|
||||
(void)load_gost_id();
|
||||
md = EVP_get_digestbyname("md_gost94");
|
||||
if(!md) return 1;
|
||||
memset(digest, 0, sizeof(digest));
|
||||
ctx = EVP_MD_CTX_create();
|
||||
if(!ctx) return 2;
|
||||
if(!EVP_DigestInit_ex(ctx, md, NULL)) return 3;
|
||||
if(!EVP_DigestUpdate(ctx, str, 10)) return 4;
|
||||
if(!EVP_DigestFinal_ex(ctx, digest, NULL)) return 5;
|
||||
/* uncomment to see the hash calculated.
|
||||
{int i;
|
||||
for(i=0; i<32; i++)
|
||||
printf(" %2.2x", (int)digest[i]);
|
||||
printf("\n");}
|
||||
*/
|
||||
if(memcmp(digest, check, sizeof(check)) != 0)
|
||||
return 6;
|
||||
return 0;
|
||||
}
|
||||
]])] , [eval "ac_cv_c_gost_works=yes"], [eval "ac_cv_c_gost_works=no"])
|
||||
CFLAGS="$BAKCFLAGS"
|
||||
else
|
||||
eval "ac_cv_c_gost_works=maybe"
|
||||
fi
|
||||
AC_MSG_RESULT($ac_cv_c_gost_works)
|
||||
])dnl
|
||||
|
||||
AC_ARG_ENABLE(gost, AC_HELP_STRING([--disable-gost], [Disable GOST support]))
|
||||
use_gost="no"
|
||||
case "$enable_gost" in
|
||||
@@ -477,8 +649,11 @@ case "$enable_gost" in
|
||||
*)
|
||||
AC_CHECK_FUNC(EVP_PKEY_set_type_str, [:],[AC_MSG_ERROR([OpenSSL 1.0.0 is needed for GOST support])])
|
||||
AC_CHECK_FUNC(EC_KEY_new, [], [AC_MSG_ERROR([OpenSSL does not support ECC, needed for GOST support])])
|
||||
use_gost="yes"
|
||||
AC_DEFINE([USE_GOST], [1], [Define this to enable GOST support.])
|
||||
AC_CHECK_GOST_WORKS
|
||||
if test $ac_cv_c_gost_works != no; then
|
||||
use_gost="yes"
|
||||
AC_DEFINE([USE_GOST], [1], [Define this to enable GOST support.])
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -606,43 +781,34 @@ AC_ARG_ENABLE(lock_checks, AC_HELP_STRING([--enable-lock-checks],
|
||||
, )
|
||||
if test x_$enable_lock_checks = x_yes; then
|
||||
AC_DEFINE(ENABLE_LOCK_CHECKS, 1, [Define if you want to use debug lock checking (slow).])
|
||||
CHECKLOCK_SRC="testcode/checklocks.c"
|
||||
AC_SUBST(CHECKLOCK_SRC)
|
||||
fi
|
||||
|
||||
# set memory allocation checking if requested
|
||||
AC_ARG_ENABLE(alloc-checks, AC_HELP_STRING([--enable-alloc-checks],
|
||||
[ enable to memory allocation statistics, for debug purposes ]),
|
||||
, )
|
||||
AC_ARG_ENABLE(alloc-lite, AC_HELP_STRING([--enable-alloc-lite],
|
||||
[ enable for lightweight alloc assertions, for debug purposes ]),
|
||||
, )
|
||||
AC_ARG_ENABLE(alloc-nonregional, AC_HELP_STRING([--enable-alloc-nonregional],
|
||||
[ enable nonregional allocs, slow but exposes regional allocations to other memory purifiers, for debug purposes ]),
|
||||
, )
|
||||
if test x_$enable_alloc_nonregional = x_yes; then
|
||||
AC_DEFINE(UNBOUND_ALLOC_NONREGIONAL, 1, [use malloc not regions, for debug use])
|
||||
fi
|
||||
if test x_$enable_alloc_checks = x_yes; then
|
||||
AC_DEFINE(UNBOUND_ALLOC_STATS, 1, [use statistics for allocs and frees, for debug use])
|
||||
else
|
||||
if test x_$enable_alloc_lite = x_yes; then
|
||||
AC_DEFINE(UNBOUND_ALLOC_LITE, 1, [use to enable lightweight alloc assertions, for debug use])
|
||||
else
|
||||
ACX_FUNC_MALLOC([unbound])
|
||||
fi
|
||||
CHECKLOCK_OBJ="checklocks.lo"
|
||||
AC_SUBST(CHECKLOCK_OBJ)
|
||||
fi
|
||||
|
||||
ACX_CHECK_GETADDRINFO_WITH_INCLUDES
|
||||
if test "$USE_WINSOCK" = 1; then
|
||||
AC_DEFINE(UB_ON_WINDOWS, 1, [Use win32 resources and API])
|
||||
UB_ON_WINDOWS=yes
|
||||
AC_SUBST(UB_ON_WINDOWS)
|
||||
AC_CHECK_HEADERS([iphlpapi.h],,, [AC_INCLUDES_DEFAULT
|
||||
#include <windows.h>
|
||||
])
|
||||
AC_CHECK_TOOL(WINDRES, windres)
|
||||
LIBS="$LIBS -liphlpapi"
|
||||
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"
|
||||
AC_SUBST(WIN_DAEMON_SRC)
|
||||
WIN_DAEMON_OBJ="win_svc.lo w_inst.lo"
|
||||
AC_SUBST(WIN_DAEMON_OBJ)
|
||||
WIN_DAEMON_OBJ_LINK="rsrc_unbound.o"
|
||||
AC_SUBST(WIN_DAEMON_OBJ_LINK)
|
||||
WIN_HOST_OBJ_LINK="rsrc_unbound_host.o"
|
||||
AC_SUBST(WIN_HOST_OBJ_LINK)
|
||||
WIN_UBANCHOR_OBJ_LINK="rsrc_unbound_anchor.o log.lo locks.lo"
|
||||
AC_SUBST(WIN_UBANCHOR_OBJ_LINK)
|
||||
WIN_CONTROL_OBJ_LINK="rsrc_unbound_control.o"
|
||||
AC_SUBST(WIN_CONTROL_OBJ_LINK)
|
||||
WIN_CHECKCONF_OBJ_LINK="rsrc_unbound_checkconf.o"
|
||||
AC_SUBST(WIN_CHECKCONF_OBJ_LINK)
|
||||
fi
|
||||
if test $ac_cv_func_getaddrinfo = no; then
|
||||
AC_LIBOBJ([fake-rfc2553])
|
||||
@@ -658,29 +824,6 @@ if test $ac_cv_func_daemon = yes; then
|
||||
])
|
||||
fi
|
||||
|
||||
# check wether strptime also works
|
||||
AC_DEFUN([AC_CHECK_STRPTIME_WORKS],
|
||||
[AC_REQUIRE([AC_PROG_CC])
|
||||
AC_MSG_CHECKING(whether strptime works)
|
||||
if test c${cross_compiling} = cno; then
|
||||
AC_RUN_IFELSE([AC_LANG_SOURCE([[
|
||||
#define _XOPEN_SOURCE
|
||||
#include <time.h>
|
||||
int main(void) { struct tm tm; char *res;
|
||||
res = strptime("20070207111842", "%Y%m%d%H%M%S", &tm);
|
||||
if (!res) return 1; return 0; }
|
||||
]])] , [eval "ac_cv_c_strptime_works=yes"], [eval "ac_cv_c_strptime_works=no"])
|
||||
else
|
||||
eval "ac_cv_c_strptime_works=maybe"
|
||||
fi
|
||||
AC_MSG_RESULT($ac_cv_c_strptime_works)
|
||||
if test $ac_cv_c_strptime_works = no; then
|
||||
AC_LIBOBJ(strptime)
|
||||
else
|
||||
AC_DEFINE_UNQUOTED([STRPTIME_WORKS], 1, [use default strptime.])
|
||||
fi
|
||||
])dnl
|
||||
AC_CHECK_FUNCS([strptime],[AC_CHECK_STRPTIME_WORKS],[AC_LIBOBJ([strptime])])
|
||||
AC_SEARCH_LIBS([setusercontext], [util])
|
||||
AC_CHECK_FUNCS([tzset sigprocmask fcntl getpwnam getrlimit setrlimit setsid sbrk chroot kill sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex])
|
||||
AC_CHECK_FUNCS([setresuid],,[AC_CHECK_FUNCS([setreuid])])
|
||||
@@ -697,18 +840,76 @@ AC_REPLACE_FUNCS(snprintf)
|
||||
AC_REPLACE_FUNCS(strlcpy)
|
||||
AC_REPLACE_FUNCS(memmove)
|
||||
AC_REPLACE_FUNCS(gmtime_r)
|
||||
LIBOBJ_WITHOUT_CTIME="$LIBOBJS"
|
||||
AC_SUBST(LIBOBJ_WITHOUT_CTIME)
|
||||
AC_REPLACE_FUNCS(ctime_r)
|
||||
|
||||
AC_ARG_ENABLE(allsymbols, AC_HELP_STRING([--enable-allsymbols], [export all symbols from libunbound and link binaries to it, smaller install size but libunbound export table is polluted by internal symbols]))
|
||||
case "$enable_allsymbols" in
|
||||
no)
|
||||
EXPORT_ALL_SYMBOLS=no
|
||||
;;
|
||||
yes)
|
||||
EXPORT_ALL_SYMBOLS=yes
|
||||
COMMON_OBJ_ALL_SYMBOLS=""
|
||||
UBSYMS=""
|
||||
EXTRALINK="-L. -L.libs -lunbound"
|
||||
AC_DEFINE(EXPORT_ALL_SYMBOLS, 1, [Define this if you enabled-allsymbols from libunbound to link binaries to it for smaller install size, but the libunbound export table is polluted by internal symbols])
|
||||
;;
|
||||
no|*)
|
||||
COMMON_OBJ_ALL_SYMBOLS='$(COMMON_OBJ)'
|
||||
UBSYMS='-export-symbols $(srcdir)/libunbound/ubsyms.def'
|
||||
EXTRALINK=""
|
||||
;;
|
||||
esac
|
||||
AC_SUBST(EXPORT_ALL_SYMBOLS)
|
||||
AC_SUBST(COMMON_OBJ_ALL_SYMBOLS)
|
||||
AC_SUBST(EXTRALINK)
|
||||
AC_SUBST(UBSYMS)
|
||||
if test x_$enable_lock_checks = x_yes; then
|
||||
UBSYMS="-export-symbols clubsyms.def"
|
||||
cp ${srcdir}/libunbound/ubsyms.def clubsyms.def
|
||||
echo lock_protect >> clubsyms.def
|
||||
echo lock_unprotect >> clubsyms.def
|
||||
echo lock_get_mem >> clubsyms.def
|
||||
echo checklock_start >> clubsyms.def
|
||||
echo checklock_stop >> clubsyms.def
|
||||
echo checklock_lock >> clubsyms.def
|
||||
echo checklock_unlock >> clubsyms.def
|
||||
echo checklock_init >> clubsyms.def
|
||||
echo checklock_thrcreate >> clubsyms.def
|
||||
echo checklock_thrjoin >> clubsyms.def
|
||||
fi
|
||||
|
||||
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).
|
||||
# gmake works.
|
||||
cat >conftest.make <<EOF
|
||||
all: conftest.lo
|
||||
|
||||
conftest.lo foo.lo bla.lo:
|
||||
if test -f "\$<"; then touch \$@; fi
|
||||
|
||||
.SUFFIXES: .lo
|
||||
.c.lo:
|
||||
if test -f "\$<"; then touch \$@; fi
|
||||
|
||||
conftest.lo: conftest.dir/conftest.c
|
||||
EOF
|
||||
mkdir conftest.dir
|
||||
touch conftest.dir/conftest.c
|
||||
rm -f conftest.lo conftest.c
|
||||
${MAKE:-make} -f conftest.make >/dev/null
|
||||
rm -f conftest.make conftest.c conftest.dir/conftest.c
|
||||
rm -rf conftest.dir
|
||||
if test ! -f conftest.lo; then
|
||||
AC_MSG_RESULT(no)
|
||||
SOURCEDETERMINE='echo "$^" | awk "-F " "{print \$$1;}" > .source'
|
||||
SOURCEFILE='`cat .source`'
|
||||
else
|
||||
AC_MSG_RESULT(yes)
|
||||
SOURCEDETERMINE=':'
|
||||
SOURCEFILE='$<'
|
||||
fi
|
||||
rm -f conftest.lo
|
||||
AC_SUBST(SOURCEDETERMINE)
|
||||
AC_SUBST(SOURCEFILE)
|
||||
|
||||
# check this after all other compilation checks, since the linking of the lib
|
||||
# may break checks after this.
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# plugin for munin to monitor usage of unbound servers.
|
||||
# To install copy this to /usr/local/share/munin/plugins/unbound_munin_
|
||||
# and use munin-node-configure (--suggest, --shell).
|
||||
#
|
||||
# (C) 2008 W.C.A. Wijngaards. BSD Licensed.
|
||||
#
|
||||
@@ -45,9 +47,9 @@
|
||||
# unbound_munin_histogram - histogram of query resolving times
|
||||
#
|
||||
# Magic markers - optional - used by installation scripts and
|
||||
# munin-config:
|
||||
# munin-config: (originally contrib family but munin-node-configure ignores it)
|
||||
#
|
||||
#%# family=contrib
|
||||
#%# family=auto
|
||||
#%# capabilities=autoconf suggest
|
||||
|
||||
# POD documentation
|
||||
@@ -175,7 +177,7 @@ if test "$1" = "autoconf" ; then
|
||||
exit 1
|
||||
fi
|
||||
if test ! -d `dirname $state`; then
|
||||
echo no "($state directory does not exist)"
|
||||
echo no "(`dirname $state` directory does not exist)"
|
||||
exit 1
|
||||
fi
|
||||
echo yes
|
||||
|
||||
+7
-4
@@ -40,7 +40,7 @@
|
||||
* to text format.
|
||||
*/
|
||||
#include "config.h"
|
||||
#include "ldns/ldns.h"
|
||||
#include <ldns/ldns.h>
|
||||
#include "daemon/cachedump.h"
|
||||
#include "daemon/remote.h"
|
||||
#include "daemon/worker.h"
|
||||
@@ -765,7 +765,7 @@ load_msg(SSL* ssl, ldns_buffer* buf, struct worker* worker)
|
||||
if(!go_on)
|
||||
return 1; /* skip this one, not all references satisfied */
|
||||
|
||||
if(!dns_cache_store(&worker->env, &qinf, &rep, 0, 0)) {
|
||||
if(!dns_cache_store(&worker->env, &qinf, &rep, 0, 0, NULL)) {
|
||||
log_warn("error out of memory");
|
||||
return 0;
|
||||
}
|
||||
@@ -814,8 +814,10 @@ print_dp_details(SSL* ssl, struct worker* worker, struct delegpt* dp)
|
||||
return;
|
||||
}
|
||||
/* lookup in infra cache */
|
||||
delay=0;
|
||||
entry_ttl = infra_get_host_rto(worker->env.infra_cache,
|
||||
&a->addr, a->addrlen, &ri, &delay, *worker->env.now);
|
||||
&a->addr, a->addrlen, dp->name, dp->namelen,
|
||||
&ri, &delay, *worker->env.now);
|
||||
if(entry_ttl == -2 && ri.rto >= USEFUL_SERVER_TOP_TIMEOUT) {
|
||||
if(!ssl_printf(ssl, "expired, rto %d msec.\n", ri.rto))
|
||||
return;
|
||||
@@ -848,7 +850,8 @@ print_dp_details(SSL* ssl, struct worker* worker, struct delegpt* dp)
|
||||
if(!ssl_printf(ssl, ", probedelay %d", delay))
|
||||
return;
|
||||
if(infra_host(worker->env.infra_cache, &a->addr, a->addrlen,
|
||||
*worker->env.now, &edns_vs, &edns_lame_known, &to)) {
|
||||
dp->name, dp->namelen, *worker->env.now, &edns_vs,
|
||||
&edns_lame_known, &to)) {
|
||||
if(edns_vs == -1) {
|
||||
if(!ssl_printf(ssl, ", noEDNS%s.",
|
||||
edns_lame_known?" probed":" assumed"))
|
||||
|
||||
+5
-1
@@ -55,7 +55,7 @@
|
||||
#ifdef HAVE_OPENSSL_ENGINE_H
|
||||
#include <openssl/engine.h>
|
||||
#endif
|
||||
#include "ldns/ldns.h"
|
||||
#include <ldns/ldns.h>
|
||||
#include "daemon/daemon.h"
|
||||
#include "daemon/worker.h"
|
||||
#include "daemon/remote.h"
|
||||
@@ -63,6 +63,7 @@
|
||||
#include "util/log.h"
|
||||
#include "util/config_file.h"
|
||||
#include "util/data/msgreply.h"
|
||||
#include "util/storage/lookup3.h"
|
||||
#include "util/storage/slabhash.h"
|
||||
#include "services/listen_dnsport.h"
|
||||
#include "services/cache/rrset.h"
|
||||
@@ -320,6 +321,7 @@ daemon_create_workers(struct daemon* daemon)
|
||||
if(!daemon->rand)
|
||||
fatal_exit("could not init random generator");
|
||||
}
|
||||
hash_set_raninit((uint32_t)ub_random(daemon->rand));
|
||||
shufport = (int*)calloc(65536, sizeof(int));
|
||||
if(!shufport)
|
||||
fatal_exit("out of memory during daemon init");
|
||||
@@ -528,6 +530,8 @@ daemon_delete(struct daemon* daemon)
|
||||
free(daemon->chroot);
|
||||
free(daemon->pidfile);
|
||||
free(daemon->env);
|
||||
SSL_CTX_free((SSL_CTX*)daemon->listen_sslctx);
|
||||
SSL_CTX_free((SSL_CTX*)daemon->connect_sslctx);
|
||||
free(daemon);
|
||||
#ifdef LEX_HAS_YYLEX_DESTROY
|
||||
/* lex cleanup */
|
||||
|
||||
@@ -80,6 +80,8 @@ struct daemon {
|
||||
struct listen_port* rc_ports;
|
||||
/** remote control connections management (for first worker) */
|
||||
struct daemon_remote* rc;
|
||||
/** ssl context for listening to dnstcp over ssl, and connecting ssl */
|
||||
void* listen_sslctx, *connect_sslctx;
|
||||
/** num threads allocated */
|
||||
int num;
|
||||
/** the worker entries */
|
||||
|
||||
+76
-87
@@ -47,7 +47,7 @@
|
||||
#include <openssl/err.h>
|
||||
#endif
|
||||
#include <ctype.h>
|
||||
#include "ldns/ldns.h"
|
||||
#include <ldns/ldns.h>
|
||||
#include "daemon/remote.h"
|
||||
#include "daemon/worker.h"
|
||||
#include "daemon/daemon.h"
|
||||
@@ -92,21 +92,6 @@
|
||||
/** if true, inhibits a lot of =0 lines from the stats output */
|
||||
static const int inhibit_zero = 1;
|
||||
|
||||
/** log ssl crypto err */
|
||||
static void
|
||||
log_crypto_err(const char* str)
|
||||
{
|
||||
/* error:[error code]:[library name]:[function name]:[reason string] */
|
||||
char buf[128];
|
||||
unsigned long e;
|
||||
ERR_error_string_n(ERR_get_error(), buf, sizeof(buf));
|
||||
log_err("%s crypto %s", str, buf);
|
||||
while( (e=ERR_get_error()) ) {
|
||||
ERR_error_string_n(e, buf, sizeof(buf));
|
||||
log_err("and additionally crypto %s", buf);
|
||||
}
|
||||
}
|
||||
|
||||
/** subtract timers and the values do not overflow or become negative */
|
||||
static void
|
||||
timeval_subtract(struct timeval* d, const struct timeval* end,
|
||||
@@ -1103,33 +1088,6 @@ do_flush_stats(SSL* ssl, struct worker* worker)
|
||||
send_ok(ssl);
|
||||
}
|
||||
|
||||
/** flush infra cache */
|
||||
static void
|
||||
do_flush_infra(SSL* ssl, struct worker* worker, char* arg)
|
||||
{
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t len;
|
||||
if(strcmp(arg, "all") == 0) {
|
||||
slabhash_clear(worker->env.infra_cache->hosts);
|
||||
send_ok(ssl);
|
||||
return;
|
||||
}
|
||||
if(!ipstrtoaddr(arg, UNBOUND_DNS_PORT, &addr, &len)) {
|
||||
(void)ssl_printf(ssl, "error parsing ip addr: '%s'\n", arg);
|
||||
return;
|
||||
}
|
||||
infra_remove_host(worker->env.infra_cache, &addr, len);
|
||||
send_ok(ssl);
|
||||
}
|
||||
|
||||
/** flush requestlist */
|
||||
static void
|
||||
do_flush_requestlist(SSL* ssl, struct worker* worker)
|
||||
{
|
||||
mesh_delete_all(worker->env.mesh);
|
||||
send_ok(ssl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Local info for deletion functions
|
||||
*/
|
||||
@@ -1152,8 +1110,71 @@ struct del_info {
|
||||
size_t num_msgs;
|
||||
/** number of key entries removed */
|
||||
size_t num_keys;
|
||||
/** length of addr */
|
||||
socklen_t addrlen;
|
||||
/** socket address for host deletion */
|
||||
struct sockaddr_storage addr;
|
||||
};
|
||||
|
||||
/** callback to delete hosts in infra cache */
|
||||
static void
|
||||
infra_del_host(struct lruhash_entry* e, void* arg)
|
||||
{
|
||||
/* entry is locked */
|
||||
struct del_info* inf = (struct del_info*)arg;
|
||||
struct infra_key* k = (struct infra_key*)e->key;
|
||||
if(sockaddr_cmp(&inf->addr, inf->addrlen, &k->addr, k->addrlen) == 0) {
|
||||
struct infra_data* d = (struct infra_data*)e->data;
|
||||
if(d->ttl >= inf->now) {
|
||||
d->ttl = inf->expired;
|
||||
inf->num_keys++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** flush infra cache */
|
||||
static void
|
||||
do_flush_infra(SSL* ssl, struct worker* worker, char* arg)
|
||||
{
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t len;
|
||||
struct del_info inf;
|
||||
if(strcmp(arg, "all") == 0) {
|
||||
slabhash_clear(worker->env.infra_cache->hosts);
|
||||
send_ok(ssl);
|
||||
return;
|
||||
}
|
||||
if(!ipstrtoaddr(arg, UNBOUND_DNS_PORT, &addr, &len)) {
|
||||
(void)ssl_printf(ssl, "error parsing ip addr: '%s'\n", arg);
|
||||
return;
|
||||
}
|
||||
/* delete all entries from cache */
|
||||
/* what we do is to set them all expired */
|
||||
inf.worker = worker;
|
||||
inf.name = 0;
|
||||
inf.len = 0;
|
||||
inf.labs = 0;
|
||||
inf.now = *worker->env.now;
|
||||
inf.expired = *worker->env.now;
|
||||
inf.expired -= 3; /* handle 3 seconds skew between threads */
|
||||
inf.num_rrsets = 0;
|
||||
inf.num_msgs = 0;
|
||||
inf.num_keys = 0;
|
||||
inf.addrlen = len;
|
||||
memmove(&inf.addr, &addr, len);
|
||||
slabhash_traverse(worker->env.infra_cache->hosts, 1, &infra_del_host,
|
||||
&inf);
|
||||
send_ok(ssl);
|
||||
}
|
||||
|
||||
/** flush requestlist */
|
||||
static void
|
||||
do_flush_requestlist(SSL* ssl, struct worker* worker)
|
||||
{
|
||||
mesh_delete_all(worker->env.mesh);
|
||||
send_ok(ssl);
|
||||
}
|
||||
|
||||
/** callback to delete rrsets in a zone */
|
||||
static void
|
||||
zone_del_rrset(struct lruhash_entry* e, void* arg)
|
||||
@@ -1527,68 +1548,36 @@ struct infra_arg {
|
||||
SSL* ssl;
|
||||
/** the time now */
|
||||
uint32_t now;
|
||||
/** ipstr */
|
||||
char* ipstr;
|
||||
};
|
||||
|
||||
/** callback for every lame element in the infra cache */
|
||||
static void
|
||||
dump_infra_lame(struct lruhash_entry* e, void* arg)
|
||||
{
|
||||
struct infra_arg* a = (struct infra_arg*)arg;
|
||||
struct infra_lame_key* k = (struct infra_lame_key*)e->key;
|
||||
struct infra_lame_data* d = (struct infra_lame_data*)e->data;
|
||||
ldns_rdf* rdf;
|
||||
size_t pos = 0;
|
||||
char* nm;
|
||||
/* skip expired */
|
||||
if(d->ttl < a->now) {
|
||||
return;
|
||||
}
|
||||
/* use ldns print for domain name */
|
||||
if(ldns_wire2dname(&rdf, k->zonename, k->namelen, &pos)
|
||||
!= LDNS_STATUS_OK)
|
||||
return;
|
||||
nm = ldns_rdf2str(rdf);
|
||||
ldns_rdf_deep_free(rdf);
|
||||
if(!ssl_printf(a->ssl, "%s lame %s ttl %d dnssec %d rec %d "
|
||||
"A %d other %d\n", a->ipstr, nm, (int)(d->ttl - a->now),
|
||||
d->isdnsseclame, d->rec_lame, d->lame_type_A, d->lame_other)) {
|
||||
free(nm);
|
||||
return;
|
||||
}
|
||||
free(nm);
|
||||
}
|
||||
|
||||
/** callback for every host element in the infra cache */
|
||||
static void
|
||||
dump_infra_host(struct lruhash_entry* e, void* arg)
|
||||
{
|
||||
struct infra_arg* a = (struct infra_arg*)arg;
|
||||
struct infra_host_key* k = (struct infra_host_key*)e->key;
|
||||
struct infra_host_data* d = (struct infra_host_data*)e->data;
|
||||
struct infra_key* k = (struct infra_key*)e->key;
|
||||
struct infra_data* d = (struct infra_data*)e->data;
|
||||
char ip_str[1024];
|
||||
char name[257];
|
||||
addr_to_str(&k->addr, k->addrlen, ip_str, sizeof(ip_str));
|
||||
a->ipstr = ip_str;
|
||||
dname_str(k->zonename, name);
|
||||
/* skip expired stuff (only backed off) */
|
||||
if(d->ttl < a->now) {
|
||||
if(d->rtt.rto >= USEFUL_SERVER_TOP_TIMEOUT) {
|
||||
if(!ssl_printf(a->ssl, "%s expired rto %d\n", ip_str,
|
||||
d->rtt.rto)) return;
|
||||
if(!ssl_printf(a->ssl, "%s %s expired rto %d\n", ip_str,
|
||||
name, d->rtt.rto)) return;
|
||||
}
|
||||
if(d->lameness)
|
||||
lruhash_traverse(d->lameness, 0, &dump_infra_lame, arg);
|
||||
return;
|
||||
}
|
||||
if(!ssl_printf(a->ssl, "%s ttl %d ping %d var %d rtt %d rto %d "
|
||||
"ednsknown %d edns %d delay %d\n",
|
||||
ip_str, (int)(d->ttl - a->now),
|
||||
if(!ssl_printf(a->ssl, "%s %s ttl %d ping %d var %d rtt %d rto %d "
|
||||
"ednsknown %d edns %d delay %d lame dnssec %d rec %d A %d "
|
||||
"other %d\n", ip_str, name, (int)(d->ttl - a->now),
|
||||
d->rtt.srtt, d->rtt.rttvar, rtt_notimeout(&d->rtt), d->rtt.rto,
|
||||
(int)d->edns_lame_known, (int)d->edns_version,
|
||||
(int)(a->now<d->probedelay?d->probedelay-a->now:0)))
|
||||
(int)(a->now<d->probedelay?d->probedelay-a->now:0),
|
||||
(int)d->isdnsseclame, (int)d->rec_lame, (int)d->lame_type_A,
|
||||
(int)d->lame_other))
|
||||
return;
|
||||
if(d->lameness)
|
||||
lruhash_traverse(d->lameness, 0, &dump_infra_lame, arg);
|
||||
}
|
||||
|
||||
/** do the dump_infra command */
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@
|
||||
* numbers. These 'statistics' may be of interest to the operator.
|
||||
*/
|
||||
#include "config.h"
|
||||
#include "ldns/wire2host.h"
|
||||
#include <ldns/wire2host.h>
|
||||
#include "daemon/stats.h"
|
||||
#include "daemon/worker.h"
|
||||
#include "daemon/daemon.h"
|
||||
|
||||
+1
-1
@@ -43,7 +43,7 @@
|
||||
#ifndef DAEMON_STATS_H
|
||||
#define DAEMON_STATS_H
|
||||
#include "util/timehist.h"
|
||||
#include "ldns/buffer.h"
|
||||
#include <ldns/buffer.h>
|
||||
struct worker;
|
||||
struct config_file;
|
||||
struct comm_point;
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
#include "services/cache/infra.h"
|
||||
#include "util/data/msgreply.h"
|
||||
#include "util/module.h"
|
||||
#include "util/net_help.h"
|
||||
#include <signal.h>
|
||||
#include <fcntl.h>
|
||||
#include <openssl/crypto.h>
|
||||
@@ -446,6 +447,13 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
|
||||
/* read ssl keys while superuser and outside chroot */
|
||||
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");
|
||||
|
||||
#ifdef HAVE_KILL
|
||||
/* check old pid file before forking */
|
||||
|
||||
+8
-8
@@ -40,7 +40,7 @@
|
||||
* pending requests.
|
||||
*/
|
||||
#include "config.h"
|
||||
#include "ldns/wire2host.h"
|
||||
#include <ldns/wire2host.h>
|
||||
#include "util/log.h"
|
||||
#include "util/net_help.h"
|
||||
#include "util/random.h"
|
||||
@@ -1092,7 +1092,7 @@ worker_init(struct worker* worker, struct config_file *cfg,
|
||||
}
|
||||
worker->front = listen_create(worker->base, ports,
|
||||
cfg->msg_buffer_size, (int)cfg->incoming_num_tcp,
|
||||
worker_handle_request, worker);
|
||||
worker->daemon->listen_sslctx, worker_handle_request, worker);
|
||||
if(!worker->front) {
|
||||
log_err("could not create listening sockets");
|
||||
worker_delete(worker);
|
||||
@@ -1105,7 +1105,7 @@ worker_init(struct worker* worker, struct config_file *cfg,
|
||||
worker->daemon->env->infra_cache, worker->rndstate,
|
||||
cfg->use_caps_bits_for_id, worker->ports, worker->numports,
|
||||
cfg->unwanted_threshold, &worker_alloc_cleanup, worker,
|
||||
cfg->do_udp);
|
||||
cfg->do_udp, worker->daemon->connect_sslctx);
|
||||
if(!worker->back) {
|
||||
log_err("could not create outgoing sockets");
|
||||
worker_delete(worker);
|
||||
@@ -1244,8 +1244,8 @@ outbound_entry_compare(void* a, void* b)
|
||||
struct outbound_entry*
|
||||
worker_send_query(uint8_t* qname, size_t qnamelen, uint16_t qtype,
|
||||
uint16_t qclass, uint16_t flags, int dnssec, int want_dnssec,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
struct module_qstate* q)
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
|
||||
size_t zonelen, struct module_qstate* q)
|
||||
{
|
||||
struct worker* worker = q->env->worker;
|
||||
struct outbound_entry* e = (struct outbound_entry*)regional_alloc(
|
||||
@@ -1255,9 +1255,9 @@ worker_send_query(uint8_t* qname, size_t qnamelen, uint16_t qtype,
|
||||
e->qstate = q;
|
||||
e->qsent = outnet_serviced_query(worker->back, qname,
|
||||
qnamelen, qtype, qclass, flags, dnssec, want_dnssec,
|
||||
q->env->cfg->tcp_upstream, addr, addrlen,
|
||||
worker_handle_service_reply, e, worker->back->udp_buff,
|
||||
&outbound_entry_compare);
|
||||
q->env->cfg->tcp_upstream, q->env->cfg->ssl_upstream, addr,
|
||||
addrlen, zone, zonelen, worker_handle_service_reply, e,
|
||||
worker->back->udp_buff, &outbound_entry_compare);
|
||||
if(!e->qsent) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+3
-1
@@ -175,6 +175,8 @@ void worker_sighandler(int sig, void* arg);
|
||||
* @param want_dnssec: signatures needed.
|
||||
* @param addr: where to.
|
||||
* @param addrlen: length of addr.
|
||||
* @param zone: wireformat dname of the zone.
|
||||
* @param zonelen: length of zone name.
|
||||
* @param q: wich query state to reactivate upon return.
|
||||
* @return: false on failure (memory or socket related). no query was
|
||||
* sent.
|
||||
@@ -182,7 +184,7 @@ void worker_sighandler(int sig, void* arg);
|
||||
struct outbound_entry* worker_send_query(uint8_t* qname, size_t qnamelen,
|
||||
uint16_t qtype, uint16_t qclass, uint16_t flags, int dnssec,
|
||||
int want_dnssec, struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
struct module_qstate* q);
|
||||
uint8_t* zone, size_t zonelen, struct module_qstate* q);
|
||||
|
||||
/**
|
||||
* process control messages from the main thread. Frees the control
|
||||
|
||||
+198
@@ -1,3 +1,201 @@
|
||||
1 February 2012: Wouter
|
||||
- Fix validation failures (like: validation failure xx: no NSEC3
|
||||
closest encloser from yy for DS zz. while building chain of trust,
|
||||
because of a bug in the TTL-fix in 1.4.15, it picked the wrong rdata
|
||||
for an NSEC3. Now it does not change rdata, and fixes TTL.
|
||||
|
||||
30 January 2012: Wouter
|
||||
- Fix version-number in libtool to be version-info so it produces
|
||||
libunbound.so.2 like it should.
|
||||
|
||||
26 January 2012: Wouter
|
||||
- Tag 1.4.15 (same as 1.4.15rc1), for 1.4.15 release.
|
||||
- trunk 1.4.16; includes changes memset testcode, #424 openindiana,
|
||||
and keyfile write fixup.
|
||||
- applied patch to support outgoing-interface with ub_ctx_set_option.
|
||||
|
||||
23 January 2012: Wouter
|
||||
- Fix memset in test code.
|
||||
|
||||
20 January 2012: Wouter
|
||||
- Fix bug #424: compile on OpenIndiana OS with gcc 4.6.2.
|
||||
|
||||
19 January 2012: Wouter
|
||||
- Fix to write key files completely to a temporary file, and if that
|
||||
succeeds, replace the real key file. So failures leave a useful file.
|
||||
|
||||
18 January 2012: Wouter
|
||||
- tag 1.4.15rc1 created
|
||||
- updated libunbound/ubsyms.def and remade tag 1.4.15rc1.
|
||||
|
||||
17 January 2012: Wouter
|
||||
- Fix bug where canonical_compare of RRSIG did not downcase the
|
||||
signer-name. This is mostly harmless because RRSIGs do not have
|
||||
to be sorted in canonical order, usually.
|
||||
|
||||
12 January 2012: Wouter
|
||||
- bug#428: add ub_version() call to libunbound. API version increase,
|
||||
with (binary) backwards compatibility for the previous version.
|
||||
|
||||
10 January 2012: Wouter
|
||||
- Fix bug #425: unbound reports wrong TTL in reply, it reports a TTL
|
||||
that would be permissible by the RFCs but it is not the TTL in the
|
||||
cache.
|
||||
- iana portlist updated.
|
||||
- uninitialised variable in reprobe for rtt blocked domains fixed.
|
||||
- lintfix and new flex output.
|
||||
|
||||
2 January 2012: Wouter
|
||||
- Fix to randomize hash function, based on 28c3 congress, reported
|
||||
by Peter van Dijk.
|
||||
|
||||
24 December 2011: Wouter
|
||||
- Fix for memory leak (about 20 bytes when a tcp or udp send operation
|
||||
towards authority servers failed, takes about 50.000 such failures to
|
||||
leak one Mb, such failures are also usually logged), reported by
|
||||
Robert Fleischmann.
|
||||
- iana portlist updated.
|
||||
|
||||
19 December 2011: Wouter
|
||||
- Fix for VU#209659 CVE-2011-4528: Unbound denial of service
|
||||
vulnerabilities from nonstandard redirection and denial of existence
|
||||
http://www.unbound.net/downloads/CVE-2011-4528.txt
|
||||
- robust checks for next-closer NSEC3s.
|
||||
- tag 1.4.14 created.
|
||||
- trunk has 1.4.15 in development.
|
||||
|
||||
15 December 2011: Wouter
|
||||
- remove uninit warning from cachedump code.
|
||||
- Fix parse error on negative SOA RRSIGs if badly ordered in the packet.
|
||||
|
||||
13 December 2011: Wouter
|
||||
- iana portlist updated.
|
||||
- svn tag 1.4.14rc1
|
||||
- fix infra cache comparison.
|
||||
- Fix to constrain signer_name to be a parent of the lookupname.
|
||||
|
||||
5 December 2011: Wouter
|
||||
- Fix getaddrinfowithincludes on windows with fedora16 mingw32-gcc.
|
||||
- Fix warnings with gcc 4.6 in compat/inet_ntop.c.
|
||||
- Fix warning unused in compat/strptime.c.
|
||||
- Fix malloc detection and double defintion.
|
||||
|
||||
2 December 2011: Wouter
|
||||
- configure generated with autoconf 2.68.
|
||||
|
||||
30 November 2011: Wouter
|
||||
- Fix for tcp-upstream and ssl-upstream for if a laptop sleeps, causes
|
||||
SERVFAILs. Also fixed for UDP (but less likely).
|
||||
|
||||
28 November 2011: Wouter
|
||||
- Fix quartile time estimate, it was too low, (thanks Jan Komissar).
|
||||
- iana ports updated.
|
||||
|
||||
11 November 2011: Wouter
|
||||
- Makefile compat with SunOS make, BSD make and GNU make.
|
||||
- iana ports updated.
|
||||
|
||||
10 November 2011: Wouter
|
||||
- Makefile changed for BSD make compatibility.
|
||||
|
||||
9 November 2011: Wouter
|
||||
- added unit test for SSL service and SSL-upstream.
|
||||
|
||||
8 November 2011: Wouter
|
||||
- can configure ssl service to one port number, and not on others.
|
||||
- fixup windows compile with ssl support.
|
||||
- Fix double free in unbound-host, reported by Steve Grubb.
|
||||
- iana portlist updated.
|
||||
|
||||
1 November 2011: Wouter
|
||||
- dns over ssl support as a client, ssl-upstream yes turns it on.
|
||||
It performs an SSL transaction for every DNS query (250 msec).
|
||||
- documentation for new options: ssl-upstream, ssl-service-key and
|
||||
ssl-service.pem.
|
||||
- iana portlist updated.
|
||||
- fix -flto detection on Lion for llvm-gcc.
|
||||
|
||||
31 October 2011: Wouter
|
||||
- dns over ssl support, ssl-service-pem and ssl-service-key files
|
||||
can be given and then TCP queries are serviced wrapped in SSL.
|
||||
|
||||
27 October 2011: Wouter
|
||||
- lame-ttl and lame-size options no longer exist, it is integrated
|
||||
with the host info. They are ignored (with verbose warning) if
|
||||
encountered to keep the config file backwards compatible.
|
||||
- fix iana-update for changing gzip compression of results.
|
||||
- fix export-all-symbols on OSX.
|
||||
|
||||
26 October 2011: Wouter
|
||||
- iana portlist updated.
|
||||
- Infra cache stores information about ping and lameness per IP, zone.
|
||||
This fixes bug #416.
|
||||
- fix iana_update target for gzipped file on iana site.
|
||||
|
||||
24 October 2011: Wouter
|
||||
- Fix resolve of partners.extranet.microsoft.com with a fix for the
|
||||
server selection for choosing out of a (particular) list of bad
|
||||
choices. (bug#415)
|
||||
- Fix make_new_space function so that the incoming query is not
|
||||
overwritten if a jostled out query causes a waiting query to be
|
||||
resumed that then fails and sends an error message. (Thanks to
|
||||
Matthew Lee).
|
||||
|
||||
21 October 2011: Wouter
|
||||
- fix --enable-allsymbols, fptr wlist is disabled on windows with this
|
||||
option enabled because of memory layout exe vs dll.
|
||||
|
||||
19 October 2011: Wouter
|
||||
- fix unbound-anchor for broken strptime on OSX lion, detected
|
||||
in configure.
|
||||
- Detect if GOST really works, openssl1.0 on OSX fails.
|
||||
- Implement ipv6%interface notation for scope_id usage.
|
||||
|
||||
17 October 2011: Wouter
|
||||
- better documentation for inform_super (Thanks Yang Zhe).
|
||||
|
||||
14 October 2011: Wouter
|
||||
- Fix for out-of-memory condition in libunbound (thanks
|
||||
Robert Fleischman).
|
||||
|
||||
13 October 2011: Wouter
|
||||
- Fix --enable-allsymbols, it depended on link specifics of the
|
||||
target platform, or fptr_wlist assertion failures could occur.
|
||||
|
||||
12 October 2011: Wouter
|
||||
- updated contrib/unbound_munin_ to family=auto so that it works with
|
||||
munin-node-configure automatically (if installed as
|
||||
/usr/local/share/munin/plugins/unbound_munin_ ).
|
||||
|
||||
27 September 2011: Wouter
|
||||
- unbound.exe -w windows option for start and stop service.
|
||||
|
||||
23 September 2011: Wouter
|
||||
- TCP-upstream calculates tcp-ping so server selection works if there
|
||||
are alternatives.
|
||||
|
||||
20 September 2011: Wouter
|
||||
- Fix classification of NS set in answer section, where there is a
|
||||
parent-child server, and the answer has the AA flag for dir.slb.com.
|
||||
Thanks to Amanda Constant from Secure64.
|
||||
|
||||
16 September 2011: Wouter
|
||||
- fix bug #408: accept patch from Steve Snyder that comments out
|
||||
unused functions in lookup3.c.
|
||||
- iana portlist updated.
|
||||
- fix EDNS1480 change memleak and TCP fallback.
|
||||
- fix various compiler warnings (reported by Paul Wouters).
|
||||
- max sent count. EDNS1480 only for rtt < 5000. No promiscuous
|
||||
fetch if sentcount > 3, stop query if sentcount > 16. Count is
|
||||
reset when referral or CNAME happens. This makes unbound better
|
||||
at managing large NS sets, they are explored when there is continued
|
||||
interest (in the form of queries).
|
||||
|
||||
15 September 2011: Wouter
|
||||
- release 1.4.13.
|
||||
- trunk contains 1.4.14 in development.
|
||||
- Unbound probes at EDNS1480 if there an EDNS0 timeout.
|
||||
|
||||
12 September 2011: Wouter
|
||||
- Reverted dns EDNS backoff fix, it did not help and needs
|
||||
fragmentation fixes instead.
|
||||
|
||||
+13
-8
@@ -123,24 +123,18 @@ server:
|
||||
# cache. Items are not cached for longer. In seconds.
|
||||
# cache-max-ttl: 86400
|
||||
|
||||
# the time to live (TTL) value for cached roundtrip times and
|
||||
# the time to live (TTL) value for cached roundtrip times, lameness and
|
||||
# EDNS version information for hosts. In seconds.
|
||||
# infra-host-ttl: 900
|
||||
|
||||
# the time to live (TTL) value for cached lame delegations. In sec.
|
||||
# infra-lame-ttl: 900
|
||||
|
||||
# the number of slabs to use for the Infrastructure cache.
|
||||
# the number of slabs must be a power of 2.
|
||||
# more slabs reduce lock contention, but fragment memory usage.
|
||||
# infra-cache-slabs: 4
|
||||
|
||||
# the maximum number of hosts that are cached (roundtrip times, EDNS).
|
||||
# the maximum number of hosts that are cached (roundtrip, EDNS, lame).
|
||||
# infra-cache-numhosts: 10000
|
||||
|
||||
# the maximum size of the lame zones cached per host. in bytes.
|
||||
# infra-cache-lame-size: 10k
|
||||
|
||||
# Enable IPv4, "yes" or "no".
|
||||
# do-ip4: yes
|
||||
|
||||
@@ -459,6 +453,17 @@ server:
|
||||
# you need to do the reverse notation yourself.
|
||||
# local-data-ptr: "192.0.2.3 www.example.com"
|
||||
|
||||
# service clients over SSL (on the TCP sockets), with plain DNS inside
|
||||
# the SSL 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: 443
|
||||
|
||||
# request upstream over SSL (with plain DNS inside the SSL stream).
|
||||
# Default is no. Can be turned on and off with unbound-control.
|
||||
# ssl-upstream: no
|
||||
|
||||
# Python config section. To enable:
|
||||
# o use --with-pythonmodule to configure before compiling.
|
||||
# o list python in the module-config string (above) to enable.
|
||||
|
||||
@@ -164,7 +164,7 @@ harden\-glue, harden\-dnssec\-stripped, harden\-below\-nxdomain,
|
||||
harden\-referral\-path, prefetch, prefetch\-key, log\-queries,
|
||||
hide\-identity, hide\-version, identity, version, val\-log\-level,
|
||||
val\-log\-squelch, ignore\-cd\-flag, add\-holddown, del\-holddown,
|
||||
keep\-missing, tcp\-upstream.
|
||||
keep\-missing, tcp\-upstream, ssl\-upstream.
|
||||
.TP
|
||||
.B get_option \fIopt
|
||||
Get the value of the option. Give the option name without a trailing ':'.
|
||||
|
||||
+24
-10
@@ -269,10 +269,7 @@ the data in the cache does not match up with the actual data any more.
|
||||
.TP
|
||||
.B infra\-host\-ttl: \fI<seconds>
|
||||
Time to live for entries in the host cache. The host cache contains
|
||||
roundtrip timing and EDNS support information. Default is 900.
|
||||
.TP
|
||||
.B infra\-lame\-ttl: \fI<seconds>
|
||||
The time to live when a delegation is discovered to be lame. Default is 900.
|
||||
roundtrip timing, lameness and EDNS support information. Default is 900.
|
||||
.TP
|
||||
.B infra\-cache\-slabs: \fI<number>
|
||||
Number of slabs in the infrastructure cache. Slabs reduce lock contention
|
||||
@@ -281,11 +278,6 @@ by threads. Must be set to a power of 2.
|
||||
.B infra\-cache\-numhosts: \fI<number>
|
||||
Number of hosts for which information is cached. Default is 10000.
|
||||
.TP
|
||||
.B infra\-cache\-lame\-size: \fI<number>
|
||||
Number of bytes that the lameness cache per host is allowed to use. Default
|
||||
is 10 kb, which gives maximum storage for a couple score zones, depending on
|
||||
the lame zone name lengths.
|
||||
.TP
|
||||
.B do\-ip4: \fI<yes or no>
|
||||
Enable or disable whether ip4 queries are answered or issued. Default is yes.
|
||||
.TP
|
||||
@@ -304,6 +296,29 @@ Enable or disable whether TCP queries are answered or issued. Default is yes.
|
||||
Enable or disable whether the upstream queries use TCP only for transport.
|
||||
Default is no. Useful in tunneling scenarios.
|
||||
.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
|
||||
TCP wireformat. The other server must support this (see \fBssl\-service\-key\fR).
|
||||
.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
|
||||
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 "",
|
||||
turned off.
|
||||
.TP
|
||||
.B ssl\-port: \fI<number>
|
||||
The port number on which to provide TCP SSL service, default 443, only
|
||||
interfaces configured with that port number as @number get the SSL service.
|
||||
.TP
|
||||
.B do\-daemonize: \fI<yes or no>
|
||||
Enable or disable whether the unbound server forks into the background as
|
||||
a daemon. Default is yes.
|
||||
@@ -1023,7 +1038,6 @@ server:
|
||||
rrset\-cache\-slabs: 1
|
||||
infra\-cache\-numhosts: 200
|
||||
infra\-cache\-slabs: 1
|
||||
infra\-cache\-lame\-size: 1k
|
||||
key\-cache\-size: 100k
|
||||
key\-cache\-slabs: 1
|
||||
neg\-cache\-size: 10k
|
||||
|
||||
+3
-3
@@ -40,9 +40,9 @@
|
||||
* Keep track of forward zones and config settings.
|
||||
*/
|
||||
#include "config.h"
|
||||
#include "ldns/rdata.h"
|
||||
#include "ldns/dname.h"
|
||||
#include "ldns/rr.h"
|
||||
#include <ldns/rdata.h>
|
||||
#include <ldns/dname.h>
|
||||
#include <ldns/rr.h>
|
||||
#include "iterator/iter_fwd.h"
|
||||
#include "iterator/iter_delegpt.h"
|
||||
#include "util/regional.h"
|
||||
|
||||
@@ -40,8 +40,8 @@
|
||||
* Keep track of stub and root hints, and read those from config.
|
||||
*/
|
||||
#include "config.h"
|
||||
#include "ldns/dname.h"
|
||||
#include "ldns/rr.h"
|
||||
#include <ldns/dname.h>
|
||||
#include <ldns/rr.h>
|
||||
#include "iterator/iter_hints.h"
|
||||
#include "iterator/iter_delegpt.h"
|
||||
#include "util/regional.h"
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "ldns/dname.h"
|
||||
#include <ldns/dname.h>
|
||||
#include "iterator/iter_priv.h"
|
||||
#include "util/regional.h"
|
||||
#include "util/log.h"
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
#ifndef ITERATOR_ITER_PRIV_H
|
||||
#define ITERATOR_ITER_PRIV_H
|
||||
#include "util/rbtree.h"
|
||||
#include "ldns/buffer.h"
|
||||
#include <ldns/buffer.h>
|
||||
struct iter_env;
|
||||
struct config_file;
|
||||
struct regional;
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
* one of the response types.
|
||||
*/
|
||||
#include "config.h"
|
||||
#include "ldns/packet.h"
|
||||
#include <ldns/packet.h>
|
||||
#include "iterator/iter_resptype.h"
|
||||
#include "iterator/iter_delegpt.h"
|
||||
#include "services/cache/dns.h"
|
||||
@@ -163,6 +163,8 @@ response_type_from_server(int rdset,
|
||||
ntohs(s->rk.rrset_class) == request->qclass &&
|
||||
dname_strict_subdomain_c(s->rk.dname,
|
||||
origzone)) {
|
||||
if((msg->rep->flags&BIT_AA))
|
||||
return RESPONSE_TYPE_ANSWER;
|
||||
return RESPONSE_TYPE_REFERRAL;
|
||||
}
|
||||
|
||||
|
||||
@@ -187,11 +187,14 @@ parse_get_cname_target(struct rrset_parse* rrset, uint8_t** sname,
|
||||
size_t* snamelen)
|
||||
{
|
||||
if(rrset->rr_count != 1) {
|
||||
struct rr_parse* sig;
|
||||
verbose(VERB_ALGO, "Found CNAME rrset with "
|
||||
"size > 1: %u", (unsigned)rrset->rr_count);
|
||||
/* use the first CNAME! */
|
||||
rrset->rr_count = 1;
|
||||
rrset->size = rrset->rr_first->size;
|
||||
for(sig=rrset->rrsig_first; sig; sig=sig->next)
|
||||
rrset->size += sig->size;
|
||||
rrset->rr_last = rrset->rr_first;
|
||||
rrset->rr_first->next = NULL;
|
||||
}
|
||||
@@ -532,8 +535,7 @@ store_rrset(ldns_buffer* pkt, struct msg_parse* msg, struct module_env* env,
|
||||
ref.key = k;
|
||||
ref.id = k->id;
|
||||
/*ignore ret: it was in the cache, ref updated */
|
||||
(void)rrset_cache_update(env->rrset_cache, &ref,
|
||||
env->alloc, now);
|
||||
(void)rrset_cache_update(env->rrset_cache, &ref, env->alloc, now);
|
||||
}
|
||||
|
||||
/** Check if there are SOA records in the authority section (negative) */
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
|
||||
#ifndef ITERATOR_ITER_SCRUB_H
|
||||
#define ITERATOR_ITER_SCRUB_H
|
||||
#include "ldns/buffer.h"
|
||||
#include <ldns/buffer.h>
|
||||
struct msg_parse;
|
||||
struct query_info;
|
||||
struct regional;
|
||||
|
||||
+11
-4
@@ -212,8 +212,13 @@ iter_filter_unsuitable(struct iter_env* iter_env, struct module_env* env,
|
||||
if(lame)
|
||||
return -1; /* server is lame */
|
||||
else if(rtt >= USEFUL_SERVER_TOP_TIMEOUT)
|
||||
/* server is unresponsive */
|
||||
return USEFUL_SERVER_TOP_TIMEOUT;
|
||||
/* server is unresponsive,
|
||||
* we used to return TOP_TIMOUT, but fairly useless,
|
||||
* because if == TOP_TIMEOUT is dropped because
|
||||
* blacklisted later, instead, remove it here, so
|
||||
* other choices (that are not blacklisted) can be
|
||||
* tried */
|
||||
return -1;
|
||||
/* select remainder from worst to best */
|
||||
else if(reclame)
|
||||
return rtt+USEFUL_SERVER_TOP_TIMEOUT*3; /* nonpref */
|
||||
@@ -420,9 +425,11 @@ dns_copy_msg(struct dns_msg* from, struct regional* region)
|
||||
|
||||
int
|
||||
iter_dns_store(struct module_env* env, struct query_info* msgqinf,
|
||||
struct reply_info* msgrep, int is_referral, uint32_t leeway)
|
||||
struct reply_info* msgrep, int is_referral, uint32_t leeway,
|
||||
struct regional* region)
|
||||
{
|
||||
return dns_cache_store(env, msgqinf, msgrep, is_referral, leeway);
|
||||
return dns_cache_store(env, msgqinf, msgrep, is_referral, leeway,
|
||||
region);
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
#ifndef ITERATOR_ITER_UTILS_H
|
||||
#define ITERATOR_ITER_UTILS_H
|
||||
#include "iterator/iter_resptype.h"
|
||||
#include "ldns/buffer.h"
|
||||
#include <ldns/buffer.h>
|
||||
struct iter_env;
|
||||
struct iter_hints;
|
||||
struct iter_forwards;
|
||||
@@ -121,10 +121,12 @@ struct dns_msg* dns_copy_msg(struct dns_msg* from, struct regional* regional);
|
||||
* @param is_referral: If true, then the given message to be stored is a
|
||||
* referral. The cache implementation may use this as a hint.
|
||||
* @param leeway: prefetch TTL leeway to expire old rrsets quicker.
|
||||
* @param region: to copy modified (cache is better) rrs back to.
|
||||
* @return 0 on alloc error (out of memory).
|
||||
*/
|
||||
int iter_dns_store(struct module_env* env, struct query_info* qinf,
|
||||
struct reply_info* rep, int is_referral, uint32_t leeway);
|
||||
struct reply_info* rep, int is_referral, uint32_t leeway,
|
||||
struct regional* region);
|
||||
|
||||
/**
|
||||
* Select randomly with n/m probability.
|
||||
|
||||
+28
-11
@@ -41,7 +41,7 @@
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "ldns/ldns.h"
|
||||
#include <ldns/ldns.h>
|
||||
#include "iterator/iterator.h"
|
||||
#include "iterator/iter_utils.h"
|
||||
#include "iterator/iter_hints.h"
|
||||
@@ -117,6 +117,7 @@ iter_new(struct module_qstate* qstate, int id)
|
||||
iq->num_current_queries = 0;
|
||||
iq->query_restart_count = 0;
|
||||
iq->referral_count = 0;
|
||||
iq->sent_count = 0;
|
||||
iq->wait_priming_stub = 0;
|
||||
iq->refetch_glue = 0;
|
||||
iq->dnssec_expected = 0;
|
||||
@@ -259,7 +260,7 @@ error_response_cache(struct module_qstate* qstate, int id, int rcode)
|
||||
/* do not waste time trying to validate this servfail */
|
||||
err.security = sec_status_indeterminate;
|
||||
verbose(VERB_ALGO, "store error response in message cache");
|
||||
if(!iter_dns_store(qstate->env, &qstate->qinfo, &err, 0, 0)) {
|
||||
if(!iter_dns_store(qstate->env, &qstate->qinfo, &err, 0, 0, NULL)) {
|
||||
log_err("error_response_cache: could not store error (nomem)");
|
||||
}
|
||||
return error_response(qstate, id, rcode);
|
||||
@@ -974,6 +975,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
iq->dp = NULL;
|
||||
iq->refetch_glue = 0;
|
||||
iq->query_restart_count++;
|
||||
iq->sent_count = 0;
|
||||
sock_list_insert(&qstate->reply_origin, NULL, 0, qstate->region);
|
||||
return next_state(iq, INIT_REQUEST_STATE);
|
||||
}
|
||||
@@ -1425,6 +1427,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
iq->deleg_msg = NULL;
|
||||
iq->refetch_glue = 1;
|
||||
iq->query_restart_count++;
|
||||
iq->sent_count = 0;
|
||||
return next_state(iq, INIT_REQUEST_STATE);
|
||||
}
|
||||
}
|
||||
@@ -1537,8 +1540,8 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
|
||||
log_query_info(VERB_QUERY, "processQueryTargets:", &qstate->qinfo);
|
||||
verbose(VERB_ALGO, "processQueryTargets: targetqueries %d, "
|
||||
"currentqueries %d", iq->num_target_queries,
|
||||
iq->num_current_queries);
|
||||
"currentqueries %d sentcount %d", iq->num_target_queries,
|
||||
iq->num_current_queries, iq->sent_count);
|
||||
|
||||
/* Make sure that we haven't run away */
|
||||
/* FIXME: is this check even necessary? */
|
||||
@@ -1547,6 +1550,11 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
"number of referrrals with %d", iq->referral_count);
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
if(iq->sent_count > MAX_SENT_COUNT) {
|
||||
verbose(VERB_QUERY, "request has exceeded the maximum "
|
||||
"number of sends with %d", iq->sent_count);
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
|
||||
/* Make sure we have a delegation point, otherwise priming failed
|
||||
* or another failure occurred */
|
||||
@@ -1573,7 +1581,8 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
/* < not <=, because although the array is large enough for <=, the
|
||||
* generated query will immediately be discarded due to depth and
|
||||
* that servfail is cached, which is not good as opportunism goes. */
|
||||
if(iq->depth < ie->max_dependency_depth) {
|
||||
if(iq->depth < ie->max_dependency_depth
|
||||
&& iq->sent_count < TARGET_FETCH_STOP) {
|
||||
tf_policy = ie->target_fetch_policy[iq->depth];
|
||||
}
|
||||
|
||||
@@ -1596,7 +1605,8 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
/* the current caps_server is the number of fallbacks sent.
|
||||
* the original query is one that matched too, so we have
|
||||
* caps_server+1 number of matching queries now */
|
||||
if(iq->caps_server+1 >= naddr*3) {
|
||||
if(iq->caps_server+1 >= naddr*3 ||
|
||||
iq->caps_server+1 >= MAX_SENT_COUNT) {
|
||||
/* we're done, process the response */
|
||||
verbose(VERB_ALGO, "0x20 fallback had %d responses "
|
||||
"match for %d wanted, done.",
|
||||
@@ -1605,6 +1615,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
iter_dec_attempts(iq->dp, 3); /* space for fallback */
|
||||
iq->num_current_queries++; /* RespState decrements it*/
|
||||
iq->referral_count++; /* make sure we don't loop */
|
||||
iq->sent_count = 0;
|
||||
iq->state = QUERY_RESP_STATE;
|
||||
return 1;
|
||||
}
|
||||
@@ -1712,7 +1723,8 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
iq->qchase.qname, iq->qchase.qname_len,
|
||||
iq->qchase.qtype, iq->qchase.qclass,
|
||||
iq->chase_flags | (iq->chase_to_rd?BIT_RD:0), EDNS_DO|BIT_CD,
|
||||
iq->dnssec_expected, &target->addr, target->addrlen, qstate);
|
||||
iq->dnssec_expected, &target->addr, target->addrlen,
|
||||
iq->dp->name, iq->dp->namelen, qstate);
|
||||
if(!outq) {
|
||||
log_addr(VERB_DETAIL, "error sending query to auth server",
|
||||
&target->addr, target->addrlen);
|
||||
@@ -1720,6 +1732,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
}
|
||||
outbound_list_insert(&iq->outlist, outq);
|
||||
iq->num_current_queries++;
|
||||
iq->sent_count++;
|
||||
qstate->ext_state[id] = module_wait_reply;
|
||||
|
||||
return 0;
|
||||
@@ -1819,7 +1832,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
"nodata ANSWER"));
|
||||
}
|
||||
if(!iter_dns_store(qstate->env, &iq->response->qinfo,
|
||||
iq->response->rep, 0, qstate->prefetch_leeway))
|
||||
iq->response->rep, 0, qstate->prefetch_leeway,
|
||||
qstate->region))
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
/* close down outstanding requests to be discarded */
|
||||
outbound_list_clear(&iq->outlist);
|
||||
@@ -1858,7 +1872,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
/* Store the referral under the current query */
|
||||
/* no prefetch-leeway, since its not the answer */
|
||||
if(!iter_dns_store(qstate->env, &iq->response->qinfo,
|
||||
iq->response->rep, 1, 0))
|
||||
iq->response->rep, 1, 0, NULL))
|
||||
return error_response(qstate, id,
|
||||
LDNS_RCODE_SERVFAIL);
|
||||
if(iq->store_parent_NS)
|
||||
@@ -1896,6 +1910,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
delegpt_log(VERB_ALGO, iq->dp);
|
||||
/* Count this as a referral. */
|
||||
iq->referral_count++;
|
||||
iq->sent_count = 0;
|
||||
/* see if the next dp is a trust anchor, or a DS was sent
|
||||
* along, indicating dnssec is expected for next zone */
|
||||
iq->dnssec_expected = iter_indicates_dnssec(qstate->env,
|
||||
@@ -1943,7 +1958,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
* the partial query answer (CNAME only). */
|
||||
/* prefetchleeway applied because this updates answer parts */
|
||||
if(!iter_dns_store(qstate->env, &iq->response->qinfo,
|
||||
iq->response->rep, 1, qstate->prefetch_leeway))
|
||||
iq->response->rep, 1, qstate->prefetch_leeway, NULL))
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
/* set the current request's qname to the new value. */
|
||||
iq->qchase.qname = sname;
|
||||
@@ -1953,6 +1968,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
iq->dp = NULL;
|
||||
/* Note the query restart. */
|
||||
iq->query_restart_count++;
|
||||
iq->sent_count = 0;
|
||||
|
||||
/* stop current outstanding queries.
|
||||
* FIXME: should the outstanding queries be waited for and
|
||||
@@ -2418,7 +2434,8 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
* from cache does not need to be stored in the msg cache. */
|
||||
if(qstate->query_flags&BIT_RD) {
|
||||
if(!iter_dns_store(qstate->env, &qstate->qinfo,
|
||||
iq->response->rep, 0, qstate->prefetch_leeway))
|
||||
iq->response->rep, 0, qstate->prefetch_leeway,
|
||||
qstate->region))
|
||||
return error_response(qstate, id,
|
||||
LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
|
||||
@@ -56,6 +56,10 @@ struct iter_priv;
|
||||
#define MAX_RESTART_COUNT 8
|
||||
/** max number of referrals. Makes sure resolver does not run away */
|
||||
#define MAX_REFERRAL_COUNT 130
|
||||
/** max number of queries-sent-out. Make sure large NS set does not loop */
|
||||
#define MAX_SENT_COUNT 16
|
||||
/** at what query-sent-count to stop target fetch policy */
|
||||
#define TARGET_FETCH_STOP 3
|
||||
/** how nice is a server without further information, in msec
|
||||
* Equals rtt initial timeout value.
|
||||
*/
|
||||
@@ -252,6 +256,9 @@ struct iter_qstate {
|
||||
/** the number of times this query as followed a referral. */
|
||||
int referral_count;
|
||||
|
||||
/** number of queries fired off */
|
||||
int sent_count;
|
||||
|
||||
/**
|
||||
* The query must store NS records from referrals as parentside RRs
|
||||
* Enabled once it hits resolution problems, to throttle retries.
|
||||
|
||||
@@ -1117,3 +1117,8 @@ int ub_ctx_data_remove(struct ub_ctx* ctx, char *data)
|
||||
free(nm);
|
||||
return UB_NOERROR;
|
||||
}
|
||||
|
||||
const char* ub_version(void)
|
||||
{
|
||||
return PACKAGE_VERSION;
|
||||
}
|
||||
|
||||
+35
-11
@@ -44,6 +44,7 @@
|
||||
#include "config.h"
|
||||
#include <ldns/dname.h>
|
||||
#include <ldns/wire2host.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include "libunbound/libworker.h"
|
||||
#include "libunbound/context.h"
|
||||
#include "libunbound/unbound.h"
|
||||
@@ -57,6 +58,7 @@
|
||||
#include "util/random.h"
|
||||
#include "util/config_file.h"
|
||||
#include "util/netevent.h"
|
||||
#include "util/storage/lookup3.h"
|
||||
#include "util/storage/slabhash.h"
|
||||
#include "util/net_help.h"
|
||||
#include "util/data/dname.h"
|
||||
@@ -84,6 +86,7 @@ libworker_delete(struct libworker* w)
|
||||
ub_randfree(w->env->rnd);
|
||||
free(w->env);
|
||||
}
|
||||
SSL_CTX_free(w->sslctx);
|
||||
outside_network_delete(w->back);
|
||||
comm_base_delete(w->base);
|
||||
free(w);
|
||||
@@ -124,6 +127,13 @@ libworker_setup(struct ub_ctx* ctx, int is_bg)
|
||||
forwards_delete(w->env->fwds);
|
||||
w->env->fwds = NULL;
|
||||
}
|
||||
if(cfg->ssl_upstream) {
|
||||
w->sslctx = connect_sslctx_create(NULL, NULL, NULL);
|
||||
if(!w->sslctx) {
|
||||
libworker_delete(w);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if(!w->is_bg || w->is_bg_thread) {
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
}
|
||||
@@ -150,6 +160,19 @@ libworker_setup(struct ub_ctx* ctx, int is_bg)
|
||||
if(!w->is_bg || w->is_bg_thread) {
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
}
|
||||
if(1) {
|
||||
/* primitive lockout for threading: if it overwrites another
|
||||
* thread it is like wiping the cache (which is likely empty
|
||||
* at the start) */
|
||||
/* note we are holding the ctx lock in normal threaded
|
||||
* cases so that is solved properly, it is only for many ctx
|
||||
* in different threads that this may clash */
|
||||
static int done_raninit = 0;
|
||||
if(!done_raninit) {
|
||||
done_raninit = 1;
|
||||
hash_set_raninit((uint32_t)ub_random(w->env->rnd));
|
||||
}
|
||||
}
|
||||
seed = 0;
|
||||
|
||||
w->base = comm_base_create(0);
|
||||
@@ -171,7 +194,7 @@ libworker_setup(struct ub_ctx* ctx, int is_bg)
|
||||
cfg->do_tcp?cfg->outgoing_num_tcp:0,
|
||||
w->env->infra_cache, w->env->rnd, cfg->use_caps_bits_for_id,
|
||||
ports, numports, cfg->unwanted_threshold,
|
||||
&libworker_alloc_cleanup, w, cfg->do_udp);
|
||||
&libworker_alloc_cleanup, w, cfg->do_udp, w->sslctx);
|
||||
if(!w->is_bg || w->is_bg_thread) {
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
}
|
||||
@@ -261,7 +284,12 @@ libworker_dobg(void* arg)
|
||||
/* setup */
|
||||
uint32_t m;
|
||||
struct libworker* w = (struct libworker*)arg;
|
||||
struct ub_ctx* ctx = w->ctx;
|
||||
struct ub_ctx* ctx;
|
||||
if(!w) {
|
||||
log_err("libunbound bg worker init failed, nomem");
|
||||
return NULL;
|
||||
}
|
||||
ctx = w->ctx;
|
||||
log_thread_set(&w->thread_num);
|
||||
#ifdef THREADS_DISABLED
|
||||
/* we are forked */
|
||||
@@ -270,10 +298,6 @@ libworker_dobg(void* arg)
|
||||
tube_close_write(ctx->qq_pipe);
|
||||
tube_close_read(ctx->rr_pipe);
|
||||
#endif
|
||||
if(!w) {
|
||||
log_err("libunbound bg worker init failed, nomem");
|
||||
return NULL;
|
||||
}
|
||||
if(!tube_setup_bg_listen(ctx->qq_pipe, w->base,
|
||||
libworker_handle_control_cmd, w)) {
|
||||
log_err("libunbound bg worker init failed, no bglisten");
|
||||
@@ -310,11 +334,11 @@ int libworker_bg(struct ub_ctx* ctx)
|
||||
if(ctx->dothread) {
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
w = libworker_setup(ctx, 1);
|
||||
if(!w) return UB_NOMEM;
|
||||
w->is_bg_thread = 1;
|
||||
#ifdef ENABLE_LOCK_CHECKS
|
||||
w->thread_num = 1; /* for nicer DEBUG checklocks */
|
||||
#endif
|
||||
if(!w) return UB_NOMEM;
|
||||
ub_thread_create(&ctx->bg_tid, libworker_dobg, w);
|
||||
} else {
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
@@ -684,7 +708,7 @@ outbound_entry_compare(void* a, void* b)
|
||||
struct outbound_entry* libworker_send_query(uint8_t* qname, size_t qnamelen,
|
||||
uint16_t qtype, uint16_t qclass, uint16_t flags, int dnssec,
|
||||
int want_dnssec, struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
struct module_qstate* q)
|
||||
uint8_t* zone, size_t zonelen, struct module_qstate* q)
|
||||
{
|
||||
struct libworker* w = (struct libworker*)q->env->worker;
|
||||
struct outbound_entry* e = (struct outbound_entry*)regional_alloc(
|
||||
@@ -694,9 +718,9 @@ struct outbound_entry* libworker_send_query(uint8_t* qname, size_t qnamelen,
|
||||
e->qstate = q;
|
||||
e->qsent = outnet_serviced_query(w->back, qname,
|
||||
qnamelen, qtype, qclass, flags, dnssec, want_dnssec,
|
||||
q->env->cfg->tcp_upstream, addr, addrlen,
|
||||
libworker_handle_service_reply, e, w->back->udp_buff,
|
||||
&outbound_entry_compare);
|
||||
q->env->cfg->tcp_upstream, q->env->cfg->ssl_upstream, addr,
|
||||
addrlen, zone, zonelen, libworker_handle_service_reply, e,
|
||||
w->back->udp_buff, &outbound_entry_compare);
|
||||
if(!e->qsent) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -81,6 +81,8 @@ struct libworker {
|
||||
struct outside_network* back;
|
||||
/** random() table for this worker. */
|
||||
struct ub_randstate* rndstate;
|
||||
/** sslcontext for SSL wrapped DNS over TCP queries */
|
||||
void* sslctx;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -118,6 +120,8 @@ void libworker_alloc_cleanup(void* arg);
|
||||
* @param want_dnssec: signatures needed.
|
||||
* @param addr: where to.
|
||||
* @param addrlen: length of addr.
|
||||
* @param zone: delegation point name.
|
||||
* @param zonelen: length of zone name wireformat dname.
|
||||
* @param q: wich query state to reactivate upon return.
|
||||
* @return: false on failure (memory or socket related). no query was
|
||||
* sent.
|
||||
@@ -125,7 +129,7 @@ void libworker_alloc_cleanup(void* arg);
|
||||
struct outbound_entry* libworker_send_query(uint8_t* qname, size_t qnamelen,
|
||||
uint16_t qtype, uint16_t qclass, uint16_t flags, int dnssec,
|
||||
int want_dnssec, struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
struct module_qstate* q);
|
||||
uint8_t* zone, size_t zonelen, struct module_qstate* q);
|
||||
|
||||
/** process incoming replies from the network */
|
||||
int libworker_handle_reply(struct comm_point* c, void* arg, int error,
|
||||
|
||||
@@ -26,3 +26,4 @@ ub_ctx_zone_add
|
||||
ub_ctx_zone_remove
|
||||
ub_ctx_data_add
|
||||
ub_ctx_data_remove
|
||||
ub_version
|
||||
|
||||
@@ -543,6 +543,12 @@ int ub_ctx_data_add(struct ub_ctx* ctx, char *data);
|
||||
*/
|
||||
int ub_ctx_data_remove(struct ub_ctx* ctx, char *data);
|
||||
|
||||
/**
|
||||
* Get a version string from the libunbound implementation.
|
||||
* @return a static constant string with the version number.
|
||||
*/
|
||||
const char* ub_version(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -606,10 +606,8 @@ struct config_file {
|
||||
size_t rrset_cache_size;
|
||||
size_t rrset_cache_slabs;
|
||||
int host_ttl;
|
||||
int lame_ttl;
|
||||
size_t infra_cache_slabs;
|
||||
size_t infra_cache_numhosts;
|
||||
size_t infra_cache_lame_size;
|
||||
char* target_fetch_policy;
|
||||
int if_automatic;
|
||||
int num_ifs;
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
#include "ldns/ldns.h"
|
||||
#include <ldns/ldns.h>
|
||||
|
||||
#undef _POSIX_C_SOURCE
|
||||
#undef _XOPEN_SOURCE
|
||||
|
||||
@@ -66,7 +66,7 @@ int storeQueryInCache(struct module_qstate* qstate, struct query_info* qinfo, st
|
||||
}
|
||||
|
||||
return dns_cache_store(qstate->env, qinfo, msgrep, is_referral,
|
||||
qstate->prefetch_leeway);
|
||||
qstate->prefetch_leeway, NULL);
|
||||
}
|
||||
|
||||
/* Invalidate the message associated with query_info stored in message cache */
|
||||
|
||||
Vendored
+36
-8
@@ -55,24 +55,49 @@
|
||||
* @param env: module environment with caches.
|
||||
* @param rep: contains list of rrsets to store.
|
||||
* @param now: current time.
|
||||
* @param qrep: update rrsets here if cache is better
|
||||
* @param region: for qrep allocs.
|
||||
*/
|
||||
static void
|
||||
store_rrsets(struct module_env* env, struct reply_info* rep, uint32_t now)
|
||||
store_rrsets(struct module_env* env, struct reply_info* rep, uint32_t now,
|
||||
struct reply_info* qrep, struct regional* region)
|
||||
{
|
||||
size_t i;
|
||||
/* see if rrset already exists in cache, if not insert it. */
|
||||
for(i=0; i<rep->rrset_count; i++) {
|
||||
rep->ref[i].key = rep->rrsets[i];
|
||||
rep->ref[i].id = rep->rrsets[i]->id;
|
||||
if(rrset_cache_update(env->rrset_cache, &rep->ref[i],
|
||||
env->alloc, now)) /* it was in the cache */
|
||||
/* update ref if it was in the cache */
|
||||
switch(rrset_cache_update(env->rrset_cache, &rep->ref[i],
|
||||
env->alloc, now)) {
|
||||
case 0: /* ref unchanged, item inserted */
|
||||
break;
|
||||
case 2: /* ref updated, cache is superior */
|
||||
if(region) {
|
||||
struct ub_packed_rrset_key* ck;
|
||||
lock_rw_rdlock(&rep->ref[i].key->entry.lock);
|
||||
/* if deleted rrset, do not copy it */
|
||||
if(rep->ref[i].key->id == 0)
|
||||
ck = NULL;
|
||||
else ck = packed_rrset_copy_region(
|
||||
rep->ref[i].key, region, now);
|
||||
lock_rw_unlock(&rep->ref[i].key->entry.lock);
|
||||
if(ck) {
|
||||
/* use cached copy if memory allows */
|
||||
qrep->rrsets[i] = ck;
|
||||
}
|
||||
}
|
||||
/* no break: also copy key item */
|
||||
case 1: /* ref updated, item inserted */
|
||||
rep->rrsets[i] = rep->ref[i].key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dns_cache_store_msg(struct module_env* env, struct query_info* qinfo,
|
||||
hashvalue_t hash, struct reply_info* rep, uint32_t leeway)
|
||||
hashvalue_t hash, struct reply_info* rep, uint32_t leeway,
|
||||
struct reply_info* qrep, struct regional* region)
|
||||
{
|
||||
struct msgreply_entry* e;
|
||||
uint32_t ttl = rep->ttl;
|
||||
@@ -83,9 +108,11 @@ dns_cache_store_msg(struct module_env* env, struct query_info* qinfo,
|
||||
rep->ref[i].key = rep->rrsets[i];
|
||||
rep->ref[i].id = rep->rrsets[i]->id;
|
||||
}
|
||||
reply_info_sortref(rep);
|
||||
|
||||
/* there was a reply_info_sortref(rep) here but it seems to be
|
||||
* unnecessary, because the cache gets locked per rrset. */
|
||||
reply_info_set_ttls(rep, *env->now);
|
||||
store_rrsets(env, rep, *env->now+leeway);
|
||||
store_rrsets(env, rep, *env->now+leeway, qrep, region);
|
||||
if(ttl == 0) {
|
||||
/* we do not store the message, but we did store the RRs,
|
||||
* which could be useful for delegation information */
|
||||
@@ -703,7 +730,8 @@ dns_cache_lookup(struct module_env* env,
|
||||
|
||||
int
|
||||
dns_cache_store(struct module_env* env, struct query_info* msgqinf,
|
||||
struct reply_info* msgrep, int is_referral, uint32_t leeway)
|
||||
struct reply_info* msgrep, int is_referral, uint32_t leeway,
|
||||
struct regional* region)
|
||||
{
|
||||
struct reply_info* rep = NULL;
|
||||
/* alloc, malloc properly (not in region, like msg is) */
|
||||
@@ -746,7 +774,7 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf,
|
||||
rep->flags |= (BIT_RA | BIT_QR);
|
||||
rep->flags &= ~(BIT_AA | BIT_CD);
|
||||
h = query_info_hash(&qinf);
|
||||
dns_cache_store_msg(env, &qinf, h, rep, leeway);
|
||||
dns_cache_store_msg(env, &qinf, h, rep, leeway, msgrep, region);
|
||||
/* qname is used inside query_info_entrysetup, and set to
|
||||
* NULL. If it has not been used, free it. free(0) is safe. */
|
||||
free(qinf.qname);
|
||||
|
||||
Vendored
+8
-2
@@ -74,10 +74,13 @@ struct dns_msg {
|
||||
* It will store only the RRsets, not the message.
|
||||
* @param leeway: TTL value, if not 0, other rrsets are considered expired
|
||||
* that many seconds before actual TTL expiry.
|
||||
* @param region: region to allocate better entries from cache into.
|
||||
* (used when is_referral is false).
|
||||
* @return 0 on alloc error (out of memory).
|
||||
*/
|
||||
int dns_cache_store(struct module_env* env, struct query_info* qinf,
|
||||
struct reply_info* rep, int is_referral, uint32_t leeway);
|
||||
struct reply_info* rep, int is_referral, uint32_t leeway,
|
||||
struct regional* region);
|
||||
|
||||
/**
|
||||
* Store message in the cache. Stores in message cache and rrset cache.
|
||||
@@ -92,9 +95,12 @@ int dns_cache_store(struct module_env* env, struct query_info* qinf,
|
||||
* Adjusts the reply info TTLs to absolute time.
|
||||
* @param leeway: TTL value, if not 0, other rrsets are considered expired
|
||||
* that many seconds before actual TTL expiry.
|
||||
* @param qrep: message that can be altered with better rrs from cache.
|
||||
* @param region: to allocate into for qmsg.
|
||||
*/
|
||||
void dns_cache_store_msg(struct module_env* env, struct query_info* qinfo,
|
||||
hashvalue_t hash, struct reply_info* rep, uint32_t leeway);
|
||||
hashvalue_t hash, struct reply_info* rep, uint32_t leeway,
|
||||
struct reply_info* qrep, struct regional* region);
|
||||
|
||||
/**
|
||||
* Find a delegation from the cache.
|
||||
|
||||
Vendored
+171
-349
@@ -39,7 +39,7 @@
|
||||
* This file contains the infrastructure cache.
|
||||
*/
|
||||
#include "config.h"
|
||||
#include "ldns/rr.h"
|
||||
#include <ldns/rr.h>
|
||||
#include "services/cache/infra.h"
|
||||
#include "util/storage/slabhash.h"
|
||||
#include "util/storage/lookup3.h"
|
||||
@@ -53,36 +53,44 @@
|
||||
#define PROBE_MAXRTO 12000 /* in msec */
|
||||
|
||||
size_t
|
||||
infra_host_sizefunc(void* k, void* ATTR_UNUSED(d))
|
||||
infra_sizefunc(void* k, void* ATTR_UNUSED(d))
|
||||
{
|
||||
struct infra_host_key* key = (struct infra_host_key*)k;
|
||||
return sizeof(*key) + sizeof(struct infra_host_data)
|
||||
struct infra_key* key = (struct infra_key*)k;
|
||||
return sizeof(*key) + sizeof(struct infra_data) + key->namelen
|
||||
+ lock_get_mem(&key->entry.lock);
|
||||
}
|
||||
|
||||
int
|
||||
infra_host_compfunc(void* key1, void* key2)
|
||||
infra_compfunc(void* key1, void* key2)
|
||||
{
|
||||
struct infra_host_key* k1 = (struct infra_host_key*)key1;
|
||||
struct infra_host_key* k2 = (struct infra_host_key*)key2;
|
||||
return sockaddr_cmp(&k1->addr, k1->addrlen, &k2->addr, k2->addrlen);
|
||||
struct infra_key* k1 = (struct infra_key*)key1;
|
||||
struct infra_key* k2 = (struct infra_key*)key2;
|
||||
int r = sockaddr_cmp(&k1->addr, k1->addrlen, &k2->addr, k2->addrlen);
|
||||
if(r != 0)
|
||||
return r;
|
||||
if(k1->namelen != k2->namelen) {
|
||||
if(k1->namelen < k2->namelen)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
return query_dname_compare(k1->zonename, k2->zonename);
|
||||
}
|
||||
|
||||
void
|
||||
infra_host_delkeyfunc(void* k, void* ATTR_UNUSED(arg))
|
||||
infra_delkeyfunc(void* k, void* ATTR_UNUSED(arg))
|
||||
{
|
||||
struct infra_host_key* key = (struct infra_host_key*)k;
|
||||
struct infra_key* key = (struct infra_key*)k;
|
||||
if(!key)
|
||||
return;
|
||||
lock_rw_destroy(&key->entry.lock);
|
||||
free(key->zonename);
|
||||
free(key);
|
||||
}
|
||||
|
||||
void
|
||||
infra_host_deldatafunc(void* d, void* ATTR_UNUSED(arg))
|
||||
infra_deldatafunc(void* d, void* ATTR_UNUSED(arg))
|
||||
{
|
||||
struct infra_host_data* data = (struct infra_host_data*)d;
|
||||
lruhash_delete(data->lameness);
|
||||
struct infra_data* data = (struct infra_data*)d;
|
||||
free(data);
|
||||
}
|
||||
|
||||
@@ -91,21 +99,16 @@ infra_create(struct config_file* cfg)
|
||||
{
|
||||
struct infra_cache* infra = (struct infra_cache*)calloc(1,
|
||||
sizeof(struct infra_cache));
|
||||
/* the size of the lameness tables are not counted */
|
||||
size_t maxmem = cfg->infra_cache_numhosts *
|
||||
(sizeof(struct infra_host_key)+sizeof(struct infra_host_data));
|
||||
size_t maxmem = cfg->infra_cache_numhosts * (sizeof(struct infra_key)+
|
||||
sizeof(struct infra_data)+INFRA_BYTES_NAME);
|
||||
infra->hosts = slabhash_create(cfg->infra_cache_slabs,
|
||||
INFRA_HOST_STARTSIZE, maxmem, &infra_host_sizefunc,
|
||||
&infra_host_compfunc, &infra_host_delkeyfunc,
|
||||
&infra_host_deldatafunc, NULL);
|
||||
INFRA_HOST_STARTSIZE, maxmem, &infra_sizefunc, &infra_compfunc,
|
||||
&infra_delkeyfunc, &infra_deldatafunc, NULL);
|
||||
if(!infra->hosts) {
|
||||
free(infra);
|
||||
return NULL;
|
||||
}
|
||||
infra->host_ttl = cfg->host_ttl;
|
||||
infra->lame_ttl = cfg->lame_ttl;
|
||||
infra->max_lame_size = cfg->infra_cache_lame_size;
|
||||
infra->jostle = cfg->jostle_time;
|
||||
return infra;
|
||||
}
|
||||
|
||||
@@ -125,11 +128,8 @@ infra_adjust(struct infra_cache* infra, struct config_file* cfg)
|
||||
if(!infra)
|
||||
return infra_create(cfg);
|
||||
infra->host_ttl = cfg->host_ttl;
|
||||
infra->lame_ttl = cfg->lame_ttl;
|
||||
infra->max_lame_size = cfg->infra_cache_lame_size;
|
||||
infra->jostle = cfg->jostle_time;
|
||||
maxmem = cfg->infra_cache_numhosts *
|
||||
(sizeof(struct infra_host_key)+sizeof(struct infra_host_data));
|
||||
maxmem = cfg->infra_cache_numhosts * (sizeof(struct infra_key)+
|
||||
sizeof(struct infra_data)+INFRA_BYTES_NAME);
|
||||
if(maxmem != slabhash_get_size(infra->hosts) ||
|
||||
cfg->infra_cache_slabs != infra->hosts->size) {
|
||||
infra_delete(infra);
|
||||
@@ -158,65 +158,44 @@ hash_addr(struct sockaddr_storage* addr, socklen_t addrlen)
|
||||
return h;
|
||||
}
|
||||
|
||||
void
|
||||
infra_remove_host(struct infra_cache* infra,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen)
|
||||
/** calculate infra hash for a key */
|
||||
static hashvalue_t
|
||||
hash_infra(struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* name)
|
||||
{
|
||||
struct infra_host_key k;
|
||||
k.addrlen = addrlen;
|
||||
memcpy(&k.addr, addr, addrlen);
|
||||
k.entry.hash = hash_addr(addr, addrlen);
|
||||
k.entry.key = (void*)&k;
|
||||
k.entry.data = NULL;
|
||||
slabhash_remove(infra->hosts, k.entry.hash, &k);
|
||||
return dname_query_hash(name, hash_addr(addr, addrlen));
|
||||
}
|
||||
|
||||
/** lookup version that does not check host ttl (you check it) */
|
||||
static struct lruhash_entry*
|
||||
infra_lookup_host_nottl(struct infra_cache* infra,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, int wr)
|
||||
struct lruhash_entry*
|
||||
infra_lookup_nottl(struct infra_cache* infra, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, uint8_t* name, size_t namelen, int wr)
|
||||
{
|
||||
struct infra_host_key k;
|
||||
struct infra_key k;
|
||||
k.addrlen = addrlen;
|
||||
memcpy(&k.addr, addr, addrlen);
|
||||
k.entry.hash = hash_addr(addr, addrlen);
|
||||
k.namelen = namelen;
|
||||
k.zonename = name;
|
||||
k.entry.hash = hash_infra(addr, addrlen, name);
|
||||
k.entry.key = (void*)&k;
|
||||
k.entry.data = NULL;
|
||||
return slabhash_lookup(infra->hosts, k.entry.hash, &k, wr);
|
||||
}
|
||||
|
||||
struct infra_host_data*
|
||||
infra_lookup_host(struct infra_cache* infra,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, int wr,
|
||||
uint32_t timenow, struct infra_host_key** key)
|
||||
{
|
||||
struct infra_host_data* data;
|
||||
struct lruhash_entry* e = infra_lookup_host_nottl(infra, addr,
|
||||
addrlen, wr);
|
||||
*key = NULL;
|
||||
if(!e)
|
||||
return NULL;
|
||||
/* check TTL */
|
||||
data = (struct infra_host_data*)e->data;
|
||||
if(data->ttl < timenow) {
|
||||
lock_rw_unlock(&e->lock);
|
||||
return NULL;
|
||||
}
|
||||
*key = (struct infra_host_key*)e->key;
|
||||
return data;
|
||||
}
|
||||
|
||||
/** init the host elements (not lame elems) */
|
||||
/** init the data elements */
|
||||
static void
|
||||
host_entry_init(struct infra_cache* infra, struct lruhash_entry* e,
|
||||
data_entry_init(struct infra_cache* infra, struct lruhash_entry* e,
|
||||
uint32_t timenow)
|
||||
{
|
||||
struct infra_host_data* data = (struct infra_host_data*)e->data;
|
||||
struct infra_data* data = (struct infra_data*)e->data;
|
||||
data->ttl = timenow + infra->host_ttl;
|
||||
rtt_init(&data->rtt);
|
||||
data->edns_version = 0;
|
||||
data->edns_lame_known = 0;
|
||||
data->probedelay = 0;
|
||||
data->isdnsseclame = 0;
|
||||
data->rec_lame = 0;
|
||||
data->lame_type_A = 0;
|
||||
data->lame_other = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -224,87 +203,93 @@ host_entry_init(struct infra_cache* infra, struct lruhash_entry* e,
|
||||
* @param infra: infra structure with config parameters.
|
||||
* @param addr: host address.
|
||||
* @param addrlen: length of addr.
|
||||
* @param name: name of zone
|
||||
* @param namelen: length of name.
|
||||
* @param tm: time now.
|
||||
* @return: the new entry or NULL on malloc failure.
|
||||
*/
|
||||
static struct lruhash_entry*
|
||||
new_host_entry(struct infra_cache* infra, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, uint32_t tm)
|
||||
new_entry(struct infra_cache* infra, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, uint8_t* name, size_t namelen, uint32_t tm)
|
||||
{
|
||||
struct infra_host_data* data;
|
||||
struct infra_host_key* key = (struct infra_host_key*)malloc(
|
||||
sizeof(struct infra_host_key));
|
||||
struct infra_data* data;
|
||||
struct infra_key* key = (struct infra_key*)malloc(sizeof(*key));
|
||||
if(!key)
|
||||
return NULL;
|
||||
data = (struct infra_host_data*)malloc(
|
||||
sizeof(struct infra_host_data));
|
||||
data = (struct infra_data*)malloc(sizeof(struct infra_data));
|
||||
if(!data) {
|
||||
free(key);
|
||||
return NULL;
|
||||
}
|
||||
key->zonename = memdup(name, namelen);
|
||||
if(!key->zonename) {
|
||||
free(key);
|
||||
free(data);
|
||||
return NULL;
|
||||
}
|
||||
key->namelen = namelen;
|
||||
lock_rw_init(&key->entry.lock);
|
||||
key->entry.hash = hash_addr(addr, addrlen);
|
||||
key->entry.hash = hash_infra(addr, addrlen, name);
|
||||
key->entry.key = (void*)key;
|
||||
key->entry.data = (void*)data;
|
||||
key->addrlen = addrlen;
|
||||
memcpy(&key->addr, addr, addrlen);
|
||||
data->lameness = NULL;
|
||||
host_entry_init(infra, &key->entry, tm);
|
||||
data_entry_init(infra, &key->entry, tm);
|
||||
return &key->entry;
|
||||
}
|
||||
|
||||
int
|
||||
infra_host(struct infra_cache* infra, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, uint32_t timenow, int* edns_vs,
|
||||
uint8_t* edns_lame_known, int* to)
|
||||
socklen_t addrlen, uint8_t* nm, size_t nmlen, uint32_t timenow,
|
||||
int* edns_vs, uint8_t* edns_lame_known, int* to)
|
||||
{
|
||||
struct lruhash_entry* e = infra_lookup_host_nottl(infra, addr,
|
||||
addrlen, 0);
|
||||
struct infra_host_data* data;
|
||||
struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen,
|
||||
nm, nmlen, 0);
|
||||
struct infra_data* data;
|
||||
int wr = 0;
|
||||
if(e && ((struct infra_host_data*)e->data)->ttl < timenow) {
|
||||
if(e && ((struct infra_data*)e->data)->ttl < timenow) {
|
||||
/* it expired, try to reuse existing entry */
|
||||
int old = ((struct infra_host_data*)e->data)->rtt.rto;
|
||||
int old = ((struct infra_data*)e->data)->rtt.rto;
|
||||
lock_rw_unlock(&e->lock);
|
||||
e = infra_lookup_host_nottl(infra, addr, addrlen, 1);
|
||||
e = infra_lookup_nottl(infra, addr, addrlen, nm, nmlen, 1);
|
||||
if(e) {
|
||||
/* if its still there we have a writelock, init */
|
||||
/* re-initialise */
|
||||
/* do not touch lameness, it may be valid still */
|
||||
host_entry_init(infra, e, timenow);
|
||||
data_entry_init(infra, e, timenow);
|
||||
wr = 1;
|
||||
/* TOP_TIMEOUT remains on reuse */
|
||||
if(old >= USEFUL_SERVER_TOP_TIMEOUT)
|
||||
((struct infra_host_data*)e->data)->rtt.rto
|
||||
((struct infra_data*)e->data)->rtt.rto
|
||||
= USEFUL_SERVER_TOP_TIMEOUT;
|
||||
}
|
||||
}
|
||||
if(!e) {
|
||||
/* insert new entry */
|
||||
if(!(e = new_host_entry(infra, addr, addrlen, timenow)))
|
||||
if(!(e = new_entry(infra, addr, addrlen, nm, nmlen, timenow)))
|
||||
return 0;
|
||||
data = (struct infra_host_data*)e->data;
|
||||
*to = rtt_timeout(&data->rtt);
|
||||
data = (struct infra_data*)e->data;
|
||||
*edns_vs = data->edns_version;
|
||||
*edns_lame_known = data->edns_lame_known;
|
||||
*to = rtt_timeout(&data->rtt);
|
||||
slabhash_insert(infra->hosts, e->hash, e, data, NULL);
|
||||
return 1;
|
||||
}
|
||||
/* use existing entry */
|
||||
data = (struct infra_host_data*)e->data;
|
||||
*to = rtt_timeout(&data->rtt);
|
||||
data = (struct infra_data*)e->data;
|
||||
*edns_vs = data->edns_version;
|
||||
*edns_lame_known = data->edns_lame_known;
|
||||
*to = rtt_timeout(&data->rtt);
|
||||
if(*to >= PROBE_MAXRTO && rtt_notimeout(&data->rtt)*4 <= *to) {
|
||||
/* delay other queries, this is the probe query */
|
||||
if(!wr) {
|
||||
lock_rw_unlock(&e->lock);
|
||||
e = infra_lookup_host_nottl(infra, addr, addrlen, 1);
|
||||
e = infra_lookup_nottl(infra, addr,addrlen,nm,nmlen, 1);
|
||||
if(!e) { /* flushed from cache real fast, no use to
|
||||
allocate just for the probedelay */
|
||||
return 1;
|
||||
}
|
||||
data = (struct infra_host_data*)e->data;
|
||||
data = (struct infra_data*)e->data;
|
||||
}
|
||||
/* add 999 to round up the timeout value from msec to sec,
|
||||
* then add a whole second so it is certain that this probe
|
||||
@@ -315,170 +300,38 @@ infra_host(struct infra_cache* infra, struct sockaddr_storage* addr,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** hash lameness key */
|
||||
static hashvalue_t
|
||||
hash_lameness(uint8_t* name)
|
||||
{
|
||||
return dname_query_hash(name, 0xab);
|
||||
}
|
||||
|
||||
int
|
||||
infra_lookup_lame(struct infra_host_data* host,
|
||||
uint8_t* name, size_t namelen, uint32_t timenow,
|
||||
int* dlame, int* rlame, int* alame, int* olame)
|
||||
infra_set_lame(struct infra_cache* infra, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, uint8_t* nm, size_t nmlen, uint32_t timenow,
|
||||
int dnsseclame, int reclame, uint16_t qtype)
|
||||
{
|
||||
struct lruhash_entry* e;
|
||||
struct infra_lame_key k;
|
||||
struct infra_lame_data *d;
|
||||
if(!host->lameness)
|
||||
return 0;
|
||||
k.entry.hash = hash_lameness(name);
|
||||
k.zonename = name;
|
||||
k.namelen = namelen;
|
||||
k.entry.key = (void*)&k;
|
||||
k.entry.data = NULL;
|
||||
e = lruhash_lookup(host->lameness, k.entry.hash, &k, 0);
|
||||
if(!e)
|
||||
return 0;
|
||||
d = (struct infra_lame_data*)e->data;
|
||||
if(d->ttl < timenow) {
|
||||
lock_rw_unlock(&e->lock);
|
||||
return 0;
|
||||
}
|
||||
*dlame = d->isdnsseclame;
|
||||
*rlame = d->rec_lame;
|
||||
*alame = d->lame_type_A;
|
||||
*olame = d->lame_other;
|
||||
lock_rw_unlock(&e->lock);
|
||||
return *dlame || *rlame || *alame || *olame;
|
||||
}
|
||||
|
||||
size_t
|
||||
infra_lame_sizefunc(void* k, void* ATTR_UNUSED(d))
|
||||
{
|
||||
struct infra_lame_key* key = (struct infra_lame_key*)k;
|
||||
return sizeof(*key) + sizeof(struct infra_lame_data)
|
||||
+ key->namelen + lock_get_mem(&key->entry.lock);
|
||||
}
|
||||
|
||||
int
|
||||
infra_lame_compfunc(void* key1, void* key2)
|
||||
{
|
||||
struct infra_lame_key* k1 = (struct infra_lame_key*)key1;
|
||||
struct infra_lame_key* k2 = (struct infra_lame_key*)key2;
|
||||
if(k1->namelen != k2->namelen) {
|
||||
if(k1->namelen < k2->namelen)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
return query_dname_compare(k1->zonename, k2->zonename);
|
||||
}
|
||||
|
||||
void
|
||||
infra_lame_delkeyfunc(void* k, void* ATTR_UNUSED(arg))
|
||||
{
|
||||
struct infra_lame_key* key = (struct infra_lame_key*)k;
|
||||
if(!key)
|
||||
return;
|
||||
lock_rw_destroy(&key->entry.lock);
|
||||
free(key->zonename);
|
||||
free(key);
|
||||
}
|
||||
|
||||
void
|
||||
infra_lame_deldatafunc(void* d, void* ATTR_UNUSED(arg))
|
||||
{
|
||||
if(!d)
|
||||
return;
|
||||
free(d);
|
||||
}
|
||||
|
||||
int
|
||||
infra_set_lame(struct infra_cache* infra,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
uint8_t* name, size_t namelen, uint32_t timenow, int dnsseclame,
|
||||
int reclame, uint16_t qtype)
|
||||
{
|
||||
struct infra_host_data* data;
|
||||
struct infra_data* data;
|
||||
struct lruhash_entry* e;
|
||||
int needtoinsert = 0;
|
||||
struct infra_lame_key* k;
|
||||
struct infra_lame_data* d;
|
||||
/* allocate at start, easier cleanup (no locks held) */
|
||||
k = (struct infra_lame_key*)malloc(sizeof(*k));
|
||||
if(!k) {
|
||||
log_err("set_lame: malloc failure");
|
||||
return 0;
|
||||
}
|
||||
d = (struct infra_lame_data*)malloc(sizeof(*d));
|
||||
if(!d) {
|
||||
free(k);
|
||||
log_err("set_lame: malloc failure");
|
||||
return 0;
|
||||
}
|
||||
k->zonename = memdup(name, namelen);
|
||||
if(!k->zonename) {
|
||||
free(d);
|
||||
free(k);
|
||||
log_err("set_lame: malloc failure");
|
||||
return 0;
|
||||
}
|
||||
lock_rw_init(&k->entry.lock);
|
||||
k->entry.hash = hash_lameness(name);
|
||||
k->entry.key = (void*)k;
|
||||
k->entry.data = (void*)d;
|
||||
d->ttl = timenow + infra->lame_ttl;
|
||||
d->isdnsseclame = dnsseclame;
|
||||
d->rec_lame = reclame;
|
||||
d->lame_type_A = (!dnsseclame && !reclame && qtype == LDNS_RR_TYPE_A);
|
||||
d->lame_other = (!dnsseclame && !reclame && qtype != LDNS_RR_TYPE_A);
|
||||
k->namelen = namelen;
|
||||
e = infra_lookup_host_nottl(infra, addr, addrlen, 1);
|
||||
e = infra_lookup_nottl(infra, addr, addrlen, nm, nmlen, 1);
|
||||
if(!e) {
|
||||
/* insert it */
|
||||
if(!(e = new_host_entry(infra, addr, addrlen, timenow))) {
|
||||
free(k->zonename);
|
||||
free(k);
|
||||
free(d);
|
||||
if(!(e = new_entry(infra, addr, addrlen, nm, nmlen, timenow))) {
|
||||
log_err("set_lame: malloc failure");
|
||||
return 0;
|
||||
}
|
||||
needtoinsert = 1;
|
||||
} else if( ((struct infra_data*)e->data)->ttl < timenow) {
|
||||
/* expired, reuse existing entry */
|
||||
data_entry_init(infra, e, timenow);
|
||||
}
|
||||
/* got an entry, now set the zone lame */
|
||||
data = (struct infra_host_data*)e->data;
|
||||
if(!data->lameness) {
|
||||
/* create hash table if not there already */
|
||||
data->lameness = lruhash_create(INFRA_LAME_STARTSIZE,
|
||||
infra->max_lame_size, infra_lame_sizefunc,
|
||||
infra_lame_compfunc, infra_lame_delkeyfunc,
|
||||
infra_lame_deldatafunc, NULL);
|
||||
if(!data->lameness) {
|
||||
log_err("set_lame: malloc failure");
|
||||
if(needtoinsert) slabhash_insert(infra->hosts,
|
||||
e->hash, e, e->data, NULL);
|
||||
else { lock_rw_unlock(&e->lock); }
|
||||
free(k->zonename);
|
||||
free(k);
|
||||
free(d);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
/* lookup existing lameness entry (if any) and merge data */
|
||||
int dlame, rlame, alame, olame;
|
||||
if(infra_lookup_lame(data, name, namelen, timenow,
|
||||
&dlame, &rlame, &alame, &olame)) {
|
||||
/* merge data into new structure */
|
||||
if(dlame) d->isdnsseclame = 1;
|
||||
if(rlame) d->rec_lame = 1;
|
||||
if(alame) d->lame_type_A = 1;
|
||||
if(olame) d->lame_other = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* inserts new entry, or updates TTL of older entry */
|
||||
lruhash_insert(data->lameness, k->entry.hash, &k->entry, d, NULL);
|
||||
|
||||
data = (struct infra_data*)e->data;
|
||||
/* merge data (if any) */
|
||||
if(dnsseclame)
|
||||
data->isdnsseclame = 1;
|
||||
if(reclame)
|
||||
data->rec_lame = 1;
|
||||
if(!dnsseclame && !reclame && qtype == LDNS_RR_TYPE_A)
|
||||
data->lame_type_A = 1;
|
||||
if(!dnsseclame && !reclame && qtype != LDNS_RR_TYPE_A)
|
||||
data->lame_other = 1;
|
||||
/* done */
|
||||
if(needtoinsert)
|
||||
slabhash_insert(infra->hosts, e->hash, e, e->data, NULL);
|
||||
else { lock_rw_unlock(&e->lock); }
|
||||
@@ -487,14 +340,15 @@ infra_set_lame(struct infra_cache* infra,
|
||||
|
||||
void
|
||||
infra_update_tcp_works(struct infra_cache* infra,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen)
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* nm,
|
||||
size_t nmlen)
|
||||
{
|
||||
struct lruhash_entry* e = infra_lookup_host_nottl(infra, addr,
|
||||
addrlen, 1);
|
||||
struct infra_host_data* data;
|
||||
struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen,
|
||||
nm, nmlen, 1);
|
||||
struct infra_data* data;
|
||||
if(!e)
|
||||
return; /* doesn't exist */
|
||||
data = (struct infra_host_data*)e->data;
|
||||
data = (struct infra_data*)e->data;
|
||||
if(data->rtt.rto >= RTT_MAX_TIMEOUT)
|
||||
/* do not disqualify this server altogether, it is better
|
||||
* than nothing */
|
||||
@@ -503,24 +357,24 @@ infra_update_tcp_works(struct infra_cache* infra,
|
||||
}
|
||||
|
||||
int
|
||||
infra_rtt_update(struct infra_cache* infra,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
int roundtrip, int orig_rtt, uint32_t timenow)
|
||||
infra_rtt_update(struct infra_cache* infra, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, uint8_t* nm, size_t nmlen, int roundtrip,
|
||||
int orig_rtt, uint32_t timenow)
|
||||
{
|
||||
struct lruhash_entry* e = infra_lookup_host_nottl(infra, addr,
|
||||
addrlen, 1);
|
||||
struct infra_host_data* data;
|
||||
struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen,
|
||||
nm, nmlen, 1);
|
||||
struct infra_data* data;
|
||||
int needtoinsert = 0;
|
||||
int rto = 1;
|
||||
if(!e) {
|
||||
if(!(e = new_host_entry(infra, addr, addrlen, timenow)))
|
||||
if(!(e = new_entry(infra, addr, addrlen, nm, nmlen, timenow)))
|
||||
return 0;
|
||||
needtoinsert = 1;
|
||||
} else if(((struct infra_host_data*)e->data)->ttl < timenow) {
|
||||
host_entry_init(infra, e, timenow);
|
||||
}
|
||||
} else if(((struct infra_data*)e->data)->ttl < timenow) {
|
||||
data_entry_init(infra, e, timenow);
|
||||
}
|
||||
/* have an entry, update the rtt */
|
||||
data = (struct infra_host_data*)e->data;
|
||||
data = (struct infra_data*)e->data;
|
||||
if(roundtrip == -1) {
|
||||
rtt_lost(&data->rtt, orig_rtt);
|
||||
} else {
|
||||
@@ -537,15 +391,15 @@ infra_rtt_update(struct infra_cache* infra,
|
||||
}
|
||||
|
||||
int infra_get_host_rto(struct infra_cache* infra,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
struct rtt_info* rtt, int* delay, uint32_t timenow)
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* nm,
|
||||
size_t nmlen, struct rtt_info* rtt, int* delay, uint32_t timenow)
|
||||
{
|
||||
struct lruhash_entry* e = infra_lookup_host_nottl(infra, addr,
|
||||
addrlen, 0);
|
||||
struct infra_host_data* data;
|
||||
struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen,
|
||||
nm, nmlen, 0);
|
||||
struct infra_data* data;
|
||||
int ttl = -2;
|
||||
if(!e) return -1;
|
||||
data = (struct infra_host_data*)e->data;
|
||||
data = (struct infra_data*)e->data;
|
||||
if(data->ttl >= timenow) {
|
||||
ttl = (int)(data->ttl - timenow);
|
||||
memmove(rtt, &data->rtt, sizeof(*rtt));
|
||||
@@ -558,23 +412,23 @@ int infra_get_host_rto(struct infra_cache* infra,
|
||||
}
|
||||
|
||||
int
|
||||
infra_edns_update(struct infra_cache* infra,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
int edns_version, uint32_t timenow)
|
||||
infra_edns_update(struct infra_cache* infra, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, uint8_t* nm, size_t nmlen, int edns_version,
|
||||
uint32_t timenow)
|
||||
{
|
||||
struct lruhash_entry* e = infra_lookup_host_nottl(infra, addr,
|
||||
addrlen, 1);
|
||||
struct infra_host_data* data;
|
||||
struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen,
|
||||
nm, nmlen, 1);
|
||||
struct infra_data* data;
|
||||
int needtoinsert = 0;
|
||||
if(!e) {
|
||||
if(!(e = new_host_entry(infra, addr, addrlen, timenow)))
|
||||
if(!(e = new_entry(infra, addr, addrlen, nm, nmlen, timenow)))
|
||||
return 0;
|
||||
needtoinsert = 1;
|
||||
} else if(((struct infra_host_data*)e->data)->ttl < timenow) {
|
||||
host_entry_init(infra, e, timenow);
|
||||
}
|
||||
} else if(((struct infra_data*)e->data)->ttl < timenow) {
|
||||
data_entry_init(infra, e, timenow);
|
||||
}
|
||||
/* have an entry, update the rtt, and the ttl */
|
||||
data = (struct infra_host_data*)e->data;
|
||||
data = (struct infra_data*)e->data;
|
||||
/* do not update if noEDNS and stored is yesEDNS */
|
||||
if(!(edns_version == -1 && (data->edns_version != -1 &&
|
||||
data->edns_lame_known))) {
|
||||
@@ -588,57 +442,23 @@ infra_edns_update(struct infra_cache* infra,
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
infra_get_lame_rtt(struct infra_cache* infra,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
uint8_t* name, size_t namelen, uint16_t qtype,
|
||||
int* lame, int* dnsseclame, int* reclame, int* rtt, uint32_t timenow)
|
||||
{
|
||||
struct infra_host_data* host;
|
||||
struct lruhash_entry* e = infra_lookup_host_nottl(infra, addr,
|
||||
addrlen, 0);
|
||||
int dlm, rlm, alm, olm;
|
||||
struct infra_data* host;
|
||||
struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen,
|
||||
name, namelen, 0);
|
||||
if(!e)
|
||||
return 0;
|
||||
host = (struct infra_host_data*)e->data;
|
||||
host = (struct infra_data*)e->data;
|
||||
*rtt = rtt_unclamped(&host->rtt);
|
||||
if(host->rtt.rto >= PROBE_MAXRTO && timenow < host->probedelay
|
||||
&& rtt_notimeout(&host->rtt)*4 <= host->rtt.rto)
|
||||
/* single probe for this domain, and we are not probing */
|
||||
*rtt = USEFUL_SERVER_TOP_TIMEOUT;
|
||||
/* check lameness first, if so, ttl on host does not matter anymore */
|
||||
if(infra_lookup_lame(host, name, namelen, timenow,
|
||||
&dlm, &rlm, &alm, &olm)) {
|
||||
if(alm && qtype == LDNS_RR_TYPE_A) {
|
||||
lock_rw_unlock(&e->lock);
|
||||
*lame = 1;
|
||||
*dnsseclame = 0;
|
||||
*reclame = 0;
|
||||
return 1;
|
||||
} else if(olm && qtype != LDNS_RR_TYPE_A) {
|
||||
lock_rw_unlock(&e->lock);
|
||||
*lame = 1;
|
||||
*dnsseclame = 0;
|
||||
*reclame = 0;
|
||||
return 1;
|
||||
} else if(dlm) {
|
||||
lock_rw_unlock(&e->lock);
|
||||
*lame = 0;
|
||||
*dnsseclame = 1;
|
||||
*reclame = 0;
|
||||
return 1;
|
||||
} else if(rlm) {
|
||||
lock_rw_unlock(&e->lock);
|
||||
*lame = 0;
|
||||
*dnsseclame = 0;
|
||||
*reclame = 1;
|
||||
return 1;
|
||||
}
|
||||
/* no lameness for this type of query */
|
||||
}
|
||||
*lame = 0;
|
||||
*dnsseclame = 0;
|
||||
*reclame = 0;
|
||||
if(timenow > host->ttl) {
|
||||
/* expired entry */
|
||||
/* see if this can be a re-probe of an unresponsive server */
|
||||
@@ -646,49 +466,51 @@ infra_get_lame_rtt(struct infra_cache* infra,
|
||||
* blacklisted servers stay blacklisted if this is chosen */
|
||||
if(host->rtt.rto >= USEFUL_SERVER_TOP_TIMEOUT) {
|
||||
*rtt = USEFUL_SERVER_TOP_TIMEOUT-1000;
|
||||
*lame = 0;
|
||||
*dnsseclame = 0;
|
||||
*reclame = 0;
|
||||
lock_rw_unlock(&e->lock);
|
||||
return 1;
|
||||
}
|
||||
lock_rw_unlock(&e->lock);
|
||||
return 0;
|
||||
}
|
||||
/* check lameness first */
|
||||
if(host->lame_type_A && qtype == LDNS_RR_TYPE_A) {
|
||||
lock_rw_unlock(&e->lock);
|
||||
*lame = 1;
|
||||
*dnsseclame = 0;
|
||||
*reclame = 0;
|
||||
return 1;
|
||||
} else if(host->lame_other && qtype != LDNS_RR_TYPE_A) {
|
||||
lock_rw_unlock(&e->lock);
|
||||
*lame = 1;
|
||||
*dnsseclame = 0;
|
||||
*reclame = 0;
|
||||
return 1;
|
||||
} else if(host->isdnsseclame) {
|
||||
lock_rw_unlock(&e->lock);
|
||||
*lame = 0;
|
||||
*dnsseclame = 1;
|
||||
*reclame = 0;
|
||||
return 1;
|
||||
} else if(host->rec_lame) {
|
||||
lock_rw_unlock(&e->lock);
|
||||
*lame = 0;
|
||||
*dnsseclame = 0;
|
||||
*reclame = 1;
|
||||
return 1;
|
||||
}
|
||||
/* no lameness for this type of query */
|
||||
lock_rw_unlock(&e->lock);
|
||||
*lame = 0;
|
||||
*dnsseclame = 0;
|
||||
*reclame = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** helper memory count for a host lame cache */
|
||||
static size_t
|
||||
count_host_lame(struct lruhash_entry* e)
|
||||
{
|
||||
struct infra_host_data* host_data = (struct infra_host_data*)e->data;
|
||||
if(!host_data->lameness)
|
||||
return 0;
|
||||
return lruhash_get_mem(host_data->lameness);
|
||||
}
|
||||
|
||||
size_t
|
||||
infra_get_mem(struct infra_cache* infra)
|
||||
{
|
||||
size_t i, bin;
|
||||
size_t s = sizeof(*infra) +
|
||||
slabhash_get_mem(infra->hosts);
|
||||
struct lruhash_entry* e;
|
||||
for(i=0; i<infra->hosts->size; i++) {
|
||||
lock_quick_lock(&infra->hosts->array[i]->lock);
|
||||
for(bin=0; bin<infra->hosts->array[i]->size; bin++) {
|
||||
lock_quick_lock(&infra->hosts->array[i]->
|
||||
array[bin].lock);
|
||||
/* count data size in bin items. */
|
||||
for(e = infra->hosts->array[i]->array[bin].
|
||||
overflow_list; e; e = e->overflow_next) {
|
||||
lock_rw_rdlock(&e->lock);
|
||||
s += count_host_lame(e);
|
||||
lock_rw_unlock(&e->lock);
|
||||
}
|
||||
lock_quick_unlock(&infra->hosts->array[i]->
|
||||
array[bin].lock);
|
||||
}
|
||||
lock_quick_unlock(&infra->hosts->array[i]->lock);
|
||||
}
|
||||
return s;
|
||||
return sizeof(*infra) + slabhash_get_mem(infra->hosts);
|
||||
}
|
||||
|
||||
Vendored
+48
-92
@@ -47,65 +47,50 @@ struct slabhash;
|
||||
struct config_file;
|
||||
|
||||
/**
|
||||
* Host information kept for every server.
|
||||
* Host information kept for every server, per zone.
|
||||
*/
|
||||
struct infra_host_key {
|
||||
struct infra_key {
|
||||
/** the host address. */
|
||||
struct sockaddr_storage addr;
|
||||
/** length of addr. */
|
||||
socklen_t addrlen;
|
||||
/** hash table entry, data of type infra_host_data. */
|
||||
/** zone name in wireformat */
|
||||
uint8_t* zonename;
|
||||
/** length of zonename */
|
||||
size_t namelen;
|
||||
/** hash table entry, data of type infra_data. */
|
||||
struct lruhash_entry entry;
|
||||
};
|
||||
|
||||
/**
|
||||
* Host information encompasses host capabilities and retransmission timeouts.
|
||||
* And lameness information (notAuthoritative, noEDNS, Recursive)
|
||||
*/
|
||||
struct infra_host_data {
|
||||
struct infra_data {
|
||||
/** TTL value for this entry. absolute time. */
|
||||
uint32_t ttl;
|
||||
|
||||
/** time in seconds (absolute) when probing re-commences, 0 disabled */
|
||||
uint32_t probedelay;
|
||||
/** round trip times for timeout calculation */
|
||||
struct rtt_info rtt;
|
||||
/** Names of the zones that are lame. NULL=no lame zones. */
|
||||
struct lruhash* lameness;
|
||||
|
||||
/** edns version that the host supports, -1 means no EDNS */
|
||||
int edns_version;
|
||||
/** if the EDNS lameness is already known or not.
|
||||
* EDNS lame is when EDNS queries or replies are dropped,
|
||||
* and cause a timeout */
|
||||
uint8_t edns_lame_known;
|
||||
};
|
||||
|
||||
/**
|
||||
* Lameness information, per host, per zone.
|
||||
*/
|
||||
struct infra_lame_key {
|
||||
/** key is zone name in wireformat */
|
||||
uint8_t* zonename;
|
||||
/** length of zonename */
|
||||
size_t namelen;
|
||||
/** lruhash entry */
|
||||
struct lruhash_entry entry;
|
||||
};
|
||||
|
||||
/**
|
||||
* Lameness information. Expires.
|
||||
* This host is lame because it is in the cache.
|
||||
*/
|
||||
struct infra_lame_data {
|
||||
/** TTL of this entry. absolute time. */
|
||||
uint32_t ttl;
|
||||
/** is the host lame (does not serve the zone authoritatively),
|
||||
* or is the host dnssec lame (does not serve DNSSEC data) */
|
||||
int isdnsseclame;
|
||||
uint8_t isdnsseclame;
|
||||
/** is the host recursion lame (not AA, but RA) */
|
||||
int rec_lame;
|
||||
uint8_t rec_lame;
|
||||
/** the host is lame (not authoritative) for A records */
|
||||
int lame_type_A;
|
||||
uint8_t lame_type_A;
|
||||
/** the host is lame (not authoritative) for other query types */
|
||||
int lame_other;
|
||||
uint8_t lame_other;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -116,18 +101,12 @@ struct infra_cache {
|
||||
struct slabhash* hosts;
|
||||
/** TTL value for host information, in seconds */
|
||||
int host_ttl;
|
||||
/** TTL for Lameness information, in seconds */
|
||||
int lame_ttl;
|
||||
/** infra lame cache max memory per host, in bytes */
|
||||
size_t max_lame_size;
|
||||
/** jostle timeout in msec */
|
||||
size_t jostle;
|
||||
};
|
||||
|
||||
/** infra host cache default hash lookup size */
|
||||
#define INFRA_HOST_STARTSIZE 32
|
||||
/** infra lame cache default hash lookup size */
|
||||
#define INFRA_LAME_STARTSIZE 2
|
||||
/** bytes per zonename reserved in the hostcache, dnamelen(zonename.com.) */
|
||||
#define INFRA_BYTES_NAME 14
|
||||
|
||||
/**
|
||||
* Create infra cache.
|
||||
@@ -142,10 +121,6 @@ struct infra_cache* infra_create(struct config_file* cfg);
|
||||
*/
|
||||
void infra_delete(struct infra_cache* infra);
|
||||
|
||||
/** explicitly delete an infra host element */
|
||||
void infra_remove_host(struct infra_cache* infra,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen);
|
||||
|
||||
/**
|
||||
* Adjust infra cache to use updated configuration settings.
|
||||
* This may clean the cache. Operates a bit like realloc.
|
||||
@@ -158,18 +133,18 @@ struct infra_cache* infra_adjust(struct infra_cache* infra,
|
||||
struct config_file* cfg);
|
||||
|
||||
/**
|
||||
* Lookup host data
|
||||
* Plain find infra data function (used by the the other functions)
|
||||
* @param infra: infrastructure cache.
|
||||
* @param addr: host address.
|
||||
* @param addrlen: length of addr.
|
||||
* @param wr: set to true to get a writelock on the entry.
|
||||
* @param timenow: what time it is now.
|
||||
* @param key: the key for the host, returned so caller can unlock when done.
|
||||
* @return: host data or NULL if not found or expired.
|
||||
* @param name: domain name of zone.
|
||||
* @param namelen: length of domain name.
|
||||
* @param wr: if true, writelock, else readlock.
|
||||
* @return the entry, could be expired (this is not checked) or NULL.
|
||||
*/
|
||||
struct infra_host_data* infra_lookup_host(struct infra_cache* infra,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, int wr,
|
||||
uint32_t timenow, struct infra_host_key** key);
|
||||
struct lruhash_entry* infra_lookup_nottl(struct infra_cache* infra,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* name,
|
||||
size_t namelen, int wr);
|
||||
|
||||
/**
|
||||
* Find host information to send a packet. Creates new entry if not found.
|
||||
@@ -180,6 +155,8 @@ struct infra_host_data* infra_lookup_host(struct infra_cache* infra,
|
||||
* @param infra: infrastructure cache.
|
||||
* @param addr: host address.
|
||||
* @param addrlen: length of addr.
|
||||
* @param name: domain name of zone.
|
||||
* @param namelen: length of domain name.
|
||||
* @param timenow: what time it is now.
|
||||
* @param edns_vs: edns version it supports, is returned.
|
||||
* @param edns_lame_known: if EDNS lame (EDNS is dropped in transit) has
|
||||
@@ -188,25 +165,8 @@ struct infra_host_data* infra_lookup_host(struct infra_cache* infra,
|
||||
* @return: 0 on error.
|
||||
*/
|
||||
int infra_host(struct infra_cache* infra, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, uint32_t timenow, int* edns_vs,
|
||||
uint8_t* edns_lame_known, int* to);
|
||||
|
||||
/**
|
||||
* Check for lameness of this server for a particular zone.
|
||||
* You must have a lock on the host structure.
|
||||
* @param host: infrastructure cache data for the host. Caller holds lock.
|
||||
* @param name: domain name of zone apex.
|
||||
* @param namelen: length of domain name.
|
||||
* @param timenow: what time it is now.
|
||||
* @param dlame: if the function returns true, is set true if dnssec lame.
|
||||
* @param rlame: if the function returns true, is set true if recursion lame.
|
||||
* @param alame: if the function returns true, is set true if qtype A lame.
|
||||
* @param olame: if the function returns true, is set true if qtype other lame.
|
||||
* @return: 0 if not lame or unknown or timed out, 1 if lame
|
||||
*/
|
||||
int infra_lookup_lame(struct infra_host_data* host,
|
||||
uint8_t* name, size_t namelen, uint32_t timenow,
|
||||
int* dlame, int* rlame, int* alame, int* olame);
|
||||
socklen_t addrlen, uint8_t* name, size_t namelen,
|
||||
uint32_t timenow, int* edns_vs, uint8_t* edns_lame_known, int* to);
|
||||
|
||||
/**
|
||||
* Set a host to be lame for the given zone.
|
||||
@@ -233,6 +193,8 @@ int infra_set_lame(struct infra_cache* infra,
|
||||
* @param infra: infrastructure cache.
|
||||
* @param addr: host address.
|
||||
* @param addrlen: length of addr.
|
||||
* @param name: zone name
|
||||
* @param namelen: zone name length
|
||||
* @param roundtrip: estimate of roundtrip time in milliseconds or -1 for
|
||||
* timeout.
|
||||
* @param orig_rtt: original rtt for the query that timed out (roundtrip==-1).
|
||||
@@ -240,8 +202,8 @@ int infra_set_lame(struct infra_cache* infra,
|
||||
* @param timenow: what time it is now.
|
||||
* @return: 0 on error. new rto otherwise.
|
||||
*/
|
||||
int infra_rtt_update(struct infra_cache* infra,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
int infra_rtt_update(struct infra_cache* infra, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, uint8_t* name, size_t namelen,
|
||||
int roundtrip, int orig_rtt, uint32_t timenow);
|
||||
|
||||
/**
|
||||
@@ -249,15 +211,20 @@ int infra_rtt_update(struct infra_cache* infra,
|
||||
* @param infra: infrastructure cache.
|
||||
* @param addr: host address.
|
||||
* @param addrlen: length of addr.
|
||||
* @param name: name of zone
|
||||
* @param namelen: length of name
|
||||
*/
|
||||
void infra_update_tcp_works(struct infra_cache* infra,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen);
|
||||
struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
uint8_t* name, size_t namelen);
|
||||
|
||||
/**
|
||||
* Update edns information for the host.
|
||||
* @param infra: infrastructure cache.
|
||||
* @param addr: host address.
|
||||
* @param addrlen: length of addr.
|
||||
* @param name: name of zone
|
||||
* @param namelen: length of name
|
||||
* @param edns_version: the version that it publishes.
|
||||
* If it is known to support EDNS then no-EDNS is not stored over it.
|
||||
* @param timenow: what time it is now.
|
||||
@@ -265,7 +232,7 @@ void infra_update_tcp_works(struct infra_cache* infra,
|
||||
*/
|
||||
int infra_edns_update(struct infra_cache* infra,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
int edns_version, uint32_t timenow);
|
||||
uint8_t* name, size_t namelen, int edns_version, uint32_t timenow);
|
||||
|
||||
/**
|
||||
* Get Lameness information and average RTT if host is in the cache.
|
||||
@@ -295,6 +262,8 @@ int infra_get_lame_rtt(struct infra_cache* infra,
|
||||
* @param infra: infra cache.
|
||||
* @param addr: host address.
|
||||
* @param addrlen: length of addr.
|
||||
* @param name: zone name
|
||||
* @param namelen: zone name length
|
||||
* @param rtt: the rtt_info is copied into here (caller alloced return struct).
|
||||
* @param delay: probe delay (if any).
|
||||
* @param timenow: what time it is now.
|
||||
@@ -302,8 +271,8 @@ int infra_get_lame_rtt(struct infra_cache* infra,
|
||||
* TTL -2: found but expired.
|
||||
*/
|
||||
int infra_get_host_rto(struct infra_cache* infra,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
struct rtt_info* rtt, int* delay, uint32_t timenow);
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* name,
|
||||
size_t namelen, struct rtt_info* rtt, int* delay, uint32_t timenow);
|
||||
|
||||
/**
|
||||
* Get memory used by the infra cache.
|
||||
@@ -314,28 +283,15 @@ size_t infra_get_mem(struct infra_cache* infra);
|
||||
|
||||
/** calculate size for the hashtable, does not count size of lameness,
|
||||
* so the hashtable is a fixed number of items */
|
||||
size_t infra_host_sizefunc(void* k, void* d);
|
||||
size_t infra_sizefunc(void* k, void* d);
|
||||
|
||||
/** compare two addresses, returns -1, 0, or +1 */
|
||||
int infra_host_compfunc(void* key1, void* key2);
|
||||
int infra_compfunc(void* key1, void* key2);
|
||||
|
||||
/** delete key, and destroy the lock */
|
||||
void infra_host_delkeyfunc(void* k, void* arg);
|
||||
void infra_delkeyfunc(void* k, void* arg);
|
||||
|
||||
/** delete data and destroy the lameness hashtable */
|
||||
void infra_host_deldatafunc(void* d, void* arg);
|
||||
|
||||
/** calculate size, which is fixed, zonename does not count so that
|
||||
* a fixed number of items is stored */
|
||||
size_t infra_lame_sizefunc(void* k, void* d);
|
||||
|
||||
/** compare zone names, returns -1, 0, +1 */
|
||||
int infra_lame_compfunc(void* key1, void* key2);
|
||||
|
||||
/** free key, lock and zonename */
|
||||
void infra_lame_delkeyfunc(void* k, void* arg);
|
||||
|
||||
/** free the lameness data */
|
||||
void infra_lame_deldatafunc(void* d, void* arg);
|
||||
void infra_deldatafunc(void* d, void* arg);
|
||||
|
||||
#endif /* SERVICES_CACHE_INFRA_H */
|
||||
|
||||
Vendored
+1
@@ -207,6 +207,7 @@ rrset_cache_update(struct rrset_cache* r, struct rrset_ref* ref,
|
||||
/* cache is superior, return that value */
|
||||
lock_rw_unlock(&e->lock);
|
||||
ub_packed_rrset_parsedelete(k, alloc);
|
||||
if(equal) return 2;
|
||||
return 1;
|
||||
}
|
||||
lock_rw_unlock(&e->lock);
|
||||
|
||||
Vendored
+4
@@ -125,6 +125,10 @@ void rrset_cache_touch(struct rrset_cache* r, struct ub_packed_rrset_key* key,
|
||||
* @param alloc: how to allocate (and deallocate) the special rrset key.
|
||||
* @param timenow: current time (to see if ttl in cache is expired).
|
||||
* @return: true if the passed reference is updated, false if it is unchanged.
|
||||
* 0: reference unchanged, inserted in cache.
|
||||
* 1: reference updated, item is inserted in cache.
|
||||
* 2: reference updated, item in cache is considered superior.
|
||||
* also the rdata is equal (but other parameters in cache are superior).
|
||||
*/
|
||||
int rrset_cache_update(struct rrset_cache* r, struct rrset_ref* ref,
|
||||
struct alloc_cache* alloc, uint32_t timenow);
|
||||
|
||||
@@ -632,12 +632,13 @@ set_recvpktinfo(int s, int family)
|
||||
* @param list: list of open ports, appended to, changed to point to list head.
|
||||
* @param rcv: receive buffer size for UDP
|
||||
* @param snd: send buffer size for UDP
|
||||
* @param ssl_port: ssl service port number
|
||||
* @return: returns false on error.
|
||||
*/
|
||||
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)
|
||||
size_t rcv, size_t snd, int ssl_port)
|
||||
{
|
||||
int s, noip6=0;
|
||||
if(!do_udp && !do_tcp)
|
||||
@@ -682,6 +683,9 @@ 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));
|
||||
if((s = make_sock_port(SOCK_STREAM, ifname, port, hints, 1,
|
||||
&noip6, 0, 0)) == -1) {
|
||||
if(noip6) {
|
||||
@@ -690,7 +694,10 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if(!port_insert(list, s, listen_type_tcp)) {
|
||||
if(is_ssl)
|
||||
verbose(VERB_ALGO, "setup TCP for SSL service");
|
||||
if(!port_insert(list, s, is_ssl?listen_type_ssl:
|
||||
listen_type_tcp)) {
|
||||
#ifndef USE_WINSOCK
|
||||
close(s);
|
||||
#else
|
||||
@@ -723,7 +730,7 @@ listen_cp_insert(struct comm_point* c, struct listen_dnsport* front)
|
||||
|
||||
struct listen_dnsport*
|
||||
listen_create(struct comm_base* base, struct listen_port* ports,
|
||||
size_t bufsize, int tcp_accept_count,
|
||||
size_t bufsize, int tcp_accept_count, void* sslctx,
|
||||
comm_point_callback_t* cb, void *cb_arg)
|
||||
{
|
||||
struct listen_dnsport* front = (struct listen_dnsport*)
|
||||
@@ -736,7 +743,7 @@ listen_create(struct comm_base* base, struct listen_port* ports,
|
||||
free(front);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* create comm points as needed */
|
||||
while(ports) {
|
||||
struct comm_point* cp = NULL;
|
||||
@@ -746,7 +753,11 @@ listen_create(struct comm_base* base, struct listen_port* ports,
|
||||
else if(ports->ftype == listen_type_tcp)
|
||||
cp = comm_point_create_tcp(base, ports->fd,
|
||||
tcp_accept_count, bufsize, cb, cb_arg);
|
||||
else if(ports->ftype == listen_type_udpancil)
|
||||
else if(ports->ftype == listen_type_ssl) {
|
||||
cp = comm_point_create_tcp(base, ports->fd,
|
||||
tcp_accept_count, bufsize, cb, cb_arg);
|
||||
cp->ssl = sslctx;
|
||||
} else if(ports->ftype == listen_type_udpancil)
|
||||
cp = comm_point_create_udp_ancil(base, ports->fd,
|
||||
front->udp_buff, cb, cb_arg);
|
||||
if(!cp) {
|
||||
@@ -830,7 +841,8 @@ listening_ports_open(struct config_file* cfg)
|
||||
if(!ports_create_if(do_auto?"::0":"::1",
|
||||
do_auto, cfg->do_udp, do_tcp,
|
||||
&hints, portbuf, &list,
|
||||
cfg->so_rcvbuf, cfg->so_sndbuf)) {
|
||||
cfg->so_rcvbuf, cfg->so_sndbuf,
|
||||
cfg->ssl_port)) {
|
||||
listening_ports_free(list);
|
||||
return NULL;
|
||||
}
|
||||
@@ -840,7 +852,8 @@ listening_ports_open(struct config_file* cfg)
|
||||
if(!ports_create_if(do_auto?"0.0.0.0":"127.0.0.1",
|
||||
do_auto, cfg->do_udp, do_tcp,
|
||||
&hints, portbuf, &list,
|
||||
cfg->so_rcvbuf, cfg->so_sndbuf)) {
|
||||
cfg->so_rcvbuf, cfg->so_sndbuf,
|
||||
cfg->ssl_port)) {
|
||||
listening_ports_free(list);
|
||||
return NULL;
|
||||
}
|
||||
@@ -852,7 +865,8 @@ listening_ports_open(struct config_file* cfg)
|
||||
hints.ai_family = AF_INET6;
|
||||
if(!ports_create_if(cfg->ifs[i], 0, cfg->do_udp,
|
||||
do_tcp, &hints, portbuf, &list,
|
||||
cfg->so_rcvbuf, cfg->so_sndbuf)) {
|
||||
cfg->so_rcvbuf, cfg->so_sndbuf,
|
||||
cfg->ssl_port)) {
|
||||
listening_ports_free(list);
|
||||
return NULL;
|
||||
}
|
||||
@@ -862,7 +876,8 @@ listening_ports_open(struct config_file* cfg)
|
||||
hints.ai_family = AF_INET;
|
||||
if(!ports_create_if(cfg->ifs[i], 0, cfg->do_udp,
|
||||
do_tcp, &hints, portbuf, &list,
|
||||
cfg->so_rcvbuf, cfg->so_sndbuf)) {
|
||||
cfg->so_rcvbuf, cfg->so_sndbuf,
|
||||
cfg->ssl_port)) {
|
||||
listening_ports_free(list);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -82,7 +82,9 @@ enum listen_type {
|
||||
/** tcp type */
|
||||
listen_type_tcp,
|
||||
/** udp ipv6 (v4mapped) for use with ancillary data */
|
||||
listen_type_udpancil
|
||||
listen_type_udpancil,
|
||||
/** ssl over tcp type */
|
||||
listen_type_ssl
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -121,6 +123,7 @@ void listening_ports_free(struct listen_port* list);
|
||||
* @param bufsize: size of datagram buffer.
|
||||
* @param tcp_accept_count: max number of simultaneous TCP connections
|
||||
* from clients.
|
||||
* @param sslctx: nonNULL if ssl context.
|
||||
* @param cb: callback function when a request arrives. It is passed
|
||||
* the packet and user argument. Return true to send a reply.
|
||||
* @param cb_arg: user data argument for callback function.
|
||||
@@ -128,7 +131,7 @@ void listening_ports_free(struct listen_port* list);
|
||||
*/
|
||||
struct listen_dnsport* listen_create(struct comm_base* base,
|
||||
struct listen_port* ports, size_t bufsize, int tcp_accept_count,
|
||||
comm_point_callback_t* cb, void* cb_arg);
|
||||
void* sslctx, comm_point_callback_t* cb, void* cb_arg);
|
||||
|
||||
/**
|
||||
* delete the listening structure
|
||||
|
||||
@@ -39,8 +39,8 @@
|
||||
* This file contains functions to enable local zone authority service.
|
||||
*/
|
||||
#include "config.h"
|
||||
#include "ldns/dname.h"
|
||||
#include "ldns/host2wire.h"
|
||||
#include <ldns/dname.h>
|
||||
#include <ldns/host2wire.h>
|
||||
#include "services/localzone.h"
|
||||
#include "util/regional.h"
|
||||
#include "util/config_file.h"
|
||||
|
||||
+58
-14
@@ -43,7 +43,7 @@
|
||||
* send back to clients.
|
||||
*/
|
||||
#include "config.h"
|
||||
#include "ldns/wire2host.h"
|
||||
#include <ldns/wire2host.h>
|
||||
#include "services/mesh.h"
|
||||
#include "services/outbound_list.h"
|
||||
#include "services/cache/dns.h"
|
||||
@@ -162,7 +162,8 @@ mesh_create(struct module_stack* stack, struct module_env* env)
|
||||
return NULL;
|
||||
}
|
||||
mesh->histogram = timehist_setup();
|
||||
if(!mesh->histogram) {
|
||||
mesh->qbuf_bak = ldns_buffer_new(env->cfg->msg_buffer_size);
|
||||
if(!mesh->histogram || !mesh->qbuf_bak) {
|
||||
free(mesh);
|
||||
log_err("mesh area alloc: out of memory");
|
||||
return NULL;
|
||||
@@ -209,6 +210,7 @@ mesh_delete(struct mesh_area* mesh)
|
||||
while(mesh->all.count)
|
||||
mesh_delete_helper(mesh->all.root);
|
||||
timehist_delete(mesh->histogram);
|
||||
ldns_buffer_free(mesh->qbuf_bak);
|
||||
free(mesh);
|
||||
}
|
||||
|
||||
@@ -232,7 +234,7 @@ mesh_delete_all(struct mesh_area* mesh)
|
||||
mesh->jostle_last = NULL;
|
||||
}
|
||||
|
||||
int mesh_make_new_space(struct mesh_area* mesh)
|
||||
int mesh_make_new_space(struct mesh_area* mesh, ldns_buffer* qbuf)
|
||||
{
|
||||
struct mesh_state* m = mesh->jostle_first;
|
||||
/* free space is available */
|
||||
@@ -250,6 +252,8 @@ int mesh_make_new_space(struct mesh_area* mesh)
|
||||
"make space for a new one",
|
||||
m->s.qinfo.qname, m->s.qinfo.qtype,
|
||||
m->s.qinfo.qclass);
|
||||
/* backup the query */
|
||||
if(qbuf) ldns_buffer_copy(mesh->qbuf_bak, qbuf);
|
||||
/* notify supers */
|
||||
if(m->super_set.count > 0) {
|
||||
verbose(VERB_ALGO, "notify supers of failure");
|
||||
@@ -259,6 +263,9 @@ int mesh_make_new_space(struct mesh_area* mesh)
|
||||
}
|
||||
mesh->stats_jostled ++;
|
||||
mesh_state_delete(&m->s);
|
||||
/* restore the query - note that the qinfo ptr to
|
||||
* the querybuffer is then correct again. */
|
||||
if(qbuf) ldns_buffer_copy(qbuf, mesh->qbuf_bak);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -280,7 +287,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
int added = 0;
|
||||
/* does this create a new reply state? */
|
||||
if(!s || s->list_select == mesh_no_list) {
|
||||
if(!mesh_make_new_space(mesh)) {
|
||||
if(!mesh_make_new_space(mesh, rep->c->buffer)) {
|
||||
verbose(VERB_ALGO, "Too many queries. dropping "
|
||||
"incoming query.");
|
||||
comm_point_drop_reply(rep);
|
||||
@@ -301,7 +308,9 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
}
|
||||
/* see if it already exists, if not, create one */
|
||||
if(!s) {
|
||||
#ifdef UNBOUND_DEBUG
|
||||
struct rbnode_t* n;
|
||||
#endif
|
||||
s = mesh_state_create(mesh->env, qinfo, qflags&BIT_RD, 0);
|
||||
if(!s) {
|
||||
log_err("mesh_state_create: out of memory; SERVFAIL");
|
||||
@@ -310,7 +319,10 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
comm_point_send_reply(rep);
|
||||
return;
|
||||
}
|
||||
n = rbtree_insert(&mesh->all, &s->node);
|
||||
#ifdef UNBOUND_DEBUG
|
||||
n =
|
||||
#endif
|
||||
rbtree_insert(&mesh->all, &s->node);
|
||||
log_assert(n != NULL);
|
||||
/* set detached (it is now) */
|
||||
mesh->num_detached_states++;
|
||||
@@ -369,12 +381,17 @@ mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
|
||||
/* see if it already exists, if not, create one */
|
||||
if(!s) {
|
||||
#ifdef UNBOUND_DEBUG
|
||||
struct rbnode_t* n;
|
||||
#endif
|
||||
s = mesh_state_create(mesh->env, qinfo, qflags&BIT_RD, 0);
|
||||
if(!s) {
|
||||
return 0;
|
||||
}
|
||||
n = rbtree_insert(&mesh->all, &s->node);
|
||||
#ifdef UNBOUND_DEBUG
|
||||
n =
|
||||
#endif
|
||||
rbtree_insert(&mesh->all, &s->node);
|
||||
log_assert(n != NULL);
|
||||
/* set detached (it is now) */
|
||||
mesh->num_detached_states++;
|
||||
@@ -408,7 +425,9 @@ void mesh_new_prefetch(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
uint16_t qflags, uint32_t leeway)
|
||||
{
|
||||
struct mesh_state* s = mesh_area_find(mesh, qinfo, qflags&BIT_RD, 0);
|
||||
#ifdef UNBOUND_DEBUG
|
||||
struct rbnode_t* n;
|
||||
#endif
|
||||
/* already exists, and for a different purpose perhaps.
|
||||
* if mesh_no_list, keep it that way. */
|
||||
if(s) {
|
||||
@@ -419,7 +438,7 @@ void mesh_new_prefetch(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
s->s.prefetch_leeway = leeway;
|
||||
return;
|
||||
}
|
||||
if(!mesh_make_new_space(mesh)) {
|
||||
if(!mesh_make_new_space(mesh, NULL)) {
|
||||
verbose(VERB_ALGO, "Too many queries. dropped prefetch.");
|
||||
mesh->stats_dropped ++;
|
||||
return;
|
||||
@@ -429,7 +448,10 @@ void mesh_new_prefetch(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
log_err("prefetch mesh_state_create: out of memory");
|
||||
return;
|
||||
}
|
||||
n = rbtree_insert(&mesh->all, &s->node);
|
||||
#ifdef UNBOUND_DEBUG
|
||||
n =
|
||||
#endif
|
||||
rbtree_insert(&mesh->all, &s->node);
|
||||
log_assert(n != NULL);
|
||||
/* set detached (it is now) */
|
||||
mesh->num_detached_states++;
|
||||
@@ -627,11 +649,16 @@ void mesh_detach_subs(struct module_qstate* qstate)
|
||||
{
|
||||
struct mesh_area* mesh = qstate->env->mesh;
|
||||
struct mesh_state_ref* ref, lookup;
|
||||
#ifdef UNBOUND_DEBUG
|
||||
struct rbnode_t* n;
|
||||
#endif
|
||||
lookup.node.key = &lookup;
|
||||
lookup.s = qstate->mesh_info;
|
||||
RBTREE_FOR(ref, struct mesh_state_ref*, &qstate->mesh_info->sub_set) {
|
||||
n = rbtree_delete(&ref->s->super_set, &lookup);
|
||||
#ifdef UNBOUND_DEBUG
|
||||
n =
|
||||
#endif
|
||||
rbtree_delete(&ref->s->super_set, &lookup);
|
||||
log_assert(n != NULL); /* must have been present */
|
||||
if(!ref->s->reply_list && !ref->s->cb_list
|
||||
&& ref->s->super_set.count == 0) {
|
||||
@@ -654,19 +681,27 @@ int mesh_attach_sub(struct module_qstate* qstate, struct query_info* qinfo,
|
||||
return 0;
|
||||
}
|
||||
if(!sub) {
|
||||
#ifdef UNBOUND_DEBUG
|
||||
struct rbnode_t* n;
|
||||
#endif
|
||||
/* create a new one */
|
||||
sub = mesh_state_create(qstate->env, qinfo, qflags, prime);
|
||||
if(!sub) {
|
||||
log_err("mesh_attach_sub: out of memory");
|
||||
return 0;
|
||||
}
|
||||
n = rbtree_insert(&mesh->all, &sub->node);
|
||||
#ifdef UNBOUND_DEBUG
|
||||
n =
|
||||
#endif
|
||||
rbtree_insert(&mesh->all, &sub->node);
|
||||
log_assert(n != NULL);
|
||||
/* set detached (it is now) */
|
||||
mesh->num_detached_states++;
|
||||
/* set new query state to run */
|
||||
n = rbtree_insert(&mesh->run, &sub->run_node);
|
||||
#ifdef UNBOUND_DEBUG
|
||||
n =
|
||||
#endif
|
||||
rbtree_insert(&mesh->run, &sub->run_node);
|
||||
log_assert(n != NULL);
|
||||
*newq = &sub->s;
|
||||
} else
|
||||
@@ -684,7 +719,9 @@ int mesh_attach_sub(struct module_qstate* qstate, struct query_info* qinfo,
|
||||
|
||||
int mesh_state_attachment(struct mesh_state* super, struct mesh_state* sub)
|
||||
{
|
||||
#ifdef UNBOUND_DEBUG
|
||||
struct rbnode_t* n;
|
||||
#endif
|
||||
struct mesh_state_ref* subref; /* points to sub, inserted in super */
|
||||
struct mesh_state_ref* superref; /* points to super, inserted in sub */
|
||||
if( !(subref = regional_alloc(super->s.region,
|
||||
@@ -698,9 +735,15 @@ int mesh_state_attachment(struct mesh_state* super, struct mesh_state* sub)
|
||||
superref->s = super;
|
||||
subref->node.key = subref;
|
||||
subref->s = sub;
|
||||
n = rbtree_insert(&sub->super_set, &superref->node);
|
||||
#ifdef UNBOUND_DEBUG
|
||||
n =
|
||||
#endif
|
||||
rbtree_insert(&sub->super_set, &superref->node);
|
||||
log_assert(n != NULL);
|
||||
n = rbtree_insert(&super->sub_set, &subref->node);
|
||||
#ifdef UNBOUND_DEBUG
|
||||
n =
|
||||
#endif
|
||||
rbtree_insert(&super->sub_set, &subref->node);
|
||||
log_assert(n != NULL);
|
||||
return 1;
|
||||
}
|
||||
@@ -1101,7 +1144,8 @@ mesh_get_mem(struct mesh_area* mesh)
|
||||
{
|
||||
struct mesh_state* m;
|
||||
size_t s = sizeof(*mesh) + sizeof(struct timehist) +
|
||||
sizeof(struct th_buck)*mesh->histogram->num;
|
||||
sizeof(struct th_buck)*mesh->histogram->num +
|
||||
sizeof(ldns_buffer) + ldns_buffer_capacity(mesh->qbuf_bak);
|
||||
RBTREE_FOR(m, struct mesh_state*, &mesh->all) {
|
||||
/* all, including m itself allocated in qstate region */
|
||||
s += regional_get_mem(m->s.region);
|
||||
|
||||
+14
-2
@@ -123,6 +123,10 @@ struct mesh_area {
|
||||
/** (extended stats) rcode nodata in replies */
|
||||
size_t ans_nodata;
|
||||
|
||||
/** backup of query if other operations recurse and need the
|
||||
* network buffers */
|
||||
ldns_buffer* qbuf_bak;
|
||||
|
||||
/** double linked list of the run-to-completion query states.
|
||||
* These are query states with a reply */
|
||||
struct mesh_state* forever_first;
|
||||
@@ -377,7 +381,8 @@ void mesh_query_done(struct mesh_state* mstate);
|
||||
* results from this query state. These can then be changed for error
|
||||
* or results.
|
||||
* Called when a module is module_finished or returns module_error.
|
||||
* The super query states become runnable with event module_event_pass.
|
||||
* The super query states become runnable with event module_event_pass,
|
||||
* it calls the current module for the super with the inform_super event.
|
||||
*
|
||||
* @param mesh: mesh area to add newly runnable modules to.
|
||||
* @param mstate: the state that has results, used to find mesh state.
|
||||
@@ -534,9 +539,16 @@ int mesh_state_ref_compare(const void* ap, const void* bp);
|
||||
/**
|
||||
* Make space for another recursion state for a reply in the mesh
|
||||
* @param mesh: mesh area
|
||||
* @param qbuf: query buffer to save if recursion is invoked to make space.
|
||||
* This buffer is necessary, because the following sequence in calls
|
||||
* can result in an overwrite of the incoming query:
|
||||
* delete_other_mesh_query - iter_clean - serviced_delete - waiting
|
||||
* udp query is sent - on error callback - callback sends SERVFAIL reply
|
||||
* over the same network channel, and shared UDP buffer is overwritten.
|
||||
* You can pass NULL if there is no buffer that must be backed up.
|
||||
* @return false if no space is available.
|
||||
*/
|
||||
int mesh_make_new_space(struct mesh_area* mesh);
|
||||
int mesh_make_new_space(struct mesh_area* mesh, ldns_buffer* qbuf);
|
||||
|
||||
/**
|
||||
* Insert mesh state into a double linked list. Inserted at end.
|
||||
|
||||
+137
-31
@@ -45,7 +45,7 @@
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
#include <sys/time.h>
|
||||
#include "ldns/wire2host.h"
|
||||
#include <ldns/wire2host.h>
|
||||
#include "services/outside_network.h"
|
||||
#include "services/listen_dnsport.h"
|
||||
#include "services/cache/infra.h"
|
||||
@@ -58,6 +58,7 @@
|
||||
#include "util/net_help.h"
|
||||
#include "util/random.h"
|
||||
#include "util/fptr_wlist.h"
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
#ifdef HAVE_NETDB_H
|
||||
#include <netdb.h>
|
||||
@@ -237,6 +238,18 @@ outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if(w->outnet->sslctx && w->ssl_upstream) {
|
||||
pend->c->ssl = outgoing_ssl_fd(w->outnet->sslctx, s);
|
||||
if(!pend->c->ssl) {
|
||||
pend->c->fd = s;
|
||||
comm_point_close(pend->c);
|
||||
return 0;
|
||||
}
|
||||
#ifdef USE_WINSOCK
|
||||
comm_point_tcp_win_bio_cb(pend->c, pend->c->ssl);
|
||||
#endif
|
||||
pend->c->ssl_shake_state = comm_ssl_shake_write;
|
||||
}
|
||||
w->pkt = NULL;
|
||||
w->next_waiting = (void*)pend;
|
||||
pend->id = LDNS_ID_WIRE(pkt);
|
||||
@@ -280,6 +293,11 @@ static void
|
||||
decomission_pending_tcp(struct outside_network* outnet,
|
||||
struct pending_tcp* pend)
|
||||
{
|
||||
if(pend->c->ssl) {
|
||||
SSL_shutdown(pend->c->ssl);
|
||||
SSL_free(pend->c->ssl);
|
||||
pend->c->ssl = NULL;
|
||||
}
|
||||
comm_point_close(pend->c);
|
||||
pend->next_free = outnet->tcp_free;
|
||||
outnet->tcp_free = pend;
|
||||
@@ -535,7 +553,8 @@ outside_network_create(struct comm_base *base, size_t bufsize,
|
||||
int do_ip6, size_t num_tcp, struct infra_cache* infra,
|
||||
struct ub_randstate* rnd, int use_caps_for_id, int* availports,
|
||||
int numavailports, size_t unwanted_threshold,
|
||||
void (*unwanted_action)(void*), void* unwanted_param, int do_udp)
|
||||
void (*unwanted_action)(void*), void* unwanted_param, int do_udp,
|
||||
void* sslctx)
|
||||
{
|
||||
struct outside_network* outnet = (struct outside_network*)
|
||||
calloc(1, sizeof(struct outside_network));
|
||||
@@ -549,6 +568,7 @@ outside_network_create(struct comm_base *base, size_t bufsize,
|
||||
outnet->num_tcp = num_tcp;
|
||||
outnet->infra = infra;
|
||||
outnet->rnd = rnd;
|
||||
outnet->sslctx = sslctx;
|
||||
outnet->svcd_overhead = 0;
|
||||
outnet->want_to_quit = 0;
|
||||
outnet->unwanted_threshold = unwanted_threshold;
|
||||
@@ -669,6 +689,7 @@ serviced_node_del(rbnode_t* node, void* ATTR_UNUSED(arg))
|
||||
struct serviced_query* sq = (struct serviced_query*)node;
|
||||
struct service_callback* p = sq->cblist, *np;
|
||||
free(sq->qbuf);
|
||||
free(sq->zone);
|
||||
while(p) {
|
||||
np = p->next;
|
||||
free(p);
|
||||
@@ -1054,7 +1075,7 @@ outnet_tcptimer(void* arg)
|
||||
struct waiting_tcp*
|
||||
pending_tcp_query(struct outside_network* outnet, ldns_buffer* packet,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, int timeout,
|
||||
comm_point_callback_t* callback, void* callback_arg)
|
||||
comm_point_callback_t* callback, void* callback_arg, int ssl_upstream)
|
||||
{
|
||||
struct pending_tcp* pend = outnet->tcp_free;
|
||||
struct waiting_tcp* w;
|
||||
@@ -1079,6 +1100,7 @@ pending_tcp_query(struct outside_network* outnet, ldns_buffer* packet,
|
||||
w->outnet = outnet;
|
||||
w->cb = callback;
|
||||
w->cb_arg = callback_arg;
|
||||
w->ssl_upstream = ssl_upstream;
|
||||
#ifndef S_SPLINT_S
|
||||
tv.tv_sec = timeout;
|
||||
tv.tv_usec = 0;
|
||||
@@ -1142,10 +1164,14 @@ lookup_serviced(struct outside_network* outnet, ldns_buffer* buff, int dnssec,
|
||||
/** Create new serviced entry */
|
||||
static struct serviced_query*
|
||||
serviced_create(struct outside_network* outnet, ldns_buffer* buff, int dnssec,
|
||||
int want_dnssec, struct sockaddr_storage* addr, socklen_t addrlen)
|
||||
int want_dnssec, int tcp_upstream, int ssl_upstream,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
|
||||
size_t zonelen)
|
||||
{
|
||||
struct serviced_query* sq = (struct serviced_query*)malloc(sizeof(*sq));
|
||||
#ifdef UNBOUND_DEBUG
|
||||
rbnode_t* ins;
|
||||
#endif
|
||||
if(!sq)
|
||||
return NULL;
|
||||
sq->node.key = sq;
|
||||
@@ -1155,8 +1181,17 @@ serviced_create(struct outside_network* outnet, ldns_buffer* buff, int dnssec,
|
||||
return NULL;
|
||||
}
|
||||
sq->qbuflen = ldns_buffer_limit(buff);
|
||||
sq->zone = memdup(zone, zonelen);
|
||||
if(!sq->zone) {
|
||||
free(sq->qbuf);
|
||||
free(sq);
|
||||
return NULL;
|
||||
}
|
||||
sq->zonelen = zonelen;
|
||||
sq->dnssec = dnssec;
|
||||
sq->want_dnssec = want_dnssec;
|
||||
sq->tcp_upstream = tcp_upstream;
|
||||
sq->ssl_upstream = ssl_upstream;
|
||||
memcpy(&sq->addr, addr, addrlen);
|
||||
sq->addrlen = addrlen;
|
||||
sq->outnet = outnet;
|
||||
@@ -1165,7 +1200,10 @@ serviced_create(struct outside_network* outnet, ldns_buffer* buff, int dnssec,
|
||||
sq->status = serviced_initial;
|
||||
sq->retry = 0;
|
||||
sq->to_be_deleted = 0;
|
||||
ins = rbtree_insert(outnet->serviced, &sq->node);
|
||||
#ifdef UNBOUND_DEBUG
|
||||
ins =
|
||||
#endif
|
||||
rbtree_insert(outnet->serviced, &sq->node);
|
||||
log_assert(ins != NULL); /* must not be already present */
|
||||
return sq;
|
||||
}
|
||||
@@ -1199,6 +1237,7 @@ serviced_delete(struct serviced_query* sq)
|
||||
if(sq->status == serviced_query_UDP_EDNS ||
|
||||
sq->status == serviced_query_UDP ||
|
||||
sq->status == serviced_query_PROBE_EDNS ||
|
||||
sq->status == serviced_query_UDP_EDNS_FRAG ||
|
||||
sq->status == serviced_query_UDP_EDNS_fallback) {
|
||||
struct pending* p = (struct pending*)sq->pending;
|
||||
if(p->pc)
|
||||
@@ -1280,7 +1319,19 @@ serviced_encode(struct serviced_query* sq, ldns_buffer* buff, int with_edns)
|
||||
edns.edns_present = 1;
|
||||
edns.ext_rcode = 0;
|
||||
edns.edns_version = EDNS_ADVERTISED_VERSION;
|
||||
edns.udp_size = EDNS_ADVERTISED_SIZE;
|
||||
if(sq->status == serviced_query_UDP_EDNS_FRAG) {
|
||||
if(addr_is_ip6(&sq->addr, sq->addrlen)) {
|
||||
if(EDNS_FRAG_SIZE_IP6 < EDNS_ADVERTISED_SIZE)
|
||||
edns.udp_size = EDNS_FRAG_SIZE_IP6;
|
||||
else edns.udp_size = EDNS_ADVERTISED_SIZE;
|
||||
} else {
|
||||
if(EDNS_FRAG_SIZE_IP4 < EDNS_ADVERTISED_SIZE)
|
||||
edns.udp_size = EDNS_FRAG_SIZE_IP4;
|
||||
else edns.udp_size = EDNS_ADVERTISED_SIZE;
|
||||
}
|
||||
} else {
|
||||
edns.udp_size = EDNS_ADVERTISED_SIZE;
|
||||
}
|
||||
edns.bits = 0;
|
||||
if(sq->dnssec & EDNS_DO)
|
||||
edns.bits = EDNS_DO;
|
||||
@@ -1304,8 +1355,8 @@ serviced_udp_send(struct serviced_query* sq, ldns_buffer* buff)
|
||||
uint8_t edns_lame_known;
|
||||
uint32_t now = *sq->outnet->now_secs;
|
||||
|
||||
if(!infra_host(sq->outnet->infra, &sq->addr, sq->addrlen, now, &vs,
|
||||
&edns_lame_known, &rtt))
|
||||
if(!infra_host(sq->outnet->infra, &sq->addr, sq->addrlen, sq->zone,
|
||||
sq->zonelen, now, &vs, &edns_lame_known, &rtt))
|
||||
return 0;
|
||||
sq->last_rtt = rtt;
|
||||
verbose(VERB_ALGO, "EDNS lookup known=%d vs=%d", edns_lame_known, vs);
|
||||
@@ -1324,7 +1375,8 @@ serviced_udp_send(struct serviced_query* sq, ldns_buffer* buff)
|
||||
sq->status = serviced_query_UDP;
|
||||
}
|
||||
}
|
||||
serviced_encode(sq, buff, sq->status == serviced_query_UDP_EDNS);
|
||||
serviced_encode(sq, buff, (sq->status == serviced_query_UDP_EDNS) ||
|
||||
(sq->status == serviced_query_UDP_EDNS_FRAG));
|
||||
sq->last_sent_time = *sq->outnet->now_tv;
|
||||
sq->edns_lame_known = (int)edns_lame_known;
|
||||
verbose(VERB_ALGO, "serviced query UDP timeout=%d msec", rtt);
|
||||
@@ -1387,11 +1439,13 @@ serviced_callbacks(struct serviced_query* sq, int error, struct comm_point* c,
|
||||
int dobackup = (sq->cblist && sq->cblist->next); /* >1 cb*/
|
||||
uint8_t *backup_p = NULL;
|
||||
size_t backlen = 0;
|
||||
rbnode_t* rem;
|
||||
#ifdef UNBOUND_DEBUG
|
||||
rbnode_t* rem =
|
||||
#endif
|
||||
/* remove from tree, and schedule for deletion, so that callbacks
|
||||
* can safely deregister themselves and even create new serviced
|
||||
* queries that are identical to this one. */
|
||||
rem = rbtree_delete(sq->outnet->serviced, sq);
|
||||
rbtree_delete(sq->outnet->serviced, sq);
|
||||
log_assert(rem); /* should have been present */
|
||||
sq->to_be_deleted = 1;
|
||||
verbose(VERB_ALGO, "svcd callbacks start");
|
||||
@@ -1472,7 +1526,7 @@ serviced_tcp_callback(struct comm_point* c, void* arg, int error,
|
||||
&sq->addr, sq->addrlen);
|
||||
if(error==NETEVENT_NOERROR)
|
||||
infra_update_tcp_works(sq->outnet->infra, &sq->addr,
|
||||
sq->addrlen);
|
||||
sq->addrlen, sq->zone, sq->zonelen);
|
||||
if(error==NETEVENT_NOERROR && sq->status == serviced_query_TCP_EDNS &&
|
||||
(LDNS_RCODE_WIRE(ldns_buffer_begin(c->buffer)) ==
|
||||
LDNS_RCODE_FORMERR || LDNS_RCODE_WIRE(ldns_buffer_begin(
|
||||
@@ -1493,10 +1547,31 @@ serviced_tcp_callback(struct comm_point* c, void* arg, int error,
|
||||
/* only store noEDNS in cache if domain is noDNSSEC */
|
||||
if(!sq->want_dnssec)
|
||||
if(!infra_edns_update(sq->outnet->infra, &sq->addr,
|
||||
sq->addrlen, -1, *sq->outnet->now_secs))
|
||||
sq->addrlen, sq->zone, sq->zonelen, -1,
|
||||
*sq->outnet->now_secs))
|
||||
log_err("Out of memory caching no edns for host");
|
||||
sq->status = serviced_query_TCP;
|
||||
}
|
||||
if(sq->tcp_upstream || sq->ssl_upstream) {
|
||||
struct timeval now = *sq->outnet->now_tv;
|
||||
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 */
|
||||
int roundtime = ((int)now.tv_sec - (int)sq->last_sent_time.tv_sec)*1000
|
||||
+ ((int)now.tv_usec - (int)sq->last_sent_time.tv_usec)/1000;
|
||||
verbose(VERB_ALGO, "measured TCP-time at %d msec", roundtime);
|
||||
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(!infra_rtt_update(sq->outnet->infra, &sq->addr,
|
||||
sq->addrlen, sq->zone, sq->zonelen, roundtime,
|
||||
sq->last_rtt, (uint32_t)now.tv_sec))
|
||||
log_err("out of memory noting rtt.");
|
||||
}
|
||||
}
|
||||
}
|
||||
/* insert address into reply info */
|
||||
if(!rep) {
|
||||
/* create one if there isn't (on errors) */
|
||||
@@ -1516,9 +1591,10 @@ serviced_tcp_initiate(struct outside_network* outnet,
|
||||
verbose(VERB_ALGO, "initiate TCP query %s",
|
||||
sq->status==serviced_query_TCP_EDNS?"EDNS":"");
|
||||
serviced_encode(sq, buff, sq->status == serviced_query_TCP_EDNS);
|
||||
sq->last_sent_time = *sq->outnet->now_tv;
|
||||
sq->pending = pending_tcp_query(outnet, buff, &sq->addr,
|
||||
sq->addrlen, TCP_AUTH_QUERY_TIMEOUT, serviced_tcp_callback,
|
||||
sq);
|
||||
sq, sq->ssl_upstream);
|
||||
if(!sq->pending) {
|
||||
/* delete from tree so that a retry by above layer does not
|
||||
* clash with this entry */
|
||||
@@ -1533,16 +1609,18 @@ serviced_tcp_send(struct serviced_query* sq, ldns_buffer* buff)
|
||||
{
|
||||
int vs, rtt;
|
||||
uint8_t edns_lame_known;
|
||||
if(!infra_host(sq->outnet->infra, &sq->addr, sq->addrlen,
|
||||
*sq->outnet->now_secs, &vs, &edns_lame_known, &rtt))
|
||||
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;
|
||||
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->outnet, buff, &sq->addr,
|
||||
sq->addrlen, TCP_AUTH_QUERY_TIMEOUT, serviced_tcp_callback,
|
||||
sq);
|
||||
sq, sq->ssl_upstream);
|
||||
return sq->pending != NULL;
|
||||
}
|
||||
|
||||
@@ -1564,9 +1642,24 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
|
||||
* by EDNS. */
|
||||
sq->status = serviced_query_UDP_EDNS;
|
||||
}
|
||||
if(sq->status == serviced_query_UDP_EDNS && sq->last_rtt < 5000) {
|
||||
/* fallback to 1480/1280 */
|
||||
sq->status = serviced_query_UDP_EDNS_FRAG;
|
||||
log_name_addr(VERB_ALGO, "try edns1xx0", sq->qbuf+10,
|
||||
&sq->addr, sq->addrlen);
|
||||
if(!serviced_udp_send(sq, c->buffer)) {
|
||||
serviced_callbacks(sq, NETEVENT_CLOSED, c, rep);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if(sq->status == serviced_query_UDP_EDNS_FRAG) {
|
||||
/* fragmentation size did not fix it */
|
||||
sq->status = serviced_query_UDP_EDNS;
|
||||
}
|
||||
sq->retry++;
|
||||
if(!(rto=infra_rtt_update(outnet->infra, &sq->addr, sq->addrlen,
|
||||
-1, sq->last_rtt, (uint32_t)now.tv_sec)))
|
||||
sq->zone, sq->zonelen, -1, sq->last_rtt,
|
||||
(uint32_t)now.tv_sec)))
|
||||
log_err("out of memory in UDP exponential backoff");
|
||||
if(sq->retry < OUTBOUND_UDP_RETRY) {
|
||||
log_name_addr(VERB_ALGO, "retry query", sq->qbuf+10,
|
||||
@@ -1589,7 +1682,8 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
|
||||
return 0;
|
||||
}
|
||||
if(!fallback_tcp) {
|
||||
if(sq->status == serviced_query_UDP_EDNS
|
||||
if( (sq->status == serviced_query_UDP_EDNS
|
||||
||sq->status == serviced_query_UDP_EDNS_FRAG)
|
||||
&& (LDNS_RCODE_WIRE(ldns_buffer_begin(c->buffer))
|
||||
== LDNS_RCODE_FORMERR || LDNS_RCODE_WIRE(
|
||||
ldns_buffer_begin(c->buffer)) == LDNS_RCODE_NOTIMPL)) {
|
||||
@@ -1609,7 +1703,7 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
|
||||
/* only store noEDNS in cache if domain is noDNSSEC */
|
||||
if(!sq->want_dnssec)
|
||||
if(!infra_edns_update(outnet->infra, &sq->addr, sq->addrlen,
|
||||
-1, (uint32_t)now.tv_sec)) {
|
||||
sq->zone, sq->zonelen, -1, (uint32_t)now.tv_sec)) {
|
||||
log_err("Out of memory caching no edns for host");
|
||||
}
|
||||
sq->status = serviced_query_UDP;
|
||||
@@ -1619,7 +1713,7 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
|
||||
log_addr(VERB_ALGO, "serviced query: EDNS works for",
|
||||
&sq->addr, sq->addrlen);
|
||||
if(!infra_edns_update(outnet->infra, &sq->addr, sq->addrlen,
|
||||
0, (uint32_t)now.tv_sec)) {
|
||||
sq->zone, sq->zonelen, 0, (uint32_t)now.tv_sec)) {
|
||||
log_err("Out of memory caching edns works");
|
||||
}
|
||||
sq->edns_lame_known = 1;
|
||||
@@ -1636,7 +1730,7 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
|
||||
log_addr(VERB_ALGO, "serviced query: EDNS fails for",
|
||||
&sq->addr, sq->addrlen);
|
||||
if(!infra_edns_update(outnet->infra, &sq->addr, sq->addrlen,
|
||||
-1, (uint32_t)now.tv_sec)) {
|
||||
sq->zone, sq->zonelen, -1, (uint32_t)now.tv_sec)) {
|
||||
log_err("Out of memory caching no edns for host");
|
||||
}
|
||||
} else {
|
||||
@@ -1654,9 +1748,14 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
|
||||
+ ((int)now.tv_usec - (int)sq->last_sent_time.tv_usec)/1000;
|
||||
verbose(VERB_ALGO, "measured roundtrip at %d msec", roundtime);
|
||||
log_assert(roundtime >= 0);
|
||||
if(!infra_rtt_update(outnet->infra, &sq->addr, sq->addrlen,
|
||||
roundtime, sq->last_rtt, (uint32_t)now.tv_sec))
|
||||
/* in case the system hibernated, do not enter a huge value,
|
||||
* above this value gives trouble with server selection */
|
||||
if(roundtime < 60000) {
|
||||
if(!infra_rtt_update(outnet->infra, &sq->addr, sq->addrlen,
|
||||
sq->zone, sq->zonelen, roundtime, sq->last_rtt,
|
||||
(uint32_t)now.tv_sec))
|
||||
log_err("out of memory noting rtt.");
|
||||
}
|
||||
}
|
||||
} /* end of if_!fallback_tcp */
|
||||
/* perform TC flag check and TCP fallback after updating our
|
||||
@@ -1665,6 +1764,7 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
|
||||
/* fallback to TCP */
|
||||
/* this discards partial UDP contents */
|
||||
if(sq->status == serviced_query_UDP_EDNS ||
|
||||
sq->status == serviced_query_UDP_EDNS_FRAG ||
|
||||
sq->status == serviced_query_UDP_EDNS_fallback)
|
||||
/* if we have unfinished EDNS_fallback, start again */
|
||||
sq->status = serviced_query_TCP_EDNS;
|
||||
@@ -1694,9 +1794,9 @@ struct serviced_query*
|
||||
outnet_serviced_query(struct outside_network* outnet,
|
||||
uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
|
||||
uint16_t flags, int dnssec, int want_dnssec, int tcp_upstream,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
comm_point_callback_t* callback, void* callback_arg,
|
||||
ldns_buffer* buff, int (*arg_compare)(void*,void*))
|
||||
int ssl_upstream, struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
uint8_t* zone, size_t zonelen, comm_point_callback_t* callback,
|
||||
void* callback_arg, ldns_buffer* buff, int (*arg_compare)(void*,void*))
|
||||
{
|
||||
struct serviced_query* sq;
|
||||
struct service_callback* cb;
|
||||
@@ -1713,16 +1813,18 @@ outnet_serviced_query(struct outside_network* outnet,
|
||||
if(!sq) {
|
||||
/* make new serviced query entry */
|
||||
sq = serviced_create(outnet, buff, dnssec, want_dnssec,
|
||||
addr, addrlen);
|
||||
tcp_upstream, ssl_upstream, addr, addrlen, zone,
|
||||
zonelen);
|
||||
if(!sq) {
|
||||
free(cb);
|
||||
return NULL;
|
||||
}
|
||||
/* perform first network action */
|
||||
if(outnet->do_udp && !tcp_upstream) {
|
||||
if(outnet->do_udp && !(tcp_upstream || ssl_upstream)) {
|
||||
if(!serviced_udp_send(sq, buff)) {
|
||||
(void)rbtree_delete(outnet->serviced, sq);
|
||||
free(sq->qbuf);
|
||||
free(sq->zone);
|
||||
free(sq);
|
||||
free(cb);
|
||||
return NULL;
|
||||
@@ -1731,6 +1833,7 @@ outnet_serviced_query(struct outside_network* outnet,
|
||||
if(!serviced_tcp_send(sq, buff)) {
|
||||
(void)rbtree_delete(outnet->serviced, sq);
|
||||
free(sq->qbuf);
|
||||
free(sq->zone);
|
||||
free(sq);
|
||||
free(cb);
|
||||
return NULL;
|
||||
@@ -1768,8 +1871,10 @@ void outnet_serviced_query_stop(struct serviced_query* sq, void* cb_arg)
|
||||
callback_list_remove(sq, cb_arg);
|
||||
/* if callbacks() routine scheduled deletion, let it do that */
|
||||
if(!sq->cblist && !sq->to_be_deleted) {
|
||||
rbnode_t* rem;
|
||||
rem = rbtree_delete(sq->outnet->serviced, sq);
|
||||
#ifdef UNBOUND_DEBUG
|
||||
rbnode_t* rem =
|
||||
#endif
|
||||
rbtree_delete(sq->outnet->serviced, sq);
|
||||
log_assert(rem); /* should be present */
|
||||
serviced_delete(sq);
|
||||
}
|
||||
@@ -1866,6 +1971,7 @@ serviced_get_mem(struct serviced_query* sq)
|
||||
if(sq->status == serviced_query_UDP_EDNS ||
|
||||
sq->status == serviced_query_UDP ||
|
||||
sq->status == serviced_query_PROBE_EDNS ||
|
||||
sq->status == serviced_query_UDP_EDNS_FRAG ||
|
||||
sq->status == serviced_query_UDP_EDNS_fallback) {
|
||||
s += sizeof(struct pending);
|
||||
s += comm_timer_get_mem(NULL);
|
||||
|
||||
@@ -118,6 +118,8 @@ struct outside_network {
|
||||
struct infra_cache* infra;
|
||||
/** where to get random numbers */
|
||||
struct ub_randstate* rnd;
|
||||
/** ssl context to create ssl wrapped TCP with DNS connections */
|
||||
void* sslctx;
|
||||
|
||||
/**
|
||||
* Array of tcp pending used for outgoing TCP connections.
|
||||
@@ -260,6 +262,8 @@ struct waiting_tcp {
|
||||
comm_point_callback_t* cb;
|
||||
/** callback user argument */
|
||||
void* cb_arg;
|
||||
/** if it uses ssl upstream */
|
||||
int ssl_upstream;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -274,6 +278,11 @@ struct service_callback {
|
||||
void* cb_arg;
|
||||
};
|
||||
|
||||
/** fallback size for fragmentation for EDNS in IPv4 */
|
||||
#define EDNS_FRAG_SIZE_IP4 1480
|
||||
/** fallback size for EDNS in IPv6, fits one fragment with ip6-tunnel-ids */
|
||||
#define EDNS_FRAG_SIZE_IP6 1260
|
||||
|
||||
/**
|
||||
* Query service record.
|
||||
* Contains query and destination. UDP, TCP, EDNS are all tried.
|
||||
@@ -293,10 +302,16 @@ struct serviced_query {
|
||||
int dnssec;
|
||||
/** We want signatures, or else the answer is likely useless */
|
||||
int want_dnssec;
|
||||
/** tcp upstream used, use tcp, or ssl_upstream for SSL */
|
||||
int tcp_upstream, ssl_upstream;
|
||||
/** where to send it */
|
||||
struct sockaddr_storage addr;
|
||||
/** length of addr field in use. */
|
||||
socklen_t addrlen;
|
||||
/** zone name, uncompressed domain name in wireformat */
|
||||
uint8_t* zone;
|
||||
/** length of zone name */
|
||||
size_t zonelen;
|
||||
/** current status */
|
||||
enum serviced_query_status {
|
||||
/** initial status */
|
||||
@@ -314,7 +329,9 @@ struct serviced_query {
|
||||
/** probe to test noEDNS0 (EDNS gives FORMERRorNOTIMP) */
|
||||
serviced_query_UDP_EDNS_fallback,
|
||||
/** probe to test TCP noEDNS0 (EDNS gives FORMERRorNOTIMP) */
|
||||
serviced_query_TCP_EDNS_fallback
|
||||
serviced_query_TCP_EDNS_fallback,
|
||||
/** send UDP query with EDNS1480 (or 1280) */
|
||||
serviced_query_UDP_EDNS_FRAG
|
||||
}
|
||||
/** variable with current status */
|
||||
status;
|
||||
@@ -356,6 +373,7 @@ struct serviced_query {
|
||||
* @param unwanted_action: the action to take.
|
||||
* @param unwanted_param: user parameter to action.
|
||||
* @param do_udp: if udp is done.
|
||||
* @param sslctx: context to create outgoing connections with (if enabled).
|
||||
* @return: the new structure (with no pending answers) or NULL on error.
|
||||
*/
|
||||
struct outside_network* outside_network_create(struct comm_base* base,
|
||||
@@ -363,7 +381,8 @@ struct outside_network* outside_network_create(struct comm_base* base,
|
||||
int do_ip4, int do_ip6, size_t num_tcp, struct infra_cache* infra,
|
||||
struct ub_randstate* rnd, int use_caps_for_id, int* availports,
|
||||
int numavailports, size_t unwanted_threshold,
|
||||
void (*unwanted_action)(void*), void* unwanted_param, int do_udp);
|
||||
void (*unwanted_action)(void*), void* unwanted_param, int do_udp,
|
||||
void* sslctx);
|
||||
|
||||
/**
|
||||
* Delete outside_network structure.
|
||||
@@ -406,12 +425,13 @@ struct pending* pending_udp_query(struct outside_network* outnet,
|
||||
* without any query been sent to the server yet.
|
||||
* @param callback: function to call on error, timeout or reply.
|
||||
* @param callback_arg: user argument for callback function.
|
||||
* @param ssl_upstream: if the tcp connection must use SSL.
|
||||
* @return: false on error for malloc or socket. Else the pending TCP object.
|
||||
*/
|
||||
struct waiting_tcp* pending_tcp_query(struct outside_network* outnet,
|
||||
ldns_buffer* packet, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, int timeout, comm_point_callback_t* callback,
|
||||
void* callback_arg);
|
||||
void* callback_arg, int ssl_upstream);
|
||||
|
||||
/**
|
||||
* Delete pending answer.
|
||||
@@ -436,10 +456,15 @@ void pending_delete(struct outside_network* outnet, struct pending* p);
|
||||
* @param want_dnssec: signatures are needed, without EDNS the answer is
|
||||
* likely to be useless.
|
||||
* @param tcp_upstream: use TCP for upstream queries.
|
||||
* @param ssl_upstream: use SSL for upstream queries.
|
||||
* @param callback: callback function.
|
||||
* @param callback_arg: user argument to callback function.
|
||||
* @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.
|
||||
This is the delegation point name for which the server is deemed
|
||||
authoritative.
|
||||
* @param zonelen: length of zone.
|
||||
* @param buff: scratch buffer to create query contents in. Empty on exit.
|
||||
* @param arg_compare: function to compare callback args, return true if
|
||||
* identical. It is given the callback_arg and args that are listed.
|
||||
@@ -449,9 +474,10 @@ void pending_delete(struct outside_network* outnet, struct pending* p);
|
||||
struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
|
||||
uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
|
||||
uint16_t flags, int dnssec, int want_dnssec, int tcp_upstream,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
comm_point_callback_t* callback, void* callback_arg,
|
||||
ldns_buffer* buff, int (*arg_compare)(void*,void*));
|
||||
int ssl_upstream, struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
uint8_t* zone, size_t zonelen, comm_point_callback_t* callback,
|
||||
void* callback_arg, ldns_buffer* buff,
|
||||
int (*arg_compare)(void*,void*));
|
||||
|
||||
/**
|
||||
* Remove service query callback.
|
||||
|
||||
@@ -1583,7 +1583,9 @@ xml_parse(BIO* xml, time_t now)
|
||||
(void)BIO_seek(data.ds, 0);
|
||||
len = BIO_get_mem_data(data.ds, &pp);
|
||||
printf("got DS bio %d: '", len);
|
||||
(void)fwrite(pp, (size_t)len, 1, stdout);
|
||||
if(!fwrite(pp, (size_t)len, 1, stdout))
|
||||
/* compilers do not allow us to ignore fwrite .. */
|
||||
fprintf(stderr, "error writing to stdout\n");
|
||||
printf("'\n");
|
||||
}
|
||||
BIO_free(data.czone);
|
||||
|
||||
@@ -255,9 +255,10 @@ print_rd(int t, char* data, size_t len)
|
||||
ldns_rr_set_owner(rr, NULL);
|
||||
status = ldns_wire2rdf(rr, rd, len+2, &pos);
|
||||
if(status != LDNS_STATUS_OK) {
|
||||
|
||||
free(rd);
|
||||
ldns_rr_free(rr);
|
||||
printf("error_printing_data");
|
||||
return;
|
||||
}
|
||||
for(i=0; i<ldns_rr_rd_count(rr); i++) {
|
||||
printf(" ");
|
||||
|
||||
+23
-11
@@ -51,6 +51,7 @@
|
||||
#include "util/data/msgparse.h"
|
||||
#include "util/data/msgreply.h"
|
||||
#include "util/data/msgencode.h"
|
||||
#include "util/data/dname.h"
|
||||
#include "util/config_file.h"
|
||||
#include "services/listen_dnsport.h"
|
||||
#include "services/outside_network.h"
|
||||
@@ -548,11 +549,17 @@ static void
|
||||
do_infra_rtt(struct replay_runtime* runtime)
|
||||
{
|
||||
struct replay_moment* now = runtime->now;
|
||||
int rto = infra_rtt_update(runtime->infra, &now->addr,
|
||||
now->addrlen, atoi(now->string), -1, runtime->now_secs);
|
||||
int rto;
|
||||
ldns_rdf* dp = ldns_dname_new_frm_str(now->variable);
|
||||
if(!dp) fatal_exit("cannot parse %s", now->variable);
|
||||
rto = infra_rtt_update(runtime->infra, &now->addr,
|
||||
now->addrlen, ldns_rdf_data(dp), ldns_rdf_size(dp),
|
||||
atoi(now->string), -1, runtime->now_secs);
|
||||
log_addr(0, "INFRA_RTT for", &now->addr, now->addrlen);
|
||||
log_info("INFRA_RTT(roundtrip %d): rto of %d", atoi(now->string), rto);
|
||||
log_info("INFRA_RTT(%s roundtrip %d): rto of %d", now->variable,
|
||||
atoi(now->string), rto);
|
||||
if(rto == 0) fatal_exit("infra_rtt_update failed");
|
||||
ldns_rdf_deep_free(dp);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -701,7 +708,7 @@ run_scenario(struct replay_runtime* runtime)
|
||||
struct listen_dnsport*
|
||||
listen_create(struct comm_base* base, struct listen_port* ATTR_UNUSED(ports),
|
||||
size_t bufsize, int ATTR_UNUSED(tcp_accept_count),
|
||||
comm_point_callback_t* cb, void* cb_arg)
|
||||
void* ATTR_UNUSED(sslctx), comm_point_callback_t* cb, void* cb_arg)
|
||||
{
|
||||
struct replay_runtime* runtime = (struct replay_runtime*)base;
|
||||
struct listen_dnsport* l= calloc(1, sizeof(struct listen_dnsport));
|
||||
@@ -870,7 +877,7 @@ outside_network_create(struct comm_base* base, size_t bufsize,
|
||||
int ATTR_UNUSED(use_caps_for_id), int* ATTR_UNUSED(availports),
|
||||
int ATTR_UNUSED(numavailports), size_t ATTR_UNUSED(unwanted_threshold),
|
||||
void (*unwanted_action)(void*), void* ATTR_UNUSED(unwanted_param),
|
||||
int ATTR_UNUSED(do_udp))
|
||||
int ATTR_UNUSED(do_udp), void* ATTR_UNUSED(sslctx))
|
||||
{
|
||||
struct replay_runtime* runtime = (struct replay_runtime*)base;
|
||||
struct outside_network* outnet = calloc(1,
|
||||
@@ -955,7 +962,8 @@ pending_udp_query(struct outside_network* outnet, ldns_buffer* packet,
|
||||
struct waiting_tcp*
|
||||
pending_tcp_query(struct outside_network* outnet, ldns_buffer* packet,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, int timeout,
|
||||
comm_point_callback_t* callback, void* callback_arg)
|
||||
comm_point_callback_t* callback, void* callback_arg,
|
||||
int ATTR_UNUSED(ssl_upstream))
|
||||
{
|
||||
struct replay_runtime* runtime = (struct replay_runtime*)outnet->base;
|
||||
struct fake_pending* pend = (struct fake_pending*)calloc(1,
|
||||
@@ -1007,20 +1015,24 @@ pending_tcp_query(struct outside_network* outnet, ldns_buffer* packet,
|
||||
struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
|
||||
uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
|
||||
uint16_t flags, int dnssec, int ATTR_UNUSED(want_dnssec),
|
||||
int ATTR_UNUSED(tcp_upstream), struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, comm_point_callback_t* callback, void* callback_arg,
|
||||
ldns_buffer* ATTR_UNUSED(buff), int (*arg_compare)(void*,void*))
|
||||
int ATTR_UNUSED(tcp_upstream), int ATTR_UNUSED(ssl_upstream),
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
|
||||
size_t ATTR_UNUSED(zonelen), comm_point_callback_t* callback,
|
||||
void* callback_arg, ldns_buffer* ATTR_UNUSED(buff),
|
||||
int (*arg_compare)(void*,void*))
|
||||
{
|
||||
struct replay_runtime* runtime = (struct replay_runtime*)outnet->base;
|
||||
struct fake_pending* pend = (struct fake_pending*)calloc(1,
|
||||
sizeof(struct fake_pending));
|
||||
char z[256];
|
||||
ldns_status status;
|
||||
(void)arg_compare;
|
||||
log_assert(pend);
|
||||
log_nametypeclass(VERB_OPS, "pending serviced query",
|
||||
qname, qtype, qclass);
|
||||
verbose(VERB_OPS, "pending serviced query flags%s%s%s%s",
|
||||
(flags&BIT_RD)?" RD":"", (flags&BIT_CD)?" CD":"",
|
||||
dname_str(zone, z);
|
||||
verbose(VERB_OPS, "pending serviced query zone %s flags%s%s%s%s",
|
||||
z, (flags&BIT_RD)?" RD":"", (flags&BIT_CD)?" CD":"",
|
||||
(flags&~(BIT_RD|BIT_CD))?" MORE":"", (dnssec)?" DO":"");
|
||||
|
||||
/* create packet with EDNS */
|
||||
|
||||
+1
-1
@@ -72,7 +72,7 @@
|
||||
#ifdef HAVE_GETOPT_H
|
||||
#include <getopt.h>
|
||||
#endif
|
||||
#include "ldns/ldns.h"
|
||||
#include <ldns/ldns.h>
|
||||
#include <signal.h>
|
||||
#include "libunbound/unbound.h"
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
|
||||
@@ -231,7 +231,7 @@ static void adjustline(char* line, struct entry* e,
|
||||
static struct entry* new_entry()
|
||||
{
|
||||
struct entry* e = LDNS_MALLOC(struct entry);
|
||||
memset(e, 0, sizeof(e));
|
||||
memset(e, 0, sizeof(*e));
|
||||
e->match_opcode = false;
|
||||
e->match_qtype = false;
|
||||
e->match_qname = false;
|
||||
|
||||
+1
-1
@@ -43,7 +43,7 @@
|
||||
#ifdef HAVE_GETOPT_H
|
||||
#include <getopt.h>
|
||||
#endif
|
||||
#include "ldns/ldns.h"
|
||||
#include <ldns/ldns.h>
|
||||
#include <signal.h>
|
||||
#include "util/log.h"
|
||||
#include "util/locks.h"
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "ldns/ldns.h"
|
||||
#include <ldns/ldns.h>
|
||||
#include "util/log.h"
|
||||
#include "util/data/dname.h"
|
||||
#include "util/data/msgparse.h"
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@
|
||||
|
||||
#ifndef TESTCODE_READHEX_H
|
||||
#define TESTCODE_READHEX_H
|
||||
#include "ldns/buffer.h"
|
||||
#include <ldns/buffer.h>
|
||||
|
||||
/**
|
||||
* Helper to convert hex string to packet buffer.
|
||||
|
||||
+13
-5
@@ -331,23 +331,31 @@ replay_moment_read(char* remain, FILE* in, const char* name, int* lineno,
|
||||
mom->evt_type = repevt_assign;
|
||||
read_assign_step(remain, mom);
|
||||
} else if(parse_keyword(&remain, "INFRA_RTT")) {
|
||||
char *s;
|
||||
char *s, *m;
|
||||
mom->evt_type = repevt_infra_rtt;
|
||||
while(isspace((int)*remain))
|
||||
remain++;
|
||||
s = remain;
|
||||
remain = strchr(s, ' ');
|
||||
if(!remain) fatal_exit("expected two args for INFRA_RTT");
|
||||
if(!remain) fatal_exit("expected three args for INFRA_RTT");
|
||||
remain[0] = 0;
|
||||
remain++;
|
||||
while(isspace((int)*remain))
|
||||
remain++;
|
||||
m = strchr(remain, ' ');
|
||||
if(!m) fatal_exit("expected three args for INFRA_RTT");
|
||||
m[0] = 0;
|
||||
m++;
|
||||
while(isspace((int)*m))
|
||||
m++;
|
||||
if(!extstrtoaddr(s, &mom->addr, &mom->addrlen))
|
||||
fatal_exit("bad infra_rtt address %s", s);
|
||||
if(strlen(remain)>0 && remain[strlen(remain)-1]=='\n')
|
||||
remain[strlen(remain)-1] = 0;
|
||||
mom->string = strdup(remain);
|
||||
if(strlen(m)>0 && m[strlen(m)-1]=='\n')
|
||||
m[strlen(m)-1] = 0;
|
||||
mom->variable = strdup(remain);
|
||||
mom->string = strdup(m);
|
||||
if(!mom->string) fatal_exit("out of memory");
|
||||
if(!mom->variable) fatal_exit("out of memory");
|
||||
} else {
|
||||
log_err("%d: unknown event type %s", *lineno, remain);
|
||||
free(mom);
|
||||
|
||||
+1
-1
@@ -75,7 +75,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 INFRA_RTT [ip] [rtt] - update infra cache entry with rtt.
|
||||
* o INFRA_RTT [ip] [dp] [rtt] - update infra cache entry with rtt.
|
||||
* o ERROR
|
||||
* ; following entry starts on the next line, ENTRY_BEGIN.
|
||||
* ; more STEP items
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@
|
||||
* construct input to test the validator with.
|
||||
*/
|
||||
#include "config.h"
|
||||
#include "ldns/ldns.h"
|
||||
#include <ldns/ldns.h>
|
||||
#include "util/log.h"
|
||||
#include "util/config_file.h"
|
||||
#include "util/net_help.h"
|
||||
|
||||
+125
-33
@@ -43,14 +43,16 @@
|
||||
#ifdef HAVE_GETOPT_H
|
||||
#include <getopt.h>
|
||||
#endif
|
||||
#include "ldns/ldns.h"
|
||||
#include <ldns/ldns.h>
|
||||
#include <signal.h>
|
||||
#include "util/locks.h"
|
||||
#include "util/log.h"
|
||||
#include "util/net_help.h"
|
||||
#include "util/data/msgencode.h"
|
||||
#include "util/data/msgparse.h"
|
||||
#include "util/data/msgreply.h"
|
||||
#include "util/data/dname.h"
|
||||
#include <openssl/err.h>
|
||||
|
||||
#ifndef PF_INET6
|
||||
/** define in case streamtcp is compiled on legacy systems */
|
||||
@@ -65,6 +67,7 @@ static void usage(char* argv[])
|
||||
printf("-f server what ipaddr@portnr to send the queries to\n");
|
||||
printf("-u use UDP. No retries are attempted.\n");
|
||||
printf("-n do not wait for an answer.\n");
|
||||
printf("-s use ssl\n");
|
||||
printf("-h this help text\n");
|
||||
exit(1);
|
||||
}
|
||||
@@ -105,7 +108,7 @@ open_svr(const char* svr, int udp)
|
||||
|
||||
/** write a query over the TCP fd */
|
||||
static void
|
||||
write_q(int fd, int udp, ldns_buffer* buf, int id,
|
||||
write_q(int fd, int udp, SSL* ssl, ldns_buffer* buf, uint16_t id,
|
||||
const char* strname, const char* strtype, const char* strclass)
|
||||
{
|
||||
struct query_info qinfo;
|
||||
@@ -128,65 +131,111 @@ write_q(int fd, int udp, ldns_buffer* buf, int id,
|
||||
|
||||
/* make query */
|
||||
qinfo_query_encode(buf, &qinfo);
|
||||
ldns_buffer_write_u16_at(buf, 0, (uint16_t)id);
|
||||
ldns_buffer_write_u16_at(buf, 0, id);
|
||||
ldns_buffer_write_u16_at(buf, 2, BIT_RD);
|
||||
|
||||
if(1) {
|
||||
/* add EDNS DO */
|
||||
struct edns_data edns;
|
||||
memset(&edns, 0, sizeof(edns));
|
||||
edns.edns_present = 1;
|
||||
edns.bits = EDNS_DO;
|
||||
edns.udp_size = 4096;
|
||||
attach_edns_record(buf, &edns);
|
||||
}
|
||||
|
||||
/* send it */
|
||||
if(!udp) {
|
||||
len = (uint16_t)ldns_buffer_limit(buf);
|
||||
len = htons(len);
|
||||
if(send(fd, (void*)&len, sizeof(len), 0)<(ssize_t)sizeof(len)){
|
||||
if(ssl) {
|
||||
if(SSL_write(ssl, (void*)&len, (int)sizeof(len)) <= 0) {
|
||||
log_crypto_err("cannot SSL_write");
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
if(send(fd, (void*)&len, sizeof(len), 0) <
|
||||
(ssize_t)sizeof(len)){
|
||||
#ifndef USE_WINSOCK
|
||||
perror("send() len failed");
|
||||
perror("send() len failed");
|
||||
#else
|
||||
printf("send len: %s\n",
|
||||
wsa_strerror(WSAGetLastError()));
|
||||
printf("send len: %s\n",
|
||||
wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(ssl) {
|
||||
if(SSL_write(ssl, (void*)ldns_buffer_begin(buf),
|
||||
(int)ldns_buffer_limit(buf)) <= 0) {
|
||||
log_crypto_err("cannot SSL_write");
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
if(send(fd, (void*)ldns_buffer_begin(buf),
|
||||
ldns_buffer_limit(buf), 0) <
|
||||
(ssize_t)ldns_buffer_limit(buf)) {
|
||||
#ifndef USE_WINSOCK
|
||||
perror("send() data failed");
|
||||
#else
|
||||
printf("send data: %s\n", wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
if(send(fd, (void*)ldns_buffer_begin(buf), ldns_buffer_limit(buf), 0) <
|
||||
(ssize_t)ldns_buffer_limit(buf)) {
|
||||
#ifndef USE_WINSOCK
|
||||
perror("send() data failed");
|
||||
#else
|
||||
printf("send data: %s\n", wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
exit(1);
|
||||
}
|
||||
|
||||
free(qinfo.qname);
|
||||
}
|
||||
|
||||
/** receive DNS datagram over TCP and print it */
|
||||
static void
|
||||
recv_one(int fd, int udp, ldns_buffer* buf)
|
||||
recv_one(int fd, int udp, SSL* ssl, ldns_buffer* buf)
|
||||
{
|
||||
uint16_t len;
|
||||
ldns_pkt* pkt;
|
||||
ldns_status status;
|
||||
if(!udp) {
|
||||
if(recv(fd, (void*)&len, sizeof(len), 0)<(ssize_t)sizeof(len)){
|
||||
if(ssl) {
|
||||
if(SSL_read(ssl, (void*)&len, (int)sizeof(len)) <= 0) {
|
||||
log_crypto_err("could not SSL_read");
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
if(recv(fd, (void*)&len, sizeof(len), 0) <
|
||||
(ssize_t)sizeof(len)) {
|
||||
#ifndef USE_WINSOCK
|
||||
perror("read() len failed");
|
||||
perror("read() len failed");
|
||||
#else
|
||||
printf("read len: %s\n",
|
||||
wsa_strerror(WSAGetLastError()));
|
||||
printf("read len: %s\n",
|
||||
wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
exit(1);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
len = ntohs(len);
|
||||
ldns_buffer_clear(buf);
|
||||
ldns_buffer_set_limit(buf, len);
|
||||
if(recv(fd, (void*)ldns_buffer_begin(buf), len, 0) <
|
||||
(ssize_t)len) {
|
||||
if(ssl) {
|
||||
int r = SSL_read(ssl, (void*)ldns_buffer_begin(buf),
|
||||
(int)len);
|
||||
if(r <= 0) {
|
||||
log_crypto_err("could not SSL_read");
|
||||
exit(1);
|
||||
}
|
||||
if(r != (int)len)
|
||||
fatal_exit("ssl_read %d of %d", r, len);
|
||||
} else {
|
||||
if(recv(fd, (void*)ldns_buffer_begin(buf), len, 0) <
|
||||
(ssize_t)len) {
|
||||
#ifndef USE_WINSOCK
|
||||
perror("read() data failed");
|
||||
perror("read() data failed");
|
||||
#else
|
||||
printf("read data: %s\n",
|
||||
wsa_strerror(WSAGetLastError()));
|
||||
printf("read data: %s\n",
|
||||
wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
exit(1);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ssize_t l;
|
||||
@@ -220,20 +269,54 @@ recv_one(int fd, int udp, ldns_buffer* buf)
|
||||
|
||||
/** send the TCP queries and print answers */
|
||||
static void
|
||||
send_em(const char* svr, int udp, int noanswer, int num, char** qs)
|
||||
send_em(const char* svr, int udp, int usessl, int noanswer, int num, char** qs)
|
||||
{
|
||||
ldns_buffer* buf = ldns_buffer_new(65553);
|
||||
int fd = open_svr(svr, udp);
|
||||
int i;
|
||||
SSL_CTX* ctx = NULL;
|
||||
SSL* ssl = NULL;
|
||||
if(!buf) fatal_exit("out of memory");
|
||||
if(usessl) {
|
||||
ctx = connect_sslctx_create(NULL, NULL, NULL);
|
||||
if(!ctx) fatal_exit("cannot create ssl ctx");
|
||||
ssl = outgoing_ssl_fd(ctx, fd);
|
||||
if(!ssl) fatal_exit("cannot create ssl");
|
||||
while(1) {
|
||||
int r;
|
||||
ERR_clear_error();
|
||||
if( (r=SSL_do_handshake(ssl)) == 1)
|
||||
break;
|
||||
r = SSL_get_error(ssl, r);
|
||||
if(r != SSL_ERROR_WANT_READ &&
|
||||
r != SSL_ERROR_WANT_WRITE) {
|
||||
log_crypto_err("could not ssl_handshake");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
if(1) {
|
||||
X509* x = SSL_get_peer_certificate(ssl);
|
||||
if(!x) printf("SSL: no peer certificate\n");
|
||||
else {
|
||||
X509_print_fp(stdout, x);
|
||||
X509_free(x);
|
||||
}
|
||||
}
|
||||
}
|
||||
for(i=0; i<num; i+=3) {
|
||||
printf("\nNext query is %s %s %s\n", qs[i], qs[i+1], qs[i+2]);
|
||||
write_q(fd, udp, buf, i, qs[i], qs[i+1], qs[i+2]);
|
||||
write_q(fd, udp, ssl, buf, ldns_get_random(), qs[i],
|
||||
qs[i+1], qs[i+2]);
|
||||
/* print at least one result */
|
||||
if(!noanswer)
|
||||
recv_one(fd, udp, buf);
|
||||
recv_one(fd, udp, ssl, buf);
|
||||
}
|
||||
|
||||
if(usessl) {
|
||||
SSL_shutdown(ssl);
|
||||
SSL_free(ssl);
|
||||
SSL_CTX_free(ctx);
|
||||
}
|
||||
#ifndef USE_WINSOCK
|
||||
close(fd);
|
||||
#else
|
||||
@@ -268,6 +351,7 @@ int main(int argc, char** argv)
|
||||
const char* svr = "127.0.0.1";
|
||||
int udp = 0;
|
||||
int noanswer = 0;
|
||||
int usessl = 0;
|
||||
|
||||
#ifdef USE_WINSOCK
|
||||
WSADATA wsa_data;
|
||||
@@ -292,7 +376,7 @@ int main(int argc, char** argv)
|
||||
if(argc == 1) {
|
||||
usage(argv);
|
||||
}
|
||||
while( (c=getopt(argc, argv, "f:hnu")) != -1) {
|
||||
while( (c=getopt(argc, argv, "f:hnsu")) != -1) {
|
||||
switch(c) {
|
||||
case 'f':
|
||||
svr = optarg;
|
||||
@@ -303,6 +387,9 @@ int main(int argc, char** argv)
|
||||
case 'u':
|
||||
udp = 1;
|
||||
break;
|
||||
case 's':
|
||||
usessl = 1;
|
||||
break;
|
||||
case 'h':
|
||||
case '?':
|
||||
default:
|
||||
@@ -316,7 +403,12 @@ int main(int argc, char** argv)
|
||||
printf("queries must be multiples of name,type,class\n");
|
||||
return 1;
|
||||
}
|
||||
send_em(svr, udp, noanswer, argc, argv);
|
||||
if(usessl) {
|
||||
ERR_load_SSL_strings();
|
||||
OpenSSL_add_all_algorithms();
|
||||
SSL_library_init();
|
||||
}
|
||||
send_em(svr, udp, usessl, noanswer, argc, argv);
|
||||
checklock_stop();
|
||||
#ifdef USE_WINSOCK
|
||||
WSACleanup();
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "ldns/rr.h"
|
||||
#include <ldns/rr.h>
|
||||
#include "util/log.h"
|
||||
#include "util/data/dname.h"
|
||||
#include "testcode/unitmain.h"
|
||||
|
||||
@@ -39,8 +39,8 @@
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "ldns/dname.h"
|
||||
#include "ldns/host2wire.h"
|
||||
#include <ldns/dname.h>
|
||||
#include <ldns/host2wire.h>
|
||||
#include "util/log.h"
|
||||
#include "testcode/unitmain.h"
|
||||
#include "util/data/dname.h"
|
||||
|
||||
+42
-30
@@ -55,7 +55,7 @@
|
||||
#ifdef HAVE_OPENSSL_ENGINE_H
|
||||
#include <openssl/engine.h>
|
||||
#endif
|
||||
#include "ldns/ldns.h"
|
||||
#include <ldns/ldns.h>
|
||||
#include "util/log.h"
|
||||
#include "testcode/unitmain.h"
|
||||
|
||||
@@ -401,6 +401,25 @@ 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,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
|
||||
size_t zonelen, int wr, uint32_t now, struct infra_key** k)
|
||||
{
|
||||
struct infra_data* d;
|
||||
struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen,
|
||||
zone, zonelen, wr);
|
||||
if(!e) return NULL;
|
||||
d = (struct infra_data*)e->data;
|
||||
if(d->ttl < now) {
|
||||
lock_rw_unlock(&e->lock);
|
||||
return NULL;
|
||||
}
|
||||
*k = (struct infra_key*)e->key;
|
||||
return d;
|
||||
}
|
||||
|
||||
/** test host cache */
|
||||
static void
|
||||
infra_test(void)
|
||||
@@ -414,70 +433,63 @@ infra_test(void)
|
||||
uint32_t now = 0;
|
||||
uint8_t edns_lame;
|
||||
int vs, to;
|
||||
struct infra_host_key* k;
|
||||
struct infra_host_data* d;
|
||||
struct infra_key* k;
|
||||
struct infra_data* d;
|
||||
int init = 376;
|
||||
int dlame, rlame, alame, olame;
|
||||
|
||||
unit_show_feature("infra cache");
|
||||
unit_assert(ipstrtoaddr("127.0.0.1", 53, &one, &onelen));
|
||||
|
||||
slab = infra_create(cfg);
|
||||
unit_assert( infra_host(slab, (struct sockaddr_storage*)&one,
|
||||
(socklen_t)sizeof(int), now, &vs, &edns_lame, &to) );
|
||||
unit_assert( infra_host(slab, &one, onelen, zone, zonelen, now,
|
||||
&vs, &edns_lame, &to) );
|
||||
unit_assert( vs == 0 && to == init && edns_lame == 0 );
|
||||
|
||||
unit_assert( infra_rtt_update(slab, &one, onelen, -1, init, now) );
|
||||
unit_assert( infra_host(slab, &one, onelen,
|
||||
unit_assert( infra_rtt_update(slab, &one, onelen, zone, zonelen, -1, init, now) );
|
||||
unit_assert( infra_host(slab, &one, onelen, zone, zonelen,
|
||||
now, &vs, &edns_lame, &to) );
|
||||
unit_assert( vs == 0 && to == init*2 && edns_lame == 0 );
|
||||
|
||||
unit_assert( infra_edns_update(slab, &one, onelen, -1, now) );
|
||||
unit_assert( infra_host(slab, &one, onelen,
|
||||
unit_assert( infra_edns_update(slab, &one, onelen, zone, zonelen, -1, now) );
|
||||
unit_assert( infra_host(slab, &one, onelen, zone, zonelen,
|
||||
now, &vs, &edns_lame, &to) );
|
||||
unit_assert( vs == -1 && to == init*2 && edns_lame == 1);
|
||||
|
||||
now += cfg->host_ttl + 10;
|
||||
unit_assert( infra_host(slab, &one, onelen,
|
||||
unit_assert( infra_host(slab, &one, onelen, zone, zonelen,
|
||||
now, &vs, &edns_lame, &to) );
|
||||
unit_assert( vs == 0 && to == init && edns_lame == 0 );
|
||||
|
||||
unit_assert( infra_set_lame(slab, &one, onelen,
|
||||
unit_assert( infra_set_lame(slab, &one, onelen,
|
||||
zone, zonelen, now, 0, 0, LDNS_RR_TYPE_A) );
|
||||
unit_assert( (d=infra_lookup_host(slab, &one, onelen, 0, now, &k)) );
|
||||
unit_assert( (d=infra_lookup_host(slab, &one, onelen, zone, zonelen, 0, now, &k)) );
|
||||
unit_assert( d->ttl == now+cfg->host_ttl );
|
||||
unit_assert( d->edns_version == 0 );
|
||||
unit_assert( infra_lookup_lame(d, zone, zonelen, now,
|
||||
&dlame, &rlame, &alame, &olame) );
|
||||
unit_assert(!dlame && !rlame && alame && !olame);
|
||||
unit_assert( !infra_lookup_lame(d, zone, zonelen,
|
||||
now+cfg->lame_ttl+10, &dlame, &rlame, &alame, &olame) );
|
||||
unit_assert( !infra_lookup_lame(d, (uint8_t*)"\000", 1, now,
|
||||
&dlame, &rlame, &alame, &olame) );
|
||||
unit_assert(!d->isdnsseclame && !d->rec_lame && d->lame_type_A &&
|
||||
!d->lame_other);
|
||||
lock_rw_unlock(&k->entry.lock);
|
||||
|
||||
/* test merge of data */
|
||||
unit_assert( infra_set_lame(slab, &one, onelen,
|
||||
unit_assert( infra_set_lame(slab, &one, onelen,
|
||||
zone, zonelen, now, 0, 0, LDNS_RR_TYPE_AAAA) );
|
||||
unit_assert( (d=infra_lookup_host(slab, &one, onelen, 0, now, &k)) );
|
||||
unit_assert( infra_lookup_lame(d, zone, zonelen, now,
|
||||
&dlame, &rlame, &alame, &olame) );
|
||||
unit_assert(!dlame && !rlame && alame && olame);
|
||||
unit_assert( (d=infra_lookup_host(slab, &one, onelen, zone, zonelen, 0, now, &k)) );
|
||||
unit_assert(!d->isdnsseclame && !d->rec_lame && d->lame_type_A &&
|
||||
d->lame_other);
|
||||
lock_rw_unlock(&k->entry.lock);
|
||||
|
||||
/* test that noEDNS cannot overwrite known-yesEDNS */
|
||||
now += cfg->host_ttl + 10;
|
||||
unit_assert( infra_host(slab, &one, onelen,
|
||||
unit_assert( infra_host(slab, &one, onelen, zone, zonelen,
|
||||
now, &vs, &edns_lame, &to) );
|
||||
unit_assert( vs == 0 && to == init && edns_lame == 0 );
|
||||
|
||||
unit_assert( infra_edns_update(slab, &one, onelen, 0, now) );
|
||||
unit_assert( infra_host(slab, &one, onelen,
|
||||
unit_assert( infra_edns_update(slab, &one, onelen, zone, zonelen, 0, now) );
|
||||
unit_assert( infra_host(slab, &one, onelen, zone, zonelen,
|
||||
now, &vs, &edns_lame, &to) );
|
||||
unit_assert( vs == 0 && to == init && edns_lame == 1 );
|
||||
|
||||
unit_assert( infra_edns_update(slab, &one, onelen, -1, now) );
|
||||
unit_assert( infra_host(slab, &one, onelen,
|
||||
unit_assert( infra_edns_update(slab, &one, onelen, zone, zonelen, -1, now) );
|
||||
unit_assert( infra_host(slab, &one, onelen, zone, zonelen,
|
||||
now, &vs, &edns_lame, &to) );
|
||||
unit_assert( vs == 0 && to == init && edns_lame == 1 );
|
||||
|
||||
|
||||
+11
-2
@@ -39,7 +39,7 @@
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "ldns/ldns.h"
|
||||
#include <ldns/ldns.h>
|
||||
#include "util/log.h"
|
||||
#include "testcode/unitmain.h"
|
||||
#include "util/data/msgparse.h"
|
||||
@@ -59,6 +59,8 @@ static int check_formerr_gone = 0;
|
||||
static int matches_nolocation = 0;
|
||||
/** see if RRSIGs are properly matched to RRsets. */
|
||||
static int check_rrsigs = 0;
|
||||
/** do not check buffer sameness */
|
||||
static int check_nosameness = 0;
|
||||
|
||||
/** match two rr lists */
|
||||
static int
|
||||
@@ -431,7 +433,8 @@ testpkt(ldns_buffer* pkt, struct alloc_cache* alloc, ldns_buffer* out,
|
||||
if(vbmp) printf("inlen %u outlen %u\n",
|
||||
(unsigned)ldns_buffer_limit(pkt),
|
||||
(unsigned)ldns_buffer_limit(out));
|
||||
test_buffers(pkt, out);
|
||||
if(!check_nosameness)
|
||||
test_buffers(pkt, out);
|
||||
if(check_rrsigs)
|
||||
check_the_rrsigs(&qi, rep);
|
||||
|
||||
@@ -607,6 +610,12 @@ void msgparse_test(void)
|
||||
testfromdrillfile(pkt, &alloc, out, "testdata/test_packets.8");
|
||||
check_formerr_gone = 0;
|
||||
|
||||
check_rrsigs = 1;
|
||||
check_nosameness = 1;
|
||||
testfromdrillfile(pkt, &alloc, out, "testdata/test_packets.9");
|
||||
check_nosameness = 0;
|
||||
check_rrsigs = 0;
|
||||
|
||||
/* cleanup */
|
||||
alloc_clear(&alloc);
|
||||
alloc_clear(&super_a);
|
||||
|
||||
Vendored
+2
-2
@@ -239,9 +239,9 @@ nx1.example.com. IN A
|
||||
SECTION ANSWER
|
||||
SECTION AUTHORITY
|
||||
example.com. 3600 IN SOA a. b. 1 2 3 4 5
|
||||
example.com. 3600 IN NS ns.example.com.
|
||||
example.com. 1800 IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. 3600 IN A 1.2.3.4
|
||||
ns.example.com. 1800 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; after another 1900 seconds the domain must have timed out.
|
||||
|
||||
Vendored
+1
-1
@@ -238,7 +238,7 @@ RANGE_END
|
||||
; store bad timing for one server to influence server selection
|
||||
; 1.2.3.44 (ns.example.net) gets 900 msec.
|
||||
; so the 376 ns.example.com is preferred.
|
||||
STEP 1 INFRA_RTT 1.2.3.44 900
|
||||
STEP 1 INFRA_RTT 1.2.3.44 example.net. 900
|
||||
|
||||
STEP 10 QUERY
|
||||
ENTRY_BEGIN
|
||||
|
||||
Vendored
+364
@@ -0,0 +1,364 @@
|
||||
; config options
|
||||
server:
|
||||
target-fetch-policy: "0 0 0 0 0"
|
||||
prefetch: "yes"
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
|
||||
CONFIG_END
|
||||
|
||||
SCENARIO_BEGIN Test resolver prefetch and a moved domain
|
||||
; for bug #425.
|
||||
|
||||
; K.ROOT-SERVERS.NET.
|
||||
RANGE_BEGIN 0 500
|
||||
ADDRESS 193.0.14.129
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
. IN NS
|
||||
SECTION ANSWER
|
||||
. IN NS K.ROOT-SERVERS.NET.
|
||||
SECTION ADDITIONAL
|
||||
K.ROOT-SERVERS.NET. IN A 193.0.14.129
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode subdomain
|
||||
ADJUST copy_id copy_query
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
com. IN A
|
||||
SECTION AUTHORITY
|
||||
com. IN NS a.gtld-servers.net.
|
||||
SECTION ADDITIONAL
|
||||
a.gtld-servers.net. IN A 192.5.6.30
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; a.gtld-servers.net. (before sale of domain)
|
||||
RANGE_BEGIN 0 30
|
||||
ADDRESS 192.5.6.30
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
com. IN NS
|
||||
SECTION ANSWER
|
||||
com. IN NS a.gtld-servers.net.
|
||||
SECTION ADDITIONAL
|
||||
a.gtld-servers.net. IN A 192.5.6.30
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode subdomain
|
||||
ADJUST copy_id copy_query
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION AUTHORITY
|
||||
example.com. 86400 IN NS old-ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
old-ns.example.com. 86400 IN A 192.168.0.1
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; a.gtld-servers.net. (after sale of domain)
|
||||
RANGE_BEGIN 40 500
|
||||
ADDRESS 192.5.6.30
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
com. IN NS
|
||||
SECTION ANSWER
|
||||
com. IN NS a.gtld-servers.net.
|
||||
SECTION ADDITIONAL
|
||||
a.gtld-servers.net. IN A 192.5.6.30
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode subdomain
|
||||
ADJUST copy_id copy_query
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION AUTHORITY
|
||||
example.com. 86400 IN NS new-ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
new-ns.example.com. 86400 IN A 172.16.0.1
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; ns.example.com. first owner
|
||||
RANGE_BEGIN 0 500
|
||||
ADDRESS 192.168.0.1
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN NS
|
||||
SECTION ANSWER
|
||||
example.com. 86400 IN NS old-ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
old-ns.example.com. 86400 IN A 192.168.0.1
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 3600 IN A 10.1.1.1
|
||||
SECTION AUTHORITY
|
||||
example.com. 86400 IN NS old-ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
old-ns.example.com. 86400 IN A 192.168.0.1
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; ns.example.com. new owner
|
||||
RANGE_BEGIN 0 500
|
||||
ADDRESS 172.16.0.1
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN NS
|
||||
SECTION ANSWER
|
||||
example.com. 86400 IN NS new-ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
new-ns.example.com. 86400 IN A 172.16.0.1
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
old-ns.example.com. IN A
|
||||
SECTION ANSWER
|
||||
old-ns.example.com. 86400 IN A 172.16.0.1
|
||||
SECTION AUTHORITY
|
||||
example.com. 86400 IN NS new-ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
new-ns.example.com. 86400 IN A 172.16.0.1
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 3600 IN A 10.2.2.2
|
||||
SECTION AUTHORITY
|
||||
example.com. 86400 IN NS new-ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
new-ns.example.com. 86400 IN A 172.16.0.1
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
STEP 1 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 3600 IN A 10.1.1.1
|
||||
SECTION AUTHORITY
|
||||
example.com. 86400 IN NS old-ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
old-ns.example.com. 86400 IN A 192.168.0.1
|
||||
ENTRY_END
|
||||
|
||||
; after 1800 secs still the cached answer
|
||||
STEP 20 TIME_PASSES ELAPSE 1800
|
||||
|
||||
STEP 30 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 40 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 1800 IN A 10.1.1.1
|
||||
SECTION AUTHORITY
|
||||
example.com. 84600 IN NS old-ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
old-ns.example.com. 84600 IN A 192.168.0.1
|
||||
ENTRY_END
|
||||
|
||||
; after 1440 we are 360 seconds before the expiry
|
||||
; but it still contacts the old-ns
|
||||
STEP 50 TIME_PASSES ELAPSE 1440
|
||||
|
||||
STEP 60 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 70 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 360 IN A 10.1.1.1
|
||||
SECTION AUTHORITY
|
||||
example.com. 83160 IN NS old-ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
old-ns.example.com. 83160 IN A 192.168.0.1
|
||||
ENTRY_END
|
||||
|
||||
STEP 80 TRAFFIC
|
||||
; let traffic flow for prefetch to happen
|
||||
|
||||
; we updated from the old-ns.
|
||||
STEP 90 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 100 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 3600 IN A 10.1.1.1
|
||||
SECTION AUTHORITY
|
||||
example.com. 83160 IN NS old-ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
old-ns.example.com. 83160 IN A 192.168.0.1
|
||||
ENTRY_END
|
||||
|
||||
; the NS record is now 10% from expiry (8640 TTL left).
|
||||
; and the A record has expired completely, retry.
|
||||
STEP 110 TIME_PASSES ELAPSE 74520
|
||||
|
||||
; the NS record should have timed out.
|
||||
; but you see the full TTL here, this is only for *this query*
|
||||
; in the cache itself its 8640, not 86400.
|
||||
STEP 120 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 130 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 3600 IN A 10.1.1.1
|
||||
SECTION AUTHORITY
|
||||
example.com. 8640 IN NS old-ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
old-ns.example.com. 8640 IN A 192.168.0.1
|
||||
ENTRY_END
|
||||
|
||||
; get it from cache
|
||||
STEP 140 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 150 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 3600 IN A 10.1.1.1
|
||||
SECTION AUTHORITY
|
||||
example.com. 8640 IN NS old-ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
old-ns.example.com. 8640 IN A 192.168.0.1
|
||||
ENTRY_END
|
||||
|
||||
; the NS record times out after 8640 seconds.
|
||||
STEP 160 TIME_PASSES ELAPSE 8641
|
||||
|
||||
; fetch it
|
||||
STEP 170 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 180 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 3600 IN A 10.2.2.2
|
||||
SECTION AUTHORITY
|
||||
example.com. 86400 IN NS new-ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
new-ns.example.com. 86400 IN A 172.16.0.1
|
||||
ENTRY_END
|
||||
|
||||
; a reply from cache
|
||||
STEP 190 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 200 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 3600 IN A 10.2.2.2
|
||||
SECTION AUTHORITY
|
||||
example.com. 86400 IN NS new-ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
new-ns.example.com. 86400 IN A 172.16.0.1
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
Vendored
+2
-2
@@ -285,9 +285,9 @@ www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 3600 IN A 88.88.88.88
|
||||
SECTION AUTHORITY
|
||||
example.com. 3600 IN NS ns.example.com.
|
||||
example.com. 1240 IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. 3600 IN A 8.8.8.8
|
||||
ns.example.com. 820 IN A 8.8.8.8
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
|
||||
Vendored
BIN
Binary file not shown.
Vendored
+1
-1
@@ -85,7 +85,7 @@ ENTRY_BEGIN
|
||||
SECTION ANSWER
|
||||
bla.example.com. IN A 10.20.30.140
|
||||
SECTION AUTHORITY
|
||||
example.com. 200 IN NS ns.example.com.
|
||||
example.com. 100 IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 10.20.30.50
|
||||
ENTRY_END
|
||||
|
||||
Vendored
BIN
Binary file not shown.
Vendored
+23
@@ -0,0 +1,23 @@
|
||||
; Test that RRSIG(SOA) is matched with the SOA record.
|
||||
; Test that FORMERR no longer happens.
|
||||
; This is output from the PowerDNS online signer.
|
||||
;
|
||||
;-- next packet --
|
||||
E2C084000001000000040
|
||||
0010E686F74656C6C73616E746961676F02736500000F0001C00C0006000100000E10002C036E733
|
||||
30662696E65726FC01B087265676973747279C0334EDFD75C0000A8C000000E1000093A8000000E1
|
||||
02075616D326963717673707635356136746A306C6C32336B71376E766D666E6136C00C003200010
|
||||
0001C2000240100000101AB14D7425114B28CE784C3A3D9B8FC5D920A8D7B5570000762000000000
|
||||
290C00C002E000100001C2000A50006080200001C204EE938804ED6C38085F80E686F74656C6C736
|
||||
16E746961676F02736500442DF70F92FCFDF5F5D3560194FCDE01B91CE6AC00910CDDA550F985C84
|
||||
F4FA1FD8DFD
|
||||
957F4382C276FD26E5A
|
||||
3C10C494DCB6D0132F930595A0901D4E0616679EA426F7D45A683CA7236F8532C1E3B3B82EF6B0C0
|
||||
2E43999F8B8FF0B001968E10AFAEFA7774FC003ED0E43DDEA776596AFD91DADECA5AD505107F97AC
|
||||
467264EC05B002E000100001C2000A50032080300001C204EE938804ED6C38085F80E686F74656C6
|
||||
C73616E746961676F027365000D4700DE3055046F2CC0529307903D40FEFC7ECFF29BB5B6B7427EB
|
||||
11B06669605B1ADFC070DAF801FB3EB59446F6C7BE5D4BC7C725BFEF2F5F416BCC8A090692F5CE76
|
||||
85923DD102677C9224E69FF10167EF8C0EC18070E986E9F0266C7CBB3270A9CD6C562157EC1074B6
|
||||
F48553DD58BBE
|
||||
12A63202C9A1DB7DA5F8560849580000295800000080000000
|
||||
|
||||
Vendored
+278
@@ -0,0 +1,278 @@
|
||||
; config options
|
||||
; The island of trust is at example.com
|
||||
server:
|
||||
trust-anchor: "example.com. 3600 IN DS 2854 3 1 46e4ffc6e9a4793b488954bd3f0cc6af0dfb201b"
|
||||
val-override-date: "20070916134226"
|
||||
target-fetch-policy: "0 0 0 0 0"
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
|
||||
CONFIG_END
|
||||
|
||||
SCENARIO_BEGIN Test validator with NSEC3 span change and cache effects.
|
||||
|
||||
; K.ROOT-SERVERS.NET.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 193.0.14.129
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
. IN NS
|
||||
SECTION ANSWER
|
||||
. IN NS K.ROOT-SERVERS.NET.
|
||||
SECTION ADDITIONAL
|
||||
K.ROOT-SERVERS.NET. IN A 193.0.14.129
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode subdomain
|
||||
ADJUST copy_id copy_query
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
com. IN A
|
||||
SECTION AUTHORITY
|
||||
com. IN NS a.gtld-servers.net.
|
||||
SECTION ADDITIONAL
|
||||
a.gtld-servers.net. IN A 192.5.6.30
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; a.gtld-servers.net.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 192.5.6.30
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
com. IN NS
|
||||
SECTION ANSWER
|
||||
com. IN NS a.gtld-servers.net.
|
||||
SECTION ADDITIONAL
|
||||
a.gtld-servers.net. IN A 192.5.6.30
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode subdomain
|
||||
ADJUST copy_id copy_query
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; ns.example.com.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 1.2.3.4
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN NS
|
||||
SECTION ANSWER
|
||||
example.com. IN NS ns.example.com.
|
||||
example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
ns.example.com. IN AAAA
|
||||
SECTION ANSWER
|
||||
; blacklisted address to stop it from using it, the negative answer uses its
|
||||
; nsec3-hash which is alittle inconvenient
|
||||
; ns.example.com. -> 7l9dbddmge35f7vr9mec78dqr6l3236k.
|
||||
ns.example.com. IN AAAA ::1
|
||||
ns.example.com. 3600 IN RRSIG AAAA 3 3 3600 20070926135752 20070829135752 2854 example.com. AExGBc6JU/xwwoSIeK/DtX8kr7AgOecx5Z2FnRiz/YSpnWGnFDt26ec=
|
||||
ENTRY_END
|
||||
|
||||
; response to DNSKEY priming query
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN DNSKEY
|
||||
SECTION ANSWER
|
||||
example.com. 3600 IN DNSKEY 256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
|
||||
example.com. 3600 IN RRSIG DNSKEY 3 2 3600 20070926134802 20070829134802 2854 example.com. MCwCFG1yhRNtTEa3Eno2zhVVuy2EJX3wAhQeLyUp6+UXcpC5qGNu9tkrTEgPUg== ;{id = 2854}
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
|
||||
ENTRY_END
|
||||
|
||||
; DS query
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qname qtype
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
sub.example.com. IN DS
|
||||
SECTION AUTHORITY
|
||||
example.com. IN SOA a. b. 1 2 3 4 5
|
||||
example.com. 3600 IN RRSIG SOA 3 2 3600 20070926135752 20070829135752 2854 example.com. AAkQt1yoMF7s4gCYlojFzi0ubw6Uo4uWPSJTz6Dp/2iWUVDbxDKpy+E=
|
||||
|
||||
; sub.example.com. -> 8r1f0ieoutlnjc03meng9e3bn2n0o9pd.
|
||||
; example.com. -> b6fuorg741ufili49mg9j4328ig53sqg.
|
||||
; proof that there is no DS here.
|
||||
; ce:
|
||||
b6fuorg741ufili49mg9j4328ig53sqg.example.com. IN NSEC3 1 1 123 aabb00123456bbccdd b6fuorg741ufili49mg9j4328ig53sqh NS SOA DNSKEY NSEC3PARAM RRSIG
|
||||
b6fuorg741ufili49mg9j4328ig53sqg.example.com. 3600 IN RRSIG NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. AKHQ0gnNP5WDab1yqbd+Bt12CSSff88sqeDR40dvhiWOcYA8mmyjYNA=
|
||||
|
||||
; span around sub.example.com., same span as foo.example.com, but it has
|
||||
; just changed and it is now larger to accomodate sub.example.com.
|
||||
6obgmo062d9935unjnnj2su5otaj9334.example.com. IN NSEC3 1 1 123 aabb00123456bbccdd 9r1f0ieoutlnjc03meng9e3bn2n0o9pd NS DS RRSIG
|
||||
6obgmo062d9935unjnnj2su5otaj9334.example.com. 3600 IN RRSIG NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. ABzruSKUUcJRNlYDqZ4UmQH/WnzeXt9Gozp3chS4cR0sqsEeGjL54eQ=
|
||||
|
||||
; span around sub.example.com. from previous delegation in nsec3-chain
|
||||
;7r1f0ieoutlnjc03meng9e3bn2n0o9pd.example.com. IN NSEC3 1 1 123 aabb00123456bbccdd 9r1f0ieoutlnjc03meng9e3bn2n0o9pd NS DS RRSIG
|
||||
;7r1f0ieoutlnjc03meng9e3bn2n0o9pd.example.com. 3600 IN RRSIG NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. AF2FOKiIfOV9KrDTuP4RwnDI6lZnmhRHE+HAh8UHEq87uakYUEHfGUY=
|
||||
ENTRY_END
|
||||
|
||||
; refer to server one down
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode subdomain
|
||||
ADJUST copy_id copy_query
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
sub.example.com. IN A
|
||||
SECTION AUTHORITY
|
||||
sub.example.com. IN NS ns.sub.example.com.
|
||||
; sub.example.com. -> 8r1f0ieoutlnjc03meng9e3bn2n0o9pd.
|
||||
; example.com. -> b6fuorg741ufili49mg9j4328ig53sqg.
|
||||
; proof that there is no DS here.
|
||||
; ce:
|
||||
b6fuorg741ufili49mg9j4328ig53sqg.example.com. IN NSEC3 1 1 123 aabb00123456bbccdd b6fuorg741ufili49mg9j4328ig53sqh NS SOA DNSKEY NSEC3PARAM RRSIG
|
||||
b6fuorg741ufili49mg9j4328ig53sqg.example.com. 3600 IN RRSIG NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. AKHQ0gnNP5WDab1yqbd+Bt12CSSff88sqeDR40dvhiWOcYA8mmyjYNA=
|
||||
|
||||
; span around sub.example.com., same span as foo.example.com, but it has
|
||||
; just changed and it is now larger to accomodate sub.example.com.
|
||||
6obgmo062d9935unjnnj2su5otaj9334.example.com. IN NSEC3 1 1 123 aabb00123456bbccdd 9r1f0ieoutlnjc03meng9e3bn2n0o9pd NS DS RRSIG
|
||||
6obgmo062d9935unjnnj2su5otaj9334.example.com. 3600 IN RRSIG NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. ABzruSKUUcJRNlYDqZ4UmQH/WnzeXt9Gozp3chS4cR0sqsEeGjL54eQ=
|
||||
|
||||
; span around sub.example.com. from previous delegation in nsec3-chain
|
||||
;7r1f0ieoutlnjc03meng9e3bn2n0o9pd.example.com. IN NSEC3 1 1 123 aabb00123456bbccdd 9r1f0ieoutlnjc03meng9e3bn2n0o9pd NS DS RRSIG
|
||||
;7r1f0ieoutlnjc03meng9e3bn2n0o9pd.example.com. 3600 IN RRSIG NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. AF2FOKiIfOV9KrDTuP4RwnDI6lZnmhRHE+HAh8UHEq87uakYUEHfGUY=
|
||||
|
||||
SECTION ADDITIONAL
|
||||
ns.sub.example.com. IN A 1.2.3.10
|
||||
ENTRY_END
|
||||
|
||||
; refer to server one down
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode subdomain
|
||||
ADJUST copy_id copy_query
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
foo.example.com. IN A
|
||||
SECTION AUTHORITY
|
||||
foo.example.com. IN NS ns.sub.example.com.
|
||||
; sub.example.com. -> 8r1f0ieoutlnjc03meng9e3bn2n0o9pd.
|
||||
; foo.example.com. -> 7obgmo062d9935unjnnj2su5otaj9334.
|
||||
; example.com. -> b6fuorg741ufili49mg9j4328ig53sqg.
|
||||
; proof that there is no DS here.
|
||||
; ce:
|
||||
b6fuorg741ufili49mg9j4328ig53sqg.example.com. IN NSEC3 1 1 123 aabb00123456bbccdd b6fuorg741ufili49mg9j4328ig53sqh NS SOA DNSKEY NSEC3PARAM RRSIG
|
||||
b6fuorg741ufili49mg9j4328ig53sqg.example.com. 3600 IN RRSIG NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. AKHQ0gnNP5WDab1yqbd+Bt12CSSff88sqeDR40dvhiWOcYA8mmyjYNA=
|
||||
|
||||
; span around sub.example.com. from previous delegation in nsec3-chain
|
||||
; note it does not cover sub.example.com.
|
||||
6obgmo062d9935unjnnj2su5otaj9334.example.com. IN NSEC3 1 1 123 aabb00123456bbccdd 7r1f0ieoutlnjc03meng9e3bn2n0o9pd NS DS RRSIG
|
||||
6obgmo062d9935unjnnj2su5otaj9334.example.com. 3600 IN RRSIG NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. ABQZ49PmeXGxUmMebbKcYI/Y3mhMdlHmshohKTbGhEsNF11OjPYmr9c=
|
||||
|
||||
SECTION ADDITIONAL
|
||||
ns.sub.example.com. IN A 1.2.3.10
|
||||
ENTRY_END
|
||||
|
||||
RANGE_END
|
||||
|
||||
; ns.sub.example.com.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 1.2.3.10
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR REFUSED
|
||||
SECTION QUESTION
|
||||
sub.example.com. IN NS
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
www.sub.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.sub.example.com. IN A 1.2.3.123
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
www.foo.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.foo.example.com. IN A 1.2.3.124
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
STEP 1 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
www.foo.example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
www.foo.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.foo.example.com. IN A 1.2.3.124
|
||||
SECTION AUTHORITY
|
||||
SECTION ADDITIONAL
|
||||
ENTRY_END
|
||||
|
||||
STEP 20 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
www.sub.example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
; recursion happens here.
|
||||
STEP 30 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
www.sub.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.sub.example.com. IN A 1.2.3.123
|
||||
SECTION AUTHORITY
|
||||
SECTION ADDITIONAL
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
+2
-2
@@ -177,8 +177,8 @@ void alloc_set_id_cleanup(struct alloc_cache* alloc, void (*cleanup)(void*),
|
||||
void* arg);
|
||||
|
||||
#ifdef UNBOUND_ALLOC_LITE
|
||||
# include "ldns/packet.h"
|
||||
# include "openssl/ssl.h"
|
||||
# include <ldns/packet.h>
|
||||
# include <openssl/ssl.h>
|
||||
# define malloc(s) unbound_stat_malloc_lite(s, __FILE__, __LINE__, __func__)
|
||||
# define calloc(n,s) unbound_stat_calloc_lite(n, s, __FILE__, __LINE__, __func__)
|
||||
# define free(p) unbound_stat_free_lite(p, __FILE__, __LINE__, __func__)
|
||||
|
||||
+26
-8
@@ -41,7 +41,7 @@
|
||||
|
||||
#include "config.h"
|
||||
#include <ctype.h>
|
||||
#include "ldns/ldns.h"
|
||||
#include <ldns/ldns.h>
|
||||
#include "util/log.h"
|
||||
|
||||
#include "util/configyyrename.h"
|
||||
@@ -88,6 +88,10 @@ config_create(void)
|
||||
cfg->do_udp = 1;
|
||||
cfg->do_tcp = 1;
|
||||
cfg->tcp_upstream = 0;
|
||||
cfg->ssl_service_key = NULL;
|
||||
cfg->ssl_service_pem = NULL;
|
||||
cfg->ssl_port = 443;
|
||||
cfg->ssl_upstream = 0;
|
||||
cfg->use_syslog = 1;
|
||||
cfg->log_time_ascii = 0;
|
||||
cfg->log_queries = 0;
|
||||
@@ -117,7 +121,6 @@ config_create(void)
|
||||
cfg->rrset_cache_size = 4 * 1024 * 1024;
|
||||
cfg->rrset_cache_slabs = 4;
|
||||
cfg->host_ttl = 900;
|
||||
cfg->lame_ttl = 900;
|
||||
cfg->bogus_ttl = 60;
|
||||
cfg->min_ttl = 0;
|
||||
cfg->max_ttl = 3600 * 24;
|
||||
@@ -125,7 +128,6 @@ config_create(void)
|
||||
cfg->prefetch_key = 0;
|
||||
cfg->infra_cache_slabs = 4;
|
||||
cfg->infra_cache_numhosts = 10000;
|
||||
cfg->infra_cache_lame_size = 10240; /* easily 40 or more entries */
|
||||
if(!(cfg->outgoing_avail_ports = (int*)calloc(65536, sizeof(int))))
|
||||
goto error_exit;
|
||||
init_outgoing_availports(cfg->outgoing_avail_ports, 65536);
|
||||
@@ -328,6 +330,10 @@ int config_set_option(struct config_file* cfg, const char* opt,
|
||||
else S_YNO("do-udp:", do_udp)
|
||||
else S_YNO("do-tcp:", do_tcp)
|
||||
else S_YNO("tcp-upstream:", tcp_upstream)
|
||||
else S_YNO("ssl-upstream:", ssl_upstream)
|
||||
else S_STR("ssl-service-key:", ssl_service_key)
|
||||
else S_STR("ssl-service-pem:", ssl_service_pem)
|
||||
else S_NUMBER_NONZERO("ssl-port:", ssl_port)
|
||||
else S_YNO("interface-automatic:", if_automatic)
|
||||
else S_YNO("do-daemonize:", do_daemonize)
|
||||
else S_NUMBER_NONZERO("port:", port)
|
||||
@@ -348,10 +354,8 @@ int config_set_option(struct config_file* cfg, const char* opt,
|
||||
else S_YNO("prefetch-key:", prefetch_key)
|
||||
else S_NUMBER_OR_ZERO("cache-max-ttl:", max_ttl)
|
||||
else S_NUMBER_OR_ZERO("infra-host-ttl:", host_ttl)
|
||||
else S_NUMBER_OR_ZERO("infra-lame-ttl:", lame_ttl)
|
||||
else S_POW2("infra-cache-slabs:", infra_cache_slabs)
|
||||
else S_SIZET_NONZERO("infra-cache-numhosts:", infra_cache_numhosts)
|
||||
else S_MEMSIZE("infra-cache-lame-size:", infra_cache_lame_size)
|
||||
else S_STR("chroot:", chrootdir)
|
||||
else S_STR("username:", username)
|
||||
else S_STR("directory:", directory)
|
||||
@@ -405,7 +409,17 @@ int config_set_option(struct config_file* cfg, const char* opt,
|
||||
else S_STR("control-cert-file:", control_cert_file)
|
||||
else S_STR("module-config:", module_conf)
|
||||
else S_STR("python-script:", python_script)
|
||||
else {
|
||||
else if (strcmp(opt, "outgoing-interface:") == 0) {
|
||||
char* d = strdup(val);
|
||||
char** oi = (char**)malloc((cfg->num_out_ifs+1)*sizeof(char*));
|
||||
if(!d || !oi) { free(d); free(oi); return -1; }
|
||||
if(cfg->out_ifs && cfg->num_out_ifs) {
|
||||
memmove(oi, cfg->out_ifs, cfg->num_out_ifs*sizeof(char*));
|
||||
free(cfg->out_ifs);
|
||||
}
|
||||
oi[cfg->num_out_ifs++] = d;
|
||||
cfg->out_ifs = oi;
|
||||
} else {
|
||||
/* unknown or unsupported (from the set_option interface):
|
||||
* interface, outgoing-interface, access-control,
|
||||
* stub-zone, name, stub-addr, stub-host, stub-prime
|
||||
@@ -571,15 +585,17 @@ config_get_option(struct config_file* cfg, const char* opt,
|
||||
else O_YNO(opt, "prefetch", prefetch)
|
||||
else O_DEC(opt, "cache-max-ttl", max_ttl)
|
||||
else O_DEC(opt, "infra-host-ttl", host_ttl)
|
||||
else O_DEC(opt, "infra-lame-ttl", lame_ttl)
|
||||
else O_DEC(opt, "infra-cache-slabs", infra_cache_slabs)
|
||||
else O_MEM(opt, "infra-cache-numhosts", infra_cache_numhosts)
|
||||
else O_MEM(opt, "infra-cache-lame-size", infra_cache_lame_size)
|
||||
else O_YNO(opt, "do-ip4", do_ip4)
|
||||
else O_YNO(opt, "do-ip6", do_ip6)
|
||||
else O_YNO(opt, "do-udp", do_udp)
|
||||
else O_YNO(opt, "do-tcp", do_tcp)
|
||||
else O_YNO(opt, "tcp-upstream", tcp_upstream)
|
||||
else O_YNO(opt, "ssl-upstream", ssl_upstream)
|
||||
else O_STR(opt, "ssl-service-key", ssl_service_key)
|
||||
else O_STR(opt, "ssl-service-pem", ssl_service_pem)
|
||||
else O_DEC(opt, "ssl-port", ssl_port)
|
||||
else O_YNO(opt, "do-daemonize", do_daemonize)
|
||||
else O_STR(opt, "chroot", chrootdir)
|
||||
else O_STR(opt, "username", username)
|
||||
@@ -734,6 +750,8 @@ config_delete(struct config_file* cfg)
|
||||
free(cfg->logfile);
|
||||
free(cfg->pidfile);
|
||||
free(cfg->target_fetch_policy);
|
||||
free(cfg->ssl_service_key);
|
||||
free(cfg->ssl_service_pem);
|
||||
if(cfg->ifs) {
|
||||
int i;
|
||||
for(i=0; i<cfg->num_ifs; i++)
|
||||
|
||||
+9
-4
@@ -79,6 +79,15 @@ struct config_file {
|
||||
/** tcp upstream queries (no UDP upstream queries) */
|
||||
int tcp_upstream;
|
||||
|
||||
/** private key file for dnstcp-ssl service (enabled if not NULL) */
|
||||
char* ssl_service_key;
|
||||
/** public key file for dnstcp-ssl service */
|
||||
char* ssl_service_pem;
|
||||
/** port on which to provide ssl service */
|
||||
int ssl_port;
|
||||
/** if outgoing tcp connections use SSL */
|
||||
int ssl_upstream;
|
||||
|
||||
/** outgoing port range number of ports (per thread) */
|
||||
int outgoing_num_ports;
|
||||
/** number of outgoing tcp buffers per (per thread) */
|
||||
@@ -106,14 +115,10 @@ struct config_file {
|
||||
size_t rrset_cache_slabs;
|
||||
/** host cache ttl in seconds */
|
||||
int host_ttl;
|
||||
/** host is lame for a zone ttl, in seconds */
|
||||
int lame_ttl;
|
||||
/** number of slabs in the infra host cache */
|
||||
size_t infra_cache_slabs;
|
||||
/** max number of hosts in the infra cache */
|
||||
size_t infra_cache_numhosts;
|
||||
/** max size of lame zones per host in the infra cache */
|
||||
size_t infra_cache_lame_size;
|
||||
|
||||
/** the target fetch policy for the iterator */
|
||||
char* target_fetch_policy;
|
||||
|
||||
+1210
-1163
File diff suppressed because it is too large
Load Diff
@@ -137,6 +137,10 @@ do-ip6{COLON} { YDVAR(1, VAR_DO_IP6) }
|
||||
do-udp{COLON} { YDVAR(1, VAR_DO_UDP) }
|
||||
do-tcp{COLON} { YDVAR(1, VAR_DO_TCP) }
|
||||
tcp-upstream{COLON} { YDVAR(1, VAR_TCP_UPSTREAM) }
|
||||
ssl-upstream{COLON} { YDVAR(1, VAR_SSL_UPSTREAM) }
|
||||
ssl-service-key{COLON} { YDVAR(1, VAR_SSL_SERVICE_KEY) }
|
||||
ssl-service-pem{COLON} { YDVAR(1, VAR_SSL_SERVICE_PEM) }
|
||||
ssl-port{COLON} { YDVAR(1, VAR_SSL_PORT) }
|
||||
do-daemonize{COLON} { YDVAR(1, VAR_DO_DAEMONIZE) }
|
||||
interface{COLON} { YDVAR(1, VAR_INTERFACE) }
|
||||
outgoing-interface{COLON} { YDVAR(1, VAR_OUTGOING_INTERFACE) }
|
||||
|
||||
+517
-450
File diff suppressed because it is too large
Load Diff
+10
-2
@@ -156,7 +156,11 @@
|
||||
VAR_HARDEN_BELOW_NXDOMAIN = 373,
|
||||
VAR_IGNORE_CD_FLAG = 374,
|
||||
VAR_LOG_QUERIES = 375,
|
||||
VAR_TCP_UPSTREAM = 376
|
||||
VAR_TCP_UPSTREAM = 376,
|
||||
VAR_SSL_UPSTREAM = 377,
|
||||
VAR_SSL_SERVICE_KEY = 378,
|
||||
VAR_SSL_SERVICE_PEM = 379,
|
||||
VAR_SSL_PORT = 380
|
||||
};
|
||||
#endif
|
||||
/* Tokens. */
|
||||
@@ -279,6 +283,10 @@
|
||||
#define VAR_IGNORE_CD_FLAG 374
|
||||
#define VAR_LOG_QUERIES 375
|
||||
#define VAR_TCP_UPSTREAM 376
|
||||
#define VAR_SSL_UPSTREAM 377
|
||||
#define VAR_SSL_SERVICE_KEY 378
|
||||
#define VAR_SSL_SERVICE_PEM 379
|
||||
#define VAR_SSL_PORT 380
|
||||
|
||||
|
||||
|
||||
@@ -295,7 +303,7 @@ typedef union YYSTYPE
|
||||
|
||||
|
||||
/* Line 1685 of yacc.c */
|
||||
#line 299 "util/configparser.h"
|
||||
#line 307 "util/configparser.h"
|
||||
} YYSTYPE;
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
||||
|
||||
+40
-8
@@ -102,7 +102,8 @@ extern struct config_parser_state* cfg_parser;
|
||||
%token VAR_AUTO_TRUST_ANCHOR_FILE VAR_KEEP_MISSING VAR_ADD_HOLDDOWN
|
||||
%token VAR_DEL_HOLDDOWN VAR_SO_RCVBUF VAR_EDNS_BUFFER_SIZE VAR_PREFETCH
|
||||
%token VAR_PREFETCH_KEY VAR_SO_SNDBUF VAR_HARDEN_BELOW_NXDOMAIN
|
||||
%token VAR_IGNORE_CD_FLAG VAR_LOG_QUERIES VAR_TCP_UPSTREAM
|
||||
%token VAR_IGNORE_CD_FLAG VAR_LOG_QUERIES VAR_TCP_UPSTREAM VAR_SSL_UPSTREAM
|
||||
%token VAR_SSL_SERVICE_KEY VAR_SSL_SERVICE_PEM VAR_SSL_PORT
|
||||
|
||||
%%
|
||||
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
|
||||
@@ -157,7 +158,8 @@ content_server: server_num_threads | server_verbosity | server_port |
|
||||
server_del_holddown | server_keep_missing | server_so_rcvbuf |
|
||||
server_edns_buffer_size | server_prefetch | server_prefetch_key |
|
||||
server_so_sndbuf | server_harden_below_nxdomain | server_ignore_cd_flag |
|
||||
server_log_queries | server_tcp_upstream
|
||||
server_log_queries | server_tcp_upstream | server_ssl_upstream |
|
||||
server_ssl_service_key | server_ssl_service_pem | server_ssl_port
|
||||
;
|
||||
stubstart: VAR_STUB_ZONE
|
||||
{
|
||||
@@ -374,6 +376,38 @@ server_tcp_upstream: VAR_TCP_UPSTREAM STRING_ARG
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
server_ssl_upstream: VAR_SSL_UPSTREAM STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_ssl_upstream:%s)\n", $2));
|
||||
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
|
||||
yyerror("expected yes or no.");
|
||||
else cfg_parser->cfg->ssl_upstream = (strcmp($2, "yes")==0);
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
server_ssl_service_key: VAR_SSL_SERVICE_KEY STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_ssl_service_key:%s)\n", $2));
|
||||
free(cfg_parser->cfg->ssl_service_key);
|
||||
cfg_parser->cfg->ssl_service_key = $2;
|
||||
}
|
||||
;
|
||||
server_ssl_service_pem: VAR_SSL_SERVICE_PEM STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_ssl_service_pem:%s)\n", $2));
|
||||
free(cfg_parser->cfg->ssl_service_pem);
|
||||
cfg_parser->cfg->ssl_service_pem = $2;
|
||||
}
|
||||
;
|
||||
server_ssl_port: VAR_SSL_PORT STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_ssl_port:%s)\n", $2));
|
||||
if(atoi($2) == 0)
|
||||
yyerror("port number expected");
|
||||
else cfg_parser->cfg->ssl_port = atoi($2);
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
server_do_daemonize: VAR_DO_DAEMONIZE STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_do_daemonize:%s)\n", $2));
|
||||
@@ -654,9 +688,8 @@ server_infra_host_ttl: VAR_INFRA_HOST_TTL STRING_ARG
|
||||
server_infra_lame_ttl: VAR_INFRA_LAME_TTL STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_infra_lame_ttl:%s)\n", $2));
|
||||
if(atoi($2) == 0 && strcmp($2, "0") != 0)
|
||||
yyerror("number expected");
|
||||
else cfg_parser->cfg->lame_ttl = atoi($2);
|
||||
verbose(VERB_DETAIL, "ignored infra-lame-ttl: %s (option "
|
||||
"removed, use infra-host-ttl)", $2);
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
@@ -672,9 +705,8 @@ server_infra_cache_numhosts: VAR_INFRA_CACHE_NUMHOSTS STRING_ARG
|
||||
server_infra_cache_lame_size: VAR_INFRA_CACHE_LAME_SIZE STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_infra_cache_lame_size:%s)\n", $2));
|
||||
if(!cfg_parse_memsize($2, &cfg_parser->cfg->
|
||||
infra_cache_lame_size))
|
||||
yyerror("number expected");
|
||||
verbose(VERB_DETAIL, "ignored infra-cache-lame-size: %s "
|
||||
"(option removed, use infra-cache-numhosts)", $2);
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "ldns/wire2host.h"
|
||||
#include <ldns/wire2host.h>
|
||||
#include "util/data/msgencode.h"
|
||||
#include "util/data/msgreply.h"
|
||||
#include "util/data/msgparse.h"
|
||||
|
||||
+12
-1
@@ -37,7 +37,7 @@
|
||||
* Routines for message parsing a packet buffer to a descriptive structure.
|
||||
*/
|
||||
#include "config.h"
|
||||
#include "ldns/ldns.h"
|
||||
#include <ldns/ldns.h>
|
||||
#include "util/data/msgparse.h"
|
||||
#include "util/net_help.h"
|
||||
#include "util/data/dname.h"
|
||||
@@ -504,6 +504,17 @@ find_rrset(struct msg_parse* msg, ldns_buffer* pkt, uint8_t* dname,
|
||||
if(!*rrset_prev) /* untwiddle if not found */
|
||||
*rrset_flags ^= PACKED_RRSET_NSEC_AT_APEX;
|
||||
}
|
||||
if(!*rrset_prev && covtype == LDNS_RR_TYPE_SOA) {
|
||||
/* if SOA try with SOA neg flag twiddled */
|
||||
*rrset_flags ^= PACKED_RRSET_SOA_NEG;
|
||||
*hash = pkt_hash_rrset_rest(dname_h, covtype, dclass,
|
||||
*rrset_flags);
|
||||
*rrset_prev = msgparse_hashtable_lookup(msg, pkt,
|
||||
*hash, *rrset_flags, dname, dnamelen, covtype,
|
||||
dclass);
|
||||
if(!*rrset_prev) /* untwiddle if not found */
|
||||
*rrset_flags ^= PACKED_RRSET_SOA_NEG;
|
||||
}
|
||||
if(*rrset_prev) {
|
||||
*prev_dname_first = (*rrset_prev)->dname;
|
||||
*prev_dname_last = dname;
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
#ifndef UTIL_DATA_MSGPARSE_H
|
||||
#define UTIL_DATA_MSGPARSE_H
|
||||
#include "util/storage/lruhash.h"
|
||||
#include "ldns/packet.h"
|
||||
#include <ldns/packet.h>
|
||||
struct rrset_parse;
|
||||
struct rr_parse;
|
||||
struct regional;
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "ldns/ldns.h"
|
||||
#include <ldns/ldns.h>
|
||||
#include "util/data/msgreply.h"
|
||||
#include "util/storage/lookup3.h"
|
||||
#include "util/log.h"
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "ldns/wire2host.h"
|
||||
#include <ldns/wire2host.h>
|
||||
#include "util/data/packed_rrset.h"
|
||||
#include "util/data/dname.h"
|
||||
#include "util/storage/lookup3.h"
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
#ifndef UTIL_DATA_PACKED_RRSET_H
|
||||
#define UTIL_DATA_PACKED_RRSET_H
|
||||
#include "util/storage/lruhash.h"
|
||||
#include "ldns/rr.h"
|
||||
#include <ldns/rr.h>
|
||||
struct alloc_cache;
|
||||
struct regional;
|
||||
|
||||
|
||||
+5
-8
@@ -194,9 +194,8 @@ fptr_whitelist_hash_sizefunc(lruhash_sizefunc_t fptr)
|
||||
{
|
||||
if(fptr == &msgreply_sizefunc) return 1;
|
||||
else if(fptr == &ub_rrset_sizefunc) return 1;
|
||||
else if(fptr == &infra_host_sizefunc) return 1;
|
||||
else if(fptr == &infra_sizefunc) return 1;
|
||||
else if(fptr == &key_entry_sizefunc) return 1;
|
||||
else if(fptr == &infra_lame_sizefunc) return 1;
|
||||
else if(fptr == &test_slabhash_sizefunc) return 1;
|
||||
return 0;
|
||||
}
|
||||
@@ -206,9 +205,8 @@ fptr_whitelist_hash_compfunc(lruhash_compfunc_t fptr)
|
||||
{
|
||||
if(fptr == &query_info_compare) return 1;
|
||||
else if(fptr == &ub_rrset_compare) return 1;
|
||||
else if(fptr == &infra_host_compfunc) return 1;
|
||||
else if(fptr == &infra_compfunc) return 1;
|
||||
else if(fptr == &key_entry_compfunc) return 1;
|
||||
else if(fptr == &infra_lame_compfunc) return 1;
|
||||
else if(fptr == &test_slabhash_compfunc) return 1;
|
||||
return 0;
|
||||
}
|
||||
@@ -218,9 +216,8 @@ fptr_whitelist_hash_delkeyfunc(lruhash_delkeyfunc_t fptr)
|
||||
{
|
||||
if(fptr == &query_entry_delete) return 1;
|
||||
else if(fptr == &ub_rrset_key_delete) return 1;
|
||||
else if(fptr == &infra_host_delkeyfunc) return 1;
|
||||
else if(fptr == &infra_delkeyfunc) return 1;
|
||||
else if(fptr == &key_entry_delkeyfunc) return 1;
|
||||
else if(fptr == &infra_lame_delkeyfunc) return 1;
|
||||
else if(fptr == &test_slabhash_delkey) return 1;
|
||||
return 0;
|
||||
}
|
||||
@@ -230,9 +227,8 @@ fptr_whitelist_hash_deldatafunc(lruhash_deldatafunc_t fptr)
|
||||
{
|
||||
if(fptr == &reply_info_delete) return 1;
|
||||
else if(fptr == &rrset_data_delete) return 1;
|
||||
else if(fptr == &infra_host_deldatafunc) return 1;
|
||||
else if(fptr == &infra_deldatafunc) return 1;
|
||||
else if(fptr == &key_entry_deldatafunc) return 1;
|
||||
else if(fptr == &infra_lame_deldatafunc) return 1;
|
||||
else if(fptr == &test_slabhash_deldata) return 1;
|
||||
return 0;
|
||||
}
|
||||
@@ -251,6 +247,7 @@ fptr_whitelist_modenv_send_query(struct outbound_entry* (*fptr)(
|
||||
uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
|
||||
uint16_t flags, int dnssec, int want_dnssec,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
uint8_t* zone, size_t zonelen,
|
||||
struct module_qstate* q))
|
||||
{
|
||||
if(fptr == &worker_send_query) return 1;
|
||||
|
||||
@@ -64,11 +64,15 @@
|
||||
* Macro to perform an assertion check for fptr wlist checks.
|
||||
* Does not get disabled in optimize mode. Check adds security by layers.
|
||||
*/
|
||||
#if defined(EXPORT_ALL_SYMBOLS)
|
||||
#define fptr_ok(x) /* nothing, dll-exe memory layout on win disables it */
|
||||
#else
|
||||
#define fptr_ok(x) \
|
||||
do { if(!(x)) \
|
||||
fatal_exit("%s:%d: %s: pointer whitelist %s failed", \
|
||||
__FILE__, __LINE__, __func__, #x); \
|
||||
} while(0);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Check function pointer whitelist for comm_point callback values.
|
||||
@@ -193,6 +197,7 @@ int fptr_whitelist_modenv_send_query(struct outbound_entry* (*fptr)(
|
||||
uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
|
||||
uint16_t flags, int dnssec, int want_dnssec,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
uint8_t* zone, size_t zonelen,
|
||||
struct module_qstate* q));
|
||||
|
||||
/**
|
||||
|
||||
@@ -3763,6 +3763,8 @@
|
||||
4168,
|
||||
4169,
|
||||
4172,
|
||||
4173,
|
||||
4174,
|
||||
4177,
|
||||
4178,
|
||||
4179,
|
||||
@@ -4394,6 +4396,7 @@
|
||||
6320,
|
||||
6321,
|
||||
6322,
|
||||
6324,
|
||||
6343,
|
||||
6346,
|
||||
6347,
|
||||
@@ -4716,6 +4719,7 @@
|
||||
8199,
|
||||
8200,
|
||||
8201,
|
||||
8202,
|
||||
8204,
|
||||
8205,
|
||||
8206,
|
||||
@@ -4924,12 +4928,14 @@
|
||||
9899,
|
||||
9900,
|
||||
9901,
|
||||
9903,
|
||||
9909,
|
||||
9911,
|
||||
9950,
|
||||
9951,
|
||||
9952,
|
||||
9953,
|
||||
9956,
|
||||
9966,
|
||||
9987,
|
||||
9990,
|
||||
@@ -4960,6 +4966,7 @@
|
||||
10104,
|
||||
10107,
|
||||
10110,
|
||||
10111,
|
||||
10113,
|
||||
10114,
|
||||
10115,
|
||||
@@ -5082,6 +5089,7 @@
|
||||
16367,
|
||||
16368,
|
||||
16384,
|
||||
16666,
|
||||
16900,
|
||||
16950,
|
||||
16991,
|
||||
@@ -5092,6 +5100,8 @@
|
||||
17007,
|
||||
17185,
|
||||
17219,
|
||||
17221,
|
||||
17222,
|
||||
17234,
|
||||
17235,
|
||||
17500,
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@
|
||||
|
||||
#ifndef UTIL_LOG_H
|
||||
#define UTIL_LOG_H
|
||||
#include "ldns/buffer.h"
|
||||
#include <ldns/buffer.h>
|
||||
|
||||
/**
|
||||
* verbosity value:
|
||||
|
||||
+6
-2
@@ -100,6 +100,8 @@ struct module_env {
|
||||
* EDNS, the answer is likely to be useless for this domain.
|
||||
* @param addr: where to.
|
||||
* @param addrlen: length of addr.
|
||||
* @param zone: delegation point name.
|
||||
* @param zonelen: length of zone name.
|
||||
* @param q: wich query state to reactivate upon return.
|
||||
* @return: false on failure (memory or socket related). no query was
|
||||
* sent. Or returns an outbound entry with qsent and qstate set.
|
||||
@@ -109,7 +111,8 @@ struct module_env {
|
||||
struct outbound_entry* (*send_query)(uint8_t* qname, size_t qnamelen,
|
||||
uint16_t qtype, uint16_t qclass, uint16_t flags, int dnssec,
|
||||
int want_dnssec, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, struct module_qstate* q);
|
||||
socklen_t addrlen, uint8_t* zone, size_t zonelen,
|
||||
struct module_qstate* q);
|
||||
|
||||
/**
|
||||
* Detach-subqueries.
|
||||
@@ -348,7 +351,8 @@ struct module_func_block {
|
||||
|
||||
/**
|
||||
* inform super querystate about the results from this subquerystate.
|
||||
* Is called when the querystate is finished.
|
||||
* Is called when the querystate is finished. The method invoked is
|
||||
* the one from the current module active in the super querystate.
|
||||
* @param qstate: the query state that is finished.
|
||||
* Examine return_rcode and return_reply in the qstate.
|
||||
* @param id: module id for this module.
|
||||
|
||||
+149
-1
@@ -38,13 +38,15 @@
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "ldns/ldns.h"
|
||||
#include <ldns/ldns.h>
|
||||
#include "util/net_help.h"
|
||||
#include "util/log.h"
|
||||
#include "util/data/dname.h"
|
||||
#include "util/module.h"
|
||||
#include "util/regional.h"
|
||||
#include <fcntl.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
/** max length of an IP address (the address portion) that we allow */
|
||||
#define MAX_ADDR_STRLEN 128 /* characters */
|
||||
@@ -188,11 +190,21 @@ ipstrtoaddr(const char* ip, int port, struct sockaddr_storage* addr,
|
||||
if(!ip) return 0;
|
||||
p = (uint16_t) port;
|
||||
if(str_is_ip6(ip)) {
|
||||
char buf[MAX_ADDR_STRLEN];
|
||||
char* s;
|
||||
struct sockaddr_in6* sa = (struct sockaddr_in6*)addr;
|
||||
*addrlen = (socklen_t)sizeof(struct sockaddr_in6);
|
||||
memset(sa, 0, *addrlen);
|
||||
sa->sin6_family = AF_INET6;
|
||||
sa->sin6_port = (in_port_t)htons(p);
|
||||
if((s=strchr(ip, '%'))) { /* ip6%interface, rfc 4007 */
|
||||
if(s-ip >= MAX_ADDR_STRLEN)
|
||||
return 0;
|
||||
strncpy(buf, ip, MAX_ADDR_STRLEN);
|
||||
buf[s-ip]=0;
|
||||
sa->sin6_scope_id = (uint32_t)atoi(s+1);
|
||||
ip = buf;
|
||||
}
|
||||
if(inet_pton((int)sa->sin6_family, ip, &sa->sin6_addr) <= 0) {
|
||||
return 0;
|
||||
}
|
||||
@@ -543,3 +555,139 @@ void sock_list_merge(struct sock_list** list, struct regional* region,
|
||||
sock_list_insert(list, &p->addr, p->len, region);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
log_crypto_err(const char* str)
|
||||
{
|
||||
/* error:[error code]:[library name]:[function name]:[reason string] */
|
||||
char buf[128];
|
||||
unsigned long e;
|
||||
ERR_error_string_n(ERR_get_error(), buf, sizeof(buf));
|
||||
log_err("%s crypto %s", str, buf);
|
||||
while( (e=ERR_get_error()) ) {
|
||||
ERR_error_string_n(e, buf, sizeof(buf));
|
||||
log_err("and additionally crypto %s", buf);
|
||||
}
|
||||
}
|
||||
|
||||
void* listen_sslctx_create(char* key, char* pem, char* verifypem)
|
||||
{
|
||||
SSL_CTX* ctx = SSL_CTX_new(SSLv23_server_method());
|
||||
if(!ctx) {
|
||||
log_crypto_err("could not SSL_CTX_new");
|
||||
return NULL;
|
||||
}
|
||||
/* no SSLv2 because has defects */
|
||||
if(!(SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2)){
|
||||
log_crypto_err("could not set SSL_OP_NO_SSLv2");
|
||||
SSL_CTX_free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
if(!SSL_CTX_use_certificate_file(ctx, pem, SSL_FILETYPE_PEM)) {
|
||||
log_err("error for cert file: %s", pem);
|
||||
log_crypto_err("error in SSL_CTX use_certificate_file");
|
||||
SSL_CTX_free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
if(!SSL_CTX_use_PrivateKey_file(ctx, key, SSL_FILETYPE_PEM)) {
|
||||
log_err("error for private key file: %s", key);
|
||||
log_crypto_err("Error in SSL_CTX use_PrivateKey_file");
|
||||
SSL_CTX_free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
if(!SSL_CTX_check_private_key(ctx)) {
|
||||
log_err("error for key file: %s", key);
|
||||
log_crypto_err("Error in SSL_CTX check_private_key");
|
||||
SSL_CTX_free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(verifypem && verifypem[0]) {
|
||||
if(!SSL_CTX_load_verify_locations(ctx, verifypem, NULL)) {
|
||||
log_crypto_err("Error in SSL_CTX verify locations");
|
||||
SSL_CTX_free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(
|
||||
verifypem));
|
||||
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void* connect_sslctx_create(char* key, char* pem, char* verifypem)
|
||||
{
|
||||
SSL_CTX* ctx = SSL_CTX_new(SSLv23_client_method());
|
||||
if(!ctx) {
|
||||
log_crypto_err("could not allocate SSL_CTX pointer");
|
||||
return NULL;
|
||||
}
|
||||
if(!(SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2)) {
|
||||
log_crypto_err("could not set SSL_OP_NO_SSLv2");
|
||||
SSL_CTX_free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
if(key && key[0]) {
|
||||
if(!SSL_CTX_use_certificate_file(ctx, pem, SSL_FILETYPE_PEM)) {
|
||||
log_err("error in client certificate %s", pem);
|
||||
log_crypto_err("error in certificate file");
|
||||
SSL_CTX_free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
if(!SSL_CTX_use_PrivateKey_file(ctx, key, SSL_FILETYPE_PEM)) {
|
||||
log_err("error in client private key %s", key);
|
||||
log_crypto_err("error in key file");
|
||||
SSL_CTX_free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
if(!SSL_CTX_check_private_key(ctx)) {
|
||||
log_err("error in client key %s", key);
|
||||
log_crypto_err("error in SSL_CTX_check_private_key");
|
||||
SSL_CTX_free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if(verifypem && verifypem[0]) {
|
||||
if(!SSL_CTX_load_verify_locations(ctx, verifypem, NULL) != 1) {
|
||||
log_crypto_err("error in SSL_CTX verify");
|
||||
SSL_CTX_free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void* incoming_ssl_fd(void* sslctx, int fd)
|
||||
{
|
||||
SSL* ssl = SSL_new((SSL_CTX*)sslctx);
|
||||
if(!ssl) {
|
||||
log_crypto_err("could not SSL_new");
|
||||
return NULL;
|
||||
}
|
||||
SSL_set_accept_state(ssl);
|
||||
(void)SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
|
||||
if(!SSL_set_fd(ssl, fd)) {
|
||||
log_crypto_err("could not SSL_set_fd");
|
||||
SSL_free(ssl);
|
||||
return NULL;
|
||||
}
|
||||
return ssl;
|
||||
}
|
||||
|
||||
void* outgoing_ssl_fd(void* sslctx, int fd)
|
||||
{
|
||||
SSL* ssl = SSL_new((SSL_CTX*)sslctx);
|
||||
if(!ssl) {
|
||||
log_crypto_err("could not SSL_new");
|
||||
return NULL;
|
||||
}
|
||||
SSL_set_connect_state(ssl);
|
||||
(void)SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
|
||||
if(!SSL_set_fd(ssl, fd)) {
|
||||
log_crypto_err("could not SSL_set_fd");
|
||||
SSL_free(ssl);
|
||||
return NULL;
|
||||
}
|
||||
return ssl;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user