diff options
author | 2022-03-30 22:29:28 +0200 | |
---|---|---|
committer | 2022-03-31 19:51:47 +0200 | |
commit | c46e5df56b67bb8ea7a068d39324c640084ead2b (patch) | |
tree | eddeb17785938e09bc42eec98ee09b8a28846de6 /ctrl/facemgr/src/loop_libevent.c | |
parent | 18fa668f25d3cc5463417ce7df6637e31578e898 (diff) |
feat: boostrap hicn 22.02
The current patch provides several new features, improvements,
bug fixes and also complete rewrite of entire components.
- lib
The hicn packet parser has been improved with a new packet
format fully based on UDP. The TCP header is still temporarily
supported but the UDP header will replace completely the new hicn
packet format. Improvements have been made to make sure every
packet parsing operation is made via this library. The current
new header can be used as header between the payload and the
UDP header or as trailer in the UDP surplus area to be tested
when UDP options will start to be used.
- hicn-light
The portable packet forwarder has been completely rewritten from
scratch with the twofold objective to improve performance and
code size but also to drop dependencies such as libparc which is
now removed by the current implementation.
- hicn control
the control library is the agent that is used to program the
packet forwarders via their binary API. This component has
benefited from significant improvements in terms of interaction
model which is now event driven and more robust to failures.
- VPP plugin has been updated to support VPP 22.02
- transport
Major improvement have been made to the RTC protocol, to the
support of IO modules and to the security sub system. Signed
manifests are the default data authenticity and integrity framework.
Confidentiality can be enabled by sharing the encryption key to the
prod/cons layer. The library has been tested with group key based
applications such as broadcast/multicast and real-time on-line
meetings with trusted server keys or MLS.
- testing
Unit testing has been introduced using GoogleTest. One third of
the code base is covered by unit testing with priority on
critical features. Functional testing has also been introduce
using Docker, linux bridging and Robot Framework to define
test with Less Code techniques to facilitate the extension
of the coverage.
Co-authored-by: Mauro Sardara <msardara@cisco.com>
Co-authored-by: Jordan Augé <jordan.auge+fdio@cisco.com>
Co-authored-by: Michele Papalini <micpapal@cisco.com>
Co-authored-by: Angelo Mantellini <manangel@cisco.com>
Co-authored-by: Jacques Samain <jsamain@cisco.com>
Co-authored-by: Olivier Roques <oroques+fdio@cisco.com>
Co-authored-by: Enrico Loparco <eloparco@cisco.com>
Co-authored-by: Giulio Grassi <gigrassi@cisco.com>
Change-Id: I75d0ef70f86d921e3ef503c99271216ff583c215
Signed-off-by: Luca Muscariello <muscariello@ieee.org>
Signed-off-by: Mauro Sardara <msardara@cisco.com>
Diffstat (limited to 'ctrl/facemgr/src/loop_libevent.c')
-rw-r--r-- | ctrl/facemgr/src/loop_libevent.c | 563 |
1 files changed, 269 insertions, 294 deletions
diff --git a/ctrl/facemgr/src/loop_libevent.c b/ctrl/facemgr/src/loop_libevent.c index 674eee905..b619e02e6 100644 --- a/ctrl/facemgr/src/loop_libevent.c +++ b/ctrl/facemgr/src/loop_libevent.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * 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: @@ -25,13 +25,13 @@ #include <assert.h> #include <event2/event.h> #include <event2/thread.h> -#include <fcntl.h> // fcntl +#include <fcntl.h> // fcntl #ifdef WITH_THREAD #include <pthread.h> #endif /* WITH_THREAD */ #include <stdlib.h> #include <sys/timerfd.h> -#include <unistd.h> // fcntl +#include <unistd.h> // fcntl #include <hicn/facemgr/api.h> #include <hicn/util/log.h> @@ -43,160 +43,150 @@ * \brief Holds all callback parameters */ typedef struct { - void * owner; - fd_callback_t callback; - void * data; + void *owner; + fd_callback_t callback; + void *data; } cb_wrapper_args_t; TYPEDEF_MAP_H(event_map, int, struct event *); -TYPEDEF_MAP(event_map, int, struct event *, int_cmp, int_snprintf, generic_snprintf); +TYPEDEF_MAP(event_map, int, struct event *, int_cmp, int_snprintf, + generic_snprintf); /* Map that associates timer fds with their associated cb_wrapper_args_t */ TYPEDEF_MAP_H(timer_fd_map, int, cb_wrapper_args_t *); -TYPEDEF_MAP(timer_fd_map, int, cb_wrapper_args_t *, int_cmp, int_snprintf, generic_snprintf); +TYPEDEF_MAP(timer_fd_map, int, cb_wrapper_args_t *, int_cmp, int_snprintf, + generic_snprintf); struct loop_s { - struct event_base * event_base; - event_map_t * event_map; - timer_fd_map_t * timer_fd_map; + struct event_base *event_base; + event_map_t *event_map; + timer_fd_map_t *timer_fd_map; #ifdef WITH_THREAD - pthread_t thread; + pthread_t thread; #endif /* WITH_THREAD */ }; /* Forward declarations */ -int _loop_unregister_fd(loop_t * loop, int fd); -int _loop_unregister_timer(loop_t * loop, int fd); - -loop_t * -loop_create() -{ - loop_t * loop = malloc(sizeof(loop_t)); - if (!loop) { - ERROR("[loop_create] Failed to allocate memory"); - goto ERR_MALLOC; - } +int _loop_unregister_fd(loop_t *loop, int fd); +int _loop_unregister_timer(loop_t *loop, int fd); + +loop_t *loop_create() { + loop_t *loop = malloc(sizeof(loop_t)); + if (!loop) { + ERROR("[loop_create] Failed to allocate memory"); + goto ERR_MALLOC; + } #ifdef WITH_THREAD - evthread_use_pthreads(); + evthread_use_pthreads(); #endif /* WITH_THREAD */ - loop->event_base = event_base_new(); - if (!loop) - goto ERR_EVENT; + loop->event_base = event_base_new(); + if (!loop) goto ERR_EVENT; - loop->event_map = event_map_create(); - if (!loop->event_map) { - ERROR("[loop_create] Failed to create event_map"); - goto ERR_EVENT_MAP; - } + loop->event_map = event_map_create(); + if (!loop->event_map) { + ERROR("[loop_create] Failed to create event_map"); + goto ERR_EVENT_MAP; + } - loop->timer_fd_map = timer_fd_map_create(); - if (!loop->timer_fd_map) { - ERROR("[loop_create] Failed to create timer_fd_map"); - goto ERR_TIMER_FD_MAP; - } + loop->timer_fd_map = timer_fd_map_create(); + if (!loop->timer_fd_map) { + ERROR("[loop_create] Failed to create timer_fd_map"); + goto ERR_TIMER_FD_MAP; + } - event_set_log_callback(NULL); + event_set_log_callback(NULL); - return loop; + return loop; - timer_fd_map_free(loop->timer_fd_map); ERR_TIMER_FD_MAP: - event_map_free(loop->event_map); + event_map_free(loop->event_map); ERR_EVENT_MAP: - event_base_free(loop->event_base); + event_base_free(loop->event_base); ERR_EVENT: - free(loop); + free(loop); ERR_MALLOC: - return NULL; + return NULL; } -void -loop_free(loop_t * loop) -{ - /* - * Release all timer cb_wrapper_args_t - * - * We need to stop all timers, this should release associated fd events at - * the same time... for that reason, this code has to be called before - * releasing events - */ - - int * timer_fd_map_array; - int n = timer_fd_map_get_key_array(loop->timer_fd_map, &timer_fd_map_array); - if (n < 0) { - ERROR("[loop_free] Could not get event map array"); - } else { - for (unsigned i = 0; i < n; i++) { - int fd = timer_fd_map_array[i]; - if (_loop_unregister_timer(loop, fd) < 0) { - ERROR("[loop_free] Could not unregister timer"); - } - } - free(timer_fd_map_array); +void loop_free(loop_t *loop) { + /* + * Release all timer cb_wrapper_args_t + * + * We need to stop all timers, this should release associated fd events at + * the same time... for that reason, this code has to be called before + * releasing events + */ + + int *timer_fd_map_array; + int n = timer_fd_map_get_key_array(loop->timer_fd_map, &timer_fd_map_array); + if (n < 0) { + ERROR("[loop_free] Could not get event map array"); + } else { + for (unsigned i = 0; i < n; i++) { + int fd = timer_fd_map_array[i]; + if (_loop_unregister_timer(loop, fd) < 0) { + ERROR("[loop_free] Could not unregister timer"); + } } - timer_fd_map_free(loop->timer_fd_map); - - /* Release all events */ - - int * event_map_array; - n = event_map_get_key_array(loop->event_map, &event_map_array); - if (n < 0) { - ERROR("[loop_free] Could not get event map array"); - } else { - for (unsigned i = 0; i < n; i++) { - int fd = event_map_array[i]; - if (_loop_unregister_fd(loop, fd) < 0) { - ERROR("[loop_free] Could not unregister fd"); - } - } - free(event_map_array); + free(timer_fd_map_array); + } + timer_fd_map_free(loop->timer_fd_map); + + /* Release all events */ + + int *event_map_array; + n = event_map_get_key_array(loop->event_map, &event_map_array); + if (n < 0) { + ERROR("[loop_free] Could not get event map array"); + } else { + for (unsigned i = 0; i < n; i++) { + int fd = event_map_array[i]; + if (_loop_unregister_fd(loop, fd) < 0) { + ERROR("[loop_free] Could not unregister fd"); + } } - event_map_free(loop->event_map); + free(event_map_array); + } + event_map_free(loop->event_map); - event_base_free(loop->event_base); + event_base_free(loop->event_base); - free(loop); + free(loop); } -int -loop_dispatch(loop_t * loop) -{ +int loop_dispatch(loop_t *loop) { #ifdef WITH_THREAD - if (pthread_create(&loop->thread, NULL, (void * (*)(void *))event_base_dispatch, loop->event_base)) { - fprintf(stderr, "Error creating thread\n"); - return -1; - } + if (pthread_create(&loop->thread, NULL, + (void *(*)(void *))event_base_dispatch, + loop->event_base)) { + fprintf(stderr, "Error creating thread\n"); + return -1; + } #else - event_base_dispatch(loop->event_base); + event_base_dispatch(loop->event_base); #endif /* WITH_THREAD */ - return 0; + return 0; } -int -loop_undispatch(loop_t * loop) -{ +int loop_undispatch(loop_t *loop) { #ifdef WITH_THREAD - DEBUG("Waiting for loop to terminate..."); - if(pthread_join(loop->thread, NULL)) { - fprintf(stderr, "Error joining thread\n"); - return -1; - } - DEBUG("Loop terminated !"); + DEBUG("Waiting for loop to terminate..."); + if (pthread_join(loop->thread, NULL)) { + ERROR("Error joining thread\n"); + return -1; + } + DEBUG("Loop terminated !"); #endif /* WITH_THREAD */ - return 0; + return 0; } -void -loop_break(loop_t * loop) -{ - event_base_loopbreak(loop->event_base); -} +void loop_break(loop_t *loop) { event_base_loopbreak(loop->event_base); } -void cb_wrapper(evutil_socket_t fd, short what, void * arg) { - cb_wrapper_args_t * cb_wrapper_args = arg; - cb_wrapper_args->callback(cb_wrapper_args->owner, fd, cb_wrapper_args->data); +void cb_wrapper(evutil_socket_t fd, short what, void *arg) { + cb_wrapper_args_t *cb_wrapper_args = arg; + cb_wrapper_args->callback(cb_wrapper_args->owner, fd, cb_wrapper_args->data); } /** @@ -208,42 +198,41 @@ void cb_wrapper(evutil_socket_t fd, short what, void * arg) { * \param [in] callback_data - User data to pass alongside callback invocation * \return 0 in case of success, -1 otherwise */ -int -_loop_register_fd(loop_t * loop, int fd, void * callback_owner, - fd_callback_t callback, void * callback_data) -{ - /* This will be freed with the event */ - cb_wrapper_args_t * cb_wrapper_args = malloc(sizeof(cb_wrapper_args_t)); - *cb_wrapper_args = (cb_wrapper_args_t) { - .owner = callback_owner, - .callback = callback, - .data = callback_data, - }; - - evutil_make_socket_nonblocking(fd); - struct event * event = event_new(loop->event_base, fd, EV_READ | EV_PERSIST, cb_wrapper, cb_wrapper_args); - if (!event) { - ERROR("[_loop_register_fd] event_new"); - goto ERR_EVENT_NEW; - } - - if (event_add(event, NULL) < 0) { - ERROR("[_loop_register_fd] event_add"); - goto ERR_EVENT_ADD; - } - - if (event_map_add(loop->event_map, fd, event) < 0) { - ERROR("[_loop_register_fd] event_map_add"); - goto ERR_EVENT_MAP; - } - - return 0; +int _loop_register_fd(loop_t *loop, int fd, void *callback_owner, + fd_callback_t callback, void *callback_data) { + /* This will be freed with the event */ + cb_wrapper_args_t *cb_wrapper_args = malloc(sizeof(cb_wrapper_args_t)); + *cb_wrapper_args = (cb_wrapper_args_t){ + .owner = callback_owner, + .callback = callback, + .data = callback_data, + }; + + evutil_make_socket_nonblocking(fd); + struct event *event = event_new(loop->event_base, fd, EV_READ | EV_PERSIST, + cb_wrapper, cb_wrapper_args); + if (!event) { + ERROR("[_loop_register_fd] event_new"); + goto ERR_EVENT_NEW; + } + + if (event_add(event, NULL) < 0) { + ERROR("[_loop_register_fd] event_add"); + goto ERR_EVENT_ADD; + } + + if (event_map_add(loop->event_map, fd, event) < 0) { + ERROR("[_loop_register_fd] event_map_add"); + goto ERR_EVENT_MAP; + } + + return 0; ERR_EVENT_MAP: ERR_EVENT_ADD: - event_free(event); + event_free(event); ERR_EVENT_NEW: - return -1; + return -1; } /** @@ -251,183 +240,169 @@ ERR_EVENT_NEW: * \param [in] fd - File descriptor to unregister * \return 0 in case of success, -1 otherwise */ -int -_loop_unregister_fd(loop_t * loop, int fd) -{ - struct event * event = NULL; +int _loop_unregister_fd(loop_t *loop, int fd) { + struct event *event = NULL; - if (event_map_remove(loop->event_map, fd, &event) < 0) { - ERROR("[_loop_unregister_fd] Error removing event associated to fd"); - return -1; - } + if (event_map_remove(loop->event_map, fd, &event) < 0) { + ERROR("[_loop_unregister_fd] Error removing event associated to fd"); + return -1; + } - assert(event); + assert(event); - cb_wrapper_args_t * cb_wrapper_args = event_get_callback_arg(event); - free(cb_wrapper_args); + cb_wrapper_args_t *cb_wrapper_args = event_get_callback_arg(event); + free(cb_wrapper_args); - event_del(event); - event_free(event); + event_del(event); + event_free(event); - return 0; + return 0; } -int -loop_timer_callback(loop_t * loop, int fd, void * data) -{ - char buf[1024]; /* size is not important */ - cb_wrapper_args_t * cb_wrapper_args = data; - while (read(fd, &buf, sizeof(buf)) > 0) - ; +int loop_timer_callback(loop_t *loop, int fd, void *data) { + char buf[1024]; /* size is not important */ + cb_wrapper_args_t *cb_wrapper_args = data; + while (read(fd, &buf, sizeof(buf)) > 0) + ; - int rc = cb_wrapper_args->callback(cb_wrapper_args->owner, fd, - cb_wrapper_args->data); + int rc = cb_wrapper_args->callback(cb_wrapper_args->owner, fd, + cb_wrapper_args->data); - return rc; + return rc; } -int -_loop_register_timer(loop_t * loop, timer_callback_data_t * timer_callback_data) -{ - int fd = timerfd_create(CLOCK_MONOTONIC, 0); - if (fd == -1) { - perror("timerfd_create"); - return -1; - } +int _loop_register_timer(loop_t *loop, + timer_callback_data_t *timer_callback_data) { + int fd = timerfd_create(CLOCK_MONOTONIC, 0); + if (fd == -1) { + perror("timerfd_create"); + return -1; + } - if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) { - perror("fcntl"); - return -1; - } + if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) { + perror("fcntl"); + return -1; + } + + struct itimerspec ts = { + .it_interval = + { + .tv_sec = timer_callback_data->delay_ms / 1000, + .tv_nsec = (timer_callback_data->delay_ms % 1000) * 1000000, + }, + .it_value = { + .tv_sec = timer_callback_data->delay_ms / 1000, + .tv_nsec = (timer_callback_data->delay_ms % 1000) * 1000000, + }}; + + if (timerfd_settime(fd, 0, &ts, NULL) == -1) { + perror("timerfd_settime"); + return -1; + } + + /* This should be freed together with the timer release */ + cb_wrapper_args_t *cb_wrapper_args = malloc(sizeof(cb_wrapper_args_t)); + *cb_wrapper_args = (cb_wrapper_args_t){ + .owner = timer_callback_data->owner, + .callback = timer_callback_data->callback, + .data = timer_callback_data->data, + }; + + if (timer_fd_map_add(loop->timer_fd_map, fd, cb_wrapper_args) < 0) { + ERROR("[_loop_register_timer] Could not add cb_wrapper to timer map"); + return -1; + } - struct itimerspec ts = { - .it_interval = { - .tv_sec = timer_callback_data->delay_ms / 1000, - .tv_nsec = (timer_callback_data->delay_ms % 1000) * 1000000, - }, - .it_value = { - .tv_sec = timer_callback_data->delay_ms / 1000, - .tv_nsec = (timer_callback_data->delay_ms % 1000) * 1000000, - } - }; - - if (timerfd_settime(fd, 0, &ts, NULL) == -1) { - perror("timerfd_settime"); - return -1; - } + if (_loop_register_fd(loop, fd, loop, (fd_callback_t)loop_timer_callback, + cb_wrapper_args) < 0) { + ERROR("[_loop_register_timer] Error registering fd to event loop"); + return -1; + } - /* This should be freed together with the timer release */ - cb_wrapper_args_t * cb_wrapper_args = malloc(sizeof(cb_wrapper_args_t)); - *cb_wrapper_args = (cb_wrapper_args_t) { - .owner = timer_callback_data->owner, - .callback = timer_callback_data->callback, - .data = timer_callback_data->data, - }; + return fd; +} - if (timer_fd_map_add(loop->timer_fd_map, fd, cb_wrapper_args) < 0) { - ERROR("[_loop_register_timer] Could not add cb_wrapper to timer map"); - return -1; - } +int _loop_unregister_timer(loop_t *loop, int fd) { + struct itimerspec ts = {.it_interval = + { + .tv_sec = 0, + .tv_nsec = 0, + }, + .it_value = { + /* This value disables the timer */ + .tv_sec = 0, + .tv_nsec = 0, + }}; + ts.it_value.tv_sec = 0; + + if (timerfd_settime(fd, 0, &ts, NULL) == -1) { + perror("timerfd_settime"); + return -1; + } - if (_loop_register_fd(loop, fd, loop, - (fd_callback_t) loop_timer_callback, cb_wrapper_args) < 0) { - ERROR("[_loop_register_timer] Error registering fd to event loop"); - return -1; - } + cb_wrapper_args_t *cb_wrapper_args; + if (timer_fd_map_remove(loop->timer_fd_map, fd, &cb_wrapper_args) < 0) { + ERROR( + "[_loop_unregister_timer] Could not remove cb_wrapper from timer map"); + return -1; + } + assert(cb_wrapper_args); + free(cb_wrapper_args); + + if (_loop_unregister_fd(loop, fd) < 0) { + ERROR("[_loop_unregister_timer] Error unregistering fd from event loop"); + return -1; + } - return fd; + close(fd); + + return 0; } -int -_loop_unregister_timer(loop_t * loop, int fd) -{ - struct itimerspec ts = { - .it_interval = { - .tv_sec = 0, - .tv_nsec = 0, - }, - .it_value = { /* This value disables the timer */ - .tv_sec = 0, - .tv_nsec = 0, - } - }; - ts.it_value.tv_sec = 0; - - if (timerfd_settime(fd, 0, &ts, NULL) == -1) { - perror("timerfd_settime"); +int loop_callback(loop_t *loop, facemgr_cb_type_t type, void *data) { + switch (type) { + case FACEMGR_CB_TYPE_REGISTER_FD: { + fd_callback_data_t *fd_callback_data = (fd_callback_data_t *)data; + if (_loop_register_fd(loop, fd_callback_data->fd, fd_callback_data->owner, + fd_callback_data->callback, + fd_callback_data->data) < 0) { + ERROR("[loop_callback] Error registering fd to event loop"); return -1; + } + break; } - cb_wrapper_args_t * cb_wrapper_args; - if (timer_fd_map_remove(loop->timer_fd_map, fd, &cb_wrapper_args) < 0) { - ERROR("[_loop_unregister_timer] Could not remove cb_wrapper from timer map"); + case FACEMGR_CB_TYPE_UNREGISTER_FD: { + fd_callback_data_t *fd_callback_data = (fd_callback_data_t *)data; + /* We need a map to associate fd and events */ + if (_loop_unregister_fd(loop, fd_callback_data->fd) < 0) { + ERROR("[loop_callback] Error unregistering fd from event loop"); return -1; + } + break; } - assert(cb_wrapper_args); - free(cb_wrapper_args); - if (_loop_unregister_fd(loop, fd) < 0) { - ERROR("[_loop_unregister_timer] Error unregistering fd from event loop"); + case FACEMGR_CB_TYPE_REGISTER_TIMER: { + timer_callback_data_t *timer_callback_data = + (timer_callback_data_t *)data; + + int fd = _loop_register_timer(loop, timer_callback_data); + if (fd < 0) { + ERROR("[loop_callback] Error registering timer to event loop"); return -1; + } + return fd; } - return 0; -} + case FACEMGR_CB_TYPE_UNREGISTER_TIMER: { + int fd = *(int *)data; -int -loop_callback(loop_t * loop, facemgr_cb_type_t type, void * data) -{ - switch(type) { - case FACEMGR_CB_TYPE_REGISTER_FD: - { - fd_callback_data_t * fd_callback_data = (fd_callback_data_t *)data; - if (_loop_register_fd(loop, fd_callback_data->fd, - fd_callback_data->owner, - fd_callback_data->callback, - fd_callback_data->data) < 0) { - - ERROR("[loop_callback] Error registering fd to event loop"); - return -1; - } - break; - } - - case FACEMGR_CB_TYPE_UNREGISTER_FD: - { - fd_callback_data_t * fd_callback_data = (fd_callback_data_t *)data; - /* We need a map to associate fd and events */ - if (_loop_unregister_fd(loop, fd_callback_data->fd) < 0) { - ERROR("[loop_callback] Error unregistering fd from event loop"); - return -1; - } - break; - } - - case FACEMGR_CB_TYPE_REGISTER_TIMER: - { - timer_callback_data_t * timer_callback_data = (timer_callback_data_t *)data; - - int fd = _loop_register_timer(loop, timer_callback_data); - if (fd < 0) { - ERROR("[loop_callback] Error registering timer to event loop"); - return -1; - } - return fd; - - } - - case FACEMGR_CB_TYPE_UNREGISTER_TIMER: - { - int fd = *(int*)data; - - if (_loop_unregister_timer(loop, fd) < 0) { - ERROR("[loop_callback] Error unregistering timer from event loop"); - return -1; - } - return 0; - - } + if (_loop_unregister_timer(loop, fd) < 0) { + ERROR("[loop_callback] Error unregistering timer from event loop"); + return -1; + } + return 0; } - return 0; + } + return 0; } - |