mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-08-17 21:25:50 +02:00
Compare commits
195
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5af8a72f83 | ||
|
|
8146c54177 | ||
|
|
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 | ||
|
|
1daad9d9c0 | ||
|
|
af93d6033c | ||
|
|
46eeced066 | ||
|
|
70c8f304c2 | ||
|
|
1a2b78e51a | ||
|
|
54d0ed9a70 | ||
|
|
d56aef7b33 | ||
|
|
accc4a6f68 | ||
|
|
39de97e176 | ||
|
|
05e118b7d5 | ||
|
|
174604914f | ||
|
|
d265c02f69 | ||
|
|
17e5bba504 | ||
|
|
5ab9b9c8f9 | ||
|
|
09375e16e7 | ||
|
|
22290ac234 | ||
|
|
86c4c11ca2 | ||
|
|
63c07d13ce | ||
|
|
e8ec432579 | ||
|
|
ad864b0f7e | ||
|
|
cafc73a74f | ||
|
|
8c04c2e187 | ||
|
|
27b5d25703 | ||
|
|
dbd816fafb | ||
|
|
47653ae679 | ||
|
|
3d2156dacc | ||
|
|
25319e6737 | ||
|
|
7359d84e2f | ||
|
|
5f08751b3b | ||
|
|
60e8c22040 | ||
|
|
a742415b5c | ||
|
|
7b5262ccd2 | ||
|
|
c3da97fb35 | ||
|
|
844b5e71b1 | ||
|
|
172260232e | ||
|
|
c155cfc8bc | ||
|
|
447b6a1149 | ||
|
|
7070c35e11 | ||
|
|
dd03b668c5 | ||
|
|
1dff4206d5 | ||
|
|
bbe76430fe | ||
|
|
2c9bf883c9 | ||
|
|
59f5480df1 | ||
|
|
bc06ab0377 | ||
|
|
668bcfc499 | ||
|
|
9229c58c2f | ||
|
|
c89323ef93 | ||
|
|
4f68378640 | ||
|
|
ff23baadcc | ||
|
|
7c128d5013 | ||
|
|
b279987e9f | ||
|
|
8ecb52c532 | ||
|
|
28912ed659 | ||
|
|
f24f631838 | ||
|
|
42730aad99 | ||
|
|
8def9c1043 | ||
|
|
ecf4deedbe | ||
|
|
139ab47dc6 | ||
|
|
608f82a1cd | ||
|
|
5cbf6d059b | ||
|
|
a11fbf9ca0 | ||
|
|
30a339d1a8 | ||
|
|
92e1ec3444 | ||
|
|
62eea87455 | ||
|
|
30602d5d59 | ||
|
|
b23ed42b55 | ||
|
|
784d659e91 | ||
|
|
4df60a1343 | ||
|
|
ca38a8bd55 | ||
|
|
6e9d8fb22c | ||
|
|
35140bb612 | ||
|
|
de82245d3e | ||
|
|
3922eed584 | ||
|
|
efb9c02d54 | ||
|
|
04fa474ac3 | ||
|
|
3c87eb6c49 | ||
|
|
fcc7f9dae0 | ||
|
|
654a9160f5 | ||
|
|
682ad09bc4 | ||
|
|
ffb54322cb | ||
|
|
cc763c103b | ||
|
|
9053ee101d | ||
|
|
0b0a580422 | ||
|
|
b4a089ff0d | ||
|
|
ee6f5c5b51 | ||
|
|
c2299a3c5f | ||
|
|
255d669e58 | ||
|
|
c07e17fda3 | ||
|
|
d8928e1b19 | ||
|
|
01dd4a3568 | ||
|
|
1550bc65f3 | ||
|
|
4011c3861b | ||
|
|
58c2cc2740 | ||
|
|
87296966ae | ||
|
|
eed924d7be | ||
|
|
36d5a75848 | ||
|
|
5996f3b2a9 | ||
|
|
5e2a137562 | ||
|
|
5a154aeb78 |
+996
-301
File diff suppressed because it is too large
Load Diff
Vendored
+1277
-795
File diff suppressed because it is too large
Load Diff
+67
-15
@@ -2,7 +2,15 @@
|
||||
# Copyright 2009, Wouter Wijngaards, NLnet Labs.
|
||||
# BSD licensed.
|
||||
#
|
||||
# Version 11
|
||||
# Version 19
|
||||
# 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.
|
||||
# 2010-08-16 Fix FLAG_OMITTED for AS_TR_CPP changes in autoconf-2.66.
|
||||
# 2010-07-02 Add check for ss_family (for minix).
|
||||
# 2010-04-26 Fix to use CPPFLAGS for CHECK_COMPILER_FLAGS.
|
||||
@@ -32,6 +40,7 @@
|
||||
# ACX_DETERMINE_EXT_FLAGS_UNBOUND - find out which flags enable BSD and POSIX.
|
||||
# ACX_CHECK_FORMAT_ATTRIBUTE - find cc printf format syntax.
|
||||
# ACX_CHECK_UNUSED_ATTRIBUTE - find cc variable unused syntax.
|
||||
# ACX_CHECK_FLTO - see if cc supports -flto and use it if so.
|
||||
# ACX_LIBTOOL_C_ONLY - create libtool for C only, improved.
|
||||
# ACX_TYPE_U_CHAR - u_char type.
|
||||
# ACX_TYPE_RLIM_T - rlim_t type.
|
||||
@@ -383,6 +392,24 @@ int test() {
|
||||
|
||||
])dnl End of ACX_DETERMINE_EXT_FLAGS_UNBOUND
|
||||
|
||||
dnl Check if CC supports -flto.
|
||||
dnl in a way that supports clang and suncc (that flag does something else,
|
||||
dnl but fails to link). It sets it in CFLAGS if it works.
|
||||
AC_DEFUN([ACX_CHECK_FLTO],
|
||||
[AC_MSG_CHECKING([if $CC supports -flto])
|
||||
BAKCFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS -flto"
|
||||
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)
|
||||
dnl result in HAVE_ATTR_FORMAT.
|
||||
dnl Make sure you also include the AHX_CONFIG_FORMAT_ATTRIBUTE.
|
||||
@@ -754,7 +781,7 @@ AC_DEFUN([ACX_CHECK_GETADDRINFO_WITH_INCLUDES],
|
||||
AC_MSG_CHECKING(for getaddrinfo)
|
||||
ac_cv_func_getaddrinfo=no
|
||||
AC_LINK_IFELSE(
|
||||
[
|
||||
[AC_LANG_SOURCE([[
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
@@ -768,14 +795,21 @@ int main() {
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
],
|
||||
]])],
|
||||
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"
|
||||
AC_LINK_IFELSE(
|
||||
AC_LANG_PROGRAM(
|
||||
[AC_LANG_PROGRAM(
|
||||
[
|
||||
#ifdef HAVE_WS2TCPIP_H
|
||||
#include <ws2tcpip.h>
|
||||
@@ -784,7 +818,7 @@ AC_LANG_PROGRAM(
|
||||
[
|
||||
(void)getaddrinfo(NULL, NULL, NULL, NULL);
|
||||
]
|
||||
),
|
||||
)],
|
||||
[
|
||||
ac_cv_func_getaddrinfo="yes"
|
||||
dnl already: LIBS="$LIBS -lws2_32"
|
||||
@@ -848,7 +882,8 @@ if echo $target | grep mingw32 >/dev/null; then
|
||||
AC_MSG_RESULT([no (windows)])
|
||||
AC_DEFINE([NONBLOCKING_IS_BROKEN], 1, [Define if the network stack does not fully support nonblocking io (causes lower performance).])
|
||||
else
|
||||
AC_RUN_IFELSE(AC_LANG_PROGRAM([
|
||||
AC_RUN_IFELSE([
|
||||
AC_LANG_SOURCE([[
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
@@ -872,7 +907,9 @@ AC_RUN_IFELSE(AC_LANG_PROGRAM([
|
||||
#ifdef HAVE_TIME_H
|
||||
#include <time.h>
|
||||
#endif
|
||||
],[[
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int port;
|
||||
int sfd, cfd;
|
||||
int num = 10;
|
||||
@@ -965,7 +1002,9 @@ AC_RUN_IFELSE(AC_LANG_PROGRAM([
|
||||
|
||||
close(sfd);
|
||||
close(cfd);
|
||||
]]), [
|
||||
return 0;
|
||||
}
|
||||
]])], [
|
||||
AC_MSG_RESULT([yes])
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
@@ -1005,13 +1044,13 @@ AC_DEFUN([ACX_FUNC_IOCTLSOCKET],
|
||||
[
|
||||
# check ioctlsocket
|
||||
AC_MSG_CHECKING(for ioctlsocket)
|
||||
AC_LINK_IFELSE(AC_LANG_PROGRAM([
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([
|
||||
#ifdef HAVE_WINSOCK2_H
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
], [
|
||||
(void)ioctlsocket(0, 0, NULL);
|
||||
]), [
|
||||
])], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_IOCTLSOCKET, 1, [if the function 'ioctlsocket' is available])
|
||||
],[AC_MSG_RESULT(no)])
|
||||
@@ -1021,10 +1060,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.
|
||||
|
||||
+1
-1
@@ -129,7 +129,7 @@ $ac_distutils_result])
|
||||
AC_MSG_CHECKING([for Python site-packages path])
|
||||
if test -z "$PYTHON_SITE_PKG"; then
|
||||
PYTHON_SITE_PKG=`$PYTHON -c "import distutils.sysconfig; \
|
||||
print distutils.sysconfig.get_python_lib(0,0);"`
|
||||
print distutils.sysconfig.get_python_lib(1,0);"`
|
||||
fi
|
||||
AC_MSG_RESULT([$PYTHON_SITE_PKG])
|
||||
AC_SUBST([PYTHON_SITE_PKG])
|
||||
|
||||
@@ -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
|
||||
|
||||
+12
-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. */
|
||||
@@ -871,4 +875,10 @@ void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
|
||||
|
||||
/** default port for DNS traffic. */
|
||||
#define UNBOUND_DNS_PORT 53
|
||||
/** default port for unbound control traffic, registered port with IANA,
|
||||
ub-dns-control 8953/tcp unbound dns nameserver control */
|
||||
#define UNBOUND_CONTROL_PORT 8953
|
||||
/** the version of unbound-control that this software implements */
|
||||
#define UNBOUND_CONTROL_VERSION 1
|
||||
|
||||
|
||||
|
||||
+311
-109
@@ -6,11 +6,11 @@ sinclude(acx_pthread.m4)
|
||||
sinclude(acx_python.m4)
|
||||
sinclude(ac_pkg_swig.m4)
|
||||
|
||||
AC_INIT(unbound, 1.4.8, unbound-bugs@nlnetlabs.nl, unbound)
|
||||
AC_INIT(unbound, 1.4.15, unbound-bugs@nlnetlabs.nl, unbound)
|
||||
|
||||
LIBUNBOUND_CURRENT=2
|
||||
LIBUNBOUND_REVISION=8
|
||||
LIBUNBOUND_AGE=0
|
||||
LIBUNBOUND_CURRENT=3
|
||||
LIBUNBOUND_REVISION=0
|
||||
LIBUNBOUND_AGE=1
|
||||
# 1.0.0 had 0:12:0
|
||||
# 1.0.1 had 0:13:0
|
||||
# 1.0.2 had 0:14:0
|
||||
@@ -33,6 +33,14 @@ LIBUNBOUND_AGE=0
|
||||
# 1.4.6 had 2:6:0
|
||||
# 1.4.7 had 2:7:0
|
||||
# 1.4.8 had 2:8:0
|
||||
# 1.4.9 had 2:9:0
|
||||
# 1.4.10 had 2:10: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()
|
||||
|
||||
# Current -- the number of the binary API that we're implementing
|
||||
# Revision -- which iteration of the implementation of the binary
|
||||
@@ -222,6 +230,7 @@ case "$debug_enabled" in
|
||||
# nothing to do.
|
||||
;;
|
||||
esac
|
||||
ACX_CHECK_FLTO
|
||||
|
||||
AC_C_INLINE
|
||||
ACX_CHECK_FORMAT_ATTRIBUTE
|
||||
@@ -279,6 +288,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
|
||||
@@ -287,19 +321,43 @@ 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
|
||||
# check windows threads
|
||||
AC_CHECK_HEADERS([windows.h],,, [AC_INCLUDES_DEFAULT])
|
||||
AC_MSG_CHECKING([for CreateThread])
|
||||
AC_TRY_COMPILE([
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
|
||||
#ifdef HAVE_WINDOWS_H
|
||||
#include <windows.h>
|
||||
#endif
|
||||
], [
|
||||
HANDLE t = CreateThread(NULL, 0, NULL, NULL, 0, NULL);
|
||||
],
|
||||
])],
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_WINDOWS_THREADS, 1, [Using Windows threads])
|
||||
,
|
||||
@@ -411,6 +469,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
|
||||
@@ -418,6 +482,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
|
||||
@@ -427,6 +499,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
|
||||
@@ -463,6 +542,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
|
||||
@@ -471,8 +648,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
|
||||
|
||||
@@ -580,7 +760,7 @@ AC_CHECK_HEADERS([expat.h],,, [AC_INCLUDES_DEFAULT])
|
||||
# set static linking if requested
|
||||
AC_SUBST(staticexe)
|
||||
staticexe=""
|
||||
AC_ARG_ENABLE(staticexe, AC_HELP_STRING([--enable-static-exe],
|
||||
AC_ARG_ENABLE(static-exe, AC_HELP_STRING([--enable-static-exe],
|
||||
[ enable to compile executables statically against event, ldns libs, for debug purposes ]),
|
||||
, )
|
||||
if test x_$enable_static_exe = x_yes; then
|
||||
@@ -600,43 +780,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])
|
||||
@@ -652,29 +823,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_TRY_RUN([
|
||||
#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])])
|
||||
@@ -691,18 +839,86 @@ 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
|
||||
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(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.
|
||||
use_ldns_builtin="no"
|
||||
AC_ARG_WITH(ldns, AC_HELP_STRING([--with-ldns=PATH],
|
||||
[specify prefix of path of ldns library to use]),
|
||||
[ specialldnsdir="$withval"
|
||||
[
|
||||
if test "$withval" != "yes"; then
|
||||
if test "$withval" != ""; then
|
||||
if test "$withval" != "/usr" -a "$withval" != ""; then
|
||||
CPPFLAGS="-I$withval/include $CPPFLAGS"
|
||||
LDFLAGS="-L$withval -L$withval/lib $LDFLAGS"
|
||||
LDFLAGS="-L$withval/lib $LDFLAGS"
|
||||
ACX_RUNTIME_PATH_ADD([$withval/lib])
|
||||
fi
|
||||
ldnsdir="$withval"
|
||||
@@ -710,23 +926,23 @@ AC_ARG_WITH(ldns, AC_HELP_STRING([--with-ldns=PATH],
|
||||
fi
|
||||
])
|
||||
|
||||
AC_ARG_WITH(ldns-builtin, AC_HELP_STRING([--with-ldns-builtin],
|
||||
[forces use of package included with this one]), [
|
||||
use_ldns_builtin="yes"
|
||||
])
|
||||
|
||||
# check if ldns is good enough
|
||||
if test "$use_ldns_builtin" = "no"; then
|
||||
AC_CHECK_LIB(ldns, ldns_buffer_copy)
|
||||
AC_CHECK_FUNC(ldns_key_buf2rsa_raw)
|
||||
AC_CHECK_FUNC(ldns_b32_ntop_extended_hex)
|
||||
if test x$use_gost = xyes; then
|
||||
AC_CHECK_FUNC(ldns_key_EVP_load_gost_id)
|
||||
AC_CHECK_FUNCS([ldns_key_EVP_unload_gost])
|
||||
else
|
||||
ac_cv_func_ldns_key_EVP_load_gost_id="yes"
|
||||
fi
|
||||
AC_CHECK_HEADERS([ldns/ldns.h],,, [AC_INCLUDES_DEFAULT
|
||||
AC_CHECK_LIB(ldns, ldns_rr_new,,[
|
||||
AC_MSG_ERROR([No ldns library found, install the ldns library into system lib dir or use --with-ldns=path to other location. The --with-ldns can point to the make-dir of ldns. Install the package ldns or download source http://www.nlnetlabs.nl/projects/ldns])
|
||||
])
|
||||
AC_CHECK_FUNC(ldns_buffer_copy)
|
||||
AC_CHECK_FUNC(ldns_key_buf2rsa_raw)
|
||||
AC_CHECK_FUNC(ldns_get_random)
|
||||
AC_CHECK_FUNC(ldns_b32_ntop_extended_hex)
|
||||
if test x$use_gost = xyes; then
|
||||
AC_CHECK_FUNC(ldns_key_EVP_load_gost_id)
|
||||
AC_CHECK_FUNCS([ldns_key_EVP_unload_gost])
|
||||
else
|
||||
ac_cv_func_ldns_key_EVP_load_gost_id="yes"
|
||||
fi
|
||||
AC_CHECK_HEADERS([ldns/ldns.h],,[
|
||||
AC_MSG_ERROR([No ldns include file found, install the ldns library development files. Install package ldns-dev or ldns-devel or download source http://www.nlnetlabs.nl/projects/ldns])
|
||||
], [AC_INCLUDES_DEFAULT
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
@@ -747,38 +963,18 @@ if test "$use_ldns_builtin" = "no"; then
|
||||
#include <ws2tcpip.h>
|
||||
#endif
|
||||
])
|
||||
if test $ac_cv_lib_ldns_ldns_buffer_copy = yes \
|
||||
-a $ac_cv_func_ldns_key_buf2rsa_raw = yes \
|
||||
-a $ac_cv_header_ldns_ldns_h = yes \
|
||||
-a $ac_cv_func_ldns_b32_ntop_extended_hex = yes \
|
||||
-a $ac_cv_func_ldns_key_EVP_load_gost_id = yes; then
|
||||
dnl ldns was found
|
||||
:
|
||||
else
|
||||
AC_MSG_ERROR([No ldns library found (or not recent); install or update ldns library, use --with-ldns=path or --with-ldns-builtin])
|
||||
fi
|
||||
if test $ac_cv_func_ldns_buffer_copy = yes \
|
||||
-a $ac_cv_func_ldns_key_buf2rsa_raw = yes \
|
||||
-a $ac_cv_func_ldns_get_random = yes \
|
||||
-a $ac_cv_header_ldns_ldns_h = yes \
|
||||
-a $ac_cv_func_ldns_b32_ntop_extended_hex = yes \
|
||||
-a $ac_cv_func_ldns_key_EVP_load_gost_id = yes; then
|
||||
dnl ldns was found
|
||||
:
|
||||
else
|
||||
AC_MSG_ERROR([ldns library is not recent, update the ldns library, install it into system lib dir or use --with-ldns=path to other location. The --with-ldns can point to the make-dir of ldns. Package libldns or download source http://www.nlnetlabs.nl/projects/ldns])
|
||||
fi
|
||||
|
||||
if test "$use_ldns_builtin" = "yes"; then
|
||||
dnl use the builtin ldns-src.tar.gz file to build ldns.
|
||||
if test ! -f $srcdir/ldns-src.tar.gz; then
|
||||
AC_MSG_ERROR([No ldns library found and no ldns-src.tar.gz, use --with-ldns=path.])
|
||||
fi
|
||||
echo "****************************************************************"
|
||||
echo "*** ***"
|
||||
echo "*** Building ldns library from package included in this one. ***"
|
||||
echo "*** ***"
|
||||
echo "****************************************************************"
|
||||
if test -d $srcdir/ldns-src; then rm -rf $srcdir/ldns-src; fi
|
||||
mkdir $srcdir/ldns-src; cp $srcdir/ldns-src.tar.gz $srcdir/ldns-src/ldns-src.tar.gz; (cd $srcdir/ldns-src; gzip -cd ldns-src.tar.gz | tar xf -); rm -f $srcdir/ldns-src/ldns-src.tar.gz; mv $srcdir/ldns-src $srcdir/ldns-srcb; mv $srcdir/ldns-srcb/ldns* $srcdir/ldns-src; rmdir $srcdir/ldns-srcb
|
||||
ldnsdir="ldns-src"
|
||||
AC_MSG_NOTICE([Configure $ldnsdir scheduled after config.status])
|
||||
AC_CONFIG_SUBDIRS([ldns-src])
|
||||
CPPFLAGS="-I$ldnsdir/include $CPPFLAGS"
|
||||
LDFLAGS="$LDFLAGS $ldnsdir/*.lo"
|
||||
AC_SUBST(ldnsdir)
|
||||
fi dnl end of use_ldns_builtin == yes
|
||||
|
||||
ACX_STRIP_EXT_FLAGS
|
||||
LDFLAGS="$LATE_LDFLAGS $LDFLAGS"
|
||||
|
||||
@@ -914,6 +1110,12 @@ void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
|
||||
|
||||
/** default port for DNS traffic. */
|
||||
#define UNBOUND_DNS_PORT 53
|
||||
/** default port for unbound control traffic, registered port with IANA,
|
||||
ub-dns-control 8953/tcp unbound dns nameserver control */
|
||||
#define UNBOUND_CONTROL_PORT 8953
|
||||
/** the version of unbound-control that this software implements */
|
||||
#define UNBOUND_CONTROL_VERSION 1
|
||||
|
||||
])
|
||||
|
||||
AC_CONFIG_FILES([Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound.conf.5 doc/unbound-control.8])
|
||||
|
||||
+15
-6
@@ -1,14 +1,15 @@
|
||||
Summary: Validating, recursive, and caching DNS resolver
|
||||
Name: unbound
|
||||
Version: 1.4.4
|
||||
Version: 1.4.8
|
||||
Release: 1%{?dist}
|
||||
License: BSD
|
||||
Url: http://www.nlnetlabs.nl/unbound/
|
||||
Source: http://www.unbound.net/downloads/%{name}-%{version}.tar.gz
|
||||
#Source1: unbound.init
|
||||
Group: System Environment/Daemons
|
||||
Requires: ldns
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
||||
BuildRequires: flex, openssl-devel
|
||||
BuildRequires: flex, openssl-devel, expat-devel, ldns-devel
|
||||
|
||||
%description
|
||||
Unbound is a validating, recursive, and caching DNS resolver.
|
||||
@@ -28,10 +29,6 @@ The source code is under a BSD License.
|
||||
|
||||
# configure with /var/unbound/unbound.conf so that all default chroot,
|
||||
# pidfile and config file are in /var/unbound, ready for chroot jail set up.
|
||||
#
|
||||
# This is a build using libldns builtin version, the resulting binaries
|
||||
# do not require libldns and this package does not have version dependencies.
|
||||
# Could be smaller using a dependency on libldns (use --with-ldns=).
|
||||
%configure --with-conf-file=%{_localstatedir}/%{name}/unbound.conf --disable-rpath
|
||||
|
||||
%build
|
||||
@@ -92,6 +89,18 @@ if [ "$1" -ge "1" ]; then
|
||||
fi
|
||||
|
||||
%changelog
|
||||
* Thu Jul 13 2011 Wouter Wijngaards <wouter@nlnetlabs.nl> - 1.4.8
|
||||
- ldns required and ldns-devel required for build, no more ldns-builtin.
|
||||
|
||||
* Thu Mar 17 2011 Wouter Wijngaards <wouter@nlnetlabs.nl> - 1.4.8
|
||||
- removed --disable-gost, assume recent openssl on the destination platform.
|
||||
|
||||
* Wed Mar 16 2011 Harold Jones <hajones@verisign.com> - 1.4.8
|
||||
- Bump version number to latest
|
||||
- Add expat-devel to BuildRequires
|
||||
- Added --disable-gost for building on CentOS 5.x
|
||||
- Added --with-ldns-builtin for CentOS 5.x
|
||||
|
||||
* Thu May 22 2008 Wouter Wijngaards <wouter@nlnetlabs.nl> - 1.0.0
|
||||
- contrib changes from Patrick Vande Walle.
|
||||
|
||||
|
||||
+108
-14
@@ -8,7 +8,7 @@
|
||||
|
||||
Summary: Validating, recursive, and caching DNS(SEC) resolver
|
||||
Name: unbound
|
||||
Version: 1.4.2
|
||||
Version: 1.4.13
|
||||
Release: 1%{?dist}
|
||||
License: BSD
|
||||
Url: http://www.nlnetlabs.nl/unbound/
|
||||
@@ -16,16 +16,20 @@ Source: http://www.unbound.net/downloads/%{name}-%{version}.tar.gz
|
||||
Source1: unbound.init
|
||||
Source2: unbound.conf
|
||||
Source3: unbound.munin
|
||||
Source4: dlv.isc.org.key
|
||||
Source4: unbound_munin_
|
||||
Source5: root.key
|
||||
Source6: dlv.isc.org.key
|
||||
Patch1: unbound-1.2-glob.patch
|
||||
|
||||
Group: System Environment/Daemons
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
||||
BuildRequires: flex, openssl-devel , ldns-devel >= 1.5.0,
|
||||
BuildRequires: libevent-devel
|
||||
BuildRequires: libevent-devel expat-devel
|
||||
%if %{with_python}
|
||||
BuildRequires: python-devel
|
||||
BuildRequires: python-devel swig
|
||||
%endif
|
||||
# Required for SVN versions
|
||||
# BuildRequires: bison
|
||||
|
||||
Requires(post): chkconfig
|
||||
Requires(preun): chkconfig
|
||||
@@ -34,6 +38,9 @@ Requires(postun): initscripts
|
||||
Requires: ldns >= 1.5.0
|
||||
Requires(pre): shadow-utils
|
||||
|
||||
Obsoletes: dnssec-conf < 1.27-2
|
||||
Provides: dnssec-conf = 1.27-1
|
||||
|
||||
%description
|
||||
Unbound is a validating, recursive, and caching DNS(SEC) resolver.
|
||||
|
||||
@@ -67,7 +74,7 @@ Summary: Libraries used by the unbound server and client applications
|
||||
Group: Applications/System
|
||||
Requires(post): /sbin/ldconfig
|
||||
Requires(postun): /sbin/ldconfig
|
||||
Requires: openssl >= 0.9.8g-12
|
||||
Requires: openssl
|
||||
|
||||
%description libs
|
||||
Contains libraries used by the unbound server and client applications
|
||||
@@ -88,14 +95,14 @@ Python modules and extensions for unbound
|
||||
|
||||
%build
|
||||
%configure --with-ldns= --with-libevent --with-pthreads --with-ssl \
|
||||
--disable-rpath --enable-debug --disable-static \
|
||||
--disable-rpath --disable-static \
|
||||
--with-conf-file=%{_sysconfdir}/%{name}/unbound.conf \
|
||||
--with-pidfile=%{_localstatedir}/run/%{name}/%{name}.pid \
|
||||
%if %{with_python}
|
||||
--with-pythonmodule --with-pyunbound \
|
||||
%endif
|
||||
--enable-sha2
|
||||
%{__make}
|
||||
--enable-sha2 --disable-gost
|
||||
%{__make} %{?_smp_mflags}
|
||||
|
||||
%install
|
||||
rm -rf %{buildroot}
|
||||
@@ -107,16 +114,19 @@ install -m 0755 %{SOURCE2} %{buildroot}%{_sysconfdir}/unbound
|
||||
install -d 0755 %{buildroot}%{_sysconfdir}/munin/plugin-conf.d
|
||||
install -m 0644 %{SOURCE3} %{buildroot}%{_sysconfdir}/munin/plugin-conf.d/unbound
|
||||
install -d 0755 %{buildroot}%{_datadir}/munin/plugins/
|
||||
install -m 0755 contrib/unbound_munin_ %{buildroot}%{_datadir}/munin/plugins/unbound
|
||||
install -m 0755 %{SOURCE4} %{buildroot}%{_datadir}/munin/plugins/unbound
|
||||
for plugin in unbound_munin_hits unbound_munin_queue unbound_munin_memory unbound_munin_by_type unbound_munin_by_class unbound_munin_by_opcode unbound_munin_by_rcode unbound_munin_by_flags unbound_munin_histogram; do
|
||||
ln -s unbound %{buildroot}%{_datadir}/munin/plugins/$plugin
|
||||
done
|
||||
|
||||
# install DLV key
|
||||
install -m 0644 %{SOURCE4} %{buildroot}%{_sysconfdir}/unbound/
|
||||
# install root and DLV key
|
||||
install -m 0644 %{SOURCE5} %{SOURCE6} %{buildroot}%{_sysconfdir}/unbound/
|
||||
|
||||
# remove static library from install (fedora packaging guidelines)
|
||||
rm -rf %{buildroot}%{_libdir}/*.la
|
||||
rm %{buildroot}%{_libdir}/*.la
|
||||
%if %{with_python}
|
||||
rm %{buildroot}%{python_sitearch}/*.la
|
||||
%endif
|
||||
|
||||
mkdir -p %{buildroot}%{_localstatedir}/run/unbound
|
||||
|
||||
@@ -128,15 +138,19 @@ rm -rf ${RPM_BUILD_ROOT}
|
||||
%doc doc/README doc/CREDITS doc/LICENSE doc/FEATURES
|
||||
%attr(0755,root,root) %{_initrddir}/%{name}
|
||||
%attr(0755,root,root) %dir %{_sysconfdir}/%{name}
|
||||
%attr(0755,unbound,unbound) %dir %{_localstatedir}/run/%{name}
|
||||
%ghost %attr(0755,unbound,unbound) %dir %{_localstatedir}/run/%{name}
|
||||
%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/%{name}/unbound.conf
|
||||
%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/%{name}/dlv.isc.org.key
|
||||
%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/%{name}/root.key
|
||||
%{_sbindir}/*
|
||||
%{_mandir}/*/*
|
||||
|
||||
%if %{with_python}
|
||||
%files python
|
||||
%{python_sitelib}/*
|
||||
%defattr(-,root,root,-)
|
||||
%{python_sitearch}/*
|
||||
%doc libunbound/python/examples/*
|
||||
%doc pythonmod/examples/*
|
||||
%endif
|
||||
|
||||
%files munin
|
||||
@@ -186,10 +200,90 @@ fi
|
||||
%postun libs -p /sbin/ldconfig
|
||||
|
||||
%changelog
|
||||
* Tue Sep 06 2011 Paul Wouters <paul@xelerance.com> - 1.4.13-1
|
||||
- Updated to 1.4.13
|
||||
- Fix install location of pythonmod from sitelib to sitearch
|
||||
- Removed patches merged in by upstream
|
||||
- Removed versioned openssl dep, it differs per branch
|
||||
|
||||
* Mon Aug 08 2011 Paul Wouters <paul@xelerance.com> - 1.4.12-3
|
||||
- Added pythonmod docs and examples
|
||||
- Fix for python module load in the server (Tom Hendrikx)
|
||||
- No longer enable --enable-debug as it causes degraded performance
|
||||
under load.
|
||||
|
||||
* Mon Jul 18 2011 Paul Wouters <paul@xelerance.com> - 1.4.12-1
|
||||
- Updated to 1.4.12
|
||||
|
||||
* Sun Jul 03 2011 Paul Wouters <paul@xelerance.com> - 1.4.11-1
|
||||
- Updated to 1.4.11
|
||||
- removed integrated CVE patch
|
||||
- updated stock unbound.conf for new options introduced
|
||||
|
||||
* Mon Jun 06 2011 Paul Wouters <paul@xelerance.com> - 1.4.10-1
|
||||
- Added ghost for /var/run/unbound (bz#656710)
|
||||
|
||||
* Mon Jun 06 2011 Paul Wouters <paul@xelerance.com> - 1.4.9-3
|
||||
- rebuilt
|
||||
|
||||
* Wed May 25 2011 Paul Wouters <paul@xelerance.com> - 1.4.9-2
|
||||
- Applied patch for CVE-2011-1922 DoS vulnerability
|
||||
|
||||
* Sun Mar 27 2011 Paul Wouters <paul@xelerance.com> - 1.4.9-1
|
||||
- Updated to 1.4.9
|
||||
|
||||
* Sat Feb 12 2011 Paul Wouters <paul@xelerance.com> - 1.4.8-2
|
||||
- rebuilt
|
||||
|
||||
* Tue Jan 25 2011 Paul Wouters <paul@xelerance.com> - 1.4.8-1
|
||||
- Updated to 1.4.8
|
||||
- Enable root key for DNSSEC
|
||||
- Fix unbound-munin to use proper file (could cause excessive logging)
|
||||
- Build unbound-python per default
|
||||
- Disable gost as Fedora/EPEL does not allow ECC and has mangled openssl
|
||||
|
||||
* Tue Oct 26 2010 Paul Wouters <paul@xelerance.com> - 1.4.5-4
|
||||
- Revert last build - it was on the wrong branch
|
||||
|
||||
* Tue Oct 26 2010 Paul Wouters <paul@xelerance.com> - 1.4.5-3
|
||||
- Disable do-ipv6 per default - causes severe degradation on non-ipv6 machines
|
||||
(see comments in inbound.conf)
|
||||
|
||||
* Tue Jun 15 2010 Paul Wouters <paul@xelerance.com> - 1.4.5-2
|
||||
- Bump release - forgot to upload the new tar ball.
|
||||
|
||||
* Tue Jun 15 2010 Paul Wouters <paul@xelerance.com> - 1.4.5-1
|
||||
- Upgraded to 1.4.5
|
||||
|
||||
* Mon May 31 2010 Paul Wouters <paul@xelerance.com> - 1.4.4-2
|
||||
- Added accidentally omitted svn patches to cvs
|
||||
|
||||
* Mon May 31 2010 Paul Wouters <paul@xelerance.com> - 1.4.4-1
|
||||
- Upgraded to 1.4.4 with svn patches
|
||||
- Obsolete dnssec-conf to ensure it is de-installed
|
||||
|
||||
* Thu Mar 11 2010 Paul Wouters <paul@xelerance.com> - 1.4.3-1
|
||||
- Update to 1.4.3 that fixes 64bit crasher
|
||||
|
||||
* Tue Mar 09 2010 Paul Wouters <paul@xelerance.com> - 1.4.2-1
|
||||
- Updated to 1.4.2
|
||||
- Updated unbound.conf with new options
|
||||
- Enabled pre-fetching DNSKEY records (DNSSEC speedup)
|
||||
- Enabled re-fetching popular records before they expire
|
||||
- Enabled logging of DNSSEC validation errors
|
||||
|
||||
* Mon Mar 01 2010 Paul Wouters <paul@xelerance.com> - 1.4.1-5
|
||||
- Overriding -D_GNU_SOURCE is no longer needed. This fixes DSO issues
|
||||
with pthreads
|
||||
|
||||
* Wed Feb 24 2010 Paul Wouters <paul@xelerance.com> - 1.4.1-3
|
||||
- Change make/configure lines to attempt to fix -lphtread linking issue
|
||||
|
||||
* Thu Feb 18 2010 Paul Wouters <paul@xelerance.com> - 1.4.1-2
|
||||
- Removed dependancy for dnssec-conf
|
||||
- Added ISC DLV key (formerly in dnssec-conf)
|
||||
- Fixup old DLV locations in unbound.conf file via %%post
|
||||
- Fix parent child disagreement handling and no-ipv6 present [svn r1953]
|
||||
|
||||
* Tue Jan 05 2010 Paul Wouters <paul@xelerance.com> - 1.4.1-1
|
||||
- Updated to 1.4.1
|
||||
|
||||
@@ -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"))
|
||||
|
||||
+6
-2
@@ -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,13 +321,14 @@ 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");
|
||||
numport = daemon_get_shufport(daemon, shufport);
|
||||
verbose(VERB_ALGO, "total of %d outgoing ports available", numport);
|
||||
|
||||
daemon->num = daemon->cfg->num_threads;
|
||||
daemon->num = (daemon->cfg->num_threads?daemon->cfg->num_threads:1);
|
||||
daemon->workers = (struct worker**)calloc((size_t)daemon->num,
|
||||
sizeof(struct worker*));
|
||||
for(i=0; i<daemon->num; i++) {
|
||||
@@ -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 */
|
||||
|
||||
+98
-95
@@ -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,
|
||||
@@ -395,7 +380,6 @@ int remote_accept_callback(struct comm_point* c, void* arg, int err,
|
||||
/* create new commpoint unless we are servicing already */
|
||||
if(rc->active >= rc->max_active) {
|
||||
log_warn("drop incoming remote control: too many connections");
|
||||
comm_point_stop_listening(c);
|
||||
close_exit:
|
||||
#ifndef USE_WINSOCK
|
||||
close(newfd);
|
||||
@@ -429,6 +413,7 @@ int remote_accept_callback(struct comm_point* c, void* arg, int err,
|
||||
n->ssl = SSL_new(rc->ctx);
|
||||
if(!n->ssl) {
|
||||
log_crypto_err("could not SSL_new");
|
||||
comm_point_delete(n->c);
|
||||
free(n);
|
||||
goto close_exit;
|
||||
}
|
||||
@@ -437,6 +422,7 @@ int remote_accept_callback(struct comm_point* c, void* arg, int err,
|
||||
if(!SSL_set_fd(n->ssl, newfd)) {
|
||||
log_crypto_err("could not SSL_set_fd");
|
||||
SSL_free(n->ssl);
|
||||
comm_point_delete(n->c);
|
||||
free(n);
|
||||
goto close_exit;
|
||||
}
|
||||
@@ -702,13 +688,14 @@ print_mem(SSL* ssl, struct worker* worker, struct daemon* daemon)
|
||||
|
||||
/** print uptime stats */
|
||||
static int
|
||||
print_uptime(SSL* ssl, struct worker* worker)
|
||||
print_uptime(SSL* ssl, struct worker* worker, int reset)
|
||||
{
|
||||
struct timeval now = *worker->env.now_tv;
|
||||
struct timeval up, dt;
|
||||
timeval_subtract(&up, &now, &worker->daemon->time_boot);
|
||||
timeval_subtract(&dt, &now, &worker->daemon->time_last_stat);
|
||||
worker->daemon->time_last_stat = now;
|
||||
if(reset)
|
||||
worker->daemon->time_last_stat = now;
|
||||
if(!ssl_printf(ssl, "time.now"SQ"%d.%6.6d\n",
|
||||
(unsigned)now.tv_sec, (unsigned)now.tv_usec)) return 0;
|
||||
if(!ssl_printf(ssl, "time.up"SQ"%d.%6.6d\n",
|
||||
@@ -892,7 +879,7 @@ do_stats(SSL* ssl, struct daemon_remote* rc, int reset)
|
||||
total.mesh_time_median /= (double)daemon->num;
|
||||
if(!print_stats(ssl, "total", &total))
|
||||
return;
|
||||
if(!print_uptime(ssl, rc->worker))
|
||||
if(!print_uptime(ssl, rc->worker, reset))
|
||||
return;
|
||||
if(daemon->cfg->stat_extended) {
|
||||
if(!print_mem(ssl, rc->worker, daemon))
|
||||
@@ -1062,6 +1049,9 @@ do_cache_remove(struct worker* worker, uint8_t* nm, size_t nmlen,
|
||||
hashvalue_t h;
|
||||
struct query_info k;
|
||||
rrset_cache_remove(worker->env.rrset_cache, nm, nmlen, t, c, 0);
|
||||
if(t == LDNS_RR_TYPE_SOA)
|
||||
rrset_cache_remove(worker->env.rrset_cache, nm, nmlen, t, c,
|
||||
PACKED_RRSET_SOA_NEG);
|
||||
k.qname = nm;
|
||||
k.qname_len = nmlen;
|
||||
k.qtype = t;
|
||||
@@ -1098,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
|
||||
*/
|
||||
@@ -1147,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)
|
||||
@@ -1522,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 */
|
||||
@@ -1867,7 +1861,8 @@ static void
|
||||
handle_req(struct daemon_remote* rc, struct rc_state* s, SSL* ssl)
|
||||
{
|
||||
int r;
|
||||
char magic[5];
|
||||
char pre[10];
|
||||
char magic[7];
|
||||
char buf[1024];
|
||||
#ifdef USE_WINSOCK
|
||||
/* makes it possible to set the socket blocking again. */
|
||||
@@ -1876,7 +1871,7 @@ handle_req(struct daemon_remote* rc, struct rc_state* s, SSL* ssl)
|
||||
#endif
|
||||
fd_set_block(s->c->fd);
|
||||
|
||||
/* try to read magic UBCT string */
|
||||
/* try to read magic UBCT[version]_space_ string */
|
||||
ERR_clear_error();
|
||||
if((r=SSL_read(ssl, magic, (int)sizeof(magic)-1)) <= 0) {
|
||||
if(SSL_get_error(ssl, r) == SSL_ERROR_ZERO_RETURN)
|
||||
@@ -1884,9 +1879,10 @@ handle_req(struct daemon_remote* rc, struct rc_state* s, SSL* ssl)
|
||||
log_crypto_err("could not SSL_read");
|
||||
return;
|
||||
}
|
||||
magic[4] = 0;
|
||||
if( r != 4 || strcmp(magic, "UBCT") != 0) {
|
||||
magic[6] = 0;
|
||||
if( r != 6 || strncmp(magic, "UBCT", 4) != 0) {
|
||||
verbose(VERB_QUERY, "control connection has bad magic string");
|
||||
/* probably wrong tool connected, ignore it completely */
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1894,6 +1890,13 @@ handle_req(struct daemon_remote* rc, struct rc_state* s, SSL* ssl)
|
||||
if(!ssl_read_line(ssl, buf, sizeof(buf))) {
|
||||
return;
|
||||
}
|
||||
snprintf(pre, sizeof(pre), "UBCT%d ", UNBOUND_CONTROL_VERSION);
|
||||
if(strcmp(magic, pre) != 0) {
|
||||
verbose(VERB_QUERY, "control connection had bad "
|
||||
"version %s, cmd: %s", magic, buf);
|
||||
ssl_printf(ssl, "error version mismatch\n");
|
||||
return;
|
||||
}
|
||||
verbose(VERB_DETAIL, "control cmd: %s", buf);
|
||||
|
||||
/* figure out what to do */
|
||||
|
||||
+5
-3
@@ -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"
|
||||
@@ -100,12 +100,14 @@ void server_stats_log(struct server_stats* stats, struct worker* worker,
|
||||
(unsigned)stats->num_queries_missed_cache,
|
||||
(unsigned)stats->num_queries_prefetch);
|
||||
log_info("server stats for thread %d: requestlist max %u avg %g "
|
||||
"exceeded %u", threadnum, (unsigned)stats->max_query_list_size,
|
||||
"exceeded %u jostled %u", threadnum,
|
||||
(unsigned)stats->max_query_list_size,
|
||||
(stats->num_queries_missed_cache+stats->num_queries_prefetch)?
|
||||
(double)stats->sum_query_list_size/
|
||||
(stats->num_queries_missed_cache+
|
||||
stats->num_queries_prefetch) : 0.0,
|
||||
(unsigned)worker->env.mesh->stats_dropped);
|
||||
(unsigned)worker->env.mesh->stats_dropped,
|
||||
(unsigned)worker->env.mesh->stats_jostled);
|
||||
}
|
||||
|
||||
/** get rrsets bogus number from validator */
|
||||
|
||||
+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;
|
||||
|
||||
+9
-1
@@ -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>
|
||||
@@ -199,7 +200,7 @@ checkrlimits(struct config_file* cfg)
|
||||
#if !defined(HAVE_PTHREAD) && !defined(HAVE_SOLARIS_THREADS)
|
||||
int numthread = 1; /* it forks */
|
||||
#else
|
||||
int numthread = cfg->num_threads;
|
||||
int numthread = (cfg->num_threads?cfg->num_threads:1);
|
||||
#endif
|
||||
size_t total = numthread * perthread + misc;
|
||||
size_t avail;
|
||||
@@ -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 */
|
||||
|
||||
+26
-13
@@ -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"
|
||||
@@ -446,7 +446,8 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
uint16_t udpsize = edns->udp_size;
|
||||
int secure = 0;
|
||||
uint32_t timenow = *worker->env.now;
|
||||
int must_validate = !(flags&BIT_CD) && worker->env.need_to_validate;
|
||||
int must_validate = (!(flags&BIT_CD) || worker->env.cfg->ignore_cd)
|
||||
&& worker->env.need_to_validate;
|
||||
struct dns_msg *msg = NULL;
|
||||
struct delegpt *dp;
|
||||
|
||||
@@ -522,7 +523,8 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
uint32_t timenow = *worker->env.now;
|
||||
uint16_t udpsize = edns->udp_size;
|
||||
int secure;
|
||||
int must_validate = !(flags&BIT_CD) && worker->env.need_to_validate;
|
||||
int must_validate = (!(flags&BIT_CD) || worker->env.cfg->ignore_cd)
|
||||
&& worker->env.need_to_validate;
|
||||
/* see if it is possible */
|
||||
if(rep->ttl < timenow) {
|
||||
/* the rrsets may have been updated in the meantime.
|
||||
@@ -737,17 +739,21 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
worker->stats.unwanted_queries++;
|
||||
return 0;
|
||||
} else if(acl == acl_refuse) {
|
||||
log_addr(VERB_ALGO, "refused query from",
|
||||
&repinfo->addr, repinfo->addrlen);
|
||||
log_buf(VERB_ALGO, "refuse", c->buffer);
|
||||
if(worker->stats.extended)
|
||||
worker->stats.unwanted_queries++;
|
||||
if(worker_check_request(c->buffer, worker) == -1) {
|
||||
comm_point_drop_reply(repinfo);
|
||||
return 0; /* discard this */
|
||||
}
|
||||
ldns_buffer_set_limit(c->buffer, LDNS_HEADER_SIZE);
|
||||
ldns_buffer_write_at(c->buffer, 4,
|
||||
(uint8_t*)"\0\0\0\0\0\0\0\0", 8);
|
||||
LDNS_QR_SET(ldns_buffer_begin(c->buffer));
|
||||
LDNS_RCODE_SET(ldns_buffer_begin(c->buffer),
|
||||
LDNS_RCODE_REFUSED);
|
||||
log_addr(VERB_ALGO, "refused query from",
|
||||
&repinfo->addr, repinfo->addrlen);
|
||||
log_buf(VERB_ALGO, "refuse", c->buffer);
|
||||
if(worker->stats.extended)
|
||||
worker->stats.unwanted_queries++;
|
||||
return 1;
|
||||
}
|
||||
if((ret=worker_check_request(c->buffer, worker)) != 0) {
|
||||
@@ -773,10 +779,16 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
server_stats_insrcode(&worker->stats, c->buffer);
|
||||
return 1;
|
||||
}
|
||||
if(worker->env.cfg->log_queries) {
|
||||
char ip[128];
|
||||
addr_to_str(&repinfo->addr, repinfo->addrlen, ip, sizeof(ip));
|
||||
log_nametypeclass(0, ip, qinfo.qname, qinfo.qtype, qinfo.qclass);
|
||||
}
|
||||
if(qinfo.qtype == LDNS_RR_TYPE_AXFR ||
|
||||
qinfo.qtype == LDNS_RR_TYPE_IXFR) {
|
||||
verbose(VERB_ALGO, "worker request: refused zone transfer.");
|
||||
log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
|
||||
ldns_buffer_rewind(c->buffer);
|
||||
LDNS_QR_SET(ldns_buffer_begin(c->buffer));
|
||||
LDNS_RCODE_SET(ldns_buffer_begin(c->buffer),
|
||||
LDNS_RCODE_REFUSED);
|
||||
@@ -1080,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);
|
||||
@@ -1093,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);
|
||||
@@ -1232,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(
|
||||
@@ -1243,7 +1255,8 @@ 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,
|
||||
addr, addrlen, worker_handle_service_reply, e,
|
||||
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
|
||||
|
||||
+391
@@ -1,3 +1,394 @@
|
||||
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.
|
||||
- tag 1.4.13rc2
|
||||
|
||||
7 September 2011: Wouter
|
||||
- Fix operation in ipv6 only (do-ip4: no) mode.
|
||||
|
||||
6 September 2011: Wouter
|
||||
- fedora specfile updated.
|
||||
|
||||
5 September 2011: Wouter
|
||||
- tag 1.4.13rc1
|
||||
|
||||
2 September 2011: Wouter
|
||||
- iana portlist updated.
|
||||
|
||||
26 August 2011: Wouter
|
||||
- Fix num-threads 0 does not segfault, reported by Simon Deziel.
|
||||
- Fix validation failures due to EDNS backoff retries, the retry
|
||||
for fetch of data has want_dnssec because the iter_indicate_dnssec
|
||||
function returns true when validation failure retry happens, and
|
||||
then the serviced query code does not fallback to noEDNS, even if
|
||||
the cache says it has this. This helps for DLV deployment when
|
||||
the DNSSEC status is not known for sure before the lookup concludes.
|
||||
|
||||
24 August 2011: Wouter
|
||||
- Applied patch from Karel Slany that fixes a memory leak in the
|
||||
unbound python module, in string conversions.
|
||||
|
||||
22 August 2011: Wouter
|
||||
- Fix validation of qtype ANY responses with CNAMEs (thanks Cathy
|
||||
Zhang and Luo Ce). Unbound responds with the RR types that are
|
||||
available at the name for qtype ANY and validates those RR types.
|
||||
It does not test for completeness (i.e. with NSEC or NSEC3 query),
|
||||
and it does not follow the CNAME or DNAME to another name (with
|
||||
even more data for the already large response).
|
||||
- Fix that internally, CNAMEs with NXDOMAIN have that as rcode.
|
||||
- Documented the options that work with control set_option command.
|
||||
- tcp-upstream yes/no option (works with set_option) for tunnels.
|
||||
|
||||
18 August 2011: Wouter
|
||||
- fix autoconf call in makedist crosscompile to RC or snapshot.
|
||||
|
||||
17 August 2011: Wouter
|
||||
- Fix validation of . DS query.
|
||||
- new xml format at IANA, new awk for iana_update.
|
||||
- iana portlist updated.
|
||||
|
||||
10 August 2011: Wouter
|
||||
- Fix python site-packages path to /usr/lib64.
|
||||
- updated patch from Tom.
|
||||
- fix memory and fd leak after out-of-memory condition.
|
||||
|
||||
9 August 2011: Wouter
|
||||
- patch from Tom Hendrikx fixes load of python modules.
|
||||
|
||||
8 August 2011: Wouter
|
||||
- make clean had ldns-src reference, removed.
|
||||
|
||||
1 August 2011: Wouter
|
||||
- Fix autoconf 2.68 warnings
|
||||
|
||||
14 July 2011: Wouter
|
||||
- Unbound implements RFC6303 (since version 1.4.7).
|
||||
- tag 1.4.12rc1 is released as 1.4.12 (without the other fixes in the
|
||||
meantime, those are for 1.4.13).
|
||||
- iana portlist updated.
|
||||
|
||||
13 July 2011: Wouter
|
||||
- Quick fix for contrib/unbound.spec example, no ldns-builtin any more.
|
||||
|
||||
11 July 2011: Wouter
|
||||
- Fix wildcard expansion no-data reply under an optout NSEC3 zone is
|
||||
validated as insecure, reported by Jia Li (lijia@cnnic.cn).
|
||||
|
||||
4 July 2011: Wouter
|
||||
- 1.4.12rc1 tag created.
|
||||
|
||||
1 July 2011: Wouter
|
||||
- version number in example config file.
|
||||
- fix that --enable-static-exe does not complain about it unknown.
|
||||
|
||||
30 June 2011: Wouter
|
||||
- tag relase 1.4.11, trunk is 1.4.12 development.
|
||||
- iana portlist updated.
|
||||
- fix bug#395: id bits of other query may leak out under conditions
|
||||
- fix replyaddr count wrong after jostled queries, which leads to
|
||||
eventual starvation where the daemon has no replyaddrs left to use.
|
||||
- fix comment about rndc port, that referred to the old port number.
|
||||
- fix that the listening socket is not closed when too many remote
|
||||
control connections are made at the same time.
|
||||
- removed ldns-src tarball inside the unbound tarball.
|
||||
|
||||
23 June 2011: Wouter
|
||||
- Changed -flto check to support clang compiler.
|
||||
- tag 1.4.11rc3 created.
|
||||
|
||||
17 June 2011: Wouter
|
||||
- tag 1.4.11rc1 created.
|
||||
- remove warning about signed/unsigned from flex (other flex version).
|
||||
- updated aclocal.m4 and libtool to match.
|
||||
- tag 1.4.11rc2 created.
|
||||
|
||||
16 June 2011: Wouter
|
||||
- log-queries: yesno option, default is no, prints querylog.
|
||||
- version is 1.4.11.
|
||||
|
||||
14 June 2011: Wouter
|
||||
- Use -flto compiler flag for link time optimization, if supported.
|
||||
- iana portlist updated.
|
||||
|
||||
12 June 2011: Wouter
|
||||
- IPv6 service address for d.root-servers.net (2001:500:2D::D).
|
||||
|
||||
10 June 2011: Wouter
|
||||
- unbound-control has version number in the header,
|
||||
UBCT[version]_space_ is the header sent by the client now.
|
||||
- Unbound control port number is registered with IANA:
|
||||
ub-dns-control 8953/tcp unbound dns nameserver control
|
||||
This is the new default for the control-port config setting.
|
||||
- statistics-interval prints the number of jostled queries to log.
|
||||
|
||||
30 May 2011: Wouter
|
||||
- Fix Makefile for U in environment, since wrong U is more common than
|
||||
deansification necessity.
|
||||
- iana portlist updated.
|
||||
- updated ldns tarball to 1.6.10rc2 snapshot of today.
|
||||
|
||||
25 May 2011: Wouter
|
||||
- Fix assertion failure when unbound generates an empty error reply
|
||||
in response to a query, CVE-2011-1922 VU#531342.
|
||||
- This fix is in tag 1.4.10.
|
||||
- defense in depth against the above bug, an error is printed to log
|
||||
instead of an assertion failure.
|
||||
|
||||
10 May 2011: Wouter
|
||||
- bug#386: --enable-allsymbols option links all binaries to libunbound
|
||||
and reduces install size significantly.
|
||||
- feature, ignore-cd-flag: yesno to provide dnssec to legacy servers.
|
||||
- iana portlist updated.
|
||||
- Fix TTL of SOA so negative TTL is separately cached from normal TTL.
|
||||
|
||||
14 April 2011: Wouter
|
||||
- configure created with newer autoconf 2.66.
|
||||
|
||||
12 April 2011: Wouter
|
||||
- bug#378: Fix that configure checks for ldns_get_random presence.
|
||||
|
||||
8 April 2011: Wouter
|
||||
- iana portlist updated.
|
||||
- queries with CD flag set cause DNSSEC validation, but the answer is
|
||||
not withheld if it is bogus. Thus, unbound will retry if it is bad
|
||||
and curb the TTL if it is bad, thus protecting the cache for use by
|
||||
downstream validators.
|
||||
- val-override-date: -1 ignores dates entirely, for NTP usage.
|
||||
|
||||
29 March 2011: Wouter
|
||||
- harden-below-nxdomain: changed so that it activates when the
|
||||
cached nxdomain is dnssec secure. This avoids backwards
|
||||
incompatibility because those old servers do not have dnssec.
|
||||
|
||||
24 March 2011: Wouter
|
||||
- iana portlist updated.
|
||||
- release 1.4.9.
|
||||
- trunk is 1.5.0
|
||||
|
||||
17 March 2011: Wouter
|
||||
- bug#370: new unbound.spec for CentOS 5.x from Harold Jones.
|
||||
Applied but did not do the --disable-gost.
|
||||
|
||||
10 March 2011: Wouter
|
||||
- tag 1.4.9 release candidate 1 created.
|
||||
|
||||
3 March 2011: Wouter
|
||||
- updated ldns to today.
|
||||
|
||||
1 March 2011: Wouter
|
||||
- Fix no ADflag for NXDOMAIN in NSEC3 optout. And wildcard in optout.
|
||||
- give config parse error for multiple names on a stub or forward zone.
|
||||
- updated ldns tarball to 1.6.9(todays snapshot).
|
||||
|
||||
24 February 2011: Wouter
|
||||
- bug #361: Fix, time.elapsed variable not reset with stats_noreset.
|
||||
|
||||
23 February 2011: Wouter
|
||||
- iana portlist updated.
|
||||
- common.sh to version 3.
|
||||
|
||||
18 February 2011: Wouter
|
||||
- common.sh in testdata updated to version 2.
|
||||
|
||||
15 February 2011: Wouter
|
||||
- Added explicit note on unbound-anchor usage:
|
||||
Please note usage of unbound-anchor root anchor is at your own risk
|
||||
and under the terms of our LICENSE (see that file in the source).
|
||||
|
||||
11 February 2011: Wouter
|
||||
- iana portlist updated.
|
||||
- tpkg updated with common.sh for common functionality.
|
||||
|
||||
7 February 2011: Wouter
|
||||
- Added regression test for addition of a .net DS to the root, and
|
||||
cache effects with different TTL for glue and DNSKEY.
|
||||
- iana portlist updated.
|
||||
|
||||
28 January 2011: Wouter
|
||||
- Fix remove private address does not throw away entire response.
|
||||
|
||||
24 January 2011: Wouter
|
||||
- release 1.4.8
|
||||
|
||||
19 January 2011: Wouter
|
||||
- fix bug#349: no -L/usr for ldns.
|
||||
|
||||
18 January 2011: Wouter
|
||||
- ldns 1.6.8 tarball included.
|
||||
- release 1.4.8rc1.
|
||||
|
||||
17 January 2011: Wouter
|
||||
- add get and set option for harden-below-nxdomain feature.
|
||||
- iana portlist updated.
|
||||
|
||||
+2
-4
@@ -11,16 +11,14 @@ This software is under BSD license, see LICENSE for details.
|
||||
|
||||
* Uses the following libraries;
|
||||
* ldns http://www.nlnetlabs.nl/ldns/ (BSD license)
|
||||
(required) can use tarball from source directory.
|
||||
(required) can use ldns build directory directly with --with-ldns=path.
|
||||
* libevent http://www.monkey.org/~provos/libevent/ (BSD license)
|
||||
(optional) can use builtin alternative instead.
|
||||
|
||||
* Make and install: ./configure; make; make install
|
||||
* Use GNU make; default on linux, often called 'gmake' on BSD and Solaris.
|
||||
* --with-ldns=/path/to/ldns
|
||||
If ldns is not detected on the system, a prepackaged tarball
|
||||
of the ldns library is used to compile and statically link against.
|
||||
If detected on the system, it will dynamically link against it.
|
||||
It will dynamically link against it.
|
||||
* --with-libevent=/path/to/libevent
|
||||
Can be set to either the system install or the build directory.
|
||||
--with-libevent=no (default) gives a builtin alternative
|
||||
|
||||
@@ -1,16 +1,21 @@
|
||||
|
||||
Specification for the unbound-control protocol.
|
||||
|
||||
Server listens on 953 TCP (localhost by default). Client connects,
|
||||
Server listens on 8953 TCP (localhost by default). Client connects,
|
||||
SSLv3 or TLSv1 connection setup (server selfsigned certificate,
|
||||
client has cert signed by server certificate).
|
||||
|
||||
Port 8953 is registered with IANA as:
|
||||
ub-dns-control 8953/tcp unbound dns nameserver control
|
||||
# Wouter Wijngaards <wouter&nlnetlabs.nl> 10 May 2011
|
||||
On may 11 2011, ticket [IANA #442315].
|
||||
|
||||
Query and Response
|
||||
------------------
|
||||
Client sends
|
||||
UBCT [commandline] \n
|
||||
fixed string UBCT, then an ascii text line, with a command,
|
||||
some whitespace allowed. Line ends with '\n'.
|
||||
UBCT[version] [commandline] \n
|
||||
fixed string UBCT1 (for version 1), then an ascii text line,
|
||||
with a command, some whitespace allowed. Line ends with '\n'.
|
||||
|
||||
Server executes command. And sends reply in ascii text over channel,
|
||||
closes the channel when done.
|
||||
|
||||
+31
-13
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# Example configuration file.
|
||||
#
|
||||
# See unbound.conf(5) man page.
|
||||
# See unbound.conf(5) man page, version @version@.
|
||||
#
|
||||
# this is a comment.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -153,6 +147,10 @@ server:
|
||||
# Enable TCP, "yes" or "no".
|
||||
# do-tcp: yes
|
||||
|
||||
# upstream connections use TCP only (and no UDP), "yes" or "no"
|
||||
# useful for tunneling scenarios, default no.
|
||||
# tcp-upstream: no
|
||||
|
||||
# Detach from the terminal, run in background, "yes" or "no".
|
||||
# do-daemonize: yes
|
||||
|
||||
@@ -212,6 +210,9 @@ server:
|
||||
|
||||
# print UTC timestamp in ascii to logfile, default is epoch in seconds.
|
||||
# log-time-ascii: no
|
||||
|
||||
# print one line with time, IP, name, type, class for every query.
|
||||
# log-queries: no
|
||||
|
||||
# the pid file. Can be an absolute path outside of chroot/work dir.
|
||||
# pidfile: "@UNBOUND_PIDFILE@"
|
||||
@@ -257,8 +258,7 @@ server:
|
||||
# Default on, which insists on dnssec data for trust-anchored zones.
|
||||
# harden-dnssec-stripped: yes
|
||||
|
||||
# Harden against queries that fall under known nxdomain names.
|
||||
# Default off because very old software can be incompatible.
|
||||
# Harden against queries that fall under dnssec-signed nxdomain names.
|
||||
# harden-below-nxdomain: no
|
||||
|
||||
# Harden the referral path by performing additional queries for
|
||||
@@ -319,6 +319,8 @@ server:
|
||||
#
|
||||
# If you want to perform DNSSEC validation, run unbound-anchor before
|
||||
# you start unbound (i.e. in the system boot scripts). And enable:
|
||||
# Please note usage of unbound-anchor root anchor is at your own risk
|
||||
# and under the terms of our LICENSE (see that file in the source).
|
||||
# auto-trust-anchor-file: "@UNBOUND_ROOTKEY_FILE@"
|
||||
|
||||
# File with DLV trusted keys. Same format as trust-anchor-file.
|
||||
@@ -351,7 +353,7 @@ server:
|
||||
|
||||
# Override the date for validation with a specific fixed date.
|
||||
# Do not set this unless you are debugging signature inception
|
||||
# and expiration. "" or "0" turns the feature off.
|
||||
# and expiration. "" or "0" turns the feature off. -1 ignores date.
|
||||
# val-override-date: ""
|
||||
|
||||
# The time to live for bogus data, rrsets and messages. This avoids
|
||||
@@ -377,6 +379,11 @@ server:
|
||||
# replies if the message is found secure. The default is off.
|
||||
# val-permissive-mode: no
|
||||
|
||||
# Ignore the CD flag in incoming queries and refuse them bogus data.
|
||||
# Enable it if the only clients of unbound are legacy servers (w2008)
|
||||
# that set CD but cannot validate themselves.
|
||||
# ignore-cd-flag: no
|
||||
|
||||
# Have the validator log failed validations for your diagnosis.
|
||||
# 0: off. 1: A line per failed user query. 2: With reason and bad IP.
|
||||
# val-log-level: 0
|
||||
@@ -446,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.
|
||||
@@ -466,7 +484,7 @@ remote-control:
|
||||
# control-interface: ::1
|
||||
|
||||
# port number for remote control operations.
|
||||
# control-port: 953
|
||||
# control-port: 8953
|
||||
|
||||
# unbound server key file.
|
||||
# server-key-file: "@UNBOUND_RUN_DIR@/unbound_server.key"
|
||||
|
||||
@@ -26,6 +26,9 @@ Suggested usage:
|
||||
# in the init scripts.
|
||||
# provide or update the root anchor (if necessary)
|
||||
unbound-anchor -a "@UNBOUND_ROOTKEY_FILE@"
|
||||
# Please note usage of this root anchor is at your own risk
|
||||
# and under the terms of our LICENSE (see source).
|
||||
#
|
||||
# start validating resolver
|
||||
# the unbound.conf contains:
|
||||
# auto-trust-anchor-file: "@UNBOUND_ROOTKEY_FILE@"
|
||||
|
||||
@@ -151,17 +151,31 @@ and lameness data.
|
||||
Show the contents of the infra cache.
|
||||
.TP
|
||||
.B set_option \fIopt: val
|
||||
Set the option to the given value without a reload. The cache is therefore
|
||||
not flushed. The option must end with a ':' and whitespace must be between the
|
||||
option and the value. Some values may not have an effect if set this way,
|
||||
the new values are not written to the config file, not all options are supported.
|
||||
Set the option to the given value without a reload. The cache is
|
||||
therefore not flushed. The option must end with a ':' and whitespace
|
||||
must be between the option and the value. Some values may not have an
|
||||
effect if set this way, the new values are not written to the config file,
|
||||
not all options are supported. This is different from the set_option call
|
||||
in libunbound, where all values work because unbound has not been inited.
|
||||
.IP
|
||||
The values that work are: statistics\-interval, statistics\-cumulative,
|
||||
do\-not\-query\-localhost, harden\-short\-bufsize, harden\-large\-queries,
|
||||
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, ssl\-upstream.
|
||||
.TP
|
||||
.B get_option \fIopt
|
||||
Get the value of the option. Give the option name without a trailing ':'.
|
||||
The value is printed. If the value is "", nothing is printed and the
|
||||
connection closes. On error 'error ...' is printed (it gives a syntax
|
||||
error on unknown option). For some options a list of values, one on
|
||||
each line, is printed. Not all options are supported.
|
||||
The value is printed. If the value is "", nothing is printed
|
||||
and the connection closes. On error 'error ...' is printed (it gives
|
||||
a syntax error on unknown option). For some options a list of values,
|
||||
one on each line, is printed. The options are shown from the config file
|
||||
as modified with set_option. For some options an override may have been
|
||||
taken that does not show up with this command, not results from e.g. the
|
||||
verbosity and forward control commands. Not all options work, see list_stubs,
|
||||
list_forwards, list_local_zones and list_local_data for those.
|
||||
.TP
|
||||
.B list_stubs
|
||||
List the stub zones in use. These are printed one by one to the output.
|
||||
|
||||
+50
-16
@@ -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
|
||||
@@ -300,6 +292,33 @@ Enable or disable whether UDP queries are answered or issued. Default is yes.
|
||||
.B do\-tcp: \fI<yes or no>
|
||||
Enable or disable whether TCP queries are answered or issued. Default is yes.
|
||||
.TP
|
||||
.B tcp\-upstream: \fI<yes or no>
|
||||
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.
|
||||
@@ -395,6 +414,12 @@ Sets logfile lines to use a timestamp in UTC ascii. Default is no, which
|
||||
prints the seconds since 1970 in brackets. No effect if using syslog, in
|
||||
that case syslog formats the timestamp printed into the log files.
|
||||
.TP
|
||||
.B log\-queries: \fI<yes or no>
|
||||
Prints one line per query to the log, with the log timestamp and IP address,
|
||||
name, type and class. Default is no. Note that it takes time to print these
|
||||
lines which makes the server (significantly) slower. Odd (nonprintable)
|
||||
characters in names are printed as '?'.
|
||||
.TP
|
||||
.B pidfile: \fI<filename>
|
||||
The process id is written to the file. Default is "@UNBOUND_PIDFILE@".
|
||||
So,
|
||||
@@ -471,7 +496,9 @@ From draft-vixie-dnsext-resimprove, returns nxdomain to queries for a name
|
||||
below another name that is already known to be nxdomain. DNSSEC mandates
|
||||
noerror for empty nonterminals, hence this is possible. Very old software
|
||||
might return nxdomain for empty nonterminals (that usually happen for reverse
|
||||
IP address lookups), and thus may be incompatible with this. Default is off.
|
||||
IP address lookups), and thus may be incompatible with this. To try to avoid
|
||||
this only DNSSEC-secure nxdomains are used, because the old software does not
|
||||
have DNSSEC. Default is off.
|
||||
.TP
|
||||
.B harden\-referral\-path: \fI<yes or no>
|
||||
Harden the referral path by performing additional queries for
|
||||
@@ -606,7 +633,8 @@ externally can create validation failures for that internal domain.
|
||||
Default is "" or "0", which disables this debugging feature. If enabled by
|
||||
giving a RRSIG style date, that date is used for verifying RRSIG inception
|
||||
and expiration dates, instead of the current date. Do not set this unless
|
||||
you are debugging signature inception and expiration.
|
||||
you are debugging signature inception and expiration. The value \-1 ignores
|
||||
the date altogether, useful for some special applications.
|
||||
.TP
|
||||
.B val\-sig\-skew\-min: \fI<seconds>
|
||||
Minimum number of seconds of clock skew to apply to validated signatures.
|
||||
@@ -654,6 +682,14 @@ receives the bogus data. For messages that are found to be secure the AD bit
|
||||
is set in replies. Also logging is performed as for full validation.
|
||||
The default value is "no".
|
||||
.TP
|
||||
.B ignore\-cd\-flag: \fI<yes or no>
|
||||
Instruct unbound to ignore the CD flag from clients and refuse to
|
||||
return bogus answers to them. Thus, the CD (Checking Disabled) flag
|
||||
does not disable checking any more. This is useful if legacy (w2008)
|
||||
servers that set the CD flag but cannot validate DNSSEC themselves are
|
||||
the clients, and then unbound provides them with DNSSEC protection.
|
||||
The default value is "no".
|
||||
.TP
|
||||
.B val\-nsec3\-keysize\-iterations: \fI<"list of values">
|
||||
List of keysize and iteration count values, separated by spaces, surrounded
|
||||
by quotes. Default is "1024 150 2048 500 4096 2500". This determines the
|
||||
@@ -877,10 +913,9 @@ By default localhost (127.0.0.1 and ::1) is listened to.
|
||||
Use 0.0.0.0 and ::0 to listen to all interfaces.
|
||||
.TP 5
|
||||
.B control\-port: <port number>
|
||||
The port number to listen on for control commands, default is 953
|
||||
(that is the same port number named uses to listen to rndc).
|
||||
If you change this port number, and permissions have been dropped, a
|
||||
reload is not sufficient to open the port again, you must then restart.
|
||||
The port number to listen on for control commands, default is 8953.
|
||||
If you change this port number, and permissions have been dropped,
|
||||
a reload is not sufficient to open the port again, you must then restart.
|
||||
.TP 5
|
||||
.B server\-key\-file: "<private key file>"
|
||||
Path to the server private key, by default unbound_server.key.
|
||||
@@ -1003,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
|
||||
|
||||
@@ -482,3 +482,13 @@ void delegpt_no_ipv6(struct delegpt* dp)
|
||||
ns->resolved = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void delegpt_no_ipv4(struct delegpt* dp)
|
||||
{
|
||||
struct delegpt_ns* ns;
|
||||
for(ns = dp->nslist; ns; ns = ns->next) {
|
||||
/* no ipv4, so only ipv6 is enough to resolve a nameserver */
|
||||
if(ns->got6)
|
||||
ns->resolved = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -339,4 +339,11 @@ void delegpt_add_neg_msg(struct delegpt* dp, struct msgreply_entry* msg);
|
||||
*/
|
||||
void delegpt_no_ipv6(struct delegpt* dp);
|
||||
|
||||
/**
|
||||
* Register the fact that there is no ipv4 and thus As are not going
|
||||
* to be queried for or be useful.
|
||||
* @param dp: the delegation point. Updated to reflect no ipv4.
|
||||
*/
|
||||
void delegpt_no_ipv4(struct delegpt* dp);
|
||||
|
||||
#endif /* ITERATOR_ITER_DELEGPT_H */
|
||||
|
||||
+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"
|
||||
@@ -132,6 +132,7 @@ compile_time_root_prime(struct regional* r, int do_ip4, int do_ip6)
|
||||
}
|
||||
if(do_ip6) {
|
||||
if(!ah(dp, r, "A.ROOT-SERVERS.NET.", "2001:503:ba3e::2:30")) return 0;
|
||||
if(!ah(dp, r, "D.ROOT-SERVERS.NET.", "2001:500:2d::d")) return 0;
|
||||
if(!ah(dp, r, "F.ROOT-SERVERS.NET.", "2001:500:2f::f")) return 0;
|
||||
if(!ah(dp, r, "H.ROOT-SERVERS.NET.", "2001:500:1::803f:235")) return 0;
|
||||
if(!ah(dp, r, "I.ROOT-SERVERS.NET.", "2001:7fe::53")) return 0;
|
||||
|
||||
@@ -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"
|
||||
@@ -54,6 +54,8 @@ response_type_from_cache(struct dns_msg* msg,
|
||||
/* If the message is NXDOMAIN, then it is an ANSWER. */
|
||||
if(FLAGS_GET_RCODE(msg->rep->flags) == LDNS_RCODE_NXDOMAIN)
|
||||
return RESPONSE_TYPE_ANSWER;
|
||||
if(request->qtype == LDNS_RR_TYPE_ANY)
|
||||
return RESPONSE_TYPE_ANSWER;
|
||||
|
||||
/* First we look at the answer section. This can tell us if this is
|
||||
* CNAME or positive ANSWER. */
|
||||
@@ -117,6 +119,15 @@ response_type_from_server(int rdset,
|
||||
if( (msg->rep->flags&BIT_RA) &&
|
||||
!(msg->rep->flags&BIT_AA) && !rdset)
|
||||
return RESPONSE_TYPE_REC_LAME;
|
||||
/* it could be a CNAME with NXDOMAIN rcode */
|
||||
for(i=0; i<msg->rep->an_numrrsets; i++) {
|
||||
s = msg->rep->rrsets[i];
|
||||
if(ntohs(s->rk.type) == LDNS_RR_TYPE_CNAME &&
|
||||
query_dname_compare(request->qname,
|
||||
s->rk.dname) == 0) {
|
||||
return RESPONSE_TYPE_CNAME;
|
||||
}
|
||||
}
|
||||
return RESPONSE_TYPE_ANSWER;
|
||||
}
|
||||
|
||||
@@ -152,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;
|
||||
}
|
||||
|
||||
@@ -179,6 +192,9 @@ response_type_from_server(int rdset,
|
||||
get_cname_target(s, &mname, &mname_len);
|
||||
}
|
||||
}
|
||||
/* not a referral, and qtype any, thus an answer */
|
||||
if(request->qtype == LDNS_RR_TYPE_ANY)
|
||||
return RESPONSE_TYPE_ANSWER;
|
||||
/* if we encountered a CNAME (or a bunch of CNAMEs), and
|
||||
* still got to here, then it is a CNAME response.
|
||||
* (This is regardless of the AA bit at this point) */
|
||||
|
||||
+18
-13
@@ -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;
|
||||
}
|
||||
@@ -363,10 +366,6 @@ scrub_normalize(ldns_buffer* pkt, struct msg_parse* msg,
|
||||
"too long");
|
||||
return 0;
|
||||
}
|
||||
/* internally we have CNAME'd/DNAME'd chains ending
|
||||
* in nxdomain with NOERROR rcode, change rcode
|
||||
* to reflect this (if needed) */
|
||||
FLAGS_SET_RCODE(msg->flags, LDNS_RCODE_NOERROR);
|
||||
if(nx && nx->type == LDNS_RR_TYPE_CNAME &&
|
||||
dname_pkt_compare(pkt, sname, nx->dname) == 0) {
|
||||
/* check next cname */
|
||||
@@ -405,14 +404,21 @@ scrub_normalize(ldns_buffer* pkt, struct msg_parse* msg,
|
||||
|
||||
/* Follow the CNAME chain. */
|
||||
if(rrset->type == LDNS_RR_TYPE_CNAME) {
|
||||
uint8_t* oldsname = sname;
|
||||
if(!parse_get_cname_target(rrset, &sname, &snamelen))
|
||||
return 0;
|
||||
prev = rrset;
|
||||
rrset = rrset->rrset_all_next;
|
||||
/* internally we have CNAME'd/DNAME'd chains ending
|
||||
* in nxdomain with NOERROR rcode, change rcode
|
||||
* to reflect this (if needed) */
|
||||
FLAGS_SET_RCODE(msg->flags, LDNS_RCODE_NOERROR);
|
||||
/* in CNAME ANY response, can have data after CNAME */
|
||||
if(qinfo->qtype == LDNS_RR_TYPE_ANY) {
|
||||
while(rrset && rrset->section ==
|
||||
LDNS_SECTION_ANSWER &&
|
||||
dname_pkt_compare(pkt, oldsname,
|
||||
rrset->dname) == 0) {
|
||||
prev = rrset;
|
||||
rrset = rrset->rrset_all_next;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -529,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) */
|
||||
@@ -643,9 +648,9 @@ scrub_sanitize(ldns_buffer* pkt, struct msg_parse* msg,
|
||||
if( (rrset->type == LDNS_RR_TYPE_A ||
|
||||
rrset->type == LDNS_RR_TYPE_AAAA) &&
|
||||
priv_rrset_bad(ie->priv, pkt, rrset)) {
|
||||
/* set servfail, so the classification becomes
|
||||
* THROWAWAY, instead of LAME or other unwanted */
|
||||
FLAGS_SET_RCODE(msg->flags, LDNS_RCODE_SERVFAIL);
|
||||
|
||||
/* do not set servfail since this leads to too
|
||||
* many drops of other people using rfc1918 space */
|
||||
remove_rrset("sanitize: removing public name with "
|
||||
"private address", pkt, msg, prev, &rrset);
|
||||
continue;
|
||||
|
||||
@@ -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;
|
||||
|
||||
+16
-4
@@ -132,6 +132,7 @@ iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg)
|
||||
return 0;
|
||||
}
|
||||
iter_env->supports_ipv6 = cfg->do_ip6;
|
||||
iter_env->supports_ipv4 = cfg->do_ip4;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -150,6 +151,7 @@ iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg)
|
||||
* o The address is bogus (DNSSEC validation failure).
|
||||
* o Listed as donotquery
|
||||
* o is ipv6 but no ipv6 support (in operating system).
|
||||
* o is ipv4 but no ipv4 support (in operating system).
|
||||
* o is lame
|
||||
* Otherwise, an rtt in milliseconds.
|
||||
* 0 .. USEFUL_SERVER_TOP_TIMEOUT-1
|
||||
@@ -194,6 +196,9 @@ iter_filter_unsuitable(struct iter_env* iter_env, struct module_env* env,
|
||||
if(!iter_env->supports_ipv6 && addr_is_ip6(&a->addr, a->addrlen)) {
|
||||
return -1; /* there is no ip6 available */
|
||||
}
|
||||
if(!iter_env->supports_ipv4 && !addr_is_ip6(&a->addr, a->addrlen)) {
|
||||
return -1; /* there is no ip4 available */
|
||||
}
|
||||
/* check lameness - need zone , class info */
|
||||
if(infra_get_lame_rtt(env->infra_cache, &a->addr, a->addrlen,
|
||||
name, namelen, qtype, &lame, &dnsseclame, &reclame,
|
||||
@@ -207,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 */
|
||||
@@ -415,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.
|
||||
|
||||
+32
-13
@@ -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);
|
||||
}
|
||||
@@ -1367,7 +1369,7 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
query_count++;
|
||||
}
|
||||
/* Send the A request. */
|
||||
if(!ns->got4) {
|
||||
if(ie->supports_ipv4 && !ns->got4) {
|
||||
if(!generate_target_query(qstate, iq, id,
|
||||
ns->name, ns->namelen,
|
||||
LDNS_RR_TYPE_A, iq->qchase.qclass)) {
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -1476,7 +1479,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
ns->done_pside6 = 1;
|
||||
query_count++;
|
||||
}
|
||||
if(!ns->done_pside4) {
|
||||
if(ie->supports_ipv4 && !ns->done_pside4) {
|
||||
/* Send the A request. */
|
||||
if(!generate_parentside_target_query(qstate, iq, id,
|
||||
ns->name, ns->namelen,
|
||||
@@ -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 */
|
||||
@@ -1556,6 +1564,8 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
}
|
||||
if(!ie->supports_ipv6)
|
||||
delegpt_no_ipv6(iq->dp);
|
||||
if(!ie->supports_ipv4)
|
||||
delegpt_no_ipv4(iq->dp);
|
||||
delegpt_log(VERB_ALGO, iq->dp);
|
||||
|
||||
if(iq->num_current_queries>0) {
|
||||
@@ -1571,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];
|
||||
}
|
||||
|
||||
@@ -1594,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.",
|
||||
@@ -1603,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;
|
||||
}
|
||||
@@ -1710,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);
|
||||
@@ -1718,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;
|
||||
@@ -1817,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);
|
||||
@@ -1856,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)
|
||||
@@ -1894,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,
|
||||
@@ -1941,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;
|
||||
@@ -1951,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
|
||||
@@ -2416,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.
|
||||
*/
|
||||
@@ -93,6 +97,9 @@ struct iter_env {
|
||||
/** A flag to indicate whether or not we have an IPv6 route */
|
||||
int supports_ipv6;
|
||||
|
||||
/** A flag to indicate whether or not we have an IPv4 route */
|
||||
int supports_ipv4;
|
||||
|
||||
/** A set of inetaddrs that should never be queried. */
|
||||
struct iter_donotq* donotq;
|
||||
|
||||
@@ -249,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.
|
||||
|
||||
Binary file not shown.
@@ -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;
|
||||
}
|
||||
|
||||
+34
-9
@@ -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,7 +718,8 @@ 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,
|
||||
addr, addrlen, libworker_handle_service_reply, e,
|
||||
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
|
||||
|
||||
+26
-3
@@ -56,6 +56,7 @@ Generate a distribution tar file for unbound.
|
||||
-l ldnsdir Directory where ldns resides. Detected from Makefile.
|
||||
-wssl openssl.xx.tar.gz Also build openssl from tarball for windows dist.
|
||||
-wxp expat.xx.tar.gz Also build expat from tarball for windows dist.
|
||||
-wldns ldns.xx.tar.gz Also build libldns from tarball for windows dist.
|
||||
-w ... Build windows binary dist. last args passed to configure.
|
||||
EOF
|
||||
exit 1
|
||||
@@ -137,6 +138,7 @@ LDNSDIR=""
|
||||
DOWIN="no"
|
||||
WINSSL=""
|
||||
WINEXPAT=""
|
||||
WINLDNS=""
|
||||
|
||||
# Parse the command line arguments.
|
||||
while [ "$1" ]; do
|
||||
@@ -151,6 +153,10 @@ while [ "$1" ]; do
|
||||
"-s")
|
||||
SNAPSHOT="yes"
|
||||
;;
|
||||
"-wldns")
|
||||
WINLDNS="$2"
|
||||
shift
|
||||
;;
|
||||
"-wssl")
|
||||
WINSSL="$2"
|
||||
shift
|
||||
@@ -187,8 +193,8 @@ if [ "$DOWIN" = "yes" ]; then
|
||||
configure="mingw32-configure"
|
||||
strip="i686-pc-mingw32-strip"
|
||||
makensis="makensis" # from mingw32-nsis package
|
||||
# in crosscompile no installed ldns, use builtin (not linux-ldns)
|
||||
cross_flag="--with-ldns-builtin"
|
||||
# flags for crosscompiled dependency libraries
|
||||
cross_flag=""
|
||||
|
||||
check_svn_root
|
||||
create_temp_dir
|
||||
@@ -214,6 +220,21 @@ if [ "$DOWIN" = "yes" ]; then
|
||||
cd ..
|
||||
fi
|
||||
|
||||
if test -n "$WINLDNS"; then
|
||||
info "Cross compile $WINLDNS"
|
||||
info "ldns tar unpack"
|
||||
(cd ..; gzip -cd $WINLDNS) | tar xf - || error_cleanup "tar unpack of $WINLDNS failed"
|
||||
cd ldns-* || error_cleanup "no ldns-X dir in tarball"
|
||||
# we can use the cross_flag with openssl in it
|
||||
info "ldns: Configure $cross_flag"
|
||||
mingw32-configure $cross_flag || error_cleanup "ldns configure failed"
|
||||
info "ldns: make"
|
||||
make || error_cleanup "ldns crosscompile failed"
|
||||
# use from the build directory.
|
||||
cross_flag="$cross_flag --with-ldns=`pwd`"
|
||||
cd ..
|
||||
fi
|
||||
|
||||
if test -n "$WINEXPAT"; then
|
||||
info "Cross compile $WINEXPAT"
|
||||
info "wxp: tar unpack"
|
||||
@@ -259,7 +280,8 @@ if [ "$DOWIN" = "yes" ]; then
|
||||
replace_text "configure.ac" "AC_INIT(unbound, $version" "AC_INIT(unbound, $version2"
|
||||
version="$version2"
|
||||
info "Rebuilding configure script (autoconf) snapshot."
|
||||
autoconf || autoheader || error_cleanup "Autoconf failed."
|
||||
autoconf || error_cleanup "Autoconf failed."
|
||||
autoheader || error_cleanup "Autoheader failed."
|
||||
rm -r autom4te* || echo "ignored"
|
||||
fi
|
||||
|
||||
@@ -410,6 +432,7 @@ replace_all doc/unbound-checkconf.8.in
|
||||
replace_all doc/unbound-control.8.in
|
||||
replace_all doc/unbound-anchor.8.in
|
||||
replace_all doc/unbound-host.1
|
||||
replace_all doc/example.conf.in
|
||||
replace_all doc/libunbound.3.in
|
||||
|
||||
info "Renaming Unbound directory to unbound-$version."
|
||||
|
||||
@@ -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;
|
||||
@@ -868,6 +866,15 @@ void log_dns_msg(const char* str, struct query_info* qinfo, struct reply_info* r
|
||||
void log_query_info(enum verbosity_value v, const char* str, struct query_info* qinf);
|
||||
void regional_log_stats(struct regional *r);
|
||||
|
||||
// Free allocated memory from marked sources returning corresponding types
|
||||
%typemap(newfree, noblock = 1) char * {
|
||||
free($1);
|
||||
}
|
||||
|
||||
// Mark as source returning newly allocated memory
|
||||
%newobject ldns_rr_type2str;
|
||||
%newobject ldns_rr_class2str;
|
||||
|
||||
// LDNS functions
|
||||
char *ldns_rr_type2str(const uint16_t atype);
|
||||
char *ldns_rr_class2str(const uint16_t aclass);
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
#include "ldns/ldns.h"
|
||||
#include <ldns/ldns.h>
|
||||
|
||||
#undef _POSIX_C_SOURCE
|
||||
#undef _XOPEN_SOURCE
|
||||
@@ -153,6 +153,8 @@ int pythonmod_init(struct module_env* env, int id)
|
||||
}
|
||||
PyRun_SimpleString("sys.path.append('"RUN_DIR"') \n");
|
||||
PyRun_SimpleString("sys.path.append('"SHARE_DIR"') \n");
|
||||
PyRun_SimpleString("import distutils.sysconfig \n");
|
||||
PyRun_SimpleString("sys.path.append(distutils.sysconfig.get_python_lib(1,0)) \n");
|
||||
if (PyRun_SimpleString("from unboundmodule import *\n") < 0)
|
||||
{
|
||||
log_err("pythonmod: cannot initialize core module: unboundmodule.py");
|
||||
|
||||
@@ -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
+37
-9
@@ -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 */
|
||||
@@ -685,7 +712,7 @@ dns_cache_lookup(struct module_env* env,
|
||||
struct reply_info* data = (struct reply_info*)e->data;
|
||||
struct dns_msg* msg;
|
||||
if(FLAGS_GET_RCODE(data->flags) == LDNS_RCODE_NXDOMAIN
|
||||
&& data->security != sec_status_bogus
|
||||
&& data->security == sec_status_secure
|
||||
&& (msg=tomsg(env, &k, data, region, now, scratch))){
|
||||
lock_rw_unlock(&e->lock);
|
||||
msg->qinfo.qname=qname;
|
||||
@@ -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
-1
@@ -207,7 +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);
|
||||
return 1;
|
||||
return 2;
|
||||
}
|
||||
lock_rw_unlock(&e->lock);
|
||||
/* Go on and insert the passed item.
|
||||
|
||||
Vendored
+3
@@ -125,6 +125,9 @@ 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.
|
||||
*/
|
||||
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"
|
||||
@@ -612,6 +612,8 @@ lz_enter_defaults(struct local_zones* zones, struct config_file* cfg,
|
||||
{
|
||||
struct local_zone* z;
|
||||
|
||||
/* this list of zones is from RFC 6303 */
|
||||
|
||||
/* localhost. zone */
|
||||
if(!lz_exists(zones, "localhost.") &&
|
||||
!lz_nodefault(cfg, "localhost.")) {
|
||||
|
||||
+73
-22
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -270,13 +277,17 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
uint16_t qflags, struct edns_data* edns, struct comm_reply* rep,
|
||||
uint16_t qid)
|
||||
{
|
||||
struct mesh_state* s = mesh_area_find(mesh, qinfo, qflags, 0);
|
||||
/* do not use CD flag from user for mesh state, we want the CD-query
|
||||
* to receive validation anyway, to protect out cache contents and
|
||||
* avoid bad-data in this cache that a downstream validator cannot
|
||||
* remove from this cache */
|
||||
struct mesh_state* s = mesh_area_find(mesh, qinfo, qflags&BIT_RD, 0);
|
||||
int was_detached = 0;
|
||||
int was_noreply = 0;
|
||||
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);
|
||||
@@ -297,8 +308,10 @@ 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;
|
||||
s = mesh_state_create(mesh->env, qinfo, qflags, 0);
|
||||
#endif
|
||||
s = mesh_state_create(mesh->env, qinfo, qflags&BIT_RD, 0);
|
||||
if(!s) {
|
||||
log_err("mesh_state_create: out of memory; SERVFAIL");
|
||||
error_encode(rep->c->buffer, LDNS_RCODE_SERVFAIL,
|
||||
@@ -306,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++;
|
||||
@@ -357,7 +373,7 @@ mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
uint16_t qflags, struct edns_data* edns, ldns_buffer* buf,
|
||||
uint16_t qid, mesh_cb_func_t cb, void* cb_arg)
|
||||
{
|
||||
struct mesh_state* s = mesh_area_find(mesh, qinfo, qflags, 0);
|
||||
struct mesh_state* s = mesh_area_find(mesh, qinfo, qflags&BIT_RD, 0);
|
||||
int was_detached = 0;
|
||||
int was_noreply = 0;
|
||||
int added = 0;
|
||||
@@ -365,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;
|
||||
s = mesh_state_create(mesh->env, qinfo, qflags, 0);
|
||||
#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++;
|
||||
@@ -403,8 +424,10 @@ mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
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, 0);
|
||||
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) {
|
||||
@@ -415,17 +438,20 @@ 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;
|
||||
}
|
||||
s = mesh_state_create(mesh->env, qinfo, qflags, 0);
|
||||
s = mesh_state_create(mesh->env, qinfo, qflags&BIT_RD, 0);
|
||||
if(!s) {
|
||||
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++;
|
||||
@@ -524,22 +550,24 @@ mesh_state_cleanup(struct mesh_state* mstate)
|
||||
int i;
|
||||
if(!mstate)
|
||||
return;
|
||||
mesh = mstate->s.env->mesh;
|
||||
/* drop unsent replies */
|
||||
if(!mstate->replies_sent) {
|
||||
struct mesh_reply* rep;
|
||||
struct mesh_cb* cb;
|
||||
for(rep=mstate->reply_list; rep; rep=rep->next) {
|
||||
comm_point_drop_reply(&rep->query_reply);
|
||||
mesh->num_reply_addrs--;
|
||||
}
|
||||
for(cb=mstate->cb_list; cb; cb=cb->next) {
|
||||
fptr_ok(fptr_whitelist_mesh_cb(cb->cb));
|
||||
(*cb->cb)(cb->cb_arg, LDNS_RCODE_SERVFAIL, NULL,
|
||||
sec_status_unchecked, NULL);
|
||||
mesh->num_reply_addrs--;
|
||||
}
|
||||
}
|
||||
|
||||
/* de-init modules */
|
||||
mesh = mstate->s.env->mesh;
|
||||
for(i=0; i<mesh->mods.num; i++) {
|
||||
fptr_ok(fptr_whitelist_mod_clear(mesh->mods.mod[i]->clear));
|
||||
(*mesh->mods.mod[i]->clear)(&mstate->s, i);
|
||||
@@ -621,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) {
|
||||
@@ -648,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
|
||||
@@ -678,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,
|
||||
@@ -692,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;
|
||||
}
|
||||
@@ -768,7 +817,8 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
|
||||
struct timeval duration;
|
||||
int secure;
|
||||
/* examine security status */
|
||||
if(m->s.env->need_to_validate && !(r->qflags&BIT_CD) && rep &&
|
||||
if(m->s.env->need_to_validate && (!(r->qflags&BIT_CD) ||
|
||||
m->s.env->cfg->ignore_cd) && rep &&
|
||||
rep->security <= sec_status_bogus) {
|
||||
rcode = LDNS_RCODE_SERVFAIL;
|
||||
if(m->s.env->cfg->stat_extended)
|
||||
@@ -1094,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.
|
||||
|
||||
+138
-32
@@ -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;
|
||||
@@ -1693,10 +1793,10 @@ callback_list_find(struct serviced_query* sq, void* cb_arg,
|
||||
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,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
comm_point_callback_t* callback, void* callback_arg,
|
||||
ldns_buffer* buff, int (*arg_compare)(void*,void*))
|
||||
uint16_t flags, int dnssec, int want_dnssec, int tcp_upstream,
|
||||
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) {
|
||||
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.
|
||||
@@ -435,10 +455,16 @@ void pending_delete(struct outside_network* outnet, struct pending* p);
|
||||
* If the value includes BIT_DO, DO bit is set when in EDNS queries.
|
||||
* @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.
|
||||
@@ -447,10 +473,11 @@ 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,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
comm_point_callback_t* callback, void* callback_arg,
|
||||
ldns_buffer* buff, int (*arg_compare)(void*,void*));
|
||||
uint16_t flags, int dnssec, int want_dnssec, int tcp_upstream,
|
||||
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);
|
||||
|
||||
@@ -318,7 +318,7 @@ morechecks(struct config_file* cfg, const char* fname)
|
||||
|
||||
if(cfg->verbosity < 0)
|
||||
fatal_exit("verbosity value < 0");
|
||||
if(cfg->num_threads < 0 || cfg->num_threads > 10000)
|
||||
if(cfg->num_threads <= 0 || cfg->num_threads > 10000)
|
||||
fatal_exit("num_threads value weird");
|
||||
if(!cfg->do_ip4 && !cfg->do_ip6)
|
||||
fatal_exit("ip4 and ip6 are both disabled, pointless");
|
||||
|
||||
@@ -81,7 +81,7 @@ while test $# -ne 0; do
|
||||
echo " -d dir use directory to store keys and certificates."
|
||||
echo " default: $DESTDIR"
|
||||
echo "please run this command using the same user id that the "
|
||||
echo "unboun daemon uses, it needs read privileges."
|
||||
echo "unbound daemon uses, it needs read privileges."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -258,12 +258,13 @@ send_file(SSL* ssl, FILE* in, char* buf, size_t sz)
|
||||
static int
|
||||
go_cmd(SSL* ssl, int argc, char* argv[])
|
||||
{
|
||||
const char* pre="UBCT";
|
||||
char pre[10];
|
||||
const char* space=" ";
|
||||
const char* newline="\n";
|
||||
int was_error = 0, first_line = 1;
|
||||
int r, i;
|
||||
char buf[1024];
|
||||
snprintf(pre, sizeof(pre), "UBCT%d ", UNBOUND_CONTROL_VERSION);
|
||||
if(SSL_write(ssl, pre, (int)strlen(pre)) <= 0)
|
||||
ssl_err("could not SSL_write");
|
||||
for(i=0; i<argc; i++) {
|
||||
|
||||
@@ -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(" ");
|
||||
|
||||
+10
-38
@@ -1,8 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
. testdata/common.sh
|
||||
|
||||
NEED_SPLINT='00-lint.tpkg'
|
||||
NEED_DOXYGEN='01-doc.tpkg'
|
||||
NEED_LDNS_TESTNS='fwd_no_edns.tpkg fwd_tcp_tc.tpkg fwd_tcp.tpkg fwd_three_service.tpkg fwd_three.tpkg fwd_ttlexpire.tpkg fwd_udp.tpkg fwd_tcp_tc6.tpkg fwd_compress_c00c.tpkg fwd_ancil.tpkg stat_timer.tpkg 05-asynclook.tpkg stream_tcp.tpkg speed_cache.tpkg fwd_oneport.tpkg fwd_udptmout.tpkg fwd_waitudp.tpkg tcp_sigpipe.tpkg hostsfileosx.tpkg local_nodefault.tpkg fwd_zero.tpkg'
|
||||
NEED_XXD='fwd_compress_c00c.tpkg fwd_zero.tpkg'
|
||||
NEED_NC='fwd_compress_c00c.tpkg fwd_zero.tpkg'
|
||||
NEED_CURL='06-ianaports.tpkg root_anchor.tpkg'
|
||||
@@ -11,8 +11,8 @@ NEED_IPV6='fwd_ancil.tpkg fwd_tcp_tc6.tpkg stub_udp6.tpkg edns_cache.tpkg'
|
||||
NEED_NOMINGW='tcp_sigpipe.tpkg 07-confroot.tpkg 08-host-lib.tpkg fwd_ancil.tpkg'
|
||||
|
||||
# test if dig and ldns-testns are available.
|
||||
if test ! -x "`which dig 2>&1`"; then echo No 'dig' in path; exit 1; fi
|
||||
if test ! -x "`which ldns-testns 2>&1`"; then echo No 'ldns-testns' in path; exit 1; fi
|
||||
test_tool_avail "dig"
|
||||
test_tool_avail "ldns-testns"
|
||||
|
||||
# test for ipv6, uses streamptcp peculiarity.
|
||||
if ./streamtcp -f ::1 2>&1 | grep "not supported" >/dev/null 2>&1; then
|
||||
@@ -33,41 +33,13 @@ sh ../testcode/mini_tpkg.sh clean
|
||||
rm -f .perfstats.txt
|
||||
for test in `ls *.tpkg`; do
|
||||
SKIP=0
|
||||
if echo $NEED_SPLINT | grep $test >/dev/null; then
|
||||
if test ! -x "`which splint`"; then
|
||||
SKIP=1;
|
||||
fi
|
||||
fi
|
||||
if echo $NEED_DOXYGEN | grep $test >/dev/null; then
|
||||
if test ! -x "`which doxygen`"; then
|
||||
SKIP=1;
|
||||
fi
|
||||
fi
|
||||
if echo $NEED_CURL | grep $test >/dev/null; then
|
||||
if test ! -x "`which curl`"; then
|
||||
SKIP=1;
|
||||
fi
|
||||
fi
|
||||
if echo $NEED_LDNS_TESTNS | grep $test >/dev/null; then
|
||||
if test ! -x "`which ldns-testns`"; then
|
||||
SKIP=1;
|
||||
fi
|
||||
fi
|
||||
if echo $NEED_XXD | grep $test >/dev/null; then
|
||||
if test ! -x "`which xxd`"; then
|
||||
SKIP=1;
|
||||
fi
|
||||
fi
|
||||
if echo $NEED_NC | grep $test >/dev/null; then
|
||||
if test ! -x "`which nc`"; then
|
||||
SKIP=1;
|
||||
fi
|
||||
fi
|
||||
if echo $NEED_WHOAMI | grep $test >/dev/null; then
|
||||
if test ! -x "`which whoami`"; then
|
||||
SKIP=1;
|
||||
fi
|
||||
fi
|
||||
skip_if_in_list $test "$NEED_SPLINT" "splint"
|
||||
skip_if_in_list $test "$NEED_DOXYGEN" "doxygen"
|
||||
skip_if_in_list $test "$NEED_CURL" "curl"
|
||||
skip_if_in_list $test "$NEED_XXD" "xxd"
|
||||
skip_if_in_list $test "$NEED_NC" "nc"
|
||||
skip_if_in_list $test "$NEED_WHOAMI" "whoami"
|
||||
|
||||
if echo $NEED_IPV6 | grep $test >/dev/null; then
|
||||
if test "$HAVE_IPV6" = no; then
|
||||
SKIP=1;
|
||||
|
||||
+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),
|
||||
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
|
||||
|
||||
@@ -81,6 +81,8 @@ mv $name.dir/* .
|
||||
|
||||
# EXE
|
||||
echo "minitpkg exe $name" > $result
|
||||
grep "Description:" $name.dsc >> $result 2>&1
|
||||
echo "DateRunStart: "`date "+%s" 2>/dev/null` >> $result
|
||||
if test -f $name.pre; then
|
||||
echo "minitpkg exe $name.pre"
|
||||
echo "minitpkg exe $name.pre" >> $result
|
||||
@@ -112,6 +114,7 @@ if test -f $name.post; then
|
||||
echo "Warning: $name.post did not exit successfully"
|
||||
fi
|
||||
fi
|
||||
echo "DateRunEnd: "`date "+%s" 2>/dev/null` >> $result
|
||||
|
||||
mv $result ..
|
||||
cd ..
|
||||
|
||||
+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
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
+256
@@ -0,0 +1,256 @@
|
||||
# common.sh - an include file for commonly used functions for test code.
|
||||
# BSD licensed (see LICENSE file).
|
||||
#
|
||||
# Version 3
|
||||
# 2011-02-23: get_pcat for PCAT, PCAT_DIFF and PCAT_PRINT defines.
|
||||
# 2011-02-18: ports check on BSD,Solaris. wait_nsd_up.
|
||||
# 2011-02-11: first version.
|
||||
#
|
||||
# include this file from a tpkg script with
|
||||
# . ../common.sh
|
||||
#
|
||||
# overview of functions available:
|
||||
# error x : print error and exit
|
||||
# info x : print info
|
||||
# test_tool_avail x : see if program in path and complain, exit if not.
|
||||
# get_ldns_testns : set LDNS_TESTNS to executable ldns-testns
|
||||
# get_make : set MAKE to gmake or make tool.
|
||||
# get_gcc : set cc or gcc in CC
|
||||
# get_pcat : set PCAT, PCAT_DIFF and PCAT_PRINT executables.
|
||||
# set_doxygen_path : set doxygen path
|
||||
# skip_if_in_list : set SKIP=1 if name in list and tool not available.
|
||||
# get_random_port x : get RND_PORT a sequence of free random port numbers.
|
||||
# wait_server_up : wait on logfile to see when server comes up.
|
||||
# wait_ldns_testns_up : wait for ldns-testns to come up.
|
||||
# wait_unbound_up : wait for unbound to come up.
|
||||
# wait_petal_up : wait for petal to come up.
|
||||
# wait_nsd_up : wait for nsd to come up.
|
||||
# wait_server_up_or_fail: wait for server to come up or print a failure string
|
||||
# kill_pid : kill a server, make sure and wait for it to go down.
|
||||
|
||||
|
||||
# print error and exit
|
||||
# $0: name of program
|
||||
# $1: error to printout.
|
||||
error () {
|
||||
echo "$0: error: $1" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# print info
|
||||
# $0: name of program
|
||||
# $1: to printout.
|
||||
info () {
|
||||
echo "$0: info: $1"
|
||||
}
|
||||
|
||||
# test if 'tool' is available in path and complain otherwise.
|
||||
# $1: tool
|
||||
test_tool_avail () {
|
||||
if test ! -x "`which $1 2>&1`"; then
|
||||
echo No "$1" in path
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# get ldns-testns tool in LDNS_TESTNS variable.
|
||||
get_ldns_testns () {
|
||||
if test -x "`which ldns-testns 2>&1`"; then
|
||||
LDNS_TESTNS=ldns-testns
|
||||
else
|
||||
LDNS_TESTNS=/home/wouter/bin/ldns-testns
|
||||
fi
|
||||
}
|
||||
|
||||
# get make tool in MAKE variable, gmake is used if present.
|
||||
get_make () {
|
||||
if test -x "`which gmake 2>&1`"; then
|
||||
MAKE=gmake
|
||||
else
|
||||
MAKE=make
|
||||
fi
|
||||
}
|
||||
|
||||
# get cc tool in CC variable, gcc is used if present.
|
||||
get_gcc () {
|
||||
if test -x "`which gcc 2>&1`"; then
|
||||
CC=gcc
|
||||
else
|
||||
CC=cc
|
||||
fi
|
||||
}
|
||||
|
||||
# get pcat, pcat-print and pcat-diff
|
||||
get_pcat () {
|
||||
PCAT=`which pcat`
|
||||
PCAT_PRINT=`which pcat-print`
|
||||
PCAT_DIFF=`which pcat-diff`
|
||||
}
|
||||
|
||||
# set SKIP=1 if the name is in list and tool is not available.
|
||||
# $1: name of package to check.
|
||||
# $2: list of packages that need the tool.
|
||||
# #3: name of the tool required.
|
||||
skip_if_in_list () {
|
||||
if echo $2 | grep $1 >/dev/null; then
|
||||
if test ! -x "`which $3 2>&1`"; then
|
||||
SKIP=1;
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# function to get a number of random port numbers.
|
||||
# $1: number of random ports.
|
||||
# RND_PORT is returned as the starting port number
|
||||
get_random_port () {
|
||||
local plist
|
||||
local cont
|
||||
local collisions
|
||||
local i
|
||||
local MAXCOLLISION=1000
|
||||
cont=1
|
||||
collisions=0
|
||||
while test "$cont" = 1; do
|
||||
#netstat -n -A ip -A ip6 -a | sed -e "s/^.*:\([0-9]*\) .*$/\1/"
|
||||
RND_PORT=$(( $RANDOM + 5354 ))
|
||||
# depending on uname try to check for collisions in port numbers
|
||||
case "`uname`" in
|
||||
linux|Linux)
|
||||
plist=`netstat -n -A ip -A ip6 -a | sed -e 's/^.*:\([0-9]*\) .*$/\1/'`
|
||||
;;
|
||||
FreeBSD|freebsd|NetBSD|netbsd|OpenBSD|openbsd)
|
||||
plist=`netstat -n -a | grep "^[ut][dc]p[46] " | sed -e 's/^.*\.\([0-9]*\) .*$/\1/'`
|
||||
;;
|
||||
Solaris|SunOS)
|
||||
plist=`netstat -n -a | sed -e 's/^.*\.\([0-9]*\) .*$/\1/' | grep '^[0-9]*$'`
|
||||
;;
|
||||
*)
|
||||
plist=""
|
||||
;;
|
||||
esac
|
||||
cont=0
|
||||
for (( i=0 ; i < $1 ; i++ )); do
|
||||
if echo "$plist" | grep '^'`expr $i + $RND_PORT`'$' >/dev/null 2>&1; then
|
||||
cont=1;
|
||||
collisions=`expr $collisions + 1`
|
||||
fi
|
||||
done
|
||||
if test $collisions = $MAXCOLLISION; then
|
||||
error "too many collisions getting random port number"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# wait for server to go up, pass <logfilename> <string to watch>
|
||||
# $1 : logfilename
|
||||
# $2 : string to watch for.
|
||||
# exits with failure if it does not come up
|
||||
wait_server_up () {
|
||||
local MAX_UP_TRY=120
|
||||
local WAIT_THRES=30
|
||||
local try
|
||||
for (( try=0 ; try <= $MAX_UP_TRY ; try++ )) ; do
|
||||
if test -f $1 && fgrep "$2" $1 >/dev/null; then
|
||||
#echo "done on try $try"
|
||||
break;
|
||||
fi
|
||||
if test $try -eq $MAX_UP_TRY; then
|
||||
echo "Server in $1 did not go up!"
|
||||
cat $1
|
||||
exit 1;
|
||||
fi
|
||||
if test $try -ge $WAIT_THRES; then
|
||||
sleep 1
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# wait for ldns-testns to come up
|
||||
# $1 : logfilename that is watched.
|
||||
wait_ldns_testns_up () {
|
||||
wait_server_up "$1" "Listening on port"
|
||||
}
|
||||
|
||||
# wait for unbound to come up
|
||||
# string 'Start of service' in log.
|
||||
# $1 : logfilename that is watched.
|
||||
wait_unbound_up () {
|
||||
wait_server_up "$1" "start of service"
|
||||
}
|
||||
|
||||
# wait for petal to come up
|
||||
# string 'petal start' in log.
|
||||
# $1 : logfilename that is watched.
|
||||
wait_petal_up () {
|
||||
wait_server_up "$1" "petal start"
|
||||
}
|
||||
|
||||
# wait for nsd to come up
|
||||
# string nsd start in log.
|
||||
# $1 : logfilename that is watched.
|
||||
wait_nsd_up () {
|
||||
wait_server_up "$1" " started (NSD "
|
||||
}
|
||||
|
||||
# wait for server to go up, pass <logfilename> <string to watch> <badstr>
|
||||
# $1 : logfile
|
||||
# $2 : success string
|
||||
# $3 : failure string
|
||||
wait_server_up_or_fail () {
|
||||
local MAX_UP_TRY=120
|
||||
local WAIT_THRES=30
|
||||
local try
|
||||
for (( try=0 ; try <= $MAX_UP_TRY ; try++ )) ; do
|
||||
if test -f $1 && fgrep "$2" $1 >/dev/null; then
|
||||
echo "done on try $try"
|
||||
break;
|
||||
fi
|
||||
if test -f $1 && fgrep "$3" $1 >/dev/null; then
|
||||
echo "failed on try $try"
|
||||
break;
|
||||
fi
|
||||
if test $try -eq $MAX_UP_TRY; then
|
||||
echo "Server in $1 did not go up!"
|
||||
cat $1
|
||||
exit 1;
|
||||
fi
|
||||
if test $try -ge $WAIT_THRES; then
|
||||
sleep 1
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# kill a pid, make sure and wait for it to go down.
|
||||
# $1 : pid to kill
|
||||
kill_pid () {
|
||||
local MAX_DOWN_TRY=120
|
||||
local WAIT_THRES=30
|
||||
local try
|
||||
kill $1
|
||||
for (( try=0 ; try <= $MAX_DOWN_TRY ; try++ )) ; do
|
||||
if kill -0 $1 >/dev/null 2>&1; then
|
||||
:
|
||||
else
|
||||
#echo "done on try $try"
|
||||
break;
|
||||
fi
|
||||
if test $try -eq $MAX_DOWN_TRY; then
|
||||
echo "Server in $1 did not go down! Send SIGKILL"
|
||||
kill -9 $1 >/dev/null 2>&1
|
||||
fi
|
||||
if test $try -ge $WAIT_THRES; then
|
||||
sleep 1
|
||||
fi
|
||||
# re-send the signal
|
||||
kill $1 >/dev/null 2>&1
|
||||
done
|
||||
return 0
|
||||
}
|
||||
|
||||
# set doxygen path, so that make doc can find doxygen
|
||||
set_doxygen_path () {
|
||||
if test -x '/home/wouter/bin/doxygen'; then
|
||||
export PATH="/home/wouter/bin:$PATH"
|
||||
fi
|
||||
}
|
||||
|
||||
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user