/** enter tagstring into zone */ static int lz_enter_zone_tag(struct local_zones* zones, char* zname, uint8_t* list, size_t len, uint16_t rr_class) { uint8_t dname[LDNS_MAX_DOMAINLEN+1]; size_t dname_len = sizeof(dname); int dname_labs, r = 0; struct local_zone* z; if(sldns_str2wire_dname_buf(zname, dname, &dname_len) != 0) { log_err("cannot parse zone name in local-zone-tag: %s", zname); return 0; } dname_labs = dname_count_labels(dname); lock_rw_rdlock(&zones->lock); z = local_zones_find(zones, dname, dname_len, dname_labs, rr_class); if(!z) { lock_rw_unlock(&zones->lock); log_err("no local-zone for tag %s", zname); return 0; } lock_rw_wrlock(&z->lock); lock_rw_unlock(&zones->lock); free(z->taglist); z->taglist = memdup(list, len); z->taglen = len; if(z->taglist) r = 1; lock_rw_unlock(&z->lock); return r; }
/** put dname into buffer */ static sldns_buffer* dname_to_buf(sldns_buffer* b, const char* str) { int e; size_t len = sldns_buffer_capacity(b); sldns_buffer_clear(b); e = sldns_str2wire_dname_buf(str, sldns_buffer_begin(b), &len); if(e != 0) fatal_exit("%s ldns: %s", __func__, sldns_get_errorstr_parse(e)); sldns_buffer_set_position(b, len); sldns_buffer_flip(b); return b; }
/** enter override into zone */ static int lz_enter_override(struct local_zones* zones, char* zname, char* netblock, char* type, uint16_t rr_class) { uint8_t dname[LDNS_MAX_DOMAINLEN+1]; size_t dname_len = sizeof(dname); int dname_labs; struct sockaddr_storage addr; int net; socklen_t addrlen; struct local_zone* z; enum localzone_type t; /* parse zone name */ if(sldns_str2wire_dname_buf(zname, dname, &dname_len) != 0) { log_err("cannot parse zone name in local-zone-override: %s %s", zname, netblock); return 0; } dname_labs = dname_count_labels(dname); /* parse netblock */ if(!netblockstrtoaddr(netblock, UNBOUND_DNS_PORT, &addr, &addrlen, &net)) { log_err("cannot parse netblock in local-zone-override: %s %s", zname, netblock); return 0; } /* parse zone type */ if(!local_zone_str2type(type, &t)) { log_err("cannot parse type in local-zone-override: %s %s %s", zname, netblock, type); return 0; } /* find localzone entry */ lock_rw_rdlock(&zones->lock); z = local_zones_find(zones, dname, dname_len, dname_labs, rr_class); if(!z) { lock_rw_unlock(&zones->lock); log_err("no local-zone for local-zone-override %s", zname); return 0; } lock_rw_wrlock(&z->lock); lock_rw_unlock(&zones->lock); /* create netblock addr_tree if not present yet */ if(!z->override_tree) { z->override_tree = (struct rbtree_t*)regional_alloc_zero( z->region, sizeof(*z->override_tree)); if(!z->override_tree) { lock_rw_unlock(&z->lock); log_err("out of memory"); return 0; } addr_tree_init(z->override_tree); } /* add new elem to tree */ if(z->override_tree) { struct local_zone_override* n; n = (struct local_zone_override*)regional_alloc_zero( z->region, sizeof(*n)); if(!n) { lock_rw_unlock(&z->lock); log_err("out of memory"); return 0; } n->type = t; if(!addr_tree_insert(z->override_tree, (struct addr_tree_node*)n, &addr, addrlen, net)) { lock_rw_unlock(&z->lock); log_err("duplicate local-zone-override %s %s", zname, netblock); return 1; } } lock_rw_unlock(&z->lock); return 1; }