9f5a87fd66
Reviewed-by: Matt Caswell <matt@openssl.org> Reviewed-by: Paul Yang <yang.yang@baishancloud.com> Signed-off-by: Ping Yu <ping.yu@intel.com> Signed-off-by: Steven Linsell <stevenx.linsell@intel.com> (Merged from https://github.com/openssl/openssl/pull/7573)
209 lines
11 KiB
Text
209 lines
11 KiB
Text
=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 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 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 ASYNC_WAIT_CTX for the duration of
|
|
that job. An ASYNC_WAIT_CTX should only be used for one ASYNC_JOB at any one
|
|
time, but can be reused after an ASYNC_JOB has finished for a subsequent
|
|
ASYNC_JOB. When the session is complete (e.g. the SSL connection is closed),
|
|
application code cleans up with ASYNC_WAIT_CTX_free().
|
|
|
|
ASYNC_WAIT_CTXs can have "wait" file descriptors associated with them. Calling
|
|
ASYNC_WAIT_CTX_get_all_fds() and passing in a pointer to an ASYNC_WAIT_CTX in
|
|
the B<ctx> parameter will return the wait file descriptors associated with that
|
|
job in B<*fd>. The number of file descriptors returned will be stored in
|
|
B<*numfds>. It is the caller's responsibility to ensure that sufficient memory
|
|
has been allocated in B<*fd> to receive all the file descriptors. Calling
|
|
ASYNC_WAIT_CTX_get_all_fds() with a NULL B<fd> value will return no file
|
|
descriptors but will still populate B<*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 an ASYNC_PAUSE
|
|
result (or since the ASYNC_WAIT_CTX was created if no ASYNC_PAUSE result has
|
|
been received). The B<numaddfds> and B<numdelfds> parameters will be populated
|
|
with the number of fds added or deleted respectively. B<*addfd> and B<*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 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 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 B<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 B<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 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 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 non-blocking 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 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:
|
|
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 ASYNC_STATUS_UNSUPPORTED if it intends
|
|
to enable the callback mechanism.
|
|
ASYNC_STATUS_ERR: The engine has a fatal problem with this request. The user
|
|
code should clean up this session.
|
|
ASYNC_STATUS_OK: The request has been successfully submitted.
|
|
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.
|
|
|
|
ASYNC_WAIT_CTX_get_status() allows user code to obtain the current status value.
|
|
If the status is any value other than 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 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() returs the engine status.
|
|
|
|
|
|
=head1 NOTES
|
|
|
|
On Windows platforms the openssl/async.h header is dependent on some
|
|
of the types customarily made available by including 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
|
|
windows.h prior to 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.0.
|
|
|
|
=head1 COPYRIGHT
|
|
|
|
Copyright 2016 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
|