#include "node.hpp" #include "uriparser.hpp" #include "logging.hpp" #include #include #include int main(int argc, char* argv[]) { namespace po = boost::program_options; po::options_description desc("Allowed options"); desc.add_options() ("help,h", "produce help message.") ("port,p", po::value()->default_value(9200), "Set listening port.") ("enable_v4", po::value()->default_value(true), "Enable/disable ipv4 accept support.") ("interface4,4", po::value()->default_value("0.0.0.0"), "Set the ipv4 address to listen on.") ("enable_v6", po::value()->default_value(true), "Enable/disable ipv6 accept support.") ("interface6,6", po::value()->default_value("::"), "Set the ipv6 address to listen on.") ("next_node,n", po::value(), "The address of the next node in the network.") ("first,f", "This is the first node and will be the communication point for the clients.") ("last,l", "this is the last node and will be able to send the original message out of the network.") ("minimum_nr_messages,m", po::value(), "minimum number of messages that needs to accumulate before starting a mix.") ("cert,c", po::value(), "The cert file to use (in pem format).") ("key,k", po::value(), "The key file (in pem format).") ("dhparam,d", po::value(), "The dhparam file.") ("certdir", po::value(), "Directory containing trusted certificates.") ; po::variables_map vm; po::store(po::parse_command_line(argc, argv, desc), vm); po::notify(vm); if (vm.count("help")) { std::cout << desc << "\n"; return 0; } bool en4 = vm["enable_v4"].as(); std::string if4 = vm["interface4"].as(); bool en6 = vm["enable_v6"].as(); std::string if6 = vm["interface6"].as(); uint16_t port = vm["port"].as(); std::string cert; if(vm.count("cert")) { std::string filename = vm["cert"].as(); if(boost::filesystem::exists(filename)) { cert = filename; } else { std::cerr << "cert file: \"" << filename << "\" does not exist"; return -1; } } else { std::cerr << "supplying a certificate is required" << std::endl; return -1; } std::string key; if(vm.count("key")) { std::string filename = vm["key"].as(); if(boost::filesystem::exists(filename)) { key = filename; } else { std::cerr << "key file: \"" << filename << "\" does not exist"; return -1; } } else { std::cerr << "supplying a key file is required" << std::endl; return -1; } std::string dhparam; if(vm.count("dhparam")) { std::string filename = vm["dhparam"].as(); if(boost::filesystem::exists(filename)) { dhparam = filename; } else { std::cerr << "dhparam file: \"" << filename << "\" does not exist"; return -1; } } else { std::cerr << "supplying a dhparam file is required" << std::endl; return -1; } ListenSettings lsettings{en4, if4, en6, if6, port, true, cert, key, dhparam}; init_logging(boost::log::trivial::severity_level::trace, "node_" + std::to_string(port)); BOOST_LOG_TRIVIAL(info) << "Started node"; bool is_first = bool(vm.count("first")); unsigned int minimum_nr_messages = 0; if(is_first) { if(vm.count("minimum_nr_messages")) { minimum_nr_messages = vm["minimum_nr_messages"].as(); } else { std::cerr << "Minimum nr of messages is a required parameter for the first node" << std::endl; return -1; } } bool is_last = bool(vm.count("last")); std::string next_node; if(vm.count("next_node")) { next_node = vm["next_node"].as(); } else { std::cerr << "next_node option is required." << std::endl; return -1; } std::string certdir; if(vm.count("certdir")) { std::string filename = vm["certdir"].as(); if(boost::filesystem::is_directory(filename)) { certdir = filename; } else { std::cerr << "cert dir: \"" << filename << "\" is not a directory"; return -1; } } Uri uri = parse_uri(next_node); NodeNetworkSettings nsettings{is_first, is_last, uri.host, uri.port, certdir, minimum_nr_messages}; Node node(lsettings, nsettings); node.run(); }