jdk/test/javax/net/ssl/templates/SSLSocketTemplate.java
changeset 42155 c9b28ab5297b
parent 41595 f1213215e135
child 42164 8a725a4f3757
equal deleted inserted replaced
42154:cd6c5ce91538 42155:c9b28ab5297b
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    20  * or visit www.oracle.com if you need additional information or have any
    20  * or visit www.oracle.com if you need additional information or have any
    21  * questions.
    21  * questions.
    22  */
    22  */
    23 
    23 
    24 // SunJSSE does not support dynamic system properties, no way to re-use
    24 import java.io.FileInputStream;
    25 // system properties in samevm/agentvm mode.
    25 import java.io.IOException;
       
    26 import java.io.InputStream;
       
    27 import java.io.OutputStream;
       
    28 import java.net.InetSocketAddress;
       
    29 import java.net.SocketTimeoutException;
       
    30 import java.security.KeyStore;
       
    31 import java.security.Security;
       
    32 import java.util.concurrent.CountDownLatch;
       
    33 import java.util.concurrent.TimeUnit;
       
    34 import javax.net.ssl.SSLContext;
       
    35 import javax.net.ssl.SSLServerSocket;
       
    36 import javax.net.ssl.SSLServerSocketFactory;
       
    37 import javax.net.ssl.SSLSocket;
       
    38 import javax.net.ssl.SSLSocketFactory;
       
    39 
       
    40 /**
       
    41  * This class defines a framework for JSSE tests.
       
    42  *
       
    43  * Please run in othervm mode.  SunJSSE does not support dynamic system
       
    44  * properties, no way to re-use system properties in samevm/agentvm mode.
       
    45  */
    26 
    46 
    27 /*
    47 /*
    28  * @test
    48  * @test
    29  * @bug 1234567
    49  * @bug 1234567
    30  * @summary Use this template to help speed your client/server tests.
    50  * @summary Use this class for JSSE tests
    31  * @run main/othervm SSLSocketTemplate
    51  * @run main/othervm SSLSocketTemplate
    32  * @author Brad Wetmore
    52  * @author Brad Wetmore
    33  */
    53  */
    34 
    54 
    35 import java.io.*;
       
    36 import javax.net.ssl.*;
       
    37 
       
    38 public class SSLSocketTemplate {
    55 public class SSLSocketTemplate {
    39 
    56 
    40     /*
    57     public static final String TEST_SRC = System.getProperty("test.src", ".");
    41      * =============================================================
    58 
    42      * Set the various variables needed for the tests, then
    59     /*
    43      * specify what tests to run on each side.
    60      * Where do we find the keystores?
    44      */
    61      */
       
    62     public static final String PATH_TO_STORES = "../etc";
       
    63     public static final String KEY_STORE_FILE = "keystore";
       
    64     public static final String TRUST_STORE_FILE = "truststore";
       
    65     public static final String PASSWORD = "passphrase";
       
    66 
       
    67     public static final int FREE_PORT = 0;
       
    68 
       
    69     // in seconds
       
    70     public static final long CLIENT_SIGNAL_TIMEOUT = 30L;
       
    71     public static final long SERVER_SIGNAL_TIMEOUT = 90L;
       
    72 
       
    73     // in millis
       
    74     public static final int CLIENT_TIMEOUT = 15000;
       
    75     public static final int SERVER_TIMEOUT = 30000;
    45 
    76 
    46     /*
    77     /*
    47      * Should we run the client or server in a separate thread?
    78      * Should we run the client or server in a separate thread?
    48      * Both sides can throw exceptions, but do you have a preference
    79      * Both sides can throw exceptions, but do you have a preference
    49      * as to which side should be the main thread.
    80      * as to which side should be the main thread.
    50      */
    81      */
    51     static boolean separateServerThread = false;
    82     private boolean separateServerThread = false;
    52 
    83 
    53     /*
    84     /*
    54      * Where do we find the keystores?
    85      * What's the server port?  Use any free port by default
    55      */
    86      */
    56     static String pathToStores = "../etc";
    87     private volatile int serverPort;
    57     static String keyStoreFile = "keystore";
    88 
    58     static String trustStoreFile = "truststore";
    89     private volatile Exception serverException;
    59     static String passwd = "passphrase";
    90     private volatile Exception clientException;
       
    91 
       
    92     private Thread clientThread;
       
    93     private Thread serverThread;
       
    94 
       
    95     private Peer serverPeer;
       
    96     private Peer clientPeer;
       
    97 
       
    98     private Application serverApplication;
       
    99     private Application clientApplication;
       
   100 
       
   101     private SSLContext context;
    60 
   102 
    61     /*
   103     /*
    62      * Is the server ready to serve?
   104      * Is the server ready to serve?
    63      */
   105      */
    64     volatile static boolean serverReady = false;
   106     private final CountDownLatch serverReadyCondition = new CountDownLatch(1);
    65 
   107 
    66     /*
   108     /*
    67      * Turn on SSL debugging?
   109      * Is the client ready to handshake?
    68      */
   110      */
    69     static boolean debug = false;
   111     private final CountDownLatch clientReadyCondition = new CountDownLatch(1);
    70 
   112 
    71     /*
   113     /*
    72      * If the client or server is doing some kind of object creation
   114      * Is the server done?
    73      * that the other side depends on, and that thread prematurely
   115      */
    74      * exits, you may experience a hang.  The test harness will
   116     private final CountDownLatch serverDoneCondition = new CountDownLatch(1);
    75      * terminate all hung threads after its timeout has expired,
   117 
    76      * currently 3 minutes by default, but you might try to be
   118     /*
    77      * smart about it....
   119      * Is the client done?
       
   120      */
       
   121     private final CountDownLatch clientDoneCondition = new CountDownLatch(1);
       
   122 
       
   123     /*
       
   124      * Public API.
       
   125      */
       
   126 
       
   127     public static interface Peer {
       
   128         void run(SSLSocketTemplate test) throws Exception;
       
   129     }
       
   130 
       
   131     public static interface Application {
       
   132         void run(SSLSocket socket, SSLSocketTemplate test) throws Exception;
       
   133     }
       
   134 
       
   135     public static void debug() {
       
   136         debug("ssl");
       
   137     }
       
   138 
       
   139     public static void debug(String mode) {
       
   140         System.setProperty("javax.net.debug", mode);
       
   141     }
       
   142 
       
   143     public static void setup(String keyFilename, String trustFilename,
       
   144             String password) {
       
   145 
       
   146         System.setProperty("javax.net.ssl.keyStore", keyFilename);
       
   147         System.setProperty("javax.net.ssl.keyStorePassword", password);
       
   148         System.setProperty("javax.net.ssl.trustStore", trustFilename);
       
   149         System.setProperty("javax.net.ssl.trustStorePassword", password);
       
   150     }
       
   151 
       
   152     public static void setup() throws Exception {
       
   153         String keyFilename = TEST_SRC + "/" + PATH_TO_STORES + "/"
       
   154                 + KEY_STORE_FILE;
       
   155         String trustFilename = TEST_SRC + "/" + PATH_TO_STORES + "/"
       
   156                 + TRUST_STORE_FILE;
       
   157 
       
   158         setup(keyFilename, trustFilename, PASSWORD);
       
   159     }
       
   160 
       
   161     public static void print(String message, Throwable... errors) {
       
   162         synchronized (System.out) {
       
   163             System.out.println(message);
       
   164             for (Throwable e : errors) {
       
   165                 e.printStackTrace(System.out);
       
   166             }
       
   167         }
       
   168     }
       
   169 
       
   170     public static KeyStore loadJksKeyStore(String filename, String password)
       
   171             throws Exception {
       
   172 
       
   173         return loadKeyStore(filename, password, "JKS");
       
   174     }
       
   175 
       
   176     public static KeyStore loadKeyStore(String filename, String password,
       
   177             String type) throws Exception {
       
   178 
       
   179         KeyStore keystore = KeyStore.getInstance(type);
       
   180         FileInputStream fis = new FileInputStream(filename);
       
   181         try {
       
   182             keystore.load(fis, password.toCharArray());
       
   183         } finally {
       
   184             fis.close();
       
   185         }
       
   186         return keystore;
       
   187     }
       
   188 
       
   189     // Try to accept a connection in 30 seconds.
       
   190     public static SSLSocket accept(SSLServerSocket sslServerSocket)
       
   191             throws IOException {
       
   192 
       
   193         return accept(sslServerSocket, SERVER_TIMEOUT);
       
   194     }
       
   195 
       
   196     public static SSLSocket accept(SSLServerSocket sslServerSocket, int timeout)
       
   197             throws IOException {
       
   198 
       
   199         try {
       
   200             sslServerSocket.setSoTimeout(timeout);
       
   201             return (SSLSocket) sslServerSocket.accept();
       
   202         } catch (SocketTimeoutException ste) {
       
   203             print("Warning: ", ste);
       
   204             return null;
       
   205         }
       
   206     }
       
   207 
       
   208     public SSLSocketTemplate setSeparateServerThread(
       
   209             boolean separateServerThread) {
       
   210 
       
   211         this.separateServerThread = separateServerThread;
       
   212         return this;
       
   213     }
       
   214 
       
   215     public SSLSocketTemplate setServerPort(int serverPort) {
       
   216         this.serverPort = serverPort;
       
   217         return this;
       
   218     }
       
   219 
       
   220     public int getServerPort() {
       
   221         return serverPort;
       
   222     }
       
   223 
       
   224     public SSLSocketTemplate setSSLContext(SSLContext context) {
       
   225         this.context = context;
       
   226         return this;
       
   227     }
       
   228 
       
   229     public SSLContext getSSLContext() {
       
   230         return context;
       
   231     }
       
   232 
       
   233     public SSLServerSocketFactory getSSLServerSocketFactory() {
       
   234         if (context != null) {
       
   235             return context.getServerSocketFactory();
       
   236         }
       
   237 
       
   238         return (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
       
   239     }
       
   240 
       
   241     public SSLSocketFactory getSSLSocketFactory() {
       
   242         if (context != null) {
       
   243             return context.getSocketFactory();
       
   244         }
       
   245 
       
   246         return (SSLSocketFactory) SSLSocketFactory.getDefault();
       
   247     }
       
   248 
       
   249     public void signalServerReady() {
       
   250         serverReadyCondition.countDown();
       
   251     }
       
   252 
       
   253     public void signalServerDone() {
       
   254         serverDoneCondition.countDown();
       
   255     }
       
   256 
       
   257     public boolean waitForClientSignal(long timeout, TimeUnit unit)
       
   258             throws InterruptedException {
       
   259 
       
   260         return clientReadyCondition.await(timeout, unit);
       
   261     }
       
   262 
       
   263     public boolean waitForClientSignal() throws InterruptedException {
       
   264         return waitForClientSignal(CLIENT_SIGNAL_TIMEOUT, TimeUnit.SECONDS);
       
   265     }
       
   266 
       
   267     public boolean waitForClientDone(long timeout, TimeUnit unit)
       
   268             throws InterruptedException {
       
   269 
       
   270         return clientDoneCondition.await(timeout, unit);
       
   271     }
       
   272 
       
   273     public boolean waitForClientDone() throws InterruptedException {
       
   274         return waitForClientDone(CLIENT_SIGNAL_TIMEOUT, TimeUnit.SECONDS);
       
   275     }
       
   276 
       
   277     public void signalClientReady() {
       
   278         clientReadyCondition.countDown();
       
   279     }
       
   280 
       
   281     public void signalClientDone() {
       
   282         clientDoneCondition.countDown();
       
   283     }
       
   284 
       
   285     public boolean waitForServerSignal(long timeout, TimeUnit unit)
       
   286             throws InterruptedException {
       
   287 
       
   288         return serverReadyCondition.await(timeout, unit);
       
   289     }
       
   290 
       
   291     public boolean waitForServerSignal() throws InterruptedException {
       
   292         return waitForServerSignal(SERVER_SIGNAL_TIMEOUT, TimeUnit.SECONDS);
       
   293     }
       
   294 
       
   295     public boolean waitForServerDone(long timeout, TimeUnit unit)
       
   296             throws InterruptedException {
       
   297 
       
   298         return serverDoneCondition.await(timeout, unit);
       
   299     }
       
   300 
       
   301     public boolean waitForServerDone() throws InterruptedException {
       
   302         return waitForServerDone(SERVER_SIGNAL_TIMEOUT, TimeUnit.SECONDS);
       
   303     }
       
   304 
       
   305     public SSLSocketTemplate setServerPeer(Peer serverPeer) {
       
   306         this.serverPeer = serverPeer;
       
   307         return this;
       
   308     }
       
   309 
       
   310     public Peer getServerPeer() {
       
   311         return serverPeer;
       
   312     }
       
   313 
       
   314     public SSLSocketTemplate setServerApplication(
       
   315             Application serverApplication) {
       
   316 
       
   317         this.serverApplication = serverApplication;
       
   318         return this;
       
   319     }
       
   320 
       
   321     public Application getServerApplication() {
       
   322         return serverApplication;
       
   323     }
       
   324 
       
   325     public SSLSocketTemplate setClientPeer(Peer clientPeer) {
       
   326         this.clientPeer = clientPeer;
       
   327         return this;
       
   328     }
       
   329 
       
   330     public Peer getClientPeer() {
       
   331         return clientPeer;
       
   332     }
       
   333 
       
   334     public SSLSocketTemplate setClientApplication(
       
   335             Application clientApplication) {
       
   336 
       
   337         this.clientApplication = clientApplication;
       
   338         return this;
       
   339     }
       
   340 
       
   341     public Application getClientApplication() {
       
   342         return clientApplication;
       
   343     }
       
   344 
       
   345     public void runTest() throws Exception {
       
   346         if (separateServerThread) {
       
   347             startServer(true, this);
       
   348             startClient(false, this);
       
   349             serverThread.join();
       
   350         } else {
       
   351             startClient(true, this);
       
   352             startServer(false, this);
       
   353             clientThread.join();
       
   354         }
       
   355 
       
   356         if (clientException != null || serverException != null) {
       
   357             throw new RuntimeException("Test failed");
       
   358         }
       
   359     }
       
   360 
       
   361     public SSLSocketTemplate() {
       
   362         serverPeer = new Peer() {
       
   363 
       
   364             @Override
       
   365             public void run(SSLSocketTemplate test) throws Exception {
       
   366                 doServerSide(test);
       
   367             }
       
   368         };
       
   369 
       
   370         clientPeer = new Peer() {
       
   371 
       
   372             @Override
       
   373             public void run(SSLSocketTemplate test) throws Exception {
       
   374                 doClientSide(test);
       
   375             }
       
   376         };
       
   377 
       
   378         serverApplication = new Application() {
       
   379 
       
   380             @Override
       
   381             public void run(SSLSocket socket, SSLSocketTemplate test)
       
   382                     throws Exception {
       
   383 
       
   384                 runServerApplication(socket);
       
   385             }
       
   386 
       
   387         };
       
   388 
       
   389         clientApplication = new Application() {
       
   390 
       
   391             @Override
       
   392             public void run(SSLSocket socket, SSLSocketTemplate test)
       
   393                     throws Exception {
       
   394 
       
   395                 runClientApplication(socket);
       
   396             }
       
   397         };
       
   398     }
       
   399 
       
   400     public static void main(String args[]) throws Exception {
       
   401         // reset the security property to make sure that the algorithms
       
   402         // and keys used in this test are not disabled.
       
   403         Security.setProperty("jdk.tls.disabledAlgorithms", "");
       
   404 
       
   405         // MD5 is used in this test case, don't disable MD5 algorithm.
       
   406         Security.setProperty(
       
   407                 "jdk.certpath.disabledAlgorithms", "MD2, RSA keySize < 1024");
       
   408 
       
   409         setup();
       
   410 
       
   411         new SSLSocketTemplate().runTest();
       
   412     }
       
   413 
       
   414     /*
       
   415      * Private part.
    78      */
   416      */
    79 
   417 
    80     /*
   418     /*
    81      * Define the server side of the test.
   419      * Define the server side of the test.
    82      *
   420      */
    83      * If the server prematurely exits, serverReady will be set to true
   421     private static void doServerSide(SSLSocketTemplate test) throws Exception {
    84      * to avoid infinite hangs.
   422         SSLServerSocket sslServerSocket;
    85      */
   423 
    86     void doServerSide() throws Exception {
   424         // kick start the server side service
    87         SSLServerSocketFactory sslssf =
   425         SSLServerSocketFactory sslssf = test.getSSLServerSocketFactory();
    88             (SSLServerSocketFactory)SSLServerSocketFactory.getDefault();
   426         sslServerSocket = (SSLServerSocket)sslssf.createServerSocket(FREE_PORT);
    89         try (SSLServerSocket sslServerSocket =
   427 
    90                 (SSLServerSocket)sslssf.createServerSocket(serverPort)) {
   428         test.setServerPort(sslServerSocket.getLocalPort());
    91 
   429         print("Server is listening on port " + test.getServerPort());
    92             serverPort = sslServerSocket.getLocalPort();
   430 
    93 
   431         // Signal the client, the server is ready to accept connection.
    94             /*
   432         test.signalServerReady();
    95              * Signal Client, we're ready for his connect.
   433 
    96              */
   434         // Try to accept a connection in 30 seconds.
    97             serverReady = true;
   435         SSLSocket sslSocket = accept(sslServerSocket);
    98 
   436         if (sslSocket == null) {
    99             try (SSLSocket sslSocket = (SSLSocket)sslServerSocket.accept()) {
   437             // Ignore the test case if no connection within 30 seconds.
   100                 InputStream sslIS = sslSocket.getInputStream();
   438             print("No incoming client connection in 30 seconds. "
   101                 OutputStream sslOS = sslSocket.getOutputStream();
   439                     + "Ignore in server side.");
   102 
   440             return;
   103                 sslIS.read();
   441         }
   104                 sslOS.write(85);
   442         print("Server accepted connection");
   105                 sslOS.flush();
   443 
   106             }
   444         // handle the connection
   107         }
   445         try {
       
   446             // Is it the expected client connection?
       
   447             //
       
   448             // Naughty test cases or third party routines may try to
       
   449             // connection to this server port unintentionally.  In
       
   450             // order to mitigate the impact of unexpected client
       
   451             // connections and avoid intermittent failure, it should
       
   452             // be checked that the accepted connection is really linked
       
   453             // to the expected client.
       
   454             boolean clientIsReady = test.waitForClientSignal();
       
   455 
       
   456             if (clientIsReady) {
       
   457                 // Run the application in server side.
       
   458                 print("Run server application");
       
   459                 test.getServerApplication().run(sslSocket, test);
       
   460             } else {    // Otherwise, ignore
       
   461                 // We don't actually care about plain socket connections
       
   462                 // for TLS communication testing generally.  Just ignore
       
   463                 // the test if the accepted connection is not linked to
       
   464                 // the expected client or the client connection timeout
       
   465                 // in 30 seconds.
       
   466                 print("The client is not the expected one or timeout. "
       
   467                         + "Ignore in server side.");
       
   468             }
       
   469         } finally {
       
   470             sslSocket.close();
       
   471             sslServerSocket.close();
       
   472         }
       
   473 
       
   474         test.signalServerDone();
       
   475     }
       
   476 
       
   477     /*
       
   478      * Define the server side application of the test for the specified socket.
       
   479      */
       
   480     private static void runServerApplication(SSLSocket socket)
       
   481             throws Exception {
       
   482 
       
   483         // here comes the test logic
       
   484         InputStream sslIS = socket.getInputStream();
       
   485         OutputStream sslOS = socket.getOutputStream();
       
   486 
       
   487         sslIS.read();
       
   488         sslOS.write(85);
       
   489         sslOS.flush();
   108     }
   490     }
   109 
   491 
   110     /*
   492     /*
   111      * Define the client side of the test.
   493      * Define the client side of the test.
   112      *
   494      */
   113      * If the server prematurely exits, serverReady will be set to true
   495     private static void doClientSide(SSLSocketTemplate test) throws Exception {
   114      * to avoid infinite hangs.
   496 
   115      */
   497         // Wait for server to get started.
   116     void doClientSide() throws Exception {
   498         //
   117 
   499         // The server side takes care of the issue if the server cannot
   118         /*
   500         // get started in 90 seconds.  The client side would just ignore
   119          * Wait for server to get started.
   501         // the test case if the serer is not ready.
   120          */
   502         boolean serverIsReady = test.waitForServerSignal();
   121         while (!serverReady) {
   503         if (!serverIsReady) {
   122             Thread.sleep(50);
   504             print("The server is not ready yet in 90 seconds. "
   123         }
   505                     + "Ignore in client side.");
   124 
   506             return;
   125         SSLSocketFactory sslsf =
   507         }
   126             (SSLSocketFactory)SSLSocketFactory.getDefault();
   508 
   127         try (SSLSocket sslSocket =
   509         SSLSocketFactory sslsf = test.getSSLSocketFactory();
   128                 (SSLSocket)sslsf.createSocket("localhost", serverPort)) {
   510         SSLSocket sslSocket = (SSLSocket)sslsf.createSocket();
   129 
       
   130             InputStream sslIS = sslSocket.getInputStream();
       
   131             OutputStream sslOS = sslSocket.getOutputStream();
       
   132 
       
   133             sslOS.write(280);
       
   134             sslOS.flush();
       
   135             sslIS.read();
       
   136         }
       
   137     }
       
   138 
       
   139     /*
       
   140      * =============================================================
       
   141      * The remainder is just support stuff
       
   142      */
       
   143 
       
   144     // use any free port by default
       
   145     volatile int serverPort = 0;
       
   146 
       
   147     volatile Exception serverException = null;
       
   148     volatile Exception clientException = null;
       
   149 
       
   150     public static void main(String[] args) throws Exception {
       
   151         String keyFilename =
       
   152             System.getProperty("test.src", ".") + "/" + pathToStores +
       
   153                 "/" + keyStoreFile;
       
   154         String trustFilename =
       
   155             System.getProperty("test.src", ".") + "/" + pathToStores +
       
   156                 "/" + trustStoreFile;
       
   157 
       
   158         System.setProperty("javax.net.ssl.keyStore", keyFilename);
       
   159         System.setProperty("javax.net.ssl.keyStorePassword", passwd);
       
   160         System.setProperty("javax.net.ssl.trustStore", trustFilename);
       
   161         System.setProperty("javax.net.ssl.trustStorePassword", passwd);
       
   162 
       
   163         if (debug) {
       
   164             System.setProperty("javax.net.debug", "all");
       
   165         }
       
   166 
       
   167         /*
       
   168          * Start the tests.
       
   169          */
       
   170         new SSLSocketTemplate();
       
   171     }
       
   172 
       
   173     Thread clientThread = null;
       
   174     Thread serverThread = null;
       
   175 
       
   176     /*
       
   177      * Primary constructor, used to drive remainder of the test.
       
   178      *
       
   179      * Fork off the other side, then do your work.
       
   180      */
       
   181     SSLSocketTemplate() throws Exception {
       
   182         Exception startException = null;
       
   183         try {
   511         try {
   184             if (separateServerThread) {
   512             try {
   185                 startServer(true);
   513                 sslSocket.connect(
   186                 startClient(false);
   514                         new InetSocketAddress("localhost",
   187             } else {
   515                                 test.getServerPort()), CLIENT_TIMEOUT);
   188                 startClient(true);
   516                 print("Client connected to server");
   189                 startServer(false);
   517             } catch (IOException ioe) {
   190             }
   518                 // The server side may be impacted by naughty test cases or
   191         } catch (Exception e) {
   519                 // third party routines, and cannot accept connections.
   192             startException = e;
   520                 //
   193         }
   521                 // Just ignore the test if the connection cannot be
   194 
   522                 // established.
   195         /*
   523                 print("Cannot make a connection in 15 seconds. "
   196          * Wait for other side to close down.
   524                         + "Ignore in client side.", ioe);
   197          */
   525                 return;
   198         if (separateServerThread) {
   526             }
   199             if (serverThread != null) {
   527 
   200                 serverThread.join();
   528             // OK, here the client and server get connected.
   201             }
   529 
   202         } else {
   530             // Signal the server, the client is ready to communicate.
   203             if (clientThread != null) {
   531             test.signalClientReady();
   204                 clientThread.join();
   532 
   205             }
   533             // There is still a chance in theory that the server thread may
   206         }
   534             // wait client-ready timeout and then quit.  The chance should
   207 
   535             // be really rare so we don't consider it until it becomes a
   208         /*
   536             // real problem.
   209          * When we get here, the test is pretty much over.
   537 
   210          * Which side threw the error?
   538             // Run the application in client side.
   211          */
   539             print("Run client application");
   212         Exception local;
   540             test.getClientApplication().run(sslSocket, test);
   213         Exception remote;
   541         } finally {
   214 
   542             sslSocket.close();
   215         if (separateServerThread) {
   543         }
   216             remote = serverException;
   544 
   217             local = clientException;
   545         test.signalClientDone();
   218         } else {
   546     }
   219             remote = clientException;
   547 
   220             local = serverException;
   548     /*
   221         }
   549      * Define the client side application of the test for the specified socket.
   222 
   550      */
   223         Exception exception = null;
   551     private static void runClientApplication(SSLSocket socket)
   224 
   552             throws Exception {
   225         /*
   553 
   226          * Check various exception conditions.
   554         InputStream sslIS = socket.getInputStream();
   227          */
   555         OutputStream sslOS = socket.getOutputStream();
   228         if ((local != null) && (remote != null)) {
   556 
   229             // If both failed, return the curthread's exception.
   557         sslOS.write(280);
   230             local.initCause(remote);
   558         sslOS.flush();
   231             exception = local;
   559         sslIS.read();
   232         } else if (local != null) {
   560     }
   233             exception = local;
   561 
   234         } else if (remote != null) {
   562     private void startServer(boolean newThread, SSLSocketTemplate test)
   235             exception = remote;
   563             throws Exception {
   236         } else if (startException != null) {
   564 
   237             exception = startException;
       
   238         }
       
   239 
       
   240         /*
       
   241          * If there was an exception *AND* a startException,
       
   242          * output it.
       
   243          */
       
   244         if (exception != null) {
       
   245             if (exception != startException && startException != null) {
       
   246                 exception.addSuppressed(startException);
       
   247             }
       
   248             throw exception;
       
   249         }
       
   250 
       
   251         // Fall-through: no exception to throw!
       
   252     }
       
   253 
       
   254     void startServer(boolean newThread) throws Exception {
       
   255         if (newThread) {
   565         if (newThread) {
   256             serverThread = new Thread() {
   566             serverThread = new Thread() {
       
   567 
   257                 @Override
   568                 @Override
   258                 public void run() {
   569                 public void run() {
   259                     try {
   570                     try {
   260                         doServerSide();
   571                         serverPeer.run(test);
   261                     } catch (Exception e) {
   572                     } catch (Exception e) {
   262                         /*
   573                         /*
   263                          * Our server thread just died.
   574                          * Our server thread just died.
   264                          *
   575                          *
   265                          * Release the client, if not active already...
   576                          * Release the client, if not active already...
   266                          */
   577                          */
   267                         System.err.println("Server died...");
   578                         print("Server died ...", e);
   268                         serverReady = true;
       
   269                         serverException = e;
   579                         serverException = e;
   270                     }
   580                     }
   271                 }
   581                 }
   272             };
   582             };
   273             serverThread.start();
   583             serverThread.start();
   274         } else {
   584         } else {
   275             try {
   585             try {
   276                 doServerSide();
   586                 serverPeer.run(test);
   277             } catch (Exception e) {
   587             } catch (Exception e) {
       
   588                 print("Server failed ...", e);
   278                 serverException = e;
   589                 serverException = e;
   279             } finally {
   590             }
   280                 serverReady = true;
   591         }
   281             }
   592     }
   282         }
   593 
   283     }
   594     private void startClient(boolean newThread, SSLSocketTemplate test)
   284 
   595             throws Exception {
   285     void startClient(boolean newThread) throws Exception {
   596 
   286         if (newThread) {
   597         if (newThread) {
   287             clientThread = new Thread() {
   598             clientThread = new Thread() {
       
   599 
   288                 @Override
   600                 @Override
   289                 public void run() {
   601                 public void run() {
   290                     try {
   602                     try {
   291                         doClientSide();
   603                         clientPeer.run(test);
   292                     } catch (Exception e) {
   604                     } catch (Exception e) {
   293                         /*
   605                         /*
   294                          * Our client thread just died.
   606                          * Our client thread just died.
   295                          */
   607                          */
   296                         System.err.println("Client died...");
   608                         print("Client died ...", e);
   297                         clientException = e;
   609                         clientException = e;
   298                     }
   610                     }
   299                 }
   611                 }
   300             };
   612             };
   301             clientThread.start();
   613             clientThread.start();
   302         } else {
   614         } else {
   303             try {
   615             try {
   304                 doClientSide();
   616                 clientPeer.run(test);
   305             } catch (Exception e) {
   617             } catch (Exception e) {
       
   618                 print("Client failed ...", e);
   306                 clientException = e;
   619                 clientException = e;
   307             }
   620             }
   308         }
   621         }
   309     }
   622     }
   310 }
   623 }