diff options
| author | Sander Vrijders <sander.vrijders@intec.ugent.be> | 2016-04-23 09:53:35 +0200 | 
|---|---|---|
| committer | Sander Vrijders <sander.vrijders@intec.ugent.be> | 2016-04-23 09:53:35 +0200 | 
| commit | b6dc5ba9576d61d42db82c3da8cb0c039fac7179 (patch) | |
| tree | 0de76147c8a7beb4c23a1931f822113b61c51a5b /src/ipcpd/shim-udp | |
| parent | 9687ace9a1faf752672774ae49a6428b378fa409 (diff) | |
| parent | a618984537f7790cd274d097223b4029473044c2 (diff) | |
| download | ouroboros-b6dc5ba9576d61d42db82c3da8cb0c039fac7179.tar.gz ouroboros-b6dc5ba9576d61d42db82c3da8cb0c039fac7179.zip | |
Merge remote-tracking branch 'upstream/be' into be
Diffstat (limited to 'src/ipcpd/shim-udp')
| -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 | 
4 files changed, 491 insertions, 0 deletions
| 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); +} | 
