この拡張機能(Peers to Send Metadata Files のための拡張機能)の目的は、クライアントがトレント(.torrent)ファイルをダウンロードする必要なく、スワームに参加できるようにすることです。代わりに、この拡張機能はクライアントが同じ種類のノードからメタデータをダウンロードすることを可能にします。これにより、マグネットリンクのサポートが可能になり、ウェブページにはスワームに参加するための十分な情報(つまり、info hash)のみが含まれます。要するに、この拡張機能により、ユーザーはトレント(.torrent)ファイルをダウンロードせずに必要なファイルをダウンロードできます。
メタデータ#
この拡張機能では、メタデータの一部である「info-dictionary」と呼ばれるメタデータのみが転送されます。この部分のデータは、他のクライアントが特定の「スワーム」に参加し、ファイルデータのダウンロードを開始する方法を知るのに十分です。また、メタデータの整合性を検証するために info-hash を使用することで、クライアントが信頼できるソースからメタデータをダウンロードし、悪意のある変更の影響を受けないことが保証されます。
メタデータは、16KiB(16384 バイト)のブロックに分割されて処理されます。これらのメタデータブロックは 0 からインデックスされます。各ブロックのサイズは 16KiB であり、最後のブロックは 16KiB より小さい場合があります。
拡張ヘッダー#
クライアントが他のノードと接続する際、ハンドシェイクメッセージを介して通信を行います。メタデータ拡張は、拡張プロトコルで定義された拡張プロトコルを使用して、自身の存在を他のノードに宣言します。具体的には、拡張ハンドシェイクメッセージの「m」ディクショナリに「ut_metadata」エントリを追加し、このメッセージで使用されるメッセージコードを識別するために使用します。さらに、ハンドシェイクメッセージには「metadata_size」フィールド(「m」ディクショナリには含まれません)も追加されます。これは、メタデータのバイト数を指定するために使用されます。つまり、クライアントと他のノードが接続し、拡張ハンドシェイクを行う場合、メタデータ拡張が利用可能であれば、クライアントは「ut_metadata」と「metadata_size」フィールドを含む拡張ハンドシェイクメッセージを送信して、他のノードにメタデータの取得をサポートしていることを通知します。
拡張ハンドシェイクメッセージの例:
{'m': {'ut_metadata', 3}, 'metadata_size': 31235}
拡張情報#
拡張メッセージはエンコードされます。3 つの異なるタイプのメッセージがあります:
- リクエスト
- データ
- 拒否
リクエストメッセージ#
リクエストメッセージは、追加のキー(つまり、追加情報)を持たないディクショナリです。ノードがこの拡張をサポートしている場合、リクエストには拒否またはデータメッセージの応答があり、応答のピースはリクエスト時と同じでなければなりません。具体的には、リクエストと応答の両方が同じデータブロック(ピース)に関連しています。
このネットワークでは、ノードは送信するすべてのデータブロック(ピース)が info-hash の検証を通過していることを確認する必要があります。つまり、ノードは完全なメタデータを取得する前に、SHA-1 アルゴリズムを実行して生成されたハッシュ値が info-hash と一致するかどうかを検証することはできません。ノードに完全なメタデータがない場合、他のノードからメタデータのリクエストを受け取った場合、リクエスト元に対して「reject」メッセージを送信してリクエストを拒否する必要があります。これは、完全なメタデータを持つノードのみが正しく info-hash の検証を行えるためです。したがって、このネットワークはファイルの転送の完全性と正確性を確保し、潜在的な悪意のある操作やデータの破損を防ぎます。
例:
{'msg_type': 0, 'piece': 0}
d8:msg_typei0e5:piecei0ee
リクエストメッセージは、最初のメタデータピースをリクエストしています。
データメッセージ#
データメッセージは、辞書に「total_size」という新しいエントリを追加します。このキーは、拡張ヘッダーの「metadata_size」と同じ意味を持ち、整数値を持ちます。このキーは、受信側が完全なデータを完全に再構築するために受信する必要があるデータブロック全体のサイズまたは長さを示します。
メタデータを転送する際には、辞書をバイナリデータにシリアル化し、プロトコルの要件に従って長さの接頭辞を付ける必要があります。この長さの接頭辞には、辞書自体の長さだけでなく、メタデータのいくつかの追加情報も含まれます。これらの追加情報はメタデータピースと呼ばれますが、辞書の一部ではなく、メッセージの一部です。メタデータピースがメタデータの最後の部分である場合、そのサイズは 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
詳細はこちらの記事を参照してください。