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