要求:可以转发和缓存DNS查询的本地DNS服务器
额外1:为它提供一个记录管理界面(HTTP处理程序)
额外2:给它起个名字
关于DNS服务器的一些事情:
*DNS服务器将名称转换为IP
*DNS主要在端口53上使用UDP协议
*DNS消息最大长度为512字节,更长的必须使用EDNS
我们需要的成分:
*UDP
*DNS消息解析器
*转发
*高速缓存
*HTTP处理程序
配方:
*UDP:支持std net package
*DNS消息解析器:根据特定协议处理来自线路的数据包将需要一些工作,为了快速实现,我们将使用golang.org/x/net/dns/dnsmessage
*转发:除了让我们使用Cloudflare公共解析器1.1.1.1
*缓存:内存和持久性,对于持久性写入,我们将使用std gob包对数据进行编码
*HTTP处理程序:应该创建,读取,更新和删除DNS记录。 无需配置文件。
打开监听端口53的UDP套接字,这将接收传入的DNS查询。 请注意,UDP只需要1个套接字来处理多个“连接”,同时TCP是每个连接1个套接字。 所以我们将在整个程序中重用conn。
解析数据包以查看它是否是DNS消息。
如果你好奇DNS消息是怎样的:
向公共解析器转发消息
解析器将回复答案,我们将获取该消息并将其提供给客户端
conn对于并发使用也是安全的,所以那些WriteToUDP应该在goroutine中。
记住答案
我们将使用map,只需按问题键入答案,它使查找变得非常容易,也不要忘记RWMutex,映射对于并发使用是不安全的。 请注意,理论上DNS查询中可能存在多个问题,但大多数DNS服务器只接受1个问题。
持久缓存
我们需要将s.data写入文件并在以后检索它。 要没有自定义解析,我们将使用std gob
注意gob在编码之前需要知道数据类型:
记录管理
这很容易,Create处理程序看起来像这样
领取专属 10元无门槛券
私享最新 技术干货