diff options
Diffstat (limited to 'openjdk/java/net/TwoStacksPlainSocketImpl_c.java')
-rw-r--r-- | openjdk/java/net/TwoStacksPlainSocketImpl_c.java | 1080 |
1 files changed, 0 insertions, 1080 deletions
diff --git a/openjdk/java/net/TwoStacksPlainSocketImpl_c.java b/openjdk/java/net/TwoStacksPlainSocketImpl_c.java deleted file mode 100644 index d86e84d0..00000000 --- a/openjdk/java/net/TwoStacksPlainSocketImpl_c.java +++ /dev/null @@ -1,1080 +0,0 @@ -/* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * 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.*; -import static java.net.InetAddress.IPv4; -import static java.net.InetAddress.IPv6; - -final class TwoStacksPlainSocketImpl_c -{ -static final int JVM_IO_ERR = -1; -static final int JVM_IO_INTR = -2; - -static final int java_net_SocketOptions_SO_TIMEOUT = SocketOptions.SO_TIMEOUT; -static final int java_net_SocketOptions_SO_BINDADDR = SocketOptions.SO_BINDADDR; -static final int java_net_SocketOptions_SO_SNDBUF = SocketOptions.SO_SNDBUF; -static final int java_net_SocketOptions_SO_RCVBUF = SocketOptions.SO_RCVBUF; -static final int java_net_SocketOptions_IP_TOS = SocketOptions.IP_TOS; -static final int java_net_SocketOptions_SO_REUSEADDR = SocketOptions.SO_REUSEADDR; -static final int java_net_SocketOptions_TCP_NODELAY = SocketOptions.TCP_NODELAY; -static final int java_net_SocketOptions_SO_OOBINLINE = SocketOptions.SO_OOBINLINE; -static final int java_net_SocketOptions_SO_KEEPALIVE = SocketOptions.SO_KEEPALIVE; -static final int java_net_SocketOptions_SO_LINGER = SocketOptions.SO_LINGER; - -/* -#include <windows.h> -#include <winsock2.h> -#include <ctype.h> -#include <stdio.h> -#include <stdlib.h> -#include <malloc.h> -#include <sys/types.h> - -#include "java_net_SocketOptions.h" -#include "java_net_TwoStacksPlainSocketImpl.h" -#include "java_net_SocketImpl.h" -#include "java_net_InetAddress.h" -#include "java_io_FileDescriptor.h" -#include "java_lang_Integer.h" - -#include "jvm.h" -#include "net_util.h" -#include "jni_util.h" -*/ - -/************************************************************************ - * TwoStacksPlainSocketImpl - */ - -/* -static jfieldID IO_fd_fdID; - -jfieldID psi_fdID; -jfieldID psi_fd1ID; -jfieldID psi_addressID; -jfieldID psi_portID; -jfieldID psi_localportID; -jfieldID psi_timeoutID; -jfieldID psi_trafficClassID; -jfieldID psi_serverSocketID; -jfieldID psi_lastfdID; -*/ - -/* - * the level of the TCP protocol for setsockopt and getsockopt - * we only want to look this up once, from the static initializer - * of TwoStacksPlainSocketImpl - */ -static int tcp_level = -1; - -static cli.System.Net.Sockets.Socket getFD(JNIEnv env, TwoStacksPlainSocketImpl _this) { - FileDescriptor fdObj = _this.fd; - - if (fdObj == NULL) { - return null; - } - return fdObj.getSocket(); -} - -static cli.System.Net.Sockets.Socket getFD1(JNIEnv env, TwoStacksPlainSocketImpl _this) { - FileDescriptor fdObj = _this.fd1; - - if (fdObj == NULL) { - return null; - } - return fdObj.getSocket(); -} - - -/* - * The initProto function is called whenever TwoStacksPlainSocketImpl is - * loaded, to cache fieldIds for efficiency. This is called everytime - * the Java class is loaded. - * - * Class: java_net_TwoStacksPlainSocketImpl - * Method: initProto - - * Signature: ()V - */ -/* -JNIEXPORT void JNICALL -Java_java_net_TwoStacksPlainSocketImpl_initProto(JNIEnv *env, jclass cls) { - - struct protoent *proto = getprotobyname("TCP"); - tcp_level = (proto == 0 ? IPPROTO_TCP: proto->p_proto); - - psi_fdID = (*env)->GetFieldID(env, cls , "fd", "Ljava/io/FileDescriptor;"); - CHECK_NULL(psi_fdID); - psi_fd1ID =(*env)->GetFieldID(env, cls , "fd1", "Ljava/io/FileDescriptor;"); - CHECK_NULL(psi_fd1ID); - psi_addressID = (*env)->GetFieldID(env, cls, "address", - "Ljava/net/InetAddress;"); - CHECK_NULL(psi_addressID); - psi_portID = (*env)->GetFieldID(env, cls, "port", "I"); - CHECK_NULL(psi_portID); - psi_lastfdID = (*env)->GetFieldID(env, cls, "lastfd", "I"); - CHECK_NULL(psi_portID); - psi_localportID = (*env)->GetFieldID(env, cls, "localport", "I"); - CHECK_NULL(psi_localportID); - psi_timeoutID = (*env)->GetFieldID(env, cls, "timeout", "I"); - CHECK_NULL(psi_timeoutID); - psi_trafficClassID = (*env)->GetFieldID(env, cls, "trafficClass", "I"); - CHECK_NULL(psi_trafficClassID); - psi_serverSocketID = (*env)->GetFieldID(env, cls, "serverSocket", - "Ljava/net/ServerSocket;"); - CHECK_NULL(psi_serverSocketID); - IO_fd_fdID = NET_GetFileDescriptorID(env); - CHECK_NULL(IO_fd_fdID); -} -*/ - -/* - * Class: java_net_TwoStacksPlainSocketImpl - * Method: socketCreate - * Signature: (Z)V - */ -static void socketCreate(JNIEnv env, TwoStacksPlainSocketImpl _this, boolean stream) { - FileDescriptor fdObj = _this.fd; - FileDescriptor fd1Obj = _this.fd1; - cli.System.Net.Sockets.Socket fd = null; - cli.System.Net.Sockets.Socket fd1 = null; - - if (IS_NULL(fdObj)) { - JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", - "null fd object"); - return; - } - fd = socket(AF_INET, (stream ? SOCK_STREAM: SOCK_DGRAM), 0); - if (fd == INVALID_SOCKET) { - NET_ThrowCurrent(env, "create"); - return; - } else { - /* Set socket attribute so it is not passed to any child process */ - //SetHandleInformation((HANDLE)(UINT_PTR)fd, HANDLE_FLAG_INHERIT, FALSE); - fdObj.setSocket(fd); - } - if (ipv6_available()) { - - if (IS_NULL(fd1Obj)) { - JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", - "null fd1 object"); - fdObj.setSocket(null); - NET_SocketClose(fd); - return; - } - fd1 = socket(AF_INET6, (stream ? SOCK_STREAM: SOCK_DGRAM), 0); - if (fd1 == INVALID_SOCKET) { - NET_ThrowCurrent(env, "create"); - fdObj.setSocket(null); - NET_SocketClose(fd); - return; - } else { - fd1Obj.setSocket(fd1); - } - } else { - _this.fd1 = null; - } -} - -/* - * inetAddress is the address object passed to the socket connect - * call. - * - * Class: java_net_TwoStacksPlainSocketImpl - * Method: socketConnect - * Signature: (Ljava/net/InetAddress;I)V - */ -static void socketConnect(JNIEnv env, TwoStacksPlainSocketImpl _this, InetAddress iaObj, int port, int timeout) -{ - int localport = _this.localport; - - /* family and localport are int fields of iaObj */ - int family; - cli.System.Net.Sockets.Socket fd = null; - cli.System.Net.Sockets.Socket fd1 = null; - boolean ipv6_supported = ipv6_available(); - - /* fd initially points to the IPv4 socket and fd1 to the IPv6 socket - * If we want to connect to IPv6 then we swap the two sockets/objects - * This way, fd is always the connected socket, and fd1 always gets closed. - */ - FileDescriptor fdObj = _this.fd; - FileDescriptor fd1Obj = _this.fd1; - - SOCKETADDRESS him; - him = new SOCKETADDRESS(); - - /* The result of the connection */ - int connect_res; - - if (!IS_NULL(fdObj)) { - fd = fdObj.getSocket(); - } - - if (ipv6_supported && !IS_NULL(fd1Obj)) { - fd1 = fd1Obj.getSocket(); - } - - if (IS_NULL(iaObj)) { - JNU_ThrowNullPointerException(env, "inet address argument is null."); - return; - } - - if (NET_InetAddressToSockaddr(env, iaObj, port, him, JNI_FALSE) != 0) { - return; - } - - family = him.him.sa_family; - if (family == AF_INET6) { - if (!ipv6_supported) { - JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", - "Protocol family not supported"); - return; - } else { - if (fd1 == null) { - JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", - "Destination unreachable"); - return; - } - /* close the v4 socket, and set fd to be the v6 socket */ - _this.fd = fd1Obj; - _this.fd1 = null; - NET_SocketClose(fd); - fd = fd1; fdObj = fd1Obj; - } - } else { - if (fd1 != null) { - fd1Obj.setSocket(null); - NET_SocketClose(fd1); - } - if (fd == null) { - JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", - "Destination unreachable"); - return; - } - } - _this.fd1 = null; - - if (timeout <= 0) { - connect_res = connect(fd, him); - if (connect_res == SOCKET_ERROR) { - connect_res = WSAGetLastError(); - } - } else { - int optval; - - /* make socket non-blocking */ - optval = 1; - ioctlsocket( fd, FIONBIO, optval ); - - /* initiate the connect */ - connect_res = connect(fd, him); - if (connect_res == SOCKET_ERROR) { - if (WSAGetLastError() != WSAEWOULDBLOCK) { - connect_res = WSAGetLastError(); - } else { - fd_set wr, ex; - 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); - t.tv_sec = timeout / 1000; - t.tv_usec = (timeout % 1000) * 1000; - - /* - * Wait for timout, connection established or - * connection failed. - */ - connect_res = select(null, wr, ex, t); - - /* - * Timeout before connection is established/failed so - * we throw exception and shutdown input/output to prevent - * socket from being used. - * The socket should be closed immediately by the caller. - */ - if (connect_res == 0) { - JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketTimeoutException", - "connect timed out"); - shutdown( fd, SD_BOTH ); - - /* make socket blocking again - just in case */ - optval = 0; - ioctlsocket( fd, FIONBIO, optval ); - return; - } - - /* - * We must now determine if the connection has been established - * or if it has failed. The logic here is designed to work around - * bug on Windows NT whereby using getsockopt to obtain the - * last error (SO_ERROR) indicates there is no error. The workaround - * on NT is to allow winsock to be scheduled and this is done by - * yielding and retrying. As yielding is problematic in heavy - * load conditions we attempt up to 3 times to get the error reason. - */ - if (!FD_ISSET(fd, ex)) { - connect_res = 0; - } else { - int retry; - for (retry=0; retry<3; retry++) { - int[] tmp = { 0 }; - NET_GetSockOpt(fd, SOL_SOCKET, SO_ERROR, - tmp); - connect_res = tmp[0]; - if (connect_res != 0) { - break; - } - Sleep(0); - } - - if (connect_res == 0) { - JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", - "Unable to establish connection"); - return; - } - } - } - } - - /* make socket blocking again */ - optval = 0; - ioctlsocket(fd, FIONBIO, optval); - } - - if (connect_res != 0) { - if (connect_res == WSAEADDRNOTAVAIL) { - 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, connect_res, "connect"); - } - return; - } - - fdObj.setSocket(fd); - - /* set the remote peer address and port */ - _this.address = iaObj; - _this.port = port; - - /* - * we need to initialize the local port field if bind was called - * previously to the connect (by the client) then localport field - * will already be initialized - */ - if (localport == 0) { - /* Now that we're a connected socket, let's extract the port number - * that the system chose for us and store it in the Socket object. - */ - if (getsockname(fd, him) == -1) { - - if (WSAGetLastError() == WSAENOTSOCK) { - JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", - "Socket closed"); - } else { - NET_ThrowCurrent(env, "getsockname failed"); - } - return; - } - port = ntohs (GET_PORT(him)); - _this.localport = port; - } -} - -/* - * Class: java_net_TwoStacksPlainSocketImpl - * Method: socketBind - * Signature: (Ljava/net/InetAddress;I)V - */ -static void socketBind(JNIEnv env, TwoStacksPlainSocketImpl _this, - InetAddress iaObj, int localport, - boolean exclBind) { - FileDescriptor fdObj = _this.fd; - FileDescriptor fd1Obj = _this.fd1; - cli.System.Net.Sockets.Socket fd = null; - cli.System.Net.Sockets.Socket fd1 = null; - boolean ipv6_supported = ipv6_available(); - - /* family is an int field of iaObj */ - int family; - int rv; - - SOCKETADDRESS him; - him = new SOCKETADDRESS(); - - family = getInetAddress_family(env, iaObj); - - if (family == IPv6 && !ipv6_supported) { - JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", - "Protocol family not supported"); - return; - } - - if (IS_NULL(fdObj) || (ipv6_supported && IS_NULL(fd1Obj))) { - JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", - "Socket closed"); - return; - } else { - fd = fdObj.getSocket(); - if (ipv6_supported) { - fd1 = fd1Obj.getSocket(); - } - } - if (IS_NULL(iaObj)) { - JNU_ThrowNullPointerException(env, "inet address argument"); - return; - } - - if (NET_InetAddressToSockaddr(env, iaObj, localport, - him, JNI_FALSE) != 0) { - return; - } - if (ipv6_supported) { - ipv6bind v6bind = new ipv6bind(); - v6bind.addr = him; - v6bind.ipv4_fd = fd; - v6bind.ipv6_fd = fd1; - rv = NET_BindV6(v6bind, exclBind); - if (rv != -1) { - /* check if the fds have changed */ - if (v6bind.ipv4_fd != fd) { - fd = v6bind.ipv4_fd; - if (fd == null) { - /* socket is closed. */ - _this.fd = null; - } else { - /* socket was re-created */ - fdObj.setSocket(fd); - } - } - if (v6bind.ipv6_fd != fd1) { - fd1 = v6bind.ipv6_fd; - if (fd1 == null) { - /* socket is closed. */ - _this.fd1 = null; - } else { - /* socket was re-created */ - fd1Obj.setSocket(fd1); - } - } - } - } else { - rv = NET_WinBind(fd, him, exclBind); - } - - if (rv == -1) { - NET_ThrowCurrent(env, "JVM_Bind"); - return; - } - - /* set the address */ - _this.address = iaObj; - - /* intialize the local port */ - if (localport == 0) { - /* Now that we're a bound socket, let's extract the port number - * that the system chose for us and store it in the Socket object. - */ - int port; - fd = him.him.sa_family == AF_INET? fd: fd1; - - if (getsockname(fd, him) == -1) { - NET_ThrowCurrent(env, "getsockname in plain socketBind"); - return; - } - port = ntohs (GET_PORT (him)); - - _this.localport = port; - } else { - _this.localport = localport; - } -} - -/* - * Class: java_net_TwoStacksPlainSocketImpl - * Method: socketListen - * Signature: (I)V - */ -static void socketListen (JNIEnv env, TwoStacksPlainSocketImpl _this, int count) -{ - /* this FileDescriptor fd field */ - FileDescriptor fdObj = _this.fd; - FileDescriptor fd1Obj = _this.fd1; - InetAddress address; - /* fdObj's int fd field */ - cli.System.Net.Sockets.Socket fd = null; - cli.System.Net.Sockets.Socket fd1 = null; - SOCKETADDRESS addr = new SOCKETADDRESS(); - - if (IS_NULL(fdObj) && IS_NULL(fd1Obj)) { - JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", - "socket closed"); - return; - } - - if (!IS_NULL(fdObj)) { - fd = fdObj.getSocket(); - } - /* Listen on V4 if address type is v4 or if v6 and address is ::0. - * Listen on V6 if address type is v6 or if v4 and address is 0.0.0.0. - * In cases, where we listen on one space only, we close the other socket. - */ - address = _this.address; - if (IS_NULL(address)) { - JNU_ThrowNullPointerException(env, "socket address"); - return; - } - if (NET_InetAddressToSockaddr(env, address, 0, addr, - JNI_FALSE) != 0) { - return; - } - - if (addr.him.sa_family == AF_INET || IN6ADDR_ISANY(addr.him6)) { - /* listen on v4 */ - if (listen(fd, count) == -1) { - NET_ThrowCurrent(env, "listen failed"); - } - } else { - NET_SocketClose (fd); - _this.fd = null; - } - if (ipv6_available() && !IS_NULL(fd1Obj)) { - fd1 = fd1Obj.getSocket(); - if (addr.him.sa_family == AF_INET6 || addr.him4.sin_addr.s_addr == INADDR_ANY) { - /* listen on v6 */ - if (listen(fd1, count) == -1) { - NET_ThrowCurrent(env, "listen failed"); - } - } else { - NET_SocketClose (fd1); - _this.fd1 = null; - } - } -} - -/* - * Class: java_net_TwoStacksPlainSocketImpl - * Method: socketAccept - * Signature: (Ljava/net/SocketImpl;)V - */ -static void socketAccept(JNIEnv env, TwoStacksPlainSocketImpl _this, SocketImpl socket) -{ - /* fields on this */ - int port; - int timeout = _this.timeout; - FileDescriptor fdObj = _this.fd; - FileDescriptor fd1Obj = _this.fd1; - - /* the FileDescriptor field on socket */ - FileDescriptor socketFdObj; - - /* the InetAddress field on socket */ - InetAddress socketAddressObj; - - /* the fd int field on fdObj */ - cli.System.Net.Sockets.Socket fd=null, fd1=null; - - SOCKETADDRESS him; - him = new SOCKETADDRESS(); - - if (IS_NULL(fdObj) && IS_NULL(fd1Obj)) { - JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", - "Socket closed"); - return; - } - if (!IS_NULL(fdObj)) { - fd = fdObj.getSocket(); - } - if (!IS_NULL(fd1Obj)) { - fd1 = fd1Obj.getSocket(); - } - if (IS_NULL(socket)) { - JNU_ThrowNullPointerException(env, "socket is null"); - return; - } else { - socketFdObj = socket.fd; - socketAddressObj = socket.address; - } - if ((IS_NULL(socketAddressObj)) || (IS_NULL(socketFdObj))) { - JNU_ThrowNullPointerException(env, "socket address or fd obj"); - return; - } - if (fd != null && fd1 != null) { - fd_set rfds = new fd_set(); - timeval t = new timeval(); - cli.System.Net.Sockets.Socket lastfd, fd2; - FD_ZERO(rfds); - FD_SET(fd,rfds); - FD_SET(fd1,rfds); - if (timeout != 0) { - t.tv_sec = timeout/1000; - t.tv_usec = (timeout%1000)*1000; - } else { - t = null; - } - int res = select (rfds, null, null, t); - if (res == 0) { - JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketTimeoutException", - "Accept timed out"); - return; - } else if (res == 1) { - fd2 = FD_ISSET(fd, rfds)? fd: fd1; - } else if (res == 2) { - /* avoid starvation */ - lastfd = _this.lastfd; - if (lastfd != null) { - fd2 = lastfd==fd? fd1: fd; - } else { - fd2 = fd; - } - _this.lastfd = fd2; - } else { - JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", - "select failed"); - return; - } - fd = fd2; - } else { - int ret; - if (fd1 != null) { - fd = fd1; - } - if (timeout != 0) { - ret = NET_Timeout(fd, timeout); - if (ret == 0) { - JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketTimeoutException", - "Accept timed out"); - return; - } else if (ret == -1) { - JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", "socket closed"); - /* REMIND: SOCKET CLOSED PROBLEM */ - /* NET_ThrowCurrent(env, "Accept failed"); */ - return; - } else if (ret == -2) { - JNU_ThrowByName(env, JNU_JAVAIOPKG+"InterruptedIOException", - "operation interrupted"); - return; - } - } - } - fd = accept(fd, him); - if (fd == null) { - /* REMIND: SOCKET CLOSED PROBLEM */ - if (false) { - JNU_ThrowByName(env, JNU_JAVAIOPKG+"InterruptedIOException", - "operation interrupted"); - } else { - JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", - "socket closed"); - } - return; - } - socketFdObj.setSocket(fd); - - if (him.him.sa_family == AF_INET) { - - /* - * fill up the remote peer port and address in the new socket structure - */ - socketAddressObj = new Inet4Address(null, ntohl(him.him4.sin_addr.s_addr)); - socket.address = socketAddressObj; - } else { - /* AF_INET6 -> Inet6Address */ - - // [IKVM] We need to convert scope_id 0 to -1 here, because for sin6_scope_id 0 means unspecified, whereas Java uses -1 - int scopeId = him.him6.sin6_scope_id; - socketAddressObj = new Inet6Address(null, him.him6.sin6_addr, scopeId == 0 ? -1 : scopeId); - } - /* fields common to AF_INET and AF_INET6 */ - - port = ntohs (GET_PORT (him)); - socket.port = port; - port = _this.localport; - socket.localport = port; - socket.address = socketAddressObj; -} - -/* - * Class: java_net_TwoStacksPlainSocketImpl - * Method: socketAvailable - * Signature: ()I - */ -static int socketAvailable(JNIEnv env, TwoStacksPlainSocketImpl _this) { - - int[] available = { -1 }; - int res; - FileDescriptor fdObj = _this.fd; - cli.System.Net.Sockets.Socket fd; - - if (IS_NULL(fdObj)) { - JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", "Socket closed"); - return -1; - } else { - fd = fdObj.getSocket(); - } - res = ioctlsocket(fd, FIONREAD, available); - /* if result isn't 0, it means an error */ - if (res != 0) { - NET_ThrowNew(env, res, "socket available"); - } - return available[0]; -} - -/* - * Class: java_net_TwoStacksPlainSocketImpl - * Method: socketClose - * Signature: ()V - */ -static void socketClose0(JNIEnv env, TwoStacksPlainSocketImpl _this, boolean useDeferredClose) { - - FileDescriptor fdObj = _this.fd; - FileDescriptor fd1Obj = _this.fd1; - cli.System.Net.Sockets.Socket fd = null; - cli.System.Net.Sockets.Socket fd1 = null; - - if (IS_NULL(fdObj) && IS_NULL(fd1Obj)) { - JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", - "socket already closed"); - return; - } - if (!IS_NULL(fdObj)) { - fd = fdObj.getSocket(); - } - if (!IS_NULL(fd1Obj)) { - fd1 = fd1Obj.getSocket(); - } - if (fd != null) { - fdObj.setSocket(null); - NET_SocketClose(fd); - } - if (fd1 != null) { - fd1Obj.setSocket(null); - NET_SocketClose(fd1); - } -} - -/* - * Socket options for plainsocketImpl - * - * - * Class: java_net_TwoStacksPlainSocketImpl - * Method: socketNativeSetOption - * Signature: (IZLjava/lang/Object;)V - */ -static void socketNativeSetOption(JNIEnv env, TwoStacksPlainSocketImpl _this, int cmd, boolean on, Object value) { - cli.System.Net.Sockets.Socket fd, fd1; - int[] level = new int[1]; - int[] optname = new int[1]; - Object optval; - - /* - * Get SOCKET and check that it hasn't been closed - */ - fd = getFD(env, _this); - fd1 = getFD1(env, _this); - if (fd == null && fd1 == null) { - JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", "Socket closed"); - return; - } - - /* - * SO_TIMEOUT is the socket option used to specify the timeout - * for ServerSocket.accept and Socket.getInputStream().read. - * It does not typically map to a native level socket option. - * For Windows we special-case this and use the SOL_SOCKET/SO_RCVTIMEO - * socket option to specify a receive timeout on the socket. This - * receive timeout is applicable to Socket only and the socket - * option should not be set on ServerSocket. - */ - if (cmd == java_net_SocketOptions_SO_TIMEOUT) { - - /* - * Don't enable the socket option on ServerSocket as it's - * meaningless (we don't receive on a ServerSocket). - */ - Object ssObj = _this.serverSocket; - if (ssObj != NULL) { - return; - } - - /* - * SO_RCVTIMEO is only supported on Microsoft's implementation - * of Windows Sockets so if WSAENOPROTOOPT returned then - * reset flag and timeout will be implemented using - * select() -- see SocketInputStream.socketRead. - */ - if (isRcvTimeoutSupported) { - int timeout = ((Integer)value).intValue(); - - /* - * Disable SO_RCVTIMEO if timeout is <= 5 second. - */ - if (timeout <= 5000) { - timeout = 0; - } - - if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, timeout) < 0) { - if (WSAGetLastError() == WSAENOPROTOOPT) { - isRcvTimeoutSupported = JNI_FALSE; - } else { - NET_ThrowCurrent(env, "setsockopt SO_RCVTIMEO"); - } - } - if (fd1 != null) { - if (setsockopt(fd1, SOL_SOCKET, SO_RCVTIMEO, timeout) < 0) { - NET_ThrowCurrent(env, "setsockopt SO_RCVTIMEO"); - } - } - } - return; - } - - /* - * Map the Java level socket option to the platform specific - * level - */ - if (NET_MapSocketOption(cmd, level, optname) != 0) { - JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", - "Invalid option"); - return; - } - - 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 : - optval = on; - break; - - case java_net_SocketOptions_SO_SNDBUF : - case java_net_SocketOptions_SO_RCVBUF : - case java_net_SocketOptions_IP_TOS : - optval = ((Integer)value).intValue(); - break; - - case java_net_SocketOptions_SO_LINGER : - { - linger ling = new linger(); - if (on) { - ling.l_onoff = 1; - ling.l_linger = ((Integer)value).intValue(); - } else { - ling.l_onoff = 0; - ling.l_linger = 0; - } - optval = ling; - } - break; - - default: /* shouldn't get here */ - JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", - "Option not supported by TwoStacksPlainSocketImpl"); - return; - } - - if (fd != null) { - if (NET_SetSockOpt(fd, level[0], optname[0], optval) < 0) { - NET_ThrowCurrent(env, "setsockopt"); - } - } - - if (fd1 != null) { - if (NET_SetSockOpt(fd1, level[0], optname[0], optval) < 0) { - NET_ThrowCurrent(env, "setsockopt"); - } - } -} - - -/* - * Class: java_net_TwoStacksPlainSocketImpl - * Method: socketGetOption - * Signature: (I)I - */ -static int socketGetOption(JNIEnv env, TwoStacksPlainSocketImpl _this, int opt, Object iaContainerObj) { - - cli.System.Net.Sockets.Socket fd, fd1; - int[] level = new int[1]; - int[] optname = new int[1]; - Object optval; - - /* - * Get SOCKET and check it hasn't been closed - */ - fd = getFD(env, _this); - fd1 = getFD1(env, _this); - - if (fd == null && fd1 == null) { - JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", "Socket closed"); - return -1; - } - if (fd == null) { - fd = fd1; - } - - /* For IPv6, we assume both sockets have the same setting always */ - - /* - * SO_BINDADDR isn't a socket option - */ - if (opt == java_net_SocketOptions_SO_BINDADDR) { - SOCKETADDRESS him; - him = new SOCKETADDRESS(); - int[] port = { 0 }; - InetAddress iaObj; - - if (fd == null) { - /* must be an IPV6 only socket. Case where both sockets are != -1 - * is handled in java - */ - fd = getFD1 (env, _this); - } - - if (getsockname(fd, him) < 0) { - NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG+"SocketException", - "Error getting socket name"); - return -1; - } - iaObj = NET_SockaddrToInetAddress(him, port); - ((InetAddressContainer)iaContainerObj).addr = 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) != 0) { - JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", "Invalid option"); - return -1; - } - - /* - * Args are int except for SO_LINGER - */ - if (opt == java_net_SocketOptions_SO_LINGER) { - optval = new linger(); - } else { - optval = new int[1]; - } - - if (NET_GetSockOpt(fd, level[0], optname[0], optval) < 0) { - NET_ThrowCurrent(env, "getsockopt"); - return -1; - } - - switch (opt) { - case java_net_SocketOptions_SO_LINGER: - return (((linger)optval).l_onoff != 0 ? ((linger)optval).l_linger: -1); - - case java_net_SocketOptions_SO_SNDBUF: - case java_net_SocketOptions_SO_RCVBUF: - case java_net_SocketOptions_IP_TOS: - return ((int[])optval)[0]; - - 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 (((int[])optval)[0] == 0) ? -1 : 1; - - default: /* shouldn't get here */ - JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", - "Option not supported by TwoStacksPlainSocketImpl"); - return -1; - } -} - -/* - * Class: java_net_TwoStacksPlainSocketImpl - * Method: socketShutdown - * Signature: (I)V - */ -static void socketShutdown(JNIEnv env, TwoStacksPlainSocketImpl _this, int howto) -{ - - FileDescriptor fdObj = _this.fd; - cli.System.Net.Sockets.Socket fd; - - /* - * WARNING: THIS NEEDS LOCKING. ALSO: SHOULD WE CHECK for fd being - * -1 already? - */ - if (IS_NULL(fdObj)) { - JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", - "socket already closed"); - return; - } else { - fd = fdObj.getSocket(); - } - shutdown(fd, howto); -} - -/* - * Class: java_net_TwoStacksPlainSocketImpl - * Method: socketSendUrgentData - * Signature: (B)V - */ -static void socketSendUrgentData(JNIEnv env, TwoStacksPlainSocketImpl _this, int data) { - /* The fd field */ - FileDescriptor fdObj = _this.fd; - int n; - cli.System.Net.Sockets.Socket fd; - - if (IS_NULL(fdObj)) { - JNU_ThrowByName(env, "java/net/SocketException", "Socket closed"); - return; - } else { - fd = fdObj.getSocket(); - /* Bug 4086704 - If the Socket associated with this file descriptor - * was closed (sysCloseFD), the the file descriptor is set to -1. - */ - if (fd == null) { - JNU_ThrowByName(env, "java/net/SocketException", "Socket closed"); - return; - } - - } - n = send(fd, new byte[] { (byte)data }, 1, MSG_OOB); - if (n == JVM_IO_ERR) { - NET_ThrowCurrent(env, "send"); - return; - } - if (n == JVM_IO_INTR) { - JNU_ThrowByName(env, "java/io/InterruptedIOException", null); - return; - } -} -} |