2006年06月
「jabber.jp と Google Talk との相互接続開始」で jabber.jp の紹介をしたのが原因というわけでもないのだろうが、 一時的に jabber サーバが過負荷になってサービス不能状態に陥ってしまった。 この jabber.jp は KLab のサーバマシン群の中では低性能なマシンを使っていたので、 この機会にと、もう少しマシなマシンへ引越しさせた。 が、負荷の問題というよりは、サーバプログラム自体に、 なにかのタイミングでハングするバグがあるようだ。 他のソフトウェアへの乗り換えも含めて対策を検討中であるが、 とりあえずハングしていないかの死活確認は必須だろう。
まず CPAN から Net::Jabber をインストール。
「Google Talk を流れるデータを見る」に、
「Net::Jabberは,インストールしようと思ってもmake testでひっかかってしまってうまくインストールできません.」と書いてあったのが
気になりながら (^^;) 作業していると...
cpan> install Net::Jabber(改行)
...
---- Unsatisfied dependencies detected during [R/RE/REATMON/Net-XMPP-1.0.tar.gz] -----
XML::Stream
Shall I follow them and prepend them to the queue
of modules we are processing right now? [yes] (改行)
Running make test
...
t/buildxml......ok
t/load..........ok
t/parse_node....ok
t/parse_tree....ok
t/tcpip.........ok
t/tcpip2ssl.....ok 2/3
ありゃ、止まってしまった。 XML-Stream-1.22/t/tcpip2ssl.t を見ると、
my $status = $stream->Connect(hostname=>"obelisk.net",
port=>5223,
namespace=>"jabber:client",
connectiontype=>"tcpip",
ssl=>1,
timeout=>10);
などと書いてある。 つまり、jabber サーバである「obelisk.net」を相手に 接続テストを行なおうとして止まってしまっている。 おそらく obelisk.net が相手にしてくれないのだろう (5222番ポートの方は相手をしてくれるようだ)。 とりあえず obelisk.net の代わりに手元の jabber サーバを指定して、 テストを成功させ、無事インストール完了。
とりあえず、さくっと死活確認スクリプトを書いてみる:
#!/usr/bin/perl
@RCPTS = ('jabber-error@gcd.org',);
use Net::Jabber qw(Client);
&ckjabber("jabber.gcd.org", 5222, "test", "XXXXXXXX", "ckjabber.$$");
&ckjabber("jabber.jp", 5222, "test", "YYYYYYYY", "ckjabber.$$");
sub ckjabber {
my ($server, $port, $username, $password, $resource) = @_;
my $client = new Net::Jabber::Client();
my $connected = 0;
my $authenticated = 0;
my $recv_subject;
my $recv_body;
my $subject = "check $server";
my $body = "This is a test message from $resource.";
my $onConnect = sub { $connected++; };
my $onAuth = sub {
$authenticated++;
$client->MessageSend(to => "$username\@$server/$resource",
subject=> $subject, body => $body, );
};
my $onMessage = sub {
my ($sid, $message) = @_;
$recv_subject = $message->GetSubject();
$recv_body = $message->GetBody();
$client->Disconnect();
};
$client->Connect(hostname => $server);
$client->SetCallBacks(onconnect => $onConnect, onauth => $onAuth,
message => $onMessage, );
$client->Execute(username => $username, password => $password,
resource => $resource,
hostname => $server, port => $port,
register => 1,
connectsleep => 0, connectattempts => 1, );
my $error;
if (! $connected) {
$error = "can't connect to $server";
} elsif (! $authenticated) {
$error = "authentication failure";
} elsif ($recv_subject ne $subject || $recv_body ne $body) {
$error = "get '$recv_subject' & '$recv_body'";
}
if ($error) {
print STDERR "$server error\n$error\n";
&mail("$server error", localtime(time) . "\n$error\n", @RCPTS);
}
}
sub mail {
my ($subject, $body, @rcpts) = @_;
open(INJECT,"|/var/qmail/bin/qmail-inject " . join(" ", @rcpts)) || die;
print INJECT "From: root\nTo: ", join(", ", @rcpts), "\n",
"Subject: $subject\n\n$body";
close(INJECT);
if ($? << 8) {
print STDERR "Fail to send mail to ", join(", ", @rcpts), "\n";
exit 1;
}
}
自分自身にメッセージを送ってみて、 同じ文面が返ってくるか確認するだけの単純なテストスクリプトだが、 jabber サーバがハングしたら検知してメールを送ってくれるだろう。 とりあえず 5 分に一度実行するように cron に仕掛けた。
好きなこと = 他の人に勝てる分野
「負けることを恐れるあまり、勝つことに価値を見いだせなくなってしまった人たち」に 頂いたコメントを見ていて、 あらためて日本語の難しさを痛感する (^^;)。
「勝てることが好き」 と 「勝てるから好き」 と 「勝つことが好き」
文字ヅラはとても似ているが意味はだいぶ違う。
私が書いたのは「勝てることが好き」だったのだが...
「勝つ」こと自体が好きと、「勝てること」が好きでは、
もちろん全然意味が違うし、
どんな分野であれ最初から「勝てる」ことなどないのだから、
勝てる「から」好き、というのもちょっと違う。
「好きだから注力する」⇒「注力するからより上達する」⇒ 「上達を実感するから、より好きになる」 という正のフィードバックによって、 しだいに勝つことができるようになるのである。 「勝つ」は結果であって、理由ではない。 つまり「勝てるから好き」ではない。 もっとも、「勝ちたいから注力しているうちに好きになる」ということは あるが。
やりたいことを見つけるにはどうすべきか?
Mimiteru さまのコメントから引用:
業務も職種も世の中にはたくさんあります。 やりたいことがわからない人は、 本当にプログラマがやりたいのかさえも漠然とした意識を持たないのかもしれません。
その通りだろう。 何がやりたいのか見つけるには、 好きでなくても手当たり次第に挑戦してみることも必要である。 何事も始めてみなければ始まらない。
ところが、挑戦してみることを勧めると、 「時間ができたら勉強したい」と答える人のなんと多いことか。 率直に言って、こう答えた時点で好きになれる可能性はゼロである。 何事も始めてからの方が困難なことが多い。 まして勝てるようなレベルを目指すなら、 好きでなければやってられないことも多いだろう。
世の中は、何をするにしても道半ばで、進むのを止めてしまえと 囁く誘惑に満ち満ちている。 「時間がない」ことを「いいわけ」にして始めないようなら、 仮に始めたとしても、困難にぶち当った途端、 山のような「いいわけ」を持ち出して自己を正当化し、 進むのを止めてしまうだろう。
好きなことがあるなら、時間なぞなくても始めてしまうだろうから、 こんな「いいわけ」は言わないだろう。 好きなことがないなら、そして何かやりたいことを見つけたいと本当に思うのなら、 「いいわけ」を口にしたくなっても思い止まるべきだ。 最初から「いいわけ」を口にしていて好きになれるはずがない。
勉強を始める最適な日は、今日という日をおいて他にない。
stone 2.3b をリリースした。 現時点ではスナップショット扱いであるが、 重大なバグが発見されない限り、 このバージョンを stone 2.3 に代えて正式リリースとする予定。 stone 2.3a からの変更点は以下の通り。
doReadWrite select ループを抜けるバグを修正
stone.c 2.2.2.6 で doReadWrite から doReadWritePair を分離したときに作りこんでしまったバグを修正。
このバグにより、意図せず doReadWrite select ループを抜けてしまい、 パフォーマンスが大幅に低下するケースがあった。 詳しくは SSL_Pending を参照。
アーカイブから stone.1 と stone.1.ja を削除
stone 2.3 と stone 2.3b との仕様の差分を、 マニュアル stone.1 および stone.1.ja に反映できていないので、 とりあえず削除。
現時点での stone の正式マニュアルは、 パッケージ同梱の README.txt および README.en.txt である。
変数名の変更など
関数の仮引数と同じ変数名のローカル変数を使っていた。 stone.c 2.2.2.23 で修正。
「『他の人に勝つ』ということに価値を見いださない人たち」に頂いたコメントから発展して、 /.j 方面でいろいろなコメントを頂いた。 いろんな考え方の人たちと議論することによって 考えが深まるので大変ありがたいことだ。 曰く:
この方は競争に勝つために勝てる分野を選んで それを好きになるという習慣を自分の中に構築して行った結果、 それがあまりにも固定化された「大前提」になってしまって、 そこに至るまでの「自分がなにをしたいのか」について ちゃんと考えることを止めてしまっているのではないかと思います。
どうやら昨今の事件によって「勝つ」という言葉の持つ負のイメージが 大きくなってしまっているようだ。 なにごとにも光と影の面がある。 勝つ人がいれば当然負ける人がいる。 負ける人のことに焦点をあてれば、 勝つことに価値が見いだせなくなるのは当然のことだろう。
では、「勝つ」という代わりに「人より『上手く』やる」と言い換えたらどうだろう? 例えば、「私は普通の人より効率的なコーディングができる」。 私よりコーディングの効率が劣る人は「負け組」だろうか?
もちろん違う。 単にコーディングに向いていないだけなのだ。 自身の適性を早く把握して、 自分に向いていることを見つけ出し、 それを好きになって取り組めば、 おそらくその分野では私より「上手く」やることができるようになるだろう。
「勝ち組」は一割以下だという。 ほとんどの人は「負け組」になってしまうから、 そもそも「勝ち負け」にこだわるのはよくないと、 まるで小学校の徒競走みたいなことを言う人がいる。
しかし、なぜ負けた人がその分野にこだわる必要があるのか? ある分野で負けても、他の分野で見返してやればいいではないか。 みんながそれぞれ自分に一番向いていることをすれば、 「勝ち組」の割合はずっとずっと増えるだろう。
これこそ、それぞれの人の多様な能力を伸ばすことをめざす 「ゆとり教育」の目標であったはずだ。 ところが現状は皆が自身の個性を無視して同じようなことを目指す。
徒競走でビリの子が出るのが問題なのではなく、 みんなを運動会に等しく駆り出すことが問題なのである。 勝ち負けをはっきりさせなければ誰が運動能力に優れ、 誰が向いていないのか曖昧になってしまう。
受験戦争が問題なのではなく、 大学で学ぶ意欲も能力もない子まで大学へ進学させようとするのが問題なのである。 大学で学ぶ意欲も能力もない子でも、 受験テクニックを無理矢理覚え込ませればテストの点は上がるかもしれないが、 そういった子たちが大学に入って何をするというのだろう。
お金儲けが問題なのではなく、 自身の適性を無視し、自分がやりたいことを見失って、 向いていない仕事を嫌々やっていることが問題なのである。 「プログラマ 35歳 定年説」に書いたように、 できるだけ早い段階で勝ち負けをはっきりさせ、 自分に向いていることを見つけるべきなのである。
仮説: ロングテール戦略が格差社会を生む
の検証の一回目 (全七回を予定)。
究極の搾取
剰余価値が生まれて以来、 持つ者が持たざる者を 搾取する、 という構図は変わらない。
産業革命の時代、資産とは生産諸手段だった。
情報革命の今日、資産とは知能である。
頭のよい者が儲け、頭がよくない者は自覚のないままに搾取されている。 搾取と言っても、一人一人の額は微々たるものだから、気付かないのだろう。 たまに、「ボロ儲け」した奴はけしからん、と一部の金持ちが槍玉にあげられるが、 本当の金持ちは目立たないようにしているものだ。 一人一人に対する搾取は極めて少額でも、 情報技術の力によって集めれば莫大な額になる。
かつて「搾取」が持っていた暗いイメージはもはやない。 産業革命時代の搾取と違って、 今日の搾取には悲惨さは微塵もない。 かつての搾取はその悲惨さによって下層階級を固定していたが、 今日の搾取にはその力はない。 したがって産業革命時代と異なり、 今日は搾取それ自体が格差社会を生んでいるわけではない。
その一方で、富を集積する力は従来と変わらず圧倒的である。 しかも、産業革命時代の機械と比べると、 今日のコンピュータおよびネットワークは、 費用対効果が極めて高い。
圧倒的な効率で富を集積する力を持ち、
しかも負の側面をほとんど持たない。
まさに究極の搾取と呼ぶにふさわしいだろう。
DNS問合わせというと、 ネームサーバの UDP/IP の 53番ポートへ問合わせるのが一般的であり、 TCP/IP の 53番ポートはゾーン転送のみに使われることが多い。 しかし RFC (RFC1035 および RFC2136) 上は TCP も、UDP と同様、 通常の問合わせにも利用することができることになっているし、 多くのネームサーバでそのような実装になっている。
手近なネームサーバが利用できない環境 (某ホテルの無線LAN 環境など ;) で、 やむを得ず遠方のネームサーバを利用する際などに、 TCP を使って問合わせをすると、 ポートフォワードすることもできて便利である。
拙著「ネーム・サーバ (前編)」に書いたようにネームサーバには二種類あって、 ここで言うネームサーバは、 「/etc/resolv.conf に登録できるネーム・サーバー」のことである。 つまり、リゾルバから問い合わせがあると, 他のネーム・サーバーに問い合わせて結果を返してくれるタイプである。 一般にはキャッシュ ネーム サーバと呼ばれることが多いようだ。
ちなみにネームサーバには他に、 「答えを知っている問い合わせに対しては答えてくれるけれど, 知らない場合は,どこどこへ聞けと冷たく言い放つタイプ」がある。
また、キャッシュ ネーム サーバの一形態として、 他のキャッシュ ネーム サーバへ問合わせを転送する フォワード専用型キャッシュネームサーバもある。
広く普及しているネームサーバ実装の一つである djbdns には、 UDP 問合わせに失敗したり、 あるいは 512バイト以上の問合わせを行なう際は、 TCP にて問合わせを行なう機能があるが、 最初から TCP しか使わない (キャッシュ) ネームサーバがあると便利だろう。 すなわち、 遠方のネームサーバへ TCP で問合わせを転送する、 フォワード専用型サーバである。
| フォワード専用型 | キャッシュ | ┌→ | ルート (root) ネームサーバ | |||
| リゾルバ | ──→ | キャッシュネームサーバ | ──→ | ネームサーバ | ─┼→ | ネームサーバ |
| UDP | TCP | ├→ | ネームサーバ | |||
| └→ | … |
といった感じで TCP専用サーバを用いる。 この TCP専用サーバの作り方は簡単で、 djbdns の場合ならば次のようなパッチをあてるだけである。
dns_transmit.c で定義されている dns_transmit_start() 関数の末尾部分で、
if (len + 16 > 512) return firsttcp(d);
return firstudp(d);
となっている部分を、
/* if (len + 16 > 512) */ return firsttcp(d);
return firstudp(d);
で置き換える。
このようなパッチをあてた dnscache プログラムを、 環境変数 FORWARDONLY をセットした状態で呼び出せば、 「servers/@」に指定したキャッシュネームサーバへ TCP で問合わせを転送する、 フォワード専用型キャッシュネームサーバになる。
ふと思いついた仮説:
ロングテール戦略が格差社会を生む
を検証していこうと思う。
「凡人が万馬券ばかり買って競馬場を去る社会」
「格差」
「過ぎたる機会は及ばざるがごとしか」など、
「格差社会」というテーマが最近ホットであるようだ。
これらのブログを読んでいて違和感を感じた。
別の視点から「格差」を論ずることができるような気がしている。
論拠は次の 7 つ。
これだけで私が何が言いたいか分かってしまった人もいるかもしれないが (^^;)、 今後一つずつ掘り下げてみる予定。 ご意見を頂ければ、より突っ込んだ議論ができるかもしれない。
ふと思い立って、このブログ(livedoor Blog)の XHTML文法チェックを行ってみた。 予想通り、山のような文法エラーが見つかった。(^^;)
片っ端から修正し、ほとんどは駆逐できたのだが、 ユーザ設定できない以下の部分についてはどうにもならない。
修正不可能な文法エラー
ユーザ設定できない部分なので修正できない。
HTMLテンプレートでアイコンのURLを示す変数の値が異常
次のようなHTMLが生成されてしまう:
<div class="powered"> <a href="http://blog.livedoor.com/"> <img src="http://img.blog.livedoor.com/img/usr/cmn/blog_pro.gif " width="117" height="28" border="0" alt="livedoor Blog(ブログ)" title="livedoor Blog(ブログ)" /> </a> </div>
なぜか、blog_pro.gif のURL の直後に改行コードが入っている。
これは、HTMLテンプレートでは「<$LDBlogLogo$>」となっている部分。
outfooterの部分
HTMLテンプレートで生成した HTML に、 システムが自動的に追加する outfooter に次のような部分がある:
<script type="text/javascript" src="http://parts.blog.livedoor.jp/js/c.js">
</script>
<script language="JavaScript">blog_counter('hiroaki_sengoku')
</script>
<script type="text/javascript" src="http://blog10.analyzer.livedoor.jp/x.js?pid=39952">
</script>
<noscript>
<img src="http://blog10.analyzer.livedoor.jp/img/a.gif?pid=39952">
</noscript>
なぜか二番目の JavaScript だけ 「language="JavaScript"」という属性になっている。 一番目、三番目と同様「type="text/javascript"」にすべきだと思う。
また、img タグが閉じていないのと、alt属性がない。
以上は、HTMLテンプレートで設定可能な範囲外であるので、 対処できない。
修正可能ではあるものの望ましくない文法エラー
上記の問題点のほか、回避手段があるとはいえ、 以下の点も問題だろう。
「ブログ検索」プラグイン
プラグインとして「ブログ検索」を使用すると、 以下のような HTML を生成してしまう:
<form action="http://sf.livedoor.com/search" method="GET" style="padding:0;margin:0px;"> <input type="HIDDEN" name="q" value="allinblog:http://sengoku.blog.klab.org/"> <input type="TEXT" name="q" class="sf"> <input type="SUBMIT" value="検索" class="sfbtn"> </form>
inputタグが閉じていない。 また、「method="GET"」は「method="get"」のほうがよいだろう。
「ブログ検索」プラグインを使わず、 「フリーエリア」プラグインを使って 正しい XHTML を書けば対処可能ではあるが...
改行をそのまま反映
「投稿フォームの設定」で「改行をそのまま反映」を選択すると、 行末に「<br>」が挿入される。 「<br />」でないと XHTML 的には文法エラーになってしまう。
Linuxでテレビ録画を行なう方法は、多くの Web ページで紹介されているが、 ビデオキャプチャ カードによっては、 Linux カーネルのバージョンが変わると一筋縄にはいかなかったりするので、 現時点での Linux カーネル安定版の最新バージョン 2.6.16.19 で、 I-O DATA 製 ハードウェア MPEG-2 エンコーダ搭載TVキャプチャボード GV-MVP/RX2Wを使う方法をメモ (2.6.24.4 で使う方法)。
まず、 LinuxTVプロジェクトから V4L ドライバの最新版を取得する。 Mercurial (a fast, lightweight Source Control Management system) が インストール済であれば、
hg clone http://linuxtv.org/hg/v4l-dvb
を実行する。Mercurial が無い場合は、 MASTER v4l-dvb development repository から最新版を選んで「tree」をクリックし、 「gz」ないし「bz2」をクリックして tar ball をダウンロード。
そのまま make install
してインストールしてもよいが、
make release VER=2.6.16.19
などと実行して、
現在使っているカーネルとは別のカーネルへインストールすることもできるし、
make menuconfig
を実行して
インストールするモジュールを選択してもよい。
私は、以下のモジュールのみ make した:
Multimedia devices --->
Video Capture Adapters --->
V4L USB devices --->
Hauppauge WinTV-PVR USB2 support
# Hauppauge 以外でも tveeprom.ko を用いるドライバであれば何でもよい
次に、ぱ研「LinuxでITVC16-STVLP」の ページに登録されている 0.6_svn3233-paken060421.tar.gz をダウンロード。 これをそのまま make すると version_check でひっかかるので、 Makefile の一行目を、
all clean install: version_check
となっているのを
all clean install:
に変更して make install
する。
make KVER=2.6.16.19 install
などと実行して、
現在使っているカーネルとは別のカーネルへインストールすることもできる。
/etc/modprobe.conf に以下の行を追加:
alias char-major-81 videodev alias char-major-81-0 ivtv alias char-major-81-1 ivtv options ivtv ntsc=j tuner=46,46
チューナの video standard の設定を変更すると、 正しい選局ができなくなるようなので、 チャンネルを設定するプログラム等で video standard の設定を行なわないようにしておく必要がありそう。
私は録画 perl スクリプトを 自作して使っている (Video::ivtv & Video::Frequencies が必要)。
senri:/home/sengoku % tv -h
Unknown option: h
Usage: tv <opt>
opt: -x ; xine
-X ; mplayer YUV
-u ; ptune-ui
-P <port> ; TV server (http)
-U <host>:<port> ; (udp)
-c <channel> ; change channel
-f <freq> ; chage frequency
-l ; input from S-Video
-r <sec> ; mpeg to stdout
-o <file> ; to file
-t <time> ; record at <time>
-j ; start at 0 sec
-0 ; use video0
-1 ; use video1
-v ; verbose
このスクリプトは予約録画 (-t オプション) もサポートしている他、
tv -P 1234
などと実行すると、
TVサーバとして利用することもできる。
つまり LAN 内の任意のマシンで、
VLC media playerを使って
http://senri:1234/?c=1
などとチャンネル指定付で tv サーバへ接続し、
TVを視聴できる。
(ビデオキャプチャ・カード GV-MVP/RX2W を使って Linux 2.6.24.4 でテレビ録画)
SSL_pending をマニュアルで調べると、
SSL_pending - obtain number of readable bytes buffered in an SSL object
SSL_pending() returns the number of bytes which are available inside ssl for immediate read.
と書いてある。つまり OpenSSL ライブラリ内に受信可能データがある場合、 そのデータバイト数を返す関数である。
なぜこんな関数が必要かというと、 データを送信しようとして SSL_write を呼び出したときも、 TCP/IP レベルでは送信だけでなく、受信も行なわれるからだ。 SSL のような暗号通信の場合、 送信は「垂れ流し」では済まず、ハンドシェークを行なう必要があるからだが、 この時、受信しようと思っていなかったデータ、 つまり通信相手が送信したデータまで読み込んでしまう場合がある。
すると、SSL_write を呼んでいるのに、 OpenSSL の受信バッファに、意図せずデータが溜まってしまう。 こうなってしまうと、select(2) や epoll(2) では検知できない。 select(2) や epoll(2) は、 I/O レベルでの受信データの有無を調べるシステムコールであり、 それより上のレベルである OpenSSL ライブラリの受信バッファのことは 関知しないからだ。
stone では、SSL_write で全てのデータを送り終わったとき、 SSL_pending を呼び出して受信すべきデータがないか確認している。 これを行なっているのが、 中継元/中継先との送受信を行なう stone の中核関数 doReadWritePair である。
select 版 stone の場合、 doReadWritePair を呼び出すのは doReadWrite である。 この関数は、 中継元/中継先との通信を行なうソケットディスクリプタのみを監視する select ループである。 epoll 版と異なり、select 版では、 select で監視するソケットの数が増えるとパフォーマンスが落ちるので、 送受信が継続しているときはメインの select ループとは別のスレッドを作成して、 パフォーマンスの低下を回避している。 送受信が途絶える (0.1 秒以上送受信が行なわれない) と、 この doReadWrite select ループを抜け、スレッドを終了して、 メイン select ループでソケットを監視する状態に戻る。
stone 2.3a (正確に言うと、stone.c 2.2.2.6 〜 2.2.2.23) では、 SSL_pending で受信すべきデータを検知したとき、 SSL_read を行なってデータを受信した直後に、 この doReadWrite select ループを抜けてしまっていた。 本来なら、データを受信したのだから 直ちにそれを中継するために送信しなければならないのであるが、 ループを抜けてしまったために、いったんスレッドを終了し、 メイン select ループで送信可能か確認し、 再びスレッドを生成して doReadWrite select ループに入る、 という無駄が生じてしまっていた。
したがって、SSL_pending でデータが検知されることが多発するような場合は、 転送速度が著しく遅くなる。 例えば、stone の受信バッファを意図的に小さくすることによって OpenSSL 内のバッファに受信データが残りやすくして SSL 通信を受信してみる:
-X 512 -z key=key.pem -z cert=cert.pem localhost:22 localhost:12346/ssl --
「-X 512」オプションによって、受信バッファのサイズを 512 バイト (デフォルトは 2048 バイト) にしている。 12346番ポートで SSL 接続を受付け、 それを復号した上で、22番ポートへ中継する設定である。 続いて、
localhost:12346/ssl localhost:12347 --
という設定で stone を走らせて、12347番ポートで受付けた接続を、 SSL で暗号化した上で 12346番ポートへ転送するようにする。 上記二つの stone を実行することによって、 12347番ポートへ接続すると、 後者の stone によっていったん SSL で暗号化された上で、 前者の stone で復号されて 22番ポートへつながる。 つまり 12347番ポートで ssh 通信が行なえる。
前者の stone として stone 2.3a select 版を使うと、 ssh 転送が異様に遅くなる。
% scp -P 12347 /boot/linuz-2.6.16.18 localhost:/tmp/ ... linuz-2.6.16.18 100% 1211KB 11.3KB/s 01:47
延々 2 分近くかかってしまうが、 最新の stone.c 2.2.2.25 を使って select 版を作ると、 1 秒以内に転送が終わる。 また、stone 2.3a select 版であっても「-X 512」オプションを指定しなければ、 SSL_pending でデータが検知されるケースがほとんどなくなるので、 1 秒以内に転送が終わる。 なお、stone 2.3a epoll 版には、doReadWrite ループがなく、 全てメインループで処理を行なうので、 このような問題はない。