<div dir="ltr">Dear Matt, <div><br></div><div>I have some questions.<br><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Oct 8, 2015 at 12:32 AM, Matt Caswell <span dir="ltr"><<a href="mailto:matt@openssl.org" target="_blank">matt@openssl.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span class=""><br>
<br>
On 07/10/15 21:44, Dmitry Belyavsky wrote:<br>
> Dear Matt,<br>
><br>
> On Wed, Oct 7, 2015 at 4:43 PM, Matt Caswell <<a href="mailto:matt@openssl.org">matt@openssl.org</a><br>
</span><span class="">> <mailto:<a href="mailto:matt@openssl.org">matt@openssl.org</a>>> wrote:<br>
><br>
><br>
><br>
>     On 07/10/15 14:29, Viktor Dukhovni wrote:<br>
>     ><br>
>     > Should applications generally enable async mode because that might<br>
>     > be beneficial down the road?  Or is this just for exotic hardware<br>
>     > not likely to be seen in most environments?<br>
><br>
>     It will only be helpful if you have an engine capable of supporting<br>
>     async. I can't really answer the question because I don't know how<br>
>     common this will be. My hope is that this will become relatively common.<br>
>     I have been toying with the idea of creating a multi-threaded async<br>
>     engine where the engine manages a pool of threads to offload async work<br>
>     to which would then offer true async support even if you don't have<br>
>     specialist hardware.<br>
><br>
><br>
> If we have an engine executing long crypto operations, how can we adopt<br>
> the engine and software using this engine to process them asynchronously?<br>
<br>
</span>The engine needs to have a way of offloading the work to "something<br>
else" so that it can come back and pick up the results later. Typically<br>
for an engine this would mean some external hardware, but as I suggested<br>
above it could be done using threads.<br>
<br>
>From an engine perspective the work would be:<br>
- Receive a request to do some crypto work in the normal way via the<br>
engine API.<br>
- Offload the work to "something else"<br></blockquote><div><br></div><div>So what is a mechanism of such an offload? Can I, for example, get the (global) ASYNC_pool and add a job (function/pointer to context) to it?</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
- Call the new API function ASYNC_pause_job(). This will return control<br>
back to the calling application.<br></blockquote><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
- At sometime later, preferably when the application knows the work has<br>
completed (* see below), the application will resume the async job. From<br>
an engine perspective this just appears as the ASYNC_pause_job()<br>
function call returning - so it just continues where it left off<br>
- The engine should verify that the work offloaded to "something else"<br>
has completed.<br>
- If not it just calls ASYNC_pause_job() again as before.<br>
- If it has completed then it collects the results and returns them back<br>
in the normal way for an engine<br>
<br>
>From an application perspective it depends whether it is using libcrypto<br>
directly, or whether it is using libssl.<br>
<a href="/"></a><span id="goog_72531392"></span><span id="goog_72531393"></span><br>
If libssl then:<br>
- the application essentially operates as normal<br>
- additionally it must call either SSL_CTX_set_mode() or SSL_set_mode to<br>
set the SSL_ASYNC_MODE<br>
- In any call to SSL_read/SSL_write/SSL_accept/SSL_connect etc, it must<br>
be prepared to handle an SSL_ERROR_WANT_ASYNC response. This works in<br>
essentially the same way as SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE,<br>
i.e sometime later (* see below) it recalls<br>
SSL_read/SSL_write/SSL_accept/SSL_connect and the async job is resumed.<br></blockquote><div><br></div><div>How will the SSL struct obtain a job id from the engine implementing, for example, "long" RSA_METHOD?</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<br>
If using libcrypto then:<br>
- the application must determine which crypto operations it wants to<br>
perform asynchronously. Those operations should be wrapped in an<br>
application defined function.<br>
- the application initiates the async job by calling ASYNC_start_job and<br>
passing in a pointer to the function to be started as a job.<br>
- from an engine perspective it will work in exactly the same way as for<br>
libssl initiated crypto work.<br>
- ASYNC_start_job may return with an ASYNC_PAUSE response. The<br>
application can go off and do other work, and then resume the job at a<br>
later time by recalling ASYNC_start_job.<br></blockquote><div><br></div><div>So do I understand correctly that if I want to perform SSL operations asynchronously, </div><div>I'm able to wrap the SSL functions into the application defined functions and then behave as described</div><div>herein before? </div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<br>
<br>
So the next question is how does the application know when it is ok to<br>
resume a job? There are two basic models:<br>
<br>
- Event based...essentially the engine signals to the application that<br>
the results are ready for collection<br>
- Polling...in this model the application will have to periodically<br>
restart the job to see if it is ready to be continued or not<br>
<br>
There are API calls available for the event based model. See<br>
ASYNC_wake(), ASYNC_clear_wake(), ASYNC_get_wait_fd(), and<br>
SSL_get_async_wait_fd() in the documentation links I sent out previously.<br>
<br>
There is some example code in the ASYNC_start_job() documentation. You<br>
can also look at the source code for the dummy async engine.<br></blockquote><div><br></div><div>Thank you. I've looked through them but still did not understand completely.</div></div><br clear="all"><div><br></div>-- <br><div class="gmail_signature">SY, Dmitry Belyavsky</div>
</div></div></div>