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
|
# This file is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
|
|
@ -760,7 +760,7 @@ with_sysroot
|
||||||
enable_libtool_lock
|
enable_libtool_lock
|
||||||
enable_rpath
|
enable_rpath
|
||||||
enable_tcp_fastopen
|
enable_tcp_fastopen
|
||||||
enable_broken_native_stub_dnssec
|
enable_native_stub_dnssec
|
||||||
with_ssl
|
with_ssl
|
||||||
enable_draft_edns_cookies
|
enable_draft_edns_cookies
|
||||||
with_libidn
|
with_libidn
|
||||||
|
@ -1406,9 +1406,8 @@ Optional Features:
|
||||||
--disable-libtool-lock avoid locking (might break parallel builds)
|
--disable-libtool-lock avoid locking (might break parallel builds)
|
||||||
--disable-rpath disable hardcoded rpath (default=enabled)
|
--disable-rpath disable hardcoded rpath (default=enabled)
|
||||||
--enable-tcp-fastopen Enable TCP Fast Open
|
--enable-tcp-fastopen Enable TCP Fast Open
|
||||||
--enable-broken-native-stub-dnssec
|
--disable-native-stub-dnssec
|
||||||
Enable very experimental and broken native stub
|
Disable native stub DNSSEC support
|
||||||
DNSSEC support
|
|
||||||
--enable-draft-edns-cookies
|
--enable-draft-edns-cookies
|
||||||
Enable experimental edns cookies
|
Enable experimental edns cookies
|
||||||
|
|
||||||
|
@ -11738,20 +11737,20 @@ _ACEOF
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
# Check whether --enable-broken-native-stub-dnssec was given.
|
# Check whether --enable-native-stub-dnssec was given.
|
||||||
if test "${enable_broken_native_stub_dnssec+set}" = set; then :
|
if test "${enable_native_stub_dnssec+set}" = set; then :
|
||||||
enableval=$enable_broken_native_stub_dnssec;
|
enableval=$enable_native_stub_dnssec;
|
||||||
fi
|
fi
|
||||||
|
|
||||||
case "$enable_broken_native_stub_dnssec" in
|
case "$enable_native_stub_dnssec" in
|
||||||
yes)
|
no)
|
||||||
|
;;
|
||||||
|
yes|*)
|
||||||
|
|
||||||
cat >>confdefs.h <<_ACEOF
|
cat >>confdefs.h <<_ACEOF
|
||||||
#define STUB_NATIVE_DNSSEC 1
|
#define STUB_NATIVE_DNSSEC 1
|
||||||
_ACEOF
|
_ACEOF
|
||||||
|
|
||||||
;;
|
|
||||||
no|*)
|
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
|
10
configure.ac
10
configure.ac
|
@ -144,12 +144,12 @@ esac
|
||||||
# ])
|
# ])
|
||||||
# fi
|
# 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]))
|
AC_ARG_ENABLE(native-stub-dnssec, AC_HELP_STRING([--disable-native-stub-dnssec], [Disable native stub DNSSEC support]))
|
||||||
case "$enable_broken_native_stub_dnssec" in
|
case "$enable_native_stub_dnssec" in
|
||||||
yes)
|
no)
|
||||||
AC_DEFINE_UNQUOTED([STUB_NATIVE_DNSSEC], [1], [Define this to enable the very experimental and broken native stub DNSSEC support.])
|
|
||||||
;;
|
;;
|
||||||
no|*)
|
yes|*)
|
||||||
|
AC_DEFINE_UNQUOTED([STUB_NATIVE_DNSSEC], [1], [Define this to enable native stub DNSSEC support.])
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
|
|
@ -192,8 +192,7 @@
|
||||||
/* Define to 1 if you have the ANSI C header files. */
|
/* Define to 1 if you have the ANSI C header files. */
|
||||||
#undef STDC_HEADERS
|
#undef STDC_HEADERS
|
||||||
|
|
||||||
/* Define this to enable the very experimental and broken native stub DNSSEC
|
/* Define this to enable native stub DNSSEC support. */
|
||||||
support. */
|
|
||||||
#undef STUB_NATIVE_DNSSEC
|
#undef STUB_NATIVE_DNSSEC
|
||||||
|
|
||||||
/* System configuration dir */
|
/* System configuration dir */
|
||||||
|
|
106
src/context.c
106
src/context.c
|
@ -43,6 +43,7 @@
|
||||||
#include <unbound.h>
|
#include <unbound.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "gldns/str2wire.h"
|
#include "gldns/str2wire.h"
|
||||||
|
@ -815,6 +816,7 @@ getdns_context_create_with_extended_memory_functions(
|
||||||
getdns_return_t r;
|
getdns_return_t r;
|
||||||
struct getdns_context *result = NULL;
|
struct getdns_context *result = NULL;
|
||||||
mf_union mf;
|
mf_union mf;
|
||||||
|
gldns_buffer gbuf;
|
||||||
|
|
||||||
if (!context || !malloc || !realloc || !free)
|
if (!context || !malloc || !realloc || !free)
|
||||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||||
|
@ -860,7 +862,30 @@ getdns_context_create_with_extended_memory_functions(
|
||||||
result->append_name = GETDNS_APPEND_NAME_ALWAYS;
|
result->append_name = GETDNS_APPEND_NAME_ALWAYS;
|
||||||
result->suffix = NULL;
|
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->upstreams = NULL;
|
||||||
|
|
||||||
result->edns_extended_rcode = 0;
|
result->edns_extended_rcode = 0;
|
||||||
|
@ -873,7 +898,7 @@ getdns_context_create_with_extended_memory_functions(
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
result->fchg_resolvconf = NULL;
|
result->fchg_resolvconf = NULL;
|
||||||
result->fchg_hosts = NULL;
|
result->fchg_hosts = NULL;
|
||||||
|
|
||||||
if (set_from_os && (r = set_os_defaults(result)))
|
if (set_from_os && (r = set_os_defaults(result)))
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -883,12 +908,12 @@ getdns_context_create_with_extended_memory_functions(
|
||||||
if ((r = create_default_dns_transports(result)))
|
if ((r = create_default_dns_transports(result)))
|
||||||
goto error;
|
goto error;
|
||||||
result->limit_outstanding_queries = 0;
|
result->limit_outstanding_queries = 0;
|
||||||
result->has_ta = priv_getdns_parse_ta_file(NULL, NULL);
|
|
||||||
result->return_dnssec_status = GETDNS_EXTENSION_FALSE;
|
result->return_dnssec_status = GETDNS_EXTENSION_FALSE;
|
||||||
|
|
||||||
/* unbound context is initialized here */
|
/* unbound context is initialized here */
|
||||||
/* Unbound needs SSL to be init'ed this early when TLS is used. However we
|
/* 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. */
|
* don't know that till later so we will have to do this every time. */
|
||||||
|
|
||||||
SSL_library_init();
|
SSL_library_init();
|
||||||
result->unbound_ctx = NULL;
|
result->unbound_ctx = NULL;
|
||||||
if ((r = rebuild_ub_ctx(result)))
|
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->dns_root_servers);
|
||||||
getdns_list_destroy(context->suffix);
|
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 */
|
/* destroy the contexts */
|
||||||
if (context->unbound_ctx)
|
if (context->unbound_ctx)
|
||||||
|
@ -1116,7 +1144,7 @@ rebuild_ub_ctx(struct getdns_context* context) {
|
||||||
set_ub_dns_transport(context);
|
set_ub_dns_transport(context);
|
||||||
|
|
||||||
/* Set default trust anchor */
|
/* Set default trust anchor */
|
||||||
if (context->has_ta) {
|
if (context->trust_anchors) {
|
||||||
(void) ub_ctx_add_ta_file(
|
(void) ub_ctx_add_ta_file(
|
||||||
context->unbound_ctx, TRUST_ANCHOR_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_return_t
|
||||||
getdns_context_set_dnssec_trust_anchors(struct getdns_context *context,
|
getdns_context_set_dnssec_trust_anchors(
|
||||||
struct getdns_list * value)
|
getdns_context *context, getdns_list *value)
|
||||||
{
|
{
|
||||||
struct getdns_list *copy = NULL;
|
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
||||||
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;
|
|
||||||
|
|
||||||
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 */
|
} /* getdns_context_set_dnssec_trust_anchors */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -2432,8 +2463,6 @@ getdns_context_local_namespace_resolve(
|
||||||
{
|
{
|
||||||
getdns_context *context = dnsreq->context;
|
getdns_context *context = dnsreq->context;
|
||||||
host_name_addrs *hnas;
|
host_name_addrs *hnas;
|
||||||
uint8_t query_name[256];
|
|
||||||
size_t query_name_len = sizeof(query_name);
|
|
||||||
uint8_t lookup[256];
|
uint8_t lookup[256];
|
||||||
getdns_list empty_list = { 0 };
|
getdns_list empty_list = { 0 };
|
||||||
getdns_bindata bindata;
|
getdns_bindata bindata;
|
||||||
|
@ -2451,10 +2480,7 @@ getdns_context_local_namespace_resolve(
|
||||||
return GETDNS_RETURN_GENERIC_ERROR;
|
return GETDNS_RETURN_GENERIC_ERROR;
|
||||||
|
|
||||||
/*Do the lookup*/
|
/*Do the lookup*/
|
||||||
if (gldns_str2wire_dname_buf(dnsreq->name,query_name,&query_name_len))
|
(void)memcpy(lookup, dnsreq->name, dnsreq->name_len);
|
||||||
return GETDNS_RETURN_GENERIC_ERROR;
|
|
||||||
|
|
||||||
(void)memcpy(lookup, query_name, query_name_len);
|
|
||||||
canonicalize_dname(lookup);
|
canonicalize_dname(lookup);
|
||||||
|
|
||||||
if (!(hnas = (host_name_addrs *)
|
if (!(hnas = (host_name_addrs *)
|
||||||
|
@ -2470,8 +2496,8 @@ getdns_context_local_namespace_resolve(
|
||||||
if (!(*response = getdns_dict_create_with_context(context)))
|
if (!(*response = getdns_dict_create_with_context(context)))
|
||||||
return GETDNS_RETURN_GENERIC_ERROR;
|
return GETDNS_RETURN_GENERIC_ERROR;
|
||||||
|
|
||||||
bindata.size = query_name_len;
|
bindata.size = dnsreq->name_len;
|
||||||
bindata.data = query_name;
|
bindata.data = dnsreq->name;
|
||||||
if (getdns_dict_set_bindata(*response, "canonical_name", &bindata))
|
if (getdns_dict_set_bindata(*response, "canonical_name", &bindata))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
@ -2673,15 +2699,23 @@ getdns_context_get_suffix(getdns_context *context, getdns_list **value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
getdns_return_t
|
getdns_return_t
|
||||||
getdns_context_get_dnssec_trust_anchors(getdns_context *context,
|
getdns_context_get_dnssec_trust_anchors(
|
||||||
getdns_list **value) {
|
getdns_context *context, getdns_list **value)
|
||||||
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
{
|
||||||
RETURN_IF_NULL(value, GETDNS_RETURN_INVALID_PARAMETER);
|
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
||||||
*value = NULL;
|
RETURN_IF_NULL(value, GETDNS_RETURN_INVALID_PARAMETER);
|
||||||
if (context->dnssec_trust_anchors) {
|
|
||||||
return getdns_list_copy(context->dnssec_trust_anchors, value);
|
if (context->trust_anchors) {
|
||||||
}
|
if ((*value = getdns_list_create_with_context(context)))
|
||||||
return GETDNS_RETURN_GOOD;
|
_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
|
getdns_return_t
|
||||||
|
|
|
@ -138,7 +138,8 @@ struct getdns_context {
|
||||||
struct getdns_list *dns_root_servers;
|
struct getdns_list *dns_root_servers;
|
||||||
getdns_append_name_t append_name;
|
getdns_append_name_t append_name;
|
||||||
struct getdns_list *suffix;
|
struct getdns_list *suffix;
|
||||||
struct getdns_list *dnssec_trust_anchors;
|
uint8_t *trust_anchors;
|
||||||
|
size_t trust_anchors_len;
|
||||||
getdns_upstreams *upstreams;
|
getdns_upstreams *upstreams;
|
||||||
uint16_t limit_outstanding_queries;
|
uint16_t limit_outstanding_queries;
|
||||||
uint32_t dnssec_allowed_skew;
|
uint32_t dnssec_allowed_skew;
|
||||||
|
@ -168,7 +169,7 @@ struct getdns_context {
|
||||||
|
|
||||||
/* A tree to hold local host information*/
|
/* A tree to hold local host information*/
|
||||||
getdns_rbtree_t local_hosts;
|
getdns_rbtree_t local_hosts;
|
||||||
int has_ta; /* No DNSSEC without trust anchor */
|
|
||||||
int return_dnssec_status;
|
int return_dnssec_status;
|
||||||
|
|
||||||
/* which resolution type the contexts are configured for
|
/* which resolution type the contexts are configured for
|
||||||
|
@ -194,6 +195,8 @@ struct getdns_context {
|
||||||
struct filechg *fchg_resolvconf;
|
struct filechg *fchg_resolvconf;
|
||||||
struct filechg *fchg_hosts;
|
struct filechg *fchg_hosts;
|
||||||
|
|
||||||
|
uint8_t trust_anchors_spc[1024];
|
||||||
|
|
||||||
}; /* getdns_context */
|
}; /* getdns_context */
|
||||||
|
|
||||||
/** internal functions **/
|
/** internal functions **/
|
||||||
|
|
|
@ -70,6 +70,10 @@ struct getdns_dict
|
||||||
struct mem_funcs mf;
|
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
|
#endif
|
||||||
|
|
||||||
/* dict.h */
|
/* dict.h */
|
||||||
|
|
2508
src/dnssec.c
2508
src/dnssec.c
File diff suppressed because it is too large
Load Diff
|
@ -39,12 +39,14 @@
|
||||||
#define DNSSEC_H_
|
#define DNSSEC_H_
|
||||||
|
|
||||||
#include "getdns/getdns.h"
|
#include "getdns/getdns.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "gldns/gbuffer.h"
|
||||||
#include "types-internal.h"
|
#include "types-internal.h"
|
||||||
|
|
||||||
/* Do some additional requests to fetch the complete validation chain */
|
/* Do some additional requests to fetch the complete validation chain */
|
||||||
void priv_getdns_get_validation_chain(getdns_dns_req *dns_req);
|
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
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -38,8 +38,8 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unbound.h>
|
#include <unbound.h>
|
||||||
#include <ldns/ldns.h>
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "gldns/wire2str.h"
|
||||||
#include "context.h"
|
#include "context.h"
|
||||||
#include "types-internal.h"
|
#include "types-internal.h"
|
||||||
#include "util-internal.h"
|
#include "util-internal.h"
|
||||||
|
@ -137,6 +137,7 @@ submit_network_request(getdns_network_req *netreq)
|
||||||
{
|
{
|
||||||
getdns_return_t r;
|
getdns_return_t r;
|
||||||
getdns_dns_req *dns_req = netreq->owner;
|
getdns_dns_req *dns_req = netreq->owner;
|
||||||
|
char name[1024];
|
||||||
|
|
||||||
if (dns_req->context->resolution_type == GETDNS_RESOLUTION_RECURSING
|
if (dns_req->context->resolution_type == GETDNS_RESOLUTION_RECURSING
|
||||||
/* TODO: Until DNSSEC with the new async stub resolver is finished,
|
/* 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)))
|
dns_req->context->timeout, &dns_req->timeout)))
|
||||||
return r;
|
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,
|
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)) ?
|
netreq, ub_resolve_callback, &(netreq->unbound_id)) ?
|
||||||
GETDNS_RETURN_GENERIC_ERROR : GETDNS_RETURN_GOOD;
|
GETDNS_RETURN_GENERIC_ERROR : GETDNS_RETURN_GOOD;
|
||||||
}
|
}
|
||||||
|
@ -173,7 +176,7 @@ submit_network_request(getdns_network_req *netreq)
|
||||||
static getdns_return_t
|
static getdns_return_t
|
||||||
getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
|
getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
|
||||||
const char *name, uint16_t request_type, getdns_dict *extensions,
|
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_callback_t callbackfn, internal_cb_t internal_cb, int usenamespaces)
|
||||||
{
|
{
|
||||||
getdns_return_t r = GETDNS_RETURN_GOOD;
|
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))
|
if (!context || !name || (!callbackfn && !internal_cb))
|
||||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||||
|
|
||||||
if ((r = validate_dname(name)))
|
if ((r = priv_getdns_validate_dname(name)))
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (extensions && (r = validate_extensions(extensions)))
|
if (extensions && (r = priv_getdns_validate_extensions(extensions)))
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
/* Set up the context assuming we won't use the specified namespaces.
|
/* 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->user_callback = callbackfn;
|
||||||
req->internal_cb = internal_cb;
|
req->internal_cb = internal_cb;
|
||||||
|
|
||||||
if (transaction_id)
|
if (dnsreq_p)
|
||||||
*transaction_id = req->trans_id;
|
*dnsreq_p = req;
|
||||||
|
|
||||||
getdns_context_track_outbound_request(req);
|
getdns_context_track_outbound_request(req);
|
||||||
|
|
||||||
|
@ -254,12 +257,12 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
|
||||||
getdns_return_t
|
getdns_return_t
|
||||||
priv_getdns_general_loop(getdns_context *context, getdns_eventloop *loop,
|
priv_getdns_general_loop(getdns_context *context, getdns_eventloop *loop,
|
||||||
const char *name, uint16_t request_type, getdns_dict *extensions,
|
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)
|
getdns_callback_t callback, internal_cb_t internal_cb)
|
||||||
{
|
{
|
||||||
return getdns_general_ns(context, loop,
|
return getdns_general_ns(context, loop,
|
||||||
name, request_type, extensions,
|
name, request_type, extensions,
|
||||||
userarg, transaction_id, callback, internal_cb, 0);
|
userarg, dnsreq_p, callback, internal_cb, 0);
|
||||||
|
|
||||||
} /* getdns_general_loop */
|
} /* getdns_general_loop */
|
||||||
|
|
||||||
|
@ -271,6 +274,7 @@ priv_getdns_address_loop(getdns_context *context, getdns_eventloop *loop,
|
||||||
getdns_dict *my_extensions = extensions;
|
getdns_dict *my_extensions = extensions;
|
||||||
getdns_return_t r;
|
getdns_return_t r;
|
||||||
uint32_t value;
|
uint32_t value;
|
||||||
|
getdns_dns_req *dnsreq = NULL;
|
||||||
|
|
||||||
if (!my_extensions) {
|
if (!my_extensions) {
|
||||||
if (!(my_extensions=getdns_dict_create_with_context(context)))
|
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,
|
r = getdns_general_ns(context, loop,
|
||||||
name, GETDNS_RRTYPE_AAAA, my_extensions,
|
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)
|
if (my_extensions != extensions)
|
||||||
getdns_dict_destroy(my_extensions);
|
getdns_dict_destroy(my_extensions);
|
||||||
|
@ -304,6 +310,7 @@ priv_getdns_hostname_loop(getdns_context *context, getdns_eventloop *loop,
|
||||||
uint16_t req_type;
|
uint16_t req_type;
|
||||||
char name[1024];
|
char name[1024];
|
||||||
getdns_return_t retval;
|
getdns_return_t retval;
|
||||||
|
getdns_dns_req *dnsreq = NULL;
|
||||||
|
|
||||||
if ((retval =
|
if ((retval =
|
||||||
getdns_dict_get_bindata(address, "address_data",
|
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;
|
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
retval = priv_getdns_general_loop(context, loop, name, req_type,
|
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;
|
return retval;
|
||||||
} /* getdns_hostname_loop */
|
} /* 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,
|
const char *name, getdns_dict *extensions, void *userarg,
|
||||||
getdns_transaction_t * transaction_id, getdns_callback_t callback)
|
getdns_transaction_t * transaction_id, getdns_callback_t callback)
|
||||||
{
|
{
|
||||||
return getdns_general_ns(context, loop, name, GETDNS_RRTYPE_SRV,
|
getdns_return_t r;
|
||||||
extensions, userarg, transaction_id, callback, NULL, 1);
|
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 */
|
} /* getdns_service_loop */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -399,11 +413,16 @@ getdns_general(getdns_context *context,
|
||||||
void *userarg, getdns_transaction_t * transaction_id,
|
void *userarg, getdns_transaction_t * transaction_id,
|
||||||
getdns_callback_t callback)
|
getdns_callback_t callback)
|
||||||
{
|
{
|
||||||
if (!context) return GETDNS_RETURN_INVALID_PARAMETER;
|
getdns_return_t r;
|
||||||
return priv_getdns_general_loop(context, context->extension,
|
getdns_dns_req *dnsreq = NULL;
|
||||||
name, request_type, extensions,
|
|
||||||
userarg, transaction_id, callback, 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 */
|
} /* getdns_general */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -42,13 +42,13 @@
|
||||||
|
|
||||||
/* private inner helper used by sync and async */
|
/* 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);
|
void priv_getdns_check_dns_req_complete(getdns_dns_req *dns_req);
|
||||||
|
|
||||||
getdns_return_t
|
getdns_return_t
|
||||||
priv_getdns_general_loop(getdns_context *context, getdns_eventloop *loop,
|
priv_getdns_general_loop(getdns_context *context, getdns_eventloop *loop,
|
||||||
const char *name, uint16_t request_type, getdns_dict *extensions,
|
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_callback_t callbackfn, internal_cb_t internal_cb);
|
||||||
|
|
||||||
getdns_return_t
|
getdns_return_t
|
||||||
|
|
|
@ -74,6 +74,10 @@ struct getdns_list
|
||||||
struct mem_funcs mf;
|
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
|
#endif
|
||||||
|
|
||||||
/* list.h */
|
/* list.h */
|
||||||
|
|
|
@ -40,6 +40,13 @@
|
||||||
#include "gldns/str2wire.h"
|
#include "gldns/str2wire.h"
|
||||||
#include "gldns/gbuffer.h"
|
#include "gldns/gbuffer.h"
|
||||||
#include "gldns/pkthdr.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
|
static int
|
||||||
is_extension_set(getdns_dict *extensions, const char *extension)
|
is_extension_set(getdns_dict *extensions, const char *extension)
|
||||||
|
@ -49,6 +56,8 @@ is_extension_set(getdns_dict *extensions, const char *extension)
|
||||||
|
|
||||||
if (! extensions)
|
if (! extensions)
|
||||||
return 0;
|
return 0;
|
||||||
|
else if (extensions == dnssec_ok_checking_disabled)
|
||||||
|
return 0;
|
||||||
|
|
||||||
r = getdns_dict_get_int(extensions, extension, &value);
|
r = getdns_dict_get_int(extensions, extension, &value);
|
||||||
return r == GETDNS_RETURN_GOOD && value == GETDNS_EXTENSION_TRUE;
|
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->state = NET_REQ_NOT_SENT;
|
||||||
net_req->owner = owner;
|
net_req->owner = owner;
|
||||||
|
|
||||||
|
net_req->dnssec_status = GETDNS_DNSSEC_INDETERMINATE;
|
||||||
|
|
||||||
net_req->upstream = NULL;
|
net_req->upstream = NULL;
|
||||||
net_req->fd = -1;
|
net_req->fd = -1;
|
||||||
net_req->transport_count = owner->context->dns_transport_count;
|
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;
|
req->timeout.timeout_cb = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* free strduped name */
|
|
||||||
GETDNS_FREE(req->my_mf, req->name);
|
|
||||||
GETDNS_FREE(req->my_mf, req);
|
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");
|
= is_extension_set(extensions, "dnssec_return_only_secure");
|
||||||
int dnssec_return_validation_chain
|
int dnssec_return_validation_chain
|
||||||
= is_extension_set(extensions, "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
|
int edns_cookies
|
||||||
= is_extension_set(extensions, "edns_cookies");
|
= is_extension_set(extensions, "edns_cookies");
|
||||||
|
|
||||||
int dnssec_extension_set = dnssec_return_status
|
int dnssec_extension_set = dnssec_return_status
|
||||||
|| dnssec_return_only_secure || dnssec_return_validation_chain
|
|| dnssec_return_only_secure || dnssec_return_validation_chain
|
||||||
|| dnssec_ok_checking_disabled;;
|
|| (extensions == dnssec_ok_checking_disabled);
|
||||||
|
|
||||||
uint32_t edns_do_bit;
|
uint32_t edns_do_bit;
|
||||||
int edns_maximum_udp_payload_size;
|
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;
|
size_t max_query_sz, max_response_sz, netreq_sz, dnsreq_base_sz;
|
||||||
uint8_t *region;
|
uint8_t *region;
|
||||||
|
|
||||||
|
if (extensions == dnssec_ok_checking_disabled)
|
||||||
|
extensions = NULL;
|
||||||
|
|
||||||
have_add_opt_parameters = getdns_dict_get_dict(extensions,
|
have_add_opt_parameters = getdns_dict_get_dict(extensions,
|
||||||
"add_opt_parameters", &add_opt_parameters) == GETDNS_RETURN_GOOD;
|
"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->netreqs[1] = NULL;
|
||||||
|
|
||||||
result->my_mf = context->mf;
|
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->context = context;
|
||||||
result->loop = loop;
|
result->loop = loop;
|
||||||
result->canceled = 0;
|
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 },
|
{ "rname" , GETDNS_RDF_N_C },
|
||||||
{ "serial" , GETDNS_RDF_I4 },
|
{ "serial" , GETDNS_RDF_I4 },
|
||||||
{ "refresh" , GETDNS_RDF_I4 },
|
{ "refresh" , GETDNS_RDF_I4 },
|
||||||
{ "refresh" , GETDNS_RDF_I4 },
|
|
||||||
{ "retry" , 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[] = {
|
static priv_getdns_rdata_def mg_rdata[] = {
|
||||||
{ "mgmname" , GETDNS_RDF_N_C }};
|
{ "mgmname" , GETDNS_RDF_N_C }};
|
||||||
static priv_getdns_rdata_def mr_rdata[] = {
|
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;
|
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
|
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;
|
getdns_return_t r = GETDNS_RETURN_GOOD;
|
||||||
struct getdns_bindata *name;
|
struct getdns_bindata *name;
|
||||||
|
struct getdns_bindata *rdata_raw;
|
||||||
|
struct getdns_bindata *bindata;
|
||||||
struct getdns_dict *rdata;
|
struct getdns_dict *rdata;
|
||||||
uint32_t rr_type;
|
uint32_t rr_type;
|
||||||
ldns_rdf *owner;
|
uint32_t rr_class = GETDNS_RRCLASS_IN;
|
||||||
ldns_status s;
|
uint32_t rr_ttl = 0;
|
||||||
size_t pos;
|
uint32_t value;
|
||||||
uint8_t *wire;
|
const priv_getdns_rr_def *rr_def;
|
||||||
size_t wire_size;
|
const priv_getdns_rdata_def *rd_def;
|
||||||
|
int n_rdata_fields;
|
||||||
|
size_t j, rdata_size_mark;
|
||||||
|
|
||||||
assert(rr_dict);
|
assert(rr_dict);
|
||||||
assert(rr);
|
assert(buf);
|
||||||
|
|
||||||
*rr = ldns_rr_new();
|
if ((r = getdns_dict_get_bindata(rr_dict, "name", &name)))
|
||||||
if (! *rr)
|
goto error;
|
||||||
return GETDNS_RETURN_MEMORY_ERROR;
|
gldns_buffer_write(buf, name->data, name->size);
|
||||||
do {
|
|
||||||
r = getdns_dict_get_bindata(rr_dict, "name", &name);
|
if ((r = getdns_dict_get_int(rr_dict, "type", &rr_type)))
|
||||||
if (r != GETDNS_RETURN_GOOD)
|
goto error;
|
||||||
break;
|
gldns_buffer_write_u16(buf, (uint16_t)rr_type);
|
||||||
owner = ldns_rdf_new_frm_data(
|
|
||||||
LDNS_RDF_TYPE_DNAME, name->size, name->data);
|
(void) getdns_dict_get_int(rr_dict, "class", &rr_class);
|
||||||
if (! owner) {
|
gldns_buffer_write_u16(buf, (uint16_t)rr_class);
|
||||||
r = GETDNS_RETURN_MEMORY_ERROR;
|
|
||||||
|
(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;
|
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);
|
gldns_buffer_write_u16_at(buf, rdata_size_mark,
|
||||||
|
(uint16_t)(gldns_buffer_position(buf)-rdata_size_mark-2));
|
||||||
r = getdns_dict_get_int(rr_dict, "type", &rr_type);
|
}
|
||||||
if (r != GETDNS_RETURN_GOOD)
|
error:
|
||||||
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);
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,8 +32,9 @@
|
||||||
#ifndef RR_DICT_H_
|
#ifndef RR_DICT_H_
|
||||||
#define RR_DICT_H_
|
#define RR_DICT_H_
|
||||||
|
|
||||||
#include <ldns/ldns.h>
|
#include "config.h"
|
||||||
#include "getdns/getdns.h"
|
#include "getdns/getdns.h"
|
||||||
|
#include "gldns/gbuffer.h"
|
||||||
|
|
||||||
typedef uint8_t *(*priv_getdns_rdf_end_t)(
|
typedef uint8_t *(*priv_getdns_rdf_end_t)(
|
||||||
uint8_t *pkt, uint8_t *pkt_end, uint8_t *rdf);
|
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 */
|
/* draft-levine-dnsextlang'ish type rr and rdata definitions */
|
||||||
|
|
||||||
#define GETDNS_RDF_INTEGER 0x010000
|
#define GETDNS_RDF_INTEGER 0x010000
|
||||||
#define GETDNS_RDF_BINDATA 0x020000
|
#define GETDNS_RDF_BINDATA 0x020000
|
||||||
#define GETDNS_RDF_DNAME 0x060000
|
#define GETDNS_RDF_DNAME 0x060000
|
||||||
#define GETDNS_RDF_REPEAT 0x100000
|
#define GETDNS_RDF_COMPRESSED 0x080000
|
||||||
|
#define GETDNS_RDF_REPEAT 0x100000
|
||||||
|
|
||||||
#define GETDNS_RDF_FIXEDSZ 0x0000FF
|
#define GETDNS_RDF_FIXEDSZ 0x0000FF
|
||||||
#define GETDNS_RDF_LEN_VAL 0x00FF00
|
#define GETDNS_RDF_LEN_VAL 0x00FF00
|
||||||
|
|
||||||
typedef enum priv_getdns_rdf_wf_type {
|
typedef enum priv_getdns_rdf_wf_type {
|
||||||
GETDNS_RDF_N = 0x060000, /* N */
|
GETDNS_RDF_N = 0x060000, /* N */
|
||||||
GETDNS_RDF_N_A = GETDNS_RDF_N, /* N[A] */
|
GETDNS_RDF_N_A = 0x060000, /* N[A] */
|
||||||
GETDNS_RDF_N_A_C = GETDNS_RDF_N, /* N[A,C] */
|
GETDNS_RDF_N_C = 0x0E0000, /* N[C] */
|
||||||
GETDNS_RDF_N_C = GETDNS_RDF_N, /* N[C] */
|
GETDNS_RDF_N_A_C = 0x0E0000, /* N[A,C] */
|
||||||
GETDNS_RDF_N_M = 0x160000, /* N[M] */
|
GETDNS_RDF_N_M = 0x160000, /* N[M] */
|
||||||
|
|
||||||
GETDNS_RDF_I1 = 0x010001, /* I1 */
|
GETDNS_RDF_I1 = 0x010001, /* I1 */
|
||||||
GETDNS_RDF_I2 = 0x010002, /* I2 */
|
GETDNS_RDF_I2 = 0x010002, /* I2 */
|
||||||
GETDNS_RDF_I4 = 0x010004, /* I4 */
|
GETDNS_RDF_I4 = 0x010004, /* I4 */
|
||||||
|
|
||||||
GETDNS_RDF_T = 0x010004, /* T */
|
GETDNS_RDF_T = 0x010004, /* T */
|
||||||
/* Time values using ring arithmetics
|
/* Time values using ring arithmetics
|
||||||
* (rfc1982) for TKEY['inception'],
|
* (rfc1982) for TKEY['inception'],
|
||||||
* TKEY['expiration'],
|
* TKEY['expiration'],
|
||||||
* RRSIG['inception'] and
|
* RRSIG['inception'] and
|
||||||
* RRSIG['expiration']
|
* RRSIG['expiration']
|
||||||
*/
|
*/
|
||||||
GETDNS_RDF_T6 = 0x020006, /* T6 */
|
GETDNS_RDF_T6 = 0x020006, /* T6 */
|
||||||
/* Absolute time values (since epoch)
|
/* Absolute time values (since epoch)
|
||||||
* for TSIG['time_signed']
|
* for TSIG['time_signed']
|
||||||
*/
|
*/
|
||||||
|
|
||||||
GETDNS_RDF_A = 0x020004, /* A */
|
GETDNS_RDF_A = 0x020004, /* A */
|
||||||
GETDNS_RDF_AA = 0x020008, /* AA */
|
GETDNS_RDF_AA = 0x020008, /* AA */
|
||||||
GETDNS_RDF_AAAA = 0x020010, /* AAAA */
|
GETDNS_RDF_AAAA = 0x020010, /* AAAA */
|
||||||
|
|
||||||
GETDNS_RDF_S = 0x020100, /* S */
|
GETDNS_RDF_S = 0x020100, /* S */
|
||||||
GETDNS_RDF_S_L = 0x020000, /* S[L] */
|
GETDNS_RDF_S_L = 0x020000, /* S[L] */
|
||||||
GETDNS_RDF_S_M = 0x120100, /* S[M] */
|
GETDNS_RDF_S_M = 0x120100, /* S[M] */
|
||||||
|
|
||||||
GETDNS_RDF_B = 0x020000, /* B */
|
GETDNS_RDF_B = 0x020000, /* B */
|
||||||
GETDNS_RDF_B_C = 0x020100, /* B[C] */
|
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 = 0x020000, /* X */
|
||||||
GETDNS_RDF_X_C = 0x020100, /* X[C] */
|
GETDNS_RDF_X_C = 0x020100, /* X[C] */
|
||||||
/* for NSEC3['salt'] and
|
/* for NSEC3['salt'] and
|
||||||
* NSEC3PARAM['salt'].
|
* NSEC3PARAM['salt'].
|
||||||
*/
|
*/
|
||||||
GETDNS_RDF_X_S = 0x020200, /* X[S] */
|
GETDNS_RDF_X_S = 0x020200, /* X[S] */
|
||||||
/* for OPT['option_data'],
|
/* for OPT['option_data'],
|
||||||
* TKEY['key_data'],
|
* TKEY['key_data'],
|
||||||
* TKEY['other_data'],
|
* TKEY['other_data'],
|
||||||
|
@ -109,12 +111,12 @@ typedef enum priv_getdns_rdf_wf_type {
|
||||||
* Although those do not have an
|
* Although those do not have an
|
||||||
* official presentation format.
|
* official presentation format.
|
||||||
*/
|
*/
|
||||||
GETDNS_RDF_X6 = 0x020006,
|
GETDNS_RDF_X6 = 0x020006,
|
||||||
GETDNS_RDF_X8 = 0x020008,
|
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;
|
} priv_getdns_rdf_type;
|
||||||
|
|
||||||
typedef struct priv_getdns_rdata_def {
|
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);
|
const priv_getdns_rr_def *priv_getdns_rr_def_lookup(uint16_t rr_type);
|
||||||
|
|
||||||
getdns_return_t priv_getdns_create_rr_from_dict(
|
getdns_return_t priv_getdns_rr_dict2wire(
|
||||||
struct getdns_dict *rr_dict, ldns_rr **rr);
|
getdns_dict *rr_dict, gldns_buffer *buf);
|
||||||
|
|
||||||
const char *priv_getdns_rr_type_name(int rr_type);
|
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);
|
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 *
|
||||||
priv_getdns_rr_iter_next(priv_getdns_rr_iter *i)
|
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,
|
priv_getdns_rr_iter *priv_getdns_rr_iter_init(priv_getdns_rr_iter *i,
|
||||||
uint8_t *pkt, size_t pkt_len);
|
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);
|
priv_getdns_rr_iter *priv_getdns_rr_iter_next(priv_getdns_rr_iter *i);
|
||||||
|
|
||||||
uint8_t *priv_getdns_owner_if_or_as_decompressed(
|
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.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <openssl/err.h>
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include "stub.h"
|
#include "stub.h"
|
||||||
|
@ -40,7 +41,6 @@
|
||||||
#include "gldns/str2wire.h"
|
#include "gldns/str2wire.h"
|
||||||
#include "rr-iter.h"
|
#include "rr-iter.h"
|
||||||
#include "context.h"
|
#include "context.h"
|
||||||
#include <ldns/util.h>
|
|
||||||
#include "util-internal.h"
|
#include "util-internal.h"
|
||||||
#include "general.h"
|
#include "general.h"
|
||||||
|
|
||||||
|
@ -273,21 +273,6 @@ create_starttls_request(getdns_dns_req *dnsreq, getdns_upstream *upstream,
|
||||||
return 1;
|
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
|
static int
|
||||||
is_starttls_response(getdns_network_req *netreq)
|
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;
|
priv_getdns_rdf_iter rdf_iter_storage, *rdf_iter;
|
||||||
uint16_t rr_type;
|
uint16_t rr_type;
|
||||||
gldns_pkt_section section;
|
gldns_pkt_section section;
|
||||||
uint8_t starttls_name_space[256],
|
uint8_t starttls_name_space[256], *starttls_name;
|
||||||
*starttls_name = starttls_name_space;
|
|
||||||
uint8_t owner_name_space[256], *owner_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*/
|
/* Servers that are not STARTTLS aware will refuse the CH query*/
|
||||||
if (GLDNS_RCODE_NOERROR != GLDNS_RCODE_WIRE(netreq->response))
|
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)
|
if (GLDNS_ANCOUNT(netreq->response) != 1)
|
||||||
return 0;
|
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
|
for ( rr_iter = priv_getdns_rr_iter_init(&rr_iter_storage
|
||||||
, netreq->response
|
, netreq->response
|
||||||
, netreq->response_len)
|
, netreq->response_len)
|
||||||
|
@ -318,25 +300,25 @@ is_starttls_response(getdns_network_req *netreq)
|
||||||
|
|
||||||
section = priv_getdns_rr_iter_section(rr_iter);
|
section = priv_getdns_rr_iter_section(rr_iter);
|
||||||
rr_type = gldns_read_uint16(rr_iter->rr_type);
|
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;
|
continue;
|
||||||
|
|
||||||
owner_name = priv_getdns_owner_if_or_as_decompressed(
|
owner_name = priv_getdns_owner_if_or_as_decompressed(
|
||||||
rr_iter, owner_name_space, &owner_name_len);
|
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;
|
continue;
|
||||||
|
|
||||||
if (!(rdf_iter = priv_getdns_rdf_iter_init(
|
if (!(rdf_iter = priv_getdns_rdf_iter_init(
|
||||||
&rdf_iter_storage, rr_iter)))
|
&rdf_iter_storage, rr_iter)))
|
||||||
continue;
|
continue;
|
||||||
/* re-use the starttls_name for the response dname*/
|
|
||||||
starttls_name = priv_getdns_rdf_if_or_as_decompressed(
|
if ((starttls_name = priv_getdns_rdf_if_or_as_decompressed(
|
||||||
rdf_iter,starttls_name_space,&starttls_name_len);
|
rdf_iter, starttls_name_space, &starttls_name_len)) &&
|
||||||
if (dname_equal(starttls_name, owner_name))
|
priv_getdns_dname_equal(starttls_name, owner_name))
|
||||||
return 1;
|
return 1;
|
||||||
else
|
|
||||||
return 0;
|
return 0;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1144,10 +1126,6 @@ stub_udp_read_cb(void *userarg)
|
||||||
}
|
}
|
||||||
netreq->response_len = read;
|
netreq->response_len = read;
|
||||||
dnsreq->upstreams->current = 0;
|
dnsreq->upstreams->current = 0;
|
||||||
|
|
||||||
/* TODO: DNSSEC */
|
|
||||||
netreq->secure = 0;
|
|
||||||
netreq->bogus = 0;
|
|
||||||
done:
|
done:
|
||||||
netreq->state = NET_REQ_FINISHED;
|
netreq->state = NET_REQ_FINISHED;
|
||||||
priv_getdns_check_dns_req_complete(dnsreq);
|
priv_getdns_check_dns_req_complete(dnsreq);
|
||||||
|
@ -1227,10 +1205,6 @@ stub_tcp_read_cb(void *userarg)
|
||||||
netreq->tcp.read_buf = NULL;
|
netreq->tcp.read_buf = NULL;
|
||||||
dnsreq->upstreams->current = 0;
|
dnsreq->upstreams->current = 0;
|
||||||
|
|
||||||
/* TODO: DNSSEC */
|
|
||||||
netreq->secure = 0;
|
|
||||||
netreq->bogus = 0;
|
|
||||||
|
|
||||||
stub_cleanup(netreq);
|
stub_cleanup(netreq);
|
||||||
close(netreq->fd);
|
close(netreq->fd);
|
||||||
priv_getdns_check_dns_req_complete(dnsreq);
|
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.*/
|
* on a working connection until we hit a problem.*/
|
||||||
upstream->upstreams->current = 0;
|
upstream->upstreams->current = 0;
|
||||||
|
|
||||||
/* TODO: DNSSEC */
|
|
||||||
netreq->secure = 0;
|
|
||||||
netreq->bogus = 0;
|
|
||||||
|
|
||||||
if (netreq->owner == upstream->starttls_req) {
|
if (netreq->owner == upstream->starttls_req) {
|
||||||
dnsreq = netreq->owner;
|
dnsreq = netreq->owner;
|
||||||
if (is_starttls_response(netreq)) {
|
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");
|
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,
|
void callback(getdns_context *context, getdns_callback_type_t callback_type,
|
||||||
getdns_dict *response, void *userarg, getdns_transaction_t trans_id)
|
getdns_dict *response, void *userarg, getdns_transaction_t trans_id)
|
||||||
{
|
{
|
||||||
|
@ -178,6 +262,7 @@ void callback(getdns_context *context, getdns_callback_type_t callback_type,
|
||||||
: getdns_pretty_print_dict(response))) {
|
: getdns_pretty_print_dict(response))) {
|
||||||
|
|
||||||
fprintf(stdout, "ASYNC response:\n%s\n", response_str);
|
fprintf(stdout, "ASYNC response:\n%s\n", response_str);
|
||||||
|
validate_chain(response);
|
||||||
free(response_str);
|
free(response_str);
|
||||||
}
|
}
|
||||||
fprintf(stdout,
|
fprintf(stdout,
|
||||||
|
@ -617,6 +702,7 @@ main(int argc, char **argv)
|
||||||
|
|
||||||
fprintf( stdout, "SYNC response:\n%s\n"
|
fprintf( stdout, "SYNC response:\n%s\n"
|
||||||
, response_str);
|
, response_str);
|
||||||
|
validate_chain(response);
|
||||||
free(response_str);
|
free(response_str);
|
||||||
} else {
|
} else {
|
||||||
r = GETDNS_RETURN_MEMORY_ERROR;
|
r = GETDNS_RETURN_MEMORY_ERROR;
|
||||||
|
|
|
@ -189,9 +189,8 @@ typedef struct getdns_network_req
|
||||||
/* request class */
|
/* request class */
|
||||||
uint16_t request_class;
|
uint16_t request_class;
|
||||||
|
|
||||||
/* result */
|
/* dnssec status */
|
||||||
int secure;
|
int dnssec_status;
|
||||||
int bogus;
|
|
||||||
|
|
||||||
/* For stub resolving */
|
/* For stub resolving */
|
||||||
struct getdns_upstream *upstream;
|
struct getdns_upstream *upstream;
|
||||||
|
@ -232,7 +231,8 @@ typedef struct getdns_dns_req {
|
||||||
getdns_rbnode_t node;
|
getdns_rbnode_t node;
|
||||||
|
|
||||||
/* name */
|
/* name */
|
||||||
char *name;
|
uint8_t name[256];
|
||||||
|
size_t name_len;
|
||||||
|
|
||||||
/* canceled flag */
|
/* canceled flag */
|
||||||
int canceled;
|
int canceled;
|
||||||
|
@ -319,6 +319,8 @@ typedef struct getdns_dns_req {
|
||||||
|
|
||||||
/* utility methods */
|
/* utility methods */
|
||||||
|
|
||||||
|
extern getdns_dict *dnssec_ok_checking_disabled;
|
||||||
|
|
||||||
/* dns request utils */
|
/* dns request utils */
|
||||||
getdns_dns_req *dns_req_new(getdns_context *context, getdns_eventloop *loop,
|
getdns_dns_req *dns_req_new(getdns_context *context, getdns_eventloop *loop,
|
||||||
const char *name, uint16_t request_type, getdns_dict *extensions);
|
const char *name, uint16_t request_type, getdns_dict *extensions);
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <ctype.h>
|
||||||
#include <unbound.h>
|
#include <unbound.h>
|
||||||
#include "getdns/getdns.h"
|
#include "getdns/getdns.h"
|
||||||
#include "dict.h"
|
#include "dict.h"
|
||||||
|
@ -60,7 +61,6 @@
|
||||||
static getdns_extension_format extformats[] = {
|
static getdns_extension_format extformats[] = {
|
||||||
{"add_opt_parameters", t_dict},
|
{"add_opt_parameters", t_dict},
|
||||||
{"add_warning_for_bad_dns", t_int},
|
{"add_warning_for_bad_dns", t_int},
|
||||||
{"dnssec_ok_checking_disabled", t_int},
|
|
||||||
{"dnssec_return_only_secure", t_int},
|
{"dnssec_return_only_secure", t_int},
|
||||||
{"dnssec_return_status", t_int},
|
{"dnssec_return_status", t_int},
|
||||||
{"dnssec_return_validation_chain", 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 *
|
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_dict *rr_dict, *rdata_dict;
|
||||||
getdns_bindata bindata;
|
getdns_bindata bindata;
|
||||||
|
@ -192,7 +192,7 @@ priv_getdns_rr_iter2rr_dict(getdns_context *context, priv_getdns_rr_iter *i)
|
||||||
uint16_t rr_type;
|
uint16_t rr_type;
|
||||||
|
|
||||||
assert(i);
|
assert(i);
|
||||||
if (!(rr_dict = getdns_dict_create_with_context(context)))
|
if (!(rr_dict = _getdns_dict_create_with_mf(mf)))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
bindata.data = priv_getdns_owner_if_or_as_decompressed(
|
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;
|
goto error;
|
||||||
}
|
}
|
||||||
if (!(rdata_dict = getdns_dict_create_with_context(context)))
|
if (!(rdata_dict = _getdns_dict_create_with_mf(mf)))
|
||||||
goto error;
|
return NULL;
|
||||||
|
|
||||||
if (i->rr_type + 10 <= i->nxt) {
|
if (i->rr_type + 10 <= i->nxt) {
|
||||||
bindata.size = i->nxt - (i->rr_type + 10);
|
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 */
|
/* list with rdf values */
|
||||||
|
|
||||||
if (! repeat_list && !(repeat_list =
|
if (! repeat_list && !(repeat_list =
|
||||||
getdns_list_create_with_context(context)))
|
_getdns_list_create_with_mf(mf)))
|
||||||
|
|
||||||
goto rdata_error;
|
goto rdata_error;
|
||||||
|
|
||||||
switch (val_type) {
|
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_dict) {
|
||||||
if (! repeat_list && !(repeat_list =
|
if (! repeat_list && !(repeat_list =
|
||||||
getdns_list_create_with_context(context)))
|
_getdns_list_create_with_mf(mf)))
|
||||||
goto rdata_error;
|
goto rdata_error;
|
||||||
|
|
||||||
if (getdns_list_append_dict(
|
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;
|
repeat_dict = NULL;
|
||||||
}
|
}
|
||||||
if (!(repeat_dict =
|
if (!(repeat_dict =
|
||||||
getdns_dict_create_with_context(context)))
|
_getdns_dict_create_with_mf(mf)))
|
||||||
goto rdata_error;
|
goto rdata_error;
|
||||||
}
|
}
|
||||||
assert(repeat_dict);
|
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_dict) {
|
||||||
if (!repeat_list && !(repeat_list =
|
if (!repeat_list && !(repeat_list =
|
||||||
getdns_list_create_with_context(context)))
|
_getdns_list_create_with_mf(mf)))
|
||||||
goto rdata_error;
|
goto rdata_error;
|
||||||
if (getdns_list_append_dict(repeat_list, repeat_dict))
|
if (getdns_list_append_dict(repeat_list, repeat_dict))
|
||||||
goto rdata_error;
|
goto rdata_error;
|
||||||
|
@ -422,8 +423,8 @@ error:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
int
|
||||||
dname_equal(uint8_t *s1, uint8_t *s2)
|
priv_getdns_dname_equal(const uint8_t *s1, const uint8_t *s2)
|
||||||
{
|
{
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
@ -432,7 +433,8 @@ dname_equal(uint8_t *s1, uint8_t *s2)
|
||||||
else if (!*s1)
|
else if (!*s1)
|
||||||
return 1;
|
return 1;
|
||||||
for (i = *s1++, s2++; i > 0; i--, s1++, s2++)
|
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;
|
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)))
|
if ((r = getdns_dict_set_dict(result, "header", header)))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
(void) gldns_str2wire_dname_buf(
|
canonical_name = req->owner->name;
|
||||||
req->owner->name, canonical_name_space, &canonical_name_len);
|
|
||||||
|
|
||||||
for ( rr_iter = priv_getdns_rr_iter_init(&rr_iter_storage
|
for ( rr_iter = priv_getdns_rr_iter_init(&rr_iter_storage
|
||||||
, req->response
|
, 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)) {
|
; rr_iter = priv_getdns_rr_iter_next(rr_iter)) {
|
||||||
|
|
||||||
if (!set_dict(&rr_dict,
|
if (!set_dict(&rr_dict,
|
||||||
priv_getdns_rr_iter2rr_dict(context, rr_iter)))
|
priv_getdns_rr_iter2rr_dict(&context->mf, rr_iter)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
section = priv_getdns_rr_iter_section(rr_iter);
|
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(
|
owner_name = priv_getdns_owner_if_or_as_decompressed(
|
||||||
rr_iter, owner_name_space, &owner_name_len);
|
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;
|
continue;
|
||||||
|
|
||||||
if (!(rdf_iter = priv_getdns_rdf_iter_init(
|
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(
|
owner_name = priv_getdns_owner_if_or_as_decompressed(
|
||||||
rr_iter, owner_name_space, &owner_name_len);
|
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;
|
continue;
|
||||||
|
|
||||||
if (!(rdf_iter = priv_getdns_rdf_iter_init(
|
if (!(rdf_iter = priv_getdns_rdf_iter_init(
|
||||||
|
@ -733,21 +734,22 @@ create_getdns_response(getdns_dns_req *completed_request)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
nreplies++;
|
nreplies++;
|
||||||
if (netreq->secure)
|
if (netreq->dnssec_status == GETDNS_DNSSEC_SECURE)
|
||||||
nsecure++;
|
nsecure++;
|
||||||
else if (! netreq->bogus)
|
else if (! netreq->dnssec_status != GETDNS_DNSSEC_BOGUS)
|
||||||
ninsecure++;
|
ninsecure++;
|
||||||
if (dnssec_return_status && netreq->bogus)
|
|
||||||
|
if (dnssec_return_status &&
|
||||||
|
netreq->dnssec_status == GETDNS_DNSSEC_BOGUS)
|
||||||
nbogus++;
|
nbogus++;
|
||||||
else if (GLDNS_RCODE_NOERROR ==
|
|
||||||
GLDNS_RCODE_WIRE(netreq->response))
|
|
||||||
nanswers++;
|
|
||||||
|
|
||||||
if (! completed_request->dnssec_return_validation_chain) {
|
if (! completed_request->dnssec_return_validation_chain) {
|
||||||
if (dnssec_return_status && netreq->bogus)
|
if (dnssec_return_status &&
|
||||||
|
netreq->dnssec_status == GETDNS_DNSSEC_BOGUS)
|
||||||
continue;
|
continue;
|
||||||
else if (completed_request->dnssec_return_only_secure
|
else if (completed_request->dnssec_return_only_secure
|
||||||
&& ! netreq->secure)
|
&& netreq->dnssec_status != GETDNS_DNSSEC_SECURE)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!(reply = priv_getdns_create_reply_dict(context,
|
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))
|
result, "canonical_name", canonical_name))
|
||||||
goto error;
|
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 ||
|
if (dnssec_return_status ||
|
||||||
completed_request->dnssec_return_validation_chain) {
|
completed_request->dnssec_return_validation_chain) {
|
||||||
|
|
||||||
if (getdns_dict_set_int(reply, "dnssec_status",
|
if (getdns_dict_set_int(reply, "dnssec_status",
|
||||||
( netreq->secure ? GETDNS_DNSSEC_SECURE
|
netreq->dnssec_status))
|
||||||
: netreq->bogus ? GETDNS_DNSSEC_BOGUS
|
|
||||||
: rrsigs_in_answer &&
|
|
||||||
context->has_ta ? GETDNS_DNSSEC_INDETERMINATE
|
|
||||||
: GETDNS_DNSSEC_INSECURE )))
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -830,7 +835,7 @@ extformatcmp(const void *a, const void *b)
|
||||||
|
|
||||||
/*---------------------------------------- validate_extensions */
|
/*---------------------------------------- validate_extensions */
|
||||||
getdns_return_t
|
getdns_return_t
|
||||||
validate_extensions(struct getdns_dict * extensions)
|
priv_getdns_validate_extensions(struct getdns_dict * extensions)
|
||||||
{
|
{
|
||||||
struct getdns_dict_item *item;
|
struct getdns_dict_item *item;
|
||||||
getdns_extension_format *extformat;
|
getdns_extension_format *extformat;
|
||||||
|
@ -852,16 +857,18 @@ validate_extensions(struct getdns_dict * extensions)
|
||||||
return GETDNS_RETURN_EXTENSION_MISFORMAT;
|
return GETDNS_RETURN_EXTENSION_MISFORMAT;
|
||||||
}
|
}
|
||||||
return GETDNS_RETURN_GOOD;
|
return GETDNS_RETURN_GOOD;
|
||||||
} /* validate_extensions */
|
} /* priv_getdns_validate_extensions */
|
||||||
|
|
||||||
getdns_return_t
|
getdns_return_t
|
||||||
getdns_apply_network_result(getdns_network_req* netreq,
|
getdns_apply_network_result(getdns_network_req* netreq,
|
||||||
struct ub_result* ub_res)
|
struct ub_result* ub_res)
|
||||||
{
|
{
|
||||||
size_t dname_len;
|
if (ub_res->bogus)
|
||||||
|
netreq->dnssec_status = GETDNS_DNSSEC_BOGUS;
|
||||||
netreq->secure = ub_res->secure;
|
else if (ub_res->secure)
|
||||||
netreq->bogus = ub_res->bogus;
|
netreq->dnssec_status = GETDNS_DNSSEC_SECURE;
|
||||||
|
else if (netreq->owner->context->trust_anchors)
|
||||||
|
netreq->dnssec_status = GETDNS_DNSSEC_INSECURE;
|
||||||
|
|
||||||
if (ub_res == NULL) /* Timeout */
|
if (ub_res == NULL) /* Timeout */
|
||||||
return GETDNS_RETURN_GOOD;
|
return GETDNS_RETURN_GOOD;
|
||||||
|
@ -900,24 +907,24 @@ getdns_apply_network_result(getdns_network_req* netreq,
|
||||||
GLDNS_RA_SET(netreq->response);
|
GLDNS_RA_SET(netreq->response);
|
||||||
GLDNS_RCODE_SET(netreq->response, ub_res->rcode);
|
GLDNS_RCODE_SET(netreq->response, ub_res->rcode);
|
||||||
|
|
||||||
dname_len = netreq->max_udp_payload_size - GLDNS_HEADER_SIZE;
|
(void) memcpy( netreq->response + GLDNS_HEADER_SIZE
|
||||||
if (gldns_str2wire_dname_buf(netreq->owner->name,
|
, netreq->owner->name, netreq->owner->name_len);
|
||||||
netreq->response + GLDNS_HEADER_SIZE, &dname_len))
|
|
||||||
return GETDNS_RETURN_GENERIC_ERROR;
|
|
||||||
|
|
||||||
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);
|
, 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->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;
|
return GETDNS_RETURN_GOOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
getdns_return_t
|
getdns_return_t
|
||||||
validate_dname(const char* dname) {
|
priv_getdns_validate_dname(const char* dname) {
|
||||||
int len;
|
int len;
|
||||||
int label_len;
|
int label_len;
|
||||||
const char* s;
|
const char* s;
|
||||||
|
@ -980,7 +987,150 @@ validate_dname(const char* dname) {
|
||||||
return GETDNS_RETURN_BAD_DOMAIN_NAME;
|
return GETDNS_RETURN_BAD_DOMAIN_NAME;
|
||||||
}
|
}
|
||||||
return GETDNS_RETURN_GOOD;
|
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 */
|
/* util-internal.c */
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
#define SCHED_DEBUG 0
|
#define SCHED_DEBUG 0
|
||||||
#define WIRE_DEBUG 0
|
#define WIRE_DEBUG 0
|
||||||
#define STUB_DEBUG 0
|
#define STUB_DEBUG 0
|
||||||
|
#define SEC_DEBUG 1
|
||||||
|
|
||||||
#ifdef S_SPLINT_S
|
#ifdef S_SPLINT_S
|
||||||
# define INLINE
|
# define INLINE
|
||||||
|
@ -122,7 +123,7 @@ getdns_return_t sockaddr_to_dict(struct getdns_context *context,
|
||||||
struct sockaddr_storage *sockaddr, struct getdns_dict ** output);
|
struct sockaddr_storage *sockaddr, struct getdns_dict ** output);
|
||||||
|
|
||||||
getdns_dict *
|
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_dns_req;
|
||||||
struct getdns_dict *create_getdns_response(struct getdns_dns_req *completed_request);
|
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_dict *priv_getdns_create_reply_dict(getdns_context *context,
|
||||||
getdns_network_req *req, getdns_list *just_addrs, int *rrsigs_in_answer);
|
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
|
* 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_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.
|
* @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 { \
|
#define DEBUG_ON(...) do { \
|
||||||
struct timeval tv; \
|
struct timeval tv; \
|
||||||
|
@ -170,6 +179,13 @@ getdns_return_t validate_extensions(struct getdns_dict * extensions);
|
||||||
#define DEBUG_STUB(...) DEBUG_OFF(__VA_ARGS__)
|
#define DEBUG_STUB(...) DEBUG_OFF(__VA_ARGS__)
|
||||||
#endif
|
#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(
|
INLINE getdns_eventloop_event *getdns_eventloop_event_init(
|
||||||
getdns_eventloop_event *ev,void *userarg, getdns_eventloop_callback read_cb,
|
getdns_eventloop_event *ev,void *userarg, getdns_eventloop_callback read_cb,
|
||||||
getdns_eventloop_callback write_cb, getdns_eventloop_callback timeout_cb)
|
getdns_eventloop_callback write_cb, getdns_eventloop_callback timeout_cb)
|
||||||
|
|
Loading…
Reference in New Issue