Thor Lancelot Simon wrote: > I think I've discovered another problem with the current non-blocking API. > > I have an application which reads data into fixed-size buffers which it > maintains per session. It uses non-blocking IO and select() when a read > returns SSL_ERROR_WANT_{READ,WRITE}. > > To conserve memory I reduced the buffer size from 16384 to 8192 and saw > sessions suddenly hang. A coworker diagnosed this as follows: > > 1) The peer sends a SSL record larger than the buffer size. > > 2) We receive the SSL record. The socket selects as ready to read. > > 3) We call SSL_read with our 8k buffer. The received data does not fit, > so OpenSSL buffers it internally and returns 8K with SSL_ERROR_WANT_READ. > The record size of the SSL record is predetermined by the sender with 16k being the maximum size specified by the protocol.
In order to return the (decrytped and authenticated) data to the application, the full record must have been received as the MAC (Message Authentication Code) is at the end of the record and checking it requires to calculate the hash over the complete record anyway. Hence, SSL_read() will only return and provide data once the full record has been recevied from the underlying socket. As the SSL communication just like TCP is stream oriented there is no way for an application to know what is the size of a record, whether data are split over several records or sent in one or whether more information inside the stream was combined to just one record. Hence you have to read from the stream with SSL_read() until there is no more data to be retrieved. As long as there are bytes available SSL_read() will return the number of bytes written to the buffer. A following call to SSL_get_errror(ssl, <number of bytes>) will return SSL_ERROR_NONE. The logic here is quite simple: the first test in ssl/ssl_lib.c:SSL_get_error() is: if (i > 0) return(SSL_ERROR_NONE); Hence the scenario you describe here (returned 8k and SSL_ERROR_WANT_READ at the same time) is technically impossible as long as you did call SSL_get_error() with the correct return value of SSL_read(). To find out whether there actually is decrypted data available to be read you may use SSL_pending() before calling SSL_read(). I have written quite some amount of applications using non-blocking I/O and while especially the shutdown behavior is questionable at least, the actual state machine never made any trouble to me. Note: I did not invent the API, I just wrote the manual pages :-) Best regards, Lutz ______________________________________________________________________ OpenSSL Project http://www.openssl.org Development Mailing List openssl-dev@openssl.org Automated List Manager [EMAIL PROTECTED]