# Non-blocking SSL handshake

**URL:** <https://www.ruby-forum.com/t/non-blocking-ssl-handshake/128359>\
**Category:** Ruby\
**Created:** [February 7, 2008, 2:20am UTC](https://www.ruby-forum.com/t/non-blocking-ssl-handshake/128359 "2008-02-07T02:20:33Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![murfhy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/d26b3c/32.png) [@murfhy](https://www.ruby-forum.com/u/murfhy)\
**Post date:** [February 7, 2008, 2:20am UTC](https://www.ruby-forum.com/t/non-blocking-ssl-handshake/128359/1 "2008-02-07T02:20:33Z")

</div>

Hello. I’m attempting to use SSL within my Fiber-based Actor framework  
(  
[http://revactor.org](http://revactor.org)) and running into problems incorporating SSL.

As far as I can discern, OpenSSL::SSL::SSLSocket#sysread and #syswrite  
are  
non-blocking (please correct me if this is wrong) if the socket is in  
the  
read/write ready state to begin with, which is great.

However, #connect and #accept, which (I believe) do the SSL handshaking,  
both block.

Is there any way to do a non-blocking SSL handshake?

---

<div class="post-metadata">

**Author:** ![murfhy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/d26b3c/32.png) [@murfhy](https://www.ruby-forum.com/u/murfhy)\
**Post date:** [February 7, 2008, 9:39pm UTC](https://www.ruby-forum.com/t/non-blocking-ssl-handshake/128359/2 "2008-02-07T21:39:27Z")

</div>

After investigating the issue some more, it appears that this is  
impossible  
without a C extension.

The ossl\_start\_ssl() function in ossl\_ssl.c, which is used by both  
OpenSSL::SSL::SSLSocket#connect and #accept, contains a loop which calls  
SSL\_connect() or SSL\_accept() repeatedly. If either of these functions  
needs the socket to be in a readable or writable state,  
rb\_io\_wait\_readable() or rb\_io\_wait\_writable() is called, blocking the  
application.

Has there been any consideration as to adding something like  
OpenSSL::SSL::SSLSocket#connect\_nonblock and #accept\_nonblock to go  
along  
with Socket#connect\_nonblock and Socket#accept\_nonblock?

---

<div class="post-metadata">

**Author:** ![murfhy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/d26b3c/32.png) [@murfhy](https://www.ruby-forum.com/u/murfhy)\
**Post date:** [February 7, 2008, 9:49pm UTC](https://www.ruby-forum.com/t/non-blocking-ssl-handshake/128359/3 "2008-02-07T21:49:28Z")

</div>

On Fri, 8 Feb 2008 05:38:57 +0900, “Tony A.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> Has there been any consideration as to adding something like  
> OpenSSL::SSL::SSLSocket#connect\_nonblock and #accept\_nonblock to go along  
> with Socket#connect\_nonblock and Socket#accept\_nonblock?

I would favor this solution myself.

-mental

---

<div class="post-metadata">

**Author:** ![murfhy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/d26b3c/32.png) [@murfhy](https://www.ruby-forum.com/u/murfhy)\
**Post date:** [February 8, 2008, 2:36am UTC](https://www.ruby-forum.com/t/non-blocking-ssl-handshake/128359/4 "2008-02-08T02:36:12Z")

</div>

On Feb 7, 2008 1:48 PM, MenTaLguY [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> 

Well, I managed to create a subclass of OpenSSL::SSL::SSLSocket in a C  
extension which implements #connect\_nonblock and #accept\_nonblock. It  
was  
quite a hack: #connect and #accept both call the static C function  
ossl\_ssl\_setup(), which for whatever reason is not called from  
#initialize.

I managed to do it by finding a third method, #session=, which also  
calls  
ossl\_ssl\_setup(). I couldn’t really figure out what this is for…  
there’s  
a whole OpenSSL::SSL::Session class defined in ossl\_ssl\_session.c, but  
the  
Init function for this file is never called, so while it’s linked into  
the  
OpenSSL C extension, it’s not accessible in the Ruby environment.

I fed #session= a bogus parameter (nil), and fortunately the method  
calls  
ossl\_ssl\_setup() before doing any typechecking on its arguments. This  
meant  
I could catch the exception it threw due to the bogus argument, but  
ossl\_ssl\_setup() was still called.

Changing the ossl\_start\_ssl() function that #connect and #accept call  
into a  
non-blocking one was pretty trivial: I just had it raise exceptions for  
when  
it needed more data to complete the connection, rather than calling  
rb\_io\_wait\_readable() / rb\_io\_wait\_writable(). If there’s any interest  
I  
can contribute the code back to the OpenSSL extension, but since it’s so  
trivial I’d encourage someone on the OpenSSL team to implement it  
themselves.
