mdns
mdns_百度百科 https://baike.baidu.com/item/mdns
在计算机网络中 , 多播DNS ( mDNS )协议将主机名解析为不包含本地名称服务器的小型网络中的IP地址。 它是一种零配置服务,使用与单播域名系统 (DNS)基本相同的编程接口,数据包格式和操作语义。 虽然Stuart Cheshire将mDNS设计为独立协议,但它可以与标准DNS服务器协同工作。
mDNS协议发布为 RFC 6762使用IP多播用户数据报协议 (UDP)数据包,由Apple Bonjour和开源Avahi软件包实现。 Android包含mDNS实现。 mDNS也已在Windows 10中实现,最初仅限于发现网络打印机[3] ,后来也能够解析主机名。
mDNS可以与DNS服务发现 (DNS-SD)结合使用, DNS服务发现是RFC 6763中单独指定的配套零配置技术。
mdns 即多播dns(Multicast DNS),mDNS主要实现了在没有传统DNS服务器的情况下使局域网内的主机实现相互发现和通信,使用的端口为5353,遵从dns协议,使用现有的DNS信息结构、名语法和资源记录类型。并且没有指定新的操作代码或响应代码。在局域网中,设备和设备之前相互通信需要知道对方的ip地址的,大多数情况,设备的ip不是静态ip地址,而是通过dhcp协议动态分配的ip 地址,如何设备发现呢,就是要mdns大显身手,例如:现在物联网设备和app之间的通信,要么app通过广播,要么通过组播,发一些特定信息,感兴趣设备应答,实现局域网设备的发现,当然mdns 比这强大。
当mDNS客户端需要解析主机名时,它会发送一个IP多播查询消息,要求具有该名称的主机标识自己。然后该目标机器多播包含其IP地址的消息。然后,该子网中的所有计算机都可以使用该信息来更新其mDNS高速缓存。任何主机都可以通过发送生存时间(TTL)等于零的响应数据包来放弃其对名称的声明。
默认情况下,mDNS仅限并且专门解析以.local顶级域(TLD)结尾的主机名。如果该域包括未实现mDNS但可以通过传统单播DNS服务器找到的主机,则会导致问题。解决此类冲突需要违反零配置目标的网络配置更改 [1] 。
首先,在 IP 协议里规定了一些保留地址,其中有一个是 224.0.0.251,对应的 IPv6 地址是 [FF02::FB]。
mDNS 协议规定了端口为 5353,而 DNS 的端口是 53。
mDNS 基于 UDP 协议。DNS 一般也是基于 UDP 协议的,但是也可以使用 TCP 协议。
如果理解了 DNS 协议,再去理解 mDNS 协议就很简单了,区别只是 mDNS 一般作用在一个局域网内的,有特定的 IP 地址,也就是 224.0.0.251,有特定的端口 5353,mDNS 的作用是实现局域网内的服务发现,查询,注册,DNS 作用是实现域名的解析,作用大概是一样的。
每个进入局域网的主机,如果开启了 mDNS 服务的话,都会向局域网内的所有主机组播一个消息,我是谁,和我的IP地址是多少。然后其他也有该服务的主机就会响应,也会告诉你,它是谁,它的 IP 地址是多少。当然,具体实现要比这个复杂点。
比如,A 主机进入局域网,开启了 mDNS 服务,并向 mDNS 服务注册以下信息:我提供 FTP 服务,我的 IP 是 192.168.1.101,端口是 21。当 B 主机进入局域网,并向 B 主机的 mDNS 服务请求,我要找局域网内 FTP 服务器,B主机的 mDNS 就会去局域网内向其他的 mDNS 询问,并且最终告诉你,有一个IP地址为 192.168.1.101,端口号是 21 的主机,也就是 A 主机提供 FTP 服务,所以 B 主机就知道了 A 主机的 IP 地址和端口号了。
大概的原理就是这样子,mDNS 提供的服务要远远多于这个,当然服务多但并不复杂。
在 Apple 的设备上(电脑,笔记本,iphone,ipad等设备)都提供了这个服务。很多 Linux 设备也提供这个服务。Windows 的设备可能没有提供,但是如果安装了 iTunes 之类的软件的话,也提供了这个服务。
这样就可以利用这个服务开发一些局域网内的自动发现,然后提供一些局域网内交互的应用了。
jmDNS 是一个 JAVA 平台的,提供 mDNS 服务的第三方库。在这个 jar 包引入到 Android 项目里,就可以获得 mDNS 服务了。Android 在 3.x 还是 4.x 之后已经提供局域网内自动发现的 API 了,所以不需要使用 jmDNS 第三方库就能实现了。
mDNS(多播 DNSMulticast DNS)允许系统在局域网中广播查询其他资源的名称。Fedora 用户经常在没有复杂名称服务的路由器上接有多个 Linux 系统。在这种情况下,mDNS 允许你按名称与多个系统通信 —— 多数情况下不用路由器。你也不必在所有本地系统上同步类似/etc/hosts之类的文件。本文介绍如何设置它。
mDNS 是一个零配置网络服务,它已经诞生了很长一段时间。Fedora Workstation 带有零配置系统 Avahi(它包含 mDNS)。(mDNS 也是 Bonjour 的一部分,可在 Mac OS 上找到。)
mDNS消息是发送到以下位置的多播UDP数据包:
-
UDP端口5353。
有效载荷结构基于单播DNS数据包格式,由两部分组成 - 标头和数据。
标题与单播DNS中的标题相同,数据部分中的子节也是如此:查询,答案,权威名称服务器和其他记录。
每个子节中的记录数与标题中相应的* COUNT字段的值相匹配。
查询
查询部分中记录的有线格式与单播DNS中的记录略有不同,添加了一个单比特字段。
领域 | 描述 | 长度位 |
---|---|---|
QNAME | 查询所属的节点的名称 | 变量 |
QTYPE | 查询的类型,即应在响应中返回的RR类型。 | 16 |
单播响应 | 布尔标志,指示是否需要单播响应 | 1 |
QCLASS | 类代码,1代表互联网和IP网络的“IN” | 15 |
与在单播DNS中一样,QNAME字段由一系列称为“标签”的长度/值子字段组成。每个标签代表完全限定域名(FQDN)中的一个以点分隔的子字符串。该列表由单个空字节终止,表示DNS的“根”。
UNICAST-RESPONSE字段用于最小化网络上不必要的广播:如果设置了比特,响应者应该直接向查询节点发送定向单播响应,而不是将响应广播到整个网络。
QCLASS字段与单播DNS中的字段相同。
资源记录
答案中的所有记录,权威名称服务器和其他记录部分具有相同的格式,统称为“资源记录”(RR)。
mDNS中的资源记录也具有来自单播DNS的略微修改的通用格式:
领域 | 描述 | 长度位 |
---|---|---|
RRNAME | 记录所属节点的名称 | 变量 |
RRTYPE | 资源记录的类型 | 16 |
缓存FLUSH | 布尔标志,指示是否应清除过时的缓存记录 | 1 |
RRCLASS | 类代码,1代表互联网和IP网络的“IN” | 15 |
TTL | 应缓存RR的时间间隔(以秒为单位) | 32 |
RDLENGTH | 表示RDATA字段长度(以八位字节为单位)的整数 | 16 |
RDATA | 资源数据;内部结构因RRTYPE而异 | 变量 |
CACHE-FLUSH位用于指示邻居节点,该记录应覆盖此RRNAME和RRTYPE的任何现有缓存条目,而不是附加到其上。
RDATA字段的格式与单播DNS中的格式相同。但是,DNS服务发现(DNS-SD)是mDNS最常见的用例,它指定了对其某些格式(特别是TXT记录)的轻微修改。
尝试pingappletv.local主机会导致mDNS客户端计算机多播以下UDP数据包:
00 00交易ID 00 00旗帜 00 01问题数量 00 00答案数量 00 00权限资源记录数 00 00其他资源记录数 07 61 70 70 6c 65 74 76“appletv” 05 6c 6f 63 61 6c“local” 00终结者 00 01类型(A记录) 00 01班。
appletv.local主机将通过多播其mDNS响应数据包进行响应。例如:
00 00 84 00 00 00 00 01 00 00 00 02 07 61 70 70 6c 65 74 76 05 6c 6f 63 61 6c 00 00 01 80 01 00 00 78 00 00 04 99 6d 07 5a c0 0c 00 1c 80 01 00 00 78 00 00 10 fe 80 00 00 00 00 00 00 02 23 32 ff fe b1 21 52 c0 0c 00 2f 80 01 00 00 78 00 00 08 c0 0c 00 04 40 00 00 08
在其标题中,非零字段是Flags字(84 00),ANCOUNT字(00 01)和ARCOUNT字(00 02)。数据再次以FQDN开头(对于appletv.local,为十六进制07 61 70 70 6c 65 74 76 05 6c 6f 63 61 6c 00),然后是该主机的DNS信息:
-
A / IPv4地址类型代码(十六进制00 01),
-
IPv4类代码(hex 80 01),
-
IPv4 TTL(十六进制00 00 78 00,持续30720秒),
-
IPv4长度(十六进制00 04),
-
四个IPv4地址字节(十六进制99 6D 07 5A或点分十进制表示法153.109.7.90),
-
FQDN偏移量(字节12的十六进制C0 0C),
-
AAAA / IPv6地址类型代码(十六进制00 1C),
-
IPv6类代码(十六进制80 01),
-
IPv6 TTL(再次为hex 00 00 78 00),
-
IPv6长度(十六进制00 10),
-
16个IPv6地址字节(十六进制FE 80 00 00 00 00 00 00 02 23 32 FF FE B1 21 52),
-
FQDN偏移量(字节12的十六进制C0 0C),
-
NSEC类型代码(hex 00 2F),
-
NSEC类代码(hex 80 01),
-
NSEC TTL(再次是十六进制00 00 78 00),
-
NSEC长度(十六进制00 08,对于一个8字节的名称部分记录),
-
8个NSEC块和位图字节(十六进制C0 0C 00 04 40 00 00 08)。