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