1 /*
2  * Copyright (c) 2010, 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 6223635
27  * @summary Code hangs at connect call even when Timeout is specified
28  * @run main SocksConnectTimeout
29  * @run main/othervm -Djava.net.preferIPv4Stack=true SocksConnectTimeout
30  */
31 
32 import java.net.InetAddress;
33 import java.net.InetSocketAddress;
34 import java.net.Proxy;
35 import java.net.Socket;
36 import java.net.ServerSocket;
37 import java.net.SocketTimeoutException;
38 import java.io.IOException;
39 import java.io.Closeable;
40 import java.util.concurrent.Phaser;
41 import java.util.concurrent.TimeUnit;
42 
43 public class SocksConnectTimeout {
44     static ServerSocket serverSocket;
45     static final boolean debug = true;
46     static final Phaser startPhaser = new Phaser(2);
47     static final Phaser finishPhaser = new Phaser(2);
48     static int failed, passed;
49 
main(String[] args)50     public static void main(String[] args) {
51         try {
52             serverSocket = new ServerSocket();
53             InetAddress localHost = InetAddress.getLocalHost();
54             serverSocket.bind(new InetSocketAddress(localHost, 0));
55 
56             (new Thread() {
57                 @Override
58                 public void run() { serve(); }
59             }).start();
60 
61             Proxy socksProxy = new Proxy(Proxy.Type.SOCKS,
62                     new InetSocketAddress(localHost, serverSocket.getLocalPort()));
63 
64             test(socksProxy);
65         } catch (IOException e) {
66             unexpected(e);
67         } finally {
68             close(serverSocket);
69 
70             if (failed > 0)
71                 throw new RuntimeException("Test Failed: passed:" + passed + ", failed:" + failed);
72         }
73     }
74 
test(Proxy proxy)75     static void test(Proxy proxy) {
76         startPhaser.arriveAndAwaitAdvance();
77         Socket socket = null;
78         try {
79             socket = new Socket(proxy);
80             connectWithTimeout(socket);
81             failed("connected successfully!");
82         } catch (SocketTimeoutException socketTimeout) {
83             debug("Passed: Received: " + socketTimeout);
84             passed();
85         } catch (Exception exception) {
86             failed("Connect timeout test failed", exception);
87         } finally {
88             finishPhaser.arriveAndAwaitAdvance();
89             close(socket);
90         }
91     }
92 
connectWithTimeout(Socket socket)93     static void connectWithTimeout(Socket socket) throws IOException {
94         socket.connect(new InetSocketAddress(InetAddress.getLocalHost(), 1234), 500);
95     }
96 
serve()97     static void serve() {
98         Socket client = null;
99         try {
100             startPhaser.arriveAndAwaitAdvance();
101             client = serverSocket.accept();
102             finishPhaser.awaitAdvanceInterruptibly(finishPhaser.arrive(), 5, TimeUnit.SECONDS);
103         } catch (Exception e) {
104             unexpected(e);
105         } finally {
106             close(client);
107         }
108     }
109 
debug(String message)110     static void debug(String message) {
111         if (debug)
112             System.out.println(message);
113     }
114 
unexpected(Exception e )115     static void unexpected(Exception e ) {
116         System.out.println("Unexcepted Exception: " + e);
117     }
118 
close(Closeable closeable)119     static void close(Closeable closeable) {
120         if (closeable != null) try { closeable.close(); } catch (IOException e) {unexpected(e);}
121     }
122 
failed(String message)123     static void failed(String message) {
124         System.out.println(message);
125         failed++;
126     }
127 
failed(String message, Exception e)128     static void failed(String message, Exception e) {
129         System.out.println(message);
130         System.out.println(e);
131         failed++;
132     }
133 
passed()134     static void passed() { passed++; };
135 
136 }
137