---- Original message ---- >Date: Tue, 22 Aug 2006 12:22:37 -0700 >From: "David Schwartz" <[EMAIL PROTECTED]> >Subject: RE: Wrapping SSL_read/SSL_write so they behave like read/write.] >To: <openssl-users@openssl.org>
> You should 'select' for writability if and only if you get a WANT_WRITE >indication, whether it comes from SSL_read or SSL_write. This is the *only* >thing that means that you would block while trying to send encrypted data to >the socket. (Whether or not you are trying to currently send any unencrypted >data has nothing to do with it.) > > 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? >>Are you suggesting that the write hit from select is an >>indication that the descriptor is writable and hence the data >>that SSL required to write before it could serve our read >>request must have been written. And so we would expect a >>successful SSL_read after this write hit from select? > > If you got a WANT_WRITE, that means the operation could not proceed until >encrypted data could be written. Once the socket is writable, the operation >can proceed. So you should retry it. No harm in retrying all current >operations (always SSL_read, but SSL_write if there's unencrypted data to >send). > >Moreover, should we not wait again for a read hit from select >before we SSL_read()? > > That would be a disaster. The corresponding encrypted data might have >already been read. You should *never* assume no inbound data will be >available until the socket is readable unless SSL_read just returned >WANT_READ and you have no called SSL_write since then. > > The SSL engine may have already read the encrypted data, during a previous >call to SSL_read or a previous call to SSL_write! So waiting for more data >to be received can deadlock you. > > Do not assume that no unencrypted data can be read until encrypted data can >be read unless you know this for a fact. The only way you can know this for >a fact is if two things are the case: > > 1) Your last SSL_read returned WANT_READ, *and* > > 2) You have not called SSL_write since then. > > Otherwise, you should *not* wait for readability before calling SSL_read. >The encrypted data may have already been read. > > Note that if an SSL_write returns WANT_READ, you should 'select' for >readability and then retry the SSL_write. No harm in doing an SSL_read >before or after that. In fact, there are good reasons for doing one both >before and after, assuming the first SSL_read doesn't return 'WANT_READ'. > 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). 2) You check for socket writability if you get WANT_WRITE for the last operation, and on hit you retry that operation. Is this understanding correct? 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? ~ Urjit DISCLAIMER ========== This e-mail may contain privileged and confidential information which is the property of Persistent Systems Pvt. Ltd. It is intended only for the use of the individual or entity to which it is addressed. If you are not the intended recipient, you are not authorized to read, retain, copy, print, distribute or use this message. If you have received this communication in error, please notify the sender and delete all copies of this message. Persistent Systems Pvt. Ltd. does not accept any liability for virus infected mails. ______________________________________________________________________ OpenSSL Project http://www.openssl.org User Support Mailing List openssl-users@openssl.org Automated List Manager [EMAIL PROTECTED]