mirror of https://github.com/getdnsapi/getdns.git
Merge branch 'devel/dnssec_maintenance' into features/valchain_without_lookups
This commit is contained in:
commit
58ff68a7a3
|
@ -2,6 +2,9 @@
|
||||||
path = src/jsmn
|
path = src/jsmn
|
||||||
url = https://github.com/getdnsapi/jsmn.git
|
url = https://github.com/getdnsapi/jsmn.git
|
||||||
branch = getdns
|
branch = getdns
|
||||||
|
[submodule "src/yxml"]
|
||||||
|
path = src/yxml
|
||||||
|
url = git://g.blicky.net/yxml.git
|
||||||
[submodule "stubby"]
|
[submodule "stubby"]
|
||||||
path = stubby
|
path = stubby
|
||||||
url = https://github.com/getdnsapi/stubby.git
|
url = https://github.com/getdnsapi/stubby.git
|
||||||
|
|
|
@ -8,9 +8,11 @@ addons:
|
||||||
packages:
|
packages:
|
||||||
- libunbound-dev
|
- libunbound-dev
|
||||||
- libidn11-dev
|
- libidn11-dev
|
||||||
|
- libyaml-dev
|
||||||
- check
|
- check
|
||||||
- libevent-dev
|
- libevent-dev
|
||||||
- libev-dev
|
- libev-dev
|
||||||
|
- libuv-dev
|
||||||
- valgrind
|
- valgrind
|
||||||
- clang
|
- clang
|
||||||
- wget
|
- wget
|
||||||
|
|
30
ChangeLog
30
ChangeLog
|
@ -1,3 +1,33 @@
|
||||||
|
* 2017-1?-??: Version 1.2.1
|
||||||
|
* Bugfix #348: Fix a linking issue in stubby when libbsd is present
|
||||||
|
Thanks Remi Gacogne
|
||||||
|
* Fix Makefile dependencies for parallel install.
|
||||||
|
Thanks ilovezfs
|
||||||
|
|
||||||
|
* 2017-09-29: Version 1.2.0
|
||||||
|
* Bugfix of rc1: authentication of first query with TLS
|
||||||
|
Thanks Travis Burtrum
|
||||||
|
* A function to set the location for library specific data,
|
||||||
|
like trust-anchors: getdns_context_set_appdata().
|
||||||
|
* Zero configuration DNSSEC - build upon the scheme
|
||||||
|
described in RFC7958. The URL from which to fetch
|
||||||
|
the trust anchor, the verification CA and email
|
||||||
|
can be set with the new getdns_context_set_trust_anchor_url(),
|
||||||
|
getdns_context_set_trust_anchor_verify_CA() and
|
||||||
|
getdns_context_set_trust_anchor_verify_email() functions.
|
||||||
|
The default values are to fetch from IANA and to validate
|
||||||
|
with the ICANN CA.
|
||||||
|
* Update of Stubby with yaml configuration file and
|
||||||
|
logging from a certain severity support.
|
||||||
|
* Fix tpkg exit status on test failure. Thanks Jim Hague.
|
||||||
|
* Refined logging levels for upstream statistics
|
||||||
|
* Reuse (best behaving) backed-off TLS upstreams when non are usable.
|
||||||
|
* Let TLS upstreams back-off a incremental amount of time.
|
||||||
|
Back-off time starts with 1 second and is doubled each failure, but
|
||||||
|
will not exceed the time given by getdns_context_set_tls_backoff_time()
|
||||||
|
* Make TLS upstream management more resilient to temporary outages
|
||||||
|
(like laptop sleeps)
|
||||||
|
|
||||||
* 2017-09-04: Version 1.1.3
|
* 2017-09-04: Version 1.1.3
|
||||||
* Small bugfixes that came out of static analysis
|
* Small bugfixes that came out of static analysis
|
||||||
* No annotations with the output of getdns_query anymore,
|
* No annotations with the output of getdns_query anymore,
|
||||||
|
|
37
Makefile.in
37
Makefile.in
|
@ -71,21 +71,26 @@ install: getdns.pc getdns_ext_event.pc install-lib @INSTALL_GETDNS_QUERY@
|
||||||
$(INSTALL) -m 644 $(srcdir)/spec/index.html $(DESTDIR)$(docdir)/spec
|
$(INSTALL) -m 644 $(srcdir)/spec/index.html $(DESTDIR)$(docdir)/spec
|
||||||
cd doc && $(MAKE) install
|
cd doc && $(MAKE) install
|
||||||
@echo "***"
|
@echo "***"
|
||||||
@echo "*** !!! IMPORTANT !!!! libgetdns needs a DNSSEC trust anchor!"
|
@echo "*** !!! IMPORTANT !!!!"
|
||||||
|
@echo "***"
|
||||||
|
@echo "*** From release 1.2.0, getdns comes with built-in DNSSEC"
|
||||||
|
@echo "*** trust anchor management. External trust anchor management,"
|
||||||
|
@echo "*** for example with unbound-anchor, is no longer necessary"
|
||||||
|
@echo "*** and no longer recommended."
|
||||||
|
@echo "***"
|
||||||
|
@echo "*** Previously installed trust anchors, in the default location -"
|
||||||
@echo "***"
|
@echo "***"
|
||||||
@echo "*** For the library to be able to perform DNSSEC, the root"
|
|
||||||
@echo "*** trust anchor needs to be present in presentation format"
|
|
||||||
@echo "*** in the file: "
|
|
||||||
@echo "*** @TRUST_ANCHOR_FILE@"
|
@echo "*** @TRUST_ANCHOR_FILE@"
|
||||||
@echo "***"
|
@echo "***"
|
||||||
@echo "*** We recomend using unbound-anchor to retrieve and install"
|
@echo "*** - will be preferred and used for DNSSEC validation, however"
|
||||||
@echo "*** the root trust anchor like this: "
|
@echo "*** getdns will fallback to trust-anchors obtained via built-in"
|
||||||
@echo "*** mkdir -p `dirname @TRUST_ANCHOR_FILE@`"
|
@echo "*** trust anchor management when the anchors from the default"
|
||||||
@echo "*** unbound-anchor -a \"@TRUST_ANCHOR_FILE@\""
|
@echo "*** location fail to validate the root DNSKEY rrset."
|
||||||
@echo "***"
|
@echo "***"
|
||||||
@echo "*** We strongly recommend package maintainers to provide the"
|
@echo "*** To prevent expired DNSSEC trust anchors to be used for"
|
||||||
@echo "*** root trust anchor by installing it with unbound-anchor"
|
@echo "*** validation, we strongly recommend removing the trust anchors"
|
||||||
@echo "*** at package installation time from the post-install script."
|
@echo "*** on the default location when there is no active external"
|
||||||
|
@echo "*** trust anchor management keeping it up-to-date."
|
||||||
@echo "***"
|
@echo "***"
|
||||||
|
|
||||||
uninstall: @UNINSTALL_GETDNS_QUERY@
|
uninstall: @UNINSTALL_GETDNS_QUERY@
|
||||||
|
@ -198,11 +203,13 @@ $(distdir):
|
||||||
mkdir -p $(distdir)/src/gldns
|
mkdir -p $(distdir)/src/gldns
|
||||||
mkdir -p $(distdir)/src/tools
|
mkdir -p $(distdir)/src/tools
|
||||||
mkdir -p $(distdir)/src/jsmn
|
mkdir -p $(distdir)/src/jsmn
|
||||||
|
mkdir -p $(distdir)/src/yxml
|
||||||
mkdir -p $(distdir)/doc
|
mkdir -p $(distdir)/doc
|
||||||
mkdir -p $(distdir)/spec
|
mkdir -p $(distdir)/spec
|
||||||
mkdir -p $(distdir)/spec/example
|
mkdir -p $(distdir)/spec/example
|
||||||
mkdir -p $(distdir)/stubby
|
mkdir -p $(distdir)/stubby
|
||||||
mkdir -p $(distdir)/stubby/src
|
mkdir -p $(distdir)/stubby/src
|
||||||
|
mkdir -p $(distdir)/stubby/src/yaml
|
||||||
cp $(srcdir)/configure.ac $(distdir)
|
cp $(srcdir)/configure.ac $(distdir)
|
||||||
cp $(srcdir)/configure $(distdir)
|
cp $(srcdir)/configure $(distdir)
|
||||||
cp $(srcdir)/AUTHORS $(distdir)
|
cp $(srcdir)/AUTHORS $(distdir)
|
||||||
|
@ -245,14 +252,18 @@ $(distdir):
|
||||||
cp $(srcdir)/spec/example/*.[ch] $(distdir)/spec/example
|
cp $(srcdir)/spec/example/*.[ch] $(distdir)/spec/example
|
||||||
cp $(srcdir)/src/tools/Makefile.in $(distdir)/src/tools
|
cp $(srcdir)/src/tools/Makefile.in $(distdir)/src/tools
|
||||||
cp $(srcdir)/src/tools/*.[ch] $(distdir)/src/tools
|
cp $(srcdir)/src/tools/*.[ch] $(distdir)/src/tools
|
||||||
cp $(srcdir)/stubby/stubby.conf.example $(distdir)/stubby
|
cp $(srcdir)/stubby/stubby.yml.example $(distdir)/stubby
|
||||||
cp $(srcdir)/stubby/stubby-setdns-macos.sh $(distdir)/stubby
|
cp $(srcdir)/stubby/stubby-setdns-macos.sh $(distdir)/stubby
|
||||||
cp $(srcdir)/stubby/src/stubby.c $(distdir)/stubby/src
|
cp $(srcdir)/stubby/src/*.[ch] $(distdir)/stubby/src
|
||||||
|
cp $(srcdir)/stubby/src/yaml/*.[ch] $(distdir)/stubby/src/yaml
|
||||||
cp $(srcdir)/stubby/COPYING $(distdir)/stubby
|
cp $(srcdir)/stubby/COPYING $(distdir)/stubby
|
||||||
cp $(srcdir)/stubby/README.md $(distdir)/stubby
|
cp $(srcdir)/stubby/README.md $(distdir)/stubby
|
||||||
cp $(srcdir)/src/jsmn/*.[ch] $(distdir)/src/jsmn
|
cp $(srcdir)/src/jsmn/*.[ch] $(distdir)/src/jsmn
|
||||||
cp $(srcdir)/src/jsmn/LICENSE $(distdir)/src/jsmn
|
cp $(srcdir)/src/jsmn/LICENSE $(distdir)/src/jsmn
|
||||||
cp $(srcdir)/src/jsmn/README.md $(distdir)/src/jsmn
|
cp $(srcdir)/src/jsmn/README.md $(distdir)/src/jsmn
|
||||||
|
cp $(srcdir)/src/yxml/*.[ch] $(distdir)/src/yxml
|
||||||
|
cp $(srcdir)/src/yxml/COPYING $(distdir)/src/yxml
|
||||||
|
cp $(srcdir)/src/yxml/yxml.pod $(distdir)/src/yxml
|
||||||
rm -f $(distdir)/Makefile $(distdir)/src/Makefile $(distdir)/src/getdns/getdns.h $(distdir)/spec/example/Makefile $(distdir)/src/test/Makefile $(distdir)/doc/Makefile $(distdir)/src/config.h
|
rm -f $(distdir)/Makefile $(distdir)/src/Makefile $(distdir)/src/getdns/getdns.h $(distdir)/spec/example/Makefile $(distdir)/src/test/Makefile $(distdir)/doc/Makefile $(distdir)/src/config.h
|
||||||
|
|
||||||
distcheck: $(distdir).tar.gz
|
distcheck: $(distdir).tar.gz
|
||||||
|
|
25
README.md
25
README.md
|
@ -87,7 +87,7 @@ If you are building from git, you need to do the following before building:
|
||||||
# autoreconf -fi
|
# autoreconf -fi
|
||||||
|
|
||||||
|
|
||||||
As well as building the getdns library 2 other tools are installed by default by the above process:
|
As well as building the getdns library two other tools may be installed:
|
||||||
|
|
||||||
* getdns_query: a command line test script wrapper for getdns
|
* getdns_query: a command line test script wrapper for getdns
|
||||||
* stubby: an experimental DNS Privacy enabled client
|
* stubby: an experimental DNS Privacy enabled client
|
||||||
|
@ -112,7 +112,7 @@ The implementation works with a variety of event loops, each built as a separate
|
||||||
## Stubby
|
## Stubby
|
||||||
|
|
||||||
* Stubby is an experimental implementation of a DNS Privacy enabled stub resolver than encrypts DNS queries using TLS. It is currently suitable for advanced/technical users - all feedback is welcome!
|
* Stubby is an experimental implementation of a DNS Privacy enabled stub resolver than encrypts DNS queries using TLS. It is currently suitable for advanced/technical users - all feedback is welcome!
|
||||||
* Details on how to use Stubby can be found in the [Stubby Reference Guide](https://getdnsapi.net/blog/dns-privacy-daemon-stubby).
|
* Details on how to use Stubby can be found in the [Stubby Reference Guide](https://dnsprivacy.org/wiki/x/JYAT).
|
||||||
* Also see [dnsprivacy.org](https://dnsprivacy.org) for more information on DNS Privacy.
|
* Also see [dnsprivacy.org](https://dnsprivacy.org) for more information on DNS Privacy.
|
||||||
|
|
||||||
## Regression Tests
|
## Regression Tests
|
||||||
|
@ -121,8 +121,6 @@ A suite of regression tests are included with the library, if you make changes o
|
||||||
want to sanity check things on your system take a look at src/test. You will need
|
want to sanity check things on your system take a look at src/test. You will need
|
||||||
to install [libcheck](https://libcheck.github.io/check/). The check library is also available from many of the package repositories for the more popular operating systems.
|
to install [libcheck](https://libcheck.github.io/check/). The check library is also available from many of the package repositories for the more popular operating systems.
|
||||||
|
|
||||||
The regression tests do not work with --enable-stub-only.
|
|
||||||
|
|
||||||
## DNSSEC dependencies
|
## DNSSEC dependencies
|
||||||
|
|
||||||
For the library to be DNSSEC capable, it needs to know the root trust anchor.
|
For the library to be DNSSEC capable, it needs to know the root trust anchor.
|
||||||
|
@ -131,13 +129,16 @@ The library will try to load the root trust anchor from
|
||||||
or more `DS` or `DNSKEY` resource records in presentation (i.e. zone file)
|
or more `DS` or `DNSKEY` resource records in presentation (i.e. zone file)
|
||||||
format. Note that this is different than the format of BIND.keys.
|
format. Note that this is different than the format of BIND.keys.
|
||||||
|
|
||||||
The best way to setup or update the root trust anchor is by using
|
##$ Zero configuration DNSSEC
|
||||||
[`unbound-anchor`](https://www.unbound.net/documentation/unbound-anchor.html).
|
|
||||||
To setup the library with the root trust anchor at the default location,
|
|
||||||
execute the following steps as root:
|
|
||||||
|
|
||||||
# mkdir -p /etc/unbound
|
When the root trust anchor is not installed in the default location and a DNSSEC query is done, getdns will try to use the trust anchors published here: http://data.iana.org/root-anchors/root-anchors.xml .
|
||||||
# unbound-anchor -a /etc/unbound/getdns-root.key
|
It will validate these anchors with the ICANN Certificate Authority certificate following the procedure described in [RFC7958].
|
||||||
|
The `root-anchors.xml` and `root-anchors.p7s` S/MIME signature will be cached in the `$HOME/.getdns` directory.
|
||||||
|
|
||||||
|
When using trust-anchors from the `root-anchors.xml` file, getdns will track the keys in the root DNSKEY rrset and store a copy in $HOME/.getdns/root.key.
|
||||||
|
Only when the KSK DNSKEY's change, a new version of `root-anchors.xml` is tried to be retrieved from [data.iana.org](https://data.iana.org/root-anchors/).
|
||||||
|
|
||||||
|
A installed trust-anchor from the default location (`/etc/unbound/getdns-root.key`) that fails to validate the root DNSKEY RRset, will also trigger the "Zero configuration DNSSEC" procedure described above.
|
||||||
|
|
||||||
Support
|
Support
|
||||||
=======
|
=======
|
||||||
|
@ -206,7 +207,7 @@ The primary platforms targeted are Linux and FreeBSD, other platform are support
|
||||||
|
|
||||||
* RHEL/CentOS 6.4
|
* RHEL/CentOS 6.4
|
||||||
* OSX 10.8
|
* OSX 10.8
|
||||||
* Ubuntu 14.04
|
* Ubuntu 16.04
|
||||||
* Microsoft Windows 8.1
|
* Microsoft Windows 8.1
|
||||||
|
|
||||||
We intend to add Android and other platforms to future releases as we have time to port it.
|
We intend to add Android and other platforms to future releases as we have time to port it.
|
||||||
|
@ -272,7 +273,7 @@ To install the [event loop integration libraries](https://getdnsapi.net/doxygen/
|
||||||
|
|
||||||
Note that in order to compile the examples, the `--with-libevent` switch is required.
|
Note that in order to compile the examples, the `--with-libevent` switch is required.
|
||||||
|
|
||||||
As of the 0.2.0 release, when installing via Homebrew, the trust anchor is expected to be located at `$(brew --prefix)/etc/getdns-root.key`. Additionally, the OpenSSL library installed by Homebrew is linked against. Note that the Homebrew OpenSSL installation clones the Keychain certificates to the default OpenSSL location so TLS certificate authentication should work out of the box.
|
Additionally, the OpenSSL library installed by Homebrew is linked against. Note that the Homebrew OpenSSL installation clones the Keychain certificates to the default OpenSSL location so TLS certificate authentication should work out of the box.
|
||||||
|
|
||||||
### Microsoft Windows 8.1
|
### Microsoft Windows 8.1
|
||||||
|
|
||||||
|
|
349
configure.ac
349
configure.ac
|
@ -36,12 +36,12 @@ sinclude(./m4/acx_getaddrinfo.m4)
|
||||||
sinclude(./m4/ax_check_compile_flag.m4)
|
sinclude(./m4/ax_check_compile_flag.m4)
|
||||||
sinclude(./m4/pkg.m4)
|
sinclude(./m4/pkg.m4)
|
||||||
|
|
||||||
AC_INIT([getdns], [1.1.3], [users@getdnsapi.net], [], [https://getdnsapi.net])
|
AC_INIT([getdns], [1.2.1], [users@getdnsapi.net], [], [https://getdnsapi.net])
|
||||||
|
|
||||||
# Dont forget to put a dash in front of the release candidate!!!
|
# Dont forget to put a dash in front of the release candidate!!!
|
||||||
# That is how it is done with semantic versioning!
|
# That is how it is done with semantic versioning!
|
||||||
#
|
#
|
||||||
AC_SUBST(RELEASE_CANDIDATE, [])
|
AC_SUBST(RELEASE_CANDIDATE, [rc1])
|
||||||
|
|
||||||
# Set current date from system if not set
|
# Set current date from system if not set
|
||||||
AC_ARG_WITH([current-date],
|
AC_ARG_WITH([current-date],
|
||||||
|
@ -51,7 +51,7 @@ AC_ARG_WITH([current-date],
|
||||||
[CURRENT_DATE="`date -u +%Y-%m-%dT%H:%M:%SZ`"])
|
[CURRENT_DATE="`date -u +%Y-%m-%dT%H:%M:%SZ`"])
|
||||||
|
|
||||||
AC_SUBST(GETDNS_VERSION, ["AC_PACKAGE_VERSION$RELEASE_CANDIDATE"])
|
AC_SUBST(GETDNS_VERSION, ["AC_PACKAGE_VERSION$RELEASE_CANDIDATE"])
|
||||||
AC_SUBST(GETDNS_NUMERIC_VERSION, [0x01010300])
|
AC_SUBST(GETDNS_NUMERIC_VERSION, [0x010200C1])
|
||||||
AC_SUBST(API_VERSION, ["December 2015"])
|
AC_SUBST(API_VERSION, ["December 2015"])
|
||||||
AC_SUBST(API_NUMERIC_VERSION, [0x07df0c00])
|
AC_SUBST(API_NUMERIC_VERSION, [0x07df0c00])
|
||||||
GETDNS_COMPILATION_COMMENT="AC_PACKAGE_NAME $GETDNS_VERSION configured on $CURRENT_DATE for the $API_VERSION version of the API"
|
GETDNS_COMPILATION_COMMENT="AC_PACKAGE_NAME $GETDNS_VERSION configured on $CURRENT_DATE for the $API_VERSION version of the API"
|
||||||
|
@ -84,10 +84,12 @@ GETDNS_COMPILATION_COMMENT="AC_PACKAGE_NAME $GETDNS_VERSION configured on $CURRE
|
||||||
# getdns-1.0.0 had libversion 5:1:4
|
# getdns-1.0.0 had libversion 5:1:4
|
||||||
# getdns-1.1.0 had libversion 6:0:0
|
# getdns-1.1.0 had libversion 6:0:0
|
||||||
# getdns-1.1.1 had libversion 6:1:0
|
# getdns-1.1.1 had libversion 6:1:0
|
||||||
# getdns-1.1.2 has libversion 7:0:1
|
# getdns-1.1.2 had libversion 7:0:1
|
||||||
# getdns-1.1.3 will have libversion 7:1:1
|
# getdns-1.1.3 had libversion 7:1:1
|
||||||
|
# getdns-1.2.0 had libversion 8:0:2
|
||||||
|
# getdns-1.2.1 will have libversion 8:1:2
|
||||||
#
|
#
|
||||||
GETDNS_LIBVERSION=7:1:1
|
GETDNS_LIBVERSION=8:1:2
|
||||||
|
|
||||||
AC_SUBST(GETDNS_COMPILATION_COMMENT)
|
AC_SUBST(GETDNS_COMPILATION_COMMENT)
|
||||||
AC_SUBST(GETDNS_LIBVERSION)
|
AC_SUBST(GETDNS_LIBVERSION)
|
||||||
|
@ -100,7 +102,18 @@ AC_PROG_CC
|
||||||
AC_PROG_CPP
|
AC_PROG_CPP
|
||||||
|
|
||||||
# Checks for programs.
|
# Checks for programs.
|
||||||
|
HOSTOS="unix"
|
||||||
AC_CANONICAL_HOST
|
AC_CANONICAL_HOST
|
||||||
|
case "${host_os}" in
|
||||||
|
cygwin*|mingw*)
|
||||||
|
HOSTOS=windows
|
||||||
|
;;
|
||||||
|
darwin*)
|
||||||
|
HOSTOS=macos
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
AC_SUBST(HOSTOS)
|
||||||
|
|
||||||
|
|
||||||
CFLAGS="$CFLAGS"
|
CFLAGS="$CFLAGS"
|
||||||
WPEDANTICFLAG=""
|
WPEDANTICFLAG=""
|
||||||
|
@ -162,7 +175,8 @@ AC_ARG_ENABLE(debug-stub, AC_HELP_STRING([--enable-debug-stub], [Enable stub deb
|
||||||
AC_ARG_ENABLE(debug-daemon, AC_HELP_STRING([--enable-debug-daemon], [Enable daemon debugging messages]))
|
AC_ARG_ENABLE(debug-daemon, AC_HELP_STRING([--enable-debug-daemon], [Enable daemon debugging messages]))
|
||||||
AC_ARG_ENABLE(debug-sec, AC_HELP_STRING([--enable-debug-sec], [Enable dnssec debugging messages]))
|
AC_ARG_ENABLE(debug-sec, AC_HELP_STRING([--enable-debug-sec], [Enable dnssec debugging messages]))
|
||||||
AC_ARG_ENABLE(debug-server, AC_HELP_STRING([--enable-debug-server], [Enable server debugging messages]))
|
AC_ARG_ENABLE(debug-server, AC_HELP_STRING([--enable-debug-server], [Enable server debugging messages]))
|
||||||
AC_ARG_ENABLE(all-debugging, AC_HELP_STRING([--enable-all-debugging], [Enable all debugging messages]))
|
AC_ARG_ENABLE(debug-anchor, AC_HELP_STRING([--enable-debug-anchor], [Enable anchor debugging messages]))
|
||||||
|
AC_ARG_ENABLE(all-debugging, AC_HELP_STRING([--enable-all-debugging], [Enable scheduling, stub and dnssec debugging]))
|
||||||
case "$enable_all_debugging" in
|
case "$enable_all_debugging" in
|
||||||
yes)
|
yes)
|
||||||
enable_debug_req=yes
|
enable_debug_req=yes
|
||||||
|
@ -171,6 +185,7 @@ case "$enable_all_debugging" in
|
||||||
enable_debug_daemon=yes
|
enable_debug_daemon=yes
|
||||||
enable_debug_sec=yes
|
enable_debug_sec=yes
|
||||||
enable_debug_server=yes
|
enable_debug_server=yes
|
||||||
|
enable_debug_anchor=yes
|
||||||
;;
|
;;
|
||||||
no|*)
|
no|*)
|
||||||
;;
|
;;
|
||||||
|
@ -217,6 +232,13 @@ case "$enable_debug_server" in
|
||||||
no|*)
|
no|*)
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
case "$enable_debug_anchor" in
|
||||||
|
yes)
|
||||||
|
AC_DEFINE_UNQUOTED([ANCHOR_DEBUG], [1], [Define this enable printing of anchor debugging messages.])
|
||||||
|
;;
|
||||||
|
no|*)
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
|
||||||
dnl Hidden debugging options
|
dnl Hidden debugging options
|
||||||
|
@ -232,7 +254,7 @@ esac
|
||||||
|
|
||||||
|
|
||||||
DEFAULT_EVENTLOOP=select_eventloop
|
DEFAULT_EVENTLOOP=select_eventloop
|
||||||
AC_CHECK_HEADERS([sys/poll.h poll.h sys/resource.h],,, [AC_INCLUDES_DEFAULT])
|
AC_CHECK_HEADERS([signal.h sys/poll.h poll.h sys/resource.h sys/types.h],,, [AC_INCLUDES_DEFAULT])
|
||||||
AC_ARG_ENABLE(poll-eventloop, AC_HELP_STRING([--disable-poll-eventloop], [Disable default eventloop based on poll (default=enabled if available)]))
|
AC_ARG_ENABLE(poll-eventloop, AC_HELP_STRING([--disable-poll-eventloop], [Disable default eventloop based on poll (default=enabled if available)]))
|
||||||
case "$enable_poll_eventloop" in
|
case "$enable_poll_eventloop" in
|
||||||
no)
|
no)
|
||||||
|
@ -280,11 +302,66 @@ case "$enable_native_stub_dnssec" in
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
# check wether strptime also works
|
||||||
|
AC_DEFUN([AC_CHECK_STRPTIME_WORKS],
|
||||||
|
[AC_REQUIRE([AC_PROG_CC])
|
||||||
|
AC_MSG_CHECKING(whether strptime works)
|
||||||
|
if test c${cross_compiling} = cno; then
|
||||||
|
AC_RUN_IFELSE([AC_LANG_SOURCE([[
|
||||||
|
#define _XOPEN_SOURCE 600
|
||||||
|
#include <time.h>
|
||||||
|
int main(void) { struct tm tm; char *res;
|
||||||
|
res = strptime("2010-07-15T00:00:00+00:00", "%t%Y%t-%t%m%t-%t%d%tT%t%H%t:%t%M%t:%t%S%t", &tm);
|
||||||
|
if (!res) return 2;
|
||||||
|
res = strptime("20070207111842", "%Y%m%d%H%M%S", &tm);
|
||||||
|
if (!res) return 1; return 0; }
|
||||||
|
]])] , [eval "ac_cv_c_strptime_works=yes"], [eval "ac_cv_c_strptime_works=no"])
|
||||||
|
else
|
||||||
|
eval "ac_cv_c_strptime_works=maybe"
|
||||||
|
fi
|
||||||
|
AC_MSG_RESULT($ac_cv_c_strptime_works)
|
||||||
|
if test $ac_cv_c_strptime_works = no; then
|
||||||
|
AC_LIBOBJ(strptime)
|
||||||
|
else
|
||||||
|
AC_DEFINE_UNQUOTED([STRPTIME_WORKS], 1, [use default strptime.])
|
||||||
|
fi
|
||||||
|
])dnl
|
||||||
|
|
||||||
|
AC_CHECK_FUNCS([strptime],[AC_CHECK_STRPTIME_WORKS],[AC_LIBOBJ([strptime])])
|
||||||
|
|
||||||
# search to set include and library paths right
|
# search to set include and library paths right
|
||||||
# find libidn (no libidn on windows though)
|
# find libidn (no libidn on windows though)
|
||||||
AC_CHECK_HEADERS([windows.h winsock.h stdio.h winsock2.h ws2tcpip.h],,, [AC_INCLUDES_DEFAULT])
|
AC_CHECK_HEADERS([windows.h winsock.h stdio.h winsock2.h ws2tcpip.h],,, [AC_INCLUDES_DEFAULT])
|
||||||
ACX_CHECK_GETADDRINFO_WITH_INCLUDES
|
ACX_CHECK_GETADDRINFO_WITH_INCLUDES
|
||||||
|
|
||||||
|
AC_ARG_WITH(fd-setsize, AS_HELP_STRING([--with-fd-setsize=size],
|
||||||
|
[Set maximum file descriptor number that can be used by select]),
|
||||||
|
[], [withval="no"])
|
||||||
|
case "$withval" in
|
||||||
|
no)
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
AC_DEFINE_UNQUOTED([FD_SETSIZE], [$withval], [Alternate value for the FD_SETSIZE])
|
||||||
|
my_enable_unbound_event_api=1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
#---- check for pthreads library
|
||||||
|
AC_ARG_WITH(libpthread, AS_HELP_STRING([--without-libpthread],
|
||||||
|
[Disable libpthread (default is autodetect)]),
|
||||||
|
[], [withval="yes"])
|
||||||
|
|
||||||
|
case "$withval" in
|
||||||
|
yes)
|
||||||
|
AC_SEARCH_LIBS([pthread_mutex_init],[pthread], [
|
||||||
|
AC_DEFINE([HAVE_PTHREAD], [1], [Have pthreads library])
|
||||||
|
LIBS="-lpthread $LIBS"
|
||||||
|
], [AC_MSG_WARN([pthreads not available])])
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
USE_NSS="no"
|
USE_NSS="no"
|
||||||
# openssl
|
# openssl
|
||||||
if test $USE_NSS = "no"; then
|
if test $USE_NSS = "no"; then
|
||||||
|
@ -512,7 +589,7 @@ case "$enable_ed25519" in
|
||||||
no)
|
no)
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
|
if test "$USE_NSS" = "no" -a "$USE_NETTLE" = "no"; then
|
||||||
AC_CHECK_DECLS([NID_ED25519], [
|
AC_CHECK_DECLS([NID_ED25519], [
|
||||||
AC_DEFINE_UNQUOTED([USE_ED25519], [1], [Define this to enable ED25519 support.])
|
AC_DEFINE_UNQUOTED([USE_ED25519], [1], [Define this to enable ED25519 support.])
|
||||||
use_ed25519="yes"
|
use_ed25519="yes"
|
||||||
|
@ -577,6 +654,22 @@ case "$enable_stub_only" in
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
my_with_yaml=0
|
||||||
|
AC_ARG_ENABLE(yaml-config,)
|
||||||
|
case "$enable_yaml_config" in
|
||||||
|
yes)
|
||||||
|
AC_DEFINE_UNQUOTED([USE_YAML_CONFIG], [1], [Define this to enable YAML config support.])
|
||||||
|
AC_DEFINE_UNQUOTED([HAVE_GETDNS_YAML2DICT], [1], [Define this to enable getdns_yaml2dict function.])
|
||||||
|
|
||||||
|
GETDNS_XTRA_OBJS="convert_yaml_to_json.lo"
|
||||||
|
my_with_yaml=1
|
||||||
|
;;
|
||||||
|
no|*)
|
||||||
|
GETDNS_XTRA_OBJS=""
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
AC_SUBST(GETDNS_XTRA_OBJS)
|
||||||
|
|
||||||
if test "$USE_WINSOCK" = 1; then
|
if test "$USE_WINSOCK" = 1; then
|
||||||
AC_MSG_NOTICE([ Building on Windows ... YES! ])
|
AC_MSG_NOTICE([ Building on Windows ... YES! ])
|
||||||
AC_DEFINE_UNQUOTED([GETDNS_ON_WINDOWS], [1], [Define this to enable Windows build.])
|
AC_DEFINE_UNQUOTED([GETDNS_ON_WINDOWS], [1], [Define this to enable Windows build.])
|
||||||
|
@ -584,6 +677,30 @@ if test "$USE_WINSOCK" = 1; then
|
||||||
LIBS="$LIBS -lgdi32 -liphlpapi"
|
LIBS="$LIBS -lgdi32 -liphlpapi"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
dnl sigset_t or _sigset_t? MinGW is latter by default.
|
||||||
|
AC_CHECK_TYPES([sigset_t],
|
||||||
|
[],
|
||||||
|
[AC_CHECK_TYPES([_sigset_t],
|
||||||
|
[],
|
||||||
|
[AC_MSG_ERROR([Can't find type `sigset_t' or type `_sigset_t'])],
|
||||||
|
[AC_INCLUDES_DEFAULT
|
||||||
|
#ifdef HAVE_SIGNAL_H
|
||||||
|
#include <signal.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
|
])
|
||||||
|
],
|
||||||
|
[AC_INCLUDES_DEFAULT
|
||||||
|
#ifdef HAVE_SIGNAL_H
|
||||||
|
#include <signal.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
|
])
|
||||||
|
AC_CHECK_FUNCS(sigemptyset sigfillset sigaddset)
|
||||||
|
|
||||||
my_with_libidn=1
|
my_with_libidn=1
|
||||||
AC_ARG_WITH(libidn, AS_HELP_STRING([--with-libidn=pathname],
|
AC_ARG_WITH(libidn, AS_HELP_STRING([--with-libidn=pathname],
|
||||||
|
@ -691,11 +808,6 @@ then
|
||||||
])
|
])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test $found_all_libs = 0
|
|
||||||
then
|
|
||||||
AC_MSG_ERROR([Missing dependencies: $MISSING_DEPS])
|
|
||||||
fi
|
|
||||||
|
|
||||||
AC_PATH_PROG([DOXYGEN], [doxygen])
|
AC_PATH_PROG([DOXYGEN], [doxygen])
|
||||||
if test -z "$DOXYGEN";
|
if test -z "$DOXYGEN";
|
||||||
then AC_MSG_WARN([doxygen not found, continuing without])
|
then AC_MSG_WARN([doxygen not found, continuing without])
|
||||||
|
@ -1010,6 +1122,7 @@ AC_SUBST(GETDNS_QUERY)
|
||||||
AC_SUBST(INSTALL_GETDNS_QUERY)
|
AC_SUBST(INSTALL_GETDNS_QUERY)
|
||||||
AC_SUBST(UNINSTALL_GETDNS_QUERY)
|
AC_SUBST(UNINSTALL_GETDNS_QUERY)
|
||||||
|
|
||||||
|
stubby_with_yaml=0
|
||||||
AC_ARG_WITH(stubby, AS_HELP_STRING([--with-stubby],
|
AC_ARG_WITH(stubby, AS_HELP_STRING([--with-stubby],
|
||||||
[Compile and install stubby, the (stub) resolver daemon]),
|
[Compile and install stubby, the (stub) resolver daemon]),
|
||||||
[], [withval="no"])
|
[], [withval="no"])
|
||||||
|
@ -1017,39 +1130,89 @@ if test x_$withval = x_yes; then
|
||||||
STUBBY="stubby"
|
STUBBY="stubby"
|
||||||
INSTALL_STUBBY="install-stubby"
|
INSTALL_STUBBY="install-stubby"
|
||||||
UNINSTALL_STUBBY="uninstall-stubby"
|
UNINSTALL_STUBBY="uninstall-stubby"
|
||||||
|
if test $my_with_yaml = 0
|
||||||
|
then
|
||||||
|
STUBBY_XTRA_OBJS="convert_yaml_to_json.lo gbuffer.lo"
|
||||||
|
stubby_with_yaml=1
|
||||||
|
my_with_yaml=1
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
STUBBY=""
|
STUBBY=""
|
||||||
INSTALL_STUBBY=""
|
INSTALL_STUBBY=""
|
||||||
UNINSTALL_STUBBY=""
|
UNINSTALL_STUBBY=""
|
||||||
|
STUBBY_XTRA_OBJS=""
|
||||||
fi
|
fi
|
||||||
AC_SUBST(STUBBY)
|
AC_SUBST(STUBBY)
|
||||||
AC_SUBST(INSTALL_STUBBY)
|
AC_SUBST(INSTALL_STUBBY)
|
||||||
AC_SUBST(UNINSTALL_STUBBY)
|
AC_SUBST(UNINSTALL_STUBBY)
|
||||||
|
AC_SUBST(STUBBY_XTRA_OBJS)
|
||||||
|
|
||||||
AC_ARG_WITH(fd-setsize, AS_HELP_STRING([--with-fd-setsize=size],
|
STUBBY_LIBS=""
|
||||||
[Set maximum file descriptor number that can be used by select]),
|
STUBBY_LDFLAGS=""
|
||||||
[], [withval="no"])
|
|
||||||
case "$withval" in
|
if test $my_with_yaml = 1
|
||||||
no)
|
then
|
||||||
;;
|
if test $stubby_with_yaml = 1
|
||||||
*)
|
then
|
||||||
AC_DEFINE_UNQUOTED([FD_SETSIZE], [$withval], [Alternate value for the FD_SETSIZE])
|
getdns_LIBS="$LIBS"
|
||||||
my_enable_unbound_event_api=1
|
getdns_LDFLAGS="$LDFLAGS"
|
||||||
;;
|
LIBS="$initial_LIBS"
|
||||||
esac
|
LDFLAGS="$initial_LDFLAGS"
|
||||||
|
fi
|
||||||
|
AC_ARG_WITH(libyaml, AS_HELP_STRING([--with-libyaml=pathname],
|
||||||
|
[path to libyaml (default: search /usr/local ..)]),
|
||||||
|
[], [withval="yes"])
|
||||||
|
if test x_$withval = x_yes; then
|
||||||
|
for dir in /usr/local /opt/local /usr/pkg /usr/sfw; do
|
||||||
|
if test -f "$dir/include/yaml.h"; then
|
||||||
|
CFLAGS="$CFLAGS -I$dir/include"
|
||||||
|
LDFLAGS="$LDFLAGS -L$dir/lib"
|
||||||
|
AC_MSG_NOTICE([Found libyaml in $dir])
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
else
|
||||||
|
if test x_$withval != x_no; then
|
||||||
|
CFLAGS="$CFLAGS -I$withval/include"
|
||||||
|
LDFLAGS="$LDFLAGS -L$withval/lib"
|
||||||
|
else
|
||||||
|
if test $stubby_with_yaml = 1
|
||||||
|
then
|
||||||
|
AC_MSG_ERROR([libyaml required for building Stubby])
|
||||||
|
fi
|
||||||
|
my_with_yaml=0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if test $my_with_yaml = 1
|
||||||
|
then
|
||||||
|
AC_MSG_NOTICE([Checking for dependency libyaml])
|
||||||
|
AC_CHECK_LIB([yaml], [yaml_parser_parse], [], [
|
||||||
|
MISSING_DEPS="${MISSING_DEPS}${MISSING_SEP}libyaml"
|
||||||
|
MISSING_SEP=", "
|
||||||
|
found_all_libs=0
|
||||||
|
])
|
||||||
|
fi
|
||||||
|
if test $stubby_with_yaml = 1
|
||||||
|
then
|
||||||
|
STUBBY_LDFLAGS="$LDFLAGS"
|
||||||
|
STUBBY_LIBS="$LIBS"
|
||||||
|
LIBS="$getdns_LIBS"
|
||||||
|
LDFLAGS="$getdns_LDFLAGS"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
AC_SUBST(STUBBY_LDFLAGS)
|
||||||
|
AC_SUBST(STUBBY_LIBS)
|
||||||
|
|
||||||
|
if test $found_all_libs = 0
|
||||||
|
then
|
||||||
|
AC_MSG_ERROR([Missing dependencies: $MISSING_DEPS])
|
||||||
|
fi
|
||||||
|
|
||||||
AC_CONFIG_FILES([Makefile src/Makefile src/version.c src/getdns/getdns.h src/getdns/getdns_extra.h spec/example/Makefile src/test/Makefile src/tools/Makefile doc/Makefile getdns.pc getdns_ext_event.pc])
|
AC_CONFIG_FILES([Makefile src/Makefile src/version.c src/getdns/getdns.h src/getdns/getdns_extra.h spec/example/Makefile src/test/Makefile src/tools/Makefile doc/Makefile getdns.pc getdns_ext_event.pc])
|
||||||
if [ test -n "$DOXYGEN" ]
|
if [ test -n "$DOXYGEN" ]
|
||||||
then AC_CONFIG_FILES([src/Doxyfile])
|
then AC_CONFIG_FILES([src/Doxyfile])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
#---- check for pthreads library
|
|
||||||
AC_SEARCH_LIBS([pthread_mutex_init],[pthread], [
|
|
||||||
AC_DEFINE([HAVE_PTHREAD], [1], [Have pthreads library])
|
|
||||||
LIBS="-lpthread $LIBS"
|
|
||||||
], [AC_MSG_WARN([pthreads not available])])
|
|
||||||
|
|
||||||
AC_MSG_CHECKING([whether the C compiler (${CC-cc}) supports the __func__ variable])
|
AC_MSG_CHECKING([whether the C compiler (${CC-cc}) supports the __func__ variable])
|
||||||
AC_LANG_PUSH(C)
|
AC_LANG_PUSH(C)
|
||||||
AC_COMPILE_IFELSE(
|
AC_COMPILE_IFELSE(
|
||||||
|
@ -1064,7 +1227,7 @@ dnl ----- Start of "Things needed for gldns" section
|
||||||
dnl -----
|
dnl -----
|
||||||
dnl ---------------------------------------------------------------------------
|
dnl ---------------------------------------------------------------------------
|
||||||
|
|
||||||
AC_CHECK_HEADERS([stdarg.h stdint.h netinet/in.h arpa/inet.h netdb.h sys/socket.h time.h sys/time.h sys/select.h endian.h],,, [AC_INCLUDES_DEFAULT])
|
AC_CHECK_HEADERS([stdarg.h stdint.h netinet/in.h arpa/inet.h netdb.h sys/socket.h time.h sys/time.h sys/select.h endian.h limits.h sys/limits.h],,, [AC_INCLUDES_DEFAULT])
|
||||||
|
|
||||||
dnl Check the printf-format attribute (if any)
|
dnl Check the printf-format attribute (if any)
|
||||||
dnl result in HAVE_ATTR_FORMAT.
|
dnl result in HAVE_ATTR_FORMAT.
|
||||||
|
@ -1107,11 +1270,12 @@ fi
|
||||||
# system implementation.
|
# system implementation.
|
||||||
PKG_CHECK_MODULES([LIBBSD],[libbsd-overlay],[
|
PKG_CHECK_MODULES([LIBBSD],[libbsd-overlay],[
|
||||||
LIBS="$LIBS $LIBBSD_LIBS"
|
LIBS="$LIBS $LIBBSD_LIBS"
|
||||||
|
STUBBY_LIBS="$STUBBY_LIBS $LIBBSD_LIBS"
|
||||||
CFLAGS="$CFLAGS $LIBBSD_CFLAGS"
|
CFLAGS="$CFLAGS $LIBBSD_CFLAGS"
|
||||||
],[
|
],[
|
||||||
AC_MSG_WARN([libbsd not found or usable; using embedded code instead])
|
AC_MSG_WARN([libbsd not found or usable; using embedded code instead])
|
||||||
])
|
])
|
||||||
AC_CHECK_DECLS([strlcpy,arc4random,arc4random_uniform])
|
AC_CHECK_DECLS([inet_pton,inet_ntop,strlcpy,arc4random,arc4random_uniform])
|
||||||
AC_REPLACE_FUNCS(inet_pton)
|
AC_REPLACE_FUNCS(inet_pton)
|
||||||
AC_REPLACE_FUNCS(inet_ntop)
|
AC_REPLACE_FUNCS(inet_ntop)
|
||||||
AC_REPLACE_FUNCS(strlcpy)
|
AC_REPLACE_FUNCS(strlcpy)
|
||||||
|
@ -1187,14 +1351,45 @@ AH_BOTTOM([
|
||||||
# ifndef FD_SETSIZE
|
# ifndef FD_SETSIZE
|
||||||
# define FD_SETSIZE 1024
|
# define FD_SETSIZE 1024
|
||||||
# endif
|
# endif
|
||||||
# define PRIsz "%Iu"
|
|
||||||
|
/* the version of the windows API enabled */
|
||||||
|
# ifndef WINVER
|
||||||
|
# define WINVER 0x0600 // 0x0502
|
||||||
|
# endif
|
||||||
|
# ifndef _WIN32_WINNT
|
||||||
|
# define _WIN32_WINNT 0x0600 // 0x0502
|
||||||
|
# endif
|
||||||
|
# ifdef HAVE_WS2TCPIP_H
|
||||||
|
# include <ws2tcpip.h>
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# ifdef _MSC_VER
|
||||||
|
# if _MSC_VER >= 1800
|
||||||
|
# define PRIsz "zu"
|
||||||
|
# else
|
||||||
|
# define PRIsz "Iu"
|
||||||
|
# endif
|
||||||
|
# else
|
||||||
|
# define PRIsz "Iu"
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# ifdef HAVE_WINSOCK2_H
|
||||||
|
# include <winsock2.h>
|
||||||
|
# endif
|
||||||
|
|
||||||
|
/* detect if we need to cast to unsigned int for FD_SET to avoid warnings */
|
||||||
|
# ifdef HAVE_WINSOCK2_H
|
||||||
|
# define FD_SET_T (u_int)
|
||||||
|
# else
|
||||||
|
# define FD_SET_T
|
||||||
|
# endif
|
||||||
|
|
||||||
/* Windows wants us to use _strdup instead of strdup */
|
/* Windows wants us to use _strdup instead of strdup */
|
||||||
# ifndef strdup
|
# ifndef strdup
|
||||||
# define strdup _strdup
|
# define strdup _strdup
|
||||||
# endif
|
# endif
|
||||||
#else
|
#else
|
||||||
# define PRIsz "%zu"
|
# define PRIsz "zu"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
@ -1203,34 +1398,6 @@ AH_BOTTOM([
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
/* the version of the windows API enabled */
|
|
||||||
#ifndef WINVER
|
|
||||||
#define WINVER 0x0600 // 0x0502
|
|
||||||
#endif
|
|
||||||
#ifndef _WIN32_WINNT
|
|
||||||
#define _WIN32_WINNT 0x0600 // 0x0502
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_WINSOCK2_H
|
|
||||||
#include <winsock2.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_WS2TCPIP_H
|
|
||||||
#include <ws2tcpip.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef USE_WINSOCK
|
|
||||||
#define ARG_LL "%ll"
|
|
||||||
#else
|
|
||||||
#define ARG_LL "%I64"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* detect if we need to cast to unsigned int for FD_SET to avoid warnings */
|
|
||||||
#ifdef HAVE_WINSOCK2_H
|
|
||||||
#define FD_SET_T (u_int)
|
|
||||||
#else
|
|
||||||
#define FD_SET_T
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
@ -1277,18 +1444,21 @@ void SHA512_Final(uint8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*);
|
||||||
unsigned char *SHA512(void* data, unsigned int data_len, unsigned char *digest);
|
unsigned char *SHA512(void* data, unsigned int data_len, unsigned char *digest);
|
||||||
#endif /* COMPAT_SHA512 */
|
#endif /* COMPAT_SHA512 */
|
||||||
|
|
||||||
#ifndef HAVE_INET_PTON
|
#ifndef HAVE_DECL_INET_PTON
|
||||||
int inet_pton(int af, const char* src, void* dst);
|
int inet_pton(int af, const char* src, void* dst);
|
||||||
#endif /* HAVE_INET_PTON */
|
#endif /* HAVE_INET_PTON */
|
||||||
|
|
||||||
#ifndef HAVE_INET_NTOP
|
#ifndef HAVE_DECL_INET_NTOP
|
||||||
const char *inet_ntop(int af, const void *src, char *dst, size_t size);
|
const char *inet_ntop(int af, const void *src, char *dst, size_t size);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_WINSOCK
|
#ifdef USE_WINSOCK
|
||||||
|
# ifndef _CUSTOM_VSNPRINTF
|
||||||
|
# define _CUSTOM_VSNPRINTF
|
||||||
static inline int _gldns_custom_vsnprintf(char *str, size_t size, const char *format, va_list ap)
|
static inline int _gldns_custom_vsnprintf(char *str, size_t size, const char *format, va_list ap)
|
||||||
{ int r = vsnprintf(str, size, format, ap); return r == -1 ? _vscprintf(format, ap) : r; }
|
{ int r = vsnprintf(str, size, format, ap); return r == -1 ? _vscprintf(format, ap) : r; }
|
||||||
# define vsnprintf _gldns_custom_vsnprintf
|
# define vsnprintf _gldns_custom_vsnprintf
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -1315,6 +1485,10 @@ static inline int _gldns_custom_vsnprintf(char *str, size_t size, const char *fo
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_NETINET_IN_H
|
#ifdef HAVE_NETINET_IN_H
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -1331,6 +1505,20 @@ static inline int _gldns_custom_vsnprintf(char *str, size_t size, const char *fo
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_LIMITS_H
|
||||||
|
#include <limits.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_SYS_LIMITS_H
|
||||||
|
#include <sys/limits.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PATH_MAX
|
||||||
|
#define _GETDNS_PATH_MAX PATH_MAX
|
||||||
|
#else
|
||||||
|
#define _GETDNS_PATH_MAX 2048
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef PRIu64
|
#ifndef PRIu64
|
||||||
#define PRIu64 "llu"
|
#define PRIu64 "llu"
|
||||||
#endif
|
#endif
|
||||||
|
@ -1363,6 +1551,29 @@ static inline int _gldns_custom_vsnprintf(char *str, size_t size, const char *fo
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(HAVE_STRPTIME) || !defined(STRPTIME_WORKS)
|
||||||
|
#define strptime unbound_strptime
|
||||||
|
struct tm;
|
||||||
|
char *strptime(const char *s, const char *format, struct tm *tm);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(HAVE_SIGSET_T) && defined(HAVE__SIGSET_T)
|
||||||
|
typedef _sigset_t sigset_t;
|
||||||
|
#endif
|
||||||
|
#if !defined(HAVE_SIGEMPTYSET)
|
||||||
|
# define sigemptyset(pset) (*(pset) = 0)
|
||||||
|
#endif
|
||||||
|
#if !defined(HAVE_SIGFILLSET)
|
||||||
|
# define sigfillset(pset) (*(pset) = (sigset_t)-1)
|
||||||
|
#endif
|
||||||
|
#if !defined(HAVE_SIGADDSET)
|
||||||
|
# define sigaddset(pset, num) (*(pset) |= (1L<<(num)))
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_LIBUNBOUND
|
#ifdef HAVE_LIBUNBOUND
|
||||||
# include <unbound.h>
|
# include <unbound.h>
|
||||||
# ifdef HAVE_UNBOUND_EVENT_H
|
# ifdef HAVE_UNBOUND_EVENT_H
|
||||||
|
@ -1380,6 +1591,10 @@ int ub_resolve_event(struct ub_ctx* ctx, const char* name, int rrtype,
|
||||||
# endif
|
# endif
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
])
|
])
|
||||||
|
|
||||||
dnl ---------------------------------------------------------------------------
|
dnl ---------------------------------------------------------------------------
|
||||||
|
|
162
src/Makefile.in
162
src/Makefile.in
|
@ -55,11 +55,13 @@ stubbysrcdir = $(srcdir)/../stubby
|
||||||
LIBTOOL = ../libtool
|
LIBTOOL = ../libtool
|
||||||
|
|
||||||
CC=@CC@
|
CC=@CC@
|
||||||
CFLAGS=-I$(srcdir) -I. -I$(srcdir)/util/auxiliary @CFLAGS@ @CPPFLAGS@ $(XTRA_CFLAGS)
|
CFLAGS=-I$(srcdir) -I. -I$(srcdir)/util/auxiliary -I$(stubbysrcdir)/src @CFLAGS@ @CPPFLAGS@ $(XTRA_CFLAGS)
|
||||||
WPEDANTICFLAG=@WPEDANTICFLAG@
|
WPEDANTICFLAG=@WPEDANTICFLAG@
|
||||||
WNOERRORFLAG=@WNOERRORFLAG@
|
WNOERRORFLAG=@WNOERRORFLAG@
|
||||||
LDFLAGS=@LDFLAGS@ @LIBS@
|
LDFLAGS=@LDFLAGS@ @LIBS@
|
||||||
|
|
||||||
|
STUBBY_LDFLAGS=@STUBBY_LDFLAGS@ @STUBBY_LIBS@
|
||||||
|
|
||||||
EXTENSION_LIBEVENT_LIB=@EXTENSION_LIBEVENT_LIB@
|
EXTENSION_LIBEVENT_LIB=@EXTENSION_LIBEVENT_LIB@
|
||||||
EXTENSION_LIBEVENT_EXT_LIBS=@EXTENSION_LIBEVENT_EXT_LIBS@
|
EXTENSION_LIBEVENT_EXT_LIBS=@EXTENSION_LIBEVENT_EXT_LIBS@
|
||||||
EXTENSION_LIBEVENT_LDFLAGS=@EXTENSION_LIBEVENT_LDFLAGS@
|
EXTENSION_LIBEVENT_LDFLAGS=@EXTENSION_LIBEVENT_LDFLAGS@
|
||||||
|
@ -75,7 +77,7 @@ C99COMPATFLAGS=@C99COMPATFLAGS@
|
||||||
DEFAULT_EVENTLOOP_OBJ=@DEFAULT_EVENTLOOP@.lo
|
DEFAULT_EVENTLOOP_OBJ=@DEFAULT_EVENTLOOP@.lo
|
||||||
|
|
||||||
GETDNS_OBJ=const-info.lo convert.lo dict.lo dnssec.lo general.lo \
|
GETDNS_OBJ=const-info.lo convert.lo dict.lo dnssec.lo general.lo \
|
||||||
list.lo request-internal.lo pubkey-pinning.lo rr-dict.lo \
|
list.lo request-internal.lo platform.lo pubkey-pinning.lo rr-dict.lo \
|
||||||
rr-iter.lo server.lo stub.lo sync.lo ub_loop.lo util-internal.lo \
|
rr-iter.lo server.lo stub.lo sync.lo ub_loop.lo util-internal.lo \
|
||||||
mdns.lo
|
mdns.lo
|
||||||
|
|
||||||
|
@ -91,10 +93,15 @@ COMPAT_OBJ=$(LIBOBJS:.o=.lo)
|
||||||
UTIL_OBJ=rbtree.lo val_secalgo.lo lruhash.lo lookup3.lo locks.lo
|
UTIL_OBJ=rbtree.lo val_secalgo.lo lruhash.lo lookup3.lo locks.lo
|
||||||
|
|
||||||
JSMN_OBJ=jsmn.lo
|
JSMN_OBJ=jsmn.lo
|
||||||
|
YXML_OBJ=yxml.lo
|
||||||
|
|
||||||
|
YAML_OBJ=convert_yaml_to_json.lo
|
||||||
|
GETDNS_XTRA_OBJS=@GETDNS_XTRA_OBJS@
|
||||||
|
STUBBY_XTRA_OBJS=@STUBBY_XTRA_OBJS@
|
||||||
|
|
||||||
EXTENSION_OBJ=$(DEFAULT_EVENTLOOP_OBJ) libevent.lo libev.lo
|
EXTENSION_OBJ=$(DEFAULT_EVENTLOOP_OBJ) libevent.lo libev.lo
|
||||||
|
|
||||||
NON_C99_OBJS=context.lo libuv.lo
|
NON_C99_OBJS=libuv.lo context.lo anchor.lo
|
||||||
|
|
||||||
.SUFFIXES: .c .o .a .lo .h
|
.SUFFIXES: .c .o .a .lo .h
|
||||||
|
|
||||||
|
@ -123,9 +130,18 @@ $(UTIL_OBJ):
|
||||||
$(JSMN_OBJ):
|
$(JSMN_OBJ):
|
||||||
$(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) -DJSMN_GETDNS -c $(srcdir)/jsmn/$(@:.lo=.c) -o $@
|
$(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) -DJSMN_GETDNS -c $(srcdir)/jsmn/$(@:.lo=.c) -o $@
|
||||||
|
|
||||||
|
$(YAML_OBJ):
|
||||||
|
$(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) -c $(stubbysrcdir)/src/yaml/$(@:.lo=.c) -o $@
|
||||||
|
|
||||||
|
$(YXML_OBJ):
|
||||||
|
$(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) -I$(srcdir)/yxml -DYXML_GETDNS -Wno-unused-parameter -c $(srcdir)/yxml/$(@:.lo=.c) -o $@
|
||||||
|
|
||||||
$(EXTENSION_OBJ):
|
$(EXTENSION_OBJ):
|
||||||
$(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) $(WPEDANTICFLAG) -c $(srcdir)/extension/$(@:.lo=.c) -o $@
|
$(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) $(WPEDANTICFLAG) -c $(srcdir)/extension/$(@:.lo=.c) -o $@
|
||||||
|
|
||||||
|
anchor.lo:
|
||||||
|
$(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) $(WPEDANTICFLAG) $(C99COMPATFLAGS) -c $(srcdir)/anchor.c -o anchor.lo
|
||||||
|
|
||||||
context.lo:
|
context.lo:
|
||||||
$(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) $(WPEDANTICFLAG) $(C99COMPATFLAGS) -c $(srcdir)/context.c -o context.lo
|
$(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) $(WPEDANTICFLAG) $(C99COMPATFLAGS) -c $(srcdir)/context.c -o context.lo
|
||||||
|
|
||||||
|
@ -144,7 +160,7 @@ install-headers: getdns/getdns.h getdns/getdns_extra.h
|
||||||
uninstall-headers:
|
uninstall-headers:
|
||||||
rm -rf $(DESTDIR)$(includedir)/getdns
|
rm -rf $(DESTDIR)$(includedir)/getdns
|
||||||
|
|
||||||
install-libs: libgetdns.la
|
install-libs: libgetdns.la $(EXTENSION_LIBEVENT_LIB) $(EXTENSION_LIBUV_LIB) $(EXTENSION_LIBEV_LIB)
|
||||||
$(INSTALL) -m 755 -d $(DESTDIR)$(libdir)
|
$(INSTALL) -m 755 -d $(DESTDIR)$(libdir)
|
||||||
$(LIBTOOL) --mode=install cp libgetdns.la $(DESTDIR)$(libdir)
|
$(LIBTOOL) --mode=install cp libgetdns.la $(DESTDIR)$(libdir)
|
||||||
if test $(have_libevent) = 1 ; then $(LIBTOOL) --mode=install cp $(EXTENSION_LIBEVENT_LIB) $(DESTDIR)$(libdir) ; fi
|
if test $(have_libevent) = 1 ; then $(LIBTOOL) --mode=install cp $(EXTENSION_LIBEVENT_LIB) $(DESTDIR)$(libdir) ; fi
|
||||||
|
@ -172,9 +188,8 @@ libgetdns_ext_uv.la: libgetdns.la libuv.lo
|
||||||
libgetdns_ext_ev.la: libgetdns.la libev.lo
|
libgetdns_ext_ev.la: libgetdns.la libev.lo
|
||||||
$(LIBTOOL) --tag=CC --mode=link $(CC) -o $@ libev.lo libgetdns.la $(LDFLAGS) $(EXTENSION_LIBEV_LDFLAGS) $(EXTENSION_LIBEV_EXT_LIBS) -rpath $(libdir) -version-info $(libversion) -no-undefined -export-symbols $(srcdir)/extension/libev.symbols
|
$(LIBTOOL) --tag=CC --mode=link $(CC) -o $@ libev.lo libgetdns.la $(LDFLAGS) $(EXTENSION_LIBEV_LDFLAGS) $(EXTENSION_LIBEV_EXT_LIBS) -rpath $(libdir) -version-info $(libversion) -no-undefined -export-symbols $(srcdir)/extension/libev.symbols
|
||||||
|
|
||||||
|
libgetdns.la: $(GETDNS_OBJ) version.lo context.lo anchor.lo $(DEFAULT_EVENTLOOP_OBJ) $(GLDNS_OBJ) $(COMPAT_OBJ) $(UTIL_OBJ) $(JSMN_OBJ) $(YXML_OBJ) $(GETDNS_XTRA_OBJS)
|
||||||
libgetdns.la: $(GETDNS_OBJ) version.lo context.lo $(DEFAULT_EVENTLOOP_OBJ) $(GLDNS_OBJ) $(COMPAT_OBJ) $(UTIL_OBJ) $(JSMN_OBJ)
|
$(LIBTOOL) --tag=CC --mode=link $(CC) -o $@ $(GETDNS_OBJ) version.lo context.lo anchor.lo $(DEFAULT_EVENTLOOP_OBJ) $(GLDNS_OBJ) $(COMPAT_OBJ) $(UTIL_OBJ) $(JSMN_OBJ) $(YXML_OBJ) $(GETDNS_XTRA_OBJS) $(LDFLAGS) -rpath $(libdir) -version-info $(libversion) -no-undefined -export-symbols $(srcdir)/libgetdns.symbols
|
||||||
$(LIBTOOL) --tag=CC --mode=link $(CC) -o $@ $(GETDNS_OBJ) version.lo context.lo $(DEFAULT_EVENTLOOP_OBJ) $(GLDNS_OBJ) $(COMPAT_OBJ) $(UTIL_OBJ) $(JSMN_OBJ) $(LDFLAGS) -rpath $(libdir) -version-info $(libversion) -no-undefined -export-symbols $(srcdir)/libgetdns.symbols
|
|
||||||
|
|
||||||
test: default
|
test: default
|
||||||
cd test && $(MAKE) $@
|
cd test && $(MAKE) $@
|
||||||
|
@ -185,17 +200,29 @@ getdns_query: default
|
||||||
stubby.lo: $(stubbysrcdir)/src/stubby.c
|
stubby.lo: $(stubbysrcdir)/src/stubby.c
|
||||||
$(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) $(WPEDANTICFLAG) -DSTUBBYCONFDIR=\"$(sysconfdir)/stubby\" -DRUNSTATEDIR=\"$(runstatedir)\" -c $< -o $@
|
$(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) $(WPEDANTICFLAG) -DSTUBBYCONFDIR=\"$(sysconfdir)/stubby\" -DRUNSTATEDIR=\"$(runstatedir)\" -c $< -o $@
|
||||||
|
|
||||||
stubby: stubby.lo libgetdns.la
|
stubby: stubby.lo libgetdns.la $(STUBBY_XTRA_OBJS)
|
||||||
$(LIBTOOL) --tag=CC --mode=link $(CC) -o $@ stubby.lo $(LDFLAGS) libgetdns.la
|
$(LIBTOOL) --tag=CC --mode=link $(CC) -o $@ stubby.lo $(STUBBY_XTRA_OBJS) $(STUBBY_LDFLAGS) libgetdns.la
|
||||||
|
|
||||||
install-stubby: stubby $(stubbysrcdir)/stubby.conf.example $(stubbysrcdir)/stubby-setdns-macos.sh
|
install-stubby-files-unix: $(stubbysrcdir)/stubby.yml.example
|
||||||
$(INSTALL) -m 755 -d $(DESTDIR)$(bindir)
|
$(INSTALL) -m 755 -d $(DESTDIR)$(stubbyconfdir)
|
||||||
$(LIBTOOL) --mode=install cp stubby $(DESTDIR)$(bindir)
|
test -f $(DESTDIR)$(stubbyconfdir)/stubby.yml || \
|
||||||
|
$(INSTALL_DATA) $(stubbysrcdir)/stubby.yml.example $(DESTDIR)$(stubbyconfdir)/stubby.yml
|
||||||
|
|
||||||
|
install-stubby-files-macos: $(stubbysrcdir)/stubby-setdns-macos.sh install-stubby-files-unix
|
||||||
$(INSTALL) -m 755 -d $(DESTDIR)$(sbindir)
|
$(INSTALL) -m 755 -d $(DESTDIR)$(sbindir)
|
||||||
$(INSTALL) -m 755 $(stubbysrcdir)/stubby-setdns-macos.sh $(DESTDIR)$(sbindir)
|
$(INSTALL) -m 755 $(stubbysrcdir)/stubby-setdns-macos.sh $(DESTDIR)$(sbindir)
|
||||||
|
|
||||||
|
stubby.yml.windows: $(stubbysrcdir)/stubby.yml.example
|
||||||
|
awk "{sub(/$$/,\"\r\")}1" $(stubbysrcdir)/stubby.yml.example > stubby.yml.windows
|
||||||
|
|
||||||
|
install-stubby-files-windows: stubby.yml.windows
|
||||||
$(INSTALL) -m 755 -d $(DESTDIR)$(stubbyconfdir)
|
$(INSTALL) -m 755 -d $(DESTDIR)$(stubbyconfdir)
|
||||||
test -f $(DESTDIR)$(stubbyconfdir)/stubby.conf || \
|
test -f $(DESTDIR)$(stubbyconfdir)/stubby.yml || \
|
||||||
$(INSTALL_DATA) $(stubbysrcdir)/stubby.conf.example $(DESTDIR)$(stubbyconfdir)/stubby.conf
|
$(INSTALL_DATA) stubby.yml.windows $(DESTDIR)$(stubbyconfdir)/stubby.yml
|
||||||
|
|
||||||
|
install-stubby: stubby install-stubby-files-@HOSTOS@
|
||||||
|
$(INSTALL) -m 755 -d $(DESTDIR)$(bindir)
|
||||||
|
$(LIBTOOL) --mode=install cp stubby $(DESTDIR)$(bindir)
|
||||||
|
|
||||||
uninstall-stubby:
|
uninstall-stubby:
|
||||||
$(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(bindir)/stubby
|
$(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(bindir)/stubby
|
||||||
|
@ -226,14 +253,17 @@ Makefile: $(srcdir)/Makefile.in ../config.status
|
||||||
|
|
||||||
depend:
|
depend:
|
||||||
(cd $(srcdir) ; awk 'BEGIN{P=1}{if(P)print}/^# Dependencies/{P=0}' Makefile.in > Makefile.in.new )
|
(cd $(srcdir) ; awk 'BEGIN{P=1}{if(P)print}/^# Dependencies/{P=0}' Makefile.in > Makefile.in.new )
|
||||||
(blddir=`pwd`; cd $(srcdir) ; gcc -MM -I. -I"$$blddir" -Iutil/auxiliary *.c gldns/*.c compat/*.c util/*.c jsmn/*.c extension/*.c| \
|
|
||||||
|
(blddir=`pwd`; cd $(srcdir) ; gcc -MM -I. -I"$$blddir" -Iyxml -Iutil/auxiliary -I../stubby/src *.c gldns/*.c compat/*.c util/*.c jsmn/*.c yxml/*.c extension/*.c ../stubby/src/*.c | \
|
||||||
sed -e "s? $$blddir/? ?g" \
|
sed -e "s? $$blddir/? ?g" \
|
||||||
-e 's? gldns/? $$(srcdir)/gldns/?g' \
|
-e 's? gldns/? $$(srcdir)/gldns/?g' \
|
||||||
-e 's? compat/? $$(srcdir)/compat/?g' \
|
-e 's? compat/? $$(srcdir)/compat/?g' \
|
||||||
-e 's? util/auxiliary/util/? $$(srcdir)/util/auxiliary/util/?g' \
|
-e 's? util/auxiliary/util/? $$(srcdir)/util/auxiliary/util/?g' \
|
||||||
-e 's? util/? $$(srcdir)/util/?g' \
|
-e 's? util/? $$(srcdir)/util/?g' \
|
||||||
-e 's? jsmn/? $$(srcdir)/jsmn/?g' \
|
-e 's? jsmn/? $$(srcdir)/jsmn/?g' \
|
||||||
|
-e 's? yxml/? $$(srcdir)/yxml/?g' \
|
||||||
-e 's? extension/? $$(srcdir)/extension/?g' \
|
-e 's? extension/? $$(srcdir)/extension/?g' \
|
||||||
|
-e 's? \.\./stubby/? $$(stubbysrcdir)/?g' \
|
||||||
-e 's? \([a-z_-]*\)\.\([ch]\)? $$(srcdir)/\1.\2?g' \
|
-e 's? \([a-z_-]*\)\.\([ch]\)? $$(srcdir)/\1.\2?g' \
|
||||||
-e 's? \$$(srcdir)/config\.h? config.h?g' \
|
-e 's? \$$(srcdir)/config\.h? config.h?g' \
|
||||||
-e 's? \$$(srcdir)/getdns/getdns_extra\.h? getdns/getdns_extra.h?g' \
|
-e 's? \$$(srcdir)/getdns/getdns_extra\.h? getdns/getdns_extra.h?g' \
|
||||||
|
@ -251,22 +281,36 @@ depend:
|
||||||
FORCE:
|
FORCE:
|
||||||
|
|
||||||
# Dependencies for gldns, utils, the extensions and compat functions
|
# Dependencies for gldns, utils, the extensions and compat functions
|
||||||
|
anchor.lo anchor.o: $(srcdir)/anchor.c \
|
||||||
|
config.h \
|
||||||
|
$(srcdir)/debug.h $(srcdir)/anchor.h \
|
||||||
|
getdns/getdns.h \
|
||||||
|
getdns/getdns_extra.h \
|
||||||
|
$(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/types-internal.h \
|
||||||
|
$(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/context.h \
|
||||||
|
$(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \
|
||||||
|
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
|
||||||
|
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
|
||||||
|
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/yxml/yxml.h \
|
||||||
|
$(srcdir)/gldns/parseutil.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/wire2str.h \
|
||||||
|
$(srcdir)/gldns/keyraw.h $(srcdir)/general.h $(srcdir)/util-internal.h $(srcdir)/platform.h
|
||||||
const-info.lo const-info.o: $(srcdir)/const-info.c \
|
const-info.lo const-info.o: $(srcdir)/const-info.c \
|
||||||
getdns/getdns.h \
|
getdns/getdns.h \
|
||||||
getdns/getdns_extra.h \
|
getdns/getdns_extra.h \
|
||||||
$(srcdir)/const-info.h
|
$(srcdir)/const-info.h
|
||||||
context.lo context.o: $(srcdir)/context.c \
|
context.lo context.o: $(srcdir)/context.c \
|
||||||
config.h \
|
config.h \
|
||||||
$(srcdir)/debug.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/wire2str.h $(srcdir)/context.h \
|
$(srcdir)/anchor.h \
|
||||||
getdns/getdns.h \
|
getdns/getdns.h \
|
||||||
getdns/getdns_extra.h \
|
getdns/getdns_extra.h \
|
||||||
|
$(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/debug.h \
|
||||||
|
$(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/wire2str.h $(srcdir)/context.h \
|
||||||
$(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h \
|
$(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h \
|
||||||
$(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \
|
$(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \
|
||||||
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
|
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
|
||||||
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
|
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
|
||||||
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \
|
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/util-internal.h $(srcdir)/platform.h $(srcdir)/dnssec.h \
|
||||||
$(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/stub.h $(srcdir)/list.h \
|
$(srcdir)/gldns/rrdef.h $(srcdir)/stub.h $(srcdir)/list.h $(srcdir)/dict.h $(srcdir)/pubkey-pinning.h
|
||||||
$(srcdir)/dict.h $(srcdir)/pubkey-pinning.h
|
|
||||||
convert.lo convert.o: $(srcdir)/convert.c \
|
convert.lo convert.o: $(srcdir)/convert.c \
|
||||||
config.h \
|
config.h \
|
||||||
getdns/getdns.h \
|
getdns/getdns.h \
|
||||||
|
@ -276,9 +320,9 @@ convert.lo convert.o: $(srcdir)/convert.c \
|
||||||
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h \
|
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h \
|
||||||
$(srcdir)/util/lruhash.h $(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h \
|
$(srcdir)/util/lruhash.h $(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h \
|
||||||
$(srcdir)/util/orig-headers/locks.h $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/rr-iter.h \
|
$(srcdir)/util/orig-headers/locks.h $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/rr-iter.h \
|
||||||
$(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/wire2str.h \
|
$(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/anchor.h $(srcdir)/gldns/wire2str.h \
|
||||||
$(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/parseutil.h $(srcdir)/const-info.h $(srcdir)/dict.h \
|
$(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/parseutil.h $(srcdir)/const-info.h $(srcdir)/dict.h \
|
||||||
$(srcdir)/list.h $(srcdir)/jsmn/jsmn.h $(srcdir)/convert.h
|
$(srcdir)/list.h $(srcdir)/jsmn/jsmn.h $(stubbysrcdir)/src/yaml/convert_yaml_to_json.h $(srcdir)/convert.h
|
||||||
dict.lo dict.o: $(srcdir)/dict.c \
|
dict.lo dict.o: $(srcdir)/dict.c \
|
||||||
config.h \
|
config.h \
|
||||||
$(srcdir)/types-internal.h \
|
$(srcdir)/types-internal.h \
|
||||||
|
@ -289,7 +333,7 @@ dict.lo dict.o: $(srcdir)/dict.c \
|
||||||
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
|
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
|
||||||
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
|
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
|
||||||
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \
|
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \
|
||||||
$(srcdir)/gldns/pkthdr.h $(srcdir)/dict.h $(srcdir)/list.h $(srcdir)/const-info.h $(srcdir)/gldns/wire2str.h \
|
$(srcdir)/gldns/pkthdr.h $(srcdir)/anchor.h $(srcdir)/dict.h $(srcdir)/list.h $(srcdir)/const-info.h $(srcdir)/gldns/wire2str.h \
|
||||||
$(srcdir)/gldns/parseutil.h
|
$(srcdir)/gldns/parseutil.h
|
||||||
dnssec.lo dnssec.o: $(srcdir)/dnssec.c \
|
dnssec.lo dnssec.o: $(srcdir)/dnssec.c \
|
||||||
config.h \
|
config.h \
|
||||||
|
@ -301,10 +345,10 @@ dnssec.lo dnssec.o: $(srcdir)/dnssec.c \
|
||||||
$(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \
|
$(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \
|
||||||
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
|
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
|
||||||
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
|
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
|
||||||
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \
|
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \
|
||||||
$(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/str2wire.h \
|
$(srcdir)/gldns/pkthdr.h $(srcdir)/anchor.h $(srcdir)/util-internal.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h \
|
||||||
$(srcdir)/gldns/rrdef.h $(srcdir)/gldns/wire2str.h $(srcdir)/gldns/keyraw.h $(srcdir)/gldns/parseutil.h \
|
$(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/wire2str.h $(srcdir)/gldns/keyraw.h \
|
||||||
$(srcdir)/general.h $(srcdir)/dict.h $(srcdir)/list.h $(srcdir)/util/val_secalgo.h \
|
$(srcdir)/gldns/parseutil.h $(srcdir)/general.h $(srcdir)/dict.h $(srcdir)/list.h $(srcdir)/util/val_secalgo.h \
|
||||||
$(srcdir)/util/orig-headers/val_secalgo.h
|
$(srcdir)/util/orig-headers/val_secalgo.h
|
||||||
general.lo general.o: $(srcdir)/general.c \
|
general.lo general.o: $(srcdir)/general.c \
|
||||||
config.h \
|
config.h \
|
||||||
|
@ -316,9 +360,9 @@ general.lo general.o: $(srcdir)/general.c \
|
||||||
$(srcdir)/gldns/wire2str.h $(srcdir)/context.h $(srcdir)/extension/default_eventloop.h \
|
$(srcdir)/gldns/wire2str.h $(srcdir)/context.h $(srcdir)/extension/default_eventloop.h \
|
||||||
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
|
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
|
||||||
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
|
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
|
||||||
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \
|
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \
|
||||||
$(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/stub.h $(srcdir)/dict.h \
|
$(srcdir)/gldns/pkthdr.h $(srcdir)/anchor.h $(srcdir)/util-internal.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/stub.h \
|
||||||
$(srcdir)/mdns.h
|
$(srcdir)/dict.h $(srcdir)/mdns.h $(srcdir)/platform.h
|
||||||
list.lo list.o: $(srcdir)/list.c $(srcdir)/types-internal.h \
|
list.lo list.o: $(srcdir)/list.c $(srcdir)/types-internal.h \
|
||||||
getdns/getdns.h \
|
getdns/getdns.h \
|
||||||
getdns/getdns_extra.h \
|
getdns/getdns_extra.h \
|
||||||
|
@ -328,7 +372,7 @@ list.lo list.o: $(srcdir)/list.c $(srcdir)/types-internal.h \
|
||||||
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
|
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
|
||||||
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
|
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
|
||||||
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \
|
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \
|
||||||
$(srcdir)/gldns/pkthdr.h $(srcdir)/list.h $(srcdir)/dict.h
|
$(srcdir)/gldns/pkthdr.h $(srcdir)/anchor.h $(srcdir)/list.h $(srcdir)/dict.h
|
||||||
mdns.lo mdns.o: $(srcdir)/mdns.c \
|
mdns.lo mdns.o: $(srcdir)/mdns.c \
|
||||||
config.h \
|
config.h \
|
||||||
$(srcdir)/debug.h $(srcdir)/context.h \
|
$(srcdir)/debug.h $(srcdir)/context.h \
|
||||||
|
@ -338,10 +382,12 @@ mdns.lo mdns.o: $(srcdir)/mdns.c \
|
||||||
$(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \
|
$(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \
|
||||||
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
|
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
|
||||||
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
|
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
|
||||||
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/general.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/rrdef.h \
|
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \
|
||||||
$(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/mdns.h \
|
$(srcdir)/gldns/pkthdr.h $(srcdir)/anchor.h $(srcdir)/general.h $(srcdir)/gldns/rrdef.h $(srcdir)/util-internal.h \
|
||||||
$(srcdir)/util/auxiliary/util/fptr_wlist.h $(srcdir)/util/lookup3.h \
|
$(srcdir)/platform.h $(srcdir)/mdns.h $(srcdir)/util/auxiliary/util/fptr_wlist.h $(srcdir)/util/lookup3.h \
|
||||||
$(srcdir)/util/orig-headers/lookup3.h
|
$(srcdir)/util/orig-headers/lookup3.h
|
||||||
|
platform.lo platform.o: $(srcdir)/platform.c $(srcdir)/platform.h \
|
||||||
|
config.h
|
||||||
pubkey-pinning.lo pubkey-pinning.o: $(srcdir)/pubkey-pinning.c \
|
pubkey-pinning.lo pubkey-pinning.o: $(srcdir)/pubkey-pinning.c \
|
||||||
config.h \
|
config.h \
|
||||||
$(srcdir)/debug.h \
|
$(srcdir)/debug.h \
|
||||||
|
@ -352,8 +398,8 @@ pubkey-pinning.lo pubkey-pinning.o: $(srcdir)/pubkey-pinning.c \
|
||||||
$(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \
|
$(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \
|
||||||
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
|
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
|
||||||
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
|
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
|
||||||
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \
|
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \
|
||||||
$(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h
|
$(srcdir)/gldns/pkthdr.h $(srcdir)/anchor.h $(srcdir)/util-internal.h
|
||||||
request-internal.lo request-internal.o: $(srcdir)/request-internal.c \
|
request-internal.lo request-internal.o: $(srcdir)/request-internal.c \
|
||||||
config.h \
|
config.h \
|
||||||
$(srcdir)/types-internal.h \
|
$(srcdir)/types-internal.h \
|
||||||
|
@ -364,8 +410,8 @@ request-internal.lo request-internal.o: $(srcdir)/request-internal.c \
|
||||||
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
|
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
|
||||||
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
|
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
|
||||||
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \
|
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \
|
||||||
$(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/dict.h \
|
$(srcdir)/gldns/pkthdr.h $(srcdir)/anchor.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h \
|
||||||
$(srcdir)/convert.h $(srcdir)/general.h
|
$(srcdir)/dict.h $(srcdir)/convert.h $(srcdir)/general.h
|
||||||
rr-dict.lo rr-dict.o: $(srcdir)/rr-dict.c $(srcdir)/rr-dict.h \
|
rr-dict.lo rr-dict.o: $(srcdir)/rr-dict.c $(srcdir)/rr-dict.h \
|
||||||
config.h \
|
config.h \
|
||||||
getdns/getdns.h \
|
getdns/getdns.h \
|
||||||
|
@ -375,7 +421,8 @@ rr-dict.lo rr-dict.o: $(srcdir)/rr-dict.c $(srcdir)/rr-dict.h \
|
||||||
$(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \
|
$(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \
|
||||||
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
|
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
|
||||||
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
|
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
|
||||||
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/rr-iter.h $(srcdir)/gldns/pkthdr.h $(srcdir)/dict.h
|
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/rr-iter.h $(srcdir)/gldns/pkthdr.h $(srcdir)/anchor.h \
|
||||||
|
$(srcdir)/dict.h
|
||||||
rr-iter.lo rr-iter.o: $(srcdir)/rr-iter.c $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \
|
rr-iter.lo rr-iter.o: $(srcdir)/rr-iter.c $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \
|
||||||
config.h \
|
config.h \
|
||||||
getdns/getdns.h \
|
getdns/getdns.h \
|
||||||
|
@ -388,7 +435,8 @@ server.lo server.o: $(srcdir)/server.c \
|
||||||
$(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \
|
$(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \
|
||||||
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
|
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
|
||||||
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
|
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
|
||||||
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h
|
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \
|
||||||
|
$(srcdir)/gldns/pkthdr.h $(srcdir)/anchor.h $(srcdir)/util-internal.h $(srcdir)/platform.h
|
||||||
stub.lo stub.o: $(srcdir)/stub.c \
|
stub.lo stub.o: $(srcdir)/stub.c \
|
||||||
config.h \
|
config.h \
|
||||||
$(srcdir)/debug.h $(srcdir)/stub.h \
|
$(srcdir)/debug.h $(srcdir)/stub.h \
|
||||||
|
@ -400,8 +448,8 @@ stub.lo stub.o: $(srcdir)/stub.c \
|
||||||
$(srcdir)/rr-dict.h $(srcdir)/context.h $(srcdir)/extension/default_eventloop.h \
|
$(srcdir)/rr-dict.h $(srcdir)/context.h $(srcdir)/extension/default_eventloop.h \
|
||||||
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h \
|
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h \
|
||||||
$(srcdir)/util/lruhash.h $(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h \
|
$(srcdir)/util/lruhash.h $(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h \
|
||||||
$(srcdir)/util/orig-headers/locks.h $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h \
|
$(srcdir)/util/orig-headers/locks.h $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/anchor.h \
|
||||||
$(srcdir)/util-internal.h $(srcdir)/general.h $(srcdir)/pubkey-pinning.h
|
$(srcdir)/util-internal.h $(srcdir)/platform.h $(srcdir)/general.h $(srcdir)/pubkey-pinning.h
|
||||||
sync.lo sync.o: $(srcdir)/sync.c \
|
sync.lo sync.o: $(srcdir)/sync.c \
|
||||||
getdns/getdns.h \
|
getdns/getdns.h \
|
||||||
config.h \
|
config.h \
|
||||||
|
@ -411,9 +459,9 @@ sync.lo sync.o: $(srcdir)/sync.c \
|
||||||
$(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \
|
$(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \
|
||||||
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
|
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
|
||||||
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
|
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
|
||||||
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/general.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h \
|
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \
|
||||||
$(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/stub.h \
|
$(srcdir)/gldns/pkthdr.h $(srcdir)/anchor.h $(srcdir)/general.h $(srcdir)/util-internal.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h \
|
||||||
$(srcdir)/gldns/wire2str.h
|
$(srcdir)/stub.h $(srcdir)/gldns/wire2str.h
|
||||||
ub_loop.lo ub_loop.o: $(srcdir)/ub_loop.c $(srcdir)/ub_loop.h \
|
ub_loop.lo ub_loop.o: $(srcdir)/ub_loop.c $(srcdir)/ub_loop.h \
|
||||||
config.h \
|
config.h \
|
||||||
getdns/getdns.h \
|
getdns/getdns.h \
|
||||||
|
@ -428,8 +476,8 @@ util-internal.lo util-internal.o: $(srcdir)/util-internal.c \
|
||||||
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h \
|
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h \
|
||||||
$(srcdir)/util/lruhash.h $(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h \
|
$(srcdir)/util/lruhash.h $(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h \
|
||||||
$(srcdir)/util/orig-headers/locks.h $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/rr-iter.h \
|
$(srcdir)/util/orig-headers/locks.h $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/rr-iter.h \
|
||||||
$(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h \
|
$(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/anchor.h $(srcdir)/gldns/str2wire.h \
|
||||||
$(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h
|
$(srcdir)/gldns/rrdef.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h
|
||||||
gbuffer.lo gbuffer.o: $(srcdir)/gldns/gbuffer.c \
|
gbuffer.lo gbuffer.o: $(srcdir)/gldns/gbuffer.c \
|
||||||
config.h \
|
config.h \
|
||||||
$(srcdir)/gldns/gbuffer.h
|
$(srcdir)/gldns/gbuffer.h
|
||||||
|
@ -479,6 +527,8 @@ sha512.lo sha512.o: $(srcdir)/compat/sha512.c \
|
||||||
config.h
|
config.h
|
||||||
strlcpy.lo strlcpy.o: $(srcdir)/compat/strlcpy.c \
|
strlcpy.lo strlcpy.o: $(srcdir)/compat/strlcpy.c \
|
||||||
config.h
|
config.h
|
||||||
|
strptime.lo strptime.o: $(srcdir)/compat/strptime.c \
|
||||||
|
config.h
|
||||||
locks.lo locks.o: $(srcdir)/util/locks.c \
|
locks.lo locks.o: $(srcdir)/util/locks.c \
|
||||||
config.h \
|
config.h \
|
||||||
$(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h
|
$(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h
|
||||||
|
@ -505,6 +555,7 @@ val_secalgo.lo val_secalgo.o: $(srcdir)/util/val_secalgo.c \
|
||||||
$(srcdir)/gldns/rrdef.h $(srcdir)/util/auxiliary/sldns/keyraw.h $(srcdir)/gldns/keyraw.h \
|
$(srcdir)/gldns/rrdef.h $(srcdir)/util/auxiliary/sldns/keyraw.h $(srcdir)/gldns/keyraw.h \
|
||||||
$(srcdir)/util/auxiliary/sldns/sbuffer.h $(srcdir)/gldns/gbuffer.h
|
$(srcdir)/util/auxiliary/sldns/sbuffer.h $(srcdir)/gldns/gbuffer.h
|
||||||
jsmn.lo jsmn.o: $(srcdir)/jsmn/jsmn.c $(srcdir)/jsmn/jsmn.h
|
jsmn.lo jsmn.o: $(srcdir)/jsmn/jsmn.c $(srcdir)/jsmn/jsmn.h
|
||||||
|
yxml.lo yxml.o: $(srcdir)/yxml/yxml.c $(srcdir)/yxml/yxml.h
|
||||||
libev.lo libev.o: $(srcdir)/extension/libev.c \
|
libev.lo libev.o: $(srcdir)/extension/libev.c \
|
||||||
config.h \
|
config.h \
|
||||||
$(srcdir)/types-internal.h \
|
$(srcdir)/types-internal.h \
|
||||||
|
@ -525,13 +576,24 @@ libuv.lo libuv.o: $(srcdir)/extension/libuv.c \
|
||||||
$(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/getdns/getdns_ext_libuv.h
|
$(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/getdns/getdns_ext_libuv.h
|
||||||
poll_eventloop.lo poll_eventloop.o: $(srcdir)/extension/poll_eventloop.c \
|
poll_eventloop.lo poll_eventloop.o: $(srcdir)/extension/poll_eventloop.c \
|
||||||
config.h \
|
config.h \
|
||||||
$(srcdir)/extension/poll_eventloop.h \
|
$(srcdir)/util-internal.h $(srcdir)/context.h \
|
||||||
getdns/getdns.h \
|
getdns/getdns.h \
|
||||||
getdns/getdns_extra.h \
|
getdns/getdns_extra.h \
|
||||||
$(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/debug.h
|
$(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h \
|
||||||
|
$(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \
|
||||||
|
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
|
||||||
|
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
|
||||||
|
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \
|
||||||
|
$(srcdir)/gldns/pkthdr.h $(srcdir)/anchor.h $(srcdir)/platform.h
|
||||||
select_eventloop.lo select_eventloop.o: $(srcdir)/extension/select_eventloop.c \
|
select_eventloop.lo select_eventloop.o: $(srcdir)/extension/select_eventloop.c \
|
||||||
config.h \
|
config.h \
|
||||||
$(srcdir)/extension/select_eventloop.h \
|
$(srcdir)/debug.h $(srcdir)/types-internal.h \
|
||||||
getdns/getdns.h \
|
getdns/getdns.h \
|
||||||
getdns/getdns_extra.h \
|
getdns/getdns_extra.h \
|
||||||
$(srcdir)/debug.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h
|
$(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/platform.h \
|
||||||
|
$(srcdir)/extension/select_eventloop.h
|
||||||
|
stubby.lo stubby.o: $(stubbysrcdir)/src/stubby.c \
|
||||||
|
config.h \
|
||||||
|
getdns/getdns.h \
|
||||||
|
getdns/getdns_extra.h \
|
||||||
|
$(stubbysrcdir)/src/yaml/convert_yaml_to_json.h
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,59 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* /brief functions for DNSSEC trust anchor management
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2017, NLnet Labs
|
||||||
|
* 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 names of the copyright holders 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 Verisign, Inc. 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 ANCHOR_H_
|
||||||
|
#define ANCHOR_H_
|
||||||
|
|
||||||
|
#include "getdns/getdns.h"
|
||||||
|
#include "getdns/getdns_extra.h"
|
||||||
|
#include <time.h>
|
||||||
|
#include "rr-iter.h"
|
||||||
|
|
||||||
|
void _getdns_context_equip_with_anchor(getdns_context *context, uint64_t *now_ms);
|
||||||
|
|
||||||
|
void _getdns_start_fetching_ta(getdns_context *context, getdns_eventloop *loop);
|
||||||
|
|
||||||
|
#define MAX_KSKS 16
|
||||||
|
#define RRSIG_RDATA_LEN 16
|
||||||
|
typedef struct _getdns_ksks {
|
||||||
|
size_t n;
|
||||||
|
uint16_t ids[MAX_KSKS];
|
||||||
|
size_t n_rrsigs;
|
||||||
|
uint8_t rrsigs[MAX_KSKS][RRSIG_RDATA_LEN];
|
||||||
|
} _getdns_ksks;
|
||||||
|
|
||||||
|
void _getdns_context_update_root_ksk(
|
||||||
|
getdns_context *context, _getdns_rrset *dnskey_set);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
/* anchor.h */
|
|
@ -0,0 +1,345 @@
|
||||||
|
/** strptime workaround (for oa macos leopard)
|
||||||
|
* This strptime follows the man strptime (2001-11-12)
|
||||||
|
* conforming to SUSv2, POSIX.1-2001
|
||||||
|
*
|
||||||
|
* This very simple version of strptime has no:
|
||||||
|
* - E alternatives
|
||||||
|
* - O alternatives
|
||||||
|
* - Glibc additions
|
||||||
|
* - Does not process week numbers
|
||||||
|
* - Does not properly processes year day
|
||||||
|
*
|
||||||
|
* LICENSE
|
||||||
|
* Copyright (c) 2008, NLnet Labs, Matthijs Mekking
|
||||||
|
* 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 NLnetLabs 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.
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#ifndef HAVE_CONFIG_H
|
||||||
|
#include <time.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef STRPTIME_WORKS
|
||||||
|
|
||||||
|
#define TM_YEAR_BASE 1900
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static const char *abb_weekdays[] = {
|
||||||
|
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", NULL
|
||||||
|
};
|
||||||
|
static const char *full_weekdays[] = {
|
||||||
|
"Sunday", "Monday", "Tuesday", "Wednesday",
|
||||||
|
"Thursday", "Friday", "Saturday", NULL
|
||||||
|
};
|
||||||
|
static const char *abb_months[] = {
|
||||||
|
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||||
|
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL
|
||||||
|
};
|
||||||
|
static const char *full_months[] = {
|
||||||
|
"January", "February", "March", "April", "May", "June",
|
||||||
|
"July", "August", "September", "October", "November", "December", NULL
|
||||||
|
};
|
||||||
|
static const char *ampm[] = {
|
||||||
|
"am", "pm", NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
match_string(const char **buf, const char **strs)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
for (i = 0; strs[i] != NULL; i++) {
|
||||||
|
int len = strlen(strs[i]);
|
||||||
|
if (strncasecmp (*buf, strs[i], len) == 0) {
|
||||||
|
*buf += len;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
str2int(const char **buf, int max)
|
||||||
|
{
|
||||||
|
int ret=0, count=0;
|
||||||
|
|
||||||
|
while (*buf[0] != '\0' && isdigit((unsigned char)*buf[0]) && count<max) {
|
||||||
|
ret = ret*10 + (*buf[0] - '0');
|
||||||
|
(*buf)++;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!count)
|
||||||
|
return -1;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Converts the character string s to values which are stored in tm
|
||||||
|
* using the format specified by format
|
||||||
|
**/
|
||||||
|
char *
|
||||||
|
unbound_strptime(const char *s, const char *format, struct tm *tm)
|
||||||
|
{
|
||||||
|
int c, ret;
|
||||||
|
int split_year = 0;
|
||||||
|
|
||||||
|
while ((c = *format) != '\0') {
|
||||||
|
/* whitespace, literal or format */
|
||||||
|
if (isspace((unsigned char)c)) { /* whitespace */
|
||||||
|
/** whitespace matches zero or more whitespace characters in the
|
||||||
|
* input string.
|
||||||
|
**/
|
||||||
|
while (isspace((unsigned char)*s))
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
else if (c == '%') { /* format */
|
||||||
|
format++;
|
||||||
|
c = *format;
|
||||||
|
switch (c) {
|
||||||
|
case '%': /* %% is converted to % */
|
||||||
|
if (*s != c) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
s++;
|
||||||
|
break;
|
||||||
|
case 'a': /* weekday name, abbreviated or full */
|
||||||
|
case 'A':
|
||||||
|
ret = match_string(&s, full_weekdays);
|
||||||
|
if (ret < 0)
|
||||||
|
ret = match_string(&s, abb_weekdays);
|
||||||
|
if (ret < 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
tm->tm_wday = ret;
|
||||||
|
break;
|
||||||
|
case 'b': /* month name, abbreviated or full */
|
||||||
|
case 'B':
|
||||||
|
case 'h':
|
||||||
|
ret = match_string(&s, full_months);
|
||||||
|
if (ret < 0)
|
||||||
|
ret = match_string(&s, abb_months);
|
||||||
|
if (ret < 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
tm->tm_mon = ret;
|
||||||
|
break;
|
||||||
|
case 'c': /* date and time representation */
|
||||||
|
if (!(s = unbound_strptime(s, "%x %X", tm))) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'C': /* century number */
|
||||||
|
ret = str2int(&s, 2);
|
||||||
|
if (ret < 0 || ret > 99) { /* must be in [00,99] */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (split_year) {
|
||||||
|
tm->tm_year = ret*100 + (tm->tm_year%100);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tm->tm_year = ret*100 - TM_YEAR_BASE;
|
||||||
|
split_year = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'd': /* day of month */
|
||||||
|
case 'e':
|
||||||
|
ret = str2int(&s, 2);
|
||||||
|
if (ret < 1 || ret > 31) { /* must be in [01,31] */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
tm->tm_mday = ret;
|
||||||
|
break;
|
||||||
|
case 'D': /* equivalent to %m/%d/%y */
|
||||||
|
if (!(s = unbound_strptime(s, "%m/%d/%y", tm))) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'H': /* hour */
|
||||||
|
ret = str2int(&s, 2);
|
||||||
|
if (ret < 0 || ret > 23) { /* must be in [00,23] */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
tm->tm_hour = ret;
|
||||||
|
break;
|
||||||
|
case 'I': /* 12hr clock hour */
|
||||||
|
ret = str2int(&s, 2);
|
||||||
|
if (ret < 1 || ret > 12) { /* must be in [01,12] */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (ret == 12) /* actually [0,11] */
|
||||||
|
ret = 0;
|
||||||
|
tm->tm_hour = ret;
|
||||||
|
break;
|
||||||
|
case 'j': /* day of year */
|
||||||
|
ret = str2int(&s, 2);
|
||||||
|
if (ret < 1 || ret > 366) { /* must be in [001,366] */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
tm->tm_yday = ret;
|
||||||
|
break;
|
||||||
|
case 'm': /* month */
|
||||||
|
ret = str2int(&s, 2);
|
||||||
|
if (ret < 1 || ret > 12) { /* must be in [01,12] */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
/* months go from 0-11 */
|
||||||
|
tm->tm_mon = (ret-1);
|
||||||
|
break;
|
||||||
|
case 'M': /* minute */
|
||||||
|
ret = str2int(&s, 2);
|
||||||
|
if (ret < 0 || ret > 59) { /* must be in [00,59] */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
tm->tm_min = ret;
|
||||||
|
break;
|
||||||
|
case 'n': /* arbitrary whitespace */
|
||||||
|
case 't':
|
||||||
|
while (isspace((unsigned char)*s))
|
||||||
|
s++;
|
||||||
|
break;
|
||||||
|
case 'p': /* am pm */
|
||||||
|
ret = match_string(&s, ampm);
|
||||||
|
if (ret < 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (tm->tm_hour < 0 || tm->tm_hour > 11) { /* %I */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret == 1) /* pm */
|
||||||
|
tm->tm_hour += 12;
|
||||||
|
break;
|
||||||
|
case 'r': /* equivalent of %I:%M:%S %p */
|
||||||
|
if (!(s = unbound_strptime(s, "%I:%M:%S %p", tm))) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'R': /* equivalent of %H:%M */
|
||||||
|
if (!(s = unbound_strptime(s, "%H:%M", tm))) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'S': /* seconds */
|
||||||
|
ret = str2int(&s, 2);
|
||||||
|
/* 60 may occur for leap seconds */
|
||||||
|
/* earlier 61 was also allowed */
|
||||||
|
if (ret < 0 || ret > 60) { /* must be in [00,60] */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
tm->tm_sec = ret;
|
||||||
|
break;
|
||||||
|
case 'T': /* equivalent of %H:%M:%S */
|
||||||
|
if (!(s = unbound_strptime(s, "%H:%M:%S", tm))) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'U': /* week number, with the first Sun of Jan being w1 */
|
||||||
|
ret = str2int(&s, 2);
|
||||||
|
if (ret < 0 || ret > 53) { /* must be in [00,53] */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
/** it is hard (and not necessary for nsd) to determine time
|
||||||
|
* data from week number.
|
||||||
|
**/
|
||||||
|
break;
|
||||||
|
case 'w': /* day of week */
|
||||||
|
ret = str2int(&s, 1);
|
||||||
|
if (ret < 0 || ret > 6) { /* must be in [0,6] */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
tm->tm_wday = ret;
|
||||||
|
break;
|
||||||
|
case 'W': /* week number, with the first Mon of Jan being w1 */
|
||||||
|
ret = str2int(&s, 2);
|
||||||
|
if (ret < 0 || ret > 53) { /* must be in [00,53] */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
/** it is hard (and not necessary for nsd) to determine time
|
||||||
|
* data from week number.
|
||||||
|
**/
|
||||||
|
break;
|
||||||
|
case 'x': /* date format */
|
||||||
|
if (!(s = unbound_strptime(s, "%m/%d/%y", tm))) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'X': /* time format */
|
||||||
|
if (!(s = unbound_strptime(s, "%H:%M:%S", tm))) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'y': /* last two digits of a year */
|
||||||
|
ret = str2int(&s, 2);
|
||||||
|
if (ret < 0 || ret > 99) { /* must be in [00,99] */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (split_year) {
|
||||||
|
tm->tm_year = ((tm->tm_year/100) * 100) + ret;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
split_year = 1;
|
||||||
|
|
||||||
|
/** currently:
|
||||||
|
* if in [0,68] we are in 21th century,
|
||||||
|
* if in [69,99] we are in 20th century.
|
||||||
|
**/
|
||||||
|
if (ret < 69) /* 2000 */
|
||||||
|
ret += 100;
|
||||||
|
tm->tm_year = ret;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'Y': /* year */
|
||||||
|
ret = str2int(&s, 4);
|
||||||
|
if (ret < 0 || ret > 9999) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
tm->tm_year = ret - TM_YEAR_BASE;
|
||||||
|
break;
|
||||||
|
case '\0':
|
||||||
|
default: /* unsupported, cannot match format */
|
||||||
|
return NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else { /* literal */
|
||||||
|
/* if input cannot match format, return NULL */
|
||||||
|
if (*s != c)
|
||||||
|
return NULL;
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
|
||||||
|
format++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return pointer to remainder of s */
|
||||||
|
return (char*) s;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* STRPTIME_WORKS */
|
|
@ -82,6 +82,10 @@ static struct const_info consts_info[] = {
|
||||||
{ 622, "GETDNS_CONTEXT_CODE_ROUND_ROBIN_UPSTREAMS", GETDNS_CONTEXT_CODE_ROUND_ROBIN_UPSTREAMS_TEXT },
|
{ 622, "GETDNS_CONTEXT_CODE_ROUND_ROBIN_UPSTREAMS", GETDNS_CONTEXT_CODE_ROUND_ROBIN_UPSTREAMS_TEXT },
|
||||||
{ 623, "GETDNS_CONTEXT_CODE_TLS_BACKOFF_TIME", GETDNS_CONTEXT_CODE_TLS_BACKOFF_TIME_TEXT },
|
{ 623, "GETDNS_CONTEXT_CODE_TLS_BACKOFF_TIME", GETDNS_CONTEXT_CODE_TLS_BACKOFF_TIME_TEXT },
|
||||||
{ 624, "GETDNS_CONTEXT_CODE_TLS_CONNECTION_RETRIES", GETDNS_CONTEXT_CODE_TLS_CONNECTION_RETRIES_TEXT },
|
{ 624, "GETDNS_CONTEXT_CODE_TLS_CONNECTION_RETRIES", GETDNS_CONTEXT_CODE_TLS_CONNECTION_RETRIES_TEXT },
|
||||||
|
{ 625, "GETDNS_CONTEXT_CODE_TRUST_ANCHORS_URL", GETDNS_CONTEXT_CODE_TRUST_ANCHORS_URL_TEXT },
|
||||||
|
{ 626, "GETDNS_CONTEXT_CODE_TRUST_ANCHORS_VERIFY_CA", GETDNS_CONTEXT_CODE_TRUST_ANCHORS_VERIFY_CA_TEXT },
|
||||||
|
{ 627, "GETDNS_CONTEXT_CODE_TRUST_ANCHORS_VERIFY_EMAIL", GETDNS_CONTEXT_CODE_TRUST_ANCHORS_VERIFY_EMAIL_TEXT },
|
||||||
|
{ 628, "GETDNS_CONTEXT_CODE_APPDATA_DIR", GETDNS_CONTEXT_CODE_APPDATA_DIR_TEXT },
|
||||||
{ 700, "GETDNS_CALLBACK_COMPLETE", GETDNS_CALLBACK_COMPLETE_TEXT },
|
{ 700, "GETDNS_CALLBACK_COMPLETE", GETDNS_CALLBACK_COMPLETE_TEXT },
|
||||||
{ 701, "GETDNS_CALLBACK_CANCEL", GETDNS_CALLBACK_CANCEL_TEXT },
|
{ 701, "GETDNS_CALLBACK_CANCEL", GETDNS_CALLBACK_CANCEL_TEXT },
|
||||||
{ 702, "GETDNS_CALLBACK_TIMEOUT", GETDNS_CALLBACK_TIMEOUT_TEXT },
|
{ 702, "GETDNS_CALLBACK_TIMEOUT", GETDNS_CALLBACK_TIMEOUT_TEXT },
|
||||||
|
@ -150,6 +154,7 @@ static struct const_name_info consts_name_info[] = {
|
||||||
{ "GETDNS_CALLBACK_COMPLETE", 700 },
|
{ "GETDNS_CALLBACK_COMPLETE", 700 },
|
||||||
{ "GETDNS_CALLBACK_ERROR", 703 },
|
{ "GETDNS_CALLBACK_ERROR", 703 },
|
||||||
{ "GETDNS_CALLBACK_TIMEOUT", 702 },
|
{ "GETDNS_CALLBACK_TIMEOUT", 702 },
|
||||||
|
{ "GETDNS_CONTEXT_CODE_APPDATA_DIR", 628 },
|
||||||
{ "GETDNS_CONTEXT_CODE_APPEND_NAME", 607 },
|
{ "GETDNS_CONTEXT_CODE_APPEND_NAME", 607 },
|
||||||
{ "GETDNS_CONTEXT_CODE_DNSSEC_ALLOWED_SKEW", 614 },
|
{ "GETDNS_CONTEXT_CODE_DNSSEC_ALLOWED_SKEW", 614 },
|
||||||
{ "GETDNS_CONTEXT_CODE_DNSSEC_TRUST_ANCHORS", 609 },
|
{ "GETDNS_CONTEXT_CODE_DNSSEC_TRUST_ANCHORS", 609 },
|
||||||
|
@ -174,6 +179,9 @@ static struct const_name_info consts_name_info[] = {
|
||||||
{ "GETDNS_CONTEXT_CODE_TLS_BACKOFF_TIME", 623 },
|
{ "GETDNS_CONTEXT_CODE_TLS_BACKOFF_TIME", 623 },
|
||||||
{ "GETDNS_CONTEXT_CODE_TLS_CONNECTION_RETRIES", 624 },
|
{ "GETDNS_CONTEXT_CODE_TLS_CONNECTION_RETRIES", 624 },
|
||||||
{ "GETDNS_CONTEXT_CODE_TLS_QUERY_PADDING_BLOCKSIZE", 620 },
|
{ "GETDNS_CONTEXT_CODE_TLS_QUERY_PADDING_BLOCKSIZE", 620 },
|
||||||
|
{ "GETDNS_CONTEXT_CODE_TRUST_ANCHORS_URL", 625 },
|
||||||
|
{ "GETDNS_CONTEXT_CODE_TRUST_ANCHORS_VERIFY_CA", 626 },
|
||||||
|
{ "GETDNS_CONTEXT_CODE_TRUST_ANCHORS_VERIFY_EMAIL", 627 },
|
||||||
{ "GETDNS_CONTEXT_CODE_UPSTREAM_RECURSIVE_SERVERS", 603 },
|
{ "GETDNS_CONTEXT_CODE_UPSTREAM_RECURSIVE_SERVERS", 603 },
|
||||||
{ "GETDNS_DNSSEC_BOGUS", 401 },
|
{ "GETDNS_DNSSEC_BOGUS", 401 },
|
||||||
{ "GETDNS_DNSSEC_INDETERMINATE", 402 },
|
{ "GETDNS_DNSSEC_INDETERMINATE", 402 },
|
||||||
|
|
710
src/context.c
710
src/context.c
|
@ -35,11 +35,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "anchor.h"
|
||||||
|
|
||||||
#ifndef USE_WINSOCK
|
#ifndef USE_WINSOCK
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
#include <pwd.h>
|
||||||
#else
|
#else
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#include <iphlpapi.h>
|
#include <iphlpapi.h>
|
||||||
|
@ -52,6 +54,7 @@ typedef unsigned short in_port_t;
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <wincrypt.h>
|
#include <wincrypt.h>
|
||||||
|
#include <shlobj.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
@ -68,7 +71,6 @@ typedef unsigned short in_port_t;
|
||||||
#endif
|
#endif
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
#ifdef HAVE_LIBUNBOUND
|
#ifdef HAVE_LIBUNBOUND
|
||||||
#include <unbound.h>
|
#include <unbound.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -78,6 +80,7 @@ typedef unsigned short in_port_t;
|
||||||
#include "context.h"
|
#include "context.h"
|
||||||
#include "types-internal.h"
|
#include "types-internal.h"
|
||||||
#include "util-internal.h"
|
#include "util-internal.h"
|
||||||
|
#include "platform.h"
|
||||||
#include "dnssec.h"
|
#include "dnssec.h"
|
||||||
#include "stub.h"
|
#include "stub.h"
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
|
@ -702,11 +705,7 @@ _getdns_upstreams_dereference(getdns_upstreams *upstreams)
|
||||||
}
|
}
|
||||||
if (upstream->fd != -1)
|
if (upstream->fd != -1)
|
||||||
{
|
{
|
||||||
#ifdef USE_WINSOCK
|
_getdns_closesocket(upstream->fd);
|
||||||
closesocket(upstream->fd);
|
|
||||||
#else
|
|
||||||
close(upstream->fd);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
while (pin) {
|
while (pin) {
|
||||||
sha256_pin_t *nextpin = pin->next;
|
sha256_pin_t *nextpin = pin->next;
|
||||||
|
@ -734,65 +733,65 @@ void _getdns_upstream_log(getdns_upstream *upstream, uint64_t system,
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
_getdns_upstream_shutdown(getdns_upstream *upstream)
|
upstream_backoff(getdns_upstream *upstream) {
|
||||||
{
|
upstream->conn_state = GETDNS_CONN_BACKOFF;
|
||||||
/*Set condition to tear down asap to stop any further scheduling*/
|
/* Increase the backoff interval incrementally up to the tls_backoff_time*/
|
||||||
upstream->conn_state = GETDNS_CONN_TEARDOWN;
|
if (upstream->conn_backoff_interval < upstream->upstreams->tls_backoff_time) {
|
||||||
/* Update total stats for the upstream.*/
|
if (upstream->conn_backoff_interval < (UINT16_MAX-1)/2)
|
||||||
upstream->total_responses+=upstream->responses_received;
|
upstream->conn_backoff_interval *= 2;
|
||||||
upstream->total_timeouts+=upstream->responses_timeouts;
|
else
|
||||||
/* Need the last auth state when using session resumption*/
|
upstream->conn_backoff_interval = upstream->upstreams->tls_backoff_time;
|
||||||
upstream->last_tls_auth_state = upstream->tls_auth_state;
|
}
|
||||||
/* Keep track of the best auth state this upstream has had*/
|
if (upstream->conn_backoff_interval < upstream->upstreams->tls_backoff_time)
|
||||||
if (upstream->tls_auth_state > upstream->best_tls_auth_state)
|
upstream->conn_retry_time = time(NULL) + upstream->conn_backoff_interval;
|
||||||
upstream->best_tls_auth_state = upstream->tls_auth_state;
|
else
|
||||||
_getdns_upstream_log(upstream, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_DEBUG,
|
upstream->conn_retry_time = time(NULL) + upstream->upstreams->tls_backoff_time;
|
||||||
"%-40s : Conn closed : Transport=%s - Resp=%d,Timeouts=%d,Auth=%s,Keepalive(ms)=%d\n",
|
upstream->total_responses = 0;
|
||||||
upstream->addr_str,
|
upstream->total_timeouts = 0;
|
||||||
(upstream->transport == GETDNS_TRANSPORT_TLS ? "TLS" : "TCP"),
|
upstream->conn_completed = 0;
|
||||||
(int)upstream->responses_received, (int)upstream->responses_timeouts,
|
upstream->conn_setup_failed = 0;
|
||||||
_getdns_auth_str(upstream->tls_auth_state), (int)upstream->keepalive_timeout);
|
upstream->conn_shutdowns = 0;
|
||||||
_getdns_upstream_log(upstream, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_DEBUG,
|
upstream->conn_backoffs++;
|
||||||
"%-40s : Upstream stats: Transport=%s - Resp=%d,Timeouts=%d,Best_auth=%s\n",
|
_getdns_upstream_log(upstream, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_NOTICE,
|
||||||
upstream->addr_str,
|
"%-40s : !Backing off this upstream - Will retry again in %ds at %s",
|
||||||
(upstream->transport == GETDNS_TRANSPORT_TLS ? "TLS" : "TCP"),
|
upstream->addr_str,
|
||||||
(int)upstream->total_responses, (int)upstream->total_timeouts,
|
upstream->conn_backoff_interval,
|
||||||
_getdns_auth_str(upstream->best_tls_auth_state));
|
asctime(gmtime(&upstream->conn_retry_time)));
|
||||||
_getdns_upstream_log(upstream, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_DEBUG,
|
}
|
||||||
"%-40s : Upstream stats: Transport=%s - Conns=%d,Conn_fails=%d,Conn_shutdowns=%d,Backoffs=%d\n",
|
|
||||||
upstream->addr_str,
|
|
||||||
(upstream->transport == GETDNS_TRANSPORT_TLS ? "TLS" : "TCP"),
|
|
||||||
(int)upstream->conn_completed, (int)upstream->conn_setup_failed,
|
|
||||||
(int)upstream->conn_shutdowns, (int)upstream->conn_backoffs);
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
_getdns_upstream_reset(getdns_upstream *upstream)
|
||||||
|
{
|
||||||
/* Back off connections that never got up service at all (probably no
|
/* Back off connections that never got up service at all (probably no
|
||||||
TCP service or incompatible TLS version/cipher).
|
TCP service or incompatible TLS version/cipher).
|
||||||
Leave choice between working upstreams to the stub.
|
Leave choice between working upstreams to the stub.
|
||||||
This back-off should be time based for TLS according to RFC7858. For now,
|
This back-off should be time based for TLS according to RFC7858. For now,
|
||||||
use the same basis if we simply can't get TCP service either.*/
|
use the same basis if we simply can't get TCP service either.*/
|
||||||
uint16_t conn_retries = upstream->upstreams->tls_connection_retries;
|
|
||||||
/* [TLS1]TODO: This arbitrary logic at the moment - review and improve!*/
|
/* [TLS1]TODO: This arbitrary logic at the moment - review and improve!*/
|
||||||
|
|
||||||
|
/*This is the configured number of retries to attempt*/
|
||||||
|
uint16_t conn_retries = upstream->upstreams->tls_connection_retries;
|
||||||
|
|
||||||
if (upstream->conn_setup_failed >= conn_retries
|
if (upstream->conn_setup_failed >= conn_retries
|
||||||
|
|
||||||
|| ((int)upstream->conn_shutdowns >= conn_retries*GETDNS_TRANSPORT_FAIL_MULT
|
|| ((int)upstream->conn_shutdowns >= conn_retries*GETDNS_TRANSPORT_FAIL_MULT
|
||||||
&& upstream->total_responses == 0)
|
&& upstream->total_responses == 0)
|
||||||
|
|
||||||
|| (upstream->conn_completed >= conn_retries &&
|
|| (upstream->conn_completed >= conn_retries &&
|
||||||
upstream->total_responses == 0 &&
|
upstream->total_responses == 0 &&
|
||||||
upstream->total_timeouts > GETDNS_TRANSPORT_FAIL_MULT)) {
|
upstream->total_timeouts > GETDNS_TRANSPORT_FAIL_MULT)) {
|
||||||
upstream->conn_state = GETDNS_CONN_BACKOFF;
|
|
||||||
upstream->conn_retry_time = time(NULL) + upstream->upstreams->tls_backoff_time;
|
|
||||||
upstream->total_responses = 0;
|
|
||||||
upstream->total_timeouts = 0;
|
|
||||||
upstream->conn_completed = 0;
|
|
||||||
upstream->conn_setup_failed = 0;
|
|
||||||
upstream->conn_shutdowns = 0;
|
|
||||||
upstream->conn_backoffs++;
|
|
||||||
|
|
||||||
_getdns_upstream_log(upstream, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_DEBUG,
|
upstream_backoff(upstream);
|
||||||
"%-40s : !Backing off this upstream - Will retry as new upstream at %s",
|
|
||||||
upstream->addr_str,
|
|
||||||
asctime(gmtime(&upstream->conn_retry_time)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If we didn't backoff it would be nice to reset the conn_backoff_interval
|
||||||
|
if the upstream is working well again otherwise it would get stuck at the
|
||||||
|
tls_backoff_time forever... How about */
|
||||||
|
if (upstream->conn_state != GETDNS_CONN_BACKOFF &&
|
||||||
|
upstream->responses_received > 1)
|
||||||
|
upstream->conn_backoff_interval = 1;
|
||||||
|
|
||||||
// Reset per connection counters
|
// Reset per connection counters
|
||||||
upstream->queries_sent = 0;
|
upstream->queries_sent = 0;
|
||||||
upstream->responses_received = 0;
|
upstream->responses_received = 0;
|
||||||
|
@ -802,17 +801,17 @@ _getdns_upstream_shutdown(getdns_upstream *upstream)
|
||||||
|
|
||||||
/* Now TLS stuff*/
|
/* Now TLS stuff*/
|
||||||
upstream->tls_auth_state = GETDNS_AUTH_NONE;
|
upstream->tls_auth_state = GETDNS_AUTH_NONE;
|
||||||
|
if (upstream->event.ev && upstream->loop) {
|
||||||
|
upstream->loop->vmt->clear(
|
||||||
|
upstream->loop, &upstream->event);
|
||||||
|
}
|
||||||
if (upstream->tls_obj != NULL) {
|
if (upstream->tls_obj != NULL) {
|
||||||
SSL_shutdown(upstream->tls_obj);
|
SSL_shutdown(upstream->tls_obj);
|
||||||
SSL_free(upstream->tls_obj);
|
SSL_free(upstream->tls_obj);
|
||||||
upstream->tls_obj = NULL;
|
upstream->tls_obj = NULL;
|
||||||
}
|
}
|
||||||
if (upstream->fd != -1) {
|
if (upstream->fd != -1) {
|
||||||
#ifdef USE_WINSOCK
|
_getdns_closesocket(upstream->fd);
|
||||||
closesocket(upstream->fd);
|
|
||||||
#else
|
|
||||||
close(upstream->fd);
|
|
||||||
#endif
|
|
||||||
upstream->fd = -1;
|
upstream->fd = -1;
|
||||||
}
|
}
|
||||||
/* Set connection ready for use again*/
|
/* Set connection ready for use again*/
|
||||||
|
@ -820,6 +819,39 @@ _getdns_upstream_shutdown(getdns_upstream *upstream)
|
||||||
upstream->conn_state = GETDNS_CONN_CLOSED;
|
upstream->conn_state = GETDNS_CONN_CLOSED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_getdns_upstream_shutdown(getdns_upstream *upstream)
|
||||||
|
{
|
||||||
|
/* Update total stats for the upstream.*/
|
||||||
|
upstream->total_responses+=upstream->responses_received;
|
||||||
|
upstream->total_timeouts+=upstream->responses_timeouts;
|
||||||
|
/* Need the last auth state when using session resumption*/
|
||||||
|
upstream->last_tls_auth_state = upstream->tls_auth_state;
|
||||||
|
/* Keep track of the best auth state this upstream has had*/
|
||||||
|
if (upstream->tls_auth_state > upstream->best_tls_auth_state)
|
||||||
|
upstream->best_tls_auth_state = upstream->tls_auth_state;
|
||||||
|
_getdns_upstream_log(upstream, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_DEBUG,
|
||||||
|
"%-40s : Conn closed: %s - Resps=%6d, Timeouts =%6d, Curr_auth =%7s, Keepalive(ms)=%6d\n",
|
||||||
|
upstream->addr_str,
|
||||||
|
(upstream->transport == GETDNS_TRANSPORT_TLS ? "TLS" : "TCP"),
|
||||||
|
(int)upstream->responses_received, (int)upstream->responses_timeouts,
|
||||||
|
_getdns_auth_str(upstream->tls_auth_state), (int)upstream->keepalive_timeout);
|
||||||
|
_getdns_upstream_log(upstream, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_INFO,
|
||||||
|
"%-40s : Upstream : %s - Resps=%6d, Timeouts =%6d, Best_auth =%7s\n",
|
||||||
|
upstream->addr_str,
|
||||||
|
(upstream->transport == GETDNS_TRANSPORT_TLS ? "TLS" : "TCP"),
|
||||||
|
(int)upstream->total_responses, (int)upstream->total_timeouts,
|
||||||
|
_getdns_auth_str(upstream->best_tls_auth_state));
|
||||||
|
_getdns_upstream_log(upstream, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_INFO,
|
||||||
|
"%-40s : Upstream : %s - Conns=%6d, Conn_fails=%6d, Conn_shuts=%7d, Backoffs =%6d\n",
|
||||||
|
upstream->addr_str,
|
||||||
|
(upstream->transport == GETDNS_TRANSPORT_TLS ? "TLS" : "TCP"),
|
||||||
|
(int)upstream->conn_completed, (int)upstream->conn_setup_failed,
|
||||||
|
(int)upstream->conn_shutdowns, (int)upstream->conn_backoffs);
|
||||||
|
|
||||||
|
_getdns_upstream_reset(upstream);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
tls_is_in_transports_list(getdns_context *context)
|
tls_is_in_transports_list(getdns_context *context)
|
||||||
{
|
{
|
||||||
|
@ -944,6 +976,7 @@ upstream_init(getdns_upstream *upstream,
|
||||||
upstream->conn_shutdowns = 0;
|
upstream->conn_shutdowns = 0;
|
||||||
upstream->conn_setup_failed = 0;
|
upstream->conn_setup_failed = 0;
|
||||||
upstream->conn_retry_time = 0;
|
upstream->conn_retry_time = 0;
|
||||||
|
upstream->conn_backoff_interval = 1;
|
||||||
upstream->conn_backoffs = 0;
|
upstream->conn_backoffs = 0;
|
||||||
upstream->total_responses = 0;
|
upstream->total_responses = 0;
|
||||||
upstream->total_timeouts = 0;
|
upstream->total_timeouts = 0;
|
||||||
|
@ -1329,6 +1362,37 @@ static void _getdns_check_expired_pending_netreqs_cb(void *arg)
|
||||||
_getdns_check_expired_pending_netreqs((getdns_context *)arg, &now_ms);
|
_getdns_check_expired_pending_netreqs((getdns_context *)arg, &now_ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char *_getdns_default_trust_anchors_url =
|
||||||
|
"http://data.iana.org/root-anchors/root-anchors.xml";
|
||||||
|
|
||||||
|
/* The ICANN CA fetched at 24 Sep 2010. Valid to 2028 */
|
||||||
|
static const char *_getdns_default_trust_anchors_verify_CA =
|
||||||
|
"-----BEGIN CERTIFICATE-----\n"
|
||||||
|
"MIIDdzCCAl+gAwIBAgIBATANBgkqhkiG9w0BAQsFADBdMQ4wDAYDVQQKEwVJQ0FO\n"
|
||||||
|
"TjEmMCQGA1UECxMdSUNBTk4gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxFjAUBgNV\n"
|
||||||
|
"BAMTDUlDQU5OIFJvb3QgQ0ExCzAJBgNVBAYTAlVTMB4XDTA5MTIyMzA0MTkxMloX\n"
|
||||||
|
"DTI5MTIxODA0MTkxMlowXTEOMAwGA1UEChMFSUNBTk4xJjAkBgNVBAsTHUlDQU5O\n"
|
||||||
|
"IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRYwFAYDVQQDEw1JQ0FOTiBSb290IENB\n"
|
||||||
|
"MQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKDb\n"
|
||||||
|
"cLhPNNqc1NB+u+oVvOnJESofYS9qub0/PXagmgr37pNublVThIzyLPGCJ8gPms9S\n"
|
||||||
|
"G1TaKNIsMI7d+5IgMy3WyPEOECGIcfqEIktdR1YWfJufXcMReZwU4v/AdKzdOdfg\n"
|
||||||
|
"ONiwc6r70duEr1IiqPbVm5T05l1e6D+HkAvHGnf1LtOPGs4CHQdpIUcy2kauAEy2\n"
|
||||||
|
"paKcOcHASvbTHK7TbbvHGPB+7faAztABLoneErruEcumetcNfPMIjXKdv1V1E3C7\n"
|
||||||
|
"MSJKy+jAqqQJqjZoQGB0necZgUMiUv7JK1IPQRM2CXJllcyJrm9WFxY0c1KjBO29\n"
|
||||||
|
"iIKK69fcglKcBuFShUECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B\n"
|
||||||
|
"Af8EBAMCAf4wHQYDVR0OBBYEFLpS6UmDJIZSL8eZzfyNa2kITcBQMA0GCSqGSIb3\n"
|
||||||
|
"DQEBCwUAA4IBAQAP8emCogqHny2UYFqywEuhLys7R9UKmYY4suzGO4nkbgfPFMfH\n"
|
||||||
|
"6M+Zj6owwxlwueZt1j/IaCayoKU3QsrYYoDRolpILh+FPwx7wseUEV8ZKpWsoDoD\n"
|
||||||
|
"2JFbLg2cfB8u/OlE4RYmcxxFSmXBg0yQ8/IoQt/bxOcEEhhiQ168H2yE5rxJMt9h\n"
|
||||||
|
"15nu5JBSewrCkYqYYmaxyOC3WrVGfHZxVI7MpIFcGdvSb2a1uyuua8l0BKgk3ujF\n"
|
||||||
|
"0/wsHNeP22qNyVO+XVBzrM8fk8BSUFuiT/6tZTYXRtEt5aKQZgXbKU5dUF3jT9qg\n"
|
||||||
|
"j/Br5BZw3X/zd325TvnswzMC1+ljLzHnQGGk\n"
|
||||||
|
"-----END CERTIFICATE-----\n";
|
||||||
|
|
||||||
|
static const char *_getdns_default_trust_anchors_verify_email =
|
||||||
|
"dnssec@iana.org";
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* getdns_context_create
|
* getdns_context_create
|
||||||
*
|
*
|
||||||
|
@ -1428,6 +1492,20 @@ getdns_context_create_with_extended_memory_functions(
|
||||||
result->suffixes = no_suffixes;
|
result->suffixes = no_suffixes;
|
||||||
result->suffixes_len = sizeof(no_suffixes);
|
result->suffixes_len = sizeof(no_suffixes);
|
||||||
|
|
||||||
|
result->trust_anchors_source = GETDNS_TASRC_NONE;
|
||||||
|
result->can_write_appdata = PROP_UNKNOWN;
|
||||||
|
result->trust_anchors_url = NULL;
|
||||||
|
result->trust_anchors_verify_email = NULL;
|
||||||
|
result->trust_anchors_verify_CA = NULL;
|
||||||
|
result->appdata_dir = NULL;
|
||||||
|
|
||||||
|
(void) memset(&result->root_ksk, 0, sizeof(result->root_ksk));
|
||||||
|
|
||||||
|
(void) memset(&result->a, 0, sizeof(result->a));
|
||||||
|
(void) memset(&result->aaaa, 0, sizeof(result->aaaa));
|
||||||
|
result->a.fd = -1;
|
||||||
|
result->aaaa.fd = -1;
|
||||||
|
|
||||||
gldns_buffer_init_vfixed_frm_data(&gbuf, result->trust_anchors_spc
|
gldns_buffer_init_vfixed_frm_data(&gbuf, result->trust_anchors_spc
|
||||||
, sizeof(result->trust_anchors_spc));
|
, sizeof(result->trust_anchors_spc));
|
||||||
|
|
||||||
|
@ -1445,12 +1523,16 @@ getdns_context_create_with_extended_memory_functions(
|
||||||
, result->trust_anchors
|
, result->trust_anchors
|
||||||
, result->trust_anchors_len);
|
, result->trust_anchors_len);
|
||||||
if (!_getdns_parse_ta_file(NULL, &gbuf)) {
|
if (!_getdns_parse_ta_file(NULL, &gbuf)) {
|
||||||
|
GETDNS_FREE(result->mf, result->trust_anchors);
|
||||||
result->trust_anchors = NULL;
|
result->trust_anchors = NULL;
|
||||||
result->trust_anchors_len = 0;
|
result->trust_anchors_len = 0;
|
||||||
}
|
} else
|
||||||
|
result->trust_anchors_source = GETDNS_TASRC_ZONE;
|
||||||
}
|
}
|
||||||
} else
|
} else {
|
||||||
result->trust_anchors = result->trust_anchors_spc;
|
result->trust_anchors = result->trust_anchors_spc;
|
||||||
|
result->trust_anchors_source = GETDNS_TASRC_ZONE;
|
||||||
|
}
|
||||||
|
|
||||||
result->upstreams = NULL;
|
result->upstreams = NULL;
|
||||||
|
|
||||||
|
@ -1484,6 +1566,9 @@ getdns_context_create_with_extended_memory_functions(
|
||||||
result->return_call_reporting = 0;
|
result->return_call_reporting = 0;
|
||||||
result->specify_class = GETDNS_RRCLASS_IN;
|
result->specify_class = GETDNS_RRCLASS_IN;
|
||||||
|
|
||||||
|
result->sys_ctxt = NULL;
|
||||||
|
result->ta_notify = NULL;
|
||||||
|
|
||||||
/* state data used to detect changes to the system config files
|
/* state data used to detect changes to the system config files
|
||||||
*/
|
*/
|
||||||
result->fchg_resolvconf = NULL;
|
result->fchg_resolvconf = NULL;
|
||||||
|
@ -1520,7 +1605,15 @@ getdns_context_create_with_extended_memory_functions(
|
||||||
#endif
|
#endif
|
||||||
/* Only initialise SSL once and ideally in a thread-safe manner */
|
/* Only initialise SSL once and ideally in a thread-safe manner */
|
||||||
if (ssl_init == false) {
|
if (ssl_init == false) {
|
||||||
|
#if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL)
|
||||||
|
OpenSSL_add_all_algorithms();
|
||||||
SSL_library_init();
|
SSL_library_init();
|
||||||
|
#else
|
||||||
|
OPENSSL_init_crypto( OPENSSL_INIT_ADD_ALL_CIPHERS
|
||||||
|
| OPENSSL_INIT_ADD_ALL_DIGESTS
|
||||||
|
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
|
||||||
|
(void)OPENSSL_init_ssl(0, NULL);
|
||||||
|
#endif
|
||||||
ssl_init = true;
|
ssl_init = true;
|
||||||
}
|
}
|
||||||
#ifdef HAVE_PTHREAD
|
#ifdef HAVE_PTHREAD
|
||||||
|
@ -1528,7 +1621,6 @@ getdns_context_create_with_extended_memory_functions(
|
||||||
#else
|
#else
|
||||||
/* XXX implement Windows-style unlock here */
|
/* XXX implement Windows-style unlock here */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_LIBUNBOUND
|
#ifdef HAVE_LIBUNBOUND
|
||||||
result->unbound_ctx = NULL;
|
result->unbound_ctx = NULL;
|
||||||
if ((r = rebuild_ub_ctx(result)))
|
if ((r = rebuild_ub_ctx(result)))
|
||||||
|
@ -1603,6 +1695,10 @@ getdns_context_destroy(struct getdns_context *context)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
context->destroying = 1;
|
context->destroying = 1;
|
||||||
|
|
||||||
|
if (context->sys_ctxt)
|
||||||
|
getdns_context_destroy(context->sys_ctxt);
|
||||||
|
|
||||||
/* cancel all outstanding requests */
|
/* cancel all outstanding requests */
|
||||||
cancel_outstanding_requests(context);
|
cancel_outstanding_requests(context);
|
||||||
|
|
||||||
|
@ -1665,10 +1761,20 @@ getdns_context_destroy(struct getdns_context *context)
|
||||||
_getdns_traverse_postorder(&context->local_hosts,
|
_getdns_traverse_postorder(&context->local_hosts,
|
||||||
destroy_local_host, context);
|
destroy_local_host, context);
|
||||||
|
|
||||||
|
|
||||||
getdns_dict_destroy(context->header);
|
getdns_dict_destroy(context->header);
|
||||||
getdns_dict_destroy(context->add_opt_parameters);
|
getdns_dict_destroy(context->add_opt_parameters);
|
||||||
|
|
||||||
|
if (context->trust_anchors_url)
|
||||||
|
GETDNS_FREE(context->mf, context->trust_anchors_url);
|
||||||
|
if (context->trust_anchors_verify_CA)
|
||||||
|
GETDNS_FREE( context->mf
|
||||||
|
, context->trust_anchors_verify_CA);
|
||||||
|
if (context->trust_anchors_verify_email)
|
||||||
|
GETDNS_FREE( context->mf
|
||||||
|
, context->trust_anchors_verify_email);
|
||||||
|
if (context->appdata_dir)
|
||||||
|
GETDNS_FREE(context->mf, context->appdata_dir);
|
||||||
|
|
||||||
#ifdef USE_WINSOCK
|
#ifdef USE_WINSOCK
|
||||||
WSACleanup();
|
WSACleanup();
|
||||||
#endif
|
#endif
|
||||||
|
@ -2442,15 +2548,15 @@ getdns_context_set_dns_root_servers(
|
||||||
if (addr_bd->size == 16 &&
|
if (addr_bd->size == 16 &&
|
||||||
inet_ntop(AF_INET6, addr_bd->data, dst, sizeof(dst)))
|
inet_ntop(AF_INET6, addr_bd->data, dst, sizeof(dst)))
|
||||||
|
|
||||||
fprintf(fh,". NS "PRIsz".root-servers.getdnsapi.net.\n"
|
fprintf(fh,". NS %"PRIsz".root-servers.getdnsapi.net.\n"
|
||||||
PRIsz".root-servers.getdnsapi.net. AAAA %s\n",
|
"%"PRIsz".root-servers.getdnsapi.net. AAAA %s\n",
|
||||||
i, i, dst);
|
i, i, dst);
|
||||||
|
|
||||||
else if (addr_bd->size == 4 &&
|
else if (addr_bd->size == 4 &&
|
||||||
inet_ntop(AF_INET, addr_bd->data, dst, sizeof(dst)))
|
inet_ntop(AF_INET, addr_bd->data, dst, sizeof(dst)))
|
||||||
|
|
||||||
fprintf(fh,". NS "PRIsz".root-servers.getdnsapi.net.\n"
|
fprintf(fh,". NS %"PRIsz".root-servers.getdnsapi.net.\n"
|
||||||
PRIsz".root-servers.getdnsapi.net. A %s\n",
|
"%"PRIsz".root-servers.getdnsapi.net. A %s\n",
|
||||||
i, i, dst);
|
i, i, dst);
|
||||||
}
|
}
|
||||||
fclose(fh);
|
fclose(fh);
|
||||||
|
@ -2615,9 +2721,11 @@ getdns_context_set_dnssec_trust_anchors(
|
||||||
context->trust_anchors = _getdns_list2wire(value,
|
context->trust_anchors = _getdns_list2wire(value,
|
||||||
context->trust_anchors_spc, &context->trust_anchors_len,
|
context->trust_anchors_spc, &context->trust_anchors_len,
|
||||||
&context->mf);
|
&context->mf);
|
||||||
|
context->trust_anchors_source = GETDNS_TASRC_APP;
|
||||||
} else {
|
} else {
|
||||||
context->trust_anchors = NULL;
|
context->trust_anchors = NULL;
|
||||||
context->trust_anchors_len = 0;
|
context->trust_anchors_len = 0;
|
||||||
|
context->trust_anchors_source = GETDNS_TASRC_NONE;
|
||||||
}
|
}
|
||||||
dispatch_updated(context, GETDNS_CONTEXT_CODE_DNSSEC_TRUST_ANCHORS);
|
dispatch_updated(context, GETDNS_CONTEXT_CODE_DNSSEC_TRUST_ANCHORS);
|
||||||
return GETDNS_RETURN_GOOD;
|
return GETDNS_RETURN_GOOD;
|
||||||
|
@ -2666,11 +2774,14 @@ getdns_context_set_upstream_recursive_servers(struct getdns_context *context,
|
||||||
struct addrinfo hints;
|
struct addrinfo hints;
|
||||||
|
|
||||||
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
||||||
RETURN_IF_NULL(upstream_list, GETDNS_RETURN_INVALID_PARAMETER);
|
|
||||||
|
|
||||||
r = getdns_list_get_length(upstream_list, &count);
|
if ( !upstream_list
|
||||||
if (count == 0 || r != GETDNS_RETURN_GOOD) {
|
|| (r = getdns_list_get_length(upstream_list, &count))
|
||||||
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
|
|| count == 0) {
|
||||||
|
_getdns_upstreams_dereference(context->upstreams);
|
||||||
|
context->upstreams = NULL;
|
||||||
|
dispatch_updated(context,
|
||||||
|
GETDNS_CONTEXT_CODE_UPSTREAM_RECURSIVE_SERVERS);
|
||||||
}
|
}
|
||||||
memset(&hints, 0, sizeof(struct addrinfo));
|
memset(&hints, 0, sizeof(struct addrinfo));
|
||||||
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
|
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
|
||||||
|
@ -3411,16 +3522,13 @@ _getdns_ns_dns_setup(struct getdns_context *context)
|
||||||
}
|
}
|
||||||
|
|
||||||
getdns_return_t
|
getdns_return_t
|
||||||
_getdns_context_prepare_for_resolution(struct getdns_context *context,
|
_getdns_context_prepare_for_resolution(getdns_context *context)
|
||||||
int usenamespaces)
|
|
||||||
{
|
{
|
||||||
size_t i;
|
|
||||||
getdns_return_t r;
|
getdns_return_t r;
|
||||||
|
|
||||||
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
||||||
if (context->destroying) {
|
if (context->destroying)
|
||||||
return GETDNS_RETURN_BAD_CONTEXT;
|
return GETDNS_RETURN_BAD_CONTEXT;
|
||||||
}
|
|
||||||
|
|
||||||
/* Transport can in theory be set per query in stub mode */
|
/* Transport can in theory be set per query in stub mode */
|
||||||
if (context->resolution_type == GETDNS_RESOLUTION_STUB &&
|
if (context->resolution_type == GETDNS_RESOLUTION_STUB &&
|
||||||
|
@ -3497,40 +3605,21 @@ _getdns_context_prepare_for_resolution(struct getdns_context *context,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
if (! usenamespaces) {
|
r = _getdns_ns_dns_setup(context);
|
||||||
r = _getdns_ns_dns_setup(context);
|
if (r == GETDNS_RETURN_GOOD)
|
||||||
if (r == GETDNS_RETURN_GOOD)
|
context->resolution_type_set = context->resolution_type;
|
||||||
context->resolution_type_set = context->resolution_type;
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = GETDNS_RETURN_GOOD;
|
|
||||||
for (i = 0; i < context->namespace_count; i++) {
|
|
||||||
switch (context->namespaces[i]) {
|
|
||||||
case GETDNS_NAMESPACE_DNS:
|
|
||||||
r = _getdns_ns_dns_setup(context);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
r = GETDNS_RETURN_BAD_CONTEXT;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (r != GETDNS_RETURN_GOOD)
|
|
||||||
return r; /* try again later (resolution_type_set) */
|
|
||||||
}
|
|
||||||
context->resolution_type_set = context->resolution_type;
|
|
||||||
return r;
|
return r;
|
||||||
} /* _getdns_context_prepare_for_resolution */
|
} /* _getdns_context_prepare_for_resolution */
|
||||||
|
|
||||||
char *
|
char *
|
||||||
_getdns_strdup(const struct mem_funcs *mfs, const char *s)
|
_getdns_strdup(const struct mem_funcs *mfs, const char *s)
|
||||||
{
|
{
|
||||||
size_t sz = strlen(s) + 1;
|
size_t sz;
|
||||||
char *r = GETDNS_XMALLOC(*mfs, char, sz);
|
char *r;
|
||||||
if (r)
|
if (!s || !(r = GETDNS_XMALLOC(*mfs, char, (sz = strlen(s) + 1))))
|
||||||
return memcpy(r, s, sz);
|
|
||||||
else
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
else
|
||||||
|
return memcpy(r, s, sz);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct getdns_bindata *
|
struct getdns_bindata *
|
||||||
|
@ -3659,12 +3748,15 @@ getdns_context_get_eventloop(getdns_context *context, getdns_eventloop **loop)
|
||||||
return GETDNS_RETURN_GOOD;
|
return GETDNS_RETURN_GOOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static size_t _getdns_get_appdata(getdns_context *context, char *path);
|
||||||
static getdns_dict*
|
static getdns_dict*
|
||||||
_get_context_settings(getdns_context* context)
|
_get_context_settings(getdns_context* context)
|
||||||
{
|
{
|
||||||
getdns_dict *result = getdns_dict_create_with_context(context);
|
getdns_dict *result = getdns_dict_create_with_context(context);
|
||||||
getdns_list *list;
|
getdns_list *list;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
const char *str_value;
|
||||||
|
char appdata_dir[_GETDNS_PATH_MAX] = "";
|
||||||
|
|
||||||
if (!result)
|
if (!result)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -3685,6 +3777,8 @@ _get_context_settings(getdns_context* context)
|
||||||
|| ( context->edns_maximum_udp_payload_size != -1
|
|| ( context->edns_maximum_udp_payload_size != -1
|
||||||
&& getdns_dict_set_int(result, "edns_maximum_udp_payload_size",
|
&& getdns_dict_set_int(result, "edns_maximum_udp_payload_size",
|
||||||
context->edns_maximum_udp_payload_size))
|
context->edns_maximum_udp_payload_size))
|
||||||
|
|| getdns_dict_set_int(result, "edns_client_subnet_private",
|
||||||
|
context->edns_client_subnet_private)
|
||||||
|| getdns_dict_set_int(result, "edns_extended_rcode",
|
|| getdns_dict_set_int(result, "edns_extended_rcode",
|
||||||
context->edns_extended_rcode)
|
context->edns_extended_rcode)
|
||||||
|| getdns_dict_set_int(result, "edns_version",
|
|| getdns_dict_set_int(result, "edns_version",
|
||||||
|
@ -3700,7 +3794,12 @@ _get_context_settings(getdns_context* context)
|
||||||
|| getdns_dict_set_int(result, "tls_backoff_time",
|
|| getdns_dict_set_int(result, "tls_backoff_time",
|
||||||
context->tls_backoff_time)
|
context->tls_backoff_time)
|
||||||
|| getdns_dict_set_int(result, "tls_connection_retries",
|
|| getdns_dict_set_int(result, "tls_connection_retries",
|
||||||
context->tls_connection_retries))
|
context->tls_connection_retries)
|
||||||
|
|| getdns_dict_set_int(result, "tls_query_padding_blocksize",
|
||||||
|
context->tls_query_padding_blocksize)
|
||||||
|
|| getdns_dict_set_int(result, "resolution_type",
|
||||||
|
context->resolution_type)
|
||||||
|
)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
/* list fields */
|
/* list fields */
|
||||||
|
@ -3719,6 +3818,14 @@ _get_context_settings(getdns_context* context)
|
||||||
getdns_list_destroy(list);
|
getdns_list_destroy(list);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
if (getdns_context_get_dnssec_trust_anchors(context, &list))
|
||||||
|
; /* pass */
|
||||||
|
|
||||||
|
else if (list && _getdns_dict_set_this_list(
|
||||||
|
result, "dnssec_trust_anchors", list)) {
|
||||||
|
getdns_list_destroy(list);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
if (context->dns_transport_count > 0) {
|
if (context->dns_transport_count > 0) {
|
||||||
/* create a namespace list */
|
/* create a namespace list */
|
||||||
if (!(list = getdns_list_create_with_context(context)))
|
if (!(list = getdns_list_create_with_context(context)))
|
||||||
|
@ -3754,6 +3861,15 @@ _get_context_settings(getdns_context* context)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
(void) _getdns_get_appdata(context, appdata_dir);
|
||||||
|
(void) getdns_dict_util_set_string(result, "appdata_dir", appdata_dir);
|
||||||
|
if (!getdns_context_get_trust_anchors_url(context, &str_value) && str_value)
|
||||||
|
(void) getdns_dict_util_set_string(result, "trust_anchors_url", str_value);
|
||||||
|
if (!getdns_context_get_trust_anchors_verify_CA(context, &str_value) && str_value)
|
||||||
|
(void) getdns_dict_util_set_string(result, "trust_anchors_verify_CA", str_value);
|
||||||
|
if (!getdns_context_get_trust_anchors_verify_email(context, &str_value) && str_value)
|
||||||
|
(void) getdns_dict_util_set_string(result, "trust_anchors_verify_email", str_value);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
error:
|
error:
|
||||||
getdns_dict_destroy(result);
|
getdns_dict_destroy(result);
|
||||||
|
@ -3771,9 +3887,24 @@ getdns_context_get_api_information(getdns_context* context)
|
||||||
&& ! getdns_dict_util_set_string(
|
&& ! getdns_dict_util_set_string(
|
||||||
result, "version_string", GETDNS_VERSION)
|
result, "version_string", GETDNS_VERSION)
|
||||||
|
|
||||||
|
&& ! getdns_dict_set_int(
|
||||||
|
result, "version_number", getdns_get_version_number())
|
||||||
|
|
||||||
|
&& ! getdns_dict_util_set_string(
|
||||||
|
result, "api_version_string", getdns_get_api_version())
|
||||||
|
|
||||||
|
&& ! getdns_dict_set_int(
|
||||||
|
result, "api_version_number", getdns_get_api_version_number())
|
||||||
|
|
||||||
&& ! getdns_dict_util_set_string(
|
&& ! getdns_dict_util_set_string(
|
||||||
result, "implementation_string", PACKAGE_URL)
|
result, "implementation_string", PACKAGE_URL)
|
||||||
|
|
||||||
|
&& ! getdns_dict_util_set_string(
|
||||||
|
result, "compilation_comment", GETDNS_COMPILATION_COMMENT)
|
||||||
|
|
||||||
|
&& ! getdns_dict_util_set_string(
|
||||||
|
result, "trust_anchor_file", TRUST_ANCHOR_FILE)
|
||||||
|
|
||||||
&& ! getdns_dict_set_int(
|
&& ! getdns_dict_set_int(
|
||||||
result, "resolution_type", context->resolution_type)
|
result, "resolution_type", context->resolution_type)
|
||||||
|
|
||||||
|
@ -4375,6 +4506,12 @@ static getdns_return_t _get_list_or_read_file(const getdns_dict *config_dict,
|
||||||
else r = GETDNS_RETURN_INVALID_PARAMETER; \
|
else r = GETDNS_RETURN_INVALID_PARAMETER; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define CONTEXT_SETTING_STRING(X) \
|
||||||
|
} else if (_streq(setting, #X )) { \
|
||||||
|
if (!(r = getdns_dict_get_bindata(config_dict, #X , &bd))) \
|
||||||
|
r = getdns_context_set_ ## X( \
|
||||||
|
context, (char *)bd->data);
|
||||||
|
|
||||||
static getdns_return_t
|
static getdns_return_t
|
||||||
_getdns_context_config_setting(getdns_context *context,
|
_getdns_context_config_setting(getdns_context *context,
|
||||||
const getdns_dict *config_dict, const getdns_bindata *setting)
|
const getdns_dict *config_dict, const getdns_bindata *setting)
|
||||||
|
@ -4386,6 +4523,7 @@ _getdns_context_config_setting(getdns_context *context,
|
||||||
getdns_transport_list_t dns_transport_list[100];
|
getdns_transport_list_t dns_transport_list[100];
|
||||||
size_t count, i;
|
size_t count, i;
|
||||||
uint32_t n;
|
uint32_t n;
|
||||||
|
getdns_bindata *bd;
|
||||||
int destroy_list = 0;
|
int destroy_list = 0;
|
||||||
|
|
||||||
if (_streq(setting, "all_context")) {
|
if (_streq(setting, "all_context")) {
|
||||||
|
@ -4423,6 +4561,10 @@ _getdns_context_config_setting(getdns_context *context,
|
||||||
CONTEXT_SETTING_INT(tls_backoff_time)
|
CONTEXT_SETTING_INT(tls_backoff_time)
|
||||||
CONTEXT_SETTING_INT(tls_connection_retries)
|
CONTEXT_SETTING_INT(tls_connection_retries)
|
||||||
CONTEXT_SETTING_INT(tls_query_padding_blocksize)
|
CONTEXT_SETTING_INT(tls_query_padding_blocksize)
|
||||||
|
CONTEXT_SETTING_STRING(trust_anchors_url)
|
||||||
|
CONTEXT_SETTING_STRING(trust_anchors_verify_CA)
|
||||||
|
CONTEXT_SETTING_STRING(trust_anchors_verify_email)
|
||||||
|
CONTEXT_SETTING_STRING(appdata_dir)
|
||||||
|
|
||||||
/**************************************/
|
/**************************************/
|
||||||
/**** ****/
|
/**** ****/
|
||||||
|
@ -4475,8 +4617,14 @@ _getdns_context_config_setting(getdns_context *context,
|
||||||
/**** Ignored context settings ****/
|
/**** Ignored context settings ****/
|
||||||
/**** ****/
|
/**** ****/
|
||||||
/************************************/
|
/************************************/
|
||||||
} else if (!_streq(setting, "implementation_string") &&
|
} else if (!_streq(setting, "implementation_string")
|
||||||
!_streq(setting, "version_string")) {
|
&& !_streq(setting, "version_string")
|
||||||
|
&& !_streq(setting, "version_number")
|
||||||
|
&& !_streq(setting, "api_version_string")
|
||||||
|
&& !_streq(setting, "api_version_number")
|
||||||
|
&& !_streq(setting, "trust_anchor_file")
|
||||||
|
&& !_streq(setting, "compilation_comment")
|
||||||
|
) {
|
||||||
r = GETDNS_RETURN_NOT_IMPLEMENTED;
|
r = GETDNS_RETURN_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
|
@ -4505,4 +4653,360 @@ getdns_context_config(getdns_context *context, const getdns_dict *config_dict)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static size_t _getdns_get_appdata(getdns_context *context, char *path)
|
||||||
|
{
|
||||||
|
size_t len = 0;
|
||||||
|
|
||||||
|
#ifdef USE_WINSOCK
|
||||||
|
# define SLASHTOK '\\'
|
||||||
|
# define APPDATA_SUBDIR "getdns"
|
||||||
|
|
||||||
|
if (context->appdata_dir) {
|
||||||
|
(void) strcpy(path, context->appdata_dir);
|
||||||
|
len = strlen(path);
|
||||||
|
|
||||||
|
} else if (! SUCCEEDED(SHGetFolderPath(NULL,
|
||||||
|
CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, path)))
|
||||||
|
DEBUG_ANCHOR("ERROR %s(): Could not get %%AppData%% directory\n"
|
||||||
|
, __FUNC__);
|
||||||
|
|
||||||
|
else if ((len = strlen(path)) + sizeof(APPDATA_SUBDIR) + 2 >= _GETDNS_PATH_MAX)
|
||||||
|
DEBUG_ANCHOR("ERROR %s(): Home path too long for appdata\n"
|
||||||
|
, __FUNC__);
|
||||||
|
#else
|
||||||
|
# define SLASHTOK '/'
|
||||||
|
# define APPDATA_SUBDIR ".getdns"
|
||||||
|
struct passwd *p = getpwuid(getuid());
|
||||||
|
char *home = NULL;
|
||||||
|
|
||||||
|
if (context->appdata_dir) {
|
||||||
|
(void) strcpy(path, context->appdata_dir);
|
||||||
|
len = strlen(path);
|
||||||
|
|
||||||
|
} else if (!(home = p ? p->pw_dir : getenv("HOME")))
|
||||||
|
DEBUG_ANCHOR("ERROR %s(): Could not get home directory\n"
|
||||||
|
, __FUNC__);
|
||||||
|
|
||||||
|
else if ((len = strlen(home)) + sizeof(APPDATA_SUBDIR) + 2 >= _GETDNS_PATH_MAX)
|
||||||
|
DEBUG_ANCHOR("ERROR %s(): Home path too long for appdata\n"
|
||||||
|
, __FUNC__);
|
||||||
|
|
||||||
|
else if (!strcpy(path, home))
|
||||||
|
; /* strcpy returns path always */
|
||||||
|
#endif
|
||||||
|
else {
|
||||||
|
if (len == 0 || ( path[len - 1] != '/'
|
||||||
|
&& path[len - 1] != '\\')) {
|
||||||
|
path[len++] = SLASHTOK;
|
||||||
|
path[len ] = '\0';
|
||||||
|
}
|
||||||
|
(void) strcpy(path + len, APPDATA_SUBDIR);
|
||||||
|
len += sizeof(APPDATA_SUBDIR) - 1;
|
||||||
|
}
|
||||||
|
if (len) {
|
||||||
|
if (path[len - 1] == '/' || path[len - 1] == '\\') {
|
||||||
|
path[--len] = '\0';
|
||||||
|
}
|
||||||
|
if (0 >
|
||||||
|
#ifdef USE_WINSOCK
|
||||||
|
mkdir(path)
|
||||||
|
#else
|
||||||
|
mkdir(path, 0755)
|
||||||
|
#endif
|
||||||
|
&& errno != EEXIST)
|
||||||
|
DEBUG_ANCHOR("ERROR %s(): Could not mkdir %s: %s\n"
|
||||||
|
, __FUNC__, path, strerror(errno));
|
||||||
|
else {
|
||||||
|
path[len++] = SLASHTOK;
|
||||||
|
path[len ] = '\0';
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *_getdns_context_get_priv_fp(getdns_context *context, const char *fn)
|
||||||
|
{
|
||||||
|
char path[_GETDNS_PATH_MAX];
|
||||||
|
FILE *f = NULL;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
(void) context;
|
||||||
|
if (!(len = _getdns_get_appdata(context, path)))
|
||||||
|
DEBUG_ANCHOR("ERROR %s(): Could nog get application data path\n"
|
||||||
|
, __FUNC__);
|
||||||
|
|
||||||
|
else if (len + strlen(fn) >= sizeof(path))
|
||||||
|
DEBUG_ANCHOR("ERROR %s(): Application data too long\n", __FUNC__);
|
||||||
|
|
||||||
|
else if (!strcpy(path + len, fn))
|
||||||
|
; /* strcpy returns path + len always */
|
||||||
|
|
||||||
|
else if (!(f = fopen(path, "r")))
|
||||||
|
DEBUG_ANCHOR("ERROR %s(): Opening \"%s\": %s\n"
|
||||||
|
, __FUNC__, path, strerror(errno));
|
||||||
|
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *_getdns_context_get_priv_file(getdns_context *context,
|
||||||
|
const char *fn, uint8_t *buf, size_t buf_len, size_t *file_sz)
|
||||||
|
{
|
||||||
|
FILE *f = NULL;
|
||||||
|
|
||||||
|
if (!(f = _getdns_context_get_priv_fp(context, fn)))
|
||||||
|
; /* pass */
|
||||||
|
|
||||||
|
else if ((*file_sz = fread(buf, 1, buf_len, f)) < (buf_len - 1) && feof(f)) {
|
||||||
|
buf[*file_sz] = 0;
|
||||||
|
(void) fclose(f);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
else if (fseek(f, 0, SEEK_END) < 0)
|
||||||
|
DEBUG_ANCHOR("ERROR %s(): Determining size of \"%s\": %s\n"
|
||||||
|
, __FUNC__, fn, strerror(errno));
|
||||||
|
|
||||||
|
else if (!(buf = GETDNS_XMALLOC(
|
||||||
|
context->mf, uint8_t, (buf_len = ftell(f) + 1))))
|
||||||
|
DEBUG_ANCHOR("ERROR %s(): Allocating %d memory for \"%s\"\n"
|
||||||
|
, __FUNC__, (int)buf_len, fn);
|
||||||
|
|
||||||
|
else {
|
||||||
|
rewind(f);
|
||||||
|
if ((*file_sz = fread(buf, 1, buf_len, f)) >= buf_len || !feof(f)) {
|
||||||
|
GETDNS_FREE(context->mf, buf);
|
||||||
|
DEBUG_ANCHOR("ERROR %s(): Reading \"%s\": %s\n"
|
||||||
|
, __FUNC__, fn, strerror(errno));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
buf[*file_sz] = 0;
|
||||||
|
(void) fclose(f);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (f)
|
||||||
|
(void) fclose(f);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int _getdns_context_write_priv_file(getdns_context *context,
|
||||||
|
const char *fn, getdns_bindata *content)
|
||||||
|
{
|
||||||
|
char path[_GETDNS_PATH_MAX], tmpfn[_GETDNS_PATH_MAX];
|
||||||
|
int fd = -1;
|
||||||
|
FILE *f = NULL;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
if (!(len = _getdns_get_appdata(context, path)))
|
||||||
|
DEBUG_ANCHOR("ERROR %s(): Could nog get application data path\n"
|
||||||
|
, __FUNC__);
|
||||||
|
|
||||||
|
else if (len + 6 >= sizeof(tmpfn)
|
||||||
|
|| len + strlen(fn) >= sizeof(path))
|
||||||
|
DEBUG_ANCHOR("ERROR %s(): Application data too long\n", __FUNC__);
|
||||||
|
|
||||||
|
|
||||||
|
else if (snprintf(tmpfn, sizeof(tmpfn), "%sXXXXXX", path) < 0)
|
||||||
|
DEBUG_ANCHOR("ERROR %s(): Creating temporary filename template\n"
|
||||||
|
, __FUNC__);
|
||||||
|
|
||||||
|
else if (!strcpy(path + len, fn))
|
||||||
|
; /* strcpy returns path + len always */
|
||||||
|
|
||||||
|
else if ((fd = mkstemp(tmpfn)) < 0)
|
||||||
|
DEBUG_ANCHOR("ERROR %s(): Creating temporary file: %s\n"
|
||||||
|
, __FUNC__, strerror(errno));
|
||||||
|
|
||||||
|
else if (!(f = fdopen(fd, "w")))
|
||||||
|
DEBUG_ANCHOR("ERROR %s(): Opening temporary file: %s\n"
|
||||||
|
, __FUNC__, strerror(errno));
|
||||||
|
|
||||||
|
else if (fwrite(content->data, 1, content->size, f) < content->size)
|
||||||
|
DEBUG_ANCHOR("ERROR %s(): Writing temporary file: %s\n"
|
||||||
|
, __FUNC__, strerror(errno));
|
||||||
|
|
||||||
|
else if (fclose(f) < 0)
|
||||||
|
DEBUG_ANCHOR("ERROR %s(): Closing temporary file: %s\n"
|
||||||
|
, __FUNC__, strerror(errno));
|
||||||
|
|
||||||
|
else if (rename(tmpfn, path) < 0)
|
||||||
|
DEBUG_ANCHOR("ERROR %s(): Renaming temporary file: %s\n"
|
||||||
|
, __FUNC__, strerror(errno));
|
||||||
|
else {
|
||||||
|
context->can_write_appdata = PROP_ABLE;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (f)
|
||||||
|
(void) fclose(f);
|
||||||
|
|
||||||
|
else if (fd >= 0)
|
||||||
|
(void) close(fd);
|
||||||
|
|
||||||
|
context->can_write_appdata = PROP_UNABLE;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _getdns_context_can_write_appdata(getdns_context *context)
|
||||||
|
{
|
||||||
|
char test_fn[30], path[_GETDNS_PATH_MAX];
|
||||||
|
size_t len;
|
||||||
|
getdns_bindata test_content = { 4, (void *)"TEST" };
|
||||||
|
|
||||||
|
if (context->can_write_appdata == PROP_ABLE)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
else if (context->can_write_appdata == PROP_UNABLE)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
(void) snprintf( test_fn, sizeof(test_fn)
|
||||||
|
, "write-test-%d.tmp", arc4random());
|
||||||
|
|
||||||
|
if (!_getdns_context_write_priv_file(context, test_fn, &test_content))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!(len = _getdns_get_appdata(context, path)))
|
||||||
|
DEBUG_ANCHOR("ERROR %s(): Could nog get application data path\n"
|
||||||
|
, __FUNC__);
|
||||||
|
|
||||||
|
else if (len + strlen(test_fn) >= sizeof(path))
|
||||||
|
DEBUG_ANCHOR("ERROR %s(): Application data too long\n", __FUNC__);
|
||||||
|
|
||||||
|
else if (!strcpy(path + len, test_fn))
|
||||||
|
; /* strcpy returns path + len always */
|
||||||
|
|
||||||
|
else if (unlink(path) < 0)
|
||||||
|
DEBUG_ANCHOR("ERROR %s(): Unlinking write test file \"%s\": %s\n"
|
||||||
|
, __FUNC__, path, strerror(errno));
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
getdns_return_t
|
||||||
|
getdns_context_set_trust_anchors_url(
|
||||||
|
getdns_context *context, const char *url)
|
||||||
|
{
|
||||||
|
const char *path;
|
||||||
|
size_t path_len;
|
||||||
|
|
||||||
|
if (!context)
|
||||||
|
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
if (url) {
|
||||||
|
if (! ((url[0] == 'h' || url[0] == 'H')
|
||||||
|
&& (url[1] == 't' || url[1] == 'T')
|
||||||
|
&& (url[2] == 't' || url[2] == 'T')
|
||||||
|
&& (url[3] == 'p' || url[3] == 'P')
|
||||||
|
&& url[4] == ':' && url[5] == '/' && url[6] == '/'
|
||||||
|
&& (path = strchr(url + 7, '/'))))
|
||||||
|
return GETDNS_RETURN_NOT_IMPLEMENTED;
|
||||||
|
|
||||||
|
path_len = strlen(path);
|
||||||
|
if (! ( path_len >= 5
|
||||||
|
&& path[path_len - 4] == '.'
|
||||||
|
&& ( path[path_len - 3] == 'x'
|
||||||
|
|| path[path_len - 3] == 'X')
|
||||||
|
&& ( path[path_len - 2] == 'm'
|
||||||
|
|| path[path_len - 2] == 'M')
|
||||||
|
&& ( path[path_len - 1] == 'l'
|
||||||
|
|| path[path_len - 1] == 'L')))
|
||||||
|
return GETDNS_RETURN_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
if (context->trust_anchors_url)
|
||||||
|
GETDNS_FREE(context->mf, context->trust_anchors_url);
|
||||||
|
context->trust_anchors_url = _getdns_strdup(&context->mf, url);
|
||||||
|
|
||||||
|
dispatch_updated(context, GETDNS_CONTEXT_CODE_TRUST_ANCHORS_URL);
|
||||||
|
return GETDNS_RETURN_GOOD;
|
||||||
|
}
|
||||||
|
|
||||||
|
getdns_return_t
|
||||||
|
getdns_context_get_trust_anchors_url(
|
||||||
|
getdns_context *context, const char **url)
|
||||||
|
{
|
||||||
|
if (!context || !url)
|
||||||
|
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
*url = context && context->trust_anchors_url
|
||||||
|
? context->trust_anchors_url
|
||||||
|
: _getdns_default_trust_anchors_url;
|
||||||
|
return GETDNS_RETURN_GOOD;
|
||||||
|
}
|
||||||
|
|
||||||
|
getdns_return_t
|
||||||
|
getdns_context_set_trust_anchors_verify_CA(
|
||||||
|
getdns_context *context, const char *verify_CA)
|
||||||
|
{
|
||||||
|
if (!context)
|
||||||
|
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
if (context->trust_anchors_verify_CA)
|
||||||
|
GETDNS_FREE(context->mf, context->trust_anchors_verify_CA);
|
||||||
|
context->trust_anchors_verify_CA =
|
||||||
|
_getdns_strdup(&context->mf, verify_CA);
|
||||||
|
|
||||||
|
dispatch_updated( context
|
||||||
|
, GETDNS_CONTEXT_CODE_TRUST_ANCHORS_VERIFY_CA);
|
||||||
|
return GETDNS_RETURN_GOOD;
|
||||||
|
}
|
||||||
|
|
||||||
|
getdns_return_t
|
||||||
|
getdns_context_get_trust_anchors_verify_CA(
|
||||||
|
getdns_context *context, const char **verify_CA)
|
||||||
|
{
|
||||||
|
if (!verify_CA)
|
||||||
|
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
*verify_CA = context && context->trust_anchors_verify_CA
|
||||||
|
? context->trust_anchors_verify_CA
|
||||||
|
: _getdns_default_trust_anchors_verify_CA;
|
||||||
|
return GETDNS_RETURN_GOOD;
|
||||||
|
}
|
||||||
|
|
||||||
|
getdns_return_t
|
||||||
|
getdns_context_set_trust_anchors_verify_email(
|
||||||
|
getdns_context *context, const char *verify_email)
|
||||||
|
{
|
||||||
|
if (!context)
|
||||||
|
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
if (context->trust_anchors_verify_email)
|
||||||
|
GETDNS_FREE(context->mf, context->trust_anchors_verify_email);
|
||||||
|
context->trust_anchors_verify_email =
|
||||||
|
_getdns_strdup(&context->mf, verify_email);
|
||||||
|
|
||||||
|
dispatch_updated( context
|
||||||
|
, GETDNS_CONTEXT_CODE_TRUST_ANCHORS_VERIFY_EMAIL);
|
||||||
|
return GETDNS_RETURN_GOOD;
|
||||||
|
}
|
||||||
|
|
||||||
|
getdns_return_t
|
||||||
|
getdns_context_get_trust_anchors_verify_email(
|
||||||
|
getdns_context *context, const char **verify_email)
|
||||||
|
{
|
||||||
|
if (!verify_email)
|
||||||
|
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
*verify_email = context && context->trust_anchors_verify_email
|
||||||
|
? context->trust_anchors_verify_email
|
||||||
|
: _getdns_default_trust_anchors_verify_email;
|
||||||
|
return GETDNS_RETURN_GOOD;
|
||||||
|
}
|
||||||
|
|
||||||
|
getdns_return_t
|
||||||
|
getdns_context_set_appdata_dir(
|
||||||
|
getdns_context *context, const char *appdata_dir)
|
||||||
|
{
|
||||||
|
if (!context)
|
||||||
|
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
if (context->appdata_dir)
|
||||||
|
GETDNS_FREE(context->mf, context->appdata_dir);
|
||||||
|
context->appdata_dir = _getdns_strdup(&context->mf, appdata_dir);
|
||||||
|
|
||||||
|
dispatch_updated(context, GETDNS_CONTEXT_CODE_APPDATA_DIR);
|
||||||
|
return GETDNS_RETURN_GOOD;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* context.c */
|
/* context.c */
|
||||||
|
|
|
@ -48,6 +48,8 @@
|
||||||
#ifdef HAVE_MDNS_SUPPORT
|
#ifdef HAVE_MDNS_SUPPORT
|
||||||
#include "util/lruhash.h"
|
#include "util/lruhash.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include "rr-iter.h"
|
||||||
|
#include "anchor.h"
|
||||||
|
|
||||||
struct getdns_dns_req;
|
struct getdns_dns_req;
|
||||||
struct ub_ctx;
|
struct ub_ctx;
|
||||||
|
@ -92,6 +94,16 @@ typedef enum getdns_conn_state {
|
||||||
GETDNS_CONN_BACKOFF
|
GETDNS_CONN_BACKOFF
|
||||||
} getdns_conn_state_t;
|
} getdns_conn_state_t;
|
||||||
|
|
||||||
|
typedef enum getdns_tasrc {
|
||||||
|
GETDNS_TASRC_NONE,
|
||||||
|
GETDNS_TASRC_ZONE,
|
||||||
|
GETDNS_TASRC_APP,
|
||||||
|
GETDNS_TASRC_FETCHING,
|
||||||
|
GETDNS_TASRC_XML,
|
||||||
|
GETDNS_TASRC_XML_UPDATE,
|
||||||
|
GETDNS_TASRC_FAILED
|
||||||
|
} getdns_tasrc;
|
||||||
|
|
||||||
typedef enum getdns_tsig_algo {
|
typedef enum getdns_tsig_algo {
|
||||||
GETDNS_NO_TSIG = 0, /* Do not use tsig */
|
GETDNS_NO_TSIG = 0, /* Do not use tsig */
|
||||||
GETDNS_HMAC_MD5 = 1, /* 128 bits */
|
GETDNS_HMAC_MD5 = 1, /* 128 bits */
|
||||||
|
@ -103,6 +115,7 @@ typedef enum getdns_tsig_algo {
|
||||||
GETDNS_HMAC_SHA512 = 7
|
GETDNS_HMAC_SHA512 = 7
|
||||||
} getdns_tsig_algo;
|
} getdns_tsig_algo;
|
||||||
|
|
||||||
|
|
||||||
typedef struct getdns_tsig_info {
|
typedef struct getdns_tsig_info {
|
||||||
getdns_tsig_algo alg;
|
getdns_tsig_algo alg;
|
||||||
const char *name;
|
const char *name;
|
||||||
|
@ -170,6 +183,7 @@ typedef struct getdns_upstream {
|
||||||
size_t conn_shutdowns;
|
size_t conn_shutdowns;
|
||||||
size_t conn_setup_failed;
|
size_t conn_setup_failed;
|
||||||
time_t conn_retry_time;
|
time_t conn_retry_time;
|
||||||
|
uint16_t conn_backoff_interval;
|
||||||
size_t conn_backoffs;
|
size_t conn_backoffs;
|
||||||
size_t total_responses;
|
size_t total_responses;
|
||||||
size_t total_timeouts;
|
size_t total_timeouts;
|
||||||
|
@ -255,6 +269,44 @@ typedef struct getdns_upstreams {
|
||||||
getdns_upstream upstreams[];
|
getdns_upstream upstreams[];
|
||||||
} getdns_upstreams;
|
} getdns_upstreams;
|
||||||
|
|
||||||
|
typedef enum tas_state {
|
||||||
|
TAS_LOOKUP_ADDRESSES = 0,
|
||||||
|
TAS_WRITE_GET_XML,
|
||||||
|
TAS_READ_XML_HDR,
|
||||||
|
TAS_READ_XML_DOC,
|
||||||
|
TAS_WRITE_GET_PS7,
|
||||||
|
TAS_READ_PS7_HDR,
|
||||||
|
TAS_READ_PS7_DOC,
|
||||||
|
TAS_DONE,
|
||||||
|
TAS_RETRY,
|
||||||
|
TAS_RETRY_GET_PS7,
|
||||||
|
TAS_RETRY_PS7_HDR,
|
||||||
|
TAS_RETRY_PS7_DOC,
|
||||||
|
TAS_RETRY_DONE
|
||||||
|
} tas_state;
|
||||||
|
|
||||||
|
typedef enum _getdns_property {
|
||||||
|
PROP_INHERIT = 0,
|
||||||
|
PROP_UNKNOWN = 1,
|
||||||
|
PROP_UNABLE = 2,
|
||||||
|
PROP_ABLE = 3
|
||||||
|
} _getdns_property;
|
||||||
|
|
||||||
|
typedef struct tas_connection {
|
||||||
|
getdns_eventloop *loop;
|
||||||
|
getdns_network_req *req;
|
||||||
|
_getdns_rrset_spc rrset_spc;
|
||||||
|
_getdns_rrset *rrset;
|
||||||
|
_getdns_rrtype_iter rr_spc;
|
||||||
|
_getdns_rrtype_iter *rr;
|
||||||
|
int fd;
|
||||||
|
getdns_eventloop_event event;
|
||||||
|
tas_state state;
|
||||||
|
getdns_tcp_state tcp;
|
||||||
|
char *http;
|
||||||
|
getdns_bindata xml;
|
||||||
|
} tas_connection;
|
||||||
|
|
||||||
struct getdns_context {
|
struct getdns_context {
|
||||||
/* Context values */
|
/* Context values */
|
||||||
getdns_resolution_t resolution_type;
|
getdns_resolution_t resolution_type;
|
||||||
|
@ -276,8 +328,24 @@ struct getdns_context {
|
||||||
const uint8_t *suffixes;
|
const uint8_t *suffixes;
|
||||||
/* Length of all suffixes in the suffix buffer */
|
/* Length of all suffixes in the suffix buffer */
|
||||||
size_t suffixes_len;
|
size_t suffixes_len;
|
||||||
|
|
||||||
uint8_t *trust_anchors;
|
uint8_t *trust_anchors;
|
||||||
size_t trust_anchors_len;
|
size_t trust_anchors_len;
|
||||||
|
getdns_tasrc trust_anchors_source;
|
||||||
|
|
||||||
|
tas_connection a;
|
||||||
|
tas_connection aaaa;
|
||||||
|
uint8_t tas_hdr_spc[512];
|
||||||
|
|
||||||
|
char *trust_anchors_url;
|
||||||
|
char *trust_anchors_verify_CA;
|
||||||
|
char *trust_anchors_verify_email;
|
||||||
|
|
||||||
|
_getdns_ksks root_ksk;
|
||||||
|
|
||||||
|
char *appdata_dir;
|
||||||
|
_getdns_property can_write_appdata;
|
||||||
|
|
||||||
getdns_upstreams *upstreams;
|
getdns_upstreams *upstreams;
|
||||||
uint16_t limit_outstanding_queries;
|
uint16_t limit_outstanding_queries;
|
||||||
uint32_t dnssec_allowed_skew;
|
uint32_t dnssec_allowed_skew;
|
||||||
|
@ -372,6 +440,18 @@ struct getdns_context {
|
||||||
unsigned return_call_reporting : 1;
|
unsigned return_call_reporting : 1;
|
||||||
uint16_t specify_class;
|
uint16_t specify_class;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Context for doing system queries.
|
||||||
|
* For example to resolve data.iana.org or to resolver the addresses
|
||||||
|
* of upstreams without specified addresses.
|
||||||
|
*/
|
||||||
|
getdns_context *sys_ctxt;
|
||||||
|
|
||||||
|
/* List of dnsreqs that want to be notified when we have fetched a
|
||||||
|
* trust anchor from data.iana.org.
|
||||||
|
*/
|
||||||
|
getdns_dns_req *ta_notify;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* state data used to detect changes to the system config files
|
* state data used to detect changes to the system config files
|
||||||
*/
|
*/
|
||||||
|
@ -415,11 +495,9 @@ void _getdns_context_log(getdns_context *context, uint64_t system,
|
||||||
* Sets up the unbound contexts with stub or recursive behavior
|
* Sets up the unbound contexts with stub or recursive behavior
|
||||||
* if needed.
|
* if needed.
|
||||||
* @param context previously initialized getdns_context
|
* @param context previously initialized getdns_context
|
||||||
* @param usenamespaces if 0 then only use the DNS, else use context namespace list
|
|
||||||
* @return GETDNS_RETURN_GOOD on success
|
* @return GETDNS_RETURN_GOOD on success
|
||||||
*/
|
*/
|
||||||
getdns_return_t _getdns_context_prepare_for_resolution(struct getdns_context *context,
|
getdns_return_t _getdns_context_prepare_for_resolution(getdns_context *context);
|
||||||
int usenamespaces);
|
|
||||||
|
|
||||||
/* Register a getdns_dns_req with context.
|
/* Register a getdns_dns_req with context.
|
||||||
* - Without pluggable unbound event API,
|
* - Without pluggable unbound event API,
|
||||||
|
@ -470,4 +548,13 @@ void _getdns_upstreams_dereference(getdns_upstreams *upstreams);
|
||||||
|
|
||||||
void _getdns_upstream_shutdown(getdns_upstream *upstream);
|
void _getdns_upstream_shutdown(getdns_upstream *upstream);
|
||||||
|
|
||||||
|
FILE *_getdns_context_get_priv_fp(getdns_context *context, const char *fn);
|
||||||
|
uint8_t *_getdns_context_get_priv_file(getdns_context *context,
|
||||||
|
const char *fn, uint8_t *buf, size_t buf_len, size_t *file_sz);
|
||||||
|
|
||||||
|
int _getdns_context_write_priv_file(getdns_context *context,
|
||||||
|
const char *fn, getdns_bindata *content);
|
||||||
|
|
||||||
|
int _getdns_context_can_write_appdata(getdns_context *context);
|
||||||
|
|
||||||
#endif /* _GETDNS_CONTEXT_H_ */
|
#endif /* _GETDNS_CONTEXT_H_ */
|
||||||
|
|
101
src/convert.c
101
src/convert.c
|
@ -32,10 +32,10 @@
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
#include "config.h"
|
|
||||||
#ifndef USE_WINSOCK
|
#ifndef USE_WINSOCK
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -54,6 +54,7 @@
|
||||||
#include "dict.h"
|
#include "dict.h"
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
#include "jsmn/jsmn.h"
|
#include "jsmn/jsmn.h"
|
||||||
|
#include "yaml/convert_yaml_to_json.h"
|
||||||
#include "convert.h"
|
#include "convert.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
|
@ -1802,3 +1803,101 @@ getdns_str2int(const char *str, uint32_t *value)
|
||||||
return GETDNS_RETURN_GOOD;
|
return GETDNS_RETURN_GOOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_YAML_CONFIG
|
||||||
|
getdns_return_t
|
||||||
|
getdns_yaml2dict(const char *str, getdns_dict **dict)
|
||||||
|
{
|
||||||
|
char *jsonstr;
|
||||||
|
|
||||||
|
if (!str || !dict)
|
||||||
|
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
jsonstr = yaml_string_to_json_string(str);
|
||||||
|
if (jsonstr) {
|
||||||
|
getdns_return_t res = getdns_str2dict(jsonstr, dict);
|
||||||
|
free(jsonstr);
|
||||||
|
return res;
|
||||||
|
} else {
|
||||||
|
return GETDNS_RETURN_GENERIC_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* USE_YAML_CONFIG */
|
||||||
|
|
||||||
|
/* WT: I am not certain about the value of yaml2list...
|
||||||
|
* I don't see how yaml2bindata and yaml2int would be different from
|
||||||
|
* the str2bindata and str2int ones.
|
||||||
|
*/
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
getdns_return_t
|
||||||
|
getdns_yaml2list(const char *str, getdns_list **list)
|
||||||
|
{
|
||||||
|
#ifdef USE_YAML_CONFIG
|
||||||
|
char *jsonstr;
|
||||||
|
|
||||||
|
if (!str || !list)
|
||||||
|
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
jsonstr = yaml_string_to_json_string(str);
|
||||||
|
if (jsonstr) {
|
||||||
|
getdns_return_t res = getdns_str2list(jsonstr, list);
|
||||||
|
free(jsonstr);
|
||||||
|
return res;
|
||||||
|
} else {
|
||||||
|
return GETDNS_RETURN_GENERIC_ERROR;
|
||||||
|
}
|
||||||
|
#else /* USE_YAML_CONFIG */
|
||||||
|
(void) str;
|
||||||
|
(void) list;
|
||||||
|
return GETDNS_RETURN_NOT_IMPLEMENTED;
|
||||||
|
#endif /* USE_YAML_CONFIG */
|
||||||
|
}
|
||||||
|
|
||||||
|
getdns_return_t
|
||||||
|
getdns_yaml2bindata(const char *str, getdns_bindata **bindata)
|
||||||
|
{
|
||||||
|
#ifdef USE_YAML_CONFIG
|
||||||
|
char *jsonstr;
|
||||||
|
|
||||||
|
if (!str || !bindata)
|
||||||
|
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
jsonstr = yaml_string_to_json_string(str);
|
||||||
|
if (jsonstr) {
|
||||||
|
getdns_return_t res = getdns_str2bindata(jsonstr, bindata);
|
||||||
|
free(jsonstr);
|
||||||
|
return res;
|
||||||
|
} else {
|
||||||
|
return GETDNS_RETURN_GENERIC_ERROR;
|
||||||
|
}
|
||||||
|
#else /* USE_YAML_CONFIG */
|
||||||
|
(void) str;
|
||||||
|
(void) bindata;
|
||||||
|
return GETDNS_RETURN_NOT_IMPLEMENTED;
|
||||||
|
#endif /* USE_YAML_CONFIG */
|
||||||
|
}
|
||||||
|
|
||||||
|
getdns_return_t
|
||||||
|
getdns_yaml2int(const char *str, uint32_t *value)
|
||||||
|
{
|
||||||
|
#ifdef USE_YAML_CONFIG
|
||||||
|
char *jsonstr;
|
||||||
|
|
||||||
|
if (!str || !value)
|
||||||
|
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
jsonstr = yaml_string_to_json_string(str);
|
||||||
|
if (jsonstr) {
|
||||||
|
getdns_return_t res = getdns_str2int(jsonstr, value);
|
||||||
|
free(jsonstr);
|
||||||
|
return res;
|
||||||
|
} else {
|
||||||
|
return GETDNS_RETURN_GENERIC_ERROR;
|
||||||
|
}
|
||||||
|
#else /* USE_YAML_CONFIG */
|
||||||
|
(void) str;
|
||||||
|
(void) value;
|
||||||
|
return GETDNS_RETURN_NOT_IMPLEMENTED;
|
||||||
|
#endif /* USE_YAML_CONFIG */
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
78
src/debug.h
78
src/debug.h
|
@ -47,45 +47,58 @@
|
||||||
|
|
||||||
#ifdef GETDNS_ON_WINDOWS
|
#ifdef GETDNS_ON_WINDOWS
|
||||||
#define DEBUG_ON(...) do { \
|
#define DEBUG_ON(...) do { \
|
||||||
struct timeval tv; \
|
struct timeval tv_dEbUgSyM; \
|
||||||
struct tm tm; \
|
struct tm tm_dEbUgSyM; \
|
||||||
char buf[10]; \
|
char buf_dEbUgSyM[10]; \
|
||||||
time_t tsec; \
|
time_t tsec_dEbUgSyM; \
|
||||||
\
|
\
|
||||||
gettimeofday(&tv, NULL); \
|
gettimeofday(&tv_dEbUgSyM, NULL); \
|
||||||
tsec = (time_t) tv.tv_sec; \
|
tsec_dEbUgSyM = (time_t) tv_dEbUgSyM.tv_sec; \
|
||||||
gmtime_s(&tm, (const time_t *) &tsec); \
|
gmtime_s(&tm_dEbUgSyM, (const time_t *) &tsec_dEbUgSyM); \
|
||||||
strftime(buf, 10, "%H:%M:%S", &tm); \
|
strftime(buf_dEbUgSyM, 10, "%H:%M:%S", &tm_dEbUgSyM); \
|
||||||
fprintf(stderr, "[%s.%.6d] ", buf, (int)tv.tv_usec); \
|
fprintf(stderr, "[%s.%.6d] ", buf_dEbUgSyM, (int)tv_dEbUgSyM.tv_usec); \
|
||||||
|
fprintf(stderr, __VA_ARGS__); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define DEBUG_NL(...) do { \
|
||||||
|
struct timeval tv_dEbUgSyM; \
|
||||||
|
struct tm tm_dEbUgSyM; \
|
||||||
|
char buf_dEbUgSyM[10]; \
|
||||||
|
time_t tsec_dEbUgSyM; \
|
||||||
|
\
|
||||||
|
gettimeofday(&tv_dEbUgSyM, NULL); \
|
||||||
|
tsec_dEbUgSyM = (time_t) tv_dEbUgSyM.tv_sec; \
|
||||||
|
gmtime_s(&tm_dEbUgSyM, (const time_t *) &tsec_dEbUgSyM); \
|
||||||
|
strftime(buf_dEbUgSyM, 10, "%H:%M:%S", &tm_dEbUgSyM); \
|
||||||
|
fprintf(stderr, "[%s.%.6d] ", buf_dEbUgSyM, (int)tv_dEbUgSyM.tv_usec); \
|
||||||
fprintf(stderr, __VA_ARGS__); \
|
fprintf(stderr, __VA_ARGS__); \
|
||||||
} while (0)
|
} while (0)
|
||||||
#else
|
#else
|
||||||
#define DEBUG_ON(...) do { \
|
#define DEBUG_ON(...) do { \
|
||||||
struct timeval tv; \
|
struct timeval tv_dEbUgSyM; \
|
||||||
struct tm tm; \
|
struct tm tm_dEbUgSyM; \
|
||||||
char buf[10]; \
|
char buf_dEbUgSyM[10]; \
|
||||||
\
|
\
|
||||||
gettimeofday(&tv, NULL); \
|
gettimeofday(&tv_dEbUgSyM, NULL); \
|
||||||
gmtime_r(&tv.tv_sec, &tm); \
|
gmtime_r(&tv_dEbUgSyM.tv_sec, &tm_dEbUgSyM); \
|
||||||
strftime(buf, 10, "%H:%M:%S", &tm); \
|
strftime(buf_dEbUgSyM, 10, "%H:%M:%S", &tm_dEbUgSyM); \
|
||||||
fprintf(stderr, "[%s.%.6d] ", buf, (int)tv.tv_usec); \
|
fprintf(stderr, "[%s.%.6d] ", buf_dEbUgSyM, (int)tv_dEbUgSyM.tv_usec); \
|
||||||
fprintf(stderr, __VA_ARGS__); \
|
fprintf(stderr, __VA_ARGS__); \
|
||||||
} while (0)
|
} while (0)
|
||||||
#endif
|
|
||||||
|
|
||||||
#define DEBUG_NL(...) do { \
|
#define DEBUG_NL(...) do { \
|
||||||
struct timeval tv; \
|
struct timeval tv_dEbUgSyM; \
|
||||||
struct tm tm; \
|
struct tm tm_dEbUgSyM; \
|
||||||
char buf[10]; \
|
char buf_dEbUgSyM[10]; \
|
||||||
\
|
\
|
||||||
gettimeofday(&tv, NULL); \
|
gettimeofday(&tv_dEbUgSyM, NULL); \
|
||||||
gmtime_r(&tv.tv_sec, &tm); \
|
gmtime_r(&tv_dEbUgSyM.tv_sec, &tm_dEbUgSyM); \
|
||||||
strftime(buf, 10, "%H:%M:%S", &tm); \
|
strftime(buf_dEbUgSyM, 10, "%H:%M:%S", &tm_dEbUgSyM); \
|
||||||
fprintf(stderr, "[%s.%.6d] ", buf, (int)tv.tv_usec); \
|
fprintf(stderr, "[%s.%.6d] ", buf_dEbUgSyM, (int)tv_dEbUgSyM.tv_usec); \
|
||||||
fprintf(stderr, __VA_ARGS__); \
|
fprintf(stderr, __VA_ARGS__); \
|
||||||
fprintf(stderr, "\n"); \
|
fprintf(stderr, "\n"); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
#define DEBUG_OFF(...) do {} while (0)
|
#define DEBUG_OFF(...) do {} while (0)
|
||||||
|
|
||||||
|
@ -162,14 +175,25 @@ static inline void debug_req(const char *msg, getdns_network_req *netreq)
|
||||||
#define DEBUG_MDNS(...) DEBUG_OFF(__VA_ARGS__)
|
#define DEBUG_MDNS(...) DEBUG_OFF(__VA_ARGS__)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(ANCHOR_DEBUG) && ANCHOR_DEBUG
|
||||||
|
#include <time.h>
|
||||||
|
#define DEBUG_ANCHOR(...) DEBUG_ON(__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define DEBUG_ANCHOR(...) DEBUG_OFF(__VA_ARGS__)
|
||||||
|
#endif
|
||||||
|
|
||||||
#if (defined(REQ_DEBUG) && REQ_DEBUG) || \
|
#if (defined(REQ_DEBUG) && REQ_DEBUG) || \
|
||||||
(defined(SCHED_DEBUG) && SCHED_DEBUG) || \
|
(defined(SCHED_DEBUG) && SCHED_DEBUG) || \
|
||||||
(defined(STUB_DEBUG) && STUB_DEBUG) || \
|
(defined(STUB_DEBUG) && STUB_DEBUG) || \
|
||||||
(defined(DAEMON_DEBUG) && DAEMON_DEBUG) || \
|
(defined(DAEMON_DEBUG) && DAEMON_DEBUG) || \
|
||||||
(defined(SEC_DEBUG) && SEC_DEBUG) || \
|
(defined(SEC_DEBUG) && SEC_DEBUG) || \
|
||||||
(defined(SERVER_DEBUG) && SERVER_DEBUG) || \
|
(defined(SERVER_DEBUG) && SERVER_DEBUG) || \
|
||||||
(defined(MDNS_DEBUG) && MDNS_DEBUG)
|
(defined(MDNS_DEBUG) && MDNS_DEBUG) || \
|
||||||
|
(defined(ANCHOR_DEBUG) && ANCHOR_DEBUG)
|
||||||
#define DEBUGGING 1
|
#define DEBUGGING 1
|
||||||
|
static inline int
|
||||||
|
_getdns_ERR_print_errors_cb_f(const char *str, size_t len, void *u)
|
||||||
|
{ DEBUG_ON("%.*s (u: %p)\n", (int)len, str, u); return 1; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -34,8 +34,8 @@
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <ctype.h>
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include <ctype.h>
|
||||||
#ifndef USE_WINSOCK
|
#ifndef USE_WINSOCK
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
|
273
src/dnssec.c
273
src/dnssec.c
|
@ -209,6 +209,7 @@
|
||||||
#include "dict.h"
|
#include "dict.h"
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
#include "util/val_secalgo.h"
|
#include "util/val_secalgo.h"
|
||||||
|
#include "anchor.h"
|
||||||
|
|
||||||
#define SIGNATURE_VERIFIED 0x10000
|
#define SIGNATURE_VERIFIED 0x10000
|
||||||
#define NSEC3_ITERATION_COUNT_HIGH 0x20000
|
#define NSEC3_ITERATION_COUNT_HIGH 0x20000
|
||||||
|
@ -601,7 +602,7 @@ static chain_head *add_rrset2val_chain(struct mem_funcs *mf,
|
||||||
dname_len = *labels - last_label[-1] + 1;
|
dname_len = *labels - last_label[-1] + 1;
|
||||||
head_sz = (sizeof(chain_head) + dname_len + 7) / 8 * 8;
|
head_sz = (sizeof(chain_head) + dname_len + 7) / 8 * 8;
|
||||||
node_count = last_label - labels - max_labels;
|
node_count = last_label - labels - max_labels;
|
||||||
DEBUG_SEC( PRIsz" labels in common. "PRIsz" labels to allocate\n"
|
DEBUG_SEC( "%"PRIsz" labels in common. %"PRIsz" labels to allocate\n"
|
||||||
, max_labels, node_count);
|
, max_labels, node_count);
|
||||||
|
|
||||||
if (! (region = GETDNS_XMALLOC(*mf, uint8_t, head_sz +
|
if (! (region = GETDNS_XMALLOC(*mf, uint8_t, head_sz +
|
||||||
|
@ -801,11 +802,14 @@ static void add_pkt2val_chain(struct mem_funcs *mf,
|
||||||
if (is_synthesized_cname(rrset))
|
if (is_synthesized_cname(rrset))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (!(rrsig = _getdns_rrsig_iter_init(&rrsig_spc, rrset))
|
||||||
|
&& _getdns_rr_iter_section(&i->rr_i) != SECTION_ANSWER)
|
||||||
|
continue; /* No sigs in authority section is okayish */
|
||||||
|
|
||||||
if (!(head = add_rrset2val_chain(mf, chain_p, rrset, netreq)))
|
if (!(head = add_rrset2val_chain(mf, chain_p, rrset, netreq)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for ( rrsig = _getdns_rrsig_iter_init(&rrsig_spc, rrset), n_rrsigs = 0
|
for ( n_rrsigs = 0; rrsig
|
||||||
; rrsig
|
|
||||||
; rrsig = _getdns_rrsig_iter_next(rrsig), n_rrsigs++) {
|
; rrsig = _getdns_rrsig_iter_next(rrsig), n_rrsigs++) {
|
||||||
|
|
||||||
/* Signature, so lookup DS/DNSKEY at signer's name */
|
/* Signature, so lookup DS/DNSKEY at signer's name */
|
||||||
|
@ -933,6 +937,17 @@ static void val_chain_sched_soa(chain_head *head, const uint8_t *dname)
|
||||||
val_chain_sched_soa_node(node);
|
val_chain_sched_soa_node(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static chain_head *_dnskey_query(const chain_node *node)
|
||||||
|
{
|
||||||
|
chain_head *head;
|
||||||
|
|
||||||
|
for (head = node->chains; head; head = head->next)
|
||||||
|
if (head->rrset.rr_type == GETDNS_RRTYPE_DNSKEY &&
|
||||||
|
head->parent == node)
|
||||||
|
return head;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static void val_chain_node_cb(getdns_dns_req *dnsreq);
|
static void val_chain_node_cb(getdns_dns_req *dnsreq);
|
||||||
static void val_chain_sched_node(chain_node *node)
|
static void val_chain_sched_node(chain_node *node)
|
||||||
{
|
{
|
||||||
|
@ -950,13 +965,27 @@ static void val_chain_sched_node(chain_node *node)
|
||||||
DEBUG_SEC("schedule DS & DNSKEY lookup for %s\n", name);
|
DEBUG_SEC("schedule DS & DNSKEY lookup for %s\n", name);
|
||||||
|
|
||||||
node->lock++;
|
node->lock++;
|
||||||
if (! node->dnskey_req /* not scheduled */ &&
|
if (! node->dnskey_req) {
|
||||||
_getdns_general_loop(context, loop, name, GETDNS_RRTYPE_DNSKEY,
|
chain_head *head;
|
||||||
CD_extension(node->chains->netreq->owner),
|
|
||||||
node, &node->dnskey_req, NULL, val_chain_node_cb))
|
|
||||||
|
|
||||||
node->dnskey_req = NULL;
|
/* Reuse the DNSKEY query if this node is scheduled in the
|
||||||
|
* context of validating a DNSKEY query, because libunbound
|
||||||
|
* does not callback from a callback for the same query.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ((head = _dnskey_query(node))) {
|
||||||
|
DEBUG_SEC("Found DNSKEY head: %p\n", (void *)head);
|
||||||
|
node->dnskey_req = head->netreq;
|
||||||
|
node->dnskey.pkt = head->netreq->response;
|
||||||
|
node->dnskey.pkt_len = head->netreq->response_len;
|
||||||
|
|
||||||
|
} else if (_getdns_general_loop(
|
||||||
|
context, loop, name, GETDNS_RRTYPE_DNSKEY,
|
||||||
|
CD_extension(node->chains->netreq->owner),
|
||||||
|
node, &node->dnskey_req, NULL, val_chain_node_cb))
|
||||||
|
|
||||||
|
node->dnskey_req = NULL;
|
||||||
|
}
|
||||||
if (! node->ds_req && node->parent /* not root */ &&
|
if (! node->ds_req && node->parent /* not root */ &&
|
||||||
_getdns_general_loop(context, loop, name, GETDNS_RRTYPE_DS,
|
_getdns_general_loop(context, loop, name, GETDNS_RRTYPE_DS,
|
||||||
CD_extension(node->chains->netreq->owner),
|
CD_extension(node->chains->netreq->owner),
|
||||||
|
@ -1423,7 +1452,7 @@ static int _getdns_verify_rrsig(struct mem_funcs *mf,
|
||||||
/* More space needed for val_rrset */
|
/* More space needed for val_rrset */
|
||||||
val_rrset = GETDNS_XMALLOC(*mf, _getdns_rr_iter, n_rrs);
|
val_rrset = GETDNS_XMALLOC(*mf, _getdns_rr_iter, n_rrs);
|
||||||
}
|
}
|
||||||
DEBUG_SEC( "sizes: "PRIsz" rrs, "PRIsz" bytes for validation buffer\n"
|
DEBUG_SEC( "sizes: %"PRIsz" rrs, %"PRIsz" bytes for validation buffer\n"
|
||||||
, n_rrs, valbuf_sz);
|
, n_rrs, valbuf_sz);
|
||||||
|
|
||||||
qsort(val_rrset, n_rrs, sizeof(_getdns_rr_iter), _rr_iter_rdata_cmp);
|
qsort(val_rrset, n_rrs, sizeof(_getdns_rr_iter), _rr_iter_rdata_cmp);
|
||||||
|
@ -1480,7 +1509,7 @@ static int _getdns_verify_rrsig(struct mem_funcs *mf,
|
||||||
gldns_buffer_write_u16_at(&valbuf, pos,
|
gldns_buffer_write_u16_at(&valbuf, pos,
|
||||||
(uint16_t)(gldns_buffer_position(&valbuf) - pos - 2));
|
(uint16_t)(gldns_buffer_position(&valbuf) - pos - 2));
|
||||||
}
|
}
|
||||||
DEBUG_SEC( "written to valbuf: "PRIsz" bytes\n"
|
DEBUG_SEC( "written to valbuf: %"PRIsz" bytes\n"
|
||||||
, gldns_buffer_position(&valbuf));
|
, gldns_buffer_position(&valbuf));
|
||||||
assert(gldns_buffer_position(&valbuf) <= valbuf_sz);
|
assert(gldns_buffer_position(&valbuf) <= valbuf_sz);
|
||||||
|
|
||||||
|
@ -1902,7 +1931,7 @@ static int ds_authenticates_keys(struct mem_funcs *mf,
|
||||||
if (digest_buf != digest_buf_spc)
|
if (digest_buf != digest_buf_spc)
|
||||||
GETDNS_FREE(*mf, digest_buf);
|
GETDNS_FREE(*mf, digest_buf);
|
||||||
|
|
||||||
DEBUG_SEC("HASH length mismatch "PRIsz" != "PRIsz"\n",
|
DEBUG_SEC("HASH length mismatch %"PRIsz" != %"PRIsz"\n",
|
||||||
digest_len, ds->rr_i.nxt - ds->rr_i.rr_type-14);
|
digest_len, ds->rr_i.nxt - ds->rr_i.rr_type-14);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1925,7 +1954,7 @@ static int ds_authenticates_keys(struct mem_funcs *mf,
|
||||||
max_supported_result = SIGNATURE_VERIFIED | keytag;
|
max_supported_result = SIGNATURE_VERIFIED | keytag;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DEBUG_SEC("valid_dsses: "PRIsz", supported_dsses: "PRIsz"\n",
|
DEBUG_SEC("valid_dsses: %"PRIsz", supported_dsses: %"PRIsz"\n",
|
||||||
valid_dsses, supported_dsses);
|
valid_dsses, supported_dsses);
|
||||||
if (valid_dsses && !supported_dsses)
|
if (valid_dsses && !supported_dsses)
|
||||||
return NO_SUPPORTED_ALGORITHMS;
|
return NO_SUPPORTED_ALGORITHMS;
|
||||||
|
@ -2522,6 +2551,11 @@ static int chain_node_get_trusted_keys(
|
||||||
node->dnskey_signer = keytag;
|
node->dnskey_signer = keytag;
|
||||||
return GETDNS_DNSSEC_SECURE;
|
return GETDNS_DNSSEC_SECURE;
|
||||||
}
|
}
|
||||||
|
/* ta is the DNSKEY for this name? */
|
||||||
|
if (_dname_equal(ta->name, node->dnskey.name)) {
|
||||||
|
*keys = ta;
|
||||||
|
return GETDNS_DNSSEC_SECURE;
|
||||||
|
}
|
||||||
/* ta is parent's ZSK */
|
/* ta is parent's ZSK */
|
||||||
if ((keytag = key_proves_nonexistance(
|
if ((keytag = key_proves_nonexistance(
|
||||||
mf, now, skew, ta, &node->ds, NULL))) {
|
mf, now, skew, ta, &node->ds, NULL))) {
|
||||||
|
@ -2544,8 +2578,13 @@ static int chain_node_get_trusted_keys(
|
||||||
} else
|
} else
|
||||||
return GETDNS_DNSSEC_BOGUS;
|
return GETDNS_DNSSEC_BOGUS;
|
||||||
|
|
||||||
if (GETDNS_DNSSEC_SECURE != (s = chain_node_get_trusted_keys(
|
s = chain_node_get_trusted_keys(mf, now, skew, node->parent, ta, keys);
|
||||||
mf, now, skew, node->parent, ta, keys)))
|
/* Set dnssec status on root DNSKEY request (for TA management) */
|
||||||
|
if (!node->parent && node->dnskey_req &&
|
||||||
|
node->dnskey.name && *node->dnskey.name == 0)
|
||||||
|
node->dnskey_req->dnssec_status = s;
|
||||||
|
|
||||||
|
if (s != GETDNS_DNSSEC_SECURE)
|
||||||
return s;
|
return s;
|
||||||
|
|
||||||
/* keys is an authenticated dnskey rrset always now (i.e. ZSK) */
|
/* keys is an authenticated dnskey rrset always now (i.e. ZSK) */
|
||||||
|
@ -2750,6 +2789,33 @@ static void chain_set_netreq_dnssec_status(chain_head *chain, _getdns_rrset_iter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void chain_clear_netreq_dnssec_status(chain_head *chain)
|
||||||
|
{
|
||||||
|
chain_head *head;
|
||||||
|
size_t node_count;
|
||||||
|
chain_node *node;
|
||||||
|
|
||||||
|
/* The netreq status is the worst for any head */
|
||||||
|
for (head = chain; head; head = head->next) {
|
||||||
|
if (!head->netreq)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
head->netreq->dnssec_status = GETDNS_DNSSEC_INDETERMINATE;
|
||||||
|
for ( node_count = head->node_count, node = head->parent
|
||||||
|
; node && node_count ; node_count--, node = node->parent ) {
|
||||||
|
|
||||||
|
node->ds_signer = -1;
|
||||||
|
node->dnskey_signer = -1;
|
||||||
|
|
||||||
|
if ( ! node->parent && node->dnskey_req
|
||||||
|
&& node->dnskey.name && !*node->dnskey.name) {
|
||||||
|
node->dnskey_req->dnssec_status =
|
||||||
|
GETDNS_DNSSEC_INDETERMINATE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* The DNSSEC status of all heads for a chain structure is evaluated by
|
/* The DNSSEC status of all heads for a chain structure is evaluated by
|
||||||
|
@ -2905,6 +2971,26 @@ static void append_rrset2val_chain_list(
|
||||||
_getdns_list_append_this_dict(val_chain_list, rr_dict))
|
_getdns_list_append_this_dict(val_chain_list, rr_dict))
|
||||||
getdns_dict_destroy(rr_dict);
|
getdns_dict_destroy(rr_dict);
|
||||||
|
|
||||||
|
/* Append the other RRSIGs, which were not used for validation too,
|
||||||
|
* because other validators might not have the same algorithm support.
|
||||||
|
*/
|
||||||
|
for ( rrsig = _getdns_rrsig_iter_init(&rrsig_spc, rrset)
|
||||||
|
; rrsig
|
||||||
|
; rrsig = _getdns_rrsig_iter_next(rrsig)) {
|
||||||
|
|
||||||
|
if (rrsig->rr_i.nxt < rrsig->rr_i.rr_type + 28)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (gldns_read_uint16(rrsig->rr_i.rr_type + 26)
|
||||||
|
== (signer & 0xFFFF))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
orig_ttl = gldns_read_uint32(rrsig->rr_i.rr_type + 14);
|
||||||
|
if ((rr_dict = _getdns_rr_iter2rr_dict_canonical(
|
||||||
|
&val_chain_list->mf, &rrsig->rr_i, &orig_ttl)) &&
|
||||||
|
_getdns_list_append_this_dict(val_chain_list, rr_dict))
|
||||||
|
getdns_dict_destroy(rr_dict);
|
||||||
|
}
|
||||||
if (val_rrset != val_rrset_spc)
|
if (val_rrset != val_rrset_spc)
|
||||||
GETDNS_FREE(val_chain_list->mf, val_rrset);
|
GETDNS_FREE(val_chain_list->mf, val_rrset);
|
||||||
}
|
}
|
||||||
|
@ -2999,6 +3085,22 @@ static void append_empty_ds2val_chain_list(
|
||||||
if (_getdns_list_append_this_dict(val_chain_list, rr_dict))
|
if (_getdns_list_append_this_dict(val_chain_list, rr_dict))
|
||||||
getdns_dict_destroy(rr_dict);
|
getdns_dict_destroy(rr_dict);
|
||||||
}
|
}
|
||||||
|
static inline chain_node *_to_the_root(chain_node *node)
|
||||||
|
{
|
||||||
|
while (node->parent) node = node->parent;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _getdns_bogus(getdns_dns_req *dnsreq)
|
||||||
|
{
|
||||||
|
getdns_network_req **netreq_p, *netreq;
|
||||||
|
|
||||||
|
for (netreq_p = dnsreq->netreqs; (netreq = *netreq_p) ; netreq_p++) {
|
||||||
|
if (netreq->dnssec_status == GETDNS_DNSSEC_BOGUS)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void _cleanup_chain(chain_head *chain,
|
static void _cleanup_chain(chain_head *chain,
|
||||||
getdns_list *val_chain_list, int full)
|
getdns_list *val_chain_list, int full)
|
||||||
|
@ -3078,30 +3180,40 @@ static void check_chain_complete(chain_head *chain)
|
||||||
_getdns_rrset_iter tas_iter;
|
_getdns_rrset_iter tas_iter;
|
||||||
|
|
||||||
if ((o = count_outstanding_requests(chain)) > 0) {
|
if ((o = count_outstanding_requests(chain)) > 0) {
|
||||||
DEBUG_SEC(PRIsz" outstanding requests\n", o);
|
DEBUG_SEC("%"PRIsz" outstanding requests\n", o);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DEBUG_SEC("Chain done!\n");
|
DEBUG_SEC("Chain done!\n");
|
||||||
dnsreq = chain->netreq->owner;
|
dnsreq = chain->netreq->owner;
|
||||||
context = dnsreq->context;
|
context = dnsreq->context;
|
||||||
|
|
||||||
|
if (dnsreq->waiting_for_ta) {
|
||||||
|
getdns_dns_req **d;
|
||||||
|
|
||||||
|
for (d = &context->ta_notify; *d; d = &(*d)->ta_notify) {
|
||||||
|
if (*d == dnsreq) {
|
||||||
|
*d = dnsreq->ta_notify;
|
||||||
|
dnsreq->ta_notify = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (context->trust_anchors_source == GETDNS_TASRC_FETCHING) {
|
||||||
|
dnsreq->waiting_for_ta = 1;
|
||||||
|
dnsreq->ta_notify = context->ta_notify;
|
||||||
|
context->ta_notify = dnsreq;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
#ifdef STUB_NATIVE_DNSSEC
|
#ifdef STUB_NATIVE_DNSSEC
|
||||||
/* Perform validation only on GETDNS_RESOLUTION_STUB (unbound_id == -1)
|
if (context->trust_anchors)
|
||||||
* Or when asked for the validation chain (to identify the RRSIGs that
|
|
||||||
* signed the RRSETs, so that only those will be included in the
|
|
||||||
* validation chain)
|
|
||||||
* In any case we must have a trust anchor.
|
|
||||||
*/
|
|
||||||
if (( chain->netreq->unbound_id == -1
|
|
||||||
|| dnsreq->dnssec_return_validation_chain)
|
|
||||||
&& context->trust_anchors)
|
|
||||||
|
|
||||||
chain_set_netreq_dnssec_status(chain,_getdns_rrset_iter_init(&tas_iter,
|
chain_set_netreq_dnssec_status(chain,_getdns_rrset_iter_init(&tas_iter,
|
||||||
context->trust_anchors, context->trust_anchors_len,
|
context->trust_anchors, context->trust_anchors_len,
|
||||||
SECTION_ANSWER));
|
SECTION_ANSWER));
|
||||||
#else
|
#else
|
||||||
if (dnsreq->dnssec_return_validation_chain
|
if (context->trust_anchors)
|
||||||
&& context->trust_anchors)
|
|
||||||
|
|
||||||
(void) chain_validate_dnssec(priv_getdns_context_mf(context),
|
(void) chain_validate_dnssec(priv_getdns_context_mf(context),
|
||||||
time(NULL), context->dnssec_allowed_skew,
|
time(NULL), context->dnssec_allowed_skew,
|
||||||
|
@ -3110,10 +3222,52 @@ static void check_chain_complete(chain_head *chain)
|
||||||
, context->trust_anchors_len
|
, context->trust_anchors_len
|
||||||
, SECTION_ANSWER));
|
, SECTION_ANSWER));
|
||||||
#endif
|
#endif
|
||||||
|
if (context->trust_anchors_source == GETDNS_TASRC_XML) {
|
||||||
|
if ((head = chain) && (node = _to_the_root(head->parent)) &&
|
||||||
|
node->dnskey.name && *node->dnskey.name == 0)
|
||||||
|
_getdns_context_update_root_ksk(context,&node->dnskey);
|
||||||
|
|
||||||
|
} else if (_getdns_bogus(dnsreq)) {
|
||||||
|
DEBUG_ANCHOR("Request was bogus!\n");
|
||||||
|
|
||||||
|
if ((head = chain) && (node = _to_the_root(head->parent))
|
||||||
|
&& node->dnskey.name && *node->dnskey.name == 0
|
||||||
|
&& node->dnskey_req->dnssec_status == GETDNS_DNSSEC_BOGUS){
|
||||||
|
|
||||||
|
DEBUG_ANCHOR("root DNSKEY set was bogus!\n");
|
||||||
|
if (!dnsreq->waiting_for_ta) {
|
||||||
|
uint64_t now = 0;
|
||||||
|
|
||||||
|
dnsreq->waiting_for_ta = 1;
|
||||||
|
_getdns_context_equip_with_anchor(
|
||||||
|
context, &now);
|
||||||
|
|
||||||
|
if (context->trust_anchors_source
|
||||||
|
== GETDNS_TASRC_XML) {
|
||||||
|
chain_clear_netreq_dnssec_status(chain);
|
||||||
|
check_chain_complete(chain);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_getdns_start_fetching_ta(
|
||||||
|
context, dnsreq->loop);
|
||||||
|
|
||||||
|
if (dnsreq->waiting_for_ta &&
|
||||||
|
context->trust_anchors_source
|
||||||
|
== GETDNS_TASRC_FETCHING) {
|
||||||
|
|
||||||
|
chain_clear_netreq_dnssec_status(chain);
|
||||||
|
dnsreq->ta_notify = context->ta_notify;
|
||||||
|
context->ta_notify = dnsreq;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DNSSEC_ROADBLOCK_AVOIDANCE
|
#ifdef DNSSEC_ROADBLOCK_AVOIDANCE
|
||||||
if ( dnsreq->dnssec_roadblock_avoidance
|
if ( dnsreq->dnssec_roadblock_avoidance
|
||||||
&& !dnsreq->avoid_dnssec_roadblocks
|
&& !dnsreq->avoid_dnssec_roadblocks
|
||||||
&& dnsreq->netreqs[0]->dnssec_status == GETDNS_DNSSEC_BOGUS) {
|
&& _getdns_bogus(dnsreq)) {
|
||||||
|
|
||||||
getdns_network_req **netreq_p, *netreq;
|
getdns_network_req **netreq_p, *netreq;
|
||||||
uint64_t now_ms = 0;
|
uint64_t now_ms = 0;
|
||||||
|
@ -3167,6 +3321,7 @@ static void check_chain_complete(chain_head *chain)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
dnsreq->waiting_for_ta = 0;
|
||||||
val_chain_list = dnsreq->dnssec_return_validation_chain
|
val_chain_list = dnsreq->dnssec_return_validation_chain
|
||||||
? getdns_list_create_with_context(context) : NULL;
|
? getdns_list_create_with_context(context) : NULL;
|
||||||
|
|
||||||
|
@ -3185,6 +3340,45 @@ static void check_chain_complete(chain_head *chain)
|
||||||
_getdns_call_user_callback(dnsreq, response_dict);
|
_getdns_call_user_callback(dnsreq, response_dict);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _getdns_ta_notify_dnsreqs(getdns_context *context)
|
||||||
|
{
|
||||||
|
getdns_dns_req **dnsreq_p, *dnsreq = NULL;
|
||||||
|
uint64_t now_ms = 0;
|
||||||
|
|
||||||
|
assert(context);
|
||||||
|
|
||||||
|
if (context->trust_anchors_source == GETDNS_TASRC_NONE ||
|
||||||
|
context->trust_anchors_source == GETDNS_TASRC_FETCHING)
|
||||||
|
return;
|
||||||
|
|
||||||
|
dnsreq_p = &context->ta_notify;
|
||||||
|
while ((dnsreq = *dnsreq_p)) {
|
||||||
|
assert(dnsreq->waiting_for_ta);
|
||||||
|
|
||||||
|
if (dnsreq->chain)
|
||||||
|
check_chain_complete(dnsreq->chain);
|
||||||
|
else {
|
||||||
|
getdns_network_req *netreq, **netreq_p;
|
||||||
|
int r = GETDNS_RETURN_GOOD;
|
||||||
|
|
||||||
|
(void) _getdns_context_prepare_for_resolution(context);
|
||||||
|
|
||||||
|
*dnsreq_p = dnsreq->ta_notify;
|
||||||
|
for ( netreq_p = dnsreq->netreqs
|
||||||
|
; !r && (netreq = *netreq_p)
|
||||||
|
; netreq_p++ ) {
|
||||||
|
|
||||||
|
if (!(r = _getdns_submit_netreq(netreq, &now_ms)))
|
||||||
|
continue;
|
||||||
|
if (r == DNS_REQ_FINISHED)
|
||||||
|
break;
|
||||||
|
_getdns_netreq_change_state(netreq, NET_REQ_ERRORED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(*dnsreq_p != dnsreq);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void _getdns_validation_chain_timeout(getdns_dns_req *dnsreq)
|
void _getdns_validation_chain_timeout(getdns_dns_req *dnsreq)
|
||||||
{
|
{
|
||||||
chain_head *head = dnsreq->chain, *next;
|
chain_head *head = dnsreq->chain, *next;
|
||||||
|
@ -3224,7 +3418,7 @@ void _getdns_validation_chain_timeout(getdns_dns_req *dnsreq)
|
||||||
|
|
||||||
void _getdns_cancel_validation_chain(getdns_dns_req *dnsreq)
|
void _getdns_cancel_validation_chain(getdns_dns_req *dnsreq)
|
||||||
{
|
{
|
||||||
chain_head *head = dnsreq->chain, *next;
|
chain_head *head = dnsreq->chain, *next, *dnskey_head;
|
||||||
chain_node *node;
|
chain_node *node;
|
||||||
size_t node_count;
|
size_t node_count;
|
||||||
|
|
||||||
|
@ -3236,7 +3430,10 @@ void _getdns_cancel_validation_chain(getdns_dns_req *dnsreq)
|
||||||
; node_count
|
; node_count
|
||||||
; node_count--, node = node->parent ) {
|
; node_count--, node = node->parent ) {
|
||||||
|
|
||||||
if (node->dnskey_req)
|
if (node->dnskey_req &&
|
||||||
|
!( (dnskey_head = _dnskey_query(node))
|
||||||
|
&& dnskey_head->netreq == node->dnskey_req))
|
||||||
|
|
||||||
_getdns_context_cancel_request(
|
_getdns_context_cancel_request(
|
||||||
node->dnskey_req->owner);
|
node->dnskey_req->owner);
|
||||||
|
|
||||||
|
@ -3267,6 +3464,7 @@ void _getdns_get_validation_chain(getdns_dns_req *dnsreq)
|
||||||
|
|
||||||
if (dnsreq->avoid_dnssec_roadblocks && chain->lock == 0)
|
if (dnsreq->avoid_dnssec_roadblocks && chain->lock == 0)
|
||||||
; /* pass */
|
; /* pass */
|
||||||
|
|
||||||
else for (netreq_p = dnsreq->netreqs; (netreq = *netreq_p) ; netreq_p++) {
|
else for (netreq_p = dnsreq->netreqs; (netreq = *netreq_p) ; netreq_p++) {
|
||||||
if (! netreq->response
|
if (! netreq->response
|
||||||
|| netreq->response_len < GLDNS_HEADER_SIZE
|
|| netreq->response_len < GLDNS_HEADER_SIZE
|
||||||
|
@ -3277,7 +3475,10 @@ void _getdns_get_validation_chain(getdns_dns_req *dnsreq)
|
||||||
|
|
||||||
netreq->dnssec_status = GETDNS_DNSSEC_INSECURE;
|
netreq->dnssec_status = GETDNS_DNSSEC_INSECURE;
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
} else if (netreq->unbound_id != -1)
|
||||||
|
netreq->dnssec_status = GETDNS_DNSSEC_INDETERMINATE;
|
||||||
|
|
||||||
add_pkt2val_chain( &dnsreq->my_mf, &chain
|
add_pkt2val_chain( &dnsreq->my_mf, &chain
|
||||||
, netreq->response, netreq->response_len
|
, netreq->response, netreq->response_len
|
||||||
, netreq
|
, netreq
|
||||||
|
@ -3415,13 +3616,17 @@ getdns_validate_dnssec3(const getdns_list *records_to_validate,
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!records_to_validate || !support_records || !trust_anchors)
|
if (!records_to_validate || !trust_anchors)
|
||||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||||
mf = (struct mem_funcs *)&records_to_validate->mf;
|
mf = (struct mem_funcs *)&records_to_validate->mf;
|
||||||
|
|
||||||
/* First convert everything to wire format
|
/* First convert everything to wire format
|
||||||
*/
|
*/
|
||||||
if (!(support = _getdns_list2wire(support_records,
|
|
||||||
|
if (!support_records)
|
||||||
|
(void) memset((support = support_buf), 0, GLDNS_HEADER_SIZE);
|
||||||
|
|
||||||
|
else if (!(support = _getdns_list2wire(support_records,
|
||||||
support_buf, &support_len, mf)))
|
support_buf, &support_len, mf)))
|
||||||
return GETDNS_RETURN_MEMORY_ERROR;
|
return GETDNS_RETURN_MEMORY_ERROR;
|
||||||
|
|
||||||
|
@ -3440,7 +3645,7 @@ getdns_validate_dnssec3(const getdns_list *records_to_validate,
|
||||||
|
|
||||||
for (i = 0; !getdns_list_get_dict(records_to_validate,i,&reply); i++) {
|
for (i = 0; !getdns_list_get_dict(records_to_validate,i,&reply); i++) {
|
||||||
|
|
||||||
DEBUG_SEC("REPLY "PRIsz", r: %d\n", i, r);
|
DEBUG_SEC("REPLY %"PRIsz", r: %d\n", i, r);
|
||||||
if (to_val != to_val_buf)
|
if (to_val != to_val_buf)
|
||||||
GETDNS_FREE(*mf, to_val);
|
GETDNS_FREE(*mf, to_val);
|
||||||
to_val_len = sizeof(to_val_buf);
|
to_val_len = sizeof(to_val_buf);
|
||||||
|
@ -3468,7 +3673,7 @@ getdns_validate_dnssec3(const getdns_list *records_to_validate,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DEBUG_SEC("REPLY "PRIsz", r: %d\n", i, r);
|
DEBUG_SEC("REPLY %"PRIsz", r: %d\n", i, r);
|
||||||
|
|
||||||
exit_free_to_val:
|
exit_free_to_val:
|
||||||
if (to_val != to_val_buf)
|
if (to_val != to_val_buf)
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
void _getdns_get_validation_chain(getdns_dns_req *dns_req);
|
void _getdns_get_validation_chain(getdns_dns_req *dns_req);
|
||||||
void _getdns_cancel_validation_chain(getdns_dns_req *dns_req);
|
void _getdns_cancel_validation_chain(getdns_dns_req *dns_req);
|
||||||
void _getdns_validation_chain_timeout(getdns_dns_req *dns_req);
|
void _getdns_validation_chain_timeout(getdns_dns_req *dns_req);
|
||||||
|
void _getdns_ta_notify_dnsreqs(getdns_context *context);
|
||||||
|
|
||||||
uint16_t _getdns_parse_ta_file(time_t *ta_mtime, gldns_buffer *gbuf);
|
uint16_t _getdns_parse_ta_file(time_t *ta_mtime, gldns_buffer *gbuf);
|
||||||
|
|
||||||
|
@ -66,6 +67,8 @@ static inline int _dnssec_rdata_to_canonicalize(uint16_t rr_type)
|
||||||
|| rr_type == GLDNS_RR_TYPE_DNAME || rr_type == GLDNS_RR_TYPE_RRSIG;
|
|| rr_type == GLDNS_RR_TYPE_DNAME || rr_type == GLDNS_RR_TYPE_RRSIG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int _getdns_bogus(getdns_dns_req *dns_req);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* dnssec.h */
|
/* dnssec.h */
|
||||||
|
|
|
@ -172,6 +172,9 @@ getdns_libuv_timeout_cb(uv_timer_t *timer, int status)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
getdns_eventloop_event *el_ev = (getdns_eventloop_event *)timer->data;
|
getdns_eventloop_event *el_ev = (getdns_eventloop_event *)timer->data;
|
||||||
|
#ifndef HAVE_NEW_UV_TIMER_CB
|
||||||
|
(void)status;
|
||||||
|
#endif
|
||||||
assert(el_ev->timeout_cb);
|
assert(el_ev->timeout_cb);
|
||||||
DEBUG_UV("enter libuv_timeout_cb(el_ev = %p, el_ev->ev = %p)\n"
|
DEBUG_UV("enter libuv_timeout_cb(el_ev = %p, el_ev->ev = %p)\n"
|
||||||
, el_ev, el_ev->ev);
|
, el_ev, el_ev->ev);
|
||||||
|
|
|
@ -27,13 +27,8 @@
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#ifdef HAVE_SYS_POLL_H
|
#include "util-internal.h"
|
||||||
#include <sys/poll.h>
|
#include "platform.h"
|
||||||
#else
|
|
||||||
#ifndef USE_WINSOCK
|
|
||||||
#include <poll.h>
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SYS_RESOURCE_H
|
#ifdef HAVE_SYS_RESOURCE_H
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -148,7 +143,7 @@ static uint64_t get_now_plus(uint64_t amount)
|
||||||
uint64_t now;
|
uint64_t now;
|
||||||
|
|
||||||
if (gettimeofday(&tv, NULL)) {
|
if (gettimeofday(&tv, NULL)) {
|
||||||
perror("gettimeofday() failed");
|
_getdns_perror("gettimeofday() failed");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
now = tv.tv_sec * 1000000 + tv.tv_usec;
|
now = tv.tv_sec * 1000000 + tv.tv_usec;
|
||||||
|
@ -296,7 +291,8 @@ poll_read_cb(int fd, getdns_eventloop_event *event)
|
||||||
(void)fd;
|
(void)fd;
|
||||||
#endif
|
#endif
|
||||||
DEBUG_SCHED( "%s(fd: %d, event: %p)\n", __FUNC__, fd, (void *)event);
|
DEBUG_SCHED( "%s(fd: %d, event: %p)\n", __FUNC__, fd, (void *)event);
|
||||||
event->read_cb(event->userarg);
|
if (event && event->read_cb)
|
||||||
|
event->read_cb(event->userarg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -306,14 +302,16 @@ poll_write_cb(int fd, getdns_eventloop_event *event)
|
||||||
(void)fd;
|
(void)fd;
|
||||||
#endif
|
#endif
|
||||||
DEBUG_SCHED( "%s(fd: %d, event: %p)\n", __FUNC__, fd, (void *)event);
|
DEBUG_SCHED( "%s(fd: %d, event: %p)\n", __FUNC__, fd, (void *)event);
|
||||||
event->write_cb(event->userarg);
|
if (event && event->write_cb)
|
||||||
|
event->write_cb(event->userarg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
poll_timeout_cb(getdns_eventloop_event *event)
|
poll_timeout_cb(getdns_eventloop_event *event)
|
||||||
{
|
{
|
||||||
DEBUG_SCHED( "%s(event: %p)\n", __FUNC__, (void *)event);
|
DEBUG_SCHED( "%s(event: %p)\n", __FUNC__, (void *)event);
|
||||||
event->timeout_cb(event->userarg);
|
if (event && event->timeout_cb)
|
||||||
|
event->timeout_cb(event->userarg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -408,11 +406,9 @@ poll_eventloop_run_once(getdns_eventloop *loop, int blocking)
|
||||||
{
|
{
|
||||||
Sleep(poll_timeout);
|
Sleep(poll_timeout);
|
||||||
} else
|
} else
|
||||||
if (WSAPoll(poll_loop->pfds, poll_loop->fd_events_free, poll_timeout) < 0) {
|
|
||||||
#else
|
|
||||||
if (poll(poll_loop->pfds, poll_loop->fd_events_free, poll_timeout) < 0) {
|
|
||||||
#endif
|
#endif
|
||||||
perror("poll() failed");
|
if (_getdns_poll(poll_loop->pfds, poll_loop->fd_events_free, poll_timeout) < 0) {
|
||||||
|
_getdns_perror("poll() failed");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
now = get_now_plus(0);
|
now = get_now_plus(0);
|
||||||
|
|
|
@ -27,9 +27,10 @@
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include "extension/select_eventloop.h"
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "types-internal.h"
|
#include "types-internal.h"
|
||||||
|
#include "platform.h"
|
||||||
|
#include "extension/select_eventloop.h"
|
||||||
|
|
||||||
static uint64_t get_now_plus(uint64_t amount)
|
static uint64_t get_now_plus(uint64_t amount)
|
||||||
{
|
{
|
||||||
|
@ -37,7 +38,7 @@ static uint64_t get_now_plus(uint64_t amount)
|
||||||
uint64_t now;
|
uint64_t now;
|
||||||
|
|
||||||
if (gettimeofday(&tv, NULL)) {
|
if (gettimeofday(&tv, NULL)) {
|
||||||
perror("gettimeofday() failed");
|
_getdns_perror("gettimeofday() failed");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
now = tv.tv_sec * 1000000 + tv.tv_usec;
|
now = tv.tv_sec * 1000000 + tv.tv_usec;
|
||||||
|
@ -235,20 +236,21 @@ select_eventloop_run_once(getdns_eventloop *loop, int blocking)
|
||||||
tv.tv_usec = (long)((timeout - now) % 1000000);
|
tv.tv_usec = (long)((timeout - now) % 1000000);
|
||||||
}
|
}
|
||||||
#ifdef USE_WINSOCK
|
#ifdef USE_WINSOCK
|
||||||
if (max_fd == -1)
|
if (max_fd == -1) {
|
||||||
{
|
if (timeout != TIMEOUT_FOREVER) {
|
||||||
if (timeout != TIMEOUT_FOREVER)
|
uint32_t timeout_ms = (tv.tv_usec / 1000) + (tv.tv_sec * 1000);
|
||||||
{
|
Sleep(timeout_ms);
|
||||||
uint32_t timeout_ms = (tv.tv_usec / 1000) + (tv.tv_sec * 1000);
|
}
|
||||||
Sleep(timeout_ms);
|
} else {
|
||||||
}
|
|
||||||
} else
|
|
||||||
#endif
|
#endif
|
||||||
if (select(max_fd + 1, &readfds, &writefds, NULL,
|
if (select(max_fd + 1, &readfds, &writefds, NULL,
|
||||||
(timeout == TIMEOUT_FOREVER ? NULL : &tv)) < 0) {
|
(timeout == TIMEOUT_FOREVER ? NULL : &tv)) < 0) {
|
||||||
perror("select() failed");
|
_getdns_perror("select() failed");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
#ifdef USE_WINSOCK
|
||||||
|
}
|
||||||
|
#endif
|
||||||
now = get_now_plus(0);
|
now = get_now_plus(0);
|
||||||
for (fd = 0; fd < (int)FD_SETSIZE; fd++) {
|
for (fd = 0; fd < (int)FD_SETSIZE; fd++) {
|
||||||
if (select_loop->fd_events[fd] &&
|
if (select_loop->fd_events[fd] &&
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "getdns/getdns.h"
|
#include "getdns/getdns.h"
|
||||||
#include "getdns/getdns_extra.h"
|
#include "getdns/getdns_extra.h"
|
||||||
|
#include "types-internal.h"
|
||||||
|
|
||||||
/* No more than select's capability queries can be outstanding,
|
/* No more than select's capability queries can be outstanding,
|
||||||
* The number of outstanding timeouts should be less or equal then
|
* The number of outstanding timeouts should be less or equal then
|
||||||
|
|
|
@ -54,6 +54,7 @@
|
||||||
#include "dict.h"
|
#include "dict.h"
|
||||||
#include "mdns.h"
|
#include "mdns.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
#include "anchor.h"
|
||||||
|
|
||||||
void _getdns_call_user_callback(getdns_dns_req *dnsreq, getdns_dict *response)
|
void _getdns_call_user_callback(getdns_dns_req *dnsreq, getdns_dict *response)
|
||||||
{
|
{
|
||||||
|
@ -213,13 +214,18 @@ _getdns_check_dns_req_complete(getdns_dns_req *dns_req)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef STUB_NATIVE_DNSSEC
|
#ifdef STUB_NATIVE_DNSSEC
|
||||||
|| (dns_req->context->resolution_type == GETDNS_RESOLUTION_STUB
|
|| ( dns_req->context->resolution_type == GETDNS_RESOLUTION_STUB
|
||||||
&& !dns_req->avoid_dnssec_roadblocks
|
&& !dns_req->avoid_dnssec_roadblocks
|
||||||
&& (dns_req->dnssec_return_status ||
|
&& (dns_req->dnssec_return_status ||
|
||||||
dns_req->dnssec_return_only_secure ||
|
dns_req->dnssec_return_only_secure ||
|
||||||
dns_req->dnssec_return_all_statuses
|
dns_req->dnssec_return_all_statuses
|
||||||
))
|
))
|
||||||
#endif
|
#endif
|
||||||
|
|| ( dns_req->context->resolution_type == GETDNS_RESOLUTION_RECURSING
|
||||||
|
&& (dns_req->dnssec_return_status ||
|
||||||
|
dns_req->dnssec_return_only_secure ||
|
||||||
|
dns_req->dnssec_return_all_statuses)
|
||||||
|
&& _getdns_bogus(dns_req))
|
||||||
)) {
|
)) {
|
||||||
/* Reschedule timeout for this DNS request
|
/* Reschedule timeout for this DNS request
|
||||||
*/
|
*/
|
||||||
|
@ -235,6 +241,7 @@ _getdns_check_dns_req_complete(getdns_dns_req *dns_req)
|
||||||
#if defined(REQ_DEBUG) && REQ_DEBUG
|
#if defined(REQ_DEBUG) && REQ_DEBUG
|
||||||
debug_req("getting validation chain for ", *dns_req->netreqs);
|
debug_req("getting validation chain for ", *dns_req->netreqs);
|
||||||
#endif
|
#endif
|
||||||
|
DEBUG_ANCHOR("Valchain lookup\n");
|
||||||
_getdns_get_validation_chain(dns_req);
|
_getdns_get_validation_chain(dns_req);
|
||||||
} else
|
} else
|
||||||
_getdns_call_user_callback(
|
_getdns_call_user_callback(
|
||||||
|
@ -442,14 +449,12 @@ _getdns_submit_netreq(getdns_network_req *netreq, uint64_t *now_ms)
|
||||||
if (_getdns_ub_loop_enabled(&context->ub_loop))
|
if (_getdns_ub_loop_enabled(&context->ub_loop))
|
||||||
ub_resolve_r = ub_resolve_event(context->unbound_ctx,
|
ub_resolve_r = ub_resolve_event(context->unbound_ctx,
|
||||||
name, netreq->request_type, dns_req->request_class,
|
name, netreq->request_type, dns_req->request_class,
|
||||||
netreq, ub_resolve_event_callback, &(netreq->unbound_id)) ?
|
netreq, ub_resolve_event_callback, &(netreq->unbound_id));
|
||||||
GETDNS_RETURN_GENERIC_ERROR : GETDNS_RETURN_GOOD;
|
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
ub_resolve_r = ub_resolve_async(context->unbound_ctx,
|
ub_resolve_r = ub_resolve_async(context->unbound_ctx,
|
||||||
name, netreq->request_type, dns_req->request_class,
|
name, netreq->request_type, dns_req->request_class,
|
||||||
netreq, ub_resolve_callback, &(netreq->unbound_id)) ?
|
netreq, ub_resolve_callback, &(netreq->unbound_id));
|
||||||
GETDNS_RETURN_GENERIC_ERROR : GETDNS_RETURN_GOOD;
|
|
||||||
if (dnsreq_freed)
|
if (dnsreq_freed)
|
||||||
return DNS_REQ_FINISHED;
|
return DNS_REQ_FINISHED;
|
||||||
dns_req->freed = NULL;
|
dns_req->freed = NULL;
|
||||||
|
@ -570,11 +575,6 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
|
||||||
if (extensions && (r = validate_extensions(extensions)))
|
if (extensions && (r = validate_extensions(extensions)))
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
/* Set up the context assuming we won't use the specified namespaces.
|
|
||||||
This is (currently) identical to setting up a pure DNS namespace */
|
|
||||||
if ((r = _getdns_context_prepare_for_resolution(context, 0)))
|
|
||||||
return r;
|
|
||||||
|
|
||||||
/* create the request */
|
/* create the request */
|
||||||
if (!(req = _getdns_dns_req_new(
|
if (!(req = _getdns_dns_req_new(
|
||||||
context, loop, name, request_type, extensions, &now_ms)))
|
context, loop, name, request_type, extensions, &now_ms)))
|
||||||
|
@ -590,9 +590,31 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
|
||||||
|
|
||||||
_getdns_context_track_outbound_request(req);
|
_getdns_context_track_outbound_request(req);
|
||||||
|
|
||||||
if (!usenamespaces)
|
if (req->dnssec_extension_set) {
|
||||||
|
if (context->trust_anchors_source == GETDNS_TASRC_XML_UPDATE)
|
||||||
|
_getdns_start_fetching_ta(context, loop);
|
||||||
|
|
||||||
|
else if (context->trust_anchors_source == GETDNS_TASRC_NONE) {
|
||||||
|
_getdns_context_equip_with_anchor(context, &now_ms);
|
||||||
|
if (context->trust_anchors_source == GETDNS_TASRC_NONE) {
|
||||||
|
_getdns_start_fetching_ta(context, loop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!usenamespaces) {
|
||||||
|
if (context->trust_anchors_source == GETDNS_TASRC_FETCHING
|
||||||
|
&& context->resolution_type == GETDNS_RESOLUTION_RECURSING
|
||||||
|
&& context->resolution_type != context->resolution_type_set) {
|
||||||
|
req->waiting_for_ta = 1;
|
||||||
|
req->ta_notify = context->ta_notify;
|
||||||
|
context->ta_notify = req;
|
||||||
|
return GETDNS_RETURN_GOOD;
|
||||||
|
}
|
||||||
|
if ((r = _getdns_context_prepare_for_resolution(context)))
|
||||||
|
; /* pass */
|
||||||
|
|
||||||
/* issue all network requests */
|
/* issue all network requests */
|
||||||
for ( netreq_p = req->netreqs
|
else for ( netreq_p = req->netreqs
|
||||||
; !r && (netreq = *netreq_p)
|
; !r && (netreq = *netreq_p)
|
||||||
; netreq_p++) {
|
; netreq_p++) {
|
||||||
if ((r = _getdns_submit_netreq(netreq, &now_ms))) {
|
if ((r = _getdns_submit_netreq(netreq, &now_ms))) {
|
||||||
|
@ -605,7 +627,7 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else for (i = 0; i < context->namespace_count; i++) {
|
} else for (i = 0; i < context->namespace_count; i++) {
|
||||||
if (context->namespaces[i] == GETDNS_NAMESPACE_LOCALNAMES) {
|
if (context->namespaces[i] == GETDNS_NAMESPACE_LOCALNAMES) {
|
||||||
|
|
||||||
if (!(r = _getdns_context_local_namespace_resolve(
|
if (!(r = _getdns_context_local_namespace_resolve(
|
||||||
|
@ -639,6 +661,16 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
|
||||||
}
|
}
|
||||||
#endif /* HAVE_MDNS_SUPPORT */
|
#endif /* HAVE_MDNS_SUPPORT */
|
||||||
} else if (context->namespaces[i] == GETDNS_NAMESPACE_DNS) {
|
} else if (context->namespaces[i] == GETDNS_NAMESPACE_DNS) {
|
||||||
|
if (context->trust_anchors_source == GETDNS_TASRC_FETCHING
|
||||||
|
&& context->resolution_type == GETDNS_RESOLUTION_RECURSING
|
||||||
|
&& context->resolution_type != context->resolution_type_set) {
|
||||||
|
req->waiting_for_ta = 1;
|
||||||
|
req->ta_notify = context->ta_notify;
|
||||||
|
context->ta_notify = req;
|
||||||
|
return GETDNS_RETURN_GOOD;
|
||||||
|
}
|
||||||
|
if ((r = _getdns_context_prepare_for_resolution(context)))
|
||||||
|
break;
|
||||||
|
|
||||||
/* TODO: We will get a good return code here even if
|
/* TODO: We will get a good return code here even if
|
||||||
the name is not found (NXDOMAIN). We should consider
|
the name is not found (NXDOMAIN). We should consider
|
||||||
|
|
|
@ -79,6 +79,16 @@ extern "C" {
|
||||||
#define GETDNS_CONTEXT_CODE_TLS_BACKOFF_TIME_TEXT "Change related to getdns_context_set_tls_backoff_time"
|
#define GETDNS_CONTEXT_CODE_TLS_BACKOFF_TIME_TEXT "Change related to getdns_context_set_tls_backoff_time"
|
||||||
#define GETDNS_CONTEXT_CODE_TLS_CONNECTION_RETRIES 624
|
#define GETDNS_CONTEXT_CODE_TLS_CONNECTION_RETRIES 624
|
||||||
#define GETDNS_CONTEXT_CODE_TLS_CONNECTION_RETRIES_TEXT "Change related to getdns_context_set_tls_connection_retries"
|
#define GETDNS_CONTEXT_CODE_TLS_CONNECTION_RETRIES_TEXT "Change related to getdns_context_set_tls_connection_retries"
|
||||||
|
|
||||||
|
#define GETDNS_CONTEXT_CODE_TRUST_ANCHORS_URL 625
|
||||||
|
#define GETDNS_CONTEXT_CODE_TRUST_ANCHORS_URL_TEXT "Change related to getdns_context_set_trust_anchors_url"
|
||||||
|
#define GETDNS_CONTEXT_CODE_TRUST_ANCHORS_VERIFY_CA 626
|
||||||
|
#define GETDNS_CONTEXT_CODE_TRUST_ANCHORS_VERIFY_CA_TEXT "Change related to getdns_context_set_trust_anchors_verify_ca"
|
||||||
|
#define GETDNS_CONTEXT_CODE_TRUST_ANCHORS_VERIFY_EMAIL 627
|
||||||
|
#define GETDNS_CONTEXT_CODE_TRUST_ANCHORS_VERIFY_EMAIL_TEXT "Change related to getdns_context_set_trust_anchors_verify_email"
|
||||||
|
#define GETDNS_CONTEXT_CODE_APPDATA_DIR 628
|
||||||
|
#define GETDNS_CONTEXT_CODE_APPDATA_DIR_TEXT "Change related to getdns_context_set_appdata_dir"
|
||||||
|
|
||||||
/** @}
|
/** @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -520,7 +530,7 @@ typedef enum getdns_loglevel_type {
|
||||||
#define GETDNS_LOG_CRIT_TEXT "Critical conditions"
|
#define GETDNS_LOG_CRIT_TEXT "Critical conditions"
|
||||||
#define GETDNS_LOG_ERR_TEXT "Error conditions"
|
#define GETDNS_LOG_ERR_TEXT "Error conditions"
|
||||||
#define GETDNS_LOG_WARNING_TEXT "Warning conditions"
|
#define GETDNS_LOG_WARNING_TEXT "Warning conditions"
|
||||||
#define GETDNS_LOG_NOTICE_TEXT "normal, but significant, condition"
|
#define GETDNS_LOG_NOTICE_TEXT "Normal, but significant, condition"
|
||||||
#define GETDNS_LOG_INFO_TEXT "Informational message"
|
#define GETDNS_LOG_INFO_TEXT "Informational message"
|
||||||
#define GETDNS_LOG_DEBUG_TEXT "Debug-level message"
|
#define GETDNS_LOG_DEBUG_TEXT "Debug-level message"
|
||||||
|
|
||||||
|
@ -531,12 +541,145 @@ typedef void (*getdns_logfunc_type) (void *userarg, uint64_t log_systems,
|
||||||
getdns_loglevel_type, const char *, va_list ap);
|
getdns_loglevel_type, const char *, va_list ap);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Register a function that will be called when there is something to log
|
||||||
|
* equally or more severe than the given level for the given system.
|
||||||
|
* @param[in] context The context from which to get the setting
|
||||||
|
* @param[in] userarg A user defined argument to be passed to the
|
||||||
|
* log function.
|
||||||
|
* @param[in] system A bitwise ORed collection of systems for which the log
|
||||||
|
* function should be called. Currently only logging
|
||||||
|
* information about upstream statistics is available;
|
||||||
|
* i.e.: GETDNS_LOG_UPSTREAM_STATS
|
||||||
|
* @param[in] level A severity level. The log function will be called
|
||||||
|
* only for messages with an equal or more severe level.
|
||||||
|
* More severe has a lower value.
|
||||||
|
* @param[in] func The log function to call with the user argument,
|
||||||
|
* the system for which the log message, the severity
|
||||||
|
* level, a printf style format string and the arguments
|
||||||
|
* for the format string, as parameter.
|
||||||
|
* @see getdns_loglevel_type
|
||||||
|
* @see getdns_logfunc_type
|
||||||
|
* @return GETDNS_RETURN_GOOD when successful
|
||||||
|
* @return GETDNS_RETURN_INVALID_PARAMETER when context was NULL.
|
||||||
*/
|
*/
|
||||||
getdns_return_t
|
getdns_return_t
|
||||||
getdns_context_set_logfunc(getdns_context *context, void *userarg,
|
getdns_context_set_logfunc(getdns_context *context, void *userarg,
|
||||||
uint64_t system, getdns_loglevel_type level, getdns_logfunc_type func);
|
uint64_t system, getdns_loglevel_type level, getdns_logfunc_type func);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define the location for storing library specific data. The location should
|
||||||
|
* be writable for the current user using the application with which the
|
||||||
|
* library is linked. Currently this is only used for storing data concerning
|
||||||
|
* zero configuration dnssec.
|
||||||
|
* @param[in] context The context from which to get the setting
|
||||||
|
* @param[in] appdata_dir A user writable location in which the library can
|
||||||
|
* store data. The last element of the path is tried
|
||||||
|
* to be created if it does not exist. When NULL is
|
||||||
|
* given, the default location is used which is
|
||||||
|
* ${HOME}/.getdns/ on Unix line systems (Linux, BSD's,
|
||||||
|
* MacOS), and %AppData%\getnds\ on Windows.
|
||||||
|
* @return GETDNS_RETURN_GOOD when successful
|
||||||
|
* @return GETDNS_RETURN_INVALID_PARAMETER when context was NULL.
|
||||||
|
*/
|
||||||
|
getdns_return_t
|
||||||
|
getdns_context_set_appdata_dir(
|
||||||
|
getdns_context *context, const char *appdata_dir);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the url for the location of the XML file from which to fetch the
|
||||||
|
* trust anchors with Zero configuration DNSSEC. The url should be for
|
||||||
|
* http, and the file should have the .xml extension.
|
||||||
|
*
|
||||||
|
* Alongside the XML file, also the S/MIME signature that will be used to
|
||||||
|
* validate the XML file, will be fetched from the url with the .xml extension
|
||||||
|
* replaced by .p7s.
|
||||||
|
*
|
||||||
|
* When successfully validated with the verify Certificate Authority and the
|
||||||
|
* verify email address, the context will be equipped with the DNSSEC trust
|
||||||
|
* anchors defined within the XML file as described in RFC7958.
|
||||||
|
* The XML file will also be stored together with the .p7s file in the
|
||||||
|
* appdata directory with the names "root-anchors.xml" and "root-anchors.p7s"
|
||||||
|
* respectively.
|
||||||
|
*
|
||||||
|
* When the trust-anchors from the XML file are used, the root DNSKEY is
|
||||||
|
* tracked and stored in the appdata directory too as "root.key"
|
||||||
|
*
|
||||||
|
* Trust anchors from the XML file will be tried when:
|
||||||
|
* - There were no other trust anchors provided, either by the default
|
||||||
|
* trust anchor file "@TRUST_ANCHOR_FILE@", or set with the
|
||||||
|
* getdns_context_set_dnssec_trust_anchors() function.
|
||||||
|
* - or the available trust anchors (from the default location or set by
|
||||||
|
* the application) caused the root DNSKEY rrset to be BOGUS.
|
||||||
|
*
|
||||||
|
* Trust anchors from the XML file will be read from the root-anchors.xml
|
||||||
|
* file in appdata directory and will only be used when validation with the
|
||||||
|
* S/MIME signatures in root-anchors.p7s succeeds with the verification
|
||||||
|
* Certificate Authority and the verification email address.
|
||||||
|
*
|
||||||
|
* A (new) version of "root-anchors.xml" and "root-anchors.p7s" will be
|
||||||
|
* fetched when:
|
||||||
|
* - The appdata directory is writeable by the current used, but the
|
||||||
|
* "root-anchors.xml" or "root-anchors.p7s" files were not available.
|
||||||
|
* - or there is a new root DNSKEY RRset (or signature) and it contains
|
||||||
|
* key_ids which were not in "root-anchors.xml."
|
||||||
|
*
|
||||||
|
* @see getdns_context_get_trust_anchors_url
|
||||||
|
* @see getdns_context_set_trust_anchors_verify_CA
|
||||||
|
* @see getdns_context_set_trust_anchors_verify_email
|
||||||
|
* @param[in] context The context to configure
|
||||||
|
* @param[in] url The url including the XML file from which the
|
||||||
|
* trust anchors (and the S/MIME signature) will be
|
||||||
|
* fetched. Default is:
|
||||||
|
* http://data.iana.org/root-anchors/root-anchors.xml
|
||||||
|
* When NULL is given, the default will be used.
|
||||||
|
* @return GETDNS_RETURN_GOOD when successful
|
||||||
|
* @return GETDNS_RETURN_INVALID_PARAMETER when context was NULL.
|
||||||
|
*/
|
||||||
|
getdns_return_t
|
||||||
|
getdns_context_set_trust_anchors_url(getdns_context *context, const char *url);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the public certificate for the Certificate Authority with which to
|
||||||
|
* validate the XML file with the S/MIME signatures fetch from the url
|
||||||
|
* given with the getdns_context_set_trust_anchors_url() function.
|
||||||
|
* @see getdns_context_get_trust_anchors_verify_CA
|
||||||
|
* @see getdns_context_set_trust_anchors_url
|
||||||
|
* @see getdns_context_set_trust_anchors_verify_email
|
||||||
|
* @param[in] context The context to configure
|
||||||
|
* @param[in] verify_CA The certificate of the Certificate Authority with
|
||||||
|
* which to validate the XML trust anchors.
|
||||||
|
* The default is the ICANN Root CA, which is valid
|
||||||
|
* till Dec 18 2029.
|
||||||
|
* When NULL is given, the default will be used.
|
||||||
|
* When an empty string is given, Zero configuration
|
||||||
|
* DNSSEC will be disabled.
|
||||||
|
* @return GETDNS_RETURN_GOOD when successful
|
||||||
|
* @return GETDNS_RETURN_INVALID_PARAMETER when context was NULL.
|
||||||
|
*/
|
||||||
|
getdns_return_t
|
||||||
|
getdns_context_set_trust_anchors_verify_CA(
|
||||||
|
getdns_context *context, const char *verify_CA);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the email address for the Subject of the signer's certificate from the
|
||||||
|
* p7s signature file with which to validate the XML file fetched from the url
|
||||||
|
* given with the getdns_context_set_trust_anchors_url() function.
|
||||||
|
* @see getdns_context_get_trust_anchors_verify_email
|
||||||
|
* @see getdns_context_set_trust_anchors_url
|
||||||
|
* @see getdns_context_set_trust_anchors_verify_CA
|
||||||
|
* @param[in] context The context to configure
|
||||||
|
* @param[in] verify_email Only signatures from this name are allowed.
|
||||||
|
* The default dnssec@iana.org.
|
||||||
|
* When NULL is given, the default will be used.
|
||||||
|
* When an empty string is given, Zero configuration
|
||||||
|
* DNSSEC will be disabled.
|
||||||
|
* @return GETDNS_RETURN_GOOD when successful
|
||||||
|
* @return GETDNS_RETURN_INVALID_PARAMETER when context was NULL.
|
||||||
|
*/
|
||||||
|
getdns_return_t
|
||||||
|
getdns_context_set_trust_anchors_verify_email(
|
||||||
|
getdns_context *context, const char *verify_email);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current resolution type setting from this context.
|
* Get the current resolution type setting from this context.
|
||||||
* @see getdns_context_set_resolution_type
|
* @see getdns_context_set_resolution_type
|
||||||
|
@ -902,6 +1045,96 @@ getdns_return_t
|
||||||
getdns_context_get_update_callback(getdns_context *context, void **userarg,
|
getdns_context_get_update_callback(getdns_context *context, void **userarg,
|
||||||
void (**value) (getdns_context *, getdns_context_code_t, void *));
|
void (**value) (getdns_context *, getdns_context_code_t, void *));
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the url for the location of the XML file from which to fetch the
|
||||||
|
* trust anchors with Zero configuration DNSSEC.
|
||||||
|
*
|
||||||
|
* Alongside the XML file, also the S/MIME signature that will be used to
|
||||||
|
* validate the XML file, will be fetched from the url with the .xml extension
|
||||||
|
* replaced by .p7s.
|
||||||
|
*
|
||||||
|
* When successfully validated with the verify Certificate Authority and the
|
||||||
|
* verify email address, the context will be equipped with the DNSSEC trust
|
||||||
|
* anchors defined within the XML file as described in RFC7958.
|
||||||
|
* The XML file will also be stored together with the .p7s file in the
|
||||||
|
* appdata directory with the names "root-anchors.xml" and "root-anchors.p7s"
|
||||||
|
* respectively.
|
||||||
|
*
|
||||||
|
* When the trust-anchors from the XML file are used, the root DNSKEY is
|
||||||
|
* tracked and stored in the appdata directory too as "root.key"
|
||||||
|
*
|
||||||
|
* Trust anchors from the XML file will be tried when:
|
||||||
|
* - There were no other trust anchors provided, either by the default
|
||||||
|
* trust anchor file "@TRUST_ANCHOR_FILE@", or set with the
|
||||||
|
* getdns_context_set_dnssec_trust_anchors() function.
|
||||||
|
* - or the available trust anchors (from the default location or set by
|
||||||
|
* the application) caused the root DNSKEY rrset to be BOGUS.
|
||||||
|
*
|
||||||
|
* Trust anchors from the XML file will be read from the root-anchors.xml
|
||||||
|
* file in appdata directory and will only be used when validation with the
|
||||||
|
* S/MIME signatures in root-anchors.p7s succeeds with the verification
|
||||||
|
* Certificate Authority and the verification email address.
|
||||||
|
*
|
||||||
|
* A (new) version of "root-anchors.xml" and "root-anchors.p7s" will be
|
||||||
|
* fetched when:
|
||||||
|
* - The appdata directory is writeable by the current used, but the
|
||||||
|
* "root-anchors.xml" or "root-anchors.p7s" files were not available.
|
||||||
|
* - or there is a new root DNSKEY RRset (or signature) and it contains
|
||||||
|
* key_ids which were not in "root-anchors.xml."
|
||||||
|
*
|
||||||
|
* @see getdns_context_set_trust_anchors_url
|
||||||
|
* @see getdns_context_get_trust_anchors_verify_CA
|
||||||
|
* @see getdns_context_get_trust_anchors_verify_email
|
||||||
|
* @param[in] context The context to configure
|
||||||
|
* @param[out] url The url including the XML file, from which the
|
||||||
|
* trust anchors (and the S/MIME signature) will be
|
||||||
|
* fetched. Default is:
|
||||||
|
* http://data.iana.org/root-anchors/root-anchors.xml
|
||||||
|
* @return GETDNS_RETURN_GOOD when successful
|
||||||
|
* @return GETDNS_RETURN_INVALID_PARAMETER when context was NULL.
|
||||||
|
*/
|
||||||
|
getdns_return_t
|
||||||
|
getdns_context_get_trust_anchors_url(
|
||||||
|
getdns_context *context, const char **url);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the public certificate for the Certificate Authority with which to
|
||||||
|
* validate the XML file with the S/MIME signatures fetch from the url
|
||||||
|
* given with the getdns_context_set_trust_anchors_url() function.
|
||||||
|
* @see getdns_context_set_trust_anchors_verify_CA
|
||||||
|
* @see getdns_context_get_trust_anchors_url
|
||||||
|
* @see getdns_context_get_trust_anchors_verify_email
|
||||||
|
* @param[in] context The context to configure
|
||||||
|
* @param[out] verify_CA The certificate of the Certificate Authority with
|
||||||
|
* which to validate the XML trust anchors.
|
||||||
|
* The default is the ICANN Root CA, which is valid
|
||||||
|
* till Dec 18 2029.
|
||||||
|
* @return GETDNS_RETURN_GOOD when successful
|
||||||
|
* @return GETDNS_RETURN_INVALID_PARAMETER when context was NULL.
|
||||||
|
*/
|
||||||
|
getdns_return_t
|
||||||
|
getdns_context_get_trust_anchors_verify_CA(
|
||||||
|
getdns_context *context, const char **verify_CA);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the email address for the Subject of the signer's certificate from the
|
||||||
|
* p7s signature file with which to validate the XML file fetched from the url
|
||||||
|
* given with the getdns_context_set_trust_anchors_url() function.
|
||||||
|
* @see getdns_context_set_trust_anchors_verify_email
|
||||||
|
* @see getdns_context_get_trust_anchors_url
|
||||||
|
* @see getdns_context_get_trust_anchors_verify_CA
|
||||||
|
* @param[in] context The context to configure
|
||||||
|
* @param[out] verify_email Only signatures from this name are allowed.
|
||||||
|
* The default dnssec@iana.org.
|
||||||
|
* @return GETDNS_RETURN_GOOD when successful
|
||||||
|
* @return GETDNS_RETURN_INVALID_PARAMETER when context was NULL.
|
||||||
|
*/
|
||||||
|
getdns_return_t
|
||||||
|
getdns_context_get_trust_anchors_verify_email(
|
||||||
|
getdns_context *context, const char **verify_email);
|
||||||
|
|
||||||
|
|
||||||
/** @}
|
/** @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -1723,6 +1956,7 @@ getdns_str2bindata(const char *str, getdns_bindata **bindata);
|
||||||
getdns_return_t
|
getdns_return_t
|
||||||
getdns_str2int(const char *str, uint32_t *value);
|
getdns_str2int(const char *str, uint32_t *value);
|
||||||
|
|
||||||
|
|
||||||
/** @}
|
/** @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
@ -95,7 +95,7 @@ gldns_rr_dnskey_key_size_raw(const unsigned char* keydata,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t gldns_calc_keytag_raw(uint8_t* key, size_t keysize)
|
uint16_t gldns_calc_keytag_raw(const uint8_t* key, size_t keysize)
|
||||||
{
|
{
|
||||||
if(keysize < 4) {
|
if(keysize < 4) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -44,7 +44,7 @@ size_t gldns_rr_dnskey_key_size_raw(const unsigned char *keydata,
|
||||||
* \param[in] keysize length of key data.
|
* \param[in] keysize length of key data.
|
||||||
* \return the keytag
|
* \return the keytag
|
||||||
*/
|
*/
|
||||||
uint16_t gldns_calc_keytag_raw(uint8_t* key, size_t keysize);
|
uint16_t gldns_calc_keytag_raw(const uint8_t* key, size_t keysize);
|
||||||
|
|
||||||
#if GLDNS_BUILD_CONFIG_HAVE_SSL
|
#if GLDNS_BUILD_CONFIG_HAVE_SSL
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1059,11 +1059,7 @@ int gldns_wire2str_tsigtime_scan(uint8_t** d, size_t* dl, char** s, size_t* sl)
|
||||||
d4 = (*d)[4];
|
d4 = (*d)[4];
|
||||||
d5 = (*d)[5];
|
d5 = (*d)[5];
|
||||||
tsigtime = (d0<<40) | (d1<<32) | (d2<<24) | (d3<<16) | (d4<<8) | d5;
|
tsigtime = (d0<<40) | (d1<<32) | (d2<<24) | (d3<<16) | (d4<<8) | d5;
|
||||||
#ifndef USE_WINSOCK
|
w = gldns_str_print(s, sl, "%"PRIu64, (uint64_t)tsigtime);
|
||||||
w = gldns_str_print(s, sl, "%llu", (long long)tsigtime);
|
|
||||||
#else
|
|
||||||
w = gldns_str_print(s, sl, "%I64u", (long long)tsigtime);
|
|
||||||
#endif
|
|
||||||
(*d)+=6;
|
(*d)+=6;
|
||||||
(*dl)-=6;
|
(*dl)-=6;
|
||||||
return w;
|
return w;
|
||||||
|
@ -1746,13 +1742,8 @@ int gldns_wire2str_edns_llq_print(char** s, size_t* sl, uint8_t* data,
|
||||||
if(error_code < llq_errors_num)
|
if(error_code < llq_errors_num)
|
||||||
w += gldns_str_print(s, sl, " %s", llq_errors[error_code]);
|
w += gldns_str_print(s, sl, " %s", llq_errors[error_code]);
|
||||||
else w += gldns_str_print(s, sl, " error %d", (int)error_code);
|
else w += gldns_str_print(s, sl, " error %d", (int)error_code);
|
||||||
#ifndef USE_WINSOCK
|
w += gldns_str_print(s, sl, " id %"PRIx64" lease-life %lu",
|
||||||
w += gldns_str_print(s, sl, " id %llx lease-life %lu",
|
(uint64_t)llq_id, (unsigned long)lease_life);
|
||||||
(unsigned long long)llq_id, (unsigned long)lease_life);
|
|
||||||
#else
|
|
||||||
w += gldns_str_print(s, sl, " id %I64x lease-life %lu",
|
|
||||||
(unsigned long long)llq_id, (unsigned long)lease_life);
|
|
||||||
#endif
|
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,10 +33,14 @@ getdns_context_get_tls_authentication
|
||||||
getdns_context_get_tls_backoff_time
|
getdns_context_get_tls_backoff_time
|
||||||
getdns_context_get_tls_connection_retries
|
getdns_context_get_tls_connection_retries
|
||||||
getdns_context_get_tls_query_padding_blocksize
|
getdns_context_get_tls_query_padding_blocksize
|
||||||
|
getdns_context_get_trust_anchors_url
|
||||||
|
getdns_context_get_trust_anchors_verify_CA
|
||||||
|
getdns_context_get_trust_anchors_verify_email
|
||||||
getdns_context_get_update_callback
|
getdns_context_get_update_callback
|
||||||
getdns_context_get_upstream_recursive_servers
|
getdns_context_get_upstream_recursive_servers
|
||||||
getdns_context_process_async
|
getdns_context_process_async
|
||||||
getdns_context_run
|
getdns_context_run
|
||||||
|
getdns_context_set_appdata_dir
|
||||||
getdns_context_set_append_name
|
getdns_context_set_append_name
|
||||||
getdns_context_set_context_update_callback
|
getdns_context_set_context_update_callback
|
||||||
getdns_context_set_dns_root_servers
|
getdns_context_set_dns_root_servers
|
||||||
|
@ -67,6 +71,9 @@ getdns_context_set_tls_authentication
|
||||||
getdns_context_set_tls_backoff_time
|
getdns_context_set_tls_backoff_time
|
||||||
getdns_context_set_tls_connection_retries
|
getdns_context_set_tls_connection_retries
|
||||||
getdns_context_set_tls_query_padding_blocksize
|
getdns_context_set_tls_query_padding_blocksize
|
||||||
|
getdns_context_set_trust_anchors_url
|
||||||
|
getdns_context_set_trust_anchors_verify_CA
|
||||||
|
getdns_context_set_trust_anchors_verify_email
|
||||||
getdns_context_set_update_callback
|
getdns_context_set_update_callback
|
||||||
getdns_context_set_upstream_recursive_servers
|
getdns_context_set_upstream_recursive_servers
|
||||||
getdns_context_set_use_threads
|
getdns_context_set_use_threads
|
||||||
|
|
73
src/mdns.c
73
src/mdns.c
|
@ -26,28 +26,11 @@
|
||||||
#include "gldns/pkthdr.h"
|
#include "gldns/pkthdr.h"
|
||||||
#include "gldns/rrdef.h"
|
#include "gldns/rrdef.h"
|
||||||
#include "util-internal.h"
|
#include "util-internal.h"
|
||||||
|
#include "platform.h"
|
||||||
#include "mdns.h"
|
#include "mdns.h"
|
||||||
|
|
||||||
#ifdef HAVE_MDNS_SUPPORT
|
#ifdef HAVE_MDNS_SUPPORT
|
||||||
|
|
||||||
#ifdef USE_WINSOCK
|
|
||||||
typedef u_short sa_family_t;
|
|
||||||
#define _getdns_EWOULDBLOCK (WSAGetLastError() == WSATRY_AGAIN ||\
|
|
||||||
WSAGetLastError() == WSAEWOULDBLOCK)
|
|
||||||
#define _getdns_EINPROGRESS (WSAGetLastError() == WSAEINPROGRESS)
|
|
||||||
#else
|
|
||||||
#define _getdns_EWOULDBLOCK (errno == EAGAIN || errno == EWOULDBLOCK)
|
|
||||||
#define _getdns_EINPROGRESS (errno == EINPROGRESS)
|
|
||||||
#define SOCKADDR struct sockaddr
|
|
||||||
#define SOCKADDR_IN struct sockaddr_in
|
|
||||||
#define SOCKADDR_IN6 struct sockaddr_in6
|
|
||||||
#define SOCKET int
|
|
||||||
#define IP_MREQ struct ip_mreq
|
|
||||||
#define IPV6_MREQ struct ipv6_mreq
|
|
||||||
#define BOOL int
|
|
||||||
#define TRUE 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Define IPV6_ADD_MEMBERSHIP for FreeBSD and Mac OS X */
|
/* Define IPV6_ADD_MEMBERSHIP for FreeBSD and Mac OS X */
|
||||||
#ifndef IPV6_ADD_MEMBERSHIP
|
#ifndef IPV6_ADD_MEMBERSHIP
|
||||||
#define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
|
#define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
|
||||||
|
@ -1148,7 +1131,8 @@ mdns_udp_multicast_read_cb(void *userarg)
|
||||||
sizeof(cnx->response), 0, NULL, NULL);
|
sizeof(cnx->response), 0, NULL, NULL);
|
||||||
|
|
||||||
|
|
||||||
if (read == -1 && _getdns_EWOULDBLOCK)
|
if (read == -1 && (_getdns_socketerror() == _getdns_EWOULDBLOCK ||
|
||||||
|
_getdns_socketerror() == _getdns_ECONNRESET))
|
||||||
return; /* TODO: this will stop the receive loop! */
|
return; /* TODO: this will stop the receive loop! */
|
||||||
|
|
||||||
if (read >= GLDNS_HEADER_SIZE)
|
if (read >= GLDNS_HEADER_SIZE)
|
||||||
|
@ -1353,11 +1337,7 @@ static int mdns_open_ipv4_multicast(SOCKADDR_STORAGE* mcast_dest, int* mcast_des
|
||||||
|
|
||||||
if (ret != 0 && fd4 != -1)
|
if (ret != 0 && fd4 != -1)
|
||||||
{
|
{
|
||||||
#ifdef USE_WINSOCK
|
_getdns_closesocket(fd4);
|
||||||
closesocket(fd4);
|
|
||||||
#else
|
|
||||||
close(fd4);
|
|
||||||
#endif
|
|
||||||
fd4 = -1;
|
fd4 = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1428,11 +1408,7 @@ static int mdns_open_ipv6_multicast(SOCKADDR_STORAGE* mcast_dest, int* mcast_des
|
||||||
|
|
||||||
if (ret != 0 && fd6 != -1)
|
if (ret != 0 && fd6 != -1)
|
||||||
{
|
{
|
||||||
#ifdef USE_WINSOCK
|
_getdns_closesocket(fd6);
|
||||||
closesocket(fd6);
|
|
||||||
#else
|
|
||||||
close(fd6);
|
|
||||||
#endif
|
|
||||||
fd6 = -1;
|
fd6 = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1514,11 +1490,7 @@ static getdns_return_t mdns_delayed_network_init(struct getdns_context *context)
|
||||||
|
|
||||||
GETDNS_CLEAR_EVENT(context->extension
|
GETDNS_CLEAR_EVENT(context->extension
|
||||||
, &context->mdns_connection[i].event);
|
, &context->mdns_connection[i].event);
|
||||||
#ifdef USE_WINSOCK
|
_getdns_closesocket(context->mdns_connection[i].fd);
|
||||||
closesocket(context->mdns_connection[i].fd);
|
|
||||||
#else
|
|
||||||
close(context->mdns_connection[i].fd);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1657,11 +1629,7 @@ void _getdns_mdns_context_destroy(struct getdns_context *context)
|
||||||
/* suppress the receive event */
|
/* suppress the receive event */
|
||||||
GETDNS_CLEAR_EVENT(context->extension, &context->mdns_connection[i].event);
|
GETDNS_CLEAR_EVENT(context->extension, &context->mdns_connection[i].event);
|
||||||
/* close the socket */
|
/* close the socket */
|
||||||
#ifdef USE_WINSOCK
|
_getdns_closesocket(context->mdns_connection[i].fd);
|
||||||
closesocket(context->mdns_connection[i].fd);
|
|
||||||
#else
|
|
||||||
close(context->mdns_connection[i].fd);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GETDNS_FREE(context->mf, context->mdns_connection);
|
GETDNS_FREE(context->mf, context->mdns_connection);
|
||||||
|
@ -1686,11 +1654,7 @@ _getdns_cancel_mdns_request(getdns_network_req *netreq)
|
||||||
{
|
{
|
||||||
mdns_cleanup(netreq);
|
mdns_cleanup(netreq);
|
||||||
if (netreq->fd >= 0) {
|
if (netreq->fd >= 0) {
|
||||||
#ifdef USE_WINSOCK
|
_getdns_closesocket(netreq->fd);
|
||||||
closesocket(netreq->fd);
|
|
||||||
#else
|
|
||||||
close(netreq->fd);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1706,11 +1670,7 @@ mdns_timeout_cb(void *userarg)
|
||||||
/* Check the required cleanup */
|
/* Check the required cleanup */
|
||||||
mdns_cleanup(netreq);
|
mdns_cleanup(netreq);
|
||||||
if (netreq->fd >= 0)
|
if (netreq->fd >= 0)
|
||||||
#ifdef USE_WINSOCK
|
_getdns_closesocket(netreq->fd);
|
||||||
closesocket(netreq->fd);
|
|
||||||
#else
|
|
||||||
close(netreq->fd);
|
|
||||||
#endif
|
|
||||||
_getdns_netreq_change_state(netreq, NET_REQ_TIMED_OUT);
|
_getdns_netreq_change_state(netreq, NET_REQ_TIMED_OUT);
|
||||||
if (netreq->owner->user_callback) {
|
if (netreq->owner->user_callback) {
|
||||||
netreq->debug_end_time = _getdns_get_time_as_uintt64();
|
netreq->debug_end_time = _getdns_get_time_as_uintt64();
|
||||||
|
@ -1745,7 +1705,8 @@ mdns_udp_read_cb(void *userarg)
|
||||||
* i.e. overflow
|
* i.e. overflow
|
||||||
*/
|
*/
|
||||||
0, NULL, NULL);
|
0, NULL, NULL);
|
||||||
if (read == -1 && _getdns_EWOULDBLOCK)
|
if (read == -1 && (_getdns_socketerror() == _getdns_EWOULDBLOCK ||
|
||||||
|
_getdns_socketerror() == _getdns_ECONNRESET))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (read < GLDNS_HEADER_SIZE)
|
if (read < GLDNS_HEADER_SIZE)
|
||||||
|
@ -1759,11 +1720,7 @@ mdns_udp_read_cb(void *userarg)
|
||||||
// TODO: check that the source address originates from the local network.
|
// TODO: check that the source address originates from the local network.
|
||||||
// TODO: check TTL = 255
|
// TODO: check TTL = 255
|
||||||
|
|
||||||
#ifdef USE_WINSOCK
|
_getdns_closesocket(netreq->fd);
|
||||||
closesocket(netreq->fd);
|
|
||||||
#else
|
|
||||||
close(netreq->fd);
|
|
||||||
#endif
|
|
||||||
/*
|
/*
|
||||||
* TODO: how to handle an MDNS response with TC bit set?
|
* TODO: how to handle an MDNS response with TC bit set?
|
||||||
* Ignore it for now, as we do not support any kind of TCP fallback
|
* Ignore it for now, as we do not support any kind of TCP fallback
|
||||||
|
@ -1814,11 +1771,7 @@ mdns_udp_write_cb(void *userarg)
|
||||||
netreq->fd, (const void *)netreq->query, pkt_len, 0,
|
netreq->fd, (const void *)netreq->query, pkt_len, 0,
|
||||||
(struct sockaddr *)&mdns_mcast_v4,
|
(struct sockaddr *)&mdns_mcast_v4,
|
||||||
sizeof(mdns_mcast_v4))) {
|
sizeof(mdns_mcast_v4))) {
|
||||||
#ifdef USE_WINSOCK
|
_getdns_closesocket(netreq->fd);
|
||||||
closesocket(netreq->fd);
|
|
||||||
#else
|
|
||||||
close(netreq->fd);
|
|
||||||
#endif
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
GETDNS_SCHEDULE_EVENT(
|
GETDNS_SCHEDULE_EVENT(
|
||||||
|
|
|
@ -24,13 +24,11 @@
|
||||||
#ifdef HAVE_MDNS_SUPPORT
|
#ifdef HAVE_MDNS_SUPPORT
|
||||||
#include "getdns/getdns.h"
|
#include "getdns/getdns.h"
|
||||||
#include "types-internal.h"
|
#include "types-internal.h"
|
||||||
|
#include "util-internal.h"
|
||||||
|
#include "platform.h"
|
||||||
#include "util/lruhash.h"
|
#include "util/lruhash.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#ifndef USE_WINSOCK
|
|
||||||
#define SOCKADDR_STORAGE struct sockaddr_storage
|
|
||||||
#endif
|
|
||||||
|
|
||||||
getdns_return_t
|
getdns_return_t
|
||||||
_getdns_submit_mdns_request(getdns_network_req *netreq);
|
_getdns_submit_mdns_request(getdns_network_req *netreq);
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ write_symbols() {
|
||||||
}
|
}
|
||||||
|
|
||||||
write_symbols libgetdns.symbols getdns/getdns.h.in getdns/getdns_extra.h.in
|
write_symbols libgetdns.symbols getdns/getdns.h.in getdns/getdns_extra.h.in
|
||||||
|
#echo getdns_yaml2dict >> libgetdns.symbols
|
||||||
echo plain_mem_funcs_user_arg >> libgetdns.symbols
|
echo plain_mem_funcs_user_arg >> libgetdns.symbols
|
||||||
echo priv_getdns_context_mf >> libgetdns.symbols
|
echo priv_getdns_context_mf >> libgetdns.symbols
|
||||||
write_symbols extension/libevent.symbols getdns/getdns_ext_libevent.h
|
write_symbols extension/libevent.symbols getdns/getdns_ext_libevent.h
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* \file platform.c
|
||||||
|
* @brief general functions with platform-dependent implementations
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2017, NLnet Labs, Sinodun
|
||||||
|
* 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 names of the copyright holders 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 Verisign, Inc. 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 "platform.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#ifdef USE_WINSOCK
|
||||||
|
|
||||||
|
void _getdns_perror(const char *str)
|
||||||
|
{
|
||||||
|
char msg[256];
|
||||||
|
int errid = WSAGetLastError();
|
||||||
|
|
||||||
|
*msg = '\0';
|
||||||
|
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
|
||||||
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
|
NULL,
|
||||||
|
errid,
|
||||||
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||||
|
msg,
|
||||||
|
sizeof(msg),
|
||||||
|
NULL);
|
||||||
|
if (*msg == '\0')
|
||||||
|
sprintf(msg, "Unknown error: %d", errid);
|
||||||
|
if (str && *str != '\0')
|
||||||
|
fprintf(stderr, "%s: ", str);
|
||||||
|
fputs(msg, stderr);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
void _getdns_perror(const char *str)
|
||||||
|
{
|
||||||
|
perror(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,84 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* \file platform.h
|
||||||
|
* @brief general functions with platform-dependent implementations
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2017, NLnet Labs, Sinodun
|
||||||
|
* 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 names of the copyright holders 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 Verisign, Inc. 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 PLATFORM_H
|
||||||
|
#define PLATFORM_H
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#ifdef USE_WINSOCK
|
||||||
|
typedef u_short sa_family_t;
|
||||||
|
#define _getdns_EAGAIN (WSATRY_AGAIN)
|
||||||
|
#define _getdns_EWOULDBLOCK (WSAEWOULDBLOCK)
|
||||||
|
#define _getdns_EINPROGRESS (WSAEINPROGRESS)
|
||||||
|
#define _getdns_EMFILE (WSAEMFILE)
|
||||||
|
#define _getdns_ECONNRESET (WSAECONNRESET)
|
||||||
|
|
||||||
|
#define _getdns_closesocket(fd) closesocket(fd)
|
||||||
|
#define _getdns_poll(fdarray, nsockets, timer) WSAPoll(fdarray, nsockets, timer)
|
||||||
|
#define _getdns_socketerror() (WSAGetLastError())
|
||||||
|
|
||||||
|
#else /* USE_WINSOCK */
|
||||||
|
|
||||||
|
#ifdef HAVE_SYS_POLL_H
|
||||||
|
# include <sys/poll.h>
|
||||||
|
#else
|
||||||
|
# include <poll.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define _getdns_EAGAIN (EAGAIN)
|
||||||
|
#define _getdns_EWOULDBLOCK (EWOULDBLOCK)
|
||||||
|
#define _getdns_EINPROGRESS (EINPROGRESS)
|
||||||
|
#define _getdns_EMFILE (EMFILE)
|
||||||
|
#define _getdns_ECONNRESET (ECONNRESET)
|
||||||
|
|
||||||
|
#define SOCKADDR struct sockaddr
|
||||||
|
#define SOCKADDR_IN struct sockaddr_in
|
||||||
|
#define SOCKADDR_IN6 struct sockaddr_in6
|
||||||
|
#define SOCKADDR_STORAGE struct sockaddr_storage
|
||||||
|
#define SOCKET int
|
||||||
|
|
||||||
|
#define IP_MREQ struct ip_mreq
|
||||||
|
#define IPV6_MREQ struct ipv6_mreq
|
||||||
|
#define BOOL int
|
||||||
|
#define TRUE 1
|
||||||
|
|
||||||
|
#define _getdns_closesocket(fd) close(fd)
|
||||||
|
#define _getdns_poll(fdarray, nsockets, timer) poll(fdarray, nsockets, timer)
|
||||||
|
#define _getdns_socketerror() (errno)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void _getdns_perror(const char *str);
|
||||||
|
|
||||||
|
#endif
|
|
@ -437,14 +437,14 @@ _getdns_verify_pinset_match(const sha256_pin_t *pinset,
|
||||||
/* digest the cert with sha256 */
|
/* digest the cert with sha256 */
|
||||||
len = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x), NULL);
|
len = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x), NULL);
|
||||||
if (len > (int)sizeof(raw)) {
|
if (len > (int)sizeof(raw)) {
|
||||||
DEBUG_STUB("%s %-35s: Pubkey %d is larger than "PRIsz" octets\n",
|
DEBUG_STUB("%s %-35s: Pubkey %d is larger than %"PRIsz" octets\n",
|
||||||
STUB_DEBUG_SETUP_TLS, __FUNC__, i, sizeof(raw));
|
STUB_DEBUG_SETUP_TLS, __FUNC__, i, sizeof(raw));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
next = raw;
|
next = raw;
|
||||||
i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x), &next);
|
i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x), &next);
|
||||||
if (next - raw != len) {
|
if (next - raw != len) {
|
||||||
DEBUG_STUB("%s %-35s: Pubkey %d claimed it needed %d octets, really needed "PRIsz"\n",
|
DEBUG_STUB("%s %-35s: Pubkey %d claimed it needed %d octets, really needed %"PRIsz"\n",
|
||||||
STUB_DEBUG_SETUP_TLS, __FUNC__, i, len, next - raw);
|
STUB_DEBUG_SETUP_TLS, __FUNC__, i, len, next - raw);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -453,7 +453,7 @@ _getdns_verify_pinset_match(const sha256_pin_t *pinset,
|
||||||
/* compare it */
|
/* compare it */
|
||||||
for (p = pinset; p; p = p->next)
|
for (p = pinset; p; p = p->next)
|
||||||
if (0 == memcmp(buf, p->pin, sizeof(p->pin))) {
|
if (0 == memcmp(buf, p->pin, sizeof(p->pin))) {
|
||||||
DEBUG_STUB("%s %-35s: Pubkey %d matched pin %p ("PRIsz")\n",
|
DEBUG_STUB("%s %-35s: Pubkey %d matched pin %p (%"PRIsz")\n",
|
||||||
STUB_DEBUG_SETUP_TLS, __FUNC__, i, (void*)p, sizeof(p->pin));
|
STUB_DEBUG_SETUP_TLS, __FUNC__, i, (void*)p, sizeof(p->pin));
|
||||||
return GETDNS_RETURN_GOOD;
|
return GETDNS_RETURN_GOOD;
|
||||||
} else
|
} else
|
||||||
|
|
|
@ -107,6 +107,12 @@ network_req_cleanup(getdns_network_req *net_req)
|
||||||
{
|
{
|
||||||
assert(net_req);
|
assert(net_req);
|
||||||
|
|
||||||
|
if (net_req->query_id_registered) {
|
||||||
|
(void) _getdns_rbtree_delete(
|
||||||
|
net_req->query_id_registered, net_req->node.key);
|
||||||
|
net_req->query_id_registered = NULL;
|
||||||
|
net_req->node.key = NULL;
|
||||||
|
}
|
||||||
if (net_req->response && (net_req->response < net_req->wire_data ||
|
if (net_req->response && (net_req->response < net_req->wire_data ||
|
||||||
net_req->response > net_req->wire_data+ net_req->wire_data_sz))
|
net_req->response > net_req->wire_data+ net_req->wire_data_sz))
|
||||||
GETDNS_FREE(net_req->owner->my_mf, net_req->response);
|
GETDNS_FREE(net_req->owner->my_mf, net_req->response);
|
||||||
|
@ -123,6 +129,12 @@ netreq_reset(getdns_network_req *net_req)
|
||||||
*/
|
*/
|
||||||
net_req->unbound_id = -1;
|
net_req->unbound_id = -1;
|
||||||
_getdns_netreq_change_state(net_req, NET_REQ_NOT_SENT);
|
_getdns_netreq_change_state(net_req, NET_REQ_NOT_SENT);
|
||||||
|
if (net_req->query_id_registered) {
|
||||||
|
(void) _getdns_rbtree_delete(net_req->query_id_registered,
|
||||||
|
(void *)(intptr_t)GLDNS_ID_WIRE(net_req->query));
|
||||||
|
net_req->query_id_registered = NULL;
|
||||||
|
net_req->node.key = NULL;
|
||||||
|
}
|
||||||
net_req->dnssec_status = GETDNS_DNSSEC_INDETERMINATE;
|
net_req->dnssec_status = GETDNS_DNSSEC_INDETERMINATE;
|
||||||
net_req->tsig_status = GETDNS_DNSSEC_INDETERMINATE;
|
net_req->tsig_status = GETDNS_DNSSEC_INDETERMINATE;
|
||||||
net_req->response_len = 0;
|
net_req->response_len = 0;
|
||||||
|
@ -170,7 +182,12 @@ network_req_init(getdns_network_req *net_req, getdns_dns_req *owner,
|
||||||
net_req->transport_count = owner->context->dns_transport_count;
|
net_req->transport_count = owner->context->dns_transport_count;
|
||||||
memcpy(net_req->transports, owner->context->dns_transports,
|
memcpy(net_req->transports, owner->context->dns_transports,
|
||||||
net_req->transport_count * sizeof(getdns_transport_list_t));
|
net_req->transport_count * sizeof(getdns_transport_list_t));
|
||||||
net_req->tls_auth_min = owner->context->tls_auth_min;
|
net_req->tls_auth_min =
|
||||||
|
owner->context->tls_auth == GETDNS_AUTHENTICATION_REQUIRED
|
||||||
|
&& owner->context->dns_transport_count == 1
|
||||||
|
&& owner->context->dns_transports[0] == GETDNS_TRANSPORT_TLS
|
||||||
|
? GETDNS_AUTHENTICATION_REQUIRED
|
||||||
|
: GETDNS_AUTHENTICATION_NONE;
|
||||||
|
|
||||||
net_req->follow_redirects = owner->context->follow_redirects;
|
net_req->follow_redirects = owner->context->follow_redirects;
|
||||||
|
|
||||||
|
@ -191,6 +208,11 @@ network_req_init(getdns_network_req *net_req, getdns_dns_req *owner,
|
||||||
/* Scheduling, touch only via _getdns_netreq_change_state!
|
/* Scheduling, touch only via _getdns_netreq_change_state!
|
||||||
*/
|
*/
|
||||||
net_req->state = NET_REQ_NOT_SENT;
|
net_req->state = NET_REQ_NOT_SENT;
|
||||||
|
/* A registered netreq (on a statefull transport)
|
||||||
|
* Deregister on reset and cleanup.
|
||||||
|
*/
|
||||||
|
net_req->query_id_registered = NULL;
|
||||||
|
net_req->node.key = NULL;
|
||||||
|
|
||||||
if (max_query_sz == 0) {
|
if (max_query_sz == 0) {
|
||||||
net_req->query = NULL;
|
net_req->query = NULL;
|
||||||
|
@ -914,6 +936,7 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop,
|
||||||
dnssec_return_full_validation_chain;
|
dnssec_return_full_validation_chain;
|
||||||
result->dnssec_return_validation_chain = dnssec_return_validation_chain
|
result->dnssec_return_validation_chain = dnssec_return_validation_chain
|
||||||
|| dnssec_return_full_validation_chain;
|
|| dnssec_return_full_validation_chain;
|
||||||
|
result->dnssec_extension_set = dnssec_extension_set;
|
||||||
result->edns_cookies = edns_cookies;
|
result->edns_cookies = edns_cookies;
|
||||||
#ifdef DNSSEC_ROADBLOCK_AVOIDANCE
|
#ifdef DNSSEC_ROADBLOCK_AVOIDANCE
|
||||||
result->dnssec_roadblock_avoidance = dnssec_roadblock_avoidance;
|
result->dnssec_roadblock_avoidance = dnssec_roadblock_avoidance;
|
||||||
|
@ -940,8 +963,10 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop,
|
||||||
result->upstreams->referenced++;
|
result->upstreams->referenced++;
|
||||||
|
|
||||||
result->finished_next = NULL;
|
result->finished_next = NULL;
|
||||||
|
result->ta_notify = NULL;
|
||||||
result->freed = NULL;
|
result->freed = NULL;
|
||||||
result->validating = 0;
|
result->validating = 0;
|
||||||
|
result->waiting_for_ta = 0;
|
||||||
result->is_dns_request = 1;
|
result->is_dns_request = 1;
|
||||||
result->request_timed_out = 0;
|
result->request_timed_out = 0;
|
||||||
result->chain = NULL;
|
result->chain = NULL;
|
||||||
|
|
46
src/server.c
46
src/server.c
|
@ -39,6 +39,8 @@
|
||||||
#include "types-internal.h"
|
#include "types-internal.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "util/rbtree.h"
|
#include "util/rbtree.h"
|
||||||
|
#include "util-internal.h"
|
||||||
|
#include "platform.h"
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
|
|
||||||
#define DNS_REQUEST_SZ 4096
|
#define DNS_REQUEST_SZ 4096
|
||||||
|
@ -135,11 +137,7 @@ static void tcp_connection_destroy(tcp_connection *conn)
|
||||||
loop->vmt->clear(loop, &conn->event);
|
loop->vmt->clear(loop, &conn->event);
|
||||||
|
|
||||||
if (conn->fd >= 0)
|
if (conn->fd >= 0)
|
||||||
#ifdef USE_WINSOCK
|
(void) _getdns_closesocket(conn->fd);
|
||||||
(void) closesocket(conn->fd);
|
|
||||||
#else
|
|
||||||
(void) close(conn->fd);
|
|
||||||
#endif
|
|
||||||
GETDNS_FREE(*mf, conn->read_buf);
|
GETDNS_FREE(*mf, conn->read_buf);
|
||||||
|
|
||||||
for (cur = conn->to_write; cur; cur = next) {
|
for (cur = conn->to_write; cur; cur = next) {
|
||||||
|
@ -189,7 +187,8 @@ static void tcp_write_cb(void *userarg)
|
||||||
}
|
}
|
||||||
to_write = conn->to_write;
|
to_write = conn->to_write;
|
||||||
if (conn->fd == -1 ||
|
if (conn->fd == -1 ||
|
||||||
(written = send(conn->fd, &to_write->write_buf[to_write->written],
|
(written = send(conn->fd,
|
||||||
|
(const void *)&to_write->write_buf[to_write->written],
|
||||||
to_write->write_buf_len - to_write->written, 0)) == -1) {
|
to_write->write_buf_len - to_write->written, 0)) == -1) {
|
||||||
|
|
||||||
/* IO error, close connection */
|
/* IO error, close connection */
|
||||||
|
@ -284,11 +283,7 @@ getdns_reply(
|
||||||
(struct sockaddr *)&conn->remote_in, conn->addrlen) == -1) {
|
(struct sockaddr *)&conn->remote_in, conn->addrlen) == -1) {
|
||||||
/* IO error, cleanup this listener */
|
/* IO error, cleanup this listener */
|
||||||
loop->vmt->clear(loop, &conn->l->event);
|
loop->vmt->clear(loop, &conn->l->event);
|
||||||
#ifdef USE_WINSOCK
|
_getdns_closesocket(conn->l->fd);
|
||||||
closesocket(conn->l->fd);
|
|
||||||
#else
|
|
||||||
close(conn->l->fd);
|
|
||||||
#endif
|
|
||||||
conn->l->fd = -1;
|
conn->l->fd = -1;
|
||||||
}
|
}
|
||||||
/* Unlink this connection */
|
/* Unlink this connection */
|
||||||
|
@ -367,7 +362,8 @@ static void tcp_read_cb(void *userarg)
|
||||||
(void) loop->vmt->schedule(loop, conn->fd,
|
(void) loop->vmt->schedule(loop, conn->fd,
|
||||||
DOWNSTREAM_IDLE_TIMEOUT, &conn->event);
|
DOWNSTREAM_IDLE_TIMEOUT, &conn->event);
|
||||||
|
|
||||||
if ((bytes_read = recv(conn->fd, conn->read_pos, conn->to_read, 0)) < 0) {
|
if ((bytes_read = recv(conn->fd,
|
||||||
|
(void *)conn->read_pos, conn->to_read, 0)) < 0) {
|
||||||
if (errno == EAGAIN || errno == EWOULDBLOCK)
|
if (errno == EAGAIN || errno == EWOULDBLOCK)
|
||||||
return; /* Come back to do the read later */
|
return; /* Come back to do the read later */
|
||||||
|
|
||||||
|
@ -481,11 +477,7 @@ static void tcp_accept_cb(void *userarg)
|
||||||
&conn->super.remote_in, &conn->super.addrlen)) == -1) {
|
&conn->super.remote_in, &conn->super.addrlen)) == -1) {
|
||||||
/* IO error, cleanup this listener */
|
/* IO error, cleanup this listener */
|
||||||
loop->vmt->clear(loop, &l->event);
|
loop->vmt->clear(loop, &l->event);
|
||||||
#ifdef USE_WINSOCK
|
_getdns_closesocket(l->fd);
|
||||||
closesocket(l->fd);
|
|
||||||
#else
|
|
||||||
close(l->fd);
|
|
||||||
#endif
|
|
||||||
l->fd = -1;
|
l->fd = -1;
|
||||||
GETDNS_FREE(*mf, conn);
|
GETDNS_FREE(*mf, conn);
|
||||||
return;
|
return;
|
||||||
|
@ -553,13 +545,17 @@ static void udp_read_cb(void *userarg)
|
||||||
conn->addrlen = sizeof(conn->remote_in);
|
conn->addrlen = sizeof(conn->remote_in);
|
||||||
if ((len = recvfrom(l->fd, (void *)buf, sizeof(buf), 0,
|
if ((len = recvfrom(l->fd, (void *)buf, sizeof(buf), 0,
|
||||||
(struct sockaddr *)&conn->remote_in, &conn->addrlen)) == -1) {
|
(struct sockaddr *)&conn->remote_in, &conn->addrlen)) == -1) {
|
||||||
|
if (_getdns_socketerror() == _getdns_ECONNRESET) {
|
||||||
|
/*
|
||||||
|
* WINSOCK gives ECONNRESET on ICMP Port Unreachable
|
||||||
|
* being received. Ignore it.
|
||||||
|
* */
|
||||||
|
GETDNS_FREE(*mf, conn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
/* IO error, cleanup this listener. */
|
/* IO error, cleanup this listener. */
|
||||||
loop->vmt->clear(loop, &l->event);
|
loop->vmt->clear(loop, &l->event);
|
||||||
#ifdef USE_WINSOCK
|
_getdns_closesocket(l->fd);
|
||||||
closesocket(l->fd);
|
|
||||||
#else
|
|
||||||
close(l->fd);
|
|
||||||
#endif
|
|
||||||
l->fd = -1;
|
l->fd = -1;
|
||||||
|
|
||||||
#if 0 && defined(SERVER_DEBUG) && SERVER_DEBUG
|
#if 0 && defined(SERVER_DEBUG) && SERVER_DEBUG
|
||||||
|
@ -708,11 +704,7 @@ static void remove_listeners(listen_set *set)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
loop->vmt->clear(loop, &l->event);
|
loop->vmt->clear(loop, &l->event);
|
||||||
#ifdef USE_WINSOCK
|
_getdns_closesocket(l->fd);
|
||||||
closesocket(l->fd);
|
|
||||||
#else
|
|
||||||
close(l->fd);
|
|
||||||
#endif
|
|
||||||
l->fd = -1;
|
l->fd = -1;
|
||||||
|
|
||||||
if (l->transport != GETDNS_TRANSPORT_TCP)
|
if (l->transport != GETDNS_TRANSPORT_TCP)
|
||||||
|
|
375
src/stub.c
375
src/stub.c
|
@ -38,17 +38,6 @@
|
||||||
*/
|
*/
|
||||||
#define INTERCEPT_COM_DS 0
|
#define INTERCEPT_COM_DS 0
|
||||||
|
|
||||||
#ifdef USE_POLL_DEFAULT_EVENTLOOP
|
|
||||||
# ifdef HAVE_SYS_POLL_H
|
|
||||||
# include <sys/poll.h>
|
|
||||||
# else
|
|
||||||
#ifdef USE_WINSOCK
|
|
||||||
#define poll(fdarray, nbsockets, timer) WSAPoll(fdarray, nbsockets, timer)
|
|
||||||
#else
|
|
||||||
# include <poll.h>
|
|
||||||
#endif
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
#include <openssl/conf.h>
|
#include <openssl/conf.h>
|
||||||
|
@ -63,21 +52,10 @@
|
||||||
#include "rr-iter.h"
|
#include "rr-iter.h"
|
||||||
#include "context.h"
|
#include "context.h"
|
||||||
#include "util-internal.h"
|
#include "util-internal.h"
|
||||||
|
#include "platform.h"
|
||||||
#include "general.h"
|
#include "general.h"
|
||||||
#include "pubkey-pinning.h"
|
#include "pubkey-pinning.h"
|
||||||
|
|
||||||
#ifdef USE_WINSOCK
|
|
||||||
typedef u_short sa_family_t;
|
|
||||||
#define _getdns_EWOULDBLOCK (WSAGetLastError() == WSATRY_AGAIN ||\
|
|
||||||
WSAGetLastError() == WSAEWOULDBLOCK)
|
|
||||||
#define _getdns_EINPROGRESS (WSAGetLastError() == WSAEINPROGRESS)
|
|
||||||
#define _getdns_EMFILE (WSAGetLastError() == WSAEMFILE)
|
|
||||||
#else
|
|
||||||
#define _getdns_EWOULDBLOCK (errno == EAGAIN || errno == EWOULDBLOCK)
|
|
||||||
#define _getdns_EINPROGRESS (errno == EINPROGRESS)
|
|
||||||
#define _getdns_EMFILE (errno == EMFILE)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* WSA TODO:
|
/* WSA TODO:
|
||||||
* STUB_TCP_WOULDBLOCK added to deal with edge triggered event loops (versus
|
* STUB_TCP_WOULDBLOCK added to deal with edge triggered event loops (versus
|
||||||
* level triggered). See also lines containing WSA TODO below...
|
* level triggered). See also lines containing WSA TODO below...
|
||||||
|
@ -105,8 +83,7 @@ static void upstream_write_cb(void *userarg);
|
||||||
static void upstream_idle_timeout_cb(void *userarg);
|
static void upstream_idle_timeout_cb(void *userarg);
|
||||||
static void upstream_schedule_netreq(getdns_upstream *upstream,
|
static void upstream_schedule_netreq(getdns_upstream *upstream,
|
||||||
getdns_network_req *netreq);
|
getdns_network_req *netreq);
|
||||||
static void upstream_reschedule_events(getdns_upstream *upstream,
|
static void upstream_reschedule_events(getdns_upstream *upstream);
|
||||||
uint64_t idle_timeout);
|
|
||||||
static int upstream_working_ok(getdns_upstream *upstream);
|
static int upstream_working_ok(getdns_upstream *upstream);
|
||||||
static int upstream_auth_status_ok(getdns_upstream *upstream,
|
static int upstream_auth_status_ok(getdns_upstream *upstream,
|
||||||
getdns_network_req *netreq);
|
getdns_network_req *netreq);
|
||||||
|
@ -438,13 +415,10 @@ tcp_connect(getdns_upstream *upstream, getdns_transport_list_t transport)
|
||||||
#endif
|
#endif
|
||||||
if (connect(fd, (struct sockaddr *)&upstream->addr,
|
if (connect(fd, (struct sockaddr *)&upstream->addr,
|
||||||
upstream->addr_len) == -1) {
|
upstream->addr_len) == -1) {
|
||||||
if (_getdns_EINPROGRESS || _getdns_EWOULDBLOCK)
|
if (_getdns_socketerror() == _getdns_EINPROGRESS ||
|
||||||
|
_getdns_socketerror() == _getdns_EWOULDBLOCK)
|
||||||
return fd;
|
return fd;
|
||||||
#ifdef USE_WINSOCK
|
_getdns_closesocket(fd);
|
||||||
closesocket(fd);
|
|
||||||
#else
|
|
||||||
close(fd);
|
|
||||||
#endif
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return fd;
|
return fd;
|
||||||
|
@ -455,22 +429,13 @@ tcp_connected(getdns_upstream *upstream) {
|
||||||
int error = 0;
|
int error = 0;
|
||||||
socklen_t len = (socklen_t)sizeof(error);
|
socklen_t len = (socklen_t)sizeof(error);
|
||||||
getsockopt(upstream->fd, SOL_SOCKET, SO_ERROR, (void*)&error, &len);
|
getsockopt(upstream->fd, SOL_SOCKET, SO_ERROR, (void*)&error, &len);
|
||||||
#ifdef USE_WINSOCK
|
if (error == _getdns_EINPROGRESS)
|
||||||
if (error == WSAEINPROGRESS)
|
|
||||||
return STUB_TCP_AGAIN;
|
return STUB_TCP_AGAIN;
|
||||||
else if (error == WSAEWOULDBLOCK)
|
else if (error == _getdns_EWOULDBLOCK || error == _getdns_EAGAIN)
|
||||||
return STUB_TCP_WOULDBLOCK;
|
|
||||||
else if (error != 0)
|
|
||||||
return STUB_SETUP_ERROR;
|
|
||||||
#else
|
|
||||||
if (error == EINPROGRESS)
|
|
||||||
return STUB_TCP_AGAIN;
|
|
||||||
else if (error == EWOULDBLOCK || error == EAGAIN)
|
|
||||||
return STUB_TCP_WOULDBLOCK;
|
return STUB_TCP_WOULDBLOCK;
|
||||||
else if (error != 0) {
|
else if (error != 0) {
|
||||||
return STUB_SETUP_ERROR;
|
return STUB_SETUP_ERROR;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
if (upstream->transport == GETDNS_TRANSPORT_TCP &&
|
if (upstream->transport == GETDNS_TRANSPORT_TCP &&
|
||||||
upstream->queries_sent == 0) {
|
upstream->queries_sent == 0) {
|
||||||
upstream->conn_state = GETDNS_CONN_OPEN;
|
upstream->conn_state = GETDNS_CONN_OPEN;
|
||||||
|
@ -496,42 +461,56 @@ stub_next_upstream(getdns_network_req *netreq)
|
||||||
dnsreq->upstreams->current_udp = 0;
|
dnsreq->upstreams->current_udp = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
remove_from_write_queue(getdns_upstream *upstream, getdns_network_req * netreq)
|
||||||
|
{
|
||||||
|
getdns_network_req *r, *prev_r;
|
||||||
|
|
||||||
|
for ( r = upstream->write_queue, prev_r = NULL
|
||||||
|
; r
|
||||||
|
; prev_r = r, r = r->write_queue_tail) {
|
||||||
|
|
||||||
|
if (r != netreq)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (prev_r)
|
||||||
|
prev_r->write_queue_tail = r->write_queue_tail;
|
||||||
|
else
|
||||||
|
upstream->write_queue = r->write_queue_tail;
|
||||||
|
|
||||||
|
if (r == upstream->write_queue_last) {
|
||||||
|
/* If r was the last netreq,
|
||||||
|
* its write_queue tail MUST be NULL
|
||||||
|
*/
|
||||||
|
assert(r->write_queue_tail == NULL);
|
||||||
|
upstream->write_queue_last = prev_r ? prev_r : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
netreq->write_queue_tail = NULL;
|
||||||
|
break; /* netreq found and removed */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
stub_cleanup(getdns_network_req *netreq)
|
stub_cleanup(getdns_network_req *netreq)
|
||||||
{
|
{
|
||||||
DEBUG_STUB("%s %-35s: MSG: %p\n",
|
DEBUG_STUB("%s %-35s: MSG: %p\n",
|
||||||
STUB_DEBUG_CLEANUP, __FUNC__, (void*)netreq);
|
STUB_DEBUG_CLEANUP, __FUNC__, (void*)netreq);
|
||||||
getdns_dns_req *dnsreq = netreq->owner;
|
getdns_dns_req *dnsreq = netreq->owner;
|
||||||
getdns_network_req *r, *prev_r;
|
|
||||||
getdns_upstream *upstream;
|
|
||||||
|
|
||||||
GETDNS_CLEAR_EVENT(dnsreq->loop, &netreq->event);
|
GETDNS_CLEAR_EVENT(dnsreq->loop, &netreq->event);
|
||||||
|
|
||||||
/* Nothing globally scheduled? Then nothing queued */
|
if (netreq->query_id_registered) {
|
||||||
if (!netreq->upstream || !(upstream = netreq->upstream)->event.ev)
|
(void) _getdns_rbtree_delete(
|
||||||
return;
|
netreq->query_id_registered, netreq->node.key);
|
||||||
|
netreq->query_id_registered = NULL;
|
||||||
/* Delete from upstream->netreq_by_query_id (if present) */
|
netreq->node.key = NULL;
|
||||||
(void) _getdns_rbtree_delete(&upstream->netreq_by_query_id,
|
}
|
||||||
(void *)(intptr_t)GLDNS_ID_WIRE(netreq->query));
|
if (netreq->upstream) {
|
||||||
|
remove_from_write_queue(netreq->upstream, netreq);
|
||||||
/* Delete from upstream->write_queue (if present) */
|
if (netreq->upstream->event.ev)
|
||||||
for (prev_r = NULL, r = upstream->write_queue; r;
|
upstream_reschedule_events(netreq->upstream);
|
||||||
prev_r = r, r = r->write_queue_tail)
|
}
|
||||||
|
|
||||||
if (r == netreq) {
|
|
||||||
if (prev_r)
|
|
||||||
prev_r->write_queue_tail = r->write_queue_tail;
|
|
||||||
else
|
|
||||||
upstream->write_queue = r->write_queue_tail;
|
|
||||||
|
|
||||||
if (r == upstream->write_queue_last)
|
|
||||||
upstream->write_queue_last =
|
|
||||||
prev_r ? prev_r : NULL;
|
|
||||||
netreq->write_queue_tail = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
upstream_reschedule_events(upstream, upstream->keepalive_timeout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -545,17 +524,8 @@ upstream_failed(getdns_upstream *upstream, int during_setup)
|
||||||
when idle.*/
|
when idle.*/
|
||||||
/* [TLS1]TODO: Work out how to re-open the connection and re-try
|
/* [TLS1]TODO: Work out how to re-open the connection and re-try
|
||||||
the queries if there is only one upstream.*/
|
the queries if there is only one upstream.*/
|
||||||
|
GETDNS_CLEAR_EVENT(upstream->loop, &upstream->event);
|
||||||
if (during_setup) {
|
if (during_setup) {
|
||||||
/* Reset timeout on setup failure to trigger fallback handling.*/
|
|
||||||
GETDNS_CLEAR_EVENT(upstream->loop, &upstream->event);
|
|
||||||
/* Need this check because if the setup failed because the interface is
|
|
||||||
not up we get -1 and then a seg fault. Found when using IPv6 address
|
|
||||||
but IPv6 interface not enabled.*/
|
|
||||||
if (upstream->fd != -1) {
|
|
||||||
GETDNS_SCHEDULE_EVENT(upstream->loop, upstream->fd, TIMEOUT_FOREVER,
|
|
||||||
getdns_eventloop_event_init(&upstream->event, upstream,
|
|
||||||
NULL, upstream_write_cb, NULL));
|
|
||||||
}
|
|
||||||
/* Special case if failure was due to authentication issues since this
|
/* Special case if failure was due to authentication issues since this
|
||||||
upstream could be used oppotunistically with no problem.*/
|
upstream could be used oppotunistically with no problem.*/
|
||||||
if (!(upstream->transport == GETDNS_TRANSPORT_TLS &&
|
if (!(upstream->transport == GETDNS_TRANSPORT_TLS &&
|
||||||
|
@ -565,6 +535,11 @@ upstream_failed(getdns_upstream *upstream, int during_setup)
|
||||||
upstream->conn_shutdowns++;
|
upstream->conn_shutdowns++;
|
||||||
/* [TLS1]TODO: Re-try these queries if possible.*/
|
/* [TLS1]TODO: Re-try these queries if possible.*/
|
||||||
}
|
}
|
||||||
|
upstream->conn_state = GETDNS_CONN_TEARDOWN;
|
||||||
|
|
||||||
|
while (upstream->write_queue)
|
||||||
|
upstream_write_cb(upstream);
|
||||||
|
|
||||||
while (upstream->netreq_by_query_id.count) {
|
while (upstream->netreq_by_query_id.count) {
|
||||||
netreq = (getdns_network_req *)
|
netreq = (getdns_network_req *)
|
||||||
_getdns_rbtree_first(&upstream->netreq_by_query_id);
|
_getdns_rbtree_first(&upstream->netreq_by_query_id);
|
||||||
|
@ -572,7 +547,7 @@ upstream_failed(getdns_upstream *upstream, int during_setup)
|
||||||
_getdns_netreq_change_state(netreq, NET_REQ_ERRORED);
|
_getdns_netreq_change_state(netreq, NET_REQ_ERRORED);
|
||||||
_getdns_check_dns_req_complete(netreq->owner);
|
_getdns_check_dns_req_complete(netreq->owner);
|
||||||
}
|
}
|
||||||
upstream->conn_state = GETDNS_CONN_TEARDOWN;
|
_getdns_upstream_shutdown(upstream);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -582,11 +557,7 @@ _getdns_cancel_stub_request(getdns_network_req *netreq)
|
||||||
STUB_DEBUG_CLEANUP, __FUNC__, (void*)netreq);
|
STUB_DEBUG_CLEANUP, __FUNC__, (void*)netreq);
|
||||||
stub_cleanup(netreq);
|
stub_cleanup(netreq);
|
||||||
if (netreq->fd >= 0) {
|
if (netreq->fd >= 0) {
|
||||||
#ifdef USE_WINSOCK
|
_getdns_closesocket(netreq->fd);
|
||||||
closesocket(netreq->fd);
|
|
||||||
#else
|
|
||||||
close(netreq->fd);
|
|
||||||
#endif
|
|
||||||
netreq->fd = -1;
|
netreq->fd = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -601,15 +572,11 @@ stub_timeout_cb(void *userarg)
|
||||||
_getdns_netreq_change_state(netreq, NET_REQ_TIMED_OUT);
|
_getdns_netreq_change_state(netreq, NET_REQ_TIMED_OUT);
|
||||||
/* Handle upstream*/
|
/* Handle upstream*/
|
||||||
if (netreq->fd >= 0) {
|
if (netreq->fd >= 0) {
|
||||||
#ifdef USE_WINSOCK
|
_getdns_closesocket(netreq->fd);
|
||||||
closesocket(netreq->fd);
|
|
||||||
#else
|
|
||||||
close(netreq->fd);
|
|
||||||
#endif
|
|
||||||
netreq->fd = -1;
|
netreq->fd = -1;
|
||||||
netreq->upstream->udp_timeouts++;
|
netreq->upstream->udp_timeouts++;
|
||||||
if (netreq->upstream->udp_timeouts % 100 == 0)
|
if (netreq->upstream->udp_timeouts % 100 == 0)
|
||||||
_getdns_upstream_log(netreq->upstream, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_DEBUG,
|
_getdns_upstream_log(netreq->upstream, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_INFO,
|
||||||
"%-40s : Upstream stats: Transport=UDP - Resp=%d,Timeouts=%d\n",
|
"%-40s : Upstream stats: Transport=UDP - Resp=%d,Timeouts=%d\n",
|
||||||
netreq->upstream->addr_str,
|
netreq->upstream->addr_str,
|
||||||
(int)netreq->upstream->udp_responses, (int)netreq->upstream->udp_timeouts);
|
(int)netreq->upstream->udp_responses, (int)netreq->upstream->udp_timeouts);
|
||||||
|
@ -641,41 +608,12 @@ upstream_idle_timeout_cb(void *userarg)
|
||||||
static void
|
static void
|
||||||
upstream_setup_timeout_cb(void *userarg)
|
upstream_setup_timeout_cb(void *userarg)
|
||||||
{
|
{
|
||||||
int ret;
|
|
||||||
getdns_upstream *upstream = (getdns_upstream *)userarg;
|
getdns_upstream *upstream = (getdns_upstream *)userarg;
|
||||||
#ifdef USE_POLL_DEFAULT_EVENTLOOP
|
|
||||||
struct pollfd fds;
|
|
||||||
#else
|
|
||||||
fd_set fds;
|
|
||||||
struct timeval tval;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
DEBUG_STUB("%s %-35s: FD: %d\n",
|
DEBUG_STUB("%s %-35s: FD: %d\n",
|
||||||
STUB_DEBUG_CLEANUP, __FUNC__, upstream->fd);
|
STUB_DEBUG_CLEANUP, __FUNC__, upstream->fd);
|
||||||
/* Clean up and trigger a write to let the fallback code to its job */
|
|
||||||
upstream_failed(upstream, 1);
|
|
||||||
|
|
||||||
/* Need to handle the case where the far end doesn't respond to a
|
upstream_failed(upstream, 1);
|
||||||
* TCP SYN and doesn't do a reset (as is the case with e.g. 8.8.8.8@853).
|
|
||||||
* For that case the socket never becomes writable so doesn't trigger any
|
|
||||||
* callbacks. If so then clear out the queue in one go.*/
|
|
||||||
#ifdef USE_POLL_DEFAULT_EVENTLOOP
|
|
||||||
fds.fd = upstream->fd;
|
|
||||||
fds.events = POLLOUT;
|
|
||||||
ret = poll(&fds, 1, 0);
|
|
||||||
#else
|
|
||||||
FD_ZERO(&fds);
|
|
||||||
FD_SET((int)(upstream->fd), &fds);
|
|
||||||
tval.tv_sec = 0;
|
|
||||||
tval.tv_usec = 0;
|
|
||||||
ret = select(upstream->fd+1, NULL, &fds, NULL, &tval);
|
|
||||||
#endif
|
|
||||||
if (ret == 0) {
|
|
||||||
DEBUG_STUB("%s %-35s: FD: %d Cleaning up dangling queue\n",
|
|
||||||
STUB_DEBUG_CLEANUP, __FUNC__, upstream->fd);
|
|
||||||
while (upstream->write_queue)
|
|
||||||
upstream_write_cb(upstream);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -701,7 +639,7 @@ stub_tcp_read(int fd, getdns_tcp_state *tcp, struct mem_funcs *mf)
|
||||||
}
|
}
|
||||||
read = recv(fd, (void *)tcp->read_pos, tcp->to_read, 0);
|
read = recv(fd, (void *)tcp->read_pos, tcp->to_read, 0);
|
||||||
if (read < 0) {
|
if (read < 0) {
|
||||||
if (_getdns_EWOULDBLOCK)
|
if (_getdns_socketerror() == _getdns_EWOULDBLOCK)
|
||||||
return STUB_TCP_WOULDBLOCK;
|
return STUB_TCP_WOULDBLOCK;
|
||||||
else
|
else
|
||||||
return STUB_TCP_ERROR;
|
return STUB_TCP_ERROR;
|
||||||
|
@ -775,6 +713,7 @@ stub_tcp_write(int fd, getdns_tcp_state *tcp, getdns_network_req *netreq)
|
||||||
|
|
||||||
} while (!_getdns_rbtree_insert(
|
} while (!_getdns_rbtree_insert(
|
||||||
&netreq->upstream->netreq_by_query_id, &netreq->node));
|
&netreq->upstream->netreq_by_query_id, &netreq->node));
|
||||||
|
netreq->query_id_registered = &netreq->upstream->netreq_by_query_id;
|
||||||
|
|
||||||
GLDNS_ID_SET(netreq->query, query_id);
|
GLDNS_ID_SET(netreq->query, query_id);
|
||||||
|
|
||||||
|
@ -818,11 +757,11 @@ stub_tcp_write(int fd, getdns_tcp_state *tcp, getdns_network_req *netreq)
|
||||||
(struct sockaddr *)&(netreq->upstream->addr),
|
(struct sockaddr *)&(netreq->upstream->addr),
|
||||||
netreq->upstream->addr_len);
|
netreq->upstream->addr_len);
|
||||||
#endif
|
#endif
|
||||||
if ((written < 0 && (_getdns_EWOULDBLOCK ||
|
if ((written < 0 && (_getdns_socketerror() == _getdns_EWOULDBLOCK ||
|
||||||
/* Add the error case where the connection is in progress which is when
|
/* Add the error case where the connection is in progress which is when
|
||||||
a cookie is not available (e.g. when doing the first request to an
|
a cookie is not available (e.g. when doing the first request to an
|
||||||
upstream). We must let the handshake complete since non-blocking. */
|
upstream). We must let the handshake complete since non-blocking. */
|
||||||
_getdns_EINPROGRESS)) ||
|
_getdns_socketerror() == _getdns_EINPROGRESS)) ||
|
||||||
(size_t)written < pkt_len + 2) {
|
(size_t)written < pkt_len + 2) {
|
||||||
|
|
||||||
/* We couldn't write the whole packet.
|
/* We couldn't write the whole packet.
|
||||||
|
@ -850,15 +789,10 @@ stub_tcp_write(int fd, getdns_tcp_state *tcp, getdns_network_req *netreq)
|
||||||
|
|
||||||
/* Coming back from an earlier unfinished write or handshake.
|
/* Coming back from an earlier unfinished write or handshake.
|
||||||
* Try to send remaining data */
|
* Try to send remaining data */
|
||||||
#ifdef USE_WINSOCK
|
written = send(fd, (void *)(tcp->write_buf + tcp->written),
|
||||||
written = send(fd, tcp->write_buf + tcp->written,
|
|
||||||
tcp->write_buf_len - tcp->written, 0);
|
tcp->write_buf_len - tcp->written, 0);
|
||||||
#else
|
|
||||||
written = write(fd, tcp->write_buf + tcp->written,
|
|
||||||
tcp->write_buf_len - tcp->written);
|
|
||||||
#endif
|
|
||||||
if (written == -1) {
|
if (written == -1) {
|
||||||
if (_getdns_EWOULDBLOCK)
|
if (_getdns_socketerror() == _getdns_EWOULDBLOCK)
|
||||||
return STUB_TCP_WOULDBLOCK;
|
return STUB_TCP_WOULDBLOCK;
|
||||||
else {
|
else {
|
||||||
DEBUG_STUB("%s %-35s: MSG: %p error while writing to TCP socket:"
|
DEBUG_STUB("%s %-35s: MSG: %p error while writing to TCP socket:"
|
||||||
|
@ -909,7 +843,7 @@ tls_verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
|
||||||
X509_verify_cert_error_string(err));
|
X509_verify_cert_error_string(err));
|
||||||
#endif
|
#endif
|
||||||
if (!preverify_ok && !upstream->tls_fallback_ok)
|
if (!preverify_ok && !upstream->tls_fallback_ok)
|
||||||
_getdns_upstream_log(upstream, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_DEBUG,
|
_getdns_upstream_log(upstream, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_ERR,
|
||||||
"%-40s : Verify failed : Transport=TLS - *Failure* - (%d) \"%s\"\n",
|
"%-40s : Verify failed : Transport=TLS - *Failure* - (%d) \"%s\"\n",
|
||||||
upstream->addr_str, err,
|
upstream->addr_str, err,
|
||||||
X509_verify_cert_error_string(err));
|
X509_verify_cert_error_string(err));
|
||||||
|
@ -945,7 +879,7 @@ tls_verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
|
||||||
DEBUG_STUB("%s %-35s: FD: %d, WARNING: Proceeding even though pinset validation failed!\n",
|
DEBUG_STUB("%s %-35s: FD: %d, WARNING: Proceeding even though pinset validation failed!\n",
|
||||||
STUB_DEBUG_SETUP_TLS, __FUNC__, upstream->fd);
|
STUB_DEBUG_SETUP_TLS, __FUNC__, upstream->fd);
|
||||||
else
|
else
|
||||||
_getdns_upstream_log(upstream, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_DEBUG,
|
_getdns_upstream_log(upstream, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_ERR,
|
||||||
"%-40s : Conn failed : Transport=TLS - *Failure* - Pinset validation failure\n",
|
"%-40s : Conn failed : Transport=TLS - *Failure* - Pinset validation failure\n",
|
||||||
upstream->addr_str);
|
upstream->addr_str);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1016,8 +950,11 @@ tls_create_object(getdns_dns_req *dnsreq, int fd, getdns_upstream *upstream)
|
||||||
X509_VERIFY_PARAM_set1_host(param, upstream->tls_auth_name, 0);
|
X509_VERIFY_PARAM_set1_host(param, upstream->tls_auth_name, 0);
|
||||||
#else
|
#else
|
||||||
if (dnsreq->netreqs[0]->tls_auth_min == GETDNS_AUTHENTICATION_REQUIRED) {
|
if (dnsreq->netreqs[0]->tls_auth_min == GETDNS_AUTHENTICATION_REQUIRED) {
|
||||||
DEBUG_STUB("%s %-35s: ERROR: TLS Authentication functionality not available\n",
|
DEBUG_STUB("%s %-35s: ERROR: Hostname Authentication not available from TLS library (check library version)\n",
|
||||||
STUB_DEBUG_SETUP_TLS, __FUNC__);
|
STUB_DEBUG_SETUP_TLS, __FUNC__);
|
||||||
|
_getdns_upstream_log(upstream, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_ERR,
|
||||||
|
"%-40s : ERROR: Hostname Authentication not available from TLS library (check library version)\n",
|
||||||
|
upstream->addr_str);
|
||||||
upstream->tls_hs_state = GETDNS_HS_FAILED;
|
upstream->tls_hs_state = GETDNS_HS_FAILED;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -1273,6 +1210,7 @@ stub_tls_write(getdns_upstream *upstream, getdns_tcp_state *tcp,
|
||||||
|
|
||||||
} while (!_getdns_rbtree_insert(
|
} while (!_getdns_rbtree_insert(
|
||||||
&netreq->upstream->netreq_by_query_id, &netreq->node));
|
&netreq->upstream->netreq_by_query_id, &netreq->node));
|
||||||
|
netreq->query_id_registered = &netreq->upstream->netreq_by_query_id;
|
||||||
|
|
||||||
GLDNS_ID_SET(netreq->query, query_id);
|
GLDNS_ID_SET(netreq->query, query_id);
|
||||||
|
|
||||||
|
@ -1397,7 +1335,8 @@ stub_udp_read_cb(void *userarg)
|
||||||
* i.e. overflow
|
* i.e. overflow
|
||||||
*/
|
*/
|
||||||
0, NULL, NULL);
|
0, NULL, NULL);
|
||||||
if (read == -1 && _getdns_EWOULDBLOCK)
|
if (read == -1 && (_getdns_socketerror() == _getdns_EWOULDBLOCK ||
|
||||||
|
_getdns_socketerror() == _getdns_ECONNRESET))
|
||||||
return; /* Try again later */
|
return; /* Try again later */
|
||||||
|
|
||||||
if (read == -1) {
|
if (read == -1) {
|
||||||
|
@ -1409,11 +1348,7 @@ stub_udp_read_cb(void *userarg)
|
||||||
_getdns_netreq_change_state(netreq, NET_REQ_ERRORED);
|
_getdns_netreq_change_state(netreq, NET_REQ_ERRORED);
|
||||||
/* Handle upstream*/
|
/* Handle upstream*/
|
||||||
if (netreq->fd >= 0) {
|
if (netreq->fd >= 0) {
|
||||||
#ifdef USE_WINSOCK
|
_getdns_closesocket(netreq->fd);
|
||||||
closesocket(netreq->fd);
|
|
||||||
#else
|
|
||||||
close(netreq->fd);
|
|
||||||
#endif
|
|
||||||
netreq->fd = -1;
|
netreq->fd = -1;
|
||||||
stub_next_upstream(netreq);
|
stub_next_upstream(netreq);
|
||||||
}
|
}
|
||||||
|
@ -1433,11 +1368,7 @@ stub_udp_read_cb(void *userarg)
|
||||||
|
|
||||||
GETDNS_CLEAR_EVENT(dnsreq->loop, &netreq->event);
|
GETDNS_CLEAR_EVENT(dnsreq->loop, &netreq->event);
|
||||||
|
|
||||||
#ifdef USE_WINSOCK
|
_getdns_closesocket(netreq->fd);
|
||||||
closesocket(netreq->fd);
|
|
||||||
#else
|
|
||||||
close(netreq->fd);
|
|
||||||
#endif
|
|
||||||
netreq->fd = -1;
|
netreq->fd = -1;
|
||||||
while (GLDNS_TC_WIRE(netreq->response)) {
|
while (GLDNS_TC_WIRE(netreq->response)) {
|
||||||
DEBUG_STUB("%s %-35s: MSG: %p TC bit set in response \n", STUB_DEBUG_READ,
|
DEBUG_STUB("%s %-35s: MSG: %p TC bit set in response \n", STUB_DEBUG_READ,
|
||||||
|
@ -1474,7 +1405,7 @@ stub_udp_read_cb(void *userarg)
|
||||||
upstream->udp_responses++;
|
upstream->udp_responses++;
|
||||||
if (upstream->udp_responses == 1 ||
|
if (upstream->udp_responses == 1 ||
|
||||||
upstream->udp_responses % 100 == 0)
|
upstream->udp_responses % 100 == 0)
|
||||||
_getdns_upstream_log(upstream, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_DEBUG,
|
_getdns_upstream_log(upstream, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_INFO,
|
||||||
"%-40s : Upstream stats: Transport=UDP - Resp=%d,Timeouts=%d\n",
|
"%-40s : Upstream stats: Transport=UDP - Resp=%d,Timeouts=%d\n",
|
||||||
upstream->addr_str,
|
upstream->addr_str,
|
||||||
(int)upstream->udp_responses, (int)upstream->udp_timeouts);
|
(int)upstream->udp_responses, (int)upstream->udp_timeouts);
|
||||||
|
@ -1530,11 +1461,7 @@ stub_udp_write_cb(void *userarg)
|
||||||
_getdns_netreq_change_state(netreq, NET_REQ_ERRORED);
|
_getdns_netreq_change_state(netreq, NET_REQ_ERRORED);
|
||||||
/* Handle upstream*/
|
/* Handle upstream*/
|
||||||
if (netreq->fd >= 0) {
|
if (netreq->fd >= 0) {
|
||||||
#ifdef USE_WINSOCK
|
_getdns_closesocket(netreq->fd);
|
||||||
closesocket(netreq->fd);
|
|
||||||
#else
|
|
||||||
close(netreq->fd);
|
|
||||||
#endif
|
|
||||||
netreq->fd = -1;
|
netreq->fd = -1;
|
||||||
stub_next_upstream(netreq);
|
stub_next_upstream(netreq);
|
||||||
}
|
}
|
||||||
|
@ -1601,7 +1528,6 @@ upstream_read_cb(void *userarg)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
||||||
/* Lookup netreq */
|
/* Lookup netreq */
|
||||||
query_id = (uint16_t) q;
|
query_id = (uint16_t) q;
|
||||||
query_id_intptr = (intptr_t) query_id;
|
query_id_intptr = (intptr_t) query_id;
|
||||||
|
@ -1613,7 +1539,16 @@ upstream_read_cb(void *userarg)
|
||||||
upstream->tcp.to_read = 2;
|
upstream->tcp.to_read = 2;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (netreq->query_id_registered == &upstream->netreq_by_query_id) {
|
||||||
|
netreq->query_id_registered = NULL;
|
||||||
|
netreq->node.key = NULL;
|
||||||
|
|
||||||
|
} else if (netreq->query_id_registered) {
|
||||||
|
(void) _getdns_rbtree_delete(
|
||||||
|
netreq->query_id_registered, netreq->node.key);
|
||||||
|
netreq->query_id_registered = NULL;
|
||||||
|
netreq->node.key = NULL;
|
||||||
|
}
|
||||||
DEBUG_STUB("%s %-35s: MSG: %p (read)\n",
|
DEBUG_STUB("%s %-35s: MSG: %p (read)\n",
|
||||||
STUB_DEBUG_READ, __FUNC__, (void*)netreq);
|
STUB_DEBUG_READ, __FUNC__, (void*)netreq);
|
||||||
_getdns_netreq_change_state(netreq, NET_REQ_FINISHED);
|
_getdns_netreq_change_state(netreq, NET_REQ_FINISHED);
|
||||||
|
@ -1700,7 +1635,9 @@ upstream_write_cb(void *userarg)
|
||||||
__FUNC__, (void*)netreq);
|
__FUNC__, (void*)netreq);
|
||||||
|
|
||||||
/* Health checks on current connection */
|
/* Health checks on current connection */
|
||||||
if (upstream->conn_state == GETDNS_CONN_TEARDOWN)
|
if (upstream->conn_state == GETDNS_CONN_TEARDOWN ||
|
||||||
|
upstream->conn_state == GETDNS_CONN_CLOSED ||
|
||||||
|
upstream->fd == -1)
|
||||||
q = STUB_CONN_GONE;
|
q = STUB_CONN_GONE;
|
||||||
else if (!upstream_working_ok(upstream))
|
else if (!upstream_working_ok(upstream))
|
||||||
q = STUB_TCP_ERROR;
|
q = STUB_TCP_ERROR;
|
||||||
|
@ -1724,10 +1661,8 @@ upstream_write_cb(void *userarg)
|
||||||
/* Could not complete the set up. Need to fallback.*/
|
/* Could not complete the set up. Need to fallback.*/
|
||||||
DEBUG_STUB("%s %-35s: Upstream: %p ERROR = %d\n", STUB_DEBUG_WRITE,
|
DEBUG_STUB("%s %-35s: Upstream: %p ERROR = %d\n", STUB_DEBUG_WRITE,
|
||||||
__FUNC__, (void*)userarg, q);
|
__FUNC__, (void*)userarg, q);
|
||||||
(void) _getdns_rbtree_delete(&upstream->netreq_by_query_id,
|
|
||||||
(void *)(intptr_t)GLDNS_ID_WIRE(netreq->query));
|
|
||||||
upstream_failed(upstream, (q == STUB_TCP_ERROR ? 0:1));
|
upstream_failed(upstream, (q == STUB_TCP_ERROR ? 0:1));
|
||||||
/* Fall through */
|
return;
|
||||||
case STUB_CONN_GONE:
|
case STUB_CONN_GONE:
|
||||||
case STUB_NO_AUTH:
|
case STUB_NO_AUTH:
|
||||||
/* Cleaning up after connection or auth check failure. Need to fallback. */
|
/* Cleaning up after connection or auth check failure. Need to fallback. */
|
||||||
|
@ -1744,6 +1679,9 @@ upstream_write_cb(void *userarg)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
/* Unqueue the netreq from the write_queue */
|
||||||
|
remove_from_write_queue(upstream, netreq);
|
||||||
|
|
||||||
if (netreq->owner->return_call_reporting &&
|
if (netreq->owner->return_call_reporting &&
|
||||||
netreq->upstream->tls_obj &&
|
netreq->upstream->tls_obj &&
|
||||||
netreq->debug_tls_peer_cert.data == NULL &&
|
netreq->debug_tls_peer_cert.data == NULL &&
|
||||||
|
@ -1756,9 +1694,9 @@ upstream_write_cb(void *userarg)
|
||||||
netreq->debug_tls_auth_status = netreq->upstream->tls_auth_state;
|
netreq->debug_tls_auth_status = netreq->upstream->tls_auth_state;
|
||||||
upstream->queries_sent++;
|
upstream->queries_sent++;
|
||||||
|
|
||||||
/* Unqueue the netreq from the write_queue */
|
/* Empty write_queue?, then deschedule upstream write_cb */
|
||||||
if (!(upstream->write_queue = netreq->write_queue_tail)) {
|
if (upstream->write_queue == NULL) {
|
||||||
upstream->write_queue_last = NULL;
|
assert(upstream->write_queue_last == NULL);
|
||||||
GETDNS_CLEAR_EVENT(upstream->loop, &upstream->event);
|
GETDNS_CLEAR_EVENT(upstream->loop, &upstream->event);
|
||||||
upstream->event.write_cb = NULL;
|
upstream->event.write_cb = NULL;
|
||||||
/* Reschedule (if already reading) to clear writable */
|
/* Reschedule (if already reading) to clear writable */
|
||||||
|
@ -1806,13 +1744,20 @@ upstream_active(getdns_upstream *upstream)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
upstream_usable(getdns_upstream *upstream)
|
upstream_usable(getdns_upstream *upstream, int backoff_ok)
|
||||||
{
|
{
|
||||||
|
/* If backoff_ok is not true then only use upstreams that are in a healthy
|
||||||
|
state. */
|
||||||
if ((upstream->conn_state == GETDNS_CONN_CLOSED ||
|
if ((upstream->conn_state == GETDNS_CONN_CLOSED ||
|
||||||
upstream->conn_state == GETDNS_CONN_SETUP ||
|
upstream->conn_state == GETDNS_CONN_SETUP ||
|
||||||
upstream->conn_state == GETDNS_CONN_OPEN) &&
|
upstream->conn_state == GETDNS_CONN_OPEN) &&
|
||||||
upstream->keepalive_shutdown == 0)
|
upstream->keepalive_shutdown == 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
/* Otherwise, allow upstreams that are backed off to be used because that
|
||||||
|
is better that having no upstream at all. */
|
||||||
|
if (backoff_ok == 1 &&
|
||||||
|
upstream->conn_state == GETDNS_CONN_BACKOFF)
|
||||||
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1828,15 +1773,22 @@ upstream_stats(getdns_upstream *upstream)
|
||||||
{
|
{
|
||||||
/* [TLS1]TODO: This arbitrary logic at the moment - review and improve!*/
|
/* [TLS1]TODO: This arbitrary logic at the moment - review and improve!*/
|
||||||
return (upstream->total_responses - upstream->total_timeouts
|
return (upstream->total_responses - upstream->total_timeouts
|
||||||
- upstream->conn_shutdowns*GETDNS_TRANSPORT_FAIL_MULT);
|
- upstream->conn_shutdowns*GETDNS_TRANSPORT_FAIL_MULT
|
||||||
|
- upstream->conn_setup_failed);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
upstream_valid(getdns_upstream *upstream,
|
upstream_valid(getdns_upstream *upstream,
|
||||||
getdns_transport_list_t transport,
|
getdns_transport_list_t transport,
|
||||||
getdns_network_req *netreq)
|
getdns_network_req *netreq,
|
||||||
|
int backoff_ok)
|
||||||
{
|
{
|
||||||
if (!(upstream->transport == transport && upstream_usable(upstream)))
|
/* Checking upstreams with backoff_ok true will aslo return upstreams
|
||||||
|
that are in a backoff state. Otherwise only use upstreams that have
|
||||||
|
a 'good' connection state. backoff_ok is usefull when no upstreams at all
|
||||||
|
are valid, for example when the network connection is down and need to
|
||||||
|
keep trying to connect before failing completely. */
|
||||||
|
if (!(upstream->transport == transport && upstream_usable(upstream, backoff_ok)))
|
||||||
return 0;
|
return 0;
|
||||||
if (transport == GETDNS_TRANSPORT_TCP)
|
if (transport == GETDNS_TRANSPORT_TCP)
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -1887,7 +1839,7 @@ upstream_select_stateful(getdns_network_req *netreq, getdns_transport_list_t tra
|
||||||
if (upstreams->upstreams[i].conn_state == GETDNS_CONN_BACKOFF &&
|
if (upstreams->upstreams[i].conn_state == GETDNS_CONN_BACKOFF &&
|
||||||
upstreams->upstreams[i].conn_retry_time < now) {
|
upstreams->upstreams[i].conn_retry_time < now) {
|
||||||
upstreams->upstreams[i].conn_state = GETDNS_CONN_CLOSED;
|
upstreams->upstreams[i].conn_state = GETDNS_CONN_CLOSED;
|
||||||
_getdns_upstream_log(upstream, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_DEBUG,
|
_getdns_upstream_log(upstream, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_NOTICE,
|
||||||
"%-40s : Re-instating upstream\n",
|
"%-40s : Re-instating upstream\n",
|
||||||
upstreams->upstreams[i].addr_str);
|
upstreams->upstreams[i].addr_str);
|
||||||
}
|
}
|
||||||
|
@ -1902,14 +1854,13 @@ upstream_select_stateful(getdns_network_req *netreq, getdns_transport_list_t tra
|
||||||
}
|
}
|
||||||
|
|
||||||
/* OK - Find the next one to use. First check we have at least one valid
|
/* OK - Find the next one to use. First check we have at least one valid
|
||||||
upstream because we completely back off failed
|
upstream (not backed-off) because we completely back off failed
|
||||||
upstreams we may have no valid upstream at all (in contrast to UDP). This
|
upstreams we may have no valid upstream at all (in contrast to UDP).*/
|
||||||
will be better communicated to the user when we have better error codes*/
|
|
||||||
i = upstreams->current_stateful;
|
i = upstreams->current_stateful;
|
||||||
do {
|
do {
|
||||||
DEBUG_STUB("%s %-35s: Testing upstreams %d %d\n", STUB_DEBUG_SETUP,
|
DEBUG_STUB("%s %-35s: Testing upstreams %d %d\n", STUB_DEBUG_SETUP,
|
||||||
__FUNC__, (int)i, (int)upstreams->upstreams[i].conn_state);
|
__FUNC__, (int)i, (int)upstreams->upstreams[i].conn_state);
|
||||||
if (upstream_valid(&upstreams->upstreams[i], transport, netreq)) {
|
if (upstream_valid(&upstreams->upstreams[i], transport, netreq, 0)) {
|
||||||
upstream = &upstreams->upstreams[i];
|
upstream = &upstreams->upstreams[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1917,14 +1868,48 @@ upstream_select_stateful(getdns_network_req *netreq, getdns_transport_list_t tra
|
||||||
if (i >= upstreams->count)
|
if (i >= upstreams->count)
|
||||||
i = 0;
|
i = 0;
|
||||||
} while (i != upstreams->current_stateful);
|
} while (i != upstreams->current_stateful);
|
||||||
if (!upstream)
|
if (!upstream) {
|
||||||
return NULL;
|
/* Oh, oh. We have no valid upstreams. Try to find one that might work so
|
||||||
|
allow backed off upstreams to be considered valid.
|
||||||
|
Don't worry about the policy, just use the one with the least bad
|
||||||
|
stats that still fits the bill (right transport, right authentication)
|
||||||
|
to try to avoid total failure due to network outages. */
|
||||||
|
do {
|
||||||
|
if (upstream_valid(&upstreams->upstreams[i], transport, netreq, 1)) {
|
||||||
|
upstream = &upstreams->upstreams[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
if (i >= upstreams->count)
|
||||||
|
i = 0;
|
||||||
|
} while (i != upstreams->current_stateful);
|
||||||
|
if (!upstream) {
|
||||||
|
/* We _really_ have nothing that authenticates well enough right now...
|
||||||
|
leave to regular backoff logic. */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
i++;
|
||||||
|
if (i >= upstreams->count)
|
||||||
|
i = 0;
|
||||||
|
if (upstream_valid(&upstreams->upstreams[i], transport, netreq, 1) &&
|
||||||
|
upstream_stats(&upstreams->upstreams[i]) > upstream_stats(upstream))
|
||||||
|
upstream = &upstreams->upstreams[i];
|
||||||
|
} while (i != upstreams->current_stateful);
|
||||||
|
upstream->conn_state = GETDNS_CONN_CLOSED;
|
||||||
|
upstream->conn_backoff_interval = 1;
|
||||||
|
_getdns_upstream_log(upstream, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_NOTICE,
|
||||||
|
"%-40s : No valid upstreams... promoting this backed-off upstream for re-try...\n",
|
||||||
|
upstream->addr_str);
|
||||||
|
return upstream;
|
||||||
|
}
|
||||||
|
|
||||||
/* Now select the specific upstream */
|
/* Now select the specific upstream */
|
||||||
if (netreq->owner->context->round_robin_upstreams == 0) {
|
if (netreq->owner->context->round_robin_upstreams == 0) {
|
||||||
/* Base the decision on the stats, noting we will have started from 0*/
|
/* Base the decision on the stats and being not backed-off,
|
||||||
|
noting we will have started from 0*/
|
||||||
for (i++; i < upstreams->count; i++) {
|
for (i++; i < upstreams->count; i++) {
|
||||||
if (upstream_valid(&upstreams->upstreams[i], transport, netreq) &&
|
if (upstream_valid(&upstreams->upstreams[i], transport, netreq, 0) &&
|
||||||
upstream_stats(&upstreams->upstreams[i]) > upstream_stats(upstream))
|
upstream_stats(&upstreams->upstreams[i]) > upstream_stats(upstream))
|
||||||
upstream = &upstreams->upstreams[i];
|
upstream = &upstreams->upstreams[i];
|
||||||
}
|
}
|
||||||
|
@ -2010,18 +1995,14 @@ upstream_connect(getdns_upstream *upstream, getdns_transport_list_t transport,
|
||||||
upstream->tls_obj = tls_create_object(dnsreq, fd, upstream);
|
upstream->tls_obj = tls_create_object(dnsreq, fd, upstream);
|
||||||
if (upstream->tls_obj == NULL) {
|
if (upstream->tls_obj == NULL) {
|
||||||
upstream_failed(upstream, 1);
|
upstream_failed(upstream, 1);
|
||||||
#ifdef USE_WINSOCK
|
_getdns_closesocket(fd);
|
||||||
closesocket(fd);
|
|
||||||
#else
|
|
||||||
close(fd);
|
|
||||||
#endif
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
upstream->tls_hs_state = GETDNS_HS_WRITE;
|
upstream->tls_hs_state = GETDNS_HS_WRITE;
|
||||||
}
|
}
|
||||||
upstream->conn_state = GETDNS_CONN_SETUP;
|
upstream->conn_state = GETDNS_CONN_SETUP;
|
||||||
_getdns_upstream_log(upstream, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_DEBUG,
|
_getdns_upstream_log(upstream, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_DEBUG,
|
||||||
"%-40s : Conn init : Transport=%s - Profile=%s\n",
|
"%-40s : Conn opened: %s - %s Profile\n",
|
||||||
upstream->addr_str, transport == GETDNS_TRANSPORT_TLS ? "TLS":"TCP",
|
upstream->addr_str, transport == GETDNS_TRANSPORT_TLS ? "TLS":"TCP",
|
||||||
dnsreq->context->tls_auth_min == GETDNS_AUTHENTICATION_NONE ? "Opportunistic":"Strict");
|
dnsreq->context->tls_auth_min == GETDNS_AUTHENTICATION_NONE ? "Opportunistic":"Strict");
|
||||||
break;
|
break;
|
||||||
|
@ -2048,12 +2029,17 @@ upstream_find_for_transport(getdns_network_req *netreq,
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* For stateful transport we should keep trying until all our transports
|
/* For stateful transport we should keep trying until all our transports
|
||||||
are exhausted/backed-off (no upstream)*/
|
are exhausted/backed-off (no upstream) and until we have tried each
|
||||||
|
upstream at least once for this netreq in a total backoff scenario */
|
||||||
|
size_t i = 0;
|
||||||
do {
|
do {
|
||||||
upstream = upstream_select_stateful(netreq, transport);
|
upstream = upstream_select_stateful(netreq, transport);
|
||||||
if (!upstream)
|
if (!upstream)
|
||||||
return NULL;
|
return NULL;
|
||||||
*fd = upstream_connect(upstream, transport, netreq->owner);
|
*fd = upstream_connect(upstream, transport, netreq->owner);
|
||||||
|
if (i >= upstream->upstreams->count)
|
||||||
|
return NULL;
|
||||||
|
i++;
|
||||||
} while (*fd == -1);
|
} while (*fd == -1);
|
||||||
DEBUG_STUB("%s %-35s: FD: %d Connecting to upstream: %p No: %d\n",
|
DEBUG_STUB("%s %-35s: FD: %d Connecting to upstream: %p No: %d\n",
|
||||||
STUB_DEBUG_SETUP, __FUNC__, *fd, (void*)upstream,
|
STUB_DEBUG_SETUP, __FUNC__, *fd, (void*)upstream,
|
||||||
|
@ -2078,7 +2064,7 @@ upstream_find_for_netreq(getdns_network_req *netreq)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
if (_getdns_EMFILE)
|
if (_getdns_socketerror() == _getdns_EMFILE)
|
||||||
return STUB_TRY_AGAIN_LATER;
|
return STUB_TRY_AGAIN_LATER;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -2091,7 +2077,7 @@ upstream_find_for_netreq(getdns_network_req *netreq)
|
||||||
}
|
}
|
||||||
/* Handle better, will give generic error*/
|
/* Handle better, will give generic error*/
|
||||||
DEBUG_STUB("%s %-35s: MSG: %p No valid upstream! \n", STUB_DEBUG_SCHEDULE, __FUNC__, (void*)netreq);
|
DEBUG_STUB("%s %-35s: MSG: %p No valid upstream! \n", STUB_DEBUG_SCHEDULE, __FUNC__, (void*)netreq);
|
||||||
_getdns_context_log(netreq->owner->context, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_DEBUG,
|
_getdns_context_log(netreq->owner->context, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_ERR,
|
||||||
"*FAILURE* no valid transports or upstreams available!\n");
|
"*FAILURE* no valid transports or upstreams available!\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -2120,11 +2106,17 @@ fallback_on_write(getdns_network_req *netreq)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
upstream_reschedule_events(getdns_upstream *upstream, uint64_t idle_timeout) {
|
upstream_reschedule_events(getdns_upstream *upstream) {
|
||||||
|
|
||||||
DEBUG_STUB("%s %-35s: FD: %d \n", STUB_DEBUG_SCHEDULE,
|
DEBUG_STUB("%s %-35s: FD: %d \n", STUB_DEBUG_SCHEDULE,
|
||||||
__FUNC__, upstream->fd);
|
__FUNC__, upstream->fd);
|
||||||
GETDNS_CLEAR_EVENT(upstream->loop, &upstream->event);
|
if (upstream->event.ev)
|
||||||
|
GETDNS_CLEAR_EVENT(upstream->loop, &upstream->event);
|
||||||
|
|
||||||
|
if (upstream->fd == -1 || !( upstream->conn_state == GETDNS_CONN_SETUP
|
||||||
|
|| upstream->conn_state == GETDNS_CONN_OPEN ))
|
||||||
|
return;
|
||||||
|
|
||||||
if (!upstream->write_queue && upstream->event.write_cb) {
|
if (!upstream->write_queue && upstream->event.write_cb) {
|
||||||
upstream->event.write_cb = NULL;
|
upstream->event.write_cb = NULL;
|
||||||
}
|
}
|
||||||
|
@ -2142,18 +2134,13 @@ upstream_reschedule_events(getdns_upstream *upstream, uint64_t idle_timeout) {
|
||||||
upstream->fd, TIMEOUT_FOREVER, &upstream->event);
|
upstream->fd, TIMEOUT_FOREVER, &upstream->event);
|
||||||
else {
|
else {
|
||||||
DEBUG_STUB("%s %-35s: FD: %d Connection idle - timeout is %d\n",
|
DEBUG_STUB("%s %-35s: FD: %d Connection idle - timeout is %d\n",
|
||||||
STUB_DEBUG_SCHEDULE, __FUNC__, upstream->fd, (int)idle_timeout);
|
STUB_DEBUG_SCHEDULE, __FUNC__, upstream->fd,
|
||||||
/* TODO: Schedule a read also anyway,
|
(int)upstream->keepalive_timeout);
|
||||||
* to digest timed out answers.
|
|
||||||
* Dont forget to schedule with upstream->fd then!
|
upstream->event.read_cb = upstream_read_cb;
|
||||||
*
|
|
||||||
* upstream->event.read_cb = upstream_read_cb;
|
|
||||||
*/
|
|
||||||
upstream->event.timeout_cb = upstream_idle_timeout_cb;
|
upstream->event.timeout_cb = upstream_idle_timeout_cb;
|
||||||
if (upstream->conn_state != GETDNS_CONN_OPEN)
|
GETDNS_SCHEDULE_EVENT(upstream->loop, upstream->fd,
|
||||||
idle_timeout = 0;
|
upstream->keepalive_timeout, &upstream->event);
|
||||||
GETDNS_SCHEDULE_EVENT(upstream->loop, -1,
|
|
||||||
idle_timeout, &upstream->event);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
40
src/sync.c
40
src/sync.c
|
@ -76,7 +76,7 @@ getdns_sync_data_init(getdns_context *context, getdns_sync_data *data)
|
||||||
# ifdef HAVE_UNBOUND_EVENT_API
|
# ifdef HAVE_UNBOUND_EVENT_API
|
||||||
if (_getdns_ub_loop_enabled(&context->ub_loop)) {
|
if (_getdns_ub_loop_enabled(&context->ub_loop)) {
|
||||||
context->ub_loop.extension = ext;
|
context->ub_loop.extension = ext;
|
||||||
} else
|
} else
|
||||||
# endif
|
# endif
|
||||||
# ifndef USE_WINSOCK
|
# ifndef USE_WINSOCK
|
||||||
return ext->vmt->schedule(ext, ub_fd(context->unbound_ctx),
|
return ext->vmt->schedule(ext, ub_fd(context->unbound_ctx),
|
||||||
|
@ -85,7 +85,9 @@ getdns_sync_data_init(getdns_context *context, getdns_sync_data *data)
|
||||||
/* No sync full recursion requests on windows without
|
/* No sync full recursion requests on windows without
|
||||||
* UNBOUND_EVENT_API because ub_fd() doesn't work on windows.
|
* UNBOUND_EVENT_API because ub_fd() doesn't work on windows.
|
||||||
*/
|
*/
|
||||||
; /* pass */
|
# ifdef HAVE_UNBOUND_EVENT_API
|
||||||
|
{ ; } /* pass */
|
||||||
|
# endif
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
return GETDNS_RETURN_GOOD;
|
return GETDNS_RETURN_GOOD;
|
||||||
|
@ -114,30 +116,24 @@ getdns_sync_data_cleanup(getdns_sync_data *data)
|
||||||
upstream = &ctxt->upstreams->upstreams[i];
|
upstream = &ctxt->upstreams->upstreams[i];
|
||||||
if (upstream->loop != &data->context->sync_eventloop.loop)
|
if (upstream->loop != &data->context->sync_eventloop.loop)
|
||||||
continue;
|
continue;
|
||||||
if (upstream->event.read_cb || upstream->event.write_cb) {
|
GETDNS_CLEAR_EVENT(upstream->loop, &upstream->event);
|
||||||
GETDNS_CLEAR_EVENT(upstream->loop, &upstream->event);
|
if (upstream->event.timeout_cb &&
|
||||||
|
( upstream->conn_state != GETDNS_CONN_OPEN
|
||||||
} else if (upstream->event.timeout_cb) {
|
|| upstream->keepalive_timeout == 0)) {
|
||||||
/* Timeout's at upstream are idle-timeouts only.
|
(*upstream->event.timeout_cb)(upstream->event.userarg);
|
||||||
* They should be fired on completion of the
|
upstream->event.timeout_cb = NULL;
|
||||||
* synchronous request.
|
|
||||||
*/
|
|
||||||
GETDNS_CLEAR_EVENT(upstream->loop, &upstream->event);
|
|
||||||
if (upstream->conn_state != GETDNS_CONN_OPEN ||
|
|
||||||
upstream->keepalive_timeout == 0)
|
|
||||||
(*upstream->event.timeout_cb)(upstream->event.userarg);
|
|
||||||
}
|
}
|
||||||
upstream->loop = data->context->extension;
|
upstream->loop = data->context->extension;
|
||||||
upstream->is_sync_loop = 0;
|
upstream->is_sync_loop = 0;
|
||||||
if (upstream->event.read_cb || upstream->event.write_cb)
|
|
||||||
GETDNS_SCHEDULE_EVENT(upstream->loop, upstream->fd,
|
|
||||||
TIMEOUT_FOREVER, &upstream->event);
|
|
||||||
|
|
||||||
else if (upstream->event.timeout_cb &&
|
if ( upstream->event.read_cb || upstream->event.write_cb
|
||||||
upstream->conn_state == GETDNS_CONN_OPEN &&
|
|| upstream->event.timeout_cb) {
|
||||||
upstream->keepalive_timeout != 0) {
|
GETDNS_SCHEDULE_EVENT(upstream->loop,
|
||||||
GETDNS_SCHEDULE_EVENT(upstream->loop, upstream->fd,
|
( upstream->event.read_cb
|
||||||
upstream->keepalive_timeout, &upstream->event);
|
|| upstream->event.write_cb ? upstream->fd : -1),
|
||||||
|
( upstream->event.timeout_cb
|
||||||
|
? upstream->keepalive_timeout : TIMEOUT_FOREVER ),
|
||||||
|
&upstream->event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@
|
||||||
CONTEXT_CREATE(TRUE);
|
CONTEXT_CREATE(TRUE);
|
||||||
|
|
||||||
ASSERT_RC(getdns_context_set_upstream_recursive_servers(context, NULL),
|
ASSERT_RC(getdns_context_set_upstream_recursive_servers(context, NULL),
|
||||||
GETDNS_RETURN_INVALID_PARAMETER, "Return code from getdns_context_set_upstream_recursive_servers()");
|
GETDNS_RETURN_GOOD, "Return code from getdns_context_set_upstream_recursive_servers()");
|
||||||
|
|
||||||
|
|
||||||
CONTEXT_DESTROY;
|
CONTEXT_DESTROY;
|
||||||
|
|
|
@ -25,4 +25,4 @@ done
|
||||||
rm -fr "${BUILDDIR}/build"
|
rm -fr "${BUILDDIR}/build"
|
||||||
mkdir "${BUILDDIR}/build"
|
mkdir "${BUILDDIR}/build"
|
||||||
cd "${BUILDDIR}/build"
|
cd "${BUILDDIR}/build"
|
||||||
"${SRCROOT}/configure" $* --prefix "${BUILDDIR}/install"
|
"${SRCROOT}/configure" $* --prefix "${BUILDDIR}/install" --enable-debug-anchor
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
builddir = @BUILDDIR@
|
||||||
|
testname = @TPKG_NAME@
|
||||||
|
LIBTOOL = $(builddir)/libtool
|
||||||
|
|
||||||
|
CFLAGS=-I$(builddir)/src
|
||||||
|
LDLIBS=$(builddir)/src/libgetdns.la
|
||||||
|
|
||||||
|
.SUFFIXES: .c .o .a .lo .h
|
||||||
|
|
||||||
|
.c.lo:
|
||||||
|
$(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
$(testname): $(testname).lo
|
||||||
|
$(LIBTOOL) --tag=CC --mode=link $(CC) $(LDLIBS) $(LDFLAGS) -o $(testname) $(testname).lo
|
||||||
|
|
|
@ -0,0 +1,111 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <getdns/getdns.h>
|
||||||
|
#include <getdns/getdns_extra.h>
|
||||||
|
|
||||||
|
int main(int ac, char *av[])
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
char *buf = NULL;
|
||||||
|
size_t len;
|
||||||
|
ssize_t bytes_read;
|
||||||
|
|
||||||
|
f = fopen(av[1], "r");
|
||||||
|
if (!f) {
|
||||||
|
fprintf(stderr, "Could not open %s", av[1]);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes_read = getdelim(&buf, &len, '\0', f);
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
if (bytes_read == -1) {
|
||||||
|
fprintf(stderr, "Could not read %s", av[1]);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
buf = realloc(buf, bytes_read + 1);
|
||||||
|
if (!buf) {
|
||||||
|
fprintf(stderr, "Could not grow buffer");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
buf[bytes_read] = '\0';
|
||||||
|
|
||||||
|
getdns_dict *dict = NULL;
|
||||||
|
getdns_list *list = NULL;
|
||||||
|
getdns_bindata *bindata = NULL;
|
||||||
|
getdns_return_t r;
|
||||||
|
|
||||||
|
if (!(dict = getdns_dict_create())) {
|
||||||
|
fprintf(stderr, "Could not create dict");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = getdns_yaml2dict(buf, &dict);
|
||||||
|
if (r) {
|
||||||
|
fprintf(stderr, "Error setting dict data: %s", getdns_get_errorstr_by_id(r));
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now add a list, bindata and int to the dict by hand to check
|
||||||
|
* the other yaml2* functions work.
|
||||||
|
*/
|
||||||
|
if (!(list = getdns_list_create())) {
|
||||||
|
fprintf(stderr, "Could not create list");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = getdns_str2list("[\"One\", \"two\", \"three\"]", &list);
|
||||||
|
if (r) {
|
||||||
|
fprintf(stderr, "Error setting list data: %s", getdns_get_errorstr_by_id(r));
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = getdns_dict_set_list(dict, "List entry", list);
|
||||||
|
if (r) {
|
||||||
|
fprintf(stderr, "Error adding list to dict: %s", getdns_get_errorstr_by_id(r));
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = getdns_str2bindata("2001:7fd::1", &bindata);
|
||||||
|
if (r) {
|
||||||
|
fprintf(stderr, "Error setting bindata: %s", getdns_get_errorstr_by_id(r));
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = getdns_dict_set_bindata(dict, "Bindata entry", bindata);
|
||||||
|
if (r) {
|
||||||
|
fprintf(stderr, "Error adding list to dict: %s", getdns_get_errorstr_by_id(r));
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t intval;
|
||||||
|
r = getdns_str2int("32767", &intval);
|
||||||
|
if (r) {
|
||||||
|
fprintf(stderr, "Error setting int: %s", getdns_get_errorstr_by_id(r));
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
if (intval != 32767) {
|
||||||
|
fprintf(stderr, "Error reading int: wrong value");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *dict_str = getdns_pretty_print_dict(dict);
|
||||||
|
if (!dict_str) {
|
||||||
|
fprintf(stderr, "Could not convert dict to string");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%s\n", dict_str);
|
||||||
|
free(dict_str);
|
||||||
|
getdns_dict_destroy(dict);
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
|
||||||
|
fail:
|
||||||
|
if (dict)
|
||||||
|
getdns_dict_destroy(dict);
|
||||||
|
if (list)
|
||||||
|
getdns_list_destroy(list);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
BaseName: 255-yaml-config
|
||||||
|
Version: 1.0
|
||||||
|
Description: Test YAML configuration
|
||||||
|
CreationDate: Wed 13 Sep 2017 12:42:32 BST
|
||||||
|
Maintainer: Jim Hague
|
||||||
|
Category:
|
||||||
|
Component:
|
||||||
|
CmdDepends:
|
||||||
|
Depends: 200-stub-only-compile.tpkg
|
||||||
|
Help:
|
||||||
|
Pre: 255-yaml-config.pre
|
||||||
|
Post:
|
||||||
|
Test: 255-yaml-config.test
|
||||||
|
AuxFiles:
|
||||||
|
Passed:
|
||||||
|
Failure:
|
|
@ -0,0 +1,87 @@
|
||||||
|
{
|
||||||
|
"Bindata entry": <bindata of 0x200107fd000000000000000000000001>,
|
||||||
|
"List entry":
|
||||||
|
[
|
||||||
|
<bindata of "One">,
|
||||||
|
<bindata of "two">,
|
||||||
|
<bindata of "three">
|
||||||
|
],
|
||||||
|
"dnssec_return_status": 1000,
|
||||||
|
"upstream_recursive_servers":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"address_data": <bindata for 145.100.185.15>,
|
||||||
|
"tls_auth_name": <bindata of "dnsovertls.sinodun.com">,
|
||||||
|
"tls_pubkey_pinset":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"digest": <bindata of "sha256">,
|
||||||
|
"value": <bindata of 62lKu9HsDVbyiPenApnc4sfmSYTHOVfFgL3pyB+cBL4=>
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address_data": <bindata for 145.100.185.16>,
|
||||||
|
"tls_auth_name": <bindata of "dnsovertls1.sinodun.com">,
|
||||||
|
"tls_pubkey_pinset":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"digest": <bindata of "sha256">,
|
||||||
|
"value": <bindata of cE2ecALeE5B+urJhDrJlVFmf38cJLAvqekONvjvpqUA=>
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address_data": <bindata for 185.49.141.37>,
|
||||||
|
"tls_auth_name": <bindata of "getdnsapi.net">,
|
||||||
|
"tls_pubkey_pinset":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"digest": <bindata of "sha256">,
|
||||||
|
"value": <bindata of foxZRnIh9gZpWnl+zEiKa0EJ2rdCGroMWm02gaxSc9Q=>
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address_data": <bindata for 184.105.193.78>,
|
||||||
|
"tls_auth_name": <bindata of "unicast.censurfridns.dk">
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address_data": <bindata for 2001:610:1:40ba:145:100:185:15>,
|
||||||
|
"tls_auth_name": <bindata of "dnsovertls.sinodun.com">,
|
||||||
|
"tls_pubkey_pinset":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"digest": <bindata of "sha256">,
|
||||||
|
"value": <bindata of 62lKu9HsDVbyiPenApnc4sfmSYTHOVfFgL3pyB+cBL4=>
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address_data": <bindata for 2001:610:1:40ba:145:100:185:16>,
|
||||||
|
"tls_auth_name": <bindata of "dnsovertls1.sinodun.com">,
|
||||||
|
"tls_pubkey_pinset":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"digest": <bindata of "sha256">,
|
||||||
|
"value": <bindata of cE2ecALeE5B+urJhDrJlVFmf38cJLAvqekONvjvpqUA=>
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address_data": <bindata for 2a04:b900:0:100::38>,
|
||||||
|
"tls_auth_name": <bindata of "getdnsapi.net">,
|
||||||
|
"tls_pubkey_pinset":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"digest": <bindata of "sha256">,
|
||||||
|
"value": <bindata of foxZRnIh9gZpWnl+zEiKa0EJ2rdCGroMWm02gaxSc9Q=>
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address_data": <bindata for 2620:ff:c000:0:1:0:64:25>,
|
||||||
|
"tls_auth_name": <bindata of "unicast.censurfridns.dk">
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
upstream_recursive_servers:
|
||||||
|
# IPv4 addresses
|
||||||
|
# The Surfnet/Sinodun servers
|
||||||
|
- address_data: 145.100.185.15
|
||||||
|
tls_auth_name: "dnsovertls.sinodun.com"
|
||||||
|
tls_pubkey_pinset:
|
||||||
|
- digest: "sha256"
|
||||||
|
value: 62lKu9HsDVbyiPenApnc4sfmSYTHOVfFgL3pyB+cBL4=
|
||||||
|
- address_data: 145.100.185.16
|
||||||
|
tls_auth_name: "dnsovertls1.sinodun.com"
|
||||||
|
tls_pubkey_pinset:
|
||||||
|
- digest: "sha256"
|
||||||
|
value: cE2ecALeE5B+urJhDrJlVFmf38cJLAvqekONvjvpqUA=
|
||||||
|
# The getdnsapi.net server
|
||||||
|
- address_data: 185.49.141.37
|
||||||
|
tls_auth_name: "getdnsapi.net"
|
||||||
|
tls_pubkey_pinset:
|
||||||
|
- digest: "sha256"
|
||||||
|
value: foxZRnIh9gZpWnl+zEiKa0EJ2rdCGroMWm02gaxSc9Q=
|
||||||
|
# The uncensored DNS servers (no SPKI available)
|
||||||
|
- address_data: 184.105.193.78
|
||||||
|
tls_auth_name: "unicast.censurfridns.dk"
|
||||||
|
# IPv6 addresses
|
||||||
|
# The Surfnet/Sinodun servers
|
||||||
|
- address_data: 2001:610:1:40ba:145:100:185:15
|
||||||
|
tls_auth_name: "dnsovertls.sinodun.com"
|
||||||
|
tls_pubkey_pinset:
|
||||||
|
- digest: "sha256"
|
||||||
|
value: 62lKu9HsDVbyiPenApnc4sfmSYTHOVfFgL3pyB+cBL4=
|
||||||
|
- address_data: 2001:610:1:40ba:145:100:185:16
|
||||||
|
tls_auth_name: "dnsovertls1.sinodun.com"
|
||||||
|
tls_pubkey_pinset:
|
||||||
|
- digest: "sha256"
|
||||||
|
value: cE2ecALeE5B+urJhDrJlVFmf38cJLAvqekONvjvpqUA=
|
||||||
|
# The getdnsapi.net server
|
||||||
|
- address_data: 2a04:b900:0:100::38
|
||||||
|
tls_auth_name: "getdnsapi.net"
|
||||||
|
tls_pubkey_pinset:
|
||||||
|
- digest: "sha256"
|
||||||
|
value: foxZRnIh9gZpWnl+zEiKa0EJ2rdCGroMWm02gaxSc9Q=
|
||||||
|
# The uncensored DNS server (no SPKI available)
|
||||||
|
- address_data: 2620:ff:c000:0:1::64:25
|
||||||
|
tls_auth_name: "unicast.censurfridns.dk"
|
||||||
|
|
||||||
|
# Require DNSSEC validation. For releases earlier than 1.2 a trust anchor must
|
||||||
|
# be configured configured manually. This can be done with unbound-anchor.
|
||||||
|
dnssec_return_status: GETDNS_EXTENSION_TRUE
|
|
@ -0,0 +1,14 @@
|
||||||
|
# #-- 255-yaml-config.test --#
|
||||||
|
# source the master var file when it's there
|
||||||
|
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
|
||||||
|
# use .tpkg.var.test for in test variable passing
|
||||||
|
[ -f .tpkg.var.test ] && source .tpkg.var.test
|
||||||
|
|
||||||
|
(
|
||||||
|
grep '^CC=' "${BUILDDIR}/build-stub-only/src/Makefile"
|
||||||
|
grep '^LDFLAGS=' "${BUILDDIR}/build-stub-only/src/Makefile"
|
||||||
|
|
||||||
|
BUILDDIR4SED=`echo "${BUILDDIR}/build-stub-only" | sed 's/\//\\\\\//g'`
|
||||||
|
sed -e "s/@BUILDDIR@/${BUILDDIR4SED}/g" \
|
||||||
|
-e "s/@TPKG_NAME@/${TPKG_NAME}/g" "${TPKG_NAME}.Makefile"
|
||||||
|
) > Makefile
|
|
@ -0,0 +1,7 @@
|
||||||
|
# #-- 255-yaml-config.test --#
|
||||||
|
# source the master var file when it's there
|
||||||
|
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
|
||||||
|
# use .tpkg.var.test for in test variable passing
|
||||||
|
[ -f .tpkg.var.test ] && source .tpkg.var.test
|
||||||
|
|
||||||
|
make && "./${TPKG_NAME}" 255-yaml-config.input | tee out && diff out "${TPKG_NAME}.good"
|
|
@ -6,7 +6,7 @@ Maintainer: Hoda Rohani
|
||||||
Category:
|
Category:
|
||||||
Component:
|
Component:
|
||||||
CmdDepends:
|
CmdDepends:
|
||||||
Depends: 110-link.tpkg
|
Depends: 210-stub-only-link.tpkg
|
||||||
Help:
|
Help:
|
||||||
Pre:
|
Pre:
|
||||||
Post:
|
Post:
|
||||||
|
|
|
@ -4,6 +4,12 @@
|
||||||
# use .tpkg.var.test for in test variable passing
|
# use .tpkg.var.test for in test variable passing
|
||||||
[ -f .tpkg.var.test ] && source .tpkg.var.test
|
[ -f .tpkg.var.test ] && source .tpkg.var.test
|
||||||
|
|
||||||
|
if grep -q '^#define HAVE_SSL_HN_AUTH 1' "${BUILDDIR}/build-stub-only/src/config.h"
|
||||||
|
then
|
||||||
|
HAVE_SSL_HN_AUTH=1
|
||||||
|
else
|
||||||
|
HAVE_SSL_HN_AUTH=0
|
||||||
|
fi
|
||||||
SERVER_IP="8.8.8.8"
|
SERVER_IP="8.8.8.8"
|
||||||
SERVER_IPv6="2001:4860:4860::8888"
|
SERVER_IPv6="2001:4860:4860::8888"
|
||||||
|
|
||||||
|
@ -126,17 +132,30 @@ for (( ii = 0; ii < 1; ii++)); do
|
||||||
SERVER_IP_TSIG_WRONG_NAME=`echo ${SERVER_IP_TSIG}${TSIG_ALG}":"${TSIG_NAME::${#TSIG_NAME}-1}":"${TSIG_SECRET}`
|
SERVER_IP_TSIG_WRONG_NAME=`echo ${SERVER_IP_TSIG}${TSIG_ALG}":"${TSIG_NAME::${#TSIG_NAME}-1}":"${TSIG_SECRET}`
|
||||||
SERVER_IP_TSIG_WRONG_SECRET=`echo ${SERVER_IP_TSIG}${TSIG_ALG}":"${TSIG_NAME}":"${TSIG_SECRET::${#TSIG_SECRET}-1}`
|
SERVER_IP_TSIG_WRONG_SECRET=`echo ${SERVER_IP_TSIG}${TSIG_ALG}":"${TSIG_NAME}":"${TSIG_SECRET::${#TSIG_SECRET}-1}`
|
||||||
|
|
||||||
NUM_GOOD_QUERIES=9
|
if [[ $HAVE_SSL_HN_AUTH = 1 ]]
|
||||||
GOOD_QUERIES=(
|
then
|
||||||
"-s -A getdnsapi.net -l U @${SERVER_IP} +edns_cookies" "U" "-"
|
NUM_GOOD_QUERIES=9
|
||||||
"-s -A getdnsapi.net -l T @${SERVER_IP}" "T" "-"
|
GOOD_QUERIES=(
|
||||||
"-s -A getdnsapi.net -l U @${SERVER_IP_TSIG}${TSIG_ALG}:${TSIG_NAME}:${TSIG_SECRET}" "U" "-"
|
"-s -A getdnsapi.net -l U @${SERVER_IP} +edns_cookies" "U" "-"
|
||||||
"-s -A getdnsapi.net -l U @${SERVER_IP_TSIG}${TSIG_NAME}:${TSIG_SECRET}" "U" "-"
|
"-s -A getdnsapi.net -l T @${SERVER_IP}" "T" "-"
|
||||||
"-s -A getdnsapi.net -l L @${TLS_SERVER_IP_NO_NAME}" "L" "N"
|
"-s -A getdnsapi.net -l U @${SERVER_IP_TSIG}${TSIG_ALG}:${TSIG_NAME}:${TSIG_SECRET}" "U" "-"
|
||||||
"-s -A getdnsapi.net -l L -m @${TLS_SERVER_IP}" "L" "S"
|
"-s -A getdnsapi.net -l U @${SERVER_IP_TSIG}${TSIG_NAME}:${TSIG_SECRET}" "U" "-"
|
||||||
"-s -A getdnsapi.net -l L -m @${TLS_SERVER_IP_NO_NAME} -K pin-sha256=\"${TLS_SERVER_KEY}\"" "L" "S"
|
"-s -A getdnsapi.net -l L @${TLS_SERVER_IP_NO_NAME}" "L" "N"
|
||||||
"-s -A getdnsapi.net -l L -m @${TLS_SERVER_IP} -K pin-sha256=\"${TLS_SERVER_KEY}\"" "L" "S"
|
"-s -A getdnsapi.net -l L -m @${TLS_SERVER_IP}" "L" "S"
|
||||||
"-s -G DNSKEY getdnsapi.net -l U @${SERVER_IP} -b 512 -D" "U" "-")
|
"-s -A getdnsapi.net -l L -m @${TLS_SERVER_IP_NO_NAME} -K pin-sha256=\"${TLS_SERVER_KEY}\"" "L" "S"
|
||||||
|
"-s -A getdnsapi.net -l L -m @${TLS_SERVER_IP} -K pin-sha256=\"${TLS_SERVER_KEY}\"" "L" "S"
|
||||||
|
"-s -G DNSKEY getdnsapi.net -l U @${SERVER_IP} -b 512 -D" "U" "-")
|
||||||
|
else
|
||||||
|
NUM_GOOD_QUERIES=7
|
||||||
|
GOOD_QUERIES=(
|
||||||
|
"-s -A getdnsapi.net -l U @${SERVER_IP} +edns_cookies" "U" "-"
|
||||||
|
"-s -A getdnsapi.net -l T @${SERVER_IP}" "T" "-"
|
||||||
|
"-s -A getdnsapi.net -l U @${SERVER_IP_TSIG}${TSIG_ALG}:${TSIG_NAME}:${TSIG_SECRET}" "U" "-"
|
||||||
|
"-s -A getdnsapi.net -l U @${SERVER_IP_TSIG}${TSIG_NAME}:${TSIG_SECRET}" "U" "-"
|
||||||
|
"-s -A getdnsapi.net -l L @${TLS_SERVER_IP_NO_NAME}" "L" "N"
|
||||||
|
"-s -A getdnsapi.net -l L -m @${TLS_SERVER_IP_NO_NAME} -K pin-sha256=\"${TLS_SERVER_KEY}\"" "L" "S"
|
||||||
|
"-s -G DNSKEY getdnsapi.net -l U @${SERVER_IP} -b 512 -D" "U" "-")
|
||||||
|
fi
|
||||||
#"-s -A getdnsapi.net -l L -m @${TLS_SERVER_SS_IP_NO_NAME} -K pin-sha256=\"${TLS_SERVER_SS_KEY}\"" "L" "S"
|
#"-s -A getdnsapi.net -l L -m @${TLS_SERVER_SS_IP_NO_NAME} -K pin-sha256=\"${TLS_SERVER_SS_KEY}\"" "L" "S"
|
||||||
|
|
||||||
NUM_GOOD_FB_QUERIES=6
|
NUM_GOOD_FB_QUERIES=6
|
||||||
|
@ -173,21 +192,21 @@ for (( ii = 0; ii < 1; ii++)); do
|
||||||
fi
|
fi
|
||||||
echo "*Success cases:"
|
echo "*Success cases:"
|
||||||
for (( j = 0; j < $NUM_GOOD_QUERIES; j+=1 )); do
|
for (( j = 0; j < $NUM_GOOD_QUERIES; j+=1 )); do
|
||||||
check_good "`"${GETDNS_QUERY}" -V +return_call_reporting $SYNC_MODE ${GOOD_QUERIES[$j*$NUM_ARGS]} `" ${GOOD_QUERIES[$((j*NUM_ARGS))+1]} ${GOOD_QUERIES[$((j*NUM_ARGS))+2]}
|
check_good "`"${GETDNS_STUB_QUERY}" -V +return_call_reporting $SYNC_MODE ${GOOD_QUERIES[$j*$NUM_ARGS]} `" ${GOOD_QUERIES[$((j*NUM_ARGS))+1]} ${GOOD_QUERIES[$((j*NUM_ARGS))+2]}
|
||||||
echo "getdns_query $SYNC_MODE ${GOOD_QUERIES[$j*$NUM_ARGS]}"
|
echo "getdns_query $SYNC_MODE ${GOOD_QUERIES[$j*$NUM_ARGS]}"
|
||||||
(( COUNT++ ))
|
(( COUNT++ ))
|
||||||
done
|
done
|
||||||
|
|
||||||
echo "*Success fallback cases:"
|
echo "*Success fallback cases:"
|
||||||
for (( j = 0; j < $NUM_GOOD_FB_QUERIES; j+=1 )); do
|
for (( j = 0; j < $NUM_GOOD_FB_QUERIES; j+=1 )); do
|
||||||
check_good "`"${GETDNS_QUERY}" -V +return_call_reporting $SYNC_MODE ${GOOD_FALLBACK_QUERIES[$j*$NUM_ARGS]} 2>/dev/null`" ${GOOD_FALLBACK_QUERIES[$((j*NUM_ARGS))+1]} ${GOOD_FALLBACK_QUERIES[$((j*NUM_ARGS))+2]}
|
check_good "`"${GETDNS_STUB_QUERY}" -V +return_call_reporting $SYNC_MODE ${GOOD_FALLBACK_QUERIES[$j*$NUM_ARGS]} 2>/dev/null`" ${GOOD_FALLBACK_QUERIES[$((j*NUM_ARGS))+1]} ${GOOD_FALLBACK_QUERIES[$((j*NUM_ARGS))+2]}
|
||||||
echo "getdns_query $SYNC_MODE ${GOOD_FALLBACK_QUERIES[$j*$NUM_ARGS]} TESTS: ${GOOD_FALLBACK_QUERIES[$((j*NUM_ARGS))+1]} ${GOOD_FALLBACK_QUERIES[$((j*NUM_ARGS))+2]}"
|
echo "getdns_query $SYNC_MODE ${GOOD_FALLBACK_QUERIES[$j*$NUM_ARGS]} TESTS: ${GOOD_FALLBACK_QUERIES[$((j*NUM_ARGS))+1]} ${GOOD_FALLBACK_QUERIES[$((j*NUM_ARGS))+2]}"
|
||||||
(( COUNT++ ))
|
(( COUNT++ ))
|
||||||
done
|
done
|
||||||
|
|
||||||
echo "*Transport not available cases:"
|
echo "*Transport not available cases:"
|
||||||
for (( j = 0; j < ${#NOT_AVAILABLE_QUERIES[@]}; j+=1 )); do
|
for (( j = 0; j < ${#NOT_AVAILABLE_QUERIES[@]}; j+=1 )); do
|
||||||
check_bad "`"${GETDNS_QUERY}" -V $SYNC_MODE ${NOT_AVAILABLE_QUERIES[${j}]} 2>&1`"
|
check_bad "`"${GETDNS_STUB_QUERY}" -V $SYNC_MODE ${NOT_AVAILABLE_QUERIES[${j}]} 2>&1`"
|
||||||
echo "getdns_query $SYNC_MODE ${NOT_AVAILABLE_QUERIES[${j}]}"
|
echo "getdns_query $SYNC_MODE ${NOT_AVAILABLE_QUERIES[${j}]}"
|
||||||
(( COUNT++ ))
|
(( COUNT++ ))
|
||||||
done
|
done
|
||||||
|
@ -198,3 +217,8 @@ done
|
||||||
echo
|
echo
|
||||||
echo "Finished transport test: did $COUNT queries, $GOOD_COUNT passes, $FAIL_COUNT failures"
|
echo "Finished transport test: did $COUNT queries, $GOOD_COUNT passes, $FAIL_COUNT failures"
|
||||||
echo
|
echo
|
||||||
|
if [[ $FAIL_COUNT -gt 0 ]]
|
||||||
|
then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,11 @@ find . -type f -name "Makefile.in" -print0 | xargs -0 rm -f && (
|
||||||
)
|
)
|
||||||
(
|
(
|
||||||
cd "${BUILDDIR}/build-event-loops"
|
cd "${BUILDDIR}/build-event-loops"
|
||||||
|
if test "`hostname`" != "bonobo"
|
||||||
|
then
|
||||||
|
echo Sorry, running dependency test on bonobo only
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
if ! ./config.status --config | grep -q 'enable-all-drafts.*--with-libevent.*--with-libev.*--with-libuv'
|
if ! ./config.status --config | grep -q 'enable-all-drafts.*--with-libevent.*--with-libev.*--with-libuv'
|
||||||
then
|
then
|
||||||
echo Skipping because not covering enough code
|
echo Skipping because not covering enough code
|
||||||
|
|
|
@ -5,10 +5,43 @@
|
||||||
[ -f .tpkg.var.test ] && source .tpkg.var.test
|
[ -f .tpkg.var.test ] && source .tpkg.var.test
|
||||||
|
|
||||||
cd "${BUILDDIR}/build-event-loops"
|
cd "${BUILDDIR}/build-event-loops"
|
||||||
if make -j 4 test
|
make -j 4 test
|
||||||
|
if test -e "${BUILDDIR}/build-event-loops/src/test/fails"
|
||||||
then
|
then
|
||||||
if test -e "${BUILDDIR}/build-event-loops/src/test/fails"
|
if test -e "${BUILDDIR}/build-event-loops/src/test/check_getdns.failed"
|
||||||
then
|
then
|
||||||
exit 1
|
echo ""
|
||||||
|
echo "********************"
|
||||||
|
echo "*** check_getdns ***"
|
||||||
|
echo "********************"
|
||||||
|
cat "${BUILDDIR}/build-event-loops/src/test/check_getdns.log"
|
||||||
fi
|
fi
|
||||||
|
if test -e "${BUILDDIR}/build-event-loops/src/test/check_getdns_event.failed"
|
||||||
|
then
|
||||||
|
echo ""
|
||||||
|
echo "**************************"
|
||||||
|
echo "*** check_getdns_event ***"
|
||||||
|
echo "**************************"
|
||||||
|
cat "${BUILDDIR}/build-event-loops/src/test/check_getdns_event.log"
|
||||||
|
fi
|
||||||
|
if test -e "${BUILDDIR}/build-event-loops/src/test/check_getdns_ev.failed"
|
||||||
|
then
|
||||||
|
echo ""
|
||||||
|
echo "***********************"
|
||||||
|
echo "*** check_getdns_ev ***"
|
||||||
|
echo "***********************"
|
||||||
|
cat "${BUILDDIR}/build-event-loops/src/test/check_getdns_ev.log"
|
||||||
|
fi
|
||||||
|
if test -e "${BUILDDIR}/build-event-loops/src/test/check_getdns_uv.failed"
|
||||||
|
then
|
||||||
|
echo ""
|
||||||
|
echo "***********************"
|
||||||
|
echo "*** check_getdns_uv ***"
|
||||||
|
echo "***********************"
|
||||||
|
cat "${BUILDDIR}/build-event-loops/src/test/check_getdns_uv.log"
|
||||||
|
fi
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
@ -3,5 +3,5 @@
|
||||||
export SRCDIR=`dirname $0`
|
export SRCDIR=`dirname $0`
|
||||||
( cd $SRCDIR
|
( cd $SRCDIR
|
||||||
./tpkg clean
|
./tpkg clean
|
||||||
rm -fr build build-stub-only build-event-loops build-static-analysis install scan-build-reports .tpkg.var.master *.info
|
rm -fr build build-stub-only build-event-loops build-static-analysis install scan-build-reports .tpkg.var.master *.info Makefile
|
||||||
)
|
)
|
||||||
|
|
|
@ -25,4 +25,4 @@ do
|
||||||
done
|
done
|
||||||
lcov $LCOV_MERGE -o run-all.info
|
lcov $LCOV_MERGE -o run-all.info
|
||||||
genhtml run-all.info --output-directory coverage-html
|
genhtml run-all.info --output-directory coverage-html
|
||||||
"${TPKG}" r
|
"${TPKG}" -n -1 r
|
||||||
|
|
|
@ -17,4 +17,4 @@ do
|
||||||
# trap keyboard interrupt (control-c)
|
# trap keyboard interrupt (control-c)
|
||||||
trap control_c 2
|
trap control_c 2
|
||||||
done
|
done
|
||||||
"${TPKG}" r
|
"${TPKG}" -n -1 r
|
||||||
|
|
|
@ -31,7 +31,7 @@ do
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
echo "${ALL}" >> Makefile
|
echo "${ALL}" >> Makefile
|
||||||
printf '\t"%s" r\n\n' "${TPKG}" >> Makefile
|
printf '\t"%s" -n -1 r\n\n' "${TPKG}" >> Makefile
|
||||||
printf 'clean:\n\t"%s" clean\n\trm -fr build build-stub-only build-event-loops build-static-analysis install scan-build-reports .tpkg.var.master *.info\n\n' "${TPKG}" >> Makefile
|
printf 'clean:\n\t"%s" clean\n\trm -fr build build-stub-only build-event-loops build-static-analysis install scan-build-reports .tpkg.var.master *.info\n\n' "${TPKG}" >> Makefile
|
||||||
for P in ${OTHERS}
|
for P in ${OTHERS}
|
||||||
do
|
do
|
||||||
|
|
|
@ -36,3 +36,4 @@ export TPKG="${TPKG}"
|
||||||
export LIBTOOL="${LIBTOOL}"
|
export LIBTOOL="${LIBTOOL}"
|
||||||
END_OF_TPKG_VAR_MASTER
|
END_OF_TPKG_VAR_MASTER
|
||||||
|
|
||||||
|
${TPKG} f 255-yaml-config.tpkg
|
||||||
|
|
|
@ -193,10 +193,13 @@ function usage() {
|
||||||
out " -p PRI\tlog using PRI as priority"
|
out " -p PRI\tlog using PRI as priority"
|
||||||
out " -k\t\tdon't remove test directory when creating/executing a tpkg package"
|
out " -k\t\tdon't remove test directory when creating/executing a tpkg package"
|
||||||
out " -n NUM\tif less than NUM of the tests are passed exit with 1"
|
out " -n NUM\tif less than NUM of the tests are passed exit with 1"
|
||||||
|
out " \t\tOtherwise exit with 0. When NUM is -1, no tests may fail"
|
||||||
|
out " \t\tOnly valid when running tpkg report"
|
||||||
out " \t\tOtherwise exit with 0. Only valid when running tpkg report"
|
out " \t\tOtherwise exit with 0. Only valid when running tpkg report"
|
||||||
out " -b DIR\tuse DIR is a base directory in stead of ."
|
out " -b DIR\tuse DIR is a base directory in stead of ."
|
||||||
out " -a ARGS\tpass the string ARGS through to the test scripts"
|
out " -a ARGS\tpass the string ARGS through to the test scripts"
|
||||||
out " -d\t\tUse directories instead of tar.gz for tpkg archive format"
|
out " -d\t\tUse directories instead of tar.gz for tpkg archive format"
|
||||||
|
out " -f\t\tForce test to be re-run if already executed"
|
||||||
out
|
out
|
||||||
out " (C) NLnetLabs, Miek Gieben. Licensed under the GPL version 2."
|
out " (C) NLnetLabs, Miek Gieben. Licensed under the GPL version 2."
|
||||||
}
|
}
|
||||||
|
@ -329,11 +332,12 @@ function report() {
|
||||||
if [[ $passed -lt $TPKG_PASS ]]; then
|
if [[ $passed -lt $TPKG_PASS ]]; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
elif [[ $failed -gt 0 ]]; then
|
elif [[ $TPKG_PASS -lt 0 ]]; then
|
||||||
exit 1
|
if [[ $failed -gt 0 ]]; then
|
||||||
else
|
exit 1
|
||||||
exit 0
|
fi
|
||||||
fi
|
fi
|
||||||
|
exit 0
|
||||||
}
|
}
|
||||||
|
|
||||||
# clone test1 to test2
|
# clone test1 to test2
|
||||||
|
@ -858,9 +862,10 @@ echo "--------------- Test Output ------------------" | write_result result.$dsc
|
||||||
pre
|
pre
|
||||||
|
|
||||||
out "[log] Executing test"
|
out "[log] Executing test"
|
||||||
|
( ${SHELL} $dsc_test ${TPKG_ARGS} 2>&1 ) > result.$dsc_basename.tmp
|
||||||
( ${SHELL} $dsc_test ${TPKG_ARGS} 2>&1 ) | write_result result.$dsc_basename
|
|
||||||
test_result=$?
|
test_result=$?
|
||||||
|
write_result result.$dsc_basename < result.$dsc_basename.tmp
|
||||||
|
rm -f result.$dsc_basename.tmp
|
||||||
epoch # would like to run after post, but that is not possible :-(
|
epoch # would like to run after post, but that is not possible :-(
|
||||||
if [ $test_result -ne 0 ]; then
|
if [ $test_result -ne 0 ]; then
|
||||||
err "[warning] Test executed with errors: $test_result."
|
err "[warning] Test executed with errors: $test_result."
|
||||||
|
|
|
@ -46,6 +46,10 @@ typedef unsigned short in_port_t;
|
||||||
#include <wincrypt.h>
|
#include <wincrypt.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_GETDNS_YAML2DICT
|
||||||
|
getdns_return_t getdns_yaml2dict(const char *, getdns_dict **dict);
|
||||||
|
#endif
|
||||||
|
|
||||||
#define EXAMPLE_PIN "pin-sha256=\"E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=\""
|
#define EXAMPLE_PIN "pin-sha256=\"E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=\""
|
||||||
|
|
||||||
static int verbosity = 0;
|
static int verbosity = 0;
|
||||||
|
@ -215,7 +219,8 @@ print_usage(FILE *out, const char *progname)
|
||||||
fprintf(out, "\t-C\t<filename>\n");
|
fprintf(out, "\t-C\t<filename>\n");
|
||||||
fprintf(out, "\t\tRead settings from config file <filename>\n");
|
fprintf(out, "\t\tRead settings from config file <filename>\n");
|
||||||
fprintf(out, "\t\tThe getdns context will be configured with these settings\n");
|
fprintf(out, "\t\tThe getdns context will be configured with these settings\n");
|
||||||
fprintf(out, "\t\tThe file must be in json dict format.\n");
|
fprintf(out, "\t\tThe file must be in YAML format (with extension of '.yml')\n");
|
||||||
|
fprintf(out, "\t\tor JSON dict format (with extension '.conf')\n");
|
||||||
if (i_am_stubby) {
|
if (i_am_stubby) {
|
||||||
fprintf(out, "\t\tBy default, configuration is first read from");
|
fprintf(out, "\t\tBy default, configuration is first read from");
|
||||||
fprintf(out, "\n\t\t\"/etc/stubby.conf\" and then from \"$HOME/.stubby.conf\"\n");
|
fprintf(out, "\n\t\t\"/etc/stubby.conf\" and then from \"$HOME/.stubby.conf\"\n");
|
||||||
|
@ -346,7 +351,7 @@ static getdns_return_t validate_chain(getdns_dict *response)
|
||||||
if ((r = getdns_list_set_dict(to_validate, 0, reply)))
|
if ((r = getdns_list_set_dict(to_validate, 0, reply)))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (verbosity) printf("reply "PRIsz", dnssec_status: ", i);
|
if (verbosity) printf("reply %d, dnssec_status: ", (int)i);
|
||||||
switch ((s = getdns_validate_dnssec(
|
switch ((s = getdns_validate_dnssec(
|
||||||
to_validate, validation_chain, trust_anchor))) {
|
to_validate, validation_chain, trust_anchor))) {
|
||||||
|
|
||||||
|
@ -478,16 +483,25 @@ done:
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void parse_config(const char *config_str)
|
static void parse_config(const char *config_str, int yaml_config)
|
||||||
{
|
{
|
||||||
getdns_dict *config_dict;
|
getdns_dict *config_dict;
|
||||||
getdns_list *list;
|
getdns_list *list;
|
||||||
getdns_return_t r;
|
getdns_return_t r;
|
||||||
|
|
||||||
if ((r = getdns_str2dict(config_str, &config_dict)))
|
if (yaml_config) {
|
||||||
|
#ifdef USE_YAML_CONFIG
|
||||||
|
r = getdns_yaml2dict(config_str, &config_dict);
|
||||||
|
#else
|
||||||
|
fprintf(stderr, "Support for YAML configuration files not available.\n");
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
r = getdns_str2dict(config_str, &config_dict);
|
||||||
|
}
|
||||||
|
if (r)
|
||||||
fprintf(stderr, "Could not parse config file: %s\n",
|
fprintf(stderr, "Could not parse config file: %s\n",
|
||||||
getdns_get_errorstr_by_id(r));
|
getdns_get_errorstr_by_id(r));
|
||||||
|
|
||||||
else {
|
else {
|
||||||
if (!(r = getdns_dict_get_list(
|
if (!(r = getdns_dict_get_list(
|
||||||
config_dict, "listen_addresses", &list))) {
|
config_dict, "listen_addresses", &list))) {
|
||||||
|
@ -535,6 +549,7 @@ int parse_config_file(const char *fn, int report_open_failure)
|
||||||
FILE *fh;
|
FILE *fh;
|
||||||
char *config_file = NULL;
|
char *config_file = NULL;
|
||||||
long config_file_sz;
|
long config_file_sz;
|
||||||
|
size_t read_sz;
|
||||||
|
|
||||||
if (!(fh = fopen(fn, "r"))) {
|
if (!(fh = fopen(fn, "r"))) {
|
||||||
if (report_open_failure)
|
if (report_open_failure)
|
||||||
|
@ -559,15 +574,16 @@ int parse_config_file(const char *fn, int report_open_failure)
|
||||||
return GETDNS_RETURN_MEMORY_ERROR;
|
return GETDNS_RETURN_MEMORY_ERROR;
|
||||||
}
|
}
|
||||||
rewind(fh);
|
rewind(fh);
|
||||||
if (fread(config_file, 1, config_file_sz, fh) != (size_t)config_file_sz) {
|
read_sz = fread(config_file, 1, config_file_sz + 1, fh);
|
||||||
|
if (read_sz > (size_t)config_file_sz || ferror(fh) || !feof(fh)) {
|
||||||
fprintf( stderr, "An error occurred while reading \"%s\": %s\n"
|
fprintf( stderr, "An error occurred while reading \"%s\": %s\n"
|
||||||
, fn, strerror(errno));
|
, fn, strerror(errno));
|
||||||
fclose(fh);
|
fclose(fh);
|
||||||
return GETDNS_RETURN_MEMORY_ERROR;
|
return GETDNS_RETURN_MEMORY_ERROR;
|
||||||
}
|
}
|
||||||
config_file[config_file_sz] = 0;
|
config_file[read_sz] = 0;
|
||||||
fclose(fh);
|
fclose(fh);
|
||||||
parse_config(config_file);
|
parse_config(config_file, strstr(fn, ".yml") != NULL);
|
||||||
free(config_file);
|
free(config_file);
|
||||||
return GETDNS_RETURN_GOOD;
|
return GETDNS_RETURN_GOOD;
|
||||||
}
|
}
|
||||||
|
@ -656,7 +672,7 @@ getdns_return_t parse_args(int argc, char **argv)
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
} else if (arg[0] == '{') {
|
} else if (arg[0] == '{') {
|
||||||
parse_config(arg);
|
parse_config(arg, 0);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
} else if (arg[0] != '-') {
|
} else if (arg[0] != '-') {
|
||||||
|
@ -1071,11 +1087,11 @@ next: ;
|
||||||
/* apply the accumulated pubkey pinset to all upstreams: */
|
/* apply the accumulated pubkey pinset to all upstreams: */
|
||||||
for (j = 0; j < upstream_count; j++) {
|
for (j = 0; j < upstream_count; j++) {
|
||||||
if (r = getdns_list_get_dict(upstream_list, j, &upstream), r) {
|
if (r = getdns_list_get_dict(upstream_list, j, &upstream), r) {
|
||||||
fprintf(stderr, "Failed to get upstream "PRIsz" when adding pinset\n", j);
|
fprintf(stderr, "Failed to get upstream %d when adding pinset\n", (int)j);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
if (r = getdns_dict_set_list(upstream, "tls_pubkey_pinset", pubkey_pinset), r) {
|
if (r = getdns_dict_set_list(upstream, "tls_pubkey_pinset", pubkey_pinset), r) {
|
||||||
fprintf(stderr, "Failed to set pubkey pinset on upstream "PRIsz"\n", j);
|
fprintf(stderr, "Failed to set pubkey pinset on upstream %d\n", (int)j);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1269,7 +1285,9 @@ void read_line_cb(void *userarg)
|
||||||
if (listen_count)
|
if (listen_count)
|
||||||
(void) getdns_context_set_listen_addresses(
|
(void) getdns_context_set_listen_addresses(
|
||||||
context, NULL, NULL, NULL);
|
context, NULL, NULL, NULL);
|
||||||
(void) getdns_context_set_idle_timeout(context, 0);
|
if (interactive && !query_file)
|
||||||
|
(void) getdns_context_set_upstream_recursive_servers(
|
||||||
|
context, NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (query_file && verbosity)
|
if (query_file && verbosity)
|
||||||
|
@ -1668,16 +1686,22 @@ static void stubby_log(void *userarg, uint64_t system,
|
||||||
#ifdef GETDNS_ON_WINDOWS
|
#ifdef GETDNS_ON_WINDOWS
|
||||||
time_t tsec;
|
time_t tsec;
|
||||||
|
|
||||||
|
if (!verbosity)
|
||||||
|
return;
|
||||||
|
|
||||||
gettimeofday(&tv, NULL);
|
gettimeofday(&tv, NULL);
|
||||||
tsec = (time_t) tv.tv_sec;
|
tsec = (time_t) tv.tv_sec;
|
||||||
gmtime_s(&tm, (const time_t *) &tsec);
|
gmtime_s(&tm, (const time_t *) &tsec);
|
||||||
#else
|
#else
|
||||||
|
if (!verbosity)
|
||||||
|
return;
|
||||||
|
|
||||||
gettimeofday(&tv, NULL);
|
gettimeofday(&tv, NULL);
|
||||||
gmtime_r(&tv.tv_sec, &tm);
|
gmtime_r(&tv.tv_sec, &tm);
|
||||||
#endif
|
#endif
|
||||||
strftime(buf, 10, "%H:%M:%S", &tm);
|
strftime(buf, 10, "%H:%M:%S", &tm);
|
||||||
(void)userarg; (void)system; (void)level;
|
(void)userarg; (void)system; (void)level;
|
||||||
(void) fprintf(stderr, "[%s.%.6d] STUBBY: ", buf, (int)tv.tv_usec);
|
(void) fprintf(stderr, "[%s.%.6d] UPSTREAM ", buf, (int)tv.tv_usec);
|
||||||
(void) vfprintf(stderr, fmt, ap);
|
(void) vfprintf(stderr, fmt, ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1725,16 +1749,16 @@ main(int argc, char **argv)
|
||||||
, "%s/.stubby.conf"
|
, "%s/.stubby.conf"
|
||||||
, getenv("HOME")
|
, getenv("HOME")
|
||||||
);
|
);
|
||||||
(void) parse_config(default_stubby_config);
|
(void) parse_config(default_stubby_config, 0);
|
||||||
(void) parse_config_file("/etc/stubby.conf", 0);
|
(void) parse_config_file("/etc/stubby.conf", 0);
|
||||||
if (n_chars > 0 && n_chars < (int)sizeof(home_stubby_conf_fn)){
|
if (n_chars > 0 && n_chars < (int)sizeof(home_stubby_conf_fn)){
|
||||||
(void) parse_config_file(home_stubby_conf_fn, 0);
|
(void) parse_config_file(home_stubby_conf_fn, 0);
|
||||||
}
|
}
|
||||||
clear_listen_list_on_arg = 1;
|
clear_listen_list_on_arg = 1;
|
||||||
|
|
||||||
(void) getdns_context_set_logfunc(context, NULL,
|
|
||||||
GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_DEBUG, stubby_log);
|
|
||||||
}
|
}
|
||||||
|
(void) getdns_context_set_logfunc(context, NULL,
|
||||||
|
GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_DEBUG, stubby_log);
|
||||||
|
|
||||||
if ((r = parse_args(argc, argv)))
|
if ((r = parse_args(argc, argv)))
|
||||||
goto done_destroy_context;
|
goto done_destroy_context;
|
||||||
clear_listen_list_on_arg = 0;
|
clear_listen_list_on_arg = 0;
|
||||||
|
|
|
@ -171,7 +171,7 @@ typedef enum network_req_state_enum
|
||||||
/* State for async tcp stub resolving */
|
/* State for async tcp stub resolving */
|
||||||
typedef struct getdns_tcp_state {
|
typedef struct getdns_tcp_state {
|
||||||
|
|
||||||
uint8_t *write_buf;
|
const uint8_t *write_buf;
|
||||||
size_t write_buf_len;
|
size_t write_buf_len;
|
||||||
size_t written;
|
size_t written;
|
||||||
|
|
||||||
|
@ -188,7 +188,9 @@ typedef struct getdns_tcp_state {
|
||||||
typedef struct getdns_network_req
|
typedef struct getdns_network_req
|
||||||
{
|
{
|
||||||
/* For storage in upstream->netreq_by_query_id */
|
/* For storage in upstream->netreq_by_query_id */
|
||||||
_getdns_rbnode_t node;
|
_getdns_rbnode_t node;
|
||||||
|
/* The netreq_by_query_id tree in which this netreq was registered */
|
||||||
|
_getdns_rbtree_t *query_id_registered;
|
||||||
#ifdef HAVE_MDNS_SUPPORT
|
#ifdef HAVE_MDNS_SUPPORT
|
||||||
/*
|
/*
|
||||||
* for storage of continuous query context in hash table of cached results.
|
* for storage of continuous query context in hash table of cached results.
|
||||||
|
@ -300,6 +302,7 @@ typedef struct getdns_dns_req {
|
||||||
unsigned dnssec_return_all_statuses : 1;
|
unsigned dnssec_return_all_statuses : 1;
|
||||||
unsigned dnssec_return_validation_chain : 1;
|
unsigned dnssec_return_validation_chain : 1;
|
||||||
unsigned dnssec_return_full_validation_chain : 1;
|
unsigned dnssec_return_full_validation_chain : 1;
|
||||||
|
unsigned dnssec_extension_set : 1;
|
||||||
#ifdef DNSSEC_ROADBLOCK_AVOIDANCE
|
#ifdef DNSSEC_ROADBLOCK_AVOIDANCE
|
||||||
unsigned dnssec_roadblock_avoidance : 1;
|
unsigned dnssec_roadblock_avoidance : 1;
|
||||||
unsigned avoid_dnssec_roadblocks : 1;
|
unsigned avoid_dnssec_roadblocks : 1;
|
||||||
|
@ -324,6 +327,7 @@ typedef struct getdns_dns_req {
|
||||||
* freed is touched by _getdns_submit_netreq only
|
* freed is touched by _getdns_submit_netreq only
|
||||||
*/
|
*/
|
||||||
unsigned validating : 1;
|
unsigned validating : 1;
|
||||||
|
unsigned waiting_for_ta : 1;
|
||||||
int *freed;
|
int *freed;
|
||||||
|
|
||||||
/* Validation chain to be canceled when this request is canceled */
|
/* Validation chain to be canceled when this request is canceled */
|
||||||
|
@ -365,6 +369,11 @@ typedef struct getdns_dns_req {
|
||||||
*/
|
*/
|
||||||
struct getdns_dns_req *finished_next;
|
struct getdns_dns_req *finished_next;
|
||||||
|
|
||||||
|
/* Linked list pointer for dns requests, which need to validate DNSSEC
|
||||||
|
* and are waiting for the root trust-anchors fetch.
|
||||||
|
*/
|
||||||
|
struct getdns_dns_req *ta_notify;
|
||||||
|
|
||||||
/* network requests for this dns request.
|
/* network requests for this dns request.
|
||||||
* The array is terminated with NULL.
|
* The array is terminated with NULL.
|
||||||
*
|
*
|
||||||
|
|
|
@ -203,7 +203,7 @@ INLINE uint64_t _getdns_get_now_ms()
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
|
|
||||||
(void) gettimeofday(&tv, NULL);
|
(void) gettimeofday(&tv, NULL);
|
||||||
return tv.tv_sec * 1000 + tv.tv_usec / 1000;
|
return (uint64_t)tv.tv_sec * 1000 + tv.tv_usec / 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
INLINE uint64_t _getdns_ms_until_expiry(uint64_t expires)
|
INLINE uint64_t _getdns_ms_until_expiry(uint64_t expires)
|
||||||
|
|
|
@ -45,6 +45,8 @@
|
||||||
#define sec_status_insecure _getdns_sec_status_insecure
|
#define sec_status_insecure _getdns_sec_status_insecure
|
||||||
#define sec_status_unchecked _getdns_sec_status_unchecked
|
#define sec_status_unchecked _getdns_sec_status_unchecked
|
||||||
#define sec_status_bogus _getdns_sec_status_bogus
|
#define sec_status_bogus _getdns_sec_status_bogus
|
||||||
|
#define fake_sha1 _getdns_fake_sha1
|
||||||
|
#define fake_dsa _getdns_fake_dsa
|
||||||
|
|
||||||
enum sec_status { sec_status_bogus = 0
|
enum sec_status { sec_status_bogus = 0
|
||||||
, sec_status_unchecked = 0
|
, sec_status_unchecked = 0
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 10f968b0e78b9aeee357d0de81a46b445c3fb27b
|
2
stubby
2
stubby
|
@ -1 +1 @@
|
||||||
Subproject commit 6114230904d9413514d521358ca7956aac99e822
|
Subproject commit 0cbd46ea6d0da727c42b0890d498366cd2b1ec2c
|
Loading…
Reference in New Issue