| push ups |
[Jul. 23rd, 2008|09:03 am] |
suomifrikki is attempting to do 100 push ups. I think it's a good challenge. I will try too and post my progress. Today I did 25. It was rather difficult. My arms are thin and weak like flex-straws. |
|
|
| Hints on non-blocking/evented OpenSSL usage |
[Jul. 23rd, 2008|05:35 pm] |
This might be of interest to you, nikolasco. Marc Lehmann says:Certain libraries (namely OpenSSL) wrap up their functionality in such a way that you *must* let the library do the I/O due to the nature of its API That is news to me, and certainly wrong:
Openssl doesn't actually enforce this, its just the simplest mode of operation with blocking sockets. if you want to do you own I/O, you are free to do (and in fact, if you are non-blocking, then doing that is much less of a hassle then trying to use openssl on non-blocking sockets directly. the retry semantics will drive you mad).
In fact, openssl completely decouples I/O from TLS handling.those cases I'd still need something like libev to give me readiness notifications. Not if you do the I/O on your own. AnyEvent::Handle for example does this, it uses EV for readyness notifications, but it could just as well use an asynchronous read or something else.
The code is very new and might still be buggy, but it outlines the principles: use a memory stream, which will avoid all issues with blocking in openssl (this might be interesting to somebody else besides us, who knows :)
set up code
You tell your ssl context the server/client mode, create two BIO_s_mem streams and connect to it, then you poll those regularly (this could be optimised a bit in C, but perl lacks the API definitions and I wasn't keen on adding them):
poll code, $self->{_tls_wbuf} is unencrypted data from the app, _wbuf the socket write buffer, _rbuf the unencrypted app read buffer.
Note that, for sockets, using async-i/o is the wrong approach (mostly because it is not efficient and ties the write buffer with interesting semantics), it doesn't scale, so readyness notifications are the way to go. Surprisingly, they are supported by windows more efficiently than by using select, but you _have_ to use multiple threads, which slows you down again, so it's not a clear trade-off to go from select to something else.In all other cases, I think it's best for the underlying library to perform the I/O for me. I strongly disagree - for everything that supports non-blocking operations async I/O is almost always wrong, because you don't know wether data is there.
letting the library do I/O ties a lot of resources that an event-based program would avoid.
It might be easiest/laziest etc., which *could* be "best" in certain situations, though :)
|
|
|