aboutsummaryrefslogtreecommitdiffstats
path: root/ext/openssl/ossl_ssl.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/openssl/ossl_ssl.c')
-rw-r--r--ext/openssl/ossl_ssl.c55
1 files changed, 29 insertions, 26 deletions
diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c
index e85430e859..323dc97f83 100644
--- a/ext/openssl/ossl_ssl.c
+++ b/ext/openssl/ossl_ssl.c
@@ -433,52 +433,49 @@ ossl_ssl_setup(VALUE self)
return Qtrue;
}
-static void
-ossl_start_ssl(SSL *ssl, int (*func)())
+static VALUE
+ossl_start_ssl(VALUE self, int (*func)())
{
+ SSL *ssl;
+ OpenFile *fptr;
+ VALUE cb;
int ret;
+ Data_Get_Struct(self, SSL, ssl);
+ GetOpenFile(ossl_ssl_get_io(self), fptr);
+ cb = ossl_sslctx_get_verify_cb(ossl_ssl_get_ctx(self));
+ SSL_set_ex_data(ssl, ossl_ssl_ex_vcb_idx, (void *)cb);
for(;;){
if((ret = func(ssl)) > 0) break;
switch(SSL_get_error(ssl, ret)){
case SSL_ERROR_WANT_WRITE:
+ rb_io_wait_writable(fptr->fd);
+ continue;
case SSL_ERROR_WANT_READ:
- rb_thread_schedule();
- continue;
+ rb_io_wait_readable(fptr->fd);
+ continue;
+ case SSL_ERROR_SYSCALL:
+ rb_sys_fail(0);
default:
ossl_raise(eSSLError, NULL);
}
}
+
+ return self;
}
static VALUE
ossl_ssl_connect(VALUE self)
{
- SSL *ssl;
- VALUE cb;
-
ossl_ssl_setup(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);
- ossl_start_ssl(ssl, SSL_connect);
-
- return self;
+ return ossl_start_ssl(self, SSL_connect);
}
static VALUE
ossl_ssl_accept(VALUE self)
{
- SSL *ssl;
- VALUE cb;
-
ossl_ssl_setup(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);
- ossl_start_ssl(ssl, SSL_accept);
-
- return self;
+ return ossl_start_ssl(self, SSL_accept);
}
static VALUE
@@ -512,8 +509,10 @@ ossl_ssl_read(int argc, VALUE *argv, VALUE self)
case SSL_ERROR_ZERO_RETURN:
rb_eof_error();
case SSL_ERROR_WANT_WRITE:
+ rb_io_wait_writable(fptr->fd);
+ continue;
case SSL_ERROR_WANT_READ:
- rb_thread_schedule();
+ rb_io_wait_readable(fptr->fd);
continue;
case SSL_ERROR_SYSCALL:
if(ERR_peek_error() == 0 && nread == 0) rb_eof_error();
@@ -542,9 +541,11 @@ ossl_ssl_write(VALUE self, VALUE str)
{
SSL *ssl;
int nwrite = 0;
+ OpenFile *fptr;
StringValue(str);
Data_Get_Struct(self, SSL, ssl);
+ GetOpenFile(ossl_ssl_get_io(self), fptr);
if (ssl) {
for (;;){
@@ -553,11 +554,13 @@ ossl_ssl_write(VALUE self, VALUE str)
case SSL_ERROR_NONE:
goto end;
case SSL_ERROR_WANT_WRITE:
+ rb_io_wait_writable(fptr->fd);
+ continue;
case SSL_ERROR_WANT_READ:
- rb_thread_schedule();
- continue;
+ rb_io_wait_readable(fptr->fd);
+ continue;
case SSL_ERROR_SYSCALL:
- rb_eof_error();
+ rb_sys_fail(0);
default:
ossl_raise(eSSLError, "SSL_write:");
}