diff options
Diffstat (limited to 'src/ipcpd')
| -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 <sander.vrijders@intec.ugent.be> - * - * 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 <sander.vrijders@intec.ugent.be> + * + * 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)) { | 
