123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258 |
- /**
- * serverMain.cpp
- * - compiles to bin/server
- * - runs a server program for experiments with PRSONA
- *
- * Stan Gurtler
- */
- #include <iostream>
- #include <fstream>
- #include "networkServer.hpp"
- using namespace std;
- /**
- * This program (bin/server) expects to be called as follows:
- * `bin/server <id> <output> <servers_are_malicious>`
- *
- * <id> - a name for this instance, which comes with a config file identifying
- * its IP address and port
- * <output> - a string that will name the file in which outputs for this run of
- * the program will be written (that is, timings and traffic data)
- * <lambda> - a positive integer that determines the absolute soundness parameter
- * for batched proofs
- * <servers_are_malicious> - a bool (given as T/t or F/f)
- * which is true when servers are in malicious security
- * and false when they are in HBC security
- */
- int main(int argc, char *argv[])
- {
- /*
- * PRELIMINARY SETUP CODE
- */
- initialize_prsona_classes();
- #if USE_SSL
- mg_init_library(MG_FEATURES_SSL);
- #else
- mg_init_library(0);
- #endif
- // The id effectively tells the server what ip/port it is
- string id = "";
- if (argc > 1)
- id = argv[1];
- string output = "default";
- if (argc > 2)
- output = argv[2];
- string outputDir = "/home/tmgurtle/prsona/prsona/out/" + output + "/" + id;
- int mkdirOut = system(("mkdir -p " + outputDir).c_str());
- mutex epochBuildUpOutputMtx;
- string epochBuildUpOutputFilename = outputDir + "/epochUp.out";
- mutex epochBreakDownOutputMtx;
- string epochBreakDownOutputFilename = outputDir + "/epochDown.out";
- mutex epochUpdateOutputMtx;
- string epochUpdateOutputFilename = outputDir + "/epochUpdate.out";
- mutex voteUpdateOutputMtx;
- string voteUpdateOutputFilename = outputDir + "/voteUpdate.out";
- mutex fullEpochOutputMtx;
- string fullEpochOutputFilename = outputDir + "/overallEpoch.out";
- mutex memUsageOutputMtx;
- string memUsageOutputFilename = outputDir + "/usage.out";
- // Default to no proof batching if not specified
- size_t lambda = 0;
- if (argc > 3)
- lambda = atoi(argv[3]);
- // Set lambda where necessary
- if (lambda > 0)
- PrsonaBase::set_lambda(lambda);
- // Default to malicious security if not specified
- bool maliciousServers = true;
- if (argc > 4)
- maliciousServers = argv[4][0] == 't' || argv[4][0] == 'T';
- // Set malicious flags where necessary
- if (maliciousServers)
- PrsonaBase::set_server_malicious();
- // This seed is used to generate temp filenames.
- string seedStr;
- if (id.empty())
- seedStr = "default-server";
- else
- {
- seedStr = id;
- seedStr += "-" + output;
- seedStr += "-server";
- }
- seed_seq seed(seedStr.begin(), seedStr.end());
- default_random_engine rng(seed);
- vector<string> serverIPs;
- vector<int> serverPorts;
- string selfIP, selfPortStr, dealerIP, dealerPortStr;
- int selfPort = 0, dealerPort = 0;
- string configDir = "/home/tmgurtle/prsona/prsona/cfg/" + output;
- // Read in from config files the server locations
- load_multiple_instances_config(serverIPs, serverPorts, (configDir + "/serverIPs.cfg").c_str());
- // Read in the ip/port corresponding to the id that this instance was given
- string selfConfigFilename = configDir + "/selfIP";
- if (!id.empty())
- {
- selfConfigFilename += "-";
- selfConfigFilename += id;
- }
- selfConfigFilename += ".cfg";
- load_single_instance_config(selfIP, selfPortStr, selfPort, selfConfigFilename.c_str());
- // And finally the dealer location
- load_single_instance_config(dealerIP, dealerPortStr, dealerPort, (configDir + "/dealerIP.cfg").c_str());
- size_t numServers = serverIPs.size();
- bool bgnDealer = selfIP == dealerIP && selfPort == dealerPort;
- struct synchronization_tool exitSync, readySync;
- mutex updateMtx;
- unique_lock<mutex> *updateLockHolder = NULL;
- atomic<size_t> epochNum(0);
- const char *options[] = {"listening_ports", selfPortStr.c_str(), 0};
- CivetServer server(options);
- /*
- * SERVER SETUP CODE
- */
- cout << "[" << seedStr << "] Establishing PRSONA server with the following parameters: " << endl;
- cout << "[" << seedStr << "] " << numServers << " PRSONA servers" << endl;
- cout << "[" << seedStr << "] This server " << (bgnDealer ? "IS" : "is NOT") << " the trusted BGN dealer" << endl;
- cout << "[" << seedStr << "] " << "Proof batching " << (lambda > 0 ? "IS" : "is NOT") << " in use." << endl;
- if (lambda > 0)
- cout << "[" << seedStr << "] Batch parameter: " << lambda << endl;
- cout << "[" << seedStr << "] Servers are set to " << (maliciousServers ? "MALICIOUS" : "HBC") << " security" << endl;
- cout << "[" << seedStr << "] This server is at IP address: " << selfIP << ":" << selfPort << endl;
- cout << "[" << seedStr << "] The BGN dealer is at IP address: " << dealerIP << ":" << dealerPort << endl;
- cout << endl;
- cout << "[" << seedStr << "] Creating PRSONA server object." << endl;
- PrsonaServer *prsonaServer = create_server(rng, dealerIP, dealerPort, bgnDealer, numServers);
- cout << "[" << seedStr << "] Setting up handlers for server." << endl;
- // Main handler
- PrsonaServerWebSocketHandler wsHandler(rng, prsonaServer, serverIPs, serverPorts, selfIP, selfPort, updateMtx, epochNum, epochBuildUpOutputMtx, epochBuildUpOutputFilename, epochBreakDownOutputMtx, epochBreakDownOutputFilename, epochUpdateOutputMtx, epochUpdateOutputFilename, voteUpdateOutputMtx, voteUpdateOutputFilename, memUsageOutputMtx, memUsageOutputFilename);
- server.addWebSocketHandler("/ws", wsHandler);
- // Exit handler (allows server to be brought down by making correct GET request)
- unique_lock<mutex> exitLock(exitSync.mtx);
- exitSync.val = 0;
- exitSync.val2 = 0;
- RemoteControlHandler exitHandler(&exitSync, "Server coming down!");
- server.addHandler(EXIT_URI, exitHandler);
- // Update mutex handler (allows servers to synchronize updates, like epochs and new users)
- UpdateLockWebSocketHandler lockHandler(updateMtx, &updateLockHolder, true);
- UpdateLockWebSocketHandler unlockHandler(updateMtx, &updateLockHolder, false);
- server.addWebSocketHandler(UPDATE_LOCK_URI, lockHandler);
- server.addWebSocketHandler(UPDATE_UNLOCK_URI, unlockHandler);
- // Epoch number handler (allows a server to indicate what epoch the system is on)
- EpochNumHandler epochNumHandler(epochNum);
- server.addHandler(WHICH_EPOCH_URI, epochNumHandler);
- // This handler (to determine system main loop readiness) is only used by the dealer
- RemoteControlHandler serverReadyHandler(&readySync, "ACK");
- // Similarly, this handler (to tell the orchestrator when epochs are ready to happen) is only used by the dealer
- EpochReadyHandler epochReadyHandler(&exitSync, &readySync, updateMtx, numServers);
- // Make-epoch trigger (which causes the dealer to initiate an epoch change)
- AltRemoteControlHandler triggerEpochHandler(1, &exitSync, "Server will initiate epoch!");
- // It's probably best to give them all a lifetime as long as the CivetWeb server object
- if (bgnDealer) // The dealer needs to wait for the other servers to check in, because it needs to lead forming the first fresh generator
- {
- // The readySync lock is only used here, while we're waiting for other servers to check in
- unique_lock<mutex> lck(readySync.mtx);
- readySync.val = 1;
- server.addHandler(SERVER_CHECK_IN_URI, serverReadyHandler);
- // In addition, there are also a few extra handlers only the dealer needs
- server.addHandler(TRIGGER_EPOCH_URI, triggerEpochHandler);
- server.addHandler(EPOCH_READY_URI, epochReadyHandler);
- cout << "[" << seedStr << "] Waiting for other servers to retrieve BGN details and check in." << endl;
- // Wait for the other servers to check in
- while (readySync.val < numServers)
- {
- cout << "[" << seedStr << "] " << readySync.val << " servers are checked in." << endl;
- readySync.cv.wait(lck);
- }
- // Once we're ready, form and distribute the first fresh generator and the H used in ElGamal operations
- initiate_generators(rng, prsonaServer, serverIPs, serverPorts, selfIP, selfPort);
- }
- else // Non-dealer servers need to check in with the dealer
- {
- cout << "[" << seedStr << "] Checking in with the BGN dealer." << endl;
- check_in_with_dealer(dealerIP, dealerPort);
- }
- /*
- * MAIN SERVER LOOP CODE
- */
- cout << "[" << seedStr << "] Entering main ready loop." << endl;
- if (bgnDealer)
- {
- while (!exitSync.val)
- {
- // exitSync.val controls when an exit is signaled.
- // exitSync.val2 controls when an epoch change is signaled
- while (!exitSync.val && !exitSync.val2)
- exitSync.cv.wait(exitLock);
- // exitSync.val2 is set by the make-epoch handler, and will be 0 in the event of signaling an exit
- if (exitSync.val2)
- {
- size_t currEpoch = epochNum.load();
- cout << "[" << seedStr << "] Executing epoch calculations (going from t = " << currEpoch << " to " << currEpoch + 1 << ")." << endl;
- make_epoch(rng, prsonaServer, serverIPs, serverPorts, selfIP, selfPort, updateMtx, epochNum, server, epochBuildUpOutputMtx, epochBuildUpOutputFilename, epochBreakDownOutputMtx, epochBreakDownOutputFilename, fullEpochOutputMtx, fullEpochOutputFilename, memUsageOutputMtx, memUsageOutputFilename);
- currEpoch = epochNum.load();
- cout << "[" << seedStr << "] Epoch calculations complete (now in t = " << currEpoch << ")." << endl;
- }
- // Make sure to reset this, so that we wait until something new is signaled to do
- exitSync.val2 = 0;
- }
- }
- else
- {
- // exitSync.val controls when an exit is signaled.
- // exitSync.val2 is not used by non-dealer servers.
- while (!exitSync.val)
- exitSync.cv.wait(exitLock);
- }
- /*
- * SHUTDOWN CODE
- */
- cout << "[" << seedStr << "] Shutting down." << endl;
- mg_exit_library();
- delete prsonaServer;
- return 0;
- }
|