int kr_pkt_clear_payload(knot_pkt_t *);
uint16_t kr_pkt_qclass(const knot_pkt_t *);
uint16_t kr_pkt_qtype(const knot_pkt_t *);
-uint32_t kr_rrsig_sig_inception(const knot_rdataset_t *, size_t);
-uint32_t kr_rrsig_sig_expiration(const knot_rdataset_t *, size_t);
+uint32_t kr_rrsig_sig_inception(const knot_rdata_t *);
+uint32_t kr_rrsig_sig_expiration(const knot_rdata_t *);
const char *kr_inaddr(const struct sockaddr *);
int kr_inaddr_family(const struct sockaddr *);
int kr_inaddr_len(const struct sockaddr *);
knot_rrset_t *rr)
{
int err = 0;
- for (uint16_t i = 0; i < rr->rrs.count; ++i) {
- const knot_dname_t *ns_name = knot_ns_name(&rr->rrs, i);
+ knot_rdata_t *rdata_i = rr->rrs.rdata;
+ for (uint16_t i = 0; i < rr->rrs.count;
+ ++i, rdata_i = knot_rdataset_next(rdata_i)) {
+ const knot_dname_t *ns_name = knot_ns_name(rdata_i);
err = zi_rrset_find_put(z_import, pkt, ns_name,
rr->rclass, KNOT_RRTYPE_A, 0);
if (err < 0) {
}
const int wild_labels = rr_sigs == NULL ? 0 :
- knot_dname_labels(rr->owner, NULL) - knot_rrsig_labels(&rr_sigs->rrs, 0);
+ knot_dname_labels(rr->owner, NULL) - knot_rrsig_labels(rr_sigs->rrs.rdata);
if (wild_labels < 0) {
return kr_ok();
}
case KNOT_RRTYPE_NSEC3:
/* Skip "suspicious" or opt-out NSEC3 sets. */
if (rr->rrs.count != 1) return kr_ok();
- if (KNOT_NSEC3_FLAG_OPT_OUT & knot_nsec3_flags(&rr->rrs, 0)) {
+ if (KNOT_NSEC3_FLAG_OPT_OUT & knot_nsec3_flags(rr->rrs.rdata)) {
if (has_optout) *has_optout = true;
return kr_ok();
}
assert(!EINVAL);
return kr_error(EINVAL);
}
- const knot_dname_t *signer = knot_rrsig_signer_name(&rr_sigs->rrs, 0);
+ const knot_dname_t *signer = knot_rrsig_signer_name(rr_sigs->rrs.rdata);
const int signer_size = knot_dname_size(signer);
k->zlf_len = signer_size - 1;
ranked_rr_array_entry_t *e = arr->at[j];
bool ok = e->qry_uid == qry->uid && !e->cached
&& e->rr->type == KNOT_RRTYPE_RRSIG
- && knot_rrsig_type_covered(&e->rr->rrs, 0) == rr->type
+ && knot_rrsig_type_covered(e->rr->rrs.rdata) == rr->type
&& knot_dname_is_equal(rr->owner, e->rr->owner);
if (!ok) continue;
entry_rrsigs = e;
/* NXDOMAIN proven *except* for wildcards. */
WITH_VERBOSE(qry) {
auto_free char *owner_str = kr_dname_text(nsec_rr->owner),
- *next_str = kr_dname_text(knot_nsec_next(&nsec_rr->rrs));
+ *next_str = kr_dname_text(knot_nsec_next(nsec_rr->rrs.rdata));
VERBOSE_MSG(qry, "=> NSEC sname: covered by: %s -> %s, new TTL %d\n",
owner_str, next_str, new_ttl);
}
* LATER(optim.): it might be faster to use the LFs we already have.
*/
knot_dname_t next[KNOT_DNAME_MAXLEN];
- int ret = knot_dname_to_wire(next, knot_nsec_next(&nsec_rr->rrs), sizeof(next));
+ int ret = knot_dname_to_wire(next, knot_nsec_next(nsec_rr->rrs.rdata), sizeof(next));
if (ret < 0) {
assert(!ret);
return kr_error(ret);
/* We have a record proving wildcard non-existence. */
WITH_VERBOSE(qry) {
auto_free char *owner_str = kr_dname_text(nsec_rr->owner),
- *next_str = kr_dname_text(knot_nsec_next(&nsec_rr->rrs));
+ *next_str = kr_dname_text(knot_nsec_next(nsec_rr->rrs.rdata));
VERBOSE_MSG(qry, "=> NSEC wildcard: covered by: %s -> %s, new TTL %d\n",
owner_str, next_str, new_ttl_log);
}
* Check the RRSIG RR validity according to RFC4035 5.3.1 .
* @param flags The flags are going to be set according to validation result.
* @param cov_labels Covered RRSet owner label count.
- * @param rrsigs RRSet containing the signatures.
- * @param sig_pos Specifies the signature within the RRSIG RRSet.
- * @param keys Associated DNSKEY RRSet.
- * @param key_pos Specifies the key within the DNSKEY RRSet,
+ * @param rrsigs rdata containing the signatures.
+ * @param key_owner Associated DNSKEY's owner.
+ * @param key_rdata Associated DNSKEY's rdata.
* @param keytag Used key tag.
* @param zone_name The name of the zone cut.
* @param timestamp Validation time.
*/
static int validate_rrsig_rr(int *flags, int cov_labels,
- const knot_rrset_t *rrsigs, size_t sig_pos,
- const knot_rrset_t *keys, size_t key_pos, uint16_t keytag,
+ const knot_rdata_t *rrsigs,
+ const knot_dname_t *key_owner, const knot_rdata_t *key_rdata,
+ uint16_t keytag,
const knot_dname_t *zone_name, uint32_t timestamp)
{
- if (!flags || !rrsigs || !keys || !zone_name) {
+ if (!flags || !rrsigs || !key_owner || !key_rdata || !zone_name) {
return kr_error(EINVAL);
}
/* bullet 5 */
- if (knot_rrsig_sig_expiration(&rrsigs->rrs, sig_pos) < timestamp) {
+ if (knot_rrsig_sig_expiration(rrsigs) < timestamp) {
return kr_error(EINVAL);
}
/* bullet 6 */
- if (knot_rrsig_sig_inception(&rrsigs->rrs, sig_pos) > timestamp) {
+ if (knot_rrsig_sig_inception(rrsigs) > timestamp) {
return kr_error(EINVAL);
}
/* bullet 2 */
- const knot_dname_t *signer_name = knot_rrsig_signer_name(&rrsigs->rrs, sig_pos);
+ const knot_dname_t *signer_name = knot_rrsig_signer_name(rrsigs);
if (!signer_name || !knot_dname_is_equal(signer_name, zone_name)) {
return kr_error(EAGAIN);
}
/* bullet 4 */
{
- int rrsig_labels = knot_rrsig_labels(&rrsigs->rrs, sig_pos);
+ int rrsig_labels = knot_rrsig_labels(rrsigs);
if (rrsig_labels > cov_labels) {
return kr_error(EINVAL);
}
}
/* bullet 7 */
- if ((!knot_dname_is_equal(keys->owner, signer_name)) ||
- (knot_dnskey_alg(&keys->rrs, key_pos) != knot_rrsig_algorithm(&rrsigs->rrs, sig_pos)) ||
- (keytag != knot_rrsig_key_tag(&rrsigs->rrs, sig_pos))) {
+ if ((!knot_dname_is_equal(key_owner, signer_name)) ||
+ (knot_dnskey_alg(key_rdata) != knot_rrsig_alg(rrsigs)) ||
+ (keytag != knot_rrsig_key_tag(rrsigs))) {
return kr_error(EINVAL);
}
/* bullet 8 */
* @param sig_pos Specifies the signature within the RRSIG RRSet.
* @return Number of added labels, -1 on error.
*/
-static int wildcard_radix_len_diff(const knot_dname_t *expanded,
- const knot_rrset_t *rrsigs, size_t sig_pos)
+static inline int wildcard_radix_len_diff(const knot_dname_t *expanded,
+ const knot_rdata_t *rrsig)
{
- if (!expanded || !rrsigs) {
+ if (!expanded || !rrsig) {
return -1;
}
- return knot_dname_labels(expanded, NULL) - knot_rrsig_labels(&rrsigs->rrs, sig_pos);
+ return knot_dname_labels(expanded, NULL) - knot_rrsig_labels(rrsig);
}
int kr_rrset_validate(kr_rrset_validation_ctx_t *vctx, const knot_rrset_t *covered)
return vctx->result;
}
+ const knot_rdata_t *key_rdata = knot_rdataset_at(&keys->rrs, key_pos);
if (key == NULL) {
- const knot_rdata_t *krr = knot_rdataset_at(&keys->rrs, key_pos);
int ret = kr_dnssec_key_from_rdata(&created_key, keys->owner,
- krr->rdata, krr->len);
+ key_rdata->data, key_rdata->len);
if (ret != 0) {
vctx->result = ret;
return vctx->result;
if ((covered->rclass != rrsig->rclass) || !knot_dname_is_equal(covered->owner, rrsig->owner)) {
continue;
}
- for (uint16_t j = 0; j < rrsig->rrs.count; ++j) {
+ knot_rdata_t *rdata_j = rrsig->rrs.rdata;
+ for (uint16_t j = 0; j < rrsig->rrs.count; ++j, rdata_j = knot_rdataset_next(rdata_j)) {
int val_flgs = 0;
int trim_labels = 0;
- if (knot_rrsig_type_covered(&rrsig->rrs, j) != covered->type) {
+ if (knot_rrsig_type_covered(rdata_j) != covered->type) {
continue;
}
- int ret = validate_rrsig_rr(&val_flgs, covered_labels, rrsig, j,
- keys, key_pos, keytag,
+ int ret = validate_rrsig_rr(&val_flgs, covered_labels, rdata_j,
+ keys->owner, key_rdata, keytag,
zone_name, timestamp);
if (ret == kr_error(EAGAIN)) {
kr_dnssec_key_free(&created_key);
continue;
}
if (val_flgs & FLG_WILDCARD_EXPANSION) {
- trim_labels = wildcard_radix_len_diff(covered->owner, rrsig, j);
+ trim_labels = wildcard_radix_len_diff(covered->owner, rdata_j);
if (trim_labels < 0) {
break;
}
}
- if (kr_check_signature(rrsig, j, (dnssec_key_t *) key, covered, trim_labels) != 0) {
+ if (kr_check_signature(rdata_j, (dnssec_key_t *) key, covered, trim_labels) != 0) {
continue;
}
if (val_flgs & FLG_WILDCARD_EXPANSION) {
static bool kr_ds_algo_support(const knot_rrset_t *ta)
{
- for (uint16_t i = 0; i < ta->rrs.count; ++i) {
- if (dnssec_algorithm_digest_support(knot_ds_digest_type(&ta->rrs, i))
- && dnssec_algorithm_key_support(knot_ds_alg(&ta->rrs, i))) {
+ knot_rdata_t *rdata_i = ta->rrs.rdata;
+ for (uint16_t i = 0; i < ta->rrs.count;
+ ++i, rdata_i = knot_rdataset_next(rdata_i)) {
+ if (dnssec_algorithm_digest_support(knot_ds_digest_type(rdata_i))
+ && dnssec_algorithm_key_support(knot_ds_alg(rdata_i))) {
return true;
}
}
}
/* If NSEC 'owner' >= 'next', it means that there is nothing after 'owner' */
-#if KNOT_VERSION_HEX < ((2 << 16) | (7 << 8) | 0)
- const knot_dname_t *next = knot_nsec_next(&nsec->rrs);
-#else
/* We have to lower-case it with libknot >= 2.7; see also RFC 6840 5.1. */
knot_dname_t next[KNOT_DNAME_MAXLEN];
- int ret = knot_dname_to_wire(next, knot_nsec_next(&nsec->rrs), sizeof(next));
- if (ret >= 0) {
- ret = knot_dname_to_lower(next);
- }
+ int ret = knot_dname_to_wire(next, knot_nsec_next(nsec->rrs.rdata), sizeof(next));
if (ret < 0) {
assert(!ret);
return kr_error(ret);
}
-#endif
+ knot_dname_to_lower(next);
+
const bool is_last_nsec = knot_dname_cmp(nsec->owner, next) >= 0;
const bool in_range = is_last_nsec || knot_dname_cmp(sname, next) < 0;
if (!in_range) {
continue;
}
- for (uint16_t j = 0; j < rrset->rrs.count; ++j) {
- if (knot_rrsig_type_covered(&rrset->rrs, j) != KNOT_RRTYPE_NSEC) {
+ knot_rdata_t *rdata_j = rrset->rrs.rdata;
+ for (uint16_t j = 0; j < rrset->rrs.count;
+ ++j, rdata_j = knot_rdataset_next(rdata_j)) {
+ if (knot_rrsig_type_covered(rdata_j) != KNOT_RRTYPE_NSEC) {
continue;
}
if (ret < 0) {
- ret = knot_rrsig_labels(&rrset->rrs, j);
+ ret = knot_rrsig_labels(rdata_j);
} else {
- if (ret != knot_rrsig_labels(&rrset->rrs, j)) {
+ if (ret != knot_rrsig_labels(rdata_j)) {
return kr_error(EINVAL);
}
}
/* Every NSEC3 RR contains data from NSEC3PARAMS. */
const size_t SALT_OFFSET = 5; /* First 5 octets contain { Alg, Flags, Iterations, Salt length } */
dnssec_binary_t rdata = {
- .size = SALT_OFFSET + (size_t) knot_nsec3_salt_length(&nsec3->rrs, 0),
+ .size = SALT_OFFSET + (size_t)knot_nsec3_salt_len(nsec3->rrs.rdata),
.data = /*const-cast*/(uint8_t *)rr->data,
};
if (rdata.size > rr->len)
goto fail;
}
- uint8_t next_size = 0;
- uint8_t *next_hash = NULL;
- knot_nsec3_next_hashed(&nsec3->rrs, 0, &next_hash, &next_size);
+ uint8_t next_size = knot_nsec3_next_len(nsec3->rrs.rdata);
+ const uint8_t *next_hash = knot_nsec3_next(nsec3->rrs.rdata);
if ((next_size > 0) && (owner_hash.size == next_size) && (name_hash.size == next_size)) {
/* All hash lengths must be same. */
if (covered) {
*flags |= FLG_NAME_COVERED;
- uint8_t nsec3_flags = knot_nsec3_flags(&nsec3->rrs, 0);
+ uint8_t nsec3_flags = knot_nsec3_flags(nsec3->rrs.rdata);
if (nsec3_flags & ~OPT_OUT_BIT) {
/* RFC5155 3.1.2 */
ret = kr_error(EINVAL);
return false;
}
- uint8_t nsec3_flags = knot_nsec3_flags(&nsec3->rrs, 0);
+ uint8_t nsec3_flags = knot_nsec3_flags(nsec3->rrs.rdata);
if (nsec3_flags & ~OPT_OUT_BIT) {
/* RFC5155 3.1.2 */
return false;
.size = rd->len,
.data = rd->data
};
- ret = authenticate_ds(key, &ds_rdata, knot_ds_digest_type(&ref->rrs, i));
+ ret = authenticate_ds(key, &ds_rdata, knot_ds_digest_type(rd));
if (ret == 0) { /* Found a good DS */
return kr_ok();
}
return sign_ctx_add_records(ctx, covered, orig_ttl, trim_labels);
}
-int kr_check_signature(const knot_rrset_t *rrsigs, size_t pos,
+int kr_check_signature(const knot_rdata_t *rrsig,
const dnssec_key_t *key, const knot_rrset_t *covered,
int trim_labels)
{
- if (!rrsigs || !key || !dnssec_key_can_verify(key)) {
+ if (!rrsig || !key || !dnssec_key_can_verify(key)) {
return kr_error(EINVAL);
}
int ret = 0;
dnssec_sign_ctx_t *sign_ctx = NULL;
- dnssec_binary_t signature = { 0, NULL };
-
- knot_rrsig_signature(&rrsigs->rrs, pos, &signature.data, &signature.size);
+ dnssec_binary_t signature = {
+ .data = /*const-cast*/(uint8_t*)knot_rrsig_signature(rrsig),
+ .size = knot_rrsig_signature_len(rrsig),
+ };
if (!signature.data || !signature.size) {
ret = kr_error(EINVAL);
goto fail;
goto fail;
}
- uint32_t orig_ttl = knot_rrsig_original_ttl(&rrsigs->rrs, pos);
- const knot_rdata_t *rd = knot_rdataset_at(&rrsigs->rrs, pos);
+ uint32_t orig_ttl = knot_rrsig_original_ttl(rrsig);
- if (sign_ctx_add_data(sign_ctx, rd->data, covered, orig_ttl, trim_labels) != 0) {
+ if (sign_ctx_add_data(sign_ctx, rrsig->data, covered, orig_ttl, trim_labels) != 0) {
ret = kr_error(ENOMEM);
goto fail;
}
* @param trim_labels Number of the leftmost labels to be removed and replaced with '*.'.
* @return 0 if signature valid, error code else.
*/
-int kr_check_signature(const knot_rrset_t *rrsigs, size_t pos,
+int kr_check_signature(const knot_rdata_t *rrsig,
const dnssec_key_t *key, const knot_rrset_t *covered,
int trim_labels);
}
/* Fetch glue for each NS */
- for (unsigned i = 0; i < rr->rrs.count; ++i) {
- const knot_dname_t *ns_name = knot_ns_name(&rr->rrs, i);
+ knot_rdata_t *rdata_i = rr->rrs.rdata;
+ for (unsigned i = 0; i < rr->rrs.count;
+ ++i, rdata_i = knot_rdataset_next(rdata_i)) {
+ const knot_dname_t *ns_name = knot_ns_name(rdata_i);
/* Glue is mandatory for NS below zone */
if (knot_dname_in(rr->owner, ns_name) && !has_glue(pkt, ns_name)) {
const char *msg =
}
if (rr->type == KNOT_RRTYPE_RRSIG) {
- int rrsig_labels = knot_rrsig_labels(&rr->rrs, 0);
+ int rrsig_labels = knot_rrsig_labels(rr->rrs.rdata);
if (rrsig_labels > cname_labels) {
/* clearly wrong RRSIG, don't pick it.
* don't fail immediately,
continue;
}
cname_chain_len += 1;
- pending_cname = knot_cname_name(&rr->rrs);
+ pending_cname = knot_cname_name(rr->rrs.rdata);
if (!pending_cname) {
break;
}
}
if (rr->type == KNOT_RRTYPE_RRSIG) {
- const knot_dname_t *signer_name = knot_rrsig_signer_name(&rr->rrs, 0);
+ const knot_dname_t *signer_name = knot_rrsig_signer_name(rr->rrs.rdata);
if (!knot_dname_is_equal(vctx->zone_name, signer_name)) {
kr_rank_set(&entry->rank, KR_RANK_MISMATCH);
vctx->err_cnt += 1;
continue;
}
if (rr->type == KNOT_RRTYPE_RRSIG) {
- return knot_rrsig_signer_name(&rr->rrs, 0);
+ return knot_rrsig_signer_name(rr->rrs.rdata);
}
}
return NULL;
const knot_rrset_t *rr = invalid_entry->rr;
if (kr_rank_test(invalid_entry->rank, KR_RANK_MISMATCH)) {
- const knot_dname_t *signer_name = knot_rrsig_signer_name(&rr->rrs, 0);
+ const knot_dname_t *signer_name = knot_rrsig_signer_name(rr->rrs.rdata);
if (knot_dname_is_sub(signer_name, qry->zone_cut.name)) {
qry->zone_cut.name = knot_dname_copy(signer_name, &req->pool);
qry->flags.AWAIT_CUT = true;
int owner_labels = knot_dname_labels(rrsigs->owner, NULL);
- for (int k = 0; k < rrsigs->rrs.count; ++k) {
- if (knot_rrsig_labels(&rrsigs->rrs, k) != owner_labels) {
+ knot_rdata_t *rdata_k = rrsigs->rrs.rdata;
+ for (int k = 0; k < rrsigs->rrs.count;
+ ++k, rdata_k = knot_rdataset_next(rdata_k)) {
+ if (knot_rrsig_labels(rdata_k) != owner_labels) {
qry->flags.DNSSEC_WEXPAND = true;
}
}
{
bool match = rr1->type == rr2->type && rr1->rclass == rr2->rclass;
if (match && rr2->type == KNOT_RRTYPE_RRSIG) {
- match = match && knot_rrsig_type_covered(&rr1->rrs, 0)
- == knot_rrsig_type_covered(&rr2->rrs, 0);
+ match = match && knot_rrsig_type_covered(rr1->rrs.rdata)
+ == knot_rrsig_type_covered(rr2->rrs.rdata);
}
match = match && knot_dname_is_equal(rr1->owner, rr2->owner);
return match;
{
return knot_pkt_qtype(pkt);
}
-uint32_t kr_rrsig_sig_inception(const knot_rdataset_t *rrs, size_t pos)
+uint32_t kr_rrsig_sig_inception(const knot_rdata_t *rdata)
{
- return knot_rrsig_sig_inception(rrs, pos);
+ return knot_rrsig_sig_inception(rdata);
}
-uint32_t kr_rrsig_sig_expiration(const knot_rdataset_t *rrs, size_t pos)
+uint32_t kr_rrsig_sig_expiration(const knot_rdata_t *rdata)
{
- return knot_rrsig_sig_expiration(rrs, pos);
+ return knot_rrsig_sig_expiration(rdata);
}
assert(rr && rr->rrs.count && rr->rrs.rdata);
uint16_t type = rr->type;
if (type == KNOT_RRTYPE_RRSIG)
- type = knot_rrsig_type_covered(&rr->rrs, 0);
+ type = knot_rrsig_type_covered(rr->rrs.rdata);
return type;
}
uint16_t type, uint16_t rclass, uint32_t ttl);
KR_EXPORT uint16_t kr_pkt_qclass(const knot_pkt_t *pkt);
KR_EXPORT uint16_t kr_pkt_qtype(const knot_pkt_t *pkt);
-KR_EXPORT uint32_t kr_rrsig_sig_inception(const knot_rdataset_t *rrs, size_t pos);
-KR_EXPORT uint32_t kr_rrsig_sig_expiration(const knot_rdataset_t *rrs, size_t pos);
+KR_EXPORT uint32_t kr_rrsig_sig_inception(const knot_rdata_t *rdata);
+KR_EXPORT uint32_t kr_rrsig_sig_expiration(const knot_rdata_t *rdata);
/* Insert name servers for this zone cut, addresses will be looked up
* on-demand (either from cache or iteratively) */
- for (unsigned i = 0; i < ns_rds.count; ++i) {
- const knot_dname_t *ns_name = knot_ns_name(&ns_rds, i);
+ knot_rdata_t *rdata_i = ns_rds.rdata;
+ for (unsigned i = 0; i < ns_rds.count;
+ ++i, rdata_i = knot_rdataset_next(rdata_i)) {
+ const knot_dname_t *ns_name = knot_ns_name(rdata_i);
(void) kr_zonecut_add(cut, ns_name, NULL);
/* Fetch NS reputation and decide whether to prefetch A/AAAA records. */
unsigned *cached = lru_get_try(ctx->cache_rep,
local mod = {}
local event_id = nil
+local knot_rdata_pt = ffi.typeof('knot_rdata_t *');
+
-- Resolve callback
-- Check time validity of RRSIGs in priming query
-- luacheck: no unused args
if rr.type == kres.type.RRSIG then
for k = 0, rr.rrs.count - 1 do
seen_rrsigs = seen_rrsigs + 1
- inception = ffi.C.kr_rrsig_sig_inception(rr.rrs, k)
- expiration = ffi.C.kr_rrsig_sig_expiration(rr.rrs, k)
+ local rdata = ffi.cast(knot_rdata_pt, rr:rdata(k));
+ inception = ffi.C.kr_rrsig_sig_inception(rdata)
+ expiration = ffi.C.kr_rrsig_sig_expiration(rdata)
if now > expiration then
-- possitive value = in the future
time_diff = now - expiration
internal.prime = {} -- function triggering priming query
internal.event = nil -- stores event id
-local knot_rdata_t_p = ffi.typeof('knot_rdata_t *');
+local knot_rdata_pt = ffi.typeof('knot_rdata_t *');
-- Copy hints from nsset table to resolver engine
-- These addresses replace root hints loaded by default from file.
ffi.C.kr_zonecut_set(roothints, kres.str2dname("."))
for dname, addresses in pairs(nsset) do
for _, rdata_addr in pairs(addresses) do
- ffi.C.kr_zonecut_add(roothints, dname, ffi.cast(knot_rdata_t_p, rdata_addr))
+ ffi.C.kr_zonecut_add(roothints, dname, ffi.cast(knot_rdata_pt, rdata_addr))
end
end
end