BIND9源碼分析之acl 的實現


  BIND配置中一大堆一大堆的acl,什么allow-query, allow-recursion, allow-update還有view的match-clients等等等等。

  acl中的主要存儲的就是IP,可以把acl當做是一個IP池,在需要驗證的時候就從這個IP池中查找該IP是否存在。那么BIND中如何實現這個非常常用的IP池的呢?

      BIND中的acl用數據結構dns_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(中文名叫基數樹)。

 

     radix tree簡直就是為IP路由存儲和查找而生的(實際上IP路由查找正是radix tree最常用的領域之一)。在存儲IP數據,尤其是CIDR的時候,radix退化成一種二叉樹,左右子樹分別表示IP的二進制表示的1或者0,所以對於IPv4,radix 樹的最大高度是32。對於CIDR的存儲,只需要存儲前綴位就可以了,比如存儲130.50.30.40/18,只需要存儲前18位即可,后面的14位不用存儲,因為在查找ACL的時候,只要對比到第18位就可以確定是否讓此IP通過驗證。

  BIND9中radix tree的實現比較復雜,可能是處於需要兼容IPv4和IPv6,以及IP地址的先后關系的考慮。

  nginx中的geo模塊也用radix tree存儲CIDR形式的IP,core/ngx_radix_tree.c的實現還是相當短小精悍的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM