diff options
author | dimitri staessens <[email protected]> | 2017-02-06 16:05:44 +0100 |
---|---|---|
committer | dimitri staessens <[email protected]> | 2017-02-06 20:04:34 +0100 |
commit | 373efaf24d3600fe4dadf6bfaaee8d19e2ec32d7 (patch) | |
tree | 8711a4edbc2a6defaab63f0dcc2b0690252307b4 /src/ipcpd/normal/enroll.c | |
parent | 4b11f952c521315883f64571e1790389e8d20f64 (diff) | |
download | ouroboros-373efaf24d3600fe4dadf6bfaaee8d19e2ec32d7.tar.gz ouroboros-373efaf24d3600fe4dadf6bfaaee8d19e2ec32d7.zip |
ipcpd, lib: Revise normal IPCP
This PR updates the normal IPCP to use the new RIB. The old ribmgr is
removed and replaced by a stub that needs to be implemented. All
components (dir, fmgr, frct) were adapted to the new RIB API. A lot
of functionality was moved outside of the ribmgr, such as the
addr_auth, which is now a component of the IPCP. The address is also
stored to the ipcpi struct. The irm tool has an option to set the gam
policy of the rib manager.
Diffstat (limited to 'src/ipcpd/normal/enroll.c')
-rw-r--r-- | src/ipcpd/normal/enroll.c | 263 |
1 files changed, 263 insertions, 0 deletions
diff --git a/src/ipcpd/normal/enroll.c b/src/ipcpd/normal/enroll.c new file mode 100644 index 00000000..695ceb1d --- /dev/null +++ b/src/ipcpd/normal/enroll.c @@ -0,0 +1,263 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * Enrollment Task + * + * Dimitri Staessens <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#define OUROBOROS_PREFIX "enrollment" + +#include <ouroboros/config.h> +#include <ouroboros/cdap.h> +#include <ouroboros/dev.h> +#include <ouroboros/logs.h> +#include <ouroboros/rib.h> + +#include "ae.h" + +#include <assert.h> +#include <stdlib.h> +#include <string.h> + +#define DLR "/" +#define DIF_PATH DLR DIF_NAME +#define BOOT_PATH DLR BOOT_NAME +#define MEMBERS_PATH DLR MEMBERS_NAME + +int enroll_handle(int fd) +{ + struct cdap * ci; + cdap_key_t key; + enum cdap_opcode oc; + char * name; + uint8_t * buf; + uint8_t * data; + ssize_t len; + uint32_t flags; + + bool boot_r = false; + bool members_r = false; + bool dif_name_r = false; + + char * boot_ro = BOOT_PATH; + char * members_ro = MEMBERS_PATH; + char * dif_ro = DIF_PATH; + + if (flow_alloc_resp(fd, 0) < 0) { + flow_dealloc(fd); + LOG_ERR("Could not respond to request."); + return -1; + } + + ci = cdap_create(fd); + if (ci == NULL) { + flow_dealloc(fd); + LOG_ERR("Failed to create CDAP instance."); + return -1; + } + + while (!(boot_r && members_r && dif_name_r)) { + key = cdap_request_wait(ci, &oc, &name, &data, + (size_t *) &len , &flags); + + assert(key >= 0); + assert(name); + + if (data != NULL) { + free(data); + LOG_WARN("Received data with enrollment request."); + } + + if (oc != CDAP_READ) { + LOG_WARN("Invalid request."); + cdap_reply_send(ci, key, -1, NULL, 0); + cdap_destroy(ci); + flow_dealloc(fd); + free(name); + return -1; + } + + if (strcmp(name, boot_ro) == 0) { + boot_r = true; + } else if (strcmp(name, members_ro) == 0) { + members_r = true; + } else if (strcmp(name, dif_ro) == 0) { + dif_name_r = true; + } else { + LOG_WARN("Illegal read: %s.", name); + cdap_reply_send(ci, key, -1, NULL, 0); + cdap_destroy(ci); + flow_dealloc(fd); + free(name); + return -1; + } + + len = rib_pack(name, &buf, PACK_HASH_ROOT); + if (len < 0) { + LOG_ERR("Failed to pack %s.", name); + cdap_reply_send(ci, key, -1, NULL, 0); + cdap_destroy(ci); + flow_dealloc(fd); + free(name); + return -1; + } + + LOG_DBG("Packed %s (%lu bytes).", name, len); + + free(name); + + if (cdap_reply_send(ci, key, 0, buf, len)) { + LOG_ERR("Failed to send CDAP reply."); + cdap_destroy(ci); + flow_dealloc(fd); + return -1; + } + + free(buf); + } + + LOG_DBG("Sent boot info to new member."); + + cdap_destroy(ci); + + flow_dealloc(fd); + + return 0; +} + +int enroll_boot(char * dst_name) +{ + struct cdap * ci; + cdap_key_t key; + uint8_t * data; + size_t len; + int fd; + + char * boot_ro = BOOT_PATH; + char * members_ro = MEMBERS_PATH; + char * dif_ro = DIF_PATH; + + fd = flow_alloc(dst_name, ENROLL_AE, NULL); + if (fd < 0) { + LOG_ERR("Failed to allocate flow."); + return -1; + } + + if (flow_alloc_res(fd)) { + LOG_ERR("Flow allocation failed."); + flow_dealloc(fd); + return -1; + } + + ci = cdap_create(fd); + if (ci == NULL) { + LOG_ERR("Failed to create CDAP instance."); + flow_dealloc(fd); + return -1; + } + + LOG_DBG("Getting boot information from %s.", dst_name); + + key = cdap_request_send(ci, CDAP_READ, boot_ro, NULL, 0, 0); + if (key < 0) { + LOG_ERR("Failed to send CDAP request."); + cdap_destroy(ci); + flow_dealloc(fd); + return -1; + } + + if (cdap_reply_wait(ci, key, &data, &len)) { + LOG_ERR("Failed to get CDAP reply."); + cdap_destroy(ci); + flow_dealloc(fd); + return -1; + } + + LOG_DBG("Packed information received (%lu bytes).", len); + + if (rib_unpack(data, len, UNPACK_CREATE)) { + LOG_WARN("Error unpacking RIB data."); + rib_del(boot_ro); + free(data); + cdap_destroy(ci); + flow_dealloc(fd); + return -1; + } + + LOG_DBG("Packed information inserted into RIB."); + + key = cdap_request_send(ci, CDAP_READ, members_ro, NULL, 0, 0); + if (key < 0) { + LOG_ERR("Failed to send CDAP request."); + cdap_destroy(ci); + flow_dealloc(fd); + return -1; + } + + if (cdap_reply_wait(ci, key, &data, &len)) { + LOG_ERR("Failed to get CDAP reply."); + cdap_destroy(ci); + flow_dealloc(fd); + return -1; + } + + LOG_DBG("Packed information received (%lu bytes).", len); + + if (rib_unpack(data, len, UNPACK_CREATE)) { + LOG_WARN("Error unpacking RIB data."); + rib_del(boot_ro); + free(data); + cdap_destroy(ci); + flow_dealloc(fd); + return -1; + } + + LOG_DBG("Packed information inserted into RIB."); + + key = cdap_request_send(ci, CDAP_READ, dif_ro, NULL, 0, 0); + if (key < 0) { + LOG_ERR("Failed to send CDAP request."); + cdap_destroy(ci); + flow_dealloc(fd); + return -1; + } + + if (cdap_reply_wait(ci, key, &data, &len)) { + LOG_ERR("Failed to get CDAP reply."); + cdap_destroy(ci); + flow_dealloc(fd); + return -1; + } + + LOG_DBG("Packed information received (%lu bytes).", len); + + if (rib_unpack(data, len, UNPACK_CREATE)) { + LOG_WARN("Error unpacking RIB data."); + rib_del(boot_ro); + free(data); + cdap_destroy(ci); + flow_dealloc(fd); + return -1; + } + + LOG_DBG("Packed information inserted into RIB."); + + cdap_destroy(ci); + + flow_dealloc(fd); + + return 0; +} |