- キット各種完売。
- msBerryDAC改造情報
2007/06/03(日)やっぱり Tualatin は熱い
この前Pentium3 800MHzからCeleron 1.4AGに載せ替えたCPUファンレスのメインマシンですが、気温が上がってきて熱くなってきました。触ると50~60℃ぐらいで書いて、唯一まわってる電源ファンの回転数がときどき上昇します。
TualatinはCPUの利用状況によらず電力を消費し続けるのでその辺が痛いです*1。クロックはかなり上昇していますが、FSBが133→100と下がっていることもあり、あまり恩恵には与れていません。
Pen3 800MHzに戻してみたら動かないし……。たしかこのCPUも拾いものだから壊れたのかなぁ……。ふと、Pentium3(Coppermine)の1Gの値段みてたら2000円しないので買おうかと検討中。
買いました
Pentium3 1GHz(SL4MF)、2千円。当時のプレミアを思えば考えられない破格ですね。ベンチマーク上は800MHzとほとんど変わらない性能。でも体感的には、ほとんど変わりません。何より負荷がかかってないときCPUが発熱しないのがいいです。
電圧設定が若干やりにくく1.55V設定(1.538V)で駆動しています。下げてもあと0.5Vぐらいが限界でしょうが、いろいろジャンパ飛ばすのが面倒なのでこのままにしておきます。
2007/05/25(金)FreeBSDはなぜ標準で APOP に対応していない?
FreeBSDでは比較的標準的に利用される pop デーモンである popa3d は、なぜか apop をサポートしていません。不思議に思ってつらつらと man を読んでいたら、次のように書かれていました。
POP3 transmits passwords in plaintext and thus, if you care about the security of your individual user accounts, should only be used either in trusted networks or tunneled over encrypted channels.
There exist extensions to the protocol that are supposed to fix this problem. popa3d does not support them yet, partly because this isn't going to fully fix the problem. In fact, APOP and the weaker defined SASL mechanisms such as CRAM-MD5 may potentially be even less secure than transmission of plaintext passwords because of the requirement that plaintext equivalents be stored on the server.
英語の練習がてら意訳してみますと、
POP3 はパスワードを平文で送ります。あなたのアカウントのセキュリティーが心配でならば、信頼されたネットワークか暗号化された通信経路を用いてください。
この問題を解決するためのプロトコルの拡張(注:APOP等のこと)が存在しますが、popa3d はサポートしていません。なぜなら、この拡張は問題を部分的に解決しますが完全な解決にはならないからです。実際、APOP や脆弱性のある SASL では CRAM-MD5 のような方式が使われおり、サーバに直接平文パスワードを記述する必要があるため、場合によっては平文パスワード認証よりもセキュリティーが劣ってしまいます。
つまりは、いくら通信路の安全を守るためとは言っても、サーバ上に大量のユーザーの平文パスワードを記述することはセキュリティ上問題ありませんかということですね。
調べてみると、apop自体に問題があるらしいですが。
結局popもftpもダメで、ssh(ssl) でトンネルしたもの以外は現状信用できないということになるんでしょうねぇ……。PAM の元に SMTP も POP も安全な形で統一してほしいのココロ。*1
2007/05/23(水)UDPをTCPにクローンするプログラム
UDPを受信してTCPにクローンするプログラム(複数クライアント対応)。本当はマルチスレッドで書いてあげるべきなのですが、そこまですると(実現する処理に対して)高級するぎる気がしたのでポーリングにしました。
というのも、TCPの通信エラーとかが出たときに(ブロックしないはずの)ソケットへの書き込み(データの送信)がバッファ一杯になるとストールして(止まって)しまうんですよね。もちろんソケットや書き込み時の関数はノンブロッキングに設定しておいても、です。C ではまだ確認していませんが、Perlで書いたときはそうでした。
TCP/IPはただ通信するだけなら簡単ですが、この手のエラー処理を考えはじめると非常に頭を使います。
プログラム
メイン部のみ。適当に main ルーチンを書けば Windows でも Unix系 でも動きます。
int max_connections=100; char buffer[0x10000]; int connection_pool[max_connections]; int accept_client(int listen_sock) { int sock, len; struct sockaddr_in sin; // accept len = sizeof(sin); sock = accept(listen_sock, (struct sockaddr *)&sin, &len); if (sock<0) error_return("client accept error"); // 接続者情報 printf("[%02d] Connection from %s\n", sock, inet_ntoa(sin.sin_addr)); // ソケットの設定 set_non_blocking(sock); return sock; } ////////////////////////////////////////////////////////////////////////////// // server main ////////////////////////////////////////////////////////////////////////////// int udp2tcp_server_main(int udp_sock, int tcp_sock) { int i; char buf[1024]; // select用の設定 fd_set fdbits; fd_set fdbits_org; FD_ZERO(&fdbits_org); FD_SET(udp_sock, &fdbits_org); FD_SET(tcp_sock, &fdbits_org); while(1) { // Select memcpy(&fdbits, &fdbits_org, sizeof(fdbits_org)); select(FD_SETSIZE, &fdbits, NULL, NULL, NULL); // New connection from TCP if ( FD_ISSET(tcp_sock, &fdbits) ) { int newsock = accept_client(tcp_sock); if (newsock>0) { // search for free connection pool point for(i=0; i<max_connections; i++) if (!connection_pool[i]) break; if (i<max_connections) { // ソケット番号をセーブ FD_SET(newsock, &fdbits_org); connection_pool[i] = newsock; dbg("[%02d] save to connection_pool[%d]\n", newsock, i); } else { // 接続を切る printf("Connections max\n"); close(newsock); } } } // Recieved from UDP int size = 0; if ( FD_ISSET(udp_sock, &fdbits) ) { size = recv(udp_sock, buffer, BUF_SIZE, MSG_DONTWAIT); if (size<0) error_exit2("UDP recv error(%d)", size); dbg("[%02d] Recieved UDP %d bytes\n", udp_sock, size); } // TCP接続クライアントにデータを送信 for(i=0; i<max_connections; i++) { int sock = connection_pool[i]; if (!sock) continue; // socket からデータ受信 if ( FD_ISSET(sock, &fdbits) ) { int s = recv(sock, buf, 1024, MSG_DONTWAIT); if (s<0) { FD_CLR(sock, &fdbits_org); connection_pool[i] = 0; dbg("[%02d] clear to connection_pool[%d]\n", sock, i); printf("[%02d] Connection close\n", sock); close(sock); continue; } } // データ送信 if (size>0) { //int s = write(sock, buf, size); int s = send(sock, buf, size, MSG_DONTWAIT); dbg("[%02d] write TCP %d bytes\n", sock, s); } } } }