I am very, very new to openssl. There is a good example (Example 5-16,
Network Security with Openssl book)) for using nonblocking openssl. It
is easy to understand. It uses one thread to handle 2 nonblocking
socket. You may have to modify it to handle multithread. At least, you
have example to follow. I am trying to modify this example, so one
openssl socket is handled by one thread using select ( native API) to
monitor socket.

Thao Dinh  

-----Original Message-----
From: [EMAIL PROTECTED]
[mailto:[EMAIL PROTECTED] On Behalf Of David Schwartz
Sent: Thursday, October 19, 2006 20:54
To: openssl-users@openssl.org
Subject: RE: Multithreading problem


> This problem was raised on this mailing list many times, but the clear

> solution (in my opinion) was not given. From OpenSSL FAQ:
> ...an SSL connection may not concurrently be used by multiple 
> threads... This means that I can't have 2 threads, one reading and one

> writing at the same time from the same socket. My application is basic

> Jabber communicator (messager) I should to constantly listen on socket

> for incoming messages and at the same time send messages written by 
> me.(this is not communication model like for example in http: 
> request,response,request,response.etc.)
> If I use simple TCP connection I create 2 threads one reading, one 
> writing. This is simple,fast and correct.(reding and writing are 
> blocking).

Actually, it's extremely complicated. For example, what do you do if you
call 'write' and it doesn't return in a reasonable amount of time?

> But when have to SSL connection this is much more complicated. I'm 
> using Delphi and Indy components. There are sugesstion on mailing list

> that concurrent socket usage can be avoided by creating non-blocking 
> socket and mutex, which is locked when any thread is using socket. But

> non-blocking socket is more complex to implement and forces me to not 
> use Indy component, since Indy components are desined to work only in 
> blocking mode (for TCP sockets this is correct design, I've read that 
> Indy 10 has an option in core to work in non-blocking mode but I don't

> known if this option is exposed to user the same way as in socet API 
> (maybe it was added to other purposes), but I have Indy 9 and don't 
> want to upgrade). So using nonblocking sockets forces me to implement 
> everything in native socket API, using  OpenSSL API (currently Indy 
> does it internally) and deal with additional complexivity of 
> nonblocking sockets.

Doesn't this kind of prove that your assumption (that non-blocking
sockets are more complicated) is wrong? Look at all the craziness you
have to go through to get blocking sockets to work right.
 
> Is there any OpenSSL function similar to socket API 'select' 
> (SSL_select) ???? If yes, then I can use blocking sockets. One thread 
> is waiting in blocking SSL_select for incoming messages, If massage 
> will come then this thread will try to acquire mutex and then carry 
> out blocking SSL_read which will not block because there is message on

> socket. I can't do this with socket API 'select' because it signals 
> any data on socket not exactly data on which SSL_read will not block. 
> (TLS renogotiation or something like this). I hope you known what I 
> mean.
> (I have tried with SSL_pending but it return 0 even if there are data 
> on socket)

You cannot use 'select' with blocking sockets. If you do, and your
'write' blocks (say because only a few bytes could be written at that
instant), you won't be able to call 'read'.

> Any suggestions? Can someone help me with this?

If you want to use blocking sockets, you can. Just use BIO pairs. You
would then have one thread that asks OpenSSL if it has any data that
needs to be written, if so, you grab it from OpenSSL (using non-blocking
operations), then block on the socket while you write it. You can keep a
thread blocked on 'read' and when you get any data from the socket, you
hand if to OpenSSL. Protect the whole BIO pair assembly with a mutex,
which you only hold while you enter the non-blocking OpenSSL logic.

So it works like this:

1) When you want to write plaintext data to the SSL layer, grab the SSL
mutex, call a non-blocking write function. If you don't write it all,
release the mutex and block on the SSL conditition variable. If you make
any forward progress, broadcast the condition variable.

2) When you want to read plaintext data from the SSL layer, grab the SSL
mutex, call a non-blocking read function. If you get no data, release
the mutex and block on the condition variable. If you make any forward
progress, broadcast the condition variable.

3) In your read thread, when you get data from the socket, grab the SSL
mutex, give the data to a non-blocking write function on the SSL BIO. If
you wrote it all, release the mutex and signal the condition variable.
If not, block on the condition variable until you write it all.

4) In your write thread, grab the mutex and block on the condition
variable. When woken, get any data from the SSL BIO. Release the mutex,
signal the condition variable, and write it to the socket. When you can
no longer make forward progress, block on the condition variable
(implicitly releasing the condition variable).

I wrote this quickly and unfortunately have to go before I have a chance
to proofread it, but it should give you the idea.

DS


______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    openssl-users@openssl.org
Automated List Manager                           [EMAIL PROTECTED]
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    openssl-users@openssl.org
Automated List Manager                           [EMAIL PROTECTED]

Reply via email to