這個擴展(Extension for Peers to Send Metadata Files)的目的是允許客戶端加入一個 swarm ,而無需先下載一個種子(.torrent)文件。相反,該擴展允許客戶端從同類節點那裡下載元數據。它使得支持磁力鏈接成為可能,在網頁上僅含有足夠的信息以加入該 swarm(即 info hash)。簡單來說,這個擴展可以讓用戶不用下載種子(.torrent)文件就能下載所需文件。
元數據#
在這個擴展中,只傳輸 metadata 部分,稱為 "info-dictionary" 。因為這部分數據足以讓其他客戶端知道如何加入到特定的 "swarm" 中,並開始下載文件數據。而通過使用 info-hash 來驗證 metadata 的完整性,可以確保客戶端從可靠的來源下載 metadata,而不會受到惡意修改的影響。
元數據被分成大小為 16KiB(16384 字節)的塊進行處理。這些元數據塊從 0 開始索引。每個塊的大小都是 16KiB,除了最後一個塊可能會比 16KiB 小。
擴展頭部#
當客戶端與其他節點建立連接時,它們會通過握手消息進行通信。元數據擴展使 Extension Protocol 規定的擴展協議來向其他節點宣布自己的存在。具體而言,它將 "ut_metadata" 條目添加到擴展握手消息的 "m" 字典中,用於標識此消息所使用的消息碼。此外,它還在握手消息中添加了 "metadata_size" 字段(不在 "m" 字典中),用於指定元數據的字節數。換句話說,當客戶端和其他節點建立連接並進行擴展握手時,如果元數據擴展可用,則客戶端將發送一個包含 "ut_metadata" 和 "metadata_size" 字段的擴展握手消息,以告知其他節點它支持獲取元數據。
分機握手消息示例:
{'m': {'ut_metadata', 3}, 'metadata_size': 31235}
擴展信息#
擴展消息已編碼。有 3 種不同類型的消息:
- request
- data
- reject
請求消息#
請求消息是一個字典,沒有額外的鍵(即附加信息)。如果節點支持該擴展,它會響應一個 reject 或者 data 消息,響應的 piece 必須與請求時相同。具體而言,請求和響應都涉及到相同的數據塊(piece)。
在該網絡中,一個節點必須驗證它發送的任何數據塊(piece)都通過了 info-hash 的校驗。也就是說,在該節點獲得完整的元數據之前,它不能運行 SHA-1 算法來驗證所生成的哈希值與 info-hash 相同。如果一個節點沒有完整的元數據,那麼當它收到其他節點的元數據請求時,它必須向請求方發送一個 "reject" 消息來拒絕請求。這是因為只有具有完整元數據的節點才能夠正確地進行 info-hash 校驗。因此,該網絡確保了文件傳輸的完整性和準確性,從而防止了潛在的惡意操作或數據損壞。
例:
{'msg_type': 0, 'piece': 0}
d8:msg_typei0e5:piecei0ee
請求消息正在請求第一個 metadata piece 。
數據消息#
數據消息在字典中增加了一個新的條目,即 "total_size" 。該鍵具有與擴展標頭中的 "metadata_size" 相同的語義,並且它的值為整數。這個鍵表示整個數據塊的總大小或長度,用於指示接收方需要接收多少數據才能完全重建原始數據。
在傳輸元數據時,需要先將字典序列化為二進制數據,並根據協議要求加上長度前綴。這個長度前綴不僅要包括字典本身的長度,還要包括元數據的一些附加信息,這些附加信息被稱為 metadata piece 。 metadata piece 不是字典的一部分,而是消息的一部分。如果 metadata piece 是元數據的最後一部分,則其大小可以小於 16KB;但如果不是最後一部分,則其大小必須是 16KB 。
例:
{'msg_type': 1, 'piece': 0, 'total_size': 3425}
d8:msg_typei1e5:piecei0e10:total_sizei34256eexxxxxxxx...
x 表示二進制數據(元數據)。
駁回消息#
拒絕消息不包含任何附加鍵或值,如果收到該消息,則應理解為對應的對等方沒有被請求的元數據。這意味著該對等方無法提供所需的數據片段。客戶端可以通過在服務一定數量的請求消息後開始拒絕它們來實現洪泛攻擊的保護。這個數量通常是所請求的元數據塊數乘以一個因子。
例:
{'msg_type': 2, 'piece': 0}
d8:msg_typei1e5:piecei0ee
Magnet URI 格式#
magnet URI 格式為:
v1: magnet:?xt=urn:btih:<info-hash>&dn=<name>&tr=<tracker-url>&x.pe=<peer-address>
v2: magnet:?xt=urn:btmh:<tagged-info-hash>&dn=<name>&tr=<tracker-url>&x.pe=<peer-address>
<info-hash>
<tagged-info-hash>
<peer-address>
xt
dn
tr
x.pe
詳情見此篇