Hello,

Our OpenSSL-enabled server is built upon non-blocking IO with IO completion ports on Windows. Everything is very efficient and fast, but there is a nagging issue with double-buffering.

Essentially, when OpenSSL calls BIO_write our application buffers the data to be sent, and initiates an IOCP write request on this buffer and returns with success. If there is a pending IOCP request we call BIO_set_retry_write and return with failure.

Similarly, when OpenSSL calls BIO_read, we satisfy the request from a buffer that is fed by completed IOCP requests. If there's no data in the buffer we call BIO_set_retry_read and return with failure.

This could be changed to be much more efficient:

BIO_write could call BIO_set_retry_write immediately and return with failure, while also initiating an IOCP write request on the buffer it received in the call. When the IOCP request completes successfully, the retried BIO_write call could be satisfied.

BIO_read could initiate an IOCP_read, and, again, call BIO_set_retry_read and return with failure. When the IOCP request completes successfully the retried BIO_read call could be satisfied.

For this to work, however, it would have to be guaranteed that OpenSSL, when retrying a BIO_read, it does so with the same buffer, and for at least as much data as was originally requested. Of course, the buffer must remain valid between the two calls. Also, when retrying a BIO_write, the call must be for the same buffer and for at least as much data as was originally written - and the buffer must remain the same during the two calls.

Is this something we could count on? We could save quite a bit of CPU time and memory by not having to copy data into temporary buffers.

Thanks in advance,

-Marton Anka

Reply via email to