mirror of https://github.com/getdnsapi/getdns.git
Allow alternative trust anchors + ...
Switch freely between stub and recursive resolving
This commit is contained in:
parent
4987a27264
commit
2884abe870
124
src/context.c
124
src/context.c
|
@ -47,6 +47,7 @@
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "gldns/str2wire.h"
|
#include "gldns/str2wire.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"
|
||||||
|
@ -563,49 +564,6 @@ priv_getdns_upstream_shutdown(getdns_upstream *upstream) {
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t*
|
|
||||||
upstream_addr(getdns_upstream *upstream)
|
|
||||||
{
|
|
||||||
return upstream->addr.ss_family == AF_INET
|
|
||||||
? (void *)&((struct sockaddr_in*)&upstream->addr)->sin_addr
|
|
||||||
: (void *)&((struct sockaddr_in6*)&upstream->addr)->sin6_addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static in_port_t
|
|
||||||
upstream_port(getdns_upstream *upstream)
|
|
||||||
{
|
|
||||||
return ntohs(upstream->addr.ss_family == AF_INET
|
|
||||||
? ((struct sockaddr_in *)&upstream->addr)->sin_port
|
|
||||||
: ((struct sockaddr_in6*)&upstream->addr)->sin6_port);
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t *
|
|
||||||
upstream_scope_id(getdns_upstream *upstream)
|
|
||||||
{
|
|
||||||
return upstream->addr.ss_family == AF_INET ? NULL
|
|
||||||
: (upstream_addr(upstream)[0] == 0xFE &&
|
|
||||||
(upstream_addr(upstream)[1] & 0xC0) == 0x80 ?
|
|
||||||
&((struct sockaddr_in6*)&upstream->addr)->sin6_scope_id : NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
upstream_ntop_buf(getdns_upstream *upstream, char *buf, size_t len)
|
|
||||||
{
|
|
||||||
/* Also possible but prints scope_id by name (nor parsed by unbound)
|
|
||||||
*
|
|
||||||
* getnameinfo((struct sockaddr *)&upstream->addr, upstream->addr_len,
|
|
||||||
* buf, len, NULL, 0, NI_NUMERICHOST)
|
|
||||||
*/
|
|
||||||
(void) inet_ntop(upstream->addr.ss_family, upstream_addr(upstream),
|
|
||||||
buf, len);
|
|
||||||
if (upstream_scope_id(upstream))
|
|
||||||
(void) snprintf(buf + strlen(buf), len - strlen(buf),
|
|
||||||
"%%%d", (int)*upstream_scope_id(upstream));
|
|
||||||
else if (upstream_port(upstream) != GETDNS_PORT_DNS && upstream_port(upstream) != GETDNS_PORT_ZERO)
|
|
||||||
(void) snprintf(buf + strlen(buf), len - strlen(buf),
|
|
||||||
"@%d", (int)upstream_port(upstream));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
net_req_query_id_cmp(const void *id1, const void *id2)
|
net_req_query_id_cmp(const void *id1, const void *id2)
|
||||||
{
|
{
|
||||||
|
@ -1134,6 +1092,7 @@ rebuild_ub_ctx(struct getdns_context* context) {
|
||||||
}
|
}
|
||||||
/* setup */
|
/* setup */
|
||||||
context->unbound_ctx = ub_ctx_create();
|
context->unbound_ctx = ub_ctx_create();
|
||||||
|
context->unbound_ta_set = 0;
|
||||||
if (!context->unbound_ctx) {
|
if (!context->unbound_ctx) {
|
||||||
return GETDNS_RETURN_MEMORY_ERROR;
|
return GETDNS_RETURN_MEMORY_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -1143,12 +1102,6 @@ rebuild_ub_ctx(struct getdns_context* context) {
|
||||||
context->edns_maximum_udp_payload_size);
|
context->edns_maximum_udp_payload_size);
|
||||||
set_ub_dns_transport(context);
|
set_ub_dns_transport(context);
|
||||||
|
|
||||||
/* Set default trust anchor */
|
|
||||||
if (context->trust_anchors) {
|
|
||||||
(void) ub_ctx_add_ta_file(
|
|
||||||
context->unbound_ctx, TRUST_ANCHOR_FILE);
|
|
||||||
}
|
|
||||||
|
|
||||||
context->ub_event.userarg = context;
|
context->ub_event.userarg = context;
|
||||||
context->ub_event.read_cb = priv_getdns_context_ub_read_cb;
|
context->ub_event.read_cb = priv_getdns_context_ub_read_cb;
|
||||||
context->ub_event.write_cb = NULL;
|
context->ub_event.write_cb = NULL;
|
||||||
|
@ -1185,10 +1138,12 @@ getdns_context_set_resolution_type(struct getdns_context *context,
|
||||||
if (value != GETDNS_RESOLUTION_STUB && value != GETDNS_RESOLUTION_RECURSING) {
|
if (value != GETDNS_RESOLUTION_STUB && value != GETDNS_RESOLUTION_RECURSING) {
|
||||||
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
|
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
|
||||||
}
|
}
|
||||||
|
#ifndef STUB_NATIVE_DNSSEC
|
||||||
if (context->resolution_type_set != 0) {
|
if (context->resolution_type_set != 0) {
|
||||||
/* already setup */
|
/* already setup */
|
||||||
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
|
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
context->resolution_type = value;
|
context->resolution_type = value;
|
||||||
|
|
||||||
dispatch_updated(context, GETDNS_CONTEXT_CODE_RESOLUTION_TYPE);
|
dispatch_updated(context, GETDNS_CONTEXT_CODE_RESOLUTION_TYPE);
|
||||||
|
@ -1958,6 +1913,50 @@ getdns_cancel_callback(getdns_context *context,
|
||||||
return r;
|
return r;
|
||||||
} /* getdns_cancel_callback */
|
} /* getdns_cancel_callback */
|
||||||
|
|
||||||
|
#ifndef STUB_NATIVE_DNSSEC
|
||||||
|
static uint8_t*
|
||||||
|
upstream_addr(getdns_upstream *upstream)
|
||||||
|
{
|
||||||
|
return upstream->addr.ss_family == AF_INET
|
||||||
|
? (void *)&((struct sockaddr_in*)&upstream->addr)->sin_addr
|
||||||
|
: (void *)&((struct sockaddr_in6*)&upstream->addr)->sin6_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static in_port_t
|
||||||
|
upstream_port(getdns_upstream *upstream)
|
||||||
|
{
|
||||||
|
return ntohs(upstream->addr.ss_family == AF_INET
|
||||||
|
? ((struct sockaddr_in *)&upstream->addr)->sin_port
|
||||||
|
: ((struct sockaddr_in6*)&upstream->addr)->sin6_port);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t *
|
||||||
|
upstream_scope_id(getdns_upstream *upstream)
|
||||||
|
{
|
||||||
|
return upstream->addr.ss_family == AF_INET ? NULL
|
||||||
|
: (upstream_addr(upstream)[0] == 0xFE &&
|
||||||
|
(upstream_addr(upstream)[1] & 0xC0) == 0x80 ?
|
||||||
|
&((struct sockaddr_in6*)&upstream->addr)->sin6_scope_id : NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
upstream_ntop_buf(getdns_upstream *upstream, char *buf, size_t len)
|
||||||
|
{
|
||||||
|
/* Also possible but prints scope_id by name (nor parsed by unbound)
|
||||||
|
*
|
||||||
|
* getnameinfo((struct sockaddr *)&upstream->addr, upstream->addr_len,
|
||||||
|
* buf, len, NULL, 0, NI_NUMERICHOST)
|
||||||
|
*/
|
||||||
|
(void) inet_ntop(upstream->addr.ss_family, upstream_addr(upstream),
|
||||||
|
buf, len);
|
||||||
|
if (upstream_scope_id(upstream))
|
||||||
|
(void) snprintf(buf + strlen(buf), len - strlen(buf),
|
||||||
|
"%%%d", (int)*upstream_scope_id(upstream));
|
||||||
|
else if (upstream_port(upstream) != GETDNS_PORT_DNS && upstream_port(upstream) != GETDNS_PORT_ZERO)
|
||||||
|
(void) snprintf(buf + strlen(buf), len - strlen(buf),
|
||||||
|
"@%d", (int)upstream_port(upstream));
|
||||||
|
}
|
||||||
|
|
||||||
static getdns_return_t
|
static getdns_return_t
|
||||||
ub_setup_stub(struct ub_ctx *ctx, getdns_context *context)
|
ub_setup_stub(struct ub_ctx *ctx, getdns_context *context)
|
||||||
{
|
{
|
||||||
|
@ -2038,21 +2037,42 @@ ub_setup_stub(struct ub_ctx *ctx, getdns_context *context)
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static getdns_return_t
|
static getdns_return_t
|
||||||
priv_getdns_ns_dns_setup(struct getdns_context *context)
|
priv_getdns_ns_dns_setup(struct getdns_context *context)
|
||||||
{
|
{
|
||||||
|
priv_getdns_rr_iter rr_spc, *rr;
|
||||||
|
char ta_str[8192];
|
||||||
assert(context);
|
assert(context);
|
||||||
|
|
||||||
switch (context->resolution_type) {
|
switch (context->resolution_type) {
|
||||||
case GETDNS_RESOLUTION_STUB:
|
case GETDNS_RESOLUTION_STUB:
|
||||||
if (!context->upstreams || !context->upstreams->count)
|
if (!context->upstreams || !context->upstreams->count)
|
||||||
return GETDNS_RETURN_GENERIC_ERROR;
|
return GETDNS_RETURN_GENERIC_ERROR;
|
||||||
|
#ifdef STUB_NATIVE_DNSSEC
|
||||||
|
return GETDNS_RETURN_GOOD;
|
||||||
|
#else
|
||||||
return ub_setup_stub(context->unbound_ctx, context);
|
return ub_setup_stub(context->unbound_ctx, context);
|
||||||
|
#endif
|
||||||
|
|
||||||
case GETDNS_RESOLUTION_RECURSING:
|
case GETDNS_RESOLUTION_RECURSING:
|
||||||
/* TODO: use the root servers via root hints file */
|
/* TODO: use the root servers via root hints file */
|
||||||
(void) ub_ctx_set_fwd(context->unbound_ctx, NULL);
|
(void) ub_ctx_set_fwd(context->unbound_ctx, NULL);
|
||||||
|
if (!context->unbound_ta_set && context->trust_anchors) {
|
||||||
|
for ( rr = priv_getdns_rr_iter_init( &rr_spc
|
||||||
|
, context->trust_anchors
|
||||||
|
, context->trust_anchors_len)
|
||||||
|
; rr ; rr = priv_getdns_rr_iter_next(rr) ) {
|
||||||
|
|
||||||
|
(void) gldns_wire2str_rr_buf(rr->pos,
|
||||||
|
rr->nxt - rr->pos, ta_str, sizeof(ta_str));
|
||||||
|
fprintf(stderr, "TA: %s\n", ta_str);
|
||||||
|
(void) ub_ctx_add_ta(
|
||||||
|
context->unbound_ctx, ta_str);
|
||||||
|
}
|
||||||
|
context->unbound_ta_set = 1;
|
||||||
|
}
|
||||||
return GETDNS_RETURN_GOOD;
|
return GETDNS_RETURN_GOOD;
|
||||||
}
|
}
|
||||||
return GETDNS_RETURN_BAD_CONTEXT;
|
return GETDNS_RETURN_BAD_CONTEXT;
|
||||||
|
@ -2113,12 +2133,6 @@ getdns_context_prepare_for_resolution(struct getdns_context *context,
|
||||||
r = GETDNS_RETURN_GOOD;
|
r = GETDNS_RETURN_GOOD;
|
||||||
for (i = 0; i < context->namespace_count; i++) {
|
for (i = 0; i < context->namespace_count; i++) {
|
||||||
switch (context->namespaces[i]) {
|
switch (context->namespaces[i]) {
|
||||||
case GETDNS_NAMESPACE_LOCALNAMES:
|
|
||||||
/* TODO: Note to self! This must change once we have
|
|
||||||
* proper namespace hanlding or asynch stub mode using ldns.*/
|
|
||||||
(void) ub_ctx_hosts(context->unbound_ctx, NULL);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GETDNS_NAMESPACE_DNS:
|
case GETDNS_NAMESPACE_DNS:
|
||||||
r = priv_getdns_ns_dns_setup(context);
|
r = priv_getdns_ns_dns_setup(context);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -166,6 +166,7 @@ struct getdns_context {
|
||||||
|
|
||||||
/* The underlying contexts that do the real work */
|
/* The underlying contexts that do the real work */
|
||||||
struct ub_ctx *unbound_ctx;
|
struct ub_ctx *unbound_ctx;
|
||||||
|
int unbound_ta_set;
|
||||||
|
|
||||||
/* A tree to hold local host information*/
|
/* A tree to hold local host information*/
|
||||||
getdns_rbtree_t local_hosts;
|
getdns_rbtree_t local_hosts;
|
||||||
|
|
Loading…
Reference in New Issue