diff options
author | Sander Vrijders <[email protected]> | 2016-11-29 11:48:17 +0100 |
---|---|---|
committer | Sander Vrijders <[email protected]> | 2016-11-29 13:54:21 +0100 |
commit | 60a6970f4d004a3bdaedc5af4e1581890ab9b462 (patch) | |
tree | 44149f4d89d02ebb246b4cb53414e848b320d031 | |
parent | ea71b87be592fec7eb8f5ae0707503c4f0fba8be (diff) | |
download | ouroboros-60a6970f4d004a3bdaedc5af4e1581890ab9b462.tar.gz ouroboros-60a6970f4d004a3bdaedc5af4e1581890ab9b462.zip |
ipcpd: normal: Complete flat address policy
This will add a check in the flat address policy to see if the address
is in use or not.
-rw-r--r-- | src/ipcpd/normal/CMakeLists.txt | 25 | ||||
-rw-r--r-- | src/ipcpd/normal/addr_auth.c | 2 | ||||
-rw-r--r-- | src/ipcpd/normal/flat.c | 63 | ||||
-rw-r--r-- | src/ipcpd/normal/pol/flat.c | 261 | ||||
-rw-r--r-- | src/ipcpd/normal/pol/flat.h (renamed from src/ipcpd/normal/flat.h) | 0 | ||||
-rw-r--r-- | src/ipcpd/normal/ribmgr.c | 2 |
6 files changed, 276 insertions, 77 deletions
diff --git a/src/ipcpd/normal/CMakeLists.txt b/src/ipcpd/normal/CMakeLists.txt index 06e41e9c..c4525b1a 100644 --- a/src/ipcpd/normal/CMakeLists.txt +++ b/src/ipcpd/normal/CMakeLists.txt @@ -23,17 +23,18 @@ protobuf_generate_c(FLOW_ALLOC_SRCS FLOW_ALLOC_HDRS protobuf_generate_c(RO_SRCS RO_HDRS ro.proto) set(SOURCE_FILES - # Add source files here - addr_auth.c - cdap_request.c - crc32.c - flat.c - fmgr.c - frct.c - main.c - ribmgr.c - shm_pci.c -) + # Add source files here + addr_auth.c + cdap_request.c + crc32.c + fmgr.c + frct.c + main.c + ribmgr.c + shm_pci.c + # Add policies last + pol/flat.c + ) add_executable (ipcpd-normal ${SOURCE_FILES} ${IPCP_SOURCES} ${STATIC_INFO_SRCS} ${FLOW_ALLOC_SRCS} ${RO_SRCS}) @@ -41,7 +42,7 @@ target_link_libraries (ipcpd-normal LINK_PUBLIC ouroboros) include(MacroAddCompileFlags) if (CMAKE_BUILD_TYPE MATCHES Debug) - macro_add_compile_flags(ipcpd-normal -DCONFIG_OUROBOROS_DEBUG) + macro_add_compile_flags(ipcpd-normal -DCONFIG_OUROBOROS_DEBUG) endif (CMAKE_BUILD_TYPE MATCHES Debug) install(TARGETS ipcpd-normal RUNTIME DESTINATION sbin) diff --git a/src/ipcpd/normal/addr_auth.c b/src/ipcpd/normal/addr_auth.c index 71bcfafa..95e4bef4 100644 --- a/src/ipcpd/normal/addr_auth.c +++ b/src/ipcpd/normal/addr_auth.c @@ -26,7 +26,7 @@ #include <ouroboros/logs.h> #include "addr_auth.h" -#include "flat.h" +#include "pol/flat.h" #include <stdlib.h> #include <assert.h> diff --git a/src/ipcpd/normal/flat.c b/src/ipcpd/normal/flat.c deleted file mode 100644 index 8caa85b4..00000000 --- a/src/ipcpd/normal/flat.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Ouroboros - Copyright (C) 2016 - * - * Policy for flat addresses in a distributed way - * - * Sander Vrijders <[email protected]> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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 "flat-addr-auth" - -#include <ouroboros/config.h> -#include <ouroboros/logs.h> - -#include <time.h> -#include <stdlib.h> -#include <math.h> - -#include "shm_pci.h" -#include "ribmgr.h" - -int flat_init(void) -{ - srand(time(NULL)); - - return 0; -} - -int flat_fini(void) -{ - return 0; -} - -uint64_t flat_address(void) -{ - uint64_t addr; - uint64_t max_addr; - struct dt_const * dtc; - - dtc = ribmgr_dt_const(); - if (dtc == NULL) - return INVALID_ADDR; - - max_addr = (1 << (8 * dtc->addr_size)) - 1; - addr = (rand() % (max_addr - 1)) + 1; - - /* FIXME: Add check for uniqueness of address */ - - return addr; -} diff --git a/src/ipcpd/normal/pol/flat.c b/src/ipcpd/normal/pol/flat.c new file mode 100644 index 00000000..4946d538 --- /dev/null +++ b/src/ipcpd/normal/pol/flat.c @@ -0,0 +1,261 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * Policy for flat addresses in a distributed way + * + * Sander Vrijders <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 "flat-addr-auth" + +#include <ouroboros/config.h> +#include <ouroboros/logs.h> +#include <ouroboros/errno.h> +#include <ouroboros/time_utils.h> + +#include <time.h> +#include <stdlib.h> +#include <math.h> +#include <string.h> +#include <assert.h> + +#include "shm_pci.h" +#include "ribmgr.h" +#include "ro.h" + +#define POL_RO_ROOT "/flat_addr" + +#define TIMEOUT 100 /* ms */ +#define STR_SIZE 100 + +#define FLAT_ADDR_REQ 0 +#define FLAT_ADDR_REPLY 1 + +struct flat_addr_msg { + uint8_t code; + uint64_t addr; +}; + +struct { + int sid; + uint64_t addr; + bool addr_in_use; + + pthread_cond_t cond; + pthread_mutex_t lock; +} flat; + +static char * my_name(void) +{ + char * name; + char addr_name[100]; + + name = malloc(STR_SIZE); + if (name == NULL) + return NULL; + + sprintf(addr_name, "%lu", (unsigned long) flat.addr); + strcpy(name, POL_RO_ROOT); + strcat(name, "/"); + strcat(name, addr_name); + + return name; +} + +/* FIXME: We should return void */ +static int ro_created(const char * name, + uint8_t * data, + size_t len) +{ + struct flat_addr_msg * msg; + + assert(name); + assert(data); + assert(len >= sizeof(*msg)); + + msg = (struct flat_addr_msg *) data; + if (msg->code == FLAT_ADDR_REQ && + msg->addr == flat.addr) { + msg->code = FLAT_ADDR_REPLY; + ro_write(name, data, len); + } + + return 0; +} + +static int ro_updated(const char * name, + uint8_t * data, + size_t len) +{ + struct flat_addr_msg * msg; + char * ro_name; + + assert(name); + assert(data); + assert(len >= sizeof(*msg)); + + ro_name = my_name(); + if (ro_name == NULL) + return -1; + + msg = (struct flat_addr_msg *) data; + if (msg->code == FLAT_ADDR_REPLY && + strcmp(name, ro_name) == 0) { + pthread_mutex_lock(&flat.lock); + flat.addr_in_use = true; + pthread_cond_broadcast(&flat.cond); + pthread_mutex_unlock(&flat.lock); + } + + free(data); + free(ro_name); + + return 0; +} + +static struct ro_sub_ops flat_sub_ops = { + .ro_created = ro_created, + .ro_updated = ro_updated, + .ro_deleted = NULL +}; + +int flat_init(void) +{ + struct ro_props * props; + pthread_condattr_t cattr; + + srand(time(NULL)); + flat.addr_in_use = false; + + props = malloc(sizeof(*props)); + if (props == NULL) + return -ENOMEM; + + pthread_mutex_init(&flat.lock, NULL); + pthread_condattr_init(&cattr); +#ifndef __APPLE__ + pthread_condattr_setclock(&cattr, PTHREAD_COND_CLOCK); +#endif + pthread_cond_init(&flat.cond, &cattr); + + flat.sid = ro_subscribe(POL_RO_ROOT, + &flat_sub_ops); + if (flat.sid < 0) { + LOG_ERR("Could not subscribe to RIB."); + pthread_cond_destroy(&flat.cond); + pthread_mutex_destroy(&flat.lock); + free(props); + return -1; + } + + props->enrol_sync = false; + props->recv_set = NO_SYNC; + props->expiry.tv_sec = 0; + props->expiry.tv_nsec = 0; + + if (ro_create(POL_RO_ROOT, props, NULL, 0)) { + LOG_ERR("Could not create RO."); + pthread_cond_destroy(&flat.cond); + pthread_mutex_destroy(&flat.lock); + free(props); + ro_unsubscribe(flat.sid); + return -1; + } + + return 0; +} + +int flat_fini(void) +{ + pthread_cond_destroy(&flat.cond); + pthread_mutex_destroy(&flat.lock); + ro_unsubscribe(flat.sid); + return 0; +} + +uint64_t flat_address(void) +{ + int ret = 0; + uint64_t max_addr; + struct dt_const * dtc; + struct timespec timeout = {(TIMEOUT / 1000), + (TIMEOUT % 1000) * MILLION}; + struct timespec abstime; + struct ro_props * props; + struct flat_addr_msg * msg; + uint8_t * buf; + char * ro_name; + + dtc = ribmgr_dt_const(); + if (dtc == NULL) + return INVALID_ADDR; + + while (ret != -ETIMEDOUT) { + clock_gettime(PTHREAD_COND_CLOCK, &abstime); + ts_add(&abstime, &timeout, &abstime); + + max_addr = (1 << (8 * dtc->addr_size)) - 1; + flat.addr = (rand() % (max_addr - 1)) + 1; + + /* FIXME: We must change this to stack memory */ + props = malloc(sizeof(*props)); + if (props == NULL) + return INVALID_ADDR; + + props->enrol_sync = false; + props->recv_set = ALL_MEMBERS; + props->expiry.tv_sec = TIMEOUT / 1000; + props->expiry.tv_nsec = (TIMEOUT % 1000) * MILLION; + + buf = malloc(sizeof(*msg)); + if (buf == NULL) { + free(props); + return INVALID_ADDR; + } + + msg = (struct flat_addr_msg *) buf; + msg->code = FLAT_ADDR_REQ; + msg->addr = flat.addr; + + /* FIXME: We may require functions to construct pathnames */ + ro_name = my_name(); + if (ro_name == NULL) { + free(props); + return INVALID_ADDR; + } + + pthread_mutex_lock(&flat.lock); + if (ro_create(ro_name, props, buf, sizeof(*msg))) { + pthread_mutex_unlock(&flat.lock); + free(props); + free(ro_name); + return INVALID_ADDR; + } + free(ro_name); + + while (flat.addr_in_use == false) { + ret = -pthread_cond_timedwait(&flat.cond, + &flat.lock, + &abstime); + if (ret == -ETIMEDOUT) + break; + } + pthread_mutex_unlock(&flat.lock); + } + + return flat.addr; +} diff --git a/src/ipcpd/normal/flat.h b/src/ipcpd/normal/pol/flat.h index 51cb511b..51cb511b 100644 --- a/src/ipcpd/normal/flat.h +++ b/src/ipcpd/normal/pol/flat.h diff --git a/src/ipcpd/normal/ribmgr.c b/src/ipcpd/normal/ribmgr.c index 524c5a39..79422909 100644 --- a/src/ipcpd/normal/ribmgr.c +++ b/src/ipcpd/normal/ribmgr.c @@ -414,7 +414,7 @@ static struct rnode * ribmgr_ro_create(const char * name, if (!(props->expiry.tv_sec == 0 && props->expiry.tv_nsec == 0)) { timeout = props->expiry.tv_sec * 1000 + - props->expiry.tv_nsec * MILLION; + props->expiry.tv_nsec / MILLION; if (timerwheel_add(rib.wheel, ro_delete_timer, new->full_name, strlen(new->full_name), timeout)) { |