Dnsdist 整体框架:
刚开始就是加载配置文件,且如果要以控制台 -c的身份登陆的话就直接登陆到了控制台去和dnsdist交互了,那部分代码跳过了,因为也不是最核心的,我下面的分析是从main中开始创建下游的时候开始的
1.会创建一个默认的池子
2.然后依据配置开始创建后端,先创建DownstreamState实例,DownstreamState实例主要包含一个多fd复用器,刚开始创建的时候默认是1个,然后调用connect连接后端,接着设置每个后端处理的最大的udp的个数是10240;将创建好的后端添加到池子中;针对每一个后端DownstreamState开启一个线程,创建的线程跑的函数是responderThread
该函数它首先会选择出准备好的socket,然后调用recv进行数据包的接收,找到对应queryid对应的state,插入到cache中,并且发送udp响应
3.下面是接收udp查询的线程,调用udpClientThread函数,对于g_udpVectorSize=1的进入for死循环,调用recvmsg接收消息,调用processUDPQuery,该函数过滤掉不合适的包,然后依据策略找到合适的下游server,如果支持cache的话,如果命中则直接构造响应返回,如果没有命中则先为后端封装udp查询状态ids,然后调用udpClientSendRequestToBackend从后端选择一个fd,调用udpClientSendRequestToBackend进行数据包的发送,该函数内部直接调用sendto
4如果g_udpVectorSize不是1的话,调用MultipleMessagesUDPClientThread(cs, holders),该函数的作用是重复的从同一个fd接收数据,调用g_udpVectorSize次recvmmsg,然后再发送给后端,这样做的目的是尽可能的从同一个fd接收更多的数据。所以说这种就是针对udp查询特别多的,用于提高udp server的性能
注意提升udp server的性能有俩种方式,一种调用recvmmsg一次性的接收多个数据包是一个批量接口,还有一个是reuseport
5还会调用maintThread定期清理PacketCache