X Version 11, Release 7.7
Version 1.1
Copyright © 1993, 1994 X Consortium
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of the X Consortium shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from the X Consortium.
X Window System is a trademark of The Open Group.
(訳)
(以下に定める条件に従い、本ソフトウェアおよび関連文書のファイル(以下「ソフトウェア」)の複製を取得するすべての人に対し、ソフトウェアを無制限に扱うことを無償で許可する。これには、ソフトウェアの複製を使用、複写、変更、結合、掲載、頒布、サブライセンス、および/または販売する権利、およびソフトウェアを提供する相手に同じことを許可する権利も無制限に含まれる。)
(上記の著作権表示および本許諾表示を、ソフトウェアのすべての複製または重要な部分に記載するものとする。)
(ソフトウェアは「現状のまま」で、明示であるか暗黙であるかを問わず、何らの保証もなく提供される。ここでいう保証には、商品性、特定の目的への適合性、および権利非侵害についての保証も含まれるが、それに限定されるものではない。X CONSORTIUM は、契約行為、不法行為、またはそれ以外であろうと、ソフトウェアに起因または関連し、あるいはソフトウェアの使用またはその他の扱いによって生じる一切の請求、損害、その他の義務について何らの責任も負わないものとする。)
(X Consortium の名称は、この表示に記載されている場合を除き、X Consortium の事前の書面による承認を得ずに、宣伝であろうとその他の形であろうと、ソフトウェアの販売を促進するもの、またはソフトウェアの使用その他の扱いを奨励するものに使用してはならない。)
(X Window System は The Open Group の商標である。)
クライアント間の通信に使えるプロトコルとしては、色々なものが考えられる。そして、この種のプロトコルには多くの類似点と等しく要求される機能がある。認証手続き、使用する版の交渉(version negotiation)、データ型の選定(data typing)、接続の管理などである。Inter-Client Exchange(ICE) プロトコルでは、そのような機能を持ったプロトコルを構築するための枠組みを規定している。ICE プロトコルを使うことで、新しいプロトコルの設計が簡単になり、実装の多くの部分が共有できるようになる。
目次
様々なプロトコル -- 存在するもの、開発中のもの、仮想のもの -- について話し合う中で、複数のプロトコルに共通する要素が多数存在することが分かった。大抵のプロトコルには認証、版の交渉(version negotiation)、接続設定、接続切断を行うための仕組みが要る。また、交信し合う二者の間で複数のプロトコルを同時に用いなければならないこともある。例えば、二者の間に関係を確立しようとすると、セッション管理機構のプロトコルや、データ転送、入力先の交渉、コマンド通知のプロトコルを同時に運用することが必要になるであろう。これらは論理構造の上では別々のプロトコルであるが、実装にあたっては能う限り多くの部品を共用するのが望ましい。
信頼に足る、バイトストリーム伝送の接続に基いて、種々のプロトコルを構築する。そのための汎用な枠組みを定めるのが Inter-Client Exchange(ICE)プロトコルである。このプロトコルでは次に挙げる作業のための基礎機構が規定される。接続の設定・切断、認証の実行、使用するプロトコルの版の交渉、エラーの報告である。ICE 接続の中で用いられるプロトコルを、ここでは下位プロトコル(subprotocol)と呼ぶことにする。ICE プロトコルにおいて、各下位プロトコルは自前の版交渉、認証、エラー報告を行うことが可能である。加えて、ICE では、交信する二者が複数の異なる下位プロトコルを用いている場合、そうした下位プロトコル群は同一の伝送層(transport layer)の接続を共同で使用できる。
交信を行おうとする二者は、ICE 外部の何らかの機構を通じて、互いの存在を知らせ合い、ICE の下位プロトコルの一つを使って通信することを取り決める(訳註:附録 B:ICE X ランデヴ・プロトコル参考)。ICE は、この交渉の内に開始方(originating party)と応答方(answering party)の区別が存在することを前提に作られている。また、この最初の交渉においては、開始方に対して応答方の名前もしくはアドレスが知らされなければならない。交信者双方が互いの存在を知らせ合うために用いる機構には、X セレクション機構、環境変数、共有ファイルなどがある。
開始方はまず、通信を試みようとする相手との間に、生きた ICE 接続が存在するか否かを調べる。もし有れば、既存の接続を再利用し、直ちに下位プロトコルの設定に進む。既存の ICE 接続が存在しなければ、開始方にて応答方への伝送接続(transport connection)を開き、ICE 接続の設定を始める。
ICE 接続の設定は主に三つの部分から成る。バイト順(byte order)に関する情報の交換、認証、接続情報の交換の三つである。双方から送り出される最初のメッセージは ByteOrder
メッセージであり、これは、このメッセージの送信者が以後の送信メッセージにおいて如何なるバイト順を使用する予定なのかを伝えるものである。次いで、開始方から ConnectionSetup
メッセージを送信する。ConnectionSetup
メッセージによって、開始方自身の情報(開発者名(vendor name)と版番号(release number))、開始方が対応している ICE の版の番号一覧、並びに開始方が受け付けている認証方式の一覧を通知する。認証は必須ではない。認証不要であれば、応答方が ConnectionReply
メッセージを返信して自身の情報を伝えたところで、接続設定は完了する。
接続設定中に認証を行う場合、応答方は ConnectionReply
メッセージではなく AuthenticationRequired
メッセージで応じる。その後、認証作業が完了するまで両者は AuthenticationReply
メッセージと AuthenticationNextPhase
メッセージを交換し合う。最後に応答方から ConnectionReply
メッセージを送信することで認証が完了する。
ICE 接続が確立すると(あるいは既存の接続が再び利用されるようになると)、開始方の ProtocolSetup
メッセージの送信を以て、下位プロトコルの交渉が始まる。このメッセージは、両者が使用することに合意した下位プロトコルの名前と、開始方がその下位プロトコルに割り当てた ICE の主たる命令コード(major opcode)とを伝えるものである。接続の認証とは別に、下位プロトコルの認証を行うこともできる。下位プロトコルの認証も必須ではない。下位プロトコルの認証が不要な場合、応答方は ProtocolReply
メッセージを返す。このメッセージによって、応答方が先の下位プロトコルに割り当てた ICE 主命令コードを通知する。
各下位プロトコルの認証は、それぞれ別々に行われる。何故かというと、必要とされる安全基準が各者で異なり得るからである。ある下位プロトコルに対して認証が行われる場合、認証は応答方がこのプロトコルに関する ProtocolReply
メッセージを発する前の段階で実施される。その際、接続の認証と同じように、当下位プロトコルに関して AuthenticationRequired
、AuthenticationReply
、AuthenticationNextPhase
メッセージを使用する。下位プロトコルの認証が終わって初めて応答方から ProtocolReply
メッセージを送信する。
下位プロトコルの設定と認証を済ませると、両者はその下位プロトコルで定義されたメッセージを用いて通信できるようになる。どのメッセージにも二つの命令コードが振られている。即ち、主たる命令コード(major opcode、主命令コード)と従たる命令コード(minor opcode、従命令コード)である。両者は ProtocolSetup
と ProtocolReply
メッセージで決定された主命令コードを用いて各メッセージを送信する。両者が用いる主命令コードは通常、一致しない。一つの下位プロトコルに対して、両者は共に二つの主命令コードを管理する必要がある。メッセージを送信するときに使う主命令コードと、受信するメッセージが保持しているはずの主命令コードである。従命令コードの値と意味は個々の下位プロトコルで定義する。
各下位プロトコルには、当の下位プロトコルを終了させることを意味するメッセージが一つ以上存在する。終了作業が一方向の通知で完了するのか、交渉を経て実行されるのかはそれぞれの下位プロトコルで定める。下位プロトコルを終了すると、その主命令コードは使えなくなる。命令コードが ProtocolSetup
によって再設定されるまで、この下位プロトコルでメッセージを送信するべきではない。
ICE には、交信中の下位プロトコルが一つもなくなった時に、接続切断の交渉を行う手続きが存在する。どちらか一方において交信中の下位プロトコルが存在しないと判断された時は、この方から WantToClose
メッセージを送信することができる。他の一方は、接続の切断に同意する場合、単にそうすれば良い。しかし、この他の一方において、接続を繋いだままにしておきたいと思われた時は、NoClose
メッセージを返信してその希望を伝えることも可能である。
接続の開始方が必ずしも下位プロトコル設定手続きの開始方と同じではないことに注意する。例として A 方が B 方に接続を図る場合を考える。A 方が ConnectionSetup
メッセージを発し、B 方が ConnectionReply
メッセージで応えたとする。(簡単にするためここでは認証の段階を省く。)一般的には、A 方が ProtocolSetup
メッセージをも発し、B 方から ProtocolReply
が返されるものである。しかし、一旦接続が確立すれば、どちらの側から下位プロトコルの交渉を始めてもよいことになっている。この例を続けると、B 方にて、A 方と通信するために自分の方から下位プロトコルを設定する必要がある、と判断されることもあり得る。その時は B 方が ProtocolSetup
メッセージを発し、A 方からの ProtocolReply
を待つことになる。
ICE メッセージでは様々な型のデータを使用する。バイト順(byte order)は最初の接続メッセージのやり取りで決める。通常、データは送信者のバイト順で送り出されるので、受信者側で適切に並び替える必要がある。64-bit 機に対応するため、ICE メッセージの長さは詰め物をして8バイトの倍数に合わせる。全てのメッセージの中の各欄も自づから16、32、64ビットの境界に揃うようになっている。次の計算式は、E バイトのデータを次の b の倍数の境界に合わせるにあたって、必要とされる詰め物のバイト数を表す。
pad(E, b) = (b - (E mod b)) mod b
Type Name | Description |
---|---|
CARD8 | 8-bit 符号無し整数 |
CARD16 | 16-bit 符号無し整数 |
CARD32 | 32-bit 符号無し整数 |
BOOL |
|
LPCE | Latin Portable Character Encoding 符号化方式の X Portable Character Set に属する一文字 |
Type Name | Type |
---|---|
VERSION | [Major, minor: CARD16] |
STRING | LISTofLPCE |
「LISTof<type>」は <type> 型を所定の数だけ並べたものを表す。具体的な符号列は用いられる文脈によって異なる。符号化に関する章を見よ。
全ての ICE メッセージには下記の情報が入っている。
Field Type | Description |
---|---|
CARD8 | プロトコルの主たる命令コード |
CARD8 | プロトコルの従たる命令コード |
CARD32 | 8バイトを単位とした後続データの長さ |
各欄の意味は次の通り、
プロトコルの主命令コード | このメッセージがどの下位プロトコルに則ったものなのかを記す。主命令コードの0番は ICE 制御メッセージの伝達に使用される。他の下位プロトコルの主命令コードは、プロトコルの交渉時に動的に割り当てられ、交換される。 |
プロトコルの従命令コード | 下位プロトコル固有の作業の中、どれが行われるのかを記す。従命令コードの0番はエラー通知用である。他の値の意味は下位プロトコルで独自に定める。 |
8バイト単位の後続データ長 | ここには先頭の8バイト以降の情報の長さを記す。どのメッセージ型も独自の形式を有するので、この値に対してそれぞれ長さの照合を行う必要がある。全ての項目のデータ長が明に暗に知れるので、これは簡単に成し遂げられる。データ長の長すぎたり短すぎたりするメッセージがあれば、深刻なプロトコル違反が行われている可能性があるので、 |
同一方向に送受信されるメッセージの全てに、表に出ない通し番号が振られている。この通し番号は 1 から始まり、当該接続の中で一意である(global to the connection)。それぞれのプロトコル毎に独立の通し番号が保持される訳ではない。
同一の主命令コードを持つメッセージは(即ち同一プロトコルのメッセージは)、受信方によって順番通りに返答されなければならない(返答が必要であれば)。異なるプロトコルに基づくメッセージは任意の順で返答してよい。
全てのプロトコルの従命令コード 0 はエラーの報告に用いる。要請(request)一つにつき、一つしかエラーを生成できない。相手方からの要請を処理している最中に複数のエラーが発生した場合、どのエラーを返すかは実装次第である。
Error
offending-minor-opcode: | CARD8 |
severity: | CanContinue, |
sequence-number: | CARD32 |
class: | CARD16 |
value(s): | <主/従命令コードとクラスによる> |
このメッセージはエラーを報告するために送信するものであり、どのプロトコルに基づくメッセージに対しても応答として使用できる。プロトコルの主命令コード空間は、いづれも Error
メッセージを備えている。全てのプロトコルの従命令コード 0 番がそれである。エラーを起こしたメッセージの従命令コードは、そのメッセージの通し番号とともに、報告される。重症度(severity)は、エラーメッセージの送り手がエラーの同定後、どのように振る舞うのかを表す。CanContinue
は、エラーを出した当のプロトコルに基づく更なるメッセージについて、送り手が受け入れるつもりであることを示す。FatalToProcotol
は、送り手が、エラーを出した当のプロトコルのメッセージはこれ以上受け付けないけれども、他のプロトコルのメッセージは受け入れられることを示す。FatalToConnection
は、送り手が当の接続において、如何なるプロトコルの如何なるメッセージもこれ以上受け付けないことを示す。一般エラーと ICE エラー(主命令コード 0)を発する際、エラー毎に指定できる重症度が決まっているので、送り手はその条件に従う必要がある。一般エラークラスと ICE エラークラスを見よ。class ではエラーが属するクラスを指定する。各プロトコルが種々のクラスを独自に定めるので、プロトコルが異なれば class の数値の意味も変わってくる。エラーの values が存在する場合、その値と型は当該プロトコルの具体的なエラークラスに従って変化する。
ICE 制御命令コードの一つ一つを以下で説明する。殆どのメッセージには、上で説明したもの以外の付加情報が入っている。付加情報はメッセージヘッダの後ろに加えられ、それを踏まえてメッセージ長が計算される。
これ以降のメッセージの説明における「Expected errors」とは、平常運転中に起り得るエラーのことである。他のエラー(特に BadMajor
、BadMinor
、BadState
、BadLength
、BadValue
、ProtocolDuplicate
そして MajorOpcodeDuplicate
)も起きる可能性はあるが、これらは通常、エラーを発行した当事者側において深刻な実装不備があることを意味している。
ByteOrder
byte-order: | MSBfirst, |
交信の両当事者は、エラーも含む他の全てのメッセージより先に、このメッセージを送信しなければならない。このメッセージには、本メッセージの送信方が以後のメッセージにおいて使用するバイト順を記す。
受信方でこのメッセージにエラーが見つかった場合、同者は Error
メッセージを送る前に必ず自分の ByteOrder
メッセージを送信しなければならない。
ConnectionSetup
versions: | LISTofVERSION |
must-authenticate: | BOOL |
authentication-protocol-names: | LISTofSTRING |
vendor: | STRING |
release: | STRING |
Responses: |
|
Expected errors: |
|
接続の開始方(「connect()」を実行した方)は、このメッセージを第二のメッセージとして送信しなければならない(ByteOrder
による立ち上げに次いで)。
versions 欄には、本メッセージの送信方が使用可能なプロトコルの版番号を、優先度に関して降順に並べる。この文書は主たる版番号 1、従たる版番号 0 である。(訳註:???)
must-authenticate が True
であれば、開始方が認証作業を要求しているということである。受理方は認証方式を決定し、それに基いて認証を実行しなければならない。must-authenticate が True
の場合、有効な返答は AuthenticationRequired
だけである。
must-authenticate が False
であれば、受理方は認証の方法を選ぶか、ホスト・アドレスに基づく(host-address-based)認証方式を使うか、もしくは認証を省くことができる。must-authenticate が False
の時には、ConnectionReply
と AuthenticationRequired
の二つが返答たり得る。ホスト・アドレスに基づく認証方式を用いる場合、AuthenticationRejected
エラーと AuthenticationFailed
エラーが起こり得る。
Authentication-protocol-names には、送り手側で実行したいと考えている認証プロトコルを列挙する(must-authenticate が False
のとき、この欄は null(空)でもよい)。must-authenticate が True
であれば、送り手は相互認証を許す方式しか提示しないものと考えられる。
vendor には、使用している ICE 実装の開発者名が入る。
release には、使用している ICE 実装の版の識別子が入る。
AuthenticationRequired
authentication-protocol-index: | CARD8 |
data: | <認証プロトコル固有のデータ> |
Response: |
|
Expected errors: |
|
このメッセージは ConnectionSetup
メッセージと ProtocolSetup
メッセージに対する返答として送信される。認証が行われることと、どの認証方式を使用するのかとを伝える。
認証プロトコルは番号で指定する。この番号は ConnectionSetup
や ProtocolSetup
で提示されたプロトコル名の配列の要素番号であり、先頭要素の番号は 0 番である。認証プロトコル固有のデータで必要なものも一緒に送信する。
AuthenticationReply
data: | <認証プロトコル固有のデータ> |
Responses: |
|
Expected errors: |
|
このメッセージは AuthenticationRequired
メッセージと AuthenticationNextPhase
メッセージに対する返答として送信される。採用した認証プロトコルに則った認証データを伝達するのが役目である。
このメッセージを送信するのは現交渉の開始方 — 即ち、ConnectionSetup
メッセージもしくは ProtocolSetup
メッセージを送信した方であるという点に注意する。
AuthenticationNextPhase
によって、認証を完了するには更なる作業が必要である旨を伝える。認証が完了した時は、当の認証の互礼(authentication handshake)が ConnectionSetup
の結果であれば ConnectionReply
が、ProtocolSetup
の結果であれば ProtocolReply
が AuthenticationReply
に対する返答となる。
AuthenticationNextPhase
data: | <認証プロトコル固有のデータ> |
Response: |
|
Expected errors: |
|
このメッセージは AuthenticationReply
メッセージに対する返答として送信されるものであり、使用中の認証プロトコルに則った認証データを伝える。
ConnectionReply
version-index: | CARD8 |
vendor: | STRING |
release: | STRING |
このメッセージは ConnectionSetup
メッセージもしくは AuthenticationReply
メッセージに対する返答として送信されるものであり、認証の互礼(authentication handshake)が完了したことを伝える。
version-index には版番号の配列の要素番号が入る。この配列は ConnectionSetup
メッセージで提示されたもので、先頭要素の番号は 0 番である。この欄を通じて、両者が接続の終了まで遵うことになる ICE プロトコルの版を定める。
vendor には使用中の ICE 実装の開発者名が入る。
release には使用中の ICE 実装の版の識別子が入る。
ProtocolSetup
protocol-name: | STRING |
major-opcode: | CARD8 |
versions: | LISTofVERSION |
vendor: | STRING |
release: | STRING |
must-authenticate: | BOOL |
authentication-protocol-names: | LISTofSTRING |
Responses: |
|
Expected errors: |
|
このメッセージを使って、プロトコルの交渉を開始し、同プロトコル固有の認証方式を相手方に提示する。
protocol-name には、このメッセージの送信側が使用したいと思っているプロトコルの名前を記す。
major-opcode には、このメッセージの送信方が自身の送り出すメッセージの中で用いることになる主命令コードを記す。
versions には、このメッセージの送信側が使用したいと思っている版の番号を、優先度に関して降順に並べる。
vendor と release には識別子として働く文字列を記す。この識別子文字列の意味は目下交渉中のプロトコルで規定される。
must-authenticate が True
であれば、開始方が認証作業を要求しているということである。受理方は認証方式を決定し、それに基いて認証を実行しなければならない。must-authenticate が True
の場合、有効な返答は AuthenticationRequired
だけである。
must-authenticate が False
であれば、受理方は認証の方法を選ぶか、ホスト・アドレスに基づく(host-address-based)認証方式を使うか、もしくは認証を省くことができる。must-authenticate が False
の時には、ProtocolReply
と AuthenticationRequired
の二つが返答たり得る。ホスト・アドレスに基づく認証方式を用いる場合、AuthenticationRejected
エラーと AuthenticationFailed
エラーが起こり得る。
Authentication-protocol-names には、送り手側で実行したいと考えている認証プロトコルを列挙する(must-authenticate が False
のとき、この欄は null(空)でもよい)。must-authenticate が True
であれば、送り手は相互認証を許す方式しか提示しないものと考えられる。
ProtocolReply
major-opcode: | CARD8 |
version-index: | CARD8 |
vendor: | STRING |
release: | STRING |
このメッセージは ProtocolSetup
メッセージもしくは AuthenticationReply
メッセージに対する返答として送信されるものであり、認証の互礼(authentication handshake)が完了したことを伝える。
major-opcode には、このメッセージの送信方が自身の送り出すメッセージの中で用いることになる主命令コードを記す。
version-index には版番号の配列の要素番号が入る。この配列は ProtocolSetup
メッセージで提示されたもので、先頭要素の番号は 0 番である。この欄を通じて、両者が接続の終了まで遵うことになるプロトコルの版を定める。
vendor と release には識別子として働く文字列を記す。この識別子文字列の意味は目下交渉中のプロトコルで規定される。
Ping
Response: |
|
このメッセージを用いて、接続が今なお機能しているかを検査する。
PingReply
このメッセージは Ping
メッセージに対する返信であり、接続が今なお機能していることを知らせる。
WantToClose
Responses: |
|
このメッセージを用いて接続終了作業の端緒を開く。メッセージの送信方においては、各プロトコル固有の手続きによって、運用中のプロトコルが残っていないと判断されている。この要求を受けて四つの展開が考えられる。
メッセージの受信方も同じ判断を下し、既に WantToClose
メッセージを送信している場合。終了作業を行おうとしているところに WantToClose
が届いた時は、両者とも単に接続を切る。
受信方ではまだ判断を下していなかったが、接続切断に同意する場合。受信方は接続を切る。
受信方の発した ProtocolSetup
が「飛行中」の場合。受信方は WantToClose
メッセージを無視する。WantToClose
メッセージの送信方は ProtocolSetup
を受け取った時点で終了作業を中止する。
受信側において、ICE プロトコルで規定されていない何らかの理由から、接続維持を望む場合。受信方は NoClose
メッセージを送信する。
状態遷移表にも関連情報が載っている。
NoClose
このメッセージは WantToClose
メッセージに対する返答として送信されるものであり、返答方にとって現時点での接続の切断が望ましくない旨を伝える。このメッセージの受信方は接続を断つべきではない。後ほど、どちらの側からでも WantToClose
に始まる手続きを提起することができる。
以下のエラーは、それらが該当する事態に際して、全てのプロトコルで使用される。ICE においては(主命令コード 0 の場合は)、FatalToProtocol
を FatalToConnection
と解釈する。
BadMinor
offending-minor-opcode: | <any> |
severity: |
|
values: | (none) |
未知の従命令コードが付されたメッセージを受信した。
BadState
offending-minor-opcode: | <any> |
severity: |
|
values: | (none) |
付属の従命令コードは有効であるが、プロトコルの手順からして現在の状態で受け取るのは適切でないメッセージを受信した。
BadLength
offending-minor-opcode: | <any> |
severity: |
|
values: | (none) |
不適当な長さのメッセージを受信した。データを容れるのに必要とされる長さを考えると、メッセージ長に過不足がある。
BadValue
offending-minor-opcode: | <any> |
severity: |
|
values: | (1)CARD32 異常があったメッセージの中の、異常な値を格納した箇所へのバイト歩数(byte offset)。(2)CARD32 異常な値を格納している箇所のデータ長。(3)<varies> 当の異常値。 |
values 欄に記した異常値のあるメッセージを受信した。
以下のエラーは全て主命令コード 0 のエラーである。
BadMajor
offending-minor-opcode: | <any> |
severity: |
|
values: | CARD8 命令コード |
指定された命令コードは未だ登録されていない。
NoAuthentication
offending-minor-opcode: |
|
severity: |
|
values: | (none) |
提示された認証プロトコルはどれも利用不能である。
NoVersion
offending-minor-opcode: |
|
severity: |
|
values: | (none) |
提示されたプロトコルの版はどれも利用不能である。
SetupFailed
offending-minor-opcode: |
|
severity: |
|
values: | STRING 理由 |
このエラーの送信側において、認証失敗以外の理由で新しい接続や新しいプロトコルを受け入れることができなかった。このエラーは大抵、送信側における追加資源の割当て失敗に起因する。理由の欄には、人間が読める形で、蹉跌の種類を詳しく記す。
AuthenticationRejected
offending-minor-opcode: |
|
severity: |
|
values: | STRING 理由 |
認証が拒絶された。交渉者が自身を適切に証明することに失敗した。理由の欄には人間が読める形で詳細を記す。
AuthenticationFailed
offending-minor-opcode: |
|
severity: |
|
values: | STRING 理由 |
認証に失敗した。AuthenticationFailed
は AuthenticationRejected
と異なり、認証が撥ねられたことを意味しない。そうではなく、このエラーの送信者が他の何らかの理由で認証を完遂できなかったことを表す。例えば、認証サーバに連絡をとれなかった場合。理由の欄には人間が読める形で詳細を記す。
ProtocolDuplicate
offending-minor-opcode: |
|
severity: |
|
values: | STRING プロトコルの名前 |
指定されたプロトコル名は既に登録されていた。この事態は、ProtocolSetup
で設定を試みている「新しい」プロトコルにとっては致命的であるが、登録済みのプロトコルには影響を与えない。
MajorOpcodeDuplicate
offending-minor-opcode: |
|
severity: |
|
values: | CARD8 命令コード |
指定された主命令コードは既に登録されていた。この事態は、ProtocolSetup
で設定を試みている「新しい」プロトコルにとっては致命的であるが、登録済みのプロトコルには影響を与えない。
UnknownProtocol
offending-minor-opcode: |
|
severity: |
|
values: | STRING プロトコルの名前 |
指定されたプロトコルには対応していない。
以下は接続開始方の状態遷移表である。
start:
他方に接続するため、ByteOrder
ConnectionSetup
を送信 -> conn_wait
conn_wait:
receive ConnectionReply
-> stasis
receive AuthenticationRequired
-> conn_auth1
receive Error
-> quit
receive <その他>, send Error
-> quit
conn_auth1:
適切な認証データであれば、 send AuthenticationReply
-> conn_auth2
不適当な認証データであれば、 send Error
-> quit
conn_auth2:
receive ConnectionReply
-> stasis
receive AuthenticationNextPhase
-> conn_auth1
receive Error
-> quit
receive <その他>, send Error
-> quit
以下は接続受理方の最上層の状態遷移である。
listener:
accept connection -> init_wait
init_wait:
receive ByteOrder
ConnectionSetup
-> auth_ask
receive <その他>, send Error
-> quit
auth_ask:
send ByteOrder
ConnectionReply
-> stasis
send AuthenticationRequired
-> auth_wait
send Error
-> quit
auth_wait:
receive AuthenticationReply
-> auth_check
receive <その他>, send Error
-> quit
auth_check:
これ以上の認証作業が不要であれば、 send ConnectionReply
-> stasis
適切な認証データであれば、 send AuthenticationNextPhase
-> auth_wait
不適当な認証データであれば、 send Error
-> quit
以下は、制御用下位プロトコルの始めの接続確立部分に続く、全者共通の最上層状態遷移である。
stasis からの分岐は必ずしも正確ではない。同一の接続の上で複数の対話が織り混ざって同時に進行しているという点を無視しているからである。
stasis:
send ProtocolSetup
-> proto_wait
receive ProtocolSetup
-> proto_reply
send Ping
-> ping_wait
receive Ping
send PingReply
-> stasis
receive WantToClose
-> shutdown_attempt
receive <その他>, send Error
-> stasis
全てのプロトコルが終了したら、 send WantToClose
-> close_wait
proto_wait:
receive ProtocolReply
-> stasis
receive AuthenticationRequired
-> give_auth1
receive Error
このプロトコルは諦める -> stasis
receive WantToClose
-> proto_wait
give_auth1:
適切な認証データであれば、 send AuthenticationReply
-> give_auth2
不適当な認証データであれば、 send Error
このプロトコルは諦める -> stasis
receive WantToClose
-> give_auth1
give_auth2:
receive ProtocolReply
-> stasis
receive AuthenticationNextPhase
-> give_auth1
receive Error
このプロトコルは諦める -> stasis
receive WantToClose
-> give_auth2
proto_reply:
send ProtocolReply
-> stasis
send AuthenticationRequired
-> take_auth1
send Error
このプロトコルは諦める -> stasis
take_auth1:
receive AuthenticationReply
-> take_auth2
receive Error
このプロトコルは諦める -> stasis
take_auth2:
適切な認証データであれば、 -> take_auth3
不適当な認証データであれば、 send Error
このプロトコルは諦める -> stasis
take_auth3:
これ以上の認証作業が不要であれば、 send ProtocolReply
-> stasis
適切な認証データであれば、 send AuthenticationNextPhase
-> take_auth1
不適当な認証データであれば、 send Error
このプロトコルは諦める -> stasis
ping_wait:
receive PingReply
-> stasis
quit:
-> 接続を断つ
以下は接続終了時の状態遷移である。
shutdown_attempt:
接続状態を保ちたい場合、 send NoClose
-> stasis
else -> quit
close_wait:
receive ProtocolSetup
-> proto_reply
receive NoClose
-> stasis
receive WantToClose
-> quit
接続切断 -> quit
下記のメッセージ符号表において、最左列に書いてあるのは使用するバイト数である。二列目に書かれているのは型(値が変化する場合)か、もしくは実際の値である。三列目は値の説明である(変数の名前等)。メッセージの受信者は unused(未使用)あるいは pad(詰め物)と称されたバイト列を無視しなければならない。
この文書では主たる版番号 1、従たる版番号 0 の ICE プロトコルの符号表を載せている。(訳註:???)
LISTof<type> は <type> 型のデータを詰め物無しで複数個並べたものを表す。配列された同型データの個数はメッセージ中のどこかに明記しなければならない。
型名 | 長さ(bytes) | 説明 |
---|---|---|
CARD8 | 1 | 8-bit 符号無し整数 |
CARD16 | 2 | 16-bit 符号無し整数 |
CARD32 | 4 | 32-bit 符号無し整数 |
LPCE | 1 | Latin Portable Character Encoding 符号化方式の X Portable Character Set に属する一文字 |
型名 | 長さ(bytes) | 型 | 説明 |
---|---|---|---|
VERSION | |||
2 | CARD16 | 主たる版番号 | |
2 | CARD16 | 従たる版番号 | |
STRING | |||
2 | CARD16 | 文字列のバイト長 | |
n | LISTofLPCE | 文字列 | |
p | unused, p = pad(n+2, 4) |
メッセージ名 | 符号 |
---|---|
Error | 0 |
ByteOrder | 1 |
ConnectionSetup | 2 |
AuthenticationRequired | 3 |
AuthenticationReply | 4 |
AuthenticationNextPhase | 5 |
ConnectionReply | 6 |
ProtocolSetup | 7 |
ProtocolReply | 8 |
Ping | 9 |
PingReply | 10 |
WantToClose | 11 |
NoClose | 12 |
Error
1 CARD8 major-opcode
1 0 Error
2 CARD16 class(エラークラス)
4 (n+p)/8+1 length
1 CARD8 offending-minor-opcode
1 severity(重症度):
0 CanContinue
1 FatalToProtocol
2 FatalToConnection
2 unused
4 CARD32 sequence number of erroneous message
(エラーがあったメッセージの通し番号)
n <varies> value(s)
p pad, p = pad(n,8)
ByteOrder
1 0 ICE
1 1 ByteOrder
1 byte-order:
0 LSBfirst(最下位バイトが先)
1 MSBfirst(最上位バイトが先)
1 unused
4 0 length
ConnectionSetup
1 0 ICE
1 2 ConnectionSetup
1 CARD8 Number of versions offered
(提示された版の数)
1 CARD8 Number of authentication protocol names offered
(提示された認証プロトコルの名前の数)
4 (i+j+k+m+p)/8+1 length
1 BOOL must-authenticate
7 unused
i STRING vendor
j STRING release
k LISTofSTRING authentication-protocol-names
(認証プロトコル名の配列)
m LISTofVERSION version-list
(版の識別名の配列)
p unused, p = pad(i+j+k+m,8)
AuthenticationRequired
1 0 ICE
1 3 AuthenticationRequired
1 CARD8 authentication-protocol-index
(認証プロトコル名の配列の要素番号)
1 unused
4 (n+p)/8+1 length
2 n length of authentication data
6 unused
n <varies> data
p unused, p = pad(n,8)
AuthenticationReply
1 0 ICE
1 4 AuthenticationReply
2 unused
4 (n+p)/8+1 length
2 n length of authentication data
6 unused
n <varies> data
p unused, p = pad(n,8)
AuthenticationNextPhase
1 0 ICE
1 5 AuthenticationNextPhase
2 unused
4 (n+p)/8+1 length
2 n length of authentication data
6 unused
n <varies> data
p unused, p = pad(n,8)
ConnectionReply
1 0 ICE
1 6 ConnectionReply
1 CARD8 version-index
(版識別名の配列の要素番号)
1 unused
4 (i+j+p)/8 length
i STRING vendor
j STRING release
p unused, p = pad(i+j,8)
ProtocolSetup
1 0 ICE
1 7 ProtocolSetup
1 CARD8 major-opcode
1 BOOL must-authenticate
4 (i+j+k+m+n+p)/8+1 length
1 CARD8 Number of versions offered
(提示された版の数)
1 CARD8 Number of authentication protocol names offered
(提示された認証プロトコルの名前の数)
6 unused
i STRING protocol-name
j STRING vendor
k STRING release
m LISTofSTRING authentication-protocol-names
(認証プロトコル名の配列)
n LISTofVERSION version-list
(版の識別名の配列)
p unused, p = pad(i+j+k+m+n,8)
ProtocolReply
1 0 ICE
1 8 ProtocolReply
1 CARD8 version-index(版識別名の配列の要素番号)
1 CARD8 major-opcode
4 (i+j+p)/8 length
i STRING vendor(意味は下位プロトコルで定義)
j STRING release(意味は下位プロトコルで定義)
p unused, p = pad(i+j, 8)
Ping
1 0 ICE
1 9 Ping
2 0 unused
4 0 length
PingReply
1 0 ICE
1 10 PingReply
2 0 unused
4 0 length
WantToClose
1 0 ICE
1 11 WantToClose
2 0 unused
4 0 length
NoClose
1 0 ICE
1 12 NoClose
2 0 unused
4 0 length
一般エラークラスを表すには、0x8000〜0xFFFF の範囲の値を用いる。下位プロトコル固有のエラーには 0x0000〜0x7FFF までの値を用いる。
二者のクライアントが ICE を介して通信するためには、通信確立に必要な情報を前以て交換する仕組みが要る、ということを第二章で述べた。ICE X ランデヴ・プロトコルはこの要求に応えるべく作られた。同一の X サーバに対して接続を持つ ICE クライアントであれば、何れの二者にもこのプロトコルを適用することができる。
ICE X ランデヴの手続きにおいて ICE 開始方として振舞おうとするクライアントは、自身の最上位ウィンドウの ICE_PROTOCOLS プロパティに、使用可能な ICE 下位プロトコル群を予め登録しておかなければならない。次いで、ICE の応答方として振舞おうとするクライアントが ICE_PROTOCOLS 型の X ClientMessage
イベントを ICE 開始方へ送信する。この ClientMessage
イベントでは、応答方のネットワーク ID と応答側の使いたい ICE 下位プロトコルを提示する。このメッセージを受け取った後、ICE 開始方はその情報を使って応答方との ICE 接続を確立する。
ICE の開始方として振舞おうとするクライアントは、自身の最上位ウィンドウの ICE_PROTOCOLS プロパティが保持するアトムの配列に、使用可能な ICE 下位プロトコルを予め登録しておく。ICE_PROTOCOLS プロパティ中に配列された各アトムの名前は「ICE_INITIATE_pname」の形を採らなければならない。「pname」には開始側の使用したい ICE 下位プロトコルの名前を、ICE ProtocolSetup
メッセージにおけるのと同様に記す。
最上位ウィンドウの ICE_PROTOCOLS プロパティに ICE_INITIATE_pname アトムを持つクライアントは、ICE_INITIATE_pname を指定した ICE_PROTOCOLS 型 ClientMessage
イベントに必ず応答しなければならない。このようなクライアント・メッセージに応答したくないクライアントは、自身の ICE_PROTOCOLS プロパティからアトム ICE_INITIATE_pname を取り除くか、もしくは ICE_PROTOCOLS プロパティそのものを削除する。
ランデヴ(待合せ)を開始するには、ICE 応答方として振舞うクライアントは ICE 開始方に対して ICE_PROTOCOLS 型の ClientMessage
イベントを送信する。この ICE_PROTOCOLS クライアント・メッセージには、両者の間で使用する下位プロトコルを開始方が決定するのに必要な情報と、応答方の ICE ネットワーク識別子の文字列表現とが入っている。
ICE 応答方は上のクライアント・メッセージ・イベントを送信する前に、自身のウィンドウの一つで文字列プロパティを定義しておかなければならない。この文字列プロパティには応答方の ICE ネットワーク識別子を表す文字列が入る。開始方はこれを用いて応答方の ICE ネットワーク識別子の一覧を取得する。
このプロパティの名前は通常 ICE_NETWORK_IDS であるが、ICE 応答方の裁量で自由に名前を付けることができる。文字列プロパティの形式は下の通り。
欄 | 値 |
---|---|
type | XA_STRING |
format | 8 |
value | カンマで区切られた ICE ネットワーク ID の並び |
ICE 応答方は、自身のウィンドウのうちの一つでこの文字列プロパティを設定した後、ICE 開始方の最上位ウィンドウへ ICE_PROTOCOLS 型 ClientMessage
イベントを送信することによって、ランデヴを始める。このイベントが送られるのは、予め最上位ウィンドウの ICE_PROTOCOLS プロパティに ICE 下位プロトコルを登録してあるウィンドウに限られねばならない。イベントの形式は下記の通り。
欄 | 値 |
---|---|
message_type | Atom = "ICE_PROTOCOLS" |
format | 32 |
data.l[0] | 使用する ICE 下位プロトコルを表すアトム |
data.l[1] | 時刻印(timestamp) |
data.l[2] | 応答方のウィンドウのうち、ICE ネットワーク ID 文字列プロパティを保持しているもののウィンドウ ID |
data.l[3] | ICE 応答方の ICE ネットワーク ID 群が記された文字列プロパティの名前を表すアトム |
data.l[4] | 予約。0 に設定しなければならない。 |
data.l[0] に入るアトムの名前は ICE_INITIATE_pname の形でなければならない。pname は ICE 応答側が使用を望む ICE 下位プロトコルの名前である。
ICE 開始方は、ICE_INITIATE_pname が指定された ICE_PROTOCOLS 型 ClientMessage
イベントを受信した時、ICE 応答方との ICE 接続を開始することができる。この接続を開くために、 クライアントは data.l[2] で指定されたウィンドウから、data.l[3] で指定された文字列プロパティを用いて、ICE 応答方の ICE ネットワーク ID 群を取得する。
何らかの理由で接続の試みが失敗した場合、クライアントは data.l[2] で指定されたウィンドウに ClientMessage
イベントを返信して、先のクライアント・メッセージ・イベントに応えなければならない。この返信イベントの形式は下表の通り。
欄 | 値 |
---|---|
message_type | Atom = "ICE_INITIATE_FAILED" |
format | 32 |
data.l[0] | 使用するべく要求されていた ICE 下位プロトコルを表すアトム |
data.l[1] | 時刻印(timestamp) |
data.l[2] | 開始方のウィンドウ ID(ICE_PROTOCOLS を保持しているウィンドウのもの) |
data.l[3] | int: 蹉跌の原因 |
data.l[4] | 予約、0 でなければならない。 |
data.l[0] と data.l[1] の値はクライアントが受信したクライアント・メッセージ・イベントから直に引き写したものである。
data.l[2] の値は、ICE_PROTOCOLS.ICE_INITIATE_pname クライアント・メッセージ・イベントが送りつけられたウィンドウの識別子を表す。
data.l[3] には以下の値の何れかが入る。
値 | 符号 | 説明 |
---|---|---|
OpenFailed | 1 | クライアントは接続を開くことができなかった(例、IceOpenConnection() の呼出しが失敗した)。クライアントが認証や権限に関わるエラーとその他のエラーを区別できる場合、前者のエラーに対しては AuthenticationFailed を返すのが好ましい。 |
AuthenticationFailed | 2 | 接続やプロトコルの設定において、認証もしくは権限の取得を拒まれた。この返答値は、クライアントが当エラーと OpenFailed とを区別できる場合に限って使用される。区別できない時は OpenFailed を返す。 |
SetupFailed | 3 | 当該接続において、クライアントは指定されたプロトコルによる通信を開設できなかった(例、IceProtocolSetup() の呼出しが失敗した)。 |
UnknownProtocol | 4 | クライアントは指定されたプロトコルを認識できなかった。(これは応答方において意味論の次元でエラーがあったことを示している。) |
Refused | 5 | クライアント・メッセージが送られてきた時、本クライアントは自身の ICE_PROTOCOLS の列から ICE_INITIATE_pname を削除している最中であった。本クライアントでは最早、クライアント・メッセージにて指定された ICE 通信を設けるつもりはない。 |
ICE の開始方として振舞おうとするクライアントは、使用する ICE 下位プロトコルを記した ICE_INITIATE_pname アトムが含まれるように、自身の最上位ウィンドウの ICE_PROTOCOLS プロパティを最新の状態に保たなければならない。ICE_INITIATE_pname アトム群を含めるべく ICE_PROTOCOLS プロパティを更新するにあたってクライアントが用いる方法は、実装によって異なる。しかし、いづれの実装においても、アトムの配列に更新前から入っていた要素が不慮に欠けてしまわないよう、クライアントはアトム配列の無欠を保って動作しなければならない。
ICE 応答方は、自身のウィンドウの一つにおいて ICE ネットワーク ID 群の文字列プロパティを設定するとき、IceListenForConnections() の呼出しの後に IceComposeNetworkIdList() を呼出すことによって、カンマで区切られた ICE ネットワーク ID 群の列を得ることができる。ICE 開始方として振舞おうとするクライアントの最上位ウィンドウを見つけるために ICE 応答方がどのような方法を用いるかは、応答方の性格次第である。利用者にクライアントのウィンドウを選んでクリックさせる方法を取るものもある。利用者とのやり取りを要求すること無しに存在しているクライアントを見つけたい場合、いくつかの無料アプリケーションで使われている XQueryTree() 関数と似たような手法も考えられる。ICE 応答方が ICE 接続の開設を目論む新規クライアントに自動で気づくようにするため、応答方の設定として、ディスプレイのルート・ウィンドウに関する SubstructureNotify イベント群を懇請するやり方でも良い。SubstructureNotify イベントを受信した時、ICE 応答方は、それが ICE_PROTOCOLS プロパティを備えた新規クライアントの最上位ウィンドウ生成の結果なのかを調べることができる。
いづれにせよ、名が pname の ICE 下位プロトコルを使おうとする ICE 応答方は、この ICE X ランデヴ機構の使用に入る前に、クライアントの最上位ウィンドウの ICE_PROTOCOLS プロパティの中に ICE_INITIATE_pname アトムが存在するか確認するものとする。ICE_PROTOCOLS プロパティに ICE_INITIATE_pname アトムが入っていない最上位ウィンドウを持つクライアントは、ICE_PROTOCOLS プロパティ型の ClientMessage
イベントの中、同プロパティに ICE 下位プロトコル pname を表す ICE_INITIATE_pname が含まれているイベントを無視するものと見做す。
ICE 下位プロトコルの版はクライアント・メッセージ・イベントに乗せて伝えることも可能であるが、ICE では、たった一つの ClientMessage
イベントに埋め込む方法と比べて、一層柔軟な版交渉の仕組みが用意されている。そのため、使用する ICE 下位プロトコルの版番号の交渉は ICE プロトコル設定(protocol setup)の段階で行われる。
二者のクライアントが「RAP V1.0」(訳註:Remote Access Protocol ver1.0)として知られる ICE 下位プロトコルで通信し合う場合。RAP の用語で当事者の一方は「代理人(agent)」と呼ばれるが、この代理人は要請を受けて他の RAP 対応アプリケーションと通信する。利用者がアプリケーションのウィンドウをクリックすることで狙ったアプリケーションとの通信を確立する方法や、新しいウィンドウの生成を代理人に見張らせて自動的に通信を確立する方法がある。
始動時、 ICE 応答方(代理人)はまず、代理人が使用できる RAP の版番号の配列(即ち、1.0)を付して、IceRegisterForProtocolReply() を呼出す。次いで応答方は IceListenForConnections() を、さらに続けて IceComposeNetworkIdList() を呼出し、結果として得られる ICE ネットワーク ID 群の文字列表現を自身のウィンドウの一つに属する文字列プロパティに格納する。
応答側(代理人側)で通信したいと思うクライアントを見つけた時は、そのクライアントの最上位ウィンドウの ICE_PROTOCOLS プロパティ内にアトム ICE_INITIATE_RAP があるか否かを調べる。存在する場合、代理人は上で説明したようにクライアントの最上位ウィンドウに ICE_PROTOCOLS クライアント・メッセージ・イベントを送信する。このクライアント・メッセージ・イベントを受信し、かつ RAP に則った ICE 接続を開設する気があるクライアントは、同者が使用可能な RAP の版番号の配列を付して IceRegisterForProtocolSetup() を実行する。同クライアントはその後、先のクライアント・メッセージ・イベントの中で代理人が指定したプロパティとウィンドウから代理人の ICE ネットワーク ID を取り出し、IceOpenConnection() を呼出す。この呼出しが成功した後、同クライアントは RAP プロトコルを指定して IceProtocolSetup() を呼出す。ICE においては、この関数の中で版交渉を行う RAP プロトコルの手続きを呼出している。
本ランデヴ機構において、クライアント・アプリケーションはクライアント・メッセージ・イベントを受け取るまで ICElib のどんな関数も呼出す必要がない、という点に注意する。