hogeとはワイルドカードのようなものです。日々起こった、さまざまなこと −すなわちワイルドカード− を取り上げて日記を書く、という意味で名付けたのかというとそうでもありません。適当に決めたらこんな理由が浮かんできました。
05/13/2012 ふむ [長年日記]
■ [Linux][Py] Ethernet over WebSocket
TAP を使って L2 フレームを WebSocket でトンネリングしてみた. 名付けて EtherWebSocket. そのまんま.
こないだの TAP は C で直接書いたけど,WebSocket を C でほげほげするのは面倒なので Python で.
そうなると TAP の Python インタフェースが必要になるのだけれど,python-pytun なるものがあったのでそれを使った. 正直に言うとこの TAP for Python は最初探しもせずに自分で書いてた. 2/3 くらい書いたところで「そういえば」と思ってぐぐったら出てきて,嬉しいような悲しいような気分になりましたとさ. 一応 自分が書いてたものの残骸はここに置いてある けど,python-pytun 使った方が良いでしょう. 中身の方向性は大体同じで,python-pytun の方が完成度が高い.
さて本題の EtherWebSocket のコード. まあ何のことはない,TAP から流れてきたフレームを WebSocket に,WebSocket から流れてきたフレームを TAP に流すだけの単純なもの. 一応 Hub and Spoke 型で動くように書いたつもりではあるけど,試してないから知らない.
で,手元でこれを使って KVM の VM を 2 台繋げてみたけど,だいぶきもいね.大体こんなイメージで本当に動いてしまった.びっくりだね.
+-----+ +-----+ | VM1 | | VM2 | +--+--+ +--+--+ | (vnet0) (vnet1) | +--+--+ +--+--+ | br0 | | br1 | +--+--+ +--+--+ | (WebSocket) | (ethws0) <===========> (ethws1)
// サーバ側起動.デフォルトだと 0.0.0.0:80 で待機する # python etherws.py --device ethws0 server // クライアント側起動.サーバの URL を指定して繋ぎに行く # python etherws.py --device ethws1 client --uri ws://localhost/ // ブリッジに繋いでやる # brctl addbr br0 # brctl addbr br1 # ifconfig br0 up # ifconfig br1 up # brctl addif br0 ethws0 # brctl addif br0 vnet0 # brctl addif br1 ethws1 # brctl addif br1 vnet1 # brctl show bridge name bridge id STP enabled interfaces br0 xxxx.xxxxxxxxxxxx no ethws0 vnet0 br1 xxxx.xxxxxxxxxxxx no ethws1 vnet1
追記
なんかタイミング系のバグがあったくさいので直した.たぶん.
ついでにフレーム転送方法をバイナリ転送に変更. 少しパフォーマンス上がった. 手元で試した感じだと scp arc4 で 1.2MB/s くらい.テキスト転送で 900KB/s くらいだったのでまずまず.
それにしても,もっと全然うんこみたいなパフォーマンスしか出ないだろうと思ってたんだけど,意外と頑張っててちょっと驚いた. まあ CPU ブン回りまくりだけど.
追記2
動かしたまま 2 日放置して,死ぬようなこともないようなので pypi に登録しておいた.
初 pypi. pypi バージンを失いました.
追記3
SSL/TLS 接続と Basic 認証を付けておいた. これで簡単な L2-VPN としても使える気がしないでもない.
追記4
メモリ増設して VM 3 台立ち上げられるようになったので Hub and Spoke を試した.
普通に動いた.サーバを経由して各クライアントへの接続性が確保されていた.
いやはやきもい.
追記5
MTU を巨大に設定することでスループットを向上できるようにしといた.
ローカルでしか試してないけど,15KB くらいにすると iperf -u でさっと計ると 500Mbps 弱くらいだった. SSL を有効にすると 250Mbps 強くらい.