aboutsummaryrefslogtreecommitdiff
path: root/node
diff options
context:
space:
mode:
authorDennis Brentjes <d.brentjes@gmail.com>2016-10-05 12:56:52 +0200
committerDennis Brentjes <d.brentjes@gmail.com>2016-10-05 14:12:28 +0200
commit88c5130eccd06e63ffca732626c0fb59426743a7 (patch)
treef9c7c4536bfa50057269c3636baedea3cb859ac1 /node
parentedc3690d62890449df3ae4c14636019bce4833f1 (diff)
downloadcmix-88c5130eccd06e63ffca732626c0fb59426743a7.tar.gz
cmix-88c5130eccd06e63ffca732626c0fb59426743a7.tar.bz2
cmix-88c5130eccd06e63ffca732626c0fb59426743a7.zip
Seperates Nodes and Clients for incoming connections.
Created a PrevNode class to reflect the seperation. Made Client movable. Added 2 empty protobuf message that declare what each connecting client is, sent when connected to a node.
Diffstat (limited to 'node')
-rw-r--r--node/CMakeLists.txt1
-rw-r--r--node/main.cpp2
-rw-r--r--node/nextnode.hpp9
-rw-r--r--node/node.cpp99
-rw-r--r--node/node.hpp10
-rw-r--r--node/prevnode.cpp14
-rw-r--r--node/prevnode.hpp42
7 files changed, 146 insertions, 31 deletions
diff --git a/node/CMakeLists.txt b/node/CMakeLists.txt
index 9151cbc..53ca12e 100644
--- a/node/CMakeLists.txt
+++ b/node/CMakeLists.txt
@@ -3,6 +3,7 @@ find_package(Boost COMPONENTS system program_options REQUIRED)
add_executable(node
main.cpp
node.hpp node.cpp
+ prevnode.hpp prevnode.cpp
nextnode.hpp nextnode.cpp
)
diff --git a/node/main.cpp b/node/main.cpp
index 1327ac5..031e0d0 100644
--- a/node/main.cpp
+++ b/node/main.cpp
@@ -12,6 +12,8 @@ int main(int argc, char* argv[]) {
init_logging(boost::log::trivial::severity_level::trace);
+ BOOST_LOG_TRIVIAL(info) << "Started node";
+
po::options_description desc("Allowed options");
desc.add_options()
("help,h", "produce help message.")
diff --git a/node/nextnode.hpp b/node/nextnode.hpp
index 9601ab5..862ca5c 100644
--- a/node/nextnode.hpp
+++ b/node/nextnode.hpp
@@ -15,12 +15,13 @@
* protobuf messages, This because there are seperate functions for each to type to use.
* And there seems no way to solve this using templates.
*/
-#define MESSAGE_SETTER(T,F,NAME) \
-inline void message_setter(cmix_proto::CMixMessage& m, cmix_proto::T##NAME const& v) { \
- *m.mutable_##F##NAME() = v; \
+#define MESSAGE_SETTER(TYPE, NAME) \
+inline void message_setter(cmix_proto::CMixMessage& m, cmix_proto::TYPE const& v) { \
+ *m.mutable_##NAME() = v; \
} \
-MESSAGE_SETTER(I,i,nitialization)
+MESSAGE_SETTER(Initialization, initialization)
+MESSAGE_SETTER(ImANode, imanode)
#undef MESSAGE_SETTER
diff --git a/node/node.cpp b/node/node.cpp
index fb5b875..c02e5e6 100644
--- a/node/node.cpp
+++ b/node/node.cpp
@@ -13,6 +13,7 @@ Node::Node(ListenSettings const& listen_settings, NodeNetworkSettings network_se
, server(io_service, listen_settings, [this](boost::asio::ip::tcp::socket&& socket){accept_handler(std::move(socket));})
, clients()
, network_settings(network_settings)
+, prev_node(Client(tcp::socket(io_service)))
, next_node(tcp::socket(io_service))
, api(get_curve25519_implementation())
, keypair(api.create_key_pair())
@@ -21,6 +22,7 @@ Node::Node(ListenSettings const& listen_settings, NodeNetworkSettings network_se
GOOGLE_PROTOBUF_VERIFY_VERSION;
auto on_connect = [this, network_settings](){
+ next_node.send(cmix_proto::ImANode());
if(network_settings.is_first) {
start_initialisation();
}
@@ -39,16 +41,18 @@ void Node::run() {
void Node::accept_handler(boost::asio::ip::tcp::socket&& socket)
{
- clients.emplace_back(std::move(socket));
+ purgatory.emplace_back(std::move(socket));
- auto it = --clients.end();
- clients.back().on_done(
+ std::list<Client>::iterator it = --purgatory.end();
+ purgatory.back().on_done(
[this, it]() {
- clients.erase(it);
+ purgatory.erase(it);
}
);
- it->receive(std::bind(&Node::handle_message, this, std::placeholders::_1));
+ it->receive([this, it](std::vector<uint8_t> const& message_buffer) {
+ handle_message(decltype(it)(it), message_buffer);
+ });
}
void Node::start_initialisation() {
@@ -58,27 +62,6 @@ void Node::start_initialisation() {
next_node.send(init);
}
-void Node::handle_message(const std::vector<uint8_t>& message_buffer)
-{
- cmix_proto::CMixMessage message;
- if(!message.ParseFromArray(message_buffer.data(), message_buffer.size())) {
- BOOST_LOG_TRIVIAL(error) << "Received something which was not a CMixMessage";
- clients.clear();
- io_service.stop();
- return;
- }
-
- switch(message.contents_case()) {
- case cmix_proto::CMixMessage::ContentsCase::kInitialization: {
- handle_initialization(message.initialization());
- break;
- }
- default: {
- BOOST_LOG_TRIVIAL(error) << "CMixMessage contains unknown contents.";
- }
- }
-}
-
void Node::handle_initialization(const cmix_proto::Initialization& init)
{
if(network_settings.is_first) {
@@ -114,6 +97,70 @@ void Node::handle_initialization(const cmix_proto::Initialization& init)
}
}
+void Node::handle_message(const std::vector<uint8_t>& message_buffer)
+{
+ cmix_proto::CMixMessage message;
+ if(!message.ParseFromArray(message_buffer.data(), message_buffer.size())) {
+ BOOST_LOG_TRIVIAL(error) << "Received something which was not a CMixMessage";
+ clients.clear();
+ io_service.stop();
+ return;
+ }
+
+ switch(message.contents_case()) {
+ case cmix_proto::CMixMessage::ContentsCase::kInitialization: {
+ handle_initialization(message.initialization());
+ break;
+ }
+ default: {
+ BOOST_LOG_TRIVIAL(error) << "CMixMessage contains unknown contents.";
+ }
+ }
+}
+
+void Node::handle_imanode(std::list<Client>::iterator handle) {
+ handle->on_done([]{});
+ prev_node = PrevNode(std::move(*handle));
+ purgatory.erase(handle);
+ prev_node.receive([this](std::vector<uint8_t> const& message_buffer){
+ handle_message(message_buffer);
+ });
+}
+
+void Node::handle_imaclient(std::list<Client>::iterator handle) {
+ clients.emplace_back(std::move(*handle));
+ std::list<Client>::iterator it = clients.end()--;
+ it->on_done([this, it]{
+ clients.erase(it);
+ });
+ purgatory.erase(handle);
+}
+
+void Node::handle_message(std::list<Client>::iterator handle, const std::vector<uint8_t>& message_buffer)
+{
+ cmix_proto::CMixMessage message;
+ if(!message.ParseFromArray(message_buffer.data(), message_buffer.size())) {
+ BOOST_LOG_TRIVIAL(error) << "Received something which was not a CMixMessage";
+ clients.clear();
+ io_service.stop();
+ return;
+ }
+
+ switch(message.contents_case()) {
+ case cmix_proto::CMixMessage::ContentsCase::kImanode: {
+ handle_imanode(handle);
+ break;
+ }
+ case cmix_proto::CMixMessage::ContentsCase::kImaclient: {
+ handle_imaclient(handle);
+ break;
+ }
+ default: {
+ BOOST_LOG_TRIVIAL(error) << "CMixMessage contains unknown contents.";
+ }
+ }
+}
+
void Node::start_precomputation() {
clients.clear();
io_service.stop();
diff --git a/node/node.hpp b/node/node.hpp
index a481c70..a4e21b3 100644
--- a/node/node.hpp
+++ b/node/node.hpp
@@ -2,6 +2,7 @@
#include "server.hpp"
#include "nodeclient.hpp"
+#include "prevnode.hpp"
#include "nextnode.hpp"
#include "api.h"
@@ -33,10 +34,12 @@ class Node
{
boost::asio::io_service io_service;
Server server;
+ std::list<Client> purgatory;
std::list<Client> clients;
NodeNetworkSettings network_settings;
+ PrevNode prev_node;
NextNode next_node;
Api api;
@@ -48,8 +51,13 @@ class Node
void start_precomputation();
void start_initialisation();
- void handle_message(std::vector<uint8_t> const& message_buffer);
void handle_initialization(cmix_proto::Initialization const& init);
+ void handle_message(std::vector<uint8_t> const& message_buffer);
+
+ void handle_imanode(std::list<Client>::iterator handle);
+ void handle_imaclient(std::list<Client>::iterator handle);
+ void handle_message(std::list<Client>::iterator handle, std::vector<uint8_t> const& message_buffer);
+
public:
/*!
diff --git a/node/prevnode.cpp b/node/prevnode.cpp
new file mode 100644
index 0000000..6af2242
--- /dev/null
+++ b/node/prevnode.cpp
@@ -0,0 +1,14 @@
+#include "prevnode.hpp"
+
+PrevNode::PrevNode(Client&& client)
+: client(std::move(client))
+{}
+
+void PrevNode::receive(std::function<void (const std::vector<uint8_t>&)> receive_handler) {
+ client.receive(receive_handler);
+}
+
+void PrevNode::close()
+{
+ client.close();
+}
diff --git a/node/prevnode.hpp b/node/prevnode.hpp
new file mode 100644
index 0000000..6a6b431
--- /dev/null
+++ b/node/prevnode.hpp
@@ -0,0 +1,42 @@
+#pragma once
+
+#include "client.hpp"
+
+#include "cmix.pb.h"
+
+#include <boost/asio/ip/tcp.hpp>
+
+/*!
+ * \file
+ */
+
+/*!
+ * \brief The PrevNode class represents the previous node in the network, will only be received from.
+ */
+class PrevNode
+{
+ Client client;
+public:
+ /*!
+ * \brief PrevNode
+ * \param socket an rvalue reference to the socket it takes ownership and uses to communicate with the previous node in the network.
+ */
+ PrevNode(Client&& socket);
+
+ /*!
+ * \brief PrevNode move assignment operator.
+ */
+ PrevNode& operator=(PrevNode&&) = default;
+
+ /*!
+ * \brief receive Forwards a receive request to the client.
+ * \param receive_handler The function to call with the received data.
+ */
+ void receive(std::function<void(std::vector<uint8_t> const&)> receive_handler);
+
+ /*!
+ * \brief close This function closes the underlying socket connection.
+ */
+ void close();
+};
+