From: Vladimír Čunát Date: Tue, 11 Jul 2023 08:17:57 +0000 (+0200) Subject: Merge branch 'master' into 6.0 X-Git-Tag: v6.0.2~37 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=08bd2d9d5521af8da911dea1332bcc4857e1487f;p=thirdparty%2Fknot-resolver.git Merge branch 'master' into 6.0 --- 08bd2d9d5521af8da911dea1332bcc4857e1487f diff --cc modules/hints/hints.c index ccbc98801,a3f2f3002..e2624225b --- a/modules/hints/hints.c +++ b/modules/hints/hints.c @@@ -44,6 -45,134 +44,10 @@@ static char * bool2jsonstr(bool val return result; } -static int put_answer(knot_pkt_t *pkt, struct kr_query *qry, knot_rrset_t *rr, bool use_nodata) -{ - int ret = 0; - if (!knot_rrset_empty(rr) || use_nodata) { - /* Update packet question */ - if (!knot_dname_is_equal(knot_pkt_qname(pkt), rr->owner)) { - kr_pkt_recycle(pkt); - knot_pkt_put_question(pkt, qry->sname, qry->sclass, qry->stype); - } - if (!knot_rrset_empty(rr)) { - /* Append to packet */ - ret = knot_pkt_put_rotate(pkt, KNOT_COMPR_HINT_QNAME, rr, - qry->reorder, KNOT_PF_FREE); - } else { - /* Return empty answer if name exists, but type doesn't match */ - knot_wire_set_aa(pkt->wire); - } - } else { - ret = kr_error(ENOENT); - } - /* Clear RR if failed */ - if (ret != 0) { - knot_rrset_clear(rr, &pkt->mm); - } - return ret; -} - -static int satisfy_reverse(/*const*/ struct hints_data *data, - knot_pkt_t *pkt, struct kr_query *qry) -{ - /* Find a matching name */ - pack_t *addr_set = kr_zonecut_find(&data->reverse_hints, qry->sname); - if (!addr_set || addr_set->len == 0) { - return kr_error(ENOENT); - } - knot_dname_t *qname = knot_dname_copy(qry->sname, &pkt->mm); - knot_rrset_t rr; - knot_rrset_init(&rr, qname, KNOT_RRTYPE_PTR, KNOT_CLASS_IN, data->ttl); - - /* Append address records from hints */ - uint8_t *addr = pack_last(*addr_set); - if (addr != NULL) { - size_t len = pack_obj_len(addr); - void *addr_val = pack_obj_val(addr); - knot_rrset_add_rdata(&rr, addr_val, len, &pkt->mm); - } - - return put_answer(pkt, qry, &rr, data->use_nodata); -} - -static int satisfy_forward(/*const*/ struct hints_data *data, - knot_pkt_t *pkt, struct kr_query *qry) -{ - /* Find a matching name */ - pack_t *addr_set = kr_zonecut_find(&data->hints, qry->sname); - if (!addr_set || addr_set->len == 0) { - return kr_error(ENOENT); - } - knot_dname_t *qname = knot_dname_copy(qry->sname, &pkt->mm); - knot_rrset_t rr; - knot_rrset_init(&rr, qname, qry->stype, qry->sclass, data->ttl); - - size_t family_len; - switch (rr.type) { - case KNOT_RRTYPE_A: - family_len = sizeof(struct in_addr); - break; - case KNOT_RRTYPE_AAAA: - family_len = sizeof(struct in6_addr); - break; - default: - goto finish; - }; - - /* Append address records from hints */ - uint8_t *addr = pack_head(*addr_set); - while (addr != pack_tail(*addr_set)) { - size_t len = pack_obj_len(addr); - void *addr_val = pack_obj_val(addr); - if (len == family_len) { - knot_rrset_add_rdata(&rr, addr_val, len, &pkt->mm); - } - addr = pack_obj_next(addr); - } -finish: - return put_answer(pkt, qry, &rr, data->use_nodata); -} - -static int query(kr_layer_t *ctx, knot_pkt_t *pkt) -{ - struct kr_query *qry = ctx->req->current_query; - if (!qry || (ctx->state & KR_STATE_FAIL)) { - return ctx->state; - } - - struct kr_module *module = ctx->api->data; - struct hints_data *data = module->data; - if (!data) { /* No valid file. */ - return ctx->state; - } - /* We can optimize for early return like this: */ - if (!data->use_nodata && qry->stype != KNOT_RRTYPE_A - && qry->stype != KNOT_RRTYPE_AAAA && qry->stype != KNOT_RRTYPE_PTR) { - return ctx->state; - } - /* FIXME: putting directly into packet breaks ordering in case the hint - * is applied after a CNAME jump. */ - const bool is_rev = + knot_dname_in_bailiwick(qry->sname, (const uint8_t *)"\4arpa\0") > 0 && + (knot_dname_in_bailiwick(qry->sname, (const uint8_t *)"\7in-addr\4arpa\0") > 0 + || knot_dname_in_bailiwick(qry->sname, (const uint8_t *)"\3ip6\4arpa\0") > 0); + if (is_rev) { - if (satisfy_reverse(data, pkt, qry) != 0) - return ctx->state; - } else { - if (satisfy_forward(data, pkt, qry) != 0) - return ctx->state; - } - - VERBOSE_MSG(qry, "<= answered from hints\n"); - qry->flags.DNSSEC_WANT = false; /* Never authenticated */ - qry->flags.CACHED = true; - qry->flags.NO_MINIMIZE = true; - pkt->parsed = pkt->size; - knot_wire_set_qr(pkt->wire); - return KR_STATE_DONE; -} - static int parse_addr_str(union kr_sockaddr *sa, const char *addr) { int family = strchr(addr, ':') ? AF_INET6 : AF_INET;