Mercurial > hg > jdk9-shenandoah > jdk
changeset 2736:174916d435c9
6965072: Need API to create SDP sockets
Reviewed-by: michaelm
line wrap: on
line diff
--- a/make/com/Makefile Wed Sep 01 17:37:45 2010 -0700 +++ b/make/com/Makefile Fri Sep 03 13:11:54 2010 +0100 @@ -31,7 +31,7 @@ PRODUCT = com include $(BUILDDIR)/common/Defs.gmk -SUBDIRS = sun +SUBDIRS = sun oracle include $(BUILDDIR)/common/Subdirs.gmk all build clean clobber::
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/make/com/oracle/Makefile Fri Sep 03 13:11:54 2010 +0100 @@ -0,0 +1,34 @@ +# +# Copyright (c) 2010, 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. +# + +BUILDDIR = ../.. +PRODUCT = oracle +include $(BUILDDIR)/common/Defs.gmk + +SUBDIRS = net +include $(BUILDDIR)/common/Subdirs.gmk + +all build clean clobber:: + $(SUBDIRS-loop)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/make/com/oracle/net/Makefile Fri Sep 03 13:11:54 2010 +0100 @@ -0,0 +1,39 @@ +# +# Copyright (c) 2010, 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. +# + +BUILDDIR = ../../.. +PRODUCT = oracle +include $(BUILDDIR)/common/Defs.gmk + +# +# Files to compile +# +AUTO_FILES_JAVA_DIRS = com/oracle/net + +# +# Rules +# +include $(BUILDDIR)/common/Classes.gmk +
--- a/make/docs/NON_CORE_PKGS.gmk Wed Sep 01 17:37:45 2010 -0700 +++ b/make/docs/NON_CORE_PKGS.gmk Fri Sep 03 13:11:54 2010 +0100 @@ -91,6 +91,8 @@ TRACING_PKGS = com.sun.tracing \ com.sun.tracing.dtrace +ORACLENET_PKGS = com.oracle.net + # non-core packages in rt.jar NON_CORE_PKGS = $(DOMAPI_PKGS) \ $(MGMT_PKGS) \ @@ -101,5 +103,6 @@ $(HTTPSERVER_PKGS) \ $(SMARTCARDIO_PKGS) \ $(TRACING_PKGS) \ - $(SCTPAPI_PKGS) + $(SCTPAPI_PKGS) \ + $(ORACLENET_PKGS)
--- a/make/java/net/FILES_c.gmk Wed Sep 01 17:37:45 2010 -0700 +++ b/make/java/net/FILES_c.gmk Fri Sep 03 13:11:54 2010 +0100 @@ -39,10 +39,6 @@ ResolverConfigurationImpl.c \ DefaultProxySelector.c -ifeq ($(PLATFORM), solaris) - FILES_c += SdpProvider.c -endif - ifeq ($(PLATFORM), linux) FILES_c += linux_close.c endif
--- a/make/java/net/Makefile Wed Sep 01 17:37:45 2010 -0700 +++ b/make/java/net/Makefile Fri Sep 03 13:11:54 2010 +0100 @@ -44,6 +44,8 @@ endif FILES_c += NTLMAuthSequence.c FILES_c += NetworkInterface_winXP.c +else + FILES_c += SdpSupport.c endif FILES_export = \ @@ -84,7 +86,8 @@ # # Find platform specific native code # -vpath %.c $(PLATFORM_SRC)/native/sun/net/dns $(PLATFORM_SRC)/native/sun/net/www/protocol/http/ntlm $(PLATFORM_SRC)/native/sun/net/spi +vpath %.c $(PLATFORM_SRC)/native/sun/net/dns $(PLATFORM_SRC)/native/sun/net/www/protocol/http/ntlm \ + $(PLATFORM_SRC)/native/sun/net/sdp $(PLATFORM_SRC)/native/sun/net/spi # # Include rules
--- a/make/java/net/mapfile-vers Wed Sep 01 17:37:45 2010 -0700 +++ b/make/java/net/mapfile-vers Fri Sep 03 13:11:54 2010 +0100 @@ -88,9 +88,10 @@ Java_java_net_PlainDatagramSocketImpl_setTimeToLive; Java_sun_net_dns_ResolverConfigurationImpl_localDomain0; Java_sun_net_dns_ResolverConfigurationImpl_fallbackDomain0; + Java_sun_net_sdp_SdpSupport_convert0; + Java_sun_net_sdp_SdpSupport_create0; 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/make/java/nio/FILES_java.gmk Wed Sep 01 17:37:45 2010 -0700 +++ b/make/java/nio/FILES_java.gmk Fri Sep 03 13:11:54 2010 +0100 @@ -199,6 +199,7 @@ sun/nio/ch/PipeImpl.java \ sun/nio/ch/PollArrayWrapper.java \ sun/nio/ch/Reflect.java \ + sun/nio/ch/Secrets.java \ sun/nio/ch/SelectionKeyImpl.java \ sun/nio/ch/SelectorImpl.java \ sun/nio/ch/SelectorProviderImpl.java \
--- a/make/sun/net/FILES_java.gmk Wed Sep 01 17:37:45 2010 -0700 +++ b/make/sun/net/FILES_java.gmk Fri Sep 03 13:11:54 2010 +0100 @@ -53,6 +53,7 @@ sun/net/ftp/FtpProtocolException.java \ sun/net/ftp/impl/FtpClient.java \ sun/net/ftp/impl/DefaultFtpClientProvider.java \ + sun/net/sdp/SdpSupport.java \ sun/net/spi/DefaultProxySelector.java \ sun/net/spi/nameservice/NameServiceDescriptor.java \ sun/net/spi/nameservice/NameService.java \ @@ -136,8 +137,6 @@ ifeq ($(PLATFORM), windows) FILES_java += sun/net/www/protocol/http/ntlm/NTLMAuthSequence.java +else + FILES_java += sun/net/sdp/SdpProvider.java endif - -ifeq ($(PLATFORM), solaris) - FILES_java += sun/net/spi/SdpProvider.java -endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/oracle/net/Sdp.java Fri Sep 03 13:11:54 2010 +0100 @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2010, 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 com.oracle.net; + +import java.net.Socket; +import java.net.ServerSocket; +import java.net.SocketImpl; +import java.net.SocketImplFactory; +import java.net.SocketException; +import java.nio.channels.SocketChannel; +import java.nio.channels.ServerSocketChannel; +import java.io.IOException; +import java.io.FileDescriptor; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.lang.reflect.Constructor; +import java.lang.reflect.AccessibleObject; +import java.lang.reflect.InvocationTargetException; + +import sun.net.sdp.SdpSupport; + +/** + * This class consists exclusively of static methods that Sockets or Channels to + * sockets that support the InfiniBand Sockets Direct Protocol (SDP). + */ + +public final class Sdp { + private Sdp() { } + + /** + * The package-privage ServerSocket(SocketImpl) constructor + */ + private static final Constructor<ServerSocket> serverSocketCtor; + static { + try { + serverSocketCtor = (Constructor<ServerSocket>) + ServerSocket.class.getDeclaredConstructor(SocketImpl.class); + setAccessible(serverSocketCtor); + } catch (NoSuchMethodException e) { + throw new AssertionError(e); + } + } + + /** + * The package-private SdpSocketImpl() constructor + */ + private static final Constructor<SocketImpl> socketImplCtor; + static { + try { + Class<?> cl = Class.forName("java.net.SdpSocketImpl", true, null); + socketImplCtor = (Constructor<SocketImpl>)cl.getDeclaredConstructor(); + setAccessible(socketImplCtor); + } catch (ClassNotFoundException e) { + throw new AssertionError(e); + } catch (NoSuchMethodException e) { + throw new AssertionError(e); + } + } + + private static void setAccessible(final AccessibleObject o) { + AccessController.doPrivileged(new PrivilegedAction<Void>() { + public Void run() { + o.setAccessible(true); + return null; + } + }); + } + + /** + * SDP enabled Socket. + */ + private static class SdpSocket extends Socket { + SdpSocket(SocketImpl impl) throws SocketException { + super(impl); + } + } + + /** + * Creates a SDP enabled SocketImpl + */ + private static SocketImpl createSocketImpl() { + try { + return socketImplCtor.newInstance(); + } catch (InstantiationException x) { + throw new AssertionError(x); + } catch (IllegalAccessException x) { + throw new AssertionError(x); + } catch (InvocationTargetException x) { + throw new AssertionError(x); + } + } + + /** + * Creates an unconnected and unbound SDP socket. The {@code Socket} is + * associated with a {@link java.net.SocketImpl} of the system-default type. + * + * @return a new Socket + * + * @throws UnsupportedOperationException + * If SDP is not supported + * @throws IOException + * If an I/O error occurs + */ + public static Socket openSocket() throws IOException { + SocketImpl impl = createSocketImpl(); + return new SdpSocket(impl); + } + + /** + * Creates an unbound SDP server socket. The {@code ServerSocket} is + * associated with a {@link java.net.SocketImpl} of the system-default type. + * + * @return a new ServerSocket + * + * @throws UnsupportedOperationException + * If SDP is not supported + * @throws IOException + * If an I/O error occurs + */ + public static ServerSocket openServerSocket() throws IOException { + // create ServerSocket via package-private constructor + SocketImpl impl = createSocketImpl(); + try { + return serverSocketCtor.newInstance(impl); + } catch (IllegalAccessException x) { + throw new AssertionError(x); + } catch (InstantiationException x) { + throw new AssertionError(x); + } catch (InvocationTargetException x) { + Throwable cause = x.getCause(); + if (cause instanceof IOException) + throw (IOException)cause; + if (cause instanceof RuntimeException) + throw (RuntimeException)cause; + throw new RuntimeException(x); + } + } + + /** + * Opens a socket channel to a SDP socket. + * + * <p> The channel will be associated with the system-wide default + * {@link java.nio.channels.spi.SelectorProvider SelectorProvider}. + * + * @return a new SocketChannel + * + * @throws UnsupportedOperationException + * If SDP is not supported or not supported by the default selector + * provider + * @throws IOException + * If an I/O error occurs. + */ + public static SocketChannel openSocketChannel() throws IOException { + FileDescriptor fd = SdpSupport.createSocket(); + return sun.nio.ch.Secrets.newSocketChannel(fd); + } + + /** + * Opens a socket channel to a SDP socket. + * + * <p> The channel will be associated with the system-wide default + * {@link java.nio.channels.spi.SelectorProvider SelectorProvider}. + * + * @return a new ServerSocketChannel + * + * @throws UnsupportedOperationException + * If SDP is not supported or not supported by the default selector + * provider + * @throws IOException + * If an I/O error occurs + */ + public static ServerSocketChannel openServerSocketChannel() + throws IOException + { + FileDescriptor fd = SdpSupport.createSocket(); + return sun.nio.ch.Secrets.newServerSocketChannel(fd); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/java/net/SdpSocketImpl.java Fri Sep 03 13:11:54 2010 +0100 @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2010, 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 java.net; + +import java.io.IOException; +import java.io.FileDescriptor; + +import sun.net.sdp.SdpSupport; + +/** + * SocketImpl that supports the SDP protocol + */ +class SdpSocketImpl extends PlainSocketImpl { + SdpSocketImpl() { } + + @Override + protected void create(boolean stream) throws IOException { + if (!stream) + throw new UnsupportedOperationException("Must be a stream socket"); + fd = SdpSupport.createSocket(); + if (socket != null) + socket.setCreated(); + if (serverSocket != null) + serverSocket.setCreated(); + } +}
--- a/src/share/classes/java/net/ServerSocket.java Wed Sep 01 17:37:45 2010 -0700 +++ b/src/share/classes/java/net/ServerSocket.java Fri Sep 03 13:11:54 2010 +0100 @@ -69,6 +69,15 @@ private boolean oldImpl = false; /** + * Package-private constructor to create a ServerSocket associated with + * the given SocketImpl. + */ + ServerSocket(SocketImpl impl) { + this.impl = impl; + impl.setServerSocket(this); + } + + /** * Creates an unbound server socket. * * @exception IOException IO error when opening the socket.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/sun/net/sdp/SdpSupport.java Fri Sep 03 13:11:54 2010 +0100 @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2010, 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.sdp; + +import java.io.IOException; +import java.io.FileDescriptor; +import java.security.AccessController; + +import sun.misc.SharedSecrets; +import sun.misc.JavaIOFileDescriptorAccess; + + +/** + * This class defines methods for creating SDP sockets or "converting" existing + * file descriptors, referencing (unbound) TCP sockets, to SDP. + */ + +public final class SdpSupport { + private static final String os = AccessController + .doPrivileged(new sun.security.action.GetPropertyAction("os.name")); + private static final boolean isSupported = (os.equals("SunOS") || (os.equals("Linux"))); + private static final JavaIOFileDescriptorAccess fdAccess = + SharedSecrets.getJavaIOFileDescriptorAccess(); + + private SdpSupport() { } + + /** + * Creates a SDP socket, returning file descriptor referencing the socket. + */ + public static FileDescriptor createSocket() throws IOException { + if (!isSupported) + throw new UnsupportedOperationException("SDP not supported on this platform"); + int fdVal = create0(); + FileDescriptor fd = new FileDescriptor(); + fdAccess.set(fd, fdVal); + return fd; + } + + /** + * Converts an existing file descriptor, that references an unbound TCP socket, + * to SDP. + */ + public static void convertSocket(FileDescriptor fd) throws IOException { + if (!isSupported) + throw new UnsupportedOperationException("SDP not supported on this platform"); + int fdVal = fdAccess.get(fd); + convert0(fdVal); + } + + private static native int create0() throws IOException; + + private static native void convert0(int fd) throws IOException; + + static { + AccessController.doPrivileged( + new sun.security.action.LoadLibraryAction("net")); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/sun/nio/ch/Secrets.java Fri Sep 03 13:11:54 2010 +0100 @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2010, 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.nio.ch; + +import java.nio.channels.SocketChannel; +import java.nio.channels.ServerSocketChannel; +import java.nio.channels.spi.SelectorProvider; +import java.io.FileDescriptor; +import java.io.IOException; + +/** + * Provides access to implementation private constructors and methods. + */ + +public final class Secrets { + private Secrets() { } + + private static SelectorProvider provider() { + SelectorProvider p = SelectorProvider.provider(); + if (!(p instanceof SelectorProviderImpl)) + throw new UnsupportedOperationException(); + return p; + } + + public static SocketChannel newSocketChannel(FileDescriptor fd) { + try { + return new SocketChannelImpl(provider(), fd, false); + } catch (IOException ioe) { + throw new AssertionError(ioe); + } + } + + public static ServerSocketChannel newServerSocketChannel(FileDescriptor fd) { + try { + return new ServerSocketChannelImpl(provider(), fd, false); + } catch (IOException ioe) { + throw new AssertionError(ioe); + } + } +}
--- a/src/share/classes/sun/nio/ch/ServerSocketChannelImpl.java Wed Sep 01 17:37:45 2010 -0700 +++ b/src/share/classes/sun/nio/ch/ServerSocketChannelImpl.java Fri Sep 03 13:11:54 2010 +0100 @@ -80,21 +80,24 @@ // -- End of fields protected by stateLock - public ServerSocketChannelImpl(SelectorProvider sp) throws IOException { + ServerSocketChannelImpl(SelectorProvider sp) throws IOException { super(sp); this.fd = Net.serverSocket(true); this.fdVal = IOUtil.fdVal(fd); this.state = ST_INUSE; } - public ServerSocketChannelImpl(SelectorProvider sp, FileDescriptor fd) + ServerSocketChannelImpl(SelectorProvider sp, + FileDescriptor fd, + boolean bound) throws IOException { super(sp); this.fd = fd; this.fdVal = IOUtil.fdVal(fd); this.state = ST_INUSE; - localAddress = Net.localAddress(fd); + if (bound) + localAddress = Net.localAddress(fd); } public ServerSocket socket() {
--- a/src/share/classes/sun/nio/ch/SocketChannelImpl.java Wed Sep 01 17:37:45 2010 -0700 +++ b/src/share/classes/sun/nio/ch/SocketChannelImpl.java Fri Sep 03 13:11:54 2010 +0100 @@ -103,6 +103,19 @@ this.state = ST_UNCONNECTED; } + SocketChannelImpl(SelectorProvider sp, + FileDescriptor fd, + boolean bound) + throws IOException + { + super(sp); + this.fd = fd; + this.fdVal = IOUtil.fdVal(fd); + this.state = ST_UNCONNECTED; + if (bound) + this.localAddress = Net.localAddress(fd); + } + // Constructor for sockets obtained from server sockets // SocketChannelImpl(SelectorProvider sp,
--- a/src/solaris/classes/sun/net/NetHooks.java Wed Sep 01 17:37:45 2010 -0700 +++ b/src/solaris/classes/sun/net/NetHooks.java Fri Sep 03 13:11:54 2010 +0100 @@ -73,28 +73,7 @@ * 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) { - return null; - } - 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; + private static final Provider provider = new sun.net.sdp.SdpProvider(); /** * Invoke prior to binding a TCP socket. @@ -104,8 +83,7 @@ int port) throws IOException { - if (provider != null) - provider.implBeforeTcpBind(fdObj, address, port); + provider.implBeforeTcpBind(fdObj, address, port); } /** @@ -116,7 +94,6 @@ int port) throws IOException { - if (provider != null) - provider.implBeforeTcpConnect(fdObj, address, port); + provider.implBeforeTcpConnect(fdObj, address, port); } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/solaris/classes/sun/net/sdp/SdpProvider.java Fri Sep 03 13:11:54 2010 +0100 @@ -0,0 +1,335 @@ +/* + * Copyright (c) 2009, 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.sdp; + +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 java.security.AccessController; + +import sun.net.sdp.SdpSupport; +import sun.security.action.GetPropertyAction; + +/** + * A NetHooks provider that converts sockets from the TCP to SDP protocol prior + * to binding or connecting. + */ + +public class SdpProvider extends NetHooks.Provider { + // 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 = AccessController.doPrivileged( + new GetPropertyAction("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 = AccessController.doPrivileged( + new GetPropertyAction("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)) { + SdpSupport.convertSocket(fdObj); + 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); + } +}
--- a/src/solaris/classes/sun/net/spi/SdpProvider.java Wed Sep 01 17:37:45 2010 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,339 +0,0 @@ -/* - * Copyright (c) 2009, 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.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/src/solaris/classes/sun/nio/ch/InheritedChannel.java Wed Sep 01 17:37:45 2010 -0700 +++ b/src/solaris/classes/sun/nio/ch/InheritedChannel.java Fri Sep 03 13:11:54 2010 +0100 @@ -96,7 +96,7 @@ FileDescriptor fd) throws IOException { - super(sp, fd); + super(sp, fd, true); } protected void implCloseSelectableChannel() throws IOException {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/solaris/native/sun/net/sdp/SdpSupport.c Fri Sep 03 13:11:54 2010 +0100 @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2009, 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. + */ + +#include <sys/types.h> +#include <sys/socket.h> +#include <errno.h> + +#if defined(__solaris__) + #if !defined(PROTO_SDP) + #define PROTO_SDP 257 + #endif +#elif defined(__linux__) + #if !defined(AF_INET_SDP) + #define AF_INET_SDP 27 + #endif +#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) + + +/** + * Creates a SDP socket. + */ +static int create(JNIEnv* env) +{ + int s; + +#if defined(__solaris__) + #ifdef AF_INET6 + int domain = ipv6_available() ? AF_INET6 : AF_INET; + #else + int domain = AF_INET; + #endif + s = socket(domain, SOCK_STREAM, PROTO_SDP); +#elif defined(__linux__) + /** + * IPv6 not supported by SDP on Linux + */ + if (ipv6_available()) { + JNU_ThrowIOException(env, "IPv6 not supported"); + return; + } + s = socket(AF_INET_SDP, SOCK_STREAM, 0); +#else + /* not supported on other platforms at this time */ + s = -1; + errno = EPROTONOSUPPORT; +#endif + + if (s < 0) + JNU_ThrowIOExceptionWithLastError(env, "socket"); + return s; +} + +/** + * Creates a SDP socket, returning file descriptor referencing the socket. + */ +JNIEXPORT jint JNICALL +Java_sun_net_sdp_SdpSupport_create0(JNIEnv *env, jclass cls) +{ + return create(env); +} + +/** + * Converts an existing file descriptor, that references an unbound TCP socket, + * to SDP. + */ +JNIEXPORT void JNICALL +Java_sun_net_sdp_SdpSupport_convert0(JNIEnv *env, jclass cls, int fd) +{ + int s = create(env); + if (s >= 0) { + socklen_t len; + int arg, 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); + } +}
--- a/src/solaris/native/sun/net/spi/SdpProvider.c Wed Sep 01 17:37:45 2010 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2009, 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. - */ - -#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 -#ifdef AF_INET6 - int domain = ipv6_available() ? AF_INET6 : AF_INET; -#else - int domain = AF_INET; -#endif - 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 -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/com/oracle/net/Sanity.java Fri Sep 03 13:11:54 2010 +0100 @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2010, 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. + */ + +import com.oracle.net.Sdp; + +import java.net.*; +import java.io.*; +import java.nio.channels.*; +import java.util.*; + +/** + * Exercise com.oracle.net.Sdp with each IP address plumbed to InfiniBand + * interfaces listed in a given file. + */ + +public class Sanity { + public static void main(String[] args) throws Exception { + // The file is a list of interfaces to test. + Scanner s = new Scanner(new File(args[0])); + try { + while (s.hasNextLine()) { + String link = s.nextLine(); + NetworkInterface ni = NetworkInterface.getByName(link); + if (ni != null) { + Enumeration<InetAddress> addrs = ni.getInetAddresses(); + while (addrs.hasMoreElements()) { + InetAddress addr = addrs.nextElement(); + System.out.format("Testing %s: %s\n", link, addr.getHostAddress()); + test(addr); + } + } + } + } finally { + s.close(); + } + } + + static void test(InetAddress addr) throws Exception { + // Test SocketChannel and ServerSocketChannel + ServerSocketChannel ssc = Sdp.openServerSocketChannel(); + try { + ssc.socket().bind(new InetSocketAddress(addr, 0)); + int port = ssc.socket().getLocalPort(); + + // SocketChannel.connect (implicit bind) + SocketChannel client = Sdp.openSocketChannel(); + 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 = Sdp.openSocketChannel(); + try { + client.socket().bind(new InetSocketAddress(addr, 0)); + client.connect(new InetSocketAddress(addr, port)); + ssc.accept().close(); + } finally { + client.close(); + } + } finally { + ssc.close(); + } + + // Test Socket and ServerSocket + ServerSocket ss = Sdp.openServerSocket(); + try { + ss.bind(new InetSocketAddress(addr, 0)); + int port = ss.getLocalPort(); + + // Socket.connect (implicit bind) + Socket s = Sdp.openSocket(); + 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 = Sdp.openSocket(); + 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/test/com/oracle/net/sanity.sh Fri Sep 03 13:11:54 2010 +0100 @@ -0,0 +1,66 @@ +# +# Copyright (c) 2010, 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 6965072 +# @summary Unit test for SDP support +# @build Sanity +# @run shell sanity.sh + +IB_LINKS=ib.links + +OS=`uname -s` +case "$OS" in + SunOS ) + /usr/sbin/dladm show-part -o LINK -p > ${IB_LINKS} + if [ $? != 0 ]; then + echo "Unable to get InfiniBand parition link information" + exit 0 + fi + ;; + Linux ) + if [ ! -f /proc/net/sdp ]; then + echo "InfiniBand SDP module not installed" + exit 0 + fi + egrep "^[ \t]+ib" /proc/net/dev|cut -d':' -f1|tr -d '\t ' > ${IB_LINKS} + ;; + * ) + echo "This test only runs on Solaris or Linux" + exit 0 + ;; +esac + +if [ -z "$TESTJAVA" ]; then + JAVA=java + TESTCLASSES=. + TESTSRC=. +else + JAVA="${TESTJAVA}/bin/java" +fi + +CLASSPATH=${TESTCLASSES}:${TESTSRC} +export CLASSPATH + +# Run sanity test (IPv4-only for now) +$JAVA -Djava.net.preferIPv4Stack=true Sanity ${IB_LINKS}
--- a/test/sun/net/sdp/ProbeIB.java Wed Sep 01 17:37:45 2010 -0700 +++ b/test/sun/net/sdp/ProbeIB.java Fri Sep 03 13:11:54 2010 +0100 @@ -34,21 +34,16 @@ public class ProbeIB { public static void main(String[] args) throws IOException { - Scanner s = new Scanner(new File("/etc/path_to_inst")); + Scanner s = new Scanner(new File(args[0])); 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); + String link = s.nextLine(); + NetworkInterface ni = NetworkInterface.getByName(link); if (ni != null) { Enumeration<InetAddress> addrs = ni.getInetAddresses(); while (addrs.hasMoreElements()) { - System.out.println(addrs.nextElement().getHostAddress()); + InetAddress addr = addrs.nextElement(); + System.out.println(addr.getHostAddress()); } } }
--- a/test/sun/net/sdp/sanity.sh Wed Sep 01 17:37:45 2010 -0700 +++ b/test/sun/net/sdp/sanity.sh Fri Sep 03 13:11:54 2010 +0100 @@ -33,14 +33,15 @@ 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" + +IB_LINKS=ib.links +IB_ADDRS=ib.addrs + +# Display IB partition link information +# (requires Solaris 11, will fail on Solaris 10) +/usr/sbin/dladm show-part -o LINK -p > ${IB_LINKS} +if [ $? != 0 ]; then + echo "Unable to get IB parition link information" exit 0 fi @@ -56,13 +57,13 @@ export CLASSPATH # Probe for IP addresses plumbed to IB interfaces -$JAVA -Djava.net.preferIPv4Stack=true ProbeIB > ib_addrs +$JAVA -Djava.net.preferIPv4Stack=true ProbeIB ${IB_LINKS} > ${IB_ADDRS} # Create sdp.conf SDPCONF=sdp.conf rm ${SDPCONF} touch ${SDPCONF} -cat ib_addrs | while read ADDR +cat ${IB_ADDRS} | while read ADDR do echo "bind ${ADDR} *" > ${SDPCONF} echo "connect ${ADDR} *" >> ${SDPCONF}