diff --git a/lib/resolve.c b/lib/resolve.c index 92cee2d76529652599c0c5e2824469fe00075a6c..86b56ac3bb014f6c941e0520a4f7b2aaf85f3aca 100644 --- a/lib/resolve.c +++ b/lib/resolve.c @@ -41,23 +41,27 @@ static int invalidate_ns(struct kr_rplan *rplan, struct kr_query *qry) static int ns_resolve_addr(struct kr_query *qry, struct kr_request *param) { struct kr_rplan *rplan = ¶m->rplan; - if (kr_rplan_satisfies(qry, qry->ns.name, KNOT_CLASS_IN, KNOT_RRTYPE_A) || - kr_rplan_satisfies(qry, qry->ns.name, KNOT_CLASS_IN, KNOT_RRTYPE_AAAA) || - qry->flags & QUERY_AWAIT_ADDR) { - DEBUG_MSG("=> dependency loop, bailing out\n"); - kr_rplan_pop(rplan, qry); - return KNOT_STATE_PRODUCE; - } /* Start NS queries from root, to avoid certain cases * where a NS drops out of cache and the rest is unavailable, * this would lead to dependency loop in current zone cut. + * Prefer IPv6 and continue with IPv4 if not available. */ - struct kr_query *next = kr_rplan_push(rplan, qry, qry->ns.name, KNOT_CLASS_IN, KNOT_RRTYPE_AAAA); - kr_zonecut_set_sbelt(&next->zone_cut); - next = kr_rplan_push(rplan, qry, qry->ns.name, KNOT_CLASS_IN, KNOT_RRTYPE_A); + uint16_t next_type = KNOT_RRTYPE_AAAA; + if (!(qry->flags & QUERY_AWAIT_IPV6)) { + next_type = KNOT_RRTYPE_AAAA; + qry->flags |= QUERY_AWAIT_IPV6; + } else if (!(qry->flags & QUERY_AWAIT_IPV4)) { + next_type = KNOT_RRTYPE_A; + qry->flags |= QUERY_AWAIT_IPV4; + } else { + DEBUG_MSG("=> dependency loop, bailing out\n"); + kr_rplan_pop(rplan, qry); + return KNOT_STATE_PRODUCE; + } + + struct kr_query *next = kr_rplan_push(rplan, qry, qry->ns.name, KNOT_CLASS_IN, next_type); kr_zonecut_set_sbelt(&next->zone_cut); - qry->flags |= QUERY_AWAIT_ADDR; return KNOT_STATE_PRODUCE; } @@ -405,7 +409,7 @@ int kr_resolve_produce(struct kr_request *request, struct sockaddr **dst, int *t return ns_resolve_addr(qry, request); } else { /* Address resolved, clear the flag */ - qry->flags &= ~QUERY_AWAIT_ADDR; + qry->flags &= ~(QUERY_AWAIT_IPV6|QUERY_AWAIT_IPV4); } } diff --git a/lib/rplan.h b/lib/rplan.h index 35c6c99c94e3e18908963253339a77c7dfbd50d9..c3a84383d4b119f12700c989c237f32b02d4b302 100644 --- a/lib/rplan.h +++ b/lib/rplan.h @@ -31,9 +31,10 @@ enum kr_query_flag { QUERY_NO_MINIMIZE = 1 << 0, /**< Don't minimize QNAME. */ QUERY_TCP = 1 << 1, /**< Use TCP for this query. */ QUERY_RESOLVED = 1 << 2, /**< Query is resolved. */ - QUERY_AWAIT_ADDR = 1 << 3, /**< Query is waiting for NS address. */ - QUERY_SAFEMODE = 1 << 4, /**< Don't use fancy stuff (EDNS...) */ - QUERY_CACHED = 1 << 5 /**< Query response is cached. */ + QUERY_AWAIT_IPV4 = 1 << 3, /**< Query is waiting for A address. */ + QUERY_AWAIT_IPV6 = 1 << 4, /**< Query is waiting for AAAA address. */ + QUERY_SAFEMODE = 1 << 5, /**< Don't use fancy stuff (EDNS...) */ + QUERY_CACHED = 1 << 6 /**< Query response is cached. */ }; /**