4个版本
0.2.1 | 2024年8月6日 |
---|---|
0.2.0 | 2024年6月25日 |
0.1.1 | 2024年1月21日 |
0.1.0 | 2024年1月20日 |
#275 in 网络编程
6,674 每月下载量
在 3 个Crate中使用 (通过 iroh-net)
45KB
887 行
该库提供了一个基于mDNS的轻量级发现服务。它旨在帮助新节点在本地网络中找到swarm,以便在不需要预配置的接触点的情况下实现加入。与使用纯mDNS相比,该库会谨慎选择何时发送查询或响应,以确保无论swarm大小如何,使用的网络带宽都不会超出界限。同时,它保持稳定的包流,这可以作为活跃性和连接性的指示。
算法
配置参数:τ(发现时间目标),φ(响应频率目标)
每个节点通过使用每个看到的mDNS响应作为其发送者的存活信号来跟踪本地swarm的成员。这给出一个对swarm大小的估计S。由于φ是期望的响应率,因此给定节点的长期平均响应频率是φ ÷ S。为了考虑到下面描述的响应生成的随机性带来的抖动,当节点超过3S ÷ φ没有被发现时,我们将其剪枝。
每个节点根据以下算法发送mDNS查询
- 将超时设置为从[τ,τ + (S + 1) × τ ÷ 10)区间随机抽取的持续时间
- 接收到另一个节点的mDNS查询后进入响应模式
- 超时后,发送mDNS查询并进入响应模式
每个节点根据以下算法对mDNS查询进行响应
- 将超时设置为
random
+extra
的持续时间random
是从[0, 100ms * (S + 1) ÷ (τ × φ))区间抽取的- 如果节点在前一个周期中发送了响应,将
extra
设置为100ms * min(10, S ÷ (τ × φ)) - 如果节点在前一个周期中没有发送响应,将
extra
设置为max(0,extra
- 100ms)
- 将计数器设置为0
- 当接收到另一个节点对此查询的mDNS响应时,增加计数器
- 当计数器大于τ•φ时进入查询模式(请注意,这假设τ•φ>1以进行正确的操作)
- 超时后发送响应并进入查询模式
在两种模式中接收到的响应都用于发现对等节点。
讨论
从区间 [0, 1) 的均匀分布中抽取 N 个样本的平均值的概率密度函数是 (1-x)^(N-1)。(要理解这一点,可以考虑对于给定的最小值 x,其他值大于 x 的概率由上述表达式给出。) 此分布的零阶矩是 1/n,一阶矩是 1/(n(n+1)),因此平均值是 1/(n + 1)。
在查询模式下,假设对群的大小 S 有正确的估计,则最早超时的平均值是 1.1τ。线性地按群的大小扩展抽取的超时时间确保了两个对等体几乎不可能同时发送查询(假设节奏远大于典型网络延迟)。
同样,最早响应超时的平均值(忽略 extra
延迟)是 100ms ÷ (τ•φ),这意味着预期的响应数平均应该在 100ms 内发送。因此,完整的查询-响应周期时间大约是 1.1τ + 100ms,在此期间将接收到 τ•φ 个响应加上少量重复的响应(重复的概率大约是延迟 ÷ 100ms)。
假设有 10% 的重复,我们得到一个响应频率为 1.1τ•φ ÷ (1.1τ + 100ms),这比我们的响应频率目标 φ 要小。
新加入的节点
在已建立的群中,所有节点已经对 S 有相当准确的估计,使得上述计算有效。当一个新节点加入时,它假设群的大小为 1,这意味着它的查询超时将在 [τ, 1.2τ) 范围内,它的响应超时将在 [0, 200ms ÷ (τ•φ) ) 范围内。因此,它可能会启动查询并很可能发送第一个响应,使自己在群中为人所知。下一轮的 extra
延迟将与群的大小计算,这个群的大小可能至少与 τ•φ 一样大,这意味着新节点将延迟一个额外的响应间隔。这为其他节点向新成员宣布自己提供了优先权。
extra
延迟还解决了多个新节点同时加入时可能出现的公平性问题,使得每个新节点都有很好的机会在最初的几轮内向群介绍自己。
mDNS 使用
- 可配置的服务名称 NAME
- 发送针对形式为
_NAME._udp.local.
(TCP 相似)的 PTR 记录的查询 - 响应提供形式为
PEER_ID._NAME._udp.local.
->PEER_ID.local.
(和相关 A/AAAA 记录)的 SRV 记录
如果与各自的 IP 地址关联了多个端口,将为每个端口提供一个指向形式为 PEER_ID-PORT._NAME._udp.local
的资源名称的 SRV 记录。
依赖项
~7–17MB
~232K SLoC