Path: blob/master/test/jdk/javax/net/ssl/finalize/SSLSessionFinalizeTest.java
41152 views
/*1* Copyright (c) 2001, 2016, 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* @summary Test behavior related to finalize26* @run main/othervm SSLSessionFinalizeTest27* @run main/othervm/policy=security.policy SSLSessionFinalizeTest28*/2930import java.io.InputStream;31import java.io.OutputStream;32import java.lang.ref.Reference;33import java.lang.ref.WeakReference;34import java.util.concurrent.ArrayBlockingQueue;3536import javax.net.ssl.SSLServerSocket;37import javax.net.ssl.SSLServerSocketFactory;38import javax.net.ssl.SSLSession;39import javax.net.ssl.SSLSessionBindingEvent;40import javax.net.ssl.SSLSessionBindingListener;41import javax.net.ssl.SSLSocket;42import javax.net.ssl.SSLSocketFactory;4344public class SSLSessionFinalizeTest {4546/*47* =============================================================48* Set the various variables needed for the tests, then49* specify what tests to run on each side.50*/5152/*53* Should we run the client or server in a separate thread?54* Both sides can throw exceptions, but do you have a preference55* as to which side should be the main thread.56*/57static boolean separateServerThread = true;5859/*60* Where do we find the keystores?61*/62static String pathToStores = "../etc";63static String keyStoreFile = "keystore";64static String trustStoreFile = "truststore";65static String passwd = "passphrase";6667/*68* Is the server ready to serve?69*/70volatile static boolean serverReady = false;7172/*73* Turn on SSL debugging?74*/75static boolean debug = 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);97serverPort = sslServerSocket.getLocalPort();9899/*100* Signal Client, we're ready for his connect.101*/102serverReady = true;103104while (serverReady) {105SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();106// System.out.printf(" accept: %s%n", sslSocket);107InputStream sslIS = sslSocket.getInputStream();108OutputStream sslOS = sslSocket.getOutputStream();109110sslIS.read();111sslOS.write(85);112sslOS.flush();113114sslSocket.close();115}116}117118/*119* Define the client side of the test.120*121* If the server prematurely exits, serverReady will be set to true122* to avoid infinite hangs.123*/124SBListener doClientSide() throws Exception {125126/*127* Wait for server to get started.128*/129while (!serverReady) {130Thread.sleep(50);131}132133SSLSocketFactory sslsf =134(SSLSocketFactory) SSLSocketFactory.getDefault();135136try {137SSLSocket sslSocket = (SSLSocket)138sslsf.createSocket("localhost", serverPort);139InputStream sslIS = sslSocket.getInputStream();140OutputStream sslOS = sslSocket.getOutputStream();141142sslOS.write(280);143sslOS.flush();144sslIS.read();145146sslOS.close();147sslIS.close();148149SSLSession sslSession = sslSocket.getSession();150System.out.printf(" sslSession: %s %n %s%n", sslSession, sslSession.getClass());151SBListener sbListener = new SBListener(sslSession);152153sslSession.putValue("x", sbListener);154155sslSession.invalidate();156157sslSocket.close();158159sslOS = null;160sslIS = null;161sslSession = null;162sslSocket = null;163Reference.reachabilityFence(sslOS);164Reference.reachabilityFence(sslIS);165Reference.reachabilityFence(sslSession);166Reference.reachabilityFence(sslSocket);167168return sbListener;169} catch (Exception ex) {170ex.printStackTrace();171throw ex;172}173}174175/*176* =============================================================177* The remainder is just support stuff178*/179180// use any free port by default181volatile int serverPort = 0;182183volatile Exception serverException = null;184volatile Exception clientException = null;185186public static void main(String[] args) throws Exception {187String keyFilename =188System.getProperty("test.src", "./") + "/" + pathToStores +189"/" + keyStoreFile;190String trustFilename =191System.getProperty("test.src", "./") + "/" + pathToStores +192"/" + trustStoreFile;193194System.setProperty("javax.net.ssl.keyStore", keyFilename);195System.setProperty("javax.net.ssl.keyStorePassword", passwd);196System.setProperty("javax.net.ssl.trustStore", trustFilename);197System.setProperty("javax.net.ssl.trustStorePassword", passwd);198199if (debug)200System.setProperty("javax.net.debug", "all");201202/*203* Start the tests.204*/205new SSLSessionFinalizeTest();206}207208ArrayBlockingQueue<Thread> threads = new ArrayBlockingQueue<Thread>(100);209210ArrayBlockingQueue<SBListener> sbListeners = new ArrayBlockingQueue<>(100);211212/*213* Primary constructor, used to drive remainder of the test.214*215* Fork off the other side, then do your work.216*/217SSLSessionFinalizeTest() throws Exception {218final int count = 1;219if (separateServerThread) {220startServer(true);221startClients(true, count);222} else {223startClients(true, count);224startServer(true);225}226227/*228* Wait for other side to close down.229*/230Thread t;231while ((t = threads.take()) != Thread.currentThread()) {232System.out.printf(" joining: %s%n", t);233t.join(1000L);234}235serverReady = false;236System.gc();237System.gc();238239240SBListener listener = null;241while ((listener = sbListeners.poll()) != null) {242if (!listener.check()) {243System.out.printf(" sbListener not called on finalize: %s%n",244listener);245}246}247248/*249* When we get here, the test is pretty much over.250*251* If the main thread excepted, that propagates back252* immediately. If the other thread threw an exception, we253* should report back.254*/255if (serverException != null) {256System.out.print("Server Exception:");257throw serverException;258}259if (clientException != null) {260System.out.print("Client Exception:");261throw clientException;262}263}264265void startServer(boolean newThread) throws Exception {266if (newThread) {267Thread t = new Thread("Server") {268public void run() {269try {270doServerSide();271} catch (Exception e) {272/*273* Our server thread just died.274*275* Release the client, if not active already...276*/277System.err.println("Server died..." + e);278serverReady = true;279serverException = e;280}281}282};283threads.add(t);284t.setDaemon(true);285t.start();286} else {287doServerSide();288}289}290291void startClients(boolean newThread, int count) throws Exception {292for (int i = 0; i < count; i++) {293System.out.printf(" newClient: %d%n", i);294startClient(newThread);295}296serverReady = false;297298threads.add(Thread.currentThread()); // add ourselves at the 'end'299}300void startClient(boolean newThread) throws Exception {301if (newThread) {302Thread t = new Thread("Client") {303public void run() {304try {305sbListeners.add(doClientSide());306} catch (Exception e) {307/*308* Our client thread just died.309*/310System.err.println("Client died..." + e);311clientException = e;312}313}314};315System.out.printf(" starting: %s%n", t);316threads.add(t);317t.start();318} else {319sbListeners.add(doClientSide());320}321}322323324static class SBListener implements SSLSessionBindingListener {325private volatile int unboundNotified;326private final WeakReference<SSLSession> session;327328SBListener(SSLSession session) {329this.unboundNotified = 0;330this.session = new WeakReference<SSLSession>(session);331}332333boolean check() {334System.out.printf(" check: %s%n", this);335return unboundNotified > 0 && session.get() == null;336}337338@Override339public void valueBound(SSLSessionBindingEvent event) {340System.out.printf(" valueBound: %s%n", event.getName());341}342343@Override344public void valueUnbound(SSLSessionBindingEvent event) {345System.out.printf(" valueUnbound: %s%n", event.getName());346unboundNotified++;347}348349public String toString() {350return "count: " + unboundNotified +351", ref: " + session.get();352}353}354}355356357