入り口に戻る

原文はこちら。
翻訳にあたって、オープンソースグループ・ジャパンの MIT ライセンスの訳を参考にした。

# Inter-Client Exchange (ICE) Protocol(日本語訳)

## X Consortium Standard

### Robert Scheifler

X Consortium

### Jordan Brown

Quarterdeck Office Systems

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.

(訳)

(本ソフトウェアおよび関連する文書のファイル（以下「ソフトウェア」）の複製を取得した全ての人物に対し、以下の条件に従うことを前提に、ソフトウェアを無制限に扱うことを無償で許可する。これには、ソフトウェアの複製を使用、複製、改変、結合、公開、頒布、再許諾、および/または販売する権利、およびソフトウェアを提供する人物に同様の行為を許可する権利が含まれるが、これらに限定されない。)

(上記の著作権表示および本許諾表示を、ソフトウェアの全ての複製または実質的な部分に記載するものとする。)

(ソフトウェアは「現状有姿」で提供され、明示的であるか黙示的であるかを問わず、いかなる種類の保証も行われない。ここでいう保証には、商品性、特定目的への適合性、および権利の非侵害性に関する保証も含まれるが、これらに限定されるものではない。THE 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 | `False` もしくは `True`
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バイト以降の情報の長さを記す。どのメッセージ型も独自の形式を有するので、この値に対してそれぞれ長さの照合を行う必要がある。全ての項目のデータ長が明に暗に知れるので、これは簡単に成し遂げられる。データ長の長すぎたり短すぎたりするメッセージがあれば、深刻なプロトコル違反が行われている可能性があるので、`BadLength` エラーを発するべきである。

## 第四章 全プロトコル共通

同一方向に送受信されるメッセージの全てに、表に出ない通し番号が振られている。この通し番号は 1 から始まり、当該接続の中で一意である(global to the connection)。それぞれのプロトコル毎に独立の通し番号が保持される訳ではない。

同一の主命令コードを持つメッセージは(即ち同一プロトコルのメッセージは)、受信方によって順番通りに返答されなければならない(返答が必要であれば)。異なるプロトコルに基づくメッセージは任意の順で返答してよい。

全てのプロトコルの従命令コード 0 はエラーの報告に用いる。要請(request)一つにつき、一つしかエラーを生成できない。相手方からの要請を処理している最中に複数のエラーが発生した場合、どのエラーを返すかは実装次第である。

`Error`

offending-minor-opcode: | CARD8
severity: | CanContinue, `FatalToProtocol`, `FatalToConnection`
sequence-number: | CARD32
class: | CARD16
value(s): | <主/従命令コードとクラスによる>

このメッセージはエラーを報告するために送信するものであり、どのプロトコルに基づくメッセージに対しても応答として使用できる。プロトコルの主命令コード空間は、いづれも `Error` メッセージを備えている。全てのプロトコルの従命令コード 0 番がそれである。エラーを起こしたメッセージの従命令コードは、そのメッセージの通し番号とともに、報告される。重症度(severity)は、エラーメッセージの送り手がエラーの同定後、どのように振る舞うのかを表す。`CanContinue` は、エラーを出した当のプロトコルに基づく更なるメッセージについて、送り手が受け入れるつもりであることを示す。`FatalToProcotol` は、送り手が、エラーを出した当のプロトコルのメッセージはこれ以上受け付けないけれども、他のプロトコルのメッセージは受け入れられることを示す。`FatalToConnection` は、送り手が当の接続において、如何なるプロトコルの如何なるメッセージもこれ以上受け付けないことを示す。一般エラーと ICE エラー(主命令コード 0)を発する際、エラー毎に指定できる重症度が決まっているので、送り手はその条件に従う必要がある。一般エラークラスと ICE エラークラスを見よ。class ではエラーが属するクラスを指定する。各プロトコルが種々のクラスを独自に定めるので、プロトコルが異なれば class の数値の意味も変わってくる。エラーの values が存在する場合、その値と型は当該プロトコルの具体的なエラークラスに従って変化する。

## 第五章 ICE 制御用下位プロトコル -- 主命令コード 0

ICE 制御命令コードの一つ一つを以下で説明する。殆どのメッセージには、上で説明したもの以外の付加情報が入っている。付加情報はメッセージヘッダの後ろに加えられ、それを踏まえてメッセージ長が計算される。

これ以降のメッセージの説明における「Expected errors」とは、平常運転中に起り得るエラーのことである。他のエラー(特に `BadMajor`、`BadMinor`、`BadState`、`BadLength`、`BadValue`、`ProtocolDuplicate` そして `MajorOpcodeDuplicate`)も起きる可能性はあるが、これらは通常、エラーを発行した当事者側において深刻な実装不備があることを意味している。

`ByteOrder`

byte-order: | MSBfirst, `LSBfirst`

交信の両当事者は、エラーも含む他の全てのメッセージより先に、このメッセージを送信しなければならない。このメッセージには、本メッセージの送信方が以後のメッセージにおいて使用するバイト順を記す。

### 註

受信方でこのメッセージにエラーが見つかった場合、同者は `Error` メッセージを送る前に必ず自分の `ByteOrder` メッセージを送信しなければならない。

`ConnectionSetup`

versions: | LISTofVERSION
must-authenticate: | BOOL
authentication-protocol-names: | LISTofSTRING
vendor: | STRING
release: | STRING
Responses: | `ConnectionReply`, `AuthenticationRequired` (下の説明を見よ)
Expected errors: | `NoVersion`, `SetupFailed`, `NoAuthentication`, `AuthenticationRejected`, `AuthenticationFailed`

接続の開始方(「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: | `AuthenticationReply`
Expected errors: | `AuthenticationRejected`, `AuthenticationFailed`

このメッセージは `ConnectionSetup` メッセージと `ProtocolSetup` メッセージに対する返答として送信される。認証が行われることと、どの認証方式を使用するのかとを伝える。

認証プロトコルは番号で指定する。この番号は `ConnectionSetup` や `ProtocolSetup`で提示されたプロトコル名の配列の要素番号であり、先頭要素の番号は 0 番である。認証プロトコル固有のデータで必要なものも一緒に送信する。

`AuthenticationReply`

data: | <認証プロトコル固有のデータ>
Responses: | `AuthenticationNextPhase`, `ConnectionReply`, `ProtocolReply`
Expected errors: | `AuthenticationRejected`, `AuthenticationFailed`, `SetupFailed`

このメッセージは `AuthenticationRequired` メッセージと `AuthenticationNextPhase` メッセージに対する返答として送信される。採用した認証プロトコルに則った認証データを伝達するのが役目である。

このメッセージを送信するのは現交渉の開始方 — 即ち、`ConnectionSetup` メッセージもしくは `ProtocolSetup` メッセージを送信した方であるという点に注意する。

`AuthenticationNextPhase` によって、認証を完了するには更なる作業が必要である旨を伝える。認証が完了した時は、当の認証の互礼(authentication handshake)が `ConnectionSetup` の結果であれば `ConnectionReply` が、`ProtocolSetup` の結果であれば `ProtocolReply` が `AuthenticationReply` に対する返答となる。

`AuthenticationNextPhase`

data: | <認証プロトコル固有のデータ>
Response: | `AuthenticationReply`
Expected errors: | `AuthenticationRejected`, `AuthenticationFailed`

このメッセージは `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: | `AuthenticationRequired`, `ProtocolReply`
Expected errors: | `UnknownProtocol`, `NoVersion`, `SetupFailed`, `NoAuthentication`, `AuthenticationRejected`, `AuthenticationFailed`

このメッセージを使って、プロトコルの交渉を開始し、同プロトコル固有の認証方式を相手方に提示する。

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`

このメッセージを用いて、接続が今なお機能しているかを検査する。

`PingReply`

このメッセージは `Ping` メッセージに対する返信であり、接続が今なお機能していることを知らせる。

`WantToClose`

Responses: | `WantToClose`, `NoClose`, `ProtocolSetup`

このメッセージを用いて接続終了作業の端緒を開く。メッセージの送信方においては、各プロトコル固有の手続きによって、運用中のプロトコルが残っていないと判断されている。この要求を受けて四つの展開が考えられる。

1. メッセージの受信方も同じ判断を下し、既に `WantToClose` メッセージを送信している場合。終了作業を行おうとしているところに `WantToClose` が届いた時は、両者とも単に接続を切る。

2. 受信方ではまだ判断を下していなかったが、接続切断に同意する場合。受信方は接続を切る。

3. 受信方の発した `ProtocolSetup` が「飛行中」の場合。受信方は `WantToClose` メッセージを無視する。`WantToClose` メッセージの送信方は `ProtocolSetup` を受け取った時点で終了作業を中止する。

4. 受信側において、ICE プロトコルで規定されていない何らかの理由から、接続維持を望む場合。受信方は `NoClose` メッセージを送信する。

状態遷移表にも関連情報が載っている。

`NoClose`

このメッセージは `WantToClose` メッセージに対する返答として送信されるものであり、返答方にとって現時点での接続の切断が望ましくない旨を伝える。このメッセージの受信方は接続を断つべきではない。後ほど、どちらの側からでも `WantToClose` に始まる手続きを提起することができる。

## 一般エラークラス

以下のエラーは、それらが該当する事態に際して、全てのプロトコルで使用される。ICE においては(主命令コード 0 の場合は)、`FatalToProtocol` を `FatalToConnection` と解釈する。

`BadMinor`

offending-minor-opcode: | <any>
severity: | `FatalToProtocol` もしくは `CanContinue`(下位プロトコル側が決める)
values: | (none)

未知の従命令コードが付されたメッセージを受信した。

`BadState`

offending-minor-opcode: | <any>
severity: | `FatalToProtocol` もしくは `CanContinue` (下位プロトコル側が決める)
values: | (none)

付属の従命令コードは有効であるが、プロトコルの手順からして現在の状態で受け取るのは適切でないメッセージを受信した。

`BadLength`

offending-minor-opcode: | <any>
severity: | `FatalToProtocol` もしくは `CanContinue` (下位プロトコル側が決める)
values: | (none)

不適当な長さのメッセージを受信した。データを容れるのに必要とされる長さを考えると、メッセージ長に過不足がある。

`BadValue`

offending-minor-opcode: | <any>
severity: | `CanContinue`
values: | (1)CARD32 異常があったメッセージの中の、異常な値を格納した箇所へのバイト歩数(byte offset)。(2)CARD32 異常な値を格納している箇所のデータ長。(3)<varies> 当の異常値。

values 欄に記した異常値のあるメッセージを受信した。

## ICE エラークラス

以下のエラーは全て主命令コード 0 のエラーである。

`BadMajor`

offending-minor-opcode: | <any>
severity: | `CanContinue`
values: | CARD8 命令コード

指定された命令コードは未だ登録されていない。

`NoAuthentication`

offending-minor-opcode: | `ConnectionSetup`, `ProtocolSetup`
severity: | `ConnectionSetup` -> `FatalToConnection`、`ProtocolSetup` -> `FatalToProtocol`
values: | (none)

提示された認証プロトコルはどれも利用不能である。

`NoVersion`

offending-minor-opcode: | `ConnectionSetup`, `ProtocolSetup`
severity: | `ConnectionSetup` -> `FatalToConnection`、`ProtocolSetup` -> `FatalToProtocol`
values: | (none)

提示されたプロトコルの版はどれも利用不能である。

`SetupFailed`

offending-minor-opcode: | `ConnectionSetup`, `ProtocolSetup`, `AuthenticationReply`
severity: | `ConnectionSetup` -> `FatalToConnection`、`ProtocolSetup` -> `FatalToProtocol`、`AuthenticationReply` -> 接続の認証であれば `FatalToConnection`、プロトコルの認証であれば `FatalToProtocol`
values: | STRING 理由

このエラーの送信側において、認証失敗以外の理由で新しい接続や新しいプロトコルを受け入れることができなかった。このエラーは大抵、送信側における追加資源の割当て失敗に起因する。理由の欄には、人間が読める形で、蹉跌の種類を詳しく記す。

`AuthenticationRejected`

offending-minor-opcode: | `AuthenticationReply`, `AuthenticationRequired`, `AuthenticationNextPhase`
severity: | `FatalToProtocol`
values: | STRING 理由

認証が拒絶された。交渉者が自身を適切に証明することに失敗した。理由の欄には人間が読める形で詳細を記す。

`AuthenticationFailed`

offending-minor-opcode: | `AuthenticationReply`, `AuthenticationRequired`, `AuthenticationNextPhase`
severity: | `FatalToProtocol`
values: | STRING 理由

認証に失敗した。`AuthenticationFailed` は `AuthenticationRejected` と異なり、認証が撥ねられたことを意味しない。そうではなく、このエラーの送信者が他の何らかの理由で認証を完遂できなかったことを表す。例えば、認証サーバに連絡をとれなかった場合。理由の欄には人間が読める形で詳細を記す。

`ProtocolDuplicate`

offending-minor-opcode: | `ProtocolSetup`
severity: | `FatalToProtocol` (下の説明を見よ)
values: | STRING プロトコルの名前

指定されたプロトコル名は既に登録されていた。この事態は、`ProtocolSetup` で設定を試みている「新しい」プロトコルにとっては致命的であるが、登録済みのプロトコルには影響を与えない。

`MajorOpcodeDuplicate`

offending-minor-opcode: | `ProtocolSetup`
severity: | `FatalToProtocol` (下の説明を見よ)
values: | CARD8 命令コード

指定された主命令コードは既に登録されていた。この事態は、`ProtocolSetup` で設定を試みている「新しい」プロトコルにとっては致命的であるが、登録済みのプロトコルには影響を与えない。

`UnknownProtocol`

offending-minor-opcode: | `ProtocolSetup`
severity: | `FatalToProtocol`
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 に属する一文字

## 列挙型

型名 | 値 | 説明
--- | --- | ---
BOOL | 0 | False
| 1 | True

## 複合型

型名 | 長さ(bytes) | 型 | 説明
--- | --- | --- | ---
VERSION |  |  |
| 2 | CARD16 | 主たる版番号
| 2 | CARD16 | 従たる版番号
STRING |  |  |
| 2 | CARD16 | 文字列のバイト長
| n | LISTofLPCE | 文字列
| p |  | unused, p = pad(n+2, 4)

## ICE 従命令コード

メッセージ名 | 符号
--- | ---
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 までの値を用いる。

### 一般エラークラスの符号表

クラス | 符号
--- | ---
BadMinor | 0x8000
BadState | 0x8001
BadLength | 0x8002
BadValue | 0x8003

### ICE 固有エラークラスの符号表

クラス | 符号
--- | ---
BadMajor | 0
NoAuthentication | 1
NoVersion | 2
SetupFailed | 3
AuthenticationRejected | 4
AuthenticationFailed | 5
ProtocolDuplicate | 6
MajorOpcodeDuplicate | 7
UnknownProtocol | 8

## 附録 A. 変更履歴

## 第 6 版から第 6.1 版へ

第 6.1 版から ICE X ランデヴ・プロトコル(附録 B)が加わり、この文書の版番号が 1.1 に更新された。

## 第 6.1 版から第 6.3 版へ

第 6.3 版から、よく知られたポートを利用した信号?(well known ports feature)を聴受するようになった。

## 附録 B. ICE X ランデヴ・プロトコル

## はじめに

二者のクライアントが ICE を介して通信するためには、通信確立に必要な情報を前以て交換する仕組みが要る、ということを第二章で述べた。ICE X ランデヴ・プロトコルはこの要求に応えるべく作られた。同一の X サーバに対して接続を持つ ICE クライアントであれば、何れの二者にもこのプロトコルを適用することができる。

## ICE X ランデヴの概要

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 下位プロトコルの版はクライアント・メッセージ・イベントに乗せて伝えることも可能であるが、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 のどんな関数も呼出す必要がない、という点に注意する。

入り口に戻る