/** find nsec3 closest encloser in neg cache */ static struct val_neg_data* neg_find_nsec3_ce(struct val_neg_zone* zone, uint8_t* qname, size_t qname_len, int qlabs, ldns_buffer* buf, uint8_t* hashnc, size_t* nclen) { struct val_neg_data* data; uint8_t hashce[SHA_DIGEST_LENGTH]; uint8_t b32[257]; size_t celen, b32len; *nclen = 0; while(qlabs > 0) { /* hash */ if(!(celen=nsec3_get_hashed(buf, qname, qname_len, zone->nsec3_hash, zone->nsec3_iter, zone->nsec3_salt, zone->nsec3_saltlen, hashce, sizeof(hashce)))) return NULL; if(!(b32len=nsec3_hash_to_b32(hashce, celen, zone->name, zone->len, b32, sizeof(b32)))) return NULL; /* lookup (exact match only) */ data = neg_find_data(zone, b32, b32len, zone->labs+1); if(data && data->in_use) { /* found ce match! */ return data; } *nclen = celen; memmove(hashnc, hashce, celen); dname_remove_label(&qname, &qname_len); qlabs --; } return NULL; }
/** get next closer for nsec3 proof */ static struct ub_packed_rrset_key* neg_nsec3_getnc(struct val_neg_zone* zone, uint8_t* hashnc, size_t nclen, struct rrset_cache* rrset_cache, struct regional* region, uint32_t now, uint8_t* b32, size_t maxb32) { struct ub_packed_rrset_key* nc_rrset; struct val_neg_data* data; size_t b32len; if(!(b32len=nsec3_hash_to_b32(hashnc, nclen, zone->name, zone->len, b32, maxb32))) return NULL; (void)neg_closest_data(zone, b32, b32len, zone->labs+1, &data); if(!data && zone->tree.count != 0) { /* could be before the first entry ; return the last * entry (possibly the rollover nsec3 at end) */ data = (struct val_neg_data*)rbtree_last(&zone->tree); } while(data && !data->in_use) data = data->parent; if(!data) return NULL; /* got a data element in tree, grab it */ nc_rrset = grab_nsec(rrset_cache, data->name, data->len, LDNS_RR_TYPE_NSEC3, zone->dclass, 0, region, 0, 0, now); if(!nc_rrset) return NULL; if(!neg_params_ok(zone, nc_rrset)) return NULL; return nc_rrset; }
size_t nsec3_get_nextowner_b32(struct ub_packed_rrset_key* rrset, int r, uint8_t* buf, size_t max) { uint8_t* nm, *zone; size_t nmlen, zonelen; if(!nsec3_get_nextowner(rrset, r, &nm, &nmlen)) return 0; /* append zone name; the owner name must be <b32>.zone */ zone = rrset->rk.dname; zonelen = rrset->rk.dname_len; dname_remove_label(&zone, &zonelen); return nsec3_hash_to_b32(nm, nmlen, zone, zonelen, buf, max); }