使用Go语言写一个DNS服务

要求:可以转发和缓存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处理程序看起来像这样

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181208A17XAO00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券