Peer-to-peer Relay Chat Protocol(PRCP) プロトコル仕様

目次

基本概要
0.注意事項・連絡先
1.バージョン
2.基本仕様
3.公開鍵暗号への対応
4.「プロトコル時刻」
5.「3桁の数字(コード)」一覧表
6.「地域コード」
半ピュアP2Pとしての実装
1.ピアとの接続
2.データの扱い
P2Pネットワークへの参加
1.サーバーへの接続
2.プロトコルバージョン等の通知
3.ピアIDの暫定割り当て・ポート開放のチェック
4.ピアデータの取得・ピアとの接続
5.ピアIDの本割り当て・鍵の取得 (Ver0.20変更)
6.プロトコル時刻の取得
7.サーバーとの接続終了
サーバーへの定期エコー
1.サーバーへの接続
2.プロトコルバージョン等の通知
3.エコー (Ver0.20変更)
4.鍵の再割り当て要求 (Ver0.20変更)
5.ピアとの接続数増加
6.プロトコル時刻の再取得
7.サーバーとの接続終了
P2Pネットワークへの参加終了
1.ピアとの接続終了
2.サーバーへの接続
3.プロトコルバージョン等の通知
4.参加終了
5.サーバーとの接続終了
ピアとのシステム通信
1.接続の受け付け
2.ピア同士のエコー
ピアとのデータ通信
1.重複判定・各ピアへの伝達
2.会話の伝達 (Ver0.20変更)
3.会話の署名確認 (Ver0.20廃止)

基本概要

 本プロトコルは、P2P地震情報のプラグインとして会話機能を提供することを目的として制作したものです。

目次へ

0.注意事項・連絡先

目次へ

1.バージョン

Ver0.20(2007/12/09改訂)
・従来のバージョンと互換性がありません。
・鍵の取得・再割り当てのデータを変更しました。
・会話の署名方法について、「伝達データの署名を確認する」のみに変更し、使用するデータについても変更しました。
・会話の伝達における「チャンネル名」の定義、「チャンネル名」「発言」の置き換えについて追加しました。
・会話の伝達における「会話データ」のデータを変更しました。
・エコー時に現在の参加ピア総数を返すようデータを変更しました。
Ver0.10(2007/10/13作成)
・初版作成。

目次へ

2.基本仕様

 TCP/IPを使用します。「サーバ」との通信は5910ポート、「ピア」との通信は5911ポート等(特に制限はない)を使用します。

 通信にはShift-JISエンコードを使用し、以下の2つの形式に従います。基本的に前者の形式を使用し、データがない場合に限り後者を使用することができます。データが複数ある場合は、原則として「:(半角コロン)」で区切ります。

3桁の数字(コード) + 半角スペース + 経由数 + 半角スペース + データ + 改行(CRLF)
3桁の数字(コード) + 半角スペース + 経由数 + 改行(CRLF)

 「経由数」は、発信元からデータを受信するまでに経由したピアの数です。サーバーとの通信では「1」を使用します。ピアとの通信では、発信する場合は「1」を使用し、受信したデータを他のピアへ伝達する時は1増やして伝達しなければなりません。また、無限ループを防ぐため、経由数が総参加ピア数の10分の1を超える場合、データをそれ以上他のピアに伝達してはいけません。

目次へ

3.公開鍵暗号への対応

 本プロトコルでは、公開鍵暗号(PKCS #1 v1.5に準拠したRSASSA、ハッシュアルゴリズムはSHA-1)を使用しています。

保証用公開鍵 (1024bit)
 ピアに割り当てた鍵に対し、サーバが行った署名を検証するときに必要になります。

HEX
30819D300D06092A864886F70D010101050003818B0030818702818100C9CE5DF978889C
24C9BEC26EA3933B12430C20FBED9ACDE23BE067165443AFA2C5132CD6273F4DBF2DC33A
1C6F9086C08CBDCFA235964B4BB306FE64E0BF48AFFFADC36FEBFC5DDADBC381176F161E
CE83147D55CB85A433A54DF6B5EA3EE4DCDE3E6102374C43E789C36EC6310477EE4BF9FF
5ACF0304313FF43FD216FDB897020111

BASE64
MIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQDJzl35eIicJMm+wm6jkzsSQwwg++2azeI7
4GcWVEOvosUTLNYnP02/LcM6HG+QhsCMvc+iNZZLS7MG/mTgv0iv/63Db+v8Xdrbw4EXbxYe
zoMUfVXLhaQzpU32teo+5NzePmECN0xD54nDbsYxBHfuS/n/Ws8DBDE/9D/SFv24lwIBEQ==

RSA Parameters - サーバー保証用公開鍵パラメータ

modulus(n): -未解析-

e: -未解析-

目次へ

4.「プロトコル時刻」

 本プロトコルでは、ネットワーク内のピアが統一した時刻を持つため「プロトコル時刻」を定めています。本プロトコル仕様書で示す日時は、すべてプロトコル時刻によるものです。許容される誤差はプラスマイナス1秒未満です。

目次へ

5.「3桁の数字(コード)」一覧表

 「x1x」「x2x」は「要求」、「x3x」「x4x」は「返答」、「x5x」「x6x」は「伝達・発信」、「x9x」は「エラー」となっています。

 注意:下記で「データ:不要」「データ:なし」と記されているのは、プロトコルにおける「データ」部分で何も指定(解析)する必要がないという意味です。逆に言えば、データに何を指定しても構いません。

ピアからサーバーへ(100番台)
113 ピアIDの暫定割り当てを要求します。
 データ:不要
114 ポート開放のチェックを要求します。
 データ:ピアID、ポート番号
115 参加中のピアデータを要求します。
 データ:ピアID
116 ピアIDの本割り当てを要求します。
 データ:ピアID、ポート番号、地域コード、接続数、最大接続数
117 鍵の割り当てを要求します。
 データ:ピアID
118 基準となるプロトコル時刻を要求します。
 データ:なし
119 通信の終了を要求します。
 データ:不要
123 エコー日時更新を要求します。
 データ:ピアID、接続数
124 鍵の再割り当てを要求します。
 データ:ピアID、以前割り当てた秘密鍵
128 参加終了を要求します。
 データ:ピアID、以前割り当てた秘密鍵
131 ([211]に対し)対応プロトコルバージョン、ソフトウェア名・ソフトウェアバージョンを返します。
 データ:プロトコルバージョン、ソフトウェア名、バージョン
192 サーバーの対応プロトコルバージョンが古く、互換性がありません。
 データ:不要
サーバーからピアへ(200番台)
211 ピアの対応プロトコルバージョン、ソフトウェア名・ソフトウェアバージョンを要求します。
 データ:なし
232 ([131]に対し)対応プロトコルバージョン、ソフトウェア名・ソフトウェアバージョンを返します。
 データ:プロトコルバージョン、ソフトウェア名、バージョン
233 ([113]に対し)ピアIDを暫定的に割り当てます。割り当てたピアIDを返します。
 データ:割り当てたピアID
234 ([114]に対し)ポート開放のチェック結果を返します。
 データ:結果(成功:1、失敗:0)
235 ([115]に対し)参加中のピアデータを返します。
 データ:「IPアドレス,ポート,ピアID:IPアドレス,ポート,ピアID...」
236 ([116]に対し)ピアIDの本割り当てを行います。
 データ:現在の参加ピア総数
237 ([117]に対し)鍵の割り当てを行います。
 データ:秘密鍵、公開鍵、有効期限、鍵の署名
238 ([118]に対し)基準となるプロトコル時刻を返します。
 データ:プロトコル時刻
239 ([119]に対し)通信の終了を受け入れます。
 データ:なし
243 ([123]に対し)エコー日時更新を受け入れます。
 データ:なし
244 ([124]に対し)鍵の再割り当てを行います。
 データ:秘密鍵、公開鍵、有効期限、鍵の署名
248 ([128]に対し)参加終了を受け入れます。
 データ:なし
291 原因不明のエラーが発生しました。
 データ:なし 対処:処理を中止します。
292 ([131]に対し)ピアの対応プロトコルバージョンが古く、互換性がありません。
 データ:なし 対処:ユーザーにその旨を伝え、P2Pネットワークへの参加を中止します。
293 要求が正しくありません。
 データ:なし 対処:処理を中止します。
294 サーバーが過負荷状態にあるか、またはメンテナンス中です。
 データ:なし 対処:処理を中止します。
295 ([117][124]に対し)鍵は既に割り当て済みです。
 データ:なし 対処:(鍵がない・期限が切れている場合)次回サーバーへのエコー時に再割り当てを要求します。
298 処理の流れがプロトコル仕様に準拠していません。
 データ:なし 対処:プログラムがプロトコル仕様に準拠するよう修正します。
299 IPアドレスが違います。
 データ:なし 対処:一旦ネットワークから切断し、参加しなおします。
ピアからピアへ(データ伝達は500番台、システム通信は600番台)
550 ※配信内容は定義されていませんが、伝達は必須です。
551 会話を伝達します。
 データ:データ署名、有効期限、公開鍵、鍵署名、鍵期限、会話データ
553

569
※配信内容は定義されていませんが、伝達は必須です。
611 ピアエコーを要求します。
 データ:不要
631 ([611]に対し)ピアエコーを返します。
 データ:不要
698 処理の流れがプロトコル仕様に準拠していません。
 データ:なし 対処:プログラムがプロトコル仕様に準拠するよう修正します。

目次へ

6.「地域コード」

 「地域コード」は3ケタの数値です。地域の区切りは、震度速報で用いられる地域区分(計186)を少しおおまかにしたものです(計138、未設定など含め計141)。なお、今後変更される可能性がありますので、変更に対応しやすい実装を行うことを推奨します。

p2pqb3_area.def - 地域コード 定義ファイル(2006/03/14)
 「地域コード」「地域名」「都道府県名」「地方名」をカンマ区切り(CSV方式)で定義しています。「地域名」及び「都道府県名」は必須ではないため、実装で不要な場合は省いても構いません。

目次へ

半ピュアP2Pとしての実装

 ※この項はあくまで実装の参考例を記すもので、定められた仕様ではありません。

目次へ

1.ピアとの接続

 サーバへの接続に連続して失敗する場合、独立してネットワークへの参加を試行することができます。

目次へ

2.データの扱い

 独立してネットワークへの参加を試行するなどした場合、署名などの割り当てがされません。よって、以下のように対処します。

 また、サーバへの接続に数時間以上失敗する場合は、受信するデータについて署名の検証を省略するなどし、署名または鍵を取得できなかったピアのデータを受信するようにします。

目次へ

P2Pネットワークへの参加

目次へ

1.サーバーへの接続

 サーバは「p2pquake.ddo.jp」、ポートは「5910」です。タイムアウト等で接続出来なかった場合は、時間をおいてやり直してください。なお、タイムアウトまでの時間は2〜3秒と短くても構いません。

 注意:同一IPアドレスから2セッション目の接続を確立しようとした場合や、接続から60秒が経過した場合、サーバーから接続が切断されることがあります。

目次へ

2.プロトコルバージョン等の通知

 サーバーへの接続が完了した後、サーバーからコード211(対応プロトコルバージョン等の要求)が送られてきます。これに対しては、コード131(対応プロトコルバージョン等の返答)にて応答します。

 データは「対応プロトコルバージョン」「ソフトウェア名」「ソフトウェアバージョン」の3つです。プロトコルバージョンは「x.xx(例:0.20)」の形式である必要がありますが、ソフトウェア名・ソフトウェアバージョンの表記は自由です。

↓ 211 1
↑ 131 1 0.10:P2PQ_PRCPPlugin:Beta4_Rev1000
↓ 212 1 0.10:PRCP_Server:Beta1_Rev1000
(↓ 292 1 Protocol_version_incompatible)
(↑ 192 1)

 問題がなければ、サーバーからコード212(対応プロトコルバージョン等の返答)が返ります。データ形式はコード131で送ったものと同じです。

 対応するプロトコルバージョンが古く互換性がない場合は、サーバーからコード292(エラー:バージョンが古い)が返されます。その場合は、その旨をユーザーに伝えてP2Pネットワークへの接続を中止する必要があります。逆に、もしサーバーの対応するプロトコルバージョンが古く互換性がない場合は、コード192(エラー:バージョンが古い)を送信し、別のサーバーとの接続を試みてください。

目次へ

3.ピアIDの暫定割り当て・ポート開放のチェック

 ピアIDとは、P2Pネットワークにおいてピアを識別するために使われるIDのことです。まず、サーバーから暫定的にピアIDを割り当ててもらう必要があります。コード113(ピアID暫定割り当て要求)を送信します。これに対しては、コード233(ピアID暫定割り当て)が返ります。データはピアIDです。

↑ 113 1
↓ 233 1 25

 次に、他ピアからの接続を受け付ける場合は、正しくポートが開放されているかチェックするために、受け付け用のポート(5911〜5915等、制限なし)でListenしてから、コード114(ポート開放チェック要求)を送信します。データはピアID、ポート番号です。

↑ 114 1 25:6911
↓ 234 1 1

 チェック結果は、コード234(ポート開放チェック返答)で返されます。データが1であれば成功、それ以外(0)であれば失敗です。

目次へ

4.ピアデータの取得・ピアとの接続

 次に、ピアとの接続を行うために、ピアデータを取得します。コード115(ピアデータの取得)を送信します。データはピアIDです。サーバーからは、コード235(ピアデータ)が返ります。

↑ 115 1 25
↓ 235 1 192.168.0.1,6911,15:192.168.0.2,6915,81:192.168.0.3,6913,66
↑ 155 1 15:66

 データは、ピアごとに「コロン区切り」です。さらに、ピアごとのIPアドレス・ポート番号・ピアIDが「カンマ区切り」となっています。これを元に、ピアに接続を試みます。

 3〜5ピアと接続したか、ピアデータを使い果たしたら、コード155(接続ピアID通知)を送信します。データは、接続したピアのIDです。

目次へ

5.ピアIDの本割り当て・鍵の取得

 ピアとの接続が完了した場合、暫定的に割り当てられていたピアIDの本割り当てを要求します。コード116(ピアIDの本割り当て要求)を送信します。データは、ピアID、ポート番号、地域コード、接続数、受け入れ可能な最大接続数です。

↑ 116 1 25:6911:901:2:6:5,8,3
↓ 236 1 29

 本割り当てが完了した場合、サーバーからコード236(ピアIDの本割り当て)が返ります。データは、現在の参加ピア総数です。

 この後、自らがP2Pネットワークへデータを発信する際に必要なRSA鍵や署名を取得します。コード117(鍵割り当ての要求)を送信します。データはピアIDです。鍵の割り当てが成功した場合、コード237(鍵割り当て)が返ります。データは、秘密鍵、公開鍵、有効期限、鍵の署名です。秘密鍵・公開鍵・鍵署名・発信署名はBASE64エンコードされています。有効期限は「YYYY/MM/DD HH-NN-SS」フォーマットです。

↑ 117 1 25
↓ 237 1 ABCDEFGHIJKLMNOPQRSTU:ABCDEFGHIJKLMN:2005/03/14 12-34-56:ABCDEFGHIJKLMN
(↓ 295 1 Key_has_allocated)

 同一IPアドレスから一定時間内に複数の鍵を取得しようとした場合などでは、コード295(エラー:鍵割り当て済み)が返ります。この場合、P2Pネットワーク参加中の「サーバーへのエコー」時に鍵の再割り当てを試み、割り当てが行われるまでは、「鍵がない(未署名)」状態で地震感知情報・伝言板メッセージを送信することになります。

目次へ

6.プロトコル時刻の取得

 鍵やデータの有効期限をチェックする際に必要な「プロトコル時刻」を取得します。コードは118です。サーバーからは、コード238が返ります。

↑ 118 1
↓ 238 1 2005/03/19 12-34-56

 時刻フォーマットは「YYYY/MM/DD HH-MM-SS」です。原則として、日本標準時とほぼ同じです。

目次へ

7.サーバーとの接続終了

 ここまでの処理が正常に行われた場合、P2Pネットワークへの参加処理は完了しました。コード119(通信終了要求)を送信し、サーバーからコード239(通信終了)が返れば、サーバーとの接続を切断してください。

↑ 119 1
↓ 239 1

目次へ

サーバーへの定期エコー

概要
 ピアが正常に動作していることを通知するため、サーバーに「エコー」する必要があります。
設定
 エコー間隔は10分以上でなければなりません。ただし、発信に必要な鍵が取得出来ていない、発信に必要な鍵の期限が切れている、接続しているピアの数が明らかに少ないといった場合に限り、10分を下回る(ただし1分以上)の間隔でも構いません。
 エコーが行われないまま30分以上経過すると、サーバーは「ピアがダウンした」と判断します。

目次へ

1.サーバーへの接続

 「P2Pネットワークへの参加 - 1.サーバーへの接続」と同様

目次へ

2.プロトコルバージョン等の通知

 「P2Pネットワークへの参加 - 2.プロトコルバージョン等の通知」と同様

目次へ

3.エコー

 エコーは、コード123です。データには、ピアIDと現在のピアとの接続数をを指定します。成功すると、コード243(エコーOK)が返ります。データは、現在の参加ピア総数です。

↑ 123 1 25:3
↓ 243 1 29
(↓ 299 1 IP_Address_has_been_changed)

 エコー時のIPアドレスが参加時と変わっている場合、コード299が返されることがあります。この場合、一旦ネットワークから切断し、参加しなおしてください。

目次へ

4.鍵の再割り当て要求

 鍵の有効期限が切れる30分前から、必要に応じてコード124(鍵の再割り当て要求)を行うことが出来ます。データには、ピアID、以前割り当てられた秘密鍵(のBASE64エンコード)を指定します。もし、参加時にコード295が返された等で以前割り当てられた秘密鍵がない場合、「Unknown」を指定します。

↑ 124 1 25:ABCDEFG
↓ 244 1 ABCDEFGHIJKLMNOPQRSTU:ABCDEFGHIJKLMN:2005/03/14 12-34-56:ABCDEFGHIJKLMN
(↓ 295 1 Key_has_allocated)

 鍵の再割り当てが成功すると、コード244が返ります。データは、秘密鍵、公開鍵、有効期限、鍵の署名です。詳細なフォーマットは「P2Pネットワークへの参加 - 5.ピアIDの本割り当て・鍵の取得」と同様です。同一IPアドレスから一定時間内に複数の鍵を取得しようとした場合などでは、コード295が返ります。この場合、次回エコー時に再び割り当てを試みてください。

目次へ

5.ピアとの接続数増加

 「P2Pネットワークへの参加 - 4.ピアデータの取得・ピアとの接続」と同様

 ただし、既に接続済みのピアと複数のセッションを確立することのないよう、ID・IPアドレスが重複していないかチェックする必要があります。

 また、コード155による接続ピアID通知には、新たに接続したピアのIDのみを通知します。

目次へ

6.プロトコル時刻の再取得

 「P2Pネットワークへの参加 - 7.プロトコル時刻の取得」と同様

目次へ

7.サーバーとの接続終了

 「P2Pネットワークへの参加 - 8.サーバーとの接続終了」と同様に、コード119を送信し、コード239が返れば接続を切断します。

目次へ

P2Pネットワークへの参加終了

目次へ

1.ピアとの接続終了

 全てのピアとの接続を切断してください。

目次へ

2.サーバーへの接続

 「P2Pネットワークへの参加 - 1.サーバーへの接続」と同様

目次へ

3.プロトコルバージョン等の通知

 「P2Pネットワークへの参加 - 2.プロトコルバージョン等の通知」と同様

目次へ

4.参加終了

 参加終了は、コード128で行います。データは、ピアID、以前割り当てた秘密鍵(のBASE64エンコード)です(鍵が割り当てられていない場合は「Unknown」)。正常に完了すれば、コード248が返ります。

↑ 128 1 25:ABCDEFG
↓ 248 1

 鍵が正しくない場合はコード293(要求が正しくない)、IPアドレスが参加時と異なっている場合はコード299(IPアドレスが一致しない)が返ります。この場合、どうすることも出来ないので、そのまま次のステップに進んでください。

目次へ

5.サーバーとの接続終了

 「P2Pネットワークへの参加 - 8.サーバーとの接続終了」と同様に、コード119を送信し、コード239が返れば接続を切断します。

目次へ

ピアとのシステム通信

目次へ

1.接続の受け付け

 ポートを開放している場合、他ピアからの接続を受け付けることがあります。接続数が限界ではない限り、速やかに接続を受け入れてください。

 受け入れた後、接続先のIPアドレスを調べた上で、他に接続しているピアとIPアドレスが重複していないか確認してください。重複していた場合、受け入れた接続を切断してください。これは、同一ピアと2セッション接続してしまうことを防ぐためです。

目次へ

2.ピア同士のエコー

 ピアとの接続が切断していないかチェックするために、2〜5分程度の間隔で接続中のピアにコード611(ピアエコー要求)を送信することができます。接続が正常であれば、相手からはコード631(ピアエコー返答)が返ります。

↑ 611 1
↓ 631 1

 10〜30秒以内に相手から応答が返らない場合や、ソケット状態が「エラー」となっている場合は、ピアとの接続を切断してください。

目次へ

ピアとのデータ通信

目次へ

1.重複判定・各ピアへの伝達

 本プロトコルでは、複数のピアと接続していることから、複数のピアから同一の通信データを受信することが当たり前のようにあります。そのため、同一の通信データかどうかを判断し、同一「ではない」場合にのみ処理を行う必要があります。

 そして、同一「ではない」と判断された場合、署名やその他を検証する前に、速やかにデータを送ってきたピア「以外」の他ピアへ情報を伝達する必要があります(※その際、「基本概要 - 2.基本仕様」に記されているよう、経由数を1プラスする必要があります)。

 また、ピアからピアへのデータ伝達における伝達コード「550番台(550-559)」「560番台(560-569)」については、本仕様書に掲載されていない数字(コード)であっても伝達を必須とします。これは、今後新しい情報を配信するためにコードが追加された場合、古いバージョンがネットワーク上に存在していてもデータの伝達が途切れないようにするためです。

目次へ

2.会話の伝達 (Ver0.20 変更)

 会話は、メッセージのやり取りに使われるものです。コード「551」で、様々なデータを指定します。

↑ 551 1 2007/10/13 12-34-56:QWERTY:901:2007/10/13 23-45-12:ABCDEFGHIJKLMN:FREETALK,901,ぬるぽ!

 データは「データ署名」「有効期限」「公開鍵」「鍵署名」「鍵期限」「会話データ」に分かれています。さらに、「会話データ」はコロン区切りで「チャンネル名」「地域コード」「発言」に分かれています。

チャンネル名
 多種多様な会話に対応するため、チャンネル名によって会話を振り分けます。本プロトコルのチャンネルには作成・削除の概念はなく、個々の利用者が自由にチャンネル名を指定することが許されます。
 ただし、オフィシャルでは「雑談」「地震津波」の2つのみをサポートします。
チャンネル名及び発言の置き換え
 チャンネル名及び発言は、データの誤分割及び誤認識を避けるため一部の文字を送受信時に置き換えなければなりません。
発信したいとき
  1. 「有効期限」を、プロトコル時刻からプラス1分にセットします。
  2. サーバから割り当てられた「秘密鍵」を使用し、署名します。署名の元となるデータは「有効期限」「会話データのMD5ハッシュ(ただしバイナリ)」の結合バイナリです。
  3. 署名結果を「データ署名」とし、サーバから割り当てられた「公開鍵」、割り当て時に付与された「鍵署名」をそれぞれセットします。このとき、これらはBASE64でエンコードしなければなりません。また、エンコード結果に含まれる改行は取り除かなければなりません。
  4. さらにサーバから割り当て時に付与された「鍵期限」をセットし、送信します。
受信したとき
 受信した会話が正しいかどうか、検証することを推奨します。
  1. 受信した「データ署名」「公開鍵」「鍵署名」をそれぞれデコードします。
  2. 「保証用公開鍵」を使用し、「鍵署名」が「公開鍵(バイナリ)」「鍵期限」の結合バイナリの署名であるか確認します。
  3. 「鍵期限」が切れていないかを確認します。この時点で、鍵は正規のものであると判定できます。
  4. 「公開鍵」を使用し、「データ署名」が「有効期限」「会話データのMD5ハッシュ(ただしバイナリ)」の結合バイナリの署名であるか確認します。
  5. 「有効期限」が切れていないかを確認します。これで、データは正規のものであると判定できます。
なお、これによって確認できることは「その鍵を使用して発信された」という1点のみです。

目次へ