-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathlibdd_rc.h
More file actions
350 lines (276 loc) · 11 KB
/
Copy pathlibdd_rc.h
File metadata and controls
350 lines (276 loc) · 11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
/* Copyright 2026-Present Datadog, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* libdd-rc - Remote Configuration Client Library
*
* C FFI interface for the Datadog Remote Configuration X509 client library.
*/
#ifndef LIBDD_RC_H
#define LIBDD_RC_H
/* Warning: This file is autogenerated by cbindgen. Do not modify. */
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
/*
Result of pushing data received from the RC delivery backend into the
internal client library recv queue (returned by the client library).
*/
enum recv_ret_t
#if __STDC_VERSION__ >= 202311L
: int32_t
#endif // __STDC_VERSION__ >= 202311L
{
/*
The message was successfully passed.
*/
RECV_RET_T_SUCCESS = 0,
};
#if __STDC_VERSION__ >= 202311L
typedef enum recv_ret_t recv_ret_t;
#else
typedef int32_t recv_ret_t;
#endif // __STDC_VERSION__ >= 202311L
/*
Result of sending data to the RC delivery backend, returned by the host
runtime.
*/
enum send_ret_t
#if __STDC_VERSION__ >= 202311L
: int32_t
#endif // __STDC_VERSION__ >= 202311L
{
/*
The FFI host accepted this request.
*/
SEND_RET_T_SUCCESS = 0,
/*
The connection is closed on the FFI side.
*/
SEND_RET_T_CLOSED = 1,
/*
An unknown error occurred.
*/
SEND_RET_T_UNKNOWN = INT32_MAX,
};
#if __STDC_VERSION__ >= 202311L
typedef enum send_ret_t send_ret_t;
#else
typedef int32_t send_ret_t;
#endif // __STDC_VERSION__ >= 202311L
/*
A [`Ctx`] is a RAII handle for an instance of a X509 verifier.
The [`Ctx`] owns the event loop / runtime that drives the internal client
execution, and owns caches of state (certificates, CRLs, etc) which are
shared across all connections to the RC delivery backend.
Each [`Ctx`] spawns a worker thread, and can have zero or more
[`FFIConnection`] registered to it to provide I/O and manage per-connection
state.
The FFI host is responsible for constructing a [`Ctx`] with [`rc_init()`],
and shutting down the [`Ctx`] with [`rc_free()`] to release all resources it
holds.
[`FFIConnection`]: super::FFIConnection
*/
typedef struct Ctx Ctx;
/*
An [`FFIConnection`] brokers I/O between the client library and the FFI host
runtime, modelling a single connection to the RC backend.
One [`FFIConnection`] directly maps to one RC backend platform session,
where "session" is typically a single WebSocket connection.
The [`FFIConnection`] holds per-connection state, and is registered to a
[`Ctx`] by the host runtime. The connection to the RC backend is managed by
the host runtime, and connection lifecycle events are communicated to the
client library by calling FFI functions with the appropriate
[`FFIConnection`] handle.
# Handling I/O
Once the [`FFIConnection`] is in the [`State::Connected`] state, it can be
used to send outgoing I/O from the library, to the RC backend, and deliver
incoming payloads from the RC backend to the library.
All I/O is handled through an [`IOHandle`] presented to the non-FFI library
code as a safe, decoupled interface. Each [`FFIConnection`] runs an
[`io_task`] when in the [`State::Connected`] state to handle outgoing
payloads.
Outgoing I/O:
```text
libdd-rc
│
▼
IOHandle::send()
│
▼
lib2ffi channel
|
│ io_task pulls from the
▼ lib2ffi & calls SendCb
SendCb
│
▼
FFI Host Runtime
│
▼
RC Backend Server
```
1. A call to [`IOHandle::send()`] is made, and the payload is added to an
internal FIFO queue.
2. Asynchronously the [`io_task`] assigned to this [`FFIConnection`] wakes
up, and pulls the payload from the queue.
3. The [`io_task`] calls the [`SendCb`] registered to the
[`FFIConnection`], invoking the callback on the FFI host.
4. The [`io_task`] frees the memory held by the payload.
Incoming I/O:
```text
RC Backend Server
│
▼
FFI Host Runtime
│
│ rc_conn_recv()
▼
ffi2lib channel
│
▼
IOHandle::recv()
│
▼
libdd-rc
```
1. The FFI host calls into this library with [`rc_conn_recv()`] which
copies the payload into an internal queue.
2. A consumer in the non-FFI code eventually pulls this incoming message
from the queue and processes it.
# FFI Interface
This type is represented across the FFI boundary as an [opaque handle]; the
host runtime can reference the handle when making subsequent FFI functions,
but cannot interact with the internal fields.
This type is expected to emit [`ConnectionEvent`] lifecycle updates to
inform the main (non-FFI) library code of state changes.
[opaque handle]: https://interrupt.memfault.com/blog/opaque-pointers
*/
typedef struct FFIConnection FFIConnection;
/*
Send `data` from the client library to the RC delivery backend over the
network [`FFIConnection`] the callback was registered to..
Passes a reference to a byte slice of `length` number of bytes that is valid
for the lifetime of the function call.
The callback is invoked with the `user_data` value provided by the caller
when configuring the send callback.
* Called by: `client library`.
* Ownership: passes shared reference to the `data` array to the host
runtime for the duration of the call.
NOTE: the client library retains ownership of `data` after this call, and it
may be freed or modified at any time after this function returns.
*/
typedef send_ret_t (*SendCb)(const uint8_t *data, uint32_t length, const void *user_data);
/*
Mark the connection as established.
The caller MUST have made a previous call to [`rc_conn_send_callback()`],
else this call will return an error and the connection will not be marked as
available internally.
* Called by: `host runtime`.
* Ownership: passes mutable reference of [`FFIConnection`] to client
library for the duration of the call.
# Safety
This call is not concurrency safe.
*/
void rc_conn_connected(struct FFIConnection *conn);
/*
Mark the connection as closed.
The caller MUST NOT call [`rc_conn_recv()`] for this `conn` after this call,
but MAY subsequently call [`rc_conn_connected()`] for the same `conn` to
resume communication.
This call blocks until in-flight [`SendCb`] calls are completed and the
internal I/O task exists cleanly, after which time it is guaranteed no more
calls to the [`SendCb`] will be made.
* Called by: `host runtime`.
* Ownership: passes mutable reference of [`FFIConnection`] to client
library for the duration of the call.
# Safety
This call is not concurrency safe.
*/
void rc_conn_disconnected(struct FFIConnection *conn);
/*
Release the resources held by this `conn`.
* Called by: `host runtime`.
* Ownership: passes ownership of [`FFIConnection`] to client library.
# Safety
The `conn` MUST be marked as disconnected ([`rc_conn_disconnected()`]) prior
to freeing the connection.
*/
void rc_conn_free(struct FFIConnection *conn);
/*
Initialise a new client connection state.
* Called by: `host runtime`.
* Ownership: passes mutable reference of `conn` for the duration of the
call, and returns ownership of [`FFIConnection`].
# Safety
This call is safe iff `ctx` points to a handle obtained from a [`rc_init()`]
call that has not yet been freed, and is concurrency safe.
*/
struct FFIConnection *rc_conn_new(const struct Ctx *ctx);
/*
Pass data received from the RC delivery backend for the `conn` connection.
* Called by: `host runtime`.
* Ownership: passes shared reference of [`FFIConnection`] and `data` to
client library for the duration of the call.
NOTE: the host runtime retains ownership of `data` after this call, and is
responsible for freeing the memory backing it after this call completes.
# Safety
The `conn` MUST have previously been marked as ready using
[`rc_conn_connected()`], and the provided `data` MUST be valid for a read of
`length` bytes for the duration of this function call.
*/
recv_ret_t rc_conn_recv(const struct FFIConnection *conn, const uint8_t *data, uint32_t length);
/*
Configure the callback used by the client library to request data be sent to
the RC backend.
This call MUST be made before the first call to [`rc_conn_connected()`] for
the same `conn`.
The `user_data` pointer is for use by the caller to pass state to the
subsequent [`SendCb`] calls, and is never referenced internally. It MAY be
null, but it MUST be safe to pass between threads.
* Called by: `host runtime`.
* Ownership: passes mutable reference of `conn` for the duration of the
call.
# Safety
This call MUST provide a `cb` that is valid and safe to call concurrently at
all times after [`rc_conn_connected()`] is called for `conn`, until a
subsequent [`rc_conn_disconnected()`] for the same `conn` returns.
*/
void rc_conn_send_callback(struct FFIConnection *conn, SendCb cb, const void *user_data);
/*
Stop the client running in [`Ctx`], and release all resources held by
[`Ctx`].
Callers MUST have previously disconnected ([`rc_conn_disconnected()`]) any
open connections and released ([`rc_conn_free()`]) any connections held by
the caller prior to calling this function.
* Called by: `host runtime`.
* Ownership: passes ownership of [`Ctx`] to client library.
# Safety
Must be called exactly once per `ctx` obtained from a prior call to
[`rc_init()`].
[`rc_conn_disconnected()`]: super::rc_conn_disconnected()
[`rc_conn_free()`]: super::rc_conn_free()
*/
void rc_free(struct Ctx *ctx);
/*
Initialise a new client [`Ctx`], starting a background thread to drive
internal execution.
* Called by: `host runtime`.
* Ownership: returns ownership of [`Ctx`] to host runtime.
# Safety
This call is always safe.
*/
struct Ctx *rc_init(void);
#endif /* LIBDD_RC_H */