const dname_type * dname_replace(region_type* region, const dname_type* name, const dname_type* src, const dname_type* dest) { /* nomenclature: name is said to be <x>.<src>. x can be null. */ dname_type* res; int x_labels = name->label_count - src->label_count; int x_len = name->name_size - src->name_size; int i; assert(dname_is_subdomain(name, src)); /* check if final size is acceptable */ if(x_len+dest->name_size > MAXDOMAINLEN) return NULL; res = (dname_type*)region_alloc(region, sizeof(dname_type) + (x_labels+dest->label_count + x_len+dest->name_size) *sizeof(uint8_t)); res->name_size = x_len+dest->name_size; res->label_count = x_labels+dest->label_count; for(i=0; i<dest->label_count; i++) ((uint8_t*)dname_label_offsets(res))[i] = dname_label_offsets(dest)[i] + x_len; for(i=dest->label_count; i<res->label_count; i++) ((uint8_t*)dname_label_offsets(res))[i] = dname_label_offsets(name)[i - dest->label_count + src->label_count]; memcpy((uint8_t*)dname_name(res), dname_name(name), x_len); memcpy((uint8_t*)dname_name(res)+x_len, dname_name(dest), dest->name_size); assert(dname_is_subdomain(res, dest)); return res; }
const char * dname_to_string_r(const dname_type *dname, const dname_type *origin, char* buf) { size_t i; size_t labels_to_convert = 0; int absolute = 1; char *dst; const uint8_t *src; if (!dname) { *buf = '\0'; return buf; } if (dname->label_count == 1) { strlcpy(buf, ".", sizeof(buf)); return buf; } labels_to_convert = dname->label_count - 1; if (origin && dname_is_subdomain(dname, origin)) { int common_labels = dname_label_match_count(dname, origin); labels_to_convert = dname->label_count - common_labels; absolute = 0; } dst = buf; src = dname_name(dname); for (i = 0; i < labels_to_convert; ++i) { size_t len = label_length(src); size_t j; ++src; for (j = 0; j < len; ++j) { uint8_t ch = *src++; if (isalnum(ch) || ch == '-' || ch == '_') { *dst++ = ch; } else if (ch == '.' || ch == '\\') { *dst++ = '\\'; *dst++ = ch; } else { snprintf(dst, 5, "\\%03u", (unsigned int)ch); dst += 4; } } *dst++ = '.'; } if (absolute) { *dst = '\0'; } else { *--dst = '\0'; } return buf; }
static void delete_zone_rrs(namedb_type* db, zone_type* zone) { rrset_type *rrset; domain_type *domain = zone->apex; domain_type *next = NULL; zone->updated = 1; #ifdef NSEC3 #ifndef FULL_PREHASH zone_nsec3_domains_destroy(db, zone); #endif /* !FULL_PREHASH */ #endif /* NSEC3 */ /* go through entire tree below the zone apex (incl subzones) */ while(domain && dname_is_subdomain( domain_dname(domain), domain_dname(zone->apex))) { DEBUG(DEBUG_XFRD,2, (LOG_INFO, "delete zone visit %s", dname_to_string(domain_dname(domain),0))); /* delete all rrsets of the zone */ while((rrset = domain_find_any_rrset(domain, zone))) { (void)rrset_delete(db, domain, rrset); } next = domain_next(domain); domain->nextdiff = next; domain = next; } #ifdef NSEC3 #ifndef FULL_PREHASH if (0 != zone_nsec3_domains_create(db, zone)) { log_msg(LOG_ERR, "Zone %s: unable to create zone NSEC3 prehash table", dname_to_string(domain_dname(zone->apex), NULL)); } #endif /* !FULL_PREHASH */ #endif /* NSEC3 */ DEBUG(DEBUG_XFRD, 1, (LOG_INFO, "axfrdel: recyclebin holds %lu bytes", (unsigned long) region_get_recycle_size(db->region))); #ifndef NDEBUG if(nsd_debug_level >= 1) region_log_stats(db->region); #endif assert(zone->soa_rrset == 0); /* keep zone->soa_nx_rrset alloced */ assert(zone->ns_rrset == 0); assert(zone->is_secure == 0); assert(zone->updated == 1); }
/* this routine determines if below a domain there exist names with * data (is_existing) or no names below the domain have data. */ static int has_data_below(domain_type* top) { domain_type* d = top; assert(d != NULL); /* in the canonical ordering subdomains are after this name */ d = domain_next(d); while(d != NULL && dname_is_subdomain(domain_dname(d), domain_dname(top))) { if(d->is_existing) return 1; d = domain_next(d); } return 0; }