- 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:
W.C.A. Wijngaards 2026-01-28 11:48:53 +01:00
parent 08a2734e91
commit 098200ba5a
6 changed files with 49 additions and 8 deletions

View file

@ -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;

View file

@ -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;
}

View file

@ -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;

View file

@ -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.

View file

@ -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);

View file

@ -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 */