mirror of https://github.com/getdnsapi/getdns.git
Merge branch 'features/native-stub-dnssec' into develop
Conflicts: configure.ac src/stub.c
This commit is contained in:
commit
f066d5ef73
|
@ -1,6 +1,6 @@
|
|||
# generated automatically by aclocal 1.15 -*- Autoconf -*-
|
||||
# generated automatically by aclocal 1.14.1 -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1996-2014 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1996-2013 Free Software Foundation, Inc.
|
||||
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
|
|
|
@ -760,7 +760,7 @@ with_sysroot
|
|||
enable_libtool_lock
|
||||
enable_rpath
|
||||
enable_tcp_fastopen
|
||||
enable_broken_native_stub_dnssec
|
||||
enable_native_stub_dnssec
|
||||
with_ssl
|
||||
enable_draft_edns_cookies
|
||||
with_libidn
|
||||
|
@ -1406,9 +1406,8 @@ Optional Features:
|
|||
--disable-libtool-lock avoid locking (might break parallel builds)
|
||||
--disable-rpath disable hardcoded rpath (default=enabled)
|
||||
--enable-tcp-fastopen Enable TCP Fast Open
|
||||
--enable-broken-native-stub-dnssec
|
||||
Enable very experimental and broken native stub
|
||||
DNSSEC support
|
||||
--disable-native-stub-dnssec
|
||||
Disable native stub DNSSEC support
|
||||
--enable-draft-edns-cookies
|
||||
Enable experimental edns cookies
|
||||
|
||||
|
@ -11738,20 +11737,20 @@ _ACEOF
|
|||
;;
|
||||
esac
|
||||
|
||||
# Check whether --enable-broken-native-stub-dnssec was given.
|
||||
if test "${enable_broken_native_stub_dnssec+set}" = set; then :
|
||||
enableval=$enable_broken_native_stub_dnssec;
|
||||
# Check whether --enable-native-stub-dnssec was given.
|
||||
if test "${enable_native_stub_dnssec+set}" = set; then :
|
||||
enableval=$enable_native_stub_dnssec;
|
||||
fi
|
||||
|
||||
case "$enable_broken_native_stub_dnssec" in
|
||||
yes)
|
||||
case "$enable_native_stub_dnssec" in
|
||||
no)
|
||||
;;
|
||||
yes|*)
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define STUB_NATIVE_DNSSEC 1
|
||||
_ACEOF
|
||||
|
||||
;;
|
||||
no|*)
|
||||
;;
|
||||
esac
|
||||
|
||||
|
|
10
configure.ac
10
configure.ac
|
@ -144,12 +144,12 @@ esac
|
|||
# ])
|
||||
# fi
|
||||
|
||||
AC_ARG_ENABLE(broken-native-stub-dnssec, AC_HELP_STRING([--enable-broken-native-stub-dnssec], [Enable very experimental and broken native stub DNSSEC support]))
|
||||
case "$enable_broken_native_stub_dnssec" in
|
||||
yes)
|
||||
AC_DEFINE_UNQUOTED([STUB_NATIVE_DNSSEC], [1], [Define this to enable the very experimental and broken native stub DNSSEC support.])
|
||||
AC_ARG_ENABLE(native-stub-dnssec, AC_HELP_STRING([--disable-native-stub-dnssec], [Disable native stub DNSSEC support]))
|
||||
case "$enable_native_stub_dnssec" in
|
||||
no)
|
||||
;;
|
||||
no|*)
|
||||
yes|*)
|
||||
AC_DEFINE_UNQUOTED([STUB_NATIVE_DNSSEC], [1], [Define this to enable native stub DNSSEC support.])
|
||||
;;
|
||||
esac
|
||||
|
||||
|
|
|
@ -192,8 +192,7 @@
|
|||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* Define this to enable the very experimental and broken native stub DNSSEC
|
||||
support. */
|
||||
/* Define this to enable native stub DNSSEC support. */
|
||||
#undef STUB_NATIVE_DNSSEC
|
||||
|
||||
/* System configuration dir */
|
||||
|
|
106
src/context.c
106
src/context.c
|
@ -43,6 +43,7 @@
|
|||
#include <unbound.h>
|
||||
#include <assert.h>
|
||||
#include <netdb.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "gldns/str2wire.h"
|
||||
|
@ -815,6 +816,7 @@ getdns_context_create_with_extended_memory_functions(
|
|||
getdns_return_t r;
|
||||
struct getdns_context *result = NULL;
|
||||
mf_union mf;
|
||||
gldns_buffer gbuf;
|
||||
|
||||
if (!context || !malloc || !realloc || !free)
|
||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
|
@ -860,7 +862,30 @@ getdns_context_create_with_extended_memory_functions(
|
|||
result->append_name = GETDNS_APPEND_NAME_ALWAYS;
|
||||
result->suffix = NULL;
|
||||
|
||||
result->dnssec_trust_anchors = NULL;
|
||||
gldns_buffer_init_frm_data(&gbuf, result->trust_anchors_spc
|
||||
, sizeof(result->trust_anchors_spc));
|
||||
|
||||
if (!_getdns_parse_ta_file(NULL, &gbuf)) {
|
||||
result->trust_anchors = NULL;
|
||||
result->trust_anchors_len = 0;
|
||||
|
||||
} else if ((result->trust_anchors_len = gldns_buffer_position(&gbuf))
|
||||
> sizeof(result->trust_anchors_spc)) {
|
||||
|
||||
if ((result->trust_anchors = GETDNS_XMALLOC(
|
||||
result->mf, uint8_t, result->trust_anchors_len))) {
|
||||
|
||||
gldns_buffer_init_frm_data(&gbuf
|
||||
, result->trust_anchors
|
||||
, result->trust_anchors_len);
|
||||
if (!_getdns_parse_ta_file(NULL, &gbuf)) {
|
||||
result->trust_anchors = NULL;
|
||||
result->trust_anchors_len = 0;
|
||||
}
|
||||
}
|
||||
} else
|
||||
result->trust_anchors = result->trust_anchors_spc;
|
||||
|
||||
result->upstreams = NULL;
|
||||
|
||||
result->edns_extended_rcode = 0;
|
||||
|
@ -873,7 +898,7 @@ getdns_context_create_with_extended_memory_functions(
|
|||
goto error;
|
||||
|
||||
result->fchg_resolvconf = NULL;
|
||||
result->fchg_hosts = NULL;
|
||||
result->fchg_hosts = NULL;
|
||||
|
||||
if (set_from_os && (r = set_os_defaults(result)))
|
||||
goto error;
|
||||
|
@ -883,12 +908,12 @@ getdns_context_create_with_extended_memory_functions(
|
|||
if ((r = create_default_dns_transports(result)))
|
||||
goto error;
|
||||
result->limit_outstanding_queries = 0;
|
||||
result->has_ta = priv_getdns_parse_ta_file(NULL, NULL);
|
||||
result->return_dnssec_status = GETDNS_EXTENSION_FALSE;
|
||||
|
||||
/* unbound context is initialized here */
|
||||
/* Unbound needs SSL to be init'ed this early when TLS is used. However we
|
||||
* don't know that till later so we will have to do this every time. */
|
||||
|
||||
SSL_library_init();
|
||||
result->unbound_ctx = NULL;
|
||||
if ((r = rebuild_ub_ctx(result)))
|
||||
|
@ -985,7 +1010,10 @@ getdns_context_destroy(struct getdns_context *context)
|
|||
|
||||
getdns_list_destroy(context->dns_root_servers);
|
||||
getdns_list_destroy(context->suffix);
|
||||
getdns_list_destroy(context->dnssec_trust_anchors);
|
||||
|
||||
if (context->trust_anchors &&
|
||||
context->trust_anchors != context->trust_anchors_spc)
|
||||
GETDNS_FREE(context->mf, context->trust_anchors);
|
||||
|
||||
/* destroy the contexts */
|
||||
if (context->unbound_ctx)
|
||||
|
@ -1116,7 +1144,7 @@ rebuild_ub_ctx(struct getdns_context* context) {
|
|||
set_ub_dns_transport(context);
|
||||
|
||||
/* Set default trust anchor */
|
||||
if (context->has_ta) {
|
||||
if (context->trust_anchors) {
|
||||
(void) ub_ctx_add_ta_file(
|
||||
context->unbound_ctx, TRUST_ANCHOR_FILE);
|
||||
}
|
||||
|
@ -1563,23 +1591,26 @@ getdns_context_set_suffix(struct getdns_context *context, struct getdns_list * v
|
|||
*
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_set_dnssec_trust_anchors(struct getdns_context *context,
|
||||
struct getdns_list * value)
|
||||
getdns_context_set_dnssec_trust_anchors(
|
||||
getdns_context *context, getdns_list *value)
|
||||
{
|
||||
struct getdns_list *copy = NULL;
|
||||
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
||||
if (value != NULL) {
|
||||
if (getdns_list_copy(value, ©) != GETDNS_RETURN_GOOD) {
|
||||
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
|
||||
}
|
||||
value = copy;
|
||||
}
|
||||
getdns_list_destroy(context->dnssec_trust_anchors);
|
||||
context->dnssec_trust_anchors = value;
|
||||
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
||||
|
||||
dispatch_updated(context, GETDNS_CONTEXT_CODE_DNSSEC_TRUST_ANCHORS);
|
||||
if (context->trust_anchors &&
|
||||
context->trust_anchors != context->trust_anchors_spc)
|
||||
GETDNS_FREE(context->mf, context->trust_anchors);
|
||||
|
||||
return GETDNS_RETURN_GOOD;
|
||||
if (value) {
|
||||
context->trust_anchors_len = sizeof(context->trust_anchors_spc);
|
||||
context->trust_anchors = _getdns_list2wire(value,
|
||||
context->trust_anchors_spc, &context->trust_anchors_len,
|
||||
&context->mf);
|
||||
} else {
|
||||
context->trust_anchors = NULL;
|
||||
context->trust_anchors_len = 0;
|
||||
}
|
||||
dispatch_updated(context, GETDNS_CONTEXT_CODE_DNSSEC_TRUST_ANCHORS);
|
||||
return GETDNS_RETURN_GOOD;
|
||||
} /* getdns_context_set_dnssec_trust_anchors */
|
||||
|
||||
static void
|
||||
|
@ -2432,8 +2463,6 @@ getdns_context_local_namespace_resolve(
|
|||
{
|
||||
getdns_context *context = dnsreq->context;
|
||||
host_name_addrs *hnas;
|
||||
uint8_t query_name[256];
|
||||
size_t query_name_len = sizeof(query_name);
|
||||
uint8_t lookup[256];
|
||||
getdns_list empty_list = { 0 };
|
||||
getdns_bindata bindata;
|
||||
|
@ -2451,10 +2480,7 @@ getdns_context_local_namespace_resolve(
|
|||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
|
||||
/*Do the lookup*/
|
||||
if (gldns_str2wire_dname_buf(dnsreq->name,query_name,&query_name_len))
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
|
||||
(void)memcpy(lookup, query_name, query_name_len);
|
||||
(void)memcpy(lookup, dnsreq->name, dnsreq->name_len);
|
||||
canonicalize_dname(lookup);
|
||||
|
||||
if (!(hnas = (host_name_addrs *)
|
||||
|
@ -2470,8 +2496,8 @@ getdns_context_local_namespace_resolve(
|
|||
if (!(*response = getdns_dict_create_with_context(context)))
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
|
||||
bindata.size = query_name_len;
|
||||
bindata.data = query_name;
|
||||
bindata.size = dnsreq->name_len;
|
||||
bindata.data = dnsreq->name;
|
||||
if (getdns_dict_set_bindata(*response, "canonical_name", &bindata))
|
||||
goto error;
|
||||
|
||||
|
@ -2673,15 +2699,23 @@ getdns_context_get_suffix(getdns_context *context, getdns_list **value) {
|
|||
}
|
||||
|
||||
getdns_return_t
|
||||
getdns_context_get_dnssec_trust_anchors(getdns_context *context,
|
||||
getdns_list **value) {
|
||||
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
||||
RETURN_IF_NULL(value, GETDNS_RETURN_INVALID_PARAMETER);
|
||||
*value = NULL;
|
||||
if (context->dnssec_trust_anchors) {
|
||||
return getdns_list_copy(context->dnssec_trust_anchors, value);
|
||||
}
|
||||
return GETDNS_RETURN_GOOD;
|
||||
getdns_context_get_dnssec_trust_anchors(
|
||||
getdns_context *context, getdns_list **value)
|
||||
{
|
||||
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
||||
RETURN_IF_NULL(value, GETDNS_RETURN_INVALID_PARAMETER);
|
||||
|
||||
if (context->trust_anchors) {
|
||||
if ((*value = getdns_list_create_with_context(context)))
|
||||
_getdns_wire2list( context->trust_anchors
|
||||
, context->trust_anchors_len
|
||||
, *value);
|
||||
else
|
||||
return GETDNS_RETURN_MEMORY_ERROR;
|
||||
} else
|
||||
*value = NULL;
|
||||
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
getdns_return_t
|
||||
|
|
|
@ -138,7 +138,8 @@ struct getdns_context {
|
|||
struct getdns_list *dns_root_servers;
|
||||
getdns_append_name_t append_name;
|
||||
struct getdns_list *suffix;
|
||||
struct getdns_list *dnssec_trust_anchors;
|
||||
uint8_t *trust_anchors;
|
||||
size_t trust_anchors_len;
|
||||
getdns_upstreams *upstreams;
|
||||
uint16_t limit_outstanding_queries;
|
||||
uint32_t dnssec_allowed_skew;
|
||||
|
@ -168,7 +169,7 @@ struct getdns_context {
|
|||
|
||||
/* A tree to hold local host information*/
|
||||
getdns_rbtree_t local_hosts;
|
||||
int has_ta; /* No DNSSEC without trust anchor */
|
||||
|
||||
int return_dnssec_status;
|
||||
|
||||
/* which resolution type the contexts are configured for
|
||||
|
@ -194,6 +195,8 @@ struct getdns_context {
|
|||
struct filechg *fchg_resolvconf;
|
||||
struct filechg *fchg_hosts;
|
||||
|
||||
uint8_t trust_anchors_spc[1024];
|
||||
|
||||
}; /* getdns_context */
|
||||
|
||||
/** internal functions **/
|
||||
|
|
|
@ -70,6 +70,10 @@ struct getdns_dict
|
|||
struct mem_funcs mf;
|
||||
};
|
||||
|
||||
inline struct getdns_dict *_getdns_dict_create_with_mf(struct mem_funcs *mf)
|
||||
{ return getdns_dict_create_with_extended_memory_functions(
|
||||
mf->mf_arg, mf->mf.ext.malloc, mf->mf.ext.realloc, mf->mf.ext.free); }
|
||||
|
||||
#endif
|
||||
|
||||
/* dict.h */
|
||||
|
|
2566
src/dnssec.c
2566
src/dnssec.c
File diff suppressed because it is too large
Load Diff
|
@ -39,12 +39,14 @@
|
|||
#define DNSSEC_H_
|
||||
|
||||
#include "getdns/getdns.h"
|
||||
#include "config.h"
|
||||
#include "gldns/gbuffer.h"
|
||||
#include "types-internal.h"
|
||||
|
||||
/* Do some additional requests to fetch the complete validation chain */
|
||||
void priv_getdns_get_validation_chain(getdns_dns_req *dns_req);
|
||||
|
||||
int priv_getdns_parse_ta_file(time_t *ta_mtime, getdns_list *ta_rrs);
|
||||
uint16_t _getdns_parse_ta_file(time_t *ta_mtime, gldns_buffer *gbuf);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -38,8 +38,8 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unbound.h>
|
||||
#include <ldns/ldns.h>
|
||||
#include "config.h"
|
||||
#include "gldns/wire2str.h"
|
||||
#include "context.h"
|
||||
#include "types-internal.h"
|
||||
#include "util-internal.h"
|
||||
|
@ -137,6 +137,7 @@ submit_network_request(getdns_network_req *netreq)
|
|||
{
|
||||
getdns_return_t r;
|
||||
getdns_dns_req *dns_req = netreq->owner;
|
||||
char name[1024];
|
||||
|
||||
if (dns_req->context->resolution_type == GETDNS_RESOLUTION_RECURSING
|
||||
/* TODO: Until DNSSEC with the new async stub resolver is finished,
|
||||
|
@ -160,9 +161,11 @@ submit_network_request(getdns_network_req *netreq)
|
|||
dns_req->context->timeout, &dns_req->timeout)))
|
||||
return r;
|
||||
}
|
||||
(void) gldns_wire2str_dname_buf(dns_req->name,
|
||||
dns_req->name_len, name, sizeof(name));
|
||||
|
||||
return ub_resolve_async(dns_req->context->unbound_ctx,
|
||||
dns_req->name, netreq->request_type, netreq->request_class,
|
||||
name, netreq->request_type, netreq->request_class,
|
||||
netreq, ub_resolve_callback, &(netreq->unbound_id)) ?
|
||||
GETDNS_RETURN_GENERIC_ERROR : GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
@ -173,7 +176,7 @@ submit_network_request(getdns_network_req *netreq)
|
|||
static getdns_return_t
|
||||
getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
|
||||
const char *name, uint16_t request_type, getdns_dict *extensions,
|
||||
void *userarg, getdns_transaction_t *transaction_id,
|
||||
void *userarg, getdns_dns_req **dnsreq_p,
|
||||
getdns_callback_t callbackfn, internal_cb_t internal_cb, int usenamespaces)
|
||||
{
|
||||
getdns_return_t r = GETDNS_RETURN_GOOD;
|
||||
|
@ -185,10 +188,10 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
|
|||
if (!context || !name || (!callbackfn && !internal_cb))
|
||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
|
||||
if ((r = validate_dname(name)))
|
||||
if ((r = priv_getdns_validate_dname(name)))
|
||||
return r;
|
||||
|
||||
if (extensions && (r = validate_extensions(extensions)))
|
||||
if (extensions && (r = priv_getdns_validate_extensions(extensions)))
|
||||
return r;
|
||||
|
||||
/* Set up the context assuming we won't use the specified namespaces.
|
||||
|
@ -204,8 +207,8 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
|
|||
req->user_callback = callbackfn;
|
||||
req->internal_cb = internal_cb;
|
||||
|
||||
if (transaction_id)
|
||||
*transaction_id = req->trans_id;
|
||||
if (dnsreq_p)
|
||||
*dnsreq_p = req;
|
||||
|
||||
getdns_context_track_outbound_request(req);
|
||||
|
||||
|
@ -254,12 +257,12 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
|
|||
getdns_return_t
|
||||
priv_getdns_general_loop(getdns_context *context, getdns_eventloop *loop,
|
||||
const char *name, uint16_t request_type, getdns_dict *extensions,
|
||||
void *userarg, getdns_transaction_t *transaction_id,
|
||||
void *userarg, getdns_dns_req **dnsreq_p,
|
||||
getdns_callback_t callback, internal_cb_t internal_cb)
|
||||
{
|
||||
return getdns_general_ns(context, loop,
|
||||
name, request_type, extensions,
|
||||
userarg, transaction_id, callback, internal_cb, 0);
|
||||
userarg, dnsreq_p, callback, internal_cb, 0);
|
||||
|
||||
} /* getdns_general_loop */
|
||||
|
||||
|
@ -271,6 +274,7 @@ priv_getdns_address_loop(getdns_context *context, getdns_eventloop *loop,
|
|||
getdns_dict *my_extensions = extensions;
|
||||
getdns_return_t r;
|
||||
uint32_t value;
|
||||
getdns_dns_req *dnsreq = NULL;
|
||||
|
||||
if (!my_extensions) {
|
||||
if (!(my_extensions=getdns_dict_create_with_context(context)))
|
||||
|
@ -286,7 +290,9 @@ priv_getdns_address_loop(getdns_context *context, getdns_eventloop *loop,
|
|||
|
||||
r = getdns_general_ns(context, loop,
|
||||
name, GETDNS_RRTYPE_AAAA, my_extensions,
|
||||
userarg, transaction_id, callback, NULL, 1);
|
||||
userarg, &dnsreq, callback, NULL, 1);
|
||||
if (dnsreq && transaction_id)
|
||||
*transaction_id = dnsreq->trans_id;
|
||||
|
||||
if (my_extensions != extensions)
|
||||
getdns_dict_destroy(my_extensions);
|
||||
|
@ -304,6 +310,7 @@ priv_getdns_hostname_loop(getdns_context *context, getdns_eventloop *loop,
|
|||
uint16_t req_type;
|
||||
char name[1024];
|
||||
getdns_return_t retval;
|
||||
getdns_dns_req *dnsreq = NULL;
|
||||
|
||||
if ((retval =
|
||||
getdns_dict_get_bindata(address, "address_data",
|
||||
|
@ -377,7 +384,9 @@ priv_getdns_hostname_loop(getdns_context *context, getdns_eventloop *loop,
|
|||
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
}
|
||||
retval = priv_getdns_general_loop(context, loop, name, req_type,
|
||||
extensions, userarg, transaction_id, callback, NULL);
|
||||
extensions, userarg, &dnsreq, callback, NULL);
|
||||
if (dnsreq && transaction_id)
|
||||
*transaction_id = dnsreq->trans_id;
|
||||
return retval;
|
||||
} /* getdns_hostname_loop */
|
||||
|
||||
|
@ -386,8 +395,13 @@ priv_getdns_service_loop(getdns_context *context, getdns_eventloop *loop,
|
|||
const char *name, getdns_dict *extensions, void *userarg,
|
||||
getdns_transaction_t * transaction_id, getdns_callback_t callback)
|
||||
{
|
||||
return getdns_general_ns(context, loop, name, GETDNS_RRTYPE_SRV,
|
||||
extensions, userarg, transaction_id, callback, NULL, 1);
|
||||
getdns_return_t r;
|
||||
getdns_dns_req *dnsreq = NULL;
|
||||
r = getdns_general_ns(context, loop, name, GETDNS_RRTYPE_SRV,
|
||||
extensions, userarg, &dnsreq, callback, NULL, 1);
|
||||
if (dnsreq && transaction_id)
|
||||
*transaction_id = dnsreq->trans_id;
|
||||
return r;
|
||||
} /* getdns_service_loop */
|
||||
|
||||
/**
|
||||
|
@ -399,11 +413,16 @@ getdns_general(getdns_context *context,
|
|||
void *userarg, getdns_transaction_t * transaction_id,
|
||||
getdns_callback_t callback)
|
||||
{
|
||||
if (!context) return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
return priv_getdns_general_loop(context, context->extension,
|
||||
name, request_type, extensions,
|
||||
userarg, transaction_id, callback, NULL);
|
||||
getdns_return_t r;
|
||||
getdns_dns_req *dnsreq = NULL;
|
||||
|
||||
if (!context) return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
r = priv_getdns_general_loop(context, context->extension,
|
||||
name, request_type, extensions,
|
||||
userarg, &dnsreq, callback, NULL);
|
||||
if (dnsreq && transaction_id)
|
||||
*transaction_id = dnsreq->trans_id;
|
||||
return r;
|
||||
} /* getdns_general */
|
||||
|
||||
/*
|
||||
|
|
|
@ -42,13 +42,13 @@
|
|||
|
||||
/* private inner helper used by sync and async */
|
||||
|
||||
void priv_getdns_call_user_callback(getdns_dns_req *, struct getdns_dict *);
|
||||
void priv_getdns_call_user_callback(getdns_dns_req *, getdns_dict *);
|
||||
void priv_getdns_check_dns_req_complete(getdns_dns_req *dns_req);
|
||||
|
||||
getdns_return_t
|
||||
priv_getdns_general_loop(getdns_context *context, getdns_eventloop *loop,
|
||||
const char *name, uint16_t request_type, getdns_dict *extensions,
|
||||
void *userarg, getdns_transaction_t *transaction_id,
|
||||
void *userarg, getdns_dns_req **dnsreq,
|
||||
getdns_callback_t callbackfn, internal_cb_t internal_cb);
|
||||
|
||||
getdns_return_t
|
||||
|
|
|
@ -74,6 +74,10 @@ struct getdns_list
|
|||
struct mem_funcs mf;
|
||||
};
|
||||
|
||||
inline struct getdns_list *_getdns_list_create_with_mf(struct mem_funcs *mf)
|
||||
{ return getdns_list_create_with_extended_memory_functions(
|
||||
mf->mf_arg, mf->mf.ext.malloc, mf->mf.ext.realloc, mf->mf.ext.free); }
|
||||
|
||||
#endif
|
||||
|
||||
/* list.h */
|
||||
|
|
|
@ -40,6 +40,13 @@
|
|||
#include "gldns/str2wire.h"
|
||||
#include "gldns/gbuffer.h"
|
||||
#include "gldns/pkthdr.h"
|
||||
#include "dict.h"
|
||||
|
||||
getdns_dict dnssec_ok_checking_disabled_spc = {
|
||||
{ RBTREE_NULL, 0, (int (*)(const void *, const void *)) strcmp },
|
||||
{ 0 }
|
||||
};
|
||||
getdns_dict *dnssec_ok_checking_disabled = &dnssec_ok_checking_disabled_spc;
|
||||
|
||||
static int
|
||||
is_extension_set(getdns_dict *extensions, const char *extension)
|
||||
|
@ -49,6 +56,8 @@ is_extension_set(getdns_dict *extensions, const char *extension)
|
|||
|
||||
if (! extensions)
|
||||
return 0;
|
||||
else if (extensions == dnssec_ok_checking_disabled)
|
||||
return 0;
|
||||
|
||||
r = getdns_dict_get_int(extensions, extension, &value);
|
||||
return r == GETDNS_RETURN_GOOD && value == GETDNS_EXTENSION_TRUE;
|
||||
|
@ -87,6 +96,8 @@ network_req_init(getdns_network_req *net_req, getdns_dns_req *owner,
|
|||
net_req->state = NET_REQ_NOT_SENT;
|
||||
net_req->owner = owner;
|
||||
|
||||
net_req->dnssec_status = GETDNS_DNSSEC_INDETERMINATE;
|
||||
|
||||
net_req->upstream = NULL;
|
||||
net_req->fd = -1;
|
||||
net_req->transport_count = owner->context->dns_transport_count;
|
||||
|
@ -193,8 +204,6 @@ dns_req_free(getdns_dns_req * req)
|
|||
req->timeout.timeout_cb = NULL;
|
||||
}
|
||||
|
||||
/* free strduped name */
|
||||
GETDNS_FREE(req->my_mf, req->name);
|
||||
GETDNS_FREE(req->my_mf, req);
|
||||
}
|
||||
|
||||
|
@ -210,14 +219,12 @@ dns_req_new(getdns_context *context, getdns_eventloop *loop,
|
|||
= is_extension_set(extensions, "dnssec_return_only_secure");
|
||||
int dnssec_return_validation_chain
|
||||
= is_extension_set(extensions, "dnssec_return_validation_chain");
|
||||
int dnssec_ok_checking_disabled
|
||||
= is_extension_set(extensions, "dnssec_ok_checking_disabled");
|
||||
int edns_cookies
|
||||
= is_extension_set(extensions, "edns_cookies");
|
||||
|
||||
int dnssec_extension_set = dnssec_return_status
|
||||
|| dnssec_return_only_secure || dnssec_return_validation_chain
|
||||
|| dnssec_ok_checking_disabled;;
|
||||
|| (extensions == dnssec_ok_checking_disabled);
|
||||
|
||||
uint32_t edns_do_bit;
|
||||
int edns_maximum_udp_payload_size;
|
||||
|
@ -252,6 +259,9 @@ dns_req_new(getdns_context *context, getdns_eventloop *loop,
|
|||
size_t max_query_sz, max_response_sz, netreq_sz, dnsreq_base_sz;
|
||||
uint8_t *region;
|
||||
|
||||
if (extensions == dnssec_ok_checking_disabled)
|
||||
extensions = NULL;
|
||||
|
||||
have_add_opt_parameters = getdns_dict_get_dict(extensions,
|
||||
"add_opt_parameters", &add_opt_parameters) == GETDNS_RETURN_GOOD;
|
||||
|
||||
|
@ -347,7 +357,12 @@ dns_req_new(getdns_context *context, getdns_eventloop *loop,
|
|||
result->netreqs[1] = NULL;
|
||||
|
||||
result->my_mf = context->mf;
|
||||
result->name = getdns_strdup(&(result->my_mf), name);
|
||||
|
||||
result->name_len = sizeof(result->name);
|
||||
if (gldns_str2wire_dname_buf(name, result->name, &result->name_len)) {
|
||||
GETDNS_FREE(result->my_mf, result);
|
||||
return NULL;
|
||||
}
|
||||
result->context = context;
|
||||
result->loop = loop;
|
||||
result->canceled = 0;
|
||||
|
|
257
src/rr-dict.c
257
src/rr-dict.c
|
@ -255,9 +255,9 @@ static priv_getdns_rdata_def soa_rdata[] = {
|
|||
{ "rname" , GETDNS_RDF_N_C },
|
||||
{ "serial" , GETDNS_RDF_I4 },
|
||||
{ "refresh" , GETDNS_RDF_I4 },
|
||||
{ "refresh" , GETDNS_RDF_I4 },
|
||||
{ "retry" , GETDNS_RDF_I4 },
|
||||
{ "expire" , GETDNS_RDF_I4 }};
|
||||
{ "expire" , GETDNS_RDF_I4 },
|
||||
{ "minimum" , GETDNS_RDF_I4 }};
|
||||
static priv_getdns_rdata_def mg_rdata[] = {
|
||||
{ "mgmname" , GETDNS_RDF_N_C }};
|
||||
static priv_getdns_rdata_def mr_rdata[] = {
|
||||
|
@ -737,192 +737,95 @@ priv_getdns_rr_type_name(int rr_type)
|
|||
return priv_getdns_rr_def_lookup(rr_type)->name;
|
||||
}
|
||||
|
||||
static getdns_return_t priv_getdns_construct_wire_rdata_from_rdata(
|
||||
struct getdns_dict *rdata, uint32_t rr_type,
|
||||
uint8_t **wire, size_t *wire_size)
|
||||
{
|
||||
getdns_return_t r = GETDNS_RETURN_GOOD;
|
||||
const ldns_rr_descriptor *rr_descript;
|
||||
const priv_getdns_rr_def *def;
|
||||
size_t i, size;
|
||||
struct getdns_bindata *bindata;
|
||||
uint32_t value;
|
||||
uint8_t *ptr;
|
||||
|
||||
assert(rdata);
|
||||
assert(wire);
|
||||
assert(wire_size);
|
||||
|
||||
def = priv_getdns_rr_def_lookup(rr_type);
|
||||
rr_descript = ldns_rr_descript(rr_type);
|
||||
|
||||
/* First calculate needed size */
|
||||
size = 0;
|
||||
for (i = 0; !r && i < def->n_rdata_fields; i++) {
|
||||
if (def->rdata[i].type & GETDNS_RDF_BINDATA)
|
||||
if ((r = getdns_dict_get_bindata(rdata,
|
||||
def->rdata[i].name, &bindata)))
|
||||
break;
|
||||
else {
|
||||
size += bindata->size;
|
||||
continue;
|
||||
}
|
||||
else if (!(def->rdata[i].type & GETDNS_RDF_INTEGER)) {
|
||||
r = GETDNS_RETURN_GENERIC_ERROR;
|
||||
break;
|
||||
}
|
||||
switch (ldns_rr_descriptor_field_type(rr_descript, i)) {
|
||||
|
||||
case LDNS_RDF_TYPE_CLASS:
|
||||
case LDNS_RDF_TYPE_ALG :
|
||||
case LDNS_RDF_TYPE_INT8 : size += 1;
|
||||
break;
|
||||
case LDNS_RDF_TYPE_TYPE :
|
||||
case LDNS_RDF_TYPE_CERT_ALG:
|
||||
case LDNS_RDF_TYPE_INT16: size += 2;
|
||||
break;
|
||||
case LDNS_RDF_TYPE_TIME :
|
||||
case LDNS_RDF_TYPE_PERIOD:
|
||||
case LDNS_RDF_TYPE_INT32: size += 4;
|
||||
break;
|
||||
default: r = GETDNS_RETURN_GENERIC_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
*wire_size = size + 2;
|
||||
*wire = ptr = GETDNS_XMALLOC(rdata->mf, uint8_t, size + 2);
|
||||
if (! ptr)
|
||||
return GETDNS_RETURN_MEMORY_ERROR;
|
||||
|
||||
ptr[0] = (uint8_t) (size >> 8) & 0xff;
|
||||
ptr[1] = (uint8_t) size & 0xff;
|
||||
ptr += 2;
|
||||
for (i = 0; !r && i < def->n_rdata_fields; i++) {
|
||||
if (def->rdata[i].type & GETDNS_RDF_BINDATA)
|
||||
if ((r = getdns_dict_get_bindata(rdata,
|
||||
def->rdata[i].name, &bindata)))
|
||||
break;
|
||||
else {
|
||||
(void) memcpy(ptr, bindata->data,
|
||||
bindata->size);
|
||||
ptr += bindata->size;
|
||||
continue;
|
||||
}
|
||||
else if (!(def->rdata[i].type & GETDNS_RDF_INTEGER)) {
|
||||
r = GETDNS_RETURN_GENERIC_ERROR;
|
||||
break;
|
||||
}
|
||||
if ((r = getdns_dict_get_int(
|
||||
rdata, def->rdata[i].name, &value)))
|
||||
break;
|
||||
|
||||
switch (ldns_rr_descriptor_field_type(rr_descript, i)) {
|
||||
|
||||
case LDNS_RDF_TYPE_CLASS:
|
||||
case LDNS_RDF_TYPE_ALG :
|
||||
case LDNS_RDF_TYPE_INT8 : ptr[0] = (uint8_t) value & 0xff;
|
||||
ptr += 1;
|
||||
break;
|
||||
case LDNS_RDF_TYPE_TYPE :
|
||||
case LDNS_RDF_TYPE_CERT_ALG:
|
||||
case LDNS_RDF_TYPE_INT16: ptr[0] = (uint8_t)(value>> 8) & 0xff;
|
||||
ptr[1] = (uint8_t) value & 0xff;
|
||||
ptr += 2;
|
||||
break;
|
||||
case LDNS_RDF_TYPE_TIME :
|
||||
case LDNS_RDF_TYPE_PERIOD:
|
||||
case LDNS_RDF_TYPE_INT32: ptr[0] = (uint8_t)(value>>24) & 0xff;
|
||||
ptr[1] = (uint8_t)(value>>16) & 0xff;
|
||||
ptr[2] = (uint8_t)(value>>8 ) & 0xff;
|
||||
ptr[3] = (uint8_t) value & 0xff;
|
||||
ptr += 4;
|
||||
break;
|
||||
default: r = GETDNS_RETURN_GENERIC_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (r)
|
||||
GETDNS_FREE(rdata->mf, ptr);
|
||||
return r;
|
||||
}
|
||||
|
||||
static getdns_return_t
|
||||
priv_getdns_dict_get_raw_rdata(struct getdns_dict *rdata,
|
||||
uint8_t **wire, size_t *wire_size)
|
||||
{
|
||||
getdns_return_t r;
|
||||
struct getdns_bindata *bindata;
|
||||
|
||||
if ((r = getdns_dict_get_bindata(rdata, "rdata_raw", &bindata)))
|
||||
return r;
|
||||
|
||||
*wire_size = bindata->size + 2;
|
||||
*wire = GETDNS_XMALLOC(rdata->mf, uint8_t, *wire_size);
|
||||
if (! *wire)
|
||||
return GETDNS_RETURN_MEMORY_ERROR;
|
||||
|
||||
(*wire)[0] = (uint8_t) (bindata->size >> 8) & 0xff;
|
||||
(*wire)[1] = (uint8_t) bindata->size & 0xff;
|
||||
|
||||
(void) memcpy(*wire + 2, bindata->data, bindata->size);
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
getdns_return_t
|
||||
priv_getdns_create_rr_from_dict(struct getdns_dict *rr_dict, ldns_rr **rr)
|
||||
priv_getdns_rr_dict2wire(getdns_dict *rr_dict, gldns_buffer *buf)
|
||||
{
|
||||
getdns_return_t r = GETDNS_RETURN_GOOD;
|
||||
struct getdns_bindata *name;
|
||||
struct getdns_bindata *rdata_raw;
|
||||
struct getdns_bindata *bindata;
|
||||
struct getdns_dict *rdata;
|
||||
uint32_t rr_type;
|
||||
ldns_rdf *owner;
|
||||
ldns_status s;
|
||||
size_t pos;
|
||||
uint8_t *wire;
|
||||
size_t wire_size;
|
||||
uint32_t rr_class = GETDNS_RRCLASS_IN;
|
||||
uint32_t rr_ttl = 0;
|
||||
uint32_t value;
|
||||
const priv_getdns_rr_def *rr_def;
|
||||
const priv_getdns_rdata_def *rd_def;
|
||||
int n_rdata_fields;
|
||||
size_t j, rdata_size_mark;
|
||||
|
||||
assert(rr_dict);
|
||||
assert(rr);
|
||||
assert(buf);
|
||||
|
||||
*rr = ldns_rr_new();
|
||||
if (! *rr)
|
||||
return GETDNS_RETURN_MEMORY_ERROR;
|
||||
do {
|
||||
r = getdns_dict_get_bindata(rr_dict, "name", &name);
|
||||
if (r != GETDNS_RETURN_GOOD)
|
||||
break;
|
||||
owner = ldns_rdf_new_frm_data(
|
||||
LDNS_RDF_TYPE_DNAME, name->size, name->data);
|
||||
if (! owner) {
|
||||
r = GETDNS_RETURN_MEMORY_ERROR;
|
||||
if ((r = getdns_dict_get_bindata(rr_dict, "name", &name)))
|
||||
goto error;
|
||||
gldns_buffer_write(buf, name->data, name->size);
|
||||
|
||||
if ((r = getdns_dict_get_int(rr_dict, "type", &rr_type)))
|
||||
goto error;
|
||||
gldns_buffer_write_u16(buf, (uint16_t)rr_type);
|
||||
|
||||
(void) getdns_dict_get_int(rr_dict, "class", &rr_class);
|
||||
gldns_buffer_write_u16(buf, (uint16_t)rr_class);
|
||||
|
||||
(void) getdns_dict_get_int(rr_dict, "ttl", &rr_ttl);
|
||||
gldns_buffer_write_u32(buf, rr_ttl);
|
||||
|
||||
/* Does rdata contain compressed names?
|
||||
* Because rdata_raw is unusable then.
|
||||
*/
|
||||
rr_def = priv_getdns_rr_def_lookup(rr_type);
|
||||
for ( rd_def = rr_def->rdata
|
||||
, n_rdata_fields = rr_def->n_rdata_fields
|
||||
; n_rdata_fields ; n_rdata_fields-- , rd_def++ ) {
|
||||
|
||||
if (rd_def->type & GETDNS_RDF_COMPRESSED)
|
||||
break;
|
||||
}
|
||||
|
||||
if ((r = getdns_dict_get_dict(rr_dict, "rdata", &rdata)))
|
||||
goto error;
|
||||
|
||||
if (n_rdata_fields == 0 && GETDNS_RETURN_GOOD ==
|
||||
(r = getdns_dict_get_bindata(rdata, "rdata_raw", &rdata_raw))) {
|
||||
|
||||
gldns_buffer_write_u16(buf, (uint16_t)rdata_raw->size);
|
||||
gldns_buffer_write(buf, rdata_raw->data, rdata_raw->size);
|
||||
|
||||
} else if (n_rdata_fields || r == GETDNS_RETURN_NO_SUCH_DICT_NAME) {
|
||||
|
||||
rdata_size_mark = gldns_buffer_position(buf);
|
||||
gldns_buffer_skip(buf, 2);
|
||||
|
||||
for ( rd_def = rr_def->rdata
|
||||
, n_rdata_fields = rr_def->n_rdata_fields
|
||||
; n_rdata_fields ; n_rdata_fields-- , rd_def++ ) {
|
||||
|
||||
if (rd_def->type & GETDNS_RDF_BINDATA) {
|
||||
if ((r = getdns_dict_get_bindata(rdata,
|
||||
rd_def->name, &bindata)))
|
||||
break;
|
||||
|
||||
gldns_buffer_write(buf, bindata->data
|
||||
, bindata->size );
|
||||
continue;
|
||||
}
|
||||
if (!(rd_def->type & GETDNS_RDF_INTEGER)) {
|
||||
r = GETDNS_RETURN_GENERIC_ERROR;
|
||||
break;
|
||||
}
|
||||
if ((r = getdns_dict_get_int(
|
||||
rdata, rd_def->name, &value)))
|
||||
break;
|
||||
|
||||
for (j = rd_def->type & GETDNS_RDF_FIXEDSZ; j; j--)
|
||||
gldns_buffer_write_u8(buf,
|
||||
(uint8_t)(value >> (8 * (j - 1))) & 0xff);
|
||||
}
|
||||
ldns_rr_set_owner(*rr, owner);
|
||||
|
||||
r = getdns_dict_get_int(rr_dict, "type", &rr_type);
|
||||
if (r != GETDNS_RETURN_GOOD)
|
||||
break;
|
||||
ldns_rr_set_type(*rr, rr_type);
|
||||
|
||||
r = getdns_dict_get_dict(rr_dict, "rdata", &rdata);
|
||||
if (r != GETDNS_RETURN_GOOD)
|
||||
break;
|
||||
|
||||
r = priv_getdns_dict_get_raw_rdata(rdata, &wire, &wire_size);
|
||||
if (r == GETDNS_RETURN_NO_SUCH_DICT_NAME) {
|
||||
r = priv_getdns_construct_wire_rdata_from_rdata(
|
||||
rdata, rr_type, &wire, &wire_size);
|
||||
}
|
||||
if (r != GETDNS_RETURN_GOOD)
|
||||
break;
|
||||
pos = 0;
|
||||
s = ldns_wire2rdf(*rr, wire, wire_size, &pos);
|
||||
GETDNS_FREE(rr_dict->mf, wire);
|
||||
if (s == LDNS_STATUS_OK)
|
||||
return r;
|
||||
r = GETDNS_RETURN_GENERIC_ERROR;
|
||||
} while (0);
|
||||
ldns_rr_free(*rr);
|
||||
gldns_buffer_write_u16_at(buf, rdata_size_mark,
|
||||
(uint16_t)(gldns_buffer_position(buf)-rdata_size_mark-2));
|
||||
}
|
||||
error:
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,8 +32,9 @@
|
|||
#ifndef RR_DICT_H_
|
||||
#define RR_DICT_H_
|
||||
|
||||
#include <ldns/ldns.h>
|
||||
#include "config.h"
|
||||
#include "getdns/getdns.h"
|
||||
#include "gldns/gbuffer.h"
|
||||
|
||||
typedef uint8_t *(*priv_getdns_rdf_end_t)(
|
||||
uint8_t *pkt, uint8_t *pkt_end, uint8_t *rdf);
|
||||
|
@ -51,56 +52,57 @@ typedef struct priv_getdns_rdf_special {
|
|||
|
||||
/* draft-levine-dnsextlang'ish type rr and rdata definitions */
|
||||
|
||||
#define GETDNS_RDF_INTEGER 0x010000
|
||||
#define GETDNS_RDF_BINDATA 0x020000
|
||||
#define GETDNS_RDF_DNAME 0x060000
|
||||
#define GETDNS_RDF_REPEAT 0x100000
|
||||
#define GETDNS_RDF_INTEGER 0x010000
|
||||
#define GETDNS_RDF_BINDATA 0x020000
|
||||
#define GETDNS_RDF_DNAME 0x060000
|
||||
#define GETDNS_RDF_COMPRESSED 0x080000
|
||||
#define GETDNS_RDF_REPEAT 0x100000
|
||||
|
||||
#define GETDNS_RDF_FIXEDSZ 0x0000FF
|
||||
#define GETDNS_RDF_LEN_VAL 0x00FF00
|
||||
#define GETDNS_RDF_FIXEDSZ 0x0000FF
|
||||
#define GETDNS_RDF_LEN_VAL 0x00FF00
|
||||
|
||||
typedef enum priv_getdns_rdf_wf_type {
|
||||
GETDNS_RDF_N = 0x060000, /* N */
|
||||
GETDNS_RDF_N_A = GETDNS_RDF_N, /* N[A] */
|
||||
GETDNS_RDF_N_A_C = GETDNS_RDF_N, /* N[A,C] */
|
||||
GETDNS_RDF_N_C = GETDNS_RDF_N, /* N[C] */
|
||||
GETDNS_RDF_N_M = 0x160000, /* N[M] */
|
||||
GETDNS_RDF_N = 0x060000, /* N */
|
||||
GETDNS_RDF_N_A = 0x060000, /* N[A] */
|
||||
GETDNS_RDF_N_C = 0x0E0000, /* N[C] */
|
||||
GETDNS_RDF_N_A_C = 0x0E0000, /* N[A,C] */
|
||||
GETDNS_RDF_N_M = 0x160000, /* N[M] */
|
||||
|
||||
GETDNS_RDF_I1 = 0x010001, /* I1 */
|
||||
GETDNS_RDF_I2 = 0x010002, /* I2 */
|
||||
GETDNS_RDF_I4 = 0x010004, /* I4 */
|
||||
GETDNS_RDF_I1 = 0x010001, /* I1 */
|
||||
GETDNS_RDF_I2 = 0x010002, /* I2 */
|
||||
GETDNS_RDF_I4 = 0x010004, /* I4 */
|
||||
|
||||
GETDNS_RDF_T = 0x010004, /* T */
|
||||
GETDNS_RDF_T = 0x010004, /* T */
|
||||
/* Time values using ring arithmetics
|
||||
* (rfc1982) for TKEY['inception'],
|
||||
* TKEY['expiration'],
|
||||
* RRSIG['inception'] and
|
||||
* RRSIG['expiration']
|
||||
*/
|
||||
GETDNS_RDF_T6 = 0x020006, /* T6 */
|
||||
GETDNS_RDF_T6 = 0x020006, /* T6 */
|
||||
/* Absolute time values (since epoch)
|
||||
* for TSIG['time_signed']
|
||||
*/
|
||||
|
||||
GETDNS_RDF_A = 0x020004, /* A */
|
||||
GETDNS_RDF_AA = 0x020008, /* AA */
|
||||
GETDNS_RDF_AAAA = 0x020010, /* AAAA */
|
||||
GETDNS_RDF_A = 0x020004, /* A */
|
||||
GETDNS_RDF_AA = 0x020008, /* AA */
|
||||
GETDNS_RDF_AAAA = 0x020010, /* AAAA */
|
||||
|
||||
GETDNS_RDF_S = 0x020100, /* S */
|
||||
GETDNS_RDF_S_L = 0x020000, /* S[L] */
|
||||
GETDNS_RDF_S_M = 0x120100, /* S[M] */
|
||||
GETDNS_RDF_S = 0x020100, /* S */
|
||||
GETDNS_RDF_S_L = 0x020000, /* S[L] */
|
||||
GETDNS_RDF_S_M = 0x120100, /* S[M] */
|
||||
|
||||
GETDNS_RDF_B = 0x020000, /* B */
|
||||
GETDNS_RDF_B_C = 0x020100, /* B[C] */
|
||||
GETDNS_RDF_B = 0x020000, /* B */
|
||||
GETDNS_RDF_B_C = 0x020100, /* B[C] */
|
||||
|
||||
GETDNS_RDF_B32_C = 0x020100, /* B32[C] */
|
||||
GETDNS_RDF_B32_C = 0x020100, /* B32[C] */
|
||||
|
||||
GETDNS_RDF_X = 0x020000, /* X */
|
||||
GETDNS_RDF_X_C = 0x020100, /* X[C] */
|
||||
GETDNS_RDF_X = 0x020000, /* X */
|
||||
GETDNS_RDF_X_C = 0x020100, /* X[C] */
|
||||
/* for NSEC3['salt'] and
|
||||
* NSEC3PARAM['salt'].
|
||||
*/
|
||||
GETDNS_RDF_X_S = 0x020200, /* X[S] */
|
||||
GETDNS_RDF_X_S = 0x020200, /* X[S] */
|
||||
/* for OPT['option_data'],
|
||||
* TKEY['key_data'],
|
||||
* TKEY['other_data'],
|
||||
|
@ -109,12 +111,12 @@ typedef enum priv_getdns_rdf_wf_type {
|
|||
* Although those do not have an
|
||||
* official presentation format.
|
||||
*/
|
||||
GETDNS_RDF_X6 = 0x020006,
|
||||
GETDNS_RDF_X8 = 0x020008,
|
||||
GETDNS_RDF_X6 = 0x020006,
|
||||
GETDNS_RDF_X8 = 0x020008,
|
||||
|
||||
GETDNS_RDF_R = 0x100000, /* Repeat */
|
||||
GETDNS_RDF_R = 0x100000, /* Repeat */
|
||||
|
||||
GETDNS_RDF_SPECIAL = 0x800000,
|
||||
GETDNS_RDF_SPECIAL = 0x800000,
|
||||
} priv_getdns_rdf_type;
|
||||
|
||||
typedef struct priv_getdns_rdata_def {
|
||||
|
@ -131,8 +133,8 @@ typedef struct priv_getdns_rr_def {
|
|||
|
||||
const priv_getdns_rr_def *priv_getdns_rr_def_lookup(uint16_t rr_type);
|
||||
|
||||
getdns_return_t priv_getdns_create_rr_from_dict(
|
||||
struct getdns_dict *rr_dict, ldns_rr **rr);
|
||||
getdns_return_t priv_getdns_rr_dict2wire(
|
||||
getdns_dict *rr_dict, gldns_buffer *buf);
|
||||
|
||||
const char *priv_getdns_rr_type_name(int rr_type);
|
||||
|
||||
|
|
|
@ -98,6 +98,13 @@ priv_getdns_rr_iter_init(priv_getdns_rr_iter *i, uint8_t *pkt, size_t pkt_len)
|
|||
return find_rrtype(i);
|
||||
}
|
||||
|
||||
priv_getdns_rr_iter *
|
||||
priv_getdns_rr_iter_rewind(priv_getdns_rr_iter *i)
|
||||
{
|
||||
assert(i);
|
||||
|
||||
return priv_getdns_rr_iter_init(i, i->pkt, i->pkt_end - i->pkt);
|
||||
}
|
||||
|
||||
priv_getdns_rr_iter *
|
||||
priv_getdns_rr_iter_next(priv_getdns_rr_iter *i)
|
||||
|
|
|
@ -62,6 +62,8 @@ typedef struct priv_getdns_rr_iter {
|
|||
priv_getdns_rr_iter *priv_getdns_rr_iter_init(priv_getdns_rr_iter *i,
|
||||
uint8_t *pkt, size_t pkt_len);
|
||||
|
||||
priv_getdns_rr_iter *priv_getdns_rr_iter_rewind(priv_getdns_rr_iter *i);
|
||||
|
||||
priv_getdns_rr_iter *priv_getdns_rr_iter_next(priv_getdns_rr_iter *i);
|
||||
|
||||
uint8_t *priv_getdns_owner_if_or_as_decompressed(
|
||||
|
|
56
src/stub.c
56
src/stub.c
|
@ -31,6 +31,7 @@
|
|||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include "config.h"
|
||||
#include <fcntl.h>
|
||||
#include "stub.h"
|
||||
|
@ -40,7 +41,6 @@
|
|||
#include "gldns/str2wire.h"
|
||||
#include "rr-iter.h"
|
||||
#include "context.h"
|
||||
#include <ldns/util.h>
|
||||
#include "util-internal.h"
|
||||
#include "general.h"
|
||||
|
||||
|
@ -273,21 +273,6 @@ create_starttls_request(getdns_dns_req *dnsreq, getdns_upstream *upstream,
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
dname_equal(uint8_t *s1, uint8_t *s2)
|
||||
{
|
||||
uint8_t i;
|
||||
for (;;) {
|
||||
if (*s1 != *s2)
|
||||
return 0;
|
||||
else if (!*s1)
|
||||
return 1;
|
||||
for (i = *s1++, s2++; i > 0; i--, s1++, s2++)
|
||||
if ((*s1 & 0xDF) != (*s2 & 0xDF))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
is_starttls_response(getdns_network_req *netreq)
|
||||
{
|
||||
|
@ -295,10 +280,10 @@ is_starttls_response(getdns_network_req *netreq)
|
|||
priv_getdns_rdf_iter rdf_iter_storage, *rdf_iter;
|
||||
uint16_t rr_type;
|
||||
gldns_pkt_section section;
|
||||
uint8_t starttls_name_space[256],
|
||||
*starttls_name = starttls_name_space;
|
||||
uint8_t starttls_name_space[256], *starttls_name;
|
||||
uint8_t owner_name_space[256], *owner_name;
|
||||
size_t starttls_name_len = 256, owner_name_len;
|
||||
size_t starttls_name_len = sizeof(starttls_name_space);
|
||||
size_t owner_name_len = sizeof(owner_name_space);;
|
||||
|
||||
/* Servers that are not STARTTLS aware will refuse the CH query*/
|
||||
if (GLDNS_RCODE_NOERROR != GLDNS_RCODE_WIRE(netreq->response))
|
||||
|
@ -307,9 +292,6 @@ is_starttls_response(getdns_network_req *netreq)
|
|||
if (GLDNS_ANCOUNT(netreq->response) != 1)
|
||||
return 0;
|
||||
|
||||
(void) gldns_str2wire_dname_buf(
|
||||
netreq->owner->name, starttls_name_space, &starttls_name_len);
|
||||
|
||||
for ( rr_iter = priv_getdns_rr_iter_init(&rr_iter_storage
|
||||
, netreq->response
|
||||
, netreq->response_len)
|
||||
|
@ -318,25 +300,25 @@ is_starttls_response(getdns_network_req *netreq)
|
|||
|
||||
section = priv_getdns_rr_iter_section(rr_iter);
|
||||
rr_type = gldns_read_uint16(rr_iter->rr_type);
|
||||
if (section != GLDNS_SECTION_ANSWER || rr_type != GETDNS_RRTYPE_TXT)
|
||||
if (section != GLDNS_SECTION_ANSWER
|
||||
|| rr_type != GETDNS_RRTYPE_TXT)
|
||||
continue;
|
||||
|
||||
owner_name = priv_getdns_owner_if_or_as_decompressed(
|
||||
rr_iter, owner_name_space, &owner_name_len);
|
||||
if (!dname_equal(starttls_name, owner_name))
|
||||
if (!priv_getdns_dname_equal(netreq->owner->name, owner_name))
|
||||
continue;
|
||||
|
||||
if (!(rdf_iter = priv_getdns_rdf_iter_init(
|
||||
&rdf_iter_storage, rr_iter)))
|
||||
continue;
|
||||
/* re-use the starttls_name for the response dname*/
|
||||
starttls_name = priv_getdns_rdf_if_or_as_decompressed(
|
||||
rdf_iter,starttls_name_space,&starttls_name_len);
|
||||
if (dname_equal(starttls_name, owner_name))
|
||||
|
||||
if ((starttls_name = priv_getdns_rdf_if_or_as_decompressed(
|
||||
rdf_iter, starttls_name_space, &starttls_name_len)) &&
|
||||
priv_getdns_dname_equal(starttls_name, owner_name))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
continue;
|
||||
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -1144,10 +1126,6 @@ stub_udp_read_cb(void *userarg)
|
|||
}
|
||||
netreq->response_len = read;
|
||||
dnsreq->upstreams->current = 0;
|
||||
|
||||
/* TODO: DNSSEC */
|
||||
netreq->secure = 0;
|
||||
netreq->bogus = 0;
|
||||
done:
|
||||
netreq->state = NET_REQ_FINISHED;
|
||||
priv_getdns_check_dns_req_complete(dnsreq);
|
||||
|
@ -1227,10 +1205,6 @@ stub_tcp_read_cb(void *userarg)
|
|||
netreq->tcp.read_buf = NULL;
|
||||
dnsreq->upstreams->current = 0;
|
||||
|
||||
/* TODO: DNSSEC */
|
||||
netreq->secure = 0;
|
||||
netreq->bogus = 0;
|
||||
|
||||
stub_cleanup(netreq);
|
||||
close(netreq->fd);
|
||||
priv_getdns_check_dns_req_complete(dnsreq);
|
||||
|
@ -1317,10 +1291,6 @@ upstream_read_cb(void *userarg)
|
|||
* on a working connection until we hit a problem.*/
|
||||
upstream->upstreams->current = 0;
|
||||
|
||||
/* TODO: DNSSEC */
|
||||
netreq->secure = 0;
|
||||
netreq->bogus = 0;
|
||||
|
||||
if (netreq->owner == upstream->starttls_req) {
|
||||
dnsreq = netreq->owner;
|
||||
if (is_starttls_response(netreq)) {
|
||||
|
|
|
@ -166,6 +166,90 @@ print_usage(FILE *out, const char *progname)
|
|||
fprintf(out, "\t-q\tQuiet mode - don't print response\n");
|
||||
}
|
||||
|
||||
static getdns_return_t validate_chain(getdns_dict *response)
|
||||
{
|
||||
getdns_return_t r;
|
||||
getdns_list *validation_chain;
|
||||
getdns_list *replies_tree;
|
||||
getdns_dict *reply;
|
||||
getdns_list *to_validate;
|
||||
getdns_list *trust_anchor;
|
||||
size_t i;
|
||||
int s;
|
||||
|
||||
if (!(to_validate = getdns_list_create()))
|
||||
return GETDNS_RETURN_MEMORY_ERROR;
|
||||
|
||||
if (!(trust_anchor = getdns_root_trust_anchor(NULL)))
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
|
||||
if ((r = getdns_dict_get_list(
|
||||
response, "validation_chain", &validation_chain)))
|
||||
return r;
|
||||
|
||||
if ((r = getdns_dict_get_list(
|
||||
response, "replies_tree", &replies_tree)))
|
||||
return r;
|
||||
|
||||
fprintf(stdout, "replies_tree %zu, dnssec_status: ", i);
|
||||
switch ((s = getdns_validate_dnssec(
|
||||
replies_tree, validation_chain, trust_anchor))) {
|
||||
|
||||
case GETDNS_DNSSEC_SECURE:
|
||||
fprintf(stdout, "GETDNS_DNSSEC_SECURE\n");
|
||||
break;
|
||||
case GETDNS_DNSSEC_BOGUS:
|
||||
fprintf(stdout, "GETDNS_DNSSEC_BOGUS\n");
|
||||
break;
|
||||
case GETDNS_DNSSEC_INDETERMINATE:
|
||||
fprintf(stdout, "GETDNS_DNSSEC_INDETERMINATE\n");
|
||||
break;
|
||||
case GETDNS_DNSSEC_INSECURE:
|
||||
fprintf(stdout, "GETDNS_DNSSEC_INSECURE\n");
|
||||
break;
|
||||
case GETDNS_DNSSEC_NOT_PERFORMED:
|
||||
fprintf(stdout, "GETDNS_DNSSEC_NOT_PERFORMED\n");
|
||||
break;
|
||||
default:
|
||||
fprintf(stdout, "%d\n", (int)s);
|
||||
}
|
||||
|
||||
i = 0;
|
||||
while (!(r = getdns_list_get_dict(replies_tree, i++, &reply))) {
|
||||
|
||||
if ((r = getdns_list_set_dict(to_validate, 0, reply)))
|
||||
return r;
|
||||
|
||||
fprintf( stdout
|
||||
, "reply %zu, dnssec_status: ", i);
|
||||
switch ((s = getdns_validate_dnssec(
|
||||
to_validate, validation_chain, trust_anchor))) {
|
||||
|
||||
case GETDNS_DNSSEC_SECURE:
|
||||
fprintf(stdout, "GETDNS_DNSSEC_SECURE\n");
|
||||
break;
|
||||
case GETDNS_DNSSEC_BOGUS:
|
||||
fprintf(stdout, "GETDNS_DNSSEC_BOGUS\n");
|
||||
break;
|
||||
case GETDNS_DNSSEC_INDETERMINATE:
|
||||
fprintf(stdout, "GETDNS_DNSSEC_INDETERMINATE\n");
|
||||
break;
|
||||
case GETDNS_DNSSEC_INSECURE:
|
||||
fprintf(stdout, "GETDNS_DNSSEC_INSECURE\n");
|
||||
break;
|
||||
case GETDNS_DNSSEC_NOT_PERFORMED:
|
||||
fprintf(stdout, "GETDNS_DNSSEC_NOT_PERFORMED\n");
|
||||
break;
|
||||
default:
|
||||
fprintf(stdout, "%d\n", (int)s);
|
||||
}
|
||||
}
|
||||
if (r != GETDNS_RETURN_NO_SUCH_LIST_ITEM)
|
||||
return r;
|
||||
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
void callback(getdns_context *context, getdns_callback_type_t callback_type,
|
||||
getdns_dict *response, void *userarg, getdns_transaction_t trans_id)
|
||||
{
|
||||
|
@ -178,6 +262,7 @@ void callback(getdns_context *context, getdns_callback_type_t callback_type,
|
|||
: getdns_pretty_print_dict(response))) {
|
||||
|
||||
fprintf(stdout, "ASYNC response:\n%s\n", response_str);
|
||||
validate_chain(response);
|
||||
free(response_str);
|
||||
}
|
||||
fprintf(stdout,
|
||||
|
@ -617,6 +702,7 @@ main(int argc, char **argv)
|
|||
|
||||
fprintf( stdout, "SYNC response:\n%s\n"
|
||||
, response_str);
|
||||
validate_chain(response);
|
||||
free(response_str);
|
||||
} else {
|
||||
r = GETDNS_RETURN_MEMORY_ERROR;
|
||||
|
|
|
@ -189,9 +189,8 @@ typedef struct getdns_network_req
|
|||
/* request class */
|
||||
uint16_t request_class;
|
||||
|
||||
/* result */
|
||||
int secure;
|
||||
int bogus;
|
||||
/* dnssec status */
|
||||
int dnssec_status;
|
||||
|
||||
/* For stub resolving */
|
||||
struct getdns_upstream *upstream;
|
||||
|
@ -232,7 +231,8 @@ typedef struct getdns_dns_req {
|
|||
getdns_rbnode_t node;
|
||||
|
||||
/* name */
|
||||
char *name;
|
||||
uint8_t name[256];
|
||||
size_t name_len;
|
||||
|
||||
/* canceled flag */
|
||||
int canceled;
|
||||
|
@ -319,6 +319,8 @@ typedef struct getdns_dns_req {
|
|||
|
||||
/* utility methods */
|
||||
|
||||
extern getdns_dict *dnssec_ok_checking_disabled;
|
||||
|
||||
/* dns request utils */
|
||||
getdns_dns_req *dns_req_new(getdns_context *context, getdns_eventloop *loop,
|
||||
const char *name, uint16_t request_type, getdns_dict *extensions);
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <unbound.h>
|
||||
#include "getdns/getdns.h"
|
||||
#include "dict.h"
|
||||
|
@ -60,7 +61,6 @@
|
|||
static getdns_extension_format extformats[] = {
|
||||
{"add_opt_parameters", t_dict},
|
||||
{"add_warning_for_bad_dns", t_int},
|
||||
{"dnssec_ok_checking_disabled", t_int},
|
||||
{"dnssec_return_only_secure", t_int},
|
||||
{"dnssec_return_status", t_int},
|
||||
{"dnssec_return_validation_chain", t_int},
|
||||
|
@ -179,7 +179,7 @@ sockaddr_to_dict(struct getdns_context *context, struct sockaddr_storage *addres
|
|||
}
|
||||
|
||||
getdns_dict *
|
||||
priv_getdns_rr_iter2rr_dict(getdns_context *context, priv_getdns_rr_iter *i)
|
||||
priv_getdns_rr_iter2rr_dict(struct mem_funcs *mf, priv_getdns_rr_iter *i)
|
||||
{
|
||||
getdns_dict *rr_dict, *rdata_dict;
|
||||
getdns_bindata bindata;
|
||||
|
@ -192,7 +192,7 @@ priv_getdns_rr_iter2rr_dict(getdns_context *context, priv_getdns_rr_iter *i)
|
|||
uint16_t rr_type;
|
||||
|
||||
assert(i);
|
||||
if (!(rr_dict = getdns_dict_create_with_context(context)))
|
||||
if (!(rr_dict = _getdns_dict_create_with_mf(mf)))
|
||||
return NULL;
|
||||
|
||||
bindata.data = priv_getdns_owner_if_or_as_decompressed(
|
||||
|
@ -248,8 +248,8 @@ priv_getdns_rr_iter2rr_dict(getdns_context *context, priv_getdns_rr_iter *i)
|
|||
|
||||
goto error;
|
||||
}
|
||||
if (!(rdata_dict = getdns_dict_create_with_context(context)))
|
||||
goto error;
|
||||
if (!(rdata_dict = _getdns_dict_create_with_mf(mf)))
|
||||
return NULL;
|
||||
|
||||
if (i->rr_type + 10 <= i->nxt) {
|
||||
bindata.size = i->nxt - (i->rr_type + 10);
|
||||
|
@ -330,7 +330,8 @@ priv_getdns_rr_iter2rr_dict(getdns_context *context, priv_getdns_rr_iter *i)
|
|||
/* list with rdf values */
|
||||
|
||||
if (! repeat_list && !(repeat_list =
|
||||
getdns_list_create_with_context(context)))
|
||||
_getdns_list_create_with_mf(mf)))
|
||||
|
||||
goto rdata_error;
|
||||
|
||||
switch (val_type) {
|
||||
|
@ -357,7 +358,7 @@ priv_getdns_rr_iter2rr_dict(getdns_context *context, priv_getdns_rr_iter *i)
|
|||
|
||||
if (repeat_dict) {
|
||||
if (! repeat_list && !(repeat_list =
|
||||
getdns_list_create_with_context(context)))
|
||||
_getdns_list_create_with_mf(mf)))
|
||||
goto rdata_error;
|
||||
|
||||
if (getdns_list_append_dict(
|
||||
|
@ -368,7 +369,7 @@ priv_getdns_rr_iter2rr_dict(getdns_context *context, priv_getdns_rr_iter *i)
|
|||
repeat_dict = NULL;
|
||||
}
|
||||
if (!(repeat_dict =
|
||||
getdns_dict_create_with_context(context)))
|
||||
_getdns_dict_create_with_mf(mf)))
|
||||
goto rdata_error;
|
||||
}
|
||||
assert(repeat_dict);
|
||||
|
@ -393,7 +394,7 @@ priv_getdns_rr_iter2rr_dict(getdns_context *context, priv_getdns_rr_iter *i)
|
|||
}
|
||||
if (repeat_dict) {
|
||||
if (!repeat_list && !(repeat_list =
|
||||
getdns_list_create_with_context(context)))
|
||||
_getdns_list_create_with_mf(mf)))
|
||||
goto rdata_error;
|
||||
if (getdns_list_append_dict(repeat_list, repeat_dict))
|
||||
goto rdata_error;
|
||||
|
@ -422,8 +423,8 @@ error:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
dname_equal(uint8_t *s1, uint8_t *s2)
|
||||
int
|
||||
priv_getdns_dname_equal(const uint8_t *s1, const uint8_t *s2)
|
||||
{
|
||||
uint8_t i;
|
||||
for (;;) {
|
||||
|
@ -432,7 +433,8 @@ dname_equal(uint8_t *s1, uint8_t *s2)
|
|||
else if (!*s1)
|
||||
return 1;
|
||||
for (i = *s1++, s2++; i > 0; i--, s1++, s2++)
|
||||
if ((*s1 & 0xDF) != (*s2 & 0xDF))
|
||||
if (*s1 != *s2 && tolower((unsigned char)*s1)
|
||||
!= tolower((unsigned char)*s2))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -543,8 +545,7 @@ priv_getdns_create_reply_dict(getdns_context *context, getdns_network_req *req,
|
|||
if ((r = getdns_dict_set_dict(result, "header", header)))
|
||||
goto error;
|
||||
|
||||
(void) gldns_str2wire_dname_buf(
|
||||
req->owner->name, canonical_name_space, &canonical_name_len);
|
||||
canonical_name = req->owner->name;
|
||||
|
||||
for ( rr_iter = priv_getdns_rr_iter_init(&rr_iter_storage
|
||||
, req->response
|
||||
|
@ -553,7 +554,7 @@ priv_getdns_create_reply_dict(getdns_context *context, getdns_network_req *req,
|
|||
; rr_iter = priv_getdns_rr_iter_next(rr_iter)) {
|
||||
|
||||
if (!set_dict(&rr_dict,
|
||||
priv_getdns_rr_iter2rr_dict(context, rr_iter)))
|
||||
priv_getdns_rr_iter2rr_dict(&context->mf, rr_iter)))
|
||||
continue;
|
||||
|
||||
section = priv_getdns_rr_iter_section(rr_iter);
|
||||
|
@ -580,7 +581,7 @@ priv_getdns_create_reply_dict(getdns_context *context, getdns_network_req *req,
|
|||
|
||||
owner_name = priv_getdns_owner_if_or_as_decompressed(
|
||||
rr_iter, owner_name_space, &owner_name_len);
|
||||
if (!dname_equal(canonical_name, owner_name))
|
||||
if (!priv_getdns_dname_equal(canonical_name, owner_name))
|
||||
continue;
|
||||
|
||||
if (!(rdf_iter = priv_getdns_rdf_iter_init(
|
||||
|
@ -653,7 +654,7 @@ priv_getdns_create_reply_dict(getdns_context *context, getdns_network_req *req,
|
|||
|
||||
owner_name = priv_getdns_owner_if_or_as_decompressed(
|
||||
rr_iter, owner_name_space, &owner_name_len);
|
||||
if (!dname_equal(canonical_name, owner_name))
|
||||
if (!priv_getdns_dname_equal(canonical_name, owner_name))
|
||||
continue;
|
||||
|
||||
if (!(rdf_iter = priv_getdns_rdf_iter_init(
|
||||
|
@ -733,21 +734,22 @@ create_getdns_response(getdns_dns_req *completed_request)
|
|||
continue;
|
||||
|
||||
nreplies++;
|
||||
if (netreq->secure)
|
||||
if (netreq->dnssec_status == GETDNS_DNSSEC_SECURE)
|
||||
nsecure++;
|
||||
else if (! netreq->bogus)
|
||||
else if (! netreq->dnssec_status != GETDNS_DNSSEC_BOGUS)
|
||||
ninsecure++;
|
||||
if (dnssec_return_status && netreq->bogus)
|
||||
|
||||
if (dnssec_return_status &&
|
||||
netreq->dnssec_status == GETDNS_DNSSEC_BOGUS)
|
||||
nbogus++;
|
||||
else if (GLDNS_RCODE_NOERROR ==
|
||||
GLDNS_RCODE_WIRE(netreq->response))
|
||||
nanswers++;
|
||||
|
||||
|
||||
if (! completed_request->dnssec_return_validation_chain) {
|
||||
if (dnssec_return_status && netreq->bogus)
|
||||
if (dnssec_return_status &&
|
||||
netreq->dnssec_status == GETDNS_DNSSEC_BOGUS)
|
||||
continue;
|
||||
else if (completed_request->dnssec_return_only_secure
|
||||
&& ! netreq->secure)
|
||||
&& netreq->dnssec_status != GETDNS_DNSSEC_SECURE)
|
||||
continue;
|
||||
}
|
||||
if (!(reply = priv_getdns_create_reply_dict(context,
|
||||
|
@ -762,15 +764,18 @@ create_getdns_response(getdns_dns_req *completed_request)
|
|||
result, "canonical_name", canonical_name))
|
||||
goto error;
|
||||
}
|
||||
/* TODO: Check instead if canonical_name for request_type
|
||||
* is in the answer section.
|
||||
*/
|
||||
if (GLDNS_RCODE_NOERROR ==
|
||||
GLDNS_RCODE_WIRE(netreq->response))
|
||||
nanswers++;
|
||||
|
||||
if (dnssec_return_status ||
|
||||
completed_request->dnssec_return_validation_chain) {
|
||||
|
||||
if (getdns_dict_set_int(reply, "dnssec_status",
|
||||
( netreq->secure ? GETDNS_DNSSEC_SECURE
|
||||
: netreq->bogus ? GETDNS_DNSSEC_BOGUS
|
||||
: rrsigs_in_answer &&
|
||||
context->has_ta ? GETDNS_DNSSEC_INDETERMINATE
|
||||
: GETDNS_DNSSEC_INSECURE )))
|
||||
netreq->dnssec_status))
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
@ -830,7 +835,7 @@ extformatcmp(const void *a, const void *b)
|
|||
|
||||
/*---------------------------------------- validate_extensions */
|
||||
getdns_return_t
|
||||
validate_extensions(struct getdns_dict * extensions)
|
||||
priv_getdns_validate_extensions(struct getdns_dict * extensions)
|
||||
{
|
||||
struct getdns_dict_item *item;
|
||||
getdns_extension_format *extformat;
|
||||
|
@ -852,16 +857,18 @@ validate_extensions(struct getdns_dict * extensions)
|
|||
return GETDNS_RETURN_EXTENSION_MISFORMAT;
|
||||
}
|
||||
return GETDNS_RETURN_GOOD;
|
||||
} /* validate_extensions */
|
||||
} /* priv_getdns_validate_extensions */
|
||||
|
||||
getdns_return_t
|
||||
getdns_apply_network_result(getdns_network_req* netreq,
|
||||
struct ub_result* ub_res)
|
||||
{
|
||||
size_t dname_len;
|
||||
|
||||
netreq->secure = ub_res->secure;
|
||||
netreq->bogus = ub_res->bogus;
|
||||
if (ub_res->bogus)
|
||||
netreq->dnssec_status = GETDNS_DNSSEC_BOGUS;
|
||||
else if (ub_res->secure)
|
||||
netreq->dnssec_status = GETDNS_DNSSEC_SECURE;
|
||||
else if (netreq->owner->context->trust_anchors)
|
||||
netreq->dnssec_status = GETDNS_DNSSEC_INSECURE;
|
||||
|
||||
if (ub_res == NULL) /* Timeout */
|
||||
return GETDNS_RETURN_GOOD;
|
||||
|
@ -900,24 +907,24 @@ getdns_apply_network_result(getdns_network_req* netreq,
|
|||
GLDNS_RA_SET(netreq->response);
|
||||
GLDNS_RCODE_SET(netreq->response, ub_res->rcode);
|
||||
|
||||
dname_len = netreq->max_udp_payload_size - GLDNS_HEADER_SIZE;
|
||||
if (gldns_str2wire_dname_buf(netreq->owner->name,
|
||||
netreq->response + GLDNS_HEADER_SIZE, &dname_len))
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
(void) memcpy( netreq->response + GLDNS_HEADER_SIZE
|
||||
, netreq->owner->name, netreq->owner->name_len);
|
||||
|
||||
gldns_write_uint16( netreq->response + GLDNS_HEADER_SIZE + dname_len
|
||||
gldns_write_uint16( netreq->response + GLDNS_HEADER_SIZE
|
||||
+ netreq->owner->name_len
|
||||
, netreq->request_type);
|
||||
gldns_write_uint16( netreq->response + GLDNS_HEADER_SIZE + dname_len + 2
|
||||
gldns_write_uint16( netreq->response + GLDNS_HEADER_SIZE
|
||||
+ netreq->owner->name_len + 2
|
||||
, netreq->request_class);
|
||||
|
||||
netreq->response_len = GLDNS_HEADER_SIZE + dname_len + 4;
|
||||
netreq->response_len = GLDNS_HEADER_SIZE + netreq->owner->name_len + 4;
|
||||
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
|
||||
getdns_return_t
|
||||
validate_dname(const char* dname) {
|
||||
priv_getdns_validate_dname(const char* dname) {
|
||||
int len;
|
||||
int label_len;
|
||||
const char* s;
|
||||
|
@ -980,7 +987,150 @@ validate_dname(const char* dname) {
|
|||
return GETDNS_RETURN_BAD_DOMAIN_NAME;
|
||||
}
|
||||
return GETDNS_RETURN_GOOD;
|
||||
} /* validate_dname */
|
||||
} /* priv_getdns_validate_dname */
|
||||
|
||||
|
||||
static void _getdns_list2wire_buf(gldns_buffer *buf, getdns_list *l)
|
||||
{
|
||||
getdns_dict *rr_dict, *q_dict;
|
||||
getdns_list *section;
|
||||
getdns_return_t r;
|
||||
size_t i, j, pkt_start, ancount, qdcount;
|
||||
uint32_t qtype, qclass;
|
||||
getdns_bindata *qname;
|
||||
|
||||
pkt_start = gldns_buffer_position(buf);
|
||||
/* Empty header */
|
||||
gldns_buffer_write_u32(buf, 0);
|
||||
gldns_buffer_write_u32(buf, 0);
|
||||
gldns_buffer_write_u32(buf, 0);
|
||||
|
||||
for ( i = 0, qdcount = 0
|
||||
; (r = getdns_list_get_dict(l, i, &rr_dict))
|
||||
!= GETDNS_RETURN_NO_SUCH_LIST_ITEM
|
||||
; i++ ) {
|
||||
|
||||
if (r) {
|
||||
if (r == GETDNS_RETURN_WRONG_TYPE_REQUESTED)
|
||||
continue;
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (getdns_dict_get_dict(rr_dict, "question", &q_dict)
|
||||
== GETDNS_RETURN_GOOD) {
|
||||
|
||||
/* rr_dict was actually a reply
|
||||
* with a question section/rr_dict
|
||||
*/
|
||||
rr_dict = q_dict;
|
||||
}
|
||||
if (getdns_dict_get_int(rr_dict, "qtype", &qtype) ||
|
||||
getdns_dict_get_bindata(rr_dict, "qname", &qname))
|
||||
continue;
|
||||
(void) getdns_dict_get_int(rr_dict, "qclass", &qclass);
|
||||
gldns_buffer_write(buf, qname->data, qname->size);
|
||||
gldns_buffer_write_u16(buf, (uint16_t)qtype);
|
||||
gldns_buffer_write_u16(buf, (uint16_t)qclass);
|
||||
qdcount++;
|
||||
}
|
||||
gldns_buffer_write_u16_at(buf, pkt_start+GLDNS_QDCOUNT_OFF, qdcount);
|
||||
for ( i = 0, ancount = 0
|
||||
; (r = getdns_list_get_dict(l, i, &rr_dict))
|
||||
!= GETDNS_RETURN_NO_SUCH_LIST_ITEM
|
||||
; i++ ) {
|
||||
|
||||
if (r) {
|
||||
if (r == GETDNS_RETURN_WRONG_TYPE_REQUESTED)
|
||||
continue;
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (priv_getdns_rr_dict2wire(rr_dict, buf)
|
||||
== GETDNS_RETURN_GOOD) {
|
||||
|
||||
ancount++;
|
||||
continue;
|
||||
}
|
||||
if (getdns_dict_get_list(rr_dict, "answer", §ion)
|
||||
== GETDNS_RETURN_GOOD) {
|
||||
|
||||
for ( j = 0
|
||||
; (r = getdns_list_get_dict(section, j, &q_dict))
|
||||
!= GETDNS_RETURN_NO_SUCH_LIST_ITEM
|
||||
; j++ ) {
|
||||
|
||||
if (r) {
|
||||
if (r ==
|
||||
GETDNS_RETURN_WRONG_TYPE_REQUESTED)
|
||||
continue;
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (priv_getdns_rr_dict2wire(q_dict, buf)
|
||||
== GETDNS_RETURN_GOOD)
|
||||
|
||||
ancount++;
|
||||
}
|
||||
}
|
||||
if (getdns_dict_get_list(rr_dict, "authority", §ion)
|
||||
== GETDNS_RETURN_GOOD) {
|
||||
|
||||
for ( j = 0
|
||||
; (r = getdns_list_get_dict(section, j, &q_dict))
|
||||
!= GETDNS_RETURN_NO_SUCH_LIST_ITEM
|
||||
; j++ ) {
|
||||
|
||||
if (r) {
|
||||
if (r ==
|
||||
GETDNS_RETURN_WRONG_TYPE_REQUESTED)
|
||||
continue;
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (priv_getdns_rr_dict2wire(q_dict, buf)
|
||||
== GETDNS_RETURN_GOOD)
|
||||
|
||||
ancount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
gldns_buffer_write_u16_at(buf, pkt_start+GLDNS_ANCOUNT_OFF, ancount);
|
||||
}
|
||||
|
||||
uint8_t *_getdns_list2wire(
|
||||
getdns_list *l, uint8_t *buf, size_t *buf_len, struct mem_funcs *mf)
|
||||
{
|
||||
gldns_buffer gbuf;
|
||||
size_t sz;
|
||||
|
||||
gldns_buffer_init_frm_data(&gbuf, buf, *buf_len);
|
||||
_getdns_list2wire_buf(&gbuf, l);
|
||||
|
||||
if ((sz = gldns_buffer_position(&gbuf)) <= *buf_len)
|
||||
return buf;
|
||||
|
||||
if (!(buf = GETDNS_XMALLOC(*mf, uint8_t, (*buf_len = sz))))
|
||||
return NULL;
|
||||
|
||||
gldns_buffer_init_frm_data(&gbuf, buf, sz);
|
||||
_getdns_list2wire_buf(&gbuf, l);
|
||||
return buf;
|
||||
}
|
||||
|
||||
void _getdns_wire2list(uint8_t *pkt, size_t pkt_len, getdns_list *l)
|
||||
{
|
||||
priv_getdns_rr_iter rr_spc, *rr;
|
||||
getdns_dict *rr_dict;
|
||||
|
||||
for ( rr = priv_getdns_rr_iter_init(&rr_spc, pkt, pkt_len)
|
||||
; rr ; rr = priv_getdns_rr_iter_next(rr)) {
|
||||
|
||||
if (!(rr_dict = priv_getdns_rr_iter2rr_dict(&l->mf, rr)))
|
||||
continue;
|
||||
|
||||
(void)getdns_list_append_dict(l, rr_dict);
|
||||
getdns_dict_destroy(rr_dict);
|
||||
}
|
||||
}
|
||||
|
||||
/* util-internal.c */
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#define SCHED_DEBUG 0
|
||||
#define WIRE_DEBUG 0
|
||||
#define STUB_DEBUG 0
|
||||
#define SEC_DEBUG 1
|
||||
|
||||
#ifdef S_SPLINT_S
|
||||
# define INLINE
|
||||
|
@ -122,7 +123,7 @@ getdns_return_t sockaddr_to_dict(struct getdns_context *context,
|
|||
struct sockaddr_storage *sockaddr, struct getdns_dict ** output);
|
||||
|
||||
getdns_dict *
|
||||
priv_getdns_rr_iter2rr_dict(getdns_context *context, priv_getdns_rr_iter *i);
|
||||
priv_getdns_rr_iter2rr_dict(struct mem_funcs *mf, priv_getdns_rr_iter *i);
|
||||
|
||||
struct getdns_dns_req;
|
||||
struct getdns_dict *create_getdns_response(struct getdns_dns_req *completed_request);
|
||||
|
@ -130,7 +131,15 @@ struct getdns_dict *create_getdns_response(struct getdns_dns_req *completed_requ
|
|||
getdns_dict *priv_getdns_create_reply_dict(getdns_context *context,
|
||||
getdns_network_req *req, getdns_list *just_addrs, int *rrsigs_in_answer);
|
||||
|
||||
getdns_return_t validate_dname(const char* dname);
|
||||
getdns_return_t priv_getdns_validate_dname(const char* dname);
|
||||
|
||||
int priv_getdns_dname_equal(const uint8_t *s1, const uint8_t *s2);
|
||||
|
||||
uint8_t *_getdns_list2wire(
|
||||
getdns_list *l, uint8_t *buf, size_t *buf_len, struct mem_funcs *mf);
|
||||
|
||||
void _getdns_wire2list(uint8_t *pkt, size_t pkt_len, getdns_list *l);
|
||||
|
||||
|
||||
/**
|
||||
* detect unrecognized extension strings or invalid extension formats
|
||||
|
@ -140,7 +149,7 @@ getdns_return_t validate_dname(const char* dname);
|
|||
* @return GETDNS_RETURN_NO_SUCH_EXTENSION A name in the extensions dict is not a valid extension.
|
||||
* @return GETDNS_RETURN_EXTENSION_MISFORMAT One or more of the extensions has a bad format.
|
||||
*/
|
||||
getdns_return_t validate_extensions(struct getdns_dict * extensions);
|
||||
getdns_return_t priv_getdns_validate_extensions(struct getdns_dict * extensions);
|
||||
|
||||
#define DEBUG_ON(...) do { \
|
||||
struct timeval tv; \
|
||||
|
@ -170,6 +179,13 @@ getdns_return_t validate_extensions(struct getdns_dict * extensions);
|
|||
#define DEBUG_STUB(...) DEBUG_OFF(__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#if defined(SEC_DEBUG) && SEC_DEBUG
|
||||
#include <time.h>
|
||||
#define DEBUG_SEC(...) DEBUG_ON(__VA_ARGS__)
|
||||
#else
|
||||
#define DEBUG_SEC(...) DEBUG_OFF(__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
INLINE getdns_eventloop_event *getdns_eventloop_event_init(
|
||||
getdns_eventloop_event *ev,void *userarg, getdns_eventloop_callback read_cb,
|
||||
getdns_eventloop_callback write_cb, getdns_eventloop_callback timeout_cb)
|
||||
|
|
Loading…
Reference in New Issue