diff options
Diffstat (limited to 'src/ipcpd')
| -rw-r--r-- | src/ipcpd/CMakeLists.txt | 29 | ||||
| -rw-r--r-- | src/ipcpd/flow.c | 87 | ||||
| -rw-r--r-- | src/ipcpd/flow.h | 63 | ||||
| -rw-r--r-- | src/ipcpd/ipcp-data.c | 499 | ||||
| -rw-r--r-- | src/ipcpd/ipcp-data.h | 90 | ||||
| -rw-r--r-- | src/ipcpd/ipcp-ops.h | 59 | ||||
| -rw-r--r-- | src/ipcpd/ipcp.c | 236 | ||||
| -rw-r--r-- | src/ipcpd/ipcp.h | 49 | ||||
| -rw-r--r-- | src/ipcpd/normal/CMakeLists.txt | 32 | ||||
| -rw-r--r-- | src/ipcpd/normal/dt_const.h (renamed from src/ipcpd/dt_const.h) | 0 | ||||
| -rw-r--r-- | src/ipcpd/normal/main.c (renamed from src/ipcpd/main.c) | 0 | ||||
| -rw-r--r-- | src/ipcpd/normal/pci.c (renamed from src/ipcpd/pci.c) | 2 | ||||
| -rw-r--r-- | src/ipcpd/normal/pci.h (renamed from src/ipcpd/pci.h) | 0 | ||||
| -rw-r--r-- | src/ipcpd/normal/shm_pci.c (renamed from src/ipcpd/shm_pci.c) | 2 | ||||
| -rw-r--r-- | src/ipcpd/normal/shm_pci.h (renamed from src/ipcpd/shm_pci.h) | 0 | ||||
| -rw-r--r-- | src/ipcpd/shim-udp/CMakeLists.txt | 31 | ||||
| -rw-r--r-- | src/ipcpd/shim-udp/main.c | 324 | ||||
| -rw-r--r-- | src/ipcpd/shim-udp/tests/CMakeLists.txt | 33 | ||||
| -rw-r--r-- | src/ipcpd/shim-udp/tests/shim_udp_test.c | 103 | 
19 files changed, 1614 insertions, 25 deletions
diff --git a/src/ipcpd/CMakeLists.txt b/src/ipcpd/CMakeLists.txt index bcb5b986..5a924ffe 100644 --- a/src/ipcpd/CMakeLists.txt +++ b/src/ipcpd/CMakeLists.txt @@ -1,26 +1,9 @@ -include_directories(${CMAKE_CURRENT_SOURCE_DIR}) -include_directories(${CMAKE_CURRENT_BINARY_DIR}) - -include_directories(${CMAKE_SOURCE_DIR}/include) -include_directories(${CMAKE_BINARY_DIR}/include) - -set(SOURCE_FILES +set(IPCP_SOURCES          # Add source files here -        main.c -        pci.c -        shm_pci.c +        ${CMAKE_CURRENT_SOURCE_DIR}/flow.c +        ${CMAKE_CURRENT_SOURCE_DIR}/ipcp.c +        ${CMAKE_CURRENT_SOURCE_DIR}/ipcp-data.c  ) -add_executable (ipcpd ${SOURCE_FILES}) - -target_link_libraries (ipcpd LINK_PUBLIC ouroboros) - -include(MacroAddCompileFlags) -if (CMAKE_BUILD_TYPE MATCHES Debug) -   MACRO_ADD_COMPILE_FLAGS(ipcpd -DCONFIG_OUROBOROS_DEBUG) -endif (CMAKE_BUILD_TYPE MATCHES Debug) - -install(TARGETS ipcpd RUNTIME DESTINATION bin) - -# Enable once ipcpd has tests -# add_subdirectory(tests) +add_subdirectory(normal) +add_subdirectory(shim-udp) diff --git a/src/ipcpd/flow.c b/src/ipcpd/flow.c new file mode 100644 index 00000000..c436733b --- /dev/null +++ b/src/ipcpd/flow.c @@ -0,0 +1,87 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * Flows + * + *    Dimitri Staessens <dimitri.staessens@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. + */ + +#include <stdlib.h> +#include "flow.h" + +#define OUROBOROS_PREFIX "ipcpd/flow" + +#include <ouroboros/logs.h> + +flow_t * flow_create(int32_t port_id) +{ +        flow_t * flow = malloc(sizeof *flow); +        if (flow == NULL) { +                LOG_DBGF("Could not malloc flow."); +                return NULL; +        } + +        INIT_LIST_HEAD(&flow->list); + +        flow->port_id = port_id; +        flow->oflags = FLOW_O_DEFAULT; +        flow->state = FLOW_NULL; + +        pthread_mutex_init(&flow->lock, NULL); + +        return flow; +} + +void flow_destroy(flow_t * flow) +{ +        if (flow == NULL) +                return; +        free(flow); +} + +int flow_set_opts(flow_t * flow, uint16_t opts) +{ +        if (flow == NULL) { +                LOG_DBGF("Non-existing flow."); +                return -1; +        } + +        pthread_mutex_lock(&flow->lock); + +        if ((opts & FLOW_O_ACCMODE) == FLOW_O_ACCMODE) { +                flow->oflags = FLOW_O_DEFAULT; +                pthread_mutex_unlock(&flow->lock); +                LOG_WARN("Invalid flow options. Setting default."); +                return -1; +        } + +        flow->oflags = opts; + +        pthread_mutex_unlock(&flow->lock); + +        return 0; +} + +uint16_t flow_get_opts(const flow_t * flow) +{ +        if (flow == NULL) { +                LOG_DBGF("Non-existing flow."); +                return FLOW_O_INVALID; +        } + +        return flow->oflags; +} diff --git a/src/ipcpd/flow.h b/src/ipcpd/flow.h new file mode 100644 index 00000000..000de5ad --- /dev/null +++ b/src/ipcpd/flow.h @@ -0,0 +1,63 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * Flows + * + *    Dimitri Staessens <dimitri.staessens@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. + */ + +#ifndef OUROBOROS_FLOW_H +#define OUROBOROS_FLOW_H + +#include <ouroboros/common.h> +#include <ouroboros/list.h> +#include <pthread.h> + +/* same values as fcntl.h */ +#define FLOW_O_RDONLY   00000000 +#define FLOW_O_WRONLY   00000001 +#define FLOW_O_RDWR     00000002 +#define FLOW_O_ACCMODE  00000003 + +#define FLOW_O_NONBLOCK 00004000 +#define FLOW_O_DEFAULT  00000002 + +#define FLOW_O_INVALID  (FLOW_O_WRONLY | FLOW_O_RDWR) + +enum flow_state { +        FLOW_NULL = 0, +        FLOW_ALLOCATED, +        FLOW_PENDING +}; + +typedef struct flow { +        struct list_head list; + +        int32_t          port_id; +        uint16_t         oflags; +        enum flow_state  state; + +        pthread_mutex_t  lock; +} flow_t; + +flow_t * flow_create(int32_t   port_id); +void     flow_destroy(flow_t * flow); + +int      flow_set_opts(flow_t * flow, uint16_t opts); +uint16_t flow_get_opts(const flow_t * flow); + +#endif /* OUROBOROS_FLOW_H */ diff --git a/src/ipcpd/ipcp-data.c b/src/ipcpd/ipcp-data.c new file mode 100644 index 00000000..1828fda9 --- /dev/null +++ b/src/ipcpd/ipcp-data.c @@ -0,0 +1,499 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * IPC process utilities + * + *    Dimitri Staessens <dimitri.staessens@intec.ugent.be> + *    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. + */ + +#include "ipcp-data.h" +#include <ouroboros/shm_du_map.h> +#include <ouroboros/list.h> +#include <ouroboros/utils.h> + +#define OUROBOROS_PREFIX "ipcp-utils" + +#include <ouroboros/logs.h> + +#include <string.h> +#include <stdlib.h> + +struct reg_entry { +        struct list_head list; +        char *           ap_name; +        uint32_t         reg_ap_id; +}; + +struct dir_entry { +        struct list_head list; +        char *     ap_name; +        uint64_t   addr; +}; + +static struct reg_entry * reg_entry_create(const char * ap_name, +                                           uint32_t     reg_ap_id) +{ +        struct reg_entry * entry = malloc(sizeof *entry); +        if (entry == NULL) +                return NULL; + +        entry->reg_ap_id = reg_ap_id; +        entry->ap_name = strdup(ap_name); +        if (entry->ap_name == NULL) +                return NULL; + +        return entry; +} + +static void reg_entry_destroy(struct reg_entry * entry) +{ +        if (entry == NULL) +                return; + +        free(entry->ap_name); +        free(entry); +} + +static struct dir_entry * dir_entry_create(const char * ap_name, +                                           uint64_t     addr) +{ +        struct dir_entry * entry = malloc(sizeof *entry); +        if (entry == NULL) +                return NULL; + +        entry->addr    = addr; +        entry->ap_name = strdup(ap_name); +        if (entry->ap_name == NULL) +                return NULL; + +        return entry; +} + +static void dir_entry_destroy(struct dir_entry * entry) +{ +        if (entry == NULL) +                return; + +        free(entry->ap_name); +        free(entry); +} + +struct ipcp_data * ipcp_data_create() +{ +        struct ipcp_data * data = malloc(sizeof *data); +        if (data == NULL) +                return NULL; + +        data->iname = NULL; +        data->type  = 0; +        data->dum   = NULL; + +        return data; +} + +struct ipcp_data * ipcp_data_init(struct ipcp_data * dst, +                                  instance_name_t * iname, +                                  enum ipcp_type    ipcp_type) +{ +        if (dst == NULL) +                return NULL; + +        dst->iname = instance_name_dup(iname); +        dst->type  = ipcp_type; + +        dst->dum = shm_du_map_open(); +        if (dst->dum == NULL) +                return NULL; + +        /* init the lists */ +        INIT_LIST_HEAD(&dst->registry); +        INIT_LIST_HEAD(&dst->flows); +        INIT_LIST_HEAD(&dst->directory); + +        /* init the mutexes */ +        pthread_mutex_init(&dst->reg_lock, NULL); +        pthread_mutex_init(&dst->dir_lock, NULL); +        pthread_mutex_init(&dst->flow_lock, NULL); + +        return dst; +} + +static void clear_registry(struct ipcp_data * data) +{ +        struct list_head * h; +        struct list_head * t; +        list_for_each_safe(h, t, &data->registry) +                reg_entry_destroy(list_entry(h, struct reg_entry, list)); +} + +static void clear_directory(struct ipcp_data * data) +{ +        struct list_head * h; +        struct list_head * t; +        list_for_each_safe(h, t, &data->directory) +                dir_entry_destroy(list_entry(h, struct dir_entry, list)); +} + +static void clear_flows(struct ipcp_data * data) +{ +        struct list_head * h; +        struct list_head * t; +        list_for_each_safe(h, t, &data->flows) +                flow_destroy(list_entry(h, flow_t, list)); + +} + +void ipcp_data_destroy(struct ipcp_data * data) +{ +        if (data == NULL) +                return; + +        /* FIXME: finish all pending operations here */ + +        if (data->iname != NULL) +                instance_name_destroy(data->iname); +        data->iname = NULL; + +        if (data->dum != NULL) +                shm_du_map_close(data->dum); +        data->dum = NULL; + +        pthread_mutex_lock(&data->reg_lock); +        pthread_mutex_lock(&data->dir_lock); +        pthread_mutex_lock(&data->flow_lock); + +        /* clear the lists */ +        clear_registry(data); +        clear_directory(data); +        clear_flows(data); + +        /* no need to unlock, just free the entire thing +        pthread_mutex_unlock(&data->flow_lock); +        pthread_mutex_unlock(&data->dir_lock); +        pthread_mutex_unlock(&data->reg_lock); +        */ + +        free(data); +} + + + +static struct reg_entry * find_reg_entry_by_name(struct ipcp_data * data, +                                                 const char *       ap_name) +{ +        struct list_head * h; +        list_for_each(h, &data->registry) { +                struct reg_entry * e = list_entry(h, struct reg_entry, list); +                if (!strcmp(e->ap_name, ap_name)) +                        return e; +        } + +        return NULL; +} + +static struct reg_entry * find_reg_entry_by_id(struct ipcp_data * data, +                                               uint32_t           reg_ap_id) +{ +        struct list_head * h; +        list_for_each(h, &data->registry) { +                struct reg_entry * e = list_entry(h, struct reg_entry, list); +                if (e->reg_ap_id == reg_ap_id) +                        return e; +        } + +        return NULL; +} + +static struct dir_entry * find_dir_entry(struct ipcp_data * data, +                                         const char *       ap_name, +                                         uint64_t           addr) +{ +        struct list_head * h; +        list_for_each(h, &data->directory) { +                struct dir_entry * e = list_entry(h, struct dir_entry, list); +                if (e->addr == addr && !strcmp(e->ap_name, ap_name)) +                        return e; +        } + +        return NULL; +} + +static struct dir_entry * find_dir_entry_any(struct ipcp_data * data, +                                             const char *       ap_name) +{ +        struct list_head * h; +        list_for_each(h, &data->directory) { +                struct dir_entry * e = list_entry(h, struct dir_entry, list); +                if (!strcmp(e->ap_name, ap_name)) +                        return e; +        } + +        return NULL; +} + +bool ipcp_data_is_in_directory(struct ipcp_data * data, +                               const char *       ap_name) +{ +        return find_dir_entry_any(data, ap_name) != NULL; +} + +int ipcp_data_del_reg_entry(struct ipcp_data * data, +                            uint32_t           reg_ap_id) +{ +        struct reg_entry * e; +        if (data == NULL) +                return -1; + +        pthread_mutex_lock(&data->reg_lock); + +        e = find_reg_entry_by_id(data, reg_ap_id); +        if (e == NULL) { +                pthread_mutex_unlock(&data->reg_lock); +                return 0; /* nothing to do */ +        } + +        list_del(&e->list); + +        reg_entry_destroy(e); + +        pthread_mutex_unlock(&data->reg_lock); + +        return 0; +} + +int ipcp_data_del_dir_entry(struct ipcp_data * data, +                            const char *       ap_name, +                            uint64_t           addr) +{ +        struct dir_entry * e; +        if (data == NULL) +                return -1; + +        pthread_mutex_lock(&data->dir_lock); + +        e = find_dir_entry(data, ap_name, addr); +        if (e == NULL) { +                pthread_mutex_unlock(&data->dir_lock); +                return 0; /* nothing to do */ +        } + +        list_del(&e->list); + +        dir_entry_destroy(e); + +        pthread_mutex_unlock(&data->dir_lock); + +        return 0; +} + +int ipcp_data_add_reg_entry(struct ipcp_data * data, +                            char *             ap_name, +                            uint32_t           reg_ap_id) +{ +        struct reg_entry * entry; + +        if (data == NULL || ap_name == NULL) +                return -1; + +        pthread_mutex_lock(&data->reg_lock); + +        if (find_reg_entry_by_name(data, ap_name) || +            find_reg_entry_by_id(data, reg_ap_id)) { +                pthread_mutex_unlock(&data->reg_lock); +                return -2; +        } + +        entry = reg_entry_create(ap_name, reg_ap_id); +        if (entry == NULL) { +                pthread_mutex_unlock(&data->reg_lock); +                return -1; +        } + +        list_add(&entry->list,&data->registry); + +        pthread_mutex_unlock(&data->reg_lock); + +        return 0; +} + +int ipcp_data_add_dir_entry(struct ipcp_data * data, +                            char *             ap_name, +                            uint64_t           addr) +{ +        struct dir_entry * entry; + +        if (data == NULL || ap_name == NULL) +                return -1; + +        pthread_mutex_lock(&data->dir_lock); + +        if (find_dir_entry(data, ap_name, addr) != NULL) { +                pthread_mutex_unlock(&data->dir_lock); +                return -2; +        } + +        entry = dir_entry_create(ap_name, addr); +        if (entry == NULL) { +                pthread_mutex_unlock(&data->dir_lock); +                return -1; +        } + +        list_add(&entry->list,&data->directory); + +        pthread_mutex_unlock(&data->dir_lock); + +        return 0; +} + +bool ipcp_data_is_in_registry(struct ipcp_data * data, +                              const char *       ap_name) +{ +        return find_reg_entry_by_name(data, ap_name) != NULL; +} + +uint32_t ipcp_data_get_reg_ap_id(struct ipcp_data * data, +                                 const char *       ap_name) +{ +        struct reg_entry * entry; +        uint32_t id; + +        pthread_mutex_lock(&data->reg_lock); + +        entry = find_reg_entry_by_name(data, ap_name); + +        if (entry == NULL) { +                pthread_mutex_unlock(&data->reg_lock); +                return 0; /* undefined behaviour */ +        } + +        id = entry->reg_ap_id; + +        pthread_mutex_unlock(&data->reg_lock); + +        return id; +} + +const char * ipcp_data_get_reg_ap_name(struct ipcp_data * data, +                                   uint32_t           reg_ap_id) +{ +        struct reg_entry * entry; +        char * name; + +        pthread_mutex_lock(&data->reg_lock); + +        entry = find_reg_entry_by_id(data, reg_ap_id); + +        if (entry == NULL) { +                pthread_mutex_unlock(&data->reg_lock); +                return NULL; +        } + +        name = strdup(entry->ap_name); +        if (name == NULL) { +                pthread_mutex_unlock(&data->reg_lock); +                return NULL; +        } + +        pthread_mutex_unlock(&data->reg_lock); + +        return name; +} + +uint64_t ipcp_data_get_addr(struct ipcp_data * data, +                            const char *       ap_name) +{ +        struct dir_entry * entry; +        uint64_t           addr; + +        pthread_mutex_lock(&data->dir_lock); + +        entry = find_dir_entry_any(data, ap_name); + +        if (entry == NULL) { +                pthread_mutex_unlock(&data->dir_lock); +                return 0; /* undefined behaviour, 0 may be a valid address */ +        } + +        addr = entry->addr; + +        pthread_mutex_unlock(&data->dir_lock); + +        return addr; +} + +flow_t * ipcp_data_find_flow(struct ipcp_data * data, +                             uint32_t           port_id) +{ +        struct list_head * h; +        list_for_each(h, &data->flows) { +                flow_t * f = list_entry(h, flow_t, list); +                if (f->port_id == port_id) +                        return f; +        } + +        return NULL; +} + +bool ipcp_data_has_flow(struct ipcp_data * data, +                        uint32_t           port_id) +{ +        return ipcp_data_find_flow(data, port_id) != NULL; +} + +int ipcp_data_add_flow(struct ipcp_data * data, +                       flow_t *           flow) +{ +        if (data == NULL || flow == NULL) +                return -1; + +        pthread_mutex_lock(&data->flow_lock); + +        if (ipcp_data_has_flow(data, flow->port_id)) { +                pthread_mutex_unlock(&data->flow_lock); +                return -2; +        } + +        list_add(&flow->list,&data->flows); + +        pthread_mutex_unlock(&data->flow_lock); + +        return 0; +} + +int ipcp_data_del_flow(struct ipcp_data * data, +                       uint32_t           port_id) +{ +        flow_t * f; + +        if (data == NULL) +                return -1; + +        pthread_mutex_lock(&data->flow_lock); + +        f = ipcp_data_find_flow(data, port_id); +        if (f == NULL) +                return -1; + +        list_del(&f->list); + +        free(f); + +        pthread_mutex_unlock(&data->flow_lock); + +        return 0; +} diff --git a/src/ipcpd/ipcp-data.h b/src/ipcpd/ipcp-data.h new file mode 100644 index 00000000..3f036ef5 --- /dev/null +++ b/src/ipcpd/ipcp-data.h @@ -0,0 +1,90 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * Utitilies for building IPC processes + * + *    Dimitri Staessens <dimitri.staessens@intec.ugent.be> + *    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. + */ + +#ifndef IPCPD_IPCP_DATA_H +#define IPCPD_IPCP_DATA_H + +#include <ouroboros/common.h> +#include <ouroboros/instance_name.h> +#include <ouroboros/list.h> +#include <sys/types.h> +#include <pthread.h> + +#include "ipcp-ops.h" +#include "flow.h" + +struct ipcp_data { +        instance_name_t   * iname; +        enum ipcp_type      type; + +        struct shm_du_map * dum; + +        struct list_head    registry; +        pthread_mutex_t     reg_lock; + +        struct list_head    flows; +        pthread_mutex_t     flow_lock; + +        struct list_head    directory; +        pthread_mutex_t     dir_lock; + +        pthread_mutex_t     lock; +}; + +struct ipcp_data * ipcp_data_create(); +struct ipcp_data * ipcp_data_init(struct ipcp_data * dst, +                                  instance_name_t *  iname, +                                  enum ipcp_type     ipcp_type); +void               ipcp_data_destroy(struct ipcp_data * data); + +int          ipcp_data_add_reg_entry(struct ipcp_data * data, +                                     char *             ap_name, +                                     uint32_t           reg_ap_id); +int          ipcp_data_del_reg_entry(struct ipcp_data * data, +                                     uint32_t           reg_ap_id); +int          ipcp_data_add_dir_entry(struct ipcp_data * data, +                                     char *             ap_name, +                                     uint64_t           addr); +int          ipcp_data_del_dir_entry(struct ipcp_data * data, +                                     const char *       ap_name, +                                     uint64_t           addr); +bool         ipcp_data_is_in_registry(struct ipcp_data * data, +                                      const char *       ap_name); +uint32_t     ipcp_data_get_reg_ap_id(struct ipcp_data * data, +                                     const char *       ap_name); +const char * ipcp_data_get_reg_ap_name(struct ipcp_data * data, +                                       uint32_t           reg_ap_id); +bool         ipcp_data_is_in_directory(struct ipcp_data * data, +                                       const char *       ap_name); +uint64_t     ipcp_data_get_addr(struct ipcp_data * data, +                                const char *       ap_name); +bool         ipcp_data_has_flow(struct ipcp_data * data, +                                uint32_t           port_id); +flow_t *     ipcp_data_find_flow(struct ipcp_data * data, +                                 uint32_t           port_id); +int          ipcp_data_add_flow(struct ipcp_data * data, +                                flow_t *           flow); +int          ipcp_data_del_flow(struct ipcp_data * data, +                                uint32_t           port_id); + +#endif /* IPCPD_IPCP_DATA_H */ diff --git a/src/ipcpd/ipcp-ops.h b/src/ipcpd/ipcp-ops.h new file mode 100644 index 00000000..5c917229 --- /dev/null +++ b/src/ipcpd/ipcp-ops.h @@ -0,0 +1,59 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * IPC process ops + * + *    Dimitri Staessens <dimitri.staessens@intec.ugent.be> + *    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. + */ + +#ifndef IPCPD_IPCP_OPS_H +#define IPCPD_IPCP_OPS_H + +#include <ouroboros/common.h> +#include <ouroboros/dif_config.h> +#include <sys/types.h> + +struct ipcp_ops { +        int   (* ipcp_bootstrap)(struct dif_config * conf); +        int   (* ipcp_enroll)(char * member_name, +                              char * n_1_dif); +        int   (* ipcp_reg)(char ** dif_names, +                           size_t len); +        int   (* ipcp_unreg)(char ** dif_names, +                             size_t len); +        int   (* ipcp_ap_reg)(char *   ap_name, +                              uint32_t reg_ap_id); +        int   (* ipcp_ap_unreg)(uint32_t reg_ap_id); +        int   (* ipcp_flow_alloc)(uint32_t port_id, +                                  char *   dst_ap_name, +                                  char *   src_ap_name, +                                  char *   src_ae_name, +                                  struct qos_spec * qos); +        int   (* ipcp_flow_alloc_resp)(uint32_t port_id, +                                       int      response); +        int   (* ipcp_flow_dealloc)(uint32_t port_id); + +        /* FIXME: let's see how this will work with the shm_du_map */ +        int   (* ipcp_du_write)(uint32_t port_id, +                                size_t map_index); + +        int   (* ipcp_du_read)(uint32_t port_id, +                               size_t map_index); +}; + +#endif /* IPCPD_IPCP_OPS_H */ diff --git a/src/ipcpd/ipcp.c b/src/ipcpd/ipcp.c new file mode 100644 index 00000000..0b652ff6 --- /dev/null +++ b/src/ipcpd/ipcp.c @@ -0,0 +1,236 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * IPC process main loop + * + *    Dimitri Staessens <dimitri.staessens@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. + */ + +#include <ouroboros/config.h> +#include <ouroboros/ipcp.h> +#include <sys/socket.h> +#include <stdlib.h> +#include "ipcp.h" + +#define OUROBOROS_PREFIX "ipcpd/ipcp" +#include <ouroboros/logs.h> + +int ipcp_arg_check(int argc, char * argv[]) +{ +        if (argc != 4) +                return -1; + +        /* argument 1: pid of irmd */ +        if (atoi(argv[1]) == 0) +                return -1; + +        /* name conformity responsibility of NMS */ + +        /* argument 2: ap name */ +        /* argument 3: instance id */ + +        return 0; +} + +int ipcp_main_loop(struct ipcp * _ipcp) +{ +        int     lsockfd; +        int     sockfd; +        uint8_t buf[IPCP_MSG_BUF_SIZE]; + +        ipcp_msg_t *    msg; +        ssize_t         count; +        buffer_t        buffer; +        ipcp_msg_t      ret_msg = IPCP_MSG__INIT; + +        dif_config_msg_t * conf_msg; +        struct dif_config  conf; + +        if (_ipcp == NULL) { +                LOG_ERR("Invalid ipcp struct."); +                return 1; +        } + +        sockfd = server_socket_open(ipcp_sock_path(getpid())); +        if (sockfd < 0) { +                LOG_ERR("Could not open server socket."); +                return 1; +        } + +        while (true) { +                ret_msg.code = IPCP_MSG_CODE__IPCP_REPLY; + +                lsockfd = accept(sockfd, 0, 0); +                if (lsockfd < 0) { +                        LOG_ERR("Cannot accept new connection"); +                        break; +                } + +                count = read(lsockfd, buf, IPCP_MSG_BUF_SIZE); +                if (count <= 0) { +                        LOG_ERR("Failed to read from socket"); +                        close(lsockfd); +                        continue; +                } + +                msg = ipcp_msg__unpack(NULL, count, buf); +                if (msg == NULL) { +                        close(lsockfd); +                        continue; +                } + +                switch (msg->code) { +                case IPCP_MSG_CODE__IPCP_BOOTSTRAP: +                        if (_ipcp->ops->ipcp_bootstrap == NULL) { +                                LOG_ERR("Bootstrap unsupported."); +                                break; +                        } +                        conf_msg = msg->conf; +                        conf.type = conf_msg->ipcp_type; +                        if (conf_msg->ipcp_type == IPCP_NORMAL) { +                                conf.addr_size = conf_msg->addr_size; +                                conf.cep_id_size = conf_msg->cep_id_size; +                                conf.pdu_length_size +                                        = conf_msg->pdu_length_size; +                                conf.qos_id_size     = conf_msg->qos_id_size; +                                conf.seqno_size      = conf_msg->seqno_size; +                                conf.ttl_size        = conf_msg->seqno_size; +                                conf.chk_size        = conf_msg->chk_size; +                                conf.min_pdu_size    = conf_msg->min_pdu_size; +                                conf.max_pdu_size    = conf_msg->max_pdu_size; +                        } +                        if (conf_msg->ipcp_type == IPCP_SHIM_UDP) { +                                conf.ip_addr = conf_msg->ip_addr; +                                conf.dns_addr = conf_msg->dns_addr; +                        } + +                        ret_msg.has_result = true; +                        ret_msg.result = _ipcp->ops->ipcp_bootstrap(&conf); +                        break; +                case IPCP_MSG_CODE__IPCP_ENROLL: +                        if (_ipcp->ops->ipcp_enroll == NULL) { +                                LOG_ERR("Enroll unsupported."); +                                break; +                        } +                        ret_msg.has_result = true; +                        ret_msg.result = _ipcp->ops->ipcp_enroll( +                                msg->member_name, msg->n_1_dif); + +                        break; + +                case IPCP_MSG_CODE__IPCP_REG: +                        if (_ipcp->ops->ipcp_reg == NULL) { +                                LOG_ERR("Reg unsupported."); +                                break; + +                        } +                        ret_msg.has_result = true; +                        ret_msg.result = _ipcp->ops->ipcp_reg( +                                msg->dif_names, msg->len); +                        break; +                case IPCP_MSG_CODE__IPCP_UNREG: +                        if (_ipcp->ops->ipcp_unreg == NULL) { +                                LOG_ERR("Unreg unsupported."); +                                break; +                        } +                        ret_msg.has_result = true; +                        ret_msg.result = _ipcp->ops->ipcp_unreg( +                                msg->dif_names, msg->len); +                        break; +                case IPCP_MSG_CODE__IPCP_AP_REG: +                        if (_ipcp->ops->ipcp_ap_reg == NULL) { +                                LOG_ERR("Ap_reg unsupported."); +                                break; +                        } +                        ret_msg.has_result = true; +                        ret_msg.result = _ipcp->ops->ipcp_ap_reg( +                                msg->ap_name, msg->reg_ap_id); +                        break; +                case IPCP_MSG_CODE__IPCP_AP_UNREG: +                        if (_ipcp->ops->ipcp_ap_unreg == NULL) { +                                LOG_ERR("Ap_unreg unsupported."); +                                break; +                        } +                        ret_msg.has_result = true; +                        ret_msg.result = _ipcp->ops->ipcp_ap_unreg( +                                msg->reg_ap_id); +                        break; +                case IPCP_MSG_CODE__IPCP_FLOW_ALLOC: +                        if (_ipcp->ops->ipcp_flow_alloc == NULL) { +                                LOG_ERR("Flow_alloc unsupported."); +                                break; +                        } +                        ret_msg.has_result = true; +                        ret_msg.result = _ipcp->ops->ipcp_flow_alloc( +                                msg->port_id, +                                msg->dst_ap_name, +                                msg->ap_name, +                                msg->ae_name, +                                NULL); +                        break; +                case IPCP_MSG_CODE__IPCP_FLOW_ALLOC_RESP: +                        if (_ipcp->ops->ipcp_flow_alloc_resp == NULL) { +                                LOG_ERR("Flow_alloc_resp unsupported."); +                                break; +                        } +                        ret_msg.has_result = true; +                        ret_msg.result = _ipcp->ops->ipcp_flow_alloc_resp( +                                msg->port_id, msg->result); +                        break; +                case IPCP_MSG_CODE__IPCP_FLOW_DEALLOC: +                        if (_ipcp->ops->ipcp_flow_dealloc == NULL) { +                                LOG_ERR("Flow_dealloc unsupported."); +                                break; +                        } +                        ret_msg.has_result = true; +                        ret_msg.result = _ipcp->ops->ipcp_flow_dealloc( +                                msg->port_id); +                        break; +                default: +                        LOG_ERR("Don't know that message code"); +                        break; +                } + +                ipcp_msg__free_unpacked(msg, NULL); + +                buffer.size = ipcp_msg__get_packed_size(&ret_msg); +                if (buffer.size == 0) { +                        LOG_ERR("Failed to send reply message"); +                        close(lsockfd); +                        continue; +                } + +                buffer.data = malloc(buffer.size); +                if (buffer.data == NULL) { +                        close(lsockfd); +                        continue; +                } + +                ipcp_msg__pack(&ret_msg, buffer.data); + +                if (write(lsockfd, buffer.data, buffer.size) == -1) { +                        free(buffer.data); +                        close(lsockfd); +                        continue; +                } + +                free(buffer.data); +                close(lsockfd); +        } + +        return 0; +} diff --git a/src/ipcpd/ipcp.h b/src/ipcpd/ipcp.h new file mode 100644 index 00000000..9decac8b --- /dev/null +++ b/src/ipcpd/ipcp.h @@ -0,0 +1,49 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * IPC process structure + * + *    Dimitri Staessens <dimitri.staessens@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. + */ + +#ifndef IPCPD_IPCP_H +#define IPCPD_IPCP_H + +#include "ipcp-ops.h" +#include "ipcp-data.h" + +enum ipcp_state { +        IPCP_INIT = 0, +        IPCP_ENROLLING, +        IPCP_BOOTSTRAPPING, +        IPCP_ENROLLED, +        IPCP_DISCONNECTED, +        IPCP_SHUTDOWN +}; + +struct ipcp { +        struct ipcp_data * data; +        struct ipcp_ops *  ops; + +        enum ipcp_state    state; +        int                irmd_fd; +}; + +int ipcp_main_loop(); +int ipcp_arg_check(int argc, char * argv[]); + +#endif diff --git a/src/ipcpd/normal/CMakeLists.txt b/src/ipcpd/normal/CMakeLists.txt new file mode 100644 index 00000000..c13cbaa3 --- /dev/null +++ b/src/ipcpd/normal/CMakeLists.txt @@ -0,0 +1,32 @@ +get_filename_component(CURRENT_SOURCE_PARENT_DIR ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY) +get_filename_component(CURRENT_BINARY_PARENT_DIR ${CMAKE_CURRENT_BINARY_DIR} DIRECTORY) + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + +include_directories(${CURRENT_SOURCE_PARENT_DIR}) +include_directories(${CURRENT_BINARY_PARENT_DIR}) + +include_directories(${CMAKE_SOURCE_DIR}/include) +include_directories(${CMAKE_BINARY_DIR}/include) + +SET(IPCP_NORMAL_TARGET ipcpd-normal CACHE STRING "IPCP_NORMAL_TARGET") + +set(SOURCE_FILES +        # Add source files here +        main.c +        pci.c +) + +add_executable (ipcpd-normal ${SOURCE_FILES} ${IPCP_SOURCES}) +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) +endif (CMAKE_BUILD_TYPE MATCHES Debug) + +install(TARGETS ipcpd-normal RUNTIME DESTINATION bin) + +# Enable once ipcp-normal has tests +# add_subdirectory(tests) diff --git a/src/ipcpd/dt_const.h b/src/ipcpd/normal/dt_const.h index bc0c1466..bc0c1466 100644 --- a/src/ipcpd/dt_const.h +++ b/src/ipcpd/normal/dt_const.h diff --git a/src/ipcpd/main.c b/src/ipcpd/normal/main.c index 7ffd1c48..7ffd1c48 100644 --- a/src/ipcpd/main.c +++ b/src/ipcpd/normal/main.c diff --git a/src/ipcpd/pci.c b/src/ipcpd/normal/pci.c index 548e40e2..d7df52b6 100644 --- a/src/ipcpd/pci.c +++ b/src/ipcpd/normal/pci.c @@ -22,7 +22,7 @@   */  #include "pci.h" -#include <malloc.h> +#include <stdlib.h>  #include <errno.h>  #define OUROBOROS_PREFIX "ipcp/pci" diff --git a/src/ipcpd/pci.h b/src/ipcpd/normal/pci.h index 3c011723..3c011723 100644 --- a/src/ipcpd/pci.h +++ b/src/ipcpd/normal/pci.h diff --git a/src/ipcpd/shm_pci.c b/src/ipcpd/normal/shm_pci.c index d44e0e8f..e76d8009 100644 --- a/src/ipcpd/shm_pci.c +++ b/src/ipcpd/normal/shm_pci.c @@ -22,7 +22,7 @@   */  #include "shm_pci.h" -#include <malloc.h> +#include <stdlib.h>  #include <errno.h>  #define SHM_PCI_HEAD_SIZE(a, b) a.addr_size * 2 +  \ diff --git a/src/ipcpd/shm_pci.h b/src/ipcpd/normal/shm_pci.h index cb8dd5dd..cb8dd5dd 100644 --- a/src/ipcpd/shm_pci.h +++ b/src/ipcpd/normal/shm_pci.h diff --git a/src/ipcpd/shim-udp/CMakeLists.txt b/src/ipcpd/shim-udp/CMakeLists.txt new file mode 100644 index 00000000..27907880 --- /dev/null +++ b/src/ipcpd/shim-udp/CMakeLists.txt @@ -0,0 +1,31 @@ +get_filename_component(CURRENT_SOURCE_PARENT_DIR ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY) +get_filename_component(CURRENT_BINARY_PARENT_DIR ${CMAKE_CURRENT_BINARY_DIR} DIRECTORY) + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + +include_directories(${CURRENT_SOURCE_PARENT_DIR}) +include_directories(${CURRENT_BINARY_PARENT_DIR}) + +include_directories(${CMAKE_SOURCE_DIR}/include) +include_directories(${CMAKE_BINARY_DIR}/include) + +SET(IPCP_SHIM_UDP_TARGET ipcpd-shim-udp CACHE STRING "IPCP_SHIM_UDP_TARGET") + +set(SHIM_UDP_SOURCES +        # Add source files here +        ${CMAKE_CURRENT_SOURCE_DIR}/main.c +) + +add_executable (ipcpd-shim-udp ${SHIM_UDP_SOURCES} ${IPCP_SOURCES}) +target_link_libraries (ipcpd-shim-udp LINK_PUBLIC ouroboros) + +include(MacroAddCompileFlags) +if (CMAKE_BUILD_TYPE MATCHES Debug) +   MACRO_ADD_COMPILE_FLAGS(ipcpd-shim-udp -DCONFIG_OUROBOROS_DEBUG) +endif (CMAKE_BUILD_TYPE MATCHES Debug) + +install(TARGETS ipcpd-shim-udp RUNTIME DESTINATION bin) + +# Enable once ipcp-shim-udp has tests +add_subdirectory(tests) diff --git a/src/ipcpd/shim-udp/main.c b/src/ipcpd/shim-udp/main.c new file mode 100644 index 00000000..df731490 --- /dev/null +++ b/src/ipcpd/shim-udp/main.c @@ -0,0 +1,324 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * Shim IPC process over UDP + * + *    Dimitri Staessens <dimitri.staessens@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. + */ + +#include <ouroboros/config.h> + +#include "ipcp.h" +#include "flow.h" +#include <ouroboros/shm_du_map.h> +#include <ouroboros/list.h> +#include <ouroboros/utils.h> +#include <ouroboros/ipcp.h> +#include <ouroboros/dif_config.h> + +#define OUROBOROS_PREFIX "ipcpd/shim-udp" + +#include <ouroboros/logs.h> + +#include <string.h> +#include <sys/socket.h> +#include <arpa/inet.h> +#include <netdb.h> +#include <netinet/in.h> +#include <signal.h> +#include <stdlib.h> +#include <pthread.h> + +#define THIS_TYPE IPCP_SHIM_UDP + +#define shim_data(type) ((struct ipcp_udp_data *) type->data) + +/* global for trapping signal */ +int irmd_pid; + +/* this IPCP's data */ +#ifdef MAKE_CHECK +extern struct ipcp * _ipcp; /* defined in test */ +#else +struct ipcp * _ipcp; +#endif + +struct ipcp_udp_data { +        /* IPCP_DATA STRUCT MUST BE FIRST!! */ +        struct ipcp_data ipcp_data; + +        uint32_t ip_addr; +        uint32_t dns_addr; + +        pthread_mutex_t   lock; +}; + +struct udp_flow { +        /* FLOW MUST BE FIRST !!!! */ +        flow_t flow; + +        uint16_t localport; + +        struct sockaddr_in * remote; +        int    fd; +}; + +void ipcp_sig_handler(int sig, siginfo_t * info, void * c) +{ +        switch(sig) { +        case SIGINT: +        case SIGTERM: +        case SIGHUP: +                LOG_DBG("Terminating by order of %d. Bye.", info->si_pid); +                if (info->si_pid == irmd_pid) { +                        shm_du_map_close(_ipcp->data->dum); +                        exit(0); +                } +        default: +                return; +        } +} + +struct ipcp_udp_data * ipcp_udp_data_create(char * ap_name, +                                            char * ap_id) +{ +        struct ipcp_udp_data * udp_data; +        struct ipcp_data *     data; +        instance_name_t *      instance_name; +        enum ipcp_type         ipcp_type; + +        instance_name = instance_name_create(); +        if (instance_name  == NULL) { +                LOG_ERR("Failed to create instance name struct."); +                return NULL; +        } + +        instance_name = instance_name_init_with( +                instance_name, ap_name, (uint16_t)atoi(ap_id)); + +        if (instance_name  == NULL) { +                LOG_ERR("Failed to create instance name struct."); +                return NULL; +        } + +        udp_data= malloc (sizeof *udp_data); +        if (udp_data == NULL) { +                LOG_DBGF("Failed to allocate."); +                return NULL; +        } + +        ipcp_type = THIS_TYPE; +        data = (struct ipcp_data *) udp_data; +        if (ipcp_data_init(data, instance_name, ipcp_type) == NULL) { +                free(udp_data); +                return NULL; +        } + +        return udp_data; +} + +int ipcp_udp_bootstrap(struct dif_config * conf) +{ +        char ipstr[INET_ADDRSTRLEN]; +        char dnsstr[INET_ADDRSTRLEN]; + +        if (conf->type != THIS_TYPE) { +                LOG_ERR("Config doesn't match IPCP type."); +                return -1; +        } + +        if (_ipcp->state != IPCP_INIT) { +                LOG_ERR("IPCP in wrong state."); +                return -1; +        } + +        inet_ntop(AF_INET, +                  &conf->ip_addr, +                  ipstr, +                  INET_ADDRSTRLEN); + +        if (conf->dns_addr != 0) +                inet_ntop(AF_INET, +                          &conf->dns_addr, +                          dnsstr, +                          INET_ADDRSTRLEN); +        else +                strcpy(dnsstr, "not set"); + +        shim_data(_ipcp)->ip_addr  = conf->ip_addr; +        shim_data(_ipcp)->dns_addr = conf->dns_addr; + +        _ipcp->state = IPCP_ENROLLED; + +        LOG_DBG("Bootstrapped shim IPCP over UDP %s-%d.", +                _ipcp->data->iname->name, _ipcp->data->iname->id); + +        LOG_DBG("Bound to IP address %s.", ipstr); +        LOG_DBG("DNS server address is %s.", dnsstr); + +        return 0; +} + +int ipcp_udp_ap_reg(char * ap_name, uint32_t reg_ap_id) +{ +        LOG_DBG("Registering local ap %s, %u.", ap_name, reg_ap_id); + +        if (_ipcp->state != IPCP_ENROLLED) { +                LOG_DBGF("Won't register with non-enrolled IPCP."); +                return -1; +        } + +        if (ipcp_data_add_reg_entry(_ipcp->data, ap_name, reg_ap_id)) { +                LOG_ERR("Failed to add AP to local registry."); +                return -1; +        } + +        LOG_MISSING; + +        return 0; +} + +int ipcp_udp_ap_unreg(uint32_t reg_ap_id) +{ +        char * name  = strdup(ipcp_data_get_reg_ap_name(_ipcp->data, +                                                        reg_ap_id)); +        LOG_DBG("Unregistering %s.", name); + +        ipcp_data_del_reg_entry(_ipcp->data, reg_ap_id); + +        /* we are using dns */ +        LOG_MISSING; + +        free (name); + +        return 0; +} + +int ipcp_udp_flow_alloc(uint32_t          port_id, +                        char *            dst_ap_name, +                        char *            src_ap_name, +                        char *            src_ae_name, +                        struct qos_spec * qos) +{ +        return 0; +} +int ipcp_udp_flow_alloc_resp(uint32_t port_id, +                             int      result) +{ +        return 0; +} + +int ipcp_udp_flow_dealloc(uint32_t port_id) +{ +        return 0; +} + +int ipcp_udp_du_write(uint32_t port_id, +                      size_t map_index) +{ +        return 0; +} + +int ipcp_udp_du_read(uint32_t port_id, +                     size_t map_index) +{ +        return 0; +} + +struct ipcp * ipcp_udp_create(char * ap_name, char * i_id) +{ +        struct ipcp * i; +        struct ipcp_udp_data * data; +        struct ipcp_ops *      ops; + +        i = malloc(sizeof *i); +        if (i == NULL) +                return NULL; + +        data = ipcp_udp_data_create(ap_name, i_id); +        if (data == NULL) { +                free(i); +                return NULL; +        } + +        ops = malloc (sizeof *ops); +        if (ops == NULL) { +                free(data); +                free(i); +                return NULL; +        } + +        ops->ipcp_bootstrap       = ipcp_udp_bootstrap; +        ops->ipcp_enroll          = NULL;                       /* shim */ +        ops->ipcp_reg             = NULL;                       /* shim */ +        ops->ipcp_unreg           = NULL;                       /* shim */ +        ops->ipcp_ap_reg          = ipcp_udp_ap_reg; +        ops->ipcp_ap_unreg        = ipcp_udp_ap_unreg; +        ops->ipcp_flow_alloc      = ipcp_udp_flow_alloc; +        ops->ipcp_flow_alloc_resp = ipcp_udp_flow_alloc_resp; +        ops->ipcp_flow_dealloc    = ipcp_udp_flow_dealloc; +        ops->ipcp_du_read         = ipcp_udp_du_read; +        ops->ipcp_du_write        = ipcp_udp_du_write; + +        i->data = (struct ipcp_data *) data; +        i->ops  = ops; + +        i->state = IPCP_INIT; + +        return i; +} + +#ifndef MAKE_CHECK + +int main (int argc, char * argv[]) +{ +        /* argument 1: pid of irmd ? */ +        /* argument 2: ap name */ +        /* argument 3: instance id */ +        struct sigaction sig_act; + +        if (ipcp_arg_check(argc, argv)) { +                LOG_ERR("Wrong arguments."); +                exit(1); +        } + +        /* store the process id of the irmd */ +        irmd_pid = atoi(argv[1]); + +        /* init sig_act */ +        memset (&sig_act, 0, sizeof sig_act); + +        /* install signal traps */ +        sig_act.sa_sigaction = &ipcp_sig_handler; +        sig_act.sa_flags     = SA_SIGINFO; + +        sigaction(SIGINT,  &sig_act, NULL); +        sigaction(SIGTERM, &sig_act, NULL); +        sigaction(SIGHUP,  &sig_act, NULL); + +        _ipcp = ipcp_udp_create(argv[2], argv[3]); +        if (_ipcp == NULL) { +                LOG_ERR("Won't."); +                exit(1); +        } + +        ipcp_main_loop(_ipcp); + +        exit(0); +} + +#endif /* MAKE_CHECK */ diff --git a/src/ipcpd/shim-udp/tests/CMakeLists.txt b/src/ipcpd/shim-udp/tests/CMakeLists.txt new file mode 100644 index 00000000..bdd7defb --- /dev/null +++ b/src/ipcpd/shim-udp/tests/CMakeLists.txt @@ -0,0 +1,33 @@ +get_filename_component(PARENT_SOURCE_PATH ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY) +get_filename_component(PARENT_BINARY_PATH ${CMAKE_CURRENT_BINARY_DIR} DIRECTORY) +get_filename_component(PARENT_DIR ${PARENT_SOURCE_PATH} NAME) + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + +include_directories(${PARENT_SOURCE_PATH}) +include_directories(${PARENT_BINARY_PATH}) + +include_directories(${CMAKE_SOURCE_DIR}/include) +include_directories(${CMAKE_BINARY_DIR}/include) + +create_test_sourcelist(${PARENT_DIR}_tests test_suite.c +                       # Add new tests here +                       shim_udp_test.c +) + +add_executable(${PARENT_DIR}_test EXCLUDE_FROM_ALL ${IPCP_SOURCES} ${${PARENT_DIR}_tests}) +target_link_libraries(${PARENT_DIR}_test ouroboros) + +include(MacroAddCompileFlags) +MACRO_ADD_COMPILE_FLAGS(${PARENT_DIR}_test -DMAKE_CHECK) + +add_dependencies(check ${PARENT_DIR}_test) + +set(tests_to_run ${${PARENT_DIR}_tests}) +remove(tests_to_run test_suite.c) + +foreach(test ${tests_to_run}) +  get_filename_component(test_name ${test} NAME_WE) +  add_test(${test_name} ${C_TEST_PATH}/${PARENT_DIR}_test ${test_name}) +endforeach(test) diff --git a/src/ipcpd/shim-udp/tests/shim_udp_test.c b/src/ipcpd/shim-udp/tests/shim_udp_test.c new file mode 100644 index 00000000..427d0e1e --- /dev/null +++ b/src/ipcpd/shim-udp/tests/shim_udp_test.c @@ -0,0 +1,103 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * Test of the Shim UDP IPCP Daemon + * + *    Dimitri Staessens <dimitri.staessens@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. + */ + +#include <ouroboros/config.h> +#include <ouroboros/dif_config.h> +#include <ouroboros/utils.h> +#include <ouroboros/shm_du_map.h> +#include <sys/types.h> +#include <stdlib.h> +#include "main.c" + +#include <ouroboros/logs.h> + +struct ipcp * _ipcp; + +int shim_udp_test(int argc, char ** argv) +{ +        /* argument 1: pid of irmd ? */ +        /* argument 2: ap name */ +        /* argument 3: instance id */ +        struct shm_du_map * dum; +        char * ipcp_name = "test-shim-ipcp"; +        char * i_id = "1"; +        int i = 0; + +        char bogus[15]; +        memset (&bogus, 0, 15); + +        struct dif_config conf; +        memset (&conf, 0, sizeof conf); +        conf.dif_name = strdup("test-dif"); +        conf.type = IPCP_SHIM_UDP; +        conf.ip_addr = 0; + +        dum = shm_du_map_create(); +        if (dum == NULL) { +                LOG_ERR("Failed to create shared memory."); +                exit(1); +        } + +        _ipcp = ipcp_udp_create(ipcp_name, i_id); +        if (_ipcp == NULL) { +                LOG_ERR("Could not instantiate shim IPCP."); +                shm_du_map_close(dum); +                exit(1); +        } + +        if (ipcp_udp_bootstrap (&conf)) { +                LOG_ERR("Could not bootstrap."); +        } + +        if(ipcp_udp_ap_reg("bogus ap", 1865)) { +                LOG_ERR("Failed to register application."); +                shm_du_map_close(dum); +                exit(1); +        } + +        if (ipcp_udp_ap_unreg(1865)) { +                LOG_ERR("Failed to unregister application."); +                shm_du_map_close(dum); +                exit(1); +        } + +        for (i = 0; i  < 1000; ++i) { +                sprintf (bogus, "bogus ap %4d", i); +                if(ipcp_udp_ap_reg(bogus, i)) { +                         LOG_ERR("Failed to register application %s.", bogus); +                         shm_du_map_close(dum); +                         exit(1); +                } +        } + +        for (i = 0; i  < 1000; ++i) { +                if(ipcp_udp_ap_unreg(i)) { +                         LOG_ERR("Failed to unregister application %d.", i); +                         shm_du_map_close(dum); +                         exit(1); +                } +        } + +        shm_du_map_close(dum); + +        exit(0); +}  | 
