1 /*
   2  * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  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
  21  * questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @bug 4429176
  27  * @summary need to sync up SSL sockets with merlin java.net changes
  28  * @run main/othervm NewSocketMethods
  29  *
  30  *     SunJSSE does not support dynamic system properties, no way to re-use
  31  *     system properties in samevm/agentvm mode.
  32  */
  33 
  34 import java.io.*;
  35 import java.net.*;
  36 import javax.net.*;
  37 import javax.net.ssl.*;
  38 
  39 /**
  40  * There are new methods for java.net.Socket class added to merlin
  41  * This test case checks the behaviour of these new methods when overriden
  42  * by methods of SSLSocket. The following methods are covered in this
  43  * test case.
  44  *
  45  *   public void sendUrgentData (int data) throws IOException
  46  *   public void setOOBInline(boolean on) throws SocketException
  47  *   public boolean getOOBInline() throws SocketException
  48  *   public SocketChannel getChannel() -- call on plain socket
  49  *   public void setTrafficClass(int tc) -- call on plain socket
  50  *                    throws SocketException
  51  *   public int getTrafficClass() -- call on plain socket
  52  *                   throws SocketException
  53  *   public void setReuseAddress(boolean on) -- call on plain socket
  54  *                    throws SocketException
  55  *   public boolean getReuseAddress()  -- call on plain socket
  56  *                       throws SocketException
  57  *   public boolean isInputShutdown()
  58  *   public boolean isOutputShutdown()
  59  *
  60  *   The methods below are covered by the test case located at:
  61  *                                 ../SocketCreation/SocketCreation.java
  62  *   public boolean isConnected()
  63  *   public boolean isBound()
  64  *
  65  */
  66 
  67 public class NewSocketMethods {
  68 
  69     /*
  70      * =============================================================
  71      * Set the various variables needed for the tests, then
  72      * specify what tests to run on each side.
  73      */
  74 
  75     /*
  76      * Should we run the client or server in a separate thread?
  77      * Both sides can throw exceptions, but do you have a preference
  78      * as to which side should be the main thread.
  79      */
  80     static boolean separateServerThread = true;
  81 
  82     /*
  83      * If some one quickly wants to check the plain socket behaviour
  84      * as a reference
  85      */
  86     static boolean useSSL = true;
  87 
  88     /*
  89      * Where do we find the keystores?
  90      */
  91     static String pathToStores = "../../../../javax/net/ssl/etc";
  92     static String keyStoreFile = "keystore";
  93     static String trustStoreFile = "truststore";
  94     static String passwd = "passphrase";
  95 
  96     /*
  97      * Is the server ready to serve?
  98      */
  99     volatile static boolean serverReady = false;
 100 
 101     /*
 102      * Turn on SSL debugging?
 103      */
 104     static boolean debug = false;
 105 
 106     /*
 107      * If the client or server is doing some kind of object creation
 108      * that the other side depends on, and that thread prematurely
 109      * exits, you may experience a hang.  The test harness will
 110      * terminate all hung threads after its timeout has expired,
 111      * currently 3 minutes by default, but you might try to be
 112      * smart about it....
 113      */
 114 
 115     /*
 116      * Define the server side of the test.
 117      *
 118      * If the server prematurely exits, serverReady will be set to true
 119      * to avoid infinite hangs.
 120      */
 121     void doServerSide() throws Exception {
 122         Socket socket;
 123         ServerSocket serverSocket;
 124         if (useSSL) {
 125             SSLServerSocketFactory sslssf =
 126                 (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
 127             serverSocket =
 128                 (SSLServerSocket) sslssf.createServerSocket(serverPort);
 129         } else {
 130            serverSocket = (ServerSocket) ServerSocketFactory.
 131                 getDefault().createServerSocket(serverPort);
 132         }
 133         serverPort = serverSocket.getLocalPort();
 134 
 135         /*
 136          * Signal Client, we're ready for his connect.
 137          */
 138         serverReady = true;
 139         try {
 140             socket = serverSocket.accept();
 141             InputStream is = socket.getInputStream();
 142             OutputStream os = socket.getOutputStream();
 143 
 144             /**
 145              * Test some new methods of java.net.Socket added to merlin
 146              */
 147             System.out.println("Server getChannel(): "
 148                          + socket.getChannel());
 149             try {
 150                 socket.setOOBInline(true);
 151             } catch (IOException success) {
 152                 // Currently we throw an IOException if this method is called
 153               }
 154             try {
 155                 System.out.println("Server getOOBInline(): "
 156                                 + socket.getOOBInline());
 157             } catch (IOException success) {
 158                 // Currently we throw an IOException if this method is called
 159               }
 160             System.out.println("Server read: " + is.read());
 161             os.write(85);
 162             os.flush();
 163             socket.close();
 164          } catch (Exception unexpected) {
 165                throw new Exception(" test failed, caught exception: "
 166                         + unexpected);
 167            }
 168     }
 169 
 170     /*
 171      * Define the client side of the test.
 172      *
 173      * If the server prematurely exits, serverReady will be set to true
 174      * to avoid infinite hangs.
 175      */
 176     void doClientSide() throws Exception {
 177         /*
 178          * Wait for server to get started.
 179          */
 180         while (!serverReady) {
 181             Thread.sleep(50);
 182         }
 183         Socket socket;
 184         if (useSSL) {
 185             SSLSocketFactory sslsf =
 186                 (SSLSocketFactory) SSLSocketFactory.getDefault();
 187             Socket plainSocket = new Socket("localhost", serverPort);
 188             socket = (SSLSocket)
 189                 sslsf.createSocket(plainSocket, "localhost", serverPort, true);
 190         }
 191         else
 192             socket = new Socket("localhost", serverPort);
 193         try {
 194             InputStream is = socket.getInputStream();
 195             OutputStream os = socket.getOutputStream();
 196 
 197             /**
 198              * test some new methods of java.net.Socket added to merlin.
 199              */
 200             System.out.println("Client isInputShutdown() "
 201                         + socket.isInputShutdown());
 202             socket.setReuseAddress(true);
 203             System.out.println("Client getReuseAddress(): "
 204                         + socket.getReuseAddress());
 205 
 206             socket.setTrafficClass(8);
 207             System.out.println("Client getTrafficClass(): "
 208                     + socket.getTrafficClass());
 209 
 210             os.write(237);
 211             os.flush();
 212             System.out.println("Client read: " + is.read());
 213             socket.close();
 214             System.out.println("Client isOutputShutdown() "
 215                         + socket.isOutputShutdown());
 216         } catch (Exception unexpected) {
 217             throw new Exception(" test failed, caught exception: "
 218                         + unexpected);
 219           }
 220     }
 221 
 222     /*
 223      * =============================================================
 224      * The remainder is just support stuff
 225      */
 226 
 227     // use any free port by default
 228     volatile int serverPort = 0;
 229 
 230     volatile Exception serverException = null;
 231     volatile Exception clientException = null;
 232 
 233     public static void main(String[] args) throws Exception {
 234         String keyFilename =
 235             System.getProperty("test.src", "./") + "/" + pathToStores +
 236                 "/" + keyStoreFile;
 237         String trustFilename =
 238             System.getProperty("test.src", "./") + "/" + pathToStores +
 239                 "/" + trustStoreFile;
 240 
 241         System.setProperty("javax.net.ssl.keyStore", keyFilename);
 242         System.setProperty("javax.net.ssl.keyStorePassword", passwd);
 243         System.setProperty("javax.net.ssl.trustStore", trustFilename);
 244         System.setProperty("javax.net.ssl.trustStorePassword", passwd);
 245 
 246         if (debug)
 247             System.setProperty("javax.net.debug", "all");
 248 
 249         /*
 250          * Start the tests.
 251          */
 252         new NewSocketMethods();
 253     }
 254 
 255     Thread clientThread = null;
 256     Thread serverThread = null;
 257 
 258     /*
 259      * Primary constructor, used to drive remainder of the test.
 260      *
 261      * Fork off the other side, then do your work.
 262      */
 263     NewSocketMethods() throws Exception {
 264         if (separateServerThread) {
 265             startServer(true);
 266             startClient(false);
 267         } else {
 268             startClient(true);
 269             startServer(false);
 270         }
 271 
 272         /*
 273          * Wait for other side to close down.
 274          */
 275         if (separateServerThread) {
 276             serverThread.join();
 277         } else {
 278             clientThread.join();
 279         }
 280 
 281         /*
 282          * When we get here, the test is pretty much over.
 283          *
 284          * If the main thread excepted, that propagates back
 285          * immediately.  If the other thread threw an exception, we
 286          * should report back.
 287          */
 288         if (serverException != null)
 289             throw serverException;
 290         if (clientException != null)
 291             throw clientException;
 292     }
 293 
 294     void startServer(boolean newThread) throws Exception {
 295         if (newThread) {
 296             serverThread = new Thread() {
 297                 public void run() {
 298                     try {
 299                         doServerSide();
 300                     } catch (Exception e) {
 301                         /*
 302                          * Our server thread just died.
 303                          *
 304                          * Release the client, if not active already...
 305                          */
 306                         System.err.println("Server died... ");
 307                         e.printStackTrace();
 308                         serverReady = true;
 309                         serverException = e;
 310                     }
 311                 }
 312             };
 313             serverThread.start();
 314         } else {
 315             doServerSide();
 316         }
 317     }
 318 
 319     void startClient(boolean newThread) throws Exception {
 320         if (newThread) {
 321             clientThread = new Thread() {
 322                 public void run() {
 323                     try {
 324                         doClientSide();
 325                     } catch (Exception e) {
 326                         /*
 327                          * Our client thread just died.
 328                          */
 329                         System.err.println("Client died...");
 330                         clientException = e;
 331                     }
 332                 }
 333             };
 334             clientThread.start();
 335         } else {
 336             doClientSide();
 337         }
 338     }
 339 }