mpcio.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. #include "mpcio.hpp"
  2. // The port number for the P1 -> P0 connection
  3. static const unsigned short port_p1_p0 = 2115;
  4. // The port number for the P2 -> P0 connection
  5. static const unsigned short port_p2_p0 = 2116;
  6. // The port number for the P2 -> P1 connection
  7. static const unsigned short port_p2_p1 = 2117;
  8. void mpcio_setup_computational(unsigned player,
  9. boost::asio::io_context &io_context,
  10. const char *p0addr, // can be NULL when player=0
  11. int num_threads,
  12. std::deque<tcp::socket> &peersocks,
  13. std::deque<tcp::socket> &serversocks)
  14. {
  15. if (player == 0) {
  16. // Listen for connections from P1 and from P2
  17. tcp::acceptor acceptor_p1(io_context,
  18. tcp::endpoint(tcp::v4(), port_p1_p0));
  19. tcp::acceptor acceptor_p2(io_context,
  20. tcp::endpoint(tcp::v4(), port_p2_p0));
  21. peersocks.clear();
  22. serversocks.clear();
  23. for (int i=0;i<num_threads;++i) {
  24. peersocks.emplace_back(io_context);
  25. serversocks.emplace_back(io_context);
  26. }
  27. for (int i=0;i<num_threads;++i) {
  28. tcp::socket peersock = acceptor_p1.accept();
  29. // Read 2 bytes from the socket, which will be the thread
  30. // number
  31. unsigned short thread_num;
  32. boost::asio::read(peersock,
  33. boost::asio::buffer(&thread_num, sizeof(thread_num)));
  34. if (thread_num >= num_threads) {
  35. std::cerr << "Received bad thread number from peer\n";
  36. } else {
  37. peersocks[thread_num] = std::move(peersock);
  38. }
  39. }
  40. for (int i=0;i<num_threads;++i) {
  41. tcp::socket serversock = acceptor_p2.accept();
  42. // Read 2 bytes from the socket, which will be the thread
  43. // number
  44. unsigned short thread_num;
  45. boost::asio::read(serversock,
  46. boost::asio::buffer(&thread_num, sizeof(thread_num)));
  47. if (thread_num >= num_threads) {
  48. std::cerr << "Received bad thread number from server\n";
  49. } else {
  50. serversocks[thread_num] = std::move(serversock);
  51. }
  52. }
  53. } else if (player == 1) {
  54. // Listen for connections from P2, make num_threads connections to P0
  55. tcp::acceptor acceptor_p2(io_context,
  56. tcp::endpoint(tcp::v4(), port_p2_p1));
  57. tcp::resolver resolver(io_context);
  58. boost::system::error_code err;
  59. peersocks.clear();
  60. serversocks.clear();
  61. for (int i=0;i<num_threads;++i) {
  62. serversocks.emplace_back(io_context);
  63. }
  64. for (unsigned short thread_num = 0; thread_num < num_threads; ++thread_num) {
  65. tcp::socket peersock(io_context);
  66. while(1) {
  67. boost::asio::connect(peersock,
  68. resolver.resolve(p0addr, std::to_string(port_p1_p0)), err);
  69. if (!err) break;
  70. std::cerr << "Connection to p0 refused, will retry.\n";
  71. sleep(1);
  72. }
  73. // Write 2 bytes to the socket indicating which thread
  74. // number this socket is for
  75. boost::asio::write(peersock,
  76. boost::asio::buffer(&thread_num, sizeof(thread_num)));
  77. peersocks.push_back(std::move(peersock));
  78. }
  79. for (int i=0;i<num_threads;++i) {
  80. tcp::socket serversock = acceptor_p2.accept();
  81. // Read 2 bytes from the socket, which will be the thread
  82. // number
  83. unsigned short thread_num;
  84. boost::asio::read(serversock,
  85. boost::asio::buffer(&thread_num, sizeof(thread_num)));
  86. if (thread_num >= num_threads) {
  87. std::cerr << "Received bad thread number from server\n";
  88. } else {
  89. serversocks[thread_num] = std::move(serversock);
  90. }
  91. }
  92. } else {
  93. std::cerr << "Invalid player number passed to mpcio_setup_computational\n";
  94. }
  95. }
  96. void mpcio_setup_server(boost::asio::io_context &io_context,
  97. const char *p0addr, const char *p1addr, int num_threads,
  98. std::deque<tcp::socket> &p0socks,
  99. std::deque<tcp::socket> &p1socks)
  100. {
  101. // Make connections to P0 and P1
  102. tcp::resolver resolver(io_context);
  103. boost::system::error_code err;
  104. p0socks.clear();
  105. p1socks.clear();
  106. for (unsigned short thread_num = 0; thread_num < num_threads; ++thread_num) {
  107. tcp::socket p0sock(io_context);
  108. while(1) {
  109. boost::asio::connect(p0sock,
  110. resolver.resolve(p0addr, std::to_string(port_p2_p0)), err);
  111. if (!err) break;
  112. std::cerr << "Connection to p0 refused, will retry.\n";
  113. sleep(1);
  114. }
  115. // Write 2 bytes to the socket indicating which thread
  116. // number this socket is for
  117. boost::asio::write(p0sock,
  118. boost::asio::buffer(&thread_num, sizeof(thread_num)));
  119. p0socks.push_back(std::move(p0sock));
  120. }
  121. for (unsigned short thread_num = 0; thread_num < num_threads; ++thread_num) {
  122. tcp::socket p1sock(io_context);
  123. while(1) {
  124. boost::asio::connect(p1sock,
  125. resolver.resolve(p1addr, std::to_string(port_p2_p1)), err);
  126. if (!err) break;
  127. std::cerr << "Connection to p1 refused, will retry.\n";
  128. sleep(1);
  129. }
  130. // Write 2 bytes to the socket indicating which thread
  131. // number this socket is for
  132. boost::asio::write(p1sock,
  133. boost::asio::buffer(&thread_num, sizeof(thread_num)));
  134. p1socks.push_back(std::move(p1sock));
  135. }
  136. }