bind acl 实现

概述

BIND配置中一大堆一大堆的acl,allow-query, allow-recursion, allow-update还有view的match-clients等 acl中的主要存储的就是IP,可以把acl当做是一个IP池,在需要验证的时候就从这个IP池中查找该IP是否存在。那么BIND中如何实现这个非常常用的IP池的呢?

数据结构

acl数据结构

struct dns_acl {
    unsigned int        magic;
    isc_mem_t       *mctx;
    isc_refcount_t      refcount;
    dns_iptable_t       *iptable;
#define node_count      iptable->radix->num_added_node
    dns_aclelement_t    *elements;
    isc_boolean_t       has_negatives;
    unsigned int        alloc;      /*%< Elements allocated */
    unsigned int        length;     /*%< Elements initialized */
    char            *name;      /*%< Temporary use only */
    ISC_LINK(dns_acl_t)     nextincache;    /*%< Ditto */
};

其中的iptable本质上就是一个radix tree(中文名叫基数树)。
Linux基数树(radix tree)是将指针与long整数键值相关联的机制,它存储有效率,并且可快速查询,用于指针与整数值的映射(如:IDR机制)、内存管理等。

主要函数

acl 环境初始化。

/*%<
 * Initialize ACL environment, setting up localhost and localnets ACLs
 */

bind acl 实现_第1张图片

调用acl初始化的函数
bind acl 实现_第2张图片

/*
 * Create a new ACL, including an IP table and an array with room
 * for 'n' ACL elements.  The elements are uninitialized and the
 * length is 0.
 */

dns_acl_create 创建acl,主要是创建一个radix tree
bind acl 实现_第3张图片

bind acl 实现_第4张图片

主要API

/*
 * Determine whether a given address or signer matches a given ACL.
 * For a match with a positive ACL element or iptable radix entry,
 * return with a positive value in match; for a match with a negated ACL
 * element or radix entry, return with a negative value in match.
 */

bind acl 实现_第5张图片

bind acl 实现_第6张图片
bind acl 实现_第7张图片

bind acl 实现_第8张图片
bind acl 实现_第9张图片

typedef struct isc_radix_tree {
   unsigned int     magic;
   isc_mem_t        *mctx;
   isc_radix_node_t     *head;
   isc_uint32_t     maxbits;    /* for IP, 32 bit addresses */
   int num_active_node;         /* for debugging purposes */
   int num_added_node;          /* total number of nodes */
} isc_radix_tree_t;
typedef struct isc_radix_node {
   isc_uint32_t bit;            /* bit length of the prefix */
   isc_prefix_t *prefix;        /* who we are in radix tree */
   struct isc_radix_node *l, *r;    /* left and right children */
   struct isc_radix_node *parent;   /* may be used */
   void *data[2];           /* pointers to IPv4 and IPV6 data */
   int node_num[2];         /* which node this was in the tree,
                       or -1 for glue nodes */
} isc_radix_node_t;
isc_result_t
isc_radix_create(isc_mem_t *mctx, isc_radix_tree_t **target, int maxbits) {
    isc_radix_tree_t *radix;

    REQUIRE(target != NULL);

    radix = isc_mem_get(mctx, sizeof(isc_radix_tree_t));
    if (radix == NULL)
        return (ISC_R_NOMEMORY);

    radix->mctx = mctx;
    radix->maxbits = maxbits;
    radix->head = NULL;
    radix->num_active_node = 0;
    radix->num_added_node = 0;
    RUNTIME_CHECK(maxbits <= RADIX_MAXBITS); /* XXX */
    radix->magic = RADIX_TREE_MAGIC;
    *target = radix;
    return (ISC_R_SUCCESS);

bind acl 实现_第10张图片
这里写图片描述

你可能感兴趣的:(bind学习)