On 07/10/15 14:29, Viktor Dukhovni wrote:
> On Wed, Oct 07, 2015 at 10:46:26AM +0100, Matt Caswell wrote:
>
>> I have also added async support to s_server and s_client through the new
>> "-async" flag. The will set the SSL_MODE_ASYNC mode. In order to have an
>> effect you will obviously also need an async engine (such as dasync)
>> loaded through the "-engine" flag. Note that dasync will only be loaded
>> dynamically and thus OpenSSL must be built "shared" for this to work.
>>
>> Documentation including some example code is available on all of this here:
>> https://github.com/mattcaswell/openssl/blob/main-async/doc/crypto/ASYNC_start_job.pod
>> https://github.com/mattcaswell/openssl/blob/main-async/doc/ssl/SSL_get_error.pod
>> https://github.com/mattcaswell/openssl/blob/main-async/doc/ssl/SSL_get_async_wait_fd.pod
>> https://github.com/mattcaswell/openssl/blob/main-async/doc/ssl/SSL_CTX_set_mode.pod
>>
>> I'd be interested to hear your thoughts.
>
> Will existing applications doing non-blocking I/O with OpenSSL need
> to be modified to handle SSL_ERROR_WANT_ASYNC? Or does that happen
> only if they explicitly request "async mode"?
No, they should not need to be modified. You will only get
SSL_ERROR_WANT_ASYNC if you have enabled SSL_MODE_ASYNC.
>
> Should applications generally enable async mode because that might
> be beneficial down the road? Or is this just for exotic hardware
> not likely to be seen in most environments?
It will only be helpful if you have an engine capable of supporting
async. I can't really answer the question because I don't know how
common this will be. My hope is that this will become relatively common.
I have been toying with the idea of creating a multi-threaded async
engine where the engine manages a pool of threads to offload async work
to which would then offer true async support even if you don't have
specialist hardware.
> For example, should Postfix enable "async" support? It does timed
> non-blocking TLS I/O and currently handles SSL_ERROR_WANT_{READ,WRITE}.
If applications already handle SSL_ERROR_WANT_READ/WRITE then IMO it is
not much extra effort to additionally handle SSL_ERROR_WANT_ASYNC so I
would encourage making the changes. You may want to consider making it a
configurable option. There is a small overhead with creating ASYNC_JOBs
and context switching into them when they start and finish.
libssl has been made async aware through the introduction of a new mode
"SSL_MODE_ASYNC". The mode is set using a call to one of the existing
functions SSL_CTX_set_mode() or SSL_set_mode(). Having set that mode
calls to functions such as SSL_read/SSL_write etc, may now start
returning an SSL_ERROR_WANT_ASYNC response (if an async capable engine
is present). To resume you simply recall SSL_read/SSL_write in the same
way as you would if you got an SSL_ERROR_WANT_READ or
SSL_ERROR_WANT_WRITE. Similarly to above you must do this from the same
thread as the original call.
As a maintainer of libevent, and spending heaps of time in the ssl abstractions, anything to remove all the insane things you must do now for async io would be a reprieve of the horrors we've dealt with over the years.
I do worry that these patches may take too much of the work away to the point of no decent control mechanism. When I see poll() everywhere, it throws up red flags.
I will spend some time with the proposed patches here, and see if I can make libevent happy, and hopefully very less complex.
Fingers crossed. Cheers!
On Wed, Oct 7, 2015 at 6:43 AM Matt Caswell <ma...@openssl.org> wrote:
On 07/10/15 14:29, Viktor Dukhovni wrote:
> On Wed, Oct 07, 2015 at 10:46:26AM +0100, Matt Caswell wrote:
>
>> I have also added async support to s_server and s_client through the new
>> "-async" flag. The will set the SSL_MODE_ASYNC mode. In order to have an
>> effect you will obviously also need an async engine (such as dasync)
>> loaded through the "-engine" flag. Note that dasync will only be loaded
>> dynamically and thus OpenSSL must be built "shared" for this to work.
>>
>> Documentation including some example code is available on all of this here:
>> https://github.com/mattcaswell/openssl/blob/main-async/doc/crypto/ASYNC_start_job.pod
>> https://github.com/mattcaswell/openssl/blob/main-async/doc/ssl/SSL_get_error.pod
>> https://github.com/mattcaswell/openssl/blob/main-async/doc/ssl/SSL_get_async_wait_fd.pod
>> https://github.com/mattcaswell/openssl/blob/main-async/doc/ssl/SSL_CTX_set_mode.pod
>>
>> I'd be interested to hear your thoughts.
>
> Will existing applications doing non-blocking I/O with OpenSSL need
> to be modified to handle SSL_ERROR_WANT_ASYNC? Or does that happen
> only if they explicitly request "async mode"?
No, they should not need to be modified. You will only get
SSL_ERROR_WANT_ASYNC if you have enabled SSL_MODE_ASYNC.
>
> Should applications generally enable async mode because that might
> be beneficial down the road? Or is this just for exotic hardware
> not likely to be seen in most environments?
It will only be helpful if you have an engine capable of supporting
async. I can't really answer the question because I don't know how
common this will be. My hope is that this will become relatively common.
I have been toying with the idea of creating a multi-threaded async
engine where the engine manages a pool of threads to offload async work
to which would then offer true async support even if you don't have
specialist hardware.
> For example, should Postfix enable "async" support? It does timed
> non-blocking TLS I/O and currently handles SSL_ERROR_WANT_{READ,WRITE}.
If applications already handle SSL_ERROR_WANT_READ/WRITE then IMO it is
not much extra effort to additionally handle SSL_ERROR_WANT_ASYNC so I
would encourage making the changes. You may want to consider making it a
configurable option. There is a small overhead with creating ASYNC_JOBs
and context switching into them when they start and finish.
Matt
_______________________________________________
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
_______________________________________________
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
On 07/10/15 14:29, Viktor Dukhovni wrote:
>
> Should applications generally enable async mode because that might
> be beneficial down the road? Or is this just for exotic hardware
> not likely to be seen in most environments?
It will only be helpful if you have an engine capable of supporting
async. I can't really answer the question because I don't know how
common this will be. My hope is that this will become relatively common.
I have been toying with the idea of creating a multi-threaded async
engine where the engine manages a pool of threads to offload async work
to which would then offer true async support even if you don't have
specialist hardware.
- Call the new API function ASYNC_pause_job(). This will return control
back to the calling application.
- At sometime later, preferably when the application knows the work has
completed (* see below), the application will resume the async job. From
an engine perspective this just appears as the ASYNC_pause_job()
function call returning - so it just continues where it left off
- The engine should verify that the work offloaded to "something else"
has completed.
- If not it just calls ASYNC_pause_job() again as before.
- If it has completed then it collects the results and returns them back
in the normal way for an engine
From an application perspective it depends whether it is using libcrypto
directly, or whether it is using libssl.
If libssl then:
- the application essentially operates as normal
- additionally it must call either SSL_CTX_set_mode() or SSL_set_mode to
set the SSL_ASYNC_MODE
- In any call to SSL_read/SSL_write/SSL_accept/SSL_connect etc, it must
be prepared to handle an SSL_ERROR_WANT_ASYNC response. This works in
essentially the same way as SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE,
i.e sometime later (* see below) it recalls
SSL_read/SSL_write/SSL_accept/SSL_connect and the async job is resumed.
If using libcrypto then:
- the application must determine which crypto operations it wants to
perform asynchronously. Those operations should be wrapped in an
application defined function.
- the application initiates the async job by calling ASYNC_start_job and
passing in a pointer to the function to be started as a job.
- from an engine perspective it will work in exactly the same way as for
libssl initiated crypto work.
- ASYNC_start_job may return with an ASYNC_PAUSE response. The
application can go off and do other work, and then resume the job at a
later time by recalling ASYNC_start_job.
So the next question is how does the application know when it is ok to
resume a job? There are two basic models:
- Event based...essentially the engine signals to the application that
the results are ready for collection
- Polling...in this model the application will have to periodically
restart the job to see if it is ready to be continued or not
There are API calls available for the event based model. See
ASYNC_wake(), ASYNC_clear_wake(), ASYNC_get_wait_fd(), and
SSL_get_async_wait_fd() in the documentation links I sent out previously.
There is some example code in the ASYNC_start_job() documentation. You
can also look at the source code for the dummy async engine.
No. I think you are confusing two different things.
1) How does an *application* perform asynchronous work (via libssl or
libcrypto) using an asynchronous capable engine?
2) How does an asynchronous capable engine offload async work to its
hardware?
These patches solve the first problem only. It provides an API and
mechanism for control to pass between the application and engine and
back again (perhaps multiple times) during the invocation of a long
running crypto operation. It also provides some mechanisms to enable an
engine to signal the completion of work to the application.
The second problem is entirely engine dependant. It will be a different
solution for different hardware. These patches do not provide a solution
to that problem.