forked from DNSPod/dnspod-sr
-
Notifications
You must be signed in to change notification settings - Fork 0
/
README
31 lines (20 loc) · 4.29 KB
/
README
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
--整体设计:本程序设计为单个进程里运行多个worker线程的模型.其中1个sentinel线程,负责监听端口并读取请求数据.
n个可配置的fetcher线程,负责在内存中查询请求的记录.如果查找失败,则把请求转发给后面的n个可配置的quizzer线程.
quizzer线程负责向权威DNS服务器请求,更新内存中的数据,并把结果返回给客户端.另外还有一个time_cron线程负责时间更新和信号处理.支持A,AAAA,NS,CNAME,MX,SOA,TXT,SRV记录.
--信号处理模块:多个线程中除了time_cron,其他线程均屏幕所有信号.其他线程遇到普通非致命信号(例如管道破裂,SIG_PIPE,通常是对方关闭socket.)时忽略,遇到致命错误(例如内存访问错误,SIG_SEGV,访问错误内存)会退出,此时整个进程退出.本程序需要监视脚本,此时启动服务器程序即可.
--本地zone文件处理模块:仅支持读取简单的root.z文件.自定义的域名解析也可以以相同格式放入这个文件.这个文件中的记录不会过期,也不进行TTL更新
--sentinel线程:程序启动时会启动一个sentinel线程,它使用epoll监听tcp和udp的53端口.接收到数据包之后,只做简单的大小判断,太大和太小的数据包将被丢弃.之后将客户端信息(tcp的socket fd或者udp的struct sockaddr_in)和包数据放入后面fetcher线程的缓冲区里.当程序性能达到瓶颈,所有fetcher缓冲区都已经满的情况下,请求包会在这里被丢弃.后续开发将会把这个模块分开成为DNS前端程序,只接收数据包并把数据包转发给后端的解析查询程序.
--fetcher线程:fetcher线程负责从内存数据库中查询记录.如果找到,则组返回DNS记录,并关闭socket(如果需要).为了降低资源消耗同时防止攻击,如果客户端使用tcp请求数据,而此时数据并不在内存中,fetcher会将请求转给后面的quizzer,并关闭socket,等待客户端重新连接.在此期间,后端的quizzer会将查询得到的结果存入内存数据库,第二次请求fetcher返回数据.如果客户端使用udp请求,则将客户端信息和查询信息一起转发后端的quizzer线程.
--quizzer线程:quizzer线程负责向授权服务器查询记录,将查询结果写入内存数据库.并返回合适的记录给客户端(如果没有客户端信息,则是一次更新请求,只写入内存数据库即可).多个fetcher和多个quizzer共享同一个查询队列,避免多个quizzer查询相同的记录.
--网络模块:使用epoll管理udp和tcp连接.udp只需要一个socket.每个tcp连接需要重新分配一个socket.该socket被后面的fetcher关闭.后端每个quizzer使用一个epoll,管理向授权查询的udp和tcp.
--存储模块:存储模块分为4种,第一种是记录存储,使用一个大的hash存储.同时跟每个记录相关联的是TTL的存储,使用红黑树存放,可以通过域名在hash中查找到对应的记录值,也可以在红黑树中查询最小值,并找到相关的hash进行记录更新.初始加载的zone文件中的记录只在hash中存储,不写入红黑树,所以不进行TTL更新.第三种是查询列表,同样使用hash存储,同时查询相同的记录值.第四种是tcp连接通知关闭链.由fetcher写入已经返回记录的使用tcp的客户端,sentinel线程关闭tcp socket,并将链接在epoll中删除.
--查询策略:从域名根部开始依序查询,第一次不查询所有NS的IP地址.每次查询如果遇到没有IP的NS,查询其中一个的IP.从顶级域查询时开始计数,最大MAX_TRYS次后如果还没有结果将会认为失败.
优化策略:
1. 主动刷新:quizzer线程会主动检测TTL红黑树中的最小值,如果有TTL将要超时的记录,加入查询过程.
2. 内存DNS数据片.某个记录第一次查询时quizzer返回授权服务器返回的数据.第二次查询时由fetcher进行组包.并把该记录的内存存储修改为DNS数据包的形式.第三次查询时fetcher只需要修改其中的TTL和DNS查询ID即可返回给客户端.
3. 查询失败时可以配置外部递归服务器的IP(例如8.8.8.8),程序会尝试向它们查询并返回结果.
功能安排:
1. 优化quizzer查询过程
2. 修改信号处理过程
3. 分开前端DNS,增加分布式布署支持
4. 更方便的配置文件更新