mirror of
https://github.com/NLnetLabs/unbound.git
synced 2024-09-21 06:37:08 +00:00
- dnstap support, with a patch from Farsight Security, written by
Robert Edmonds. The --enable-dnstap needs libfstrm and protobuf-c. It is BSD licensed (see dnstap/dnstap.c). Building with --enable-dnstap needs pkg-config with this patch. - Noted dnstap in doc/README and doc/CREDITS. git-svn-id: file:///svn/unbound/trunk@3206 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
efe66a977e
commit
8ccba42b1f
19
Makefile.in
19
Makefile.in
@ -21,6 +21,8 @@ EXEEXT=@EXEEXT@
|
||||
configfile=@ub_conf_file@
|
||||
CHECKLOCK_SRC=testcode/checklocks.c
|
||||
CHECKLOCK_OBJ=@CHECKLOCK_OBJ@
|
||||
DNSTAP_SRC=@DNSTAP_SRC@
|
||||
DNSTAP_OBJ=@DNSTAP_OBJ@
|
||||
WITH_PYTHONMODULE=@WITH_PYTHONMODULE@
|
||||
WITH_PYUNBOUND=@WITH_PYUNBOUND@
|
||||
PYTHON_SITE_PKG=@PYTHON_SITE_PKG@
|
||||
@ -43,6 +45,7 @@ PYUNBOUND_TARGET=@PYUNBOUND_TARGET@
|
||||
# K&R C compilers), but causes problems if $U is defined in the env).
|
||||
U=
|
||||
|
||||
PROTOC_C=@PROTOC_C@
|
||||
SWIG=@SWIG@
|
||||
YACC=@YACC@
|
||||
LEX=@LEX@
|
||||
@ -106,7 +109,7 @@ util/winsock_event.c validator/autotrust.c validator/val_anchor.c \
|
||||
validator/validator.c validator/val_kcache.c validator/val_kentry.c \
|
||||
validator/val_neg.c validator/val_nsec3.c validator/val_nsec.c \
|
||||
validator/val_secalgo.c validator/val_sigcrypt.c \
|
||||
validator/val_utils.c dns64/dns64.c $(CHECKLOCK_SRC)
|
||||
validator/val_utils.c dns64/dns64.c $(CHECKLOCK_SRC) $(DNSTAP_SRC)
|
||||
COMMON_OBJ_WITHOUT_NETCALL=dns.lo infra.lo rrset.lo dname.lo msgencode.lo \
|
||||
msgparse.lo msgreply.lo packed_rrset.lo iterator.lo iter_delegpt.lo \
|
||||
iter_donotq.lo iter_fwd.lo iter_hints.lo iter_priv.lo iter_resptype.lo \
|
||||
@ -117,7 +120,7 @@ random.lo rbtree.lo regional.lo rtt.lo dnstree.lo lookup3.lo lruhash.lo \
|
||||
slabhash.lo timehist.lo tube.lo winsock_event.lo autotrust.lo val_anchor.lo \
|
||||
validator.lo val_kcache.lo val_kentry.lo val_neg.lo val_nsec3.lo val_nsec.lo \
|
||||
val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo \
|
||||
$(PYTHONMOD_OBJ) $(CHECKLOCK_OBJ)
|
||||
$(PYTHONMOD_OBJ) $(CHECKLOCK_OBJ) $(DNSTAP_OBJ)
|
||||
COMMON_OBJ=$(COMMON_OBJ_WITHOUT_NETCALL) netevent.lo listen_dnsport.lo \
|
||||
outside_network.lo
|
||||
# set to $COMMON_OBJ or to "" if --enableallsymbols
|
||||
@ -357,6 +360,18 @@ unbound-control-setup: smallapp/unbound-control-setup.sh
|
||||
cp smallapp/unbound-control-setup.sh $@
|
||||
-chmod +x $@
|
||||
|
||||
# dnstap
|
||||
dnstap.lo dnstap.o: $(srcdir)/dnstap/dnstap.c config.h dnstap/dnstap_config.h \
|
||||
dnstap/dnstap.pb-c.c dnstap/dnstap.pb-c.h $(srcdir)/dnstap/dnstap.h \
|
||||
$(srcdir)/util/config_file.h $(srcdir)/util/log.h \
|
||||
$(srcdir)/util/netevent.h $(srcdir)/util/net_help.h
|
||||
|
||||
dnstap/dnstap.pb-c.c dnstap/dnstap.pb-c.h: $(srcdir)/dnstap/dnstap.proto
|
||||
@-if test ! -d dnstap; then $(INSTALL) -d dnstap; fi
|
||||
$(PROTOC_C) --c_out=. $(srcdir)/dnstap/dnstap.proto
|
||||
|
||||
dnstap.pb-c.lo dnstap.pb-c.o: dnstap/dnstap.pb-c.c dnstap/dnstap.pb-c.h
|
||||
|
||||
# Python Module
|
||||
pythonmod.lo pythonmod.o: $(srcdir)/pythonmod/pythonmod.c config.h \
|
||||
pythonmod/interface.h \
|
||||
|
@ -19,6 +19,9 @@
|
||||
/* Whether daemon is deprecated */
|
||||
#undef DEPRECATED_DAEMON
|
||||
|
||||
/* default dnstap socket path */
|
||||
#undef DNSTAP_SOCKET_PATH
|
||||
|
||||
/* Define if you want to use debug lock checking (slow). */
|
||||
#undef ENABLE_LOCK_CHECKS
|
||||
|
||||
@ -539,6 +542,9 @@
|
||||
/* define this to enable debug checks. */
|
||||
#undef UNBOUND_DEBUG
|
||||
|
||||
/* Define to 1 to enable dnstap support */
|
||||
#undef USE_DNSTAP
|
||||
|
||||
/* Define this to enable ECDSA support. */
|
||||
#undef USE_ECDSA
|
||||
|
||||
|
441
configure
vendored
441
configure
vendored
@ -636,6 +636,18 @@ INSTALLTARGET
|
||||
ALLTARGET
|
||||
SOURCEFILE
|
||||
SOURCEDETERMINE
|
||||
DNSTAP_OBJ
|
||||
DNSTAP_SRC
|
||||
opt_dnstap_socket_path
|
||||
ENABLE_DNSTAP
|
||||
libprotobuf_c_LIBS
|
||||
libprotobuf_c_CFLAGS
|
||||
libfstrm_LIBS
|
||||
libfstrm_CFLAGS
|
||||
PKG_CONFIG_LIBDIR
|
||||
PKG_CONFIG_PATH
|
||||
PKG_CONFIG
|
||||
PROTOC_C
|
||||
UBSYMS
|
||||
EXTRALINK
|
||||
COMMON_OBJ_ALL_SYMBOLS
|
||||
@ -824,6 +836,8 @@ with_libexpat
|
||||
enable_static_exe
|
||||
enable_lock_checks
|
||||
enable_allsymbols
|
||||
enable_dnstap
|
||||
with_dnstap_socket_path
|
||||
with_libunbound_only
|
||||
'
|
||||
ac_precious_vars='build_alias
|
||||
@ -837,7 +851,14 @@ CPPFLAGS
|
||||
CPP
|
||||
YACC
|
||||
YFLAGS
|
||||
PYTHON_VERSION'
|
||||
PYTHON_VERSION
|
||||
PKG_CONFIG
|
||||
PKG_CONFIG_PATH
|
||||
PKG_CONFIG_LIBDIR
|
||||
libfstrm_CFLAGS
|
||||
libfstrm_LIBS
|
||||
libprotobuf_c_CFLAGS
|
||||
libprotobuf_c_LIBS'
|
||||
|
||||
|
||||
# Initialize some variables set by options.
|
||||
@ -1481,6 +1502,7 @@ Optional Features:
|
||||
--enable-allsymbols export all symbols from libunbound and link binaries
|
||||
to it, smaller install size but libunbound export
|
||||
table is polluted by internal symbols
|
||||
--enable-dnstap Enable dnstap support (requires fstrm, protobuf-c)
|
||||
|
||||
Optional Packages:
|
||||
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
|
||||
@ -1525,6 +1547,8 @@ Optional Packages:
|
||||
an explicit path). Slower, but allows use of large
|
||||
outgoing port ranges.
|
||||
--with-libexpat=path specify explicit path for libexpat.
|
||||
--with-dnstap-socket-path=pathname
|
||||
set default dnstap socket path
|
||||
--with-libunbound-only do not build daemon and tool programs
|
||||
|
||||
Some influential environment variables:
|
||||
@ -1546,6 +1570,19 @@ Some influential environment variables:
|
||||
The installed Python version to use, for example '2.3'. This
|
||||
string will be appended to the Python interpreter canonical
|
||||
name.
|
||||
PKG_CONFIG path to pkg-config utility
|
||||
PKG_CONFIG_PATH
|
||||
directories to add to pkg-config's search path
|
||||
PKG_CONFIG_LIBDIR
|
||||
path overriding pkg-config's built-in search path
|
||||
libfstrm_CFLAGS
|
||||
C compiler flags for libfstrm, overriding pkg-config
|
||||
libfstrm_LIBS
|
||||
linker flags for libfstrm, overriding pkg-config
|
||||
libprotobuf_c_CFLAGS
|
||||
C compiler flags for libprotobuf_c, overriding pkg-config
|
||||
libprotobuf_c_LIBS
|
||||
linker flags for libprotobuf_c, overriding pkg-config
|
||||
|
||||
Use these variables to override the choices made by `configure' or to help
|
||||
it to find libraries and programs with nonstandard names/locations.
|
||||
@ -19861,6 +19898,405 @@ if test x_$enable_lock_checks = x_yes; then
|
||||
echo checklock_thrjoin >> clubsyms.def
|
||||
fi
|
||||
|
||||
# check for dnstap if requested
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
|
||||
if test -n "$ac_tool_prefix"; then
|
||||
# Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
|
||||
set dummy ${ac_tool_prefix}pkg-config; ac_word=$2
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
|
||||
$as_echo_n "checking for $ac_word... " >&6; }
|
||||
if ${ac_cv_path_PKG_CONFIG+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
case $PKG_CONFIG in
|
||||
[\\/]* | ?:[\\/]*)
|
||||
ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
|
||||
;;
|
||||
*)
|
||||
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
|
||||
for as_dir in $PATH
|
||||
do
|
||||
IFS=$as_save_IFS
|
||||
test -z "$as_dir" && as_dir=.
|
||||
for ac_exec_ext in '' $ac_executable_extensions; do
|
||||
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
|
||||
ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
done
|
||||
IFS=$as_save_IFS
|
||||
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
PKG_CONFIG=$ac_cv_path_PKG_CONFIG
|
||||
if test -n "$PKG_CONFIG"; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5
|
||||
$as_echo "$PKG_CONFIG" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
|
||||
|
||||
fi
|
||||
if test -z "$ac_cv_path_PKG_CONFIG"; then
|
||||
ac_pt_PKG_CONFIG=$PKG_CONFIG
|
||||
# Extract the first word of "pkg-config", so it can be a program name with args.
|
||||
set dummy pkg-config; ac_word=$2
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
|
||||
$as_echo_n "checking for $ac_word... " >&6; }
|
||||
if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
case $ac_pt_PKG_CONFIG in
|
||||
[\\/]* | ?:[\\/]*)
|
||||
ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path.
|
||||
;;
|
||||
*)
|
||||
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
|
||||
for as_dir in $PATH
|
||||
do
|
||||
IFS=$as_save_IFS
|
||||
test -z "$as_dir" && as_dir=.
|
||||
for ac_exec_ext in '' $ac_executable_extensions; do
|
||||
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
|
||||
ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
done
|
||||
IFS=$as_save_IFS
|
||||
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG
|
||||
if test -n "$ac_pt_PKG_CONFIG"; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5
|
||||
$as_echo "$ac_pt_PKG_CONFIG" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
|
||||
if test "x$ac_pt_PKG_CONFIG" = x; then
|
||||
PKG_CONFIG=""
|
||||
else
|
||||
case $cross_compiling:$ac_tool_warned in
|
||||
yes:)
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
|
||||
$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
|
||||
ac_tool_warned=yes ;;
|
||||
esac
|
||||
PKG_CONFIG=$ac_pt_PKG_CONFIG
|
||||
fi
|
||||
else
|
||||
PKG_CONFIG="$ac_cv_path_PKG_CONFIG"
|
||||
fi
|
||||
|
||||
fi
|
||||
if test -n "$PKG_CONFIG"; then
|
||||
_pkg_min_version=0.9.0
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5
|
||||
$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; }
|
||||
if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
PKG_CONFIG=""
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check whether --enable-dnstap was given.
|
||||
if test "${enable_dnstap+set}" = set; then :
|
||||
enableval=$enable_dnstap; opt_dnstap=$enableval
|
||||
else
|
||||
opt_dnstap=no
|
||||
fi
|
||||
|
||||
|
||||
|
||||
# Check whether --with-dnstap-socket-path was given.
|
||||
if test "${with_dnstap_socket_path+set}" = set; then :
|
||||
withval=$with_dnstap_socket_path; opt_dnstap_socket_path=$withval
|
||||
else
|
||||
opt_dnstap_socket_path="$UNBOUND_RUN_DIR/dnstap.sock"
|
||||
fi
|
||||
|
||||
|
||||
if test "x$opt_dnstap" != "xno"; then
|
||||
# Extract the first word of "protoc-c", so it can be a program name with args.
|
||||
set dummy protoc-c; ac_word=$2
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
|
||||
$as_echo_n "checking for $ac_word... " >&6; }
|
||||
if ${ac_cv_path_PROTOC_C+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
case $PROTOC_C in
|
||||
[\\/]* | ?:[\\/]*)
|
||||
ac_cv_path_PROTOC_C="$PROTOC_C" # Let the user override the test with a path.
|
||||
;;
|
||||
*)
|
||||
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
|
||||
for as_dir in $PATH
|
||||
do
|
||||
IFS=$as_save_IFS
|
||||
test -z "$as_dir" && as_dir=.
|
||||
for ac_exec_ext in '' $ac_executable_extensions; do
|
||||
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
|
||||
ac_cv_path_PROTOC_C="$as_dir/$ac_word$ac_exec_ext"
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
done
|
||||
IFS=$as_save_IFS
|
||||
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
PROTOC_C=$ac_cv_path_PROTOC_C
|
||||
if test -n "$PROTOC_C"; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $PROTOC_C" >&5
|
||||
$as_echo "$PROTOC_C" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
|
||||
|
||||
if test -z "$PROTOC_C"; then
|
||||
as_fn_error $? "The protoc-c program was not found. Please install protobuf-c!" "$LINENO" 5
|
||||
fi
|
||||
|
||||
pkg_failed=no
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libfstrm" >&5
|
||||
$as_echo_n "checking for libfstrm... " >&6; }
|
||||
|
||||
if test -n "$libfstrm_CFLAGS"; then
|
||||
pkg_cv_libfstrm_CFLAGS="$libfstrm_CFLAGS"
|
||||
elif test -n "$PKG_CONFIG"; then
|
||||
if test -n "$PKG_CONFIG" && \
|
||||
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libfstrm\""; } >&5
|
||||
($PKG_CONFIG --exists --print-errors "libfstrm") 2>&5
|
||||
ac_status=$?
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||
test $ac_status = 0; }; then
|
||||
pkg_cv_libfstrm_CFLAGS=`$PKG_CONFIG --cflags "libfstrm" 2>/dev/null`
|
||||
test "x$?" != "x0" && pkg_failed=yes
|
||||
else
|
||||
pkg_failed=yes
|
||||
fi
|
||||
else
|
||||
pkg_failed=untried
|
||||
fi
|
||||
if test -n "$libfstrm_LIBS"; then
|
||||
pkg_cv_libfstrm_LIBS="$libfstrm_LIBS"
|
||||
elif test -n "$PKG_CONFIG"; then
|
||||
if test -n "$PKG_CONFIG" && \
|
||||
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libfstrm\""; } >&5
|
||||
($PKG_CONFIG --exists --print-errors "libfstrm") 2>&5
|
||||
ac_status=$?
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||
test $ac_status = 0; }; then
|
||||
pkg_cv_libfstrm_LIBS=`$PKG_CONFIG --libs "libfstrm" 2>/dev/null`
|
||||
test "x$?" != "x0" && pkg_failed=yes
|
||||
else
|
||||
pkg_failed=yes
|
||||
fi
|
||||
else
|
||||
pkg_failed=untried
|
||||
fi
|
||||
|
||||
|
||||
|
||||
if test $pkg_failed = yes; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
|
||||
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
|
||||
_pkg_short_errors_supported=yes
|
||||
else
|
||||
_pkg_short_errors_supported=no
|
||||
fi
|
||||
if test $_pkg_short_errors_supported = yes; then
|
||||
libfstrm_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libfstrm" 2>&1`
|
||||
else
|
||||
libfstrm_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libfstrm" 2>&1`
|
||||
fi
|
||||
# Put the nasty error message in config.log where it belongs
|
||||
echo "$libfstrm_PKG_ERRORS" >&5
|
||||
|
||||
as_fn_error $? "Package requirements (libfstrm) were not met:
|
||||
|
||||
$libfstrm_PKG_ERRORS
|
||||
|
||||
Consider adjusting the PKG_CONFIG_PATH environment variable if you
|
||||
installed software in a non-standard prefix.
|
||||
|
||||
Alternatively, you may set the environment variables libfstrm_CFLAGS
|
||||
and libfstrm_LIBS to avoid the need to call pkg-config.
|
||||
See the pkg-config man page for more details." "$LINENO" 5
|
||||
elif test $pkg_failed = untried; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
|
||||
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
|
||||
as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
|
||||
is in your PATH or set the PKG_CONFIG environment variable to the full
|
||||
path to pkg-config.
|
||||
|
||||
Alternatively, you may set the environment variables libfstrm_CFLAGS
|
||||
and libfstrm_LIBS to avoid the need to call pkg-config.
|
||||
See the pkg-config man page for more details.
|
||||
|
||||
To get pkg-config, see <http://pkg-config.freedesktop.org/>.
|
||||
See \`config.log' for more details" "$LINENO" 5; }
|
||||
else
|
||||
libfstrm_CFLAGS=$pkg_cv_libfstrm_CFLAGS
|
||||
libfstrm_LIBS=$pkg_cv_libfstrm_LIBS
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
|
||||
fi
|
||||
|
||||
pkg_failed=no
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libprotobuf_c" >&5
|
||||
$as_echo_n "checking for libprotobuf_c... " >&6; }
|
||||
|
||||
if test -n "$libprotobuf_c_CFLAGS"; then
|
||||
pkg_cv_libprotobuf_c_CFLAGS="$libprotobuf_c_CFLAGS"
|
||||
elif test -n "$PKG_CONFIG"; then
|
||||
if test -n "$PKG_CONFIG" && \
|
||||
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libprotobuf-c\""; } >&5
|
||||
($PKG_CONFIG --exists --print-errors "libprotobuf-c") 2>&5
|
||||
ac_status=$?
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||
test $ac_status = 0; }; then
|
||||
pkg_cv_libprotobuf_c_CFLAGS=`$PKG_CONFIG --cflags "libprotobuf-c" 2>/dev/null`
|
||||
test "x$?" != "x0" && pkg_failed=yes
|
||||
else
|
||||
pkg_failed=yes
|
||||
fi
|
||||
else
|
||||
pkg_failed=untried
|
||||
fi
|
||||
if test -n "$libprotobuf_c_LIBS"; then
|
||||
pkg_cv_libprotobuf_c_LIBS="$libprotobuf_c_LIBS"
|
||||
elif test -n "$PKG_CONFIG"; then
|
||||
if test -n "$PKG_CONFIG" && \
|
||||
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libprotobuf-c\""; } >&5
|
||||
($PKG_CONFIG --exists --print-errors "libprotobuf-c") 2>&5
|
||||
ac_status=$?
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||
test $ac_status = 0; }; then
|
||||
pkg_cv_libprotobuf_c_LIBS=`$PKG_CONFIG --libs "libprotobuf-c" 2>/dev/null`
|
||||
test "x$?" != "x0" && pkg_failed=yes
|
||||
else
|
||||
pkg_failed=yes
|
||||
fi
|
||||
else
|
||||
pkg_failed=untried
|
||||
fi
|
||||
|
||||
|
||||
|
||||
if test $pkg_failed = yes; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
|
||||
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
|
||||
_pkg_short_errors_supported=yes
|
||||
else
|
||||
_pkg_short_errors_supported=no
|
||||
fi
|
||||
if test $_pkg_short_errors_supported = yes; then
|
||||
libprotobuf_c_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libprotobuf-c" 2>&1`
|
||||
else
|
||||
libprotobuf_c_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libprotobuf-c" 2>&1`
|
||||
fi
|
||||
# Put the nasty error message in config.log where it belongs
|
||||
echo "$libprotobuf_c_PKG_ERRORS" >&5
|
||||
|
||||
as_fn_error $? "Package requirements (libprotobuf-c) were not met:
|
||||
|
||||
$libprotobuf_c_PKG_ERRORS
|
||||
|
||||
Consider adjusting the PKG_CONFIG_PATH environment variable if you
|
||||
installed software in a non-standard prefix.
|
||||
|
||||
Alternatively, you may set the environment variables libprotobuf_c_CFLAGS
|
||||
and libprotobuf_c_LIBS to avoid the need to call pkg-config.
|
||||
See the pkg-config man page for more details." "$LINENO" 5
|
||||
elif test $pkg_failed = untried; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
|
||||
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
|
||||
as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
|
||||
is in your PATH or set the PKG_CONFIG environment variable to the full
|
||||
path to pkg-config.
|
||||
|
||||
Alternatively, you may set the environment variables libprotobuf_c_CFLAGS
|
||||
and libprotobuf_c_LIBS to avoid the need to call pkg-config.
|
||||
See the pkg-config man page for more details.
|
||||
|
||||
To get pkg-config, see <http://pkg-config.freedesktop.org/>.
|
||||
See \`config.log' for more details" "$LINENO" 5; }
|
||||
else
|
||||
libprotobuf_c_CFLAGS=$pkg_cv_libprotobuf_c_CFLAGS
|
||||
libprotobuf_c_LIBS=$pkg_cv_libprotobuf_c_LIBS
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
|
||||
fi
|
||||
DNSTAP_CFLAGS="$libfstrm_CFLAGS $libprotobuf_c_CFLAGS"
|
||||
DNSTAP_LIBS="$libfstrm_LIBS $libprotobuf_c_LIBS"
|
||||
|
||||
LIBS="$LIBS $DNSTAP_LIBS"
|
||||
CFLAGS="$CFLAGS $DNSTAP_CFLAGS"
|
||||
|
||||
$as_echo "#define USE_DNSTAP 1" >>confdefs.h
|
||||
|
||||
ENABLE_DNSTAP=1
|
||||
|
||||
|
||||
|
||||
hdr_dnstap_socket_path="`echo $opt_dnstap_socket_path | sed -e 's/\\\\/\\\\\\\\/g'`"
|
||||
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define DNSTAP_SOCKET_PATH "$hdr_dnstap_socket_path"
|
||||
_ACEOF
|
||||
|
||||
|
||||
DNSTAP_SRC="dnstap/dnstap.c dnstap/dnstap.pb-c.c"
|
||||
|
||||
DNSTAP_OBJ="dnstap.lo dnstap.pb-c.lo"
|
||||
|
||||
|
||||
else
|
||||
|
||||
ENABLE_DNSTAP=0
|
||||
|
||||
|
||||
|
||||
fi
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if ${MAKE:-make} supports $< with implicit rule in scope" >&5
|
||||
$as_echo_n "checking if ${MAKE:-make} supports $< with implicit rule in scope... " >&6; }
|
||||
# on openBSD, the implicit rule make $< work.
|
||||
@ -19994,7 +20430,7 @@ _ACEOF
|
||||
|
||||
|
||||
|
||||
ac_config_files="$ac_config_files Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound.conf.5 doc/unbound-control.8 doc/unbound-host.1 smallapp/unbound-control-setup.sh"
|
||||
ac_config_files="$ac_config_files Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound.conf.5 doc/unbound-control.8 doc/unbound-host.1 smallapp/unbound-control-setup.sh dnstap/dnstap_config.h"
|
||||
|
||||
ac_config_headers="$ac_config_headers config.h"
|
||||
|
||||
@ -20986,6 +21422,7 @@ do
|
||||
"doc/unbound-control.8") CONFIG_FILES="$CONFIG_FILES doc/unbound-control.8" ;;
|
||||
"doc/unbound-host.1") CONFIG_FILES="$CONFIG_FILES doc/unbound-host.1" ;;
|
||||
"smallapp/unbound-control-setup.sh") CONFIG_FILES="$CONFIG_FILES smallapp/unbound-control-setup.sh" ;;
|
||||
"dnstap/dnstap_config.h") CONFIG_FILES="$CONFIG_FILES dnstap/dnstap_config.h" ;;
|
||||
"config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
|
||||
|
||||
*) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
|
||||
|
25
configure.ac
25
configure.ac
@ -5,6 +5,8 @@ sinclude(acx_nlnetlabs.m4)
|
||||
sinclude(ax_pthread.m4)
|
||||
sinclude(acx_python.m4)
|
||||
sinclude(ac_pkg_swig.m4)
|
||||
sinclude(pkg.m4)
|
||||
sinclude(dnstap/dnstap.m4)
|
||||
|
||||
# must be numbers. ac_defun because of later processing
|
||||
m4_define([VERSION_MAJOR],[1])
|
||||
@ -1094,6 +1096,27 @@ if test x_$enable_lock_checks = x_yes; then
|
||||
echo checklock_thrjoin >> clubsyms.def
|
||||
fi
|
||||
|
||||
# check for dnstap if requested
|
||||
dt_DNSTAP([$UNBOUND_RUN_DIR/dnstap.sock],
|
||||
[
|
||||
LIBS="$LIBS $DNSTAP_LIBS"
|
||||
CFLAGS="$CFLAGS $DNSTAP_CFLAGS"
|
||||
AC_DEFINE([USE_DNSTAP], [1], [Define to 1 to enable dnstap support])
|
||||
AC_SUBST([ENABLE_DNSTAP], [1])
|
||||
|
||||
AC_SUBST([opt_dnstap_socket_path])
|
||||
ACX_ESCAPE_BACKSLASH($opt_dnstap_socket_path, hdr_dnstap_socket_path)
|
||||
AC_DEFINE_UNQUOTED(DNSTAP_SOCKET_PATH,
|
||||
["$hdr_dnstap_socket_path"], [default dnstap socket path])
|
||||
|
||||
AC_SUBST([DNSTAP_SRC], ["dnstap/dnstap.c dnstap/dnstap.pb-c.c"])
|
||||
AC_SUBST([DNSTAP_OBJ], ["dnstap.lo dnstap.pb-c.lo"])
|
||||
],
|
||||
[
|
||||
AC_SUBST([ENABLE_DNSTAP], [0])
|
||||
]
|
||||
)
|
||||
|
||||
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).
|
||||
@ -1345,6 +1368,6 @@ void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
|
||||
|
||||
])
|
||||
|
||||
AC_CONFIG_FILES([Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound.conf.5 doc/unbound-control.8 doc/unbound-host.1 smallapp/unbound-control-setup.sh])
|
||||
AC_CONFIG_FILES([Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound.conf.5 doc/unbound-control.8 doc/unbound-host.1 smallapp/unbound-control-setup.sh dnstap/dnstap_config.h])
|
||||
AC_CONFIG_HEADER([config.h])
|
||||
AC_OUTPUT
|
||||
|
@ -401,6 +401,17 @@ daemon_create_workers(struct daemon* daemon)
|
||||
daemon->num = (daemon->cfg->num_threads?daemon->cfg->num_threads:1);
|
||||
daemon->workers = (struct worker**)calloc((size_t)daemon->num,
|
||||
sizeof(struct worker*));
|
||||
if(daemon->cfg->dnstap) {
|
||||
#ifdef USE_DNSTAP
|
||||
daemon->dtenv = dt_create(daemon->cfg->dnstap_socket_path,
|
||||
daemon->num);
|
||||
if (!daemon->dtenv)
|
||||
fatal_exit("dt_create failed");
|
||||
dt_apply_cfg(daemon->dtenv, daemon->cfg);
|
||||
#else
|
||||
fatal_exit("dnstap enabled in config but not built with dnstap support");
|
||||
#endif
|
||||
}
|
||||
for(i=0; i<daemon->num; i++) {
|
||||
if(!(daemon->workers[i] = worker_create(daemon, i,
|
||||
shufport+numport*i/daemon->num,
|
||||
@ -585,6 +596,9 @@ daemon_cleanup(struct daemon* daemon)
|
||||
free(daemon->workers);
|
||||
daemon->workers = NULL;
|
||||
daemon->num = 0;
|
||||
#ifdef USE_DNSTAP
|
||||
dt_delete(daemon->dtenv);
|
||||
#endif
|
||||
daemon->cfg = NULL;
|
||||
}
|
||||
|
||||
|
@ -59,6 +59,11 @@ struct local_zones;
|
||||
struct ub_randstate;
|
||||
struct daemon_remote;
|
||||
|
||||
#include "dnstap/dnstap_config.h"
|
||||
#ifdef USE_DNSTAP
|
||||
struct dt_env;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Structure holding worker list.
|
||||
* Holds globally visible information.
|
||||
@ -109,6 +114,10 @@ struct daemon {
|
||||
struct timeval time_last_stat;
|
||||
/** time when daemon started */
|
||||
struct timeval time_boot;
|
||||
#ifdef USE_DNSTAP
|
||||
/** the dnstap environment master value, copied and changed by threads*/
|
||||
struct dt_env* dtenv;
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -777,16 +777,24 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
struct query_info qinfo;
|
||||
struct edns_data edns;
|
||||
enum acl_access acl;
|
||||
int rc = 0;
|
||||
|
||||
if(error != NETEVENT_NOERROR) {
|
||||
/* some bad tcp query DNS formats give these error calls */
|
||||
verbose(VERB_ALGO, "handle request called with err=%d", error);
|
||||
return 0;
|
||||
}
|
||||
#ifdef USE_DNSTAP
|
||||
if(worker->dtenv.log_client_query_messages)
|
||||
dt_msg_send_client_query(&worker->dtenv, &repinfo->addr, c->type,
|
||||
c->buffer);
|
||||
#endif
|
||||
acl = acl_list_lookup(worker->daemon->acl, &repinfo->addr,
|
||||
repinfo->addrlen);
|
||||
if((ret=deny_refuse_all(c, acl, worker, repinfo)) != -1)
|
||||
{
|
||||
if(ret == 1)
|
||||
goto send_reply;
|
||||
return ret;
|
||||
}
|
||||
if((ret=worker_check_request(c->buffer, worker)) != 0) {
|
||||
@ -810,7 +818,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
|
||||
LDNS_RCODE_FORMERR);
|
||||
server_stats_insrcode(&worker->stats, c->buffer);
|
||||
return 1;
|
||||
goto send_reply;
|
||||
}
|
||||
if(worker->env.cfg->log_queries) {
|
||||
char ip[128];
|
||||
@ -829,7 +837,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
worker->stats.qtype[qinfo.qtype]++;
|
||||
server_stats_insrcode(&worker->stats, c->buffer);
|
||||
}
|
||||
return 1;
|
||||
goto send_reply;
|
||||
}
|
||||
if((ret=parse_edns_from_pkt(c->buffer, &edns)) != 0) {
|
||||
verbose(VERB_ALGO, "worker parse edns: formerror.");
|
||||
@ -838,7 +846,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
|
||||
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer), ret);
|
||||
server_stats_insrcode(&worker->stats, c->buffer);
|
||||
return 1;
|
||||
goto send_reply;
|
||||
}
|
||||
if(edns.edns_present && edns.edns_version != 0) {
|
||||
edns.ext_rcode = (uint8_t)(EDNS_RCODE_BADVERS>>4);
|
||||
@ -851,7 +859,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
|
||||
sldns_buffer_read_u16_at(c->buffer, 2), NULL);
|
||||
attach_edns_record(c->buffer, &edns);
|
||||
return 1;
|
||||
goto send_reply;
|
||||
}
|
||||
if(edns.edns_present && edns.udp_size < NORMAL_UDP_SIZE &&
|
||||
worker->daemon->cfg->harden_short_bufsize) {
|
||||
@ -879,7 +887,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
sldns_buffer_write_at(c->buffer, 4,
|
||||
(uint8_t*)"\0\0\0\0\0\0\0\0", 8);
|
||||
sldns_buffer_flip(c->buffer);
|
||||
return 1;
|
||||
goto send_reply;
|
||||
}
|
||||
if(worker->stats.extended)
|
||||
server_stats_insquery(&worker->stats, c, qinfo.qtype,
|
||||
@ -889,7 +897,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
if(qinfo.qclass == LDNS_RR_CLASS_CH && answer_chaos(worker, &qinfo,
|
||||
&edns, c->buffer)) {
|
||||
server_stats_insrcode(&worker->stats, c->buffer);
|
||||
return 1;
|
||||
goto send_reply;
|
||||
}
|
||||
if(local_zones_answer(worker->daemon->local_zones, &qinfo, &edns,
|
||||
c->buffer, worker->scratchpad)) {
|
||||
@ -899,13 +907,15 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
return 0;
|
||||
}
|
||||
server_stats_insrcode(&worker->stats, c->buffer);
|
||||
return 1;
|
||||
goto send_reply;
|
||||
}
|
||||
|
||||
/* We've looked in our local zones. If the answer isn't there, we
|
||||
* might need to bail out based on ACLs now. */
|
||||
if((ret=deny_refuse_non_local(c, acl, worker, repinfo)) != -1)
|
||||
{
|
||||
if(ret == 1)
|
||||
goto send_reply;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -923,7 +933,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
server_stats_insrcode(&worker->stats, c->buffer);
|
||||
log_addr(VERB_ALGO, "refused nonrec (cache snoop) query from",
|
||||
&repinfo->addr, repinfo->addrlen);
|
||||
return 1;
|
||||
goto send_reply;
|
||||
}
|
||||
h = query_info_hash(&qinfo);
|
||||
if((e=slabhash_lookup(worker->env.msg_cache, h, &qinfo, 0))) {
|
||||
@ -942,10 +952,11 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
reply_and_prefetch(worker, &qinfo,
|
||||
sldns_buffer_read_u16_at(c->buffer, 2),
|
||||
repinfo, leeway);
|
||||
return 0;
|
||||
rc = 0;
|
||||
goto send_reply_rc;
|
||||
}
|
||||
lock_rw_unlock(&e->lock);
|
||||
return 1;
|
||||
goto send_reply;
|
||||
}
|
||||
verbose(VERB_ALGO, "answer from the cache failed");
|
||||
lock_rw_unlock(&e->lock);
|
||||
@ -955,7 +966,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
|
||||
sldns_buffer_read_u16_at(c->buffer, 2), repinfo,
|
||||
&edns)) {
|
||||
return 1;
|
||||
goto send_reply;
|
||||
}
|
||||
verbose(VERB_ALGO, "answer norec from cache -- "
|
||||
"need to validate or not primed");
|
||||
@ -977,6 +988,16 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
&edns, repinfo, *(uint16_t*)(void *)sldns_buffer_begin(c->buffer));
|
||||
worker_mem_report(worker, NULL);
|
||||
return 0;
|
||||
|
||||
send_reply:
|
||||
rc = 1;
|
||||
send_reply_rc:
|
||||
#ifdef USE_DNSTAP
|
||||
if(worker->dtenv.log_client_response_messages)
|
||||
dt_msg_send_client_response(&worker->dtenv, &repinfo->addr,
|
||||
c->type, c->buffer);
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
void
|
||||
@ -1084,6 +1105,14 @@ worker_create(struct daemon* daemon, int id, int* ports, int n)
|
||||
return NULL;
|
||||
}
|
||||
seed = 0;
|
||||
#ifdef USE_DNSTAP
|
||||
if(daemon->cfg->dnstap) {
|
||||
log_assert(daemon->dtenv != NULL);
|
||||
memcpy(&worker->dtenv, daemon->dtenv, sizeof(struct dt_env));
|
||||
if(!dt_init(&worker->dtenv))
|
||||
fatal_exit("dt_init failed");
|
||||
}
|
||||
#endif
|
||||
return worker;
|
||||
}
|
||||
|
||||
@ -1091,6 +1120,11 @@ int
|
||||
worker_init(struct worker* worker, struct config_file *cfg,
|
||||
struct listen_port* ports, int do_sigs)
|
||||
{
|
||||
#ifdef USE_DNSTAP
|
||||
struct dt_env* dtenv = &worker->dtenv;
|
||||
#else
|
||||
void* dtenv = NULL;
|
||||
#endif
|
||||
worker->need_to_exit = 0;
|
||||
worker->base = comm_base_create(do_sigs);
|
||||
if(!worker->base) {
|
||||
@ -1139,7 +1173,8 @@ 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->daemon->listen_sslctx, worker_handle_request, worker);
|
||||
worker->daemon->listen_sslctx, dtenv, worker_handle_request,
|
||||
worker);
|
||||
if(!worker->front) {
|
||||
log_err("could not create listening sockets");
|
||||
worker_delete(worker);
|
||||
@ -1152,7 +1187,8 @@ 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, worker->daemon->connect_sslctx, cfg->delay_close);
|
||||
cfg->do_udp, worker->daemon->connect_sslctx, cfg->delay_close,
|
||||
dtenv);
|
||||
if(!worker->back) {
|
||||
log_err("could not create outgoing sockets");
|
||||
worker_delete(worker);
|
||||
|
@ -51,6 +51,7 @@
|
||||
#include "util/data/msgparse.h"
|
||||
#include "daemon/stats.h"
|
||||
#include "util/module.h"
|
||||
#include "dnstap/dnstap.h"
|
||||
struct listen_dnsport;
|
||||
struct outside_network;
|
||||
struct config_file;
|
||||
@ -116,6 +117,11 @@ struct worker {
|
||||
|
||||
/** module environment passed to modules, changed for this thread */
|
||||
struct module_env env;
|
||||
|
||||
#ifdef USE_DNSTAP
|
||||
/** dnstap environment, changed for this thread */
|
||||
struct dt_env dtenv;
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
|
499
dnstap/dnstap.c
Normal file
499
dnstap/dnstap.c
Normal file
@ -0,0 +1,499 @@
|
||||
/* dnstap support for Unbound */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Farsight Security, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "dnstap/dnstap_config.h"
|
||||
|
||||
#ifdef USE_DNSTAP
|
||||
|
||||
#include "config.h"
|
||||
#include <sys/time.h>
|
||||
#include "ldns/sbuffer.h"
|
||||
#include "util/config_file.h"
|
||||
#include "util/net_help.h"
|
||||
#include "util/netevent.h"
|
||||
#include "util/log.h"
|
||||
|
||||
#include <fstrm.h>
|
||||
#include <protobuf-c/protobuf-c.h>
|
||||
|
||||
#include "dnstap/dnstap.h"
|
||||
#include "dnstap/dnstap.pb-c.h"
|
||||
|
||||
#define DNSTAP_CONTENT_TYPE "protobuf:dnstap.Dnstap"
|
||||
#define DNSTAP_INITIAL_BUF_SIZE 256
|
||||
|
||||
struct dt_msg {
|
||||
void *buf;
|
||||
size_t len_buf;
|
||||
Dnstap__Dnstap d;
|
||||
Dnstap__Message m;
|
||||
};
|
||||
|
||||
static int
|
||||
dt_pack(const Dnstap__Dnstap *d, void **buf, size_t *sz)
|
||||
{
|
||||
ProtobufCBufferSimple sbuf;
|
||||
|
||||
sbuf.base.append = protobuf_c_buffer_simple_append;
|
||||
sbuf.len = 0;
|
||||
sbuf.alloced = DNSTAP_INITIAL_BUF_SIZE;
|
||||
sbuf.data = malloc(sbuf.alloced);
|
||||
if (sbuf.data == NULL)
|
||||
return 0;
|
||||
sbuf.must_free_data = 1;
|
||||
|
||||
*sz = dnstap__dnstap__pack_to_buffer(d, (ProtobufCBuffer *) &sbuf);
|
||||
if (sbuf.data == NULL)
|
||||
return 0;
|
||||
*buf = sbuf.data;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
dt_send(const struct dt_env *env, void *buf, size_t len_buf)
|
||||
{
|
||||
fstrm_res res;
|
||||
if (!buf)
|
||||
return;
|
||||
res = fstrm_io_submit(env->fio, env->fq, buf, len_buf,
|
||||
fstrm_free_wrapper, NULL);
|
||||
if (res != FSTRM_RES_SUCCESS)
|
||||
free(buf);
|
||||
}
|
||||
|
||||
static void
|
||||
dt_msg_init(const struct dt_env *env,
|
||||
struct dt_msg *dm,
|
||||
Dnstap__Message__Type mtype)
|
||||
{
|
||||
memset(dm, 0, sizeof(*dm));
|
||||
dm->d.base.descriptor = &dnstap__dnstap__descriptor;
|
||||
dm->m.base.descriptor = &dnstap__message__descriptor;
|
||||
dm->d.type = DNSTAP__DNSTAP__TYPE__MESSAGE;
|
||||
dm->d.message = &dm->m;
|
||||
dm->m.type = mtype;
|
||||
if (env->identity != NULL) {
|
||||
dm->d.identity.data = (uint8_t *) env->identity;
|
||||
dm->d.identity.len = (size_t) env->len_identity;
|
||||
dm->d.has_identity = 1;
|
||||
}
|
||||
if (env->version != NULL) {
|
||||
dm->d.version.data = (uint8_t *) env->version;
|
||||
dm->d.version.len = (size_t) env->len_version;
|
||||
dm->d.has_version = 1;
|
||||
}
|
||||
}
|
||||
|
||||
struct dt_env *
|
||||
dt_create(const char *socket_path, unsigned num_workers)
|
||||
{
|
||||
char *fio_err;
|
||||
struct dt_env *env;
|
||||
struct fstrm_io_options *fopt;
|
||||
struct fstrm_unix_writer_options *fuwopt;
|
||||
|
||||
verbose(VERB_OPS, "opening dnstap socket %s", socket_path);
|
||||
log_assert(socket_path != NULL);
|
||||
log_assert(num_workers > 0);
|
||||
|
||||
env = (struct dt_env *) calloc(1, sizeof(struct dt_env));
|
||||
if (!env)
|
||||
return NULL;
|
||||
|
||||
fuwopt = fstrm_unix_writer_options_init();
|
||||
fstrm_unix_writer_options_set_socket_path(fuwopt, socket_path);
|
||||
fopt = fstrm_io_options_init();
|
||||
fstrm_io_options_set_content_type(fopt,
|
||||
DNSTAP_CONTENT_TYPE,
|
||||
sizeof(DNSTAP_CONTENT_TYPE) - 1);
|
||||
fstrm_io_options_set_num_queues(fopt, num_workers);
|
||||
fstrm_io_options_set_writer(fopt, fstrm_unix_writer, fuwopt);
|
||||
env->fio = fstrm_io_init(fopt, &fio_err);
|
||||
if (env->fio == NULL) {
|
||||
verbose(VERB_DETAIL, "dt_create: fstrm_io_init() failed: %s",
|
||||
fio_err);
|
||||
free(fio_err);
|
||||
free(env);
|
||||
env = NULL;
|
||||
}
|
||||
fstrm_io_options_destroy(&fopt);
|
||||
fstrm_unix_writer_options_destroy(&fuwopt);
|
||||
|
||||
return env;
|
||||
}
|
||||
|
||||
static void
|
||||
dt_apply_identity(struct dt_env *env, struct config_file *cfg)
|
||||
{
|
||||
char buf[MAXHOSTNAMELEN+1];
|
||||
if (!cfg->dnstap_send_identity)
|
||||
return;
|
||||
free(env->identity);
|
||||
if (cfg->dnstap_identity == NULL || cfg->dnstap_identity[0] == 0) {
|
||||
if (gethostname(buf, MAXHOSTNAMELEN) == 0) {
|
||||
buf[MAXHOSTNAMELEN] = 0;
|
||||
env->identity = strdup(buf);
|
||||
} else {
|
||||
fatal_exit("dt_apply_identity: gethostname() failed");
|
||||
}
|
||||
} else {
|
||||
env->identity = strdup(cfg->dnstap_identity);
|
||||
}
|
||||
if (env->identity == NULL)
|
||||
fatal_exit("dt_apply_identity: strdup() failed");
|
||||
env->len_identity = strlen(env->identity);
|
||||
verbose(VERB_OPS, "dnstap identity field set to \"%s\"",
|
||||
env->identity);
|
||||
}
|
||||
|
||||
static void
|
||||
dt_apply_version(struct dt_env *env, struct config_file *cfg)
|
||||
{
|
||||
if (!cfg->dnstap_send_version)
|
||||
return;
|
||||
free(env->version);
|
||||
if (cfg->dnstap_version == NULL || cfg->dnstap_version[0] == 0)
|
||||
env->version = strdup(PACKAGE_STRING);
|
||||
else
|
||||
env->version = strdup(cfg->dnstap_version);
|
||||
if (env->version == NULL)
|
||||
fatal_exit("dt_apply_version: strdup() failed");
|
||||
env->len_version = strlen(env->version);
|
||||
verbose(VERB_OPS, "dnstap version field set to \"%s\"",
|
||||
env->version);
|
||||
}
|
||||
|
||||
void
|
||||
dt_apply_cfg(struct dt_env *env, struct config_file *cfg)
|
||||
{
|
||||
if (!cfg->dnstap)
|
||||
return;
|
||||
|
||||
dt_apply_identity(env, cfg);
|
||||
dt_apply_version(env, cfg);
|
||||
if ((env->log_resolver_query_messages =
|
||||
cfg->dnstap_log_resolver_query_messages))
|
||||
{
|
||||
verbose(VERB_OPS, "dnstap Message/RESOLVER_QUERY enabled");
|
||||
}
|
||||
if ((env->log_resolver_response_messages =
|
||||
cfg->dnstap_log_resolver_response_messages))
|
||||
{
|
||||
verbose(VERB_OPS, "dnstap Message/RESOLVER_RESPONSE enabled");
|
||||
}
|
||||
if ((env->log_client_query_messages =
|
||||
cfg->dnstap_log_client_query_messages))
|
||||
{
|
||||
verbose(VERB_OPS, "dnstap Message/CLIENT_QUERY enabled");
|
||||
}
|
||||
if ((env->log_client_response_messages =
|
||||
cfg->dnstap_log_client_response_messages))
|
||||
{
|
||||
verbose(VERB_OPS, "dnstap Message/CLIENT_RESPONSE enabled");
|
||||
}
|
||||
if ((env->log_forwarder_query_messages =
|
||||
cfg->dnstap_log_forwarder_query_messages))
|
||||
{
|
||||
verbose(VERB_OPS, "dnstap Message/FORWARDER_QUERY enabled");
|
||||
}
|
||||
if ((env->log_forwarder_response_messages =
|
||||
cfg->dnstap_log_forwarder_response_messages))
|
||||
{
|
||||
verbose(VERB_OPS, "dnstap Message/FORWARDER_RESPONSE enabled");
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
dt_init(struct dt_env *env)
|
||||
{
|
||||
env->fq = fstrm_io_get_queue(env->fio);
|
||||
if (env->fq == NULL)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
dt_delete(struct dt_env *env)
|
||||
{
|
||||
if (!env)
|
||||
return;
|
||||
verbose(VERB_OPS, "closing dnstap socket");
|
||||
fstrm_io_destroy(&env->fio);
|
||||
free(env->identity);
|
||||
free(env->version);
|
||||
free(env);
|
||||
}
|
||||
|
||||
static void
|
||||
dt_fill_timeval(const struct timeval *tv,
|
||||
uint64_t *time_sec, protobuf_c_boolean *has_time_sec,
|
||||
uint32_t *time_nsec, protobuf_c_boolean *has_time_nsec)
|
||||
{
|
||||
*time_sec = tv->tv_sec;
|
||||
*time_nsec = tv->tv_usec * 1000;
|
||||
*has_time_sec = 1;
|
||||
*has_time_nsec = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
dt_fill_buffer(sldns_buffer *b, ProtobufCBinaryData *p, protobuf_c_boolean *has)
|
||||
{
|
||||
log_assert(b != NULL);
|
||||
p->len = sldns_buffer_limit(b);
|
||||
p->data = sldns_buffer_begin(b);
|
||||
*has = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
dt_msg_fill_net(struct dt_msg *dm,
|
||||
struct sockaddr_storage *ss,
|
||||
enum comm_point_type cptype,
|
||||
ProtobufCBinaryData *addr, protobuf_c_boolean *has_addr,
|
||||
uint32_t *port, protobuf_c_boolean *has_port)
|
||||
{
|
||||
log_assert(ss->ss_family == AF_INET6 || ss->ss_family == AF_INET);
|
||||
if (ss->ss_family == AF_INET6) {
|
||||
struct sockaddr_in6 *s = (struct sockaddr_in6 *) ss;
|
||||
|
||||
/* socket_family */
|
||||
dm->m.socket_family = DNSTAP__SOCKET_FAMILY__INET6;
|
||||
dm->m.has_socket_family = 1;
|
||||
|
||||
/* addr: query_address or response_address */
|
||||
addr->data = s->sin6_addr.s6_addr;
|
||||
addr->len = 16; /* IPv6 */
|
||||
*has_addr = 1;
|
||||
|
||||
/* port: query_port or response_port */
|
||||
*port = ntohs(s->sin6_port);
|
||||
*has_port = 1;
|
||||
} else if (ss->ss_family == AF_INET) {
|
||||
struct sockaddr_in *s = (struct sockaddr_in *) ss;
|
||||
|
||||
/* socket_family */
|
||||
dm->m.socket_family = DNSTAP__SOCKET_FAMILY__INET;
|
||||
dm->m.has_socket_family = 1;
|
||||
|
||||
/* addr: query_address or response_address */
|
||||
addr->data = (uint8_t *) &s->sin_addr.s_addr;
|
||||
addr->len = 4; /* IPv4 */
|
||||
*has_addr = 1;
|
||||
|
||||
/* port: query_port or response_port */
|
||||
*port = ntohs(s->sin_port);
|
||||
*has_port = 1;
|
||||
}
|
||||
|
||||
log_assert(cptype == comm_udp || cptype == comm_tcp);
|
||||
if (cptype == comm_udp) {
|
||||
/* socket_protocol */
|
||||
dm->m.socket_protocol = DNSTAP__SOCKET_PROTOCOL__UDP;
|
||||
dm->m.has_socket_protocol = 1;
|
||||
} else if (cptype == comm_tcp) {
|
||||
/* socket_protocol */
|
||||
dm->m.socket_protocol = DNSTAP__SOCKET_PROTOCOL__TCP;
|
||||
dm->m.has_socket_protocol = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dt_msg_send_client_query(struct dt_env *env,
|
||||
struct sockaddr_storage *qsock,
|
||||
enum comm_point_type cptype,
|
||||
sldns_buffer *qmsg)
|
||||
{
|
||||
struct dt_msg dm;
|
||||
struct timeval qtime;
|
||||
|
||||
gettimeofday(&qtime, NULL);
|
||||
|
||||
/* type */
|
||||
dt_msg_init(env, &dm, DNSTAP__MESSAGE__TYPE__CLIENT_QUERY);
|
||||
|
||||
/* query_time */
|
||||
dt_fill_timeval(&qtime,
|
||||
&dm.m.query_time_sec, &dm.m.has_query_time_sec,
|
||||
&dm.m.query_time_nsec, &dm.m.has_query_time_nsec);
|
||||
|
||||
/* query_message */
|
||||
dt_fill_buffer(qmsg, &dm.m.query_message, &dm.m.has_query_message);
|
||||
|
||||
/* socket_family, socket_protocol, query_address, query_port */
|
||||
log_assert(cptype == comm_udp || cptype == comm_tcp);
|
||||
dt_msg_fill_net(&dm, qsock, cptype,
|
||||
&dm.m.query_address, &dm.m.has_query_address,
|
||||
&dm.m.query_port, &dm.m.has_query_port);
|
||||
|
||||
if (dt_pack(&dm.d, &dm.buf, &dm.len_buf))
|
||||
dt_send(env, dm.buf, dm.len_buf);
|
||||
}
|
||||
|
||||
void
|
||||
dt_msg_send_client_response(struct dt_env *env,
|
||||
struct sockaddr_storage *qsock,
|
||||
enum comm_point_type cptype,
|
||||
sldns_buffer *rmsg)
|
||||
{
|
||||
struct dt_msg dm;
|
||||
struct timeval rtime;
|
||||
|
||||
gettimeofday(&rtime, NULL);
|
||||
|
||||
/* type */
|
||||
dt_msg_init(env, &dm, DNSTAP__MESSAGE__TYPE__CLIENT_RESPONSE);
|
||||
|
||||
/* response_time */
|
||||
dt_fill_timeval(&rtime,
|
||||
&dm.m.response_time_sec, &dm.m.has_response_time_sec,
|
||||
&dm.m.response_time_nsec, &dm.m.has_response_time_nsec);
|
||||
|
||||
/* response_message */
|
||||
dt_fill_buffer(rmsg, &dm.m.response_message, &dm.m.has_response_message);
|
||||
|
||||
/* socket_family, socket_protocol, query_address, query_port */
|
||||
log_assert(cptype == comm_udp || cptype == comm_tcp);
|
||||
dt_msg_fill_net(&dm, qsock, cptype,
|
||||
&dm.m.query_address, &dm.m.has_query_address,
|
||||
&dm.m.query_port, &dm.m.has_query_port);
|
||||
|
||||
if (dt_pack(&dm.d, &dm.buf, &dm.len_buf))
|
||||
dt_send(env, dm.buf, dm.len_buf);
|
||||
}
|
||||
|
||||
void
|
||||
dt_msg_send_outside_query(struct dt_env *env,
|
||||
struct sockaddr_storage *rsock,
|
||||
enum comm_point_type cptype,
|
||||
uint8_t *zone, size_t zone_len,
|
||||
sldns_buffer *qmsg)
|
||||
{
|
||||
struct dt_msg dm;
|
||||
struct timeval qtime;
|
||||
uint16_t qflags;
|
||||
|
||||
gettimeofday(&qtime, NULL);
|
||||
qflags = sldns_buffer_read_u16_at(qmsg, 2);
|
||||
|
||||
/* type */
|
||||
if (qflags & BIT_RD) {
|
||||
if (!env->log_forwarder_query_messages)
|
||||
return;
|
||||
dt_msg_init(env, &dm, DNSTAP__MESSAGE__TYPE__FORWARDER_QUERY);
|
||||
} else {
|
||||
if (!env->log_resolver_query_messages)
|
||||
return;
|
||||
dt_msg_init(env, &dm, DNSTAP__MESSAGE__TYPE__RESOLVER_QUERY);
|
||||
}
|
||||
|
||||
/* query_zone */
|
||||
dm.m.query_zone.data = zone;
|
||||
dm.m.query_zone.len = zone_len;
|
||||
dm.m.has_query_zone = 1;
|
||||
|
||||
/* query_time_sec, query_time_nsec */
|
||||
dt_fill_timeval(&qtime,
|
||||
&dm.m.query_time_sec, &dm.m.has_query_time_sec,
|
||||
&dm.m.query_time_nsec, &dm.m.has_query_time_nsec);
|
||||
|
||||
/* query_message */
|
||||
dt_fill_buffer(qmsg, &dm.m.query_message, &dm.m.has_query_message);
|
||||
|
||||
/* socket_family, socket_protocol, response_address, response_port */
|
||||
log_assert(cptype == comm_udp || cptype == comm_tcp);
|
||||
dt_msg_fill_net(&dm, rsock, cptype,
|
||||
&dm.m.response_address, &dm.m.has_response_address,
|
||||
&dm.m.response_port, &dm.m.has_response_port);
|
||||
|
||||
if (dt_pack(&dm.d, &dm.buf, &dm.len_buf))
|
||||
dt_send(env, dm.buf, dm.len_buf);
|
||||
}
|
||||
|
||||
void
|
||||
dt_msg_send_outside_response(struct dt_env *env,
|
||||
struct sockaddr_storage *rsock,
|
||||
enum comm_point_type cptype,
|
||||
uint8_t *zone, size_t zone_len,
|
||||
uint8_t *qbuf, size_t qbuf_len,
|
||||
const struct timeval *qtime,
|
||||
const struct timeval *rtime,
|
||||
sldns_buffer *rmsg)
|
||||
{
|
||||
struct dt_msg dm;
|
||||
uint16_t qflags;
|
||||
|
||||
log_assert(qbuf_len >= sizeof(qflags));
|
||||
memcpy(&qflags, qbuf, sizeof(qflags));
|
||||
qflags = ntohs(qflags);
|
||||
|
||||
/* type */
|
||||
if (qflags & BIT_RD) {
|
||||
if (!env->log_forwarder_response_messages)
|
||||
return;
|
||||
dt_msg_init(env, &dm, DNSTAP__MESSAGE__TYPE__FORWARDER_RESPONSE);
|
||||
} else {
|
||||
if (!env->log_resolver_query_messages)
|
||||
return;
|
||||
dt_msg_init(env, &dm, DNSTAP__MESSAGE__TYPE__RESOLVER_RESPONSE);
|
||||
}
|
||||
|
||||
/* query_zone */
|
||||
dm.m.query_zone.data = zone;
|
||||
dm.m.query_zone.len = zone_len;
|
||||
dm.m.has_query_zone = 1;
|
||||
|
||||
/* query_time_sec, query_time_nsec */
|
||||
dt_fill_timeval(qtime,
|
||||
&dm.m.query_time_sec, &dm.m.has_query_time_sec,
|
||||
&dm.m.query_time_nsec, &dm.m.has_query_time_nsec);
|
||||
|
||||
/* response_time_sec, response_time_nsec */
|
||||
dt_fill_timeval(rtime,
|
||||
&dm.m.response_time_sec, &dm.m.has_response_time_sec,
|
||||
&dm.m.response_time_nsec, &dm.m.has_response_time_nsec);
|
||||
|
||||
/* response_message */
|
||||
dt_fill_buffer(rmsg, &dm.m.response_message, &dm.m.has_response_message);
|
||||
|
||||
/* socket_family, socket_protocol, response_address, response_port */
|
||||
log_assert(cptype == comm_udp || cptype == comm_tcp);
|
||||
dt_msg_fill_net(&dm, rsock, cptype,
|
||||
&dm.m.response_address, &dm.m.has_response_address,
|
||||
&dm.m.response_port, &dm.m.has_response_port);
|
||||
|
||||
if (dt_pack(&dm.d, &dm.buf, &dm.len_buf))
|
||||
dt_send(env, dm.buf, dm.len_buf);
|
||||
}
|
||||
|
||||
#endif /* USE_DNSTAP */
|
188
dnstap/dnstap.h
Normal file
188
dnstap/dnstap.h
Normal file
@ -0,0 +1,188 @@
|
||||
/* dnstap support for Unbound */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Farsight Security, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef UNBOUND_DNSTAP_H
|
||||
#define UNBOUND_DNSTAP_H
|
||||
|
||||
#include "dnstap/dnstap_config.h"
|
||||
|
||||
#ifdef USE_DNSTAP
|
||||
|
||||
struct config_file;
|
||||
struct fstrm_io;
|
||||
struct fstrm_queue;
|
||||
struct sldns_buffer;
|
||||
|
||||
struct dt_env {
|
||||
/** dnstap I/O socket */
|
||||
struct fstrm_io *fio;
|
||||
|
||||
/** dnstap I/O queue */
|
||||
struct fstrm_queue *fq;
|
||||
|
||||
/** dnstap "identity" field, NULL if disabled */
|
||||
char *identity;
|
||||
|
||||
/** dnstap "version" field, NULL if disabled */
|
||||
char *version;
|
||||
|
||||
/** length of "identity" field */
|
||||
unsigned len_identity;
|
||||
|
||||
/** length of "version" field */
|
||||
unsigned len_version;
|
||||
|
||||
/** whether to log Message/RESOLVER_QUERY */
|
||||
unsigned log_resolver_query_messages : 1;
|
||||
/** whether to log Message/RESOLVER_RESPONSE */
|
||||
unsigned log_resolver_response_messages : 1;
|
||||
/** whether to log Message/CLIENT_QUERY */
|
||||
unsigned log_client_query_messages : 1;
|
||||
/** whether to log Message/CLIENT_RESPONSE */
|
||||
unsigned log_client_response_messages : 1;
|
||||
/** whether to log Message/FORWARDER_QUERY */
|
||||
unsigned log_forwarder_query_messages : 1;
|
||||
/** whether to log Message/FORWARDER_RESPONSE */
|
||||
unsigned log_forwarder_response_messages : 1;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create dnstap environment object. Afterwards, call dt_apply_cfg() to fill in
|
||||
* the config variables and dt_init() to fill in the per-worker state. Each
|
||||
* worker needs a copy of this object but with its own I/O queue (the fq field
|
||||
* of the structure) to ensure lock-free access to its own per-worker circular
|
||||
* queue. Duplicate the environment object if more than one worker needs to
|
||||
* share access to the dnstap I/O socket.
|
||||
* @param socket_path: path to dnstap logging socket, must be non-NULL.
|
||||
* @param num_workers: number of worker threads, must be > 0.
|
||||
* @return dt_env object, NULL on failure.
|
||||
*/
|
||||
struct dt_env *
|
||||
dt_create(const char *socket_path, unsigned num_workers);
|
||||
|
||||
/**
|
||||
* Apply config settings.
|
||||
* @param env: dnstap environment object.
|
||||
* @param cfg: new config settings.
|
||||
*/
|
||||
void
|
||||
dt_apply_cfg(struct dt_env *env, struct config_file *cfg);
|
||||
|
||||
/**
|
||||
* Initialize per-worker state in dnstap environment object.
|
||||
* @param env: dnstap environment object to initialize, created with dt_create().
|
||||
* @return: true on success, false on failure.
|
||||
*/
|
||||
int
|
||||
dt_init(struct dt_env *env);
|
||||
|
||||
/**
|
||||
* Delete dnstap environment object. Closes dnstap I/O socket and deletes all
|
||||
* per-worker I/O queues.
|
||||
*/
|
||||
void
|
||||
dt_delete(struct dt_env *env);
|
||||
|
||||
/**
|
||||
* Create and send a new dnstap "Message" event of type CLIENT_QUERY.
|
||||
* @param env: dnstap environment object.
|
||||
* @param qsock: address/port of client.
|
||||
* @param cptype: comm_udp or comm_tcp.
|
||||
* @param qmsg: query message.
|
||||
*/
|
||||
void
|
||||
dt_msg_send_client_query(struct dt_env *env,
|
||||
struct sockaddr_storage *qsock,
|
||||
enum comm_point_type cptype,
|
||||
struct sldns_buffer *qmsg);
|
||||
|
||||
/**
|
||||
* Create and send a new dnstap "Message" event of type CLIENT_RESPONSE.
|
||||
* @param env: dnstap environment object.
|
||||
* @param qsock: address/port of client.
|
||||
* @param cptype: comm_udp or comm_tcp.
|
||||
* @param rmsg: response message.
|
||||
*/
|
||||
void
|
||||
dt_msg_send_client_response(struct dt_env *env,
|
||||
struct sockaddr_storage *qsock,
|
||||
enum comm_point_type cptype,
|
||||
struct sldns_buffer *rmsg);
|
||||
|
||||
/**
|
||||
* Create and send a new dnstap "Message" event of type RESOLVER_QUERY or
|
||||
* FORWARDER_QUERY. The type used is dependent on the value of the RD bit
|
||||
* in the query header.
|
||||
* @param env: dnstap environment object.
|
||||
* @param rsock: address/port of server the query is being sent to.
|
||||
* @param cptype: comm_udp or comm_tcp.
|
||||
* @param zone: query zone.
|
||||
* @param zone_len: length of zone.
|
||||
* @param qmsg: query message.
|
||||
*/
|
||||
void
|
||||
dt_msg_send_outside_query(struct dt_env *env,
|
||||
struct sockaddr_storage *rsock,
|
||||
enum comm_point_type cptype,
|
||||
uint8_t *zone, size_t zone_len,
|
||||
struct sldns_buffer *qmsg);
|
||||
|
||||
/**
|
||||
* Create and send a new dnstap "Message" event of type RESOLVER_RESPONSE or
|
||||
* FORWARDER_RESPONSE. The type used is dependent on the value of the RD bit
|
||||
* in the query header.
|
||||
* @param env: dnstap environment object.
|
||||
* @param rsock: address/port of server the response was received from.
|
||||
* @param cptype: comm_udp or comm_tcp.
|
||||
* @param zone: query zone.
|
||||
* @param zone_len: length of zone.
|
||||
* @param qbuf: outside_network's qbuf key.
|
||||
* @param qbuf_len: length of outside_network's qbuf key.
|
||||
* @param qtime: time query message was sent.
|
||||
* @param rtime: time response message was sent.
|
||||
* @param rmsg: response message.
|
||||
*/
|
||||
void
|
||||
dt_msg_send_outside_response(struct dt_env *env,
|
||||
struct sockaddr_storage *rsock,
|
||||
enum comm_point_type cptype,
|
||||
uint8_t *zone, size_t zone_len,
|
||||
uint8_t *qbuf, size_t qbuf_len,
|
||||
const struct timeval *qtime,
|
||||
const struct timeval *rtime,
|
||||
struct sldns_buffer *rmsg);
|
||||
|
||||
#endif /* USE_DNSTAP */
|
||||
|
||||
#endif /* UNBOUND_DNSTAP_H */
|
31
dnstap/dnstap.m4
Normal file
31
dnstap/dnstap.m4
Normal file
@ -0,0 +1,31 @@
|
||||
# dnstap.m4
|
||||
|
||||
# dt_DNSTAP(default_dnstap_socket_path, [action-if-true], [action-if-false])
|
||||
# --------------------------------------------------------------------------
|
||||
# Check for required dnstap libraries and add dnstap configure args.
|
||||
AC_DEFUN([dt_DNSTAP],
|
||||
[
|
||||
AC_ARG_ENABLE([dnstap],
|
||||
AS_HELP_STRING([--enable-dnstap],
|
||||
[Enable dnstap support (requires fstrm, protobuf-c)]),
|
||||
[opt_dnstap=$enableval], [opt_dnstap=no])
|
||||
|
||||
AC_ARG_WITH([dnstap-socket-path],
|
||||
AS_HELP_STRING([--with-dnstap-socket-path=pathname],
|
||||
[set default dnstap socket path]),
|
||||
[opt_dnstap_socket_path=$withval], [opt_dnstap_socket_path="$1"])
|
||||
|
||||
if test "x$opt_dnstap" != "xno"; then
|
||||
AC_PATH_PROG([PROTOC_C], [protoc-c])
|
||||
if test -z "$PROTOC_C"; then
|
||||
AC_MSG_ERROR([The protoc-c program was not found. Please install protobuf-c!])
|
||||
fi
|
||||
PKG_CHECK_MODULES([libfstrm], [libfstrm])
|
||||
PKG_CHECK_MODULES([libprotobuf_c], [libprotobuf-c])
|
||||
DNSTAP_CFLAGS="$libfstrm_CFLAGS $libprotobuf_c_CFLAGS"
|
||||
DNSTAP_LIBS="$libfstrm_LIBS $libprotobuf_c_LIBS"
|
||||
$2
|
||||
else
|
||||
$3
|
||||
fi
|
||||
])
|
518
dnstap/dnstap.pb-c.c
Normal file
518
dnstap/dnstap.pb-c.c
Normal file
@ -0,0 +1,518 @@
|
||||
/* Generated by the protocol buffer compiler. DO NOT EDIT! */
|
||||
|
||||
/* Do not generate deprecated warnings for self */
|
||||
#ifndef PROTOBUF_C_NO_DEPRECATED
|
||||
#define PROTOBUF_C_NO_DEPRECATED
|
||||
#endif
|
||||
|
||||
#include "dnstap/dnstap.pb-c.h"
|
||||
void dnstap__dnstap__init
|
||||
(Dnstap__Dnstap *message)
|
||||
{
|
||||
static Dnstap__Dnstap init_value = DNSTAP__DNSTAP__INIT;
|
||||
*message = init_value;
|
||||
}
|
||||
size_t dnstap__dnstap__get_packed_size
|
||||
(const Dnstap__Dnstap *message)
|
||||
{
|
||||
PROTOBUF_C_ASSERT (message->base.descriptor == &dnstap__dnstap__descriptor);
|
||||
return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
|
||||
}
|
||||
size_t dnstap__dnstap__pack
|
||||
(const Dnstap__Dnstap *message,
|
||||
uint8_t *out)
|
||||
{
|
||||
PROTOBUF_C_ASSERT (message->base.descriptor == &dnstap__dnstap__descriptor);
|
||||
return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
|
||||
}
|
||||
size_t dnstap__dnstap__pack_to_buffer
|
||||
(const Dnstap__Dnstap *message,
|
||||
ProtobufCBuffer *buffer)
|
||||
{
|
||||
PROTOBUF_C_ASSERT (message->base.descriptor == &dnstap__dnstap__descriptor);
|
||||
return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
|
||||
}
|
||||
Dnstap__Dnstap *
|
||||
dnstap__dnstap__unpack
|
||||
(ProtobufCAllocator *allocator,
|
||||
size_t len,
|
||||
const uint8_t *data)
|
||||
{
|
||||
return (Dnstap__Dnstap *)
|
||||
protobuf_c_message_unpack (&dnstap__dnstap__descriptor,
|
||||
allocator, len, data);
|
||||
}
|
||||
void dnstap__dnstap__free_unpacked
|
||||
(Dnstap__Dnstap *message,
|
||||
ProtobufCAllocator *allocator)
|
||||
{
|
||||
PROTOBUF_C_ASSERT (message->base.descriptor == &dnstap__dnstap__descriptor);
|
||||
protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
|
||||
}
|
||||
void dnstap__message__init
|
||||
(Dnstap__Message *message)
|
||||
{
|
||||
static Dnstap__Message init_value = DNSTAP__MESSAGE__INIT;
|
||||
*message = init_value;
|
||||
}
|
||||
size_t dnstap__message__get_packed_size
|
||||
(const Dnstap__Message *message)
|
||||
{
|
||||
PROTOBUF_C_ASSERT (message->base.descriptor == &dnstap__message__descriptor);
|
||||
return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
|
||||
}
|
||||
size_t dnstap__message__pack
|
||||
(const Dnstap__Message *message,
|
||||
uint8_t *out)
|
||||
{
|
||||
PROTOBUF_C_ASSERT (message->base.descriptor == &dnstap__message__descriptor);
|
||||
return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
|
||||
}
|
||||
size_t dnstap__message__pack_to_buffer
|
||||
(const Dnstap__Message *message,
|
||||
ProtobufCBuffer *buffer)
|
||||
{
|
||||
PROTOBUF_C_ASSERT (message->base.descriptor == &dnstap__message__descriptor);
|
||||
return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
|
||||
}
|
||||
Dnstap__Message *
|
||||
dnstap__message__unpack
|
||||
(ProtobufCAllocator *allocator,
|
||||
size_t len,
|
||||
const uint8_t *data)
|
||||
{
|
||||
return (Dnstap__Message *)
|
||||
protobuf_c_message_unpack (&dnstap__message__descriptor,
|
||||
allocator, len, data);
|
||||
}
|
||||
void dnstap__message__free_unpacked
|
||||
(Dnstap__Message *message,
|
||||
ProtobufCAllocator *allocator)
|
||||
{
|
||||
PROTOBUF_C_ASSERT (message->base.descriptor == &dnstap__message__descriptor);
|
||||
protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
|
||||
}
|
||||
const ProtobufCEnumValue dnstap__dnstap__type__enum_values_by_number[1] =
|
||||
{
|
||||
{ "MESSAGE", "DNSTAP__DNSTAP__TYPE__MESSAGE", 1 },
|
||||
};
|
||||
static const ProtobufCIntRange dnstap__dnstap__type__value_ranges[] = {
|
||||
{1, 0},{0, 1}
|
||||
};
|
||||
const ProtobufCEnumValueIndex dnstap__dnstap__type__enum_values_by_name[1] =
|
||||
{
|
||||
{ "MESSAGE", 0 },
|
||||
};
|
||||
const ProtobufCEnumDescriptor dnstap__dnstap__type__descriptor =
|
||||
{
|
||||
PROTOBUF_C_ENUM_DESCRIPTOR_MAGIC,
|
||||
"dnstap.Dnstap.Type",
|
||||
"Type",
|
||||
"Dnstap__Dnstap__Type",
|
||||
"dnstap",
|
||||
1,
|
||||
dnstap__dnstap__type__enum_values_by_number,
|
||||
1,
|
||||
dnstap__dnstap__type__enum_values_by_name,
|
||||
1,
|
||||
dnstap__dnstap__type__value_ranges,
|
||||
NULL,NULL,NULL,NULL /* reserved[1234] */
|
||||
};
|
||||
static const ProtobufCFieldDescriptor dnstap__dnstap__field_descriptors[5] =
|
||||
{
|
||||
{
|
||||
"identity",
|
||||
1,
|
||||
PROTOBUF_C_LABEL_OPTIONAL,
|
||||
PROTOBUF_C_TYPE_BYTES,
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Dnstap, has_identity),
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Dnstap, identity),
|
||||
NULL,
|
||||
NULL,
|
||||
0, /* packed */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
{
|
||||
"version",
|
||||
2,
|
||||
PROTOBUF_C_LABEL_OPTIONAL,
|
||||
PROTOBUF_C_TYPE_BYTES,
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Dnstap, has_version),
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Dnstap, version),
|
||||
NULL,
|
||||
NULL,
|
||||
0, /* packed */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
{
|
||||
"extra",
|
||||
3,
|
||||
PROTOBUF_C_LABEL_OPTIONAL,
|
||||
PROTOBUF_C_TYPE_BYTES,
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Dnstap, has_extra),
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Dnstap, extra),
|
||||
NULL,
|
||||
NULL,
|
||||
0, /* packed */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
{
|
||||
"message",
|
||||
14,
|
||||
PROTOBUF_C_LABEL_OPTIONAL,
|
||||
PROTOBUF_C_TYPE_MESSAGE,
|
||||
0, /* quantifier_offset */
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Dnstap, message),
|
||||
&dnstap__message__descriptor,
|
||||
NULL,
|
||||
0, /* packed */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
{
|
||||
"type",
|
||||
15,
|
||||
PROTOBUF_C_LABEL_REQUIRED,
|
||||
PROTOBUF_C_TYPE_ENUM,
|
||||
0, /* quantifier_offset */
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Dnstap, type),
|
||||
&dnstap__dnstap__type__descriptor,
|
||||
NULL,
|
||||
0, /* packed */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
};
|
||||
static const unsigned dnstap__dnstap__field_indices_by_name[] = {
|
||||
2, /* field[2] = extra */
|
||||
0, /* field[0] = identity */
|
||||
3, /* field[3] = message */
|
||||
4, /* field[4] = type */
|
||||
1, /* field[1] = version */
|
||||
};
|
||||
static const ProtobufCIntRange dnstap__dnstap__number_ranges[2 + 1] =
|
||||
{
|
||||
{ 1, 0 },
|
||||
{ 14, 3 },
|
||||
{ 0, 5 }
|
||||
};
|
||||
const ProtobufCMessageDescriptor dnstap__dnstap__descriptor =
|
||||
{
|
||||
PROTOBUF_C_MESSAGE_DESCRIPTOR_MAGIC,
|
||||
"dnstap.Dnstap",
|
||||
"Dnstap",
|
||||
"Dnstap__Dnstap",
|
||||
"dnstap",
|
||||
sizeof(Dnstap__Dnstap),
|
||||
5,
|
||||
dnstap__dnstap__field_descriptors,
|
||||
dnstap__dnstap__field_indices_by_name,
|
||||
2, dnstap__dnstap__number_ranges,
|
||||
(ProtobufCMessageInit) dnstap__dnstap__init,
|
||||
NULL,NULL,NULL /* reserved[123] */
|
||||
};
|
||||
const ProtobufCEnumValue dnstap__message__type__enum_values_by_number[10] =
|
||||
{
|
||||
{ "AUTH_QUERY", "DNSTAP__MESSAGE__TYPE__AUTH_QUERY", 1 },
|
||||
{ "AUTH_RESPONSE", "DNSTAP__MESSAGE__TYPE__AUTH_RESPONSE", 2 },
|
||||
{ "RESOLVER_QUERY", "DNSTAP__MESSAGE__TYPE__RESOLVER_QUERY", 3 },
|
||||
{ "RESOLVER_RESPONSE", "DNSTAP__MESSAGE__TYPE__RESOLVER_RESPONSE", 4 },
|
||||
{ "CLIENT_QUERY", "DNSTAP__MESSAGE__TYPE__CLIENT_QUERY", 5 },
|
||||
{ "CLIENT_RESPONSE", "DNSTAP__MESSAGE__TYPE__CLIENT_RESPONSE", 6 },
|
||||
{ "FORWARDER_QUERY", "DNSTAP__MESSAGE__TYPE__FORWARDER_QUERY", 7 },
|
||||
{ "FORWARDER_RESPONSE", "DNSTAP__MESSAGE__TYPE__FORWARDER_RESPONSE", 8 },
|
||||
{ "STUB_QUERY", "DNSTAP__MESSAGE__TYPE__STUB_QUERY", 9 },
|
||||
{ "STUB_RESPONSE", "DNSTAP__MESSAGE__TYPE__STUB_RESPONSE", 10 },
|
||||
};
|
||||
static const ProtobufCIntRange dnstap__message__type__value_ranges[] = {
|
||||
{1, 0},{0, 10}
|
||||
};
|
||||
const ProtobufCEnumValueIndex dnstap__message__type__enum_values_by_name[10] =
|
||||
{
|
||||
{ "AUTH_QUERY", 0 },
|
||||
{ "AUTH_RESPONSE", 1 },
|
||||
{ "CLIENT_QUERY", 4 },
|
||||
{ "CLIENT_RESPONSE", 5 },
|
||||
{ "FORWARDER_QUERY", 6 },
|
||||
{ "FORWARDER_RESPONSE", 7 },
|
||||
{ "RESOLVER_QUERY", 2 },
|
||||
{ "RESOLVER_RESPONSE", 3 },
|
||||
{ "STUB_QUERY", 8 },
|
||||
{ "STUB_RESPONSE", 9 },
|
||||
};
|
||||
const ProtobufCEnumDescriptor dnstap__message__type__descriptor =
|
||||
{
|
||||
PROTOBUF_C_ENUM_DESCRIPTOR_MAGIC,
|
||||
"dnstap.Message.Type",
|
||||
"Type",
|
||||
"Dnstap__Message__Type",
|
||||
"dnstap",
|
||||
10,
|
||||
dnstap__message__type__enum_values_by_number,
|
||||
10,
|
||||
dnstap__message__type__enum_values_by_name,
|
||||
1,
|
||||
dnstap__message__type__value_ranges,
|
||||
NULL,NULL,NULL,NULL /* reserved[1234] */
|
||||
};
|
||||
static const ProtobufCFieldDescriptor dnstap__message__field_descriptors[14] =
|
||||
{
|
||||
{
|
||||
"type",
|
||||
1,
|
||||
PROTOBUF_C_LABEL_REQUIRED,
|
||||
PROTOBUF_C_TYPE_ENUM,
|
||||
0, /* quantifier_offset */
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, type),
|
||||
&dnstap__message__type__descriptor,
|
||||
NULL,
|
||||
0, /* packed */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
{
|
||||
"socket_family",
|
||||
2,
|
||||
PROTOBUF_C_LABEL_OPTIONAL,
|
||||
PROTOBUF_C_TYPE_ENUM,
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, has_socket_family),
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, socket_family),
|
||||
&dnstap__socket_family__descriptor,
|
||||
NULL,
|
||||
0, /* packed */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
{
|
||||
"socket_protocol",
|
||||
3,
|
||||
PROTOBUF_C_LABEL_OPTIONAL,
|
||||
PROTOBUF_C_TYPE_ENUM,
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, has_socket_protocol),
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, socket_protocol),
|
||||
&dnstap__socket_protocol__descriptor,
|
||||
NULL,
|
||||
0, /* packed */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
{
|
||||
"query_address",
|
||||
4,
|
||||
PROTOBUF_C_LABEL_OPTIONAL,
|
||||
PROTOBUF_C_TYPE_BYTES,
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, has_query_address),
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, query_address),
|
||||
NULL,
|
||||
NULL,
|
||||
0, /* packed */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
{
|
||||
"response_address",
|
||||
5,
|
||||
PROTOBUF_C_LABEL_OPTIONAL,
|
||||
PROTOBUF_C_TYPE_BYTES,
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, has_response_address),
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, response_address),
|
||||
NULL,
|
||||
NULL,
|
||||
0, /* packed */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
{
|
||||
"query_port",
|
||||
6,
|
||||
PROTOBUF_C_LABEL_OPTIONAL,
|
||||
PROTOBUF_C_TYPE_UINT32,
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, has_query_port),
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, query_port),
|
||||
NULL,
|
||||
NULL,
|
||||
0, /* packed */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
{
|
||||
"response_port",
|
||||
7,
|
||||
PROTOBUF_C_LABEL_OPTIONAL,
|
||||
PROTOBUF_C_TYPE_UINT32,
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, has_response_port),
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, response_port),
|
||||
NULL,
|
||||
NULL,
|
||||
0, /* packed */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
{
|
||||
"query_time_sec",
|
||||
8,
|
||||
PROTOBUF_C_LABEL_OPTIONAL,
|
||||
PROTOBUF_C_TYPE_UINT64,
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, has_query_time_sec),
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, query_time_sec),
|
||||
NULL,
|
||||
NULL,
|
||||
0, /* packed */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
{
|
||||
"query_time_nsec",
|
||||
9,
|
||||
PROTOBUF_C_LABEL_OPTIONAL,
|
||||
PROTOBUF_C_TYPE_FIXED32,
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, has_query_time_nsec),
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, query_time_nsec),
|
||||
NULL,
|
||||
NULL,
|
||||
0, /* packed */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
{
|
||||
"query_message",
|
||||
10,
|
||||
PROTOBUF_C_LABEL_OPTIONAL,
|
||||
PROTOBUF_C_TYPE_BYTES,
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, has_query_message),
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, query_message),
|
||||
NULL,
|
||||
NULL,
|
||||
0, /* packed */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
{
|
||||
"query_zone",
|
||||
11,
|
||||
PROTOBUF_C_LABEL_OPTIONAL,
|
||||
PROTOBUF_C_TYPE_BYTES,
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, has_query_zone),
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, query_zone),
|
||||
NULL,
|
||||
NULL,
|
||||
0, /* packed */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
{
|
||||
"response_time_sec",
|
||||
12,
|
||||
PROTOBUF_C_LABEL_OPTIONAL,
|
||||
PROTOBUF_C_TYPE_UINT64,
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, has_response_time_sec),
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, response_time_sec),
|
||||
NULL,
|
||||
NULL,
|
||||
0, /* packed */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
{
|
||||
"response_time_nsec",
|
||||
13,
|
||||
PROTOBUF_C_LABEL_OPTIONAL,
|
||||
PROTOBUF_C_TYPE_FIXED32,
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, has_response_time_nsec),
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, response_time_nsec),
|
||||
NULL,
|
||||
NULL,
|
||||
0, /* packed */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
{
|
||||
"response_message",
|
||||
14,
|
||||
PROTOBUF_C_LABEL_OPTIONAL,
|
||||
PROTOBUF_C_TYPE_BYTES,
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, has_response_message),
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, response_message),
|
||||
NULL,
|
||||
NULL,
|
||||
0, /* packed */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
};
|
||||
static const unsigned dnstap__message__field_indices_by_name[] = {
|
||||
3, /* field[3] = query_address */
|
||||
9, /* field[9] = query_message */
|
||||
5, /* field[5] = query_port */
|
||||
8, /* field[8] = query_time_nsec */
|
||||
7, /* field[7] = query_time_sec */
|
||||
10, /* field[10] = query_zone */
|
||||
4, /* field[4] = response_address */
|
||||
13, /* field[13] = response_message */
|
||||
6, /* field[6] = response_port */
|
||||
12, /* field[12] = response_time_nsec */
|
||||
11, /* field[11] = response_time_sec */
|
||||
1, /* field[1] = socket_family */
|
||||
2, /* field[2] = socket_protocol */
|
||||
0, /* field[0] = type */
|
||||
};
|
||||
static const ProtobufCIntRange dnstap__message__number_ranges[1 + 1] =
|
||||
{
|
||||
{ 1, 0 },
|
||||
{ 0, 14 }
|
||||
};
|
||||
const ProtobufCMessageDescriptor dnstap__message__descriptor =
|
||||
{
|
||||
PROTOBUF_C_MESSAGE_DESCRIPTOR_MAGIC,
|
||||
"dnstap.Message",
|
||||
"Message",
|
||||
"Dnstap__Message",
|
||||
"dnstap",
|
||||
sizeof(Dnstap__Message),
|
||||
14,
|
||||
dnstap__message__field_descriptors,
|
||||
dnstap__message__field_indices_by_name,
|
||||
1, dnstap__message__number_ranges,
|
||||
(ProtobufCMessageInit) dnstap__message__init,
|
||||
NULL,NULL,NULL /* reserved[123] */
|
||||
};
|
||||
const ProtobufCEnumValue dnstap__socket_family__enum_values_by_number[2] =
|
||||
{
|
||||
{ "INET", "DNSTAP__SOCKET_FAMILY__INET", 1 },
|
||||
{ "INET6", "DNSTAP__SOCKET_FAMILY__INET6", 2 },
|
||||
};
|
||||
static const ProtobufCIntRange dnstap__socket_family__value_ranges[] = {
|
||||
{1, 0},{0, 2}
|
||||
};
|
||||
const ProtobufCEnumValueIndex dnstap__socket_family__enum_values_by_name[2] =
|
||||
{
|
||||
{ "INET", 0 },
|
||||
{ "INET6", 1 },
|
||||
};
|
||||
const ProtobufCEnumDescriptor dnstap__socket_family__descriptor =
|
||||
{
|
||||
PROTOBUF_C_ENUM_DESCRIPTOR_MAGIC,
|
||||
"dnstap.SocketFamily",
|
||||
"SocketFamily",
|
||||
"Dnstap__SocketFamily",
|
||||
"dnstap",
|
||||
2,
|
||||
dnstap__socket_family__enum_values_by_number,
|
||||
2,
|
||||
dnstap__socket_family__enum_values_by_name,
|
||||
1,
|
||||
dnstap__socket_family__value_ranges,
|
||||
NULL,NULL,NULL,NULL /* reserved[1234] */
|
||||
};
|
||||
const ProtobufCEnumValue dnstap__socket_protocol__enum_values_by_number[2] =
|
||||
{
|
||||
{ "UDP", "DNSTAP__SOCKET_PROTOCOL__UDP", 1 },
|
||||
{ "TCP", "DNSTAP__SOCKET_PROTOCOL__TCP", 2 },
|
||||
};
|
||||
static const ProtobufCIntRange dnstap__socket_protocol__value_ranges[] = {
|
||||
{1, 0},{0, 2}
|
||||
};
|
||||
const ProtobufCEnumValueIndex dnstap__socket_protocol__enum_values_by_name[2] =
|
||||
{
|
||||
{ "TCP", 1 },
|
||||
{ "UDP", 0 },
|
||||
};
|
||||
const ProtobufCEnumDescriptor dnstap__socket_protocol__descriptor =
|
||||
{
|
||||
PROTOBUF_C_ENUM_DESCRIPTOR_MAGIC,
|
||||
"dnstap.SocketProtocol",
|
||||
"SocketProtocol",
|
||||
"Dnstap__SocketProtocol",
|
||||
"dnstap",
|
||||
2,
|
||||
dnstap__socket_protocol__enum_values_by_number,
|
||||
2,
|
||||
dnstap__socket_protocol__enum_values_by_name,
|
||||
1,
|
||||
dnstap__socket_protocol__value_ranges,
|
||||
NULL,NULL,NULL,NULL /* reserved[1234] */
|
||||
};
|
158
dnstap/dnstap.pb-c.h
Normal file
158
dnstap/dnstap.pb-c.h
Normal file
@ -0,0 +1,158 @@
|
||||
/* Generated by the protocol buffer compiler. DO NOT EDIT! */
|
||||
|
||||
#ifndef PROTOBUF_C_dnstap_2fdnstap_2eproto__INCLUDED
|
||||
#define PROTOBUF_C_dnstap_2fdnstap_2eproto__INCLUDED
|
||||
|
||||
#include <google/protobuf-c/protobuf-c.h>
|
||||
|
||||
PROTOBUF_C_BEGIN_DECLS
|
||||
|
||||
|
||||
typedef struct _Dnstap__Dnstap Dnstap__Dnstap;
|
||||
typedef struct _Dnstap__Message Dnstap__Message;
|
||||
|
||||
|
||||
/* --- enums --- */
|
||||
|
||||
typedef enum _Dnstap__Dnstap__Type {
|
||||
DNSTAP__DNSTAP__TYPE__MESSAGE = 1
|
||||
} Dnstap__Dnstap__Type;
|
||||
typedef enum _Dnstap__Message__Type {
|
||||
DNSTAP__MESSAGE__TYPE__AUTH_QUERY = 1,
|
||||
DNSTAP__MESSAGE__TYPE__AUTH_RESPONSE = 2,
|
||||
DNSTAP__MESSAGE__TYPE__RESOLVER_QUERY = 3,
|
||||
DNSTAP__MESSAGE__TYPE__RESOLVER_RESPONSE = 4,
|
||||
DNSTAP__MESSAGE__TYPE__CLIENT_QUERY = 5,
|
||||
DNSTAP__MESSAGE__TYPE__CLIENT_RESPONSE = 6,
|
||||
DNSTAP__MESSAGE__TYPE__FORWARDER_QUERY = 7,
|
||||
DNSTAP__MESSAGE__TYPE__FORWARDER_RESPONSE = 8,
|
||||
DNSTAP__MESSAGE__TYPE__STUB_QUERY = 9,
|
||||
DNSTAP__MESSAGE__TYPE__STUB_RESPONSE = 10
|
||||
} Dnstap__Message__Type;
|
||||
typedef enum _Dnstap__SocketFamily {
|
||||
DNSTAP__SOCKET_FAMILY__INET = 1,
|
||||
DNSTAP__SOCKET_FAMILY__INET6 = 2
|
||||
} Dnstap__SocketFamily;
|
||||
typedef enum _Dnstap__SocketProtocol {
|
||||
DNSTAP__SOCKET_PROTOCOL__UDP = 1,
|
||||
DNSTAP__SOCKET_PROTOCOL__TCP = 2
|
||||
} Dnstap__SocketProtocol;
|
||||
|
||||
/* --- messages --- */
|
||||
|
||||
struct _Dnstap__Dnstap
|
||||
{
|
||||
ProtobufCMessage base;
|
||||
protobuf_c_boolean has_identity;
|
||||
ProtobufCBinaryData identity;
|
||||
protobuf_c_boolean has_version;
|
||||
ProtobufCBinaryData version;
|
||||
protobuf_c_boolean has_extra;
|
||||
ProtobufCBinaryData extra;
|
||||
Dnstap__Dnstap__Type type;
|
||||
Dnstap__Message *message;
|
||||
};
|
||||
#define DNSTAP__DNSTAP__INIT \
|
||||
{ PROTOBUF_C_MESSAGE_INIT (&dnstap__dnstap__descriptor) \
|
||||
, 0,{0,NULL}, 0,{0,NULL}, 0,{0,NULL}, 0, NULL }
|
||||
|
||||
|
||||
struct _Dnstap__Message
|
||||
{
|
||||
ProtobufCMessage base;
|
||||
Dnstap__Message__Type type;
|
||||
protobuf_c_boolean has_socket_family;
|
||||
Dnstap__SocketFamily socket_family;
|
||||
protobuf_c_boolean has_socket_protocol;
|
||||
Dnstap__SocketProtocol socket_protocol;
|
||||
protobuf_c_boolean has_query_address;
|
||||
ProtobufCBinaryData query_address;
|
||||
protobuf_c_boolean has_response_address;
|
||||
ProtobufCBinaryData response_address;
|
||||
protobuf_c_boolean has_query_port;
|
||||
uint32_t query_port;
|
||||
protobuf_c_boolean has_response_port;
|
||||
uint32_t response_port;
|
||||
protobuf_c_boolean has_query_time_sec;
|
||||
uint64_t query_time_sec;
|
||||
protobuf_c_boolean has_query_time_nsec;
|
||||
uint32_t query_time_nsec;
|
||||
protobuf_c_boolean has_query_message;
|
||||
ProtobufCBinaryData query_message;
|
||||
protobuf_c_boolean has_query_zone;
|
||||
ProtobufCBinaryData query_zone;
|
||||
protobuf_c_boolean has_response_time_sec;
|
||||
uint64_t response_time_sec;
|
||||
protobuf_c_boolean has_response_time_nsec;
|
||||
uint32_t response_time_nsec;
|
||||
protobuf_c_boolean has_response_message;
|
||||
ProtobufCBinaryData response_message;
|
||||
};
|
||||
#define DNSTAP__MESSAGE__INIT \
|
||||
{ PROTOBUF_C_MESSAGE_INIT (&dnstap__message__descriptor) \
|
||||
, 0, 0,0, 0,0, 0,{0,NULL}, 0,{0,NULL}, 0,0, 0,0, 0,0, 0,0, 0,{0,NULL}, 0,{0,NULL}, 0,0, 0,0, 0,{0,NULL} }
|
||||
|
||||
|
||||
/* Dnstap__Dnstap methods */
|
||||
void dnstap__dnstap__init
|
||||
(Dnstap__Dnstap *message);
|
||||
size_t dnstap__dnstap__get_packed_size
|
||||
(const Dnstap__Dnstap *message);
|
||||
size_t dnstap__dnstap__pack
|
||||
(const Dnstap__Dnstap *message,
|
||||
uint8_t *out);
|
||||
size_t dnstap__dnstap__pack_to_buffer
|
||||
(const Dnstap__Dnstap *message,
|
||||
ProtobufCBuffer *buffer);
|
||||
Dnstap__Dnstap *
|
||||
dnstap__dnstap__unpack
|
||||
(ProtobufCAllocator *allocator,
|
||||
size_t len,
|
||||
const uint8_t *data);
|
||||
void dnstap__dnstap__free_unpacked
|
||||
(Dnstap__Dnstap *message,
|
||||
ProtobufCAllocator *allocator);
|
||||
/* Dnstap__Message methods */
|
||||
void dnstap__message__init
|
||||
(Dnstap__Message *message);
|
||||
size_t dnstap__message__get_packed_size
|
||||
(const Dnstap__Message *message);
|
||||
size_t dnstap__message__pack
|
||||
(const Dnstap__Message *message,
|
||||
uint8_t *out);
|
||||
size_t dnstap__message__pack_to_buffer
|
||||
(const Dnstap__Message *message,
|
||||
ProtobufCBuffer *buffer);
|
||||
Dnstap__Message *
|
||||
dnstap__message__unpack
|
||||
(ProtobufCAllocator *allocator,
|
||||
size_t len,
|
||||
const uint8_t *data);
|
||||
void dnstap__message__free_unpacked
|
||||
(Dnstap__Message *message,
|
||||
ProtobufCAllocator *allocator);
|
||||
/* --- per-message closures --- */
|
||||
|
||||
typedef void (*Dnstap__Dnstap_Closure)
|
||||
(const Dnstap__Dnstap *message,
|
||||
void *closure_data);
|
||||
typedef void (*Dnstap__Message_Closure)
|
||||
(const Dnstap__Message *message,
|
||||
void *closure_data);
|
||||
|
||||
/* --- services --- */
|
||||
|
||||
|
||||
/* --- descriptors --- */
|
||||
|
||||
extern const ProtobufCEnumDescriptor dnstap__socket_family__descriptor;
|
||||
extern const ProtobufCEnumDescriptor dnstap__socket_protocol__descriptor;
|
||||
extern const ProtobufCMessageDescriptor dnstap__dnstap__descriptor;
|
||||
extern const ProtobufCEnumDescriptor dnstap__dnstap__type__descriptor;
|
||||
extern const ProtobufCMessageDescriptor dnstap__message__descriptor;
|
||||
extern const ProtobufCEnumDescriptor dnstap__message__type__descriptor;
|
||||
|
||||
PROTOBUF_C_END_DECLS
|
||||
|
||||
|
||||
#endif /* PROTOBUF_dnstap_2fdnstap_2eproto__INCLUDED */
|
262
dnstap/dnstap.proto
Normal file
262
dnstap/dnstap.proto
Normal file
@ -0,0 +1,262 @@
|
||||
// dnstap: flexible, structured event replication format for DNS software
|
||||
//
|
||||
// This file contains the protobuf schemas for the "dnstap" structured event
|
||||
// replication format for DNS software.
|
||||
|
||||
// Written in 2013-2014 by Farsight Security, Inc.
|
||||
//
|
||||
// To the extent possible under law, the author(s) have dedicated all
|
||||
// copyright and related and neighboring rights to this file to the public
|
||||
// domain worldwide. This file is distributed without any warranty.
|
||||
//
|
||||
// You should have received a copy of the CC0 Public Domain Dedication along
|
||||
// with this file. If not, see:
|
||||
//
|
||||
// <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
|
||||
package dnstap;
|
||||
|
||||
// "Dnstap": this is the top-level dnstap type, which is a "union" type that
|
||||
// contains other kinds of dnstap payloads, although currently only one type
|
||||
// of dnstap payload is defined.
|
||||
// See: https://developers.google.com/protocol-buffers/docs/techniques#union
|
||||
message Dnstap {
|
||||
// DNS server identity.
|
||||
// If enabled, this is the identity string of the DNS server which generated
|
||||
// this message. Typically this would be the same string as returned by an
|
||||
// "NSID" (RFC 5001) query.
|
||||
optional bytes identity = 1;
|
||||
|
||||
// DNS server version.
|
||||
// If enabled, this is the version string of the DNS server which generated
|
||||
// this message. Typically this would be the same string as returned by a
|
||||
// "version.bind" query.
|
||||
optional bytes version = 2;
|
||||
|
||||
// Extra data for this payload.
|
||||
// This field can be used for adding an arbitrary byte-string annotation to
|
||||
// the payload. No encoding or interpretation is applied or enforced.
|
||||
optional bytes extra = 3;
|
||||
|
||||
// Identifies which field below is filled in.
|
||||
enum Type {
|
||||
MESSAGE = 1;
|
||||
}
|
||||
required Type type = 15;
|
||||
|
||||
// One of the following will be filled in.
|
||||
optional Message message = 14;
|
||||
}
|
||||
|
||||
// SocketFamily: the network protocol family of a socket. This specifies how
|
||||
// to interpret "network address" fields.
|
||||
enum SocketFamily {
|
||||
INET = 1; // IPv4 (RFC 791)
|
||||
INET6 = 2; // IPv6 (RFC 2460)
|
||||
}
|
||||
|
||||
// SocketProtocol: the transport protocol of a socket. This specifies how to
|
||||
// interpret "transport port" fields.
|
||||
enum SocketProtocol {
|
||||
UDP = 1; // User Datagram Protocol (RFC 768)
|
||||
TCP = 2; // Transmission Control Protocol (RFC 793)
|
||||
}
|
||||
|
||||
// Message: a wire-format (RFC 1035 section 4) DNS message and associated
|
||||
// metadata. Applications generating "Message" payloads should follow
|
||||
// certain requirements based on the MessageType, see below.
|
||||
message Message {
|
||||
|
||||
// There are eight types of "Message" defined that correspond to the
|
||||
// four arrows in the following diagram, slightly modified from RFC 1035
|
||||
// section 2:
|
||||
|
||||
// +---------+ +----------+ +--------+
|
||||
// | | query | | query | |
|
||||
// | Stub |-SQ--------CQ->| Recursive|-RQ----AQ->| Auth. |
|
||||
// | Resolver| | Server | | Name |
|
||||
// | |<-SR--------CR-| |<-RR----AR-| Server |
|
||||
// +---------+ response | | response | |
|
||||
// +----------+ +--------+
|
||||
|
||||
// Each arrow has two Type values each, one for each "end" of each arrow,
|
||||
// because these are considered to be distinct events. Each end of each
|
||||
// arrow on the diagram above has been marked with a two-letter Type
|
||||
// mnemonic. Clockwise from upper left, these mnemonic values are:
|
||||
//
|
||||
// SQ: STUB_QUERY
|
||||
// CQ: CLIENT_QUERY
|
||||
// RQ: RESOLVER_QUERY
|
||||
// AQ: AUTH_QUERY
|
||||
// AR: AUTH_RESPONSE
|
||||
// RR: RESOLVER_RESPONSE
|
||||
// CR: CLIENT_RESPONSE
|
||||
// SR: STUB_RESPONSE
|
||||
|
||||
// Two additional types of "Message" have been defined for the
|
||||
// "forwarding" case where an upstream DNS server is responsible for
|
||||
// further recursion. These are not shown on the diagram above, but have
|
||||
// the following mnemonic values:
|
||||
|
||||
// FQ: FORWARDER_QUERY
|
||||
// FR: FORWARDER_RESPONSE
|
||||
|
||||
// The "Message" Type values are defined below.
|
||||
|
||||
enum Type {
|
||||
// AUTH_QUERY is a DNS query message received from a resolver by an
|
||||
// authoritative name server, from the perspective of the authorative
|
||||
// name server.
|
||||
AUTH_QUERY = 1;
|
||||
|
||||
// AUTH_RESPONSE is a DNS response message sent from an authoritative
|
||||
// name server to a resolver, from the perspective of the authoritative
|
||||
// name server.
|
||||
AUTH_RESPONSE = 2;
|
||||
|
||||
// RESOLVER_QUERY is a DNS query message sent from a resolver to an
|
||||
// authoritative name server, from the perspective of the resolver.
|
||||
// Resolvers typically clear the RD (recursion desired) bit when
|
||||
// sending queries.
|
||||
RESOLVER_QUERY = 3;
|
||||
|
||||
// RESOLVER_RESPONSE is a DNS response message received from an
|
||||
// authoritative name server by a resolver, from the perspective of
|
||||
// the resolver.
|
||||
RESOLVER_RESPONSE = 4;
|
||||
|
||||
// CLIENT_QUERY is a DNS query message sent from a client to a DNS
|
||||
// server which is expected to perform further recursion, from the
|
||||
// perspective of the DNS server. The client may be a stub resolver or
|
||||
// forwarder or some other type of software which typically sets the RD
|
||||
// (recursion desired) bit when querying the DNS server. The DNS server
|
||||
// may be a simple forwarding proxy or it may be a full recursive
|
||||
// resolver.
|
||||
CLIENT_QUERY = 5;
|
||||
|
||||
// CLIENT_RESPONSE is a DNS response message sent from a DNS server to
|
||||
// a client, from the perspective of the DNS server. The DNS server
|
||||
// typically sets the RA (recursion available) bit when responding.
|
||||
CLIENT_RESPONSE = 6;
|
||||
|
||||
// FORWARDER_QUERY is a DNS query message sent from a downstream DNS
|
||||
// server to an upstream DNS server which is expected to perform
|
||||
// further recursion, from the perspective of the downstream DNS
|
||||
// server.
|
||||
FORWARDER_QUERY = 7;
|
||||
|
||||
// FORWARDER_RESPONSE is a DNS response message sent from an upstream
|
||||
// DNS server performing recursion to a downstream DNS server, from the
|
||||
// perspective of the downstream DNS server.
|
||||
FORWARDER_RESPONSE = 8;
|
||||
|
||||
// STUB_QUERY is a DNS query message sent from a stub resolver to a DNS
|
||||
// server, from the perspective of the stub resolver.
|
||||
STUB_QUERY = 9;
|
||||
|
||||
// STUB_RESPONSE is a DNS response message sent from a DNS server to a
|
||||
// stub resolver, from the perspective of the stub resolver.
|
||||
STUB_RESPONSE = 10;
|
||||
}
|
||||
|
||||
// One of the Type values described above.
|
||||
required Type type = 1;
|
||||
|
||||
// One of the SocketFamily values described above.
|
||||
optional SocketFamily socket_family = 2;
|
||||
|
||||
// One of the SocketProtocol values described above.
|
||||
optional SocketProtocol socket_protocol = 3;
|
||||
|
||||
// The network address of the message initiator.
|
||||
// For SocketFamily INET, this field is 4 octets (IPv4 address).
|
||||
// For SocketFamily INET6, this field is 16 octets (IPv6 address).
|
||||
optional bytes query_address = 4;
|
||||
|
||||
// The network address of the message responder.
|
||||
// For SocketFamily INET, this field is 4 octets (IPv4 address).
|
||||
// For SocketFamily INET6, this field is 16 octets (IPv6 address).
|
||||
optional bytes response_address = 5;
|
||||
|
||||
// The transport port of the message initiator.
|
||||
// This is a 16-bit UDP or TCP port number, depending on SocketProtocol.
|
||||
optional uint32 query_port = 6;
|
||||
|
||||
// The transport port of the message responder.
|
||||
// This is a 16-bit UDP or TCP port number, depending on SocketProtocol.
|
||||
optional uint32 response_port = 7;
|
||||
|
||||
// The time at which the DNS query message was sent or received, depending
|
||||
// on whether this is an AUTH_QUERY, RESOLVER_QUERY, or CLIENT_QUERY.
|
||||
// This is the number of seconds since the UNIX epoch.
|
||||
optional uint64 query_time_sec = 8;
|
||||
|
||||
// The time at which the DNS query message was sent or received.
|
||||
// This is the seconds fraction, expressed as a count of nanoseconds.
|
||||
optional fixed32 query_time_nsec = 9;
|
||||
|
||||
// The initiator's original wire-format DNS query message, verbatim.
|
||||
optional bytes query_message = 10;
|
||||
|
||||
// The "zone" or "bailiwick" pertaining to the DNS query message.
|
||||
// This is a wire-format DNS domain name.
|
||||
optional bytes query_zone = 11;
|
||||
|
||||
// The time at which the DNS response message was sent or received,
|
||||
// depending on whether this is an AUTH_RESPONSE, RESOLVER_RESPONSE, or
|
||||
// CLIENT_RESPONSE.
|
||||
// This is the number of seconds since the UNIX epoch.
|
||||
optional uint64 response_time_sec = 12;
|
||||
|
||||
// The time at which the DNS response message was sent or received.
|
||||
// This is the seconds fraction, expressed as a count of nanoseconds.
|
||||
optional fixed32 response_time_nsec = 13;
|
||||
|
||||
// The responder's original wire-format DNS response message, verbatim.
|
||||
optional bytes response_message = 14;
|
||||
}
|
||||
|
||||
// All fields except for 'type' in the Message schema are optional.
|
||||
// It is recommended that at least the following fields be filled in for
|
||||
// particular types of Messages.
|
||||
|
||||
// AUTH_QUERY:
|
||||
// socket_family, socket_protocol
|
||||
// query_address, query_port
|
||||
// query_message
|
||||
// query_time_sec, query_time_nsec
|
||||
|
||||
// AUTH_RESPONSE:
|
||||
// socket_family, socket_protocol
|
||||
// query_address, query_port
|
||||
// query_time_sec, query_time_nsec
|
||||
// response_message
|
||||
// response_time_sec, response_time_nsec
|
||||
|
||||
// RESOLVER_QUERY:
|
||||
// socket_family, socket_protocol
|
||||
// query_name, query_type, query_class
|
||||
// query_message
|
||||
// query_time_sec, query_time_nsec
|
||||
// query_zone
|
||||
// response_address, response_port
|
||||
|
||||
// RESOLVER_RESPONSE:
|
||||
// socket_family, socket_protocol
|
||||
// query_name, query_type, query_class
|
||||
// query_time_sec, query_time_nsec
|
||||
// query_zone
|
||||
// response_address, response_port
|
||||
// response_message
|
||||
// response_time_sec, response_time_nsec
|
||||
|
||||
// CLIENT_QUERY:
|
||||
// socket_family, socket_protocol
|
||||
// query_message
|
||||
// query_time_sec, query_time_nsec
|
||||
|
||||
// CLIENT_RESPONSE:
|
||||
// socket_family, socket_protocol
|
||||
// query_time_sec, query_time_nsec
|
||||
// response_message
|
||||
// response_time_sec, response_time_nsec
|
17
dnstap/dnstap_config.h
Normal file
17
dnstap/dnstap_config.h
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef UNBOUND_DNSTAP_CONFIG_H
|
||||
#define UNBOUND_DNSTAP_CONFIG_H
|
||||
|
||||
/*
|
||||
* Process this file (dnstap_config.h.in) with AC_CONFIG_FILES to generate
|
||||
* dnstap_config.h.
|
||||
*
|
||||
* This file exists so that USE_DNSTAP can be used without including config.h.
|
||||
*/
|
||||
|
||||
#if 1 /* ENABLE_DNSTAP */
|
||||
# ifndef USE_DNSTAP
|
||||
# define USE_DNSTAP 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif /* UNBOUND_DNSTAP_CONFIG_H */
|
17
dnstap/dnstap_config.h.in
Normal file
17
dnstap/dnstap_config.h.in
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef UNBOUND_DNSTAP_CONFIG_H
|
||||
#define UNBOUND_DNSTAP_CONFIG_H
|
||||
|
||||
/*
|
||||
* Process this file (dnstap_config.h.in) with AC_CONFIG_FILES to generate
|
||||
* dnstap_config.h.
|
||||
*
|
||||
* This file exists so that USE_DNSTAP can be used without including config.h.
|
||||
*/
|
||||
|
||||
#if @ENABLE_DNSTAP@ /* ENABLE_DNSTAP */
|
||||
# ifndef USE_DNSTAP
|
||||
# define USE_DNSTAP 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif /* UNBOUND_DNSTAP_CONFIG_H */
|
@ -20,3 +20,4 @@ Luca Bruno - patch for windows support in libunbound hosts and resolvconf().
|
||||
Tom Hendrikx - contributed split-itar.sh a useful script to 5011-track ITAR.
|
||||
Daisuke HIGASHI - patch for rrset-roundrobin and minimal-responses.
|
||||
Simon Perrault - DNS64 module.
|
||||
Robert Edmonds - dnstap code.
|
||||
|
@ -1,3 +1,10 @@
|
||||
5 August 2014: Wouter
|
||||
- dnstap support, with a patch from Farsight Security, written by
|
||||
Robert Edmonds. The --enable-dnstap needs libfstrm and protobuf-c.
|
||||
It is BSD licensed (see dnstap/dnstap.c).
|
||||
Building with --enable-dnstap needs pkg-config with this patch.
|
||||
- Noted dnstap in doc/README and doc/CREDITS.
|
||||
|
||||
1 August 2014: Wouter
|
||||
- Patch add msg, rrset, infra and key cache sizes to stats command
|
||||
from Maciej Soltysiak.
|
||||
|
@ -4,6 +4,7 @@ http://unbound.net
|
||||
|
||||
This software is under BSD license, see LICENSE for details.
|
||||
The DNS64 module has BSD license in dns64/dns64.c.
|
||||
The DNSTAP code has BSD license in dnstap/dnstap.c.
|
||||
|
||||
* Download the latest release version of this software from
|
||||
http://unbound.net
|
||||
|
@ -233,7 +233,7 @@ libworker_setup(struct ub_ctx* ctx, int is_bg, struct event_base* eb)
|
||||
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, w->sslctx,
|
||||
cfg->delay_close);
|
||||
cfg->delay_close, NULL);
|
||||
if(!w->is_bg || w->is_bg_thread) {
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
}
|
||||
|
159
pkg.m4
Normal file
159
pkg.m4
Normal file
@ -0,0 +1,159 @@
|
||||
# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
|
||||
# serial 1 (pkg-config-0.24)
|
||||
#
|
||||
# Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# PKG_PROG_PKG_CONFIG([MIN-VERSION])
|
||||
# ----------------------------------
|
||||
AC_DEFUN([PKG_PROG_PKG_CONFIG],
|
||||
[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
|
||||
m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])
|
||||
m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$])
|
||||
AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])
|
||||
AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path])
|
||||
AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path])
|
||||
|
||||
if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
|
||||
AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
|
||||
fi
|
||||
if test -n "$PKG_CONFIG"; then
|
||||
_pkg_min_version=m4_default([$1], [0.9.0])
|
||||
AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
|
||||
if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
PKG_CONFIG=""
|
||||
fi
|
||||
fi[]dnl
|
||||
])# PKG_PROG_PKG_CONFIG
|
||||
|
||||
# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
|
||||
#
|
||||
# Check to see whether a particular set of modules exists. Similar
|
||||
# to PKG_CHECK_MODULES(), but does not set variables or print errors.
|
||||
#
|
||||
# Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
|
||||
# only at the first occurence in configure.ac, so if the first place
|
||||
# it's called might be skipped (such as if it is within an "if", you
|
||||
# have to call PKG_CHECK_EXISTS manually
|
||||
# --------------------------------------------------------------
|
||||
AC_DEFUN([PKG_CHECK_EXISTS],
|
||||
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
|
||||
if test -n "$PKG_CONFIG" && \
|
||||
AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
|
||||
m4_default([$2], [:])
|
||||
m4_ifvaln([$3], [else
|
||||
$3])dnl
|
||||
fi])
|
||||
|
||||
# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
|
||||
# ---------------------------------------------
|
||||
m4_define([_PKG_CONFIG],
|
||||
[if test -n "$$1"; then
|
||||
pkg_cv_[]$1="$$1"
|
||||
elif test -n "$PKG_CONFIG"; then
|
||||
PKG_CHECK_EXISTS([$3],
|
||||
[pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`
|
||||
test "x$?" != "x0" && pkg_failed=yes ],
|
||||
[pkg_failed=yes])
|
||||
else
|
||||
pkg_failed=untried
|
||||
fi[]dnl
|
||||
])# _PKG_CONFIG
|
||||
|
||||
# _PKG_SHORT_ERRORS_SUPPORTED
|
||||
# -----------------------------
|
||||
AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
|
||||
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
|
||||
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
|
||||
_pkg_short_errors_supported=yes
|
||||
else
|
||||
_pkg_short_errors_supported=no
|
||||
fi[]dnl
|
||||
])# _PKG_SHORT_ERRORS_SUPPORTED
|
||||
|
||||
|
||||
# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
|
||||
# [ACTION-IF-NOT-FOUND])
|
||||
#
|
||||
#
|
||||
# Note that if there is a possibility the first call to
|
||||
# PKG_CHECK_MODULES might not happen, you should be sure to include an
|
||||
# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
|
||||
#
|
||||
#
|
||||
# --------------------------------------------------------------
|
||||
AC_DEFUN([PKG_CHECK_MODULES],
|
||||
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
|
||||
AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
|
||||
AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
|
||||
|
||||
pkg_failed=no
|
||||
AC_MSG_CHECKING([for $1])
|
||||
|
||||
_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
|
||||
_PKG_CONFIG([$1][_LIBS], [libs], [$2])
|
||||
|
||||
m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
|
||||
and $1[]_LIBS to avoid the need to call pkg-config.
|
||||
See the pkg-config man page for more details.])
|
||||
|
||||
if test $pkg_failed = yes; then
|
||||
AC_MSG_RESULT([no])
|
||||
_PKG_SHORT_ERRORS_SUPPORTED
|
||||
if test $_pkg_short_errors_supported = yes; then
|
||||
$1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
|
||||
else
|
||||
$1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
|
||||
fi
|
||||
# Put the nasty error message in config.log where it belongs
|
||||
echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
|
||||
|
||||
m4_default([$4], [AC_MSG_ERROR(
|
||||
[Package requirements ($2) were not met:
|
||||
|
||||
$$1_PKG_ERRORS
|
||||
|
||||
Consider adjusting the PKG_CONFIG_PATH environment variable if you
|
||||
installed software in a non-standard prefix.
|
||||
|
||||
_PKG_TEXT])[]dnl
|
||||
])
|
||||
elif test $pkg_failed = untried; then
|
||||
AC_MSG_RESULT([no])
|
||||
m4_default([$4], [AC_MSG_FAILURE(
|
||||
[The pkg-config script could not be found or is too old. Make sure it
|
||||
is in your PATH or set the PKG_CONFIG environment variable to the full
|
||||
path to pkg-config.
|
||||
|
||||
_PKG_TEXT
|
||||
|
||||
To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl
|
||||
])
|
||||
else
|
||||
$1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
|
||||
$1[]_LIBS=$pkg_cv_[]$1[]_LIBS
|
||||
AC_MSG_RESULT([yes])
|
||||
$3
|
||||
fi[]dnl
|
||||
])# PKG_CHECK_MODULES
|
@ -848,7 +848,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, void* sslctx,
|
||||
comm_point_callback_t* cb, void *cb_arg)
|
||||
struct dt_env* dtenv, comm_point_callback_t* cb, void *cb_arg)
|
||||
{
|
||||
struct listen_dnsport* front = (struct listen_dnsport*)
|
||||
malloc(sizeof(struct listen_dnsport));
|
||||
@ -882,6 +882,7 @@ listen_create(struct comm_base* base, struct listen_port* ports,
|
||||
listen_delete(front);
|
||||
return NULL;
|
||||
}
|
||||
cp->dtenv = dtenv;
|
||||
cp->do_not_close = 1;
|
||||
if(!listen_cp_insert(cp, front)) {
|
||||
log_err("malloc failed");
|
||||
|
@ -129,6 +129,7 @@ void listening_ports_free(struct listen_port* list);
|
||||
* @param tcp_accept_count: max number of simultaneous TCP connections
|
||||
* from clients.
|
||||
* @param sslctx: nonNULL if ssl context.
|
||||
* @param dtenv: nonNULL if dnstap enabled.
|
||||
* @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.
|
||||
@ -136,7 +137,8 @@ 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,
|
||||
void* sslctx, comm_point_callback_t* cb, void* cb_arg);
|
||||
void* sslctx, struct dt_env *dtenv, comm_point_callback_t* cb,
|
||||
void* cb_arg);
|
||||
|
||||
/**
|
||||
* delete the listening structure
|
||||
|
@ -58,6 +58,7 @@
|
||||
#include "util/random.h"
|
||||
#include "util/fptr_wlist.h"
|
||||
#include "ldns/sbuffer.h"
|
||||
#include "dnstap/dnstap.h"
|
||||
#ifdef HAVE_OPENSSL_SSL_H
|
||||
#include <openssl/ssl.h>
|
||||
#endif
|
||||
@ -75,11 +76,10 @@
|
||||
#define OUTBOUND_UDP_RETRY 1
|
||||
|
||||
/** initiate TCP transaction for serviced query */
|
||||
static void serviced_tcp_initiate(struct outside_network* outnet,
|
||||
struct serviced_query* sq, sldns_buffer* buff);
|
||||
static void serviced_tcp_initiate(struct serviced_query* sq, sldns_buffer* buff);
|
||||
/** with a fd available, randomize and send UDP */
|
||||
static int randomize_and_send_udp(struct outside_network* outnet,
|
||||
struct pending* pend, sldns_buffer* packet, int timeout);
|
||||
static int randomize_and_send_udp(struct pending* pend, sldns_buffer* packet,
|
||||
int timeout);
|
||||
|
||||
int
|
||||
pending_cmp(const void* key1, const void* key2)
|
||||
@ -378,7 +378,7 @@ outnet_send_wait_udp(struct outside_network* outnet)
|
||||
free(pend->pkt); /* freeing now makes get_mem correct */
|
||||
pend->pkt = NULL;
|
||||
pend->pkt_len = 0;
|
||||
if(!randomize_and_send_udp(outnet, pend, outnet->udp_buff,
|
||||
if(!randomize_and_send_udp(pend, outnet->udp_buff,
|
||||
pend->timeout)) {
|
||||
/* callback error on pending */
|
||||
if(pend->cb) {
|
||||
@ -588,7 +588,7 @@ outside_network_create(struct comm_base *base, size_t bufsize,
|
||||
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* sslctx, int delayclose)
|
||||
void* sslctx, int delayclose, struct dt_env* dtenv)
|
||||
{
|
||||
struct outside_network* outnet = (struct outside_network*)
|
||||
calloc(1, sizeof(struct outside_network));
|
||||
@ -604,6 +604,9 @@ outside_network_create(struct comm_base *base, size_t bufsize,
|
||||
outnet->infra = infra;
|
||||
outnet->rnd = rnd;
|
||||
outnet->sslctx = sslctx;
|
||||
#ifdef USE_DNSTAP
|
||||
outnet->dtenv = dtenv;
|
||||
#endif
|
||||
outnet->svcd_overhead = 0;
|
||||
outnet->want_to_quit = 0;
|
||||
outnet->unwanted_threshold = unwanted_threshold;
|
||||
@ -992,10 +995,10 @@ select_ifport(struct outside_network* outnet, struct pending* pend,
|
||||
}
|
||||
|
||||
static int
|
||||
randomize_and_send_udp(struct outside_network* outnet, struct pending* pend,
|
||||
sldns_buffer* packet, int timeout)
|
||||
randomize_and_send_udp(struct pending* pend, sldns_buffer* packet, int timeout)
|
||||
{
|
||||
struct timeval tv;
|
||||
struct outside_network* outnet = pend->sq->outnet;
|
||||
|
||||
/* select id */
|
||||
if(!select_id(outnet, pend, packet)) {
|
||||
@ -1028,30 +1031,38 @@ randomize_and_send_udp(struct outside_network* outnet, struct pending* pend,
|
||||
tv.tv_usec = (timeout%1000)*1000;
|
||||
#endif
|
||||
comm_timer_set(pend->timer, &tv);
|
||||
|
||||
#ifdef USE_DNSTAP
|
||||
if(outnet->dtenv &&
|
||||
(outnet->dtenv->log_resolver_query_messages ||
|
||||
outnet->dtenv->log_forwarder_query_messages))
|
||||
dt_msg_send_outside_query(outnet->dtenv, &pend->addr, comm_udp,
|
||||
pend->sq->zone, pend->sq->zonelen, packet);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct pending*
|
||||
pending_udp_query(struct outside_network* outnet, sldns_buffer* packet,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, int timeout,
|
||||
comm_point_callback_t* cb, void* cb_arg)
|
||||
pending_udp_query(struct serviced_query* sq, struct sldns_buffer* packet,
|
||||
int timeout, comm_point_callback_t* cb, void* cb_arg)
|
||||
{
|
||||
struct pending* pend = (struct pending*)calloc(1, sizeof(*pend));
|
||||
if(!pend) return NULL;
|
||||
pend->outnet = outnet;
|
||||
pend->addrlen = addrlen;
|
||||
memmove(&pend->addr, addr, addrlen);
|
||||
pend->outnet = sq->outnet;
|
||||
pend->sq = sq;
|
||||
pend->addrlen = sq->addrlen;
|
||||
memmove(&pend->addr, &sq->addr, sq->addrlen);
|
||||
pend->cb = cb;
|
||||
pend->cb_arg = cb_arg;
|
||||
pend->node.key = pend;
|
||||
pend->timer = comm_timer_create(outnet->base, pending_udp_timer_cb,
|
||||
pend->timer = comm_timer_create(sq->outnet->base, pending_udp_timer_cb,
|
||||
pend);
|
||||
if(!pend->timer) {
|
||||
free(pend);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(outnet->unused_fds == NULL) {
|
||||
if(sq->outnet->unused_fds == NULL) {
|
||||
/* no unused fd, cannot create a new port (randomly) */
|
||||
verbose(VERB_ALGO, "no fds available, udp query waiting");
|
||||
pend->timeout = timeout;
|
||||
@ -1064,15 +1075,15 @@ pending_udp_query(struct outside_network* outnet, sldns_buffer* packet,
|
||||
return NULL;
|
||||
}
|
||||
/* put at end of waiting list */
|
||||
if(outnet->udp_wait_last)
|
||||
outnet->udp_wait_last->next_waiting = pend;
|
||||
if(sq->outnet->udp_wait_last)
|
||||
sq->outnet->udp_wait_last->next_waiting = pend;
|
||||
else
|
||||
outnet->udp_wait_first = pend;
|
||||
outnet->udp_wait_last = pend;
|
||||
sq->outnet->udp_wait_first = pend;
|
||||
sq->outnet->udp_wait_last = pend;
|
||||
return pend;
|
||||
}
|
||||
if(!randomize_and_send_udp(outnet, pend, packet, timeout)) {
|
||||
pending_delete(outnet, pend);
|
||||
if(!randomize_and_send_udp(pend, packet, timeout)) {
|
||||
pending_delete(sq->outnet, pend);
|
||||
return NULL;
|
||||
}
|
||||
return pend;
|
||||
@ -1114,12 +1125,11 @@ outnet_tcptimer(void* arg)
|
||||
use_free_buffer(outnet);
|
||||
}
|
||||
|
||||
struct waiting_tcp*
|
||||
pending_tcp_query(struct outside_network* outnet, sldns_buffer* packet,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, int timeout,
|
||||
comm_point_callback_t* callback, void* callback_arg, int ssl_upstream)
|
||||
struct waiting_tcp*
|
||||
pending_tcp_query(struct serviced_query* sq, sldns_buffer* packet,
|
||||
int timeout, comm_point_callback_t* callback, void* callback_arg)
|
||||
{
|
||||
struct pending_tcp* pend = outnet->tcp_free;
|
||||
struct pending_tcp* pend = sq->outnet->tcp_free;
|
||||
struct waiting_tcp* w;
|
||||
struct timeval tv;
|
||||
uint16_t id;
|
||||
@ -1129,20 +1139,20 @@ pending_tcp_query(struct outside_network* outnet, sldns_buffer* packet,
|
||||
if(!w) {
|
||||
return NULL;
|
||||
}
|
||||
if(!(w->timer = comm_timer_create(outnet->base, outnet_tcptimer, w))) {
|
||||
if(!(w->timer = comm_timer_create(sq->outnet->base, outnet_tcptimer, w))) {
|
||||
free(w);
|
||||
return NULL;
|
||||
}
|
||||
w->pkt = NULL;
|
||||
w->pkt_len = 0;
|
||||
id = ((unsigned)ub_random(outnet->rnd)>>8) & 0xffff;
|
||||
id = ((unsigned)ub_random(sq->outnet->rnd)>>8) & 0xffff;
|
||||
LDNS_ID_SET(sldns_buffer_begin(packet), id);
|
||||
memcpy(&w->addr, addr, addrlen);
|
||||
w->addrlen = addrlen;
|
||||
w->outnet = outnet;
|
||||
memcpy(&w->addr, &sq->addr, sq->addrlen);
|
||||
w->addrlen = sq->addrlen;
|
||||
w->outnet = sq->outnet;
|
||||
w->cb = callback;
|
||||
w->cb_arg = callback_arg;
|
||||
w->ssl_upstream = ssl_upstream;
|
||||
w->ssl_upstream = sq->ssl_upstream;
|
||||
#ifndef S_SPLINT_S
|
||||
tv.tv_sec = timeout;
|
||||
tv.tv_usec = 0;
|
||||
@ -1155,16 +1165,23 @@ pending_tcp_query(struct outside_network* outnet, sldns_buffer* packet,
|
||||
waiting_tcp_delete(w);
|
||||
return NULL;
|
||||
}
|
||||
#ifdef USE_DNSTAP
|
||||
if(sq->outnet->dtenv &&
|
||||
(sq->outnet->dtenv->log_resolver_query_messages ||
|
||||
sq->outnet->dtenv->log_forwarder_query_messages))
|
||||
dt_msg_send_outside_query(sq->outnet->dtenv, &sq->addr,
|
||||
comm_tcp, sq->zone, sq->zonelen, packet);
|
||||
#endif
|
||||
} else {
|
||||
/* queue up */
|
||||
w->pkt = (uint8_t*)w + sizeof(struct waiting_tcp);
|
||||
w->pkt_len = sldns_buffer_limit(packet);
|
||||
memmove(w->pkt, sldns_buffer_begin(packet), w->pkt_len);
|
||||
w->next_waiting = NULL;
|
||||
if(outnet->tcp_wait_last)
|
||||
outnet->tcp_wait_last->next_waiting = w;
|
||||
else outnet->tcp_wait_first = w;
|
||||
outnet->tcp_wait_last = w;
|
||||
if(sq->outnet->tcp_wait_last)
|
||||
sq->outnet->tcp_wait_last->next_waiting = w;
|
||||
else sq->outnet->tcp_wait_first = w;
|
||||
sq->outnet->tcp_wait_last = w;
|
||||
}
|
||||
return w;
|
||||
}
|
||||
@ -1426,8 +1443,8 @@ serviced_udp_send(struct serviced_query* sq, sldns_buffer* buff)
|
||||
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);
|
||||
sq->pending = pending_udp_query(sq->outnet, buff, &sq->addr,
|
||||
sq->addrlen, rtt, serviced_udp_callback, sq);
|
||||
sq->pending = pending_udp_query(sq, buff, rtt,
|
||||
serviced_udp_callback, sq);
|
||||
if(!sq->pending)
|
||||
return 0;
|
||||
return 1;
|
||||
@ -1576,13 +1593,21 @@ serviced_tcp_callback(struct comm_point* c, void* arg, int error,
|
||||
if(error==NETEVENT_NOERROR)
|
||||
infra_update_tcp_works(sq->outnet->infra, &sq->addr,
|
||||
sq->addrlen, sq->zone, sq->zonelen);
|
||||
#ifdef USE_DNSTAP
|
||||
if(sq->outnet->dtenv &&
|
||||
(sq->outnet->dtenv->log_resolver_response_messages ||
|
||||
sq->outnet->dtenv->log_forwarder_response_messages))
|
||||
dt_msg_send_outside_response(sq->outnet->dtenv, &sq->addr,
|
||||
c->type, sq->zone, sq->zonelen, sq->qbuf, sq->qbuflen,
|
||||
&sq->last_sent_time, sq->outnet->now_tv, c->buffer);
|
||||
#endif
|
||||
if(error==NETEVENT_NOERROR && sq->status == serviced_query_TCP_EDNS &&
|
||||
(LDNS_RCODE_WIRE(sldns_buffer_begin(c->buffer)) ==
|
||||
LDNS_RCODE_FORMERR || LDNS_RCODE_WIRE(sldns_buffer_begin(
|
||||
c->buffer)) == LDNS_RCODE_NOTIMPL) ) {
|
||||
/* attempt to fallback to nonEDNS */
|
||||
sq->status = serviced_query_TCP_EDNS_fallback;
|
||||
serviced_tcp_initiate(sq->outnet, sq, c->buffer);
|
||||
serviced_tcp_initiate(sq, c->buffer);
|
||||
return 0;
|
||||
} else if(error==NETEVENT_NOERROR &&
|
||||
sq->status == serviced_query_TCP_EDNS_fallback &&
|
||||
@ -1634,16 +1659,14 @@ serviced_tcp_callback(struct comm_point* c, void* arg, int error,
|
||||
}
|
||||
|
||||
static void
|
||||
serviced_tcp_initiate(struct outside_network* outnet,
|
||||
struct serviced_query* sq, sldns_buffer* buff)
|
||||
serviced_tcp_initiate(struct serviced_query* sq, sldns_buffer* buff)
|
||||
{
|
||||
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->ssl_upstream);
|
||||
sq->pending = pending_tcp_query(sq, buff, TCP_AUTH_QUERY_TIMEOUT,
|
||||
serviced_tcp_callback, sq);
|
||||
if(!sq->pending) {
|
||||
/* delete from tree so that a retry by above layer does not
|
||||
* clash with this entry */
|
||||
@ -1667,9 +1690,8 @@ serviced_tcp_send(struct serviced_query* sq, sldns_buffer* buff)
|
||||
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->ssl_upstream);
|
||||
sq->pending = pending_tcp_query(sq, buff, TCP_AUTH_QUERY_TIMEOUT,
|
||||
serviced_tcp_callback, sq);
|
||||
return sq->pending != NULL;
|
||||
}
|
||||
|
||||
@ -1730,6 +1752,14 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
|
||||
serviced_callbacks(sq, error, c, rep);
|
||||
return 0;
|
||||
}
|
||||
#ifdef USE_DNSTAP
|
||||
if(outnet->dtenv &&
|
||||
(outnet->dtenv->log_resolver_response_messages ||
|
||||
outnet->dtenv->log_forwarder_response_messages))
|
||||
dt_msg_send_outside_response(outnet->dtenv, &sq->addr, c->type,
|
||||
sq->zone, sq->zonelen, sq->qbuf, sq->qbuflen,
|
||||
&sq->last_sent_time, sq->outnet->now_tv, c->buffer);
|
||||
#endif
|
||||
if(!fallback_tcp) {
|
||||
if( (sq->status == serviced_query_UDP_EDNS
|
||||
||sq->status == serviced_query_UDP_EDNS_FRAG)
|
||||
@ -1818,7 +1848,7 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
|
||||
/* if we have unfinished EDNS_fallback, start again */
|
||||
sq->status = serviced_query_TCP_EDNS;
|
||||
else sq->status = serviced_query_TCP;
|
||||
serviced_tcp_initiate(outnet, sq, c->buffer);
|
||||
serviced_tcp_initiate(sq, c->buffer);
|
||||
return 0;
|
||||
}
|
||||
/* yay! an answer */
|
||||
|
@ -45,6 +45,7 @@
|
||||
|
||||
#include "util/rbtree.h"
|
||||
#include "util/netevent.h"
|
||||
#include "dnstap/dnstap_config.h"
|
||||
struct pending;
|
||||
struct pending_timeout;
|
||||
struct ub_randstate;
|
||||
@ -55,6 +56,8 @@ struct infra_cache;
|
||||
struct port_comm;
|
||||
struct port_if;
|
||||
struct sldns_buffer;
|
||||
struct serviced_query;
|
||||
struct dt_env;
|
||||
|
||||
/**
|
||||
* Send queries to outside servers and wait for answers from servers.
|
||||
@ -125,6 +128,10 @@ struct outside_network {
|
||||
struct ub_randstate* rnd;
|
||||
/** ssl context to create ssl wrapped TCP with DNS connections */
|
||||
void* sslctx;
|
||||
#ifdef USE_DNSTAP
|
||||
/** dnstap environment */
|
||||
struct dt_env* dtenv;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Array of tcp pending used for outgoing TCP connections.
|
||||
@ -212,6 +219,8 @@ struct pending {
|
||||
void* cb_arg;
|
||||
/** the outside network it is part of */
|
||||
struct outside_network* outnet;
|
||||
/** the corresponding serviced_query */
|
||||
struct serviced_query* sq;
|
||||
|
||||
/*---- filled if udp pending is waiting -----*/
|
||||
/** next in waiting list. */
|
||||
@ -387,6 +396,7 @@ struct serviced_query {
|
||||
* @param sslctx: context to create outgoing connections with (if enabled).
|
||||
* @param delayclose: if not 0, udp sockets are delayed before timeout closure.
|
||||
* msec to wait on timeouted udp sockets.
|
||||
* @param dtenv: environment to send dnstap events 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,
|
||||
@ -395,7 +405,7 @@ struct outside_network* outside_network_create(struct comm_base* base,
|
||||
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* sslctx, int delayclose);
|
||||
void* sslctx, int delayclose, struct dt_env *dtenv);
|
||||
|
||||
/**
|
||||
* Delete outside_network structure.
|
||||
@ -412,39 +422,32 @@ void outside_network_quit_prepare(struct outside_network* outnet);
|
||||
/**
|
||||
* Send UDP query, create pending answer.
|
||||
* Changes the ID for the query to be random and unique for that destination.
|
||||
* @param outnet: provides the event handling
|
||||
* @param sq: serviced query.
|
||||
* @param packet: wireformat query to send to destination.
|
||||
* @param addr: address to send to.
|
||||
* @param addrlen: length of addr.
|
||||
* @param timeout: in milliseconds from now.
|
||||
* @param callback: function to call on error, timeout or reply.
|
||||
* @param callback_arg: user argument for callback function.
|
||||
* @return: NULL on error for malloc or socket. Else the pending query object.
|
||||
*/
|
||||
struct pending* pending_udp_query(struct outside_network* outnet,
|
||||
struct sldns_buffer* packet, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, int timeout, comm_point_callback_t* callback,
|
||||
struct pending* pending_udp_query(struct serviced_query* sq,
|
||||
struct sldns_buffer* packet, int timeout, comm_point_callback_t* callback,
|
||||
void* callback_arg);
|
||||
|
||||
/**
|
||||
* Send TCP query. May wait for TCP buffer. Selects ID to be random, and
|
||||
* checks id.
|
||||
* @param outnet: provides the event handling.
|
||||
* @param sq: serviced query.
|
||||
* @param packet: wireformat query to send to destination. copied from.
|
||||
* @param addr: address to send to.
|
||||
* @param addrlen: length of addr.
|
||||
* @param timeout: in seconds from now.
|
||||
* Timer starts running now. Timer may expire if all buffers are used,
|
||||
* without any query been sent to the server yet.
|
||||
* @param callback: function to call on error, timeout or reply.
|
||||
* @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,
|
||||
struct sldns_buffer* packet, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, int timeout, comm_point_callback_t* callback,
|
||||
void* callback_arg, int ssl_upstream);
|
||||
struct waiting_tcp* pending_tcp_query(struct serviced_query* sq,
|
||||
struct sldns_buffer* packet, int timeout, comm_point_callback_t* callback,
|
||||
void* callback_arg);
|
||||
|
||||
/**
|
||||
* Delete pending answer.
|
||||
|
@ -734,7 +734,8 @@ 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),
|
||||
void* ATTR_UNUSED(sslctx), comm_point_callback_t* cb, void* cb_arg)
|
||||
void* ATTR_UNUSED(sslctx), struct dt_env* ATTR_UNUSED(dtenv),
|
||||
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));
|
||||
@ -901,7 +902,7 @@ outside_network_create(struct comm_base* base, size_t bufsize,
|
||||
int ATTR_UNUSED(numavailports), size_t ATTR_UNUSED(unwanted_threshold),
|
||||
void (*unwanted_action)(void*), void* ATTR_UNUSED(unwanted_param),
|
||||
int ATTR_UNUSED(do_udp), void* ATTR_UNUSED(sslctx),
|
||||
int ATTR_UNUSED(delayclose))
|
||||
int ATTR_UNUSED(delayclose), struct dt_env* ATTR_UNUSED(dtenv))
|
||||
{
|
||||
struct replay_runtime* runtime = (struct replay_runtime*)base;
|
||||
struct outside_network* outnet = calloc(1,
|
||||
@ -934,11 +935,11 @@ outside_network_quit_prepare(struct outside_network* ATTR_UNUSED(outnet))
|
||||
}
|
||||
|
||||
struct pending*
|
||||
pending_udp_query(struct outside_network* outnet, sldns_buffer* packet,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, int timeout,
|
||||
comm_point_callback_t* callback, void* callback_arg)
|
||||
pending_udp_query(struct serviced_query* sq, sldns_buffer* packet,
|
||||
int timeout, comm_point_callback_t* callback, void* callback_arg)
|
||||
{
|
||||
struct replay_runtime* runtime = (struct replay_runtime*)outnet->base;
|
||||
struct replay_runtime* runtime = (struct replay_runtime*)
|
||||
sq->outnet->base;
|
||||
struct fake_pending* pend = (struct fake_pending*)calloc(1,
|
||||
sizeof(struct fake_pending));
|
||||
log_assert(pend);
|
||||
@ -947,8 +948,8 @@ pending_udp_query(struct outside_network* outnet, sldns_buffer* packet,
|
||||
sldns_buffer_write(pend->buffer, sldns_buffer_begin(packet),
|
||||
sldns_buffer_limit(packet));
|
||||
sldns_buffer_flip(pend->buffer);
|
||||
memcpy(&pend->addr, addr, addrlen);
|
||||
pend->addrlen = addrlen;
|
||||
memcpy(&pend->addr, &sq->addr, sq->addrlen);
|
||||
pend->addrlen = sq->addrlen;
|
||||
pend->callback = callback;
|
||||
pend->cb_arg = callback_arg;
|
||||
pend->timeout = timeout/1000;
|
||||
@ -983,13 +984,12 @@ pending_udp_query(struct outside_network* outnet, sldns_buffer* packet,
|
||||
return (struct pending*)pend;
|
||||
}
|
||||
|
||||
struct waiting_tcp*
|
||||
pending_tcp_query(struct outside_network* outnet, sldns_buffer* packet,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, int timeout,
|
||||
comm_point_callback_t* callback, void* callback_arg,
|
||||
int ATTR_UNUSED(ssl_upstream))
|
||||
struct waiting_tcp*
|
||||
pending_tcp_query(struct serviced_query* sq, sldns_buffer* packet,
|
||||
int timeout, comm_point_callback_t* callback, void* callback_arg)
|
||||
{
|
||||
struct replay_runtime* runtime = (struct replay_runtime*)outnet->base;
|
||||
struct replay_runtime* runtime = (struct replay_runtime*)
|
||||
sq->outnet->base;
|
||||
struct fake_pending* pend = (struct fake_pending*)calloc(1,
|
||||
sizeof(struct fake_pending));
|
||||
log_assert(pend);
|
||||
@ -998,8 +998,8 @@ pending_tcp_query(struct outside_network* outnet, sldns_buffer* packet,
|
||||
sldns_buffer_write(pend->buffer, sldns_buffer_begin(packet),
|
||||
sldns_buffer_limit(packet));
|
||||
sldns_buffer_flip(pend->buffer);
|
||||
memcpy(&pend->addr, addr, addrlen);
|
||||
pend->addrlen = addrlen;
|
||||
memcpy(&pend->addr, &sq->addr, sq->addrlen);
|
||||
pend->addrlen = sq->addrlen;
|
||||
pend->callback = callback;
|
||||
pend->cb_arg = callback_arg;
|
||||
pend->timeout = timeout;
|
||||
|
@ -211,6 +211,10 @@ config_create(void)
|
||||
if(!(cfg->module_conf = strdup("validator iterator"))) goto error_exit;
|
||||
if(!(cfg->val_nsec3_key_iterations =
|
||||
strdup("1024 150 2048 500 4096 2500"))) goto error_exit;
|
||||
#if defined(DNSTAP_SOCKET_PATH)
|
||||
if(!(cfg->dnstap_socket_path = strdup(DNSTAP_SOCKET_PATH)))
|
||||
goto error_exit;
|
||||
#endif
|
||||
return cfg;
|
||||
error_exit:
|
||||
config_delete(cfg);
|
||||
@ -888,6 +892,9 @@ config_delete(struct config_file* cfg)
|
||||
free(cfg->server_cert_file);
|
||||
free(cfg->control_key_file);
|
||||
free(cfg->control_cert_file);
|
||||
free(cfg->dnstap_socket_path);
|
||||
free(cfg->dnstap_identity);
|
||||
free(cfg->dnstap_version);
|
||||
free(cfg);
|
||||
}
|
||||
|
||||
|
@ -311,6 +311,32 @@ struct config_file {
|
||||
|
||||
/* Synthetize all AAAA record despite the presence of an authoritative one */
|
||||
int dns64_synthall;
|
||||
|
||||
/** true to enable dnstap support */
|
||||
int dnstap;
|
||||
/** dnstap socket path */
|
||||
char* dnstap_socket_path;
|
||||
/** true to send "identity" via dnstap */
|
||||
int dnstap_send_identity;
|
||||
/** true to send "version" via dnstap */
|
||||
int dnstap_send_version;
|
||||
/** dnstap "identity", hostname is used if "". */
|
||||
char* dnstap_identity;
|
||||
/** dnstap "version", package version is used if "". */
|
||||
char* dnstap_version;
|
||||
|
||||
/** true to log dnstap RESOLVER_QUERY message events */
|
||||
int dnstap_log_resolver_query_messages;
|
||||
/** true to log dnstap RESOLVER_RESPONSE message events */
|
||||
int dnstap_log_resolver_response_messages;
|
||||
/** true to log dnstap CLIENT_QUERY message events */
|
||||
int dnstap_log_client_query_messages;
|
||||
/** true to log dnstap CLIENT_RESPONSE message events */
|
||||
int dnstap_log_client_response_messages;
|
||||
/** true to log dnstap FORWARDER_QUERY message events */
|
||||
int dnstap_log_forwarder_query_messages;
|
||||
/** true to log dnstap FORWARDER_RESPONSE message events */
|
||||
int dnstap_log_forwarder_response_messages;
|
||||
};
|
||||
|
||||
/**
|
||||
|
2210
util/configlexer.c
2210
util/configlexer.c
File diff suppressed because it is too large
Load Diff
@ -327,6 +327,25 @@ rrset-roundrobin{COLON} { YDVAR(1, VAR_RRSET_ROUNDROBIN) }
|
||||
max-udp-size{COLON} { YDVAR(1, VAR_MAX_UDP_SIZE) }
|
||||
dns64-prefix{COLON} { YDVAR(1, VAR_DNS64_PREFIX) }
|
||||
dns64-synthall{COLON} { YDVAR(1, VAR_DNS64_SYNTHALL) }
|
||||
dnstap{COLON} { YDVAR(0, VAR_DNSTAP) }
|
||||
dnstap-enable{COLON} { YDVAR(1, VAR_DNSTAP_ENABLE) }
|
||||
dnstap-socket-path{COLON} { YDVAR(1, VAR_DNSTAP_SOCKET_PATH) }
|
||||
dnstap-send-identity{COLON} { YDVAR(1, VAR_DNSTAP_SEND_IDENTITY) }
|
||||
dnstap-send-version{COLON} { YDVAR(1, VAR_DNSTAP_SEND_VERSION) }
|
||||
dnstap-identity{COLON} { YDVAR(1, VAR_DNSTAP_IDENTITY) }
|
||||
dnstap-version{COLON} { YDVAR(1, VAR_DNSTAP_VERSION) }
|
||||
dnstap-log-resolver-query-messages{COLON} {
|
||||
YDVAR(1, VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES) }
|
||||
dnstap-log-resolver-response-messages{COLON} {
|
||||
YDVAR(1, VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES) }
|
||||
dnstap-log-client-query-messages{COLON} {
|
||||
YDVAR(1, VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES) }
|
||||
dnstap-log-client-response-messages{COLON} {
|
||||
YDVAR(1, VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES) }
|
||||
dnstap-log-forwarder-query-messages{COLON} {
|
||||
YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES) }
|
||||
dnstap-log-forwarder-response-messages{COLON} {
|
||||
YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES) }
|
||||
<INITIAL,val>{NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++; }
|
||||
|
||||
/* Quoted strings. Strip leading and ending quotes */
|
||||
|
1420
util/configparser.c
1420
util/configparser.c
File diff suppressed because it is too large
Load Diff
@ -178,7 +178,20 @@ extern int yydebug;
|
||||
VAR_DELAY_CLOSE = 387,
|
||||
VAR_UNBLOCK_LAN_ZONES = 388,
|
||||
VAR_DNS64_PREFIX = 389,
|
||||
VAR_DNS64_SYNTHALL = 390
|
||||
VAR_DNS64_SYNTHALL = 390,
|
||||
VAR_DNSTAP = 391,
|
||||
VAR_DNSTAP_ENABLE = 392,
|
||||
VAR_DNSTAP_SOCKET_PATH = 393,
|
||||
VAR_DNSTAP_SEND_IDENTITY = 394,
|
||||
VAR_DNSTAP_SEND_VERSION = 395,
|
||||
VAR_DNSTAP_IDENTITY = 396,
|
||||
VAR_DNSTAP_VERSION = 397,
|
||||
VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES = 398,
|
||||
VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES = 399,
|
||||
VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES = 400,
|
||||
VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES = 401,
|
||||
VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES = 402,
|
||||
VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES = 403
|
||||
};
|
||||
#endif
|
||||
/* Tokens. */
|
||||
@ -315,6 +328,19 @@ extern int yydebug;
|
||||
#define VAR_UNBLOCK_LAN_ZONES 388
|
||||
#define VAR_DNS64_PREFIX 389
|
||||
#define VAR_DNS64_SYNTHALL 390
|
||||
#define VAR_DNSTAP 391
|
||||
#define VAR_DNSTAP_ENABLE 392
|
||||
#define VAR_DNSTAP_SOCKET_PATH 393
|
||||
#define VAR_DNSTAP_SEND_IDENTITY 394
|
||||
#define VAR_DNSTAP_SEND_VERSION 395
|
||||
#define VAR_DNSTAP_IDENTITY 396
|
||||
#define VAR_DNSTAP_VERSION 397
|
||||
#define VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES 398
|
||||
#define VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES 399
|
||||
#define VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES 400
|
||||
#define VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES 401
|
||||
#define VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES 402
|
||||
#define VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES 403
|
||||
|
||||
|
||||
|
||||
@ -328,7 +354,7 @@ typedef union YYSTYPE
|
||||
|
||||
|
||||
/* Line 2049 of yacc.c */
|
||||
#line 332 "util/configparser.h"
|
||||
#line 358 "util/configparser.h"
|
||||
} YYSTYPE;
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
||||
|
@ -107,12 +107,21 @@ extern struct config_parser_state* cfg_parser;
|
||||
%token VAR_STUB_FIRST VAR_MINIMAL_RESPONSES VAR_RRSET_ROUNDROBIN
|
||||
%token VAR_MAX_UDP_SIZE VAR_DELAY_CLOSE VAR_UNBLOCK_LAN_ZONES
|
||||
%token VAR_DNS64_PREFIX VAR_DNS64_SYNTHALL
|
||||
%token VAR_DNSTAP VAR_DNSTAP_ENABLE VAR_DNSTAP_SOCKET_PATH
|
||||
%token VAR_DNSTAP_SEND_IDENTITY VAR_DNSTAP_SEND_VERSION
|
||||
%token VAR_DNSTAP_IDENTITY VAR_DNSTAP_VERSION
|
||||
%token VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES
|
||||
%token VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES
|
||||
%token VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES
|
||||
%token VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES
|
||||
%token VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES
|
||||
%token VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES
|
||||
|
||||
%%
|
||||
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
|
||||
toplevelvar: serverstart contents_server | stubstart contents_stub |
|
||||
forwardstart contents_forward | pythonstart contents_py |
|
||||
rcstart contents_rc
|
||||
rcstart contents_rc | dtstart contents_dt
|
||||
;
|
||||
|
||||
/* server: declaration */
|
||||
@ -1317,6 +1326,122 @@ rc_control_cert_file: VAR_CONTROL_CERT_FILE STRING_ARG
|
||||
cfg_parser->cfg->control_cert_file = $2;
|
||||
}
|
||||
;
|
||||
dtstart: VAR_DNSTAP
|
||||
{
|
||||
OUTYY(("\nP(dnstap:)\n"));
|
||||
}
|
||||
;
|
||||
contents_dt: contents_dt content_dt
|
||||
| ;
|
||||
content_dt: dt_dnstap_enable | dt_dnstap_socket_path |
|
||||
dt_dnstap_send_identity | dt_dnstap_send_version |
|
||||
dt_dnstap_identity | dt_dnstap_version |
|
||||
dt_dnstap_log_resolver_query_messages |
|
||||
dt_dnstap_log_resolver_response_messages |
|
||||
dt_dnstap_log_client_query_messages |
|
||||
dt_dnstap_log_client_response_messages |
|
||||
dt_dnstap_log_forwarder_query_messages |
|
||||
dt_dnstap_log_forwarder_response_messages
|
||||
;
|
||||
dt_dnstap_enable: VAR_DNSTAP_ENABLE STRING_ARG
|
||||
{
|
||||
OUTYY(("P(dt_dnstap_enable:%s)\n", $2));
|
||||
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
|
||||
yyerror("expected yes or no.");
|
||||
else cfg_parser->cfg->dnstap = (strcmp($2, "yes")==0);
|
||||
}
|
||||
;
|
||||
dt_dnstap_socket_path: VAR_DNSTAP_SOCKET_PATH STRING_ARG
|
||||
{
|
||||
OUTYY(("P(dt_dnstap_socket_path:%s)\n", $2));
|
||||
free(cfg_parser->cfg->dnstap_socket_path);
|
||||
cfg_parser->cfg->dnstap_socket_path = $2;
|
||||
}
|
||||
;
|
||||
dt_dnstap_send_identity: VAR_DNSTAP_SEND_IDENTITY STRING_ARG
|
||||
{
|
||||
OUTYY(("P(dt_dnstap_send_identity:%s)\n", $2));
|
||||
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
|
||||
yyerror("expected yes or no.");
|
||||
else cfg_parser->cfg->dnstap_send_identity = (strcmp($2, "yes")==0);
|
||||
}
|
||||
;
|
||||
dt_dnstap_send_version: VAR_DNSTAP_SEND_VERSION STRING_ARG
|
||||
{
|
||||
OUTYY(("P(dt_dnstap_send_version:%s)\n", $2));
|
||||
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
|
||||
yyerror("expected yes or no.");
|
||||
else cfg_parser->cfg->dnstap_send_version = (strcmp($2, "yes")==0);
|
||||
}
|
||||
;
|
||||
dt_dnstap_identity: VAR_DNSTAP_IDENTITY STRING_ARG
|
||||
{
|
||||
OUTYY(("P(dt_dnstap_identity:%s)\n", $2));
|
||||
free(cfg_parser->cfg->dnstap_identity);
|
||||
cfg_parser->cfg->dnstap_identity = $2;
|
||||
}
|
||||
;
|
||||
dt_dnstap_version: VAR_DNSTAP_VERSION STRING_ARG
|
||||
{
|
||||
OUTYY(("P(dt_dnstap_version:%s)\n", $2));
|
||||
free(cfg_parser->cfg->dnstap_version);
|
||||
cfg_parser->cfg->dnstap_version = $2;
|
||||
}
|
||||
;
|
||||
dt_dnstap_log_resolver_query_messages: VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES STRING_ARG
|
||||
{
|
||||
OUTYY(("P(dt_dnstap_log_resolver_query_messages:%s)\n", $2));
|
||||
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
|
||||
yyerror("expected yes or no.");
|
||||
else cfg_parser->cfg->dnstap_log_resolver_query_messages =
|
||||
(strcmp($2, "yes")==0);
|
||||
}
|
||||
;
|
||||
dt_dnstap_log_resolver_response_messages: VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES STRING_ARG
|
||||
{
|
||||
OUTYY(("P(dt_dnstap_log_resolver_response_messages:%s)\n", $2));
|
||||
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
|
||||
yyerror("expected yes or no.");
|
||||
else cfg_parser->cfg->dnstap_log_resolver_response_messages =
|
||||
(strcmp($2, "yes")==0);
|
||||
}
|
||||
;
|
||||
dt_dnstap_log_client_query_messages: VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES STRING_ARG
|
||||
{
|
||||
OUTYY(("P(dt_dnstap_log_client_query_messages:%s)\n", $2));
|
||||
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
|
||||
yyerror("expected yes or no.");
|
||||
else cfg_parser->cfg->dnstap_log_client_query_messages =
|
||||
(strcmp($2, "yes")==0);
|
||||
}
|
||||
;
|
||||
dt_dnstap_log_client_response_messages: VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES STRING_ARG
|
||||
{
|
||||
OUTYY(("P(dt_dnstap_log_client_response_messages:%s)\n", $2));
|
||||
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
|
||||
yyerror("expected yes or no.");
|
||||
else cfg_parser->cfg->dnstap_log_client_response_messages =
|
||||
(strcmp($2, "yes")==0);
|
||||
}
|
||||
;
|
||||
dt_dnstap_log_forwarder_query_messages: VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES STRING_ARG
|
||||
{
|
||||
OUTYY(("P(dt_dnstap_log_forwarder_query_messages:%s)\n", $2));
|
||||
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
|
||||
yyerror("expected yes or no.");
|
||||
else cfg_parser->cfg->dnstap_log_forwarder_query_messages =
|
||||
(strcmp($2, "yes")==0);
|
||||
}
|
||||
;
|
||||
dt_dnstap_log_forwarder_response_messages: VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES STRING_ARG
|
||||
{
|
||||
OUTYY(("P(dt_dnstap_log_forwarder_response_messages:%s)\n", $2));
|
||||
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
|
||||
yyerror("expected yes or no.");
|
||||
else cfg_parser->cfg->dnstap_log_forwarder_response_messages =
|
||||
(strcmp($2, "yes")==0);
|
||||
}
|
||||
;
|
||||
pythonstart: VAR_PYTHON
|
||||
{
|
||||
OUTYY(("\nP(python:)\n"));
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include "util/fptr_wlist.h"
|
||||
#include "ldns/pkthdr.h"
|
||||
#include "ldns/sbuffer.h"
|
||||
#include "dnstap/dnstap.h"
|
||||
#ifdef HAVE_OPENSSL_SSL_H
|
||||
#include <openssl/ssl.h>
|
||||
#endif
|
||||
@ -1940,7 +1941,19 @@ comm_point_send_reply(struct comm_reply *repinfo)
|
||||
else
|
||||
comm_point_send_udp_msg(repinfo->c, repinfo->c->buffer,
|
||||
(struct sockaddr*)&repinfo->addr, repinfo->addrlen);
|
||||
#ifdef USE_DNSTAP
|
||||
if(repinfo->c->dtenv != NULL &&
|
||||
repinfo->c->dtenv->log_client_response_messages)
|
||||
dt_msg_send_client_response(repinfo->c->dtenv,
|
||||
&repinfo->addr, repinfo->c->type, repinfo->c->buffer);
|
||||
#endif
|
||||
} else {
|
||||
#ifdef USE_DNSTAP
|
||||
if(repinfo->c->tcp_parent->dtenv != NULL &&
|
||||
repinfo->c->tcp_parent->dtenv->log_client_response_messages)
|
||||
dt_msg_send_client_response(repinfo->c->tcp_parent->dtenv,
|
||||
&repinfo->addr, repinfo->c->type, repinfo->c->buffer);
|
||||
#endif
|
||||
comm_point_start_listening(repinfo->c, -1, TCP_QUERY_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
@ -188,6 +188,10 @@ struct comm_point {
|
||||
comm_ssl_shake_hs_write
|
||||
} ssl_shake_state;
|
||||
|
||||
/* -------- dnstap ------- */
|
||||
/** the dnstap environment */
|
||||
struct dt_env* dtenv;
|
||||
|
||||
/** is this a UDP, TCP-accept or TCP socket. */
|
||||
enum comm_point_type {
|
||||
/** UDP socket - handle datagrams. */
|
||||
|
Loading…
Reference in New Issue
Block a user