From f706404e6e40043b87ff19e32c8fd11958772e9d Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 26 Jul 2013 19:47:09 +0200 Subject: More cleanups --- mmss/CMakeLists.txt | 1 + mmss/config.cpp | 7 ++- mmss/gmrf.cpp | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++++ mmss/iface.cpp | 64 +++++++---------------- mmss/log.cpp | 47 +---------------- mmss/mmss.cpp | 49 ++++++++---------- mmss/mmss.hpp | 108 +++++++++++++++++++++++++-------------- mmss/protocol.cpp | 14 ++--- mmss/schedule.cpp | 12 +---- mmss/types.hpp | 5 +- mmss/util.hpp | 47 +++++++++++++++++ 11 files changed, 316 insertions(+), 181 deletions(-) create mode 100644 mmss/gmrf.cpp create mode 100644 mmss/util.hpp diff --git a/mmss/CMakeLists.txt b/mmss/CMakeLists.txt index 047e348..04ac405 100644 --- a/mmss/CMakeLists.txt +++ b/mmss/CMakeLists.txt @@ -5,6 +5,7 @@ BISON_TARGET(mmss_config_parse config.y ${CMAKE_CURRENT_BINARY_DIR}/config.yy.cp add_executable(mmss config.cpp + gmrf.cpp iface.cpp log.cpp mmss.cpp diff --git a/mmss/config.cpp b/mmss/config.cpp index 529e9b1..4492ffd 100644 --- a/mmss/config.cpp +++ b/mmss/config.cpp @@ -40,13 +40,12 @@ namespace Config { void add_network(context_t *mmss, config_t *conf, const char *name) { logf(mmss, LOG_NOTICE, "adding network `%s'", name); - network_t *net = new network_t; + std::shared_ptr net = std::make_shared(); - net->name = strdup(name); + net->name = name; net->mtu = 1500; - net->next = conf->networks; - conf->networks = net; + conf->network.push_back(net); } } diff --git a/mmss/gmrf.cpp b/mmss/gmrf.cpp new file mode 100644 index 0000000..d6eecbc --- /dev/null +++ b/mmss/gmrf.cpp @@ -0,0 +1,143 @@ +/* + Copyright (c) 2013, Matthias Schiffer + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#include "mmss.hpp" +#include "util.hpp" + +#include + + +extern "C" { + +gmrf_addr_t gmrf_iface_get_addr(gmrf_t *gmrf, gmrf_iface_t *iface) { + return iface->address; +} + +const char* gmrf_iface_get_name(gmrf_t *gmrf, gmrf_iface_t *iface) { + return iface->name.c_str(); +} + +size_t gmrf_iface_get_mtu(gmrf_t *gmrf, gmrf_iface_t *iface) { + auto net = iface->net.lock(); + if (!net) + return 0; + + return net->mtu; +} + +bool gmrf_iface_send(gmrf_t *gmrf, gmrf_iface_t *iface, const void *data, size_t len, const gmrf_addr_t *dest) { + auto src_iface = iface->iface.lock(); + assert(src_iface); + + auto net = src_iface->net.lock(); + if (!net) + return false; + + for (auto dest_iface : net->interfaces) { + if (gmrf_addr_equal(&dest_iface->address, dest)) { + MMSS::enqueue(gmrf->mmss, src_iface, dest_iface, data, len); + break; + } + } + + return true; +} + +bool gmrf_iface_send_bc(gmrf_t *gmrf, gmrf_iface_t *iface, const void *data, size_t len) { + auto src_iface = iface->iface.lock(); + assert(src_iface); + + auto net = src_iface->net.lock(); + if (!net) + return false; + + for (auto dest_iface : net->interfaces) { + if (dest_iface != src_iface) + MMSS::enqueue(gmrf->mmss, src_iface, dest_iface, data, len); + } + + return true; +} + +void gmrf_schedule(gmrf_t *gmrf, gmrf_scheduled_func f, void *arg, unsigned delay) { + auto node = gmrf->node.lock(); + assert(node); + + std::shared_ptr scheduled = std::make_shared(); + + scheduled->node = node; + scheduled->f = f; + scheduled->arg = arg; + + gmrf->mmss->scheduled_queue.put(scheduled, gmrf->mmss->now+delay); +} + +gmrf_time_t gmrf_now(gmrf_t *gmrf) { + return gmrf->mmss->now; +} + +void gmrf_random_bytes(gmrf_t *gmrf, void *buffer, size_t len) { + uint8_t *data = reinterpret_cast(buffer); + + size_t i; + for (i = 0; i < len; i++) + data[i] = rand_r(&gmrf->rand_seed); +} + +static inline const char* get_log_prefix(int log_level) { + switch(log_level) { + case LOG_CRIT: + return "Fatal: "; + case LOG_ERR: + return "Error: "; + case LOG_WARNING: + return "Warning: "; + case LOG_NOTICE: + return "Info: "; + case LOG_INFO: + return "Verbose: "; + case LOG_DEBUG: + return "DEBUG: "; + default: + return ""; + } +} + +void gmrf_logf(gmrf_t *gmrf, int priority, const char *format, ...) { + char buf[1024]; + size_t pos = 0; + + pos += MMSS::snprintf_safe(buf, sizeof(buf), "%s: %s", gmrf->name.c_str(), get_log_prefix(priority)); + + va_list ap; + va_start(ap, format); + vsnprintf(buf+pos, sizeof(buf)-pos, format, ap); + va_end(ap); + + MMSS::logf(gmrf->mmss, priority, "%s", buf); +} + +} diff --git a/mmss/iface.cpp b/mmss/iface.cpp index e25eccd..602daa2 100644 --- a/mmss/iface.cpp +++ b/mmss/iface.cpp @@ -32,29 +32,34 @@ namespace MMSS { void dispatch(std::shared_ptr packet) { - packet->dest->node->proto->handle_packet(packet->dest->node, packet->dest->node->ctx, packet->dest, - &packet->source->address, packet->data.get(), packet->len); + auto source = packet->source.lock(); + auto dest = packet->dest.lock(); + if (!source || !dest) + return; + + auto node = dest->node.lock(); + if (!node) + return; + + node->proto->handle_packet(node.get(), node->ctx, dest.get(), &source->address, packet->data.get(), packet->len); } -void add_iface(gmrf_t *node, network_t *net, const char *name, const gmrf_addr_t *address) { - gmrf_iface_t *iface = new gmrf_iface_t; +void add_iface(std::shared_ptr node, std::shared_ptr net, const std::string &name, const gmrf_addr_t *address) { + std::shared_ptr iface = iface_t::create(); - iface->name = strdup(name); + iface->name = name; iface->address = *address; iface->node = node; iface->net = net; - iface->node_next = node->interfaces; - node->interfaces = iface; + node->interfaces.push_back(iface); + net->interfaces.push_back(iface); - iface->network_next = net->interfaces; - net->interfaces = iface; - - node->proto->add_iface(node, node->ctx, iface); + node->proto->add_iface(node.get(), node->ctx, iface.get()); } -static void enqueue(context_t *mmss, gmrf_iface_t *source, gmrf_iface_t *dest, const void *data, size_t len) { +void enqueue(context_t *mmss, std::shared_ptr source, std::shared_ptr dest, const void *data, size_t len) { std::shared_ptr packet = std::make_shared(); packet->sent = mmss->now; @@ -69,38 +74,3 @@ static void enqueue(context_t *mmss, gmrf_iface_t *source, gmrf_iface_t *dest, c } } - - -gmrf_addr_t gmrf_iface_get_addr(gmrf_t *gmrf, gmrf_iface_t *iface) { - return iface->address; -} - -const char* gmrf_iface_get_name(gmrf_t *gmrf, gmrf_iface_t *iface) { - return iface->name; -} - -size_t gmrf_iface_get_mtu(gmrf_t *gmrf, gmrf_iface_t *iface) { - return iface->net->mtu; -} - -bool gmrf_iface_send(gmrf_t *gmrf, gmrf_iface_t *iface, const void *data, size_t len, const gmrf_addr_t *dest) { - gmrf_iface_t *dest_iface; - for (dest_iface = iface->net->interfaces; dest_iface; dest_iface = dest_iface->network_next) { - if (gmrf_addr_equal(&dest_iface->address, dest)) { - MMSS::enqueue(gmrf->mmss, iface, dest_iface, data, len); - break; - } - } - - return true; -} - -bool gmrf_iface_send_bc(gmrf_t *gmrf, gmrf_iface_t *iface, const void *data, size_t len) { - gmrf_iface_t *dest_iface; - for (dest_iface = iface->net->interfaces; dest_iface; dest_iface = dest_iface->network_next) { - if (dest_iface != iface) - enqueue(gmrf->mmss, iface, dest_iface, data, len); - } - - return true; -} diff --git a/mmss/log.cpp b/mmss/log.cpp index 029b1d6..b66cf6f 100644 --- a/mmss/log.cpp +++ b/mmss/log.cpp @@ -25,41 +25,10 @@ #include "mmss.hpp" - -#include -#include - +#include "util.hpp" namespace MMSS { -static inline int snprintf_safe(char *buffer, size_t size, const char *format, ...) { - std::va_list ap; - va_start(ap, format); - int ret = std::vsnprintf(buffer, size, format, ap); - va_end(ap); - - return ret < 0 ? 0 : ret > size ? size : ret; -} - -static inline const char* get_log_prefix(int log_level) { - switch(log_level) { - case LOG_CRIT: - return "Fatal: "; - case LOG_ERR: - return "Error: "; - case LOG_WARNING: - return "Warning: "; - case LOG_NOTICE: - return "Info: "; - case LOG_INFO: - return "Verbose: "; - case LOG_DEBUG: - return "DEBUG: "; - default: - return ""; - } -} - void logf(context_t *mmss, int priority, const char *format, ...) { char buf[1024]; size_t pos = 0; @@ -75,17 +44,3 @@ void logf(context_t *mmss, int priority, const char *format, ...) { } } - -void gmrf_logf(gmrf_t *gmrf, int priority, const char *format, ...) { - char buf[1024]; - size_t pos = 0; - - pos += MMSS::snprintf_safe(buf, sizeof(buf), "%s: %s", gmrf->name, MMSS::get_log_prefix(priority)); - - va_list ap; - va_start(ap, format); - vsnprintf(buf+pos, sizeof(buf)-pos, format, ap); - va_end(ap); - - MMSS::logf(gmrf->mmss, priority, "%s", buf); -} diff --git a/mmss/mmss.cpp b/mmss/mmss.cpp index cb50329..1d918e4 100644 --- a/mmss/mmss.cpp +++ b/mmss/mmss.cpp @@ -30,25 +30,11 @@ #include -gmrf_time_t gmrf_now(gmrf_t *gmrf) { - return gmrf->mmss->now; -} - -void gmrf_random_bytes(gmrf_t *gmrf, void *buffer, size_t len) { - uint8_t *data = reinterpret_cast(buffer); - - size_t i; - for (i = 0; i < len; i++) - data[i] = rand_r(&gmrf->rand_seed); -} - namespace MMSS { -static void init_nodes(gmrf_t *nodes) { - gmrf_t *node; - for (node = nodes; node; node = node->next) { - node->ctx = node->proto->init(node); - } +static void init_nodes(std::list> &nodes) { + for (auto node : nodes) + node->ctx = node->proto->init(node.get()); } @@ -85,22 +71,29 @@ void main(int argc, char *argv[]) { read_config(&mmss, &conf, "babel_test.mmss"); - network_t net0 = { .mtu = 1500 }, net1 = { .mtu = 1500 }; - gmrf_t node1 = { .name = strdup("node1"), .mmss = &mmss, .rand_seed = 1, .proto = proto }; - gmrf_t node2 = { .name = strdup("node2"), .mmss = &mmss, .rand_seed = 2, .proto = proto }; - gmrf_t node3 = { .name = strdup("node3"), .mmss = &mmss, .rand_seed = 3, .proto = proto }; + std::shared_ptr net0 = std::make_shared(); + std::shared_ptr net1 = std::make_shared(); + + *net0 = (network_t){ .mtu = 1500 }; + *net1 = (network_t){ .mtu = 1500 }; + + std::shared_ptr node1 = node_t::create(&mmss, "node1", 1, proto); + std::shared_ptr node2 = node_t::create(&mmss, "node2", 2, proto); + std::shared_ptr node3 = node_t::create(&mmss, "node3", 3, proto); + + std::list> nodes; - node2.next = &node1; - node3.next = &node2; - gmrf_t *nodes = &node3; + nodes.push_back(node1); + nodes.push_back(node2); + nodes.push_back(node3); init_nodes(nodes); gmrf_addr_t addr1 = {{1}}, addr2 = {{2}}, addr3 = {{3}}, addr4 = {{4}}; - add_iface(&node1, &net0, "mmss0", &addr1); - add_iface(&node2, &net0, "mmss0", &addr2); - add_iface(&node2, &net1, "mmss1", &addr3); - add_iface(&node3, &net1, "mmss1", &addr4); + add_iface(node1, net0, "mmss0", &addr1); + add_iface(node2, net0, "mmss0", &addr2); + add_iface(node2, net1, "mmss1", &addr3); + add_iface(node3, net1, "mmss1", &addr4); while (true) { int timeout = get_queue_timeout(&mmss); diff --git a/mmss/mmss.hpp b/mmss/mmss.hpp index 78c93be..4045c40 100644 --- a/mmss/mmss.hpp +++ b/mmss/mmss.hpp @@ -29,9 +29,67 @@ #include "queue.hpp" +#include #include +struct gmrf { +private: + gmrf(MMSS::context_t *mmss0, const std::string &name0, unsigned rand_seed0, const MMSS::protocol_t *proto0) : + mmss(mmss0), name(name0), rand_seed(rand_seed0), proto(proto0) {} + gmrf(gmrf const&) = delete; + gmrf& operator=(gmrf const&) = delete; + +public: + static std::shared_ptr create(MMSS::context_t *mmss, const std::string &name, unsigned rand_seed, const MMSS::protocol_t *proto) { + MMSS::node_t *node = new MMSS::node_t(mmss, name, rand_seed, proto); + + std::shared_ptr ptr(node); + node->node = ptr; + + return ptr; + } + + std::weak_ptr node; + + MMSS::context_t *mmss; + + std::string name; + + gmrf_context_t *ctx; + std::list> interfaces; + + unsigned rand_seed; + + const MMSS::protocol_t *proto; +}; + +struct gmrf_iface { +private: + gmrf_iface() {} + gmrf_iface(gmrf_iface const&) = delete; + gmrf_iface& operator=(gmrf_iface const&) = delete; + +public: + static std::shared_ptr create() { + MMSS::iface_t *iface = new MMSS::iface_t; + + std::shared_ptr ptr(iface); + iface->iface = ptr; + + return ptr; + } + + std::weak_ptr iface; + + std::string name; + gmrf_addr_t address; + + std::weak_ptr node; + std::weak_ptr net; +}; + + namespace MMSS { class context_t { @@ -45,17 +103,15 @@ public: class config_t { public: - network_t *networks; - gmrf_t *nodes; + std::list> network; + std::list> nodes; }; class network_t { public: - network_t *next; + std::string name; - char *name; - - gmrf_iface_t *interfaces; + std::list> interfaces; size_t mtu; }; @@ -63,8 +119,8 @@ class packet_t { public: uint64_t sent; - gmrf_iface_t *source; - gmrf_iface_t *dest; + std::weak_ptr source; + std::weak_ptr dest; size_t len; std::unique_ptr data; @@ -72,7 +128,7 @@ public: class scheduled_t { public: - gmrf_t *node; + std::shared_ptr node; gmrf_scheduled_func f; void *arg; }; @@ -80,20 +136,15 @@ public: const protocol_t* load_protocol(const char *module); -namespace Config { - -void add_network(context_t *mmss, config_t *conf, const char *name); - -} - bool read_config(context_t *mmss, config_t *conf, const char *filename); -void add_iface(gmrf_t *node, network_t *net, const char *name, const gmrf_addr_t *address); +void add_iface(std::shared_ptr node, std::shared_ptr net, const std::string &name, const gmrf_addr_t *address); uint64_t now(const context_t *mmss); void dispatch(std::shared_ptr packet); void run_scheduled(std::shared_ptr scheduled); +void enqueue(context_t *mmss, std::shared_ptr source, std::shared_ptr dest, const void *data, size_t len); void logf(context_t *mmss, int priority, const char *format, ...); @@ -111,31 +162,14 @@ static inline size_t alignto(size_t l, size_t a) { return ((l+a-1)/a)*a; } -} - -struct gmrf { - gmrf_t *next; - - char *name; - MMSS::context_t *mmss; - gmrf_context_t *ctx; - gmrf_iface_t *interfaces; - - unsigned rand_seed; +namespace Config { - const MMSS::protocol_t *proto; -}; +void add_network(context_t *mmss, config_t *conf, const char *name); -struct gmrf_iface { - gmrf_iface_t *node_next; - gmrf_iface_t *network_next; +} - char *name; - gmrf_addr_t address; +} - gmrf_t *node; - MMSS::network_t *net; -}; #endif /* _GMRF_MMSS_MMSS_HPP_ */ diff --git a/mmss/protocol.cpp b/mmss/protocol.cpp index f08d13e..3bbfeb1 100644 --- a/mmss/protocol.cpp +++ b/mmss/protocol.cpp @@ -33,21 +33,21 @@ namespace MMSS { const protocol_t* load_protocol(const char *module) { - void *handle = dlopen(module, RTLD_NOW); + void *handle = ::dlopen(module, RTLD_NOW); if (!handle) { - fprintf(stderr, "unable to load protocol from `%s': %s\n", module, dlerror()); + std::fprintf(stderr, "unable to load protocol from `%s': %s\n", module, dlerror()); return NULL; } - dlerror(); - const protocol_t *proto = reinterpret_cast(dlsym(handle, "mmss_protocol_info")); + ::dlerror(); + const protocol_t *proto = reinterpret_cast(::dlsym(handle, "mmss_protocol_info")); if (!proto) { - fprintf(stderr, "unable to load protocol from `%s': %s\n", module, dlerror()); - dlclose(handle); + std::fprintf(stderr, "unable to load protocol from `%s': %s\n", module, dlerror()); + ::dlclose(handle); return NULL; } - fprintf(stderr, "loaded protocol `%s' version %s\n", proto->get_name(), proto->get_version()); + std::fprintf(stderr, "loaded protocol `%s' version %s\n", proto->get_name(), proto->get_version()); return proto; } diff --git a/mmss/schedule.cpp b/mmss/schedule.cpp index 88de519..7e6247e 100644 --- a/mmss/schedule.cpp +++ b/mmss/schedule.cpp @@ -30,17 +30,7 @@ namespace MMSS { void run_scheduled(std::shared_ptr scheduled) { - scheduled->f(scheduled->node, scheduled->node->ctx, scheduled->arg); + scheduled->f(scheduled->node.get(), scheduled->node->ctx, scheduled->arg); } } - -void gmrf_schedule(gmrf_t *gmrf, gmrf_scheduled_func f, void *arg, unsigned delay) { - std::shared_ptr scheduled = std::make_shared(); - - scheduled->node = gmrf; - scheduled->f = f; - scheduled->arg = arg; - - gmrf->mmss->scheduled_queue.put(scheduled, gmrf->mmss->now+delay); -} diff --git a/mmss/types.hpp b/mmss/types.hpp index e8a63cc..3daa486 100644 --- a/mmss/types.hpp +++ b/mmss/types.hpp @@ -33,8 +33,8 @@ extern "C" { -#include #include +#include } @@ -48,6 +48,9 @@ class scheduled_t; typedef ::mmss_protocol_t protocol_t; +typedef ::gmrf_t node_t; +typedef ::gmrf_iface_t iface_t; + } #endif /* _GMRF_MMSS_TYPES_HPP_ */ diff --git a/mmss/util.hpp b/mmss/util.hpp new file mode 100644 index 0000000..147a9aa --- /dev/null +++ b/mmss/util.hpp @@ -0,0 +1,47 @@ +/* + Copyright (c) 2013, Matthias Schiffer + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#ifndef _GMRF_MMSS_UTIL_HPP_ +#define _GMRF_MMSS_UTIL_HPP_ + +#include +#include + + +namespace MMSS { + +static inline int snprintf_safe(char *buffer, size_t size, const char *format, ...) { + std::va_list ap; + va_start(ap, format); + int ret = std::vsnprintf(buffer, size, format, ap); + va_end(ap); + + return ret < 0 ? 0 : ret > size ? size : ret; +} + +} + +#endif /* _GMRF_MMSS_UTIL_HPP_ */ -- cgit v1.2.3