aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt3
-rw-r--r--client/CMakeLists.txt1
-rw-r--r--client/cmixclient.cpp38
-rw-r--r--client/cmixclient.hpp9
-rw-r--r--client/node.cpp23
-rw-r--r--client/node.hpp72
-rw-r--r--libcmix-network/CMakeLists.txt3
-rw-r--r--libcmix-network/client.cpp36
-rw-r--r--libcmix-network/client.hpp37
-rw-r--r--libcmix-network/nodeclient.cpp22
-rw-r--r--libcmix-network/nodeclient.hpp49
-rw-r--r--libcmix-network/protobufclient.cpp0
-rw-r--r--libcmix-network/protobufclient.hpp148
-rw-r--r--libcmix-protobuf/cmix.proto2
-rw-r--r--network-handler/CMakeLists.txt21
-rw-r--r--network-handler/main.cpp49
-rw-r--r--network-handler/networkhandler.cpp32
-rw-r--r--network-handler/networkhandler.hpp51
-rw-r--r--network-handler/nodemanager.cpp14
-rw-r--r--network-handler/nodemanager.hpp56
-rw-r--r--network-handler/userclient.cpp21
-rw-r--r--network-handler/userclient.hpp46
-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
29 files changed, 236 insertions, 746 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 92b61d9..5056777 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -27,11 +27,10 @@ add_subdirectory(libcmix-crypto)
add_subdirectory(libcmix)
add_subdirectory(liblog)
-add_subdirectory(libcmix-network)
add_subdirectory(libcmix-protobuf)
+add_subdirectory(libcmix-network)
-add_subdirectory(network-handler)
add_subdirectory(node)
add_subdirectory(client)
diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt
index e04bf6a..489a136 100644
--- a/client/CMakeLists.txt
+++ b/client/CMakeLists.txt
@@ -3,7 +3,6 @@ find_package(Boost COMPONENTS system program_options REQUIRED)
add_executable(client
main.cpp
cmixclient.hpp cmixclient.cpp
- node.hpp node.cpp
)
if(WIN32)
diff --git a/client/cmixclient.cpp b/client/cmixclient.cpp
index 195c5e0..1ffd904 100644
--- a/client/cmixclient.cpp
+++ b/client/cmixclient.cpp
@@ -2,15 +2,16 @@
#include "cmixclient.hpp"
void CMixClient::key_exchange(int i) {
- shared_keys.resize(network_connections.size());
+ BOOST_LOG_TRIVIAL(trace) << "Sending KeyExchange for node: " << i;
+ shared_keys.resize(network_details.size());
cmix_proto::KeyExchange ke;
ke.set_public_key(keypair.pub, keypair.pub_len);
- network_connections[i].send(ke);
+ network_connections[i].async_send(ke);
cmix_proto::Bye bye;
- network_connections[i].send(bye);
+ network_connections[i].async_send(bye);
}
void CMixClient::initialize_connections() {
@@ -20,25 +21,14 @@ void CMixClient::initialize_connections() {
auto handler = [this, i]() mutable {
cmix_proto::ImAClient imaclient;
BOOST_LOG_TRIVIAL(trace) << "sending imaclient to node: " << i;
- network_connections.at(i).send(imaclient);
+ network_connections.at(i).async_send(imaclient);
key_exchange(i);
};
network_connections.emplace_back(boost::asio::ip::tcp::socket(io_service));
network_connections.back().async_connect(network_details[i].host, network_details[i].port, handler);
-
- }
-}
-
-cmix_proto::CMixMessage CMixClient::parse_cmix_message(std::vector<uint8_t> const& buffer)
-{
- cmix_proto::CMixMessage message;
- if(!message.ParseFromArray(buffer.data(), buffer.size())) {
- BOOST_LOG_TRIVIAL(error) << "Received something which was not a CMixMessage";
- throw std::runtime_error("Network communication was disrupted in a unrecoverable way.");
}
- return message;
}
void CMixClient::handle_key_exchange(int node_id, cmix_proto::KeyExchange const& ke)
@@ -46,19 +36,8 @@ void CMixClient::handle_key_exchange(int node_id, cmix_proto::KeyExchange const&
shared_keys[node_id] = api.derive_shared_key(keypair, reinterpret_cast<uint8_t const*>(ke.public_key().c_str()), false);
}
-void CMixClient::handle_message(int node_id, std::vector<uint8_t> const& message_buffer)
+void CMixClient::handle_message(int node_id, cmix_proto::CMixMessage message)
{
- cmix_proto::CMixMessage message;
- try {
- message = parse_cmix_message(message_buffer);
- } catch(std::runtime_error const& e) {
- for(auto&& connection : network_connections) {
- connection.close();
- }
- io_service.stop();
- return;
- }
-
switch(message.contents_case()) {
case cmix_proto::CMixMessage::ContentsCase::kKeyexchange: {
handle_key_exchange(node_id, *message.mutable_keyexchange());
@@ -85,6 +64,11 @@ CMixClient::CMixClient(std::vector<NodeDetails> details)
initialize_connections();
}
+CMixClient::~CMixClient()
+{
+ api.free_key_pair(keypair);
+}
+
void CMixClient::run() {
io_service.run();
}
diff --git a/client/cmixclient.hpp b/client/cmixclient.hpp
index 5c6405a..056e2b3 100644
--- a/client/cmixclient.hpp
+++ b/client/cmixclient.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "node.hpp"
+#include "protobufclient.hpp"
#include "api.h"
#include "logging.hpp"
@@ -21,7 +21,7 @@ class CMixClient {
boost::asio::io_service io_service;
std::vector<NodeDetails> network_details;
- std::vector<Node> network_connections;
+ std::vector<ProtobufClient<SendReceive>> network_connections;
Api api;
KeyPair keypair;
@@ -31,14 +31,13 @@ class CMixClient {
void initialize_connections();
- cmix_proto::CMixMessage parse_cmix_message(std::vector<uint8_t> const& buffer);
-
void handle_key_exchange(int node_id, cmix_proto::KeyExchange const& ke);
- void handle_message(int node_id, std::vector<uint8_t> const& message_buffer);
+ void handle_message(int node_id, cmix_proto::CMixMessage message);
public:
CMixClient(std::vector<NodeDetails> details);
+ ~CMixClient();
void run();
}; \ No newline at end of file
diff --git a/client/node.cpp b/client/node.cpp
deleted file mode 100644
index 46375f4..0000000
--- a/client/node.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-#include "node.hpp"
-
-#include "logging.hpp"
-
-using namespace boost::asio::ip;
-
-Node::Node(tcp::socket&& socket)
-: client(std::move(socket))
-{}
-
-void Node::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 Node::receive(std::function<void (const std::vector<uint8_t>&)> receive_handler) {
- client.receive(receive_handler);
-}
-
-void Node::close()
-{
- client.close();
-}
diff --git a/client/node.hpp b/client/node.hpp
deleted file mode 100644
index afcf56a..0000000
--- a/client/node.hpp
+++ /dev/null
@@ -1,72 +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(ImAClient, imaclient)
-MESSAGE_SETTER(Bye, bye)
-MESSAGE_SETTER(KeyExchange, keyexchange)
-
-#undef MESSAGE_SETTER
-
-/*!
- * \brief The Node class represents a node in the network.
- */
-class Node
-{
- Client client;
-public:
- /*!
- * \brief Node
- * \param socket an rvalue reference to the socket it takes ownership and uses to communicate with the next node in the network.
- */
- Node(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 receive
- * \param receive_handler
- */
- void receive(std::function<void(std::vector<uint8_t> const&)> receive_handler);
-
- /*!
- * \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/libcmix-network/CMakeLists.txt b/libcmix-network/CMakeLists.txt
index 5891254..c64c8b7 100644
--- a/libcmix-network/CMakeLists.txt
+++ b/libcmix-network/CMakeLists.txt
@@ -9,7 +9,7 @@ add_library(cmix-network
connect.hpp connect.cpp
server.hpp server.cpp
client.hpp client.cpp
- nodeclient.hpp nodeclient.cpp
+ protobufclient.hpp protobufclient.cpp
uriparser.hpp uriparser.cpp
)
@@ -27,6 +27,7 @@ target_link_libraries(cmix-network
PUBLIC ${CMAKE_THREAD_LIBS_INIT}
PRIVATE cmix
PRIVATE log
+ PRIVATE cmix-protobuf
)
if(WIN32)
diff --git a/libcmix-network/client.cpp b/libcmix-network/client.cpp
index f693afa..755989b 100644
--- a/libcmix-network/client.cpp
+++ b/libcmix-network/client.cpp
@@ -2,13 +2,6 @@
#include "connect.hpp"
-#include "logging.hpp"
-
-#include <boost/asio/placeholders.hpp>
-#include <boost/bind.hpp>
-#include <boost/asio/buffer.hpp>
-#include <boost/array.hpp>
-
#include <iostream>
using namespace boost::asio::ip;
@@ -39,26 +32,6 @@ std::array<uint8_t, 4> Client::prepare_length_prefix(uint32_t length)
return buf;
}
-void Client::send(std::string message) {
-
- auto length_buffer = prepare_length_prefix(message.size());
-
- boost::array<boost::asio::const_buffer, 2> package = {
- boost::asio::buffer(length_buffer.data(), length_buffer.size()),
- boost::asio::buffer(message)
- };
-
- auto handler = [](boost::system::error_code const& ec, std::size_t bytes_transferred) {
- if(ec) {
- BOOST_LOG_TRIVIAL(fatal) << ec;
- throw std::runtime_error("unable to send message");
- }
- };
-
- socket.async_send(package, 0, handler);
-
-}
-
std::vector<uint8_t> Client::received_bytes_to_vector(size_t read_bytes)
{
buffer->commit(read_bytes);
@@ -103,15 +76,6 @@ void Client::handle_receive_size(Client::MessageHandler message_handler, error_c
}
}
-void Client::receive(MessageHandler message_handler) {
- using namespace boost::asio::placeholders;
-
- socket.async_receive(
- buffer->prepare(4),
- boost::bind(&Client::handle_receive_size, this, message_handler, error(), bytes_transferred())
- );
-}
-
void Client::close()
{
socket.close();
diff --git a/libcmix-network/client.hpp b/libcmix-network/client.hpp
index dc3787d..7bfea7d 100644
--- a/libcmix-network/client.hpp
+++ b/libcmix-network/client.hpp
@@ -1,7 +1,13 @@
#pragma once
+#include "logging.hpp"
+
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/streambuf.hpp>
+#include <boost/asio/placeholders.hpp>
+#include <boost/bind.hpp>
+#include <boost/asio/buffer.hpp>
+#include <boost/array.hpp>
#include <array>
@@ -69,17 +75,44 @@ public:
*/
void async_connect(std::string next_host, std::string next_port, std::function<void()> on_connect);
+ inline static void foo() {}
+
/*!
* \brief send sends the string prefixed with it's length over the socket.
* \param message The string to be sent.
*/
- void send(std::string message);
+ template <typename F>
+ void async_send(std::string message, F on_sent) {
+ auto length_buffer = prepare_length_prefix(message.size());
+
+ boost::array<boost::asio::const_buffer, 2> package = {
+ boost::asio::buffer(length_buffer.data(), length_buffer.size()),
+ boost::asio::buffer(message)
+ };
+
+ auto handler = [on_sent](boost::system::error_code const& ec, std::size_t bytes_transferred) {
+ if(ec) {
+ BOOST_LOG_TRIVIAL(fatal) << ec;
+ throw std::runtime_error("unable to send message");
+ }
+ on_sent();
+ };
+
+ socket.async_send(package, 0, handler);
+ }
/*!
* \brief receive
* \param message_handler The function to call when a message has been received.
*/
- void receive(MessageHandler message_handler);
+ void receive(MessageHandler message_handler) {
+ using namespace boost::asio::placeholders;
+
+ socket.async_receive(
+ buffer->prepare(4),
+ boost::bind(&Client::handle_receive_size, this, message_handler, error(), bytes_transferred())
+ );
+ }
/*!
* \brief close Closes the underlying socket.
diff --git a/libcmix-network/nodeclient.cpp b/libcmix-network/nodeclient.cpp
deleted file mode 100644
index 9b026ba..0000000
--- a/libcmix-network/nodeclient.cpp
+++ /dev/null
@@ -1,22 +0,0 @@
-#include "nodeclient.hpp"
-
-#include <iostream>
-
-NodeClient::NodeClient(boost::asio::ip::tcp::socket &&socket)
-: client(std::move(socket))
-{}
-
-void NodeClient::handle_message(std::vector<uint8_t> message)
-{
- std::cout << std::string(message.begin(), message.end()) << std::endl;
-}
-
-void NodeClient::receive()
-{
- client.receive(std::bind(&NodeClient::handle_message, this, std::placeholders::_1));
-}
-
-void NodeClient::on_done(Client::OnDoneFT done) {
- client.on_done(done);
-}
-
diff --git a/libcmix-network/nodeclient.hpp b/libcmix-network/nodeclient.hpp
deleted file mode 100644
index ca1ee67..0000000
--- a/libcmix-network/nodeclient.hpp
+++ /dev/null
@@ -1,49 +0,0 @@
-#pragma once
-
-#include "client.hpp"
-
-#include <boost/asio/ip/tcp.hpp>
-
-#include <vector>
-
-/*!
- * \file
- */
-
-/*!
- * \brief The NodeClient class
- */
-class NodeClient
-{
- /*!
- * \brief client
- */
- Client client;
-
- /*!
- * \brief handle_message
- * \param message
- */
- void handle_message(std::vector<uint8_t> message);
-
-public:
-
- /*!
- * \brief NodeClient
- * \param socket
- */
- NodeClient(boost::asio::ip::tcp::socket&& socket);
-
- virtual ~NodeClient() = default;
-
- /*!
- * \brief receive
- */
- void receive();
-
- /*!
- * \brief on_done
- * \param done
- */
- void on_done(Client::OnDoneFT done);
-};
diff --git a/libcmix-network/protobufclient.cpp b/libcmix-network/protobufclient.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libcmix-network/protobufclient.cpp
diff --git a/libcmix-network/protobufclient.hpp b/libcmix-network/protobufclient.hpp
new file mode 100644
index 0000000..1c97cfa
--- /dev/null
+++ b/libcmix-network/protobufclient.hpp
@@ -0,0 +1,148 @@
+#pragma once
+
+#include "client.hpp"
+
+#include "logging.hpp"
+#include "cmix.pb.h"
+
+#include <type_traits>
+
+struct Send;
+struct Receive;
+struct SendReceive;
+
+template<typename T>
+class ProtobufClient;
+
+typedef ProtobufClient<Receive> Receiver;
+typedef ProtobufClient<Send> Sender;
+typedef ProtobufClient<SendReceive> SenderReceiver;
+
+template<typename T = SendReceive>
+class ProtobufClient
+{
+ Client client;
+
+
+ #define MESSAGE_SETTER(TYPE, NAME) \
+ 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(ImAClient, imaclient)
+ MESSAGE_SETTER(Bye, bye)
+ MESSAGE_SETTER(KeyExchange, keyexchange)
+
+ #undef MESSAGE_SETTER
+
+public:
+ /*!
+ * \brief ProtobufClient
+ * \param socket An rvalue reference to a socket it will now own and receive from.
+ */
+ ProtobufClient(boost::asio::ip::tcp::socket&& socket)
+ : client(std::move(socket))
+ {}
+
+ /*!
+ * \brief Move constructor for ProtobufClient.
+ */
+ ProtobufClient(ProtobufClient&& c) = default;
+
+ ProtobufClient(Client&& c)
+ : client(std::move(c))
+ {}
+
+ template<typename Ty>
+ ProtobufClient(ProtobufClient<Ty>&& r)
+ : client(std::move(r.client))
+ {}
+
+ /*!
+ * \brief Move assignment for ProtobufClient.
+ */
+ ProtobufClient& operator=(ProtobufClient&&) = default;
+
+ /*!
+ * \brief async_connect Asynchronously connects to next_host:port and calls on_connect
+ * \param next_host The host to connect to
+ * \param next_port The port to connect to
+ * \param on_connect The callback to call on a succes.
+ */
+ template<typename F>
+ void async_connect(std::string next_host, std::string next_port, F on_connect) {
+ client.async_connect(next_host, next_port, on_connect);
+ }
+
+
+ template<typename V, typename F, typename std::enable_if<(sizeof(V), std::is_same<T, Send>::value || std::is_same<T, SendReceive>::value), void>::type* = nullptr>
+ void async_send(V value, F on_sent) {
+ cmix_proto::CMixMessage m;
+ message_setter(m, value);
+ client.async_send(m.SerializeAsString(), on_sent);
+ }
+
+ /*!
+ * \brief send sends the string prefixed with it's length over the socket asynchronously.
+ * \param message The string to be sent.
+ */
+ template<typename V, typename std::enable_if<(sizeof(V), std::is_same<T, Send>::value || std::is_same<T, SendReceive>::value)>::type* = nullptr>
+ void async_send(V value) {
+ cmix_proto::CMixMessage m;
+ message_setter(m, value);
+ client.async_send(m.SerializeAsString(), []{});
+ }
+
+ /*!
+ * \brief receive
+ * \param message_handler The function to call when a message has been received.
+ */
+ template <typename F, typename std::enable_if<(sizeof(F), std::is_same<T, Receive>::value || std::is_same<T, SendReceive>::value)>::type* = nullptr>
+ void receive(F message_handler) {
+ auto f = [message_handler](std::vector<uint8_t> const& buffer) {
+ cmix_proto::CMixMessage message;
+ if(!message.ParseFromArray(buffer.data(), buffer.size())) {
+ BOOST_LOG_TRIVIAL(error) << "Received something which was not a CMixMessage";
+ throw std::runtime_error("Network communication was disrupted in a unrecoverable way.");
+ }
+ message_handler(message);
+ };
+ client.receive(f);
+ }
+
+ /*!
+ * \brief close Closes the underlying socket.
+ */
+ void close(){
+ client.close();
+ }
+
+ /*!
+ * \brief on_done sets the done callback.
+ * \param f The new done callback function.
+ */
+ template <typename F>
+ void on_done(F f) {
+ client.on_done(f);
+ }
+
+ friend Receiver make_receiver(Receiver&& r);
+
+ friend SenderReceiver make_sender_receiver(SenderReceiver&& r);
+ friend SenderReceiver make_sender_receiver(Receiver&& r);
+};
+
+inline Receiver make_receiver(Receiver&& r) {
+ return Receiver(std::move(r.client));
+}
+
+inline SenderReceiver make_sender_receiver(SenderReceiver&& r) {
+ return SenderReceiver(std::move(r.client));
+}
+
+inline SenderReceiver make_sender_receiver(Receiver&& r)
+{
+ return SenderReceiver(std::move(r.client));
+}
diff --git a/libcmix-protobuf/cmix.proto b/libcmix-protobuf/cmix.proto
index 8bbc303..e098cdf 100644
--- a/libcmix-protobuf/cmix.proto
+++ b/libcmix-protobuf/cmix.proto
@@ -26,6 +26,6 @@ message CMixMessage {
ImANode imanode = 2;
ImAClient imaclient = 3;
Bye bye = 4;
- KeyExchange keyexchange= 5;
+ KeyExchange keyexchange = 5;
}
}
diff --git a/network-handler/CMakeLists.txt b/network-handler/CMakeLists.txt
deleted file mode 100644
index 072172e..0000000
--- a/network-handler/CMakeLists.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-
-find_package(Boost COMPONENTS system program_options REQUIRED)
-
-add_executable(network-handler
- main.cpp
- networkhandler.hpp networkhandler.cpp
- userclient.hpp userclient.cpp
- nodemanager.hpp nodemanager.cpp
-)
-
-target_compile_options(network-handler
- PRIVATE "-std=c++11"
-)
-
-target_link_libraries(network-handler
- PRIVATE Boost::boost
- PRIVATE Boost::program_options
- PRIVATE Boost::system
- PRIVATE cmix
- PRIVATE cmix-network
-)
diff --git a/network-handler/main.cpp b/network-handler/main.cpp
deleted file mode 100644
index 84de894..0000000
--- a/network-handler/main.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-
-#include "networkhandler.hpp"
-#include "nodemanager.hpp"
-
-#include <boost/program_options.hpp>
-
-#include <string>
-#include <iostream>
-#include <cstdint>
-
-NodeManager key_exchange_phase();
-
-int main(int argc, char* argv[]) {
- namespace po = boost::program_options;
-
- po::options_description desc("Allowed options");
- desc.add_options()
- ("help,h", "produce help message.")
- ("port,p", po::value<uint16_t>()->default_value(9200), "Set listening port.")
- ("enable_v4", po::value<bool>()->default_value(true), "Enable/disable ipv4 accept support.")
- ("interface4,4", po::value<std::string>()->default_value("0.0.0.0"), "Set the ipv4 address to listen on.")
- ("enable_v6", po::value<bool>()->default_value(true), "Enable/disable ipv6 accept support.")
- ("interface6,6", po::value<std::string>()->default_value("::"), "Set the ipv6 address to listen on.")
- ("nodes,n", po::value<std::string>(), "Set the node addreses to use in the cmix network.")
- ;
-
- po::variables_map vm;
- po::store(po::parse_command_line(argc, argv, desc), vm);
- po::notify(vm);
-
- if (vm.count("help")) {
- std::cout << desc << "\n";
- return 0;
- }
-
- bool en4 = vm["enable_v4"].as<bool>();
- std::string if4 = vm["interface4"].as<std::string>();
- bool en6 = vm["enable_v6"].as<bool>();
- std::string if6 = vm["interface6"].as<std::string>();
- uint16_t port = vm["port"].as<uint16_t>();
-
- NodeManager node_manager({});
-
- ListenSettings lsettings{en4, if4, en6, if6, port};
-
- NetworkHandler handler(lsettings);
- handler.run();
-}
-
diff --git a/network-handler/networkhandler.cpp b/network-handler/networkhandler.cpp
deleted file mode 100644
index 614d270..0000000
--- a/network-handler/networkhandler.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-#include "networkhandler.hpp"
-
-#include <boost/bind.hpp>
-#include <boost/asio/placeholders.hpp>
-
-#include <memory>
-#include <iostream>
-
-NetworkHandler::NetworkHandler(const ListenSettings& listen_settings)
-: io_service()
-, server(io_service, listen_settings, [this](boost::asio::ip::tcp::socket&& socket){accept_handler(std::move(socket));})
-, clients()
-{}
-
-void NetworkHandler::accept_handler(boost::asio::ip::tcp::socket&& socket)
-{
- std::list<UserClient>::iterator it = clients.emplace(clients.end(), std::move(socket));
- clients.back().on_done(
- [this, it]() {
- clients.erase(it);
- }
- );
-
- clients.back().receive();
-}
-
-void NetworkHandler::run()
-{
- io_service.run();
-}
-
-
diff --git a/network-handler/networkhandler.hpp b/network-handler/networkhandler.hpp
deleted file mode 100644
index e9bb7fa..0000000
--- a/network-handler/networkhandler.hpp
+++ /dev/null
@@ -1,51 +0,0 @@
-#pragma once
-
-#include "server.hpp"
-#include "userclient.hpp"
-
-#include <boost/asio/io_service.hpp>
-
-#include <list>
-
-/*!
- * \file
- */
-
-/*!
- * \brief The NetworkHandler class
- */
-class NetworkHandler
-{
- /*!
- * \brief io_service
- */
- boost::asio::io_service io_service;
-
- /*!
- * \brief server
- */
- Server server;
-
- /*!
- * \brief clients
- */
- std::list<UserClient> clients;
-
- /*!
- * \brief accept_handler
- * \param socket
- */
- void accept_handler(boost::asio::ip::tcp::socket&& socket);
-
-public:
- /*!
- * \brief NetworkHandler
- * \param listen_settings
- */
- NetworkHandler(ListenSettings const& listen_settings);
-
- /*!
- * \brief run
- */
- void run();
-};
diff --git a/network-handler/nodemanager.cpp b/network-handler/nodemanager.cpp
deleted file mode 100644
index 165cb3b..0000000
--- a/network-handler/nodemanager.cpp
+++ /dev/null
@@ -1,14 +0,0 @@
-#include "nodemanager.hpp"
-
-#include "connect.hpp"
-
-NodeManager::NodeManager(std::vector<ConnectionInfo> connections)
-: io_service()
-, api(get_curve25519_implementation())
-, key_pair(api.create_key_pair())
-, nodes()
-{
- for(auto&& ci : connections) {
- nodes.emplace_back(connect(ci.host, ci.port, io_service));
- }
-}
diff --git a/network-handler/nodemanager.hpp b/network-handler/nodemanager.hpp
deleted file mode 100644
index 91d7160..0000000
--- a/network-handler/nodemanager.hpp
+++ /dev/null
@@ -1,56 +0,0 @@
-#pragma once
-
-#include "nodeclient.hpp"
-#include "api.h"
-#include "curve25519.h"
-
-#include <list>
-
-/*!
- * \file
- */
-
-/*!
- * \brief The ConnectionInfo struct
- */
-struct ConnectionInfo {
- std::string host; ///< The host
- std::string port; ///< The port
-};
-
-/*!
- * \brief The NodeManager class
- *
- * This class will probably never be fleshed out.
- */
-class NodeManager
-{
- /*!
- * \brief io_service
- */
- boost::asio::io_service io_service;
-
- /*!
- * \brief api
- */
- Api api;
-
- /*!
- * \brief key_pair
- */
- KeyPair key_pair;
-
- /*!
- * \brief nodes
- */
- std::list<NodeClient> nodes;
-public:
-
- /*!
- * \brief NodeManager
- * \param connections
- */
- NodeManager(std::vector<ConnectionInfo> connections);
-
-
-};
diff --git a/network-handler/userclient.cpp b/network-handler/userclient.cpp
deleted file mode 100644
index bf4eaa4..0000000
--- a/network-handler/userclient.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
-#include "userclient.hpp"
-
-#include <iostream>
-
-void UserClient::handle_message(std::vector<uint8_t> message)
-{
- std::cout << std::string(message.begin(), message.end());
-}
-
-UserClient::UserClient(boost::asio::ip::tcp::socket&& socket)
-: client(std::move(socket))
-{}
-
-void UserClient::receive()
-{
- client.receive(std::bind(&UserClient::handle_message, this, std::placeholders::_1));
-}
-
-void UserClient::on_done(Client::OnDoneFT done) {
- client.on_done(done);
-}
diff --git a/network-handler/userclient.hpp b/network-handler/userclient.hpp
deleted file mode 100644
index af810a7..0000000
--- a/network-handler/userclient.hpp
+++ /dev/null
@@ -1,46 +0,0 @@
-#pragma once
-
-#include <boost/asio/ip/tcp.hpp>
-
-#include "client.hpp"
-
-/*!
- * \file
- */
-
-/*!
- * \brief The UserClient class
- */
-class UserClient
-{
- /*!
- * \brief client
- */
- Client client;
-
- /*!
- * \brief handle_message
- * \param message
- */
- void handle_message(std::vector<uint8_t> message);
-
-public:
- /*!
- * \brief UserClient
- * \param socket
- */
- UserClient(boost::asio::ip::tcp::socket&& socket);
- virtual ~UserClient() = default;
-
- /*!
- * \brief receive
- */
- void receive();
-
- /*!
- * \brief on_done
- * \param done
- */
- void on_done(Client::OnDoneFT done);
-
-};
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();
-};
-