On Wed, 2008-03-05 at 13:54 -0500, Thor Lancelot Simon wrote: > On Wed, Mar 05, 2008 at 12:10:04PM -0500, Geoff Thorpe wrote: > > > > I was not involved in the discussion so am not familiar with the > > arguments. However I agree that SSL_[poll|select]() would be unwise > > because it presumes to make the SSL/TLS stack transport-aware, whereas > > the BIO scheme is an honest (if sometimes inelegant) attempt to leave > > the stack transport-agnostic. SSL/TLS can be fed data on all sides > > But you can't stay transport-agnostic and actually use the stack in > non-blocking mode now.
You can't, but libssl sure can. That's why SSL_poll() is not a good idea IMHO. I've written SSL utils/tests that read and write memory on all 4 I/O points of the SSL state machine, and I'd argue that I'm using the stack in a *very* non-blocking mode in that case, what on earth can it block on? It's up to me to get new data to the two read inputs, and get data from the two send outputs, but *I'm* transport-aware, not the stack. SSL/TLS is a duplex data encapsulation protocol, it has *nothing* to do with TCP, unix domain sockets, stdio, or networking. Per se. It's assumptions involve pairs of reliable, unidirectional data-streams, that's all. Moreover, awareness of when data is available (read) and when output buffering is available (send, congestion, etc) depends on your SSL/TLS *use-case*. Ideally, there should be no network code anywhere in ./ssl/, and in fact there should only be network code in transport-specific files in ./crypto/bio/. So having an SSL_[poll| select]() interface in ssl.h is extremely counter-intuitive to me. > You *must* extract the underlying file descriptor > and sleep on it with select/poll, which effectively forecloses any option > of using some other asynchronous event mechanism at the same time except > heavyweight signals, under Unix at least (and using signals that way will > butcher performance; I have benchmarked this). Sure, your circumstances may be like that. But I won't accept that openssl should wed itself to this model inextricably. If you already have "proprietary code" to this effect, then you don't need openssl.org to reproduce your solution for you. I don't mean to be argumentative, just saying that it's unacceptable to take a short-sighted approach to openssl.org's tree just to mimic what someone has already done when scratching their specific itch. Async crypto is a hard problem for openssl because of its historical baggage. We will crack it, but not in a way that solves the easiest use-case and makes all other use-cases harder than ever. If you're in an embedded/custom OS with a flat-memory model and no user-mode, and some opaque code provides your I/O and crypto via callbacks, please tell me how SSL_poll() is going to help? > > Sure, but that's because you are *not* suspended miles down a code path > > that you need to find your way back to. It means the state-machine has > > advanced as far as it can go and to advance further, you will need the > > presence of either input on your read BIO or some drainage on your write > > BIO. Those events are on the exterior of the SSL/TLS state-machine and > > represent a stable state, the code-paths exit cleanly in that state and > > when progress is possible, we will go down new code paths to do new > > work. This is not the same as trying to pick up where you left off way > > down a code-path that has not been designed with suspend-and-retry > > semantics in mind. Eg. if you were calling SSL_read() when you got a > > WANT_WRITE, but you then called SSL_write() - it should *not* crash. > > Should not, or does not? I think you're a bit optimistic about the > current implementation, for what it's worth. Failure to retry the exact > same operation, now, causes chaos, including data corruption. Ahh, well I didn't know about that. It shouldn't be the case (obviously). Do do you have any idea why? Fixes are welcome ;-) > > What you're describing, about being able to replay your way down a prior > > code-path, would be very hard to make robust in an equivalent way. > > For what it's worth, I and my coworkers have done this, to an originally > openssl-derived code base, which still retains BIO, etc., and it was not > too hard to make it work at least as well as the current read/write > suspension does. I've also done it, and maybe I have an impatient nature, but I got royally hacked off and honestly wouldn't have trusted the result much ("audit *that* you [EMAIL PROTECTED]"). Bear in mind that if the stack is going to support async crypto, it ought to be ready for *any* crypto operation to go async. Did your changes only enable asynchronicity on specific calls/paths? I say "any" because the decision as to which operations should be async (and when) may be related to factors other than the particular code-path that got you there. Eg. resource availability, data-size, load, algorithm, key/iv-locality, time-slicing, [...]. > > No, this is one form it must be able to take, but this is not *the* > > general method for OpenSSL to support. > > But it is the only way that works now. And that is the problem: the > current API, I think, essentially precludes the simultaneous use of > some other notification mechanism for another type of asynchronous > events, because _while_ you are sleeping for some SSL sessions in > select/poll for I/O ready on their file descriptors, you can not be > doing anything else. s/_while_/_if_/ And even then, if you've got the right mojo (and the right reasons), you can get a select/poll syscall to wake up prematurely without necessarily needing a crypto fd to become readable. And if results are conveyed with flags, shared-mem, [etc] then the whole file-descriptor business is a bad fit. As you said yourself in an earlier post, you can also use your own dummy fd to kick out a select/poll call if needed. File-descriptors are fine-print, and I don't want to get bogged down in them. > It all gets easier with multiple threads, of > course -- but it is precisely single-threaded, "traditional Unix" > event-driven applications that are the consumers of the existing > non-blocking API. I think you're right; we do largely agree on, > given the opportunity to start over from scratch, a new API for this > ought to look. But I am just highly skeptical that it's possible to do > anything cleaner than the (admittedly ugly, but ugly in the same way > the current API is ugly) scheme I've described, and actually keep > existing single-threaded code written to the non-blocking API working > with non-blocking I/O. As I've already said, I think the right approach sits around the SSL code, not within it. I think stack-switching is the one way to be sure that any operation, at any time, can be given the option, if you desire, to choose, if the crypto logic deems appropriate, to suspend the current processing in way that can be directly resumed at the appropriate later moment. It also makes it a libcrypto (BIO, ENGINE, [...]) mechanism rather than a libssl one. It's not just pure crypto that could use this, extensive X509 chain-verification may want (or need) to go async, if we're going to solve this async problem, then let's at least solve it across the board. Eg. async CRL-lookups, suspend processing on PRNG entropy starvation, [...]. There are also other "stacks" of potential interest, such as ssh, smime, h/w-accelerated compute-clusters, [whatever]. > You have to be able to wait for I/O completion > on some sessions and crypto completion on others (or, ideally, both, > for each direction of one session!) at the same time -- and the > basically mandatory use of select/poll in the existing API precludes > using anything else to wait on the crypto. Again, I don't disagree with you in the specific/mundane case of SSL on TCP on unix on bulk-standard/we-don't-need-no-stinkin-threads applications. But the async problem should not be tackled at that level alone. > At least, so it seems to > me (though I am eager to see what you come up with). Hmm, so am I. Spare time, work, family, open source. One of them will have to go ... :-) Cheers, Geoff ______________________________________________________________________ OpenSSL Project http://www.openssl.org Development Mailing List openssl-dev@openssl.org Automated List Manager [EMAIL PROTECTED]