opensslのライブラリを使ったネットワークプログラミングは通常のBSD socketプログラミングが出来ればほぼそのまま関数をちょっと追加したり置き換えたりするだけで対応できるの(しかしドキュメントが中途半端で辛いです)ですが、selectで入力を待つところが微妙におかしなことになっています。
冷静に考えるとSSL通信の検証や復号化のためにはバイト単位ではなくある程度大きな単位で読み込んだ上でないと出来ないので、SSL_readで1バイトとか細々と読み込むとSSLライブラリ内のバッファにはデータがあるけれどselectは反応しない、という事態は当然発生するのですが。
従ってSSL化したソケットをselectするときは同時にSSLのバッファにデータ残っていないか調べる必要があります。SSL_pending(SSL* ssl)関数でバッファに残っているデータのバイト数が取得できるので、
fd_set readfds;
int nfds;
struct timeval timeout;
nfds=SSLfileno(ssl)+1;
timeout.tv_sec=0;timeout.tv_usec=0;
while(1)
{
FD_ZERO(&readfds);
FD_SET(SSL_get_fd(ssl),&readfds);
int pending=SSL_pending(ssl);
if(!pending){select(nfds,&readfds,(fd_set*)0,(fd_set*)0,&timeout);};
if(pending || FD_ISSET(SSLfileno(ssl),&readfds))
{
読み込み処理
}
}
みたいなコーディングをすればいいようです。
2008-09-04 01:51:45[プログラミング]
この記事へのトラックバックURL: https://www.asmusic.jp/ASHARD/score/tb.cgi/yu-oishi/20080902_1
手動トラックバック