BitTorrent v2

2020-09-08 05:07:02

Libtorrent-2.0刚刚发布,有几个主要的新特性。其中之一是对BitTorrent v2的支持。

BEP 52的大部分规范工作是由8472完成的。对BitTorrent v2的libtorrent支持主要是由Steven Siloti实现的。BiglyBT还将在不久的将来发布BitTorrent v2的实现。

在谷歌宣布产生冲突后不久,BitTorrent v2开始努力摆脱SHA-1作为碎片的散列函数。考虑到一个新的散列函数不会向后兼容,在我们遭受兼容性打击的同时,还提出了一些其他的更改。这篇文章描述了BitTorrent v2协议的新特性。

片断数据的散列函数更改为SHA-256。这样做的一个结果是散列是32字节而不是20字节。在BitTorrent v2中,信息字典也是由SHA-256计算的,这对DHT和跟踪器的兼容性构成了挑战,后者的协议要求20字节的哈希。为了处理此问题,分布式哈希表和跟踪器对v2 Torrent的通告和查找使用截断为20字节的SHA-256信息散列。

这是最初创建v2协议的基本原理之一。这意味着从根本上说,v2 Torrent将由与v1 Torrent不同的散列来标识,这将始终创建单独的群,即使在共享相同的文件时也是如此。稍后将在向后兼容性一节中详细介绍这一点。

在BitTorrent v1中,片段是散列的,生成的散列包含在.torrent文件/元数据中(在信息字典中)。在大多数情况下,片段散列是.Torrent文件大小的大部分。要将.torrent文件大小保持在大文件的合理大小范围内,可以增加片段大小,这意味着每个哈希表示文件的更大部分。较大片段大小的结果是,如果散列失败,则必须重新下载文件的较大部分,直到该片段通过散列检查。

改进这两个度量的一个旧想法是使用Merkle散列树来表示片段散列(最初是在Tribler中实现的)。这会使.torrent文件保持较小,因为您只需要树的根哈希。BitTorrent v2对片段使用Merkle散列树(但Tribler实现的协议不同)。这有以下优点:

Torrent元数据(特别是.Torrent文件的信息字典部分)变得小得多。这减少了添加磁铁链接时的启动延迟,因为在Torrent下载本身可以开始之前需要下载更少的字节。

下载的数据可以在块级别上进行验证。这意味着如果对等设备发送损坏的数据,它可以立即被发现,并且只需要重新下载16 KiB。也可以确定地识别发送损坏数据的对等体。与识别v1中的坏对等点(有时称为智能禁令)所需的启发式算法相比,这是一个很大的改进。

散列树的叶子始终为16 KiB(数据块大小),而不考虑数据段大小。片段大小的概念仍然存在,并且仍然在对等线路协议中使用,就像今天一样。例如在HAVE和REQUEST消息中。但是,片段散列实际上不是片段内容的散列,而是片段散列树的根。即完整Merkle树的子树。

在v2中,.torrent文件必须仍然包含这些片段散列(实际上是Merkle树中代表片段级别的散列)。这有助于分发和存储散列,以便在重新启动正在设定种子的客户端时不必重新计算它们。它们还存储在恢复状态中。对于v2 Torrent,.torrent文件大小并不小,因为它仍然包含片段散列,但是信息字典是小的,这是磁铁链接开始下载所需的部分。

BitTorrent v2不仅使用哈希树,还为Torrent中的每个文件形成哈希树。这有几个优点:

相同的文件将始终具有相同的哈希,并且可以更容易地从一个Torrent移动到另一个Torrent(在创建Torrent时),而不必重新对任何内容进行哈希处理。相同的文件也可以更容易地跨不同的群进行识别,因为它们的根哈希仅取决于文件的内容。

所有文件都将分片对齐,这意味着每个文件后面都有隐式PAD文件。

这解决了一个长期的愿望,即更容易地跨群识别重复文件或查找文件的多个源。

正如前面提到的,在大多数情况下,片段散列占据了信息字典中的大部分空间。例外情况是具有大量小文件的Torrent;然后是使用最多空间的文件列表。在v1 Torrents中,文件列表表示为具有完整路径的单个文件列表。在具有深层目录结构的Torrent中(或仅具有长名称的目录),这些目录名将重复多次,从而加剧问题。

V2 Torrent通过对目录结构使用更有效的编码来解决这个问题,减少了重复。目录结构不是平面列表,而是存储为树(使用本码字典)。这导致目录名只被提及一次。例如:

';文件';:[{';属性';:';x';,';长度';:12323346,';路径';:[';F';]},{';属性';:';p';,';长度';:62958,';路径';:[';.pad';,';62958';]},{';attr';:';x';,';Length';:2567,';path';:[';这是一个非常长的目录名,在v1 Torrents';,';A';]},{';attr';]},{';attr';]},{';attr';:';p';,';长度';:62969,';路径';:[';.pad';,';62969';]},{';attr';:';x';,';长度';:14515845,';路径';:[';这是一个非常长的目录名,在v1 Torrents';,';B';]},{';attr';:';p';,';Length';:33147,';path';:[';.pad';,';33147';]},{';attr';]},{';p';,';路径';:[';.pad';,';33147';]},{';p';,';:';x';,';长度';:912052,';路径';:[';这是一个非常长的目录名,在v1 Torrents';,';C';]},{';attr';:';p';,';长度';:5452,';路径&##中多次重复。:[';.pad';,';5452';]},{';attr';:';x';,';length';:1330332,';path';:[';这是一个非常长的目录名,在v1 Torrents';,';D';]},{';属性';:';p';,';长度';:45924,';路径';:[';.pad';,';45924';]},{';属性';:';x';,';长度';:2529209,';路径';:[';这是一个非常长的目录名,最终会在v1 Torrents中被重复多次。

';文件树';:{';F';:{';';属性';:';x';,';长度';:12323346,';片根';:';d1dca3b4a65568b6d62ef2f62d21fcdb676099797c8aa3e092aa0adcb9a9f6a5';}},';这是一个非常长的目录名,最终在v1 Torrent';中被重复多次。:{';A';:{';';:{';attr';:';x';,';长度';:2567,';片根';:';f6e5b48ebc00d7c6351aafdec9a0fa40ab9c8effe8ac6cfb565df070d9532f70';}},';B';:{';';:{';attr';:';X';,';长度';:14515845,';片根';:';271d61e521401cfb332110aa472dae5f0d49209036eb394e5cf8a108f2d3fb03';}},';C';:{';';:{';属性';:';x';,';长度';:912052,';片根';:';d66919d15e1d90ead86302c9a1ee9ef73b446be261d65b8d8d78c589ae04cdc0';},';D';:{';';:{';属性';:';x';,';长度';:1330332,';片根';:';202e6b10310d5aae83261d8ee4459939715186cd9f43336f37ca5571ab4b9628';}},';E';:{';';:{';属性';:';x';,';长度';:2529209,';片根';:';9cc7c9c9319a80c807eeefb885dff5f49fe7bf5fba6a6fc3ffee5d5898eb5fdb';},

在v1 Torrent中,块的大小不受规范的限制。拥有一块小于16 KiB的块大小的块没有多大意义,但这并不是不允许的。绝大多数创建的洪流都使用2的幂的块大小,但也有一些离群值不是16 KiB的,但仍然可以被16 KiB整除。V2 Torrents收紧了对块大小的要求,要求它们必须:

这样做的主要原因是片段散列适合散列树。由于v2片段散列实际上是片段的Merkle散列树根,因此它必须表示块的2次方。

.torrent文件是使用BINCODING编码的树形结构。在BENCODING中,存在具有多个可能编码的单个值的少数情况。整数可以用前导零编码,也可以不用前导零编码,0可以编码为负0。这些编码一直都是非法的,但解析器历来都很宽容并接受它们。也许最常见的例子是如何要求字典中的键按字典顺序排序。然而,一些Torrent创作者未能对它们进行分类,因此客户接受了它们。

这主要在往返折弯编码结构时引起问题。一旦解析,词典条目的特定顺序或前导零的特定数量可能会丢失。因此,当重新编码结构时,它可能会有所不同。如果正在往返的字典是INFO-DICTIONARY,那么INFO-HASH已经改变,事情就会崩溃。

词条排序不正确的词典。例如“D1:B3:foo1:A3:Bare”(“A”应排在“B”之前)

实施这些编码还有助于使两个人从相同的文件创建Torrent,最终得到相同的信息散列和相同的Torrent。

磁铁链路协议已扩展为支持v2 Torrent。与v1 SHA-1信息散列的urn:btih:prefix一样,还有一个新的前缀:urn:btmh:用于完整的v2 SHA0256信息散列。例如,磁铁链接如下所示:

带有btmh前缀的信息散列是以十六进制编码的多散列格式的v2信息散列。实际上,这意味着它将有一个双字节前缀0x12 0x20。为了向后兼容,可以在磁链路中包括V1(BTIH)和V2(BTMH)信息散列两者。

BitTorrent v2中所有不向后兼容的新功能都被仔细地命名为新名称,以允许它们与v1的对等物共存。因此,创建混合洪流是可能的。也就是说,可以同时参与v1和v2群的Torrent,服务于相同的文件。

混合Torrent有两个信息散列,一个v1 SHA-1散列,一个(可能被截断)SHA-256散列。这就形成了两个蜂群,或者说是一个隔离的蜂群。Libtorrent将对等点标记为是否支持v2。该信息还通过新的对等交换(PEX)标志进行中继。

混合.torrent文件既包括片段散列,也包括每个文件的树根散列。

对于对测试BitTorrent v2实现感兴趣的任何人(或使用libtorrent-2.0的客户端),您可以在此处找到测试Torrents: