CFI

X-Seqno: 5862
To: delegate@etl.go.jp
From: ysato@etl.go.jp (Yutaka Sato =?ISO-2022-JP?B?GyRAOjRGI0stGyhK?=)
Subject: [DeleGate] CFI 1.0 (parts of draft-ver.2)
Date: Fri, 5 Sep 97 16:37:15 JST
Organization: Electrotechnical Laboratory, Tsukuba Science City
Lines: 292
Message-Id: 
References: 
Mime-Version: 1.0 (generated by vin2.0)
Content-Type: text/plain; charset=ISO-2022-JP

あれれー、これって 09/01 にポストしたんですが、出て来てないように見えます。
Data: が古かったせいではねられたんですかね。Date を切って再送してみます。
--

In message  on 08/31/97(21:21:33) I wrote:
 |あー、ごめんなさい。(書きかけの CFI のドキュメントではこう書いてた

というのも勘違いで、ドキュメントには Output-Header とありました(^_^;

最近、仕事でCFIを使ってみようかという方(学情のAせんせ、電総研のT氏他)
がいらっしゃることもあり、8月中旬に一旦仕様書を兼ねてドキュメントを書き
かけたのですが、その後またどたばたしていて中断しています。このまま腐って
しまうのも可哀想なので、読解可能な部分を抜粋して公開します。

---------------------------------------------------------------------------
CFI: The Common Filter Interface for Application Level Gateway Systems
(書きかけ)

佐藤豊 電子技術総合研究所情報アーキテクチャ部
Yutaka Sato, Computer Science Division, Electrotechnical Laboratory
 http://www.etl.go.jp/~ysato/
1997/08/15

多目的応用プロトコルゲートウェイ「DeleGate」では利用者の手による機能の付加・
拡張を支援するための「外部フィルタ」と呼ぶ機能を提供している。これは利用者が
用意したプログラムをDeleGateとクライアント、あるいはサーバとDeleGateとの間の
通進路上に挿入し、その通進路上を流れるデータをフィルタ(変換・加工等)するこ
とにより、利用者が必要とする付加機能を実現するものである。

また、入力データやクライアントの種別等の条件に応じて適用すべきフィルタを選択
し実行を制御するために、CFI(Common Filter Interface)と呼ぶインターフェ
イスを提供している。これは単純な構文のスクリプト言語により、フィルタの選択、
フィルタプログラムに渡す実行環境の制御、および基本的なデータ変換機能を提供す
るものである。

入力を加工して出力するフィルタという単純で汎用のインターフェイスを用いること
によって、既存のプログラムを変更せずにそのまま利用することができ、また新たに
フィルタプログラムを開発する際にも特別な知識や手順を何ら必要としない。外部フ
ィルタ機能とCFIの組合せにより、簡便にして強力な拡張支援機能が提供され、
実際に様々な応用が行われている。CFIそのものはDeleGateの機能や実装に依存せ
ず、プロキシシステム一般で利用できることを意図して設計されたインターフェイス
仕様である。


1. 外部フィルタの種類

図1に示すように、フィルタを挿入できる位置はクライアント(CL)とDeleGate(DG)と
の間、サーバ(SV)とDeleGateとの間、あるいは「上流」の"Master"-DeleGate(MD)と
DeleGateとの間の通進路である。フィルタによる中継の方法には2つの種類があり、
双方向に中継を行うフィルタ(FCL,FMD,FSV)と、一方向のみの中継を行うフィルタが
ある。

   +----+            +----+                  +----+            +----+
   |    +-- FFROMCL ->    +- FTOMD -->    --->    +- FTOSV ---->    |
   |    |            |    |                  |    |            |    |
   |    |            |    |                  |(MD)|            |    |
   | CL <====== FCL => DG <= FMD ====>    ===> DG <= FSV ======> SV | 
   |    |            |    |                  |    |            |    |
   |    |            |    |                  |    |            |    |
   |    <---- FTOCL -+    <- FFROMMD -    ---+    <- FFROMSV --+    |
   +----+            +----+                  +----+            +----+

   図1. Locations of filters

   FCL      // クライアントとの間の送受信データ(双方向)
   FFROMCL  // クライアントから受信するデータ
   FTOCL    // クライアントへ送信するデータ
   FSV      // サーバとの間の送受信データ(双方向)
   FTOSV    // サーバへ送信するデータ
   FFROMSV  // サーバから受信するデータ
   FMD      // 上流DeleGateとの間の送受信データ (DeleGateプロトコル)(双方向)
   FTOMD    // 上流DeleGateへ送信するデータ (DeleGateプロトコル)
   FFROMMD  // 上流DeleGateから受信するデータ (DeleGateプロトコル)


--(読解不能のため中略)--


1.2 簡単な利用例

まず、簡単な利用例を示して、外部フィルタと CFI の機能を概観する。以下では、
応用プロトコル上で転送されるデータの単位をメッセージと呼ぶ。クライアントから
サーバへ送られるメッセージを要求メッセージ、サーバからクライアントへ送られる
メッセージを応答メッセージと呼ぶ。いくつかのプロトコル(NNTP,POP,SMTP,HTTP等)
では、メッセージ形式はRFC822形式(あるいはその拡張仕様であるMIME形式)に基
づいており、ヘッダ部とボディ部から構成されている。
即ち、要求コマンド行[+データ(MIME形式)]、応答コード行[+データ(MIME形式)」
のような形式である。

(1) 文字コード変換

DeleGate自体はサーバへ接続した後双方向の透過中継だけを行い、FTOCL パラメタで
指定したフィルタプログラム(ja2eucとする)により、クライアント向けの文字コー
ドを EUC に変換する。

  % delegated -P8119 FTOCL="ja2euc" SERVER=tcprelay://poppserver:110/

この例では CFI は利用しておらず、アプリケーションプロトコル(ここではPOP)上
を流れる全ての転送データ(制御メッセージを含む)が変換プログラムを通過するが、
変換の対象となるデータはユーザデータ中にしか現れず、また変換によりデータ長が
変動しても問題ないため、実用に足る。実際には、DeleGateは文字コード変換機能を
組み込みのフィルタとして持っているので、内部で処理できる(FTOCL=-eucとする)

(2) メッセージヘッダの削除(HTTP要求ヘッダフィールドの削除)

組織外部のサーバに接続する時などに、組織内部の情報がサーバに送られてしまうこ
とを防ぎたいことがある。例えば、HTTPのRefererフィールドなどである。DeleGate
をHTTPプロキシとして動作させ、クライアントからサーバへ送られたHTTP要求ヘッダ
のうち、Refererフィールドを削除する。ここでFTOSVに指定した tosv.cfi ファイル
は、非常に簡単な CFI スクリプトの例である。

  % delegated  -P8080 FTOSV="tosv.cfi" SERVER=http

  tosv.cfiの内容:
  #!cfi                           ## 以下がCFIスクリプトであることの目印
  Remove/Referer:                 ## ヘッダ中のRefererフィールドを削除する
  Remove/fieldName: pattern       ## patternにマッチするフィールド削除する

"Remove/フィールド名" という行は、指定されたフィールドを削除して中継すること
を指示している。フィールド値を指定すれば、そのフィールド値のパターンにマッチ
する値を持つフィールドを削除する。

(3) メッセージボディの変換(HTTP応答メッセージ中の画像データ変換)

DeleGateをHTTPプロキシとして動作させ、クライアント向けの画像データ形式のうち
GIF 形式で無いものを GIF に変換する例である。FTOCLに指定したCFIスクリプト
tocl.cfi は、「--」という行で区切られた2つの要素スクリプトを含んでいる。
CFIスクリプトは先頭から走査され、条件に適合するスクリプトがあった時、それを
実行して終了する。

  % delegated -P8080 FTOCL="tocl.cfi" SERVER=http

  tocl.cfiの内容:
  #!cfi
  Content-Type: image/x-xbitmap    ## データのContent-Typeがxbitmap型の時
  Filter: xbitmap2gif              ## データをGIF形式に変換し
  Output/Content-Type: image/gif   ## Content-TypeフィールドをGIFに設定
  --
  User-Agent: Mosaic               ## User-AgentがMosaicであり
  Content-Type: image/jpeg         ## データがJPEG形式である時
  Filter: jpeg2gif                 ## データをGIF形式に変換し
  Output/Content-Type: image/gif   ## Content-TypeにGIFを設定する

HTTPのメッセージは、ヘッダ部とボディ部からなる。ヘッダ部ではボディ部に含まれ
るデータの型などのメタ情報を記述し、ボディ部はデータ自体である。
Filterで指定したプログラムに渡されるのはボディ部のデータ本体だけであり、その
データを扱う既存のプログラムをそのまま利用して変換を行うことができる。
ボディ部の変換の結果を反映して、ヘッダ部のメタ情報も書き換える必要がある。
上記のスクリプトでは Content-Type の差し替えを指示している。一方、Content-
Lengthなどは CFI インタプリタにより自動的に設定される。


--(読解不能のため中略)--


1.3 CFIプログラムに渡される実行環境 / 外部フィルタの実行環境

CFI使用時には、DeleGateサーバからCFIインタプリタが、さらにそこからCFIプログ
ラムが、各々プロセスとして実行される。
CFIプログラム起動時の標準入力/出力、および環境変数。

                      +-----------------+
                      | DeleGate        |
                      +--+-+----+-------+
                         | v    |[environment-info]
                      +--+------v-------+            +=================+
                      | CFI-interpreter |<---------- | CFI-scripts     |
                      +--+--------------+            +=================+
                         | |[environtment variables]
                         | v
  [file-descriptor#0] +==+==============+ [file-descriptor#1]
  ------------------->+ CFI-program     +-------------------->
                      +=================+  to socket | pipe | temporary-file

1.3.1 ファイルディスクリプタ

図1に示した各種フィルタ起動時の標準入出力は、以下のようにソケット(S)または
パイプ(P)に接続されている。

  Table.1  Bindings of file descriptors
  ----------+--------------------------------------------------------
  filter    |      file descriptor number
  type      |       0           |       1          |   2
  ----------+-------------------+------------------+-------------
  FCL       | S-to/from-client  | S-to/from-server |
  FTOCL     | P-from-DeleGate   | S-to-client      | RPORT ?
  FFROMCL   | S-from-client     | P-to-DeleGate    | LOG ?
  FSV       | S-to/from-DeleGate| S-to/from-server | new-DeleGate?
  FTOSV     | P-from-DeleGate   | S-to-server      | RECEPTOR ?
  FFROMSV   | S-from-server     | P-to-DeleGate    |
  FFROMMD   | S-from-DeleGate   | S-to-DeleGatte   |

ただし、Windows (Win32) 上ではソケットを、子プロセスとして起動するCFIプログラム
に渡すことができないため、いずれもパイプによるインターフェイスで提供している。
(一旦パイプでDeleGateに戻し、その先のソケットとの間を単純中継している)

1.3.2 応用プロトコル共通環境変数

起動の時期によって、CFIプログラム(フィルタ)に渡される環境は異なる。まず、FCL
やFFROMCLは、クライアントとの接続が成立した直後から中継を行うフィルタであるた
め、TCPコネクションから得られる、以下の情報のみが渡される。これが全てのフィルタ
に共通して渡される最小セットの環境変数である。

  Table.2  The minimum common set of environment variables for filters
  --------------------------------------------------------------------
  REMOTE_HOST -- client's host name
  REMOTE_ADDR -- client's host address
  REMOTE_PORT -- client's port number
  ...


--(読解不能のため中略)--


1.3.3 応用プロトコル固有環境変数

特定のプロトコル毎に、その転送データをDeleGateが解釈した結果、フィルタに提供
される情報。
MIMEメッセージ形式に準拠するメッセージ形式を採用している応用プロトコル(SMTP,
POP,NNTP,HTTP)を中継する時のフィルタには(FCLとFFROMCLを除き)、CGI互換の環境
変数と、いくつかのDeleGate独自の環境変数が渡される。

環境変数
  HTTP_canonHeaderNames


--(読解不能のため中略)--


3. CFIスクリプトの構文と機能

CFI で扱う主対象は、RFC822形式に準拠するメッセージ(HTTP,NNTP,SMTP,POP,...)
であるため、CFI スクリプトの構文もRFC822風の形式とした。加工する対象と同じ
形式であるため直観的に理解しやすく、利用者が馴染みやすいという利点がある。

種別:マッチングによる条件判定。ヘッダの加工。ヘッダ生成。ボディ生成。

3.1 CFIスクリプトの構文

1つ以上の要素スクリプトからなり、各要素スクリプトは RFC822 ヘッダフィールド
形式である。各要素スクリプトは、それを適用するための条件が満たされているか
否かを「判定」し、条件を満たすスクリプトを「実行」する。したがって各フィール
ドは
・適用条件を指定する
・適用された場合に加工を行う
という2つの役割を役割を持つが、マッチングのみ、加工のみのために使われるフィ
ールドもある。

  Table X. The syntax of the CFI script 
  --------------------------------------------------------------------
  CFI-script: "#!cfi" CRLF scirptUnit [ "__" CRLF scriptUnit ]*

  scriptUnit:  MIME-hdrFiled            // 条件判定(フィールド値の一致)
             | "Tail/" MIME-hdrField    // 条件判定(フィールド値末尾の一致)
             | "Remove/" MIME-hdrField  // 条件判定+削除
             | "Output/" MIME-hdrField  // 無条件ヘッダ出力(置換)
             | "Output-Header:" MIME-hdrField  // 無条件ヘッダ出力
             | "Output-Prefix:" data    // 無条件ボディ出力(先頭)
             | "Output-Postfix:" data   // 無条件ボディ出力(末尾)

  cfiSort:      FCL | FTOCL | FFROMCL | ...
  MIME-hdrField:   MIME-fieldName ":" [fieldValue]
  MIME-filedName:
               "X-Request-" MIME-field  // 要求メッセージ中のフィールド

  // 動作指定フィールド
  Remove/fieldName: fieldValue          // フィールドの削除
  Output/fieldName: fieldValue          // フィールドの新規追加
  Filter: systemCommand                 // フィルタコマンド
  CGI: systemCommand                    // フィルタコマンド(CGI互換)
  --------------------------------------------------------------------

複数の要素スクリプトの間は、"--" という行で区切る。スクリプトは先頭から評価
され、適用条件に適合した要素スクリプトが実行される。要素スクリプトが "--"
で終端していた場合には、それで終了する。すなわち "--" は 排他的 OR に相当す
る。一方、区切り "++" は、その後のスクリプトの評価を続行することを表す。
最後まで走査してマッチする要素スクリプトがなかったら、透過中継される。

マッチング対象として指定したフィールドが無い時は TRUE。
フィールド値が空の場合には、そのフィールドが存在しさえすれば、フィールド値に
よらず TRUE。通常は、先頭の部分列の一致。str.* に相当する。

--(以下読解不能のため略)--

---------------------------------------------------------------------------

                               @ @
佐┬─┐─┬─┌   //\^^   ( - )
藤├─  │ │ / 876m\  _<   >_ 
豊┴── ┴ ┴──────────────────────────────┘