--- a/jdk/make/java/net/FILES_c.gmk Fri Apr 03 22:10:36 2009 +0100
+++ b/jdk/make/java/net/FILES_c.gmk Mon Apr 06 08:59:33 2009 +0100
@@ -39,6 +39,10 @@
ResolverConfigurationImpl.c \
DefaultProxySelector.c
+ifeq ($(PLATFORM), solaris)
+ FILES_c += SdpProvider.c
+endif
+
ifeq ($(PLATFORM), linux)
FILES_c += linux_close.c
endif
--- a/jdk/make/java/net/Makefile Fri Apr 03 22:10:36 2009 +0100
+++ b/jdk/make/java/net/Makefile Mon Apr 06 08:59:33 2009 +0100
@@ -108,11 +108,24 @@
#
LOCALE_SET_DEFINITION = jre
-properties: $(LIBDIR) $(LIBDIR)/net.properties
+MISC_FILES = $(LIBDIR) $(LIBDIR)/net.properties
$(LIBDIR)/net.properties: $(SHARE_SRC)/lib/net.properties
@$(RM) $@
$(CP) $< $@
-build: properties
+#
+# SDP configuration template
+#
+ifeq ($(PLATFORM), solaris)
+SDP_PATH = sdp/sdp.conf.template
+SDP_CONF = $(LIBDIR)/$(SDP_PATH)
+$(SDP_CONF): $(PLATFORM_SRC)/lib/$(SDP_PATH)
+ @$(RM) $*
+ $(install-file)
+MISC_FILES += $(SDP_CONF)
+endif
+
+build: $(MISC_FILES)
+
--- a/jdk/make/java/net/mapfile-vers Fri Apr 03 22:10:36 2009 +0100
+++ b/jdk/make/java/net/mapfile-vers Mon Apr 06 08:59:33 2009 +0100
@@ -90,6 +90,7 @@
Java_sun_net_dns_ResolverConfigurationImpl_fallbackDomain0;
Java_sun_net_spi_DefaultProxySelector_init;
Java_sun_net_spi_DefaultProxySelector_getSystemProxy;
+ Java_sun_net_spi_SdpProvider_convert;
NET_AllocSockaddr;
NET_SockaddrToInetAddress;
NET_SockaddrEqualsInetAddress;
--- a/jdk/make/sun/net/FILES_java.gmk Fri Apr 03 22:10:36 2009 +0100
+++ b/jdk/make/sun/net/FILES_java.gmk Mon Apr 06 08:59:33 2009 +0100
@@ -39,6 +39,7 @@
sun/net/TransferProtocolClient.java \
sun/net/ConnectionResetException.java \
sun/net/NetProperties.java \
+ sun/net/NetHooks.java \
sun/net/util/IPAddressUtil.java \
sun/net/dns/ResolverConfiguration.java \
sun/net/dns/ResolverConfigurationImpl.java \
@@ -123,3 +124,7 @@
ifeq ($(PLATFORM), windows)
FILES_java += sun/net/www/protocol/http/NTLMAuthSequence.java
endif
+
+ifeq ($(PLATFORM), solaris)
+ FILES_java += sun/net/spi/SdpProvider.java
+endif
--- a/jdk/src/share/classes/java/net/AbstractPlainSocketImpl.java Fri Apr 03 22:10:36 2009 +0100
+++ b/jdk/src/share/classes/java/net/AbstractPlainSocketImpl.java Mon Apr 06 08:59:33 2009 +0100
@@ -33,6 +33,7 @@
import java.io.ByteArrayOutputStream;
import sun.net.ConnectionResetException;
+import sun.net.NetHooks;
/**
* Default Socket Implementation. This implementation does
@@ -304,6 +305,11 @@
*/
synchronized void doConnect(InetAddress address, int port, int timeout) throws IOException {
+ synchronized (fdLock) {
+ if (!closePending && (socket == null || !socket.isBound())) {
+ NetHooks.beforeTcpConnect(fd, address, port);
+ }
+ }
try {
FileDescriptor fd = acquireFD();
try {
@@ -339,6 +345,11 @@
protected synchronized void bind(InetAddress address, int lport)
throws IOException
{
+ synchronized (fdLock) {
+ if (!closePending && (socket == null || !socket.isBound())) {
+ NetHooks.beforeTcpBind(fd, address, lport);
+ }
+ }
socketBind(address, lport);
if (socket != null)
socket.setBound();
--- a/jdk/src/share/classes/sun/nio/ch/AsynchronousServerSocketChannelImpl.java Fri Apr 03 22:10:36 2009 +0100
+++ b/jdk/src/share/classes/sun/nio/ch/AsynchronousServerSocketChannelImpl.java Mon Apr 06 08:59:33 2009 +0100
@@ -37,6 +37,7 @@
import java.util.Collections;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
+import sun.net.NetHooks;
/**
* Base implementation of AsynchronousServerSocketChannel.
@@ -131,6 +132,7 @@
synchronized (stateLock) {
if (localAddress != null)
throw new AlreadyBoundException();
+ NetHooks.beforeTcpBind(fd, isa.getAddress(), isa.getPort());
Net.bind(fd, isa.getAddress(), isa.getPort());
Net.listen(fd, backlog < 1 ? 50 : backlog);
localAddress = Net.localAddress(fd);
--- a/jdk/src/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java Fri Apr 03 22:10:36 2009 +0100
+++ b/jdk/src/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java Mon Apr 06 08:59:33 2009 +0100
@@ -38,6 +38,7 @@
import java.util.Collections;
import java.util.concurrent.*;
import java.util.concurrent.locks.*;
+import sun.net.NetHooks;
/**
* Base implementation of AsynchronousSocketChannel
@@ -387,6 +388,7 @@
throw new AlreadyBoundException();
InetSocketAddress isa = (local == null) ?
new InetSocketAddress(0) : Net.checkAddress(local);
+ NetHooks.beforeTcpBind(fd, isa.getAddress(), isa.getPort());
Net.bind(fd, isa.getAddress(), isa.getPort());
localAddress = Net.localAddress(fd);
}
--- a/jdk/src/share/classes/sun/nio/ch/ServerSocketChannelImpl.java Fri Apr 03 22:10:36 2009 +0100
+++ b/jdk/src/share/classes/sun/nio/ch/ServerSocketChannelImpl.java Mon Apr 06 08:59:33 2009 +0100
@@ -31,6 +31,7 @@
import java.nio.channels.*;
import java.nio.channels.spi.*;
import java.util.*;
+import sun.net.NetHooks;
/**
@@ -191,6 +192,7 @@
SecurityManager sm = System.getSecurityManager();
if (sm != null)
sm.checkListen(isa.getPort());
+ NetHooks.beforeTcpBind(fd, isa.getAddress(), isa.getPort());
Net.bind(fd, isa.getAddress(), isa.getPort());
Net.listen(fd, backlog < 1 ? 50 : backlog);
synchronized (stateLock) {
--- a/jdk/src/share/classes/sun/nio/ch/SocketChannelImpl.java Fri Apr 03 22:10:36 2009 +0100
+++ b/jdk/src/share/classes/sun/nio/ch/SocketChannelImpl.java Mon Apr 06 08:59:33 2009 +0100
@@ -32,6 +32,7 @@
import java.nio.channels.*;
import java.nio.channels.spi.*;
import java.util.*;
+import sun.net.NetHooks;
/**
@@ -526,6 +527,7 @@
throw new AlreadyBoundException();
InetSocketAddress isa = (local == null) ?
new InetSocketAddress(0) : Net.checkAddress(local);
+ NetHooks.beforeTcpBind(fd, isa.getAddress(), isa.getPort());
Net.bind(fd, isa.getAddress(), isa.getPort());
localAddress = Net.localAddress(fd);
}
@@ -577,6 +579,12 @@
if (!isOpen()) {
return false;
}
+ // notify hook only if unbound
+ if (localAddress == null) {
+ NetHooks.beforeTcpConnect(fd,
+ isa.getAddress(),
+ isa.getPort());
+ }
readerThread = NativeThread.current();
}
for (;;) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/solaris/classes/sun/net/NetHooks.java Mon Apr 06 08:59:33 2009 +0100
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.net;
+
+import java.net.InetAddress;
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import sun.security.action.GetPropertyAction;
+
+/**
+ * Defines static methods to be invoked prior to binding or connecting TCP sockets.
+ */
+
+public final class NetHooks {
+
+ /**
+ * A provider with hooks to allow sockets be converted prior to binding or
+ * connecting a TCP socket.
+ *
+ * <p> Concrete implementations of this class should define a zero-argument
+ * constructor and implement the abstract methods specified below.
+ */
+ public static abstract class Provider {
+ /**
+ * Initializes a new instance of this class.
+ */
+ protected Provider() {}
+
+ /**
+ * Invoked prior to binding a TCP socket.
+ */
+ public abstract void implBeforeTcpBind(FileDescriptor fdObj,
+ InetAddress address,
+ int port)
+ throws IOException;
+
+ /**
+ * Invoked prior to connecting an unbound TCP socket.
+ */
+ public abstract void implBeforeTcpConnect(FileDescriptor fdObj,
+ InetAddress address,
+ int port)
+ throws IOException;
+ }
+
+ /**
+ * For now, we load the SDP provider on Solaris. In the future this may
+ * be changed to use the ServiceLoader facility to allow the deployment of
+ * other providers.
+ */
+ private static Provider loadProvider(final String cn) {
+ return AccessController
+ .doPrivileged(new PrivilegedAction<Provider>() {
+ @Override public Provider run() {
+ Class<Provider> c;
+ try {
+ c = (Class<Provider>)Class.forName(cn, true, null);
+ } catch (ClassNotFoundException x) {
+ throw new AssertionError(x);
+ }
+ try {
+ return c.newInstance();
+ } catch (IllegalAccessException x) {
+ throw new AssertionError(x);
+ } catch (InstantiationException x) {
+ throw new AssertionError(x);
+ }
+ }});
+ }
+ private static final Provider provider = AccessController
+ .doPrivileged(new GetPropertyAction("os.name")).equals("SunOS") ?
+ loadProvider("sun.net.spi.SdpProvider") : null;
+
+ /**
+ * Invoke prior to binding a TCP socket.
+ */
+ public static void beforeTcpBind(FileDescriptor fdObj,
+ InetAddress address,
+ int port)
+ throws IOException
+ {
+ if (provider != null)
+ provider.implBeforeTcpBind(fdObj, address, port);
+ }
+
+ /**
+ * Invoke prior to connecting an unbound TCP socket.
+ */
+ public static void beforeTcpConnect(FileDescriptor fdObj,
+ InetAddress address,
+ int port)
+ throws IOException
+ {
+ if (provider != null)
+ provider.implBeforeTcpConnect(fdObj, address, port);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/solaris/classes/sun/net/spi/SdpProvider.java Mon Apr 06 08:59:33 2009 +0100
@@ -0,0 +1,339 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.net.spi;
+
+import sun.net.NetHooks;
+import java.net.InetAddress;
+import java.net.Inet4Address;
+import java.net.UnknownHostException;
+import java.util.*;
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.PrintStream;
+
+import sun.misc.SharedSecrets;
+import sun.misc.JavaIOFileDescriptorAccess;
+
+/**
+ * A NetHooks provider that converts sockets from the TCP to SDP protocol prior
+ * to binding or connecting.
+ */
+
+public class SdpProvider extends NetHooks.Provider {
+ private static final JavaIOFileDescriptorAccess fdAccess =
+ SharedSecrets.getJavaIOFileDescriptorAccess();
+
+ // maximum port
+ private static final int MAX_PORT = 65535;
+
+ // indicates if SDP is enabled and the rules for when the protocol is used
+ private final boolean enabled;
+ private final List<Rule> rules;
+
+ // logging for debug purposes
+ private PrintStream log;
+
+ public SdpProvider() {
+ // if this property is not defined then there is nothing to do.
+ String file = System.getProperty("com.sun.sdp.conf");
+ if (file == null) {
+ this.enabled = false;
+ this.rules = null;
+ return;
+ }
+
+ // load configuration file
+ List<Rule> list = null;
+ if (file != null) {
+ try {
+ list = loadRulesFromFile(file);
+ } catch (IOException e) {
+ fail("Error reading %s: %s", file, e.getMessage());
+ }
+ }
+
+ // check if debugging is enabled
+ PrintStream out = null;
+ String logfile = System.getProperty("com.sun.sdp.debug");
+ if (logfile != null) {
+ out = System.out;
+ if (logfile.length() > 0) {
+ try {
+ out = new PrintStream(logfile);
+ } catch (IOException ignore) { }
+ }
+ }
+
+ this.enabled = !list.isEmpty();
+ this.rules = list;
+ this.log = out;
+ }
+
+ // supported actions
+ private static enum Action {
+ BIND,
+ CONNECT;
+ }
+
+ // a rule for matching a bind or connect request
+ private static interface Rule {
+ boolean match(Action action, InetAddress address, int port);
+ }
+
+ // rule to match port[-end]
+ private static class PortRangeRule implements Rule {
+ private final Action action;
+ private final int portStart;
+ private final int portEnd;
+ PortRangeRule(Action action, int portStart, int portEnd) {
+ this.action = action;
+ this.portStart = portStart;
+ this.portEnd = portEnd;
+ }
+ Action action() {
+ return action;
+ }
+ @Override
+ public boolean match(Action action, InetAddress address, int port) {
+ return (action == this.action &&
+ port >= this.portStart &&
+ port <= this.portEnd);
+ }
+ }
+
+ // rule to match address[/prefix] port[-end]
+ private static class AddressPortRangeRule extends PortRangeRule {
+ private final byte[] addressAsBytes;
+ private final int prefixByteCount;
+ private final byte mask;
+ AddressPortRangeRule(Action action, InetAddress address,
+ int prefix, int port, int end)
+ {
+ super(action, port, end);
+ this.addressAsBytes = address.getAddress();
+ this.prefixByteCount = prefix >> 3;
+ this.mask = (byte)(0xff << (8 - (prefix % 8)));
+ }
+ @Override
+ public boolean match(Action action, InetAddress address, int port) {
+ if (action != action())
+ return false;
+ byte[] candidate = address.getAddress();
+ // same address type?
+ if (candidate.length != addressAsBytes.length)
+ return false;
+ // check bytes
+ for (int i=0; i<prefixByteCount; i++) {
+ if (candidate[i] != addressAsBytes[i])
+ return false;
+ }
+ // check remaining bits
+ if ((prefixByteCount < addressAsBytes.length) &&
+ ((candidate[prefixByteCount] & mask) !=
+ (addressAsBytes[prefixByteCount] & mask)))
+ return false;
+ return super.match(action, address, port);
+ }
+ }
+
+ // parses port:[-end]
+ private static int[] parsePortRange(String s) {
+ int pos = s.indexOf('-');
+ try {
+ int[] result = new int[2];
+ if (pos < 0) {
+ boolean all = s.equals("*");
+ result[0] = all ? 0 : Integer.parseInt(s);
+ result[1] = all ? MAX_PORT : result[0];
+ } else {
+ String low = s.substring(0, pos);
+ if (low.length() == 0) low = "*";
+ String high = s.substring(pos+1);
+ if (high.length() == 0) high = "*";
+ result[0] = low.equals("*") ? 0 : Integer.parseInt(low);
+ result[1] = high.equals("*") ? MAX_PORT : Integer.parseInt(high);
+ }
+ return result;
+ } catch (NumberFormatException e) {
+ return new int[0];
+ }
+ }
+
+ private static void fail(String msg, Object... args) {
+ Formatter f = new Formatter();
+ f.format(msg, args);
+ throw new RuntimeException(f.out().toString());
+ }
+
+ // loads rules from the given file
+ // Each non-blank/non-comment line must have the format:
+ // ("bind" | "connect") 1*LWSP-char (hostname | ipaddress["/" prefix])
+ // 1*LWSP-char ("*" | port) [ "-" ("*" | port) ]
+ private static List<Rule> loadRulesFromFile(String file)
+ throws IOException
+ {
+ Scanner scanner = new Scanner(new File(file));
+ try {
+ List<Rule> result = new ArrayList<Rule>();
+ while (scanner.hasNextLine()) {
+ String line = scanner.nextLine().trim();
+
+ // skip blank lines and comments
+ if (line.length() == 0 || line.charAt(0) == '#')
+ continue;
+
+ // must have 3 fields
+ String[] s = line.split("\\s+");
+ if (s.length != 3) {
+ fail("Malformed line '%s'", line);
+ continue;
+ }
+
+ // first field is the action ("bind" or "connect")
+ Action action = null;
+ for (Action a: Action.values()) {
+ if (s[0].equalsIgnoreCase(a.name())) {
+ action = a;
+ break;
+ }
+ }
+ if (action == null) {
+ fail("Action '%s' not recognized", s[0]);
+ continue;
+ }
+
+ // * port[-end]
+ int[] ports = parsePortRange(s[2]);
+ if (ports.length == 0) {
+ fail("Malformed port range '%s'", s[2]);
+ continue;
+ }
+
+ // match all addresses
+ if (s[1].equals("*")) {
+ result.add(new PortRangeRule(action, ports[0], ports[1]));
+ continue;
+ }
+
+ // hostname | ipaddress[/prefix]
+ int pos = s[1].indexOf('/');
+ try {
+ if (pos < 0) {
+ // hostname or ipaddress (no prefix)
+ InetAddress[] addresses = InetAddress.getAllByName(s[1]);
+ for (InetAddress address: addresses) {
+ int prefix =
+ (address instanceof Inet4Address) ? 32 : 128;
+ result.add(new AddressPortRangeRule(action, address,
+ prefix, ports[0], ports[1]));
+ }
+ } else {
+ // ipaddress/prefix
+ InetAddress address = InetAddress
+ .getByName(s[1].substring(0, pos));
+ int prefix = -1;
+ try {
+ prefix = Integer.parseInt(s[1].substring(pos+1));
+ if (address instanceof Inet4Address) {
+ // must be 1-31
+ if (prefix < 0 || prefix > 32) prefix = -1;
+ } else {
+ // must be 1-128
+ if (prefix < 0 || prefix > 128) prefix = -1;
+ }
+ } catch (NumberFormatException e) {
+ }
+
+ if (prefix > 0) {
+ result.add(new AddressPortRangeRule(action,
+ address, prefix, ports[0], ports[1]));
+ } else {
+ fail("Malformed prefix '%s'", s[1]);
+ continue;
+ }
+ }
+ } catch (UnknownHostException uhe) {
+ fail("Unknown host or malformed IP address '%s'", s[1]);
+ continue;
+ }
+ }
+ return result;
+ } finally {
+ scanner.close();
+ }
+ }
+
+ // converts unbound TCP socket to a SDP socket if it matches the rules
+ private void convertTcpToSdpIfMatch(FileDescriptor fdObj,
+ Action action,
+ InetAddress address,
+ int port)
+ throws IOException
+ {
+ boolean matched = false;
+ for (Rule rule: rules) {
+ if (rule.match(action, address, port)) {
+ int fd = fdAccess.get(fdObj);
+ convert(fd);
+ matched = true;
+ break;
+ }
+ }
+ if (log != null) {
+ String addr = (address instanceof Inet4Address) ?
+ address.getHostAddress() : "[" + address.getHostAddress() + "]";
+ if (matched) {
+ log.format("%s to %s:%d (socket converted to SDP protocol)\n", action, addr, port);
+ } else {
+ log.format("%s to %s:%d (no match)\n", action, addr, port);
+ }
+ }
+ }
+
+ @Override
+ public void implBeforeTcpBind(FileDescriptor fdObj,
+ InetAddress address,
+ int port)
+ throws IOException
+ {
+ if (enabled)
+ convertTcpToSdpIfMatch(fdObj, Action.BIND, address, port);
+ }
+
+ @Override
+ public void implBeforeTcpConnect(FileDescriptor fdObj,
+ InetAddress address,
+ int port)
+ throws IOException
+ {
+ if (enabled)
+ convertTcpToSdpIfMatch(fdObj, Action.CONNECT, address, port);
+ }
+
+ // -- native methods --
+ private static native void convert(int fd) throws IOException;
+}
--- a/jdk/src/solaris/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java Fri Apr 03 22:10:36 2009 +0100
+++ b/jdk/src/solaris/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java Mon Apr 06 08:59:33 2009 +0100
@@ -32,6 +32,7 @@
import java.io.IOException;
import java.io.FileDescriptor;
import java.security.AccessController;
+import sun.net.NetHooks;
import sun.security.action.GetPropertyAction;
/**
@@ -305,6 +306,7 @@
sm.checkConnect(isa.getAddress().getHostAddress(), isa.getPort());
// check and set state
+ boolean notifyBeforeTcpConnect;
synchronized (stateLock) {
if (state == ST_CONNECTED)
throw new AlreadyConnectedException();
@@ -312,12 +314,16 @@
throw new ConnectionPendingException();
state = ST_PENDING;
pendingRemote = remote;
+ notifyBeforeTcpConnect = (localAddress == null);
}
AbstractFuture<Void,A> result = null;
Throwable e = null;
try {
begin();
+ // notify hook if unbound
+ if (notifyBeforeTcpConnect)
+ NetHooks.beforeTcpConnect(fd, isa.getAddress(), isa.getPort());
int n = Net.connect(fd, isa.getAddress(), isa.getPort());
if (n == IOStatus.UNAVAILABLE) {
// connection could not be established immediately
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/solaris/lib/sdp/sdp.conf.template Mon Apr 06 08:59:33 2009 +0100
@@ -0,0 +1,30 @@
+#
+# Configuration file to enable InfiniBand Sockets Direct Protocol.
+#
+# Each line that does not start with a comment (#) is a rule to indicate when
+# the SDP transport protocol should be used. The format of a rule is as follows:
+# ("bind"|"connect") 1*LWSP-char (hostname|ipaddress["/"prefix]) 1*LWSP-char ("*"|port)["-"("*"|port)]
+#
+# A "bind" rule indicates that the SDP protocol transport should be used when
+# a TCP socket binds to an address/port that matches the rule. A "connect" rule
+# indicates that the SDP protocol transport should be used when an unbound
+# TCP socket attempts to connect to an address/port that matches the rule.
+# Addresses may be specified as hostnames or literal Internet Protocol (IP)
+# addresses. When a literal IP address is used then a prefix length may be used
+# to indicate the number of bits for matching (useful when a block of addresses
+# or subnet is allocated to the InfiniBand fabric).
+
+# Use SDP for all sockets that bind to specific local addresses
+#bind 192.168.1.1 *
+#bind fe80::21b:24ff:fe3d:7896 *
+
+# Use SDP for all sockets that bind to the wildcard address in a port range
+#bind 0.0.0.0 5000-5999
+#bind ::0 5000-5999
+
+# Use SDP when connecting to all application services on 192.168.1.*
+#connect 192.168.1.0/24 1024-*
+
+# Use SDP when connecting to the http server or MySQL database on hpccluster.
+#connect hpccluster.foo.com 80
+#connect hpccluster.foo.com 3306
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/solaris/native/sun/net/spi/SdpProvider.c Mon Apr 06 08:59:33 2009 +0100
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#if defined(__solaris__) && !defined(PROTO_SDP)
+#define PROTO_SDP 257
+#endif
+
+#include "jni.h"
+#include "jni_util.h"
+#include "net_util.h"
+
+#define RESTARTABLE(_cmd, _result) do { \
+ do { \
+ _result = _cmd; \
+ } while((_result == -1) && (errno == EINTR)); \
+} while(0)
+
+JNIEXPORT void JNICALL
+Java_sun_net_spi_SdpProvider_convert(JNIEnv *env, jclass cls, jint fd)
+{
+#ifdef PROTO_SDP
+ int domain = ipv6_available() ? AF_INET6 : AF_INET;
+ int s = socket(domain, SOCK_STREAM, PROTO_SDP);
+ if (s < 0) {
+ JNU_ThrowIOExceptionWithLastError(env, "socket");
+ } else {
+ int arg, len, res;
+ struct linger linger;
+
+ /* copy socket options that are relevant to SDP */
+ len = sizeof(arg);
+ if (getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&arg, &len) == 0)
+ setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&arg, len);
+ len = sizeof(arg);
+ if (getsockopt(fd, SOL_SOCKET, SO_OOBINLINE, (char*)&arg, &len) == 0)
+ setsockopt(s, SOL_SOCKET, SO_OOBINLINE, (char*)&arg, len);
+ len = sizeof(linger);
+ if (getsockopt(fd, SOL_SOCKET, SO_LINGER, (void*)&linger, &len) == 0)
+ setsockopt(s, SOL_SOCKET, SO_LINGER, (char*)&linger, len);
+
+ RESTARTABLE(dup2(s, fd), res);
+ if (res < 0)
+ JNU_ThrowIOExceptionWithLastError(env, "dup2");
+ RESTARTABLE(close(s), res);
+ }
+#else
+ JNU_ThrowInternalError(env, "should not reach here");
+#endif
+}
--- a/jdk/src/solaris/native/sun/nio/ch/FileChannelImpl.c Fri Apr 03 22:10:36 2009 +0100
+++ b/jdk/src/solaris/native/sun/nio/ch/FileChannelImpl.c Mon Apr 06 08:59:33 2009 +0100
@@ -231,6 +231,8 @@
if (result < 0) {
if (errno == EAGAIN)
return IOS_UNAVAILABLE;
+ if (errno == EOPNOTSUPP)
+ return IOS_UNSUPPORTED_CASE;
if ((errno == EINVAL) && ((ssize_t)count >= 0))
return IOS_UNSUPPORTED_CASE;
if (errno == EINTR)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/windows/classes/sun/net/NetHooks.java Mon Apr 06 08:59:33 2009 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package sun.net;
+
+import java.net.InetAddress;
+import java.io.FileDescriptor;
+import java.io.IOException;
+
+/**
+ * Defines static methods to ensure that any installed net hooks are invoked
+ * prior to binding or connecting TCP sockets.
+ */
+
+public final class NetHooks {
+
+ /**
+ * Invoke prior to binding a TCP socket.
+ */
+ public static void beforeTcpBind(FileDescriptor fdObj,
+ InetAddress address,
+ int port)
+ throws IOException
+ {
+ // nothing to do
+ }
+
+ /**
+ * Invoke prior to connecting an unbound TCP socket.
+ */
+ public static void beforeTcpConnect(FileDescriptor fdObj,
+ InetAddress address,
+ int port)
+ throws IOException
+ {
+ // nothing to do
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/net/sdp/ProbeIB.java Mon Apr 06 08:59:33 2009 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.net.NetworkInterface;
+import java.net.InetAddress;
+import java.util.Scanner;
+import java.util.Enumeration;
+
+/**
+ * Probes for InfiniBand devices plumbed with IP addresses.
+ */
+
+public class ProbeIB {
+ public static void main(String[] args) throws IOException {
+ Scanner s = new Scanner(new File("/etc/path_to_inst"));
+ try {
+ while (s.hasNextLine()) {
+ String line = s.nextLine();
+ if (line.startsWith("#"))
+ continue;
+ String[] fields = line.split("\\s+");
+ if (!fields[2].equals("\"ibd\""))
+ continue;
+ String name = fields[2].substring(1, fields[2].length()-1) + fields[1];
+ NetworkInterface ni = NetworkInterface.getByName(name);
+ if (ni != null) {
+ Enumeration<InetAddress> addrs = ni.getInetAddresses();
+ while (addrs.hasMoreElements()) {
+ System.out.println(addrs.nextElement().getHostAddress());
+ }
+ }
+ }
+ } finally {
+ s.close();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/net/sdp/Sanity.java Mon Apr 06 08:59:33 2009 +0100
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.net.*;
+import java.io.*;
+import java.nio.channels.*;
+import java.util.Enumeration;
+
+/**
+ * Sanity check Socket/ServerSocket and each of the stream-oriented channels
+ * on each IP address plumbed to the network adapters.
+ */
+
+public class Sanity {
+ public static void main(String[] args) throws Exception {
+ Enumeration<NetworkInterface> nifs = NetworkInterface.getNetworkInterfaces();
+ while (nifs.hasMoreElements()) {
+ NetworkInterface ni = nifs.nextElement();
+ Enumeration<InetAddress> addrs = ni.getInetAddresses();
+ while (addrs.hasMoreElements()) {
+ InetAddress addr = addrs.nextElement();
+ test(addr);
+ }
+ }
+ }
+
+ static void test(InetAddress addr) throws Exception {
+ System.out.println(addr.getHostAddress());
+
+ // ServerSocketChannel.bind
+ ServerSocketChannel ssc = ServerSocketChannel.open();
+ try {
+ ssc.bind(new InetSocketAddress(addr, 0));
+ int port = ((InetSocketAddress)(ssc.getLocalAddress())).getPort();
+
+ // SocketChannel.connect (implicit bind)
+ SocketChannel client = SocketChannel.open();
+ try {
+ client.connect(new InetSocketAddress(addr, port));
+ SocketChannel peer = ssc.accept();
+ try {
+ testConnection(Channels.newOutputStream(client),
+ Channels.newInputStream(peer));
+ } finally {
+ peer.close();
+ }
+ } finally {
+ client.close();
+ }
+
+ // SocketChannel.connect (explicit bind)
+ client = SocketChannel.open();
+ try {
+ client.bind(new InetSocketAddress(addr, 0))
+ .connect(new InetSocketAddress(addr, port));
+ ssc.accept().close();
+ } finally {
+ client.close();
+ }
+ } finally {
+ ssc.close();
+ }
+
+ // AsynchronousServerSocketChannel.bind
+ AsynchronousServerSocketChannel server =
+ AsynchronousServerSocketChannel.open();
+ try {
+ server.bind(new InetSocketAddress(addr, 0));
+ int port = ((InetSocketAddress)(server.getLocalAddress())).getPort();
+
+ // AsynchronousSocketChannel.connect (implicit bind)
+ AsynchronousSocketChannel client = AsynchronousSocketChannel.open();
+ try {
+ client.connect(new InetSocketAddress(addr, port)).get();
+ AsynchronousSocketChannel peer = server.accept().get();
+ try {
+ testConnection(Channels.newOutputStream(client),
+ Channels.newInputStream(peer));
+ } finally {
+ peer.close();
+ }
+ } finally {
+ client.close();
+ }
+
+ // AsynchronousSocketChannel.connect (explicit bind)
+ client = AsynchronousSocketChannel.open();
+ try {
+ client.bind(new InetSocketAddress(addr, 0))
+ .connect(new InetSocketAddress(addr, port)).get();
+ server.accept().get().close();
+ } finally {
+ client.close();
+ }
+ } finally {
+ server.close();
+ }
+
+ // ServerSocket.bind
+ ServerSocket ss = new ServerSocket();
+ try {
+ ss.bind(new InetSocketAddress(addr, 0));
+ int port = ss.getLocalPort();
+
+ // Socket.connect (implicit bind)
+ Socket s = new Socket();
+ try {
+ s.connect(new InetSocketAddress(addr, port));
+ Socket peer = ss.accept();
+ try {
+ testConnection(s.getOutputStream(), peer.getInputStream());
+ } finally {
+ peer.close();
+ }
+ } finally {
+ s.close();
+ }
+
+ // Socket.connect (explicit bind)
+ s = new Socket();
+ try {
+ s.bind(new InetSocketAddress(addr, 0));
+ s.connect(new InetSocketAddress(addr, port));
+ ss.accept().close();
+ } finally {
+ s.close();
+ }
+ } finally {
+ ss.close();
+ }
+ }
+
+ static void testConnection(OutputStream out, InputStream in)
+ throws IOException
+ {
+ byte[] msg = "hello".getBytes();
+ out.write(msg);
+
+ byte[] ba = new byte[100];
+ int nread = 0;
+ while (nread < msg.length) {
+ int n = in.read(ba);
+ if (n < 0)
+ throw new IOException("EOF not expected!");
+ nread += n;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/net/sdp/sanity.sh Mon Apr 06 08:59:33 2009 +0100
@@ -0,0 +1,72 @@
+#
+# Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
+# @test
+# @bug 4890703
+# @summary Unit test for Solaris SDP support
+# @build ProbeIB Sanity
+# @run shell sanity.sh
+
+# Check we are on Solaris and that SDP is enabled
+OS=`uname -s`
+if [ "$OS" != "SunOS" ]; then
+ echo "This is a Solaris-only test"
+ exit 0
+fi
+SDPADM=/usr/sbin/sdpadm
+if [ ! -f ${SDPADM} ]; then
+ echo "SDP not available"
+ exit 0
+fi
+${SDPADM} status|grep Enabled
+if [ $? != 0 ]; then
+ echo "SDP not enabled"
+ exit 0
+fi
+
+if [ -z "$TESTJAVA" ]; then
+ JAVA=java
+ TESTCLASSES=.
+ TESTSRC=.
+else
+ JAVA="${TESTJAVA}/bin/java"
+fi
+
+CLASSPATH=${TESTCLASSES}:${TESTSRC}
+export CLASSPATH
+
+# Probe for IP addresses plumbed to IB interfaces
+$JAVA -Djava.net.preferIPv4Stack=true ProbeIB > ib_addrs
+
+# Create sdp.conf
+SDPCONF=sdp.conf
+rm ${SDPCONF}
+touch ${SDPCONF}
+cat ib_addrs | while read ADDR
+do
+ echo "bind ${ADDR} *" > ${SDPCONF}
+ echo "connect ${ADDR} *" >> ${SDPCONF}
+done
+
+# Sanity check
+$JAVA -Djava.net.preferIPv4Stack=true -Dcom.sun.sdp.conf=${SDPCONF} -Dcom.sun.sdp.debug Sanity