- Lookup localzones by taglist from acl.

git-svn-id: file:///svn/unbound/trunk@3764 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Ralph Dolmans 2016-06-07 08:36:19 +00:00
parent 7ea03d9ee2
commit ff091efe7b
7 changed files with 82 additions and 35 deletions

View 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

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

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

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

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

View 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;
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 subdomain of zone */
if(result->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;

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