From: Ralph Dolmans Date: Tue, 7 Jun 2016 08:36:19 +0000 (+0000) Subject: - Lookup localzones by taglist from acl. X-Git-Tag: release-1.5.10~100 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ff091efe7b155d9b1b229ba0549e8c977fa45376;p=thirdparty%2Funbound.git - Lookup localzones by taglist from acl. git-svn-id: file:///svn/unbound/trunk@3764 be551aaa-1e26-0410-a405-d3ace91eadb9 --- diff --git a/daemon/acl_list.c b/daemon/acl_list.c index 98be99b35..d09b46e5e 100644 --- a/daemon/acl_list.c +++ b/daemon/acl_list.c @@ -392,13 +392,18 @@ acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg) } enum acl_access -acl_list_lookup(struct acl_list* acl, struct sockaddr_storage* addr, +acl_get_control(struct acl_addr* acl) +{ + if(acl) return acl->control; + return acl_deny; +} + +struct acl_addr* +acl_addr_lookup(struct acl_list* acl, struct sockaddr_storage* addr, socklen_t addrlen) { - struct acl_addr* r = (struct acl_addr*)addr_tree_lookup(&acl->tree, + return (struct acl_addr*)addr_tree_lookup(&acl->tree, addr, addrlen); - if(r) return r->control; - return acl_deny; } size_t diff --git a/daemon/acl_list.h b/daemon/acl_list.h index fd4374d8f..fc0e9cabf 100644 --- a/daemon/acl_list.h +++ b/daemon/acl_list.h @@ -123,14 +123,22 @@ void acl_list_delete(struct acl_list* acl); int acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg); /** - * Lookup address to see its access control status. + * Lookup access control status for acl structure. + * @param acl: structure for acl storage. + * @return: what to do with message from this address. + */ +enum acl_access acl_get_control(struct acl_addr* acl); + +/** + * Lookup address to see its acl structure * @param acl: structure for address storage. * @param addr: address to check * @param addrlen: length of addr. - * @return: what to do with message from this address. + * @return: acl structure from this address. */ -enum acl_access acl_list_lookup(struct acl_list* acl, - struct sockaddr_storage* addr, socklen_t addrlen); +struct acl_addr* +acl_addr_lookup(struct acl_list* acl, struct sockaddr_storage* addr, + socklen_t addrlen); /** * Get memory used by acl structure. diff --git a/daemon/worker.c b/daemon/worker.c index 33a6883f9..fb4f73c6d 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -804,6 +804,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error, struct query_info qinfo; struct edns_data edns; enum acl_access acl; + struct acl_addr* acladdr; int rc = 0; if(error != NETEVENT_NOERROR) { @@ -816,8 +817,9 @@ worker_handle_request(struct comm_point* c, void* arg, int error, dt_msg_send_client_query(&worker->dtenv, &repinfo->addr, c->type, c->buffer); #endif - acl = acl_list_lookup(worker->daemon->acl, &repinfo->addr, + acladdr = acl_addr_lookup(worker->daemon->acl, &repinfo->addr, repinfo->addrlen); + acl = acl_get_control(acladdr); if((ret=deny_refuse_all(c, acl, worker, repinfo)) != -1) { if(ret == 1) @@ -941,7 +943,8 @@ worker_handle_request(struct comm_point* c, void* arg, int error, goto send_reply; } if(local_zones_answer(worker->daemon->local_zones, &qinfo, &edns, - c->buffer, worker->scratchpad, repinfo)) { + c->buffer, worker->scratchpad, repinfo, + acladdr->taglist, acladdr->taglen)) { regional_free_all(worker->scratchpad); if(sldns_buffer_limit(c->buffer) == 0) { comm_point_drop_reply(repinfo); diff --git a/doc/Changelog b/doc/Changelog index 660157147..21a09daf9 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,3 +1,6 @@ +7 June 2016: Ralph + - Lookup localzones by taglist from acl. + 7 June 2016: Wouter - Fix #773: Non-standard Python location build failure with pyunbound. diff --git a/libunbound/libworker.c b/libunbound/libworker.c index 2af392706..899210978 100644 --- a/libunbound/libworker.c +++ b/libunbound/libworker.c @@ -608,7 +608,7 @@ int libworker_fg(struct ub_ctx* ctx, struct ctx_query* q) sldns_buffer_write_u16_at(w->back->udp_buff, 0, qid); sldns_buffer_write_u16_at(w->back->udp_buff, 2, qflags); if(local_zones_answer(ctx->local_zones, &qinfo, &edns, - w->back->udp_buff, w->env->scratch, NULL)) { + w->back->udp_buff, w->env->scratch, NULL, NULL, 0)) { regional_free_all(w->env->scratch); libworker_fillup_fg(q, LDNS_RCODE_NOERROR, w->back->udp_buff, sec_status_insecure, NULL); @@ -678,7 +678,7 @@ int libworker_attach_mesh(struct ub_ctx* ctx, struct ctx_query* q, sldns_buffer_write_u16_at(w->back->udp_buff, 0, qid); sldns_buffer_write_u16_at(w->back->udp_buff, 2, qflags); if(local_zones_answer(ctx->local_zones, &qinfo, &edns, - w->back->udp_buff, w->env->scratch, NULL)) { + w->back->udp_buff, w->env->scratch, NULL, NULL, 0)) { regional_free_all(w->env->scratch); free(qinfo.qname); libworker_event_done_cb(q, LDNS_RCODE_NOERROR, @@ -798,7 +798,7 @@ handle_newq(struct libworker* w, uint8_t* buf, uint32_t len) sldns_buffer_write_u16_at(w->back->udp_buff, 0, qid); sldns_buffer_write_u16_at(w->back->udp_buff, 2, qflags); if(local_zones_answer(w->ctx->local_zones, &qinfo, &edns, - w->back->udp_buff, w->env->scratch, NULL)) { + w->back->udp_buff, w->env->scratch, NULL, NULL, 0)) { regional_free_all(w->env->scratch); q->msg_security = sec_status_insecure; add_bg_result(w, q, w->back->udp_buff, UB_NOERROR, NULL); diff --git a/services/localzone.c b/services/localzone.c index 7acb5bd72..1f8c63bce 100644 --- a/services/localzone.c +++ b/services/localzone.c @@ -1013,6 +1013,15 @@ local_zones_apply_cfg(struct local_zones* zones, struct config_file* cfg) struct local_zone* local_zones_lookup(struct local_zones* zones, uint8_t* name, size_t len, int labs, uint16_t dclass) +{ + return local_zones_tags_lookup(zones, name, len, labs, + dclass, NULL, 0); +} + +struct local_zone* +local_zones_tags_lookup(struct local_zones* zones, + uint8_t* name, size_t len, int labs, uint16_t dclass, + uint8_t* taglist, size_t taglen) { rbnode_t* res = NULL; struct local_zone *result; @@ -1022,25 +1031,26 @@ local_zones_lookup(struct local_zones* zones, key.name = name; key.namelen = len; key.namelabs = labs; - if(rbtree_find_less_equal(&zones->ztree, &key, &res)) { - /* exact */ - return (struct local_zone*)res; - } else { - /* smaller element (or no element) */ - int m; - result = (struct local_zone*)res; - if(!result || result->dclass != dclass) - return NULL; - /* count number of labels matched */ - (void)dname_lab_cmp(result->name, result->namelabs, key.name, - key.namelabs, &m); - while(result) { /* go up until qname is subdomain of zone */ - if(result->namelabs <= m) - break; - result = result->parent; - } - return result; + rbtree_find_less_equal(&zones->ztree, &key, &res); + result = (struct local_zone*)res; + /* exact or smaller element (or no element) */ + int m; + if(!result || result->dclass != dclass) + return NULL; + /* count number of labels matched */ + (void)dname_lab_cmp(result->name, result->namelabs, key.name, + key.namelabs, &m); + while(result) { /* go up until qname is zone or subdomain of zone */ + if(result->namelabs <= m) { + if(!result->taglist) + break; + if(taglist_intersect(result->taglist, + result->taglen, taglist, taglen)) + break; + } + result = result->parent; } + return result; } struct local_zone* @@ -1278,7 +1288,7 @@ lz_inform_print(struct local_zone* z, struct query_info* qinfo, int local_zones_answer(struct local_zones* zones, struct query_info* qinfo, struct edns_data* edns, sldns_buffer* buf, struct regional* temp, - struct comm_reply* repinfo) + struct comm_reply* repinfo, uint8_t* taglist, size_t taglen) { /* see if query is covered by a zone, * if so: - try to match (exact) local data @@ -1288,8 +1298,8 @@ local_zones_answer(struct local_zones* zones, struct query_info* qinfo, struct local_zone* z; int r; lock_rw_rdlock(&zones->lock); - z = local_zones_lookup(zones, qinfo->qname, - qinfo->qname_len, labs, qinfo->qclass); + z = local_zones_tags_lookup(zones, qinfo->qname, + qinfo->qname_len, labs, qinfo->qclass, taglist, taglen); if(!z) { lock_rw_unlock(&zones->lock); return 0; diff --git a/services/localzone.h b/services/localzone.h index 91347cdaf..253584a4d 100644 --- a/services/localzone.h +++ b/services/localzone.h @@ -215,6 +215,22 @@ int local_data_cmp(const void* d1, const void* d2); */ void local_zone_delete(struct local_zone* z); +/** + * Lookup zone that contains the given name, class and taglist. + * User must lock the tree or result zone. + * @param zones: the zones tree + * @param name: dname to lookup + * @param len: length of name. + * @param labs: labelcount of name. + * @param dclass: class to lookup. + * @param taglist: taglist to lookup. + * @param taglen: lenth of taglist. + * @return closest local_zone or NULL if no covering zone is found. + */ +struct local_zone* local_zones_tags_lookup(struct local_zones* zones, + uint8_t* name, size_t len, int labs, uint16_t dclass, + uint8_t* taglist, size_t taglen); + /** * Lookup zone that contains the given name, class. * User must lock the tree or result zone. @@ -244,13 +260,15 @@ void local_zones_print(struct local_zones* zones); * @param buf: buffer with query ID and flags, also for reply. * @param temp: temporary storage region. * @param repinfo: source address for checks. may be NULL. + * @param taglist: taglist for checks. May be NULL. + * @param taglen: length of the taglist. * @return true if answer is in buffer. false if query is not answered * by authority data. If the reply should be dropped altogether, the return * value is true, but the buffer is cleared (empty). */ int local_zones_answer(struct local_zones* zones, struct query_info* qinfo, struct edns_data* edns, struct sldns_buffer* buf, struct regional* temp, - struct comm_reply* repinfo); + struct comm_reply* repinfo, uint8_t* taglist, size_t taglen); /** * Parse the string into localzone type.