Peer Exchange (PEX) 为 swarms(节点群
它提供了比大多数其他来源更为实时的 swarm 视图,并且还减少了频繁查询其他来源的必要性
与规范节点优先级
协议扩展
PEX 通过扩展协议引入新消息 ut_pex 。
在握手中协商添加的消息:
{
m: {
ut_pex: <implementation-dependent local message ID (positive integer)>,
...
},
...
}
扩展消息本身由 BitTorrent/扩展消息头和随后的 bencoded 编码载荷组成:
{
added: <one or more contacts in IPv4 compact format (string)>
added.f: <optional, bit-flags, 1 byte per added IPv4 peer (string)>
added6: <one or more contacts IPv6 compact format (string)>,
added6.f: <optional, bit-flags, 1 byte per added IPv6 peer (string)>,
dropped: <one or more contacts in IPv6 compact format (string)>,
dropped6: <one or more contacts in IPv6 compact format (string)>
}
标志定义如下:
Bit | when set |
---|---|
0x01 | 首选加密,如分机握手中的 e 字段所示 |
0x02 | 做种/仅上传 |
0x04 | 支持 uTP |
0x08 | 节点指示 ut_holepunch 支持分机握手 |
0x10 | 传出连接,节点可访问 |
一个节点只有在成功建立连接后才能被包含在“added”字段中,当它断开连接后则需要被包含在“dropped”字段中。一旦一个节点已经被添加,客户端必须确保在适当的时候发送相应的“dropped”事件。仅仅向其他节点发出“added”信号而从未对其进行“dropped”的操作是不符合规范的行为。
原因一:PEX 旨在反映客户端当前连接的节点,这确保了 PEX 提供比其他节点发现机制更好的实时信息。原因二:仅传播经过验证的节点可减少攻击者滥用 BitTorrent swarms 进行分布式拒绝服务攻击的机会。
相互通信的客户端应将其批量更新频率限制为每分钟一次
不需要在握手后立即发送 PEX 消息,例如,在 torrent 启动期间,客户端可能会等到它建立足够的连接以使发送的 PEX 消息变得有价值。
添加或删除的联系人不得包含重复项。
只要不影响正确性,就可以在更新消息之间省略暂时性连接-断开连接或断开连接-重新连接事件。
实现说明:对于每个已连接的节点,一种简单的方法是将其尚未发送的连接/断开连接事件排队,并在生成消息时忽略重复和瞬时连接。另外一种更加节省内存的方法是为每个 torrent 记录连接/断开连接事件的时间轴,并为每个节点存储一个指针,指向已经发送的事件的时间点。在创建 PEX 消息时,只需推进指针,注意消除重复项并省略短暂连接即可。
在同一条消息中不应删除已添加的联系人
除初始 PEX 消息外,添加的 ipv4/ipv6 联系人的总和不应超过 50 个条目。这同样适用于删除的条目。
消息必须包含以下至少一个字段:added, added6, dropped, dropped6。
客户端可能会断开严重违反这些约束的节点。
填充未充分利用的列表
含以下组合
- 应满足的网络连接要求
- 节点在做种时断开与其他对等节点的连接
- 基于在 IPv4 和 IPv6 之间的相同节点 ID 断开重复节点的连接
可能导致 added 或 added6 列表未充分利用。使用 PEX 协议可能会导致种子列表中出现过少的连接节点。如果一个种子节点没有可以传播的连接节点,而其他节点只有能够传播给其他种子节点的连接节点,那么 PEX 的效果会被大幅降低,从而导致种子列表中的连接节点数量过少。在IPv4 占主导地位的种子群中,也会遇到类似的问题,即获取 IPv6 连接节点比较困难,因为 IPv6 连接节点会被视为已经建立的 IPv4 连接的重复,从而阻止它们通过 PEX 进行传播。
为了解决这个问题,BitTorrent 协议指定了一个“活动要求”,用于确定何时将连接视为非活动状态并应终止。但是,在某些情况下,如果客户端连接到特定地址系列(例如 IPv4 或 IPv6)的客户端少于 25 个,则此活动性要求会放宽。相反,客户端可以为该地址系列保留最多 25 个最近建立和完全握手的连接的列表,并记录任何断开连接的原因。这些原因将使远程联系人有资格包含在“added”或“added6”列表中。这些列表可能是指给定地址系列的受信任或允许的远程主机的列表。通过维护最近连接的列表并记录断开连接原因,客户端可以更好地管理其连接,并确保它与网络中可靠稳定的节点保持连接:
- 同一节点 ID 已在不同的地址系列下连接
网络地址格式或族不同(例如 IPv4 与 IPv6) - 两个对等节点无法或不愿意相互建立连接以交换共享文件片段的情况
- 本地资源限制,例如全局连接数已超过限制
PEX 消息在包含最近断开连接的联系人时需要从“最近已看到的列表”中清除该联系人,以使其不会在下一条消息中再次发送。当列表通过短暂的连接-断开事件重新填充时,如果所有必要条件都满足,这些事件可能会包含在下一条消息中。换句话说,在从“最近已看到的列表”中填充初始 PEX 消息的同时,客户端还可以跳过某些连接-断开事件,这样就能更有效地构建 PEX 消息。简单来说,当一个节点与其他对等节点断开连接后,它将被删除并不再包括在该节点发送的下一条 PEX 消息中。但是,如果该节点重新连接到网络并符合一定的条件,那么它可能会再次出现在该节点的 PEX 消息中。此外,客户端还可以跳过不必要的连接和断开事件,以更有效地构建 PEX 消息。
最近看到的联系人并不一定是当前正在进行的连接,所以它们需要在下一条 PEX 消息中被删除
在同一条 PEX 消息中不能同时添加和删除相同地址的限制仍必须保留。
选择少于 25 个活动连接和不超过 25 个最近看到的联系人的要求,为了确保最多只能累积两条可丢弃联系人的 PEX 消息,并且只有在没有足够的活动联系人可以填充 PEX 消息时才会发送旧版信息。
请注意,这个豁免规则可以分别应用于IPv4和IPv6。即使有足够的 IPv4 活动连接,但如果 IPv6 相关的列表数量不足,客户端仍可以在 PEX 消息中包含最近看到的 IPv6 联系人,反之亦然。
安全注意事项
接收到的 PEX 消息应被视为不受信任且可能是恶意的
攻击者可能会尝试通过与其他节点协作向 swarm 发起虚假信息洪泛攻击
PEX 还可以通过诱导 BitTorrent 客户端对受害者 IP 范围进行连接尝试用于发起分布式拒绝服务攻击(DDoS),从而使这些 IP 地址的网络流量骤增,造成网络拥塞和服务不可用。
为了缓解这些问题,客户端应该避免从单个 PEX 源获取所有连接候选者。重复的 IP 地址(例如具有不同端口的 IP 地址)应该被忽略
总结
PEX 是一种用于 BitTorrent 协议的扩展。它通过允许 BitTorrent 客户端交换各自所知道的其他用户的 IP 地址和端口信息,来扩展节点列表并增强网络连接。
PEX 允许客户端直接与其他客户端进行通信并交换节点信息。通过这种方式可以更快地发现和连接其他节点,加快下载速度,并减轻 tracker 的负担,同时也提高了网络的可靠性和及时性。
需要注意的是,PEX 功能可以被禁用或限制,因为它不受 BitTorrent 协议规范的约束,并且可能会导致某些问题,如假节点攻击、隐私泄露等。因此,在使用 PEX 时,应该考虑安全和隐私的问题,并根据具体情况进行配置和调整。
参考链接
- http://www.bittorrent.org/beps/bep_0011.html
- https://en.wikipedia.org/wiki/Peer_exchange