Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/ikvm-fork.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjfrijters <jfrijters>2013-08-15 20:25:09 +0400
committerjfrijters <jfrijters>2013-08-15 20:25:09 +0400
commitfd37f3de153416df36c2e90727b8c16fc1d0c730 (patch)
tree095ca217c91ad86938a26cccf08f572208b8657d /openjdk/sun
parentf4419eda6439fb82d6f4266dfa069d32af5b0348 (diff)
Merged 7u40 changes in sun/nio/ch/Net.java and partially merged DatagramChannelImpl.java.
Diffstat (limited to 'openjdk/sun')
-rw-r--r--openjdk/sun/nio/ch/DatagramChannelImpl.java52
-rw-r--r--openjdk/sun/nio/ch/Net.java107
2 files changed, 140 insertions, 19 deletions
diff --git a/openjdk/sun/nio/ch/DatagramChannelImpl.java b/openjdk/sun/nio/ch/DatagramChannelImpl.java
index b2631530..08cc5c95 100644
--- a/openjdk/sun/nio/ch/DatagramChannelImpl.java
+++ b/openjdk/sun/nio/ch/DatagramChannelImpl.java
@@ -86,8 +86,8 @@ class DatagramChannelImpl
private int state = ST_UNINITIALIZED;
// Binding
- private SocketAddress localAddress;
- private SocketAddress remoteAddress;
+ private InetSocketAddress localAddress;
+ private InetSocketAddress remoteAddress;
// Our socket adaptor, if any
private DatagramSocket socket;
@@ -95,6 +95,12 @@ class DatagramChannelImpl
// Multicast support
private MembershipRegistry registry;
+ // set true when socket is bound and SO_REUSEADDRESS is emulated
+ private boolean reuseAddressEmulated;
+
+ // set true/false when socket is already bound and SO_REUSEADDR is emulated
+ private boolean isReuseAddress;
+
// -- End of fields protected by stateLock
@@ -163,7 +169,7 @@ class DatagramChannelImpl
synchronized (stateLock) {
if (!isOpen())
throw new ClosedChannelException();
- return localAddress;
+ return Net.getRevealedLocalAddress(localAddress);
}
}
@@ -223,6 +229,12 @@ class DatagramChannelImpl
}
return this;
}
+ if (name == StandardSocketOptions.SO_REUSEADDR &&
+ Net.useExclusiveBind() && localAddress != null)
+ {
+ reuseAddressEmulated = true;
+ this.isReuseAddress = (Boolean)value;
+ }
// remaining options don't need any special handling
Net.setSocketOption(fd, Net.UNSPEC, name, value);
@@ -281,6 +293,12 @@ class DatagramChannelImpl
}
}
+ if (name == StandardSocketOptions.SO_REUSEADDR &&
+ reuseAddressEmulated)
+ {
+ return (T)Boolean.valueOf(isReuseAddress);
+ }
+
// no special handling
return (T) Net.getSocketOption(fd, Net.UNSPEC, name);
}
@@ -416,7 +434,7 @@ class DatagramChannelImpl
synchronized (writeLock) {
ensureOpen();
- InetSocketAddress isa = (InetSocketAddress)target;
+ InetSocketAddress isa = Net.checkAddress(target);
InetAddress ia = isa.getAddress();
if (ia == null)
throw new IOException("Target address not resolved");
@@ -427,9 +445,9 @@ class DatagramChannelImpl
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
if (ia.isMulticastAddress()) {
- sm.checkMulticast(isa.getAddress());
+ sm.checkMulticast(ia);
} else {
- sm.checkConnect(isa.getAddress().getHostAddress(),
+ sm.checkConnect(ia.getHostAddress(),
isa.getPort());
}
}
@@ -449,7 +467,7 @@ class DatagramChannelImpl
return 0;
writerThread = NativeThread.current();
do {
- n = send(fd, src, target);
+ n = send(fd, src, isa);
} while ((n == IOStatus.INTERRUPTED) && isOpen());
synchronized (stateLock) {
@@ -466,7 +484,7 @@ class DatagramChannelImpl
}
}
- private int send(FileDescriptor fd, ByteBuffer src, SocketAddress target)
+ private int send(FileDescriptor fd, ByteBuffer src, InetSocketAddress target)
throws IOException
{
if (src.hasArray())
@@ -496,7 +514,7 @@ class DatagramChannelImpl
}
private int sendFromManagedBuffer(FileDescriptor fd, ByteBuffer bb,
- SocketAddress target)
+ InetSocketAddress target)
throws IOException
{
int pos = bb.position();
@@ -508,7 +526,7 @@ class DatagramChannelImpl
int written;
try {
written = send0(preferIPv6, fd, bb.array(), bb.arrayOffset() + pos,
- rem, target);
+ rem, target.getAddress(), target.getPort());
} catch (PortUnreachableException pue) {
if (isConnected())
throw pue;
@@ -700,6 +718,7 @@ class DatagramChannelImpl
}
}
+ @Override
public DatagramChannel connect(SocketAddress sa) throws IOException {
int localPort = 0;
@@ -721,7 +740,7 @@ class DatagramChannelImpl
// Connection succeeded; disallow further invocation
state = ST_CONNECTED;
- remoteAddress = sa;
+ remoteAddress = isa;
sender = isa;
cachedSenderInetAddress = isa.getAddress();
cachedSenderPort = isa.getPort();
@@ -740,12 +759,13 @@ class DatagramChannelImpl
synchronized (stateLock) {
if (!isConnected() || !isOpen())
return this;
- InetSocketAddress isa = (InetSocketAddress)remoteAddress;
+ InetSocketAddress isa = remoteAddress;
SecurityManager sm = System.getSecurityManager();
if (sm != null)
sm.checkConnect(isa.getAddress().getHostAddress(),
isa.getPort());
- disconnect0(fd);
+ boolean isIPv6 = (family == StandardProtocolFamily.INET6);
+ disconnect0(fd, isIPv6);
remoteAddress = null;
state = ST_UNCONNECTED;
@@ -1074,15 +1094,15 @@ class DatagramChannelImpl
private static native void initIDs();
- private static native void disconnect0(FileDescriptor fd)
+ private static native void disconnect0(FileDescriptor fd, boolean isIPv6)
throws IOException;
private native int receive0(FileDescriptor fd, byte[] buf, int pos, int len,
boolean connected)
throws IOException;
- private native int send0(boolean preferIPv6, FileDescriptor fd, byte[] buf, int pos, int len,
- SocketAddress sa)
+ private native int send0(boolean preferIPv6, FileDescriptor fd, byte[] buf, int pos,
+ int len, InetAddress addr, int port)
throws IOException;
static {
diff --git a/openjdk/sun/nio/ch/Net.java b/openjdk/sun/nio/ch/Net.java
index 71ae5436..d9ab0f0f 100644
--- a/openjdk/sun/nio/ch/Net.java
+++ b/openjdk/sun/nio/ch/Net.java
@@ -31,6 +31,7 @@ import java.nio.channels.*;
import java.util.*;
import java.security.AccessController;
import java.security.PrivilegedAction;
+import java.security.PrivilegedExceptionAction;
class Net { // package-private
@@ -44,6 +45,40 @@ class Net { // package-private
}
};
+ // Value of jdk.net.revealLocalAddress
+ private static boolean revealLocalAddress;
+
+ // True if jdk.net.revealLocalAddress had been read
+ private static volatile boolean propRevealLocalAddress;
+
+ // set to true if exclusive binding is on for Windows
+ private static final boolean exclusiveBind;
+
+ static {
+ int availLevel = isExclusiveBindAvailable();
+ if (availLevel >= 0) {
+ String exclBindProp =
+ java.security.AccessController.doPrivileged(
+ new PrivilegedAction<String>() {
+ @Override
+ public String run() {
+ return System.getProperty(
+ "sun.net.useExclusiveBind");
+ }
+ });
+ if (exclBindProp != null) {
+ exclusiveBind = exclBindProp.length() == 0 ?
+ true : Boolean.parseBoolean(exclBindProp);
+ } else if (availLevel == 1) {
+ exclusiveBind = true;
+ } else {
+ exclusiveBind = false;
+ }
+ } else {
+ exclusiveBind = false;
+ }
+ }
+
// -- Miscellaneous utilities --
private static volatile boolean checkedIPv6 = false;
@@ -61,6 +96,13 @@ class Net { // package-private
}
/**
+ * Returns true if exclusive binding is on
+ */
+ static boolean useExclusiveBind() {
+ return exclusiveBind;
+ }
+
+ /**
* Tells whether IPv6 sockets can join IPv4 multicast groups
*/
static boolean canIPv6SocketJoinIPv4Group() {
@@ -148,6 +190,58 @@ class Net { // package-private
}
/**
+ * Returns the local address after performing a SecurityManager#checkConnect.
+ */
+ static InetSocketAddress getRevealedLocalAddress(InetSocketAddress addr) {
+ SecurityManager sm = System.getSecurityManager();
+ if (addr == null || sm == null)
+ return addr;
+
+ if (!getRevealLocalAddress()) {
+ // Return loopback address only if security check fails
+ try{
+ sm.checkConnect(addr.getAddress().getHostAddress(), -1);
+ //Security check passed
+ } catch (SecurityException e) {
+ //Return loopback address
+ addr = getLoopbackAddress(addr.getPort());
+ }
+ }
+ return addr;
+ }
+
+ static String getRevealedLocalAddressAsString(InetSocketAddress addr) {
+ if (!getRevealLocalAddress() && System.getSecurityManager() != null)
+ addr = getLoopbackAddress(addr.getPort());
+ return addr.toString();
+ }
+
+ private static boolean getRevealLocalAddress() {
+ if (!propRevealLocalAddress) {
+ try {
+ revealLocalAddress = Boolean.parseBoolean(
+ AccessController.doPrivileged(
+ new PrivilegedExceptionAction<String>() {
+ public String run() {
+ return System.getProperty(
+ "jdk.net.revealLocalAddress");
+ }
+ }));
+
+ } catch (Exception e) {
+ // revealLocalAddress is false
+ }
+ propRevealLocalAddress = true;
+ }
+ return revealLocalAddress;
+ }
+
+ private static InetSocketAddress getLoopbackAddress(int port) {
+ return new InetSocketAddress(InetAddress.getLoopbackAddress(),
+ port);
+ }
+
+ /**
* Returns any IPv4 address of the given network interface, or
* null if the interface does not have any IPv4 addresses.
*/
@@ -308,6 +402,12 @@ class Net { // package-private
private static native boolean isIPv6Available0();
+ /*
+ * Returns 1 for Windows versions that support exclusive binding by default, 0
+ * for those that do not, and -1 for Solaris/Linux/Mac OS
+ */
+ private static native int isExclusiveBindAvailable();
+
private static native boolean canIPv6SocketJoinIPv4Group0();
private static native boolean canJoin6WithIPv4Group0();
@@ -341,11 +441,12 @@ class Net { // package-private
{
boolean preferIPv6 = isIPv6Available() &&
(family != StandardProtocolFamily.INET);
- bind0(preferIPv6, fd, addr, port);
+ bind0(fd, preferIPv6, exclusiveBind, addr, port);
}
- private static native void bind0(boolean preferIPv6, FileDescriptor fd,
- InetAddress addr, int port)
+ private static native void bind0(FileDescriptor fd, boolean preferIPv6,
+ boolean useExclBind, InetAddress addr,
+ int port)
throws IOException;
static native void listen(FileDescriptor fd, int backlog) throws IOException;