Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/sun/security/ssl/SSLSocketImpl/SSLSocketCloseHang.java
38853 views
/*1* Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 8184328 825336826* @summary JDK8u131-b34-socketRead0 hang at SSL read27* @run main/othervm SSLSocketCloseHang28* @run main/othervm SSLSocketCloseHang shutdownInputTest29*/3031import java.io.*;32import java.net.*;33import java.util.*;34import java.security.*;35import javax.net.ssl.*;3637public class SSLSocketCloseHang {3839/*40* =============================================================41* Set the various variables needed for the tests, then42* specify what tests to run on each side.43*/4445/*46* Should we run the client or server in a separate thread?47* Both sides can throw exceptions, but do you have a preference48* as to which side should be the main thread.49*/50static boolean separateServerThread = true;5152/*53* Where do we find the keystores?54*/55static String pathToStores = "../../../../javax/net/ssl/etc";56static String keyStoreFile = "keystore";57static String trustStoreFile = "truststore";58static String passwd = "passphrase";5960/*61* Is the server ready to serve?62*/63volatile static boolean serverReady = false;6465/*66* Was the client responsible for closing the socket67*/68volatile static boolean clientClosed = false;6970/*71* Turn on SSL debugging?72*/73static boolean debug = false;7475static boolean shutdownInputTest = false;7677/*78* If the client or server is doing some kind of object creation79* that the other side depends on, and that thread prematurely80* exits, you may experience a hang. The test harness will81* terminate all hung threads after its timeout has expired,82* currently 3 minutes by default, but you might try to be83* smart about it....84*/8586/*87* Define the server side of the test.88*89* If the server prematurely exits, serverReady will be set to true90* to avoid infinite hangs.91*/92void doServerSide() throws Exception {93SSLServerSocketFactory sslssf =94(SSLServerSocketFactory) SSLServerSocketFactory.getDefault();95SSLServerSocket sslServerSocket =96(SSLServerSocket) sslssf.createServerSocket(serverPort);9798serverPort = sslServerSocket.getLocalPort();99100/*101* Signal Client, we're ready for his connect.102*/103serverReady = true;104105System.err.println("Server accepting: " + System.nanoTime());106SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();107System.err.println("Server accepted: " + System.nanoTime());108sslSocket.startHandshake();109System.err.println("Server handshake complete: " + System.nanoTime());110while (!clientClosed) {111Thread.sleep(500);112}113}114115/*116* Define the client side of the test.117*118* If the server prematurely exits, serverReady will be set to true119* to avoid infinite hangs.120*/121void doClientSide() throws Exception {122boolean caught = false;123124/*125* Wait for server to get started.126*/127System.out.println("waiting on server");128while (!serverReady) {129Thread.sleep(50);130}131Thread.sleep(500);132System.out.println("server ready");133134Socket baseSocket = new Socket("localhost", serverPort);135baseSocket.setSoTimeout(1000);136137SSLSocketFactory sslsf =138(SSLSocketFactory) SSLSocketFactory.getDefault();139SSLSocket sslSocket = (SSLSocket)140sslsf.createSocket(baseSocket, "localhost", serverPort, false);141142// handshaking143System.err.println("Client starting handshake: " + System.nanoTime());144sslSocket.startHandshake();145System.err.println("Client handshake done: " + System.nanoTime());146147Thread.sleep(500);148System.err.println("Client closing: " + System.nanoTime());149150if (shutdownInputTest) {151try {152sslSocket.shutdownInput();153} catch (SSLException e) {154if (!e.getMessage().contains155("closing inbound before receiving peer's close_notify")) {156throw new RuntimeException("expected different exception message. " +157e.getMessage());158}159}160if (!sslSocket.getSession().isValid()) {161throw new RuntimeException("expected session to remain valid");162}163164} else {165sslSocket.close();166}167168169170clientClosed = true;171System.err.println("Client closed: " + System.nanoTime());172}173174/*175* =============================================================176* The remainder is just support stuff177*/178179// use any free port by default180volatile int serverPort = 0;181182volatile Exception serverException = null;183volatile Exception clientException = null;184185volatile byte[] serverDigest = null;186187public static void main(String[] args) throws Exception {188String keyFilename =189System.getProperty("test.src", "./") + "/" + pathToStores +190"/" + keyStoreFile;191String trustFilename =192System.getProperty("test.src", "./") + "/" + pathToStores +193"/" + trustStoreFile;194195System.setProperty("javax.net.ssl.keyStore", keyFilename);196System.setProperty("javax.net.ssl.keyStorePassword", passwd);197System.setProperty("javax.net.ssl.trustStore", trustFilename);198System.setProperty("javax.net.ssl.trustStorePassword", passwd);199200if (debug)201System.setProperty("javax.net.debug", "all");202203shutdownInputTest = args.length > 0 ? true : false;204205/*206* Start the tests.207*/208new SSLSocketCloseHang();209}210211Thread clientThread = null;212Thread serverThread = null;213214/*215* Primary constructor, used to drive remainder of the test.216*217* Fork off the other side, then do your work.218*/219SSLSocketCloseHang() throws Exception {220if (separateServerThread) {221startServer(true);222startClient(false);223} else {224startClient(true);225startServer(false);226}227228/*229* Wait for other side to close down.230*/231if (separateServerThread) {232serverThread.join();233} else {234clientThread.join();235}236237/*238* When we get here, the test is pretty much over.239*240* If the main thread excepted, that propagates back241* immediately. If the other thread threw an exception, we242* should report back.243*/244if (serverException != null) {245System.out.print("Server Exception:");246throw serverException;247}248if (clientException != null) {249System.out.print("Client Exception:");250throw clientException;251}252}253254void startServer(boolean newThread) throws Exception {255if (newThread) {256serverThread = new Thread() {257public void run() {258try {259doServerSide();260} catch (Exception e) {261/*262* Our server thread just died.263*264* Release the client, if not active already...265*/266System.err.println("Server died...");267System.err.println(e);268serverReady = true;269serverException = e;270}271}272};273serverThread.start();274} else {275doServerSide();276}277}278279void startClient(boolean newThread) throws Exception {280if (newThread) {281clientThread = new Thread() {282public void run() {283try {284doClientSide();285} catch (Exception e) {286/*287* Our client thread just died.288*/289System.err.println("Client died...");290clientException = e;291}292}293};294clientThread.start();295} else {296doClientSide();297}298}299}300301302