main.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. /* Copyright (C) 2014 Carlos Aguilar Melchor, Joris Barrier, Marc-Olivier Killijian
  2. * This file is part of XPIR.
  3. *
  4. * XPIR is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * XPIR is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with XPIR. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #include "main.hpp"
  18. // Client constants
  19. static const std::string DEFAULT_IP("127.0.0.1");
  20. static const int DEFAULT_PORT = 1234;
  21. static const bool DEFAULT_AUTOCHOICE = false;
  22. // Optimizer constants
  23. static const int DEFAULT_SECURITY = 80;
  24. static const unsigned long DEFAULT_N = 1000;
  25. static const unsigned int DEFAULT_L = 24000000;
  26. static const unsigned int DEFAULT_TUPC = 100000000;
  27. static const unsigned int DEFAULT_TDOC = 100000000;
  28. static const unsigned int DEFAULT_K = 80;
  29. static const unsigned int DEFAULT_ALPHAMAX = 0; // 0 means no limit
  30. static const unsigned int DEFAULT_DMAX = 4;
  31. static const unsigned int DEFAULT_DMIN = 1;
  32. static const FitnessType DEFAULT_FITNESSMETHOD = MAX;
  33. static const std::string DEFAULT_CRYPTO_PARAMS("LWE:80:1024:60:22");
  34. //Global vars
  35. string fileToOptimizeFrom;
  36. bool no_pipeline = false;
  37. void sighandler(int sig_num)
  38. {
  39. FixedVars fixedVars;
  40. cerr.flush();
  41. if(sig_num == SIGPIPE)
  42. cerr << "Broken pipe detected";
  43. cerr << endl << "Exiting client..." << endl << endl;
  44. exit(EXIT_SUCCESS);
  45. }
  46. void defineClientOptions(ClientParams* paramsPtr, po::options_description* odptr){
  47. odptr->add_options()
  48. ("help,h",
  49. "help message")
  50. ("serverip,ip",
  51. po::value<string>(&paramsPtr->server_ip)->default_value(DEFAULT_IP),
  52. "PIR server IP" )
  53. ("port,p",
  54. po::value<int>(&paramsPtr->port)->default_value(DEFAULT_PORT),
  55. "PIR server port")
  56. ("autochoice,c",
  57. "Auto-choose the first file")
  58. ("dry-run",
  59. "Enable dry-run mode")
  60. ("verbose-optim",
  61. "Ask the optimizer to be more verbose")
  62. ("dont-write",
  63. "Don't write result to a file")
  64. ("file,f",
  65. po::value<std::string>(&fileToOptimizeFrom),
  66. "Use a config file to test different optimizations in dry-run mode (see sample.conf)");
  67. }
  68. void defineOptimizerOptions(FixedVars* varsPtr, po::options_description* odptr){
  69. odptr->add_options()
  70. ("file-nbr,n",
  71. po::value<uint64_t>(),
  72. "Used in dry-run mode only: Number of database elements" )
  73. ("file-size,l",
  74. po::value<uint64_t>(),
  75. "Used in dry-run mode only: Database element size in bits")
  76. ("upload,up",
  77. po::value<double>(),
  78. "Force client upload speed in bits/s (bandwith test will be skipped)")
  79. ("download,down",
  80. po::value<double>(),
  81. "Force client download speed in bits/s (bandwidth test will be skipped)")
  82. ("crypto-params,r",
  83. po::value<string>(&varsPtr->manual_crypto_params),
  84. "Set cryptographic parameteres manually")
  85. ("security,k",
  86. po::value<unsigned int>(&varsPtr->k)->default_value(DEFAULT_SECURITY),
  87. "Security bits wanted")
  88. ("dmin",
  89. po::value<unsigned int>(&varsPtr->dMin)->default_value(DEFAULT_DMIN),
  90. "Min dimension value to test")
  91. ("dmax",
  92. po::value<unsigned int>(&varsPtr->dMax)->default_value(DEFAULT_DMAX),
  93. "Max dimension value to test")
  94. ("alphaMax,a",
  95. po::value<unsigned int>(&varsPtr->alphaMax)->default_value(DEFAULT_ALPHAMAX),
  96. "Max aggregation value to test (1 = no aggregation, 0 = no limit)")
  97. ("fitness,x",
  98. po::value<int>((int*)&varsPtr->fitness)->default_value((int)DEFAULT_FITNESSMETHOD),
  99. "Set fitness method to: \n0=SUM Sum of the times on each task\n1=MAX Max of server times + Max of client times\n2=CLOUD Dollars in a cloud model (see sourcecode)");
  100. }
  101. void defineHiddenOptions(FixedVars* varsPtr, po::options_description* odptr){
  102. odptr->add_options()
  103. ("no-pipeline", "No pipeline mode\n")
  104. ("reclvl",
  105. po::value<unsigned int>(),
  106. "Number of dimension used for database representation");
  107. }
  108. void processOptions(FixedVars* varsPtr, ClientParams* paramsPtr, po::variables_map vm){
  109. // Client options
  110. if(vm.count("serverip"))
  111. {
  112. std::cout << "CLI: Server ip set to " << paramsPtr->server_ip << std::endl;
  113. }
  114. if(vm.count("port"))
  115. {
  116. std::cout << "CLI: Upload port set to " << paramsPtr->port << std::endl;
  117. }
  118. if(vm.count("autochoice"))
  119. {
  120. std::cout << "CLI: Auto-choice activated" << std::endl;
  121. paramsPtr->autochoice = true;
  122. }
  123. if(vm.count("dry-run"))
  124. {
  125. std::cout << "CLI: Dry-run mode activated" << std::endl;
  126. paramsPtr->dryrunmode = true;
  127. varsPtr->n = DEFAULT_N;
  128. varsPtr->l = DEFAULT_L;
  129. varsPtr->Tupc = DEFAULT_TUPC;
  130. varsPtr->Tdos = DEFAULT_TUPC;
  131. varsPtr->Tdoc = DEFAULT_TDOC;
  132. varsPtr->Tups = DEFAULT_TDOC;
  133. std::cout << "CLI: Setting default values for dry-run mode (a thousand mp3 files, 100MBit/s connection)" <<std::endl;
  134. }
  135. if(vm.count("verbose-optim"))
  136. {
  137. std::cout << "CLI: Will ask the optimizer to be more verbose" << std::endl;
  138. paramsPtr->verboseoptim = true;
  139. }
  140. if(vm.count("dont-write"))
  141. {
  142. std::cout << "CLI: Will ask PIRReplyWriter not to write to a file" << std::endl;
  143. paramsPtr->dontwrite = true;
  144. }
  145. else paramsPtr->dontwrite = false;
  146. // Optimizer options
  147. if(vm.count("file-nbr"))
  148. {
  149. if(vm.count("dry-run"))
  150. {
  151. varsPtr->n = vm["file-nbr"].as<uint64_t>();
  152. std::cout << "CLI: Changing number of database elements to "\
  153. << varsPtr->n << std::endl;
  154. }
  155. else
  156. {
  157. std::cout << "CLI: Option -n,--file-nbr ignored as we are not in dry-run mode"\
  158. << std::endl;
  159. }
  160. }
  161. if(vm.count("file-size")) {
  162. if(vm.count("dry-run"))
  163. {
  164. varsPtr->l = vm["file-size"].as<uint64_t>();
  165. std::cout << "CLI: Changing database element size to " << varsPtr->l <<std::endl;
  166. }
  167. else
  168. {
  169. std::cout << "CLI: Option -l,--file-size ignored as we are not in dry-run mode"
  170. << std::endl;
  171. }
  172. }
  173. if (vm.count("upload"))
  174. {
  175. varsPtr->Tupc = vm["upload"].as<double>();
  176. varsPtr->Tdos = varsPtr->Tupc;
  177. cout << "CLI: Upload speed forced to "<< varsPtr->Tupc << endl;
  178. }
  179. if (vm.count("download"))
  180. {
  181. varsPtr->Tdoc = vm["download"].as<double>();
  182. varsPtr->Tups = varsPtr->Tdoc;
  183. cout << "CLI: Download speed forced to "<< varsPtr->Tdoc << endl;
  184. }
  185. if(vm.count("crypto-params"))
  186. {
  187. std::cout << "CLI: Crypto parameters set to " << varsPtr->manual_crypto_params << std::endl;
  188. std::vector<std::string> fields;
  189. boost::algorithm::split(fields, varsPtr->manual_crypto_params, boost::algorithm::is_any_of(":"));
  190. if (fields.size()>1 && atoi(fields[1].c_str()) > 0)
  191. {
  192. varsPtr->k = atoi(fields[1].c_str());
  193. }
  194. if (fields.size()>4)
  195. {
  196. std::cout << "CLI: WARNING Absorption size will be overriden by the optimizer" << varsPtr->manual_crypto_params << std::endl;
  197. varsPtr->k = 0;
  198. }
  199. }
  200. if(vm.count("security"))
  201. {
  202. std::cout << "CLI: Security set to " << varsPtr->k << std::endl;
  203. }
  204. if (vm.count("dmin"))
  205. {
  206. cout << "CLI: Minimum recursion level set to "<< varsPtr->dMin << endl;
  207. }
  208. if (vm.count("dmax"))
  209. {
  210. cout << "CLI: Maximum recursion level set to "<< varsPtr->dMax << endl;
  211. }
  212. if(vm.count("alphaMax"))
  213. {
  214. varsPtr->alphaMax = vm["alphaMax"].as<unsigned int>();
  215. cout << "CLI: Max aggregation set to "<< varsPtr->alphaMax << endl;
  216. }
  217. if(vm.count("fitness"))
  218. {
  219. cout << "CLI: Fitness method set to "<< varsPtr->fitness << endl;
  220. }
  221. // Hidden options
  222. if (vm.count("reclvl"))
  223. {
  224. varsPtr->dMax = vm["reclvl"].as<unsigned int>();
  225. varsPtr->dMin = vm["reclvl"].as<unsigned int>();
  226. cout << "CLI: Recursion level forced to "<< varsPtr->dMax << endl;
  227. }
  228. if (vm.count("no-pipeline"))
  229. {
  230. std::cout << "CLI: WARNING no pipeline mode activated" << std::endl;
  231. no_pipeline = true;
  232. }
  233. }
  234. int main(int argc, char** argv)
  235. {
  236. boost::asio::io_service ios;
  237. // Vars for the optimizer (and pot. client)
  238. FixedVars fixedVars = {}; // Inits to default value all fields
  239. // Vars for the client only
  240. ClientParams clientParams = {}; // Same here
  241. // Add and define options
  242. po::options_description od("Client options");
  243. po::options_description optimizeropts("Optimizer options");
  244. po::options_description hidden("Hidden options");
  245. defineOptimizerOptions(&fixedVars, &optimizeropts);
  246. defineClientOptions(&clientParams, &od);
  247. defineHiddenOptions(&fixedVars, &hidden);
  248. // Set which options are visible and which not
  249. po::options_description visible;
  250. visible.add(od).add(optimizeropts);
  251. po::options_description all;
  252. all.add(visible).add(hidden);
  253. po::variables_map vm;
  254. // Parse options from command line
  255. try {
  256. po::store(po::parse_command_line(argc, argv, all), vm);
  257. }
  258. catch (const std::exception& ex)
  259. {
  260. std::cout << "CLI: Error checking program options: " << ex.what() << std::endl;
  261. std::cout << visible << std::endl;
  262. return 1;
  263. }
  264. po::notify(vm);
  265. // Show usage help if requested
  266. if(vm.count("help")) {
  267. std::cout << visible << endl;
  268. return 0;
  269. }
  270. // Set variables according to options
  271. processOptions(&fixedVars, &clientParams, vm);
  272. // If we are on dry-run mode run only the optimizer not the client
  273. if(vm.count("dry-run"))
  274. {
  275. std::cout << "CLI: Dry-run mode activated" << std::endl;
  276. // The optimizer connects to the same PIR server but on a higher port for
  277. // optimization related exchanges
  278. PIROptimizer optimizer(clientParams.server_ip, clientParams.port, fixedVars.fitness);
  279. if (vm.count("file"))
  280. {
  281. int experience_nbr = OptimService::getNumberOfExperiences(fileToOptimizeFrom);
  282. if(experience_nbr == -1)
  283. {
  284. cout << "CLI: Unable to open : " << fileToOptimizeFrom << " aborting" << endl;
  285. cout << "CLI: Try exp/sample.conf to test a predefined set of configurations" << endl;
  286. return 1;
  287. }
  288. for (int exp_i = 0 ; exp_i <= experience_nbr ; exp_i++)
  289. {
  290. OptimService::readTestValues(exp_i, fixedVars, fileToOptimizeFrom);
  291. OptimService::writeHeadFile(exp_i, fixedVars);
  292. optimizer.optimize(fixedVars, exp_i);
  293. }
  294. }
  295. else
  296. {
  297. cout << "CLI: Default example : A thousand mp3 files, ADSL, no aggregation, k=80" << endl;
  298. cout << "CLI: n : " << fixedVars.n << " l : " << fixedVars.l;
  299. cout << "CLI: Tupc : " << fixedVars.Tupc << " Tdoc : " << fixedVars.Tdoc << endl;
  300. OptimService::writeHeadFile(0, fixedVars);
  301. optimizer.optimize(fixedVars, 0);
  302. }
  303. return 0;
  304. }
  305. // If we are not in dry-run mode create client and controller
  306. PIRClientSimple client(ios, clientParams, fixedVars);
  307. PIRController controller(client);
  308. // Set no_pipeline if needed
  309. if(no_pipeline) client.no_pipeline(true);
  310. // Start by connecting to the PIR server
  311. client.connect();
  312. // Downloads the file catalog
  313. client.downloadCatalog();
  314. // Get from the server whether we are in client-driven mode or not
  315. client.rcvPIRParamsExchangeMethod();
  316. // Use the optimizer to choose best parameters
  317. // (returns immediately in server-driven mode)
  318. client.optimize();
  319. // Send PIR and cryptographic parameters to the server in client-driven mode
  320. // and receive and process them in server-driven mode
  321. client.processCryptoParams();
  322. client.processPIRParams();
  323. /*User chooses the file here.*/
  324. client.chooseFile();
  325. double start = omp_get_wtime();
  326. /* Asynchronously generate and send the request
  327. separately in two threads*/
  328. client.startProcessQuery();
  329. /* Receive asynchronously the response from the server and
  330. asynchronously writes it */
  331. client.startProcessResult();
  332. client.joinAllThreads();
  333. double end = omp_get_wtime();
  334. cout << "CLI: Query RTT was " << end-start << " seconds" << endl;
  335. cout << "CLI: Exiting..." << endl;
  336. return EXIT_SUCCESS;
  337. }