Commit c7ccfbe6 authored by Marek Vavruša's avatar Marek Vavruša

lib/resolve: stub resolution with predefined address

the library is able to resolve query in stub mode (no referral chasing,
zone cut lookup) if asked to
validator turns off for stub queries, validating stub is NYI
parent 1454cc16
......@@ -88,6 +88,7 @@ struct pkt_rcode {
};
struct query_flag {
static const int NO_MINIMIZE = 1 << 0;
static const int NO_THROTTLE = 1 << 1;
static const int NO_IPV6 = 1 << 2;
static const int NO_IPV4 = 1 << 3;
static const int RESOLVED = 1 << 5;
......@@ -96,6 +97,7 @@ struct query_flag {
static const int NO_CACHE = 1 << 11;
static const int EXPIRING = 1 << 12;
static const int DNSSEC_WANT = 1 << 14;
static const int STUB = 1 << 17;
};
/*
......
......@@ -37,7 +37,7 @@ static const knot_dname_t *minimized_qname(struct kr_query *query, uint16_t *qty
{
/* Minimization disabled. */
const knot_dname_t *qname = query->sname;
if (qname[0] == '\0' || query->flags & QUERY_NO_MINIMIZE) {
if (qname[0] == '\0' || query->flags & (QUERY_NO_MINIMIZE|QUERY_STUB)) {
return qname;
}
......@@ -260,6 +260,11 @@ static int process_authority(knot_pkt_t *pkt, struct kr_request *req)
struct kr_query *qry = req->current_query;
const knot_pktsection_t *ns = knot_pkt_section(pkt, KNOT_AUTHORITY);
/* Stub resolution doesn't process authority */
if (qry->flags & QUERY_STUB) {
return KNOT_STATE_CONSUME;
}
#ifdef STRICT_MODE
/* AA, terminate resolution chain. */
if (knot_wire_get_aa(pkt->wire)) {
......@@ -337,7 +342,7 @@ static int process_answer(knot_pkt_t *pkt, struct kr_request *req)
}
/* This answer didn't improve resolution chain, therefore must be authoritative (relaxed to negative). */
if (!is_authoritative(pkt, query)) {
if (!(query->flags & QUERY_STUB) && !is_authoritative(pkt, query)) {
if (pkt_class & (PKT_NXDOMAIN|PKT_NODATA)) {
DEBUG_MSG("<= lame response: non-auth sent negative response\n");
return KNOT_STATE_FAIL;
......@@ -524,8 +529,7 @@ static int resolve(knot_layer_t *ctx, knot_pkt_t *pkt)
}
/* Resolve authority to see if it's referral or authoritative. */
int state = KNOT_STATE_CONSUME;
state = process_authority(pkt, req);
int state = process_authority(pkt, req);
switch(state) {
case KNOT_STATE_CONSUME: /* Not referral, process answer. */
DEBUG_MSG("<= rcode: %s\n", rcode ? rcode->name : "??");
......
......@@ -300,8 +300,9 @@ static int validate(knot_layer_t *ctx, knot_pkt_t *pkt)
return ctx->state;
}
/* Pass-through if user doesn't want secure answer. */
if (!(qry->flags & QUERY_DNSSEC_WANT)) {
/* Pass-through if user doesn't want secure answer or stub. */
/* @todo: Validating stub resolver mode. */
if (!(qry->flags & QUERY_DNSSEC_WANT) || (qry->flags & QUERY_STUB)) {
return ctx->state;
}
/* Answer for RRSIG may not set DO=1, but all records MUST still validate. */
......
......@@ -325,8 +325,14 @@ static int query_finalize(struct kr_request *request, struct kr_query *qry, knot
knot_pkt_begin(pkt, KNOT_ADDITIONAL);
if (!(qry->flags & QUERY_SAFEMODE)) {
ret = edns_create(pkt, request->answer, request);
if (ret == 0) { /* Enable DNSSEC for query. */
if (qry->flags & QUERY_DNSSEC_WANT) {
if (ret == 0) {
/* Stub resolution (ask for +rd and +do) */
if (qry->flags & QUERY_STUB) {
knot_wire_set_rd(pkt->wire);
if (knot_pkt_has_dnssec(request->answer))
knot_edns_set_do(pkt->opt_rr);
/* Full resolution (ask for +cd and +do) */
} else if (qry->flags & QUERY_DNSSEC_WANT) {
knot_edns_set_do(pkt->opt_rr);
knot_wire_set_cd(pkt->wire);
}
......@@ -539,6 +545,11 @@ static int zone_cut_check(struct kr_request *request, struct kr_query *qry, knot
map_t *trust_anchors = &request->ctx->trust_anchors;
map_t *negative_anchors = &request->ctx->negative_anchors;
/* Stub mode, just forward and do not solve cut. */
if (qry->flags & QUERY_STUB) {
return KNOT_STATE_PRODUCE;
}
/* The query wasn't resolved from cache,
* now it's the time to look up closest zone cut from cache. */
if (qry->flags & QUERY_AWAIT_CUT) {
......@@ -653,7 +664,7 @@ int kr_resolve_produce(struct kr_request *request, struct sockaddr **dst, int *t
}
if (qry->flags & (QUERY_AWAIT_IPV4|QUERY_AWAIT_IPV6)) {
kr_nsrep_elect_addr(qry, request->ctx);
} else if (!qry->ns.name || !(qry->flags & QUERY_TCP)) { /* Keep address when TCP retransmit. */
} else if (!qry->ns.name || !(qry->flags & (QUERY_TCP|QUERY_STUB))) { /* Keep NS when requerying/stub. */
/* Root DNSKEY must be fetched from the hints to avoid chicken and egg problem. */
if (qry->sname[0] == '\0' && qry->stype == KNOT_RRTYPE_DNSKEY) {
DEBUG_MSG(qry, "=> priming root DNSKEY\n");
......
......@@ -44,6 +44,7 @@
X(DNSSEC_WANT, 1 << 14) /**< Want DNSSEC secured answer. */ \
X(DNSSEC_BOGUS, 1 << 15) /**< Query response is DNSSEC bogus. */ \
X(DNSSEC_INSECURE, 1 << 16) /**< Query response is DNSSEC insecure. */ \
X(STUB, 1 << 17) /**< Stub resolution, accept received answer as solved. */ \
/** Query flags */
enum kr_query_flag {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment