1/* 2 * Copyright (c) 2001, 2011, 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 4482446 27 * @summary java.net.SocketTimeoutException on 98, NT, 2000 for JSSE 28 * @run main/othervm ReuseAddr 29 * 30 * SunJSSE does not support dynamic system properties, no way to re-use 31 * system properties in samevm/agentvm mode. 32 * @author Brad Wetmore 33 */ 34 35import java.io.*; 36import java.net.*; 37import javax.net.ssl.*; 38 39public class ReuseAddr { 40 41 /* 42 * ============================================================= 43 * Set the various variables needed for the tests, then 44 * specify what tests to run on each side. 45 */ 46 47 /* 48 * Should we run the client or server in a separate thread? 49 * Both sides can throw exceptions, but do you have a preference 50 * as to which side should be the main thread. 51 */ 52 static boolean separateServerThread = true; 53 54 /* 55 * Where do we find the keystores? 56 */ 57 private final static String pathToStores = "../../../../javax/net/ssl/etc"; 58 static String keyStoreFile = "keystore"; 59 static String trustStoreFile = "truststore"; 60 static String passwd = "passphrase"; 61 62 /* 63 * Is the server ready to serve? 64 */ 65 volatile static boolean serverReady = false; 66 67 /* 68 * Turn on SSL debugging? 69 */ 70 static boolean debug = false; 71 72 /* 73 * If the client or server is doing some kind of object creation 74 * that the other side depends on, and that thread prematurely 75 * exits, you may experience a hang. The test harness will 76 * terminate all hung threads after its timeout has expired, 77 * currently 3 minutes by default, but you might try to be 78 * smart about it.... 79 */ 80 81 /* 82 * Define the server side of the test. 83 * 84 * If the server prematurely exits, serverReady will be set to true 85 * to avoid infinite hangs. 86 */ 87 void doServerSide() throws Exception { 88 SSLServerSocketFactory sslssf = 89 (SSLServerSocketFactory) SSLServerSocketFactory.getDefault(); 90 SSLServerSocket sslServerSocket = 91 (SSLServerSocket) sslssf.createServerSocket(serverPort); 92 serverPort = sslServerSocket.getLocalPort(); 93 94 /* 95 * Signal Client, we're ready for his connect. 96 */ 97 serverReady = true; 98 99 SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept(); 100 InputStream sslIS = sslSocket.getInputStream(); 101 OutputStream sslOS = sslSocket.getOutputStream(); 102 103 sslIS.read(); 104 sslOS.write(85); 105 sslOS.flush(); 106 107 sslSocket.close(); 108 109 // Close original server socket 110 sslServerSocket.close(); 111 112 // Try rebinding to same port 113 sslServerSocket = 114 (SSLServerSocket) sslssf.createServerSocket(serverPort); 115 sslServerSocket.close(); 116 } 117 118 /* 119 * Define the client side of the test. 120 * 121 * If the server prematurely exits, serverReady will be set to true 122 * to avoid infinite hangs. 123 */ 124 void doClientSide() throws Exception { 125 126 /* 127 * Wait for server to get started. 128 */ 129 while (!serverReady) { 130 Thread.sleep(50); 131 } 132 133 SSLSocketFactory sslsf = 134 (SSLSocketFactory) SSLSocketFactory.getDefault(); 135 SSLSocket sslSocket = (SSLSocket) 136 sslsf.createSocket("localhost", serverPort); 137 138 InputStream sslIS = sslSocket.getInputStream(); 139 OutputStream sslOS = sslSocket.getOutputStream(); 140 141 sslOS.write(280); 142 sslOS.flush(); 143 sslIS.read(); 144 145 sslSocket.close(); 146 } 147 148 /* 149 * ============================================================= 150 * The remainder is just support stuff 151 */ 152 153 // use any free port by default 154 volatile int serverPort = 0; 155 156 volatile Exception serverException = null; 157 volatile Exception clientException = null; 158 159 public static void main(String[] args) throws Exception { 160 String keyFilename = 161 System.getProperty("test.src", "./") + "/" + pathToStores + 162 "/" + keyStoreFile; 163 String trustFilename = 164 System.getProperty("test.src", "./") + "/" + pathToStores + 165 "/" + trustStoreFile; 166 167 System.setProperty("javax.net.ssl.keyStore", keyFilename); 168 System.setProperty("javax.net.ssl.keyStorePassword", passwd); 169 System.setProperty("javax.net.ssl.trustStore", trustFilename); 170 System.setProperty("javax.net.ssl.trustStorePassword", passwd); 171 172 if (debug) 173 System.setProperty("javax.net.debug", "all"); 174 175 /* 176 * Start the tests. 177 */ 178 new ReuseAddr(); 179 } 180 181 Thread clientThread = null; 182 Thread serverThread = null; 183 184 /* 185 * Primary constructor, used to drive remainder of the test. 186 * 187 * Fork off the other side, then do your work. 188 */ 189 ReuseAddr() throws Exception { 190 if (separateServerThread) { 191 startServer(true); 192 startClient(false); 193 } else { 194 startClient(true); 195 startServer(false); 196 } 197 198 /* 199 * Wait for other side to close down. 200 */ 201 if (separateServerThread) { 202 serverThread.join(); 203 } else { 204 clientThread.join(); 205 } 206 207 /* 208 * When we get here, the test is pretty much over. 209 * 210 * If the main thread excepted, that propagates back 211 * immediately. If the other thread threw an exception, we 212 * should report back. 213 */ 214 if (serverException != null) 215 throw serverException; 216 if (clientException != null) 217 throw clientException; 218 } 219 220 void startServer(boolean newThread) throws Exception { 221 if (newThread) { 222 serverThread = new Thread() { 223 public void run() { 224 try { 225 doServerSide(); 226 } catch (Exception e) { 227 /* 228 * Our server thread just died. 229 * 230 * Release the client, if not active already... 231 */ 232 System.err.println("Server died..."); 233 serverReady = true; 234 serverException = e; 235 } 236 } 237 }; 238 serverThread.start(); 239 } else { 240 doServerSide(); 241 } 242 } 243 244 void startClient(boolean newThread) throws Exception { 245 if (newThread) { 246 clientThread = new Thread() { 247 public void run() { 248 try { 249 doClientSide(); 250 } catch (Exception e) { 251 /* 252 * Our client thread just died. 253 */ 254 System.err.println("Client died..."); 255 clientException = e; 256 } 257 } 258 }; 259 clientThread.start(); 260 } else { 261 doClientSide(); 262 } 263 } 264} 265