BitTorrent 扩展协议(Extension Protocol)详解

概述

一个协议从制定之初就不可能是完美的,总是要根据具体情况扩展功能,但扩展功能的同时要考虑与旧版本协议的兼容性,否则当一个用户升级了新的协议后,可能之前的许多功能就不能用,因为可能大多数人还没有升级。

BitTorrent 扩展协议(Extension Protocol)为 BitTorrent 协议簇提供了一个简单而轻量的扩展方式,可以在保证兼容性的同时为协议加入新的功能。比如基于 DHT 协议 的磁力链接就是使用扩展协议加入的新功能。

本文将介绍 BT 扩展协议的报文格式和时序。

回顾“伙伴(Peer)协议

伙伴(Peer)协议在完成握手后,为每一种消息都指定了一个唯一的 ID,并且每次发送消息时,都要在消息的最开始处填充本次消息的字节长度,这个长度也包含“长度”这项数据本身占据的空间。

伙伴(Peer)协议中并没有可以用于扩展功能的消息类型,所以扩展协议为此新增了一个消息类型,并指定了唯一的 ID,即 extended 消息,ID 是 20

“扩展”消息

扩展消息的用处是完成扩展协议本身的握手流程,并且协助其它协议的工作,比如协助 DHT 协议 传输 DHT 节点的 UDP 端口。

扩展消息的 ID 为 20,当程序发送这一消息时,其布局是下面这样的,

第 0 ~ 3 个字节第 4 个字节第 5 个字节若干个字节
整个消息的长度消息的 ID(20)扩展消息的 ID载荷(payload)
extended 消息布局

报文中的第五个字节如果为 0 则表示这是握手消息,如果大于 0 则表示为其它协议的消息。报文中的载荷当扩展消息 ID 为 0 是是握手消息的载荷,其它情况下则由具体的协议规定,比如 DHT 协议 就规定了载荷的格式。

握手消息

握手消息应当在 伙伴(Peer)协议 完成握手后立即发送给对方,一方收到握手消息后,也可以向对方发送握手消息用来禁用某个协议,或者协商某个协议。

握手消息的载荷是一个经过了 B 编码的字典。下面列出的所有的字典中的项目都是可选的,任何一个未知的项目都应该被忽略,字典的全部内容都是区分大小写的。

这个字典中包含下列内容。

  • m:一个字典,从一个字符串映射到一个非负整数。字符串是受支持的协议的名称,非负整数是这个协议的 ID。协议的名称必须是唯一的,ID 则只需要保证对于通信双方唯一即可。如果 ID 为 0 则表示发送方希望禁用这个 ID 对应的协议。
  • p:一个整数,表示发送握手消息的一方监听的 TCP 端口号。对于握手消息的接收方,通常不需要发送这一项,因为对方只有在知道了监听端口后才能够向其发送握手消息。
  • v:客户端的名称(UTF-8),比如 “uTorrent 1.2”。
  • yourip:一个字符串,表示握手消息发送方看到的接收方的 IP 地址的紧凑表。消息的接收方可能持有多个 IP 地址,这一项可以告诉接收方它的哪个 IP 被发送方所使用。
  • ipv6:如果发送方持有一个或多个 IPV6 地址,则应该将这些 IPV6 地址以紧凑表的形式写入到这一项中。
  • ipv4:基本同 ipv6
  • reqq:一个整数,表示发送方允许多少个消息排队处理,超出此数量后消息可能会被丢弃。

这种握手消息比较奇怪,通常来说,一方发送握手消息后,另一方会以另外的格式来回复握手消息,比如 TLS 的 ClientHello 消息和 ServerHello 消息。但这里握手消息无论是发送还是回复都遵循同一种格式,不过也意料之中,毕竟 P2P 网络中不区分客户端和服务端。

举个例子来直观地了解一下握手消息。

d1:md11:LT_metadatai1e6:ut_pexi2ee1:pi6881e1:v12:uTorrent 1.2e

上面就是一个合法的握手消息的载荷,如果将其转化为 JSON 格式则是下面这样。

{
    "m": {
        "LT_metadata": 1,
        "ut_pex": 2
    },
    "p": 6881,
    "v": "uTorrent 1.2"
}

参考资料

Extension Protocol

本文作者:ADD-SP
本文链接https://www.addesp.com/archives/5563
版权声明:本博客所有文章除特别声明外,均默认采用 CC-BY-NC-SA 4.0 许可协议。
暂无评论

发送评论 编辑评论


上一篇
下一篇