Compare commits

...

174 Commits

Author SHA1 Message Date
Sara Dickinson f8c95b4f15 Update Stubby to fix Windows build issues 2023-01-09 16:50:12 +00:00
Sara Dickinson ee534d10bf Fix typo preventing Windows build when Pkgconfig not available 2023-01-09 16:40:19 +00:00
Willem Toorop 6395fe43cc Fix #536 Broken trust anchor files are silently ignored 2023-01-02 16:03:59 +01:00
Willem Toorop d98d307e64 New 1.7.3 release with quickfix 1.4.3 stubby release 2022-12-22 15:22:09 +01:00
Willem Toorop c8df60e67d
Merge pull request #532 from GabrielGanne/cmake-required-version-fix
Increase CMake required version 3.5 -> 3.20
2022-12-22 15:18:56 +01:00
Gabriel Ganne 037892739f Increase CMake required version 3.5 -> 3.20
Commit 777e0b245c introduced cmake_path
which has been added to Cmake in 3.20 onlyi [1], so this should only make
the error message more explicit.

[1] https://cmake.org/cmake/help/git-master/command/cmake_path.html
2022-11-09 11:51:55 +01:00
Willem Toorop 9c076ca34b Issue #526 Some gldns files need stdlib 2022-08-22 10:41:05 +02:00
Willem Toorop 3a71bd350e getdns-1.7.2 quickfix stubby release 2022-08-19 20:00:36 +02:00
Willem Toorop 8aa19255b8 Leave out some tests that fail to be reviewed later on 2022-08-19 15:42:13 +02:00
Willem Toorop 7eaf8454a2 Okay, assert detection with check is broken (at least with me) 2022-08-19 15:08:46 +02:00
Willem Toorop 2e04e9f8b6 Why do these tests destroy the context from a callback? 2022-08-19 14:46:15 +02:00
Willem Toorop a19177d41e Bump version for release 2022-08-19 13:27:06 +02:00
Willem Toorop a1451df680 Fix #512 update README.md to show correct pgp key location 2022-08-19 11:36:34 +02:00
Willem Toorop 777e0b245c Fix #517 Allow Absolute paths in pkg-config 2022-08-19 11:29:45 +02:00
Willem Toorop 2d48a3bd1b Fix Issue #524 merge upstream ssl_dane into submodule 2022-08-19 11:01:57 +02:00
Willem Toorop 9bb533ab57 Update stubby (and no release yet) 2022-08-12 18:56:03 +02:00
Willem Toorop 86bd62cb40
Merge pull request #523 from getdnsapi/gnu_tls_alpn
Add support for `dot` ALPN for GnuTLS
2022-08-12 15:27:59 +02:00
Sara Dickinson adcdf20289 Add support for dot ALPN for GnuTLS 2022-08-12 12:45:15 +01:00
Willem Toorop aca15088e5 Update stubby 2022-08-11 16:48:23 +02:00
Willem Toorop 1ea92a68ad Set version to first release candidate 2022-08-11 16:24:42 +02:00
Willem Toorop 142f616693 ChangeLog entry for issue getdnsapi/stubby#295 2022-08-11 16:21:14 +02:00
Willem Toorop 6b65aed443 Fix getdnsapi/stubby#295 set default build type to RelWithDebInfo
And expose CFLAGS through GETDNS_BUILD_CFLAGS define and via getdns_context_get_api_information()
2022-08-11 16:15:30 +02:00
Willem Toorop 0cb72000f8 Avoid using old OpenSSL HMAC functions 2022-08-11 12:26:41 +02:00
Willem Toorop 1748ca4c29 First step in dealing with OpenSSL 3.0 warnings 2022-08-11 11:30:53 +02:00
Willem Toorop b181782e0e Update gldns 2022-08-11 11:30:34 +02:00
Willem Toorop f97ee14b69 Merge branch 'madebr-cmake_pkgconfig' into develop 2022-08-10 16:10:38 +02:00
Willem Toorop 1a1e79603c Merge branch 'cmake_pkgconfig' of github.com:madebr/getdns into madebr-cmake_pkgconfig 2022-08-10 16:10:13 +02:00
Willem Toorop 875c03176e Log uzlonewolf contribution 2022-08-10 14:58:38 +02:00
uzlonewolf 2d7d8a4ea5 Tighten up _getdns_ipaddr_dict_mf() so it does not grab random strings beginning with '*' 2022-08-10 14:53:43 +02:00
Willem Toorop 8e2accfd74 Log fix from Shikha 2022-08-10 14:32:35 +02:00
Willem Toorop 861ae30725
Merge pull request #520 from SharmaShikha-84/master
Fix for issue in UDP stream selection in case of timeouts.
2022-08-10 14:31:18 +02:00
Willem Toorop dc5026f2c8
Merge pull request #515 from thesamesam/develop
CMakeLists.txt: use CMAKE_INSTALL_MANDIR too
2022-08-09 17:02:36 +02:00
Willem Toorop 10a000b916
Merge pull request #518 from amialkow/develop
Fixed allowed offset range during name compression.
2022-08-09 17:00:13 +02:00
Willem Toorop 893d4720c9
Merge pull request #519 from getdnsapi/use_dot_alpn
Update Stubby to always send the `dot` ALPN when using DoT
2022-08-09 16:54:30 +02:00
Willem Toorop 2bbac1163b
Merge branch 'develop' into use_dot_alpn 2022-08-09 16:54:20 +02:00
Sara Dickinson 9d8eea97a5 Fix typo in cmake module for libidn2 2022-07-21 14:17:53 +01:00
Sara Dickinson c0e45395b8
Merge pull request #522 from jpbion/fixlibidn2
Category: Strengthen LibIDN2 version determination during cmake run
2022-07-21 14:14:35 +01:00
Joel Bion ed7bfa107e Category: Strengthen LibIDN2 version determination during cmake run 2022-07-20 16:01:25 -07:00
Shikha Sharma 94dbb8e916
Update stub.c
Fix for issue mentioned below:
Scenario: 4 UDP steams corresponding to 4 IP's configured.
Outbound query is always sent to 1st IP in the list unless there is a timeout.
If there is a timeout, the next outbound query is sent to the 2nd IP in the list.
If the 1st IP still times out then the next 2n queries (this increases in powers of 2) go to the 2nd IP.
If the 2nd IP times out at any point, then queries are sent to the 3rd IP (following the same algorithm of 2n queries before reverting to the 2nd IP)

Observation: Even if there is no timeout on 2nd IP, some queries are still sent to 3rd IP.
From code: The stream is switched whenever there is a timeout. If 10 messages were sent to first IP and they all timeout , the stream is switched 10 times in the current code.   
Suggestion: Switch stream only on the first timeout on a stream or ignore when the timeout occurs on a stream which is not the current_udp stream.
2022-06-13 17:06:55 +02:00
Sara Dickinson a5a1256adc Update Stubby to always send the `dot` ALPN when using DoT 2022-06-07 10:27:39 +01:00
Andrzej Mialkowski 190dbe1b91 Fixed allowed offset range during name compression. 2022-05-22 23:12:28 -07:00
Sam James c50288f71e
CMakeLists.txt: use CMAKE_INSTALL_MANDIR too
Signed-off-by: Sam James <sam@gentoo.org>
2022-03-30 05:27:54 +01:00
Willem Toorop c2e085ee9e
Merge pull request #509 from thesamesam/change-docdir-variable
CMakeLists.txt: use canonical GNUInstallDirs variable for docdir
2022-03-29 15:00:27 +02:00
Willem Toorop 01715688d7 Sync crypto funcs from Unbound 2022-02-04 16:32:54 +01:00
Willem Toorop ecb9de2c29 Sync gldns from Unbound sldns 2022-02-04 15:24:21 +01:00
Willem Toorop b86f8e904c Vim leftover 2022-02-04 14:55:39 +01:00
Willem Toorop 45683d3cfe Fix for getdnsapi/stubby#295
rdata not correctly written for validation for certain RR types
2022-01-11 00:09:44 +01:00
Sam James 822166d7ad
CMakeLists.txt: use canonical GNUInstallDirs variable for docdir
We use the GNUInstallDir variables for the rest of the build system
locations, so let's use CMAKE_INSTALL_DOCDIR too to allow customisation
downstream.

(In Gentoo, we set it to the exact package version including downstream-only
revisions.)

Signed-off-by: Sam James <sam@gentoo.org>
2021-06-09 23:57:40 +00:00
Willem Toorop e4661f957e getdns-1.7.0 release
-----BEGIN PGP SIGNATURE-----
 
 iQJIBAABCgAyFiEE3DTuXbJBe8wVHlEA5fj4IS93pJgFAmC6dzkUHHdpbGxlbUBu
 bG5ldGxhYnMubmwACgkQ5fj4IS93pJhrZg//YROnFsupA7JVFhaO05b20vDWxhp8
 kRBfsMyox8w4cOE0QXqcqsogmxAw0wyLp14+TvVwRxivcl21GyKTY07YpJDSopvy
 BM1DIPZ8O32ONyJUmEzAdJwvDcYJx4FIAeCAyK0bP7ev+ung1Q2GgSzej7oXd6hZ
 WCMSPZZcTnFXQ7w/4Fe4pQVoZWGVonEXBJbCUTgyeiKYnGXTO1qISsqeeYaMgP0n
 vPa4k8kSlr/KPDnD7ts0BKsWOFiHJyi/rHjLZVq8f5pCB3FE3FR3jlIo2e8w7hLM
 SC8wxH58+prHbe+1zNZiMA3OXY7nozvSO3QkomLm3QH/r73CkqkBYfBLAJ0LRuHj
 s0TRY7y7GEUGWPnLjkCw+H3/aumEep0i7YaVV5Tj1g+Htt4fMxZhQPWO/T+LGZap
 ILsN+LmqGR9ARHAo+j2REmot0ubk9FP+fan2EIe6c6/cOxSyIe3LncfLG/7U4MlF
 SYxcRtlzQrrU40hoA8S6xGRrSvG4qjthWTWsv35VzTZXA5nHuSdZn0HpWlfLrOi6
 CSZueZ1lQ9hfgTTbLLCdZYbmWDAPv13YBkLWQTSQy955vc34x/h+qRodhzfX8w18
 ypzqEmQwUQFXdG/Wat5vGcOf+M+6Ak2QqmN88AgfHmyKbQUEh6JbpvF85q7gp8ad
 A49nb6aGD2cuREI=
 =iTYQ
 -----END PGP SIGNATURE-----

Merge tag 'v1.7.0'

getdns-1.7.0 release
2021-06-04 20:57:12 +02:00
Willem Toorop 1f2aa585fc getdns-1.7.0 release 2021-06-04 20:53:14 +02:00
Willem Toorop 2a0114591a Resolve compile warnings
Thanks Andreas!
2021-06-03 20:45:55 +02:00
Anonymous Maarten de2137562d cmake: find libuv pkgconfig non-QUIET 2021-05-28 23:03:44 +02:00
Anonymous Maarten 6eb1a6790a cmake: don't call find_package_handle_standard_args when using pkg_config + cache variables 2021-05-28 16:03:30 +02:00
Anonymous Maarten f92f97bf1e Findlibidn module is not available 2021-05-28 14:15:40 +02:00
Anonymous Maarten cf2b805ef7 Try FindPkgConfig to find modules before going manual 2021-05-28 14:15:40 +02:00
Jim Hague 6dfbfa5dc5 Add header-present guards to include of sys/time.h.
I'm not sure why this hasn't been hit before - it breaks the build on
Windows. I guess that another change has started dragging in this file
where it wasn't used before.
2021-05-28 00:05:20 +01:00
Jim Hague 686285ef59 Re-remove strings.h include.
Again, looks like another copied-from-elsewhere problem.
2021-05-28 00:04:11 +01:00
Jim Hague ae854a8650 Re-add include guards to parseutil.c.
The lack of them breaks the build on Windows.

I suspect we may have another copied-from-elsewhere problem.
2021-05-27 22:24:17 +01:00
Willem Toorop ca97810ed6 Merge branch 'release/v1.7.0' into develop 2021-05-27 22:34:55 +02:00
Willem Toorop df4c7ce4f9 Mention event extension rename (back to old names) in ChangeLog 2021-05-27 22:23:16 +02:00
Willem Toorop 359a44d336 Merge branch 'release/v1.7.0' into develop 2021-05-27 22:21:43 +02:00
Willem Toorop 48a7700fa9 Update ChangeLog 2021-05-27 22:21:03 +02:00
Willem Toorop 2b348b046d Merge branch 'amialkow-develop4' into release/v1.7.0 2021-05-27 22:08:05 +02:00
Willem Toorop 50463c7480 Merge branch 'develop4' of https://github.com/amialkow/getdns into amialkow-develop4 2021-05-27 21:56:38 +02:00
Willem Toorop 1012e34441 update of ldns 2021-05-27 21:23:16 +02:00
Willem Toorop 3f07247e64 Merge branch 'develop' into release/v1.7.0 2021-05-27 20:41:23 +02:00
Willem Toorop 86aa356b48 Release version 1.7.0 tomorrow 2021-05-27 20:39:26 +02:00
Jim Hague fc62f8877c When cross-compiling, assume strptime() is POSIX unless told otherwise.
But issue a warning when making that assumption. Add new option
FORCE_COMPAT_STRPTIME to force the use of the compat version
when cross-compiling and the target platform strptime() is not
POSIX-compliant. Poster children for the latter are BSD platforms,
including MacOS, where %t is not handled POSIXly.

Fix #472
2021-05-27 12:11:49 +01:00
Jim Hague f9c3a359ed Revise recent lookup3.c update to restore building on Windows.
As we're now building with CMake, and CMake can supply endianness, just insist on using that.
2021-05-27 09:45:30 +01:00
Willem Toorop a694080400 First release candidate tomorrow 2021-05-27 09:59:15 +02:00
Willem Toorop fe79e7e633 Bump version 2021-05-26 23:29:44 +02:00
Willem Toorop 61f9ab4351 All tests again 2021-05-26 23:17:44 +02:00
Willem Toorop 6c3f75f4e9 Test transports with OpenSSL 2021-05-26 23:16:02 +02:00
Willem Toorop d055caff44 Test only transports 2021-05-26 23:02:30 +02:00
Willem Toorop 880189367a Make tcp_send_timeout work with GnuTLS 2021-05-26 23:01:45 +02:00
Willem Toorop ed9ac22c66 Update stubby to develop branch 2021-05-26 22:47:19 +02:00
Willem Toorop 189be4b5a5 Try to improve travis results with tcp_send_timeout 2021-05-26 22:37:55 +02:00
amialkow bfdba6d9d7 Merge branch 'getdnsapi:develop' into develop4 2021-05-26 09:55:16 -07:00
Willem Toorop 75b750b3f9
Merge pull request #506 from amialkow/develop3
Fixes #504
2021-05-26 16:11:01 +02:00
Willem Toorop 6a722f5d79
Merge pull request #496 from banburybill/develop
Some Windows behaviour fixes.
2021-05-26 16:09:35 +02:00
Willem Toorop eeb460af8d Merge branch 'develop' of github.com:getdnsapi/getdns into develop 2021-05-26 16:06:30 +02:00
Willem Toorop e030b2525d Merge branch 'maciejsszmigiero-tcp-send-timeout' into develop 2021-05-26 16:05:27 +02:00
Willem Toorop 45ef080bad Changelog entry for getdns_context_set_tcp_send_timeout() contribution
Thanks a lot @maciejsszmigiero , this looks really valueable!
2021-05-26 16:03:56 +02:00
Willem Toorop 624f688967 Honour the claim from documentation: When not set (the default), the system default is left alone. 2021-05-26 15:57:52 +02:00
Willem Toorop 515127289c Merge branch 'tcp-send-timeout' of https://github.com/maciejsszmigiero/getdns into maciejsszmigiero-tcp-send-timeout 2021-05-26 15:56:55 +02:00
Willem Toorop ae090a29b1
Merge pull request #482 from neheb/patch-1
val_secalgo: add missing DSA header
2021-05-26 15:48:10 +02:00
Willem Toorop 7b388a1576 ChangeLog update for issue #480 2021-05-26 15:45:53 +02:00
Willem Toorop df2997d9b7 Eliminate compiler warnings in tests 2021-05-26 15:44:24 +02:00
Willem Toorop 1184f2b8ea Update components from Unbound 2021-05-26 15:43:40 +02:00
Willem Toorop 55be327f69 Fix wrong extension names from merge 2021-05-26 15:42:35 +02:00
Willem Toorop d934b4129f Merge branch 'banburybill-feature/installdlls' into develop 2021-05-26 15:13:11 +02:00
Willem Toorop 3966459fdb Merge branch 'feature/installdlls' of https://github.com/banburybill/getdns into banburybill-feature/installdlls 2021-05-26 15:12:59 +02:00
Willem Toorop c1b6903e58
Merge pull request #472 from cohall-2020/develop
Skip check_c_source_runs when cross-compiling.
2021-05-26 11:21:43 +02:00
Willem Toorop 8abc3b62b8
Merge pull request #468 from renaudallard/develop
Added checks for LibreSSL and OpenBSD
2021-05-26 11:18:20 +02:00
Willem Toorop 63e4d1a1ef
Merge pull request #474 from banburybill/feature/blocking-select
Observe blocking flag in select run_once.
2021-05-26 11:17:20 +02:00
Andrzej Mialkowski 8b558afde0 Fixes #505. Disable packet size checking. 2021-05-15 13:20:30 -07:00
Andrzej Mialkowski 7f606ea14f Add missing rr types: SVCB and HTTPS 2021-05-15 12:32:58 -07:00
Andrzej Mialkowski fa282a59ec Add missing rr types: SVCB and HTTPS 2021-05-15 12:32:58 -07:00
Andrzej Mialkowski 7b12e21ad0 Implement name compression during response packet generation. Compression is required by certain clients like UDP to fit response in packet size limit. While generating packet small cache stores recently used names (currently 4 entries) and uses relative references to previous instances of the same name. Each reused instance is just two bytes of relative reference (0xC000 + offset). Cache is currently performing lookup for query name, responses and CNAMEs. 2021-05-09 14:45:16 -07:00
Willem Toorop 291e001881
Merge pull request #497 from har-riz/develop
Fix typo in cmakeconfig.h.in files
2021-01-27 13:40:26 +01:00
har-riz 0a13e4dbd3
Fix typo in cmakeconfig.h.in files
Fix typo in CMAKE included files, so Stubby can use TLS v1.3 with chipersuites options ON.

This solve issue that's written in here :
https://github.com/getdnsapi/stubby/issues/240
2021-01-27 18:29:22 +07:00
Jim Hague 42e4cfc383 Windowqs mkstemp: open() needs more permissions.
Specifically:

1. The open must be for read only or read/write - use read/write.
2. The file permission must permit read and write.
2020-12-12 21:16:46 +00:00
Jim Hague 6439b0407a Add platform functions for reporting file errors.
Windows socket error numbers are not reported using errno, but with
WSAGetLastError(). _getdns_errnostr() and friends as implemented on
Windows don't work for errors resulting from file open/close/read/write
etc.

So add a parallel set of functions specifically for file errors.
2020-12-11 16:08:02 +00:00
Jim Hague 7fe308f718
Merge pull request #492 from fcelda/fix-lib-naming
Fix naming of extension libraries
2020-11-04 10:13:10 +00:00
Jim Hague 4440a24352
Merge pull request #489 from fcelda/fix-lib-exports
Fix exporting symbols for extension libraries
2020-11-04 10:04:43 +00:00
Willem Toorop ebeff97192
Merge pull request #486 from elindsey/eli
only check for and process read/write events if status is success
2020-10-05 12:34:28 +02:00
Jan Vcelak 03fc32984e build: fix naming of extension libraries 2020-10-05 12:23:27 +02:00
Jan Vcelak 6507e4c469 build: fix exporting symbols for extension libraries 2020-09-18 14:02:30 +02:00
Eli Lindsey 71521626d9 only check for and process read/write events if status is success 2020-09-10 10:59:12 -04:00
Rosen Penev 80cdfb3bd0
fix compilation without deprecated OpenSSL APIs
Several cmake header checks were missing and added.

Added rsa.h include.

Remove ENGINE_load_dynamic. ENGINE_load_builtin_engines already does
this.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-08-04 19:54:18 -07:00
Willem Toorop bda845ce43 Issue #430 listeners reply returned wireformat
So that proxies based on `getdns_set_listen_addresses()` reply with compression from the original response.
2020-08-04 00:05:04 +02:00
Maciej S. Szmigiero 606a88f9aa
Add "tcp_send_timeout" option to set a TCP send data timeout
When using Stubby as a system DNS over TLS resolver with a Internet
connection that disconnects and reconnects from time to time there is often
a long waiting time (~20 minutes) after the connection reconnects before
DNS queries start to work again.

This is because in this particular case all the upstream TLS TCP
connections in Stubby are stuck waiting for upstream server response.
Which will never arrive since the host external IP address might have
changed and / or NAT router connection tracking entries for these TCP
connections might have been removed when the Internet connection
reconnected.

By default Linux tries to retransmit data on a TCP connection 15 times
before finally terminating it.
This takes 16 - 20 minutes, which is obviously a very long time to wait for
system DNS resolving to work again.
This is a real problem on weak mobile connections.

Thankfully, there is a "TCP_USER_TIMEOUT" per-socket option that allows
explicitly setting how long the network stack will wait in such cases.

Let's add a matching "tcp_send_timeout" option to getdns that allows
setting this option on outgoing TCP sockets.
For backward compatibility the code won't try to set it by default.

With this option set to, for example, 15 seconds Stubby recovers pretty
much instantly in such cases.

Signed-off-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name>
2020-07-13 00:21:16 +02:00
Willem Toorop fc4eb466b9
Merge pull request #478 from banburybill/feature/static-openssl
Add system libraries when checking OpenSSL functions.
2020-06-25 12:18:15 +02:00
Jim Hague c9072b2526 Add system libraries when checking OpenSSL functions.
If OpenSSL is a static library, linking the test programs will require
system libraries.
2020-06-24 22:07:29 +01:00
Jim Hague 1c97459ec3 Install the DLLs when installing on Windows. 2020-06-24 14:36:30 +01:00
Willem Toorop 7c767b1a5f
Merge pull request #476 from elindsey/develop
register only a single poll_t with libuv
2020-06-19 10:24:17 +02:00
Eli Lindsey 2673a5736c register only a single poll_t with libuv
Most of the time we only need a read _or_ a write callback registered
with libuv - for example, on a UDP request a write callback is
registered, when executed the write callback performs the write,
deregisters itself, and registers a read callback.

However there is one case where getdns registers both read and write
callbacks: when a backlog of TCP requests is going to the same upstream
resolver, we use a single fd and queue the requests. In this instance we
want to listen for both read (to get responses for requests we've
already sent) and write (to continue to send our pending requests).

libuv, like most event libraries, only allows one callback to be
registered per fd. To get notification for both reads and writes, you
should examine the event flags and have appropriate conditional logic
within the single callback. Today getdns incorrectly tries to register
two separate poll_t with libuv, one for read and one for write - this
results in a crash (internal libuv assertion guaranteeing that only a
single poll_t is registered per fd).

Testing was done by using flamethrower
(https://github.com/DNS-OARC/flamethrower) to toss queries at a program
that embeds getdns.

Note that a higher qps trigger a _different_ getdns/libuv crashing bug
that occurs when the TCP backlog grows so large that requests start to
time out. That crash is not addressed in this PR, and will be more
involved to fix.
2020-06-18 17:31:34 -04:00
Jim Hague 8a95f3d279 Observe blocking flag in select run_once.
Currently run_once always blocks.
2020-06-12 10:49:47 +01:00
Willem Toorop f020cca206
Merge pull request #473 from rogers0/PR/fix_cmake
Fix install path for cmake build since we use GNUInstallDirs
2020-05-27 17:42:24 +02:00
Roger Shimizu 7c6188c53d Fix install path for cmake build since we use GNUInstallDirs
So we use install path below since cmake v3.0 [1]:
 - CMAKE_INSTALL_LIBDIR
 - CMAKE_INSTALL_INCLUDEDIR

[1] https://cmake.org/cmake/help/v3.0/module/GNUInstallDirs.html
2020-05-27 00:30:33 +09:00
cohall-2020 5e7bf99a5f
Merge pull request #1 from cohall-2020/cohall-2020-patch-CMakeList
Update CMakeLists.txt
2020-05-08 13:27:00 +02:00
Willem Toorop 5c79e2c731
Merge pull request #471 from getdnsapi/feature/privacy-aware-cookies
Privacy aware DNS Cookies
2020-05-01 11:13:00 +02:00
cohall-2020 320dd098a8
Update CMakeLists.txt 2020-04-28 23:56:40 +02:00
Willem Toorop 8bd87c490e Fix of const-info.c 2020-04-14 20:58:36 +02:00
Willem Toorop 9ecd3fde1c Privacy aware DNS Cookies
Track source IP address in an efficient manner to make sure the same cookie will not be sent from different source IP addresses.
2020-04-09 16:24:34 +02:00
Willem Toorop de13a0c32d Better retry on badcookie flooding prevention 2020-04-08 19:16:51 +02:00
Willem Toorop 8b62970e0c Response to BADCOOKIE extended rcode 2020-04-08 16:08:56 +02:00
Willem Toorop 563b2b113a Show dns_root_servers setting in API information 2020-03-27 10:11:26 +01:00
Renaud Allard 31031d7c57 Added checks for LibreSSL and OpenBSD 2020-03-24 14:14:39 +01:00
Willem Toorop 73cee29f55 Make TLS Handshake timeout max 4/5th of timeout
for the query, just like connection setup timeout was, so fallback transport have a chance too when TCP connection setup is less well detectable (as with TCP_FASTOPEN on MacOS).
2020-03-16 14:50:59 +01:00
Jim Hague 0b01ad8e6f Merge branch 'develop' of https://github.com/getdnsapi/getdns into develop 2020-03-16 11:23:52 +00:00
Willem Toorop 3c6756d68b Issue #466: Memory leak with retrying queries
(for examples with search paths).
Thanks doublez13.
2020-03-13 22:31:01 +01:00
Jim Hague 3f9e0f9671 Merge branch 'my-develop' into develop
Update Stubby and add small GnuTLS version fixup to signature selection.
2020-03-12 16:17:08 +00:00
Jim Hague be09306567 Update Stubby to pick up latest Stubby release tag and Windows packaging details. 2020-03-12 16:13:11 +00:00
Jim Hague cd386cd917 Merge commit '26a95b5b8a213096641654c5b97976e66ec32e5d' into my-develop
# Conflicts:
#	src/gnutls/tls.c
2020-03-12 15:51:22 +00:00
Willem Toorop 2c51db610a
Merge pull request #465 from banburybill/develop
Relax GnuTLS priority strings slightly to allow getdns to work with T…
2020-03-05 14:52:55 +01:00
Willem Toorop 26a95b5b8a Fix DoT with GnuTLS >= 3.6 2020-03-05 14:46:32 +01:00
Jim Hague 0078977ada Merge branch 'develop' into my-develop 2020-03-05 13:25:24 +00:00
Jim Hague 9baf655a7b Relax GnuTLS priority strings slightly to allow getdns to work with TLS1.3 servers.
Now GnuTLS 3.6.5 and later are in the field, we've run into problems handshaking with TLS1.3 servers with a GnuTLS build. OpenSSL works fine. Comparing the client handshake of GnuTLS and OpenSSL, we found GnuTLS was being considerably more restrictive. This change loosens the restriction so GnuTLS presents nearly the same set of cipher and other options and OpenSSL. OpenSSL provides more signature algorithms. The change gets GetDNS working against Quad1, Quad8, Quad9 and the getdnsapi servers.
2020-03-05 13:24:44 +00:00
Willem Toorop c234865a80 Print GnuTLS debug messages 2020-03-05 13:39:30 +01:00
Willem Toorop 6972c99268
Merge pull request #464 from banburybill/develop
Various small fixes
2020-03-05 10:14:28 +01:00
Jim Hague 252d68e67a Update stubby. 2020-03-04 16:06:14 +00:00
Jim Hague 37e33bc7f5 Merge branch 'develop' into my-develop 2020-03-04 15:30:47 +00:00
Jim Hague e96e334932 Point ssl_dane submodule back at getdnsapi version. 2020-03-04 15:30:26 +00:00
Jim Hague 55ffca15ce Merge branch 'develop' into my-develop 2020-03-04 15:13:57 +00:00
Jim Hague 1328fac5ae Merge commit 'ef455471f4f1db778e7bcc58818fc780a280c16d' into develop 2020-03-04 15:13:02 +00:00
Willem Toorop ef455471f4 Work around dnsmasq issue 2020-03-04 10:57:11 +00:00
Jim Hague f01e7188c8 CMake libunbound fixups.
1. ub_ctx_set_stub is in unbound.h, not unbound-events.h.
2. Only bother looking for unbound event API if enabled.
3. If building stub only, ensure all libunbound items are off. This is necessary in case we first configure without stub only, and then change to stub only.

Fixes #463
2020-03-04 09:45:52 +00:00
Jim Hague 65f7d96678 Merge branch 'develop' into my-develop 2020-03-03 17:29:52 +00:00
Jim Hague 822d8ad703 Revise recent lookup3.c update to restore building on Windows.
As we're now building with CMake, and CMake can supply endianness, just insist on using that.
2020-03-03 17:28:34 +00:00
Jim Hague 2e4070a3cd Merge branch 'develop' into my-develop 2020-03-03 14:51:17 +00:00
Willem Toorop 689415971a Run all tests again 2020-03-03 13:14:45 +00:00
Willem Toorop e7d435e426 Name only authentication with GNUTLS 2020-03-03 13:04:27 +00:00
Willem Toorop 9c8b70e4bc Eliminate compile error 2020-03-03 13:03:58 +00:00
Jim Hague 38627fbb01 Merge branch 'develop' into my-develop 2020-03-03 11:30:13 +00:00
Jim Hague 3073d33560 Update stubby. 2020-03-02 18:13:47 +00:00
Willem Toorop af46e20721 Fix reporting authentication failure 2020-03-02 15:51:46 +00:00
Willem Toorop e17ed3938c Fix: mem leak with gnutls 2020-03-02 15:12:18 +00:00
Willem Toorop 1067326bd0 Merge branch 'develop' of github.com:getdnsapi/getdns into develop 2020-03-02 15:31:28 +01:00
Willem Toorop f05c0ad754 Testing GNUTLS DoT tests 2020-03-02 15:30:58 +01:00
Willem Toorop 16c20fe04d
Merge pull request #462 from doublez13/develop
Fix uninitialized value in tls_create_object
2020-03-02 15:20:51 +01:00
Willem Toorop f73bf0dfa5 Dependencies for travis (+ testing...) 2020-03-02 15:17:03 +01:00
Willem Toorop 3b5d1a9353 Stub only links with GNUTLS
And valgrind check includes DoT session
2020-03-02 15:12:33 +01:00
Willem Toorop f3a38e9a40 Sync tools shared with unbound 2020-03-02 15:11:58 +01:00
Jim Hague 5721c501c3 Point stubby at my repo. 2020-03-02 13:41:12 +00:00
Zane Zakraisek b804b8effb Fix uninitialized value in tls_create_object
On the first call to tls_create_object (stub.c), tls_fallback_ok is read
before being initialized. This patch initializes tls_fallback_ok to 0 in
upsteam_init (context.c)

Valgrind complains about the uninitialized value:
==14774== Conditional jump or move depends on uninitialised value(s)
==14774==    at 0x1528C3: tls_create_object (stub.c:900)
==14774==    by 0x1556AD: upstream_connect (stub.c:2065)
==14774==    by 0x15582E: upstream_find_for_transport (stub.c:2109)
==14774==    by 0x1558B7: upstream_find_for_netreq (stub.c:2130)
==14774==    by 0x156027: _getdns_submit_stub_request (stub.c:2296)
==14774==    by 0x1421C8: _getdns_submit_netreq (general.c:478)
==14774==    by 0x14261D: getdns_general_ns (general.c:636)
==14774==    by 0x142905: _getdns_general_loop (general.c:731)
==14774==    by 0x1432FB: getdns_general (general.c:888)
==14774==    by 0x118B94: incoming_request_handler (stubby.c:692)
==14774==    by 0x14F46B: udp_read_cb (server.c:762)
==14774==    by 0x15C86B: poll_read_cb (poll_eventloop.c:295)
==14774==  Uninitialised value was created by a heap allocation
==14774==    at 0x483877F: malloc (vg_replace_malloc.c:309)
==14774==    by 0x123CCF: upstreams_create (context.c:581)
==14774==    by 0x128B24: getdns_context_set_upstream_recursive_servers (context.c:2760)
==14774==    by 0x12DBFE: _getdns_context_config_setting (context.c:4646)
==14774==    by 0x12FF47: getdns_context_config (context.c:4769)
==14774==    by 0x1178C2: parse_config (stubby.c:297)
==14774==    by 0x117B24: parse_config_file (stubby.c:343)
==14774==    by 0x11919F: main (stubby.c:833)
2020-03-01 14:13:27 -07:00
Willem Toorop fe30672afa shorten code with string conversion functions 2020-02-28 20:33:22 +01:00
Willem Toorop e19e6bd464 getdns-1.6.0 release
-----BEGIN PGP SIGNATURE-----
 
 iQJIBAABCgAyFiEE3DTuXbJBe8wVHlEA5fj4IS93pJgFAl5ZKkAUHHdpbGxlbUBu
 bG5ldGxhYnMubmwACgkQ5fj4IS93pJjVeA/+MIMCZm0pSET6kAIauItpeA506/2a
 U6Us1mQRKFu3kAq655CiCC2amXH+oPZg8ESKBqFn4AbbzSiWMcHEQh91v6vHGYe9
 0V1CciUUScFW2PlodKg/Ulxy+COmrmonkz4X/NbepsikYXUu4xmVL+FgfGw1xvAu
 mxLMWW3oZi7Rgr3zAixgNLE3t7KgjVVRXBNVDb9on3IyydAkgssUJQHAsupJJQy+
 CCPrqpj4s3nLGSACVkCQPJIYewYKAnvTwLSy2+9mOP8clIgmVonoeEaYwM5x0RU/
 boeqXR7A6iA6CvReeG/vQa/MVcVIIY/p7FSYZwtxrHef8cPXG9H8GVKy9s+xlNEO
 7tEG6uhwGq52i9zDfVi36TXwWe/FW9ER5cytmlhcMOIkMnH6KHn3iZrx6mVhInob
 93cwl+vVGd/MSt7JnDwsvRI1uUsdSapbqK58c/aCrC9aag9YWhwnGPMByqfyXJUf
 5Yv43/AI9wI0UY2BPzvtZbtfwL+30VotZLUJRmoBtmKJQ6XQ98LG3NPeq83v5Wzd
 DxRcCqLNwEBh0qADtdfEd07H+Hf5F7GT6xqJo+IWrTaZ+naZNMsVajGJtSpCthCq
 k02naEtEMegc9C+fsrbFfQeuvvBPnFgUJKFVQJH6UrMG278tkEklmHmJwnZKtSFY
 ZhNgm/04AG1hcdU=
 =pOTk
 -----END PGP SIGNATURE-----

Merge tag 'v1.6.0'

getdns-1.6.0 release
2020-02-28 16:03:59 +01:00
Willem Toorop 1b3f570792 Bump version for release 2020-02-28 15:39:53 +01:00
Willem Toorop 328903cb52
Merge pull request #459 from banburybill/release/1.6.0-rc.1
Tighten Nettle version checking, and fix build issue with Nettle >= 3.4.
2020-02-25 14:36:44 +01:00
Jim Hague ab49db8aa5 Tighten Nettle version checking, and fix build issue with Nettle >= 3.4.
Nettle 3.4 introduced accessor functions for obtaining nettle_secp_256r1 and nettle_secp_384r1. Use them if present.

Fixes #458
2020-02-25 13:30:25 +00:00
Willem Toorop f9db16a65e Merge branch 'develop' 2019-04-03 16:19:31 +02:00
Willem Toorop 67b7a8c024 Release 1.5.1
-----BEGIN PGP SIGNATURE-----
 
 iQJIBAABCgAyFiEE3DTuXbJBe8wVHlEA5fj4IS93pJgFAlw4tmgUHHdpbGxlbUBu
 bG5ldGxhYnMubmwACgkQ5fj4IS93pJi/vQ/8DPP6FoYLSBsDVgO+qU7KYzlFdSaX
 UNbLGxrmss2YSpN6BHkQN8FOpHMxJl2kxSNI0cJjFrpIG5OSevR+dj22JafDl10J
 +yrjeS8KI2JtEFEYWbmCT5u+EzYV6pZosiJhbg8mfAAby/hQcU+fTVjnsXYzI6WW
 8u9AhV0tSrdJaV7a9ng92FudgLiuh+9CDjMRcAOSpBTsLsd201e4A1VnGEIgOJVD
 v2bqde98WGaKcWq4b4WhUoNXd4L6IPw8GTLvl/taRB+Mio3zSDPEA2eKQOUH3n44
 Ork+yu4uiaPXJ/o8920bQ0FFs827M6crXrb7GmtjR1BKrNZtxCj0VW89d4thcVSG
 7Vjn2yFzZrXI9Z3QrVyGAltI5PyUbky+z2OJIpqWE2BjRPq9uqVcl9bDkGqYfIXm
 29oNjBg/nFObx0ev9IFcae07uf9k3Vc3UbTqFnKN53YipkCPcp2FT+YYXN8qHlrV
 Hmj1HXVfh0IsmSjb67d5UU1kt7HQmEYq+7DKPLohUJ5ITkxNF10DFgZW1QzqZA4G
 XbxQz2IbcVKZ4aQWBkzKuLK2V7kDmclLMrSTqk13/l8u9WhJ05s52bXB/rR5FWxQ
 ze4msZP66gfKwVkp44IYkEQrHpqnJwvAk4ASBBH0Uob/Dm5qvCkWd+2VPZgtMMaQ
 RYz3of1NZsliGbg=
 =Nj+6
 -----END PGP SIGNATURE-----

Merge tag 'v1.5.1'

Release 1.5.1
2019-01-11 16:31:45 +01:00
Willem Toorop 215d553c0b Merge branch 'release/1.5.0' 2018-12-21 17:22:17 +01:00
99 changed files with 3653 additions and 1326 deletions

4
.gitmodules vendored
View File

@ -12,5 +12,5 @@
branch = develop
[submodule "src/ssl_dane"]
path = src/ssl_dane
url = https://github.com/banburybill/ssl_dane
branch = feature/windows-native-build
url = https://github.com/getdnsapi/ssl_dane
branch = getdns

View File

@ -19,8 +19,9 @@ addons:
- clang
- wget
- openssh-client
- libgnutls28-dev
script:
- mkdir tests
- cd tests
- ../src/test/tpkg/run-all.sh
# - ../src/test/tpkg/run-one.sh 275-server-capabilities.tpkg -V
# - ../src/test/tpkg/run-one.sh 290-transports.tpkg -V

View File

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
cmake_minimum_required(VERSION 3.20 FATAL_ERROR)
if (POLICY CMP0075)
cmake_policy(SET CMP0075 NEW)
@ -6,34 +6,73 @@ endif ()
# The following must be set BEFORE doing project() or enable_language().
if (NOT CMAKE_BUILD_TYPE)
message(STATUS "No build type defined; defaulting to 'Debug'")
set(CMAKE_BUILD_TYPE "Debug" CACHE STRING
message(STATUS "No build type defined; defaulting to 'RelWithDebInfo'")
set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING
"The type of build. Possible values are: Debug, Release, RelWithDebInfo and MinSizeRel.")
endif ()
set(PACKAGE "getdns")
set(PACKAGE_NAME "getdns")
set(PACKAGE_VERSION "1.6.0")
set(PACKAGE_VERSION "1.7.3")
set(PACKAGE_BUGREPORT "team@getdnsapi.net")
set(PACKAGE_URL "https://getdnsapi.net")
# Dont forget to put a dash in front of the release candidate!!!
# That is how it is done with semantic versioning!
set(RELEASE_CANDIDATE "-rc.1")
set(RELEASE_CANDIDATE "")
set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}${RELEASE_CANDIDATE}")
set(PACKAGE_TARNAME "${PACKAGE}-${PACKAGE_VERSION}${RELEASE_CANDIDATE}")
set(GETDNS_VERSION "${PACKAGE_VERSION}${RELEASE_CANDIDATE}")
set(GETDNS_NUMERIC_VERSION 0x0105ffd1)
set(GETDNS_NUMERIC_VERSION 0x01070200)
set(API_VERSION "December 2015")
set(API_NUMERIC_VERSION 0x07df0c00)
# Version 11:2:1 in libtool-speak.
set(GETDNS_VERSION_CURRENT 11)
set(GETDNS_VERSION_REVISION 3)
set(GETDNS_VERSION_AGE 1)
# Library version
# ---------------
# current:revision:age
# (binary-api-number):(which-binary-api-version):(how-many-nrs-backwardscompat)
# if source code changes increment revision
# if any interfaces have been added/removed/changed since last update then
# increment current and set revision to 0
# if any interfaces have been added since the last public release then increment age
# if any interfaces have been removed or changed since the last public release then
# set age to 0
#
# getdns-0.1.4 had libversion 0:0:0
# getdns-0.1.5 had libversion 1:0:0
# getdns-0.1.6 had libversion 1:1:0
# getdns-0.1.7 had libversion 1:2:1 (but should have had 2:0:1)
# getdns-0.1.8 had libversion 1:3:0 (but should have had 2:1:1)
# getdns-0.2.0 had libversion 2:2:1
# getdns-0.3.0 had libversion 3:3:2
# getdns-0.3.1 had libversion 3:4:2
# getdns-0.3.2 had libversion 3:5:2
# getdns-0.3.3 had libversion 3:6:2
# getdns-0.5.0 had libversion 4:0:3
# getdns-0.5.1 had libversion 4:1:3 (but should have been getdns-0.6.0)
# getdns-0.9.0 had libversion 5:0:4
# getdns-1.0.0 had libversion 5:1:4
# getdns-1.1.0 had libversion 6:0:0
# getdns-1.1.1 had libversion 6:1:0
# getdns-1.1.2 had libversion 7:0:1
# getdns-1.1.3 had libversion 7:1:1
# getdns-1.2.0 had libversion 8:0:2
# getdns-1.2.1 had libversion 8:1:2
# getdns-1.3.0 had libversion 9:0:3
# getdns-1.4.0 had libversion 10:0:0
# getdns-1.4.1 had libversion 10:1:0
# getdns-1.4.2 had libversion 10:2:0
# getdns-1.5.0 had libversion 11:0:1
# getdns-1.5.1 had libversion 11:1:1
# getdns-1.5.2 had libversion 11:2:1
# getdns-1.6.0 had libversion 11:3:1
# getdns-1.7.0 has libversion 12:0:2
set(GETDNS_VERSION_CURRENT 12)
set(GETDNS_VERSION_REVISION 0)
set(GETDNS_VERSION_AGE 2)
project(getdns VERSION ${PACKAGE_VERSION} LANGUAGES C)
@ -64,7 +103,7 @@ elseif (APPLE)
elseif (UNIX)
set(HOSTOS "unix")
if (NOT ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
if (NOT ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD" AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_POSIX_C_SOURCE=200112L -D_XOPEN_SOURCE=600")
endif ()
if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
@ -128,6 +167,8 @@ option(BUILD_LIBUV "Build libuv support library available." ON)
option(USE_LIBIDN2 "Use libidn2 if available." ON)
option(USE_GNUTLS "Use GnuTLS for TLS connections." OFF)
option(FORCE_COMPAT_STRPTIME "Force use of internal strptime when cross-compiling." OFF)
# Above names chosen for user consistency. Now define substituted names.
set(REQ_DEBUG ${ENABLE_DEBUG_REQ})
set(SCHED_DEBUG ${ENABLE_DEBUG_SCHED})
@ -221,6 +262,7 @@ check_include_file(inttypes.h HAVE_INTTYPES_H)
check_include_file(limits.h HAVE_LIMITS_H)
check_include_file(sys/limits.h HAVE_SYS_LIMITS_H)
check_include_file(stdarg.h HAVE_STDARG_H)
check_include_file(stddef.h HAVE_STDDEF_H)
check_include_file(stdint.h HAVE_STDINT_H)
check_include_file(stdio.h HAVE_STDIO_H)
check_include_file(stdlib.h HAVE_STDLIB_H)
@ -296,8 +338,12 @@ check_include_file(openssl/err.h HAVE_OPENSSL_ERR_H)
check_include_file(openssl/rand.h HAVE_OPENSSL_RAND_H)
check_include_file(openssl/conf.h HAVE_OPENSSL_CONF_H)
check_include_file(openssl/engine.h HAVE_OPENSSL_ENGINE_H)
check_include_file(openssl/bn.h HAVE_OPENSSL_BN_H)
check_include_file(openssl/dsa.h HAVE_OPENSSL_DSA_H)
check_include_file(openssl/rsa.h HAVE_OPENSSL_RSA_H)
check_include_file(openssl/param_build.h HAVE_OPENSSL_PARAM_BUILD_H)
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_LIBRARIES})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_LIBRARIES} ${getdns_system_libs})
check_function_exists(DSA_SIG_set0 HAVE_DSA_SIG_SET0)
check_function_exists(DSA_set0_pqg HAVE_DSA_SET0_PQG)
check_function_exists(DSA_set0_key HAVE_DSA_SET0_KEY)
@ -328,6 +374,8 @@ check_function_exists(SSL_set_ciphersuites HAVE_SSL_SET_CIPHERSUITES)
check_function_exists(OPENSSL_init_crypto HAVE_OPENSSL_INIT_CRYPTO)
check_function_exists(OSSL_PARAM_BLD_new HAVE_OSSL_PARAM_BLD_NEW)
check_symbol_exists(SSL_dane_enable "openssl/ssl.h" HAVE_SSL_DANE_ENABLE)
check_symbol_exists(SSL_CTX_set1_curves_list "openssl/ssl.h" HAVE_DECL_SSL_CTX_SET1_CURVES_LIST)
check_symbol_exists(SSL_set1_curves_list "openssl/ssl.h" HAVE_DECL_SSL_SET1_CURVES_LIST)
@ -365,14 +413,19 @@ endif()
# handle digital signature algorithms. GnuTLS uses Nettle internally.
if (USE_GNUTLS)
find_package(GnuTLS "3.5.0" REQUIRED)
find_package(Nettle REQUIRED)
find_package(Nettle "3.2" REQUIRED)
set(tlsdir "gnutls")
set(HAVE_NETTLE 1)
set(CMAKE_REQUIRED_INCLUDES ${NETTLE_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${NETTLE_LIBRARIES})
check_include_file(nettle/dsa-compat.h HAVE_NETTLE_DSA_COMPAT_H)
check_include_file(nettle/eddsa.h HAVE_NETTLE_EDDSA_H)
# API change in Nettle 3.4.
check_symbol_exists(nettle_get_secp_256r1 "nettle/ecc-curve.h" HAVE_NETTLE_GET_SECP_256R1)
check_symbol_exists(nettle_get_secp_384r1 "nettle/ecc-curve.h" HAVE_NETTLE_GET_SECP_384R1)
endif()
# Sort out what signature algorithms can be used.
@ -390,7 +443,7 @@ endif ()
if (USE_ED448)
if (USE_GNUTLS)
message(WARNING "ED448 enabled and Nettle does not support it. Disabled.")
message(WARNING "ED448 enabled and Nettle support not implemented. Disabled.")
unset(USE_ED448)
elseif (NOT HAVE_SSL_ED448)
message(WARNING "ED448 enabled and OpenSSL does not support it. Disabled.")
@ -446,9 +499,19 @@ if (NOT ENABLE_STUB_ONLY)
set(CMAKE_REQUIRED_INCLUDES ${LIBUNBOUND_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${LIBUNBOUND_LIBRARIES})
check_symbol_exists(ub_ctx_set_stub "unbound.h" HAVE_UB_CTX_SET_STUB)
if (ENABLE_UNBOUND_EVENT_API)
check_include_file(unbound-event.h HAVE_UNBOUND_EVENT_H)
check_symbol_exists(ub_ctx_create_ub_event "unbound-event.h" HAVE_UNBOUND_EVENT_API)
check_symbol_exists(ub_ctx_set_stub "unbound-event.h" HAVE_UB_CTX_SET_STUB)
endif ()
else ()
# Ensure we're not using libunbound items.
set(HAVE_LIBUNBOUND 0)
set(HAVE_UNBOUND_EVENT_H 0)
set(HAVE_UNBOUND_EVENT_API 0)
set(HAVE_UB_CTX_SET_STUB 0)
endif ()
# Event loop extension
@ -478,8 +541,15 @@ set(STRPTIME_TEST_SOURCE "\n
if (!res) return 1; return 0; }")
if (HAVE_STRPTIME)
if (CMAKE_CROSSCOMPILING)
if (NOT FORCE_COMPAT_STRPTIME)
message(WARNING "Assuming strptime() is POSIX compliant with %t matching any white space. Specify FORCE_COMPAT_STRPTIME on non-compliant platforms e.g. BSD derived.")
set(STRPTIME_WORKS 1)
endif ()
else ()
check_c_source_runs("${STRPTIME_TEST_SOURCE}" STRPTIME_WORKS)
endif ()
endif ()
try_compile(HAVE___FUNC__
${CMAKE_CURRENT_BINARY_DIR}
@ -506,6 +576,8 @@ else ()
endif ()
endif ()
check_symbol_exists(TCP_USER_TIMEOUT "sys/socket.h;netinet/tcp.h" HAVE_DECL_TCP_USER_TIMEOUT)
# Main library
add_library(getdns_objects OBJECT
src/anchor.c
@ -616,9 +688,6 @@ if (NOT HAVE_SSL_DANE_ENABLE)
target_include_directories(getdns_objects PRIVATE src/ssl_dane)
set(USE_DANESSL 1)
endif ()
if (Libidn_FOUND)
target_include_directories(getdns_objects PRIVATE ${LIBIDN_INCLUDE_DIR})
endif ()
if (Libidn2_FOUND)
target_include_directories(getdns_objects PRIVATE ${LIBIDN2_INCLUDE_DIR})
endif ()
@ -652,9 +721,6 @@ if (ENABLE_STATIC)
if (Libunbound_FOUND)
target_link_libraries(getdns PUBLIC Libunbound::Libunbound)
endif ()
if (Libidn_FOUND)
target_link_libraries(getdns PUBLIC Libidn::Libidn)
endif ()
if (Libidn2_FOUND)
target_link_libraries(getdns PUBLIC Libidn2::Libidn2)
endif ()
@ -684,9 +750,6 @@ if (ENABLE_SHARED)
if (Libunbound_FOUND)
target_link_libraries(getdns_shared PUBLIC Libunbound::Libunbound)
endif ()
if (Libidn_FOUND)
target_link_libraries(getdns_shared PUBLIC Libidn::Libidn)
endif ()
if (Libidn2_FOUND)
target_link_libraries(getdns_shared PUBLIC Libidn2::Libidn2)
endif ()
@ -727,27 +790,27 @@ if (USE_LIBEV)
set_property(TARGET ev_objects PROPERTY POSITION_INDEPENDENT_CODE 1)
set_property(TARGET ev_objects PROPERTY C_STANDARD 11)
if (ENABLE_STATIC)
add_library(getdns_ex_ev STATIC $<TARGET_OBJECTS:ev_objects>)
target_include_directories(getdns_ex_ev PRIVATE Libev::Libev)
target_link_libraries(getdns_ex_ev PUBLIC getdns Libev::Libev)
add_library(getdns_ext_ev STATIC $<TARGET_OBJECTS:ev_objects>)
target_include_directories(getdns_ext_ev PRIVATE Libev::Libev)
target_link_libraries(getdns_ext_ev PUBLIC getdns Libev::Libev)
if (Libunbound_FOUND)
target_link_libraries(getdns_ex_ev PUBLIC Libunbound::Libunbound)
target_link_libraries(getdns_ext_ev PUBLIC Libunbound::Libunbound)
endif ()
set_target_properties(getdns_ex_ev PROPERTIES OUTPUT_NAME getdns_ex_ev${static_lib_suffix})
set_target_properties(getdns_ext_ev PROPERTIES OUTPUT_NAME getdns_ext_ev${static_lib_suffix})
endif ()
if (ENABLE_SHARED)
add_library(getdns_ex_ev_shared SHARED $<TARGET_OBJECTS:ev_objects>)
target_include_directories(getdns_ex_ev_shared PRIVATE Libev::Libev)
target_link_libraries(getdns_ex_ev_shared PUBLIC getdns_shared Libev::Libev)
add_library(getdns_ext_ev_shared SHARED $<TARGET_OBJECTS:ev_objects>)
target_include_directories(getdns_ext_ev_shared PRIVATE Libev::Libev)
target_link_libraries(getdns_ext_ev_shared PUBLIC getdns_shared Libev::Libev)
if (Libunbound_FOUND)
target_link_libraries(getdns_ex_ev_shared PUBLIC Libunbound::Libunbound)
target_link_libraries(getdns_ext_ev_shared PUBLIC Libunbound::Libunbound)
endif ()
set_target_properties(getdns_ex_ev_shared PROPERTIES OUTPUT_NAME getdns_ex_ev)
target_shared_library_version(getdns_ex_ev_shared ${GETDNS_VERSION_CURRENT} ${GETDNS_VERSION_REVISION} ${GETDNS_VERSION_AGE})
set_target_properties(getdns_ext_ev_shared PROPERTIES OUTPUT_NAME getdns_ext_ev)
target_shared_library_version(getdns_ext_ev_shared ${GETDNS_VERSION_CURRENT} ${GETDNS_VERSION_REVISION} ${GETDNS_VERSION_AGE})
file(STRINGS src/extension/libev.symbols symbols)
target_shared_library_exports(getdns_ex_ev_shared getdns_ex_ev "${symbols}")
target_shared_library_exports(getdns_ext_ev_shared getdns_ext_ev "${symbols}")
if (NOT ENABLE_STATIC)
add_library(getdns_ex_ev ALIAS getdns_ex_ev_shared)
add_library(getdns_ext_ev ALIAS getdns_ext_ev_shared)
endif ()
endif ()
else ()
@ -778,27 +841,27 @@ if (USE_LIBEVENT2)
set_property(TARGET event2_objects PROPERTY POSITION_INDEPENDENT_CODE 1)
set_property(TARGET event2_objects PROPERTY C_STANDARD 11)
if (ENABLE_STATIC)
add_library(getdns_ex_event STATIC $<TARGET_OBJECTS:event2_objects>)
target_include_directories(getdns_ex_event PRIVATE Libevent2::Libevent_code)
target_link_libraries(getdns_ex_event PUBLIC getdns Libevent2::Libevent_core)
add_library(getdns_ext_event STATIC $<TARGET_OBJECTS:event2_objects>)
target_include_directories(getdns_ext_event PRIVATE Libevent2::Libevent_code)
target_link_libraries(getdns_ext_event PUBLIC getdns Libevent2::Libevent_core)
if (Libunbound_FOUND)
target_link_libraries(getdns_ex_event PUBLIC Libunbound::Libunbound)
target_link_libraries(getdns_ext_event PUBLIC Libunbound::Libunbound)
endif ()
set_target_properties(getdns_ex_event PROPERTIES OUTPUT_NAME getdns_ex_event${static_lib_suffix})
set_target_properties(getdns_ext_event PROPERTIES OUTPUT_NAME getdns_ext_event${static_lib_suffix})
endif ()
if (ENABLE_SHARED)
add_library(getdns_ex_event_shared SHARED $<TARGET_OBJECTS:event2_objects>)
target_include_directories(getdns_ex_event_shared PRIVATE Libevent2::Libevent_code)
target_link_libraries(getdns_ex_event_shared PUBLIC getdns_shared Libevent2::Libevent_core)
add_library(getdns_ext_event_shared SHARED $<TARGET_OBJECTS:event2_objects>)
target_include_directories(getdns_ext_event_shared PRIVATE Libevent2::Libevent_code)
target_link_libraries(getdns_ext_event_shared PUBLIC getdns_shared Libevent2::Libevent_core)
if (Libunbound_FOUND)
target_link_libraries(getdns_ex_event_shared PUBLIC Libunbound::Libunbound)
target_link_libraries(getdns_ext_event_shared PUBLIC Libunbound::Libunbound)
endif ()
set_target_properties(getdns_ex_event_shared PROPERTIES OUTPUT_NAME getdns_ex_event)
target_shared_library_version(getdns_ex_event_shared ${GETDNS_VERSION_CURRENT} ${GETDNS_VERSION_REVISION} ${GETDNS_VERSION_AGE})
set_target_properties(getdns_ext_event_shared PROPERTIES OUTPUT_NAME getdns_ext_event)
target_shared_library_version(getdns_ext_event_shared ${GETDNS_VERSION_CURRENT} ${GETDNS_VERSION_REVISION} ${GETDNS_VERSION_AGE})
file(STRINGS src/extension/libevent.symbols symbols)
target_shared_library_exports(getdns_ex_event_shared getdns_ex_event "${symbols}")
target_shared_library_exports(getdns_ext_event_shared getdns_ext_event "${symbols}")
if (NOT ENABLE_STATIC)
add_library(getdns_ex_event ALIAS getdns_ex_event_shared)
add_library(getdns_ext_event ALIAS getdns_ext_event_shared)
endif ()
endif ()
else ()
@ -830,27 +893,27 @@ if (USE_LIBUV)
set_property(TARGET uv_objects PROPERTY POSITION_INDEPENDENT_CODE 1)
set_property(TARGET uv_objects PROPERTY C_STANDARD 11)
if (ENABLE_STATIC)
add_library(getdns_ex_uv STATIC $<TARGET_OBJECTS:uv_objects>)
target_include_directories(getdns_ex_uv PRIVATE Libuv::Libuv)
target_link_libraries(getdns_ex_uv PUBLIC getdns Libuv::Libuv)
add_library(getdns_ext_uv STATIC $<TARGET_OBJECTS:uv_objects>)
target_include_directories(getdns_ext_uv PRIVATE Libuv::Libuv)
target_link_libraries(getdns_ext_uv PUBLIC getdns Libuv::Libuv)
if (Libunbound_FOUND)
target_link_libraries(getdns_ex_uv PUBLIC Libunbound::Libunbound)
target_link_libraries(getdns_ext_uv PUBLIC Libunbound::Libunbound)
endif ()
set_target_properties(getdns_ex_uv PROPERTIES OUTPUT_NAME getdns_ex_uv${static_lib_suffix})
set_target_properties(getdns_ext_uv PROPERTIES OUTPUT_NAME getdns_ext_uv${static_lib_suffix})
endif ()
if (ENABLE_SHARED)
add_library(getdns_ex_uv_shared SHARED $<TARGET_OBJECTS:uv_objects>)
target_include_directories(getdns_ex_uv_shared PRIVATE Libuv::Libuv)
target_link_libraries(getdns_ex_uv_shared PUBLIC getdns_shared Libuv::Libuv)
add_library(getdns_ext_uv_shared SHARED $<TARGET_OBJECTS:uv_objects>)
target_include_directories(getdns_ext_uv_shared PRIVATE Libuv::Libuv)
target_link_libraries(getdns_ext_uv_shared PUBLIC getdns_shared Libuv::Libuv)
if (Libunbound_FOUND)
target_link_libraries(getdns_ex_uv_shared PUBLIC Libunbound::Libunbound)
target_link_libraries(getdns_ext_uv_shared PUBLIC Libunbound::Libunbound)
endif ()
set_target_properties(getdns_ex_uv_shared PROPERTIES OUTPUT_NAME getdns_ex_uv)
target_shared_library_version(getdns_ex_uv_shared ${GETDNS_VERSION_CURRENT} ${GETDNS_VERSION_REVISION} ${GETDNS_VERSION_AGE})
set_target_properties(getdns_ext_uv_shared PROPERTIES OUTPUT_NAME getdns_ext_uv)
target_shared_library_version(getdns_ext_uv_shared ${GETDNS_VERSION_CURRENT} ${GETDNS_VERSION_REVISION} ${GETDNS_VERSION_AGE})
file(STRINGS src/extension/libuv.symbols symbols)
target_shared_library_exports(getdns_ex_uv_shared getdns_ex_uv "${symbols}")
target_shared_library_exports(getdns_ext_uv_shared getdns_ext_uv "${symbols}")
if (NOT ENABLE_STATIC)
add_library(getdns_ex_uv ALIAS getdns_ex_uv_shared)
add_library(getdns_ext_uv ALIAS getdns_ext_uv_shared)
endif ()
endif ()
else ()
@ -912,7 +975,7 @@ if (BUILD_TESTING)
if (USE_LIBEVENT2)
add_executable(check_getdns_event ${GETDNS_TEST_SOURCE_FILES})
target_link_libraries(check_getdns_event PRIVATE ${GETDNS_TEST_LINK_LIBS} getdns_ex_event)
target_link_libraries(check_getdns_event PRIVATE ${GETDNS_TEST_LINK_LIBS} getdns_ext_event)
add_test(NAME test_libevent COMMAND check_getdns_event)
set_property(TEST test_libevent PROPERTY
ENVIRONMENT "GETDNS_TEST_PORT=44321;CK_TIMEOUT_MULTIPLIER=2;CK_LOG_FILE_NAME=check_getdns_event.log"
@ -921,7 +984,7 @@ if (BUILD_TESTING)
if (USE_LIBEV)
add_executable(check_getdns_ev ${GETDNS_TEST_SOURCE_FILES})
target_link_libraries(check_getdns_ev PRIVATE ${GETDNS_TEST_LINK_LIBS} getdns_ex_ev)
target_link_libraries(check_getdns_ev PRIVATE ${GETDNS_TEST_LINK_LIBS} getdns_ext_ev)
add_test(NAME test_libev COMMAND check_getdns_ev)
set_property(TEST test_libev PROPERTY
ENVIRONMENT "GETDNS_TEST_PORT=45321;CK_TIMEOUT_MULTIPLIER=2;CK_LOG_FILE_NAME=check_getdns_ev.log"
@ -930,7 +993,7 @@ if (BUILD_TESTING)
if (USE_LIBUV)
add_executable(check_getdns_uv ${GETDNS_TEST_SOURCE_FILES})
target_link_libraries(check_getdns_uv PRIVATE ${GETDNS_TEST_LINK_LIBS} getdns_ex_uv)
target_link_libraries(check_getdns_uv PRIVATE ${GETDNS_TEST_LINK_LIBS} getdns_ext_uv)
add_test(NAME test_libuv COMMAND check_getdns_uv)
set_property(TEST test_libuv PROPERTY
ENVIRONMENT "GETDNS_TEST_PORT=46321;CK_TIMEOUT_MULTIPLIER=2;CK_LOG_FILE_NAME=check_getdns_uv.log"
@ -964,6 +1027,8 @@ if (BUILD_TESTING)
endif ()
# Substitutions in files.
string(TOUPPER "${CMAKE_BUILD_TYPE}" GETDNS_BUILD_RELTYPE)
string(REPLACE "\"" "\\\"" GETDNS_BUILD_CFLAGS "${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_${GETDNS_BUILD_RELTYPE}}")
configure_file(cmake/include/cmakeconfig.h.in config.h)
configure_file(src/getdns/getdns.h.in getdns/getdns.h)
configure_file(src/getdns/getdns_extra.h.in getdns/getdns_extra.h)
@ -996,47 +1061,48 @@ foreach (man ${mans})
endforeach()
set(prefix ${CMAKE_INSTALL_PREFIX})
cmake_path(APPEND libdir_for_pc_file "\${prefix}" "${CMAKE_INSTALL_LIBDIR}")
cmake_path(APPEND includedir_for_pc_file "\${prefix}" "${CMAKE_INSTALL_INCLUDEDIR}")
configure_file(getdns.pc.in getdns.pc @ONLY)
# Installing.
if (ENABLE_STATIC)
install(TARGETS getdns LIBRARY DESTINATION lib ARCHIVE DESTINATION lib)
install(TARGETS getdns LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
if (USE_LIBEV)
install(TARGETS getdns_ex_ev LIBRARY DESTINATION lib ARCHIVE DESTINATION lib)
install(TARGETS getdns_ext_ev LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif ()
if (USE_LIBEVENT2)
install(TARGETS getdns_ex_event LIBRARY DESTINATION lib ARCHIVE DESTINATION lib)
install(TARGETS getdns_ext_event LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif ()
if (USE_LIBUV)
install(TARGETS getdns_ex_uv LIBRARY DESTINATION lib ARCHIVE DESTINATION lib)
install(TARGETS getdns_ext_uv LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif ()
endif ()
if (ENABLE_SHARED)
install(TARGETS getdns_shared LIBRARY DESTINATION lib ARCHIVE DESTINATION lib)
install(TARGETS getdns_shared LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
if (USE_LIBEV)
install(TARGETS getdns_ex_ev_shared LIBRARY DESTINATION lib ARCHIVE DESTINATION lib)
install(TARGETS getdns_ext_ev_shared LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
endif ()
if (USE_LIBEVENT2)
install(TARGETS getdns_ex_event_shared LIBRARY DESTINATION lib ARCHIVE DESTINATION lib)
install(TARGETS getdns_ext_event_shared LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
endif ()
if (USE_LIBUV)
install(TARGETS getdns_ex_uv_shared LIBRARY DESTINATION lib ARCHIVE DESTINATION lib)
install(TARGETS getdns_ext_uv_shared LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
endif ()
endif ()
if (BUILD_GETDNS_QUERY)
install(TARGETS getdns_query RUNTIME DESTINATION bin)
install(TARGETS getdns_query RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
endif ()
if (BUILD_GETDNS_SERVER_MON)
install(TARGETS getdns_server_mon RUNTIME DESTINATION bin)
install(TARGETS getdns_server_mon RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
endif ()
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/getdns DESTINATION include)
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/man3 DESTINATION share/man)
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/getdns DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/man3 DESTINATION ${CMAKE_INSTALL_MANDIR})
set(docdir share/doc/getdns)
install(FILES AUTHORS ChangeLog COPYING LICENSE NEWS README.md DESTINATION ${docdir})
install(FILES spec/index.html DESTINATION ${docdir}/spec)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/getdns.pc DESTINATION lib/pkgconfig)
install(FILES AUTHORS ChangeLog COPYING LICENSE NEWS README.md DESTINATION ${CMAKE_INSTALL_DOCDIR})
install(FILES spec/index.html DESTINATION ${CMAKE_INSTALL_DOCDIR}/spec)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/getdns.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
install(CODE "message(\"\
***\n\
@ -1080,17 +1146,17 @@ if (BUILD_EXAMPLES)
if (USE_LIBEVENT2)
add_executable(example-simple-answers spec/example/example-simple-answers.c)
target_include_directories(example-simple-answers PRIVATE spec/example)
target_link_libraries(example-simple-answers PRIVATE getdns getdns_ex_event)
target_link_libraries(example-simple-answers PRIVATE getdns getdns_ext_event)
set_property(TARGET example-simple-answers PROPERTY C_STANDARD 11)
add_executable(example-tree spec/example/example-tree.c)
target_include_directories(example-tree PRIVATE spec/example)
target_link_libraries(example-tree PRIVATE getdns getdns_ex_event)
target_link_libraries(example-tree PRIVATE getdns getdns_ext_event)
set_property(TARGET example-tree PROPERTY C_STANDARD 11)
add_executable(example-reverse spec/example/example-reverse.c)
target_include_directories(example-reverse PRIVATE spec/example)
target_link_libraries(example-reverse PRIVATE getdns getdns_ex_event)
target_link_libraries(example-reverse PRIVATE getdns getdns_ext_event)
set_property(TARGET example-reverse PROPERTY C_STANDARD 11)
else ()
message(WARNING "\

View File

@ -1,4 +1,61 @@
* 2020-02-??: Version 1.6.0
* 2023-??-??: Version 1.7.4
* Issue #536: Broken trust anchor files are silently ignored
Thanks Stéphane Bortzmeyer
* 2022-12-22: Version 1.7.3
* PR #532: Increase CMake required version 3.5 -> 3.20, because we
need cmake_path for Absolute paths in pkg-config (See Issue #517)
Thanks Gabriel Ganne
* Updated to Stubby 0.4.3 quickfix release
* 2022-08-19: Version 1.7.2
* Updated to Stubby 0.4.2 quickfix release
* 2022-08-19: Version 1.7.1
* Always send the `dot` ALPN when using DoT
* Strengthen version determination for Libidn2 during cmake processing
(thanks jpbion).
* Fix for issue in UDP stream selection in case of timeouts.
Thanks Shikha Sharma
* Fix using asterisk in ipstr for any address. Thanks uzlonewolf.
* Issue stubby#295: rdata not correctly written for validation for
certain RR type. Also, set default built type to RelWithDebInfo and
expose CFLAGS via GETDNS_BUILD_CFLAGS define and via
getdns_context_get_api_information()
* Issue #524: Bug fixes from submodules' upstream?
Thanks Johnnyslee
* Issue #517: Allow Absolute path CMAKE_INSTALL_{INCLUDE,LIB}DIR in
pkg-config files. Thanks Alex Shpilkin
* Issue #512: Update README.md to show correct PGP key location.
Thanks Katze Prior.
* 2021-06-04: Version 1.7.0
* Make TLS Handshake timeout max 4/5th of timeout for the query,
just like connection setup timeout was, so fallback transport
have a chance too when TCP connection setup is less well
detectable (as with TCP_FASTOPEN on MacOS).
* Issue #466: Memory leak with retrying queries (for examples
with search paths). Thanks doublez13.
* Issue #480: Handling of strptime when Cross compiling with CMake.
A new option to FORCE_COMPAT_STRPTIME (default disabled) will
(when disabled) make cmake assume the target platform has a POSIX
compatible strptime when cross-compiling.
* Setting of the number of milliseconds send data may remain
unacknowledged by the peer in a TCP connection (when supported
by the OS) with getdns_context_set_tcp_send_timeout()
Thanks maciejsszmigiero.
* Issue #497: Fix typo in CMAKE included files, so Stubby can use
TLS v1.3 with chipersuites options ON. Thanks har-riz.
* Basic name compression on server replied messages. Thanks amialkow!
This alleviates (but might not completely resolve) issues #495 and
#320 .
* Eventloop extensions back to the old names libgetdns_ext_event,
libgetdns_ext_ev and libgetdns_ext_uv.
* Compilation warning fixes. Thanks Andreas!
* 2020-02-28: Version 1.6.0
* Issues #457, #458, #461: New symbols with libnettle >= 3.4.
Thanks hanvinke & kometchtech for testing & reporting.
* Issue #432: answer_ipv4_address and answer_ipv6_address in reply
and response dicts.
* Issue #430: Record and guard UDP max payload size with servers.

View File

@ -48,7 +48,7 @@ Once it is built you should take a look at `spec/example` to see how the library
Download the sources from our [github repo](https://github.com/getdnsapi/getdns)
or from [getdnsapi.net](https://getdnsapi.net) and verify the download using
the checksums (SHA1 or MD5) or using gpg to verify the signature. Our keys are
available from the [pgp keyservers](https://keyserver.pgp.com)
available from the [openpgp keyserver](https://keys.openpgp.org/)
* `willem@nlnetlabs.nl`, key id E5F8F8212F77A498

View File

@ -15,6 +15,7 @@
#cmakedefine HAVE_LIMITS_H 1
#cmakedefine HAVE_SYS_LIMITS_H 1
#cmakedefine HAVE_STDARG_H 1
#cmakedefine HAVE_STDDEF_H 1
#cmakedefine HAVE_STDINT_H 1
#cmakedefine HAVE_STDIO_H 1
#cmakedefine HAVE_STDLIB_H 1
@ -58,6 +59,10 @@
#cmakedefine HAVE_OPENSSL_RAND_H 1
#cmakedefine HAVE_OPENSSL_CONF_H 1
#cmakedefine HAVE_OPENSSL_ENGINE_H 1
#cmakedefine HAVE_OPENSSL_BN_H 1
#cmakedefine HAVE_OPENSSL_DSA_H 1
#cmakedefine HAVE_OPENSSL_RSA_H 1
#cmakedefine HAVE_OPENSSL_PARAM_BUILD_H 1
#cmakedefine HAVE_DSA_SIG_SET0 1
#cmakedefine HAVE_DSA_SET0_PQG 1
@ -79,17 +84,22 @@
#cmakedefine HAVE_HMAC_CTX_NEW 1
#cmakedefine HAVE_NETTLE_GET_SECP_256R1 1
#cmakedefine HAVE_NETTLE_GET_SECP_384R1 1
#cmakedefine HAVE_TLS_CLIENT_METHOD 1
#cmakedefine HAVE_OPENSSL_VERSION_NUM 1
#cmakedefine HAVE_OPENSSL_VERSION 1
#cmakedefine HAVE_SSL_CTX_DANE_ENABLE 1
#cmakedefine HAVE_SSL_CTX_SET_CIPHERSUITS 1
#cmakedefine HAVE_SSL_SET_CIPHERSUITS 1
#cmakedefine HAVE_SSL_CTX_SET_CIPHERSUITES 1
#cmakedefine HAVE_SSL_SET_CIPHERSUITES 1
#cmakedefine HAVE_OPENSSL_INIT_CRYPTO 1
#cmakedefine HAVE_OSSL_PARAM_BLD_NEW 1
#cmakedefine HAVE_SSL_DANE_ENABLE 1
#cmakedefine HAVE_DECL_SSL_CTX_SET1_CURVES_LIST 1
#cmakedefine HAVE_DECL_SSL_SET1_CURVES_LIST 1
@ -208,6 +218,8 @@
#cmakedefine USE_OSX_TCP_FASTOPEN 1
#cmakedefine HAVE_DECL_TCP_USER_TIMEOUT 1
#cmakedefine HAVE_NEW_UV_TIMER_CB 1
#cmakedefine HAVE_TARGET_ENDIANNESS
@ -230,6 +242,10 @@
# define FD_SETSIZE 1024
# endif
#ifdef __cplusplus
extern "C" {
#endif
/* the version of the windows API enabled */
# ifndef WINVER
# define WINVER 0x0600 // 0x0502
@ -296,12 +312,11 @@
#include <string.h>
#endif
#ifdef __cplusplus
extern "C" {
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#if STDC_HEADERS
#include <stdlib.h>
#ifdef HAVE_STDDEF_H
#include <stddef.h>
#endif
@ -444,7 +459,7 @@ static inline int _gldns_custom_vsnprintf(char *str, size_t size, const char *fo
# define ATTR_UNUSED(x) x
#elif defined(__cplusplus)
# define ATTR_UNUSED(x)
#elif defined(HAVE_ATTR_UNUSED)
#elif defined(__GNUC__)
# define ATTR_UNUSED(x) x __attribute__((unused))
#else /* !HAVE_ATTR_UNUSED */
# define ATTR_UNUSED(x) x

View File

@ -28,6 +28,18 @@ This module will set the following variables in your project:
#]=======================================================================]
find_package(PkgConfig QUIET)
if (PKG_CONFIG_FOUND)
pkg_check_modules(PkgCheck IMPORTED_TARGET GLOBAL check)
endif ()
if (PkgCheck_FOUND)
set(CHECK_INCLUDE_DIR ${PkgCheck_INCLUDE_DIRS} CACHE FILEPATH "check include path")
set(CHECK_LIBRARIES ${PkgCheck_LIBRARIES} CACHE STRING "check libraries")
set(CHECK_VERSION ${PkgCheck_VERSION})
add_library(Check::Check ALIAS PkgConfig::PkgCheck)
set(Check_FOUND ON)
else ()
find_path(CHECK_INCLUDE_DIR check.h
HINTS
"${CHECK_DIR}"
@ -50,7 +62,7 @@ if (NOT CHECK_LIBRARY)
)
endif ()
set(CHECK_LIBRARIES "")
set(_CHECK_LIBARIES "")
# Check may need the math, subunit and rt libraries on Unix
if (UNIX)
@ -59,16 +71,18 @@ if (UNIX)
find_library(CHECK_SUBUNIT_LIBRARY subunit)
if (CHECK_MATH_LIBRARY)
list(APPEND CHECK_LIBRARIES "${CHECK_MATH_LIBRARY}")
list(APPEND _CHECK_LIBARIES "${CHECK_MATH_LIBRARY}")
endif ()
if (CHECK_RT_LIBRARY)
list(APPEND CHECK_LIBRARIES "${CHECK_RT_LIBRARY}")
list(APPEND _CHECK_LIBARIES "${CHECK_RT_LIBRARY}")
endif ()
if (CHECK_SUBUNIT_LIBRARY)
list(APPEND CHECK_LIBRARIES "${CHECK_SUBUNIT_LIBRARY}")
list(APPEND _CHECK_LIBARIES "${CHECK_SUBUNIT_LIBRARY}")
endif ()
endif()
set(CHECK_LIBRARIES ${_CHECK_LIBARIES} ${CHECK_LIBRARY} CACHE STRING "check libraries")
if (CHECK_INCLUDE_DIR AND CHECK_LIBRARY)
if (NOT TARGET Check::Check)
add_library(Check::Check UNKNOWN IMPORTED)
@ -94,5 +108,7 @@ find_package_handle_standard_args(Check
VERSION_VAR CHECK_VERSION
)
endif()
mark_as_advanced(CHECK_INCLUDE_DIR CHECK_LIBRARIES CHECK_LIBRARY
CHECK_MATH_LIBRARY CHECK_RT_LIBRARY CHECK_SUBUNIT_LIBRARY)

View File

@ -30,6 +30,20 @@ This module will set the following variables in your project:
#]=======================================================================]
find_package(PkgConfig QUIET)
if (PKG_CONFIG_FOUND)
pkg_check_modules(PkgGnuTLS IMPORTED_TARGET GLOBAL QUIET gnutls)
pkg_check_modules(PkgGnuTLSDane IMPORTED_TARGET GLOBAL QUIET gnutls-dane)
endif ()
if (PkgGnuTLS_FOUND AND PkgGnuTLSDane_FOUND)
set(GNUTLS_INCLUDE_DIR ${PkgGnuTLS_INCLUDE_DIRS} $PkgGnuTLSDane_INCLUDE_DIRS} CACHE FILEPATH "GnuTLS include path")
set(NETTLE_LIBRARIES ${PkgGnuTLS_LIBRARIES} ${PkgGnuTLSDane_LIBRARIES} CACHE STRING "GnuTLS libraries")
set(NETTLE_VERSION ${PkgGnuTLS_VERSION})
add_library(GnuTLS::GnuTLS ALIAS PkgConfig::PkgGnuTLS)
add_library(GnuTLS::Dane ALIAS PkgConfig::PkgGnuTLSDane)
set(GnuTLS_FOUND ON)
else ()
find_path(GNUTLS_INCLUDE_DIR gnutls/gnutls.h
HINTS
"${GNUTLS_DIR}"
@ -48,7 +62,7 @@ find_library(GNUTLS_DANE_LIBRARY NAMES gnutls-dane libgnutls-dane
"${GNUTLS_DIR}/lib"
)
set(GNUTLS_LIBRARIES "")
set(_GNUTLS_LIBRARIES "")
if (GNUTLS_INCLUDE_DIR AND GNUTLS_LIBRARY AND GNUTLS_DANE_LIBRARY)
if (NOT TARGET GnuTLS::GnuTLS)
@ -74,12 +88,14 @@ if (GNUTLS_INCLUDE_DIR AND GNUTLS_LIBRARY AND GNUTLS_DANE_LIBRARY)
endif ()
endif ()
list(APPEND GNUTLS_LIBRARIES "${GNUTLS_LIBRARY}" "${GNUTLS_DANE_LIBRARY}")
list(APPEND _GNUTLS_LIBRARIES "${GNUTLS_LIBRARY}" "${GNUTLS_DANE_LIBRARY}")
set(GNUTLS_LIBRARIES ${_GNUTLS_LIBRARIES} CACHE STRING "GnuTLS libraries")
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(GnuTLS
REQUIRED_VARS GNUTLS_LIBRARIES GNUTLS_INCLUDE_DIR
VERSION_VAR GNUTLS_VERSION
)
endif ()
mark_as_advanced(GNUTLS_INCLUDE_DIR GNUTLS_LIBRARIES GNUTLS_LIBRARY GNUTLS_DANE_LIBRARY)

View File

@ -28,27 +28,37 @@ This module will set the following variables in your project:
#]=======================================================================]
find_package(PkgConfig QUIET)
if (PKG_CONFIG_FOUND)
pkg_check_modules(PkgLibevent IMPORTED_TARGET GLOBAL QUIET libevent>=2)
endif ()
if (PkgLibevent_FOUND)
set(LIBEVENT2_INCLUDE_DIR ${PkgLibevent_INCLUDE_DIRS} CACHE FILEPATH "libevent2 include path")
set(LIBEVENT2_LIBRARIES ${PkgLibevent_LIBRARIES} CACHE STRING "libevent2 libraries")
set(LIBEVENT2_VERSION ${PkgLibevent_VERSION})
add_library(Libevent2::Libevent_core ALIAS PkgConfig::PkgLibevent)
set(Libevent2_FOUND ON)
else ()
find_path(LIBEVENT2_INCLUDE_DIR event2/event.h
HINTS
"${LIBEVENT2_DIR}"
"${LIBEVENT2_DIR}/include"
)
find_library(LIBEVENT2_LIBRARY NAMES event_core libevent_core
find_library(LIBEVENT2_LIBRARIES NAMES event_core libevent_core
HINTS
"${LIBEVENT2_DIR}"
"${LIBEVENT2_DIR}/lib"
)
set(LIBEVENT2_LIBRARIES "")
if (LIBEVENT2_INCLUDE_DIR AND LIBEVENT2_LIBRARY)
if (LIBEVENT2_INCLUDE_DIR AND LIBEVENT2_LIBRARIES)
if (NOT TARGET Libevent2::Libevent_core)
add_library(Libevent2::Libevent_core UNKNOWN IMPORTED)
set_target_properties(Libevent2::Libevent_core PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${LIBEVENT2_INCLUDE_DIR}"
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
IMPORTED_LOCATION "${LIBEVENT2_LIBRARY}"
IMPORTED_LOCATION "${LIBEVENT2_LIBRARIES}"
)
endif ()
@ -58,12 +68,11 @@ if (LIBEVENT2_INCLUDE_DIR AND LIBEVENT2_LIBRARY)
endif ()
endif ()
list(APPEND LIBEVENT2_LIBRARIES "${LIBEVENT2_LIBRARY}")
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Libevent2
REQUIRED_VARS LIBEVENT2_LIBRARIES LIBEVENT2_INCLUDE_DIR
VERSION_VAR LIBEVENT2_VERSION
)
endif ()
mark_as_advanced(LIBEVENT2_INCLUDE_DIR LIBEVENT2_LIBRARIES LIBEVENT2_LIBRARY)
mark_as_advanced(LIBEVENT2_INCLUDE_DIR LIBEVENT2_LIBRARIES)

View File

@ -28,42 +28,50 @@ This module will set the following variables in your project:
#]=======================================================================]
find_package(PkgConfig QUIET)
if (PKG_CONFIG_FOUND)
pkg_check_modules(PkgLibIdn2 IMPORTED_TARGET GLOBAL libidn2)
endif ()
if (PkgLibIdn2_FOUND)
set(LIBIDN2_INCLUDE_DIR ${PkgLibIdn2_INCLUDE_DIRS} CACHE FILEPATH "libidn2 include path")
set(LIBIDN2_LIBRARIES ${PkgLibIdn2_LIBRARIES} CACHE STRING "libidn2 libraries")
set(LIBIDN2_VERSION ${PkgLibIdn2_VERSION})
add_library(Libidn2::Libidn2 ALIAS PkgConfig::PkgLibIdn2)
set(Libidn2_FOUND ON)
else ()
find_path(LIBIDN2_INCLUDE_DIR idn2.h
HINTS
"${LIBIDN2_DIR}"
"${LIBIDN2_DIR}/include"
)
find_library(LIBIDN2_LIBRARY NAMES idn2 libidn2
find_library(LIBIDN2_LIBRARIES NAMES idn2 libidn2
HINTS
"${LIBIDN2_DIR}"
"${LIBIDN2_DIR}/lib"
)
set(LIBIDN2_LIBRARIES "")
if (LIBIDN2_INCLUDE_DIR AND LIBIDN2_LIBRARY)
if (LIBIDN2_INCLUDE_DIR AND LIBIDN2_LIBRARIES)
if (NOT TARGET Libidn2::Libidn2)
add_library(Libidn2::Libidn2 UNKNOWN IMPORTED)
set_target_properties(Libidn2::Libidn2 PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${LIBIDN2_INCLUDE_DIR}"
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
IMPORTED_LOCATION "${LIBIDN2_LIBRARY}"
IMPORTED_LOCATION "${LIBIDN2_LIBRARIES}"
)
endif ()
if (NOT LIBIDN2_VERSION AND LIBIDN2_INCLUDE_DIR AND EXISTS "${LIBIDN2_INCLUDE_DIR}/unbound.h")
file(STRINGS "${LIBIDN2_INCLUDE_DIR}/idn2.h" LIBIDN2_H REGEX "^#define IDN2_VERSION ")
string(REGEX REPLACE "^.*IDN2_VERSION \"([0-9.]+)\".*$" "\\1" LIBIDN2_VERSION "${LIBIDN2_H}")
if (NOT LIBIDN2_VERSION AND LIBIDN2_INCLUDE_DIR AND EXISTS "${LIBIDN2_INCLUDE_DIR}/idn2.h")
file(STRINGS "${LIBIDN2_INCLUDE_DIR}/idn2.h" LIBIDN2_H REGEX "^[ \t]*#[ \t]*define[ \t]+IDN2_VERSION[ \t]")
string(REGEX REPLACE "^.*IDN2_VERSION[ \t]+\"([0-9.]+)\".*$" "\\1" LIBIDN2_VERSION "${LIBIDN2_H}")
endif ()
endif ()
list(APPEND LIBIDN2_LIBRARIES "${LIBIDN2_LIBRARY}")
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Libidn2
REQUIRED_VARS LIBIDN2_LIBRARIES LIBIDN2_INCLUDE_DIR
VERSION_VAR LIBIDN2_VERSION
)
endif ()
mark_as_advanced(LIBIDN2_INCLUDE_DIR LIBIDN2_LIBRARIES LIBIDN2_LIBRARY)
mark_as_advanced(LIBIDN2_INCLUDE_DIR LIBIDN2_LIBRARIES)

View File

@ -28,6 +28,18 @@ This module will set the following variables in your project:
#]=======================================================================]
find_package(PkgConfig QUIET)
if (PKG_CONFIG_FOUND)
pkg_check_modules(PkgLibunbound IMPORTED_TARGET GLOBAL QUIET libunbound)
endif ()
if (PkgLibunbound_FOUND)
set(LIBUNBOUND_INCLUDE_DIR ${PkgLibunbound_INCLUDE_DIRS} CACHE FILEPATH "libunbound include path")
set(LIBUNBOUND_LIBRARIES ${PkgLibunbound_LIBRARIES} CACHE STRING "libunbound libraries")
set(LIBUNBOUND_VERSION ${PkgLibunbound_VERSION})
add_library(Libunbound::Libunbound ALIAS PkgConfig::PkgLibunbound)
set(Libunbound_FOUND ON)
else ()
find_path(LIBUNBOUND_INCLUDE_DIR unbound.h
HINTS
"${LIBUNBOUND_DIR}"
@ -40,14 +52,14 @@ find_library(LIBUNBOUND_LIBRARY NAMES unbound
"${LIBUNBOUND_DIR}/lib"
)
set(LIBUNBOUND_LIBRARIES "")
set(_LIBUNBOUND_LIBRARIES "")
if (UNIX)
find_package(Threads REQUIRED)
find_package(OpenSSL REQUIRED)
list(APPEND LIBUNBOUND_LIBRARIES "${CMAKE_THREAD_LIBS_INIT}")
list(APPEND LIBUNBOUND_LIBRARIES "${OPENSSL_LIBRARIES}")
list(APPEND _LIBUNBOUND_LIBRARIES "${CMAKE_THREAD_LIBS_INIT}")
list(APPEND _LIBUNBOUND_LIBRARIES "${OPENSSL_LIBRARIES}")
endif()
if (LIBUNBOUND_INCLUDE_DIR AND LIBUNBOUND_LIBRARY)
@ -79,12 +91,14 @@ if (LIBUNBOUND_INCLUDE_DIR AND LIBUNBOUND_LIBRARY)
endif ()
endif ()
list(APPEND LIBUNBOUND_LIBRARIES "${LIBUNBOUND_LIBRARY}")
list(APPEND _LIBUNBOUND_LIBRARIES "${LIBUNBOUND_LIBRARY}")
set(LIBUNBOUND_LIBRARIES ${_LIBUNBOUND_LIBRARIES} CACHE STRING "libunbound libraries")
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Libunbound
REQUIRED_VARS LIBUNBOUND_LIBRARIES LIBUNBOUND_INCLUDE_DIR
VERSION_VAR LIBUNBOUND_VERSION
)
endif ()
mark_as_advanced(LIBUNBOUND_INCLUDE_DIR LIBUNBOUND_LIBRARIES LIBUNBOUND_LIBRARY)

View File

@ -28,27 +28,37 @@ This module will set the following variables in your project:
#]=======================================================================]
find_package(PkgConfig QUIET)
if (PKG_CONFIG_FOUND)
pkg_check_modules(PkgLibuv IMPORTED_TARGET GLOBAL libuv)
endif ()
if (PkgLibuv_FOUND)
set(LIBUV_INCLUDE_DIR ${PkgLibuv_INCLUDE_DIRS} CACHE FILEPATH "libuv include path")
set(LIBUV_LIBRARIES ${PkgLibuv_LIBRARIES} CACHE STRING "libuv libraries")
set(LIBUV_VERSION ${PkgLibuv_VERSION})
add_library(Libuv::Libuv ALIAS PkgConfig::PkgLibuv)
set(Libuv_FOUND ON)
else ()
find_path(LIBUV_INCLUDE_DIR uv.h
HINTS
"${LIBUV_DIR}"
"${LIBUV_DIR}/include"
)
find_library(LIBUV_LIBRARY NAMES uv libuv
find_library(LIBUV_LIBRARIES NAMES uv libuv
HINTS
"${LIBUV_DIR}"
"${LIBUV_DIR}/lib"
)
set(LIBUV_LIBRARIES "")
if (LIBUV_INCLUDE_DIR AND LIBUV_LIBRARY)
if (LIBUV_INCLUDE_DIR AND LIBUV_LIBRARIES)
if (NOT TARGET Libuv::Libuv)
add_library(Libuv::Libuv UNKNOWN IMPORTED)
set_target_properties(Libuv::Libuv PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${LIBUV_INCLUDE_DIR}"
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
IMPORTED_LOCATION "${LIBUV_LIBRARY}"
IMPORTED_LOCATION "${LIBUV_LIBRARIES}"
)
endif ()
@ -62,12 +72,11 @@ if (LIBUV_INCLUDE_DIR AND LIBUV_LIBRARY)
endif ()
endif ()
list(APPEND LIBUV_LIBRARIES "${LIBUV_LIBRARY}")
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Libuv
REQUIRED_VARS LIBUV_LIBRARIES LIBUV_INCLUDE_DIR
VERSION_VAR LIBUV_VERSION
)
endif ()
mark_as_advanced(LIBUV_INCLUDE_DIR LIBUV_LIBRARIES LIBUV_LIBRARY)
mark_as_advanced(LIBUV_INCLUDE_DIR LIBUV_LIBRARIES)

View File

@ -30,6 +30,20 @@ This module will set the following variables in your project:
#]=======================================================================]
find_package(PkgConfig QUIET)
if(PKG_CONFIG_FOUND)
pkg_check_modules(PkgNettle IMPORTED_TARGET GLOBAL nettle)
pkg_check_modules(PkgHogweed IMPORTED_TARGET GLOBAL QUIET hogweed)
endif()
if(PkgNettle_FOUND AND PkHogweed_FOUND)
set(NETTLE_INCLUDE_DIR ${PkgNettle_INCLUDE_DIRS} ${PkgHogweed_INCLUDE_DIRS} CACHE FILEPATH "Nettle include path")
set(NETTLE_LIBRARIES ${PkgNettle_LIBRARIES} ${PkgHogweed_LIBRARIES} CACHE STRING "Nettle libraries")
set(NETTLE_VERSION ${PkgNettle_VERSION})
add_library(Nettle::Nettle ALIAS PkgConfig::PkgNettle)
add_library(Nettle::Hogweed ALIAS PkgConfig::PkgHogweed)
set(Nettle_FOUND ON)
else()
find_path(NETTLE_INCLUDE_DIR nettle/version.h
HINTS
"${NETTLE_DIR}"
@ -48,16 +62,17 @@ find_library(HOGWEED_LIBRARY NAMES hogweed libhogweed
"${NETTLE_DIR}/lib"
)
set(NETTLE_LIBRARIES "")
set(_NETTLE_LIBRARIES ${NETTLE_LIBRARY} ${HOGWEED_LIBRARY})
# May need gmp library on Unix.
if (UNIX)
find_library(NETTLE_GMP_LIBRARY gmp)
endif ()
if (NETTLE_GMP_LIBRARY)
list(APPEND NETTLE_LIBRARIES "${NETTLE_GMP_LIBRARY}")
endif ()
list(APPEND _NETTLE_LIBRARIES "${NETTLE_GMP_LIBRARY}")
endif ()
set(NETTLE_LIBRARIES ${_NETTLE_LIBRARIES} CACHE STRING "nettle libraries")
if (NETTLE_INCLUDE_DIR AND NETTLE_LIBRARY AND HOGWEED_LIBRARY)
if (NOT TARGET Nettle::Nettle)
@ -91,5 +106,6 @@ find_package_handle_standard_args(Nettle
REQUIRED_VARS NETTLE_LIBRARIES NETTLE_INCLUDE_DIR
VERSION_VAR NETTLE_VERSION
)
endif()
mark_as_advanced(NETTLE_INCLUDE_DIR NETTLE_LIBRARIES NETTLE_LIBRARY HOGWEED_LIBRARY)
mark_as_advanced(NETTLE_INCLUDE_DIR NETTLE_LIBRARIES NETTLE_LIBRARY HOGWEED_LIBRARY NETTLE_GMP_LIBRARY)

View File

@ -20,7 +20,7 @@ function(target_shared_library_exports lib libname symbols)
file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/${libname}.ver" " ${symbol};\n")
endforeach ()
file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/${libname}.ver" "local:\n *;\n};\n")
target_link_libraries(${lib} PRIVATE "-Wl,--version-script=getdns.ver")
target_link_libraries(${lib} PRIVATE "-Wl,--version-script=${libname}.ver")
else ()
message(WARNING "Unknown platform, ${lib} exports not set.")
endif ()

View File

@ -76,7 +76,7 @@ getdns_dict **response)
The getdns_general(3) and getdns_general_sync functions provide public entry
points into the getdns API library to retrieve any valid responses to a query
from the DNS (note that other namespaces in the context are not used). Most
typical use cases for applications are probably satisifed via calls to
typical use cases for applications are probably satisfied via calls to
getdns_address(3) which would replace getaddrinfo(3).
.HP 3

View File

@ -1,7 +1,7 @@
prefix=@prefix@
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include
libdir=@libdir_for_pc_file@
includedir=@includedir_for_pc_file@
Name: getdns
Version: @GETDNS_VERSION@

View File

@ -1,7 +1,7 @@
prefix=@prefix@
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include
libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@
includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
Name: getdns_ext_event
Version: @GETDNS_VERSION@

View File

@ -39,5 +39,5 @@ int mkstemp(char *template)
{
if (_mktemp_s(template, strlen(template) + 1) != 0)
return -1;
return open(template, _O_CREAT | _O_EXCL, _S_IWRITE);
return open(template, _O_CREAT | _O_EXCL | _O_RDWR, _S_IWRITE | _S_IREAD);
}

View File

@ -248,6 +248,7 @@ static struct const_name_info consts_name_info[] = {
{ "GETDNS_OPCODE_STATUS", 2 },
{ "GETDNS_OPCODE_UPDATE", 5 },
{ "GETDNS_RCODE_BADALG", 21 },
{ "GETDNS_RCODE_BADCOOKIE", 23 },
{ "GETDNS_RCODE_BADKEY", 17 },
{ "GETDNS_RCODE_BADMODE", 19 },
{ "GETDNS_RCODE_BADNAME", 20 },
@ -255,7 +256,6 @@ static struct const_name_info consts_name_info[] = {
{ "GETDNS_RCODE_BADTIME", 18 },
{ "GETDNS_RCODE_BADTRUNC", 22 },
{ "GETDNS_RCODE_BADVERS", 16 },
{ "GETDNS_RCODE_COOKIE", 23 },
{ "GETDNS_RCODE_FORMERR", 1 },
{ "GETDNS_RCODE_NOERROR", 0 },
{ "GETDNS_RCODE_NOTAUTH", 9 },
@ -328,6 +328,7 @@ static struct const_name_info consts_name_info[] = {
{ "GETDNS_RRTYPE_GPOS", 27 },
{ "GETDNS_RRTYPE_HINFO", 13 },
{ "GETDNS_RRTYPE_HIP", 55 },
{ "GETDNS_RRTYPE_HTTPS", 65 },
{ "GETDNS_RRTYPE_IPSECKEY", 45 },
{ "GETDNS_RRTYPE_ISDN", 20 },
{ "GETDNS_RRTYPE_IXFR", 251 },
@ -373,6 +374,7 @@ static struct const_name_info consts_name_info[] = {
{ "GETDNS_RRTYPE_SPF", 99 },
{ "GETDNS_RRTYPE_SRV", 33 },
{ "GETDNS_RRTYPE_SSHFP", 44 },
{ "GETDNS_RRTYPE_SVCB", 64 },
{ "GETDNS_RRTYPE_TA", 32768 },
{ "GETDNS_RRTYPE_TALINK", 58 },
{ "GETDNS_RRTYPE_TKEY", 249 },

View File

@ -926,6 +926,7 @@ upstream_init(getdns_upstream *upstream,
/* For sharing a socket to this upstream with TCP */
upstream->fd = -1;
upstream->expires = 0;
upstream->tls_fallback_ok = 0;
upstream->tls_obj = NULL;
upstream->tls_session = NULL;
upstream->tls_cipher_list = NULL;
@ -952,9 +953,12 @@ upstream_init(getdns_upstream *upstream,
(void) getdns_eventloop_event_init(
&upstream->finished_event, upstream, NULL, NULL, NULL);
upstream->has_client_cookie = 0;
upstream->has_prev_client_cookie = 0;
upstream->has_server_cookie = 0;
upstream->server_cookie_len = 0;
(void) memset(&upstream->server_cookie, 0,
sizeof(upstream->server_cookie));
upstream->src_addr_checked = 0;
(void) memset(&upstream->src_addr, 0, sizeof(upstream->src_addr));
upstream->src_addr_len = 0;
upstream->tsig_alg = GETDNS_NO_TSIG;
upstream->tsig_dname_len = 0;
@ -1289,7 +1293,7 @@ transaction_id_cmp(const void *id1, const void *id2)
static void
NULL_update_callback(
getdns_context *context, getdns_context_code_t code, void *userarg)
{ (void)context; (void)code; (void)userarg; }
{ (void)context; (void)code; (void)userarg; /* unused parameters */ }
static int
netreq_expiry_cmp(const void *id1, const void *id2)
@ -1386,6 +1390,7 @@ getdns_context_create_with_extended_memory_functions(
#endif
result->processing = 0;
result->destroying = 0;
result->to_destroy = 0;
result->my_mf.mf_arg = userarg;
result->my_mf.mf.ext.malloc = malloc;
result->my_mf.mf.ext.realloc = realloc;
@ -1431,6 +1436,7 @@ getdns_context_create_with_extended_memory_functions(
result->timeout = 5000;
result->idle_timeout = 0;
result->tcp_send_timeout = -1;
result->follow_redirects = GETDNS_REDIRECTS_FOLLOW;
result->dns_root_servers = NULL;
#if defined(HAVE_LIBUNBOUND) && !defined(HAVE_UB_CTX_SET_STUB)
@ -1637,8 +1643,11 @@ getdns_context_destroy(struct getdns_context *context)
if (context == NULL)
return;
/* If being destroyed during getdns callback, fail via assert */
assert(context->processing == 0);
if (context->processing == 1) {
context->to_destroy = 1;
return;
}
if (context->destroying)
return;
@ -2363,6 +2372,34 @@ getdns_context_set_idle_timeout(getdns_context *context, uint64_t timeout)
return GETDNS_RETURN_GOOD;
} /* getdns_context_set_timeout */
/*
* getdns_context_unset_tcp_send_timeout
*
*/
getdns_return_t
getdns_context_unset_tcp_send_timeout(getdns_context *context)
{
if (!context)
return GETDNS_RETURN_INVALID_PARAMETER;
context->tcp_send_timeout = -1;
return GETDNS_RETURN_GOOD;
}
/*
* getdns_context_set_tcp_send_timeout
*
*/
getdns_return_t
getdns_context_set_tcp_send_timeout(struct getdns_context *context,
uint32_t value)
{
if (!context || value > INT_MAX)
return GETDNS_RETURN_INVALID_PARAMETER;
context->tcp_send_timeout = value;
return GETDNS_RETURN_GOOD;
}
/*
* getdns_context_set_follow_redirects
@ -3728,14 +3765,13 @@ uint32_t
getdns_context_get_num_pending_requests(const getdns_context* context,
struct timeval* next_timeout)
{
(void)next_timeout;
(void)next_timeout; /* unused parameter */
if (!context)
return GETDNS_RETURN_INVALID_PARAMETER;
if (context->outbound_requests.count)
context->extension->vmt->run_once(context->extension, 0);
return context->outbound_requests.count;
}
@ -3833,6 +3869,9 @@ _get_context_settings(const getdns_context* context)
(context->timeout > 0xFFFFFFFFull) ? 0xFFFFFFFF: (uint32_t) context->timeout)
|| getdns_dict_set_int(result, "idle_timeout",
(context->idle_timeout > 0xFFFFFFFFull) ? 0xFFFFFFFF : (uint32_t) context->idle_timeout)
|| ( context->tcp_send_timeout != -1
&& getdns_dict_set_int(result, "tcp_send_timeout",
context->tcp_send_timeout))
|| getdns_dict_set_int(result, "limit_outstanding_queries",
context->limit_outstanding_queries)
|| getdns_dict_set_int(result, "dnssec_allowed_skew",
@ -3895,6 +3934,14 @@ _get_context_settings(const getdns_context* context)
getdns_list_destroy(list);
goto error;
}
if (getdns_context_get_dns_root_servers(context, &list))
; /* pass */
else if (list && _getdns_dict_set_this_list(
result, "dns_root_servers", list)) {
getdns_list_destroy(list);
goto error;
}
if (context->dns_transport_count > 0) {
/* create a namespace list */
if (!(list = getdns_list_create_with_context(context)))
@ -4052,6 +4099,9 @@ getdns_context_get_api_information(const getdns_context* context)
&& ! getdns_dict_util_set_string(
result, "compilation_comment", GETDNS_COMPILATION_COMMENT)
&& ! getdns_dict_util_set_string(
result, "build_cflags", GETDNS_BUILD_CFLAGS)
&& ! getdns_dict_util_set_string(
result, "default_trust_anchor_location", TRUST_ANCHOR_FILE)
@ -4102,7 +4152,7 @@ getdns_context_set_use_threads(getdns_context* context, int use_threads) {
else
r = ub_ctx_async(context->unbound_ctx, 0);
#else
(void)use_threads;
(void)use_threads; /* unused parameter */
#endif
return r == 0 ? GETDNS_RETURN_GOOD : GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
}
@ -4296,6 +4346,16 @@ CONTEXT_GETTER(timeout , uint64_t)
CONTEXT_GETTER(idle_timeout , uint64_t)
CONTEXT_GETTER(follow_redirects , getdns_redirects_t)
getdns_return_t
getdns_context_get_tcp_send_timeout(
const getdns_context *context, uint32_t* value)
{
if (!context || !value) return GETDNS_RETURN_INVALID_PARAMETER;
*value = context->tcp_send_timeout == -1 ? 0
: context->tcp_send_timeout;
return GETDNS_RETURN_GOOD;
}
getdns_return_t
getdns_context_get_dns_root_servers(
const getdns_context *context, getdns_list **value)
@ -4635,6 +4695,7 @@ _getdns_context_config_setting(getdns_context *context,
CONTEXT_SETTING_INT(dns_transport)
CONTEXT_SETTING_ARRAY(dns_transport_list, transport_list)
CONTEXT_SETTING_INT(idle_timeout)
CONTEXT_SETTING_INT(tcp_send_timeout)
CONTEXT_SETTING_INT(limit_outstanding_queries)
CONTEXT_SETTING_INT(timeout)
CONTEXT_SETTING_INT(follow_redirects)
@ -4877,7 +4938,7 @@ FILE *_getdns_context_get_priv_fp(
_getdns_log(&context->log
, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_INFO
, "Error opening \"%s\": %s\n"
, path, _getdns_errnostr());
, path, _getdns_fileerrnostr());
return f;
}
@ -4956,31 +5017,31 @@ int _getdns_context_write_priv_file(getdns_context *context,
_getdns_log(&context->log
, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_INFO
, "Could not create temporary file \"%s\": %s\n"
, tmpfn, _getdns_errnostr());
, tmpfn, _getdns_fileerrnostr());
else if (!(f = fdopen(fd, "w")))
_getdns_log(&context->log
, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR
, "Error opening temporary file \"%s\": %s\n"
, tmpfn, _getdns_errnostr());
, tmpfn, _getdns_fileerrnostr());
else if (fwrite(content->data, 1, content->size, f) < content->size)
_getdns_log(&context->log
, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR
, "Error writing to temporary file \"%s\": %s\n"
, tmpfn, _getdns_errnostr());
, tmpfn, _getdns_fileerrnostr());
else if (fclose(f) < 0)
else if (fclose(f))
_getdns_log(&context->log
, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR
, "Error closing temporary file \"%s\": %s\n"
, tmpfn, _getdns_errnostr());
, "Error closing temporary file \"%s\": %s (%p)\n"
, tmpfn, _getdns_fileerrnostr(), f);
else if (rename(tmpfn, path) < 0)
_getdns_log(&context->log
, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR
, "Error renaming temporary file \"%s\" to \"%s\""
": %s\n", tmpfn, path, _getdns_errnostr());
": %s\n", tmpfn, path, _getdns_fileerrnostr());
else {
context->can_write_appdata = PROP_ABLE;
return 1;
@ -5033,7 +5094,7 @@ int _getdns_context_can_write_appdata(getdns_context *context)
_getdns_log(&context->log
, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR
, "Error unlinking write test file: \"%s\": %s\n"
, path, _getdns_errnostr());
, path, _getdns_fileerrnostr());
return 1;
}
@ -5346,7 +5407,7 @@ getdns_context_set_tls_curves_list(
dispatch_updated(context, GETDNS_CONTEXT_CODE_TLS_CIPHER_LIST);
return GETDNS_RETURN_GOOD;
#else
(void)tls_curves_list;
(void)tls_curves_list; /* unused parameter */
return GETDNS_RETURN_NOT_IMPLEMENTED;
#endif
}

View File

@ -243,15 +243,13 @@ typedef struct getdns_upstream {
unsigned is_sync_loop : 1;
/* EDNS cookies */
uint32_t secret;
uint8_t client_cookie[8];
uint8_t prev_client_cookie[8];
uint8_t server_cookie[32];
uint8_t server_cookie[40];
size_t server_cookie_len;
unsigned has_client_cookie : 1;
unsigned has_prev_client_cookie : 1;
unsigned has_server_cookie : 1;
unsigned server_cookie_len : 5;
uint64_t src_addr_checked;
struct sockaddr_storage src_addr;
socklen_t src_addr_len;
char src_addr_str[INET6_ADDRSTRLEN];
/* TSIG */
uint8_t tsig_dname[256];
@ -327,6 +325,7 @@ struct getdns_context {
size_t namespace_count;
uint64_t timeout;
uint64_t idle_timeout;
int tcp_send_timeout; /* -1 is unset */
getdns_redirects_t follow_redirects;
getdns_list *dns_root_servers;
@ -398,6 +397,7 @@ struct getdns_context {
int processing;
int destroying;
int to_destroy;
struct mem_funcs mf;
struct mem_funcs my_mf;

View File

@ -122,7 +122,7 @@ getdns_convert_ulabel_to_alabel(const char *ulabel)
if (idn2_lookup_u8((uint8_t *)ulabel, &alabel, IDN2_TRANSITIONAL) == IDN2_OK)
return (char *)alabel;
#else
(void)ulabel;
(void)ulabel; /* unused parameter */
#endif
return NULL;
}
@ -149,7 +149,7 @@ getdns_convert_alabel_to_ulabel(const char *alabel)
if (idn2_to_unicode_8z8z(alabel, &ulabel, 0) == IDN2_OK)
return ulabel;
#else
(void)alabel;
(void)alabel; /* unused parameter */
#endif
return NULL;
}
@ -529,8 +529,10 @@ _getdns_fp2rr_list(struct mem_funcs *mf,
else while (r == GETDNS_RETURN_GOOD && !feof(in)) {
len = GLDNS_RR_BUF_SIZE;
dname_len = 0;
if (gldns_fp2wire_rr_buf(in, rr, &len, &dname_len, &pst))
if (gldns_fp2wire_rr_buf(in, rr, &len, &dname_len, &pst)) {
r = GETDNS_RETURN_GENERIC_ERROR;
break;
}
if (dname_len && dname_len < sizeof(pst.prev_rr)) {
memcpy(pst.prev_rr, rr, dname_len);
pst.prev_rr_len = dname_len;
@ -744,6 +746,75 @@ getdns_wire2msg_dict_scan(
else GLDNS_ ## Y ## _CLR(header); \
}
static getdns_return_t
_getdns_reply_dict2wire_hdr(
const getdns_dict *reply, gldns_buffer *gbuf, getdns_bindata *wf_reply)
{
size_t pkt_start = gldns_buffer_position(gbuf);
size_t pkt_len = wf_reply->size;
uint8_t *header = gldns_buffer_current(gbuf);
uint8_t *pkt_end = header + pkt_len;
getdns_list *sec;
size_t sec_len;
uint32_t n, i;
_getdns_rr_iter rr_iter_storage, *rr_iter;
getdns_list *section;
size_t rrs2skip;
getdns_dict *rr_dict;
gldns_buffer_write(gbuf, wf_reply->data, wf_reply->size);
if (GLDNS_QDCOUNT(header) != 1
|| (GLDNS_ARCOUNT(header) != 0 && GLDNS_ARCOUNT(header) != 1))
return GETDNS_RETURN_GENERIC_ERROR;
sec_len = 0;
if (!getdns_dict_get_list(reply, "answer", &sec))
(void) getdns_list_get_length(sec, &sec_len);
if (sec_len != GLDNS_ANCOUNT(header))
return GETDNS_RETURN_GENERIC_ERROR;
sec_len = 0;
if (!getdns_dict_get_list(reply, "authority", &sec))
(void) getdns_list_get_length(sec, &sec_len);
if (sec_len != GLDNS_NSCOUNT(header))
return GETDNS_RETURN_GENERIC_ERROR;
rrs2skip = 1 + GLDNS_ANCOUNT(header) + GLDNS_NSCOUNT(header);
SET_HEADER_INT(id, ID);
SET_HEADER_BIT(qr, QR);
SET_HEADER_BIT(aa, AA);
SET_HEADER_BIT(tc, TC);
SET_HEADER_BIT(rd, RD);
SET_HEADER_BIT(cd, CD);
SET_HEADER_BIT(ra, RA);
SET_HEADER_BIT(ad, AD);
SET_HEADER_INT(opcode, OPCODE);
SET_HEADER_INT(rcode, RCODE);
SET_HEADER_BIT(z, Z);
for ( rr_iter = _getdns_rr_iter_init(&rr_iter_storage, header, pkt_len)
; rr_iter
; rr_iter = _getdns_rr_iter_next(rr_iter)) {
if (rr_iter->nxt > pkt_end)
return GETDNS_RETURN_GENERIC_ERROR;
if (!--rrs2skip)
break;
/* TODO: Delete sigs when do bit was off */
}
gldns_buffer_set_position(gbuf, rr_iter->nxt - header);
if (!getdns_dict_get_list(reply, "additional", &section)) {
for ( n = 0, i = 0
; !getdns_list_get_dict(section, i, &rr_dict); i++) {
if (!_getdns_rr_dict2wire(rr_dict, gbuf))
n++;
}
gldns_buffer_write_u16_at(gbuf, pkt_start+GLDNS_ARCOUNT_OFF, n);
}
return GETDNS_RETURN_GOOD;
}
getdns_return_t
_getdns_reply_dict2wire(
const getdns_dict *reply, gldns_buffer *buf, int reuse_header)
@ -754,6 +825,7 @@ _getdns_reply_dict2wire(
getdns_list *section;
getdns_dict *rr_dict;
getdns_bindata *qname;
name_cache_t name_cache = {0};
int remove_dnssec;
pkt_start = gldns_buffer_position(buf);
@ -783,7 +855,7 @@ _getdns_reply_dict2wire(
if (!getdns_dict_get_bindata(reply, "/question/qname", &qname) &&
!getdns_dict_get_int(reply, "/question/qtype", &qtype)) {
(void)getdns_dict_get_int(reply, "/question/qclass", &qclass);
gldns_buffer_write(buf, qname->data, qname->size);
_getdns_rr_buffer_write_cached_name(buf, qname, &name_cache);
gldns_buffer_write_u16(buf, (uint16_t)qtype);
gldns_buffer_write_u16(buf, (uint16_t)qclass);
gldns_buffer_write_u16_at(buf, pkt_start+GLDNS_QDCOUNT_OFF, 1);
@ -806,7 +878,7 @@ _getdns_reply_dict2wire(
!getdns_dict_get_int(rr_dict, "type", &rr_type) &&
rr_type == GETDNS_RRTYPE_RRSIG)
continue;
if (!_getdns_rr_dict2wire(rr_dict, buf))
if (!_getdns_rr_dict2wire_cache(rr_dict, buf, &name_cache))
n++;
}
gldns_buffer_write_u16_at(buf, pkt_start+GLDNS_ANCOUNT_OFF, n);
@ -850,6 +922,8 @@ _getdns_msg_dict2wire_buf(const getdns_dict *msg_dict, gldns_buffer *gbuf)
getdns_return_t r;
getdns_list *replies;
getdns_dict *reply;
getdns_list *wf_replies = NULL;
getdns_bindata *wf_reply;
size_t i;
if ((r = getdns_dict_get_list(msg_dict, "replies_tree", &replies))) {
@ -857,8 +931,23 @@ _getdns_msg_dict2wire_buf(const getdns_dict *msg_dict, gldns_buffer *gbuf)
return r;
return _getdns_reply_dict2wire(msg_dict, gbuf, 0);
}
(void) getdns_dict_get_list(msg_dict, "replies_full", &wf_replies);
for (i = 0; r == GETDNS_RETURN_GOOD; i++) {
if (!(r = getdns_list_get_dict(replies, i, &reply)))
if ((r = getdns_list_get_dict(replies, i, &reply)))
;
else if (wf_replies
&& !getdns_list_get_bindata(wf_replies, i, &wf_reply)) {
size_t pkt_start = gldns_buffer_position(gbuf);
if (!gldns_buffer_reserve(gbuf, wf_reply->size))
return GETDNS_RETURN_NEED_MORE_SPACE;
if ((r = _getdns_reply_dict2wire_hdr( reply, gbuf
, wf_reply))) {
gldns_buffer_set_position(gbuf, pkt_start);
r = _getdns_reply_dict2wire(reply, gbuf, 0);
}
} else
r = _getdns_reply_dict2wire(reply, gbuf, 0);
}
return r == GETDNS_RETURN_NO_SUCH_LIST_ITEM ? GETDNS_RETURN_GOOD : r;
@ -1102,7 +1191,7 @@ _getdns_ipaddr_dict_mf(struct mem_funcs *mf, const char *ipstr)
tsig_name_str = "";
}
}
if (*ipstr == '*') {
if (*ipstr == '*' && *(ipstr+1) == '\0') {
getdns_dict_util_set_string(r, "address_type", "IPv6");
addr.size = 16;
(void) memset(buf, 0, 16);
@ -1814,8 +1903,8 @@ getdns_yaml2list(const char *str, getdns_list **list)
return GETDNS_RETURN_GENERIC_ERROR;
}
#else /* USE_YAML_CONFIG */
(void) str;
(void) list;
(void) str; /* unused parameter */
(void) list; /* unused parameter */
return GETDNS_RETURN_NOT_IMPLEMENTED;
#endif /* USE_YAML_CONFIG */
}
@ -1838,8 +1927,8 @@ getdns_yaml2bindata(const char *str, getdns_bindata **bindata)
return GETDNS_RETURN_GENERIC_ERROR;
}
#else /* USE_YAML_CONFIG */
(void) str;
(void) bindata;
(void) str; /* unused parameter */
(void) bindata; /* unused parameter */
return GETDNS_RETURN_NOT_IMPLEMENTED;
#endif /* USE_YAML_CONFIG */
}
@ -1862,8 +1951,8 @@ getdns_yaml2int(const char *str, uint32_t *value)
return GETDNS_RETURN_GENERIC_ERROR;
}
#else /* USE_YAML_CONFIG */
(void) str;
(void) value;
(void) str; /* unused parameter */
(void) value; /* unused parameter */
return GETDNS_RETURN_NOT_IMPLEMENTED;
#endif /* USE_YAML_CONFIG */
}

View File

@ -892,6 +892,7 @@ getdns_pp_list(gldns_buffer *buf, size_t indent, const getdns_list *list,
struct getdns_bindata *bindata_item;
uint32_t int_item;
const char *strval;
char abuf[80];
if (list == NULL)
return 0;
@ -933,7 +934,21 @@ getdns_pp_list(gldns_buffer *buf, size_t indent, const getdns_list *list,
if (getdns_list_get_bindata(list, i, &bindata_item) !=
GETDNS_RETURN_GOOD)
return -1;
if (getdns_pp_bindata(
if (for_literals && (bindata_item->size == 4 ||
bindata_item->size == 16 )) {
if (gldns_buffer_printf(buf,
(json ? "\"%s\"" : " <bindata for %s>"),
inet_ntop(( bindata_item->size == 4
? AF_INET : AF_INET6)
, bindata_item->data
, abuf
, sizeof(abuf) - 1
)) < 0)
return -1;
} else if (getdns_pp_bindata(
buf, bindata_item, 0, json) < 0)
return -1;
break;
@ -1030,12 +1045,12 @@ _getdns_print_rcode(gldns_buffer *buf, uint32_t rcode)
" GETDNS_RCODE_BADSIG" , " GETDNS_RCODE_BADKEY" ,
" GETDNS_RCODE_BADTIME" , " GETDNS_RCODE_BADMODE" ,
" GETDNS_RCODE_BADNAME" , " GETDNS_RCODE_BADALG" ,
" GETDNS_RCODE_BADTRUNC"
" GETDNS_RCODE_BADTRUNC", " GETDNS_RCODE_BADCOOKIE"
};
if (rcode <= 10)
(void) gldns_buffer_printf(buf, "%s", rcodes[rcode]);
else if (rcode >= 16 && rcode <= 22)
(void) gldns_buffer_printf(buf, "%s", rcodes[rcode-6]);
else if (rcode >= 16 && rcode <= 23)
(void) gldns_buffer_printf(buf, "%s", rcodes[rcode-5]);
else
return 0;
return 1;
@ -1141,6 +1156,11 @@ getdns_pp_dict(gldns_buffer * buf, size_t indent,
if (!json && strcmp(item->node.key, "rcode") == 0 &&
_getdns_print_rcode(buf, item->i.data.n))
break;
if (!json &&
strcmp(item->node.key, "extended_rcode") == 0 &&
item->i.data.n >= 16 &&
_getdns_print_rcode(buf, item->i.data.n))
break;
if (gldns_buffer_printf(
buf,(json < 2 ? " %d" : "%d"), item->i.data.n) < 0)
return -1;
@ -1199,8 +1219,9 @@ getdns_pp_dict(gldns_buffer * buf, size_t indent,
if (getdns_pp_list(buf, indent, item->i.data.list,
(strcmp(item->node.key, "namespaces") == 0 ||
strcmp(item->node.key, "dns_transport_list") == 0
|| strcmp(item->node.key, "bad_dns") == 0),
json) < 0)
|| strcmp(item->node.key, "bad_dns") == 0 ||
strcmp(item->node.key, "dns_root_servers") == 0
), json) < 0)
return -1;
break;

View File

@ -922,7 +922,7 @@ static getdns_dict *CD_extension(getdns_dns_req *dnsreq)
? dnssec_ok_checking_disabled_roadblock_avoidance
: dnssec_ok_checking_disabled_avoid_roadblocks;
#else
(void)dnsreq;
(void)dnsreq; /* unused parameter */
return dnssec_ok_checking_disabled;
#endif
}
@ -1554,7 +1554,7 @@ static int _getdns_verify_rrsig(const struct mem_funcs *mf,
for ( rdf = _getdns_rdf_iter_init(&rdf_spc, &val_rrset[i])
; rdf
; rdf = _getdns_rdf_iter_next(rdf) ) {
if (!(rdf->rdd_pos->type & GETDNS_RDF_N)) {
if ((rdf->rdd_pos->type & GETDNS_RDF_N) != GETDNS_RDF_N) {
gldns_buffer_write(
&valbuf, rdf->pos, rdf->nxt - rdf->pos);
continue;

View File

@ -97,7 +97,7 @@ static void
getdns_libev_read_cb(struct ev_loop *l, struct ev_io *io, int revents)
{
getdns_eventloop_event *el_ev = (getdns_eventloop_event *)io->data;
(void)l; (void)revents;
(void)l; (void)revents; /* unused parameters */
assert(el_ev->read_cb);
el_ev->read_cb(el_ev->userarg);
}
@ -106,7 +106,7 @@ static void
getdns_libev_write_cb(struct ev_loop *l, struct ev_io *io, int revents)
{
getdns_eventloop_event *el_ev = (getdns_eventloop_event *)io->data;
(void)l; (void)revents;
(void)l; (void)revents; /* unused parameters */
assert(el_ev->write_cb);
el_ev->write_cb(el_ev->userarg);
}
@ -115,7 +115,7 @@ static void
getdns_libev_timeout_cb(struct ev_loop *l, struct ev_timer *timer, int revents)
{
getdns_eventloop_event *el_ev = (getdns_eventloop_event *)timer->data;
(void)l; (void)revents;
(void)l; (void)revents; /* unused parameters */
assert(el_ev->timeout_cb);
el_ev->timeout_cb(el_ev->userarg);
}

View File

@ -99,7 +99,7 @@ static getdns_return_t
getdns_libevent_clear(getdns_eventloop *loop, getdns_eventloop_event *el_ev)
{
struct event *my_ev = (struct event *)el_ev->ev;
(void)loop;
(void)loop; /* unused parameter */
assert(my_ev);
@ -115,7 +115,7 @@ static void
getdns_libevent_callback(evutil_socket_t fd, short bits, void *arg)
{
getdns_eventloop_event *el_ev = (getdns_eventloop_event *)arg;
(void)fd;
(void)fd; /* unused parameter */
if (bits & EV_READ) {
assert(el_ev->read_cb);

View File

@ -73,8 +73,7 @@ getdns_libuv_cleanup(getdns_eventloop *loop)
}
typedef struct poll_timer {
uv_poll_t read;
uv_poll_t write;
uv_poll_t poll;
uv_timer_t timer;
int to_close;
struct mem_funcs mf;
@ -104,22 +103,15 @@ getdns_libuv_clear(getdns_eventloop *loop, getdns_eventloop_event *el_ev)
poll_timer *my_ev = (poll_timer *)el_ev->ev;
uv_poll_t *my_poll;
uv_timer_t *my_timer;
(void)loop;
(void)loop; /* unused parameter */
assert(my_ev);
DEBUG_UV("enter libuv_clear(el_ev = %p, my_ev = %p, to_close = %d)\n"
, el_ev, my_ev, my_ev->to_close);
if (el_ev->read_cb) {
my_poll = &my_ev->read;
uv_poll_stop(my_poll);
my_ev->to_close += 1;
my_poll->data = my_ev;
uv_close((uv_handle_t *)my_poll, getdns_libuv_close_cb);
}
if (el_ev->write_cb) {
my_poll = &my_ev->write;
if (el_ev->read_cb || el_ev->write_cb) {
my_poll = &my_ev->poll;
uv_poll_stop(my_poll);
my_ev->to_close += 1;
my_poll->data = my_ev;
@ -139,29 +131,29 @@ getdns_libuv_clear(getdns_eventloop *loop, getdns_eventloop_event *el_ev)
}
static void
getdns_libuv_read_cb(uv_poll_t *poll, int status, int events)
getdns_libuv_cb(uv_poll_t *poll, int status, int events)
{
getdns_eventloop_event *el_ev = (getdns_eventloop_event *)poll->data;
(void)status; (void)events;
if (status == 0) {
if (events & UV_READABLE) {
assert(el_ev->read_cb);
DEBUG_UV("enter libuv_read_cb(el_ev = %p, el_ev->ev = %p)\n"
, el_ev, el_ev->ev);
el_ev->read_cb(el_ev->userarg);
DEBUG_UV("exit libuv_read_cb(el_ev = %p, el_ev->ev = %p)\n"
, el_ev, el_ev->ev);
}
static void
getdns_libuv_write_cb(uv_poll_t *poll, int status, int events)
{
getdns_eventloop_event *el_ev = (getdns_eventloop_event *)poll->data;
(void)status; (void)events;
} else if (events & UV_WRITABLE) {
assert(el_ev->write_cb);
DEBUG_UV("enter libuv_write_cb(el_ev = %p, el_ev->ev = %p)\n"
, el_ev, el_ev->ev);
el_ev->write_cb(el_ev->userarg);
DEBUG_UV("exit libuv_write_cb(el_ev = %p, el_ev->ev = %p)\n"
, el_ev, el_ev->ev);
} else {
assert(ASSERT_UNREACHABLE);
}
}
}
static void
@ -173,7 +165,7 @@ getdns_libuv_timeout_cb(uv_timer_t *timer, int status)
{
getdns_eventloop_event *el_ev = (getdns_eventloop_event *)timer->data;
#ifndef HAVE_NEW_UV_TIMER_CB
(void)status;
(void)status; /* unused parameter */
#endif
assert(el_ev->timeout_cb);
DEBUG_UV("enter libuv_timeout_cb(el_ev = %p, el_ev->ev = %p)\n"
@ -206,17 +198,14 @@ getdns_libuv_schedule(getdns_eventloop *loop,
my_ev->mf = ext->mf;
el_ev->ev = my_ev;
if (el_ev->read_cb) {
my_poll = &my_ev->read;
if (el_ev->read_cb || el_ev->write_cb) {
my_poll = &my_ev->poll;
my_poll->data = el_ev;
uv_poll_init(ext->loop, my_poll, fd);
uv_poll_start(my_poll, UV_READABLE, getdns_libuv_read_cb);
}
if (el_ev->write_cb) {
my_poll = &my_ev->write;
my_poll->data = el_ev;
uv_poll_init(ext->loop, my_poll, fd);
uv_poll_start(my_poll, UV_WRITABLE, getdns_libuv_write_cb);
int events =
(el_ev->read_cb ? UV_READABLE : 0) |
(el_ev->write_cb ? UV_WRITABLE : 0);
uv_poll_start(my_poll, events, getdns_libuv_cb);
}
if (el_ev->timeout_cb) {
my_timer = &my_ev->timer;

View File

@ -288,7 +288,7 @@ static void
poll_read_cb(int fd, getdns_eventloop_event *event)
{
#if !defined(SCHED_DEBUG) || !SCHED_DEBUG
(void)fd;
(void)fd; /* unused parameter */
#endif
DEBUG_SCHED( "%s(fd: %d, event: %p)\n", __FUNC__, fd, (void *)event);
if (event && event->read_cb)
@ -299,7 +299,7 @@ static void
poll_write_cb(int fd, getdns_eventloop_event *event)
{
#if !defined(SCHED_DEBUG) || !SCHED_DEBUG
(void)fd;
(void)fd; /* unused parameter */
#endif
DEBUG_SCHED( "%s(fd: %d, event: %p)\n", __FUNC__, fd, (void *)event);
if (event && event->write_cb)

View File

@ -154,14 +154,14 @@ select_eventloop_clear(getdns_eventloop *loop, getdns_eventloop_event *event)
static void
select_eventloop_cleanup(getdns_eventloop *loop)
{
(void)loop;
(void)loop; /* unused parameter */
}
static void
select_read_cb(int fd, getdns_eventloop_event *event)
{
#if !defined(SCHED_DEBUG) || !SCHED_DEBUG
(void)fd;
(void)fd; /* unused parameter */
#endif
DEBUG_SCHED( "%s(fd: %d, event: %p)\n", __FUNC__, fd, (void *)event);
event->read_cb(event->userarg);
@ -171,7 +171,7 @@ static void
select_write_cb(int fd, getdns_eventloop_event *event)
{
#if !defined(SCHED_DEBUG) || !SCHED_DEBUG
(void)fd;
(void)fd; /* unused parameter */
#endif
DEBUG_SCHED( "%s(fd: %d, event: %p)\n", __FUNC__, fd, (void *)event);
event->write_cb(event->userarg);
@ -181,7 +181,7 @@ static void
select_timeout_cb(int fd, getdns_eventloop_event *event)
{
#if !defined(SCHED_DEBUG) || !SCHED_DEBUG
(void)fd;
(void)fd; /* unused parameter */
#endif
DEBUG_SCHED( "%s(fd: %d, event: %p)\n", __FUNC__, fd, (void *)event);
event->timeout_cb(event->userarg);
@ -244,7 +244,7 @@ select_eventloop_run_once(getdns_eventloop *loop, int blocking)
} else {
#endif
if (select(max_fd + 1, &readfds, &writefds, NULL,
(timeout == TIMEOUT_FOREVER ? NULL : &tv)) < 0) {
((blocking && timeout == TIMEOUT_FOREVER) ? NULL : &tv)) < 0) {
if (_getdns_socketerror_wants_retry())
return;
@ -309,7 +309,7 @@ _getdns_select_eventloop_init(struct mem_funcs *mf, _getdns_select_eventloop *lo
select_eventloop_run,
select_eventloop_run_once
};
(void) mf;
(void) mf; /* unused parameter */
(void) memset(loop, 0, sizeof(_getdns_select_eventloop));
loop->loop.vmt = &select_eventloop_vmt;
}

View File

@ -256,7 +256,7 @@ static void
ub_resolve_event_callback(void* arg, int rcode, void *pkt, int pkt_len,
int sec, char* why_bogus, int was_ratelimited)
{
(void) was_ratelimited;
(void) was_ratelimited; /* unused parameter */
#else
static void
ub_resolve_event_callback(void* arg, int rcode, void *pkt, int pkt_len,

View File

@ -417,6 +417,8 @@ typedef enum getdns_callback_type_t {
#define GETDNS_RRTYPE_OPENPGPKEY 61
#define GETDNS_RRTYPE_CSYNC 62
#define GETDNS_RRTYPE_ZONEMD 63
#define GETDNS_RRTYPE_SVCB 64
#define GETDNS_RRTYPE_HTTPS 65
#define GETDNS_RRTYPE_SPF 99
#define GETDNS_RRTYPE_UINFO 100
#define GETDNS_RRTYPE_UID 101
@ -492,7 +494,7 @@ typedef enum getdns_callback_type_t {
#define GETDNS_RCODE_BADNAME 20
#define GETDNS_RCODE_BADALG 21
#define GETDNS_RCODE_BADTRUNC 22
#define GETDNS_RCODE_COOKIE 23
#define GETDNS_RCODE_BADCOOKIE 23
/** @}
*/
@ -1514,6 +1516,24 @@ getdns_context_set_dns_transport_list(getdns_context *context,
getdns_return_t
getdns_context_set_idle_timeout(getdns_context *context, uint64_t timeout);
/**
* Set the number of milliseconds send data may remain unacknowledged by
* the peer in a TCP connection, if supported by the operation system.
* When not set (the default), the system default is left alone.
*
* @see getdns_context_get_tcp_send_timeout
* @see getdns_context_unset_tcp_send_timeout
* @param context The context to configure
* @param value The number of milliseconds the send data may remain
* unacknowledged by the peer in a TCP connection.
* @return GETDNS_RETURN_GOOD when successful.
* @return GETDNS_RETURN_INVALID_PARAMETER when context was NULL or the
* value was too high.
*/
getdns_return_t
getdns_context_set_tcp_send_timeout(getdns_context *context,
uint32_t value);
/**
* Limit the number of outstanding DNS queries. When more than limit requests
* are scheduled, they are kept on an internal queue, to be rescheduled when
@ -1579,7 +1599,7 @@ getdns_context_set_follow_redirects(getdns_context *context,
* contains at least two names: address_type (whose value is
* a bindata; it is currently either "IPv4" or "IPv6") and
* address_data (whose value is a bindata).
* This implementation also accepts a list of addressxi
* This implementation also accepts a list of address
* bindatas. Or a list of rr_dicts for address records (i.e.
* the additional section of a NS query for ".", or a with
* getdns_fp2rr_list() converted root.hints file).

View File

@ -128,6 +128,7 @@ extern "C" {
#define GETDNS_NUMERIC_VERSION @GETDNS_NUMERIC_VERSION@
#define GETDNS_API_VERSION "@API_VERSION@"
#define GETDNS_API_NUMERIC_VERSION @API_NUMERIC_VERSION@
#define GETDNS_BUILD_CFLAGS "@GETDNS_BUILD_CFLAGS@"
/** @}
*/
@ -540,6 +541,18 @@ getdns_context_set_tls_query_padding_blocksize(getdns_context *context, uint16_t
getdns_return_t
getdns_context_unset_edns_maximum_udp_payload_size(getdns_context *context);
/**
* Configure context to use the system default setting for the time
* send data may remain unacknowledged by the peer in a TCP connection.
* @see getdns_context_set_tcp_send_timeout
* @see getdns_context_get_tcp_send_timeout
* @param context The context to configure
* @return GETDNS_RETURN_GOOD on success
* @return GETDNS_RETURN_INVALID_PARAMETER if context is null.
*/
getdns_return_t
getdns_context_unset_tcp_send_timeout(getdns_context *context);
typedef enum getdns_loglevel_type {
GETDNS_LOG_EMERG = 0,
@ -992,6 +1005,22 @@ getdns_return_t
getdns_context_get_idle_timeout(
const getdns_context *context, uint64_t *timeout);
/**
* Get the number of milliseconds send data may remain unacknowledged by
* the peer in a TCP connection setting from context.
* @see getdns_context_set_tcp_send_timeout
* @see getdns_context_unset_tcp_send_timeout
* @param[in] context The context from which to get the setting
* @param[out] value The number of milliseconds the send data may remain
* unacknowledged by the peer in a TCP connection.
* When the value is unset, 0 is returned.
* @return GETDNS_RETURN_GOOD when successful
* @return GETDNS_RETURN_INVALID_PARAMETER when context or value was NULL.
*/
getdns_return_t
getdns_context_get_tcp_send_timeout(const getdns_context *context,
uint32_t *value);
/**
* Get the setting that says whether or not DNS queries follow redirects.
* @see getdns_context_set_follow_redirects

View File

@ -232,7 +232,6 @@ INLINE void gldns_buffer_clear(gldns_buffer *buffer)
* the position is set to 0.
*
* \param[in] buffer the buffer to flip
* \return void
*/
INLINE void gldns_buffer_flip(gldns_buffer *buffer)
{
@ -782,7 +781,6 @@ int gldns_buffer_printf(gldns_buffer *buffer, const char *format, ...)
/**
* frees the buffer.
* \param[in] *buffer the buffer to be freed
* \return void
*/
void gldns_buffer_free(gldns_buffer *buffer);
@ -790,7 +788,6 @@ void gldns_buffer_free(gldns_buffer *buffer);
* Makes the buffer fixed and returns a pointer to the data. The
* caller is responsible for free'ing the result.
* \param[in] *buffer the buffer to be exported
* \return void
*/
void *gldns_buffer_export(gldns_buffer *buffer);

View File

@ -13,10 +13,7 @@
#include "gldns/gbuffer.h"
#include <limits.h>
#include <stdlib.h>
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
gldns_lookup_table gldns_directive_types[] = {
{ GLDNS_DIR_TTL, "$TTL" },
@ -37,7 +34,7 @@ gldns_fget_token_l(FILE *f, char *token, const char *delim, size_t limit, int *l
{
int c, prev_c;
int p; /* 0 -> no parentheses seen, >0 nr of ( seen */
int com, quoted;
int com, quoted, only_blank;
char *t;
size_t i;
const char *d;
@ -56,6 +53,7 @@ gldns_fget_token_l(FILE *f, char *token, const char *delim, size_t limit, int *l
com = 0;
quoted = 0;
prev_c = 0;
only_blank = 1; /* Assume we got only <blank> until now */
t = token;
if (del[0] == '"') {
quoted = 1;
@ -104,6 +102,22 @@ gldns_fget_token_l(FILE *f, char *token, const char *delim, size_t limit, int *l
if (line_nr) {
*line_nr = *line_nr + 1;
}
if (only_blank && i > 0) {
/* Got only <blank> so far. Reset and try
* again with the next line.
*/
i = 0;
t = token;
}
if (p == 0) {
/* If p != 0 then the next line is a continuation. So
* we assume that the next line starts with a blank only
* if it is actually a new line.
*/
only_blank = 1; /* Assume next line starts with
* <blank>.
*/
}
if (p == 0 && i > 0) {
goto tokenread;
} else {
@ -123,7 +137,7 @@ gldns_fget_token_l(FILE *f, char *token, const char *delim, size_t limit, int *l
if (line_nr) {
*line_nr = *line_nr + 1;
}
if (limit > 0 && (i >= limit || (size_t)(t-token) >= limit)) {
if (limit > 0 && (i+1 >= limit || (size_t)(t-token)+1 >= limit)) {
*t = '\0';
return -1;
}
@ -134,23 +148,49 @@ gldns_fget_token_l(FILE *f, char *token, const char *delim, size_t limit, int *l
/* check if we hit the delim */
for (d = del; *d; d++) {
if (c == *d)
break;
}
if (c == *d && i > 0 && prev_c != '\\' && p == 0) {
if (c == '\n' && line_nr) {
*line_nr = *line_nr + 1;
}
if (only_blank) {
/* Got only <blank> so far. Reset and
* try again with the next line.
*/
i = 0;
t = token;
only_blank = 1;
prev_c = c;
continue;
}
goto tokenread;
}
if (c != ' ' && c != '\t') {
/* Found something that is not <blank> */
only_blank= 0;
}
if (c != '\0' && c != '\n') {
i++;
}
if (limit > 0 && (i >= limit || (size_t)(t-token) >= limit)) {
/* is there space for the character and the zero after it */
if (limit > 0 && (i+1 >= limit || (size_t)(t-token)+1 >= limit)) {
*t = '\0';
return -1;
}
if (c != '\0' && c != '\n') {
*t++ = c;
}
if (c == '\n') {
if (line_nr) {
*line_nr = *line_nr + 1;
}
only_blank = 1; /* Assume next line starts with
* <blank>.
*/
}
if (c == '\\' && prev_c == '\\')
prev_c = 0;
else prev_c = c;
@ -329,8 +369,8 @@ gldns_bget_token_par(gldns_buffer *b, char *token, const char *delim,
/* in parentheses */
/* do not write ' ' if we want to skip spaces */
if(!(skipw && (strchr(skipw, c)||strchr(skipw, ' ')))) {
/* check for space for the space character */
if (limit > 0 && (i >= limit || (size_t)(t-token) >= limit)) {
/* check for space for the space character and a zero delimiter after that. */
if (limit > 0 && (i+1 >= limit || (size_t)(t-token)+1 >= limit)) {
*t = '\0';
return -1;
}
@ -357,7 +397,7 @@ gldns_bget_token_par(gldns_buffer *b, char *token, const char *delim,
}
i++;
if (limit > 0 && (i >= limit || (size_t)(t-token) >= limit)) {
if (limit > 0 && (i+1 >= limit || (size_t)(t-token)+1 >= limit)) {
*t = '\0';
return -1;
}

View File

@ -153,7 +153,6 @@ int gldns_bgetc(struct gldns_buffer *buffer);
* the position to the first character that is not in *s.
* \param[in] *buffer buffer to use
* \param[in] *s characters to skip
* \return void
*/
void gldns_bskipcs(struct gldns_buffer *buffer, const char *s);
@ -162,7 +161,6 @@ void gldns_bskipcs(struct gldns_buffer *buffer, const char *s);
* the position to the first character that is not in *s.
* \param[in] *fp file to use
* \param[in] *s characters to skip
* \return void
*/
void gldns_fskipcs(FILE *fp, const char *s);
@ -173,7 +171,6 @@ void gldns_fskipcs(FILE *fp, const char *s);
* \param[in] *fp file to use
* \param[in] *s characters to skip
* \param[in] line_nr pointer to an integer containing the current line number (for debugging purposes)
* \return void
*/
void gldns_fskipcs_l(FILE *fp, const char *s, int *line_nr);

View File

@ -14,12 +14,8 @@
#include "config.h"
#include "gldns/parseutil.h"
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#ifdef HAVE_TIME_H
#include <time.h>
#endif
#include <ctype.h>
gldns_lookup_table *
@ -171,7 +167,7 @@ gldns_gmtime64_r(int64_t clock, struct tm *result)
static int64_t
gldns_serial_arithmetics_time(int32_t time, time_t now)
{
int32_t offset = time - (int32_t) now;
int32_t offset = (int32_t)((uint32_t) time - (uint32_t) now);
return (int64_t) now + offset;
}
@ -213,11 +209,13 @@ gldns_hexdigit_to_int(char ch)
}
uint32_t
gldns_str2period(const char *nptr, const char **endptr)
gldns_str2period(const char *nptr, const char **endptr, int* overflow)
{
int sign = 0;
uint32_t i = 0;
uint32_t seconds = 0;
const uint32_t maxint = 0xffffffff;
*overflow = 0;
for(*endptr = nptr; **endptr; (*endptr)++) {
switch (**endptr) {
@ -240,26 +238,46 @@ gldns_str2period(const char *nptr, const char **endptr)
break;
case 's':
case 'S':
if(seconds > maxint-i) {
*overflow = 1;
return 0;
}
seconds += i;
i = 0;
break;
case 'm':
case 'M':
if(i > maxint/60 || seconds > maxint-(i*60)) {
*overflow = 1;
return 0;
}
seconds += i * 60;
i = 0;
break;
case 'h':
case 'H':
if(i > maxint/(60*60) || seconds > maxint-(i*60*60)) {
*overflow = 1;
return 0;
}
seconds += i * 60 * 60;
i = 0;
break;
case 'd':
case 'D':
if(i > maxint/(60*60*24) || seconds > maxint-(i*60*60*24)) {
*overflow = 1;
return 0;
}
seconds += i * 60 * 60 * 24;
i = 0;
break;
case 'w':
case 'W':
if(i > maxint/(60*60*24*7) || seconds > maxint-(i*60*60*24*7)) {
*overflow = 1;
return 0;
}
seconds += i * 60 * 60 * 24 * 7;
i = 0;
break;
@ -273,15 +291,27 @@ gldns_str2period(const char *nptr, const char **endptr)
case '7':
case '8':
case '9':
if(i > maxint/10 || i*10 > maxint - (**endptr - '0')) {
*overflow = 1;
return 0;
}
i *= 10;
i += (**endptr - '0');
break;
default:
if(seconds > maxint-i) {
*overflow = 1;
return 0;
}
seconds += i;
/* disregard signedness */
return seconds;
}
}
if(seconds > maxint-i) {
*overflow = 1;
return 0;
}
seconds += i;
/* disregard signedness */
return seconds;
@ -623,13 +653,18 @@ size_t gldns_b64_ntop_calculate_size(size_t srcsize)
*
* This routine does not insert spaces or linebreaks after 76 characters.
*/
int gldns_b64_ntop(uint8_t const *src, size_t srclength,
char *target, size_t targsize)
static int gldns_b64_ntop_base(uint8_t const *src, size_t srclength,
char *target, size_t targsize, int base64url, int padding)
{
const char* b64 =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
char* b64;
const char pad64 = '=';
size_t i = 0, o = 0;
if(base64url)
b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123"
"456789-_";
else
b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123"
"456789+/";
if(targsize < gldns_b64_ntop_calculate_size(srclength))
return -1;
/* whole chunks: xxxxxxyy yyyyzzzz zzwwwwww */
@ -649,18 +684,26 @@ int gldns_b64_ntop(uint8_t const *src, size_t srclength,
target[o] = b64[src[i] >> 2];
target[o+1] = b64[ ((src[i]&0x03)<<4) | (src[i+1]>>4) ];
target[o+2] = b64[ ((src[i+1]&0x0f)<<2) ];
if(padding) {
target[o+3] = pad64;
/* i += 2; */
o += 4;
} else {
o += 3;
}
break;
case 1:
/* one at end, converted into A B = = */
target[o] = b64[src[i] >> 2];
target[o+1] = b64[ ((src[i]&0x03)<<4) ];
if(padding) {
target[o+2] = pad64;
target[o+3] = pad64;
/* i += 1; */
o += 4;
} else {
o += 2;
}
break;
case 0:
default:
@ -673,19 +716,36 @@ int gldns_b64_ntop(uint8_t const *src, size_t srclength,
return (int)o;
}
int gldns_b64_ntop(uint8_t const *src, size_t srclength, char *target,
size_t targsize)
{
return gldns_b64_ntop_base(src, srclength, target, targsize,
0 /* no base64url */, 1 /* padding */);
}
int gldns_b64url_ntop(uint8_t const *src, size_t srclength, char *target,
size_t targsize)
{
return gldns_b64_ntop_base(src, srclength, target, targsize,
1 /* base64url */, 0 /* no padding */);
}
size_t gldns_b64_pton_calculate_size(size_t srcsize)
{
return (((((srcsize + 3) / 4) * 3)) + 1);
}
int gldns_b64_pton(char const *src, uint8_t *target, size_t targsize)
/* padding not required if srcsize is set */
static int gldns_b64_pton_base(char const *src, size_t srcsize, uint8_t *target,
size_t targsize, int base64url)
{
const uint8_t pad64 = 64; /* is 64th in the b64 array */
const char* s = src;
uint8_t in[4];
size_t o = 0, incount = 0;
int check_padding = (srcsize) ? 0 : 1;
while(*s) {
while(*s && (check_padding || srcsize)) {
/* skip any character that is not base64 */
/* conceptually we do:
const char* b64 = pad'=' is appended to array
@ -694,30 +754,43 @@ int gldns_b64_pton(char const *src, uint8_t *target, size_t targsize)
and use d-b64;
*/
char d = *s++;
srcsize--;
if(d <= 'Z' && d >= 'A')
d -= 'A';
else if(d <= 'z' && d >= 'a')
d = d - 'a' + 26;
else if(d <= '9' && d >= '0')
d = d - '0' + 52;
else if(d == '+')
else if(!base64url && d == '+')
d = 62;
else if(d == '/')
else if(base64url && d == '-')
d = 62;
else if(!base64url && d == '/')
d = 63;
else if(d == '=')
d = 64;
else continue;
in[incount++] = (uint8_t)d;
if(incount != 4)
else if(base64url && d == '_')
d = 63;
else if(d == '=') {
if(!check_padding)
continue;
d = 64;
} else continue;
in[incount++] = (uint8_t)d;
/* work on block of 4, unless padding is not used and there are
* less than 4 chars left */
if(incount != 4 && (check_padding || srcsize))
continue;
assert(!check_padding || incount==4);
/* process whole block of 4 characters into 3 output bytes */
if(in[3] == pad64 && in[2] == pad64) { /* A B = = */
if((incount == 2 ||
(incount == 4 && in[3] == pad64 && in[2] == pad64))) { /* A B = = */
if(o+1 > targsize)
return -1;
target[o] = (in[0]<<2) | ((in[1]&0x30)>>4);
o += 1;
break; /* we are done */
} else if(in[3] == pad64) { /* A B C = */
} else if(incount == 3 ||
(incount == 4 && in[3] == pad64)) { /* A B C = */
if(o+2 > targsize)
return -1;
target[o] = (in[0]<<2) | ((in[1]&0x30)>>4);
@ -725,7 +798,7 @@ int gldns_b64_pton(char const *src, uint8_t *target, size_t targsize)
o += 2;
break; /* we are done */
} else {
if(o+3 > targsize)
if(incount != 4 || o+3 > targsize)
return -1;
/* write xxxxxxyy yyyyzzzz zzwwwwww */
target[o] = (in[0]<<2) | ((in[1]&0x30)>>4);
@ -737,3 +810,32 @@ int gldns_b64_pton(char const *src, uint8_t *target, size_t targsize)
}
return (int)o;
}
int gldns_b64_pton(char const *src, uint8_t *target, size_t targsize)
{
return gldns_b64_pton_base(src, 0, target, targsize, 0);
}
int gldns_b64url_pton(char const *src, size_t srcsize, uint8_t *target,
size_t targsize)
{
if(!srcsize) {
return 0;
}
return gldns_b64_pton_base(src, srcsize, target, targsize, 1);
}
int gldns_b64_contains_nonurl(char const *src, size_t srcsize)
{
const char* s = src;
while(*s && srcsize) {
char d = *s++;
srcsize--;
/* the '+' and the '/' and padding '=' is not allowed in b64
* url encoding */
if(d == '+' || d == '/' || d == '=') {
return 1;
}
}
return 0;
}

View File

@ -58,7 +58,7 @@ time_t gldns_mktime_from_utc(const struct tm *tm);
* The function interprets time as the number of seconds since epoch
* with respect to now using serial arithmetics (rfc1982).
* That number of seconds is then converted to broken-out time information.
* This is especially usefull when converting the inception and expiration
* This is especially useful when converting the inception and expiration
* fields of RRSIG records.
*
* \param[in] time number of seconds since epoch (midnight, January 1st, 1970)
@ -74,9 +74,11 @@ struct tm * gldns_serial_arithmetics_gmtime_r(int32_t time, time_t now, struct t
* converts a ttl value (like 5d2h) to a long.
* \param[in] nptr the start of the string
* \param[out] endptr points to the last char in case of error
* \param[out] overflow returns if the string causes integer overflow error,
* the number is too big, string of digits too long.
* \return the convert duration value
*/
uint32_t gldns_str2period(const char *nptr, const char **endptr);
uint32_t gldns_str2period(const char *nptr, const char **endptr, int* overflow);
/**
* Returns the int value of the given (hex) digit
@ -92,13 +94,17 @@ size_t gldns_b64_ntop_calculate_size(size_t srcsize);
int gldns_b64_ntop(uint8_t const *src, size_t srclength,
char *target, size_t targsize);
int gldns_b64url_ntop(uint8_t const *src, size_t srclength, char *target,
size_t targsize);
/**
* calculates the size needed to store the result of gldns_b64_pton
*/
size_t gldns_b64_pton_calculate_size(size_t srcsize);
int gldns_b64_pton(char const *src, uint8_t *target, size_t targsize);
int gldns_b64url_pton(char const *src, size_t srcsize, uint8_t *target,
size_t targsize);
int gldns_b64_contains_nonurl(char const *src, size_t srcsize);
/**
* calculates the size needed to store the result of b32_ntop

View File

@ -97,18 +97,22 @@ extern "C" {
#define QDCOUNT(wirebuf) (ntohs(*(uint16_t *)(wirebuf+QDCOUNT_OFF)))
*/
#define GLDNS_QDCOUNT(wirebuf) (gldns_read_uint16(wirebuf+GLDNS_QDCOUNT_OFF))
#define GLDNS_QDCOUNT_SET(wirebuf, i) (gldns_write_uint16(wirebuf+GLDNS_QDCOUNT_OFF, i))
/* Counter of the answer section */
#define GLDNS_ANCOUNT_OFF 6
#define GLDNS_ANCOUNT(wirebuf) (gldns_read_uint16(wirebuf+GLDNS_ANCOUNT_OFF))
#define GLDNS_ANCOUNT_SET(wirebuf, i) (gldns_write_uint16(wirebuf+GLDNS_ANCOUNT_OFF, i))
/* Counter of the authority section */
#define GLDNS_NSCOUNT_OFF 8
#define GLDNS_NSCOUNT(wirebuf) (gldns_read_uint16(wirebuf+GLDNS_NSCOUNT_OFF))
#define GLDNS_NSCOUNT_SET(wirebuf, i) (gldns_write_uint16(wirebuf+GLDNS_NSCOUNT_OFF, i))
/* Counter of the additional section */
#define GLDNS_ARCOUNT_OFF 10
#define GLDNS_ARCOUNT(wirebuf) (gldns_read_uint16(wirebuf+GLDNS_ARCOUNT_OFF))
#define GLDNS_ARCOUNT_SET(wirebuf, i) (gldns_write_uint16(wirebuf+GLDNS_ARCOUNT_OFF, i))
/**
* The sections of a packet

View File

@ -155,6 +155,9 @@ static const gldns_rdf_type type_csync_wireformat[] = {
static const gldns_rdf_type type_zonemd_wireformat[] = {
GLDNS_RDF_TYPE_INT32, GLDNS_RDF_TYPE_INT8, GLDNS_RDF_TYPE_INT8, GLDNS_RDF_TYPE_HEX
};
static const gldns_rdf_type type_svcb_wireformat[] = {
GLDNS_RDF_TYPE_INT16, GLDNS_RDF_TYPE_DNAME
};
/* nsec3 is some vars, followed by same type of data of nsec */
static const gldns_rdf_type type_nsec3_wireformat[] = {
/* GLDNS_RDF_TYPE_NSEC3_VARS, GLDNS_RDF_TYPE_NSEC3_NEXT_OWNER, GLDNS_RDF_TYPE_NSEC*/
@ -388,8 +391,10 @@ static gldns_rr_descriptor rdata_field_descriptors[] = {
{GLDNS_RR_TYPE_CSYNC, "CSYNC", 3, 3, type_csync_wireformat, GLDNS_RDF_TYPE_NONE, GLDNS_RR_NO_COMPRESS, 0 },
/* 63 */
{GLDNS_RR_TYPE_ZONEMD, "ZONEMD", 4, 4, type_zonemd_wireformat, GLDNS_RDF_TYPE_NONE, GLDNS_RR_NO_COMPRESS, 0 },
{(enum gldns_enum_rr_type)0, "TYPE64", 1, 1, type_0_wireformat, GLDNS_RDF_TYPE_NONE, GLDNS_RR_NO_COMPRESS, 0 },
{(enum gldns_enum_rr_type)0, "TYPE65", 1, 1, type_0_wireformat, GLDNS_RDF_TYPE_NONE, GLDNS_RR_NO_COMPRESS, 0 },
/* 64 */
{GLDNS_RR_TYPE_SVCB, "SVCB", 2, 2, type_svcb_wireformat, GLDNS_RDF_TYPE_SVCPARAM, GLDNS_RR_NO_COMPRESS, 1 },
/* 65 */
{GLDNS_RR_TYPE_HTTPS, "HTTPS", 2, 2, type_svcb_wireformat, GLDNS_RDF_TYPE_SVCPARAM, GLDNS_RR_NO_COMPRESS, 1 },
{(enum gldns_enum_rr_type)0, "TYPE66", 1, 1, type_0_wireformat, GLDNS_RDF_TYPE_NONE, GLDNS_RR_NO_COMPRESS, 0 },
{(enum gldns_enum_rr_type)0, "TYPE67", 1, 1, type_0_wireformat, GLDNS_RDF_TYPE_NONE, GLDNS_RR_NO_COMPRESS, 0 },
{(enum gldns_enum_rr_type)0, "TYPE68", 1, 1, type_0_wireformat, GLDNS_RDF_TYPE_NONE, GLDNS_RR_NO_COMPRESS, 0 },

View File

@ -195,7 +195,9 @@ enum gldns_enum_rr_type
GLDNS_RR_TYPE_CDNSKEY = 60, /** RFC 7344 */
GLDNS_RR_TYPE_OPENPGPKEY = 61, /* RFC 7929 */
GLDNS_RR_TYPE_CSYNC = 62, /* RFC 7477 */
GLDNS_RR_TYPE_ZONEMD = 63, /* draft-wessels-dns-zone-digest */
GLDNS_RR_TYPE_ZONEMD = 63, /* RFC8976 */
GLDNS_RR_TYPE_SVCB = 64, /* draft-ietf-dnsop-svcb-https-04 */
GLDNS_RR_TYPE_HTTPS = 65, /* draft-ietf-dnsop-svcb-https-04 */
GLDNS_RR_TYPE_SPF = 99, /* RFC 4408 */
@ -358,8 +360,13 @@ enum gldns_enum_rdf_type
/** TSIG extended 16bit error value */
GLDNS_RDF_TYPE_TSIGERROR,
/* draft-ietf-dnsop-svcb-https-05:
* each SvcParam consisting of a SvcParamKey=SvcParamValue pair or
* a standalone SvcParamKey */
GLDNS_RDF_TYPE_SVCPARAM,
/* Aliases */
GLDNS_RDF_TYPE_BITMAP = GLDNS_RDF_TYPE_NSEC
GLDNS_RDF_TYPE_BITMAP = GLDNS_RDF_TYPE_NSEC,
};
typedef enum gldns_enum_rdf_type gldns_rdf_type;
@ -432,10 +439,43 @@ enum gldns_enum_edns_option
GLDNS_EDNS_N3U = 7, /* RFC6975 */
GLDNS_EDNS_CLIENT_SUBNET = 8, /* RFC7871 */
GLDNS_EDNS_KEEPALIVE = 11, /* draft-ietf-dnsop-edns-tcp-keepalive*/
GLDNS_EDNS_PADDING = 12 /* RFC7830 */
GLDNS_EDNS_PADDING = 12, /* RFC7830 */
GLDNS_EDNS_EDE = 15, /* RFC8914 */
GLDNS_EDNS_CLIENT_TAG = 16 /* draft-bellis-dnsop-edns-tags-01 */
};
typedef enum gldns_enum_edns_option gldns_edns_option;
enum gldns_enum_ede_code
{
GLDNS_EDE_NONE = -1, /* EDE undefined for internal use */
GLDNS_EDE_OTHER = 0,
GLDNS_EDE_UNSUPPORTED_DNSKEY_ALG = 1,
GLDNS_EDE_UNSUPPORTED_DS_DIGEST = 2,
GLDNS_EDE_STALE_ANSWER = 3,
GLDNS_EDE_FORGED_ANSWER = 4,
GLDNS_EDE_DNSSEC_INDETERMINATE = 5,
GLDNS_EDE_DNSSEC_BOGUS = 6,
GLDNS_EDE_SIGNATURE_EXPIRED = 7,
GLDNS_EDE_SIGNATURE_NOT_YET_VALID = 8,
GLDNS_EDE_DNSKEY_MISSING = 9,
GLDNS_EDE_RRSIGS_MISSING = 10,
GLDNS_EDE_NO_ZONE_KEY_BIT_SET = 11,
GLDNS_EDE_NSEC_MISSING = 12,
GLDNS_EDE_CACHED_ERROR = 13,
GLDNS_EDE_NOT_READY = 14,
GLDNS_EDE_BLOCKED = 15,
GLDNS_EDE_CENSORED = 16,
GLDNS_EDE_FILTERED = 17,
GLDNS_EDE_PROHIBITED = 18,
GLDNS_EDE_STALE_NXDOMAIN_ANSWER = 19,
GLDNS_EDE_NOT_AUTHORITATIVE = 20,
GLDNS_EDE_NOT_SUPPORTED = 21,
GLDNS_EDE_NO_REACHABLE_AUTHORITY = 22,
GLDNS_EDE_NETWORK_ERROR = 23,
GLDNS_EDE_INVALID_DATA = 24,
};
typedef enum gldns_enum_ede_code gldns_ede_code;
#define GLDNS_EDNS_MASK_DO_BIT 0x8000
/** TSIG and TKEY extended rcodes (16bit), 0-15 are the normal rcodes. */

View File

@ -26,11 +26,12 @@
#endif
#include <stdlib.h>
/** bits for the offset */
#define RET_OFFSET_MASK (((unsigned)(~GLDNS_WIREPARSE_MASK))>>GLDNS_WIREPARSE_SHIFT)
/** return an error */
#define RET_ERR(e, off) ((int)((e)|((off)<<GLDNS_WIREPARSE_SHIFT)))
#define RET_ERR(e, off) ((int)(((e)&GLDNS_WIREPARSE_MASK)|(((off)&RET_OFFSET_MASK)<<GLDNS_WIREPARSE_SHIFT)))
/** Move parse error but keep its ID */
#define RET_ERR_SHIFT(e, move) RET_ERR(GLDNS_WIREPARSE_ERROR(e), GLDNS_WIREPARSE_OFFSET(e)+(move));
#define GLDNS_IP6ADDRLEN (128/8)
/*
* No special care is taken, all dots are translated into
@ -81,7 +82,7 @@ static int gldns_str2wire_dname_buf_rel(const char* str, uint8_t* buf,
for (s = str; *s; s++, q++) {
if (q >= buf + *olen)
return RET_ERR(GLDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL, q-buf);
if (q > buf + GLDNS_MAX_DOMAINLEN)
if (q >= buf + GLDNS_MAX_DOMAINLEN)
return RET_ERR(GLDNS_WIREPARSE_ERR_DOMAINNAME_OVERFLOW, q-buf);
switch (*s) {
case '.':
@ -118,7 +119,7 @@ static int gldns_str2wire_dname_buf_rel(const char* str, uint8_t* buf,
if(rel) *rel = 1;
if (q >= buf + *olen)
return RET_ERR(GLDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL, q-buf);
if (q > buf + GLDNS_MAX_DOMAINLEN) {
if (q >= buf + GLDNS_MAX_DOMAINLEN) {
return RET_ERR(GLDNS_WIREPARSE_ERR_DOMAINNAME_OVERFLOW, q-buf);
}
if (label_len > GLDNS_MAX_LABELLEN) {
@ -249,11 +250,16 @@ rrinternal_get_ttl(gldns_buffer* strbuf, char* token, size_t token_len,
int* not_there, uint32_t* ttl, uint32_t default_ttl)
{
const char* endptr;
int overflow;
if(gldns_bget_token(strbuf, token, "\t\n ", token_len) == -1) {
return RET_ERR(GLDNS_WIREPARSE_ERR_SYNTAX_TTL,
gldns_buffer_position(strbuf));
}
*ttl = (uint32_t) gldns_str2period(token, &endptr);
*ttl = (uint32_t) gldns_str2period(token, &endptr, &overflow);
if(overflow) {
return RET_ERR(GLDNS_WIREPARSE_ERR_SYNTAX_INTEGER_OVERFLOW,
gldns_buffer_position(strbuf));
}
if (strlen(token) > 0 && !isdigit((unsigned char)token[0])) {
*not_there = 1;
@ -373,7 +379,8 @@ rrinternal_get_quoted(gldns_buffer* strbuf, const char** delimiters,
/* skip spaces */
while(gldns_buffer_remaining(strbuf) > 0 &&
*(gldns_buffer_current(strbuf)) == ' ') {
(*(gldns_buffer_current(strbuf)) == ' ' ||
*(gldns_buffer_current(strbuf)) == '\t')) {
gldns_buffer_skip(strbuf, 1);
}
@ -545,9 +552,10 @@ gldns_parse_rdf_token(gldns_buffer* strbuf, char* token, size_t token_len,
{
size_t slen;
/* skip spaces */
/* skip spaces and tabs */
while(gldns_buffer_remaining(strbuf) > 0 && !*quoted &&
*(gldns_buffer_current(strbuf)) == ' ') {
(*(gldns_buffer_current(strbuf)) == ' ' ||
*(gldns_buffer_current(strbuf)) == '\t')) {
gldns_buffer_skip(strbuf, 1);
}
@ -603,7 +611,10 @@ gldns_affix_token(gldns_buffer* strbuf, char* token, size_t* token_len,
size_t addstrlen = 0;
/* add space */
if(addlen < 1) return 0;
/* when addlen < 2, the token buffer is full considering the NULL byte
* from strlen and will lead to buffer overflow with the second
* assignment below. */
if(addlen < 2) return 0;
token[*token_strlen] = ' ';
token[++(*token_strlen)] = 0;
@ -616,6 +627,122 @@ gldns_affix_token(gldns_buffer* strbuf, char* token, size_t* token_len,
return 1;
}
static int gldns_str2wire_svcparam_key_cmp(const void *a, const void *b)
{
return gldns_read_uint16(*(uint8_t**) a)
- gldns_read_uint16(*(uint8_t**) b);
}
/**
* Add constraints to the SVCB RRs which involve the whole set
*/
static int gldns_str2wire_check_svcbparams(uint8_t* rdata, uint16_t rdata_len)
{
size_t nparams = 0, i;
uint8_t new_rdata[GLDNS_MAX_RDFLEN];
uint8_t* new_rdata_ptr = new_rdata;
uint8_t* svcparams[MAX_NUMBER_OF_SVCPARAMS];
uint8_t* rdata_ptr = rdata;
uint16_t rdata_remaining = rdata_len;
/* find the SvcParams */
while (rdata_remaining) {
uint16_t svcbparam_len;
svcparams[nparams] = rdata_ptr;
if (rdata_remaining < 4)
return GLDNS_WIREPARSE_ERR_SVCPARAM_BROKEN_RDATA;
svcbparam_len = gldns_read_uint16(rdata_ptr + 2);
rdata_remaining -= 4;
rdata_ptr += 4;
if (rdata_remaining < svcbparam_len)
return GLDNS_WIREPARSE_ERR_SVCPARAM_BROKEN_RDATA;
rdata_remaining -= svcbparam_len;
rdata_ptr += svcbparam_len;
nparams += 1;
if (nparams >= MAX_NUMBER_OF_SVCPARAMS)
return GLDNS_WIREPARSE_ERR_SVCB_TOO_MANY_PARAMS;
}
/* In draft-ietf-dnsop-svcb-https-06 Section 7:
*
* In wire format, the keys are represented by their numeric
* values in network byte order, concatenated in ascending order.
*/
qsort((void *)svcparams
,nparams
,sizeof(uint8_t*)
,gldns_str2wire_svcparam_key_cmp);
/* The code below revolves around semantic errors in the SVCParam set.
* So long as we do not distinguish between running Unbound as a primary
* or as a secondary, we default to secondary behavior and we ignore the
* semantic errors. */
#ifdef SVCB_SEMANTIC_ERRORS
{
uint8_t* mandatory = NULL;
/* In draft-ietf-dnsop-svcb-https-06 Section 7:
*
* Keys (...) MUST NOT appear more than once.
*
* If they key has already been seen, we have a duplicate
*/
for(i=0; i < nparams; i++) {
uint16_t key = gldns_read_uint16(svcparams[i]);
if(i + 1 < nparams && key == gldns_read_uint16(svcparams[i+1]))
return GLDNS_WIREPARSE_ERR_SVCB_DUPLICATE_KEYS;
if(key == SVCB_KEY_MANDATORY)
mandatory = svcparams[i];
}
/* 4. verify that all the SvcParamKeys in mandatory are present */
if(mandatory) {
/* Divide by sizeof(uint16_t)*/
uint16_t mandatory_nkeys = gldns_read_uint16(mandatory + 2) / sizeof(uint16_t);
/* Guaranteed by gldns_str2wire_svcparam_key_value */
assert(mandatory_nkeys > 0);
for(i=0; i < mandatory_nkeys; i++) {
uint16_t mandatory_key = gldns_read_uint16(
mandatory
+ 2 * sizeof(uint16_t)
+ i * sizeof(uint16_t));
uint8_t found = 0;
size_t j;
for(j=0; j < nparams; j++) {
if(mandatory_key == gldns_read_uint16(svcparams[j])) {
found = 1;
break;
}
}
if(!found)
return GLDNS_WIREPARSE_ERR_SVCB_MANDATORY_MISSING_PARAM;
}
}
}
#endif
/* Write rdata in correct order */
for (i = 0; i < nparams; i++) {
uint16_t svcparam_len = gldns_read_uint16(svcparams[i] + 2)
+ 2 * sizeof(uint16_t);
if ((unsigned)(new_rdata_ptr - new_rdata) + svcparam_len > sizeof(new_rdata))
return GLDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
memcpy(new_rdata_ptr, svcparams[i], svcparam_len);
new_rdata_ptr += svcparam_len;
}
memcpy(rdata, new_rdata, rdata_len);
return GLDNS_WIREPARSE_ERR_OK;
}
/** parse rdata from string into rr buffer(-remainder after dname). */
static int
rrinternal_parse_rdata(gldns_buffer* strbuf, char* token, size_t token_len,
@ -655,7 +782,8 @@ rrinternal_parse_rdata(gldns_buffer* strbuf, char* token, size_t token_len,
/* unknown RR data */
if(token_strlen>=2 && strncmp(token, "\\#", 2) == 0 &&
!quoted && (token_strlen == 2 || token[2]==' ')) {
!quoted && (token_strlen == 2 || token[2]==' ' ||
token[2]=='\t')) {
was_unknown_rr_format = 1;
if((status=rrinternal_parse_unknown(strbuf, token,
token_len, rr, rr_len, &rr_cur_len,
@ -713,6 +841,42 @@ rrinternal_parse_rdata(gldns_buffer* strbuf, char* token, size_t token_len,
/* write rdata length */
gldns_write_uint16(rr+dname_len+8, (uint16_t)(rr_cur_len-dname_len-10));
*rr_len = rr_cur_len;
/* SVCB/HTTPS handling */
if (rr_type == GLDNS_RR_TYPE_SVCB || rr_type == GLDNS_RR_TYPE_HTTPS) {
size_t rdata_len = rr_cur_len - dname_len - 10;
uint8_t *rdata = rr+dname_len + 10;
/* skip 1st rdata field SvcPriority (uint16_t) */
if (rdata_len < sizeof(uint16_t))
return GLDNS_WIREPARSE_ERR_OK;
rdata_len -= sizeof(uint16_t);
rdata += sizeof(uint16_t);
/* skip 2nd rdata field dname */
while (rdata_len && *rdata != 0) {
uint8_t label_len;
if (*rdata & 0xC0)
return GLDNS_WIREPARSE_ERR_OK;
label_len = *rdata + 1;
if (rdata_len < label_len)
return GLDNS_WIREPARSE_ERR_OK;
rdata_len -= label_len;
rdata += label_len;
}
/* The root label is one more character, so smaller
* than 1 + 1 means no Svcparam Keys */
if (rdata_len < 2 || *rdata != 0)
return GLDNS_WIREPARSE_ERR_OK;
rdata_len -= 1;
rdata += 1;
return gldns_str2wire_check_svcbparams(rdata, rdata_len);
}
return GLDNS_WIREPARSE_ERR_OK;
}
@ -737,7 +901,7 @@ gldns_str2wire_rr_buf_internal(const char* str, uint8_t* rr, size_t* len,
{
int status;
int not_there = 0;
char token[GLDNS_MAX_RDFLEN+1] = "";
char token[GLDNS_MAX_RDFLEN+1];
uint32_t ttl = 0;
uint16_t tp = 0, cl = 0;
size_t ddlen = 0;
@ -899,12 +1063,15 @@ int gldns_fp2wire_rr_buf(FILE* in, uint8_t* rr, size_t* len, size_t* dname_len,
return s;
} else if(strncmp(line, "$TTL", 4) == 0 && isspace((unsigned char)line[4])) {
const char* end = NULL;
int overflow = 0;
strlcpy((char*)rr, line, *len);
*len = 0;
*dname_len = 0;
if(!parse_state) return GLDNS_WIREPARSE_ERR_OK;
parse_state->default_ttl = gldns_str2period(
gldns_strip_ws(line+5), &end);
gldns_strip_ws(line+5), &end, &overflow);
if(overflow)
return GLDNS_WIREPARSE_ERR_SYNTAX_INTEGER_OVERFLOW;
} else if (strncmp(line, "$INCLUDE", 8) == 0) {
strlcpy((char*)rr, line, *len);
*len = 0;
@ -930,11 +1097,533 @@ int gldns_fp2wire_rr_buf(FILE* in, uint8_t* rr, size_t* len, size_t* dname_len,
memmove(parse_state->prev_rr, rr, *dname_len);
parse_state->prev_rr_len = (*dname_len);
}
if(r == GLDNS_WIREPARSE_ERR_OK && parse_state) {
parse_state->default_ttl = gldns_wirerr_get_ttl(
rr, *len, *dname_len);
}
return r;
}
return GLDNS_WIREPARSE_ERR_OK;
}
static int
gldns_str2wire_svcparam_key_lookup(const char *key, size_t key_len)
{
char buf[64];
char *endptr;
unsigned long int key_value;
if (key_len >= 4 && key_len <= 8 && !strncmp(key, "key", 3)) {
memcpy(buf, key + 3, key_len - 3);
buf[key_len - 3] = 0;
key_value = strtoul(buf, &endptr, 10);
if (endptr > buf /* digits seen */
&& *endptr == 0 /* no non-digit chars after digits */
&& key_value <= 65535) /* no overflow */
return key_value;
} else switch (key_len) {
case sizeof("mandatory")-1:
if (!strncmp(key, "mandatory", sizeof("mandatory")-1))
return SVCB_KEY_MANDATORY;
if (!strncmp(key, "echconfig", sizeof("echconfig")-1))
return SVCB_KEY_ECH; /* allow "echconfig" as well as "ech" */
break;
case sizeof("alpn")-1:
if (!strncmp(key, "alpn", sizeof("alpn")-1))
return SVCB_KEY_ALPN;
if (!strncmp(key, "port", sizeof("port")-1))
return SVCB_KEY_PORT;
break;
case sizeof("no-default-alpn")-1:
if (!strncmp( key , "no-default-alpn"
, sizeof("no-default-alpn")-1))
return SVCB_KEY_NO_DEFAULT_ALPN;
break;
case sizeof("ipv4hint")-1:
if (!strncmp(key, "ipv4hint", sizeof("ipv4hint")-1))
return SVCB_KEY_IPV4HINT;
if (!strncmp(key, "ipv6hint", sizeof("ipv6hint")-1))
return SVCB_KEY_IPV6HINT;
break;
case sizeof("ech")-1:
if (!strncmp(key, "ech", sizeof("ech")-1))
return SVCB_KEY_ECH;
break;
default:
break;
}
/* Although the returned value might be used by the caller,
* the parser has erred, so the zone will not be loaded.
*/
return -1;
}
static int
gldns_str2wire_svcparam_port(const char* val, uint8_t* rd, size_t* rd_len)
{
unsigned long int port;
char *endptr;
if (*rd_len < 6)
return GLDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
port = strtoul(val, &endptr, 10);
if (endptr > val /* digits seen */
&& *endptr == 0 /* no non-digit chars after digits */
&& port <= 65535) { /* no overflow */
gldns_write_uint16(rd, SVCB_KEY_PORT);
gldns_write_uint16(rd + 2, sizeof(uint16_t));
gldns_write_uint16(rd + 4, port);
*rd_len = 6;
return GLDNS_WIREPARSE_ERR_OK;
}
return GLDNS_WIREPARSE_ERR_SVCB_PORT_VALUE_SYNTAX;
}
static int
gldns_str2wire_svcbparam_ipv4hint(const char* val, uint8_t* rd, size_t* rd_len)
{
size_t count;
char ip_str[INET_ADDRSTRLEN+1];
char *next_ip_str;
size_t i;
for (i = 0, count = 1; val[i]; i++) {
if (val[i] == ',')
count += 1;
if (count > SVCB_MAX_COMMA_SEPARATED_VALUES) {
return GLDNS_WIREPARSE_ERR_SVCB_IPV4_TOO_MANY_ADDRESSES;
}
}
if (*rd_len < (GLDNS_IP4ADDRLEN * count) + 4)
return GLDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
/* count is number of comma's in val + 1; so the actual number of IPv4
* addresses in val
*/
gldns_write_uint16(rd, SVCB_KEY_IPV4HINT);
gldns_write_uint16(rd + 2, GLDNS_IP4ADDRLEN * count);
*rd_len = 4;
while (count) {
if (!(next_ip_str = strchr(val, ','))) {
if (inet_pton(AF_INET, val, rd + *rd_len) != 1)
break;
*rd_len += GLDNS_IP4ADDRLEN;
assert(count == 1);
} else if (next_ip_str - val >= (int)sizeof(ip_str))
break;
else {
memcpy(ip_str, val, next_ip_str - val);
ip_str[next_ip_str - val] = 0;
if (inet_pton(AF_INET, ip_str, rd + *rd_len) != 1) {
break;
}
*rd_len += GLDNS_IP4ADDRLEN;
val = next_ip_str + 1;
}
count--;
}
if (count) /* verify that we parsed all values */
return GLDNS_WIREPARSE_ERR_SYNTAX_IP4;
return GLDNS_WIREPARSE_ERR_OK;
}
static int
gldns_str2wire_svcbparam_ipv6hint(const char* val, uint8_t* rd, size_t* rd_len)
{
size_t count;
char ip_str[INET6_ADDRSTRLEN+1];
char *next_ip_str;
size_t i;
for (i = 0, count = 1; val[i]; i++) {
if (val[i] == ',')
count += 1;
if (count > SVCB_MAX_COMMA_SEPARATED_VALUES) {
return GLDNS_WIREPARSE_ERR_SVCB_IPV6_TOO_MANY_ADDRESSES;
}
}
if (*rd_len < (GLDNS_IP6ADDRLEN * count) + 4)
return GLDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
/* count is number of comma's in val + 1; so the actual number of IPv6
* addresses in val
*/
gldns_write_uint16(rd, SVCB_KEY_IPV6HINT);
gldns_write_uint16(rd + 2, GLDNS_IP6ADDRLEN * count);
*rd_len = 4;
while (count) {
if (!(next_ip_str = strchr(val, ','))) {
if (inet_pton(AF_INET6, val, rd + *rd_len) != 1)
break;
*rd_len += GLDNS_IP6ADDRLEN;
assert(count == 1);
} else if (next_ip_str - val >= (int)sizeof(ip_str))
break;
else {
memcpy(ip_str, val, next_ip_str - val);
ip_str[next_ip_str - val] = 0;
if (inet_pton(AF_INET6, ip_str, rd + *rd_len) != 1) {
break;
}
*rd_len += GLDNS_IP6ADDRLEN;
val = next_ip_str + 1;
}
count--;
}
if (count) /* verify that we parsed all values */
return GLDNS_WIREPARSE_ERR_SYNTAX_IP6;
return GLDNS_WIREPARSE_ERR_OK;
}
/* compare function used for sorting uint16_t's */
static int
gldns_network_uint16_cmp(const void *a, const void *b)
{
return ((int)gldns_read_uint16(a)) - ((int)gldns_read_uint16(b));
}
static int
gldns_str2wire_svcbparam_mandatory(const char* val, uint8_t* rd, size_t* rd_len)
{
size_t i, count, val_len;
char* next_key;
val_len = strlen(val);
for (i = 0, count = 1; val[i]; i++) {
if (val[i] == ',')
count += 1;
if (count > SVCB_MAX_COMMA_SEPARATED_VALUES) {
return GLDNS_WIREPARSE_ERR_SVCB_MANDATORY_TOO_MANY_KEYS;
}
}
if (sizeof(uint16_t) * (count + 2) > *rd_len)
return GLDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
gldns_write_uint16(rd, SVCB_KEY_MANDATORY);
gldns_write_uint16(rd + 2, sizeof(uint16_t) * count);
*rd_len = 4;
while (1) {
int svcparamkey;
if (!(next_key = strchr(val, ','))) {
svcparamkey = gldns_str2wire_svcparam_key_lookup(val, val_len);
if (svcparamkey < 0) {
return GLDNS_WIREPARSE_ERR_SVCB_UNKNOWN_KEY;
}
gldns_write_uint16(rd + *rd_len, svcparamkey);
*rd_len += 2;
break;
} else {
svcparamkey = gldns_str2wire_svcparam_key_lookup(val, next_key - val);
if (svcparamkey < 0) {
return GLDNS_WIREPARSE_ERR_SVCB_UNKNOWN_KEY;
}
gldns_write_uint16(rd + *rd_len,
svcparamkey);
*rd_len += 2;
}
val_len -= next_key - val + 1;
val = next_key + 1; /* skip the comma */
}
/* In draft-ietf-dnsop-svcb-https-06 Section 7:
*
* "In wire format, the keys are represented by their numeric
* values in network byte order, concatenated in ascending order."
*/
qsort((void *)(rd + 4), count, sizeof(uint16_t), gldns_network_uint16_cmp);
/* The code below revolves around semantic errors in the SVCParam set.
* So long as we do not distinguish between running Unbound as a primary
* or as a secondary, we default to secondary behavior and we ignore the
* semantic errors. */
#ifdef SVCB_SEMANTIC_ERRORS
/* In draft-ietf-dnsop-svcb-https-06 Section 8
* automatically mandatory MUST NOT appear in its own value-list
*/
if (gldns_read_uint16(rd + 4) == SVCB_KEY_MANDATORY)
return GLDNS_WIREPARSE_ERR_SVCB_MANDATORY_IN_MANDATORY;
/* Guarantee key uniqueness. After the sort we only need to
* compare neighbouring keys */
if (count > 1) {
for (i = 0; i < count - 1; i++) {
uint8_t* current_pos = (rd + 4 + (sizeof(uint16_t) * i));
uint16_t key = gldns_read_uint16(current_pos);
if (key == gldns_read_uint16(current_pos + 2)) {
return GLDNS_WIREPARSE_ERR_SVCB_MANDATORY_DUPLICATE_KEY;
}
}
}
#endif
return GLDNS_WIREPARSE_ERR_OK;
}
static int
gldns_str2wire_svcbparam_ech_value(const char* val, uint8_t* rd, size_t* rd_len)
{
uint8_t buffer[GLDNS_MAX_RDFLEN];
int wire_len;
/* single 0 represents empty buffer */
if(strcmp(val, "0") == 0) {
if (*rd_len < 4)
return GLDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
gldns_write_uint16(rd, SVCB_KEY_ECH);
gldns_write_uint16(rd + 2, 0);
return GLDNS_WIREPARSE_ERR_OK;
}
wire_len = gldns_b64_pton(val, buffer, GLDNS_MAX_RDFLEN);
if (wire_len <= 0) {
return GLDNS_WIREPARSE_ERR_SYNTAX_B64;
} else if ((unsigned)wire_len + 4 > *rd_len) {
return GLDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
} else {
gldns_write_uint16(rd, SVCB_KEY_ECH);
gldns_write_uint16(rd + 2, wire_len);
memcpy(rd + 4, buffer, wire_len);
*rd_len = 4 + wire_len;
return GLDNS_WIREPARSE_ERR_OK;
}
}
static const char*
gldns_str2wire_svcbparam_parse_next_unescaped_comma(const char *val)
{
while (*val) {
/* Only return when the comma is not escaped*/
if (*val == '\\'){
++val;
if (!*val)
break;
} else if (*val == ',')
return val;
val++;
}
return NULL;
}
/* The source is already properly unescaped, this double unescaping is purely to allow for
* comma's in comma separated alpn lists.
*
* In draft-ietf-dnsop-svcb-https-06 Section 7:
* To enable simpler parsing, this SvcParamValue MUST NOT contain escape sequences.
*/
static size_t
gldns_str2wire_svcbparam_parse_copy_unescaped(uint8_t *dst,
const char *src, size_t len)
{
uint8_t *orig_dst = dst;
while (len) {
if (*src == '\\') {
src++;
len--;
if (!len)
break;
}
*dst++ = *src++;
len--;
}
return (size_t)(dst - orig_dst);
}
static int
gldns_str2wire_svcbparam_alpn_value(const char* val,
uint8_t* rd, size_t* rd_len)
{
uint8_t unescaped_dst[GLDNS_MAX_RDFLEN];
uint8_t *dst = unescaped_dst;
const char *next_str;
size_t str_len;
size_t dst_len;
size_t val_len;
val_len = strlen(val);
if (val_len > sizeof(unescaped_dst)) {
return GLDNS_WIREPARSE_ERR_SVCB_ALPN_KEY_TOO_LARGE;
}
while (val_len) {
size_t key_len;
str_len = (next_str = gldns_str2wire_svcbparam_parse_next_unescaped_comma(val))
? (size_t)(next_str - val) : val_len;
if (str_len > 255) {
return GLDNS_WIREPARSE_ERR_SVCB_ALPN_KEY_TOO_LARGE;
}
key_len = gldns_str2wire_svcbparam_parse_copy_unescaped(dst + 1, val, str_len);
*dst++ = key_len;
dst += key_len;
if (!next_str)
break;
/* skip the comma in the next iteration */
val_len -= next_str - val + 1;
val = next_str + 1;
}
dst_len = dst - unescaped_dst;
if (*rd_len < 4 + dst_len)
return GLDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
gldns_write_uint16(rd, SVCB_KEY_ALPN);
gldns_write_uint16(rd + 2, dst_len);
memcpy(rd + 4, unescaped_dst, dst_len);
*rd_len = 4 + dst_len;
return GLDNS_WIREPARSE_ERR_OK;
}
static int
gldns_str2wire_svcparam_value(const char *key, size_t key_len,
const char *val, uint8_t* rd, size_t* rd_len)
{
size_t str_len;
int svcparamkey = gldns_str2wire_svcparam_key_lookup(key, key_len);
if (svcparamkey < 0) {
return GLDNS_WIREPARSE_ERR_SVCB_UNKNOWN_KEY;
}
/* key without value */
if (val == NULL) {
switch (svcparamkey) {
#ifdef SVCB_SEMANTIC_ERRORS
case SVCB_KEY_MANDATORY:
case SVCB_KEY_ALPN:
case SVCB_KEY_PORT:
case SVCB_KEY_IPV4HINT:
case SVCB_KEY_IPV6HINT:
return GLDNS_WIREPARSE_ERR_SVCB_MISSING_PARAM;
#endif
default:
if (*rd_len < 4)
return GLDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
gldns_write_uint16(rd, svcparamkey);
gldns_write_uint16(rd + 2, 0);
*rd_len = 4;
return GLDNS_WIREPARSE_ERR_OK;
}
}
/* value is non-empty */
switch (svcparamkey) {
case SVCB_KEY_PORT:
return gldns_str2wire_svcparam_port(val, rd, rd_len);
case SVCB_KEY_IPV4HINT:
return gldns_str2wire_svcbparam_ipv4hint(val, rd, rd_len);
case SVCB_KEY_IPV6HINT:
return gldns_str2wire_svcbparam_ipv6hint(val, rd, rd_len);
case SVCB_KEY_MANDATORY:
return gldns_str2wire_svcbparam_mandatory(val, rd, rd_len);
#ifdef SVCB_SEMANTIC_ERRORS
case SVCB_KEY_NO_DEFAULT_ALPN:
return GLDNS_WIREPARSE_ERR_SVCB_NO_DEFAULT_ALPN_VALUE;
#endif
case SVCB_KEY_ECH:
return gldns_str2wire_svcbparam_ech_value(val, rd, rd_len);
case SVCB_KEY_ALPN:
return gldns_str2wire_svcbparam_alpn_value(val, rd, rd_len);
default:
str_len = strlen(val);
if (*rd_len < 4 + str_len)
return GLDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
gldns_write_uint16(rd, svcparamkey);
gldns_write_uint16(rd + 2, str_len);
memcpy(rd + 4, val, str_len);
*rd_len = 4 + str_len;
return GLDNS_WIREPARSE_ERR_OK;
}
return GLDNS_WIREPARSE_ERR_GENERAL;
}
static int gldns_str2wire_svcparam_buf(const char* str, uint8_t* rd, size_t* rd_len)
{
const char* eq_pos;
char unescaped_val[GLDNS_MAX_RDFLEN];
char* val_out = unescaped_val;
const char* val_in;
eq_pos = strchr(str, '=');
/* case: key=value */
if (eq_pos != NULL && eq_pos[1]) {
val_in = eq_pos + 1;
/* unescape characters and "" blocks */
if (*val_in == '"') {
val_in++;
while (*val_in != '"'
&& (size_t)(val_out - unescaped_val + 1) < sizeof(unescaped_val)
&& gldns_parse_char( (uint8_t*) val_out, &val_in)) {
val_out++;
}
} else {
while ((size_t)(val_out - unescaped_val + 1) < sizeof(unescaped_val)
&& gldns_parse_char( (uint8_t*) val_out, &val_in)) {
val_out++;
}
}
*val_out = 0;
return gldns_str2wire_svcparam_value(str, eq_pos - str,
unescaped_val[0] ? unescaped_val : NULL, rd, rd_len);
}
/* case: key= */
else if (eq_pos != NULL && !(eq_pos[1])) {
return gldns_str2wire_svcparam_value(str, eq_pos - str, NULL, rd, rd_len);
}
/* case: key */
else {
return gldns_str2wire_svcparam_value(str, strlen(str), NULL, rd, rd_len);
}
}
int gldns_str2wire_rdf_buf(const char* str, uint8_t* rd, size_t* len,
gldns_rdf_type rdftype)
{
@ -1009,6 +1698,8 @@ int gldns_str2wire_rdf_buf(const char* str, uint8_t* rd, size_t* len,
return gldns_str2wire_int16_data_buf(str, rd, len);
case GLDNS_RDF_TYPE_AMTRELAY:
return gldns_str2wire_amtrelay_buf(str, rd, len);
case GLDNS_RDF_TYPE_SVCPARAM:
return gldns_str2wire_svcparam_buf(str, rd, len);
case GLDNS_RDF_TYPE_UNKNOWN:
case GLDNS_RDF_TYPE_SERVICE:
return GLDNS_WIREPARSE_ERR_NOT_IMPL;
@ -1479,9 +2170,13 @@ int gldns_str2wire_tsigtime_buf(const char* str, uint8_t* rd, size_t* len)
int gldns_str2wire_period_buf(const char* str, uint8_t* rd, size_t* len)
{
const char* end;
uint32_t p = gldns_str2period(str, &end);
int overflow;
uint32_t p = gldns_str2period(str, &end, &overflow);
if(*end != 0)
return RET_ERR(GLDNS_WIREPARSE_ERR_SYNTAX_PERIOD, end-str);
if(overflow)
return RET_ERR(GLDNS_WIREPARSE_ERR_SYNTAX_INTEGER_OVERFLOW,
end-str);
if(*len < 4)
return GLDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
gldns_write_uint32(rd, p);
@ -1494,13 +2189,17 @@ static int
loc_parse_cm(char* my_str, char** endstr, uint8_t* m, uint8_t* e)
{
uint32_t meters = 0, cm = 0, val;
char* cm_endstr;
while (isblank((unsigned char)*my_str)) {
my_str++;
}
meters = (uint32_t)strtol(my_str, &my_str, 10);
if (*my_str == '.') {
my_str++;
cm = (uint32_t)strtol(my_str, &my_str, 10);
cm = (uint32_t)strtol(my_str, &cm_endstr, 10);
if(cm_endstr == my_str + 1)
cm *= 10;
my_str = cm_endstr;
}
if (meters >= 1) {
*e = 2;

View File

@ -23,10 +23,27 @@ extern "C" {
#endif
struct gldns_struct_lookup_table;
#define GLDNS_IP4ADDRLEN (32/8)
#define GLDNS_IP6ADDRLEN (128/8)
/** buffer to read an RR, cannot be larger than 64K because of packet size */
#define GLDNS_RR_BUF_SIZE 65535 /* bytes */
#define GLDNS_DEFAULT_TTL 3600
/* SVCB keys currently defined in draft-ietf-dnsop-svcb-https */
#define SVCB_KEY_MANDATORY 0
#define SVCB_KEY_ALPN 1
#define SVCB_KEY_NO_DEFAULT_ALPN 2
#define SVCB_KEY_PORT 3
#define SVCB_KEY_IPV4HINT 4
#define SVCB_KEY_ECH 5
#define SVCB_KEY_IPV6HINT 6
#define SVCPARAMKEY_COUNT 7
#define MAX_NUMBER_OF_SVCPARAMS 64
#define SVCB_MAX_COMMA_SEPARATED_VALUES 1000
/*
* To convert class and type to string see
* gldns_get_rr_class_by_name(str)
@ -170,7 +187,7 @@ uint8_t* gldns_wirerr_get_rdatawl(uint8_t* rr, size_t len, size_t dname_len);
#define GLDNS_WIREPARSE_MASK 0x0fff
#define GLDNS_WIREPARSE_SHIFT 12
#define GLDNS_WIREPARSE_ERROR(e) ((e)&GLDNS_WIREPARSE_MASK)
#define GLDNS_WIREPARSE_OFFSET(e) (((e)&~GLDNS_WIREPARSE_MASK)>>GLDNS_WIREPARSE_SHIFT)
#define GLDNS_WIREPARSE_OFFSET(e) ((((unsigned)(e))&~GLDNS_WIREPARSE_MASK)>>GLDNS_WIREPARSE_SHIFT)
/* use lookuptable to get error string, gldns_wireparse_errors */
#define GLDNS_WIREPARSE_ERR_OK 0
#define GLDNS_WIREPARSE_ERR_GENERAL 342
@ -204,6 +221,20 @@ uint8_t* gldns_wirerr_get_rdatawl(uint8_t* rr, size_t len, size_t dname_len);
#define GLDNS_WIREPARSE_ERR_SYNTAX_INTEGER_OVERFLOW 370
#define GLDNS_WIREPARSE_ERR_INCLUDE 371
#define GLDNS_WIREPARSE_ERR_PARENTHESIS 372
#define GLDNS_WIREPARSE_ERR_SVCB_UNKNOWN_KEY 373
#define GLDNS_WIREPARSE_ERR_SVCB_MISSING_PARAM 374
#define GLDNS_WIREPARSE_ERR_SVCB_TOO_MANY_PARAMS 375
#define GLDNS_WIREPARSE_ERR_SVCB_DUPLICATE_KEYS 376
#define GLDNS_WIREPARSE_ERR_SVCB_MANDATORY_TOO_MANY_KEYS 377
#define GLDNS_WIREPARSE_ERR_SVCB_MANDATORY_MISSING_PARAM 378
#define GLDNS_WIREPARSE_ERR_SVCB_MANDATORY_DUPLICATE_KEY 379
#define GLDNS_WIREPARSE_ERR_SVCB_MANDATORY_IN_MANDATORY 380
#define GLDNS_WIREPARSE_ERR_SVCB_PORT_VALUE_SYNTAX 381
#define GLDNS_WIREPARSE_ERR_SVCB_IPV4_TOO_MANY_ADDRESSES 382
#define GLDNS_WIREPARSE_ERR_SVCB_IPV6_TOO_MANY_ADDRESSES 383
#define GLDNS_WIREPARSE_ERR_SVCB_ALPN_KEY_TOO_LARGE 384
#define GLDNS_WIREPARSE_ERR_SVCB_NO_DEFAULT_ALPN_VALUE 385
#define GLDNS_WIREPARSE_ERR_SVCPARAM_BROKEN_RDATA 386
/**
* Get reference to a constant string for the (parse) error.

View File

@ -14,6 +14,7 @@
* Contains functions to translate the wireformat to text
* representation, as well as functions to print them.
*/
#include <stdlib.h>
#include "config.h"
#include "gldns/wire2str.h"
#include "gldns/str2wire.h"
@ -150,6 +151,30 @@ static gldns_lookup_table gldns_wireparse_errors_data[] = {
{ GLDNS_WIREPARSE_ERR_SYNTAX_INTEGER_OVERFLOW, "Syntax error, integer overflow" },
{ GLDNS_WIREPARSE_ERR_INCLUDE, "$INCLUDE directive was seen in the zone" },
{ GLDNS_WIREPARSE_ERR_PARENTHESIS, "Parse error, parenthesis mismatch" },
{ GLDNS_WIREPARSE_ERR_SVCB_UNKNOWN_KEY, "Unknown SvcParamKey"},
{ GLDNS_WIREPARSE_ERR_SVCB_MISSING_PARAM, "SvcParam is missing a SvcParamValue"},
{ GLDNS_WIREPARSE_ERR_SVCB_DUPLICATE_KEYS, "Duplicate SVCB key found"},
{ GLDNS_WIREPARSE_ERR_SVCB_MANDATORY_TOO_MANY_KEYS, "Too many keys in mandatory" },
{ GLDNS_WIREPARSE_ERR_SVCB_TOO_MANY_PARAMS,
"Too many SvcParams. Unbound only allows 63 entries" },
{ GLDNS_WIREPARSE_ERR_SVCB_MANDATORY_MISSING_PARAM,
"Mandatory SvcParamKey is missing"},
{ GLDNS_WIREPARSE_ERR_SVCB_MANDATORY_DUPLICATE_KEY,
"Keys in SvcParam mandatory MUST be unique" },
{ GLDNS_WIREPARSE_ERR_SVCB_MANDATORY_IN_MANDATORY,
"mandatory MUST not be included as mandatory parameter" },
{ GLDNS_WIREPARSE_ERR_SVCB_PORT_VALUE_SYNTAX,
"Could not parse port SvcParamValue" },
{ GLDNS_WIREPARSE_ERR_SVCB_IPV4_TOO_MANY_ADDRESSES,
"Too many IPv4 addresses in ipv4hint" },
{ GLDNS_WIREPARSE_ERR_SVCB_IPV6_TOO_MANY_ADDRESSES,
"Too many IPv6 addresses in ipv6hint" },
{ GLDNS_WIREPARSE_ERR_SVCB_ALPN_KEY_TOO_LARGE,
"Alpn strings need to be smaller than 255 chars"},
{ GLDNS_WIREPARSE_ERR_SVCB_NO_DEFAULT_ALPN_VALUE,
"No-default-alpn should not have a value" },
{ GLDNS_WIREPARSE_ERR_SVCPARAM_BROKEN_RDATA,
"General SVCParam error" },
{ 0, NULL }
};
gldns_lookup_table* gldns_wireparse_errors = gldns_wireparse_errors_data;
@ -171,6 +196,7 @@ static gldns_lookup_table gldns_edns_options_data[] = {
{ 8, "edns-client-subnet" },
{ 11, "edns-tcp-keepalive"},
{ 12, "Padding" },
{ 15, "EDE"},
{ 0, NULL}
};
gldns_lookup_table* gldns_edns_options = gldns_edns_options_data;
@ -197,6 +223,12 @@ static gldns_lookup_table gldns_tsig_errors_data[] = {
};
gldns_lookup_table* gldns_tsig_errors = gldns_tsig_errors_data;
/* draft-ietf-dnsop-svcb-https-06: 6. Initial SvcParamKeys */
const char *svcparamkey_strs[] = {
"mandatory", "alpn", "no-default-alpn", "port",
"ipv4hint", "ech", "ipv6hint"
};
char* gldns_wire2str_pkt(uint8_t* data, size_t len)
{
size_t slen = (size_t)gldns_wire2str_pkt_buf(data, len, NULL, 0);
@ -788,6 +820,7 @@ int gldns_wire2str_dname_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen,
unsigned i, counter=0;
unsigned maxcompr = 1000; /* loop detection, max compr ptrs */
int in_buf = 1;
size_t dname_len = 0;
if(comprloop) {
if(*comprloop != 0)
maxcompr = 30; /* for like ipv6 reverse name, per label */
@ -821,9 +854,12 @@ int gldns_wire2str_dname_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen,
if(!pkt || target >= pktlen)
return w + gldns_str_print(s, slen,
"ErrorComprPtrOutOfBounds");
if(counter++ > maxcompr)
if(counter++ > maxcompr) {
if(comprloop && *comprloop < 10)
(*comprloop)++;
return w + gldns_str_print(s, slen,
"ErrorComprPtrLooped");
}
in_buf = 0;
pos = pkt+target;
continue;
@ -840,6 +876,16 @@ int gldns_wire2str_dname_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen,
labellen = (uint8_t)*dlen;
else if(!in_buf && pos+(size_t)labellen > pkt+pktlen)
labellen = (uint8_t)(pkt + pktlen - pos);
dname_len += ((size_t)labellen)+1;
if(dname_len > GLDNS_MAX_DOMAINLEN) {
/* dname_len counts the uncompressed length we have
* seen so far, and the domain name has become too
* long, prevent the loop from printing overly long
* content. */
w += gldns_str_print(s, slen,
"ErrorDomainNameTooLong");
return w;
}
for(i=0; i<(unsigned)labellen; i++) {
w += dname_char_print(s, slen, *pos++);
}
@ -938,6 +984,253 @@ int gldns_wire2str_ttl_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen)
return gldns_str_print(s, slen, "%u", (unsigned)ttl);
}
static int
gldns_print_svcparamkey(char** s, size_t* slen, uint16_t svcparamkey)
{
if (svcparamkey < SVCPARAMKEY_COUNT) {
return gldns_str_print(s, slen, "%s", svcparamkey_strs[svcparamkey]);
}
else {
return gldns_str_print(s, slen, "key%d", (int)svcparamkey);
}
}
static int gldns_wire2str_svcparam_port2str(char** s,
size_t* slen, uint16_t data_len, uint8_t* data)
{
int w = 0;
if (data_len != 2)
return -1; /* wireformat error, a short is 2 bytes */
w = gldns_str_print(s, slen, "=%d", (int)gldns_read_uint16(data));
return w;
}
static int gldns_wire2str_svcparam_ipv4hint2str(char** s,
size_t* slen, uint16_t data_len, uint8_t* data)
{
char ip_str[INET_ADDRSTRLEN + 1];
int w = 0;
assert(data_len > 0);
if ((data_len % GLDNS_IP4ADDRLEN) == 0) {
if (inet_ntop(AF_INET, data, ip_str, sizeof(ip_str)) == NULL)
return -1; /* wireformat error, incorrect size or inet family */
w += gldns_str_print(s, slen, "=%s", ip_str);
data += GLDNS_IP4ADDRLEN;
while ((data_len -= GLDNS_IP4ADDRLEN) > 0) {
if (inet_ntop(AF_INET, data, ip_str, sizeof(ip_str)) == NULL)
return -1; /* wireformat error, incorrect size or inet family */
w += gldns_str_print(s, slen, ",%s", ip_str);
data += GLDNS_IP4ADDRLEN;
}
} else
return -1;
return w;
}
static int gldns_wire2str_svcparam_ipv6hint2str(char** s,
size_t* slen, uint16_t data_len, uint8_t* data)
{
char ip_str[INET6_ADDRSTRLEN + 1];
int w = 0;
assert(data_len > 0);
if ((data_len % GLDNS_IP6ADDRLEN) == 0) {
if (inet_ntop(AF_INET6, data, ip_str, sizeof(ip_str)) == NULL)
return -1; /* wireformat error, incorrect size or inet family */
w += gldns_str_print(s, slen, "=%s", ip_str);
data += GLDNS_IP6ADDRLEN;
while ((data_len -= GLDNS_IP6ADDRLEN) > 0) {
if (inet_ntop(AF_INET6, data, ip_str, sizeof(ip_str)) == NULL)
return -1; /* wireformat error, incorrect size or inet family */
w += gldns_str_print(s, slen, ",%s", ip_str);
data += GLDNS_IP6ADDRLEN;
}
} else
return -1;
return w;
}
static int gldns_wire2str_svcparam_mandatory2str(char** s,
size_t* slen, uint16_t data_len, uint8_t* data)
{
int w = 0;
assert(data_len > 0);
if (data_len % sizeof(uint16_t))
return -1; /* wireformat error, data_len must be multiple of shorts */
w += gldns_str_print(s, slen, "=");
w += gldns_print_svcparamkey(s, slen, gldns_read_uint16(data));
data += 2;
while ((data_len -= sizeof(uint16_t))) {
w += gldns_str_print(s, slen, ",");
w += gldns_print_svcparamkey(s, slen, gldns_read_uint16(data));
data += 2;
}
return w;
}
static int gldns_wire2str_svcparam_alpn2str(char** s,
size_t* slen, uint16_t data_len, uint8_t* data)
{
uint8_t *dp = (void *)data;
int w = 0;
assert(data_len > 0); /* Guaranteed by gldns_wire2str_svcparam_scan */
w += gldns_str_print(s, slen, "=\"");
while (data_len) {
/* alpn is list of length byte (str_len) followed by a string of that size */
uint8_t i, str_len = *dp++;
if (str_len > --data_len)
return -1;
for (i = 0; i < str_len; i++) {
if (dp[i] == '"' || dp[i] == '\\')
w += gldns_str_print(s, slen, "\\\\\\%c", dp[i]);
else if (dp[i] == ',')
w += gldns_str_print(s, slen, "\\\\%c", dp[i]);
else if (!isprint(dp[i]))
w += gldns_str_print(s, slen, "\\%03u", (unsigned) dp[i]);
else
w += gldns_str_print(s, slen, "%c", dp[i]);
}
dp += str_len;
if ((data_len -= str_len))
w += gldns_str_print(s, slen, "%s", ",");
}
w += gldns_str_print(s, slen, "\"");
return w;
}
static int gldns_wire2str_svcparam_ech2str(char** s,
size_t* slen, uint16_t data_len, uint8_t* data)
{
int size;
int w = 0;
assert(data_len > 0); /* Guaranteed by gldns_wire2str_svcparam_scan */
w += gldns_str_print(s, slen, "=\"");
if ((size = gldns_b64_ntop(data, data_len, *s, *slen)) < 0)
return -1;
(*s) += size;
(*slen) -= size;
w += gldns_str_print(s, slen, "\"");
return w + size;
}
int gldns_wire2str_svcparam_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen)
{
uint8_t ch;
uint16_t svcparamkey, data_len;
int written_chars = 0;
int r, i;
/* verify that we have enough data to read svcparamkey and data_len */
if(*dlen < 4)
return -1;
svcparamkey = gldns_read_uint16(*d);
data_len = gldns_read_uint16(*d+2);
*d += 4;
*dlen -= 4;
/* verify that we have data_len data */
if (data_len > *dlen)
return -1;
written_chars += gldns_print_svcparamkey(s, slen, svcparamkey);
if (!data_len) {
/* Some SvcParams MUST have values */
switch (svcparamkey) {
case SVCB_KEY_ALPN:
case SVCB_KEY_PORT:
case SVCB_KEY_IPV4HINT:
case SVCB_KEY_IPV6HINT:
case SVCB_KEY_MANDATORY:
return -1;
default:
return written_chars;
}
}
switch (svcparamkey) {
case SVCB_KEY_PORT:
r = gldns_wire2str_svcparam_port2str(s, slen, data_len, *d);
break;
case SVCB_KEY_IPV4HINT:
r = gldns_wire2str_svcparam_ipv4hint2str(s, slen, data_len, *d);
break;
case SVCB_KEY_IPV6HINT:
r = gldns_wire2str_svcparam_ipv6hint2str(s, slen, data_len, *d);
break;
case SVCB_KEY_MANDATORY:
r = gldns_wire2str_svcparam_mandatory2str(s, slen, data_len, *d);
break;
case SVCB_KEY_NO_DEFAULT_ALPN:
return -1; /* wireformat error, should not have a value */
case SVCB_KEY_ALPN:
r = gldns_wire2str_svcparam_alpn2str(s, slen, data_len, *d);
break;
case SVCB_KEY_ECH:
r = gldns_wire2str_svcparam_ech2str(s, slen, data_len, *d);
break;
default:
r = gldns_str_print(s, slen, "=\"");
for (i = 0; i < data_len; i++) {
ch = (*d)[i];
if (ch == '"' || ch == '\\')
r += gldns_str_print(s, slen, "\\%c", ch);
else if (!isprint(ch))
r += gldns_str_print(s, slen, "\\%03u", (unsigned) ch);
else
r += gldns_str_print(s, slen, "%c", ch);
}
r += gldns_str_print(s, slen, "\"");
break;
}
if (r <= 0)
return -1; /* wireformat error */
written_chars += r;
*d += data_len;
*dlen -= data_len;
return written_chars;
}
int gldns_wire2str_rdf_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen,
int rdftype, uint8_t* pkt, size_t pktlen, int* comprloop)
{
@ -1018,6 +1311,8 @@ int gldns_wire2str_rdf_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen,
case GLDNS_RDF_TYPE_AMTRELAY:
return gldns_wire2str_amtrelay_scan(d, dlen, s, slen, pkt,
pktlen, comprloop);
case GLDNS_RDF_TYPE_SVCPARAM:
return gldns_wire2str_svcparam_scan(d, dlen, s, slen);
case GLDNS_RDF_TYPE_TSIGERROR:
return gldns_wire2str_tsigerror_scan(d, dlen, s, slen);
}

View File

@ -59,7 +59,7 @@ char* gldns_wire2str_pkt(uint8_t* data, size_t len);
char* gldns_wire2str_rr(uint8_t* rr, size_t len);
/**
* Conver wire dname to a string.
* Convert wire dname to a string.
* @param dname: the dname in uncompressed wireformat.
* @param dname_len: length of the dname.
* @return string or NULL on failure.
@ -494,6 +494,18 @@ int gldns_wire2str_opcode_buf(int opcode, char* str, size_t len);
int gldns_wire2str_dname_buf(uint8_t* dname, size_t dname_len, char* str,
size_t len);
/**
* Convert wire SVCB to a string with user buffer.
* @param d: the SVCB data in uncompressed wireformat.
* @param dlen: length of the SVCB data.
* @param s: the string to write to.
* @param slen: length of string.
* @return the number of characters for this element, excluding zerobyte.
* Is larger or equal than str_len if output was truncated.
*/
int gldns_wire2str_svcparam_scan(uint8_t** d, size_t* dlen, char** s,
size_t* slen);
/**
* Scan wireformat rdf field to string, with user buffers.
* It shifts the arguments to move along (see gldns_wire2str_pkt_scan).

View File

@ -94,10 +94,4 @@ typedef struct _getdns_tls_x509
gnutls_datum_t tls;
} _getdns_tls_x509;
typedef struct _getdns_tls_hmac
{
gnutls_hmac_hd_t tls;
unsigned int md_len;
} _getdns_tls_hmac;
#endif /* _GETDNS_TLS_INTERNAL_H */

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2018-2019, NLnet Labs
* Copyright (c) 2018-2020, NLnet Labs
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -102,7 +102,18 @@ static int set_connection_ciphers(_getdns_tls_connection* conn)
char* pri = NULL;
int res;
pri = getdns_priappend(conn->mfs, pri, "NONE:+COMP-ALL:+SIGN-RSA-SHA384");
pri = getdns_priappend(conn->mfs, pri, "NONE:+COMP-ALL:+SIGN-ALL"
/* Remove all the weak ones */
":-SIGN-RSA-MD5"
":-SIGN-RSA-SHA1:-SIGN-RSA-SHA224:-SIGN-RSA-SHA256"
":-SIGN-DSA-SHA1:-SIGN-DSA-SHA224:-SIGN-DSA-SHA256"
#if GNUTLS_VERSION_NUMBER >= 0x030505
":-SIGN-ECDSA-SHA1:-SIGN-ECDSA-SHA224:-SIGN-ECDSA-SHA256"
#endif
#if GNUTLS_VERSION_NUMBER >= 0x030601
":-SIGN-RSA-PSS-SHA256"
#endif
);
if (conn->cipher_suites)
pri = getdns_priappend(conn->mfs, pri, conn->cipher_suites);
@ -119,7 +130,11 @@ static int set_connection_ciphers(_getdns_tls_connection* conn)
else if (conn->ctx->curve_list)
pri = getdns_priappend(conn->mfs, pri, conn->ctx->curve_list);
else
#if GNUTLS_VERSION_NUMBER >= 0x030605
pri = getdns_priappend(conn->mfs, pri, "+GROUP-EC-ALL");
#else
pri = getdns_priappend(conn->mfs, pri, "+CURVE-ALL");
#endif
gnutls_protocol_t min = conn->min_tls;
gnutls_protocol_t max = conn->max_tls;
@ -134,19 +149,17 @@ static int set_connection_ciphers(_getdns_tls_connection* conn)
for (gnutls_protocol_t i = min; i <= max; ++i)
pri = getdns_priappend(conn->mfs, pri, _getdns_tls_priorities[i]);
}
if (pri) {
res = gnutls_priority_set_direct(conn->tls, pri, NULL);
if (res != GNUTLS_E_SUCCESS) {
_getdns_log(conn->log
, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_ERR
, GETDNS_LOG_UPSTREAM_STATS
, (res == GNUTLS_E_SUCCESS ? GETDNS_LOG_DEBUG : GETDNS_LOG_ERR)
, "%s: %s %s (%s)\n"
, STUB_DEBUG_SETUP_TLS
, "Error configuring TLS connection with "
, "Configuring TLS connection with "
, pri
, gnutls_strerror(res));
}
}
else
res = gnutls_set_default_priority(conn->tls);
GETDNS_FREE(*conn->mfs, pri);
@ -165,7 +178,16 @@ static getdns_return_t error_may_want_read_write(_getdns_tls_connection* conn, i
return GETDNS_RETURN_TLS_WANT_READ;
else
return GETDNS_RETURN_TLS_WANT_WRITE;
case GNUTLS_E_FATAL_ALERT_RECEIVED:
_getdns_log( conn->log
, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_ERR
, "%s %s %d (%s)\n"
, STUB_DEBUG_SETUP_TLS
, "Error in TLS handshake"
, (int)gnutls_alert_get(conn->tls)
, gnutls_alert_get_name(gnutls_alert_get(conn->tls))
);
/* fallthrough */
default:
return GETDNS_RETURN_GENERIC_ERROR;
}
@ -249,7 +271,7 @@ getdns_return_t _getdns_tls_context_free(struct mem_funcs* mfs, _getdns_tls_cont
void _getdns_tls_context_pinset_init(_getdns_tls_context* ctx)
{
(void) ctx;
(void) ctx; /* unused parameter */
}
getdns_return_t _getdns_tls_context_set_min_max_tls_version(_getdns_tls_context* ctx, getdns_tls_version_t min, getdns_tls_version_t max)
@ -319,6 +341,11 @@ getdns_return_t _getdns_tls_context_set_ca(_getdns_tls_context* ctx, const char*
return GETDNS_RETURN_GOOD;
}
void _getdns_gnutls_stub_log(int level, const char *msg)
{
DEBUG_STUB("GnuTLS log (%.2d): %s", level, msg);
}
_getdns_tls_connection* _getdns_tls_connection_new(struct mem_funcs* mfs, _getdns_tls_context* ctx, int fd, const getdns_log_config* log)
{
_getdns_tls_connection* res;
@ -353,7 +380,9 @@ _getdns_tls_connection* _getdns_tls_connection_new(struct mem_funcs* mfs, _getdn
gnutls_certificate_set_x509_trust_dir(res->cred, ctx->ca_trust_path, GNUTLS_X509_FMT_PEM);
}
if (gnutls_init(&res->tls, GNUTLS_CLIENT | GNUTLS_NONBLOCK) != GNUTLS_E_SUCCESS)
gnutls_global_set_log_level(99);
gnutls_global_set_log_function(_getdns_gnutls_stub_log);
if (gnutls_init(&res->tls, GNUTLS_CLIENT | GNUTLS_NONBLOCK | GNUTLS_NO_SIGNAL) != GNUTLS_E_SUCCESS)
goto failed;
if (set_connection_ciphers(res) != GNUTLS_E_SUCCESS) {
@ -364,6 +393,12 @@ _getdns_tls_connection* _getdns_tls_connection_new(struct mem_funcs* mfs, _getdn
if (dane_state_init(&res->dane_state, DANE_F_IGNORE_DNSSEC) != DANE_E_SUCCESS)
goto failed;
gnutls_datum_t proto;
proto.data = (unsigned char *)"dot";
proto.size = 3;
if (gnutls_alpn_set_protocols(res->tls, &proto, 1, 0) != GNUTLS_E_SUCCESS)
goto failed;
gnutls_transport_set_int(res->tls, fd);
return res;
@ -709,8 +744,11 @@ failsafe:
GETDNS_FREE(*conn->mfs, new_cert_list);
}
if (ret != DANE_E_SUCCESS)
if (ret != DANE_E_SUCCESS) {
*errnum = ret;
*errmsg = dane_strerror(ret);
return GETDNS_RETURN_GENERIC_ERROR;
}
if (verify != 0) {
if (verify & DANE_VERIFY_CERT_DIFFERS) {
@ -764,6 +802,8 @@ getdns_return_t _getdns_tls_session_free(struct mem_funcs* mfs, _getdns_tls_sess
{
if (!s)
return GETDNS_RETURN_INVALID_PARAMETER;
if (s->tls.data)
gnutls_free(s->tls.data);
GETDNS_FREE(*mfs, s);
return GETDNS_RETURN_GOOD;
}
@ -835,55 +875,6 @@ unsigned char* _getdns_tls_hmac_hash(struct mem_funcs* mfs, int algorithm, const
return res;
}
_getdns_tls_hmac* _getdns_tls_hmac_new(struct mem_funcs* mfs, int algorithm, const void* key, size_t key_size)
{
gnutls_mac_algorithm_t alg;
_getdns_tls_hmac* res;
if (get_gnu_mac_algorithm(algorithm, &alg) != GETDNS_RETURN_GOOD)
return NULL;
if (!(res = GETDNS_MALLOC(*mfs, struct _getdns_tls_hmac)))
return NULL;
if (gnutls_hmac_init(&res->tls, alg, key, key_size) < 0) {
GETDNS_FREE(*mfs, res);
return NULL;
}
res->md_len = gnutls_hmac_get_len(alg);
return res;
}
getdns_return_t _getdns_tls_hmac_add(_getdns_tls_hmac* h, const void* data, size_t data_size)
{
if (!h || !h->tls || !data)
return GETDNS_RETURN_INVALID_PARAMETER;
if (gnutls_hmac(h->tls, data, data_size) < 0)
return GETDNS_RETURN_GENERIC_ERROR;
else
return GETDNS_RETURN_GOOD;
}
unsigned char* _getdns_tls_hmac_end(struct mem_funcs* mfs, _getdns_tls_hmac* h, size_t* output_size)
{
unsigned char* res;
if (!h || !h->tls)
return NULL;
res = (unsigned char*) GETDNS_XMALLOC(*mfs, unsigned char, h->md_len);
if (!res)
return NULL;
gnutls_hmac_deinit(h->tls, res);
if (output_size)
*output_size = h->md_len;
GETDNS_FREE(*mfs, h);
return res;
}
void _getdns_tls_sha1(const void* data, size_t data_size, unsigned char* buf)
{
gnutls_hash_fast(GNUTLS_DIG_SHA1, data, data_size, buf);

View File

@ -30,6 +30,7 @@ getdns_context_get_resolution_type
getdns_context_get_resolvconf
getdns_context_get_round_robin_upstreams
getdns_context_get_suffix
getdns_context_get_tcp_send_timeout
getdns_context_get_timeout
getdns_context_get_tls_authentication
getdns_context_get_tls_backoff_time
@ -78,6 +79,7 @@ getdns_context_set_resolvconf
getdns_context_set_return_dnssec_status
getdns_context_set_round_robin_upstreams
getdns_context_set_suffix
getdns_context_set_tcp_send_timeout
getdns_context_set_timeout
getdns_context_set_tls_authentication
getdns_context_set_tls_backoff_time
@ -98,6 +100,7 @@ getdns_context_set_update_callback
getdns_context_set_upstream_recursive_servers
getdns_context_set_use_threads
getdns_context_unset_edns_maximum_udp_payload_size
getdns_context_unset_tcp_send_timeout
getdns_convert_alabel_to_ulabel
getdns_convert_dns_name_to_fqdn
getdns_convert_fqdn_to_dns_name

View File

@ -29,19 +29,29 @@
#ifdef HAVE_OPENSSL_BN_H
#include <openssl/bn.h>
#endif
#ifdef HAVE_OPENSSL_PARAM_BUILD_H
# include <openssl/param_build.h>
#else
# ifdef HAVE_OPENSSL_RSA_H
# include <openssl/rsa.h>
# endif
# ifdef HAVE_OPENSSL_DSA_H
# include <openssl/dsa.h>
# endif
#endif
#ifdef HAVE_OPENSSL_DSA_H
#include <openssl/dsa.h>
#endif
#ifdef HAVE_OPENSSL_RSA_H
#include <openssl/rsa.h>
#endif
#endif /* HAVE_SSL */
#ifdef HAVE_SSL
#ifdef USE_GOST
/** store GOST engine reference loaded into OpenSSL library */
#ifdef OPENSSL_NO_ENGINE
#if defined(OPENSSL_NO_ENGINE) || OPENSSL_VERSION_NUMBER > 0x30000000
int
gldns_key_EVP_load_gost_id(void)
{
@ -113,49 +123,71 @@ void gldns_key_EVP_unload_gost(void)
#endif /* ifndef OPENSSL_NO_ENGINE */
#endif /* USE_GOST */
DSA *
gldns_key_buf2dsa_raw(unsigned char* key, size_t len)
/* Retrieve params as BIGNUM from raw buffer */
static int
gldns_key_dsa_buf_bignum(unsigned char* key, size_t len, BIGNUM** p,
BIGNUM** q, BIGNUM** g, BIGNUM** y)
{
uint8_t T;
uint16_t length;
uint16_t offset;
DSA *dsa;
BIGNUM *Q; BIGNUM *P;
BIGNUM *G; BIGNUM *Y;
if(len == 0)
return NULL;
return 0;
T = (uint8_t)key[0];
length = (64 + T * 8);
offset = 1;
if (T > 8) {
return NULL;
return 0;
}
if(len < (size_t)1 + SHA_DIGEST_LENGTH + 3*length)
return NULL;
return 0;
Q = BN_bin2bn(key+offset, SHA_DIGEST_LENGTH, NULL);
*q = BN_bin2bn(key+offset, SHA_DIGEST_LENGTH, NULL);
offset += SHA_DIGEST_LENGTH;
P = BN_bin2bn(key+offset, (int)length, NULL);
*p = BN_bin2bn(key+offset, (int)length, NULL);
offset += length;
G = BN_bin2bn(key+offset, (int)length, NULL);
*g = BN_bin2bn(key+offset, (int)length, NULL);
offset += length;
Y = BN_bin2bn(key+offset, (int)length, NULL);
*y = BN_bin2bn(key+offset, (int)length, NULL);
/* create the key and set its properties */
if(!Q || !P || !G || !Y || !(dsa = DSA_new())) {
BN_free(Q);
BN_free(P);
BN_free(G);
BN_free(Y);
return NULL;
if(!*q || !*p || !*g || !*y) {
BN_free(*q);
BN_free(*p);
BN_free(*g);
BN_free(*y);
return 0;
}
return 1;
}
#if defined(HAVE_DSA_SET0_PQG) && defined(HAVE_DSA_SET0_KEY)
#ifndef HAVE_OSSL_PARAM_BLD_NEW
DSA *
gldns_key_buf2dsa_raw(unsigned char* key, size_t len)
{
DSA *dsa;
BIGNUM *Q=NULL, *P=NULL, *G=NULL, *Y=NULL;
if(!gldns_key_dsa_buf_bignum(key, len, &P, &Q, &G, &Y)) {
return NULL;
}
/* create the key and set its properties */
if(!(dsa = DSA_new())) {
return NULL;
}
#if OPENSSL_VERSION_NUMBER < 0x10100000 || \
(defined(HAVE_LIBRESSL) && LIBRESSL_VERSION_NUMBER < 0x02070000f)
#ifndef S_SPLINT_S
dsa->p = P;
dsa->q = Q;
dsa->g = G;
dsa->pub_key = Y;
#endif /* splint */
#else /* OPENSSL_VERSION_NUMBER */
if (!DSA_set0_pqg(dsa, P, Q, G)) {
/* QPG not yet attached, need to free */
BN_free(Q);
@ -172,33 +204,115 @@ gldns_key_buf2dsa_raw(unsigned char* key, size_t len)
BN_free(Y);
return NULL;
}
#else
# ifndef S_SPLINT_S
dsa->p = P;
dsa->q = Q;
dsa->g = G;
dsa->pub_key = Y;
# endif /* splint */
#endif
return dsa;
}
#endif /* HAVE_OSSL_PARAM_BLD_NEW */
RSA *
gldns_key_buf2rsa_raw(unsigned char* key, size_t len)
EVP_PKEY *gldns_key_dsa2pkey_raw(unsigned char* key, size_t len)
{
#ifdef HAVE_OSSL_PARAM_BLD_NEW
EVP_PKEY* evp_key = NULL;
EVP_PKEY_CTX* ctx;
BIGNUM *p=NULL, *q=NULL, *g=NULL, *y=NULL;
OSSL_PARAM_BLD* param_bld;
OSSL_PARAM* params = NULL;
if(!gldns_key_dsa_buf_bignum(key, len, &p, &q, &g, &y)) {
return NULL;
}
param_bld = OSSL_PARAM_BLD_new();
if(!param_bld) {
BN_free(p);
BN_free(q);
BN_free(g);
BN_free(y);
return NULL;
}
if(!OSSL_PARAM_BLD_push_BN(param_bld, "p", p) ||
!OSSL_PARAM_BLD_push_BN(param_bld, "g", g) ||
!OSSL_PARAM_BLD_push_BN(param_bld, "q", q) ||
!OSSL_PARAM_BLD_push_BN(param_bld, "pub", y)) {
OSSL_PARAM_BLD_free(param_bld);
BN_free(p);
BN_free(q);
BN_free(g);
BN_free(y);
return NULL;
}
params = OSSL_PARAM_BLD_to_param(param_bld);
OSSL_PARAM_BLD_free(param_bld);
ctx = EVP_PKEY_CTX_new_from_name(NULL, "DSA", NULL);
if(!ctx) {
OSSL_PARAM_free(params);
BN_free(p);
BN_free(q);
BN_free(g);
BN_free(y);
return NULL;
}
if(EVP_PKEY_fromdata_init(ctx) <= 0) {
EVP_PKEY_CTX_free(ctx);
OSSL_PARAM_free(params);
BN_free(p);
BN_free(q);
BN_free(g);
BN_free(y);
return NULL;
}
if(EVP_PKEY_fromdata(ctx, &evp_key, EVP_PKEY_PUBLIC_KEY, params) <= 0) {
EVP_PKEY_CTX_free(ctx);
OSSL_PARAM_free(params);
BN_free(p);
BN_free(q);
BN_free(g);
BN_free(y);
return NULL;
}
EVP_PKEY_CTX_free(ctx);
OSSL_PARAM_free(params);
BN_free(p);
BN_free(q);
BN_free(g);
BN_free(y);
return evp_key;
#else
DSA* dsa;
EVP_PKEY* evp_key = EVP_PKEY_new();
if(!evp_key) {
return NULL;
}
dsa = gldns_key_buf2dsa_raw(key, len);
if(!dsa) {
EVP_PKEY_free(evp_key);
return NULL;
}
if(EVP_PKEY_assign_DSA(evp_key, dsa) == 0) {
DSA_free(dsa);
EVP_PKEY_free(evp_key);
return NULL;
}
return evp_key;
#endif
}
/* Retrieve params as BIGNUM from raw buffer, n is modulus, e is exponent */
static int
gldns_key_rsa_buf_bignum(unsigned char* key, size_t len, BIGNUM** n,
BIGNUM** e)
{
uint16_t offset;
uint16_t exp;
uint16_t int16;
RSA *rsa;
BIGNUM *modulus;
BIGNUM *exponent;
if (len == 0)
return NULL;
return 0;
if (key[0] == 0) {
if(len < 3)
return NULL;
return 0;
memmove(&int16, key+1, 2);
exp = ntohs(int16);
offset = 3;
@ -209,46 +323,140 @@ gldns_key_buf2rsa_raw(unsigned char* key, size_t len)
/* key length at least one */
if(len < (size_t)offset + exp + 1)
return NULL;
return 0;
/* Exponent */
exponent = BN_new();
if(!exponent) return NULL;
(void) BN_bin2bn(key+offset, (int)exp, exponent);
*e = BN_new();
if(!*e) return 0;
(void) BN_bin2bn(key+offset, (int)exp, *e);
offset += exp;
/* Modulus */
modulus = BN_new();
if(!modulus) {
BN_free(exponent);
return NULL;
*n = BN_new();
if(!*n) {
BN_free(*e);
return 0;
}
/* length of the buffer must match the key length! */
(void) BN_bin2bn(key+offset, (int)(len - offset), modulus);
(void) BN_bin2bn(key+offset, (int)(len - offset), *n);
return 1;
}
#ifndef HAVE_OSSL_PARAM_BLD_NEW
RSA *
gldns_key_buf2rsa_raw(unsigned char* key, size_t len)
{
BIGNUM* modulus = NULL;
BIGNUM* exponent = NULL;
RSA *rsa;
if(!gldns_key_rsa_buf_bignum(key, len, &modulus, &exponent))
return NULL;
rsa = RSA_new();
if(!rsa) {
BN_free(exponent);
BN_free(modulus);
return NULL;
}
#if OPENSSL_VERSION_NUMBER < 0x10100000 || \
(defined(HAVE_LIBRESSL) && LIBRESSL_VERSION_NUMBER < 0x02070000f)
#ifndef S_SPLINT_S
rsa->n = modulus;
rsa->e = exponent;
#endif /* splint */
#if defined(HAVE_RSA_SET0_KEY)
#else /* OPENSSL_VERSION_NUMBER */
if (!RSA_set0_key(rsa, modulus, exponent, NULL)) {
BN_free(exponent);
BN_free(modulus);
RSA_free(rsa);
return NULL;
}
#else
# ifndef S_SPLINT_S
rsa->n = modulus;
rsa->e = exponent;
# endif /* splint */
#endif
return rsa;
}
#endif /* HAVE_OSSL_PARAM_BLD_NEW */
EVP_PKEY* gldns_key_rsa2pkey_raw(unsigned char* key, size_t len)
{
#ifdef HAVE_OSSL_PARAM_BLD_NEW
EVP_PKEY* evp_key = NULL;
EVP_PKEY_CTX* ctx;
BIGNUM *n=NULL, *e=NULL;
OSSL_PARAM_BLD* param_bld;
OSSL_PARAM* params = NULL;
if(!gldns_key_rsa_buf_bignum(key, len, &n, &e)) {
return NULL;
}
param_bld = OSSL_PARAM_BLD_new();
if(!param_bld) {
BN_free(n);
BN_free(e);
return NULL;
}
if(!OSSL_PARAM_BLD_push_BN(param_bld, "n", n)) {
OSSL_PARAM_BLD_free(param_bld);
BN_free(n);
BN_free(e);
return NULL;
}
if(!OSSL_PARAM_BLD_push_BN(param_bld, "e", e)) {
OSSL_PARAM_BLD_free(param_bld);
BN_free(n);
BN_free(e);
return NULL;
}
params = OSSL_PARAM_BLD_to_param(param_bld);
OSSL_PARAM_BLD_free(param_bld);
ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL);
if(!ctx) {
OSSL_PARAM_free(params);
BN_free(n);
BN_free(e);
return NULL;
}
if(EVP_PKEY_fromdata_init(ctx) <= 0) {
EVP_PKEY_CTX_free(ctx);
OSSL_PARAM_free(params);
BN_free(n);
BN_free(e);
return NULL;
}
if(EVP_PKEY_fromdata(ctx, &evp_key, EVP_PKEY_PUBLIC_KEY, params) <= 0) {
EVP_PKEY_CTX_free(ctx);
OSSL_PARAM_free(params);
BN_free(n);
BN_free(e);
return NULL;
}
EVP_PKEY_CTX_free(ctx);
OSSL_PARAM_free(params);
BN_free(n);
BN_free(e);
return evp_key;
#else
RSA* rsa;
EVP_PKEY *evp_key = EVP_PKEY_new();
if(!evp_key) {
return NULL;
}
rsa = gldns_key_buf2rsa_raw(key, len);
if(!rsa) {
EVP_PKEY_free(evp_key);
return NULL;
}
if(EVP_PKEY_assign_RSA(evp_key, rsa) == 0) {
RSA_free(rsa);
EVP_PKEY_free(evp_key);
return NULL;
}
return evp_key;
#endif
}
#ifdef USE_GOST
EVP_PKEY*
@ -279,6 +487,62 @@ gldns_gost2pkey_raw(unsigned char* key, size_t keylen)
EVP_PKEY*
gldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo)
{
#ifdef HAVE_OSSL_PARAM_BLD_NEW
unsigned char buf[256+2]; /* sufficient for 2*384/8+1 */
EVP_PKEY *evp_key = NULL;
EVP_PKEY_CTX* ctx;
OSSL_PARAM_BLD* param_bld;
OSSL_PARAM* params = NULL;
char* group = NULL;
/* check length, which uncompressed must be 2 bignums */
if(algo == GLDNS_ECDSAP256SHA256) {
if(keylen != 2*256/8) return NULL;
group = "prime256v1";
} else if(algo == GLDNS_ECDSAP384SHA384) {
if(keylen != 2*384/8) return NULL;
group = "P-384";
} else {
return NULL;
}
if(keylen+1 > sizeof(buf)) { /* sanity check */
return NULL;
}
/* prepend the 0x04 for uncompressed format */
buf[0] = POINT_CONVERSION_UNCOMPRESSED;
memmove(buf+1, key, keylen);
param_bld = OSSL_PARAM_BLD_new();
if(!param_bld) {
return NULL;
}
if(!OSSL_PARAM_BLD_push_utf8_string(param_bld, "group", group, 0) ||
!OSSL_PARAM_BLD_push_octet_string(param_bld, "pub", buf, keylen+1)) {
OSSL_PARAM_BLD_free(param_bld);
return NULL;
}
params = OSSL_PARAM_BLD_to_param(param_bld);
OSSL_PARAM_BLD_free(param_bld);
ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL);
if(!ctx) {
OSSL_PARAM_free(params);
return NULL;
}
if(EVP_PKEY_fromdata_init(ctx) <= 0) {
EVP_PKEY_CTX_free(ctx);
OSSL_PARAM_free(params);
return NULL;
}
if(EVP_PKEY_fromdata(ctx, &evp_key, EVP_PKEY_PUBLIC_KEY, params) <= 0) {
EVP_PKEY_CTX_free(ctx);
OSSL_PARAM_free(params);
return NULL;
}
EVP_PKEY_CTX_free(ctx);
OSSL_PARAM_free(params);
return evp_key;
#else
unsigned char buf[256+2]; /* sufficient for 2*384/8+1 */
const unsigned char* pp = buf;
EVP_PKEY *evp_key;
@ -315,6 +579,7 @@ gldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo)
return NULL;
}
return evp_key;
#endif /* HAVE_OSSL_PARAM_BLD_NEW */
}
#endif /* USE_ECDSA */

View File

@ -37,6 +37,7 @@ int gldns_key_EVP_load_gost_id(void);
/** Release the engine reference held for the GOST engine. */
void gldns_key_EVP_unload_gost(void);
#ifndef HAVE_OSSL_PARAM_BLD_NEW
/**
* Like gldns_key_buf2dsa, but uses raw buffer.
* \param[in] key the uncompressed wireformat of the key.
@ -44,6 +45,15 @@ void gldns_key_EVP_unload_gost(void);
* \return a DSA * structure with the key material
*/
DSA *gldns_key_buf2dsa_raw(unsigned char* key, size_t len);
#endif
/**
* Converts a holding buffer with DSA key material to EVP PKEY in openssl.
* \param[in] key the uncompressed wireformat of the key.
* \param[in] len length of key data
* \return the key or NULL on error.
*/
EVP_PKEY *gldns_key_dsa2pkey_raw(unsigned char* key, size_t len);
/**
* Converts a holding buffer with key material to EVP PKEY in openssl.
@ -64,6 +74,7 @@ EVP_PKEY* gldns_gost2pkey_raw(unsigned char* key, size_t keylen);
*/
EVP_PKEY* gldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo);
#ifndef HAVE_OSSL_PARAM_BLD_NEW
/**
* Like gldns_key_buf2rsa, but uses raw buffer.
* \param[in] key the uncompressed wireformat of the key.
@ -71,6 +82,15 @@ EVP_PKEY* gldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo);
* \return a RSA * structure with the key material
*/
RSA *gldns_key_buf2rsa_raw(unsigned char* key, size_t len);
#endif
/**
* Converts a holding buffer with RSA key material to EVP PKEY in openssl.
* \param[in] key the uncompressed wireformat of the key.
* \param[in] len length of key data
* \return the key or NULL on error.
*/
EVP_PKEY* gldns_key_rsa2pkey_raw(unsigned char* key, size_t len);
/**
* Converts a holding buffer with key material to EVP PKEY in openssl.

View File

@ -81,12 +81,4 @@ typedef struct _getdns_tls_x509
X509* ssl;
} _getdns_tls_x509;
typedef struct _getdns_tls_hmac
{
HMAC_CTX *ctx;
#ifndef HAVE_HMAC_CTX_NEW
HMAC_CTX ctx_space;
#endif
} _getdns_tls_hmac;
#endif /* _GETDNS_TLS_INTERNAL_H */

View File

@ -48,19 +48,21 @@
#include "context.h"
#include "const-info.h"
#ifdef USE_DANESSL
#if defined(USE_DANESSL) || defined(LIBRESSL_VERSION_NUMBER)
# include "ssl_dane/danessl.h"
#endif
#include "tls.h"
/* Double check configure has worked as expected. */
#ifndef LIBRESSL_VERSION_NUMBER
#if defined(USE_DANESSL) && \
(defined(HAVE_SSL_DANE_ENABLE) || \
defined(HAVE_OPENSSL_INIT_CRYPTO) || \
defined(HAVE_SSL_CTX_DANE_ENABLE))
#error Configure error USE_DANESSL defined with OpenSSL 1.1 functions!
#endif
#endif
/* Cipher suites recommended in RFC7525. */
static char const * const _getdns_tls_context_default_cipher_list =
@ -95,8 +97,8 @@ static int _getdns_tls_verify_always_ok(int ok, X509_STORE_CTX *ctx)
strcpy(buf, "<unknown>");
DEBUG_STUB("DEBUG Cert verify: depth=%d verify=%d err=%d subject=%s errorstr=%s\n", depth, ok, err, buf, X509_verify_cert_error_string(err));
# else /* defined(STUB_DEBUG) && STUB_DEBUG */
(void)ok;
(void)ctx;
(void)ok; /* unused parameter */
(void)ctx; /* unused parameter */
# endif /* #else defined(STUB_DEBUG) && STUB_DEBUG */
return 1;
}
@ -318,6 +320,10 @@ void _getdns_tls_init()
#endif
}
#define DOT_PROTO_ALPN_ID "dot"
#define DOT_PROTO_ALPN "\x3" DOT_PROTO_ALPN_ID
#define DOT_PROTO_ALPN_LEN (sizeof(DOT_PROTO_ALPN) - 1)
_getdns_tls_context* _getdns_tls_context_new(struct mem_funcs* mfs, const getdns_log_config* log)
{
_getdns_tls_context* res;
@ -346,6 +352,8 @@ _getdns_tls_context* _getdns_tls_context_new(struct mem_funcs* mfs, const getdns
GETDNS_FREE(*mfs, res);
return NULL;
}
SSL_CTX_set_alpn_protos(res->ssl, (const uint8_t *)DOT_PROTO_ALPN,
DOT_PROTO_ALPN_LEN);
return res;
}
@ -425,7 +433,7 @@ getdns_return_t _getdns_tls_context_set_min_max_tls_version(_getdns_tls_context*
* We've used TLSv1_2_client_method() creating the context, so
* error if they asked for anything other than TLS 1.2 or better.
*/
(void) ctx;
(void) ctx; /* unused parameter */
if ((!min || min == GETDNS_TLS1_2) && !max)
return GETDNS_RETURN_GOOD;
@ -693,7 +701,7 @@ getdns_return_t _getdns_tls_connection_set_min_max_tls_version(_getdns_tls_conne
* We've used TLSv1_2_client_method() creating the context, so
* error if they asked for anything other than TLS 1.2 or better.
*/
(void) conn;
(void) conn; /* unused parameter */
if ((!min || min == GETDNS_TLS1_2) && !max)
return GETDNS_RETURN_GOOD;
@ -912,7 +920,7 @@ getdns_return_t _getdns_tls_connection_set_host_pinset(_getdns_tls_connection* c
#if defined(HAVE_SSL_DANE_ENABLE)
int osr = SSL_dane_enable(conn->ssl, *auth_name ? auth_name : NULL);
(void) osr;
(void) osr; /* unused parameter */
DEBUG_STUB("%s %-35s: DEBUG: SSL_dane_enable(\"%s\") -> %d\n"
, STUB_DEBUG_SETUP_TLS, __FUNC__, auth_name, osr);
SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, _getdns_tls_verify_always_ok);
@ -938,7 +946,7 @@ getdns_return_t _getdns_tls_connection_set_host_pinset(_getdns_tls_connection* c
int osr = DANESSL_init(conn->ssl,
*auth_name ? auth_name : NULL,
*auth_name ? auth_names : NULL);
(void) osr;
(void) osr; /* unused parameter */
DEBUG_STUB("%s %-35s: DEBUG: DANESSL_init(\"%s\") -> %d\n"
, STUB_DEBUG_SETUP_TLS, __FUNC__, auth_name, osr);
SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, _getdns_tls_verify_always_ok);
@ -1189,70 +1197,6 @@ unsigned char* _getdns_tls_hmac_hash(struct mem_funcs* mfs, int algorithm, const
return res;
}
_getdns_tls_hmac* _getdns_tls_hmac_new(struct mem_funcs* mfs, int algorithm, const void* key, size_t key_size)
{
const EVP_MD *digester = get_digester(algorithm);
_getdns_tls_hmac* res;
if (!digester)
return NULL;
if (!(res = GETDNS_MALLOC(*mfs, struct _getdns_tls_hmac)))
return NULL;
#ifdef HAVE_HMAC_CTX_NEW
res->ctx = HMAC_CTX_new();
if (!res->ctx) {
GETDNS_FREE(*mfs, res);
return NULL;
}
#else
res->ctx = &res->ctx_space;
HMAC_CTX_init(res->ctx);
#endif
if (!HMAC_Init_ex(res->ctx, key, key_size, digester, NULL)) {
#ifdef HAVE_HMAC_CTX_NEW
HMAC_CTX_free(res->ctx);
#endif
GETDNS_FREE(*mfs, res);
return NULL;
}
return res;
}
getdns_return_t _getdns_tls_hmac_add(_getdns_tls_hmac* h, const void* data, size_t data_size)
{
if (!h || !h->ctx || !data)
return GETDNS_RETURN_INVALID_PARAMETER;
if (!HMAC_Update(h->ctx, data, data_size))
return GETDNS_RETURN_GENERIC_ERROR;
else
return GETDNS_RETURN_GOOD;
}
unsigned char* _getdns_tls_hmac_end(struct mem_funcs* mfs, _getdns_tls_hmac* h, size_t* output_size)
{
unsigned char* res;
unsigned int md_len;
res = (unsigned char*) GETDNS_XMALLOC(*mfs, unsigned char, GETDNS_TLS_MAX_DIGEST_LENGTH);
if (!res)
return NULL;
(void) HMAC_Final(h->ctx, res, &md_len);
#ifdef HAVE_HMAC_CTX_NEW
HMAC_CTX_free(h->ctx);
#endif
GETDNS_FREE(*mfs, h);
if (output_size)
*output_size = md_len;
return res;
}
void _getdns_tls_sha1(const void* data, size_t data_size, unsigned char* buf)
{
SHA1(data, data_size, buf);

View File

@ -166,6 +166,11 @@ const char *_getdns_strerror(DWORD errnum)
}
}
const char *_getdns_filestrerror(int errnum)
{
return strerror(errnum);
}
#else
void _getdns_perror(const char *str)

View File

@ -60,6 +60,7 @@ typedef u_short sa_family_t;
#define _getdns_socketerror() (WSAGetLastError())
const char *_getdns_strerror(DWORD errnum);
const char *_getdns_filestrerror(int errnum);
#else /* USE_WINSOCK */
#ifndef HAVE_SYS_POLL_H
@ -132,10 +133,13 @@ const char *_getdns_strerror(DWORD errnum);
#define _getdns_socketerror() (errno)
const char *_getdns_strerror(int errnum);
#define _getdns_filestrerror(errnum) (_getdns_strerror(errnum))
#endif
void _getdns_perror(const char *str);
#define _getdns_fileerror() (errno)
#define _getdns_fileerrnostr() (_getdns_filestrerror(_getdns_fileerror()))
#define _getdns_errnostr() (_getdns_strerror(_getdns_socketerror()))
#define _getdns_error_wants_retry(X) ( (X) != 0 \
&& ( (X) == _getdns_EINTR \

View File

@ -147,6 +147,7 @@ netreq_reset(getdns_network_req *net_req)
net_req->dnssec_status = GETDNS_DNSSEC_INDETERMINATE;
net_req->tsig_status = GETDNS_DNSSEC_INDETERMINATE;
net_req->response_len = 0;
net_req->response_opt = NULL;
/* Some fields to record info for return_call_reporting */
net_req->debug_start_time = 0;
net_req->debug_end_time = 0;
@ -208,6 +209,9 @@ network_req_init(getdns_network_req *net_req, getdns_dns_req *owner,
net_req->transport_current = 0;
memset(&net_req->event, 0, sizeof(net_req->event));
net_req->keepalive_sent = 0;
net_req->badcookie_retry = 0;
net_req->cookie_sent = 0;
memset(&net_req->client_cookie, 0, sizeof(net_req->client_cookie));
net_req->write_queue_tail = NULL;
/* Some fields to record info for return_call_reporting */
net_req->debug_tls_auth_status = GETDNS_AUTH_NONE;
@ -308,6 +312,7 @@ _getdns_network_req_clear_upstream_options(getdns_network_req * req)
req->response = req->opt + 11 + req->base_query_option_sz;
pktlen = req->response - req->query;
gldns_write_uint16(req->query - 2, (uint16_t) pktlen);
req->response_opt = NULL;
}
}
@ -317,6 +322,9 @@ _getdns_netreq_reinit(getdns_network_req *netreq)
uint8_t *base_opt_backup;
size_t base_opt_rr_sz;
if (netreq->response && (netreq->response < netreq->wire_data ||
netreq->response > netreq->wire_data+ netreq->wire_data_sz))
GETDNS_NULL_FREE(netreq->owner->my_mf, netreq->response);
if (!netreq->query) {
(void) netreq_reset(netreq);
return;
@ -476,7 +484,7 @@ void
_getdns_network_validate_tsig(getdns_network_req *req)
{
#if defined(HAVE_NSS) || defined(HAVE_NETTLE)
(void)req;
(void)req; /* unused parameter */
#else
_getdns_rr_iter rr_spc, *rr;
_getdns_rdf_iter rdf_spc, *rdf;
@ -492,7 +500,9 @@ _getdns_network_validate_tsig(getdns_network_req *req)
unsigned char *result_mac;
size_t result_mac_len;
uint16_t original_id;
_getdns_tls_hmac *hmac;
size_t data_size;
uint8_t *data;
DEBUG_STUB("%s %-35s: Validate TSIG\n", STUB_DEBUG_TSIG, __FUNC__);
for ( rr = _getdns_rr_iter_init(&rr_spc, req->query,
@ -599,19 +609,33 @@ _getdns_network_validate_tsig(getdns_network_req *req)
gldns_read_uint16(req->response + 10) - 1);
gldns_write_uint16(req->response, original_id);
hmac = _getdns_tls_hmac_new(&req->owner->my_mf, req->upstream->tsig_alg, req->upstream->tsig_key, req->upstream->tsig_size);
if (!hmac)
data_size = request_mac_len + 2
+ (size_t)(rr->pos - req->response)
+ gldns_buffer_position(&gbuf);
data = GETDNS_XMALLOC(req->owner->my_mf, uint8_t, data_size);
if (!data) {
DEBUG_STUB("%s %-35s: Error allocating %d bytes\n",
STUB_DEBUG_TSIG, __FUNC__, (int)(data_size));
return;
}
memcpy(data , request_mac - 2 , request_mac_len + 2);
memcpy(data + request_mac_len + 2, req->response, rr->pos - req->response);
memcpy(data + request_mac_len + 2 + (size_t)(rr->pos - req->response)
, tsig_vars, gldns_buffer_position(&gbuf));
_getdns_tls_hmac_add(hmac, request_mac - 2, request_mac_len + 2);
_getdns_tls_hmac_add(hmac, req->response, rr->pos - req->response);
_getdns_tls_hmac_add(hmac, tsig_vars, gldns_buffer_position(&gbuf));
result_mac = _getdns_tls_hmac_end(&req->owner->my_mf, hmac, &result_mac_len);
if (!result_mac)
result_mac = _getdns_tls_hmac_hash(&req->owner->my_mf
, req->upstream->tsig_alg
, req->upstream->tsig_key
, req->upstream->tsig_size
, data, data_size , &result_mac_len);
GETDNS_FREE(req->owner->my_mf, data);
if (!result_mac) {
DEBUG_STUB("%s %-35s: Error calculating TSIG digest\n",
STUB_DEBUG_TSIG, __FUNC__);
return;
DEBUG_STUB("%s %-35s: Result MAC length: %d\n",
STUB_DEBUG_TSIG, __FUNC__, (int)(result_mac_len));
}
DEBUG_STUB("%s %-35s: Result MAC length: %d for %d bytes of data\n",
STUB_DEBUG_TSIG, __FUNC__, (int)(result_mac_len), (int)data_size);
if (result_mac_len == response_mac_len &&
memcmp(result_mac, response_mac, result_mac_len) == 0)
req->tsig_status = GETDNS_DNSSEC_SECURE;

View File

@ -47,7 +47,7 @@
static const uint8_t *
apl_n_rdf_end(const uint8_t *pkt, const uint8_t *pkt_end, const uint8_t *rdf)
{
(void)pkt;
(void)pkt; /* unused parameter */
return rdf < pkt_end ? rdf + 1 : NULL;
}
static getdns_return_t
@ -91,7 +91,7 @@ apl_afdpart_rdf_end(
const uint8_t *pkt, const uint8_t *pkt_end, const uint8_t *rdf)
{
const uint8_t *end = rdf + (rdf[-1] & 0x7F);
(void)(pkt);
(void)pkt; /* unused parameter */
return end <= pkt_end ? end : NULL;
}
static getdns_return_t
@ -217,6 +217,7 @@ ipseckey_gateway_2wire(
{
assert(rdf - 2 >= rdata && rdf[-2] > 0);
(void)rdata; /* unused parameter */
switch (rdf[-2]) {
case 1: if (!value || value->size != 4)
return GETDNS_RETURN_INVALID_PARAMETER;
@ -280,7 +281,7 @@ static const uint8_t *
hip_pk_algorithm_rdf_end(
const uint8_t *pkt, const uint8_t *pkt_end, const uint8_t *rdf)
{
(void)(pkt);
(void)pkt; /* unused parameter */
return rdf + 4 > pkt_end ? NULL
: rdf + 4 + *rdf + gldns_read_uint16(rdf + 2) > pkt_end ? NULL
: rdf + 1;
@ -326,7 +327,7 @@ static _getdns_rdf_special hip_pk_algorithm = {
static const uint8_t *
hip_hit_rdf_end(const uint8_t *pkt, const uint8_t *pkt_end, const uint8_t *rdf)
{
(void)(pkt);
(void)pkt; /* unused parameter */
return rdf + 3 > pkt_end ? NULL
: rdf + 3 + rdf[-1] + gldns_read_uint16(rdf + 1) > pkt_end ? NULL
: rdf + 1;
@ -380,7 +381,7 @@ static const uint8_t *
hip_public_key_rdf_end(
const uint8_t *pkt, const uint8_t *pkt_end, const uint8_t *rdf)
{
(void)(pkt);
(void)pkt; /* unused parameter */
return rdf + 2 > pkt_end ? NULL
: rdf + 2 + rdf[-2] + gldns_read_uint16(rdf) > pkt_end ? NULL
: rdf + 2 + rdf[-2] + gldns_read_uint16(rdf);
@ -434,7 +435,7 @@ static _getdns_rdf_special hip_public_key = {
static const uint8_t *
amtrelay_D_rdf_end(const uint8_t *pkt, const uint8_t *pkt_end, const uint8_t *rdf)
{
(void)pkt;
(void)pkt; /* unused parameter */
return rdf < pkt_end ? rdf + 1 : NULL;
}
static getdns_return_t
@ -471,7 +472,8 @@ static const uint8_t *
amtrelay_rtype_rdf_end(
const uint8_t *pkt, const uint8_t *pkt_end, const uint8_t *rdf)
{
(void)pkt; (void)pkt_end;
(void)pkt; /* unused parameter */
(void)pkt_end; /* unused parameter */
return rdf;
}
static getdns_return_t
@ -581,6 +583,7 @@ amtrelay_relay_2wire(
{
assert(rdf - 1 >= rdata && (rdf[-1] & 0x7F) > 0);
(void)rdata; /* unused parameter */
switch (rdf[-1] & 0x7F) {
case 1: if (!value || value->size != 4)
return GETDNS_RETURN_INVALID_PARAMETER;
@ -1293,8 +1296,39 @@ write_rdata_field(gldns_buffer *buf, uint8_t *rdata_start,
return r != GETDNS_RETURN_NO_SUCH_LIST_ITEM ? r : GETDNS_RETURN_GOOD;
}
void
_getdns_rr_buffer_write_cached_name(gldns_buffer *buf, getdns_bindata *name, name_cache_t *name_cache)
{
size_t name_size = name->size;
uint8_t *name_data = name->data;
if((NULL != name_cache) && (name_size > 2)) {
unsigned count = name_cache->count;
name_cache_entry_t *entry_ptr = &name_cache->entry[(count < NAME_CACHE_ENTRIES)?count:NAME_CACHE_ENTRIES];
name_cache_entry_t *table_start = &name_cache->entry[0];
/* Search backward if name is already in cache */
while(entry_ptr-- > table_start) {
if((entry_ptr->name->size == name_size) &&
!memcmp(entry_ptr->name->data, name_data, name_size)) {
gldns_buffer_write_u16(buf, (uint16_t)(0xc000 | entry_ptr->name_offset));
return;
}
}
unsigned name_offset = gldns_buffer_position(buf);
if (name_offset < 0x4000) {
/* Cache name */
entry_ptr = &name_cache->entry[count % NAME_CACHE_ENTRIES];
entry_ptr->name = name;
entry_ptr->name_offset = name_offset;
name_cache->count = count + 1;
}
}
gldns_buffer_write(buf, name_data, name_size);
return;
}
getdns_return_t
_getdns_rr_dict2wire(const getdns_dict *rr_dict, gldns_buffer *buf)
_getdns_rr_dict2wire_cache(const getdns_dict *rr_dict, gldns_buffer *buf,
name_cache_t *name_cache)
{
getdns_return_t r = GETDNS_RETURN_GOOD;
getdns_bindata root = { 1, (void *)"" };
@ -1325,7 +1359,7 @@ _getdns_rr_dict2wire(const getdns_dict *rr_dict, gldns_buffer *buf)
} else
return r;
}
gldns_buffer_write(buf, name->data, name->size);
_getdns_rr_buffer_write_cached_name(buf, name, name_cache);
gldns_buffer_write_u16(buf, (uint16_t)rr_type);
(void) getdns_dict_get_int(rr_dict, "class", &rr_class);
@ -1378,6 +1412,14 @@ _getdns_rr_dict2wire(const getdns_dict *rr_dict, gldns_buffer *buf)
gldns_buffer_skip(buf, 2);
rdata_start = gldns_buffer_current(buf);
/* Special case CNAME payload */
if((rr_type == GETDNS_RRTYPE_CNAME) && (n_rdata_fields == 1) &&
(rd_def->type & GETDNS_RDF_BINDATA) && !(rd_def->type & GETDNS_RDF_REPEAT) &&
(GETDNS_RETURN_GOOD == (r = getdns_dict_get_bindata(rdata, rd_def->name, &rdata_raw)))) {
_getdns_rr_buffer_write_cached_name(buf, rdata_raw, name_cache);
} else {
for ( rd_def = rr_def->rdata
, n_rdata_fields = rr_def->n_rdata_fields
; n_rdata_fields ; n_rdata_fields-- , rd_def++ ) {
@ -1415,6 +1457,7 @@ _getdns_rr_dict2wire(const getdns_dict *rr_dict, gldns_buffer *buf)
break;
}
}
}
gldns_buffer_write_u16_at(buf, rdata_size_mark,
(uint16_t)(gldns_buffer_position(buf)-rdata_size_mark-2));
}

View File

@ -143,8 +143,25 @@ typedef struct _getdns_rr_def {
const _getdns_rr_def *_getdns_rr_def_lookup(uint16_t rr_type);
getdns_return_t _getdns_rr_dict2wire(
const getdns_dict *rr_dict, gldns_buffer *buf);
#define NAME_CACHE_ENTRIES 4
typedef struct __name_cache_entry {
getdns_bindata *name;
unsigned name_offset;
} name_cache_entry_t;
typedef struct __name_cache {
unsigned count;
name_cache_entry_t entry[NAME_CACHE_ENTRIES];
} name_cache_t;
void _getdns_rr_buffer_write_cached_name(
gldns_buffer *buf, getdns_bindata *name, name_cache_t *name_cache);
getdns_return_t _getdns_rr_dict2wire_cache(
const getdns_dict *rr_dict, gldns_buffer *buf, name_cache_t *name_cache);
#define _getdns_rr_dict2wire(d, b) _getdns_rr_dict2wire_cache((d),(b), NULL)
const char *_getdns_rr_type_name(int rr_type);

@ -1 +1 @@
Subproject commit 187838104f3cfc9634148ae41a717e00c0d68e67
Subproject commit 89ff45974cafa7e03f0503ed013fe3e680698c20

View File

@ -33,6 +33,10 @@
#include "config.h"
#ifndef USE_WINSOCK
#include <netdb.h>
#endif
/* Intercept and do not sent out COM DS queries with TLS
* For debugging purposes only. Never commit with this turned on.
*/
@ -53,6 +57,7 @@
#include "general.h"
#include "pubkey-pinning.h"
/* WSA TODO:
* STUB_TCP_RETRY added to deal with edge triggered event loops (versus
* level triggered). See also lines containing WSA TODO below...
@ -73,10 +78,6 @@
/* Arbritray number of message for EDNS keepalive resend*/
#define EDNS_KEEPALIVE_RESEND 5
static time_t secret_rollover_time = 0;
static uint32_t secret = 0;
static uint32_t prev_secret = 0;
static void upstream_read_cb(void *userarg);
static void upstream_write_cb(void *userarg);
static void upstream_idle_timeout_cb(void *userarg);
@ -97,47 +98,6 @@ uint64_t _getdns_get_time_as_uintt64();
/* General utility functions */
/*****************************/
static void
rollover_secret()
{
time_t now = 0;
/* Create and roll server secrets */
if (time(&now) <= secret_rollover_time)
return;
/* Remember previous secret, in to keep answering on rollover
* boundary with old cookie.
*/
prev_secret = secret;
secret = arc4random();
/* Next rollover over EDNS_COOKIE_ROLLOVER_TIME with 30% jitter,
* I.e. some offset + or - 15% of the future point in time.
*/
secret_rollover_time = now + (EDNS_COOKIE_ROLLOVER_TIME / 20 * 17)
+ arc4random_uniform(EDNS_COOKIE_ROLLOVER_TIME / 10 * 3);
}
static void
calc_new_cookie(getdns_upstream *upstream, uint8_t *cookie)
{
unsigned char md_value[GETDNS_TLS_MAX_DIGEST_LENGTH];
size_t md_len;
size_t i;
sa_family_t af = upstream->addr.ss_family;
void *sa_addr = ((struct sockaddr*)&upstream->addr)->sa_data;
size_t addr_len = ( af == AF_INET6 ? sizeof(struct sockaddr_in6)
: af == AF_INET ? sizeof(struct sockaddr_in)
: 0 ) - sizeof(sa_family_t);
_getdns_tls_cookie_sha256(secret, sa_addr, addr_len, md_value, &md_len);
(void) memset(cookie, 0, 8);
for (i = 0; i < md_len; i++)
cookie[i % 8] ^= md_value[i];
}
static getdns_return_t
attach_edns_client_subnet_private(getdns_network_req *req)
{
@ -169,57 +129,72 @@ static getdns_return_t
attach_edns_cookie(getdns_network_req *req)
{
getdns_upstream *upstream = req->upstream;
uint16_t sz;
void* val;
uint8_t buf[8 + 32]; /* server cookies can be no larger than 32 bytes */
rollover_secret();
if (!upstream->has_client_cookie) {
calc_new_cookie(upstream, upstream->client_cookie);
upstream->secret = secret;
upstream->has_client_cookie = 1;
if (upstream->server_cookie_len) {
if (!req->badcookie_retry && bind(req->fd, (struct sockaddr *)
&upstream->src_addr, upstream->src_addr_len)) {
sz = 8;
val = upstream->client_cookie;
} else if (upstream->secret != secret) {
memcpy( upstream->prev_client_cookie
, upstream->client_cookie, 8);
upstream->has_prev_client_cookie = 1;
calc_new_cookie(upstream, upstream->client_cookie);
upstream->secret = secret;
_getdns_upstream_log(upstream,
GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_INFO,
"%-40s : Upstream : %s with source address: %s. "
"Renewing Client Cookie.\n", upstream->addr_str,
strerror(errno), upstream->src_addr_str);
sz = 8;
val = upstream->client_cookie;
} else if (!upstream->has_server_cookie) {
sz = 8;
val = upstream->client_cookie;
} else {
sz = 8 + upstream->server_cookie_len;
memcpy(buf, upstream->client_cookie, 8);
memcpy(buf+8, upstream->server_cookie, upstream->server_cookie_len);
val = buf;
upstream->server_cookie_len = 0;
upstream->src_addr_checked = 0;
} else
return _getdns_network_req_add_upstream_option(
req, EDNS_COOKIE_OPCODE,
upstream->server_cookie_len,
upstream->server_cookie);
}
return _getdns_network_req_add_upstream_option(req, EDNS_COOKIE_OPCODE, sz, val);
if (_getdns_get_now_ms() - upstream->src_addr_checked < 3600000) {
/* This upstream has been registered to *not* support cookies.
* We will recheck one hour after this was registered.
*/
return 0;
}
/* Try to get a new server cookie for this upstream
* Explicitly connect on UDP only.
*/
if (req->fd >= 0 && connect(req->fd,
(struct sockaddr*)&upstream->addr, upstream->addr_len)) {
_getdns_upstream_log(upstream,
GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_WARNING,
"%-40s : Upstream : Could not connect(): %s. "
"Required for privacy aware Cookies. Cookies disabled.\n",
upstream->addr_str, strerror(errno));
/* Don't recheck for another hour */
upstream->src_addr_checked = _getdns_get_now_ms();
return 0;
}
/* Create new client cookie */
req->cookie_sent = 1;
gldns_write_uint32(req->client_cookie, arc4random());
gldns_write_uint32(req->client_cookie + 4, arc4random());
return _getdns_network_req_add_upstream_option(
req, EDNS_COOKIE_OPCODE, 8, req->client_cookie);
}
/* Will find a matching OPT RR, but leaves the caller to validate it
*
* Returns 2 when found
* 0 when not found
* and 1 on FORMERR
*/
#define MATCH_OPT_FOUND 2
#define MATCH_OPT_NOT_FOUND 0
#define MATCH_OPT_ERROR 1
static int
match_edns_opt_rr(uint16_t code, uint8_t *response, size_t response_len,
match_edns_opt_rr(uint16_t code, getdns_network_req *netreq,
const uint8_t **position, uint16_t *option_len)
{
_getdns_rr_iter rr_iter_storage, *rr_iter;
const uint8_t *pos;
const uint8_t *pos, *rdata_end;
uint16_t rdata_len, opt_code = 0, opt_len = 0;
static uint8_t *NO_OPT_RR = (uint8_t *)"\x00\x00";
/* Search for the OPT RR (if any) */
if (!netreq->response_opt) {
_getdns_rr_iter rr_iter_storage, *rr_iter;
for ( rr_iter = _getdns_rr_iter_init(&rr_iter_storage
, response, response_len)
, netreq->response, netreq->response_len)
; rr_iter
; rr_iter = _getdns_rr_iter_next(rr_iter)) {
@ -228,95 +203,195 @@ match_edns_opt_rr(uint16_t code, uint8_t *response, size_t response_len,
if (gldns_read_uint16(rr_iter->rr_type) != GETDNS_RRTYPE_OPT)
continue;
break;
}
if (! rr_iter)
return 0; /* No OPT, no cookie */
pos = rr_iter->rr_type + 8;
if (! rr_iter) {
netreq->response_opt = NO_OPT_RR;
return MATCH_OPT_NOT_FOUND;
}
pos = netreq->response_opt = rr_iter->rr_type + 8;
#if defined(STUB_DEBUG) && STUB_DEBUG
char str_spc[8192], *str = str_spc;
size_t str_len = sizeof(str_spc);
uint8_t *data = (uint8_t *)rr_iter->pos;
size_t data_len = rr_iter->nxt - rr_iter->pos;
(void) gldns_wire2str_rr_scan(
&data, &data_len, &str, &str_len, (uint8_t *)rr_iter->pkt, rr_iter->pkt_end - rr_iter->pkt, NULL);
(void) gldns_wire2str_rr_scan(&data, &data_len, &str, &str_len,
(uint8_t *)rr_iter->pkt, rr_iter->pkt_end - rr_iter->pkt,
NULL);
DEBUG_STUB("%s %-35s: OPT RR: %s",
STUB_DEBUG_READ, __FUNC__, str_spc);
#endif
/* Check limits only the first time*/
if (pos + 2 > rr_iter->nxt
|| pos + 2 + gldns_read_uint16(pos) > rr_iter->nxt) {
netreq->response_opt = NO_OPT_RR;
return MATCH_OPT_ERROR;
}
} else if (netreq->response_opt == NO_OPT_RR)
return MATCH_OPT_NOT_FOUND;
else
/* Reuse earlier found option */
pos = netreq->response_opt;;
/* OPT found, now search for the specified option */
if (pos + 2 > rr_iter->nxt)
return 1; /* FORMERR */
rdata_len = gldns_read_uint16(pos);
pos += 2;
rdata_end = pos + rdata_len;
rdata_len = gldns_read_uint16(pos); pos += 2;
if (pos + rdata_len > rr_iter->nxt)
return 1; /* FORMERR */
while (pos < rr_iter->nxt) {
while (pos < rdata_end) {
opt_code = gldns_read_uint16(pos); pos += 2;
opt_len = gldns_read_uint16(pos); pos += 2;
if (pos + opt_len > rr_iter->nxt)
return 1; /* FORMERR */
if (pos + opt_len > rdata_end)
return MATCH_OPT_ERROR;
if (opt_code == code)
break;
pos += opt_len; /* Skip unknown options */
}
if (pos >= rr_iter->nxt || opt_code != code)
return 0; /* Everything OK, just no cookie found. */
if (pos >= rdata_end || opt_code != code)
return MATCH_OPT_NOT_FOUND;
*position = pos;
*option_len = opt_len;
return 2;
return MATCH_OPT_FOUND;
}
/* TODO: Test combinations of EDNS0 options*/
static int
match_and_process_server_cookie(
getdns_upstream *upstream, uint8_t *response, size_t response_len)
getdns_upstream *upstream, getdns_network_req *netreq)
{
const uint8_t *position = NULL;
uint16_t option_len = 0;
int found = match_edns_opt_rr(EDNS_COOKIE_OPCODE, response,
response_len, &position, &option_len);
if (found != 2)
return found;
int gai_r;
int found = match_edns_opt_rr(EDNS_COOKIE_OPCODE, netreq,
&position, &option_len);
if (found == MATCH_OPT_ERROR) {
_getdns_upstream_log(upstream,
GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_WARNING,
"%-40s : Upstream : Error getting Cookie option.\n",
upstream->addr_str);
if (option_len < 16 || option_len > 40)
return 1; /* FORMERR */
if (!upstream->has_client_cookie)
return 1; /* Cookie reply, but we didn't sent one */
if (memcmp(upstream->client_cookie, position, 8) != 0) {
if (!upstream->has_prev_client_cookie)
return 1; /* Cookie didn't match */
if (memcmp(upstream->prev_client_cookie, position, 8) != 0)
return 1; /* Previous cookie didn't match either */
upstream->has_server_cookie = 0;
return 0; /* Don't store server cookie, because it
* is for our previous client cookie
*/
return 1; /* Discard and wait for better response */
}
position += 8;
option_len -= 8;
upstream->has_server_cookie = 1;
else if (found == MATCH_OPT_NOT_FOUND) {
/* Option not found, server does not support cookies */
if (upstream->server_cookie_len > 8) {
_getdns_upstream_log(upstream,
GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_ERR,
"%-40s : Upstream : Server did not return "
" DNS Cookie. Response discarded.\n",
upstream->addr_str);
return 1; /* Discard response */
} else if (netreq->cookie_sent) {
_getdns_upstream_log(upstream,
GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_INFO,
"%-40s : Upstream : Does not support DNS Cookies"
". Retrying in one hour.\n", upstream->addr_str);
upstream->src_addr_checked = _getdns_get_now_ms();
}
return 0; /* Use response */
}
assert(found == MATCH_OPT_FOUND);
if (option_len < 16 || option_len > 40) {
_getdns_upstream_log(upstream,
GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_WARNING,
"%-40s : Upstream : "
"Unsupported Server Cookie size: %d.\n",
upstream->addr_str, (int)option_len);
return 1; /* Discard and wait for better response */
}
if (upstream->server_cookie_len > 8) {
if (memcmp(upstream->server_cookie, position, 8)) {
_getdns_upstream_log(upstream,
GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_WARNING,
"%-40s : Upstream : DNS Cookie did not match.\n",
upstream->addr_str);
return 1; /* Discard and wait for better response */
}
/* Update server cookie */
upstream->server_cookie_len = option_len;
(void) memcpy(upstream->server_cookie, position, option_len);
return 0; /* Use response */
} else if (!netreq->cookie_sent) {
_getdns_upstream_log(upstream,
GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_WARNING,
"%-40s : Upstream : "
"DNS Cookie received but none sent.\n",upstream->addr_str);
return 1; /* Discard and wait for better response */
}
if (memcmp(netreq->client_cookie, position, 8)) {
_getdns_upstream_log(upstream,
GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_WARNING,
"%-40s : Upstream : DNS Cookie did not match.\n",
upstream->addr_str);
return 1; /* Discard and wait for better response */
}
/* A new client cookie matched, store server cookie but only if we
* can get the source IP address.
*/
upstream->src_addr_checked = _getdns_get_now_ms();
upstream->src_addr_len = sizeof(upstream->src_addr);
if (getsockname(netreq->fd,(struct sockaddr*)
&upstream->src_addr, &upstream->src_addr_len)) {
_getdns_upstream_log(upstream,
GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_WARNING,
"%-40s : Upstream : Could not get source address: %s. "
"Privacy aware DNS Cookies not supported.\n",
upstream->addr_str, strerror(errno));
} else if ((gai_r = getnameinfo((struct sockaddr *)
&upstream->src_addr, upstream->src_addr_len,
upstream->src_addr_str, sizeof(upstream->src_addr_str),
NULL, 0, NI_NUMERICHOST))) {
_getdns_upstream_log(upstream,
GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_WARNING,
"%-40s : Upstream : Could not print source address: %s. "
"Privacy aware DNS Cookies not supported.\n",
upstream->addr_str, gai_strerror(gai_r));
} else {
switch (upstream->src_addr.ss_family) {
case AF_INET:
((struct sockaddr_in *)&upstream->src_addr)->sin_port = 0;
break;
case AF_INET6:
((struct sockaddr_in6*)&upstream->src_addr)->sin6_port = 0;
break;
default:
return 0;
}
_getdns_upstream_log(upstream,
GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_DEBUG,
"%-40s : Upstream : "
"Registering new Server Cookie for source address: %s.\n",
upstream->addr_str, upstream->src_addr_str);
upstream->server_cookie_len = option_len;
(void) memcpy(upstream->server_cookie, position, option_len);
return 0;
}
return 0;
}
static void
process_keepalive(
getdns_upstream *upstream, getdns_network_req *netreq,
uint8_t *response, size_t response_len)
process_keepalive( getdns_upstream *upstream, getdns_network_req *netreq)
{
const uint8_t *position = NULL;
uint16_t option_len = 0;
int found = match_edns_opt_rr(GLDNS_EDNS_KEEPALIVE, response,
response_len, &position, &option_len);
int found = match_edns_opt_rr(GLDNS_EDNS_KEEPALIVE, netreq,
&position, &option_len);
if (found != 2 || option_len != 2) {
if (netreq->keepalive_sent == 1) {
/* For TCP if no keepalive sent back, then we must use 0 idle timeout
@ -373,8 +448,27 @@ getdns_sock_nonblock(int sockfd)
#endif
}
/** best effort to set TCP send timeout */
static void
getdns_sock_tcp_send_timeout(getdns_upstream *upstream, int sockfd,
int send_timeout)
{
#if defined(HAVE_DECL_TCP_USER_TIMEOUT)
unsigned int val = send_timeout;
if (setsockopt(sockfd, IPPROTO_TCP, TCP_USER_TIMEOUT,
&val, sizeof(val)) != 0) {
_getdns_upstream_log(upstream,
GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_WARNING,
"%-40s : Upstream : "
"Could not enable TCP send timeout\n",
upstream->addr_str);
}
#endif
}
static int
tcp_connect(getdns_upstream *upstream, getdns_transport_list_t transport)
tcp_connect(getdns_upstream *upstream, getdns_transport_list_t transport,
int send_timeout)
{
#if defined(TCP_FASTOPEN) || defined(TCP_FASTOPEN_CONNECT)
# ifdef USE_WINSOCK
@ -393,6 +487,8 @@ tcp_connect(getdns_upstream *upstream, getdns_transport_list_t transport)
return -1;
getdns_sock_nonblock(fd);
if (send_timeout != -1)
getdns_sock_tcp_send_timeout(upstream, fd, send_timeout);
#ifdef USE_OSX_TCP_FASTOPEN
sa_endpoints_t endpoints;
endpoints.sae_srcif = 0;
@ -409,7 +505,7 @@ tcp_connect(getdns_upstream *upstream, getdns_transport_list_t transport)
_getdns_socketerror() == _getdns_EWOULDBLOCK)
return fd;
(void)transport;
(void)transport; /* unused parameter */
#else /* USE_OSX_TCP_FASTOPEN */
/* Note that error detection is different with TFO. Since the handshake
doesn't start till the sendto() lack of connection is often delayed until
@ -457,7 +553,7 @@ tcp_connect(getdns_upstream *upstream, getdns_transport_list_t transport)
"%-40s : Upstream : Could not setup TCP TFO\n",
upstream->addr_str);
# else
(void)transport;
(void)transport; /* unused parameter */
# endif/* HAVE_DECL_TCP_FASTOPEN*/
# endif /* HAVE_DECL_TCP_FASTOPEN_CONNECT */
#endif /* USE_OSX_TCP_FASTOPEN */
@ -613,6 +709,8 @@ static void
stub_timeout_cb(void *userarg)
{
getdns_network_req *netreq = (getdns_network_req *)userarg;
getdns_upstream *upstream = netreq? netreq->upstream: NULL;
getdns_upstreams *upstreams = upstream? upstream->upstreams: NULL;
DEBUG_STUB("%s %-35s: MSG: %p\n",
STUB_DEBUG_CLEANUP, __FUNC__, (void*)netreq);
stub_cleanup(netreq);
@ -627,6 +725,8 @@ stub_timeout_cb(void *userarg)
"%-40s : Upstream : UDP - Resps=%6d, Timeouts =%6d (logged every 100 responses)\n",
netreq->upstream->addr_str,
(int)netreq->upstream->udp_responses, (int)netreq->upstream->udp_timeouts);
/* Only choose next stream if the timeout is on current UDP stream */
if (upstreams && (upstream == &upstreams->upstreams[upstreams->current_udp]))
stub_next_upstream(netreq);
} else {
netreq->upstream->responses_timeouts++;
@ -957,7 +1057,9 @@ tls_create_object(getdns_dns_req *dnsreq, int fd, getdns_upstream *upstream)
}
}
_getdns_tls_connection_set_host_pinset(tls, upstream->tls_auth_name, upstream->tls_pubkey_pinset);
if (upstream->tls_pubkey_pinset)
_getdns_tls_connection_set_host_pinset(
tls, upstream->tls_auth_name, upstream->tls_pubkey_pinset);
/* Session resumption. There are trade-offs here. Want to do it when
possible only if we have the right type of connection. Note a change
@ -982,7 +1084,7 @@ tls_do_handshake(getdns_upstream *upstream)
int r;
while ((r = _getdns_tls_connection_do_handshake(upstream->tls_obj)) != GETDNS_RETURN_GOOD)
{
uint64_t timeout_tls = _getdns_ms_until_expiry(upstream->expires);
uint64_t timeout_tls = _getdns_ms_until_expiry(upstream->expires)/5*4;
if (timeout_tls < MIN_TLS_HS_TIMEOUT)
timeout_tls = MIN_TLS_HS_TIMEOUT;
@ -1035,8 +1137,8 @@ tls_do_handshake(getdns_upstream *upstream)
: "*Failure*" ));
upstream->tls_auth_state = GETDNS_AUTH_FAILED;
} else {
long verify_errno;
const char* verify_errmsg;
long verify_errno = 0;
const char* verify_errmsg = "Unknown verify error (fix reporting!)";
if (_getdns_tls_connection_certificate_verify(upstream->tls_obj, &verify_errno, &verify_errmsg)) {
upstream->tls_auth_state = GETDNS_AUTH_FAILED;
@ -1340,6 +1442,7 @@ _getdns_get_time_as_uintt64() {
/**************************/
static void stub_udp_write_cb(void *userarg);
static void
stub_udp_read_cb(void *userarg)
{
@ -1385,14 +1488,15 @@ stub_udp_read_cb(void *userarg)
if (GLDNS_ID_WIRE(netreq->response) != GLDNS_ID_WIRE(netreq->query))
return; /* Cache poisoning attempt ;) */
if (netreq->owner->edns_cookies && match_and_process_server_cookie(
upstream, netreq->response, read))
if (netreq->owner->edns_cookies) {
netreq->response_len = read;
if (match_and_process_server_cookie(upstream, netreq)) {
netreq->response_len = 0; /* 0 means error */
return; /* Client cookie didn't match? */
}
netreq->response_len = 0; /* 0 means error */
}
GETDNS_CLEAR_EVENT(dnsreq->loop, &netreq->event);
_getdns_closesocket(netreq->fd);
netreq->fd = -1;
while (GLDNS_TC_WIRE(netreq->response)) {
DEBUG_STUB("%s %-35s: MSG: %p TC bit set in response \n", STUB_DEBUG_READ,
__FUNC__, (void*)netreq);
@ -1403,6 +1507,9 @@ stub_udp_read_cb(void *userarg)
if (next_transport != GETDNS_TRANSPORT_TCP &&
next_transport != GETDNS_TRANSPORT_TLS)
break;
_getdns_closesocket(netreq->fd);
netreq->fd = -1;
/* For now, special case where fallback should be on the same upstream*/
if ((netreq->fd = upstream_connect(upstream, next_transport,
dnsreq)) == -1)
@ -1412,10 +1519,27 @@ stub_udp_read_cb(void *userarg)
_getdns_ms_until_expiry(dnsreq->expires),
getdns_eventloop_event_init(&netreq->event,
netreq, NULL, NULL, stub_timeout_cb));
return;
}
netreq->response_len = read;
if (netreq->owner->edns_cookies
&& !netreq->badcookie_retry
&& netreq->response_opt /* actually: assert(netreq->response_opt) */
&& (netreq->response_opt[-4] << 4 | GLDNS_RCODE_WIRE(netreq->response))
== GETDNS_RCODE_BADCOOKIE
&& netreq->fd >= 0) {
/* Retry over UDP with the newly learned Cookie */
netreq->badcookie_retry = 1;
GETDNS_SCHEDULE_EVENT(dnsreq->loop, netreq->fd,
_getdns_ms_until_expiry(dnsreq->expires),
getdns_eventloop_event_init(&netreq->event, netreq,
NULL, stub_udp_write_cb, stub_timeout_cb));
return;
}
_getdns_closesocket(netreq->fd);
netreq->fd = -1;
if (!dnsreq->context->round_robin_upstreams)
dnsreq->upstreams->current_udp = 0;
else {
@ -1582,16 +1706,12 @@ upstream_read_cb(void *userarg)
upstream->tcp.read_buf = NULL;
upstream->responses_received++;
/* !THIS CODE NEEDS TESTING! */
if (netreq->owner->edns_cookies &&
match_and_process_server_cookie(
netreq->upstream, upstream->tcp.read_buf,
upstream->tcp.read_pos - upstream->tcp.read_buf))
match_and_process_server_cookie(netreq->upstream, netreq))
return; /* Client cookie didn't match (or FORMERR) */
if (netreq->owner->context->idle_timeout != 0)
process_keepalive(netreq->upstream, netreq, netreq->response,
netreq->response_len);
process_keepalive(netreq->upstream, netreq);
netreq->debug_end_time = _getdns_get_time_as_uintt64();
/* This also reschedules events for the upstream*/
@ -2053,7 +2173,8 @@ upstream_connect(getdns_upstream *upstream, getdns_transport_list_t transport,
/* Use existing if available*/
if (upstream->fd != -1)
return upstream->fd;
fd = tcp_connect(upstream, transport);
fd = tcp_connect(upstream, transport,
dnsreq->context->tcp_send_timeout);
if (fd == -1) {
upstream_failed(upstream, 1);
return -1;

View File

@ -154,7 +154,8 @@ getdns_sync_cb(getdns_context *context, getdns_callback_type_t callback_type,
getdns_dict *response, void *userarg, getdns_transaction_t transaction_id)
{
getdns_sync_data *data = (getdns_sync_data *)userarg;
(void)context; (void)callback_type; (void)transaction_id;
(void)context; (void)callback_type; /* unused parameters */
(void)transaction_id; /* unused parameter */
assert(data);

View File

@ -457,7 +457,7 @@
void *userarg,
getdns_transaction_t transaction_id)
{
(void)context; (void)response; (void)userarg;
(void)context; (void)response; (void)userarg; /* unused parameters */
callback_called++;
@ -466,23 +466,23 @@
callback_canceled++;
ck_assert_msg(transaction_id % 2,
"Only callbacks with odd transaction_ids were canceled, this one is even: %d",
transaction_id);
(int)transaction_id);
}
else if(callback_type == GETDNS_CALLBACK_COMPLETE)
{
callback_completed++;
ck_assert_msg((transaction_id % 2) == 0,
"One callbacks with even transaction_ids should complete, this one is odd: %d",
transaction_id);
(int)transaction_id);
}
else
{
if(transaction_id % 2)
ck_abort_msg("callback_type should == GETDNS_CALLBACK_CANCEL for odd transaction_id (%d), got: %d",
transaction_id, callback_type);
(int)transaction_id, (int)callback_type);
else
ck_abort_msg("callback_type should == GETDNS_CALLBACK_COMPLETE for even transaction_id (%d), got %d",
transaction_id, callback_type);
(int)transaction_id, (int)callback_type);
}
}
@ -491,7 +491,7 @@
*/
void verify_getdns_cancel_callback(struct extracted_response *ex_response)
{
(void)ex_response;
(void)ex_response; /* unused parameter */
/*
* increment callback_called global to prove callback was called.
*/

View File

@ -57,6 +57,8 @@ int event_loop_type = 0;
void extract_response(struct getdns_dict *response, struct extracted_response *ex_response)
{
int have_answer_type = 0;
int get_reply = 0;
uint32_t rcode;
ck_assert_msg(response != NULL, "Response should not be NULL");
/* fprintf(stderr, "%s\n", getdns_pretty_print_dict(response)); */
@ -103,10 +105,18 @@ void extract_response(struct getdns_dict *response, struct extracted_response *e
ex_response->question = NULL;
return;
}
/* Work around dnsmasq issue in which NXDOMAIN AAAA responses
* are returned as NODATA. In such cases use the other A response
* which does have rcode NXDOMAIN.
*/
if (ex_response->status == GETDNS_RESPSTATUS_NO_NAME
&& !getdns_dict_get_int(response, "/replies_tree/1/header/rcode", &rcode)
&& rcode == GETDNS_RCODE_NXDOMAIN)
get_reply = 1;
ASSERT_RC(getdns_list_get_dict(ex_response->replies_tree, 0, &ex_response->replies_tree_sub_dict),
GETDNS_RETURN_GOOD, "Failed to extract \"replies_tree[0]\"");
ck_assert_msg(ex_response->replies_tree_sub_dict != NULL, "replies_tree[0] dict should not be NULL");
ASSERT_RC(getdns_list_get_dict(ex_response->replies_tree, get_reply, &ex_response->replies_tree_sub_dict),
GETDNS_RETURN_GOOD, "Failed to extract \"replies_tree[#]\"");
ck_assert_msg(ex_response->replies_tree_sub_dict != NULL, "replies_tree[#] dict should not be NULL");
ASSERT_RC(getdns_dict_get_list(ex_response->replies_tree_sub_dict, "additional", &ex_response->additional),
GETDNS_RETURN_GOOD, "Failed to extract \"additional\"");
@ -186,7 +196,7 @@ void assert_nodata(struct extracted_response *ex_response)
ASSERT_RC(getdns_list_get_length(ex_response->answer, &length),
GETDNS_RETURN_GOOD, "Failed to extract \"answer\" length");
ck_assert_msg(length == 0, "Expected \"answer\" length == 0, got %d", length);
ck_assert_msg(length == 0, "Expected \"answer\" length == 0, got %d", (int)length);
ASSERT_RC(ex_response->status, GETDNS_RESPSTATUS_NO_NAME, "Unexpected value for \"status\"");
}
@ -212,7 +222,7 @@ void assert_address_in_answer(struct extracted_response *ex_response, int a, int
ASSERT_RC(getdns_list_get_length(ex_response->answer, &length),
GETDNS_RETURN_GOOD, "Failed to extract \"answer\" length");
ck_assert_msg(length == ancount, "Expected \"answer\" length == ancount: %d, got %d", ancount, length);
ck_assert_msg(length == ancount, "Expected \"answer\" length == ancount: %d, got %d", (int)ancount, (int)length);
for(i = 0; i < length; i++)
{
@ -247,7 +257,7 @@ void assert_address_in_just_address_answers(struct extracted_response *ex_respon
GETDNS_RETURN_GOOD, "Failed to extract \"just_address_answers\" length");
if (length == 0) resp_str = getdns_pretty_print_dict(ex_response->response);
ck_assert_msg(length > 0, "Expected \"just_address_answers\" length > 0, got %d\n%s", length, resp_str);
ck_assert_msg(length > 0, "Expected \"just_address_answers\" length > 0, got %d\n%s", (int)length, resp_str);
if (length == 0) free(resp_str);
}
@ -284,7 +294,7 @@ void assert_soa_in_authority(struct extracted_response *ex_response)
ASSERT_RC(getdns_list_get_length(ex_response->authority, &length),
GETDNS_RETURN_GOOD, "Failed to extract \"authority\" length");
ck_assert_msg(length == nscount, "Expected \"authority\" length == nscount: %d, got %d", nscount, length);
ck_assert_msg(length == nscount, "Expected \"authority\" length == nscount: %d, got %d", (int)nscount, (int)length);
for(i = 0; i < length; i++)
{
@ -318,7 +328,7 @@ void assert_ptr_in_answer(struct extracted_response *ex_response)
ASSERT_RC(getdns_list_get_length(ex_response->answer, &length),
GETDNS_RETURN_GOOD, "Failed to extract \"answer\" length");
ck_assert_msg(length == ancount, "Expected \"answer\" length == ancount: %d, got %d", ancount, length);
ck_assert_msg(length == ancount, "Expected \"answer\" length == ancount: %d, got %d", (int)ancount, (int)length);
for(i = 0; i < length; i++)
{
@ -339,7 +349,7 @@ void destroy_callbackfn(struct getdns_context *context,
void *userarg,
getdns_transaction_t transaction_id) {
int* flag = (int*)userarg;
(void)callback_type; (void)transaction_id;
(void)callback_type; (void)transaction_id; /* unused parameters */
*flag = 1;
getdns_dict_destroy(response);
getdns_context_destroy(context);
@ -359,7 +369,7 @@ void callbackfn(struct getdns_context *context,
{
typedef void (*fn_ptr)(struct extracted_response *ex_response);
fn_ptr fn = ((fn_cont *)userarg)->fn;
(void)context; (void)transaction_id;
(void)context; (void)transaction_id; /* unused parameters */
/*
* If userarg is NULL, either a negative test case
@ -399,7 +409,7 @@ void callbackfn(struct getdns_context *context,
void update_callbackfn(struct getdns_context *context,
getdns_context_code_t changed_item)
{
(void)context;
(void)context; /* unused parameter */
ck_assert_msg(changed_item == expected_changed_item,
"Expected changed_item == %d, got %d",
changed_item, expected_changed_item);

View File

@ -183,6 +183,7 @@
}
END_TEST
#if 0
START_TEST (getdns_context_destroy_7)
{
/*
@ -205,7 +206,6 @@
RUN_EVENT_LOOP;
CONTEXT_DESTROY;
ck_assert_msg(flag == 1, "flag should == 1, got %d", flag);
}
END_TEST
@ -229,10 +229,10 @@
&flag, &transaction_id, destroy_callbackfn),
GETDNS_RETURN_GOOD, "Return code from getdns_address()");
getdns_cancel_callback(context, transaction_id);
RUN_EVENT_LOOP;
CONTEXT_DESTROY;
ck_assert_msg(flag == 1, "flag should == 1, got %d", flag);
}
END_TEST
@ -264,14 +264,14 @@
RUN_EVENT_LOOP;
CONTEXT_DESTROY;
ck_assert_msg(flag == 1, "flag should == 1, got %d", flag);
}
END_TEST
#endif
void verify_getdns_context_destroy(struct extracted_response *ex_response)
{
(void)ex_response;
(void)ex_response; /* unused parameter */
/*
* Sleep for a second to make getdns_context_destroy() wait.
*/
@ -301,10 +301,11 @@
tcase_add_test(tc_pos, getdns_context_destroy_4);
tcase_add_test(tc_pos, getdns_context_destroy_5);
tcase_add_test(tc_pos, getdns_context_destroy_6);
// raise aborts via assertion failures
#if 0
tcase_add_test_raise_signal(tc_pos, getdns_context_destroy_7, SIGABRT);
tcase_add_test_raise_signal(tc_pos, getdns_context_destroy_8, SIGABRT);
tcase_add_test_raise_signal(tc_pos, getdns_context_destroy_9, SIGABRT);
#endif
suite_add_tcase(s, tc_pos);
return s;

View File

@ -266,7 +266,7 @@ void timeout_3_cb(struct getdns_context *context,
getdns_callback_type_t callback_type,
struct getdns_dict * response,
void *userarg, getdns_transaction_t transaction_id) {
(void)response; (void)transaction_id;
(void)response; (void)transaction_id; /* unused parameters */
timeout_thread_data *tdata = (timeout_thread_data*)userarg;
tdata->num_callbacks++;
if (callback_type == GETDNS_CALLBACK_TIMEOUT) {

View File

@ -44,7 +44,8 @@
char *alabel = NULL;
ck_assert_msg( getdns_convert_alabel_to_ulabel( alabel ) == 0,
"Was not expecting %d from getdns_convert_alabel_to_ulabel()", getdns_convert_alabel_to_ulabel( alabel ) );
"Was not expecting %p from getdns_convert_alabel_to_ulabel()",
(void *)getdns_convert_alabel_to_ulabel( alabel ) );
}
END_TEST

View File

@ -45,7 +45,8 @@
ck_assert_msg(( getdns_convert_ulabel_to_alabel( ulabel ) == 0 ),
"Was not expecting %d from getdns_convert_ulabel_to_alabel()", getdns_convert_ulabel_to_alabel( ulabel ) );
"Was not expecting %p from getdns_convert_ulabel_to_alabel()",
(void *)getdns_convert_ulabel_to_alabel( ulabel ) );
}
END_TEST

View File

@ -161,7 +161,7 @@
GETDNS_RETURN_GOOD, "Return code from getdns_dict_get_bindata()");
ck_assert_msg(answer->size == bindata.size, "Expected bindata size == %d, got: %d",
bindata.size, answer->size);
(int)bindata.size, (int)answer->size);
ck_assert_msg(strcmp((char *)answer->data, (char *)bindata.data) == 0,
"Expected bindata data to be \"%s\", got: \"%s\"",
(char *)bindata.data, (char *)answer->data);

View File

@ -98,7 +98,7 @@
ASSERT_RC(getdns_list_get_length(answer, &length),
GETDNS_RETURN_GOOD, "Return code from getdns_list_get_length()");
ck_assert_msg(length == 3, "Expected length == 3, got %d", length);
ck_assert_msg(length == 3, "Expected length == 3, got %d", (int)length);
for(i = 0; i < length; i++)
{

View File

@ -112,9 +112,9 @@
ASSERT_RC(getdns_dict_get_bindata(this_dict, "bindata", &retrieved_bindata),
GETDNS_RETURN_GOOD, "Return code from getdns_dict_get_bindata()");
ck_assert_msg(retrieved_bindata->size, second_bindata.size,
ck_assert_msg(retrieved_bindata->size == second_bindata.size,
"Expected retrieved bindata size == %d, got: %d",
second_bindata.size, retrieved_bindata->size);
(int)second_bindata.size, (int)retrieved_bindata->size);
ck_assert_msg(strcmp((char *)retrieved_bindata->data, (char *)second_bindata.data) == 0,
"Expected retrieved bindata to be \"%s\", got: \"%s\"",
@ -152,7 +152,7 @@
ck_assert_msg(retrieved_bindata->size == bindata.size,
"Expected retrieved bindata size == %d, got: %d",
bindata.size, retrieved_bindata->size);
(int)bindata.size, (int)retrieved_bindata->size);
ck_assert_msg(strcmp((char *)retrieved_bindata->data, (char *)bindata.data) == 0,
"Expected bindata data to be \"%s\", got: \"%s\"",

View File

@ -47,7 +47,7 @@
ptr = getdns_display_ip_address(NULL);
ck_assert_msg(ptr == NULL, "Expected retrieved bindata == NULL, got: %p",
ptr);
(void *)ptr);
}
END_TEST
@ -64,7 +64,7 @@
ptr = getdns_display_ip_address(&bindata_of_ipv4_or_ipv6_address);
ck_assert_msg(ptr == NULL, "Expected pointer == NULL, got: %p",
ptr);
(void *)ptr);
}
END_TEST

View File

@ -53,7 +53,7 @@
void run_event_loop_impl(struct getdns_context* context, void* eventloop) {
struct ev_loop* loop = (struct ev_loop*) eventloop;
(void)context;
(void)context; /* unused parameter */
ev_run(loop, 0);
}

View File

@ -49,7 +49,7 @@
void run_event_loop_impl(struct getdns_context* context, void* eventloop) {
struct event_base* base = (struct event_base*) eventloop;
(void)context;
(void)context; /* unused parameter */
event_base_dispatch(base);
}

View File

@ -49,7 +49,7 @@
void run_event_loop_impl(struct getdns_context* context, void* eventloop) {
uv_loop_t* loop = (uv_loop_t*) eventloop;
(void)context;
(void)context; /* unused parameter */
uv_run(loop, UV_RUN_DEFAULT);
}

View File

@ -89,7 +89,7 @@
ASSERT_RC(getdns_list_get_length(list, &length),
GETDNS_RETURN_GOOD, "Return code from getdns_list_get_length()");
ck_assert_msg(length == 3, "Expected length == 3, got %d", length);
ck_assert_msg(length == 3, "Expected length == 3, got %d", (int)length);
LIST_DESTROY(list);
}
@ -110,7 +110,7 @@
ASSERT_RC(getdns_list_get_length(list, &length),
GETDNS_RETURN_GOOD, "Return code from getdns_list_get_length()");
ck_assert_msg(length == 0, "Expected length == 3, got %d", length);
ck_assert_msg(length == 0, "Expected length == 3, got %d", (int)length);
LIST_DESTROY(list);
}

View File

@ -37,11 +37,11 @@
#include "getdns/getdns_extra.h"
void run_event_loop_impl(struct getdns_context* context, void* eventloop) {
(void)eventloop;
(void)eventloop; /* unused parameter */
getdns_context_run(context);
}
void* create_eventloop_impl(struct getdns_context* context) {
(void)context;
(void)context; /* unused parameter */
return NULL;
}

View File

@ -211,8 +211,8 @@ void transport_cb(struct getdns_context *context,
struct getdns_dict * response,
void *userarg, getdns_transaction_t transaction_id) {
/* Don't really care about the answer*/
(void)context; (void)callback_type; (void)response;
(void)userarg; (void)transaction_id;
(void)context; (void)callback_type; (void)response; /* unused parameters */
(void)userarg; (void)transaction_id; /* unused parameters */
return;
}

View File

@ -57,7 +57,7 @@ this_callbackfn(struct getdns_context *this_context,
struct getdns_dict *this_response,
void *this_userarg, getdns_transaction_t this_transaction_id)
{
(void)this_context; (void)this_userarg;
(void)this_context; (void)this_userarg; /* unused parameters */
if (this_callback_type == GETDNS_CALLBACK_COMPLETE) { /* This is a callback with data */
char *res = getdns_pretty_print_dict(this_response);

View File

@ -17,4 +17,4 @@ rm -fr "${BUILDDIR}/build-stub-only"
mkdir "${BUILDDIR}/build-stub-only"
cd "${BUILDDIR}/build-stub-only"
rm -f CMakeCache.txt
cmake -E env CXXFLAGS="-g" cmake -DENABLE_STUB_ONLY=ON -DENABLE_DEBUG_SERVER=ON -DENABLE_DEBUG_ANCHOR=ON -DCMAKE_INSTALL_PREFIX=../install-stub-only $* ${SRCROOT}
cmake -E env CXXFLAGS="-g" cmake -DUSE_GNUTLS=OFF -DENABLE_STUB_ONLY=ON -DENABLE_DEBUG_SERVER=ON -DENABLE_DEBUG_ANCHOR=ON -DCMAKE_INSTALL_PREFIX=../install-stub-only $* ${SRCROOT}

View File

@ -5,3 +5,5 @@ qwerlkjhasdfpuiqwyerm.1234kjhrqwersv.com
-H 8.8.8.8
-H 2a04:b900:0:100::37
-A _acme-challenge.getdnsapi.net
@185.49.141.38 nlnetlabs.nl +edns_cookies
-L dnsprivacy.org

View File

@ -100,3 +100,19 @@
obj:/usr/local/lib/libunbound.so.8.1.5
obj:/usr/local/lib/libunbound.so.8.1.5
}
{
<insert_a_suppression_name_here>
Memcheck:Cond
obj:/usr/lib/x86_64-linux-gnu/libgnutls.so.*
obj:/usr/lib/x86_64-linux-gnu/libgnutls.so.*
obj:/usr/lib/x86_64-linux-gnu/libgnutls.so.*
obj:/usr/lib/x86_64-linux-gnu/libgnutls.so.*
obj:/usr/lib/x86_64-linux-gnu/libgnutls.so.*
fun:gnutls_x509_ext_import_subject_alt_names
fun:gnutls_x509_crt_import
fun:gnutls_x509_crt_list_import
fun:gnutls_x509_crt_list_import2
fun:gnutls_x509_trust_list_add_trust_mem
fun:gnutls_x509_trust_list_add_trust_file
fun:gnutls_x509_trust_list_add_system_trust
}

View File

@ -11,5 +11,5 @@ elif ! ( "./${TPKG_NAME}" "${TPKG_NAME}.net-dns.org" | tee out )
then
exit 1
else
diff out "${TPKG_NAME}.good"
diff out "${TPKG_NAME}.good" --ignore-matching-lines=";; MSG SIZE rcvd: "
fi

View File

@ -9,10 +9,6 @@ int main()
getdns_return_t r;
getdns_context *ctx = NULL;
getdns_dict *extensions = NULL;
getdns_bindata ipv4 = { 4, (uint8_t*)"IPv4" };
/* 185.49.141.37 */
getdns_bindata nsip = { 4, (uint8_t*)"\xb9\x31\x8c\x3c" };
getdns_dict *upstream = NULL;
getdns_list *upstreams = NULL;
getdns_dict *response = NULL;
uint32_t value;
@ -21,39 +17,20 @@ int main()
if ((r = getdns_context_create(&ctx, 1)))
fprintf(stderr, "Could not create context");
else if (!(extensions = getdns_dict_create_with_context(ctx))) {
fprintf(stderr, "Could not create dictionary");
r = GETDNS_RETURN_MEMORY_ERROR;
} else if ((r = getdns_dict_set_int(extensions, "/header/rd", 0)))
fprintf(stderr, "Could not set RD bit");
else if ((r = getdns_dict_set_int(extensions, "/add_opt_parameters/do_bit", 1)))
fprintf(stderr, "Could not set qtype");
else if (!(upstream = getdns_dict_create_with_context(ctx))) {
fprintf(stderr, "Could not create upstream dictionary");
r = GETDNS_RETURN_MEMORY_ERROR;
} else if ((r = getdns_dict_set_bindata(upstream, "address_type", &ipv4)))
fprintf(stderr, "Could set \"address_type\"");
else if ((r = getdns_dict_set_bindata(upstream, "address_data", &nsip)))
fprintf(stderr, "Could set \"address_data\"");
else if (!(upstreams = getdns_list_create_with_context(ctx))) {
fprintf(stderr, "Could not create upstreams list");
r = GETDNS_RETURN_MEMORY_ERROR;
} else if ((r = getdns_list_set_dict(upstreams, 0, upstream)))
fprintf(stderr, "Could not append upstream to upstreams list");
else if ((r = getdns_context_set_resolution_type(ctx, GETDNS_RESOLUTION_STUB)))
fprintf(stderr, "Could not set stub mode");
else if ((r = getdns_str2list("[ 185.49.140.60 ]", &upstreams)))
fprintf(stderr, "Could not make upstreams list");
else if ((r = getdns_context_set_upstream_recursive_servers(ctx, upstreams)))
fprintf(stderr, "Could not set upstreams list");
else if ((r = getdns_str2dict("{ header: { rd: 0 }"
", add_opt_parameters: { do_bit: 1 }"
"}", &extensions)))
fprintf(stderr, "Could not create extensions");
else if ((r = getdns_general_sync(ctx, "bogus.nlnetlabs.nl.", GETDNS_RRTYPE_TXT, extensions, &response)))
fprintf(stderr, "Could not do lookup");
@ -61,7 +38,8 @@ int main()
fprintf(stderr, "Could not get status from response");
else if (value != GETDNS_RESPSTATUS_GOOD) {
fprintf(stderr, "response['status'] != GETDNS_RESPSTATUS_GOOD");
fprintf(stderr, "response['status'] != GETDNS_RESPSTATUS_GOOD: %s"
, getdns_get_errorstr_by_id(value));
r = GETDNS_RETURN_GENERIC_ERROR;
} else if ((r = getdns_dict_get_int(response, "/replies_tree/0/header/rd", &value)))
@ -100,8 +78,6 @@ int main()
getdns_dict_destroy(response);
if (upstreams)
getdns_list_destroy(upstreams);
if (upstream)
getdns_dict_destroy(upstream);
if (extensions)
getdns_dict_destroy(extensions);
if (ctx)

View File

@ -134,38 +134,39 @@ for (( ii = 0; ii < 1; ii++)); do
if [[ $HAVE_SSL_HN_AUTH = 1 ]]
then
NUM_GOOD_QUERIES=8
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}" "L" "S"
"-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 TXT large.getdnsapi.net -l U @${SERVER_IP} -b 512 -D" "U" "-")
"-s -A getdnsapi.net -l L -m @${TLS_SERVER_IP} -K pin-sha256=\"${TLS_SERVER_KEY}\"" "L" "S")
#"-s -A getdnsapi.net -l U @185.49.141.38 +edns_cookies" "U" "-"
#"-s -G TXT large.getdnsapi.net -l U @8.8.8.8 -b 512 -D" "U" "-"
else
NUM_GOOD_QUERIES=6
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 TXT large.getdnsapi.net -l U @${SERVER_IP} -b 512 -D" "U" "-"
"-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 U @185.49.141.38 +edns_cookies" "U" "-"
# "-s -G TXT large.getdnsapi.net -l U @8.8.8.8 -b 512 -D" "U" "-"
fi
NUM_GOOD_FB_QUERIES=6
NUM_GOOD_FB_QUERIES=4
GOOD_FALLBACK_QUERIES=(
"-s -A getdnsapi.net -l LU @${SERVER_IP}" "U" "-"
"-s -A getdnsapi.net -l LT @${SERVER_IP}" "T" "-"
"-s -A getdnsapi.net -l LT @${TLS_SERVER_IP_NO_NAME}" "L" "N"
"-s -A getdnsapi.net -l LT -m @${TLS_SERVER_IP_NO_NAME}" "L" "N"
"-s -A getdnsapi.net -l L @${SERVER_IP} @${TLS_SERVER_IP_NO_NAME}" "L" "-"
"-s -G TXT large.getdnsapi.net -l UT @${SERVER_IP} -b 512 -D" "T" "-")
"-s -A getdnsapi.net -l L @${SERVER_IP} @${TLS_SERVER_IP_NO_NAME}" "L" "-")
#"-s -A getdnsapi.net -l LU @${SERVER_IP}" "U" "-"
#"-s -G TXT large.getdnsapi.net -l UT @$8.8.8.8 -b 512 -D" "T" "-"
NOT_AVAILABLE_QUERIES=(
"-s -A getdnsapi.net -l L @${SERVER_IP}"
@ -199,7 +200,7 @@ for (( ii = 0; ii < 1; ii++)); do
echo "*Success fallback cases:"
for (( j = 0; j < $NUM_GOOD_FB_QUERIES; j+=1 )); do
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]}
check_good "`"${GETDNS_STUB_QUERY}" '{tcp_send_timeout:1000}' -y 7 -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]}"
(( COUNT++ ))
done

View File

@ -408,39 +408,6 @@ getdns_return_t _getdns_tls_get_api_information(getdns_dict* dict);
*/
unsigned char* _getdns_tls_hmac_hash(struct mem_funcs* mfs, int algorithm, const void* key, size_t key_size, const void* data, size_t data_size, size_t* output_size);
/**
* Return a new HMAC handle.
*
* @param mfs pointer to getdns memory functions.
* @param algorithm hash algorithm to use (<code>GETDNS_HMAC_?</code>).
* @param key the key.
* @param key_size the key size.
* @return HMAC handle or NULL on error.
*/
_getdns_tls_hmac* _getdns_tls_hmac_new(struct mem_funcs* mfs, int algorithm, const void* key, size_t key_size);
/**
* Add data to a HMAC.
*
* @param h the HMAC.
* @param data the data to add.
* @param data_size the size of data to add.
* @return GETDNS_RETURN_GOOD if added.
* @return GETDNS_RETURN_INVALID_PARAMETER if h is null or has no HMAC.
* @return GETDNS_RETURN_GENERIC_ERROR on error.
*/
getdns_return_t _getdns_tls_hmac_add(_getdns_tls_hmac* h, const void* data, size_t data_size);
/**
* Return the HMAC digest and free the handle.
*
* @param mfs pointer to getdns memory functions.
* @param h the HMAC.
* @param output_size the output size will be written here if not NULL.
* @return output malloc'd buffer with output, NULL on error.
*/
unsigned char* _getdns_tls_hmac_end(struct mem_funcs* mfs, _getdns_tls_hmac* h, size_t* output_size);
/**
* Calculate a SHA1 hash.
*

View File

@ -72,6 +72,10 @@
#include <openssl/engine.h>
#endif
#if defined(HAVE_OPENSSL_DSA_H) && defined(USE_DSA)
#include <openssl/dsa.h>
#endif
/** fake DSA support for unit tests */
int fake_dsa = 0;
/** fake SHA1 support for unit tests */
@ -138,6 +142,69 @@ secalgo_hash_sha256(unsigned char* buf, size_t len, unsigned char* res)
#endif
}
/** hash structure for keeping track of running hashes */
struct secalgo_hash {
/** the openssl message digest context */
EVP_MD_CTX* ctx;
};
/** create secalgo hash with hash type */
static struct secalgo_hash* secalgo_hash_create_md(const EVP_MD* md)
{
struct secalgo_hash* h;
if(!md)
return NULL;
h = calloc(1, sizeof(*h));
if(!h)
return NULL;
h->ctx = EVP_MD_CTX_create();
if(!h->ctx) {
free(h);
return NULL;
}
if(!EVP_DigestInit_ex(h->ctx, md, NULL)) {
EVP_MD_CTX_destroy(h->ctx);
free(h);
return NULL;
}
return h;
}
struct secalgo_hash* secalgo_hash_create_sha384(void)
{
return secalgo_hash_create_md(EVP_sha384());
}
struct secalgo_hash* secalgo_hash_create_sha512(void)
{
return secalgo_hash_create_md(EVP_sha512());
}
int secalgo_hash_update(struct secalgo_hash* hash, uint8_t* data, size_t len)
{
return EVP_DigestUpdate(hash->ctx, (unsigned char*)data,
(unsigned int)len);
}
int secalgo_hash_final(struct secalgo_hash* hash, uint8_t* result,
size_t maxlen, size_t* resultlen)
{
if(EVP_MD_CTX_size(hash->ctx) > (int)maxlen) {
*resultlen = 0;
log_err("secalgo_hash_final: hash buffer too small");
return 0;
}
*resultlen = EVP_MD_CTX_size(hash->ctx);
return EVP_DigestFinal_ex(hash->ctx, result, NULL);
}
void secalgo_hash_delete(struct secalgo_hash* hash)
{
if(!hash) return;
EVP_MD_CTX_destroy(hash->ctx);
free(hash);
}
/**
* Return size of DS digest according to its hash algorithm.
* @param algo: DS digest algo.
@ -327,8 +394,10 @@ setup_dsa_sig(unsigned char** sig, unsigned int* len)
#ifdef HAVE_DSA_SIG_SET0
if(!DSA_SIG_set0(dsasig, R, S)) return 0;
#else
# ifndef S_SPLINT_S
dsasig->r = R;
dsasig->s = S;
# endif /* S_SPLINT_S */
#endif
*sig = NULL;
newlen = i2d_DSA_SIG(dsasig, sig);
@ -445,29 +514,13 @@ static int
setup_key_digest(int algo, EVP_PKEY** evp_key, const EVP_MD** digest_type,
unsigned char* key, size_t keylen)
{
#if defined(USE_DSA) && defined(USE_SHA1)
DSA* dsa;
#endif
RSA* rsa;
switch(algo) {
#if defined(USE_DSA) && defined(USE_SHA1)
case LDNS_DSA:
case LDNS_DSA_NSEC3:
*evp_key = EVP_PKEY_new();
*evp_key = sldns_key_dsa2pkey_raw(key, keylen);
if(!*evp_key) {
log_err("verify: malloc failure in crypto");
return 0;
}
dsa = sldns_key_buf2dsa_raw(key, keylen);
if(!dsa) {
verbose(VERB_QUERY, "verify: "
"sldns_key_buf2dsa_raw failed");
return 0;
}
if(EVP_PKEY_assign_DSA(*evp_key, dsa) == 0) {
verbose(VERB_QUERY, "verify: "
"EVP_PKEY_assign_DSA failed");
verbose(VERB_QUERY, "verify: sldns_key_dsa2pkey failed");
return 0;
}
#ifdef HAVE_EVP_DSS1
@ -490,20 +543,9 @@ setup_key_digest(int algo, EVP_PKEY** evp_key, const EVP_MD** digest_type,
#if defined(HAVE_EVP_SHA512) && defined(USE_SHA2)
case LDNS_RSASHA512:
#endif
*evp_key = EVP_PKEY_new();
*evp_key = sldns_key_rsa2pkey_raw(key, keylen);
if(!*evp_key) {
log_err("verify: malloc failure in crypto");
return 0;
}
rsa = sldns_key_buf2rsa_raw(key, keylen);
if(!rsa) {
verbose(VERB_QUERY, "verify: "
"sldns_key_buf2rsa_raw SHA failed");
return 0;
}
if(EVP_PKEY_assign_RSA(*evp_key, rsa) == 0) {
verbose(VERB_QUERY, "verify: "
"EVP_PKEY_assign_RSA SHA failed");
verbose(VERB_QUERY, "verify: sldns_key_rsa2pkey SHA failed");
return 0;
}
@ -527,20 +569,9 @@ setup_key_digest(int algo, EVP_PKEY** evp_key, const EVP_MD** digest_type,
#endif /* defined(USE_SHA1) || (defined(HAVE_EVP_SHA256) && defined(USE_SHA2)) || (defined(HAVE_EVP_SHA512) && defined(USE_SHA2)) */
case LDNS_RSAMD5:
*evp_key = EVP_PKEY_new();
*evp_key = sldns_key_rsa2pkey_raw(key, keylen);
if(!*evp_key) {
log_err("verify: malloc failure in crypto");
return 0;
}
rsa = sldns_key_buf2rsa_raw(key, keylen);
if(!rsa) {
verbose(VERB_QUERY, "verify: "
"sldns_key_buf2rsa_raw MD5 failed");
return 0;
}
if(EVP_PKEY_assign_RSA(*evp_key, rsa) == 0) {
verbose(VERB_QUERY, "verify: "
"EVP_PKEY_assign_RSA MD5 failed");
verbose(VERB_QUERY, "verify: sldns_key_rsa2pkey MD5 failed");
return 0;
}
*digest_type = EVP_md5();
@ -818,6 +849,64 @@ secalgo_hash_sha256(unsigned char* buf, size_t len, unsigned char* res)
(void)HASH_HashBuf(HASH_AlgSHA256, res, buf, (unsigned long)len);
}
/** the secalgo hash structure */
struct secalgo_hash {
/** hash context */
HASHContext* ctx;
};
/** create hash struct of type */
static struct secalgo_hash* secalgo_hash_create_type(HASH_HashType tp)
{
struct secalgo_hash* h = calloc(1, sizeof(*h));
if(!h)
return NULL;
h->ctx = HASH_Create(tp);
if(!h->ctx) {
free(h);
return NULL;
}
return h;
}
struct secalgo_hash* secalgo_hash_create_sha384(void)
{
return secalgo_hash_create_type(HASH_AlgSHA384);
}
struct secalgo_hash* secalgo_hash_create_sha512(void)
{
return secalgo_hash_create_type(HASH_AlgSHA512);
}
int secalgo_hash_update(struct secalgo_hash* hash, uint8_t* data, size_t len)
{
HASH_Update(hash->ctx, (unsigned char*)data, (unsigned int)len);
return 1;
}
int secalgo_hash_final(struct secalgo_hash* hash, uint8_t* result,
size_t maxlen, size_t* resultlen)
{
unsigned int reslen = 0;
if(HASH_ResultLenContext(hash->ctx) > (unsigned int)maxlen) {
*resultlen = 0;
log_err("secalgo_hash_final: hash buffer too small");
return 0;
}
HASH_End(hash->ctx, (unsigned char*)result, &reslen,
(unsigned int)maxlen);
*resultlen = (size_t)reslen;
return 1;
}
void secalgo_hash_delete(struct secalgo_hash* hash)
{
if(!hash) return;
HASH_Destroy(hash->ctx);
free(hash);
}
size_t
ds_digest_size_supported(int algo)
{
@ -985,6 +1074,7 @@ static SECKEYPublicKey* nss_buf2ecdsa(unsigned char* key, size_t len, int algo)
return pk;
}
#if defined(USE_DSA) && defined(USE_SHA1)
static SECKEYPublicKey* nss_buf2dsa(unsigned char* key, size_t len)
{
SECKEYPublicKey* pk;
@ -1045,6 +1135,7 @@ static SECKEYPublicKey* nss_buf2dsa(unsigned char* key, size_t len)
}
return pk;
}
#endif /* USE_DSA && USE_SHA1 */
static SECKEYPublicKey* nss_buf2rsa(unsigned char* key, size_t len)
{
@ -1444,6 +1535,82 @@ secalgo_hash_sha256(unsigned char* buf, size_t len, unsigned char* res)
_digest_nettle(SHA256_DIGEST_SIZE, (uint8_t*)buf, len, res);
}
/** secalgo hash structure */
struct secalgo_hash {
/** if it is 384 or 512 */
int active;
/** context for sha384 */
struct sha384_ctx ctx384;
/** context for sha512 */
struct sha512_ctx ctx512;
};
struct secalgo_hash* secalgo_hash_create_sha384(void)
{
struct secalgo_hash* h = calloc(1, sizeof(*h));
if(!h)
return NULL;
h->active = 384;
sha384_init(&h->ctx384);
return h;
}
struct secalgo_hash* secalgo_hash_create_sha512(void)
{
struct secalgo_hash* h = calloc(1, sizeof(*h));
if(!h)
return NULL;
h->active = 512;
sha512_init(&h->ctx512);
return h;
}
int secalgo_hash_update(struct secalgo_hash* hash, uint8_t* data, size_t len)
{
if(hash->active == 384) {
sha384_update(&hash->ctx384, len, data);
} else if(hash->active == 512) {
sha512_update(&hash->ctx512, len, data);
} else {
return 0;
}
return 1;
}
int secalgo_hash_final(struct secalgo_hash* hash, uint8_t* result,
size_t maxlen, size_t* resultlen)
{
if(hash->active == 384) {
if(SHA384_DIGEST_SIZE > maxlen) {
*resultlen = 0;
log_err("secalgo_hash_final: hash buffer too small");
return 0;
}
*resultlen = SHA384_DIGEST_SIZE;
sha384_digest(&hash->ctx384, SHA384_DIGEST_SIZE,
(unsigned char*)result);
} else if(hash->active == 512) {
if(SHA512_DIGEST_SIZE > maxlen) {
*resultlen = 0;
log_err("secalgo_hash_final: hash buffer too small");
return 0;
}
*resultlen = SHA512_DIGEST_SIZE;
sha512_digest(&hash->ctx512, SHA512_DIGEST_SIZE,
(unsigned char*)result);
} else {
*resultlen = 0;
return 0;
}
return 1;
}
void secalgo_hash_delete(struct secalgo_hash* hash)
{
if(!hash) return;
free(hash);
}
/**
* Return size of DS digest according to its hash algorithm.
* @param algo: DS digest algo.
@ -1508,13 +1675,21 @@ dnskey_algo_id_is_supported(int id)
{
/* uses libnettle */
switch(id) {
#if defined(USE_DSA) && defined(USE_SHA1)
case LDNS_DSA:
case LDNS_DSA_NSEC3:
#if defined(USE_DSA) && defined(USE_SHA1)
return 1;
#else
if(fake_dsa || fake_sha1) return 1;
return 0;
#endif
#ifdef USE_SHA1
case LDNS_RSASHA1:
case LDNS_RSASHA1_NSEC3:
#ifdef USE_SHA1
return 1;
#else
if(fake_sha1) return 1;
return 0;
#endif
#ifdef USE_SHA2
case LDNS_RSASHA256:
@ -1726,7 +1901,11 @@ _verify_nettle_ecdsa(sldns_buffer* buf, unsigned int digest_size, unsigned char*
{
uint8_t digest[SHA256_DIGEST_SIZE];
mpz_t x, y;
#ifdef HAVE_NETTLE_GET_SECP_256R1
nettle_ecc_point_init(&pubkey, nettle_get_secp_256r1());
#else
nettle_ecc_point_init(&pubkey, &nettle_secp_256r1);
#endif
nettle_mpz_init_set_str_256_u(x, SHA256_DIGEST_SIZE, key);
nettle_mpz_init_set_str_256_u(y, SHA256_DIGEST_SIZE, key+SHA256_DIGEST_SIZE);
nettle_mpz_set_str_256_u(signature.r, SHA256_DIGEST_SIZE, sigblock);
@ -1737,13 +1916,18 @@ _verify_nettle_ecdsa(sldns_buffer* buf, unsigned int digest_size, unsigned char*
res &= nettle_ecdsa_verify (&pubkey, SHA256_DIGEST_SIZE, digest, &signature);
mpz_clear(x);
mpz_clear(y);
nettle_ecc_point_clear(&pubkey);
break;
}
case SHA384_DIGEST_SIZE:
{
uint8_t digest[SHA384_DIGEST_SIZE];
mpz_t x, y;
#ifdef HAVE_NETTLE_GET_SECP_384R1
nettle_ecc_point_init(&pubkey, nettle_get_secp_384r1());
#else
nettle_ecc_point_init(&pubkey, &nettle_secp_384r1);
#endif
nettle_mpz_init_set_str_256_u(x, SHA384_DIGEST_SIZE, key);
nettle_mpz_init_set_str_256_u(y, SHA384_DIGEST_SIZE, key+SHA384_DIGEST_SIZE);
nettle_mpz_set_str_256_u(signature.r, SHA384_DIGEST_SIZE, sigblock);
@ -1819,6 +2003,15 @@ verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock,
return sec_status_bogus;
}
#ifndef USE_DSA
if((algo == LDNS_DSA || algo == LDNS_DSA_NSEC3) &&(fake_dsa||fake_sha1))
return sec_status_secure;
#endif
#ifndef USE_SHA1
if(fake_sha1 && (algo == LDNS_DSA || algo == LDNS_DSA_NSEC3 || algo == LDNS_RSASHA1 || algo == LDNS_RSASHA1_NSEC3))
return sec_status_secure;
#endif
switch(algo) {
#if defined(USE_DSA) && defined(USE_SHA1)
case LDNS_DSA:

View File

@ -47,6 +47,8 @@
#define sldns_ecdsa2pkey_raw gldns_ecdsa2pkey_raw
#define sldns_buffer_begin gldns_buffer_begin
#define sldns_buffer_limit gldns_buffer_limit
#define sldns_key_dsa2pkey_raw gldns_key_dsa2pkey_raw
#define sldns_key_rsa2pkey_raw gldns_key_rsa2pkey_raw
#include "util/val_secalgo.h"

View File

@ -366,7 +366,7 @@ void callback(getdns_context *context, getdns_callback_type_t callback_type,
getdns_dict *response, void *userarg, getdns_transaction_t trans_id)
{
char *response_str;
(void)context; (void)userarg;
(void)context; (void)userarg; /* unused parameters */
/* This is a callback with data */;
if (response && !quiet && (response_str = json ?
@ -1440,7 +1440,7 @@ static void request_cb(
dns_msg *msg = (dns_msg *)userarg;
uint32_t qid;
getdns_return_t r = GETDNS_RETURN_GOOD;
uint32_t n, rcode, dnssec_status;
uint32_t n, rcode, dnssec_status = GETDNS_DNSSEC_INDETERMINATE;
#if defined(SERVER_DEBUG) && SERVER_DEBUG
getdns_bindata *qname;
@ -1457,7 +1457,7 @@ static void request_cb(
if (qname_str != unknown_qname)
free(qname_str);
#else
(void)transaction_id;
(void)transaction_id; /* unused parameter */
#endif
assert(msg);
@ -1556,8 +1556,8 @@ static void incoming_request_handler(getdns_context *context,
getdns_dict *rr;
uint32_t rr_type;
(void)callback_type;
(void)userarg;
(void)callback_type; /* unused parameter */
(void)userarg; /* unused parameter */
if (!query_extensions_spc &&
!(query_extensions_spc = getdns_dict_create()))
@ -1757,7 +1757,7 @@ static void _getdns_query_log(void *userarg, uint64_t system,
gmtime_r(&tv.tv_sec, &tm);
#endif
strftime(buf, 10, "%H:%M:%S", &tm);
(void)userarg; (void)system; (void)level;
(void)userarg; (void)system; (void)level; /* unused parameters */
(void) fprintf(stderr, "[%s.%.6d] UPSTREAM ", buf, (int)tv.tv_usec);
(void) vfprintf(stderr, fmt, ap);
}

View File

@ -1569,10 +1569,10 @@ static void out_of_order_callback(getdns_context *context,
void *userarg,
getdns_transaction_t transaction_id)
{
(void) context;
(void) callback_type;
(void) response;
(void) transaction_id;
(void) context; /* unused parameter */
(void) callback_type; /* unused parameter */
(void) response; /* unused parameter */
(void) transaction_id; /* unused parameter */
struct async_query *query = (struct async_query *) userarg;
static unsigned callback_no;
@ -1717,7 +1717,7 @@ int main(int ac, char *av[])
bool use_tcp = false;
bool use_tls = false;
(void) ac;
(void) ac; /* unused parameter */
test_info.errout = stderr;
atexit(exit_tidy);

View File

@ -233,8 +233,6 @@ typedef struct getdns_network_req
int edns_maximum_udp_payload_size;
uint16_t max_udp_payload_size;
size_t keepalive_sent;
/* Network requests scheduled to write after me */
struct getdns_network_req *write_queue_tail;
@ -244,7 +242,13 @@ typedef struct getdns_network_req
getdns_auth_state_t debug_tls_auth_status;
getdns_bindata debug_tls_peer_cert;
const char *debug_tls_version;
size_t debug_udp;
/* Some booleans */
unsigned debug_udp : 1;
unsigned keepalive_sent : 1;
unsigned badcookie_retry: 1;
unsigned cookie_sent : 1;
uint8_t client_cookie[8];
/* When more space is needed for the wire_data response than is
* available in wire_data[], it will be allocated separately.
@ -267,6 +271,7 @@ typedef struct getdns_network_req
size_t base_query_option_sz;
size_t response_len;
uint8_t *response;
const uint8_t *response_opt; /* offset of OPT RR in response */
size_t wire_data_sz;
uint8_t wire_data[];

View File

@ -122,13 +122,13 @@ typedef struct my_event {
static void my_event_base_free(struct ub_event_base* base)
{
/* We don't allocate our event base, so no need to free */
(void)base;
(void)base; /* unused parameter */
return;
}
static int my_event_base_dispatch(struct ub_event_base* base)
{
(void)base;
(void)base; /* unused parameter */
/* We run the event loop extension for which this ub_event_base is an
* interface ourselfs, so no need to let libunbound call dispatch.
*/
@ -138,7 +138,7 @@ static int my_event_base_dispatch(struct ub_event_base* base)
static int my_event_base_loopexit(struct ub_event_base* base, struct timeval* tv)
{
(void)tv;
(void)tv; /* unused parameter */
/* Not sure when this will be called. But it is of no influence as we
* run the event loop ourself.
*/
@ -353,7 +353,7 @@ static int my_timer_del(struct ub_event* ev)
static int my_signal_add(struct ub_event* ub_ev, struct timeval* tv)
{
(void)ub_ev; (void)tv;
(void)ub_ev; (void)tv; /* unused parameters */
/* Only unbound daaemon workers use signals */
DEBUG_SCHED("UB_LOOP ERROR: signal_add()\n");
return -1;
@ -361,7 +361,7 @@ static int my_signal_add(struct ub_event* ub_ev, struct timeval* tv)
static int my_signal_del(struct ub_event* ub_ev)
{
(void)ub_ev;
(void)ub_ev; /* unused parameter */
/* Only unbound daaemon workers use signals */
DEBUG_SCHED("UB_LOOP ERROR: signal_del()\n");
return -1;
@ -370,13 +370,13 @@ static int my_signal_del(struct ub_event* ub_ev)
static void my_winsock_unregister_wsaevent(struct ub_event* ev)
{
/* wsa events don't get registered with libunbound */
(void)ev;
(void)ev; /* unused parameter */
}
static void my_winsock_tcp_wouldblock(struct ub_event* ev, int bits)
{
#ifndef USE_WINSOCK
(void)ev; (void)bits;
(void)ev; (void)bits; /* unused parameters */
#else
if (bits & UB_EV_READ)
AS_MY_EVENT(ev)->read_wouldblock = 1;
@ -434,7 +434,7 @@ static struct ub_event* my_signal_new(struct ub_event_base* base, int fd,
void (*cb)(int, short, void*), void* arg)
{
/* Not applicable, because in unbound used in the daemon only */
(void)base; (void)fd; (void)cb; (void)arg;
(void)base; (void)fd; (void)cb; (void)arg; /* unused parameters */
return NULL;
}
@ -442,7 +442,7 @@ static struct ub_event* my_winsock_register_wsaevent(struct ub_event_base *b,
void* wsaevent, void (*cb)(int, short, void*), void* arg)
{
/* Not applicable, because in unbound used for tubes only */
(void)b; (void)wsaevent; (void)cb; (void)arg;
(void)b; (void)wsaevent; (void)cb; (void)arg; /* unused parameters */
return NULL;
}

View File

@ -299,9 +299,10 @@ _getdns_rr_iter2rr_dict_canonical(
}
} else if (rdf->rdd_pos->type == GETDNS_RDF_SPECIAL)
val_type = wf_special;
else
assert(((val_type = wf_int), 0));
else {
val_type = wf_int;
assert(0);
}
if (! rdf->rdd_repeat) {
switch (val_type) {
case wf_int:
@ -642,6 +643,12 @@ _getdns_create_reply_dict(getdns_context *context, getdns_network_req *req,
rr_type == GETDNS_RRTYPE_RRSIG && rrsigs_in_answer)
*rrsigs_in_answer = 1;
if (section == SECTION_ADDITIONAL &&
rr_type == GETDNS_RRTYPE_OPT &&
getdns_dict_set_int( result, "/header/extended_rcode"
, (uint32_t)rr_iter->rr_type[4] << 4
| GLDNS_RCODE_WIRE(req->response)))
goto error;
if (section != SECTION_ANSWER) {
if (_getdns_list_append_this_dict(
sections[section], rr_dict))
@ -1402,7 +1409,7 @@ getdns_return_t
getdns_apply_network_result(getdns_network_req* netreq,
int rcode, void *pkt, int pkt_len, int sec, char* why_bogus)
{
(void)why_bogus;
(void)why_bogus; /* unused parameter */
netreq->dnssec_status = sec == 0 ? GETDNS_DNSSEC_INSECURE
: sec == 2 ? GETDNS_DNSSEC_SECURE

View File

@ -213,6 +213,17 @@ INLINE uint64_t _getdns_ms_until_expiry(uint64_t expires)
return now_ms >= expires ? 0 : expires - now_ms;
}
INLINE uint64_t _getdns_get_now_ms2(uint64_t *now_ms)
{
struct timeval tv;
if (!now_ms) return _getdns_get_now_ms();
if (*now_ms) return *now_ms;
(void) gettimeofday(&tv, NULL);
return (*now_ms = (uint64_t)tv.tv_sec * 1000 + tv.tv_usec / 1000);
}
INLINE uint64_t _getdns_ms_until_expiry2(uint64_t expires, uint64_t *now_ms)
{
if (*now_ms == 0) *now_ms = _getdns_get_now_ms();

View File

@ -1,10 +1,10 @@
#!/bin/sh
REPO=http://unbound.net/svn/trunk
REPO=https://raw.githubusercontent.com/NLnetLabs/unbound/master
wget -O rbtree.c ${REPO}/util/rbtree.c
wget -O orig-headers/rbtree.h ${REPO}/util/rbtree.h
wget -O val_secalgo.c ${REPO}/validator/val_secalgo.c
wget -O ../tls/val_secalgo.c ${REPO}/validator/val_secalgo.c
wget -O orig-headers/val_secalgo.h ${REPO}/validator/val_secalgo.h
wget -O lruhash.c ${REPO}/util/storage/lruhash.c
wget -O orig-headers/lruhash.h ${REPO}/util/storage/lruhash.h

View File

@ -42,7 +42,6 @@
#include "config.h"
#include "util/locks.h"
#include <signal.h>
#include <string.h>
#ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif

View File

@ -1,4 +1,7 @@
/*
May 2019(Wouter) patch to enable the valgrind clean implementation all the
time. This enables better security audit and checks, which is better
than the speedup. Git issue #30. Renamed the define ARRAY_CLEAN_ACCESS.
February 2013(Wouter) patch defines for BSD endianness, from Brad Smith.
January 2012(Wouter) added randomised initial value, fallout from 28c3.
March 2007(Wouter) adapted from lookup3.c original, add config.h include.
@ -44,12 +47,18 @@ on 1 byte), but shoehorning those bytes into integers efficiently is messy.
-------------------------------------------------------------------------------
*/
/*#define SELF_TEST 1*/
#define ARRAY_CLEAN_ACCESS 1
#include "config.h"
#include "util/storage/lookup3.h"
#include <stdio.h> /* defines printf for tests */
#include <time.h> /* defines time_t for timings in the test */
/*
* If our build system provides endianness info, signalled by
* HAVE_TARGET_ENDIANNESS and the presence or absence of TARGET_IS_BIG_ENDIAN,
* use that. Otherwise try to work out the endianness.
*/
#if defined(HAVE_TARGET_ENDIANNESS)
# if defined(TARGET_IS_BIG_ENDIAN)
# define HASH_LITTLE_ENDIAN 0
@ -59,6 +68,7 @@ on 1 byte), but shoehorning those bytes into integers efficiently is messy.
# define HASH_BIG_ENDIAN 0
# endif
#else
# include <sys/param.h> /* attempt to define endianness */
# ifdef HAVE_SYS_TYPES_H
# include <sys/types.h> /* attempt to define endianness (solaris) */
# endif
@ -72,7 +82,6 @@ on 1 byte), but shoehorning those bytes into integers efficiently is messy.
# if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
# include <sys/endian.h> /* attempt to define endianness */
# endif
/*
* My best guess at if you are big-endian or little-endian. This may
* need adjustment.
@ -102,7 +111,11 @@ on 1 byte), but shoehorning those bytes into integers efficiently is messy.
# define HASH_LITTLE_ENDIAN 0
# define HASH_BIG_ENDIAN 0
# endif
#endif /* defined(TARGET_IS_BIG_ENDIAN) */
#endif /* defined(HAVE_TARGET_ENDIANNESS) */
#define hashsize(n) ((uint32_t)1<<(n))
#define hashmask(n) (hashsize(n)-1)
#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
/* random initial value */
static uint32_t raninit = (uint32_t)0xdeadbeef;
@ -113,10 +126,6 @@ hash_set_raninit(uint32_t v)
raninit = v;
}
#define hashsize(n) ((uint32_t)1<<(n))
#define hashmask(n) (hashsize(n)-1)
#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
/*
-------------------------------------------------------------------------------
mix -- mix 3 32-bit values reversibly.
@ -345,7 +354,7 @@ uint32_t hashlittle( const void *key, size_t length, uint32_t initval)
u.ptr = key;
if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) {
const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */
#ifdef VALGRIND
#ifdef ARRAY_CLEAN_ACCESS
const uint8_t *k8;
#endif
@ -370,7 +379,7 @@ uint32_t hashlittle( const void *key, size_t length, uint32_t initval)
* still catch it and complain. The masking trick does make the hash
* noticeably faster for short strings (like English words).
*/
#ifndef VALGRIND
#ifndef ARRAY_CLEAN_ACCESS
switch(length)
{

View File

@ -40,8 +40,6 @@
*
*/
#include <stdlib.h>
#include "config.h"
#include "util/storage/lruhash.h"
#include "util/fptr_wlist.h"
@ -401,12 +399,12 @@ lruhash_remove(struct lruhash* table, hashvalue_type hash, void* key)
}
table->num--;
table->space_used -= (*table->sizefunc)(entry->key, entry->data);
lock_quick_unlock(&table->lock);
lock_rw_wrlock(&entry->lock);
if(table->markdelfunc)
(*table->markdelfunc)(entry->key);
lock_rw_unlock(&entry->lock);
lock_quick_unlock(&bin->lock);
lock_quick_unlock(&table->lock);
/* finish removal */
d = entry->data;
(*table->delkeyfunc)(entry->key, table->cb_arg);

View File

@ -36,8 +36,6 @@
#ifndef UTIL_LOCKS_H
#define UTIL_LOCKS_H
#include <string.h>
/**
* \file
* Locking primitives.
@ -221,7 +219,6 @@ void* ub_thread_key_get(ub_thread_key_type key);
#else /* we do not HAVE_SOLARIS_THREADS and no PTHREADS */
/******************* WINDOWS THREADS ************************/
#ifdef HAVE_WINDOWS_THREADS
#include <winsock2.h>
#include <windows.h>
/* Use a mutex */

View File

@ -43,6 +43,7 @@
#ifndef VALIDATOR_VAL_SECALGO_H
#define VALIDATOR_VAL_SECALGO_H
struct sldns_buffer;
struct secalgo_hash;
/** Return size of nsec3 hash algorithm, 0 if not supported */
size_t nsec3_hash_algo_size_supported(int id);
@ -67,6 +68,48 @@ int secalgo_nsec3_hash(int algo, unsigned char* buf, size_t len,
*/
void secalgo_hash_sha256(unsigned char* buf, size_t len, unsigned char* res);
/**
* Start a hash of type sha384. Allocates structure, then inits it,
* so that a series of updates can be performed, before the final result.
* @return hash structure. NULL on malloc failure or no support.
*/
struct secalgo_hash* secalgo_hash_create_sha384(void);
/**
* Start a hash of type sha512. Allocates structure, then inits it,
* so that a series of updates can be performed, before the final result.
* @return hash structure. NULL on malloc failure or no support.
*/
struct secalgo_hash* secalgo_hash_create_sha512(void);
/**
* Update a hash with more information to add to it.
* @param hash: the hash that is updated.
* @param data: data to add.
* @param len: length of data.
* @return false on failure.
*/
int secalgo_hash_update(struct secalgo_hash* hash, uint8_t* data, size_t len);
/**
* Get the final result of the hash.
* @param hash: the hash that has had updates to it.
* @param result: where to store the result.
* @param maxlen: length of the result buffer, eg. size of the allocation.
* If not large enough the routine fails.
* @param resultlen: the length of the result, returned to the caller.
* How much of maxlen is used.
* @return false on failure.
*/
int secalgo_hash_final(struct secalgo_hash* hash, uint8_t* result,
size_t maxlen, size_t* resultlen);
/**
* Delete the hash structure.
* @param hash: the hash to delete.
*/
void secalgo_hash_delete(struct secalgo_hash* hash);
/**
* Return size of DS digest according to its hash algorithm.
* @param algo: DS digest algo.

View File

@ -39,8 +39,6 @@
* Implementation of a redblack tree.
*/
#include <stdlib.h>
#include "config.h"
#include "log.h"
#include "fptr_wlist.h"

2
stubby

@ -1 +1 @@
Subproject commit a105556619d4873d20e18580cdbf877514e38405
Subproject commit b53867d1ec467822dbd9e1a0ad6598f84a9f5ed7