mirror of
https://github.com/NLnetLabs/unbound.git
synced 2024-09-21 06:37:08 +00:00
python contribution from Zdenek Vasicek and Marek Vavrusa (BSD licensed).
git-svn-id: file:///svn/unbound/trunk@1556 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
910167b38c
commit
0799d77798
@ -292,7 +292,7 @@ util/configparser.c util/configparser.h: $(srcdir)/util/configparser.y
|
||||
clean:
|
||||
rm -f *.o *.d *.lo *~ tags
|
||||
rm -f unbound unbound-checkconf unbound-host unbound-control unbound-control-setup libunbound.la
|
||||
rm -rf autom4te.cache .libs build doc/html
|
||||
rm -rf autom4te.cache .libs build doc/html doc/xml
|
||||
|
||||
realclean: clean
|
||||
rm -f config.status config.log config.h.in config.h
|
||||
|
122
ac_pkg_swig.m4
Normal file
122
ac_pkg_swig.m4
Normal file
@ -0,0 +1,122 @@
|
||||
# ===========================================================================
|
||||
# http://autoconf-archive.cryp.to/ac_pkg_swig.html
|
||||
# ===========================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AC_PROG_SWIG([major.minor.micro])
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# This macro searches for a SWIG installation on your system. If found you
|
||||
# should call SWIG via $(SWIG). You can use the optional first argument to
|
||||
# check if the version of the available SWIG is greater than or equal to
|
||||
# the value of the argument. It should have the format: N[.N[.N]] (N is a
|
||||
# number between 0 and 999. Only the first N is mandatory.)
|
||||
#
|
||||
# If the version argument is given (e.g. 1.3.17), AC_PROG_SWIG checks that
|
||||
# the swig package is this version number or higher.
|
||||
#
|
||||
# In configure.in, use as:
|
||||
#
|
||||
# AC_PROG_SWIG(1.3.17)
|
||||
# SWIG_ENABLE_CXX
|
||||
# SWIG_MULTI_MODULE_SUPPORT
|
||||
# SWIG_PYTHON
|
||||
#
|
||||
# LAST MODIFICATION
|
||||
#
|
||||
# 2008-04-12
|
||||
#
|
||||
# COPYLEFT
|
||||
#
|
||||
# Copyright (c) 2008 Sebastian Huber <sebastian-huber@web.de>
|
||||
# Copyright (c) 2008 Alan W. Irwin <irwin@beluga.phys.uvic.ca>
|
||||
# Copyright (c) 2008 Rafael Laboissiere <rafael@laboissiere.net>
|
||||
# Copyright (c) 2008 Andrew Collier <colliera@ukzn.ac.za>
|
||||
#
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# As a special exception, the respective Autoconf Macro's copyright owner
|
||||
# gives unlimited permission to copy, distribute and modify the configure
|
||||
# scripts that are the output of Autoconf when processing the Macro. You
|
||||
# need not follow the terms of the GNU General Public License when using
|
||||
# or distributing such scripts, even though portions of the text of the
|
||||
# Macro appear in them. The GNU General Public License (GPL) does govern
|
||||
# all other use of the material that constitutes the Autoconf Macro.
|
||||
#
|
||||
# This special exception to the GPL applies to versions of the Autoconf
|
||||
# Macro released by the Autoconf Macro Archive. When you make and
|
||||
# distribute a modified version of the Autoconf Macro, you may extend this
|
||||
# special exception to the GPL to apply to your modified version as well.
|
||||
|
||||
AC_DEFUN([AC_PROG_SWIG],[
|
||||
AC_PATH_PROG([SWIG],[swig])
|
||||
if test -z "$SWIG" ; then
|
||||
AC_MSG_WARN([cannot find 'swig' program. You should look at http://www.swig.org])
|
||||
SWIG='echo "Error: SWIG is not installed. You should look at http://www.swig.org" ; false'
|
||||
elif test -n "$1" ; then
|
||||
AC_MSG_CHECKING([for SWIG version])
|
||||
[swig_version=`$SWIG -version 2>&1 | grep 'SWIG Version' | sed 's/.*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*/\1/g'`]
|
||||
AC_MSG_RESULT([$swig_version])
|
||||
if test -n "$swig_version" ; then
|
||||
# Calculate the required version number components
|
||||
[required=$1]
|
||||
[required_major=`echo $required | sed 's/[^0-9].*//'`]
|
||||
if test -z "$required_major" ; then
|
||||
[required_major=0]
|
||||
fi
|
||||
[required=`echo $required | sed 's/[0-9]*[^0-9]//'`]
|
||||
[required_minor=`echo $required | sed 's/[^0-9].*//'`]
|
||||
if test -z "$required_minor" ; then
|
||||
[required_minor=0]
|
||||
fi
|
||||
[required=`echo $required | sed 's/[0-9]*[^0-9]//'`]
|
||||
[required_patch=`echo $required | sed 's/[^0-9].*//'`]
|
||||
if test -z "$required_patch" ; then
|
||||
[required_patch=0]
|
||||
fi
|
||||
# Calculate the available version number components
|
||||
[available=$swig_version]
|
||||
[available_major=`echo $available | sed 's/[^0-9].*//'`]
|
||||
if test -z "$available_major" ; then
|
||||
[available_major=0]
|
||||
fi
|
||||
[available=`echo $available | sed 's/[0-9]*[^0-9]//'`]
|
||||
[available_minor=`echo $available | sed 's/[^0-9].*//'`]
|
||||
if test -z "$available_minor" ; then
|
||||
[available_minor=0]
|
||||
fi
|
||||
[available=`echo $available | sed 's/[0-9]*[^0-9]//'`]
|
||||
[available_patch=`echo $available | sed 's/[^0-9].*//'`]
|
||||
if test -z "$available_patch" ; then
|
||||
[available_patch=0]
|
||||
fi
|
||||
if test $available_major -ne $required_major \
|
||||
-o $available_minor -ne $required_minor \
|
||||
-o $available_patch -lt $required_patch ; then
|
||||
AC_MSG_WARN([SWIG version >= $1 is required. You have $swig_version. You should look at http://www.swig.org])
|
||||
SWIG='echo "Error: SWIG version >= $1 is required. You have '"$swig_version"'. You should look at http://www.swig.org" ; false'
|
||||
else
|
||||
AC_MSG_NOTICE([SWIG executable is '$SWIG'])
|
||||
SWIG_LIB=`$SWIG -swiglib`
|
||||
AC_MSG_NOTICE([SWIG library directory is '$SWIG_LIB'])
|
||||
fi
|
||||
else
|
||||
AC_MSG_WARN([cannot determine SWIG version])
|
||||
SWIG='echo "Error: Cannot determine SWIG version. You should look at http://www.swig.org" ; false'
|
||||
fi
|
||||
fi
|
||||
AC_SUBST([SWIG_LIB])
|
||||
])
|
194
acx_python.m4
Normal file
194
acx_python.m4
Normal file
@ -0,0 +1,194 @@
|
||||
AC_DEFUN([AC_PYTHON_DEVEL],[
|
||||
#
|
||||
# Allow the use of a (user set) custom python version
|
||||
#
|
||||
AC_ARG_VAR([PYTHON_VERSION],[The installed Python
|
||||
version to use, for example '2.3'. This string
|
||||
will be appended to the Python interpreter
|
||||
canonical name.])
|
||||
|
||||
AC_PATH_PROG([PYTHON],[python[$PYTHON_VERSION]])
|
||||
if test -z "$PYTHON"; then
|
||||
AC_MSG_ERROR([Cannot find python$PYTHON_VERSION in your system path])
|
||||
PYTHON_VERSION=""
|
||||
fi
|
||||
|
||||
#
|
||||
# Check for a version of Python >= 2.1.0
|
||||
#
|
||||
AC_MSG_CHECKING([for a version of Python >= '2.1.0'])
|
||||
ac_supports_python_ver=`$PYTHON -c "import sys, string; \
|
||||
ver = string.split(sys.version)[[0]]; \
|
||||
print ver >= '2.1.0'"`
|
||||
if test "$ac_supports_python_ver" != "True"; then
|
||||
if test -z "$PYTHON_NOVERSIONCHECK"; then
|
||||
AC_MSG_RESULT([no])
|
||||
AC_MSG_FAILURE([
|
||||
This version of the AC@&t@_PYTHON_DEVEL macro
|
||||
doesn't work properly with versions of Python before
|
||||
2.1.0. You may need to re-run configure, setting the
|
||||
variables PYTHON_CPPFLAGS, PYTHON_LDFLAGS, PYTHON_SITE_PKG,
|
||||
PYTHON_EXTRA_LIBS and PYTHON_EXTRA_LDFLAGS by hand.
|
||||
Moreover, to disable this check, set PYTHON_NOVERSIONCHECK
|
||||
to something else than an empty string.
|
||||
])
|
||||
else
|
||||
AC_MSG_RESULT([skip at user request])
|
||||
fi
|
||||
else
|
||||
AC_MSG_RESULT([yes])
|
||||
fi
|
||||
|
||||
#
|
||||
# if the macro parameter ``version'' is set, honour it
|
||||
#
|
||||
if test -n "$1"; then
|
||||
AC_MSG_CHECKING([for a version of Python $1])
|
||||
ac_supports_python_ver=`$PYTHON -c "import sys, string; \
|
||||
ver = string.split(sys.version)[[0]]; \
|
||||
print ver $1"`
|
||||
if test "$ac_supports_python_ver" = "True"; then
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
AC_MSG_ERROR([this package requires Python $1.
|
||||
If you have it installed, but it isn't the default Python
|
||||
interpreter in your system path, please pass the PYTHON_VERSION
|
||||
variable to configure. See ``configure --help'' for reference.
|
||||
])
|
||||
PYTHON_VERSION=""
|
||||
fi
|
||||
fi
|
||||
|
||||
#
|
||||
# Check if you have distutils, else fail
|
||||
#
|
||||
AC_MSG_CHECKING([for the distutils Python package])
|
||||
ac_distutils_result=`$PYTHON -c "import distutils" 2>&1`
|
||||
if test -z "$ac_distutils_result"; then
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
AC_MSG_ERROR([cannot import Python module "distutils".
|
||||
Please check your Python installation. The error was:
|
||||
$ac_distutils_result])
|
||||
PYTHON_VERSION=""
|
||||
fi
|
||||
|
||||
#
|
||||
# Check for Python include path
|
||||
#
|
||||
AC_MSG_CHECKING([for Python include path])
|
||||
if test -z "$PYTHON_CPPFLAGS"; then
|
||||
python_path=`$PYTHON -c "import distutils.sysconfig; \
|
||||
print distutils.sysconfig.get_python_inc();"`
|
||||
if test -n "${python_path}"; then
|
||||
python_path="-I$python_path"
|
||||
fi
|
||||
PYTHON_CPPFLAGS=$python_path
|
||||
fi
|
||||
AC_MSG_RESULT([$PYTHON_CPPFLAGS])
|
||||
AC_SUBST([PYTHON_CPPFLAGS])
|
||||
|
||||
#
|
||||
# Check for Python library path
|
||||
#
|
||||
AC_MSG_CHECKING([for Python library path])
|
||||
if test -z "$PYTHON_LDFLAGS"; then
|
||||
# (makes two attempts to ensure we've got a version number
|
||||
# from the interpreter)
|
||||
py_version=`$PYTHON -c "from distutils.sysconfig import *; \
|
||||
from string import join; \
|
||||
print join(get_config_vars('VERSION'))"`
|
||||
if test "$py_version" == "[None]"; then
|
||||
if test -n "$PYTHON_VERSION"; then
|
||||
py_version=$PYTHON_VERSION
|
||||
else
|
||||
py_version=`$PYTHON -c "import sys; \
|
||||
print sys.version[[:3]]"`
|
||||
fi
|
||||
fi
|
||||
|
||||
PYTHON_LDFLAGS=`$PYTHON -c "from distutils.sysconfig import *; \
|
||||
from string import join; \
|
||||
print '-L' + get_python_lib(0,1), \
|
||||
'-lpython';"`$py_version
|
||||
fi
|
||||
AC_MSG_RESULT([$PYTHON_LDFLAGS])
|
||||
AC_SUBST([PYTHON_LDFLAGS])
|
||||
|
||||
#
|
||||
# Check for site packages
|
||||
#
|
||||
AC_MSG_CHECKING([for Python site-packages path])
|
||||
if test -z "$PYTHON_SITE_PKG"; then
|
||||
PYTHON_SITE_PKG=`$PYTHON -c "import distutils.sysconfig; \
|
||||
print distutils.sysconfig.get_python_lib(0,0);"`
|
||||
fi
|
||||
AC_MSG_RESULT([$PYTHON_SITE_PKG])
|
||||
AC_SUBST([PYTHON_SITE_PKG])
|
||||
|
||||
#
|
||||
# libraries which must be linked in when embedding
|
||||
#
|
||||
AC_MSG_CHECKING(python extra libraries)
|
||||
if test -z "$PYTHON_EXTRA_LIBS"; then
|
||||
PYTHON_EXTRA_LIBS=`$PYTHON -c "import distutils.sysconfig; \
|
||||
conf = distutils.sysconfig.get_config_var; \
|
||||
print conf('LOCALMODLIBS'), conf('LIBS')"`
|
||||
fi
|
||||
AC_MSG_RESULT([$PYTHON_EXTRA_LIBS])
|
||||
AC_SUBST(PYTHON_EXTRA_LIBS)
|
||||
|
||||
#
|
||||
# linking flags needed when embedding
|
||||
#
|
||||
AC_MSG_CHECKING(python extra linking flags)
|
||||
if test -z "$PYTHON_EXTRA_LDFLAGS"; then
|
||||
PYTHON_EXTRA_LDFLAGS=`$PYTHON -c "import distutils.sysconfig; \
|
||||
conf = distutils.sysconfig.get_config_var; \
|
||||
print conf('LINKFORSHARED')"`
|
||||
fi
|
||||
AC_MSG_RESULT([$PYTHON_EXTRA_LDFLAGS])
|
||||
AC_SUBST(PYTHON_EXTRA_LDFLAGS)
|
||||
|
||||
#
|
||||
# final check to see if everything compiles alright
|
||||
#
|
||||
AC_MSG_CHECKING([consistency of all components of python development environment])
|
||||
AC_LANG_PUSH([C])
|
||||
# save current global flags
|
||||
LIBS="$ac_save_LIBS $PYTHON_LDFLAGS"
|
||||
CPPFLAGS="$ac_save_CPPFLAGS $PYTHON_CPPFLAGS"
|
||||
AC_TRY_LINK([
|
||||
#include <Python.h>
|
||||
],[
|
||||
Py_Initialize();
|
||||
],[pythonexists=yes],[pythonexists=no])
|
||||
|
||||
AC_MSG_RESULT([$pythonexists])
|
||||
|
||||
if test ! "$pythonexists" = "yes"; then
|
||||
AC_MSG_ERROR([
|
||||
Could not link test program to Python. Maybe the main Python library has been
|
||||
installed in some non-standard library path. If so, pass it to configure,
|
||||
via the LDFLAGS environment variable.
|
||||
Example: ./configure LDFLAGS="-L/usr/non-standard-path/python/lib"
|
||||
============================================================================
|
||||
ERROR!
|
||||
You probably have to install the development version of the Python package
|
||||
for your distribution. The exact name of this package varies among them.
|
||||
============================================================================
|
||||
])
|
||||
PYTHON_VERSION=""
|
||||
fi
|
||||
AC_LANG_POP
|
||||
# turn back to default flags
|
||||
CPPFLAGS="$ac_save_CPPFLAGS"
|
||||
LIBS="$ac_save_LIBS"
|
||||
|
||||
#
|
||||
# all done!
|
||||
#
|
||||
])
|
||||
|
15
config.h.in
15
config.h.in
@ -167,6 +167,9 @@
|
||||
/* Define to 1 if you have the <pwd.h> header file. */
|
||||
#undef HAVE_PWD_H
|
||||
|
||||
/* Define if you have Python libraries and header files. */
|
||||
#undef HAVE_PYTHON
|
||||
|
||||
/* Define to 1 if you have the `random' function. */
|
||||
#undef HAVE_RANDOM
|
||||
|
||||
@ -239,6 +242,9 @@
|
||||
/* Define to 1 if you have the `strlcpy' function. */
|
||||
#undef HAVE_STRLCPY
|
||||
|
||||
/* Define if you have Swig libraries and header files. */
|
||||
#undef HAVE_SWIG
|
||||
|
||||
/* Define to 1 if you have the <syslog.h> header file. */
|
||||
#undef HAVE_SYSLOG_H
|
||||
|
||||
@ -370,6 +376,9 @@
|
||||
/* Directory to chdir to */
|
||||
#undef RUN_DIR
|
||||
|
||||
/* Shared data */
|
||||
#undef SHARE_DIR
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
@ -394,6 +403,12 @@
|
||||
/* the version of the windows API enabled */
|
||||
#undef WINVER
|
||||
|
||||
/* Define if you want Python module. */
|
||||
#undef WITH_PYTHONMODULE
|
||||
|
||||
/* Define if you want PyUnbound. */
|
||||
#undef WITH_PYUNBOUND
|
||||
|
||||
/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
|
||||
`char[]'. */
|
||||
#undef YYTEXT_POINTER
|
||||
|
718
configure
vendored
718
configure
vendored
@ -817,6 +817,7 @@ EGREP
|
||||
ub_conf_file
|
||||
UNBOUND_RUN_DIR
|
||||
UNBOUND_CHROOT_DIR
|
||||
UNBOUND_SHARE_DIR
|
||||
UNBOUND_PIDFILE
|
||||
UNBOUND_USERNAME
|
||||
DEPFLAG
|
||||
@ -843,6 +844,18 @@ ECHO
|
||||
RANLIB
|
||||
STRIP
|
||||
LIBTOOL
|
||||
PYTHON_VERSION
|
||||
PYTHON
|
||||
PYTHON_CPPFLAGS
|
||||
PYTHON_LDFLAGS
|
||||
PYTHON_SITE_PKG
|
||||
PYTHON_EXTRA_LIBS
|
||||
PYTHON_EXTRA_LDFLAGS
|
||||
SWIG
|
||||
SWIG_LIB
|
||||
swig
|
||||
WITH_PYTHONMODULE
|
||||
WITH_PYUNBOUND
|
||||
HAVE_SSL
|
||||
RUNTIME_PATH
|
||||
acx_pthread_config
|
||||
@ -867,7 +880,8 @@ LIBS
|
||||
CPPFLAGS
|
||||
CPP
|
||||
YACC
|
||||
YFLAGS'
|
||||
YFLAGS
|
||||
PYTHON_VERSION'
|
||||
ac_subdirs_all='ldns-src'
|
||||
|
||||
# Initialize some variables set by options.
|
||||
@ -1466,6 +1480,8 @@ Optional Packages:
|
||||
part of cfg file)
|
||||
--with-chroot-dir=path set default directory to chroot to (by default same
|
||||
as run-dir)
|
||||
--with-share-dir=path set default directory with shared data (by default
|
||||
same as share/unbound)
|
||||
--with-pidfile=filename set default pathname to unbound pidfile (default
|
||||
run-dir/unbound.pid)
|
||||
--with-username=user set default user that unbound changes to (default
|
||||
@ -1474,6 +1490,10 @@ Optional Packages:
|
||||
--with-pic try to use only PIC/non-PIC objects [default=use
|
||||
both]
|
||||
--with-tags[=TAGS] include additional configurations [automatic]
|
||||
--with-pyunbound build PyUnbound, or --without-pyunbound to skip it.
|
||||
(default=no)
|
||||
--with-pythonmodule build Python module, or --without-pythonmodule to
|
||||
disable script engine. (default=no)
|
||||
--with-ssl=pathname enable SSL (will check /usr/local/ssl /usr/lib/ssl
|
||||
/usr/ssl /usr/pkg /usr/local /opt/local /usr/sfw
|
||||
/usr)
|
||||
@ -1502,6 +1522,10 @@ Some influential environment variables:
|
||||
YFLAGS The list of arguments that will be passed by default to $YACC.
|
||||
This script will default YFLAGS to the empty string to avoid a
|
||||
default value of `-d' given by some make applications.
|
||||
PYTHON_VERSION
|
||||
The installed Python version to use, for example '2.3'. This
|
||||
string will be appended to the Python interpreter canonical
|
||||
name.
|
||||
|
||||
Use these variables to override the choices made by `configure' or to help
|
||||
it to find libraries and programs with nonstandard names/locations.
|
||||
@ -3392,6 +3416,21 @@ _ACEOF
|
||||
|
||||
|
||||
|
||||
# Check whether --with-share-dir was given.
|
||||
if test "${with_share_dir+set}" = set; then
|
||||
withval=$with_share_dir; UNBOUND_SHARE_DIR="$withval"
|
||||
else
|
||||
UNBOUND_SHARE_DIR="$UNBOUND_RUN_DIR"
|
||||
fi
|
||||
|
||||
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define SHARE_DIR "$UNBOUND_SHARE_DIR"
|
||||
_ACEOF
|
||||
|
||||
|
||||
|
||||
# Check whether --with-pidfile was given.
|
||||
if test "${with_pidfile+set}" = set; then
|
||||
withval=$with_pidfile; UNBOUND_PIDFILE="$withval"
|
||||
@ -6842,7 +6881,7 @@ ia64-*-hpux*)
|
||||
;;
|
||||
*-*-irix6*)
|
||||
# Find out which ABI we are using.
|
||||
echo '#line 6845 "configure"' > conftest.$ac_ext
|
||||
echo '#line 6884 "configure"' > conftest.$ac_ext
|
||||
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
|
||||
(eval $ac_compile) 2>&5
|
||||
ac_status=$?
|
||||
@ -8156,11 +8195,11 @@ else
|
||||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:8159: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:8198: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:8163: \$? = $ac_status" >&5
|
||||
echo "$as_me:8202: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s "$ac_outfile"; then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
# So say no if there are warnings other than the usual output.
|
||||
@ -8446,11 +8485,11 @@ else
|
||||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:8449: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:8488: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:8453: \$? = $ac_status" >&5
|
||||
echo "$as_me:8492: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s "$ac_outfile"; then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
# So say no if there are warnings other than the usual output.
|
||||
@ -8550,11 +8589,11 @@ else
|
||||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:8553: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:8592: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>out/conftest.err)
|
||||
ac_status=$?
|
||||
cat out/conftest.err >&5
|
||||
echo "$as_me:8557: \$? = $ac_status" >&5
|
||||
echo "$as_me:8596: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s out/conftest2.$ac_objext
|
||||
then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
@ -10901,7 +10940,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 10904 "configure"
|
||||
#line 10943 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@ -11001,7 +11040,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 11004 "configure"
|
||||
#line 11043 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@ -13421,11 +13460,11 @@ else
|
||||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:13424: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:13463: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:13428: \$? = $ac_status" >&5
|
||||
echo "$as_me:13467: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s "$ac_outfile"; then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
# So say no if there are warnings other than the usual output.
|
||||
@ -13525,11 +13564,11 @@ else
|
||||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:13528: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:13567: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>out/conftest.err)
|
||||
ac_status=$?
|
||||
cat out/conftest.err >&5
|
||||
echo "$as_me:13532: \$? = $ac_status" >&5
|
||||
echo "$as_me:13571: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s out/conftest2.$ac_objext
|
||||
then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
@ -15089,11 +15128,11 @@ else
|
||||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:15092: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:15131: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:15096: \$? = $ac_status" >&5
|
||||
echo "$as_me:15135: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s "$ac_outfile"; then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
# So say no if there are warnings other than the usual output.
|
||||
@ -15193,11 +15232,11 @@ else
|
||||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:15196: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:15235: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>out/conftest.err)
|
||||
ac_status=$?
|
||||
cat out/conftest.err >&5
|
||||
echo "$as_me:15200: \$? = $ac_status" >&5
|
||||
echo "$as_me:15239: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s out/conftest2.$ac_objext
|
||||
then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
@ -17382,11 +17421,11 @@ else
|
||||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:17385: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:17424: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:17389: \$? = $ac_status" >&5
|
||||
echo "$as_me:17428: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s "$ac_outfile"; then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
# So say no if there are warnings other than the usual output.
|
||||
@ -17672,11 +17711,11 @@ else
|
||||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:17675: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:17714: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:17679: \$? = $ac_status" >&5
|
||||
echo "$as_me:17718: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s "$ac_outfile"; then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
# So say no if there are warnings other than the usual output.
|
||||
@ -17776,11 +17815,11 @@ else
|
||||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:17779: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:17818: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>out/conftest.err)
|
||||
ac_status=$?
|
||||
cat out/conftest.err >&5
|
||||
echo "$as_me:17783: \$? = $ac_status" >&5
|
||||
echo "$as_me:17822: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s out/conftest2.$ac_objext
|
||||
then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
@ -21662,6 +21701,563 @@ echo "${ECHO_T}Fixing libtool for -rpath problems." >&6; }
|
||||
fi
|
||||
|
||||
|
||||
# Check for PyUnbound
|
||||
|
||||
# Check whether --with-pyunbound was given.
|
||||
if test "${with_pyunbound+set}" = set; then
|
||||
withval=$with_pyunbound;
|
||||
else
|
||||
withval="no"
|
||||
fi
|
||||
|
||||
|
||||
ub_test_python=no
|
||||
ub_with_pyunbound=no
|
||||
if test x_$withval != x_no; then
|
||||
ub_with_pyunbound=yes
|
||||
ub_test_python=yes
|
||||
fi
|
||||
|
||||
# Check for Python module
|
||||
|
||||
# Check whether --with-pythonmodule was given.
|
||||
if test "${with_pythonmodule+set}" = set; then
|
||||
withval=$with_pythonmodule;
|
||||
else
|
||||
withval="no"
|
||||
fi
|
||||
|
||||
|
||||
ub_with_pythonmod=no
|
||||
if test x_$withval != x_no; then
|
||||
ub_with_pythonmod=yes
|
||||
ub_test_python=yes
|
||||
fi
|
||||
|
||||
# Check for Python & SWIG only on PyUnbound or PyModule
|
||||
if test x_$ub_test_python != x_no; then
|
||||
|
||||
# Check for Python
|
||||
ub_have_python=no
|
||||
|
||||
#
|
||||
# Allow the use of a (user set) custom python version
|
||||
#
|
||||
|
||||
|
||||
# Extract the first word of "python[$PYTHON_VERSION]", so it can be a program name with args.
|
||||
set dummy python$PYTHON_VERSION; ac_word=$2
|
||||
{ echo "$as_me:$LINENO: checking for $ac_word" >&5
|
||||
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
|
||||
if test "${ac_cv_path_PYTHON+set}" = set; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
case $PYTHON in
|
||||
[\\/]* | ?:[\\/]*)
|
||||
ac_cv_path_PYTHON="$PYTHON" # 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
|
||||
ac_cv_path_PYTHON="$as_dir/$ac_word$ac_exec_ext"
|
||||
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
done
|
||||
IFS=$as_save_IFS
|
||||
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
PYTHON=$ac_cv_path_PYTHON
|
||||
if test -n "$PYTHON"; then
|
||||
{ echo "$as_me:$LINENO: result: $PYTHON" >&5
|
||||
echo "${ECHO_T}$PYTHON" >&6; }
|
||||
else
|
||||
{ echo "$as_me:$LINENO: result: no" >&5
|
||||
echo "${ECHO_T}no" >&6; }
|
||||
fi
|
||||
|
||||
|
||||
if test -z "$PYTHON"; then
|
||||
{ { echo "$as_me:$LINENO: error: Cannot find python$PYTHON_VERSION in your system path" >&5
|
||||
echo "$as_me: error: Cannot find python$PYTHON_VERSION in your system path" >&2;}
|
||||
{ (exit 1); exit 1; }; }
|
||||
PYTHON_VERSION=""
|
||||
fi
|
||||
|
||||
#
|
||||
# Check for a version of Python >= 2.1.0
|
||||
#
|
||||
{ echo "$as_me:$LINENO: checking for a version of Python >= '2.1.0'" >&5
|
||||
echo $ECHO_N "checking for a version of Python >= '2.1.0'... $ECHO_C" >&6; }
|
||||
ac_supports_python_ver=`$PYTHON -c "import sys, string; \
|
||||
ver = string.split(sys.version)[0]; \
|
||||
print ver >= '2.1.0'"`
|
||||
if test "$ac_supports_python_ver" != "True"; then
|
||||
if test -z "$PYTHON_NOVERSIONCHECK"; then
|
||||
{ echo "$as_me:$LINENO: result: no" >&5
|
||||
echo "${ECHO_T}no" >&6; }
|
||||
{ { echo "$as_me:$LINENO: error:
|
||||
This version of the AC_PYTHON_DEVEL macro
|
||||
doesn't work properly with versions of Python before
|
||||
2.1.0. You may need to re-run configure, setting the
|
||||
variables PYTHON_CPPFLAGS, PYTHON_LDFLAGS, PYTHON_SITE_PKG,
|
||||
PYTHON_EXTRA_LIBS and PYTHON_EXTRA_LDFLAGS by hand.
|
||||
Moreover, to disable this check, set PYTHON_NOVERSIONCHECK
|
||||
to something else than an empty string.
|
||||
|
||||
See \`config.log' for more details." >&5
|
||||
echo "$as_me: error:
|
||||
This version of the AC_PYTHON_DEVEL macro
|
||||
doesn't work properly with versions of Python before
|
||||
2.1.0. You may need to re-run configure, setting the
|
||||
variables PYTHON_CPPFLAGS, PYTHON_LDFLAGS, PYTHON_SITE_PKG,
|
||||
PYTHON_EXTRA_LIBS and PYTHON_EXTRA_LDFLAGS by hand.
|
||||
Moreover, to disable this check, set PYTHON_NOVERSIONCHECK
|
||||
to something else than an empty string.
|
||||
|
||||
See \`config.log' for more details." >&2;}
|
||||
{ (exit 1); exit 1; }; }
|
||||
else
|
||||
{ echo "$as_me:$LINENO: result: skip at user request" >&5
|
||||
echo "${ECHO_T}skip at user request" >&6; }
|
||||
fi
|
||||
else
|
||||
{ echo "$as_me:$LINENO: result: yes" >&5
|
||||
echo "${ECHO_T}yes" >&6; }
|
||||
fi
|
||||
|
||||
#
|
||||
# if the macro parameter ``version'' is set, honour it
|
||||
#
|
||||
if test -n ""; then
|
||||
{ echo "$as_me:$LINENO: checking for a version of Python " >&5
|
||||
echo $ECHO_N "checking for a version of Python ... $ECHO_C" >&6; }
|
||||
ac_supports_python_ver=`$PYTHON -c "import sys, string; \
|
||||
ver = string.split(sys.version)[0]; \
|
||||
print ver "`
|
||||
if test "$ac_supports_python_ver" = "True"; then
|
||||
{ echo "$as_me:$LINENO: result: yes" >&5
|
||||
echo "${ECHO_T}yes" >&6; }
|
||||
else
|
||||
{ echo "$as_me:$LINENO: result: no" >&5
|
||||
echo "${ECHO_T}no" >&6; }
|
||||
{ { echo "$as_me:$LINENO: error: this package requires Python .
|
||||
If you have it installed, but it isn't the default Python
|
||||
interpreter in your system path, please pass the PYTHON_VERSION
|
||||
variable to configure. See \`\`configure --help'' for reference.
|
||||
" >&5
|
||||
echo "$as_me: error: this package requires Python .
|
||||
If you have it installed, but it isn't the default Python
|
||||
interpreter in your system path, please pass the PYTHON_VERSION
|
||||
variable to configure. See \`\`configure --help'' for reference.
|
||||
" >&2;}
|
||||
{ (exit 1); exit 1; }; }
|
||||
PYTHON_VERSION=""
|
||||
fi
|
||||
fi
|
||||
|
||||
#
|
||||
# Check if you have distutils, else fail
|
||||
#
|
||||
{ echo "$as_me:$LINENO: checking for the distutils Python package" >&5
|
||||
echo $ECHO_N "checking for the distutils Python package... $ECHO_C" >&6; }
|
||||
ac_distutils_result=`$PYTHON -c "import distutils" 2>&1`
|
||||
if test -z "$ac_distutils_result"; then
|
||||
{ echo "$as_me:$LINENO: result: yes" >&5
|
||||
echo "${ECHO_T}yes" >&6; }
|
||||
else
|
||||
{ echo "$as_me:$LINENO: result: no" >&5
|
||||
echo "${ECHO_T}no" >&6; }
|
||||
{ { echo "$as_me:$LINENO: error: cannot import Python module \"distutils\".
|
||||
Please check your Python installation. The error was:
|
||||
$ac_distutils_result" >&5
|
||||
echo "$as_me: error: cannot import Python module \"distutils\".
|
||||
Please check your Python installation. The error was:
|
||||
$ac_distutils_result" >&2;}
|
||||
{ (exit 1); exit 1; }; }
|
||||
PYTHON_VERSION=""
|
||||
fi
|
||||
|
||||
#
|
||||
# Check for Python include path
|
||||
#
|
||||
{ echo "$as_me:$LINENO: checking for Python include path" >&5
|
||||
echo $ECHO_N "checking for Python include path... $ECHO_C" >&6; }
|
||||
if test -z "$PYTHON_CPPFLAGS"; then
|
||||
python_path=`$PYTHON -c "import distutils.sysconfig; \
|
||||
print distutils.sysconfig.get_python_inc();"`
|
||||
if test -n "${python_path}"; then
|
||||
python_path="-I$python_path"
|
||||
fi
|
||||
PYTHON_CPPFLAGS=$python_path
|
||||
fi
|
||||
{ echo "$as_me:$LINENO: result: $PYTHON_CPPFLAGS" >&5
|
||||
echo "${ECHO_T}$PYTHON_CPPFLAGS" >&6; }
|
||||
|
||||
|
||||
#
|
||||
# Check for Python library path
|
||||
#
|
||||
{ echo "$as_me:$LINENO: checking for Python library path" >&5
|
||||
echo $ECHO_N "checking for Python library path... $ECHO_C" >&6; }
|
||||
if test -z "$PYTHON_LDFLAGS"; then
|
||||
# (makes two attempts to ensure we've got a version number
|
||||
# from the interpreter)
|
||||
py_version=`$PYTHON -c "from distutils.sysconfig import *; \
|
||||
from string import join; \
|
||||
print join(get_config_vars('VERSION'))"`
|
||||
if test "$py_version" == "None"; then
|
||||
if test -n "$PYTHON_VERSION"; then
|
||||
py_version=$PYTHON_VERSION
|
||||
else
|
||||
py_version=`$PYTHON -c "import sys; \
|
||||
print sys.version[:3]"`
|
||||
fi
|
||||
fi
|
||||
|
||||
PYTHON_LDFLAGS=`$PYTHON -c "from distutils.sysconfig import *; \
|
||||
from string import join; \
|
||||
print '-L' + get_python_lib(0,1), \
|
||||
'-lpython';"`$py_version
|
||||
fi
|
||||
{ echo "$as_me:$LINENO: result: $PYTHON_LDFLAGS" >&5
|
||||
echo "${ECHO_T}$PYTHON_LDFLAGS" >&6; }
|
||||
|
||||
|
||||
#
|
||||
# Check for site packages
|
||||
#
|
||||
{ echo "$as_me:$LINENO: checking for Python site-packages path" >&5
|
||||
echo $ECHO_N "checking for Python site-packages path... $ECHO_C" >&6; }
|
||||
if test -z "$PYTHON_SITE_PKG"; then
|
||||
PYTHON_SITE_PKG=`$PYTHON -c "import distutils.sysconfig; \
|
||||
print distutils.sysconfig.get_python_lib(0,0);"`
|
||||
fi
|
||||
{ echo "$as_me:$LINENO: result: $PYTHON_SITE_PKG" >&5
|
||||
echo "${ECHO_T}$PYTHON_SITE_PKG" >&6; }
|
||||
|
||||
|
||||
#
|
||||
# libraries which must be linked in when embedding
|
||||
#
|
||||
{ echo "$as_me:$LINENO: checking python extra libraries" >&5
|
||||
echo $ECHO_N "checking python extra libraries... $ECHO_C" >&6; }
|
||||
if test -z "$PYTHON_EXTRA_LIBS"; then
|
||||
PYTHON_EXTRA_LIBS=`$PYTHON -c "import distutils.sysconfig; \
|
||||
conf = distutils.sysconfig.get_config_var; \
|
||||
print conf('LOCALMODLIBS'), conf('LIBS')"`
|
||||
fi
|
||||
{ echo "$as_me:$LINENO: result: $PYTHON_EXTRA_LIBS" >&5
|
||||
echo "${ECHO_T}$PYTHON_EXTRA_LIBS" >&6; }
|
||||
|
||||
|
||||
#
|
||||
# linking flags needed when embedding
|
||||
#
|
||||
{ echo "$as_me:$LINENO: checking python extra linking flags" >&5
|
||||
echo $ECHO_N "checking python extra linking flags... $ECHO_C" >&6; }
|
||||
if test -z "$PYTHON_EXTRA_LDFLAGS"; then
|
||||
PYTHON_EXTRA_LDFLAGS=`$PYTHON -c "import distutils.sysconfig; \
|
||||
conf = distutils.sysconfig.get_config_var; \
|
||||
print conf('LINKFORSHARED')"`
|
||||
fi
|
||||
{ echo "$as_me:$LINENO: result: $PYTHON_EXTRA_LDFLAGS" >&5
|
||||
echo "${ECHO_T}$PYTHON_EXTRA_LDFLAGS" >&6; }
|
||||
|
||||
|
||||
#
|
||||
# final check to see if everything compiles alright
|
||||
#
|
||||
{ echo "$as_me:$LINENO: checking consistency of all components of python development environment" >&5
|
||||
echo $ECHO_N "checking consistency of all components of python development environment... $ECHO_C" >&6; }
|
||||
ac_ext=c
|
||||
ac_cpp='$CPP $CPPFLAGS'
|
||||
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
|
||||
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
|
||||
ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
||||
|
||||
# save current global flags
|
||||
LIBS="$ac_save_LIBS $PYTHON_LDFLAGS"
|
||||
CPPFLAGS="$ac_save_CPPFLAGS $PYTHON_CPPFLAGS"
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
|
||||
Py_Initialize();
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
rm -f conftest.$ac_objext conftest$ac_exeext
|
||||
if { (ac_try="$ac_link"
|
||||
case "(($ac_try" in
|
||||
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
*) ac_try_echo=$ac_try;;
|
||||
esac
|
||||
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
|
||||
(eval "$ac_link") 2>conftest.er1
|
||||
ac_status=$?
|
||||
grep -v '^ *+' conftest.er1 >conftest.err
|
||||
rm -f conftest.er1
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } && {
|
||||
test -z "$ac_c_werror_flag" ||
|
||||
test ! -s conftest.err
|
||||
} && test -s conftest$ac_exeext &&
|
||||
$as_test_x conftest$ac_exeext; then
|
||||
pythonexists=yes
|
||||
else
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
pythonexists=no
|
||||
fi
|
||||
|
||||
rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
|
||||
{ echo "$as_me:$LINENO: result: $pythonexists" >&5
|
||||
echo "${ECHO_T}$pythonexists" >&6; }
|
||||
|
||||
if test ! "$pythonexists" = "yes"; then
|
||||
{ { echo "$as_me:$LINENO: error:
|
||||
Could not link test program to Python. Maybe the main Python library has been
|
||||
installed in some non-standard library path. If so, pass it to configure,
|
||||
via the LDFLAGS environment variable.
|
||||
Example: ./configure LDFLAGS=\"-L/usr/non-standard-path/python/lib\"
|
||||
============================================================================
|
||||
ERROR!
|
||||
You probably have to install the development version of the Python package
|
||||
for your distribution. The exact name of this package varies among them.
|
||||
============================================================================
|
||||
" >&5
|
||||
echo "$as_me: error:
|
||||
Could not link test program to Python. Maybe the main Python library has been
|
||||
installed in some non-standard library path. If so, pass it to configure,
|
||||
via the LDFLAGS environment variable.
|
||||
Example: ./configure LDFLAGS=\"-L/usr/non-standard-path/python/lib\"
|
||||
============================================================================
|
||||
ERROR!
|
||||
You probably have to install the development version of the Python package
|
||||
for your distribution. The exact name of this package varies among them.
|
||||
============================================================================
|
||||
" >&2;}
|
||||
{ (exit 1); exit 1; }; }
|
||||
PYTHON_VERSION=""
|
||||
fi
|
||||
ac_ext=c
|
||||
ac_cpp='$CPP $CPPFLAGS'
|
||||
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
|
||||
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
|
||||
ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
||||
|
||||
# turn back to default flags
|
||||
CPPFLAGS="$ac_save_CPPFLAGS"
|
||||
LIBS="$ac_save_LIBS"
|
||||
|
||||
#
|
||||
# all done!
|
||||
#
|
||||
|
||||
if test ! -z "PYTHON_VERSION"; then
|
||||
|
||||
# Have Python
|
||||
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define HAVE_PYTHON 1
|
||||
_ACEOF
|
||||
|
||||
LIBS="$PYTHON_LDFLAGS $LIBS"
|
||||
CFLAGS="$CFLAGS $PYTHON_CPPFLAGS"
|
||||
ub_have_python=yes
|
||||
|
||||
# Check for SWIG
|
||||
ub_have_swig=no
|
||||
|
||||
# Extract the first word of "swig", so it can be a program name with args.
|
||||
set dummy swig; ac_word=$2
|
||||
{ echo "$as_me:$LINENO: checking for $ac_word" >&5
|
||||
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
|
||||
if test "${ac_cv_path_SWIG+set}" = set; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
case $SWIG in
|
||||
[\\/]* | ?:[\\/]*)
|
||||
ac_cv_path_SWIG="$SWIG" # Let the user override the test with a path.
|
||||
;;
|
||||
*)
|
||||
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
|
||||
for as_dir in $PATH
|
||||
do
|
||||
IFS=$as_save_IFS
|
||||
test -z "$as_dir" && as_dir=.
|
||||
for ac_exec_ext in '' $ac_executable_extensions; do
|
||||
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
|
||||
ac_cv_path_SWIG="$as_dir/$ac_word$ac_exec_ext"
|
||||
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
done
|
||||
IFS=$as_save_IFS
|
||||
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
SWIG=$ac_cv_path_SWIG
|
||||
if test -n "$SWIG"; then
|
||||
{ echo "$as_me:$LINENO: result: $SWIG" >&5
|
||||
echo "${ECHO_T}$SWIG" >&6; }
|
||||
else
|
||||
{ echo "$as_me:$LINENO: result: no" >&5
|
||||
echo "${ECHO_T}no" >&6; }
|
||||
fi
|
||||
|
||||
|
||||
if test -z "$SWIG" ; then
|
||||
{ echo "$as_me:$LINENO: WARNING: cannot find 'swig' program. You should look at http://www.swig.org" >&5
|
||||
echo "$as_me: WARNING: cannot find 'swig' program. You should look at http://www.swig.org" >&2;}
|
||||
SWIG='echo "Error: SWIG is not installed. You should look at http://www.swig.org" ; false'
|
||||
elif test -n "" ; then
|
||||
{ echo "$as_me:$LINENO: checking for SWIG version" >&5
|
||||
echo $ECHO_N "checking for SWIG version... $ECHO_C" >&6; }
|
||||
swig_version=`$SWIG -version 2>&1 | grep 'SWIG Version' | sed 's/.*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*/\1/g'`
|
||||
{ echo "$as_me:$LINENO: result: $swig_version" >&5
|
||||
echo "${ECHO_T}$swig_version" >&6; }
|
||||
if test -n "$swig_version" ; then
|
||||
# Calculate the required version number components
|
||||
required=
|
||||
required_major=`echo $required | sed 's/[^0-9].*//'`
|
||||
if test -z "$required_major" ; then
|
||||
required_major=0
|
||||
fi
|
||||
required=`echo $required | sed 's/[0-9]*[^0-9]//'`
|
||||
required_minor=`echo $required | sed 's/[^0-9].*//'`
|
||||
if test -z "$required_minor" ; then
|
||||
required_minor=0
|
||||
fi
|
||||
required=`echo $required | sed 's/[0-9]*[^0-9]//'`
|
||||
required_patch=`echo $required | sed 's/[^0-9].*//'`
|
||||
if test -z "$required_patch" ; then
|
||||
required_patch=0
|
||||
fi
|
||||
# Calculate the available version number components
|
||||
available=$swig_version
|
||||
available_major=`echo $available | sed 's/[^0-9].*//'`
|
||||
if test -z "$available_major" ; then
|
||||
available_major=0
|
||||
fi
|
||||
available=`echo $available | sed 's/[0-9]*[^0-9]//'`
|
||||
available_minor=`echo $available | sed 's/[^0-9].*//'`
|
||||
if test -z "$available_minor" ; then
|
||||
available_minor=0
|
||||
fi
|
||||
available=`echo $available | sed 's/[0-9]*[^0-9]//'`
|
||||
available_patch=`echo $available | sed 's/[^0-9].*//'`
|
||||
if test -z "$available_patch" ; then
|
||||
available_patch=0
|
||||
fi
|
||||
if test $available_major -ne $required_major \
|
||||
-o $available_minor -ne $required_minor \
|
||||
-o $available_patch -lt $required_patch ; then
|
||||
{ echo "$as_me:$LINENO: WARNING: SWIG version >= is required. You have $swig_version. You should look at http://www.swig.org" >&5
|
||||
echo "$as_me: WARNING: SWIG version >= is required. You have $swig_version. You should look at http://www.swig.org" >&2;}
|
||||
SWIG='echo "Error: SWIG version >= is required. You have '"$swig_version"'. You should look at http://www.swig.org" ; false'
|
||||
else
|
||||
{ echo "$as_me:$LINENO: SWIG executable is '$SWIG'" >&5
|
||||
echo "$as_me: SWIG executable is '$SWIG'" >&6;}
|
||||
SWIG_LIB=`$SWIG -swiglib`
|
||||
{ echo "$as_me:$LINENO: SWIG library directory is '$SWIG_LIB'" >&5
|
||||
echo "$as_me: SWIG library directory is '$SWIG_LIB'" >&6;}
|
||||
fi
|
||||
else
|
||||
{ echo "$as_me:$LINENO: WARNING: cannot determine SWIG version" >&5
|
||||
echo "$as_me: WARNING: cannot determine SWIG version" >&2;}
|
||||
SWIG='echo "Error: Cannot determine SWIG version. You should look at http://www.swig.org" ; false'
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
{ echo "$as_me:$LINENO: checking SWIG" >&5
|
||||
echo $ECHO_N "checking SWIG... $ECHO_C" >&6; }
|
||||
if test -z SWIG; then
|
||||
{ echo "$as_me:$LINENO: result: failed" >&5
|
||||
echo "${ECHO_T}failed" >&6; }
|
||||
swig=""
|
||||
|
||||
else
|
||||
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define HAVE_SWIG 1
|
||||
_ACEOF
|
||||
|
||||
swig="$SWIG"
|
||||
|
||||
{ echo "$as_me:$LINENO: result: done" >&5
|
||||
echo "${ECHO_T}done" >&6; }
|
||||
fi
|
||||
|
||||
# If have Python & SWIG
|
||||
if test ! -z "SWIG"; then
|
||||
|
||||
# Declare PythonMod
|
||||
if test x_$ub_with_pythonmod != x_no; then
|
||||
{ echo "$as_me:$LINENO: result: Will build Python module." >&5
|
||||
echo "${ECHO_T}Will build Python module." >&6; }
|
||||
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define WITH_PYTHONMODULE 1
|
||||
_ACEOF
|
||||
|
||||
WITH_PYTHONMODULE=yes
|
||||
|
||||
fi
|
||||
|
||||
# Declare PyUnbound
|
||||
if test x_$ub_with_pyunbound != x_no; then
|
||||
{ echo "$as_me:$LINENO: result: Will build PyUnbound." >&5
|
||||
echo "${ECHO_T}Will build PyUnbound." >&6; }
|
||||
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define WITH_PYUNBOUND 1
|
||||
_ACEOF
|
||||
|
||||
WITH_PYUNBOUND=yes
|
||||
|
||||
fi
|
||||
else
|
||||
{ echo "$as_me:$LINENO: result: SWIG libraries not found" >&5
|
||||
echo "${ECHO_T}SWIG libraries not found" >&6; }
|
||||
ub_with_pyunbound=no
|
||||
ub_with_pythonmod=no
|
||||
fi
|
||||
else
|
||||
{ echo "$as_me:$LINENO: result: Python libraries not found" >&5
|
||||
echo "${ECHO_T}Python libraries not found" >&6; }
|
||||
ub_with_pyunbound=no
|
||||
ub_with_pythonmod=no
|
||||
fi
|
||||
fi
|
||||
|
||||
# Checks for libraries.
|
||||
|
||||
|
||||
@ -28141,6 +28737,7 @@ EGREP!$EGREP$ac_delim
|
||||
ub_conf_file!$ub_conf_file$ac_delim
|
||||
UNBOUND_RUN_DIR!$UNBOUND_RUN_DIR$ac_delim
|
||||
UNBOUND_CHROOT_DIR!$UNBOUND_CHROOT_DIR$ac_delim
|
||||
UNBOUND_SHARE_DIR!$UNBOUND_SHARE_DIR$ac_delim
|
||||
UNBOUND_PIDFILE!$UNBOUND_PIDFILE$ac_delim
|
||||
UNBOUND_USERNAME!$UNBOUND_USERNAME$ac_delim
|
||||
DEPFLAG!$DEPFLAG$ac_delim
|
||||
@ -28167,22 +28764,26 @@ ECHO!$ECHO$ac_delim
|
||||
RANLIB!$RANLIB$ac_delim
|
||||
STRIP!$STRIP$ac_delim
|
||||
LIBTOOL!$LIBTOOL$ac_delim
|
||||
PYTHON_VERSION!$PYTHON_VERSION$ac_delim
|
||||
PYTHON!$PYTHON$ac_delim
|
||||
PYTHON_CPPFLAGS!$PYTHON_CPPFLAGS$ac_delim
|
||||
PYTHON_LDFLAGS!$PYTHON_LDFLAGS$ac_delim
|
||||
PYTHON_SITE_PKG!$PYTHON_SITE_PKG$ac_delim
|
||||
PYTHON_EXTRA_LIBS!$PYTHON_EXTRA_LIBS$ac_delim
|
||||
PYTHON_EXTRA_LDFLAGS!$PYTHON_EXTRA_LDFLAGS$ac_delim
|
||||
SWIG!$SWIG$ac_delim
|
||||
SWIG_LIB!$SWIG_LIB$ac_delim
|
||||
swig!$swig$ac_delim
|
||||
WITH_PYTHONMODULE!$WITH_PYTHONMODULE$ac_delim
|
||||
WITH_PYUNBOUND!$WITH_PYUNBOUND$ac_delim
|
||||
HAVE_SSL!$HAVE_SSL$ac_delim
|
||||
RUNTIME_PATH!$RUNTIME_PATH$ac_delim
|
||||
acx_pthread_config!$acx_pthread_config$ac_delim
|
||||
PTHREAD_CC!$PTHREAD_CC$ac_delim
|
||||
PTHREAD_LIBS!$PTHREAD_LIBS$ac_delim
|
||||
PTHREAD_CFLAGS!$PTHREAD_CFLAGS$ac_delim
|
||||
staticexe!$staticexe$ac_delim
|
||||
CHECKLOCK_SRC!$CHECKLOCK_SRC$ac_delim
|
||||
LIBOBJS!$LIBOBJS$ac_delim
|
||||
UB_ON_WINDOWS!$UB_ON_WINDOWS$ac_delim
|
||||
ldnsdir!$ldnsdir$ac_delim
|
||||
subdirs!$subdirs$ac_delim
|
||||
LTLIBOBJS!$LTLIBOBJS$ac_delim
|
||||
_ACEOF
|
||||
|
||||
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 92; then
|
||||
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then
|
||||
break
|
||||
elif $ac_last_try; then
|
||||
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
|
||||
@ -28201,6 +28802,55 @@ fi
|
||||
|
||||
cat >>$CONFIG_STATUS <<_ACEOF
|
||||
cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof
|
||||
/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
|
||||
_ACEOF
|
||||
sed '
|
||||
s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g
|
||||
s/^/s,@/; s/!/@,|#_!!_#|/
|
||||
:n
|
||||
t n
|
||||
s/'"$ac_delim"'$/,g/; t
|
||||
s/$/\\/; p
|
||||
N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n
|
||||
' >>$CONFIG_STATUS <conf$$subs.sed
|
||||
rm -f conf$$subs.sed
|
||||
cat >>$CONFIG_STATUS <<_ACEOF
|
||||
CEOF$ac_eof
|
||||
_ACEOF
|
||||
|
||||
|
||||
ac_delim='%!_!# '
|
||||
for ac_last_try in false false false false false :; do
|
||||
cat >conf$$subs.sed <<_ACEOF
|
||||
PTHREAD_CFLAGS!$PTHREAD_CFLAGS$ac_delim
|
||||
staticexe!$staticexe$ac_delim
|
||||
CHECKLOCK_SRC!$CHECKLOCK_SRC$ac_delim
|
||||
LIBOBJS!$LIBOBJS$ac_delim
|
||||
UB_ON_WINDOWS!$UB_ON_WINDOWS$ac_delim
|
||||
ldnsdir!$ldnsdir$ac_delim
|
||||
subdirs!$subdirs$ac_delim
|
||||
LTLIBOBJS!$LTLIBOBJS$ac_delim
|
||||
_ACEOF
|
||||
|
||||
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 8; then
|
||||
break
|
||||
elif $ac_last_try; then
|
||||
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
|
||||
echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}
|
||||
{ (exit 1); exit 1; }; }
|
||||
else
|
||||
ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
|
||||
fi
|
||||
done
|
||||
|
||||
ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed`
|
||||
if test -n "$ac_eof"; then
|
||||
ac_eof=`echo "$ac_eof" | sort -nru | sed 1q`
|
||||
ac_eof=`expr $ac_eof + 1`
|
||||
fi
|
||||
|
||||
cat >>$CONFIG_STATUS <<_ACEOF
|
||||
cat >"\$tmp/subs-2.sed" <<\CEOF$ac_eof
|
||||
/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end
|
||||
_ACEOF
|
||||
sed '
|
||||
@ -28458,7 +29108,7 @@ s&@builddir@&$ac_builddir&;t t
|
||||
s&@abs_builddir@&$ac_abs_builddir&;t t
|
||||
s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
|
||||
$ac_datarootdir_hack
|
||||
" $ac_file_inputs | sed -f "$tmp/subs-1.sed" >$tmp/out
|
||||
" $ac_file_inputs | sed -f "$tmp/subs-1.sed" | sed -f "$tmp/subs-2.sed" >$tmp/out
|
||||
|
||||
test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
|
||||
{ ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
|
||||
|
92
configure.ac
92
configure.ac
@ -3,6 +3,8 @@
|
||||
AC_PREREQ(2.56)
|
||||
sinclude(acx_nlnetlabs.m4)
|
||||
sinclude(acx_pthread.m4)
|
||||
sinclude(acx_python.m4)
|
||||
sinclude(ac_pkg_swig.m4)
|
||||
|
||||
AC_INIT(unbound, 1.3.0, unbound-bugs@nlnetlabs.nl, unbound)
|
||||
|
||||
@ -101,6 +103,14 @@ AC_SUBST(UNBOUND_CHROOT_DIR)
|
||||
ACX_ESCAPE_BACKSLASH($UNBOUND_CHOOT_DIR, hdr_chroot)
|
||||
AC_DEFINE_UNQUOTED(CHROOT_DIR, ["$hdr_chroot"], [Directory to chroot to])
|
||||
|
||||
AC_ARG_WITH(share-dir,
|
||||
AC_HELP_STRING([--with-share-dir=path],
|
||||
[set default directory with shared data (by default same as share/unbound)]),
|
||||
UNBOUND_SHARE_DIR="$withval",
|
||||
UNBOUND_SHARE_DIR="$UNBOUND_RUN_DIR")
|
||||
AC_SUBST(UNBOUND_SHARE_DIR)
|
||||
AC_DEFINE_UNQUOTED(SHARE_DIR, ["$UNBOUND_SHARE_DIR"], [Shared data])
|
||||
|
||||
AC_ARG_WITH(pidfile,
|
||||
AC_HELP_STRING([--with-pidfile=filename],
|
||||
[set default pathname to unbound pidfile (default run-dir/unbound.pid)]),
|
||||
@ -197,6 +207,88 @@ ACX_TYPE_IN_PORT_T
|
||||
# add option to disable the evil rpath
|
||||
ACX_ARG_RPATH
|
||||
|
||||
# Check for PyUnbound
|
||||
AC_ARG_WITH(pyunbound,
|
||||
AC_HELP_STRING([--with-pyunbound],
|
||||
[build PyUnbound, or --without-pyunbound to skip it. (default=no)]),
|
||||
[], [ withval="no" ])
|
||||
|
||||
ub_test_python=no
|
||||
ub_with_pyunbound=no
|
||||
if test x_$withval != x_no; then
|
||||
ub_with_pyunbound=yes
|
||||
ub_test_python=yes
|
||||
fi
|
||||
|
||||
# Check for Python module
|
||||
AC_ARG_WITH(pythonmodule,
|
||||
AC_HELP_STRING([--with-pythonmodule],
|
||||
[build Python module, or --without-pythonmodule to disable script engine. (default=no)]),
|
||||
[], [ withval="no" ])
|
||||
|
||||
ub_with_pythonmod=no
|
||||
if test x_$withval != x_no; then
|
||||
ub_with_pythonmod=yes
|
||||
ub_test_python=yes
|
||||
fi
|
||||
|
||||
# Check for Python & SWIG only on PyUnbound or PyModule
|
||||
if test x_$ub_test_python != x_no; then
|
||||
|
||||
# Check for Python
|
||||
ub_have_python=no
|
||||
AC_PYTHON_DEVEL
|
||||
if test ! -z "PYTHON_VERSION"; then
|
||||
|
||||
# Have Python
|
||||
AC_DEFINE(HAVE_PYTHON,1,[Define if you have Python libraries and header files.])
|
||||
LIBS="$PYTHON_LDFLAGS $LIBS"
|
||||
CFLAGS="$CFLAGS $PYTHON_CPPFLAGS"
|
||||
ub_have_python=yes
|
||||
|
||||
# Check for SWIG
|
||||
ub_have_swig=no
|
||||
AC_PROG_SWIG
|
||||
AC_MSG_CHECKING(SWIG)
|
||||
if test -z SWIG; then
|
||||
AC_MSG_RESULT(failed, won't build Python module and PyUnbound)
|
||||
AC_SUBST(swig, "")
|
||||
else
|
||||
AC_DEFINE(HAVE_SWIG, 1, [Define if you have Swig libraries and header files.])
|
||||
AC_SUBST(swig, "$SWIG")
|
||||
AC_MSG_RESULT(done)
|
||||
fi
|
||||
|
||||
# If have Python & SWIG
|
||||
if test ! -z "SWIG"; then
|
||||
|
||||
# Declare PythonMod
|
||||
if test x_$ub_with_pythonmod != x_no; then
|
||||
AC_MSG_RESULT(Will build Python module.)
|
||||
AC_DEFINE(WITH_PYTHONMODULE, 1, [Define if you want Python module.])
|
||||
WITH_PYTHONMODULE=yes
|
||||
AC_SUBST(WITH_PYTHONMODULE)
|
||||
fi
|
||||
|
||||
# Declare PyUnbound
|
||||
if test x_$ub_with_pyunbound != x_no; then
|
||||
AC_MSG_RESULT(Will build PyUnbound.)
|
||||
AC_DEFINE(WITH_PYUNBOUND, 1, [Define if you want PyUnbound.])
|
||||
WITH_PYUNBOUND=yes
|
||||
AC_SUBST(WITH_PYUNBOUND)
|
||||
fi
|
||||
else
|
||||
AC_MSG_RESULT(SWIG libraries not found, won't build PythonMod or PyUnbound)
|
||||
ub_with_pyunbound=no
|
||||
ub_with_pythonmod=no
|
||||
fi
|
||||
else
|
||||
AC_MSG_RESULT(Python libraries not found, won't build PythonMod or PyUnbound)
|
||||
ub_with_pyunbound=no
|
||||
ub_with_pythonmod=no
|
||||
fi
|
||||
fi
|
||||
|
||||
# Checks for libraries.
|
||||
ACX_WITH_SSL
|
||||
ACX_LIB_SSL
|
||||
|
@ -12,3 +12,4 @@ distribution but may be helpful.
|
||||
* unbound_cacti.tar.gz : setup files for cacti statistics report
|
||||
* selinux: the .fc and .te files for SElinux protection of the unbound daemon
|
||||
* unbound.plist: launchd configuration file for MacOSX.
|
||||
* python: use libunbound from python.
|
||||
|
28
contrib/python/LICENSE
Normal file
28
contrib/python/LICENSE
Normal file
@ -0,0 +1,28 @@
|
||||
Copyright (c) 2009, Zdenek Vasicek (vasicek AT fit.vutbr.cz)
|
||||
Marek Vavrusa (xvavru00 AT stud.fit.vutbr.cz)
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the organization 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 OWNER 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.
|
74
contrib/python/Makefile
Normal file
74
contrib/python/Makefile
Normal file
@ -0,0 +1,74 @@
|
||||
#
|
||||
# Makefile: compilation of pyUnbound and documentation, testing
|
||||
#
|
||||
# Copyright (c) 2009, Zdenek Vasicek (vasicek AT fit.vutbr.cz)
|
||||
# Marek Vavrusa (xvavru00 AT stud.fit.vutbr.cz)
|
||||
#
|
||||
# This software is open source.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# * Neither the name of the organization 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 REGENTS 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.
|
||||
|
||||
help:
|
||||
@echo "Please use \`make <target>' where <target> is one of"
|
||||
@echo " testenv to make test environment and run bash "
|
||||
@echo " usefull in case you don't want to install unbound but want to test examples"
|
||||
@echo " doc to make documentation"
|
||||
@echo " clean clean all"
|
||||
|
||||
.PHONY: testenv clean doc swig
|
||||
|
||||
_unbound.so: ../../Makefile
|
||||
$(MAKE) -C ../..
|
||||
|
||||
../../.libs/libunbound.so.0: ../../Makefile
|
||||
$(MAKE) -C ../..
|
||||
|
||||
../../ldns-src/lib/libldns.so: ../../ldns-src/Makefile
|
||||
$(MAKE) -C ../../ldns-src
|
||||
|
||||
clean:
|
||||
rm -rdf examples/unbound
|
||||
rm -f _unbound.so libunbound_wrap.o
|
||||
$(MAKE) -C ../.. clean
|
||||
|
||||
testenv: ../../.libs/libunbound.so.0 ../../ldns-src/lib/libldns.so _unbound.so
|
||||
rm -rdf examples/unbound
|
||||
cd examples && mkdir unbound && ln -s ../../unbound.py unbound/__init__.py && ln -s ../../_unbound.so unbound/_unbound.so && ln -s ../../../../.libs/libunbound.so.0 unbound/libunbound.so.0 && ln -s ../../../../ldns-src/lib/libldns.so.1 unbound/libldns.so.1 && ls -la
|
||||
@echo "Run a script by typing ./script_name.py"
|
||||
cd examples && LD_LIBRARY_PATH=unbound bash
|
||||
rm -rdf examples/unbound
|
||||
|
||||
doc: ../../.libs/libunbound.so.0 _unbound.so
|
||||
$(MAKE) -C docs html
|
||||
|
||||
#for development only
|
||||
swig: libunbound.i
|
||||
swig -python -o libunbound_wrap.c -I../.. libunbound.i
|
||||
gcc -c libunbound_wrap.c -O9 -fPIC -I../.. -I/usr/include/python2.5 -I. -o libunbound_wrap.o
|
||||
ld -shared libunbound_wrap.o -L../../.libs -lunbound -o _unbound.so
|
||||
|
70
contrib/python/docs/Makefile
Normal file
70
contrib/python/docs/Makefile
Normal file
@ -0,0 +1,70 @@
|
||||
# Makefile for Sphinx documentation
|
||||
#
|
||||
|
||||
# You can set these variables from the command line.
|
||||
SPHINXOPTS =
|
||||
SPHINXBUILD = sphinx-build
|
||||
PAPER =
|
||||
|
||||
# Internal variables.
|
||||
PAPEROPT_a4 = -D latex_paper_size=a4
|
||||
PAPEROPT_letter = -D latex_paper_size=letter
|
||||
ALLSPHINXOPTS = -d build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
|
||||
|
||||
.PHONY: help clean html web pickle htmlhelp latex changes linkcheck
|
||||
|
||||
help:
|
||||
@echo "Please use \`make <target>' where <target> is one of"
|
||||
@echo " html to make standalone HTML files"
|
||||
@echo " pickle to make pickle files (usable by e.g. sphinx-web)"
|
||||
@echo " htmlhelp to make HTML files and a HTML help project"
|
||||
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
|
||||
@echo " changes to make an overview over all changed/added/deprecated items"
|
||||
@echo " linkcheck to check all external links for integrity"
|
||||
|
||||
clean:
|
||||
-rm -rf build/*
|
||||
|
||||
html:
|
||||
mkdir -p build/html build/doctrees
|
||||
LD_LIBRARY_PATH=../../../.libs:../../../ldns-src/lib $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) build/html
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in build/html."
|
||||
|
||||
pickle:
|
||||
mkdir -p build/pickle build/doctrees
|
||||
LD_LIBRARY_PATH=../../../.libs:../../../ldns-src/lib $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) build/pickle
|
||||
@echo
|
||||
@echo "Build finished; now you can process the pickle files or run"
|
||||
@echo " sphinx-web build/pickle"
|
||||
@echo "to start the sphinx-web server."
|
||||
|
||||
web: pickle
|
||||
|
||||
htmlhelp:
|
||||
mkdir -p build/htmlhelp build/doctrees
|
||||
LD_LIBRARY_PATH=../../../.libs:../../../ldns-src/lib $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) build/htmlhelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run HTML Help Workshop with the" \
|
||||
".hhp project file in build/htmlhelp."
|
||||
|
||||
latex:
|
||||
mkdir -p build/latex build/doctrees
|
||||
LD_LIBRARY_PATH=../../../.libs:../../../ldns-src/lib $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) build/latex
|
||||
@echo
|
||||
@echo "Build finished; the LaTeX files are in build/latex."
|
||||
@echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
|
||||
"run these through (pdf)latex."
|
||||
|
||||
changes:
|
||||
mkdir -p build/changes build/doctrees
|
||||
LD_LIBRARY_PATH=../../../.libs:../../../ldns-src/lib $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) build/changes
|
||||
@echo
|
||||
@echo "The overview file is in build/changes."
|
||||
|
||||
linkcheck:
|
||||
mkdir -p build/linkcheck build/doctrees
|
||||
LD_LIBRARY_PATH=../../../.libs:../../../ldns-src/lib $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) build/linkcheck
|
||||
@echo
|
||||
@echo "Link check complete; look for any errors in the above output " \
|
||||
"or in build/linkcheck/output.txt."
|
179
contrib/python/docs/source/conf.py
Normal file
179
contrib/python/docs/source/conf.py
Normal file
@ -0,0 +1,179 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Unbound documentation build configuration file
|
||||
#
|
||||
# This file is execfile()d with the current directory set to its containing dir.
|
||||
#
|
||||
# The contents of this file are pickled, so don't put values in the namespace
|
||||
# that aren't pickleable (module imports are okay, they're removed automatically).
|
||||
#
|
||||
# All configuration values have a default value; values that are commented out
|
||||
# serve to show the default value.
|
||||
|
||||
import sys, os
|
||||
|
||||
# If your extensions are in another directory, add it here. If the directory
|
||||
# is relative to the documentation root, use os.path.abspath to make it
|
||||
# absolute, like shown here.
|
||||
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__),'../../')))
|
||||
#print sys.path
|
||||
|
||||
# General configuration
|
||||
# ---------------------
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be extensions
|
||||
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
||||
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest']
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
# The suffix of source filenames.
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# General substitutions.
|
||||
project = 'pyUnbound'
|
||||
copyright = '2009, Zdenek Vasicek, Marek Vavrusa'
|
||||
|
||||
# The default replacements for |version| and |release|, also used in various
|
||||
# other places throughout the built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '1.0'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '1.0.0'
|
||||
|
||||
# There are two options for replacing |today|: either, you set today to some
|
||||
# non-false value, then it is used:
|
||||
#today = ''
|
||||
# Else, today_fmt is used as the format for a strftime call.
|
||||
today_fmt = '%B %d, %Y'
|
||||
|
||||
# List of documents that shouldn't be included in the build.
|
||||
#unused_docs = []
|
||||
|
||||
# List of directories, relative to source directories, that shouldn't be searched
|
||||
# for source files.
|
||||
#exclude_dirs = []
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all documents.
|
||||
#default_role = None
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
#add_function_parentheses = True
|
||||
|
||||
# If true, the current module name will be prepended to all description
|
||||
# unit titles (such as .. function::).
|
||||
#add_module_names = True
|
||||
|
||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||
# output. They are ignored by default.
|
||||
#show_authors = False
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
|
||||
# Options for HTML output
|
||||
# -----------------------
|
||||
|
||||
# The style sheet to use for HTML and HTML Help pages. A file of that name
|
||||
# must exist either in Sphinx' static/ path, or in one of the custom paths
|
||||
# given in html_static_path.
|
||||
html_style = 'default.css'
|
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to
|
||||
# "<project> v<release> documentation".
|
||||
#html_title = None
|
||||
|
||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||
#html_short_title = None
|
||||
|
||||
# The name of an image file (within the static path) to place at the top of
|
||||
# the sidebar.
|
||||
#html_logo = None
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
#html_favicon = None
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static']
|
||||
|
||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||
# using the given strftime format.
|
||||
html_last_updated_fmt = '%b %d, %Y'
|
||||
|
||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||
# typographically correct entities.
|
||||
#html_use_smartypants = True
|
||||
|
||||
# Custom sidebar templates, maps document names to template names.
|
||||
#html_sidebars = {}
|
||||
|
||||
# Additional templates that should be rendered to pages, maps page names to
|
||||
# template names.
|
||||
#html_additional_pages = {}
|
||||
|
||||
# If false, no module index is generated.
|
||||
html_use_modindex = False
|
||||
|
||||
# If false, no index is generated.
|
||||
#html_use_index = True
|
||||
|
||||
# If true, the index is split into individual pages for each letter.
|
||||
#html_split_index = False
|
||||
|
||||
# If true, the reST sources are included in the HTML build as _sources/<name>.
|
||||
html_copy_source = False
|
||||
|
||||
# If true, an OpenSearch description file will be output, and all pages will
|
||||
# contain a <link> tag referring to it. The value of this option must be the
|
||||
# base URL from which the finished HTML is served.
|
||||
#html_use_opensearch = ''
|
||||
|
||||
# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
|
||||
#html_file_suffix = ''
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'Unbounddoc'
|
||||
|
||||
|
||||
# Options for LaTeX output
|
||||
# ------------------------
|
||||
|
||||
# The paper size ('letter' or 'a4').
|
||||
#latex_paper_size = 'letter'
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#latex_font_size = '10pt'
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title, author, document class [howto/manual]).
|
||||
latex_documents = [
|
||||
('index', 'Unbound.tex', 'Unbound Documentation',
|
||||
'Zdenek Vasicek, Marek Vavrusa', 'manual'),
|
||||
]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
# the title page.
|
||||
#latex_logo = None
|
||||
|
||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||
# not chapters.
|
||||
#latex_use_parts = False
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#latex_preamble = ''
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#latex_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#latex_use_modindex = True
|
26
contrib/python/docs/source/examples/example1a.rst
Normal file
26
contrib/python/docs/source/examples/example1a.rst
Normal file
@ -0,0 +1,26 @@
|
||||
.. _example_resolve_name:
|
||||
|
||||
==============================
|
||||
Resolve a name
|
||||
==============================
|
||||
|
||||
This basic example shows how to create a context and resolve a host address (DNS record of A type).
|
||||
|
||||
::
|
||||
|
||||
#!/usr/bin/python
|
||||
import unbound
|
||||
|
||||
ctx = unbound.ub_ctx()
|
||||
ctx.resolvconf("/etc/resolv.conf")
|
||||
|
||||
status, result = ctx.resolve("www.google.com")
|
||||
if status == 0 and result.havedata:
|
||||
print "Result.data:", result.data.address_list
|
||||
elif status != 0:
|
||||
print "Resolve error:", unbound.ub_strerror(status)
|
||||
|
||||
In contrast with C API, the source code is more compact while the performance of C implementation is preserved.
|
||||
The main advantage is that you need not take care about the deallocation and allocation of context and result structures; pyUnbound module do it automatically for you.
|
||||
|
||||
If only domain name is given, the :meth:`unbound.ub_ctx.resolve` looks for A records in IN class.
|
33
contrib/python/docs/source/examples/example1b.rst
Normal file
33
contrib/python/docs/source/examples/example1b.rst
Normal file
@ -0,0 +1,33 @@
|
||||
.. _example_reverse_lookup:
|
||||
|
||||
==============================
|
||||
Reverse DNS lookup
|
||||
==============================
|
||||
|
||||
Reverse DNS lookup involves determining the hostname associated with a given IP address.
|
||||
This example shows how reverse lookup can be done using unbound module.
|
||||
|
||||
For the reverse DNS records, the special domain in-addr.arpa is reserved.
|
||||
For example, a host name for the IP address 74.125.43.147 can be obtained by issuing a DNS query for the PTR record for address 147.43.125.74.in-addr.arpa.
|
||||
|
||||
::
|
||||
|
||||
#!/usr/bin/python
|
||||
import unbound
|
||||
|
||||
ctx = unbound.ub_ctx()
|
||||
ctx.resolvconf("/etc/resolv.conf")
|
||||
|
||||
status, result = ctx.resolve(unbound.reverse("74.125.43.147") + ".in-addr.arpa.", unbound.RR_TYPE_PTR, unbound.RR_CLASS_IN)
|
||||
if status == 0 and result.havedata:
|
||||
print "Result.data:", result.data.domain_list
|
||||
elif status != 0:
|
||||
print "Resolve error:", unbound.ub_strerror(status)
|
||||
|
||||
In order to simplify the python code, unbound module contains function which reverses the hostname components.
|
||||
This function is defined as follows::
|
||||
|
||||
def reverse(domain):
|
||||
return '.'.join([a for a in domain.split(".")][::-1])
|
||||
|
||||
|
41
contrib/python/docs/source/examples/example2.rst
Normal file
41
contrib/python/docs/source/examples/example2.rst
Normal file
@ -0,0 +1,41 @@
|
||||
.. _example_setup_ctx:
|
||||
|
||||
==============================
|
||||
Lookup from threads
|
||||
==============================
|
||||
|
||||
This example shows how to use unbound module from a threaded program.
|
||||
In this example, three lookup threads are created which work in background.
|
||||
Each thread resolves different DNS record.
|
||||
|
||||
::
|
||||
|
||||
#!/usr/bin/python
|
||||
from unbound import ub_ctx, RR_TYPE_A, RR_CLASS_IN
|
||||
from threading import Thread
|
||||
|
||||
ctx = ub_ctx()
|
||||
ctx.resolvconf("/etc/resolv.conf")
|
||||
|
||||
class LookupThread(Thread):
|
||||
def __init__(self,ctx, name):
|
||||
Thread.__init__(self)
|
||||
self.ctx = ctx
|
||||
self.name = name
|
||||
|
||||
def run(self):
|
||||
print "Thread lookup started:",self.name
|
||||
status, result = self.ctx.resolve(self.name, RR_TYPE_A, RR_CLASS_IN)
|
||||
if status == 0 and result.havedata:
|
||||
print " Result:",self.name,":", result.data.address_list
|
||||
|
||||
threads = []
|
||||
for name in ["www.fit.vutbr.cz","www.vutbr.cz","www.google.com"]:
|
||||
thread = LookupThread(ctx, name)
|
||||
thread.start()
|
||||
threads.append(thread)
|
||||
|
||||
for thread in threads:
|
||||
thread.join()
|
||||
|
||||
|
36
contrib/python/docs/source/examples/example3.rst
Normal file
36
contrib/python/docs/source/examples/example3.rst
Normal file
@ -0,0 +1,36 @@
|
||||
.. _example_asynch:
|
||||
|
||||
==============================
|
||||
Asynchronous lookup
|
||||
==============================
|
||||
|
||||
This example performs the name lookup in the background.
|
||||
The main program keeps running while the name is resolved.
|
||||
|
||||
::
|
||||
|
||||
#!/usr/bin/python
|
||||
import time
|
||||
import unbound
|
||||
|
||||
ctx = unbound.ub_ctx()
|
||||
ctx.resolvconf("/etc/resolv.conf")
|
||||
|
||||
def call_back(my_data,status,result):
|
||||
print "Call_back:", my_data
|
||||
if status == 0 and result.havedata:
|
||||
print "Result:", result.data.address_list
|
||||
my_data['done_flag'] = True
|
||||
|
||||
|
||||
my_data = {'done_flag':False,'arbitrary':"object"}
|
||||
status, async_id = ctx.resolve_async("www.seznam.cz", my_data, call_back, unbound.RR_TYPE_A, unbound.RR_CLASS_IN)
|
||||
|
||||
while (status == 0) and (not my_data['done_flag']):
|
||||
status = ctx.process()
|
||||
time.sleep(0.1)
|
||||
|
||||
if (status != 0):
|
||||
print "Resolve error:", unbound.ub_strerror(status)
|
||||
|
||||
The :meth:`unbound.ub_ctx.resolve_async` method is able to pass on any Python object. In this example, we used a dictionary object `my_data`.
|
34
contrib/python/docs/source/examples/example4.rst
Normal file
34
contrib/python/docs/source/examples/example4.rst
Normal file
@ -0,0 +1,34 @@
|
||||
.. _example_examine:
|
||||
|
||||
==============================
|
||||
DNSSEC validator
|
||||
==============================
|
||||
|
||||
This example program performs DNSSEC validation of a DNS lookup.
|
||||
|
||||
::
|
||||
|
||||
#!/usr/bin/python
|
||||
import os
|
||||
from unbound import ub_ctx,RR_TYPE_A,RR_CLASS_IN
|
||||
|
||||
ctx = ub_ctx()
|
||||
ctx.resolvconf("/etc/resolv.conf")
|
||||
if (os.path.isfile("keys")):
|
||||
ctx.add_ta_file("keys") #read public keys for DNSSEC verification
|
||||
|
||||
status, result = ctx.resolve("www.nic.cz", RR_TYPE_A, RR_CLASS_IN)
|
||||
if status == 0 and result.havedata:
|
||||
|
||||
print "Result:", result.data.address_list
|
||||
|
||||
if result.secure:
|
||||
print "Result is secure"
|
||||
elif result.bogus:
|
||||
print "Result is bogus"
|
||||
else:
|
||||
print "Result is insecure"
|
||||
|
||||
More detailed informations can be seen in libUnbound DNSSEC tutorial `here`_.
|
||||
|
||||
.. _here: http://www.unbound.net/documentation/libunbound-tutorial-6.html
|
29
contrib/python/docs/source/examples/example5.rst
Normal file
29
contrib/python/docs/source/examples/example5.rst
Normal file
@ -0,0 +1,29 @@
|
||||
.. _example_resolver_only:
|
||||
|
||||
==============================
|
||||
Resolver only
|
||||
==============================
|
||||
|
||||
This example program shows how to perform DNS resolution only.
|
||||
Unbound contains two basic modules: resolver and validator.
|
||||
In case, the validator is not necessary, the validator module can be turned off using "module-config" option.
|
||||
This option contains a list of module names separated by the space char. This list determined which modules should be employed and in what order.
|
||||
|
||||
::
|
||||
|
||||
#!/usr/bin/python
|
||||
import os
|
||||
from unbound import ub_ctx,RR_TYPE_A,RR_CLASS_IN
|
||||
|
||||
ctx = ub_ctx()
|
||||
ctx.set_option("module-config:","iterator")
|
||||
ctx.resolvconf("/etc/resolv.conf")
|
||||
|
||||
status, result = ctx.resolve("www.google.com", RR_TYPE_A, RR_CLASS_IN)
|
||||
if status == 0 and result.havedata:
|
||||
|
||||
print "Result:", result.data.address_list
|
||||
|
||||
.. note::
|
||||
The :meth:`unbound.ub_ctx.set_option` method must be used before the first resolution (i.e. before :meth:`unbound.ub_ctx.resolve` or :meth:`unbound.ub_ctx.resolve_async` call).
|
||||
|
27
contrib/python/docs/source/examples/example6-1.py
Normal file
27
contrib/python/docs/source/examples/example6-1.py
Normal file
@ -0,0 +1,27 @@
|
||||
#!/usr/bin/python
|
||||
from unbound import ub_ctx,ub_strerror,RR_TYPE_A,RR_CLASS_IN
|
||||
|
||||
ctx = ub_ctx()
|
||||
ctx.resolvconf("/etc/resolv.conf")
|
||||
|
||||
status, result = ctx.resolve("test.record.xxx", RR_TYPE_A, RR_CLASS_IN)
|
||||
if status == 0 and result.havedata:
|
||||
print "Result:", result.data.address_list
|
||||
else:
|
||||
print "No record found"
|
||||
|
||||
#define new local zone
|
||||
status = ctx.zone_add("xxx.","static")
|
||||
if (status != 0): print "Error zone_add:",status, ub_strerror(status)
|
||||
|
||||
#add RR to the zone
|
||||
status = ctx.data_add("test.record.xxx. IN A 1.2.3.4")
|
||||
if (status != 0): print "Error data_add:",status, ub_strerror(status)
|
||||
|
||||
#lookup for an A record
|
||||
status, result = ctx.resolve("test.record.xxx", RR_TYPE_A, RR_CLASS_IN)
|
||||
if status == 0 and result.havedata:
|
||||
print "Result:", result.data.as_address_list()
|
||||
else:
|
||||
print "No record found"
|
||||
|
11
contrib/python/docs/source/examples/example6.rst
Normal file
11
contrib/python/docs/source/examples/example6.rst
Normal file
@ -0,0 +1,11 @@
|
||||
.. _example_localzone:
|
||||
|
||||
==============================
|
||||
Local zone manipulation
|
||||
==============================
|
||||
|
||||
This example program shows how to define local zone containing custom DNS records.
|
||||
|
||||
.. literalinclude:: example6-1.py
|
||||
:language: python
|
||||
|
17
contrib/python/docs/source/examples/example7-1.py
Normal file
17
contrib/python/docs/source/examples/example7-1.py
Normal file
@ -0,0 +1,17 @@
|
||||
#!/usr/bin/python
|
||||
# vim:fileencoding=utf-8
|
||||
#
|
||||
# IDN (Internationalized Domain Name) lookup support
|
||||
#
|
||||
import unbound
|
||||
|
||||
ctx = unbound.ub_ctx()
|
||||
ctx.resolvconf("/etc/resolv.conf")
|
||||
|
||||
status, result = ctx.resolve(u"www.háčkyčárky.cz", unbound.RR_TYPE_A, unbound.RR_CLASS_IN)
|
||||
if status == 0 and result.havedata:
|
||||
print "Result:"
|
||||
print " raw data:", result.data
|
||||
for k in result.data.address_list:
|
||||
print " address:%s" % k
|
||||
|
16
contrib/python/docs/source/examples/example7-2.py
Normal file
16
contrib/python/docs/source/examples/example7-2.py
Normal file
@ -0,0 +1,16 @@
|
||||
#!/usr/bin/python
|
||||
# vim:fileencoding=utf-8
|
||||
#
|
||||
# IDN (Internationalized Domain Name) lookup support (lookup for MX)
|
||||
#
|
||||
import unbound
|
||||
|
||||
ctx = unbound.ub_ctx()
|
||||
ctx.resolvconf("/etc/resolv.conf")
|
||||
|
||||
status, result = ctx.resolve(u"háčkyčárky.cz", unbound.RR_TYPE_MX, unbound.RR_CLASS_IN)
|
||||
if status == 0 and result.havedata:
|
||||
print "Result:"
|
||||
print " raw data:", result.data
|
||||
for k in result.data.mx_list_idn:
|
||||
print " priority:%d address:%s" % k
|
18
contrib/python/docs/source/examples/example7.rst
Normal file
18
contrib/python/docs/source/examples/example7.rst
Normal file
@ -0,0 +1,18 @@
|
||||
.. _example_idna:
|
||||
|
||||
=================================================
|
||||
Internationalized domain name support
|
||||
=================================================
|
||||
|
||||
Unlike the libUnbound, pyUnbound is able to handle IDN queries.
|
||||
|
||||
.. literalinclude:: example7-1.py
|
||||
:language: python
|
||||
|
||||
If we use unicode string in :meth:`unbound.ub_ctx.resolve` method, the IDN DNAME conversion (if it is necessary) is performed on background.
|
||||
|
||||
.. literalinclude:: example7-2.py
|
||||
:language: python
|
||||
|
||||
The :class:`unbound.ub_data` class contains attributes suffix which converts the dname to UTF string. These attributes have the '_idn' suffix.
|
||||
Apart from this aproach, two conversion functions exist (:func:`unbound.idn2dname` and :func:`unbound.dname2idn`).
|
31
contrib/python/docs/source/examples/example8-1.py
Normal file
31
contrib/python/docs/source/examples/example8-1.py
Normal file
@ -0,0 +1,31 @@
|
||||
#!/usr/bin/python
|
||||
# vim:fileencoding=utf-8
|
||||
#
|
||||
# Lookup for MX and NS records
|
||||
#
|
||||
import unbound
|
||||
|
||||
ctx = unbound.ub_ctx()
|
||||
ctx.resolvconf("/etc/resolv.conf")
|
||||
|
||||
status, result = ctx.resolve("nic.cz", unbound.RR_TYPE_MX, unbound.RR_CLASS_IN)
|
||||
if status == 0 and result.havedata:
|
||||
print "Result:"
|
||||
print " raw data:", result.data
|
||||
for k in result.data.mx_list:
|
||||
print " priority:%d address:%s" % k
|
||||
|
||||
status, result = ctx.resolve("nic.cz", unbound.RR_TYPE_A, unbound.RR_CLASS_IN)
|
||||
if status == 0 and result.havedata:
|
||||
print "Result:"
|
||||
print " raw data:", result.data
|
||||
for k in result.data.address_list:
|
||||
print " address:%s" % k
|
||||
|
||||
status, result = ctx.resolve("nic.cz", unbound.RR_TYPE_NS, unbound.RR_CLASS_IN)
|
||||
if status == 0 and result.havedata:
|
||||
print "Result:"
|
||||
print " raw data:", result.data
|
||||
for k in result.data.domain_list:
|
||||
print " host: %s" % k
|
||||
|
28
contrib/python/docs/source/examples/example8.rst
Normal file
28
contrib/python/docs/source/examples/example8.rst
Normal file
@ -0,0 +1,28 @@
|
||||
.. _example_mxlookup:
|
||||
|
||||
=================================================
|
||||
Lookup for MX and NS records
|
||||
=================================================
|
||||
|
||||
The pyUnbound extension provides functions which are able to encode RAW RDATA produces by unbound resolver (see :class:`unbound.ub_data`).
|
||||
|
||||
.. literalinclude:: example8-1.py
|
||||
:language: python
|
||||
|
||||
Previous example produces following output::
|
||||
|
||||
Result:
|
||||
raw data: 00 0F 05 6D 61 69 6C 34 03 6E 69 63 02 63 7A 00;00 14 02 6D 78 05 63 7A 6E 69 63 03 6F 72 67 00;00 0A 04 6D 61 69 6C 03 6E 69 63 02 63 7A 00
|
||||
priority:15 address: mail4.nic.cz.
|
||||
priority:20 address: mx.cznic.org.
|
||||
priority:10 address: mail.nic.cz.
|
||||
|
||||
Result:
|
||||
raw data: D9 1F CD 32
|
||||
address: 217.31.205.50
|
||||
|
||||
Result:
|
||||
raw data: 01 61 02 6E 73 03 6E 69 63 02 63 7A 00;01 65 02 6E 73 03 6E 69 63 02 63 7A 00;01 63 02 6E 73 03 6E 69 63 02 63 7A 00
|
||||
host: a.ns.nic.cz.
|
||||
host: e.ns.nic.cz.
|
||||
host: c.ns.nic.cz.
|
14
contrib/python/docs/source/examples/index.rst
Normal file
14
contrib/python/docs/source/examples/index.rst
Normal file
@ -0,0 +1,14 @@
|
||||
Examples
|
||||
==============================
|
||||
|
||||
Here you can find several examples which utilizes the unbound library in Python environment.
|
||||
Unbound is a caching validator and resolver and can be linked into an application, as a library where can answer DNS queries for the application.
|
||||
This set of examples shows how to use the functions from Python environment.
|
||||
|
||||
`Tutorials`
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:glob:
|
||||
|
||||
example*
|
27
contrib/python/docs/source/index.rst
Normal file
27
contrib/python/docs/source/index.rst
Normal file
@ -0,0 +1,27 @@
|
||||
PyUnbound documentation
|
||||
=======================================
|
||||
|
||||
This project contains an Unbound wrapper providing the thinnest layer over the library possible.
|
||||
Everything you can do from the libUnbound C API, you can do from Python, even more.
|
||||
|
||||
Contents
|
||||
----------
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
intro.rst
|
||||
install.rst
|
||||
examples/index.rst
|
||||
modules/unbound
|
||||
|
||||
Module Documentation
|
||||
-----------------------
|
||||
|
||||
* Module :mod:`unbound`
|
||||
|
||||
Indices and tables
|
||||
-------------------
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`search`
|
||||
|
35
contrib/python/docs/source/install.rst
Normal file
35
contrib/python/docs/source/install.rst
Normal file
@ -0,0 +1,35 @@
|
||||
Installation
|
||||
===================================
|
||||
|
||||
**Prerequisites**
|
||||
|
||||
Python 2.4 or higher, SWIG 1.3 or higher, GNU make
|
||||
|
||||
**Download**
|
||||
|
||||
You can download the source codes `here`_.
|
||||
The latest release is 1.1.1, Jan 15, 2009.
|
||||
|
||||
.. _here: unbound-1.1.1-py.tar.gz
|
||||
|
||||
**Compiling**
|
||||
|
||||
After downloading, you can compile the pyUnbound library by doing::
|
||||
|
||||
> tar -xzf unbound-1.1.1-py.tar.gz
|
||||
> cd unbound-1.1.1
|
||||
> ./configure --with-pyunbound
|
||||
> make
|
||||
|
||||
You need GNU make to compile sources; SWIG and Python devel libraries to compile extension module.
|
||||
|
||||
|
||||
**Testing**
|
||||
|
||||
If the compilation is successfull, you can test the python LDNS extension module by::
|
||||
|
||||
> cd contrib/python
|
||||
> make testenv
|
||||
> ./dns-lookup.py
|
||||
|
||||
In contrib/examples you can find simple applications written in Python using the Unbound extension.
|
39
contrib/python/docs/source/intro.rst
Normal file
39
contrib/python/docs/source/intro.rst
Normal file
@ -0,0 +1,39 @@
|
||||
Introduction
|
||||
===================================
|
||||
|
||||
**Unbound**
|
||||
|
||||
`Unbound`_ is an implementation of a DNS resolver, that performs caching and DNSSEC validation.
|
||||
Together with unbound, the libunbound library is provided.
|
||||
This library can be used to convert hostnames to ip addresses, and back, as well as obtain other information.
|
||||
Since the resolver allows to specify the class and type of a query (A record, NS, MX, ...), this library offers powerful resolving tool.
|
||||
The library also performs public-key validation of results with DNSSEC.
|
||||
|
||||
.. _Unbound: http://www.unbound.net/documentation
|
||||
|
||||
**pyUnbound**
|
||||
|
||||
The pyUnbound is an extension module for Python which provides an object-oriented interface to libunbound.
|
||||
It is the first Python module which offers thread-safe caching resolver.
|
||||
|
||||
The interface was designed with the emphasis on the simplicity of use.
|
||||
There are two main classes :class:`unbound.ub_ctx` (a validation and resolution context) and :class:`unbound.ub_result` which contains the validation and resolution results.
|
||||
The objects are thread-safe, and a context can be used in non-threaded as well as threaded environment.
|
||||
Resolution can be performed blocking and non-blocking (i.e. asynchronous).
|
||||
The asynchronous method returns from the call immediately, so that processing can go on, while the results become available later.
|
||||
|
||||
**Features**
|
||||
* customizable caching validation resolver for synchronous and asynchronous lookups
|
||||
* easy to use object interface
|
||||
* easy to integrate extension module
|
||||
* designed for thread environment (i.e. thread-safe)
|
||||
* allows define and customize of local zone and its RR's during the operation (i.e. without restart)
|
||||
* includes encoding functions to simplify the results retrieval
|
||||
* Internationalized domain name (`IDN`_) support
|
||||
|
||||
.. _IDN: http://en.wikipedia.org/wiki/Internationalized_domain_name
|
||||
|
||||
**Application area**
|
||||
* DNS-based applications performing DNS lookups; the caching resolver can reduce overhead
|
||||
* Applications where the validation of DNS records is required
|
||||
* Great solution for customizable and dynamic DNS-based white/blacklists (spam rejection, connection rejection, ...) using the dynamic local zone manipulation
|
167
contrib/python/docs/source/modules/unbound.rst
Normal file
167
contrib/python/docs/source/modules/unbound.rst
Normal file
@ -0,0 +1,167 @@
|
||||
Unbound module documentation
|
||||
================================
|
||||
|
||||
.. automodule:: unbound
|
||||
|
||||
Class ub_ctx
|
||||
--------------
|
||||
.. autoclass:: ub_ctx
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
.. automethod:: __init__
|
||||
|
||||
Class ub_result
|
||||
----------------------
|
||||
.. autoclass:: ub_result
|
||||
:members:
|
||||
|
||||
.. attribute:: qname
|
||||
|
||||
The original question, name text string.
|
||||
|
||||
.. attribute:: qtype
|
||||
|
||||
The class asked for.
|
||||
|
||||
.. attribute:: canonname
|
||||
|
||||
Canonical name for the result (the final cname). May be empty if no canonical name exists.
|
||||
|
||||
.. attribute:: answer_packet
|
||||
|
||||
The DNS answer packet. Network formatted. Can contain DNSSEC types.
|
||||
|
||||
.. attribute:: havedata
|
||||
|
||||
If there is any data, this property is true. If false, there was no data (nxdomain may be true, rcode can be set).
|
||||
|
||||
.. attribute:: secure
|
||||
|
||||
True, if the result is validated securely.
|
||||
False, if validation failed or domain queried has no security info.
|
||||
|
||||
It is possible to get a result with no data (havedata is false),
|
||||
and secure is true. This means that the non-existance of the data
|
||||
was cryptographically proven (with signatures).
|
||||
|
||||
.. attribute:: bogus
|
||||
|
||||
If the result was not secure (secure==0), and this result is due to a security failure, bogus is true.
|
||||
This means the data has been actively tampered with, signatures
|
||||
failed, expected signatures were not present, timestamps on
|
||||
signatures were out of date and so on.
|
||||
|
||||
If secure==0 and bogus==0, this can happen if the data is not secure
|
||||
because security is disabled for that domain name.
|
||||
This means the data is from a domain where data is not signed.
|
||||
|
||||
.. attribute:: nxdomain
|
||||
|
||||
If there was no data, and the domain did not exist, this is true.
|
||||
If it is false, and there was no data, then the domain name is purported to exist, but the requested data type is not available.
|
||||
|
||||
.. attribute:: rcode
|
||||
|
||||
DNS RCODE for the result. May contain additional error code if there was no data due to an error.
|
||||
0 (RCODE_NOERROR) if okay. See predefined `RCODE_` constants.
|
||||
|
||||
RCODE can be represented in display representation form (string) using :attr:`rcode_str` attribute.
|
||||
|
||||
Class ub_data
|
||||
----------------------
|
||||
.. autoclass:: ub_data
|
||||
:members:
|
||||
|
||||
Functions
|
||||
----------------------
|
||||
.. autofunction:: reverse
|
||||
.. autofunction:: idn2dname
|
||||
.. autofunction:: dname2idn
|
||||
|
||||
Predefined constants
|
||||
-----------------------
|
||||
|
||||
**RCODE**
|
||||
* RCODE_FORMERR = 1
|
||||
* RCODE_NOERROR = 0
|
||||
* RCODE_NOTAUTH = 9
|
||||
* RCODE_NOTIMPL = 4
|
||||
* RCODE_NOTZONE = 10
|
||||
* RCODE_NXDOMAIN = 3
|
||||
* RCODE_NXRRSET = 8
|
||||
* RCODE_REFUSED = 5
|
||||
* RCODE_SERVFAIL = 2
|
||||
* RCODE_YXDOMAIN = 6
|
||||
* RCODE_YXRRSET = 7
|
||||
|
||||
**RR_CLASS**
|
||||
* RR_CLASS_ANY = 255
|
||||
* RR_CLASS_CH = 3
|
||||
* RR_CLASS_HS = 4
|
||||
* RR_CLASS_IN = 1
|
||||
* RR_CLASS_NONE = 254
|
||||
|
||||
**RR_TYPE**
|
||||
* RR_TYPE_A = 1
|
||||
* RR_TYPE_A6 = 38
|
||||
* RR_TYPE_AAAA = 28
|
||||
* RR_TYPE_AFSDB = 18
|
||||
* RR_TYPE_ANY = 255
|
||||
* RR_TYPE_APL = 42
|
||||
* RR_TYPE_ATMA = 34
|
||||
* RR_TYPE_AXFR = 252
|
||||
* RR_TYPE_CERT = 37
|
||||
* RR_TYPE_CNAME = 5
|
||||
* RR_TYPE_DHCID = 49
|
||||
* RR_TYPE_DLV = 32769
|
||||
* RR_TYPE_DNAME = 39
|
||||
* RR_TYPE_DNSKEY = 48
|
||||
* RR_TYPE_DS = 43
|
||||
* RR_TYPE_EID = 31
|
||||
* RR_TYPE_GID = 102
|
||||
* RR_TYPE_GPOS = 27
|
||||
* RR_TYPE_HINFO = 13
|
||||
* RR_TYPE_IPSECKEY = 45
|
||||
* RR_TYPE_ISDN = 20
|
||||
* RR_TYPE_IXFR = 251
|
||||
* RR_TYPE_KEY = 25
|
||||
* RR_TYPE_KX = 36
|
||||
* RR_TYPE_LOC = 29
|
||||
* RR_TYPE_MAILA = 254
|
||||
* RR_TYPE_MAILB = 253
|
||||
* RR_TYPE_MB = 7
|
||||
* RR_TYPE_MD = 3
|
||||
* RR_TYPE_MF = 4
|
||||
* RR_TYPE_MG = 8
|
||||
* RR_TYPE_MINFO = 14
|
||||
* RR_TYPE_MR = 9
|
||||
* RR_TYPE_MX = 15
|
||||
* RR_TYPE_NAPTR = 35
|
||||
* RR_TYPE_NIMLOC = 32
|
||||
* RR_TYPE_NS = 2
|
||||
* RR_TYPE_NSAP = 22
|
||||
* RR_TYPE_NSAP_PTR = 23
|
||||
* RR_TYPE_NSEC = 47
|
||||
* RR_TYPE_NSEC3 = 50
|
||||
* RR_TYPE_NSEC3PARAMS = 51
|
||||
* RR_TYPE_NULL = 10
|
||||
* RR_TYPE_NXT = 30
|
||||
* RR_TYPE_OPT = 41
|
||||
* RR_TYPE_PTR = 12
|
||||
* RR_TYPE_PX = 26
|
||||
* RR_TYPE_RP = 17
|
||||
* RR_TYPE_RRSIG = 46
|
||||
* RR_TYPE_RT = 21
|
||||
* RR_TYPE_SIG = 24
|
||||
* RR_TYPE_SINK = 40
|
||||
* RR_TYPE_SOA = 6
|
||||
* RR_TYPE_SRV = 33
|
||||
* RR_TYPE_SSHFP = 44
|
||||
* RR_TYPE_TSIG = 250
|
||||
* RR_TYPE_TXT = 16
|
||||
* RR_TYPE_UID = 101
|
||||
* RR_TYPE_UINFO = 100
|
||||
* RR_TYPE_UNSPEC = 103
|
||||
* RR_TYPE_WKS = 11
|
||||
* RR_TYPE_X25 = 19
|
56
contrib/python/examples/async-lookup.py
Normal file
56
contrib/python/examples/async-lookup.py
Normal file
@ -0,0 +1,56 @@
|
||||
#!/usr/bin/python
|
||||
'''
|
||||
async-lookup.py : This example shows how to use asynchronous lookups
|
||||
|
||||
Authors: Zdenek Vasicek (vasicek AT fit.vutbr.cz)
|
||||
Marek Vavrusa (xvavru00 AT stud.fit.vutbr.cz)
|
||||
|
||||
Copyright (c) 2008. All rights reserved.
|
||||
|
||||
This software is open source.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
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 REGENTS 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.
|
||||
'''
|
||||
import unbound
|
||||
import time
|
||||
|
||||
ctx = unbound.ub_ctx()
|
||||
ctx.resolvconf("/etc/resolv.conf")
|
||||
|
||||
def call_back(my_data,status,result):
|
||||
print "Call_back:", my_data
|
||||
if status == 0 and result.havedata:
|
||||
print "Result:", result.data.address_list
|
||||
my_data['done_flag'] = True
|
||||
|
||||
|
||||
my_data = {'done_flag':False,'arbitrary':"object"}
|
||||
status, async_id = ctx.resolve_async("www.nic.cz", my_data, call_back, unbound.RR_TYPE_A, unbound.RR_CLASS_IN)
|
||||
|
||||
while (status == 0) and (not my_data['done_flag']):
|
||||
status = ctx.process()
|
||||
time.sleep(0.1)
|
||||
|
||||
if (status != 0):
|
||||
print "Resolve error:", unbound.ub_strerror(status)
|
44
contrib/python/examples/dns-lookup.py
Normal file
44
contrib/python/examples/dns-lookup.py
Normal file
@ -0,0 +1,44 @@
|
||||
#!/usr/bin/python
|
||||
'''
|
||||
dns-lookup.py : This example shows how to resolve IP address
|
||||
|
||||
Authors: Zdenek Vasicek (vasicek AT fit.vutbr.cz)
|
||||
Marek Vavrusa (xvavru00 AT stud.fit.vutbr.cz)
|
||||
|
||||
Copyright (c) 2008. All rights reserved.
|
||||
|
||||
This software is open source.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
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 REGENTS 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.
|
||||
'''
|
||||
import unbound
|
||||
|
||||
ctx = unbound.ub_ctx()
|
||||
ctx.resolvconf("/etc/resolv.conf")
|
||||
|
||||
status, result = ctx.resolve("www.nic.cz", unbound.RR_TYPE_A, unbound.RR_CLASS_IN)
|
||||
if status == 0 and result.havedata:
|
||||
print "Result:", result.data.address_list
|
||||
elif status != 0:
|
||||
print "Error:", unbound.ub_strerror(status)
|
59
contrib/python/examples/dnssec-valid.py
Normal file
59
contrib/python/examples/dnssec-valid.py
Normal file
@ -0,0 +1,59 @@
|
||||
#!/usr/bin/python
|
||||
'''
|
||||
dnssec-valid.py: DNSSEC validation
|
||||
|
||||
Authors: Zdenek Vasicek (vasicek AT fit.vutbr.cz)
|
||||
Marek Vavrusa (xvavru00 AT stud.fit.vutbr.cz)
|
||||
|
||||
Copyright (c) 2008. All rights reserved.
|
||||
|
||||
This software is open source.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
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 REGENTS 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.
|
||||
'''
|
||||
import os
|
||||
from unbound import ub_ctx,RR_TYPE_A,RR_CLASS_IN
|
||||
|
||||
ctx = ub_ctx()
|
||||
ctx.resolvconf("/etc/resolv.conf")
|
||||
|
||||
fw = open("dnssec-valid.txt","wb")
|
||||
ctx.debugout(fw)
|
||||
ctx.debuglevel(2)
|
||||
|
||||
if os.path.isfile("keys"):
|
||||
ctx.add_ta_file("keys") #read public keys for DNSSEC verificatio
|
||||
|
||||
status, result = ctx.resolve("www.nic.cz", RR_TYPE_A, RR_CLASS_IN)
|
||||
if status == 0 and result.havedata:
|
||||
|
||||
print "Result:", result.data.address_list
|
||||
|
||||
if result.secure:
|
||||
print "Result is secure"
|
||||
elif result.bogus:
|
||||
print "Result is bogus"
|
||||
else:
|
||||
print "Result is insecure"
|
||||
|
61
contrib/python/examples/example8-1.py
Normal file
61
contrib/python/examples/example8-1.py
Normal file
@ -0,0 +1,61 @@
|
||||
#!/usr/bin/python
|
||||
# vim:fileencoding=utf-8
|
||||
'''
|
||||
example8-1.py: Example shows how to lookup for MX and NS records
|
||||
|
||||
Authors: Zdenek Vasicek (vasicek AT fit.vutbr.cz)
|
||||
Marek Vavrusa (xvavru00 AT stud.fit.vutbr.cz)
|
||||
|
||||
Copyright (c) 2008. All rights reserved.
|
||||
|
||||
This software is open source.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
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 REGENTS 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.
|
||||
'''
|
||||
import unbound
|
||||
|
||||
ctx = unbound.ub_ctx()
|
||||
ctx.resolvconf("/etc/resolv.conf")
|
||||
|
||||
status, result = ctx.resolve("nic.cz", unbound.RR_TYPE_MX, unbound.RR_CLASS_IN)
|
||||
if status == 0 and result.havedata:
|
||||
print "Result:"
|
||||
print " raw data:", result.data
|
||||
for k in result.data.mx_list:
|
||||
print " priority:%d address:%s" % k
|
||||
|
||||
status, result = ctx.resolve("nic.cz", unbound.RR_TYPE_A, unbound.RR_CLASS_IN)
|
||||
if status == 0 and result.havedata:
|
||||
print "Result:"
|
||||
print " raw data:", result.data
|
||||
for k in result.data.address_list:
|
||||
print " address:%s" % k
|
||||
|
||||
status, result = ctx.resolve("nic.cz", unbound.RR_TYPE_NS, unbound.RR_CLASS_IN)
|
||||
if status == 0 and result.havedata:
|
||||
print "Result:"
|
||||
print " raw data:", result.data
|
||||
for k in result.data.domain_list:
|
||||
print " host: %s" % k
|
||||
|
62
contrib/python/examples/idn-lookup.py
Normal file
62
contrib/python/examples/idn-lookup.py
Normal file
@ -0,0 +1,62 @@
|
||||
#!/usr/bin/python
|
||||
# vim:fileencoding=utf-8
|
||||
'''
|
||||
idn-lookup.py: IDN (Internationalized Domain Name) lookup support
|
||||
|
||||
Authors: Zdenek Vasicek (vasicek AT fit.vutbr.cz)
|
||||
Marek Vavrusa (xvavru00 AT stud.fit.vutbr.cz)
|
||||
|
||||
Copyright (c) 2008. All rights reserved.
|
||||
|
||||
This software is open source.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
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 REGENTS 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.
|
||||
'''
|
||||
import unbound
|
||||
import locale
|
||||
|
||||
ctx = unbound.ub_ctx()
|
||||
ctx.set_option("module-config:","iterator") #We don't need validation
|
||||
ctx.resolvconf("/etc/resolv.conf")
|
||||
|
||||
#The unicode IDN string is automatically converted (if necessary)
|
||||
status, result = ctx.resolve(u"www.háčkyčárky.cz", unbound.RR_TYPE_A, unbound.RR_CLASS_IN)
|
||||
if status == 0 and result.havedata:
|
||||
print "Result:"
|
||||
print " raw data:", result.data
|
||||
for k in result.data.address_list:
|
||||
print " address:%s" % k
|
||||
|
||||
status, result = ctx.resolve(u"háčkyčárky.cz", unbound.RR_TYPE_MX, unbound.RR_CLASS_IN)
|
||||
if status == 0 and result.havedata:
|
||||
print "Result:"
|
||||
print " raw data:", result.data
|
||||
for k in result.data.mx_list_idn:
|
||||
print " priority:%d address:%s" % k
|
||||
|
||||
status, result = ctx.resolve(unbound.reverse('217.31.204.66')+'.in-addr.arpa', unbound.RR_TYPE_PTR, unbound.RR_CLASS_IN)
|
||||
if status == 0 and result.havedata:
|
||||
print "Result.data:", result.data
|
||||
for k in result.data.domain_list_idn:
|
||||
print " dname:%s" % k
|
53
contrib/python/examples/mx-lookup.py
Normal file
53
contrib/python/examples/mx-lookup.py
Normal file
@ -0,0 +1,53 @@
|
||||
#!/usr/bin/python
|
||||
# vim:fileencoding=utf-8
|
||||
'''
|
||||
mx-lookup.py: Lookup for MX records
|
||||
|
||||
Authors: Zdenek Vasicek (vasicek AT fit.vutbr.cz)
|
||||
Marek Vavrusa (xvavru00 AT stud.fit.vutbr.cz)
|
||||
|
||||
Copyright (c) 2008. All rights reserved.
|
||||
|
||||
This software is open source.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
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 REGENTS 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.
|
||||
'''
|
||||
import unbound
|
||||
|
||||
ctx = unbound.ub_ctx()
|
||||
ctx.resolvconf("/etc/resolv.conf")
|
||||
|
||||
status, result = ctx.resolve("nic.cz", unbound.RR_TYPE_MX, unbound.RR_CLASS_IN)
|
||||
if status == 0 and result.havedata:
|
||||
print "Result:"
|
||||
print " raw data:", result.data
|
||||
for k in result.data.mx_list:
|
||||
print " priority:%d address:%s" % k
|
||||
|
||||
status, result = ctx.resolve("nic.cz", unbound.RR_TYPE_A, unbound.RR_CLASS_IN)
|
||||
if status == 0 and result.havedata:
|
||||
print "Result:"
|
||||
print " raw data:", result.data
|
||||
for k in result.data.address_list:
|
||||
print " address:%s" % k
|
47
contrib/python/examples/ns-lookup.py
Normal file
47
contrib/python/examples/ns-lookup.py
Normal file
@ -0,0 +1,47 @@
|
||||
#!/usr/bin/python
|
||||
# vim:fileencoding=utf-8
|
||||
'''
|
||||
ns-lookup.py: Example shows how to lookup for NS records
|
||||
|
||||
Authors: Zdenek Vasicek (vasicek AT fit.vutbr.cz)
|
||||
Marek Vavrusa (xvavru00 AT stud.fit.vutbr.cz)
|
||||
|
||||
Copyright (c) 2008. All rights reserved.
|
||||
|
||||
This software is open source.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
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 REGENTS 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.
|
||||
'''
|
||||
import unbound
|
||||
|
||||
ctx = unbound.ub_ctx()
|
||||
ctx.resolvconf("/etc/resolv.conf")
|
||||
|
||||
status, result = ctx.resolve("vutbr.cz", unbound.RR_TYPE_NS, unbound.RR_CLASS_IN)
|
||||
if status == 0 and result.havedata:
|
||||
print "Result:"
|
||||
print " raw data:", result.data
|
||||
for k in result.data.domain_list:
|
||||
print " host: %s" % k
|
||||
|
43
contrib/python/examples/reverse-lookup.py
Normal file
43
contrib/python/examples/reverse-lookup.py
Normal file
@ -0,0 +1,43 @@
|
||||
#!/usr/bin/python
|
||||
'''
|
||||
reverse-lookup.py: Example shows how to resolve reverse record
|
||||
|
||||
Authors: Zdenek Vasicek (vasicek AT fit.vutbr.cz)
|
||||
Marek Vavrusa (xvavru00 AT stud.fit.vutbr.cz)
|
||||
|
||||
Copyright (c) 2008. All rights reserved.
|
||||
|
||||
This software is open source.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
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 REGENTS 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.
|
||||
'''
|
||||
import unbound
|
||||
|
||||
ctx = unbound.ub_ctx()
|
||||
ctx.resolvconf("/etc/resolv.conf")
|
||||
|
||||
status, result = ctx.resolve(unbound.reverse("74.125.43.147") + ".in-addr.arpa.", unbound.RR_TYPE_PTR, unbound.RR_CLASS_IN)
|
||||
if status == 0 and result.havedata:
|
||||
print "Result.data:", result.data, result.data.domain_list
|
||||
|
930
contrib/python/libunbound.i
Normal file
930
contrib/python/libunbound.i
Normal file
@ -0,0 +1,930 @@
|
||||
/*
|
||||
* libounbound.i: pyUnbound module (libunbound wrapper for Python)
|
||||
*
|
||||
* Copyright (c) 2009, Zdenek Vasicek (vasicek AT fit.vutbr.cz)
|
||||
* Marek Vavrusa (xvavru00 AT stud.fit.vutbr.cz)
|
||||
*
|
||||
* This software is open source.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the organization 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 REGENTS 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.
|
||||
*/
|
||||
%module unbound
|
||||
%{
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include "libunbound/unbound.h"
|
||||
%}
|
||||
|
||||
%pythoncode %{
|
||||
import encodings.idna
|
||||
%}
|
||||
|
||||
//%include "doc.i"
|
||||
%include "file.i"
|
||||
|
||||
%feature("docstring") strerror "Convert error value to a human readable string."
|
||||
|
||||
// ================================================================================
|
||||
// ub_resolve - perform resolution and validation
|
||||
// ================================================================================
|
||||
%typemap(in,numinputs=0,noblock=1) (struct ub_result** result)
|
||||
{
|
||||
struct ub_result* newubr;
|
||||
$1 = &newubr;
|
||||
}
|
||||
|
||||
/* result generation */
|
||||
%typemap(argout,noblock=1) (struct ub_result** result)
|
||||
{
|
||||
PyObject* tuple;
|
||||
tuple = PyTuple_New(2);
|
||||
PyTuple_SetItem(tuple, 0, $result);
|
||||
if (result == 0) {
|
||||
PyTuple_SetItem(tuple, 1, SWIG_NewPointerObj(SWIG_as_voidptr(newubr), SWIGTYPE_p_ub_result, SWIG_POINTER_OWN | 0 ));
|
||||
} else {
|
||||
PyTuple_SetItem(tuple, 1, Py_None);
|
||||
}
|
||||
$result = tuple;
|
||||
}
|
||||
|
||||
|
||||
// ================================================================================
|
||||
// ub_ctx - validation context
|
||||
// ================================================================================
|
||||
%nodefaultctor ub_ctx; //no default constructor & destructor
|
||||
%nodefaultdtor ub_ctx;
|
||||
|
||||
%newobject ub_ctx_create;
|
||||
%delobject ub_ctx_delete;
|
||||
%rename(_ub_ctx_delete) ub_ctx_delete;
|
||||
|
||||
%newobject ub_resolve;
|
||||
|
||||
%inline %{
|
||||
void ub_ctx_free_dbg (struct ub_ctx* c) {
|
||||
printf("******** UB_CTX free 0x%lX ************\n", (long unsigned int)c);
|
||||
ub_ctx_delete(c);
|
||||
}
|
||||
|
||||
//RR types
|
||||
enum enum_rr_type
|
||||
{
|
||||
/** a host address */
|
||||
RR_TYPE_A = 1,
|
||||
/** an authoritative name server */
|
||||
RR_TYPE_NS = 2,
|
||||
/** a mail destination (Obsolete - use MX) */
|
||||
RR_TYPE_MD = 3,
|
||||
/** a mail forwarder (Obsolete - use MX) */
|
||||
RR_TYPE_MF = 4,
|
||||
/** the canonical name for an alias */
|
||||
RR_TYPE_CNAME = 5,
|
||||
/** marks the start of a zone of authority */
|
||||
RR_TYPE_SOA = 6,
|
||||
/** a mailbox domain name (EXPERIMENTAL) */
|
||||
RR_TYPE_MB = 7,
|
||||
/** a mail group member (EXPERIMENTAL) */
|
||||
RR_TYPE_MG = 8,
|
||||
/** a mail rename domain name (EXPERIMENTAL) */
|
||||
RR_TYPE_MR = 9,
|
||||
/** a null RR (EXPERIMENTAL) */
|
||||
RR_TYPE_NULL = 10,
|
||||
/** a well known service description */
|
||||
RR_TYPE_WKS = 11,
|
||||
/** a domain name pointer */
|
||||
RR_TYPE_PTR = 12,
|
||||
/** host information */
|
||||
RR_TYPE_HINFO = 13,
|
||||
/** mailbox or mail list information */
|
||||
RR_TYPE_MINFO = 14,
|
||||
/** mail exchange */
|
||||
RR_TYPE_MX = 15,
|
||||
/** text strings */
|
||||
RR_TYPE_TXT = 16,
|
||||
/** RFC1183 */
|
||||
RR_TYPE_RP = 17,
|
||||
/** RFC1183 */
|
||||
RR_TYPE_AFSDB = 18,
|
||||
/** RFC1183 */
|
||||
RR_TYPE_X25 = 19,
|
||||
/** RFC1183 */
|
||||
RR_TYPE_ISDN = 20,
|
||||
/** RFC1183 */
|
||||
RR_TYPE_RT = 21,
|
||||
/** RFC1706 */
|
||||
RR_TYPE_NSAP = 22,
|
||||
/** RFC1348 */
|
||||
RR_TYPE_NSAP_PTR = 23,
|
||||
/** 2535typecode */
|
||||
RR_TYPE_SIG = 24,
|
||||
/** 2535typecode */
|
||||
RR_TYPE_KEY = 25,
|
||||
/** RFC2163 */
|
||||
RR_TYPE_PX = 26,
|
||||
/** RFC1712 */
|
||||
RR_TYPE_GPOS = 27,
|
||||
/** ipv6 address */
|
||||
RR_TYPE_AAAA = 28,
|
||||
/** LOC record RFC1876 */
|
||||
RR_TYPE_LOC = 29,
|
||||
/** 2535typecode */
|
||||
RR_TYPE_NXT = 30,
|
||||
/** draft-ietf-nimrod-dns-01.txt */
|
||||
RR_TYPE_EID = 31,
|
||||
/** draft-ietf-nimrod-dns-01.txt */
|
||||
RR_TYPE_NIMLOC = 32,
|
||||
/** SRV record RFC2782 */
|
||||
RR_TYPE_SRV = 33,
|
||||
/** http://www.jhsoft.com/rfc/af-saa-0069.000.rtf */
|
||||
RR_TYPE_ATMA = 34,
|
||||
/** RFC2915 */
|
||||
RR_TYPE_NAPTR = 35,
|
||||
/** RFC2230 */
|
||||
RR_TYPE_KX = 36,
|
||||
/** RFC2538 */
|
||||
RR_TYPE_CERT = 37,
|
||||
/** RFC2874 */
|
||||
RR_TYPE_A6 = 38,
|
||||
/** RFC2672 */
|
||||
RR_TYPE_DNAME = 39,
|
||||
/** dnsind-kitchen-sink-02.txt */
|
||||
RR_TYPE_SINK = 40,
|
||||
/** Pseudo OPT record... */
|
||||
RR_TYPE_OPT = 41,
|
||||
/** RFC3123 */
|
||||
RR_TYPE_APL = 42,
|
||||
/** draft-ietf-dnsext-delegation */
|
||||
RR_TYPE_DS = 43,
|
||||
/** SSH Key Fingerprint */
|
||||
RR_TYPE_SSHFP = 44,
|
||||
/** draft-richardson-ipseckey-rr-11.txt */
|
||||
RR_TYPE_IPSECKEY = 45,
|
||||
/** draft-ietf-dnsext-dnssec-25 */
|
||||
RR_TYPE_RRSIG = 46,
|
||||
RR_TYPE_NSEC = 47,
|
||||
RR_TYPE_DNSKEY = 48,
|
||||
RR_TYPE_DHCID = 49,
|
||||
|
||||
RR_TYPE_NSEC3 = 50,
|
||||
RR_TYPE_NSEC3PARAMS = 51,
|
||||
|
||||
RR_TYPE_UINFO = 100,
|
||||
RR_TYPE_UID = 101,
|
||||
RR_TYPE_GID = 102,
|
||||
RR_TYPE_UNSPEC = 103,
|
||||
|
||||
RR_TYPE_TSIG = 250,
|
||||
RR_TYPE_IXFR = 251,
|
||||
RR_TYPE_AXFR = 252,
|
||||
/** A request for mailbox-related records (MB, MG or MR) */
|
||||
RR_TYPE_MAILB = 253,
|
||||
/** A request for mail agent RRs (Obsolete - see MX) */
|
||||
RR_TYPE_MAILA = 254,
|
||||
/** any type (wildcard) */
|
||||
RR_TYPE_ANY = 255,
|
||||
|
||||
/* RFC 4431, 5074, DNSSEC Lookaside Validation */
|
||||
RR_TYPE_DLV = 32769,
|
||||
};
|
||||
|
||||
// RR classes
|
||||
enum enum_rr_class
|
||||
{
|
||||
/** the Internet */
|
||||
RR_CLASS_IN = 1,
|
||||
/** Chaos class */
|
||||
RR_CLASS_CH = 3,
|
||||
/** Hesiod (Dyer 87) */
|
||||
RR_CLASS_HS = 4,
|
||||
/** None class, dynamic update */
|
||||
RR_CLASS_NONE = 254,
|
||||
/** Any class */
|
||||
RR_CLASS_ANY = 255,
|
||||
};
|
||||
%}
|
||||
|
||||
%feature("docstring") ub_ctx "Unbound resolving and validation context.
|
||||
|
||||
The validation context is created to hold the resolver status, validation keys and a small cache (containing messages, rrsets, roundtrip times, trusted keys, lameness information).
|
||||
|
||||
**Usage**
|
||||
|
||||
>>> import unbound
|
||||
>>> ctx = unbound.ub_ctx()
|
||||
>>> ctx.resolvconf(\"/etc/resolv.conf\")
|
||||
>>> status, result = ctx.resolve(\"www.google.com\", unbound.RR_TYPE_A, unbound.RR_CLASS_IN)
|
||||
>>> if status==0 and result.havedata:
|
||||
>>> print \"Result:\",result.data.address_list
|
||||
Result: ['74.125.43.147', '74.125.43.99', '74.125.43.103', '74.125.43.104']
|
||||
"
|
||||
|
||||
%extend ub_ctx
|
||||
{
|
||||
%pythoncode %{
|
||||
def __init__(self):
|
||||
"""Creates a resolving and validation context.
|
||||
|
||||
An exception is invoked if the process of creation an ub_ctx instance fails.
|
||||
"""
|
||||
self.this = _unbound.ub_ctx_create()
|
||||
if not self.this:
|
||||
raise Exception("Fatal error: unbound context initialization failed")
|
||||
|
||||
#__swig_destroy__ = _unbound.ub_ctx_free_dbg
|
||||
__swig_destroy__ = _unbound._ub_ctx_delete
|
||||
|
||||
#UB_CTX_METHODS_#
|
||||
def add_ta(self,ta):
|
||||
"""Add a trust anchor to the given context.
|
||||
|
||||
The trust anchor is a string, on one line, that holds a valid DNSKEY or DS RR.
|
||||
|
||||
:param ta:
|
||||
string, with zone-format RR on one line. [domainname] [TTL optional] [type] [class optional] [rdata contents]
|
||||
:returns: (int) 0 if OK, else error.
|
||||
"""
|
||||
return _unbound.ub_ctx_add_ta(self,ta)
|
||||
#parameters: struct ub_ctx *,char *,
|
||||
#retvals: int
|
||||
|
||||
def add_ta_file(self,fname):
|
||||
"""Add trust anchors to the given context.
|
||||
|
||||
Pass name of a file with DS and DNSKEY records (like from dig or drill).
|
||||
|
||||
:param fname:
|
||||
filename of file with keyfile with trust anchors.
|
||||
:returns: (int) 0 if OK, else error.
|
||||
"""
|
||||
return _unbound.ub_ctx_add_ta_file(self,fname)
|
||||
#parameters: struct ub_ctx *,char *,
|
||||
#retvals: int
|
||||
|
||||
def config(self,fname):
|
||||
"""setup configuration for the given context.
|
||||
|
||||
:param fname:
|
||||
unbound config file (not all settings applicable). This is a power-users interface that lets you specify all sorts of options. For some specific options, such as adding trust anchors, special routines exist.
|
||||
:returns: (int) 0 if OK, else error.
|
||||
"""
|
||||
return _unbound.ub_ctx_config(self,fname)
|
||||
#parameters: struct ub_ctx *,char *,
|
||||
#retvals: int
|
||||
|
||||
def debuglevel(self,d):
|
||||
"""Set debug verbosity for the context Output is directed to stderr.
|
||||
|
||||
:param d:
|
||||
debug level, 0 is off, 1 is very minimal, 2 is detailed, and 3 is lots.
|
||||
:returns: (int) 0 if OK, else error.
|
||||
"""
|
||||
return _unbound.ub_ctx_debuglevel(self,d)
|
||||
#parameters: struct ub_ctx *,int,
|
||||
#retvals: int
|
||||
|
||||
def debugout(self,out):
|
||||
"""Set debug output (and error output) to the specified stream.
|
||||
|
||||
Pass None to disable. Default is stderr.
|
||||
|
||||
:param out:
|
||||
File stream to log to.
|
||||
:returns: (int) 0 if OK, else error.
|
||||
|
||||
**Usage:**
|
||||
|
||||
In order to log into file, use
|
||||
|
||||
::
|
||||
|
||||
ctx = unbound.ub_ctx()
|
||||
fw = fopen("debug.log")
|
||||
ctx.debuglevel(3)
|
||||
ctx.debugout(fw)
|
||||
|
||||
Another option is to print the debug informations to stderr output
|
||||
|
||||
::
|
||||
|
||||
ctx = unbound.ub_ctx()
|
||||
ctx.debuglevel(10)
|
||||
ctx.debugout(sys.stderr)
|
||||
"""
|
||||
return _unbound.ub_ctx_debugout(self,out)
|
||||
#parameters: struct ub_ctx *,void *,
|
||||
#retvals: int
|
||||
|
||||
def hosts(self,fname="/etc/hosts"):
|
||||
"""Read list of hosts from the filename given.
|
||||
|
||||
Usually "/etc/hosts". These addresses are not flagged as DNSSEC secure when queried for.
|
||||
|
||||
:param fname:
|
||||
file name string. If None "/etc/hosts" is used.
|
||||
:returns: (int) 0 if OK, else error.
|
||||
"""
|
||||
return _unbound.ub_ctx_hosts(self,fname)
|
||||
#parameters: struct ub_ctx *,char *,
|
||||
#retvals: int
|
||||
|
||||
def print_local_zones(self):
|
||||
"""Print the local zones and their content (RR data) to the debug output.
|
||||
|
||||
:returns: (int) 0 if OK, else error.
|
||||
"""
|
||||
return _unbound.ub_ctx_print_local_zones(self)
|
||||
#parameters: struct ub_ctx *,
|
||||
#retvals: int
|
||||
|
||||
def resolvconf(self,fname="/etc/resolv.conf"):
|
||||
"""Read list of nameservers to use from the filename given.
|
||||
|
||||
Usually "/etc/resolv.conf". Uses those nameservers as caching proxies. If they do not support DNSSEC, validation may fail.
|
||||
|
||||
Only nameservers are picked up, the searchdomain, ndots and other settings from resolv.conf(5) are ignored.
|
||||
|
||||
:param fname:
|
||||
file name string. If None "/etc/resolv.conf" is used.
|
||||
:returns: (int) 0 if OK, else error.
|
||||
"""
|
||||
return _unbound.ub_ctx_resolvconf(self,fname)
|
||||
#parameters: struct ub_ctx *,char *,
|
||||
#retvals: int
|
||||
|
||||
def set_async(self,dothread):
|
||||
"""Set a context behaviour for asynchronous action.
|
||||
|
||||
:param dothread:
|
||||
if True, enables threading and a call to :meth:`resolve_async` creates a thread to handle work in the background.
|
||||
If False, a process is forked to handle work in the background.
|
||||
Changes to this setting after :meth:`async` calls have been made have no effect (delete and re-create the context to change).
|
||||
:returns: (int) 0 if OK, else error.
|
||||
"""
|
||||
return _unbound.ub_ctx_async(self,dothread)
|
||||
#parameters: struct ub_ctx *,int,
|
||||
#retvals: int
|
||||
|
||||
def set_fwd(self,addr):
|
||||
"""Set machine to forward DNS queries to, the caching resolver to use.
|
||||
|
||||
IP4 or IP6 address. Forwards all DNS requests to that machine, which is expected to run a recursive resolver. If the is not DNSSEC-capable, validation may fail. Can be called several times, in that case the addresses are used as backup servers.
|
||||
|
||||
To read the list of nameservers from /etc/resolv.conf (from DHCP or so), use the call :meth:`resolvconf`.
|
||||
|
||||
:param addr:
|
||||
address, IP4 or IP6 in string format. If the addr is None, forwarding is disabled.
|
||||
:returns: (int) 0 if OK, else error.
|
||||
"""
|
||||
return _unbound.ub_ctx_set_fwd(self,addr)
|
||||
#parameters: struct ub_ctx *,char *,
|
||||
#retvals: int
|
||||
|
||||
def set_option(self,opt,val):
|
||||
"""Set an option for the context.
|
||||
|
||||
Changes to the options after :meth:`resolve`, :meth:`resolve_async`, :meth:`zone_add`, :meth:`zone_remove`, :meth:`data_add` or :meth:`data_remove` have no effect (you have to delete and re-create the context).
|
||||
|
||||
:param opt:
|
||||
option name from the unbound.conf config file format. (not all settings applicable). The name includes the trailing ':' for example set_option("logfile:", "mylog.txt"); This is a power-users interface that lets you specify all sorts of options. For some specific options, such as adding trust anchors, special routines exist.
|
||||
:param val:
|
||||
value of the option.
|
||||
:returns: (int) 0 if OK, else error.
|
||||
"""
|
||||
return _unbound.ub_ctx_set_option(self,opt,val)
|
||||
#parameters: struct ub_ctx *,char *,char *,
|
||||
#retvals: int
|
||||
|
||||
def trustedkeys(self,fname):
|
||||
"""Add trust anchors to the given context.
|
||||
|
||||
Pass the name of a bind-style config file with trusted-keys{}.
|
||||
|
||||
:param fname:
|
||||
filename of file with bind-style config entries with trust anchors.
|
||||
:returns: (int) 0 if OK, else error.
|
||||
"""
|
||||
return _unbound.ub_ctx_trustedkeys(self,fname)
|
||||
#parameters: struct ub_ctx *,char *,
|
||||
#retvals: int
|
||||
#_UB_CTX_METHODS#
|
||||
|
||||
def zone_print(self):
|
||||
"""Print local zones using debougout"""
|
||||
_unbound.ub_ctx_print_local_zones(self)
|
||||
|
||||
def zone_add(self,zonename,zonetype):
|
||||
"""Add new local zone
|
||||
|
||||
:param zonename: zone domain name (e.g. myzone.)
|
||||
:param zonetype: type of the zone ("static",...)
|
||||
:returns: (int) 0 if OK, else error.
|
||||
"""
|
||||
return _unbound.ub_ctx_zone_add(self,zonename, zonetype)
|
||||
#parameters: struct ub_ctx *,char*, char*
|
||||
#retvals: int
|
||||
|
||||
def zone_remove(self,zonename):
|
||||
"""Remove local zone
|
||||
|
||||
If exists, removes local zone with all the RRs.
|
||||
|
||||
:param zonename: zone domain name
|
||||
:returns: (int) 0 if OK, else error.
|
||||
"""
|
||||
return _unbound.ub_ctx_zone_remove(self,zonename)
|
||||
#parameters: struct ub_ctx *,char*
|
||||
#retvals: int
|
||||
|
||||
def data_add(self,rrdata):
|
||||
"""Add new local RR data
|
||||
|
||||
:param rrdata: string, in zone-format on one line. [domainname] [TTL optional] [type] [class optional] [rdata contents]
|
||||
:returns: (int) 0 if OK, else error.
|
||||
|
||||
**Usage**
|
||||
The local data ...
|
||||
|
||||
::
|
||||
|
||||
>>> ctx = unbound.ub_ctx()
|
||||
>>> ctx.zone_add("mydomain.net.","static")
|
||||
0
|
||||
>>> status = ctx.data_add("test.mydomain.net. IN A 192.168.1.1")
|
||||
0
|
||||
>>> status, result = ctx.resolve("test.mydomain.net")
|
||||
>>> if status==0 and result.havedata:
|
||||
>>> print \"Result:\",result.data.address_list
|
||||
Result: ['192.168.1.1']
|
||||
|
||||
"""
|
||||
return _unbound.ub_ctx_data_add(self,rrdata)
|
||||
#parameters: struct ub_ctx *,char*
|
||||
#retvals: int
|
||||
|
||||
def data_remove(self,rrdata):
|
||||
"""Remove local RR data
|
||||
|
||||
If exists, remove resource record from local zone
|
||||
|
||||
:param rrdata: string, in zone-format on one line. [domainname] [TTL optional] [type] [class optional] [rdata contents]
|
||||
:returns: (int) 0 if OK, else error.
|
||||
"""
|
||||
return _unbound.ub_ctx_data_remove(self,rrdata)
|
||||
#parameters: struct ub_ctx *,char*
|
||||
#retvals: int
|
||||
|
||||
#UB_METHODS_#
|
||||
def cancel(self,async_id):
|
||||
"""Cancel an async query in progress.
|
||||
|
||||
Its callback will not be called.
|
||||
|
||||
:param async_id:
|
||||
which query to cancel.
|
||||
:returns: (int) 0 if OK, else error.
|
||||
"""
|
||||
return _unbound.ub_cancel(self,async_id)
|
||||
#parameters: struct ub_ctx *,int,
|
||||
#retvals: int
|
||||
|
||||
def get_fd(self):
|
||||
"""Get file descriptor.
|
||||
|
||||
Wait for it to become readable, at this point answers are returned from the asynchronous validating resolver. Then call the ub_process to continue processing. This routine works immediately after context creation, the fd does not change.
|
||||
|
||||
:returns: (int) -1 on error, or file descriptor to use select(2) with.
|
||||
"""
|
||||
return _unbound.ub_fd(self)
|
||||
#parameters: struct ub_ctx *,
|
||||
#retvals: int
|
||||
|
||||
def poll(self):
|
||||
"""Poll a context to see if it has any new results Do not poll in a loop, instead extract the fd below to poll for readiness, and then check, or wait using the wait routine.
|
||||
|
||||
:returns: (int) 0 if nothing to read, or nonzero if a result is available. If nonzero, call ctx_process() to do callbacks.
|
||||
"""
|
||||
return _unbound.ub_poll(self)
|
||||
#parameters: struct ub_ctx *,
|
||||
#retvals: int
|
||||
|
||||
def process(self):
|
||||
"""Call this routine to continue processing results from the validating resolver (when the fd becomes readable).
|
||||
|
||||
Will perform necessary callbacks.
|
||||
|
||||
:returns: (int) 0 if OK, else error.
|
||||
"""
|
||||
return _unbound.ub_process(self)
|
||||
#parameters: struct ub_ctx *,
|
||||
#retvals: int
|
||||
|
||||
def resolve(self,name,rrtype=RR_TYPE_A,rrclass=RR_CLASS_IN):
|
||||
"""Perform resolution and validation of the target name.
|
||||
|
||||
:param name:
|
||||
domain name in text format (a string or unicode string). IDN domain name have to be passed as a unicode string.
|
||||
:param rrtype:
|
||||
type of RR in host order (optional argument). Default value is RR_TYPE_A (A class).
|
||||
:param rrclass:
|
||||
class of RR in host order (optional argument). Default value is RR_CLASS_IN (for internet).
|
||||
:returns: * (int) 0 if OK, else error.
|
||||
* (:class:`ub_result`) the result data is returned in a newly allocated result structure. May be None on return, return value is set to an error in that case (out of memory).
|
||||
"""
|
||||
if isinstance(name, unicode): #probably IDN
|
||||
return _unbound.ub_resolve(self,idn2dname(name),rrtype,rrclass)
|
||||
else:
|
||||
return _unbound.ub_resolve(self,name,rrtype,rrclass)
|
||||
#parameters: struct ub_ctx *,char *,int,int,
|
||||
#retvals: int,struct ub_result **
|
||||
|
||||
def resolve_async(self,name,mydata,callback,rrtype=RR_TYPE_A,rrclass=RR_CLASS_IN):
|
||||
"""Perform resolution and validation of the target name.
|
||||
|
||||
Asynchronous, after a while, the callback will be called with your data and the result.
|
||||
If an error happens during processing, your callback will be called with error set to a nonzero value (and result==None).
|
||||
|
||||
:param name:
|
||||
domain name in text format (a string or unicode string). IDN domain name have to be passed as a unicode string.
|
||||
:param mydata:
|
||||
this data is your own data (you can pass arbitrary python object or None) which are passed on to the callback function.
|
||||
:param callback:
|
||||
call-back function which is called on completion of the resolution.
|
||||
:param rrtype:
|
||||
type of RR in host order (optional argument). Default value is RR_TYPE_A (A class).
|
||||
:param rrclass:
|
||||
class of RR in host order (optional argument). Default value is RR_CLASS_IN (for internet).
|
||||
:returns: * (int) 0 if OK, else error.
|
||||
* (int) async_id, an identifier number is returned for the query as it is in progress. It can be used to cancel the query.
|
||||
|
||||
**Call-back function:**
|
||||
The call-back function looks as the follows::
|
||||
|
||||
def call_back(mydata, status, result):
|
||||
pass
|
||||
|
||||
**Parameters:**
|
||||
* `mydata` - mydata object
|
||||
* `status` - 0 when a result has been found
|
||||
* `result` - the result structure. The result may be None, in that case err is set.
|
||||
|
||||
"""
|
||||
if isinstance(name, unicode): #probably IDN
|
||||
return _unbound._ub_resolve_async(self,idn2dname(name),rrtype,rrclass,mydata,callback)
|
||||
else:
|
||||
return _unbound._ub_resolve_async(self,name,rrtype,rrclass,mydata,callback)
|
||||
#parameters: struct ub_ctx *,char *,int,int,void *,ub_callback_t,
|
||||
#retvals: int, int
|
||||
|
||||
def wait(self):
|
||||
"""Wait for a context to finish with results.
|
||||
|
||||
Calls after the wait for you. After the wait, there are no more outstanding asynchronous queries.
|
||||
|
||||
:returns: (int) 0 if OK, else error.
|
||||
"""
|
||||
return _unbound.ub_wait(self)
|
||||
#parameters: struct ub_ctx *,
|
||||
#retvals: int
|
||||
|
||||
#_UB_METHODS#
|
||||
%}
|
||||
}
|
||||
|
||||
|
||||
// ================================================================================
|
||||
// ub_result - validation and resolution results
|
||||
// ================================================================================
|
||||
%nodefaultctor ub_result; //no default constructor & destructor
|
||||
%nodefaultdtor ub_result;
|
||||
|
||||
%delobject ub_resolve_free;
|
||||
%rename(_ub_resolve_free) ub_resolve_free;
|
||||
|
||||
%inline %{
|
||||
void ub_resolve_free_dbg (struct ub_result* r) {
|
||||
printf("******** UB_RESOLVE free 0x%lX ************\n", (long unsigned int)r);
|
||||
ub_resolve_free(r);
|
||||
}
|
||||
%}
|
||||
|
||||
%feature("docstring") ub_result "The validation and resolution results."
|
||||
|
||||
//ub_result.rcode
|
||||
%inline %{
|
||||
enum result_enum_rcode {
|
||||
RCODE_NOERROR = 0,
|
||||
RCODE_FORMERR = 1,
|
||||
RCODE_SERVFAIL = 2,
|
||||
RCODE_NXDOMAIN = 3,
|
||||
RCODE_NOTIMPL = 4,
|
||||
RCODE_REFUSED = 5,
|
||||
RCODE_YXDOMAIN = 6,
|
||||
RCODE_YXRRSET = 7,
|
||||
RCODE_NXRRSET = 8,
|
||||
RCODE_NOTAUTH = 9,
|
||||
RCODE_NOTZONE = 10
|
||||
};
|
||||
%}
|
||||
|
||||
%pythoncode %{
|
||||
class ub_data:
|
||||
"""Class which makes the resolution results accessible"""
|
||||
def __init__(self, data):
|
||||
"""Creates ub_data class
|
||||
:param data: a list of the result data in RAW format
|
||||
"""
|
||||
if data == None:
|
||||
raise Exception("ub_data init: No data")
|
||||
self.data = data
|
||||
|
||||
def __str__(self):
|
||||
"""Represents data as string"""
|
||||
return ';'.join([' '.join(map(lambda x:"%02X" % ord(x),a)) for a in self.data])
|
||||
|
||||
@staticmethod
|
||||
def dname2str(s, ofs=0, maxlen=0):
|
||||
"""Parses DNAME and produces a list of labels
|
||||
|
||||
:param ofs: where the conversion should start to parse data
|
||||
:param maxlen: maximum length (0 means parse to the end)
|
||||
:returns: list of labels (string)
|
||||
"""
|
||||
if not s:
|
||||
return []
|
||||
|
||||
res = []
|
||||
slen = len(s)
|
||||
if maxlen > 0:
|
||||
slen = min(slen, maxlen)
|
||||
|
||||
idx = ofs
|
||||
while (idx < slen):
|
||||
complen = ord(s[idx])
|
||||
res.append(s[idx+1:idx+1+complen])
|
||||
idx += complen + 1
|
||||
|
||||
return res
|
||||
|
||||
def as_raw_data(self):
|
||||
"""Returns a list of RAW strings"""
|
||||
return self.data
|
||||
|
||||
raw = property(as_raw_data, doc="Returns RAW data (a list of binary encoded strings). See :meth:`as_raw_data`")
|
||||
|
||||
def as_mx_list(self):
|
||||
"""Represents data as a list of MX records (query for RR_TYPE_MX)
|
||||
|
||||
:returns: list of tuples (priority, dname)
|
||||
"""
|
||||
return [(256*ord(rdf[0])+ord(rdf[1]),'.'.join([a for a in self.dname2str(rdf,2)])) for rdf in self.data]
|
||||
|
||||
mx_list = property(as_mx_list, doc="Returns a list of tuples containing priority and domain names. See :meth:`as_mx_list`")
|
||||
|
||||
def as_idn_mx_list(self):
|
||||
"""Represents data as a list of MX records (query for RR_TYPE_MX)
|
||||
|
||||
:returns: list of tuples (priority, unicode dname)
|
||||
"""
|
||||
return [(256*ord(rdf[0])+ord(rdf[1]),'.'.join([encodings.idna.ToUnicode(a) for a in self.dname2str(rdf,2)])) for rdf in self.data]
|
||||
|
||||
mx_list_idn = property(as_idn_mx_list, doc="Returns a list of tuples containing priority and IDN domain names. See :meth:`as_idn_mx_list`")
|
||||
|
||||
def as_address_list(self):
|
||||
"""Represents data as a list of IP addresses (query for RR_TYPE_PTR)
|
||||
|
||||
:returns: list of strings
|
||||
"""
|
||||
return ['.'.join(map(lambda x:str(ord(x)),a)) for a in self.data]
|
||||
|
||||
address_list = property(as_address_list, doc="Returns a list of IP addresses. See :meth:`as_address_list`")
|
||||
|
||||
def as_domain_list(self):
|
||||
"""Represents data as a list of domain names (query for RR_TYPE_A)
|
||||
|
||||
:returns: list of strings
|
||||
"""
|
||||
return map(lambda x:'.'.join(self.dname2str(x)), self.data)
|
||||
|
||||
domain_list = property(as_domain_list, doc="Returns a list of domain names. See :meth:`as_domain_list`")
|
||||
|
||||
def as_idn_domain_list(self):
|
||||
"""Represents data as a list of unicode domain names (query for RR_TYPE_A)
|
||||
|
||||
:returns: list of strings
|
||||
"""
|
||||
return map(lambda x: '.'.join([encodings.idna.ToUnicode(a) for a in self.dname2str(x)]), self.data)
|
||||
|
||||
domain_list_idn = property(as_idn_domain_list, doc="Returns a list of IDN domain names. See :meth:`as_idn_domain_list`")
|
||||
%}
|
||||
|
||||
%extend ub_result
|
||||
{
|
||||
|
||||
%rename(_data) data;
|
||||
|
||||
PyObject* _ub_result_data(struct ub_result* result) {
|
||||
PyObject *list;
|
||||
int i,j,cnt;
|
||||
if ((result == 0) || (!result->havedata) || (result->data == 0))
|
||||
return Py_None;
|
||||
|
||||
for (cnt=0,i=0;;i++,cnt++)
|
||||
if (result->data[i] == 0)
|
||||
break;
|
||||
|
||||
list = PyList_New(cnt);
|
||||
for (i=0;i<cnt;i++)
|
||||
PyList_SetItem(list, i, PyString_FromStringAndSize(result->data[i],result->len[i]));
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
%pythoncode %{
|
||||
def __init__(self):
|
||||
raise Exception("This class can't be created directly.")
|
||||
|
||||
#__swig_destroy__ = _unbound.ub_resolve_free_dbg
|
||||
__swig_destroy__ = _unbound._ub_resolve_free
|
||||
|
||||
#havedata = property(_unbound.ub_result_havedata_get, _unbound.ub_result_havedata_set, "Havedata property")
|
||||
|
||||
rcode2str = {RCODE_NOERROR:'no error', RCODE_FORMERR:'form error', RCODE_SERVFAIL:'serv fail', RCODE_NXDOMAIN:'nx domain', RCODE_NOTIMPL:'not implemented', RCODE_REFUSED:'refused', RCODE_YXDOMAIN:'yxdomain', RCODE_YXRRSET:'yxrrset', RCODE_NXRRSET:'nxrrset', RCODE_NOTAUTH:'not auth', RCODE_NOTZONE:'not zone'}
|
||||
|
||||
def _get_rcode_str(self):
|
||||
"""Returns rcode in display representation form
|
||||
|
||||
:returns: string
|
||||
"""
|
||||
return self.rcode2str[self.rcode]
|
||||
|
||||
__swig_getmethods__["rcode_str"] = _get_rcode_str
|
||||
if _newclass:rcode_str = _swig_property(_get_rcode_str)
|
||||
|
||||
def _get_raw_data(self):
|
||||
"""Result data, a list of network order DNS rdata items.
|
||||
|
||||
Data are represented as a list of strings. To decode RAW data to the list of IP addresses use :attr:`data` attribute which returns an :class:`ub_data` instance containing conversion function.
|
||||
"""
|
||||
return self._ub_result_data(self)
|
||||
|
||||
__swig_getmethods__["rawdata"] = _get_raw_data
|
||||
rawdata = property(_get_raw_data, doc="Returns raw data, a list of rdata items. To decode RAW data use the :attr:`data` attribute which returns an instance of :class:`ub_data` containing the conversion functions.")
|
||||
|
||||
def _get_data(self):
|
||||
if not self.havedata: return None
|
||||
return ub_data(self._ub_result_data(self))
|
||||
|
||||
__swig_getmethods__["data"] = _get_data
|
||||
data = property(_get_data, doc="Returns :class:`ub_data` instance containing various decoding functions or None")
|
||||
|
||||
%}
|
||||
|
||||
}
|
||||
|
||||
%exception ub_resolve
|
||||
%{
|
||||
//printf("resolve_start(%lX)\n",(long unsigned int)arg1);
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
$function
|
||||
Py_END_ALLOW_THREADS
|
||||
//printf("resolve_stop()\n");
|
||||
%}
|
||||
|
||||
%include "libunbound/unbound.h"
|
||||
|
||||
%inline %{
|
||||
//SWIG will see the ub_ctx as a class
|
||||
struct ub_ctx {
|
||||
};
|
||||
%}
|
||||
|
||||
//ub_ctx_debugout void* parameter correction
|
||||
int ub_ctx_debugout(struct ub_ctx* ctx, FILE* out);
|
||||
|
||||
// ================================================================================
|
||||
// ub_resolve_async - perform asynchronous resolution and validation
|
||||
// ================================================================================
|
||||
|
||||
%typemap(in,numinputs=0,noblock=1) (int* async_id)
|
||||
{
|
||||
int asyncid = -1;
|
||||
$1 = &asyncid;
|
||||
}
|
||||
|
||||
%apply PyObject* {void* mydata}
|
||||
|
||||
/* result generation */
|
||||
%typemap(argout,noblock=1) (int* async_id)
|
||||
{
|
||||
PyObject* tuple;
|
||||
tuple = PyTuple_New(2);
|
||||
PyTuple_SetItem(tuple, 0, $result);
|
||||
PyTuple_SetItem(tuple, 1, SWIG_From_int(asyncid));
|
||||
$result = tuple;
|
||||
}
|
||||
|
||||
// Grab a Python function object as a Python object.
|
||||
%typemap(in) (PyObject *pyfunc) {
|
||||
if (!PyCallable_Check($input))
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError, "Need a callable object!");
|
||||
return NULL;
|
||||
}
|
||||
$1 = $input;
|
||||
}
|
||||
|
||||
// Python callback workaround
|
||||
int _ub_resolve_async(struct ub_ctx* ctx, char* name, int rrtype, int rrclass, void* mydata, PyObject *pyfunc, int* async_id);
|
||||
|
||||
%{
|
||||
struct cb_data {
|
||||
PyObject* data;
|
||||
PyObject* func;
|
||||
};
|
||||
|
||||
static void PythonCallBack(void* iddata, int status, struct ub_result* result)
|
||||
{
|
||||
PyObject *func, *arglist;
|
||||
PyObject *fresult;
|
||||
struct cb_data* id;
|
||||
id = (struct cb_data*) iddata;
|
||||
arglist = Py_BuildValue("(OiO)",id->data,status, SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ub_result, 0 | 0 )); // Build argument list
|
||||
fresult = PyEval_CallObject(id->func,arglist); // Call Python
|
||||
Py_DECREF(id->func);
|
||||
Py_DECREF(id->data);
|
||||
free(id);
|
||||
ub_resolve_free(result); //free ub_result
|
||||
//ub_resolve_free_dbg(result); //free ub_result
|
||||
Py_DECREF(arglist); // Trash arglist
|
||||
Py_XDECREF(fresult);
|
||||
}
|
||||
|
||||
int _ub_resolve_async(struct ub_ctx* ctx, char* name, int rrtype, int rrclass, PyObject* mydata, PyObject *pyfunc, int* async_id) {
|
||||
struct cb_data* id;
|
||||
id = (struct cb_data*) malloc(sizeof(struct cb_data));
|
||||
id->data = mydata;
|
||||
id->func = pyfunc;
|
||||
|
||||
int i = ub_resolve_async(ctx,name,rrtype,rrclass, (void *) id, PythonCallBack, async_id);
|
||||
Py_INCREF(mydata);
|
||||
Py_INCREF(pyfunc);
|
||||
return i;
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
%pythoncode %{
|
||||
ub_resolve_async = _unbound._ub_resolve_async
|
||||
|
||||
def reverse(domain):
|
||||
"""Reverse domain name
|
||||
|
||||
Usable for reverse lookups when the IP address should be reversed
|
||||
"""
|
||||
return '.'.join([a for a in domain.split(".")][::-1])
|
||||
|
||||
def idn2dname(idnname):
|
||||
"""Converts domain name in IDN format to canonic domain name
|
||||
|
||||
:param idnname: (unicode string) IDN name
|
||||
:returns: (string) domain name
|
||||
"""
|
||||
return '.'.join([encodings.idna.ToASCII(a) for a in idnname.split('.')])
|
||||
|
||||
def dname2idn(name):
|
||||
"""Converts canonic domain name in IDN format to unicode string
|
||||
|
||||
:param name: (string) domain name
|
||||
:returns: (unicode string) domain name
|
||||
"""
|
||||
return '.'.join([encodings.idna.ToUnicode(a) for a in name.split('.')])
|
||||
|
||||
%}
|
||||
|
5776
contrib/python/libunbound_wrap.c
Normal file
5776
contrib/python/libunbound_wrap.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -11,6 +11,6 @@ At NLnet Labs, Jelte Jansen, Mark Santcroos and Matthijs Mekking
|
||||
reviewed the unbound C sources.
|
||||
|
||||
Jakob Schlyter - for advice on secure settings, random numbers and blacklists.
|
||||
|
||||
Ondřej Surý - running coverity analysis tool on 0.9 dev version.
|
||||
Alexander Gall - multihomed, anycast testing of unbound resolver server.
|
||||
Zdenek Vasicek and Marek Vavrusa - python module.
|
||||
|
@ -1,3 +1,7 @@
|
||||
25 March 2009: Wouter
|
||||
- initial import of the python contribution from Zdenek Vasicek and
|
||||
Marek Vavrusa.
|
||||
|
||||
24 March 2009: Wouter
|
||||
- more neat configure.ac. Removed duplicate config.h includes.
|
||||
- neater config.h.in.
|
||||
|
@ -386,6 +386,11 @@ server:
|
||||
# you need to do the reverse notation yourself.
|
||||
# local-data-ptr: "192.0.2.3 www.example.com"
|
||||
|
||||
# Python config section, list python in the module-config string to enable.
|
||||
python:
|
||||
# Script file to load
|
||||
python-script: "@UNBOUND_SHARE_DIR@/ubmodule-tst.py"
|
||||
|
||||
# Remote control config section.
|
||||
remote-control:
|
||||
# Enable remote control with unbound-control(8) here.
|
||||
|
@ -913,7 +913,7 @@ MAN_LINKS = NO
|
||||
# generate an XML file that captures the structure of
|
||||
# the code including all documentation.
|
||||
|
||||
GENERATE_XML = NO
|
||||
GENERATE_XML = YES
|
||||
|
||||
# The XML_OUTPUT tag is used to specify where the XML pages will be put.
|
||||
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
|
||||
|
@ -906,3 +906,123 @@ ub_ctx_hosts(struct ub_ctx* ctx, char* fname)
|
||||
fclose(in);
|
||||
return UB_NOERROR;
|
||||
}
|
||||
|
||||
static int ub_ctx_check_finalize(struct ub_ctx* ctx)
|
||||
{
|
||||
int res = 0;
|
||||
lock_basic_lock(&ctx->cfglock);
|
||||
if (!ctx->finalized) {
|
||||
res = context_finalize(ctx);
|
||||
}
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
return res;
|
||||
}
|
||||
|
||||
/** Print local zones and RR data */
|
||||
int ub_ctx_print_local_zones(struct ub_ctx* ctx)
|
||||
{
|
||||
int res = ub_ctx_check_finalize(ctx);
|
||||
if (res) return res;
|
||||
|
||||
local_zones_print(ctx->local_zones);
|
||||
|
||||
return UB_NOERROR;
|
||||
}
|
||||
|
||||
/** Add a new zone */
|
||||
int ub_ctx_zone_add(struct ub_ctx* ctx, char *zone_name, char *zone_type)
|
||||
{
|
||||
enum localzone_type t;
|
||||
struct local_zone* z;
|
||||
uint8_t* nm;
|
||||
int nmlabs;
|
||||
size_t nmlen;
|
||||
|
||||
int res = ub_ctx_check_finalize(ctx);
|
||||
if (res) return res;
|
||||
|
||||
if(!local_zone_str2type(zone_type, &t)) {
|
||||
return UB_SYNTAX;
|
||||
}
|
||||
|
||||
if(!parse_dname(zone_name, &nm, &nmlen, &nmlabs)) {
|
||||
return UB_SYNTAX;
|
||||
}
|
||||
|
||||
lock_quick_lock(&ctx->local_zones->lock);
|
||||
if((z=local_zones_find(ctx->local_zones, nm, nmlen, nmlabs, LDNS_RR_CLASS_IN))) {
|
||||
/* already present in tree */
|
||||
lock_rw_wrlock(&z->lock);
|
||||
z->type = t; /* update type anyway */
|
||||
lock_rw_unlock(&z->lock);
|
||||
free(nm);
|
||||
lock_quick_unlock(&ctx->local_zones->lock);
|
||||
return UB_NOERROR;
|
||||
}
|
||||
if(!local_zones_add_zone(ctx->local_zones, nm, nmlen, nmlabs, LDNS_RR_CLASS_IN, t)) {
|
||||
lock_quick_unlock(&ctx->local_zones->lock);
|
||||
return UB_NOMEM;
|
||||
}
|
||||
lock_quick_unlock(&ctx->local_zones->lock);
|
||||
return UB_NOERROR;
|
||||
}
|
||||
|
||||
/** Remove zone */
|
||||
int ub_ctx_zone_remove(struct ub_ctx* ctx, char *zone_name)
|
||||
{
|
||||
struct local_zone* z;
|
||||
uint8_t* nm;
|
||||
int nmlabs;
|
||||
size_t nmlen;
|
||||
|
||||
int res = ub_ctx_check_finalize(ctx);
|
||||
if (res) return res;
|
||||
|
||||
if(!parse_dname(zone_name, &nm, &nmlen, &nmlabs)) {
|
||||
return UB_SYNTAX;
|
||||
}
|
||||
|
||||
lock_quick_lock(&ctx->local_zones->lock);
|
||||
if((z=local_zones_find(ctx->local_zones, nm, nmlen, nmlabs, LDNS_RR_CLASS_IN))) {
|
||||
/* present in tree */
|
||||
local_zones_del_zone(ctx->local_zones, z);
|
||||
}
|
||||
free(nm);
|
||||
lock_quick_unlock(&ctx->local_zones->lock);
|
||||
return UB_NOERROR;
|
||||
}
|
||||
|
||||
/** Add new RR data */
|
||||
int ub_ctx_data_add(struct ub_ctx* ctx, char *data)
|
||||
{
|
||||
ldns_buffer* buf;
|
||||
int res = ub_ctx_check_finalize(ctx);
|
||||
if (res) return res;
|
||||
|
||||
lock_basic_lock(&ctx->cfglock);
|
||||
buf = ldns_buffer_new(ctx->env->cfg->msg_buffer_size);
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
|
||||
res = local_zones_add_RR(ctx->local_zones, data, buf);
|
||||
|
||||
ldns_buffer_free(buf);
|
||||
return (!res) ? UB_NOMEM : UB_NOERROR;
|
||||
}
|
||||
|
||||
/* Remove RR data */
|
||||
int ub_ctx_data_remove(struct ub_ctx* ctx, char *data)
|
||||
{
|
||||
uint8_t* nm;
|
||||
int nmlabs;
|
||||
size_t nmlen;
|
||||
int res = ub_ctx_check_finalize(ctx);
|
||||
if (res) return res;
|
||||
|
||||
if(!parse_dname(data, &nm, &nmlen, &nmlabs))
|
||||
return UB_SYNTAX;
|
||||
|
||||
local_zones_del_data(ctx->local_zones, nm, nmlen, nmlabs, LDNS_RR_CLASS_IN);
|
||||
|
||||
free(nm);
|
||||
return UB_NOERROR;
|
||||
}
|
||||
|
@ -20,3 +20,8 @@ ub_resolve_async
|
||||
ub_cancel
|
||||
ub_resolve_free
|
||||
ub_strerror
|
||||
ub_ctx_print_local_zones
|
||||
ub_ctx_zone_add
|
||||
ub_ctx_zone_remove
|
||||
ub_ctx_data_add
|
||||
ub_ctx_data_remove
|
||||
|
@ -470,4 +470,10 @@ void ub_resolve_free(struct ub_result* result);
|
||||
*/
|
||||
const char* ub_strerror(int err);
|
||||
|
||||
int ub_ctx_print_local_zones(struct ub_ctx* ctx);
|
||||
int ub_ctx_zone_add(struct ub_ctx* ctx, char *zone_name, char *zone_type);
|
||||
int ub_ctx_zone_remove(struct ub_ctx* ctx, char *zone_name);
|
||||
int ub_ctx_data_add(struct ub_ctx* ctx, char *data);
|
||||
int ub_ctx_data_remove(struct ub_ctx* ctx, char *data);
|
||||
|
||||
#endif /* _UB_UNBOUND_H */
|
||||
|
28
pythonmod/LICENSE
Normal file
28
pythonmod/LICENSE
Normal file
@ -0,0 +1,28 @@
|
||||
Copyright (c) 2009, Zdenek Vasicek (vasicek AT fit.vutbr.cz)
|
||||
Marek Vavrusa (xvavru00 AT stud.fit.vutbr.cz)
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the organization 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 OWNER 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.
|
58
pythonmod/Makefile
Normal file
58
pythonmod/Makefile
Normal file
@ -0,0 +1,58 @@
|
||||
# Makefile: tests unbound python module (please edit SCRIPT variable)
|
||||
#
|
||||
# Copyright (c) 2009, Zdenek Vasicek (vasicek AT fit.vutbr.cz)
|
||||
# Marek Vavrusa (xvavru00 AT stud.fit.vutbr.cz)
|
||||
#
|
||||
# This software is open source.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# * Neither the name of the organization 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 REGENTS 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.
|
||||
|
||||
SUEXEC = sudo
|
||||
UNBOUND = ../unbound
|
||||
SCRIPT = ./test-dict.conf
|
||||
|
||||
UNBOUND_OPTS = -dv -c $(SCRIPT)
|
||||
|
||||
.PHONY: test sudo suexec doc
|
||||
|
||||
all: test
|
||||
|
||||
$(UNBOUND):
|
||||
make -C ..
|
||||
|
||||
test: $(UNBOUND)
|
||||
$(UNBOUND) $(UNBOUND_OPTS)
|
||||
|
||||
sudo: $(UNBOUND)
|
||||
sudo $(UNBOUND) $(UNBOUND_OPTS)
|
||||
|
||||
suexec: $(UNBOUND)
|
||||
su -c "$(UNBOUND) $(UNBOUND_OPTS)"
|
||||
|
||||
doc:
|
||||
$(MAKE) -C doc html
|
73
pythonmod/doc/Makefile
Normal file
73
pythonmod/doc/Makefile
Normal file
@ -0,0 +1,73 @@
|
||||
# Makefile for Sphinx documentation
|
||||
#
|
||||
|
||||
# You can set these variables from the command line.
|
||||
SPHINXOPTS =
|
||||
SPHINXBUILD = sphinx-build
|
||||
PAPER =
|
||||
|
||||
# Internal variables.
|
||||
PAPEROPT_a4 = -D latex_paper_size=a4
|
||||
PAPEROPT_letter = -D latex_paper_size=letter
|
||||
ALLSPHINXOPTS = -d build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
|
||||
|
||||
.PHONY: env help clean html web pickle htmlhelp latex changes linkcheck
|
||||
|
||||
help:
|
||||
@echo "Please use \`make <target>' where <target> is one of"
|
||||
@echo " html to make standalone HTML files"
|
||||
@echo " pickle to make pickle files (usable by e.g. sphinx-web)"
|
||||
@echo " htmlhelp to make HTML files and a HTML help project"
|
||||
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
|
||||
@echo " changes to make an overview over all changed/added/deprecated items"
|
||||
@echo " linkcheck to check all external links for integrity"
|
||||
|
||||
clean:
|
||||
-rm -rf build/*
|
||||
|
||||
env:
|
||||
|
||||
html: env
|
||||
mkdir -p build/html build/doctrees
|
||||
LD_LIBRARY_PATH=../../.libs:../../ldns-src/lib $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) build/html
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in build/html."
|
||||
|
||||
pickle: env
|
||||
mkdir -p build/pickle build/doctrees
|
||||
LD_LIBRARY_PATH=../../.libs:../../ldns-src/lib $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) build/pickle
|
||||
@echo
|
||||
@echo "Build finished; now you can process the pickle files or run"
|
||||
@echo " sphinx-web build/pickle"
|
||||
@echo "to start the sphinx-web server."
|
||||
|
||||
web: pickle
|
||||
|
||||
htmlhelp: env
|
||||
mkdir -p build/htmlhelp build/doctrees
|
||||
LD_LIBRARY_PATH=../../.libs:../../ldns-src/lib $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) build/htmlhelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run HTML Help Workshop with the" \
|
||||
".hhp project file in build/htmlhelp."
|
||||
|
||||
latex: env
|
||||
mkdir -p build/latex build/doctrees
|
||||
LD_LIBRARY_PATH=../../.libs:../../ldns-src/lib $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) build/latex
|
||||
@echo
|
||||
@echo "Build finished; the LaTeX files are in build/latex."
|
||||
@echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
|
||||
"run these through (pdf)latex."
|
||||
|
||||
changes: env
|
||||
mkdir -p build/changes build/doctrees
|
||||
LD_LIBRARY_PATH=../../.libs:../../ldns-src/lib $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) build/changes
|
||||
@echo
|
||||
@echo "The overview file is in build/changes."
|
||||
|
||||
linkcheck: env
|
||||
mkdir -p build/linkcheck build/doctrees
|
||||
LD_LIBRARY_PATH=../../.libs:../../ldns-src/lib $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) build/linkcheck
|
||||
@echo
|
||||
@echo "Link check complete; look for any errors in the above output " \
|
||||
"or in build/linkcheck/output.txt."
|
||||
|
179
pythonmod/doc/source/conf.py
Normal file
179
pythonmod/doc/source/conf.py
Normal file
@ -0,0 +1,179 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Unbound scripting interface documentation build configuration file
|
||||
#
|
||||
# This file is execfile()d with the current directory set to its containing dir.
|
||||
#
|
||||
# The contents of this file are pickled, so don't put values in the namespace
|
||||
# that aren't pickleable (module imports are okay, they're removed automatically).
|
||||
#
|
||||
# All configuration values have a default value; values that are commented out
|
||||
# serve to show the default value.
|
||||
|
||||
import sys, os
|
||||
|
||||
# If your extensions are in another directory, add it here. If the directory
|
||||
# is relative to the documentation root, use os.path.abspath to make it
|
||||
# absolute, like shown here.
|
||||
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__),'../..')))
|
||||
#print sys.path
|
||||
|
||||
# General configuration
|
||||
# ---------------------
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be extensions
|
||||
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
||||
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest']
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
# The suffix of source filenames.
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# General substitutions.
|
||||
project = 'Unbound scriptable interface'
|
||||
copyright = '2009, Zdenek Vasicek, Marek Vavrusa'
|
||||
|
||||
# The default replacements for |version| and |release|, also used in various
|
||||
# other places throughout the built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '1.0'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '1.0.0'
|
||||
|
||||
# There are two options for replacing |today|: either, you set today to some
|
||||
# non-false value, then it is used:
|
||||
#today = ''
|
||||
# Else, today_fmt is used as the format for a strftime call.
|
||||
today_fmt = '%B %d, %Y'
|
||||
|
||||
# List of documents that shouldn't be included in the build.
|
||||
#unused_docs = []
|
||||
|
||||
# List of directories, relative to source directories, that shouldn't be searched
|
||||
# for source files.
|
||||
#exclude_dirs = []
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all documents.
|
||||
#default_role = None
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
#add_function_parentheses = True
|
||||
|
||||
# If true, the current module name will be prepended to all description
|
||||
# unit titles (such as .. function::).
|
||||
#add_module_names = True
|
||||
|
||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||
# output. They are ignored by default.
|
||||
#show_authors = False
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
|
||||
# Options for HTML output
|
||||
# -----------------------
|
||||
|
||||
# The style sheet to use for HTML and HTML Help pages. A file of that name
|
||||
# must exist either in Sphinx' static/ path, or in one of the custom paths
|
||||
# given in html_static_path.
|
||||
html_style = 'default.css'
|
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to
|
||||
# "<project> v<release> documentation".
|
||||
#html_title = None
|
||||
|
||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||
#html_short_title = None
|
||||
|
||||
# The name of an image file (within the static path) to place at the top of
|
||||
# the sidebar.
|
||||
#html_logo = None
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
#html_favicon = None
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static']
|
||||
|
||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||
# using the given strftime format.
|
||||
html_last_updated_fmt = '%b %d, %Y'
|
||||
|
||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||
# typographically correct entities.
|
||||
#html_use_smartypants = True
|
||||
|
||||
# Custom sidebar templates, maps document names to template names.
|
||||
#html_sidebars = {}
|
||||
|
||||
# Additional templates that should be rendered to pages, maps page names to
|
||||
# template names.
|
||||
#html_additional_pages = {}
|
||||
|
||||
# If false, no module index is generated.
|
||||
html_use_modindex = False
|
||||
|
||||
# If false, no index is generated.
|
||||
html_use_index = True
|
||||
|
||||
# If true, the index is split into individual pages for each letter.
|
||||
#html_split_index = False
|
||||
|
||||
# If true, the reST sources are included in the HTML build as _sources/<name>.
|
||||
html_copy_source = False
|
||||
|
||||
# If true, an OpenSearch description file will be output, and all pages will
|
||||
# contain a <link> tag referring to it. The value of this option must be the
|
||||
# base URL from which the finished HTML is served.
|
||||
#html_use_opensearch = ''
|
||||
|
||||
# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
|
||||
#html_file_suffix = ''
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'unbound_interface'
|
||||
|
||||
|
||||
# Options for LaTeX output
|
||||
# ------------------------
|
||||
|
||||
# The paper size ('letter' or 'a4').
|
||||
#latex_paper_size = 'letter'
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#latex_font_size = '10pt'
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title, author, document class [howto/manual]).
|
||||
latex_documents = [
|
||||
('index', 'Unbound_interface.tex', 'Unbound scriptable interface',
|
||||
'Zdenek Vasicek, Marek Vavrusa', 'manual'),
|
||||
]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
# the title page.
|
||||
#latex_logo = None
|
||||
|
||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||
# not chapters.
|
||||
#latex_use_parts = False
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#latex_preamble = ''
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#latex_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#latex_use_modindex = True
|
37
pythonmod/doc/source/examples/example0-1.py
Normal file
37
pythonmod/doc/source/examples/example0-1.py
Normal file
@ -0,0 +1,37 @@
|
||||
|
||||
print mod_env.fname # Print module script name
|
||||
mod_env.data = "test" # Store global module data
|
||||
|
||||
def init(id, cfg):
|
||||
log_info("pythonmod: init called, module id is %d port: %d script: %s" % (id, cfg.port, cfg.python_script))
|
||||
return True
|
||||
|
||||
def deinit(id):
|
||||
log_info("pythonmod: deinit called, module id is %d" % id)
|
||||
return True
|
||||
|
||||
def inform_super(id, qstate, superqstate, qdata):
|
||||
return True
|
||||
|
||||
def operate(id, event, qstate, qdata):
|
||||
log_info("pythonmod: operate called, id: %d, event:%s" % (id, strmodulevent(event)))
|
||||
|
||||
if event == MODULE_EVENT_NEW:
|
||||
qstate.ext_state[id] = MODULE_WAIT_MODULE
|
||||
return True
|
||||
|
||||
if event == MODULE_EVENT_MODDONE:
|
||||
log_info("pythonmod: module we are waiting for is done")
|
||||
qstate.ext_state[id] = MODULE_FINISHED
|
||||
return True
|
||||
|
||||
if event == MODULE_EVENT_PASS:
|
||||
log_info("pythonmod: event_pass")
|
||||
qstate.ext_state[id] = MODULE_ERROR
|
||||
return True
|
||||
|
||||
log_err("pythonmod: BAD event")
|
||||
qstate.ext_state[id] = MODULE_ERROR
|
||||
return True
|
||||
|
||||
log_info("pythonmod: script loaded.")
|
129
pythonmod/doc/source/examples/example0.rst
Normal file
129
pythonmod/doc/source/examples/example0.rst
Normal file
@ -0,0 +1,129 @@
|
||||
.. _example_handler:
|
||||
|
||||
Fundamentals
|
||||
================
|
||||
|
||||
This basic example shows how to create simple python module which will pass on the requests to the iterator.
|
||||
|
||||
How to enable python module
|
||||
----------------------------
|
||||
If you look into unbound configuration file, you can find the option `module-config` which specifies the names and the order of modules to be used.
|
||||
Example configuration::
|
||||
|
||||
module-config: "validator python iterator"
|
||||
|
||||
As soon as the DNS query arrives, Unbound calls modules starting from leftmost - the validator *(it is the first module on the list)*.
|
||||
The validator does not know the answer *(it can only validate)*, thus it will pass on the event to the next module.
|
||||
Next module is python which can
|
||||
|
||||
a) generate answer *(response)*
|
||||
When python module generates the response unbound calls validator. Validator grabs the answer and determines the security flag.
|
||||
|
||||
b) pass on the event to the iterator.
|
||||
When iterator resolves the query, Unbound informs python module (event :data:`module_event_moddone`). In the end, when the python module is done, validator is called.
|
||||
|
||||
Note that the python module is called with :data:`module_event_pass` event, because new DNS event was already handled by validator.
|
||||
|
||||
Another situation occurs when we use the following configuration::
|
||||
|
||||
module-config: "python validator iterator"
|
||||
|
||||
Python module is the first module here, so it's invoked with :data:`module_event_new` event *(new query)*.
|
||||
|
||||
On Python module initialization, module loads script from `python-script` option::
|
||||
|
||||
python-script: "/unbound/test/ubmodule.py"
|
||||
|
||||
Simple python module step by step
|
||||
---------------------------------
|
||||
|
||||
Script file must contain four compulsory functions:
|
||||
|
||||
.. function:: init(id, cfg)
|
||||
|
||||
Initialize module internals, like database etc.
|
||||
Called just once on module load.
|
||||
|
||||
:param id: module identifier (integer)
|
||||
:param cfg: :class:`config_file` configuration structure
|
||||
|
||||
::
|
||||
|
||||
def init(id, cfg):
|
||||
log_info("pythonmod: init called, module id is %d port: %d script: %s" % (id, cfg.port, cfg.python_script))
|
||||
return True
|
||||
|
||||
|
||||
.. function:: deinit(id)
|
||||
|
||||
Deinitialize module internals.
|
||||
Called just once on module unload.
|
||||
|
||||
:param id: module identifier (integer)
|
||||
|
||||
::
|
||||
|
||||
def deinit(id):
|
||||
log_info("pythonmod: deinit called, module id is %d" % id)
|
||||
return True
|
||||
|
||||
|
||||
.. function:: inform_super(id, qstate, superqstate, qdata)
|
||||
|
||||
Inform super querystate about the results from this subquerystate.
|
||||
Is called when the querystate is finished.
|
||||
|
||||
:param id: module identifier (integer)
|
||||
:param qstate: :class:`module_qstate` Query state
|
||||
:param superqstate: :class:`pythonmod_qstate` Mesh state
|
||||
:param qdata: :class:`query_info` Query data
|
||||
|
||||
::
|
||||
|
||||
def inform_super(id, qstate, superqstate, qdata):
|
||||
return True
|
||||
|
||||
|
||||
|
||||
.. function:: operate(id, event, qstate, qdata)
|
||||
|
||||
Perform action on pending query. Accepts a new query, or work on pending query.
|
||||
|
||||
You have to set qstate.ext_state on exit.
|
||||
The state informs unbound about result and controls the following states.
|
||||
|
||||
:param id: module identifier (integer)
|
||||
:param qstate: :class:`module_qstate` query state structure
|
||||
:param qdata: :class:`query_info` per query data, here you can store your own data
|
||||
|
||||
::
|
||||
|
||||
def operate(id, event, qstate, qdata):
|
||||
log_info("pythonmod: operate called, id: %d, event:%s" % (id, strmodulevent(event)))
|
||||
if event == MODULE_EVENT_NEW:
|
||||
qstate.ext_state[id] = MODULE_WAIT_MODULE
|
||||
return True
|
||||
|
||||
if event == MODULE_EVENT_MODDONE:
|
||||
qstate.ext_state[id] = MODULE_FINISHED
|
||||
return True
|
||||
|
||||
if event == MODULE_EVENT_PASS:
|
||||
qstate.ext_state[id] = MODULE_ERROR
|
||||
return True
|
||||
|
||||
log_err("pythonmod: BAD event")
|
||||
qstate.ext_state[id] = MODULE_ERROR
|
||||
return True
|
||||
|
||||
|
||||
Complete source code
|
||||
--------------------
|
||||
|
||||
.. literalinclude:: example0-1.py
|
||||
:language: python
|
||||
|
||||
As you can see, the source code is much more flexible in contrast to C modules.
|
||||
Moreover, compulsory functions called on appropriate module events allows to handle almost
|
||||
anything from web control to query analysis.
|
||||
|
42
pythonmod/doc/source/examples/example1.rst
Normal file
42
pythonmod/doc/source/examples/example1.rst
Normal file
@ -0,0 +1,42 @@
|
||||
.. _log_handler:
|
||||
|
||||
Packet logger
|
||||
=========================
|
||||
|
||||
This example shows how to log and print details about query and response.
|
||||
As soon as the ``iterator`` has finished (event is :data:`module_event_moddone`), ``qstate.return_msg`` contains response packet or ``None``.
|
||||
This packet will be send to a client that asked for it.
|
||||
|
||||
Complete source code
|
||||
--------------------
|
||||
|
||||
.. literalinclude:: ../../../examples/log.py
|
||||
:language: python
|
||||
|
||||
Testing
|
||||
------------------
|
||||
Run the unbound server:
|
||||
|
||||
``root@localhost>unbound -dv -c ./test-log.conf``
|
||||
|
||||
In case you use own configuration file, don't forget to enable python module: ``module-config: "validator python iterator"`` and use valid script path: ``python-script: "./examples/log.py"``.
|
||||
|
||||
Example of output::
|
||||
|
||||
[1231790168] unbound[7941:0] info: response for <f.gtld-servers.NET. AAAA IN>
|
||||
[1231790168] unbound[7941:0] info: reply from <gtld-servers.NET.> 192.5.6.31#53
|
||||
[1231790168] unbound[7941:0] info: query response was ANSWER
|
||||
[1231790168] unbound[7941:0] info: pythonmod: operate called, id: 1, event:module_event_moddone
|
||||
----------------------------------------------------------------------------------------------------
|
||||
Query: f.gtld-servers.NET., type: AAAA (28), class: IN (1)
|
||||
----------------------------------------------------------------------------------------------------
|
||||
Return reply :: flags: 8080, QDcount: 1, Security:0, TTL=86400
|
||||
qinfo :: qname: ['f', 'gtld-servers', 'NET', ''] f.gtld-servers.NET., qtype: AAAA, qclass: IN
|
||||
Reply:
|
||||
0 : ['gtld-servers', 'NET', ''] gtld-servers.NET. flags: 0000 type: SOA (6) class: IN (1)
|
||||
0 : TTL= 86400
|
||||
0x00 | 00 3A 02 41 32 05 4E 53 54 4C 44 03 43 4F 4D 00 05 | . : . A 2 . N S T L D . C O M . .
|
||||
0x10 | 05 6E 73 74 6C 64 0C 76 65 72 69 73 69 67 6E 2D 67 | . n s t l d . v e r i s i g n - g
|
||||
0x20 | 67 72 73 03 43 4F 4D 00 77 74 2D 64 00 00 0E 10 00 | g r s . C O M . w t - d . . . . .
|
||||
0x30 | 00 00 03 84 00 12 75 00 00 01 51 80 | . . . . . . u . . . Q .
|
||||
|
46
pythonmod/doc/source/examples/example2.rst
Normal file
46
pythonmod/doc/source/examples/example2.rst
Normal file
@ -0,0 +1,46 @@
|
||||
Response generation
|
||||
=====================
|
||||
|
||||
This example shows how to handle queries and generate response packet.
|
||||
|
||||
.. note::
|
||||
If the python module is the first module and validator module is enabled (``module-config: "python validator iterator"``),
|
||||
a return_msg security flag has to be set at least to 2. Leaving security flag untouched causes that the
|
||||
response will be refused by unbound worker as unbound will consider it as non-valid response.
|
||||
|
||||
Complete source code
|
||||
--------------------
|
||||
|
||||
.. literalinclude:: ../../../examples/resgen.py
|
||||
:language: python
|
||||
|
||||
Testing
|
||||
-------
|
||||
|
||||
Run the unbound server:
|
||||
|
||||
``root@localhost>unbound -dv -c ./test-resgen.conf``
|
||||
|
||||
Query for a A record ending with .localdomain
|
||||
|
||||
``dig A test.xxx.localdomain @127.0.0.1``
|
||||
|
||||
Dig produces the following output::
|
||||
|
||||
;; global options: printcmd
|
||||
;; Got answer:
|
||||
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 48426
|
||||
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
|
||||
|
||||
;; QUESTION SECTION:
|
||||
;test.xxx.localdomain. IN A
|
||||
|
||||
;; ANSWER SECTION:
|
||||
test.xxx.localdomain. 10 IN A 127.0.0.1
|
||||
|
||||
;; Query time: 2 msec
|
||||
;; SERVER: 127.0.0.1#53(127.0.0.1)
|
||||
;; WHEN: Mon Jan 01 12:46:02 2009
|
||||
;; MSG SIZE rcvd: 54
|
||||
|
||||
As we handle (override) in python module only queries ending with "localdomain.", the unboud can still resolve host names.
|
63
pythonmod/doc/source/examples/example3.rst
Normal file
63
pythonmod/doc/source/examples/example3.rst
Normal file
@ -0,0 +1,63 @@
|
||||
Response modification
|
||||
=====================
|
||||
|
||||
This example shows how to modify the response produced by the ``iterator`` module.
|
||||
|
||||
As soon as the iterator module returns the response, we :
|
||||
|
||||
1. invalidate the data in cache
|
||||
2. modify the response *TTL*
|
||||
3. rewrite the data in cache
|
||||
4. return modified packet
|
||||
|
||||
Note that the steps 1 and 3 are neccessary only in case, the python module is the first module in the processing chain.
|
||||
In other cases, the validator module guarantees updating data which are produced by iterator module.
|
||||
|
||||
Complete source code
|
||||
--------------------
|
||||
|
||||
.. literalinclude:: ../../../examples/resmod.py
|
||||
:language: python
|
||||
|
||||
Testing
|
||||
-------
|
||||
|
||||
Run Unbound server:
|
||||
|
||||
``root@localhost>unbound -dv -c ./test-resmod.conf``
|
||||
|
||||
Issue a query for name ending with "nic.cz."
|
||||
|
||||
``>>>dig A @127.0.0.1 www.nic.cz``
|
||||
|
||||
::
|
||||
|
||||
;; global options: printcmd
|
||||
;; Got answer:
|
||||
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 48831
|
||||
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 3, ADDITIONAL: 5
|
||||
|
||||
;; QUESTION SECTION:
|
||||
;www.nic.cz. IN A
|
||||
|
||||
;; ANSWER SECTION:
|
||||
www.nic.cz. 10 IN A 217.31.205.50
|
||||
|
||||
;; AUTHORITY SECTION:
|
||||
nic.cz. 10 IN NS e.ns.nic.cz.
|
||||
nic.cz. 10 IN NS a.ns.nic.cz.
|
||||
nic.cz. 10 IN NS c.ns.nic.cz.
|
||||
|
||||
;; ADDITIONAL SECTION:
|
||||
a.ns.nic.cz. 10 IN A 217.31.205.180
|
||||
a.ns.nic.cz. 10 IN AAAA 2001:1488:dada:176::180
|
||||
c.ns.nic.cz. 10 IN A 195.66.241.202
|
||||
c.ns.nic.cz. 10 IN AAAA 2a01:40:1000::2
|
||||
e.ns.nic.cz. 10 IN A 194.146.105.38
|
||||
|
||||
;; Query time: 166 msec
|
||||
;; SERVER: 127.0.0.1#53(127.0.0.1)
|
||||
;; WHEN: Mon Jan 02 13:39:43 2009
|
||||
;; MSG SIZE rcvd: 199
|
||||
|
||||
As you can see, TTL of all the records is set to 10.
|
164
pythonmod/doc/source/examples/example4.rst
Normal file
164
pythonmod/doc/source/examples/example4.rst
Normal file
@ -0,0 +1,164 @@
|
||||
DNS-based language dictionary
|
||||
===============================
|
||||
|
||||
This example shows how to create a simple language dictionary based on **DNS**
|
||||
service within 15 minutes. The translation will be performed using TXT resource records.
|
||||
|
||||
Key parts
|
||||
-----------
|
||||
|
||||
Initialization
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
On **init()** module loads dictionary from a text file containing records in ``word [tab] translation`` format.
|
||||
::
|
||||
|
||||
def init(id, cfg):
|
||||
log_info("pythonmod: dict init")
|
||||
f = open("examples/dict_data.txt", "r")
|
||||
...
|
||||
|
||||
The suitable file can be found at http://slovnik.zcu.cz
|
||||
|
||||
DNS query and word lookup
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Let's define the following format od DNS queries: ``word1[.]word2[.] ... wordN[.]{en,cs}[._dict_.cz.]``.
|
||||
Word lookup is done by simple ``dict`` lookup from broken DNS request.
|
||||
Query name is divided into a list of labels. This list is accesible as qname_list attribute.
|
||||
::
|
||||
|
||||
aword = ' '.join(qstate.qinfo.qname_list[0:-4]) #skip last four labels
|
||||
adict = qstate.qinfo.qname_list[-4] #get 4th label from the end
|
||||
|
||||
words = [] #list of words
|
||||
if (adict == "en") and (aword in en_dict):
|
||||
words = en_dict[aword]
|
||||
|
||||
if (adict == "cs") and (aword in cz_dict):
|
||||
words = cz_dict[aword] # CS -> EN
|
||||
|
||||
In the first step, we get a string in the form: ``word1[space]word2[space]...word[space]``.
|
||||
In the second assignment, fourth label from the end is obtained. This label should contains *"cs"* or *"en"*.
|
||||
This label determines the direction of translation.
|
||||
|
||||
|
||||
Forming of a DNS reply
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
DNS reply is formed only on valid match and added as TXT answer.
|
||||
::
|
||||
|
||||
msg = DNSMessage(qstate.qinfo.qname_str, RR_TYPE_TXT, RR_CLASS_IN, PKT_AA)
|
||||
|
||||
for w in words:
|
||||
msg.answer.append("%s 300 IN TXT \"%s\"" % (qstate.qinfo.qname_str, w.replace("\"", "\\\"")))
|
||||
|
||||
if not msg.set_return_msg(qstate):
|
||||
qstate.ext_state[id] = MODULE_ERROR
|
||||
return True
|
||||
|
||||
qstate.return_rcode = RCODE_NOERROR
|
||||
qstate.ext_state[id] = MODULE_FINISHED
|
||||
return True
|
||||
|
||||
In the first step, a :class:`DNSMessage` instance is created for a given query *(type TXT)*.
|
||||
The fourth argument specifies the flags *(authoritative answer)*.
|
||||
In the second step, we append TXT records containing the translation *(on the right side of RR)*.
|
||||
Then, the response is finished and ``qstate.return_msg`` contains new response.
|
||||
If no error, the module sets :attr:`module_qstate.return_rcode` and :attr:`module_qstate.ext_state`.
|
||||
|
||||
**Steps:**
|
||||
|
||||
1. create :class:`DNSMessage` instance
|
||||
2. append TXT records containing the translation
|
||||
3. set response to ``qstate.return_msg``
|
||||
|
||||
Testing
|
||||
-------
|
||||
|
||||
Run the Unbound server:
|
||||
|
||||
``root@localhost>unbound -dv -c ./test-dict.conf``
|
||||
|
||||
In case you use own configuration file, don't forget to enable Python module::
|
||||
|
||||
module-config: "validator python iterator"
|
||||
|
||||
and use valid script path::
|
||||
|
||||
python-script: "./examples/dict.py"
|
||||
|
||||
The translation from english word *"a bar fly"* to Czech can be done by doing:
|
||||
|
||||
``>>>dig TXT @127.0.0.1 a.bar.fly.en._dict_.cz``
|
||||
|
||||
::
|
||||
|
||||
; (1 server found)
|
||||
;; global options: printcmd
|
||||
;; Got answer:
|
||||
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 48691
|
||||
;; flags: aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
|
||||
|
||||
;; QUESTION SECTION:
|
||||
;a.bar.fly.en._dict_.cz. IN TXT
|
||||
|
||||
;; ANSWER SECTION:
|
||||
a.bar.fly.en._dict_.cz. 300 IN TXT "barov\253 povale\232"
|
||||
|
||||
;; Query time: 5 msec
|
||||
;; SERVER: 127.0.0.1#53(127.0.0.1)
|
||||
;; WHEN: Mon Jan 01 17:44:18 2009
|
||||
;; MSG SIZE rcvd: 67
|
||||
|
||||
``>>>dig TXT @127.0.0.1 nic.cs._dict_.cz``
|
||||
::
|
||||
|
||||
; <<>> DiG 9.5.0-P2 <<>> TXT @127.0.0.1 nic.cs._dict_.cz
|
||||
; (1 server found)
|
||||
;; global options: printcmd
|
||||
;; Got answer:
|
||||
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 58710
|
||||
;; flags: aa rd ra; QUERY: 1, ANSWER: 6, AUTHORITY: 0, ADDITIONAL: 0
|
||||
|
||||
;; QUESTION SECTION:
|
||||
;nic.cs._dict_.cz. IN TXT
|
||||
|
||||
;; ANSWER SECTION:
|
||||
nic.cs._dict_.cz. 300 IN TXT "aught"
|
||||
nic.cs._dict_.cz. 300 IN TXT "naught"
|
||||
nic.cs._dict_.cz. 300 IN TXT "nihil"
|
||||
nic.cs._dict_.cz. 300 IN TXT "nix"
|
||||
nic.cs._dict_.cz. 300 IN TXT "nothing"
|
||||
nic.cs._dict_.cz. 300 IN TXT "zilch"
|
||||
|
||||
;; Query time: 0 msec
|
||||
;; SERVER: 127.0.0.1#53(127.0.0.1)
|
||||
;; WHEN: Mon Jan 01 17:45:39 2009
|
||||
;; MSG SIZE rcvd: 143
|
||||
|
||||
Proof that the unbound still works as resolver.
|
||||
|
||||
``>>>dig A @127.0.0.1 www.nic.cz``
|
||||
::
|
||||
|
||||
; (1 server found)
|
||||
;; global options: printcmd
|
||||
;; Got answer:
|
||||
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 19996
|
||||
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 3, ADDITIONAL: 5
|
||||
|
||||
;; QUESTION SECTION:
|
||||
;www.nic.cz. IN A
|
||||
|
||||
;; ANSWER SECTION:
|
||||
www.nic.cz. 1662 IN A 217.31.205.50
|
||||
|
||||
;; AUTHORITY SECTION:
|
||||
...
|
||||
|
||||
Complete source code
|
||||
--------------------
|
||||
|
||||
.. literalinclude:: ../../../examples/dict.py
|
||||
:language: python
|
15
pythonmod/doc/source/examples/index.rst
Normal file
15
pythonmod/doc/source/examples/index.rst
Normal file
@ -0,0 +1,15 @@
|
||||
.. _Tutorials:
|
||||
|
||||
==============================
|
||||
Tutorials
|
||||
==============================
|
||||
|
||||
Here you can find several tutorials which clarify the usage and capabilities of Unbound scriptable interface.
|
||||
|
||||
`Tutorials`
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:glob:
|
||||
|
||||
example*
|
34
pythonmod/doc/source/index.rst
Normal file
34
pythonmod/doc/source/index.rst
Normal file
@ -0,0 +1,34 @@
|
||||
Unbound scriptable interface
|
||||
=======================================
|
||||
|
||||
Python module for **Unbound** provides easy-to-use flexible solution,
|
||||
for scripting query events and much more!
|
||||
|
||||
Along with extensible **SWIG** interface, it turns **Unbound** into dynamic *DNS* service
|
||||
designed for rapid development of *DNS* based applications, like detailed *(per query/domain)* statistics,
|
||||
monitoring with anything Python can offer *(database backend, http server)*.
|
||||
|
||||
**Key features**
|
||||
* Rapid dynamic DNS-based application development in **Python**
|
||||
* Extensible interface with **SWIG**
|
||||
* Easy to use debugging and analysis tool
|
||||
* Capable to produce authoritative answers
|
||||
* Support for logging or doing detailed statistics
|
||||
* Allows to manipulate with content of cache memory
|
||||
|
||||
Contents
|
||||
--------
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
install
|
||||
examples/index
|
||||
usecase
|
||||
modules/index
|
||||
|
||||
Indices and tables
|
||||
-------------------
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`search`
|
||||
|
59
pythonmod/doc/source/install.rst
Normal file
59
pythonmod/doc/source/install.rst
Normal file
@ -0,0 +1,59 @@
|
||||
Installation
|
||||
===================================
|
||||
|
||||
**Prerequisites**
|
||||
|
||||
Python 2.4 or higher, SWIG 1.3 or higher, GNU make
|
||||
|
||||
**Download**
|
||||
|
||||
You can download the source codes `here`_.
|
||||
The latest release is 1.1.1, Jan 15, 2009.
|
||||
|
||||
.. _here: unbound-1.1.1-py.tar.gz
|
||||
|
||||
**Compiling**
|
||||
|
||||
After downloading, you can compile the Unbound library by doing::
|
||||
|
||||
> tar -xzf unbound-1.1.1-py.tar.gz
|
||||
> cd unbound-1.1.1
|
||||
> ./configure --with-pythonmodule
|
||||
> make
|
||||
|
||||
You need GNU make to compile sources.
|
||||
SWIG and Python devel libraries to compile extension module.
|
||||
|
||||
**Testing**
|
||||
|
||||
If the compilation is successful, you can test the extension module by::
|
||||
|
||||
> cd pythonmod
|
||||
> make sudo # or "make test" or "make suexec"
|
||||
|
||||
This will start unbound server with language dictionary service (see :ref:`Tutorials`).
|
||||
In order to test this service, type::
|
||||
|
||||
> dig TXT @127.0.0.1 aught.en._dict_.cz
|
||||
|
||||
Dig should print this message (czech equivalent of aught)::
|
||||
|
||||
; <<>> DiG 9.5.0-P2 <<>> TXT @127.0.0.1 aught.en._dict_.cz
|
||||
; (1 server found)
|
||||
;; global options: printcmd
|
||||
;; Got answer:
|
||||
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 30085
|
||||
;; flags: aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
|
||||
|
||||
;; QUESTION SECTION:
|
||||
;aught.en._dict_.cz. IN TXT
|
||||
|
||||
;; ANSWER SECTION:
|
||||
aught.en._dict_.cz. 300 IN TXT "nic"
|
||||
|
||||
;; Query time: 11 msec
|
||||
;; SERVER: 127.0.0.1#53(127.0.0.1)
|
||||
;; WHEN: Thu Jan 10 16:45:58 2009
|
||||
;; MSG SIZE rcvd: 52
|
||||
|
||||
The ``pythonmod/examples`` directory contains simple applications written in Python.
|
350
pythonmod/doc/source/modules/config.rst
Normal file
350
pythonmod/doc/source/modules/config.rst
Normal file
@ -0,0 +1,350 @@
|
||||
Configuration interface
|
||||
=======================
|
||||
|
||||
Currently passed to Python module in init(module_id, cfg).
|
||||
|
||||
config_file
|
||||
--------------------
|
||||
|
||||
.. class:: config_file
|
||||
|
||||
This class provides these data attributes:
|
||||
|
||||
.. attribute:: verbosity
|
||||
|
||||
Verbosity level as specified in the config file.
|
||||
|
||||
.. attribute:: stat_interval
|
||||
|
||||
Statistics interval (in seconds).
|
||||
|
||||
.. attribute:: stat_cumulative
|
||||
|
||||
If false, statistics values are reset after printing them.
|
||||
|
||||
.. attribute:: stat_extended
|
||||
|
||||
If true, the statistics are kept in greater detail.
|
||||
|
||||
.. attribute:: num_threads
|
||||
|
||||
Number of threads to create.
|
||||
|
||||
.. attribute:: port
|
||||
|
||||
Port on which queries are answered.
|
||||
|
||||
.. attribute:: do_ip4
|
||||
|
||||
Do ip4 query support.
|
||||
|
||||
.. attribute:: do_ip6
|
||||
|
||||
Do ip6 query support.
|
||||
|
||||
.. attribute:: do_udp
|
||||
|
||||
Do udp query support.
|
||||
|
||||
.. attribute:: do_tcp
|
||||
|
||||
Do tcp query support.
|
||||
|
||||
.. attribute:: outgoing_num_ports
|
||||
|
||||
Outgoing port range number of ports (per thread).
|
||||
|
||||
.. attribute:: outgoing_num_tcp
|
||||
|
||||
Number of outgoing tcp buffers per (per thread).
|
||||
|
||||
.. attribute:: incoming_num_tcp
|
||||
|
||||
Number of incoming tcp buffers per (per thread).
|
||||
|
||||
.. attribute:: outgoing_avail_ports
|
||||
|
||||
Allowed udp port numbers, array with 0 if not allowed.
|
||||
|
||||
.. attribute:: msg_buffer_size
|
||||
|
||||
Number of bytes buffer size for DNS messages.
|
||||
|
||||
.. attribute:: msg_cache_size
|
||||
|
||||
Size of the message cache.
|
||||
|
||||
.. attribute:: msg_cache_slabs
|
||||
|
||||
Slabs in the message cache.
|
||||
|
||||
.. attribute:: num_queries_per_thread
|
||||
|
||||
Number of queries every thread can service.
|
||||
|
||||
.. attribute:: jostle_time
|
||||
|
||||
Number of msec to wait before items can be jostled out.
|
||||
|
||||
.. attribute:: rrset_cache_size
|
||||
|
||||
Size of the rrset cache.
|
||||
|
||||
.. attribute:: rrset_cache_slabs
|
||||
|
||||
Slabs in the rrset cache.
|
||||
|
||||
.. attribute:: host_ttl
|
||||
|
||||
Host cache ttl in seconds.
|
||||
|
||||
.. attribute:: lame_ttl
|
||||
|
||||
Host is lame for a zone ttl, in seconds.
|
||||
|
||||
.. attribute:: infra_cache_slabs
|
||||
|
||||
Number of slabs in the infra host cache.
|
||||
|
||||
.. attribute:: infra_cache_numhosts
|
||||
|
||||
Max number of hosts in the infra cache.
|
||||
|
||||
.. attribute:: infra_cache_lame_size
|
||||
|
||||
Max size of lame zones per host in the infra cache.
|
||||
|
||||
.. attribute:: target_fetch_policy
|
||||
|
||||
The target fetch policy for the iterator.
|
||||
|
||||
.. attribute:: if_automatic
|
||||
|
||||
Automatic interface for incoming messages. Uses ipv6 remapping,
|
||||
and recvmsg/sendmsg ancillary data to detect interfaces, boolean.
|
||||
|
||||
.. attribute:: num_ifs
|
||||
|
||||
Number of interfaces to open. If 0 default all interfaces.
|
||||
|
||||
.. attribute:: ifs
|
||||
|
||||
Interface description strings (IP addresses).
|
||||
|
||||
.. attribute:: num_out_ifs
|
||||
|
||||
Number of outgoing interfaces to open.
|
||||
If 0 default all interfaces.
|
||||
|
||||
.. attribute:: out_ifs
|
||||
|
||||
Outgoing interface description strings (IP addresses).
|
||||
|
||||
.. attribute:: root_hints
|
||||
|
||||
The root hints.
|
||||
|
||||
.. attribute:: stubs
|
||||
|
||||
The stub definitions, linked list.
|
||||
|
||||
.. attribute:: forwards
|
||||
|
||||
The forward zone definitions, linked list.
|
||||
|
||||
.. attribute:: donotqueryaddrs
|
||||
|
||||
List of donotquery addresses, linked list.
|
||||
|
||||
.. attribute:: acls
|
||||
|
||||
List of access control entries, linked list.
|
||||
|
||||
.. attribute:: donotquery_localhost
|
||||
|
||||
Use default localhost donotqueryaddr entries.
|
||||
|
||||
.. attribute:: harden_short_bufsize
|
||||
|
||||
Harden against very small edns buffer sizes.
|
||||
|
||||
.. attribute:: harden_large_queries
|
||||
|
||||
Harden against very large query sizes.
|
||||
|
||||
.. attribute:: harden_glue
|
||||
|
||||
Harden against spoofed glue (out of zone data).
|
||||
|
||||
.. attribute:: harden_dnssec_stripped
|
||||
|
||||
Harden against receiving no DNSSEC data for trust anchor.
|
||||
|
||||
.. attribute:: harden_referral_path
|
||||
|
||||
Harden the referral path, query for NS,A,AAAA and validate.
|
||||
|
||||
.. attribute:: use_caps_bits_for_id
|
||||
|
||||
Use 0x20 bits in query as random ID bits.
|
||||
|
||||
.. attribute:: private_address
|
||||
|
||||
Strip away these private addrs from answers, no DNS Rebinding.
|
||||
|
||||
.. attribute:: private_domain
|
||||
|
||||
Allow domain (and subdomains) to use private address space.
|
||||
|
||||
.. attribute:: unwanted_threshold
|
||||
|
||||
What threshold for unwanted action.
|
||||
|
||||
.. attribute:: chrootdir
|
||||
|
||||
Chrootdir, if not "" or chroot will be done.
|
||||
|
||||
.. attribute:: username
|
||||
|
||||
Username to change to, if not "".
|
||||
|
||||
.. attribute:: directory
|
||||
|
||||
Working directory.
|
||||
|
||||
.. attribute:: logfile
|
||||
|
||||
Filename to log to.
|
||||
|
||||
.. attribute:: pidfile
|
||||
|
||||
Pidfile to write pid to.
|
||||
|
||||
.. attribute:: use_syslog
|
||||
|
||||
Should log messages be sent to syslogd.
|
||||
|
||||
.. attribute:: hide_identity
|
||||
|
||||
Do not report identity (id.server, hostname.bind).
|
||||
|
||||
.. attribute:: hide_version
|
||||
|
||||
Do not report version (version.server, version.bind).
|
||||
|
||||
.. attribute:: identity
|
||||
|
||||
Identity, hostname is returned if "".
|
||||
|
||||
.. attribute:: version
|
||||
|
||||
Version, package version returned if "".
|
||||
|
||||
.. attribute:: module_conf
|
||||
|
||||
The module configuration string.
|
||||
|
||||
.. attribute:: trust_anchor_file_list
|
||||
|
||||
Files with trusted DS and DNSKEYs in zonefile format, list.
|
||||
|
||||
.. attribute:: trust_anchor_list
|
||||
|
||||
List of trustanchor keys, linked list.
|
||||
|
||||
.. attribute:: trusted_keys_file_list
|
||||
|
||||
Files with trusted DNSKEYs in named.conf format, list.
|
||||
|
||||
.. attribute:: dlv_anchor_file
|
||||
|
||||
DLV anchor file.
|
||||
|
||||
.. attribute:: dlv_anchor_list
|
||||
|
||||
DLV anchor inline.
|
||||
|
||||
.. attribute:: max_ttl
|
||||
|
||||
The number of seconds maximal TTL used for RRsets and messages.
|
||||
|
||||
.. attribute:: val_date_override
|
||||
|
||||
If not 0, this value is the validation date for RRSIGs.
|
||||
|
||||
.. attribute:: bogus_ttl
|
||||
|
||||
This value sets the number of seconds before revalidating bogus.
|
||||
|
||||
.. attribute:: val_clean_additional
|
||||
|
||||
Should validator clean additional section for secure msgs.
|
||||
|
||||
.. attribute:: val_permissive_mode
|
||||
|
||||
Should validator allow bogus messages to go through.
|
||||
|
||||
.. attribute:: val_nsec3_key_iterations
|
||||
|
||||
Nsec3 maximum iterations per key size, string.
|
||||
|
||||
.. attribute:: key_cache_size
|
||||
|
||||
Size of the key cache.
|
||||
|
||||
.. attribute:: key_cache_slabs
|
||||
|
||||
Slabs in the key cache.
|
||||
|
||||
.. attribute:: neg_cache_size
|
||||
|
||||
Size of the neg cache.
|
||||
|
||||
|
||||
.. attribute:: local_zones
|
||||
|
||||
Local zones config.
|
||||
|
||||
.. attribute:: local_zones_nodefault
|
||||
|
||||
Local zones nodefault list.
|
||||
|
||||
.. attribute:: local_data
|
||||
|
||||
Local data RRs configged.
|
||||
|
||||
.. attribute:: remote_control_enable
|
||||
|
||||
Remote control section. enable toggle.
|
||||
|
||||
.. attribute:: control_ifs
|
||||
|
||||
The interfaces the remote control should listen on.
|
||||
|
||||
.. attribute:: control_port
|
||||
|
||||
Port number for the control port.
|
||||
|
||||
.. attribute:: server_key_file
|
||||
|
||||
Private key file for server.
|
||||
|
||||
.. attribute:: server_cert_file
|
||||
|
||||
Certificate file for server.
|
||||
|
||||
.. attribute:: control_key_file
|
||||
|
||||
Private key file for unbound-control.
|
||||
|
||||
.. attribute:: control_cert_file
|
||||
|
||||
Certificate file for unbound-control.
|
||||
|
||||
.. attribute:: do_daemonize
|
||||
|
||||
Daemonize, i.e. fork into the background.
|
||||
|
||||
.. attribute:: python_script
|
||||
|
||||
Python script file.
|
412
pythonmod/doc/source/modules/env.rst
Normal file
412
pythonmod/doc/source/modules/env.rst
Normal file
@ -0,0 +1,412 @@
|
||||
Global environment
|
||||
==================
|
||||
|
||||
Global variables
|
||||
----------------
|
||||
|
||||
.. envvar:: mod_env
|
||||
|
||||
Module environment, contains data pointer for module-specific data.
|
||||
See :class:`pythonmod_env`.
|
||||
|
||||
|
||||
Predefined constants
|
||||
-----------------------
|
||||
|
||||
Module extended state
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. data:: module_state_initial
|
||||
|
||||
Initial state - new DNS query.
|
||||
|
||||
.. data:: module_wait_reply
|
||||
|
||||
Waiting for reply to outgoing network query.
|
||||
|
||||
.. data:: module_wait_module
|
||||
|
||||
Module is waiting for another module.
|
||||
|
||||
.. data:: module_wait_subquery
|
||||
|
||||
Module is waiting for sub-query.
|
||||
|
||||
.. data:: module_error
|
||||
|
||||
Module could not finish the query.
|
||||
|
||||
.. data:: module_finished
|
||||
|
||||
Module is finished with query.
|
||||
|
||||
Module event
|
||||
~~~~~~~~~~~~~
|
||||
.. data:: module_event_new
|
||||
|
||||
New DNS query.
|
||||
|
||||
.. data:: module_event_pass
|
||||
|
||||
Query passed by other module.
|
||||
|
||||
.. data:: module_event_reply
|
||||
|
||||
Reply inbound from server.
|
||||
|
||||
.. data:: module_event_noreply
|
||||
|
||||
No reply, timeout or other error.
|
||||
|
||||
.. data:: module_event_capsfail
|
||||
|
||||
Reply is there, but capitalisation check failed.
|
||||
|
||||
.. data:: module_event_moddone
|
||||
|
||||
Next module is done, and its reply is awaiting you.
|
||||
|
||||
.. data:: module_event_error
|
||||
|
||||
Error occured.
|
||||
|
||||
Security status
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
.. data:: sec_status_unchecked
|
||||
|
||||
Means that object has yet to be validated.
|
||||
|
||||
.. data:: sec_status_bogus
|
||||
|
||||
Means that the object *(RRset or message)* failed to validate
|
||||
*(according to local policy)*, but should have validated.
|
||||
|
||||
.. data:: sec_status_indeterminate
|
||||
|
||||
Means that the object is insecure, but not
|
||||
authoritatively so. Generally this means that the RRset is not
|
||||
below a configured trust anchor.
|
||||
|
||||
.. data:: sec_status_insecure
|
||||
|
||||
Means that the object is authoritatively known to be
|
||||
insecure. Generally this means that this RRset is below a trust
|
||||
anchor, but also below a verified, insecure delegation.
|
||||
|
||||
.. data:: sec_status_secure
|
||||
|
||||
Means that the object (RRset or message) validated according to local policy.
|
||||
|
||||
Resource records (RR sets)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The different RR classes.
|
||||
|
||||
.. data:: RR_CLASS_IN
|
||||
|
||||
Internet.
|
||||
|
||||
.. data:: RR_CLASS_CH
|
||||
|
||||
Chaos.
|
||||
|
||||
.. data:: RR_CLASS_HS
|
||||
|
||||
Hesiod (Dyer 87)
|
||||
|
||||
.. data:: RR_CLASS_NONE
|
||||
|
||||
None class, dynamic update.
|
||||
|
||||
.. data:: RR_CLASS_ANY
|
||||
|
||||
Any class.
|
||||
|
||||
|
||||
The different RR types.
|
||||
|
||||
|
||||
.. data:: RR_TYPE_A
|
||||
|
||||
A host address.
|
||||
|
||||
.. data:: RR_TYPE_NS
|
||||
|
||||
An authoritative name server.
|
||||
|
||||
.. data:: RR_TYPE_MD
|
||||
|
||||
A mail destination (Obsolete - use MX).
|
||||
|
||||
.. data:: RR_TYPE_MF
|
||||
|
||||
A mail forwarder (Obsolete - use MX).
|
||||
|
||||
.. data:: RR_TYPE_CNAME
|
||||
|
||||
The canonical name for an alias.
|
||||
|
||||
.. data:: RR_TYPE_SOA
|
||||
|
||||
Marks the start of a zone of authority.
|
||||
|
||||
.. data:: RR_TYPE_MB
|
||||
|
||||
A mailbox domain name (EXPERIMENTAL).
|
||||
|
||||
.. data:: RR_TYPE_MG
|
||||
|
||||
A mail group member (EXPERIMENTAL).
|
||||
|
||||
.. data:: RR_TYPE_MR
|
||||
|
||||
A mail rename domain name (EXPERIMENTAL).
|
||||
|
||||
.. data:: RR_TYPE_NULL
|
||||
|
||||
A null RR (EXPERIMENTAL).
|
||||
|
||||
.. data:: RR_TYPE_WKS
|
||||
|
||||
A well known service description.
|
||||
|
||||
.. data:: RR_TYPE_PTR
|
||||
|
||||
A domain name pointer.
|
||||
|
||||
.. data:: RR_TYPE_HINFO
|
||||
|
||||
Host information.
|
||||
|
||||
.. data:: RR_TYPE_MINFO
|
||||
|
||||
Mailbox or mail list information.
|
||||
|
||||
.. data:: RR_TYPE_MX
|
||||
|
||||
Mail exchange.
|
||||
|
||||
.. data:: RR_TYPE_TXT
|
||||
|
||||
Text strings.
|
||||
|
||||
.. data:: RR_TYPE_RP
|
||||
|
||||
RFC1183.
|
||||
|
||||
.. data:: RR_TYPE_AFSDB
|
||||
|
||||
RFC1183.
|
||||
|
||||
.. data:: RR_TYPE_X25
|
||||
|
||||
RFC1183.
|
||||
|
||||
.. data:: RR_TYPE_ISDN
|
||||
|
||||
RFC1183.
|
||||
|
||||
.. data:: RR_TYPE_RT
|
||||
|
||||
RFC1183.
|
||||
|
||||
.. data:: RR_TYPE_NSAP
|
||||
|
||||
RFC1706.
|
||||
|
||||
.. data:: RR_TYPE_NSAP_PTR
|
||||
|
||||
RFC1348.
|
||||
|
||||
.. data:: RR_TYPE_SIG
|
||||
|
||||
2535typecode.
|
||||
|
||||
.. data:: RR_TYPE_KEY
|
||||
|
||||
2535typecode.
|
||||
|
||||
.. data:: RR_TYPE_PX
|
||||
|
||||
RFC2163.
|
||||
|
||||
.. data:: RR_TYPE_GPOS
|
||||
|
||||
RFC1712.
|
||||
|
||||
.. data:: RR_TYPE_AAAA
|
||||
|
||||
IPv6 address.
|
||||
|
||||
.. data:: RR_TYPE_LOC
|
||||
|
||||
LOC record RFC1876.
|
||||
|
||||
.. data:: RR_TYPE_NXT
|
||||
|
||||
2535typecode.
|
||||
|
||||
.. data:: RR_TYPE_EID
|
||||
|
||||
draft-ietf-nimrod-dns-01.txt.
|
||||
|
||||
.. data:: RR_TYPE_NIMLOC
|
||||
|
||||
draft-ietf-nimrod-dns-01.txt.
|
||||
|
||||
.. data:: RR_TYPE_SRV
|
||||
|
||||
SRV record RFC2782.
|
||||
|
||||
.. data:: RR_TYPE_ATMA
|
||||
|
||||
http://www.jhsoft.com/rfc/af-saa-0069.000.rtf.
|
||||
|
||||
.. data:: RR_TYPE_NAPTR
|
||||
|
||||
RFC2915.
|
||||
|
||||
.. data:: RR_TYPE_KX
|
||||
|
||||
RFC2230.
|
||||
|
||||
.. data:: RR_TYPE_CERT
|
||||
|
||||
RFC2538.
|
||||
|
||||
.. data:: RR_TYPE_A6
|
||||
|
||||
RFC2874.
|
||||
|
||||
.. data:: RR_TYPE_DNAME
|
||||
|
||||
RFC2672.
|
||||
|
||||
.. data:: RR_TYPE_SINK
|
||||
|
||||
dnsind-kitchen-sink-02.txt.
|
||||
|
||||
.. data:: RR_TYPE_OPT
|
||||
|
||||
Pseudo OPT record.
|
||||
|
||||
.. data:: RR_TYPE_APL
|
||||
|
||||
RFC3123.
|
||||
|
||||
.. data:: RR_TYPE_DS
|
||||
|
||||
draft-ietf-dnsext-delegation.
|
||||
|
||||
.. data:: RR_TYPE_SSHFP
|
||||
|
||||
SSH Key Fingerprint.
|
||||
|
||||
.. data:: RR_TYPE_IPSECKEY
|
||||
|
||||
draft-richardson-ipseckey-rr-11.txt.
|
||||
|
||||
.. data:: RR_TYPE_RRSIG
|
||||
|
||||
draft-ietf-dnsext-dnssec-25.
|
||||
|
||||
.. data:: RR_TYPE_NSEC
|
||||
.. data:: RR_TYPE_DNSKEY
|
||||
.. data:: RR_TYPE_DHCID
|
||||
.. data:: RR_TYPE_NSEC3
|
||||
.. data:: RR_TYPE_NSEC3PARAMS
|
||||
.. data:: RR_TYPE_UINFO
|
||||
.. data:: RR_TYPE_UID
|
||||
.. data:: RR_TYPE_GID
|
||||
.. data:: RR_TYPE_UNSPEC
|
||||
.. data:: RR_TYPE_TSIG
|
||||
.. data:: RR_TYPE_IXFR
|
||||
.. data:: RR_TYPE_AXFR
|
||||
.. data:: RR_TYPE_MAILB
|
||||
|
||||
A request for mailbox-related records (MB, MG or MR).
|
||||
|
||||
.. data:: RR_TYPE_MAILA
|
||||
|
||||
A request for mail agent RRs (Obsolete - see MX).
|
||||
|
||||
.. data:: RR_TYPE_ANY
|
||||
|
||||
Any type *(wildcard)*.
|
||||
|
||||
.. data:: RR_TYPE_DLV
|
||||
|
||||
RFC 4431, 5074, DNSSEC Lookaside Validation.
|
||||
|
||||
Return codes
|
||||
~~~~~~~~~~~~
|
||||
|
||||
Return codes for packets.
|
||||
|
||||
.. data:: RCODE_NOERROR
|
||||
.. data:: RCODE_FORMERR
|
||||
.. data:: RCODE_SERVFAIL
|
||||
.. data:: RCODE_NXDOMAIN
|
||||
.. data:: RCODE_NOTIMPL
|
||||
.. data:: RCODE_REFUSED
|
||||
.. data:: RCODE_YXDOMAIN
|
||||
.. data:: RCODE_YXRRSET
|
||||
.. data:: RCODE_NXRRSET
|
||||
.. data:: RCODE_NOTAUTH
|
||||
.. data:: RCODE_NOTZONE
|
||||
|
||||
Packet data
|
||||
~~~~~~~~~~~~
|
||||
|
||||
.. data:: PKT_QR
|
||||
|
||||
Query - query flag.
|
||||
|
||||
.. data:: PKT_AA
|
||||
|
||||
Authoritative Answer - server flag.
|
||||
|
||||
.. data:: PKT_TC
|
||||
|
||||
Truncated - server flag.
|
||||
|
||||
.. data:: PKT_RD
|
||||
|
||||
Recursion desired - query flag.
|
||||
|
||||
.. data:: PKT_CD
|
||||
|
||||
Checking disabled - query flag.
|
||||
|
||||
.. data:: PKT_RA
|
||||
|
||||
Recursion available - server flag.
|
||||
|
||||
.. data:: PKT_AD
|
||||
|
||||
Authenticated data - server flag.
|
||||
|
||||
|
||||
Verbosity value
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
.. data:: NO_VERBOSE
|
||||
|
||||
No verbose messages.
|
||||
|
||||
.. data:: VERB_OPS
|
||||
|
||||
Operational information.
|
||||
|
||||
.. data:: VERB_DETAIL
|
||||
|
||||
Detailed information.
|
||||
|
||||
.. data:: VERB_QUERY
|
||||
|
||||
Query level information.
|
||||
|
||||
.. data:: VERB_ALGO
|
||||
|
||||
Algorithm level information.
|
120
pythonmod/doc/source/modules/functions.rst
Normal file
120
pythonmod/doc/source/modules/functions.rst
Normal file
@ -0,0 +1,120 @@
|
||||
Scriptable functions
|
||||
====================
|
||||
|
||||
Network
|
||||
-------
|
||||
|
||||
.. function:: ntohs(netshort)
|
||||
|
||||
This subroutine converts values between the host and network byte order.
|
||||
Specifically, **ntohs()** converts 16-bit quantities from network byte order to host byte order.
|
||||
|
||||
:param netshort: 16-bit short addr
|
||||
:rtype: converted addr
|
||||
|
||||
|
||||
Cache
|
||||
-----
|
||||
|
||||
.. function:: storeQueryInCache(qstate, qinfo, msgrep, is_referral)
|
||||
|
||||
Store pending query in local cache.
|
||||
|
||||
:param qstate: :class:`module_qstate`
|
||||
:param qinfo: :class:`query_info`
|
||||
:param msgrep: :class:`reply_info`
|
||||
:param is_referal: integer
|
||||
:rtype: boolean
|
||||
|
||||
.. function:: invalidateQueryInCache(qstate, qinfo)
|
||||
|
||||
Invalidate record in local cache.
|
||||
|
||||
:param qstate: :class:`module_qstate`
|
||||
:param qinfo: :class:`query_info`
|
||||
|
||||
|
||||
Logging
|
||||
-------
|
||||
|
||||
.. function:: verbose(level, msg)
|
||||
|
||||
Log a verbose message, pass the level for this message.
|
||||
No trailing newline is needed.
|
||||
|
||||
:param level: verbosity level for this message, compared to global verbosity setting.
|
||||
:param msg: string message
|
||||
|
||||
.. function:: log_info(msg)
|
||||
|
||||
Log informational message. No trailing newline is needed.
|
||||
|
||||
:param msg: string message
|
||||
|
||||
.. function:: log_err(msg)
|
||||
|
||||
Log error message. No trailing newline is needed.
|
||||
|
||||
:param msg: string message
|
||||
|
||||
.. function:: log_warn(msg)
|
||||
|
||||
Log warning message. No trailing newline is needed.
|
||||
|
||||
:param msg: string message
|
||||
|
||||
.. function:: log_hex(msg, data, length)
|
||||
|
||||
Log a hex-string to the log. Can be any length.
|
||||
performs mallocs to do so, slow. But debug useful.
|
||||
|
||||
:param msg: string desc to accompany the hexdump.
|
||||
:param data: data to dump in hex format.
|
||||
:param length: length of data.
|
||||
|
||||
.. function:: log_dns_msg(str, qinfo, reply)
|
||||
|
||||
Log DNS message.
|
||||
|
||||
:param str: string message
|
||||
:param qinfo: :class:`query_info`
|
||||
:param reply: :class:`reply_info`
|
||||
|
||||
.. function:: log_query_info(verbosity_value, str, qinf)
|
||||
|
||||
Log query information.
|
||||
|
||||
:param verbosity_value: see constants
|
||||
:param str: string message
|
||||
:param qinf: :class:`query_info`
|
||||
|
||||
.. function:: regional_log_stats(r)
|
||||
|
||||
Log regional statistics.
|
||||
|
||||
:param r: :class:`regional`
|
||||
|
||||
Debugging
|
||||
---------
|
||||
|
||||
.. function:: strextstate(module_ext_state)
|
||||
|
||||
Debug utility, module external qstate to string.
|
||||
|
||||
:param module_ext_state: the state value.
|
||||
:rtype: descriptive string.
|
||||
|
||||
.. function:: strmodulevent(module_event)
|
||||
|
||||
Debug utility, module event to string.
|
||||
|
||||
:param module_event: the module event value.
|
||||
:rtype: descriptive string.
|
||||
|
||||
.. function:: ldns_rr_type2str(atype)
|
||||
|
||||
Convert RR type to string.
|
||||
|
||||
.. function:: ldns_rr_class2str(aclass)
|
||||
|
||||
Convert RR class to string.
|
11
pythonmod/doc/source/modules/index.rst
Normal file
11
pythonmod/doc/source/modules/index.rst
Normal file
@ -0,0 +1,11 @@
|
||||
Unbound module documentation
|
||||
=======================================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
env
|
||||
struct
|
||||
functions
|
||||
config
|
||||
|
427
pythonmod/doc/source/modules/struct.rst
Normal file
427
pythonmod/doc/source/modules/struct.rst
Normal file
@ -0,0 +1,427 @@
|
||||
Scriptable structures
|
||||
=====================
|
||||
|
||||
module_qstate
|
||||
-----------------------
|
||||
|
||||
.. class:: module_qstate
|
||||
|
||||
Module state, per query.
|
||||
|
||||
This class provides these data attributes:
|
||||
|
||||
.. attribute:: qinfo
|
||||
|
||||
(:class:`query_info`) Informations about query being answered. Name, RR type, RR class.
|
||||
|
||||
.. attribute:: query_flags
|
||||
|
||||
(uint16) Flags for query. See QF_BIT\_ predefined constants.
|
||||
|
||||
.. attribute:: is_priming
|
||||
|
||||
If this is a (stub or root) priming query (with hints).
|
||||
|
||||
.. attribute:: reply
|
||||
|
||||
comm_reply contains server replies.
|
||||
|
||||
.. attribute:: return_msg
|
||||
|
||||
(:class:`dns_msg`) The reply message, with message for client and calling module (read-only attribute).
|
||||
Note that if you want to create of modify return_msg you should use :class:`DNSMessage`.
|
||||
|
||||
.. attribute:: return_rcode
|
||||
|
||||
The rcode, in case of error, instead of a reply message. Determines whether the return_msg contains reply.
|
||||
|
||||
.. attribute:: region
|
||||
|
||||
Region for this query. Cleared when query process finishes.
|
||||
|
||||
.. attribute:: curmod
|
||||
|
||||
Which module is executing.
|
||||
|
||||
.. attribute:: ext_state[]
|
||||
|
||||
Module states.
|
||||
|
||||
.. attribute:: env
|
||||
|
||||
Environment for this query.
|
||||
|
||||
.. attribute:: mesh_info
|
||||
|
||||
Mesh related information for this query.
|
||||
|
||||
|
||||
query_info
|
||||
----------------
|
||||
|
||||
.. class:: query_info
|
||||
|
||||
This class provides these data attributes:
|
||||
|
||||
.. attribute:: qname
|
||||
|
||||
The original question in the wireformat format (e.g. \\x03www\\x03nic\\x02cz\\x00 for www.nic.cz)
|
||||
|
||||
.. attribute:: qname_len
|
||||
|
||||
Lenght of question name (number of bytes).
|
||||
|
||||
.. attribute:: qname_list[]
|
||||
|
||||
The question ``qname`` converted into list of labels (e.g. ['www','nic','cz',''] for www.nic.cz)
|
||||
|
||||
.. attribute:: qname_str
|
||||
|
||||
The question ``qname`` converted into string (e.g. www.nic.cz. for www.nic.cz)
|
||||
|
||||
.. attribute:: qtype
|
||||
|
||||
The class type asked for. See RR_TYPE\_ predefined constants.
|
||||
|
||||
.. attribute:: qtype_str
|
||||
|
||||
The ``qtype`` in display presentation format (string) (e.g 'A' for RR_TYPE_A)
|
||||
|
||||
.. attribute:: qclass
|
||||
|
||||
The question class. See RR_CLASS\_ predefined constants.
|
||||
|
||||
.. attribute:: qclass_str
|
||||
|
||||
The ``qclass`` in display presentation format (string).
|
||||
|
||||
reply_info
|
||||
--------------------
|
||||
|
||||
.. class:: reply_info
|
||||
|
||||
This class provides these data attributes:
|
||||
|
||||
.. attribute:: flags
|
||||
|
||||
The flags for the answer, host byte order.
|
||||
|
||||
.. attribute:: qdcount
|
||||
|
||||
Number of RRs in the query section.
|
||||
If qdcount is not 0, then it is 1, and the data that appears
|
||||
in the reply is the same as the query_info.
|
||||
Host byte order.
|
||||
|
||||
.. attribute:: ttl
|
||||
|
||||
TTL of the entire reply (for negative caching).
|
||||
only for use when there are 0 RRsets in this message.
|
||||
if there are RRsets, check those instead.
|
||||
|
||||
.. attribute:: security
|
||||
|
||||
The security status from DNSSEC validation of this message. See sec_status\_ predefined constants.
|
||||
|
||||
.. attribute:: an_numrrsets
|
||||
|
||||
Number of RRsets in each section.
|
||||
The answer section. Add up the RRs in every RRset to calculate
|
||||
the number of RRs, and the count for the dns packet.
|
||||
The number of RRs in RRsets can change due to RRset updates.
|
||||
|
||||
.. attribute:: ns_numrrsets
|
||||
|
||||
Count of authority section RRsets
|
||||
|
||||
.. attribute:: ar_numrrsets
|
||||
|
||||
Count of additional section RRsets
|
||||
|
||||
.. attribute:: rrset_count
|
||||
|
||||
Number of RRsets: an_numrrsets + ns_numrrsets + ar_numrrsets
|
||||
|
||||
.. attribute:: rrsets[]
|
||||
|
||||
(:class:`ub_packed_rrset_key`) List of RR sets in the order in which they appear in the reply message.
|
||||
Number of elements is ancount + nscount + arcount RRsets.
|
||||
|
||||
.. attribute:: ref[]
|
||||
|
||||
(:class:`rrset_ref`) Packed array of ids (see counts) and pointers to packed_rrset_key.
|
||||
The number equals ancount + nscount + arcount RRsets.
|
||||
These are sorted in ascending pointer, the locking order. So
|
||||
this list can be locked (and id, ttl checked), to see if
|
||||
all the data is available and recent enough.
|
||||
|
||||
|
||||
dns_msg
|
||||
--------------
|
||||
|
||||
.. class:: dns_msg
|
||||
|
||||
Region allocated message reply
|
||||
|
||||
This class provides these data attributes:
|
||||
|
||||
.. attribute:: qinfo
|
||||
|
||||
(:class:`query_info`) Informations about query.
|
||||
|
||||
.. attribute:: rep
|
||||
|
||||
(:class:`reply_info`) This attribute points to the packed reply structure.
|
||||
|
||||
|
||||
packed_rrset_key
|
||||
----------------------
|
||||
|
||||
.. class:: packed_rrset_key
|
||||
|
||||
The identifying information for an RRset.
|
||||
|
||||
This class provides these data attributes:
|
||||
|
||||
.. attribute:: dname
|
||||
|
||||
The domain name. If not empty (for ``id = None``) it is allocated, and
|
||||
contains the wireformat domain name. This dname is not canonicalized.
|
||||
E.g., the dname contains \\x03www\\x03nic\\x02cz\\x00 for www.nic.cz.
|
||||
|
||||
.. attribute:: dname_len
|
||||
|
||||
Length of the domain name, including last 0 root octet.
|
||||
|
||||
.. attribute:: dname_list[]
|
||||
|
||||
The domain name ``dname`` converted into list of labels (see :attr:`query_info.qname_list`).
|
||||
|
||||
.. attribute:: dname_str
|
||||
|
||||
The domain name ``dname`` converted into string (see :attr:`query_info.qname_str`).
|
||||
|
||||
.. attribute:: flags
|
||||
|
||||
Flags.
|
||||
|
||||
.. attribute:: type
|
||||
|
||||
The rrset type in network format.
|
||||
|
||||
.. attribute:: type_str
|
||||
|
||||
The rrset type in display presentation format.
|
||||
|
||||
.. attribute:: rrset_class
|
||||
|
||||
The rrset class in network format.
|
||||
|
||||
.. attribute:: rrset_class_str
|
||||
|
||||
The rrset class in display presentation format.
|
||||
|
||||
ub_packed_rrset_key
|
||||
-------------------------
|
||||
|
||||
.. class:: ub_packed_rrset_key
|
||||
|
||||
This structure contains an RRset. A set of resource records that
|
||||
share the same domain name, type and class.
|
||||
Due to memory management and threading, the key structure cannot be
|
||||
deleted, although the data can be. The id can be set to 0 to store and the
|
||||
structure can be recycled with a new id.
|
||||
|
||||
The :class:`ub_packed_rrset_key` provides these data attributes:
|
||||
|
||||
.. attribute:: entry
|
||||
|
||||
(:class:`lruhash_entry`) Entry into hashtable. Note the lock is never destroyed,
|
||||
even when this key is retired to the cache.
|
||||
the data pointer (if not None) points to a :class:`packed_rrset`.
|
||||
|
||||
.. attribute:: id
|
||||
|
||||
The ID of this rrset. unique, based on threadid + sequenceno.
|
||||
ids are not reused, except after flushing the cache.
|
||||
zero is an unused entry, and never a valid id.
|
||||
Check this value after getting entry.lock.
|
||||
The other values in this struct may only be altered after changing
|
||||
the id (which needs a writelock on entry.lock).
|
||||
|
||||
.. attribute:: rk
|
||||
|
||||
(:class:`packed_rrset_key`) RR set data.
|
||||
|
||||
|
||||
lruhash_entry
|
||||
-------------------------
|
||||
|
||||
.. class:: lruhash_entry
|
||||
|
||||
The :class:`ub_packed_rrset_key` provides these data attributes:
|
||||
|
||||
.. attribute:: lock
|
||||
|
||||
rwlock for access to the contents of the entry. Note that you cannot change hash and key, if so, you have to delete it to change hash or key.
|
||||
|
||||
.. attribute:: data
|
||||
|
||||
(:class:`packed_rrset_data`) entry data stored in wireformat (RRs and RRsigs).
|
||||
|
||||
packed_rrset_data
|
||||
-----------------------
|
||||
|
||||
.. class:: packed_rrset_data
|
||||
|
||||
Rdata is stored in wireformat. The dname is stored in wireformat.
|
||||
|
||||
TTLs are stored as absolute values (and could be expired).
|
||||
|
||||
RRSIGs are stored in the arrays after the regular rrs.
|
||||
|
||||
You need the packed_rrset_key to know dname, type, class of the
|
||||
resource records in this RRset. (if signed the rrsig gives the type too).
|
||||
|
||||
The :class:`packed_rrset_data` provides these data attributes:
|
||||
|
||||
.. attribute:: ttl
|
||||
|
||||
TTL (in seconds like time()) of the RRset.
|
||||
Same for all RRs see rfc2181(5.2).
|
||||
|
||||
.. attribute:: count
|
||||
|
||||
Number of RRs.
|
||||
|
||||
.. attribute:: rrsig_count
|
||||
|
||||
Number of rrsigs, if 0 no rrsigs.
|
||||
|
||||
.. attribute:: trust
|
||||
|
||||
The trustworthiness of the RRset data.
|
||||
|
||||
.. attribute:: security
|
||||
|
||||
Security status of the RRset data. See sec_status\_ predefined constants.
|
||||
|
||||
.. attribute:: rr_len[]
|
||||
|
||||
Length of every RR's rdata, rr_len[i] is size of rr_data[i].
|
||||
|
||||
.. attribute:: rr_ttl[]
|
||||
|
||||
TTL of every rr. rr_ttl[i] ttl of rr i.
|
||||
|
||||
.. attribute:: rr_data[]
|
||||
|
||||
Array of RR's rdata (list of strings). The rdata is stored in uncompressed wireformat.
|
||||
The first 16B of rr_data[i] is rdlength in network format.
|
||||
|
||||
|
||||
DNSMessage
|
||||
----------------
|
||||
|
||||
.. class:: DNSMessage
|
||||
|
||||
Abstract representation of DNS message.
|
||||
|
||||
**Usage**
|
||||
|
||||
This example shows how to create an authoritative answer response
|
||||
|
||||
::
|
||||
|
||||
msg = DNSMessage(qstate.qinfo.qname_str, RR_TYPE_A, RR_CLASS_IN, PKT_AA)
|
||||
|
||||
#append RR
|
||||
if (qstate.qinfo.qtype == RR_TYPE_A) or (qstate.qinfo.qtype == RR_TYPE_ANY):
|
||||
msg.answer.append("%s 10 IN A 127.0.0.1" % qstate.qinfo.qname_str)
|
||||
|
||||
#set qstate.return_msg
|
||||
if not msg.set_return_msg(qstate):
|
||||
raise Exception("Can't create response")
|
||||
|
||||
The :class:`DNSMessage` provides these methods and data attributes:
|
||||
|
||||
.. method:: __init__(self, rr_name, rr_type, rr_class = RR_CLASS_IN, query_flags = 0, default_ttl = 0)
|
||||
|
||||
Prepares an answer (DNS packet) from qiven information. Query flags are combination of PKT_xx contants.
|
||||
|
||||
.. method:: set_return_msg(self, qstate)
|
||||
|
||||
This method fills qstate return message according to the given informations.
|
||||
It takes lists of RRs in each section of answer, created necessray RRsets in wire format and store the result in :attr:`qstate.return_msg`.
|
||||
Returns 1 if OK.
|
||||
|
||||
.. attribute:: rr_name
|
||||
|
||||
RR name of question.
|
||||
|
||||
.. attribute:: rr_type
|
||||
|
||||
RR type of question.
|
||||
|
||||
.. attribute:: rr_class
|
||||
|
||||
RR class of question.
|
||||
|
||||
.. attribute:: default_ttl
|
||||
|
||||
Default time-to-live.
|
||||
|
||||
.. attribute:: query_flags
|
||||
|
||||
Query flags. See PKT\_ predefined constants.
|
||||
|
||||
.. attribute:: question[]
|
||||
|
||||
List of resource records that should appear (in the same order) in question section of answer.
|
||||
|
||||
.. attribute:: answer[]
|
||||
|
||||
List of resource records that should appear (in the same order) in answer section of answer.
|
||||
|
||||
.. attribute:: authority[]
|
||||
|
||||
List of resource records that should appear (in the same order) in authority section of answer.
|
||||
|
||||
.. attribute:: additional[]
|
||||
|
||||
List of resource records that should appear (in the same order) in additional section of answer.
|
||||
|
||||
pythonmod_env
|
||||
-----------------------
|
||||
|
||||
.. class:: pythonmod_env
|
||||
|
||||
Global state for the module.
|
||||
|
||||
This class provides these data attributes:
|
||||
|
||||
.. attribute:: data
|
||||
|
||||
Here you can keep your own data shared across each thread.
|
||||
|
||||
.. attribute:: fname
|
||||
|
||||
Python script filename.
|
||||
|
||||
.. attribute:: qstate
|
||||
|
||||
Module query state.
|
||||
|
||||
pythonmod_qstate
|
||||
-----------------------
|
||||
|
||||
.. class:: pythonmod_qstate
|
||||
|
||||
Per query state for the iterator module.
|
||||
|
||||
This class provides these data attributes:
|
||||
|
||||
.. attribute:: data
|
||||
|
||||
Here you can keep your own private data (each thread has own data object).
|
||||
|
38
pythonmod/doc/source/usecase.rst
Normal file
38
pythonmod/doc/source/usecase.rst
Normal file
@ -0,0 +1,38 @@
|
||||
Use cases (examples)
|
||||
====================
|
||||
|
||||
Dynamic DNS Service discovery (DNS-SD_)
|
||||
-------------------------------------------
|
||||
Synchronized with database engine, for example *MySQL*.
|
||||
|
||||
.. _DNS-SD: http://www.dns-sd.org/
|
||||
|
||||
Firewall control
|
||||
----------------
|
||||
Control firewall (e.g. enable incomming SSH connection) with DNS query signed with private key.
|
||||
So firewall can blocks every service during normal operation.
|
||||
|
||||
Scriptable DNS-based blacklist (DNS-BL_)
|
||||
-------------------------------------------
|
||||
Scripted in Python with already provided features, takes advantage of DNS reply, because
|
||||
almost every mail server supports DNS based blacklisting.
|
||||
|
||||
.. _DNS-BL: http://www.dnsbl.org
|
||||
|
||||
DNS based Wake-On-Lan
|
||||
---------------------
|
||||
Controled by secured queries secured with private key.
|
||||
|
||||
Dynamic translation service
|
||||
---------------------------
|
||||
DNS request can be translated to virtualy any answer, that's easy to implement in client side
|
||||
because of many DNS libraries available.
|
||||
|
||||
Examples :
|
||||
* **Dictionary** - using *IDN* for non-ascii strings transfer, ``dig TXT slovo.en._dict_.nic.cz`` returns translation of "slovo" to EN.
|
||||
* **Translation** - Extends *DNS-SD*, for example DNS to Jabber to find out people logged in.
|
||||
* **Exchange rate calculator** - ``dig TXT 1000.99.czk.eur._rates_.nic.cz`` returns the given sum (1000.99 CZK) in EURs.
|
||||
|
||||
Dynamic ENUM service
|
||||
--------------------
|
||||
Support for redirection, synchronization, etc.
|
77
pythonmod/examples/calc.py
Normal file
77
pythonmod/examples/calc.py
Normal file
@ -0,0 +1,77 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
calc.py: DNS-based calculator
|
||||
|
||||
Copyright (c) 2009, Zdenek Vasicek (vasicek AT fit.vutbr.cz)
|
||||
Marek Vavrusa (xvavru00 AT stud.fit.vutbr.cz)
|
||||
|
||||
This software is open source.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the organization 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 REGENTS 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.
|
||||
'''
|
||||
|
||||
#Try: dig @localhost 1*25._calc_.cz.
|
||||
|
||||
def init(id, cfg): return True
|
||||
def deinit(id): return True
|
||||
def inform_super(id, qstate, superqstate, qdata): return True
|
||||
|
||||
def operate(id, event, qstate, qdata):
|
||||
|
||||
if (event == MODULE_EVENT_NEW) or (event == MODULE_EVENT_PASS):
|
||||
|
||||
if qstate.qinfo.qname_str.endswith("._calc_.cz."):
|
||||
try:
|
||||
res = eval(''.join(qstate.qinfo.qname_list[0:-3]))
|
||||
except:
|
||||
res = "exception"
|
||||
|
||||
msg = DNSMessage(qstate.qinfo.qname_str, RR_TYPE_TXT, RR_CLASS_IN, PKT_QR | PKT_RA | PKT_AA) #, 300)
|
||||
msg.answer.append("%s 300 IN TXT \"%s\"" % (qstate.qinfo.qname_str,res))
|
||||
if not msg.set_return_msg(qstate):
|
||||
qstate.ext_state[id] = MODULE_ERROR
|
||||
return True
|
||||
|
||||
qstate.return_rcode = RCODE_NOERROR
|
||||
qstate.ext_state[id] = MODULE_FINISHED
|
||||
return True
|
||||
|
||||
else:
|
||||
#Pass on the unknown query to the iterator
|
||||
qstate.ext_state[id] = MODULE_WAIT_MODULE
|
||||
return True
|
||||
|
||||
elif event == MODULE_EVENT_MODDONE:
|
||||
#the iterator has finished
|
||||
qstate.ext_state[id] = MODULE_FINISHED
|
||||
return True
|
||||
|
||||
log_err("pythonmod: Unknown event")
|
||||
qstate.ext_state[id] = MODULE_ERROR
|
||||
return True
|
||||
|
121
pythonmod/examples/dict.py
Normal file
121
pythonmod/examples/dict.py
Normal file
@ -0,0 +1,121 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
calc.py: DNS-based czech-english dictionary
|
||||
|
||||
Copyright (c) 2009, Zdenek Vasicek (vasicek AT fit.vutbr.cz)
|
||||
Marek Vavrusa (xvavru00 AT stud.fit.vutbr.cz)
|
||||
|
||||
This software is open source.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the organization 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 REGENTS 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.
|
||||
'''
|
||||
import os
|
||||
cz_dict = {}
|
||||
en_dict = {}
|
||||
|
||||
def init(id, cfg):
|
||||
log_info("pythonmod: dict init")
|
||||
f = open("examples/dict_data.txt", "r")
|
||||
try:
|
||||
for line in f:
|
||||
if line.startswith('#'):
|
||||
continue
|
||||
itm = line.split("\t", 3)
|
||||
if len(itm) < 2:
|
||||
continue
|
||||
en,cs = itm[0:2]
|
||||
|
||||
if not (cs in cz_dict):
|
||||
cz_dict[cs] = [en] # [cs] = en
|
||||
else:
|
||||
cz_dict[cs].append(en) # [cs] = en
|
||||
|
||||
if not (en in en_dict):
|
||||
en_dict[en] = [cs] # [en] = cs
|
||||
else:
|
||||
en_dict[en].append(cs) # [en] = cs
|
||||
|
||||
finally:
|
||||
f.close()
|
||||
return True
|
||||
|
||||
def deinit(id):
|
||||
log_info("pythonmod: dict deinit")
|
||||
return True
|
||||
|
||||
def operate(id, event, qstate, qdata):
|
||||
if (event == MODULE_EVENT_NEW) or (event == MODULE_EVENT_PASS):
|
||||
|
||||
if qstate.qinfo.qname_str.endswith("._dict_.cz."):
|
||||
|
||||
aword = ' '.join(qstate.qinfo.qname_list[0:-4])
|
||||
adict = qstate.qinfo.qname_list[-4]
|
||||
|
||||
log_info("pythonmod: dictionary look up; word:%s dict:%s" % (aword,adict))
|
||||
|
||||
words = []
|
||||
if (adict == "en") and (aword in en_dict):
|
||||
words = en_dict[aword] # EN -> CS
|
||||
if (adict == "cs") and (aword in cz_dict):
|
||||
words = cz_dict[aword] # CS -> EN
|
||||
|
||||
if len(words) and ((qstate.qinfo.qtype == RR_TYPE_TXT) or (qstate.qinfo.qtype == RR_TYPE_ANY)):
|
||||
|
||||
msg = DNSMessage(qstate.qinfo.qname_str, RR_TYPE_TXT, RR_CLASS_IN, PKT_RD | PKT_RA | PKT_AA)
|
||||
for w in words:
|
||||
msg.answer.append("%s 300 IN TXT \"%s\"" % (qstate.qinfo.qname_str,w.replace("\"","\\\"")))
|
||||
|
||||
if not msg.set_return_msg(qstate):
|
||||
qstate.ext_state[id] = MODULE_ERROR
|
||||
return True
|
||||
|
||||
qstate.return_rcode = RCODE_NOERROR
|
||||
qstate.ext_state[id] = MODULE_FINISHED
|
||||
return True
|
||||
|
||||
else:
|
||||
qstate.return_rcode = RCODE_SERVFAIL
|
||||
qstate.ext_state[id] = MODULE_FINISHED
|
||||
return True
|
||||
|
||||
else: #Pass on the unknown query to the iterator
|
||||
qstate.ext_state[id] = MODULE_WAIT_MODULE
|
||||
return True
|
||||
|
||||
elif event == MODULE_EVENT_MODDONE: #the iterator has finished
|
||||
#we don't need modify result
|
||||
qstate.ext_state[id] = MODULE_FINISHED
|
||||
return True
|
||||
|
||||
log_err("pythonmod: Unknown event")
|
||||
qstate.ext_state[id] = MODULE_ERROR
|
||||
return True
|
||||
|
||||
def inform_super(id, qstate, superqstate, qdata):
|
||||
return True
|
||||
|
6
pythonmod/examples/dict_data.txt
Normal file
6
pythonmod/examples/dict_data.txt
Normal file
@ -0,0 +1,6 @@
|
||||
* * web
|
||||
computer poèítaèový adj: Zdenìk Bro¾
|
||||
computer poèítaè n:
|
||||
domain doména n: Zdenìk Bro¾
|
||||
query otazník n: Zdenìk Bro¾
|
||||
network sí» n: [it.] poèítaèová
|
119
pythonmod/examples/log.py
Normal file
119
pythonmod/examples/log.py
Normal file
@ -0,0 +1,119 @@
|
||||
import os
|
||||
'''
|
||||
calc.py: Response packet logger
|
||||
|
||||
Copyright (c) 2009, Zdenek Vasicek (vasicek AT fit.vutbr.cz)
|
||||
Marek Vavrusa (xvavru00 AT stud.fit.vutbr.cz)
|
||||
|
||||
This software is open source.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the organization 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 REGENTS 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.
|
||||
'''
|
||||
|
||||
def dataHex(data, prefix=""):
|
||||
"""Converts binary string data to display representation form"""
|
||||
res = ""
|
||||
for i in range(0, (len(data)+15)/16):
|
||||
res += "%s0x%02X | " % (prefix, i*16)
|
||||
d = map(lambda x:ord(x), data[i*16:i*16+17])
|
||||
for ch in d:
|
||||
res += "%02X " % ch
|
||||
for i in range(0,17-len(d)):
|
||||
res += " "
|
||||
res += "| "
|
||||
for ch in d:
|
||||
if (ch < 32) or (ch > 127):
|
||||
res += ". "
|
||||
else:
|
||||
res += "%c " % ch
|
||||
res += "\n"
|
||||
return res
|
||||
|
||||
def logDnsMsg(qstate):
|
||||
"""Logs response"""
|
||||
|
||||
r = qstate.return_msg.rep
|
||||
q = qstate.return_msg.qinfo
|
||||
|
||||
print "-"*100
|
||||
print("Query: %s, type: %s (%d), class: %s (%d) " % (
|
||||
qstate.qinfo.qname_str, qstate.qinfo.qtype_str, qstate.qinfo.qtype,
|
||||
qstate.qinfo.qclass_str, qstate.qinfo.qclass))
|
||||
print "-"*100
|
||||
print "Return reply :: flags: %04X, QDcount: %d, Security:%d, TTL=%d" % (r.flags, r.qdcount, r.security, r.ttl)
|
||||
print " qinfo :: qname: %s %s, qtype: %s, qclass: %s" % (str(q.qname_list), q.qname_str, q.qtype_str, q.qclass_str)
|
||||
|
||||
if (r):
|
||||
print "Reply:"
|
||||
for i in range(0, r.rrset_count):
|
||||
rr = r.rrsets[i]
|
||||
|
||||
rk = rr.rk
|
||||
print i,":",rk.dname_list, rk.dname_str, "flags: %04X" % rk.flags,
|
||||
print "type:",rk.type_str,"(%d)" % ntohs(rk.type), "class:",rk.rrset_class_str,"(%d)" % ntohs(rk.rrset_class)
|
||||
|
||||
d = rr.entry.data
|
||||
for j in range(0,d.count+d.rrsig_count):
|
||||
print " ",j,":","TTL=",d.rr_ttl[j],
|
||||
if (j >= d.count): print "rrsig",
|
||||
print
|
||||
print dataHex(d.rr_data[j]," ")
|
||||
|
||||
print "-"*100
|
||||
|
||||
def init(id, cfg):
|
||||
log_info("pythonmod: init called, module id is %d port: %d script: %s" % (id, cfg.port, cfg.python_script))
|
||||
return True
|
||||
|
||||
def deinit(id):
|
||||
log_info("pythonmod: deinit called, module id is %d" % id)
|
||||
return True
|
||||
|
||||
def inform_super(id, qstate, superqstate, qdata):
|
||||
return True
|
||||
|
||||
def operate(id, event, qstate, qdata):
|
||||
log_info("pythonmod: operate called, id: %d, event:%s" % (id, strmodulevent(event)))
|
||||
|
||||
if (event == MODULE_EVENT_NEW) or (event == MODULE_EVENT_PASS):
|
||||
#Pass on the new event to the iterator
|
||||
qstate.ext_state[id] = MODULE_WAIT_MODULE
|
||||
return True
|
||||
|
||||
if event == MODULE_EVENT_MODDONE:
|
||||
#Iterator finished, show response (if any)
|
||||
|
||||
if (qstate.return_msg):
|
||||
logDnsMsg(qstate)
|
||||
|
||||
qstate.ext_state[id] = MODULE_FINISHED
|
||||
return True
|
||||
|
||||
qstate.ext_state[id] = MODULE_ERROR
|
||||
return True
|
||||
|
73
pythonmod/examples/resgen.py
Normal file
73
pythonmod/examples/resgen.py
Normal file
@ -0,0 +1,73 @@
|
||||
'''
|
||||
resgen.py: This example shows how to generate authoritative response
|
||||
|
||||
Copyright (c) 2009, Zdenek Vasicek (vasicek AT fit.vutbr.cz)
|
||||
Marek Vavrusa (xvavru00 AT stud.fit.vutbr.cz)
|
||||
|
||||
This software is open source.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the organization 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 REGENTS 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.
|
||||
'''
|
||||
def init(id, cfg): return True
|
||||
|
||||
def deinit(id): return True
|
||||
|
||||
def inform_super(id, qstate, superqstate, qdata): return True
|
||||
|
||||
def operate(id, event, qstate, qdata):
|
||||
if (event == MODULE_EVENT_NEW) or (event == MODULE_EVENT_PASS):
|
||||
if (qstate.qinfo.qname_str.endswith(".localdomain.")): #query name ends with localdomain
|
||||
#create instance of DNS message (packet) with given parameters
|
||||
msg = DNSMessage(qstate.qinfo.qname_str, RR_TYPE_A, RR_CLASS_IN, PKT_QR | PKT_RA | PKT_AA)
|
||||
#append RR
|
||||
if (qstate.qinfo.qtype == RR_TYPE_A) or (qstate.qinfo.qtype == RR_TYPE_ANY):
|
||||
msg.answer.append("%s 10 IN A 127.0.0.1" % qstate.qinfo.qname_str)
|
||||
#set qstate.return_msg
|
||||
if not msg.set_return_msg(qstate):
|
||||
qstate.ext_state[id] = MODULE_ERROR
|
||||
return True
|
||||
|
||||
#we don't need validation, result is valid
|
||||
qstate.return_msg.rep.security = 2
|
||||
|
||||
qstate.return_rcode = RCODE_NOERROR
|
||||
qstate.ext_state[id] = MODULE_FINISHED
|
||||
return True
|
||||
else:
|
||||
#pass the query to validator
|
||||
qstate.ext_state[id] = MODULE_WAIT_MODULE
|
||||
return True
|
||||
|
||||
if event == MODULE_EVENT_MODDONE:
|
||||
log_info("pythonmod: iterator module done")
|
||||
qstate.ext_state[id] = MODULE_FINISHED
|
||||
return True
|
||||
|
||||
log_err("pythonmod: bad event")
|
||||
qstate.ext_state[id] = MODULE_ERROR
|
||||
return True
|
88
pythonmod/examples/resmod.py
Normal file
88
pythonmod/examples/resmod.py
Normal file
@ -0,0 +1,88 @@
|
||||
'''
|
||||
resmod.py: This example shows how to modify the response from iterator
|
||||
|
||||
Copyright (c) 2009, Zdenek Vasicek (vasicek AT fit.vutbr.cz)
|
||||
Marek Vavrusa (xvavru00 AT stud.fit.vutbr.cz)
|
||||
|
||||
This software is open source.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the organization 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 REGENTS 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.
|
||||
'''
|
||||
|
||||
def init(id, cfg): return True
|
||||
|
||||
def deinit(id): return True
|
||||
|
||||
def inform_super(id, qstate, superqstate, qdata): return True
|
||||
|
||||
def setTTL(qstate, ttl):
|
||||
"""Updates return_msg TTL and the TTL of all the RRs"""
|
||||
if qstate.return_msg:
|
||||
qstate.return_msg.rep.ttl = ttl
|
||||
if (qstate.return_msg.rep):
|
||||
for i in range(0,qstate.return_msg.rep.rrset_count):
|
||||
d = qstate.return_msg.rep.rrsets[i].entry.data
|
||||
for j in range(0,d.count+d.rrsig_count):
|
||||
d.rr_ttl[j] = ttl
|
||||
|
||||
def operate(id, event, qstate, qdata):
|
||||
if (event == MODULE_EVENT_NEW) or (event == MODULE_EVENT_PASS):
|
||||
#pass the query to validator
|
||||
qstate.ext_state[id] = MODULE_WAIT_MODULE
|
||||
return True
|
||||
|
||||
if event == MODULE_EVENT_MODDONE:
|
||||
log_info("pythonmod: iterator module done")
|
||||
|
||||
if not qstate.return_msg:
|
||||
qstate.ext_state[id] = MODULE_FINISHED
|
||||
return True
|
||||
|
||||
#modify the response
|
||||
|
||||
qdn = qstate.qinfo.qname_str
|
||||
if qdn.endswith(".nic.cz."):
|
||||
#invalidate response in cache added by iterator
|
||||
#invalidateQueryInCache(qstate, qstate.return_msg.qinfo)
|
||||
|
||||
#modify TTL to 10 secs and store response in cache
|
||||
#setTTL(qstate, 5)
|
||||
#if not storeQueryInCache(qstate, qstate.return_msg.qinfo, qstate.return_msg.rep, 0):
|
||||
# qstate.ext_state[id] = MODULE_ERROR
|
||||
# return False
|
||||
|
||||
#modify TTL of response, which will be send to a) validator and then b) client
|
||||
setTTL(qstate, 10)
|
||||
qstate.return_rcode = RCODE_NOERROR
|
||||
|
||||
qstate.ext_state[id] = MODULE_FINISHED
|
||||
return True
|
||||
|
||||
log_err("pythonmod: bad event")
|
||||
qstate.ext_state[id] = MODULE_ERROR
|
||||
return True
|
803
pythonmod/interface.i
Normal file
803
pythonmod/interface.i
Normal file
@ -0,0 +1,803 @@
|
||||
/*
|
||||
* interface.i: unbound python module
|
||||
*/
|
||||
|
||||
%module Unbound
|
||||
%{
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <stdarg.h>
|
||||
#include "config.h"
|
||||
#include "util/log.h"
|
||||
#include "util/module.h"
|
||||
#include "util/regional.h"
|
||||
#include "util/config_file.h"
|
||||
#include "util/data/msgreply.h"
|
||||
#include "util/data/packed_rrset.h"
|
||||
#include "util/storage/lruhash.h"
|
||||
#include "services/cache/dns.h"
|
||||
%}
|
||||
|
||||
%include "stdint.i" // uint_16_t can be known type now
|
||||
|
||||
%inline %{
|
||||
//converts [len][data][len][data][0] string to a List of labels (PyStrings)
|
||||
PyObject* GetNameAsLabelList(const char* name, int len) {
|
||||
PyObject* list;
|
||||
int cnt=0, i;
|
||||
|
||||
i = 0;
|
||||
while (i < len) {
|
||||
i += name[i] + 1;
|
||||
cnt++;
|
||||
}
|
||||
|
||||
list = PyList_New(cnt);
|
||||
i = 0; cnt = 0;
|
||||
while (i < len) {
|
||||
PyList_SetItem(list, cnt, PyString_FromStringAndSize(name + i + 1, name[i]));
|
||||
i += name[i] + 1;
|
||||
cnt++;
|
||||
}
|
||||
return list;
|
||||
}
|
||||
%}
|
||||
|
||||
/* ************************************************************************************ *
|
||||
Structure query_info
|
||||
* ************************************************************************************ */
|
||||
/* Query info */
|
||||
%ignore query_info::qname;
|
||||
%ignore query_info::qname_len;
|
||||
|
||||
|
||||
struct query_info {
|
||||
%immutable;
|
||||
char* qname;
|
||||
size_t qname_len;
|
||||
uint16_t qtype;
|
||||
uint16_t qclass;
|
||||
%mutable;
|
||||
};
|
||||
|
||||
%inline %{
|
||||
enum enum_rr_class {
|
||||
RR_CLASS_IN = 1,
|
||||
RR_CLASS_CH = 3,
|
||||
RR_CLASS_HS = 4,
|
||||
RR_CLASS_NONE = 254,
|
||||
RR_CLASS_ANY = 255,
|
||||
};
|
||||
|
||||
enum enum_rr_type {
|
||||
RR_TYPE_A = 1,
|
||||
RR_TYPE_NS = 2,
|
||||
RR_TYPE_MD = 3,
|
||||
RR_TYPE_MF = 4,
|
||||
RR_TYPE_CNAME = 5,
|
||||
RR_TYPE_SOA = 6,
|
||||
RR_TYPE_MB = 7,
|
||||
RR_TYPE_MG = 8,
|
||||
RR_TYPE_MR = 9,
|
||||
RR_TYPE_NULL = 10,
|
||||
RR_TYPE_WKS = 11,
|
||||
RR_TYPE_PTR = 12,
|
||||
RR_TYPE_HINFO = 13,
|
||||
RR_TYPE_MINFO = 14,
|
||||
RR_TYPE_MX = 15,
|
||||
RR_TYPE_TXT = 16,
|
||||
RR_TYPE_RP = 17,
|
||||
RR_TYPE_AFSDB = 18,
|
||||
RR_TYPE_X25 = 19,
|
||||
RR_TYPE_ISDN = 20,
|
||||
RR_TYPE_RT = 21,
|
||||
RR_TYPE_NSAP = 22,
|
||||
RR_TYPE_NSAP_PTR = 23,
|
||||
RR_TYPE_SIG = 24,
|
||||
RR_TYPE_KEY = 25,
|
||||
RR_TYPE_PX = 26,
|
||||
RR_TYPE_GPOS = 27,
|
||||
RR_TYPE_AAAA = 28,
|
||||
RR_TYPE_LOC = 29,
|
||||
RR_TYPE_NXT = 30,
|
||||
RR_TYPE_EID = 31,
|
||||
RR_TYPE_NIMLOC = 32,
|
||||
RR_TYPE_SRV = 33,
|
||||
RR_TYPE_ATMA = 34,
|
||||
RR_TYPE_NAPTR = 35,
|
||||
RR_TYPE_KX = 36,
|
||||
RR_TYPE_CERT = 37,
|
||||
RR_TYPE_A6 = 38,
|
||||
RR_TYPE_DNAME = 39,
|
||||
RR_TYPE_SINK = 40,
|
||||
RR_TYPE_OPT = 41,
|
||||
RR_TYPE_APL = 42,
|
||||
RR_TYPE_DS = 43,
|
||||
RR_TYPE_SSHFP = 44,
|
||||
RR_TYPE_IPSECKEY = 45,
|
||||
RR_TYPE_RRSIG = 46,
|
||||
RR_TYPE_NSEC = 47,
|
||||
RR_TYPE_DNSKEY = 48,
|
||||
RR_TYPE_DHCID = 49,
|
||||
RR_TYPE_NSEC3 = 50,
|
||||
RR_TYPE_NSEC3PARAMS = 51,
|
||||
RR_TYPE_UINFO = 100,
|
||||
RR_TYPE_UID = 101,
|
||||
RR_TYPE_GID = 102,
|
||||
RR_TYPE_UNSPEC = 103,
|
||||
RR_TYPE_TSIG = 250,
|
||||
RR_TYPE_IXFR = 251,
|
||||
RR_TYPE_AXFR = 252,
|
||||
RR_TYPE_MAILB = 253,
|
||||
RR_TYPE_MAILA = 254,
|
||||
RR_TYPE_ANY = 255,
|
||||
RR_TYPE_DLV = 32769,
|
||||
};
|
||||
|
||||
PyObject* _get_qname(struct query_info* q) {
|
||||
return PyString_FromStringAndSize(q->qname, q->qname_len);
|
||||
}
|
||||
|
||||
PyObject* _get_qname_components(struct query_info* q) {
|
||||
return GetNameAsLabelList(q->qname, q->qname_len);
|
||||
}
|
||||
%}
|
||||
|
||||
%inline %{
|
||||
PyObject* dnameAsStr(const char* dname) {
|
||||
char buf[LDNS_MAX_DOMAINLEN+1];
|
||||
buf[0] = '\0';
|
||||
dname_str(dname, buf);
|
||||
return PyString_FromString(buf);
|
||||
}
|
||||
%}
|
||||
|
||||
%extend query_info {
|
||||
%pythoncode %{
|
||||
def _get_qtype_str(self): return ldns_rr_type2str(self.qtype)
|
||||
__swig_getmethods__["qtype_str"] = _get_qtype_str
|
||||
if _newclass:qtype_str = _swig_property(_get_qtype_str)
|
||||
|
||||
def _get_qclass_str(self): return ldns_rr_class2str(self.qclass)
|
||||
__swig_getmethods__["qclass_str"] = _get_qclass_str
|
||||
if _newclass:qclass_str = _swig_property(_get_qclass_str)
|
||||
|
||||
__swig_getmethods__["qname"] = _Unbound._get_qname
|
||||
if _newclass:qname = _swig_property(_Unbound._get_qname)
|
||||
|
||||
__swig_getmethods__["qname_list"] = _Unbound._get_qname_components
|
||||
if _newclass:qname_list = _swig_property(_Unbound._get_qname_components)
|
||||
|
||||
def _get_qname_str(self): return dnameAsStr(self.qname)
|
||||
__swig_getmethods__["qname_str"] = _get_qname_str
|
||||
if _newclass:qname_str = _swig_property(_get_qname_str)
|
||||
%}
|
||||
}
|
||||
|
||||
/* ************************************************************************************ *
|
||||
Structure packed_rrset_key
|
||||
* ************************************************************************************ */
|
||||
%ignore packed_rrset_key::dname;
|
||||
%ignore packed_rrset_key::dname_len;
|
||||
|
||||
/* RRsets */
|
||||
struct packed_rrset_key {
|
||||
%immutable;
|
||||
char* dname;
|
||||
size_t dname_len;
|
||||
uint32_t flags;
|
||||
uint16_t type; //rrset type in network format
|
||||
uint16_t rrset_class; //rrset class in network format
|
||||
%mutable;
|
||||
};
|
||||
|
||||
//This subroutine converts values between the host and network byte order.
|
||||
//Specifically, ntohs() converts 16-bit quantities from network byte order to host byte order.
|
||||
uint16_t ntohs(uint16_t netshort);
|
||||
|
||||
%inline %{
|
||||
PyObject* _get_dname(struct packed_rrset_key* k) {
|
||||
return PyString_FromStringAndSize(k->dname, k->dname_len);
|
||||
}
|
||||
PyObject* _get_dname_components(struct packed_rrset_key* k) {
|
||||
return GetNameAsLabelList(k->dname, k->dname_len);
|
||||
}
|
||||
%}
|
||||
|
||||
%extend packed_rrset_key {
|
||||
%pythoncode %{
|
||||
def _get_type_str(self): return ldns_rr_type2str(_Unbound.ntohs(self.type))
|
||||
__swig_getmethods__["type_str"] = _get_type_str
|
||||
if _newclass:type_str = _swig_property(_get_type_str)
|
||||
|
||||
def _get_class_str(self): return ldns_rr_class2str(_Unbound.ntohs(self.rrset_class))
|
||||
__swig_getmethods__["rrset_class_str"] = _get_class_str
|
||||
if _newclass:rrset_class_str = _swig_property(_get_class_str)
|
||||
|
||||
__swig_getmethods__["dname"] = _Unbound._get_dname
|
||||
if _newclass:dname = _swig_property(_Unbound._get_dname)
|
||||
|
||||
__swig_getmethods__["dname_list"] = _Unbound._get_dname_components
|
||||
if _newclass:dname_list = _swig_property(_Unbound._get_dname_components)
|
||||
|
||||
def _get_dname_str(self): return dnameAsStr(self.dname)
|
||||
__swig_getmethods__["dname_str"] = _get_dname_str
|
||||
if _newclass:dname_str = _swig_property(_get_dname_str)
|
||||
%}
|
||||
}
|
||||
|
||||
#if defined(SWIGWORDSIZE64)
|
||||
typedef long int rrset_id_t;
|
||||
#else
|
||||
typedef long long int rrset_id_t;
|
||||
#endif
|
||||
|
||||
struct ub_packed_rrset_key {
|
||||
struct lruhash_entry entry;
|
||||
rrset_id_t id;
|
||||
struct packed_rrset_key rk;
|
||||
};
|
||||
|
||||
struct lruhash_entry {
|
||||
lock_rw_t lock;
|
||||
struct lruhash_entry* overflow_next;
|
||||
struct lruhash_entry* lru_next;
|
||||
struct lruhash_entry* lru_prev;
|
||||
hashvalue_t hash;
|
||||
void* key;
|
||||
struct packed_rrset_data* data;
|
||||
};
|
||||
|
||||
%ignore packed_rrset_data::rr_len;
|
||||
%ignore packed_rrset_data::rr_ttl;
|
||||
%ignore packed_rrset_data::rr_data;
|
||||
|
||||
struct packed_rrset_data {
|
||||
uint32_t ttl; //TTL (in seconds like time())
|
||||
|
||||
size_t count; //number of rrs
|
||||
size_t rrsig_count; //number of rrsigs
|
||||
|
||||
enum rrset_trust trust;
|
||||
enum sec_status security;
|
||||
|
||||
size_t* rr_len; //length of every rr's rdata
|
||||
uint32_t *rr_ttl; //ttl of every rr
|
||||
uint8_t** rr_data; //array of pointers to every rr's rdata; The rr_data[i] rdata is stored in uncompressed wireformat.
|
||||
};
|
||||
|
||||
%pythoncode %{
|
||||
class RRSetData_RRLen:
|
||||
def __init__(self, obj): self.obj = obj
|
||||
def __getitem__(self, index): return _Unbound._get_data_rr_len(self.obj, index)
|
||||
def __len__(self): return obj.count + obj.rrsig_count
|
||||
class RRSetData_RRTTL:
|
||||
def __init__(self, obj): self.obj = obj
|
||||
def __getitem__(self, index): return _Unbound._get_data_rr_ttl(self.obj, index)
|
||||
def __setitem__(self, index, value): _Unbound._set_data_rr_ttl(self.obj, index, value)
|
||||
def __len__(self): return obj.count + obj.rrsig_count
|
||||
class RRSetData_RRData:
|
||||
def __init__(self, obj): self.obj = obj
|
||||
def __getitem__(self, index): return _Unbound._get_data_rr_data(self.obj, index)
|
||||
def __len__(self): return obj.count + obj.rrsig_count
|
||||
%}
|
||||
|
||||
%inline %{
|
||||
PyObject* _get_data_rr_len(struct packed_rrset_data* d, int idx) {
|
||||
if ((d != NULL) && (idx >= 0) && (idx < (d->count+d->rrsig_count)))
|
||||
return PyInt_FromLong(d->rr_len[idx]);
|
||||
return Py_None;
|
||||
}
|
||||
void _set_data_rr_ttl(struct packed_rrset_data* d, int idx, uint32_t ttl)
|
||||
{
|
||||
if ((d != NULL) && (idx >= 0) && (idx < (d->count+d->rrsig_count)))
|
||||
d->rr_ttl[idx] = ttl;
|
||||
}
|
||||
PyObject* _get_data_rr_ttl(struct packed_rrset_data* d, int idx) {
|
||||
if ((d != NULL) && (idx >= 0) && (idx < (d->count+d->rrsig_count)))
|
||||
return PyInt_FromLong(d->rr_ttl[idx]);
|
||||
return Py_None;
|
||||
}
|
||||
PyObject* _get_data_rr_data(struct packed_rrset_data* d, int idx) {
|
||||
if ((d != NULL) && (idx >= 0) && (idx < (d->count+d->rrsig_count)))
|
||||
return PyString_FromStringAndSize(d->rr_data[idx],d->rr_len[idx]);
|
||||
return Py_None;
|
||||
}
|
||||
%}
|
||||
|
||||
%extend packed_rrset_data {
|
||||
%pythoncode %{
|
||||
def _get_data_rr_len(self): return RRSetData_RRLen(self)
|
||||
__swig_getmethods__["rr_len"] = _get_data_rr_len
|
||||
if _newclass:rr_len = _swig_property(_get_data_rr_len)
|
||||
def _get_data_rr_ttl(self): return RRSetData_RRTTL(self)
|
||||
__swig_getmethods__["rr_ttl"] =_get_data_rr_ttl
|
||||
if _newclass:rr_len = _swig_property(_get_data_rr_ttl)
|
||||
def _get_data_rr_data(self): return RRSetData_RRData(self)
|
||||
__swig_getmethods__["rr_data"] = _get_data_rr_data
|
||||
if _newclass:rr_len = _swig_property(_get_data_rr_data)
|
||||
%}
|
||||
}
|
||||
|
||||
/* ************************************************************************************ *
|
||||
Structure reply_info
|
||||
* ************************************************************************************ */
|
||||
/* Messages */
|
||||
%ignore reply_info::rrsets;
|
||||
%ignore reply_info::ref;
|
||||
|
||||
struct reply_info {
|
||||
uint16_t flags;
|
||||
uint16_t qdcount;
|
||||
uint32_t ttl;
|
||||
|
||||
uint16_t authoritative;
|
||||
enum sec_status security;
|
||||
|
||||
size_t an_numrrsets;
|
||||
size_t ns_numrrsets;
|
||||
size_t ar_numrrsets;
|
||||
size_t rrset_count; // an_numrrsets + ns_numrrsets + ar_numrrsets
|
||||
|
||||
struct ub_packed_rrset_key** rrsets;
|
||||
struct rrset_ref ref[1]; //?
|
||||
};
|
||||
|
||||
struct rrset_ref {
|
||||
struct ub_packed_rrset_key* key;
|
||||
rrset_id_t id;
|
||||
};
|
||||
|
||||
struct dns_msg {
|
||||
struct query_info qinfo;
|
||||
struct reply_info *rep;
|
||||
};
|
||||
|
||||
%pythoncode %{
|
||||
class ReplyInfo_RRSet:
|
||||
def __init__(self, obj): self.obj = obj
|
||||
def __getitem__(self, index): return _Unbound._rrset_rrsets_get(self.obj, index)
|
||||
def __len__(self): return obj.rrset_count
|
||||
|
||||
class ReplyInfo_Ref:
|
||||
def __init__(self, obj): self.obj = obj
|
||||
def __getitem__(self, index): return _Unbound._rrset_ref_get(self.obj, index)
|
||||
def __len__(self): return obj.rrset_count
|
||||
%}
|
||||
|
||||
%inline %{
|
||||
struct ub_packed_rrset_key* _rrset_rrsets_get(struct reply_info* r, int idx) {
|
||||
if ((r != NULL) && (idx >= 0) && (idx < r->rrset_count))
|
||||
return r->rrsets[idx];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct rrset_ref* _rrset_ref_get(struct reply_info* r, int idx) {
|
||||
if ((r != NULL) && (idx >= 0) && (idx < r->rrset_count)) {
|
||||
//printf("_rrset_ref_get: %lX key:%lX\n", r->ref + idx, r->ref[idx].key);
|
||||
return &(r->ref[idx]);
|
||||
// return &(r->ref[idx]);
|
||||
}
|
||||
//printf("_rrset_ref_get: NULL\n");
|
||||
return NULL;
|
||||
}
|
||||
%}
|
||||
|
||||
%extend reply_info {
|
||||
%pythoncode %{
|
||||
def _rrset_ref_get(self): return ReplyInfo_Ref(self)
|
||||
__swig_getmethods__["ref"] = _rrset_ref_get
|
||||
if _newclass:ref = _swig_property(_rrset_ref_get)
|
||||
|
||||
def _rrset_rrsets_get(self): return ReplyInfo_RRSet(self)
|
||||
__swig_getmethods__["rrsets"] = _rrset_rrsets_get
|
||||
if _newclass:rrsets = _swig_property(_rrset_rrsets_get)
|
||||
%}
|
||||
}
|
||||
|
||||
/* ************************************************************************************ *
|
||||
Structure module_qstate
|
||||
* ************************************************************************************ */
|
||||
%ignore module_qstate::ext_state;
|
||||
%ignore module_qstate::minfo;
|
||||
|
||||
/* Query state */
|
||||
struct module_qstate {
|
||||
struct query_info qinfo;
|
||||
uint16_t query_flags; //See QF_BIT_xx constants
|
||||
int is_priming;
|
||||
|
||||
struct comm_reply* reply;
|
||||
struct dns_msg* return_msg;
|
||||
int return_rcode;
|
||||
struct regional* region; /* unwrapped */
|
||||
|
||||
int curmod;
|
||||
|
||||
enum module_ext_state ext_state[MAX_MODULE];
|
||||
void* minfo[MAX_MODULE];
|
||||
|
||||
struct module_env* env; /* unwrapped */
|
||||
struct mesh_state* mesh_info;
|
||||
};
|
||||
|
||||
%constant int MODULE_COUNT = MAX_MODULE;
|
||||
|
||||
%constant int QF_BIT_CD = 0x0010;
|
||||
%constant int QF_BIT_AD = 0x0020;
|
||||
%constant int QF_BIT_Z = 0x0040;
|
||||
%constant int QF_BIT_RA = 0x0080;
|
||||
%constant int QF_BIT_RD = 0x0100;
|
||||
%constant int QF_BIT_TC = 0x0200;
|
||||
%constant int QF_BIT_AA = 0x0400;
|
||||
%constant int QF_BIT_QR = 0x8000;
|
||||
|
||||
%inline %{
|
||||
enum enum_return_rcode {
|
||||
RCODE_NOERROR = 0,
|
||||
RCODE_FORMERR = 1,
|
||||
RCODE_SERVFAIL = 2,
|
||||
RCODE_NXDOMAIN = 3,
|
||||
RCODE_NOTIMPL = 4,
|
||||
RCODE_REFUSED = 5,
|
||||
RCODE_YXDOMAIN = 6,
|
||||
RCODE_YXRRSET = 7,
|
||||
RCODE_NXRRSET = 8,
|
||||
RCODE_NOTAUTH = 9,
|
||||
RCODE_NOTZONE = 10
|
||||
};
|
||||
%}
|
||||
|
||||
%pythoncode %{
|
||||
class ExtState:
|
||||
def __init__(self, obj): self.obj = obj
|
||||
def __str__(self):
|
||||
return ", ".join([_Unbound.strextstate(_Unbound._ext_state_get(self.obj,a)) for a in range(0, _Unbound.MODULE_COUNT)])
|
||||
def __getitem__(self, index): return _Unbound._ext_state_get(self.obj, index)
|
||||
def __setitem__(self, index, value): _Unbound._ext_state_set(self.obj, index, value)
|
||||
def __len__(self): return _Unbound.MODULE_COUNT
|
||||
%}
|
||||
|
||||
%inline %{
|
||||
enum module_ext_state _ext_state_get(struct module_qstate* q, int idx) {
|
||||
if ((q != NULL) && (idx >= 0) && (idx < MAX_MODULE)) {
|
||||
return q->ext_state[idx];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void _ext_state_set(struct module_qstate* q, int idx, enum module_ext_state state) {
|
||||
if ((q != NULL) && (idx >= 0) && (idx < MAX_MODULE)) {
|
||||
q->ext_state[idx] = state;
|
||||
}
|
||||
}
|
||||
%}
|
||||
|
||||
%extend module_qstate {
|
||||
%pythoncode %{
|
||||
def set_ext_state(self, id, state):
|
||||
"""Sets the ext state"""
|
||||
_Unbound._ext_state_set(self, id, state)
|
||||
|
||||
def __ext_state_get(self): return ExtState(self)
|
||||
__swig_getmethods__["ext_state"] = __ext_state_get
|
||||
if _newclass:ext_state = _swig_property(__ext_state_get)#, __ext_state_set)
|
||||
%}
|
||||
}
|
||||
|
||||
/* ************************************************************************************ *
|
||||
Structure config_strlist
|
||||
* ************************************************************************************ */
|
||||
struct config_strlist {
|
||||
struct config_strlist* next;
|
||||
char* str;
|
||||
};
|
||||
|
||||
/* ************************************************************************************ *
|
||||
Structure config_str2list
|
||||
* ************************************************************************************ */
|
||||
struct config_str2list {
|
||||
struct config_str2list* next;
|
||||
char* str;
|
||||
char* str2;
|
||||
};
|
||||
|
||||
/* ************************************************************************************ *
|
||||
Structure config_file
|
||||
* ************************************************************************************ */
|
||||
struct config_file {
|
||||
int verbosity;
|
||||
int stat_interval;
|
||||
int stat_cumulative;
|
||||
int stat_extended;
|
||||
int num_threads;
|
||||
int port;
|
||||
int do_ip4;
|
||||
int do_ip6;
|
||||
int do_udp;
|
||||
int do_tcp;
|
||||
int outgoing_num_ports;
|
||||
size_t outgoing_num_tcp;
|
||||
size_t incoming_num_tcp;
|
||||
int* outgoing_avail_ports;
|
||||
size_t msg_buffer_size;
|
||||
size_t msg_cache_size;
|
||||
size_t msg_cache_slabs;
|
||||
size_t num_queries_per_thread;
|
||||
size_t jostle_time;
|
||||
size_t rrset_cache_size;
|
||||
size_t rrset_cache_slabs;
|
||||
int host_ttl;
|
||||
int lame_ttl;
|
||||
size_t infra_cache_slabs;
|
||||
size_t infra_cache_numhosts;
|
||||
size_t infra_cache_lame_size;
|
||||
char* target_fetch_policy;
|
||||
int if_automatic;
|
||||
int num_ifs;
|
||||
char **ifs;
|
||||
int num_out_ifs;
|
||||
char **out_ifs;
|
||||
struct config_strlist* root_hints;
|
||||
struct config_stub* stubs;
|
||||
struct config_stub* forwards;
|
||||
struct config_strlist* donotqueryaddrs;
|
||||
struct config_str2list* acls;
|
||||
int donotquery_localhost;
|
||||
int harden_short_bufsize;
|
||||
int harden_large_queries;
|
||||
int harden_glue;
|
||||
int harden_dnssec_stripped;
|
||||
int harden_referral_path;
|
||||
int use_caps_bits_for_id;
|
||||
struct config_strlist* private_address;
|
||||
struct config_strlist* private_domain;
|
||||
size_t unwanted_threshold;
|
||||
char* chrootdir;
|
||||
char* username;
|
||||
char* directory;
|
||||
char* logfile;
|
||||
char* pidfile;
|
||||
int use_syslog;
|
||||
int hide_identity;
|
||||
int hide_version;
|
||||
char* identity;
|
||||
char* version;
|
||||
char* module_conf;
|
||||
struct config_strlist* trust_anchor_file_list;
|
||||
struct config_strlist* trust_anchor_list;
|
||||
struct config_strlist* trusted_keys_file_list;
|
||||
char* dlv_anchor_file;
|
||||
struct config_strlist* dlv_anchor_list;
|
||||
int max_ttl;
|
||||
int32_t val_date_override;
|
||||
int bogus_ttl;
|
||||
int val_clean_additional;
|
||||
int val_permissive_mode;
|
||||
char* val_nsec3_key_iterations;
|
||||
size_t key_cache_size;
|
||||
size_t key_cache_slabs;
|
||||
size_t neg_cache_size;
|
||||
struct config_str2list* local_zones;
|
||||
struct config_strlist* local_zones_nodefault;
|
||||
struct config_strlist* local_data;
|
||||
int remote_control_enable;
|
||||
struct config_strlist* control_ifs;
|
||||
int control_port;
|
||||
char* server_key_file;
|
||||
char* server_cert_file;
|
||||
char* control_key_file;
|
||||
char* control_cert_file;
|
||||
int do_daemonize;
|
||||
char* python_script;
|
||||
};
|
||||
|
||||
/* ************************************************************************************ *
|
||||
Enums
|
||||
* ************************************************************************************ */
|
||||
%rename ("MODULE_STATE_INITIAL") "module_state_initial";
|
||||
%rename ("MODULE_WAIT_REPLY") "module_wait_reply";
|
||||
%rename ("MODULE_WAIT_MODULE") "module_wait_module";
|
||||
%rename ("MODULE_WAIT_SUBQUERY") "module_wait_subquery";
|
||||
%rename ("MODULE_ERROR") "module_error";
|
||||
%rename ("MODULE_FINISHED") "module_finished";
|
||||
|
||||
enum module_ext_state {
|
||||
module_state_initial = 0,
|
||||
module_wait_reply,
|
||||
module_wait_module,
|
||||
module_wait_subquery,
|
||||
module_error,
|
||||
module_finished
|
||||
};
|
||||
|
||||
%rename ("MODULE_EVENT_NEW") "module_event_new";
|
||||
%rename ("MODULE_EVENT_PASS") "module_event_pass";
|
||||
%rename ("MODULE_EVENT_REPLY") "module_event_reply";
|
||||
%rename ("MODULE_EVENT_NOREPLY") "module_event_noreply";
|
||||
%rename ("MODULE_EVENT_CAPSFAIL") "module_event_capsfail";
|
||||
%rename ("MODULE_EVENT_MODDONE") "module_event_moddone";
|
||||
%rename ("MODULE_EVENT_ERROR") "module_event_error";
|
||||
|
||||
enum module_ev {
|
||||
module_event_new = 0,
|
||||
module_event_pass,
|
||||
module_event_reply,
|
||||
module_event_noreply,
|
||||
module_event_capsfail,
|
||||
module_event_moddone,
|
||||
module_event_error
|
||||
};
|
||||
|
||||
enum sec_status {
|
||||
sec_status_unchecked = 0,
|
||||
sec_status_bogus,
|
||||
sec_status_indeterminate,
|
||||
sec_status_insecure,
|
||||
sec_status_secure
|
||||
};
|
||||
|
||||
enum verbosity_value {
|
||||
NO_VERBOSE = 0,
|
||||
VERB_OPS,
|
||||
VERB_DETAIL,
|
||||
VERB_QUERY,
|
||||
VERB_ALGO
|
||||
};
|
||||
|
||||
%{
|
||||
int checkList(PyObject *l)
|
||||
{
|
||||
PyObject* item;
|
||||
int i;
|
||||
|
||||
if (l == Py_None)
|
||||
return 1;
|
||||
|
||||
if (PyList_Check(l))
|
||||
{
|
||||
for (i=0; i < PyList_Size(l); i++)
|
||||
{
|
||||
item = PyList_GetItem(l, i);
|
||||
if (!PyString_Check(item))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ldns_rr_list* createRRList(PyObject *l, uint32_t default_ttl)
|
||||
{
|
||||
PyObject* item;
|
||||
ldns_status status;
|
||||
ldns_rr_list* rr_list;
|
||||
ldns_rr* rr;
|
||||
int i;
|
||||
|
||||
if (PyList_Size(l) == 0)
|
||||
return NULL;
|
||||
|
||||
rr_list = ldns_rr_list_new();
|
||||
|
||||
for (i=0; i < PyList_Size(l); i++)
|
||||
{
|
||||
item = PyList_GetItem(l, i);
|
||||
|
||||
status = ldns_rr_new_frm_str(&rr, PyString_AsString(item), default_ttl, 0, 0);
|
||||
if (status != LDNS_STATUS_OK)
|
||||
continue;
|
||||
|
||||
if (!ldns_rr_list_push_rr(rr_list, rr))
|
||||
continue;
|
||||
|
||||
}
|
||||
return rr_list;
|
||||
}
|
||||
|
||||
int set_return_msg(struct module_qstate* qstate,
|
||||
const char* rr_name, ldns_rr_type rr_type, ldns_rr_class rr_class , uint16_t flags, uint32_t default_ttl,
|
||||
PyObject* question, PyObject* answer, PyObject* authority, PyObject* additional)
|
||||
{
|
||||
ldns_pkt* pkt = 0;
|
||||
ldns_status status;
|
||||
ldns_rr_list* rr_list1 = 0,*rr_list2 = 0,*rr_list3 = 0,*rr_list4 = 0;
|
||||
ldns_buffer *qb = 0;
|
||||
struct dns_msg* m = 0;
|
||||
struct msg_parse* p = 0;
|
||||
int res = 1;
|
||||
|
||||
if ((!checkList(question)) || (!checkList(answer)) || (!checkList(authority)) || (!checkList(additional)))
|
||||
return 0;
|
||||
|
||||
status = ldns_pkt_query_new_frm_str(&pkt, rr_name, rr_type, rr_class, flags);
|
||||
if ((status != LDNS_STATUS_OK) || (pkt == 0))
|
||||
return 0;
|
||||
|
||||
rr_list1 = createRRList(question, default_ttl);
|
||||
if ((rr_list1) && (res)) res = ldns_pkt_push_rr_list(pkt, LDNS_SECTION_QUESTION, rr_list1);
|
||||
rr_list2 = createRRList(answer, default_ttl);
|
||||
if ((rr_list2) && (res)) res = ldns_pkt_push_rr_list(pkt, LDNS_SECTION_ANSWER, rr_list2);
|
||||
rr_list3 = createRRList(authority, default_ttl);
|
||||
if ((rr_list3) && (res)) res = ldns_pkt_push_rr_list(pkt, LDNS_SECTION_AUTHORITY, rr_list3);
|
||||
rr_list4 = createRRList(additional, default_ttl);
|
||||
if ((rr_list4) && (res)) res = ldns_pkt_push_rr_list(pkt, LDNS_SECTION_ADDITIONAL, rr_list4);
|
||||
|
||||
if ((res) && ((qb = ldns_buffer_new(LDNS_MIN_BUFLEN)) == 0)) res = 0;
|
||||
if ((res) && (ldns_pkt2buffer_wire(qb, pkt) != LDNS_STATUS_OK)) res = 0;
|
||||
|
||||
if (res) res = createResponse(qstate, qb);
|
||||
|
||||
if (qb) ldns_buffer_free(qb);
|
||||
|
||||
ldns_pkt_free(pkt); //this function dealocates pkt as well as rr_lists
|
||||
return res;
|
||||
}
|
||||
%}
|
||||
|
||||
%constant uint16_t PKT_QR = 1; /* QueRy - query flag */
|
||||
%constant uint16_t PKT_AA = 2; /* Authoritative Answer - server flag */
|
||||
%constant uint16_t PKT_TC = 4; /* TrunCated - server flag */
|
||||
%constant uint16_t PKT_RD = 8; /* Recursion Desired - query flag */
|
||||
%constant uint16_t PKT_CD = 16; /* Checking Disabled - query flag */
|
||||
%constant uint16_t PKT_RA = 32; /* Recursion Available - server flag */
|
||||
%constant uint16_t PKT_AD = 64; /* Authenticated Data - server flag */
|
||||
|
||||
int set_return_msg(struct module_qstate* qstate,
|
||||
const char* rr_name, int rr_type, int rr_class , uint16_t flags, uint32_t default_ttl,
|
||||
PyObject* question, PyObject* answer, PyObject* authority, PyObject* additional);
|
||||
|
||||
%pythoncode %{
|
||||
class DNSMessage:
|
||||
def __init__(self, rr_name, rr_type, rr_class = RR_CLASS_IN, query_flags = 0, default_ttl = 0):
|
||||
"""Query flags is a combination of PKT_xx contants"""
|
||||
self.rr_name = rr_name
|
||||
self.rr_type = rr_type
|
||||
self.rr_class = rr_class
|
||||
self.default_ttl = default_ttl
|
||||
self.query_flags = query_flags
|
||||
self.question = []
|
||||
self.answer = []
|
||||
self.authority = []
|
||||
self.additional = []
|
||||
|
||||
def set_return_msg(self, qstate):
|
||||
"""Returns 1 if OK"""
|
||||
status = _Unbound.set_return_msg(qstate, self.rr_name, self.rr_type, self.rr_class,
|
||||
self.query_flags, self.default_ttl,
|
||||
self.question, self.answer, self.authority, self.additional)
|
||||
|
||||
if (status) and (PKT_AA & self.query_flags):
|
||||
qstate.return_msg.rep.authoritative = 1
|
||||
|
||||
return status
|
||||
|
||||
%}
|
||||
/* ************************************************************************************ *
|
||||
Functions
|
||||
* ************************************************************************************ */
|
||||
|
||||
// Various debuging functions
|
||||
void verbose(enum verbosity_value level, const char* format, ...);
|
||||
void log_info(const char* format, ...);
|
||||
void log_err(const char* format, ...);
|
||||
void log_warn(const char* format, ...);
|
||||
void log_hex(const char* msg, void* data, size_t length);
|
||||
void log_dns_msg(const char* str, struct query_info* qinfo, struct reply_info* rep);
|
||||
void log_query_info(enum verbosity_value v, const char* str, struct query_info* qinf);
|
||||
void regional_log_stats(struct regional *r);
|
||||
|
||||
// LDNS functions
|
||||
char *ldns_rr_type2str(const uint16_t atype);
|
||||
char *ldns_rr_class2str(const uint16_t aclass);
|
||||
|
||||
// Functions from pythonmod_utils
|
||||
int storeQueryInCache(struct module_qstate* qstate, struct query_info* qinfo, struct reply_info* msgrep, int is_referral);
|
||||
void invalidateQueryInCache(struct module_qstate* qstate, struct query_info* qinfo);
|
||||
|
||||
// Module conversion functions
|
||||
const char* strextstate(enum module_ext_state s);
|
||||
const char* strmodulevent(enum module_ev e);
|
292
pythonmod/pythonmod.c
Normal file
292
pythonmod/pythonmod.c
Normal file
@ -0,0 +1,292 @@
|
||||
/*
|
||||
* pythonmod.c: unbound module C wrapper
|
||||
*
|
||||
* Copyright (c) 2009, Zdenek Vasicek (vasicek AT fit.vutbr.cz)
|
||||
* Marek Vavrusa (xvavru00 AT stud.fit.vutbr.cz)
|
||||
*
|
||||
* This software is open source.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the organization 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 REGENTS 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 "config.h"
|
||||
#include "pythonmod/pythonmod.h"
|
||||
#include "util/module.h"
|
||||
#include "util/config_file.h"
|
||||
#include "pythonmod_utils.h"
|
||||
#include <Python.h>
|
||||
|
||||
// Generated
|
||||
#include "pythonmod/interface.h"
|
||||
|
||||
int pythonmod_init(struct module_env* env, int id)
|
||||
{
|
||||
// Initialize module
|
||||
struct pythonmod_env* pe = (struct pythonmod_env*)calloc(1, sizeof(struct pythonmod_env));
|
||||
if (!pe)
|
||||
{
|
||||
log_err("pythonmod: malloc failure");
|
||||
return 0;
|
||||
}
|
||||
|
||||
env->modinfo[id] = (void*) pe;
|
||||
pe->fname = NULL;
|
||||
pe->module = NULL;
|
||||
pe->dict = NULL;
|
||||
pe->data = NULL;
|
||||
pe->qstate = NULL;
|
||||
|
||||
// Initialize module
|
||||
if ((pe->fname = env->cfg->python_script) == NULL)
|
||||
{
|
||||
log_err("pythonmod: no script given.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Initialize Python libraries
|
||||
if (!Py_IsInitialized())
|
||||
{
|
||||
Py_SetProgramName("unbound");
|
||||
Py_NoSiteFlag = 1;
|
||||
Py_Initialize();
|
||||
PyEval_InitThreads();
|
||||
PyEval_ReleaseLock();
|
||||
SWIG_init();
|
||||
}
|
||||
|
||||
// Initialize Python
|
||||
PyRun_SimpleString("import sys \n");
|
||||
PyRun_SimpleString("sys.path.append('.') \n");
|
||||
PyRun_SimpleString("sys.path.append('"RUN_DIR"') \n");
|
||||
if (PyRun_SimpleString("from Unbound import *\n") < 0)
|
||||
{
|
||||
log_err("pythonmod: cannot initialize core module: Unbound.py");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Check Python file load
|
||||
FILE* script_py = NULL;
|
||||
if ((script_py = fopen(pe->fname, "r")) == NULL)
|
||||
{
|
||||
log_err("pythonmod: can't open file %s for reading", pe->fname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Load file
|
||||
pe->module = PyImport_AddModule("__main__");
|
||||
pe->dict = PyModule_GetDict(pe->module);
|
||||
pe->data = Py_None;
|
||||
Py_INCREF(pe->data);
|
||||
PyModule_AddObject(pe->module, "mod_env", pe->data);
|
||||
|
||||
//TODO: deallocation of pe->... if an error occurs
|
||||
|
||||
if (PyRun_SimpleFile(script_py, pe->fname) < 0)
|
||||
{
|
||||
log_err("pythonmod: can't parse Python script %s", pe->fname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fclose(script_py);
|
||||
|
||||
if ((pe->func_init = PyDict_GetItemString(pe->dict, "init")) == NULL)
|
||||
{
|
||||
log_err("pythonmod: function init is missing in %s", pe->fname);
|
||||
return 0;
|
||||
}
|
||||
if ((pe->func_deinit = PyDict_GetItemString(pe->dict, "deinit")) == NULL)
|
||||
{
|
||||
log_err("pythonmod: function deinit is missing in %s", pe->fname);
|
||||
return 0;
|
||||
}
|
||||
if ((pe->func_operate = PyDict_GetItemString(pe->dict, "operate")) == NULL)
|
||||
{
|
||||
log_err("pythonmod: function operate is missing in %s", pe->fname);
|
||||
return 0;
|
||||
}
|
||||
if ((pe->func_inform = PyDict_GetItemString(pe->dict, "inform_super")) == NULL)
|
||||
{
|
||||
log_err("pythonmod: function inform_super is missing in %s", pe->fname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyEval_AcquireLock();
|
||||
PyObject* py_cfg = SWIG_NewPointerObj((void*) env->cfg, SWIGTYPE_p_config_file, 0);
|
||||
PyObject* res = PyObject_CallFunction(pe->func_init, "iO", id, py_cfg);
|
||||
if (PyErr_Occurred())
|
||||
{
|
||||
log_err("pythonmod: Exception occurred in function init");
|
||||
PyErr_Print();
|
||||
}
|
||||
|
||||
Py_XDECREF(res);
|
||||
Py_XDECREF(py_cfg);
|
||||
PyEval_ReleaseLock();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void pythonmod_deinit(struct module_env* env, int id)
|
||||
{
|
||||
struct pythonmod_env* pe = env->modinfo[id];
|
||||
if(pe == NULL)
|
||||
return;
|
||||
|
||||
// Free Python resources
|
||||
if(pe->module != NULL)
|
||||
{
|
||||
// Deinit module
|
||||
PyEval_AcquireLock();
|
||||
PyObject* res = PyObject_CallFunction(pe->func_deinit, "i", id);
|
||||
if (PyErr_Occurred()) {
|
||||
log_err("pythonmod: Exception occurred in function deinit");
|
||||
PyErr_Print();
|
||||
}
|
||||
// Free result if any
|
||||
Py_XDECREF(res);
|
||||
// Free shared data if any
|
||||
Py_XDECREF(pe->data);
|
||||
|
||||
Py_Finalize();
|
||||
}
|
||||
|
||||
// Module is deallocated in Python
|
||||
env->modinfo[id] = NULL;
|
||||
}
|
||||
|
||||
void pythonmod_inform_super(struct module_qstate* qstate, int id, struct module_qstate* super)
|
||||
{
|
||||
struct pythonmod_env* pe = (struct pythonmod_env*)qstate->env->modinfo[id];
|
||||
struct pythonmod_qstate* pq = (struct pythonmod_qstate*)qstate->minfo[id];
|
||||
|
||||
log_query_info(VERB_ALGO, "pythonmod: inform_super, sub is", &qstate->qinfo);
|
||||
log_query_info(VERB_ALGO, "super is", &super->qinfo);
|
||||
|
||||
PyObject* py_qstate = SWIG_NewPointerObj((void*) qstate, SWIGTYPE_p_module_qstate, 0);
|
||||
PyObject* py_sqstate = SWIG_NewPointerObj((void*) super, SWIGTYPE_p_module_qstate, 0);
|
||||
|
||||
PyEval_AcquireLock();
|
||||
PyObject* res = PyObject_CallFunction(pe->func_inform, "iOOO", id, py_qstate, py_sqstate, pq->data);
|
||||
|
||||
if (PyErr_Occurred())
|
||||
{
|
||||
log_err("pythonmod: Exception occurred in function inform_super");
|
||||
PyErr_Print();
|
||||
qstate->ext_state[id] = module_error;
|
||||
}
|
||||
else if ((res == NULL) || (!PyObject_IsTrue(res)))
|
||||
{
|
||||
log_err("pythonmod: python returned bad code in inform_super");
|
||||
qstate->ext_state[id] = module_error;
|
||||
}
|
||||
|
||||
Py_XDECREF(res);
|
||||
Py_XDECREF(py_sqstate);
|
||||
Py_XDECREF(py_qstate);
|
||||
|
||||
PyEval_ReleaseLock();
|
||||
}
|
||||
|
||||
void pythonmod_operate(struct module_qstate* qstate, enum module_ev event, int id, struct outbound_entry* outbound)
|
||||
{
|
||||
struct pythonmod_env* pe = (struct pythonmod_env*)qstate->env->modinfo[id];
|
||||
struct pythonmod_qstate* pq = (struct pythonmod_qstate*)qstate->minfo[id];
|
||||
|
||||
if ( pq == NULL)
|
||||
{
|
||||
// create qstate
|
||||
pq = qstate->minfo[id] = malloc(sizeof(struct pythonmod_qstate));
|
||||
|
||||
//Initialize per query data
|
||||
pq->data = Py_None;
|
||||
Py_INCREF(pq->data);
|
||||
}
|
||||
|
||||
// Lock Python
|
||||
PyEval_AcquireLock();
|
||||
|
||||
// Call operate
|
||||
PyObject* py_qstate = SWIG_NewPointerObj((void*) qstate, SWIGTYPE_p_module_qstate, 0);
|
||||
PyObject* res = PyObject_CallFunction(pe->func_operate, "iiOO", id, (int) event, py_qstate, pq->data);
|
||||
if (PyErr_Occurred())
|
||||
{
|
||||
log_err("pythonmod: Exception occurred in function operate, event: %s", strmodulevent(event));
|
||||
PyErr_Print();
|
||||
qstate->ext_state[id] = module_error;
|
||||
}
|
||||
else if ((res == NULL) || (!PyObject_IsTrue(res)))
|
||||
{
|
||||
log_err("pythonmod: python returned bad code, event: %s", strmodulevent(event));
|
||||
qstate->ext_state[id] = module_error;
|
||||
}
|
||||
Py_XDECREF(res);
|
||||
Py_XDECREF(py_qstate);
|
||||
|
||||
// Unlock Python
|
||||
PyEval_ReleaseLock();
|
||||
|
||||
}
|
||||
|
||||
void pythonmod_clear(struct module_qstate* qstate, int id)
|
||||
{
|
||||
if (qstate == NULL)
|
||||
return;
|
||||
|
||||
struct pythonmod_qstate* pq = qstate->minfo[id];
|
||||
log_info("pythonmod: clear, id: %d, pq:%lX", id, (unsigned long int)pq);
|
||||
if(pq != NULL)
|
||||
{
|
||||
Py_DECREF(pq->data);
|
||||
// Free qstate
|
||||
free(pq);
|
||||
}
|
||||
|
||||
qstate->minfo[id] = NULL;
|
||||
}
|
||||
|
||||
size_t pythonmod_get_mem(struct module_env* env, int id)
|
||||
{
|
||||
struct pythonmod_env* pe = (struct pythonmod_env*)env->modinfo[id];
|
||||
log_info("pythonmod: get_mem, id: %d, pe:%lX", id, (unsigned long int)pe);
|
||||
if(!pe)
|
||||
return 0;
|
||||
return sizeof(*pe);
|
||||
}
|
||||
|
||||
/**
|
||||
* The module function block
|
||||
*/
|
||||
static struct module_func_block pythonmod_block = {
|
||||
"python",
|
||||
&pythonmod_init, &pythonmod_deinit, &pythonmod_operate, &pythonmod_inform_super,
|
||||
&pythonmod_clear, &pythonmod_get_mem
|
||||
};
|
||||
|
||||
struct module_func_block* pythonmod_get_funcblock()
|
||||
{
|
||||
return &pythonmod_block;
|
||||
}
|
103
pythonmod/pythonmod.h
Normal file
103
pythonmod/pythonmod.h
Normal file
@ -0,0 +1,103 @@
|
||||
/*
|
||||
* pythonmod.h: module header file
|
||||
*
|
||||
* Copyright (c) 2009, Zdenek Vasicek (vasicek AT fit.vutbr.cz)
|
||||
* Marek Vavrusa (xvavru00 AT stud.fit.vutbr.cz)
|
||||
*
|
||||
* This software is open source.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the organization 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 REGENTS 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 PYTHONMOD_H
|
||||
#define PYTHONMOD_H
|
||||
#include "util/module.h"
|
||||
#include "services/outbound_list.h"
|
||||
#include <Python.h>
|
||||
|
||||
struct PyObject;
|
||||
|
||||
/**
|
||||
* Global state for the module.
|
||||
*/
|
||||
struct pythonmod_env {
|
||||
|
||||
/** Python script filename. */
|
||||
const char* fname;
|
||||
|
||||
/** Python module. */
|
||||
PyObject* module;
|
||||
|
||||
/** Module functions */
|
||||
PyObject* func_init;
|
||||
PyObject* func_deinit;
|
||||
PyObject* func_operate;
|
||||
PyObject* func_inform;
|
||||
|
||||
/** Python dictionary. */
|
||||
PyObject* dict;
|
||||
|
||||
/** Module data. */
|
||||
PyObject* data;
|
||||
|
||||
/** Module qstate. */
|
||||
struct module_qstate* qstate;
|
||||
};
|
||||
|
||||
/**
|
||||
* Per query state for the iterator module.
|
||||
*/
|
||||
struct pythonmod_qstate {
|
||||
|
||||
/** Module per query data. */
|
||||
PyObject* data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the module function block.
|
||||
* @return: function block with function pointers to module methods.
|
||||
*/
|
||||
struct module_func_block* pythonmod_get_funcblock();
|
||||
|
||||
/** python module init */
|
||||
int pythonmod_init(struct module_env* env, int id);
|
||||
|
||||
/** python module deinit */
|
||||
void pythonmod_deinit(struct module_env* env, int id);
|
||||
|
||||
/** python module operate on a query */
|
||||
void pythonmod_operate(struct module_qstate* qstate, enum module_ev event, int id, struct outbound_entry* outbound);
|
||||
|
||||
/** python module */
|
||||
void pythonmod_inform_super(struct module_qstate* qstate, int id, struct module_qstate* super);
|
||||
|
||||
/** python module cleanup query state */
|
||||
void pythonmod_clear(struct module_qstate* qstate, int id);
|
||||
|
||||
/** python module alloc size routine */
|
||||
size_t pythonmod_get_mem(struct module_env* env, int id);
|
||||
#endif /* PYTHONMOD_H */
|
144
pythonmod/pythonmod_utils.c
Normal file
144
pythonmod/pythonmod_utils.c
Normal file
@ -0,0 +1,144 @@
|
||||
/*
|
||||
* pythonmod_utils.c: utilities used by wrapper
|
||||
*
|
||||
* Copyright (c) 2009, Zdenek Vasicek (vasicek AT fit.vutbr.cz)
|
||||
* Marek Vavrusa (xvavru00 AT stud.fit.vutbr.cz)
|
||||
*
|
||||
* This software is open source.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the organization 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 REGENTS 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 "util/module.h"
|
||||
#include "util/net_help.h"
|
||||
#include "services/cache/dns.h"
|
||||
#include "util/data/msgparse.h"
|
||||
#include "util/data/msgreply.h"
|
||||
#include <Python.h>
|
||||
|
||||
/** Store the reply_info and query_info pair in message cache (qstate->msg_cache) */
|
||||
int storeQueryInCache(struct module_qstate* qstate, struct query_info* qinfo, struct reply_info* msgrep, int is_referral)
|
||||
{
|
||||
if (!msgrep)
|
||||
return 0;
|
||||
|
||||
if (msgrep->authoritative) //authoritative answer can't be stored in cache
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError, "Authoritative answer can't be stored");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return dns_cache_store(qstate->env, qinfo, msgrep, is_referral);
|
||||
}
|
||||
|
||||
/** Invalidate the message associated with query_info stored in message cache */
|
||||
void invalidateQueryInCache(struct module_qstate* qstate, struct query_info* qinfo)
|
||||
{
|
||||
hashvalue_t h;
|
||||
struct lruhash_entry* e;
|
||||
struct reply_info *r;
|
||||
size_t i, j;
|
||||
|
||||
h = query_info_hash(qinfo);
|
||||
if ((e=slabhash_lookup(qstate->env->msg_cache, h, qinfo, 0)))
|
||||
{
|
||||
r = (struct reply_info*)(e->data);
|
||||
if (r)
|
||||
{
|
||||
r->ttl = 0;
|
||||
for(i=0; i< r->rrset_count; i++)
|
||||
{
|
||||
struct packed_rrset_data* data = (struct packed_rrset_data*) r->ref[i].key->entry.data;
|
||||
if(i>0 && r->ref[i].key == r->ref[i-1].key)
|
||||
continue;
|
||||
|
||||
data->ttl = r->ttl;
|
||||
for(j=0; j<data->count + data->rrsig_count; j++)
|
||||
data->rr_ttl[j] = r->ttl;
|
||||
}
|
||||
}
|
||||
lock_rw_unlock(&e->lock);
|
||||
} else {
|
||||
log_info("invalidateQueryInCache: qinfo is not in cache");
|
||||
}
|
||||
}
|
||||
|
||||
/** Create response according to the ldns packet content */
|
||||
int createResponse(struct module_qstate* qstate, ldns_buffer* pkt)
|
||||
{
|
||||
struct msg_parse* prs;
|
||||
struct edns_data edns;
|
||||
|
||||
/* parse message */
|
||||
prs = (struct msg_parse*) regional_alloc(qstate->env->scratch, sizeof(struct msg_parse));
|
||||
if (!prs) {
|
||||
log_err("storeResponse: out of memory on incoming message");
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(prs, 0, sizeof(*prs));
|
||||
memset(&edns, 0, sizeof(edns));
|
||||
|
||||
ldns_buffer_set_position(pkt, 0);
|
||||
if (parse_packet(pkt, prs, qstate->env->scratch) != LDNS_RCODE_NOERROR) {
|
||||
verbose(VERB_ALGO, "storeResponse: parse error on reply packet");
|
||||
return 0;
|
||||
}
|
||||
/* edns is not examined, but removed from message to help cache */
|
||||
if(parse_extract_edns(prs, &edns) != LDNS_RCODE_NOERROR)
|
||||
return 0;
|
||||
|
||||
/* remove CD-bit, we asked for in case we handle validation ourself */
|
||||
prs->flags &= ~BIT_CD;
|
||||
|
||||
/* allocate response dns_msg in region */
|
||||
qstate->return_msg = (struct dns_msg*)regional_alloc(qstate->region, sizeof(struct dns_msg));
|
||||
if (!qstate->return_msg)
|
||||
return 0;
|
||||
|
||||
memset(qstate->return_msg, 0, sizeof(*qstate->return_msg));
|
||||
if(!parse_create_msg(pkt, prs, NULL, &(qstate->return_msg)->qinfo, &(qstate->return_msg)->rep, qstate->region)) {
|
||||
log_err("storeResponse: malloc failure: allocating incoming dns_msg");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Make sure that the RA flag is set (since the presence of
|
||||
* this module means that recursion is available) */
|
||||
//qstate->return_msg->rep->flags |= BIT_RA;
|
||||
|
||||
/* Clear the AA flag */
|
||||
/* FIXME: does this action go here or in some other module? */
|
||||
//qstate->return_msg->rep->flags &= ~BIT_AA;
|
||||
|
||||
/* make sure QR flag is on */
|
||||
//qstate->return_msg->rep->flags |= BIT_QR;
|
||||
|
||||
if(verbosity >= VERB_ALGO)
|
||||
log_dns_msg("storeResponse: packet:", &qstate->return_msg->qinfo, qstate->return_msg->rep);
|
||||
|
||||
return 1;
|
||||
}
|
75
pythonmod/pythonmod_utils.h
Normal file
75
pythonmod/pythonmod_utils.h
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* pythonmod_utils.h: utils header file
|
||||
*
|
||||
* Copyright (c) 2009, Zdenek Vasicek (vasicek AT fit.vutbr.cz)
|
||||
* Marek Vavrusa (xvavru00 AT stud.fit.vutbr.cz)
|
||||
*
|
||||
* This software is open source.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the organization 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 REGENTS 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 PYTHONMOD_UTILS_H
|
||||
#define PYTHONMOD_UTILS_H
|
||||
|
||||
#include "util/module.h"
|
||||
|
||||
/**
|
||||
* Store the reply_info and query_info pair in message cache (qstate->msg_cache)
|
||||
*
|
||||
* @param qstate: module environment
|
||||
* @param qinfo: query info, the query for which answer is stored.
|
||||
* @param msgrep: reply in dns_msg
|
||||
* @param is_referral: If true, then the given message to be stored is a
|
||||
* referral. The cache implementation may use this as a hint.
|
||||
* It will store only the RRsets, not the message.
|
||||
* @return 0 on alloc error (out of memory).
|
||||
*/
|
||||
int storeQueryInCache(struct module_qstate* qstate, struct query_info* qinfo, struct reply_info* msgrep, int is_referral);
|
||||
|
||||
|
||||
/**
|
||||
* Invalidate the message associated with query_info stored in message cache.
|
||||
*
|
||||
* This function invalidates the record in message cache associated with the given query only if such a record exists.
|
||||
*
|
||||
* @param qstate: module environment
|
||||
* @param qinfo: query info, the query for which answer is stored.
|
||||
*/
|
||||
void invalidateQueryInCache(struct module_qstate* qstate, struct query_info* qinfo);
|
||||
|
||||
/**
|
||||
* Create response according to the ldns packet content
|
||||
*
|
||||
* This function fills qstate.return_msg up with data of a given packet
|
||||
*
|
||||
* @param qstate: module environment
|
||||
* @param pkt: a ldns_buffer which contains ldns_packet data
|
||||
*/
|
||||
int createResponse(struct module_qstate* qstate, ldns_buffer* pkt);
|
||||
|
||||
#endif /* PYTHONMOD_UTILS_H */
|
438
pythonmod/test-calc.conf
Normal file
438
pythonmod/test-calc.conf
Normal file
@ -0,0 +1,438 @@
|
||||
#
|
||||
# Example configuration file.
|
||||
#
|
||||
# See unbound.conf(5) man page.
|
||||
#
|
||||
# this is a comment.
|
||||
|
||||
#Use this to include other text into the file.
|
||||
#include: "otherfile.conf"
|
||||
|
||||
# The server clause sets the main parameters.
|
||||
server:
|
||||
# whitespace is not necessary, but looks cleaner.
|
||||
|
||||
# verbosity number, 0 is least verbose. 1 is default.
|
||||
verbosity: 1
|
||||
|
||||
# print statistics to the log (for every thread) every N seconds.
|
||||
# Set to "" or 0 to disable. Default is disabled.
|
||||
# statistics-interval: 0
|
||||
|
||||
# enable cumulative statistics, without clearing them after printing.
|
||||
# statistics-cumulative: no
|
||||
|
||||
# enable extended statistics (query types, answer codes, status)
|
||||
# printed from unbound-control. default off, because of speed.
|
||||
# extended-statistics: no
|
||||
|
||||
# number of threads to create. 1 disables threading.
|
||||
# num-threads: 1
|
||||
|
||||
# specify the interfaces to answer queries from by ip-address.
|
||||
# The default is to listen to localhost (127.0.0.1 and ::1).
|
||||
# specify 0.0.0.0 and ::0 to bind to all available interfaces.
|
||||
# specify every interface on a new 'interface:' labelled line.
|
||||
# The listen interfaces are not changed on reload, only on restart.
|
||||
interface: 0.0.0.0
|
||||
# interface: 192.0.2.154
|
||||
# interface: 2001:DB8::5
|
||||
|
||||
# enable this feature to copy the source address of queries to reply.
|
||||
# Socket options are not supported on all platforms. experimental.
|
||||
# interface-automatic: no
|
||||
|
||||
# port to answer queries from
|
||||
# port: 53
|
||||
|
||||
# specify the interfaces to send outgoing queries to authoritative
|
||||
# server from by ip-address. If none, the default (all) interface
|
||||
# is used. Specify every interface on a 'outgoing-interface:' line.
|
||||
# outgoing-interface: 192.0.2.153
|
||||
# outgoing-interface: 2001:DB8::5
|
||||
# outgoing-interface: 2001:DB8::6
|
||||
|
||||
# number of ports to allocate per thread, determines the size of the
|
||||
# port range that can be open simultaneously.
|
||||
# outgoing-range: 256
|
||||
|
||||
# permit unbound to use this port number or port range for
|
||||
# making outgoing queries, using an outgoing interface.
|
||||
# outgoing-port-permit: 32768
|
||||
|
||||
# deny unbound the use this of port number or port range for
|
||||
# making outgoing queries, using an outgoing interface.
|
||||
# Use this to make sure unbound does not grab a UDP port that some
|
||||
# other server on this computer needs. The default is to avoid
|
||||
# IANA-assigned port numbers.
|
||||
# outgoing-port-avoid: "3200-3208"
|
||||
|
||||
# number of outgoing simultaneous tcp buffers to hold per thread.
|
||||
# outgoing-num-tcp: 10
|
||||
|
||||
# number of incoming simultaneous tcp buffers to hold per thread.
|
||||
# incoming-num-tcp: 10
|
||||
|
||||
# buffer size for handling DNS data. No messages larger than this
|
||||
# size can be sent or received, by UDP or TCP. In bytes.
|
||||
# msg-buffer-size: 65552
|
||||
|
||||
# the amount of memory to use for the message cache.
|
||||
# plain value in bytes or you can append k, m or G. default is "4Mb".
|
||||
# msg-cache-size: 4m
|
||||
|
||||
# the number of slabs to use for the message cache.
|
||||
# the number of slabs must be a power of 2.
|
||||
# more slabs reduce lock contention, but fragment memory usage.
|
||||
# msg-cache-slabs: 4
|
||||
|
||||
# the number of queries that a thread gets to service.
|
||||
# num-queries-per-thread: 1024
|
||||
|
||||
# if very busy, 50% queries run to completion, 50% get timeout in msec
|
||||
# jostle-timeout: 200
|
||||
|
||||
# the amount of memory to use for the RRset cache.
|
||||
# plain value in bytes or you can append k, m or G. default is "4Mb".
|
||||
# rrset-cache-size: 4m
|
||||
|
||||
# the number of slabs to use for the RRset cache.
|
||||
# the number of slabs must be a power of 2.
|
||||
# more slabs reduce lock contention, but fragment memory usage.
|
||||
# rrset-cache-slabs: 4
|
||||
|
||||
# the time to live (TTL) value cap for RRsets and messages in the
|
||||
# cache. Items are not cached for longer. In seconds.
|
||||
# cache-max-ttl: 86400
|
||||
|
||||
# the time to live (TTL) value for cached roundtrip times and
|
||||
# EDNS version information for hosts. In seconds.
|
||||
# infra-host-ttl: 900
|
||||
|
||||
# the time to live (TTL) value for cached lame delegations. In sec.
|
||||
# infra-lame-ttl: 900
|
||||
|
||||
# the number of slabs to use for the Infrastructure cache.
|
||||
# the number of slabs must be a power of 2.
|
||||
# more slabs reduce lock contention, but fragment memory usage.
|
||||
# infra-cache-slabs: 4
|
||||
|
||||
# the maximum number of hosts that are cached (roundtrip times, EDNS).
|
||||
# infra-cache-numhosts: 10000
|
||||
|
||||
# the maximum size of the lame zones cached per host. in bytes.
|
||||
# infra-cache-lame-size: 10k
|
||||
|
||||
# Enable IPv4, "yes" or "no".
|
||||
# do-ip4: yes
|
||||
|
||||
# Enable IPv6, "yes" or "no".
|
||||
# do-ip6: yes
|
||||
|
||||
# Enable UDP, "yes" or "no".
|
||||
# do-udp: yes
|
||||
|
||||
# Enable TCP, "yes" or "no".
|
||||
# do-tcp: yes
|
||||
|
||||
# Detach from the terminal, run in background, "yes" or "no".
|
||||
do-daemonize: no
|
||||
|
||||
# control which clients are allowed to make (recursive) queries
|
||||
# to this server. Specify classless netblocks with /size and action.
|
||||
# By default everything is refused, except for localhost.
|
||||
# Choose deny (drop message), refuse (polite error reply),
|
||||
# allow (recursive ok), allow_snoop (recursive and nonrecursive ok)
|
||||
access-control: 0.0.0.0/0 allow
|
||||
# access-control: 127.0.0.0/8 allow
|
||||
# access-control: ::0/0 refuse
|
||||
# access-control: ::1 allow
|
||||
# access-control: ::ffff:127.0.0.1 allow
|
||||
|
||||
# if given, a chroot(2) is done to the given directory.
|
||||
# i.e. you can chroot to the working directory, for example,
|
||||
# for extra security, but make sure all files are in that directory.
|
||||
#
|
||||
# If chroot is enabled, you should pass the configfile (from the
|
||||
# commandline) as a full path from the original root. After the
|
||||
# chroot has been performed the now defunct portion of the config
|
||||
# file path is removed to be able to reread the config after a reload.
|
||||
#
|
||||
# All other file paths (working dir, logfile, roothints, and
|
||||
# key files) can be specified in several ways:
|
||||
# o as an absolute path relative to the new root.
|
||||
# o as a relative path to the working directory.
|
||||
# o as an absolute path relative to the original root.
|
||||
# In the last case the path is adjusted to remove the unused portion.
|
||||
#
|
||||
# The pid file can be absolute and outside of the chroot, it is
|
||||
# written just prior to performing the chroot and dropping permissions.
|
||||
#
|
||||
# Additionally, unbound may need to access /dev/random (for entropy).
|
||||
# How to do this is specific to your OS.
|
||||
#
|
||||
# If you give "" no chroot is performed. The path must not end in a /.
|
||||
chroot: ""
|
||||
|
||||
# if given, user privileges are dropped (after binding port),
|
||||
# and the given username is assumed. Default is user "unbound".
|
||||
# If you give "" no privileges are dropped.
|
||||
username: ""
|
||||
|
||||
# the working directory. The relative files in this config are
|
||||
# relative to this directory. If you give "" the working directory
|
||||
# is not changed.
|
||||
directory: ""
|
||||
|
||||
# the log file, "" means log to stderr.
|
||||
# Use of this option sets use-syslog to "no".
|
||||
logfile: ""
|
||||
|
||||
# Log to syslog(3) if yes. The log facility LOG_DAEMON is used to
|
||||
# log to, with identity "unbound". If yes, it overrides the logfile.
|
||||
# use-syslog: yes
|
||||
|
||||
# the pid file. Can be an absolute path outside of chroot/work dir.
|
||||
pidfile: "unbound.pid"
|
||||
|
||||
# file to read root hints from.
|
||||
# get one from ftp://FTP.INTERNIC.NET/domain/named.cache
|
||||
# root-hints: ""
|
||||
|
||||
# enable to not answer id.server and hostname.bind queries.
|
||||
# hide-identity: no
|
||||
|
||||
# enable to not answer version.server and version.bind queries.
|
||||
# hide-version: no
|
||||
|
||||
# the identity to report. Leave "" or default to return hostname.
|
||||
# identity: ""
|
||||
|
||||
# the version to report. Leave "" or default to return package version.
|
||||
# version: ""
|
||||
|
||||
# the target fetch policy.
|
||||
# series of integers describing the policy per dependency depth.
|
||||
# The number of values in the list determines the maximum dependency
|
||||
# depth the recursor will pursue before giving up. Each integer means:
|
||||
# -1 : fetch all targets opportunistically,
|
||||
# 0: fetch on demand,
|
||||
# positive value: fetch that many targets opportunistically.
|
||||
# Enclose the list of numbers between quotes ("").
|
||||
# target-fetch-policy: "3 2 1 0 0"
|
||||
|
||||
# Harden against very small EDNS buffer sizes.
|
||||
# harden-short-bufsize: no
|
||||
|
||||
# Harden against unseemly large queries.
|
||||
# harden-large-queries: no
|
||||
|
||||
# Harden against out of zone rrsets, to avoid spoofing attempts.
|
||||
# harden-glue: yes
|
||||
|
||||
# Harden against receiving dnssec-stripped data. If you turn it
|
||||
# off, failing to validate dnskey data for a trustanchor will
|
||||
# trigger insecure mode for that zone (like without a trustanchor).
|
||||
# Default on, which insists on dnssec data for trust-anchored zones.
|
||||
# harden-dnssec-stripped: yes
|
||||
|
||||
# Harden the referral path by performing additional queries for
|
||||
# infrastructure data. Validates the replies (if possible).
|
||||
# Default off, because the lookups burden the server. Experimental
|
||||
# implementation of draft-wijngaards-dnsext-resolver-side-mitigation.
|
||||
# harden-referral-path: no
|
||||
|
||||
# Use 0x20-encoded random bits in the query to foil spoof attempts.
|
||||
# This feature is an experimental implementation of draft dns-0x20.
|
||||
# use-caps-for-id: no
|
||||
|
||||
# Enforce privacy of these addresses. Strips them away from answers.
|
||||
# It may cause DNSSEC validation to additionally mark it as bogus.
|
||||
# Protects against 'DNS Rebinding' (uses browser as network proxy).
|
||||
# Only 'private-domain' and 'local-data' names are allowed to have
|
||||
# these private addresses. No default.
|
||||
# private-address: 10.0.0.0/8
|
||||
# private-address: 172.16.0.0/12
|
||||
# private-address: 192.168.0.0/16
|
||||
# private-address: 192.254.0.0/16
|
||||
# private-address: fd00::/8
|
||||
# private-address: fe80::/10
|
||||
|
||||
# Allow the domain (and its subdomains) to contain private addresses.
|
||||
# local-data statements are allowed to contain private addresses too.
|
||||
# private-domain: "example.com"
|
||||
|
||||
# If nonzero, unwanted replies are not only reported in statistics,
|
||||
# but also a running total is kept per thread. If it reaches the
|
||||
# threshold, a warning is printed and a defensive action is taken,
|
||||
# the cache is cleared to flush potential poison out of it.
|
||||
# A suggested value is 10000000, the default is 0 (turned off).
|
||||
# unwanted-reply-threshold: 0
|
||||
|
||||
# Do not query the following addresses. No DNS queries are sent there.
|
||||
# List one address per entry. List classless netblocks with /size,
|
||||
# do-not-query-address: 127.0.0.1/8
|
||||
# do-not-query-address: ::1
|
||||
|
||||
# if yes, the above default do-not-query-address entries are present.
|
||||
# if no, localhost can be queried (for testing and debugging).
|
||||
# do-not-query-localhost: yes
|
||||
|
||||
# module configuration of the server. A string with identifiers
|
||||
# separated by spaces. "iterator" or "validator iterator"
|
||||
module-config: "validator python iterator"
|
||||
|
||||
# File with DLV trusted keys. Same format as trust-anchor-file.
|
||||
# There can be only one DLV configured, it is trusted from root down.
|
||||
# Download https://secure.isc.org/ops/dlv/dlv.isc.org.key
|
||||
# dlv-anchor-file: "dlv.isc.org.key"
|
||||
|
||||
# File with trusted keys for validation. Specify more than one file
|
||||
# with several entries, one file per entry.
|
||||
# Zone file format, with DS and DNSKEY entries.
|
||||
# trust-anchor-file: ""
|
||||
|
||||
# Trusted key for validation. DS or DNSKEY. specify the RR on a
|
||||
# single line, surrounded by "". TTL is ignored. class is IN default.
|
||||
# (These examples are from August 2007 and may not be valid anymore).
|
||||
# trust-anchor: "nlnetlabs.nl. DNSKEY 257 3 5 AQPzzTWMz8qSWIQlfRnPckx2BiVmkVN6LPupO3mbz7FhLSnm26n6iG9N Lby97Ji453aWZY3M5/xJBSOS2vWtco2t8C0+xeO1bc/d6ZTy32DHchpW 6rDH1vp86Ll+ha0tmwyy9QP7y2bVw5zSbFCrefk8qCUBgfHm9bHzMG1U BYtEIQ=="
|
||||
# trust-anchor: "jelte.nlnetlabs.nl. DS 42860 5 1 14D739EB566D2B1A5E216A0BA4D17FA9B038BE4A"
|
||||
|
||||
# File with trusted keys for validation. Specify more than one file
|
||||
# with several entries, one file per entry. Like trust-anchor-file
|
||||
# but has a different file format. Format is BIND-9 style format,
|
||||
# the trusted-keys { name flag proto algo "key"; }; clauses are read.
|
||||
# trusted-keys-file: ""
|
||||
|
||||
# Override the date for validation with a specific fixed date.
|
||||
# Do not set this unless you are debugging signature inception
|
||||
# and expiration. "" or "0" turns the feature off.
|
||||
# val-override-date: ""
|
||||
|
||||
# The time to live for bogus data, rrsets and messages. This avoids
|
||||
# some of the revalidation, until the time interval expires. in secs.
|
||||
# val-bogus-ttl: 60
|
||||
|
||||
# Should additional section of secure message also be kept clean of
|
||||
# unsecure data. Useful to shield the users of this validator from
|
||||
# potential bogus data in the additional section. All unsigned data
|
||||
# in the additional section is removed from secure messages.
|
||||
# val-clean-additional: yes
|
||||
|
||||
# Turn permissive mode on to permit bogus messages. Thus, messages
|
||||
# for which security checks failed will be returned to clients,
|
||||
# instead of SERVFAIL. It still performs the security checks, which
|
||||
# result in interesting log files and possibly the AD bit in
|
||||
# replies if the message is found secure. The default is off.
|
||||
# val-permissive-mode: no
|
||||
|
||||
# It is possible to configure NSEC3 maximum iteration counts per
|
||||
# keysize. Keep this table very short, as linear search is done.
|
||||
# A message with an NSEC3 with larger count is marked insecure.
|
||||
# List in ascending order the keysize and count values.
|
||||
# val-nsec3-keysize-iterations: "1024 150 2048 500 4096 2500"
|
||||
|
||||
# the amount of memory to use for the key cache.
|
||||
# plain value in bytes or you can append k, m or G. default is "4Mb".
|
||||
# key-cache-size: 4m
|
||||
|
||||
# the number of slabs to use for the key cache.
|
||||
# the number of slabs must be a power of 2.
|
||||
# more slabs reduce lock contention, but fragment memory usage.
|
||||
# key-cache-slabs: 4
|
||||
|
||||
# the amount of memory to use for the negative cache (used for DLV).
|
||||
# plain value in bytes or you can append k, m or G. default is "1Mb".
|
||||
# neg-cache-size: 1m
|
||||
|
||||
# a number of locally served zones can be configured.
|
||||
# local-zone: <zone> <type>
|
||||
# local-data: "<resource record string>"
|
||||
# o deny serves local data (if any), else, drops queries.
|
||||
# o refuse serves local data (if any), else, replies with error.
|
||||
# o static serves local data, else, nxdomain or nodata answer.
|
||||
# o transparent serves local data, else, resolves normally .
|
||||
# o redirect serves the zone data for any subdomain in the zone.
|
||||
# o nodefault can be used to normally resolve AS112 zones.
|
||||
#
|
||||
# defaults are localhost address, reverse for 127.0.0.1 and ::1
|
||||
# and nxdomain for AS112 zones. If you configure one of these zones
|
||||
# the default content is omitted, or you can omit it with 'nodefault'.
|
||||
#
|
||||
# If you configure local-data without specifying local-zone, by
|
||||
# default a transparent local-zone is created for the data.
|
||||
#
|
||||
# You can add locally served data with
|
||||
# local-zone: "local." static
|
||||
# local-data: "mycomputer.local. IN A 192.0.2.51"
|
||||
# local-data: 'mytext.local TXT "content of text record"'
|
||||
#
|
||||
# You can override certain queries with
|
||||
# local-data: "adserver.example.com A 127.0.0.1"
|
||||
#
|
||||
# You can redirect a domain to a fixed address with
|
||||
# (this makes example.com, www.example.com, etc, all go to 192.0.2.3)
|
||||
# local-zone: "example.com" redirect
|
||||
# local-data: "example.com A 192.0.2.3"
|
||||
#
|
||||
# Shorthand to make PTR records, "IPv4 name" or "IPv6 name".
|
||||
# You can also add PTR records using local-data directly, but then
|
||||
# you need to do the reverse notation yourself.
|
||||
# local-data-ptr: "192.0.2.3 www.example.com"
|
||||
|
||||
# Python config section
|
||||
python:
|
||||
# Script file to load
|
||||
python-script: "./examples/calc.py"
|
||||
|
||||
# Remote control config section.
|
||||
remote-control:
|
||||
# Enable remote control with unbound-control(8) here.
|
||||
# set up the keys and certificates with unbound-control-setup.
|
||||
# control-enable: no
|
||||
|
||||
# what interfaces are listened to for remote control.
|
||||
# give 0.0.0.0 and ::0 to listen to all interfaces.
|
||||
# control-interface: 127.0.0.1
|
||||
# control-interface: ::1
|
||||
|
||||
# port number for remote control operations.
|
||||
# control-port: 953
|
||||
|
||||
# unbound server key file.
|
||||
# server-key-file: "/usr/local/etc/unbound/unbound_server.key"
|
||||
|
||||
# unbound server certificate file.
|
||||
# server-cert-file: "/usr/local/etc/unbound/unbound_server.pem"
|
||||
|
||||
# unbound-control key file.
|
||||
# control-key-file: "/usr/local/etc/unbound/unbound_control.key"
|
||||
|
||||
# unbound-control certificate file.
|
||||
# control-cert-file: "/usr/local/etc/unbound/unbound_control.pem"
|
||||
|
||||
# Stub zones.
|
||||
# Create entries like below, to make all queries for 'example.com' and
|
||||
# 'example.org' go to the given list of nameservers. list zero or more
|
||||
# nameservers by hostname or by ipaddress. If you set stub-prime to yes,
|
||||
# the list is treated as priming hints (default is no).
|
||||
# stub-zone:
|
||||
# name: "example.com"
|
||||
# stub-addr: 192.0.2.68
|
||||
# stub-prime: "no"
|
||||
# stub-zone:
|
||||
# name: "example.org"
|
||||
# stub-host: ns.example.com.
|
||||
|
||||
# Forward zones
|
||||
# Create entries like below, to make all queries for 'example.com' and
|
||||
# 'example.org' go to the given list of servers. These servers have to handle
|
||||
# recursion to other nameservers. List zero or more nameservers by hostname
|
||||
# or by ipaddress. Use an entry with name "." to forward all queries.
|
||||
# forward-zone:
|
||||
# name: "example.com"
|
||||
# forward-addr: 192.0.2.68
|
||||
# forward-addr: 192.0.2.73@5355 # forward to port 5355.
|
||||
# forward-zone:
|
||||
# name: "example.org"
|
||||
# forward-host: fwd.example.com
|
438
pythonmod/test-dict.conf
Normal file
438
pythonmod/test-dict.conf
Normal file
@ -0,0 +1,438 @@
|
||||
#
|
||||
# Example configuration file.
|
||||
#
|
||||
# See unbound.conf(5) man page.
|
||||
#
|
||||
# this is a comment.
|
||||
|
||||
#Use this to include other text into the file.
|
||||
#include: "otherfile.conf"
|
||||
|
||||
# The server clause sets the main parameters.
|
||||
server:
|
||||
# whitespace is not necessary, but looks cleaner.
|
||||
|
||||
# verbosity number, 0 is least verbose. 1 is default.
|
||||
verbosity: 1
|
||||
|
||||
# print statistics to the log (for every thread) every N seconds.
|
||||
# Set to "" or 0 to disable. Default is disabled.
|
||||
# statistics-interval: 0
|
||||
|
||||
# enable cumulative statistics, without clearing them after printing.
|
||||
# statistics-cumulative: no
|
||||
|
||||
# enable extended statistics (query types, answer codes, status)
|
||||
# printed from unbound-control. default off, because of speed.
|
||||
# extended-statistics: no
|
||||
|
||||
# number of threads to create. 1 disables threading.
|
||||
# num-threads: 1
|
||||
|
||||
# specify the interfaces to answer queries from by ip-address.
|
||||
# The default is to listen to localhost (127.0.0.1 and ::1).
|
||||
# specify 0.0.0.0 and ::0 to bind to all available interfaces.
|
||||
# specify every interface on a new 'interface:' labelled line.
|
||||
# The listen interfaces are not changed on reload, only on restart.
|
||||
interface: 0.0.0.0
|
||||
# interface: 192.0.2.154
|
||||
# interface: 2001:DB8::5
|
||||
|
||||
# enable this feature to copy the source address of queries to reply.
|
||||
# Socket options are not supported on all platforms. experimental.
|
||||
# interface-automatic: no
|
||||
|
||||
# port to answer queries from
|
||||
# port: 53
|
||||
|
||||
# specify the interfaces to send outgoing queries to authoritative
|
||||
# server from by ip-address. If none, the default (all) interface
|
||||
# is used. Specify every interface on a 'outgoing-interface:' line.
|
||||
# outgoing-interface: 192.0.2.153
|
||||
# outgoing-interface: 2001:DB8::5
|
||||
# outgoing-interface: 2001:DB8::6
|
||||
|
||||
# number of ports to allocate per thread, determines the size of the
|
||||
# port range that can be open simultaneously.
|
||||
# outgoing-range: 256
|
||||
|
||||
# permit unbound to use this port number or port range for
|
||||
# making outgoing queries, using an outgoing interface.
|
||||
# outgoing-port-permit: 32768
|
||||
|
||||
# deny unbound the use this of port number or port range for
|
||||
# making outgoing queries, using an outgoing interface.
|
||||
# Use this to make sure unbound does not grab a UDP port that some
|
||||
# other server on this computer needs. The default is to avoid
|
||||
# IANA-assigned port numbers.
|
||||
# outgoing-port-avoid: "3200-3208"
|
||||
|
||||
# number of outgoing simultaneous tcp buffers to hold per thread.
|
||||
# outgoing-num-tcp: 10
|
||||
|
||||
# number of incoming simultaneous tcp buffers to hold per thread.
|
||||
# incoming-num-tcp: 10
|
||||
|
||||
# buffer size for handling DNS data. No messages larger than this
|
||||
# size can be sent or received, by UDP or TCP. In bytes.
|
||||
# msg-buffer-size: 65552
|
||||
|
||||
# the amount of memory to use for the message cache.
|
||||
# plain value in bytes or you can append k, m or G. default is "4Mb".
|
||||
# msg-cache-size: 4m
|
||||
|
||||
# the number of slabs to use for the message cache.
|
||||
# the number of slabs must be a power of 2.
|
||||
# more slabs reduce lock contention, but fragment memory usage.
|
||||
# msg-cache-slabs: 4
|
||||
|
||||
# the number of queries that a thread gets to service.
|
||||
# num-queries-per-thread: 1024
|
||||
|
||||
# if very busy, 50% queries run to completion, 50% get timeout in msec
|
||||
# jostle-timeout: 200
|
||||
|
||||
# the amount of memory to use for the RRset cache.
|
||||
# plain value in bytes or you can append k, m or G. default is "4Mb".
|
||||
# rrset-cache-size: 4m
|
||||
|
||||
# the number of slabs to use for the RRset cache.
|
||||
# the number of slabs must be a power of 2.
|
||||
# more slabs reduce lock contention, but fragment memory usage.
|
||||
# rrset-cache-slabs: 4
|
||||
|
||||
# the time to live (TTL) value cap for RRsets and messages in the
|
||||
# cache. Items are not cached for longer. In seconds.
|
||||
# cache-max-ttl: 86400
|
||||
|
||||
# the time to live (TTL) value for cached roundtrip times and
|
||||
# EDNS version information for hosts. In seconds.
|
||||
# infra-host-ttl: 900
|
||||
|
||||
# the time to live (TTL) value for cached lame delegations. In sec.
|
||||
# infra-lame-ttl: 900
|
||||
|
||||
# the number of slabs to use for the Infrastructure cache.
|
||||
# the number of slabs must be a power of 2.
|
||||
# more slabs reduce lock contention, but fragment memory usage.
|
||||
# infra-cache-slabs: 4
|
||||
|
||||
# the maximum number of hosts that are cached (roundtrip times, EDNS).
|
||||
# infra-cache-numhosts: 10000
|
||||
|
||||
# the maximum size of the lame zones cached per host. in bytes.
|
||||
# infra-cache-lame-size: 10k
|
||||
|
||||
# Enable IPv4, "yes" or "no".
|
||||
# do-ip4: yes
|
||||
|
||||
# Enable IPv6, "yes" or "no".
|
||||
# do-ip6: yes
|
||||
|
||||
# Enable UDP, "yes" or "no".
|
||||
# do-udp: yes
|
||||
|
||||
# Enable TCP, "yes" or "no".
|
||||
# do-tcp: yes
|
||||
|
||||
# Detach from the terminal, run in background, "yes" or "no".
|
||||
do-daemonize: no
|
||||
|
||||
# control which clients are allowed to make (recursive) queries
|
||||
# to this server. Specify classless netblocks with /size and action.
|
||||
# By default everything is refused, except for localhost.
|
||||
# Choose deny (drop message), refuse (polite error reply),
|
||||
# allow (recursive ok), allow_snoop (recursive and nonrecursive ok)
|
||||
access-control: 0.0.0.0/0 allow
|
||||
# access-control: 127.0.0.0/8 allow
|
||||
# access-control: ::0/0 refuse
|
||||
# access-control: ::1 allow
|
||||
# access-control: ::ffff:127.0.0.1 allow
|
||||
|
||||
# if given, a chroot(2) is done to the given directory.
|
||||
# i.e. you can chroot to the working directory, for example,
|
||||
# for extra security, but make sure all files are in that directory.
|
||||
#
|
||||
# If chroot is enabled, you should pass the configfile (from the
|
||||
# commandline) as a full path from the original root. After the
|
||||
# chroot has been performed the now defunct portion of the config
|
||||
# file path is removed to be able to reread the config after a reload.
|
||||
#
|
||||
# All other file paths (working dir, logfile, roothints, and
|
||||
# key files) can be specified in several ways:
|
||||
# o as an absolute path relative to the new root.
|
||||
# o as a relative path to the working directory.
|
||||
# o as an absolute path relative to the original root.
|
||||
# In the last case the path is adjusted to remove the unused portion.
|
||||
#
|
||||
# The pid file can be absolute and outside of the chroot, it is
|
||||
# written just prior to performing the chroot and dropping permissions.
|
||||
#
|
||||
# Additionally, unbound may need to access /dev/random (for entropy).
|
||||
# How to do this is specific to your OS.
|
||||
#
|
||||
# If you give "" no chroot is performed. The path must not end in a /.
|
||||
chroot: ""
|
||||
|
||||
# if given, user privileges are dropped (after binding port),
|
||||
# and the given username is assumed. Default is user "unbound".
|
||||
# If you give "" no privileges are dropped.
|
||||
username: ""
|
||||
|
||||
# the working directory. The relative files in this config are
|
||||
# relative to this directory. If you give "" the working directory
|
||||
# is not changed.
|
||||
directory: ""
|
||||
|
||||
# the log file, "" means log to stderr.
|
||||
# Use of this option sets use-syslog to "no".
|
||||
logfile: ""
|
||||
|
||||
# Log to syslog(3) if yes. The log facility LOG_DAEMON is used to
|
||||
# log to, with identity "unbound". If yes, it overrides the logfile.
|
||||
# use-syslog: yes
|
||||
|
||||
# the pid file. Can be an absolute path outside of chroot/work dir.
|
||||
pidfile: "unbound.pid"
|
||||
|
||||
# file to read root hints from.
|
||||
# get one from ftp://FTP.INTERNIC.NET/domain/named.cache
|
||||
# root-hints: ""
|
||||
|
||||
# enable to not answer id.server and hostname.bind queries.
|
||||
# hide-identity: no
|
||||
|
||||
# enable to not answer version.server and version.bind queries.
|
||||
# hide-version: no
|
||||
|
||||
# the identity to report. Leave "" or default to return hostname.
|
||||
# identity: ""
|
||||
|
||||
# the version to report. Leave "" or default to return package version.
|
||||
# version: ""
|
||||
|
||||
# the target fetch policy.
|
||||
# series of integers describing the policy per dependency depth.
|
||||
# The number of values in the list determines the maximum dependency
|
||||
# depth the recursor will pursue before giving up. Each integer means:
|
||||
# -1 : fetch all targets opportunistically,
|
||||
# 0: fetch on demand,
|
||||
# positive value: fetch that many targets opportunistically.
|
||||
# Enclose the list of numbers between quotes ("").
|
||||
# target-fetch-policy: "3 2 1 0 0"
|
||||
|
||||
# Harden against very small EDNS buffer sizes.
|
||||
# harden-short-bufsize: no
|
||||
|
||||
# Harden against unseemly large queries.
|
||||
# harden-large-queries: no
|
||||
|
||||
# Harden against out of zone rrsets, to avoid spoofing attempts.
|
||||
# harden-glue: yes
|
||||
|
||||
# Harden against receiving dnssec-stripped data. If you turn it
|
||||
# off, failing to validate dnskey data for a trustanchor will
|
||||
# trigger insecure mode for that zone (like without a trustanchor).
|
||||
# Default on, which insists on dnssec data for trust-anchored zones.
|
||||
# harden-dnssec-stripped: yes
|
||||
|
||||
# Harden the referral path by performing additional queries for
|
||||
# infrastructure data. Validates the replies (if possible).
|
||||
# Default off, because the lookups burden the server. Experimental
|
||||
# implementation of draft-wijngaards-dnsext-resolver-side-mitigation.
|
||||
# harden-referral-path: no
|
||||
|
||||
# Use 0x20-encoded random bits in the query to foil spoof attempts.
|
||||
# This feature is an experimental implementation of draft dns-0x20.
|
||||
# use-caps-for-id: no
|
||||
|
||||
# Enforce privacy of these addresses. Strips them away from answers.
|
||||
# It may cause DNSSEC validation to additionally mark it as bogus.
|
||||
# Protects against 'DNS Rebinding' (uses browser as network proxy).
|
||||
# Only 'private-domain' and 'local-data' names are allowed to have
|
||||
# these private addresses. No default.
|
||||
# private-address: 10.0.0.0/8
|
||||
# private-address: 172.16.0.0/12
|
||||
# private-address: 192.168.0.0/16
|
||||
# private-address: 192.254.0.0/16
|
||||
# private-address: fd00::/8
|
||||
# private-address: fe80::/10
|
||||
|
||||
# Allow the domain (and its subdomains) to contain private addresses.
|
||||
# local-data statements are allowed to contain private addresses too.
|
||||
# private-domain: "example.com"
|
||||
|
||||
# If nonzero, unwanted replies are not only reported in statistics,
|
||||
# but also a running total is kept per thread. If it reaches the
|
||||
# threshold, a warning is printed and a defensive action is taken,
|
||||
# the cache is cleared to flush potential poison out of it.
|
||||
# A suggested value is 10000000, the default is 0 (turned off).
|
||||
# unwanted-reply-threshold: 0
|
||||
|
||||
# Do not query the following addresses. No DNS queries are sent there.
|
||||
# List one address per entry. List classless netblocks with /size,
|
||||
# do-not-query-address: 127.0.0.1/8
|
||||
# do-not-query-address: ::1
|
||||
|
||||
# if yes, the above default do-not-query-address entries are present.
|
||||
# if no, localhost can be queried (for testing and debugging).
|
||||
# do-not-query-localhost: yes
|
||||
|
||||
# module configuration of the server. A string with identifiers
|
||||
# separated by spaces. "iterator" or "validator iterator"
|
||||
module-config: "validator python iterator"
|
||||
|
||||
# File with DLV trusted keys. Same format as trust-anchor-file.
|
||||
# There can be only one DLV configured, it is trusted from root down.
|
||||
# Download https://secure.isc.org/ops/dlv/dlv.isc.org.key
|
||||
# dlv-anchor-file: "dlv.isc.org.key"
|
||||
|
||||
# File with trusted keys for validation. Specify more than one file
|
||||
# with several entries, one file per entry.
|
||||
# Zone file format, with DS and DNSKEY entries.
|
||||
# trust-anchor-file: ""
|
||||
|
||||
# Trusted key for validation. DS or DNSKEY. specify the RR on a
|
||||
# single line, surrounded by "". TTL is ignored. class is IN default.
|
||||
# (These examples are from August 2007 and may not be valid anymore).
|
||||
# trust-anchor: "nlnetlabs.nl. DNSKEY 257 3 5 AQPzzTWMz8qSWIQlfRnPckx2BiVmkVN6LPupO3mbz7FhLSnm26n6iG9N Lby97Ji453aWZY3M5/xJBSOS2vWtco2t8C0+xeO1bc/d6ZTy32DHchpW 6rDH1vp86Ll+ha0tmwyy9QP7y2bVw5zSbFCrefk8qCUBgfHm9bHzMG1U BYtEIQ=="
|
||||
# trust-anchor: "jelte.nlnetlabs.nl. DS 42860 5 1 14D739EB566D2B1A5E216A0BA4D17FA9B038BE4A"
|
||||
|
||||
# File with trusted keys for validation. Specify more than one file
|
||||
# with several entries, one file per entry. Like trust-anchor-file
|
||||
# but has a different file format. Format is BIND-9 style format,
|
||||
# the trusted-keys { name flag proto algo "key"; }; clauses are read.
|
||||
# trusted-keys-file: ""
|
||||
|
||||
# Override the date for validation with a specific fixed date.
|
||||
# Do not set this unless you are debugging signature inception
|
||||
# and expiration. "" or "0" turns the feature off.
|
||||
# val-override-date: ""
|
||||
|
||||
# The time to live for bogus data, rrsets and messages. This avoids
|
||||
# some of the revalidation, until the time interval expires. in secs.
|
||||
# val-bogus-ttl: 60
|
||||
|
||||
# Should additional section of secure message also be kept clean of
|
||||
# unsecure data. Useful to shield the users of this validator from
|
||||
# potential bogus data in the additional section. All unsigned data
|
||||
# in the additional section is removed from secure messages.
|
||||
# val-clean-additional: yes
|
||||
|
||||
# Turn permissive mode on to permit bogus messages. Thus, messages
|
||||
# for which security checks failed will be returned to clients,
|
||||
# instead of SERVFAIL. It still performs the security checks, which
|
||||
# result in interesting log files and possibly the AD bit in
|
||||
# replies if the message is found secure. The default is off.
|
||||
# val-permissive-mode: no
|
||||
|
||||
# It is possible to configure NSEC3 maximum iteration counts per
|
||||
# keysize. Keep this table very short, as linear search is done.
|
||||
# A message with an NSEC3 with larger count is marked insecure.
|
||||
# List in ascending order the keysize and count values.
|
||||
# val-nsec3-keysize-iterations: "1024 150 2048 500 4096 2500"
|
||||
|
||||
# the amount of memory to use for the key cache.
|
||||
# plain value in bytes or you can append k, m or G. default is "4Mb".
|
||||
# key-cache-size: 4m
|
||||
|
||||
# the number of slabs to use for the key cache.
|
||||
# the number of slabs must be a power of 2.
|
||||
# more slabs reduce lock contention, but fragment memory usage.
|
||||
# key-cache-slabs: 4
|
||||
|
||||
# the amount of memory to use for the negative cache (used for DLV).
|
||||
# plain value in bytes or you can append k, m or G. default is "1Mb".
|
||||
# neg-cache-size: 1m
|
||||
|
||||
# a number of locally served zones can be configured.
|
||||
# local-zone: <zone> <type>
|
||||
# local-data: "<resource record string>"
|
||||
# o deny serves local data (if any), else, drops queries.
|
||||
# o refuse serves local data (if any), else, replies with error.
|
||||
# o static serves local data, else, nxdomain or nodata answer.
|
||||
# o transparent serves local data, else, resolves normally .
|
||||
# o redirect serves the zone data for any subdomain in the zone.
|
||||
# o nodefault can be used to normally resolve AS112 zones.
|
||||
#
|
||||
# defaults are localhost address, reverse for 127.0.0.1 and ::1
|
||||
# and nxdomain for AS112 zones. If you configure one of these zones
|
||||
# the default content is omitted, or you can omit it with 'nodefault'.
|
||||
#
|
||||
# If you configure local-data without specifying local-zone, by
|
||||
# default a transparent local-zone is created for the data.
|
||||
#
|
||||
# You can add locally served data with
|
||||
# local-zone: "local." static
|
||||
# local-data: "mycomputer.local. IN A 192.0.2.51"
|
||||
# local-data: 'mytext.local TXT "content of text record"'
|
||||
#
|
||||
# You can override certain queries with
|
||||
# local-data: "adserver.example.com A 127.0.0.1"
|
||||
#
|
||||
# You can redirect a domain to a fixed address with
|
||||
# (this makes example.com, www.example.com, etc, all go to 192.0.2.3)
|
||||
# local-zone: "example.com" redirect
|
||||
# local-data: "example.com A 192.0.2.3"
|
||||
#
|
||||
# Shorthand to make PTR records, "IPv4 name" or "IPv6 name".
|
||||
# You can also add PTR records using local-data directly, but then
|
||||
# you need to do the reverse notation yourself.
|
||||
# local-data-ptr: "192.0.2.3 www.example.com"
|
||||
|
||||
# Python config section
|
||||
python:
|
||||
# Script file to load
|
||||
python-script: "./examples/dict.py"
|
||||
|
||||
# Remote control config section.
|
||||
remote-control:
|
||||
# Enable remote control with unbound-control(8) here.
|
||||
# set up the keys and certificates with unbound-control-setup.
|
||||
# control-enable: no
|
||||
|
||||
# what interfaces are listened to for remote control.
|
||||
# give 0.0.0.0 and ::0 to listen to all interfaces.
|
||||
# control-interface: 127.0.0.1
|
||||
# control-interface: ::1
|
||||
|
||||
# port number for remote control operations.
|
||||
# control-port: 953
|
||||
|
||||
# unbound server key file.
|
||||
# server-key-file: "/usr/local/etc/unbound/unbound_server.key"
|
||||
|
||||
# unbound server certificate file.
|
||||
# server-cert-file: "/usr/local/etc/unbound/unbound_server.pem"
|
||||
|
||||
# unbound-control key file.
|
||||
# control-key-file: "/usr/local/etc/unbound/unbound_control.key"
|
||||
|
||||
# unbound-control certificate file.
|
||||
# control-cert-file: "/usr/local/etc/unbound/unbound_control.pem"
|
||||
|
||||
# Stub zones.
|
||||
# Create entries like below, to make all queries for 'example.com' and
|
||||
# 'example.org' go to the given list of nameservers. list zero or more
|
||||
# nameservers by hostname or by ipaddress. If you set stub-prime to yes,
|
||||
# the list is treated as priming hints (default is no).
|
||||
# stub-zone:
|
||||
# name: "example.com"
|
||||
# stub-addr: 192.0.2.68
|
||||
# stub-prime: "no"
|
||||
# stub-zone:
|
||||
# name: "example.org"
|
||||
# stub-host: ns.example.com.
|
||||
|
||||
# Forward zones
|
||||
# Create entries like below, to make all queries for 'example.com' and
|
||||
# 'example.org' go to the given list of servers. These servers have to handle
|
||||
# recursion to other nameservers. List zero or more nameservers by hostname
|
||||
# or by ipaddress. Use an entry with name "." to forward all queries.
|
||||
# forward-zone:
|
||||
# name: "example.com"
|
||||
# forward-addr: 192.0.2.68
|
||||
# forward-addr: 192.0.2.73@5355 # forward to port 5355.
|
||||
# forward-zone:
|
||||
# name: "example.org"
|
||||
# forward-host: fwd.example.com
|
438
pythonmod/test-log.conf
Normal file
438
pythonmod/test-log.conf
Normal file
@ -0,0 +1,438 @@
|
||||
#
|
||||
# Example configuration file.
|
||||
#
|
||||
# See unbound.conf(5) man page.
|
||||
#
|
||||
# this is a comment.
|
||||
|
||||
#Use this to include other text into the file.
|
||||
#include: "otherfile.conf"
|
||||
|
||||
# The server clause sets the main parameters.
|
||||
server:
|
||||
# whitespace is not necessary, but looks cleaner.
|
||||
|
||||
# verbosity number, 0 is least verbose. 1 is default.
|
||||
verbosity: 1
|
||||
|
||||
# print statistics to the log (for every thread) every N seconds.
|
||||
# Set to "" or 0 to disable. Default is disabled.
|
||||
# statistics-interval: 0
|
||||
|
||||
# enable cumulative statistics, without clearing them after printing.
|
||||
# statistics-cumulative: no
|
||||
|
||||
# enable extended statistics (query types, answer codes, status)
|
||||
# printed from unbound-control. default off, because of speed.
|
||||
# extended-statistics: no
|
||||
|
||||
# number of threads to create. 1 disables threading.
|
||||
# num-threads: 1
|
||||
|
||||
# specify the interfaces to answer queries from by ip-address.
|
||||
# The default is to listen to localhost (127.0.0.1 and ::1).
|
||||
# specify 0.0.0.0 and ::0 to bind to all available interfaces.
|
||||
# specify every interface on a new 'interface:' labelled line.
|
||||
# The listen interfaces are not changed on reload, only on restart.
|
||||
interface: 0.0.0.0
|
||||
# interface: 192.0.2.154
|
||||
# interface: 2001:DB8::5
|
||||
|
||||
# enable this feature to copy the source address of queries to reply.
|
||||
# Socket options are not supported on all platforms. experimental.
|
||||
# interface-automatic: no
|
||||
|
||||
# port to answer queries from
|
||||
# port: 53
|
||||
|
||||
# specify the interfaces to send outgoing queries to authoritative
|
||||
# server from by ip-address. If none, the default (all) interface
|
||||
# is used. Specify every interface on a 'outgoing-interface:' line.
|
||||
# outgoing-interface: 192.0.2.153
|
||||
# outgoing-interface: 2001:DB8::5
|
||||
# outgoing-interface: 2001:DB8::6
|
||||
|
||||
# number of ports to allocate per thread, determines the size of the
|
||||
# port range that can be open simultaneously.
|
||||
# outgoing-range: 256
|
||||
|
||||
# permit unbound to use this port number or port range for
|
||||
# making outgoing queries, using an outgoing interface.
|
||||
# outgoing-port-permit: 32768
|
||||
|
||||
# deny unbound the use this of port number or port range for
|
||||
# making outgoing queries, using an outgoing interface.
|
||||
# Use this to make sure unbound does not grab a UDP port that some
|
||||
# other server on this computer needs. The default is to avoid
|
||||
# IANA-assigned port numbers.
|
||||
# outgoing-port-avoid: "3200-3208"
|
||||
|
||||
# number of outgoing simultaneous tcp buffers to hold per thread.
|
||||
# outgoing-num-tcp: 10
|
||||
|
||||
# number of incoming simultaneous tcp buffers to hold per thread.
|
||||
# incoming-num-tcp: 10
|
||||
|
||||
# buffer size for handling DNS data. No messages larger than this
|
||||
# size can be sent or received, by UDP or TCP. In bytes.
|
||||
# msg-buffer-size: 65552
|
||||
|
||||
# the amount of memory to use for the message cache.
|
||||
# plain value in bytes or you can append k, m or G. default is "4Mb".
|
||||
# msg-cache-size: 4m
|
||||
|
||||
# the number of slabs to use for the message cache.
|
||||
# the number of slabs must be a power of 2.
|
||||
# more slabs reduce lock contention, but fragment memory usage.
|
||||
# msg-cache-slabs: 4
|
||||
|
||||
# the number of queries that a thread gets to service.
|
||||
# num-queries-per-thread: 1024
|
||||
|
||||
# if very busy, 50% queries run to completion, 50% get timeout in msec
|
||||
# jostle-timeout: 200
|
||||
|
||||
# the amount of memory to use for the RRset cache.
|
||||
# plain value in bytes or you can append k, m or G. default is "4Mb".
|
||||
# rrset-cache-size: 4m
|
||||
|
||||
# the number of slabs to use for the RRset cache.
|
||||
# the number of slabs must be a power of 2.
|
||||
# more slabs reduce lock contention, but fragment memory usage.
|
||||
# rrset-cache-slabs: 4
|
||||
|
||||
# the time to live (TTL) value cap for RRsets and messages in the
|
||||
# cache. Items are not cached for longer. In seconds.
|
||||
# cache-max-ttl: 86400
|
||||
|
||||
# the time to live (TTL) value for cached roundtrip times and
|
||||
# EDNS version information for hosts. In seconds.
|
||||
# infra-host-ttl: 900
|
||||
|
||||
# the time to live (TTL) value for cached lame delegations. In sec.
|
||||
# infra-lame-ttl: 900
|
||||
|
||||
# the number of slabs to use for the Infrastructure cache.
|
||||
# the number of slabs must be a power of 2.
|
||||
# more slabs reduce lock contention, but fragment memory usage.
|
||||
# infra-cache-slabs: 4
|
||||
|
||||
# the maximum number of hosts that are cached (roundtrip times, EDNS).
|
||||
# infra-cache-numhosts: 10000
|
||||
|
||||
# the maximum size of the lame zones cached per host. in bytes.
|
||||
# infra-cache-lame-size: 10k
|
||||
|
||||
# Enable IPv4, "yes" or "no".
|
||||
# do-ip4: yes
|
||||
|
||||
# Enable IPv6, "yes" or "no".
|
||||
# do-ip6: yes
|
||||
|
||||
# Enable UDP, "yes" or "no".
|
||||
# do-udp: yes
|
||||
|
||||
# Enable TCP, "yes" or "no".
|
||||
# do-tcp: yes
|
||||
|
||||
# Detach from the terminal, run in background, "yes" or "no".
|
||||
do-daemonize: no
|
||||
|
||||
# control which clients are allowed to make (recursive) queries
|
||||
# to this server. Specify classless netblocks with /size and action.
|
||||
# By default everything is refused, except for localhost.
|
||||
# Choose deny (drop message), refuse (polite error reply),
|
||||
# allow (recursive ok), allow_snoop (recursive and nonrecursive ok)
|
||||
access-control: 0.0.0.0/0 allow
|
||||
# access-control: 127.0.0.0/8 allow
|
||||
# access-control: ::0/0 refuse
|
||||
# access-control: ::1 allow
|
||||
# access-control: ::ffff:127.0.0.1 allow
|
||||
|
||||
# if given, a chroot(2) is done to the given directory.
|
||||
# i.e. you can chroot to the working directory, for example,
|
||||
# for extra security, but make sure all files are in that directory.
|
||||
#
|
||||
# If chroot is enabled, you should pass the configfile (from the
|
||||
# commandline) as a full path from the original root. After the
|
||||
# chroot has been performed the now defunct portion of the config
|
||||
# file path is removed to be able to reread the config after a reload.
|
||||
#
|
||||
# All other file paths (working dir, logfile, roothints, and
|
||||
# key files) can be specified in several ways:
|
||||
# o as an absolute path relative to the new root.
|
||||
# o as a relative path to the working directory.
|
||||
# o as an absolute path relative to the original root.
|
||||
# In the last case the path is adjusted to remove the unused portion.
|
||||
#
|
||||
# The pid file can be absolute and outside of the chroot, it is
|
||||
# written just prior to performing the chroot and dropping permissions.
|
||||
#
|
||||
# Additionally, unbound may need to access /dev/random (for entropy).
|
||||
# How to do this is specific to your OS.
|
||||
#
|
||||
# If you give "" no chroot is performed. The path must not end in a /.
|
||||
chroot: ""
|
||||
|
||||
# if given, user privileges are dropped (after binding port),
|
||||
# and the given username is assumed. Default is user "unbound".
|
||||
# If you give "" no privileges are dropped.
|
||||
username: ""
|
||||
|
||||
# the working directory. The relative files in this config are
|
||||
# relative to this directory. If you give "" the working directory
|
||||
# is not changed.
|
||||
directory: ""
|
||||
|
||||
# the log file, "" means log to stderr.
|
||||
# Use of this option sets use-syslog to "no".
|
||||
logfile: ""
|
||||
|
||||
# Log to syslog(3) if yes. The log facility LOG_DAEMON is used to
|
||||
# log to, with identity "unbound". If yes, it overrides the logfile.
|
||||
# use-syslog: yes
|
||||
|
||||
# the pid file. Can be an absolute path outside of chroot/work dir.
|
||||
pidfile: "unbound.pid"
|
||||
|
||||
# file to read root hints from.
|
||||
# get one from ftp://FTP.INTERNIC.NET/domain/named.cache
|
||||
# root-hints: ""
|
||||
|
||||
# enable to not answer id.server and hostname.bind queries.
|
||||
# hide-identity: no
|
||||
|
||||
# enable to not answer version.server and version.bind queries.
|
||||
# hide-version: no
|
||||
|
||||
# the identity to report. Leave "" or default to return hostname.
|
||||
# identity: ""
|
||||
|
||||
# the version to report. Leave "" or default to return package version.
|
||||
# version: ""
|
||||
|
||||
# the target fetch policy.
|
||||
# series of integers describing the policy per dependency depth.
|
||||
# The number of values in the list determines the maximum dependency
|
||||
# depth the recursor will pursue before giving up. Each integer means:
|
||||
# -1 : fetch all targets opportunistically,
|
||||
# 0: fetch on demand,
|
||||
# positive value: fetch that many targets opportunistically.
|
||||
# Enclose the list of numbers between quotes ("").
|
||||
# target-fetch-policy: "3 2 1 0 0"
|
||||
|
||||
# Harden against very small EDNS buffer sizes.
|
||||
# harden-short-bufsize: no
|
||||
|
||||
# Harden against unseemly large queries.
|
||||
# harden-large-queries: no
|
||||
|
||||
# Harden against out of zone rrsets, to avoid spoofing attempts.
|
||||
# harden-glue: yes
|
||||
|
||||
# Harden against receiving dnssec-stripped data. If you turn it
|
||||
# off, failing to validate dnskey data for a trustanchor will
|
||||
# trigger insecure mode for that zone (like without a trustanchor).
|
||||
# Default on, which insists on dnssec data for trust-anchored zones.
|
||||
# harden-dnssec-stripped: yes
|
||||
|
||||
# Harden the referral path by performing additional queries for
|
||||
# infrastructure data. Validates the replies (if possible).
|
||||
# Default off, because the lookups burden the server. Experimental
|
||||
# implementation of draft-wijngaards-dnsext-resolver-side-mitigation.
|
||||
# harden-referral-path: no
|
||||
|
||||
# Use 0x20-encoded random bits in the query to foil spoof attempts.
|
||||
# This feature is an experimental implementation of draft dns-0x20.
|
||||
# use-caps-for-id: no
|
||||
|
||||
# Enforce privacy of these addresses. Strips them away from answers.
|
||||
# It may cause DNSSEC validation to additionally mark it as bogus.
|
||||
# Protects against 'DNS Rebinding' (uses browser as network proxy).
|
||||
# Only 'private-domain' and 'local-data' names are allowed to have
|
||||
# these private addresses. No default.
|
||||
# private-address: 10.0.0.0/8
|
||||
# private-address: 172.16.0.0/12
|
||||
# private-address: 192.168.0.0/16
|
||||
# private-address: 192.254.0.0/16
|
||||
# private-address: fd00::/8
|
||||
# private-address: fe80::/10
|
||||
|
||||
# Allow the domain (and its subdomains) to contain private addresses.
|
||||
# local-data statements are allowed to contain private addresses too.
|
||||
# private-domain: "example.com"
|
||||
|
||||
# If nonzero, unwanted replies are not only reported in statistics,
|
||||
# but also a running total is kept per thread. If it reaches the
|
||||
# threshold, a warning is printed and a defensive action is taken,
|
||||
# the cache is cleared to flush potential poison out of it.
|
||||
# A suggested value is 10000000, the default is 0 (turned off).
|
||||
# unwanted-reply-threshold: 0
|
||||
|
||||
# Do not query the following addresses. No DNS queries are sent there.
|
||||
# List one address per entry. List classless netblocks with /size,
|
||||
# do-not-query-address: 127.0.0.1/8
|
||||
# do-not-query-address: ::1
|
||||
|
||||
# if yes, the above default do-not-query-address entries are present.
|
||||
# if no, localhost can be queried (for testing and debugging).
|
||||
# do-not-query-localhost: yes
|
||||
|
||||
# module configuration of the server. A string with identifiers
|
||||
# separated by spaces. "iterator" or "validator iterator"
|
||||
module-config: "validator python iterator"
|
||||
|
||||
# File with DLV trusted keys. Same format as trust-anchor-file.
|
||||
# There can be only one DLV configured, it is trusted from root down.
|
||||
# Download https://secure.isc.org/ops/dlv/dlv.isc.org.key
|
||||
# dlv-anchor-file: "dlv.isc.org.key"
|
||||
|
||||
# File with trusted keys for validation. Specify more than one file
|
||||
# with several entries, one file per entry.
|
||||
# Zone file format, with DS and DNSKEY entries.
|
||||
# trust-anchor-file: ""
|
||||
|
||||
# Trusted key for validation. DS or DNSKEY. specify the RR on a
|
||||
# single line, surrounded by "". TTL is ignored. class is IN default.
|
||||
# (These examples are from August 2007 and may not be valid anymore).
|
||||
# trust-anchor: "nlnetlabs.nl. DNSKEY 257 3 5 AQPzzTWMz8qSWIQlfRnPckx2BiVmkVN6LPupO3mbz7FhLSnm26n6iG9N Lby97Ji453aWZY3M5/xJBSOS2vWtco2t8C0+xeO1bc/d6ZTy32DHchpW 6rDH1vp86Ll+ha0tmwyy9QP7y2bVw5zSbFCrefk8qCUBgfHm9bHzMG1U BYtEIQ=="
|
||||
# trust-anchor: "jelte.nlnetlabs.nl. DS 42860 5 1 14D739EB566D2B1A5E216A0BA4D17FA9B038BE4A"
|
||||
|
||||
# File with trusted keys for validation. Specify more than one file
|
||||
# with several entries, one file per entry. Like trust-anchor-file
|
||||
# but has a different file format. Format is BIND-9 style format,
|
||||
# the trusted-keys { name flag proto algo "key"; }; clauses are read.
|
||||
# trusted-keys-file: ""
|
||||
|
||||
# Override the date for validation with a specific fixed date.
|
||||
# Do not set this unless you are debugging signature inception
|
||||
# and expiration. "" or "0" turns the feature off.
|
||||
# val-override-date: ""
|
||||
|
||||
# The time to live for bogus data, rrsets and messages. This avoids
|
||||
# some of the revalidation, until the time interval expires. in secs.
|
||||
# val-bogus-ttl: 60
|
||||
|
||||
# Should additional section of secure message also be kept clean of
|
||||
# unsecure data. Useful to shield the users of this validator from
|
||||
# potential bogus data in the additional section. All unsigned data
|
||||
# in the additional section is removed from secure messages.
|
||||
# val-clean-additional: yes
|
||||
|
||||
# Turn permissive mode on to permit bogus messages. Thus, messages
|
||||
# for which security checks failed will be returned to clients,
|
||||
# instead of SERVFAIL. It still performs the security checks, which
|
||||
# result in interesting log files and possibly the AD bit in
|
||||
# replies if the message is found secure. The default is off.
|
||||
# val-permissive-mode: no
|
||||
|
||||
# It is possible to configure NSEC3 maximum iteration counts per
|
||||
# keysize. Keep this table very short, as linear search is done.
|
||||
# A message with an NSEC3 with larger count is marked insecure.
|
||||
# List in ascending order the keysize and count values.
|
||||
# val-nsec3-keysize-iterations: "1024 150 2048 500 4096 2500"
|
||||
|
||||
# the amount of memory to use for the key cache.
|
||||
# plain value in bytes or you can append k, m or G. default is "4Mb".
|
||||
# key-cache-size: 4m
|
||||
|
||||
# the number of slabs to use for the key cache.
|
||||
# the number of slabs must be a power of 2.
|
||||
# more slabs reduce lock contention, but fragment memory usage.
|
||||
# key-cache-slabs: 4
|
||||
|
||||
# the amount of memory to use for the negative cache (used for DLV).
|
||||
# plain value in bytes or you can append k, m or G. default is "1Mb".
|
||||
# neg-cache-size: 1m
|
||||
|
||||
# a number of locally served zones can be configured.
|
||||
# local-zone: <zone> <type>
|
||||
# local-data: "<resource record string>"
|
||||
# o deny serves local data (if any), else, drops queries.
|
||||
# o refuse serves local data (if any), else, replies with error.
|
||||
# o static serves local data, else, nxdomain or nodata answer.
|
||||
# o transparent serves local data, else, resolves normally .
|
||||
# o redirect serves the zone data for any subdomain in the zone.
|
||||
# o nodefault can be used to normally resolve AS112 zones.
|
||||
#
|
||||
# defaults are localhost address, reverse for 127.0.0.1 and ::1
|
||||
# and nxdomain for AS112 zones. If you configure one of these zones
|
||||
# the default content is omitted, or you can omit it with 'nodefault'.
|
||||
#
|
||||
# If you configure local-data without specifying local-zone, by
|
||||
# default a transparent local-zone is created for the data.
|
||||
#
|
||||
# You can add locally served data with
|
||||
# local-zone: "local." static
|
||||
# local-data: "mycomputer.local. IN A 192.0.2.51"
|
||||
# local-data: 'mytext.local TXT "content of text record"'
|
||||
#
|
||||
# You can override certain queries with
|
||||
# local-data: "adserver.example.com A 127.0.0.1"
|
||||
#
|
||||
# You can redirect a domain to a fixed address with
|
||||
# (this makes example.com, www.example.com, etc, all go to 192.0.2.3)
|
||||
# local-zone: "example.com" redirect
|
||||
# local-data: "example.com A 192.0.2.3"
|
||||
#
|
||||
# Shorthand to make PTR records, "IPv4 name" or "IPv6 name".
|
||||
# You can also add PTR records using local-data directly, but then
|
||||
# you need to do the reverse notation yourself.
|
||||
# local-data-ptr: "192.0.2.3 www.example.com"
|
||||
|
||||
# Python config section
|
||||
python:
|
||||
# Script file to load
|
||||
python-script: "./examples/log.py"
|
||||
|
||||
# Remote control config section.
|
||||
remote-control:
|
||||
# Enable remote control with unbound-control(8) here.
|
||||
# set up the keys and certificates with unbound-control-setup.
|
||||
# control-enable: no
|
||||
|
||||
# what interfaces are listened to for remote control.
|
||||
# give 0.0.0.0 and ::0 to listen to all interfaces.
|
||||
# control-interface: 127.0.0.1
|
||||
# control-interface: ::1
|
||||
|
||||
# port number for remote control operations.
|
||||
# control-port: 953
|
||||
|
||||
# unbound server key file.
|
||||
# server-key-file: "/usr/local/etc/unbound/unbound_server.key"
|
||||
|
||||
# unbound server certificate file.
|
||||
# server-cert-file: "/usr/local/etc/unbound/unbound_server.pem"
|
||||
|
||||
# unbound-control key file.
|
||||
# control-key-file: "/usr/local/etc/unbound/unbound_control.key"
|
||||
|
||||
# unbound-control certificate file.
|
||||
# control-cert-file: "/usr/local/etc/unbound/unbound_control.pem"
|
||||
|
||||
# Stub zones.
|
||||
# Create entries like below, to make all queries for 'example.com' and
|
||||
# 'example.org' go to the given list of nameservers. list zero or more
|
||||
# nameservers by hostname or by ipaddress. If you set stub-prime to yes,
|
||||
# the list is treated as priming hints (default is no).
|
||||
# stub-zone:
|
||||
# name: "example.com"
|
||||
# stub-addr: 192.0.2.68
|
||||
# stub-prime: "no"
|
||||
# stub-zone:
|
||||
# name: "example.org"
|
||||
# stub-host: ns.example.com.
|
||||
|
||||
# Forward zones
|
||||
# Create entries like below, to make all queries for 'example.com' and
|
||||
# 'example.org' go to the given list of servers. These servers have to handle
|
||||
# recursion to other nameservers. List zero or more nameservers by hostname
|
||||
# or by ipaddress. Use an entry with name "." to forward all queries.
|
||||
# forward-zone:
|
||||
# name: "example.com"
|
||||
# forward-addr: 192.0.2.68
|
||||
# forward-addr: 192.0.2.73@5355 # forward to port 5355.
|
||||
# forward-zone:
|
||||
# name: "example.org"
|
||||
# forward-host: fwd.example.com
|
438
pythonmod/test-resgen.conf
Normal file
438
pythonmod/test-resgen.conf
Normal file
@ -0,0 +1,438 @@
|
||||
#
|
||||
# Example configuration file.
|
||||
#
|
||||
# See unbound.conf(5) man page.
|
||||
#
|
||||
# this is a comment.
|
||||
|
||||
#Use this to include other text into the file.
|
||||
#include: "otherfile.conf"
|
||||
|
||||
# The server clause sets the main parameters.
|
||||
server:
|
||||
# whitespace is not necessary, but looks cleaner.
|
||||
|
||||
# verbosity number, 0 is least verbose. 1 is default.
|
||||
verbosity: 1
|
||||
|
||||
# print statistics to the log (for every thread) every N seconds.
|
||||
# Set to "" or 0 to disable. Default is disabled.
|
||||
# statistics-interval: 0
|
||||
|
||||
# enable cumulative statistics, without clearing them after printing.
|
||||
# statistics-cumulative: no
|
||||
|
||||
# enable extended statistics (query types, answer codes, status)
|
||||
# printed from unbound-control. default off, because of speed.
|
||||
# extended-statistics: no
|
||||
|
||||
# number of threads to create. 1 disables threading.
|
||||
# num-threads: 1
|
||||
|
||||
# specify the interfaces to answer queries from by ip-address.
|
||||
# The default is to listen to localhost (127.0.0.1 and ::1).
|
||||
# specify 0.0.0.0 and ::0 to bind to all available interfaces.
|
||||
# specify every interface on a new 'interface:' labelled line.
|
||||
# The listen interfaces are not changed on reload, only on restart.
|
||||
interface: 0.0.0.0
|
||||
# interface: 192.0.2.154
|
||||
# interface: 2001:DB8::5
|
||||
|
||||
# enable this feature to copy the source address of queries to reply.
|
||||
# Socket options are not supported on all platforms. experimental.
|
||||
# interface-automatic: no
|
||||
|
||||
# port to answer queries from
|
||||
# port: 53
|
||||
|
||||
# specify the interfaces to send outgoing queries to authoritative
|
||||
# server from by ip-address. If none, the default (all) interface
|
||||
# is used. Specify every interface on a 'outgoing-interface:' line.
|
||||
# outgoing-interface: 192.0.2.153
|
||||
# outgoing-interface: 2001:DB8::5
|
||||
# outgoing-interface: 2001:DB8::6
|
||||
|
||||
# number of ports to allocate per thread, determines the size of the
|
||||
# port range that can be open simultaneously.
|
||||
# outgoing-range: 256
|
||||
|
||||
# permit unbound to use this port number or port range for
|
||||
# making outgoing queries, using an outgoing interface.
|
||||
# outgoing-port-permit: 32768
|
||||
|
||||
# deny unbound the use this of port number or port range for
|
||||
# making outgoing queries, using an outgoing interface.
|
||||
# Use this to make sure unbound does not grab a UDP port that some
|
||||
# other server on this computer needs. The default is to avoid
|
||||
# IANA-assigned port numbers.
|
||||
# outgoing-port-avoid: "3200-3208"
|
||||
|
||||
# number of outgoing simultaneous tcp buffers to hold per thread.
|
||||
# outgoing-num-tcp: 10
|
||||
|
||||
# number of incoming simultaneous tcp buffers to hold per thread.
|
||||
# incoming-num-tcp: 10
|
||||
|
||||
# buffer size for handling DNS data. No messages larger than this
|
||||
# size can be sent or received, by UDP or TCP. In bytes.
|
||||
# msg-buffer-size: 65552
|
||||
|
||||
# the amount of memory to use for the message cache.
|
||||
# plain value in bytes or you can append k, m or G. default is "4Mb".
|
||||
# msg-cache-size: 4m
|
||||
|
||||
# the number of slabs to use for the message cache.
|
||||
# the number of slabs must be a power of 2.
|
||||
# more slabs reduce lock contention, but fragment memory usage.
|
||||
# msg-cache-slabs: 4
|
||||
|
||||
# the number of queries that a thread gets to service.
|
||||
# num-queries-per-thread: 1024
|
||||
|
||||
# if very busy, 50% queries run to completion, 50% get timeout in msec
|
||||
# jostle-timeout: 200
|
||||
|
||||
# the amount of memory to use for the RRset cache.
|
||||
# plain value in bytes or you can append k, m or G. default is "4Mb".
|
||||
# rrset-cache-size: 4m
|
||||
|
||||
# the number of slabs to use for the RRset cache.
|
||||
# the number of slabs must be a power of 2.
|
||||
# more slabs reduce lock contention, but fragment memory usage.
|
||||
# rrset-cache-slabs: 4
|
||||
|
||||
# the time to live (TTL) value cap for RRsets and messages in the
|
||||
# cache. Items are not cached for longer. In seconds.
|
||||
# cache-max-ttl: 86400
|
||||
|
||||
# the time to live (TTL) value for cached roundtrip times and
|
||||
# EDNS version information for hosts. In seconds.
|
||||
# infra-host-ttl: 900
|
||||
|
||||
# the time to live (TTL) value for cached lame delegations. In sec.
|
||||
# infra-lame-ttl: 900
|
||||
|
||||
# the number of slabs to use for the Infrastructure cache.
|
||||
# the number of slabs must be a power of 2.
|
||||
# more slabs reduce lock contention, but fragment memory usage.
|
||||
# infra-cache-slabs: 4
|
||||
|
||||
# the maximum number of hosts that are cached (roundtrip times, EDNS).
|
||||
# infra-cache-numhosts: 10000
|
||||
|
||||
# the maximum size of the lame zones cached per host. in bytes.
|
||||
# infra-cache-lame-size: 10k
|
||||
|
||||
# Enable IPv4, "yes" or "no".
|
||||
# do-ip4: yes
|
||||
|
||||
# Enable IPv6, "yes" or "no".
|
||||
# do-ip6: yes
|
||||
|
||||
# Enable UDP, "yes" or "no".
|
||||
# do-udp: yes
|
||||
|
||||
# Enable TCP, "yes" or "no".
|
||||
# do-tcp: yes
|
||||
|
||||
# Detach from the terminal, run in background, "yes" or "no".
|
||||
do-daemonize: no
|
||||
|
||||
# control which clients are allowed to make (recursive) queries
|
||||
# to this server. Specify classless netblocks with /size and action.
|
||||
# By default everything is refused, except for localhost.
|
||||
# Choose deny (drop message), refuse (polite error reply),
|
||||
# allow (recursive ok), allow_snoop (recursive and nonrecursive ok)
|
||||
access-control: 0.0.0.0/0 allow
|
||||
# access-control: 127.0.0.0/8 allow
|
||||
# access-control: ::0/0 refuse
|
||||
# access-control: ::1 allow
|
||||
# access-control: ::ffff:127.0.0.1 allow
|
||||
|
||||
# if given, a chroot(2) is done to the given directory.
|
||||
# i.e. you can chroot to the working directory, for example,
|
||||
# for extra security, but make sure all files are in that directory.
|
||||
#
|
||||
# If chroot is enabled, you should pass the configfile (from the
|
||||
# commandline) as a full path from the original root. After the
|
||||
# chroot has been performed the now defunct portion of the config
|
||||
# file path is removed to be able to reread the config after a reload.
|
||||
#
|
||||
# All other file paths (working dir, logfile, roothints, and
|
||||
# key files) can be specified in several ways:
|
||||
# o as an absolute path relative to the new root.
|
||||
# o as a relative path to the working directory.
|
||||
# o as an absolute path relative to the original root.
|
||||
# In the last case the path is adjusted to remove the unused portion.
|
||||
#
|
||||
# The pid file can be absolute and outside of the chroot, it is
|
||||
# written just prior to performing the chroot and dropping permissions.
|
||||
#
|
||||
# Additionally, unbound may need to access /dev/random (for entropy).
|
||||
# How to do this is specific to your OS.
|
||||
#
|
||||
# If you give "" no chroot is performed. The path must not end in a /.
|
||||
chroot: ""
|
||||
|
||||
# if given, user privileges are dropped (after binding port),
|
||||
# and the given username is assumed. Default is user "unbound".
|
||||
# If you give "" no privileges are dropped.
|
||||
username: ""
|
||||
|
||||
# the working directory. The relative files in this config are
|
||||
# relative to this directory. If you give "" the working directory
|
||||
# is not changed.
|
||||
directory: ""
|
||||
|
||||
# the log file, "" means log to stderr.
|
||||
# Use of this option sets use-syslog to "no".
|
||||
logfile: ""
|
||||
|
||||
# Log to syslog(3) if yes. The log facility LOG_DAEMON is used to
|
||||
# log to, with identity "unbound". If yes, it overrides the logfile.
|
||||
# use-syslog: yes
|
||||
|
||||
# the pid file. Can be an absolute path outside of chroot/work dir.
|
||||
pidfile: "unbound.pid"
|
||||
|
||||
# file to read root hints from.
|
||||
# get one from ftp://FTP.INTERNIC.NET/domain/named.cache
|
||||
# root-hints: ""
|
||||
|
||||
# enable to not answer id.server and hostname.bind queries.
|
||||
# hide-identity: no
|
||||
|
||||
# enable to not answer version.server and version.bind queries.
|
||||
# hide-version: no
|
||||
|
||||
# the identity to report. Leave "" or default to return hostname.
|
||||
# identity: ""
|
||||
|
||||
# the version to report. Leave "" or default to return package version.
|
||||
# version: ""
|
||||
|
||||
# the target fetch policy.
|
||||
# series of integers describing the policy per dependency depth.
|
||||
# The number of values in the list determines the maximum dependency
|
||||
# depth the recursor will pursue before giving up. Each integer means:
|
||||
# -1 : fetch all targets opportunistically,
|
||||
# 0: fetch on demand,
|
||||
# positive value: fetch that many targets opportunistically.
|
||||
# Enclose the list of numbers between quotes ("").
|
||||
# target-fetch-policy: "3 2 1 0 0"
|
||||
|
||||
# Harden against very small EDNS buffer sizes.
|
||||
# harden-short-bufsize: no
|
||||
|
||||
# Harden against unseemly large queries.
|
||||
# harden-large-queries: no
|
||||
|
||||
# Harden against out of zone rrsets, to avoid spoofing attempts.
|
||||
# harden-glue: yes
|
||||
|
||||
# Harden against receiving dnssec-stripped data. If you turn it
|
||||
# off, failing to validate dnskey data for a trustanchor will
|
||||
# trigger insecure mode for that zone (like without a trustanchor).
|
||||
# Default on, which insists on dnssec data for trust-anchored zones.
|
||||
# harden-dnssec-stripped: yes
|
||||
|
||||
# Harden the referral path by performing additional queries for
|
||||
# infrastructure data. Validates the replies (if possible).
|
||||
# Default off, because the lookups burden the server. Experimental
|
||||
# implementation of draft-wijngaards-dnsext-resolver-side-mitigation.
|
||||
# harden-referral-path: no
|
||||
|
||||
# Use 0x20-encoded random bits in the query to foil spoof attempts.
|
||||
# This feature is an experimental implementation of draft dns-0x20.
|
||||
# use-caps-for-id: no
|
||||
|
||||
# Enforce privacy of these addresses. Strips them away from answers.
|
||||
# It may cause DNSSEC validation to additionally mark it as bogus.
|
||||
# Protects against 'DNS Rebinding' (uses browser as network proxy).
|
||||
# Only 'private-domain' and 'local-data' names are allowed to have
|
||||
# these private addresses. No default.
|
||||
# private-address: 10.0.0.0/8
|
||||
# private-address: 172.16.0.0/12
|
||||
# private-address: 192.168.0.0/16
|
||||
# private-address: 192.254.0.0/16
|
||||
# private-address: fd00::/8
|
||||
# private-address: fe80::/10
|
||||
|
||||
# Allow the domain (and its subdomains) to contain private addresses.
|
||||
# local-data statements are allowed to contain private addresses too.
|
||||
# private-domain: "example.com"
|
||||
|
||||
# If nonzero, unwanted replies are not only reported in statistics,
|
||||
# but also a running total is kept per thread. If it reaches the
|
||||
# threshold, a warning is printed and a defensive action is taken,
|
||||
# the cache is cleared to flush potential poison out of it.
|
||||
# A suggested value is 10000000, the default is 0 (turned off).
|
||||
# unwanted-reply-threshold: 0
|
||||
|
||||
# Do not query the following addresses. No DNS queries are sent there.
|
||||
# List one address per entry. List classless netblocks with /size,
|
||||
# do-not-query-address: 127.0.0.1/8
|
||||
# do-not-query-address: ::1
|
||||
|
||||
# if yes, the above default do-not-query-address entries are present.
|
||||
# if no, localhost can be queried (for testing and debugging).
|
||||
# do-not-query-localhost: yes
|
||||
|
||||
# module configuration of the server. A string with identifiers
|
||||
# separated by spaces. "iterator" or "validator iterator"
|
||||
module-config: "validator python iterator"
|
||||
|
||||
# File with DLV trusted keys. Same format as trust-anchor-file.
|
||||
# There can be only one DLV configured, it is trusted from root down.
|
||||
# Download https://secure.isc.org/ops/dlv/dlv.isc.org.key
|
||||
# dlv-anchor-file: "dlv.isc.org.key"
|
||||
|
||||
# File with trusted keys for validation. Specify more than one file
|
||||
# with several entries, one file per entry.
|
||||
# Zone file format, with DS and DNSKEY entries.
|
||||
# trust-anchor-file: ""
|
||||
|
||||
# Trusted key for validation. DS or DNSKEY. specify the RR on a
|
||||
# single line, surrounded by "". TTL is ignored. class is IN default.
|
||||
# (These examples are from August 2007 and may not be valid anymore).
|
||||
# trust-anchor: "nlnetlabs.nl. DNSKEY 257 3 5 AQPzzTWMz8qSWIQlfRnPckx2BiVmkVN6LPupO3mbz7FhLSnm26n6iG9N Lby97Ji453aWZY3M5/xJBSOS2vWtco2t8C0+xeO1bc/d6ZTy32DHchpW 6rDH1vp86Ll+ha0tmwyy9QP7y2bVw5zSbFCrefk8qCUBgfHm9bHzMG1U BYtEIQ=="
|
||||
# trust-anchor: "jelte.nlnetlabs.nl. DS 42860 5 1 14D739EB566D2B1A5E216A0BA4D17FA9B038BE4A"
|
||||
|
||||
# File with trusted keys for validation. Specify more than one file
|
||||
# with several entries, one file per entry. Like trust-anchor-file
|
||||
# but has a different file format. Format is BIND-9 style format,
|
||||
# the trusted-keys { name flag proto algo "key"; }; clauses are read.
|
||||
# trusted-keys-file: ""
|
||||
|
||||
# Override the date for validation with a specific fixed date.
|
||||
# Do not set this unless you are debugging signature inception
|
||||
# and expiration. "" or "0" turns the feature off.
|
||||
# val-override-date: ""
|
||||
|
||||
# The time to live for bogus data, rrsets and messages. This avoids
|
||||
# some of the revalidation, until the time interval expires. in secs.
|
||||
# val-bogus-ttl: 60
|
||||
|
||||
# Should additional section of secure message also be kept clean of
|
||||
# unsecure data. Useful to shield the users of this validator from
|
||||
# potential bogus data in the additional section. All unsigned data
|
||||
# in the additional section is removed from secure messages.
|
||||
# val-clean-additional: yes
|
||||
|
||||
# Turn permissive mode on to permit bogus messages. Thus, messages
|
||||
# for which security checks failed will be returned to clients,
|
||||
# instead of SERVFAIL. It still performs the security checks, which
|
||||
# result in interesting log files and possibly the AD bit in
|
||||
# replies if the message is found secure. The default is off.
|
||||
# val-permissive-mode: no
|
||||
|
||||
# It is possible to configure NSEC3 maximum iteration counts per
|
||||
# keysize. Keep this table very short, as linear search is done.
|
||||
# A message with an NSEC3 with larger count is marked insecure.
|
||||
# List in ascending order the keysize and count values.
|
||||
# val-nsec3-keysize-iterations: "1024 150 2048 500 4096 2500"
|
||||
|
||||
# the amount of memory to use for the key cache.
|
||||
# plain value in bytes or you can append k, m or G. default is "4Mb".
|
||||
# key-cache-size: 4m
|
||||
|
||||
# the number of slabs to use for the key cache.
|
||||
# the number of slabs must be a power of 2.
|
||||
# more slabs reduce lock contention, but fragment memory usage.
|
||||
# key-cache-slabs: 4
|
||||
|
||||
# the amount of memory to use for the negative cache (used for DLV).
|
||||
# plain value in bytes or you can append k, m or G. default is "1Mb".
|
||||
# neg-cache-size: 1m
|
||||
|
||||
# a number of locally served zones can be configured.
|
||||
# local-zone: <zone> <type>
|
||||
# local-data: "<resource record string>"
|
||||
# o deny serves local data (if any), else, drops queries.
|
||||
# o refuse serves local data (if any), else, replies with error.
|
||||
# o static serves local data, else, nxdomain or nodata answer.
|
||||
# o transparent serves local data, else, resolves normally .
|
||||
# o redirect serves the zone data for any subdomain in the zone.
|
||||
# o nodefault can be used to normally resolve AS112 zones.
|
||||
#
|
||||
# defaults are localhost address, reverse for 127.0.0.1 and ::1
|
||||
# and nxdomain for AS112 zones. If you configure one of these zones
|
||||
# the default content is omitted, or you can omit it with 'nodefault'.
|
||||
#
|
||||
# If you configure local-data without specifying local-zone, by
|
||||
# default a transparent local-zone is created for the data.
|
||||
#
|
||||
# You can add locally served data with
|
||||
# local-zone: "local." static
|
||||
# local-data: "mycomputer.local. IN A 192.0.2.51"
|
||||
# local-data: 'mytext.local TXT "content of text record"'
|
||||
#
|
||||
# You can override certain queries with
|
||||
# local-data: "adserver.example.com A 127.0.0.1"
|
||||
#
|
||||
# You can redirect a domain to a fixed address with
|
||||
# (this makes example.com, www.example.com, etc, all go to 192.0.2.3)
|
||||
# local-zone: "example.com" redirect
|
||||
# local-data: "example.com A 192.0.2.3"
|
||||
#
|
||||
# Shorthand to make PTR records, "IPv4 name" or "IPv6 name".
|
||||
# You can also add PTR records using local-data directly, but then
|
||||
# you need to do the reverse notation yourself.
|
||||
# local-data-ptr: "192.0.2.3 www.example.com"
|
||||
|
||||
# Python config section
|
||||
python:
|
||||
# Script file to load
|
||||
python-script: "./examples/resgen.py"
|
||||
|
||||
# Remote control config section.
|
||||
remote-control:
|
||||
# Enable remote control with unbound-control(8) here.
|
||||
# set up the keys and certificates with unbound-control-setup.
|
||||
# control-enable: no
|
||||
|
||||
# what interfaces are listened to for remote control.
|
||||
# give 0.0.0.0 and ::0 to listen to all interfaces.
|
||||
# control-interface: 127.0.0.1
|
||||
# control-interface: ::1
|
||||
|
||||
# port number for remote control operations.
|
||||
# control-port: 953
|
||||
|
||||
# unbound server key file.
|
||||
# server-key-file: "/usr/local/etc/unbound/unbound_server.key"
|
||||
|
||||
# unbound server certificate file.
|
||||
# server-cert-file: "/usr/local/etc/unbound/unbound_server.pem"
|
||||
|
||||
# unbound-control key file.
|
||||
# control-key-file: "/usr/local/etc/unbound/unbound_control.key"
|
||||
|
||||
# unbound-control certificate file.
|
||||
# control-cert-file: "/usr/local/etc/unbound/unbound_control.pem"
|
||||
|
||||
# Stub zones.
|
||||
# Create entries like below, to make all queries for 'example.com' and
|
||||
# 'example.org' go to the given list of nameservers. list zero or more
|
||||
# nameservers by hostname or by ipaddress. If you set stub-prime to yes,
|
||||
# the list is treated as priming hints (default is no).
|
||||
# stub-zone:
|
||||
# name: "example.com"
|
||||
# stub-addr: 192.0.2.68
|
||||
# stub-prime: "no"
|
||||
# stub-zone:
|
||||
# name: "example.org"
|
||||
# stub-host: ns.example.com.
|
||||
|
||||
# Forward zones
|
||||
# Create entries like below, to make all queries for 'example.com' and
|
||||
# 'example.org' go to the given list of servers. These servers have to handle
|
||||
# recursion to other nameservers. List zero or more nameservers by hostname
|
||||
# or by ipaddress. Use an entry with name "." to forward all queries.
|
||||
# forward-zone:
|
||||
# name: "example.com"
|
||||
# forward-addr: 192.0.2.68
|
||||
# forward-addr: 192.0.2.73@5355 # forward to port 5355.
|
||||
# forward-zone:
|
||||
# name: "example.org"
|
||||
# forward-host: fwd.example.com
|
439
pythonmod/test-resmod.conf
Normal file
439
pythonmod/test-resmod.conf
Normal file
@ -0,0 +1,439 @@
|
||||
#
|
||||
# Example configuration file.
|
||||
#
|
||||
# See unbound.conf(5) man page.
|
||||
#
|
||||
# this is a comment.
|
||||
|
||||
#Use this to include other text into the file.
|
||||
#include: "otherfile.conf"
|
||||
|
||||
# The server clause sets the main parameters.
|
||||
server:
|
||||
# whitespace is not necessary, but looks cleaner.
|
||||
|
||||
# verbosity number, 0 is least verbose. 1 is default.
|
||||
verbosity: 1
|
||||
|
||||
# print statistics to the log (for every thread) every N seconds.
|
||||
# Set to "" or 0 to disable. Default is disabled.
|
||||
# statistics-interval: 0
|
||||
|
||||
# enable cumulative statistics, without clearing them after printing.
|
||||
# statistics-cumulative: no
|
||||
|
||||
# enable extended statistics (query types, answer codes, status)
|
||||
# printed from unbound-control. default off, because of speed.
|
||||
# extended-statistics: no
|
||||
|
||||
# number of threads to create. 1 disables threading.
|
||||
# num-threads: 1
|
||||
|
||||
# specify the interfaces to answer queries from by ip-address.
|
||||
# The default is to listen to localhost (127.0.0.1 and ::1).
|
||||
# specify 0.0.0.0 and ::0 to bind to all available interfaces.
|
||||
# specify every interface on a new 'interface:' labelled line.
|
||||
# The listen interfaces are not changed on reload, only on restart.
|
||||
interface: 0.0.0.0
|
||||
# interface: 192.0.2.154
|
||||
# interface: 2001:DB8::5
|
||||
|
||||
# enable this feature to copy the source address of queries to reply.
|
||||
# Socket options are not supported on all platforms. experimental.
|
||||
# interface-automatic: no
|
||||
|
||||
# port to answer queries from
|
||||
# port: 53
|
||||
|
||||
# specify the interfaces to send outgoing queries to authoritative
|
||||
# server from by ip-address. If none, the default (all) interface
|
||||
# is used. Specify every interface on a 'outgoing-interface:' line.
|
||||
# outgoing-interface: 192.0.2.153
|
||||
# outgoing-interface: 2001:DB8::5
|
||||
# outgoing-interface: 2001:DB8::6
|
||||
|
||||
# number of ports to allocate per thread, determines the size of the
|
||||
# port range that can be open simultaneously.
|
||||
# outgoing-range: 256
|
||||
|
||||
# permit unbound to use this port number or port range for
|
||||
# making outgoing queries, using an outgoing interface.
|
||||
# outgoing-port-permit: 32768
|
||||
|
||||
# deny unbound the use this of port number or port range for
|
||||
# making outgoing queries, using an outgoing interface.
|
||||
# Use this to make sure unbound does not grab a UDP port that some
|
||||
# other server on this computer needs. The default is to avoid
|
||||
# IANA-assigned port numbers.
|
||||
# outgoing-port-avoid: "3200-3208"
|
||||
|
||||
# number of outgoing simultaneous tcp buffers to hold per thread.
|
||||
# outgoing-num-tcp: 10
|
||||
|
||||
# number of incoming simultaneous tcp buffers to hold per thread.
|
||||
# incoming-num-tcp: 10
|
||||
|
||||
# buffer size for handling DNS data. No messages larger than this
|
||||
# size can be sent or received, by UDP or TCP. In bytes.
|
||||
# msg-buffer-size: 65552
|
||||
|
||||
# the amount of memory to use for the message cache.
|
||||
# plain value in bytes or you can append k, m or G. default is "4Mb".
|
||||
# msg-cache-size: 4m
|
||||
|
||||
# the number of slabs to use for the message cache.
|
||||
# the number of slabs must be a power of 2.
|
||||
# more slabs reduce lock contention, but fragment memory usage.
|
||||
# msg-cache-slabs: 4
|
||||
|
||||
# the number of queries that a thread gets to service.
|
||||
# num-queries-per-thread: 1024
|
||||
|
||||
# if very busy, 50% queries run to completion, 50% get timeout in msec
|
||||
# jostle-timeout: 200
|
||||
|
||||
# the amount of memory to use for the RRset cache.
|
||||
# plain value in bytes or you can append k, m or G. default is "4Mb".
|
||||
# rrset-cache-size: 4m
|
||||
|
||||
# the number of slabs to use for the RRset cache.
|
||||
# the number of slabs must be a power of 2.
|
||||
# more slabs reduce lock contention, but fragment memory usage.
|
||||
# rrset-cache-slabs: 4
|
||||
|
||||
# the time to live (TTL) value cap for RRsets and messages in the
|
||||
# cache. Items are not cached for longer. In seconds.
|
||||
# cache-max-ttl: 86400
|
||||
|
||||
# the time to live (TTL) value for cached roundtrip times and
|
||||
# EDNS version information for hosts. In seconds.
|
||||
# infra-host-ttl: 900
|
||||
|
||||
# the time to live (TTL) value for cached lame delegations. In sec.
|
||||
# infra-lame-ttl: 900
|
||||
|
||||
# the number of slabs to use for the Infrastructure cache.
|
||||
# the number of slabs must be a power of 2.
|
||||
# more slabs reduce lock contention, but fragment memory usage.
|
||||
# infra-cache-slabs: 4
|
||||
|
||||
# the maximum number of hosts that are cached (roundtrip times, EDNS).
|
||||
# infra-cache-numhosts: 10000
|
||||
|
||||
# the maximum size of the lame zones cached per host. in bytes.
|
||||
# infra-cache-lame-size: 10k
|
||||
|
||||
# Enable IPv4, "yes" or "no".
|
||||
# do-ip4: yes
|
||||
|
||||
# Enable IPv6, "yes" or "no".
|
||||
# do-ip6: yes
|
||||
|
||||
# Enable UDP, "yes" or "no".
|
||||
# do-udp: yes
|
||||
|
||||
# Enable TCP, "yes" or "no".
|
||||
# do-tcp: yes
|
||||
|
||||
# Detach from the terminal, run in background, "yes" or "no".
|
||||
do-daemonize: no
|
||||
|
||||
# control which clients are allowed to make (recursive) queries
|
||||
# to this server. Specify classless netblocks with /size and action.
|
||||
# By default everything is refused, except for localhost.
|
||||
# Choose deny (drop message), refuse (polite error reply),
|
||||
# allow (recursive ok), allow_snoop (recursive and nonrecursive ok)
|
||||
access-control: 0.0.0.0/0 allow
|
||||
# access-control: 127.0.0.0/8 allow
|
||||
# access-control: ::0/0 refuse
|
||||
# access-control: ::1 allow
|
||||
# access-control: ::ffff:127.0.0.1 allow
|
||||
|
||||
# if given, a chroot(2) is done to the given directory.
|
||||
# i.e. you can chroot to the working directory, for example,
|
||||
# for extra security, but make sure all files are in that directory.
|
||||
#
|
||||
# If chroot is enabled, you should pass the configfile (from the
|
||||
# commandline) as a full path from the original root. After the
|
||||
# chroot has been performed the now defunct portion of the config
|
||||
# file path is removed to be able to reread the config after a reload.
|
||||
#
|
||||
# All other file paths (working dir, logfile, roothints, and
|
||||
# key files) can be specified in several ways:
|
||||
# o as an absolute path relative to the new root.
|
||||
# o as a relative path to the working directory.
|
||||
# o as an absolute path relative to the original root.
|
||||
# In the last case the path is adjusted to remove the unused portion.
|
||||
#
|
||||
# The pid file can be absolute and outside of the chroot, it is
|
||||
# written just prior to performing the chroot and dropping permissions.
|
||||
#
|
||||
# Additionally, unbound may need to access /dev/random (for entropy).
|
||||
# How to do this is specific to your OS.
|
||||
#
|
||||
# If you give "" no chroot is performed. The path must not end in a /.
|
||||
chroot: ""
|
||||
|
||||
# if given, user privileges are dropped (after binding port),
|
||||
# and the given username is assumed. Default is user "unbound".
|
||||
# If you give "" no privileges are dropped.
|
||||
username: ""
|
||||
|
||||
# the working directory. The relative files in this config are
|
||||
# relative to this directory. If you give "" the working directory
|
||||
# is not changed.
|
||||
directory: ""
|
||||
|
||||
# the log file, "" means log to stderr.
|
||||
# Use of this option sets use-syslog to "no".
|
||||
logfile: ""
|
||||
|
||||
# Log to syslog(3) if yes. The log facility LOG_DAEMON is used to
|
||||
# log to, with identity "unbound". If yes, it overrides the logfile.
|
||||
# use-syslog: yes
|
||||
|
||||
# the pid file. Can be an absolute path outside of chroot/work dir.
|
||||
pidfile: "unbound.pid"
|
||||
|
||||
# file to read root hints from.
|
||||
# get one from ftp://FTP.INTERNIC.NET/domain/named.cache
|
||||
# root-hints: ""
|
||||
|
||||
# enable to not answer id.server and hostname.bind queries.
|
||||
# hide-identity: no
|
||||
|
||||
# enable to not answer version.server and version.bind queries.
|
||||
# hide-version: no
|
||||
|
||||
# the identity to report. Leave "" or default to return hostname.
|
||||
# identity: ""
|
||||
|
||||
# the version to report. Leave "" or default to return package version.
|
||||
# version: ""
|
||||
|
||||
# the target fetch policy.
|
||||
# series of integers describing the policy per dependency depth.
|
||||
# The number of values in the list determines the maximum dependency
|
||||
# depth the recursor will pursue before giving up. Each integer means:
|
||||
# -1 : fetch all targets opportunistically,
|
||||
# 0: fetch on demand,
|
||||
# positive value: fetch that many targets opportunistically.
|
||||
# Enclose the list of numbers between quotes ("").
|
||||
# target-fetch-policy: "3 2 1 0 0"
|
||||
|
||||
# Harden against very small EDNS buffer sizes.
|
||||
# harden-short-bufsize: no
|
||||
|
||||
# Harden against unseemly large queries.
|
||||
# harden-large-queries: no
|
||||
|
||||
# Harden against out of zone rrsets, to avoid spoofing attempts.
|
||||
# harden-glue: yes
|
||||
|
||||
# Harden against receiving dnssec-stripped data. If you turn it
|
||||
# off, failing to validate dnskey data for a trustanchor will
|
||||
# trigger insecure mode for that zone (like without a trustanchor).
|
||||
# Default on, which insists on dnssec data for trust-anchored zones.
|
||||
# harden-dnssec-stripped: yes
|
||||
|
||||
# Harden the referral path by performing additional queries for
|
||||
# infrastructure data. Validates the replies (if possible).
|
||||
# Default off, because the lookups burden the server. Experimental
|
||||
# implementation of draft-wijngaards-dnsext-resolver-side-mitigation.
|
||||
# harden-referral-path: no
|
||||
|
||||
# Use 0x20-encoded random bits in the query to foil spoof attempts.
|
||||
# This feature is an experimental implementation of draft dns-0x20.
|
||||
# use-caps-for-id: no
|
||||
|
||||
# Enforce privacy of these addresses. Strips them away from answers.
|
||||
# It may cause DNSSEC validation to additionally mark it as bogus.
|
||||
# Protects against 'DNS Rebinding' (uses browser as network proxy).
|
||||
# Only 'private-domain' and 'local-data' names are allowed to have
|
||||
# these private addresses. No default.
|
||||
# private-address: 10.0.0.0/8
|
||||
# private-address: 172.16.0.0/12
|
||||
# private-address: 192.168.0.0/16
|
||||
# private-address: 192.254.0.0/16
|
||||
# private-address: fd00::/8
|
||||
# private-address: fe80::/10
|
||||
|
||||
# Allow the domain (and its subdomains) to contain private addresses.
|
||||
# local-data statements are allowed to contain private addresses too.
|
||||
# private-domain: "example.com"
|
||||
|
||||
# If nonzero, unwanted replies are not only reported in statistics,
|
||||
# but also a running total is kept per thread. If it reaches the
|
||||
# threshold, a warning is printed and a defensive action is taken,
|
||||
# the cache is cleared to flush potential poison out of it.
|
||||
# A suggested value is 10000000, the default is 0 (turned off).
|
||||
# unwanted-reply-threshold: 0
|
||||
|
||||
# Do not query the following addresses. No DNS queries are sent there.
|
||||
# List one address per entry. List classless netblocks with /size,
|
||||
# do-not-query-address: 127.0.0.1/8
|
||||
# do-not-query-address: ::1
|
||||
|
||||
# if yes, the above default do-not-query-address entries are present.
|
||||
# if no, localhost can be queried (for testing and debugging).
|
||||
# do-not-query-localhost: yes
|
||||
|
||||
# module configuration of the server. A string with identifiers
|
||||
# separated by spaces. "iterator" or "validator iterator"
|
||||
#module-config: "python iterator"
|
||||
module-config: "validator python iterator"
|
||||
|
||||
# File with DLV trusted keys. Same format as trust-anchor-file.
|
||||
# There can be only one DLV configured, it is trusted from root down.
|
||||
# Download https://secure.isc.org/ops/dlv/dlv.isc.org.key
|
||||
# dlv-anchor-file: "dlv.isc.org.key"
|
||||
|
||||
# File with trusted keys for validation. Specify more than one file
|
||||
# with several entries, one file per entry.
|
||||
# Zone file format, with DS and DNSKEY entries.
|
||||
# trust-anchor-file: ""
|
||||
|
||||
# Trusted key for validation. DS or DNSKEY. specify the RR on a
|
||||
# single line, surrounded by "". TTL is ignored. class is IN default.
|
||||
# (These examples are from August 2007 and may not be valid anymore).
|
||||
# trust-anchor: "nlnetlabs.nl. DNSKEY 257 3 5 AQPzzTWMz8qSWIQlfRnPckx2BiVmkVN6LPupO3mbz7FhLSnm26n6iG9N Lby97Ji453aWZY3M5/xJBSOS2vWtco2t8C0+xeO1bc/d6ZTy32DHchpW 6rDH1vp86Ll+ha0tmwyy9QP7y2bVw5zSbFCrefk8qCUBgfHm9bHzMG1U BYtEIQ=="
|
||||
# trust-anchor: "jelte.nlnetlabs.nl. DS 42860 5 1 14D739EB566D2B1A5E216A0BA4D17FA9B038BE4A"
|
||||
|
||||
# File with trusted keys for validation. Specify more than one file
|
||||
# with several entries, one file per entry. Like trust-anchor-file
|
||||
# but has a different file format. Format is BIND-9 style format,
|
||||
# the trusted-keys { name flag proto algo "key"; }; clauses are read.
|
||||
# trusted-keys-file: ""
|
||||
|
||||
# Override the date for validation with a specific fixed date.
|
||||
# Do not set this unless you are debugging signature inception
|
||||
# and expiration. "" or "0" turns the feature off.
|
||||
# val-override-date: ""
|
||||
|
||||
# The time to live for bogus data, rrsets and messages. This avoids
|
||||
# some of the revalidation, until the time interval expires. in secs.
|
||||
# val-bogus-ttl: 60
|
||||
|
||||
# Should additional section of secure message also be kept clean of
|
||||
# unsecure data. Useful to shield the users of this validator from
|
||||
# potential bogus data in the additional section. All unsigned data
|
||||
# in the additional section is removed from secure messages.
|
||||
# val-clean-additional: yes
|
||||
|
||||
# Turn permissive mode on to permit bogus messages. Thus, messages
|
||||
# for which security checks failed will be returned to clients,
|
||||
# instead of SERVFAIL. It still performs the security checks, which
|
||||
# result in interesting log files and possibly the AD bit in
|
||||
# replies if the message is found secure. The default is off.
|
||||
# val-permissive-mode: no
|
||||
|
||||
# It is possible to configure NSEC3 maximum iteration counts per
|
||||
# keysize. Keep this table very short, as linear search is done.
|
||||
# A message with an NSEC3 with larger count is marked insecure.
|
||||
# List in ascending order the keysize and count values.
|
||||
# val-nsec3-keysize-iterations: "1024 150 2048 500 4096 2500"
|
||||
|
||||
# the amount of memory to use for the key cache.
|
||||
# plain value in bytes or you can append k, m or G. default is "4Mb".
|
||||
# key-cache-size: 4m
|
||||
|
||||
# the number of slabs to use for the key cache.
|
||||
# the number of slabs must be a power of 2.
|
||||
# more slabs reduce lock contention, but fragment memory usage.
|
||||
# key-cache-slabs: 4
|
||||
|
||||
# the amount of memory to use for the negative cache (used for DLV).
|
||||
# plain value in bytes or you can append k, m or G. default is "1Mb".
|
||||
# neg-cache-size: 1m
|
||||
|
||||
# a number of locally served zones can be configured.
|
||||
# local-zone: <zone> <type>
|
||||
# local-data: "<resource record string>"
|
||||
# o deny serves local data (if any), else, drops queries.
|
||||
# o refuse serves local data (if any), else, replies with error.
|
||||
# o static serves local data, else, nxdomain or nodata answer.
|
||||
# o transparent serves local data, else, resolves normally .
|
||||
# o redirect serves the zone data for any subdomain in the zone.
|
||||
# o nodefault can be used to normally resolve AS112 zones.
|
||||
#
|
||||
# defaults are localhost address, reverse for 127.0.0.1 and ::1
|
||||
# and nxdomain for AS112 zones. If you configure one of these zones
|
||||
# the default content is omitted, or you can omit it with 'nodefault'.
|
||||
#
|
||||
# If you configure local-data without specifying local-zone, by
|
||||
# default a transparent local-zone is created for the data.
|
||||
#
|
||||
# You can add locally served data with
|
||||
# local-zone: "local." static
|
||||
# local-data: "mycomputer.local. IN A 192.0.2.51"
|
||||
# local-data: 'mytext.local TXT "content of text record"'
|
||||
#
|
||||
# You can override certain queries with
|
||||
# local-data: "adserver.example.com A 127.0.0.1"
|
||||
#
|
||||
# You can redirect a domain to a fixed address with
|
||||
# (this makes example.com, www.example.com, etc, all go to 192.0.2.3)
|
||||
# local-zone: "example.com" redirect
|
||||
# local-data: "example.com A 192.0.2.3"
|
||||
#
|
||||
# Shorthand to make PTR records, "IPv4 name" or "IPv6 name".
|
||||
# You can also add PTR records using local-data directly, but then
|
||||
# you need to do the reverse notation yourself.
|
||||
# local-data-ptr: "192.0.2.3 www.example.com"
|
||||
|
||||
# Python config section
|
||||
python:
|
||||
# Script file to load
|
||||
python-script: "./examples/resmod.py"
|
||||
|
||||
# Remote control config section.
|
||||
remote-control:
|
||||
# Enable remote control with unbound-control(8) here.
|
||||
# set up the keys and certificates with unbound-control-setup.
|
||||
# control-enable: no
|
||||
|
||||
# what interfaces are listened to for remote control.
|
||||
# give 0.0.0.0 and ::0 to listen to all interfaces.
|
||||
# control-interface: 127.0.0.1
|
||||
# control-interface: ::1
|
||||
|
||||
# port number for remote control operations.
|
||||
# control-port: 953
|
||||
|
||||
# unbound server key file.
|
||||
# server-key-file: "/usr/local/etc/unbound/unbound_server.key"
|
||||
|
||||
# unbound server certificate file.
|
||||
# server-cert-file: "/usr/local/etc/unbound/unbound_server.pem"
|
||||
|
||||
# unbound-control key file.
|
||||
# control-key-file: "/usr/local/etc/unbound/unbound_control.key"
|
||||
|
||||
# unbound-control certificate file.
|
||||
# control-cert-file: "/usr/local/etc/unbound/unbound_control.pem"
|
||||
|
||||
# Stub zones.
|
||||
# Create entries like below, to make all queries for 'example.com' and
|
||||
# 'example.org' go to the given list of nameservers. list zero or more
|
||||
# nameservers by hostname or by ipaddress. If you set stub-prime to yes,
|
||||
# the list is treated as priming hints (default is no).
|
||||
# stub-zone:
|
||||
# name: "example.com"
|
||||
# stub-addr: 192.0.2.68
|
||||
# stub-prime: "no"
|
||||
# stub-zone:
|
||||
# name: "example.org"
|
||||
# stub-host: ns.example.com.
|
||||
|
||||
# Forward zones
|
||||
# Create entries like below, to make all queries for 'example.com' and
|
||||
# 'example.org' go to the given list of servers. These servers have to handle
|
||||
# recursion to other nameservers. List zero or more nameservers by hostname
|
||||
# or by ipaddress. Use an entry with name "." to forward all queries.
|
||||
# forward-zone:
|
||||
# name: "example.com"
|
||||
# forward-addr: 192.0.2.68
|
||||
# forward-addr: 192.0.2.73@5355 # forward to port 5355.
|
||||
# forward-zone:
|
||||
# name: "example.org"
|
||||
# forward-host: fwd.example.com
|
156
pythonmod/ubmodule-msg.py
Normal file
156
pythonmod/ubmodule-msg.py
Normal file
@ -0,0 +1,156 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
ubmodule-msg.py: simple response packet logger
|
||||
|
||||
Authors: Zdenek Vasicek (vasicek AT fit.vutbr.cz)
|
||||
Marek Vavrusa (xvavru00 AT stud.fit.vutbr.cz)
|
||||
|
||||
Copyright (c) 2008. All rights reserved.
|
||||
|
||||
This software is open source.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
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 REGENTS 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.
|
||||
'''
|
||||
import os
|
||||
|
||||
def init(id, cfg):
|
||||
log_info("pythonmod: init called, module id is %d port: %d script: %s" % (id, cfg.port, cfg.python_script))
|
||||
return True
|
||||
|
||||
def deinit(id):
|
||||
log_info("pythonmod: deinit called, module id is %d" % id)
|
||||
return True
|
||||
|
||||
def inform_super(id, qstate, superqstate, qdata):
|
||||
return True
|
||||
|
||||
def setTTL(qstate, ttl):
|
||||
"""Sets return_msg TTL and all the RRs TTL"""
|
||||
if qstate.return_msg:
|
||||
qstate.return_msg.rep.ttl = ttl
|
||||
if (qstate.return_msg.rep):
|
||||
for i in range(0,qstate.return_msg.rep.rrset_count):
|
||||
d = qstate.return_msg.rep.rrsets[i].entry.data
|
||||
for j in range(0,d.count+d.rrsig_count):
|
||||
d.rr_ttl[j] = ttl
|
||||
|
||||
def dataHex(data, prefix=""):
|
||||
res = ""
|
||||
for i in range(0, (len(data)+15)/16):
|
||||
res += "%s0x%02X | " % (prefix, i*16)
|
||||
d = map(lambda x:ord(x), data[i*16:i*16+17])
|
||||
for ch in d:
|
||||
res += "%02X " % ch
|
||||
for i in range(0,17-len(d)):
|
||||
res += " "
|
||||
res += "| "
|
||||
for ch in d:
|
||||
if (ch < 32) or (ch > 127):
|
||||
res += ". "
|
||||
else:
|
||||
res += "%c " % ch
|
||||
res += "\n"
|
||||
return res
|
||||
|
||||
def printReturnMsg(qstate):
|
||||
print "Return MSG rep :: flags: %04X, QDcount: %d, Security:%d, TTL=%d" % (qstate.return_msg.rep.flags, qstate.return_msg.rep.qdcount,qstate.return_msg.rep.security, qstate.return_msg.rep.ttl)
|
||||
print " qinfo :: qname:",qstate.return_msg.qinfo.qname_list, qstate.return_msg.qinfo.qname_str, "type:",qstate.return_msg.qinfo.qtype_str, "class:",qstate.return_msg.qinfo.qclass_str
|
||||
if (qstate.return_msg.rep):
|
||||
print "RRSets:",qstate.return_msg.rep.rrset_count
|
||||
prevkey = None
|
||||
for i in range(0,qstate.return_msg.rep.rrset_count):
|
||||
r = qstate.return_msg.rep.rrsets[i]
|
||||
rk = r.rk
|
||||
print i,":",rk.dname_list, rk.dname_str, "flags: %04X" % rk.flags,
|
||||
print "type:",rk.type_str,"(%d)" % ntohs(rk.type), "class:",rk.rrset_class_str,"(%d)" % ntohs(rk.rrset_class)
|
||||
|
||||
d = r.entry.data
|
||||
print " RRDatas:",d.count+d.rrsig_count
|
||||
for j in range(0,d.count+d.rrsig_count):
|
||||
print " ",j,":","TTL=",d.rr_ttl[j],"RR data:"
|
||||
print dataHex(d.rr_data[j]," ")
|
||||
|
||||
|
||||
def operate(id, event, qstate, qdata):
|
||||
log_info("pythonmod: operate called, id: %d, event:%s" % (id, strmodulevent(event)))
|
||||
#print "pythonmod: per query data", qdata
|
||||
|
||||
print "Query:", ''.join(map(lambda x:chr(max(32,ord(x))),qstate.qinfo.qname)), qstate.qinfo.qname_list, qstate.qinfo.qname_str,
|
||||
print "Type:",qstate.qinfo.qtype_str,"(%d)" % qstate.qinfo.qtype,
|
||||
print "Class:",qstate.qinfo.qclass_str,"(%d)" % qstate.qinfo.qclass
|
||||
print
|
||||
|
||||
#if event == MODULE_EVENT_PASS: #pokud mame "validator python iterator"
|
||||
if (event == MODULE_EVENT_NEW) and (qstate.qinfo.qname_str.endswith(".seznam.cz.")): #pokud mame "python validator iterator"
|
||||
print qstate.qinfo.qname_str
|
||||
|
||||
qstate.ext_state[id] = MODULE_FINISHED
|
||||
|
||||
msg = DNSMessage(qstate.qinfo.qname_str, RR_TYPE_A, RR_CLASS_IN, PKT_QR | PKT_RA | PKT_AA) #, 300)
|
||||
#msg.authority.append("xxx.seznam.cz. 10 IN A 192.168.1.1")
|
||||
#msg.additional.append("yyy.seznam.cz. 10 IN A 1.1.1.2.")
|
||||
|
||||
if qstate.qinfo.qtype == RR_TYPE_A:
|
||||
msg.answer.append("%s 10 IN A 192.168.1.1" % qstate.qinfo.qname_str)
|
||||
if (qstate.qinfo.qtype == RR_TYPE_SRV) or (qstate.qinfo.qtype == RR_TYPE_ANY):
|
||||
msg.answer.append("%s 10 IN SRV 0 0 80 neinfo.example.com." % qstate.qinfo.qname_str)
|
||||
if (qstate.qinfo.qtype == RR_TYPE_TXT) or (qstate.qinfo.qtype == RR_TYPE_ANY):
|
||||
msg.answer.append("%s 10 IN TXT path=/" % qstate.qinfo.qname_str)
|
||||
|
||||
if not msg.set_return_msg(qstate):
|
||||
qstate.ext_state[id] = MODULE_ERROR
|
||||
return True
|
||||
|
||||
#qstate.return_msg.rep.security = 2 #pokud nebude nasledovat validator, je zapotrebi nastavit security, aby nebyl paket zahozen v mesh_send_reply
|
||||
printReturnMsg(qstate)
|
||||
|
||||
#Authoritative result can't be stored in cache
|
||||
#if (not storeQueryInCache(qstate, qstate.return_msg.qinfo, qstate.return_msg.rep, 0)):
|
||||
# print "Can't store in cache"
|
||||
# qstate.ext_state[id] = MODULE_ERROR
|
||||
# return False
|
||||
#print "Store OK"
|
||||
|
||||
qstate.return_rcode = RCODE_NOERROR
|
||||
return True
|
||||
|
||||
if event == MODULE_EVENT_NEW:
|
||||
qstate.ext_state[id] = MODULE_WAIT_MODULE
|
||||
return True
|
||||
|
||||
if event == MODULE_EVENT_MODDONE:
|
||||
log_info("pythonmod: previous module done")
|
||||
qstate.ext_state[id] = MODULE_FINISHED
|
||||
return True
|
||||
|
||||
if event == MODULE_EVENT_PASS:
|
||||
log_info("pythonmod: event_pass")
|
||||
qstate.ext_state[id] = MODULE_ERROR
|
||||
return True
|
||||
|
||||
log_err("pythonmod: BAD event")
|
||||
qstate.ext_state[id] = MODULE_ERROR
|
||||
return True
|
||||
|
||||
log_info("pythonmod: script loaded.")
|
149
pythonmod/ubmodule-tst.py
Normal file
149
pythonmod/ubmodule-tst.py
Normal file
@ -0,0 +1,149 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
ubmodule-tst.py:
|
||||
|
||||
Authors: Zdenek Vasicek (vasicek AT fit.vutbr.cz)
|
||||
Marek Vavrusa (xvavru00 AT stud.fit.vutbr.cz)
|
||||
|
||||
Copyright (c) 2008. All rights reserved.
|
||||
|
||||
This software is open source.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
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 REGENTS 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.
|
||||
'''
|
||||
def init(id, cfg):
|
||||
log_info("pythonmod: init called, module id is %d port: %d script: %s" % (id, cfg.port, cfg.python_script))
|
||||
return True
|
||||
|
||||
def deinit(id):
|
||||
log_info("pythonmod: deinit called, module id is %d" % id)
|
||||
return True
|
||||
|
||||
def inform_super(id, qstate, superqstate, qdata):
|
||||
return True
|
||||
|
||||
def setTTL(qstate, ttl):
|
||||
"""Sets return_msg TTL and all the RRs TTL"""
|
||||
if qstate.return_msg:
|
||||
qstate.return_msg.rep.ttl = ttl
|
||||
if (qstate.return_msg.rep):
|
||||
for i in range(0,qstate.return_msg.rep.rrset_count):
|
||||
d = qstate.return_msg.rep.rrsets[i].entry.data
|
||||
for j in range(0,d.count+d.rrsig_count):
|
||||
d.rr_ttl[j] = ttl
|
||||
|
||||
def dataHex(data, prefix=""):
|
||||
res = ""
|
||||
for i in range(0, (len(data)+15)/16):
|
||||
res += "%s0x%02X | " % (prefix, i*16)
|
||||
d = map(lambda x:ord(x), data[i*16:i*16+17])
|
||||
for ch in d:
|
||||
res += "%02X " % ch
|
||||
for i in range(0,17-len(d)):
|
||||
res += " "
|
||||
res += "| "
|
||||
for ch in d:
|
||||
if (ch < 32) or (ch > 127):
|
||||
res += ". "
|
||||
else:
|
||||
res += "%c " % ch
|
||||
res += "\n"
|
||||
return res
|
||||
|
||||
def printReturnMsg(qstate):
|
||||
print "Return MSG rep :: flags: %04X, QDcount: %d, Security:%d, TTL=%d" % (qstate.return_msg.rep.flags, qstate.return_msg.rep.qdcount,qstate.return_msg.rep.security, qstate.return_msg.rep.ttl)
|
||||
print " qinfo :: qname:",qstate.return_msg.qinfo.qname_list, qstate.return_msg.qinfo.qname_str, "type:",qstate.return_msg.qinfo.qtype_str, "class:",qstate.return_msg.qinfo.qclass_str
|
||||
if (qstate.return_msg.rep):
|
||||
print "RRSets:",qstate.return_msg.rep.rrset_count
|
||||
prevkey = None
|
||||
for i in range(0,qstate.return_msg.rep.rrset_count):
|
||||
r = qstate.return_msg.rep.rrsets[i]
|
||||
rk = r.rk
|
||||
print i,":",rk.dname_list, rk.dname_str, "flags: %04X" % rk.flags,
|
||||
print "type:",rk.type_str,"(%d)" % ntohs(rk.type), "class:",rk.rrset_class_str,"(%d)" % ntohs(rk.rrset_class)
|
||||
|
||||
d = r.entry.data
|
||||
print " RRDatas:",d.count+d.rrsig_count
|
||||
for j in range(0,d.count+d.rrsig_count):
|
||||
print " ",j,":","TTL=",d.rr_ttl[j],"RR data:"
|
||||
print dataHex(d.rr_data[j]," ")
|
||||
|
||||
def operate(id, event, qstate, qdata):
|
||||
log_info("pythonmod: operate called, id: %d, event:%s" % (id, strmodulevent(event)))
|
||||
#print "pythonmod: per query data", qdata
|
||||
|
||||
print "Query:", ''.join(map(lambda x:chr(max(32,ord(x))),qstate.qinfo.qname)), qstate.qinfo.qname_list,
|
||||
print "Type:",qstate.qinfo.qtype_str,"(%d)" % qstate.qinfo.qtype,
|
||||
print "Class:",qstate.qinfo.qclass_str,"(%d)" % qstate.qinfo.qclass
|
||||
print
|
||||
|
||||
# TEST:
|
||||
# > dig @127.0.0.1 www.seznam.cz A
|
||||
# > dig @127.0.0.1 3.76.75.77.in-addr.arpa. PTR
|
||||
# prvni dva dotazy vrati TTL 100
|
||||
# > dig @127.0.0.1 www.seznam.cz A
|
||||
# > dig @127.0.0.1 3.76.75.77.in-addr.arpa. PTR
|
||||
# dalsi dva dotazy vrati TTL 10, ktere se bude s dalsimi dotazy snizovat, nez vyprsi a znovu se zaktivuje mesh
|
||||
|
||||
if qstate.return_msg:
|
||||
printReturnMsg(qstate)
|
||||
|
||||
#qdn = '.'.join(qstate.qinfo.qname_list)
|
||||
qdn = qstate.qinfo.qname_str
|
||||
|
||||
#Pokud dotaz konci na nasledujici, pozmenime TTL zpravy, ktera se posle klientovi (return_msg) i zpravy v CACHE
|
||||
if qdn.endswith(".seznam.cz.") or qdn.endswith('.in-addr.arpa.'):
|
||||
#pokud je v cache odpoved z iteratoru, pak ji zneplatnime, jinak se moduly nazavolaji do te doby, nez vyprsi TTL
|
||||
invalidateQueryInCache(qstate, qstate.return_msg.qinfo)
|
||||
|
||||
if (qstate.return_msg.rep.authoritative):
|
||||
print "X"*300
|
||||
|
||||
setTTL(qstate, 10) #do cache nastavime TTL na 10
|
||||
if not storeQueryInCache(qstate, qstate.return_msg.qinfo, qstate.return_msg.rep, 0):
|
||||
qstate.ext_state[id] = MODULE_ERROR
|
||||
return False
|
||||
|
||||
setTTL(qstate, 100) #odpoved klientovi prijde s TTL 100
|
||||
qstate.return_rcode = RCODE_NOERROR
|
||||
|
||||
if event == MODULE_EVENT_NEW:
|
||||
qstate.ext_state[id] = MODULE_WAIT_MODULE
|
||||
return True
|
||||
|
||||
if event == MODULE_EVENT_MODDONE:
|
||||
log_info("pythonmod: previous module done")
|
||||
qstate.ext_state[id] = MODULE_FINISHED
|
||||
return True
|
||||
|
||||
if event == MODULE_EVENT_PASS:
|
||||
log_info("pythonmod: event_pass")
|
||||
qstate.ext_state[id] = MODULE_ERROR
|
||||
return True
|
||||
|
||||
log_err("pythonmod: BAD event")
|
||||
qstate.ext_state[id] = MODULE_ERROR
|
||||
return True
|
||||
|
||||
log_info("pythonmod: script loaded.")
|
3
services/cache/dns.c
vendored
3
services/cache/dns.c
vendored
@ -432,6 +432,7 @@ tomsg(struct module_env* env, struct msgreply_entry* e, struct reply_info* r,
|
||||
msg->rep->ns_numrrsets = r->ns_numrrsets;
|
||||
msg->rep->ar_numrrsets = r->ar_numrrsets;
|
||||
msg->rep->rrset_count = r->rrset_count;
|
||||
msg->rep->authoritative = r->authoritative;
|
||||
if(!rrset_array_lock(r->ref, r->rrset_count, now))
|
||||
return NULL;
|
||||
for(i=0; i<msg->rep->rrset_count; i++) {
|
||||
@ -461,6 +462,7 @@ rrset_msg(struct ub_packed_rrset_key* rrset, struct regional* region,
|
||||
if(!msg)
|
||||
return NULL;
|
||||
msg->rep->flags = BIT_QR; /* reply, no AA, no error */
|
||||
msg->rep->authoritative = 0; /* reply stored in cache can't be authoritative */
|
||||
msg->rep->qdcount = 1;
|
||||
msg->rep->ttl = d->ttl - now;
|
||||
msg->rep->security = sec_status_unchecked;
|
||||
@ -495,6 +497,7 @@ synth_dname_msg(struct ub_packed_rrset_key* rrset, struct regional* region,
|
||||
if(!msg)
|
||||
return NULL;
|
||||
msg->rep->flags = BIT_QR; /* reply, no AA, no error */
|
||||
msg->rep->authoritative = 0; /* reply stored in cache can't be authoritative */
|
||||
msg->rep->qdcount = 1;
|
||||
msg->rep->ttl = d->ttl - now;
|
||||
msg->rep->security = sec_status_unchecked;
|
||||
|
@ -120,7 +120,7 @@ local_data_cmp(const void* d1, const void* d2)
|
||||
}
|
||||
|
||||
/** form wireformat from text format domain name */
|
||||
static int
|
||||
int
|
||||
parse_dname(const char* str, uint8_t** res, size_t* len, int* labs)
|
||||
{
|
||||
ldns_rdf* rdf;
|
||||
|
@ -294,4 +294,10 @@ int local_zones_add_RR(struct local_zones* zones, const char* rr,
|
||||
void local_zones_del_data(struct local_zones* zones,
|
||||
uint8_t* name, size_t len, int labs, uint16_t dclass);
|
||||
|
||||
|
||||
/**
|
||||
* Form wireformat from text format domain name.
|
||||
*/
|
||||
int parse_dname(const char* str, uint8_t** res, size_t* len, int* labs);
|
||||
|
||||
#endif /* SERVICES_LOCALZONE_H */
|
||||
|
@ -45,6 +45,10 @@
|
||||
#include "iterator/iterator.h"
|
||||
#include "validator/validator.h"
|
||||
|
||||
#ifdef WITH_PYTHONMODULE
|
||||
#include "pythonmod/pythonmod.h"
|
||||
#endif
|
||||
|
||||
/** count number of modules (words) in the string */
|
||||
static int
|
||||
count_modules(const char* s)
|
||||
@ -109,21 +113,29 @@ struct
|
||||
module_func_block* module_factory(const char** str)
|
||||
{
|
||||
/* these are the modules available */
|
||||
int num = 2;
|
||||
const char* names[] = {"iterator", "validator", NULL};
|
||||
const char* names[] = {"iterator", "validator",
|
||||
#ifdef WITH_PYTHONMODULE
|
||||
"python",
|
||||
#endif
|
||||
NULL};
|
||||
struct module_func_block* (*fb[])(void) =
|
||||
{&iter_get_funcblock, &val_get_funcblock, NULL};
|
||||
{&iter_get_funcblock, &val_get_funcblock,
|
||||
#ifdef WITH_PYTHONMODULE
|
||||
&pythonmod_get_funcblock,
|
||||
#endif
|
||||
NULL};
|
||||
|
||||
int i;
|
||||
int i = 0;
|
||||
const char* s = *str;
|
||||
while(*s && isspace((int)*s))
|
||||
s++;
|
||||
for(i=0; i<num; i++) {
|
||||
while(names[i]) {
|
||||
if(strncmp(names[i], s, strlen(names[i])) == 0) {
|
||||
s += strlen(names[i]);
|
||||
*str = s;
|
||||
return (*fb[i])();
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
@ -61,6 +61,9 @@
|
||||
#ifdef HAVE_GLOB_H
|
||||
#include <glob.h>
|
||||
#endif
|
||||
#ifdef WITH_PYTHONMODULE
|
||||
#include "pythonmod/pythonmod.h"
|
||||
#endif
|
||||
|
||||
/** Give checkconf usage, and exit (1). */
|
||||
static void
|
||||
@ -547,6 +550,9 @@ checkconf(const char* cfgfile, const char* opt)
|
||||
morechecks(cfg, cfgfile);
|
||||
check_mod(cfg, iter_get_funcblock());
|
||||
check_mod(cfg, val_get_funcblock());
|
||||
#ifdef WITH_PYTHONMODULE
|
||||
check_mod(cfg, pythonmod_get_funcblock());
|
||||
#endif
|
||||
check_fwd(cfg);
|
||||
if(opt) print_option(cfg, opt);
|
||||
else printf("unbound-checkconf: no errors in %s\n", cfgfile);
|
||||
|
@ -157,6 +157,8 @@ config_create()
|
||||
cfg->local_zones_nodefault = NULL;
|
||||
cfg->local_data = NULL;
|
||||
|
||||
if(!(cfg->python_script = strdup(SHARE_DIR"/ubmodule.py")))
|
||||
goto error_exit;
|
||||
cfg->remote_control_enable = 0;
|
||||
cfg->control_ifs = NULL;
|
||||
cfg->control_port = 953;
|
||||
@ -384,6 +386,8 @@ int config_set_option(struct config_file* cfg, const char* opt,
|
||||
return cfg_parse_memsize(val, &cfg->neg_cache_size);
|
||||
} else if(strcmp(opt, "local-data:") == 0) {
|
||||
return cfg_strlist_insert(&cfg->local_data, strdup(val));
|
||||
} else if(strcmp(opt, "local-zone:") == 0) {
|
||||
return cfg_parse_local_zone(cfg, val);
|
||||
} else if(strcmp(opt, "control-enable:") == 0) {
|
||||
IS_YES_OR_NO;
|
||||
cfg->remote_control_enable = (strcmp(val, "yes") == 0);
|
||||
@ -407,6 +411,9 @@ int config_set_option(struct config_file* cfg, const char* opt,
|
||||
} else if(strcmp(opt, "module-config:") == 0) {
|
||||
free(cfg->module_conf);
|
||||
return (cfg->module_conf = strdup(val)) != NULL;
|
||||
} else if(strcmp(opt, "python-script:") == 0) {
|
||||
free(cfg->python_script);
|
||||
return (cfg->python_script = strdup(val)) != NULL;
|
||||
} else {
|
||||
/* unknown or unsupported (from the library interface) */
|
||||
return 0;
|
||||
@ -917,7 +924,7 @@ fname_after_chroot(const char* fname, struct config_file* cfg, int use_chdir)
|
||||
}
|
||||
|
||||
/** return next space character in string */
|
||||
static char* next_space_pos(char* str)
|
||||
static char* next_space_pos(const char* str)
|
||||
{
|
||||
char* sp = strchr(str, ' ');
|
||||
char* tab = strchr(str, '\t');
|
||||
@ -929,7 +936,7 @@ static char* next_space_pos(char* str)
|
||||
}
|
||||
|
||||
/** return last space character in string */
|
||||
static char* last_space_pos(char* str)
|
||||
static char* last_space_pos(const char* str)
|
||||
{
|
||||
char* sp = strrchr(str, ' ');
|
||||
char* tab = strrchr(str, '\t');
|
||||
@ -940,6 +947,49 @@ static char* last_space_pos(char* str)
|
||||
return (sp>tab)?sp:tab;
|
||||
}
|
||||
|
||||
int
|
||||
cfg_parse_local_zone(struct config_file* cfg, const char* val)
|
||||
{
|
||||
const char *type, *name_end, *name;
|
||||
char buf[256];
|
||||
|
||||
/* parse it as: [zone_name] [between stuff] [zone_type] */
|
||||
name = val;
|
||||
while(*name && isspace(*name))
|
||||
name++;
|
||||
if(!*name) {
|
||||
log_err("syntax error: too short: %s", val);
|
||||
return 0;
|
||||
}
|
||||
name_end = next_space_pos(name);
|
||||
if(!name_end || !*name_end) {
|
||||
log_err("syntax error: expected zone type: %s", val);
|
||||
return 0;
|
||||
}
|
||||
if (name_end - name > 255) {
|
||||
log_err("syntax error: bad zone name: %s", val);
|
||||
return 0;
|
||||
}
|
||||
strncpy(buf, name, (size_t)(name_end-name));
|
||||
buf[name_end-name] = '\0';
|
||||
|
||||
type = last_space_pos(name_end);
|
||||
while(type && *type && isspace(*type))
|
||||
type++;
|
||||
if(!type || !*type) {
|
||||
log_err("syntax error: expected zone type: %s", val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(strcmp(type, "nodefault")==0) {
|
||||
return cfg_strlist_insert(&cfg->local_zones_nodefault,
|
||||
strdup(name));
|
||||
} else {
|
||||
return cfg_str2list_insert(&cfg->local_zones, strdup(buf),
|
||||
strdup(type));
|
||||
}
|
||||
}
|
||||
|
||||
char* cfg_ptr_reverse(char* str)
|
||||
{
|
||||
char* ip, *ip_end;
|
||||
|
@ -241,6 +241,9 @@ struct config_file {
|
||||
/** certificate file for unbound-control */
|
||||
char* control_cert_file;
|
||||
|
||||
/** Python script file */
|
||||
char* python_script;
|
||||
|
||||
/** daemonize, i.e. fork into the background. */
|
||||
int do_daemonize;
|
||||
};
|
||||
@ -394,6 +397,14 @@ int cfg_count_numbers(const char* str);
|
||||
*/
|
||||
int cfg_parse_memsize(const char* str, size_t* res);
|
||||
|
||||
/**
|
||||
* Parse local-zone directive into two strings and register it in the config.
|
||||
* @param cfg: to put it in.
|
||||
* @param val: argument strings to local-zone, "example.com nodefault".
|
||||
* @return: false on failure
|
||||
*/
|
||||
int cfg_parse_local_zone(struct config_file* cfg, const char* val);
|
||||
|
||||
/**
|
||||
* Mark "number" or "low-high" as available or not in ports array.
|
||||
* @param str: string in input
|
||||
|
1645
util/configlexer.c
1645
util/configlexer.c
File diff suppressed because it is too large
Load Diff
@ -214,6 +214,8 @@ server-key-file{COLON} { YDVAR(1, VAR_SERVER_KEY_FILE) }
|
||||
server-cert-file{COLON} { YDVAR(1, VAR_SERVER_CERT_FILE) }
|
||||
control-key-file{COLON} { YDVAR(1, VAR_CONTROL_KEY_FILE) }
|
||||
control-cert-file{COLON} { YDVAR(1, VAR_CONTROL_CERT_FILE) }
|
||||
python-script{COLON} { YDVAR(1, VAR_PYTHON_SCRIPT) }
|
||||
python{COLON} { YDVAR(0, VAR_PYTHON) }
|
||||
domain-insecure{COLON} { YDVAR(1, VAR_DOMAIN_INSECURE) }
|
||||
<INITIAL,val>{NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++; }
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -138,7 +138,9 @@
|
||||
VAR_STUB_PRIME = 354,
|
||||
VAR_UNWANTED_REPLY_THRESHOLD = 355,
|
||||
VAR_LOG_TIME_ASCII = 356,
|
||||
VAR_DOMAIN_INSECURE = 357
|
||||
VAR_DOMAIN_INSECURE = 357,
|
||||
VAR_PYTHON = 358,
|
||||
VAR_PYTHON_SCRIPT = 359
|
||||
};
|
||||
#endif
|
||||
/* Tokens. */
|
||||
@ -242,6 +244,8 @@
|
||||
#define VAR_UNWANTED_REPLY_THRESHOLD 355
|
||||
#define VAR_LOG_TIME_ASCII 356
|
||||
#define VAR_DOMAIN_INSECURE 357
|
||||
#define VAR_PYTHON 358
|
||||
#define VAR_PYTHON_SCRIPT 359
|
||||
|
||||
|
||||
|
||||
@ -253,7 +257,7 @@ typedef union YYSTYPE
|
||||
char* str;
|
||||
}
|
||||
/* Line 1489 of yacc.c. */
|
||||
#line 257 "util/configparser.h"
|
||||
#line 261 "util/configparser.h"
|
||||
YYSTYPE;
|
||||
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
|
@ -97,12 +97,13 @@ extern struct config_parser_state* cfg_parser;
|
||||
%token VAR_SERVER_CERT_FILE VAR_CONTROL_KEY_FILE VAR_CONTROL_CERT_FILE
|
||||
%token VAR_EXTENDED_STATISTICS VAR_LOCAL_DATA_PTR VAR_JOSTLE_TIMEOUT
|
||||
%token VAR_STUB_PRIME VAR_UNWANTED_REPLY_THRESHOLD VAR_LOG_TIME_ASCII
|
||||
%token VAR_DOMAIN_INSECURE
|
||||
%token VAR_DOMAIN_INSECURE VAR_PYTHON VAR_PYTHON_SCRIPT
|
||||
|
||||
%%
|
||||
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
|
||||
toplevelvar: serverstart contents_server | stubstart contents_stub |
|
||||
forwardstart contents_forward | rcstart contents_rc
|
||||
forwardstart contents_forward | pythonstart contents_py |
|
||||
rcstart contents_rc
|
||||
;
|
||||
|
||||
/* server: declaration */
|
||||
@ -1003,6 +1004,21 @@ rc_control_cert_file: VAR_CONTROL_CERT_FILE STRING
|
||||
cfg_parser->cfg->control_cert_file = $2;
|
||||
}
|
||||
;
|
||||
pythonstart: VAR_PYTHON
|
||||
{
|
||||
OUTYY(("\nP(python:)\n"));
|
||||
}
|
||||
;
|
||||
contents_py: contents_py content_py
|
||||
| ;
|
||||
content_py: py_script
|
||||
;
|
||||
py_script: VAR_PYTHON_SCRIPT STRING
|
||||
{
|
||||
OUTYY(("P(python-script:%s)\n", $2));
|
||||
free(cfg_parser->cfg->python_script);
|
||||
cfg_parser->cfg->python_script = $2;
|
||||
}
|
||||
%%
|
||||
|
||||
/* parse helper routines could be here */
|
||||
|
@ -719,7 +719,7 @@ reply_info_answer_encode(struct query_info* qinf, struct reply_info* rep,
|
||||
uint16_t flags;
|
||||
int attach_edns = 1;
|
||||
|
||||
if(!cached) {
|
||||
if(!cached || rep->authoritative) {
|
||||
/* original flags, copy RD and CD bits from query. */
|
||||
flags = rep->flags | (qflags & (BIT_RD|BIT_CD));
|
||||
} else {
|
||||
|
@ -97,6 +97,7 @@ construct_reply_info_base(struct regional* region, uint16_t flags, size_t qd,
|
||||
rep->ar_numrrsets = ar;
|
||||
rep->rrset_count = total;
|
||||
rep->security = sec;
|
||||
rep->authoritative = 0;
|
||||
/* array starts after the refs */
|
||||
if(region)
|
||||
rep->rrsets = (struct ub_packed_rrset_key**)&(rep->ref[0]);
|
||||
|
@ -98,13 +98,19 @@ struct reply_info {
|
||||
/** the flags for the answer, host byte order. */
|
||||
uint16_t flags;
|
||||
|
||||
/**
|
||||
* This flag informs unbound the answer is authoritative and
|
||||
* the AA flag should be preserved.
|
||||
*/
|
||||
uint8_t authoritative;
|
||||
|
||||
/**
|
||||
* Number of RRs in the query section.
|
||||
* If qdcount is not 0, then it is 1, and the data that appears
|
||||
* in the reply is the same as the query_info.
|
||||
* Host byte order.
|
||||
*/
|
||||
uint16_t qdcount;
|
||||
uint8_t qdcount;
|
||||
|
||||
/**
|
||||
* TTL of the entire reply (for negative caching).
|
||||
@ -127,8 +133,7 @@ struct reply_info {
|
||||
size_t an_numrrsets;
|
||||
|
||||
/** Count of authority section RRsets */
|
||||
size_t ns_numrrsets;
|
||||
|
||||
size_t ns_numrrsets;
|
||||
/** Count of additional section RRsets */
|
||||
size_t ar_numrrsets;
|
||||
|
||||
|
@ -73,6 +73,10 @@
|
||||
#include "winrc/win_svc.h"
|
||||
#endif
|
||||
|
||||
#ifdef WITH_PYTHONMODULE
|
||||
#include "pythonmod/pythonmod.h"
|
||||
#endif
|
||||
|
||||
int
|
||||
fptr_whitelist_comm_point(comm_point_callback_t *fptr)
|
||||
{
|
||||
@ -295,6 +299,9 @@ fptr_whitelist_mod_init(int (*fptr)(struct module_env* env, int id))
|
||||
{
|
||||
if(fptr == &iter_init) return 1;
|
||||
else if(fptr == &val_init) return 1;
|
||||
#ifdef WITH_PYTHONMODULE
|
||||
else if(fptr == &pythonmod_init) return 1;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -303,6 +310,9 @@ fptr_whitelist_mod_deinit(void (*fptr)(struct module_env* env, int id))
|
||||
{
|
||||
if(fptr == &iter_deinit) return 1;
|
||||
else if(fptr == &val_deinit) return 1;
|
||||
#ifdef WITH_PYTHONMODULE
|
||||
else if(fptr == &pythonmod_deinit) return 1;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -312,6 +322,9 @@ fptr_whitelist_mod_operate(void (*fptr)(struct module_qstate* qstate,
|
||||
{
|
||||
if(fptr == &iter_operate) return 1;
|
||||
else if(fptr == &val_operate) return 1;
|
||||
#ifdef WITH_PYTHONMODULE
|
||||
else if(fptr == &pythonmod_operate) return 1;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -321,6 +334,9 @@ fptr_whitelist_mod_inform_super(void (*fptr)(
|
||||
{
|
||||
if(fptr == &iter_inform_super) return 1;
|
||||
else if(fptr == &val_inform_super) return 1;
|
||||
#ifdef WITH_PYTHONMODULE
|
||||
else if(fptr == &pythonmod_inform_super) return 1;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -330,6 +346,9 @@ fptr_whitelist_mod_clear(void (*fptr)(struct module_qstate* qstate,
|
||||
{
|
||||
if(fptr == &iter_clear) return 1;
|
||||
else if(fptr == &val_clear) return 1;
|
||||
#ifdef WITH_PYTHONMODULE
|
||||
else if(fptr == &pythonmod_clear) return 1;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -338,6 +357,9 @@ fptr_whitelist_mod_get_mem(size_t (*fptr)(struct module_env* env, int id))
|
||||
{
|
||||
if(fptr == &iter_get_mem) return 1;
|
||||
else if(fptr == &val_get_mem) return 1;
|
||||
#ifdef WITH_PYTHONMODULE
|
||||
else if(fptr == &pythonmod_get_mem) return 1;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user