|
グヌーテラプロトコル仕様書v0.4 原文はこちら(PDFフォーマット)、読めない方はここでGET
クリップ2・ディストリビューテッド・サーチ・サービシズ
http://dss.clip2.com
dss-protocols@clip2.com
訳者:こば、カワサキ、梅田
訳の問題はkoba@jnutella.org
, kawasaki@jnutella.org
, umeda@jnutella.org
翻訳完了日:2000年8月19日,梅田さんのご指摘により、訳を改善.(2001/01/09)
グヌーテラ(発音は「ニューテラ」という)は、分散型検索のプロトコルです。グヌーテラ・プロトコルは従来のクライアント/中央集権型サーバの検索パラダイムをサポートしますが、グヌーテラの特徴というものはピア・ツー・ピアで、中心が無いモデルなのです。このモデルでは、すべてのクライアントがサーバであり、逆にクライアントなのです。サーバントと呼ばれるグヌーテラは、通
常クライアントとサーバ双方と連携を行って作業を行っています。サーバントは、クライアントサイドにユーザーがクエリーを出し、検索結果
を見つけたことができるためのインターフェイスを提供します。それと同時にサーバントは、他のサーバントからのクエリーも受け取り、ローカルのデータとの適応を見て、検索条件に当てはまった結果
を返すのです。この分散型の性質のために、グヌーテラのプロトコルを実行するサーバントのネットワークは、フォルト・トレラントとなるのです(高い障害耐久性を発揮します)。つまり、もしサーバのサブセット(部分集合)がオフラインになったとしてもネットワークの運営が中断されることはないのです。
■プロトコルの定義
グヌーテラのプロトコルは、サーバントがネットワーク上で通
信を行うための方法を定義しています。同プロトコルは、サーバント間のデータ通
信を行うためのデスクリプター(descriptors:種類を確認しデータ記録を合体させるのに使われるキーワード)の集合と、デスクリプターのサーバント間での交換を管理するルールの集合とで構成されています。現在、以下のデスクリプターが定義されています。
| デスクリプター |
解説 |
| ピング(Ping) |
ネットワーク上でホストを探すのに使われます。ピングのデスクリプターを受け取ったサーバントは1つ以上のポングのデスクリプターを返すと予期されます(期待されます)。 |
| ポング(Pong) |
ピングへの返答です。接続されたグヌーテラ・サーバントのアドレス、及び、ネットワークへと利用可能なデータの総量
とみなされる情報を含みます。 |
| クエリー(Query) |
分散型ネットワークを検索するために必要となる主要なメカニズム。もしローカルのデータの中に検索にふさわしいものが見つかったら、クエリーのデスクリプターを受け取ったサーバントはクエリーヒットを返信します。 |
| クエリーヒット(QueryHit) |
クエリーの返信です。一致したクエリーのマッチングを行うデータを手に入れるために、このデスクリプターは十分な情報を持つ受け取り人を提供します。 |
| プッシュ(Push) |
ファイアウォール化されたサーバントが、ネットワークへのファイルベースのデータを提供することを可能にするメカニズムです。 |
現在ネットワーク上に存在する他の別
のサーバントと接続を確立することで、グヌーテラサーバントは、ネットワークと自身との接続を行います。他のサーバントのアドレスの獲得は、プロトコルの定義の一部ではありません。ですから、それについてはここでは詳述を避けます(ホストのキャッシュサービスは、グヌーテラのサーバントのアドレスの獲得を自動的に行うという方法を通
じて、現在顕著に見られる方法ですが)。
他のサーバントのアドレスを取得してTCP/IP接続が確立されると、
次のようなグヌーテラの接続要求がASCII文字列で送られることになります。
GNUTELLA
CONNECT<protocol version string>/\n\n
ここでは、この仕様書のバージョンでは
"0.4" (訳注:16進数で0x30 0x2e
0x34)と定義されています.
-
Page1 -
この接続要求を受け入れるサーバントは
GNUTELLA OK\n\n
と応答しなければなりません.
接続を受け取るために他のいかなる返答は、サーバントの気が進まないことを示します。サーバントは様々な理由で、入ってくる接続要求(incoming
connection)を断るかもしれません−入ってくる接続スロットのサーバントのプールが使い果
たされるかもしれませんし、例えば要求しているサーバントとして、同じバージョンのプロトコルをサポートしていないかもしれません。
1度サーバントがネットワークへの接続に成功すると、グヌーテラ・プロトコルのデスクリプターを送受信することで他のサーバントと通
信を行います。互いのデスクリプターは、次に与えられたようなバイト構造を持つデスクリプターのヘッダーによって処理されます。
ノート1:特に指定がないかぎり、以下のデータ構造中のフィールドはすべて
ネットワークバイトオーダ(つまりビックエンディアン)です.
■次のような構造の中にあるすべてのIPアドレスはIPv4のフォーマットです。例えば、IPv4バイトアレーなど。
byte 0
byte 1
byte 2
byte 3
これをドットを含むアドレスとして表現すると、208.17.50.4.
■デスクリプター・ヘッダー
| メッセージID(Message
ID) |
ペイロード・デスクリプター(Payload
Descriptor) |
TTL |
ホップ数(Hops) |
ペイロード長(Payload
Length) |
バイト・オフセット0、15、16、17、18、19、22
-
Page2 -
●デスクリプター・ID ネットワーク上のデスクリプターを一意に見分けるための16バイト・ストリング
●ペイロード・デスクリプター 0x00=ピング(Ping)、0x01=ポング(Pong)、0x40=プッシュ(Push)、0x80=クエリー(Query)、0x81=クエリーヒット(QueryHit)
●TTL、タイム・トゥ・リブ(Time To
Live) ネットワークからパケットが削除されるまで、グヌーテラのサーバントからサーバントへと転送されることになるデスクリプターの数字で。互いのサーバントは、他のサーバントへパスする際にTTLを1つずつ減らしていきます。TTLが0に達すると、デスクリプターはもうそれ以上転送されることはありません。
●ホップ数 デスクリプターが転送される数字です。サーバントからサーバントへとデスクリプターはパスされ、その際、ヘッダーにあるTTLとホップ数のフィールドは次の公式を満たさなくてはなりません。
TTL(0)=TTL(i)+Hops(i)
ここでTTL(i)とHops(i)は、i 回ホップされたdescriptorのヘッダ部に
おける、TTLとHOPフィールドの値です.
●ペイロード長 このヘッダの直後に続くdescriptorの長さを表します.
ヘッダの末尾から数えてペイロード長後ろから、次のヘッダが続き
ます.つまりGnutellaの(ネットワーク上の)バイト列には (descriptorの境界を調整するための)空白やパディング(pad
bytes) がありません.
TTLはネットワークにあるデスクリプターを消去するための唯一のメカニズムです。サーバントは、必要なものとしては低く受け取ったデスクリプターのTTLのフィールドを注意深く綿密に調べるべきです。TTLフィールドの乱用は、不必要なネットワークトラフィックとネットワークパフォーマンスの低下を招くからです。
ペイロード長フィールドは、ネットワーク上を流れるデータから、次のデスクリ
プターの始まりをサーバントが見つけるためのたったひとつ信頼できる方法です。
グヌーテラ・プロトコルは(descriptorの区切りの)目印となる文字列や、
(一度descriptorを見失ったバイトストリームから再び)デスクリプターの始
まりを見つける手段を提供していません. それゆえにサーバントはペイロード長を厳密に確認すべきであり、もしサーバ
ントがバイト列からdescriptorを見失ったら、その接続を切断するべきです.
以下4つのdescriptorのいずれかが、ペイロードとしてヘッダの直後に続きます.
■ピング(0x00)Ping(0x00)
Ping descriptorに対応するペイロードはなく、長さ0です.
Pingは、Playload_Descriptor フィールドが0x00、Payload_Lengthフィールド
が0x00000000 の ヘッダだけで現わされます.
Pingは、ネットワーク(の状態)を試すために他のサーバントに向けて使われます.
Pingを受け取ったサーバントはPongを応答するか選択してよく、Pongにはアクティ
ブなサーバントのアドレスとネットワーク上で共有しているデータの総量
が含まれ ます.
この文書では、サーバントがどのような頻度でピング・デスクリプターを送るべきであるかとか、ネットワーク上でのピング・トラフィックの最小化を行うためのすべての試みをサーバントが行うべきであるとかいうようなことは、頻度の時と同じように推薦はおこないません。
-
Page3 -
■ポング(0x01)Pong(0x01)
| ポート(Port) |
IPアドレス(IP
Address) |
共有されたファイル数(Number
of Files Shared) |
共有されたキロバイト数(Number
of Kilobytes Shared) |
バイトオフセット0,1,2,5,6,9,10,13
●ポート Pingに応答したサーバントが接続を待ち受けるポート番号
●IPアドレス 反応があったホストのIPアドレス
●This field is in
little endian format.
●共有されたファイル数 与えられたIPアドレスとポートを持つサーバントが、ネットワーク上で共有しているファイルの数
●共有されたキロバイト数 与えられたIPアドレスとポートを持つサーバントが、ネットワーク上で共有しているキロバイト数
インカミングのピング・デスクリプターへの反応として、ポング・デスクリプターは唯一送られるものです。1つ以上のポング・デスクリプターが、単一のピング・デスクリプターへの反応として送られるということは妥当です。これは、ホストのキャッシュが、ピングのリクエストへの反応としてキャッシュされたサーバントのアドレス情報を送ることを可能にします。
■クエリー(0x80)
| 最低速度(Minimum Speed) |
検索基準(Search criteria) |
バイト・オフセット、0、1、2、・・・
●最低速度 このメッセージに応じるべきサーバントの最低速度(キロバイト/秒)。
nキロバイト/秒の最低速度フィールドを持つクエリー・デスクリプターには、
nキロバイト/秒以上で通信できるサーバントのみがQuery Hitを応答すべきです.
●検索基準 null
(=0x00) で終端させた検索文字列です. このストリングの最大長は、デスクリプター・ヘッダーのPayload_Lengthフィー
ルドによって制限されます。
■クエリーヒット(0x81)QueryHiy(0x81)
|ヒット数(Number of Hits)|ポート(Port)|IPアドレス(IP Address)|速度(Speed)|結果
セット(Result Set)|サーバント識別子(Servent Identifier)|バイト・オフセット、0,1,2,3,6,7,10,11、n、n+16
●ヒット数 結果
セットの中のクエリーヒットの数(以下参照)
●ポート インカミングの接続を受け取ることができる応じたホストのポート番号
●IPアドレス 応じたホストのIPアドレス
●速度 応じたホストの速度
-
Page4 -
●結果
セット クエリーに一致した応答のセット。このセットは含んでいる、以下の構造によって示されるNumber_of_Hitsの要素を含んでおります。
| ファイル・インボックス(File
Inbox) |
ファイル・サイズ(File
Size) |
ファイル名(File
Name) |
バイト・オフセット、0,3,4,7,8、・・・
●ファイル・インデックス 応じたホストによってアサインされた番号で、クエリーに一致したファイルのマッチングを確認するために唯一使われます。
●ファイル・サイズ ファイルのインデックスとしてFile_Indexが指定されたファイルのサイズ
●ファイル名 ファイルのインデックスとしてFile_Indexが指定されたダブル−ヌルの名前
結果セットのサイズは、デスクリプター・ヘッダーのPayload_Lengthフィールドによって制限されます。
●サーバント識別
子 ネットワークで返答のあったサーバントを認識するための16バイトのストリング。これは、通
常サーバントのネットワーク・アドレスの機能です。サーバント識別
子は、プッシュ・デスクリプターの操作の際に必要な道具です(下を参照)。
クエリーヒットのデスクリプターは、インカミングのクエリー・デスクリプターへの返答の中に送られるだけます。もしそれが厳密にクエリーの検索基準と適応するデータを含んでいる場合には、サーバントは、クエリーヒットを使ってクエリーに対してだけ返答すべきです。
クエリーヒットのデスクリプター・ヘッダー中のDescriptor_IDフィールドは、対
応するクエリーのDescriptor_IDと同じ値にすべきです。これによりそのクエリー
に対応するクエリーヒット・デスクリプターを見分けることができます。
■プッシュ(0x40)Push(0x40)
| サーバント識別
子(Servent Identifier) |
ファイル・インデックス(File
Index) |
IPアドレス(IP
Address) |
ポート(Port) |
バイト・オフセット、0,15,16,19,20,23,24,25
●サーバント識別
子 サーバント識別子 File_Indexで現されるファイルのプッシュを要求されてい
るサーバントを、ネットワーク上で一意に見分けるための16バイトのストリ
ング。 プッシュリクエストを送信するサーバントは、対応するクエリーヒット
のServent_Identifierの値をこのフィールドにセットすべきです。
これによりプッシュリクエストの受取人は、自分がそのリクエストの対象であ
るのかどうかを決定できます.
●ファイル・インデックス ターゲットとなるサーバントからプッシュされたファイルを一意に識別
するインデックスです。プッシュリクエストを識別するこのサーバントは、クエリーヒットのデスクリプターの返答の中の結果
セットから来たFile_Indexフィールドの一つの価値へとこのフィールドをセットすべきです。
●IPアドレス File_Indexを持つファイルがプッシュされるべきホストのIPアドレス
●ポート File_Indexのインデックスを持つファイルがプッシュされるべきポート
-
Page5 -
サーバントはincoming接続をサポートしていないサーバントからQueryHit識別
子を受け取るとPush識別子を送信するでしょう。
これはQueryHit識別子を送っているサーバントがファイヤーウォールの内側にいる場合起きます。サーバントがPush識別
子を受け取った場合、サーバント識別子フィールドにそのサーバントの識別
子の値が含まれていた場合、Push要求として処理します。
■識別
子のルーティング
Gnutellaネットワークのピアツーピアの性質によりサーバントはネットワークのトラフィック(クエリー、クエリー応答、PUSH要求)を適切なやり方でルーティングしなければなりません。よい振る舞いをするGnutellaサーバントはプロトコル識別
子を以下のような規則にしたがってルーティングを行います。
1.Pong識別子はPing識別子が運ばれてきたのと同じ経路に沿ってのみ送信されます。こうすることでPing識別
子をルーティングしたそれらのサーバントだけが応答としてPong識別
子を見るということが保証されます。識別子ID=nをもつPong識別子を受け取っているが、識別
子ID=nをもつPing識別子を見たことのないサーバントはネットワークからPong識別
子を取り除かなければなりません。
2.QueryHit識別子はQuery識別子が運ばれてきたのと同じ経路に沿ってのみ送信されます。こうすることでQuery識別
子をルーティングしたそれらのサーバントだけが応答としてQueryHit識別
子を見るということが保証されます。識別子ID=nをもつQueryHit識別
子を受け取っているが、識別子ID=nをもつQuery識別子を見たことのないサーバントはネットワークからPong識別
子を取り除かなければなりません。
3.Push識別子はQueryHit識別子が運ばれてきたのと同じ経路に沿ってのみ送信されます。こうすることでQueryHit識別
子をルーティングしたそれらのサーバントだけが応答としてPush識別
子を見るということが保証されます。識別子ID=nをもつPush識別子を受け取っているが、識別
子ID=nをもつQueryHit識別子を見たことのないサーバントはネットワークからPush識別
子を取り除かなければなりません。
4.サーバントはやってきたPingやQuery識別子をそれらを配送したサーバントを除いて、直接接続しているすべてのサーバントにフォワードします。
5.サーバントは直接接続しているすべてのサーバントに識別子をフォワードする前に識別
子ヘッダのTTLフィールドを1つ減らし、Hopsフィールドを1つ増やします。識別
子ヘッダのTTLフィールドを1つ減らした結果その値が0であるということが判明したら、その識別
子はあらゆる接続にフォワードされません。
6.既に受け取ったのと同じペイロード識別子と識別子IDをもった識別
子を受け取ったサーバントはその識別子をフォワードしないようにしなければなりません。再びフォワードするのはほとんどネットワーク帯域の無駄
使いです。
-
Page6 -
(ルーティング説明図)
例1.PingとPongのルーティング
例2.Query/QueryHit/Pushのルーティング
 |
-> |
 |
■ファイルのダウンロード
いったんサーバントがQueryHit識別子を受け取ると、その識別
子の検索結果集合に書かれているファイルの直接ダウンロードを初期化します。ファイルはネットワークではなく直接ダウンロードされます。ファイルデータはGnutellaネットワーク上で転送されることはありません。
ファイルのダウンロードプロトコルはHTTPです。ダウンロードを初期化したサーバントは目的のサーバに以下のような形式の要求文字列を送信します:
GET /get/<File Index>/<File Name>/HTTP/1.0\r\n
Connection: Keep-Alive\r\n
Range: bytes=0-\r\n
\r\n
ここで<File Index>と<File Name>はQueryHit識別子の検索結果
集合に含まれるファイルインデクス/ファイル名の一対です。
たとえば、検索結果集合に記載欄が以下のような場合
(表)
この記載欄に書かれているファイルのダウンロード要求が以下のように初期化されることになります。
GET /get/2468/Foobar.mp3/HTTP/1.0\r\n
Connection: Keep-Alive\r\n
Range: bytes=0-\r\n
\r\n
このダウンロード要求を受け取ったサーバはHTTP1.0遵守のこのようなヘッダで応答します。
HTTP 200 OK\r\n
Server: Gnutella\r\n
Content-type: application/binary\r\n
Content-length: 4356789\r\n
\r\n
ファイルのデータはその後続き、サーバのHTTP応答で提供されるContent-lengthの中で特定されたバイト数を読みこまれ、含まれることになります。
Gnutellaプロトコルはダウンロードが終了した地点から中断されたダウンロードを再開できるようにHTTP範囲パラメータをサポートします。
©
2000 Ian Hall-Beyer. All Rights Reserved.
<manuka@nerdherd.net>
|