#include "cmixclient.hpp" void CMixClient::key_exchange(int i) { shared_keys.resize(network_connections.size()); cmix_proto::KeyExchange ke; ke.set_public_key(keypair.pub, keypair.pub_len); network_connections[i].send(ke); cmix_proto::Bye bye; network_connections[i].send(bye); } void CMixClient::initialize_connections() { network_connections.reserve(network_details.size()); for(int i = 0; i < network_details.size(); ++i) { auto handler = [this, i]() mutable { cmix_proto::ImAClient imaclient; BOOST_LOG_TRIVIAL(trace) << "sending imaclient to node: " << i; network_connections.at(i).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 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) { shared_keys[node_id] = api.derive_shared_key(keypair, reinterpret_cast(ke.public_key().c_str()), false); } void CMixClient::handle_message(int node_id, std::vector const& message_buffer) { 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()); return; } default: { BOOST_LOG_TRIVIAL(error) << "Received unknown message"; } } for(auto&& connection : network_connections) { connection.close(); } io_service.stop(); } CMixClient::CMixClient(std::vector details) : io_service() , network_details(details) , network_connections() , api(get_implementation()) , keypair(api.create_key_pair()) { initialize_connections(); } void CMixClient::run() { io_service.run(); }