Excuse me if I am saying the obvious. But did you factor the fact that an SSL renegotiation or handshake can happen anytime during the conversation?
Irrespective of whether you are doing SSL_read or SSL_write... That is why you have to check for pending write during a SSL_read and vice versa in the non blocking case. This is what the manpage says at least. I may be wrong here. --- Henrik Thuermer <[EMAIL PROTECTED]> wrote: > At 11:59 17.07.2006 +0100, you wrote: > >Henrik Thuermer wrote: > >> If we receive some data we process it via one > BIO_write call followed by > >> SSL_read calls until the call to SSL_read fails > with SSL_get_error() == > >> SSL_ERROR_WANT_READ or SSL_read returns no more > data (SSL_ERROR_WANT_WRITE > >> is also handled correctly - I hope). Then we stop > reading from the ssl > >> connection until we receive new data. > > > >Just to confirm your understanding on this point, > as your description is > >unclear. > > Sorry if I was unclear in my email. > > > > >You may not necessarily receive new data, as in new > >application level data. > > > > I do not understand what you mean here. Maybe the > misunderstanding is that > you assume the ssl library handles the tcp socket? > But in our case the > socket handling (send/recv) is done by the > application not by the ssl library. > > If I write "receive some data" I mean our > application reads the data from a > TCP socket and transfer it to the ssl connection via > BIO_write. Our read > routine looks something like this (The BIO was > "connected" to the ssl > object with SSL_set_bio before ssl connection > setup): > > void ReceiveSomeData(SSL* ssl, SOCKET s, BIO* > bioRead) > { > > .... > > int rcvd = recv(s, recvBuffer, 8192, 0); > > int bytesWritten = BIO_write(bioRead, > recvBuffer, rcvd); > > if (bytesWritten != rcvd) { > assert(false); > // this never happens during our tests > } > > while (true) { > > char buffer[bufferLength]; > int bytesRead = SSL_read (ssl, buffer, > bufferLenght); > > if (bytesRead > 0) > DoSomethingWithTheData(); > else if (bytesRead == 0) > // nothing more to decrypt -> stop here > until we receive more data > break; > else if (bytesRead < 0) { > if (SSL_get_error() == > SSL_ERROR_WANT_READ) { > // nothing more to decrypt -> stop > here until we receive > more data > ERR_clear_error(); > break; > } > if (SSL_get_error() == > SSL_ERROR_WANT_WRITE) { > // never happens during our test > (initial ssl connection > setup is done > // at another place) > ERR_clear_error(); > SendOutStandingSSLData(); > } > } > } > > ... > } > > > > >It is safe to keep trying SSL_write() after every > SSL_read() to see if > >it can do more work, otherwise it will persist with > the WANT_READ state. > > > > I'm really not familiar with the library sorce code. > I only stepped into it > during debugging and found the following: > > SSL_read internally calls ssl2_read_internal: > > static int ssl2_read_internal(SSL *s, void *buf, int > len, int peek) > { > > ... > > if (s->rstate == SSL_ST_READ_BODY) > { > n=s->s2->rlength+2+s->s2->three_byte_header; > if (n > (int)s->packet_length) > { > n-=s->packet_length; > i=read_n(s,(unsigned int)n,(unsigned > int)n,1); > if (i <= 0) return(i); /* ERROR */ > } > > ... > > } > > In our case this returns in the line marked with /* > ERROR */ (should this > be /* error or non-blocking */ like at the other > call to read_n?). The > internal read state remains SSL_ST_READ_BODY. If > SSL_read is called the > next time it immediatly falls into this if statement > evaluating > > n=s->s2->rlength+2+s->s2->three_byte_header; > > But if we have called SSL_write before, it may have > changed the value of > s->s2->three_byte_header. > I did not test wether SSL_write really _changed_ > s->s2->three_byte_header > (it certainly will touch it). > But: Our problem disappears if we do not call > SSL_write in this situation > but wait until some more data is available and we > can call > BIO_write/SSL_read again hoping that this will > change the read state to > SSL_ST_READ_HEADER :-). This leads me to the > assumption that sometimes you > should not call SSL_write (unlikely?) or that we use > the ssl library in the > wrong way (likely, but where is the mistake?). > > > > > >If you are non-blocking the only special case is to > start ignoring the > >select/poll/read/write writability event mechanism > to drive your writes > >at the point you get WANT_READ from SSL_write(). > But keep watching and > >processing readability events like normal, but > while ignoring > >writability events after each call to SSL_read() > (successful or not) > >attempt a SSL_write(), if that no longer returns > WANT_READ then you can > >stop ignoring and start using your writability > event indication to drive > >SSL_write() again. > > > > I think we handle WANT_READ/WANT_WRITE correctly (at > least the cases which > happens in our test environment) because: > -ssl connection setup is always successful > -after ssl connection setup the only error we get is > WANT_READ after > SSL_read returns with -1, which the application > interprets as: no more or > not enough encrypted data in internal buffer, wait > until new data is received. > > > > > > > >> This works but it is only a hack, of course (and > may deadlock sometimes if > >> ssl->rstate == SSL_ST_READ_HEADER on both sides > of the connection at the > >> same time). What we are doing wrong? > > > >I've not taken in the problem completely here. If > this deadlock is > >correct, can you provide a packet/data dump of the > session. > > > > The deadlock did not happen up to now and it's an > "application level" > === message truncated === __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com ______________________________________________________________________ OpenSSL Project http://www.openssl.org User Support Mailing List openssl-users@openssl.org Automated List Manager [EMAIL PROTECTED]