6964547: Impossible to set useV4 in SocksSocketImpl
Summary: Add socksProxyVersion property
Reviewed-by: alanb, michaelm
--- a/jdk/make/sun/net/FILES_java.gmk Thu Jan 13 11:02:28 2011 +0000
+++ b/jdk/make/sun/net/FILES_java.gmk Thu Jan 13 13:24:58 2011 +0000
@@ -33,6 +33,7 @@
sun/net/ProgressEvent.java \
sun/net/ProgressListener.java \
sun/net/ProgressMeteringPolicy.java \
+ sun/net/SocksProxy.java \
sun/net/TelnetInputStream.java \
sun/net/TelnetOutputStream.java \
sun/net/TelnetProtocolException.java \
--- a/jdk/src/share/classes/java/io/PrintStream.java Thu Jan 13 11:02:28 2011 +0000
+++ b/jdk/src/share/classes/java/io/PrintStream.java Thu Jan 13 13:24:58 2011 +0000
@@ -70,7 +70,7 @@
private OutputStreamWriter charOut;
/**
- * nonNull is explicitly delcared here so as not to create an extra
+ * nonNull is explicitly declared here so as not to create an extra
* dependency on java.util.Objects.nonNull. PrintStream is loaded
* early during system initialization.
*/
--- a/jdk/src/share/classes/java/net/SocksSocketImpl.java Thu Jan 13 11:02:28 2011 +0000
+++ b/jdk/src/share/classes/java/net/SocksSocketImpl.java Thu Jan 13 13:24:58 2011 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,7 @@
import java.io.BufferedOutputStream;
import java.security.AccessController;
import java.security.PrivilegedExceptionAction;
+import sun.net.SocksProxy;
import sun.net.www.ParseUtil;
/* import org.ietf.jgss.*; */
@@ -397,6 +398,11 @@
// Use getHostString() to avoid reverse lookups
server = ((InetSocketAddress) p.address()).getHostString();
serverPort = ((InetSocketAddress) p.address()).getPort();
+ if (p instanceof SocksProxy) {
+ if (((SocksProxy)p).protocolVersion() == 4) {
+ useV4 = true;
+ }
+ }
// Connects to the SOCKS server
try {
@@ -700,6 +706,11 @@
// Use getHostString() to avoid reverse lookups
server = ((InetSocketAddress) p.address()).getHostString();
serverPort = ((InetSocketAddress) p.address()).getPort();
+ if (p instanceof SocksProxy) {
+ if (((SocksProxy)p).protocolVersion() == 4) {
+ useV4 = true;
+ }
+ }
// Connects to the SOCKS server
try {
--- a/jdk/src/share/classes/java/net/doc-files/net-properties.html Thu Jan 13 11:02:28 2011 +0000
+++ b/jdk/src/share/classes/java/net/doc-files/net-properties.html Thu Jan 13 13:24:58 2011 +0000
@@ -127,10 +127,15 @@
are specified. If SOCKS is supported by a Java SE implementation, the
following properties will be used:</P>
<UL>
- <LI><P><B>socksProxyHost</B> (default: <non>)<BR>
+ <LI><P><B>socksProxyHost</B> (default: <none>)<BR>
The hostname, or address, of the proxy server.</P>
<LI><P><B>socksProxyPort</B> (default: 1080)<BR>
The port number of the proxy server.</P>
+ <LI><P><B>socksProxyVersion</B> (default: 5)<BR>
+ The version of the SOCKS protocol supported by the server. The
+ default is <code>5</code> indicating SOCKS V5, alternatively
+ <code>4</code> can be specified for SOCKS V4. Setting the property
+ to values other than these leads to unspecified behavior.</P>
<LI><P><B>java.net.socks.username</B> (default: <none>)<BR>
Username to use if the SOCKSv5 server asks for authentication
and no java.net.Authenticator instance was found.</P>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/net/SocksProxy.java Thu Jan 13 13:24:58 2011 +0000
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.net;
+
+import java.net.Proxy;
+import java.net.SocketAddress;
+
+/**
+ * Proxy wrapper class so we can determine the socks protocol version.
+ */
+public final class SocksProxy extends Proxy {
+ private final int version;
+
+ private SocksProxy(SocketAddress addr, int version) {
+ super(Proxy.Type.SOCKS, addr);
+ this.version = version;
+ }
+
+ public static SocksProxy create(SocketAddress addr, int version) {
+ return new SocksProxy(addr, version);
+ }
+
+ public int protocolVersion() {
+ return version;
+ }
+}
--- a/jdk/src/share/classes/sun/net/spi/DefaultProxySelector.java Thu Jan 13 11:02:28 2011 +0000
+++ b/jdk/src/share/classes/sun/net/spi/DefaultProxySelector.java Thu Jan 13 13:24:58 2011 +0000
@@ -25,13 +25,20 @@
package sun.net.spi;
-import sun.net.NetProperties;
-import java.net.*;
-import java.util.*;
-import java.io.*;
+import java.net.InetSocketAddress;
+import java.net.Proxy;
+import java.net.ProxySelector;
+import java.net.SocketAddress;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+import java.io.IOException;
import sun.misc.RegexpPool;
import java.security.AccessController;
import java.security.PrivilegedAction;
+import sun.net.NetProperties;
+import sun.net.SocksProxy;
/**
* Supports proxy settings using system properties This proxy selector
@@ -75,6 +82,8 @@
{"socket", "socksProxy"}
};
+ private static final String SOCKS_PROXY_VERSION = "socksProxyVersion";
+
private static boolean hasSystemProxies = false;
static {
@@ -287,7 +296,8 @@
saddr = InetSocketAddress.createUnresolved(phost, pport);
// Socks is *always* the last on the list.
if (j == (props[i].length - 1)) {
- return new Proxy(Proxy.Type.SOCKS, saddr);
+ int version = NetProperties.getInteger(SOCKS_PROXY_VERSION, 5).intValue();
+ return SocksProxy.create(saddr, version);
} else {
return new Proxy(Proxy.Type.HTTP, saddr);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/Socks/SocksProxyVersion.java Thu Jan 13 13:24:58 2011 +0000
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6964547
+ * @run main/othervm SocksProxyVersion
+ * @summary test socksProxyVersion system property
+ */
+
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketException;
+import java.io.DataInputStream;
+import java.io.IOException;
+
+public class SocksProxyVersion implements Runnable {
+ ServerSocket ss;
+ volatile boolean failed;
+
+ public static void main(String[] args) throws Exception {
+ new SocksProxyVersion();
+ }
+
+ public SocksProxyVersion() throws Exception {
+ ss = new ServerSocket(0);
+ int port = ss.getLocalPort();
+ Thread serverThread = new Thread(this);
+ serverThread.start();
+
+ System.setProperty("socksProxyHost", "localhost");
+ System.setProperty("socksProxyPort", Integer.toString(port));
+
+ // SOCKS V4
+ System.setProperty("socksProxyVersion", Integer.toString(4));
+ try (Socket s = new Socket()) {
+ s.connect(new InetSocketAddress("localhost", port));
+ } catch (SocketException e) {
+ // java.net.SocketException: Malformed reply from SOCKS server
+ // This exception is OK, since the "server" does not implement
+ // the socks protocol. It just verifies the version and closes.
+ }
+
+ // SOCKS V5
+ System.setProperty("socksProxyVersion", Integer.toString(5));
+ try (Socket s = new Socket()) {
+ s.connect(new InetSocketAddress("localhost", port));
+ } catch (SocketException e) { /* OK */ }
+
+ serverThread.join();
+ if (failed) {
+ throw new RuntimeException("socksProxyVersion not being set correctly");
+ }
+ }
+
+ public void run() {
+ try (ss) {
+ Socket s = ss.accept();
+ int version = (s.getInputStream()).read();
+ if (version != 4) {
+ System.out.println("Got " + version + ", expected 4");
+ failed = true;
+ }
+ s.close();
+
+ s = ss.accept();
+ version = (s.getInputStream()).read();
+ if (version != 5) {
+ System.out.println("Got " + version + ", expected 5");
+ failed = true;
+ }
+ s.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+}