diff --git a/openjdk/allsources.lst b/openjdk/allsources.lst index 4a88c5d1..640f009b 100644 --- a/openjdk/allsources.lst +++ b/openjdk/allsources.lst @@ -102,6 +102,10 @@ java/lang/System.java java/lang/Thread.java java/lang/ThrowableHelper.java java/lang/VMSystemProperties.java +java/net/DualStackPlainDatagramSocketImpl.java +java/net/DualStackPlainDatagramSocketImpl_c.java +java/net/DualStackPlainSocketImpl.java +java/net/DualStackPlainSocketImpl_c.java java/net/net_util_md.java java/net/SocketInputStream.java java/net/SocketOutputStream.java diff --git a/openjdk/ikvm/internal/Winsock.java b/openjdk/ikvm/internal/Winsock.java index c072d94f..86cbb852 100644 --- a/openjdk/ikvm/internal/Winsock.java +++ b/openjdk/ikvm/internal/Winsock.java @@ -1,5 +1,5 @@ /* - Copyright (C) 2010 Jeroen Frijters + Copyright (C) 2010-2011 Jeroen Frijters This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -136,6 +136,7 @@ public final class Winsock public static final int IPV6_MULTICAST_HOPS = SocketOptionName.MulticastTimeToLive; public static final int IPV6_ADD_MEMBERSHIP = SocketOptionName.AddMembership; public static final int IPV6_DROP_MEMBERSHIP = SocketOptionName.DropMembership; + public static final int IPV6_V6ONLY = 27; public static final int SIO_UDP_CONNRESET = 0x9800000C; @@ -417,6 +418,10 @@ public final class Winsock ep = new IPEndPoint(cli.System.Net.IPAddress.IPv6Any, 0); } } + else + { + ep = v4mapped(socket, ep); + } if (socket.get_SocketType().Value == SocketType.Dgram) { // NOTE we use async connect to work around the issue that the .NET Socket class disallows sync Connect after the socket has received WSAECONNRESET @@ -440,6 +445,31 @@ public final class Winsock } } + private static IPEndPoint v4mapped(cli.System.Net.Sockets.Socket socket, IPEndPoint ep) + { + // when binding an IPv6 socket to an IPv4 address, we need to use a mapped v4 address + if (socket.get_AddressFamily().Value == AF_INET6 && ep.get_AddressFamily().Value == AF_INET) + { + byte[] v4 = ep.get_Address().GetAddressBytes(); + if (v4[0] == 0 && v4[1] == 0 && v4[2] == 0 && v4[3] == 0) + { + return new IPEndPoint(IPAddress.IPv6Any, ep.get_Port()); + } + else + { + byte[] v6 = new byte[16]; + v6[10] = -1; + v6[11] = -1; + v6[12] = v4[0]; + v6[13] = v4[1]; + v6[14] = v4[2]; + v6[15] = v4[3]; + return new IPEndPoint(new IPAddress(v6), ep.get_Port()); + } + } + return ep; + } + public static int bind(cli.System.Net.Sockets.Socket socket, IIPEndPointWrapper ep) { if (socket == null) @@ -451,7 +481,7 @@ public final class Winsock { if (false) throw new cli.System.Net.Sockets.SocketException(); if (false) throw new cli.System.ObjectDisposedException(""); - socket.Bind(ep.get()); + socket.Bind(v4mapped(socket, ep.get())); return 0; } catch (cli.System.Net.Sockets.SocketException x) @@ -715,7 +745,7 @@ public final class Winsock } else { - return socket.SendTo(buf, off, len, SocketFlags.wrap(flags), to.get()); + return socket.SendTo(buf, off, len, SocketFlags.wrap(flags), v4mapped(socket, to.get())); } } catch (cli.System.ArgumentException _) diff --git a/openjdk/java/io/FileDescriptor.java b/openjdk/java/io/FileDescriptor.java index b446f2a8..5ffb5151 100644 --- a/openjdk/java/io/FileDescriptor.java +++ b/openjdk/java/io/FileDescriptor.java @@ -168,7 +168,7 @@ public final class FileDescriptor { * {@code false} otherwise. */ public boolean valid() { - return stream != null; + return stream != null || socket != null; } /** diff --git a/openjdk/java/net/DualStackPlainDatagramSocketImpl.java b/openjdk/java/net/DualStackPlainDatagramSocketImpl.java index 7533dea1..dddc50cc 100644 --- a/openjdk/java/net/DualStackPlainDatagramSocketImpl.java +++ b/openjdk/java/net/DualStackPlainDatagramSocketImpl.java @@ -25,9 +25,6 @@ package java.net; import java.io.IOException; -import java.io.FileDescriptor; -import sun.misc.SharedSecrets; -import sun.misc.JavaIOFileDescriptorAccess; /** * This class defines the plain DatagramSocketImpl that is used on @@ -44,20 +41,19 @@ import sun.misc.JavaIOFileDescriptorAccess; class DualStackPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl { - static JavaIOFileDescriptorAccess fdAccess = SharedSecrets.getJavaIOFileDescriptorAccess(); protected void datagramSocketCreate() throws SocketException { if (fd == null) throw new SocketException("Socket closed"); - int newfd = socketCreate(false /* v6Only */); + cli.System.Net.Sockets.Socket newfd = socketCreate(false /* v6Only */); - fdAccess.set(fd, newfd); + fd.setSocket(newfd); } protected synchronized void bind0(int lport, InetAddress laddr) throws SocketException { - int nativefd = checkAndReturnNativeFD(); + cli.System.Net.Sockets.Socket nativefd = checkAndReturnNativeFD(); if (laddr == null) throw new NullPointerException("argument address"); @@ -71,7 +67,7 @@ class DualStackPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl } protected synchronized int peek(InetAddress address) throws IOException { - int nativefd = checkAndReturnNativeFD(); + cli.System.Net.Sockets.Socket nativefd = checkAndReturnNativeFD(); if (address == null) throw new NullPointerException("Null address in peek()"); @@ -84,7 +80,7 @@ class DualStackPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl } protected synchronized int peekData(DatagramPacket p) throws IOException { - int nativefd = checkAndReturnNativeFD(); + cli.System.Net.Sockets.Socket nativefd = checkAndReturnNativeFD(); if (p == null) throw new NullPointerException("packet"); @@ -95,7 +91,7 @@ class DualStackPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl } protected synchronized void receive0(DatagramPacket p) throws IOException { - int nativefd = checkAndReturnNativeFD(); + cli.System.Net.Sockets.Socket nativefd = checkAndReturnNativeFD(); if (p == null) throw new NullPointerException("packet"); @@ -106,7 +102,7 @@ class DualStackPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl } protected void send(DatagramPacket p) throws IOException { - int nativefd = checkAndReturnNativeFD(); + cli.System.Net.Sockets.Socket nativefd = checkAndReturnNativeFD(); if (p == null) throw new NullPointerException("null packet"); @@ -119,7 +115,7 @@ class DualStackPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl } protected void connect0(InetAddress address, int port) throws SocketException { - int nativefd = checkAndReturnNativeFD(); + cli.System.Net.Sockets.Socket nativefd = checkAndReturnNativeFD(); if (address == null) throw new NullPointerException("address"); @@ -131,19 +127,19 @@ class DualStackPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl if (fd == null || !fd.valid()) return; // disconnect doesn't throw any exceptions - socketDisconnect(fdAccess.get(fd)); + socketDisconnect(fd.getSocket()); } protected void datagramSocketClose() { if (fd == null || !fd.valid()) return; // close doesn't throw any exceptions - socketClose(fdAccess.get(fd)); - fdAccess.set(fd, -1); + socketClose(fd.getSocket()); + fd.setSocket(null); } protected void socketSetOption(int opt, Object val) throws SocketException { - int nativefd = checkAndReturnNativeFD(); + cli.System.Net.Sockets.Socket nativefd = checkAndReturnNativeFD(); int optionValue = 0; @@ -165,7 +161,7 @@ class DualStackPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl } protected Object socketGetOption(int opt) throws SocketException { - int nativefd = checkAndReturnNativeFD(); + cli.System.Net.Sockets.Socket nativefd = checkAndReturnNativeFD(); // SO_BINDADDR is not a socket option. if (opt == SO_BINDADDR) { @@ -225,41 +221,88 @@ class DualStackPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl } /* END Multicast specific methods */ - private int checkAndReturnNativeFD() throws SocketException { + private cli.System.Net.Sockets.Socket checkAndReturnNativeFD() throws SocketException { if (fd == null || !fd.valid()) throw new SocketException("Socket closed"); - return fdAccess.get(fd); + return fd.getSocket(); } /* Native methods */ - private static native void initIDs(); + private static cli.System.Net.Sockets.Socket socketCreate(boolean v6Only) { + ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv(); + cli.System.Net.Sockets.Socket ret = DualStackPlainDatagramSocketImpl_c.socketCreate(env, v6Only); + env.ThrowPendingException(); + return ret; + } - private static native int socketCreate(boolean v6Only); + private static void socketBind(cli.System.Net.Sockets.Socket fd, InetAddress localAddress, int localport) + throws SocketException { + ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv(); + DualStackPlainDatagramSocketImpl_c.socketBind(env, fd, localAddress, localport); + env.ThrowPendingException(); + } - private static native void socketBind(int fd, InetAddress localAddress, int localport) - throws SocketException; + private static void socketConnect(cli.System.Net.Sockets.Socket fd, InetAddress address, int port) + throws SocketException { + ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv(); + DualStackPlainDatagramSocketImpl_c.socketConnect(env, fd, address, port); + env.ThrowPendingException(); + } - private static native void socketConnect(int fd, InetAddress address, int port) - throws SocketException; + private static void socketDisconnect(cli.System.Net.Sockets.Socket fd) { + ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv(); + DualStackPlainDatagramSocketImpl_c.socketDisconnect(env, fd); + env.ThrowPendingException(); + } - private static native void socketDisconnect(int fd); + private static void socketClose(cli.System.Net.Sockets.Socket fd) { + ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv(); + DualStackPlainDatagramSocketImpl_c.socketClose(env, fd); + env.ThrowPendingException(); + } - private static native void socketClose(int fd); + private static int socketLocalPort(cli.System.Net.Sockets.Socket fd) throws SocketException { + ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv(); + int ret = DualStackPlainDatagramSocketImpl_c.socketLocalPort(env, fd); + env.ThrowPendingException(); + return ret; + } - private static native int socketLocalPort(int fd) throws SocketException; + private static Object socketLocalAddress(cli.System.Net.Sockets.Socket fd) throws SocketException { + ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv(); + Object ret = DualStackPlainDatagramSocketImpl_c.socketLocalAddress(env, fd); + env.ThrowPendingException(); + return ret; + } - private static native Object socketLocalAddress(int fd) throws SocketException; + private static int socketReceiveOrPeekData(cli.System.Net.Sockets.Socket fd, DatagramPacket packet, + int timeout, boolean connected, boolean peek) throws IOException { + ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv(); + int ret = DualStackPlainDatagramSocketImpl_c.socketReceiveOrPeekData(env, fd, packet, timeout, connected, peek); + env.ThrowPendingException(); + return ret; + } - private static native int socketReceiveOrPeekData(int fd, DatagramPacket packet, - int timeout, boolean connected, boolean peek) throws IOException; + private static void socketSend(cli.System.Net.Sockets.Socket fd, byte[] data, int offset, int length, + InetAddress address, int port, boolean connected) throws IOException { + ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv(); + DualStackPlainDatagramSocketImpl_c.socketSend(env, fd, data, offset, length, address, port, connected); + env.ThrowPendingException(); + } - private static native void socketSend(int fd, byte[] data, int offset, int length, - InetAddress address, int port, boolean connected) throws IOException; + private static void socketSetIntOption(cli.System.Net.Sockets.Socket fd, int cmd, + int optionValue) throws SocketException { + ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv(); + DualStackPlainDatagramSocketImpl_c.socketSetIntOption(env, fd, cmd, optionValue); + env.ThrowPendingException(); + } - private static native void socketSetIntOption(int fd, int cmd, - int optionValue) throws SocketException; - - private static native int socketGetIntOption(int fd, int cmd) throws SocketException; + private static int socketGetIntOption(cli.System.Net.Sockets.Socket fd, int cmd) throws SocketException { + ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv(); + int ret = DualStackPlainDatagramSocketImpl_c.socketGetIntOption(env, fd, cmd); + env.ThrowPendingException(); + return ret; + } } diff --git a/openjdk/java/net/DualStackPlainDatagramSocketImpl_c.java b/openjdk/java/net/DualStackPlainDatagramSocketImpl_c.java index 6521e1e5..5abb1109 100644 --- a/openjdk/java/net/DualStackPlainDatagramSocketImpl_c.java +++ b/openjdk/java/net/DualStackPlainDatagramSocketImpl_c.java @@ -22,6 +22,22 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ +package java.net; + +import java.io.FileDescriptor; +import static ikvm.internal.JNI.*; +import static ikvm.internal.Winsock.*; +import static java.net.net_util_md.*; + +final class DualStackPlainDatagramSocketImpl_c +{ +static final int TRUE = 1; +static final int FALSE = 0; + +static final int JVM_IO_ERR = -1; +static final int JVM_IO_INTR = -2; + +/* #include #include #include "jni.h" @@ -35,27 +51,26 @@ * behaviour whereby receiving a "connection reset" status resets the * socket. */ -static jboolean purgeOutstandingICMP(JNIEnv *env, jint fd) +static boolean purgeOutstandingICMP(JNIEnv env, cli.System.Net.Sockets.Socket fd) { - jboolean got_icmp = JNI_FALSE; - char buf[1]; - fd_set tbl; - struct timeval t = { 0, 0 }; - struct sockaddr_in rmtaddr; - int addrlen = sizeof(rmtaddr); + boolean got_icmp = false; + byte[] buf = new byte[1]; + fd_set tbl = new fd_set(); + timeval t = new timeval(); + SOCKETADDRESS rmtaddr = null; /* * Peek at the queue to see if there is an ICMP port unreachable. If there * is then receive it. */ - FD_ZERO(&tbl); - FD_SET(fd, &tbl); - while(1) { - if (select(/*ignored*/fd+1, &tbl, 0, 0, &t) <= 0) { + FD_ZERO(tbl); + FD_SET(fd, tbl); + while(true) { + if (select(tbl, null, null, t) <= 0) { break; } if (recvfrom(fd, buf, 1, MSG_PEEK, - (struct sockaddr *)&rmtaddr, &addrlen) != JVM_IO_ERR) { + rmtaddr) != JVM_IO_ERR) { break; } if (WSAGetLastError() != WSAECONNRESET) { @@ -63,7 +78,7 @@ static jboolean purgeOutstandingICMP(JNIEnv *env, jint fd) break; } - recvfrom(fd, buf, 1, 0, (struct sockaddr *)&rmtaddr, &addrlen); + recvfrom(fd, buf, 1, 0, rmtaddr); got_icmp = JNI_TRUE; } @@ -75,25 +90,25 @@ static jboolean purgeOutstandingICMP(JNIEnv *env, jint fd) * Method: socketCreate * Signature: (Z)I */ -JNIEXPORT jint JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketCreate - (JNIEnv *env, jclass clazz, jboolean v6Only /*unused*/) { - int fd, rv, opt=0, t=TRUE; - DWORD x1, x2; /* ignored result codes */ +static cli.System.Net.Sockets.Socket socketCreate + (JNIEnv env, boolean v6Only /*unused*/) { + cli.System.Net.Sockets.Socket fd; + int rv, opt=0, t=TRUE; - fd = (int) socket(AF_INET6, SOCK_DGRAM, 0); + fd = socket(AF_INET6, SOCK_DGRAM, 0); if (fd == INVALID_SOCKET) { NET_ThrowNew(env, WSAGetLastError(), "Socket creation failed"); - return -1; + return null; } - rv = setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &opt, sizeof(opt)); + rv = setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, opt); if (rv == SOCKET_ERROR) { NET_ThrowNew(env, WSAGetLastError(), "Socket creation failed"); - return -1; + return null; } - SetHandleInformation((HANDLE)(UINT_PTR)fd, HANDLE_FLAG_INHERIT, FALSE); - NET_SetSockOpt(fd, SOL_SOCKET, SO_BROADCAST, (char*)&t, sizeof(BOOL)); + //SetHandleInformation((HANDLE)(UINT_PTR)fd, HANDLE_FLAG_INHERIT, FALSE); + NET_SetSockOpt(fd, SOL_SOCKET, SO_BROADCAST, t); /* SIO_UDP_CONNRESET fixes a "bug" introduced in Windows 2000, which * returns connection reset errors on unconnected UDP sockets (as well @@ -101,7 +116,7 @@ JNIEXPORT jint JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketCrea * when the socket is connected. */ t = FALSE; - WSAIoctl(fd ,SIO_UDP_CONNRESET ,&t ,sizeof(t) ,&x1 ,sizeof(x1) ,&x2 ,0 ,0); + WSAIoctl(fd ,SIO_UDP_CONNRESET ,false); return fd; } @@ -111,18 +126,18 @@ JNIEXPORT jint JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketCrea * Method: socketBind * Signature: (ILjava/net/InetAddress;I)V */ -JNIEXPORT void JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketBind - (JNIEnv *env, jclass clazz, jint fd, jobject iaObj, jint port) { +static void socketBind + (JNIEnv env, cli.System.Net.Sockets.Socket fd, InetAddress iaObj, int port) { SOCKETADDRESS sa; + sa = new SOCKETADDRESS(); int rv; - int sa_len = sizeof(sa); - if (NET_InetAddressToSockaddr(env, iaObj, port, (struct sockaddr *)&sa, - &sa_len, JNI_TRUE) != 0) { + if (NET_InetAddressToSockaddr(env, iaObj, port, sa, + JNI_TRUE) != 0) { return; } - rv = bind(fd, (struct sockaddr *)&sa, sa_len); + rv = bind(fd, sa); if (rv == SOCKET_ERROR) { if (WSAGetLastError() == WSAEACCES) { @@ -137,27 +152,26 @@ JNIEXPORT void JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketBind * Method: socketConnect * Signature: (ILjava/net/InetAddress;I)V */ -JNIEXPORT void JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketConnect - (JNIEnv *env, jclass clazz, jint fd, jobject iaObj, jint port) { +static void socketConnect + (JNIEnv env, cli.System.Net.Sockets.Socket fd, InetAddress iaObj, int port) { SOCKETADDRESS sa; + sa = new SOCKETADDRESS(); int rv; - int sa_len = sizeof(sa); - DWORD x1, x2; /* ignored result codes */ int t = TRUE; - if (NET_InetAddressToSockaddr(env, iaObj, port, (struct sockaddr *)&sa, - &sa_len, JNI_TRUE) != 0) { + if (NET_InetAddressToSockaddr(env, iaObj, port, sa, + JNI_TRUE) != 0) { return; } - rv = connect(fd, (struct sockaddr *)&sa, sa_len); + rv = connect(fd, sa); if (rv == SOCKET_ERROR) { NET_ThrowNew(env, WSAGetLastError(), "connect"); return; } /* see comment in socketCreate */ - WSAIoctl(fd, SIO_UDP_CONNRESET, &t, sizeof(t), &x1, sizeof(x1), &x2, 0, 0); + WSAIoctl(fd, SIO_UDP_CONNRESET, true); } /* @@ -165,18 +179,15 @@ JNIEXPORT void JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketConn * Method: socketDisconnect * Signature: (I)V */ -JNIEXPORT void JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketDisconnect - (JNIEnv *env, jclass clazz, jint fd ) { +static void socketDisconnect + (JNIEnv env, cli.System.Net.Sockets.Socket fd ) { SOCKETADDRESS sa; - int sa_len = sizeof(sa); - DWORD x1, x2; /* ignored result codes */ - int t = FALSE; + sa = new SOCKETADDRESS(); - memset(&sa, 0, sa_len); - connect(fd, (struct sockaddr *)&sa, sa_len); + connect(fd, sa); /* see comment in socketCreate */ - WSAIoctl(fd, SIO_UDP_CONNRESET, &t, sizeof(t), &x1, sizeof(x1), &x2, 0, 0); + WSAIoctl(fd, SIO_UDP_CONNRESET, false); } /* @@ -184,8 +195,8 @@ JNIEXPORT void JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketDisc * Method: socketClose * Signature: (I)V */ -JNIEXPORT void JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketClose - (JNIEnv *env, jclass clazz , jint fd) { +static void socketClose + (JNIEnv env, cli.System.Net.Sockets.Socket fd) { NET_SocketClose(fd); } @@ -195,16 +206,16 @@ JNIEXPORT void JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketClos * Method: socketLocalPort * Signature: (I)I */ -JNIEXPORT jint JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketLocalPort - (JNIEnv *env, jclass clazz, jint fd) { +static int socketLocalPort + (JNIEnv env, cli.System.Net.Sockets.Socket fd) { SOCKETADDRESS sa; - int len = sizeof(sa); + sa = new SOCKETADDRESS(); - if (getsockname(fd, (struct sockaddr *)&sa, &len) == SOCKET_ERROR) { + if (getsockname(fd, sa) == SOCKET_ERROR) { NET_ThrowNew(env, WSAGetLastError(), "JVM_GetSockName"); return -1; } - return (int) ntohs((u_short)GET_PORT(&sa)); + return ntohs(GET_PORT(sa)); } /* @@ -212,19 +223,19 @@ JNIEXPORT jint JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketLoca * Method: socketLocalAddress * Signature: (I)Ljava/lang/Object; */ -JNIEXPORT jobject JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketLocalAddress - (JNIEnv *env , jclass clazz, jint fd) { +static InetAddress socketLocalAddress + (JNIEnv env , cli.System.Net.Sockets.Socket fd) { SOCKETADDRESS sa; - int len = sizeof(sa); - jobject iaObj; - int port; + sa = new SOCKETADDRESS(); + InetAddress iaObj; + int[] port = { 0 }; - if (getsockname(fd, (struct sockaddr *)&sa, &len) == SOCKET_ERROR) { + if (getsockname(fd, sa) == SOCKET_ERROR) { NET_ThrowNew(env, WSAGetLastError(), "Error getting socket name"); - return NULL; + return null; } - iaObj = NET_SockaddrToInetAddress(env, (struct sockaddr *)&sa, &port); + iaObj = NET_SockaddrToInetAddress(env, sa, port); return iaObj; } @@ -233,33 +244,32 @@ JNIEXPORT jobject JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketL * Method: socketReceiveOrPeekData * Signature: (ILjava/net/DatagramPacket;IZZ)I */ -JNIEXPORT jint JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketReceiveOrPeekData - (JNIEnv *env, jclass clazz, jint fd, jobject dpObj, - jint timeout, jboolean connected, jboolean peek) { +static int socketReceiveOrPeekData + (JNIEnv env, cli.System.Net.Sockets.Socket fd, DatagramPacket dpObj, + int timeout, boolean connected, boolean peek) { SOCKETADDRESS sa; - int sa_len = sizeof(sa); + sa = new SOCKETADDRESS(); int port, rv, flags=0; - char BUF[MAX_BUFFER_LEN]; - char *fullPacket; - BOOL retry; - jlong prevTime = 0; + boolean retry; + long prevTime = 0; - jint packetBufferOffset, packetBufferLen; - jbyteArray packetBuffer; + int packetBufferOffset, packetBufferLen; + byte[] packetBuffer; /* if we are only peeking. Called from peekData */ if (peek) { flags = MSG_PEEK; } - packetBuffer = (*env)->GetObjectField(env, dpObj, dp_bufID); - packetBufferOffset = (*env)->GetIntField(env, dpObj, dp_offsetID); - packetBufferLen = (*env)->GetIntField(env, dpObj, dp_bufLengthID); + packetBuffer = dpObj.buf; + packetBufferOffset = dpObj.offset; + packetBufferLen = dpObj.bufLength; + /* if (packetBufferLen > MAX_BUFFER_LEN) { /* Note: the buffer needn't be greater than 65,536 (0xFFFF) * the max size of an IP packet. Anything bigger is truncated anyway. - */ + *-/ if (packetBufferLen > MAX_PACKET_LEN) { packetBufferLen = MAX_PACKET_LEN; } @@ -271,36 +281,34 @@ JNIEXPORT jint JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketRece } else { fullPacket = &(BUF[0]); } + */ do { - retry = FALSE; + retry = false; - if (timeout) { + if (timeout != 0) { if (prevTime == 0) { prevTime = JVM_CurrentTimeMillis(env, 0); } rv = NET_Timeout(fd, timeout); if (rv <= 0) { if (rv == 0) { - JNU_ThrowByName(env,JNU_JAVANETPKG "SocketTimeoutException", + JNU_ThrowByName(env,JNU_JAVANETPKG+"SocketTimeoutException", "Receive timed out"); } else if (rv == JVM_IO_ERR) { - JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", + JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", "Socket closed"); } else if (rv == JVM_IO_INTR) { - JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException", + JNU_ThrowByName(env, JNU_JAVAIOPKG+"InterruptedIOException", "operation interrupted"); } - if (packetBufferLen > MAX_BUFFER_LEN) { - free(fullPacket); - } return -1; } } /* receive the packet */ - rv = recvfrom(fd, fullPacket, packetBufferLen, flags, - (struct sockaddr *)&sa, &sa_len); + rv = recvfrom(fd, packetBuffer, packetBufferOffset, packetBufferLen, flags, + sa); if (rv == SOCKET_ERROR && (WSAGetLastError() == WSAECONNRESET)) { /* An icmp port unreachable - we must receive this as Windows @@ -310,29 +318,25 @@ JNIEXPORT jint JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketRece purgeOutstandingICMP(env, fd); if (connected) { - JNU_ThrowByName(env, JNU_JAVANETPKG "PortUnreachableException", + JNU_ThrowByName(env, JNU_JAVANETPKG+"PortUnreachableException", "ICMP Port Unreachable"); - if (packetBufferLen > MAX_BUFFER_LEN) - free(fullPacket); return -1; - } else if (timeout) { + } else if (timeout != 0) { /* Adjust timeout */ - jlong newTime = JVM_CurrentTimeMillis(env, 0); - timeout -= (jint)(newTime - prevTime); + long newTime = JVM_CurrentTimeMillis(env, 0); + timeout -= (int)(newTime - prevTime); if (timeout <= 0) { - JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException", + JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketTimeoutException", "Receive timed out"); - if (packetBufferLen > MAX_BUFFER_LEN) - free(fullPacket); return -1; } prevTime = newTime; } - retry = TRUE; + retry = true; } } while (retry); - port = (int) ntohs ((u_short) GET_PORT((SOCKETADDRESS *)&sa)); + port = ntohs (GET_PORT(sa)); /* truncate the data if the packet's length is too small */ if (rv > packetBufferLen) { @@ -347,49 +351,45 @@ JNIEXPORT jint JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketRece rv = packetBufferLen; } else { /* failure */ - (*env)->SetIntField(env, dpObj, dp_lengthID, 0); + dpObj.length = 0; } } if (rv == -1) { - JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "socket closed"); + JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", "socket closed"); } else if (rv == -2) { - JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException", + JNU_ThrowByName(env, JNU_JAVAIOPKG+"InterruptedIOException", "operation interrupted"); } else if (rv < 0) { NET_ThrowCurrent(env, "Datagram receive failed"); } else { - jobject packetAddress; + InetAddress packetAddress; /* * Check if there is an InetAddress already associated with this * packet. If so, we check if it is the same source address. We * can't update any existing InetAddress because it is immutable */ - packetAddress = (*env)->GetObjectField(env, dpObj, dp_addressID); + packetAddress = dpObj.address; if (packetAddress != NULL) { - if (!NET_SockaddrEqualsInetAddress(env, (struct sockaddr *)&sa, + if (!NET_SockaddrEqualsInetAddress(sa, packetAddress)) { /* force a new InetAddress to be created */ - packetAddress = NULL; + packetAddress = null; } } if (packetAddress == NULL) { - packetAddress = NET_SockaddrToInetAddress(env, (struct sockaddr *)&sa, - &port); + int[] tmp = { port }; + packetAddress = NET_SockaddrToInetAddress(sa, tmp); + port = tmp[0]; /* stuff the new Inetaddress into the packet */ - (*env)->SetObjectField(env, dpObj, dp_addressID, packetAddress); + dpObj.address = packetAddress; } /* populate the packet */ - (*env)->SetByteArrayRegion(env, packetBuffer, packetBufferOffset, rv, - (jbyte *)fullPacket); - (*env)->SetIntField(env, dpObj, dp_portID, port); - (*env)->SetIntField(env, dpObj, dp_lengthID, rv); + dpObj.port = port; + dpObj.length = rv; } - if (packetBufferLen > MAX_BUFFER_LEN) { - free(fullPacket); - } return port; } @@ -398,30 +398,27 @@ JNIEXPORT jint JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketRece * Method: socketSend * Signature: (I[BIILjava/net/InetAddress;IZ)V */ -JNIEXPORT void JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketSend - (JNIEnv *env, jclass clazz, jint fd, jbyteArray data, jint offset, jint length, - jobject iaObj, jint port, jboolean connected) { +static void socketSend + (JNIEnv env, cli.System.Net.Sockets.Socket fd, byte[] data, int offset, int length, + InetAddress iaObj, int port, boolean connected) { SOCKETADDRESS sa; - int sa_len = sizeof(sa); - SOCKETADDRESS *sap = &sa; - char BUF[MAX_BUFFER_LEN]; - char *fullPacket; int rv; if (connected) { - sap = 0; /* arg to JVM_Sendto () null in this case */ - sa_len = 0; + sa = null; /* arg to JVM_Sendto () null in this case */ } else { - if (NET_InetAddressToSockaddr(env, iaObj, port, (struct sockaddr *)&sa, - &sa_len, JNI_TRUE) != 0) { + sa = new SOCKETADDRESS(); + if (NET_InetAddressToSockaddr(env, iaObj, port, sa, + JNI_TRUE) != 0) { return; } } + /* if (length > MAX_BUFFER_LEN) { /* Note: the buffer needn't be greater than 65,536 (0xFFFF) * the max size of an IP packet. Anything bigger is truncated anyway. - */ + *-/ if (length > MAX_PACKET_LEN) { length = MAX_PACKET_LEN; } @@ -433,22 +430,18 @@ JNIEXPORT void JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketSend } else { fullPacket = &(BUF[0]); } + */ - (*env)->GetByteArrayRegion(env, data, offset, length, - (jbyte *)fullPacket); - rv = sendto(fd, fullPacket, length, 0, (struct sockaddr *)sap, sa_len); + rv = sendto(fd, data, offset, length, 0, sa); if (rv == SOCKET_ERROR) { if (rv == JVM_IO_ERR) { NET_ThrowNew(env, WSAGetLastError(), "Datagram send failed"); } else if (rv == JVM_IO_INTR) { - JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException", + JNU_ThrowByName(env, JNU_JAVAIOPKG+"InterruptedIOException", "operation interrupted"); } } - if (length > MAX_BUFFER_LEN) { - free(fullPacket); - } } /* @@ -456,17 +449,17 @@ JNIEXPORT void JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketSend * Method: socketSetIntOption * Signature: (III)V */ -JNIEXPORT void JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketSetIntOption - (JNIEnv *env, jclass clazz, jint fd , jint cmd, jint value) { - int level, opt; +static void socketSetIntOption + (JNIEnv env, cli.System.Net.Sockets.Socket fd , int cmd, int value) { + int[] level = { 0 }, opt = { 0 }; - if (NET_MapSocketOption(cmd, &level, &opt) < 0) { - JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", + if (NET_MapSocketOption(cmd, level, opt) < 0) { + JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", "Invalid option"); return; } - if (NET_SetSockOpt(fd, level, opt, (char *)&value, sizeof(value)) < 0) { + if (NET_SetSockOpt(fd, level[0], opt[0], value) < 0) { NET_ThrowNew(env, WSAGetLastError(), "setsockopt"); } } @@ -476,21 +469,21 @@ JNIEXPORT void JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketSetI * Method: socketGetIntOption * Signature: (II)I */ -JNIEXPORT jint JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketGetIntOption - (JNIEnv *env, jclass clazz, jint fd, jint cmd) { - int level, opt, result=0; - int result_len = sizeof(result); +static int socketGetIntOption + (JNIEnv env, cli.System.Net.Sockets.Socket fd, int cmd) { + int[] level = { 0 }, opt = { 0 }, result = { 0 }; - if (NET_MapSocketOption(cmd, &level, &opt) < 0) { - JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", + if (NET_MapSocketOption(cmd, level, opt) < 0) { + JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", "Invalid option"); return -1; } - if (NET_GetSockOpt(fd, level, opt, (void *)&result, &result_len) < 0) { + if (NET_GetSockOpt(fd, level[0], opt[0], result) < 0) { NET_ThrowNew(env, WSAGetLastError(), "getsockopt"); return -1; } - return result; + return result[0]; +} } diff --git a/openjdk/java/net/DualStackPlainSocketImpl.java b/openjdk/java/net/DualStackPlainSocketImpl.java index 4073b9d5..4f35a6c6 100644 --- a/openjdk/java/net/DualStackPlainSocketImpl.java +++ b/openjdk/java/net/DualStackPlainSocketImpl.java @@ -26,8 +26,6 @@ package java.net; import java.io.IOException; import java.io.FileDescriptor; -import sun.misc.SharedSecrets; -import sun.misc.JavaIOFileDescriptorAccess; /** * This class defines the plain SocketImpl that is used on Windows platforms @@ -36,12 +34,11 @@ import sun.misc.JavaIOFileDescriptorAccess; * single file descriptor. * * @author Chris Hegarty + * @author Jeroen Frijters */ class DualStackPlainSocketImpl extends AbstractPlainSocketImpl { - static JavaIOFileDescriptorAccess fdAccess = SharedSecrets.getJavaIOFileDescriptorAccess(); - public DualStackPlainSocketImpl() {} public DualStackPlainSocketImpl(FileDescriptor fd) { @@ -52,14 +49,14 @@ class DualStackPlainSocketImpl extends AbstractPlainSocketImpl if (fd == null) throw new SocketException("Socket closed"); - int newfd = socket0(stream, false /*v6 Only*/); + cli.System.Net.Sockets.Socket newfd = socket0(stream, false /*v6 Only*/); - fdAccess.set(fd, newfd); + fd.setSocket(newfd); } void socketConnect(InetAddress address, int port, int timeout) throws IOException { - int nativefd = checkAndReturnNativeFD(); + cli.System.Net.Sockets.Socket nativefd = checkAndReturnNativeFD(); if (address == null) throw new NullPointerException("inet address argument is null."); @@ -88,7 +85,7 @@ class DualStackPlainSocketImpl extends AbstractPlainSocketImpl } void socketBind(InetAddress address, int port) throws IOException { - int nativefd = checkAndReturnNativeFD(); + cli.System.Net.Sockets.Socket nativefd = checkAndReturnNativeFD(); if (address == null) throw new NullPointerException("inet address argument is null."); @@ -104,18 +101,18 @@ class DualStackPlainSocketImpl extends AbstractPlainSocketImpl } void socketListen(int backlog) throws IOException { - int nativefd = checkAndReturnNativeFD(); + cli.System.Net.Sockets.Socket nativefd = checkAndReturnNativeFD(); listen0(nativefd, backlog); } void socketAccept(SocketImpl s) throws IOException { - int nativefd = checkAndReturnNativeFD(); + cli.System.Net.Sockets.Socket nativefd = checkAndReturnNativeFD(); if (s == null) throw new NullPointerException("socket is null"); - int newfd = -1; + cli.System.Net.Sockets.Socket newfd = null; InetSocketAddress[] isaa = new InetSocketAddress[1]; if (timeout <= 0) { newfd = accept0(nativefd, isaa); @@ -124,7 +121,7 @@ class DualStackPlainSocketImpl extends AbstractPlainSocketImpl try { waitForNewConnection(nativefd, timeout); newfd = accept0(nativefd, isaa); - if (newfd != -1) { + if (newfd != null) { configureBlocking(newfd, true); } } finally { @@ -132,7 +129,7 @@ class DualStackPlainSocketImpl extends AbstractPlainSocketImpl } } /* Update (SocketImpl)s' fd */ - fdAccess.set(s.fd, newfd); + s.fd.setSocket(newfd); /* Update socketImpls remote port, address and localport */ InetSocketAddress isa = isaa[0]; s.port = isa.getPort(); @@ -141,7 +138,7 @@ class DualStackPlainSocketImpl extends AbstractPlainSocketImpl } int socketAvailable() throws IOException { - int nativefd = checkAndReturnNativeFD(); + cli.System.Net.Sockets.Socket nativefd = checkAndReturnNativeFD(); return available0(nativefd); } @@ -152,18 +149,18 @@ class DualStackPlainSocketImpl extends AbstractPlainSocketImpl if (!fd.valid()) return; - close0(fdAccess.get(fd)); - fdAccess.set(fd, -1); + close0(fd.getSocket()); + fd.setSocket(null); } void socketShutdown(int howto) throws IOException { - int nativefd = checkAndReturnNativeFD(); + cli.System.Net.Sockets.Socket nativefd = checkAndReturnNativeFD(); shutdown0(nativefd, howto); } void socketSetOption(int opt, boolean on, Object value) throws SocketException { - int nativefd = checkAndReturnNativeFD(); + cli.System.Net.Sockets.Socket nativefd = checkAndReturnNativeFD(); if (opt == SO_TIMEOUT) { // timeout implemented through select. return; @@ -198,7 +195,7 @@ class DualStackPlainSocketImpl extends AbstractPlainSocketImpl } int socketGetOption(int opt, Object iaContainerObj) throws SocketException { - int nativefd = checkAndReturnNativeFD(); + cli.System.Net.Sockets.Socket nativefd = checkAndReturnNativeFD(); // SO_BINDADDR is not a socket option. if (opt == SO_BINDADDR) { @@ -219,58 +216,122 @@ class DualStackPlainSocketImpl extends AbstractPlainSocketImpl } void socketSendUrgentData(int data) throws IOException { - int nativefd = checkAndReturnNativeFD(); + cli.System.Net.Sockets.Socket nativefd = checkAndReturnNativeFD(); sendOOB(nativefd, data); } - private int checkAndReturnNativeFD() throws SocketException { + private cli.System.Net.Sockets.Socket checkAndReturnNativeFD() throws SocketException { if (fd == null || !fd.valid()) throw new SocketException("Socket closed"); - return fdAccess.get(fd); + return fd.getSocket(); } static final int WOULDBLOCK = -2; // Nothing available (non-blocking) - static { - initIDs(); - } - /* Native methods */ - static native void initIDs(); + static cli.System.Net.Sockets.Socket socket0(boolean stream, boolean v6Only) throws IOException { + ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv(); + cli.System.Net.Sockets.Socket ret = DualStackPlainSocketImpl_c.socket0(env, stream, v6Only); + env.ThrowPendingException(); + return ret; + } - static native int socket0(boolean stream, boolean v6Only) throws IOException; + static void bind0(cli.System.Net.Sockets.Socket fd, InetAddress localAddress, int localport) + throws IOException { + ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv(); + DualStackPlainSocketImpl_c.bind0(env, fd, localAddress, localport); + env.ThrowPendingException(); + } - static native void bind0(int fd, InetAddress localAddress, int localport) - throws IOException; + static int connect0(cli.System.Net.Sockets.Socket fd, InetAddress remote, int remotePort) + throws IOException { + ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv(); + int ret = DualStackPlainSocketImpl_c.connect0(env, fd, remote, remotePort); + env.ThrowPendingException(); + return ret; + } - static native int connect0(int fd, InetAddress remote, int remotePort) - throws IOException; + static void waitForConnect(cli.System.Net.Sockets.Socket fd, int timeout) throws IOException { + ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv(); + DualStackPlainSocketImpl_c.waitForConnect(env, fd, timeout); + env.ThrowPendingException(); + } - static native void waitForConnect(int fd, int timeout) throws IOException; + static int localPort0(cli.System.Net.Sockets.Socket fd) throws IOException { + ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv(); + int ret = DualStackPlainSocketImpl_c.localPort0(env, fd); + env.ThrowPendingException(); + return ret; + } - static native int localPort0(int fd) throws IOException; + static void localAddress(cli.System.Net.Sockets.Socket fd, InetAddressContainer in) throws SocketException { + ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv(); + DualStackPlainSocketImpl_c.localAddress(env, fd, in); + env.ThrowPendingException(); + } - static native void localAddress(int fd, InetAddressContainer in) throws SocketException; + static void listen0(cli.System.Net.Sockets.Socket fd, int backlog) throws IOException { + ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv(); + DualStackPlainSocketImpl_c.listen0(env, fd, backlog); + env.ThrowPendingException(); + } - static native void listen0(int fd, int backlog) throws IOException; + static cli.System.Net.Sockets.Socket accept0(cli.System.Net.Sockets.Socket fd, InetSocketAddress[] isaa) throws IOException { + ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv(); + cli.System.Net.Sockets.Socket ret = DualStackPlainSocketImpl_c.accept0(env, fd, isaa); + env.ThrowPendingException(); + return ret; + } - static native int accept0(int fd, InetSocketAddress[] isaa) throws IOException; + static void waitForNewConnection(cli.System.Net.Sockets.Socket fd, int timeout) throws IOException { + ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv(); + DualStackPlainSocketImpl_c.waitForNewConnection(env, fd, timeout); + env.ThrowPendingException(); + } - static native void waitForNewConnection(int fd, int timeout) throws IOException; + static int available0(cli.System.Net.Sockets.Socket fd) throws IOException { + ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv(); + int ret = DualStackPlainSocketImpl_c.available0(env, fd); + env.ThrowPendingException(); + return ret; + } - static native int available0(int fd) throws IOException; + static void close0(cli.System.Net.Sockets.Socket fd) throws IOException { + ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv(); + DualStackPlainSocketImpl_c.close0(env, fd); + env.ThrowPendingException(); + } - static native void close0(int fd) throws IOException; + static void shutdown0(cli.System.Net.Sockets.Socket fd, int howto) throws IOException { + ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv(); + DualStackPlainSocketImpl_c.shutdown0(env, fd, howto); + env.ThrowPendingException(); + } - static native void shutdown0(int fd, int howto) throws IOException; + static void setIntOption(cli.System.Net.Sockets.Socket fd, int cmd, int optionValue) throws SocketException { + ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv(); + DualStackPlainSocketImpl_c.setIntOption(env, fd, cmd, optionValue); + env.ThrowPendingException(); + } - static native void setIntOption(int fd, int cmd, int optionValue) throws SocketException; + static int getIntOption(cli.System.Net.Sockets.Socket fd, int cmd) throws SocketException { + ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv(); + int ret = DualStackPlainSocketImpl_c.getIntOption(env, fd, cmd); + env.ThrowPendingException(); + return ret; + } - static native int getIntOption(int fd, int cmd) throws SocketException; + static void sendOOB(cli.System.Net.Sockets.Socket fd, int data) throws IOException { + ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv(); + DualStackPlainSocketImpl_c.sendOOB(env, fd, data); + env.ThrowPendingException(); + } - static native void sendOOB(int fd, int data) throws IOException; - - static native void configureBlocking(int fd, boolean blocking) throws IOException; + static void configureBlocking(cli.System.Net.Sockets.Socket fd, boolean blocking) throws IOException { + ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv(); + DualStackPlainSocketImpl_c.configureBlocking(env, fd, blocking); + env.ThrowPendingException(); + } } diff --git a/openjdk/java/net/DualStackPlainSocketImpl_c.java b/openjdk/java/net/DualStackPlainSocketImpl_c.java index 5f22e887..b5b856dd 100644 --- a/openjdk/java/net/DualStackPlainSocketImpl_c.java +++ b/openjdk/java/net/DualStackPlainSocketImpl_c.java @@ -22,6 +22,21 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ +package java.net; + +import java.io.FileDescriptor; +import static ikvm.internal.JNI.*; +import static ikvm.internal.Winsock.*; +import static java.net.net_util_md.*; + +final class DualStackPlainSocketImpl_c +{ +private static final int JVM_IO_ERR = -1; +private static final int JVM_IO_INTR = -2; + +private static final int SET_BLOCKING = 0; +private static final int SET_NONBLOCKING = 1; +/* #include #include #include "jni.h" @@ -31,14 +46,14 @@ #define SET_BLOCKING 0 #define SET_NONBLOCKING 1 -static jclass isa_class; /* java.net.InetSocketAddress */ -static jmethodID isa_ctorID; /* InetSocketAddress(InetAddress, int) */ +static jclass isa_class; /* java.net.InetSocketAddress *-/ +static jmethodID isa_ctorID; /* InetSocketAddress(InetAddress, int) *-/ /* * Class: java_net_DualStackPlainSocketImpl * Method: initIDs * Signature: ()V - */ + *-/ JNIEXPORT void JNICALL Java_java_net_DualStackPlainSocketImpl_initIDs (JNIEnv *env, jclass clazz) { @@ -56,22 +71,22 @@ JNIEXPORT void JNICALL Java_java_net_DualStackPlainSocketImpl_initIDs * Method: socket0 * Signature: (ZZ)I */ -JNIEXPORT jint JNICALL Java_java_net_DualStackPlainSocketImpl_socket0 - (JNIEnv *env, jclass clazz, jboolean stream, jboolean v6Only /*unused*/) { - int fd, rv, opt=0; +static cli.System.Net.Sockets.Socket socket0 + (JNIEnv env, boolean stream, boolean v6Only /*unused*/) { + cli.System.Net.Sockets.Socket fd; + int rv, opt=0; fd = NET_Socket(AF_INET6, (stream ? SOCK_STREAM : SOCK_DGRAM), 0); if (fd == INVALID_SOCKET) { NET_ThrowNew(env, WSAGetLastError(), "create"); - return -1; + return null; } - rv = setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &opt, sizeof(opt)); + rv = setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, opt); if (rv == SOCKET_ERROR) { NET_ThrowNew(env, WSAGetLastError(), "create"); } - SetHandleInformation((HANDLE)(UINT_PTR)fd, HANDLE_FLAG_INHERIT, FALSE); return fd; } @@ -81,18 +96,18 @@ JNIEXPORT jint JNICALL Java_java_net_DualStackPlainSocketImpl_socket0 * Method: bind0 * Signature: (ILjava/net/InetAddress;I)V */ -JNIEXPORT void JNICALL Java_java_net_DualStackPlainSocketImpl_bind0 - (JNIEnv *env, jclass clazz, jint fd, jobject iaObj, jint port) { +static void bind0 + (JNIEnv env, cli.System.Net.Sockets.Socket fd, InetAddress iaObj, int port) { SOCKETADDRESS sa; + sa = new SOCKETADDRESS(); int rv; - int sa_len = sizeof(sa); - if (NET_InetAddressToSockaddr(env, iaObj, port, (struct sockaddr *)&sa, - &sa_len, JNI_TRUE) != 0) { + if (NET_InetAddressToSockaddr(env, iaObj, port, sa, + JNI_TRUE) != 0) { return; } - rv = NET_Bind(fd, (struct sockaddr *)&sa, sa_len); + rv = NET_Bind(fd, sa); if (rv == SOCKET_ERROR) NET_ThrowNew(env, WSAGetLastError(), "JVM_Bind"); @@ -103,24 +118,24 @@ JNIEXPORT void JNICALL Java_java_net_DualStackPlainSocketImpl_bind0 * Method: connect0 * Signature: (ILjava/net/InetAddress;I)I */ -JNIEXPORT jint JNICALL Java_java_net_DualStackPlainSocketImpl_connect0 - (JNIEnv *env, jclass clazz, jint fd, jobject iaObj, jint port) { +static int connect0 + (JNIEnv env, cli.System.Net.Sockets.Socket fd, InetAddress iaObj, int port) { SOCKETADDRESS sa; + sa = new SOCKETADDRESS(); int rv; - int sa_len = sizeof(sa); - if (NET_InetAddressToSockaddr(env, iaObj, port, (struct sockaddr *)&sa, - &sa_len, JNI_TRUE) != 0) { + if (NET_InetAddressToSockaddr(env, iaObj, port, sa, + JNI_TRUE) != 0) { return -1; } - rv = connect(fd, (struct sockaddr *)&sa, sa_len); + rv = connect(fd, sa); if (rv == SOCKET_ERROR) { int err = WSAGetLastError(); if (err == WSAEWOULDBLOCK) { - return java_net_DualStackPlainSocketImpl_WOULDBLOCK; + return java.net.DualStackPlainSocketImpl.WOULDBLOCK; } else if (err == WSAEADDRNOTAVAIL) { - JNU_ThrowByName(env, JNU_JAVANETPKG "ConnectException", + JNU_ThrowByName(env, JNU_JAVANETPKG+"ConnectException", "connect: Address is invalid on local machine, or port is not valid on remote machine"); } else { NET_ThrowNew(env, err, "connect"); @@ -135,17 +150,17 @@ JNIEXPORT jint JNICALL Java_java_net_DualStackPlainSocketImpl_connect0 * Method: waitForConnect * Signature: (II)V */ -JNIEXPORT void JNICALL Java_java_net_DualStackPlainSocketImpl_waitForConnect - (JNIEnv *env, jclass clazz, jint fd, jint timeout) { +static void waitForConnect + (JNIEnv env, cli.System.Net.Sockets.Socket fd, int timeout) { int rv, retry; - int optlen = sizeof(rv); fd_set wr, ex; - struct timeval t; + wr = new fd_set(); ex = new fd_set(); + timeval t = new timeval(); - FD_ZERO(&wr); - FD_ZERO(&ex); - FD_SET(fd, &wr); - FD_SET(fd, &ex); + FD_ZERO(wr); + FD_ZERO(ex); + FD_SET(fd, wr); + FD_SET(fd, ex); t.tv_sec = timeout / 1000; t.tv_usec = (timeout % 1000) * 1000; @@ -153,7 +168,7 @@ JNIEXPORT void JNICALL Java_java_net_DualStackPlainSocketImpl_waitForConnect * Wait for timeout, connection established or * connection failed. */ - rv = select(fd+1, 0, &wr, &ex, &t); + rv = select(null, wr, ex, t); /* * Timeout before connection is established/failed so @@ -162,7 +177,7 @@ JNIEXPORT void JNICALL Java_java_net_DualStackPlainSocketImpl_waitForConnect * The socket should be closed immediately by the caller. */ if (rv == 0) { - JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException", + JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketTimeoutException", "connect timed out"); shutdown( fd, SD_BOTH ); return; @@ -173,7 +188,7 @@ JNIEXPORT void JNICALL Java_java_net_DualStackPlainSocketImpl_waitForConnect * the socket will appear writable when the connect fails so we * check for error rather than writable. */ - if (!FD_ISSET(fd, &ex)) { + if (!FD_ISSET(fd, ex)) { return; /* connection established */ } @@ -186,16 +201,18 @@ JNIEXPORT void JNICALL Java_java_net_DualStackPlainSocketImpl_waitForConnect * load conditions we attempt up to 3 times to get the error reason. */ for (retry=0; retry<3; retry++) { + int[] tmp = { 0 }; NET_GetSockOpt(fd, SOL_SOCKET, SO_ERROR, - (char*)&rv, &optlen); - if (rv) { + tmp); + rv = tmp[0]; + if (rv != 0) { break; } Sleep(0); } if (rv == 0) { - JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", + JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", "Unable to establish connection"); } else { NET_ThrowNew(env, rv, "connect"); @@ -207,21 +224,21 @@ JNIEXPORT void JNICALL Java_java_net_DualStackPlainSocketImpl_waitForConnect * Method: localPort0 * Signature: (I)I */ -JNIEXPORT jint JNICALL Java_java_net_DualStackPlainSocketImpl_localPort0 - (JNIEnv *env, jclass clazz, jint fd) { +static int localPort0 + (JNIEnv env, cli.System.Net.Sockets.Socket fd) { SOCKETADDRESS sa; - int len = sizeof(sa); + sa = new SOCKETADDRESS(); - if (getsockname(fd, (struct sockaddr *)&sa, &len) == SOCKET_ERROR) { + if (getsockname(fd, sa) == SOCKET_ERROR) { if (WSAGetLastError() == WSAENOTSOCK) { - JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", + JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", "Socket closed"); } else { NET_ThrowNew(env, WSAGetLastError(), "getsockname failed"); } return -1; } - return (int) ntohs((u_short)GET_PORT(&sa)); + return ntohs(GET_PORT(sa)); } /* @@ -229,26 +246,20 @@ JNIEXPORT jint JNICALL Java_java_net_DualStackPlainSocketImpl_localPort0 * Method: localAddress * Signature: (ILjava/net/InetAddressContainer;)V */ -JNIEXPORT void JNICALL Java_java_net_DualStackPlainSocketImpl_localAddress - (JNIEnv *env, jclass clazz, jint fd, jobject iaContainerObj) { - int port; +static void localAddress + (JNIEnv env, cli.System.Net.Sockets.Socket fd, InetAddressContainer iaContainerObj) { + int[] port = { 0 }; SOCKETADDRESS sa; - int len = sizeof(sa); - jobject iaObj; - jclass iaContainerClass; - jfieldID iaFieldID; + sa = new SOCKETADDRESS(); + InetAddress iaObj; - if (getsockname(fd, (struct sockaddr *)&sa, &len) == SOCKET_ERROR) { + if (getsockname(fd, sa) == SOCKET_ERROR) { NET_ThrowNew(env, WSAGetLastError(), "Error getting socket name"); return; } - iaObj = NET_SockaddrToInetAddress(env, (struct sockaddr *)&sa, &port); - CHECK_NULL(iaObj); + iaObj = NET_SockaddrToInetAddress(env, sa, port); - iaContainerClass = (*env)->GetObjectClass(env, iaContainerObj); - iaFieldID = (*env)->GetFieldID(env, iaContainerClass, "addr", "Ljava/net/InetAddress;"); - CHECK_NULL(iaFieldID); - (*env)->SetObjectField(env, iaContainerObj, iaFieldID, iaObj); + iaContainerObj.addr = iaObj; } @@ -257,8 +268,8 @@ JNIEXPORT void JNICALL Java_java_net_DualStackPlainSocketImpl_localAddress * Method: listen0 * Signature: (II)V */ -JNIEXPORT void JNICALL Java_java_net_DualStackPlainSocketImpl_listen0 - (JNIEnv *env, jclass clazz, jint fd, jint backlog) { +static void listen0 + (JNIEnv env, cli.System.Net.Sockets.Socket fd, int backlog) { if (listen(fd, backlog) == SOCKET_ERROR) { NET_ThrowNew(env, WSAGetLastError(), "listen failed"); } @@ -269,31 +280,31 @@ JNIEXPORT void JNICALL Java_java_net_DualStackPlainSocketImpl_listen0 * Method: accept0 * Signature: (I[Ljava/net/InetSocketAddress;)I */ -JNIEXPORT jint JNICALL Java_java_net_DualStackPlainSocketImpl_accept0 - (JNIEnv *env, jclass clazz, jint fd, jobjectArray isaa) { - int newfd, port=0; - jobject isa; - jobject ia; +static cli.System.Net.Sockets.Socket accept0 + (JNIEnv env, cli.System.Net.Sockets.Socket fd, InetSocketAddress[] isaa) { + cli.System.Net.Sockets.Socket newfd; + int[] port = { 0 }; + InetSocketAddress isa; + InetAddress ia; SOCKETADDRESS sa; - int len = sizeof(sa); + sa = new SOCKETADDRESS(); - memset((char *)&sa, 0, len); - newfd = accept(fd, (struct sockaddr *)&sa, &len); + newfd = accept(fd, sa); if (newfd == INVALID_SOCKET) { if (WSAGetLastError() == -2) { - JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException", + JNU_ThrowByName(env, JNU_JAVAIOPKG+"InterruptedIOException", "operation interrupted"); } else { - JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", + JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", "socket closed"); } - return -1; + return null; } - ia = NET_SockaddrToInetAddress(env, (struct sockaddr *)&sa, &port); - isa = (*env)->NewObject(env, isa_class, isa_ctorID, ia, port); - (*env)->SetObjectArrayElement(env, isaa, 0, isa); + ia = NET_SockaddrToInetAddress(env, sa, port); + isa = new InetSocketAddress(ia, port[0]); + isaa[0] = isa; return newfd; } @@ -303,18 +314,18 @@ JNIEXPORT jint JNICALL Java_java_net_DualStackPlainSocketImpl_accept0 * Method: waitForNewConnection * Signature: (II)V */ -JNIEXPORT void JNICALL Java_java_net_DualStackPlainSocketImpl_waitForNewConnection - (JNIEnv *env, jclass clazz, jint fd, jint timeout) { +static void waitForNewConnection + (JNIEnv env, cli.System.Net.Sockets.Socket fd, int timeout) { int rv; rv = NET_Timeout(fd, timeout); if (rv == 0) { - JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException", + JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketTimeoutException", "Accept timed out"); } else if (rv == -1) { - JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "socket closed"); + JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", "socket closed"); } else if (rv == -2) { - JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException", + JNU_ThrowByName(env, JNU_JAVAIOPKG+"InterruptedIOException", "operation interrupted"); } } @@ -324,15 +335,15 @@ JNIEXPORT void JNICALL Java_java_net_DualStackPlainSocketImpl_waitForNewConnecti * Method: available0 * Signature: (I)I */ -JNIEXPORT jint JNICALL Java_java_net_DualStackPlainSocketImpl_available0 - (JNIEnv *env, jclass clazz, jint fd) { - jint available = -1; +static int available0 + (JNIEnv env, cli.System.Net.Sockets.Socket fd) { + int[] available = { -1 }; - if ((ioctlsocket(fd, FIONREAD, &available)) == SOCKET_ERROR) { + if ((ioctlsocket(fd, FIONREAD, available)) == SOCKET_ERROR) { NET_ThrowNew(env, WSAGetLastError(), "socket available"); } - return available; + return available[0]; } /* @@ -340,8 +351,8 @@ JNIEXPORT jint JNICALL Java_java_net_DualStackPlainSocketImpl_available0 * Method: close0 * Signature: (I)V */ -JNIEXPORT void JNICALL Java_java_net_DualStackPlainSocketImpl_close0 - (JNIEnv *env, jclass clazz, jint fd) { +static void close0 + (JNIEnv env, cli.System.Net.Sockets.Socket fd) { NET_SocketClose(fd); } @@ -350,8 +361,8 @@ JNIEXPORT void JNICALL Java_java_net_DualStackPlainSocketImpl_close0 * Method: shutdown0 * Signature: (II)V */ -JNIEXPORT void JNICALL Java_java_net_DualStackPlainSocketImpl_shutdown0 - (JNIEnv *env, jclass clazz, jint fd, jint howto) { +static void shutdown0 + (JNIEnv env, cli.System.Net.Sockets.Socket fd, int howto) { shutdown(fd, howto); } @@ -361,37 +372,36 @@ JNIEXPORT void JNICALL Java_java_net_DualStackPlainSocketImpl_shutdown0 * Method: setIntOption * Signature: (III)V */ -JNIEXPORT void JNICALL Java_java_net_DualStackPlainSocketImpl_setIntOption - (JNIEnv *env, jclass clazz, jint fd, jint cmd, jint value) { +static void setIntOption + (JNIEnv env, cli.System.Net.Sockets.Socket fd, int cmd, int value) { - int level, opt; - struct linger linger; - char *parg; - int arglen; + int[] level = { 0 }; + int[] opt = { 0 }; + linger linger; + Object optval; - if (NET_MapSocketOption(cmd, &level, &opt) < 0) { - JNU_ThrowByNameWithLastError(env, - JNU_JAVANETPKG "SocketException", + if (NET_MapSocketOption(cmd, level, opt) < 0) { + JNU_ThrowByName(env, + JNU_JAVANETPKG+"SocketException", "Invalid option"); return; } - if (opt == java_net_SocketOptions_SO_LINGER) { - parg = (char *)&linger; - arglen = sizeof(linger); + if (opt[0] == java.net.SocketOptions.SO_LINGER) { + linger = new linger(); if (value >= 0) { linger.l_onoff = 1; - linger.l_linger = (unsigned short)value; + linger.l_linger = value & 0xFFFF; } else { linger.l_onoff = 0; linger.l_linger = 0; } + optval = linger; } else { - parg = (char *)&value; - arglen = sizeof(value); + optval = value; } - if (NET_SetSockOpt(fd, level, opt, parg, arglen) < 0) { + if (NET_SetSockOpt(fd, level[0], opt[0], optval) < 0) { NET_ThrowNew(env, WSAGetLastError(), "setsockopt"); } } @@ -401,39 +411,39 @@ JNIEXPORT void JNICALL Java_java_net_DualStackPlainSocketImpl_setIntOption * Method: getIntOption * Signature: (II)I */ -JNIEXPORT jint JNICALL Java_java_net_DualStackPlainSocketImpl_getIntOption - (JNIEnv *env, jclass clazz, jint fd, jint cmd) { +static int getIntOption + (JNIEnv env, cli.System.Net.Sockets.Socket fd, int cmd) { - int level, opt; - int result=0; - struct linger linger; - char *arg; - int arglen; + int[] level = { 0 }; + int[] opt = { 0 }; + int[] result = { 0 }; + linger linger; + Object optval; - if (NET_MapSocketOption(cmd, &level, &opt) < 0) { - JNU_ThrowByNameWithLastError(env, - JNU_JAVANETPKG "SocketException", + if (NET_MapSocketOption(cmd, level, opt) < 0) { + JNU_ThrowByName(env, + JNU_JAVANETPKG+"SocketException", "Unsupported socket option"); return -1; } - if (opt == java_net_SocketOptions_SO_LINGER) { - arg = (char *)&linger; - arglen = sizeof(linger); + if (opt[0] == java.net.SocketOptions.SO_LINGER) { + linger = new linger(); + optval = linger; } else { - arg = (char *)&result; - arglen = sizeof(result); + linger = null; + optval = result; } - if (NET_GetSockOpt(fd, level, opt, arg, &arglen) < 0) { + if (NET_GetSockOpt(fd, level[0], opt[0], optval) < 0) { NET_ThrowNew(env, WSAGetLastError(), "getsockopt"); return -1; } - if (opt == java_net_SocketOptions_SO_LINGER) - return linger.l_onoff ? linger.l_linger : -1; + if (opt[0] == java.net.SocketOptions.SO_LINGER) + return linger.l_onoff != 0 ? linger.l_linger : -1; else - return result; + return result[0]; } @@ -442,16 +452,15 @@ JNIEXPORT jint JNICALL Java_java_net_DualStackPlainSocketImpl_getIntOption * Method: sendOOB * Signature: (II)V */ -JNIEXPORT void JNICALL Java_java_net_DualStackPlainSocketImpl_sendOOB - (JNIEnv *env, jclass clazz, jint fd, jint data) { - jint n; - unsigned char d = (unsigned char) data & 0xff; +static void sendOOB + (JNIEnv env, cli.System.Net.Sockets.Socket fd, int data) { + int n; - n = send(fd, (char *)&data, 1, MSG_OOB); + n = send(fd, new byte[] { (byte)data }, 1, MSG_OOB); if (n == JVM_IO_ERR) { NET_ThrowNew(env, WSAGetLastError(), "send"); } else if (n == JVM_IO_INTR) { - JNU_ThrowByName(env, "java/io/InterruptedIOException", 0); + JNU_ThrowByName(env, "java.io.InterruptedIOException", null); } } @@ -460,9 +469,9 @@ JNIEXPORT void JNICALL Java_java_net_DualStackPlainSocketImpl_sendOOB * Method: configureBlocking * Signature: (IZ)V */ -JNIEXPORT void JNICALL Java_java_net_DualStackPlainSocketImpl_configureBlocking - (JNIEnv *env, jclass clazz, jint fd, jboolean blocking) { - u_long arg; +static void configureBlocking + (JNIEnv env, cli.System.Net.Sockets.Socket fd, boolean blocking) { + int arg; int result; if (blocking == JNI_TRUE) { @@ -471,8 +480,9 @@ JNIEXPORT void JNICALL Java_java_net_DualStackPlainSocketImpl_configureBlocking arg = SET_NONBLOCKING; // 1 } - result = ioctlsocket(fd, FIONBIO, &arg); + result = ioctlsocket(fd, FIONBIO, arg); if (result == SOCKET_ERROR) { NET_ThrowNew(env, WSAGetLastError(), "configureBlocking"); } } +} diff --git a/openjdk/java/net/TwoStacksPlainDatagramSocketImpl.java b/openjdk/java/net/TwoStacksPlainDatagramSocketImpl.java index 85708342..e606c758 100644 --- a/openjdk/java/net/TwoStacksPlainDatagramSocketImpl.java +++ b/openjdk/java/net/TwoStacksPlainDatagramSocketImpl.java @@ -224,11 +224,3 @@ class TwoStacksPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl private static final boolean runningOnMono = cli.System.Type.GetType("Mono.Runtime") != null; } - -// we don't support a dual-stack approach yet, so we simply make it an alias for the two-stacks approach -class DualStackPlainDatagramSocketImpl extends TwoStacksPlainDatagramSocketImpl { - // we need this method, because DatagramSocket uses reflection to check for this methods existance - protected int peekData(DatagramPacket p) throws IOException { - return super.peekData(p); - } -} diff --git a/openjdk/java/net/TwoStacksPlainSocketImpl.java b/openjdk/java/net/TwoStacksPlainSocketImpl.java index d6f9f403..555db486 100644 --- a/openjdk/java/net/TwoStacksPlainSocketImpl.java +++ b/openjdk/java/net/TwoStacksPlainSocketImpl.java @@ -243,14 +243,3 @@ class TwoStacksPlainSocketImpl extends AbstractPlainSocketImpl env.ThrowPendingException(); } } - -// we don't support a dual-stack approach yet, so we simply make it an alias for the two-stacks approach -class DualStackPlainSocketImpl extends TwoStacksPlainSocketImpl -{ - DualStackPlainSocketImpl() { - } - - DualStackPlainSocketImpl(FileDescriptor fd) { - super(fd); - } -} diff --git a/openjdk/java/net/net_util_md.java b/openjdk/java/net/net_util_md.java index 39afec68..62b3e8b5 100644 --- a/openjdk/java/net/net_util_md.java +++ b/openjdk/java/net/net_util_md.java @@ -25,6 +25,7 @@ package java.net; +import java.io.FileDescriptor; import cli.System.Net.IPAddress; import cli.System.Net.IPEndPoint; import static ikvm.internal.JNI.*; @@ -734,6 +735,10 @@ final class net_util_md } } + static InetAddress NET_SockaddrToInetAddress(JNIEnv env, SOCKETADDRESS him, int[] port) { + return NET_SockaddrToInetAddress(him, port); + } + static InetAddress NET_SockaddrToInetAddress(SOCKETADDRESS him, int[] port) { InetAddress iaObj; if (him.sa_family == AF_INET6) { @@ -821,4 +826,13 @@ final class net_util_md static void Sleep(int ms) { cli.System.Threading.Thread.Sleep(ms); } + + static cli.System.Net.Sockets.Socket NET_Socket (int domain, int type, int protocol) { + cli.System.Net.Sockets.Socket sock; + sock = socket (domain, type, protocol); + if (sock != INVALID_SOCKET) { + //SetHandleInformation((HANDLE)(uintptr_t)sock, HANDLE_FLAG_INHERIT, FALSE); + } + return sock; + } } diff --git a/runtime/openjdk.cs b/runtime/openjdk.cs index dc8d2ce3..b7c39dbe 100644 --- a/runtime/openjdk.cs +++ b/runtime/openjdk.cs @@ -3760,11 +3760,22 @@ namespace IKVM.NativeCode.java static class InetAddressImplFactory { - // On Linux we can't bind both an IPv4 and IPv6 to the same port, so we have to disable IPv6 until we have a dual-stack implementation. - // Mono on Windows doesn't appear to support IPv6 either (Mono on Linux does). - private static readonly bool ipv6supported = Type.GetType("Mono.Runtime") == null - && Environment.OSVersion.Platform == PlatformID.Win32NT - && System.Net.Sockets.Socket.OSSupportsIPv6; + private static readonly bool ipv6supported = Init(); + + private static bool Init() + { + string env = IKVM.Internal.JVM.SafeGetEnvironmentVariable("IKVM_IPV6"); + int val; + if (env != null && Int32.TryParse(env, out val)) + { + return (val & 1) != 0; + } + // On Linux we can't bind both an IPv4 and IPv6 to the same port, so we have to disable IPv6 until we have a dual-stack implementation. + // Mono on Windows doesn't appear to support IPv6 either (Mono on Linux does). + return Type.GetType("Mono.Runtime") == null + && Environment.OSVersion.Platform == PlatformID.Win32NT + && System.Net.Sockets.Socket.OSSupportsIPv6; + } public static bool isIPv6Supported() { diff --git a/runtime/openjdk/sun.nio.ch.cs b/runtime/openjdk/sun.nio.ch.cs index ca9ed16c..0b52ed1f 100644 --- a/runtime/openjdk/sun.nio.ch.cs +++ b/runtime/openjdk/sun.nio.ch.cs @@ -492,9 +492,17 @@ namespace IKVM.NativeCode.sun.nio.ch { public static bool isIPv6Available0() { - // we only support IPv6 on Vista and up + string env = IKVM.Internal.JVM.SafeGetEnvironmentVariable("IKVM_IPV6"); + int val; + if (env != null && Int32.TryParse(env, out val)) + { + return (val & 2) != 0; + } + // we only support IPv6 on Vista and up (because there is no TwoStacks nio implementation) // (non-Windows OSses are currently not supported) - return System.Net.Sockets.Socket.OSSupportsIPv6 + // Mono on Windows doesn't appear to support IPv6 either (Mono on Linux does). + return Type.GetType("Mono.Runtime") == null + && System.Net.Sockets.Socket.OSSupportsIPv6 && Environment.OSVersion.Platform == PlatformID.Win32NT && Environment.OSVersion.Version.Major >= 6; }