]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Lookup localzones by taglist from acl.
authorRalph Dolmans <ralph@nlnetlabs.nl>
Tue, 7 Jun 2016 08:36:19 +0000 (08:36 +0000)
committerRalph Dolmans <ralph@nlnetlabs.nl>
Tue, 7 Jun 2016 08:36:19 +0000 (08:36 +0000)
git-svn-id: file:///svn/unbound/trunk@3764 be551aaa-1e26-0410-a405-d3ace91eadb9

daemon/acl_list.c
daemon/acl_list.h
daemon/worker.c
doc/Changelog
libunbound/libworker.c
services/localzone.c
services/localzone.h

index 98be99b35b3835c4a18c305984f2993b4438c31f..d09b46e5e04687f2d546c1533da1e008fee617af 100644 (file)
@@ -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 
index fd4374d8f327b38a524789da02fbdb3da3a356e6..fc0e9cabf3dfc43b8877c2b885285e445fd350ad 100644 (file)
@@ -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.
index 33a6883f9219ab55c3c4aef021540a53a6afe47b..fb4f73c6d2758a08c521891a3c768fef694648aa 100644 (file)
@@ -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);
index 6601571479285b052385fc6e46c749feeec6dea5..21a09daf9b45687b218babba4c97321e45cf016e 100644 (file)
@@ -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.
 
index 2af392706b684ec5388c1accc3573cc6d3e429df..89921097812f5ae49f9b44495c9d1d61b09b575d 100644 (file)
@@ -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);
index 7acb5bd7212e7115923a5a120b7099cafb2c0e57..1f8c63bce4def2bbb92539d155cfa40b2edd2a65 100644 (file)
@@ -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;
index 91347cdaf9ec129fad79f7e09e9b0b8d378e678d..253584a4d7a61968b5a14ee11d885383da452dc9 100644 (file)
@@ -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.