> >     If you get a 'select' hit, whether for readability or
> > writability, you
> >should retry *all* operations, whether reads or writes.
> > (Obviously, don't
> >call SSL_write unless you have some data to write!)

> >     Again, I also recommend trying an SSL_read on any hit,
> > whether for
> >readability or writability, before doing anything else. This
> > will 100%
> >ensure you don't deadlock (as long as you call SSL_read after
> > each SSL_write
> >until it runs out) nd it will give you better behavior under
> > edge conditions
> >like memory pressure.

> Sorry, but could you give a little more explaination for this,
> probably with an example?

        There are two things going on here.

        One is a low memory condition. An attempt to write may fail even though
there's data to be read. So you want to call SSL_read before SSL_write in a
condition where you're going to call both.

        However, this can cause a nasty race condition. You select for 
writability
because you're writing a lot. You get a hit, you call SSL_write. While
SSL_write is running it has to read some data from the socket. This turns
out to be application data. If you don't call SSL_read (even though you
never got a readability hit from 'select'), you can deadlock. (The data is
not on the socket anymore, the SSL engine has it.)

        So you should only 'select' when SSL tells you to. Otherwise, assume the
operation might complete without blocking, because it in fact might. Do not
'select' for readability just because you want to read *unencrypted* data.
Only 'select' for readability if the SSL engine tells you that it needs to
read data to make forward progress. (In fact, there's no harm in doing the
'select', but there is harm in refusing to call SSL_read until you get a hit
from 'select'.)

> So in short,
> 1) you check for socket readability if you get WANT_READ for
> your last operation, and on hit you retry the last operation
> (whether SSL_read or SSL_write).

        Correct. And you do not wait for 'select' to give you a read hit to call
SSL_read -- the SSL engine might have already read the data from the socket
during a call to SSL_write!

> 2) You check for socket writability if you get WANT_WRITE for
> the last operation, and on hit you retry that operation.

        Yes.

> Is this understanding correct?

        You got it. Basically, you do not assume any connection between the 
motion
of encrypted data and the motion of unencrypted data.

> With this understanding, the following piece of code should
> work with an assumption that you beforehand know how much of
> application data are you expecting and set the buffer size
> appropriately. Buffer full is one condition when you return ....
>
> select(for the socket readability)
> socket_ssl_read(fd) /* This is the wrapper */
> process_the_data();
>
> socket_ssl_read(fd)
> {
>     set appropriate buffer size;
>     while(1)
>     {
>         ret = SSL_read();
>         if (ret < 1)
>         {
>            ret1 = SSL_get_error();
>            switch(ret1)
>            {
>            case WANT_READ:   select(for readability);
>                              break;
>            case WANT_WRITE:  select(for writability);
>                              break;
>            default:  return error;
>            }
>         }
>         if (buffer full)
>            return;
>     }
> }
> Something similar can be done for SSL_write wrapper.
>
> In the current context, these wrappers can be called for each
> connectio descriptor.
> But then the wrappers will return only on error or after they
> read the full data. So will that actually exibit blocking
> behavior?

        Yes, this seems to be pseudo-code for a correct way to get blocking
behavior with non-blocking sockets. Of course, it's not really blocking
behavior because the calls to 'select' allow you to get other work done. I
believe that's what you want, so this should give it to you.

        DS


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

Reply via email to