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
This commit is contained in:
Willem Toorop 2021-06-04 20:57:12 +02:00
commit e4661f957e
82 changed files with 1468 additions and 660 deletions

4
.gitmodules vendored
View File

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

View File

@ -19,8 +19,9 @@ addons:
- clang - clang
- wget - wget
- openssh-client - openssh-client
- libgnutls28-dev
script: script:
- mkdir tests - mkdir tests
- cd tests - cd tests
- ../src/test/tpkg/run-all.sh - ../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

@ -13,7 +13,7 @@ endif ()
set(PACKAGE "getdns") set(PACKAGE "getdns")
set(PACKAGE_NAME "getdns") set(PACKAGE_NAME "getdns")
set(PACKAGE_VERSION "1.6.0") set(PACKAGE_VERSION "1.7.0")
set(PACKAGE_BUGREPORT "team@getdnsapi.net") set(PACKAGE_BUGREPORT "team@getdnsapi.net")
set(PACKAGE_URL "https://getdnsapi.net") set(PACKAGE_URL "https://getdnsapi.net")
@ -25,7 +25,7 @@ set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}${RELEASE_CANDIDATE}")
set(PACKAGE_TARNAME "${PACKAGE}-${PACKAGE_VERSION}${RELEASE_CANDIDATE}") set(PACKAGE_TARNAME "${PACKAGE}-${PACKAGE_VERSION}${RELEASE_CANDIDATE}")
set(GETDNS_VERSION "${PACKAGE_VERSION}${RELEASE_CANDIDATE}") set(GETDNS_VERSION "${PACKAGE_VERSION}${RELEASE_CANDIDATE}")
set(GETDNS_NUMERIC_VERSION 0x01060000) set(GETDNS_NUMERIC_VERSION 0x01070000)
set(API_VERSION "December 2015") set(API_VERSION "December 2015")
set(API_NUMERIC_VERSION 0x07df0c00) set(API_NUMERIC_VERSION 0x07df0c00)
@ -68,10 +68,11 @@ set(API_NUMERIC_VERSION 0x07df0c00)
# getdns-1.5.0 had libversion 11:0:1 # getdns-1.5.0 had libversion 11:0:1
# getdns-1.5.1 had libversion 11:1:1 # getdns-1.5.1 had libversion 11:1:1
# getdns-1.5.2 had libversion 11:2:1 # getdns-1.5.2 had libversion 11:2:1
# getdns-1.6.0 has libversion 11:3:1 # getdns-1.6.0 had libversion 11:3:1
set(GETDNS_VERSION_CURRENT 11) # getdns-1.7.0 has libversion 12:0:2
set(GETDNS_VERSION_REVISION 3) set(GETDNS_VERSION_CURRENT 12)
set(GETDNS_VERSION_AGE 1) set(GETDNS_VERSION_REVISION 0)
set(GETDNS_VERSION_AGE 2)
project(getdns VERSION ${PACKAGE_VERSION} LANGUAGES C) project(getdns VERSION ${PACKAGE_VERSION} LANGUAGES C)
@ -102,7 +103,7 @@ elseif (APPLE)
elseif (UNIX) elseif (UNIX)
set(HOSTOS "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") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_POSIX_C_SOURCE=200112L -D_XOPEN_SOURCE=600")
endif () endif ()
if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
@ -166,6 +167,8 @@ option(BUILD_LIBUV "Build libuv support library available." ON)
option(USE_LIBIDN2 "Use libidn2 if available." ON) option(USE_LIBIDN2 "Use libidn2 if available." ON)
option(USE_GNUTLS "Use GnuTLS for TLS connections." OFF) 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. # Above names chosen for user consistency. Now define substituted names.
set(REQ_DEBUG ${ENABLE_DEBUG_REQ}) set(REQ_DEBUG ${ENABLE_DEBUG_REQ})
set(SCHED_DEBUG ${ENABLE_DEBUG_SCHED}) set(SCHED_DEBUG ${ENABLE_DEBUG_SCHED})
@ -334,8 +337,11 @@ check_include_file(openssl/err.h HAVE_OPENSSL_ERR_H)
check_include_file(openssl/rand.h HAVE_OPENSSL_RAND_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/conf.h HAVE_OPENSSL_CONF_H)
check_include_file(openssl/engine.h HAVE_OPENSSL_ENGINE_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)
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_SIG_set0 HAVE_DSA_SIG_SET0)
check_function_exists(DSA_set0_pqg HAVE_DSA_SET0_PQG) check_function_exists(DSA_set0_pqg HAVE_DSA_SET0_PQG)
check_function_exists(DSA_set0_key HAVE_DSA_SET0_KEY) check_function_exists(DSA_set0_key HAVE_DSA_SET0_KEY)
@ -489,9 +495,19 @@ if (NOT ENABLE_STUB_ONLY)
set(CMAKE_REQUIRED_INCLUDES ${LIBUNBOUND_INCLUDE_DIR}) set(CMAKE_REQUIRED_INCLUDES ${LIBUNBOUND_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${LIBUNBOUND_LIBRARIES}) set(CMAKE_REQUIRED_LIBRARIES ${LIBUNBOUND_LIBRARIES})
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.h" HAVE_UB_CTX_SET_STUB)
check_symbol_exists(ub_ctx_set_stub "unbound-event.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)
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 () endif ()
# Event loop extension # Event loop extension
@ -521,7 +537,14 @@ set(STRPTIME_TEST_SOURCE "\n
if (!res) return 1; return 0; }") if (!res) return 1; return 0; }")
if (HAVE_STRPTIME) if (HAVE_STRPTIME)
check_c_source_runs("${STRPTIME_TEST_SOURCE}" STRPTIME_WORKS) 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 () endif ()
try_compile(HAVE___FUNC__ try_compile(HAVE___FUNC__
@ -549,6 +572,8 @@ else ()
endif () endif ()
endif () endif ()
check_symbol_exists(TCP_USER_TIMEOUT "sys/socket.h;netinet/tcp.h" HAVE_DECL_TCP_USER_TIMEOUT)
# Main library # Main library
add_library(getdns_objects OBJECT add_library(getdns_objects OBJECT
src/anchor.c src/anchor.c
@ -770,27 +795,27 @@ if (USE_LIBEV)
set_property(TARGET ev_objects PROPERTY POSITION_INDEPENDENT_CODE 1) set_property(TARGET ev_objects PROPERTY POSITION_INDEPENDENT_CODE 1)
set_property(TARGET ev_objects PROPERTY C_STANDARD 11) set_property(TARGET ev_objects PROPERTY C_STANDARD 11)
if (ENABLE_STATIC) if (ENABLE_STATIC)
add_library(getdns_ex_ev STATIC $<TARGET_OBJECTS:ev_objects>) add_library(getdns_ext_ev STATIC $<TARGET_OBJECTS:ev_objects>)
target_include_directories(getdns_ex_ev PRIVATE Libev::Libev) target_include_directories(getdns_ext_ev PRIVATE Libev::Libev)
target_link_libraries(getdns_ex_ev PUBLIC getdns Libev::Libev) target_link_libraries(getdns_ext_ev PUBLIC getdns Libev::Libev)
if (Libunbound_FOUND) if (Libunbound_FOUND)
target_link_libraries(getdns_ex_ev PUBLIC Libunbound::Libunbound) target_link_libraries(getdns_ext_ev PUBLIC Libunbound::Libunbound)
endif () 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 () endif ()
if (ENABLE_SHARED) if (ENABLE_SHARED)
add_library(getdns_ex_ev_shared SHARED $<TARGET_OBJECTS:ev_objects>) add_library(getdns_ext_ev_shared SHARED $<TARGET_OBJECTS:ev_objects>)
target_include_directories(getdns_ex_ev_shared PRIVATE Libev::Libev) target_include_directories(getdns_ext_ev_shared PRIVATE Libev::Libev)
target_link_libraries(getdns_ex_ev_shared PUBLIC getdns_shared Libev::Libev) target_link_libraries(getdns_ext_ev_shared PUBLIC getdns_shared Libev::Libev)
if (Libunbound_FOUND) if (Libunbound_FOUND)
target_link_libraries(getdns_ex_ev_shared PUBLIC Libunbound::Libunbound) target_link_libraries(getdns_ext_ev_shared PUBLIC Libunbound::Libunbound)
endif () endif ()
set_target_properties(getdns_ex_ev_shared PROPERTIES OUTPUT_NAME getdns_ex_ev) set_target_properties(getdns_ext_ev_shared PROPERTIES OUTPUT_NAME getdns_ext_ev)
target_shared_library_version(getdns_ex_ev_shared ${GETDNS_VERSION_CURRENT} ${GETDNS_VERSION_REVISION} ${GETDNS_VERSION_AGE}) target_shared_library_version(getdns_ext_ev_shared ${GETDNS_VERSION_CURRENT} ${GETDNS_VERSION_REVISION} ${GETDNS_VERSION_AGE})
file(STRINGS src/extension/libev.symbols symbols) 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) 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 ()
endif () endif ()
else () else ()
@ -821,27 +846,27 @@ if (USE_LIBEVENT2)
set_property(TARGET event2_objects PROPERTY POSITION_INDEPENDENT_CODE 1) set_property(TARGET event2_objects PROPERTY POSITION_INDEPENDENT_CODE 1)
set_property(TARGET event2_objects PROPERTY C_STANDARD 11) set_property(TARGET event2_objects PROPERTY C_STANDARD 11)
if (ENABLE_STATIC) if (ENABLE_STATIC)
add_library(getdns_ex_event STATIC $<TARGET_OBJECTS:event2_objects>) add_library(getdns_ext_event STATIC $<TARGET_OBJECTS:event2_objects>)
target_include_directories(getdns_ex_event PRIVATE Libevent2::Libevent_code) target_include_directories(getdns_ext_event PRIVATE Libevent2::Libevent_code)
target_link_libraries(getdns_ex_event PUBLIC getdns Libevent2::Libevent_core) target_link_libraries(getdns_ext_event PUBLIC getdns Libevent2::Libevent_core)
if (Libunbound_FOUND) if (Libunbound_FOUND)
target_link_libraries(getdns_ex_event PUBLIC Libunbound::Libunbound) target_link_libraries(getdns_ext_event PUBLIC Libunbound::Libunbound)
endif () 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 () endif ()
if (ENABLE_SHARED) if (ENABLE_SHARED)
add_library(getdns_ex_event_shared SHARED $<TARGET_OBJECTS:event2_objects>) add_library(getdns_ext_event_shared SHARED $<TARGET_OBJECTS:event2_objects>)
target_include_directories(getdns_ex_event_shared PRIVATE Libevent2::Libevent_code) target_include_directories(getdns_ext_event_shared PRIVATE Libevent2::Libevent_code)
target_link_libraries(getdns_ex_event_shared PUBLIC getdns_shared Libevent2::Libevent_core) target_link_libraries(getdns_ext_event_shared PUBLIC getdns_shared Libevent2::Libevent_core)
if (Libunbound_FOUND) if (Libunbound_FOUND)
target_link_libraries(getdns_ex_event_shared PUBLIC Libunbound::Libunbound) target_link_libraries(getdns_ext_event_shared PUBLIC Libunbound::Libunbound)
endif () endif ()
set_target_properties(getdns_ex_event_shared PROPERTIES OUTPUT_NAME getdns_ex_event) set_target_properties(getdns_ext_event_shared PROPERTIES OUTPUT_NAME getdns_ext_event)
target_shared_library_version(getdns_ex_event_shared ${GETDNS_VERSION_CURRENT} ${GETDNS_VERSION_REVISION} ${GETDNS_VERSION_AGE}) target_shared_library_version(getdns_ext_event_shared ${GETDNS_VERSION_CURRENT} ${GETDNS_VERSION_REVISION} ${GETDNS_VERSION_AGE})
file(STRINGS src/extension/libevent.symbols symbols) 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) 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 ()
endif () endif ()
else () else ()
@ -873,27 +898,27 @@ if (USE_LIBUV)
set_property(TARGET uv_objects PROPERTY POSITION_INDEPENDENT_CODE 1) set_property(TARGET uv_objects PROPERTY POSITION_INDEPENDENT_CODE 1)
set_property(TARGET uv_objects PROPERTY C_STANDARD 11) set_property(TARGET uv_objects PROPERTY C_STANDARD 11)
if (ENABLE_STATIC) if (ENABLE_STATIC)
add_library(getdns_ex_uv STATIC $<TARGET_OBJECTS:uv_objects>) add_library(getdns_ext_uv STATIC $<TARGET_OBJECTS:uv_objects>)
target_include_directories(getdns_ex_uv PRIVATE Libuv::Libuv) target_include_directories(getdns_ext_uv PRIVATE Libuv::Libuv)
target_link_libraries(getdns_ex_uv PUBLIC getdns Libuv::Libuv) target_link_libraries(getdns_ext_uv PUBLIC getdns Libuv::Libuv)
if (Libunbound_FOUND) if (Libunbound_FOUND)
target_link_libraries(getdns_ex_uv PUBLIC Libunbound::Libunbound) target_link_libraries(getdns_ext_uv PUBLIC Libunbound::Libunbound)
endif () 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 () endif ()
if (ENABLE_SHARED) if (ENABLE_SHARED)
add_library(getdns_ex_uv_shared SHARED $<TARGET_OBJECTS:uv_objects>) add_library(getdns_ext_uv_shared SHARED $<TARGET_OBJECTS:uv_objects>)
target_include_directories(getdns_ex_uv_shared PRIVATE Libuv::Libuv) target_include_directories(getdns_ext_uv_shared PRIVATE Libuv::Libuv)
target_link_libraries(getdns_ex_uv_shared PUBLIC getdns_shared Libuv::Libuv) target_link_libraries(getdns_ext_uv_shared PUBLIC getdns_shared Libuv::Libuv)
if (Libunbound_FOUND) if (Libunbound_FOUND)
target_link_libraries(getdns_ex_uv_shared PUBLIC Libunbound::Libunbound) target_link_libraries(getdns_ext_uv_shared PUBLIC Libunbound::Libunbound)
endif () endif ()
set_target_properties(getdns_ex_uv_shared PROPERTIES OUTPUT_NAME getdns_ex_uv) set_target_properties(getdns_ext_uv_shared PROPERTIES OUTPUT_NAME getdns_ext_uv)
target_shared_library_version(getdns_ex_uv_shared ${GETDNS_VERSION_CURRENT} ${GETDNS_VERSION_REVISION} ${GETDNS_VERSION_AGE}) target_shared_library_version(getdns_ext_uv_shared ${GETDNS_VERSION_CURRENT} ${GETDNS_VERSION_REVISION} ${GETDNS_VERSION_AGE})
file(STRINGS src/extension/libuv.symbols symbols) 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) 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 ()
endif () endif ()
else () else ()
@ -955,7 +980,7 @@ if (BUILD_TESTING)
if (USE_LIBEVENT2) if (USE_LIBEVENT2)
add_executable(check_getdns_event ${GETDNS_TEST_SOURCE_FILES}) 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) add_test(NAME test_libevent COMMAND check_getdns_event)
set_property(TEST test_libevent PROPERTY set_property(TEST test_libevent PROPERTY
ENVIRONMENT "GETDNS_TEST_PORT=44321;CK_TIMEOUT_MULTIPLIER=2;CK_LOG_FILE_NAME=check_getdns_event.log" ENVIRONMENT "GETDNS_TEST_PORT=44321;CK_TIMEOUT_MULTIPLIER=2;CK_LOG_FILE_NAME=check_getdns_event.log"
@ -964,7 +989,7 @@ if (BUILD_TESTING)
if (USE_LIBEV) if (USE_LIBEV)
add_executable(check_getdns_ev ${GETDNS_TEST_SOURCE_FILES}) 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) add_test(NAME test_libev COMMAND check_getdns_ev)
set_property(TEST test_libev PROPERTY set_property(TEST test_libev PROPERTY
ENVIRONMENT "GETDNS_TEST_PORT=45321;CK_TIMEOUT_MULTIPLIER=2;CK_LOG_FILE_NAME=check_getdns_ev.log" ENVIRONMENT "GETDNS_TEST_PORT=45321;CK_TIMEOUT_MULTIPLIER=2;CK_LOG_FILE_NAME=check_getdns_ev.log"
@ -973,7 +998,7 @@ if (BUILD_TESTING)
if (USE_LIBUV) if (USE_LIBUV)
add_executable(check_getdns_uv ${GETDNS_TEST_SOURCE_FILES}) 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) add_test(NAME test_libuv COMMAND check_getdns_uv)
set_property(TEST test_libuv PROPERTY set_property(TEST test_libuv PROPERTY
ENVIRONMENT "GETDNS_TEST_PORT=46321;CK_TIMEOUT_MULTIPLIER=2;CK_LOG_FILE_NAME=check_getdns_uv.log" ENVIRONMENT "GETDNS_TEST_PORT=46321;CK_TIMEOUT_MULTIPLIER=2;CK_LOG_FILE_NAME=check_getdns_uv.log"
@ -1043,43 +1068,43 @@ configure_file(getdns.pc.in getdns.pc @ONLY)
# Installing. # Installing.
if (ENABLE_STATIC) 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) 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 () endif ()
if (USE_LIBEVENT2) 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 () endif ()
if (USE_LIBUV) 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 ()
endif () endif ()
if (ENABLE_SHARED) 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) 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 () endif ()
if (USE_LIBEVENT2) 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 () endif ()
if (USE_LIBUV) 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 ()
endif () endif ()
if (BUILD_GETDNS_QUERY) if (BUILD_GETDNS_QUERY)
install(TARGETS getdns_query RUNTIME DESTINATION bin) install(TARGETS getdns_query RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
endif () endif ()
if (BUILD_GETDNS_SERVER_MON) if (BUILD_GETDNS_SERVER_MON)
install(TARGETS getdns_server_mon RUNTIME DESTINATION bin) install(TARGETS getdns_server_mon RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
endif () endif ()
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/getdns DESTINATION include) install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/getdns DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/man3 DESTINATION share/man) install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/man3 DESTINATION share/man)
set(docdir share/doc/getdns) set(docdir share/doc/getdns)
install(FILES AUTHORS ChangeLog COPYING LICENSE NEWS README.md DESTINATION ${docdir}) install(FILES AUTHORS ChangeLog COPYING LICENSE NEWS README.md DESTINATION ${docdir})
install(FILES spec/index.html DESTINATION ${docdir}/spec) install(FILES spec/index.html DESTINATION ${docdir}/spec)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/getdns.pc DESTINATION lib/pkgconfig) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/getdns.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
install(CODE "message(\"\ install(CODE "message(\"\
***\n\ ***\n\
@ -1123,17 +1148,17 @@ if (BUILD_EXAMPLES)
if (USE_LIBEVENT2) if (USE_LIBEVENT2)
add_executable(example-simple-answers spec/example/example-simple-answers.c) add_executable(example-simple-answers spec/example/example-simple-answers.c)
target_include_directories(example-simple-answers PRIVATE spec/example) 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) set_property(TARGET example-simple-answers PROPERTY C_STANDARD 11)
add_executable(example-tree spec/example/example-tree.c) add_executable(example-tree spec/example/example-tree.c)
target_include_directories(example-tree PRIVATE spec/example) 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) set_property(TARGET example-tree PROPERTY C_STANDARD 11)
add_executable(example-reverse spec/example/example-reverse.c) add_executable(example-reverse spec/example/example-reverse.c)
target_include_directories(example-reverse PRIVATE spec/example) 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) set_property(TARGET example-reverse PROPERTY C_STANDARD 11)
else () else ()
message(WARNING "\ message(WARNING "\

View File

@ -1,3 +1,27 @@
* 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 * 2020-02-28: Version 1.6.0
* Issues #457, #458, #461: New symbols with libnettle >= 3.4. * Issues #457, #458, #461: New symbols with libnettle >= 3.4.
Thanks hanvinke & kometchtech for testing & reporting. Thanks hanvinke & kometchtech for testing & reporting.

View File

@ -58,6 +58,9 @@
#cmakedefine HAVE_OPENSSL_RAND_H 1 #cmakedefine HAVE_OPENSSL_RAND_H 1
#cmakedefine HAVE_OPENSSL_CONF_H 1 #cmakedefine HAVE_OPENSSL_CONF_H 1
#cmakedefine HAVE_OPENSSL_ENGINE_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_DSA_SIG_SET0 1 #cmakedefine HAVE_DSA_SIG_SET0 1
#cmakedefine HAVE_DSA_SET0_PQG 1 #cmakedefine HAVE_DSA_SET0_PQG 1
@ -88,8 +91,8 @@
#cmakedefine HAVE_OPENSSL_VERSION 1 #cmakedefine HAVE_OPENSSL_VERSION 1
#cmakedefine HAVE_SSL_CTX_DANE_ENABLE 1 #cmakedefine HAVE_SSL_CTX_DANE_ENABLE 1
#cmakedefine HAVE_SSL_CTX_SET_CIPHERSUITS 1 #cmakedefine HAVE_SSL_CTX_SET_CIPHERSUITES 1
#cmakedefine HAVE_SSL_SET_CIPHERSUITS 1 #cmakedefine HAVE_SSL_SET_CIPHERSUITES 1
#cmakedefine HAVE_OPENSSL_INIT_CRYPTO 1 #cmakedefine HAVE_OPENSSL_INIT_CRYPTO 1
@ -211,6 +214,8 @@
#cmakedefine USE_OSX_TCP_FASTOPEN 1 #cmakedefine USE_OSX_TCP_FASTOPEN 1
#cmakedefine HAVE_DECL_TCP_USER_TIMEOUT 1
#cmakedefine HAVE_NEW_UV_TIMER_CB 1 #cmakedefine HAVE_NEW_UV_TIMER_CB 1
#cmakedefine HAVE_TARGET_ENDIANNESS #cmakedefine HAVE_TARGET_ENDIANNESS
@ -447,7 +452,7 @@ static inline int _gldns_custom_vsnprintf(char *str, size_t size, const char *fo
# define ATTR_UNUSED(x) x # define ATTR_UNUSED(x) x
#elif defined(__cplusplus) #elif defined(__cplusplus)
# define ATTR_UNUSED(x) # define ATTR_UNUSED(x)
#elif defined(HAVE_ATTR_UNUSED) #elif defined(__GNUC__)
# define ATTR_UNUSED(x) x __attribute__((unused)) # define ATTR_UNUSED(x) x __attribute__((unused))
#else /* !HAVE_ATTR_UNUSED */ #else /* !HAVE_ATTR_UNUSED */
# define ATTR_UNUSED(x) x # define ATTR_UNUSED(x) x

View File

@ -20,7 +20,7 @@ function(target_shared_library_exports lib libname symbols)
file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/${libname}.ver" " ${symbol};\n") file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/${libname}.ver" " ${symbol};\n")
endforeach () endforeach ()
file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/${libname}.ver" "local:\n *;\n};\n") 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 () else ()
message(WARNING "Unknown platform, ${lib} exports not set.") message(WARNING "Unknown platform, ${lib} exports not set.")
endif () endif ()

View File

@ -76,7 +76,7 @@ getdns_dict **response)
The getdns_general(3) and getdns_general_sync functions provide public entry 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 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 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). getdns_address(3) which would replace getaddrinfo(3).
.HP 3 .HP 3

View File

@ -1,9 +1,9 @@
prefix=@prefix@ prefix=@prefix@
exec_prefix=${prefix} exec_prefix=${prefix}
libdir=${exec_prefix}/lib libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@
includedir=${prefix}/include includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
Name: getdns Name: getdns
Version: @GETDNS_VERSION@ Version: @GETDNS_VERSION@
Description: A modern asynchronous DNS library Description: A modern asynchronous DNS library

View File

@ -1,9 +1,9 @@
prefix=@prefix@ prefix=@prefix@
exec_prefix=${prefix} exec_prefix=${prefix}
libdir=${exec_prefix}/lib libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@
includedir=${prefix}/include includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
Name: getdns_ext_event Name: getdns_ext_event
Version: @GETDNS_VERSION@ Version: @GETDNS_VERSION@
Description: A modern asynchronous DNS library Description: A modern asynchronous DNS library

View File

@ -39,5 +39,5 @@ int mkstemp(char *template)
{ {
if (_mktemp_s(template, strlen(template) + 1) != 0) if (_mktemp_s(template, strlen(template) + 1) != 0)
return -1; 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_STATUS", 2 },
{ "GETDNS_OPCODE_UPDATE", 5 }, { "GETDNS_OPCODE_UPDATE", 5 },
{ "GETDNS_RCODE_BADALG", 21 }, { "GETDNS_RCODE_BADALG", 21 },
{ "GETDNS_RCODE_BADCOOKIE", 23 },
{ "GETDNS_RCODE_BADKEY", 17 }, { "GETDNS_RCODE_BADKEY", 17 },
{ "GETDNS_RCODE_BADMODE", 19 }, { "GETDNS_RCODE_BADMODE", 19 },
{ "GETDNS_RCODE_BADNAME", 20 }, { "GETDNS_RCODE_BADNAME", 20 },
@ -255,7 +256,6 @@ static struct const_name_info consts_name_info[] = {
{ "GETDNS_RCODE_BADTIME", 18 }, { "GETDNS_RCODE_BADTIME", 18 },
{ "GETDNS_RCODE_BADTRUNC", 22 }, { "GETDNS_RCODE_BADTRUNC", 22 },
{ "GETDNS_RCODE_BADVERS", 16 }, { "GETDNS_RCODE_BADVERS", 16 },
{ "GETDNS_RCODE_COOKIE", 23 },
{ "GETDNS_RCODE_FORMERR", 1 }, { "GETDNS_RCODE_FORMERR", 1 },
{ "GETDNS_RCODE_NOERROR", 0 }, { "GETDNS_RCODE_NOERROR", 0 },
{ "GETDNS_RCODE_NOTAUTH", 9 }, { "GETDNS_RCODE_NOTAUTH", 9 },
@ -328,6 +328,7 @@ static struct const_name_info consts_name_info[] = {
{ "GETDNS_RRTYPE_GPOS", 27 }, { "GETDNS_RRTYPE_GPOS", 27 },
{ "GETDNS_RRTYPE_HINFO", 13 }, { "GETDNS_RRTYPE_HINFO", 13 },
{ "GETDNS_RRTYPE_HIP", 55 }, { "GETDNS_RRTYPE_HIP", 55 },
{ "GETDNS_RRTYPE_HTTPS", 65 },
{ "GETDNS_RRTYPE_IPSECKEY", 45 }, { "GETDNS_RRTYPE_IPSECKEY", 45 },
{ "GETDNS_RRTYPE_ISDN", 20 }, { "GETDNS_RRTYPE_ISDN", 20 },
{ "GETDNS_RRTYPE_IXFR", 251 }, { "GETDNS_RRTYPE_IXFR", 251 },
@ -373,6 +374,7 @@ static struct const_name_info consts_name_info[] = {
{ "GETDNS_RRTYPE_SPF", 99 }, { "GETDNS_RRTYPE_SPF", 99 },
{ "GETDNS_RRTYPE_SRV", 33 }, { "GETDNS_RRTYPE_SRV", 33 },
{ "GETDNS_RRTYPE_SSHFP", 44 }, { "GETDNS_RRTYPE_SSHFP", 44 },
{ "GETDNS_RRTYPE_SVCB", 64 },
{ "GETDNS_RRTYPE_TA", 32768 }, { "GETDNS_RRTYPE_TA", 32768 },
{ "GETDNS_RRTYPE_TALINK", 58 }, { "GETDNS_RRTYPE_TALINK", 58 },
{ "GETDNS_RRTYPE_TKEY", 249 }, { "GETDNS_RRTYPE_TKEY", 249 },

View File

@ -926,6 +926,7 @@ upstream_init(getdns_upstream *upstream,
/* For sharing a socket to this upstream with TCP */ /* For sharing a socket to this upstream with TCP */
upstream->fd = -1; upstream->fd = -1;
upstream->expires = 0; upstream->expires = 0;
upstream->tls_fallback_ok = 0;
upstream->tls_obj = NULL; upstream->tls_obj = NULL;
upstream->tls_session = NULL; upstream->tls_session = NULL;
upstream->tls_cipher_list = NULL; upstream->tls_cipher_list = NULL;
@ -952,9 +953,12 @@ upstream_init(getdns_upstream *upstream,
(void) getdns_eventloop_event_init( (void) getdns_eventloop_event_init(
&upstream->finished_event, upstream, NULL, NULL, NULL); &upstream->finished_event, upstream, NULL, NULL, NULL);
upstream->has_client_cookie = 0; upstream->server_cookie_len = 0;
upstream->has_prev_client_cookie = 0; (void) memset(&upstream->server_cookie, 0,
upstream->has_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_alg = GETDNS_NO_TSIG;
upstream->tsig_dname_len = 0; upstream->tsig_dname_len = 0;
@ -1289,7 +1293,7 @@ transaction_id_cmp(const void *id1, const void *id2)
static void static void
NULL_update_callback( NULL_update_callback(
getdns_context *context, getdns_context_code_t code, void *userarg) 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 static int
netreq_expiry_cmp(const void *id1, const void *id2) netreq_expiry_cmp(const void *id1, const void *id2)
@ -1431,6 +1435,7 @@ getdns_context_create_with_extended_memory_functions(
result->timeout = 5000; result->timeout = 5000;
result->idle_timeout = 0; result->idle_timeout = 0;
result->tcp_send_timeout = -1;
result->follow_redirects = GETDNS_REDIRECTS_FOLLOW; result->follow_redirects = GETDNS_REDIRECTS_FOLLOW;
result->dns_root_servers = NULL; result->dns_root_servers = NULL;
#if defined(HAVE_LIBUNBOUND) && !defined(HAVE_UB_CTX_SET_STUB) #if defined(HAVE_LIBUNBOUND) && !defined(HAVE_UB_CTX_SET_STUB)
@ -2363,6 +2368,34 @@ getdns_context_set_idle_timeout(getdns_context *context, uint64_t timeout)
return GETDNS_RETURN_GOOD; return GETDNS_RETURN_GOOD;
} /* getdns_context_set_timeout */ } /* 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 * getdns_context_set_follow_redirects
@ -3728,7 +3761,7 @@ uint32_t
getdns_context_get_num_pending_requests(const getdns_context* context, getdns_context_get_num_pending_requests(const getdns_context* context,
struct timeval* next_timeout) struct timeval* next_timeout)
{ {
(void)next_timeout; (void)next_timeout; /* unused parameter */
if (!context) if (!context)
return GETDNS_RETURN_INVALID_PARAMETER; return GETDNS_RETURN_INVALID_PARAMETER;
@ -3833,6 +3866,9 @@ _get_context_settings(const getdns_context* context)
(context->timeout > 0xFFFFFFFFull) ? 0xFFFFFFFF: (uint32_t) context->timeout) (context->timeout > 0xFFFFFFFFull) ? 0xFFFFFFFF: (uint32_t) context->timeout)
|| getdns_dict_set_int(result, "idle_timeout", || getdns_dict_set_int(result, "idle_timeout",
(context->idle_timeout > 0xFFFFFFFFull) ? 0xFFFFFFFF : (uint32_t) context->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", || getdns_dict_set_int(result, "limit_outstanding_queries",
context->limit_outstanding_queries) context->limit_outstanding_queries)
|| getdns_dict_set_int(result, "dnssec_allowed_skew", || getdns_dict_set_int(result, "dnssec_allowed_skew",
@ -3895,6 +3931,14 @@ _get_context_settings(const getdns_context* context)
getdns_list_destroy(list); getdns_list_destroy(list);
goto error; 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) { if (context->dns_transport_count > 0) {
/* create a namespace list */ /* create a namespace list */
if (!(list = getdns_list_create_with_context(context))) if (!(list = getdns_list_create_with_context(context)))
@ -4102,7 +4146,7 @@ getdns_context_set_use_threads(getdns_context* context, int use_threads) {
else else
r = ub_ctx_async(context->unbound_ctx, 0); r = ub_ctx_async(context->unbound_ctx, 0);
#else #else
(void)use_threads; (void)use_threads; /* unused parameter */
#endif #endif
return r == 0 ? GETDNS_RETURN_GOOD : GETDNS_RETURN_CONTEXT_UPDATE_FAIL; return r == 0 ? GETDNS_RETURN_GOOD : GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
} }
@ -4296,6 +4340,16 @@ CONTEXT_GETTER(timeout , uint64_t)
CONTEXT_GETTER(idle_timeout , uint64_t) CONTEXT_GETTER(idle_timeout , uint64_t)
CONTEXT_GETTER(follow_redirects , getdns_redirects_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_return_t
getdns_context_get_dns_root_servers( getdns_context_get_dns_root_servers(
const getdns_context *context, getdns_list **value) const getdns_context *context, getdns_list **value)
@ -4635,6 +4689,7 @@ _getdns_context_config_setting(getdns_context *context,
CONTEXT_SETTING_INT(dns_transport) CONTEXT_SETTING_INT(dns_transport)
CONTEXT_SETTING_ARRAY(dns_transport_list, transport_list) CONTEXT_SETTING_ARRAY(dns_transport_list, transport_list)
CONTEXT_SETTING_INT(idle_timeout) CONTEXT_SETTING_INT(idle_timeout)
CONTEXT_SETTING_INT(tcp_send_timeout)
CONTEXT_SETTING_INT(limit_outstanding_queries) CONTEXT_SETTING_INT(limit_outstanding_queries)
CONTEXT_SETTING_INT(timeout) CONTEXT_SETTING_INT(timeout)
CONTEXT_SETTING_INT(follow_redirects) CONTEXT_SETTING_INT(follow_redirects)
@ -4877,7 +4932,7 @@ FILE *_getdns_context_get_priv_fp(
_getdns_log(&context->log _getdns_log(&context->log
, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_INFO , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_INFO
, "Error opening \"%s\": %s\n" , "Error opening \"%s\": %s\n"
, path, _getdns_errnostr()); , path, _getdns_fileerrnostr());
return f; return f;
} }
@ -4956,31 +5011,31 @@ int _getdns_context_write_priv_file(getdns_context *context,
_getdns_log(&context->log _getdns_log(&context->log
, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_INFO , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_INFO
, "Could not create temporary file \"%s\": %s\n" , "Could not create temporary file \"%s\": %s\n"
, tmpfn, _getdns_errnostr()); , tmpfn, _getdns_fileerrnostr());
else if (!(f = fdopen(fd, "w"))) else if (!(f = fdopen(fd, "w")))
_getdns_log(&context->log _getdns_log(&context->log
, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR
, "Error opening temporary file \"%s\": %s\n" , "Error opening temporary file \"%s\": %s\n"
, tmpfn, _getdns_errnostr()); , tmpfn, _getdns_fileerrnostr());
else if (fwrite(content->data, 1, content->size, f) < content->size) else if (fwrite(content->data, 1, content->size, f) < content->size)
_getdns_log(&context->log _getdns_log(&context->log
, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR
, "Error writing to temporary file \"%s\": %s\n" , "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(&context->log
, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR
, "Error closing temporary file \"%s\": %s\n" , "Error closing temporary file \"%s\": %s (%p)\n"
, tmpfn, _getdns_errnostr()); , tmpfn, _getdns_fileerrnostr(), f);
else if (rename(tmpfn, path) < 0) else if (rename(tmpfn, path) < 0)
_getdns_log(&context->log _getdns_log(&context->log
, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR
, "Error renaming temporary file \"%s\" to \"%s\"" , "Error renaming temporary file \"%s\" to \"%s\""
": %s\n", tmpfn, path, _getdns_errnostr()); ": %s\n", tmpfn, path, _getdns_fileerrnostr());
else { else {
context->can_write_appdata = PROP_ABLE; context->can_write_appdata = PROP_ABLE;
return 1; return 1;
@ -5033,7 +5088,7 @@ int _getdns_context_can_write_appdata(getdns_context *context)
_getdns_log(&context->log _getdns_log(&context->log
, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR
, "Error unlinking write test file: \"%s\": %s\n" , "Error unlinking write test file: \"%s\": %s\n"
, path, _getdns_errnostr()); , path, _getdns_fileerrnostr());
return 1; return 1;
} }
@ -5346,7 +5401,7 @@ getdns_context_set_tls_curves_list(
dispatch_updated(context, GETDNS_CONTEXT_CODE_TLS_CIPHER_LIST); dispatch_updated(context, GETDNS_CONTEXT_CODE_TLS_CIPHER_LIST);
return GETDNS_RETURN_GOOD; return GETDNS_RETURN_GOOD;
#else #else
(void)tls_curves_list; (void)tls_curves_list; /* unused parameter */
return GETDNS_RETURN_NOT_IMPLEMENTED; return GETDNS_RETURN_NOT_IMPLEMENTED;
#endif #endif
} }

View File

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

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) if (idn2_lookup_u8((uint8_t *)ulabel, &alabel, IDN2_TRANSITIONAL) == IDN2_OK)
return (char *)alabel; return (char *)alabel;
#else #else
(void)ulabel; (void)ulabel; /* unused parameter */
#endif #endif
return NULL; return NULL;
} }
@ -149,7 +149,7 @@ getdns_convert_alabel_to_ulabel(const char *alabel)
if (idn2_to_unicode_8z8z(alabel, &ulabel, 0) == IDN2_OK) if (idn2_to_unicode_8z8z(alabel, &ulabel, 0) == IDN2_OK)
return ulabel; return ulabel;
#else #else
(void)alabel; (void)alabel; /* unused parameter */
#endif #endif
return NULL; return NULL;
} }
@ -744,6 +744,75 @@ getdns_wire2msg_dict_scan(
else GLDNS_ ## Y ## _CLR(header); \ 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_return_t
_getdns_reply_dict2wire( _getdns_reply_dict2wire(
const getdns_dict *reply, gldns_buffer *buf, int reuse_header) const getdns_dict *reply, gldns_buffer *buf, int reuse_header)
@ -754,6 +823,7 @@ _getdns_reply_dict2wire(
getdns_list *section; getdns_list *section;
getdns_dict *rr_dict; getdns_dict *rr_dict;
getdns_bindata *qname; getdns_bindata *qname;
name_cache_t name_cache = {0};
int remove_dnssec; int remove_dnssec;
pkt_start = gldns_buffer_position(buf); pkt_start = gldns_buffer_position(buf);
@ -783,7 +853,7 @@ _getdns_reply_dict2wire(
if (!getdns_dict_get_bindata(reply, "/question/qname", &qname) && if (!getdns_dict_get_bindata(reply, "/question/qname", &qname) &&
!getdns_dict_get_int(reply, "/question/qtype", &qtype)) { !getdns_dict_get_int(reply, "/question/qtype", &qtype)) {
(void)getdns_dict_get_int(reply, "/question/qclass", &qclass); (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)qtype);
gldns_buffer_write_u16(buf, (uint16_t)qclass); gldns_buffer_write_u16(buf, (uint16_t)qclass);
gldns_buffer_write_u16_at(buf, pkt_start+GLDNS_QDCOUNT_OFF, 1); gldns_buffer_write_u16_at(buf, pkt_start+GLDNS_QDCOUNT_OFF, 1);
@ -806,7 +876,7 @@ _getdns_reply_dict2wire(
!getdns_dict_get_int(rr_dict, "type", &rr_type) && !getdns_dict_get_int(rr_dict, "type", &rr_type) &&
rr_type == GETDNS_RRTYPE_RRSIG) rr_type == GETDNS_RRTYPE_RRSIG)
continue; continue;
if (!_getdns_rr_dict2wire(rr_dict, buf)) if (!_getdns_rr_dict2wire_cache(rr_dict, buf, &name_cache))
n++; n++;
} }
gldns_buffer_write_u16_at(buf, pkt_start+GLDNS_ANCOUNT_OFF, n); gldns_buffer_write_u16_at(buf, pkt_start+GLDNS_ANCOUNT_OFF, n);
@ -848,8 +918,10 @@ getdns_return_t
_getdns_msg_dict2wire_buf(const getdns_dict *msg_dict, gldns_buffer *gbuf) _getdns_msg_dict2wire_buf(const getdns_dict *msg_dict, gldns_buffer *gbuf)
{ {
getdns_return_t r; getdns_return_t r;
getdns_list *replies; getdns_list *replies;
getdns_dict *reply; getdns_dict *reply;
getdns_list *wf_replies = NULL;
getdns_bindata *wf_reply;
size_t i; size_t i;
if ((r = getdns_dict_get_list(msg_dict, "replies_tree", &replies))) { if ((r = getdns_dict_get_list(msg_dict, "replies_tree", &replies))) {
@ -857,8 +929,23 @@ _getdns_msg_dict2wire_buf(const getdns_dict *msg_dict, gldns_buffer *gbuf)
return r; return r;
return _getdns_reply_dict2wire(msg_dict, gbuf, 0); 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++) { 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); r = _getdns_reply_dict2wire(reply, gbuf, 0);
} }
return r == GETDNS_RETURN_NO_SUCH_LIST_ITEM ? GETDNS_RETURN_GOOD : r; return r == GETDNS_RETURN_NO_SUCH_LIST_ITEM ? GETDNS_RETURN_GOOD : r;
@ -1814,8 +1901,8 @@ getdns_yaml2list(const char *str, getdns_list **list)
return GETDNS_RETURN_GENERIC_ERROR; return GETDNS_RETURN_GENERIC_ERROR;
} }
#else /* USE_YAML_CONFIG */ #else /* USE_YAML_CONFIG */
(void) str; (void) str; /* unused parameter */
(void) list; (void) list; /* unused parameter */
return GETDNS_RETURN_NOT_IMPLEMENTED; return GETDNS_RETURN_NOT_IMPLEMENTED;
#endif /* USE_YAML_CONFIG */ #endif /* USE_YAML_CONFIG */
} }
@ -1838,8 +1925,8 @@ getdns_yaml2bindata(const char *str, getdns_bindata **bindata)
return GETDNS_RETURN_GENERIC_ERROR; return GETDNS_RETURN_GENERIC_ERROR;
} }
#else /* USE_YAML_CONFIG */ #else /* USE_YAML_CONFIG */
(void) str; (void) str; /* unused parameter */
(void) bindata; (void) bindata; /* unused parameter */
return GETDNS_RETURN_NOT_IMPLEMENTED; return GETDNS_RETURN_NOT_IMPLEMENTED;
#endif /* USE_YAML_CONFIG */ #endif /* USE_YAML_CONFIG */
} }
@ -1862,8 +1949,8 @@ getdns_yaml2int(const char *str, uint32_t *value)
return GETDNS_RETURN_GENERIC_ERROR; return GETDNS_RETURN_GENERIC_ERROR;
} }
#else /* USE_YAML_CONFIG */ #else /* USE_YAML_CONFIG */
(void) str; (void) str; /* unused parameter */
(void) value; (void) value; /* unused parameter */
return GETDNS_RETURN_NOT_IMPLEMENTED; return GETDNS_RETURN_NOT_IMPLEMENTED;
#endif /* USE_YAML_CONFIG */ #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; struct getdns_bindata *bindata_item;
uint32_t int_item; uint32_t int_item;
const char *strval; const char *strval;
char abuf[80];
if (list == NULL) if (list == NULL)
return 0; 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) != if (getdns_list_get_bindata(list, i, &bindata_item) !=
GETDNS_RETURN_GOOD) GETDNS_RETURN_GOOD)
return -1; 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) buf, bindata_item, 0, json) < 0)
return -1; return -1;
break; break;
@ -1021,21 +1036,21 @@ static int
_getdns_print_rcode(gldns_buffer *buf, uint32_t rcode) _getdns_print_rcode(gldns_buffer *buf, uint32_t rcode)
{ {
static const char *rcodes[] = { static const char *rcodes[] = {
" GETDNS_RCODE_NOERROR" , " GETDNS_RCODE_FORMERR" , " GETDNS_RCODE_NOERROR" , " GETDNS_RCODE_FORMERR" ,
" GETDNS_RCODE_SERVFAIL", " GETDNS_RCODE_NXDOMAIN", " GETDNS_RCODE_SERVFAIL", " GETDNS_RCODE_NXDOMAIN" ,
" GETDNS_RCODE_NOTIMP" , " GETDNS_RCODE_REFUSED" , " GETDNS_RCODE_NOTIMP" , " GETDNS_RCODE_REFUSED" ,
" GETDNS_RCODE_YXDOMAIN", " GETDNS_RCODE_YXRRSET" , " GETDNS_RCODE_YXDOMAIN", " GETDNS_RCODE_YXRRSET" ,
" GETDNS_RCODE_NXRRSET" , " GETDNS_RCODE_NOTAUTH" , " GETDNS_RCODE_NXRRSET" , " GETDNS_RCODE_NOTAUTH" ,
" GETDNS_RCODE_NOTZONE" , " GETDNS_RCODE_NOTZONE" ,
" GETDNS_RCODE_BADSIG" , " GETDNS_RCODE_BADKEY" , " GETDNS_RCODE_BADSIG" , " GETDNS_RCODE_BADKEY" ,
" GETDNS_RCODE_BADTIME" , " GETDNS_RCODE_BADMODE" , " GETDNS_RCODE_BADTIME" , " GETDNS_RCODE_BADMODE" ,
" GETDNS_RCODE_BADNAME" , " GETDNS_RCODE_BADALG" , " GETDNS_RCODE_BADNAME" , " GETDNS_RCODE_BADALG" ,
" GETDNS_RCODE_BADTRUNC" " GETDNS_RCODE_BADTRUNC", " GETDNS_RCODE_BADCOOKIE"
}; };
if (rcode <= 10) if (rcode <= 10)
(void) gldns_buffer_printf(buf, "%s", rcodes[rcode]); (void) gldns_buffer_printf(buf, "%s", rcodes[rcode]);
else if (rcode >= 16 && rcode <= 22) else if (rcode >= 16 && rcode <= 23)
(void) gldns_buffer_printf(buf, "%s", rcodes[rcode-6]); (void) gldns_buffer_printf(buf, "%s", rcodes[rcode-5]);
else else
return 0; return 0;
return 1; return 1;
@ -1141,6 +1156,11 @@ getdns_pp_dict(gldns_buffer * buf, size_t indent,
if (!json && strcmp(item->node.key, "rcode") == 0 && if (!json && strcmp(item->node.key, "rcode") == 0 &&
_getdns_print_rcode(buf, item->i.data.n)) _getdns_print_rcode(buf, item->i.data.n))
break; 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( if (gldns_buffer_printf(
buf,(json < 2 ? " %d" : "%d"), item->i.data.n) < 0) buf,(json < 2 ? " %d" : "%d"), item->i.data.n) < 0)
return -1; return -1;
@ -1164,7 +1184,7 @@ getdns_pp_dict(gldns_buffer * buf, size_t indent,
, 40 , 40
)) < 0) )) < 0)
return -1; return -1;
} else if (!json && } else if (!json &&
(strcmp(item->node.key, "pin-sha256") == 0 || (strcmp(item->node.key, "pin-sha256") == 0 ||
strcmp(item->node.key, "value") == 0) && strcmp(item->node.key, "value") == 0) &&
@ -1199,8 +1219,9 @@ getdns_pp_dict(gldns_buffer * buf, size_t indent,
if (getdns_pp_list(buf, indent, item->i.data.list, if (getdns_pp_list(buf, indent, item->i.data.list,
(strcmp(item->node.key, "namespaces") == 0 || (strcmp(item->node.key, "namespaces") == 0 ||
strcmp(item->node.key, "dns_transport_list") == 0 strcmp(item->node.key, "dns_transport_list") == 0
|| strcmp(item->node.key, "bad_dns") == 0), || strcmp(item->node.key, "bad_dns") == 0 ||
json) < 0) strcmp(item->node.key, "dns_root_servers") == 0
), json) < 0)
return -1; return -1;
break; 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_roadblock_avoidance
: dnssec_ok_checking_disabled_avoid_roadblocks; : dnssec_ok_checking_disabled_avoid_roadblocks;
#else #else
(void)dnsreq; (void)dnsreq; /* unused parameter */
return dnssec_ok_checking_disabled; return dnssec_ok_checking_disabled;
#endif #endif
} }

View File

@ -97,7 +97,7 @@ static void
getdns_libev_read_cb(struct ev_loop *l, struct ev_io *io, int revents) getdns_libev_read_cb(struct ev_loop *l, struct ev_io *io, int revents)
{ {
getdns_eventloop_event *el_ev = (getdns_eventloop_event *)io->data; 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); assert(el_ev->read_cb);
el_ev->read_cb(el_ev->userarg); 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_libev_write_cb(struct ev_loop *l, struct ev_io *io, int revents)
{ {
getdns_eventloop_event *el_ev = (getdns_eventloop_event *)io->data; 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); assert(el_ev->write_cb);
el_ev->write_cb(el_ev->userarg); 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_libev_timeout_cb(struct ev_loop *l, struct ev_timer *timer, int revents)
{ {
getdns_eventloop_event *el_ev = (getdns_eventloop_event *)timer->data; 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); assert(el_ev->timeout_cb);
el_ev->timeout_cb(el_ev->userarg); 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) getdns_libevent_clear(getdns_eventloop *loop, getdns_eventloop_event *el_ev)
{ {
struct event *my_ev = (struct event *)el_ev->ev; struct event *my_ev = (struct event *)el_ev->ev;
(void)loop; (void)loop; /* unused parameter */
assert(my_ev); assert(my_ev);
@ -115,7 +115,7 @@ static void
getdns_libevent_callback(evutil_socket_t fd, short bits, void *arg) getdns_libevent_callback(evutil_socket_t fd, short bits, void *arg)
{ {
getdns_eventloop_event *el_ev = (getdns_eventloop_event *)arg; getdns_eventloop_event *el_ev = (getdns_eventloop_event *)arg;
(void)fd; (void)fd; /* unused parameter */
if (bits & EV_READ) { if (bits & EV_READ) {
assert(el_ev->read_cb); assert(el_ev->read_cb);

View File

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

View File

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

View File

@ -154,14 +154,14 @@ select_eventloop_clear(getdns_eventloop *loop, getdns_eventloop_event *event)
static void static void
select_eventloop_cleanup(getdns_eventloop *loop) select_eventloop_cleanup(getdns_eventloop *loop)
{ {
(void)loop; (void)loop; /* unused parameter */
} }
static void static void
select_read_cb(int fd, getdns_eventloop_event *event) select_read_cb(int fd, getdns_eventloop_event *event)
{ {
#if !defined(SCHED_DEBUG) || !SCHED_DEBUG #if !defined(SCHED_DEBUG) || !SCHED_DEBUG
(void)fd; (void)fd; /* unused parameter */
#endif #endif
DEBUG_SCHED( "%s(fd: %d, event: %p)\n", __FUNC__, fd, (void *)event); DEBUG_SCHED( "%s(fd: %d, event: %p)\n", __FUNC__, fd, (void *)event);
event->read_cb(event->userarg); event->read_cb(event->userarg);
@ -171,7 +171,7 @@ static void
select_write_cb(int fd, getdns_eventloop_event *event) select_write_cb(int fd, getdns_eventloop_event *event)
{ {
#if !defined(SCHED_DEBUG) || !SCHED_DEBUG #if !defined(SCHED_DEBUG) || !SCHED_DEBUG
(void)fd; (void)fd; /* unused parameter */
#endif #endif
DEBUG_SCHED( "%s(fd: %d, event: %p)\n", __FUNC__, fd, (void *)event); DEBUG_SCHED( "%s(fd: %d, event: %p)\n", __FUNC__, fd, (void *)event);
event->write_cb(event->userarg); event->write_cb(event->userarg);
@ -181,7 +181,7 @@ static void
select_timeout_cb(int fd, getdns_eventloop_event *event) select_timeout_cb(int fd, getdns_eventloop_event *event)
{ {
#if !defined(SCHED_DEBUG) || !SCHED_DEBUG #if !defined(SCHED_DEBUG) || !SCHED_DEBUG
(void)fd; (void)fd; /* unused parameter */
#endif #endif
DEBUG_SCHED( "%s(fd: %d, event: %p)\n", __FUNC__, fd, (void *)event); DEBUG_SCHED( "%s(fd: %d, event: %p)\n", __FUNC__, fd, (void *)event);
event->timeout_cb(event->userarg); event->timeout_cb(event->userarg);
@ -244,7 +244,7 @@ select_eventloop_run_once(getdns_eventloop *loop, int blocking)
} else { } else {
#endif #endif
if (select(max_fd + 1, &readfds, &writefds, NULL, if (select(max_fd + 1, &readfds, &writefds, NULL,
(timeout == TIMEOUT_FOREVER ? NULL : &tv)) < 0) { ((blocking && timeout == TIMEOUT_FOREVER) ? NULL : &tv)) < 0) {
if (_getdns_socketerror_wants_retry()) if (_getdns_socketerror_wants_retry())
return; return;
@ -309,7 +309,7 @@ _getdns_select_eventloop_init(struct mem_funcs *mf, _getdns_select_eventloop *lo
select_eventloop_run, select_eventloop_run,
select_eventloop_run_once select_eventloop_run_once
}; };
(void) mf; (void) mf; /* unused parameter */
(void) memset(loop, 0, sizeof(_getdns_select_eventloop)); (void) memset(loop, 0, sizeof(_getdns_select_eventloop));
loop->loop.vmt = &select_eventloop_vmt; 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, ub_resolve_event_callback(void* arg, int rcode, void *pkt, int pkt_len,
int sec, char* why_bogus, int was_ratelimited) int sec, char* why_bogus, int was_ratelimited)
{ {
(void) was_ratelimited; (void) was_ratelimited; /* unused parameter */
#else #else
static void static void
ub_resolve_event_callback(void* arg, int rcode, void *pkt, int pkt_len, 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_OPENPGPKEY 61
#define GETDNS_RRTYPE_CSYNC 62 #define GETDNS_RRTYPE_CSYNC 62
#define GETDNS_RRTYPE_ZONEMD 63 #define GETDNS_RRTYPE_ZONEMD 63
#define GETDNS_RRTYPE_SVCB 64
#define GETDNS_RRTYPE_HTTPS 65
#define GETDNS_RRTYPE_SPF 99 #define GETDNS_RRTYPE_SPF 99
#define GETDNS_RRTYPE_UINFO 100 #define GETDNS_RRTYPE_UINFO 100
#define GETDNS_RRTYPE_UID 101 #define GETDNS_RRTYPE_UID 101
@ -473,26 +475,26 @@ typedef enum getdns_callback_type_t {
* \defgroup rcodes Rcodes * \defgroup rcodes Rcodes
* @{ * @{
*/ */
#define GETDNS_RCODE_NOERROR 0 #define GETDNS_RCODE_NOERROR 0
#define GETDNS_RCODE_FORMERR 1 #define GETDNS_RCODE_FORMERR 1
#define GETDNS_RCODE_SERVFAIL 2 #define GETDNS_RCODE_SERVFAIL 2
#define GETDNS_RCODE_NXDOMAIN 3 #define GETDNS_RCODE_NXDOMAIN 3
#define GETDNS_RCODE_NOTIMP 4 #define GETDNS_RCODE_NOTIMP 4
#define GETDNS_RCODE_REFUSED 5 #define GETDNS_RCODE_REFUSED 5
#define GETDNS_RCODE_YXDOMAIN 6 #define GETDNS_RCODE_YXDOMAIN 6
#define GETDNS_RCODE_YXRRSET 7 #define GETDNS_RCODE_YXRRSET 7
#define GETDNS_RCODE_NXRRSET 8 #define GETDNS_RCODE_NXRRSET 8
#define GETDNS_RCODE_NOTAUTH 9 #define GETDNS_RCODE_NOTAUTH 9
#define GETDNS_RCODE_NOTZONE 10 #define GETDNS_RCODE_NOTZONE 10
#define GETDNS_RCODE_BADVERS 16 #define GETDNS_RCODE_BADVERS 16
#define GETDNS_RCODE_BADSIG 16 #define GETDNS_RCODE_BADSIG 16
#define GETDNS_RCODE_BADKEY 17 #define GETDNS_RCODE_BADKEY 17
#define GETDNS_RCODE_BADTIME 18 #define GETDNS_RCODE_BADTIME 18
#define GETDNS_RCODE_BADMODE 19 #define GETDNS_RCODE_BADMODE 19
#define GETDNS_RCODE_BADNAME 20 #define GETDNS_RCODE_BADNAME 20
#define GETDNS_RCODE_BADALG 21 #define GETDNS_RCODE_BADALG 21
#define GETDNS_RCODE_BADTRUNC 22 #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_return_t
getdns_context_set_idle_timeout(getdns_context *context, uint64_t timeout); 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 * 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 * are scheduled, they are kept on an internal queue, to be rescheduled when

View File

@ -540,6 +540,18 @@ getdns_context_set_tls_query_padding_blocksize(getdns_context *context, uint16_t
getdns_return_t getdns_return_t
getdns_context_unset_edns_maximum_udp_payload_size(getdns_context *context); 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 { typedef enum getdns_loglevel_type {
GETDNS_LOG_EMERG = 0, GETDNS_LOG_EMERG = 0,
@ -992,6 +1004,22 @@ getdns_return_t
getdns_context_get_idle_timeout( getdns_context_get_idle_timeout(
const getdns_context *context, uint64_t *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. * Get the setting that says whether or not DNS queries follow redirects.
* @see getdns_context_set_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. * the position is set to 0.
* *
* \param[in] buffer the buffer to flip * \param[in] buffer the buffer to flip
* \return void
*/ */
INLINE void gldns_buffer_flip(gldns_buffer *buffer) 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. * frees the buffer.
* \param[in] *buffer the buffer to be freed * \param[in] *buffer the buffer to be freed
* \return void
*/ */
void gldns_buffer_free(gldns_buffer *buffer); 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 * Makes the buffer fixed and returns a pointer to the data. The
* caller is responsible for free'ing the result. * caller is responsible for free'ing the result.
* \param[in] *buffer the buffer to be exported * \param[in] *buffer the buffer to be exported
* \return void
*/ */
void *gldns_buffer_export(gldns_buffer *buffer); void *gldns_buffer_export(gldns_buffer *buffer);

View File

@ -14,9 +14,6 @@
#include <limits.h> #include <limits.h>
#include <stdlib.h> #include <stdlib.h>
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
gldns_lookup_table gldns_directive_types[] = { gldns_lookup_table gldns_directive_types[] = {
{ GLDNS_DIR_TTL, "$TTL" }, { GLDNS_DIR_TTL, "$TTL" },
@ -123,7 +120,7 @@ gldns_fget_token_l(FILE *f, char *token, const char *delim, size_t limit, int *l
if (line_nr) { if (line_nr) {
*line_nr = *line_nr + 1; *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'; *t = '\0';
return -1; return -1;
} }
@ -144,7 +141,8 @@ gldns_fget_token_l(FILE *f, char *token, const char *delim, size_t limit, int *l
if (c != '\0' && c != '\n') { if (c != '\0' && c != '\n') {
i++; 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'; *t = '\0';
return -1; return -1;
} }
@ -329,8 +327,8 @@ gldns_bget_token_par(gldns_buffer *b, char *token, const char *delim,
/* in parentheses */ /* in parentheses */
/* do not write ' ' if we want to skip spaces */ /* do not write ' ' if we want to skip spaces */
if(!(skipw && (strchr(skipw, c)||strchr(skipw, ' ')))) { if(!(skipw && (strchr(skipw, c)||strchr(skipw, ' ')))) {
/* check for space for the space character */ /* check for space for the space character and a zero delimiter after that. */
if (limit > 0 && (i >= limit || (size_t)(t-token) >= limit)) { if (limit > 0 && (i+1 >= limit || (size_t)(t-token)+1 >= limit)) {
*t = '\0'; *t = '\0';
return -1; return -1;
} }
@ -357,7 +355,7 @@ gldns_bget_token_par(gldns_buffer *b, char *token, const char *delim,
} }
i++; 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'; *t = '\0';
return -1; 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. * the position to the first character that is not in *s.
* \param[in] *buffer buffer to use * \param[in] *buffer buffer to use
* \param[in] *s characters to skip * \param[in] *s characters to skip
* \return void
*/ */
void gldns_bskipcs(struct gldns_buffer *buffer, const char *s); 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. * the position to the first character that is not in *s.
* \param[in] *fp file to use * \param[in] *fp file to use
* \param[in] *s characters to skip * \param[in] *s characters to skip
* \return void
*/ */
void gldns_fskipcs(FILE *fp, const char *s); 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] *fp file to use
* \param[in] *s characters to skip * \param[in] *s characters to skip
* \param[in] line_nr pointer to an integer containing the current line number (for debugging purposes) * \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); void gldns_fskipcs_l(FILE *fp, const char *s, int *line_nr);

View File

@ -171,7 +171,7 @@ gldns_gmtime64_r(int64_t clock, struct tm *result)
static int64_t static int64_t
gldns_serial_arithmetics_time(int32_t time, time_t now) 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; return (int64_t) now + offset;
} }
@ -623,13 +623,18 @@ size_t gldns_b64_ntop_calculate_size(size_t srcsize)
* *
* This routine does not insert spaces or linebreaks after 76 characters. * This routine does not insert spaces or linebreaks after 76 characters.
*/ */
int gldns_b64_ntop(uint8_t const *src, size_t srclength, static int gldns_b64_ntop_base(uint8_t const *src, size_t srclength,
char *target, size_t targsize) char *target, size_t targsize, int base64url, int padding)
{ {
const char* b64 = char* b64;
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
const char pad64 = '='; const char pad64 = '=';
size_t i = 0, o = 0; size_t i = 0, o = 0;
if(base64url)
b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123"
"456789-_";
else
b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123"
"456789+/";
if(targsize < gldns_b64_ntop_calculate_size(srclength)) if(targsize < gldns_b64_ntop_calculate_size(srclength))
return -1; return -1;
/* whole chunks: xxxxxxyy yyyyzzzz zzwwwwww */ /* whole chunks: xxxxxxyy yyyyzzzz zzwwwwww */
@ -649,18 +654,26 @@ int gldns_b64_ntop(uint8_t const *src, size_t srclength,
target[o] = b64[src[i] >> 2]; target[o] = b64[src[i] >> 2];
target[o+1] = b64[ ((src[i]&0x03)<<4) | (src[i+1]>>4) ]; target[o+1] = b64[ ((src[i]&0x03)<<4) | (src[i+1]>>4) ];
target[o+2] = b64[ ((src[i+1]&0x0f)<<2) ]; target[o+2] = b64[ ((src[i+1]&0x0f)<<2) ];
target[o+3] = pad64; if(padding) {
/* i += 2; */ target[o+3] = pad64;
o += 4; /* i += 2; */
o += 4;
} else {
o += 3;
}
break; break;
case 1: case 1:
/* one at end, converted into A B = = */ /* one at end, converted into A B = = */
target[o] = b64[src[i] >> 2]; target[o] = b64[src[i] >> 2];
target[o+1] = b64[ ((src[i]&0x03)<<4) ]; target[o+1] = b64[ ((src[i]&0x03)<<4) ];
target[o+2] = pad64; if(padding) {
target[o+3] = pad64; target[o+2] = pad64;
/* i += 1; */ target[o+3] = pad64;
o += 4; /* i += 1; */
o += 4;
} else {
o += 2;
}
break; break;
case 0: case 0:
default: default:
@ -673,19 +686,36 @@ int gldns_b64_ntop(uint8_t const *src, size_t srclength,
return (int)o; 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) size_t gldns_b64_pton_calculate_size(size_t srcsize)
{ {
return (((((srcsize + 3) / 4) * 3)) + 1); 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 uint8_t pad64 = 64; /* is 64th in the b64 array */
const char* s = src; const char* s = src;
uint8_t in[4]; uint8_t in[4];
size_t o = 0, incount = 0; 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 */ /* skip any character that is not base64 */
/* conceptually we do: /* conceptually we do:
const char* b64 = pad'=' is appended to array const char* b64 = pad'=' is appended to array
@ -694,30 +724,43 @@ int gldns_b64_pton(char const *src, uint8_t *target, size_t targsize)
and use d-b64; and use d-b64;
*/ */
char d = *s++; char d = *s++;
srcsize--;
if(d <= 'Z' && d >= 'A') if(d <= 'Z' && d >= 'A')
d -= 'A'; d -= 'A';
else if(d <= 'z' && d >= 'a') else if(d <= 'z' && d >= 'a')
d = d - 'a' + 26; d = d - 'a' + 26;
else if(d <= '9' && d >= '0') else if(d <= '9' && d >= '0')
d = d - '0' + 52; d = d - '0' + 52;
else if(d == '+') else if(!base64url && d == '+')
d = 62; d = 62;
else if(d == '/') else if(base64url && d == '-')
d = 62;
else if(!base64url && d == '/')
d = 63; d = 63;
else if(d == '=') else if(base64url && d == '_')
d = 63;
else if(d == '=') {
if(!check_padding)
continue;
d = 64; d = 64;
else continue; } else continue;
in[incount++] = (uint8_t)d; in[incount++] = (uint8_t)d;
if(incount != 4) /* 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; continue;
assert(!check_padding || incount==4);
/* process whole block of 4 characters into 3 output bytes */ /* 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) if(o+1 > targsize)
return -1; return -1;
target[o] = (in[0]<<2) | ((in[1]&0x30)>>4); target[o] = (in[0]<<2) | ((in[1]&0x30)>>4);
o += 1; o += 1;
break; /* we are done */ 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) if(o+2 > targsize)
return -1; return -1;
target[o] = (in[0]<<2) | ((in[1]&0x30)>>4); target[o] = (in[0]<<2) | ((in[1]&0x30)>>4);
@ -725,7 +768,7 @@ int gldns_b64_pton(char const *src, uint8_t *target, size_t targsize)
o += 2; o += 2;
break; /* we are done */ break; /* we are done */
} else { } else {
if(o+3 > targsize) if(incount != 4 || o+3 > targsize)
return -1; return -1;
/* write xxxxxxyy yyyyzzzz zzwwwwww */ /* write xxxxxxyy yyyyzzzz zzwwwwww */
target[o] = (in[0]<<2) | ((in[1]&0x30)>>4); target[o] = (in[0]<<2) | ((in[1]&0x30)>>4);
@ -737,3 +780,17 @@ int gldns_b64_pton(char const *src, uint8_t *target, size_t targsize)
} }
return (int)o; 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);
}

View File

@ -92,13 +92,16 @@ size_t gldns_b64_ntop_calculate_size(size_t srcsize);
int gldns_b64_ntop(uint8_t const *src, size_t srclength, int gldns_b64_ntop(uint8_t const *src, size_t srclength,
char *target, size_t targsize); 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 * calculates the size needed to store the result of gldns_b64_pton
*/ */
size_t gldns_b64_pton_calculate_size(size_t srcsize); 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_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);
/** /**
* calculates the size needed to store the result of b32_ntop * calculates the size needed to store the result of b32_ntop

View File

@ -195,7 +195,9 @@ enum gldns_enum_rr_type
GLDNS_RR_TYPE_CDNSKEY = 60, /** RFC 7344 */ GLDNS_RR_TYPE_CDNSKEY = 60, /** RFC 7344 */
GLDNS_RR_TYPE_OPENPGPKEY = 61, /* RFC 7929 */ GLDNS_RR_TYPE_OPENPGPKEY = 61, /* RFC 7929 */
GLDNS_RR_TYPE_CSYNC = 62, /* RFC 7477 */ 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,
GLDNS_RR_TYPE_HTTPS = 65,
GLDNS_RR_TYPE_SPF = 99, /* RFC 4408 */ GLDNS_RR_TYPE_SPF = 99, /* RFC 4408 */
@ -432,7 +434,8 @@ enum gldns_enum_edns_option
GLDNS_EDNS_N3U = 7, /* RFC6975 */ GLDNS_EDNS_N3U = 7, /* RFC6975 */
GLDNS_EDNS_CLIENT_SUBNET = 8, /* RFC7871 */ GLDNS_EDNS_CLIENT_SUBNET = 8, /* RFC7871 */
GLDNS_EDNS_KEEPALIVE = 11, /* draft-ietf-dnsop-edns-tcp-keepalive*/ GLDNS_EDNS_KEEPALIVE = 11, /* draft-ietf-dnsop-edns-tcp-keepalive*/
GLDNS_EDNS_PADDING = 12 /* RFC7830 */ GLDNS_EDNS_PADDING = 12, /* RFC7830 */
GLDNS_EDNS_CLIENT_TAG = 16 /* draft-bellis-dnsop-edns-tags-01 */
}; };
typedef enum gldns_enum_edns_option gldns_edns_option; typedef enum gldns_enum_edns_option gldns_edns_option;

View File

@ -81,7 +81,7 @@ static int gldns_str2wire_dname_buf_rel(const char* str, uint8_t* buf,
for (s = str; *s; s++, q++) { for (s = str; *s; s++, q++) {
if (q >= buf + *olen) if (q >= buf + *olen)
return RET_ERR(GLDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL, q-buf); 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); return RET_ERR(GLDNS_WIREPARSE_ERR_DOMAINNAME_OVERFLOW, q-buf);
switch (*s) { switch (*s) {
case '.': case '.':
@ -118,7 +118,7 @@ static int gldns_str2wire_dname_buf_rel(const char* str, uint8_t* buf,
if(rel) *rel = 1; if(rel) *rel = 1;
if (q >= buf + *olen) if (q >= buf + *olen)
return RET_ERR(GLDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL, q-buf); 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); return RET_ERR(GLDNS_WIREPARSE_ERR_DOMAINNAME_OVERFLOW, q-buf);
} }
if (label_len > GLDNS_MAX_LABELLEN) { if (label_len > GLDNS_MAX_LABELLEN) {
@ -930,6 +930,10 @@ 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); memmove(parse_state->prev_rr, rr, *dname_len);
parse_state->prev_rr_len = (*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 r;
} }
return GLDNS_WIREPARSE_ERR_OK; return GLDNS_WIREPARSE_ERR_OK;
@ -1494,13 +1498,17 @@ static int
loc_parse_cm(char* my_str, char** endstr, uint8_t* m, uint8_t* e) loc_parse_cm(char* my_str, char** endstr, uint8_t* m, uint8_t* e)
{ {
uint32_t meters = 0, cm = 0, val; uint32_t meters = 0, cm = 0, val;
char* cm_endstr;
while (isblank((unsigned char)*my_str)) { while (isblank((unsigned char)*my_str)) {
my_str++; my_str++;
} }
meters = (uint32_t)strtol(my_str, &my_str, 10); meters = (uint32_t)strtol(my_str, &my_str, 10);
if (*my_str == '.') { if (*my_str == '.') {
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) { if (meters >= 1) {
*e = 2; *e = 2;

View File

@ -14,6 +14,7 @@
* Contains functions to translate the wireformat to text * Contains functions to translate the wireformat to text
* representation, as well as functions to print them. * representation, as well as functions to print them.
*/ */
#include <stdlib.h>
#include "config.h" #include "config.h"
#include "gldns/wire2str.h" #include "gldns/wire2str.h"
#include "gldns/str2wire.h" #include "gldns/str2wire.h"
@ -821,9 +822,12 @@ int gldns_wire2str_dname_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen,
if(!pkt || target >= pktlen) if(!pkt || target >= pktlen)
return w + gldns_str_print(s, slen, return w + gldns_str_print(s, slen,
"ErrorComprPtrOutOfBounds"); "ErrorComprPtrOutOfBounds");
if(counter++ > maxcompr) if(counter++ > maxcompr) {
if(comprloop && *comprloop < 10)
(*comprloop)++;
return w + gldns_str_print(s, slen, return w + gldns_str_print(s, slen,
"ErrorComprPtrLooped"); "ErrorComprPtrLooped");
}
in_buf = 0; in_buf = 0;
pos = pkt+target; pos = pkt+target;
continue; continue;

View File

@ -5,7 +5,7 @@
*/ */
/* /*
* Copyright (c) 2018-2019, NLnet Labs * Copyright (c) 2018-2020, NLnet Labs
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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; char* pri = NULL;
int res; 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) if (conn->cipher_suites)
pri = getdns_priappend(conn->mfs, pri, 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) else if (conn->ctx->curve_list)
pri = getdns_priappend(conn->mfs, pri, conn->ctx->curve_list); pri = getdns_priappend(conn->mfs, pri, conn->ctx->curve_list);
else else
#if GNUTLS_VERSION_NUMBER >= 0x030605
pri = getdns_priappend(conn->mfs, pri, "+GROUP-EC-ALL");
#else
pri = getdns_priappend(conn->mfs, pri, "+CURVE-ALL"); pri = getdns_priappend(conn->mfs, pri, "+CURVE-ALL");
#endif
gnutls_protocol_t min = conn->min_tls; gnutls_protocol_t min = conn->min_tls;
gnutls_protocol_t max = conn->max_tls; gnutls_protocol_t max = conn->max_tls;
@ -134,18 +149,16 @@ static int set_connection_ciphers(_getdns_tls_connection* conn)
for (gnutls_protocol_t i = min; i <= max; ++i) for (gnutls_protocol_t i = min; i <= max; ++i)
pri = getdns_priappend(conn->mfs, pri, _getdns_tls_priorities[i]); pri = getdns_priappend(conn->mfs, pri, _getdns_tls_priorities[i]);
} }
if (pri) { if (pri) {
res = gnutls_priority_set_direct(conn->tls, pri, NULL); res = gnutls_priority_set_direct(conn->tls, pri, NULL);
if (res != GNUTLS_E_SUCCESS) { _getdns_log(conn->log
_getdns_log(conn->log , GETDNS_LOG_UPSTREAM_STATS
, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_ERR , (res == GNUTLS_E_SUCCESS ? GETDNS_LOG_DEBUG : GETDNS_LOG_ERR)
, "%s: %s %s (%s)\n" , "%s: %s %s (%s)\n"
, STUB_DEBUG_SETUP_TLS , STUB_DEBUG_SETUP_TLS
, "Error configuring TLS connection with " , "Configuring TLS connection with "
, pri , pri
, gnutls_strerror(res)); , gnutls_strerror(res));
}
} }
else else
res = gnutls_set_default_priority(conn->tls); res = gnutls_set_default_priority(conn->tls);
@ -165,7 +178,16 @@ static getdns_return_t error_may_want_read_write(_getdns_tls_connection* conn, i
return GETDNS_RETURN_TLS_WANT_READ; return GETDNS_RETURN_TLS_WANT_READ;
else else
return GETDNS_RETURN_TLS_WANT_WRITE; 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: default:
return GETDNS_RETURN_GENERIC_ERROR; 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 _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) 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; 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* _getdns_tls_connection_new(struct mem_funcs* mfs, _getdns_tls_context* ctx, int fd, const getdns_log_config* log)
{ {
_getdns_tls_connection* res; _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); 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; goto failed;
if (set_connection_ciphers(res) != GNUTLS_E_SUCCESS) { if (set_connection_ciphers(res) != GNUTLS_E_SUCCESS) {
@ -709,8 +738,11 @@ failsafe:
GETDNS_FREE(*conn->mfs, new_cert_list); 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; return GETDNS_RETURN_GENERIC_ERROR;
}
if (verify != 0) { if (verify != 0) {
if (verify & DANE_VERIFY_CERT_DIFFERS) { if (verify & DANE_VERIFY_CERT_DIFFERS) {
@ -764,6 +796,8 @@ getdns_return_t _getdns_tls_session_free(struct mem_funcs* mfs, _getdns_tls_sess
{ {
if (!s) if (!s)
return GETDNS_RETURN_INVALID_PARAMETER; return GETDNS_RETURN_INVALID_PARAMETER;
if (s->tls.data)
gnutls_free(s->tls.data);
GETDNS_FREE(*mfs, s); GETDNS_FREE(*mfs, s);
return GETDNS_RETURN_GOOD; return GETDNS_RETURN_GOOD;
} }

View File

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

View File

@ -21,10 +21,10 @@
#include <openssl/err.h> #include <openssl/err.h>
#include <openssl/md5.h> #include <openssl/md5.h>
#ifdef HAVE_OPENSSL_CONF_H #ifdef HAVE_OPENSSL_CONF_H
# include <openssl/conf.h> #include <openssl/conf.h>
#endif #endif
#ifdef HAVE_OPENSSL_ENGINE_H #ifdef HAVE_OPENSSL_ENGINE_H
# include <openssl/engine.h> #include <openssl/engine.h>
#endif #endif
#ifdef HAVE_OPENSSL_BN_H #ifdef HAVE_OPENSSL_BN_H
#include <openssl/bn.h> #include <openssl/bn.h>
@ -35,6 +35,9 @@
#ifdef HAVE_OPENSSL_DSA_H #ifdef HAVE_OPENSSL_DSA_H
#include <openssl/dsa.h> #include <openssl/dsa.h>
#endif #endif
#ifdef HAVE_OPENSSL_RSA_H
#include <openssl/rsa.h>
#endif
#endif /* HAVE_SSL */ #endif /* HAVE_SSL */
#ifdef HAVE_SSL #ifdef HAVE_SSL
@ -74,7 +77,6 @@ gldns_key_EVP_load_gost_id(void)
if(!e) { if(!e) {
/* load it ourself, in case statically linked */ /* load it ourself, in case statically linked */
ENGINE_load_builtin_engines(); ENGINE_load_builtin_engines();
ENGINE_load_dynamic();
e = ENGINE_by_id("gost"); e = ENGINE_by_id("gost");
} }
if(!e) { if(!e) {

View File

@ -48,19 +48,21 @@
#include "context.h" #include "context.h"
#include "const-info.h" #include "const-info.h"
#ifdef USE_DANESSL #if defined(USE_DANESSL) || defined(LIBRESSL_VERSION_NUMBER)
# include "ssl_dane/danessl.h" # include "ssl_dane/danessl.h"
#endif #endif
#include "tls.h" #include "tls.h"
/* Double check configure has worked as expected. */ /* Double check configure has worked as expected. */
#ifndef LIBRESSL_VERSION_NUMBER
#if defined(USE_DANESSL) && \ #if defined(USE_DANESSL) && \
(defined(HAVE_SSL_DANE_ENABLE) || \ (defined(HAVE_SSL_DANE_ENABLE) || \
defined(HAVE_OPENSSL_INIT_CRYPTO) || \ defined(HAVE_OPENSSL_INIT_CRYPTO) || \
defined(HAVE_SSL_CTX_DANE_ENABLE)) defined(HAVE_SSL_CTX_DANE_ENABLE))
#error Configure error USE_DANESSL defined with OpenSSL 1.1 functions! #error Configure error USE_DANESSL defined with OpenSSL 1.1 functions!
#endif #endif
#endif
/* Cipher suites recommended in RFC7525. */ /* Cipher suites recommended in RFC7525. */
static char const * const _getdns_tls_context_default_cipher_list = 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>"); 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)); 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 */ # else /* defined(STUB_DEBUG) && STUB_DEBUG */
(void)ok; (void)ok; /* unused parameter */
(void)ctx; (void)ctx; /* unused parameter */
# endif /* #else defined(STUB_DEBUG) && STUB_DEBUG */ # endif /* #else defined(STUB_DEBUG) && STUB_DEBUG */
return 1; return 1;
} }
@ -425,7 +427,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 * We've used TLSv1_2_client_method() creating the context, so
* error if they asked for anything other than TLS 1.2 or better. * 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) if ((!min || min == GETDNS_TLS1_2) && !max)
return GETDNS_RETURN_GOOD; return GETDNS_RETURN_GOOD;
@ -693,7 +695,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 * We've used TLSv1_2_client_method() creating the context, so
* error if they asked for anything other than TLS 1.2 or better. * 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) if ((!min || min == GETDNS_TLS1_2) && !max)
return GETDNS_RETURN_GOOD; return GETDNS_RETURN_GOOD;
@ -912,7 +914,7 @@ getdns_return_t _getdns_tls_connection_set_host_pinset(_getdns_tls_connection* c
#if defined(HAVE_SSL_DANE_ENABLE) #if defined(HAVE_SSL_DANE_ENABLE)
int osr = SSL_dane_enable(conn->ssl, *auth_name ? auth_name : NULL); 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" DEBUG_STUB("%s %-35s: DEBUG: SSL_dane_enable(\"%s\") -> %d\n"
, STUB_DEBUG_SETUP_TLS, __FUNC__, auth_name, osr); , STUB_DEBUG_SETUP_TLS, __FUNC__, auth_name, osr);
SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, _getdns_tls_verify_always_ok); SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, _getdns_tls_verify_always_ok);
@ -938,7 +940,7 @@ getdns_return_t _getdns_tls_connection_set_host_pinset(_getdns_tls_connection* c
int osr = DANESSL_init(conn->ssl, int osr = DANESSL_init(conn->ssl,
*auth_name ? auth_name : NULL, *auth_name ? auth_name : NULL,
*auth_name ? auth_names : NULL); *auth_name ? auth_names : NULL);
(void) osr; (void) osr; /* unused parameter */
DEBUG_STUB("%s %-35s: DEBUG: DANESSL_init(\"%s\") -> %d\n" DEBUG_STUB("%s %-35s: DEBUG: DANESSL_init(\"%s\") -> %d\n"
, STUB_DEBUG_SETUP_TLS, __FUNC__, auth_name, osr); , STUB_DEBUG_SETUP_TLS, __FUNC__, auth_name, osr);
SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, _getdns_tls_verify_always_ok); SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, _getdns_tls_verify_always_ok);

View File

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

View File

@ -60,6 +60,7 @@ typedef u_short sa_family_t;
#define _getdns_socketerror() (WSAGetLastError()) #define _getdns_socketerror() (WSAGetLastError())
const char *_getdns_strerror(DWORD errnum); const char *_getdns_strerror(DWORD errnum);
const char *_getdns_filestrerror(int errnum);
#else /* USE_WINSOCK */ #else /* USE_WINSOCK */
#ifndef HAVE_SYS_POLL_H #ifndef HAVE_SYS_POLL_H
@ -132,10 +133,13 @@ const char *_getdns_strerror(DWORD errnum);
#define _getdns_socketerror() (errno) #define _getdns_socketerror() (errno)
const char *_getdns_strerror(int errnum); const char *_getdns_strerror(int errnum);
#define _getdns_filestrerror(errnum) (_getdns_strerror(errnum))
#endif #endif
void _getdns_perror(const char *str); 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_errnostr() (_getdns_strerror(_getdns_socketerror()))
#define _getdns_error_wants_retry(X) ( (X) != 0 \ #define _getdns_error_wants_retry(X) ( (X) != 0 \
&& ( (X) == _getdns_EINTR \ && ( (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->dnssec_status = GETDNS_DNSSEC_INDETERMINATE;
net_req->tsig_status = GETDNS_DNSSEC_INDETERMINATE; net_req->tsig_status = GETDNS_DNSSEC_INDETERMINATE;
net_req->response_len = 0; net_req->response_len = 0;
net_req->response_opt = NULL;
/* Some fields to record info for return_call_reporting */ /* Some fields to record info for return_call_reporting */
net_req->debug_start_time = 0; net_req->debug_start_time = 0;
net_req->debug_end_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; net_req->transport_current = 0;
memset(&net_req->event, 0, sizeof(net_req->event)); memset(&net_req->event, 0, sizeof(net_req->event));
net_req->keepalive_sent = 0; 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; net_req->write_queue_tail = NULL;
/* Some fields to record info for return_call_reporting */ /* Some fields to record info for return_call_reporting */
net_req->debug_tls_auth_status = GETDNS_AUTH_NONE; 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; req->response = req->opt + 11 + req->base_query_option_sz;
pktlen = req->response - req->query; pktlen = req->response - req->query;
gldns_write_uint16(req->query - 2, (uint16_t) pktlen); 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; uint8_t *base_opt_backup;
size_t base_opt_rr_sz; 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) { if (!netreq->query) {
(void) netreq_reset(netreq); (void) netreq_reset(netreq);
return; return;
@ -476,7 +484,7 @@ void
_getdns_network_validate_tsig(getdns_network_req *req) _getdns_network_validate_tsig(getdns_network_req *req)
{ {
#if defined(HAVE_NSS) || defined(HAVE_NETTLE) #if defined(HAVE_NSS) || defined(HAVE_NETTLE)
(void)req; (void)req; /* unused parameter */
#else #else
_getdns_rr_iter rr_spc, *rr; _getdns_rr_iter rr_spc, *rr;
_getdns_rdf_iter rdf_spc, *rdf; _getdns_rdf_iter rdf_spc, *rdf;

View File

@ -47,7 +47,7 @@
static const uint8_t * static const uint8_t *
apl_n_rdf_end(const uint8_t *pkt, const uint8_t *pkt_end, const uint8_t *rdf) 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; return rdf < pkt_end ? rdf + 1 : NULL;
} }
static getdns_return_t 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 *pkt, const uint8_t *pkt_end, const uint8_t *rdf)
{ {
const uint8_t *end = rdf + (rdf[-1] & 0x7F); const uint8_t *end = rdf + (rdf[-1] & 0x7F);
(void)(pkt); (void)pkt; /* unused parameter */
return end <= pkt_end ? end : NULL; return end <= pkt_end ? end : NULL;
} }
static getdns_return_t static getdns_return_t
@ -217,6 +217,7 @@ ipseckey_gateway_2wire(
{ {
assert(rdf - 2 >= rdata && rdf[-2] > 0); assert(rdf - 2 >= rdata && rdf[-2] > 0);
(void)rdata; /* unused parameter */
switch (rdf[-2]) { switch (rdf[-2]) {
case 1: if (!value || value->size != 4) case 1: if (!value || value->size != 4)
return GETDNS_RETURN_INVALID_PARAMETER; return GETDNS_RETURN_INVALID_PARAMETER;
@ -280,7 +281,7 @@ static const uint8_t *
hip_pk_algorithm_rdf_end( hip_pk_algorithm_rdf_end(
const uint8_t *pkt, const uint8_t *pkt_end, const uint8_t *rdf) 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 return rdf + 4 > pkt_end ? NULL
: rdf + 4 + *rdf + gldns_read_uint16(rdf + 2) > pkt_end ? NULL : rdf + 4 + *rdf + gldns_read_uint16(rdf + 2) > pkt_end ? NULL
: rdf + 1; : rdf + 1;
@ -326,7 +327,7 @@ static _getdns_rdf_special hip_pk_algorithm = {
static const uint8_t * static const uint8_t *
hip_hit_rdf_end(const uint8_t *pkt, const uint8_t *pkt_end, const uint8_t *rdf) 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 return rdf + 3 > pkt_end ? NULL
: rdf + 3 + rdf[-1] + gldns_read_uint16(rdf + 1) > pkt_end ? NULL : rdf + 3 + rdf[-1] + gldns_read_uint16(rdf + 1) > pkt_end ? NULL
: rdf + 1; : rdf + 1;
@ -380,7 +381,7 @@ static const uint8_t *
hip_public_key_rdf_end( hip_public_key_rdf_end(
const uint8_t *pkt, const uint8_t *pkt_end, const uint8_t *rdf) 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 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) > pkt_end ? NULL
: rdf + 2 + rdf[-2] + gldns_read_uint16(rdf); : rdf + 2 + rdf[-2] + gldns_read_uint16(rdf);
@ -434,7 +435,7 @@ static _getdns_rdf_special hip_public_key = {
static const uint8_t * static const uint8_t *
amtrelay_D_rdf_end(const uint8_t *pkt, const uint8_t *pkt_end, const uint8_t *rdf) 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; return rdf < pkt_end ? rdf + 1 : NULL;
} }
static getdns_return_t static getdns_return_t
@ -471,7 +472,8 @@ static const uint8_t *
amtrelay_rtype_rdf_end( amtrelay_rtype_rdf_end(
const uint8_t *pkt, const uint8_t *pkt_end, const uint8_t *rdf) 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; return rdf;
} }
static getdns_return_t static getdns_return_t
@ -581,6 +583,7 @@ amtrelay_relay_2wire(
{ {
assert(rdf - 1 >= rdata && (rdf[-1] & 0x7F) > 0); assert(rdf - 1 >= rdata && (rdf[-1] & 0x7F) > 0);
(void)rdata; /* unused parameter */
switch (rdf[-1] & 0x7F) { switch (rdf[-1] & 0x7F) {
case 1: if (!value || value->size != 4) case 1: if (!value || value->size != 4)
return GETDNS_RETURN_INVALID_PARAMETER; 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; 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 < 0xc000) {
/* 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_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_return_t r = GETDNS_RETURN_GOOD;
getdns_bindata root = { 1, (void *)"" }; getdns_bindata root = { 1, (void *)"" };
@ -1325,7 +1359,7 @@ _getdns_rr_dict2wire(const getdns_dict *rr_dict, gldns_buffer *buf)
} else } else
return r; 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); gldns_buffer_write_u16(buf, (uint16_t)rr_type);
(void) getdns_dict_get_int(rr_dict, "class", &rr_class); (void) getdns_dict_get_int(rr_dict, "class", &rr_class);
@ -1378,42 +1412,51 @@ _getdns_rr_dict2wire(const getdns_dict *rr_dict, gldns_buffer *buf)
gldns_buffer_skip(buf, 2); gldns_buffer_skip(buf, 2);
rdata_start = gldns_buffer_current(buf); rdata_start = gldns_buffer_current(buf);
for ( rd_def = rr_def->rdata /* Special case CNAME payload */
, n_rdata_fields = rr_def->n_rdata_fields if((rr_type == GETDNS_RRTYPE_CNAME) && (n_rdata_fields == 1) &&
; n_rdata_fields ; n_rdata_fields-- , rd_def++ ) { (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)))) {
if (rd_def->type == GETDNS_RDF_REPEAT) _getdns_rr_buffer_write_cached_name(buf, rdata_raw, name_cache);
break; } else {
if ((r = write_rdata_field(buf, for ( rd_def = rr_def->rdata
rdata_start, rd_def, rdata))) , n_rdata_fields = rr_def->n_rdata_fields
break; ; n_rdata_fields ; n_rdata_fields-- , rd_def++ ) {
}
if (n_rdata_fields == 0 || r) {
/* pass */;
} else if ((r = getdns_dict_get_list( if (rd_def->type == GETDNS_RDF_REPEAT)
rdata, rd_def->name, &list))) { break;
/* pass */;
} else for ( i = 0
; r == GETDNS_RETURN_GOOD
; i++) {
if ((r = getdns_list_get_dict(list, i, &rdata))) {
if (r == GETDNS_RETURN_NO_SUCH_LIST_ITEM)
r = GETDNS_RETURN_GOOD;
break;
}
for ( rep_rd_def = rd_def + 1
, rep_n_rdata_fields = n_rdata_fields - 1
; rep_n_rdata_fields
; rep_n_rdata_fields--, rep_rd_def++ ) {
if ((r = write_rdata_field(buf, if ((r = write_rdata_field(buf,
rdata_start, rep_rd_def, rdata))) rdata_start, rd_def, rdata)))
break; break;
} }
if (n_rdata_fields == 0 || r) {
/* pass */;
} else if ((r = getdns_dict_get_list(
rdata, rd_def->name, &list))) {
/* pass */;
} else for ( i = 0
; r == GETDNS_RETURN_GOOD
; i++) {
if ((r = getdns_list_get_dict(list, i, &rdata))) {
if (r == GETDNS_RETURN_NO_SUCH_LIST_ITEM)
r = GETDNS_RETURN_GOOD;
break;
}
for ( rep_rd_def = rd_def + 1
, rep_n_rdata_fields = n_rdata_fields - 1
; rep_n_rdata_fields
; rep_n_rdata_fields--, rep_rd_def++ ) {
if ((r = write_rdata_field(buf,
rdata_start, rep_rd_def, rdata)))
break;
}
}
} }
gldns_buffer_write_u16_at(buf, rdata_size_mark, gldns_buffer_write_u16_at(buf, rdata_size_mark,
(uint16_t)(gldns_buffer_position(buf)-rdata_size_mark-2)); (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); const _getdns_rr_def *_getdns_rr_def_lookup(uint16_t rr_type);
getdns_return_t _getdns_rr_dict2wire( #define NAME_CACHE_ENTRIES 4
const getdns_dict *rr_dict, gldns_buffer *buf);
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); const char *_getdns_rr_type_name(int rr_type);

@ -1 +1 @@
Subproject commit 187838104f3cfc9634148ae41a717e00c0d68e67 Subproject commit afd5b88687f05554513d9caf000f08904e32e6a4

View File

@ -33,6 +33,10 @@
#include "config.h" #include "config.h"
#ifndef USE_WINSOCK
#include <netdb.h>
#endif
/* Intercept and do not sent out COM DS queries with TLS /* Intercept and do not sent out COM DS queries with TLS
* For debugging purposes only. Never commit with this turned on. * For debugging purposes only. Never commit with this turned on.
*/ */
@ -53,6 +57,7 @@
#include "general.h" #include "general.h"
#include "pubkey-pinning.h" #include "pubkey-pinning.h"
/* WSA TODO: /* WSA TODO:
* STUB_TCP_RETRY added to deal with edge triggered event loops (versus * STUB_TCP_RETRY added to deal with edge triggered event loops (versus
* level triggered). See also lines containing WSA TODO below... * level triggered). See also lines containing WSA TODO below...
@ -73,10 +78,6 @@
/* Arbritray number of message for EDNS keepalive resend*/ /* Arbritray number of message for EDNS keepalive resend*/
#define EDNS_KEEPALIVE_RESEND 5 #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_read_cb(void *userarg);
static void upstream_write_cb(void *userarg); static void upstream_write_cb(void *userarg);
static void upstream_idle_timeout_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 */ /* 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 static getdns_return_t
attach_edns_client_subnet_private(getdns_network_req *req) attach_edns_client_subnet_private(getdns_network_req *req)
{ {
@ -169,154 +129,269 @@ static getdns_return_t
attach_edns_cookie(getdns_network_req *req) attach_edns_cookie(getdns_network_req *req)
{ {
getdns_upstream *upstream = req->upstream; 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) { if (upstream->server_cookie_len) {
calc_new_cookie(upstream, upstream->client_cookie); if (!req->badcookie_retry && bind(req->fd, (struct sockaddr *)
upstream->secret = secret; &upstream->src_addr, upstream->src_addr_len)) {
upstream->has_client_cookie = 1;
sz = 8; _getdns_upstream_log(upstream,
val = upstream->client_cookie; GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_INFO,
} else if (upstream->secret != secret) { "%-40s : Upstream : %s with source address: %s. "
memcpy( upstream->prev_client_cookie "Renewing Client Cookie.\n", upstream->addr_str,
, upstream->client_cookie, 8); strerror(errno), upstream->src_addr_str);
upstream->has_prev_client_cookie = 1;
calc_new_cookie(upstream, upstream->client_cookie);
upstream->secret = secret;
sz = 8; upstream->server_cookie_len = 0;
val = upstream->client_cookie; upstream->src_addr_checked = 0;
} else if (!upstream->has_server_cookie) { } else
sz = 8; return _getdns_network_req_add_upstream_option(
val = upstream->client_cookie; req, EDNS_COOKIE_OPCODE,
} else { upstream->server_cookie_len,
sz = 8 + upstream->server_cookie_len; upstream->server_cookie);
memcpy(buf, upstream->client_cookie, 8);
memcpy(buf+8, upstream->server_cookie, upstream->server_cookie_len);
val = buf;
} }
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 /* 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 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) const uint8_t **position, uint16_t *option_len)
{ {
_getdns_rr_iter rr_iter_storage, *rr_iter; const uint8_t *pos, *rdata_end;
const uint8_t *pos;
uint16_t rdata_len, opt_code = 0, opt_len = 0; 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) */ /* Search for the OPT RR (if any) */
for ( rr_iter = _getdns_rr_iter_init(&rr_iter_storage if (!netreq->response_opt) {
, response, response_len) _getdns_rr_iter rr_iter_storage, *rr_iter;
; rr_iter for ( rr_iter = _getdns_rr_iter_init(&rr_iter_storage
; rr_iter = _getdns_rr_iter_next(rr_iter)) { , netreq->response, netreq->response_len)
; rr_iter
; rr_iter = _getdns_rr_iter_next(rr_iter)) {
if (_getdns_rr_iter_section(rr_iter) != SECTION_ADDITIONAL) if (_getdns_rr_iter_section(rr_iter) != SECTION_ADDITIONAL)
continue; continue;
if (gldns_read_uint16(rr_iter->rr_type) != GETDNS_RRTYPE_OPT) if (gldns_read_uint16(rr_iter->rr_type) != GETDNS_RRTYPE_OPT)
continue; continue;
break;
break; }
} if (! rr_iter) {
if (! rr_iter) netreq->response_opt = NO_OPT_RR;
return 0; /* No OPT, no cookie */ return MATCH_OPT_NOT_FOUND;
}
pos = rr_iter->rr_type + 8; pos = netreq->response_opt = rr_iter->rr_type + 8;
#if defined(STUB_DEBUG) && STUB_DEBUG #if defined(STUB_DEBUG) && STUB_DEBUG
char str_spc[8192], *str = str_spc; char str_spc[8192], *str = str_spc;
size_t str_len = sizeof(str_spc); size_t str_len = sizeof(str_spc);
uint8_t *data = (uint8_t *)rr_iter->pos; uint8_t *data = (uint8_t *)rr_iter->pos;
size_t data_len = rr_iter->nxt - rr_iter->pos; size_t data_len = rr_iter->nxt - rr_iter->pos;
(void) gldns_wire2str_rr_scan( (void) gldns_wire2str_rr_scan(&data, &data_len, &str, &str_len,
&data, &data_len, &str, &str_len, (uint8_t *)rr_iter->pkt, rr_iter->pkt_end - rr_iter->pkt, NULL); (uint8_t *)rr_iter->pkt, rr_iter->pkt_end - rr_iter->pkt,
DEBUG_STUB("%s %-35s: OPT RR: %s", NULL);
STUB_DEBUG_READ, __FUNC__, str_spc); DEBUG_STUB("%s %-35s: OPT RR: %s",
STUB_DEBUG_READ, __FUNC__, str_spc);
#endif #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 */ rdata_len = gldns_read_uint16(pos);
if (pos + 2 > rr_iter->nxt) pos += 2;
return 1; /* FORMERR */ rdata_end = pos + rdata_len;
rdata_len = gldns_read_uint16(pos); pos += 2; while (pos < rdata_end) {
if (pos + rdata_len > rr_iter->nxt)
return 1; /* FORMERR */
while (pos < rr_iter->nxt) {
opt_code = gldns_read_uint16(pos); pos += 2; opt_code = gldns_read_uint16(pos); pos += 2;
opt_len = gldns_read_uint16(pos); pos += 2; opt_len = gldns_read_uint16(pos); pos += 2;
if (pos + opt_len > rr_iter->nxt) if (pos + opt_len > rdata_end)
return 1; /* FORMERR */ return MATCH_OPT_ERROR;
if (opt_code == code) if (opt_code == code)
break; break;
pos += opt_len; /* Skip unknown options */ pos += opt_len; /* Skip unknown options */
} }
if (pos >= rr_iter->nxt || opt_code != code) if (pos >= rdata_end || opt_code != code)
return 0; /* Everything OK, just no cookie found. */ return MATCH_OPT_NOT_FOUND;
*position = pos; *position = pos;
*option_len = opt_len; *option_len = opt_len;
return 2; return MATCH_OPT_FOUND;
} }
/* TODO: Test combinations of EDNS0 options*/ /* TODO: Test combinations of EDNS0 options*/
static int static int
match_and_process_server_cookie( 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; const uint8_t *position = NULL;
uint16_t option_len = 0; uint16_t option_len = 0;
int found = match_edns_opt_rr(EDNS_COOKIE_OPCODE, response, int gai_r;
response_len, &position, &option_len); int found = match_edns_opt_rr(EDNS_COOKIE_OPCODE, netreq,
if (found != 2) &position, &option_len);
return found; 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; /* Discard and wait for better response */
return 1; /* FORMERR */ }
else if (found == MATCH_OPT_NOT_FOUND) {
if (!upstream->has_client_cookie) /* Option not found, server does not support cookies */
return 1; /* Cookie reply, but we didn't sent one */ if (upstream->server_cookie_len > 8) {
_getdns_upstream_log(upstream,
if (memcmp(upstream->client_cookie, position, 8) != 0) { GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_ERR,
if (!upstream->has_prev_client_cookie) "%-40s : Upstream : Server did not return "
return 1; /* Cookie didn't match */ " DNS Cookie. Response discarded.\n",
if (memcmp(upstream->prev_client_cookie, position, 8) != 0) upstream->addr_str);
return 1; /* Previous cookie didn't match either */
return 1; /* Discard response */
upstream->has_server_cookie = 0;
return 0; /* Don't store server cookie, because it } else if (netreq->cookie_sent) {
* is for our previous client cookie _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;
} }
position += 8;
option_len -= 8;
upstream->has_server_cookie = 1;
upstream->server_cookie_len = option_len;
(void) memcpy(upstream->server_cookie, position, option_len);
return 0; return 0;
} }
static void static void
process_keepalive( process_keepalive( getdns_upstream *upstream, getdns_network_req *netreq)
getdns_upstream *upstream, getdns_network_req *netreq,
uint8_t *response, size_t response_len)
{ {
const uint8_t *position = NULL; const uint8_t *position = NULL;
uint16_t option_len = 0; uint16_t option_len = 0;
int found = match_edns_opt_rr(GLDNS_EDNS_KEEPALIVE, response, int found = match_edns_opt_rr(GLDNS_EDNS_KEEPALIVE, netreq,
response_len, &position, &option_len); &position, &option_len);
if (found != 2 || option_len != 2) { if (found != 2 || option_len != 2) {
if (netreq->keepalive_sent == 1) { if (netreq->keepalive_sent == 1) {
/* For TCP if no keepalive sent back, then we must use 0 idle timeout /* For TCP if no keepalive sent back, then we must use 0 idle timeout
@ -373,8 +448,27 @@ getdns_sock_nonblock(int sockfd)
#endif #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 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) #if defined(TCP_FASTOPEN) || defined(TCP_FASTOPEN_CONNECT)
# ifdef USE_WINSOCK # ifdef USE_WINSOCK
@ -393,6 +487,8 @@ tcp_connect(getdns_upstream *upstream, getdns_transport_list_t transport)
return -1; return -1;
getdns_sock_nonblock(fd); getdns_sock_nonblock(fd);
if (send_timeout != -1)
getdns_sock_tcp_send_timeout(upstream, fd, send_timeout);
#ifdef USE_OSX_TCP_FASTOPEN #ifdef USE_OSX_TCP_FASTOPEN
sa_endpoints_t endpoints; sa_endpoints_t endpoints;
endpoints.sae_srcif = 0; endpoints.sae_srcif = 0;
@ -409,7 +505,7 @@ tcp_connect(getdns_upstream *upstream, getdns_transport_list_t transport)
_getdns_socketerror() == _getdns_EWOULDBLOCK) _getdns_socketerror() == _getdns_EWOULDBLOCK)
return fd; return fd;
(void)transport; (void)transport; /* unused parameter */
#else /* USE_OSX_TCP_FASTOPEN */ #else /* USE_OSX_TCP_FASTOPEN */
/* Note that error detection is different with TFO. Since the handshake /* Note that error detection is different with TFO. Since the handshake
doesn't start till the sendto() lack of connection is often delayed until 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", "%-40s : Upstream : Could not setup TCP TFO\n",
upstream->addr_str); upstream->addr_str);
# else # else
(void)transport; (void)transport; /* unused parameter */
# endif/* HAVE_DECL_TCP_FASTOPEN*/ # endif/* HAVE_DECL_TCP_FASTOPEN*/
# endif /* HAVE_DECL_TCP_FASTOPEN_CONNECT */ # endif /* HAVE_DECL_TCP_FASTOPEN_CONNECT */
#endif /* USE_OSX_TCP_FASTOPEN */ #endif /* USE_OSX_TCP_FASTOPEN */
@ -957,7 +1053,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 /* 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 possible only if we have the right type of connection. Note a change
@ -982,7 +1080,7 @@ tls_do_handshake(getdns_upstream *upstream)
int r; int r;
while ((r = _getdns_tls_connection_do_handshake(upstream->tls_obj)) != GETDNS_RETURN_GOOD) 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) if (timeout_tls < MIN_TLS_HS_TIMEOUT)
timeout_tls = MIN_TLS_HS_TIMEOUT; timeout_tls = MIN_TLS_HS_TIMEOUT;
@ -1035,8 +1133,8 @@ tls_do_handshake(getdns_upstream *upstream)
: "*Failure*" )); : "*Failure*" ));
upstream->tls_auth_state = GETDNS_AUTH_FAILED; upstream->tls_auth_state = GETDNS_AUTH_FAILED;
} else { } else {
long verify_errno; long verify_errno = 0;
const char* verify_errmsg; const char* verify_errmsg = "Unknown verify error (fix reporting!)";
if (_getdns_tls_connection_certificate_verify(upstream->tls_obj, &verify_errno, &verify_errmsg)) { if (_getdns_tls_connection_certificate_verify(upstream->tls_obj, &verify_errno, &verify_errmsg)) {
upstream->tls_auth_state = GETDNS_AUTH_FAILED; upstream->tls_auth_state = GETDNS_AUTH_FAILED;
@ -1340,6 +1438,7 @@ _getdns_get_time_as_uintt64() {
/**************************/ /**************************/
static void stub_udp_write_cb(void *userarg);
static void static void
stub_udp_read_cb(void *userarg) stub_udp_read_cb(void *userarg)
{ {
@ -1385,14 +1484,15 @@ stub_udp_read_cb(void *userarg)
if (GLDNS_ID_WIRE(netreq->response) != GLDNS_ID_WIRE(netreq->query)) if (GLDNS_ID_WIRE(netreq->response) != GLDNS_ID_WIRE(netreq->query))
return; /* Cache poisoning attempt ;) */ return; /* Cache poisoning attempt ;) */
if (netreq->owner->edns_cookies && match_and_process_server_cookie( if (netreq->owner->edns_cookies) {
upstream, netreq->response, read)) netreq->response_len = read;
return; /* Client cookie didn't match? */ 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_CLEAR_EVENT(dnsreq->loop, &netreq->event);
_getdns_closesocket(netreq->fd);
netreq->fd = -1;
while (GLDNS_TC_WIRE(netreq->response)) { while (GLDNS_TC_WIRE(netreq->response)) {
DEBUG_STUB("%s %-35s: MSG: %p TC bit set in response \n", STUB_DEBUG_READ, DEBUG_STUB("%s %-35s: MSG: %p TC bit set in response \n", STUB_DEBUG_READ,
__FUNC__, (void*)netreq); __FUNC__, (void*)netreq);
@ -1403,6 +1503,9 @@ stub_udp_read_cb(void *userarg)
if (next_transport != GETDNS_TRANSPORT_TCP && if (next_transport != GETDNS_TRANSPORT_TCP &&
next_transport != GETDNS_TRANSPORT_TLS) next_transport != GETDNS_TRANSPORT_TLS)
break; break;
_getdns_closesocket(netreq->fd);
netreq->fd = -1;
/* For now, special case where fallback should be on the same upstream*/ /* For now, special case where fallback should be on the same upstream*/
if ((netreq->fd = upstream_connect(upstream, next_transport, if ((netreq->fd = upstream_connect(upstream, next_transport,
dnsreq)) == -1) dnsreq)) == -1)
@ -1412,10 +1515,27 @@ stub_udp_read_cb(void *userarg)
_getdns_ms_until_expiry(dnsreq->expires), _getdns_ms_until_expiry(dnsreq->expires),
getdns_eventloop_event_init(&netreq->event, getdns_eventloop_event_init(&netreq->event,
netreq, NULL, NULL, stub_timeout_cb)); netreq, NULL, NULL, stub_timeout_cb));
return; return;
} }
netreq->response_len = read; 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) if (!dnsreq->context->round_robin_upstreams)
dnsreq->upstreams->current_udp = 0; dnsreq->upstreams->current_udp = 0;
else { else {
@ -1426,7 +1546,7 @@ stub_udp_read_cb(void *userarg)
netreq->debug_end_time = _getdns_get_time_as_uintt64(); netreq->debug_end_time = _getdns_get_time_as_uintt64();
_getdns_netreq_change_state(netreq, NET_REQ_FINISHED); _getdns_netreq_change_state(netreq, NET_REQ_FINISHED);
upstream->udp_responses++; upstream->udp_responses++;
upstream->back_off = 1; upstream->back_off = 1;
if (upstream->udp_responses == 1 || if (upstream->udp_responses == 1 ||
upstream->udp_responses % 100 == 0) upstream->udp_responses % 100 == 0)
_getdns_upstream_log(upstream, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_INFO, _getdns_upstream_log(upstream, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_INFO,
@ -1582,16 +1702,12 @@ upstream_read_cb(void *userarg)
upstream->tcp.read_buf = NULL; upstream->tcp.read_buf = NULL;
upstream->responses_received++; upstream->responses_received++;
/* !THIS CODE NEEDS TESTING! */
if (netreq->owner->edns_cookies && if (netreq->owner->edns_cookies &&
match_and_process_server_cookie( match_and_process_server_cookie(netreq->upstream, netreq))
netreq->upstream, upstream->tcp.read_buf,
upstream->tcp.read_pos - upstream->tcp.read_buf))
return; /* Client cookie didn't match (or FORMERR) */ return; /* Client cookie didn't match (or FORMERR) */
if (netreq->owner->context->idle_timeout != 0) if (netreq->owner->context->idle_timeout != 0)
process_keepalive(netreq->upstream, netreq, netreq->response, process_keepalive(netreq->upstream, netreq);
netreq->response_len);
netreq->debug_end_time = _getdns_get_time_as_uintt64(); netreq->debug_end_time = _getdns_get_time_as_uintt64();
/* This also reschedules events for the upstream*/ /* This also reschedules events for the upstream*/
@ -2053,7 +2169,8 @@ upstream_connect(getdns_upstream *upstream, getdns_transport_list_t transport,
/* Use existing if available*/ /* Use existing if available*/
if (upstream->fd != -1) if (upstream->fd != -1)
return upstream->fd; return upstream->fd;
fd = tcp_connect(upstream, transport); fd = tcp_connect(upstream, transport,
dnsreq->context->tcp_send_timeout);
if (fd == -1) { if (fd == -1) {
upstream_failed(upstream, 1); upstream_failed(upstream, 1);
return -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_dict *response, void *userarg, getdns_transaction_t transaction_id)
{ {
getdns_sync_data *data = (getdns_sync_data *)userarg; 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); assert(data);

View File

@ -457,7 +457,7 @@
void *userarg, void *userarg,
getdns_transaction_t transaction_id) getdns_transaction_t transaction_id)
{ {
(void)context; (void)response; (void)userarg; (void)context; (void)response; (void)userarg; /* unused parameters */
callback_called++; callback_called++;
@ -466,23 +466,23 @@
callback_canceled++; callback_canceled++;
ck_assert_msg(transaction_id % 2, ck_assert_msg(transaction_id % 2,
"Only callbacks with odd transaction_ids were canceled, this one is even: %d", "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) else if(callback_type == GETDNS_CALLBACK_COMPLETE)
{ {
callback_completed++; callback_completed++;
ck_assert_msg((transaction_id % 2) == 0, ck_assert_msg((transaction_id % 2) == 0,
"One callbacks with even transaction_ids should complete, this one is odd: %d", "One callbacks with even transaction_ids should complete, this one is odd: %d",
transaction_id); (int)transaction_id);
} }
else else
{ {
if(transaction_id % 2) if(transaction_id % 2)
ck_abort_msg("callback_type should == GETDNS_CALLBACK_CANCEL for odd transaction_id (%d), got: %d", 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 else
ck_abort_msg("callback_type should == GETDNS_CALLBACK_COMPLETE for even transaction_id (%d), got %d", 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 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. * 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) void extract_response(struct getdns_dict *response, struct extracted_response *ex_response)
{ {
int have_answer_type = 0; int have_answer_type = 0;
int get_reply = 0;
uint32_t rcode;
ck_assert_msg(response != NULL, "Response should not be NULL"); ck_assert_msg(response != NULL, "Response should not be NULL");
/* fprintf(stderr, "%s\n", getdns_pretty_print_dict(response)); */ /* 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; ex_response->question = NULL;
return; 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), 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[0]\""); GETDNS_RETURN_GOOD, "Failed to extract \"replies_tree[#]\"");
ck_assert_msg(ex_response->replies_tree_sub_dict != NULL, "replies_tree[0] dict should not be NULL"); 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), ASSERT_RC(getdns_dict_get_list(ex_response->replies_tree_sub_dict, "additional", &ex_response->additional),
GETDNS_RETURN_GOOD, "Failed to extract \"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), ASSERT_RC(getdns_list_get_length(ex_response->answer, &length),
GETDNS_RETURN_GOOD, "Failed to extract \"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\""); 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), ASSERT_RC(getdns_list_get_length(ex_response->answer, &length),
GETDNS_RETURN_GOOD, "Failed to extract \"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++) 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"); GETDNS_RETURN_GOOD, "Failed to extract \"just_address_answers\" length");
if (length == 0) resp_str = getdns_pretty_print_dict(ex_response->response); 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); 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), ASSERT_RC(getdns_list_get_length(ex_response->authority, &length),
GETDNS_RETURN_GOOD, "Failed to extract \"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++) 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), ASSERT_RC(getdns_list_get_length(ex_response->answer, &length),
GETDNS_RETURN_GOOD, "Failed to extract \"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++) for(i = 0; i < length; i++)
{ {
@ -339,7 +349,7 @@ void destroy_callbackfn(struct getdns_context *context,
void *userarg, void *userarg,
getdns_transaction_t transaction_id) { getdns_transaction_t transaction_id) {
int* flag = (int*)userarg; int* flag = (int*)userarg;
(void)callback_type; (void)transaction_id; (void)callback_type; (void)transaction_id; /* unused parameters */
*flag = 1; *flag = 1;
getdns_dict_destroy(response); getdns_dict_destroy(response);
getdns_context_destroy(context); getdns_context_destroy(context);
@ -359,7 +369,7 @@ void callbackfn(struct getdns_context *context,
{ {
typedef void (*fn_ptr)(struct extracted_response *ex_response); typedef void (*fn_ptr)(struct extracted_response *ex_response);
fn_ptr fn = ((fn_cont *)userarg)->fn; 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 * 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, void update_callbackfn(struct getdns_context *context,
getdns_context_code_t changed_item) getdns_context_code_t changed_item)
{ {
(void)context; (void)context; /* unused parameter */
ck_assert_msg(changed_item == expected_changed_item, ck_assert_msg(changed_item == expected_changed_item,
"Expected changed_item == %d, got %d", "Expected changed_item == %d, got %d",
changed_item, expected_changed_item); changed_item, expected_changed_item);

View File

@ -271,7 +271,7 @@
void verify_getdns_context_destroy(struct extracted_response *ex_response) 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. * Sleep for a second to make getdns_context_destroy() wait.
*/ */

View File

@ -266,7 +266,7 @@ void timeout_3_cb(struct getdns_context *context,
getdns_callback_type_t callback_type, getdns_callback_type_t callback_type,
struct getdns_dict * response, struct getdns_dict * response,
void *userarg, getdns_transaction_t transaction_id) { 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; timeout_thread_data *tdata = (timeout_thread_data*)userarg;
tdata->num_callbacks++; tdata->num_callbacks++;
if (callback_type == GETDNS_CALLBACK_TIMEOUT) { if (callback_type == GETDNS_CALLBACK_TIMEOUT) {

View File

@ -44,7 +44,8 @@
char *alabel = NULL; char *alabel = NULL;
ck_assert_msg( getdns_convert_alabel_to_ulabel( alabel ) == 0, 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 END_TEST

View File

@ -45,7 +45,8 @@
ck_assert_msg(( getdns_convert_ulabel_to_alabel( ulabel ) == 0 ), 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 END_TEST

View File

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

View File

@ -98,7 +98,7 @@
ASSERT_RC(getdns_list_get_length(answer, &length), ASSERT_RC(getdns_list_get_length(answer, &length),
GETDNS_RETURN_GOOD, "Return code from getdns_list_get_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++) for(i = 0; i < length; i++)
{ {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -89,7 +89,7 @@
ASSERT_RC(getdns_list_get_length(list, &length), ASSERT_RC(getdns_list_get_length(list, &length),
GETDNS_RETURN_GOOD, "Return code from getdns_list_get_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); LIST_DESTROY(list);
} }
@ -110,7 +110,7 @@
ASSERT_RC(getdns_list_get_length(list, &length), ASSERT_RC(getdns_list_get_length(list, &length),
GETDNS_RETURN_GOOD, "Return code from getdns_list_get_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); LIST_DESTROY(list);
} }

View File

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

View File

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

View File

@ -57,7 +57,7 @@ this_callbackfn(struct getdns_context *this_context,
struct getdns_dict *this_response, struct getdns_dict *this_response,
void *this_userarg, getdns_transaction_t this_transaction_id) 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 */ if (this_callback_type == GETDNS_CALLBACK_COMPLETE) { /* This is a callback with data */
char *res = getdns_pretty_print_dict(this_response); 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" mkdir "${BUILDDIR}/build-stub-only"
cd "${BUILDDIR}/build-stub-only" cd "${BUILDDIR}/build-stub-only"
rm -f CMakeCache.txt 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 8.8.8.8
-H 2a04:b900:0:100::37 -H 2a04:b900:0:100::37
-A _acme-challenge.getdnsapi.net -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
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 then
exit 1 exit 1
else else
diff out "${TPKG_NAME}.good" diff out "${TPKG_NAME}.good" --ignore-matching-lines=";; MSG SIZE rcvd: "
fi fi

View File

@ -9,10 +9,6 @@ int main()
getdns_return_t r; getdns_return_t r;
getdns_context *ctx = NULL; getdns_context *ctx = NULL;
getdns_dict *extensions = 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_list *upstreams = NULL;
getdns_dict *response = NULL; getdns_dict *response = NULL;
uint32_t value; uint32_t value;
@ -21,39 +17,20 @@ int main()
if ((r = getdns_context_create(&ctx, 1))) if ((r = getdns_context_create(&ctx, 1)))
fprintf(stderr, "Could not create context"); 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))) else if ((r = getdns_context_set_resolution_type(ctx, GETDNS_RESOLUTION_STUB)))
fprintf(stderr, "Could not set stub mode"); 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))) else if ((r = getdns_context_set_upstream_recursive_servers(ctx, upstreams)))
fprintf(stderr, "Could not set upstreams list"); 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))) else if ((r = getdns_general_sync(ctx, "bogus.nlnetlabs.nl.", GETDNS_RRTYPE_TXT, extensions, &response)))
fprintf(stderr, "Could not do lookup"); fprintf(stderr, "Could not do lookup");
@ -61,7 +38,8 @@ int main()
fprintf(stderr, "Could not get status from response"); fprintf(stderr, "Could not get status from response");
else if (value != GETDNS_RESPSTATUS_GOOD) { 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; r = GETDNS_RETURN_GENERIC_ERROR;
} else if ((r = getdns_dict_get_int(response, "/replies_tree/0/header/rd", &value))) } else if ((r = getdns_dict_get_int(response, "/replies_tree/0/header/rd", &value)))
@ -100,8 +78,6 @@ int main()
getdns_dict_destroy(response); getdns_dict_destroy(response);
if (upstreams) if (upstreams)
getdns_list_destroy(upstreams); getdns_list_destroy(upstreams);
if (upstream)
getdns_dict_destroy(upstream);
if (extensions) if (extensions)
getdns_dict_destroy(extensions); getdns_dict_destroy(extensions);
if (ctx) if (ctx)

View File

@ -199,7 +199,7 @@ for (( ii = 0; ii < 1; ii++)); do
echo "*Success fallback cases:" echo "*Success fallback cases:"
for (( j = 0; j < $NUM_GOOD_FB_QUERIES; j+=1 )); do for (( j = 0; j < $NUM_GOOD_FB_QUERIES; j+=1 )); do
check_good "`"${GETDNS_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]}" echo "getdns_query $SYNC_MODE ${GOOD_FALLBACK_QUERIES[$j*$NUM_ARGS]} TESTS: ${GOOD_FALLBACK_QUERIES[$((j*NUM_ARGS))+1]} ${GOOD_FALLBACK_QUERIES[$((j*NUM_ARGS))+2]}"
(( COUNT++ )) (( COUNT++ ))
done done

View File

@ -72,6 +72,10 @@
#include <openssl/engine.h> #include <openssl/engine.h>
#endif #endif
#if defined(HAVE_OPENSSL_DSA_H) && defined(USE_DSA)
#include <openssl/dsa.h>
#endif
/** fake DSA support for unit tests */ /** fake DSA support for unit tests */
int fake_dsa = 0; int fake_dsa = 0;
/** fake SHA1 support for unit tests */ /** fake SHA1 support for unit tests */
@ -138,6 +142,69 @@ secalgo_hash_sha256(unsigned char* buf, size_t len, unsigned char* res)
#endif #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. * Return size of DS digest according to its hash algorithm.
* @param algo: DS digest algo. * @param algo: DS digest algo.
@ -327,8 +394,10 @@ setup_dsa_sig(unsigned char** sig, unsigned int* len)
#ifdef HAVE_DSA_SIG_SET0 #ifdef HAVE_DSA_SIG_SET0
if(!DSA_SIG_set0(dsasig, R, S)) return 0; if(!DSA_SIG_set0(dsasig, R, S)) return 0;
#else #else
# ifndef S_SPLINT_S
dsasig->r = R; dsasig->r = R;
dsasig->s = S; dsasig->s = S;
# endif /* S_SPLINT_S */
#endif #endif
*sig = NULL; *sig = NULL;
newlen = i2d_DSA_SIG(dsasig, sig); newlen = i2d_DSA_SIG(dsasig, sig);
@ -818,6 +887,64 @@ secalgo_hash_sha256(unsigned char* buf, size_t len, unsigned char* res)
(void)HASH_HashBuf(HASH_AlgSHA256, res, buf, (unsigned long)len); (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 size_t
ds_digest_size_supported(int algo) ds_digest_size_supported(int algo)
{ {
@ -985,6 +1112,7 @@ static SECKEYPublicKey* nss_buf2ecdsa(unsigned char* key, size_t len, int algo)
return pk; return pk;
} }
#if defined(USE_DSA) && defined(USE_SHA1)
static SECKEYPublicKey* nss_buf2dsa(unsigned char* key, size_t len) static SECKEYPublicKey* nss_buf2dsa(unsigned char* key, size_t len)
{ {
SECKEYPublicKey* pk; SECKEYPublicKey* pk;
@ -1045,6 +1173,7 @@ static SECKEYPublicKey* nss_buf2dsa(unsigned char* key, size_t len)
} }
return pk; return pk;
} }
#endif /* USE_DSA && USE_SHA1 */
static SECKEYPublicKey* nss_buf2rsa(unsigned char* key, size_t len) static SECKEYPublicKey* nss_buf2rsa(unsigned char* key, size_t len)
{ {
@ -1444,6 +1573,82 @@ secalgo_hash_sha256(unsigned char* buf, size_t len, unsigned char* res)
_digest_nettle(SHA256_DIGEST_SIZE, (uint8_t*)buf, len, 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. * Return size of DS digest according to its hash algorithm.
* @param algo: DS digest algo. * @param algo: DS digest algo.
@ -1508,13 +1713,21 @@ dnskey_algo_id_is_supported(int id)
{ {
/* uses libnettle */ /* uses libnettle */
switch(id) { switch(id) {
#if defined(USE_DSA) && defined(USE_SHA1)
case LDNS_DSA: case LDNS_DSA:
case LDNS_DSA_NSEC3: case LDNS_DSA_NSEC3:
#if defined(USE_DSA) && defined(USE_SHA1)
return 1;
#else
if(fake_dsa || fake_sha1) return 1;
return 0;
#endif #endif
#ifdef USE_SHA1
case LDNS_RSASHA1: case LDNS_RSASHA1:
case LDNS_RSASHA1_NSEC3: case LDNS_RSASHA1_NSEC3:
#ifdef USE_SHA1
return 1;
#else
if(fake_sha1) return 1;
return 0;
#endif #endif
#ifdef USE_SHA2 #ifdef USE_SHA2
case LDNS_RSASHA256: case LDNS_RSASHA256:
@ -1741,6 +1954,7 @@ _verify_nettle_ecdsa(sldns_buffer* buf, unsigned int digest_size, unsigned char*
res &= nettle_ecdsa_verify (&pubkey, SHA256_DIGEST_SIZE, digest, &signature); res &= nettle_ecdsa_verify (&pubkey, SHA256_DIGEST_SIZE, digest, &signature);
mpz_clear(x); mpz_clear(x);
mpz_clear(y); mpz_clear(y);
nettle_ecc_point_clear(&pubkey);
break; break;
} }
case SHA384_DIGEST_SIZE: case SHA384_DIGEST_SIZE:
@ -1827,6 +2041,15 @@ verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock,
return sec_status_bogus; 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) { switch(algo) {
#if defined(USE_DSA) && defined(USE_SHA1) #if defined(USE_DSA) && defined(USE_SHA1)
case LDNS_DSA: case LDNS_DSA:

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

View File

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

View File

@ -233,8 +233,6 @@ typedef struct getdns_network_req
int edns_maximum_udp_payload_size; int edns_maximum_udp_payload_size;
uint16_t max_udp_payload_size; uint16_t max_udp_payload_size;
size_t keepalive_sent;
/* Network requests scheduled to write after me */ /* Network requests scheduled to write after me */
struct getdns_network_req *write_queue_tail; 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_auth_state_t debug_tls_auth_status;
getdns_bindata debug_tls_peer_cert; getdns_bindata debug_tls_peer_cert;
const char *debug_tls_version; 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 /* When more space is needed for the wire_data response than is
* available in wire_data[], it will be allocated separately. * 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 base_query_option_sz;
size_t response_len; size_t response_len;
uint8_t *response; uint8_t *response;
const uint8_t *response_opt; /* offset of OPT RR in response */
size_t wire_data_sz; size_t wire_data_sz;
uint8_t wire_data[]; 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) static void my_event_base_free(struct ub_event_base* base)
{ {
/* We don't allocate our event base, so no need to free */ /* We don't allocate our event base, so no need to free */
(void)base; (void)base; /* unused parameter */
return; return;
} }
static int my_event_base_dispatch(struct ub_event_base* base) 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 /* We run the event loop extension for which this ub_event_base is an
* interface ourselfs, so no need to let libunbound call dispatch. * 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) 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 /* Not sure when this will be called. But it is of no influence as we
* run the event loop ourself. * 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) 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 */ /* Only unbound daaemon workers use signals */
DEBUG_SCHED("UB_LOOP ERROR: signal_add()\n"); DEBUG_SCHED("UB_LOOP ERROR: signal_add()\n");
return -1; 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) static int my_signal_del(struct ub_event* ub_ev)
{ {
(void)ub_ev; (void)ub_ev; /* unused parameter */
/* Only unbound daaemon workers use signals */ /* Only unbound daaemon workers use signals */
DEBUG_SCHED("UB_LOOP ERROR: signal_del()\n"); DEBUG_SCHED("UB_LOOP ERROR: signal_del()\n");
return -1; 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) static void my_winsock_unregister_wsaevent(struct ub_event* ev)
{ {
/* wsa events don't get registered with libunbound */ /* 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) static void my_winsock_tcp_wouldblock(struct ub_event* ev, int bits)
{ {
#ifndef USE_WINSOCK #ifndef USE_WINSOCK
(void)ev; (void)bits; (void)ev; (void)bits; /* unused parameters */
#else #else
if (bits & UB_EV_READ) if (bits & UB_EV_READ)
AS_MY_EVENT(ev)->read_wouldblock = 1; 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) void (*cb)(int, short, void*), void* arg)
{ {
/* Not applicable, because in unbound used in the daemon only */ /* 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; 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) void* wsaevent, void (*cb)(int, short, void*), void* arg)
{ {
/* Not applicable, because in unbound used for tubes only */ /* 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; return NULL;
} }

View File

@ -299,9 +299,10 @@ _getdns_rr_iter2rr_dict_canonical(
} }
} else if (rdf->rdd_pos->type == GETDNS_RDF_SPECIAL) } else if (rdf->rdd_pos->type == GETDNS_RDF_SPECIAL)
val_type = wf_special; val_type = wf_special;
else else {
assert(((val_type = wf_int), 0)); val_type = wf_int;
assert(0);
}
if (! rdf->rdd_repeat) { if (! rdf->rdd_repeat) {
switch (val_type) { switch (val_type) {
case wf_int: 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) rr_type == GETDNS_RRTYPE_RRSIG && rrsigs_in_answer)
*rrsigs_in_answer = 1; *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 (section != SECTION_ANSWER) {
if (_getdns_list_append_this_dict( if (_getdns_list_append_this_dict(
sections[section], rr_dict)) sections[section], rr_dict))
@ -1402,7 +1409,7 @@ getdns_return_t
getdns_apply_network_result(getdns_network_req* netreq, getdns_apply_network_result(getdns_network_req* netreq,
int rcode, void *pkt, int pkt_len, int sec, char* why_bogus) 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 netreq->dnssec_status = sec == 0 ? GETDNS_DNSSEC_INSECURE
: sec == 2 ? GETDNS_DNSSEC_SECURE : 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; 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) INLINE uint64_t _getdns_ms_until_expiry2(uint64_t expires, uint64_t *now_ms)
{ {
if (*now_ms == 0) *now_ms = _getdns_get_now_ms(); if (*now_ms == 0) *now_ms = _getdns_get_now_ms();

View File

@ -1,10 +1,10 @@
#!/bin/sh #!/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 rbtree.c ${REPO}/util/rbtree.c
wget -O orig-headers/rbtree.h ${REPO}/util/rbtree.h 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 orig-headers/val_secalgo.h ${REPO}/validator/val_secalgo.h
wget -O lruhash.c ${REPO}/util/storage/lruhash.c wget -O lruhash.c ${REPO}/util/storage/lruhash.c
wget -O orig-headers/lruhash.h ${REPO}/util/storage/lruhash.h wget -O orig-headers/lruhash.h ${REPO}/util/storage/lruhash.h

View File

@ -42,7 +42,6 @@
#include "config.h" #include "config.h"
#include "util/locks.h" #include "util/locks.h"
#include <signal.h> #include <signal.h>
#include <string.h>
#ifdef HAVE_SYS_WAIT_H #ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h> #include <sys/wait.h>
#endif #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. February 2013(Wouter) patch defines for BSD endianness, from Brad Smith.
January 2012(Wouter) added randomised initial value, fallout from 28c3. January 2012(Wouter) added randomised initial value, fallout from 28c3.
March 2007(Wouter) adapted from lookup3.c original, add config.h include. March 2007(Wouter) adapted from lookup3.c original, add config.h include.
@ -44,6 +47,7 @@ on 1 byte), but shoehorning those bytes into integers efficiently is messy.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
*/ */
/*#define SELF_TEST 1*/ /*#define SELF_TEST 1*/
#define ARRAY_CLEAN_ACCESS 1
#include "config.h" #include "config.h"
#include "util/storage/lookup3.h" #include "util/storage/lookup3.h"
@ -59,50 +63,8 @@ on 1 byte), but shoehorning those bytes into integers efficiently is messy.
# define HASH_BIG_ENDIAN 0 # define HASH_BIG_ENDIAN 0
# endif # endif
#else #else
#ifdef HAVE_SYS_TYPES_H # error "Target endianness required."
# include <sys/types.h> /* attempt to define endianness (solaris) */ #endif /* defined(HAVE_TARGET_ENDIANNESS) */
#endif
#if defined(linux) || defined(__OpenBSD__)
# ifdef HAVE_ENDIAN_H
# include <endian.h> /* attempt to define endianness */
# else
# include <machine/endian.h> /* on older OpenBSD */
# endif
#endif
#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.
*/
#if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && \
__BYTE_ORDER == __LITTLE_ENDIAN) || \
(defined(i386) || defined(__i386__) || defined(__i486__) || \
defined(__i586__) || defined(__i686__) || defined(vax) || defined(MIPSEL) || defined(__x86))
# define HASH_LITTLE_ENDIAN 1
# define HASH_BIG_ENDIAN 0
#elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && \
__BYTE_ORDER == __BIG_ENDIAN) || \
(defined(sparc) || defined(__sparc) || defined(__sparc__) || defined(POWERPC) || defined(mc68000) || defined(sel))
# define HASH_LITTLE_ENDIAN 0
# define HASH_BIG_ENDIAN 1
#elif defined(_MACHINE_ENDIAN_H_)
/* test for machine_endian_h protects failure if some are empty strings */
# if defined(_BYTE_ORDER) && defined(_BIG_ENDIAN) && _BYTE_ORDER == _BIG_ENDIAN
# define HASH_LITTLE_ENDIAN 0
# define HASH_BIG_ENDIAN 1
# endif
# if defined(_BYTE_ORDER) && defined(_LITTLE_ENDIAN) && _BYTE_ORDER == _LITTLE_ENDIAN
# define HASH_LITTLE_ENDIAN 1
# define HASH_BIG_ENDIAN 0
# endif /* _MACHINE_ENDIAN_H_ */
#else
# define HASH_LITTLE_ENDIAN 0
# define HASH_BIG_ENDIAN 0
#endif
#endif /* defined(TARGET_IS_BIG_ENDIAN) */
/* random initial value */ /* random initial value */
static uint32_t raninit = (uint32_t)0xdeadbeef; static uint32_t raninit = (uint32_t)0xdeadbeef;
@ -345,7 +307,7 @@ uint32_t hashlittle( const void *key, size_t length, uint32_t initval)
u.ptr = key; u.ptr = key;
if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) { if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) {
const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */ const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */
#ifdef VALGRIND #ifdef ARRAY_CLEAN_ACCESS
const uint8_t *k8; const uint8_t *k8;
#endif #endif
@ -370,7 +332,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 * still catch it and complain. The masking trick does make the hash
* noticeably faster for short strings (like English words). * noticeably faster for short strings (like English words).
*/ */
#ifndef VALGRIND #ifndef ARRAY_CLEAN_ACCESS
switch(length) switch(length)
{ {

View File

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

View File

@ -36,8 +36,6 @@
#ifndef UTIL_LOCKS_H #ifndef UTIL_LOCKS_H
#define UTIL_LOCKS_H #define UTIL_LOCKS_H
#include <string.h>
/** /**
* \file * \file
* Locking primitives. * 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 */ #else /* we do not HAVE_SOLARIS_THREADS and no PTHREADS */
/******************* WINDOWS THREADS ************************/ /******************* WINDOWS THREADS ************************/
#ifdef HAVE_WINDOWS_THREADS #ifdef HAVE_WINDOWS_THREADS
#include <winsock2.h>
#include <windows.h> #include <windows.h>
/* Use a mutex */ /* Use a mutex */

View File

@ -43,6 +43,7 @@
#ifndef VALIDATOR_VAL_SECALGO_H #ifndef VALIDATOR_VAL_SECALGO_H
#define VALIDATOR_VAL_SECALGO_H #define VALIDATOR_VAL_SECALGO_H
struct sldns_buffer; struct sldns_buffer;
struct secalgo_hash;
/** Return size of nsec3 hash algorithm, 0 if not supported */ /** Return size of nsec3 hash algorithm, 0 if not supported */
size_t nsec3_hash_algo_size_supported(int id); 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); 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. * Return size of DS digest according to its hash algorithm.
* @param algo: DS digest algo. * @param algo: DS digest algo.

View File

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

2
stubby

@ -1 +1 @@
Subproject commit 709374879bca5d77548df68fd91c51174a862229 Subproject commit 40b6bf95391f639cc86e5d328e89011ef4c16437