BSL v0.0.0
AMMOS Bundle Protocol Security Library (BSL)
Loading...
Searching...
No Matches
mock_bpa.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2025 The Johns Hopkins University Applied Physics
3 * Laboratory LLC.
4 *
5 * This file is part of the Bundle Protocol Security Library (BSL).
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 * This work was performed for the Jet Propulsion Laboratory, California
18 * Institute of Technology, sponsored by the United States Government under
19 * the prime contract 80NM0018D0004 between the Caltech and NASA under
20 * subcontract 1700763.
21 */
26#include <arpa/inet.h>
27#include <errno.h>
28#include <m-atomic.h>
29#include <m-buffer.h>
30#include <netdb.h>
31#include <poll.h>
32#include <signal.h>
33#include <sys/socket.h>
34#include <sys/types.h>
35#include <sys/un.h>
36#include <unistd.h>
37
38#include <BPSecLib_Private.h>
39#include <BPSecLib_Public.h>
40
41#include "bsl_mock_bpa.h"
42#include "mock_bpa_ctr.h"
43
44static atomic_bool stop_state;
45
46#define DATA_QUEUE_SIZE 100
47
48BUFFER_DEF(data_queue, mock_bpa_ctr_t, DATA_QUEUE_SIZE,
49 BUFFER_QUEUE | BUFFER_THREAD_SAFE | BUFFER_PUSH_INIT_POP_MOVE | BUFFER_BLOCKING)
50
51static data_queue_t over_rx;
52static data_queue_t over_tx;
53static data_queue_t under_rx;
54static data_queue_t under_tx;
55static data_queue_t deliver;
56static data_queue_t forward;
57
58static pthread_t thr_over_rx, thr_under_rx, thr_deliver, thr_forward;
59
60// Library context
61static BSL_LibCtx_t *bsl;
62
63// Configuration
64static BSL_HostEID_t app_eid;
65static struct sockaddr_in6 over_addr = { .sin6_family = 0 };
66static struct sockaddr_in6 app_addr = { .sin6_family = 0 };
67static struct sockaddr_in6 under_addr = { .sin6_family = 0 };
68static struct sockaddr_in6 router_addr = { .sin6_family = 0 };
69static int tx_notify_r, tx_notify_w;
70static BSL_HostEID_t sec_eid;
71
72static int ingest_netaddr(struct sockaddr_in6 *addr, const char *optarg)
73{
74 const char *node = optarg;
75 const char *service = "4556";
76 char *sep = strchr(optarg, ':');
77 if (sep)
78 {
79 *sep = '\0';
80 service = sep + 1; // might be at the terminator
81 }
82 struct addrinfo hints = {
83 .ai_family = AF_INET6,
84 .ai_socktype = SOCK_DGRAM,
85 .ai_protocol = IPPROTO_UDP,
86 .ai_flags = AI_ADDRCONFIG | AI_NUMERICSERV,
87 };
88 struct addrinfo *result;
89
90 BSL_LOG_DEBUG("Resolving under address: %s %s", node, service);
91 int res = getaddrinfo(node, service, &hints, &result);
92 if (res)
93 {
94 BSL_LOG_ERR("Failed to resolve router address: %s", optarg);
95 return 1;
96 }
97 else
98 {
99 for (const struct addrinfo *rp = result; rp != NULL; rp = rp->ai_next)
100 {
101 // use first address
102 if (rp->ai_family == AF_INET6)
103 {
104 memcpy(addr, rp->ai_addr, rp->ai_addrlen);
105 break;
106 }
107 }
108 freeaddrinfo(result);
109 }
110 return 0;
111}
112
113static int bind_udp(int *sock, const struct sockaddr_in6 *addr)
114{
115 *sock = socket(addr->sin6_family, SOCK_DGRAM, IPPROTO_UDP);
116 if (*sock < 0)
117 {
118 BSL_LOG_ERR("Failed to open UDP socket");
119 return 2;
120 }
121 {
122 char nodebuf[INET6_ADDRSTRLEN];
123 inet_ntop(addr->sin6_family, &addr->sin6_addr, nodebuf, sizeof(nodebuf));
124 BSL_LOG_DEBUG("Binding UDP socket to [%s]:%d", nodebuf, ntohs(addr->sin6_port));
125
126 int res = bind(*sock, (struct sockaddr *)addr, sizeof(*addr));
127 if (res)
128 {
129 close(*sock);
130 BSL_LOG_ERR("Failed to bind UDP socket, errno %d", errno);
131 return 3;
132 }
133 }
134
135 return 0;
136}
137
138static int mock_bpa_process(BSL_PolicyLocation_e loc, MockBPA_Bundle_t *bundle)
139{
140 (void)loc;
141 (void)bundle;
142 BSL_LOG_INFO("Mock BPA: Invoking mock_bpa_process");
143 BSL_SecurityActionSet_t *malloced_action_set = calloc(BSL_SecurityActionSet_Sizeof(), 1);
144 BSL_SecurityResponseSet_t *malloced_response_set = calloc(BSL_SecurityResponseSet_Sizeof(), 1);
145 int returncode = -1;
146
147 BSL_BundleRef_t bundle_ref = { 0 };
148 bundle_ref.data = bundle;
149 BSL_LOG_INFO("Mock BPA: Calling BSL_API_QuerySecurity");
150 returncode = BSL_API_QuerySecurity(bsl, malloced_action_set, &bundle_ref, loc);
151 if (returncode != 0)
152 {
153 BSL_LOG_ERR("Failed to query security: code=%d", returncode);
154 goto cleanup;
155 }
156
157 BSL_LOG_INFO("Mock BPA: Calling BSL_API_ApplySecurity");
158 returncode = BSL_API_ApplySecurity(bsl, malloced_response_set, &bundle_ref, malloced_action_set);
159 if (returncode < 0)
160 {
161 BSL_LOG_ERR("Failed to apply security: code=%d", returncode);
162 goto cleanup;
163 }
164
165 BSL_LOG_INFO("Mock BPA: mock_bpa_process SUCCESS (code=0)");
166
167cleanup:
168 free(malloced_action_set);
169 free(malloced_response_set);
170 return returncode;
171}
172
173static void sig_stop(int signum _U_)
174{
175 atomic_store(&stop_state, true);
176 BSL_LOG_INFO("signal received %d", signum);
177}
178
179static void *work_over_rx(void *arg _U_)
180{
181 BSL_LOG_INFO("work_over_rx started");
182 while (true)
183 {
184 mock_bpa_ctr_t item;
185 data_queue_pop(&item, over_rx);
186 if (item.encoded.len == 0)
187 {
188 break;
189 }
190 BSL_LOG_INFO("over_rx");
191 mock_bpa_decode(&item, bsl);
192
193 if (mock_bpa_process(BSL_POLICYLOCATION_APPIN, item.bundle_ref.data))
194 {
195 BSL_LOG_ERR("work_over_rx failed security processing");
196 mock_bpa_ctr_deinit(&item);
197 continue;
198 }
199
200 // loopback
201 data_queue_push(deliver, item);
202 }
203 BSL_LOG_INFO("work_over_rx stopped");
204
205 return NULL;
206}
207
208static void *work_under_rx(void *arg _U_)
209{
210 BSL_LOG_INFO("work_under_rx started");
211 while (true)
212 {
213 mock_bpa_ctr_t item;
214 data_queue_pop(&item, under_rx);
215 if (item.encoded.len == 0)
216 {
217 break;
218 }
219
220 BSL_LOG_INFO("under_rx");
221 if (mock_bpa_decode(&item, bsl))
222 {
223 BSL_LOG_ERR("work_under_rx failed to decode bundle");
224 mock_bpa_ctr_deinit(&item);
225 continue;
226 }
227
228 if (mock_bpa_process(BSL_POLICYLOCATION_CLIN, item.bundle_ref.data))
229 {
230 BSL_LOG_ERR("work_under_rx failed security processing");
231 mock_bpa_ctr_deinit(&item);
232 continue;
233 }
234
235 // loopback
236 data_queue_push(forward, item);
237 }
238 BSL_LOG_INFO("work_under_rx stopped");
239
240 return NULL;
241}
242
243static void *work_deliver(void *arg _U_)
244{
245 BSL_LOG_INFO("work_deliver started");
246 while (true)
247 {
248 mock_bpa_ctr_t item;
249 data_queue_pop(&item, deliver);
250 if (item.encoded.len == 0)
251 {
252 break;
253 }
254 BSL_LOG_INFO("deliver");
255
256 if (mock_bpa_process(BSL_POLICYLOCATION_APPOUT, item.bundle_ref.data))
257 {
258 BSL_LOG_ERR("work_deliver failed security processing");
259 mock_bpa_ctr_deinit(&item);
260 continue;
261 }
262
263 mock_bpa_encode(&item);
264 data_queue_push(over_tx, item);
265 {
266 uint8_t buf = 0;
267 int nbytes = write(tx_notify_w, &buf, sizeof(uint8_t));
268 if (nbytes < 0)
269 {
270 BSL_LOG_ERR("Failed to write: %ld", nbytes);
271 }
272 }
273 }
274 BSL_LOG_INFO("work_deliver stopped");
275
276 return NULL;
277}
278
279static void *work_forward(void *arg _U_)
280{
281 BSL_LOG_INFO("work_forward started");
282 while (true)
283 {
284 mock_bpa_ctr_t item;
285 data_queue_pop(&item, forward);
286 if (item.encoded.len == 0)
287 {
288 break;
289 }
290 BSL_LOG_INFO("forward");
291
292 if (mock_bpa_process(BSL_POLICYLOCATION_CLOUT, item.bundle_ref.data))
293 {
294 BSL_LOG_ERR("work_forward failed security processing");
295 mock_bpa_ctr_deinit(&item);
296 continue;
297 }
298
299 mock_bpa_encode(&item);
300 data_queue_push(under_tx, item);
301 {
302 uint8_t buf = 0;
303 int nbytes = write(tx_notify_w, &buf, sizeof(uint8_t));
304 if (nbytes < 0)
305 {
306 BSL_LOG_ERR("Failed to write, got %ld", nbytes);
307 }
308 }
309 }
310 BSL_LOG_INFO("work_forward stopped");
311
312 return NULL;
313}
314
315static int bpa_init(void)
316{
317 {
318 struct sigaction stopper = {
319 .sa_handler = sig_stop,
320 };
321 sigaction(SIGINT, &stopper, NULL);
322 sigaction(SIGTERM, &stopper, NULL);
323 }
324
325 data_queue_init(over_rx, DATA_QUEUE_SIZE);
326 data_queue_init(over_tx, DATA_QUEUE_SIZE);
327 data_queue_init(under_rx, DATA_QUEUE_SIZE);
328 data_queue_init(under_tx, DATA_QUEUE_SIZE);
329 data_queue_init(deliver, DATA_QUEUE_SIZE);
330 data_queue_init(forward, DATA_QUEUE_SIZE);
331
332 {
333 // event socket for waking the I/O thread
334 int fds[2];
335 if (pipe(fds) != 0)
336 {
337 return 3;
338 }
339 tx_notify_r = fds[0];
340 tx_notify_w = fds[1];
341 }
342
343 if (pthread_create(&thr_under_rx, NULL, work_under_rx, NULL))
344 {
345 return 2;
346 }
347 if (pthread_create(&thr_over_rx, NULL, work_over_rx, NULL))
348 {
349 return 2;
350 }
351 if (pthread_create(&thr_deliver, NULL, work_deliver, NULL))
352 {
353 return 2;
354 }
355 if (pthread_create(&thr_forward, NULL, work_forward, NULL))
356 {
357 return 2;
358 }
359 return 0;
360}
361
362static int bpa_exec(void)
363{
364 int retval = 0;
365
366 int over_sock, under_sock;
367 if (bind_udp(&over_sock, &over_addr))
368 {
369 return 3;
370 }
371 if (bind_udp(&under_sock, &under_addr))
372 {
373 return 3;
374 }
375
376 struct pollfd pfds[] = {
377 { .fd = tx_notify_r, .events = POLLIN },
378 { .fd = under_sock },
379 { .fd = over_sock },
380 };
381 struct pollfd *const tx_notify_pfd = pfds;
382 struct pollfd *const under_pfd = pfds + 1;
383 struct pollfd *const over_pfd = pfds + 2;
384
385 BSL_LOG_INFO("READY");
386
387 while (!atomic_load(&stop_state))
388 {
389 under_pfd->events = POLLIN;
390 if (!data_queue_empty_p(under_tx))
391 {
392 under_pfd->events |= POLLOUT;
393 }
394
395 over_pfd->events = POLLIN;
396 if (!data_queue_empty_p(over_tx))
397 {
398 over_pfd->events |= POLLOUT;
399 }
400
401 int res = poll(pfds, sizeof(pfds) / sizeof(struct pollfd), -1);
402 if (res < 0)
403 {
404 retval = 4;
405 break;
406 }
407
408 if (tx_notify_pfd->revents & POLLIN)
409 {
410 // no actual data, just clear the pipe
411 uint8_t buf;
412 int nbytes = read(tx_notify_r, &buf, sizeof(uint8_t));
413 if (nbytes < 0)
414 {
415 BSL_LOG_ERR("Cannot read: %ld", nbytes);
416 }
417 }
418
419 if (over_pfd->revents & POLLIN)
420 {
421 uint8_t buf[65536];
422 struct iovec iov = {
423 .iov_base = buf,
424 .iov_len = sizeof(buf),
425 };
426 struct msghdr msg = {
427 .msg_iovlen = 1,
428 .msg_iov = &iov,
429 };
430 ssize_t got = recvmsg(over_sock, &msg, 0);
431 if (got > 0)
432 {
433 BSL_LOG_DEBUG("over_sock recv %zd", got);
434 mock_bpa_ctr_t item;
435 mock_bpa_ctr_init(&item);
436 BSL_Data_AppendFrom(&item.encoded, got, buf);
437
438 data_queue_push(over_rx, item);
439 }
440 }
441 if (over_pfd->revents & POLLOUT)
442 {
443 mock_bpa_ctr_t item;
444 data_queue_pop(&item, over_tx);
445
446 BSL_LOG_DEBUG("over_sock send %zd", item.encoded.len);
447 struct iovec iov = {
448 .iov_base = item.encoded.ptr,
449 .iov_len = item.encoded.len,
450 };
451 struct msghdr msg = {
452 .msg_name = &app_addr,
453 .msg_namelen = sizeof(app_addr),
454 .msg_iovlen = 1,
455 .msg_iov = &iov,
456 };
457 ssize_t got = sendmsg(over_sock, &msg, 0);
458 if (got != (ssize_t)item.encoded.len)
459 {
460 BSL_LOG_ERR("over_sock failed to send all %zd bytes, only %zd sent: %d", item.encoded.len, got, errno);
461 }
462 mock_bpa_ctr_deinit(&item);
463 }
464
465 if (under_pfd->revents & POLLIN)
466 {
467 uint8_t buf[65536];
468 struct iovec iov = {
469 .iov_base = buf,
470 .iov_len = sizeof(buf),
471 };
472 struct msghdr msg = {
473 .msg_iovlen = 1,
474 .msg_iov = &iov,
475 };
476 ssize_t got = recvmsg(under_sock, &msg, 0);
477 if (got > 0)
478 {
479 BSL_LOG_DEBUG("under_sock recv %zd", got);
480 mock_bpa_ctr_t item;
481 mock_bpa_ctr_init(&item);
482 BSL_Data_AppendFrom(&item.encoded, got, buf);
483
484 data_queue_push(under_rx, item);
485 }
486 }
487 if (under_pfd->revents & POLLOUT)
488 {
489 mock_bpa_ctr_t item;
490 data_queue_pop(&item, under_tx);
491
492 BSL_LOG_DEBUG("under_sock send %zd", item.encoded.len);
493 struct iovec iov = {
494 .iov_base = item.encoded.ptr,
495 .iov_len = item.encoded.len,
496 };
497 struct msghdr msg = {
498 .msg_name = &router_addr,
499 .msg_namelen = sizeof(router_addr),
500 .msg_iovlen = 1,
501 .msg_iov = &iov,
502 };
503 ssize_t got = sendmsg(under_sock, &msg, 0);
504 if (got != (ssize_t)item.encoded.len)
505 {
506 BSL_LOG_ERR("under_sock failed to send all %zd bytes, only %zd sent", item.encoded.len, got);
507 }
508 mock_bpa_ctr_deinit(&item);
509 }
510 }
511
512 close(over_sock);
513 close(under_sock);
514 return retval;
515}
516
517static void bpa_cleanup(void)
518{
519 mock_bpa_ctr_t item;
520
521 // join RX workers first
522 // mock_bpa_ctr_init(&item);
523 data_queue_push(under_rx, item);
524 // mock_bpa_ctr_init(&item);
525 data_queue_push(over_rx, item);
526 if (pthread_join(thr_under_rx, NULL))
527 {
528 BSL_LOG_ERR("Failed to join the work_under_rx");
529 }
530 if (pthread_join(thr_over_rx, NULL))
531 {
532 BSL_LOG_ERR("Failed to join the work_over_rx");
533 }
534
535 // then delivery/forward workers after RX are all flushed
536 // mock_bpa_ctr_init(&item);
537 data_queue_push(forward, item);
538 // mock_bpa_ctr_init(&item);
539 data_queue_push(deliver, item);
540 if (pthread_join(thr_forward, NULL))
541 {
542 BSL_LOG_ERR("Failed to join the work_forward");
543 }
544 if (pthread_join(thr_deliver, NULL))
545 {
546 BSL_LOG_ERR("Failed to join the work_deliver");
547 }
548
549 close(tx_notify_r);
550 close(tx_notify_w);
551 data_queue_clear(over_rx);
552 data_queue_clear(over_tx);
553 data_queue_clear(under_rx);
554 data_queue_clear(under_tx);
555 data_queue_clear(deliver);
556 data_queue_clear(forward);
557
558 BSL_HostEID_Deinit(&sec_eid);
559 BSL_HostEID_Deinit(&app_eid);
560 ASSERT_PROPERTY(BSL_API_DeinitLib(bsl) == 0);
561}
562
563static void show_usage(const char *argv0)
564{
565 fprintf(stderr,
566 "Usage: %s -o <over-socket address:port> -a <application address:port>\n"
567 " -u <under-socket address:port> -r <router address:port>\n"
568 " -e <app-EID> -s <sec-src-EID>\n",
569 argv0);
570}
571
574
575int main(int argc, char **argv)
576{
577 BSL_openlog();
578 int retval = 0;
579
580 atomic_init(&stop_state, false);
581
582 if (bsl_mock_bpa_init())
583 {
584 BSL_LOG_ERR("Failed to initialize mock BPA");
585 retval = 2;
586 }
587
588 // TODO XXX FIX BEFORE MERGE!!
589 bsl = calloc(50000, 1);
590 if (BSL_API_InitLib(bsl))
591 {
592 BSL_LOG_ERR("Failed to initialize BSL");
593 retval = 2;
594 }
595
596 BSL_PolicyDesc_t policy_callbacks = { .deinit_fn = BSLP_Deinit,
597 .query_fn = BSLP_QueryPolicy,
598 .user_data = malloc(100000) };
599 assert(BSL_SUCCESS == BSL_API_RegisterPolicyProvider(bsl, policy_callbacks));
600
601 BSL_SecCtxDesc_t security_context_callbacks;
602 (void)security_context_callbacks;
603
604 BSL_HostEID_Init(&app_eid);
605 BSL_HostEID_Init(&sec_eid);
606 if (!retval)
607 {
608 int opt;
609 while ((opt = getopt(argc, argv, "ha:o:a:u:r:e:s:")) != -1)
610 {
611 switch (opt)
612 {
613 case 'o':
614 ingest_netaddr(&over_addr, optarg);
615 break;
616 case 'a':
617 ingest_netaddr(&app_addr, optarg);
618 break;
619 case 'u':
620 ingest_netaddr(&under_addr, optarg);
621 break;
622 case 'r':
623 ingest_netaddr(&router_addr, optarg);
624 break;
625 case 'e':
626 if (BSL_HostEID_DecodeFromText(&app_eid, optarg))
627 {
628 BSL_LOG_ERR("Failed to decode app EID: %s", optarg);
629 retval = 1;
630 }
631 break;
632 case 's':
633 if (BSL_HostEID_DecodeFromText(&sec_eid, optarg))
634 {
635 BSL_LOG_ERR("Failed to decode BPSec EID: %s", optarg);
636 retval = 1;
637 }
638 break;
639 case 'h':
640 default:
641 show_usage(argv[0]);
642 retval = 1;
643 break;
644 }
645 }
646 if (!retval && (over_addr.sin6_family != AF_INET6))
647 {
648 BSL_LOG_ERR("Missing over-socket address\n");
649 show_usage(argv[0]);
650 retval = 1;
651 }
652 if (!retval && (app_addr.sin6_family != AF_INET6))
653 {
654 BSL_LOG_ERR("Missing application address\n");
655 show_usage(argv[0]);
656 retval = 1;
657 }
658 if (!retval && (under_addr.sin6_family != AF_INET6))
659 {
660 BSL_LOG_ERR("Missing under-socket address\n");
661 show_usage(argv[0]);
662 retval = 1;
663 }
664 if (!retval && (router_addr.sin6_family != AF_INET6))
665 {
666 BSL_LOG_ERR("Missing router address\n");
667 show_usage(argv[0]);
668 retval = 1;
669 }
670 }
671
672 if (!retval)
673 {
674 retval = bpa_init();
675 }
676 if (!retval)
677 {
678 retval = bpa_exec();
679 }
680
681 if (retval != 1)
682 {
683 bpa_cleanup();
684 }
686 BSL_closelog();
687 free(bsl);
688 return retval;
689}
Single entry-point include file for all of the BPSec Lib (BSL) frontend API.
#define BSL_LOG_DEBUG(...)
This is an overloaded member function, provided for convenience. It differs from the above function o...
#define BSL_LOG_INFO(...)
This is an overloaded member function, provided for convenience. It differs from the above function o...
#define _U_
Mark an unused parameter Within a function definition.
#define BSL_LOG_ERR(...)
This is an overloaded member function, provided for convenience. It differs from the above function o...
@ BSL_SUCCESS
Placeholder for non-error code.
Single entry-point include file for all of the "Public" BPSec Lib (BSL) frontend API.
BSL_PolicyLocation_e
Indicates where in the lifecycle of the BPA the bundle is querying for security policy.
@ BSL_POLICYLOCATION_APPOUT
Bundle destination at delivery.
@ BSL_POLICYLOCATION_APPIN
Bundle source at creation.
@ BSL_POLICYLOCATION_CLIN
Bundle ingress from CLA.
@ BSL_POLICYLOCATION_CLOUT
Bundle egress to CLA.
Header for the implementation of an example default security context (RFC 9173).
int BSL_HostEID_Init(BSL_HostEID_t *eid)
Initialize an abstract EID.
int BSL_HostEID_DecodeFromText(BSL_HostEID_t *eid, const char *text)
Decode an EID from its text form.
void BSL_HostEID_Deinit(BSL_HostEID_t *eid)
De-initialize an abstract EID.
void BSL_openlog(void)
Opens the event log.
void BSL_closelog(void)
Closes the event log.
int BSL_API_InitLib(BSL_LibCtx_t *lib)
Initialize the BPSecLib (BSL) library context.
int BSL_API_QuerySecurity(const BSL_LibCtx_t *bsl, BSL_SecurityActionSet_t *output_action_set, const BSL_BundleRef_t *bundle, BSL_PolicyLocation_e location)
Query BSL to populate a BSL_SecurityActionSet_t containg security processing instructions.
int BSL_API_RegisterPolicyProvider(BSL_LibCtx_t *lib, BSL_PolicyDesc_t desc)
Register a Policy Provider module with the BSL.
int BSL_API_ApplySecurity(const BSL_LibCtx_t *bsl, BSL_SecurityResponseSet_t *response_output, BSL_BundleRef_t *bundle, const BSL_SecurityActionSet_t *policy_actions)
Performs the given security operations on a Bundle, modifying or even dropping it entirely.
int BSL_API_DeinitLib(BSL_LibCtx_t *lib)
Deinitialize and release any resources held by the BSL.
int BSLP_QueryPolicy(const void *user_data, BSL_SecurityActionSet_t *output_action_set, const BSL_BundleRef_t *bundle, BSL_PolicyLocation_e location)
Note that criticality is HIGH.
Spec of locally-defined data structures.
size_t BSL_SecurityActionSet_Sizeof(void)
Returns size of the struct, helpful for dynamic allocation.
size_t BSL_SecurityResponseSet_Sizeof()
Returns size of this struct type.
int BSL_Data_AppendFrom(BSL_Data_t *data, size_t len, BSL_DataConstPtr_t src)
Append an initialized data struct with a given size.
void bsl_mock_bpa_deinit(void)
Clean up the mock BPA for the current process.
int bsl_mock_bpa_init(void)
Register this mock BPA for the current process.
Declarations for Agent initialization.
Reference to a Bundle owned and stored in the host BPA.
void * data
Opaque pointer, not used by the BSL.
size_t len
Size of the data buffer.
BSL_DataPtr_t ptr
Pointer to the front of the buffer.
Opaque pointer to BPA-specific Endpoint ID storage.
Concrete definition of library context.
Descriptor of opaque data and callbacks for Policy Provider.
BSL_PolicyDeinit_f deinit_fn
Function to deinit the policy provider at termination of BPA.
Security Context descriptor (interface)
Contains the populated security operations for this bundle.
Contains the results and outcomes after performing the security operations.
A container for encoded and decoded bundle data.
BSL_Data_t encoded
Encoded PDU.
BSL_BundleRef_t bundle_ref
The decoded bundle.