Gnutella: 自らを生み出した世界より長く生き残ったプロトコル
(rickcarlino.com)- Gnutella は忘れ去られたファイル共有プロトコルに近いが、分散型技術を意識していなかった何百万人ものユーザーが MP3 ダウンロードという問題を解決した実例だった
- 2000〜2001年の米国では インターネット普及率 が50%に達し、低価格化した MP3プレーヤー、ストリーミングの限界、ファイルを自分で管理する文化が採用を後押しした
- サーバーレス構造と 単一障害点 の不在により、AOL による中止後も巻き戻しが難しく、何年にもわたる停止の試みにもかかわらず動作し続けた
- 基本構造は HTTP によるファイル転送と TCPゴシッププロトコル の結合であり、PING/PONG、QUERY/QUERYHIT、PUSH が検索・応答・ファイアウォール回避を担う
- 主流から消えた理由は即時的な技術的失敗ではなく、当時の ユーザー環境 が消滅したためであり、ネットワークは縮小した規模で今も生き続けている
Gnutella が長く生き残った理由
- Gnutella は多くの人が忘れてしまったファイル共有プロトコルだが、分散型技術を理解しようとしていなかった一般ユーザー何百万人もが、現実の問題を解決するために使った事例である
- ユーザーはトークン価格の上昇のような動機ではなく、MP3 ダウンロード のために Gnutella ネットワークに参加し、ネットワークは爆発的に成長した後、およそ10年間安定期にあり、その後は利用量が減りながらも長い尾を引いて存続した
- Gnutella は LimeWire のようなより目立つプロジェクトの裏に隠れた構成技術であり、現代のプラットフォームによる 囲い込み型エコシステム のせいで、ファイルシステムそのものを知らないインターネットユーザーすら増えた
- Gnutella プロジェクトは、AOL が中止した社内デモが公開状態で流出したことから始まり、サーバーのない分散設計のため、一度公開されると取り消すのが難しかった
- Gnutella は停止の試みにもかかわらず何年も動作し続け、元の
Gnutella.exeのコピーも archive.org で見つけられる - 失敗したプロトコルと見なしにくい理由は明確である
- 何百万人もの同時アクティブユーザーにまで拡張し、およそ10年にわたり主流のユースケースとして栄えた
- 主流から消えた理由はプロトコル自体の即時的な失敗ではなく、Gnutella が生まれた ユーザー環境 が消えたためである
- 今日でも縮小した規模で動作し続けている
採用を生んだ歴史的条件
- 2000〜2001年ごろ、米国の消費者向け インターネット普及率 は50%に達し、インターネットはマニア向けの道具から日常的な基盤へと変わりつつあった
- 音楽ファイル共有が一般化した背景には、複数の条件が同時に作用していた
- 音楽業界が変化する消費者の嗜好に適応できなかった
- MP3プレーヤー とソリッドステートストレージが安価になり、広く普及した
- 低速なダイヤルアップ接続では音楽ストリーミングは現実的でなかった
- ディスク容量、ディレクトリ、バックアップ、ダウンロードファイルを自分で管理することが、当時の一般的なコンピュータユーザーにも受け入れられていた
- こうした条件は2010年代初頭まで続いたファイル共有の黄金期を生み、LimeWire はその時代の体験を象徴する名前として残った
- Gnutella には 単一障害点 がなかったため潰しにくく、基本プロトコルは単純だったが、仕様に含まれる任意拡張のおかげで容易に拡張できた
プロトコルの基本的性格
- Gnutella は大多数のユーザーにとってはファイル転送ツールだったが、本質的には blob を探す P2P 検索エンジン に近い
- 原理的には簡易 DNS、グローバルなキー/バリュー型メタデータ検索テーブル、Unreal Tournament のリーグマッチングサービスのような用途にも使えたが、実際の歴史では、検索語に一致するファイルのダウンロード、とりわけ MP3 ダウンロードとして記憶されている
- Gnutella 0.6 のドラフト仕様では、共有対象リソースは他のリソースへのマッピング、暗号鍵、あらゆる形式のファイル、キー指定可能なリソースのメタ情報など、何でもあり得るとされている
- 一般的な利用フローは次の通りだった
- LimeWire、BearShare、GTK-Gnutella のような Gnutella クライアント を起動する
- クライアントがインターネット上のどこかにいるいくつかのピアに接続する
- ユーザーが
LinkinPark.mp3.exeのような検索語を入力する - 問い合わせがピアからピアへとネットワークの外側へ広がっていく
- 世界中の無作為なコンピュータから結果がゆっくり返ってくる
- ユーザーはファイル名を見て偽物かどうかを推測し、接続速度を比較し、ウイルスがないことを願う
- ファイルを選ぶと、クライアントがユーザーのコンピュータから HTTP で直接断片をダウンロードする
- 間違ったファイルを受け取るうちに新しいコンテンツを偶然発見したり、マルウェアを受け取ったりすることもあり、こうした 探索的採集 的な行動はレコメンドエンジンの登場とともに消えていった
- クライアントは通常、4つの主要機能を提供した
- クエリマネージャ: 数千のピアにわたってゆっくり広がる検索を処理する
- ファイルマネージャ: 共有するディレクトリやパス、ダウンロードファイルの保存先を指定する
- 転送マネージャ: 双方向ファイル転送の再開、分割、管理を処理する
- 付加機能: IRC チャット、掲示板、検索クエリモニタ、特定ホストの探索といった機能が含まれたが、その多くはプロトコル自体の一部ではなかった
- Gnutella エコシステムには LimeWire のような市場リーダーがいた一方で、複数のクライアントが共存し、独立開発者がクライアントをゼロから実装することもできた
- Gnutella Bun Client の実装過程では、仕様にない内容、文書化されていない機能、追加仕様に散在する機能が数多くあり、プロトコルは有機的に進化してきた
HTTP とゴシッププロトコルの結合
- 個人コンピュータで HTTP サーバーを立てて IP アドレスを知らせればファイル共有はできそうに見えるが、今日では NAT、ファイアウォール、家庭向け ISP の方針などにより、インバウンド TCP ポートを公開するのは難しい
- 20年前には、ローカルマシンで小さな HTTP サーバーを動かし、グローバル IP で外部公開することが今よりずっと一般的に可能だった
- Gnutella はこの環境を活用し、ゴシップを交わすピアのメッシュの中で各参加者がファイルをホストできるようにした
- LimeWire でファイルをダウンロードする転送段階は、
curlやwgetでファイルを取得するのに似ていた - HTTP サーバーだけでは P2P ファイル共有ネットワークにはならない
- 当時でも ISP が安定した固定 IP を提供しないことは多かった
- 今日共有した IP アドレスが明日には変わっていることもあった
http://74.6.231.21:4000のような任意の URL は検索エンジンに索引されていなかった可能性が高く、ノートPCを閉じればオフラインになった
- Gnutella クライアントは HTTP サーバーと並行して TCP ベースのゴシッププロトコル を実行した
- 他の Gnutella 参加者に対し、共有ディレクトリを HTTP で提供するピアのメッシュの中で自らの存在を知らせる
- ピアのアドレス、帯域幅、遅延、検索クエリのような情報がメッシュ内を移動する
- ファイアウォールに対処する手段もあったが、現代の NAT 問題を解決するには後の拡張が必要だった
- Gnutella ノードの基本的な役割は3つある
- ローカル HTTP サーバーで望む相手にファイルを転送する
- ゴシップメッセージを通じて利用可能なファイルを検索し、通知する
- 必要に応じてファイアウォール回避のための技法を用いる
- Gnutella には中央の入口やユーザー登録簿がないため、いったんメッシュに入れば新しいピア、流入する検索クエリ、そのほかのネットワークトラフィックを見つけられる
ブートストラップ
- ブートストラップ とは、招待もなく正面玄関もない P2P メッシュへ最初に入るために、いくつかの初期ピアを見つけるプロセスである
- Gnutella のグローバルネットワークは参加者の IP アドレスの混成体であり、メインネットワークにつながっている信頼できるピア1つに接続するだけで、多数のユーザー集合によるネットワークトラフィックが見え始める
- 時間が経つにつれて PONG メッセージ経由でより多くのピアが見つかり、ピア一覧は再接続のためにディスクへ保存される
- IP アドレスの変更やオフライン状態のため、保存されたピア一覧は時間とともに一部が無効になり、クライアントは有効なピアが見つかるまで一覧をたどって試行する
- 初めてネットワークに参加する場合や、長期間接続していなかったあとに戻る場合には、保存済み一覧だけでは十分でないことがあり、ブートストラップが必要になる
- 最も一般的な方法は Gnutella Web Cache (GWebCache) である
- ボランティアが運営する独立した Web サーバー群の連合であり、通常は CGI や PHP スクリプトの形をした小さな Web アプリケーションである
- 自発的に情報を提供した Gnutella 参加者の IP アドレスを記録する
- 現在のサーバーが停止した場合に備えて、他の GWebCache サーバーの IP やドメインを記録する
- 代替となる GWebCache サーバーの一覧を提供する
- 現在把握されている Gnutella ネットワーク参加者の IP アドレス一覧を提供する
- 一部の Gnutella クライアントはキャッシュサーバーに自動接続し、別のクライアントでは IP を設定ファイルや設定メニューにコピーして貼り付ける必要がある
- 初期ピアに接続した後は、ネットワークメッセージの内部でより多くのピアを間接的に集められるため、キャッシュへの依存度は下がる
- GWebCache は 中央ボトルネック ではない
- 互いに無関係な GWebCache サーバーが複数存在する
- GWebCache なしでクライアントをブートストラップする方法も複数ある
- GWebCache がなくても Gnutella は利便性の低い形ながら生き延びられる
- ブートストラップ一覧のリクエスト例は次の通り
- URL の末尾に
?get=1&client=TEST&version=1を付けると一覧を取得できるが、あまりに多くリクエストするとすぐにレート制限される
- URL の末尾に
http://cache.jayl.de/g2/gwc.php
http://gweb.4octets.co.uk/skulls.php
http://midian.jayl.de/g2/bazooka.php
http://p2p.findclan.net/skulls.php
http://skulls.gwc.dyslexicfish.net/skulls.php
- 出力例は次の通り
H|106.107.193.27:23459|88579
H|182.233.59.26:23464|88581
U|http://bj.ddns.net/skulls/skulls.php|208999
U|http://scissors.gwc.dyslexicfish.net:3709/|341201
Hで始まる項目はピアで、Uで始まる項目は後で使える重複キャッシュサーバーである
主要メッセージ型
- Gnutella は TCP ベースのプロトコル であり、インバウンド接続を受けるピアに接続すると、まずハンドシェイクが行われる
- クライアントは
GNUTELLA CONNECT/0.4またはGNUTELLA CONNECT/0.6を送り、相手が肯定応答を返すと接続が確立され、バイナリの Gnutella メッセージが流れ始める - すべてのバイナリメッセージは 23バイトのヘッダ で始まる
- ヘッダにはメッセージ ID、ペイロード型、TTL、ホップ数、ペイロード長が含まれる
- TTL はメッセージの残り寿命で、ホップ数はすでに移動した距離である
TTL + Hopsはメッセージが本来意図していた到達範囲を表す
- 実質的な中核メッセージは5種類である
- PING: 生きているピアを探索する。ペイロード型
0x00 - PONG: PING への応答であり、IP アドレス、ポート、共有統計を含む。ペイロード型
0x01 - QUERY: ユーザーまたは近隣ピアが開始した検索要求である。ペイロード型
0x80 - QUERYHIT: QUERY への肯定応答であり、ファイル結果レコードとダウンロード用の接続情報を含む。ペイロード型
0x81 - PUSH: ファイアウォールの背後にいるアップローダー向けの回避策であり、ファイル保有者に対してダウンローダー側へ再接続するよう求める。ペイロード型
0x40
- PING: 生きているピアを探索する。ペイロード型
BYEメッセージもあるが、厳密には必須ではない- プロトコルメッセージは 拡張データフィールド をサポートしており、クライアントはネットワーク全体を壊さずに機能を追加できる
- GTK-Gnutella は小さな中核プロトコルにはなかった TLS、IPv6、UDP などの機能をサポートしている
プロトコル拡張
- 5つのメッセージ型だけを実装しても動作する Gnutella クライアントを作れる可能性はあるが、仕様はほぼ30年前のものであり、エコシステムは止まっていない
- Gnutella は古いパケットの中に新しいアイデアを入れられる余地を残していた
- GGEP (Gnutella Generic Extension Protocol) は、通常メッセージ内に拡張データを入れるための汎用的な空間を提供する
- HUGE (Hash/URN Gnutella Extensions) は、クライアントがファイル名だけでなく SHA ハッシュでもファイルを識別できるようにする
- XML 拡張ペイロードのサポートについても言及されているが、仕様ではそれを過去のものとして扱っており、現代のネットワークトラフィックでは観測されていない
- 元の設計は小規模だったが、成長し続けられるだけの柔軟性を備えていた
検索と転送の仕組み
- PING/PONG メッセージはノード間を行き来する心拍の役割を果たす
- PING には通常の23バイトヘッダ以外に必須ペイロードはないが、任意の GGEP 拡張データを含められる
- PONG には応答した servent のポート、IPv4 アドレス、共有ファイル数、共有キロバイト数が含まれる
- ノードは PONG に付随する IP/ポート情報を集めてメッシュ内でより接続性の高いメンバーとなり、その情報を後続セッションのために保存する
- QUERY/QUERYHIT は PING/PONG と似たように動作するが、ピア告知ではなく検索トラフィックを運ぶ
- QUERY は最低速度、すなわち転送帯域幅フィールドを含み、その後ろに NUL 終端の検索文字列が続く
- 例:
beethoven.mp3 - QUERY メッセージは送信元から外側へ洪水のように広がり、QUERYHIT メッセージは結果がある場合に送信元へ戻ってくる
- QUERYHIT には応答者の IP アドレス、ポート、速度、結果セットが含まれる
- 各結果にはファイルインデックス、ファイルサイズ、ファイル名、任意のメタデータや拡張が含まれる
- ファイルインデックスは後で HTTP 経由でファイルを要求する際に使われる
- Gnutella の フラッディングルーティング の性質により、結果の到着は遅く、完了まで数分かかることもあった
- LimeWire のエンジニアたちは、これをよりスケーラブルに処理するために動的クエリルーティングを考案した
- ブルームフィルタと賢いネットワークトポロジーを活用した
- この高度な構成により、フラッディングルーティングの問題なしに数百万ユーザー規模へ拡張できた
- 今日でも大半の主流クライアントがこのシステムを実装している
PUSH とファイアウォール
- PUSH メッセージは、一部の HTTP サーバーがファイアウォールを越えられるよう助ける回避策だが、すべてのケースを解決するわけではない
- 通常の HTTP のようにクライアントがサーバーへ接続する代わりに、サーバーへクライアント側へ接続してもらうよう依頼する方式に近い
- PUSH メッセージには、アップローダーがダウンローダーを見つけるために必要な servent 識別子やその他の識別子が含まれる
- クライアントが直接接続できないため、相手に折り返し接続してファイルを送ってもらうよう依頼する形である
- 詳細は Gnutella 仕様 を参照
- 現代のクライアントは、この問題をより自然に扱うために追加の手法や UDP 拡張を利用している
残された意味と参考資料
- Gnutella は優れた初期設計により、数百万の同時ユーザーへ拡張し、遮断を回避し、外部の助けなしに数十年オンライン状態を保ってきた
- 実トラフィックが流れた途端に崩壊したネットワークではなく、Y2K 文化の一部だったネットワークが今なお消えていないという事実は、その設計の堅牢さを示している
- Gnutella がかすんでいった本当の理由は、それを生み出した世界より長く生き残ったからだ、という結論に近い
- ネットワーク自体は、プロトコル関連資料をホストしていたサイト群よりも長く生き延びた
-
参考リンク
- GTK-Gnutella GitHub - 2020年代に実際に Gnutella を使いたい場合に使うクライアントであり、リードメンテナーは Gnutella 0.6 仕様の策定に参加し、今も活動している
- Gnutella Bun Client GitHub - TypeScript/Bun で書かれた趣味的な Gnutella クライアント実装で、実際に動作し、GTK-Gnutella とおおむね互換性があるが完全ではない
- Gnutella Terminology Glossary - QRP、GGEP、GIV など Gnutella 用語と関連概念を扱う用語集
- Gnutella Forums - Gnutella クライアント、トラブルシューティング、ネットワーク議論のための古いフォーラムで、2026年時点ではあまり活発ではない
- Cap’n Bry’s Gnutella Site - 古い Gnutella ファンページ
- Annotated Gnutella Protocol Specification v0.4 - 原文および注釈付きの Gnutella 0.4 プロトコル仕様
- Gnutella Protocol 0.6 Draft - 後続の Gnutella 0.6 プロトコルドラフト仕様
- Query Routing Protocol Spec - 無駄なフラッディングを減らす Gnutella のクエリルーティングシステム QRP の仕様で、図は失われている
1件のコメント
Lobste.rsの意見
Gnutellaは、検索語に合うファイルをダウンロードして、たいていはMP3を手軽に大量に手に入れられるものとして記憶しているが、その「別のもの」もあった
懐かしさを呼び起こしてくれてうれしいし、今のウェブが怪物になってしまったのは残念だ
2000年代半ばの大学の寮はフラットなネットワークで、iTunesがとても人気だったが、ネットワーク上の誰にでも音楽を共有していた
Circuit Cityで買った新品の64ビットHPノートPCを1週間でEvanescenceとGreen Dayでいっぱいにして、Columbia House CD Clubはもう必要ないように感じた
卒業から数年後、誰かがまずい相手の前でその話を持ち出したことで、ITが公式に知ることになり、結局閉鎖しなければならなくなった
後になって気づいたが、大学ネットワークの上に作ったファイル共有ノードの「フラットなネットワーク」ではなく、ネットワーク自体がフラットだったという意味だったのだ
それでも大学時代は、こういうことをやるには楽しい時期だった
Soulseekは今でもかなり生きていて、ちゃんと動いている
Gnutellaでいちばんおかしいのは、GNUプロジェクトとは何の関係もないのに、ただGNUがかっこよく見えたから名前に入れたという点だ
Gnutellaの中核技術を、より新しいsmall-webやGeminiに近いコンテンツ発見にどれだけ再利用できるのか、よく気になる
「失敗した」という言い方は不完全だ。一般に成功か失敗かするのではなく、ある目標に照らして成功したり失敗したりするだけだ
Gnutellaユーザーがもはや存在しなくなったことには、大きく2つの理由があり、どちらも失敗と見なせる
第一に、Gnutellaとその各種ソフトウェアは、ユーザーのプライバシー保護を十分に行えず、現実上・認識上のリスクにさらしていた
第二に、メディアファイル配布システムとしては非常に優れていたが、大半のユーザーを満足させる品質と価格のバランスを提供できなかった。ユーザーが求めていた無制限アクセスは与えたが、本物のコンテンツだという保証はできず、Spotifyはその両方を提供した
そういう意味では、Gnutellaユーザーは今も存在しているが、今は別のものを使っている
*.gmiファイルのアーカイブを作り、Gnutella拡張で検索可能にすること、そして人々がgemtext文書に署名して公開できるポインタシステムを考えていた新しいアイデアそのものではないが、Gemtext + Gnutella配布の組み合わせは新しく見える: https://github.com/RickCarlino/gnutella-bun-client/…
この記事はGPT-5.4とのやり取りでブレインストーミングした結果を後のために埋めておいたもので、まだ共有するつもりはなかったので、その点は注意して見てほしい
Gemini + Gnutella領域でどんな考えがあるのか聞いてみたいし、Linkedin、Reddit、Fediverseなどで見つけやすく、ブログにも連絡先がある
OnionShareもかなり面白い: https://onionshare.org/
DaRkWeBの一部になれるかもしれない
文書を見る限り、直接接続のファイル転送ツールに近そうだ
Gnutellaが当時の条件で長く生き残った理由の1つとして、P2P検索スパムを行う実質的な動機があまりなかった点が抜けている気がする
その後、P2P検索スパムは実際に発生した
最近IRCにスパムがほとんどないのも、似たような理由に見える
プロトコルの多くの部分がクライアントを信頼している点が興味深い
GUIDはランダムであるべきだが、ユーザーが制御できるので、全員がGUIDを
0000に設定することもできる。現代的にGnutellaを作り直すなら、複雑な鍵交換システムとED25519鍵ベースのIDを入れる可能性が高い広告しているファイル数や帯域幅なども、実質的にはユーザーが真実を言っていると信じる構造だ。もっと複雑なプロトコルなら、こうした主張を実際に検証しようとしたかもしれない
鍵署名や評判管理を多く入れていたら実装が複雑になりすぎた可能性があり、むしろ単純さこそが成功理由だったのかもしれない。Gnutellaクライアントは実際に作れる
多くの現代P2Pプロジェクトはこの点を見落としていると思う。好きなプロジェクトであるSecure Scuttlebuttも、さまざまな失敗や悪用事例を考慮してほとんど完璧なものを作ろうとした結果、結局動くクライアントが仕様策定者の作った1つしかない生態系になってしまった印象がある
同じ例は
gemini://にも当てはまる。P2Pではなく連合型プロトコルだが、仕様に問題や穴が多くても、結局人々は実際にクライアントを作り、問題があるにもかかわらず生態系にはかなり多様な実装があるGnutellaがその時点で盛り上がった背景には、Berkeley XCFのメンバーだったGene KanとSpencer Kimballの役割が大きかった
Spencerはその後Googleで優れたエンジニアリングの仕事を数多く行い、今はデータベース企業Cockroach LabsのCEOだ
Geneは検索企業をSunに売却して早くに成功したが、残念なことに2002年、あまりに若くして悲劇的にこの世を去った