diff --git a/core/pom.xml b/core/pom.xml index 2784fc501..e1b40ef98 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -11,7 +11,7 @@ dk.alexandra.fresco master-pom - 1.3.4-SNAPSHOT + 1.3.5 diff --git a/core/src/main/java/dk/alexandra/fresco/framework/network/socket/Connector.java b/core/src/main/java/dk/alexandra/fresco/framework/network/socket/Connector.java index 31a723d9f..c0fafda10 100644 --- a/core/src/main/java/dk/alexandra/fresco/framework/network/socket/Connector.java +++ b/core/src/main/java/dk/alexandra/fresco/framework/network/socket/Connector.java @@ -2,26 +2,20 @@ import dk.alexandra.fresco.framework.Party; import dk.alexandra.fresco.framework.configuration.NetworkConfiguration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.net.ServerSocketFactory; +import javax.net.SocketFactory; +import javax.net.ssl.SSLHandshakeException; import java.io.IOException; import java.net.ConnectException; import java.net.ServerSocket; import java.net.Socket; import java.time.Duration; -import java.time.Instant; import java.util.HashMap; import java.util.Map; -import java.util.concurrent.CompletionService; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorCompletionService; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import javax.net.ServerSocketFactory; -import javax.net.SocketFactory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import java.util.concurrent.*; public class Connector implements NetworkConnector { @@ -73,35 +67,45 @@ public Map getSocketMap() { */ private Map connectNetwork(final NetworkConfiguration conf, final Duration timeout) { + Map socketMap = new HashMap<>(conf.noOfParties()); + // We use two threads. One for the client connections and one for the server connections. final int connectionThreads = 2; ExecutorService connectionExecutor = Executors.newFixedThreadPool(connectionThreads); + // If either the client or the server thread fails we would like cancel the other as soon as // possible. For this purpose we use a CompletionService. - CompletionService> connectionService = - new ExecutorCompletionService<>(connectionExecutor); - connectionService.submit(() -> connectClient(conf)); - connectionService.submit(() -> connectServer(conf)); - Duration remainingTime = timeout; - try { - Instant start = Instant.now(); - for (int i = 0; i < connectionThreads; i++) { - remainingTime = remainingTime.minus(Duration.between(start, Instant.now())); - Future> completed = - connectionService.poll(remainingTime.toMillis(), TimeUnit.MILLISECONDS); - if (completed == null) { - throw new TimeoutException("Timed out waiting for client connections"); + + try (ServerSocket server = serverFactory.createServerSocket(conf.getMe().getPort())) { + Future> clients = connectionExecutor.submit(() -> connectClient(conf)); + Future> servers = connectionExecutor.submit(() -> connectServer(server, conf)); + connectionExecutor.shutdown(); + boolean termination = connectionExecutor.awaitTermination(timeout.toMillis(), TimeUnit.MILLISECONDS); + if (!termination) { + throw new RuntimeException("Timed out waiting for client connections"); + } + socketMap.putAll(servers.get()); + socketMap.putAll(clients.get()); + } catch (ExecutionException | IOException | InterruptedException e) { + for (Map.Entry entry : socketMap.entrySet()) { + // In case the first completed successfully but the other did not. + try { + entry.getValue().close(); + } + catch (IOException ignored){ + // ignore, we don't care that it is already closed. + } + } + // These two exceptions are expected in this form for some tests, they might break things if they change (maybe). + if (e instanceof ExecutionException || e instanceof IOException) { + // HandshakeExceptions need to be explicit. + if (e.getCause() instanceof SSLHandshakeException) { + throw new RuntimeException("Failed to connect network", e.getCause()); } else { - // Below, will either collect the connections made by the completed thread, or throw an - // ExecutionException, if the thread failed while trying to make the required connections. - socketMap.putAll(completed.get()); + throw new RuntimeException("Failed to connect network", e); } } - } catch (ExecutionException e) { - throw new RuntimeException("Failed to connect network", e.getCause()); - } catch (Exception e) { - throw new RuntimeException("Failed to connect network", e); } finally { connectionExecutor.shutdownNow(); } @@ -117,50 +121,60 @@ private Map connectNetwork(final NetworkConfiguration conf, private Map connectClient(final NetworkConfiguration conf) throws InterruptedException, IOException { Map socketMap = new HashMap<>(conf.noOfParties() - conf.getMyId()); - for (int i = conf.getMyId() + 1; i <= conf.noOfParties(); i++) { - Party p = conf.getParty(i); - boolean connectionMade = false; - int attempts = 0; - while (!connectionMade) { - try { - Socket sock = socketFactory.createSocket(p.getHostname(), p.getPort()); - for (int j = 0; j < PARTY_ID_BYTES; j++) { - byte b = (byte) (conf.getMyId() >>> j * Byte.SIZE); - sock.getOutputStream().write(b); + try { + for (int i = conf.getMyId() + 1; i <= conf.noOfParties(); i++) { + // TODO: Split this up into N async tasks instead + Party p = conf.getParty(i); + boolean connectionMade = false; + int attempts = 0; + while (!connectionMade) { + try { + Socket sock = socketFactory.createSocket(p.getHostname(), p.getPort()); + for (int j = 0; j < PARTY_ID_BYTES; j++) { + byte b = (byte) (conf.getMyId() >>> j * Byte.SIZE); + sock.getOutputStream().write(b); + } + connectionMade = true; + socketMap.put(i, sock); + logger.info("P{}: connected to {}", conf.getMyId(), p); + } catch (ConnectException e) { + // A ConnectionException is expected if the opposing side is not listening for our + // connection attempt yet. We ignore this and try again. + Thread.sleep(1L << ++attempts); + // This should probably not busy-wait for each party } - connectionMade = true; - socketMap.put(i, sock); - logger.info("P{}: connected to {}", conf.getMyId(), p); - } catch (ConnectException e) { - // A connect exception is expected if the opposing side is not listening for our - // connection attempt yet. We ignore this and try again. - Thread.sleep(1 << ++attempts); } } } + catch (Exception e) { + for (Map.Entry entry : socketMap.entrySet()) { + entry.getValue().close(); + } + throw e; + } return socketMap; } /** * Listens for connections from the opposing parties with lower id's. - * - * @throws IOException thrown if an {@link IOException} occurs while listening. */ - private Map connectServer(final NetworkConfiguration conf) throws IOException { + private Map connectServer(ServerSocket server, final NetworkConfiguration conf) { Map socketMap = new HashMap<>(conf.getMyId() - 1); if (conf.getMyId() > 1) { - try (ServerSocket server = serverFactory.createServerSocket(conf.getMe().getPort())) { + try { logger.info("P{}: bound at port {}", conf.getMyId(), conf.getMe().getPort()); - for (int i = 1; i < conf.getMyId(); i++) { - Socket sock = server.accept(); - int id = 0; - for (int j = 0; j < PARTY_ID_BYTES; j++) { - id ^= sock.getInputStream().read() << j * Byte.SIZE; - } - socketMap.put(id, sock); - logger.info("P{}: accepted connection from P{}", conf.getMyId(), id); - socketMap.put(id, sock); + for (int i = 1; i < conf.getMyId(); i++) { + Socket sock = server.accept(); + int id = 0; + for (int j = 0; j < PARTY_ID_BYTES; j++) { + id ^= sock.getInputStream().read() << j * Byte.SIZE; } + socketMap.put(id, sock); + logger.info("P{}: accepted connection from P{}", conf.getMyId(), id); + socketMap.put(id, sock); + } + } catch (IOException e) { + logger.info(e.getMessage()); } } return socketMap; diff --git a/core/src/main/java/dk/alexandra/fresco/framework/network/socket/SocketNetwork.java b/core/src/main/java/dk/alexandra/fresco/framework/network/socket/SocketNetwork.java index 54cebd17f..43745da4b 100644 --- a/core/src/main/java/dk/alexandra/fresco/framework/network/socket/SocketNetwork.java +++ b/core/src/main/java/dk/alexandra/fresco/framework/network/socket/SocketNetwork.java @@ -3,22 +3,19 @@ import dk.alexandra.fresco.framework.configuration.NetworkConfiguration; import dk.alexandra.fresco.framework.network.CloseableNetwork; import dk.alexandra.fresco.framework.util.ExceptionConverter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.net.ServerSocketFactory; +import javax.net.SocketFactory; +import java.io.IOException; import java.net.Socket; import java.time.Duration; import java.time.temporal.ChronoUnit; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; -import java.util.Objects; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; -import javax.net.ServerSocketFactory; -import javax.net.SocketFactory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * A {@link CloseableNetwork} implementation based on regular the {@link Socket} interface (i.e., @@ -194,10 +191,10 @@ private void closeCommunication() { r.stop(); } for (Socket sock : sockets) { - ExceptionConverter.safe(() -> { + try { sock.close(); - return null; - }, "Unable to properly close socket"); + } catch (IOException ignored) { + } } } diff --git a/core/src/test/java/dk/alexandra/fresco/framework/network/socket/TestConnector.java b/core/src/test/java/dk/alexandra/fresco/framework/network/socket/TestConnector.java index 63add5d46..d111f958d 100644 --- a/core/src/test/java/dk/alexandra/fresco/framework/network/socket/TestConnector.java +++ b/core/src/test/java/dk/alexandra/fresco/framework/network/socket/TestConnector.java @@ -1,6 +1,10 @@ package dk.alexandra.fresco.framework.network.socket; import dk.alexandra.fresco.framework.configuration.NetworkConfiguration; +import dk.alexandra.fresco.framework.configuration.NetworkUtil; +import org.junit.Ignore; +import org.junit.Test; + import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -8,8 +12,6 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; -import dk.alexandra.fresco.framework.configuration.NetworkUtil; -import org.junit.Test; /** * Note: this test simply covers code not tested in {@link TestSocketNetwork}. @@ -17,6 +19,7 @@ public class TestConnector { @Test(expected = InterruptedException.class) + @Ignore("There is no reason for this to fail anymore") public void testInterruptWhileConnecting() throws Throwable { ExecutorService es = Executors.newFixedThreadPool(2); Map confs = NetworkUtil.getNetworkConfigurations(2); diff --git a/demos/aes/pom.xml b/demos/aes/pom.xml index 45d034623..cee2526f4 100644 --- a/demos/aes/pom.xml +++ b/demos/aes/pom.xml @@ -3,7 +3,7 @@ dk.alexandra.fresco demos - 1.3.4-SNAPSHOT + 1.3.5 4.0.0 @@ -19,7 +19,7 @@ dk.alexandra.fresco bristol - 1.3.4-SNAPSHOT + 1.3.5 diff --git a/demos/aggregation/pom.xml b/demos/aggregation/pom.xml index 248d461b3..b8aa2d03e 100644 --- a/demos/aggregation/pom.xml +++ b/demos/aggregation/pom.xml @@ -4,7 +4,7 @@ dk.alexandra.fresco demos - 1.3.4-SNAPSHOT + 1.3.5 4.0.0 diff --git a/demos/common/pom.xml b/demos/common/pom.xml index 03b7916bc..18220e4b4 100644 --- a/demos/common/pom.xml +++ b/demos/common/pom.xml @@ -3,7 +3,7 @@ dk.alexandra.fresco demos - 1.3.4-SNAPSHOT + 1.3.5 4.0.0 diff --git a/demos/distance/pom.xml b/demos/distance/pom.xml index c252c98ee..6e51f51c1 100644 --- a/demos/distance/pom.xml +++ b/demos/distance/pom.xml @@ -3,7 +3,7 @@ dk.alexandra.fresco demos - 1.3.4-SNAPSHOT + 1.3.5 4.0.0 diff --git a/demos/pom.xml b/demos/pom.xml index 4b8988af8..d310eb5fb 100644 --- a/demos/pom.xml +++ b/demos/pom.xml @@ -3,7 +3,7 @@ dk.alexandra.fresco master-pom - 1.3.4-SNAPSHOT + 1.3.5 4.0.0 diff --git a/demos/psi/pom.xml b/demos/psi/pom.xml index 8077e2bc4..f7e76a3c6 100644 --- a/demos/psi/pom.xml +++ b/demos/psi/pom.xml @@ -3,7 +3,7 @@ dk.alexandra.fresco demos - 1.3.4-SNAPSHOT + 1.3.5 4.0.0 @@ -19,7 +19,7 @@ dk.alexandra.fresco bristol - 1.3.4-SNAPSHOT + 1.3.5 diff --git a/demos/sum/pom.xml b/demos/sum/pom.xml index 2c35738d9..292c3151b 100644 --- a/demos/sum/pom.xml +++ b/demos/sum/pom.xml @@ -3,7 +3,7 @@ dk.alexandra.fresco demos - 1.3.4-SNAPSHOT + 1.3.5 4.0.0 diff --git a/lib/bristol/pom.xml b/lib/bristol/pom.xml index 121d2c6c3..b0c851336 100644 --- a/lib/bristol/pom.xml +++ b/lib/bristol/pom.xml @@ -42,6 +42,6 @@ fresco-lib-pom dk.alexandra.fresco - 1.3.4-SNAPSHOT + 1.3.5 diff --git a/lib/common/pom.xml b/lib/common/pom.xml index 09c93e06f..47fea31e1 100644 --- a/lib/common/pom.xml +++ b/lib/common/pom.xml @@ -6,7 +6,7 @@ fresco-lib-pom dk.alexandra.fresco - 1.3.4-SNAPSHOT + 1.3.5 4.0.0 diff --git a/lib/dea/pom.xml b/lib/dea/pom.xml index 0891f765e..a74262446 100644 --- a/lib/dea/pom.xml +++ b/lib/dea/pom.xml @@ -55,7 +55,7 @@ fresco-lib-pom dk.alexandra.fresco - 1.3.4-SNAPSHOT + 1.3.5 diff --git a/lib/debug/pom.xml b/lib/debug/pom.xml index bbddaf816..a89b1ba8a 100644 --- a/lib/debug/pom.xml +++ b/lib/debug/pom.xml @@ -5,7 +5,7 @@ fresco-lib-pom dk.alexandra.fresco - 1.3.4-SNAPSHOT + 1.3.5 4.0.0 diff --git a/lib/fixed/pom.xml b/lib/fixed/pom.xml index e17f90d22..56c24433b 100644 --- a/lib/fixed/pom.xml +++ b/lib/fixed/pom.xml @@ -5,7 +5,7 @@ fresco-lib-pom dk.alexandra.fresco - 1.3.4-SNAPSHOT + 1.3.5 4.0.0 diff --git a/lib/list/pom.xml b/lib/list/pom.xml index 826778a26..c1f5a6bb3 100644 --- a/lib/list/pom.xml +++ b/lib/list/pom.xml @@ -5,7 +5,7 @@ fresco-lib-pom dk.alexandra.fresco - 1.3.4-SNAPSHOT + 1.3.5 4.0.0 diff --git a/lib/lp/pom.xml b/lib/lp/pom.xml index 8ad2e91ae..f723d5f48 100644 --- a/lib/lp/pom.xml +++ b/lib/lp/pom.xml @@ -51,6 +51,6 @@ fresco-lib-pom dk.alexandra.fresco - 1.3.4-SNAPSHOT + 1.3.5 diff --git a/lib/mimc/pom.xml b/lib/mimc/pom.xml index 93c32d7ad..ca23cb76b 100644 --- a/lib/mimc/pom.xml +++ b/lib/mimc/pom.xml @@ -6,7 +6,7 @@ fresco-lib-pom dk.alexandra.fresco - 1.3.4-SNAPSHOT + 1.3.5 4.0.0 diff --git a/lib/pom.xml b/lib/pom.xml index 4a10991f9..514c5a629 100644 --- a/lib/pom.xml +++ b/lib/pom.xml @@ -19,6 +19,6 @@ master-pom dk.alexandra.fresco - 1.3.4-SNAPSHOT + 1.3.5 diff --git a/pom.xml b/pom.xml index 7d99405b7..7e1e812ff 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ dk.alexandra.fresco master-pom - 1.3.4-SNAPSHOT + 1.3.5 pom FRESCO parent pom diff --git a/suite/pom.xml b/suite/pom.xml index d6c6d5a42..31bf1c323 100644 --- a/suite/pom.xml +++ b/suite/pom.xml @@ -3,7 +3,7 @@ dk.alexandra.fresco master-pom - 1.3.4-SNAPSHOT + 1.3.5 4.0.0 diff --git a/suite/spdz/pom.xml b/suite/spdz/pom.xml index ea3429261..2e28f3c41 100644 --- a/suite/spdz/pom.xml +++ b/suite/spdz/pom.xml @@ -6,7 +6,7 @@ dk.alexandra.fresco fresco-protocol-suites-pom - 1.3.4-SNAPSHOT + 1.3.5 4.0.0 @@ -71,68 +71,68 @@ dk.alexandra.fresco dea - 1.3.4-SNAPSHOT + 1.3.5 test-jar test dk.alexandra.fresco dea - 1.3.4-SNAPSHOT + 1.3.5 test dk.alexandra.fresco lp - 1.3.4-SNAPSHOT + 1.3.5 test-jar test dk.alexandra.fresco lp - 1.3.4-SNAPSHOT + 1.3.5 test dk.alexandra.fresco mimc - 1.3.4-SNAPSHOT + 1.3.5 test-jar test dk.alexandra.fresco common - 1.3.4-SNAPSHOT + 1.3.5 test-jar test dk.alexandra.fresco fixed - 1.3.4-SNAPSHOT + 1.3.5 test-jar test dk.alexandra.fresco list - 1.3.4-SNAPSHOT + 1.3.5 test-jar test dk.alexandra.fresco commitment - 1.3.4-SNAPSHOT + 1.3.5 test-jar test dk.alexandra.fresco mimc - 1.3.4-SNAPSHOT + 1.3.5 test diff --git a/suite/spdz2k/pom.xml b/suite/spdz2k/pom.xml index b81c5210e..b99336c15 100644 --- a/suite/spdz2k/pom.xml +++ b/suite/spdz2k/pom.xml @@ -6,7 +6,7 @@ dk.alexandra.fresco fresco-protocol-suites-pom - 1.3.4-SNAPSHOT + 1.3.5 4.0.0 diff --git a/suite/tinytables/pom.xml b/suite/tinytables/pom.xml index ffc9fc434..4a676cab5 100644 --- a/suite/tinytables/pom.xml +++ b/suite/tinytables/pom.xml @@ -7,7 +7,7 @@ dk.alexandra.fresco fresco-protocol-suites-pom - 1.3.4-SNAPSHOT + 1.3.5 4.0.0 @@ -57,12 +57,12 @@ dk.alexandra.fresco common - 1.3.4-SNAPSHOT + 1.3.5 dk.alexandra.fresco ot - 1.3.4-SNAPSHOT + 1.3.5 diff --git a/tools/bitTriples/pom.xml b/tools/bitTriples/pom.xml index 449659653..61f7a5923 100644 --- a/tools/bitTriples/pom.xml +++ b/tools/bitTriples/pom.xml @@ -5,7 +5,7 @@ tools-master-pom dk.alexandra.fresco - 1.3.4-SNAPSHOT + 1.3.5 4.0.0 diff --git a/tools/commitment/pom.xml b/tools/commitment/pom.xml index 75b9b7a83..f6ea0654a 100644 --- a/tools/commitment/pom.xml +++ b/tools/commitment/pom.xml @@ -8,7 +8,7 @@ dk.alexandra.fresco tools-master-pom - 1.3.4-SNAPSHOT + 1.3.5 4.0.0 @@ -39,7 +39,7 @@ dk.alexandra.fresco test test-jar - 1.3.4-SNAPSHOT + 1.3.5 diff --git a/tools/mascot/pom.xml b/tools/mascot/pom.xml index 05aba3064..ae2576ac4 100644 --- a/tools/mascot/pom.xml +++ b/tools/mascot/pom.xml @@ -8,7 +8,7 @@ dk.alexandra.fresco tools-master-pom - 1.3.4-SNAPSHOT + 1.3.5 4.0.0 diff --git a/tools/ot/pom.xml b/tools/ot/pom.xml index 0abf4be64..cb741f671 100644 --- a/tools/ot/pom.xml +++ b/tools/ot/pom.xml @@ -7,7 +7,7 @@ dk.alexandra.fresco tools-master-pom - 1.3.4-SNAPSHOT + 1.3.5 4.0.0 @@ -19,7 +19,7 @@ dk.alexandra.fresco commitment - 1.3.4-SNAPSHOT + 1.3.5 org.bouncycastle diff --git a/tools/pom.xml b/tools/pom.xml index 0c9d2f34b..7d4776fcf 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -4,7 +4,7 @@ dk.alexandra.fresco master-pom - 1.3.4-SNAPSHOT + 1.3.5 4.0.0