Start with fetching root-anchors remotely

Also lays the foundation for looking up upstreams by name and DANE authentication of upstreams.
This commit is contained in:
Willem Toorop 2017-06-28 20:35:30 +02:00
parent ff1ebbf671
commit fb267938c3
5 changed files with 101 additions and 1 deletions

View File

@ -1467,6 +1467,9 @@ getdns_context_create_with_extended_memory_functions(
result->return_call_reporting = 0;
result->specify_class = GETDNS_RRCLASS_IN;
result->sys_ctxt = NULL;
result->ta_notify = NULL;
/* state data used to detect changes to the system config files
*/
result->fchg_resolvconf = NULL;
@ -1596,6 +1599,10 @@ getdns_context_destroy(struct getdns_context *context)
return;
context->destroying = 1;
if (context->sys_ctxt)
getdns_context_destroy(context->sys_ctxt);
/* cancel all outstanding requests */
cancel_outstanding_requests(context);

View File

@ -95,7 +95,8 @@ typedef enum getdns_conn_state {
typedef enum getdns_tasrc {
GETDNS_TASRC_NONE,
GETDNS_TASRC_ZONE,
GETDNS_TASRC_XML
GETDNS_TASRC_XML,
GETDNS_TASRC_FAILED
} getdns_tasrc;
typedef enum getdns_tsig_algo {
@ -371,6 +372,18 @@ struct getdns_context {
unsigned return_call_reporting : 1;
uint16_t specify_class;
/*
* Context for doing system queries.
* For example to resolve data.iana.org or to resolver the addresses
* of upstreams without specified addresses.
*/
getdns_context *sys_ctxt;
/* List of dnsreqs that want to be notified when we have fetched a
* trust anchor from data.iana.org.
*/
getdns_dns_req *ta_notify;
/*
* state data used to detect changes to the system config files
*/

View File

@ -2980,6 +2980,14 @@ static void append_empty_ds2val_chain_list(
getdns_dict_destroy(rr_dict);
}
static void data_iana_org_a(getdns_dns_req *dnsreq)
{
getdns_dns_req *orig_dnsreq = (getdns_dns_req *)dnsreq->user_pointer;
DEBUG_SEC("Address for data.iana.org. found\n");
_getdns_context_cancel_request(dnsreq);
check_chain_complete(orig_dnsreq->chain);
}
static void check_chain_complete(chain_head *chain)
{
getdns_dns_req *dnsreq;
@ -2999,6 +3007,70 @@ static void check_chain_complete(chain_head *chain)
dnsreq = chain->netreq->owner;
context = dnsreq->context;
if (dnsreq->waiting_for_ta) {
getdns_dns_req **d;
for (d = &context->ta_notify; *d; d = &(*d)->ta_notify) {
if (*d == dnsreq) {
*d = dnsreq->ta_notify;
dnsreq->ta_notify = NULL;
dnsreq->waiting_for_ta = 0;
break;
}
}
} else if (context->trust_anchors_source == GETDNS_TASRC_NONE) {
DEBUG_SEC("Need to fetch a trust anchor\n");
dnsreq->waiting_for_ta = 1;
dnsreq->ta_notify = context->ta_notify;
context->ta_notify = dnsreq;
if (dnsreq->ta_notify)
return; /* Wait for the notify callback */
else if (!context->sys_ctxt) {
if (getdns_context_create_with_extended_memory_functions(
&context->sys_ctxt, 1,
context->mf.mf_arg,
context->mf.mf.ext.malloc,
context->mf.mf.ext.realloc,
context->mf.mf.ext.free)) {
DEBUG_SEC("TA fetch: Error creating system context\n");
} else if (getdns_context_set_eventloop(
context->sys_ctxt, context->extension) ||
getdns_context_set_resolution_type(
context->sys_ctxt, GETDNS_RESOLUTION_STUB)
) {
DEBUG_SEC("TA fetch: Error configuring system context\n");
getdns_context_destroy(context->sys_ctxt);
context->sys_ctxt = NULL;
}
}
if (context->sys_ctxt) {
DEBUG_SEC("Start of fetching of root-anchors.xml\n");
if (!_getdns_general_loop(context->sys_ctxt,
dnsreq->loop, "data.iana.org.", GETDNS_RRTYPE_A,
NULL, dnsreq, NULL, NULL, data_iana_org_a)
#if 0
|| !_getdns_general_loop(context->sys_ctxt,
dnsreq->loop, "data.iana.org.", GETDNS_RRTYPE_AAAA,
NULL, context, NULL, data_iana_org_aaaa)
#endif
)
return;
DEBUG_SEC("Scheduling of lookup for \"data.iana.org.\" failed\n");
getdns_context_destroy(context->sys_ctxt);
context->sys_ctxt = NULL;
}
dnsreq->waiting_for_ta = 0;
context->ta_notify = dnsreq->ta_notify;
dnsreq->ta_notify = NULL;
}
#ifdef STUB_NATIVE_DNSSEC
/* Perform validation only on GETDNS_RESOLUTION_STUB (unbound_id == -1)
* Or when asked for the validation chain (to identify the RRSIGs that

View File

@ -940,8 +940,10 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop,
result->upstreams->referenced++;
result->finished_next = NULL;
result->ta_notify = NULL;
result->freed = NULL;
result->validating = 0;
result->waiting_for_ta = 0;
result->is_dns_request = 1;
result->request_timed_out = 0;
result->chain = NULL;

View File

@ -324,6 +324,7 @@ typedef struct getdns_dns_req {
* freed is touched by _getdns_submit_netreq only
*/
unsigned validating : 1;
unsigned waiting_for_ta : 1;
int *freed;
/* Validation chain to be canceled when this request is canceled */
@ -365,6 +366,11 @@ typedef struct getdns_dns_req {
*/
struct getdns_dns_req *finished_next;
/* Linked list pointer for dns requests, which need to validate DNSSEC
* and are waiting for the root trust-anchors fetch.
*/
struct getdns_dns_req *ta_notify;
/* network requests for this dns request.
* The array is terminated with NULL.
*