/** print one line with udb RR */ static void print_udb_rr(uint8_t* name, udb_ptr* urr) { buffer_type buffer; region_type* region = region_create(xalloc, free); region_type* tmpregion = region_create(xalloc, free); buffer_type* tmpbuffer = buffer_create(region, MAX_RDLENGTH); rr_type rr; ssize_t c; domain_table_type* owners; owners = domain_table_create(region); rr.owner = domain_table_insert(owners, dname_make(region, name, 0)); /* to RR */ rr.type = RR(urr)->type; rr.klass = RR(urr)->klass; rr.ttl = RR(urr)->ttl; buffer_create_from(&buffer, RR(urr)->wire, RR(urr)->len); c = rdata_wireformat_to_rdata_atoms(region, owners, RR(urr)->type, RR(urr)->len, &buffer, &rr.rdatas); if(c == -1) { printf("cannot parse wireformat\n"); region_destroy(region); return; } rr.rdata_count = c; print_rr(stdout, NULL, &rr, tmpregion, tmpbuffer); region_destroy(region); region_destroy(tmpregion); }
static int delete_RR(namedb_type* db, const dname_type* dname, uint16_t type, uint16_t klass, domain_type* prevdomain, buffer_type* packet, size_t rdatalen, zone_type *zone, region_type* temp_region, int is_axfr) { domain_type *domain; rrset_type *rrset; domain = domain_table_find(db->domains, dname); if(!domain) { log_msg(LOG_WARNING, "diff: domain %s does not exist", dname_to_string(dname,0)); buffer_skip(packet, rdatalen); return 1; /* not fatal error */ } rrset = domain_find_rrset(domain, zone, type); if(!rrset) { log_msg(LOG_WARNING, "diff: rrset %s does not exist", dname_to_string(dname,0)); buffer_skip(packet, rdatalen); return 1; /* not fatal error */ } else { /* find the RR in the rrset */ domain_table_type *temptable; rdata_atom_type *rdatas; ssize_t rdata_num; int rrnum; temptable = domain_table_create(temp_region); /* This will ensure that the dnames in rdata are * normalized, conform RFC 4035, section 6.2 */ rdata_num = rdata_wireformat_to_rdata_atoms( temp_region, temptable, type, rdatalen, packet, &rdatas); if(rdata_num == -1) { log_msg(LOG_ERR, "diff: bad rdata for %s", dname_to_string(dname,0)); return 0; } rrnum = find_rr_num(rrset, type, klass, rdatas, rdata_num); if(rrnum == -1) { log_msg(LOG_WARNING, "diff: RR <%s, %s> does not exist", dname_to_string(dname,0), rrtype_to_string(type)); return 1; /* not fatal error */ } #ifdef NSEC3 #ifndef FULL_PREHASH if (is_axfr == 0) { struct domain *parent = domain; do { if (0 != namedb_add_nsec3_mod_domain(db, parent)) { return 0; } parent = parent->parent; } while (parent != zone->apex->parent); } #else (void)is_axfr; #endif /* !FULL_PREHASH */ #endif /* NSEC3 */ if(rrset->rr_count == 1) { /* delete entire rrset */ domain = rrset_delete(db, domain, rrset); if (domain && domain != prevdomain && !domain->nextdiff) { /* this domain is not yet in the diff chain */ prevdomain->nextdiff = domain; } } else { /* swap out the bad RR and decrease the count */ rr_type* rrs_orig = rrset->rrs; add_rdata_to_recyclebin(db, &rrset->rrs[rrnum]); if(rrnum < rrset->rr_count-1) rrset->rrs[rrnum] = rrset->rrs[rrset->rr_count-1]; memset(&rrset->rrs[rrset->rr_count-1], 0, sizeof(rr_type)); /* realloc the rrs array one smaller */ rrset->rrs = region_alloc_init(db->region, rrs_orig, sizeof(rr_type) * (rrset->rr_count-1)); if(!rrset->rrs) { log_msg(LOG_ERR, "out of memory, %s:%d", __FILE__, __LINE__); exit(1); } region_recycle(db->region, rrs_orig, sizeof(rr_type) * rrset->rr_count); rrset->rr_count --; } } return 1; }