1 /*
   2  * Copyright (c) 2001, 2019, 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             // Solaris does not support set/get of IPV6_TCLASS when connected
 207             if (!"SunOS".equals(System.getProperty("os.name"))) {
 208                 socket.setTrafficClass(8);
 209                 System.out.println("Client getTrafficClass(): "
 210                         + socket.getTrafficClass());
 211             }
 212 
 213             os.write(237);
 214             os.flush();
 215             System.out.println("Client read: " + is.read());
 216             socket.close();
 217             System.out.println("Client isOutputShutdown() "
 218                         + socket.isOutputShutdown());
 219         } catch (Exception unexpected) {
 220             throw new Exception(" test failed, caught exception: "
 221                         + unexpected);
 222           }
 223     }
 224 
 225     /*
 226      * =============================================================
 227      * The remainder is just support stuff
 228      */
 229 
 230     // use any free port by default
 231     volatile int serverPort = 0;
 232 
 233     volatile Exception serverException = null;
 234     volatile Exception clientException = null;
 235 
 236     public static void main(String[] args) throws Exception {
 237         String keyFilename =
 238             System.getProperty("test.src", "./") + "/" + pathToStores +
 239                 "/" + keyStoreFile;
 240         String trustFilename =
 241             System.getProperty("test.src", "./") + "/" + pathToStores +
 242                 "/" + trustStoreFile;
 243 
 244         System.setProperty("javax.net.ssl.keyStore", keyFilename);
 245         System.setProperty("javax.net.ssl.keyStorePassword", passwd);
 246         System.setProperty("javax.net.ssl.trustStore", trustFilename);
 247         System.setProperty("javax.net.ssl.trustStorePassword", passwd);
 248 
 249         if (debug)
 250             System.setProperty("javax.net.debug", "all");
 251 
 252         /*
 253          * Start the tests.
 254          */
 255         new NewSocketMethods();
 256     }
 257 
 258     Thread clientThread = null;
 259     Thread serverThread = null;
 260 
 261     /*
 262      * Primary constructor, used to drive remainder of the test.
 263      *
 264      * Fork off the other side, then do your work.
 265      */
 266     NewSocketMethods() throws Exception {
 267         if (separateServerThread) {
 268             startServer(true);
 269             startClient(false);
 270         } else {
 271             startClient(true);
 272             startServer(false);
 273         }
 274 
 275         /*
 276          * Wait for other side to close down.
 277          */
 278         if (separateServerThread) {
 279             serverThread.join();
 280         } else {
 281             clientThread.join();
 282         }
 283 
 284         /*
 285          * When we get here, the test is pretty much over.
 286          *
 287          * If the main thread excepted, that propagates back
 288          * immediately.  If the other thread threw an exception, we
 289          * should report back.
 290          */
 291         if (serverException != null)
 292             throw serverException;
 293         if (clientException != null)
 294             throw clientException;
 295     }
 296 
 297     void startServer(boolean newThread) throws Exception {
 298         if (newThread) {
 299             serverThread = new Thread() {
 300                 public void run() {
 301                     try {
 302                         doServerSide();
 303                     } catch (Exception e) {
 304                         /*
 305                          * Our server thread just died.
 306                          *
 307                          * Release the client, if not active already...
 308                          */
 309                         System.err.println("Server died... ");
 310                         e.printStackTrace();
 311                         serverReady = true;
 312                         serverException = e;
 313                     }
 314                 }
 315             };
 316             serverThread.start();
 317         } else {
 318             doServerSide();
 319         }
 320     }
 321 
 322     void startClient(boolean newThread) throws Exception {
 323         if (newThread) {
 324             clientThread = new Thread() {
 325                 public void run() {
 326                     try {
 327                         doClientSide();
 328                     } catch (Exception e) {
 329                         /*
 330                          * Our client thread just died.
 331                          */
 332                         System.err.println("Client died...");
 333                         clientException = e;
 334                     }
 335                 }
 336             };
 337             clientThread.start();
 338         } else {
 339             doClientSide();
 340         }
 341     }
 342 }