hogeとはワイルドカードのようなものです。日々起こった、さまざまなこと −すなわちワイルドカード− を取り上げて日記を書く、という意味で名付けたのかというとそうでもありません。適当に決めたらこんな理由が浮かんできました。
05/02/2012 うむ [長年日記]
■ [JS][日記] Pyコードシューター を改造
パワーアップアイテムを実装してみた. それだけ.
微妙にバランスを壊した気がするけどまあいいや.
それにしてもコードがあまりに汚すぎてひどい. 何も考えず思いつきで書くとこうなるという反面教師だな.
05/10/2012 ふむ [長年日記]
■ [Linux] TAP を使ってみる
L2 な仮想デバイスを作れ,そのデバイスに対する入出力をファイルディスクリプタ経由で行うことのできる TAP を使ってみる.
Linux の Documentation/networking/tuntap.txt に色々書いてあるので,適当に読みつつ tapcap なるものを書いてみた.
$ gcc -o tapcap tapcap.c $ sudo ./tapcap tapcap0
引数にデバイス名を渡して実行してやると,仮想デバイスが出来上がる.
$ ifconfig tapcap0 tapcap0 Link encap:Ethernet HWaddr xx:xx:xx:xx:xx:xx inet6 addr: fe80::xxxx:xxxx:xxxx:xxxx/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:500 RX bytes:0 (0.0 B) TX bytes:328 (328.0 B)
一方,プロセス側ではこのデバイスがファイルディスクリプタとして見えている. tapcap は fd をひたすら read して hexdump するだけの小さなブツなので,ブリッジに繋ぐなど殴る蹴るの暴行を加えると,
$ sudo brctl addif br0 tapcap0 $ brctl show bridge name bridge id STP enabled interfaces br0 xxxx.xxxxxxxxxxxx no eth0 tapcap0
L2 フレームがべろべろと流れ始める.ちなみにこいつは IPv4/ICMP/ブロードキャスト.
-- Thu May 10 23:41:49 2012 0x0000: ffff ffff ffff 001c c039 0ceb 0800 4500 0x0010: 0054 0000 4000 4001 155a ac10 e62e ac10 0x0020: e6ff 0800 28eb 6108 0001 add3 ab4f 0000 0x0030: 0000 5115 0500 0000 0000 1011 1213 1415 0x0040: 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 0x0050: 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 0x0060: 3637
ちなみにこのデバイスには tcpdump をかけることもできるのでプロセスによる hexdump はただのオマケ.
TAP 自体は write つまり送信もサポートしてるので色々遊べそう. 邪悪な意味も含めて.
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 強くらい.