From: GOTOU Yuuzou Date: 2003-12-06T21:49:20+09:00 Subject: [ruby-dev:22172] Re: invalid parameter to fcntl in drb.rb In message <263A4B5D-27E2-11D8-B108-000393814512@mva.biglobe.ne.jp>, `Masatoshi SEKI ' wrote: > > SSLでO_NONBLOCKにするとまずいというのは他のところでもおきている > > ようなのですが、O_NONBLOCKにする必要はあるのでしょうか? > > > > # http://lists.community.tummy.com/pipermail/enbd/2001/000228.html > > # http://mail.gnu.org/archive/html/monit-dev/2002-11/msg00069.html > > # など > > なんでNOBLOCKにしていたか思い出せません。 > SSLに限らずNONBLOCKしないようにしたら問題あるかなあ。 > > 抜いてcommitしてしまおうかしら。 出遅れてしまいましたが、SSL_accept や SSL_accept の際にもう 一度呼び出す必要があるケースがあるようなので、添付のパッチの ように対処してみたところ、NetBSD 1.6ZC での test_drbssl は通 るようになりました。 先にこっちをコミットしたほうがいいですかね。 -- ごとうゆうぞう Index: ossl_ssl.c =================================================================== RCS file: /src/ruby/ext/openssl/ossl_ssl.c,v retrieving revision 1.10 diff -u -p -r1.10 ossl_ssl.c --- ossl_ssl.c 4 Nov 2003 23:48:13 -0000 1.10 +++ ossl_ssl.c 6 Dec 2003 12:29:38 -0000 @@ -435,6 +435,27 @@ ossl_ssl_setup(VALUE self) return Qtrue; } +static void +ossl_start_ssl(SSL *ssl, int (*func)()) +{ + int ret; + + for(;;){ + if((ret = func(ssl)) > 0) break; + switch(SSL_get_error(ssl, ret)){ + case SSL_ERROR_NONE: + break; + case SSL_ERROR_WANT_WRITE: + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_X509_LOOKUP: + rb_thread_schedule(); + continue; + default: + ossl_raise(eSSLError, "SSL_accept:"); + } + } +} + static VALUE ossl_ssl_connect(VALUE self) { @@ -445,9 +466,7 @@ ossl_ssl_connect(VALUE self) Data_Get_Struct(self, SSL, ssl); cb = ossl_sslctx_get_verify_cb(ossl_ssl_get_ctx(self)); SSL_set_ex_data(ssl, ossl_ssl_ex_vcb_idx, (void *)cb); - if (SSL_connect(ssl) <= 0) { - ossl_raise(eSSLError, "SSL_connect:"); - } + ossl_start_ssl(ssl, SSL_connect); return self; } @@ -462,9 +481,7 @@ ossl_ssl_accept(VALUE self) Data_Get_Struct(self, SSL, ssl); cb = ossl_sslctx_get_verify_cb(ossl_ssl_get_ctx(self)); SSL_set_ex_data(ssl, ossl_ssl_ex_vcb_idx, (void *)cb); - if (SSL_accept(ssl) <= 0) { - ossl_raise(eSSLError, "SSL_accept:"); - } + ossl_start_ssl(ssl, SSL_accept); return self; } @@ -482,7 +499,9 @@ ossl_ssl_read(VALUE self, VALUE len) str = rb_str_new(0, ilen); if (ssl) { + TRAP_BEG; nread = SSL_read(ssl, RSTRING(str)->ptr, RSTRING(str)->len); + TRAP_END; if (nread < 0) { ossl_raise(eSSLError, "SSL_read:"); }