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]

Reply via email to