mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
- Lookup localzones by taglist from acl.
git-svn-id: file:///svn/unbound/trunk@3764 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
7ea03d9ee2
commit
ff091efe7b
7 changed files with 82 additions and 35 deletions
|
|
@ -392,13 +392,18 @@ acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
enum acl_access
|
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)
|
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);
|
addr, addrlen);
|
||||||
if(r) return r->control;
|
|
||||||
return acl_deny;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
|
|
|
||||||
|
|
@ -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);
|
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 acl: structure for address storage.
|
||||||
* @param addr: address to check
|
* @param addr: address to check
|
||||||
* @param addrlen: length of addr.
|
* @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 acl_addr*
|
||||||
struct sockaddr_storage* addr, socklen_t addrlen);
|
acl_addr_lookup(struct acl_list* acl, struct sockaddr_storage* addr,
|
||||||
|
socklen_t addrlen);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get memory used by acl structure.
|
* Get memory used by acl structure.
|
||||||
|
|
|
||||||
|
|
@ -804,6 +804,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||||
struct query_info qinfo;
|
struct query_info qinfo;
|
||||||
struct edns_data edns;
|
struct edns_data edns;
|
||||||
enum acl_access acl;
|
enum acl_access acl;
|
||||||
|
struct acl_addr* acladdr;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
if(error != NETEVENT_NOERROR) {
|
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,
|
dt_msg_send_client_query(&worker->dtenv, &repinfo->addr, c->type,
|
||||||
c->buffer);
|
c->buffer);
|
||||||
#endif
|
#endif
|
||||||
acl = acl_list_lookup(worker->daemon->acl, &repinfo->addr,
|
acladdr = acl_addr_lookup(worker->daemon->acl, &repinfo->addr,
|
||||||
repinfo->addrlen);
|
repinfo->addrlen);
|
||||||
|
acl = acl_get_control(acladdr);
|
||||||
if((ret=deny_refuse_all(c, acl, worker, repinfo)) != -1)
|
if((ret=deny_refuse_all(c, acl, worker, repinfo)) != -1)
|
||||||
{
|
{
|
||||||
if(ret == 1)
|
if(ret == 1)
|
||||||
|
|
@ -941,7 +943,8 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||||
goto send_reply;
|
goto send_reply;
|
||||||
}
|
}
|
||||||
if(local_zones_answer(worker->daemon->local_zones, &qinfo, &edns,
|
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);
|
regional_free_all(worker->scratchpad);
|
||||||
if(sldns_buffer_limit(c->buffer) == 0) {
|
if(sldns_buffer_limit(c->buffer) == 0) {
|
||||||
comm_point_drop_reply(repinfo);
|
comm_point_drop_reply(repinfo);
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
7 June 2016: Ralph
|
||||||
|
- Lookup localzones by taglist from acl.
|
||||||
|
|
||||||
7 June 2016: Wouter
|
7 June 2016: Wouter
|
||||||
- Fix #773: Non-standard Python location build failure with pyunbound.
|
- Fix #773: Non-standard Python location build failure with pyunbound.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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, 0, qid);
|
||||||
sldns_buffer_write_u16_at(w->back->udp_buff, 2, qflags);
|
sldns_buffer_write_u16_at(w->back->udp_buff, 2, qflags);
|
||||||
if(local_zones_answer(ctx->local_zones, &qinfo, &edns,
|
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);
|
regional_free_all(w->env->scratch);
|
||||||
libworker_fillup_fg(q, LDNS_RCODE_NOERROR,
|
libworker_fillup_fg(q, LDNS_RCODE_NOERROR,
|
||||||
w->back->udp_buff, sec_status_insecure, NULL);
|
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, 0, qid);
|
||||||
sldns_buffer_write_u16_at(w->back->udp_buff, 2, qflags);
|
sldns_buffer_write_u16_at(w->back->udp_buff, 2, qflags);
|
||||||
if(local_zones_answer(ctx->local_zones, &qinfo, &edns,
|
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);
|
regional_free_all(w->env->scratch);
|
||||||
free(qinfo.qname);
|
free(qinfo.qname);
|
||||||
libworker_event_done_cb(q, LDNS_RCODE_NOERROR,
|
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, 0, qid);
|
||||||
sldns_buffer_write_u16_at(w->back->udp_buff, 2, qflags);
|
sldns_buffer_write_u16_at(w->back->udp_buff, 2, qflags);
|
||||||
if(local_zones_answer(w->ctx->local_zones, &qinfo, &edns,
|
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);
|
regional_free_all(w->env->scratch);
|
||||||
q->msg_security = sec_status_insecure;
|
q->msg_security = sec_status_insecure;
|
||||||
add_bg_result(w, q, w->back->udp_buff, UB_NOERROR, NULL);
|
add_bg_result(w, q, w->back->udp_buff, UB_NOERROR, NULL);
|
||||||
|
|
|
||||||
|
|
@ -1013,6 +1013,15 @@ local_zones_apply_cfg(struct local_zones* zones, struct config_file* cfg)
|
||||||
struct local_zone*
|
struct local_zone*
|
||||||
local_zones_lookup(struct local_zones* zones,
|
local_zones_lookup(struct local_zones* zones,
|
||||||
uint8_t* name, size_t len, int labs, uint16_t dclass)
|
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;
|
rbnode_t* res = NULL;
|
||||||
struct local_zone *result;
|
struct local_zone *result;
|
||||||
|
|
@ -1022,25 +1031,26 @@ local_zones_lookup(struct local_zones* zones,
|
||||||
key.name = name;
|
key.name = name;
|
||||||
key.namelen = len;
|
key.namelen = len;
|
||||||
key.namelabs = labs;
|
key.namelabs = labs;
|
||||||
if(rbtree_find_less_equal(&zones->ztree, &key, &res)) {
|
rbtree_find_less_equal(&zones->ztree, &key, &res);
|
||||||
/* exact */
|
result = (struct local_zone*)res;
|
||||||
return (struct local_zone*)res;
|
/* exact or smaller element (or no element) */
|
||||||
} else {
|
int m;
|
||||||
/* smaller element (or no element) */
|
if(!result || result->dclass != dclass)
|
||||||
int m;
|
return NULL;
|
||||||
result = (struct local_zone*)res;
|
/* count number of labels matched */
|
||||||
if(!result || result->dclass != dclass)
|
(void)dname_lab_cmp(result->name, result->namelabs, key.name,
|
||||||
return NULL;
|
key.namelabs, &m);
|
||||||
/* count number of labels matched */
|
while(result) { /* go up until qname is zone or subdomain of zone */
|
||||||
(void)dname_lab_cmp(result->name, result->namelabs, key.name,
|
if(result->namelabs <= m) {
|
||||||
key.namelabs, &m);
|
if(!result->taglist)
|
||||||
while(result) { /* go up until qname is subdomain of zone */
|
break;
|
||||||
if(result->namelabs <= m)
|
if(taglist_intersect(result->taglist,
|
||||||
break;
|
result->taglen, taglist, taglen))
|
||||||
result = result->parent;
|
break;
|
||||||
}
|
}
|
||||||
return result;
|
result = result->parent;
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct local_zone*
|
struct local_zone*
|
||||||
|
|
@ -1278,7 +1288,7 @@ lz_inform_print(struct local_zone* z, struct query_info* qinfo,
|
||||||
int
|
int
|
||||||
local_zones_answer(struct local_zones* zones, struct query_info* qinfo,
|
local_zones_answer(struct local_zones* zones, struct query_info* qinfo,
|
||||||
struct edns_data* edns, sldns_buffer* buf, struct regional* temp,
|
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,
|
/* see if query is covered by a zone,
|
||||||
* if so: - try to match (exact) local data
|
* 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;
|
struct local_zone* z;
|
||||||
int r;
|
int r;
|
||||||
lock_rw_rdlock(&zones->lock);
|
lock_rw_rdlock(&zones->lock);
|
||||||
z = local_zones_lookup(zones, qinfo->qname,
|
z = local_zones_tags_lookup(zones, qinfo->qname,
|
||||||
qinfo->qname_len, labs, qinfo->qclass);
|
qinfo->qname_len, labs, qinfo->qclass, taglist, taglen);
|
||||||
if(!z) {
|
if(!z) {
|
||||||
lock_rw_unlock(&zones->lock);
|
lock_rw_unlock(&zones->lock);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -215,6 +215,22 @@ int local_data_cmp(const void* d1, const void* d2);
|
||||||
*/
|
*/
|
||||||
void local_zone_delete(struct local_zone* z);
|
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.
|
* Lookup zone that contains the given name, class.
|
||||||
* User must lock the tree or result zone.
|
* 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 buf: buffer with query ID and flags, also for reply.
|
||||||
* @param temp: temporary storage region.
|
* @param temp: temporary storage region.
|
||||||
* @param repinfo: source address for checks. may be NULL.
|
* @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
|
* @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
|
* by authority data. If the reply should be dropped altogether, the return
|
||||||
* value is true, but the buffer is cleared (empty).
|
* value is true, but the buffer is cleared (empty).
|
||||||
*/
|
*/
|
||||||
int local_zones_answer(struct local_zones* zones, struct query_info* qinfo,
|
int local_zones_answer(struct local_zones* zones, struct query_info* qinfo,
|
||||||
struct edns_data* edns, struct sldns_buffer* buf, struct regional* temp,
|
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.
|
* Parse the string into localzone type.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue