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