void val_neg_addreferral(struct val_neg_cache* neg, struct reply_info* rep, uint8_t* zone_name) { size_t i, need; uint8_t* signer; size_t signer_len; uint16_t dclass; struct val_neg_zone* zone; /* no SOA in this message, find RRSIG over NSEC's signer name. * note the NSEC records are maybe not validated yet */ signer = reply_nsec_signer(rep, &signer_len, &dclass); if(!signer) return; if(!dname_subdomain_c(signer, zone_name)) { /* the signer is not in the bailiwick, throw it out */ return; } log_nametypeclass(VERB_ALGO, "negcache insert referral ", signer, LDNS_RR_TYPE_NS, dclass); /* ask for enough space to store all of it */ need = calc_data_need(rep) + calc_zone_need(signer, signer_len); lock_basic_lock(&neg->lock); neg_make_space(neg, need); /* find or create the zone entry */ zone = neg_find_zone(neg, signer, signer_len, dclass); if(!zone) { if(!(zone = neg_create_zone(neg, signer, signer_len, dclass))) { lock_basic_unlock(&neg->lock); log_err("out of memory adding negative zone"); return; } } val_neg_zone_take_inuse(zone); /* insert the NSECs */ for(i=rep->an_numrrsets; i< rep->an_numrrsets+rep->ns_numrrsets; i++){ if(ntohs(rep->rrsets[i]->rk.type) != LDNS_RR_TYPE_NSEC && ntohs(rep->rrsets[i]->rk.type) != LDNS_RR_TYPE_NSEC3) continue; if(!dname_subdomain_c(rep->rrsets[i]->rk.dname, zone->name)) continue; /* insert NSEC into this zone's tree */ neg_insert_data(neg, zone, rep->rrsets[i]); } if(zone->tree.count == 0) { /* remove empty zone if inserts failed */ neg_delete_zone(neg, zone); } lock_basic_unlock(&neg->lock); }
void val_neg_addreply(struct val_neg_cache* neg, struct reply_info* rep) { size_t i, need; struct ub_packed_rrset_key* soa; struct val_neg_zone* zone; /* see if secure nsecs inside */ if(!reply_has_nsec(rep)) return; /* find the zone name in message */ soa = reply_find_soa(rep); if(!soa) return; log_nametypeclass(VERB_ALGO, "negcache insert for zone", soa->rk.dname, LDNS_RR_TYPE_SOA, ntohs(soa->rk.rrset_class)); /* ask for enough space to store all of it */ need = calc_data_need(rep) + calc_zone_need(soa->rk.dname, soa->rk.dname_len); lock_basic_lock(&neg->lock); neg_make_space(neg, need); /* find or create the zone entry */ zone = neg_find_zone(neg, soa->rk.dname, soa->rk.dname_len, ntohs(soa->rk.rrset_class)); if(!zone) { if(!(zone = neg_create_zone(neg, soa->rk.dname, soa->rk.dname_len, ntohs(soa->rk.rrset_class)))) { lock_basic_unlock(&neg->lock); log_err("out of memory adding negative zone"); return; } } val_neg_zone_take_inuse(zone); /* insert the NSECs */ for(i=rep->an_numrrsets; i< rep->an_numrrsets+rep->ns_numrrsets; i++){ if(ntohs(rep->rrsets[i]->rk.type) != LDNS_RR_TYPE_NSEC) continue; if(!dname_subdomain_c(rep->rrsets[i]->rk.dname, zone->name)) continue; /* insert NSEC into this zone's tree */ neg_insert_data(neg, zone, rep->rrsets[i]); } if(zone->tree.count == 0) { /* remove empty zone if inserts failed */ neg_delete_zone(neg, zone); } lock_basic_unlock(&neg->lock); }
/** add a random item */ static void add_item(struct val_neg_cache* neg) { struct val_neg_zone* z; struct packed_rrset_data rd; struct ub_packed_rrset_key nsec; size_t rr_len; time_t rr_ttl; uint8_t* rr_data; char* zname = get_random_zone(); char* from, *to; lock_basic_lock(&neg->lock); if(negverbose) log_nametypeclass(0, "add to zone", (uint8_t*)zname, 0, 0); z = neg_find_zone(neg, (uint8_t*)zname, strlen(zname)+1, LDNS_RR_CLASS_IN); if(!z) { z = neg_create_zone(neg, (uint8_t*)zname, strlen(zname)+1, LDNS_RR_CLASS_IN); } unit_assert(z); val_neg_zone_take_inuse(z); /* construct random NSEC item */ get_random_data(&from, &to, zname); /* create nsec and insert it */ memset(&rd, 0, sizeof(rd)); memset(&nsec, 0, sizeof(nsec)); nsec.rk.dname = (uint8_t*)from; nsec.rk.dname_len = strlen(from)+1; nsec.rk.type = htons(LDNS_RR_TYPE_NSEC); nsec.rk.rrset_class = htons(LDNS_RR_CLASS_IN); nsec.entry.data = &rd; rd.security = sec_status_secure; rd.count = 1; rd.rr_len = &rr_len; rr_len = 19; rd.rr_ttl = &rr_ttl; rr_ttl = 0; rd.rr_data = &rr_data; rr_data = (uint8_t*)to; neg_insert_data(neg, z, &nsec); lock_basic_unlock(&neg->lock); }