1 /* 2 * Copyright (c) 1999, 2008, 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 /* @test 25 * @bug 4208804 26 * 27 * @summary Incoming connections should be subject to timeout 28 * @author Adrian Colley 29 * 30 * @build TestIface TestImpl TestImpl_Stub 31 * @run main/othervm/policy=security.policy/timeout=60 32 * -Dsun.rmi.transport.tcp.readTimeout=5000 ReadTimeoutTest 33 */ 34 35 /* This test sets a very short read timeout, exports an object, and then 36 * connects to the port and does nothing. The server should close the 37 * connection after the timeout. If that doesn't happen, the test fails. 38 * 39 * A background thread does the read. The foreground waits for DELAY*4 40 * and then aborts. This should give sufficient margin for timing slop. 41 */ 42 43 import java.rmi.*; 44 import java.rmi.server.RMISocketFactory; 45 import java.io.*; 46 import java.net.*; 47 import java.util.concurrent.CountDownLatch; 48 import java.util.concurrent.TimeUnit; 49 50 public class ReadTimeoutTest 51 { 52 private static final int DELAY = 5000; // milliseconds 53 54 public static void main(String[] args) 55 throws Exception 56 { 57 // Make trouble for ourselves 58 if (System.getSecurityManager() == null) 59 System.setSecurityManager(new RMISecurityManager()); 60 61 // Flaky code alert - hope this is executed before TCPTransport.<clinit> 62 System.setProperty("sun.rmi.transport.tcp.readTimeout", Integer.toString(DELAY)); 63 64 // Set the socket factory. 65 System.err.println("(installing socket factory)"); 66 SomeFactory fac = new SomeFactory(); 67 RMISocketFactory.setSocketFactory(fac); 68 69 // Create remote object 70 TestImpl impl = new TestImpl(); 71 72 // Export and get which port. 73 System.err.println("(exporting remote object)"); 74 int port = fac.whichPort(); 75 76 // Sanity 77 if (port == 0) 78 throw new Error("TEST FAILED: export didn't reserve a port(?)"); 79 try (Socket DoS = new Socket("127.0.0.1", port)) { 80 // Now, connect to that port 81 //Thread.sleep(2000); 82 System.err.println("(connecting to listening port on 127.0.0.1:" + 83 port + ")"); 84 InputStream stream = DoS.getInputStream(); 85 86 // Read on the socket in the background 87 CountDownLatch done = new CountDownLatch(1); 88 (new SomeReader(stream, done)).start(); 89 90 // Wait for completion 91 if (done.await(DELAY * 4, TimeUnit.SECONDS)) { 92 System.err.println("TEST PASSED."); 93 } else { 94 throw new Error("TEST FAILED."); 95 } 96 } catch (InterruptedException ie) { 97 throw new Error("Unexpected error happen in reader:" + ie); 98 } finally { 99 impl.unexport(); 100 } 101 // Should exit here 102 } 103 104 private static class SomeFactory 105 extends RMISocketFactory 106 { 107 private int servport = 0; 108 109 @Override 110 public Socket createSocket(String h, int p) 111 throws IOException 112 { 113 return (new Socket(h, p)); 114 } 115 116 /** Create a server socket and remember which port it's on. 117 * Aborts if createServerSocket(0) is called twice, because then 118 * it doesn't know whether to remember the first or second port. 119 */ 120 @Override 121 public ServerSocket createServerSocket(int p) 122 throws IOException 123 { 124 ServerSocket ss; 125 ss = new ServerSocket(p); 126 if (p == 0) { 127 if (servport != 0) { 128 System.err.println("TEST FAILED: " + 129 "Duplicate createServerSocket(0)"); 130 throw new Error("Test aborted (createServerSocket)"); 131 } 132 servport = ss.getLocalPort(); 133 } 134 return (ss); 135 } 136 137 /** Return which port was reserved by createServerSocket(0). 138 * If the return value was 0, createServerSocket(0) wasn't called. 139 */ 140 public int whichPort() { 141 return (servport); 142 } 143 } // end class SomeFactory 144 145 protected static class SomeReader extends Thread { 146 private final InputStream readon; 147 private final CountDownLatch done; 148 149 public SomeReader(InputStream s, CountDownLatch done) { 150 super(); 151 this.setDaemon(true); 152 this.readon = s; 153 this.done = done; 154 } 155 156 @Override 157 public void run() { 158 try { 159 int c = this.readon.read(); 160 if (c != -1) 161 throw new Error ("Server returned " + c); 162 done.countDown(); 163 } catch (IOException e) { 164 e.printStackTrace(); 165 } 166 } 167 } // end class SomeReader 168 }