#include #include #include #include "Untrusted.hpp" #include "start.hpp" class Epoch { boost::asio::io_context &io_context; uint32_t epoch_num; std::mutex m; std::condition_variable cv; bool epoch_complete; void round_cb(uint32_t round_num) { if (round_num) { printf("Round %u complete\n", round_num); boost::asio::post(io_context, [this]{ proceed(); }); } else { printf("Epoch %u complete\n", epoch_num); { std::lock_guard lk(m); epoch_complete = true; } cv.notify_one(); } } public: Epoch(boost::asio::io_context &context, uint32_t ep_num): io_context(context), epoch_num(ep_num), epoch_complete(false) {} void proceed() { ecall_routing_proceed([this](uint32_t round_num) { round_cb(round_num); }); } void wait() { std::unique_lock lk(m); cv.wait(lk, [this]{ return epoch_complete; }); } }; static void epoch(NetIO &netio, char **args) { static uint32_t epoch_num = 1; uint16_t num_nodes = netio.num_nodes; uint32_t num_tokens[num_nodes]; uint32_t tot_tokens = 0; for (nodenum_t j=0;j 0) { // Pick a random remaining token uint32_t r = uint32_t(lrand48()) % rem_tokens; for (nodenum_t j=0;j ts; for (int j=0; j csocket, const boost::system::error_code& error, size_t auth_size, size_t msgbundle_size) { if(!error) { #ifdef VERBOSE_NET printf("Accept handler success\n"); #endif // Read header (1 uint64_t) from the socket and extract the client ID size_t header; clientid_t cid; boost::asio::read(*csocket, boost::asio::buffer(&header, sizeof(uint64_t))); if((header & 0xff) == CLIENT_AUTHENTICATE) { // Read the authentication token boost::asio::read(*csocket, boost::asio::buffer(&header, auth_size)); } else if ((header & 0xff) == CLIENT_MESSAGE_BUNDLE) { unsigned char *msgbundle = (unsigned char*) malloc(msgbundle_size); cid = (clientid_t)(header >> 8); // Read the message_bundle boost::asio::read(*csocket, boost::asio::buffer(msgbundle, msgbundle_size)); //Ingest the message_bundle bool ret = ecall_ingest_msgbundle(cid, msgbundle, apiparams.m_priv_out); free(msgbundle); } start_accept(netio, auth_size, msgbundle_size); } else { printf("Accept handler failed\n"); } } /* Asynchronously accept client connections */ void start_accept(NetIO &netio, size_t auth_size, size_t msgbundle_size) { boost::asio::io_context &io_context = netio.io_context(); const NodeConfig &myconf = netio.myconfig(); std::shared_ptr csocket(new tcp::socket(netio.io_context())); tcp::resolver resolver(io_context); std::shared_ptr client_acceptor; client_acceptor = std::shared_ptr( new tcp::acceptor(io_context, resolver.resolve(myconf.clistenhost, myconf.clistenport)->endpoint())); #ifdef VERBOSE_NET std::cout << "Accepting on " << myconf.clistenhost << ":" << myconf.clistenport << "\n"; #endif client_acceptor->async_accept(*csocket, boost::bind(&handle_async_clients, netio, csocket, boost::asio::placeholders::error, auth_size, msgbundle_size)); } void runAsyncListeners(NetIO &netio) { const Config &conf = netio.config(); const NodeConfig &myconf = netio.myconfig(); if(myconf.roles & ROLE_INGESTION) { size_t auth_size, msgbundle_size; auth_size = SGX_AESGCM_MAC_SIZE; msgbundle_size = SGX_AESGCM_IV_SIZE + (conf.m_priv_out * conf.msg_size) + SGX_AESGCM_MAC_SIZE; start_accept(netio, auth_size, msgbundle_size); } }