Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/sun/security/ssl/SSLSocketImpl/ClientTimeout.java
38853 views
/*1* Copyright (c) 2005, 2011, 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// SunJSSE does not support dynamic system properties, no way to re-use24// system properties in samevm/agentvm mode.2526/*27* @test28* @bug 483649329* @ignore need further evaluation30* @summary Socket timeouts for SSLSockets causes data corruption.31* @run main/othervm ClientTimeout32*/3334import java.io.*;35import java.net.*;36import java.util.*;37import java.security.*;38import javax.net.ssl.*;3940public class ClientTimeout {4142/*43* =============================================================44* Set the various variables needed for the tests, then45* specify what tests to run on each side.46*/4748/*49* Should we run the client or server in a separate thread?50* Both sides can throw exceptions, but do you have a preference51* as to which side should be the main thread.52*/53static boolean separateServerThread = true;5455/*56* Where do we find the keystores?57*/58static String pathToStores = "../../../../javax/net/ssl/etc";59static String keyStoreFile = "keystore";60static String trustStoreFile = "truststore";61static String passwd = "passphrase";6263/*64* Is the server ready to serve?65*/66volatile static boolean serverReady = false;6768/*69* Turn on SSL debugging?70*/71static boolean debug = false;727374/*75* define the rhythm of timeout exception76*/77static boolean rhythm = true;7879/*80* If the client or server is doing some kind of object creation81* that the other side depends on, and that thread prematurely82* exits, you may experience a hang. The test harness will83* terminate all hung threads after its timeout has expired,84* currently 3 minutes by default, but you might try to be85* smart about it....86*/8788/*89* Define the server side of the test.90*91* If the server prematurely exits, serverReady will be set to true92* to avoid infinite hangs.93*/94void doServerSide() throws Exception {95SSLServerSocketFactory sslssf =96(SSLServerSocketFactory) SSLServerSocketFactory.getDefault();97SSLServerSocket sslServerSocket =98(SSLServerSocket) sslssf.createServerSocket(serverPort);99100serverPort = sslServerSocket.getLocalPort();101102/*103* Signal Client, we're ready for his connect.104*/105serverReady = true;106107SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();108InputStream sslIS = sslSocket.getInputStream();109OutputStream sslOS = sslSocket.getOutputStream();110sslSocket.startHandshake();111112// transfer a file to client.113String transFilename =114System.getProperty("test.src", "./") + "/" +115this.getClass().getName() + ".java";116MessageDigest md = MessageDigest.getInstance("SHA");117DigestInputStream transIns = new DigestInputStream(118new FileInputStream(transFilename), md);119120byte[] bytes = new byte[2000];121int i = 0;122while (true) {123// reset the cycle124if (i >= bytes.length) {125i = 0;126}127128int length = 0;129if ((length = transIns.read(bytes, 0, i++)) == -1) {130break;131} else {132sslOS.write(bytes, 0, length);133sslOS.flush();134135if (i % 3 == 0) {136Thread.sleep(300); // Stall past the timeout...137}138}139}140serverDigest = md.digest();141transIns.close();142sslSocket.close();143}144145/*146* Define the client side of the test.147*148* If the server prematurely exits, serverReady will be set to true149* to avoid infinite hangs.150*/151void doClientSide() throws Exception {152boolean caught = false;153154/*155* Wait for server to get started.156*/157while (!serverReady) {158Thread.sleep(50);159}160161Socket baseSocket = new Socket("localhost", serverPort) {162MyInputStream ins = null;163164public InputStream getInputStream() throws IOException {165if (ins != null) {166return ins;167} else {168ins = new MyInputStream(super.getInputStream());169return ins;170}171}172};173174SSLSocketFactory sslsf =175(SSLSocketFactory) SSLSocketFactory.getDefault();176SSLSocket sslSocket = (SSLSocket)177sslsf.createSocket(baseSocket, "localhost", serverPort, true);178179InputStream sslIS = sslSocket.getInputStream();180OutputStream sslOS = sslSocket.getOutputStream();181182// handshaking183sslSocket.setSoTimeout(100); // The stall timeout.184while (true) {185try {186rhythm = true;187sslSocket.startHandshake();188break;189} catch (SocketTimeoutException e) {190System.out.println("Handshaker exception: "191+ e.getMessage());192}193}194195// read application data from server196MessageDigest md = MessageDigest.getInstance("SHA");197DigestInputStream transIns = new DigestInputStream(sslIS, md);198byte[] bytes = new byte[2000];199while (true) {200try {201rhythm = true;202203while (transIns.read(bytes, 0, 17) != -1) {204rhythm = true;205}206break;207} catch (SocketTimeoutException e) {208System.out.println("InputStream Exception: "209+ e.getMessage());210}211}212// Wait for server to get ready.213while (serverDigest == null) {214Thread.sleep(20);215}216217byte[] cliDigest = md.digest();218if (!Arrays.equals(cliDigest, serverDigest)) {219throw new Exception("Application data trans error");220}221222transIns.close();223sslSocket.close();224}225226/*227* =============================================================228* The remainder is just support stuff229*/230231static class MyInputStream extends InputStream {232InputStream ins = null;233234public MyInputStream(InputStream ins) {235this.ins = ins;236}237238public int read() throws IOException {239return read(new byte[1], 0, 1);240}241242public int read(byte[] data, int offset, int len) throws IOException {243if (!ClientTimeout.rhythm) {244throw new SocketTimeoutException(245"Throwing a timeout exception");246}247ClientTimeout.rhythm = false;248return ins.read(data, offset, len);249}250}251252// use any free port by default253volatile int serverPort = 0;254255volatile Exception serverException = null;256volatile Exception clientException = null;257258volatile byte[] serverDigest = null;259260public static void main(String[] args) throws Exception {261String keyFilename =262System.getProperty("test.src", "./") + "/" + pathToStores +263"/" + keyStoreFile;264String trustFilename =265System.getProperty("test.src", "./") + "/" + pathToStores +266"/" + trustStoreFile;267268System.setProperty("javax.net.ssl.keyStore", keyFilename);269System.setProperty("javax.net.ssl.keyStorePassword", passwd);270System.setProperty("javax.net.ssl.trustStore", trustFilename);271System.setProperty("javax.net.ssl.trustStorePassword", passwd);272273if (debug)274System.setProperty("javax.net.debug", "all");275276/*277* Start the tests.278*/279new ClientTimeout();280}281282Thread clientThread = null;283Thread serverThread = null;284285/*286* Primary constructor, used to drive remainder of the test.287*288* Fork off the other side, then do your work.289*/290ClientTimeout() throws Exception {291if (separateServerThread) {292startServer(true);293startClient(false);294} else {295startClient(true);296startServer(false);297}298299/*300* Wait for other side to close down.301*/302if (separateServerThread) {303serverThread.join();304} else {305clientThread.join();306}307308/*309* When we get here, the test is pretty much over.310*311* If the main thread excepted, that propagates back312* immediately. If the other thread threw an exception, we313* should report back.314*/315if (serverException != null) {316System.out.print("Server Exception:");317throw serverException;318}319if (clientException != null) {320System.out.print("Client Exception:");321throw clientException;322}323}324325void startServer(boolean newThread) throws Exception {326if (newThread) {327serverThread = new Thread() {328public void run() {329try {330doServerSide();331} catch (Exception e) {332/*333* Our server thread just died.334*335* Release the client, if not active already...336*/337System.err.println("Server died...");338System.err.println(e);339serverReady = true;340serverException = e;341}342}343};344serverThread.start();345} else {346doServerSide();347}348}349350void startClient(boolean newThread) throws Exception {351if (newThread) {352clientThread = new Thread() {353public void run() {354try {355doClientSide();356} catch (Exception e) {357/*358* Our client thread just died.359*/360System.err.println("Client died...");361clientException = e;362}363}364};365clientThread.start();366} else {367doClientSide();368}369}370}371372373