diff --git a/include/neocomm/node.hpp b/include/neocomm/node.hpp index 0260e46..00d50f9 100644 --- a/include/neocomm/node.hpp +++ b/include/neocomm/node.hpp @@ -48,6 +48,28 @@ public: unsigned short port = 8085); ~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); + private: dht::DhtRunner dht_node; }; diff --git a/src/node.cpp b/src/node.cpp index 05a0753..aaaa369 100644 --- a/src/node.cpp +++ b/src/node.cpp @@ -18,10 +18,94 @@ #include "neocomm/node.hpp" +#include +#include +#include + neocomm::node::node(unsigned short port) { - dht_node.run(port, dht::crypto::generateIdentity(), true); +#ifdef WOE32 + gnutls_global_init(); +#endif + try { + dht_node.run(port, + dht::crypto::generateIdentity(), true); + } + catch(const std::exception &e) + { + // rethrow exception + throw e; + } +} + +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; + } } neocomm::node::~node() { dht_node.join(); +#ifdef WOE32 + gnutls_global_deinit(); +#endif +} + +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()); }