Unbound启动流程分析

news/2024/11/5 0:07:03/文章来源:https://www.cnblogs.com/yghr/p/18260484

unbound入口在run_daemon方法。

daemon_init方法,分配struct daemon结构体,设置信号处理方法,初始化openssl库,设置时区,设置daemon->need_to_exit为0,初始化模块栈(modstack_init方法)设置deamon->mods结构体(struct module_stack)的num为0、mod为NULL,为daemon->env(struct module_env*)分配内存,把&daemon->mod设置到daemon->env->modstack上,初始化edns选项(edns_known_options_list方法)设置daemon->env的edns_known_options_num值为0、edns_known_options指针分配256个sizeof(struct edns_known_option)大小的内存,初始化daemon->superalloc结构体(struct alloc_cache),为daemon
->acl(struct acl_list *)、daemon->acl_interface(struct acl_list )、daemon->tcl(struct tcl_list )指针分配内存,调用listen_setup_locks方法初始化stream_wait_count_lock、http2_query_buffer_count_lock、http2_response_buffer_count_lock锁,设置启动时间daemon->time_boot、daemon->time_boot_last(struct timeval)为当前时间,为daemon->env->auth_zones(struct auth_zones)分配内存(内部是一颗红黑树,根据class和zone比较:auth_zone_cmp、auth_xfer_cmp),为daemon->env->ends_strings(struct edns_strings)分配内存。

config_create方法,为cfg变量(struct config_file)分配内存,根据方法中cfgfile(char)参数和daemon->chroot变量读取配置文件到cfg中。
apply_setting方法,把cfg设置到daemon->cfg上,设置日志可见性verbosity全局变量,根据配置文件设置一些全局变量,设置文件数量和内存大小限制(rlimit),设置日志ident(默认是unbound),分别创建以下缓存:

  • daemon->env->msg_cache (struct slabhash *)第一层哈希表大小为cfg->msg_cache_slabs、二层哈希表大小为1024,最大内存为cfg->msg_cache_size,比较方法为query_info_compare(比较type、class、域名),key:struct msgreply_entry,data:struct reply_info
  • daemon->env->rrset_cache(struct rrset_cache*)内部也是struct slabhash结构,第一层哈希表大小为cfg->rrset_cache_slabs(默认是4)、二层哈希表大小为1024,最大内存为cfg->rrset_cache_size(默认为4M),比较方法为ub_rrset_compare(比较type、class、域名),key:struct ub_packed_rrset_key,data:struct packed_rrset_data
  • daemon->env->infra_cache(struct infra_cache*):内部有3个slabhash,分别是cfg->env->infra_cache->hosts、cfg->env->infra_cache->domain_rates、cfg->env->infra_cache->client_ip_rates,1颗红黑树cfg->env->infra_cache->domain_limits、2颗地址树cfg->env->infra_cache->wait_limits_netblock、cfg->env->infra_cache->wait_limits_cookie_netblock。
  1. hosts:struct slabhash结构,第一层哈希表大小为cfg->infra_cache_slabs、二层哈希表大小为32,最大内存为cfg->infra_cache_numhosts * (sizeof(struct infra_key)+sizeof(struct infra_data)+ 14),比较方法为infra_compfunc(比较sock地址、zone),key:struct infra_key,data:struct infra_data
  2. domain_rates:struct slabhash结构,第一层哈希表大小为cfg->ratelimit_slabs、二层哈希表大小为32,最大内存为cfg->ratelimit_size,比较方法为rate_compfunc(比较域名),key:struct rate_key,data:struct rate_data
  3. client_ip_rates:struct slabhash结构,第一层哈希表大小为cfg->ip_ratelimit_slabs、二层哈希表大小为32,最大内存为cfg->ip_ratelimit_size,比较方法为ip_rate_compfunc(比较ip地址),key:struct ip_rate_key,data:struct ip_rate_data(也是struct rate_data)。
  4. domain_limits:struct rbtree_type结构,节点为struct domain_limit_data,比较方法为name_tree_compare(比较class、域名),存储从配置文件中读取的cfg->ratelimit_for_domain、cfg->ratelimit_below_domain的域名限制。

slabhash是一个二级哈希表,第二级哈希表是lru哈希表。

config_lookup_uid方法,获取uid和gid。
daemon_open_shared_ports方法,根据cfg->ifs获取网卡地址或者ip地址和端口,如果开启reuseport选项且线程数量大于1就开启reuseport,把创建好的监听套接字设置到daemon->ports上,如果cfg->remote_control_enable为1,创用于远程控制的套接字daemon->rc_ports。
perform_setup方法,设置远程控制的ssl相关的东西,设置syslog,创建pid文件干掉旧进程,设置了daemon模式则fork子进程挂到后台,切换当前工作目录、uid、gid,设置日志文件。
daemon_fork方法

  • 通过views_create方法,创建daemon->views(struct views *)红黑树,节点为struct view *,比较方法为view_cmp(比较域名)。
  • 通过views_apply_cfg方法,把daemon->cfg->views中的配置添加到daemon->views方法。
  • 通过acl_list_apply_cfg方法,创建daemon->acl(struct acl_list *)红黑树,节点为struct addr_tree_node,比较方法为addr_tree_cmp(比较网段),并读取配置中的acl配置加载到daemon->acl中,并添加127.0.0.0/8 allow::1 allow::ffff:127.0.0.1 allow规则。
  • 通过acl_interface_apply_cfg方法,创建daemon->acl_interface(struct acl_list *)红黑树,节点为struct acl_addr

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/826881.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何给 GoPro 拍摄的视频添加时间水印 All In One

如何给 GoPro 拍摄的视频添加时间水印 All In One 执法记录仪 时间水印是指在拍摄的照片或视频上添加一个显示时间的标识。 这个标识通常以数字的形式出现在画面的一个角落,它显示了拍摄的具体日期和时间。 时间水印的目的是为了记录下拍摄的时间,以便用户可以更好地回顾和分…

《使用Gin框架构建分布式应用》读后感

1.为什么选择这本书? 因为工作中有一个项目使用了Go进行开发,项目用到了MySQL, Redis,GORM,Rabbitmq,Zap等组件进行开发,没有使用到Web框架,因为本人是Web开发方向,所以就想了解下Web框架在Go开发中的应用,看看别人是怎么用的。国外的Go Web框架有:Echo, Gin, Iris, …

计算机组成原理基础知识(一)

来源:早期的冯诺依曼计算机以运算器为中心,现代计算机以存储器为中心; 现代计算器的结构:计算机硬件的基本组成:计算机系统的层次结构:计算机的性能指标:小练习:进制转换:

《图解设计模式》 第四部分 分开考虑

第九章 Bridge模式//使用代码 public class Main(){public static void main(String[] args){Display d1 = new Display(new StringDisPlayImpl("Hello, China."));Display d2 = new CountDisplay(new StringDisPlayImpl("Hello, World."));CountDisplay d…

Redis底层数据结构 SDS

SDS 字符串在 Redis 中是很常用的,键值对中的键是字符串类型,值有时也是字符串类型。 Redis 是用 C 语言实现的,但是它没有直接使用 C 语言的 char* 字符数组来实现字符串,而是自己封装了一个名为简单动态字符串(simple dynamic string,SDS) 的数据结构来表示字符串, 也…

PackageTracer实验中第一次Ping必然会丢包的原因

在packageTracer中做实验时发现首次ping位于不同网络中的主机时必然会超时,我对此疑惑不解,但是上网没有找到相关解答,于是我通过包跟踪找到了答案,于是将其记录下来,希望对后拉的读者有所帮助。PS:R0与R1的位置有误 PC1 Ping PC3 的过程首先,当我们在PC1发出Ping命令时…

easy-mock搭建mock平台

环境: mac 1、前提: 需要已安装node和npm(easy-mock是node.js开发的)、redis、mongodb 安装mongodb(mongodb很大,剩余内存需要10个G左右)$ brew install mongodb-atlas $ atlas setup2、安装easy-mockgit clone https://github.com/easy-mock/easy-mock.git #选择要把eas…

easy-mock搭建mock服务

环境: mac 1、前提: 需要已安装node和npm(easy-mock是node.js开发的)、redis、mongodb 安装mongodb(mongodb很大,剩余内存需要10个G左右)$ brew install mongodb-atlas $ atlas setup2、安装easy-mockgit clone https://github.com/easy-mock/easy-mock.git #选择要把eas…

[编程笔记] 奇怪的bug - 公共提示组件不生效

很简单的一个功能,初看的时候就猜到是用的某个组件,其他地方要用一般照抄,改下文案即可,这种弹出肯定是公共组件了。然鹅,很神奇的是我新做的页面,复制以后没效果!项目中有这么一个提示框:对应的代码是:top.msg.ok(123)很简单的一个功能,初看的时候就猜到是用的某个组…

linux内存管理学习总结

一、内存寻址 1.1 逻辑地址、线性地址、物理地址的概念 1.2 逻辑地址转换线性地址步骤 1.3 线性地址到物理地址的转换 二、内存管理 2.1 引导内存分配器阶段 2.2 内存管理子系统 2.3 32位架构的地址空间划分 2.4 64位架构的地址空间划分 2.5 内核态的内存管理 2.6 用户态内存管…