OpenSSL は色々と苦労が多い。今回ハマったのは、ハンドシェークや通信のやりとりを実行する層・・・というかバッファーを挟む為、socket を select しても反応が無いくせに、バッファーにだけはデータが溜っていたという奴。
○ シナリオはこう。送信側が SSL_write でデータを送信する。受信側は select 系システムコールを用いて受信可能状態になれば SSL_read を行う。SSL_read を行うと SSL 層は socket からある程度のサイズのデータを読み出す(man を見るかぎり 16kB?)。だが、この SSL 層のバッファーに溜っているよりも小さなサイズのデータを読み出してしまった場合に困ったことになってしまう。次の SSL_read を行えばバッファーに残っている分を読み出すなり出来るわけだが、socket に変化が無い為 select に頼っている限りは、SSL_read が出来なくてハマり状態に陥ってしまう。この時現象としては、送信側の SSL_write が延々 SSL_ERROR_WANT_WRITE を返すという挙動として現れる。
○ SSL の挙動を追っていないのでなんともだけど、この時恐らく受信側は、送信側に「待たんか!ワレ」とストップをかけているのやろうね。もしストップがかかっていないのであれば送信側は遠慮なくデータを送りつづける事になるので、socket には変化があるわけだから。(もっとも、その場合でも送信側が送信しきった後は変化が止まるわけだから、この考え方ではいけないわけだけど)。
○ まぁ、とりあえず 16kB を意識して十分なバッファーを用意して一気に読み出せという事なのか・・・。でも、SSL_read から読み出すべきデータサイズを教えてくれるような素敵な API があるわけでもないので、もしかしたら何回も読み出せという間抜けなコードを書いたいいのか・・・。悩ましい限り。
○ あ、後マニュアルを見ると WANT_WRITE だの WANT_READ だのが帰ってきた場合は、同じ引数でもっかいアクセスしろぉ〜と書いてあったりする。まぁ今回の問題とは関係なかったっぽいが。