}
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
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.
struct query_info qinfo;
struct edns_data edns;
enum acl_access acl;
+ struct acl_addr* acladdr;
int rc = 0;
if(error != NETEVENT_NOERROR) {
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)
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);
+7 June 2016: Ralph
+ - Lookup localzones by taglist from acl.
+
7 June 2016: Wouter
- Fix #773: Non-standard Python location build failure with pyunbound.
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);
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,
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);
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;
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*
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
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;
*/
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.
* @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.