BitTorrent プロトコル仕様書以下の内容は Bram Cohen さんによる BitTorrent protocol specification の日本語訳です。翻訳者の英語読解力不足のため、訳文には若干怪しい点があります。このプロトコルに沿ってダウンローダなどを実装しようという人は、必ず原文にも当たり内容を確認するようお願いします。 BitTorrent はファイル配信のためのプロトコルです。Web とシームレスに結合するため、ダウンロードするファイルを URL で指定できるよう設計されています。ひとつのファイルに対して多数のダウンロード要求が同時に発生した場合、ダウンローダ・プログラムはお互いにアップロードし合うことで帯域の消費を抑えながら多数の同時ダウンロードを可能にします。BitTorrent はこの点で通常の HTTP を使ったファイル転送に優っています。 BitTorrent によるファイル配信の構成要素は以下の通り。
多数のユーザがひとつのファイルを一斉にダウンロードしようとしていると仮定します。 BitTorrent 使ってファイル配信をおこなうには、次の手順でホストを設定します。
ユーザ側のダウンロード手順は以下の通り。
ここでおこなわれる接続の内容は以下の通り。
メタインフォ・ファイルおよびトラッカのレスポンスは共に、シンプルかつ効率的で拡張性に富んだ bencoding (bee encoding と発音)という形式を用いています。bencoding メッセージは入れ子状の(Python の)辞書とリストであり、文字列と整数値を保持しています。辞書のキーにない値がセットされた場合もそれを無視するようになっているため、後から新たな内容を加えて拡張することも可能です。 Bencoding の記法は以下の通り。
メタインフォ・ファイルは次のキーを持つ bencoding 済みの辞書です。
ダウンローダからトラッカへのクエリには 2 通りの方法があります。トラッカは HTTP GET パラメータによって情報を受信し、bencoding 形式で応答を返します。トラッカは自前の Web サーバ機能も備えていることに注目してください。この Web サーバ機能は Apache モジュールとして実装したみたいに立派に動作します。 トラッカへの GET リクエストには以下のキーがあります。
トラッカからのレスポンスは becoding データの辞書です。クエリに失敗した場合、レスポンスのキー メタインフォ・ファイルやトラッカのクエリを拡張する場合は、その互換性を確実なものにするため Bram Cohen に連絡を取って進めるようにしてください。 BitTorrent のピア・プロトコルは TCP 上で動作します。動作させる上で特別なソケット・オプションは何も必要ありません。 ピア同士の接続は相互に対称な構造になっています。メッセージはお互いどちらの方向にも同じ形式で送られ、データもやはり両方向で送受信されます。 ピア・プロトコルではメタインフォ・ファイルの 0 から始まるファイルのインデックスを使ってピースを指定します。ピアはピースのダウンロードが終わるとハッシュ値が一致するかどうかを調べ、一致すればそのピースを所持していることを他のすべてのピアにアナウンスします。 ピア同士の接続においてはお互いにチョーク状態かどうか(choke または unchoke)、要求状態にあるかどうか(interested または not interested)を表す2ビットの情報が含まれます。チョーク状態になると、それが解除されるまで一切データは送信されなくなります。チョークの理論と技術的な解説は後ほどおこないます。 接続の一方が interested で、もう一方が非チョーク状態ならば、データの転送が開始されます。要求の状態は常に最新に保たれていなければなりません。あるダウンローダが非チョーク状態のピアに対し要求するものが何もない場合は、チョークせずに要求されたものがないことを通知する必要があります。この機能の厳密な実装には手がかかりますが、これによって非チョーク状態のダウンローダはどのピアがダウンロードを開始したのか即座に知ることが可能になります。 接続は unchoke と not interested の状態で開始されます。 転送が開始されると、ダウンローダは複数のピース要求をいっぺんにキューに入れ TCP パフォーマンスの改善をはかります(パイプライニング)。一方 TCP バッファに書き込みきれなかったピース要求はアプリケーション・レベルのネットワーク・バッファに置かず即座にメモリ上のキューに入れなければなりません。こうすることでダウンローダがチョーク状態に入ったときすぐに切り離すことが可能になります。 ピア通信プロトコルは、ハンドシェイクと、それに続く長さのプリフィクス付きメッセージのエンドレスなストリーム通信により成り立っています。ハンドシェイクは数字の 19 とそれに続く 'BitTorrent protocol' という文字列で始まります。最初の数字は文字列の長さを表わすプリフィクスです。新たなプロトコルを作る場合もこの方式に従ってください。そうすることでわずかな違いでそれぞれを判別できるようになります。 これ以降に述べるプロトコルで送信される整数値はいずれも 4 バイトでバイトオーダはビッグエンディアンです。 固定長のヘッダの次には 8 バイトの予約領域があります。現在リリースれている実装においてこの領域はすべて 0 になっています。たとえばプロトコルの拡張でそのうち3バイトを使いたいというときは、その互換性を確かなものにするため Bram Cohen に連絡を取って進めるようにしてください。 次の部分は 20 バイトの SHA1 ハッシュ値です。これはメタ・インフォファイルの ダウンローダ・ハッシュ値の次は 20 バイトのピア id です。ピア id はトラッカへのリクエストとして送信されるものと同じで、トラッカの応答のピア一覧にもあるものです。受信側のピア id が送信側が期待する値と異なる場合も接続は提供されます。 以上でハンドシェークは終了です。次に来るのはストリーム切り替えの length プレフィクスとメッセージです。長さゼロのメッセージはキープアライブを意味し、無視されます。キープアライブは通常2分に1度の間隔で送信されますが、予定より早くデータが到着した場合はこれより早いタイミングでタイムアウトを発生させることも可能です。 キープアライブ以外のメッセージはすべてタイプを表す1バイトのデータで始まります。その内容は以下の通り。
'choke'、'unchoke'、'interested' および 'not interested' の場合ペイロードはありません。 'bitfield' は最初のメッセージとして送信します。ペイロードのビットフィールドはピースのインデックスで、そのダウンローダが送信済みのものは 1、そのほかには0をセットします。提供できるピースがまだ何もないダウンローダはこの 'bitfield' メッセージをスキップしてかまいません。ビットフィールドの最初の1バイトは上位ビットから下位ビットに向かってそれぞれ 0 から 7 の値に対応します。次の1バイトは 8から 15 という具合です。残りのスペアビットにはゼロをセットします。 'have' メッセージのペイロードは1個の数値で、ダウンローダがダウンロードを完了し、ハッシュ値のチェックを終えたことを示す指標です。 'request' メッセージは index、begin、length をペイロードとして持っています。後の2つはバイトオフセットです。length の値は EOF により切り捨てられていない限り2のべき乗になります。現在の実装はすべて 215 となっており、 217 より大きな値で接続を閉じるようになっています。 'cancel' メッセージはのペイロードは 'request' メッセージと同じです。通常はダウンロードの終了間近、「エンドゲーム・モード」において送信されます。ダウンロードの終了が真近になると、ダウンロードが完了したダウンローダは接続を切ってしまうため、最後の数ピースのダウンロードのアクセスが単一のラインに集中し、長く時間がかかってしまいがちです。最後の数ピースの処理を迅速におこなうため、そのダウンローダがダウンロードできなくて保留になっているすべてのリクエストを、そのダウンローダからダウンロードしているすべてのピアに対し送信します。その際効率が低下してしまうことを避けるため、ピースのダウンロードが完了したものについては 'cancel' をすべてのピアに送信します。 'piece' メッセージには index、begin、piece が含まれます。これらは 'request' メッセージにと連動していることに注意してください。choke や unchoke メッセージはす早く送られるのに、転送スピードがすごく遅い場合、期待していないピースが届いてしまうこともあるからです。 ダウンローダは通常各ピースをランダムな順序でダウンロードします。このためピースの全体や一部をどのピアからもらってもいいようになっています。 チョークが必要な理由はいくつかあります。TCP の輻湊回避機能は大量の接続がいっぺんに来た場合、往々にしてうまく働かないためです。またチョークにより各ピアが「お互いさま」的アルゴリズムを使って動作すれば、ダウンロードスピードの安定が実現可能になります。 以下に述べるチョークのアルゴリズムは既に実装されているものです。新たなアルゴリズムを考える場合、ネットワーク全体が新たなアルゴリズムだけで構成されているときと古いアルゴリズムが混在しているとき両方で動くようにしなければなりません。 良いチョーキング・アルゴリズムはいくつもの事柄を同時に監視するようなものでなければなりません。同時に発生する多数のアップロードが適切なパフォーマンスを得られるようにし、細動現象と呼ばれるチョーク、チョーク解除の頻発を回避しなければなりません。また、ダウンロードさせてくれたピアに対しては優遇するようにしなければなりません。さらに時々使用していない接続を試し、現在使用している接続よりもベターな接続がないか探すようにしなくてはなりません。これを楽観的チョーク解除と呼びます。 現在実装済みのチョーク・アルゴリズムでは細動現象を同じ接続先に対し10秒に1度のチョークしか許可しないという単純なアルゴリズムで回避しています。またアップロード先としてチョークを解除する相手ははダウンロードのレートが良く、interested なピア4つまでに制限しています。なお not interested であってもアップロードのレートが良いピアはチョーク解除されますが、interested であってもアップロードに貢献していないピアはチョークされます。またダウンローダが完全なファイルを保持している場合、非チョーク先に対しダウンロードのレートよりもアップロードのレートを優先させるようになっています。 楽観的チョーク解除のために、アップロードのレートにかかわらずチョーク解除されるピアが必ず1つ存在します(そのピアが interested な場合はダウンロードの許可を与える4つのピアのひとつにカウントされます)。楽観的チョーク解除の対象ピアは30秒ごとに切り替わります。ローテーション対象のピアに対しちゃんとしたピースのアップロード機会を与えるため、3回までアップロード開始の機会が与えられるようになっています。 最終更新 2004-03-02 17:19:12 |
BitTorrent protocol specification の日本語訳
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
© 2004-2010, Yasushi Iwata