VSAP

X-Seqno: 5798
To: delegate@etl.go.jp
From: ysato@etl.go.jp (Yutaka Sato 佐藤豊)
Subject: What is VSAP ?
Date: Wed, 6 Aug 97 17:22:18 JST
Organization: Electrotechnical Laboratory, Tsukuba Science City
Lines: 125
Message-ID: 
Mime-Version: 1.0 (generated by vin2.0)
Content-Type: text/plain; charset=ISO-2022-JP

VSAP(Virtual Socket Association Protocol)とは?

                               -- ありがとうSocks、そして、さようなら --

DeleGate/4.3.0 を出荷してようやく夏休みが来たかなという感じの佐藤です。
4.3.0では、これまでいろいろタマッてたものを実装できて、すっきりしました。
8月の頭から中旬にかけては、気分が沸騰しちゃってもう大変(^_^;最大の
目玉は、VSAP(まだ仮称かも?)というプロトコルです。一言で言えば、遠
隔のホスト上でsocket()の接続を行うもので、要するにSocksのようなモノです。
Socksとの大きな違いは、

 ・指定したポート番号でBINDしてACCEPTできる
 ・仮想的なアドレスで接続できる(ipaddress:port-numberに限らない)

という点です。(知られてないと思いますが)自分では、以前作ったVIABUS,
Teleport, couplerプロトコルを統合して思いきり単純化して焼き直したようなも
のだ(になるだろう)と思っています。これで何がうれしいかというと、例えば、

 ・内部サーバのファイアウォール越えができる
 ・一つのサーバを入口として、複数のサーバで動的に負荷分散ができる
 ・動的に割り当てられたアドレスのサーバを固定アドレス:ポートで公開できる

というようなことです。
ぼくは、SocksV5にはこのような機能が入るだろうと期待して待ってたのですが、
結局クライアントのためのファイアウォール越えしか考えられていないようです。
standard track を走っている規格にちょっかい出すのもシンドイし、それにSocks
の、最小限の機能をきっちり提供する、という方向性(だと思う)は、ぼくが
仮想へろへろで遊んでみたいこととマッチしません。そんなわけで、独自にプロ
トコルを考えてみることにしました。

VSAPは、ASCIIベースのシンボリックなメッセージ形式をとっています、おそらく
perlでもごく簡単に VSAP サーバを実装できるんではないかと思います。最終的
には、Socks上位互換なバイナリ形式のメッセージ形式も併用したいと思ってい
ます。また、socket ライブラリの互換関数ライブラリも作ろうと思います。

さて、どんなふうなプロトコルかですが。例えば以下のような感じで動作します。

  localhost% delegated -P8000 SERVER=vsap  … VSAPサーバとして動作する

  localhost% telnet localhost 8000
  Trying 127.0.0.1 ...
  Connected to localhost.
  Escape character is '^]'.
  BIND localhost:8080
  VSAP/0.1 210 1 127.0.0.1:8080 bound.
  LISTEN 1
  VSAP/0.1 220 listen ok.
  ACCEPT
 … ここで他から telnet localhost 8080
  VSAP/0.1 230 1 127.0.0.1:8080 127.0.0.1:1682 accepted.
  RELAY
  … 以下双方向に中継

VSAPでは、「仮想的なソケットのアドレスファミリ」をサポートしようと考えて
います。仮想的では無い例ですが、例えば AF_UNIX なアドレスで、遠隔のサーバ
とクライアントが接続することができます。つまり、サーバ側では、VSAPサーバに
接続した後、
  BIND /tmp/dgsock1
  LISTEN 1
  ACCEPT
 …接続待ち…
  RELAY
とやり、クライアント側では、
  CONNECT /tmp/
 …接続待ち…
  RELAY
とやるわけです。pty などもこの手でうまく扱えると面白いと思います。さらに、
例えば、

  BIND http://server/path

というのができるとすると、DeleGate の MOUNT ができる。いや、これができると
DeleGateのMOUNTがいらなくなるのではなく、これをDeleGateのMOUNTで実装する
ことになります。これを実用的に動かすためには、DeleGateのconfiguration を
遠隔から動的に変える必要があり、4.3.0 でもやりかけたのですが、セキュリティ
の問題もからむので、これはじっくり考えることにしました。

VSAPによる「負荷分散」は、VSAPから実サーバに処理を分配するのではなく、
サーバ側から VSAP上に BIND/ACCEPT しに来て処理を引き取るため、ごく当り前
に、適切な負荷分散が実現し、またサーバの増減や故障にも、当り前に自動的に
対応することができます。

まだ作りかけのプロトコルではありますが、現在の実装でも以下のような感じで
結構実用的に使うことができると思います。

(例0)VSAPサーバの起動
firewall% delegated -P8000 SERVER=vsap PORT=8080-8081

(例1)内部のクライアントからVSAP経由で外部に接続する
internal% delegated -P8080 CONNECT="{vsap/firewall:8000}"  ...

(例2)内部のサーバをVSAP経由で外部に公開する
internal% delegated -P8080@firewall:8000 SERVER=http ...

(例3)負荷分散
internal-01% delegated -P8080@firewall:8000
internal-02% delegated -P8080@firewall:8000
internal-11% delegated -P8081@firewall:8000
internal-12% delegated -P8081@firewall:8000

(例4)VSAPの多段中継
internalA% delegated -P8000 SERVER=vsap://filrewall:8000 (tcprelayでも可)
internalB% delegated -P8080@internalA:8000 ...


なお、上記の例を書いてたら、バグが見つかりました。現在の実装上、実用上何も
問題ありませんが、一応同封のパッチでフィックスします。

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