Sebastián Treu wrote:

> The main idea was avoid polling in an infinite loop consuming CPU
> resources. I wrote that code thinking in: "If the particular client
> socket is calling our (thread) attention then fetchs the data". I
> thought on that approach as I don't know another for non-blocking IO
> without a poll cycle. If I loop forever on the  SSL_read() function,
> CPU will be kept busy on that job so I thought in a way of not having
> to do so. Instead, something should "inform" that on that socket is
> data ready to be read.

Right, but your code call 'select' even if it doesn't need to read data from
the socket.
 
> Mmmh...I can't see how to do it without select(). The main important
> thing here is that this thread is attending only 1 client. Maybe it's
> confusing because "why use select() then if you are polling always on
> the same IO socket?". Answer: I don't know if there is another system
> call to block until a file descriptor is ready to be read.

You totally missed my point. You are correct that you need to block
somewhere, you are simply blocking in the wrong place for the wrong reason.
The only reason you should ever block using 'select' on an SSL connection is
because the SSL state machine cannot make forward progress until the socket
is ready. But you call 'select' without knowing this.
 
> Then, if I read first with SSL_read() on non-blocking IO, every time
> the client isn't writting or sending anything, the server is using and
> wasting cpu cycles. Without the select() approach and with a maximun
> of 32 clients my cpu usage went to 200% ( 100 per core). With the
> select() approach the cpu usage is relative to the clients
> reading/writting actions.

What? How does calling SSL_read *first* waste CPU cycles? You *cannot* call
'select' until you *know* that you need to call 'select'. The data the SSL
state machine needs to make forward progress may already have been read.
 
> I believe you are more experienced developer than me (in fact, i'm not
> what you can call A developer) and if not much to ask, how do you
> solve this kind of problem? (without removing the roots of the
> multithreaded server design) I mean, how can you block execution
> waiting for a "noise" on the file descriptor to take some action
> without using select()?

I guess I wasn't clear. The problem is not that you are calling 'select' at
all, the problem is that you are calling 'select' even when you have
absolutely no reason to do so.

Call SSL_read. If you make forward progress, great. If you make no forward
progress, the SSL state machine will tell you why. If, for example, it
returns a 'WANT_READ' indication, then you know that the SSL state machine
cannot make forward progress unless it reads from the socket. Then, and only
then, does it make sense to call 'select'.

Again, you *MUST* get this idea out of your head:
"Read data from socket, decrypt it, pass it to application."
That is *NOT* what SSL_read does. SSL_read is *NOT* a decryption function.
It is an entry point into a state machine that can do all kinds of things,
including reading from the socket.

Here's where your code blows up horribly:

1) You call SSL_write. A renegotiation is in progress, so it reads data from
the socket to see if it can complete the renegotiation. It gets the data
needed to complete the renegotiation and some encrypted application data. It
sends the encrypted data you asked it to, and returns success.

2) You enter your broken read function and call 'select', but the data has
already arrived and been read (in step 1). You deadlock waiting forever for
data that is already here.

Do you see? You cannot call 'select' unless you know for a fact that the SSL
state machine needs to read from the socket. Otherwise you could be waiting
for something that already happened or is not supposed to happen.

Do not "look through" the SSL state machine. Let it do its job.
 
DS



______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    openssl-users@openssl.org
Automated List Manager                           majord...@openssl.org

Reply via email to