Network Working Group Request for Comments: 2371 Category: Standards Track |
J. Lyon Microsoft K. Evans J. Klein Tandem Computers July 1998 |
このドキュメントは、インターネット社会の為のインターネット標準トラックプロトコルを規定しており、改善の為の議論と提案を求めている。このプロトコルの標準化の状態と状況については、"Internet Official Protocol Standards" (STD 1) の現在の版を参照されたい。このメモの配布は制限されない。
Copyright (C) The Internet Society (1998). All Rights Reserved.
異なるノードが幾つかの作業を協調する多くのアプリケーションでは、作業が原子的に起こることを保証する必要性がある。すなわち、各ノードはたとえ障害に直面しても、作業が完了したか否かについて同じ結論に達しなければならない。このドキュメントは、簡易な、この完了を容易に実装できるプロトコルを提案する。
Table of Contents
1. 導入
2. 利用例
3. トランザクション
4. コネクション
5. トランザクション識別子
6. プッシュ vs. プルトランザクション
7. TIP トランザクションマネージャー識別とコネクション確立
8. TIP ユニフォーム資源位置子
9. コネクションの状態
10.プロトコルバージョン
11.コマンドと応答
12.コマンドパイプライン
13.TIP コマンド
14.エラー処理
15.コネクション障害とリカバリ
16.セキュリティの考慮
17.参照
18.作者のアドレス
19.コメント
付録 A. TIP 多重化プロトコルバージョン 2.0
完全なコピーライト宣言
原子的コミットメントを達成するための標準的な方法は、2 フェーズコミットプロトコルである。原子的コミットメントと 2 フェーズコミットプロトコルについては [1] を参照されたい。
多数の 2 フェーズコミットプロトコルが、数年にわたって実装され続けている。しかし、主に複雑であるが故に、それらのどれもインターネットで広く使用されていない。その複雑性の大半は、2 フェーズコミットプロトコルが、特定のプログラムツープログラム通信プロトコルと一緒にまとめられ、そのプロトコルが非常に大規模な基盤の頂上に存在するという事実から来る。
このメモは、非常に簡易な 2 フェーズコミットプロトコルを提案する。異なるノードがトランザクションの結果にどのように同意するかだけを規定することによって、その簡易性を達成する。どのノードが同意しているかという主要点は、他のプロトコルを経て通信されることを可能にする (要求もする)。そうすることによって、アプリケーション通信セマンティクスとデータ表現 (2, 3 個命名するだけ) に関する全ての問題を避ける。アプリケーション通信プロトコルに依存せず、トランザクションマネージャーは他のトランザクションマネージャーと暗号メッセージを認証するために、トランスポート層セキュリティプロトコル [3] を使用してもよい。
このプロトコルは、あるインターネットノード上のトランザクションマネージャーが、別のノード上のトランザクションマネージャーと通信するために主に使用されるだろうと予測される。アプリケーションプログラムと資源マネージャーが、トランザクションマネージャーに話し掛けるためにこのプロトコルを使用できるが、この通信は大抵イントラノードであり、大半のトランザクションマネージャーは既にそのタスクに対する十分過ぎるインタフェースを持っている。
このプロトコルが既存のものを置き換えることは期待しないが、多くの既存の混成トランザクションマネージャーがお互いに通信するためにこのプロトコルを実装することが、比較的に容易であることは期待する。
TIP プロトコルに関連する補足情報については、[5] で見ることができる。
今日、電子買い物かごは多くの電子店舗において共通的な比喩である。消費者は電子カタログに目を通し、商品を選択し、それを電子買い物かごに入れる。HTTP サーバ [2] は、クライアントコンテキスト (例えば消費者の買い物かご) の足跡を保持し、後続の消費者要求を再開するために、URL 符号化からコンテキストクッキーにわたる様々な手段を提供する。
一旦消費者が買い物を終了したら、それらの選択をコミットし、交わした注文を確認する決定を下すかもしれない。大半の注文は、同じ買い物トランザクションの一部として実行されることを除いて、お互いに関係を持たない。あるいは、お互いに依存しているかもしれない (例えば、特殊な注文の一部として行われたならば)。これらの詳細にも関わらず、消費者は全ての注文が信頼のある確認レシートに正常に記入されることを期待するだろう今日の電子店舗は、そのような全ての注文の受領を調整するために、独自の特別なプロトコルを実装しなければならない。このプログラミングは、注文が複数の電子店舗を通じて受領される場合特に複雑である。この複雑性は、インターネットアプリケーションの潜在的な利便性を制限し、成長の制約となる。このドキュメントで規定されるプロトコルは、インターネットサーバが共有作業 (電子買い物かご中の注文の受領) の単位において、合意を達成するための標準を提供することを意図している。注文を受領するサーバ (例えば CGI プログラム) は、ローカルのトランザクションマネージャーを呼んでトランザクションを開始し、その作業に参加している他のサーバにそのトランザクションへの加入を求めたいかもしれない。注文を受領するサーバは、HTTP 要求のユーザデータとしてトランザクションへの参照を、他のサーバに渡す。他のサーバは、ローカルトランザクションを開始するためにトランザクションマネージャを呼び、このドキュメントで定義されたプロトコルを使用しているトランザクションに加わることを求める。一旦全ての注文が受領されたら、2 フェーズコミットプロトコルの実行が、関わりのあるトランザクションマネージャーに委任される。もしトランザクションがコミットしたら全ての注文が正常に受領され、消費者は信頼のある確認を得る。もしトランザクションがアボートしたら、どの注文も受領されず、消費者はその問題を通知されるだろう。
例外処理と障害回復が特別なコンポーネントに委任されるので、トランザクションはこれらのアプリケーションの非常に簡素なプログラミングをサポートする。さらに、エンドユーザは部分的な成功のみの結果を取り扱う必要はない。この例は、HTTP サーバがどのようにプロトコルを使用できるかを示すが、アプリケーションは遠隔データベースにアクセスする (例えば ODBC 経由) 時や、他の既存のプロトコル (例えば RPC) を使用する遠隔サービスを呼び出す際にこのプロトコルを使用してもよい。プロトコルは、混成のネットワークにあるアプリケーションが、たとえ異なる通信プロトコルを使用していても、同じトランザクションに参加することを容易にする。
"トランザクション" は、実行されるコンピュータの作業が原始的なセマンティクスを持つプログラミングモデルに与えられた用語である。すなわち、全ての作業が正常に完了し永久的な更新となる (トランザクションコミット) か、もしいずれかの作業が失敗したら更新されない (トランザクションアボート)。トランザクション (作業の単位) を構成する作業は、アプリケーションによって定義される。
トランザクションインターネットプロトコル (TIP) は、低いコネクション設定コストの、順番を信頼できるストリームトランスポートを必要とする。インターネット (IP) 環境では TIP は TCP 上で動作し、オプションで、安全で認証されたコネクションを提供するために TLS を使用する。またオプションで、同じ TCP か TLS コネクション上で軽量コネクションを多重化するためのプロトコルを使用する。
トランザクションを共有するトランザクションマネージャーは、TCP コネクション (オプションで TLS) を確立する。プロトコルは、2 つのトランザクションマネージャー間で共有された各々の同時トランザクションのために、異なるコネクションを使用する。トランザクションが終了した後、そのコネクションは異なるトランザクションで再使用できる。
オプションで、一つのトランザクションのみに TCP か TLS を割り当てる代わりに、2 つのトランザクションマネードャは同じ TCP か TLS コネクション上で、軽量コネクションを多重化するプロトコルに同意し、各々の同時トランザクションを別々の軽量コネクションに割り当ててもよい。軽量コネクションの使用は、冗長性と同時トランザクションの実行に割り当てられた資源消費を減らす。ここに記述されたものと同様の技術は、既存のトランザクション処理システムで広く使用されている。そうしたプロトコルの一つにの例として、付録 A を参照されたい。
TIP プロトコル自身は TCP と TLS の言葉で規定されているが、他のトランスポートプロトコルでの TIP の使用を除外するわけではないことに注意されたい。しかし、選択されたトランザクションが TCP と同等の意味を提供し、TIP プロトコルを適切にマッピングすることを保証することは、実装者の範疇である。
このドキュメントでは、"コネクション" または "TCP コネクション" という用語は TIP TCP コネクション、TIP TLS コネクション、あるいは TIP 多重コネクション (TCP か TLS 上の) のことを言う。各々のケースで振る舞いは同じであり相違は生まれない。コネクションのタイプ間の振る舞いには相違があるが、これらは明示的に言及される。
不幸にも、トランザクションと識別子の形式についてグローバルに受諾された標準が全く無く、様々な標準や専用形式がある。TIP トランザクション識別子で許された形式は、以下の "TIP ユニフォーム資源位置子" のセクションに規定されている。トランザクションマネージャーは、適切な方法でその内部トランザクションに識別子をこの TIP 形式にマッピングする。さらに、スーペリア/サブオーディネートの関係におけるグループはトランザクションに自身の識別子を割り当て、これらの識別子は関係が最初に確立される時に交換される。従って、トランザクションマネージャーはトランザクション識別子の自分自身の形式を内部的に使用する。しかし、関与している各々のスーペリア/サブオーディネートの関係に対して、相手のトランザクション識別子を覚えておかなければならない。
ノード "A" 上のあるプログラムがトランザクションを生成し、ノード "B" 上のあるプログラムにトランザクションの一部の作業を行うことを望むと仮定する。これを行うために二つの古典的な方法がある。"プッシュ" モデルと "プル" モデルと呼ばれるものである。
"プッシュ" モデルでは、A 上のプログラムは自分のトランザクションマネージャーに、ノード B にそのトランザクションのエクスポートすることを最初に依頼する。A のトランザクションマネージャーは B の TM にメッセージを送信し、A のサブオーディネートとしてトランザクションを実体化することを依頼し、そのトランザクションの名前を返却する。そして、A 上のプログラムは B 上の対応者にメッセージを送信し、"作業を実行し、そちらのトランザクションマネージャーが既に名前を知っているトランザクションに参加してほしい ..." 旨の指示を命ずる。A の TM はトランザクションを B の TM に送信したことを知っているので、A の TM は B の TM が 2 フェーズコミット処理に入ることを知る。
"プル" モデルでは、A 上のプログラムは "作業を実行し、そちらのトランザクションマネージャーが既に名前を知っているトランザクションに参加してほしい ..." 旨の指示を命ずるメッセージを B に単に送信するだけである。B 上のプログラムは、自分の TM にトランザクションへの参加を依頼する。その時、B の TM は A からトランザクションを "取り込む" だろう。この取り込みの結果、A の TM は B の TM が 2 フェーズコミット処理に入ることを知る。
ここで規定されたプロトコルは、"プッシュ" と "プル" モデルの両方をサポートする。
TIP トランザクションマネージャーが接続するために、お互いを識別し、所在を突き止められなければならない。これを行うために必要な情報は、TIP トランザクションマネージャーアドレスによって示される。
[この規約は、TIP トランザクションマネージャーが最初に獲得するトランザクションマネージャーアドレス (恐らく幾つかの実装特定の設定メカニズムを通じたものだろう) を規定しない。
TIP トランザクションマネージャーアドレスは以下の形式である。
<hostport><path>
<hostport> の要素は以下のように構成される。
<host>[:<port>]
<host> は <dns name> か <ip address> のいずれかであり、<port> はトランザクションマネージャー (あるいはプロクシ) が TIP コネクションの確立要求をリッスンしているポートを示す 10進数である。もしポート番号が省略されていたら、標準的な TIP ポート番号 (3372) が使用される。
<dns name> は標準的な名前であり、ドメイン名サービスで受け入れられる。それはコマンドの受信者に有効である資格を十分持つ。
<ip address> は IP アドレスで、一般的な形式: ピリオドの文字で区切られた 4 つの 10 進数である。
<hostport> の要素は <path> 要素の範囲 (場所) を定義する。
トランザクションマネージャーアドレスの <path> 要素は、<hostport> によって定義された場所にある特定の TIP トランザクションマネージャーを識別するデータを含む。
<path> 要素は以下の形式である。
"/" [path_segments] path_segments = segment *( "/" segment ) segment = *pchar *( ";" param ) param = *pchar pchar = unreserved | escaped | ":" | "@" | "&" | "=" | "+" unreserved = ASCII character octets with values in the range (inclusive): 48-57, 65-90, 97-122 | "$" | "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")" | "," escaped = "%" hex hex hex = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "A" | "B" | "C" | "D" | "E" | "F" | "a" | "b" | "c" | "d" | "e" | "f"
<path> 要素は、一つのスラッシュ "/" 文字で区切られたパスセグメントのシーケンスから成る。パスセグメントの中で、文字 "/", ";", "=", "?" は予約されている。各々のパスセグメントは、セミコロン ";" 文字によって指し示されるパラメタのシーケンスを含んでもよい。パラメタは、相対的な参照の解析には意味を持たない。
[トランザクションマネージャーアドレスの形式は、ユニフォーム資源識別子 (URI) [8] で提案されたスキームに従うことを意図している。]
従って、TIP トランザクションマネージャーアドレスは、コネクション起動者 (一次) に TCP コネクション (<hostport>) で使用される終点識別子を提供し、コネクション受信者 (二次) に特定の TIP トランザクションマネージャー (<path>) の位置を決めるパスを提供する。これは、一次と二次の TIP トランザクションマネージャー間で確立されるコネクションで必要な情報の全てである。
コネクションが確立された後、一次側は IDENTIFY コマンドを発行する。このコマンドは、一次側トランザクションマネージャーアドレスと二次側トランザクションマネージャーアドレスの 2 つのトランザクションマネージャーアドレスをパラメタで含む。
一次側トランザクションマネージャーアドレスは、コネクションを起動する TIP トランザクションマネージャーを識別する。この情報は、コネクションのいずれか一方が、2 フェーズコミットプロトコルを完了するために他方との新しいコネクションを再確立しなければならない時、コネクション障害後のあるケースにおいて必要である。もし一次側がコネクションの再確立を必要とするならば、そのジョブは容易であり、元のコネクションと同じ方法でコネクションが確立される。しかし、もし二次側がコネクションの再確立を必要とするならば、元のコネクションの起動側への接触方法を知らなければならない。この情報は、IDENTIFY コマンド上の一次側トランザクションマネージャーアドレスを通じて二次側に提供される。もし一次側トランザクションマネージャーアドレスが提供されないならば、一次側はコネクションの再確立を必要とする (すなわちリカバリ動作の実行) アクションを実行してはならない。
二次側トランザクションマネージャーアドレスは、受信側 TIP トランザクションマネージャーを識別する。中間プロクシサーバ経由の TIP 通信の場合、プロクシサーバはこの URL を要求された TIP トランザクションマネージャーを正しく識別し、接続するために使用してもよい。
トランザクションとトランザクションマネージャーは、TIP プロトコルに割り当てられた資源である。トランザクションマネージャーとトランザクションは、トランザクションマネージャーアドレススキームを使用して配置される。一旦コネクションが確立されたら、それぞれのトランザクションマネージャーに割り当てられたトランザクションを操作するために、TIP コマンドを送信してもよい。
リモートノードからトランザクションをプルしたいアプリケーションは、リモートトランザクションへの参照を提供しなければならない。その参照により、ローカルトランザクションマネージャー (すなわちトランザクションをプルするトランザクションマネージャー) は、リモートトランザクションマネージャーに接続し、特定のトランザクションを識別することが可能になる。トランザクションをリモートノードにプッシュしたいアプリケーションは、リモートトランザクションマネージャー (すなわちトランザクションがプッシュされるトランザクションマネージャー) への参照を提供しなければならない。その参照により、ローカルトランザクションマネージャーはリモートトランザクションマネージャーの位置を突き止めることが可能になる。TIP プロトコルは、アプリケーションとトランザクションマネージャーがトランザクションマネージャーやトランザクションへの参照を交換することを可能にする URL スキーム [4] を定義する。
TIP URL は以下の形式である。
tip://<transaction manager address>?<transaction string>
<transaction manager address> は、TIP トランザクションマネージャーを識別し (上記のセクション 7 で定義されているように)、<transaction string> はトランザクション識別子を指定する。以下の 2 つの形式のうちのどちらであってもよい。
i. "urn:" <NID> ":" <NSS>
標準的なトランザクション識別子。RFC
2142 で規定されている、ユニフォーム資源名 (URN) として提案されたインターネット標準に適合し、<NID>
は名前空間識別子であり、<NSS> は名前空間特定文字列である。名前空間
ID は、名前空間特定文字列の記法上の解釈を決定する。名前空間特定文字列は、トランザクション識別子
(<NID> で定義される) を表す文字列のシーケンスである。これらのフィールドの内容における規則は、[6]
で規定される (正しい文字、符号化等)。
<transaction string> のこの形式は標準的な表現で、グローバルトランザクション識別子を表現するために使用してもよい。<NID> の例は、<iso> か <xopen> である。例えば、
tip://123.123.123.123/?urn:xopen:xid
名前空間 ID は登録が必要である。これを行うための詳細は、[7] を参照されたい。
ii. <transaction identifier>
トランザクション識別子を表している表示可能な
ASCII 文字のシーケンス (":" を除く 32 〜 126 までの範囲の値を持つオクテット)。この非標準のケースでは、グローバルなユニーク性を保証するのは、<transaction
manager address> と <transaction identifier> の結合である。例えば、
tip://123.123.123.123/?transid1
トランザクション識別子から非標準の TIP URL を生成するには、最初にトランザクション識別子中の全ての予約文字を同等のエスケープシーケンスに置き換え、その後適切なトランザクションマネージャーアドレスを挿入する。もしトランザクション識別子が自分が生成したものならば、自分自身のトランザクションマネージャーアドレスを挿入する。もしトランザクション識別子が、自分で起動した TIP コネクション上で受信したものならば、IDENTIFY コマンドで送信した二次側トランザクションマネージャーアドレスを使用する。もしトランザクション識別子が、自分で起動しなかった TIP コネクション上で受信したものならば、IDENTIFY コマンドで受信した一次側トランザクションマネージャーアドレスを使用する。
TIP URL はグローバルな永久的なユニークさを保証しなければならない。このユニーク性制約は TIP URL が決して重複しないことを保証する。それにより、起こり得る決定的でない振る舞いを避けられる。どのようにユニーク性を達成するかは実装特定である。例えば、汎用ユニーク識別子 (UUID、さらにグローバルユニーク識別子、GUID ([9] 参照) としても知られる) を、<transaction string> の部分に使用することができる。ある標準的なトランザクション識別子は、グローバルなユニークを保証するための自身の規則 (例えば OSI CCR 原子動作識別子) を定義してもよいことに注意されたい。
上記で規定されたものを除いて、TIP URL スキームは [4] で定義された予約文字の規則に従い、[4] のセクション 5 で定義されているようにエスケープシーケンスを使用する。
TIP プロトコル自身は、TIP URL スキームを使用しないことに注意されたい (TIP プロトコルは、トランザクションマネージャーアドレススキームを使用する)。TIP URL スキームは、他のプロトコル、例えば協調アプリケーション処理、を通じてトランザクション識別子情報を渡すための標準的な方法として提案されている。TIP URL は、ローカルトランザクションマネージャーと、例えばトランザクションをリモートのトランザクションマネージャーからプルするために、アプリケーションをある特定の TIP トランザクションに割り当てるのに必要な情報を通信するために使用してもよい。各々の TIP 実装は、この目的のために API の幾つかのセットを提供する ([5] はそうした API の例を含む) ことが予想される。
どんな時でも、コネクションの一方の側だけがコマンドの送信を許され、他方の側は受信したコマンドに応答することが許されるだけである。このドキュメント全体で、コマンドの送信をやるされた側を "一次側" と呼び、他方の側を "二次側" と呼ぶ。最初に、コネクションを起動した側が一次側であるが、幾つかのコマンドによりこの役割が切り替わる。アイドル状態に達した時には常に、元の極に戻る。
多重化が使用される時は、根本のコネクション (多重化状態になっているだろう) の極に関わらず、これらの役割は各々の "仮想" コネクションに個別に適用される。
パイプラインを使用して、二次側は "帯域外" でコマンドを送信してもよい。これは、コネクションの極に影響しない (一次側と二次側の役割は切り替わらない)。詳細はセクション 12 を参照されたい。
通常のケースでは、初期状態の時 TIP コネクションは一次側だけがクローズすべきである。ある異常ケースでは必要になるかもしれないが、二次側によってコネクションがクローズされることは通常望ましくない。
如何なる時も、コネクションは以下の状態の一つである。二次側の観点では、応答を送信した時に状態は変わり、一次側の観点では、応答を受信した時に状態は変わる。
Initial:
初期コネクションは Initial
状態で開始される。この状態に入る際、コネクションを起動した側が一次側になり、他方の側が二次側になる。この状態でコネクションに割り当てられたトランザクションは存在しない。この状態から、一次側は
IDENTIFY か TLS コマンドを送信できる。
Idle:
この状態では、一次側と二次側はプロトコルバージョンを合意しており、一次側は二次側に障害後の再接続のために識別子を供給している。この状態でコネクションに割り当てられたトランザクションは存在しない。この状態に入る際、コネクションを起動した側が一次側になり、他方の側が二次側になる。この状態から、一次側は次のコマンドを送信できる:
BEGIN, MULTIPLEX, PUSH, PULL, QUERY, RECONNECT。
Begun:
この状態では、コネクションは活性トランザクションに割り当てられ、1
フェーズプロトコルによってのみ完了できる。BEGIN コマンドに対する
BEGUN 応答が、コネクションをこの状態に変える。Begun 状態でのコネクション障害は、トランザクションがアボートすることを意味する。この状態から、一次側は
ABORT か COMMIT コマンドを送信することができる。
Enlisted:
この状態では、コネクションは活性トランザクションに割り当てられ、1
フェーズプロトコルか 2 フェーズプロトコルによって完了できる。PUSH
コマンドに対する PUSHED 応答か、PULL コマンドに対する PULLED 応答がコネクションをこの状態に変える。Enlisted
状態でのコネクション障害は、トランザクションがアボートすることを意味する。この状態から、一次側は
ABORT か COMMIT か PREPARE コマンドを送信することができる。
Prepared:
この状態では、コネクションは準備されたトランザクションに割り当てられる。PREPARE
コマンドに対する PREPARED 応答か、RECONNECT コマンドに対する RECONNECTED
応答が、コネクションをこの状態に変える。他の状態とは異なり、この状態でのコネクション障害は、トランザクションを自動的にアボートさせない。この状態から、一次側は
ABORT か COMMIT コマンドを送信することができる。
Multiplexing:
この状態では、コネクションは多重化プロトコルによって使用され、それ自身のコネクションのセットを提供する。この状態では、そのコネクション上での
TIP コマンドは可能ではない。(無論、多重化プロトコルによって提供されたコネクション上では、TIP
コマンドは可能である)。コネクションは、この状態から抜けることはできない。
Tls:
この状態では、コネクションは
TLS プロトコルによって使用されており、それ自身の安全なコネクションを提供する。この状態では、そのコネクション上での
TIP コマンドは可能ではない。(無論、TLS プロトコルによって提供されたコネクション上では、TIP
コマンドは可能である)。コネクションは、この状態から抜けることはできない。
Error:
この状態では、プロトコルエラーが発生しコネクションがもはや有効でない。コネクションは、この状態から抜けることはできない。
このドキュメントは、プロトコルのバージョン 3 を規定している。将来のバージョンを適応するために、一次側は自身が理解する最小と最大のバージョン番号を示すメッセージを送信する。二次側は、自身が理解する最大のバージョンで応答する。
こうした交換を行った後、最大のバージョン番号のより小さいもの (すなわち、両方が理解できる最大のバージョン番号) を使用して通信を行うことできる。この交換は必須であり、IDENTIFY コマンド (と IDENTIFIED 応答) を使用して行う。
もし、一方の側でサポートされた最大のバージョン番号が廃止されたものと見なし、もう一方の側ではもはやサポートしていなければ、有効な通信を行うことはできない。この場合、より新しい側がコネクションを単に切断すべきである。
全てのコマンドと応答は、CR (13 の値を持つオクテット) か LR (10 の値を持つオクテット) が後ろに続く、32 〜 126 までの範囲の値を持つオクテットだけを使用した、ASCII テキストの 1 行で構成される。各行は 1 つ以上の "単語" に分割でき、連続した単語は 1 つ以上の空白オクテット (値 32) によって区切られる。
各行の開始と終端に任意の個数の空白を付与することは許されており、無視される。
空か全体的に空白から成る行は無視される。(これの一つの意味は、もし望むなら CR と LF の両方で行を終了できるということである。LF は空行の終了として扱われ、無視される)。
全てのケースにおいて、各行の最初のワードはコマンドや応答のタイプを示す。定義された全てのコマンドと応答は、英大文字のみから成る。
幾つかのコマンドと応答では、後続のワードはコマンドや応答に対するパラメタを運び、各々のコマンドや応答は固定数のパラメタを採る。
最初の未定義ワード (を含む) の後ろのコマンドや応答行上の全てのワードは、全て無視される。これらはデバッグや他の目的のために、人間が読める情報を渡すために使用できる。
通信の冗長性を減らし効率を改善するために、複数の TIP "行" (コマンドや応答) を一緒にパイプライン化 (連結) し、単一のメッセージとして送信することが可能である。(一次側によって後で処理するために、二次側によって) 行を "前に" 送信してもよい。例えば、ABORT コマンドの直後に続く BEGIN コマンドや、COMMITTED 応答の直後に続く PULL コマンドがそうである。
パイプライン行を送信することは、実装オプションである。どの行を一緒にパイプライン化するかについても同様である。通常、パイプライン化された行が、受信側によって処理される時のコネクションの状態に正当であることは明白でなければならない。これを決定することは送信側の責任である。
全ての実装体は、パイプライン化された行の受信をサポートしなければならない。その処理についての規則は、以下のパラグラフで規定される。
コネクション状態が一行を読める (コマンドか応答のいずれか) 状態である時、その行は (受信した時) 処理される。そのような状態に再び達するまで、コネクションから行は読まれない。もし、他方の側が送信する番ではない時に一行がコネクション上で受信されたら、その行は拒否しない。その代わりに、コネクション状態が再び行を必要とする時にそれを取り出して処理する。受信側は受信した行の順序で行を処理し、応答を発行しなければならない。もし行が異常を引き起こしたら、そのコネクションは Error 状態に入り、そのコネクション上の全ての後続行を破棄する。
コマンドは、コネクションかトランザクションのいずれかに関係する。コネクションに関係するコマンドは、IDENTIFY, MULTIPLEX, TLS である。トランザクションに関係するコマンドは、ABORT, BEGIN, COMMIT, PREPARE, PULL, PUSH, QUERY, RECONNECT である。
以下は全ての正しいコマンドの一覧であり、各コマンドに対する全ての可能な応答である。
このコマンドは Begun, Enlisted, Prepared 状態で有効である。これは、そのコネクションの現トランザクションをアボートすることを二次側に通知する。可能な応答は以下のものである。
ABORTED
トランザクションがアボートした。そのコネクションは
Idle 状態に入る。
ERROR
コマンドが無効な状態で発行されたか、不正な形式である。そのコネクションは
Error 状態に入る。
このコマンドは Idle 状態でのみ有効である。これは、新しいトランザクションを生成し、それをコネクションに割り当てることを二次側に依頼する。新たに生成されたトランザクションは、1 フェーズプロトコルで完了する。可能な応答は以下のものである。
BEGUN <トランザクション識別子>
新しいトランザクションが正常に開始され、そのトランザクションはコネクションの現トランザクションである。そのコネクションは
Begun 状態に入る。
NOTBEGUN
新しいトランザクションを開始できなかった。そのコネクションは
Idle 状態のままである。
ERROR
コマンドが無効な状態で発行されたか、不正な形式である。そのコネクションは
Error 状態に入る。
このコマンドは Begun, Enlisted, Prepared 状態で有効である。Begun か Enlisted 状態では、トランザクションをコミットする試みを二次側に依頼し、Prepared 状態では、トランザクションがコミットしたことを二次側に通知する。Enlisted 状態では、このコマンドは 1 フェーズプロトコルを表し、送信側が 1) トランザクションに関連するローカルな回復可能資源が無く、2) サブオーディネートが一つだけである (送信側は如何なるトランザクションリカバリ処理にも関係しないだろう) 時にのみ行われるべきであることに注意されたい。可能な応答は以下のものである。
ABORTED
この応答は、Begun と Enlisted
状態からのみ可能である。これはある側がトランザクションのコミットメントを拒否したことを示す。そして、トランザクションはコミットの代わりにアボートされた。そのコネクションは
Idle 状態に入る。
COMMITTED
この応答はトランザクションがコミットし、一次側がそのトランザクションに関して二次側への責任をもはや持たないことを示す。そのコネクションは
Idle 状態に入る。
ERROR
コマンドが無効な状態で発行されたか、不正な形式である。そのコネクションは
Error 状態に入る。
このコマンドは如何なる状態でも有効であり、前の応答が認識されなかったか不正な形式であったことを二次側に通知する。二次側はこのコマンドに対して応答すべきではない。そのコネクションは Error 状態に入る。
IDENTIFY |
<最小のプロトコルバージョン>
|
IDENTIFIED <プロトコルバージョン>
二次側は正常に接触し、一次側トランザクションマネージャーアドレスを保存した。この応答は、二次側によってサポートされている最大のプロトコルバージョンを含む。全ての将来の通信は、IDENTIFY
コマンドと IDENTIFIED 応答中のプロトコルバージョンのより小さいものを使用して行われると想定される。そのコネクションは
Idle 状態に入る。
NEEDTLS
二次側は TLS の保証付きコネクション上の通信だけを望んでいる。そのコネクションは
Tls 状態に入り、全ての後続の通信は TLS プロトコルによって定義されたように行われる。このプロトコルは、IDENTIFY
コマンドの行終端後の最初のオクテット (一次側によって送信されたデータ)
と NEEDTLS 応答の行終端後の最初バイト (二次側によって送信されたデータ)
から開始される。これは、実装体が IDENTIFY コマンドか NEEDTLS 応答のいずれかの後に、CR
と LF オクテットの両方を送信してはならないことを意味する。TLS
プロトコルの最初のバイトが LF オクテットであることは誤りである。TLS
プロトコルによって提供されるコネクションは、Initial 状態で始まる。TLS
が折衝された後、一次側は IDENTIFY コマンドを再送しなければならない。もし一次側が
TLS プロトコルをサポートできない (あるいは使用を拒否する) ならば、そのコネクションをクローズする。
ERROR
コマンドが無効な状態で発行されたか、不正な形式である。この応答は、二次側が一次側によってサポートされた範囲のプロトコルバージョンを全てサポートしていない場合でも発生する。そのコネクションは
Error 状態に入る。一次側はそのコネクションをクローズすべきである。
このコマンドは Idle 状態でのみ有効である。このコマンドは、既存のコネクション上で非常に数多くのコネクションを供給する、多重化プロトコルとしてコネクションを使用するための同意を求める。一次側は、ある特定の多重化プロトコルを提案する。二次側は、このプロトコルの使用を受諾するか拒否するかのいずれかを行うことができる。
現在、唯一定義済みのプロトコル識別子は "TMP2.0" であり、TIP 多重化プロトコル、バージョン 2.0 を指す。このプロトコルに関する詳細は、付録 A を参照されたい。将来、他のプロトコル識別子が定義されるかもしれない。
もし MULTIPLEX が受諾されたら、指定された多重化プロトコルは基礎的なコネクションを全体的に制御する。このプロトコルは、MULTIPLEX コマンドの行終端後の最初のオクテット (一次側によって送信されたデータ) と MULTIPLEXING 応答の行終端後の最初バイト (起動側によって受信されたデータ) から開始される。これは、実装体が MULTIPLEX コマンドか MULTIPLEXING 応答のいずれかの後に、CR と LF オクテットの両方を送信してはならないことを意味する。多重化プロトコルの最初のバイトが LF オクテットであることは誤りである。
TMP V2.0 を使用する時、単一の TIP コマンド (TMP アプリケーションメッセージ) は、単一の TMP パケットの中に完全に含まなければならないことに注意されたい (TMP PUSH フラグは TIP では使用しない)。MULTIPLEX コマンドに対する可能な応答は以下のものである。
MULTIPLEXING
二次側は、指定された多重化プロトコルの使用を同意する。そのコネクションは
Multiplexing 状態に入り、全ての後続の通信はそのプロトコルによって定義された通りに行われる。多重化プロトコルによって生成された全てのコネクションは、Idle
状態から開始される。
CANTMULTIPLEX
二次側は、指定された多重化プロトコルをサポートできない
(あるいは使用を拒否)。そのコネクションは、Idle 状態のままである。
ERROR
コマンドが無効な状態で発行されたか、不正な形式である。そのコネクションは
Error 状態に入る。
このコマンドは Enlisted 状態でのみ有効である。このコマンドは、二次側にトランザクションのコミットメントのための準備 (2 フェーズコミットのフェーズ 1) を要求する。可能な応答は以下のものである。
PREPARED
サブオーディネートはトランザクションを準備した。そのコネクションは
PREPARED 状態に入る。
ABORTED
サブオーディネートはトランザクションのコミットを拒否した。そのコネクションは
Idle 状態に入る。この応答の後、スーペリアはそのトランザクションに関する責任をサブオーディネートに対して持たない。
READONLY
サブオーディネートは、トランザクションがコミットするかアボートするかもはや気にしない。この応答の後、スーペリアはそのトランザクションに関する責任をサブオーディネートに対して持たない。
ERROR
コマンドが無効な状態で発行されたか、不正な形式である。そのコネクションは
Error 状態に入る。
PULL |
<スーペリアのトランザクション識別子>
|
PULLED
関係が確立された。この応答を受信した時、指定されたトランザクションはコネクションの現トランザクションになり、そのコネクションは
Enlisted 状態に入る。さらに、一次側と二次側の役割が逆転する。(すなわち、スーペリアはそのコネクションの一次側になる)。
NOTPULLED
関係は確立されなかった
(おそらく二次側が要求されたトランザクションを持っていなかったため)。そのコネクションは
Idle 状態のままである。
ERROR
コマンドが無効な状態で発行されたか、不正な形式である。そのコネクションは
Error 状態に入る。
このコマンドは Idle 状態でのみ有効である。このコマンドは、トランザクションにおいてスーペリア/サブオーディネートの関係を確立することを求め、コネクションの一次側はスーペリアになる。<トランザクション文字列> の全体の値 ("TIP ユニフォーム資源位置子" のセクションで規定) を、トランザクション識別子として指定しなければならない。可能な応答は以下のものである。
PUSHED <サブオーディネートのトランザクション識別子>
関係が確立され、サブオーディネートがそれによってトランザクション認識する識別子を返却する。トランザクションはコネクションの現トランザクションになり、そのコネクションは
Enlisted 状態に入る。
ALREADYPUSHED <サブオーディネートのトランザクション識別子>
関係が確立され、サブオーディネートがそれによってトランザクション認識する識別子を返却する。しかし、サブオーディネートはそのトランザクションを既に認識しており、2
フェーズコミットプロトコルが異なるコネクションを経由して到達することを期待している。この場合、そのコネクションは
Idle 状態のままである。
NOTPUSHED
関係が確立できなかった。そのコネクションは
Idle 状態のままである。
ERROR
コマンドが無効な状態で発行されたか、不正な形式である。そのコネクションは
Error 状態に入る。
このコマンドは Idle 状態でのみ有効である。サブオーディネートは、特定のトランザクションがまだスーペリア側に存在するか否かを決定するために、このコマンドを使用する。可能な応答は以下のものである。
QUERIEDEXISTS
トランザクションがまだ存在している。そのコネクションは
Idle 状態のままである。
QUERIEDNOTFOUND
トランザクションはもう存在しない。そのコネクションは
Idle 状態のままである。
ERROR
コマンドが無効な状態で発行されたか、不正な形式である。そのコネクションは
Error 状態に入る。
このコマンドは Idle 状態でのみ有効である。スーペリアは、前のコネクションが Prepared 状態中に消失した時、トランザクションのためのコネクションを再確立するためにこのコマンドを使用する。可能な応答は以下のものである。
RECONNECTED
サブオーディネートは再確立を受諾する。そのコネクションは
Prepared 状態に入る。
NOTRECONNECTED
サブオーディネートは、そのトランザクションをもはや知らない。そのコネクションは
Idle 状態のままである。
ERROR
コマンドが無効な状態で発行されたか、不正な形式である。そのコネクションは
Error 状態に入る。
このコマンドは Initial 状態でのみ有効である。一次側は、TLS を使用してセキュリティを考慮したコネクションの確立を試みるために、このコマンドを使用する。
もし TLS コマンドが受諾されたら、TLS プロトコルは基礎的なコネクションを全体的に制御する。このプロトコルは、TLS コマンドの行終端後の最初のオクテット (一次側によって送信されたデータ) と TLSING 応答の行終端後の最初バイト (一次側によって受信されたデータ) から開始される。これは、実装体が TLS コマンドか TLSING 応答のいずれかの後に、CR と LF オクテットの両方を送信してはならないことを意味する。TLS プロトコルの最初のバイトが LF オクテットであることは誤りである。
TLS コマンドに対する可能な応答は以下のものである。
TLSING
二次側は、TLS プロトコル [3]
の使用を同意する。そのコネクションは Tls 状態に入り、以降の全ての通信は
TLS ロトコルによって定義された通りに行われる。TLS プロトコルによって提供された全てのコネクションは、Initial
状態から開始される。
CANTTLS
二次側は、TLS プロトコルをサポートできない
(あるいは使用を拒否)。そのコネクションは、Initial 状態のままである。
ERROR
コマンドが無効な状態で発行されたか、不正な形式である。そのコネクションは
Error 状態に入る。
もしいずれかの側が理解できない行を受信したら、そのコネクションをクローズする。もしいずれかの側 (コマンドか応答のいずれか) がコネクション上で ERROR 指示か ERROR 応答を受信したら、そのコネクションは Error 状態に入り、そのコネクション上で更に通信を行うことはできない。実装体はコネクションをクローズしてもよい。コネクションのクローズは、他方の側によって通信障害として扱われる。
ERROR 指示か ERROR 応答の受信は、他方の側があなたはプロトコルを適切に実装していないと思っていることを示す。
コネクション障害は、通信障害やいずれかの側がコネクションをクローズすることにより引き起こされるかもしれない。TIP 実装体は、TIP コネクション障害を検出するために私的なメカニズム (例えばソケットキープアライブやタイムアウトスキーム) を使用すると想定される。
コネクションの状態によって、コネクション障害時に、トランザクションマネージャーは様々な動作を行う必要があるだろう。
もしコネクションが Initial か Idle 状態で障害になったら、そのコネクションはトランザクションを参照していない。何の動作も必要ない。
もしコネクションが Multiplexing 状態で障害になったら、多重化プロトコルによって提供された全てのコネクションが失敗したと想定される。その各々が独立して処理される。
もしコネクションが Begun か Enlisted 状態で COMMIT が送信された後で障害になったら、トランザクションの完了がサブオーディネートに委任され (スーペリアは関係していない)、スーペリアはトランザクションの結果を知らない (サブオーディネートは知っている)。スーペリアは、トランザクションの結果を決定するためにアプリケーション特定の手段を使用する。(スーペリアはそのトランザクションに関係する回復可能な資源を持っていないので、この場合トランザクションの完全性について妥協しない)。もしコネクションが Begun か Enlisted 状態で COMMIT が送信される前に障害になったら、そのトランザクションはアボートするだろう。
もしコネクションが Prepared 状態で障害になったら、スーペリアとサブオーディネートで適切な動作が異なる。
もしスーペリアがトランザクションのコミットを決定したら、最終的に新しいコネクションをサブオーディネートに確立しなければならず、そのトランザクションに対して RECONNECT コマンドを送信する。もしスーペリアが NOTRECONNECTED 応答を受信したら、他に何も行う必要はない。しかし、もし RECONNECTED 応答を受信したら、スーペリアは COMMIT 要求を送信し、COMMITTED 応答を受信しなければならない。
もしスーペリアがトランザクションのアボートを決定したら、新しいコネクションを確立して、そのトランザクションに対する RECONNECT コマンドを送信してもよい (が、必要ではない)。もしスーペリアが RECONNECTED 応答を受信したら、ABORT コマンドを送信すべきである。
上記の定義は、もし都合が良ければ、スーペリアがトランザクションの結果を知る前にコネクションを再確立することを可能にする。RECONNECT コマンドが成功したら、そのコネクションは Prepared 状態に戻り、トランザクションの結果が分かった時に、スーペリアは適宜 COMMIT か ABORT コマンドを送信することができる。
サブオーディネートは、前のコネクションが障害になったことを認識する前に、RECONNECT コマンドを受信する可能性があることに注意されたい。この場合、サブオーディネートは RECONNECT 応答を障害指示として扱い、そのコネクションに関連する資源を一掃し、トランザクション状態を新しいコネクションに割り当てる。
もしサブオーディネートが、Prepared 状態でコネクション障害を検出したら、サブオーディネートはスーペリアへの新しいコネクションの生成を定期的に試み、そのトランザクションに対して QUERY コマンドを送信すべきである。サブオーディネートは、以下の二つのイベントの一つが発生するまでこれを継続すべきである。
もし TIP システムが QUERY か RECONNECT コマンドのいずれかを受信し、ある理由によりその要求を満足することができない (例えば、必要なリカバリ情報が現在利用できない) ならば、そのコネクションを落とすべきであることに注意されたい。
このセクションは、アプリケーション開発者やトランザクション開発者、及びユーザに、このドキュメントによって示された TIP のセキュリティの意味を知らせることを意図している。セキュリティリスクを減らすために幾つかの提案を行っているが、この議論は記述された問題に対する決定的な解決方法を含んでいない。
全ての 2 フェーズコミットプロトコルのように、対応するメカニズムが通信プロトコルに適用されなければ、アプリケーション通信プロトコルに適用されるセキュリティメカニズムは覆され易い。例えば、アプリケーションプロトコルを使用する側の間での認証では、少なくとも確実性の同じレベルへの TIP 交換のセキュリティをサポートしなければならない。
TLS はオプションのクライアント側認証、オプションのサーバ側認証、オプションのパケット暗号化を提供する。
TIP 実装体は、もし TLS が使用されなければサービスの提供を拒否してもよい。もしパケット暗号化が使用されなければ、サービスの提供を拒否してもよい。もしリモート側が認証されなかったら (TLS を経て)、サービスの提供を拒否してもよい。
TIP 実装体は自身の (TLS による )認証を望むべきである。これは、実装体がクラテアントとして動作するのでも、サーバとして動作するのでも真である。
一旦リモーと側が認証されたら、TIP トランザクションマネージャーは、どの操作を許可するかを決定するために、そのリモート側の識別子を使用してもよい。
コネクション上で TLS を使用するか否か、そしてもし使用するならどのように TLS を使用するか、またその後何の操作を許すかについては、TIP トランザクションマネージャーをお互いに接続するセキュリティ指針によって決定される。どのようにこれらのセキュリティ指針を決定するか、そしてどのように TIP トランザクションマネージャーがそれよを認識するかについては、実装にとっては全て私的事項であり、このドキュメントのスコープ外である。
悪意のあるユーザが、あるトランザクションマネージャーで現在活性中のトランザクションの識別子を知っていると仮定する。もし悪者がトランザクションマネージャーへの TIP コネクションをオープンし、PULL コマンドを送信し、そのコネクションをクローズすると、そのトランザクションをアボートさせることができる。結果的に、トランザクションの正当な所有者に対してサービスの拒否を引き起こす。
もし TLS を使用しない、あるいはリモード側が認証されていない、あるいはリモート側が承認されていないならば、実装体は PULL コマンドを拒否することによってこの攻撃を回避してもよい。
トランザクションが Prepared 状態の間に、二つのトランザクションマネージャー間のコネクションがクローズされると、各々のトランザクションマネージャーは、コネクションが再確立できるまでトランザクションについての情報を覚えておく必要がある。
もし悪意のあるユーザが、この事実を利用して繰り返しトランザクションを生成し、Prepared 状態にしてコネクションを落としたら、トランザクションマネージャーがリソースの疲弊に陥るかもしれない。結果、そのトランザクションマネージャーの全ての正当なユーザに対して、サービスが拒否される。
もし TLS を使用しない、あるいはリモード側が認証されていない、あるいはリモート側が承認されていないならば、実装体は PUSH コマンドを拒否することによってこの攻撃を回避してもよい。
もしサブオーディネートトランザクションマネージャーが、ある特定の準備されたトランザクションのためのコネクションを失ったら、悪意のあるユーザはトランザクションマネージャーへの TIP コネクションを起動し、そのトランザクションのための RECONNECT コマンド、続いて COMMIT か ABORT コマンドを送信することができる。従って、アボートさせるべき場合に、悪意のあるユーザがトランザクションの一部をコミット等をさせることができる。
実装体は、トランザクション中のスーペリアの認証された識別子を記録し、もし TLS を使用しない、あるいはリモード側の認証された識別子が元のスーペリアの識別子と同一でないならば RECONNECT コマンドを拒否することによって、この攻撃を回避してもよい。
もし悪意のあるユーザが TIP コネクション上のトラフィックを捕捉できるならば、別の攻撃を計画する際に有効な情報を推論できるかもしれない。例えば、もしコメントフィールドにトランザクションマネージャーの製品名とバージョン番号が含まれているならば、悪意のあるユーザはその実装体に何のセキュリティバグが存在するかを決めるのに、この情報を使用できるかもしれない。
実装体はセション暗号化を提供する TLS を常に使用し、TLS/TLSING コマンド/応答のペアに所有者を示す情報を含めないことによって、この攻撃を回避してもよい。
もし悪意のあるユーザが TIP コネクション上のトラフィックを捕捉し、変更できるならば、数多くの方法で破壊をもたらすことができる。例えば、COMMIT コマンドを ABORT コマンドに置き換えることができるだろう。
実装体は、セション暗号化とリモート側の認証を提供する TLS を常に使用することによって、この攻撃を回避することができる。
[1] Gray, J. and A. Reuter (1993), Transaction Processing: Concepts and Techniques. San Francisco, CA: Morgan Kaufmann Publishers. (ISBN 1-55860-190-2).
[2] Fielding, R., Gettys, J., Mogul, J., Frystyk, H., and T. Berners-Lee, "Hypertext Transfer Protocol -- HTTP/1.1", RFC 2068, January 1997.
[3] Dierks, T., et. al., "The TLS Protocol Version 1.0", Work in Progress.
[4] Berners-Lee, T., Masinter, L., and M. McCahill, "Uniform Resource Locators (URL)", RFC 1738, December 1994.
[5] Evans, K., Klein, J., and J. Lyon, "Transaction Internet Protocol - Requirements and Supplemental Information", RFC 2372, July 1998.
[6] Moats, R., "URN Syntax", RFC 2141, May 1997.
[7] Faltstrom, P., et. al., "Namespace Identifier Requirements for URN Services", Work in Progress.
[8] Berners-Lee, T., et. at., "Uniform Resource Identifiers (URI): Generic Syntax and Semantics", Work in Progress.
[9] Leach, P., and R. Salz, "UUIDs and GUIDs", Work in Progress.
Jim Lyon Microsoft Corporation One Microsoft Way Redmond, WA 98052-6399, USA Phone: +1 (206) 936 0867 Fax: +1 (206) 936 7329 EMail: JimLyon@Microsoft.Com
Keith Evans Tandem Computers, Inc. 5425 Stevens Creek Blvd Santa Clara, CA 95051-7200, USA Phone: +1 (408) 285 5314 Fax: +1 (408) 285 5245 EMail: Keith.Evans@Tandem.Com Johannes Klein Tandem Computers Inc. 10555 Ridgeview Court Cupertino, CA 95014-0789, USA Phone: +1 (408) 285 0453 Fax: +1 (408) 285 9818 EMail: Johannes.Klein@Tandem.Com
このドキュメントに対するコメントは作者 (<JimLyon@Microsoft.Com>, <Keith.Evans@Tandem.Com>, <Johannes.Klein@Tandem.Com>) か、TIP メーリングリスト (<Tip@Lists.Tandem.Com>) に送信されたい。TIP メーリングリストには、メッセージ本体のどこかに "subscribe tip <full name>" という行を含んだメールを <Listserv@Lists.Tandem.Com> に送信することによって購読できる。
この付録は、TIP 多重化プロトコル (TMP: TIP Multiplexing Protocol) のバージョン 2.0 を規定している。TMP は TIP プロトコルと単独で使用することを意図しており、TIP プロトコル規定の一部を形成している。TMP V2.0 は、TIP V3.0 によってサポートされた多重化プロトコルのみである。
TMP は、単一の TCP コネクション上に複数の軽量コネクションを生成するための単純なメカニズムを提供する複数のそうした軽量コネクションは同時に活性化することができる。TMP はバイト型のサービスを提供するが、メッセージの境界線のマーキングを可能にしている。
各々のトランザクションのために単一の TCP コネクションを生成するために、インターネット上で広く使用されている幾つかのプロトコルが存在する。不幸にもこれらのトランザクションは短命であるため、使用される資源と TCP の輻輳制御メカニズムに関連する遅延の両方に関して、これらの TCP コネクションを設定したり解放するコストが重要になる。
TIP 多重化プロトコル (TMP) は TCP の最上位で動作する単純なプロトコルであり、複数の軽量コネクションを単一のトランスポートコネクション上で使用できる。従って TMP は TCP コネクションのより効率的な利用を提供する。複数の TMP コネクションからのデータを挟むことができ、メッセージの境界線とストリームマーカの終端の両方を提供できる。
TMP は信頼できるバイト順番のトランスポートサービスの最上位で動作するので、TCP が信頼性を保証するために行わなければならない追加作業の大半を避けることができる。例えば、TMP コネクションは確認が不要なので、データを送信する前に完了の同期をとるために待つ必要が無い。
注記: TMP は多重化プロトコルを一般化することを意図してはいない。もし多重化を必要とする異なるプロトコルを設計するならば、TMP は適切かもしれないし不適切かもしれない。大きいメッセージを持つプロトコルは受信側のバッファ容量を超えることがあり得、ある条件下においてこれはデットロックを引き起こし得る。TIP は要求-応答のプロトコルであり、全てのメッセージは短いので、TMP を TIP と一緒に使用する場合、この問題を被ることはない。
基本的なプロトコルモデルは、信頼できるバイトストリーム上で処理する複数の軽量コネクションのモデルである。コネクションを起動する側は一次側と呼ばれ、コネクションを受諾する側は二次側と呼ばれる。
コネクションは片方向でも両方向でもよく、両方向コネクションの終端は別々にクローズしてもよい。コネクションは正常にクローズしてもよいし、異常解放を示すためにリセットしてもよい。コネクションのアボートは、両方のデータストリームをクローズする。
一旦コネクションがオープンされたら、アプリケーションはそのコネクション上にメッセージを送信し、アプリケーションレベルのメッセージの終端を通知することができる。アプリケーションメッセージは TMP パケットにカプセル化され、バイトストリーム上で転送される。単一の TIP コマンド (TMP アプリケーションメッセージ) は、単一の TMP パケット内に全体を含めなければならない。
TMP パケットは、0 個以上のデータのオクテットが続く 64 ビットのヘッダから構成される。ヘッダは、フラグバイト、コネクション識別子、パケット長の三つのフィールドを含む。コネクション識別子とパケット長はどちらも整数であり、ネットワークバイトオーダで送信しなければならない。
フラグ +--------+--------+--------+--------+ |SFPR0000| Connection ID | +--------+--------+--------+--------+ | | Length | +--------+--------+--------+--------+
名前 | マスク | 説明 |
SYN FIN PUSH RESET |
1xxx|0000 x1xx|0000 xx1x|0000 xxx1|0000 |
新しいコネクションをオープンする 既存のコネクションをクローズする アプリケーションレベルのメッセージ境界をマークする コネクションをアボートする |
各々の TMP コネクションは、24 ビット整数によって識別される。元になる TCP コネクションを起動した側によって生成された TMP コネクションは識別子を持たなければならず、他方の側によって生成されたコネクションは片方の識別子を持たなければならない。
TMP コネクションは複数の異なる状態、Closed, OpenWrite, OpenSynRead, OpenSynReset, OpenReadWrite, CloseWrite, CloseRead、で存在することができる。コネクションは SYN, FIN, RESET ビットを持ったパケットの受信に対する応答か、アプリケーションによって呼ばれた API に対する応答で、その状態を変更できる。利用可能な API 呼びだしは、オープン、クローズ、アボートである。
大半の状態の意味は明白である (例えば OpenWrite は、コネクションが書き込みのためにオープンされたことを意味する)。OpenSynRead と OpenResetRead の意味については、より詳細な説明が必要である。
OpenSynRead 状態では、一次側がコネクションの出力データストリームをオープンして、即座にクローズし、読み込むための入力データストリームをオープンするための二次側からの SYN 応答を待っている。
OpenResetRead 状態では、一次側がコネクションをオープンして、即座にアボートし、最終的にコネクションをクローズするための二次側からの SYN 応答を待っている。
以下に表される状態表は、与えられたイベントに対する応答で発生するアクションと状態遷移を示している。各状態で受け入れられるイベントは、優先度の最も高いものが一番最初に現れるよう優先度順でリスト化されている。もし一つのメッセージに複数のイベントが提供されたら、リストに一致するイベントが処理される。もし複数のイベントが一致したら、最も高い優先度を持つイベントが受け入れられ、一番最初に処理される。残りのイベントは全て、結果的に後続する状態で処理される。
例えば、もし 二次側の TMP コネクションが Closed 状態にあり、二次側が SYN イベント、FIN イベント、入力データイベント (例えば DATA-IN) を含むパケットを受信したら、二次側は最初に SYN イベントを受け入れる (それは Close 状態で唯一一致するので)。二次側はコネクションを受諾し、SYN イベントを送信して ReadWrite 状態に入る。SYN イベントは未処理のイベントのリストから除去される。残りのイベントは FIN と DATA-IN である。ReadWrite 状態で、二次側は入力データを読む (DATA-IN イベントは FIN イベントよりも高い優先度を持っているので、DATA-IN イベントが最初に処理される)。一旦データが読み込まれ、DATA-IN イベントが未処理イベントのリストから除去されたら、FIN イベントが処理され、二次側は CloseWrite 状態に入る。
もし二次側が SYN イベントを含んでいるパケットを受信し、ある理由 (例えば資源不足) によりそのコネクションを受け入れられないならば、二次側は SYN イベントと、それに続く RESET イベントを送信することによって拒否すべきである。両方のイベントは同じ TMP パケットの一部として送信できることに注意されたい。
いずれかの側が理解できない TMP パケットか、不正な状態であるイベントを受信したら、TCP コネクションをクローズする。
エントリ状態 | イベント | アクション | 次の状態 |
Closed | SYN OPEN |
SYN SYN |
ReadWrite OpenWrite |
OpenWrite | SYN WRITE CLOSE ABORT |
Accept DATA-OUT FIN RESET |
ReadWrite OpenWrite OpenSynRead OpenSynReset |
OpenSynRead | SYN | Accept | CloseRead |
OpenSynReset | SYN | Accept | Closed |
ReadWrite | DATA-IN FIN RESET WRITE CLOSE ABORT |
Accept Accept Accept DATA-OUT FIN RESET |
ReadWrite CloseWrite Closed ReadWrite CloseRead Closed |
CloseWrite | RESET WRITE CLOSE ABORT |
Accept DATA-OUT FIN RESET |
Closed CloseWrite Closed Closed |
CloseRead | DATA-IN FIN RESET ABORT |
Accept Accept Accept RESET |
CloseRead Closed Closed Closed |
TMP イベント優先度と状態遷移
Copyright (C) The Internet Society (1998). All Rights Reserved.
This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to the Internet Society or other Internet organizations, except as needed for the purpose of developing Internet standards in which case the procedures for copyrights defined in the Internet Standards process must be followed, or as required to translate it into languages other than English.
The limited permissions granted above are perpetual and will not be revoked by the Internet Society or its successors or assigns.
(このドキュメントと翻訳は全体または一部を、如何なる種類の制限無しで、上記のコピーライト記述を提供し、このパラグラフを全てのコピーや派生作業に含めて、他者へコピーや供給してもよく、コメントしたり、別途説明したり、実装を援助するといった派生作業を準備、コピー、出版、配布してもよい。しかし、このドキュメント自身は、インターネット標準プロセスで定義された手続きに従わなければならず、インターネット標準を開発する目的で必要な場合や、英語以外の言語に翻訳するために必要な場合を除いて、コピーライト記述やインターネット社会、他のインターネット組織への参照等を、如何なる方法でも修正してはならない。
上記で認められた制限された許可は永久的であり、インターネット社会や継承者や割当て者によって無効にされることはないだろう。)
This document and the information contained herein is provided on an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.