mirror of https://github.com/getdnsapi/getdns.git
Merge remote-tracking branch 'upstream/develop' into devel/doxygen
This commit is contained in:
commit
d28283a850
11
ChangeLog
11
ChangeLog
|
@ -1,4 +1,13 @@
|
|||
* 2017-04-??: Version 1.1.0
|
||||
* bugfix: Reschedule request timeout when getting the DNSSEC chain.
|
||||
* getdns_context_unset_edns_maximum_udp_payload_size() to reset
|
||||
to default IPv4/IPv6 dependent edns max udp payload size.
|
||||
* Implement sensible default edns0 padding policy. Thanks DKG.
|
||||
* Keep connections open with sync requests too.
|
||||
* Fix of event loops so they do not give up with naked timers with
|
||||
windows. Thanks Christian Huitema.
|
||||
* Include peer certificate with DNS-over-TLS in combination with
|
||||
the return_call_reporting extension.
|
||||
* More fine grained control over TLS upstream retry and back off
|
||||
behaviour with getdns_context_set_tls_backoff_time() and
|
||||
getdns_context_set_tls_connection_retries().
|
||||
|
@ -14,7 +23,7 @@
|
|||
Thanks Neil Cook
|
||||
* bugfix: authentication failure for self signed cert + only pinset
|
||||
* bugfix: issue with session re-use making authentication appear to fail
|
||||
|
||||
|
||||
* 2017-01-13: Version 1.0.0
|
||||
* edns0_cookies extension enabled by default (per RFC7873)
|
||||
* dnssec_roadblock_avoidance enabled by default (per RFC8027)
|
||||
|
|
16
configure.ac
16
configure.ac
|
@ -37,7 +37,7 @@ sinclude(./m4/ax_check_compile_flag.m4)
|
|||
sinclude(./m4/pkg.m4)
|
||||
|
||||
AC_INIT([getdns], [1.1.0], [users@getdnsapi.net], [], [https://getdnsapi.net])
|
||||
AC_SUBST(RELEASE_CANDIDATE, [-rc1])
|
||||
AC_SUBST(RELEASE_CANDIDATE, [-rc2])
|
||||
|
||||
# Set current date from system if not set
|
||||
AC_ARG_WITH([current-date],
|
||||
|
@ -47,7 +47,7 @@ AC_ARG_WITH([current-date],
|
|||
[CURRENT_DATE="`date -u +%Y-%m-%dT%H:%M:%SZ`"])
|
||||
|
||||
AC_SUBST(GETDNS_VERSION, ["AC_PACKAGE_VERSION$RELEASE_CANDIDATE"])
|
||||
AC_SUBST(GETDNS_NUMERIC_VERSION, [0x0100C100])
|
||||
AC_SUBST(GETDNS_NUMERIC_VERSION, [0x0100C200])
|
||||
AC_SUBST(API_VERSION, ["December 2015"])
|
||||
AC_SUBST(API_NUMERIC_VERSION, [0x07df0c00])
|
||||
GETDNS_COMPILATION_COMMENT="AC_PACKAGE_NAME $GETDNS_VERSION configured on $CURRENT_DATE for the $API_VERSION version of the API"
|
||||
|
@ -149,15 +149,16 @@ fi
|
|||
])
|
||||
ACX_ARG_RPATH
|
||||
|
||||
|
||||
AC_ARG_ENABLE(debug-req, AC_HELP_STRING([--enable-debug-req], [Enable request debugging]))
|
||||
AC_ARG_ENABLE(debug-sched, AC_HELP_STRING([--enable-debug-sched], [Enable scheduling debugging messages]))
|
||||
AC_ARG_ENABLE(debug-stub, AC_HELP_STRING([--enable-debug-stub], [Enable stub debugging messages]))
|
||||
AC_ARG_ENABLE(debug-daemon, AC_HELP_STRING([--enable-debug-daemon], [Enable daemon debugging messages]))
|
||||
AC_ARG_ENABLE(debug-sec, AC_HELP_STRING([--enable-debug-sec], [Enable dnssec debugging messages]))
|
||||
AC_ARG_ENABLE(debug-server, AC_HELP_STRING([--enable-debug-server], [Enable server debugging messages]))
|
||||
AC_ARG_ENABLE(all-debugging, AC_HELP_STRING([--enable-all-debugging], [Enable scheduling, stub and dnssec debugging]))
|
||||
AC_ARG_ENABLE(all-debugging, AC_HELP_STRING([--enable-all-debugging], [Enable all debugging messages]))
|
||||
case "$enable_all_debugging" in
|
||||
yes)
|
||||
enable_debug_req=yes
|
||||
enable_debug_sched=yes
|
||||
enable_debug_stub=yes
|
||||
enable_debug_daemon=yes
|
||||
|
@ -167,6 +168,13 @@ case "$enable_all_debugging" in
|
|||
no|*)
|
||||
;;
|
||||
esac
|
||||
case "$enable_debug_req" in
|
||||
yes)
|
||||
AC_DEFINE_UNQUOTED([REQ_DEBUG], [1], [Define this to enable printing of request debugging messages.])
|
||||
;;
|
||||
no|*)
|
||||
;;
|
||||
esac
|
||||
case "$enable_debug_sched" in
|
||||
yes)
|
||||
AC_DEFINE_UNQUOTED([SCHED_DEBUG], [1], [Define this to enable printing of scheduling debugging messages.])
|
||||
|
|
|
@ -153,8 +153,6 @@ static getdns_return_t set_ub_dns_transport(struct getdns_context*);
|
|||
static void set_ub_limit_outstanding_queries(struct getdns_context*,
|
||||
uint16_t);
|
||||
static void set_ub_dnssec_allowed_skew(struct getdns_context*, uint32_t);
|
||||
static void set_ub_edns_maximum_udp_payload_size(struct getdns_context*,
|
||||
int);
|
||||
#endif
|
||||
|
||||
/* Stuff to make it compile pedantically */
|
||||
|
@ -691,11 +689,15 @@ _getdns_upstreams_dereference(getdns_upstreams *upstreams)
|
|||
while (upstream->finished_dnsreqs) {
|
||||
dnsreq = upstream->finished_dnsreqs;
|
||||
upstream->finished_dnsreqs = dnsreq->finished_next;
|
||||
_getdns_context_cancel_request(dnsreq);
|
||||
if (!dnsreq->internal_cb) { /* Not part of chain */
|
||||
debug_req("Destroy ", *dnsreq->netreqs);
|
||||
_getdns_context_cancel_request(dnsreq);
|
||||
}
|
||||
}
|
||||
if (upstream->tls_session != NULL)
|
||||
SSL_SESSION_free(upstream->tls_session);
|
||||
|
||||
if (upstream->tls_obj != NULL) {
|
||||
if (upstream->tls_session != NULL)
|
||||
SSL_SESSION_free(upstream->tls_session);
|
||||
SSL_shutdown(upstream->tls_obj);
|
||||
SSL_free(upstream->tls_obj);
|
||||
}
|
||||
|
@ -1434,7 +1436,7 @@ getdns_context_create_with_extended_memory_functions(
|
|||
result->edns_version = 0;
|
||||
result->edns_do_bit = 0;
|
||||
result->edns_client_subnet_private = 0;
|
||||
result->tls_query_padding_blocksize = 1; /* default is to not try to pad */
|
||||
result->tls_query_padding_blocksize = 1; /* default is to pad queries sensibly */
|
||||
result->tls_ctx = NULL;
|
||||
|
||||
result->extension = &result->default_eventloop.loop;
|
||||
|
@ -1796,9 +1798,9 @@ rebuild_ub_ctx(struct getdns_context* context) {
|
|||
"target-fetch-policy:", "0 0 0 0 0");
|
||||
#endif
|
||||
set_ub_dnssec_allowed_skew(context,
|
||||
context->dnssec_allowed_skew);
|
||||
set_ub_edns_maximum_udp_payload_size(context,
|
||||
context->edns_maximum_udp_payload_size);
|
||||
context->dnssec_allowed_skew);
|
||||
set_ub_number_opt(context, "edns-buffer-size:",
|
||||
context->edns_maximum_udp_payload_size);
|
||||
set_ub_dns_transport(context);
|
||||
|
||||
context->ub_event.userarg = context;
|
||||
|
@ -2208,18 +2210,38 @@ getdns_context_set_timeout(struct getdns_context *context, uint64_t timeout)
|
|||
*
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_set_idle_timeout(struct getdns_context *context, uint64_t timeout)
|
||||
getdns_context_set_idle_timeout(getdns_context *context, uint64_t timeout)
|
||||
{
|
||||
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
||||
size_t i;
|
||||
|
||||
/* Shuold we enforce maximum based on edns-tcp-keepalive spec? */
|
||||
/* 0 should be allowed as that is the default.*/
|
||||
if (!context)
|
||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
|
||||
context->idle_timeout = timeout;
|
||||
/* Shuold we enforce maximum based on edns-tcp-keepalive spec? */
|
||||
/* 0 should be allowed as that is the default.*/
|
||||
|
||||
dispatch_updated(context, GETDNS_CONTEXT_CODE_IDLE_TIMEOUT);
|
||||
context->idle_timeout = timeout;
|
||||
|
||||
return GETDNS_RETURN_GOOD;
|
||||
dispatch_updated(context, GETDNS_CONTEXT_CODE_IDLE_TIMEOUT);
|
||||
|
||||
if (timeout)
|
||||
return GETDNS_RETURN_GOOD;
|
||||
|
||||
/* If timeout == 0, call scheduled idle timeout events */
|
||||
for (i = 0; i < context->upstreams->count; i++) {
|
||||
getdns_upstream *upstream =
|
||||
&context->upstreams->upstreams[i];
|
||||
|
||||
if (!upstream->event.ev ||
|
||||
!upstream->event.timeout_cb ||
|
||||
upstream->event.read_cb ||
|
||||
upstream->event.write_cb)
|
||||
continue;
|
||||
|
||||
GETDNS_CLEAR_EVENT(upstream->loop, &upstream->event);
|
||||
upstream->event.timeout_cb(upstream->event.userarg);
|
||||
}
|
||||
return GETDNS_RETURN_GOOD;
|
||||
} /* getdns_context_set_timeout */
|
||||
|
||||
|
||||
|
@ -2831,15 +2853,26 @@ error:
|
|||
} /* getdns_context_set_upstream_recursive_servers */
|
||||
|
||||
|
||||
/*
|
||||
* getdns_context_unset_edns_maximum_udp_payload_size
|
||||
*
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_unset_edns_maximum_udp_payload_size(getdns_context *context)
|
||||
{
|
||||
if (!context)
|
||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
|
||||
#ifdef HAVE_LIBUNBOUND
|
||||
static void
|
||||
set_ub_edns_maximum_udp_payload_size(struct getdns_context* context,
|
||||
int value) {
|
||||
/* edns-buffer-size */
|
||||
if (value >= 512 && value <= 65535)
|
||||
set_ub_number_opt(context, "edns-buffer-size:", (uint16_t)value);
|
||||
}
|
||||
set_ub_number_opt(context, "edns-buffer-size:", 4096);
|
||||
#endif
|
||||
if (context->edns_maximum_udp_payload_size != -1) {
|
||||
context->edns_maximum_udp_payload_size = -1;
|
||||
dispatch_updated(context,
|
||||
GETDNS_CONTEXT_CODE_EDNS_MAXIMUM_UDP_PAYLOAD_SIZE);
|
||||
}
|
||||
return GETDNS_RETURN_GOOD;
|
||||
} /* getdns_context_set_edns_maximum_udp_payload_size */
|
||||
|
||||
/*
|
||||
* getdns_context_set_edns_maximum_udp_payload_size
|
||||
|
@ -2852,12 +2885,8 @@ getdns_context_set_edns_maximum_udp_payload_size(struct getdns_context *context,
|
|||
if (!context)
|
||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
|
||||
/* check for < 512. uint16_t won't let it go above max) */
|
||||
if (value < 512)
|
||||
value = 512;
|
||||
|
||||
#ifdef HAVE_LIBUNBOUND
|
||||
set_ub_edns_maximum_udp_payload_size(context, value);
|
||||
set_ub_number_opt(context, "edns-buffer-size:", value);
|
||||
#endif
|
||||
if (value != context->edns_maximum_udp_payload_size) {
|
||||
context->edns_maximum_udp_payload_size = value;
|
||||
|
@ -3079,13 +3108,17 @@ getdns_cancel_callback(getdns_context *context,
|
|||
|
||||
getdns_context_request_count_changed(context);
|
||||
|
||||
debug_req("CB Cancel ", *dnsreq->netreqs);
|
||||
if (dnsreq->user_callback) {
|
||||
dnsreq->context->processing = 1;
|
||||
dnsreq->user_callback(dnsreq->context, GETDNS_CALLBACK_CANCEL,
|
||||
NULL, dnsreq->user_pointer, dnsreq->trans_id);
|
||||
dnsreq->context->processing = 0;
|
||||
}
|
||||
_getdns_context_cancel_request(dnsreq);
|
||||
if (!dnsreq->internal_cb) { /* Not part of chain */
|
||||
debug_req("Destroy ", *dnsreq->netreqs);
|
||||
_getdns_context_cancel_request(dnsreq);
|
||||
}
|
||||
return GETDNS_RETURN_GOOD;
|
||||
} /* getdns_cancel_callback */
|
||||
|
||||
|
@ -3094,6 +3127,7 @@ _getdns_context_request_timed_out(getdns_dns_req *dnsreq)
|
|||
{
|
||||
DEBUG_SCHED("%s(%p)\n", __FUNC__, (void *)dnsreq);
|
||||
|
||||
debug_req("CB Timeout ", *dnsreq->netreqs);
|
||||
if (dnsreq->user_callback) {
|
||||
dnsreq->context->processing = 1;
|
||||
dnsreq->user_callback(dnsreq->context, GETDNS_CALLBACK_TIMEOUT,
|
||||
|
@ -4150,7 +4184,8 @@ getdns_context_get_edns_maximum_udp_payload_size(getdns_context *context,
|
|||
uint16_t* value) {
|
||||
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
||||
RETURN_IF_NULL(value, GETDNS_RETURN_INVALID_PARAMETER);
|
||||
*value = context->edns_maximum_udp_payload_size;
|
||||
*value = context->edns_maximum_udp_payload_size == -1 ? 0
|
||||
: context->edns_maximum_udp_payload_size;
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
|
|
29
src/debug.h
29
src/debug.h
|
@ -36,7 +36,6 @@
|
|||
#define DEBUG_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#define STUB_DEBUG_ENTRY "=> ENTRY: "
|
||||
#define STUB_DEBUG_SETUP "--- SETUP: "
|
||||
#define STUB_DEBUG_SETUP_TLS "--- SETUP(TLS): "
|
||||
|
@ -91,6 +90,31 @@
|
|||
|
||||
#define DEBUG_OFF(...) do {} while (0)
|
||||
|
||||
#if defined(REQ_DEBUG) && REQ_DEBUG
|
||||
#include <time.h>
|
||||
#define DEBUG_REQ(...) DEBUG_ON(__VA_ARGS__)
|
||||
#include "gldns/wire2str.h"
|
||||
#include "rr-dict.h"
|
||||
#include "types-internal.h"
|
||||
static inline void debug_req(const char *msg, getdns_network_req *netreq)
|
||||
{
|
||||
char str[1024];
|
||||
struct timeval tv;
|
||||
uint64_t t;
|
||||
|
||||
(void) gettimeofday(&tv, NULL);
|
||||
t = tv.tv_sec * 1000 + tv.tv_usec / 1000;
|
||||
t = t >= netreq->owner->expires ? 0 : netreq->owner->expires - t;
|
||||
(void) gldns_wire2str_dname_buf(netreq->owner->name,
|
||||
netreq->owner->name_len, str, sizeof(str));
|
||||
DEBUG_REQ("NETREQ %s %4"PRIu64" %s %s\n", msg, t,
|
||||
str, _getdns_rr_type_name(netreq->request_type));
|
||||
}
|
||||
#else
|
||||
#define DEBUG_REQ(...) DEBUG_OFF(__VA_ARGS__)
|
||||
#define debug_req(...) DEBUG_OFF(__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#if defined(SCHED_DEBUG) && SCHED_DEBUG
|
||||
#include <time.h>
|
||||
#define DEBUG_SCHED(...) DEBUG_ON(__VA_ARGS__)
|
||||
|
@ -139,7 +163,8 @@
|
|||
#define DEBUG_MDNS(...) DEBUG_OFF(__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#if (defined(SCHED_DEBUG) && SCHED_DEBUG) || \
|
||||
#if (defined(REQ_DEBUG) && REQ_DEBUG) || \
|
||||
(defined(SCHED_DEBUG) && SCHED_DEBUG) || \
|
||||
(defined(STUB_DEBUG) && STUB_DEBUG) || \
|
||||
(defined(DAEMON_DEBUG) && DAEMON_DEBUG) || \
|
||||
(defined(SEC_DEBUG) && SEC_DEBUG) || \
|
||||
|
|
37
src/dnssec.c
37
src/dnssec.c
|
@ -3113,6 +3113,43 @@ static void check_chain_complete(chain_head *chain)
|
|||
_getdns_call_user_callback(dnsreq, response_dict);
|
||||
}
|
||||
|
||||
void _getdns_validation_chain_timeout(getdns_dns_req *dnsreq)
|
||||
{
|
||||
chain_head *head = dnsreq->chain, *next;
|
||||
chain_node *node;
|
||||
size_t node_count;
|
||||
|
||||
while (head) {
|
||||
next = head->next;
|
||||
|
||||
for ( node_count = head->node_count, node = head->parent
|
||||
; node_count
|
||||
; node_count--, node = node->parent ) {
|
||||
|
||||
if (!_getdns_netreq_finished(node->dnskey_req)) {
|
||||
_getdns_context_cancel_request(
|
||||
node->dnskey_req->owner);
|
||||
node->dnskey_req = NULL;
|
||||
}
|
||||
|
||||
if (!_getdns_netreq_finished(node->ds_req)) {
|
||||
_getdns_context_cancel_request(
|
||||
node->ds_req->owner);
|
||||
node->ds_req = NULL;
|
||||
}
|
||||
|
||||
if (!_getdns_netreq_finished(node->soa_req)) {
|
||||
_getdns_context_cancel_request(
|
||||
node->soa_req->owner);
|
||||
node->soa_req = NULL;
|
||||
}
|
||||
}
|
||||
head = next;
|
||||
}
|
||||
dnsreq->request_timed_out = 1;
|
||||
check_chain_complete(dnsreq->chain);
|
||||
}
|
||||
|
||||
void _getdns_cancel_validation_chain(getdns_dns_req *dnsreq)
|
||||
{
|
||||
chain_head *head = dnsreq->chain, *next;
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
/* Do some additional requests to fetch the complete validation chain */
|
||||
void _getdns_get_validation_chain(getdns_dns_req *dns_req);
|
||||
void _getdns_cancel_validation_chain(getdns_dns_req *dns_req);
|
||||
void _getdns_validation_chain_timeout(getdns_dns_req *dns_req);
|
||||
|
||||
uint16_t _getdns_parse_ta_file(time_t *ta_mtime, gldns_buffer *gbuf);
|
||||
|
||||
|
|
|
@ -30,8 +30,10 @@
|
|||
#ifdef HAVE_SYS_POLL_H
|
||||
#include <sys/poll.h>
|
||||
#else
|
||||
#ifndef USE_WINSOCK
|
||||
#include <poll.h>
|
||||
#endif
|
||||
#endif
|
||||
#ifdef HAVE_SYS_RESOURCE_H
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
|
@ -402,6 +404,10 @@ poll_eventloop_run_once(getdns_eventloop *loop, int blocking)
|
|||
, poll_timeout
|
||||
);
|
||||
#ifdef USE_WINSOCK
|
||||
if (poll_loop->fd_events_free == 0)
|
||||
{
|
||||
Sleep(poll_timeout);
|
||||
} else
|
||||
if (WSAPoll(poll_loop->pfds, poll_loop->fd_events_free, poll_timeout) < 0) {
|
||||
#else
|
||||
if (poll(poll_loop->pfds, poll_loop->fd_events_free, poll_timeout) < 0) {
|
||||
|
|
|
@ -234,6 +234,16 @@ select_eventloop_run_once(getdns_eventloop *loop, int blocking)
|
|||
tv.tv_sec = (long)((timeout - now) / 1000000);
|
||||
tv.tv_usec = (long)((timeout - now) % 1000000);
|
||||
}
|
||||
#ifdef USE_WINSOCK
|
||||
if (max_fd == -1)
|
||||
{
|
||||
if (timeout != TIMEOUT_FOREVER)
|
||||
{
|
||||
uint32_t timeout_ms = (tv.tv_usec / 1000) + (tv.tv_sec * 1000);
|
||||
Sleep(timeout_ms);
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
if (select(max_fd + 1, &readfds, &writefds, NULL,
|
||||
(timeout == TIMEOUT_FOREVER ? NULL : &tv)) < 0) {
|
||||
perror("select() failed");
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
#include "stub.h"
|
||||
#include "dict.h"
|
||||
#include "mdns.h"
|
||||
#include "debug.h"
|
||||
|
||||
void _getdns_call_user_callback(getdns_dns_req *dnsreq, getdns_dict *response)
|
||||
{
|
||||
|
@ -61,8 +62,9 @@ void _getdns_call_user_callback(getdns_dns_req *dnsreq, getdns_dict *response)
|
|||
if (dnsreq->user_callback) {
|
||||
dnsreq->context->processing = 1;
|
||||
dnsreq->user_callback(dnsreq->context,
|
||||
(response ? GETDNS_CALLBACK_COMPLETE
|
||||
: GETDNS_CALLBACK_ERROR),
|
||||
( ! response ? GETDNS_CALLBACK_ERROR
|
||||
: dnsreq->request_timed_out ? GETDNS_CALLBACK_TIMEOUT
|
||||
: GETDNS_CALLBACK_COMPLETE ),
|
||||
response, dnsreq->user_pointer, dnsreq->trans_id);
|
||||
dnsreq->context->processing = 0;
|
||||
}
|
||||
|
@ -186,6 +188,14 @@ _getdns_check_dns_req_complete(getdns_dns_req *dns_req)
|
|||
return;
|
||||
}
|
||||
}
|
||||
#if defined(REQ_DEBUG) && REQ_DEBUG
|
||||
if (dns_req->internal_cb)
|
||||
debug_req("CB Internal", *dns_req->netreqs);
|
||||
else if (results_found)
|
||||
debug_req("CB Complete", *dns_req->netreqs);
|
||||
else
|
||||
debug_req("CB Error ", *dns_req->netreqs);
|
||||
#endif
|
||||
if (dns_req->internal_cb) {
|
||||
_getdns_context_clear_outbound_request(dns_req);
|
||||
dns_req->internal_cb(dns_req);
|
||||
|
@ -206,9 +216,20 @@ _getdns_check_dns_req_complete(getdns_dns_req *dns_req)
|
|||
dns_req->dnssec_return_all_statuses
|
||||
))
|
||||
#endif
|
||||
))
|
||||
)) {
|
||||
/* Reschedule timeout for this DNS request
|
||||
*/
|
||||
if (dns_req->timeout.timeout_cb && dns_req->timeout.ev)
|
||||
GETDNS_CLEAR_EVENT(dns_req->loop, &dns_req->timeout);
|
||||
|
||||
GETDNS_SCHEDULE_EVENT(dns_req->loop, -1,
|
||||
_getdns_ms_until_expiry2(dns_req->expires, &now_ms),
|
||||
getdns_eventloop_event_init(&dns_req->timeout, dns_req,
|
||||
NULL, NULL, (getdns_eventloop_callback)
|
||||
_getdns_validation_chain_timeout));
|
||||
|
||||
_getdns_get_validation_chain(dns_req);
|
||||
else
|
||||
} else
|
||||
_getdns_call_user_callback(
|
||||
dns_req, _getdns_create_getdns_response(dns_req));
|
||||
}
|
||||
|
@ -373,6 +394,8 @@ _getdns_submit_netreq(getdns_network_req *netreq, uint64_t *now_ms)
|
|||
}
|
||||
_getdns_netreq_change_state(netreq, NET_REQ_IN_FLIGHT);
|
||||
|
||||
debug_req("Submitting ", netreq);
|
||||
|
||||
#ifdef STUB_NATIVE_DNSSEC
|
||||
# ifdef DNSSEC_ROADBLOCK_AVOIDANCE
|
||||
|
||||
|
|
|
@ -275,6 +275,9 @@ getdns_context_set_edns_client_subnet_private(getdns_context *context, uint8_t v
|
|||
|
||||
getdns_return_t
|
||||
getdns_context_set_tls_query_padding_blocksize(getdns_context *context, uint16_t value);
|
||||
|
||||
getdns_return_t
|
||||
getdns_context_unset_edns_maximum_udp_payload_size(getdns_context *context);
|
||||
/** @}
|
||||
*/
|
||||
|
||||
|
|
|
@ -69,6 +69,7 @@ getdns_context_set_tls_query_padding_blocksize
|
|||
getdns_context_set_update_callback
|
||||
getdns_context_set_upstream_recursive_servers
|
||||
getdns_context_set_use_threads
|
||||
getdns_context_unset_edns_maximum_udp_payload_size
|
||||
getdns_convert_alabel_to_ulabel
|
||||
getdns_convert_dns_name_to_fqdn
|
||||
getdns_convert_fqdn_to_dns_name
|
||||
|
|
|
@ -110,6 +110,9 @@ network_req_cleanup(getdns_network_req *net_req)
|
|||
if (net_req->response && (net_req->response < net_req->wire_data ||
|
||||
net_req->response > net_req->wire_data+ net_req->wire_data_sz))
|
||||
GETDNS_FREE(net_req->owner->my_mf, net_req->response);
|
||||
if (net_req->debug_tls_peer_cert.size &&
|
||||
net_req->debug_tls_peer_cert.data)
|
||||
OPENSSL_free(net_req->debug_tls_peer_cert.data);
|
||||
}
|
||||
|
||||
static uint8_t *
|
||||
|
@ -182,6 +185,8 @@ network_req_init(getdns_network_req *net_req, getdns_dns_req *owner,
|
|||
net_req->write_queue_tail = NULL;
|
||||
/* Some fields to record info for return_call_reporting */
|
||||
net_req->debug_tls_auth_status = GETDNS_AUTH_NONE;
|
||||
net_req->debug_tls_peer_cert.size = 0;
|
||||
net_req->debug_tls_peer_cert.data = NULL;
|
||||
net_req->debug_udp = 0;
|
||||
|
||||
/* Scheduling, touch only via _getdns_netreq_change_state!
|
||||
|
@ -939,6 +944,7 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop,
|
|||
result->freed = NULL;
|
||||
result->validating = 0;
|
||||
result->is_dns_request = 1;
|
||||
result->request_timed_out = 0;
|
||||
result->chain = NULL;
|
||||
|
||||
network_req_init(result->netreqs[0], result,
|
||||
|
|
69
src/stub.c
69
src/stub.c
|
@ -32,11 +32,21 @@
|
|||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
/* Intercept and do not sent out COM DS queries with TLS
|
||||
* For debugging purposes only. Never commit with this turned on.
|
||||
*/
|
||||
#define INTERCEPT_COM_DS 0
|
||||
|
||||
#ifdef USE_POLL_DEFAULT_EVENTLOOP
|
||||
# ifdef HAVE_SYS_POLL_H
|
||||
# include <sys/poll.h>
|
||||
# else
|
||||
#ifdef USE_WINSOCK
|
||||
#define poll(fdarray, nbsockets, timer) WSAPoll(fdarray, nbsockets, timer)
|
||||
#else
|
||||
# include <poll.h>
|
||||
#endif
|
||||
# endif
|
||||
#endif
|
||||
#include "debug.h"
|
||||
|
@ -1280,12 +1290,15 @@ stub_tls_write(getdns_upstream *upstream, getdns_tcp_state *tcp,
|
|||
return STUB_OUT_OF_OPTIONS;
|
||||
netreq->keepalive_sent = 1;
|
||||
}
|
||||
if (netreq->owner->tls_query_padding_blocksize > 1) {
|
||||
if (netreq->owner->tls_query_padding_blocksize > 0) {
|
||||
uint16_t blksz = netreq->owner->tls_query_padding_blocksize;
|
||||
if (blksz == 1) /* use a sensible default policy */
|
||||
blksz = 128;
|
||||
pkt_len = netreq->response - netreq->query;
|
||||
pkt_len += 4; /* this accounts for the OPTION-CODE and OPTION-LENGTH of the padding */
|
||||
padding_sz = pkt_len % netreq->owner->tls_query_padding_blocksize;
|
||||
padding_sz = pkt_len % blksz;
|
||||
if (padding_sz)
|
||||
padding_sz = netreq->owner->tls_query_padding_blocksize - padding_sz;
|
||||
padding_sz = blksz - padding_sz;
|
||||
if (_getdns_network_req_add_upstream_option(netreq,
|
||||
EDNS_PADDING_OPCODE,
|
||||
padding_sz, NULL))
|
||||
|
@ -1299,10 +1312,39 @@ stub_tls_write(getdns_upstream *upstream, getdns_tcp_state *tcp,
|
|||
|
||||
/* TODO[TLS]: Handle error cases, partial writes, renegotiation etc. */
|
||||
ERR_clear_error();
|
||||
written = SSL_write(tls_obj, netreq->query - 2, pkt_len + 2);
|
||||
if (written <= 0)
|
||||
return STUB_TCP_ERROR;
|
||||
#if INTERCEPT_COM_DS
|
||||
/* Intercept and do not sent out COM DS queries. For debugging
|
||||
* purposes only. Never commit with this turned on.
|
||||
*/
|
||||
if (netreq->request_type == GETDNS_RRTYPE_DS &&
|
||||
netreq->owner->name_len == 5 &&
|
||||
netreq->owner->name[0] == 3 &&
|
||||
(netreq->owner->name[1] & 0xDF) == 'C' &&
|
||||
(netreq->owner->name[2] & 0xDF) == 'O' &&
|
||||
(netreq->owner->name[3] & 0xDF) == 'M' &&
|
||||
netreq->owner->name[4] == 0) {
|
||||
|
||||
debug_req("Intercepting", netreq);
|
||||
written = pkt_len + 2;
|
||||
} else
|
||||
#endif
|
||||
written = SSL_write(tls_obj, netreq->query - 2, pkt_len + 2);
|
||||
if (written <= 0) {
|
||||
/* SSL_write will not do partial writes, because
|
||||
* SSL_MODE_ENABLE_PARTIAL_WRITE is not default,
|
||||
* but the write could fail because of renegotiation.
|
||||
* In that case SSL_get_error() will return
|
||||
* SSL_ERROR_WANT_READ or, SSL_ERROR_WANT_WRITE.
|
||||
* Return for retry in such cases.
|
||||
*/
|
||||
switch (SSL_get_error(tls_obj, written)) {
|
||||
case SSL_ERROR_WANT_READ:
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
return STUB_TCP_AGAIN;
|
||||
default:
|
||||
return STUB_TCP_ERROR;
|
||||
}
|
||||
}
|
||||
/* We were able to write everything! Start reading. */
|
||||
return (int) query_id;
|
||||
|
||||
|
@ -1618,6 +1660,7 @@ upstream_write_cb(void *userarg)
|
|||
getdns_upstream *upstream = (getdns_upstream *)userarg;
|
||||
getdns_network_req *netreq = upstream->write_queue;
|
||||
int q;
|
||||
X509 *cert;
|
||||
|
||||
if (!netreq) {
|
||||
GETDNS_CLEAR_EVENT(upstream->loop, &upstream->event);
|
||||
|
@ -1672,6 +1715,14 @@ upstream_write_cb(void *userarg)
|
|||
return;
|
||||
|
||||
default:
|
||||
if (netreq->owner->return_call_reporting &&
|
||||
netreq->upstream->tls_obj &&
|
||||
netreq->debug_tls_peer_cert.data == NULL &&
|
||||
(cert = SSL_get_peer_certificate(netreq->upstream->tls_obj))) {
|
||||
netreq->debug_tls_peer_cert.size = i2d_X509(
|
||||
cert, &netreq->debug_tls_peer_cert.data);
|
||||
X509_free(cert);
|
||||
}
|
||||
/* Need this because auth status is reset on connection close */
|
||||
netreq->debug_tls_auth_status = netreq->upstream->tls_auth_state;
|
||||
upstream->queries_sent++;
|
||||
|
@ -2063,6 +2114,12 @@ upstream_reschedule_events(getdns_upstream *upstream, uint64_t idle_timeout) {
|
|||
else {
|
||||
DEBUG_STUB("%s %-35s: FD: %d Connection idle - timeout is %d\n",
|
||||
STUB_DEBUG_SCHEDULE, __FUNC__, upstream->fd, (int)idle_timeout);
|
||||
/* TODO: Schedule a read also anyway,
|
||||
* to digest timed out answers.
|
||||
* Dont forget to schedule with upstream->fd then!
|
||||
*
|
||||
* upstream->event.read_cb = upstream_read_cb;
|
||||
*/
|
||||
upstream->event.timeout_cb = upstream_idle_timeout_cb;
|
||||
if (upstream->conn_state != GETDNS_CONN_OPEN)
|
||||
idle_timeout = 0;
|
||||
|
|
16
src/sync.c
16
src/sync.c
|
@ -123,18 +123,22 @@ getdns_sync_data_cleanup(getdns_sync_data *data)
|
|||
* synchronous request.
|
||||
*/
|
||||
GETDNS_CLEAR_EVENT(upstream->loop, &upstream->event);
|
||||
(*upstream->event.timeout_cb)(upstream->event.userarg);
|
||||
|
||||
/* This should have cleared the event */
|
||||
assert(!upstream->event.read_cb &&
|
||||
!upstream->event.write_cb &&
|
||||
!upstream->event.timeout_cb);
|
||||
if (upstream->conn_state != GETDNS_CONN_OPEN ||
|
||||
upstream->keepalive_timeout == 0)
|
||||
(*upstream->event.timeout_cb)(upstream->event.userarg);
|
||||
}
|
||||
upstream->loop = data->context->extension;
|
||||
upstream->is_sync_loop = 0;
|
||||
if (upstream->event.read_cb || upstream->event.write_cb)
|
||||
GETDNS_SCHEDULE_EVENT(upstream->loop, upstream->fd,
|
||||
TIMEOUT_FOREVER, &upstream->event);
|
||||
|
||||
else if (upstream->event.timeout_cb &&
|
||||
upstream->conn_state == GETDNS_CONN_OPEN &&
|
||||
upstream->keepalive_timeout != 0) {
|
||||
GETDNS_SCHEDULE_EVENT(upstream->loop, upstream->fd,
|
||||
upstream->keepalive_timeout, &upstream->event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,10 +30,14 @@
|
|||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include <unistd.h>
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
|
||||
#endif
|
||||
#include <check.h>
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
#include "getdns/getdns.h"
|
||||
#include "check_getdns_common.h"
|
||||
#include "check_getdns_address.h"
|
||||
|
|
|
@ -29,10 +29,14 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
|
||||
#endif
|
||||
#include <check.h>
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
#include "getdns/getdns.h"
|
||||
#include "config.h"
|
||||
#include "check_getdns_common.h"
|
||||
|
|
|
@ -27,10 +27,14 @@
|
|||
#ifndef _check_getdns_context_set_timeout_h_
|
||||
#define _check_getdns_context_set_timeout_h_
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
|
||||
#endif
|
||||
#include <check.h>
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
Suite *
|
||||
getdns_context_set_timeout_suite (void);
|
||||
|
|
|
@ -41,10 +41,14 @@
|
|||
#else
|
||||
#include <ev.h>
|
||||
#endif
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
|
||||
#endif
|
||||
#include <check.h>
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
#include "check_getdns_common.h"
|
||||
|
||||
void run_event_loop_impl(struct getdns_context* context, void* eventloop) {
|
||||
|
|
|
@ -37,10 +37,14 @@
|
|||
|
||||
#include "getdns/getdns_ext_libevent.h"
|
||||
#include "check_getdns_libevent.h"
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
|
||||
#endif
|
||||
#include <check.h>
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
#include "check_getdns_common.h"
|
||||
|
||||
void run_event_loop_impl(struct getdns_context* context, void* eventloop) {
|
||||
|
|
|
@ -37,10 +37,14 @@
|
|||
|
||||
#include "getdns/getdns_ext_libuv.h"
|
||||
#include <uv.h>
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
|
||||
#endif
|
||||
#include <check.h>
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
#include "check_getdns_common.h"
|
||||
|
||||
void run_event_loop_impl(struct getdns_context* context, void* eventloop) {
|
||||
|
|
|
@ -27,10 +27,14 @@
|
|||
#ifndef _check_getdns_transport_h_
|
||||
#define _check_getdns_transport_h_
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
|
||||
#endif
|
||||
#include <check.h>
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
Suite *
|
||||
getdns_transport_suite (void);
|
||||
|
|
|
@ -33,6 +33,19 @@ rm -f report.txt
|
|||
echo ""
|
||||
fi
|
||||
) >> report.txt
|
||||
(
|
||||
cd ${SRCROOT}/src
|
||||
if [ `grep '^#define[ ]*INTERCEPT_COM_DS[ ]*1' stub.c | wc -l` -gt 0 ]
|
||||
then
|
||||
echo "*** "
|
||||
echo "*** The repo contained the COM DS queries interception"
|
||||
echo "*** with TLS transports turned on, this should be off"
|
||||
echo "*** "
|
||||
grep -n '^#define[ ]INTERCEPT_COM_DS[ ]*1' stub.c
|
||||
echo ""
|
||||
fi
|
||||
) >> report.txt
|
||||
|
||||
|
||||
if [ -s report.txt ]
|
||||
then
|
||||
|
|
|
@ -6,7 +6,7 @@ Maintainer: Willem Toorop
|
|||
Category:
|
||||
Component:
|
||||
CmdDepends: valgrind
|
||||
Depends: 110-link.tpkg
|
||||
Depends: 210-stub-only-link.tpkg
|
||||
Help:
|
||||
Pre:
|
||||
Post:
|
||||
|
|
|
@ -54,7 +54,7 @@ static const char *default_stubby_config =
|
|||
", dns_transport_list: [ GETDNS_TRANSPORT_TLS, GETDNS_TRANSPORT_UDP, GETDNS_TRANSPORT_TCP ]"
|
||||
", idle_timeout: 10000"
|
||||
", listen_addresses: [ 127.0.0.1@53, 0::1@53 ]"
|
||||
", tls_query_padding_blocksize: 256"
|
||||
", tls_query_padding_blocksize: 1"
|
||||
", edns_client_subnet_private : 1"
|
||||
"}";
|
||||
static int clear_listen_list_on_arg = 0;
|
||||
|
@ -243,7 +243,8 @@ print_usage(FILE *out, const char *progname)
|
|||
fprintf(out, "\t-n\tSet TLS authentication mode to NONE (default)\n");
|
||||
fprintf(out, "\t-m\tSet TLS authentication mode to REQUIRED\n");
|
||||
fprintf(out, "\t-p\tPretty print response dict\n");
|
||||
fprintf(out, "\t-P <blocksize>\tPad TLS queries to a multiple of blocksize\n");
|
||||
fprintf(out, "\t-P <blocksize>\tPad TLS queries to a multiple of blocksize\n"
|
||||
"\t\t(special values: 0: no padding, 1: sensible default policy)\n");
|
||||
fprintf(out, "\t-q\tQuiet mode - don't print response\n");
|
||||
fprintf( out, "\t-r\tSet recursing resolution type%s\n"
|
||||
, i_am_stubby ? "(default = stub)" : "");
|
||||
|
@ -271,7 +272,7 @@ print_usage(FILE *out, const char *progname)
|
|||
fprintf(out, "\t-u\tSet transport to UDP with TCP fallback (default)\n");
|
||||
fprintf(out, "\t-U\tSet transport to UDP only\n");
|
||||
fprintf(out, "\t-l <transports>\tSet transport list. List can contain 1 of each of the characters\n");
|
||||
fprintf(out, "\t\t\t U T L S for UDP, TCP or TLS e.g 'UT' or 'LTU' \n");
|
||||
fprintf(out, "\t\t\t U T L for UDP, TCP or TLS e.g 'UT' or 'LTU' \n");
|
||||
fprintf(out, "\t-z <listen address>\n");
|
||||
fprintf(out, "\t\tListen for DNS requests on the given IP address\n");
|
||||
fprintf(out, "\t\t<listen address> is in the same format as upstreams.\n");
|
||||
|
@ -1229,6 +1230,7 @@ void read_line_cb(void *userarg)
|
|||
if (listen_count)
|
||||
(void) getdns_context_set_listen_addresses(
|
||||
context, NULL, NULL, NULL);
|
||||
(void) getdns_context_set_idle_timeout(context, 0);
|
||||
return;
|
||||
}
|
||||
if (query_file)
|
||||
|
|
|
@ -240,6 +240,7 @@ typedef struct getdns_network_req
|
|||
uint64_t debug_start_time;
|
||||
uint64_t debug_end_time;
|
||||
getdns_auth_state_t debug_tls_auth_status;
|
||||
getdns_bindata debug_tls_peer_cert;
|
||||
size_t debug_udp;
|
||||
|
||||
/* When more space is needed for the wire_data response than is
|
||||
|
@ -313,6 +314,7 @@ typedef struct getdns_dns_req {
|
|||
unsigned dnssec_ok_checking_disabled : 1;
|
||||
unsigned is_sync_request : 1;
|
||||
unsigned is_dns_request : 1;
|
||||
unsigned request_timed_out : 1;
|
||||
|
||||
/* The validating and freed variables are used to make sure a single
|
||||
* code path is followed while processing a DNS request, even when
|
||||
|
|
|
@ -904,6 +904,15 @@ _getdns_create_call_reporting_dict(
|
|||
getdns_dict_destroy(netreq_debug);
|
||||
return NULL;
|
||||
}
|
||||
if (getdns_dict_set_bindata(netreq_debug, "tls_peer_cert",
|
||||
&netreq->debug_tls_peer_cert)) {
|
||||
|
||||
getdns_dict_destroy(netreq_debug);
|
||||
return NULL;
|
||||
}
|
||||
netreq->debug_tls_peer_cert.size = 0;
|
||||
OPENSSL_free(netreq->debug_tls_peer_cert.data);
|
||||
netreq->debug_tls_peer_cert.data = NULL;
|
||||
return netreq_debug;
|
||||
}
|
||||
|
||||
|
@ -1254,6 +1263,7 @@ _getdns_create_getdns_response(getdns_dns_req *completed_request)
|
|||
GETDNS_FREE(context->mf, srvs.rrs);
|
||||
}
|
||||
if (getdns_dict_set_int(result, GETDNS_STR_KEY_STATUS,
|
||||
completed_request->request_timed_out ||
|
||||
nreplies == 0 ? GETDNS_RESPSTATUS_ALL_TIMEOUT :
|
||||
completed_request->dnssec_return_only_secure && nsecure == 0 && ninsecure > 0
|
||||
? GETDNS_RESPSTATUS_NO_SECURE_ANSWERS :
|
||||
|
|
Loading…
Reference in New Issue