--- old/src/java.base/windows/native/libnet/DualStackPlainSocketImpl.c 2018-03-06 12:26:28.798157956 -0800 +++ new/src/java.base/windows/native/libnet/DualStackPlainSocketImpl.c 2018-03-06 12:26:28.482157956 -0800 @@ -371,33 +371,6 @@ /* * Class: java_net_DualStackPlainSocketImpl - * 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; - SOCKETADDRESS sa; - int len = sizeof(sa); - jobject iaObj; - jclass iaContainerClass; - jfieldID iaFieldID; - - if (getsockname(fd, &sa.sa, &len) == SOCKET_ERROR) { - NET_ThrowNew(env, WSAGetLastError(), "Error getting socket name"); - return; - } - iaObj = NET_SockaddrToInetAddress(env, &sa, &port); - CHECK_NULL(iaObj); - - iaContainerClass = (*env)->GetObjectClass(env, iaContainerObj); - iaFieldID = (*env)->GetFieldID(env, iaContainerClass, "addr", "Ljava/net/InetAddress;"); - CHECK_NULL(iaFieldID); - (*env)->SetObjectField(env, iaContainerObj, iaFieldID, iaObj); -} - -/* - * Class: java_net_DualStackPlainSocketImpl * Method: socketListen * Signature: (I)V */ @@ -619,44 +592,6 @@ /* * Class: java_net_DualStackPlainSocketImpl - * Method: getIntOption - * Signature: (II)I - */ -JNIEXPORT jint JNICALL Java_java_net_DualStackPlainSocketImpl_getIntOption - (JNIEnv *env, jclass clazz, jint fd, jint cmd) -{ - int level = 0, opt = 0; - int result=0; - struct linger linger = {0, 0}; - char *arg; - int arglen; - - if (NET_MapSocketOption(cmd, &level, &opt) < 0) { - JNU_ThrowByName(env, "java/net/SocketException", "Invalid option"); - return -1; - } - - if (opt == java_net_SocketOptions_SO_LINGER) { - arg = (char *)&linger; - arglen = sizeof(linger); - } else { - arg = (char *)&result; - arglen = sizeof(result); - } - - if (NET_GetSockOpt(fd, level, opt, arg, &arglen) < 0) { - NET_ThrowNew(env, WSAGetLastError(), "getsockopt"); - return -1; - } - - if (opt == java_net_SocketOptions_SO_LINGER) - return linger.l_onoff ? linger.l_linger : -1; - else - return result; -} - -/* - * Class: java_net_DualStackPlainSocketImpl * Method: socketNativeSetOption * Signature: (IZLjava/lang/Object;)V */ @@ -706,17 +641,17 @@ switch (cmd) { - case java_net_SocketOptions_TCP_NODELAY : - case java_net_SocketOptions_SO_OOBINLINE : - case java_net_SocketOptions_SO_KEEPALIVE : - case java_net_SocketOptions_SO_REUSEADDR : + case java_net_SocketOptions_TCP_NODELAY: + case java_net_SocketOptions_SO_OOBINLINE: + case java_net_SocketOptions_SO_KEEPALIVE: + case java_net_SocketOptions_SO_REUSEADDR: optval.i = (on ? 1 : 0); optlen = sizeof(optval.i); break; - case java_net_SocketOptions_SO_SNDBUF : - case java_net_SocketOptions_SO_RCVBUF : - case java_net_SocketOptions_IP_TOS : + case java_net_SocketOptions_SO_SNDBUF: + case java_net_SocketOptions_SO_RCVBUF: + case java_net_SocketOptions_IP_TOS: { jclass cls; jfieldID fid; @@ -773,7 +708,100 @@ Java_java_net_DualStackPlainSocketImpl_socketNativeGetOption (JNIEnv *env, jobject this, jint opt, jobject iaContainerObj) { - return -1; + /* The fd field */ + jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID); + + int fd; + int level = 0, optname = 0, optlen = 0; + union { + int i; + struct linger ling; + } optval; + + /* + * Get SOCKET and check it hasn't been closed + */ + if (IS_NULL(fdObj)) { + JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed"); + return -1; + } else { + fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID); + } + if (fd < 0) { + JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed"); + return -1; + } + memset((char *)&optval, 0, sizeof(optval)); + + /* + * SO_BINDADDR isn't a socket option + */ + if (opt == java_net_SocketOptions_SO_BINDADDR) { + SOCKETADDRESS sa; + int len = sizeof(sa); + int port; + jobject iaObj; + jclass iaContainerClass; + jfieldID iaFieldID; + + if (getsockname(fd, &sa.sa, &len) == SOCKET_ERROR) { + NET_ThrowNew(env, WSAGetLastError(), "Error getting socket name"); + return -1; + } + iaObj = NET_SockaddrToInetAddress(env, &sa, &port); + CHECK_NULL_RETURN(iaObj, -1); + + iaContainerClass = (*env)->GetObjectClass(env, iaContainerObj); + iaFieldID = (*env)->GetFieldID(env, iaContainerClass, "addr", "Ljava/net/InetAddress;"); + CHECK_NULL_RETURN(iaFieldID, -1); + (*env)->SetObjectField(env, iaContainerObj, iaFieldID, iaObj); + return 0; /* notice change from before */ + } + + /* + * Map the Java level socket option to the platform specific + * level and option name. + */ + if (NET_MapSocketOption(opt, &level, &optname)) { + JNU_ThrowByName(env, "java/net/SocketException", "Invalid option"); + return -1; + } + + /* + * Args are int except for SO_LINGER + */ + if (opt == java_net_SocketOptions_SO_LINGER) { + optlen = sizeof(optval.ling); + } else { + optlen = sizeof(optval.i); + optval.i = 0; + } + + if (NET_GetSockOpt(fd, level, optname, (void *)&optval, &optlen) < 0) { + NET_ThrowNew(env, WSAGetLastError(), "getsockopt"); + return -1; + } + + switch (opt) { + case java_net_SocketOptions_SO_LINGER: + return (optval.ling.l_onoff ? optval.ling.l_linger: -1); + + case java_net_SocketOptions_SO_SNDBUF: + case java_net_SocketOptions_SO_RCVBUF: + case java_net_SocketOptions_IP_TOS: + return optval.i; + + case java_net_SocketOptions_TCP_NODELAY: + case java_net_SocketOptions_SO_OOBINLINE: + case java_net_SocketOptions_SO_KEEPALIVE: + case java_net_SocketOptions_SO_REUSEADDR: + return (optval.i == 0) ? -1 : 1; + + default: /* shouldn't get here */ + JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", + "Option not supported by TwoStacksPlainSocketImpl"); + return -1; + } } /*