提交 66db0733 编写于 作者: A alanb

4890703: Support SDP (sol)

Reviewed-by: michaelm
上级 b905eaa5
...@@ -39,6 +39,10 @@ FILES_c = \ ...@@ -39,6 +39,10 @@ FILES_c = \
ResolverConfigurationImpl.c \ ResolverConfigurationImpl.c \
DefaultProxySelector.c DefaultProxySelector.c
ifeq ($(PLATFORM), solaris)
FILES_c += SdpProvider.c
endif
ifeq ($(PLATFORM), linux) ifeq ($(PLATFORM), linux)
FILES_c += linux_close.c FILES_c += linux_close.c
endif endif
......
...@@ -108,11 +108,24 @@ CLASSES.export += java.lang.Integer java.io.FileDescriptor java.net.InetAddressI ...@@ -108,11 +108,24 @@ CLASSES.export += java.lang.Integer java.io.FileDescriptor java.net.InetAddressI
# #
LOCALE_SET_DEFINITION = jre LOCALE_SET_DEFINITION = jre
properties: $(LIBDIR) $(LIBDIR)/net.properties MISC_FILES = $(LIBDIR) $(LIBDIR)/net.properties
$(LIBDIR)/net.properties: $(SHARE_SRC)/lib/net.properties $(LIBDIR)/net.properties: $(SHARE_SRC)/lib/net.properties
@$(RM) $@ @$(RM) $@
$(CP) $< $@ $(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)
...@@ -90,6 +90,7 @@ SUNWprivate_1.1 { ...@@ -90,6 +90,7 @@ SUNWprivate_1.1 {
Java_sun_net_dns_ResolverConfigurationImpl_fallbackDomain0; Java_sun_net_dns_ResolverConfigurationImpl_fallbackDomain0;
Java_sun_net_spi_DefaultProxySelector_init; Java_sun_net_spi_DefaultProxySelector_init;
Java_sun_net_spi_DefaultProxySelector_getSystemProxy; Java_sun_net_spi_DefaultProxySelector_getSystemProxy;
Java_sun_net_spi_SdpProvider_convert;
NET_AllocSockaddr; NET_AllocSockaddr;
NET_SockaddrToInetAddress; NET_SockaddrToInetAddress;
NET_SockaddrEqualsInetAddress; NET_SockaddrEqualsInetAddress;
......
...@@ -39,6 +39,7 @@ FILES_java = \ ...@@ -39,6 +39,7 @@ FILES_java = \
sun/net/TransferProtocolClient.java \ sun/net/TransferProtocolClient.java \
sun/net/ConnectionResetException.java \ sun/net/ConnectionResetException.java \
sun/net/NetProperties.java \ sun/net/NetProperties.java \
sun/net/NetHooks.java \
sun/net/util/IPAddressUtil.java \ sun/net/util/IPAddressUtil.java \
sun/net/dns/ResolverConfiguration.java \ sun/net/dns/ResolverConfiguration.java \
sun/net/dns/ResolverConfigurationImpl.java \ sun/net/dns/ResolverConfigurationImpl.java \
...@@ -123,3 +124,7 @@ FILES_java = \ ...@@ -123,3 +124,7 @@ FILES_java = \
ifeq ($(PLATFORM), windows) ifeq ($(PLATFORM), windows)
FILES_java += sun/net/www/protocol/http/NTLMAuthSequence.java FILES_java += sun/net/www/protocol/http/NTLMAuthSequence.java
endif endif
ifeq ($(PLATFORM), solaris)
FILES_java += sun/net/spi/SdpProvider.java
endif
...@@ -33,6 +33,7 @@ import java.io.FileDescriptor; ...@@ -33,6 +33,7 @@ import java.io.FileDescriptor;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import sun.net.ConnectionResetException; import sun.net.ConnectionResetException;
import sun.net.NetHooks;
/** /**
* Default Socket Implementation. This implementation does * Default Socket Implementation. This implementation does
...@@ -304,6 +305,11 @@ abstract class AbstractPlainSocketImpl extends SocketImpl ...@@ -304,6 +305,11 @@ abstract class AbstractPlainSocketImpl extends SocketImpl
*/ */
synchronized void doConnect(InetAddress address, int port, int timeout) throws IOException { 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 { try {
FileDescriptor fd = acquireFD(); FileDescriptor fd = acquireFD();
try { try {
...@@ -339,6 +345,11 @@ abstract class AbstractPlainSocketImpl extends SocketImpl ...@@ -339,6 +345,11 @@ abstract class AbstractPlainSocketImpl extends SocketImpl
protected synchronized void bind(InetAddress address, int lport) protected synchronized void bind(InetAddress address, int lport)
throws IOException throws IOException
{ {
synchronized (fdLock) {
if (!closePending && (socket == null || !socket.isBound())) {
NetHooks.beforeTcpBind(fd, address, lport);
}
}
socketBind(address, lport); socketBind(address, lport);
if (socket != null) if (socket != null)
socket.setBound(); socket.setBound();
......
...@@ -37,6 +37,7 @@ import java.util.HashSet; ...@@ -37,6 +37,7 @@ import java.util.HashSet;
import java.util.Collections; import java.util.Collections;
import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock;
import sun.net.NetHooks;
/** /**
* Base implementation of AsynchronousServerSocketChannel. * Base implementation of AsynchronousServerSocketChannel.
...@@ -131,6 +132,7 @@ abstract class AsynchronousServerSocketChannelImpl ...@@ -131,6 +132,7 @@ abstract class AsynchronousServerSocketChannelImpl
synchronized (stateLock) { synchronized (stateLock) {
if (localAddress != null) if (localAddress != null)
throw new AlreadyBoundException(); throw new AlreadyBoundException();
NetHooks.beforeTcpBind(fd, isa.getAddress(), isa.getPort());
Net.bind(fd, isa.getAddress(), isa.getPort()); Net.bind(fd, isa.getAddress(), isa.getPort());
Net.listen(fd, backlog < 1 ? 50 : backlog); Net.listen(fd, backlog < 1 ? 50 : backlog);
localAddress = Net.localAddress(fd); localAddress = Net.localAddress(fd);
......
...@@ -38,6 +38,7 @@ import java.util.HashSet; ...@@ -38,6 +38,7 @@ import java.util.HashSet;
import java.util.Collections; import java.util.Collections;
import java.util.concurrent.*; import java.util.concurrent.*;
import java.util.concurrent.locks.*; import java.util.concurrent.locks.*;
import sun.net.NetHooks;
/** /**
* Base implementation of AsynchronousSocketChannel * Base implementation of AsynchronousSocketChannel
...@@ -387,6 +388,7 @@ abstract class AsynchronousSocketChannelImpl ...@@ -387,6 +388,7 @@ abstract class AsynchronousSocketChannelImpl
throw new AlreadyBoundException(); throw new AlreadyBoundException();
InetSocketAddress isa = (local == null) ? InetSocketAddress isa = (local == null) ?
new InetSocketAddress(0) : Net.checkAddress(local); new InetSocketAddress(0) : Net.checkAddress(local);
NetHooks.beforeTcpBind(fd, isa.getAddress(), isa.getPort());
Net.bind(fd, isa.getAddress(), isa.getPort()); Net.bind(fd, isa.getAddress(), isa.getPort());
localAddress = Net.localAddress(fd); localAddress = Net.localAddress(fd);
} }
......
...@@ -31,6 +31,7 @@ import java.net.*; ...@@ -31,6 +31,7 @@ import java.net.*;
import java.nio.channels.*; import java.nio.channels.*;
import java.nio.channels.spi.*; import java.nio.channels.spi.*;
import java.util.*; import java.util.*;
import sun.net.NetHooks;
/** /**
...@@ -191,6 +192,7 @@ class ServerSocketChannelImpl ...@@ -191,6 +192,7 @@ class ServerSocketChannelImpl
SecurityManager sm = System.getSecurityManager(); SecurityManager sm = System.getSecurityManager();
if (sm != null) if (sm != null)
sm.checkListen(isa.getPort()); sm.checkListen(isa.getPort());
NetHooks.beforeTcpBind(fd, isa.getAddress(), isa.getPort());
Net.bind(fd, isa.getAddress(), isa.getPort()); Net.bind(fd, isa.getAddress(), isa.getPort());
Net.listen(fd, backlog < 1 ? 50 : backlog); Net.listen(fd, backlog < 1 ? 50 : backlog);
synchronized (stateLock) { synchronized (stateLock) {
......
...@@ -32,6 +32,7 @@ import java.nio.ByteBuffer; ...@@ -32,6 +32,7 @@ import java.nio.ByteBuffer;
import java.nio.channels.*; import java.nio.channels.*;
import java.nio.channels.spi.*; import java.nio.channels.spi.*;
import java.util.*; import java.util.*;
import sun.net.NetHooks;
/** /**
...@@ -526,6 +527,7 @@ class SocketChannelImpl ...@@ -526,6 +527,7 @@ class SocketChannelImpl
throw new AlreadyBoundException(); throw new AlreadyBoundException();
InetSocketAddress isa = (local == null) ? InetSocketAddress isa = (local == null) ?
new InetSocketAddress(0) : Net.checkAddress(local); new InetSocketAddress(0) : Net.checkAddress(local);
NetHooks.beforeTcpBind(fd, isa.getAddress(), isa.getPort());
Net.bind(fd, isa.getAddress(), isa.getPort()); Net.bind(fd, isa.getAddress(), isa.getPort());
localAddress = Net.localAddress(fd); localAddress = Net.localAddress(fd);
} }
...@@ -577,6 +579,12 @@ class SocketChannelImpl ...@@ -577,6 +579,12 @@ class SocketChannelImpl
if (!isOpen()) { if (!isOpen()) {
return false; return false;
} }
// notify hook only if unbound
if (localAddress == null) {
NetHooks.beforeTcpConnect(fd,
isa.getAddress(),
isa.getPort());
}
readerThread = NativeThread.current(); readerThread = NativeThread.current();
} }
for (;;) { for (;;) {
......
/*
* 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);
}
}
/*
* 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;
}
...@@ -32,6 +32,7 @@ import java.util.concurrent.*; ...@@ -32,6 +32,7 @@ import java.util.concurrent.*;
import java.io.IOException; import java.io.IOException;
import java.io.FileDescriptor; import java.io.FileDescriptor;
import java.security.AccessController; import java.security.AccessController;
import sun.net.NetHooks;
import sun.security.action.GetPropertyAction; import sun.security.action.GetPropertyAction;
/** /**
...@@ -305,6 +306,7 @@ class UnixAsynchronousSocketChannelImpl ...@@ -305,6 +306,7 @@ class UnixAsynchronousSocketChannelImpl
sm.checkConnect(isa.getAddress().getHostAddress(), isa.getPort()); sm.checkConnect(isa.getAddress().getHostAddress(), isa.getPort());
// check and set state // check and set state
boolean notifyBeforeTcpConnect;
synchronized (stateLock) { synchronized (stateLock) {
if (state == ST_CONNECTED) if (state == ST_CONNECTED)
throw new AlreadyConnectedException(); throw new AlreadyConnectedException();
...@@ -312,12 +314,16 @@ class UnixAsynchronousSocketChannelImpl ...@@ -312,12 +314,16 @@ class UnixAsynchronousSocketChannelImpl
throw new ConnectionPendingException(); throw new ConnectionPendingException();
state = ST_PENDING; state = ST_PENDING;
pendingRemote = remote; pendingRemote = remote;
notifyBeforeTcpConnect = (localAddress == null);
} }
AbstractFuture<Void,A> result = null; AbstractFuture<Void,A> result = null;
Throwable e = null; Throwable e = null;
try { try {
begin(); begin();
// notify hook if unbound
if (notifyBeforeTcpConnect)
NetHooks.beforeTcpConnect(fd, isa.getAddress(), isa.getPort());
int n = Net.connect(fd, isa.getAddress(), isa.getPort()); int n = Net.connect(fd, isa.getAddress(), isa.getPort());
if (n == IOStatus.UNAVAILABLE) { if (n == IOStatus.UNAVAILABLE) {
// connection could not be established immediately // connection could not be established immediately
......
#
# 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
/*
* 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
}
...@@ -231,6 +231,8 @@ Java_sun_nio_ch_FileChannelImpl_transferTo0(JNIEnv *env, jobject this, ...@@ -231,6 +231,8 @@ Java_sun_nio_ch_FileChannelImpl_transferTo0(JNIEnv *env, jobject this,
if (result < 0) { if (result < 0) {
if (errno == EAGAIN) if (errno == EAGAIN)
return IOS_UNAVAILABLE; return IOS_UNAVAILABLE;
if (errno == EOPNOTSUPP)
return IOS_UNSUPPORTED_CASE;
if ((errno == EINVAL) && ((ssize_t)count >= 0)) if ((errno == EINVAL) && ((ssize_t)count >= 0))
return IOS_UNSUPPORTED_CASE; return IOS_UNSUPPORTED_CASE;
if (errno == EINTR) if (errno == EINTR)
......
/*
* 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
}
}
/*
* 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();
}
}
}
/*
* 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;
}
}
}
#
# 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
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册