< prev index next >
src/java.base/windows/classes/java/net/DualStackPlainSocketImpl.java
Print this page
rev 49701 : [mq]: 8201510-Merge-TwoStacksPlainSocketImpl-into-DualStackPlainSocketImpl
@@ -24,58 +24,70 @@
*/
package java.net;
import java.io.IOException;
import java.io.FileDescriptor;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import sun.security.action.GetPropertyAction;
import jdk.internal.misc.SharedSecrets;
import jdk.internal.misc.JavaIOFileDescriptorAccess;
/**
- * This class defines the plain SocketImpl that is used on Windows platforms
- * greater or equal to Windows Vista. These platforms have a dual
- * layer TCP/IP stack and can handle both IPv4 and IPV6 through a
- * single file descriptor.
+ * This class defines the plain SocketImpl.
+ * When java.net.preferIPv4Stack system property is set to true, it uses
+ * IPv4-only socket.
+ * When java.net.preferIPv4Stack is set to false, it handles both IPv4
+ * and IPv6 through a single file descriptor.
*
* @author Chris Hegarty
*/
class DualStackPlainSocketImpl extends AbstractPlainSocketImpl {
private static final JavaIOFileDescriptorAccess fdAccess =
SharedSecrets.getJavaIOFileDescriptorAccess();
- // true if this socket is exclusively bound
- private final boolean exclusiveBind;
+ private static final boolean preferIPv4Stack =
+ Boolean.parseBoolean(AccessController.doPrivileged(
+ new GetPropertyAction("java.net.preferIPv4Stack", "false")));
+
+ private static final boolean useExclusiveBind =
+ Boolean.parseBoolean(AccessController.doPrivileged(
+ new GetPropertyAction("sun.net.useExclusiveBind", "true")));
- // emulates SO_REUSEADDR when exclusiveBind is true
+ // emulates SO_REUSEADDR when useExclusiveBind is true
private boolean isReuseAddress;
- public DualStackPlainSocketImpl(boolean exclBind) {
- exclusiveBind = exclBind;
+ public DualStackPlainSocketImpl() {
}
- public DualStackPlainSocketImpl(FileDescriptor fd, boolean exclBind) {
+ public DualStackPlainSocketImpl(FileDescriptor fd) {
this.fd = fd;
- exclusiveBind = exclBind;
}
+ @Override
void socketCreate(boolean stream) throws IOException {
if (fd == null)
throw new SocketException("Socket closed");
- int newfd = socket0(stream, false /*v6 Only*/);
+ int newfd = socket0(stream);
fdAccess.set(fd, newfd);
}
+ @Override
void socketConnect(InetAddress address, int port, int timeout)
throws IOException {
int nativefd = checkAndReturnNativeFD();
if (address == null)
throw new NullPointerException("inet address argument is null.");
+ if (preferIPv4Stack && !(address instanceof Inet4Address))
+ throw new SocketException("Protocol family not supported");
+
int connectResult;
if (timeout <= 0) {
connectResult = connect0(nativefd, address, port);
} else {
configureBlocking(nativefd, false);
@@ -95,32 +107,38 @@
*/
if (localport == 0)
localport = localPort0(nativefd);
}
+ @Override
void socketBind(InetAddress address, int port) throws IOException {
int nativefd = checkAndReturnNativeFD();
if (address == null)
throw new NullPointerException("inet address argument is null.");
- bind0(nativefd, address, port, exclusiveBind);
+ if (preferIPv4Stack && !(address instanceof Inet4Address))
+ throw new SocketException("Protocol family not supported");
+
+ bind0(nativefd, address, port, useExclusiveBind);
if (port == 0) {
localport = localPort0(nativefd);
} else {
localport = port;
}
this.address = address;
}
+ @Override
void socketListen(int backlog) throws IOException {
int nativefd = checkAndReturnNativeFD();
listen0(nativefd, backlog);
}
+ @Override
void socketAccept(SocketImpl s) throws IOException {
int nativefd = checkAndReturnNativeFD();
if (s == null)
throw new NullPointerException("socket is null");
@@ -146,17 +164,21 @@
/* Update socketImpls remote port, address and localport */
InetSocketAddress isa = isaa[0];
s.port = isa.getPort();
s.address = isa.getAddress();
s.localport = localport;
+ if (preferIPv4Stack && !(s.address instanceof Inet4Address))
+ throw new SocketException("Protocol family not supported");
}
+ @Override
int socketAvailable() throws IOException {
int nativefd = checkAndReturnNativeFD();
return available0(nativefd);
}
+ @Override
void socketClose0(boolean useDeferredClose/*unused*/) throws IOException {
if (fd == null)
throw new SocketException("Socket closed");
if (!fd.valid())
@@ -165,50 +187,61 @@
final int nativefd = fdAccess.get(fd);
fdAccess.set(fd, -1);
close0(nativefd);
}
+ @Override
void socketShutdown(int howto) throws IOException {
int nativefd = checkAndReturnNativeFD();
shutdown0(nativefd, howto);
}
// Intentional fallthrough after SO_REUSEADDR
@SuppressWarnings("fallthrough")
+ @Override
void socketSetOption(int opt, boolean on, Object value)
throws SocketException {
- int nativefd = checkAndReturnNativeFD();
- if (opt == SO_TIMEOUT) { // timeout implemented through select.
- return;
- }
// SO_REUSEPORT is not supported on Windows.
if (opt == SO_REUSEPORT) {
throw new UnsupportedOperationException("unsupported option");
}
+ int nativefd = checkAndReturnNativeFD();
+
+ if (opt == SO_TIMEOUT) {
+ if (preferIPv4Stack) {
+ // Don't enable the socket option on ServerSocket as it's
+ // meaningless (we don't receive on a ServerSocket).
+ if (serverSocket == null) {
+ setSoTimeout0(nativefd, ((Integer)value).intValue());
+ }
+ } // else timeout is implemented through select.
+ return;
+ }
+
int optionValue = 0;
switch(opt) {
- case SO_REUSEADDR :
- if (exclusiveBind) {
+ case SO_REUSEADDR:
+ if (useExclusiveBind) {
// SO_REUSEADDR emulated when using exclusive bind
isReuseAddress = on;
return;
}
// intentional fallthrough
- case TCP_NODELAY :
- case SO_OOBINLINE :
- case SO_KEEPALIVE :
+ case TCP_NODELAY:
+ case SO_OOBINLINE:
+ case SO_KEEPALIVE:
optionValue = on ? 1 : 0;
break;
- case SO_SNDBUF :
- case SO_RCVBUF :
- case IP_TOS :
+ case SO_SNDBUF:
+ case SO_RCVBUF:
+ case IP_TOS:
optionValue = ((Integer)value).intValue();
break;
- case SO_LINGER :
+ case SO_LINGER:
if (on) {
optionValue = ((Integer)value).intValue();
} else {
optionValue = -1;
}
@@ -218,39 +251,44 @@
}
setIntOption(nativefd, opt, optionValue);
}
- int socketGetOption(int opt, Object iaContainerObj) throws SocketException {
+ @Override
+ int socketGetOption(int opt, Object iaContainerObj)
+ throws SocketException {
+
+ // SO_REUSEPORT is not supported on Windows.
+ if (opt == SO_REUSEPORT) {
+ throw new UnsupportedOperationException("unsupported option");
+ }
+
int nativefd = checkAndReturnNativeFD();
// SO_BINDADDR is not a socket option.
if (opt == SO_BINDADDR) {
localAddress(nativefd, (InetAddressContainer)iaContainerObj);
return 0; // return value doesn't matter.
}
- // SO_REUSEPORT is not supported on Windows.
- if (opt == SO_REUSEPORT) {
- throw new UnsupportedOperationException("unsupported option");
- }
// SO_REUSEADDR emulated when using exclusive bind
- if (opt == SO_REUSEADDR && exclusiveBind)
- return isReuseAddress? 1 : -1;
+ if (opt == SO_REUSEADDR && useExclusiveBind)
+ return isReuseAddress ? 1 : -1;
int value = getIntOption(nativefd, opt);
switch (opt) {
- case TCP_NODELAY :
- case SO_OOBINLINE :
- case SO_KEEPALIVE :
- case SO_REUSEADDR :
+ case TCP_NODELAY:
+ case SO_OOBINLINE:
+ case SO_KEEPALIVE:
+ case SO_REUSEADDR:
return (value == 0) ? -1 : 1;
}
return value;
}
+ @Override
void socketSendUrgentData(int data) throws IOException {
int nativefd = checkAndReturnNativeFD();
sendOOB(nativefd, data);
}
@@ -269,11 +307,11 @@
/* Native methods */
static native void initIDs();
- static native int socket0(boolean stream, boolean v6Only) throws IOException;
+ static native int socket0(boolean stream) throws IOException;
static native void bind0(int fd, InetAddress localAddress, int localport,
boolean exclBind)
throws IOException;
@@ -298,10 +336,12 @@
static native void shutdown0(int fd, int howto) throws IOException;
static native void setIntOption(int fd, int cmd, int optionValue) throws SocketException;
+ static native void setSoTimeout0(int fd, int timeout) throws SocketException;
+
static native int getIntOption(int fd, int cmd) throws SocketException;
static native void sendOOB(int fd, int data) throws IOException;
static native void configureBlocking(int fd, boolean blocking) throws IOException;
< prev index next >