mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-02-18 10:09:27 -05:00
- rpz-zone-load, optimise rpz_insert_local_zones_trigger to remove second
local zones tree lookup for non local data cases.
This commit is contained in:
parent
08a2734e91
commit
098200ba5a
6 changed files with 49 additions and 8 deletions
|
|
@ -1339,7 +1339,7 @@ perform_zone_add(RES* ssl, struct local_zones* zones, char* arg)
|
|||
return 1;
|
||||
}
|
||||
if(!local_zones_add_zone(zones, nm, nmlen,
|
||||
nmlabs, LDNS_RR_CLASS_IN, t)) {
|
||||
nmlabs, LDNS_RR_CLASS_IN, t, NULL)) {
|
||||
lock_rw_unlock(&zones->lock);
|
||||
ssl_printf(ssl, "error out of memory\n");
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -1385,7 +1385,7 @@ int ub_ctx_zone_add(struct ub_ctx* ctx, const char *zone_name,
|
|||
return UB_NOERROR;
|
||||
}
|
||||
if(!local_zones_add_zone(ctx->local_zones, nm, nmlen, nmlabs,
|
||||
LDNS_RR_CLASS_IN, t)) {
|
||||
LDNS_RR_CLASS_IN, t, NULL)) {
|
||||
lock_rw_unlock(&ctx->local_zones->lock);
|
||||
return UB_NOMEM;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2231,7 +2231,7 @@ set_kiddo_parents(struct local_zone* z, struct local_zone* match,
|
|||
|
||||
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)
|
||||
enum localzone_type tp, int* duplicate)
|
||||
{
|
||||
int exact;
|
||||
/* create */
|
||||
|
|
@ -2239,6 +2239,7 @@ struct local_zone* local_zones_add_zone(struct local_zones* zones,
|
|||
struct local_zone* z = local_zone_create(name, len, labs, tp, dclass);
|
||||
if(!z) {
|
||||
free(name);
|
||||
if(duplicate) *duplicate = 0;
|
||||
return NULL;
|
||||
}
|
||||
lock_rw_wrlock(&z->lock);
|
||||
|
|
@ -2252,8 +2253,14 @@ struct local_zone* local_zones_add_zone(struct local_zones* zones,
|
|||
if(exact||!rbtree_insert(&zones->ztree, &z->node)) {
|
||||
/* duplicate entry! */
|
||||
lock_rw_unlock(&z->lock);
|
||||
if(duplicate) {
|
||||
*duplicate = 1;
|
||||
z->name = NULL; /* Do not delete the name in
|
||||
local_zone_delete. */
|
||||
}
|
||||
local_zone_delete(z);
|
||||
log_err("internal: duplicate entry in local_zones_add_zone");
|
||||
if(duplicate == NULL)
|
||||
log_err("internal: duplicate entry in local_zones_add_zone");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -2297,7 +2304,7 @@ local_zones_add_RR(struct local_zones* zones, const char* rr)
|
|||
z = local_zones_lookup(zones, rr_name, len, labs, rr_class, rr_type);
|
||||
if(!z) {
|
||||
z = local_zones_add_zone(zones, rr_name, len, labs, rr_class,
|
||||
local_zone_transparent);
|
||||
local_zone_transparent, NULL);
|
||||
if(!z) {
|
||||
lock_rw_unlock(&zones->lock);
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -403,11 +403,17 @@ local_zones_find_le(struct local_zones* zones,
|
|||
* @param labs: labelcount of name.
|
||||
* @param dclass: class to add.
|
||||
* @param tp: type.
|
||||
* @param duplicate: Allows to check if a NULL return from the function is a
|
||||
* memory error, or a duplicate entry. Pass NULL to have it not returned,
|
||||
* the name is freed on errors, and for a duplicate a log message is
|
||||
* printed. Pass not NULL, and when the error is a duplicate, the function
|
||||
* returns NULL, and the variable is set true. The name is not freed
|
||||
* when there is a duplicate, no error is printed by this function.
|
||||
* @return local_zone or NULL on error, caller must printout memory error.
|
||||
*/
|
||||
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);
|
||||
enum localzone_type tp, int* duplicate);
|
||||
|
||||
/**
|
||||
* Delete a zone. Caller must hold the zones lock.
|
||||
|
|
|
|||
|
|
@ -698,6 +698,34 @@ rpz_insert_local_zones_trigger(struct local_zones* lz, uint8_t* dname,
|
|||
return;
|
||||
}
|
||||
|
||||
/* For not a local-data action.
|
||||
* Insert the zone, then detect a duplicate, instead of find it first,
|
||||
* for speed of searching the tree once. */
|
||||
if(a != RPZ_LOCAL_DATA_ACTION) {
|
||||
int duplicate = 0;
|
||||
lock_rw_wrlock(&lz->lock);
|
||||
tp = rpz_action_to_localzone_type(a);
|
||||
z = local_zones_add_zone(lz, dname, dnamelen,
|
||||
dnamelabs, rrclass, tp, &duplicate);
|
||||
if(z == NULL) {
|
||||
if(duplicate) {
|
||||
char* rrstr = dname_rdata_to_str(dname, dnamelen, rrtype,
|
||||
rrclass, ttl, rdata, rdata_len);
|
||||
verbose(VERB_ALGO, "rpz: skipping duplicate record: %s", rrstr);
|
||||
free(rrstr);
|
||||
free(dname);
|
||||
lock_rw_unlock(&lz->lock);
|
||||
return;
|
||||
}
|
||||
log_warn("rpz: create failed, out of memory");
|
||||
lock_rw_unlock(&lz->lock);
|
||||
/* dname will be free'd in failed local_zone_create() */
|
||||
return;
|
||||
}
|
||||
lock_rw_unlock(&lz->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
lock_rw_wrlock(&lz->lock);
|
||||
/* exact match */
|
||||
z = local_zones_find(lz, dname, dnamelen, dnamelabs, LDNS_RR_CLASS_IN);
|
||||
|
|
@ -713,7 +741,7 @@ rpz_insert_local_zones_trigger(struct local_zones* lz, uint8_t* dname,
|
|||
if(z == NULL) {
|
||||
tp = rpz_action_to_localzone_type(a);
|
||||
z = local_zones_add_zone(lz, dname, dnamelen,
|
||||
dnamelabs, rrclass, tp);
|
||||
dnamelabs, rrclass, tp, NULL);
|
||||
if(z == NULL) {
|
||||
log_warn("rpz: create failed");
|
||||
lock_rw_unlock(&lz->lock);
|
||||
|
|
|
|||
|
|
@ -1265,7 +1265,7 @@ static void localzone_parents_test(void)
|
|||
nmlabs = dname_count_size_labels(nm, &nmlen);
|
||||
lock_rw_wrlock(&z2->lock);
|
||||
local_zones_add_zone(z2, nm, nmlen, nmlabs, LDNS_RR_CLASS_IN,
|
||||
local_zone_always_nxdomain);
|
||||
local_zone_always_nxdomain, NULL);
|
||||
lock_rw_unlock(&z2->lock);
|
||||
}
|
||||
/* The trees should be the same, iterate and check the nodes */
|
||||
|
|
|
|||
Loading…
Reference in a new issue