#pragma once #include "server.hpp" #include "receiver.hpp" #include "senderreceiver.hpp" #include "sender.hpp" #include "performanceclient.hpp" #include "api.h" #include "cmix.h" #include "cmix.pb.h" #include #include #include #include #include #include #include /*! * \file */ #ifndef NDEBUG /*! * \brief to_string Debug function that turns a groupelement to a string. * \param el element to convert. * \param ctx The context to use. * \return The string containing the binary data of the array representation of the groupelement */ inline std::string to_string(GroupElement el, CMixContext const& ctx) { std::string ret; ret.resize(get_group_element_array_size(&ctx)); element_to_buffer(&ctx, &ret[0], el); return ret; } #endif /*! * \brief The NodeNetworkSettings struct */ struct NodeNetworkSettings { bool is_first; ///< Are we the first node in the network. bool is_last; ///< Are we the last node in the network. std::string next_host; ///< Next nodes host. std::string next_port; ///< Next nodes port. std::string certdir; ///< Directory containing trusted certificate authorities. unsigned int minimum_nr_messages; ///< The minimum number of available messages before starting to run a mix; unsigned int nr_mixes; ///< The number of simultaneous mixes the network will perform. }; /*! * \brief Details if and where to send performance data. */ struct PerformanceSettings { bool run; ///< bool indicating if we should even run performance tasks. std::string host; ///< host at which a statsd runs. std::string port; ///< port on which a statsd runs. std::string name; ///< our identifier for the statsd. }; /*! * \brief some boilerplate to optimize some of the google protobuf memory allocations. */ template struct ArenaMessage { /*! * \brief arena The arena allocater provided by protobuf. */ google::protobuf::Arena arena; /*! * \brief get Create a new object in the arena and create a ref. * \return a new ref to a T. */ T& get() { return *google::protobuf::Arena::CreateMessage(&arena); } }; /*! * \brief The Node class */ class Node { struct CMixClientData { GroupElement shared_value; }; boost::asio::io_service io_service; boost::asio::deadline_timer timer; std::shared_ptr ssl_ctx; Server server; typedef std::list Purgatory; Purgatory purgatory; boost::optional performance; typedef std::map ClientConnections; ClientConnections clients; typedef std::map ClientData; ClientData data; typedef std::map> ClientMessages; ClientMessages messages; NodeNetworkSettings network_settings; SSLReceiver prev_node; SSLSender next_node; CMixContext cmix_ctx; std::vector participants; bool shutting_down; void accept_handler(std::unique_ptr>&& socket, std::shared_ptr ctx); void connect_to_next_node(); void start_initialisation(); void start_precomputation(); void start_realtime_phase(); void shutdown(); bool send_bye(bool got_bye); void start_timer_delayed_mix(); void handle_node_initialization(cmix_proto::Initialization const& init); void handle_node_secretkey(cmix_proto::SecretKey const& secret); void handle_node_prepre(cmix_proto::PrePre const& prepre); void handle_node_premix(cmix_proto::PreMix const& premix); void handle_node_prepost(cmix_proto::PrePost const& prepost); void handle_node_commitments(cmix_proto::Commitments const& commitments); void handle_node_realpre(cmix_proto::RealPre const& realpre); void handle_node_realmix(cmix_proto::RealMix const& realmix); void handle_node_realpost(cmix_proto::RealPost const& realpost); void handle_node_message(cmix_proto::CMixMessage message); void handle_client_keyexchange(ClientConnections::key_type handle, cmix_proto::KeyExchange const& ke); void handle_client_bye(ClientConnections::key_type handle, cmix_proto::Bye const&); void handle_client_usermessage(ClientConnections::key_type handle, cmix_proto::UserMessage const& um); void handle_client_message(ClientConnections::key_type handle, cmix_proto::CMixMessage message); void handle_imanode(Purgatory::iterator handle, cmix_proto::ImANode const&); void handle_imaclient(Purgatory::iterator handle, cmix_proto::ImAClient const& c); void handle_message(Purgatory::iterator handle, cmix_proto::CMixMessage message); public: /*! * \brief Node * \param listen_settings The listen settings for the accepter. * \param network_settings The network settings containing if we are first and who is the next node. * \param performance_settings The connections settings for a statsd. */ Node(ListenSettings const& listen_settings, NodeNetworkSettings network_settings, PerformanceSettings performance_settings); ~Node(); /*! * \brief run Starts the underlying io_service */ void run(); };