本プロトコルは、P2P地震情報のプラグインとして会話機能を提供することを目的として制作したものです。
TCP/IPを使用します。「サーバ」との通信は5910ポート、「ピア」との通信は5911ポート等(特に制限はない)を使用します。
通信にはShift-JISエンコードを使用し、以下の2つの形式に従います。基本的に前者の形式を使用し、データがない場合に限り後者を使用することができます。データが複数ある場合は、原則として「:(半角コロン)」で区切ります。
3桁の数字(コード) + 半角スペース + 経由数
+ 半角スペース + データ + 改行(CRLF)
3桁の数字(コード) + 半角スペース + 経由数
+ 改行(CRLF)
「経由数」は、発信元からデータを受信するまでに経由したピアの数です。サーバーとの通信では「1」を使用します。ピアとの通信では、発信する場合は「1」を使用し、受信したデータを他のピアへ伝達する時は1増やして伝達しなければなりません。また、無限ループを防ぐため、経由数が総参加ピア数の10分の1を超える場合、データをそれ以上他のピアに伝達してはいけません。
本プロトコルでは、公開鍵暗号(PKCS #1 v1.5に準拠したRSASSA、ハッシュアルゴリズムはSHA-1)を使用しています。
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: -未解析-
本プロトコルでは、ネットワーク内のピアが統一した時刻を持つため「プロトコル時刻」を定めています。本プロトコル仕様書で示す日時は、すべてプロトコル時刻によるものです。許容される誤差はプラスマイナス1秒未満です。
「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 | ピアエコーを要求します。 データ:不要 |
612 | ピアIDを要求します。 データ:不要 |
614 | ピア対応プロトコルバージョン、ソフトウェア名・ソフトウェアバージョンを要求します。 データ:プロトコルバージョン、ソフトウェア名、バージョン |
631 | ([611]に対し)ピアエコーを返します。 データ:不要 |
632 | ([612]に対し)ピアIDを返します。 データ:ピアID |
634 | ([614]に対し)ピア対応プロトコルバージョン、ソフトウェア名・ソフトウェアバージョンを返します。 データ:プロトコルバージョン、ソフトウェア名、バージョン |
698 | 処理の流れがプロトコル仕様に準拠していません。 データ:なし 対処:プログラムがプロトコル仕様に準拠するよう修正します。 |
「地域コード」は3ケタの数値です。地域の区切りは、震度速報で用いられる地域区分(計186)を少しおおまかにしたものです(計138、未設定など含め計141)。なお、今後変更される可能性がありますので、変更に対応しやすい実装を行うことを推奨します。
※この項はあくまで実装の参考例を記すもので、定められた仕様ではありません。
サーバへの接続に連続して失敗する場合、独立してネットワークへの参加を試行することができます。
独立してネットワークへの参加を試行するなどした場合、署名などの割り当てがされません。よって、以下のように対処します。
また、サーバへの接続に数時間以上失敗する場合は、受信するデータについて署名の検証を省略するなどし、署名または鍵を取得できなかったピアのデータを受信するようにします。
サーバは「p2pquake.ddo.jp」、ポートは「5910」です。タイムアウト等で接続出来なかった場合は、時間をおいてやり直してください。なお、タイムアウトまでの時間は2〜3秒と短くても構いません。
注意:同一IPアドレスから2セッション目の接続を確立しようとした場合や、接続から60秒が経過した場合、サーバーから接続が切断されることがあります。
サーバーへの接続が完了した後、サーバーからコード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(エラー:バージョンが古い)を送信し、別のサーバーとの接続を試みてください。
ピア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)であれば失敗です。
次に、ピアとの接続を行うために、ピアデータを取得します。コード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です。
ピアとの接続が完了した場合、暫定的に割り当てられていたピア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ネットワーク参加中の「サーバーへのエコー」時に鍵の再割り当てを試み、割り当てが行われるまでは、「鍵がない(未署名)」状態で地震感知情報・伝言板メッセージを送信することになります。
鍵やデータの有効期限をチェックする際に必要な「プロトコル時刻」を取得します。コードは118です。サーバーからは、コード238が返ります。
↑ 118 1
↓ 238 1 2005/03/19 12-34-56
時刻フォーマットは「YYYY/MM/DD HH-MM-SS」です。原則として、日本標準時とほぼ同じです。
ここまでの処理が正常に行われた場合、P2Pネットワークへの参加処理は完了しました。コード119(通信終了要求)を送信し、サーバーからコード239(通信終了)が返れば、サーバーとの接続を切断してください。
↑ 119 1
↓ 239 1
「P2Pネットワークへの参加 - 1.サーバーへの接続」と同様
「P2Pネットワークへの参加 - 2.プロトコルバージョン等の通知」と同様
エコーは、コード123です。データには、ピアIDと現在のピアとの接続数をを指定します。成功すると、コード243(エコーOK)が返ります。データは、現在の参加ピア総数です。
↑ 123 1 25:3
↓ 243 1 29
(↓ 299 1 IP_Address_has_been_changed)
エコー時のIPアドレスが参加時と変わっている場合、コード299が返されることがあります。この場合、一旦ネットワークから切断し、参加しなおしてください。
鍵の有効期限が切れる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が返ります。この場合、次回エコー時に再び割り当てを試みてください。
「P2Pネットワークへの参加 - 4.ピアデータの取得・ピアとの接続」と同様
ただし、既に接続済みのピアと複数のセッションを確立することのないよう、ID・IPアドレスが重複していないかチェックする必要があります。
また、コード155による接続ピアID通知には、新たに接続したピアのIDのみを通知します。
「P2Pネットワークへの参加 - 7.プロトコル時刻の取得」と同様
「P2Pネットワークへの参加 - 8.サーバーとの接続終了」と同様に、コード119を送信し、コード239が返れば接続を切断します。
全てのピアとの接続を切断してください。
「P2Pネットワークへの参加 - 1.サーバーへの接続」と同様
「P2Pネットワークへの参加 - 2.プロトコルバージョン等の通知」と同様
参加終了は、コード128で行います。データは、ピアID、以前割り当てた秘密鍵(のBASE64エンコード)です(鍵が割り当てられていない場合は「Unknown」)。正常に完了すれば、コード248が返ります。
↑ 128 1 25:ABCDEFG
↓ 248 1
鍵が正しくない場合はコード293(要求が正しくない)、IPアドレスが参加時と異なっている場合はコード299(IPアドレスが一致しない)が返ります。この場合、どうすることも出来ないので、そのまま次のステップに進んでください。
「P2Pネットワークへの参加 - 8.サーバーとの接続終了」と同様に、コード119を送信し、コード239が返れば接続を切断します。
ポートを開放している場合、他ピアからの接続を受け付けることがあります。接続数が限界ではない限り、速やかに接続を受け入れてください。
受け入れた後、接続先のIPアドレスを調べた上で、他に接続しているピアとIPアドレスが重複していないか確認してください。重複していた場合、受け入れた接続を切断してください。これは、同一ピアと2セッション接続してしまうことを防ぐためです。
接続が確立したとき、初期通信を行わなければなりません。また、初期通信が完了するまではいかなるデータ伝達(500番台)も行ってはなりません。
初期通信は、接続を受け付けた側から始まります。プロトコルバージョンとピアIDをやり取りします。
まず、コード614(バージョン要求)でプロトコルバージョンを要求します(データには自分自身のバージョン情報を含みます)。コード634(バージョン返答)が返ります。
↑ 614 1 0.20:PRCP_Client:Beta1_Rev1001
↓ 634 1 0.21:PRCP_Client:Beta1_Rev1003
(↓ 694 1 Protocol_version_incompatible)
相手プロトコルバージョンが古い場合、コード694を返し、接続を切断します。こちらのプロトコルバージョンが古い場合は、コード694が返され切断されます。
次に、ピアIDを把握するために、コード612(ピアID要求)でピアIDを要求します。ピアからは、コード632(ピアID返答)が返ります。データはピアIDです。
↑ 612 1
↓ 632 1 26
コード632が返りピアIDが判明した場合、接続中のピアとピアIDが重複していないか確認し、重複していた場合はどちらかの接続を切断しなければなりません。これは、同一ピアと2セッション接続してしまうことを防ぐためです。
ピアとの接続が切断していないかチェックするために、2〜5分程度の間隔で接続中のピアにコード611(ピアエコー要求)を送信することができます。接続が正常であれば、相手からはコード631(ピアエコー返答)が返ります。
↑ 611 1
↓ 631 1
10〜30秒以内に相手から応答が返らない場合や、ソケット状態が「エラー」となっている場合は、ピアとの接続を切断してください。
本プロトコルでは、複数のピアと接続していることから、複数のピアから同一の通信データを受信することが当たり前のようにあります。そのため、同一の通信データかどうかを判断し、同一「ではない」場合にのみ処理を行う必要があります。
そして、同一「ではない」と判断された場合、署名やその他を検証する前に、速やかにデータを送ってきたピア「以外」の他ピアへ情報を伝達する必要があります(※その際、「基本概要 - 2.基本仕様」に記されているよう、経由数を1プラスする必要があります)。
また、ピアからピアへのデータ伝達における伝達コード「550番台(550-559)」「560番台(560-569)」については、本仕様書に掲載されていない数字(コード)であっても伝達を必須とします。これは、今後新しい情報を配信するためにコードが追加された場合、古いバージョンがネットワーク上に存在していてもデータの伝達が途切れないようにするためです。
会話は、メッセージのやり取りに使われるものです。コード「551」で、様々なデータを指定します。
↑ 551 1 2007/10/13 12-34-56:QWERTY:901:2007/10/13 23-45-12:ABCDEFGHIJKLMN:FREETALK,901,ぬるぽ!
データは「データ署名」「有効期限」「公開鍵」「鍵署名」「鍵期限」「会話データ」に分かれています。さらに、「会話データ」はコロン区切りで「チャンネル名」「地域コード」「発言」に分かれています。