Repository: incubator-geode Updated Branches: refs/heads/develop a00a2ff29 -> 4265fa593
GEODE-2059 client SSL handshake attempts do not time out Client SSL connection attempts are now configured to be able to time out during the SSL handshake Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/4265fa59 Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/4265fa59 Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/4265fa59 Branch: refs/heads/develop Commit: 4265fa59346d3730b98a5949e04822512a0aa6c8 Parents: a00a2ff Author: Bruce Schuchardt <[email protected]> Authored: Wed Nov 2 12:26:12 2016 -0700 Committer: Bruce Schuchardt <[email protected]> Committed: Wed Nov 2 12:28:05 2016 -0700 ---------------------------------------------------------------------- .../cache/server/internal/LoadMonitor.java | 2 +- .../geode/internal/net/SocketCreator.java | 7 +- .../internal/net/SSLSocketIntegrationTest.java | 78 +++++++++++++++++++- 3 files changed, 83 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4265fa59/geode-core/src/main/java/org/apache/geode/cache/server/internal/LoadMonitor.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/cache/server/internal/LoadMonitor.java b/geode-core/src/main/java/org/apache/geode/cache/server/internal/LoadMonitor.java index 496dbc8..1c571a9 100644 --- a/geode-core/src/main/java/org/apache/geode/cache/server/internal/LoadMonitor.java +++ b/geode-core/src/main/java/org/apache/geode/cache/server/internal/LoadMonitor.java @@ -146,7 +146,7 @@ public class LoadMonitor implements ConnectionListener { private int skippedLoadUpdates; public PollingThread(long pollInterval, int forceUpdateFrequency) { - super("BridgeServer-LoadPollingThread"); + super("Cache Server Load Polling Thread"); this.pollInterval = pollInterval; this.forceUpdateFrequency = forceUpdateFrequency; this.setDaemon(true); http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4265fa59/geode-core/src/main/java/org/apache/geode/internal/net/SocketCreator.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/internal/net/SocketCreator.java b/geode-core/src/main/java/org/apache/geode/internal/net/SocketCreator.java index a3ba102..742e7f3 100755 --- a/geode-core/src/main/java/org/apache/geode/internal/net/SocketCreator.java +++ b/geode-core/src/main/java/org/apache/geode/internal/net/SocketCreator.java @@ -964,7 +964,7 @@ public class SocketCreator { optionalWatcher.beforeConnect(socket); } socket.connect(sockaddr, Math.max(timeout, 0)); - configureClientSSLSocket(socket); + configureClientSSLSocket(socket, timeout); return socket; } else { if (clientSide && this.clientSocketFactory != null) { @@ -1063,7 +1063,7 @@ public class SocketCreator { * When a socket is accepted from a server socket, it should be passed to this method for SSL * configuration. */ - private void configureClientSSLSocket(Socket socket) throws IOException { + private void configureClientSSLSocket(Socket socket, int timeout) throws IOException { if (socket instanceof SSLSocket) { SSLSocket sslSocket = (SSLSocket) socket; @@ -1082,6 +1082,9 @@ public class SocketCreator { } try { + if (timeout > 0) { + sslSocket.setSoTimeout(timeout); + } sslSocket.startHandshake(); SSLSession session = sslSocket.getSession(); Certificate[] peer = session.getPeerCertificates(); http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4265fa59/geode-core/src/test/java/org/apache/geode/internal/net/SSLSocketIntegrationTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/org/apache/geode/internal/net/SSLSocketIntegrationTest.java b/geode-core/src/test/java/org/apache/geode/internal/net/SSLSocketIntegrationTest.java index d5a947c..5746d9b 100755 --- a/geode-core/src/test/java/org/apache/geode/internal/net/SSLSocketIntegrationTest.java +++ b/geode-core/src/test/java/org/apache/geode/internal/net/SSLSocketIntegrationTest.java @@ -19,18 +19,25 @@ import static org.apache.geode.distributed.ConfigurationProperties.*; import static org.apache.geode.internal.security.SecurableCommunicationChannel.*; import static org.assertj.core.api.Assertions.*; +import com.jayway.awaitility.Awaitility; +import com.sun.tools.hat.internal.model.StackTrace; + import java.io.File; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.InetAddress; +import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; +import java.net.SocketTimeoutException; import java.net.URL; import java.util.Properties; +import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; +import org.apache.geode.internal.security.SecurableCommunicationChannel; import org.junit.After; import org.junit.Before; import org.junit.Rule; @@ -51,7 +58,7 @@ import org.apache.geode.test.junit.categories.IntegrationTest; * <p> * <p> * Renamed from {@code JSSESocketJUnitTest}. - * + * * @see ClientSocketFactoryIntegrationTest */ @Category(IntegrationTest.class) @@ -140,6 +147,75 @@ public class SSLSocketIntegrationTest { .until(() -> assertThat(this.messageFromClient.get()).isEqualTo(MESSAGE)); } + @Test + public void configureClientSSLSocketCanTimeOut() throws Exception { + final Semaphore serverCoordination = new Semaphore(0); + + // configure a non-SSL server socket. We will connect + // a client SSL socket to it and demonstrate that the + // handshake times out + final ServerSocket serverSocket = new ServerSocket(); + serverSocket.bind(new InetSocketAddress(SocketCreator.getLocalHost(), 0)); + Thread serverThread = new Thread() { + public void run() { + serverCoordination.release(); + try (Socket clientSocket = serverSocket.accept()) { + System.out.println("server thread accepted a connection"); + serverCoordination.acquire(); + } catch (Exception e) { + System.err.println("accept failed"); + e.printStackTrace(); + } + try { + serverSocket.close(); + } catch (IOException e) { + // ignored + } + System.out.println("server thread is exiting"); + } + }; + serverThread.setName("SocketCreatorJUnitTest serverSocket thread"); + serverThread.setDaemon(true); + serverThread.start(); + + serverCoordination.acquire(); + + SocketCreator socketCreator = + SocketCreatorFactory.getSocketCreatorForComponent(SecurableCommunicationChannel.SERVER); + + int serverSocketPort = serverSocket.getLocalPort(); + try { + Awaitility.await("connect to server socket").atMost(30, TimeUnit.SECONDS).until(() -> { + try { + Socket clientSocket = socketCreator.connectForClient( + SocketCreator.getLocalHost().getHostAddress(), serverSocketPort, 2000); + clientSocket.close(); + System.err.println( + "client successfully connected to server but should not have been able to do so"); + return false; + } catch (SocketTimeoutException e) { + // we need to verify that this timed out in the handshake + // code + System.out.println("client connect attempt timed out - checking stack trace"); + StackTraceElement[] trace = e.getStackTrace(); + for (StackTraceElement element : trace) { + if (element.getMethodName().equals("configureClientSSLSocket")) { + System.out.println("client connect attempt timed out in the appropriate method"); + return true; + } + } + // it wasn't in the configuration method so we need to try again + } catch (IOException e) { + // server socket may not be in accept() yet, causing a connection-refused + // exception + } + return false; + }); + } finally { + serverCoordination.release(); + } + } + private File findTestKeystore() throws IOException { return copyKeystoreResourceToFile("/ssl/trusted.keystore"); }
