aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt1
-rw-r--r--client/CMakeLists.txt1
-rw-r--r--client/cmixclient.hpp4
-rw-r--r--libcmix-common/CMakeLists.txt16
-rw-r--r--libcmix-common/cmixprotofunctor.cpp16
-rw-r--r--libcmix-common/cmixprotofunctor.hpp19
-rw-r--r--libcmix-common/receiver.hpp24
-rw-r--r--libcmix-common/sender.hpp24
-rw-r--r--libcmix-common/senderreceiver.cpp10
-rw-r--r--libcmix-common/senderreceiver.hpp28
-rw-r--r--libcmix-network/CMakeLists.txt3
-rw-r--r--libcmix-network/client.hpp4
-rw-r--r--libcmix-network/protobufclient.hpp141
-rw-r--r--node/CMakeLists.txt1
-rw-r--r--node/node.cpp24
-rw-r--r--node/node.hpp6
16 files changed, 178 insertions, 144 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5056777..f30c66e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -31,6 +31,7 @@ add_subdirectory(liblog)
add_subdirectory(libcmix-protobuf)
add_subdirectory(libcmix-network)
+add_subdirectory(libcmix-common)
add_subdirectory(node)
add_subdirectory(client)
diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt
index 489a136..68a37da 100644
--- a/client/CMakeLists.txt
+++ b/client/CMakeLists.txt
@@ -25,4 +25,5 @@ target_link_libraries(client
PRIVATE cmix-bignum
PRIVATE cmix-network
PRIVATE cmix-protobuf
+ PRIVATE cmix-common
)
diff --git a/client/cmixclient.hpp b/client/cmixclient.hpp
index 056e2b3..71be7c9 100644
--- a/client/cmixclient.hpp
+++ b/client/cmixclient.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "protobufclient.hpp"
+#include "senderreceiver.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<ProtobufClient<SendReceive>> network_connections;
+ std::vector<SenderReceiver> network_connections;
Api api;
KeyPair keypair;
diff --git a/libcmix-common/CMakeLists.txt b/libcmix-common/CMakeLists.txt
new file mode 100644
index 0000000..0861e95
--- /dev/null
+++ b/libcmix-common/CMakeLists.txt
@@ -0,0 +1,16 @@
+
+add_library(cmix-common
+ cmixprotofunctor.hpp cmixprotofunctor.cpp
+ receiver.hpp
+ sender.hpp
+ senderreceiver.hpp senderreceiver.cpp
+)
+
+target_include_directories(cmix-common
+ PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
+)
+
+target_link_libraries(cmix-common
+ PRIVATE cmix-protobuf
+ PRIVATE cmix-network
+) \ No newline at end of file
diff --git a/libcmix-common/cmixprotofunctor.cpp b/libcmix-common/cmixprotofunctor.cpp
new file mode 100644
index 0000000..a026628
--- /dev/null
+++ b/libcmix-common/cmixprotofunctor.cpp
@@ -0,0 +1,16 @@
+#include "cmixprotofunctor.hpp"
+
+#define MESSAGE_SETTER_DEF(TYPE, NAME) \
+ CMixProtoFunctor::proto_type CMixProtoFunctor::operator()(cmix_proto::TYPE const& v) { \
+ proto_type m; \
+ *m.mutable_##NAME() = v; \
+ return m; \
+ } \
+
+MESSAGE_SETTER_DEF(Initialization, initialization)
+MESSAGE_SETTER_DEF(ImANode, imanode)
+MESSAGE_SETTER_DEF(ImAClient, imaclient)
+MESSAGE_SETTER_DEF(Bye, bye)
+MESSAGE_SETTER_DEF(KeyExchange, keyexchange)
+
+#undef MESSAGE_SETTER_DEF \ No newline at end of file
diff --git a/libcmix-common/cmixprotofunctor.hpp b/libcmix-common/cmixprotofunctor.hpp
new file mode 100644
index 0000000..c15f218
--- /dev/null
+++ b/libcmix-common/cmixprotofunctor.hpp
@@ -0,0 +1,19 @@
+#pragma once
+
+#include "cmix.pb.h"
+
+struct CMixProtoFunctor {
+
+ typedef cmix_proto::CMixMessage proto_type;
+
+ #define MESSAGE_SETTER_DECL(TYPE) \
+ proto_type operator()(cmix_proto::TYPE const& v)
+
+ MESSAGE_SETTER_DECL(Initialization);
+ MESSAGE_SETTER_DECL(ImANode);
+ MESSAGE_SETTER_DECL(ImAClient);
+ MESSAGE_SETTER_DECL(Bye);
+ MESSAGE_SETTER_DECL(KeyExchange);
+
+ #undef MESSAGE_SETTER
+};
diff --git a/libcmix-common/receiver.hpp b/libcmix-common/receiver.hpp
new file mode 100644
index 0000000..a70cde0
--- /dev/null
+++ b/libcmix-common/receiver.hpp
@@ -0,0 +1,24 @@
+#pragma once
+
+#include "cmixprotofunctor.hpp"
+
+#include "protobufclient.hpp"
+
+struct SenderReceiver;
+
+struct Receiver : private ProtobufClient<CMixProtoFunctor>
+{
+ friend SenderReceiver;
+
+ using ProtobufClient::ProtobufClient;
+
+ using ProtobufClient::async_receive;
+
+ using ProtobufClient::async_connect;
+
+ using ProtobufClient::close;
+
+ using ProtobufClient::on_done;
+
+ using ProtobufClient::is_open;
+};
diff --git a/libcmix-common/sender.hpp b/libcmix-common/sender.hpp
new file mode 100644
index 0000000..72f0b3d
--- /dev/null
+++ b/libcmix-common/sender.hpp
@@ -0,0 +1,24 @@
+#pragma once
+
+#include "cmixprotofunctor.hpp"
+
+#include "protobufclient.hpp"
+
+struct SenderReceiver;
+
+struct Sender : private ProtobufClient<CMixProtoFunctor>
+{
+ friend SenderReceiver;
+
+ using ProtobufClient::ProtobufClient;
+
+ using ProtobufClient::async_send;
+
+ using ProtobufClient::async_connect;
+
+ using ProtobufClient::close;
+
+ using ProtobufClient::on_done;
+
+ using ProtobufClient::is_open;
+};
diff --git a/libcmix-common/senderreceiver.cpp b/libcmix-common/senderreceiver.cpp
new file mode 100644
index 0000000..eafa8a5
--- /dev/null
+++ b/libcmix-common/senderreceiver.cpp
@@ -0,0 +1,10 @@
+
+#include "senderreceiver.hpp"
+
+SenderReceiver::SenderReceiver(Receiver&& r)
+: ProtobufClient(std::move(r))
+{}
+
+SenderReceiver::SenderReceiver(Sender&& s)
+: ProtobufClient(std::move(s))
+{}
diff --git a/libcmix-common/senderreceiver.hpp b/libcmix-common/senderreceiver.hpp
new file mode 100644
index 0000000..9a07f78
--- /dev/null
+++ b/libcmix-common/senderreceiver.hpp
@@ -0,0 +1,28 @@
+#pragma once
+
+#include "cmixprotofunctor.hpp"
+#include "receiver.hpp"
+#include "sender.hpp"
+
+#include "protobufclient.hpp"
+
+struct SenderReceiver : private ProtobufClient<CMixProtoFunctor>
+{
+ explicit SenderReceiver(Receiver&& r);
+
+ explicit SenderReceiver(Sender&& s);
+
+ using ProtobufClient::ProtobufClient;
+
+ using ProtobufClient::async_receive;
+
+ using ProtobufClient::async_send;
+
+ using ProtobufClient::async_connect;
+
+ using ProtobufClient::close;
+
+ using ProtobufClient::on_done;
+
+ using ProtobufClient::is_open;
+}; \ No newline at end of file
diff --git a/libcmix-network/CMakeLists.txt b/libcmix-network/CMakeLists.txt
index c64c8b7..ee0f6e9 100644
--- a/libcmix-network/CMakeLists.txt
+++ b/libcmix-network/CMakeLists.txt
@@ -26,8 +26,7 @@ target_link_libraries(cmix-network
PUBLIC Boost::system
PUBLIC ${CMAKE_THREAD_LIBS_INIT}
PRIVATE cmix
- PRIVATE log
- PRIVATE cmix-protobuf
+ PUBLIC log
)
if(WIN32)
diff --git a/libcmix-network/client.hpp b/libcmix-network/client.hpp
index 7b88282..4990667 100644
--- a/libcmix-network/client.hpp
+++ b/libcmix-network/client.hpp
@@ -102,10 +102,10 @@ public:
}
/*!
- * \brief receive
+ * \brief async_receive
* \param message_handler The function to call when a message has been received.
*/
- void receive(MessageHandler message_handler) {
+ void async_receive(MessageHandler message_handler) {
using namespace boost::asio::placeholders;
socket.async_receive(
diff --git a/libcmix-network/protobufclient.hpp b/libcmix-network/protobufclient.hpp
index 077ce62..c28c347 100644
--- a/libcmix-network/protobufclient.hpp
+++ b/libcmix-network/protobufclient.hpp
@@ -3,150 +3,43 @@
#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
+template <typename T>
+class ProtobufClient : private Client
{
- 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);
- }
+ using Client::Client;
+ using Client::operator=;
+ using Client::async_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>
+ template<typename V, typename F>
void async_send(V value, F on_sent) {
- cmix_proto::CMixMessage m;
- message_setter(m, value);
- client.async_send(m.SerializeAsString(), on_sent);
+ typename T::proto_type m = T()(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>
+ template<typename V>
void async_send(V value) {
- cmix_proto::CMixMessage m;
- message_setter(m, value);
- client.async_send(m.SerializeAsString(), []{});
+ async_send(value, []{});
}
- /*!
- * \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) {
+ template <typename F>
+ void async_receive(F message_handler) {
auto f = [message_handler](std::vector<uint8_t> const& buffer) {
- cmix_proto::CMixMessage message;
+ typename T::proto_type 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();
+ Client::async_receive(f);
}
- /*!
- * \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);
- }
-
- bool is_open() const{
- return client.is_open();
- }
-
- friend Receiver make_receiver(Receiver&& r);
-
- friend SenderReceiver make_sender_receiver(SenderReceiver&& r);
- friend SenderReceiver make_sender_receiver(Receiver&& r);
+ using Client::close;
+ using Client::on_done;
+ using Client::is_open;
};
-
-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/node/CMakeLists.txt b/node/CMakeLists.txt
index c5ec53f..05468bd 100644
--- a/node/CMakeLists.txt
+++ b/node/CMakeLists.txt
@@ -25,4 +25,5 @@ target_link_libraries(node
PRIVATE cmix-bignum
PRIVATE cmix-network
PRIVATE cmix-protobuf
+ PRIVATE cmix-common
)
diff --git a/node/node.cpp b/node/node.cpp
index f06e389..5487299 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(ProtobufClient<Receive>(tcp::socket(io_service)))
-, next_node(ProtobufClient<Send>(tcp::socket(io_service)))
+, prev_node(Receiver(tcp::socket(io_service)))
+, next_node(Sender(tcp::socket(io_service)))
, api(get_implementation())
, keypair(api.create_key_pair())
, network_pub_key()
@@ -42,14 +42,14 @@ void Node::run() {
void Node::accept_handler(boost::asio::ip::tcp::socket&& socket)
{
- std::list<ProtobufClient<Receive>>::iterator it = purgatory.emplace(purgatory.end(), std::move(socket));
+ std::list<Receiver>::iterator it = purgatory.emplace(purgatory.end(), std::move(socket));
purgatory.back().on_done(
[this, it]() {
purgatory.erase(it);
}
);
- it->receive([this, it](cmix_proto::CMixMessage message) {
+ it->async_receive([this, it](cmix_proto::CMixMessage message) {
handle_message(it, message);
});
}
@@ -109,7 +109,7 @@ void Node::handle_node_message(cmix_proto::CMixMessage message)
prev_node.close();
if (!shutting_down) {
send_bye();
- prev_node.receive([this](cmix_proto::CMixMessage message){
+ prev_node.async_receive([this](cmix_proto::CMixMessage message){
handle_node_message(message);
});
}
@@ -119,7 +119,7 @@ void Node::handle_node_message(cmix_proto::CMixMessage message)
BOOST_LOG_TRIVIAL(error) << "handle_node_message: CMixMessage contains unknown contents.";
}
}
- prev_node.receive([this](cmix_proto::CMixMessage message) {
+ prev_node.async_receive([this](cmix_proto::CMixMessage message) {
handle_node_message(message);
});
}
@@ -131,7 +131,7 @@ void Node::handle_client_message(ClientMap::key_type handle, cmix_proto::CMixMes
BOOST_LOG_TRIVIAL(trace) << "Deriving shared key";
api.derive_shared_key(keypair, reinterpret_cast<uint8_t const*>(message.keyexchange().public_key().c_str()), true);
- clients.at(handle).receive([this, handle](cmix_proto::CMixMessage message){
+ clients.at(handle).async_receive([this, handle](cmix_proto::CMixMessage message){
handle_client_message(handle, message);
});
return;
@@ -154,9 +154,9 @@ void Node::handle_client_message(ClientMap::key_type handle, cmix_proto::CMixMes
void Node::handle_imanode(std::list<Receiver>::iterator handle) {
handle->on_done([]{});
- prev_node = make_receiver(std::move(*handle));
+ prev_node = Receiver(std::move(*handle));
purgatory.erase(handle);
- prev_node.receive([this](cmix_proto::CMixMessage message){
+ prev_node.async_receive([this](cmix_proto::CMixMessage message){
handle_node_message(message);
});
}
@@ -164,17 +164,17 @@ void Node::handle_imanode(std::list<Receiver>::iterator handle) {
void Node::handle_imaclient(std::list<Receiver>::iterator handle, cmix_proto::ImAClient c) {
BOOST_LOG_TRIVIAL(trace) << "Handling imaclient";
std::string client_id = c.id();
- clients.emplace(c.id(), make_sender_receiver(std::move(*handle)));
+ clients.emplace(c.id(), SenderReceiver(std::move(*handle)));
clients.at(c.id()).on_done([this, client_id]{
clients.erase(client_id);
});
purgatory.erase(handle);
- clients.at(c.id()).receive([this, client_id](cmix_proto::CMixMessage message) {
+ clients.at(c.id()).async_receive([this, client_id](cmix_proto::CMixMessage message) {
handle_client_message(client_id, message);
});
}
-void Node::handle_message(std::list<ProtobufClient<Receive>>::iterator handle, cmix_proto::CMixMessage message)
+void Node::handle_message(std::list<Receiver>::iterator handle, cmix_proto::CMixMessage message)
{
switch(message.contents_case()) {
case cmix_proto::CMixMessage::ContentsCase::kImanode: {
diff --git a/node/node.hpp b/node/node.hpp
index 868c4b8..9423860 100644
--- a/node/node.hpp
+++ b/node/node.hpp
@@ -1,7 +1,9 @@
#pragma once
#include "server.hpp"
-#include "protobufclient.hpp"
+#include "receiver.hpp"
+#include "senderreceiver.hpp"
+#include "sender.hpp"
#include "api.h"
@@ -61,7 +63,7 @@ class Node
void handle_imanode(std::list<Receiver>::iterator handle);
void handle_imaclient(std::list<Receiver>::iterator handle, cmix_proto::ImAClient c);
- void handle_message(std::list<ProtobufClient<Receive>>::iterator handle, cmix_proto::CMixMessage message);
+ void handle_message(std::list<Receiver>::iterator handle, cmix_proto::CMixMessage message);
public:
/*!