Synchronous dnssec_return_validation_chain support

This commit is contained in:
Willem Toorop 2014-02-13 12:28:55 +01:00
parent 703ed14d28
commit df32c65c0f
3 changed files with 66 additions and 15 deletions

View File

@ -41,6 +41,7 @@
#include "types-internal.h" #include "types-internal.h"
#include "util-internal.h" #include "util-internal.h"
#include <string.h> #include <string.h>
#include "validation-chain.h"
/* stuff to make it compile pedantically */ /* stuff to make it compile pedantically */
#define UNUSED_PARAM(x) ((void)(x)) #define UNUSED_PARAM(x) ((void)(x))
@ -104,8 +105,13 @@ getdns_general_sync(struct getdns_context *context,
return GETDNS_RETURN_MEMORY_ERROR; return GETDNS_RETURN_MEMORY_ERROR;
response_status = submit_request_sync(req); response_status = submit_request_sync(req);
if (response_status == GETDNS_RETURN_GOOD) if (response_status == GETDNS_RETURN_GOOD) {
if (is_extension_set(req->extensions,
"dnssec_return_validation_chain"))
*response = priv_getdns_get_validation_chain_sync(req);
else
*response = create_getdns_response(req); *response = create_getdns_response(req);
}
dns_req_free(req); dns_req_free(req);
return response_status; return response_status;

View File

@ -49,6 +49,7 @@ struct validation_chain {
struct mem_funcs mf; struct mem_funcs mf;
getdns_dns_req *dns_req; getdns_dns_req *dns_req;
size_t lock; size_t lock;
struct getdns_dict **sync_response;
}; };
struct chain_response { struct chain_response {
@ -102,8 +103,11 @@ static void callback_on_complete_chain(struct validation_chain *chain)
getdns_keys); getdns_keys);
getdns_list_destroy(getdns_keys); getdns_list_destroy(getdns_keys);
ldns_rr_list_free(keys); ldns_rr_list_free(keys);
destroy_chain(chain); if (chain->sync_response) {
*chain->sync_response = response;
} else
priv_getdns_call_user_callback(dns_req, response); priv_getdns_call_user_callback(dns_req, response);
destroy_chain(chain);
} }
} }
@ -182,7 +186,27 @@ static void chain_response_init(
response->unbound_id = -1; response->unbound_id = -1;
} }
static void launch_chain_link_lookup(struct validation_chain *chain, char *name) static int
resolve(char* name, int rrtype, struct chain_response *response)
{
int r;
struct ub_result *ub_res;
if (response->chain->sync_response) {
ub_res = NULL;
r = ub_resolve(response->chain->dns_req->context->unbound_ctx,
name, rrtype, LDNS_RR_CLASS_IN, &ub_res);
ub_chain_response_callback(response, r, ub_res);
return r;
} else
return ub_resolve_async(
response->chain->dns_req->context->unbound_ctx,
name, rrtype, LDNS_RR_CLASS_IN, response,
ub_chain_response_callback, &response->unbound_id);
}
static void
launch_chain_link_lookup(struct validation_chain *chain, char *name)
{ {
int r; int r;
struct chain_link *link = (struct chain_link *) struct chain_link *link = (struct chain_link *)
@ -201,23 +225,20 @@ static void launch_chain_link_lookup(struct validation_chain *chain, char *name)
ldns_rbtree_insert(&(chain->root), (ldns_rbnode_t *)link); ldns_rbtree_insert(&(chain->root), (ldns_rbnode_t *)link);
chain->lock++; chain->lock++;
r = ub_resolve_async(chain->dns_req->context->unbound_ctx, r = resolve(name, LDNS_RR_TYPE_DNSKEY, &link->DNSKEY);
name, LDNS_RR_TYPE_DNSKEY, LDNS_RR_CLASS_IN, &link->DNSKEY,
ub_chain_response_callback, &link->DNSKEY.unbound_id);
if (r != 0) if (r != 0)
link->DNSKEY.err = r; link->DNSKEY.err = r;
if (name[0] != '.' || name[1] != '\0') { if (name[0] != '.' || name[1] != '\0') {
r = ub_resolve_async(chain->dns_req->context->unbound_ctx, r = resolve(name, LDNS_RR_TYPE_DS, &link->DS);
name, LDNS_RR_TYPE_DS, LDNS_RR_CLASS_IN, &link->DS,
ub_chain_response_callback, &link->DS.unbound_id);
if (r != 0) if (r != 0)
link->DS.err = r; link->DS.err = r;
} }
chain->lock--; chain->lock--;
} }
static struct validation_chain *create_chain(getdns_dns_req *dns_req) static struct validation_chain *create_chain(
getdns_dns_req *dns_req, struct getdns_dict **sync_response)
{ {
struct validation_chain *chain = GETDNS_MALLOC( struct validation_chain *chain = GETDNS_MALLOC(
dns_req->context->mf, struct validation_chain); dns_req->context->mf, struct validation_chain);
@ -233,6 +254,7 @@ static struct validation_chain *create_chain(getdns_dns_req *dns_req)
chain->mf.mf.ext.free = dns_req->context->mf.mf.ext.free; chain->mf.mf.ext.free = dns_req->context->mf.mf.ext.free;
chain->dns_req = dns_req; chain->dns_req = dns_req;
chain->lock = 0; chain->lock = 0;
chain->sync_response = sync_response;
return chain; return chain;
} }
@ -255,14 +277,19 @@ static void destroy_chain(struct validation_chain *chain)
} }
/* 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) static void
getdns_get_validation_chain(
getdns_dns_req *dns_req, struct getdns_dict **sync_response)
{ {
getdns_network_req *netreq = dns_req->first_req; getdns_network_req *netreq = dns_req->first_req;
struct validation_chain *chain = create_chain(dns_req); struct validation_chain *chain = create_chain(dns_req, sync_response);
if (! chain) { if (! chain) {
if (sync_response)
*sync_response = create_getdns_response(dns_req);
else
priv_getdns_call_user_callback( priv_getdns_call_user_callback(
dns_req, create_getdns_response(chain->dns_req)); dns_req, create_getdns_response(dns_req));
return; return;
} }
while (netreq) { while (netreq) {
@ -279,4 +306,18 @@ void priv_getdns_get_validation_chain(getdns_dns_req *dns_req)
callback_on_complete_chain(chain); callback_on_complete_chain(chain);
} }
void priv_getdns_get_validation_chain(getdns_dns_req *dns_req)
{
getdns_get_validation_chain(dns_req, NULL);
}
struct getdns_dict *
priv_getdns_get_validation_chain_sync(getdns_dns_req *dns_req)
{
struct getdns_dict *sync_response = NULL;
getdns_get_validation_chain(dns_req, &sync_response);
return sync_response;
}
/* validation-chain.c */ /* validation-chain.c */

View File

@ -38,11 +38,15 @@
#ifndef VALIDATION_CHAIN_H_ #ifndef VALIDATION_CHAIN_H_
#define VALIDATION_CHAIN_H_ #define VALIDATION_CHAIN_H_
#include "getdns/getdns.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);
struct getdns_dict * priv_getdns_get_validation_chain_sync(
getdns_dns_req *dns_req);
#endif #endif
/* validation-chain.h */ /* validation-chain.h */