简介DNS的全称domain name system , 既然是一个系统就有客户端和服务器之分 。一般情况来说我们并不需要感知这个DNS客户端的存在 , 因为我们在浏览器访问某个域名的时候 , 浏览器作为客户端已经实现了这个工作 。
但是有时候我们没有使用浏览器 , 比如?.NETty环境中 , 如何构建一个DNS请求呢?
DNS传输协议简介在RFC的规范中 , DNS传输协议有很多种,如下所示:
- DNS-over-UDP/53简称”Do53″,是使用UDP进行DNS查询传输的协议 。
- DNS-over-TCP/53简称”Do53/TCP”,是使用TCP进行DNS查询传输的协议 。
- DNSCrypt,对DNS传输协议进行加密的方法 。
- DNS-over-TLS简称”DoT”,使用TLS进行DNS协议传输 。
- DNS-over-HTTPS简称”DoH”,使用HTTPS进行DNS协议传输 。
- DNS-over-TOR,使用VPN或者tunnels连接DNS 。
DNS的IP地址先来考虑一下如何在netty中使用Do53/TCP协议 , 进行DNS查询 。
因为DNS是客户端和服务器的模式 , 我们需要做的是构建一个DNS客户端 , 向已知的DNS服务器端进行查询 。
已知的DNS服务器地址有哪些呢?
除了13个root DNS IP地址以外 , 还出现了很多免费的公共DNS服务器地址,比如我们常用的阿里DNS,同时提供了IPv4/IPv6 DNS和DoT/DoH服务 。
IPv4: 223.5.5.5223.6.6.6IPv6: 2400:3200::12400:3200:baba::1DoH 地址: https://dns.alidns.com/dns-queryDoT 地址: dns.alidns.com
再比如百度DNS , 提供了一组IPv4和IPv6的地址:IPv4: 180.76.76.76IPv6: 2400:da00::6666
还有114DNS:114.114.114.114114.114.115.115
当然还有很多其他的公共免费DNS , 这里我选择使用阿里的IPv4:223.5.5.5为例 。有了IP地址 , 我们还需要指定netty的连接端口号 , 这里默认的是53 。
然后就是我们要查询的域名了 , 这里以www.flydean.com为例 。
你也可以使用你系统中配置的DNS解析地址 , 以mac为例 , 可以通过nslookup进行查看本地的DNS地址:
nslookupwww.flydean.comServer:8.8.8.8Address:8.8.8.8#53Non-authoritative answer:www.flydean.com canonical name = flydean.com.Name:flydean.comAddress: 47.107.98.187
Do53/TCP在netty中的使用有了DNS Server的IP地址 , 接下来我们需要做的就是搭建netty client , 然后向DNS server端发送DNS查询消息 。搭建DNS netty client因为我们进行的是TCP连接 , 所以可以借助于netty中的NIO操作来实现 , 也就是说我们需要使用NioEventLoopGroup和NIOSocketChannel来搭建netty客户端:
【手把手教你在netty中使用TCP协议请求DNS服务器】
final String dnsServer = "223.5.5.5";final int dnsPort = 53;EventLoopGroup group = new NioEventLoopGroup();Bootstrap b = new Bootstrap();b.group(group).channel(NioSocketChannel.class).handler(new Do53ChannelInitializer());final Channel ch = b.connect(dnsServer, dnsPort).sync().channel();
netty中的NIO Socket底层使用的就是TCP协议 , 所以我们只需要像常用的netty客户端服务一样构建客户端即可 。然后调用Bootstrap的connect方法连接到DNS服务器 , 就建立好了channel连接 。
这里我们在handler中传入了自定义的Do53ChannelInitializer , 我们知道handler的作用是对消息进行编码、解码和对消息进行读取 。因为目前我们并不知道客户端查询的消息格式 , 所以Do53ChannelInitializer的实现我们在后面再进行详细讲解 。
发送DNS查询消息netty提供了DNS消息的封装 , 所有的DNS消息 , 包括查询和响应都是DnsMessage的子类 。
每个DnsMessage都有一个唯一标记的ID , 还有代表这个message类型的DnsOpCode 。
对于DNS来说 , opCode有下面这几种:
public static final DnsOpCode QUERY = new DnsOpCode(0, "QUERY");public static final DnsOpCode IQUERY = new DnsOpCode(1, "IQUERY");public static final DnsOpCode STATUS = new DnsOpCode(2, "STATUS");public static final DnsOpCode NOTIFY = new DnsOpCode(4, "NOTIFY");public static final DnsOpCode UPDATE = new DnsOpCode(5, "UPDATE");
因为每个DnsMessage都可能包含4个sections,每个section都以DnsSection来表示 。因为有4个section , 所以在DnsSection定义了4个section类型:
推荐阅读
- 阿里3个小时手把手教你用zookeeper实现分布式锁
- 2021年取消非师范考教资-2021年非师范不能考教师编制-2021年非师范考教资后成绩保留多久
- 设置路由器wifi上网方法教程 192.168.0.1 登陆页面
- 教练:驾考新规定要不断停车 女子科目三考试把安全员开吐了
- 狗十三反映的家庭教育,狗十三讲什么-
- 虹鳟鱼做法教程 清蒸虹鳟鱼的做法
- 招聘|“47人面试,竟有35人缺考”,县城教师招聘,出现多人中途放弃!
- 第一学历是什么意思?
- 营养师教你几个小诀窍管住你的贪吃嘴
- 丰胸秘籍三部曲教你减肥不减胸