1=pod 2 3=head1 NAME 4 5ASYNC_WAIT_CTX_new, ASYNC_WAIT_CTX_free, ASYNC_WAIT_CTX_set_wait_fd, 6ASYNC_WAIT_CTX_get_fd, ASYNC_WAIT_CTX_get_all_fds, 7ASYNC_WAIT_CTX_get_changed_fds, ASYNC_WAIT_CTX_clear_fd, 8ASYNC_WAIT_CTX_set_callback, ASYNC_WAIT_CTX_get_callback, 9ASYNC_WAIT_CTX_set_status, ASYNC_WAIT_CTX_get_status, ASYNC_callback_fn, 10ASYNC_STATUS_UNSUPPORTED, ASYNC_STATUS_ERR, ASYNC_STATUS_OK, 11ASYNC_STATUS_EAGAIN 12- functions to manage waiting for asynchronous jobs to complete 13 14=head1 SYNOPSIS 15 16 #include <openssl/async.h> 17 18 #define ASYNC_STATUS_UNSUPPORTED 0 19 #define ASYNC_STATUS_ERR 1 20 #define ASYNC_STATUS_OK 2 21 #define ASYNC_STATUS_EAGAIN 3 22 typedef int (*ASYNC_callback_fn)(void *arg); 23 ASYNC_WAIT_CTX *ASYNC_WAIT_CTX_new(void); 24 void ASYNC_WAIT_CTX_free(ASYNC_WAIT_CTX *ctx); 25 int ASYNC_WAIT_CTX_set_wait_fd(ASYNC_WAIT_CTX *ctx, const void *key, 26 OSSL_ASYNC_FD fd, 27 void *custom_data, 28 void (*cleanup)(ASYNC_WAIT_CTX *, const void *, 29 OSSL_ASYNC_FD, void *)); 30 int ASYNC_WAIT_CTX_get_fd(ASYNC_WAIT_CTX *ctx, const void *key, 31 OSSL_ASYNC_FD *fd, void **custom_data); 32 int ASYNC_WAIT_CTX_get_all_fds(ASYNC_WAIT_CTX *ctx, OSSL_ASYNC_FD *fd, 33 size_t *numfds); 34 int ASYNC_WAIT_CTX_get_changed_fds(ASYNC_WAIT_CTX *ctx, OSSL_ASYNC_FD *addfd, 35 size_t *numaddfds, OSSL_ASYNC_FD *delfd, 36 size_t *numdelfds); 37 int ASYNC_WAIT_CTX_clear_fd(ASYNC_WAIT_CTX *ctx, const void *key); 38 int ASYNC_WAIT_CTX_set_callback(ASYNC_WAIT_CTX *ctx, 39 ASYNC_callback_fn callback, 40 void *callback_arg); 41 int ASYNC_WAIT_CTX_get_callback(ASYNC_WAIT_CTX *ctx, 42 ASYNC_callback_fn *callback, 43 void **callback_arg); 44 int ASYNC_WAIT_CTX_set_status(ASYNC_WAIT_CTX *ctx, int status); 45 int ASYNC_WAIT_CTX_get_status(ASYNC_WAIT_CTX *ctx); 46 47 48=head1 DESCRIPTION 49 50For an overview of how asynchronous operations are implemented in OpenSSL see 51L<ASYNC_start_job(3)>. An B<ASYNC_WAIT_CTX> object represents an asynchronous 52"session", i.e. a related set of crypto operations. For example in SSL terms 53this would have a one-to-one correspondence with an SSL connection. 54 55Application code must create an B<ASYNC_WAIT_CTX> using the ASYNC_WAIT_CTX_new() 56function prior to calling ASYNC_start_job() (see L<ASYNC_start_job(3)>). When 57the job is started it is associated with the B<ASYNC_WAIT_CTX> for the duration 58of that job. An B<ASYNC_WAIT_CTX> should only be used for one B<ASYNC_JOB> at 59any one time, but can be reused after an B<ASYNC_JOB> has finished for a 60subsequent B<ASYNC_JOB>. When the session is complete (e.g. the SSL connection 61is closed), application code cleans up with ASYNC_WAIT_CTX_free(). 62 63B<ASYNC_WAIT_CTX>s can have "wait" file descriptors associated with them. 64Calling ASYNC_WAIT_CTX_get_all_fds() and passing in a pointer to an 65B<ASYNC_WAIT_CTX> in the I<ctx> parameter will return the wait file descriptors 66associated with that job in I<*fd>. The number of file descriptors returned will 67be stored in I<*numfds>. It is the caller's responsibility to ensure that 68sufficient memory has been allocated in I<*fd> to receive all the file 69descriptors. Calling ASYNC_WAIT_CTX_get_all_fds() with a NULL I<fd> value will 70return no file descriptors but will still populate I<*numfds>. Therefore, 71application code is typically expected to call this function twice: once to get 72the number of fds, and then again when sufficient memory has been allocated. If 73only one asynchronous engine is being used then normally this call will only 74ever return one fd. If multiple asynchronous engines are being used then more 75could be returned. 76 77The function ASYNC_WAIT_CTX_get_changed_fds() can be used to detect if any fds 78have changed since the last call time ASYNC_start_job() returned B<ASYNC_PAUSE> 79(or since the B<ASYNC_WAIT_CTX> was created if no B<ASYNC_PAUSE> result has 80been received). The I<numaddfds> and I<numdelfds> parameters will be populated 81with the number of fds added or deleted respectively. I<*addfd> and I<*delfd> 82will be populated with the list of added and deleted fds respectively. Similarly 83to ASYNC_WAIT_CTX_get_all_fds() either of these can be NULL, but if they are not 84NULL then the caller is responsible for ensuring sufficient memory is allocated. 85 86Implementers of async aware code (e.g. engines) are encouraged to return a 87stable fd for the lifetime of the B<ASYNC_WAIT_CTX> in order to reduce the 88"churn" of regularly changing fds - although no guarantees of this are provided 89to applications. 90 91Applications can wait for the file descriptor to be ready for "read" using a 92system function call such as select or poll (being ready for "read" indicates 93that the job should be resumed). If no file descriptor is made available then an 94application will have to periodically "poll" the job by attempting to restart it 95to see if it is ready to continue. 96 97Async aware code (e.g. engines) can get the current B<ASYNC_WAIT_CTX> from the 98job via L<ASYNC_get_wait_ctx(3)> and provide a file descriptor to use for 99waiting on by calling ASYNC_WAIT_CTX_set_wait_fd(). Typically this would be done 100by an engine immediately prior to calling ASYNC_pause_job() and not by end user 101code. An existing association with a file descriptor can be obtained using 102ASYNC_WAIT_CTX_get_fd() and cleared using ASYNC_WAIT_CTX_clear_fd(). Both of 103these functions requires a I<key> value which is unique to the async aware 104code. This could be any unique value but a good candidate might be the 105B<ENGINE *> for the engine. The I<custom_data> parameter can be any value, and 106will be returned in a subsequent call to ASYNC_WAIT_CTX_get_fd(). The 107ASYNC_WAIT_CTX_set_wait_fd() function also expects a pointer to a "cleanup" 108routine. This can be NULL but if provided will automatically get called when 109the B<ASYNC_WAIT_CTX> is freed, and gives the engine the opportunity to close 110the fd or any other resources. Note: The "cleanup" routine does not get called 111if the fd is cleared directly via a call to ASYNC_WAIT_CTX_clear_fd(). 112 113An example of typical usage might be an async capable engine. User code would 114initiate cryptographic operations. The engine would initiate those operations 115asynchronously and then call ASYNC_WAIT_CTX_set_wait_fd() followed by 116ASYNC_pause_job() to return control to the user code. The user code can then 117perform other tasks or wait for the job to be ready by calling "select" or other 118similar function on the wait file descriptor. The engine can signal to the user 119code that the job should be resumed by making the wait file descriptor 120"readable". Once resumed the engine should clear the wake signal on the wait 121file descriptor. 122 123As well as a file descriptor, user code may also be notified via a callback. The 124callback and data pointers are stored within the B<ASYNC_WAIT_CTX> along with an 125additional status field that can be used for the notification of retries from an 126engine. This additional method can be used when the user thinks that a file 127descriptor is too costly in terms of CPU cycles or in some context where a file 128descriptor is not appropriate. 129 130ASYNC_WAIT_CTX_set_callback() sets the callback and the callback argument. The 131callback will be called to notify user code when an engine completes a 132cryptography operation. It is a requirement that the callback function is small 133and nonblocking as it will be run in the context of a polling mechanism or an 134interrupt. 135 136ASYNC_WAIT_CTX_get_callback() returns the callback set in the B<ASYNC_WAIT_CTX> 137structure. 138 139ASYNC_WAIT_CTX_set_status() allows an engine to set the current engine status. 140The possible status values are the following: 141 142=over 4 143 144=item B<ASYNC_STATUS_UNSUPPORTED> 145 146The engine does not support the callback mechanism. This is the default value. 147The engine must call ASYNC_WAIT_CTX_set_status() to set the status to some value 148other than B<ASYNC_STATUS_UNSUPPORTED> if it intends to enable the callback 149mechanism. 150 151=item B<ASYNC_STATUS_ERR> 152 153The engine has a fatal problem with this request. The user code should clean up 154this session. 155 156=item B<ASYNC_STATUS_OK> 157 158The request has been successfully submitted. 159 160=item B<ASYNC_STATUS_EAGAIN> 161 162The engine has some problem which will be recovered soon, such as a buffer is 163full, so user code should resume the job. 164 165=back 166 167ASYNC_WAIT_CTX_get_status() allows user code to obtain the current status value. 168If the status is any value other than B<ASYNC_STATUS_OK> then the user code 169should not expect to receive a callback from the engine even if one has been 170set. 171 172An example of the usage of the callback method might be the following. User 173code would initiate cryptographic operations, and the engine code would dispatch 174this operation to hardware, and if the dispatch is successful, then the engine 175code would call ASYNC_pause_job() to return control to the user code. After 176that, user code can perform other tasks. When the hardware completes the 177operation, normally it is detected by a polling function or an interrupt, as the 178user code set a callback by calling ASYNC_WAIT_CTX_set_callback() previously, 179then the registered callback will be called. 180 181=head1 RETURN VALUES 182 183ASYNC_WAIT_CTX_new() returns a pointer to the newly allocated B<ASYNC_WAIT_CTX> 184or NULL on error. 185 186ASYNC_WAIT_CTX_set_wait_fd, ASYNC_WAIT_CTX_get_fd, ASYNC_WAIT_CTX_get_all_fds, 187ASYNC_WAIT_CTX_get_changed_fds, ASYNC_WAIT_CTX_clear_fd, 188ASYNC_WAIT_CTX_set_callback, ASYNC_WAIT_CTX_get_callback and 189ASYNC_WAIT_CTX_set_status all return 1 on success or 0 on error. 190ASYNC_WAIT_CTX_get_status() returns the engine status. 191 192 193=head1 NOTES 194 195On Windows platforms the F<< <openssl/async.h> >> header is dependent on some 196of the types customarily made available by including F<< <windows.h> >>. The 197application developer is likely to require control over when the latter 198is included, commonly as one of the first included headers. Therefore, 199it is defined as an application developer's responsibility to include 200F<< <windows.h> >> prior to F<< <openssl/async.h> >>. 201 202=head1 SEE ALSO 203 204L<crypto(7)>, L<ASYNC_start_job(3)> 205 206=head1 HISTORY 207 208ASYNC_WAIT_CTX_new(), ASYNC_WAIT_CTX_free(), ASYNC_WAIT_CTX_set_wait_fd(), 209ASYNC_WAIT_CTX_get_fd(), ASYNC_WAIT_CTX_get_all_fds(), 210ASYNC_WAIT_CTX_get_changed_fds() and ASYNC_WAIT_CTX_clear_fd() 211were added in OpenSSL 1.1.0. 212 213ASYNC_WAIT_CTX_set_callback(), ASYNC_WAIT_CTX_get_callback(), 214ASYNC_WAIT_CTX_set_status(), and ASYNC_WAIT_CTX_get_status() 215were added in OpenSSL 3.0. 216 217=head1 COPYRIGHT 218 219Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved. 220 221Licensed under the Apache License 2.0 (the "License"). You may not use 222this file except in compliance with the License. You can obtain a copy 223in the file LICENSE in the source distribution or at 224L<https://www.openssl.org/source/license.html>. 225 226=cut 227