diff --git a/CMakeLists.txt b/CMakeLists.txt index b61697e..ce39b33 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,12 +40,11 @@ include_directories( # Define files set(SRCS - src/node.cpp) + "src/node.cpp") set(HDRS - include/neocomm/channel.hpp - include/neocomm/message.hpp - include/neocomm/node.hpp) + "include/neocomm/channel.hpp" + "include/neocomm/node.hpp") # Define C++ compiler flags set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wextra -Wpedantic -Werror -Wfatal-errors -pedantic-errors -fno-elide-constructors") @@ -78,7 +77,7 @@ else() add_library(${TARGET_NAME} STATIC ${SRCS}) endif() set_target_properties(${TARGET_NAME} - PROPERTIES PUBLIC_HEADER ${HDRS}) + PROPERTIES PUBLIC_HEADER "${HDRS}") install(TARGETS ${TARGET_NAME} ARCHIVE DESTINATION lib/ diff --git a/include/neocomm/channel.hpp b/include/neocomm/channel.hpp index 793698b..d45c107 100644 --- a/include/neocomm/channel.hpp +++ b/include/neocomm/channel.hpp @@ -19,28 +19,15 @@ #pragma once #include - -#include "identity.hpp" +#include +#include namespace neocomm { -/** - * @brief Container class of all data and basic functions pertaining to - * channel functionality. - */ -class channel { -public: - /** - * @brief Initialize the channel class and start receiving messages - * for the given ID. - * - * @param chan_id The ID of the channel. - */ - channel(const std::string &chan_id); // TODO - ~channel(); // TODO -private: - const std::string chan_id; - std::vector msgs; // messages to and from the channel +struct channel { + dht::InfoHash key; + std::future token; + std::list messages; }; } diff --git a/include/neocomm/message.hpp b/include/neocomm/message.hpp deleted file mode 100644 index aaafbbd..0000000 --- a/include/neocomm/message.hpp +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2018 Ortega Froysa, Nicolás - * Author: Ortega Froysa, Nicolás - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -#pragma once - -#include -#include - -#include "identity.hpp" - -namespace neocomm { - -/** - * @brief Container for data of a user message. - */ -class message { -private: - const std::string text; - const struct tm time_stamp; - const identity from; -}; - -} diff --git a/include/neocomm/identity.hpp b/include/neocomm/neocomm.hpp similarity index 81% rename from include/neocomm/identity.hpp rename to include/neocomm/neocomm.hpp index 92079f7..417b9cc 100644 --- a/include/neocomm/identity.hpp +++ b/include/neocomm/neocomm.hpp @@ -18,17 +18,4 @@ #pragma once -namespace neocomm { - -/** - * @brief Container class for data pertaining to a user. - */ -class identity { -public: -private: - const std::string id; - std::string nick; - std::string client_info; -}; - -} +#include "node.hpp" diff --git a/include/neocomm/node.hpp b/include/neocomm/node.hpp index d23d3d6..1d92a86 100644 --- a/include/neocomm/node.hpp +++ b/include/neocomm/node.hpp @@ -18,89 +18,39 @@ #pragma once -#include "identity.hpp" -#include "channel.hpp" +#include "neocomm/channel.hpp" -#include -#include #include +#include namespace neocomm { -/** - * @brief NeoComm node object. - * - * @details Contains the necessary interfaces to create a - * NeoComm node and connect to a NeoComm network. - */ class node { public: - /** - * @brief Initialize a NeoComm node. - * - * @param port Listen on a given port (8085 by default). - */ - node(unsigned short port = 8085); - /** - * @brief Initialize a NeoComm node inputting a list of - * known nodes from a file. - * - * @param node_file Path to file containing node list. - * @param port Listen on a given port (8085 by default). - */ - node(const std::string &node_file, - unsigned short port = 8085); + node(const unsigned short port = 31133); ~node(); - /** - * @brief Connect the node to a given address. - * - * @param address The IP or domain name of the other node. - * @param port The port of the other node. - */ - void connect(const std::string &address, - unsigned short port); - /** - * @brief Import and connect to a list of nodes from a - * previous session. - * - * @param node_file File containing the node list. - */ - void import_nodes(const std::string &node_file); - /** - * @brief Export currently connected nodes to a file. - * - * @param node_file File to export nodes to. - */ - void export_nodes(const std::string &node_file); - - /** - * @brief Join and receive messages from a channel. - * - * @param chan_id The ID of the channel. - */ - void join_channel(const std::string &chan_id); // TODO - /** - * @brief Retrieve the channel object. - * - * @param chan_id The ID of the channel. - * - * @return The channel object. - */ - channel* get_channel(const std::string &chan_id); // TODO - /** - * @brief Leave a channel. - * - * @param chan_id The ID of the channel. - */ - void leave_channel(const std::string &chan_id); // TODO + inline void connect(const std::string &address, + const std::string &port) { + network.bootstrap(address, port); + } + void import_nodes(const std::string &file_path); // TODO + void export_nodes(const std::string &file_path); // TODO + void join_channel(const std::string &name); + void leave_channel(const std::string &name); private: - unsigned int pm_timeout; // timeout for private message reception confirmation - unsigned int chan_timeout; // timeout for channel presence message - std::vector channels; // channels connected to via the node - std::vector identities; // known users on the network - dht::DhtRunner dht_node; // the actual OpenDHT node + inline struct channel *get_channel( + const std::string &name) { + for(auto &i : channels) + { + if(i.first == name) + return &i.second; + } + return nullptr; + } + dht::DhtRunner network; + std::map channels; }; } diff --git a/src/node.cpp b/src/node.cpp index 98ce772..64ab8d8 100644 --- a/src/node.cpp +++ b/src/node.cpp @@ -18,96 +18,33 @@ #include "neocomm/node.hpp" -#include -#include -#include +using namespace neocomm; -neocomm::node::node(unsigned short port) { -#ifdef WOE32 - gnutls_global_init(); -#endif - try { - dht_node.run(port, - dht::crypto::generateIdentity(), true); - } - catch(const std::exception &e) - { - // rethrow exception - throw e; - } +node::node(unsigned short port) { + // TODO: see about preserving an identity + network.run(port, dht::crypto::generateIdentity(), true); } -neocomm::node::node(const std::string &node_file, - unsigned short port) { -#ifdef WOE32 - gnutls_global_init(); -#endif - try { - dht_node.run(port, - dht::crypto::generateIdentity(), true); - } - catch(const std::exception &e) - { - // rethrow exception - throw e; - } - - import_nodes(node_file); +node::~node() { + network.join(); } -neocomm::node::~node() { - dht_node.join(); -#ifdef WOE32 - gnutls_global_deinit(); -#endif +void node::join_channel(const std::string &name) { + if(get_channel(name)) + return; + channels[name].key = dht::InfoHash::get(name); + channels[name].token = network.listen( + channels[name].key, + [&](std::string &&msg) { + channels[name].messages.push_back(msg); + return true; + }); } -void neocomm::node::connect(const std::string &address, - unsigned short port) { - if(not dht_node.isRunning()) - throw std::runtime_error("Node is not yet running."); - dht_node.bootstrap(address, std::to_string(port)); -} - -void neocomm::node::import_nodes( - const std::string &node_file) { - if(not dht_node.isRunning()) - throw std::runtime_error("Node is not yet running."); - msgpack::unpacker upak; - { - std::ifstream import_file(node_file, std::ios::binary - bitor std::ios::ate); - if(not import_file.is_open()) - { - throw std::runtime_error("Failed to open file " + - node_file); - } - auto file_size = import_file.tellg(); - import_file.seekg(0, std::ios::beg); - upak.reserve_buffer(file_size); - import_file.read(upak.buffer(), file_size); - } - - msgpack::object_handle obj_handler; - while(upak.next(obj_handler)) - { - auto imported_nodes = - obj_handler.get().as< - std::vector>(); - dht_node.bootstrap(imported_nodes); - } -} - -void neocomm::node::export_nodes( - const std::string &node_file) { - if(not dht_node.isRunning()) - throw std::runtime_error("Node is not yet running."); - std::ofstream export_file(node_file, std::ios::binary); - if(not export_file.is_open()) - { - throw std::runtime_error("Failed to open file " + - node_file); - } - - msgpack::pack(export_file, dht_node.exportNodes()); +void node::leave_channel(const std::string &name) { + if(!get_channel(name)) + return; + network.cancelListen(channels[name].key, + channels[name].token.get()); + channels.erase(name); }