From 0799d77798fb1f77d70a2f28b053980ad37c4d47 Mon Sep 17 00:00:00 2001 From: Wouter Wijngaards Date: Wed, 25 Mar 2009 14:47:47 +0000 Subject: [PATCH] python contribution from Zdenek Vasicek and Marek Vavrusa (BSD licensed). git-svn-id: file:///svn/unbound/trunk@1556 be551aaa-1e26-0410-a405-d3ace91eadb9 --- Makefile.in | 2 +- ac_pkg_swig.m4 | 122 + acx_python.m4 | 194 + config.h.in | 15 + configure | 718 +- configure.ac | 92 + contrib/README | 1 + contrib/python/LICENSE | 28 + contrib/python/Makefile | 74 + contrib/python/docs/Makefile | 70 + contrib/python/docs/source/conf.py | 179 + .../python/docs/source/examples/example1a.rst | 26 + .../python/docs/source/examples/example1b.rst | 33 + .../python/docs/source/examples/example2.rst | 41 + .../python/docs/source/examples/example3.rst | 36 + .../python/docs/source/examples/example4.rst | 34 + .../python/docs/source/examples/example5.rst | 29 + .../python/docs/source/examples/example6-1.py | 27 + .../python/docs/source/examples/example6.rst | 11 + .../python/docs/source/examples/example7-1.py | 17 + .../python/docs/source/examples/example7-2.py | 16 + .../python/docs/source/examples/example7.rst | 18 + .../python/docs/source/examples/example8-1.py | 31 + .../python/docs/source/examples/example8.rst | 28 + contrib/python/docs/source/examples/index.rst | 14 + contrib/python/docs/source/index.rst | 27 + contrib/python/docs/source/install.rst | 35 + contrib/python/docs/source/intro.rst | 39 + .../python/docs/source/modules/unbound.rst | 167 + contrib/python/examples/async-lookup.py | 56 + contrib/python/examples/dns-lookup.py | 44 + contrib/python/examples/dnssec-valid.py | 59 + contrib/python/examples/example8-1.py | 61 + contrib/python/examples/idn-lookup.py | 62 + contrib/python/examples/mx-lookup.py | 53 + contrib/python/examples/ns-lookup.py | 47 + contrib/python/examples/reverse-lookup.py | 43 + contrib/python/libunbound.i | 930 +++ contrib/python/libunbound_wrap.c | 5776 +++++++++++++++++ doc/CREDITS | 2 +- doc/Changelog | 4 + doc/example.conf.in | 5 + doc/unbound.doxygen | 2 +- libunbound/libunbound.c | 120 + libunbound/ubsyms.def | 5 + libunbound/unbound.h | 6 + pythonmod/LICENSE | 28 + pythonmod/Makefile | 58 + pythonmod/doc/Makefile | 73 + pythonmod/doc/source/conf.py | 179 + pythonmod/doc/source/examples/example0-1.py | 37 + pythonmod/doc/source/examples/example0.rst | 129 + pythonmod/doc/source/examples/example1.rst | 42 + pythonmod/doc/source/examples/example2.rst | 46 + pythonmod/doc/source/examples/example3.rst | 63 + pythonmod/doc/source/examples/example4.rst | 164 + pythonmod/doc/source/examples/index.rst | 15 + pythonmod/doc/source/index.rst | 34 + pythonmod/doc/source/install.rst | 59 + pythonmod/doc/source/modules/config.rst | 350 + pythonmod/doc/source/modules/env.rst | 412 ++ pythonmod/doc/source/modules/functions.rst | 120 + pythonmod/doc/source/modules/index.rst | 11 + pythonmod/doc/source/modules/struct.rst | 427 ++ pythonmod/doc/source/usecase.rst | 38 + pythonmod/examples/calc.py | 77 + pythonmod/examples/dict.py | 121 + pythonmod/examples/dict_data.txt | 6 + pythonmod/examples/log.py | 119 + pythonmod/examples/resgen.py | 73 + pythonmod/examples/resmod.py | 88 + pythonmod/interface.i | 803 +++ pythonmod/pythonmod.c | 292 + pythonmod/pythonmod.h | 103 + pythonmod/pythonmod_utils.c | 144 + pythonmod/pythonmod_utils.h | 75 + pythonmod/test-calc.conf | 438 ++ pythonmod/test-dict.conf | 438 ++ pythonmod/test-log.conf | 438 ++ pythonmod/test-resgen.conf | 438 ++ pythonmod/test-resmod.conf | 439 ++ pythonmod/ubmodule-msg.py | 156 + pythonmod/ubmodule-tst.py | 149 + services/cache/dns.c | 3 + services/localzone.c | 2 +- services/localzone.h | 6 + services/modstack.c | 22 +- smallapp/unbound-checkconf.c | 6 + util/config_file.c | 54 +- util/config_file.h | 11 + util/configlexer.c | 1645 ++--- util/configlexer.lex | 2 + util/configparser.c | 936 +-- util/configparser.h | 8 +- util/configparser.y | 20 +- util/data/msgencode.c | 2 +- util/data/msgreply.c | 1 + util/data/msgreply.h | 11 +- util/fptr_wlist.c | 22 + 99 files changed, 17516 insertions(+), 1316 deletions(-) create mode 100644 ac_pkg_swig.m4 create mode 100644 acx_python.m4 create mode 100644 contrib/python/LICENSE create mode 100644 contrib/python/Makefile create mode 100644 contrib/python/docs/Makefile create mode 100644 contrib/python/docs/source/conf.py create mode 100644 contrib/python/docs/source/examples/example1a.rst create mode 100644 contrib/python/docs/source/examples/example1b.rst create mode 100644 contrib/python/docs/source/examples/example2.rst create mode 100644 contrib/python/docs/source/examples/example3.rst create mode 100644 contrib/python/docs/source/examples/example4.rst create mode 100644 contrib/python/docs/source/examples/example5.rst create mode 100644 contrib/python/docs/source/examples/example6-1.py create mode 100644 contrib/python/docs/source/examples/example6.rst create mode 100644 contrib/python/docs/source/examples/example7-1.py create mode 100644 contrib/python/docs/source/examples/example7-2.py create mode 100644 contrib/python/docs/source/examples/example7.rst create mode 100644 contrib/python/docs/source/examples/example8-1.py create mode 100644 contrib/python/docs/source/examples/example8.rst create mode 100644 contrib/python/docs/source/examples/index.rst create mode 100644 contrib/python/docs/source/index.rst create mode 100644 contrib/python/docs/source/install.rst create mode 100644 contrib/python/docs/source/intro.rst create mode 100644 contrib/python/docs/source/modules/unbound.rst create mode 100644 contrib/python/examples/async-lookup.py create mode 100644 contrib/python/examples/dns-lookup.py create mode 100644 contrib/python/examples/dnssec-valid.py create mode 100644 contrib/python/examples/example8-1.py create mode 100644 contrib/python/examples/idn-lookup.py create mode 100644 contrib/python/examples/mx-lookup.py create mode 100644 contrib/python/examples/ns-lookup.py create mode 100644 contrib/python/examples/reverse-lookup.py create mode 100644 contrib/python/libunbound.i create mode 100644 contrib/python/libunbound_wrap.c create mode 100644 pythonmod/LICENSE create mode 100644 pythonmod/Makefile create mode 100644 pythonmod/doc/Makefile create mode 100644 pythonmod/doc/source/conf.py create mode 100644 pythonmod/doc/source/examples/example0-1.py create mode 100644 pythonmod/doc/source/examples/example0.rst create mode 100644 pythonmod/doc/source/examples/example1.rst create mode 100644 pythonmod/doc/source/examples/example2.rst create mode 100644 pythonmod/doc/source/examples/example3.rst create mode 100644 pythonmod/doc/source/examples/example4.rst create mode 100644 pythonmod/doc/source/examples/index.rst create mode 100644 pythonmod/doc/source/index.rst create mode 100644 pythonmod/doc/source/install.rst create mode 100644 pythonmod/doc/source/modules/config.rst create mode 100644 pythonmod/doc/source/modules/env.rst create mode 100644 pythonmod/doc/source/modules/functions.rst create mode 100644 pythonmod/doc/source/modules/index.rst create mode 100644 pythonmod/doc/source/modules/struct.rst create mode 100644 pythonmod/doc/source/usecase.rst create mode 100644 pythonmod/examples/calc.py create mode 100644 pythonmod/examples/dict.py create mode 100644 pythonmod/examples/dict_data.txt create mode 100644 pythonmod/examples/log.py create mode 100644 pythonmod/examples/resgen.py create mode 100644 pythonmod/examples/resmod.py create mode 100644 pythonmod/interface.i create mode 100644 pythonmod/pythonmod.c create mode 100644 pythonmod/pythonmod.h create mode 100644 pythonmod/pythonmod_utils.c create mode 100644 pythonmod/pythonmod_utils.h create mode 100644 pythonmod/test-calc.conf create mode 100644 pythonmod/test-dict.conf create mode 100644 pythonmod/test-log.conf create mode 100644 pythonmod/test-resgen.conf create mode 100644 pythonmod/test-resmod.conf create mode 100644 pythonmod/ubmodule-msg.py create mode 100644 pythonmod/ubmodule-tst.py diff --git a/Makefile.in b/Makefile.in index 96a55cbaa..daac35d5f 100644 --- a/Makefile.in +++ b/Makefile.in @@ -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 diff --git a/ac_pkg_swig.m4 b/ac_pkg_swig.m4 new file mode 100644 index 000000000..738f69d45 --- /dev/null +++ b/ac_pkg_swig.m4 @@ -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 +# Copyright (c) 2008 Alan W. Irwin +# Copyright (c) 2008 Rafael Laboissiere +# Copyright (c) 2008 Andrew Collier +# +# 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 . +# +# 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]) +]) diff --git a/acx_python.m4 b/acx_python.m4 new file mode 100644 index 000000000..abf23286f --- /dev/null +++ b/acx_python.m4 @@ -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 + ],[ + 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! + # +]) + diff --git a/config.h.in b/config.h.in index 068e409ab..3714ea93b 100644 --- a/config.h.in +++ b/config.h.in @@ -167,6 +167,9 @@ /* Define to 1 if you have the 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 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 diff --git a/configure b/configure index ae7cc2922..bdb0d5304 100755 --- a/configure +++ b/configure @@ -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 < conftest.$ac_ext <&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 + +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 >$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"; } && diff --git a/configure.ac b/configure.ac index 49a39cdcb..f5f7d1371 100644 --- a/configure.ac +++ b/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 diff --git a/contrib/README b/contrib/README index f8ff7d9b1..f35bca7ab 100644 --- a/contrib/README +++ b/contrib/README @@ -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. diff --git a/contrib/python/LICENSE b/contrib/python/LICENSE new file mode 100644 index 000000000..7b769d091 --- /dev/null +++ b/contrib/python/LICENSE @@ -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. diff --git a/contrib/python/Makefile b/contrib/python/Makefile new file mode 100644 index 000000000..1c8a50021 --- /dev/null +++ b/contrib/python/Makefile @@ -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 ' where 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 + diff --git a/contrib/python/docs/Makefile b/contrib/python/docs/Makefile new file mode 100644 index 000000000..d54ecb9e6 --- /dev/null +++ b/contrib/python/docs/Makefile @@ -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 ' where 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." diff --git a/contrib/python/docs/source/conf.py b/contrib/python/docs/source/conf.py new file mode 100644 index 000000000..6309d5029 --- /dev/null +++ b/contrib/python/docs/source/conf.py @@ -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 +# " v 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/. +html_copy_source = False + +# If true, an OpenSearch description file will be output, and all pages will +# contain a 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 diff --git a/contrib/python/docs/source/examples/example1a.rst b/contrib/python/docs/source/examples/example1a.rst new file mode 100644 index 000000000..3c81547f2 --- /dev/null +++ b/contrib/python/docs/source/examples/example1a.rst @@ -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. diff --git a/contrib/python/docs/source/examples/example1b.rst b/contrib/python/docs/source/examples/example1b.rst new file mode 100644 index 000000000..ea1e6f57d --- /dev/null +++ b/contrib/python/docs/source/examples/example1b.rst @@ -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]) + + diff --git a/contrib/python/docs/source/examples/example2.rst b/contrib/python/docs/source/examples/example2.rst new file mode 100644 index 000000000..c009ec1f5 --- /dev/null +++ b/contrib/python/docs/source/examples/example2.rst @@ -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() + + diff --git a/contrib/python/docs/source/examples/example3.rst b/contrib/python/docs/source/examples/example3.rst new file mode 100644 index 000000000..91360335c --- /dev/null +++ b/contrib/python/docs/source/examples/example3.rst @@ -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`. diff --git a/contrib/python/docs/source/examples/example4.rst b/contrib/python/docs/source/examples/example4.rst new file mode 100644 index 000000000..996ef4ede --- /dev/null +++ b/contrib/python/docs/source/examples/example4.rst @@ -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 diff --git a/contrib/python/docs/source/examples/example5.rst b/contrib/python/docs/source/examples/example5.rst new file mode 100644 index 000000000..0a31d9a57 --- /dev/null +++ b/contrib/python/docs/source/examples/example5.rst @@ -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). + diff --git a/contrib/python/docs/source/examples/example6-1.py b/contrib/python/docs/source/examples/example6-1.py new file mode 100644 index 000000000..0f405448c --- /dev/null +++ b/contrib/python/docs/source/examples/example6-1.py @@ -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" + diff --git a/contrib/python/docs/source/examples/example6.rst b/contrib/python/docs/source/examples/example6.rst new file mode 100644 index 000000000..478e13909 --- /dev/null +++ b/contrib/python/docs/source/examples/example6.rst @@ -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 + diff --git a/contrib/python/docs/source/examples/example7-1.py b/contrib/python/docs/source/examples/example7-1.py new file mode 100644 index 000000000..802bd1c35 --- /dev/null +++ b/contrib/python/docs/source/examples/example7-1.py @@ -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 + diff --git a/contrib/python/docs/source/examples/example7-2.py b/contrib/python/docs/source/examples/example7-2.py new file mode 100644 index 000000000..5a41f8dc9 --- /dev/null +++ b/contrib/python/docs/source/examples/example7-2.py @@ -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 diff --git a/contrib/python/docs/source/examples/example7.rst b/contrib/python/docs/source/examples/example7.rst new file mode 100644 index 000000000..d4050215e --- /dev/null +++ b/contrib/python/docs/source/examples/example7.rst @@ -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`). diff --git a/contrib/python/docs/source/examples/example8-1.py b/contrib/python/docs/source/examples/example8-1.py new file mode 100644 index 000000000..79060167d --- /dev/null +++ b/contrib/python/docs/source/examples/example8-1.py @@ -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 + diff --git a/contrib/python/docs/source/examples/example8.rst b/contrib/python/docs/source/examples/example8.rst new file mode 100644 index 000000000..8cdfcdc0a --- /dev/null +++ b/contrib/python/docs/source/examples/example8.rst @@ -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. diff --git a/contrib/python/docs/source/examples/index.rst b/contrib/python/docs/source/examples/index.rst new file mode 100644 index 000000000..c2c9cf457 --- /dev/null +++ b/contrib/python/docs/source/examples/index.rst @@ -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* diff --git a/contrib/python/docs/source/index.rst b/contrib/python/docs/source/index.rst new file mode 100644 index 000000000..b42e05262 --- /dev/null +++ b/contrib/python/docs/source/index.rst @@ -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` + diff --git a/contrib/python/docs/source/install.rst b/contrib/python/docs/source/install.rst new file mode 100644 index 000000000..34108e012 --- /dev/null +++ b/contrib/python/docs/source/install.rst @@ -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. diff --git a/contrib/python/docs/source/intro.rst b/contrib/python/docs/source/intro.rst new file mode 100644 index 000000000..f751f54c0 --- /dev/null +++ b/contrib/python/docs/source/intro.rst @@ -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 diff --git a/contrib/python/docs/source/modules/unbound.rst b/contrib/python/docs/source/modules/unbound.rst new file mode 100644 index 000000000..21f4a12d8 --- /dev/null +++ b/contrib/python/docs/source/modules/unbound.rst @@ -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 diff --git a/contrib/python/examples/async-lookup.py b/contrib/python/examples/async-lookup.py new file mode 100644 index 000000000..52a2d3c75 --- /dev/null +++ b/contrib/python/examples/async-lookup.py @@ -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) diff --git a/contrib/python/examples/dns-lookup.py b/contrib/python/examples/dns-lookup.py new file mode 100644 index 000000000..2821ed3ba --- /dev/null +++ b/contrib/python/examples/dns-lookup.py @@ -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) diff --git a/contrib/python/examples/dnssec-valid.py b/contrib/python/examples/dnssec-valid.py new file mode 100644 index 000000000..3e05ddd7a --- /dev/null +++ b/contrib/python/examples/dnssec-valid.py @@ -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" + diff --git a/contrib/python/examples/example8-1.py b/contrib/python/examples/example8-1.py new file mode 100644 index 000000000..6816da0c2 --- /dev/null +++ b/contrib/python/examples/example8-1.py @@ -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 + diff --git a/contrib/python/examples/idn-lookup.py b/contrib/python/examples/idn-lookup.py new file mode 100644 index 000000000..7cfdc9e94 --- /dev/null +++ b/contrib/python/examples/idn-lookup.py @@ -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 diff --git a/contrib/python/examples/mx-lookup.py b/contrib/python/examples/mx-lookup.py new file mode 100644 index 000000000..cdcd1b166 --- /dev/null +++ b/contrib/python/examples/mx-lookup.py @@ -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 diff --git a/contrib/python/examples/ns-lookup.py b/contrib/python/examples/ns-lookup.py new file mode 100644 index 000000000..f9eafb28a --- /dev/null +++ b/contrib/python/examples/ns-lookup.py @@ -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 + diff --git a/contrib/python/examples/reverse-lookup.py b/contrib/python/examples/reverse-lookup.py new file mode 100644 index 000000000..4d3e0bb36 --- /dev/null +++ b/contrib/python/examples/reverse-lookup.py @@ -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 + diff --git a/contrib/python/libunbound.i b/contrib/python/libunbound.i new file mode 100644 index 000000000..a9a71aca2 --- /dev/null +++ b/contrib/python/libunbound.i @@ -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 + #include + #include + #include + #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;idata[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('.')]) + +%} + diff --git a/contrib/python/libunbound_wrap.c b/contrib/python/libunbound_wrap.c new file mode 100644 index 000000000..507349b6a --- /dev/null +++ b/contrib/python/libunbound_wrap.c @@ -0,0 +1,5776 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 1.3.38 + * + * This file is not intended to be easily readable and contains a number of + * coding conventions designed to improve portability and efficiency. Do not make + * changes to this file unless you know what you are doing--modify the SWIG + * interface file instead. + * ----------------------------------------------------------------------------- */ + +#define SWIGPYTHON +#define SWIG_PYTHON_DIRECTOR_NO_VTABLE + +/* ----------------------------------------------------------------------------- + * This section contains generic SWIG labels for method/variable + * declarations/attributes, and other compiler dependent labels. + * ----------------------------------------------------------------------------- */ + +/* template workaround for compilers that cannot correctly implement the C++ standard */ +#ifndef SWIGTEMPLATEDISAMBIGUATOR +# if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560) +# define SWIGTEMPLATEDISAMBIGUATOR template +# elif defined(__HP_aCC) +/* Needed even with `aCC -AA' when `aCC -V' reports HP ANSI C++ B3910B A.03.55 */ +/* If we find a maximum version that requires this, the test would be __HP_aCC <= 35500 for A.03.55 */ +# define SWIGTEMPLATEDISAMBIGUATOR template +# else +# define SWIGTEMPLATEDISAMBIGUATOR +# endif +#endif + +/* inline attribute */ +#ifndef SWIGINLINE +# if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__)) +# define SWIGINLINE inline +# else +# define SWIGINLINE +# endif +#endif + +/* attribute recognised by some compilers to avoid 'unused' warnings */ +#ifndef SWIGUNUSED +# if defined(__GNUC__) +# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +# define SWIGUNUSED __attribute__ ((__unused__)) +# else +# define SWIGUNUSED +# endif +# elif defined(__ICC) +# define SWIGUNUSED __attribute__ ((__unused__)) +# else +# define SWIGUNUSED +# endif +#endif + +#ifndef SWIG_MSC_UNSUPPRESS_4505 +# if defined(_MSC_VER) +# pragma warning(disable : 4505) /* unreferenced local function has been removed */ +# endif +#endif + +#ifndef SWIGUNUSEDPARM +# ifdef __cplusplus +# define SWIGUNUSEDPARM(p) +# else +# define SWIGUNUSEDPARM(p) p SWIGUNUSED +# endif +#endif + +/* internal SWIG method */ +#ifndef SWIGINTERN +# define SWIGINTERN static SWIGUNUSED +#endif + +/* internal inline SWIG method */ +#ifndef SWIGINTERNINLINE +# define SWIGINTERNINLINE SWIGINTERN SWIGINLINE +#endif + +/* exporting methods */ +#if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) +# ifndef GCC_HASCLASSVISIBILITY +# define GCC_HASCLASSVISIBILITY +# endif +#endif + +#ifndef SWIGEXPORT +# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# if defined(STATIC_LINKED) +# define SWIGEXPORT +# else +# define SWIGEXPORT __declspec(dllexport) +# endif +# else +# if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY) +# define SWIGEXPORT __attribute__ ((visibility("default"))) +# else +# define SWIGEXPORT +# endif +# endif +#endif + +/* calling conventions for Windows */ +#ifndef SWIGSTDCALL +# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# define SWIGSTDCALL __stdcall +# else +# define SWIGSTDCALL +# endif +#endif + +/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ +#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) +# define _CRT_SECURE_NO_DEPRECATE +#endif + +/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */ +#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE) +# define _SCL_SECURE_NO_DEPRECATE +#endif + + + +/* Python.h has to appear first */ +#include + +/* ----------------------------------------------------------------------------- + * swigrun.swg + * + * This file contains generic C API SWIG runtime support for pointer + * type checking. + * ----------------------------------------------------------------------------- */ + +/* This should only be incremented when either the layout of swig_type_info changes, + or for whatever reason, the runtime changes incompatibly */ +#define SWIG_RUNTIME_VERSION "4" + +/* define SWIG_TYPE_TABLE_NAME as "SWIG_TYPE_TABLE" */ +#ifdef SWIG_TYPE_TABLE +# define SWIG_QUOTE_STRING(x) #x +# define SWIG_EXPAND_AND_QUOTE_STRING(x) SWIG_QUOTE_STRING(x) +# define SWIG_TYPE_TABLE_NAME SWIG_EXPAND_AND_QUOTE_STRING(SWIG_TYPE_TABLE) +#else +# define SWIG_TYPE_TABLE_NAME +#endif + +/* + You can use the SWIGRUNTIME and SWIGRUNTIMEINLINE macros for + creating a static or dynamic library from the SWIG runtime code. + In 99.9% of the cases, SWIG just needs to declare them as 'static'. + + But only do this if strictly necessary, ie, if you have problems + with your compiler or suchlike. +*/ + +#ifndef SWIGRUNTIME +# define SWIGRUNTIME SWIGINTERN +#endif + +#ifndef SWIGRUNTIMEINLINE +# define SWIGRUNTIMEINLINE SWIGRUNTIME SWIGINLINE +#endif + +/* Generic buffer size */ +#ifndef SWIG_BUFFER_SIZE +# define SWIG_BUFFER_SIZE 1024 +#endif + +/* Flags for pointer conversions */ +#define SWIG_POINTER_DISOWN 0x1 +#define SWIG_CAST_NEW_MEMORY 0x2 + +/* Flags for new pointer objects */ +#define SWIG_POINTER_OWN 0x1 + + +/* + Flags/methods for returning states. + + The SWIG conversion methods, as ConvertPtr, return and integer + that tells if the conversion was successful or not. And if not, + an error code can be returned (see swigerrors.swg for the codes). + + Use the following macros/flags to set or process the returning + states. + + In old versions of SWIG, code such as the following was usually written: + + if (SWIG_ConvertPtr(obj,vptr,ty.flags) != -1) { + // success code + } else { + //fail code + } + + Now you can be more explicit: + + int res = SWIG_ConvertPtr(obj,vptr,ty.flags); + if (SWIG_IsOK(res)) { + // success code + } else { + // fail code + } + + which is the same really, but now you can also do + + Type *ptr; + int res = SWIG_ConvertPtr(obj,(void **)(&ptr),ty.flags); + if (SWIG_IsOK(res)) { + // success code + if (SWIG_IsNewObj(res) { + ... + delete *ptr; + } else { + ... + } + } else { + // fail code + } + + I.e., now SWIG_ConvertPtr can return new objects and you can + identify the case and take care of the deallocation. Of course that + also requires SWIG_ConvertPtr to return new result values, such as + + int SWIG_ConvertPtr(obj, ptr,...) { + if () { + if () { + *ptr = ; + return SWIG_NEWOBJ; + } else { + *ptr = ; + return SWIG_OLDOBJ; + } + } else { + return SWIG_BADOBJ; + } + } + + Of course, returning the plain '0(success)/-1(fail)' still works, but you can be + more explicit by returning SWIG_BADOBJ, SWIG_ERROR or any of the + SWIG errors code. + + Finally, if the SWIG_CASTRANK_MODE is enabled, the result code + allows to return the 'cast rank', for example, if you have this + + int food(double) + int fooi(int); + + and you call + + food(1) // cast rank '1' (1 -> 1.0) + fooi(1) // cast rank '0' + + just use the SWIG_AddCast()/SWIG_CheckState() +*/ + +#define SWIG_OK (0) +#define SWIG_ERROR (-1) +#define SWIG_IsOK(r) (r >= 0) +#define SWIG_ArgError(r) ((r != SWIG_ERROR) ? r : SWIG_TypeError) + +/* The CastRankLimit says how many bits are used for the cast rank */ +#define SWIG_CASTRANKLIMIT (1 << 8) +/* The NewMask denotes the object was created (using new/malloc) */ +#define SWIG_NEWOBJMASK (SWIG_CASTRANKLIMIT << 1) +/* The TmpMask is for in/out typemaps that use temporal objects */ +#define SWIG_TMPOBJMASK (SWIG_NEWOBJMASK << 1) +/* Simple returning values */ +#define SWIG_BADOBJ (SWIG_ERROR) +#define SWIG_OLDOBJ (SWIG_OK) +#define SWIG_NEWOBJ (SWIG_OK | SWIG_NEWOBJMASK) +#define SWIG_TMPOBJ (SWIG_OK | SWIG_TMPOBJMASK) +/* Check, add and del mask methods */ +#define SWIG_AddNewMask(r) (SWIG_IsOK(r) ? (r | SWIG_NEWOBJMASK) : r) +#define SWIG_DelNewMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_NEWOBJMASK) : r) +#define SWIG_IsNewObj(r) (SWIG_IsOK(r) && (r & SWIG_NEWOBJMASK)) +#define SWIG_AddTmpMask(r) (SWIG_IsOK(r) ? (r | SWIG_TMPOBJMASK) : r) +#define SWIG_DelTmpMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_TMPOBJMASK) : r) +#define SWIG_IsTmpObj(r) (SWIG_IsOK(r) && (r & SWIG_TMPOBJMASK)) + +/* Cast-Rank Mode */ +#if defined(SWIG_CASTRANK_MODE) +# ifndef SWIG_TypeRank +# define SWIG_TypeRank unsigned long +# endif +# ifndef SWIG_MAXCASTRANK /* Default cast allowed */ +# define SWIG_MAXCASTRANK (2) +# endif +# define SWIG_CASTRANKMASK ((SWIG_CASTRANKLIMIT) -1) +# define SWIG_CastRank(r) (r & SWIG_CASTRANKMASK) +SWIGINTERNINLINE int SWIG_AddCast(int r) { + return SWIG_IsOK(r) ? ((SWIG_CastRank(r) < SWIG_MAXCASTRANK) ? (r + 1) : SWIG_ERROR) : r; +} +SWIGINTERNINLINE int SWIG_CheckState(int r) { + return SWIG_IsOK(r) ? SWIG_CastRank(r) + 1 : 0; +} +#else /* no cast-rank mode */ +# define SWIG_AddCast +# define SWIG_CheckState(r) (SWIG_IsOK(r) ? 1 : 0) +#endif + + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void *(*swig_converter_func)(void *, int *); +typedef struct swig_type_info *(*swig_dycast_func)(void **); + +/* Structure to store information on one type */ +typedef struct swig_type_info { + const char *name; /* mangled name of this type */ + const char *str; /* human readable name of this type */ + swig_dycast_func dcast; /* dynamic cast function down a hierarchy */ + struct swig_cast_info *cast; /* linked list of types that can cast into this type */ + void *clientdata; /* language specific type data */ + int owndata; /* flag if the structure owns the clientdata */ +} swig_type_info; + +/* Structure to store a type and conversion function used for casting */ +typedef struct swig_cast_info { + swig_type_info *type; /* pointer to type that is equivalent to this type */ + swig_converter_func converter; /* function to cast the void pointers */ + struct swig_cast_info *next; /* pointer to next cast in linked list */ + struct swig_cast_info *prev; /* pointer to the previous cast */ +} swig_cast_info; + +/* Structure used to store module information + * Each module generates one structure like this, and the runtime collects + * all of these structures and stores them in a circularly linked list.*/ +typedef struct swig_module_info { + swig_type_info **types; /* Array of pointers to swig_type_info structures that are in this module */ + size_t size; /* Number of types in this module */ + struct swig_module_info *next; /* Pointer to next element in circularly linked list */ + swig_type_info **type_initial; /* Array of initially generated type structures */ + swig_cast_info **cast_initial; /* Array of initially generated casting structures */ + void *clientdata; /* Language specific module data */ +} swig_module_info; + +/* + Compare two type names skipping the space characters, therefore + "char*" == "char *" and "Class" == "Class", etc. + + Return 0 when the two name types are equivalent, as in + strncmp, but skipping ' '. +*/ +SWIGRUNTIME int +SWIG_TypeNameComp(const char *f1, const char *l1, + const char *f2, const char *l2) { + for (;(f1 != l1) && (f2 != l2); ++f1, ++f2) { + while ((*f1 == ' ') && (f1 != l1)) ++f1; + while ((*f2 == ' ') && (f2 != l2)) ++f2; + if (*f1 != *f2) return (*f1 > *f2) ? 1 : -1; + } + return (int)((l1 - f1) - (l2 - f2)); +} + +/* + Check type equivalence in a name list like ||... + Return 0 if not equal, 1 if equal +*/ +SWIGRUNTIME int +SWIG_TypeEquiv(const char *nb, const char *tb) { + int equiv = 0; + const char* te = tb + strlen(tb); + const char* ne = nb; + while (!equiv && *ne) { + for (nb = ne; *ne; ++ne) { + if (*ne == '|') break; + } + equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0; + if (*ne) ++ne; + } + return equiv; +} + +/* + Check type equivalence in a name list like ||... + Return 0 if equal, -1 if nb < tb, 1 if nb > tb +*/ +SWIGRUNTIME int +SWIG_TypeCompare(const char *nb, const char *tb) { + int equiv = 0; + const char* te = tb + strlen(tb); + const char* ne = nb; + while (!equiv && *ne) { + for (nb = ne; *ne; ++ne) { + if (*ne == '|') break; + } + equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0; + if (*ne) ++ne; + } + return equiv; +} + + +/* + Check the typename +*/ +SWIGRUNTIME swig_cast_info * +SWIG_TypeCheck(const char *c, swig_type_info *ty) { + if (ty) { + swig_cast_info *iter = ty->cast; + while (iter) { + if (strcmp(iter->type->name, c) == 0) { + if (iter == ty->cast) + return iter; + /* Move iter to the top of the linked list */ + iter->prev->next = iter->next; + if (iter->next) + iter->next->prev = iter->prev; + iter->next = ty->cast; + iter->prev = 0; + if (ty->cast) ty->cast->prev = iter; + ty->cast = iter; + return iter; + } + iter = iter->next; + } + } + return 0; +} + +/* + Identical to SWIG_TypeCheck, except strcmp is replaced with a pointer comparison +*/ +SWIGRUNTIME swig_cast_info * +SWIG_TypeCheckStruct(swig_type_info *from, swig_type_info *ty) { + if (ty) { + swig_cast_info *iter = ty->cast; + while (iter) { + if (iter->type == from) { + if (iter == ty->cast) + return iter; + /* Move iter to the top of the linked list */ + iter->prev->next = iter->next; + if (iter->next) + iter->next->prev = iter->prev; + iter->next = ty->cast; + iter->prev = 0; + if (ty->cast) ty->cast->prev = iter; + ty->cast = iter; + return iter; + } + iter = iter->next; + } + } + return 0; +} + +/* + Cast a pointer up an inheritance hierarchy +*/ +SWIGRUNTIMEINLINE void * +SWIG_TypeCast(swig_cast_info *ty, void *ptr, int *newmemory) { + return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr, newmemory); +} + +/* + Dynamic pointer casting. Down an inheritance hierarchy +*/ +SWIGRUNTIME swig_type_info * +SWIG_TypeDynamicCast(swig_type_info *ty, void **ptr) { + swig_type_info *lastty = ty; + if (!ty || !ty->dcast) return ty; + while (ty && (ty->dcast)) { + ty = (*ty->dcast)(ptr); + if (ty) lastty = ty; + } + return lastty; +} + +/* + Return the name associated with this type +*/ +SWIGRUNTIMEINLINE const char * +SWIG_TypeName(const swig_type_info *ty) { + return ty->name; +} + +/* + Return the pretty name associated with this type, + that is an unmangled type name in a form presentable to the user. +*/ +SWIGRUNTIME const char * +SWIG_TypePrettyName(const swig_type_info *type) { + /* The "str" field contains the equivalent pretty names of the + type, separated by vertical-bar characters. We choose + to print the last name, as it is often (?) the most + specific. */ + if (!type) return NULL; + if (type->str != NULL) { + const char *last_name = type->str; + const char *s; + for (s = type->str; *s; s++) + if (*s == '|') last_name = s+1; + return last_name; + } + else + return type->name; +} + +/* + Set the clientdata field for a type +*/ +SWIGRUNTIME void +SWIG_TypeClientData(swig_type_info *ti, void *clientdata) { + swig_cast_info *cast = ti->cast; + /* if (ti->clientdata == clientdata) return; */ + ti->clientdata = clientdata; + + while (cast) { + if (!cast->converter) { + swig_type_info *tc = cast->type; + if (!tc->clientdata) { + SWIG_TypeClientData(tc, clientdata); + } + } + cast = cast->next; + } +} +SWIGRUNTIME void +SWIG_TypeNewClientData(swig_type_info *ti, void *clientdata) { + SWIG_TypeClientData(ti, clientdata); + ti->owndata = 1; +} + +/* + Search for a swig_type_info structure only by mangled name + Search is a O(log #types) + + We start searching at module start, and finish searching when start == end. + Note: if start == end at the beginning of the function, we go all the way around + the circular list. +*/ +SWIGRUNTIME swig_type_info * +SWIG_MangledTypeQueryModule(swig_module_info *start, + swig_module_info *end, + const char *name) { + swig_module_info *iter = start; + do { + if (iter->size) { + register size_t l = 0; + register size_t r = iter->size - 1; + do { + /* since l+r >= 0, we can (>> 1) instead (/ 2) */ + register size_t i = (l + r) >> 1; + const char *iname = iter->types[i]->name; + if (iname) { + register int compare = strcmp(name, iname); + if (compare == 0) { + return iter->types[i]; + } else if (compare < 0) { + if (i) { + r = i - 1; + } else { + break; + } + } else if (compare > 0) { + l = i + 1; + } + } else { + break; /* should never happen */ + } + } while (l <= r); + } + iter = iter->next; + } while (iter != end); + return 0; +} + +/* + Search for a swig_type_info structure for either a mangled name or a human readable name. + It first searches the mangled names of the types, which is a O(log #types) + If a type is not found it then searches the human readable names, which is O(#types). + + We start searching at module start, and finish searching when start == end. + Note: if start == end at the beginning of the function, we go all the way around + the circular list. +*/ +SWIGRUNTIME swig_type_info * +SWIG_TypeQueryModule(swig_module_info *start, + swig_module_info *end, + const char *name) { + /* STEP 1: Search the name field using binary search */ + swig_type_info *ret = SWIG_MangledTypeQueryModule(start, end, name); + if (ret) { + return ret; + } else { + /* STEP 2: If the type hasn't been found, do a complete search + of the str field (the human readable name) */ + swig_module_info *iter = start; + do { + register size_t i = 0; + for (; i < iter->size; ++i) { + if (iter->types[i]->str && (SWIG_TypeEquiv(iter->types[i]->str, name))) + return iter->types[i]; + } + iter = iter->next; + } while (iter != end); + } + + /* neither found a match */ + return 0; +} + +/* + Pack binary data into a string +*/ +SWIGRUNTIME char * +SWIG_PackData(char *c, void *ptr, size_t sz) { + static const char hex[17] = "0123456789abcdef"; + register const unsigned char *u = (unsigned char *) ptr; + register const unsigned char *eu = u + sz; + for (; u != eu; ++u) { + register unsigned char uu = *u; + *(c++) = hex[(uu & 0xf0) >> 4]; + *(c++) = hex[uu & 0xf]; + } + return c; +} + +/* + Unpack binary data from a string +*/ +SWIGRUNTIME const char * +SWIG_UnpackData(const char *c, void *ptr, size_t sz) { + register unsigned char *u = (unsigned char *) ptr; + register const unsigned char *eu = u + sz; + for (; u != eu; ++u) { + register char d = *(c++); + register unsigned char uu; + if ((d >= '0') && (d <= '9')) + uu = ((d - '0') << 4); + else if ((d >= 'a') && (d <= 'f')) + uu = ((d - ('a'-10)) << 4); + else + return (char *) 0; + d = *(c++); + if ((d >= '0') && (d <= '9')) + uu |= (d - '0'); + else if ((d >= 'a') && (d <= 'f')) + uu |= (d - ('a'-10)); + else + return (char *) 0; + *u = uu; + } + return c; +} + +/* + Pack 'void *' into a string buffer. +*/ +SWIGRUNTIME char * +SWIG_PackVoidPtr(char *buff, void *ptr, const char *name, size_t bsz) { + char *r = buff; + if ((2*sizeof(void *) + 2) > bsz) return 0; + *(r++) = '_'; + r = SWIG_PackData(r,&ptr,sizeof(void *)); + if (strlen(name) + 1 > (bsz - (r - buff))) return 0; + strcpy(r,name); + return buff; +} + +SWIGRUNTIME const char * +SWIG_UnpackVoidPtr(const char *c, void **ptr, const char *name) { + if (*c != '_') { + if (strcmp(c,"NULL") == 0) { + *ptr = (void *) 0; + return name; + } else { + return 0; + } + } + return SWIG_UnpackData(++c,ptr,sizeof(void *)); +} + +SWIGRUNTIME char * +SWIG_PackDataName(char *buff, void *ptr, size_t sz, const char *name, size_t bsz) { + char *r = buff; + size_t lname = (name ? strlen(name) : 0); + if ((2*sz + 2 + lname) > bsz) return 0; + *(r++) = '_'; + r = SWIG_PackData(r,ptr,sz); + if (lname) { + strncpy(r,name,lname+1); + } else { + *r = 0; + } + return buff; +} + +SWIGRUNTIME const char * +SWIG_UnpackDataName(const char *c, void *ptr, size_t sz, const char *name) { + if (*c != '_') { + if (strcmp(c,"NULL") == 0) { + memset(ptr,0,sz); + return name; + } else { + return 0; + } + } + return SWIG_UnpackData(++c,ptr,sz); +} + +#ifdef __cplusplus +} +#endif + +/* Errors in SWIG */ +#define SWIG_UnknownError -1 +#define SWIG_IOError -2 +#define SWIG_RuntimeError -3 +#define SWIG_IndexError -4 +#define SWIG_TypeError -5 +#define SWIG_DivisionByZero -6 +#define SWIG_OverflowError -7 +#define SWIG_SyntaxError -8 +#define SWIG_ValueError -9 +#define SWIG_SystemError -10 +#define SWIG_AttributeError -11 +#define SWIG_MemoryError -12 +#define SWIG_NullReferenceError -13 + + + +/* Compatibility marcos for Python 3 */ +#if PY_VERSION_HEX >= 0x03000000 + +#define PyClass_Check(obj) PyObject_IsInstance(obj, (PyObject *)&PyType_Type) +#define PyInt_Check(x) PyLong_Check(x) +#define PyInt_AsLong(x) PyLong_AsLong(x) +#define PyInt_FromLong(x) PyLong_FromLong(x) +#define PyString_Format(fmt, args) PyUnicode_Format(fmt, args) + +#endif + +#ifndef Py_TYPE +# define Py_TYPE(op) ((op)->ob_type) +#endif + +/* SWIG APIs for compatibility of both Python 2 & 3 */ + +#if PY_VERSION_HEX >= 0x03000000 +# define SWIG_Python_str_FromFormat PyUnicode_FromFormat +#else +# define SWIG_Python_str_FromFormat PyString_FromFormat +#endif + +SWIGINTERN char* +SWIG_Python_str_AsChar(PyObject *str) +{ +#if PY_VERSION_HEX >= 0x03000000 + str = PyUnicode_AsUTF8String(str); + return PyBytes_AsString(str); +#else + return PyString_AsString(str); +#endif +} + +SWIGINTERN PyObject* +SWIG_Python_str_FromChar(const char *c) +{ +#if PY_VERSION_HEX >= 0x03000000 + return PyUnicode_FromString(c); +#else + return PyString_FromString(c); +#endif +} + +/* Add PyOS_snprintf for old Pythons */ +#if PY_VERSION_HEX < 0x02020000 +# if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WATCOM) +# define PyOS_snprintf _snprintf +# else +# define PyOS_snprintf snprintf +# endif +#endif + +/* A crude PyString_FromFormat implementation for old Pythons */ +#if PY_VERSION_HEX < 0x02020000 + +#ifndef SWIG_PYBUFFER_SIZE +# define SWIG_PYBUFFER_SIZE 1024 +#endif + +static PyObject * +PyString_FromFormat(const char *fmt, ...) { + va_list ap; + char buf[SWIG_PYBUFFER_SIZE * 2]; + int res; + va_start(ap, fmt); + res = vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + return (res < 0 || res >= (int)sizeof(buf)) ? 0 : PyString_FromString(buf); +} +#endif + +/* Add PyObject_Del for old Pythons */ +#if PY_VERSION_HEX < 0x01060000 +# define PyObject_Del(op) PyMem_DEL((op)) +#endif +#ifndef PyObject_DEL +# define PyObject_DEL PyObject_Del +#endif + +/* A crude PyExc_StopIteration exception for old Pythons */ +#if PY_VERSION_HEX < 0x02020000 +# ifndef PyExc_StopIteration +# define PyExc_StopIteration PyExc_RuntimeError +# endif +# ifndef PyObject_GenericGetAttr +# define PyObject_GenericGetAttr 0 +# endif +#endif + +/* Py_NotImplemented is defined in 2.1 and up. */ +#if PY_VERSION_HEX < 0x02010000 +# ifndef Py_NotImplemented +# define Py_NotImplemented PyExc_RuntimeError +# endif +#endif + +/* A crude PyString_AsStringAndSize implementation for old Pythons */ +#if PY_VERSION_HEX < 0x02010000 +# ifndef PyString_AsStringAndSize +# define PyString_AsStringAndSize(obj, s, len) {*s = PyString_AsString(obj); *len = *s ? strlen(*s) : 0;} +# endif +#endif + +/* PySequence_Size for old Pythons */ +#if PY_VERSION_HEX < 0x02000000 +# ifndef PySequence_Size +# define PySequence_Size PySequence_Length +# endif +#endif + +/* PyBool_FromLong for old Pythons */ +#if PY_VERSION_HEX < 0x02030000 +static +PyObject *PyBool_FromLong(long ok) +{ + PyObject *result = ok ? Py_True : Py_False; + Py_INCREF(result); + return result; +} +#endif + +/* Py_ssize_t for old Pythons */ +/* This code is as recommended by: */ +/* http://www.python.org/dev/peps/pep-0353/#conversion-guidelines */ +#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN) +typedef int Py_ssize_t; +# define PY_SSIZE_T_MAX INT_MAX +# define PY_SSIZE_T_MIN INT_MIN +#endif + +/* ----------------------------------------------------------------------------- + * error manipulation + * ----------------------------------------------------------------------------- */ + +SWIGRUNTIME PyObject* +SWIG_Python_ErrorType(int code) { + PyObject* type = 0; + switch(code) { + case SWIG_MemoryError: + type = PyExc_MemoryError; + break; + case SWIG_IOError: + type = PyExc_IOError; + break; + case SWIG_RuntimeError: + type = PyExc_RuntimeError; + break; + case SWIG_IndexError: + type = PyExc_IndexError; + break; + case SWIG_TypeError: + type = PyExc_TypeError; + break; + case SWIG_DivisionByZero: + type = PyExc_ZeroDivisionError; + break; + case SWIG_OverflowError: + type = PyExc_OverflowError; + break; + case SWIG_SyntaxError: + type = PyExc_SyntaxError; + break; + case SWIG_ValueError: + type = PyExc_ValueError; + break; + case SWIG_SystemError: + type = PyExc_SystemError; + break; + case SWIG_AttributeError: + type = PyExc_AttributeError; + break; + default: + type = PyExc_RuntimeError; + } + return type; +} + + +SWIGRUNTIME void +SWIG_Python_AddErrorMsg(const char* mesg) +{ + PyObject *type = 0; + PyObject *value = 0; + PyObject *traceback = 0; + + if (PyErr_Occurred()) PyErr_Fetch(&type, &value, &traceback); + if (value) { + PyObject *old_str = PyObject_Str(value); + PyErr_Clear(); + Py_XINCREF(type); + + PyErr_Format(type, "%s %s", SWIG_Python_str_AsChar(old_str), mesg); + Py_DECREF(old_str); + Py_DECREF(value); + } else { + PyErr_SetString(PyExc_RuntimeError, mesg); + } +} + +#if defined(SWIG_PYTHON_NO_THREADS) +# if defined(SWIG_PYTHON_THREADS) +# undef SWIG_PYTHON_THREADS +# endif +#endif +#if defined(SWIG_PYTHON_THREADS) /* Threading support is enabled */ +# if !defined(SWIG_PYTHON_USE_GIL) && !defined(SWIG_PYTHON_NO_USE_GIL) +# if (PY_VERSION_HEX >= 0x02030000) /* For 2.3 or later, use the PyGILState calls */ +# define SWIG_PYTHON_USE_GIL +# endif +# endif +# if defined(SWIG_PYTHON_USE_GIL) /* Use PyGILState threads calls */ +# ifndef SWIG_PYTHON_INITIALIZE_THREADS +# define SWIG_PYTHON_INITIALIZE_THREADS PyEval_InitThreads() +# endif +# ifdef __cplusplus /* C++ code */ + class SWIG_Python_Thread_Block { + bool status; + PyGILState_STATE state; + public: + void end() { if (status) { PyGILState_Release(state); status = false;} } + SWIG_Python_Thread_Block() : status(true), state(PyGILState_Ensure()) {} + ~SWIG_Python_Thread_Block() { end(); } + }; + class SWIG_Python_Thread_Allow { + bool status; + PyThreadState *save; + public: + void end() { if (status) { PyEval_RestoreThread(save); status = false; }} + SWIG_Python_Thread_Allow() : status(true), save(PyEval_SaveThread()) {} + ~SWIG_Python_Thread_Allow() { end(); } + }; +# define SWIG_PYTHON_THREAD_BEGIN_BLOCK SWIG_Python_Thread_Block _swig_thread_block +# define SWIG_PYTHON_THREAD_END_BLOCK _swig_thread_block.end() +# define SWIG_PYTHON_THREAD_BEGIN_ALLOW SWIG_Python_Thread_Allow _swig_thread_allow +# define SWIG_PYTHON_THREAD_END_ALLOW _swig_thread_allow.end() +# else /* C code */ +# define SWIG_PYTHON_THREAD_BEGIN_BLOCK PyGILState_STATE _swig_thread_block = PyGILState_Ensure() +# define SWIG_PYTHON_THREAD_END_BLOCK PyGILState_Release(_swig_thread_block) +# define SWIG_PYTHON_THREAD_BEGIN_ALLOW PyThreadState *_swig_thread_allow = PyEval_SaveThread() +# define SWIG_PYTHON_THREAD_END_ALLOW PyEval_RestoreThread(_swig_thread_allow) +# endif +# else /* Old thread way, not implemented, user must provide it */ +# if !defined(SWIG_PYTHON_INITIALIZE_THREADS) +# define SWIG_PYTHON_INITIALIZE_THREADS +# endif +# if !defined(SWIG_PYTHON_THREAD_BEGIN_BLOCK) +# define SWIG_PYTHON_THREAD_BEGIN_BLOCK +# endif +# if !defined(SWIG_PYTHON_THREAD_END_BLOCK) +# define SWIG_PYTHON_THREAD_END_BLOCK +# endif +# if !defined(SWIG_PYTHON_THREAD_BEGIN_ALLOW) +# define SWIG_PYTHON_THREAD_BEGIN_ALLOW +# endif +# if !defined(SWIG_PYTHON_THREAD_END_ALLOW) +# define SWIG_PYTHON_THREAD_END_ALLOW +# endif +# endif +#else /* No thread support */ +# define SWIG_PYTHON_INITIALIZE_THREADS +# define SWIG_PYTHON_THREAD_BEGIN_BLOCK +# define SWIG_PYTHON_THREAD_END_BLOCK +# define SWIG_PYTHON_THREAD_BEGIN_ALLOW +# define SWIG_PYTHON_THREAD_END_ALLOW +#endif + +/* ----------------------------------------------------------------------------- + * Python API portion that goes into the runtime + * ----------------------------------------------------------------------------- */ + +#ifdef __cplusplus +extern "C" { +#if 0 +} /* cc-mode */ +#endif +#endif + +/* ----------------------------------------------------------------------------- + * Constant declarations + * ----------------------------------------------------------------------------- */ + +/* Constant Types */ +#define SWIG_PY_POINTER 4 +#define SWIG_PY_BINARY 5 + +/* Constant information structure */ +typedef struct swig_const_info { + int type; + char *name; + long lvalue; + double dvalue; + void *pvalue; + swig_type_info **ptype; +} swig_const_info; + + +/* ----------------------------------------------------------------------------- + * Wrapper of PyInstanceMethod_New() used in Python 3 + * It is exported to the generated module, used for -fastproxy + * ----------------------------------------------------------------------------- */ +SWIGRUNTIME PyObject* SWIG_PyInstanceMethod_New(PyObject *self, PyObject *func) +{ +#if PY_VERSION_HEX >= 0x03000000 + return PyInstanceMethod_New(func); +#else + return NULL; +#endif +} + +#ifdef __cplusplus +#if 0 +{ /* cc-mode */ +#endif +} +#endif + + +/* ----------------------------------------------------------------------------- + * See the LICENSE file for information on copyright, usage and redistribution + * of SWIG, and the README file for authors - http://www.swig.org/release.html. + * + * pyrun.swg + * + * This file contains the runtime support for Python modules + * and includes code for managing global variables and pointer + * type checking. + * + * ----------------------------------------------------------------------------- */ + +/* Common SWIG API */ + +/* for raw pointers */ +#define SWIG_Python_ConvertPtr(obj, pptr, type, flags) SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, 0) +#define SWIG_ConvertPtr(obj, pptr, type, flags) SWIG_Python_ConvertPtr(obj, pptr, type, flags) +#define SWIG_ConvertPtrAndOwn(obj,pptr,type,flags,own) SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, own) +#define SWIG_NewPointerObj(ptr, type, flags) SWIG_Python_NewPointerObj(ptr, type, flags) +#define SWIG_CheckImplicit(ty) SWIG_Python_CheckImplicit(ty) +#define SWIG_AcquirePtr(ptr, src) SWIG_Python_AcquirePtr(ptr, src) +#define swig_owntype int + +/* for raw packed data */ +#define SWIG_ConvertPacked(obj, ptr, sz, ty) SWIG_Python_ConvertPacked(obj, ptr, sz, ty) +#define SWIG_NewPackedObj(ptr, sz, type) SWIG_Python_NewPackedObj(ptr, sz, type) + +/* for class or struct pointers */ +#define SWIG_ConvertInstance(obj, pptr, type, flags) SWIG_ConvertPtr(obj, pptr, type, flags) +#define SWIG_NewInstanceObj(ptr, type, flags) SWIG_NewPointerObj(ptr, type, flags) + +/* for C or C++ function pointers */ +#define SWIG_ConvertFunctionPtr(obj, pptr, type) SWIG_Python_ConvertFunctionPtr(obj, pptr, type) +#define SWIG_NewFunctionPtrObj(ptr, type) SWIG_Python_NewPointerObj(ptr, type, 0) + +/* for C++ member pointers, ie, member methods */ +#define SWIG_ConvertMember(obj, ptr, sz, ty) SWIG_Python_ConvertPacked(obj, ptr, sz, ty) +#define SWIG_NewMemberObj(ptr, sz, type) SWIG_Python_NewPackedObj(ptr, sz, type) + + +/* Runtime API */ + +#define SWIG_GetModule(clientdata) SWIG_Python_GetModule() +#define SWIG_SetModule(clientdata, pointer) SWIG_Python_SetModule(pointer) +#define SWIG_NewClientData(obj) SwigPyClientData_New(obj) + +#define SWIG_SetErrorObj SWIG_Python_SetErrorObj +#define SWIG_SetErrorMsg SWIG_Python_SetErrorMsg +#define SWIG_ErrorType(code) SWIG_Python_ErrorType(code) +#define SWIG_Error(code, msg) SWIG_Python_SetErrorMsg(SWIG_ErrorType(code), msg) +#define SWIG_fail goto fail + + +/* Runtime API implementation */ + +/* Error manipulation */ + +SWIGINTERN void +SWIG_Python_SetErrorObj(PyObject *errtype, PyObject *obj) { + SWIG_PYTHON_THREAD_BEGIN_BLOCK; + PyErr_SetObject(errtype, obj); + Py_DECREF(obj); + SWIG_PYTHON_THREAD_END_BLOCK; +} + +SWIGINTERN void +SWIG_Python_SetErrorMsg(PyObject *errtype, const char *msg) { + SWIG_PYTHON_THREAD_BEGIN_BLOCK; + PyErr_SetString(errtype, (char *) msg); + SWIG_PYTHON_THREAD_END_BLOCK; +} + +#define SWIG_Python_Raise(obj, type, desc) SWIG_Python_SetErrorObj(SWIG_Python_ExceptionType(desc), obj) + +/* Set a constant value */ + +SWIGINTERN void +SWIG_Python_SetConstant(PyObject *d, const char *name, PyObject *obj) { + PyDict_SetItemString(d, (char*) name, obj); + Py_DECREF(obj); +} + +/* Append a value to the result obj */ + +SWIGINTERN PyObject* +SWIG_Python_AppendOutput(PyObject* result, PyObject* obj) { +#if !defined(SWIG_PYTHON_OUTPUT_TUPLE) + if (!result) { + result = obj; + } else if (result == Py_None) { + Py_DECREF(result); + result = obj; + } else { + if (!PyList_Check(result)) { + PyObject *o2 = result; + result = PyList_New(1); + PyList_SetItem(result, 0, o2); + } + PyList_Append(result,obj); + Py_DECREF(obj); + } + return result; +#else + PyObject* o2; + PyObject* o3; + if (!result) { + result = obj; + } else if (result == Py_None) { + Py_DECREF(result); + result = obj; + } else { + if (!PyTuple_Check(result)) { + o2 = result; + result = PyTuple_New(1); + PyTuple_SET_ITEM(result, 0, o2); + } + o3 = PyTuple_New(1); + PyTuple_SET_ITEM(o3, 0, obj); + o2 = result; + result = PySequence_Concat(o2, o3); + Py_DECREF(o2); + Py_DECREF(o3); + } + return result; +#endif +} + +/* Unpack the argument tuple */ + +SWIGINTERN int +SWIG_Python_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, PyObject **objs) +{ + if (!args) { + if (!min && !max) { + return 1; + } else { + PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got none", + name, (min == max ? "" : "at least "), (int)min); + return 0; + } + } + if (!PyTuple_Check(args)) { + PyErr_SetString(PyExc_SystemError, "UnpackTuple() argument list is not a tuple"); + return 0; + } else { + register Py_ssize_t l = PyTuple_GET_SIZE(args); + if (l < min) { + PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d", + name, (min == max ? "" : "at least "), (int)min, (int)l); + return 0; + } else if (l > max) { + PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d", + name, (min == max ? "" : "at most "), (int)max, (int)l); + return 0; + } else { + register int i; + for (i = 0; i < l; ++i) { + objs[i] = PyTuple_GET_ITEM(args, i); + } + for (; l < max; ++l) { + objs[l] = 0; + } + return i + 1; + } + } +} + +/* A functor is a function object with one single object argument */ +#if PY_VERSION_HEX >= 0x02020000 +#define SWIG_Python_CallFunctor(functor, obj) PyObject_CallFunctionObjArgs(functor, obj, NULL); +#else +#define SWIG_Python_CallFunctor(functor, obj) PyObject_CallFunction(functor, "O", obj); +#endif + +/* + Helper for static pointer initialization for both C and C++ code, for example + static PyObject *SWIG_STATIC_POINTER(MyVar) = NewSomething(...); +*/ +#ifdef __cplusplus +#define SWIG_STATIC_POINTER(var) var +#else +#define SWIG_STATIC_POINTER(var) var = 0; if (!var) var +#endif + +/* ----------------------------------------------------------------------------- + * Pointer declarations + * ----------------------------------------------------------------------------- */ + +/* Flags for new pointer objects */ +#define SWIG_POINTER_NOSHADOW (SWIG_POINTER_OWN << 1) +#define SWIG_POINTER_NEW (SWIG_POINTER_NOSHADOW | SWIG_POINTER_OWN) + +#define SWIG_POINTER_IMPLICIT_CONV (SWIG_POINTER_DISOWN << 1) + +#ifdef __cplusplus +extern "C" { +#if 0 +} /* cc-mode */ +#endif +#endif + +/* How to access Py_None */ +#if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# ifndef SWIG_PYTHON_NO_BUILD_NONE +# ifndef SWIG_PYTHON_BUILD_NONE +# define SWIG_PYTHON_BUILD_NONE +# endif +# endif +#endif + +#ifdef SWIG_PYTHON_BUILD_NONE +# ifdef Py_None +# undef Py_None +# define Py_None SWIG_Py_None() +# endif +SWIGRUNTIMEINLINE PyObject * +_SWIG_Py_None(void) +{ + PyObject *none = Py_BuildValue((char*)""); + Py_DECREF(none); + return none; +} +SWIGRUNTIME PyObject * +SWIG_Py_None(void) +{ + static PyObject *SWIG_STATIC_POINTER(none) = _SWIG_Py_None(); + return none; +} +#endif + +/* The python void return value */ + +SWIGRUNTIMEINLINE PyObject * +SWIG_Py_Void(void) +{ + PyObject *none = Py_None; + Py_INCREF(none); + return none; +} + +/* SwigPyClientData */ + +typedef struct { + PyObject *klass; + PyObject *newraw; + PyObject *newargs; + PyObject *destroy; + int delargs; + int implicitconv; +} SwigPyClientData; + +SWIGRUNTIMEINLINE int +SWIG_Python_CheckImplicit(swig_type_info *ty) +{ + SwigPyClientData *data = (SwigPyClientData *)ty->clientdata; + return data ? data->implicitconv : 0; +} + +SWIGRUNTIMEINLINE PyObject * +SWIG_Python_ExceptionType(swig_type_info *desc) { + SwigPyClientData *data = desc ? (SwigPyClientData *) desc->clientdata : 0; + PyObject *klass = data ? data->klass : 0; + return (klass ? klass : PyExc_RuntimeError); +} + + +SWIGRUNTIME SwigPyClientData * +SwigPyClientData_New(PyObject* obj) +{ + if (!obj) { + return 0; + } else { + SwigPyClientData *data = (SwigPyClientData *)malloc(sizeof(SwigPyClientData)); + /* the klass element */ + data->klass = obj; + Py_INCREF(data->klass); + /* the newraw method and newargs arguments used to create a new raw instance */ + if (PyClass_Check(obj)) { + data->newraw = 0; + data->newargs = obj; + Py_INCREF(obj); + } else { +#if (PY_VERSION_HEX < 0x02020000) + data->newraw = 0; +#else + data->newraw = PyObject_GetAttrString(data->klass, (char *)"__new__"); +#endif + if (data->newraw) { + Py_INCREF(data->newraw); + data->newargs = PyTuple_New(1); + PyTuple_SetItem(data->newargs, 0, obj); + } else { + data->newargs = obj; + } + Py_INCREF(data->newargs); + } + /* the destroy method, aka as the C++ delete method */ + data->destroy = PyObject_GetAttrString(data->klass, (char *)"__swig_destroy__"); + if (PyErr_Occurred()) { + PyErr_Clear(); + data->destroy = 0; + } + if (data->destroy) { + int flags; + Py_INCREF(data->destroy); + flags = PyCFunction_GET_FLAGS(data->destroy); +#ifdef METH_O + data->delargs = !(flags & (METH_O)); +#else + data->delargs = 0; +#endif + } else { + data->delargs = 0; + } + data->implicitconv = 0; + return data; + } +} + +SWIGRUNTIME void +SwigPyClientData_Del(SwigPyClientData* data) +{ + Py_XDECREF(data->newraw); + Py_XDECREF(data->newargs); + Py_XDECREF(data->destroy); +} + +/* =============== SwigPyObject =====================*/ + +typedef struct { + PyObject_HEAD + void *ptr; + swig_type_info *ty; + int own; + PyObject *next; +} SwigPyObject; + +SWIGRUNTIME PyObject * +SwigPyObject_long(SwigPyObject *v) +{ + return PyLong_FromVoidPtr(v->ptr); +} + +SWIGRUNTIME PyObject * +SwigPyObject_format(const char* fmt, SwigPyObject *v) +{ + PyObject *res = NULL; + PyObject *args = PyTuple_New(1); + if (args) { + if (PyTuple_SetItem(args, 0, SwigPyObject_long(v)) == 0) { + PyObject *ofmt = SWIG_Python_str_FromChar(fmt); + if (ofmt) { +#if PY_VERSION_HEX >= 0x03000000 + res = PyUnicode_Format(ofmt,args); +#else + res = PyString_Format(ofmt,args); +#endif + Py_DECREF(ofmt); + } + Py_DECREF(args); + } + } + return res; +} + +SWIGRUNTIME PyObject * +SwigPyObject_oct(SwigPyObject *v) +{ + return SwigPyObject_format("%o",v); +} + +SWIGRUNTIME PyObject * +SwigPyObject_hex(SwigPyObject *v) +{ + return SwigPyObject_format("%x",v); +} + +SWIGRUNTIME PyObject * +#ifdef METH_NOARGS +SwigPyObject_repr(SwigPyObject *v) +#else +SwigPyObject_repr(SwigPyObject *v, PyObject *args) +#endif +{ + const char *name = SWIG_TypePrettyName(v->ty); + PyObject *hex = SwigPyObject_hex(v); + PyObject *repr = SWIG_Python_str_FromFormat("", name, hex); + Py_DECREF(hex); + if (v->next) { +#ifdef METH_NOARGS + PyObject *nrep = SwigPyObject_repr((SwigPyObject *)v->next); +#else + PyObject *nrep = SwigPyObject_repr((SwigPyObject *)v->next, args); +#endif +#if PY_VERSION_HEX >= 0x03000000 + PyObject *joined = PyUnicode_Concat(repr, nrep); + Py_DecRef(repr); + Py_DecRef(nrep); + repr = joined; +#else + PyString_ConcatAndDel(&repr,nrep); +#endif + } + return repr; +} + +SWIGRUNTIME int +SwigPyObject_print(SwigPyObject *v, FILE *fp, int SWIGUNUSEDPARM(flags)) +{ +#ifdef METH_NOARGS + PyObject *repr = SwigPyObject_repr(v); +#else + PyObject *repr = SwigPyObject_repr(v, NULL); +#endif + if (repr) { + fputs(SWIG_Python_str_AsChar(repr), fp); + Py_DECREF(repr); + return 0; + } else { + return 1; + } +} + +SWIGRUNTIME PyObject * +SwigPyObject_str(SwigPyObject *v) +{ + char result[SWIG_BUFFER_SIZE]; + return SWIG_PackVoidPtr(result, v->ptr, v->ty->name, sizeof(result)) ? + SWIG_Python_str_FromChar(result) : 0; +} + +SWIGRUNTIME int +SwigPyObject_compare(SwigPyObject *v, SwigPyObject *w) +{ + void *i = v->ptr; + void *j = w->ptr; + return (i < j) ? -1 : ((i > j) ? 1 : 0); +} + +/* Added for Python 3.x, whould it also useful for Python 2.x? */ +SWIGRUNTIME PyObject* +SwigPyObject_richcompare(SwigPyObject *v, SwigPyObject *w, int op) +{ + PyObject* res; + if( op != Py_EQ && op != Py_NE ) { + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; + } + if( (SwigPyObject_compare(v, w)==0) == (op == Py_EQ) ) + res = Py_True; + else + res = Py_False; + Py_INCREF(res); + return res; +} + + +SWIGRUNTIME PyTypeObject* _PySwigObject_type(void); + +SWIGRUNTIME PyTypeObject* +SwigPyObject_type(void) { + static PyTypeObject *SWIG_STATIC_POINTER(type) = _PySwigObject_type(); + return type; +} + +SWIGRUNTIMEINLINE int +SwigPyObject_Check(PyObject *op) { + return (Py_TYPE(op) == SwigPyObject_type()) + || (strcmp(Py_TYPE(op)->tp_name,"SwigPyObject") == 0); +} + +SWIGRUNTIME PyObject * +SwigPyObject_New(void *ptr, swig_type_info *ty, int own); + +SWIGRUNTIME void +SwigPyObject_dealloc(PyObject *v) +{ + SwigPyObject *sobj = (SwigPyObject *) v; + PyObject *next = sobj->next; + if (sobj->own == SWIG_POINTER_OWN) { + swig_type_info *ty = sobj->ty; + SwigPyClientData *data = ty ? (SwigPyClientData *) ty->clientdata : 0; + PyObject *destroy = data ? data->destroy : 0; + if (destroy) { + /* destroy is always a VARARGS method */ + PyObject *res; + if (data->delargs) { + /* we need to create a temporal object to carry the destroy operation */ + PyObject *tmp = SwigPyObject_New(sobj->ptr, ty, 0); + res = SWIG_Python_CallFunctor(destroy, tmp); + Py_DECREF(tmp); + } else { + PyCFunction meth = PyCFunction_GET_FUNCTION(destroy); + PyObject *mself = PyCFunction_GET_SELF(destroy); + res = ((*meth)(mself, v)); + } + Py_XDECREF(res); + } +#if !defined(SWIG_PYTHON_SILENT_MEMLEAK) + else { + const char *name = SWIG_TypePrettyName(ty); + printf("swig/python detected a memory leak of type '%s', no destructor found.\n", (name ? name : "unknown")); + } +#endif + } + Py_XDECREF(next); + PyObject_DEL(v); +} + +SWIGRUNTIME PyObject* +SwigPyObject_append(PyObject* v, PyObject* next) +{ + SwigPyObject *sobj = (SwigPyObject *) v; +#ifndef METH_O + PyObject *tmp = 0; + if (!PyArg_ParseTuple(next,(char *)"O:append", &tmp)) return NULL; + next = tmp; +#endif + if (!SwigPyObject_Check(next)) { + return NULL; + } + sobj->next = next; + Py_INCREF(next); + return SWIG_Py_Void(); +} + +SWIGRUNTIME PyObject* +#ifdef METH_NOARGS +SwigPyObject_next(PyObject* v) +#else +SwigPyObject_next(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) +#endif +{ + SwigPyObject *sobj = (SwigPyObject *) v; + if (sobj->next) { + Py_INCREF(sobj->next); + return sobj->next; + } else { + return SWIG_Py_Void(); + } +} + +SWIGINTERN PyObject* +#ifdef METH_NOARGS +SwigPyObject_disown(PyObject *v) +#else +SwigPyObject_disown(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) +#endif +{ + SwigPyObject *sobj = (SwigPyObject *)v; + sobj->own = 0; + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject* +#ifdef METH_NOARGS +SwigPyObject_acquire(PyObject *v) +#else +SwigPyObject_acquire(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) +#endif +{ + SwigPyObject *sobj = (SwigPyObject *)v; + sobj->own = SWIG_POINTER_OWN; + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject* +SwigPyObject_own(PyObject *v, PyObject *args) +{ + PyObject *val = 0; +#if (PY_VERSION_HEX < 0x02020000) + if (!PyArg_ParseTuple(args,(char *)"|O:own",&val)) +#else + if (!PyArg_UnpackTuple(args, (char *)"own", 0, 1, &val)) +#endif + { + return NULL; + } + else + { + SwigPyObject *sobj = (SwigPyObject *)v; + PyObject *obj = PyBool_FromLong(sobj->own); + if (val) { +#ifdef METH_NOARGS + if (PyObject_IsTrue(val)) { + SwigPyObject_acquire(v); + } else { + SwigPyObject_disown(v); + } +#else + if (PyObject_IsTrue(val)) { + SwigPyObject_acquire(v,args); + } else { + SwigPyObject_disown(v,args); + } +#endif + } + return obj; + } +} + +#ifdef METH_O +static PyMethodDef +swigobject_methods[] = { + {(char *)"disown", (PyCFunction)SwigPyObject_disown, METH_NOARGS, (char *)"releases ownership of the pointer"}, + {(char *)"acquire", (PyCFunction)SwigPyObject_acquire, METH_NOARGS, (char *)"aquires ownership of the pointer"}, + {(char *)"own", (PyCFunction)SwigPyObject_own, METH_VARARGS, (char *)"returns/sets ownership of the pointer"}, + {(char *)"append", (PyCFunction)SwigPyObject_append, METH_O, (char *)"appends another 'this' object"}, + {(char *)"next", (PyCFunction)SwigPyObject_next, METH_NOARGS, (char *)"returns the next 'this' object"}, + {(char *)"__repr__",(PyCFunction)SwigPyObject_repr, METH_NOARGS, (char *)"returns object representation"}, + {0, 0, 0, 0} +}; +#else +static PyMethodDef +swigobject_methods[] = { + {(char *)"disown", (PyCFunction)SwigPyObject_disown, METH_VARARGS, (char *)"releases ownership of the pointer"}, + {(char *)"acquire", (PyCFunction)SwigPyObject_acquire, METH_VARARGS, (char *)"aquires ownership of the pointer"}, + {(char *)"own", (PyCFunction)SwigPyObject_own, METH_VARARGS, (char *)"returns/sets ownership of the pointer"}, + {(char *)"append", (PyCFunction)SwigPyObject_append, METH_VARARGS, (char *)"appends another 'this' object"}, + {(char *)"next", (PyCFunction)SwigPyObject_next, METH_VARARGS, (char *)"returns the next 'this' object"}, + {(char *)"__repr__",(PyCFunction)SwigPyObject_repr, METH_VARARGS, (char *)"returns object representation"}, + {0, 0, 0, 0} +}; +#endif + +#if PY_VERSION_HEX < 0x02020000 +SWIGINTERN PyObject * +SwigPyObject_getattr(SwigPyObject *sobj,char *name) +{ + return Py_FindMethod(swigobject_methods, (PyObject *)sobj, name); +} +#endif + +SWIGRUNTIME PyTypeObject* +_PySwigObject_type(void) { + static char swigobject_doc[] = "Swig object carries a C/C++ instance pointer"; + + static PyNumberMethods SwigPyObject_as_number = { + (binaryfunc)0, /*nb_add*/ + (binaryfunc)0, /*nb_subtract*/ + (binaryfunc)0, /*nb_multiply*/ + /* nb_divide removed in Python 3 */ +#if PY_VERSION_HEX < 0x03000000 + (binaryfunc)0, /*nb_divide*/ +#endif + (binaryfunc)0, /*nb_remainder*/ + (binaryfunc)0, /*nb_divmod*/ + (ternaryfunc)0,/*nb_power*/ + (unaryfunc)0, /*nb_negative*/ + (unaryfunc)0, /*nb_positive*/ + (unaryfunc)0, /*nb_absolute*/ + (inquiry)0, /*nb_nonzero*/ + 0, /*nb_invert*/ + 0, /*nb_lshift*/ + 0, /*nb_rshift*/ + 0, /*nb_and*/ + 0, /*nb_xor*/ + 0, /*nb_or*/ +#if PY_VERSION_HEX < 0x03000000 + 0, /*nb_coerce*/ +#endif + (unaryfunc)SwigPyObject_long, /*nb_int*/ + (unaryfunc)SwigPyObject_long, /*nb_long*/ + (unaryfunc)0, /*nb_float*/ +#if PY_VERSION_HEX < 0x03000000 + (unaryfunc)SwigPyObject_oct, /*nb_oct*/ + (unaryfunc)SwigPyObject_hex, /*nb_hex*/ +#endif +#if PY_VERSION_HEX >= 0x03000000 /* 3.0 */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_index, nb_inplace_divide removed */ +#elif PY_VERSION_HEX >= 0x02050000 /* 2.5.0 */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_index */ +#elif PY_VERSION_HEX >= 0x02020000 /* 2.2.0 */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_true_divide */ +#elif PY_VERSION_HEX >= 0x02000000 /* 2.0.0 */ + 0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_or */ +#endif + }; + + static PyTypeObject swigpyobject_type; + static int type_init = 0; + if (!type_init) { + const PyTypeObject tmp + = { + /* PyOjbect header changed in Python 3 */ +#if PY_VERSION_HEX >= 0x03000000 + PyVarObject_HEAD_INIT(&PyType_Type, 0) +#else + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ +#endif + (char *)"SwigPyObject", /* tp_name */ + sizeof(SwigPyObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)SwigPyObject_dealloc, /* tp_dealloc */ + (printfunc)SwigPyObject_print, /* tp_print */ +#if PY_VERSION_HEX < 0x02020000 + (getattrfunc)SwigPyObject_getattr, /* tp_getattr */ +#else + (getattrfunc)0, /* tp_getattr */ +#endif + (setattrfunc)0, /* tp_setattr */ + (cmpfunc)SwigPyObject_compare, /* tp_compare */ + (reprfunc)SwigPyObject_repr, /* tp_repr */ + &SwigPyObject_as_number, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + (hashfunc)0, /* tp_hash */ + (ternaryfunc)0, /* tp_call */ + (reprfunc)SwigPyObject_str, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + swigobject_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + (richcmpfunc)SwigPyObject_richcompare, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ +#if PY_VERSION_HEX >= 0x02020000 + 0, /* tp_iter */ + 0, /* tp_iternext */ + swigobject_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ +#endif +#if PY_VERSION_HEX >= 0x02030000 + 0, /* tp_del */ +#endif +#ifdef COUNT_ALLOCS + 0,0,0,0 /* tp_alloc -> tp_next */ +#endif + }; + swigpyobject_type = tmp; + /* for Python 3 we already assigned the ob_type in PyVarObject_HEAD_INIT() */ +#if PY_VERSION_HEX < 0x03000000 + swigpyobject_type.ob_type = &PyType_Type; +#endif + type_init = 1; + } + return &swigpyobject_type; +} + +SWIGRUNTIME PyObject * +SwigPyObject_New(void *ptr, swig_type_info *ty, int own) +{ + SwigPyObject *sobj = PyObject_NEW(SwigPyObject, SwigPyObject_type()); + if (sobj) { + sobj->ptr = ptr; + sobj->ty = ty; + sobj->own = own; + sobj->next = 0; + } + return (PyObject *)sobj; +} + +/* ----------------------------------------------------------------------------- + * Implements a simple Swig Packed type, and use it instead of string + * ----------------------------------------------------------------------------- */ + +typedef struct { + PyObject_HEAD + void *pack; + swig_type_info *ty; + size_t size; +} SwigPyPacked; + +SWIGRUNTIME int +SwigPyPacked_print(SwigPyPacked *v, FILE *fp, int SWIGUNUSEDPARM(flags)) +{ + char result[SWIG_BUFFER_SIZE]; + fputs("pack, v->size, 0, sizeof(result))) { + fputs("at ", fp); + fputs(result, fp); + } + fputs(v->ty->name,fp); + fputs(">", fp); + return 0; +} + +SWIGRUNTIME PyObject * +SwigPyPacked_repr(SwigPyPacked *v) +{ + char result[SWIG_BUFFER_SIZE]; + if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))) { + return SWIG_Python_str_FromFormat("", result, v->ty->name); + } else { + return SWIG_Python_str_FromFormat("", v->ty->name); + } +} + +SWIGRUNTIME PyObject * +SwigPyPacked_str(SwigPyPacked *v) +{ + char result[SWIG_BUFFER_SIZE]; + if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))){ + return SWIG_Python_str_FromFormat("%s%s", result, v->ty->name); + } else { + return SWIG_Python_str_FromChar(v->ty->name); + } +} + +SWIGRUNTIME int +SwigPyPacked_compare(SwigPyPacked *v, SwigPyPacked *w) +{ + size_t i = v->size; + size_t j = w->size; + int s = (i < j) ? -1 : ((i > j) ? 1 : 0); + return s ? s : strncmp((char *)v->pack, (char *)w->pack, 2*v->size); +} + +SWIGRUNTIME PyTypeObject* _PySwigPacked_type(void); + +SWIGRUNTIME PyTypeObject* +SwigPyPacked_type(void) { + static PyTypeObject *SWIG_STATIC_POINTER(type) = _PySwigPacked_type(); + return type; +} + +SWIGRUNTIMEINLINE int +SwigPyPacked_Check(PyObject *op) { + return ((op)->ob_type == _PySwigPacked_type()) + || (strcmp((op)->ob_type->tp_name,"SwigPyPacked") == 0); +} + +SWIGRUNTIME void +SwigPyPacked_dealloc(PyObject *v) +{ + if (SwigPyPacked_Check(v)) { + SwigPyPacked *sobj = (SwigPyPacked *) v; + free(sobj->pack); + } + PyObject_DEL(v); +} + +SWIGRUNTIME PyTypeObject* +_PySwigPacked_type(void) { + static char swigpacked_doc[] = "Swig object carries a C/C++ instance pointer"; + static PyTypeObject swigpypacked_type; + static int type_init = 0; + if (!type_init) { + const PyTypeObject tmp + = { + /* PyObject header changed in Python 3 */ +#if PY_VERSION_HEX>=0x03000000 + PyVarObject_HEAD_INIT(&PyType_Type, 0) +#else + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ +#endif + (char *)"SwigPyPacked", /* tp_name */ + sizeof(SwigPyPacked), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)SwigPyPacked_dealloc, /* tp_dealloc */ + (printfunc)SwigPyPacked_print, /* tp_print */ + (getattrfunc)0, /* tp_getattr */ + (setattrfunc)0, /* tp_setattr */ + (cmpfunc)SwigPyPacked_compare, /* tp_compare */ + (reprfunc)SwigPyPacked_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + (hashfunc)0, /* tp_hash */ + (ternaryfunc)0, /* tp_call */ + (reprfunc)SwigPyPacked_str, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + swigpacked_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ +#if PY_VERSION_HEX >= 0x02020000 + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ +#endif +#if PY_VERSION_HEX >= 0x02030000 + 0, /* tp_del */ +#endif +#ifdef COUNT_ALLOCS + 0,0,0,0 /* tp_alloc -> tp_next */ +#endif + }; + swigpypacked_type = tmp; + /* for Python 3 the ob_type already assigned in PyVarObject_HEAD_INIT() */ +#if PY_VERSION_HEX < 0x03000000 + swigpypacked_type.ob_type = &PyType_Type; +#endif + type_init = 1; + } + return &swigpypacked_type; +} + +SWIGRUNTIME PyObject * +SwigPyPacked_New(void *ptr, size_t size, swig_type_info *ty) +{ + SwigPyPacked *sobj = PyObject_NEW(SwigPyPacked, SwigPyPacked_type()); + if (sobj) { + void *pack = malloc(size); + if (pack) { + memcpy(pack, ptr, size); + sobj->pack = pack; + sobj->ty = ty; + sobj->size = size; + } else { + PyObject_DEL((PyObject *) sobj); + sobj = 0; + } + } + return (PyObject *) sobj; +} + +SWIGRUNTIME swig_type_info * +SwigPyPacked_UnpackData(PyObject *obj, void *ptr, size_t size) +{ + if (SwigPyPacked_Check(obj)) { + SwigPyPacked *sobj = (SwigPyPacked *)obj; + if (sobj->size != size) return 0; + memcpy(ptr, sobj->pack, size); + return sobj->ty; + } else { + return 0; + } +} + +/* ----------------------------------------------------------------------------- + * pointers/data manipulation + * ----------------------------------------------------------------------------- */ + +SWIGRUNTIMEINLINE PyObject * +_SWIG_This(void) +{ + return SWIG_Python_str_FromChar("this"); +} + +SWIGRUNTIME PyObject * +SWIG_This(void) +{ + static PyObject *SWIG_STATIC_POINTER(swig_this) = _SWIG_This(); + return swig_this; +} + +/* #define SWIG_PYTHON_SLOW_GETSET_THIS */ + +/* TODO: I don't know how to implement the fast getset in Python 3 right now */ +#if PY_VERSION_HEX>=0x03000000 +#define SWIG_PYTHON_SLOW_GETSET_THIS +#endif + +SWIGRUNTIME SwigPyObject * +SWIG_Python_GetSwigThis(PyObject *pyobj) +{ + if (SwigPyObject_Check(pyobj)) { + return (SwigPyObject *) pyobj; + } else { + PyObject *obj = 0; +#if (!defined(SWIG_PYTHON_SLOW_GETSET_THIS) && (PY_VERSION_HEX >= 0x02030000)) + if (PyInstance_Check(pyobj)) { + obj = _PyInstance_Lookup(pyobj, SWIG_This()); + } else { + PyObject **dictptr = _PyObject_GetDictPtr(pyobj); + if (dictptr != NULL) { + PyObject *dict = *dictptr; + obj = dict ? PyDict_GetItem(dict, SWIG_This()) : 0; + } else { +#ifdef PyWeakref_CheckProxy + if (PyWeakref_CheckProxy(pyobj)) { + PyObject *wobj = PyWeakref_GET_OBJECT(pyobj); + return wobj ? SWIG_Python_GetSwigThis(wobj) : 0; + } +#endif + obj = PyObject_GetAttr(pyobj,SWIG_This()); + if (obj) { + Py_DECREF(obj); + } else { + if (PyErr_Occurred()) PyErr_Clear(); + return 0; + } + } + } +#else + obj = PyObject_GetAttr(pyobj,SWIG_This()); + if (obj) { + Py_DECREF(obj); + } else { + if (PyErr_Occurred()) PyErr_Clear(); + return 0; + } +#endif + if (obj && !SwigPyObject_Check(obj)) { + /* a PyObject is called 'this', try to get the 'real this' + SwigPyObject from it */ + return SWIG_Python_GetSwigThis(obj); + } + return (SwigPyObject *)obj; + } +} + +/* Acquire a pointer value */ + +SWIGRUNTIME int +SWIG_Python_AcquirePtr(PyObject *obj, int own) { + if (own == SWIG_POINTER_OWN) { + SwigPyObject *sobj = SWIG_Python_GetSwigThis(obj); + if (sobj) { + int oldown = sobj->own; + sobj->own = own; + return oldown; + } + } + return 0; +} + +/* Convert a pointer value */ + +SWIGRUNTIME int +SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int flags, int *own) { + if (!obj) return SWIG_ERROR; + if (obj == Py_None) { + if (ptr) *ptr = 0; + return SWIG_OK; + } else { + SwigPyObject *sobj = SWIG_Python_GetSwigThis(obj); + if (own) + *own = 0; + while (sobj) { + void *vptr = sobj->ptr; + if (ty) { + swig_type_info *to = sobj->ty; + if (to == ty) { + /* no type cast needed */ + if (ptr) *ptr = vptr; + break; + } else { + swig_cast_info *tc = SWIG_TypeCheck(to->name,ty); + if (!tc) { + sobj = (SwigPyObject *)sobj->next; + } else { + if (ptr) { + int newmemory = 0; + *ptr = SWIG_TypeCast(tc,vptr,&newmemory); + if (newmemory == SWIG_CAST_NEW_MEMORY) { + assert(own); + if (own) + *own = *own | SWIG_CAST_NEW_MEMORY; + } + } + break; + } + } + } else { + if (ptr) *ptr = vptr; + break; + } + } + if (sobj) { + if (own) + *own = *own | sobj->own; + if (flags & SWIG_POINTER_DISOWN) { + sobj->own = 0; + } + return SWIG_OK; + } else { + int res = SWIG_ERROR; + if (flags & SWIG_POINTER_IMPLICIT_CONV) { + SwigPyClientData *data = ty ? (SwigPyClientData *) ty->clientdata : 0; + if (data && !data->implicitconv) { + PyObject *klass = data->klass; + if (klass) { + PyObject *impconv; + data->implicitconv = 1; /* avoid recursion and call 'explicit' constructors*/ + impconv = SWIG_Python_CallFunctor(klass, obj); + data->implicitconv = 0; + if (PyErr_Occurred()) { + PyErr_Clear(); + impconv = 0; + } + if (impconv) { + SwigPyObject *iobj = SWIG_Python_GetSwigThis(impconv); + if (iobj) { + void *vptr; + res = SWIG_Python_ConvertPtrAndOwn((PyObject*)iobj, &vptr, ty, 0, 0); + if (SWIG_IsOK(res)) { + if (ptr) { + *ptr = vptr; + /* transfer the ownership to 'ptr' */ + iobj->own = 0; + res = SWIG_AddCast(res); + res = SWIG_AddNewMask(res); + } else { + res = SWIG_AddCast(res); + } + } + } + Py_DECREF(impconv); + } + } + } + } + return res; + } + } +} + +/* Convert a function ptr value */ + +SWIGRUNTIME int +SWIG_Python_ConvertFunctionPtr(PyObject *obj, void **ptr, swig_type_info *ty) { + if (!PyCFunction_Check(obj)) { + return SWIG_ConvertPtr(obj, ptr, ty, 0); + } else { + void *vptr = 0; + + /* here we get the method pointer for callbacks */ + const char *doc = (((PyCFunctionObject *)obj) -> m_ml -> ml_doc); + const char *desc = doc ? strstr(doc, "swig_ptr: ") : 0; + if (desc) { + desc = ty ? SWIG_UnpackVoidPtr(desc + 10, &vptr, ty->name) : 0; + if (!desc) return SWIG_ERROR; + } + if (ty) { + swig_cast_info *tc = SWIG_TypeCheck(desc,ty); + if (tc) { + int newmemory = 0; + *ptr = SWIG_TypeCast(tc,vptr,&newmemory); + assert(!newmemory); /* newmemory handling not yet implemented */ + } else { + return SWIG_ERROR; + } + } else { + *ptr = vptr; + } + return SWIG_OK; + } +} + +/* Convert a packed value value */ + +SWIGRUNTIME int +SWIG_Python_ConvertPacked(PyObject *obj, void *ptr, size_t sz, swig_type_info *ty) { + swig_type_info *to = SwigPyPacked_UnpackData(obj, ptr, sz); + if (!to) return SWIG_ERROR; + if (ty) { + if (to != ty) { + /* check type cast? */ + swig_cast_info *tc = SWIG_TypeCheck(to->name,ty); + if (!tc) return SWIG_ERROR; + } + } + return SWIG_OK; +} + +/* ----------------------------------------------------------------------------- + * Create a new pointer object + * ----------------------------------------------------------------------------- */ + +/* + Create a new instance object, whitout calling __init__, and set the + 'this' attribute. +*/ + +SWIGRUNTIME PyObject* +SWIG_Python_NewShadowInstance(SwigPyClientData *data, PyObject *swig_this) +{ +#if (PY_VERSION_HEX >= 0x02020000) + PyObject *inst = 0; + PyObject *newraw = data->newraw; + if (newraw) { + inst = PyObject_Call(newraw, data->newargs, NULL); + if (inst) { +#if !defined(SWIG_PYTHON_SLOW_GETSET_THIS) + PyObject **dictptr = _PyObject_GetDictPtr(inst); + if (dictptr != NULL) { + PyObject *dict = *dictptr; + if (dict == NULL) { + dict = PyDict_New(); + *dictptr = dict; + PyDict_SetItem(dict, SWIG_This(), swig_this); + } + } +#else + PyObject *key = SWIG_This(); + PyObject_SetAttr(inst, key, swig_this); +#endif + } + } else { +#if PY_VERSION_HEX >= 0x03000000 + inst = PyBaseObject_Type.tp_new((PyTypeObject*) data->newargs, Py_None, Py_None); + Py_INCREF(data->newargs); + PyObject_SetAttr(inst, SWIG_This(), swig_this); + Py_TYPE(inst)->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG; +#else + PyObject *dict = PyDict_New(); + PyDict_SetItem(dict, SWIG_This(), swig_this); + inst = PyInstance_NewRaw(data->newargs, dict); + Py_DECREF(dict); +#endif + } + return inst; +#else +#if (PY_VERSION_HEX >= 0x02010000) + PyObject *inst; + PyObject *dict = PyDict_New(); + PyDict_SetItem(dict, SWIG_This(), swig_this); + inst = PyInstance_NewRaw(data->newargs, dict); + Py_DECREF(dict); + return (PyObject *) inst; +#else + PyInstanceObject *inst = PyObject_NEW(PyInstanceObject, &PyInstance_Type); + if (inst == NULL) { + return NULL; + } + inst->in_class = (PyClassObject *)data->newargs; + Py_INCREF(inst->in_class); + inst->in_dict = PyDict_New(); + if (inst->in_dict == NULL) { + Py_DECREF(inst); + return NULL; + } +#ifdef Py_TPFLAGS_HAVE_WEAKREFS + inst->in_weakreflist = NULL; +#endif +#ifdef Py_TPFLAGS_GC + PyObject_GC_Init(inst); +#endif + PyDict_SetItem(inst->in_dict, SWIG_This(), swig_this); + return (PyObject *) inst; +#endif +#endif +} + +SWIGRUNTIME void +SWIG_Python_SetSwigThis(PyObject *inst, PyObject *swig_this) +{ + PyObject *dict; +#if (PY_VERSION_HEX >= 0x02020000) && !defined(SWIG_PYTHON_SLOW_GETSET_THIS) + PyObject **dictptr = _PyObject_GetDictPtr(inst); + if (dictptr != NULL) { + dict = *dictptr; + if (dict == NULL) { + dict = PyDict_New(); + *dictptr = dict; + } + PyDict_SetItem(dict, SWIG_This(), swig_this); + return; + } +#endif + dict = PyObject_GetAttrString(inst, (char*)"__dict__"); + PyDict_SetItem(dict, SWIG_This(), swig_this); + Py_DECREF(dict); +} + + +SWIGINTERN PyObject * +SWIG_Python_InitShadowInstance(PyObject *args) { + PyObject *obj[2]; + if (!SWIG_Python_UnpackTuple(args,(char*)"swiginit", 2, 2, obj)) { + return NULL; + } else { + SwigPyObject *sthis = SWIG_Python_GetSwigThis(obj[0]); + if (sthis) { + SwigPyObject_append((PyObject*) sthis, obj[1]); + } else { + SWIG_Python_SetSwigThis(obj[0], obj[1]); + } + return SWIG_Py_Void(); + } +} + +/* Create a new pointer object */ + +SWIGRUNTIME PyObject * +SWIG_Python_NewPointerObj(void *ptr, swig_type_info *type, int flags) { + if (!ptr) { + return SWIG_Py_Void(); + } else { + int own = (flags & SWIG_POINTER_OWN) ? SWIG_POINTER_OWN : 0; + PyObject *robj = SwigPyObject_New(ptr, type, own); + SwigPyClientData *clientdata = type ? (SwigPyClientData *)(type->clientdata) : 0; + if (clientdata && !(flags & SWIG_POINTER_NOSHADOW)) { + PyObject *inst = SWIG_Python_NewShadowInstance(clientdata, robj); + if (inst) { + Py_DECREF(robj); + robj = inst; + } + } + return robj; + } +} + +/* Create a new packed object */ + +SWIGRUNTIMEINLINE PyObject * +SWIG_Python_NewPackedObj(void *ptr, size_t sz, swig_type_info *type) { + return ptr ? SwigPyPacked_New((void *) ptr, sz, type) : SWIG_Py_Void(); +} + +/* -----------------------------------------------------------------------------* + * Get type list + * -----------------------------------------------------------------------------*/ + +#ifdef SWIG_LINK_RUNTIME +void *SWIG_ReturnGlobalTypeList(void *); +#endif + +SWIGRUNTIME swig_module_info * +SWIG_Python_GetModule(void) { + static void *type_pointer = (void *)0; + /* first check if module already created */ + if (!type_pointer) { +#ifdef SWIG_LINK_RUNTIME + type_pointer = SWIG_ReturnGlobalTypeList((void *)0); +#else + type_pointer = PyCObject_Import((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION, + (char*)"type_pointer" SWIG_TYPE_TABLE_NAME); + if (PyErr_Occurred()) { + PyErr_Clear(); + type_pointer = (void *)0; + } +#endif + } + return (swig_module_info *) type_pointer; +} + +#if PY_MAJOR_VERSION < 2 +/* PyModule_AddObject function was introduced in Python 2.0. The following function + is copied out of Python/modsupport.c in python version 2.3.4 */ +SWIGINTERN int +PyModule_AddObject(PyObject *m, char *name, PyObject *o) +{ + PyObject *dict; + if (!PyModule_Check(m)) { + PyErr_SetString(PyExc_TypeError, + "PyModule_AddObject() needs module as first arg"); + return SWIG_ERROR; + } + if (!o) { + PyErr_SetString(PyExc_TypeError, + "PyModule_AddObject() needs non-NULL value"); + return SWIG_ERROR; + } + + dict = PyModule_GetDict(m); + if (dict == NULL) { + /* Internal error -- modules must have a dict! */ + PyErr_Format(PyExc_SystemError, "module '%s' has no __dict__", + PyModule_GetName(m)); + return SWIG_ERROR; + } + if (PyDict_SetItemString(dict, name, o)) + return SWIG_ERROR; + Py_DECREF(o); + return SWIG_OK; +} +#endif + +SWIGRUNTIME void +SWIG_Python_DestroyModule(void *vptr) +{ + swig_module_info *swig_module = (swig_module_info *) vptr; + swig_type_info **types = swig_module->types; + size_t i; + for (i =0; i < swig_module->size; ++i) { + swig_type_info *ty = types[i]; + if (ty->owndata) { + SwigPyClientData *data = (SwigPyClientData *) ty->clientdata; + if (data) SwigPyClientData_Del(data); + } + } + Py_DECREF(SWIG_This()); +} + +SWIGRUNTIME void +SWIG_Python_SetModule(swig_module_info *swig_module) { + static PyMethodDef swig_empty_runtime_method_table[] = { {NULL, NULL, 0, NULL} };/* Sentinel */ + +#if PY_VERSION_HEX >= 0x03000000 + /* Add a dummy module object into sys.modules */ + PyObject *module = PyImport_AddModule((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION); +#else + PyObject *module = Py_InitModule((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION, + swig_empty_runtime_method_table); +#endif + PyObject *pointer = PyCObject_FromVoidPtr((void *) swig_module, SWIG_Python_DestroyModule); + if (pointer && module) { + PyModule_AddObject(module, (char*)"type_pointer" SWIG_TYPE_TABLE_NAME, pointer); + } else { + Py_XDECREF(pointer); + } +} + +/* The python cached type query */ +SWIGRUNTIME PyObject * +SWIG_Python_TypeCache(void) { + static PyObject *SWIG_STATIC_POINTER(cache) = PyDict_New(); + return cache; +} + +SWIGRUNTIME swig_type_info * +SWIG_Python_TypeQuery(const char *type) +{ + PyObject *cache = SWIG_Python_TypeCache(); + PyObject *key = SWIG_Python_str_FromChar(type); + PyObject *obj = PyDict_GetItem(cache, key); + swig_type_info *descriptor; + if (obj) { + descriptor = (swig_type_info *) PyCObject_AsVoidPtr(obj); + } else { + swig_module_info *swig_module = SWIG_Python_GetModule(); + descriptor = SWIG_TypeQueryModule(swig_module, swig_module, type); + if (descriptor) { + obj = PyCObject_FromVoidPtr(descriptor, NULL); + PyDict_SetItem(cache, key, obj); + Py_DECREF(obj); + } + } + Py_DECREF(key); + return descriptor; +} + +/* + For backward compatibility only +*/ +#define SWIG_POINTER_EXCEPTION 0 +#define SWIG_arg_fail(arg) SWIG_Python_ArgFail(arg) +#define SWIG_MustGetPtr(p, type, argnum, flags) SWIG_Python_MustGetPtr(p, type, argnum, flags) + +SWIGRUNTIME int +SWIG_Python_AddErrMesg(const char* mesg, int infront) +{ + if (PyErr_Occurred()) { + PyObject *type = 0; + PyObject *value = 0; + PyObject *traceback = 0; + PyErr_Fetch(&type, &value, &traceback); + if (value) { + PyObject *old_str = PyObject_Str(value); + Py_XINCREF(type); + PyErr_Clear(); + if (infront) { + PyErr_Format(type, "%s %s", mesg, SWIG_Python_str_AsChar(old_str)); + } else { + PyErr_Format(type, "%s %s", SWIG_Python_str_AsChar(old_str), mesg); + } + Py_DECREF(old_str); + } + return 1; + } else { + return 0; + } +} + +SWIGRUNTIME int +SWIG_Python_ArgFail(int argnum) +{ + if (PyErr_Occurred()) { + /* add information about failing argument */ + char mesg[256]; + PyOS_snprintf(mesg, sizeof(mesg), "argument number %d:", argnum); + return SWIG_Python_AddErrMesg(mesg, 1); + } else { + return 0; + } +} + +SWIGRUNTIMEINLINE const char * +SwigPyObject_GetDesc(PyObject *self) +{ + SwigPyObject *v = (SwigPyObject *)self; + swig_type_info *ty = v ? v->ty : 0; + return ty ? ty->str : (char*)""; +} + +SWIGRUNTIME void +SWIG_Python_TypeError(const char *type, PyObject *obj) +{ + if (type) { +#if defined(SWIG_COBJECT_TYPES) + if (obj && SwigPyObject_Check(obj)) { + const char *otype = (const char *) SwigPyObject_GetDesc(obj); + if (otype) { + PyErr_Format(PyExc_TypeError, "a '%s' is expected, 'SwigPyObject(%s)' is received", + type, otype); + return; + } + } else +#endif + { + const char *otype = (obj ? obj->ob_type->tp_name : 0); + if (otype) { + PyObject *str = PyObject_Str(obj); + const char *cstr = str ? SWIG_Python_str_AsChar(str) : 0; + if (cstr) { + PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s(%s)' is received", + type, otype, cstr); + } else { + PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s' is received", + type, otype); + } + Py_XDECREF(str); + return; + } + } + PyErr_Format(PyExc_TypeError, "a '%s' is expected", type); + } else { + PyErr_Format(PyExc_TypeError, "unexpected type is received"); + } +} + + +/* Convert a pointer value, signal an exception on a type mismatch */ +SWIGRUNTIME void * +SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int argnum, int flags) { + void *result; + if (SWIG_Python_ConvertPtr(obj, &result, ty, flags) == -1) { + PyErr_Clear(); + if (flags & SWIG_POINTER_EXCEPTION) { + SWIG_Python_TypeError(SWIG_TypePrettyName(ty), obj); + SWIG_Python_ArgFail(argnum); + } + } + return result; +} + + +#ifdef __cplusplus +#if 0 +{ /* cc-mode */ +#endif +} +#endif + + + +#define SWIG_exception_fail(code, msg) do { SWIG_Error(code, msg); SWIG_fail; } while(0) + +#define SWIG_contract_assert(expr, msg) if (!(expr)) { SWIG_Error(SWIG_RuntimeError, msg); SWIG_fail; } else + + + +/* -------- TYPES TABLE (BEGIN) -------- */ + +#define SWIGTYPE_p_FILE swig_types[0] +#define SWIGTYPE_p_char swig_types[1] +#define SWIGTYPE_p_f_p_void_int_p_struct_ub_result__void swig_types[2] +#define SWIGTYPE_p_int swig_types[3] +#define SWIGTYPE_p_p_char swig_types[4] +#define SWIGTYPE_p_p_ub_result swig_types[5] +#define SWIGTYPE_p_ub_ctx swig_types[6] +#define SWIGTYPE_p_ub_result swig_types[7] +#define SWIGTYPE_p_void swig_types[8] +static swig_type_info *swig_types[10]; +static swig_module_info swig_module = {swig_types, 9, 0, 0, 0, 0}; +#define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name) +#define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name) + +/* -------- TYPES TABLE (END) -------- */ + +#if (PY_VERSION_HEX <= 0x02000000) +# if !defined(SWIG_PYTHON_CLASSIC) +# error "This python version requires swig to be run with the '-classic' option" +# endif +#endif + +/*----------------------------------------------- + @(target):= _unbound.so + ------------------------------------------------*/ +#if PY_VERSION_HEX >= 0x03000000 +# define SWIG_init PyInit__unbound + +#else +# define SWIG_init init_unbound + +#endif +#define SWIG_name "_unbound" + +#define SWIGVERSION 0x010338 +#define SWIG_VERSION SWIGVERSION + + +#define SWIG_as_voidptr(a) (void *)((const void *)(a)) +#define SWIG_as_voidptrptr(a) ((void)SWIG_as_voidptr(*a),(void**)(a)) + + + #include + #include + #include + #include + #include "libunbound/unbound.h" + + + 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, + }; + + + #define SWIG_From_long PyInt_FromLong + + +SWIGINTERNINLINE PyObject * +SWIG_From_int (int value) +{ + return SWIG_From_long (value); +} + + + void ub_resolve_free_dbg (struct ub_result* r) { + printf("******** UB_RESOLVE free 0x%lX ************\n", (long unsigned int)r); + ub_resolve_free(r); + } + + + 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 + }; + + +SWIGINTERN swig_type_info* +SWIG_pchar_descriptor(void) +{ + static int init = 0; + static swig_type_info* info = 0; + if (!init) { + info = SWIG_TypeQuery("_p_char"); + init = 1; + } + return info; +} + + +SWIGINTERN int +SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc) +{ +#if PY_VERSION_HEX>=0x03000000 + if (PyUnicode_Check(obj)) +#else + if (PyString_Check(obj)) +#endif + { + char *cstr; Py_ssize_t len; +#if PY_VERSION_HEX>=0x03000000 + obj = PyUnicode_AsUTF8String(obj); + PyBytes_AsStringAndSize(obj, &cstr, &len); +#else + PyString_AsStringAndSize(obj, &cstr, &len); +#endif + if (cptr) { + if (alloc) { + /* + In python the user should not be able to modify the inner + string representation. To warranty that, if you define + SWIG_PYTHON_SAFE_CSTRINGS, a new/copy of the python string + buffer is always returned. + + The default behavior is just to return the pointer value, + so, be careful. + */ +#if defined(SWIG_PYTHON_SAFE_CSTRINGS) + if (*alloc != SWIG_OLDOBJ) +#else + if (*alloc == SWIG_NEWOBJ) +#endif + { + *cptr = (char *)memcpy((char *)malloc((len + 1)*sizeof(char)), cstr, sizeof(char)*(len + 1)); + *alloc = SWIG_NEWOBJ; + } + else { + *cptr = cstr; + *alloc = SWIG_OLDOBJ; + } + } else { + *cptr = SWIG_Python_str_AsChar(obj); + } + } + if (psize) *psize = len + 1; + return SWIG_OK; + } else { + swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); + if (pchar_descriptor) { + void* vptr = 0; + if (SWIG_ConvertPtr(obj, &vptr, pchar_descriptor, 0) == SWIG_OK) { + if (cptr) *cptr = (char *) vptr; + if (psize) *psize = vptr ? (strlen((char *)vptr) + 1) : 0; + if (alloc) *alloc = SWIG_OLDOBJ; + return SWIG_OK; + } + } + } + return SWIG_TypeError; +} + + + + + +SWIGINTERNINLINE PyObject * +SWIG_FromCharPtrAndSize(const char* carray, size_t size) +{ + if (carray) { + if (size > INT_MAX) { + swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); + return pchar_descriptor ? + SWIG_NewPointerObj((char *)(carray), pchar_descriptor, 0) : SWIG_Py_Void(); + } else { +#if PY_VERSION_HEX >= 0x03000000 + return PyUnicode_FromStringAndSize(carray, (int)(size)); +#else + return PyString_FromStringAndSize(carray, (int)(size)); +#endif + } + } else { + return SWIG_Py_Void(); + } +} + + +SWIGINTERNINLINE PyObject * +SWIG_FromCharPtr(const char *cptr) +{ + return SWIG_FromCharPtrAndSize(cptr, (cptr ? strlen(cptr) : 0)); +} + + +#include +#if !defined(SWIG_NO_LLONG_MAX) +# if !defined(LLONG_MAX) && defined(__GNUC__) && defined (__LONG_LONG_MAX__) +# define LLONG_MAX __LONG_LONG_MAX__ +# define LLONG_MIN (-LLONG_MAX - 1LL) +# define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL) +# endif +#endif + + +SWIGINTERN int +SWIG_AsVal_double (PyObject *obj, double *val) +{ + int res = SWIG_TypeError; + if (PyFloat_Check(obj)) { + if (val) *val = PyFloat_AsDouble(obj); + return SWIG_OK; + } else if (PyInt_Check(obj)) { + if (val) *val = PyInt_AsLong(obj); + return SWIG_OK; + } else if (PyLong_Check(obj)) { + double v = PyLong_AsDouble(obj); + if (!PyErr_Occurred()) { + if (val) *val = v; + return SWIG_OK; + } else { + PyErr_Clear(); + } + } +#ifdef SWIG_PYTHON_CAST_MODE + { + int dispatch = 0; + double d = PyFloat_AsDouble(obj); + if (!PyErr_Occurred()) { + if (val) *val = d; + return SWIG_AddCast(SWIG_OK); + } else { + PyErr_Clear(); + } + if (!dispatch) { + long v = PyLong_AsLong(obj); + if (!PyErr_Occurred()) { + if (val) *val = v; + return SWIG_AddCast(SWIG_AddCast(SWIG_OK)); + } else { + PyErr_Clear(); + } + } + } +#endif + return res; +} + + +#include + + +#include + + +SWIGINTERNINLINE int +SWIG_CanCastAsInteger(double *d, double min, double max) { + double x = *d; + if ((min <= x && x <= max)) { + double fx = floor(x); + double cx = ceil(x); + double rd = ((x - fx) < 0.5) ? fx : cx; /* simple rint */ + if ((errno == EDOM) || (errno == ERANGE)) { + errno = 0; + } else { + double summ, reps, diff; + if (rd < x) { + diff = x - rd; + } else if (rd > x) { + diff = rd - x; + } else { + return 1; + } + summ = rd + x; + reps = diff/summ; + if (reps < 8*DBL_EPSILON) { + *d = rd; + return 1; + } + } + } + return 0; +} + + +SWIGINTERN int +SWIG_AsVal_long (PyObject *obj, long* val) +{ + if (PyInt_Check(obj)) { + if (val) *val = PyInt_AsLong(obj); + return SWIG_OK; + } else if (PyLong_Check(obj)) { + long v = PyLong_AsLong(obj); + if (!PyErr_Occurred()) { + if (val) *val = v; + return SWIG_OK; + } else { + PyErr_Clear(); + } + } +#ifdef SWIG_PYTHON_CAST_MODE + { + int dispatch = 0; + long v = PyInt_AsLong(obj); + if (!PyErr_Occurred()) { + if (val) *val = v; + return SWIG_AddCast(SWIG_OK); + } else { + PyErr_Clear(); + } + if (!dispatch) { + double d; + int res = SWIG_AddCast(SWIG_AsVal_double (obj,&d)); + if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, LONG_MIN, LONG_MAX)) { + if (val) *val = (long)(d); + return res; + } + } + } +#endif + return SWIG_TypeError; +} + + +SWIGINTERN int +SWIG_AsVal_int (PyObject * obj, int *val) +{ + long v; + int res = SWIG_AsVal_long (obj, &v); + if (SWIG_IsOK(res)) { + if ((v < INT_MIN || v > INT_MAX)) { + return SWIG_OverflowError; + } else { + if (val) *val = (int)(v); + } + } + return res; +} + +SWIGINTERN PyObject *ub_result__ub_result_data(struct ub_result *self,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;idata[i],result->len[i])); + + return list; + } + + //SWIG will see the ub_ctx as a class + struct ub_ctx { + }; + + +SWIGINTERN int +SWIG_AsValFilePtr(PyObject *obj, FILE **val) { + static swig_type_info* desc = 0; + void *vptr = 0; + if (!desc) desc = SWIG_TypeQuery("FILE *"); + if ((SWIG_ConvertPtr(obj, &vptr, desc, 0)) == SWIG_OK) { + if (val) *val = (FILE *)vptr; + return SWIG_OK; + } +#if PY_VERSION_HEX < 0x03000000 + if (PyFile_Check(obj)) { + if (val) *val = PyFile_AsFile(obj); + return SWIG_OK; + } +#endif + return SWIG_TypeError; +} + + + 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; + } + + +#ifdef __cplusplus +extern "C" { +#endif +SWIGINTERN PyObject *_wrap_ub_ctx_free_dbg(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_ctx *arg1 = (struct ub_ctx *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:ub_ctx_free_dbg",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_ctx, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_ctx_free_dbg" "', argument " "1"" of type '" "struct ub_ctx *""'"); + } + arg1 = (struct ub_ctx *)(argp1); + ub_ctx_free_dbg(arg1); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_resolve_free_dbg(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_result *arg1 = (struct ub_result *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:ub_resolve_free_dbg",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_result, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_resolve_free_dbg" "', argument " "1"" of type '" "struct ub_result *""'"); + } + arg1 = (struct ub_result *)(argp1); + ub_resolve_free_dbg(arg1); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_result_qname_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_result *arg1 = (struct ub_result *) 0 ; + char *arg2 = (char *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + int res2 ; + char *buf2 = 0 ; + int alloc2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"OO:ub_result_qname_set",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_result, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_result_qname_set" "', argument " "1"" of type '" "struct ub_result *""'"); + } + arg1 = (struct ub_result *)(argp1); + res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ub_result_qname_set" "', argument " "2"" of type '" "char *""'"); + } + arg2 = (char *)(buf2); + if (arg1->qname) free((char*)arg1->qname); + if (arg2) { + size_t size = strlen((const char *)(arg2)) + 1; + arg1->qname = (char *)(char *)memcpy((char *)malloc((size)*sizeof(char)), (const char *)(arg2), sizeof(char)*(size)); + } else { + arg1->qname = 0; + } + resultobj = SWIG_Py_Void(); + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return resultobj; +fail: + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_result_qname_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_result *arg1 = (struct ub_result *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + char *result = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:ub_result_qname_get",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_result, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_result_qname_get" "', argument " "1"" of type '" "struct ub_result *""'"); + } + arg1 = (struct ub_result *)(argp1); + result = (char *) ((arg1)->qname); + resultobj = SWIG_FromCharPtr((const char *)result); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_result_qtype_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_result *arg1 = (struct ub_result *) 0 ; + int arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + int val2 ; + int ecode2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"OO:ub_result_qtype_set",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_result, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_result_qtype_set" "', argument " "1"" of type '" "struct ub_result *""'"); + } + arg1 = (struct ub_result *)(argp1); + ecode2 = SWIG_AsVal_int(obj1, &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ub_result_qtype_set" "', argument " "2"" of type '" "int""'"); + } + arg2 = (int)(val2); + if (arg1) (arg1)->qtype = arg2; + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_result_qtype_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_result *arg1 = (struct ub_result *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + int result; + + if (!PyArg_ParseTuple(args,(char *)"O:ub_result_qtype_get",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_result, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_result_qtype_get" "', argument " "1"" of type '" "struct ub_result *""'"); + } + arg1 = (struct ub_result *)(argp1); + result = (int) ((arg1)->qtype); + resultobj = SWIG_From_int((int)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_result_qclass_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_result *arg1 = (struct ub_result *) 0 ; + int arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + int val2 ; + int ecode2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"OO:ub_result_qclass_set",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_result, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_result_qclass_set" "', argument " "1"" of type '" "struct ub_result *""'"); + } + arg1 = (struct ub_result *)(argp1); + ecode2 = SWIG_AsVal_int(obj1, &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ub_result_qclass_set" "', argument " "2"" of type '" "int""'"); + } + arg2 = (int)(val2); + if (arg1) (arg1)->qclass = arg2; + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_result_qclass_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_result *arg1 = (struct ub_result *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + int result; + + if (!PyArg_ParseTuple(args,(char *)"O:ub_result_qclass_get",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_result, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_result_qclass_get" "', argument " "1"" of type '" "struct ub_result *""'"); + } + arg1 = (struct ub_result *)(argp1); + result = (int) ((arg1)->qclass); + resultobj = SWIG_From_int((int)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_result__data_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_result *arg1 = (struct ub_result *) 0 ; + char **arg2 = (char **) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + void *argp2 = 0 ; + int res2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"OO:ub_result__data_set",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_result, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_result__data_set" "', argument " "1"" of type '" "struct ub_result *""'"); + } + arg1 = (struct ub_result *)(argp1); + res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_p_char, 0 | 0 ); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ub_result__data_set" "', argument " "2"" of type '" "char **""'"); + } + arg2 = (char **)(argp2); + if (arg1) (arg1)->data = arg2; + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_result__data_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_result *arg1 = (struct ub_result *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + char **result = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:ub_result__data_get",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_result, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_result__data_get" "', argument " "1"" of type '" "struct ub_result *""'"); + } + arg1 = (struct ub_result *)(argp1); + result = (char **) ((arg1)->data); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_p_char, 0 | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_result_len_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_result *arg1 = (struct ub_result *) 0 ; + int *arg2 = (int *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + void *argp2 = 0 ; + int res2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"OO:ub_result_len_set",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_result, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_result_len_set" "', argument " "1"" of type '" "struct ub_result *""'"); + } + arg1 = (struct ub_result *)(argp1); + res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_int, SWIG_POINTER_DISOWN | 0 ); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ub_result_len_set" "', argument " "2"" of type '" "int *""'"); + } + arg2 = (int *)(argp2); + if (arg1) (arg1)->len = arg2; + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_result_len_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_result *arg1 = (struct ub_result *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + int *result = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:ub_result_len_get",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_result, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_result_len_get" "', argument " "1"" of type '" "struct ub_result *""'"); + } + arg1 = (struct ub_result *)(argp1); + result = (int *) ((arg1)->len); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_int, 0 | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_result_canonname_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_result *arg1 = (struct ub_result *) 0 ; + char *arg2 = (char *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + int res2 ; + char *buf2 = 0 ; + int alloc2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"OO:ub_result_canonname_set",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_result, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_result_canonname_set" "', argument " "1"" of type '" "struct ub_result *""'"); + } + arg1 = (struct ub_result *)(argp1); + res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ub_result_canonname_set" "', argument " "2"" of type '" "char *""'"); + } + arg2 = (char *)(buf2); + if (arg1->canonname) free((char*)arg1->canonname); + if (arg2) { + size_t size = strlen((const char *)(arg2)) + 1; + arg1->canonname = (char *)(char *)memcpy((char *)malloc((size)*sizeof(char)), (const char *)(arg2), sizeof(char)*(size)); + } else { + arg1->canonname = 0; + } + resultobj = SWIG_Py_Void(); + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return resultobj; +fail: + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_result_canonname_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_result *arg1 = (struct ub_result *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + char *result = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:ub_result_canonname_get",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_result, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_result_canonname_get" "', argument " "1"" of type '" "struct ub_result *""'"); + } + arg1 = (struct ub_result *)(argp1); + result = (char *) ((arg1)->canonname); + resultobj = SWIG_FromCharPtr((const char *)result); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_result_rcode_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_result *arg1 = (struct ub_result *) 0 ; + int arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + int val2 ; + int ecode2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"OO:ub_result_rcode_set",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_result, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_result_rcode_set" "', argument " "1"" of type '" "struct ub_result *""'"); + } + arg1 = (struct ub_result *)(argp1); + ecode2 = SWIG_AsVal_int(obj1, &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ub_result_rcode_set" "', argument " "2"" of type '" "int""'"); + } + arg2 = (int)(val2); + if (arg1) (arg1)->rcode = arg2; + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_result_rcode_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_result *arg1 = (struct ub_result *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + int result; + + if (!PyArg_ParseTuple(args,(char *)"O:ub_result_rcode_get",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_result, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_result_rcode_get" "', argument " "1"" of type '" "struct ub_result *""'"); + } + arg1 = (struct ub_result *)(argp1); + result = (int) ((arg1)->rcode); + resultobj = SWIG_From_int((int)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_result_answer_packet_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_result *arg1 = (struct ub_result *) 0 ; + void *arg2 = (void *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + int res2 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"OO:ub_result_answer_packet_set",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_result, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_result_answer_packet_set" "', argument " "1"" of type '" "struct ub_result *""'"); + } + arg1 = (struct ub_result *)(argp1); + res2 = SWIG_ConvertPtr(obj1,SWIG_as_voidptrptr(&arg2), 0, SWIG_POINTER_DISOWN); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ub_result_answer_packet_set" "', argument " "2"" of type '" "void *""'"); + } + if (arg1) (arg1)->answer_packet = arg2; + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_result_answer_packet_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_result *arg1 = (struct ub_result *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + void *result = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:ub_result_answer_packet_get",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_result, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_result_answer_packet_get" "', argument " "1"" of type '" "struct ub_result *""'"); + } + arg1 = (struct ub_result *)(argp1); + result = (void *) ((arg1)->answer_packet); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_void, 0 | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_result_answer_len_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_result *arg1 = (struct ub_result *) 0 ; + int arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + int val2 ; + int ecode2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"OO:ub_result_answer_len_set",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_result, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_result_answer_len_set" "', argument " "1"" of type '" "struct ub_result *""'"); + } + arg1 = (struct ub_result *)(argp1); + ecode2 = SWIG_AsVal_int(obj1, &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ub_result_answer_len_set" "', argument " "2"" of type '" "int""'"); + } + arg2 = (int)(val2); + if (arg1) (arg1)->answer_len = arg2; + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_result_answer_len_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_result *arg1 = (struct ub_result *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + int result; + + if (!PyArg_ParseTuple(args,(char *)"O:ub_result_answer_len_get",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_result, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_result_answer_len_get" "', argument " "1"" of type '" "struct ub_result *""'"); + } + arg1 = (struct ub_result *)(argp1); + result = (int) ((arg1)->answer_len); + resultobj = SWIG_From_int((int)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_result_havedata_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_result *arg1 = (struct ub_result *) 0 ; + int arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + int val2 ; + int ecode2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"OO:ub_result_havedata_set",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_result, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_result_havedata_set" "', argument " "1"" of type '" "struct ub_result *""'"); + } + arg1 = (struct ub_result *)(argp1); + ecode2 = SWIG_AsVal_int(obj1, &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ub_result_havedata_set" "', argument " "2"" of type '" "int""'"); + } + arg2 = (int)(val2); + if (arg1) (arg1)->havedata = arg2; + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_result_havedata_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_result *arg1 = (struct ub_result *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + int result; + + if (!PyArg_ParseTuple(args,(char *)"O:ub_result_havedata_get",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_result, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_result_havedata_get" "', argument " "1"" of type '" "struct ub_result *""'"); + } + arg1 = (struct ub_result *)(argp1); + result = (int) ((arg1)->havedata); + resultobj = SWIG_From_int((int)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_result_nxdomain_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_result *arg1 = (struct ub_result *) 0 ; + int arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + int val2 ; + int ecode2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"OO:ub_result_nxdomain_set",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_result, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_result_nxdomain_set" "', argument " "1"" of type '" "struct ub_result *""'"); + } + arg1 = (struct ub_result *)(argp1); + ecode2 = SWIG_AsVal_int(obj1, &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ub_result_nxdomain_set" "', argument " "2"" of type '" "int""'"); + } + arg2 = (int)(val2); + if (arg1) (arg1)->nxdomain = arg2; + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_result_nxdomain_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_result *arg1 = (struct ub_result *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + int result; + + if (!PyArg_ParseTuple(args,(char *)"O:ub_result_nxdomain_get",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_result, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_result_nxdomain_get" "', argument " "1"" of type '" "struct ub_result *""'"); + } + arg1 = (struct ub_result *)(argp1); + result = (int) ((arg1)->nxdomain); + resultobj = SWIG_From_int((int)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_result_secure_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_result *arg1 = (struct ub_result *) 0 ; + int arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + int val2 ; + int ecode2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"OO:ub_result_secure_set",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_result, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_result_secure_set" "', argument " "1"" of type '" "struct ub_result *""'"); + } + arg1 = (struct ub_result *)(argp1); + ecode2 = SWIG_AsVal_int(obj1, &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ub_result_secure_set" "', argument " "2"" of type '" "int""'"); + } + arg2 = (int)(val2); + if (arg1) (arg1)->secure = arg2; + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_result_secure_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_result *arg1 = (struct ub_result *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + int result; + + if (!PyArg_ParseTuple(args,(char *)"O:ub_result_secure_get",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_result, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_result_secure_get" "', argument " "1"" of type '" "struct ub_result *""'"); + } + arg1 = (struct ub_result *)(argp1); + result = (int) ((arg1)->secure); + resultobj = SWIG_From_int((int)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_result_bogus_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_result *arg1 = (struct ub_result *) 0 ; + int arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + int val2 ; + int ecode2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"OO:ub_result_bogus_set",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_result, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_result_bogus_set" "', argument " "1"" of type '" "struct ub_result *""'"); + } + arg1 = (struct ub_result *)(argp1); + ecode2 = SWIG_AsVal_int(obj1, &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ub_result_bogus_set" "', argument " "2"" of type '" "int""'"); + } + arg2 = (int)(val2); + if (arg1) (arg1)->bogus = arg2; + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_result_bogus_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_result *arg1 = (struct ub_result *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + int result; + + if (!PyArg_ParseTuple(args,(char *)"O:ub_result_bogus_get",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_result, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_result_bogus_get" "', argument " "1"" of type '" "struct ub_result *""'"); + } + arg1 = (struct ub_result *)(argp1); + result = (int) ((arg1)->bogus); + resultobj = SWIG_From_int((int)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_result__ub_result_data(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_result *arg1 = (struct ub_result *) 0 ; + struct ub_result *arg2 = (struct ub_result *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + void *argp2 = 0 ; + int res2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + PyObject *result = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"OO:ub_result__ub_result_data",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_result, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_result__ub_result_data" "', argument " "1"" of type '" "struct ub_result *""'"); + } + arg1 = (struct ub_result *)(argp1); + res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_ub_result, 0 | 0 ); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ub_result__ub_result_data" "', argument " "2"" of type '" "struct ub_result *""'"); + } + arg2 = (struct ub_result *)(argp2); + result = (PyObject *)ub_result__ub_result_data(arg1,arg2); + resultobj = result; + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *ub_result_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!PyArg_ParseTuple(args,(char*)"O:swigregister", &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_ub_result, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *_wrap_ub_ctx_create(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_ctx *result = 0 ; + + if (!PyArg_ParseTuple(args,(char *)":ub_ctx_create")) SWIG_fail; + result = (struct ub_ctx *)ub_ctx_create(); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ub_ctx, SWIG_POINTER_OWN | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap__ub_ctx_delete(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_ctx *arg1 = (struct ub_ctx *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:_ub_ctx_delete",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_ctx, SWIG_POINTER_DISOWN | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "_ub_ctx_delete" "', argument " "1"" of type '" "struct ub_ctx *""'"); + } + arg1 = (struct ub_ctx *)(argp1); + ub_ctx_delete(arg1); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_ctx_set_option(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_ctx *arg1 = (struct ub_ctx *) 0 ; + char *arg2 = (char *) 0 ; + char *arg3 = (char *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + int res2 ; + char *buf2 = 0 ; + int alloc2 = 0 ; + int res3 ; + char *buf3 = 0 ; + int alloc3 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + PyObject * obj2 = 0 ; + int result; + + if (!PyArg_ParseTuple(args,(char *)"OOO:ub_ctx_set_option",&obj0,&obj1,&obj2)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_ctx, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_ctx_set_option" "', argument " "1"" of type '" "struct ub_ctx *""'"); + } + arg1 = (struct ub_ctx *)(argp1); + res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ub_ctx_set_option" "', argument " "2"" of type '" "char *""'"); + } + arg2 = (char *)(buf2); + res3 = SWIG_AsCharPtrAndSize(obj2, &buf3, NULL, &alloc3); + if (!SWIG_IsOK(res3)) { + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "ub_ctx_set_option" "', argument " "3"" of type '" "char *""'"); + } + arg3 = (char *)(buf3); + result = (int)ub_ctx_set_option(arg1,arg2,arg3); + resultobj = SWIG_From_int((int)(result)); + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + if (alloc3 == SWIG_NEWOBJ) free((char*)buf3); + return resultobj; +fail: + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + if (alloc3 == SWIG_NEWOBJ) free((char*)buf3); + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_ctx_config(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_ctx *arg1 = (struct ub_ctx *) 0 ; + char *arg2 = (char *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + int res2 ; + char *buf2 = 0 ; + int alloc2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + int result; + + if (!PyArg_ParseTuple(args,(char *)"OO:ub_ctx_config",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_ctx, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_ctx_config" "', argument " "1"" of type '" "struct ub_ctx *""'"); + } + arg1 = (struct ub_ctx *)(argp1); + res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ub_ctx_config" "', argument " "2"" of type '" "char *""'"); + } + arg2 = (char *)(buf2); + result = (int)ub_ctx_config(arg1,arg2); + resultobj = SWIG_From_int((int)(result)); + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return resultobj; +fail: + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_ctx_set_fwd(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_ctx *arg1 = (struct ub_ctx *) 0 ; + char *arg2 = (char *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + int res2 ; + char *buf2 = 0 ; + int alloc2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + int result; + + if (!PyArg_ParseTuple(args,(char *)"OO:ub_ctx_set_fwd",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_ctx, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_ctx_set_fwd" "', argument " "1"" of type '" "struct ub_ctx *""'"); + } + arg1 = (struct ub_ctx *)(argp1); + res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ub_ctx_set_fwd" "', argument " "2"" of type '" "char *""'"); + } + arg2 = (char *)(buf2); + result = (int)ub_ctx_set_fwd(arg1,arg2); + resultobj = SWIG_From_int((int)(result)); + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return resultobj; +fail: + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_ctx_resolvconf(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_ctx *arg1 = (struct ub_ctx *) 0 ; + char *arg2 = (char *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + int res2 ; + char *buf2 = 0 ; + int alloc2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + int result; + + if (!PyArg_ParseTuple(args,(char *)"OO:ub_ctx_resolvconf",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_ctx, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_ctx_resolvconf" "', argument " "1"" of type '" "struct ub_ctx *""'"); + } + arg1 = (struct ub_ctx *)(argp1); + res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ub_ctx_resolvconf" "', argument " "2"" of type '" "char *""'"); + } + arg2 = (char *)(buf2); + result = (int)ub_ctx_resolvconf(arg1,arg2); + resultobj = SWIG_From_int((int)(result)); + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return resultobj; +fail: + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_ctx_hosts(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_ctx *arg1 = (struct ub_ctx *) 0 ; + char *arg2 = (char *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + int res2 ; + char *buf2 = 0 ; + int alloc2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + int result; + + if (!PyArg_ParseTuple(args,(char *)"OO:ub_ctx_hosts",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_ctx, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_ctx_hosts" "', argument " "1"" of type '" "struct ub_ctx *""'"); + } + arg1 = (struct ub_ctx *)(argp1); + res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ub_ctx_hosts" "', argument " "2"" of type '" "char *""'"); + } + arg2 = (char *)(buf2); + result = (int)ub_ctx_hosts(arg1,arg2); + resultobj = SWIG_From_int((int)(result)); + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return resultobj; +fail: + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_ctx_add_ta(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_ctx *arg1 = (struct ub_ctx *) 0 ; + char *arg2 = (char *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + int res2 ; + char *buf2 = 0 ; + int alloc2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + int result; + + if (!PyArg_ParseTuple(args,(char *)"OO:ub_ctx_add_ta",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_ctx, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_ctx_add_ta" "', argument " "1"" of type '" "struct ub_ctx *""'"); + } + arg1 = (struct ub_ctx *)(argp1); + res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ub_ctx_add_ta" "', argument " "2"" of type '" "char *""'"); + } + arg2 = (char *)(buf2); + result = (int)ub_ctx_add_ta(arg1,arg2); + resultobj = SWIG_From_int((int)(result)); + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return resultobj; +fail: + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_ctx_add_ta_file(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_ctx *arg1 = (struct ub_ctx *) 0 ; + char *arg2 = (char *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + int res2 ; + char *buf2 = 0 ; + int alloc2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + int result; + + if (!PyArg_ParseTuple(args,(char *)"OO:ub_ctx_add_ta_file",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_ctx, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_ctx_add_ta_file" "', argument " "1"" of type '" "struct ub_ctx *""'"); + } + arg1 = (struct ub_ctx *)(argp1); + res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ub_ctx_add_ta_file" "', argument " "2"" of type '" "char *""'"); + } + arg2 = (char *)(buf2); + result = (int)ub_ctx_add_ta_file(arg1,arg2); + resultobj = SWIG_From_int((int)(result)); + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return resultobj; +fail: + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_ctx_trustedkeys(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_ctx *arg1 = (struct ub_ctx *) 0 ; + char *arg2 = (char *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + int res2 ; + char *buf2 = 0 ; + int alloc2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + int result; + + if (!PyArg_ParseTuple(args,(char *)"OO:ub_ctx_trustedkeys",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_ctx, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_ctx_trustedkeys" "', argument " "1"" of type '" "struct ub_ctx *""'"); + } + arg1 = (struct ub_ctx *)(argp1); + res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ub_ctx_trustedkeys" "', argument " "2"" of type '" "char *""'"); + } + arg2 = (char *)(buf2); + result = (int)ub_ctx_trustedkeys(arg1,arg2); + resultobj = SWIG_From_int((int)(result)); + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return resultobj; +fail: + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_ctx_debugout__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_ctx *arg1 = (struct ub_ctx *) 0 ; + void *arg2 = (void *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + int res2 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + int result; + + if (!PyArg_ParseTuple(args,(char *)"OO:ub_ctx_debugout",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_ctx, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_ctx_debugout" "', argument " "1"" of type '" "struct ub_ctx *""'"); + } + arg1 = (struct ub_ctx *)(argp1); + res2 = SWIG_ConvertPtr(obj1,SWIG_as_voidptrptr(&arg2), 0, 0); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ub_ctx_debugout" "', argument " "2"" of type '" "void *""'"); + } + result = (int)ub_ctx_debugout(arg1,arg2); + resultobj = SWIG_From_int((int)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_ctx_debuglevel(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_ctx *arg1 = (struct ub_ctx *) 0 ; + int arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + int val2 ; + int ecode2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + int result; + + if (!PyArg_ParseTuple(args,(char *)"OO:ub_ctx_debuglevel",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_ctx, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_ctx_debuglevel" "', argument " "1"" of type '" "struct ub_ctx *""'"); + } + arg1 = (struct ub_ctx *)(argp1); + ecode2 = SWIG_AsVal_int(obj1, &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ub_ctx_debuglevel" "', argument " "2"" of type '" "int""'"); + } + arg2 = (int)(val2); + result = (int)ub_ctx_debuglevel(arg1,arg2); + resultobj = SWIG_From_int((int)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_ctx_async(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_ctx *arg1 = (struct ub_ctx *) 0 ; + int arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + int val2 ; + int ecode2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + int result; + + if (!PyArg_ParseTuple(args,(char *)"OO:ub_ctx_async",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_ctx, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_ctx_async" "', argument " "1"" of type '" "struct ub_ctx *""'"); + } + arg1 = (struct ub_ctx *)(argp1); + ecode2 = SWIG_AsVal_int(obj1, &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ub_ctx_async" "', argument " "2"" of type '" "int""'"); + } + arg2 = (int)(val2); + result = (int)ub_ctx_async(arg1,arg2); + resultobj = SWIG_From_int((int)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_poll(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_ctx *arg1 = (struct ub_ctx *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + int result; + + if (!PyArg_ParseTuple(args,(char *)"O:ub_poll",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_ctx, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_poll" "', argument " "1"" of type '" "struct ub_ctx *""'"); + } + arg1 = (struct ub_ctx *)(argp1); + result = (int)ub_poll(arg1); + resultobj = SWIG_From_int((int)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_wait(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_ctx *arg1 = (struct ub_ctx *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + int result; + + if (!PyArg_ParseTuple(args,(char *)"O:ub_wait",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_ctx, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_wait" "', argument " "1"" of type '" "struct ub_ctx *""'"); + } + arg1 = (struct ub_ctx *)(argp1); + result = (int)ub_wait(arg1); + resultobj = SWIG_From_int((int)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_fd(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_ctx *arg1 = (struct ub_ctx *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + int result; + + if (!PyArg_ParseTuple(args,(char *)"O:ub_fd",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_ctx, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_fd" "', argument " "1"" of type '" "struct ub_ctx *""'"); + } + arg1 = (struct ub_ctx *)(argp1); + result = (int)ub_fd(arg1); + resultobj = SWIG_From_int((int)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_process(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_ctx *arg1 = (struct ub_ctx *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + int result; + + if (!PyArg_ParseTuple(args,(char *)"O:ub_process",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_ctx, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_process" "', argument " "1"" of type '" "struct ub_ctx *""'"); + } + arg1 = (struct ub_ctx *)(argp1); + result = (int)ub_process(arg1); + resultobj = SWIG_From_int((int)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_resolve(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_ctx *arg1 = (struct ub_ctx *) 0 ; + char *arg2 = (char *) 0 ; + int arg3 ; + int arg4 ; + struct ub_result **arg5 = (struct ub_result **) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + int res2 ; + char *buf2 = 0 ; + int alloc2 = 0 ; + int val3 ; + int ecode3 = 0 ; + int val4 ; + int ecode4 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + PyObject * obj2 = 0 ; + PyObject * obj3 = 0 ; + int result; + + struct ub_result* newubr; + arg5 = &newubr; + if (!PyArg_ParseTuple(args,(char *)"OOOO:ub_resolve",&obj0,&obj1,&obj2,&obj3)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_ctx, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_resolve" "', argument " "1"" of type '" "struct ub_ctx *""'"); + } + arg1 = (struct ub_ctx *)(argp1); + res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ub_resolve" "', argument " "2"" of type '" "char *""'"); + } + arg2 = (char *)(buf2); + ecode3 = SWIG_AsVal_int(obj2, &val3); + if (!SWIG_IsOK(ecode3)) { + SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "ub_resolve" "', argument " "3"" of type '" "int""'"); + } + arg3 = (int)(val3); + ecode4 = SWIG_AsVal_int(obj3, &val4); + if (!SWIG_IsOK(ecode4)) { + SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "ub_resolve" "', argument " "4"" of type '" "int""'"); + } + arg4 = (int)(val4); + + //printf("resolve_start(%lX)\n",(long unsigned int)arg1); + Py_BEGIN_ALLOW_THREADS + result = (int)ub_resolve(arg1,arg2,arg3,arg4,arg5); + Py_END_ALLOW_THREADS + //printf("resolve_stop()\n"); + + resultobj = SWIG_From_int((int)(result)); + PyObject* tuple; + tuple = PyTuple_New(2); + PyTuple_SetItem(tuple, 0, resultobj); + 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); + } + resultobj = tuple; + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return resultobj; +fail: + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_resolve_async(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_ctx *arg1 = (struct ub_ctx *) 0 ; + char *arg2 = (char *) 0 ; + int arg3 ; + int arg4 ; + void *arg5 = (void *) 0 ; + ub_callback_t arg6 = (ub_callback_t) 0 ; + int *arg7 = (int *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + int res2 ; + char *buf2 = 0 ; + int alloc2 = 0 ; + int val3 ; + int ecode3 = 0 ; + int val4 ; + int ecode4 = 0 ; + int res5 ; + void *argp7 = 0 ; + int res7 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + PyObject * obj2 = 0 ; + PyObject * obj3 = 0 ; + PyObject * obj4 = 0 ; + PyObject * obj5 = 0 ; + PyObject * obj6 = 0 ; + int result; + + if (!PyArg_ParseTuple(args,(char *)"OOOOOOO:ub_resolve_async",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_ctx, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_resolve_async" "', argument " "1"" of type '" "struct ub_ctx *""'"); + } + arg1 = (struct ub_ctx *)(argp1); + res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ub_resolve_async" "', argument " "2"" of type '" "char *""'"); + } + arg2 = (char *)(buf2); + ecode3 = SWIG_AsVal_int(obj2, &val3); + if (!SWIG_IsOK(ecode3)) { + SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "ub_resolve_async" "', argument " "3"" of type '" "int""'"); + } + arg3 = (int)(val3); + ecode4 = SWIG_AsVal_int(obj3, &val4); + if (!SWIG_IsOK(ecode4)) { + SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "ub_resolve_async" "', argument " "4"" of type '" "int""'"); + } + arg4 = (int)(val4); + res5 = SWIG_ConvertPtr(obj4,SWIG_as_voidptrptr(&arg5), 0, 0); + if (!SWIG_IsOK(res5)) { + SWIG_exception_fail(SWIG_ArgError(res5), "in method '" "ub_resolve_async" "', argument " "5"" of type '" "void *""'"); + } + { + int res = SWIG_ConvertFunctionPtr(obj5, (void**)(&arg6), SWIGTYPE_p_f_p_void_int_p_struct_ub_result__void); + if (!SWIG_IsOK(res)) { + SWIG_exception_fail(SWIG_ArgError(res), "in method '" "ub_resolve_async" "', argument " "6"" of type '" "ub_callback_t""'"); + } + } + res7 = SWIG_ConvertPtr(obj6, &argp7,SWIGTYPE_p_int, 0 | 0 ); + if (!SWIG_IsOK(res7)) { + SWIG_exception_fail(SWIG_ArgError(res7), "in method '" "ub_resolve_async" "', argument " "7"" of type '" "int *""'"); + } + arg7 = (int *)(argp7); + result = (int)ub_resolve_async(arg1,arg2,arg3,arg4,arg5,arg6,arg7); + resultobj = SWIG_From_int((int)(result)); + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return resultobj; +fail: + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_cancel(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_ctx *arg1 = (struct ub_ctx *) 0 ; + int arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + int val2 ; + int ecode2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + int result; + + if (!PyArg_ParseTuple(args,(char *)"OO:ub_cancel",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_ctx, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_cancel" "', argument " "1"" of type '" "struct ub_ctx *""'"); + } + arg1 = (struct ub_ctx *)(argp1); + ecode2 = SWIG_AsVal_int(obj1, &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ub_cancel" "', argument " "2"" of type '" "int""'"); + } + arg2 = (int)(val2); + result = (int)ub_cancel(arg1,arg2); + resultobj = SWIG_From_int((int)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap__ub_resolve_free(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_result *arg1 = (struct ub_result *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:_ub_resolve_free",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_result, SWIG_POINTER_DISOWN | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "_ub_resolve_free" "', argument " "1"" of type '" "struct ub_result *""'"); + } + arg1 = (struct ub_result *)(argp1); + ub_resolve_free(arg1); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_strerror(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + int arg1 ; + int val1 ; + int ecode1 = 0 ; + PyObject * obj0 = 0 ; + char *result = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:ub_strerror",&obj0)) SWIG_fail; + ecode1 = SWIG_AsVal_int(obj0, &val1); + if (!SWIG_IsOK(ecode1)) { + SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "ub_strerror" "', argument " "1"" of type '" "int""'"); + } + arg1 = (int)(val1); + result = (char *)ub_strerror(arg1); + resultobj = SWIG_FromCharPtr((const char *)result); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_ctx_print_local_zones(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_ctx *arg1 = (struct ub_ctx *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + int result; + + if (!PyArg_ParseTuple(args,(char *)"O:ub_ctx_print_local_zones",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_ctx, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_ctx_print_local_zones" "', argument " "1"" of type '" "struct ub_ctx *""'"); + } + arg1 = (struct ub_ctx *)(argp1); + result = (int)ub_ctx_print_local_zones(arg1); + resultobj = SWIG_From_int((int)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_ctx_zone_add(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_ctx *arg1 = (struct ub_ctx *) 0 ; + char *arg2 = (char *) 0 ; + char *arg3 = (char *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + int res2 ; + char *buf2 = 0 ; + int alloc2 = 0 ; + int res3 ; + char *buf3 = 0 ; + int alloc3 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + PyObject * obj2 = 0 ; + int result; + + if (!PyArg_ParseTuple(args,(char *)"OOO:ub_ctx_zone_add",&obj0,&obj1,&obj2)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_ctx, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_ctx_zone_add" "', argument " "1"" of type '" "struct ub_ctx *""'"); + } + arg1 = (struct ub_ctx *)(argp1); + res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ub_ctx_zone_add" "', argument " "2"" of type '" "char *""'"); + } + arg2 = (char *)(buf2); + res3 = SWIG_AsCharPtrAndSize(obj2, &buf3, NULL, &alloc3); + if (!SWIG_IsOK(res3)) { + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "ub_ctx_zone_add" "', argument " "3"" of type '" "char *""'"); + } + arg3 = (char *)(buf3); + result = (int)ub_ctx_zone_add(arg1,arg2,arg3); + resultobj = SWIG_From_int((int)(result)); + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + if (alloc3 == SWIG_NEWOBJ) free((char*)buf3); + return resultobj; +fail: + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + if (alloc3 == SWIG_NEWOBJ) free((char*)buf3); + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_ctx_zone_remove(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_ctx *arg1 = (struct ub_ctx *) 0 ; + char *arg2 = (char *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + int res2 ; + char *buf2 = 0 ; + int alloc2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + int result; + + if (!PyArg_ParseTuple(args,(char *)"OO:ub_ctx_zone_remove",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_ctx, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_ctx_zone_remove" "', argument " "1"" of type '" "struct ub_ctx *""'"); + } + arg1 = (struct ub_ctx *)(argp1); + res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ub_ctx_zone_remove" "', argument " "2"" of type '" "char *""'"); + } + arg2 = (char *)(buf2); + result = (int)ub_ctx_zone_remove(arg1,arg2); + resultobj = SWIG_From_int((int)(result)); + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return resultobj; +fail: + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_ctx_data_add(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_ctx *arg1 = (struct ub_ctx *) 0 ; + char *arg2 = (char *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + int res2 ; + char *buf2 = 0 ; + int alloc2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + int result; + + if (!PyArg_ParseTuple(args,(char *)"OO:ub_ctx_data_add",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_ctx, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_ctx_data_add" "', argument " "1"" of type '" "struct ub_ctx *""'"); + } + arg1 = (struct ub_ctx *)(argp1); + res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ub_ctx_data_add" "', argument " "2"" of type '" "char *""'"); + } + arg2 = (char *)(buf2); + result = (int)ub_ctx_data_add(arg1,arg2); + resultobj = SWIG_From_int((int)(result)); + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return resultobj; +fail: + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_ctx_data_remove(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_ctx *arg1 = (struct ub_ctx *) 0 ; + char *arg2 = (char *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + int res2 ; + char *buf2 = 0 ; + int alloc2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + int result; + + if (!PyArg_ParseTuple(args,(char *)"OO:ub_ctx_data_remove",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_ctx, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_ctx_data_remove" "', argument " "1"" of type '" "struct ub_ctx *""'"); + } + arg1 = (struct ub_ctx *)(argp1); + res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ub_ctx_data_remove" "', argument " "2"" of type '" "char *""'"); + } + arg2 = (char *)(buf2); + result = (int)ub_ctx_data_remove(arg1,arg2); + resultobj = SWIG_From_int((int)(result)); + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return resultobj; +fail: + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return NULL; +} + + +SWIGINTERN PyObject *ub_ctx_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!PyArg_ParseTuple(args,(char*)"O:swigregister", &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_ub_ctx, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *_wrap_ub_ctx_debugout__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_ctx *arg1 = (struct ub_ctx *) 0 ; + FILE *arg2 = (FILE *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + FILE *val2 ; + int ecode2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + int result; + + if (!PyArg_ParseTuple(args,(char *)"OO:ub_ctx_debugout",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_ctx, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ub_ctx_debugout" "', argument " "1"" of type '" "struct ub_ctx *""'"); + } + arg1 = (struct ub_ctx *)(argp1); + ecode2 = SWIG_AsValFilePtr(obj1, &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ub_ctx_debugout" "', argument " "2"" of type '" "FILE *""'"); + } + arg2 = (FILE *)(val2); + result = (int)ub_ctx_debugout(arg1,arg2); + resultobj = SWIG_From_int((int)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ub_ctx_debugout(PyObject *self, PyObject *args) { + int argc; + PyObject *argv[3]; + int ii; + + if (!PyTuple_Check(args)) SWIG_fail; + argc = (int)PyObject_Length(args); + for (ii = 0; (ii < argc) && (ii < 2); ii++) { + argv[ii] = PyTuple_GET_ITEM(args,ii); + } + if (argc == 2) { + int _v; + void *vptr = 0; + int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_ub_ctx, 0); + _v = SWIG_CheckState(res); + if (_v) { + { + int res = SWIG_AsValFilePtr(argv[1], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + return _wrap_ub_ctx_debugout__SWIG_1(self, args); + } + } + } + if (argc == 2) { + int _v; + void *vptr = 0; + int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_ub_ctx, 0); + _v = SWIG_CheckState(res); + if (_v) { + void *ptr = 0; + int res = SWIG_ConvertPtr(argv[1], &ptr, 0, 0); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_ub_ctx_debugout__SWIG_0(self, args); + } + } + } + +fail: + SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'ub_ctx_debugout'.\n" + " Possible C/C++ prototypes are:\n" + " ub_ctx_debugout(struct ub_ctx *,void *)\n" + " ub_ctx_debugout(struct ub_ctx *,FILE *)\n"); + return NULL; +} + + +SWIGINTERN PyObject *_wrap__ub_resolve_async(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + struct ub_ctx *arg1 = (struct ub_ctx *) 0 ; + char *arg2 = (char *) 0 ; + int arg3 ; + int arg4 ; + void *arg5 = (void *) 0 ; + PyObject *arg6 = (PyObject *) 0 ; + int *arg7 = (int *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + int res2 ; + char *buf2 = 0 ; + int alloc2 = 0 ; + int val3 ; + int ecode3 = 0 ; + int val4 ; + int ecode4 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + PyObject * obj2 = 0 ; + PyObject * obj3 = 0 ; + PyObject * obj4 = 0 ; + PyObject * obj5 = 0 ; + int result; + + int asyncid = -1; + arg7 = &asyncid; + if (!PyArg_ParseTuple(args,(char *)"OOOOOO:_ub_resolve_async",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ub_ctx, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "_ub_resolve_async" "', argument " "1"" of type '" "struct ub_ctx *""'"); + } + arg1 = (struct ub_ctx *)(argp1); + res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "_ub_resolve_async" "', argument " "2"" of type '" "char *""'"); + } + arg2 = (char *)(buf2); + ecode3 = SWIG_AsVal_int(obj2, &val3); + if (!SWIG_IsOK(ecode3)) { + SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "_ub_resolve_async" "', argument " "3"" of type '" "int""'"); + } + arg3 = (int)(val3); + ecode4 = SWIG_AsVal_int(obj3, &val4); + if (!SWIG_IsOK(ecode4)) { + SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "_ub_resolve_async" "', argument " "4"" of type '" "int""'"); + } + arg4 = (int)(val4); + arg5 = obj4; + { + if (!PyCallable_Check(obj5)) + { + PyErr_SetString(PyExc_TypeError, "Need a callable object!"); + return NULL; + } + arg6 = obj5; + } + result = (int)_ub_resolve_async(arg1,arg2,arg3,arg4,arg5,arg6,arg7); + resultobj = SWIG_From_int((int)(result)); + PyObject* tuple; + tuple = PyTuple_New(2); + PyTuple_SetItem(tuple, 0, resultobj); + PyTuple_SetItem(tuple, 1, SWIG_From_int(asyncid)); + resultobj = tuple; + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return resultobj; +fail: + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return NULL; +} + + +static PyMethodDef SwigMethods[] = { + { (char *)"SWIG_PyInstanceMethod_New", (PyCFunction)SWIG_PyInstanceMethod_New, METH_O, NULL}, + { (char *)"ub_ctx_free_dbg", _wrap_ub_ctx_free_dbg, METH_VARARGS, NULL}, + { (char *)"ub_resolve_free_dbg", _wrap_ub_resolve_free_dbg, METH_VARARGS, NULL}, + { (char *)"ub_result_qname_set", _wrap_ub_result_qname_set, METH_VARARGS, NULL}, + { (char *)"ub_result_qname_get", _wrap_ub_result_qname_get, METH_VARARGS, NULL}, + { (char *)"ub_result_qtype_set", _wrap_ub_result_qtype_set, METH_VARARGS, NULL}, + { (char *)"ub_result_qtype_get", _wrap_ub_result_qtype_get, METH_VARARGS, NULL}, + { (char *)"ub_result_qclass_set", _wrap_ub_result_qclass_set, METH_VARARGS, NULL}, + { (char *)"ub_result_qclass_get", _wrap_ub_result_qclass_get, METH_VARARGS, NULL}, + { (char *)"ub_result__data_set", _wrap_ub_result__data_set, METH_VARARGS, NULL}, + { (char *)"ub_result__data_get", _wrap_ub_result__data_get, METH_VARARGS, NULL}, + { (char *)"ub_result_len_set", _wrap_ub_result_len_set, METH_VARARGS, NULL}, + { (char *)"ub_result_len_get", _wrap_ub_result_len_get, METH_VARARGS, NULL}, + { (char *)"ub_result_canonname_set", _wrap_ub_result_canonname_set, METH_VARARGS, NULL}, + { (char *)"ub_result_canonname_get", _wrap_ub_result_canonname_get, METH_VARARGS, NULL}, + { (char *)"ub_result_rcode_set", _wrap_ub_result_rcode_set, METH_VARARGS, NULL}, + { (char *)"ub_result_rcode_get", _wrap_ub_result_rcode_get, METH_VARARGS, NULL}, + { (char *)"ub_result_answer_packet_set", _wrap_ub_result_answer_packet_set, METH_VARARGS, NULL}, + { (char *)"ub_result_answer_packet_get", _wrap_ub_result_answer_packet_get, METH_VARARGS, NULL}, + { (char *)"ub_result_answer_len_set", _wrap_ub_result_answer_len_set, METH_VARARGS, NULL}, + { (char *)"ub_result_answer_len_get", _wrap_ub_result_answer_len_get, METH_VARARGS, NULL}, + { (char *)"ub_result_havedata_set", _wrap_ub_result_havedata_set, METH_VARARGS, NULL}, + { (char *)"ub_result_havedata_get", _wrap_ub_result_havedata_get, METH_VARARGS, NULL}, + { (char *)"ub_result_nxdomain_set", _wrap_ub_result_nxdomain_set, METH_VARARGS, NULL}, + { (char *)"ub_result_nxdomain_get", _wrap_ub_result_nxdomain_get, METH_VARARGS, NULL}, + { (char *)"ub_result_secure_set", _wrap_ub_result_secure_set, METH_VARARGS, NULL}, + { (char *)"ub_result_secure_get", _wrap_ub_result_secure_get, METH_VARARGS, NULL}, + { (char *)"ub_result_bogus_set", _wrap_ub_result_bogus_set, METH_VARARGS, NULL}, + { (char *)"ub_result_bogus_get", _wrap_ub_result_bogus_get, METH_VARARGS, NULL}, + { (char *)"ub_result__ub_result_data", _wrap_ub_result__ub_result_data, METH_VARARGS, NULL}, + { (char *)"ub_result_swigregister", ub_result_swigregister, METH_VARARGS, NULL}, + { (char *)"ub_ctx_create", _wrap_ub_ctx_create, METH_VARARGS, NULL}, + { (char *)"_ub_ctx_delete", _wrap__ub_ctx_delete, METH_VARARGS, NULL}, + { (char *)"ub_ctx_set_option", _wrap_ub_ctx_set_option, METH_VARARGS, NULL}, + { (char *)"ub_ctx_config", _wrap_ub_ctx_config, METH_VARARGS, NULL}, + { (char *)"ub_ctx_set_fwd", _wrap_ub_ctx_set_fwd, METH_VARARGS, NULL}, + { (char *)"ub_ctx_resolvconf", _wrap_ub_ctx_resolvconf, METH_VARARGS, NULL}, + { (char *)"ub_ctx_hosts", _wrap_ub_ctx_hosts, METH_VARARGS, NULL}, + { (char *)"ub_ctx_add_ta", _wrap_ub_ctx_add_ta, METH_VARARGS, NULL}, + { (char *)"ub_ctx_add_ta_file", _wrap_ub_ctx_add_ta_file, METH_VARARGS, NULL}, + { (char *)"ub_ctx_trustedkeys", _wrap_ub_ctx_trustedkeys, METH_VARARGS, NULL}, + { (char *)"ub_ctx_debuglevel", _wrap_ub_ctx_debuglevel, METH_VARARGS, NULL}, + { (char *)"ub_ctx_async", _wrap_ub_ctx_async, METH_VARARGS, NULL}, + { (char *)"ub_poll", _wrap_ub_poll, METH_VARARGS, NULL}, + { (char *)"ub_wait", _wrap_ub_wait, METH_VARARGS, NULL}, + { (char *)"ub_fd", _wrap_ub_fd, METH_VARARGS, NULL}, + { (char *)"ub_process", _wrap_ub_process, METH_VARARGS, NULL}, + { (char *)"ub_resolve", _wrap_ub_resolve, METH_VARARGS, NULL}, + { (char *)"ub_resolve_async", _wrap_ub_resolve_async, METH_VARARGS, NULL}, + { (char *)"ub_cancel", _wrap_ub_cancel, METH_VARARGS, NULL}, + { (char *)"_ub_resolve_free", _wrap__ub_resolve_free, METH_VARARGS, NULL}, + { (char *)"ub_strerror", _wrap_ub_strerror, METH_VARARGS, NULL}, + { (char *)"ub_ctx_print_local_zones", _wrap_ub_ctx_print_local_zones, METH_VARARGS, NULL}, + { (char *)"ub_ctx_zone_add", _wrap_ub_ctx_zone_add, METH_VARARGS, NULL}, + { (char *)"ub_ctx_zone_remove", _wrap_ub_ctx_zone_remove, METH_VARARGS, NULL}, + { (char *)"ub_ctx_data_add", _wrap_ub_ctx_data_add, METH_VARARGS, NULL}, + { (char *)"ub_ctx_data_remove", _wrap_ub_ctx_data_remove, METH_VARARGS, NULL}, + { (char *)"ub_ctx_swigregister", ub_ctx_swigregister, METH_VARARGS, NULL}, + { (char *)"ub_ctx_debugout", _wrap_ub_ctx_debugout, METH_VARARGS, NULL}, + { (char *)"_ub_resolve_async", _wrap__ub_resolve_async, METH_VARARGS, NULL}, + { NULL, NULL, 0, NULL } +}; + + +/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */ + +static swig_type_info _swigt__p_FILE = {"_p_FILE", "FILE *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_char = {"_p_char", "char *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_f_p_void_int_p_struct_ub_result__void = {"_p_f_p_void_int_p_struct_ub_result__void", "void (*)(void *,int,struct ub_result *)|ub_callback_t", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_int = {"_p_int", "int *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_p_char = {"_p_p_char", "char **", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_p_ub_result = {"_p_p_ub_result", "struct ub_result **", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_ub_ctx = {"_p_ub_ctx", "struct ub_ctx *|ub_ctx *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_ub_result = {"_p_ub_result", "struct ub_result *|ub_result *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_void = {"_p_void", "void *", 0, 0, (void*)0, 0}; + +static swig_type_info *swig_type_initial[] = { + &_swigt__p_FILE, + &_swigt__p_char, + &_swigt__p_f_p_void_int_p_struct_ub_result__void, + &_swigt__p_int, + &_swigt__p_p_char, + &_swigt__p_p_ub_result, + &_swigt__p_ub_ctx, + &_swigt__p_ub_result, + &_swigt__p_void, +}; + +static swig_cast_info _swigc__p_FILE[] = { {&_swigt__p_FILE, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_char[] = { {&_swigt__p_char, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_f_p_void_int_p_struct_ub_result__void[] = { {&_swigt__p_f_p_void_int_p_struct_ub_result__void, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_int[] = { {&_swigt__p_int, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_p_char[] = { {&_swigt__p_p_char, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_p_ub_result[] = { {&_swigt__p_p_ub_result, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_ub_ctx[] = { {&_swigt__p_ub_ctx, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_ub_result[] = { {&_swigt__p_ub_result, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_void[] = { {&_swigt__p_void, 0, 0, 0},{0, 0, 0, 0}}; + +static swig_cast_info *swig_cast_initial[] = { + _swigc__p_FILE, + _swigc__p_char, + _swigc__p_f_p_void_int_p_struct_ub_result__void, + _swigc__p_int, + _swigc__p_p_char, + _swigc__p_p_ub_result, + _swigc__p_ub_ctx, + _swigc__p_ub_result, + _swigc__p_void, +}; + + +/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (END) -------- */ + +static swig_const_info swig_const_table[] = { +{0, 0, 0, 0.0, 0, 0}}; + +#ifdef __cplusplus +} +#endif +/* ----------------------------------------------------------------------------- + * Type initialization: + * This problem is tough by the requirement that no dynamic + * memory is used. Also, since swig_type_info structures store pointers to + * swig_cast_info structures and swig_cast_info structures store pointers back + * to swig_type_info structures, we need some lookup code at initialization. + * The idea is that swig generates all the structures that are needed. + * The runtime then collects these partially filled structures. + * The SWIG_InitializeModule function takes these initial arrays out of + * swig_module, and does all the lookup, filling in the swig_module.types + * array with the correct data and linking the correct swig_cast_info + * structures together. + * + * The generated swig_type_info structures are assigned staticly to an initial + * array. We just loop through that array, and handle each type individually. + * First we lookup if this type has been already loaded, and if so, use the + * loaded structure instead of the generated one. Then we have to fill in the + * cast linked list. The cast data is initially stored in something like a + * two-dimensional array. Each row corresponds to a type (there are the same + * number of rows as there are in the swig_type_initial array). Each entry in + * a column is one of the swig_cast_info structures for that type. + * The cast_initial array is actually an array of arrays, because each row has + * a variable number of columns. So to actually build the cast linked list, + * we find the array of casts associated with the type, and loop through it + * adding the casts to the list. The one last trick we need to do is making + * sure the type pointer in the swig_cast_info struct is correct. + * + * First off, we lookup the cast->type name to see if it is already loaded. + * There are three cases to handle: + * 1) If the cast->type has already been loaded AND the type we are adding + * casting info to has not been loaded (it is in this module), THEN we + * replace the cast->type pointer with the type pointer that has already + * been loaded. + * 2) If BOTH types (the one we are adding casting info to, and the + * cast->type) are loaded, THEN the cast info has already been loaded by + * the previous module so we just ignore it. + * 3) Finally, if cast->type has not already been loaded, then we add that + * swig_cast_info to the linked list (because the cast->type) pointer will + * be correct. + * ----------------------------------------------------------------------------- */ + +#ifdef __cplusplus +extern "C" { +#if 0 +} /* c-mode */ +#endif +#endif + +#if 0 +#define SWIGRUNTIME_DEBUG +#endif + + +SWIGRUNTIME void +SWIG_InitializeModule(void *clientdata) { + size_t i; + swig_module_info *module_head, *iter; + int found, init; + + clientdata = clientdata; + + /* check to see if the circular list has been setup, if not, set it up */ + if (swig_module.next==0) { + /* Initialize the swig_module */ + swig_module.type_initial = swig_type_initial; + swig_module.cast_initial = swig_cast_initial; + swig_module.next = &swig_module; + init = 1; + } else { + init = 0; + } + + /* Try and load any already created modules */ + module_head = SWIG_GetModule(clientdata); + if (!module_head) { + /* This is the first module loaded for this interpreter */ + /* so set the swig module into the interpreter */ + SWIG_SetModule(clientdata, &swig_module); + module_head = &swig_module; + } else { + /* the interpreter has loaded a SWIG module, but has it loaded this one? */ + found=0; + iter=module_head; + do { + if (iter==&swig_module) { + found=1; + break; + } + iter=iter->next; + } while (iter!= module_head); + + /* if the is found in the list, then all is done and we may leave */ + if (found) return; + /* otherwise we must add out module into the list */ + swig_module.next = module_head->next; + module_head->next = &swig_module; + } + + /* When multiple interpeters are used, a module could have already been initialized in + a different interpreter, but not yet have a pointer in this interpreter. + In this case, we do not want to continue adding types... everything should be + set up already */ + if (init == 0) return; + + /* Now work on filling in swig_module.types */ +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: size %d\n", swig_module.size); +#endif + for (i = 0; i < swig_module.size; ++i) { + swig_type_info *type = 0; + swig_type_info *ret; + swig_cast_info *cast; + +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name); +#endif + + /* if there is another module already loaded */ + if (swig_module.next != &swig_module) { + type = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, swig_module.type_initial[i]->name); + } + if (type) { + /* Overwrite clientdata field */ +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: found type %s\n", type->name); +#endif + if (swig_module.type_initial[i]->clientdata) { + type->clientdata = swig_module.type_initial[i]->clientdata; +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: found and overwrite type %s \n", type->name); +#endif + } + } else { + type = swig_module.type_initial[i]; + } + + /* Insert casting types */ + cast = swig_module.cast_initial[i]; + while (cast->type) { + /* Don't need to add information already in the list */ + ret = 0; +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: look cast %s\n", cast->type->name); +#endif + if (swig_module.next != &swig_module) { + ret = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, cast->type->name); +#ifdef SWIGRUNTIME_DEBUG + if (ret) printf("SWIG_InitializeModule: found cast %s\n", ret->name); +#endif + } + if (ret) { + if (type == swig_module.type_initial[i]) { +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: skip old type %s\n", ret->name); +#endif + cast->type = ret; + ret = 0; + } else { + /* Check for casting already in the list */ + swig_cast_info *ocast = SWIG_TypeCheck(ret->name, type); +#ifdef SWIGRUNTIME_DEBUG + if (ocast) printf("SWIG_InitializeModule: skip old cast %s\n", ret->name); +#endif + if (!ocast) ret = 0; + } + } + + if (!ret) { +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: adding cast %s\n", cast->type->name); +#endif + if (type->cast) { + type->cast->prev = cast; + cast->next = type->cast; + } + type->cast = cast; + } + cast++; + } + /* Set entry in modules->types array equal to the type */ + swig_module.types[i] = type; + } + swig_module.types[i] = 0; + +#ifdef SWIGRUNTIME_DEBUG + printf("**** SWIG_InitializeModule: Cast List ******\n"); + for (i = 0; i < swig_module.size; ++i) { + int j = 0; + swig_cast_info *cast = swig_module.cast_initial[i]; + printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name); + while (cast->type) { + printf("SWIG_InitializeModule: cast type %s\n", cast->type->name); + cast++; + ++j; + } + printf("---- Total casts: %d\n",j); + } + printf("**** SWIG_InitializeModule: Cast List ******\n"); +#endif +} + +/* This function will propagate the clientdata field of type to +* any new swig_type_info structures that have been added into the list +* of equivalent types. It is like calling +* SWIG_TypeClientData(type, clientdata) a second time. +*/ +SWIGRUNTIME void +SWIG_PropagateClientData(void) { + size_t i; + swig_cast_info *equiv; + static int init_run = 0; + + if (init_run) return; + init_run = 1; + + for (i = 0; i < swig_module.size; i++) { + if (swig_module.types[i]->clientdata) { + equiv = swig_module.types[i]->cast; + while (equiv) { + if (!equiv->converter) { + if (equiv->type && !equiv->type->clientdata) + SWIG_TypeClientData(equiv->type, swig_module.types[i]->clientdata); + } + equiv = equiv->next; + } + } + } +} + +#ifdef __cplusplus +#if 0 +{ + /* c-mode */ +#endif +} +#endif + + + +#ifdef __cplusplus +extern "C" { +#endif + + /* Python-specific SWIG API */ +#define SWIG_newvarlink() SWIG_Python_newvarlink() +#define SWIG_addvarlink(p, name, get_attr, set_attr) SWIG_Python_addvarlink(p, name, get_attr, set_attr) +#define SWIG_InstallConstants(d, constants) SWIG_Python_InstallConstants(d, constants) + + /* ----------------------------------------------------------------------------- + * global variable support code. + * ----------------------------------------------------------------------------- */ + + typedef struct swig_globalvar { + char *name; /* Name of global variable */ + PyObject *(*get_attr)(void); /* Return the current value */ + int (*set_attr)(PyObject *); /* Set the value */ + struct swig_globalvar *next; + } swig_globalvar; + + typedef struct swig_varlinkobject { + PyObject_HEAD + swig_globalvar *vars; + } swig_varlinkobject; + + SWIGINTERN PyObject * + swig_varlink_repr(swig_varlinkobject *SWIGUNUSEDPARM(v)) { +#if PY_VERSION_HEX >= 0x03000000 + return PyUnicode_InternFromString(""); +#else + return PyString_FromString(""); +#endif + } + + SWIGINTERN PyObject * + swig_varlink_str(swig_varlinkobject *v) { +#if PY_VERSION_HEX >= 0x03000000 + PyObject *str = PyUnicode_InternFromString("("); + PyObject *tail; + PyObject *joined; + swig_globalvar *var; + for (var = v->vars; var; var=var->next) { + tail = PyUnicode_FromString(var->name); + joined = PyUnicode_Concat(str, tail); + Py_DecRef(str); + Py_DecRef(tail); + str = joined; + if (var->next) { + tail = PyUnicode_InternFromString(", "); + joined = PyUnicode_Concat(str, tail); + Py_DecRef(str); + Py_DecRef(tail); + str = joined; + } + } + tail = PyUnicode_InternFromString(")"); + joined = PyUnicode_Concat(str, tail); + Py_DecRef(str); + Py_DecRef(tail); + str = joined; +#else + PyObject *str = PyString_FromString("("); + swig_globalvar *var; + for (var = v->vars; var; var=var->next) { + PyString_ConcatAndDel(&str,PyString_FromString(var->name)); + if (var->next) PyString_ConcatAndDel(&str,PyString_FromString(", ")); + } + PyString_ConcatAndDel(&str,PyString_FromString(")")); +#endif + return str; + } + + SWIGINTERN int + swig_varlink_print(swig_varlinkobject *v, FILE *fp, int SWIGUNUSEDPARM(flags)) { + PyObject *str = swig_varlink_str(v); + fprintf(fp,"Swig global variables "); + fprintf(fp,"%s\n", SWIG_Python_str_AsChar(str)); + Py_DECREF(str); + return 0; + } + + SWIGINTERN void + swig_varlink_dealloc(swig_varlinkobject *v) { + swig_globalvar *var = v->vars; + while (var) { + swig_globalvar *n = var->next; + free(var->name); + free(var); + var = n; + } + } + + SWIGINTERN PyObject * + swig_varlink_getattr(swig_varlinkobject *v, char *n) { + PyObject *res = NULL; + swig_globalvar *var = v->vars; + while (var) { + if (strcmp(var->name,n) == 0) { + res = (*var->get_attr)(); + break; + } + var = var->next; + } + if (res == NULL && !PyErr_Occurred()) { + PyErr_SetString(PyExc_NameError,"Unknown C global variable"); + } + return res; + } + + SWIGINTERN int + swig_varlink_setattr(swig_varlinkobject *v, char *n, PyObject *p) { + int res = 1; + swig_globalvar *var = v->vars; + while (var) { + if (strcmp(var->name,n) == 0) { + res = (*var->set_attr)(p); + break; + } + var = var->next; + } + if (res == 1 && !PyErr_Occurred()) { + PyErr_SetString(PyExc_NameError,"Unknown C global variable"); + } + return res; + } + + SWIGINTERN PyTypeObject* + swig_varlink_type(void) { + static char varlink__doc__[] = "Swig var link object"; + static PyTypeObject varlink_type; + static int type_init = 0; + if (!type_init) { + const PyTypeObject tmp + = { + /* PyObject header changed in Python 3 */ +#if PY_VERSION_HEX >= 0x03000000 + PyVarObject_HEAD_INIT(&PyType_Type, 0) +#else + PyObject_HEAD_INIT(NULL) + 0, /* Number of items in variable part (ob_size) */ +#endif + (char *)"swigvarlink", /* Type name (tp_name) */ + sizeof(swig_varlinkobject), /* Basic size (tp_basicsize) */ + 0, /* Itemsize (tp_itemsize) */ + (destructor) swig_varlink_dealloc, /* Deallocator (tp_dealloc) */ + (printfunc) swig_varlink_print, /* Print (tp_print) */ + (getattrfunc) swig_varlink_getattr, /* get attr (tp_getattr) */ + (setattrfunc) swig_varlink_setattr, /* Set attr (tp_setattr) */ + 0, /* tp_compare */ + (reprfunc) swig_varlink_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + (reprfunc)swig_varlink_str, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + 0, /* tp_flags */ + varlink__doc__, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ +#if PY_VERSION_HEX >= 0x02020000 + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* tp_iter -> tp_weaklist */ +#endif +#if PY_VERSION_HEX >= 0x02030000 + 0, /* tp_del */ +#endif +#ifdef COUNT_ALLOCS + 0,0,0,0 /* tp_alloc -> tp_next */ +#endif + }; + varlink_type = tmp; + /* for Python 3 we already assigned the ob_type in PyVarObject_HEAD_INIT() */ +#if PY_VERSION_HEX < 0x03000000 + varlink_type.ob_type = &PyType_Type; +#endif + type_init = 1; + } + return &varlink_type; + } + + /* Create a variable linking object for use later */ + SWIGINTERN PyObject * + SWIG_Python_newvarlink(void) { + swig_varlinkobject *result = PyObject_NEW(swig_varlinkobject, swig_varlink_type()); + if (result) { + result->vars = 0; + } + return ((PyObject*) result); + } + + SWIGINTERN void + SWIG_Python_addvarlink(PyObject *p, char *name, PyObject *(*get_attr)(void), int (*set_attr)(PyObject *p)) { + swig_varlinkobject *v = (swig_varlinkobject *) p; + swig_globalvar *gv = (swig_globalvar *) malloc(sizeof(swig_globalvar)); + if (gv) { + size_t size = strlen(name)+1; + gv->name = (char *)malloc(size); + if (gv->name) { + strncpy(gv->name,name,size); + gv->get_attr = get_attr; + gv->set_attr = set_attr; + gv->next = v->vars; + } + } + v->vars = gv; + } + + SWIGINTERN PyObject * + SWIG_globals(void) { + static PyObject *_SWIG_globals = 0; + if (!_SWIG_globals) _SWIG_globals = SWIG_newvarlink(); + return _SWIG_globals; + } + + /* ----------------------------------------------------------------------------- + * constants/methods manipulation + * ----------------------------------------------------------------------------- */ + + /* Install Constants */ + SWIGINTERN void + SWIG_Python_InstallConstants(PyObject *d, swig_const_info constants[]) { + PyObject *obj = 0; + size_t i; + for (i = 0; constants[i].type; ++i) { + switch(constants[i].type) { + case SWIG_PY_POINTER: + obj = SWIG_NewPointerObj(constants[i].pvalue, *(constants[i]).ptype,0); + break; + case SWIG_PY_BINARY: + obj = SWIG_NewPackedObj(constants[i].pvalue, constants[i].lvalue, *(constants[i].ptype)); + break; + default: + obj = 0; + break; + } + if (obj) { + PyDict_SetItemString(d, constants[i].name, obj); + Py_DECREF(obj); + } + } + } + + /* -----------------------------------------------------------------------------*/ + /* Fix SwigMethods to carry the callback ptrs when needed */ + /* -----------------------------------------------------------------------------*/ + + SWIGINTERN void + SWIG_Python_FixMethods(PyMethodDef *methods, + swig_const_info *const_table, + swig_type_info **types, + swig_type_info **types_initial) { + size_t i; + for (i = 0; methods[i].ml_name; ++i) { + const char *c = methods[i].ml_doc; + if (c && (c = strstr(c, "swig_ptr: "))) { + int j; + swig_const_info *ci = 0; + const char *name = c + 10; + for (j = 0; const_table[j].type; ++j) { + if (strncmp(const_table[j].name, name, + strlen(const_table[j].name)) == 0) { + ci = &(const_table[j]); + break; + } + } + if (ci) { + size_t shift = (ci->ptype) - types; + swig_type_info *ty = types_initial[shift]; + size_t ldoc = (c - methods[i].ml_doc); + size_t lptr = strlen(ty->name)+2*sizeof(void*)+2; + char *ndoc = (char*)malloc(ldoc + lptr + 10); + if (ndoc) { + char *buff = ndoc; + void *ptr = (ci->type == SWIG_PY_POINTER) ? ci->pvalue : 0; + if (ptr) { + strncpy(buff, methods[i].ml_doc, ldoc); + buff += ldoc; + strncpy(buff, "swig_ptr: ", 10); + buff += 10; + SWIG_PackVoidPtr(buff, ptr, ty->name, lptr); + methods[i].ml_doc = ndoc; + } + } + } + } + } + } + +#ifdef __cplusplus +} +#endif + +/* -----------------------------------------------------------------------------* + * Partial Init method + * -----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" +#endif + +SWIGEXPORT +#if PY_VERSION_HEX >= 0x03000000 +PyObject* +#else +void +#endif +SWIG_init(void) { + PyObject *m, *d; + + /* Fix SwigMethods to carry the callback ptrs when needed */ + SWIG_Python_FixMethods(SwigMethods, swig_const_table, swig_types, swig_type_initial); +#if PY_VERSION_HEX >= 0x03000000 + static struct PyModuleDef SWIG_module = { + PyModuleDef_HEAD_INIT, + (char *) SWIG_name, + NULL, + -1, + SwigMethods, + NULL, + NULL, + NULL, + NULL + }; + + m = PyModule_Create(&SWIG_module); +#else + m = Py_InitModule((char *) SWIG_name, SwigMethods); +#endif + d = PyModule_GetDict(m); + + SWIG_InitializeModule(0); + SWIG_InstallConstants(d,swig_const_table); + + + SWIG_Python_SetConstant(d, "RR_TYPE_A",SWIG_From_int((int)(RR_TYPE_A))); + SWIG_Python_SetConstant(d, "RR_TYPE_NS",SWIG_From_int((int)(RR_TYPE_NS))); + SWIG_Python_SetConstant(d, "RR_TYPE_MD",SWIG_From_int((int)(RR_TYPE_MD))); + SWIG_Python_SetConstant(d, "RR_TYPE_MF",SWIG_From_int((int)(RR_TYPE_MF))); + SWIG_Python_SetConstant(d, "RR_TYPE_CNAME",SWIG_From_int((int)(RR_TYPE_CNAME))); + SWIG_Python_SetConstant(d, "RR_TYPE_SOA",SWIG_From_int((int)(RR_TYPE_SOA))); + SWIG_Python_SetConstant(d, "RR_TYPE_MB",SWIG_From_int((int)(RR_TYPE_MB))); + SWIG_Python_SetConstant(d, "RR_TYPE_MG",SWIG_From_int((int)(RR_TYPE_MG))); + SWIG_Python_SetConstant(d, "RR_TYPE_MR",SWIG_From_int((int)(RR_TYPE_MR))); + SWIG_Python_SetConstant(d, "RR_TYPE_NULL",SWIG_From_int((int)(RR_TYPE_NULL))); + SWIG_Python_SetConstant(d, "RR_TYPE_WKS",SWIG_From_int((int)(RR_TYPE_WKS))); + SWIG_Python_SetConstant(d, "RR_TYPE_PTR",SWIG_From_int((int)(RR_TYPE_PTR))); + SWIG_Python_SetConstant(d, "RR_TYPE_HINFO",SWIG_From_int((int)(RR_TYPE_HINFO))); + SWIG_Python_SetConstant(d, "RR_TYPE_MINFO",SWIG_From_int((int)(RR_TYPE_MINFO))); + SWIG_Python_SetConstant(d, "RR_TYPE_MX",SWIG_From_int((int)(RR_TYPE_MX))); + SWIG_Python_SetConstant(d, "RR_TYPE_TXT",SWIG_From_int((int)(RR_TYPE_TXT))); + SWIG_Python_SetConstant(d, "RR_TYPE_RP",SWIG_From_int((int)(RR_TYPE_RP))); + SWIG_Python_SetConstant(d, "RR_TYPE_AFSDB",SWIG_From_int((int)(RR_TYPE_AFSDB))); + SWIG_Python_SetConstant(d, "RR_TYPE_X25",SWIG_From_int((int)(RR_TYPE_X25))); + SWIG_Python_SetConstant(d, "RR_TYPE_ISDN",SWIG_From_int((int)(RR_TYPE_ISDN))); + SWIG_Python_SetConstant(d, "RR_TYPE_RT",SWIG_From_int((int)(RR_TYPE_RT))); + SWIG_Python_SetConstant(d, "RR_TYPE_NSAP",SWIG_From_int((int)(RR_TYPE_NSAP))); + SWIG_Python_SetConstant(d, "RR_TYPE_NSAP_PTR",SWIG_From_int((int)(RR_TYPE_NSAP_PTR))); + SWIG_Python_SetConstant(d, "RR_TYPE_SIG",SWIG_From_int((int)(RR_TYPE_SIG))); + SWIG_Python_SetConstant(d, "RR_TYPE_KEY",SWIG_From_int((int)(RR_TYPE_KEY))); + SWIG_Python_SetConstant(d, "RR_TYPE_PX",SWIG_From_int((int)(RR_TYPE_PX))); + SWIG_Python_SetConstant(d, "RR_TYPE_GPOS",SWIG_From_int((int)(RR_TYPE_GPOS))); + SWIG_Python_SetConstant(d, "RR_TYPE_AAAA",SWIG_From_int((int)(RR_TYPE_AAAA))); + SWIG_Python_SetConstant(d, "RR_TYPE_LOC",SWIG_From_int((int)(RR_TYPE_LOC))); + SWIG_Python_SetConstant(d, "RR_TYPE_NXT",SWIG_From_int((int)(RR_TYPE_NXT))); + SWIG_Python_SetConstant(d, "RR_TYPE_EID",SWIG_From_int((int)(RR_TYPE_EID))); + SWIG_Python_SetConstant(d, "RR_TYPE_NIMLOC",SWIG_From_int((int)(RR_TYPE_NIMLOC))); + SWIG_Python_SetConstant(d, "RR_TYPE_SRV",SWIG_From_int((int)(RR_TYPE_SRV))); + SWIG_Python_SetConstant(d, "RR_TYPE_ATMA",SWIG_From_int((int)(RR_TYPE_ATMA))); + SWIG_Python_SetConstant(d, "RR_TYPE_NAPTR",SWIG_From_int((int)(RR_TYPE_NAPTR))); + SWIG_Python_SetConstant(d, "RR_TYPE_KX",SWIG_From_int((int)(RR_TYPE_KX))); + SWIG_Python_SetConstant(d, "RR_TYPE_CERT",SWIG_From_int((int)(RR_TYPE_CERT))); + SWIG_Python_SetConstant(d, "RR_TYPE_A6",SWIG_From_int((int)(RR_TYPE_A6))); + SWIG_Python_SetConstant(d, "RR_TYPE_DNAME",SWIG_From_int((int)(RR_TYPE_DNAME))); + SWIG_Python_SetConstant(d, "RR_TYPE_SINK",SWIG_From_int((int)(RR_TYPE_SINK))); + SWIG_Python_SetConstant(d, "RR_TYPE_OPT",SWIG_From_int((int)(RR_TYPE_OPT))); + SWIG_Python_SetConstant(d, "RR_TYPE_APL",SWIG_From_int((int)(RR_TYPE_APL))); + SWIG_Python_SetConstant(d, "RR_TYPE_DS",SWIG_From_int((int)(RR_TYPE_DS))); + SWIG_Python_SetConstant(d, "RR_TYPE_SSHFP",SWIG_From_int((int)(RR_TYPE_SSHFP))); + SWIG_Python_SetConstant(d, "RR_TYPE_IPSECKEY",SWIG_From_int((int)(RR_TYPE_IPSECKEY))); + SWIG_Python_SetConstant(d, "RR_TYPE_RRSIG",SWIG_From_int((int)(RR_TYPE_RRSIG))); + SWIG_Python_SetConstant(d, "RR_TYPE_NSEC",SWIG_From_int((int)(RR_TYPE_NSEC))); + SWIG_Python_SetConstant(d, "RR_TYPE_DNSKEY",SWIG_From_int((int)(RR_TYPE_DNSKEY))); + SWIG_Python_SetConstant(d, "RR_TYPE_DHCID",SWIG_From_int((int)(RR_TYPE_DHCID))); + SWIG_Python_SetConstant(d, "RR_TYPE_NSEC3",SWIG_From_int((int)(RR_TYPE_NSEC3))); + SWIG_Python_SetConstant(d, "RR_TYPE_NSEC3PARAMS",SWIG_From_int((int)(RR_TYPE_NSEC3PARAMS))); + SWIG_Python_SetConstant(d, "RR_TYPE_UINFO",SWIG_From_int((int)(RR_TYPE_UINFO))); + SWIG_Python_SetConstant(d, "RR_TYPE_UID",SWIG_From_int((int)(RR_TYPE_UID))); + SWIG_Python_SetConstant(d, "RR_TYPE_GID",SWIG_From_int((int)(RR_TYPE_GID))); + SWIG_Python_SetConstant(d, "RR_TYPE_UNSPEC",SWIG_From_int((int)(RR_TYPE_UNSPEC))); + SWIG_Python_SetConstant(d, "RR_TYPE_TSIG",SWIG_From_int((int)(RR_TYPE_TSIG))); + SWIG_Python_SetConstant(d, "RR_TYPE_IXFR",SWIG_From_int((int)(RR_TYPE_IXFR))); + SWIG_Python_SetConstant(d, "RR_TYPE_AXFR",SWIG_From_int((int)(RR_TYPE_AXFR))); + SWIG_Python_SetConstant(d, "RR_TYPE_MAILB",SWIG_From_int((int)(RR_TYPE_MAILB))); + SWIG_Python_SetConstant(d, "RR_TYPE_MAILA",SWIG_From_int((int)(RR_TYPE_MAILA))); + SWIG_Python_SetConstant(d, "RR_TYPE_ANY",SWIG_From_int((int)(RR_TYPE_ANY))); + SWIG_Python_SetConstant(d, "RR_TYPE_DLV",SWIG_From_int((int)(RR_TYPE_DLV))); + SWIG_Python_SetConstant(d, "RR_CLASS_IN",SWIG_From_int((int)(RR_CLASS_IN))); + SWIG_Python_SetConstant(d, "RR_CLASS_CH",SWIG_From_int((int)(RR_CLASS_CH))); + SWIG_Python_SetConstant(d, "RR_CLASS_HS",SWIG_From_int((int)(RR_CLASS_HS))); + SWIG_Python_SetConstant(d, "RR_CLASS_NONE",SWIG_From_int((int)(RR_CLASS_NONE))); + SWIG_Python_SetConstant(d, "RR_CLASS_ANY",SWIG_From_int((int)(RR_CLASS_ANY))); + SWIG_Python_SetConstant(d, "RCODE_NOERROR",SWIG_From_int((int)(RCODE_NOERROR))); + SWIG_Python_SetConstant(d, "RCODE_FORMERR",SWIG_From_int((int)(RCODE_FORMERR))); + SWIG_Python_SetConstant(d, "RCODE_SERVFAIL",SWIG_From_int((int)(RCODE_SERVFAIL))); + SWIG_Python_SetConstant(d, "RCODE_NXDOMAIN",SWIG_From_int((int)(RCODE_NXDOMAIN))); + SWIG_Python_SetConstant(d, "RCODE_NOTIMPL",SWIG_From_int((int)(RCODE_NOTIMPL))); + SWIG_Python_SetConstant(d, "RCODE_REFUSED",SWIG_From_int((int)(RCODE_REFUSED))); + SWIG_Python_SetConstant(d, "RCODE_YXDOMAIN",SWIG_From_int((int)(RCODE_YXDOMAIN))); + SWIG_Python_SetConstant(d, "RCODE_YXRRSET",SWIG_From_int((int)(RCODE_YXRRSET))); + SWIG_Python_SetConstant(d, "RCODE_NXRRSET",SWIG_From_int((int)(RCODE_NXRRSET))); + SWIG_Python_SetConstant(d, "RCODE_NOTAUTH",SWIG_From_int((int)(RCODE_NOTAUTH))); + SWIG_Python_SetConstant(d, "RCODE_NOTZONE",SWIG_From_int((int)(RCODE_NOTZONE))); +#if PY_VERSION_HEX >= 0x03000000 + return m; +#else + return; +#endif +} + diff --git a/doc/CREDITS b/doc/CREDITS index c512a8a1a..83b250de5 100644 --- a/doc/CREDITS +++ b/doc/CREDITS @@ -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. diff --git a/doc/Changelog b/doc/Changelog index 0a93ac4cb..ac8e92cfa 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -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. diff --git a/doc/example.conf.in b/doc/example.conf.in index 119aecd38..52386ddd1 100644 --- a/doc/example.conf.in +++ b/doc/example.conf.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. diff --git a/doc/unbound.doxygen b/doc/unbound.doxygen index 066fe5051..2baaeb3a2 100644 --- a/doc/unbound.doxygen +++ b/doc/unbound.doxygen @@ -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 diff --git a/libunbound/libunbound.c b/libunbound/libunbound.c index 9c5c79fcf..4daa31301 100644 --- a/libunbound/libunbound.c +++ b/libunbound/libunbound.c @@ -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; +} diff --git a/libunbound/ubsyms.def b/libunbound/ubsyms.def index 7a8c5852f..0d50a2b9e 100644 --- a/libunbound/ubsyms.def +++ b/libunbound/ubsyms.def @@ -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 diff --git a/libunbound/unbound.h b/libunbound/unbound.h index e9e5f6ebc..7a7a31fa9 100644 --- a/libunbound/unbound.h +++ b/libunbound/unbound.h @@ -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 */ diff --git a/pythonmod/LICENSE b/pythonmod/LICENSE new file mode 100644 index 000000000..7b769d091 --- /dev/null +++ b/pythonmod/LICENSE @@ -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. diff --git a/pythonmod/Makefile b/pythonmod/Makefile new file mode 100644 index 000000000..bf35bec72 --- /dev/null +++ b/pythonmod/Makefile @@ -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 diff --git a/pythonmod/doc/Makefile b/pythonmod/doc/Makefile new file mode 100644 index 000000000..b02935317 --- /dev/null +++ b/pythonmod/doc/Makefile @@ -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 ' where 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." + diff --git a/pythonmod/doc/source/conf.py b/pythonmod/doc/source/conf.py new file mode 100644 index 000000000..bc7a5aba6 --- /dev/null +++ b/pythonmod/doc/source/conf.py @@ -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 +# " v 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/. +html_copy_source = False + +# If true, an OpenSearch description file will be output, and all pages will +# contain a 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 diff --git a/pythonmod/doc/source/examples/example0-1.py b/pythonmod/doc/source/examples/example0-1.py new file mode 100644 index 000000000..98a9acccd --- /dev/null +++ b/pythonmod/doc/source/examples/example0-1.py @@ -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.") diff --git a/pythonmod/doc/source/examples/example0.rst b/pythonmod/doc/source/examples/example0.rst new file mode 100644 index 000000000..80eca5ea6 --- /dev/null +++ b/pythonmod/doc/source/examples/example0.rst @@ -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. + diff --git a/pythonmod/doc/source/examples/example1.rst b/pythonmod/doc/source/examples/example1.rst new file mode 100644 index 000000000..09d78035b --- /dev/null +++ b/pythonmod/doc/source/examples/example1.rst @@ -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 + [1231790168] unbound[7941:0] info: reply from 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 . + diff --git a/pythonmod/doc/source/examples/example2.rst b/pythonmod/doc/source/examples/example2.rst new file mode 100644 index 000000000..a0bfee4e5 --- /dev/null +++ b/pythonmod/doc/source/examples/example2.rst @@ -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. diff --git a/pythonmod/doc/source/examples/example3.rst b/pythonmod/doc/source/examples/example3.rst new file mode 100644 index 000000000..8ba43a8c7 --- /dev/null +++ b/pythonmod/doc/source/examples/example3.rst @@ -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. diff --git a/pythonmod/doc/source/examples/example4.rst b/pythonmod/doc/source/examples/example4.rst new file mode 100644 index 000000000..0f8353d68 --- /dev/null +++ b/pythonmod/doc/source/examples/example4.rst @@ -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 diff --git a/pythonmod/doc/source/examples/index.rst b/pythonmod/doc/source/examples/index.rst new file mode 100644 index 000000000..6c5022581 --- /dev/null +++ b/pythonmod/doc/source/examples/index.rst @@ -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* diff --git a/pythonmod/doc/source/index.rst b/pythonmod/doc/source/index.rst new file mode 100644 index 000000000..fe9bcf42b --- /dev/null +++ b/pythonmod/doc/source/index.rst @@ -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` + diff --git a/pythonmod/doc/source/install.rst b/pythonmod/doc/source/install.rst new file mode 100644 index 000000000..991e2b4be --- /dev/null +++ b/pythonmod/doc/source/install.rst @@ -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. diff --git a/pythonmod/doc/source/modules/config.rst b/pythonmod/doc/source/modules/config.rst new file mode 100644 index 000000000..1277bcedd --- /dev/null +++ b/pythonmod/doc/source/modules/config.rst @@ -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. diff --git a/pythonmod/doc/source/modules/env.rst b/pythonmod/doc/source/modules/env.rst new file mode 100644 index 000000000..42dbbd1cf --- /dev/null +++ b/pythonmod/doc/source/modules/env.rst @@ -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. diff --git a/pythonmod/doc/source/modules/functions.rst b/pythonmod/doc/source/modules/functions.rst new file mode 100644 index 000000000..45a469fec --- /dev/null +++ b/pythonmod/doc/source/modules/functions.rst @@ -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. diff --git a/pythonmod/doc/source/modules/index.rst b/pythonmod/doc/source/modules/index.rst new file mode 100644 index 000000000..ff0b95695 --- /dev/null +++ b/pythonmod/doc/source/modules/index.rst @@ -0,0 +1,11 @@ +Unbound module documentation +======================================= + +.. toctree:: + :maxdepth: 2 + + env + struct + functions + config + diff --git a/pythonmod/doc/source/modules/struct.rst b/pythonmod/doc/source/modules/struct.rst new file mode 100644 index 000000000..c41e10b73 --- /dev/null +++ b/pythonmod/doc/source/modules/struct.rst @@ -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). + diff --git a/pythonmod/doc/source/usecase.rst b/pythonmod/doc/source/usecase.rst new file mode 100644 index 000000000..7a77349f1 --- /dev/null +++ b/pythonmod/doc/source/usecase.rst @@ -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. diff --git a/pythonmod/examples/calc.py b/pythonmod/examples/calc.py new file mode 100644 index 000000000..3230e37e3 --- /dev/null +++ b/pythonmod/examples/calc.py @@ -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 + diff --git a/pythonmod/examples/dict.py b/pythonmod/examples/dict.py new file mode 100644 index 000000000..c8088a89c --- /dev/null +++ b/pythonmod/examples/dict.py @@ -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 + diff --git a/pythonmod/examples/dict_data.txt b/pythonmod/examples/dict_data.txt new file mode 100644 index 000000000..04cd3badf --- /dev/null +++ b/pythonmod/examples/dict_data.txt @@ -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á diff --git a/pythonmod/examples/log.py b/pythonmod/examples/log.py new file mode 100644 index 000000000..c17106b0f --- /dev/null +++ b/pythonmod/examples/log.py @@ -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 + diff --git a/pythonmod/examples/resgen.py b/pythonmod/examples/resgen.py new file mode 100644 index 000000000..804c0bd1d --- /dev/null +++ b/pythonmod/examples/resgen.py @@ -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 diff --git a/pythonmod/examples/resmod.py b/pythonmod/examples/resmod.py new file mode 100644 index 000000000..cf392e4da --- /dev/null +++ b/pythonmod/examples/resmod.py @@ -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 diff --git a/pythonmod/interface.i b/pythonmod/interface.i new file mode 100644 index 000000000..399cbd59a --- /dev/null +++ b/pythonmod/interface.i @@ -0,0 +1,803 @@ +/* + * interface.i: unbound python module + */ + +%module Unbound +%{ + #include + #include + #include + #include + #include + #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); diff --git a/pythonmod/pythonmod.c b/pythonmod/pythonmod.c new file mode 100644 index 000000000..10068aeb3 --- /dev/null +++ b/pythonmod/pythonmod.c @@ -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 + +// 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; +} diff --git a/pythonmod/pythonmod.h b/pythonmod/pythonmod.h new file mode 100644 index 000000000..a394e5960 --- /dev/null +++ b/pythonmod/pythonmod.h @@ -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 + +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 */ diff --git a/pythonmod/pythonmod_utils.c b/pythonmod/pythonmod_utils.c new file mode 100644 index 000000000..6ad6fde18 --- /dev/null +++ b/pythonmod/pythonmod_utils.c @@ -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 + +/** 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; jcount + 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; +} diff --git a/pythonmod/pythonmod_utils.h b/pythonmod/pythonmod_utils.h new file mode 100644 index 000000000..b2042ab1f --- /dev/null +++ b/pythonmod/pythonmod_utils.h @@ -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 */ diff --git a/pythonmod/test-calc.conf b/pythonmod/test-calc.conf new file mode 100644 index 000000000..47a9d2c22 --- /dev/null +++ b/pythonmod/test-calc.conf @@ -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: + # local-data: "" + # 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 diff --git a/pythonmod/test-dict.conf b/pythonmod/test-dict.conf new file mode 100644 index 000000000..8f032833f --- /dev/null +++ b/pythonmod/test-dict.conf @@ -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: + # local-data: "" + # 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 diff --git a/pythonmod/test-log.conf b/pythonmod/test-log.conf new file mode 100644 index 000000000..8237e6a89 --- /dev/null +++ b/pythonmod/test-log.conf @@ -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: + # local-data: "" + # 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 diff --git a/pythonmod/test-resgen.conf b/pythonmod/test-resgen.conf new file mode 100644 index 000000000..352ade176 --- /dev/null +++ b/pythonmod/test-resgen.conf @@ -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: + # local-data: "" + # 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 diff --git a/pythonmod/test-resmod.conf b/pythonmod/test-resmod.conf new file mode 100644 index 000000000..e716478c3 --- /dev/null +++ b/pythonmod/test-resmod.conf @@ -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: + # local-data: "" + # 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 diff --git a/pythonmod/ubmodule-msg.py b/pythonmod/ubmodule-msg.py new file mode 100644 index 000000000..d234d609f --- /dev/null +++ b/pythonmod/ubmodule-msg.py @@ -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.") diff --git a/pythonmod/ubmodule-tst.py b/pythonmod/ubmodule-tst.py new file mode 100644 index 000000000..d0d4cd442 --- /dev/null +++ b/pythonmod/ubmodule-tst.py @@ -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.") diff --git a/services/cache/dns.c b/services/cache/dns.c index 2164dd3b0..2e7ba642e 100644 --- a/services/cache/dns.c +++ b/services/cache/dns.c @@ -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; irep->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; diff --git a/services/localzone.c b/services/localzone.c index 3934ec626..1be05d153 100644 --- a/services/localzone.c +++ b/services/localzone.c @@ -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; diff --git a/services/localzone.h b/services/localzone.h index 1652a95af..687b89546 100644 --- a/services/localzone.h +++ b/services/localzone.h @@ -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 */ diff --git a/services/modstack.c b/services/modstack.c index fe352ff49..b9252ce7e 100644 --- a/services/modstack.c +++ b/services/modstack.c @@ -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 #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); diff --git a/util/config_file.c b/util/config_file.c index 758518022..59f54b0fc 100644 --- a/util/config_file.c +++ b/util/config_file.c @@ -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; diff --git a/util/config_file.h b/util/config_file.h index f50f863a7..b5f88239b 100644 --- a/util/config_file.h +++ b/util/config_file.h @@ -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 diff --git a/util/configlexer.c b/util/configlexer.c index d178422bf..d7dbde8ff 100644 --- a/util/configlexer.c +++ b/util/configlexer.c @@ -362,8 +362,8 @@ static void yy_fatal_error (yyconst char msg[] ); *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; -#define YY_NUM_RULES 115 -#define YY_END_OF_BUFFER 116 +#define YY_NUM_RULES 117 +#define YY_END_OF_BUFFER 118 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -371,126 +371,127 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_accept[1074] = +static yyconst flex_int16_t yy_accept[1088] = { 0, - 1, 1, 97, 97, 101, 101, 105, 105, 109, 109, - 1, 1, 116, 113, 1, 95, 95, 114, 113, 114, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 97, - 98, 98, 99, 114, 101, 102, 102, 103, 114, 108, - 105, 106, 106, 107, 114, 109, 110, 110, 111, 114, - 112, 96, 112, 100, 114, 112, 113, 0, 1, 0, - 113, 0, 2, 0, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 1, 1, 99, 99, 103, 103, 107, 107, 111, 111, + 1, 1, 118, 115, 1, 97, 97, 116, 115, 116, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 99, + 100, 100, 101, 116, 103, 104, 104, 105, 116, 110, + 107, 108, 108, 109, 116, 111, 112, 112, 113, 116, + 114, 98, 114, 102, 116, 114, 115, 0, 1, 0, + 115, 0, 2, 0, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 97, 0, 101, 0, 108, 0, 105, 109, 0, 112, - 0, 112, 0, 112, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 112, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 99, 0, 103, 0, 110, 0, 107, 111, 0, + 114, 0, 114, 0, 114, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 114, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 112, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 50, 113, 113, 113, 113, - 113, 6, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 112, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 114, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 50, 115, + 115, 115, 115, 115, 6, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 114, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 112, 113, 113, 20, 113, 113, 113, - 113, 12, 13, 113, 15, 14, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 3, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 112, 113, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 114, 115, + 115, 20, 115, 115, 115, 115, 12, 13, 115, 15, + 14, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 95, 115, 115, 115, 115, 3, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 104, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 23, 113, - 113, 113, 113, 113, 113, 113, 24, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 63, 104, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 62, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 115, 115, 115, 115, 115, 114, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 106, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 23, 115, 115, 115, 115, + 115, 115, 115, 24, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 63, + 106, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 62, 115, 115, 115, 115, 115, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 21, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 22, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 17, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 51, 52, 113, 49, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 5, 113, 113, 113, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 21, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 22, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 17, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 51, 52, 115, 49, 115, 115, 115, 115, 115, - 113, 113, 113, 113, 113, 65, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 81, 80, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 25, 113, 113, 113, 113, 53, - 113, 113, 113, 113, 113, 78, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 42, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 4, + 115, 115, 115, 115, 115, 115, 5, 115, 115, 115, + 115, 115, 115, 115, 115, 65, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 81, 80, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 25, 115, 115, 115, 115, + 53, 115, 115, 115, 115, 115, 78, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 42, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 89, 113, - 16, 113, 113, 113, 55, 56, 54, 113, 113, 113, - 113, 113, 61, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 69, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 31, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 60, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 4, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 89, 115, 16, 115, 115, 115, 55, 56, 54, 115, + 115, 115, 115, 115, 61, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 69, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 31, 115, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 64, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 71, 113, 113, 113, - 113, 59, 113, 87, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 32, - 33, 113, 38, 74, 113, 82, 79, 113, 27, 113, - 76, 113, 113, 113, 113, 113, 7, 113, 48, 86, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 66, 113, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 60, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 64, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 94, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 71, 115, 115, 115, 115, 59, 115, 87, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 32, 33, 115, 38, 74, 115, 82, + 79, 115, 27, 115, 76, 115, 115, 115, 115, 115, + 7, 115, 48, 86, 115, 115, 115, 115, 115, 115, - 113, 94, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 75, 26, 28, 113, 113, 113, 113, 113, - 47, 113, 113, 113, 90, 113, 113, 113, 113, 113, - 113, 45, 113, 113, 113, 113, 113, 113, 92, 113, - 113, 113, 113, 113, 113, 113, 11, 113, 113, 113, - 113, 113, 113, 10, 113, 113, 29, 113, 91, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 93, - 88, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 34, 113, 113, 113, 113, 113, 30, 113, 113, 113, - 67, 68, 113, 113, 113, 70, 113, 113, 113, 113, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 66, 115, 115, 96, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 75, 26, 28, 115, + 115, 115, 115, 115, 47, 115, 115, 115, 90, 115, + 115, 115, 115, 115, 115, 45, 115, 115, 115, 115, + 115, 115, 92, 115, 115, 115, 115, 115, 115, 115, + 11, 115, 115, 115, 115, 115, 115, 10, 115, 115, + 29, 115, 91, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 93, 88, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 34, 115, 115, 115, 115, 115, - 113, 113, 113, 113, 113, 113, 113, 113, 18, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 85, 113, 113, 113, 113, 113, 113, 19, 113, 9, - 113, 113, 83, 39, 113, 113, 113, 73, 57, 113, - 113, 41, 44, 40, 113, 35, 113, 8, 113, 113, - 72, 113, 113, 113, 36, 113, 84, 113, 113, 58, - 43, 37, 113, 113, 113, 113, 46, 113, 113, 113, - 113, 77, 0 + 30, 115, 115, 115, 67, 68, 115, 115, 115, 70, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 18, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 85, 115, 115, 115, 115, 115, + 115, 19, 115, 9, 115, 115, 83, 39, 115, 115, + 115, 73, 57, 115, 115, 41, 44, 40, 115, 35, + 115, 8, 115, 115, 72, 115, 115, 115, 36, 115, + 84, 115, 115, 58, 43, 37, 115, 115, 115, 115, + 46, 115, 115, 115, 115, 77, 0 } ; static yyconst flex_int32_t yy_ec[256] = @@ -533,253 +534,259 @@ static yyconst flex_int32_t yy_meta[40] = 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; -static yyconst flex_int16_t yy_base[1088] = +static yyconst flex_int16_t yy_base[1102] = { 0, 0, 0, 37, 40, 44, 51, 63, 75, 56, 68, - 87, 108, 2075, 2061, 50, 2157, 2157, 2157, 129, 94, + 87, 108, 2101, 2087, 50, 2184, 2184, 2184, 129, 94, 33, 124, 94, 49, 74, 61, 91, 92, 110, 111, - 112, 133, 50, 135, 137, 136, 145, 143, 159, 2060, - 2157, 2157, 2157, 122, 2058, 2157, 2157, 2157, 157, 2057, - 2067, 2157, 2157, 2157, 176, 2055, 2157, 2157, 2157, 180, - 2054, 2157, 184, 2157, 188, 90, 2052, 194, 198, 2061, - 205, 2060, 2157, 2059, 158, 166, 122, 116, 189, 181, - 206, 190, 198, 200, 208, 209, 217, 192, 202, 221, - 222, 225, 229, 231, 230, 213, 235, 234, 236, 240, + 112, 133, 50, 135, 137, 136, 145, 143, 164, 2086, + 2184, 2184, 2184, 122, 2084, 2184, 2184, 2184, 157, 2081, + 2091, 2184, 2184, 2184, 179, 2079, 2184, 2184, 2184, 167, + 2078, 2184, 185, 2184, 189, 90, 2077, 195, 199, 2086, + 206, 1658, 2184, 1620, 190, 199, 122, 116, 149, 182, + 208, 191, 201, 207, 209, 161, 212, 210, 147, 217, + 222, 216, 214, 228, 230, 231, 233, 234, 236, 238, - 241, 244, 246, 247, 249, 250, 251, 254, 72, 255, - 1981, 266, 1615, 271, 1560, 286, 875, 651, 269, 384, - 290, 296, 280, 266, 289, 283, 292, 293, 295, 302, - 314, 298, 301, 303, 272, 304, 305, 310, 311, 312, - 316, 320, 330, 332, 321, 344, 340, 346, 348, 347, - 349, 333, 337, 350, 351, 352, 356, 360, 147, 361, - 358, 362, 369, 372, 373, 370, 366, 374, 376, 381, - 383, 388, 393, 308, 390, 395, 396, 397, 401, 402, - 404, 412, 408, 410, 411, 413, 416, 417, 418, 420, - 419, 426, 425, 438, 423, 427, 433, 436, 443, 445, + 240, 239, 241, 244, 246, 248, 242, 249, 250, 72, + 256, 1547, 273, 880, 277, 812, 284, 736, 600, 278, + 526, 288, 294, 502, 287, 291, 281, 292, 293, 295, + 302, 314, 298, 301, 303, 257, 304, 305, 310, 311, + 312, 316, 320, 330, 332, 321, 344, 340, 346, 348, + 347, 349, 333, 337, 350, 351, 352, 356, 357, 360, + 362, 363, 365, 367, 374, 376, 375, 373, 378, 381, + 383, 382, 387, 388, 395, 308, 391, 399, 401, 403, + 393, 408, 410, 416, 404, 413, 414, 417, 419, 420, + 422, 421, 423, 426, 428, 436, 430, 441, 431, 442, - 446, 442, 454, 448, 455, 456, 463, 459, 457, 461, - 466, 467, 486, 472, 470, 471, 474, 478, 476, 480, - 483, 484, 494, 507, 490, 497, 506, 509, 508, 511, - 514, 515, 482, 516, 517, 530, 521, 531, 518, 538, - 532, 534, 535, 539, 542, 2157, 544, 547, 548, 549, - 550, 2157, 551, 552, 553, 559, 555, 563, 564, 566, - 574, 567, 575, 570, 577, 581, 585, 583, 584, 588, - 589, 592, 594, 604, 600, 610, 591, 601, 611, 605, - 620, 622, 617, 624, 626, 632, 628, 630, 636, 635, - 637, 629, 638, 640, 644, 645, 653, 655, 657, 650, + 445, 447, 449, 452, 453, 460, 456, 458, 459, 466, + 464, 462, 465, 471, 470, 491, 472, 477, 475, 478, + 485, 481, 483, 488, 489, 495, 512, 499, 502, 504, + 511, 513, 514, 515, 521, 522, 523, 524, 539, 535, + 537, 544, 551, 538, 516, 548, 536, 549, 2184, 554, + 540, 552, 556, 558, 2184, 559, 562, 563, 564, 571, + 567, 569, 573, 575, 582, 578, 583, 580, 590, 586, + 592, 593, 594, 597, 596, 603, 606, 613, 607, 622, + 611, 609, 614, 619, 626, 628, 634, 631, 636, 638, + 637, 639, 645, 644, 641, 647, 649, 650, 653, 651, - 659, 665, 662, 666, 667, 671, 672, 673, 674, 675, - 682, 684, 678, 696, 685, 688, 686, 689, 694, 702, - 698, 700, 703, 706, 710, 711, 712, 713, 715, 716, - 714, 717, 723, 725, 728, 733, 2157, 740, 727, 736, - 738, 2157, 2157, 739, 2157, 2157, 741, 742, 748, 757, - 747, 749, 754, 759, 755, 765, 763, 770, 774, 760, - 773, 782, 772, 784, 786, 788, 790, 792, 793, 794, - 797, 798, 804, 811, 807, 795, 813, 815, 2157, 799, - 816, 817, 819, 821, 823, 824, 827, 830, 825, 831, - 832, 833, 839, 842, 841, 847, 846, 849, 851, 852, + 660, 659, 666, 658, 663, 674, 672, 673, 677, 679, + 657, 681, 682, 683, 690, 691, 693, 694, 701, 698, + 699, 704, 705, 706, 712, 708, 710, 711, 713, 715, + 717, 720, 726, 728, 732, 722, 735, 724, 736, 739, + 745, 2184, 748, 747, 749, 751, 2184, 2184, 750, 2184, + 2184, 752, 754, 760, 768, 759, 753, 756, 763, 769, + 773, 770, 777, 779, 783, 784, 788, 790, 791, 794, + 795, 800, 799, 801, 797, 808, 804, 817, 819, 802, + 2184, 820, 810, 825, 827, 2184, 822, 828, 818, 833, + 829, 834, 835, 841, 844, 839, 845, 846, 847, 852, - 853, 878, 855, 856, 858, 861, 862, 868, 884, 865, - 857, 873, 870, 888, 886, 890, 898, 2157, 904, 902, - 893, 895, 901, 907, 913, 891, 903, 919, 2157, 915, - 920, 921, 922, 923, 928, 936, 2157, 933, 924, 935, - 938, 940, 942, 943, 944, 948, 950, 949, 951, 957, - 953, 966, 970, 952, 959, 969, 971, 976, 973, 974, - 975, 2157, 215, 978, 982, 979, 980, 981, 993, 986, - 990, 987, 997, 999, 996, 1002, 1003, 1008, 1009, 1010, - 1011, 1012, 1013, 1016, 1014, 1017, 2157, 1022, 1020, 1018, - 1035, 1042, 1033, 1044, 1047, 1045, 1051, 1043, 1049, 1058, + 856, 854, 850, 855, 861, 865, 862, 866, 891, 867, + 869, 871, 874, 873, 881, 878, 883, 870, 888, 893, + 901, 899, 903, 906, 2184, 915, 908, 912, 914, 916, + 917, 918, 919, 920, 929, 2184, 925, 928, 930, 932, + 936, 941, 943, 2184, 946, 948, 944, 949, 952, 953, + 956, 954, 960, 962, 963, 965, 966, 964, 968, 977, + 980, 973, 984, 974, 981, 989, 986, 987, 990, 2184, + 259, 991, 997, 994, 998, 1000, 1001, 1002, 1008, 1003, + 1009, 1011, 1010, 1013, 1019, 1020, 1022, 1024, 1025, 1026, + 1027, 1030, 1028, 1031, 2184, 1036, 1034, 1038, 1047, 1054, - 1059, 1055, 1061, 1062, 1064, 1066, 1056, 1063, 1069, 1072, - 1073, 1074, 1084, 1086, 1087, 1089, 1075, 1091, 1096, 1079, - 1094, 1102, 2157, 1108, 1110, 1111, 1104, 1107, 1115, 1112, - 1116, 1117, 1118, 1120, 1121, 1123, 2157, 1129, 615, 1125, - 1122, 1130, 1133, 1134, 1131, 1138, 1139, 1142, 1147, 1148, - 1151, 1154, 1155, 1156, 1163, 1164, 1167, 2157, 1165, 1162, - 1178, 1172, 1174, 1179, 1180, 1182, 1183, 1184, 1186, 1190, - 1187, 1191, 1188, 1192, 1194, 1195, 1198, 1209, 1199, 1216, - 1217, 2157, 2157, 1221, 2157, 1210, 1218, 1200, 1222, 1223, - 1229, 1224, 1230, 1226, 1232, 1234, 2157, 1239, 1235, 1240, + 1051, 1060, 1056, 1061, 1062, 1059, 1065, 1072, 1074, 1070, + 1076, 1068, 1081, 1078, 1071, 1087, 1079, 1088, 1090, 1091, + 1092, 1095, 1100, 1097, 1104, 1105, 1106, 1107, 1109, 1113, + 1110, 2184, 1120, 1123, 1126, 1122, 1124, 1129, 1130, 1132, + 1133, 1134, 1136, 1137, 1139, 2184, 1145, 1138, 1141, 1142, + 1146, 1149, 1148, 1154, 1155, 1158, 1165, 1170, 1160, 1171, + 1161, 1169, 1177, 1184, 1186, 1187, 2184, 1189, 1173, 1196, + 1198, 1183, 1193, 1205, 1185, 1201, 1203, 1206, 1207, 1208, + 1209, 1210, 1212, 1213, 1214, 1215, 1218, 1227, 1219, 1233, + 1236, 2184, 2184, 1238, 2184, 1240, 1230, 1234, 1241, 1242, - 1025, 1241, 1247, 1243, 1245, 2157, 1249, 1248, 1256, 1261, - 1250, 1252, 1264, 1265, 1267, 1271, 1274, 1258, 1275, 1277, - 1280, 1284, 1281, 1282, 1283, 1285, 1287, 1289, 2157, 2157, - 1294, 1298, 1290, 1303, 1308, 1311, 1314, 1310, 1316, 1318, - 1319, 1320, 1321, 1323, 2157, 1331, 1332, 1328, 1337, 2157, - 1335, 1324, 1325, 1339, 1345, 2157, 1347, 1348, 1349, 1351, - 1350, 1353, 1357, 1365, 1358, 1361, 1366, 1374, 1362, 1376, - 1382, 1364, 1378, 1381, 1384, 1387, 1388, 2157, 1394, 1390, - 1397, 1393, 1396, 1404, 1400, 1401, 1402, 1403, 1405, 1406, - 1409, 1407, 1411, 1417, 1416, 1413, 1428, 1415, 1430, 2157, + 1248, 1244, 1249, 1251, 1252, 1253, 2184, 1255, 1254, 1258, + 1039, 1260, 1266, 1263, 1269, 2184, 1271, 1267, 1277, 1281, + 1268, 1270, 1279, 1288, 1295, 1291, 1285, 1287, 1289, 1297, + 1299, 1305, 1298, 1301, 1302, 1304, 1308, 1306, 2184, 2184, + 1310, 1315, 1314, 1316, 1326, 1332, 1330, 1331, 1334, 1336, + 1338, 1337, 1339, 1341, 1342, 2184, 1348, 1349, 1350, 1358, + 2184, 1345, 1346, 1359, 1363, 1362, 2184, 1365, 1366, 1368, + 1369, 1372, 1371, 1375, 1382, 1376, 1383, 1384, 1392, 1389, + 1394, 1400, 1396, 1399, 1403, 1405, 1407, 1408, 2184, 1414, + 1397, 1418, 1410, 1421, 1427, 1412, 1416, 1423, 1425, 1428, - 1431, 1438, 1434, 1435, 1440, 1443, 1444, 1437, 1447, 1448, - 1449, 1450, 1460, 1463, 1466, 1465, 1472, 1468, 1469, 1451, - 1479, 1471, 1475, 1482, 1478, 1483, 1485, 1486, 2157, 1489, - 2157, 1496, 1492, 1490, 2157, 2157, 2157, 1503, 751, 1504, - 1286, 1507, 2157, 1494, 1511, 1500, 1513, 1515, 1516, 1502, - 1509, 1518, 1520, 1519, 1524, 1531, 1526, 1534, 1536, 1535, - 1541, 1532, 1542, 1548, 1544, 1545, 1547, 1551, 1556, 1557, - 1555, 1558, 1553, 1554, 1569, 2157, 1572, 1559, 1574, 1577, - 1579, 1580, 1581, 1582, 1590, 2157, 1586, 1592, 1593, 1596, - 1597, 1600, 1598, 1601, 1603, 1605, 1607, 1609, 1610, 2157, + 1429, 1432, 1430, 1437, 1434, 1438, 1439, 1451, 1440, 1442, + 2184, 1448, 1459, 1444, 1456, 1457, 1460, 1461, 1467, 1468, + 1470, 1471, 1472, 1474, 1478, 1484, 1490, 1477, 1491, 1492, + 1494, 1475, 1501, 1495, 1497, 1503, 1499, 1506, 1507, 1510, + 2184, 1508, 2184, 1514, 1512, 1516, 2184, 2184, 2184, 1523, + 1521, 1527, 1522, 1532, 2184, 1529, 1533, 1535, 1536, 1539, + 1540, 1542, 1541, 1545, 1544, 1537, 1553, 1559, 1543, 1560, + 1564, 1563, 1567, 1570, 1554, 1576, 1573, 1575, 1577, 1580, + 1581, 1583, 1587, 1585, 1586, 1582, 1584, 1598, 2184, 1601, + 1589, 1603, 1606, 1608, 1590, 1611, 1613, 1620, 2184, 1616, - 1611, 1612, 1616, 1617, 1620, 1627, 1623, 1633, 1635, 1630, - 1638, 1640, 2157, 1641, 1643, 1644, 1648, 1650, 1645, 1652, - 1653, 1657, 1658, 1660, 1662, 1664, 1665, 1667, 1670, 1671, - 1673, 1672, 1674, 1676, 1686, 1680, 2157, 1682, 1688, 1693, - 1696, 2157, 1689, 2157, 1695, 1699, 1706, 1703, 1708, 1710, - 1700, 1712, 1713, 1719, 1715, 1717, 1722, 1716, 1723, 2157, - 2157, 1728, 2157, 2157, 1731, 2157, 2157, 1735, 2157, 1737, - 2157, 1743, 1739, 1726, 1741, 1744, 2157, 1746, 2157, 2157, - 1747, 1748, 1751, 1754, 1755, 1757, 1758, 1759, 1760, 1761, - 1765, 1768, 1762, 1766, 1769, 1773, 1774, 1784, 2157, 1776, + 1622, 1623, 1626, 1627, 1629, 1628, 1630, 1631, 1634, 1636, + 1637, 1639, 2184, 1641, 1642, 1645, 1646, 1652, 1662, 1654, + 1664, 1666, 1640, 1669, 1671, 2184, 1672, 1674, 1656, 1679, + 1676, 1680, 1681, 1682, 1688, 1685, 1690, 2184, 1692, 1693, + 1695, 1697, 1700, 1699, 1701, 1702, 1703, 1707, 1713, 1710, + 2184, 1711, 1715, 1721, 1723, 2184, 1725, 2184, 1726, 1727, + 1734, 1735, 1738, 1743, 1728, 1730, 1740, 1749, 1746, 1747, + 1751, 1753, 1755, 2184, 2184, 1758, 2184, 2184, 1765, 2184, + 2184, 1767, 2184, 1769, 2184, 1775, 1771, 1760, 1762, 1773, + 2184, 1780, 2184, 2184, 1777, 1781, 1785, 1787, 1788, 1736, - 1789, 2157, 1787, 1780, 1785, 1791, 1792, 1800, 1802, 1793, - 1795, 1801, 2157, 2157, 2157, 1804, 1806, 1813, 1805, 1810, - 2157, 1816, 1817, 1819, 2157, 1822, 1825, 1826, 1827, 1829, - 1830, 2157, 1831, 1837, 1839, 1833, 1841, 1850, 2157, 1851, - 1843, 1854, 1852, 1853, 1858, 1860, 2157, 1845, 1863, 1866, - 1867, 1870, 1868, 2157, 1871, 1872, 2157, 1875, 2157, 1877, - 1883, 1886, 1888, 1891, 1881, 1879, 1900, 1902, 1892, 2157, - 2157, 1894, 1898, 1903, 1904, 1905, 1907, 1908, 1909, 1911, - 2157, 1912, 1914, 1917, 1919, 1921, 2157, 1924, 1925, 1926, - 2157, 2157, 1935, 1928, 1936, 2157, 1938, 1939, 1941, 1947, + 1789, 1791, 1792, 1774, 1796, 1793, 1797, 1798, 1799, 1805, + 1806, 1808, 2184, 1809, 1813, 2184, 1815, 1816, 1817, 1820, + 1819, 1822, 1830, 1826, 1828, 1829, 2184, 2184, 2184, 1831, + 1837, 1833, 1839, 1842, 2184, 1844, 1845, 1853, 2184, 1855, + 1846, 1848, 1858, 1861, 1859, 2184, 1850, 1869, 1870, 1862, + 1872, 1879, 2184, 1876, 1873, 1880, 1882, 1884, 1886, 1888, + 2184, 1889, 1890, 1895, 1892, 1896, 1898, 2184, 1902, 1899, + 2184, 1906, 2184, 1900, 1913, 1907, 1916, 1918, 1919, 1921, + 1927, 1924, 1925, 2184, 2184, 1926, 1928, 1930, 1931, 1933, + 1932, 1934, 1939, 1941, 2184, 1940, 1944, 1951, 1942, 1954, - 1944, 1942, 1949, 1948, 1950, 1952, 1955, 1959, 2157, 1963, - 1965, 1966, 1968, 1970, 1972, 1974, 1973, 1978, 1980, 1975, - 2157, 1982, 1984, 1990, 1996, 1992, 1999, 2157, 2000, 2157, - 2003, 2004, 2157, 2157, 2005, 2007, 2010, 2157, 2157, 2008, - 2012, 2157, 2157, 2157, 2018, 2157, 2019, 2157, 2021, 2011, - 2157, 2014, 2025, 2030, 2157, 2034, 2157, 2027, 2035, 2157, - 2157, 2157, 2037, 2022, 2044, 2031, 2157, 2038, 2045, 2046, - 2048, 2157, 2157, 2078, 2084, 2090, 2096, 2102, 94, 2108, - 2114, 2120, 2126, 2132, 2138, 2144, 2150 + 2184, 1955, 1953, 1956, 2184, 2184, 1966, 1957, 1959, 2184, + 1967, 1969, 1970, 1974, 1975, 1976, 1978, 1977, 1979, 1980, + 1984, 1987, 2184, 1990, 1993, 1994, 1997, 2001, 1998, 2002, + 2003, 2007, 2009, 2010, 2184, 2015, 2012, 2019, 2022, 2025, + 2027, 2184, 2031, 2184, 2034, 2035, 2184, 2184, 2028, 2038, + 2039, 2184, 2184, 2004, 2041, 2184, 2184, 2184, 2043, 2184, + 2046, 2184, 2048, 2049, 2184, 2051, 2053, 2055, 2184, 2057, + 2184, 2058, 2059, 2184, 2184, 2184, 2061, 2062, 2067, 2063, + 2184, 2068, 2071, 2073, 2075, 2184, 2184, 2105, 2111, 2117, + 2123, 2129, 94, 2135, 2141, 2147, 2153, 2159, 2165, 2171, + + 2177 } ; -static yyconst flex_int16_t yy_def[1088] = +static yyconst flex_int16_t yy_def[1102] = { 0, - 1073, 1, 1074, 1074, 1075, 1075, 1076, 1076, 1077, 1077, - 1078, 1078, 1073, 1079, 1073, 1073, 1073, 1073, 1080, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1081, - 1073, 1073, 1073, 1081, 1082, 1073, 1073, 1073, 1082, 1083, - 1073, 1073, 1073, 1073, 1083, 1084, 1073, 1073, 1073, 1084, - 1085, 1073, 1086, 1073, 1085, 1085, 1079, 1079, 1073, 1087, - 1080, 1087, 1073, 1080, 1079, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, + 1087, 1, 1088, 1088, 1089, 1089, 1090, 1090, 1091, 1091, + 1092, 1092, 1087, 1093, 1087, 1087, 1087, 1087, 1094, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1095, + 1087, 1087, 1087, 1095, 1096, 1087, 1087, 1087, 1096, 1097, + 1087, 1087, 1087, 1087, 1097, 1098, 1087, 1087, 1087, 1098, + 1099, 1087, 1100, 1087, 1099, 1099, 1093, 1093, 1087, 1101, + 1094, 1101, 1087, 1094, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 1081, 1081, 1082, 1082, 1083, 1083, 1073, 1084, 1084, 1085, - 1085, 1086, 1086, 1085, 1079, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1085, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1095, 1095, 1096, 1096, 1097, 1097, 1087, 1098, 1098, + 1099, 1099, 1100, 1100, 1099, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1099, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1085, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1073, 1079, 1079, 1079, 1079, - 1079, 1073, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1085, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1099, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1087, 1093, + 1093, 1093, 1093, 1093, 1087, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1099, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1085, 1079, 1079, 1073, 1079, 1079, 1079, - 1079, 1073, 1073, 1079, 1073, 1073, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1073, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1085, 1079, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1099, 1093, + 1093, 1087, 1093, 1093, 1093, 1093, 1087, 1087, 1093, 1087, + 1087, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1087, 1093, 1093, 1093, 1093, 1087, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1073, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1073, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1073, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 1079, 1073, 1085, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1073, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, + 1093, 1093, 1093, 1093, 1093, 1099, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1087, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1087, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1087, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1087, + 1099, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1087, 1093, 1093, 1093, 1093, 1093, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1073, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1073, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1073, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 1079, 1073, 1073, 1079, 1073, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1073, 1079, 1079, 1079, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1087, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1087, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1087, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1087, 1087, 1093, 1087, 1093, 1093, 1093, 1093, 1093, - 1079, 1079, 1079, 1079, 1079, 1073, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1073, 1073, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1073, 1079, 1079, 1079, 1079, 1073, - 1079, 1079, 1079, 1079, 1079, 1073, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1073, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1073, + 1093, 1093, 1093, 1093, 1093, 1093, 1087, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1087, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1087, 1087, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1087, 1093, 1093, 1093, 1093, + 1087, 1093, 1093, 1093, 1093, 1093, 1087, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1087, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1073, 1079, - 1073, 1079, 1079, 1079, 1073, 1073, 1073, 1079, 1079, 1079, - 1079, 1079, 1073, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1073, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1073, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1073, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1087, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1087, 1093, 1087, 1093, 1093, 1093, 1087, 1087, 1087, 1093, + 1093, 1093, 1093, 1093, 1087, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1087, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1087, 1093, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1073, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1073, 1079, 1079, 1079, - 1079, 1073, 1079, 1073, 1079, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1073, - 1073, 1079, 1073, 1073, 1079, 1073, 1073, 1079, 1073, 1079, - 1073, 1079, 1079, 1079, 1079, 1079, 1073, 1079, 1073, 1073, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1073, 1079, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1087, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1087, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1087, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1087, 1093, 1093, 1093, 1093, 1087, 1093, 1087, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1087, 1087, 1093, 1087, 1087, 1093, 1087, + 1087, 1093, 1087, 1093, 1087, 1093, 1093, 1093, 1093, 1093, + 1087, 1093, 1087, 1087, 1093, 1093, 1093, 1093, 1093, 1093, - 1079, 1073, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1073, 1073, 1073, 1079, 1079, 1079, 1079, 1079, - 1073, 1079, 1079, 1079, 1073, 1079, 1079, 1079, 1079, 1079, - 1079, 1073, 1079, 1079, 1079, 1079, 1079, 1079, 1073, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1073, 1079, 1079, 1079, - 1079, 1079, 1079, 1073, 1079, 1079, 1073, 1079, 1073, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1073, - 1073, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 1073, 1079, 1079, 1079, 1079, 1079, 1073, 1079, 1079, 1079, - 1073, 1073, 1079, 1079, 1079, 1073, 1079, 1079, 1079, 1079, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1087, 1093, 1093, 1087, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1087, 1087, 1087, 1093, + 1093, 1093, 1093, 1093, 1087, 1093, 1093, 1093, 1087, 1093, + 1093, 1093, 1093, 1093, 1093, 1087, 1093, 1093, 1093, 1093, + 1093, 1093, 1087, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1087, 1093, 1093, 1093, 1093, 1093, 1093, 1087, 1093, 1093, + 1087, 1093, 1087, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1087, 1087, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1087, 1093, 1093, 1093, 1093, 1093, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1073, 1079, - 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 1073, 1079, 1079, 1079, 1079, 1079, 1079, 1073, 1079, 1073, - 1079, 1079, 1073, 1073, 1079, 1079, 1079, 1073, 1073, 1079, - 1079, 1073, 1073, 1073, 1079, 1073, 1079, 1073, 1079, 1079, - 1073, 1079, 1079, 1079, 1073, 1079, 1073, 1079, 1079, 1073, - 1073, 1073, 1079, 1079, 1079, 1079, 1073, 1079, 1079, 1079, - 1079, 1073, 0, 1073, 1073, 1073, 1073, 1073, 1073, 1073, - 1073, 1073, 1073, 1073, 1073, 1073, 1073 + 1087, 1093, 1093, 1093, 1087, 1087, 1093, 1093, 1093, 1087, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1087, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1087, 1093, 1093, 1093, 1093, 1093, + 1093, 1087, 1093, 1087, 1093, 1093, 1087, 1087, 1093, 1093, + 1093, 1087, 1087, 1093, 1093, 1087, 1087, 1087, 1093, 1087, + 1093, 1087, 1093, 1093, 1087, 1093, 1093, 1093, 1087, 1093, + 1087, 1093, 1093, 1087, 1087, 1087, 1093, 1093, 1093, 1093, + 1087, 1093, 1093, 1093, 1093, 1087, 0, 1087, 1087, 1087, + 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, + + 1087 } ; -static yyconst flex_int16_t yy_nxt[2197] = +static yyconst flex_int16_t yy_nxt[2224] = { 0, 14, 15, 16, 17, 18, 19, 18, 14, 14, 14, 14, 18, 20, 21, 14, 22, 23, 24, 25, 14, @@ -790,242 +797,245 @@ static yyconst flex_int16_t yy_nxt[2197] = 59, 68, 68, 49, 51, 52, 53, 54, 60, 18, 57, 58, 59, 68, 84, 55, 51, 52, 53, 54, 60, 18, 85, 96, 68, 82, 68, 55, 15, 16, - 17, 62, 63, 64, 67, 67, 164, 67, 67, 65, + 17, 62, 63, 64, 67, 67, 166, 67, 67, 65, - 67, 83, 121, 68, 68, 67, 68, 86, 66, 15, - 16, 17, 62, 63, 64, 79, 124, 87, 80, 88, - 65, 81, 68, 68, 68, 111, 111, 89, 68, 66, + 67, 83, 122, 68, 68, 67, 68, 86, 66, 15, + 16, 17, 62, 63, 64, 79, 125, 87, 80, 88, + 65, 81, 68, 68, 68, 112, 112, 89, 68, 66, 72, 73, 72, 72, 68, 72, 68, 76, 90, 91, - 72, 74, 128, 92, 77, 68, 93, 68, 68, 68, - 94, 78, 127, 103, 100, 68, 97, 68, 105, 68, - 113, 207, 98, 113, 101, 99, 95, 102, 104, 107, - 68, 68, 109, 125, 108, 106, 110, 115, 68, 115, - 115, 126, 115, 118, 118, 72, 73, 72, 72, 120, - 72, 120, 120, 68, 120, 67, 123, 67, 67, 69, + 72, 74, 129, 92, 77, 68, 93, 68, 68, 68, + 94, 78, 128, 104, 101, 68, 97, 68, 106, 68, + 114, 68, 98, 114, 102, 99, 95, 103, 105, 108, + 119, 119, 100, 68, 109, 107, 68, 110, 138, 130, + 116, 111, 116, 116, 143, 116, 72, 73, 72, 72, + 121, 72, 121, 121, 68, 121, 67, 124, 67, 67, - 67, 68, 68, 70, 68, 67, 72, 73, 72, 72, - 68, 72, 68, 131, 68, 130, 72, 74, 68, 129, - 68, 68, 133, 141, 136, 68, 137, 121, 134, 68, - 135, 132, 138, 68, 68, 139, 143, 68, 145, 142, - 144, 68, 68, 68, 146, 150, 68, 68, 68, 140, - 148, 151, 68, 68, 147, 149, 68, 153, 68, 68, - 158, 68, 68, 68, 152, 154, 68, 68, 155, 111, - 111, 163, 118, 118, 113, 156, 157, 113, 121, 160, - 159, 166, 73, 161, 68, 165, 162, 115, 181, 115, - 115, 120, 115, 120, 120, 68, 120, 72, 73, 72, + 69, 67, 68, 68, 70, 126, 67, 72, 73, 72, + 72, 68, 72, 68, 127, 132, 131, 72, 74, 68, + 68, 68, 68, 134, 68, 137, 68, 139, 68, 68, + 140, 135, 144, 133, 68, 147, 145, 136, 146, 148, + 68, 142, 68, 68, 141, 68, 68, 149, 68, 152, + 68, 68, 68, 68, 68, 150, 68, 154, 68, 160, + 68, 68, 68, 151, 153, 156, 157, 165, 68, 68, + 155, 122, 158, 183, 159, 163, 112, 112, 162, 161, + 114, 119, 119, 114, 164, 116, 167, 116, 116, 121, + 116, 121, 121, 68, 121, 72, 73, 72, 72, 122, - 72, 68, 72, 168, 68, 68, 167, 68, 123, 172, - 68, 178, 171, 68, 68, 68, 68, 68, 179, 169, - 68, 182, 68, 68, 68, 170, 68, 189, 68, 187, - 173, 183, 68, 68, 184, 174, 224, 185, 180, 191, - 175, 186, 68, 190, 68, 68, 176, 177, 188, 68, - 192, 194, 68, 196, 193, 197, 68, 195, 68, 68, - 68, 68, 68, 68, 68, 200, 198, 199, 68, 204, - 68, 201, 68, 68, 68, 210, 211, 202, 68, 213, - 208, 68, 121, 203, 68, 68, 68, 214, 68, 209, - 205, 218, 206, 68, 216, 68, 121, 217, 221, 212, + 72, 170, 168, 68, 68, 68, 124, 68, 169, 174, + 68, 180, 173, 68, 68, 68, 68, 68, 181, 171, + 68, 184, 68, 68, 68, 172, 68, 191, 68, 189, + 175, 185, 68, 68, 186, 176, 227, 187, 182, 193, + 177, 188, 68, 192, 68, 68, 178, 179, 190, 68, + 194, 196, 68, 198, 195, 199, 68, 197, 68, 68, + 68, 68, 68, 68, 68, 202, 200, 201, 68, 68, + 204, 203, 68, 207, 68, 68, 210, 68, 205, 68, + 213, 214, 211, 216, 206, 122, 68, 68, 68, 217, + 68, 208, 209, 68, 68, 68, 212, 219, 221, 68, - 68, 222, 68, 219, 215, 68, 223, 68, 68, 68, - 226, 220, 227, 68, 68, 230, 68, 225, 228, 232, - 68, 231, 68, 68, 68, 68, 236, 229, 68, 68, - 68, 68, 68, 239, 246, 68, 235, 68, 68, 68, - 233, 238, 247, 234, 240, 68, 237, 242, 68, 243, - 68, 241, 244, 245, 68, 68, 252, 68, 68, 253, - 68, 255, 248, 250, 251, 249, 68, 68, 68, 68, - 259, 68, 257, 68, 254, 68, 260, 258, 68, 68, - 256, 263, 68, 121, 68, 275, 68, 262, 68, 261, - 68, 272, 68, 265, 68, 68, 68, 264, 68, 271, + 68, 225, 224, 68, 215, 68, 218, 68, 226, 220, + 222, 68, 223, 68, 229, 68, 68, 230, 228, 232, + 68, 233, 68, 235, 231, 68, 68, 234, 68, 68, + 239, 68, 68, 68, 68, 68, 236, 242, 68, 238, + 68, 249, 68, 68, 241, 243, 237, 245, 68, 240, + 247, 248, 246, 68, 68, 244, 250, 68, 255, 68, + 251, 68, 256, 252, 68, 68, 254, 259, 68, 253, + 68, 68, 68, 263, 68, 261, 68, 68, 68, 257, + 262, 264, 68, 68, 68, 258, 267, 122, 260, 68, + 68, 266, 279, 68, 265, 68, 269, 68, 276, 275, - 266, 267, 68, 292, 273, 274, 68, 277, 276, 68, - 279, 280, 268, 269, 270, 278, 281, 282, 68, 68, - 68, 68, 283, 68, 287, 284, 68, 68, 68, 68, - 68, 298, 293, 68, 285, 286, 290, 295, 294, 296, - 289, 288, 68, 68, 68, 299, 68, 68, 297, 291, - 68, 68, 302, 300, 68, 304, 68, 305, 301, 68, - 68, 68, 68, 68, 68, 68, 313, 68, 307, 311, - 308, 68, 303, 312, 309, 68, 68, 316, 68, 68, - 306, 321, 68, 310, 317, 314, 68, 68, 324, 68, - 326, 322, 318, 68, 315, 68, 68, 68, 320, 323, + 68, 68, 268, 68, 73, 270, 271, 68, 277, 278, + 281, 68, 284, 280, 68, 283, 68, 272, 273, 274, + 282, 285, 286, 68, 68, 68, 68, 68, 68, 291, + 288, 287, 289, 68, 68, 68, 68, 290, 122, 297, + 305, 293, 294, 296, 292, 298, 299, 68, 68, 68, + 68, 68, 68, 300, 301, 295, 68, 302, 303, 304, + 68, 68, 308, 68, 68, 306, 68, 309, 68, 307, + 68, 68, 311, 310, 68, 68, 68, 312, 318, 68, + 316, 68, 313, 68, 317, 68, 321, 68, 315, 326, + 68, 314, 68, 322, 68, 68, 329, 319, 68, 327, - 68, 68, 319, 68, 68, 331, 121, 325, 327, 328, - 334, 335, 68, 68, 329, 338, 68, 68, 330, 333, - 332, 337, 68, 68, 344, 336, 340, 68, 339, 68, - 341, 342, 68, 343, 68, 345, 68, 346, 68, 347, - 68, 68, 68, 350, 68, 348, 349, 68, 68, 68, - 68, 351, 68, 607, 352, 354, 68, 68, 359, 356, - 360, 353, 68, 119, 357, 68, 355, 68, 358, 68, - 361, 68, 366, 362, 68, 364, 365, 68, 68, 68, - 367, 368, 369, 68, 68, 68, 68, 68, 370, 375, - 68, 373, 374, 377, 68, 363, 68, 68, 68, 372, + 320, 323, 68, 331, 68, 68, 68, 325, 68, 68, + 328, 324, 120, 332, 336, 68, 333, 330, 122, 68, + 340, 68, 339, 68, 334, 68, 68, 337, 335, 345, + 338, 68, 341, 342, 68, 343, 344, 347, 68, 348, + 68, 349, 350, 68, 346, 352, 68, 351, 68, 68, + 68, 68, 355, 68, 353, 354, 68, 68, 357, 68, + 356, 68, 68, 68, 364, 68, 359, 365, 361, 68, + 68, 68, 68, 362, 366, 68, 360, 363, 68, 358, + 370, 371, 367, 369, 68, 68, 68, 376, 373, 68, + 372, 68, 374, 68, 68, 68, 375, 380, 382, 378, - 68, 68, 371, 378, 381, 376, 68, 379, 68, 385, - 68, 386, 68, 382, 68, 68, 387, 380, 68, 383, - 388, 384, 68, 68, 68, 68, 68, 68, 68, 68, - 393, 392, 394, 395, 389, 68, 391, 121, 397, 68, - 68, 390, 399, 400, 396, 68, 401, 402, 68, 398, - 68, 68, 68, 68, 68, 409, 404, 403, 408, 68, - 68, 68, 407, 68, 415, 405, 68, 68, 406, 68, - 418, 68, 68, 410, 419, 68, 411, 68, 420, 416, - 797, 412, 68, 422, 68, 68, 68, 413, 414, 423, - 421, 417, 424, 425, 68, 426, 68, 429, 68, 427, + 379, 381, 68, 68, 368, 68, 68, 377, 385, 384, + 68, 68, 386, 68, 383, 388, 68, 68, 68, 392, + 68, 393, 68, 68, 68, 68, 394, 68, 395, 68, + 387, 389, 68, 391, 68, 390, 68, 118, 68, 399, + 68, 396, 398, 400, 68, 401, 397, 68, 122, 402, + 405, 68, 403, 406, 407, 409, 404, 68, 408, 68, + 68, 68, 68, 68, 68, 68, 68, 416, 68, 411, + 415, 68, 68, 414, 425, 68, 422, 410, 412, 413, + 68, 68, 68, 423, 417, 68, 427, 418, 426, 68, + 429, 68, 419, 424, 430, 68, 68, 428, 420, 421, - 68, 428, 68, 430, 68, 68, 68, 68, 431, 68, - 68, 68, 432, 433, 435, 437, 68, 436, 438, 68, - 444, 440, 439, 68, 434, 68, 441, 68, 68, 68, - 442, 68, 445, 68, 451, 68, 68, 68, 443, 68, - 447, 449, 68, 68, 68, 68, 452, 448, 446, 455, - 450, 68, 457, 68, 68, 454, 453, 458, 68, 68, - 462, 68, 463, 121, 68, 68, 456, 68, 68, 68, - 68, 459, 460, 68, 68, 476, 117, 68, 461, 464, - 68, 481, 68, 472, 473, 68, 482, 483, 475, 465, - 68, 480, 471, 466, 474, 467, 68, 477, 68, 468, + 68, 433, 68, 68, 432, 436, 68, 68, 435, 68, + 437, 68, 68, 68, 68, 431, 68, 434, 438, 439, + 68, 440, 68, 443, 117, 442, 445, 441, 444, 68, + 68, 68, 68, 446, 68, 447, 448, 68, 449, 68, + 68, 68, 450, 452, 453, 68, 68, 68, 459, 454, + 451, 68, 457, 68, 455, 456, 68, 68, 68, 68, + 460, 458, 68, 463, 68, 465, 68, 68, 68, 462, + 461, 466, 470, 68, 68, 468, 471, 122, 68, 68, + 464, 68, 68, 68, 467, 68, 68, 469, 484, 472, + 68, 485, 115, 68, 489, 68, 480, 481, 486, 483, - 68, 469, 68, 68, 478, 68, 470, 68, 484, 487, - 68, 488, 485, 68, 68, 68, 68, 489, 492, 68, - 491, 486, 479, 495, 490, 68, 497, 68, 493, 496, - 494, 68, 68, 68, 68, 68, 68, 499, 500, 501, - 68, 503, 498, 504, 502, 68, 505, 68, 68, 506, - 68, 507, 68, 509, 68, 68, 68, 510, 512, 511, - 68, 68, 68, 68, 68, 68, 516, 508, 517, 68, - 523, 68, 518, 520, 513, 515, 519, 521, 68, 522, - 514, 68, 68, 68, 526, 68, 68, 68, 68, 531, - 68, 68, 68, 68, 68, 528, 532, 525, 68, 68, + 68, 490, 473, 68, 479, 68, 474, 482, 475, 488, + 491, 68, 476, 68, 477, 68, 487, 495, 68, 478, + 68, 492, 496, 497, 68, 493, 68, 68, 68, 68, + 68, 68, 68, 500, 494, 502, 505, 68, 501, 499, + 68, 68, 68, 498, 68, 507, 504, 508, 68, 509, + 512, 503, 506, 68, 511, 68, 68, 510, 68, 513, + 68, 68, 514, 515, 68, 68, 68, 518, 68, 521, + 519, 516, 68, 520, 68, 68, 68, 68, 68, 527, + 68, 517, 525, 526, 529, 68, 68, 530, 524, 68, + 522, 528, 68, 68, 523, 532, 68, 535, 68, 68, - 524, 537, 68, 527, 530, 68, 533, 534, 68, 68, - 535, 68, 529, 536, 68, 68, 540, 538, 539, 543, - 68, 68, 68, 68, 68, 68, 68, 541, 68, 68, - 68, 549, 68, 542, 68, 544, 545, 68, 552, 665, - 554, 546, 548, 550, 547, 68, 551, 68, 553, 557, - 555, 560, 556, 558, 68, 68, 68, 68, 559, 68, - 561, 68, 562, 68, 563, 566, 567, 68, 68, 564, - 68, 68, 568, 68, 68, 68, 68, 569, 68, 565, - 574, 68, 576, 570, 68, 68, 68, 68, 571, 578, - 572, 68, 573, 575, 577, 582, 68, 583, 68, 68, + 531, 68, 68, 68, 540, 533, 68, 534, 537, 68, + 68, 541, 68, 68, 68, 68, 536, 539, 544, 546, + 68, 68, 68, 68, 542, 68, 543, 538, 549, 545, + 548, 68, 68, 547, 68, 552, 68, 68, 68, 68, + 68, 550, 68, 68, 551, 558, 68, 553, 68, 554, + 68, 68, 561, 676, 563, 555, 557, 559, 556, 68, + 560, 566, 562, 68, 565, 567, 68, 569, 68, 570, + 564, 68, 68, 68, 68, 572, 568, 68, 571, 575, + 68, 576, 68, 68, 68, 573, 68, 577, 68, 579, + 68, 68, 578, 68, 580, 574, 581, 583, 582, 68, - 585, 68, 579, 68, 584, 581, 68, 586, 68, 589, - 580, 587, 590, 588, 68, 592, 68, 593, 594, 68, - 68, 591, 68, 68, 68, 595, 597, 68, 68, 68, - 68, 601, 68, 68, 68, 68, 605, 68, 596, 609, - 606, 68, 68, 68, 598, 68, 68, 600, 599, 611, - 68, 68, 602, 604, 68, 608, 615, 613, 603, 68, - 68, 616, 610, 68, 617, 612, 68, 68, 68, 614, - 623, 624, 619, 622, 68, 68, 68, 68, 618, 68, - 625, 620, 626, 630, 68, 628, 68, 633, 621, 629, - 68, 68, 68, 627, 68, 68, 68, 632, 68, 68, + 68, 585, 68, 68, 68, 584, 592, 68, 588, 68, + 587, 593, 68, 586, 594, 595, 68, 68, 68, 68, + 589, 68, 68, 591, 598, 68, 597, 602, 590, 601, + 603, 600, 68, 604, 68, 68, 68, 596, 68, 599, + 607, 68, 68, 605, 68, 68, 68, 611, 68, 68, + 68, 68, 615, 68, 68, 606, 616, 68, 68, 619, + 68, 68, 608, 610, 609, 621, 68, 68, 612, 614, + 68, 618, 68, 68, 613, 625, 617, 68, 620, 622, + 623, 68, 68, 68, 626, 68, 624, 627, 630, 68, + 628, 633, 629, 634, 632, 68, 68, 68, 68, 68, - 68, 641, 68, 68, 68, 631, 68, 68, 642, 645, - 68, 68, 68, 634, 635, 636, 638, 637, 640, 643, - 639, 68, 68, 648, 649, 651, 646, 644, 68, 68, - 68, 647, 650, 68, 68, 68, 68, 653, 68, 654, - 656, 68, 68, 658, 68, 652, 68, 68, 660, 659, - 655, 68, 68, 68, 667, 68, 657, 68, 666, 68, - 68, 68, 68, 669, 68, 661, 670, 663, 68, 662, - 68, 672, 664, 68, 673, 668, 68, 68, 678, 68, - 674, 676, 677, 68, 675, 671, 68, 68, 679, 68, - 681, 685, 68, 68, 68, 68, 68, 68, 68, 68, + 635, 68, 631, 638, 637, 68, 636, 639, 68, 640, + 68, 642, 643, 68, 641, 68, 644, 68, 68, 68, + 68, 68, 68, 651, 68, 68, 68, 68, 652, 656, + 68, 68, 645, 648, 646, 654, 650, 647, 653, 68, + 659, 649, 68, 660, 657, 68, 68, 655, 68, 661, + 68, 658, 68, 68, 68, 662, 68, 663, 665, 667, + 68, 68, 669, 68, 68, 68, 68, 68, 671, 666, + 68, 664, 68, 678, 670, 68, 668, 677, 68, 68, + 68, 68, 68, 68, 672, 673, 674, 680, 681, 68, + 675, 68, 683, 68, 684, 679, 687, 68, 685, 68, - 799, 68, 68, 683, 680, 684, 68, 682, 690, 693, - 68, 691, 689, 686, 687, 68, 688, 692, 699, 694, - 68, 695, 68, 68, 696, 700, 68, 697, 68, 698, - 68, 68, 68, 68, 706, 68, 68, 68, 708, 709, - 68, 702, 701, 68, 68, 704, 710, 68, 703, 68, - 705, 68, 711, 707, 714, 713, 715, 68, 712, 68, - 68, 68, 68, 68, 719, 68, 720, 716, 721, 68, - 68, 722, 725, 68, 68, 717, 68, 68, 68, 718, - 723, 724, 726, 730, 728, 729, 68, 731, 68, 732, - 68, 727, 735, 68, 68, 736, 68, 733, 737, 68, + 68, 68, 686, 68, 682, 688, 689, 68, 690, 68, + 68, 68, 696, 68, 68, 691, 68, 68, 68, 692, + 68, 693, 68, 694, 695, 704, 68, 68, 68, 701, + 697, 700, 702, 698, 703, 699, 705, 707, 68, 710, + 708, 711, 68, 68, 68, 706, 68, 709, 68, 68, + 68, 68, 717, 68, 68, 720, 721, 68, 68, 713, + 68, 68, 68, 712, 715, 725, 714, 716, 722, 718, + 68, 68, 719, 723, 68, 68, 726, 68, 68, 724, + 68, 68, 731, 68, 68, 732, 733, 68, 68, 737, + 727, 728, 729, 734, 68, 68, 68, 730, 735, 736, - 68, 739, 68, 738, 741, 68, 68, 743, 68, 68, - 734, 744, 68, 68, 68, 68, 68, 68, 68, 68, - 740, 68, 753, 68, 745, 68, 746, 68, 68, 68, - 742, 747, 755, 748, 749, 750, 756, 757, 751, 754, - 68, 759, 68, 68, 752, 763, 68, 68, 762, 68, - 68, 758, 68, 760, 765, 68, 68, 766, 761, 68, - 68, 68, 68, 68, 767, 770, 764, 774, 769, 771, - 775, 768, 68, 777, 776, 68, 773, 68, 68, 779, - 68, 68, 772, 68, 68, 781, 783, 68, 782, 778, - 68, 68, 780, 786, 68, 68, 787, 68, 68, 785, + 738, 68, 740, 741, 68, 743, 68, 744, 68, 68, + 742, 68, 68, 739, 747, 68, 748, 68, 749, 68, + 68, 751, 68, 750, 68, 753, 68, 752, 68, 745, + 68, 746, 755, 68, 756, 68, 757, 68, 758, 68, + 68, 68, 68, 759, 68, 765, 68, 754, 760, 68, + 68, 68, 68, 768, 68, 761, 68, 762, 767, 769, + 68, 763, 766, 68, 771, 774, 775, 764, 68, 68, + 773, 68, 68, 68, 778, 777, 776, 770, 772, 68, + 68, 779, 68, 68, 68, 787, 68, 68, 783, 68, + 68, 788, 784, 780, 781, 789, 68, 790, 792, 782, - 788, 68, 68, 789, 68, 784, 68, 790, 68, 792, - 796, 795, 68, 791, 68, 68, 68, 798, 800, 68, - 793, 68, 794, 68, 802, 68, 801, 68, 68, 807, - 68, 68, 68, 803, 810, 809, 68, 804, 68, 805, - 806, 808, 813, 68, 68, 812, 68, 68, 68, 811, - 816, 815, 817, 68, 68, 821, 68, 68, 818, 68, - 68, 822, 819, 68, 814, 68, 68, 68, 68, 68, - 68, 68, 116, 824, 820, 825, 823, 826, 828, 829, - 827, 68, 832, 830, 68, 831, 68, 833, 837, 68, - 834, 68, 68, 68, 68, 836, 835, 840, 68, 841, + 786, 791, 68, 68, 68, 785, 68, 68, 796, 68, + 794, 68, 795, 68, 799, 68, 793, 800, 68, 68, + 68, 798, 68, 801, 68, 802, 68, 805, 68, 797, + 809, 803, 804, 68, 68, 68, 812, 808, 806, 68, + 811, 68, 807, 813, 68, 68, 815, 68, 68, 68, + 810, 68, 68, 68, 68, 68, 68, 68, 823, 113, + 817, 814, 822, 818, 819, 68, 68, 824, 816, 820, + 826, 68, 68, 821, 825, 68, 68, 828, 829, 68, + 830, 827, 68, 834, 831, 68, 833, 68, 68, 68, + 835, 838, 68, 68, 68, 68, 68, 68, 68, 68, - 838, 842, 68, 844, 68, 68, 845, 843, 68, 68, - 68, 839, 68, 68, 847, 68, 848, 68, 850, 68, - 846, 68, 68, 68, 68, 849, 856, 114, 68, 68, - 859, 860, 68, 854, 851, 68, 852, 857, 861, 68, - 853, 858, 68, 855, 863, 68, 864, 68, 862, 866, - 68, 867, 68, 68, 869, 68, 68, 68, 868, 871, - 68, 865, 68, 873, 68, 68, 875, 874, 877, 68, - 68, 879, 68, 880, 68, 870, 68, 68, 882, 68, - 872, 876, 68, 68, 68, 68, 68, 884, 68, 878, - 886, 883, 68, 890, 68, 888, 891, 889, 68, 887, + 832, 68, 68, 837, 840, 839, 836, 841, 842, 843, + 68, 844, 846, 68, 845, 68, 847, 851, 68, 848, + 68, 853, 73, 68, 850, 68, 849, 854, 68, 852, + 855, 856, 68, 858, 68, 68, 859, 857, 68, 68, + 68, 68, 68, 68, 861, 862, 68, 864, 68, 68, + 860, 68, 68, 68, 68, 863, 870, 68, 68, 873, + 73, 868, 865, 874, 68, 866, 68, 871, 68, 867, + 872, 879, 869, 875, 68, 877, 68, 878, 68, 876, + 880, 68, 881, 68, 68, 883, 68, 884, 68, 882, + 885, 68, 68, 68, 68, 889, 888, 68, 887, 891, - 68, 68, 881, 895, 885, 68, 894, 68, 68, 893, - 897, 68, 68, 896, 892, 68, 898, 899, 68, 900, - 68, 902, 68, 901, 68, 68, 906, 68, 68, 68, - 905, 68, 903, 907, 68, 68, 910, 911, 68, 909, - 68, 912, 913, 68, 904, 908, 914, 68, 915, 68, - 916, 68, 917, 68, 918, 68, 68, 921, 68, 68, - 68, 920, 923, 68, 922, 925, 68, 68, 924, 68, - 68, 68, 68, 68, 68, 919, 932, 68, 68, 926, - 68, 68, 928, 929, 930, 68, 68, 927, 68, 933, - 937, 938, 68, 931, 936, 939, 68, 68, 935, 68, + 68, 893, 68, 894, 68, 68, 886, 68, 896, 68, + 890, 68, 68, 68, 68, 68, 892, 898, 900, 68, + 904, 897, 68, 68, 902, 68, 905, 68, 903, 901, + 909, 895, 899, 68, 908, 68, 907, 68, 68, 68, + 68, 911, 68, 906, 912, 913, 68, 68, 68, 910, + 68, 914, 68, 915, 916, 68, 920, 919, 68, 68, + 917, 68, 918, 68, 921, 68, 941, 68, 923, 925, + 68, 926, 68, 924, 68, 922, 927, 68, 928, 68, + 929, 68, 930, 68, 931, 68, 68, 68, 932, 68, + 934, 935, 68, 68, 936, 937, 933, 68, 939, 68, - 934, 68, 941, 68, 68, 68, 940, 68, 942, 948, - 943, 947, 68, 68, 68, 944, 68, 68, 68, 945, - 949, 953, 68, 946, 954, 68, 950, 957, 68, 68, - 959, 68, 955, 951, 68, 960, 952, 68, 68, 68, - 956, 68, 68, 68, 963, 68, 964, 962, 958, 68, - 965, 68, 970, 68, 967, 68, 968, 68, 966, 961, - 969, 971, 68, 68, 68, 68, 68, 973, 972, 974, - 68, 977, 68, 975, 976, 68, 979, 981, 68, 68, - 68, 978, 68, 68, 68, 984, 987, 68, 982, 68, - 983, 68, 985, 68, 980, 68, 989, 986, 68, 991, + 68, 68, 938, 68, 68, 68, 945, 946, 68, 68, + 68, 68, 940, 942, 947, 943, 944, 68, 68, 953, + 68, 68, 951, 952, 950, 68, 955, 68, 68, 68, + 949, 68, 68, 961, 68, 948, 956, 962, 68, 954, + 68, 68, 68, 68, 968, 68, 957, 958, 959, 68, + 960, 68, 967, 963, 68, 971, 68, 68, 68, 964, + 68, 965, 68, 966, 973, 68, 969, 68, 974, 976, + 68, 68, 970, 68, 68, 977, 972, 980, 978, 979, + 975, 68, 68, 984, 68, 68, 981, 982, 68, 983, + 985, 68, 68, 986, 68, 988, 68, 987, 68, 991, - 68, 990, 992, 68, 68, 994, 68, 995, 997, 988, - 68, 993, 68, 996, 68, 68, 68, 68, 999, 68, - 68, 68, 1002, 68, 68, 998, 68, 1007, 1009, 68, - 1005, 68, 1001, 68, 1000, 1010, 68, 68, 68, 1003, - 68, 1016, 1011, 1006, 1008, 1012, 1004, 68, 68, 1013, - 68, 68, 1015, 68, 68, 1018, 68, 1017, 1021, 68, - 68, 68, 68, 1014, 68, 1025, 1028, 68, 1020, 1024, - 1019, 68, 1022, 1023, 1030, 68, 1029, 68, 68, 1033, - 68, 1034, 68, 1027, 68, 68, 68, 68, 1026, 1038, - 68, 1039, 68, 112, 68, 1042, 68, 1031, 1036, 1041, + 68, 68, 68, 989, 68, 990, 995, 68, 68, 992, + 68, 68, 68, 996, 68, 998, 997, 1001, 68, 68, + 993, 994, 1004, 999, 1000, 68, 1003, 1005, 68, 1006, + 68, 68, 1002, 68, 1009, 1010, 68, 68, 68, 68, + 68, 1011, 68, 68, 68, 68, 68, 1008, 1013, 1007, + 1016, 68, 68, 68, 68, 1021, 68, 1012, 1024, 1015, + 1019, 1014, 1023, 68, 1017, 68, 68, 68, 68, 68, + 1030, 68, 1018, 1020, 1022, 1025, 1026, 1027, 68, 68, + 1031, 68, 68, 1029, 1032, 1035, 68, 68, 68, 68, + 68, 68, 68, 1028, 1039, 1042, 68, 1034, 1038, 68, - 1032, 1043, 68, 1035, 68, 1037, 1040, 1044, 68, 1045, - 1046, 68, 68, 1047, 1048, 68, 68, 68, 1051, 68, - 68, 1049, 68, 68, 68, 1050, 68, 1052, 1054, 1055, - 68, 68, 1057, 68, 68, 1056, 1060, 68, 1058, 68, - 1053, 1061, 68, 68, 1059, 1062, 68, 68, 1064, 68, - 68, 1063, 1068, 1065, 1066, 1067, 68, 68, 68, 1072, - 68, 73, 73, 73, 68, 1069, 121, 119, 117, 116, - 114, 1070, 112, 68, 1073, 1073, 1073, 1071, 40, 40, - 40, 40, 40, 40, 45, 45, 45, 45, 45, 45, - 50, 50, 50, 50, 50, 50, 56, 56, 56, 56, + 1033, 1044, 68, 1036, 1043, 68, 68, 1037, 1047, 68, + 68, 1041, 1048, 68, 68, 68, 68, 1040, 1052, 68, + 1053, 68, 68, 1056, 68, 1045, 1050, 68, 1046, 1049, + 1057, 68, 1055, 1058, 68, 1051, 1067, 68, 1060, 68, + 68, 1054, 1059, 68, 1061, 1062, 68, 68, 1064, 1065, + 68, 68, 1063, 68, 1069, 68, 1066, 1068, 68, 1071, + 68, 68, 1070, 68, 1074, 68, 1075, 68, 1076, 68, + 68, 68, 1078, 68, 68, 68, 1072, 1079, 1081, 68, + 68, 1073, 1077, 68, 1082, 68, 1086, 68, 73, 68, + 122, 120, 118, 117, 1080, 1083, 115, 1084, 113, 68, - 56, 56, 61, 61, 61, 61, 61, 61, 71, 71, - 71, 71, 71, 71, 111, 111, 1073, 1073, 111, 111, - 113, 113, 1073, 113, 1073, 113, 115, 1073, 1073, 1073, - 1073, 115, 118, 118, 1073, 1073, 118, 118, 120, 1073, - 1073, 1073, 1073, 120, 122, 122, 122, 122, 122, 122, - 72, 72, 72, 72, 72, 72, 13, 1073, 1073, 1073, - 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, - 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, - 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, - 1073, 1073, 1073, 1073, 1073, 1073 + 1087, 1087, 1087, 1087, 1085, 40, 40, 40, 40, 40, + 40, 45, 45, 45, 45, 45, 45, 50, 50, 50, + 50, 50, 50, 56, 56, 56, 56, 56, 56, 61, + 61, 61, 61, 61, 61, 71, 71, 71, 71, 71, + 71, 112, 112, 1087, 1087, 112, 112, 114, 114, 1087, + 114, 1087, 114, 116, 1087, 1087, 1087, 1087, 116, 119, + 119, 1087, 1087, 119, 119, 121, 1087, 1087, 1087, 1087, + 121, 123, 123, 123, 123, 123, 123, 72, 72, 72, + 72, 72, 72, 13, 1087, 1087, 1087, 1087, 1087, 1087, + 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, + 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, + 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, + 1087, 1087, 1087 } ; -static yyconst flex_int16_t yy_chk[2197] = +static yyconst flex_int16_t yy_chk[2224] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -1035,240 +1045,243 @@ static yyconst flex_int16_t yy_chk[2197] = 5, 15, 4, 6, 6, 15, 5, 6, 9, 9, 9, 24, 33, 6, 7, 7, 7, 7, 9, 7, 10, 10, 10, 26, 26, 7, 8, 8, 8, 8, - 10, 8, 26, 33, 109, 24, 25, 8, 11, 11, - 11, 11, 11, 11, 1079, 20, 109, 20, 20, 11, + 10, 8, 26, 33, 110, 24, 25, 8, 11, 11, + 11, 11, 11, 11, 1093, 20, 110, 20, 20, 11, 20, 25, 66, 27, 28, 20, 23, 27, 11, 12, 12, 12, 12, 12, 12, 23, 66, 27, 23, 28, 12, 23, 29, 30, 31, 44, 44, 29, 78, 12, 19, 19, 19, 19, 77, 19, 22, 22, 30, 31, 19, 19, 78, 31, 22, 32, 32, 34, 36, 35, - 32, 22, 77, 36, 35, 38, 34, 37, 37, 159, - 49, 159, 34, 49, 35, 34, 32, 35, 36, 38, - 75, 39, 39, 75, 38, 37, 39, 55, 76, 55, - 55, 76, 55, 60, 60, 63, 63, 63, 63, 65, - 63, 65, 65, 80, 65, 68, 63, 68, 68, 69, + 32, 22, 77, 36, 35, 38, 34, 37, 37, 89, + 49, 79, 34, 49, 35, 34, 32, 35, 36, 38, + 60, 60, 34, 86, 38, 37, 39, 39, 86, 79, + 55, 39, 55, 55, 89, 55, 63, 63, 63, 63, + 65, 63, 65, 65, 80, 65, 68, 63, 68, 68, - 68, 79, 82, 69, 88, 68, 71, 71, 71, 71, - 83, 71, 84, 81, 89, 80, 71, 71, 81, 79, - 85, 86, 82, 88, 85, 96, 86, 463, 83, 87, - 84, 81, 87, 90, 91, 87, 90, 92, 91, 89, - 90, 93, 95, 94, 92, 96, 98, 97, 99, 87, - 94, 97, 100, 101, 93, 95, 102, 99, 103, 104, - 104, 105, 106, 107, 98, 100, 108, 110, 101, 112, - 112, 108, 119, 119, 114, 102, 103, 114, 124, 105, - 104, 124, 123, 106, 135, 110, 107, 116, 135, 116, - 116, 121, 116, 121, 121, 126, 121, 122, 122, 122, + 69, 68, 75, 82, 69, 75, 68, 71, 71, 71, + 71, 76, 71, 83, 76, 81, 80, 71, 71, 84, + 81, 85, 88, 82, 87, 85, 93, 87, 92, 90, + 87, 83, 90, 81, 91, 92, 90, 84, 91, 93, + 94, 88, 95, 96, 87, 97, 98, 94, 99, 97, + 100, 102, 101, 103, 107, 95, 104, 99, 105, 105, + 106, 108, 109, 96, 98, 101, 102, 109, 111, 136, + 100, 471, 103, 136, 104, 107, 113, 113, 106, 105, + 115, 120, 120, 115, 108, 117, 111, 117, 117, 122, + 117, 122, 122, 127, 122, 123, 123, 123, 123, 125, - 122, 125, 122, 126, 127, 128, 125, 129, 122, 130, - 132, 132, 129, 133, 130, 134, 136, 137, 133, 127, - 174, 136, 138, 139, 140, 128, 131, 142, 141, 140, - 131, 137, 142, 145, 138, 131, 174, 138, 134, 144, - 131, 139, 143, 143, 144, 152, 131, 131, 141, 153, - 144, 146, 147, 148, 145, 149, 146, 147, 148, 150, - 149, 151, 154, 155, 156, 152, 150, 151, 157, 156, - 161, 153, 158, 160, 162, 162, 163, 154, 167, 164, - 160, 163, 166, 155, 164, 165, 168, 165, 169, 161, - 157, 168, 158, 170, 166, 171, 120, 167, 171, 163, + 123, 127, 125, 126, 128, 129, 123, 130, 126, 131, + 133, 133, 130, 134, 131, 135, 137, 138, 134, 128, + 176, 137, 139, 140, 141, 129, 132, 143, 142, 141, + 132, 138, 143, 146, 139, 132, 176, 139, 135, 145, + 132, 140, 144, 144, 145, 153, 132, 132, 142, 154, + 145, 147, 148, 149, 146, 150, 147, 148, 149, 151, + 150, 152, 155, 156, 157, 153, 151, 152, 158, 159, + 155, 154, 160, 158, 161, 162, 161, 163, 156, 164, + 164, 165, 162, 166, 157, 168, 165, 167, 166, 167, + 169, 159, 160, 170, 172, 171, 163, 168, 170, 173, - 172, 172, 175, 169, 165, 173, 173, 176, 177, 178, - 176, 170, 177, 179, 180, 180, 181, 175, 178, 182, - 183, 181, 184, 185, 182, 186, 186, 179, 187, 188, - 189, 191, 190, 189, 195, 195, 185, 193, 192, 196, - 183, 188, 196, 184, 190, 197, 187, 192, 198, 193, - 194, 191, 194, 194, 202, 199, 200, 200, 201, 201, - 204, 203, 197, 198, 199, 197, 203, 205, 206, 209, - 207, 208, 205, 210, 202, 207, 208, 206, 211, 212, - 204, 211, 215, 216, 214, 218, 217, 210, 219, 209, - 218, 215, 220, 212, 233, 221, 222, 211, 213, 214, + 174, 174, 173, 177, 165, 181, 167, 175, 175, 169, + 171, 178, 172, 179, 178, 180, 185, 179, 177, 181, + 182, 182, 183, 184, 180, 186, 187, 183, 184, 188, + 188, 189, 190, 192, 191, 193, 185, 191, 194, 187, + 195, 197, 197, 199, 190, 192, 186, 194, 196, 189, + 196, 196, 195, 198, 200, 193, 198, 201, 202, 202, + 199, 203, 203, 199, 204, 205, 201, 206, 207, 200, + 208, 209, 206, 210, 212, 208, 211, 213, 210, 204, + 209, 211, 215, 214, 217, 205, 214, 219, 207, 218, + 220, 213, 221, 222, 212, 223, 215, 221, 218, 217, - 213, 213, 225, 233, 216, 217, 223, 220, 219, 226, - 222, 223, 213, 213, 213, 221, 224, 224, 227, 224, - 229, 228, 225, 230, 229, 226, 231, 232, 234, 235, - 239, 239, 234, 237, 227, 228, 232, 236, 235, 237, - 231, 230, 236, 238, 241, 240, 242, 243, 238, 232, - 240, 244, 243, 241, 245, 245, 247, 247, 242, 248, - 249, 250, 251, 253, 254, 255, 256, 257, 249, 254, - 250, 256, 244, 255, 251, 258, 259, 259, 260, 262, - 248, 261, 264, 253, 259, 257, 261, 263, 263, 265, - 265, 261, 259, 266, 258, 268, 269, 267, 260, 262, + 224, 225, 214, 216, 124, 216, 216, 226, 219, 220, + 223, 228, 226, 222, 229, 225, 230, 216, 216, 216, + 224, 227, 227, 231, 227, 232, 233, 234, 245, 232, + 229, 228, 230, 235, 236, 237, 238, 231, 121, 237, + 245, 234, 235, 236, 233, 238, 239, 240, 247, 241, + 244, 239, 251, 240, 241, 235, 242, 242, 243, 244, + 246, 248, 248, 243, 252, 246, 250, 250, 253, 247, + 254, 256, 252, 251, 257, 258, 259, 253, 260, 261, + 258, 262, 254, 260, 259, 263, 263, 264, 257, 265, + 266, 256, 268, 263, 265, 267, 267, 261, 270, 265, - 270, 271, 259, 277, 272, 270, 273, 264, 266, 267, - 273, 274, 275, 278, 268, 277, 274, 280, 269, 272, - 271, 276, 276, 279, 283, 275, 279, 539, 278, 283, - 280, 281, 281, 282, 282, 284, 284, 285, 285, 286, - 287, 292, 288, 289, 286, 287, 288, 290, 289, 291, - 293, 290, 294, 539, 291, 293, 295, 296, 296, 295, - 297, 292, 300, 118, 295, 297, 294, 298, 295, 299, - 298, 301, 302, 299, 303, 300, 301, 302, 304, 305, - 303, 304, 305, 306, 307, 308, 309, 310, 306, 311, - 313, 309, 310, 313, 311, 299, 312, 315, 317, 308, + 262, 263, 269, 269, 271, 272, 273, 264, 275, 274, + 266, 263, 119, 270, 274, 276, 271, 268, 277, 279, + 278, 282, 277, 281, 272, 278, 283, 275, 273, 283, + 276, 284, 279, 280, 280, 281, 282, 285, 285, 286, + 286, 287, 288, 288, 284, 290, 287, 289, 289, 291, + 290, 292, 293, 295, 291, 292, 294, 293, 295, 296, + 294, 297, 298, 300, 300, 299, 297, 301, 299, 311, + 304, 302, 301, 299, 302, 305, 298, 299, 303, 296, + 305, 306, 303, 304, 307, 308, 306, 311, 308, 309, + 307, 310, 309, 312, 313, 314, 310, 315, 316, 313, - 316, 318, 307, 314, 316, 312, 319, 314, 314, 320, - 321, 321, 322, 317, 320, 323, 322, 315, 324, 318, - 323, 319, 325, 326, 327, 328, 331, 329, 330, 332, - 328, 327, 329, 330, 324, 333, 326, 334, 332, 339, - 335, 325, 334, 335, 331, 336, 336, 338, 340, 333, - 341, 344, 338, 347, 348, 349, 340, 339, 348, 351, - 349, 352, 347, 739, 351, 341, 353, 355, 344, 350, - 354, 354, 360, 350, 355, 357, 350, 356, 356, 352, - 739, 350, 358, 358, 363, 361, 359, 350, 350, 359, - 357, 353, 360, 361, 362, 362, 364, 365, 365, 363, + 314, 315, 315, 316, 303, 317, 318, 312, 319, 318, + 320, 321, 319, 319, 317, 321, 322, 323, 324, 325, + 326, 326, 327, 328, 325, 329, 327, 330, 328, 331, + 320, 322, 332, 324, 336, 323, 338, 118, 333, 332, + 334, 329, 331, 333, 335, 334, 330, 337, 339, 335, + 338, 340, 336, 339, 340, 343, 337, 341, 341, 344, + 343, 345, 349, 346, 352, 357, 353, 354, 358, 345, + 353, 356, 354, 352, 359, 359, 356, 344, 346, 349, + 355, 360, 362, 357, 355, 361, 361, 355, 360, 363, + 363, 364, 355, 358, 364, 365, 366, 362, 355, 355, - 366, 364, 367, 366, 368, 369, 370, 376, 367, 371, - 372, 380, 368, 369, 371, 373, 373, 372, 374, 375, - 380, 376, 375, 374, 370, 377, 377, 378, 381, 382, - 378, 383, 381, 384, 387, 385, 386, 389, 378, 387, - 383, 385, 388, 390, 391, 392, 388, 384, 382, 391, - 386, 393, 393, 395, 394, 390, 389, 394, 397, 396, - 398, 398, 399, 399, 400, 401, 392, 403, 404, 411, - 405, 395, 396, 406, 407, 408, 117, 410, 397, 400, - 408, 411, 413, 404, 405, 412, 412, 413, 407, 401, - 402, 410, 403, 402, 406, 402, 409, 409, 415, 402, + 367, 367, 368, 369, 366, 370, 370, 371, 369, 375, + 371, 373, 372, 374, 380, 365, 377, 368, 372, 373, + 376, 374, 383, 377, 116, 376, 379, 375, 378, 378, + 389, 379, 382, 380, 387, 382, 383, 384, 384, 385, + 388, 391, 385, 387, 388, 390, 392, 393, 394, 389, + 385, 396, 392, 394, 390, 391, 395, 397, 398, 399, + 395, 393, 403, 398, 400, 400, 402, 404, 401, 397, + 396, 401, 405, 405, 407, 403, 406, 406, 408, 410, + 399, 411, 418, 412, 402, 414, 413, 404, 415, 407, + 416, 416, 114, 415, 418, 417, 411, 412, 416, 414, - 414, 402, 416, 426, 409, 421, 402, 422, 414, 417, - 417, 419, 415, 423, 420, 427, 419, 420, 423, 424, - 422, 416, 409, 426, 421, 425, 428, 430, 424, 427, - 425, 428, 431, 432, 433, 434, 439, 431, 432, 433, - 435, 435, 430, 436, 434, 438, 438, 440, 436, 438, - 441, 439, 442, 441, 443, 444, 445, 442, 444, 443, - 446, 448, 447, 449, 454, 451, 448, 440, 449, 450, - 455, 455, 450, 452, 445, 447, 451, 453, 452, 454, - 446, 456, 453, 457, 458, 459, 460, 461, 458, 465, - 464, 466, 467, 468, 465, 460, 466, 457, 470, 472, + 419, 419, 408, 409, 410, 420, 409, 413, 409, 417, + 420, 422, 409, 421, 409, 423, 416, 424, 424, 409, + 427, 421, 426, 427, 428, 422, 429, 426, 430, 431, + 432, 433, 434, 430, 423, 432, 435, 437, 431, 429, + 438, 435, 439, 428, 440, 438, 434, 439, 441, 440, + 443, 433, 437, 442, 442, 443, 447, 441, 445, 445, + 446, 448, 445, 446, 449, 450, 452, 449, 451, 452, + 450, 447, 453, 451, 454, 455, 458, 456, 457, 458, + 459, 448, 456, 457, 460, 462, 464, 461, 455, 460, + 453, 459, 461, 465, 454, 463, 463, 466, 467, 468, - 456, 471, 471, 459, 464, 469, 467, 468, 475, 473, - 469, 474, 461, 470, 476, 477, 474, 472, 473, 477, - 478, 479, 480, 481, 482, 483, 485, 475, 484, 486, - 490, 483, 489, 476, 488, 478, 479, 601, 486, 601, - 489, 480, 482, 484, 481, 493, 485, 491, 488, 492, - 490, 494, 491, 492, 492, 498, 494, 496, 493, 495, - 495, 499, 496, 497, 497, 500, 501, 502, 507, 498, - 500, 501, 502, 503, 504, 508, 505, 503, 506, 499, - 505, 509, 507, 504, 510, 511, 512, 517, 504, 509, - 504, 520, 504, 506, 508, 513, 513, 514, 514, 515, + 462, 466, 469, 472, 473, 464, 474, 465, 468, 473, + 475, 474, 476, 477, 478, 480, 467, 472, 477, 479, + 479, 481, 483, 482, 475, 484, 476, 469, 482, 478, + 481, 485, 486, 480, 487, 485, 488, 489, 490, 491, + 493, 483, 492, 494, 484, 491, 497, 486, 496, 487, + 498, 611, 494, 611, 497, 488, 490, 492, 489, 499, + 493, 500, 496, 501, 499, 500, 500, 502, 503, 503, + 498, 506, 502, 504, 505, 505, 501, 507, 504, 508, + 512, 509, 510, 515, 508, 506, 509, 510, 511, 512, + 514, 517, 511, 513, 512, 507, 512, 513, 512, 516, - 516, 516, 510, 518, 515, 512, 521, 517, 519, 520, - 511, 518, 521, 519, 522, 524, 527, 525, 526, 528, - 524, 522, 525, 526, 530, 527, 529, 529, 531, 532, - 533, 533, 534, 535, 541, 536, 538, 540, 528, 541, - 538, 538, 542, 545, 530, 543, 544, 532, 531, 543, - 546, 547, 534, 536, 548, 540, 547, 545, 535, 549, - 550, 548, 542, 551, 549, 544, 552, 553, 554, 546, - 555, 556, 551, 554, 560, 555, 556, 559, 550, 557, - 557, 552, 559, 562, 562, 561, 563, 565, 553, 561, - 561, 564, 565, 560, 566, 567, 568, 564, 569, 571, + 518, 515, 519, 520, 521, 514, 522, 522, 518, 524, + 517, 523, 523, 516, 524, 525, 525, 526, 527, 528, + 519, 529, 531, 521, 528, 530, 527, 533, 520, 531, + 534, 530, 533, 535, 536, 534, 537, 526, 535, 529, + 538, 538, 539, 536, 540, 541, 542, 542, 543, 544, + 548, 545, 547, 549, 550, 537, 547, 547, 551, 550, + 553, 552, 539, 541, 540, 552, 554, 555, 543, 545, + 556, 549, 559, 561, 544, 556, 548, 557, 551, 553, + 554, 562, 558, 560, 557, 569, 555, 558, 561, 563, + 559, 564, 560, 565, 563, 572, 564, 575, 565, 566, - 573, 573, 570, 572, 574, 563, 575, 576, 574, 577, - 577, 579, 588, 566, 567, 568, 570, 569, 572, 575, - 571, 578, 586, 580, 581, 586, 578, 576, 580, 581, - 587, 579, 584, 584, 589, 590, 592, 588, 594, 589, - 591, 591, 593, 593, 595, 587, 596, 599, 595, 594, - 590, 598, 600, 602, 603, 604, 592, 605, 602, 603, - 608, 607, 611, 605, 612, 596, 607, 599, 609, 598, - 618, 609, 600, 610, 610, 604, 613, 614, 615, 615, - 611, 613, 614, 616, 612, 608, 617, 619, 616, 620, - 618, 622, 621, 623, 624, 625, 622, 626, 741, 627, + 566, 568, 562, 570, 569, 573, 568, 570, 570, 571, + 571, 573, 574, 576, 572, 577, 575, 574, 578, 579, + 580, 581, 582, 582, 583, 584, 585, 586, 583, 587, + 587, 589, 576, 579, 577, 585, 581, 578, 584, 588, + 590, 580, 597, 591, 588, 590, 598, 586, 591, 594, + 594, 589, 596, 599, 600, 596, 602, 597, 599, 601, + 601, 603, 603, 604, 605, 606, 609, 608, 605, 600, + 610, 598, 612, 613, 604, 614, 602, 612, 613, 618, + 621, 615, 622, 617, 606, 608, 609, 615, 617, 619, + 610, 623, 619, 620, 620, 614, 623, 627, 621, 628, - 741, 628, 633, 620, 617, 621, 631, 619, 627, 631, - 632, 627, 626, 623, 624, 634, 625, 628, 636, 632, - 635, 633, 638, 636, 634, 637, 637, 634, 639, 635, - 640, 641, 642, 643, 643, 644, 652, 653, 646, 647, - 648, 639, 638, 646, 647, 641, 648, 651, 640, 649, - 642, 654, 649, 644, 652, 651, 653, 655, 649, 657, - 658, 659, 661, 660, 658, 662, 659, 654, 660, 663, - 665, 661, 664, 666, 669, 655, 672, 664, 667, 657, - 662, 663, 665, 669, 667, 668, 668, 670, 670, 671, - 673, 666, 674, 674, 671, 675, 675, 672, 676, 676, + 624, 629, 622, 626, 618, 624, 625, 625, 626, 630, + 633, 631, 632, 634, 635, 627, 636, 632, 638, 628, + 637, 629, 641, 630, 631, 641, 643, 642, 644, 637, + 633, 636, 637, 634, 638, 635, 642, 644, 645, 646, + 644, 647, 647, 648, 646, 643, 649, 645, 650, 652, + 651, 653, 653, 654, 655, 657, 658, 662, 663, 649, + 657, 658, 659, 648, 651, 662, 650, 652, 659, 654, + 660, 664, 655, 660, 666, 665, 663, 668, 669, 660, + 670, 671, 669, 673, 672, 670, 671, 674, 676, 675, + 664, 665, 666, 672, 675, 677, 678, 668, 673, 674, - 677, 679, 680, 677, 681, 682, 679, 683, 683, 681, - 673, 684, 685, 686, 687, 688, 684, 689, 690, 692, - 680, 691, 691, 693, 685, 696, 685, 698, 695, 694, - 682, 685, 693, 686, 687, 688, 694, 695, 689, 692, - 697, 697, 699, 701, 690, 702, 703, 704, 701, 708, - 702, 696, 705, 698, 704, 706, 707, 705, 699, 709, - 710, 711, 712, 720, 706, 709, 703, 713, 708, 710, - 714, 707, 713, 715, 714, 714, 712, 716, 715, 717, - 718, 719, 711, 722, 717, 719, 721, 723, 720, 716, - 725, 721, 718, 724, 724, 726, 725, 727, 728, 723, + 676, 680, 678, 679, 679, 681, 681, 682, 683, 691, + 680, 684, 682, 677, 685, 685, 686, 686, 687, 687, + 688, 690, 693, 688, 696, 692, 690, 691, 697, 683, + 692, 684, 694, 694, 695, 698, 696, 699, 696, 695, + 700, 701, 703, 696, 702, 702, 705, 693, 697, 704, + 706, 707, 709, 705, 710, 698, 714, 699, 704, 706, + 712, 700, 703, 708, 708, 712, 713, 701, 715, 716, + 710, 713, 717, 718, 716, 715, 714, 707, 709, 719, + 720, 717, 721, 722, 723, 725, 724, 732, 721, 728, + 725, 726, 722, 718, 719, 726, 726, 727, 729, 720, - 726, 730, 734, 727, 733, 722, 744, 728, 732, 732, - 738, 734, 746, 730, 750, 738, 740, 740, 742, 742, - 732, 751, 733, 745, 745, 747, 744, 748, 749, 750, - 752, 754, 753, 746, 753, 752, 755, 747, 757, 748, - 749, 751, 756, 756, 762, 755, 758, 760, 759, 754, - 759, 758, 760, 761, 763, 764, 765, 766, 761, 767, - 764, 765, 762, 768, 757, 773, 774, 771, 769, 770, - 772, 778, 115, 767, 763, 768, 766, 769, 770, 771, - 769, 775, 774, 772, 777, 773, 779, 775, 780, 780, - 777, 781, 782, 783, 784, 779, 778, 783, 787, 784, + 724, 728, 727, 729, 730, 723, 731, 734, 733, 735, + 731, 737, 732, 733, 736, 736, 730, 737, 738, 739, + 742, 735, 740, 738, 745, 739, 744, 744, 746, 734, + 750, 740, 742, 751, 753, 750, 753, 746, 744, 752, + 752, 756, 745, 754, 754, 757, 757, 758, 759, 766, + 751, 760, 761, 763, 762, 769, 765, 764, 765, 112, + 759, 756, 764, 760, 761, 767, 775, 766, 758, 762, + 768, 768, 770, 763, 767, 772, 771, 770, 771, 773, + 772, 769, 774, 776, 773, 777, 775, 778, 776, 779, + 777, 780, 780, 781, 786, 782, 787, 784, 785, 783, - 781, 785, 785, 788, 788, 789, 789, 787, 790, 791, - 793, 782, 792, 794, 791, 795, 792, 796, 794, 797, - 790, 798, 799, 801, 802, 793, 801, 113, 803, 804, - 804, 805, 805, 798, 795, 807, 796, 802, 806, 806, - 797, 803, 810, 799, 808, 808, 809, 809, 807, 811, - 811, 812, 812, 814, 815, 815, 816, 819, 814, 817, - 817, 810, 818, 819, 820, 821, 821, 820, 822, 822, - 823, 824, 824, 825, 825, 816, 826, 827, 827, 828, - 818, 821, 829, 830, 832, 831, 833, 829, 834, 823, - 831, 828, 836, 835, 838, 833, 836, 834, 835, 832, + 774, 791, 795, 779, 782, 781, 778, 782, 783, 784, + 788, 785, 787, 790, 786, 792, 788, 793, 793, 790, + 794, 795, 74, 796, 792, 797, 791, 796, 800, 794, + 797, 798, 798, 801, 801, 802, 802, 800, 803, 804, + 806, 805, 807, 808, 804, 805, 809, 807, 810, 811, + 803, 812, 823, 814, 815, 806, 814, 816, 817, 817, + 72, 811, 808, 818, 818, 809, 820, 815, 829, 810, + 816, 823, 812, 819, 819, 821, 821, 822, 822, 820, + 824, 824, 825, 825, 827, 828, 828, 829, 831, 827, + 830, 830, 832, 833, 834, 834, 833, 836, 832, 835, - 839, 843, 826, 841, 830, 840, 840, 845, 841, 839, - 845, 846, 851, 843, 838, 848, 846, 847, 847, 848, - 849, 850, 850, 849, 852, 853, 854, 855, 858, 856, - 853, 854, 851, 855, 857, 859, 858, 859, 874, 857, - 862, 862, 865, 865, 852, 856, 868, 868, 870, 870, - 872, 873, 873, 875, 874, 872, 876, 878, 878, 881, - 882, 876, 882, 883, 881, 884, 884, 885, 883, 886, - 887, 888, 889, 890, 893, 875, 891, 891, 894, 885, - 892, 895, 887, 888, 889, 896, 897, 886, 900, 892, - 896, 897, 904, 890, 895, 898, 898, 905, 894, 903, + 835, 837, 837, 839, 839, 840, 831, 841, 841, 842, + 834, 844, 843, 845, 846, 847, 836, 843, 845, 848, + 849, 842, 850, 852, 847, 849, 850, 853, 848, 846, + 855, 840, 844, 854, 854, 855, 853, 857, 859, 860, + 865, 859, 866, 852, 860, 861, 861, 862, 900, 857, + 863, 862, 867, 863, 864, 864, 868, 867, 869, 870, + 865, 868, 866, 871, 869, 872, 900, 873, 871, 873, + 876, 876, 888, 872, 889, 870, 879, 879, 882, 882, + 884, 884, 886, 887, 887, 890, 904, 886, 888, 895, + 890, 892, 892, 896, 895, 896, 889, 897, 898, 898, - 893, 901, 901, 906, 907, 910, 900, 911, 903, 909, - 904, 908, 908, 912, 909, 905, 916, 919, 917, 906, - 910, 917, 920, 907, 918, 918, 911, 922, 922, 923, - 924, 924, 919, 912, 926, 926, 916, 927, 928, 929, - 920, 930, 931, 933, 929, 936, 930, 928, 923, 934, - 931, 935, 937, 937, 934, 941, 935, 948, 933, 927, - 936, 938, 938, 940, 943, 944, 942, 941, 940, 942, - 945, 945, 946, 943, 944, 949, 948, 950, 950, 951, - 953, 946, 952, 955, 956, 953, 958, 958, 951, 960, - 952, 966, 955, 965, 949, 961, 961, 956, 962, 963, + 899, 901, 897, 902, 903, 906, 904, 905, 905, 907, + 908, 909, 899, 901, 906, 902, 903, 910, 911, 912, + 912, 914, 910, 911, 909, 915, 915, 917, 918, 919, + 908, 921, 920, 922, 922, 907, 917, 923, 924, 914, + 925, 926, 923, 930, 932, 932, 918, 919, 920, 931, + 921, 933, 931, 924, 934, 936, 936, 937, 941, 925, + 942, 926, 947, 930, 938, 938, 933, 940, 940, 942, + 943, 945, 934, 944, 950, 943, 937, 947, 944, 945, + 941, 948, 949, 951, 951, 955, 948, 949, 954, 950, + 952, 952, 956, 954, 957, 956, 958, 955, 959, 959, - 963, 962, 964, 964, 969, 966, 972, 967, 969, 960, - 973, 965, 967, 968, 968, 974, 975, 976, 973, 977, - 978, 979, 976, 980, 982, 972, 983, 982, 984, 984, - 979, 985, 975, 986, 974, 985, 988, 989, 990, 977, - 994, 994, 986, 980, 983, 988, 978, 993, 995, 989, - 997, 998, 993, 999, 1002, 997, 1001, 995, 1000, 1000, - 1004, 1003, 1005, 990, 1006, 1004, 1007, 1007, 999, 1003, - 998, 1008, 1001, 1002, 1010, 1010, 1008, 1011, 1012, 1013, - 1013, 1014, 1014, 1006, 1015, 1017, 1016, 1020, 1005, 1018, - 1018, 1019, 1019, 111, 1022, 1023, 1023, 1011, 1016, 1022, + 960, 962, 963, 957, 965, 958, 964, 964, 966, 960, + 967, 970, 974, 965, 969, 967, 966, 972, 972, 976, + 962, 963, 976, 969, 970, 975, 975, 977, 977, 978, + 978, 979, 974, 980, 981, 982, 982, 983, 986, 981, + 987, 983, 988, 989, 991, 990, 992, 980, 987, 979, + 990, 993, 996, 994, 999, 996, 997, 986, 999, 989, + 993, 988, 998, 998, 991, 1003, 1000, 1002, 1004, 1008, + 1008, 1009, 992, 994, 997, 1000, 1002, 1003, 1007, 1011, + 1009, 1012, 1013, 1007, 1011, 1014, 1014, 1015, 1016, 1018, + 1017, 1019, 1020, 1004, 1018, 1021, 1021, 1013, 1017, 1022, - 1012, 1024, 1024, 1015, 1026, 1017, 1020, 1025, 1025, 1026, - 1027, 1027, 1029, 1029, 1031, 1031, 1032, 1035, 1036, 1036, - 1040, 1032, 1037, 1050, 1041, 1035, 1052, 1037, 1041, 1045, - 1045, 1047, 1049, 1049, 1064, 1047, 1053, 1053, 1050, 1058, - 1040, 1054, 1054, 1066, 1052, 1056, 1056, 1059, 1059, 1063, - 1068, 1058, 1066, 1063, 1064, 1065, 1065, 1069, 1070, 1071, - 1071, 74, 72, 70, 67, 1068, 61, 56, 51, 50, - 45, 1069, 40, 14, 13, 0, 0, 1070, 1074, 1074, - 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1075, 1075, - 1076, 1076, 1076, 1076, 1076, 1076, 1077, 1077, 1077, 1077, + 1012, 1024, 1024, 1015, 1022, 1025, 1026, 1016, 1027, 1027, + 1029, 1020, 1028, 1028, 1030, 1031, 1054, 1019, 1032, 1032, + 1033, 1033, 1034, 1037, 1037, 1025, 1030, 1036, 1026, 1029, + 1038, 1038, 1036, 1039, 1039, 1031, 1054, 1040, 1041, 1041, + 1049, 1034, 1040, 1043, 1043, 1045, 1045, 1046, 1049, 1050, + 1050, 1051, 1046, 1055, 1059, 1059, 1051, 1055, 1061, 1063, + 1063, 1064, 1061, 1066, 1067, 1067, 1068, 1068, 1070, 1070, + 1072, 1073, 1073, 1077, 1078, 1080, 1064, 1077, 1079, 1079, + 1082, 1066, 1072, 1083, 1080, 1084, 1085, 1085, 70, 67, + 61, 56, 51, 50, 1078, 1082, 45, 1083, 40, 14, - 1077, 1077, 1078, 1078, 1078, 1078, 1078, 1078, 1080, 1080, - 1080, 1080, 1080, 1080, 1081, 1081, 0, 0, 1081, 1081, - 1082, 1082, 0, 1082, 0, 1082, 1083, 0, 0, 0, - 0, 1083, 1084, 1084, 0, 0, 1084, 1084, 1085, 0, - 0, 0, 0, 1085, 1086, 1086, 1086, 1086, 1086, 1086, - 1087, 1087, 1087, 1087, 1087, 1087, 1073, 1073, 1073, 1073, - 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, - 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, - 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, - 1073, 1073, 1073, 1073, 1073, 1073 + 13, 0, 0, 0, 1084, 1088, 1088, 1088, 1088, 1088, + 1088, 1089, 1089, 1089, 1089, 1089, 1089, 1090, 1090, 1090, + 1090, 1090, 1090, 1091, 1091, 1091, 1091, 1091, 1091, 1092, + 1092, 1092, 1092, 1092, 1092, 1094, 1094, 1094, 1094, 1094, + 1094, 1095, 1095, 0, 0, 1095, 1095, 1096, 1096, 0, + 1096, 0, 1096, 1097, 0, 0, 0, 0, 1097, 1098, + 1098, 0, 0, 1098, 1098, 1099, 0, 0, 0, 0, + 1099, 1100, 1100, 1100, 1100, 1100, 1100, 1101, 1101, 1101, + 1101, 1101, 1101, 1087, 1087, 1087, 1087, 1087, 1087, 1087, + 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, + 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, + 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1087, + 1087, 1087, 1087 } ; static yy_state_type yy_last_accepting_state; @@ -1392,7 +1405,7 @@ static void config_end_include(void) #define YY_NO_INPUT 1 #endif -#line 1394 "" +#line 1407 "" #define INITIAL 0 #define quotedstring 1 @@ -1579,7 +1592,7 @@ YY_DECL #line 120 "util/configlexer.lex" -#line 1581 "" +#line 1594 "" if ( !(yy_init) ) { @@ -1638,13 +1651,13 @@ yy_match: while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 1074 ) + if ( yy_current_state >= 1088 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_base[yy_current_state] != 2157 ); + while ( yy_base[yy_current_state] != 2184 ); yy_find_action: yy_act = yy_accept[yy_current_state]; @@ -2142,43 +2155,53 @@ YY_RULE_SETUP case 94: YY_RULE_SETUP #line 217 "util/configlexer.lex" -{ YDVAR(1, VAR_DOMAIN_INSECURE) } +{ YDVAR(1, VAR_PYTHON_SCRIPT) } YY_BREAK case 95: -/* rule 95 can match eol */ YY_RULE_SETUP #line 218 "util/configlexer.lex" +{ YDVAR(0, VAR_PYTHON) } + YY_BREAK +case 96: +YY_RULE_SETUP +#line 219 "util/configlexer.lex" +{ YDVAR(1, VAR_DOMAIN_INSECURE) } + YY_BREAK +case 97: +/* rule 97 can match eol */ +YY_RULE_SETUP +#line 220 "util/configlexer.lex" { LEXOUT(("NL\n")); cfg_parser->line++; } YY_BREAK /* Quoted strings. Strip leading and ending quotes */ -case 96: +case 98: YY_RULE_SETUP -#line 221 "util/configlexer.lex" +#line 223 "util/configlexer.lex" { BEGIN(quotedstring); LEXOUT(("QS ")); } YY_BREAK case YY_STATE_EOF(quotedstring): -#line 222 "util/configlexer.lex" +#line 224 "util/configlexer.lex" { yyerror("EOF inside quoted string"); if(--num_args == 0) { BEGIN(INITIAL); } else { BEGIN(val); } } YY_BREAK -case 97: +case 99: YY_RULE_SETUP -#line 227 "util/configlexer.lex" +#line 229 "util/configlexer.lex" { LEXOUT(("STR(%s) ", yytext)); yymore(); } YY_BREAK -case 98: -/* rule 98 can match eol */ +case 100: +/* rule 100 can match eol */ YY_RULE_SETUP -#line 228 "util/configlexer.lex" +#line 230 "util/configlexer.lex" { yyerror("newline inside quoted string, no end \""); cfg_parser->line++; BEGIN(INITIAL); } YY_BREAK -case 99: +case 101: YY_RULE_SETUP -#line 230 "util/configlexer.lex" +#line 232 "util/configlexer.lex" { LEXOUT(("QE ")); if(--num_args == 0) { BEGIN(INITIAL); } @@ -2191,34 +2214,34 @@ YY_RULE_SETUP } YY_BREAK /* Single Quoted strings. Strip leading and ending quotes */ -case 100: +case 102: YY_RULE_SETUP -#line 242 "util/configlexer.lex" +#line 244 "util/configlexer.lex" { BEGIN(singlequotedstr); LEXOUT(("SQS ")); } YY_BREAK case YY_STATE_EOF(singlequotedstr): -#line 243 "util/configlexer.lex" +#line 245 "util/configlexer.lex" { yyerror("EOF inside quoted string"); if(--num_args == 0) { BEGIN(INITIAL); } else { BEGIN(val); } } YY_BREAK -case 101: +case 103: YY_RULE_SETUP -#line 248 "util/configlexer.lex" +#line 250 "util/configlexer.lex" { LEXOUT(("STR(%s) ", yytext)); yymore(); } YY_BREAK -case 102: -/* rule 102 can match eol */ +case 104: +/* rule 104 can match eol */ YY_RULE_SETUP -#line 249 "util/configlexer.lex" +#line 251 "util/configlexer.lex" { yyerror("newline inside quoted string, no end '"); cfg_parser->line++; BEGIN(INITIAL); } YY_BREAK -case 103: +case 105: YY_RULE_SETUP -#line 251 "util/configlexer.lex" +#line 253 "util/configlexer.lex" { LEXOUT(("SQE ")); if(--num_args == 0) { BEGIN(INITIAL); } @@ -2231,38 +2254,38 @@ YY_RULE_SETUP } YY_BREAK /* include: directive */ -case 104: +case 106: YY_RULE_SETUP -#line 263 "util/configlexer.lex" +#line 265 "util/configlexer.lex" { LEXOUT(("v(%s) ", yytext)); inc_prev = YYSTATE; BEGIN(include); } YY_BREAK case YY_STATE_EOF(include): -#line 265 "util/configlexer.lex" +#line 267 "util/configlexer.lex" { yyerror("EOF inside include directive"); BEGIN(inc_prev); } YY_BREAK -case 105: -YY_RULE_SETUP -#line 269 "util/configlexer.lex" -{ LEXOUT(("ISP ")); /* ignore */ } - YY_BREAK -case 106: -/* rule 106 can match eol */ -YY_RULE_SETUP -#line 270 "util/configlexer.lex" -{ LEXOUT(("NL\n")); cfg_parser->line++;} - YY_BREAK case 107: YY_RULE_SETUP #line 271 "util/configlexer.lex" -{ LEXOUT(("IQS ")); BEGIN(include_quoted); } +{ LEXOUT(("ISP ")); /* ignore */ } YY_BREAK case 108: +/* rule 108 can match eol */ YY_RULE_SETUP #line 272 "util/configlexer.lex" +{ LEXOUT(("NL\n")); cfg_parser->line++;} + YY_BREAK +case 109: +YY_RULE_SETUP +#line 273 "util/configlexer.lex" +{ LEXOUT(("IQS ")); BEGIN(include_quoted); } + YY_BREAK +case 110: +YY_RULE_SETUP +#line 274 "util/configlexer.lex" { LEXOUT(("Iunquotedstr(%s) ", yytext)); config_start_include(yytext); @@ -2270,27 +2293,27 @@ YY_RULE_SETUP } YY_BREAK case YY_STATE_EOF(include_quoted): -#line 277 "util/configlexer.lex" +#line 279 "util/configlexer.lex" { yyerror("EOF inside quoted string"); BEGIN(inc_prev); } YY_BREAK -case 109: +case 111: YY_RULE_SETUP -#line 281 "util/configlexer.lex" +#line 283 "util/configlexer.lex" { LEXOUT(("ISTR(%s) ", yytext)); yymore(); } YY_BREAK -case 110: -/* rule 110 can match eol */ +case 112: +/* rule 112 can match eol */ YY_RULE_SETUP -#line 282 "util/configlexer.lex" +#line 284 "util/configlexer.lex" { yyerror("newline before \" in include name"); cfg_parser->line++; BEGIN(inc_prev); } YY_BREAK -case 111: +case 113: YY_RULE_SETUP -#line 284 "util/configlexer.lex" +#line 286 "util/configlexer.lex" { LEXOUT(("IQE ")); yytext[yyleng - 1] = '\0'; @@ -2300,7 +2323,7 @@ YY_RULE_SETUP YY_BREAK case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(val): -#line 290 "util/configlexer.lex" +#line 292 "util/configlexer.lex" { yy_set_bol(1); /* Set beginning of line, so "^" rules match. */ if (config_include_stack_ptr == 0) { @@ -2311,33 +2334,33 @@ case YY_STATE_EOF(val): } } YY_BREAK -case 112: +case 114: YY_RULE_SETUP -#line 300 "util/configlexer.lex" +#line 302 "util/configlexer.lex" { LEXOUT(("unquotedstr(%s) ", yytext)); if(--num_args == 0) { BEGIN(INITIAL); } yylval.str = strdup(yytext); return STRING; } YY_BREAK -case 113: +case 115: YY_RULE_SETUP -#line 304 "util/configlexer.lex" +#line 306 "util/configlexer.lex" { ub_c_error_msg("unknown keyword '%s'", yytext); } YY_BREAK -case 114: +case 116: YY_RULE_SETUP -#line 308 "util/configlexer.lex" +#line 310 "util/configlexer.lex" { ub_c_error_msg("stray '%s'", yytext); } YY_BREAK -case 115: +case 117: YY_RULE_SETUP -#line 312 "util/configlexer.lex" +#line 314 "util/configlexer.lex" ECHO; YY_BREAK -#line 2339 "" +#line 2362 "" case YY_END_OF_BUFFER: { @@ -2627,7 +2650,7 @@ static int yy_get_next_buffer (void) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 1074 ) + if ( yy_current_state >= 1088 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -2655,11 +2678,11 @@ static int yy_get_next_buffer (void) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 1074 ) + if ( yy_current_state >= 1088 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 1073); + yy_is_jam = (yy_current_state == 1087); return yy_is_jam ? 0 : yy_current_state; } @@ -3296,7 +3319,7 @@ void yyfree (void * ptr ) #define YYTABLES_NAME "yytables" -#line 312 "util/configlexer.lex" +#line 314 "util/configlexer.lex" diff --git a/util/configlexer.lex b/util/configlexer.lex index bed3b3a47..1d47b77e3 100644 --- a/util/configlexer.lex +++ b/util/configlexer.lex @@ -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) } {NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++; } diff --git a/util/configparser.c b/util/configparser.c index 6b1fc6eea..b63ece883 100644 --- a/util/configparser.c +++ b/util/configparser.c @@ -165,7 +165,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. */ @@ -269,6 +271,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 @@ -327,7 +331,7 @@ typedef union YYSTYPE char* str; } /* Line 187 of yacc.c. */ -#line 331 "util/configparser.c" +#line 335 "util/configparser.c" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 @@ -340,7 +344,7 @@ typedef union YYSTYPE /* Line 216 of yacc.c. */ -#line 344 "util/configparser.c" +#line 348 "util/configparser.c" #ifdef short # undef short @@ -555,20 +559,20 @@ union yyalloc /* YYFINAL -- State number of the termination state. */ #define YYFINAL 2 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 184 +#define YYLAST 194 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 103 +#define YYNTOKENS 105 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 104 +#define YYNNTS 108 /* YYNRULES -- Number of rules. */ -#define YYNRULES 197 +#define YYNRULES 203 /* YYNRULES -- Number of states. */ -#define YYNSTATES 289 +#define YYNSTATES 296 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 357 +#define YYMAXUTOK 359 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -611,7 +615,7 @@ static const yytype_uint8 yytranslate[] = 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, - 95, 96, 97, 98, 99, 100, 101, 102 + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104 }; #if YYDEBUG @@ -619,105 +623,109 @@ static const yytype_uint8 yytranslate[] = YYRHS. */ static const yytype_uint16 yyprhs[] = { - 0, 0, 3, 4, 7, 10, 13, 16, 19, 21, - 24, 25, 27, 29, 31, 33, 35, 37, 39, 41, - 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, - 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, - 83, 85, 87, 89, 91, 93, 95, 97, 99, 101, - 103, 105, 107, 109, 111, 113, 115, 117, 119, 121, - 123, 125, 127, 129, 131, 133, 135, 137, 139, 141, - 143, 145, 147, 149, 151, 153, 155, 157, 159, 161, - 163, 165, 167, 169, 171, 173, 175, 177, 180, 181, - 183, 185, 187, 189, 191, 194, 195, 197, 199, 201, + 0, 0, 3, 4, 7, 10, 13, 16, 19, 22, + 24, 27, 28, 30, 32, 34, 36, 38, 40, 42, + 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, + 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, + 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, + 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, + 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, + 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, + 164, 166, 168, 170, 172, 174, 176, 178, 180, 183, + 184, 186, 188, 190, 192, 194, 197, 198, 200, 202, 204, 207, 210, 213, 216, 219, 222, 225, 228, 231, 234, 237, 240, 243, 246, 249, 252, 255, 258, 261, 264, 267, 270, 273, 276, 279, 282, 285, 288, 291, 294, 297, 300, 303, 306, 309, 312, 315, 318, 321, 324, 327, 330, 333, 336, 339, 342, 345, 348, 351, 354, 357, 360, 363, 366, 369, 372, 375, 378, 381, - 384, 388, 391, 394, 397, 400, 403, 406, 409, 412, - 415, 418, 422, 425, 428, 431, 434, 437, 440, 443, - 446, 449, 451, 454, 455, 457, 459, 461, 463, 465, - 467, 469, 472, 475, 478, 481, 484, 487 + 384, 387, 391, 394, 397, 400, 403, 406, 409, 412, + 415, 418, 421, 425, 428, 431, 434, 437, 440, 443, + 446, 449, 452, 454, 457, 458, 460, 462, 464, 466, + 468, 470, 472, 475, 478, 481, 484, 487, 490, 493, + 495, 498, 499, 501 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int16 yyrhs[] = { - 104, 0, -1, -1, 104, 105, -1, 106, 107, -1, - 109, 110, -1, 112, 113, -1, 197, 198, -1, 11, - -1, 107, 108, -1, -1, 115, -1, 116, -1, 120, - -1, 123, -1, 129, -1, 130, -1, 131, -1, 132, - -1, 121, -1, 136, -1, 137, -1, 138, -1, 139, - -1, 140, -1, 153, -1, 154, -1, 155, -1, 157, - -1, 158, -1, 126, -1, 159, -1, 160, -1, 163, - -1, 161, -1, 162, -1, 164, -1, 165, -1, 166, - -1, 174, -1, 148, -1, 149, -1, 150, -1, 151, - -1, 167, -1, 177, -1, 144, -1, 146, -1, 178, - -1, 180, -1, 181, -1, 182, -1, 127, -1, 152, - -1, 184, -1, 185, -1, 145, -1, 183, -1, 134, - -1, 122, -1, 141, -1, 175, -1, 179, -1, 168, - -1, 176, -1, 187, -1, 188, -1, 128, -1, 117, - -1, 133, -1, 170, -1, 118, -1, 124, -1, 125, - -1, 142, -1, 143, -1, 186, -1, 169, -1, 171, - -1, 172, -1, 119, -1, 189, -1, 156, -1, 173, - -1, 135, -1, 147, -1, 38, -1, 110, 111, -1, - -1, 190, -1, 191, -1, 192, -1, 193, -1, 44, - -1, 113, 114, -1, -1, 194, -1, 195, -1, 196, - -1, 13, 10, -1, 12, 10, -1, 76, 10, -1, - 79, 10, -1, 96, 10, -1, 14, 10, -1, 16, - 10, -1, 67, 10, -1, 15, 10, -1, 80, 10, - -1, 81, 10, -1, 31, 10, -1, 60, 10, -1, - 75, 10, -1, 17, 10, -1, 18, 10, -1, 19, - 10, -1, 20, 10, -1, 77, 10, -1, 66, 10, - -1, 101, 10, -1, 21, 10, -1, 22, 10, -1, - 23, 10, -1, 24, 10, -1, 25, 10, -1, 68, - 10, -1, 82, 10, -1, 83, 10, -1, 54, 10, - -1, 64, 10, -1, 55, 10, -1, 102, 10, -1, - 48, 10, -1, 49, 10, -1, 50, 10, -1, 51, - 10, -1, 61, 10, -1, 26, 10, -1, 27, 10, - -1, 28, 10, -1, 98, 10, -1, 29, 10, -1, - 30, 10, -1, 32, 10, -1, 33, 10, -1, 35, - 10, -1, 36, 10, -1, 34, 10, -1, 41, 10, - -1, 42, 10, -1, 43, 10, -1, 52, 10, -1, - 71, 10, -1, 85, 10, -1, 78, 10, -1, 86, - 10, -1, 87, 10, -1, 100, 10, -1, 47, 10, - -1, 69, 10, -1, 72, 10, 10, -1, 53, 10, - -1, 56, 10, -1, 70, 10, -1, 57, 10, -1, - 58, 10, -1, 59, 10, -1, 65, 10, -1, 62, - 10, -1, 63, 10, -1, 84, 10, -1, 73, 10, - 10, -1, 74, 10, -1, 97, 10, -1, 37, 10, - -1, 39, 10, -1, 40, 10, -1, 99, 10, -1, - 37, 10, -1, 45, 10, -1, 46, 10, -1, 88, - -1, 198, 199, -1, -1, 200, -1, 202, -1, 201, - -1, 203, -1, 204, -1, 205, -1, 206, -1, 89, - 10, -1, 91, 10, -1, 90, 10, -1, 92, 10, - -1, 93, 10, -1, 94, 10, -1, 95, 10, -1 + 106, 0, -1, -1, 106, 107, -1, 108, 109, -1, + 111, 112, -1, 114, 115, -1, 209, 210, -1, 199, + 200, -1, 11, -1, 109, 110, -1, -1, 117, -1, + 118, -1, 122, -1, 125, -1, 131, -1, 132, -1, + 133, -1, 134, -1, 123, -1, 138, -1, 139, -1, + 140, -1, 141, -1, 142, -1, 155, -1, 156, -1, + 157, -1, 159, -1, 160, -1, 128, -1, 161, -1, + 162, -1, 165, -1, 163, -1, 164, -1, 166, -1, + 167, -1, 168, -1, 176, -1, 150, -1, 151, -1, + 152, -1, 153, -1, 169, -1, 179, -1, 146, -1, + 148, -1, 180, -1, 182, -1, 183, -1, 184, -1, + 129, -1, 154, -1, 186, -1, 187, -1, 147, -1, + 185, -1, 136, -1, 124, -1, 143, -1, 177, -1, + 181, -1, 170, -1, 178, -1, 189, -1, 190, -1, + 130, -1, 119, -1, 135, -1, 172, -1, 120, -1, + 126, -1, 127, -1, 144, -1, 145, -1, 188, -1, + 171, -1, 173, -1, 174, -1, 121, -1, 191, -1, + 158, -1, 175, -1, 137, -1, 149, -1, 38, -1, + 112, 113, -1, -1, 192, -1, 193, -1, 194, -1, + 195, -1, 44, -1, 115, 116, -1, -1, 196, -1, + 197, -1, 198, -1, 13, 10, -1, 12, 10, -1, + 76, 10, -1, 79, 10, -1, 96, 10, -1, 14, + 10, -1, 16, 10, -1, 67, 10, -1, 15, 10, + -1, 80, 10, -1, 81, 10, -1, 31, 10, -1, + 60, 10, -1, 75, 10, -1, 17, 10, -1, 18, + 10, -1, 19, 10, -1, 20, 10, -1, 77, 10, + -1, 66, 10, -1, 101, 10, -1, 21, 10, -1, + 22, 10, -1, 23, 10, -1, 24, 10, -1, 25, + 10, -1, 68, 10, -1, 82, 10, -1, 83, 10, + -1, 54, 10, -1, 64, 10, -1, 55, 10, -1, + 102, 10, -1, 48, 10, -1, 49, 10, -1, 50, + 10, -1, 51, 10, -1, 61, 10, -1, 26, 10, + -1, 27, 10, -1, 28, 10, -1, 98, 10, -1, + 29, 10, -1, 30, 10, -1, 32, 10, -1, 33, + 10, -1, 35, 10, -1, 36, 10, -1, 34, 10, + -1, 41, 10, -1, 42, 10, -1, 43, 10, -1, + 52, 10, -1, 71, 10, -1, 85, 10, -1, 78, + 10, -1, 86, 10, -1, 87, 10, -1, 100, 10, + -1, 47, 10, -1, 69, 10, -1, 72, 10, 10, + -1, 53, 10, -1, 56, 10, -1, 70, 10, -1, + 57, 10, -1, 58, 10, -1, 59, 10, -1, 65, + 10, -1, 62, 10, -1, 63, 10, -1, 84, 10, + -1, 73, 10, 10, -1, 74, 10, -1, 97, 10, + -1, 37, 10, -1, 39, 10, -1, 40, 10, -1, + 99, 10, -1, 37, 10, -1, 45, 10, -1, 46, + 10, -1, 88, -1, 200, 201, -1, -1, 202, -1, + 204, -1, 203, -1, 205, -1, 206, -1, 207, -1, + 208, -1, 89, 10, -1, 91, 10, -1, 90, 10, + -1, 92, 10, -1, 93, 10, -1, 94, 10, -1, + 95, 10, -1, 103, -1, 210, 211, -1, -1, 212, + -1, 104, 10, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 103, 103, 103, 104, 104, 105, 105, 109, 114, - 115, 116, 116, 116, 117, 117, 118, 118, 118, 119, - 119, 119, 120, 120, 120, 121, 121, 122, 122, 123, - 123, 124, 124, 125, 125, 126, 126, 127, 127, 128, - 128, 129, 129, 129, 130, 130, 130, 131, 131, 131, - 132, 132, 133, 133, 134, 134, 135, 135, 136, 136, - 136, 137, 137, 138, 138, 139, 139, 139, 140, 140, - 141, 141, 142, 142, 143, 143, 143, 144, 144, 145, - 145, 146, 146, 147, 147, 148, 150, 162, 163, 164, - 164, 164, 164, 166, 178, 179, 180, 180, 180, 182, - 191, 200, 211, 220, 229, 238, 251, 266, 275, 284, - 293, 302, 311, 320, 329, 338, 347, 356, 365, 379, - 388, 395, 402, 409, 417, 424, 431, 438, 445, 453, - 461, 468, 475, 484, 493, 500, 507, 518, 526, 539, - 548, 557, 565, 578, 587, 596, 605, 614, 627, 634, - 644, 654, 664, 674, 684, 694, 701, 708, 717, 724, - 734, 748, 755, 773, 782, 791, 801, 811, 818, 826, - 839, 847, 867, 874, 889, 896, 903, 910, 920, 927, - 934, 941, 946, 947, 948, 948, 948, 949, 949, 949, - 950, 952, 962, 971, 978, 985, 992, 999 + 0, 103, 103, 103, 104, 104, 105, 105, 106, 110, + 115, 116, 117, 117, 117, 118, 118, 119, 119, 119, + 120, 120, 120, 121, 121, 121, 122, 122, 123, 123, + 124, 124, 125, 125, 126, 126, 127, 127, 128, 128, + 129, 129, 130, 130, 130, 131, 131, 131, 132, 132, + 132, 133, 133, 134, 134, 135, 135, 136, 136, 137, + 137, 137, 138, 138, 139, 139, 140, 140, 140, 141, + 141, 142, 142, 143, 143, 144, 144, 144, 145, 145, + 146, 146, 147, 147, 148, 148, 149, 151, 163, 164, + 165, 165, 165, 165, 167, 179, 180, 181, 181, 181, + 183, 192, 201, 212, 221, 230, 239, 252, 267, 276, + 285, 294, 303, 312, 321, 330, 339, 348, 357, 366, + 380, 389, 396, 403, 410, 418, 425, 432, 439, 446, + 454, 462, 469, 476, 485, 494, 501, 508, 519, 527, + 540, 549, 558, 566, 579, 588, 597, 606, 615, 628, + 635, 645, 655, 665, 675, 685, 695, 702, 709, 718, + 725, 735, 749, 756, 774, 783, 792, 802, 812, 819, + 827, 840, 848, 868, 875, 890, 897, 904, 911, 921, + 928, 935, 942, 947, 948, 949, 949, 949, 950, 950, + 950, 951, 953, 963, 972, 979, 986, 993, 1000, 1007, + 1012, 1013, 1014, 1016 }; #endif @@ -758,17 +766,17 @@ static const char *const yytname[] = "VAR_SERVER_CERT_FILE", "VAR_CONTROL_KEY_FILE", "VAR_CONTROL_CERT_FILE", "VAR_EXTENDED_STATISTICS", "VAR_LOCAL_DATA_PTR", "VAR_JOSTLE_TIMEOUT", "VAR_STUB_PRIME", "VAR_UNWANTED_REPLY_THRESHOLD", "VAR_LOG_TIME_ASCII", - "VAR_DOMAIN_INSECURE", "$accept", "toplevelvars", "toplevelvar", - "serverstart", "contents_server", "content_server", "stubstart", - "contents_stub", "content_stub", "forwardstart", "contents_forward", - "content_forward", "server_num_threads", "server_verbosity", - "server_statistics_interval", "server_statistics_cumulative", - "server_extended_statistics", "server_port", "server_interface", - "server_outgoing_interface", "server_outgoing_range", - "server_outgoing_port_permit", "server_outgoing_port_avoid", - "server_outgoing_num_tcp", "server_incoming_num_tcp", - "server_interface_automatic", "server_do_ip4", "server_do_ip6", - "server_do_udp", "server_do_tcp", "server_do_daemonize", + "VAR_DOMAIN_INSECURE", "VAR_PYTHON", "VAR_PYTHON_SCRIPT", "$accept", + "toplevelvars", "toplevelvar", "serverstart", "contents_server", + "content_server", "stubstart", "contents_stub", "content_stub", + "forwardstart", "contents_forward", "content_forward", + "server_num_threads", "server_verbosity", "server_statistics_interval", + "server_statistics_cumulative", "server_extended_statistics", + "server_port", "server_interface", "server_outgoing_interface", + "server_outgoing_range", "server_outgoing_port_permit", + "server_outgoing_port_avoid", "server_outgoing_num_tcp", + "server_incoming_num_tcp", "server_interface_automatic", "server_do_ip4", + "server_do_ip6", "server_do_udp", "server_do_tcp", "server_do_daemonize", "server_use_syslog", "server_log_time_ascii", "server_chroot", "server_username", "server_directory", "server_logfile", "server_pidfile", "server_root_hints", "server_dlv_anchor_file", @@ -797,7 +805,8 @@ static const char *const yytname[] = "stub_prime", "forward_name", "forward_host", "forward_addr", "rcstart", "contents_rc", "content_rc", "rc_control_enable", "rc_control_port", "rc_control_interface", "rc_server_key_file", "rc_server_cert_file", - "rc_control_key_file", "rc_control_cert_file", 0 + "rc_control_key_file", "rc_control_cert_file", "pythonstart", + "contents_py", "content_py", "py_script", 0 }; #endif @@ -816,58 +825,60 @@ static const yytype_uint16 yytoknum[] = 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, - 355, 356, 357 + 355, 356, 357, 358, 359 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { - 0, 103, 104, 104, 105, 105, 105, 105, 106, 107, - 107, 108, 108, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 109, 110, 110, 111, - 111, 111, 111, 112, 113, 113, 114, 114, 114, 115, - 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, - 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, - 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, - 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, - 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, - 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, - 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, - 196, 197, 198, 198, 199, 199, 199, 199, 199, 199, - 199, 200, 201, 202, 203, 204, 205, 206 + 0, 105, 106, 106, 107, 107, 107, 107, 107, 108, + 109, 109, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 111, 112, 112, + 113, 113, 113, 113, 114, 115, 115, 116, 116, 116, + 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, + 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, + 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, + 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, + 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, + 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, + 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, + 197, 198, 199, 200, 200, 201, 201, 201, 201, 201, + 201, 201, 202, 203, 204, 205, 206, 207, 208, 209, + 210, 210, 211, 212 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { - 0, 2, 0, 2, 2, 2, 2, 2, 1, 2, - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 2, 0, 2, 2, 2, 2, 2, 2, 1, + 2, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 2, 0, 1, - 1, 1, 1, 1, 2, 0, 1, 1, 1, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, + 1, 1, 1, 1, 1, 2, 0, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 1, 2, 0, 1, 1, 1, 1, 1, 1, - 1, 2, 2, 2, 2, 2, 2, 2 + 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 1, 2, 0, 1, 1, 1, 1, 1, + 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, + 2, 0, 1, 2 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state @@ -875,8 +886,8 @@ static const yytype_uint8 yyr2[] = means the default is an error. */ static const yytype_uint8 yydefact[] = { - 2, 0, 1, 8, 86, 93, 181, 3, 10, 88, - 95, 183, 4, 5, 6, 7, 0, 0, 0, 0, + 2, 0, 1, 9, 87, 94, 182, 199, 3, 11, + 89, 96, 184, 201, 4, 5, 6, 8, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -884,94 +895,96 @@ static const yytype_uint8 yydefact[] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 9, 11, 12, 68, 71, 80, 13, 19, 59, - 14, 72, 73, 30, 52, 67, 15, 16, 17, 18, - 69, 58, 84, 20, 21, 22, 23, 24, 60, 74, - 75, 46, 56, 47, 85, 40, 41, 42, 43, 53, - 25, 26, 27, 82, 28, 29, 31, 32, 34, 35, - 33, 36, 37, 38, 44, 63, 77, 70, 78, 79, - 83, 39, 61, 64, 45, 48, 62, 49, 50, 51, - 57, 54, 55, 76, 65, 66, 81, 0, 0, 0, - 0, 87, 89, 90, 91, 92, 0, 0, 0, 94, - 96, 97, 98, 0, 0, 0, 0, 0, 0, 0, - 182, 184, 186, 185, 187, 188, 189, 190, 100, 99, - 104, 107, 105, 113, 114, 115, 116, 120, 121, 122, - 123, 124, 137, 138, 139, 141, 142, 110, 143, 144, - 147, 145, 146, 148, 149, 150, 158, 132, 133, 134, - 135, 151, 161, 128, 130, 162, 164, 165, 166, 111, - 136, 168, 169, 129, 167, 118, 106, 125, 159, 163, - 152, 0, 0, 172, 112, 101, 117, 154, 102, 108, - 109, 126, 127, 170, 153, 155, 156, 103, 173, 140, - 157, 119, 131, 174, 175, 176, 177, 178, 179, 180, - 191, 193, 192, 194, 195, 196, 197, 160, 171 + 0, 0, 0, 0, 10, 12, 13, 69, 72, 81, + 14, 20, 60, 15, 73, 74, 31, 53, 68, 16, + 17, 18, 19, 70, 59, 85, 21, 22, 23, 24, + 25, 61, 75, 76, 47, 57, 48, 86, 41, 42, + 43, 44, 54, 26, 27, 28, 83, 29, 30, 32, + 33, 35, 36, 34, 37, 38, 39, 45, 64, 78, + 71, 79, 80, 84, 40, 62, 65, 46, 49, 63, + 50, 51, 52, 58, 55, 56, 77, 66, 67, 82, + 0, 0, 0, 0, 88, 90, 91, 92, 93, 0, + 0, 0, 95, 97, 98, 99, 0, 0, 0, 0, + 0, 0, 0, 183, 185, 187, 186, 188, 189, 190, + 191, 0, 200, 202, 101, 100, 105, 108, 106, 114, + 115, 116, 117, 121, 122, 123, 124, 125, 138, 139, + 140, 142, 143, 111, 144, 145, 148, 146, 147, 149, + 150, 151, 159, 133, 134, 135, 136, 152, 162, 129, + 131, 163, 165, 166, 167, 112, 137, 169, 170, 130, + 168, 119, 107, 126, 160, 164, 153, 0, 0, 173, + 113, 102, 118, 155, 103, 109, 110, 127, 128, 171, + 154, 156, 157, 104, 174, 141, 158, 120, 132, 175, + 176, 177, 178, 179, 180, 181, 192, 194, 193, 195, + 196, 197, 198, 203, 161, 172 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { - -1, 1, 7, 8, 12, 91, 9, 13, 171, 10, - 14, 179, 92, 93, 94, 95, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, - 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, - 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, - 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, - 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, - 160, 161, 162, 163, 164, 165, 166, 172, 173, 174, - 175, 180, 181, 182, 11, 15, 190, 191, 192, 193, - 194, 195, 196, 197 + -1, 1, 8, 9, 14, 94, 10, 15, 174, 11, + 16, 182, 95, 96, 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, + 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, + 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, + 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, + 163, 164, 165, 166, 167, 168, 169, 175, 176, 177, + 178, 183, 184, 185, 12, 17, 193, 194, 195, 196, + 197, 198, 199, 200, 13, 18, 202, 203 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ -#define YYPACT_NINF -13 +#define YYPACT_NINF -103 static const yytype_int16 yypact[] = { - -13, 76, -13, -13, -13, -13, -13, -13, -13, -13, - -13, -13, -12, 40, 46, 4, 15, 16, 17, 18, - 22, 23, 24, 68, 71, 72, 90, 91, 92, 93, - 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, - 105, 106, 107, 108, 109, 111, 112, 113, 114, 115, - 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, - 126, 127, 128, 130, 131, 132, 133, 134, 135, 136, - 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, - 147, 148, 149, 150, 151, 152, 153, 155, 156, 157, - 158, -13, -13, -13, -13, -13, -13, -13, -13, -13, - -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, - -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, - -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, - -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, - -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, - -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, - -13, -13, -13, -13, -13, -13, -13, 159, 160, 161, - 162, -13, -13, -13, -13, -13, 163, 164, 165, -13, - -13, -13, -13, 166, 167, 168, 169, 170, 171, 172, - -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, - -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, - -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, - -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, - -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, - -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, - -13, 173, 174, -13, -13, -13, -13, -13, -13, -13, - -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, - -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, - -13, -13, -13, -13, -13, -13, -13, -13, -13 + -103, 0, -103, -103, -103, -103, -103, -103, -103, -103, + -103, -103, -103, -103, 92, -36, -32, -74, -102, -4, + -3, -2, -1, 2, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + 29, 30, 31, 32, 33, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 79, 80, 81, + 82, 83, 84, 85, -103, -103, -103, -103, -103, -103, + -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, + -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, + -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, + -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, + -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, + -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, + -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, + 86, 87, 88, 89, -103, -103, -103, -103, -103, 90, + 91, 119, -103, -103, -103, -103, 120, 121, 122, 126, + 127, 128, 170, -103, -103, -103, -103, -103, -103, -103, + -103, 171, -103, -103, -103, -103, -103, -103, -103, -103, + -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, + -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, + -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, + -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, + -103, -103, -103, -103, -103, -103, -103, 172, 173, -103, + -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, + -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, + -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, + -103, -103, -103, -103, -103, -103 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { - -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, - -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, - -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, - -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, - -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, - -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, - -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, - -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, - -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, - -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, - -13, -13, -13, -13 + -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, + -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, + -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, + -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, + -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, + -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, + -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, + -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, + -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, + -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, + -103, -103, -103, -103, -103, -103, -103, -103 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If @@ -981,74 +994,77 @@ static const yytype_int8 yypgoto[] = #define YYTABLE_NINF -1 static const yytype_uint16 yytable[] = { - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 36, 37, 38, 39, 40, 198, 199, 200, 201, 41, - 42, 43, 202, 203, 204, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, - 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, - 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, - 79, 80, 81, 82, 83, 84, 2, 167, 205, 168, - 169, 206, 207, 176, 85, 86, 87, 3, 88, 89, - 90, 177, 178, 183, 184, 185, 186, 187, 188, 189, - 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, - 218, 219, 220, 221, 4, 222, 223, 224, 225, 226, - 5, 227, 228, 229, 230, 231, 232, 233, 234, 235, - 236, 237, 238, 239, 240, 241, 242, 243, 244, 170, - 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, - 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 6, 269, 270, 271, 272, 273, - 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, - 284, 285, 286, 287, 288 + 2, 170, 201, 171, 172, 179, 204, 205, 206, 207, + 0, 3, 208, 180, 181, 186, 187, 188, 189, 190, + 191, 192, 209, 210, 211, 212, 213, 214, 215, 216, + 217, 218, 219, 220, 221, 222, 223, 224, 4, 225, + 226, 227, 228, 229, 5, 230, 231, 232, 233, 234, + 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, + 245, 246, 247, 173, 248, 249, 250, 251, 252, 253, + 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, + 264, 265, 266, 267, 268, 269, 270, 271, 6, 272, + 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, + 283, 284, 0, 7, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 285, + 286, 287, 288, 44, 45, 46, 289, 290, 291, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, + 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, + 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, + 292, 293, 294, 295, 0, 0, 0, 0, 88, 89, + 90, 0, 91, 92, 93 }; -static const yytype_uint8 yycheck[] = +static const yytype_int8 yycheck[] = { - 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, - 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 10, 10, 10, 10, 41, - 42, 43, 10, 10, 10, 47, 48, 49, 50, 51, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, - 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, - 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, - 82, 83, 84, 85, 86, 87, 0, 37, 10, 39, - 40, 10, 10, 37, 96, 97, 98, 11, 100, 101, - 102, 45, 46, 89, 90, 91, 92, 93, 94, 95, + 0, 37, 104, 39, 40, 37, 10, 10, 10, 10, + -1, 11, 10, 45, 46, 89, 90, 91, 92, 93, + 94, 95, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 38, 10, + 10, 10, 10, 10, 44, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 38, 10, 10, 10, 10, 10, - 44, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 99, + 10, 10, 10, 99, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 88, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 88, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10 + 10, 10, -1, 103, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 10, + 10, 10, 10, 41, 42, 43, 10, 10, 10, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, + 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, + 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, + 10, 10, 10, 10, -1, -1, -1, -1, 96, 97, + 98, -1, 100, 101, 102 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { - 0, 104, 0, 11, 38, 44, 88, 105, 106, 109, - 112, 197, 107, 110, 113, 198, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 36, 41, 42, 43, 47, 48, 49, 50, 51, 52, - 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, - 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, - 83, 84, 85, 86, 87, 96, 97, 98, 100, 101, - 102, 108, 115, 116, 117, 118, 119, 120, 121, 122, - 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, - 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, - 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, - 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, - 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, - 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, - 183, 184, 185, 186, 187, 188, 189, 37, 39, 40, - 99, 111, 190, 191, 192, 193, 37, 45, 46, 114, - 194, 195, 196, 89, 90, 91, 92, 93, 94, 95, - 199, 200, 201, 202, 203, 204, 205, 206, 10, 10, + 0, 106, 0, 11, 38, 44, 88, 103, 107, 108, + 111, 114, 199, 209, 109, 112, 115, 200, 210, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 41, 42, 43, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 96, 97, + 98, 100, 101, 102, 110, 117, 118, 119, 120, 121, + 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, + 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, + 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, + 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, + 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, + 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, + 37, 39, 40, 99, 113, 192, 193, 194, 195, 37, + 45, 46, 116, 196, 197, 198, 89, 90, 91, 92, + 93, 94, 95, 201, 202, 203, 204, 205, 206, 207, + 208, 104, 211, 212, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, @@ -1057,7 +1073,7 @@ static const yytype_uint8 yystos[] = 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10 + 10, 10, 10, 10, 10, 10 }; #define yyerrok (yyerrstatus = 0) @@ -1871,15 +1887,15 @@ yyreduce: YY_REDUCE_PRINT (yyn); switch (yyn) { - case 8: -#line 110 "util/configparser.y" + case 9: +#line 111 "util/configparser.y" { OUTYY(("\nP(server:)\n")); } break; - case 86: -#line 151 "util/configparser.y" + case 87: +#line 152 "util/configparser.y" { struct config_stub* s; OUTYY(("\nP(stub_zone:)\n")); @@ -1892,8 +1908,8 @@ yyreduce: } break; - case 93: -#line 167 "util/configparser.y" + case 94: +#line 168 "util/configparser.y" { struct config_stub* s; OUTYY(("\nP(forward_zone:)\n")); @@ -1906,8 +1922,8 @@ yyreduce: } break; - case 99: -#line 183 "util/configparser.y" + case 100: +#line 184 "util/configparser.y" { OUTYY(("P(server_num_threads:%s)\n", (yyvsp[(2) - (2)].str))); if(atoi((yyvsp[(2) - (2)].str)) == 0 && strcmp((yyvsp[(2) - (2)].str), "0") != 0) @@ -1917,8 +1933,8 @@ yyreduce: } break; - case 100: -#line 192 "util/configparser.y" + case 101: +#line 193 "util/configparser.y" { OUTYY(("P(server_verbosity:%s)\n", (yyvsp[(2) - (2)].str))); if(atoi((yyvsp[(2) - (2)].str)) == 0 && strcmp((yyvsp[(2) - (2)].str), "0") != 0) @@ -1928,8 +1944,8 @@ yyreduce: } break; - case 101: -#line 201 "util/configparser.y" + case 102: +#line 202 "util/configparser.y" { OUTYY(("P(server_statistics_interval:%s)\n", (yyvsp[(2) - (2)].str))); if(strcmp((yyvsp[(2) - (2)].str), "") == 0 || strcmp((yyvsp[(2) - (2)].str), "0") == 0) @@ -1941,8 +1957,8 @@ yyreduce: } break; - case 102: -#line 212 "util/configparser.y" + case 103: +#line 213 "util/configparser.y" { OUTYY(("P(server_statistics_cumulative:%s)\n", (yyvsp[(2) - (2)].str))); if(strcmp((yyvsp[(2) - (2)].str), "yes") != 0 && strcmp((yyvsp[(2) - (2)].str), "no") != 0) @@ -1952,8 +1968,8 @@ yyreduce: } break; - case 103: -#line 221 "util/configparser.y" + case 104: +#line 222 "util/configparser.y" { OUTYY(("P(server_extended_statistics:%s)\n", (yyvsp[(2) - (2)].str))); if(strcmp((yyvsp[(2) - (2)].str), "yes") != 0 && strcmp((yyvsp[(2) - (2)].str), "no") != 0) @@ -1963,8 +1979,8 @@ yyreduce: } break; - case 104: -#line 230 "util/configparser.y" + case 105: +#line 231 "util/configparser.y" { OUTYY(("P(server_port:%s)\n", (yyvsp[(2) - (2)].str))); if(atoi((yyvsp[(2) - (2)].str)) == 0) @@ -1974,8 +1990,8 @@ yyreduce: } break; - case 105: -#line 239 "util/configparser.y" + case 106: +#line 240 "util/configparser.y" { OUTYY(("P(server_interface:%s)\n", (yyvsp[(2) - (2)].str))); if(cfg_parser->cfg->num_ifs == 0) @@ -1989,8 +2005,8 @@ yyreduce: } break; - case 106: -#line 252 "util/configparser.y" + case 107: +#line 253 "util/configparser.y" { OUTYY(("P(server_outgoing_interface:%s)\n", (yyvsp[(2) - (2)].str))); if(cfg_parser->cfg->num_out_ifs == 0) @@ -2006,8 +2022,8 @@ yyreduce: } break; - case 107: -#line 267 "util/configparser.y" + case 108: +#line 268 "util/configparser.y" { OUTYY(("P(server_outgoing_range:%s)\n", (yyvsp[(2) - (2)].str))); if(atoi((yyvsp[(2) - (2)].str)) == 0) @@ -2017,8 +2033,8 @@ yyreduce: } break; - case 108: -#line 276 "util/configparser.y" + case 109: +#line 277 "util/configparser.y" { OUTYY(("P(server_outgoing_port_permit:%s)\n", (yyvsp[(2) - (2)].str))); if(!cfg_mark_ports((yyvsp[(2) - (2)].str), 1, @@ -2028,8 +2044,8 @@ yyreduce: } break; - case 109: -#line 285 "util/configparser.y" + case 110: +#line 286 "util/configparser.y" { OUTYY(("P(server_outgoing_port_avoid:%s)\n", (yyvsp[(2) - (2)].str))); if(!cfg_mark_ports((yyvsp[(2) - (2)].str), 0, @@ -2039,8 +2055,8 @@ yyreduce: } break; - case 110: -#line 294 "util/configparser.y" + case 111: +#line 295 "util/configparser.y" { OUTYY(("P(server_outgoing_num_tcp:%s)\n", (yyvsp[(2) - (2)].str))); if(atoi((yyvsp[(2) - (2)].str)) == 0 && strcmp((yyvsp[(2) - (2)].str), "0") != 0) @@ -2050,8 +2066,8 @@ yyreduce: } break; - case 111: -#line 303 "util/configparser.y" + case 112: +#line 304 "util/configparser.y" { OUTYY(("P(server_incoming_num_tcp:%s)\n", (yyvsp[(2) - (2)].str))); if(atoi((yyvsp[(2) - (2)].str)) == 0 && strcmp((yyvsp[(2) - (2)].str), "0") != 0) @@ -2061,8 +2077,8 @@ yyreduce: } break; - case 112: -#line 312 "util/configparser.y" + case 113: +#line 313 "util/configparser.y" { OUTYY(("P(server_interface_automatic:%s)\n", (yyvsp[(2) - (2)].str))); if(strcmp((yyvsp[(2) - (2)].str), "yes") != 0 && strcmp((yyvsp[(2) - (2)].str), "no") != 0) @@ -2072,8 +2088,8 @@ yyreduce: } break; - case 113: -#line 321 "util/configparser.y" + case 114: +#line 322 "util/configparser.y" { OUTYY(("P(server_do_ip4:%s)\n", (yyvsp[(2) - (2)].str))); if(strcmp((yyvsp[(2) - (2)].str), "yes") != 0 && strcmp((yyvsp[(2) - (2)].str), "no") != 0) @@ -2083,8 +2099,8 @@ yyreduce: } break; - case 114: -#line 330 "util/configparser.y" + case 115: +#line 331 "util/configparser.y" { OUTYY(("P(server_do_ip6:%s)\n", (yyvsp[(2) - (2)].str))); if(strcmp((yyvsp[(2) - (2)].str), "yes") != 0 && strcmp((yyvsp[(2) - (2)].str), "no") != 0) @@ -2094,8 +2110,8 @@ yyreduce: } break; - case 115: -#line 339 "util/configparser.y" + case 116: +#line 340 "util/configparser.y" { OUTYY(("P(server_do_udp:%s)\n", (yyvsp[(2) - (2)].str))); if(strcmp((yyvsp[(2) - (2)].str), "yes") != 0 && strcmp((yyvsp[(2) - (2)].str), "no") != 0) @@ -2105,8 +2121,8 @@ yyreduce: } break; - case 116: -#line 348 "util/configparser.y" + case 117: +#line 349 "util/configparser.y" { OUTYY(("P(server_do_tcp:%s)\n", (yyvsp[(2) - (2)].str))); if(strcmp((yyvsp[(2) - (2)].str), "yes") != 0 && strcmp((yyvsp[(2) - (2)].str), "no") != 0) @@ -2116,8 +2132,8 @@ yyreduce: } break; - case 117: -#line 357 "util/configparser.y" + case 118: +#line 358 "util/configparser.y" { OUTYY(("P(server_do_daemonize:%s)\n", (yyvsp[(2) - (2)].str))); if(strcmp((yyvsp[(2) - (2)].str), "yes") != 0 && strcmp((yyvsp[(2) - (2)].str), "no") != 0) @@ -2127,8 +2143,8 @@ yyreduce: } break; - case 118: -#line 366 "util/configparser.y" + case 119: +#line 367 "util/configparser.y" { OUTYY(("P(server_use_syslog:%s)\n", (yyvsp[(2) - (2)].str))); if(strcmp((yyvsp[(2) - (2)].str), "yes") != 0 && strcmp((yyvsp[(2) - (2)].str), "no") != 0) @@ -2143,8 +2159,8 @@ yyreduce: } break; - case 119: -#line 380 "util/configparser.y" + case 120: +#line 381 "util/configparser.y" { OUTYY(("P(server_log_time_ascii:%s)\n", (yyvsp[(2) - (2)].str))); if(strcmp((yyvsp[(2) - (2)].str), "yes") != 0 && strcmp((yyvsp[(2) - (2)].str), "no") != 0) @@ -2154,8 +2170,8 @@ yyreduce: } break; - case 120: -#line 389 "util/configparser.y" + case 121: +#line 390 "util/configparser.y" { OUTYY(("P(server_chroot:%s)\n", (yyvsp[(2) - (2)].str))); free(cfg_parser->cfg->chrootdir); @@ -2163,8 +2179,8 @@ yyreduce: } break; - case 121: -#line 396 "util/configparser.y" + case 122: +#line 397 "util/configparser.y" { OUTYY(("P(server_username:%s)\n", (yyvsp[(2) - (2)].str))); free(cfg_parser->cfg->username); @@ -2172,8 +2188,8 @@ yyreduce: } break; - case 122: -#line 403 "util/configparser.y" + case 123: +#line 404 "util/configparser.y" { OUTYY(("P(server_directory:%s)\n", (yyvsp[(2) - (2)].str))); free(cfg_parser->cfg->directory); @@ -2181,8 +2197,8 @@ yyreduce: } break; - case 123: -#line 410 "util/configparser.y" + case 124: +#line 411 "util/configparser.y" { OUTYY(("P(server_logfile:%s)\n", (yyvsp[(2) - (2)].str))); free(cfg_parser->cfg->logfile); @@ -2191,8 +2207,8 @@ yyreduce: } break; - case 124: -#line 418 "util/configparser.y" + case 125: +#line 419 "util/configparser.y" { OUTYY(("P(server_pidfile:%s)\n", (yyvsp[(2) - (2)].str))); free(cfg_parser->cfg->pidfile); @@ -2200,8 +2216,8 @@ yyreduce: } break; - case 125: -#line 425 "util/configparser.y" + case 126: +#line 426 "util/configparser.y" { OUTYY(("P(server_root_hints:%s)\n", (yyvsp[(2) - (2)].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->root_hints, (yyvsp[(2) - (2)].str))) @@ -2209,8 +2225,8 @@ yyreduce: } break; - case 126: -#line 432 "util/configparser.y" + case 127: +#line 433 "util/configparser.y" { OUTYY(("P(server_dlv_anchor_file:%s)\n", (yyvsp[(2) - (2)].str))); free(cfg_parser->cfg->dlv_anchor_file); @@ -2218,8 +2234,8 @@ yyreduce: } break; - case 127: -#line 439 "util/configparser.y" + case 128: +#line 440 "util/configparser.y" { OUTYY(("P(server_dlv_anchor:%s)\n", (yyvsp[(2) - (2)].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->dlv_anchor_list, (yyvsp[(2) - (2)].str))) @@ -2227,8 +2243,8 @@ yyreduce: } break; - case 128: -#line 446 "util/configparser.y" + case 129: +#line 447 "util/configparser.y" { OUTYY(("P(server_trust_anchor_file:%s)\n", (yyvsp[(2) - (2)].str))); if(!cfg_strlist_insert(&cfg_parser->cfg-> @@ -2237,8 +2253,8 @@ yyreduce: } break; - case 129: -#line 454 "util/configparser.y" + case 130: +#line 455 "util/configparser.y" { OUTYY(("P(server_trusted_keys_file:%s)\n", (yyvsp[(2) - (2)].str))); if(!cfg_strlist_insert(&cfg_parser->cfg-> @@ -2247,8 +2263,8 @@ yyreduce: } break; - case 130: -#line 462 "util/configparser.y" + case 131: +#line 463 "util/configparser.y" { OUTYY(("P(server_trust_anchor:%s)\n", (yyvsp[(2) - (2)].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->trust_anchor_list, (yyvsp[(2) - (2)].str))) @@ -2256,8 +2272,8 @@ yyreduce: } break; - case 131: -#line 469 "util/configparser.y" + case 132: +#line 470 "util/configparser.y" { OUTYY(("P(server_domain_insecure:%s)\n", (yyvsp[(2) - (2)].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->domain_insecure, (yyvsp[(2) - (2)].str))) @@ -2265,8 +2281,8 @@ yyreduce: } break; - case 132: -#line 476 "util/configparser.y" + case 133: +#line 477 "util/configparser.y" { OUTYY(("P(server_hide_identity:%s)\n", (yyvsp[(2) - (2)].str))); if(strcmp((yyvsp[(2) - (2)].str), "yes") != 0 && strcmp((yyvsp[(2) - (2)].str), "no") != 0) @@ -2276,8 +2292,8 @@ yyreduce: } break; - case 133: -#line 485 "util/configparser.y" + case 134: +#line 486 "util/configparser.y" { OUTYY(("P(server_hide_version:%s)\n", (yyvsp[(2) - (2)].str))); if(strcmp((yyvsp[(2) - (2)].str), "yes") != 0 && strcmp((yyvsp[(2) - (2)].str), "no") != 0) @@ -2287,8 +2303,8 @@ yyreduce: } break; - case 134: -#line 494 "util/configparser.y" + case 135: +#line 495 "util/configparser.y" { OUTYY(("P(server_identity:%s)\n", (yyvsp[(2) - (2)].str))); free(cfg_parser->cfg->identity); @@ -2296,8 +2312,8 @@ yyreduce: } break; - case 135: -#line 501 "util/configparser.y" + case 136: +#line 502 "util/configparser.y" { OUTYY(("P(server_version:%s)\n", (yyvsp[(2) - (2)].str))); free(cfg_parser->cfg->version); @@ -2305,8 +2321,8 @@ yyreduce: } break; - case 136: -#line 508 "util/configparser.y" + case 137: +#line 509 "util/configparser.y" { OUTYY(("P(server_msg_buffer_size:%s)\n", (yyvsp[(2) - (2)].str))); if(atoi((yyvsp[(2) - (2)].str)) == 0) @@ -2318,8 +2334,8 @@ yyreduce: } break; - case 137: -#line 519 "util/configparser.y" + case 138: +#line 520 "util/configparser.y" { OUTYY(("P(server_msg_cache_size:%s)\n", (yyvsp[(2) - (2)].str))); if(!cfg_parse_memsize((yyvsp[(2) - (2)].str), &cfg_parser->cfg->msg_cache_size)) @@ -2328,8 +2344,8 @@ yyreduce: } break; - case 138: -#line 527 "util/configparser.y" + case 139: +#line 528 "util/configparser.y" { OUTYY(("P(server_msg_cache_slabs:%s)\n", (yyvsp[(2) - (2)].str))); if(atoi((yyvsp[(2) - (2)].str)) == 0) @@ -2343,8 +2359,8 @@ yyreduce: } break; - case 139: -#line 540 "util/configparser.y" + case 140: +#line 541 "util/configparser.y" { OUTYY(("P(server_num_queries_per_thread:%s)\n", (yyvsp[(2) - (2)].str))); if(atoi((yyvsp[(2) - (2)].str)) == 0) @@ -2354,8 +2370,8 @@ yyreduce: } break; - case 140: -#line 549 "util/configparser.y" + case 141: +#line 550 "util/configparser.y" { OUTYY(("P(server_jostle_timeout:%s)\n", (yyvsp[(2) - (2)].str))); if(atoi((yyvsp[(2) - (2)].str)) == 0 && strcmp((yyvsp[(2) - (2)].str), "0") != 0) @@ -2365,8 +2381,8 @@ yyreduce: } break; - case 141: -#line 558 "util/configparser.y" + case 142: +#line 559 "util/configparser.y" { OUTYY(("P(server_rrset_cache_size:%s)\n", (yyvsp[(2) - (2)].str))); if(!cfg_parse_memsize((yyvsp[(2) - (2)].str), &cfg_parser->cfg->rrset_cache_size)) @@ -2375,8 +2391,8 @@ yyreduce: } break; - case 142: -#line 566 "util/configparser.y" + case 143: +#line 567 "util/configparser.y" { OUTYY(("P(server_rrset_cache_slabs:%s)\n", (yyvsp[(2) - (2)].str))); if(atoi((yyvsp[(2) - (2)].str)) == 0) @@ -2390,8 +2406,8 @@ yyreduce: } break; - case 143: -#line 579 "util/configparser.y" + case 144: +#line 580 "util/configparser.y" { OUTYY(("P(server_infra_host_ttl:%s)\n", (yyvsp[(2) - (2)].str))); if(atoi((yyvsp[(2) - (2)].str)) == 0 && strcmp((yyvsp[(2) - (2)].str), "0") != 0) @@ -2401,8 +2417,8 @@ yyreduce: } break; - case 144: -#line 588 "util/configparser.y" + case 145: +#line 589 "util/configparser.y" { OUTYY(("P(server_infra_lame_ttl:%s)\n", (yyvsp[(2) - (2)].str))); if(atoi((yyvsp[(2) - (2)].str)) == 0 && strcmp((yyvsp[(2) - (2)].str), "0") != 0) @@ -2412,8 +2428,8 @@ yyreduce: } break; - case 145: -#line 597 "util/configparser.y" + case 146: +#line 598 "util/configparser.y" { OUTYY(("P(server_infra_cache_numhosts:%s)\n", (yyvsp[(2) - (2)].str))); if(atoi((yyvsp[(2) - (2)].str)) == 0) @@ -2423,8 +2439,8 @@ yyreduce: } break; - case 146: -#line 606 "util/configparser.y" + case 147: +#line 607 "util/configparser.y" { OUTYY(("P(server_infra_cache_lame_size:%s)\n", (yyvsp[(2) - (2)].str))); if(!cfg_parse_memsize((yyvsp[(2) - (2)].str), &cfg_parser->cfg-> @@ -2434,8 +2450,8 @@ yyreduce: } break; - case 147: -#line 615 "util/configparser.y" + case 148: +#line 616 "util/configparser.y" { OUTYY(("P(server_infra_cache_slabs:%s)\n", (yyvsp[(2) - (2)].str))); if(atoi((yyvsp[(2) - (2)].str)) == 0) @@ -2449,8 +2465,8 @@ yyreduce: } break; - case 148: -#line 628 "util/configparser.y" + case 149: +#line 629 "util/configparser.y" { OUTYY(("P(server_target_fetch_policy:%s)\n", (yyvsp[(2) - (2)].str))); free(cfg_parser->cfg->target_fetch_policy); @@ -2458,8 +2474,8 @@ yyreduce: } break; - case 149: -#line 635 "util/configparser.y" + case 150: +#line 636 "util/configparser.y" { OUTYY(("P(server_harden_short_bufsize:%s)\n", (yyvsp[(2) - (2)].str))); if(strcmp((yyvsp[(2) - (2)].str), "yes") != 0 && strcmp((yyvsp[(2) - (2)].str), "no") != 0) @@ -2470,8 +2486,8 @@ yyreduce: } break; - case 150: -#line 645 "util/configparser.y" + case 151: +#line 646 "util/configparser.y" { OUTYY(("P(server_harden_large_queries:%s)\n", (yyvsp[(2) - (2)].str))); if(strcmp((yyvsp[(2) - (2)].str), "yes") != 0 && strcmp((yyvsp[(2) - (2)].str), "no") != 0) @@ -2482,8 +2498,8 @@ yyreduce: } break; - case 151: -#line 655 "util/configparser.y" + case 152: +#line 656 "util/configparser.y" { OUTYY(("P(server_harden_glue:%s)\n", (yyvsp[(2) - (2)].str))); if(strcmp((yyvsp[(2) - (2)].str), "yes") != 0 && strcmp((yyvsp[(2) - (2)].str), "no") != 0) @@ -2494,8 +2510,8 @@ yyreduce: } break; - case 152: -#line 665 "util/configparser.y" + case 153: +#line 666 "util/configparser.y" { OUTYY(("P(server_harden_dnssec_stripped:%s)\n", (yyvsp[(2) - (2)].str))); if(strcmp((yyvsp[(2) - (2)].str), "yes") != 0 && strcmp((yyvsp[(2) - (2)].str), "no") != 0) @@ -2506,8 +2522,8 @@ yyreduce: } break; - case 153: -#line 675 "util/configparser.y" + case 154: +#line 676 "util/configparser.y" { OUTYY(("P(server_harden_referral_path:%s)\n", (yyvsp[(2) - (2)].str))); if(strcmp((yyvsp[(2) - (2)].str), "yes") != 0 && strcmp((yyvsp[(2) - (2)].str), "no") != 0) @@ -2518,8 +2534,8 @@ yyreduce: } break; - case 154: -#line 685 "util/configparser.y" + case 155: +#line 686 "util/configparser.y" { OUTYY(("P(server_use_caps_for_id:%s)\n", (yyvsp[(2) - (2)].str))); if(strcmp((yyvsp[(2) - (2)].str), "yes") != 0 && strcmp((yyvsp[(2) - (2)].str), "no") != 0) @@ -2530,8 +2546,8 @@ yyreduce: } break; - case 155: -#line 695 "util/configparser.y" + case 156: +#line 696 "util/configparser.y" { OUTYY(("P(server_private_address:%s)\n", (yyvsp[(2) - (2)].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->private_address, (yyvsp[(2) - (2)].str))) @@ -2539,8 +2555,8 @@ yyreduce: } break; - case 156: -#line 702 "util/configparser.y" + case 157: +#line 703 "util/configparser.y" { OUTYY(("P(server_private_domain:%s)\n", (yyvsp[(2) - (2)].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->private_domain, (yyvsp[(2) - (2)].str))) @@ -2548,8 +2564,8 @@ yyreduce: } break; - case 157: -#line 709 "util/configparser.y" + case 158: +#line 710 "util/configparser.y" { OUTYY(("P(server_unwanted_reply_threshold:%s)\n", (yyvsp[(2) - (2)].str))); if(atoi((yyvsp[(2) - (2)].str)) == 0 && strcmp((yyvsp[(2) - (2)].str), "0") != 0) @@ -2559,8 +2575,8 @@ yyreduce: } break; - case 158: -#line 718 "util/configparser.y" + case 159: +#line 719 "util/configparser.y" { OUTYY(("P(server_do_not_query_address:%s)\n", (yyvsp[(2) - (2)].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->donotqueryaddrs, (yyvsp[(2) - (2)].str))) @@ -2568,8 +2584,8 @@ yyreduce: } break; - case 159: -#line 725 "util/configparser.y" + case 160: +#line 726 "util/configparser.y" { OUTYY(("P(server_do_not_query_localhost:%s)\n", (yyvsp[(2) - (2)].str))); if(strcmp((yyvsp[(2) - (2)].str), "yes") != 0 && strcmp((yyvsp[(2) - (2)].str), "no") != 0) @@ -2580,8 +2596,8 @@ yyreduce: } break; - case 160: -#line 735 "util/configparser.y" + case 161: +#line 736 "util/configparser.y" { OUTYY(("P(server_access_control:%s %s)\n", (yyvsp[(2) - (3)].str), (yyvsp[(3) - (3)].str))); if(strcmp((yyvsp[(3) - (3)].str), "deny")!=0 && strcmp((yyvsp[(3) - (3)].str), "refuse")!=0 && @@ -2596,8 +2612,8 @@ yyreduce: } break; - case 161: -#line 749 "util/configparser.y" + case 162: +#line 750 "util/configparser.y" { OUTYY(("P(server_module_conf:%s)\n", (yyvsp[(2) - (2)].str))); free(cfg_parser->cfg->module_conf); @@ -2605,8 +2621,8 @@ yyreduce: } break; - case 162: -#line 756 "util/configparser.y" + case 163: +#line 757 "util/configparser.y" { OUTYY(("P(server_val_override_date:%s)\n", (yyvsp[(2) - (2)].str))); if(strlen((yyvsp[(2) - (2)].str)) == 0 || strcmp((yyvsp[(2) - (2)].str), "0") == 0) { @@ -2625,8 +2641,8 @@ yyreduce: } break; - case 163: -#line 774 "util/configparser.y" + case 164: +#line 775 "util/configparser.y" { OUTYY(("P(server_cache_max_ttl:%s)\n", (yyvsp[(2) - (2)].str))); if(atoi((yyvsp[(2) - (2)].str)) == 0 && strcmp((yyvsp[(2) - (2)].str), "0") != 0) @@ -2636,8 +2652,8 @@ yyreduce: } break; - case 164: -#line 783 "util/configparser.y" + case 165: +#line 784 "util/configparser.y" { OUTYY(("P(server_bogus_ttl:%s)\n", (yyvsp[(2) - (2)].str))); if(atoi((yyvsp[(2) - (2)].str)) == 0 && strcmp((yyvsp[(2) - (2)].str), "0") != 0) @@ -2647,8 +2663,8 @@ yyreduce: } break; - case 165: -#line 792 "util/configparser.y" + case 166: +#line 793 "util/configparser.y" { OUTYY(("P(server_val_clean_additional:%s)\n", (yyvsp[(2) - (2)].str))); if(strcmp((yyvsp[(2) - (2)].str), "yes") != 0 && strcmp((yyvsp[(2) - (2)].str), "no") != 0) @@ -2659,8 +2675,8 @@ yyreduce: } break; - case 166: -#line 802 "util/configparser.y" + case 167: +#line 803 "util/configparser.y" { OUTYY(("P(server_val_permissive_mode:%s)\n", (yyvsp[(2) - (2)].str))); if(strcmp((yyvsp[(2) - (2)].str), "yes") != 0 && strcmp((yyvsp[(2) - (2)].str), "no") != 0) @@ -2671,8 +2687,8 @@ yyreduce: } break; - case 167: -#line 812 "util/configparser.y" + case 168: +#line 813 "util/configparser.y" { OUTYY(("P(server_val_nsec3_keysize_iterations:%s)\n", (yyvsp[(2) - (2)].str))); free(cfg_parser->cfg->val_nsec3_key_iterations); @@ -2680,8 +2696,8 @@ yyreduce: } break; - case 168: -#line 819 "util/configparser.y" + case 169: +#line 820 "util/configparser.y" { OUTYY(("P(server_key_cache_size:%s)\n", (yyvsp[(2) - (2)].str))); if(!cfg_parse_memsize((yyvsp[(2) - (2)].str), &cfg_parser->cfg->key_cache_size)) @@ -2690,8 +2706,8 @@ yyreduce: } break; - case 169: -#line 827 "util/configparser.y" + case 170: +#line 828 "util/configparser.y" { OUTYY(("P(server_key_cache_slabs:%s)\n", (yyvsp[(2) - (2)].str))); if(atoi((yyvsp[(2) - (2)].str)) == 0) @@ -2705,8 +2721,8 @@ yyreduce: } break; - case 170: -#line 840 "util/configparser.y" + case 171: +#line 841 "util/configparser.y" { OUTYY(("P(server_neg_cache_size:%s)\n", (yyvsp[(2) - (2)].str))); if(!cfg_parse_memsize((yyvsp[(2) - (2)].str), &cfg_parser->cfg->neg_cache_size)) @@ -2715,8 +2731,8 @@ yyreduce: } break; - case 171: -#line 848 "util/configparser.y" + case 172: +#line 849 "util/configparser.y" { OUTYY(("P(server_local_zone:%s %s)\n", (yyvsp[(2) - (3)].str), (yyvsp[(3) - (3)].str))); if(strcmp((yyvsp[(3) - (3)].str), "static")!=0 && strcmp((yyvsp[(3) - (3)].str), "deny")!=0 && @@ -2737,8 +2753,8 @@ yyreduce: } break; - case 172: -#line 868 "util/configparser.y" + case 173: +#line 869 "util/configparser.y" { OUTYY(("P(server_local_data:%s)\n", (yyvsp[(2) - (2)].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->local_data, (yyvsp[(2) - (2)].str))) @@ -2746,8 +2762,8 @@ yyreduce: } break; - case 173: -#line 875 "util/configparser.y" + case 174: +#line 876 "util/configparser.y" { char* ptr; OUTYY(("P(server_local_data_ptr:%s)\n", (yyvsp[(2) - (2)].str))); @@ -2763,8 +2779,8 @@ yyreduce: } break; - case 174: -#line 890 "util/configparser.y" + case 175: +#line 891 "util/configparser.y" { OUTYY(("P(name:%s)\n", (yyvsp[(2) - (2)].str))); free(cfg_parser->cfg->stubs->name); @@ -2772,8 +2788,8 @@ yyreduce: } break; - case 175: -#line 897 "util/configparser.y" + case 176: +#line 898 "util/configparser.y" { OUTYY(("P(stub-host:%s)\n", (yyvsp[(2) - (2)].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->stubs->hosts, (yyvsp[(2) - (2)].str))) @@ -2781,8 +2797,8 @@ yyreduce: } break; - case 176: -#line 904 "util/configparser.y" + case 177: +#line 905 "util/configparser.y" { OUTYY(("P(stub-addr:%s)\n", (yyvsp[(2) - (2)].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->stubs->addrs, (yyvsp[(2) - (2)].str))) @@ -2790,8 +2806,8 @@ yyreduce: } break; - case 177: -#line 911 "util/configparser.y" + case 178: +#line 912 "util/configparser.y" { OUTYY(("P(stub-prime:%s)\n", (yyvsp[(2) - (2)].str))); if(strcmp((yyvsp[(2) - (2)].str), "yes") != 0 && strcmp((yyvsp[(2) - (2)].str), "no") != 0) @@ -2802,8 +2818,8 @@ yyreduce: } break; - case 178: -#line 921 "util/configparser.y" + case 179: +#line 922 "util/configparser.y" { OUTYY(("P(name:%s)\n", (yyvsp[(2) - (2)].str))); free(cfg_parser->cfg->forwards->name); @@ -2811,8 +2827,8 @@ yyreduce: } break; - case 179: -#line 928 "util/configparser.y" + case 180: +#line 929 "util/configparser.y" { OUTYY(("P(forward-host:%s)\n", (yyvsp[(2) - (2)].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->forwards->hosts, (yyvsp[(2) - (2)].str))) @@ -2820,8 +2836,8 @@ yyreduce: } break; - case 180: -#line 935 "util/configparser.y" + case 181: +#line 936 "util/configparser.y" { OUTYY(("P(forward-addr:%s)\n", (yyvsp[(2) - (2)].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->forwards->addrs, (yyvsp[(2) - (2)].str))) @@ -2829,15 +2845,15 @@ yyreduce: } break; - case 181: -#line 942 "util/configparser.y" + case 182: +#line 943 "util/configparser.y" { OUTYY(("\nP(remote-control:)\n")); } break; - case 191: -#line 953 "util/configparser.y" + case 192: +#line 954 "util/configparser.y" { OUTYY(("P(control_enable:%s)\n", (yyvsp[(2) - (2)].str))); if(strcmp((yyvsp[(2) - (2)].str), "yes") != 0 && strcmp((yyvsp[(2) - (2)].str), "no") != 0) @@ -2848,8 +2864,8 @@ yyreduce: } break; - case 192: -#line 963 "util/configparser.y" + case 193: +#line 964 "util/configparser.y" { OUTYY(("P(control_port:%s)\n", (yyvsp[(2) - (2)].str))); if(atoi((yyvsp[(2) - (2)].str)) == 0) @@ -2859,8 +2875,8 @@ yyreduce: } break; - case 193: -#line 972 "util/configparser.y" + case 194: +#line 973 "util/configparser.y" { OUTYY(("P(control_interface:%s)\n", (yyvsp[(2) - (2)].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->control_ifs, (yyvsp[(2) - (2)].str))) @@ -2868,8 +2884,8 @@ yyreduce: } break; - case 194: -#line 979 "util/configparser.y" + case 195: +#line 980 "util/configparser.y" { OUTYY(("P(rc_server_key_file:%s)\n", (yyvsp[(2) - (2)].str))); free(cfg_parser->cfg->server_key_file); @@ -2877,8 +2893,8 @@ yyreduce: } break; - case 195: -#line 986 "util/configparser.y" + case 196: +#line 987 "util/configparser.y" { OUTYY(("P(rc_server_cert_file:%s)\n", (yyvsp[(2) - (2)].str))); free(cfg_parser->cfg->server_cert_file); @@ -2886,8 +2902,8 @@ yyreduce: } break; - case 196: -#line 993 "util/configparser.y" + case 197: +#line 994 "util/configparser.y" { OUTYY(("P(rc_control_key_file:%s)\n", (yyvsp[(2) - (2)].str))); free(cfg_parser->cfg->control_key_file); @@ -2895,8 +2911,8 @@ yyreduce: } break; - case 197: -#line 1000 "util/configparser.y" + case 198: +#line 1001 "util/configparser.y" { OUTYY(("P(rc_control_cert_file:%s)\n", (yyvsp[(2) - (2)].str))); free(cfg_parser->cfg->control_cert_file); @@ -2904,9 +2920,25 @@ yyreduce: } break; + case 199: +#line 1008 "util/configparser.y" + { + OUTYY(("\nP(python:)\n")); + } + break; + + case 203: +#line 1017 "util/configparser.y" + { + OUTYY(("P(python-script:%s)\n", (yyvsp[(2) - (2)].str))); + free(cfg_parser->cfg->python_script); + cfg_parser->cfg->python_script = (yyvsp[(2) - (2)].str); + } + break; + /* Line 1267 of yacc.c. */ -#line 2910 "util/configparser.c" +#line 2942 "util/configparser.c" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); @@ -3120,7 +3152,7 @@ yyreturn: } -#line 1006 "util/configparser.y" +#line 1022 "util/configparser.y" /* parse helper routines could be here */ diff --git a/util/configparser.h b/util/configparser.h index 47f8a887f..1112a9f34 100644 --- a/util/configparser.h +++ b/util/configparser.h @@ -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 diff --git a/util/configparser.y b/util/configparser.y index 230c3d838..85c9e78a5 100644 --- a/util/configparser.y +++ b/util/configparser.y @@ -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 */ diff --git a/util/data/msgencode.c b/util/data/msgencode.c index b46818a93..b98719843 100644 --- a/util/data/msgencode.c +++ b/util/data/msgencode.c @@ -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 { diff --git a/util/data/msgreply.c b/util/data/msgreply.c index 888571e3e..1d02c38db 100644 --- a/util/data/msgreply.c +++ b/util/data/msgreply.c @@ -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]); diff --git a/util/data/msgreply.h b/util/data/msgreply.h index 3d17cbe40..87570e622 100644 --- a/util/data/msgreply.h +++ b/util/data/msgreply.h @@ -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; diff --git a/util/fptr_wlist.c b/util/fptr_wlist.c index 6bae9fb3f..189809b22 100644 --- a/util/fptr_wlist.c +++ b/util/fptr_wlist.c @@ -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; }