/* Remove RR data */ int ub_ctx_data_remove(struct ub_ctx* ctx, char *data) { uint8_t* nm; int nmlabs; size_t nmlen; int res = ub_ctx_finalize(ctx); if (res) return res; if(!parse_dname(data, &nm, &nmlen, &nmlabs)) return UB_SYNTAX; local_zones_del_data(ctx->local_zones, nm, nmlen, nmlabs, LDNS_RR_CLASS_IN); free(nm); return UB_NOERROR; }
/** lookup a zone in rbtree; exact match only; SLOW due to parse */ static int lz_exists(struct local_zones* zones, const char* name) { struct local_zone z; z.node.key = &z; z.dclass = LDNS_RR_CLASS_IN; if(!parse_dname(name, &z.name, &z.namelen, &z.namelabs)) { log_err("bad name %s", name); return 0; } lock_rw_rdlock(&zones->lock); if(rbtree_search(&zones->ztree, &z.node)) { lock_rw_unlock(&zones->lock); free(z.name); return 1; } lock_rw_unlock(&zones->lock); free(z.name); return 0; }
/* Add a new zone */ int ub_ctx_zone_add(struct ub_ctx* ctx, const char *zone_name, const char *zone_type) { enum localzone_type t; struct local_zone* z; uint8_t* nm; int nmlabs; size_t nmlen; int res = ub_ctx_finalize(ctx); if (res) return res; if(!local_zone_str2type(zone_type, &t)) { return UB_SYNTAX; } if(!parse_dname(zone_name, &nm, &nmlen, &nmlabs)) { return UB_SYNTAX; } lock_rw_wrlock(&ctx->local_zones->lock); if((z=local_zones_find(ctx->local_zones, nm, nmlen, nmlabs, LDNS_RR_CLASS_IN))) { /* already present in tree */ lock_rw_wrlock(&z->lock); z->type = t; /* update type anyway */ lock_rw_unlock(&z->lock); lock_rw_unlock(&ctx->local_zones->lock); free(nm); return UB_NOERROR; } if(!local_zones_add_zone(ctx->local_zones, nm, nmlen, nmlabs, LDNS_RR_CLASS_IN, t)) { lock_rw_unlock(&ctx->local_zones->lock); return UB_NOMEM; } lock_rw_unlock(&ctx->local_zones->lock); return UB_NOERROR; }
/* Remove zone */ int ub_ctx_zone_remove(struct ub_ctx* ctx, char *zone_name) { struct local_zone* z; uint8_t* nm; int nmlabs; size_t nmlen; int res = ub_ctx_finalize(ctx); if (res) return res; if(!parse_dname(zone_name, &nm, &nmlen, &nmlabs)) { return UB_SYNTAX; } lock_quick_lock(&ctx->local_zones->lock); if((z=local_zones_find(ctx->local_zones, nm, nmlen, nmlabs, LDNS_RR_CLASS_IN))) { /* present in tree */ local_zones_del_zone(ctx->local_zones, z); } lock_quick_unlock(&ctx->local_zones->lock); free(nm); return UB_NOERROR; }
/** enter a new zone */ static struct local_zone* lz_enter_zone(struct local_zones* zones, const char* name, const char* type, uint16_t dclass) { struct local_zone* z; enum localzone_type t; uint8_t* nm; size_t len; int labs; if(!parse_dname(name, &nm, &len, &labs)) { log_err("bad zone name %s %s", name, type); return NULL; } if(!local_zone_str2type(type, &t)) { log_err("bad lz_enter_zone type %s %s", name, type); free(nm); return NULL; } if(!(z=lz_enter_zone_dname(zones, nm, len, labs, t, dclass))) { log_err("could not enter zone %s %s", name, type); return NULL; } return z; }
int ub_ctx_set_stub(struct ub_ctx* ctx, const char* zone, const char* addr, int isprime) { char* a; struct config_stub **prev, *elem; /* check syntax for zone name */ if(zone) { uint8_t* nm; int nmlabs; size_t nmlen; if(!parse_dname(zone, &nm, &nmlen, &nmlabs)) { errno=EINVAL; return UB_SYNTAX; } free(nm); } else { zone = "."; } /* check syntax for addr (if not NULL) */ if(addr) { struct sockaddr_storage storage; socklen_t stlen; if(!extstrtoaddr(addr, &storage, &stlen)) { errno=EINVAL; return UB_SYNTAX; } } lock_basic_lock(&ctx->cfglock); if(ctx->finalized) { lock_basic_unlock(&ctx->cfglock); errno=EINVAL; return UB_AFTERFINAL; } /* arguments all right, now find or add the stub */ prev = &ctx->env->cfg->stubs; elem = cfg_stub_find(&prev, zone); if(!elem && !addr) { /* not found and we want to delete, nothing to do */ lock_basic_unlock(&ctx->cfglock); return UB_NOERROR; } else if(elem && !addr) { /* found, and we want to delete */ *prev = elem->next; config_delstub(elem); lock_basic_unlock(&ctx->cfglock); return UB_NOERROR; } else if(!elem) { /* not found, create the stub entry */ elem=(struct config_stub*)calloc(1, sizeof(struct config_stub)); if(elem) elem->name = strdup(zone); if(!elem || !elem->name) { free(elem); lock_basic_unlock(&ctx->cfglock); errno = ENOMEM; return UB_NOMEM; } elem->next = ctx->env->cfg->stubs; ctx->env->cfg->stubs = elem; } /* add the address to the list and set settings */ elem->isprime = isprime; a = strdup(addr); if(!a) { lock_basic_unlock(&ctx->cfglock); errno = ENOMEM; return UB_NOMEM; } if(!cfg_strlist_insert(&elem->addrs, a)) { lock_basic_unlock(&ctx->cfglock); errno = ENOMEM; return UB_NOMEM; } lock_basic_unlock(&ctx->cfglock); return UB_NOERROR; }