diff options
| -rw-r--r-- | CMakeLists.txt | 1 | ||||
| -rw-r--r-- | client/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | client/cmixclient.hpp | 4 | ||||
| -rw-r--r-- | libcmix-common/CMakeLists.txt | 16 | ||||
| -rw-r--r-- | libcmix-common/cmixprotofunctor.cpp | 16 | ||||
| -rw-r--r-- | libcmix-common/cmixprotofunctor.hpp | 19 | ||||
| -rw-r--r-- | libcmix-common/receiver.hpp | 24 | ||||
| -rw-r--r-- | libcmix-common/sender.hpp | 24 | ||||
| -rw-r--r-- | libcmix-common/senderreceiver.cpp | 10 | ||||
| -rw-r--r-- | libcmix-common/senderreceiver.hpp | 28 | ||||
| -rw-r--r-- | libcmix-network/CMakeLists.txt | 3 | ||||
| -rw-r--r-- | libcmix-network/client.hpp | 4 | ||||
| -rw-r--r-- | libcmix-network/protobufclient.hpp | 141 | ||||
| -rw-r--r-- | node/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | node/node.cpp | 24 | ||||
| -rw-r--r-- | node/node.hpp | 6 |
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: /*! |
