Probe
这一步骤称为冲突检测:设备的mDNS在接入网络或接入服务之前一般要先进行Probe过程,向网络中的其它主机发送询问,验证所要发送的资源记录名字(本机名或者服务名)在网络中是否已经存在。其流程如下:
首先,probe将向对应的组播地址和端口发送三个相同的UDP查询数据包,查询所要发送的资源名称在网络中是否有重名。
类似于DNS查询报文,我们既可以对某名字的指定资源类型进行冲突探测,也可以对还有某名字的所有类型资源进行冲突检测(制定type值为255,即“ANY”)。
在RFC6762的规定中,三个查询mDNS查询报文之间的时间间隔通常为250ms,从第一个查询报文发送的时间起,到第三个查询报文发送后250ms为止,如果接收到了来自其他设备的组播回应。则将资源重新命名,5s后重新进行Probe。如果未收到,则结束顺利结束Probe进入Annoucing阶段
根据RFC文档的描述,以下几点需要特别说明:
-
Probe之前本机不必检查cache,只有当前实时网络环境中的资源记录才会干扰其进程;
-
Probe过程中重复发送副本的时间间隔仅为250ms,远低于常规副本发送规定的1s。因此,当一个设备收到Probe的查询名字请求的时候应该尽快回复并立刻,所以在Probe的查询名字请求中。一般将unicast-response bit置为1(即发送“QU”查询报文)。这样可以允许其它设备使用单播方式向源地址和端口发送回复。相对于组播更快。
-
如果在网络环境中,可以确定主机名字一定不会被其它设备所使用,则可以省略probe步骤
-
在发送Probe查询时,如果两个Probe查询同一资源记录,并同时到达同一主机中,那么得到的回复都将会是无冲突。接下来两个主机发送名字的时候,局域网中就会出现重复的名字。为了处理这种情况,在Probe查询报文的authority部分会附带主机准备发送的资源记录详情。
- Probe的authority:当两台设备的Probe报文同时发送到第三台设备的mDNS模块,且查询的资源记录相同时,第三台应该进行如下处理:
- 两个报文查询的是同一个记录的情况下:两个报文从class字段开始,到type字段直到rdata字段,按照字典序逐字段比较大小。字典序靠前的报文,视为失败,主机将把字典序靠后的报文的authority中包含的资源记录作为回复发送给他。而字典序靠后的报文视为胜利,主机将不会回复,这样字典序靠后的主机得到的回应是无冲突,而靠前的主机得到了一个与其将要发送的资源记录冲突的资源记录,就会进入重命名阶段。
- 两个报文查询的多个记录的情况下:把两个报文中的记录先各自按照字典序排序,接下来将两边报文中的记录成对的按照字典序一一对应比较大小,直到出现不匹配,然后按照上述机制处理。如果一个资源的记录已经比较完,而另一个还有,则将还有的那个视为胜利,即字典序靠后。如果全部比较完仍然完全一致,按照实际情况来说,是没有冲突的,因为如果出现冲突,至少IP地址不应该一样。或者主机名称不应该一样。
-
mDNS是多播,因此上述同时(这里说的同时是指时间误差比较小)到达的冲突处理在每个主机都会发生,相对于及其不稳定的时间顺序来说,采用字典序比较结果才能保持在每个主机每个时间的反应都一致。同时,如果真的是冲突发生,那么按照字典序比较就一定会分出大小。。。如果不明白为什么,那么说明你对DNS的资源记录和工作原理还不太了解。
- 大型复杂的系统中如果10s之内发生了15次以上的冲突,主机在重新probe之前必须等待5s。在简易设备中,每发生一次冲突等5s即可(如图)。