Beispiel #1
0
/** 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;
}
Beispiel #2
0
/** enter a new zone with allocated dname returns with WRlock */
static struct local_zone*
lz_enter_zone_dname(struct local_zones* zones, uint8_t* nm, size_t len, 
	int labs, enum localzone_type t, uint16_t c)
{
	struct local_zone* z = local_zone_create(nm, len, labs, t, c);
	if(!z) {
		free(nm);
		log_err("out of memory");
		return NULL;
	}

	/* add to rbtree */
	lock_rw_wrlock(&zones->lock);
	lock_rw_wrlock(&z->lock);
	if(!rbtree_insert(&zones->ztree, &z->node)) {
		log_warn("duplicate local-zone");
		lock_rw_unlock(&z->lock);
		local_zone_delete(z);
		/* find the correct zone, so not an error for duplicate */
		z = local_zones_find(zones, nm, len, labs, c);
		lock_rw_wrlock(&z->lock);
		lock_rw_unlock(&zones->lock);
		return z;
	}
	lock_rw_unlock(&zones->lock);
	return z;
}
Beispiel #3
0
struct local_zone* local_zones_add_zone(struct local_zones* zones,
	uint8_t* name, size_t len, int labs, uint16_t dclass,
	enum localzone_type tp)
{
	/* create */
	struct local_zone* z = local_zone_create(name, len, labs, tp, dclass);
	if(!z) {
		free(name);
		return NULL;
	}
	lock_rw_wrlock(&z->lock);

	/* find the closest parent */
	z->parent = local_zones_find(zones, name, len, labs, dclass);

	/* insert into the tree */
	if(!rbtree_insert(&zones->ztree, &z->node)) {
		/* duplicate entry! */
		lock_rw_unlock(&z->lock);
		local_zone_delete(z);
		log_err("internal: duplicate entry in local_zones_add_zone");
		return NULL;
	}

	/* set parent pointers right */
	set_kiddo_parents(z, z->parent, z);

	lock_rw_unlock(&z->lock);
	return z;
}
Beispiel #4
0
/** Remove a zone */
static void
do_zone_remove(SSL* ssl, struct worker* worker, char* arg)
{
	uint8_t* nm;
	int nmlabs;
	size_t nmlen;
	struct local_zone* z;
	if(!parse_arg_name(ssl, arg, &nm, &nmlen, &nmlabs))
		return;
	lock_quick_lock(&worker->daemon->local_zones->lock);
	if((z=local_zones_find(worker->daemon->local_zones, nm, nmlen, 
		nmlabs, LDNS_RR_CLASS_IN))) {
		/* present in tree */
		local_zones_del_zone(worker->daemon->local_zones, z);
	}
	lock_quick_unlock(&worker->daemon->local_zones->lock);
	free(nm);
	send_ok(ssl);
}
Beispiel #5
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;
}
Beispiel #6
0
/** Add a new zone */
static void
do_zone_add(SSL* ssl, struct worker* worker, char* arg)
{
	uint8_t* nm;
	int nmlabs;
	size_t nmlen;
	char* arg2;
	enum localzone_type t;
	struct local_zone* z;
	if(!find_arg2(ssl, arg, &arg2))
		return;
	if(!parse_arg_name(ssl, arg, &nm, &nmlen, &nmlabs))
		return;
	if(!local_zone_str2type(arg2, &t)) {
		ssl_printf(ssl, "error not a zone type. %s\n", arg2);
		free(nm);
		return;
	}
	lock_quick_lock(&worker->daemon->local_zones->lock);
	if((z=local_zones_find(worker->daemon->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);
		free(nm);
		lock_quick_unlock(&worker->daemon->local_zones->lock);
		send_ok(ssl);
		return;
	}
	if(!local_zones_add_zone(worker->daemon->local_zones, nm, nmlen, 
		nmlabs, LDNS_RR_CLASS_IN, t)) {
		lock_quick_unlock(&worker->daemon->local_zones->lock);
		ssl_printf(ssl, "error out of memory\n");
		return;
	}
	lock_quick_unlock(&worker->daemon->local_zones->lock);
	send_ok(ssl);
}
Beispiel #7
0
/* 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;
}
Beispiel #8
0
/** 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;
}