[#24112] ruby/tk crashes on bcc32 — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp>

山本です。原因を追求してたのですが、力尽きました。

19 messages 2004/08/18
[#24127] Re: ruby/tk crashes on bcc32 — Hidetoshi NAGAI <nagai@...> 2004/08/19

永井@知能.九工大です.

[#24131] Re: ruby/tk crashes on bcc32 — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp> 2004/08/19

山本です。

[#24135] Re: ruby/tk crashes on bcc32 — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp> 2004/08/19

山本です。試行錯誤の結果、これで落ちなくなりました。

[ruby-dev:24072] SSLSocket#wait

From: GOTOU Yuuzou <gotoyuzo@...>
Date: 2004-08-13 20:16:17 UTC
List: ruby-dev #24072
ごとうゆうぞうです。

やまださんに教えてもらったのですが、

  http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=265429

というレポートが出ています。調べてみたところ、SSLのレベルで
バッファされたデータがある場合に、IO.selectで待っても返って
こないのが原因のようです。

SSLSocketが到着済みのデータを検出するインターフェースを提供
していなかったので、他にどうすることもできなかったのですが、
io/waitに合わせてSSLSocket#wait([timeout])を用意することにし
ようと思います。

そして、net/protocol.rbのNet::InternetMessageIO#rbuf_fillで、
ソケットがwaitを持っていればこれを使い、そうでなければこれま
で通りIO.selectを使うようにすると良さそうなのですが、どうで
しょう。

# 1.8と1.9の両方に同様の対処をしようと思いますが、添付のパッ
# チは1.9用です。

-- 
ごとうゆうぞう

Index: lib/net/protocol.rb
===================================================================
RCS file: /var/cvs/src/ruby/lib/net/protocol.rb,v
retrieving revision 1.77
diff -u -p -F^[^A-Za-z0-9_+-]*\(class\|module\|def\)[^A-Za-z0-9_+-] -r1.77 protocol.rb
--- lib/net/protocol.rb	10 May 2004 13:28:26 -0000	1.77
+++ lib/net/protocol.rb	13 Aug 2004 20:11:36 -0000
@@ -129,7 +129,8 @@     def readline
     private
 
     def rbuf_fill
-      until IO.select([@io], nil, nil, @read_timeout)
+      unless @io.respond_to?(:wait) ? @io.wait(@read_timeout) :
+               IO.select([@io], nil, nil, @read_timeout)
         raise TimeoutError, "socket read timeout (#{@read_timeout} sec)"
       end
       @rbuf << @io.sysread(1024)
Index: ext/openssl/ossl_ssl.c
===================================================================
RCS file: /var/cvs/src/ruby/ext/openssl/ossl_ssl.c,v
retrieving revision 1.14
diff -u -p -F^[^A-Za-z0-9_+-]*\(class\|module\|def\)[^A-Za-z0-9_+-] -r1.14 ossl_ssl.c
--- ext/openssl/ossl_ssl.c	26 May 2004 18:11:29 -0000	1.14
+++ ext/openssl/ossl_ssl.c	13 Aug 2004 20:11:36 -0000
@@ -513,6 +513,10 @@ ossl_ssl_read(int argc, VALUE *argv, VAL
 	    case SSL_ERROR_WANT_READ:
 		rb_thread_schedule();
 		continue;
+	    case SSL_ERROR_SYSCALL:
+		if(ERR_peek_error() == 0 && nread == 0)
+		    ossl_raise(rb_eEOFError, "End of file reached");
+		ossl_raise(eSSLError, "SSL_read: %s", strerror(errno));
 	    default:
 		ossl_raise(eSSLError, "SSL_read:");
 	    }
@@ -705,6 +709,20 @@ ossl_ssl_get_state(VALUE self)
     return ret;
 }
 
+static VALUE
+ossl_ssl_pending(VALUE self)
+{
+    SSL *ssl;
+
+    Data_Get_Struct(self, SSL, ssl);
+    if (!ssl) {
+        rb_warning("SSL session is not started yet.");
+        return Qnil;
+    }
+
+    return INT2NUM(SSL_pending(ssl));
+}
+
 void
 Init_ossl_ssl()
 {
@@ -744,6 +762,7 @@     /* class SSLSocket */
     rb_define_method(cSSLSocket, "peer_cert_chain", ossl_ssl_get_peer_cert_chain, 0);
     rb_define_method(cSSLSocket, "cipher",     ossl_ssl_get_cipher, 0);
     rb_define_method(cSSLSocket, "state",      ossl_ssl_get_state, 0);
+    rb_define_method(cSSLSocket, "pending",    ossl_ssl_pending, 0);
 
 #define ossl_ssl_def_const(x) rb_define_const(mSSL, #x, INT2FIX(SSL_##x))
 
Index: ext/openssl/lib/openssl/buffering.rb
===================================================================
RCS file: /var/cvs/src/ruby/ext/openssl/lib/openssl/buffering.rb,v
retrieving revision 1.6
diff -u -p -F^[^A-Za-z0-9_+-]*\(class\|module\|def\)[^A-Za-z0-9_+-] -r1.6 buffering.rb
--- ext/openssl/lib/openssl/buffering.rb	26 May 2004 18:11:29 -0000	1.6
+++ ext/openssl/lib/openssl/buffering.rb	13 Aug 2004 20:11:36 -0000
@@ -31,7 +31,9 @@   def initialize(*args)
   def fill_rbuff
     @rbuffer = "" unless defined? @rbuffer
     begin
-      if self.respond_to?(:to_io)
+      if self.respond_to?(:wait)
+        self.wait
+      elsif self.respond_to?(:to_io)
         IO.select([self.to_io], nil, nil)
       end
       @rbuffer << self.sysread(BLOCK_SIZE)
Index: ext/openssl/lib/openssl/ssl.rb
===================================================================
RCS file: /var/cvs/src/ruby/ext/openssl/lib/openssl/ssl.rb,v
retrieving revision 1.7
diff -u -p -F^[^A-Za-z0-9_+-]*\(class\|module\|def\)[^A-Za-z0-9_+-] -r1.7 ssl.rb
--- ext/openssl/lib/openssl/ssl.rb	26 May 2004 18:11:29 -0000	1.7
+++ ext/openssl/lib/openssl/ssl.rb	13 Aug 2004 20:11:36 -0000
@@ -52,6 +52,23 @@       def do_not_reverse_lookup=(flag)
     class SSLSocket
       include Buffering
       include SocketForwarder
+
+      def ready?
+        if (size = pending) && (size > 0)
+          return size
+        end
+        return nil
+      end
+
+      def wait(timeout=nil)
+        if (size = pending) && (size > 0)
+          return self
+        elsif IO.select([self], nil, nil, timeout)
+          return self
+        else
+          return false
+        end
+      end
     end
 
     class SSLServer

In This Thread

Prev Next