/** \file connection.cpp \author michael.zohner@ec-spride.de \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation Copyright (C) 2019 ENCRYPTO Group, TU Darmstadt This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ABY is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . \brief Connection Implementation */ #include "connection.h" #include "constants.h" #include "socket.h" #include "utils.h" #include #include #include bool Connect(const std::string& address, uint16_t port, std::vector> &sockets, uint32_t id) { #ifndef BATCH std::cout << "Connecting party "<< id <<": " << address << ", " << port << std::endl; #endif assert(sockets.size() <= std::numeric_limits::max()); for (size_t j = 0; j < sockets.size(); j++) { sockets[j] = Connect(address, port); if (sockets[j]) { // handshake sockets[j]->Send(&id, sizeof(id)); uint32_t index = static_cast(j); sockets[j]->Send(&index, sizeof(index)); } else { return false; } } return true; } bool Listen(const std::string& address, uint16_t port, std::vector>> &sockets, size_t numConnections, uint32_t myID) { auto listen_socket = std::make_unique(); if (!listen_socket->Bind(address, port)) { std::cerr << "Error: a socket could not be bound\n"; return false; } if (!listen_socket->Listen()) { std::cerr << "Error: could not listen on the socket \n"; return false; } for (size_t i = 0; i < numConnections; i++) { auto sock = listen_socket->Accept(); if (!sock) { std::cerr << "Error: could not accept connection\n"; return false; } // receive initial pid when connected uint32_t nID; uint32_t conID; //a mix of threadID and role - depends on the application sock->Receive(&nID, sizeof(nID)); sock->Receive(&conID, sizeof(conID)); if (nID >= sockets.size()) //Not more than two parties currently allowed { sock->Close(); i--; // try same index again continue; } if (conID >= sockets[myID].size()) { sock->Close(); i--; // try same index again continue; } // locate the socket appropriately sockets[nID][conID] = std::move(sock); } #ifndef BATCH std::cout << "Listening finished" << std::endl; #endif return true; } std::unique_ptr Connect(const std::string& address, uint16_t port) { auto socket = std::make_unique(); for (int i = 0; i < RETRY_CONNECT; i++) { if (socket->Connect(address, port)) return socket; SleepMiliSec(10); } std::cerr << "Connect failed due to timeout!\n"; return nullptr; } std::unique_ptr Listen(const std::string& address, uint16_t port) { auto listen_socket = std::make_unique(); if (!listen_socket->Bind(address, port)) { return nullptr; } if (!listen_socket->Listen()) { return nullptr; } return listen_socket->Accept(); }