add an additional async notification communication method based on callback
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)
This commit is contained in:
parent
61e033308b
commit
9f5a87fd66
14 changed files with 368 additions and 19 deletions
|
@ -59,6 +59,9 @@ struct async_wait_ctx_st {
|
|||
struct fd_lookup_st *fds;
|
||||
size_t numadd;
|
||||
size_t numdel;
|
||||
ASYNC_callback_fn callback;
|
||||
void *callback_arg;
|
||||
int status;
|
||||
};
|
||||
|
||||
DEFINE_STACK_OF(ASYNC_JOB)
|
||||
|
|
|
@ -182,6 +182,41 @@ int ASYNC_WAIT_CTX_clear_fd(ASYNC_WAIT_CTX *ctx, const void *key)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int ASYNC_WAIT_CTX_set_callback(ASYNC_WAIT_CTX *ctx,
|
||||
ASYNC_callback_fn callback,
|
||||
void *callback_arg)
|
||||
{
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
|
||||
ctx->callback = callback;
|
||||
ctx->callback_arg = callback_arg;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ASYNC_WAIT_CTX_get_callback(ASYNC_WAIT_CTX *ctx,
|
||||
ASYNC_callback_fn *callback,
|
||||
void **callback_arg)
|
||||
{
|
||||
if (ctx->callback == NULL)
|
||||
return 0;
|
||||
|
||||
*callback = ctx->callback;
|
||||
*callback_arg = ctx->callback_arg;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ASYNC_WAIT_CTX_set_status(ASYNC_WAIT_CTX *ctx, int status)
|
||||
{
|
||||
ctx->status = status;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ASYNC_WAIT_CTX_get_status(ASYNC_WAIT_CTX *ctx)
|
||||
{
|
||||
return ctx->status;
|
||||
}
|
||||
|
||||
void async_wait_ctx_reset_counts(ASYNC_WAIT_CTX *ctx)
|
||||
{
|
||||
struct fd_lookup_st *curr, *prev = NULL;
|
||||
|
|
|
@ -4,13 +4,22 @@
|
|||
|
||||
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 - functions to manage
|
||||
waiting for asynchronous jobs to complete
|
||||
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,
|
||||
|
@ -26,6 +35,14 @@ waiting for asynchronous jobs to complete
|
|||
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
|
||||
|
@ -103,14 +120,58 @@ 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 and ASYNC_WAIT_CTX_clear_fd all return 1 on
|
||||
success or 0 on error.
|
||||
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
|
||||
|
||||
|
@ -132,6 +193,10 @@ 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.
|
||||
|
|
|
@ -107,22 +107,26 @@ ASYNC_pause_job() is called whilst not within the context of a job then no
|
|||
action is taken and ASYNC_pause_job() returns immediately.
|
||||
|
||||
ASYNC_get_wait_ctx() can be used to get a pointer to the ASYNC_WAIT_CTX
|
||||
for the B<job>. ASYNC_WAIT_CTXs can have a "wait" file descriptor associated
|
||||
with them. 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.
|
||||
for the B<job>. ASYNC_WAIT_CTXs contain two different ways to notify
|
||||
applications that a job is ready to be resumed. One is a "wait" file
|
||||
descriptor, and the other is a "callback" mechanism.
|
||||
|
||||
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 L<ASYNC_WAIT_CTX_set_wait_fd(3)> 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.
|
||||
The "wait" file descriptor associated with ASYNC_WAIT_CTX is used for
|
||||
applications to 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_WAIT_CTXs also have a "callback" mechanism to notify applications. The
|
||||
callback is set by an application, and it will be automatically called when an
|
||||
engine completes a cryptography operation, so that the application can resume
|
||||
the paused work flow without polling. An engine could be written to look whether
|
||||
the callback has been set. If it has then it would use the callback mechanism
|
||||
in preference to the file descriptor notifications. If a callback is not set
|
||||
then the engine may use file descriptor based notifications. Please note that
|
||||
not all engines may support the callback mechanism, so the callback may not be
|
||||
used even if it has been set. See ASYNC_WAIT_CTX_new() for more details.
|
||||
|
||||
The ASYNC_block_pause() function will prevent the currently active job from
|
||||
pausing. The block will remain in place until a subsequent call to
|
||||
|
|
96
doc/man3/SSL_set_async_callback.pod
Normal file
96
doc/man3/SSL_set_async_callback.pod
Normal file
|
@ -0,0 +1,96 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
SSL_CTX_set_async_callback,
|
||||
SSL_CTX_set_async_callback_arg,
|
||||
SSL_set_async_callback,
|
||||
SSL_set_async_callback_arg,
|
||||
SSL_get_async_status,
|
||||
SSL_async_callback_fn
|
||||
- manage asynchronous operations
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
=for comment multiple includes
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
typedef int (*SSL_async_callback_fn)(SSL *s, void *arg);
|
||||
int SSL_CTX_set_async_callback(SSL_CTX *ctx, SSL_async_callback_fn callback);
|
||||
int SSL_CTX_set_async_callback_arg(SSL_CTX *ctx, void *arg);
|
||||
int SSL_set_async_callback(SSL *s, SSL_async_callback_fn callback);
|
||||
int SSL_set_async_callback_arg(SSL *s, void *arg);
|
||||
int SSL_get_async_status(SSL *s, int *status);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
SSL_CTX_set_async_callback() sets an asynchronous callback function. All SSL
|
||||
objects generated based on this SSL_CTX will get this callback. If an engine
|
||||
supports the callback mechanism, it will be automatically called if
|
||||
SSL_MODE_ASYNC has been set and an asynchronous capable engine completes a
|
||||
cryptography operation to notify the application to resume the paused work flow.
|
||||
|
||||
SSL_CTX_set_async_callback_arg() sets the callback argument.
|
||||
|
||||
SSL_set_async_callback() allows an application to set a callback in an
|
||||
asynchronous SSL object, so that when an engine completes a cryptography
|
||||
operation, the callback will be called to notify the application to resume the
|
||||
paused work flow.
|
||||
|
||||
SSL_set_async_callback_arg() sets an argument for the SSL object when the above
|
||||
callback is called.
|
||||
|
||||
SSL_get_async_status() returns the engine status. This function facilitates the
|
||||
communication from the engine to the application. During an SSL session,
|
||||
cryptographic operations are dispatched to an engine. The engine status is very
|
||||
useful for an application to know if the operation has been successfully
|
||||
dispatched. If the engine does not support this additional callback method,
|
||||
"ASYNC_STATUS_UNSUPPORTED" will be returned. See ASYNC_WAIT_CTX_set_status() for
|
||||
a description of all of the status values.
|
||||
|
||||
An example of the above functions would be the following.
|
||||
1. Application sets the async callback and callback data on an SSL connection
|
||||
by calling SSL_set_async_callback().
|
||||
2. Application sets SSL_MODE_ASYNC and makes an asynchronous SSL call
|
||||
3. OpenSSL submits the asynchronous request to the engine. If a retry occurs at
|
||||
this point then the status within the ASYNC_WAIT_CTX would be set and the async
|
||||
callback function would be called (goto Step 7).
|
||||
4. The OpenSSL engine pauses the current job and returns, so that the
|
||||
application can continue processing other connections.
|
||||
5. At a future point in time (probably via a polling mechanism or via an
|
||||
interrupt) the engine will become aware that the asynchronous request has
|
||||
finished processing.
|
||||
6. The engine will call the application's callback passing the callback data as
|
||||
a parameter.
|
||||
7. The callback function should then run. Note: 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.
|
||||
8. It is the application's responsibility via the callback function to schedule
|
||||
recalling the OpenSSL asynchronous function and to continue processing.
|
||||
9. The callback function has the option to check the status returned via
|
||||
SSL_get_async_status() to determine whether a retry happened instead of the
|
||||
request being submitted, allowing different processing if required.
|
||||
|
||||
=head1 RETURN VALUES
|
||||
|
||||
SSL_CTX_set_async_callback(), SSL_set_async_callback(),
|
||||
SSL_CTX_set_async_callback_arg(), SSL_CTX_set_async_callback_arg() and
|
||||
SSL_get_async_status() return 1 on success or 0 on error.
|
||||
|
||||
=head1 HISTORY
|
||||
|
||||
SSL_CTX_set_async_callback(), SSL_CTX_set_async_callback_arg(),
|
||||
SSL_set_async_callback(), SSL_set_async_callback_arg() and
|
||||
SSL_get_async_status() were first added to OpenSSL 3.0.0.
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
|
||||
Licensed under the OpenSSL license (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
|
|
@ -403,6 +403,8 @@ static void wait_cleanup(ASYNC_WAIT_CTX *ctx, const void *key,
|
|||
static void dummy_pause_job(void) {
|
||||
ASYNC_JOB *job;
|
||||
ASYNC_WAIT_CTX *waitctx;
|
||||
ASYNC_callback_fn callback;
|
||||
void * callback_arg;
|
||||
OSSL_ASYNC_FD pipefds[2] = {0, 0};
|
||||
OSSL_ASYNC_FD *writefd;
|
||||
#if defined(ASYNC_WIN)
|
||||
|
@ -417,6 +419,18 @@ static void dummy_pause_job(void) {
|
|||
|
||||
waitctx = ASYNC_get_wait_ctx(job);
|
||||
|
||||
if (ASYNC_WAIT_CTX_get_callback(waitctx, &callback, &callback_arg) && callback != NULL) {
|
||||
/*
|
||||
* In the Dummy async engine we are cheating. We call the callback that the job
|
||||
* is complete before the call to ASYNC_pause_job(). A real
|
||||
* async engine would only call the callback when the job was actually complete
|
||||
*/
|
||||
(*callback)(callback_arg);
|
||||
ASYNC_pause_job();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (ASYNC_WAIT_CTX_get_fd(waitctx, engine_dasync_id, &pipefds[0],
|
||||
(void **)&writefd)) {
|
||||
pipefds[1] = *writefd;
|
||||
|
|
|
@ -31,12 +31,18 @@ extern "C" {
|
|||
|
||||
typedef struct async_job_st ASYNC_JOB;
|
||||
typedef struct async_wait_ctx_st ASYNC_WAIT_CTX;
|
||||
typedef int (*ASYNC_callback_fn)(void *arg);
|
||||
|
||||
#define ASYNC_ERR 0
|
||||
#define ASYNC_NO_JOBS 1
|
||||
#define ASYNC_PAUSE 2
|
||||
#define ASYNC_FINISH 3
|
||||
|
||||
#define ASYNC_STATUS_UNSUPPORTED 0
|
||||
#define ASYNC_STATUS_ERR 1
|
||||
#define ASYNC_STATUS_OK 2
|
||||
#define ASYNC_STATUS_EAGAIN 3
|
||||
|
||||
int ASYNC_init_thread(size_t max_size, size_t init_size);
|
||||
void ASYNC_cleanup_thread(void);
|
||||
|
||||
|
@ -52,6 +58,14 @@ 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_callback(ASYNC_WAIT_CTX *ctx,
|
||||
ASYNC_callback_fn *callback,
|
||||
void **callback_arg);
|
||||
int ASYNC_WAIT_CTX_set_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);
|
||||
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);
|
||||
|
|
|
@ -293,6 +293,9 @@ typedef int (*SSL_custom_ext_parse_cb_ex)(SSL *s, unsigned int ext_type,
|
|||
/* Typedef for verification callback */
|
||||
typedef int (*SSL_verify_cb)(int preverify_ok, X509_STORE_CTX *x509_ctx);
|
||||
|
||||
/* Typedef for SSL async callback */
|
||||
typedef int (*SSL_async_callback_fn)(SSL *s, void *arg);
|
||||
|
||||
/*
|
||||
* Some values are reserved until OpenSSL 1.2.0 because they were previously
|
||||
* included in SSL_OP_ALL in a 1.1.x release.
|
||||
|
@ -1815,6 +1818,12 @@ __owur int SSL_get_all_async_fds(SSL *s, OSSL_ASYNC_FD *fds, size_t *numfds);
|
|||
__owur int SSL_get_changed_async_fds(SSL *s, OSSL_ASYNC_FD *addfd,
|
||||
size_t *numaddfds, OSSL_ASYNC_FD *delfd,
|
||||
size_t *numdelfds);
|
||||
__owur int SSL_CTX_set_async_callback(SSL_CTX *ctx, SSL_async_callback_fn callback);
|
||||
__owur int SSL_CTX_set_async_callback_arg(SSL_CTX *ctx, void *arg);
|
||||
__owur int SSL_set_async_callback(SSL *s, SSL_async_callback_fn callback);
|
||||
__owur int SSL_set_async_callback_arg(SSL *s, void *arg);
|
||||
__owur int SSL_get_async_status(SSL *s, int *status);
|
||||
|
||||
# endif
|
||||
__owur int SSL_accept(SSL *ssl);
|
||||
__owur int SSL_stateless(SSL *s);
|
||||
|
|
|
@ -831,6 +831,9 @@ SSL *SSL_new(SSL_CTX *ctx)
|
|||
s->psk_find_session_cb = ctx->psk_find_session_cb;
|
||||
s->psk_use_session_cb = ctx->psk_use_session_cb;
|
||||
|
||||
s->async_cb = ctx->async_cb;
|
||||
s->async_cb_arg = ctx->async_cb_arg;
|
||||
|
||||
s->job = NULL;
|
||||
|
||||
#ifndef OPENSSL_NO_CT
|
||||
|
@ -1652,6 +1655,40 @@ int SSL_get_changed_async_fds(SSL *s, OSSL_ASYNC_FD *addfd, size_t *numaddfds,
|
|||
numdelfds);
|
||||
}
|
||||
|
||||
int SSL_CTX_set_async_callback(SSL_CTX *ctx, SSL_async_callback_fn callback)
|
||||
{
|
||||
ctx->async_cb = callback;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SSL_CTX_set_async_callback_arg(SSL_CTX *ctx, void *arg)
|
||||
{
|
||||
ctx->async_cb_arg = arg;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SSL_set_async_callback(SSL *s, SSL_async_callback_fn callback)
|
||||
{
|
||||
s->async_cb = callback;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SSL_set_async_callback_arg(SSL *s, void *arg)
|
||||
{
|
||||
s->async_cb_arg = arg;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SSL_get_async_status(SSL *s, int *status)
|
||||
{
|
||||
ASYNC_WAIT_CTX *ctx = s->waitctx;
|
||||
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
*status = ASYNC_WAIT_CTX_get_status(ctx);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SSL_accept(SSL *s)
|
||||
{
|
||||
if (s->handshake_func == NULL) {
|
||||
|
@ -1677,6 +1714,13 @@ long SSL_get_default_timeout(const SSL *s)
|
|||
return s->method->get_timeout();
|
||||
}
|
||||
|
||||
static int ssl_async_wait_ctx_cb(void *arg)
|
||||
{
|
||||
SSL *s = (SSL *)arg;
|
||||
|
||||
return s->async_cb(s, s->async_cb_arg);
|
||||
}
|
||||
|
||||
static int ssl_start_async_job(SSL *s, struct ssl_async_args *args,
|
||||
int (*func) (void *))
|
||||
{
|
||||
|
@ -1685,6 +1729,10 @@ static int ssl_start_async_job(SSL *s, struct ssl_async_args *args,
|
|||
s->waitctx = ASYNC_WAIT_CTX_new();
|
||||
if (s->waitctx == NULL)
|
||||
return -1;
|
||||
if (s->async_cb != NULL
|
||||
&& !ASYNC_WAIT_CTX_set_callback
|
||||
(s->waitctx, ssl_async_wait_ctx_cb, s))
|
||||
return -1;
|
||||
}
|
||||
switch (ASYNC_start_job(&s->job, s->waitctx, &ret, func, args,
|
||||
sizeof(struct ssl_async_args))) {
|
||||
|
|
|
@ -1076,6 +1076,10 @@ struct ssl_ctx_st {
|
|||
|
||||
/* Do we advertise Post-handshake auth support? */
|
||||
int pha_enabled;
|
||||
|
||||
/* Callback for SSL async handling */
|
||||
SSL_async_callback_fn async_cb;
|
||||
void *async_cb_arg;
|
||||
};
|
||||
|
||||
struct ssl_st {
|
||||
|
@ -1471,6 +1475,10 @@ struct ssl_st {
|
|||
/* Callback to determine if early_data is acceptable or not */
|
||||
SSL_allow_early_data_cb_fn allow_early_data_cb;
|
||||
void *allow_early_data_cb_data;
|
||||
|
||||
/* Callback for SSL async handling */
|
||||
SSL_async_callback_fn async_cb;
|
||||
void *async_cb_arg;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -123,6 +123,43 @@ static int test_ASYNC_init_thread(void)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int test_callback(void *arg)
|
||||
{
|
||||
printf("callback test pass\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int test_ASYNC_callback_status(void)
|
||||
{
|
||||
ASYNC_WAIT_CTX *waitctx = NULL;
|
||||
int set_arg = 100;
|
||||
ASYNC_callback_fn get_callback;
|
||||
void *get_arg;
|
||||
int set_status = 1;
|
||||
|
||||
if ( !ASYNC_init_thread(1, 0)
|
||||
|| (waitctx = ASYNC_WAIT_CTX_new()) == NULL
|
||||
|| ASYNC_WAIT_CTX_set_callback(waitctx, test_callback, (void*)&set_arg)
|
||||
!= 1
|
||||
|| ASYNC_WAIT_CTX_get_callback(waitctx, &get_callback, &get_arg)
|
||||
!= 1
|
||||
|| test_callback != get_callback
|
||||
|| get_arg != (void*)&set_arg
|
||||
|| (*get_callback)(get_arg) != 1
|
||||
|| ASYNC_WAIT_CTX_set_status(waitctx, set_status) != 1
|
||||
|| set_status != ASYNC_WAIT_CTX_get_status(waitctx)) {
|
||||
fprintf(stderr, "test_ASYNC_callback_status() failed\n");
|
||||
ASYNC_WAIT_CTX_free(waitctx);
|
||||
ASYNC_cleanup_thread();
|
||||
return 0;
|
||||
}
|
||||
|
||||
ASYNC_WAIT_CTX_free(waitctx);
|
||||
ASYNC_cleanup_thread();
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
static int test_ASYNC_start_job(void)
|
||||
{
|
||||
ASYNC_JOB *job = NULL;
|
||||
|
@ -279,6 +316,7 @@ int main(int argc, char **argv)
|
|||
CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
|
||||
|
||||
if ( !test_ASYNC_init_thread()
|
||||
|| !test_ASYNC_callback_status()
|
||||
|| !test_ASYNC_start_job()
|
||||
|| !test_ASYNC_get_current_job()
|
||||
|| !test_ASYNC_WAIT_CTX_get_all_fds()
|
||||
|
|
|
@ -4622,3 +4622,7 @@ CRYPTO_siv128_cleanup 4577 3_0_0 EXIST::FUNCTION:SIV
|
|||
CRYPTO_siv128_speed 4578 3_0_0 EXIST::FUNCTION:SIV
|
||||
OPENSSL_INIT_set_config_filename 4579 3_0_0 EXIST::FUNCTION:STDIO
|
||||
OPENSSL_INIT_set_config_file_flags 4580 3_0_0 EXIST::FUNCTION:STDIO
|
||||
ASYNC_WAIT_CTX_get_callback 4581 3_0_0 EXIST::FUNCTION:
|
||||
ASYNC_WAIT_CTX_set_callback 4582 3_0_0 EXIST::FUNCTION:
|
||||
ASYNC_WAIT_CTX_set_status 4583 3_0_0 EXIST::FUNCTION:
|
||||
ASYNC_WAIT_CTX_get_status 4584 3_0_0 EXIST::FUNCTION:
|
||||
|
|
|
@ -498,3 +498,8 @@ SSL_CTX_get_recv_max_early_data 498 3_0_0 EXIST::FUNCTION:
|
|||
SSL_CTX_set_recv_max_early_data 499 3_0_0 EXIST::FUNCTION:
|
||||
SSL_CTX_set_post_handshake_auth 500 3_0_0 EXIST::FUNCTION:
|
||||
SSL_get_signature_type_nid 501 3_0_0 EXIST::FUNCTION:
|
||||
SSL_CTX_set_async_callback 502 3_0_0 EXIST::FUNCTION:
|
||||
SSL_CTX_set_async_callback_arg 503 3_0_0 EXIST::FUNCTION:
|
||||
SSL_set_async_callback 504 3_0_0 EXIST::FUNCTION:
|
||||
SSL_set_async_callback_arg 505 3_0_0 EXIST::FUNCTION:
|
||||
SSL_get_async_status 506 3_0_0 EXIST::FUNCTION:
|
||||
|
|
|
@ -90,6 +90,8 @@ custom_ext_free_cb datatype
|
|||
custom_ext_parse_cb datatype
|
||||
pem_password_cb datatype
|
||||
ssl_ct_validation_cb datatype
|
||||
ASYNC_callback_fn datatype
|
||||
SSL_async_callback_fn datatype
|
||||
#
|
||||
BIO_append_filename define
|
||||
BIO_destroy_bio_pair define
|
||||
|
@ -475,3 +477,7 @@ X509_STORE_set_verify_func define
|
|||
EVP_PKEY_CTX_set1_id define
|
||||
EVP_PKEY_CTX_get1_id define
|
||||
EVP_PKEY_CTX_get1_id_len define
|
||||
ASYNC_STATUS_EAGAIN define
|
||||
ASYNC_STATUS_OK define
|
||||
ASYNC_STATUS_ERR define
|
||||
ASYNC_STATUS_UNSUPPORTED define
|
||||
|
|
Loading…
Reference in a new issue