On Wed, Mar 05, 2008 at 10:01:26AM -0500, Geoff Thorpe wrote: > Hi Thor, > > On Sun, 2008-03-02 at 23:21 -0500, Thor Lancelot Simon wrote: > > > FWIW, this is not really the right way of implementing async support in > > > openssl. "Completion" events are not always going to be related to file > > > descriptors in any clear way > > > > Certainly if the file in question is one for a Unix device driver, and > > that device driver is in use for asynchronous hardware-accellerated crypto > > operations, there will, in fact, be a perfectly clear relationship. > > Well, maybe in the cases you're interested in, but this is not an > assumption I'm prepared to make w.r.t. abstractions. Even for crypto > drivers that are fd-based, it would be lazy/inefficient for there to be > a fd *per-operation* - ie. whilst a process's communication with a > driver might very well be fd-based, the presence of data on that fd > wouldn't necessarily indicate which asynchronous operation had > completed. And even on unix, completions could occur via signals, IPC > (of various forms), whatever. If openssl is to provide support for > asynchronous completion, there needs to be a general interface for it.
Well, I did not suggest that one would ever use a file descriptor per operation. But, let me try again. Note first that that OpenSSL does not abstract I/O completion waiting (the API provides SSL_read(), SSL_write(), SSL_connect(), SSL_shutdown(), but *not* SSL_poll() or SSL_select). When I proposed correcting this, last year, I got a pretty strongly negative reception. Note next that there are already a nontrivial number of nontrivial applications using the existing non-blocking select()/poll() driven API to OpenSSL, despite its warts. This API *already* requires, quite explicitly, extracting the file descriptor from each SSL session and adding those descriptors to a select() or poll() set. Applications are already written to this API and it does not abstract completion waiting as you suggest it should (I happen to agree with you, but neither you nor I can adjust all of everyone else's code out there in the world!). This API also *already* requires any operations that would block to be reissued at the SSL layer by retrying exactly the same operation again after the file descriptor for that session comes up ready with select or poll. I do not love this API, but it is what all the existing, non-threaded non-blocking OpenSSL API consumers are written to, and I think it would be a considerable mistake to change it now. So, given my "note first" and "note second" I believe I have established that, to do non-blocking I/O in a single-threaded application with OpenSSL, one must already: 1) Dip beneath the SSL abstraction layer to get the file descriptor for each session. 2) Use select() or poll() to wait on all those file descriptors. 3) Retry operations, exactly as issued prior to completion waiting, when their sessions' descriptors come up ready in select or poll (whether to select for read-ready or write-ready is known by the WANT_READ or WANT_WRITE SSL errors returned when the operation would block). I propose, then, to extend the existing interface to accomodate non-blocking operation of ENGINEs themselves, by: 4) Adding a method to probe whether an ENGINE supports non-blocking operation. 5) Adding a method, for such ENGINEs, to get the file descriptor to add to the select or poll set (or, on other platforms, what must nonetheless be a file-descriptor-based completion waiting mechanism functionally equivalent to select or poll, because this is what the current API requires already) the application must already be using for I/O, to find out if any operations have completed on the underlying cryptographic device. 6) Adding a second method, for such ENGINEs, to find out whether the request for a given SSL session completed. 4) Adding one more return value when an SSL-level operation would block, WANT_CRYPTO, which means that the application must add the ENGINE-specified fd from #5 above to its select or poll set. Given the already existing API for non-blocking operation in OpenSSL, I must confess I am pretty much baffled how else it _could_ work. I do not think it is possible to abstract the completion waiting mechanism so that it doesn't involve file descriptors because you cannot use some other such mechanism in tandem with select or poll (which the API already needs) since those explicitly sleep the application until a descriptor comes ready. However, it's basically trivial for an ENGINE which itself is notified by some other mechanism to arrange to wake the application via a file descriptor by simply looping a pipe or socket back to itself and writing a byte or message there, FWIW. Unfortunately, I don't have code I can offer as patches against OpenSSL- current for this; what I have are patches against a proprietary vendor- modified OpenSSL which doesn't use the ENGINE interface but uses something functionally equivalent to it. I am proposing to reimplement as free code but I'm somewhat hesitant to spend what I estimate as at least two weeks of effort if there's a lack of consensus that this is the right way to go... Thor ______________________________________________________________________ OpenSSL Project http://www.openssl.org Development Mailing List openssl-dev@openssl.org Automated List Manager [EMAIL PROTECTED]