My understanding is that if SSL_ERROR_WANT_WRITE happened with
SSL_read(), the next SSL_read() would actually call write() to make
the forward progress.

-Kyle H

On Sun, Oct 25, 2009 at 11:03 PM, Darryl Miles
<darryl-mailingli...@netbauds.net> wrote:
> David Schwartz wrote:
>>
>> Darryl Miles wrote:
>>
>>> I do not believe the SSL_write() call is allowed to access the
>>> underlying BIO/kernel-socket to read in more data.  I think SSL_write()
>>> is allowed to process any data already read into buffer (from kernel to
>>> OpenSSL library internal buffer) in an attempt to unstall the situation
>>> itself.  But it can't invoke read() on the kernel for it.
>>
>> If SSL_write has to read from the socket to make forward progress, there
>> is
>> absolutely no reason it shouldn't just do so. There is no reason it should
>> compel the application to do it.
>>
>> My documentation says:
>>
>>       [T]he return value of SSL_write() will yield SSL_ERROR_WANT_READ or
>>       SSL_ERROR_WANT_WRITE. As at any time a re-negotiation is possible, a
>>       call to SSL_write() can also cause read operations! The calling
>> process
>>       then must repeat the call after taking appropriate action to satisfy
>>       the needs of SSL_write(). The action depends on the underlying BIO.
>>       When using a non-blocking socket, nothing is to be done, but
>> select()
>>       can be used to check for the required condition. When using a
>> buffering
>>       BIO, like a BIO pair, data must be written into or retrieved out of
>> the
>>       BIO before being able to continue.
>>
>> This suggests the exact opposite of what you said. One of these sources is
>> right and the other is wrong, and it makes a huge difference which!
>>
>> My understanding, for many years, coincides with this documentation.
>> However, I can't think of any specific case where this difference would
>> have
>> affected me, as my coding is extremely defensive and would tolerate either
>> mechanism without a problem.
>
> "One of these sources is right and the other is wrong" ... Yes, no, maybe...
>  You maybe correct in the detail here, I am going on my hazy-memory of
> experimenting with this situation and the observable behavior.  But I never
> wrote up notes on the matter not saw fit to improve the documentation.
>
> My conclusions on it were that an SSL_write() can cause a packet decode to
> complete but only:
>  * If the data for the entire packet has already been read() into the SSL
> user-space buffer (i.e. no longer in the BIO/kernel).  The read-ahead
> optimization makes it possible for this to happen.
>  * If there is no application data waiting to be destructively removed ahead
> of the re-negotiation packet.  i.e. SSL_read().  Until all application data
> has been sunk/removed from OpenSSL it won't decode the next packet.
>
> My memory on this was that SSL_write() itself won't call on the BIO to
> perform a read() but it will attempt to decode the next incoming packet from
> the data it may already have, this is in the hope that it turns out to be
> the re-negotiation response (in many situations it gets lucky!). If it
> decodes the next packet and it turns out to be incoming application data
> then SSL_write() is stuffed!  No amount of calling it again will clear the
> -1/WANT_READ condition.
>
>
>
> The largest part of my previous post was explaining how to handle the
> situation generalls and calling SSL_read() and then re-trying SSL_write() to
> see if the condition has cleared it the way to deal with it.  You can not
> rely on repeatedly calling SSL_write() alone to clear the problem.  Which
> was my interpretation of what Jason was asking.
>
>
>
> To re-express the same thing another way:
>
> SSL_write() calls can not by-pass the already in-progress inbound
> application data (to get at the re-negotiation response packet immediately).
>  There is a possibility there is still some application data waiting to be
> SSL_read() before the re-negotiation SSL protocol packet can be seen,
> decoded and processed.
>
> Imagine the re-negotiation SSL protocol packet is actually still inside the
> kernel buffering (waiting for user-space to read() to pull it).  Now image
> that there are at least 2 large full-size application data packets also
> spanned across the user-space and kernel buffers (ahead of the SSL
> re-negotiation packet).
>
> SSL_write() has no where to put the data once it has decoded a large
> full-sized application data packet.  Inside OpenSSL there is a rigid
> buffering scheme, there is a decode buffer into which the encrypted packet
> is read in from BIO/kernel.  There is also a clear-text buffer into which
> the resultant application data from a single packet decode can be stored.
>  The decode/decyption process only takes place if the clear-text buffer is
> empty (i.e. user-space has SSL_read() all the previous data from it, so it
> will attempt to pull in more data and re-fill it).
>
> It is for sure that OpenSSL doesn't have an infinite expandable memory
> buffer to keep holding application data to allow SSL_write() to find the
> re-negotiation packet.  So it is the worst-case scenario I have in mind when
> explaining how to handle the matter in my previous post.
>
>
>
> The documentation could certainly be improved no matter what the correct way
> to express the situation is.  The docs were written to support the
> implementation (not the other way around).
>
>
> Darryl
> ______________________________________________________________________
> OpenSSL Project                                 http://www.openssl.org
> User Support Mailing List                    openssl-us...@openssl.org
> Automated List Manager                           majord...@openssl.org
>
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    openssl-users@openssl.org
Automated List Manager                           majord...@openssl.org

Reply via email to