| =pod |
| |
| =head1 NAME |
| |
| ASYNC_WAIT_CTX_new, ASYNC_WAIT_CTX_free, ASYNC_WAIT_CTX_set_wait_fd, |
| ASYNC_WAIT_CTX_get_fd, ASYNC_WAIT_CTX_get_all_fds, |
| ASYNC_WAIT_CTX_get_changed_fds, ASYNC_WAIT_CTX_clear_fd, |
| ASYNC_WAIT_CTX_set_callback, ASYNC_WAIT_CTX_get_callback, |
| ASYNC_WAIT_CTX_set_status, ASYNC_WAIT_CTX_get_status, ASYNC_callback_fn, |
| ASYNC_STATUS_UNSUPPORTED, ASYNC_STATUS_ERR, ASYNC_STATUS_OK, |
| ASYNC_STATUS_EAGAIN |
| - functions to manage waiting for asynchronous jobs to complete |
| |
| =head1 SYNOPSIS |
| |
| #include <openssl/async.h> |
| |
| #define ASYNC_STATUS_UNSUPPORTED 0 |
| #define ASYNC_STATUS_ERR 1 |
| #define ASYNC_STATUS_OK 2 |
| #define ASYNC_STATUS_EAGAIN 3 |
| typedef int (*ASYNC_callback_fn)(void *arg); |
| ASYNC_WAIT_CTX *ASYNC_WAIT_CTX_new(void); |
| void ASYNC_WAIT_CTX_free(ASYNC_WAIT_CTX *ctx); |
| int ASYNC_WAIT_CTX_set_wait_fd(ASYNC_WAIT_CTX *ctx, const void *key, |
| OSSL_ASYNC_FD fd, |
| void *custom_data, |
| void (*cleanup)(ASYNC_WAIT_CTX *, const void *, |
| OSSL_ASYNC_FD, void *)); |
| int ASYNC_WAIT_CTX_get_fd(ASYNC_WAIT_CTX *ctx, const void *key, |
| OSSL_ASYNC_FD *fd, void **custom_data); |
| int ASYNC_WAIT_CTX_get_all_fds(ASYNC_WAIT_CTX *ctx, OSSL_ASYNC_FD *fd, |
| size_t *numfds); |
| int ASYNC_WAIT_CTX_get_changed_fds(ASYNC_WAIT_CTX *ctx, OSSL_ASYNC_FD *addfd, |
| size_t *numaddfds, OSSL_ASYNC_FD *delfd, |
| size_t *numdelfds); |
| int ASYNC_WAIT_CTX_clear_fd(ASYNC_WAIT_CTX *ctx, const void *key); |
| int ASYNC_WAIT_CTX_set_callback(ASYNC_WAIT_CTX *ctx, |
| ASYNC_callback_fn callback, |
| void *callback_arg); |
| int ASYNC_WAIT_CTX_get_callback(ASYNC_WAIT_CTX *ctx, |
| ASYNC_callback_fn *callback, |
| void **callback_arg); |
| int ASYNC_WAIT_CTX_set_status(ASYNC_WAIT_CTX *ctx, int status); |
| int ASYNC_WAIT_CTX_get_status(ASYNC_WAIT_CTX *ctx); |
| |
| |
| =head1 DESCRIPTION |
| |
| For an overview of how asynchronous operations are implemented in OpenSSL see |
| L<ASYNC_start_job(3)>. An B<ASYNC_WAIT_CTX> object represents an asynchronous |
| "session", i.e. a related set of crypto operations. For example in SSL terms |
| this would have a one-to-one correspondence with an SSL connection. |
| |
| Application code must create an B<ASYNC_WAIT_CTX> using the ASYNC_WAIT_CTX_new() |
| function prior to calling ASYNC_start_job() (see L<ASYNC_start_job(3)>). When |
| the job is started it is associated with the B<ASYNC_WAIT_CTX> for the duration |
| of that job. An B<ASYNC_WAIT_CTX> should only be used for one B<ASYNC_JOB> at |
| any one time, but can be reused after an B<ASYNC_JOB> has finished for a |
| subsequent B<ASYNC_JOB>. When the session is complete (e.g. the SSL connection |
| is closed), application code cleans up with ASYNC_WAIT_CTX_free(). |
| |
| B<ASYNC_WAIT_CTX>s can have "wait" file descriptors associated with them. |
| Calling ASYNC_WAIT_CTX_get_all_fds() and passing in a pointer to an |
| B<ASYNC_WAIT_CTX> in the I<ctx> parameter will return the wait file descriptors |
| associated with that job in I<*fd>. The number of file descriptors returned will |
| be stored in I<*numfds>. It is the caller's responsibility to ensure that |
| sufficient memory has been allocated in I<*fd> to receive all the file |
| descriptors. Calling ASYNC_WAIT_CTX_get_all_fds() with a NULL I<fd> value will |
| return no file descriptors but will still populate I<*numfds>. Therefore, |
| application code is typically expected to call this function twice: once to get |
| the number of fds, and then again when sufficient memory has been allocated. If |
| only one asynchronous engine is being used then normally this call will only |
| ever return one fd. If multiple asynchronous engines are being used then more |
| could be returned. |
| |
| The function ASYNC_WAIT_CTX_get_changed_fds() can be used to detect if any fds |
| have changed since the last call time ASYNC_start_job() returned B<ASYNC_PAUSE> |
| (or since the B<ASYNC_WAIT_CTX> was created if no B<ASYNC_PAUSE> result has |
| been received). The I<numaddfds> and I<numdelfds> parameters will be populated |
| with the number of fds added or deleted respectively. I<*addfd> and I<*delfd> |
| will be populated with the list of added and deleted fds respectively. Similarly |
| to ASYNC_WAIT_CTX_get_all_fds() either of these can be NULL, but if they are not |
| NULL then the caller is responsible for ensuring sufficient memory is allocated. |
| |
| Implementors of async aware code (e.g. engines) are encouraged to return a |
| stable fd for the lifetime of the B<ASYNC_WAIT_CTX> in order to reduce the |
| "churn" of regularly changing fds - although no guarantees of this are provided |
| to applications. |
| |
| Applications can wait for the file descriptor to be ready for "read" using a |
| system function call such as select or poll (being ready for "read" indicates |
| that the job should be resumed). If no file descriptor is made available then an |
| application will have to periodically "poll" the job by attempting to restart it |
| to see if it is ready to continue. |
| |
| Async aware code (e.g. engines) can get the current B<ASYNC_WAIT_CTX> from the |
| job via L<ASYNC_get_wait_ctx(3)> and provide a file descriptor to use for |
| waiting on by calling ASYNC_WAIT_CTX_set_wait_fd(). Typically this would be done |
| by an engine immediately prior to calling ASYNC_pause_job() and not by end user |
| code. An existing association with a file descriptor can be obtained using |
| ASYNC_WAIT_CTX_get_fd() and cleared using ASYNC_WAIT_CTX_clear_fd(). Both of |
| these functions requires a I<key> value which is unique to the async aware |
| code. This could be any unique value but a good candidate might be the |
| B<ENGINE *> for the engine. The I<custom_data> parameter can be any value, and |
| will be returned in a subsequent call to ASYNC_WAIT_CTX_get_fd(). The |
| ASYNC_WAIT_CTX_set_wait_fd() function also expects a pointer to a "cleanup" |
| routine. This can be NULL but if provided will automatically get called when |
| the B<ASYNC_WAIT_CTX> is freed, and gives the engine the opportunity to close |
| the fd or any other resources. Note: The "cleanup" routine does not get called |
| if the fd is cleared directly via a call to ASYNC_WAIT_CTX_clear_fd(). |
| |
| An example of typical usage might be an async capable engine. User code would |
| initiate cryptographic operations. The engine would initiate those operations |
| asynchronously and then call ASYNC_WAIT_CTX_set_wait_fd() followed by |
| ASYNC_pause_job() to return control to the user code. The user code can then |
| perform other tasks or wait for the job to be ready by calling "select" or other |
| similar function on the wait file descriptor. The engine can signal to the user |
| code that the job should be resumed by making the wait file descriptor |
| "readable". Once resumed the engine should clear the wake signal on the wait |
| file descriptor. |
| |
| As well as a file descriptor, user code may also be notified via a callback. The |
| callback and data pointers are stored within the B<ASYNC_WAIT_CTX> along with an |
| additional status field that can be used for the notification of retries from an |
| engine. This additional method can be used when the user thinks that a file |
| descriptor is too costly in terms of CPU cycles or in some context where a file |
| descriptor is not appropriate. |
| |
| ASYNC_WAIT_CTX_set_callback() sets the callback and the callback argument. The |
| callback will be called to notify user code when an engine completes a |
| cryptography operation. It is a requirement that the callback function is small |
| and nonblocking as it will be run in the context of a polling mechanism or an |
| interrupt. |
| |
| ASYNC_WAIT_CTX_get_callback() returns the callback set in the B<ASYNC_WAIT_CTX> |
| structure. |
| |
| ASYNC_WAIT_CTX_set_status() allows an engine to set the current engine status. |
| The possible status values are the following: |
| |
| =over 4 |
| |
| =item B<ASYNC_STATUS_UNSUPPORTED> |
| |
| The engine does not support the callback mechanism. This is the default value. |
| The engine must call ASYNC_WAIT_CTX_set_status() to set the status to some value |
| other than B<ASYNC_STATUS_UNSUPPORTED> if it intends to enable the callback |
| mechanism. |
| |
| =item B<ASYNC_STATUS_ERR> |
| |
| The engine has a fatal problem with this request. The user code should clean up |
| this session. |
| |
| =item B<ASYNC_STATUS_OK> |
| |
| The request has been successfully submitted. |
| |
| =item B<ASYNC_STATUS_EAGAIN> |
| |
| The engine has some problem which will be recovered soon, such as a buffer is |
| full, so user code should resume the job. |
| |
| =back |
| |
| ASYNC_WAIT_CTX_get_status() allows user code to obtain the current status value. |
| If the status is any value other than B<ASYNC_STATUS_OK> then the user code |
| should not expect to receive a callback from the engine even if one has been |
| set. |
| |
| An example of the usage of the callback method might be the following. User |
| code would initiate cryptographic operations, and the engine code would dispatch |
| this operation to hardware, and if the dispatch is successful, then the engine |
| code would call ASYNC_pause_job() to return control to the user code. After |
| that, user code can perform other tasks. When the hardware completes the |
| operation, normally it is detected by a polling function or an interrupt, as the |
| user code set a callback by calling ASYNC_WAIT_CTX_set_callback() previously, |
| then the registered callback will be called. |
| |
| =head1 RETURN VALUES |
| |
| ASYNC_WAIT_CTX_new() returns a pointer to the newly allocated B<ASYNC_WAIT_CTX> |
| or NULL on error. |
| |
| ASYNC_WAIT_CTX_set_wait_fd, ASYNC_WAIT_CTX_get_fd, ASYNC_WAIT_CTX_get_all_fds, |
| ASYNC_WAIT_CTX_get_changed_fds, ASYNC_WAIT_CTX_clear_fd, |
| ASYNC_WAIT_CTX_set_callback, ASYNC_WAIT_CTX_get_callback and |
| ASYNC_WAIT_CTX_set_status all return 1 on success or 0 on error. |
| ASYNC_WAIT_CTX_get_status() returns the engine status. |
| |
| |
| =head1 NOTES |
| |
| On Windows platforms the F<< <openssl/async.h> >> header is dependent on some |
| of the types customarily made available by including F<< <windows.h> >>. The |
| application developer is likely to require control over when the latter |
| is included, commonly as one of the first included headers. Therefore, |
| it is defined as an application developer's responsibility to include |
| F<< <windows.h> >> prior to F<< <openssl/async.h> >>. |
| |
| =head1 SEE ALSO |
| |
| L<crypto(7)>, L<ASYNC_start_job(3)> |
| |
| =head1 HISTORY |
| |
| ASYNC_WAIT_CTX_new(), ASYNC_WAIT_CTX_free(), ASYNC_WAIT_CTX_set_wait_fd(), |
| ASYNC_WAIT_CTX_get_fd(), ASYNC_WAIT_CTX_get_all_fds(), |
| ASYNC_WAIT_CTX_get_changed_fds() and ASYNC_WAIT_CTX_clear_fd() |
| were added in OpenSSL 1.1.0. |
| |
| ASYNC_WAIT_CTX_set_callback(), ASYNC_WAIT_CTX_get_callback(), |
| ASYNC_WAIT_CTX_set_status(), and ASYNC_WAIT_CTX_get_status() |
| were added in OpenSSL 3.0. |
| |
| =head1 COPYRIGHT |
| |
| Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved. |
| |
| Licensed under the Apache License 2.0 (the "License"). You may not use |
| this file except in compliance with the License. You can obtain a copy |
| in the file LICENSE in the source distribution or at |
| L<https://www.openssl.org/source/license.html>. |
| |
| =cut |