作者能力有限, 在行文或测试或分析过程中, 也许出现些许错误, 因此并不代表本文所阐述的内容均正确无误。


背景

# bittorrent.org bep0007 草案地址 
https://www.bittorrent.org/beps/bep_0007.html

起初

bep 0007 起初是为了更好的支持 IPv6, 一开始的做法是在连接 tracker 时在 url 参数中添加 ipv6=? 的字段,但是这样会有造假的隐患。

优点

向 tracker 汇报多个 IP 从而增强各个用户或客户端之间的连接性。

举个栗子
# deluge 1.3.15 在汇报数据事请求的 url
https://pt.tracker/announce?announceKey=2@ff26fff4127841a86161449bcdc19c2f&info_hash=%bd%1a%3c%84%ac%22n%a86%f77b%170zi%baF%9a%07&peer_id=-DE13F0-r6szDsvMI*KX&port=50659&uploaded=0&downloaded=0&left=64459120526&corrupt=0&key=8E9B9F2E&event=started&numwant=200&compact=1&no_peer_id=1&supportcrypto=1&redundant=0&ipv6=2001%3abc8%3axxxx%3axxx%3a%3axxxx

分析一下请求参数

announceKey: 请求鉴权参数
info_hash: 种子的 hash, url 内的 hash 是转码过的, 本质上与客户端内显示的种子 hash 相同
peer_id: 客户端生成的一个 id, 此 id 用于识别本种子的此次连接, 不同种子不同, 同一种子在客户端重启之后会刷新
port: 客户端 torrent 端口, 是各个 peer 用于连接以及数据传输的端口
uploaded, downloaded, left, corrupt, redundant: 数据统计字段
key: 针对客户端的标记, 不受 IP 变更影响
event: 汇报事件, started 即是任务开始
numwant: 希望 tracker 返回 peerlist 的长度
compact: 客户端是否支持压缩格式
no_peer_id: 客户端不需要其他 peer 的 peer_id
supportcrypto: 客户端是否支持加密
ipv6: 由客户端汇报的 IPv6 地址

可以发现,作者安装的 Deluge 1.3.15 在 url 中附加了 ipv6 参数。

新的协议

根据草案内容, 新的汇报方式是由客户端根据本机所使用的 IP 地址, 分别向 tracker 汇报。
注意, 这里提到的根据 IP 地址分别汇报, 不仅限于 IPv4 + IPv6 这种组合, 亦可以是双 IPv4 或其它组合。
因此会出现以下这种情况:

[2021-10-16T12:20:53.363][TRACE console] 57441 (events.js 388:22) [2001:bc8:xxxx:xxx::xxxx] [GET] [/announce?announceKey=2@ff26fff4127841a86161449bcdc19c2f&info_hash=%bd%1a%3c%84%ac%22n%a86%f77b%170zi%baF%9a%07&peer_id=-DE13F0-r6szDsvMI*KX&port=50659&uploaded=0&downloaded=0&left=64459120526&corrupt=0&key=8E9B9F2E&event=started&numwant=200&compact=1&no_peer_id=1&supportcrypto=1&redundant=0&ipv6=2001%3abc8%3axxxx%3axxx%3a%3axxxx] [Deluge 1.3.15]
[2021-10-16T12:20:53.943][TRACE console] 57448 (events.js 388:22) [195.154.xxx.xxx] [GET] [/announce?announceKey=2@ff26fff4127841a86161449bcdc19c2f&info_hash=%bd%1a%3c%84%ac%22n%a86%f77b%170zi%baF%9a%07&peer_id=-DE13F0-r6szDsvMI*KX&port=50659&uploaded=0&downloaded=0&left=64459120526&corrupt=0&key=8E9B9F2E&event=started&numwant=200&compact=1&no_peer_id=1&supportcrypto=1&redundant=0&ipv6=2001%3abc8%3axxxx%3axxx%3a%3axxxx] [Deluge 1.3.15]

以上两次日志截取于 tracker 服务器日志, 可以发现 Deluge 1.3.15 在本次汇报中, 分别使用 v4 以及 v6 地址汇报了两次, 除了所绑定的 IP 以及汇报时间以外, 在数据上没有任何差别。
具体的各个客户端以及客户端的各个版本间对本草案支持程度的测试结果将在文章结尾罗列

在下文的叙述过程中, “Bep 0007” 仅表示新的 Bep 0007, 即根据不同的 IP 地址分别汇报一次

问题

大部分 PT 内站均使用的 NexusPHP 框架, 而 NexusPHP 并未考虑这个草案的适配(主要也是因为 NexusPHP 属实是一款历史悠久的框架了), 所以在内站中会有以下几类情况出现。

  1. 站点 SysOp 解决了这个问题
  2. N 次汇报都被处理, 造成数据增长 x N
  3. 仅接收第 1 次汇报, 之后的汇报以汇报频率过高的错误返回给客户端
  4. 插入数据失败, 返回 PL Err 1
  5. 数据上似乎没有问题(也可能是没发现), 但是在客户端列表中有重复 Peer 的表现
  6. 强制要求用户关闭 v6 或者选择单地址或者降版本

六类情况

  1. 第一类情况, 视站点 SysOp 的考虑而定, 有的是草率的丢弃的除第一次的汇报数据; 当然也有的是将 N 次汇报使用的 IP 入库, 存入 peer list中, 而对数据变更只做一次操作。当然第二种方法是最完美的, 既考虑了数据上的准确, 也没有放弃 bep 0007 所带来的优点
  2. 第二类情况, 这个暂时不清楚是站点 SysOp 的失误还是什么原因, 因为内站中只有个别站点有这个情况, 在用盒子 RSS 某水果站的时候, 曾经出现过客户端统计上传增长了 5T, 而站点上传数据增长了 8T 的情况。
  3. 内站中也有个别站点出现这个情况, 视站点的 SysOp 对 tracker 部分的修改而定, 需要注意的是, 在这种情况下, 客户端 tracker 连接状态里, 虽然显示为工作以及 freq limit, 但是数据统计是正常的
  4. 不说了, 暂时就一个站出现了这个情况
  5. 这个是很多站出现的情况
  6. = =. 没什么好说的, 站点的权力

个别情况的解释

暂时鸽了

解决 - 用户侧

大部分出现问题的都是 qBittorrent 4.2.1 以上的版本。因此如果用户方想要解决这个问题, 可以考虑降级或更换其它客户端。
除了更换客户端, 那有没有什么别的办法呢?
答案是有, 考虑出现这个情况的原因, Bep 0007 规定了针对不同 IP 分别汇报的方式, 那我们可以通过以下方式解决:

  1. 本地机器屏蔽多余的 IP, 大部分用户都是因为 v4 与 v6 双栈引起的, 那可以考虑屏蔽掉 v6, 屏蔽 v6 可以从客户端中选择 IPv4 地址以及在机器或虚拟机层面屏蔽 v6
  2. 但是, 去掉 v6 会一定程度的降低客户端对外的连接性, 因此可以考虑单纯的屏蔽 tracker 的 v4 地址以及 v6 地址。Linux 上可以考虑用 iptables DROP 掉目的地址为 tracker 地址的出方向流量
    除了这个, 也可以考虑在解析方面解决, 将 tracker 的 v4 或 v6 解析到一个不正常的 IP 地址, 比如 v4 的 127.0.0.1 地址, 具体操作可以考虑修改本机的 hosts 文件或者在路由器上将特定 tracker 域名解析到不正常的 IP 地址
    这类思路的实现方法还有很多, 也就不多做赘述了

测试

几点说明

  1. 因为作者家里没有 IPv6 地址, 为了测试, 采用 Clash + TUN 的模式增加了一张虚拟网卡, 实测 qBittorrent 在这种情况下也会多次汇报
  2. Windows 环境下的测试所用 qBittorrent 的安装包均从 https://www.fosshub.com/qBittorrent-old.html 下载
    Linux 环境下除非特殊说明, 均自编译方式安装
  3. 支持 Bep 0007 只代表支持 Bep 0007 的特性, 并不代表在实际使用中会出现问题(测试总结部分会有说明)
  4. 能力及时间有限, 仅测试具有代表性的几个客户端以及各自各个版本

    测试结果

    客户端以及版本 libtorrent 版本 平台 是否支持Bep 0007
    qb 4.1.9 x64 1.1.13.0 Windows N
    qb 4.2.0 x64 1.2.2.0 Windows N
    qb 4.2.1 x64 1.2.3.0 Windows N
    qb 4.2.2 x64 1.2.5.0 Windows Y
    qb 4.2.3 x64 1.2.5.0 Windows Y
    qb 4.2.4 x64 1.2.6.0 Windows Y
    qb 4.2.5 x64 1.1.14.0 Linux N
    qb 4.2.5 x64 1.2.5.0 Linux Y
    Deluge 1.3.15 1.1.11.0 Linux Y
    Deluge 1.3.15 1.1.14.0 Linux (QuickBox lite) N
    Transmission 2.94 / Linux N
    等待补充 / / /

有趣的事情

在测试中发现, qb 两次汇报的间隔在 100ms 左右, 而 de 在 400ms 左右, 当然这部分也有可能是作者测试所用的 tracker 服务器的误差所致。 (也许是个伏笔)

测试总结

  1. qb 方面, 除了 qb 的版本以外, 也需要考虑所使用的 libtorrent 库的版本。比如 4.2.5 版本, 搭配 1.1.14.0 的 libtorrent 不支持 Bep 0007, 但是搭配 1.2.5.0 却支持 Bep 0007
  2. de 方面, 1.3.15 搭配上 1.1.11.0 的 libtorrent 竟然就支持 Bep 0007。测试完 qb 之后我甚至以为是 libtorrent 在 1.2.5.0 以及之后就支持了 Bep 0007。但是测完 de 之后, 又让我陷入了疑惑当中。同时 1.3.15 到配上更新的 libtorrent 1.1.14.0 竟然不支持, 当然应该是 QuickBox lite 做了什么设置导致这样的结果, 后续还会做更多更完整的测试来验证这个问题。
  3. 需要注意的是, 支持 Bep 0007 的并不代表在站点中一定会遇到问题, 一是上文提到的数据 x N 或是报错本就具有偶发性, 二是确实存在一些情况即使支持 Bep 0007 但是在站点中并未遇到错误, 三是各个站点的 tracker 的代码都做了这样或那样的改动, 具体出现的情况也是不一样的
    比如在实际使用中 Deluge 1.3.15 + libtorrent 1.1.11.0 的这个搭配, 是支持 Bep 0007 的, 在某站却不会报 PL Err 1 的错误, 可以正常使用; 但是在某动物站却报 freq limit 的错误。

总结

Bep 0007 作为一项草案, 其目的是为了通过汇报所有 IP 从而优化各个客户端之间的连接性, 不过内站各个站点因为这个草案出现了许多问题, 希望有能力的站点今早适配这个特性, 毕竟 Bep 0007 这个草案, 对用户来说, 是有益的。

局限性

由于作者能力不足,不能从源码层面解释各个客户端各个情况下支持或不支持 Bep 0007 的原因。希望有能力的大佬能做更深层次的研究。