aboutsummaryrefslogtreecommitdiff
path: root/node
diff options
context:
space:
mode:
authorDennis Brentjes <d.brentjes@gmail.com>2016-10-12 14:26:12 +0200
committerDennis Brentjes <d.brentjes@gmail.com>2016-10-12 14:26:12 +0200
commit7bca48bc5b5e37a3a8b0b23e57b88d069fa50589 (patch)
tree47cd62512e631a064852015c65bb1965bc72414a /node
parent0fb433690c0ca5f9561fe9e2e973e2cd61b873ba (diff)
downloadcmix-7bca48bc5b5e37a3a8b0b23e57b88d069fa50589.tar.gz
cmix-7bca48bc5b5e37a3a8b0b23e57b88d069fa50589.tar.bz2
cmix-7bca48bc5b5e37a3a8b0b23e57b88d069fa50589.zip
Major network rewrite.
One generic class has been introduced to handle all connection types. Typedefs provide Sender Receiver and SenderReceiver types, which limit the functionality of the types. As to not accidentally communicate with the wrong node about things.
Diffstat (limited to 'node')
-rw-r--r--node/CMakeLists.txt2
-rw-r--r--node/nextnode.cpp19
-rw-r--r--node/nextnode.hpp66
-rw-r--r--node/node.cpp82
-rw-r--r--node/node.hpp24
-rw-r--r--node/prevnode.cpp14
-rw-r--r--node/prevnode.hpp42
7 files changed, 34 insertions, 215 deletions
diff --git a/node/CMakeLists.txt b/node/CMakeLists.txt
index 53ca12e..c5ec53f 100644
--- a/node/CMakeLists.txt
+++ b/node/CMakeLists.txt
@@ -3,8 +3,6 @@ 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
)
if(WIN32)
diff --git a/node/nextnode.cpp b/node/nextnode.cpp
deleted file mode 100644
index 8c5b7eb..0000000
--- a/node/nextnode.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-#include "nextnode.hpp"
-
-#include "logging.hpp"
-
-using namespace boost::asio::ip;
-
-NextNode::NextNode(tcp::socket&& socket)
-: client(std::move(socket))
-{}
-
-void NextNode::async_connect(std::string next_host, std::string next_port, std::function<void ()> on_connect)
-{
- client.async_connect(next_host, next_port, on_connect);
-}
-
-void NextNode::close()
-{
- client.close();
-}
diff --git a/node/nextnode.hpp b/node/nextnode.hpp
deleted file mode 100644
index c2e064c..0000000
--- a/node/nextnode.hpp
+++ /dev/null
@@ -1,66 +0,0 @@
-#pragma once
-
-#include "client.hpp"
-
-#include "cmix.pb.h"
-
-#include <boost/asio/ip/tcp.hpp>
-
-/*!
- * \file
- */
-
-/*!
- * MESSAGE_SETTER is a boilerplate macro that generates a setter function for our CMix
- * 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(TYPE, NAME) \
-inline void message_setter(cmix_proto::CMixMessage& m, cmix_proto::TYPE const& v) { \
- *m.mutable_##NAME() = v; \
-} \
-
-MESSAGE_SETTER(Initialization, initialization)
-MESSAGE_SETTER(ImANode, imanode)
-MESSAGE_SETTER(Bye, bye)
-
-#undef MESSAGE_SETTER
-
-/*!
- * \brief The NextNode class represents the next node in the network, will only be sent to.
- */
-class NextNode
-{
- Client client;
-public:
- /*!
- * \brief NextNode
- * \param socket an rvalue reference to the socket it takes ownership and uses to communicate with the next node in the network.
- */
- NextNode(boost::asio::ip::tcp::socket&& socket);
-
- /*!
- * \brief send
- * \param v The CMixMessage type we try to send and first have to wrap in a CMixMessage.
- */
- template <typename T>
- void send(T v) {
- cmix_proto::CMixMessage m;
- message_setter(m, v);
- client.send(m.SerializeAsString());
- }
-
- /*!
- * \brief async_connect
- * \param next_host The host of the next node.
- * \param next_port The port of the next node.
- * \param on_connect The callback to call when the connect was succesfull.
- */
- void async_connect(std::string next_host, std::string next_port, std::function<void()> on_connect);
-
- /*!
- * \brief close This function closes the underlying socket connection.
- */
- void close();
-};
-
diff --git a/node/node.cpp b/node/node.cpp
index db18253..1fd83c2 100644
--- a/node/node.cpp
+++ b/node/node.cpp
@@ -13,8 +13,8 @@ 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))
+, prev_node(ProtobufClient<Receive>(tcp::socket(io_service)))
+, next_node(ProtobufClient<Send>(tcp::socket(io_service)))
, api(get_implementation())
, keypair(api.create_key_pair())
, network_pub_key()
@@ -22,7 +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());
+ next_node.async_send(cmix_proto::ImANode());
if(network_settings.is_first) {
start_initialisation();
}
@@ -41,17 +41,15 @@ void Node::run() {
void Node::accept_handler(boost::asio::ip::tcp::socket&& socket)
{
- purgatory.emplace_back(std::move(socket));
-
- std::list<Client>::iterator it = --purgatory.end();
+ std::list<ProtobufClient<Receive>>::iterator it = purgatory.emplace(purgatory.end(), std::move(socket));
purgatory.back().on_done(
[this, it]() {
purgatory.erase(it);
}
);
- it->receive([this, it](std::vector<uint8_t> const& message_buffer) {
- handle_message(it, message_buffer);
+ it->receive([this, it](cmix_proto::CMixMessage message) {
+ handle_message(it, message);
});
}
@@ -59,18 +57,7 @@ void Node::start_initialisation() {
cmix_proto::Initialization init;
init.set_public_share(keypair.pub, keypair.pub_len);
- next_node.send(init);
-}
-
-cmix_proto::CMixMessage Node::parse_cmix_message(const std::vector<uint8_t>& buffer)
-{
- cmix_proto::CMixMessage message;
- if(!message.ParseFromArray(buffer.data(), buffer.size())) {
- BOOST_LOG_TRIVIAL(error) << "Received something which was not a CMixMessage";
- io_service.stop();
- throw std::runtime_error("Network communication was disrupted in a unrecoverable way.");
- }
- return message;
+ next_node.async_send(init);
}
void Node::handle_initialization(const cmix_proto::Initialization& init)
@@ -95,7 +82,7 @@ void Node::handle_initialization(const cmix_proto::Initialization& init)
cmix_proto::Initialization init;
init.set_public_share(new_shared.data, new_shared.len);
- next_node.send(init);
+ next_node.async_send(init);
free_bignum(&shared);
free_bignum(&mod);
@@ -103,9 +90,8 @@ void Node::handle_initialization(const cmix_proto::Initialization& init)
}
}
-void Node::handle_node_message(const std::vector<uint8_t>& message_buffer)
+void Node::handle_node_message(cmix_proto::CMixMessage message)
{
- cmix_proto::CMixMessage message = parse_cmix_message(message_buffer);
switch(message.contents_case()) {
case cmix_proto::CMixMessage::ContentsCase::kInitialization: {
handle_initialization(message.initialization());
@@ -119,22 +105,20 @@ void Node::handle_node_message(const std::vector<uint8_t>& message_buffer)
BOOST_LOG_TRIVIAL(error) << "handle_node_message: CMixMessage contains unknown contents.";
}
}
- prev_node.receive([this](std::vector<uint8_t> const& buffer) {
- handle_node_message(buffer);
+ prev_node.receive([this](cmix_proto::CMixMessage message) {
+ handle_node_message(message);
});
}
-void Node::handle_client_message(std::list<Client>::iterator handle, const std::vector<uint8_t>& message_buffer)
+void Node::handle_client_message(std::list<SenderReceiver>::iterator handle, cmix_proto::CMixMessage message)
{
- cmix_proto::CMixMessage message = parse_cmix_message(message_buffer);
- BOOST_LOG_TRIVIAL(trace) << "case: " << message.contents_case();
switch(message.contents_case()) {
case cmix_proto::CMixMessage::ContentsCase::kKeyexchange: {
BOOST_LOG_TRIVIAL(trace) << "Deriving shared key";
api.derive_shared_key(keypair, reinterpret_cast<uint8_t const*>(message.keyexchange().public_key().c_str()), true);
- handle->receive([this, handle](std::vector<uint8_t> const& buffer){
- handle_client_message(handle, buffer);
+ handle->receive([this, handle](cmix_proto::CMixMessage message){
+ handle_client_message(handle, message);
});
return;
}
@@ -144,17 +128,6 @@ void Node::handle_client_message(std::list<Client>::iterator handle, const std::
handle->close();
clients.erase(handle);
- if(clients.size() == 0) {
- cmix_proto::Bye bye;
- next_node.send(bye);
-
- io_service.post([this]{
- BOOST_LOG_TRIVIAL(trace) << "Shutting down";
- io_service.stop();
- });
-
- }
-
return;
}
default: {
@@ -165,36 +138,29 @@ void Node::handle_client_message(std::list<Client>::iterator handle, const std::
clients.erase(handle);
}
-void Node::handle_imanode(std::list<Client>::iterator handle) {
+void Node::handle_imanode(std::list<Receiver>::iterator handle) {
handle->on_done([]{});
- prev_node = PrevNode(std::move(*handle));
+ prev_node = make_receiver(std::move(*handle));
purgatory.erase(handle);
- prev_node.receive([this](std::vector<uint8_t> const& message_buffer){
- handle_node_message(message_buffer);
+ prev_node.receive([this](cmix_proto::CMixMessage message){
+ handle_node_message(message);
});
}
-void Node::handle_imaclient(std::list<Client>::iterator handle) {
- std::list<Client>::iterator it = clients.emplace(clients.end(), std::move(*handle));
+void Node::handle_imaclient(std::list<Receiver>::iterator handle) {
+ BOOST_LOG_TRIVIAL(trace) << "Handling imaclient";
+ std::list<SenderReceiver>::iterator it = clients.emplace(clients.end(), make_sender_receiver(std::move(*handle)));
it->on_done([this, it]{
clients.erase(it);
});
purgatory.erase(handle);
- it->receive([this, it](std::vector<uint8_t> buffer) {
- handle_client_message(it, buffer);
+ it->receive([this, it](cmix_proto::CMixMessage message) {
+ handle_client_message(it, message);
});
}
-void Node::handle_message(std::list<Client>::iterator handle, const std::vector<uint8_t>& message_buffer)
+void Node::handle_message(std::list<ProtobufClient<Receive>>::iterator handle, cmix_proto::CMixMessage message)
{
- cmix_proto::CMixMessage message;
- try {
- message = parse_cmix_message(message_buffer);
- } catch(std::runtime_error const& e) {
- purgatory.erase(handle);
- return;
- }
-
switch(message.contents_case()) {
case cmix_proto::CMixMessage::ContentsCase::kImanode: {
handle_imanode(handle);
diff --git a/node/node.hpp b/node/node.hpp
index 44e379f..9f1f3a2 100644
--- a/node/node.hpp
+++ b/node/node.hpp
@@ -1,9 +1,7 @@
#pragma once
#include "server.hpp"
-#include "nodeclient.hpp"
-#include "prevnode.hpp"
-#include "nextnode.hpp"
+#include "protobufclient.hpp"
#include "api.h"
@@ -33,13 +31,13 @@ class Node
{
boost::asio::io_service io_service;
Server server;
- std::list<Client> purgatory;
- std::list<Client> clients;
+ std::list<Receiver> purgatory;
+ std::list<SenderReceiver> clients;
NodeNetworkSettings network_settings;
- PrevNode prev_node;
- NextNode next_node;
+ Receiver prev_node;
+ Sender next_node;
Api api;
KeyPair keypair;
@@ -50,16 +48,14 @@ class Node
void start_precomputation();
void start_initialisation();
- cmix_proto::CMixMessage parse_cmix_message(std::vector<uint8_t> const& buffer);
-
void handle_initialization(cmix_proto::Initialization const& init);
- void handle_node_message(std::vector<uint8_t> const& message_buffer);
+ void handle_node_message(cmix_proto::CMixMessage message);
- void handle_client_message(std::list<Client>::iterator handle, std::vector<uint8_t> const& message_buffer);
+ void handle_client_message(std::list<SenderReceiver>::iterator handle, cmix_proto::CMixMessage message);
- 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);
+ void handle_imanode(std::list<Receiver>::iterator handle);
+ void handle_imaclient(std::list<Receiver>::iterator handle);
+ void handle_message(std::list<ProtobufClient<Receive>>::iterator handle, cmix_proto::CMixMessage message);
public:
diff --git a/node/prevnode.cpp b/node/prevnode.cpp
deleted file mode 100644
index 6af2242..0000000
--- a/node/prevnode.cpp
+++ /dev/null
@@ -1,14 +0,0 @@
-#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
deleted file mode 100644
index 6a6b431..0000000
--- a/node/prevnode.hpp
+++ /dev/null
@@ -1,42 +0,0 @@
-#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();
-};
-