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

github.com/mono/ikvm-fork.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiguel de Icaza <miguel@gnome.org>2016-02-27 23:38:24 +0300
committerMiguel de Icaza <miguel@gnome.org>2016-02-27 23:38:24 +0300
commit94d4a298ad560f8674d746dea2d51e26e0a97f2a (patch)
treeae303637d83843abf98938b07eb9808880cea9fa /openjdk/java/net
parentc9edfe788667d5777e97e3f2fd195080d06dd32c (diff)
Remove unused filesmaster-signed
Diffstat (limited to 'openjdk/java/net')
-rw-r--r--openjdk/java/net/DefaultDatagramSocketImplFactory.java151
-rw-r--r--openjdk/java/net/DualStackPlainDatagramSocketImpl.java334
-rw-r--r--openjdk/java/net/DualStackPlainDatagramSocketImpl_c.java488
-rw-r--r--openjdk/java/net/DualStackPlainSocketImpl.java360
-rw-r--r--openjdk/java/net/DualStackPlainSocketImpl_c.java490
-rw-r--r--openjdk/java/net/PlainSocketImpl.java356
-rw-r--r--openjdk/java/net/SocketInputStream.java332
-rw-r--r--openjdk/java/net/SocketOutputStream.java254
-rw-r--r--openjdk/java/net/SocketUtil.java190
-rw-r--r--openjdk/java/net/TwoStacksPlainDatagramSocketImpl.java269
-rw-r--r--openjdk/java/net/TwoStacksPlainDatagramSocketImpl_c.java2463
-rw-r--r--openjdk/java/net/TwoStacksPlainSocketImpl.java285
-rw-r--r--openjdk/java/net/TwoStacksPlainSocketImpl_c.java1080
-rw-r--r--openjdk/java/net/net_util_md.java884
14 files changed, 0 insertions, 7936 deletions
diff --git a/openjdk/java/net/DefaultDatagramSocketImplFactory.java b/openjdk/java/net/DefaultDatagramSocketImplFactory.java
deleted file mode 100644
index 7d4f8edb..00000000
--- a/openjdk/java/net/DefaultDatagramSocketImplFactory.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (c) 2007, 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.security.AccessController;
-import java.security.PrivilegedAction;
-
-/**
- * This class defines a factory for creating DatagramSocketImpls. It defaults
- * to creating plain DatagramSocketImpls, but may create other DatagramSocketImpls
- * by setting the impl.prefix system property.
- *
- * For Windows versions lower than Windows Vista a TwoStacksPlainDatagramSocketImpl
- * is always created. This impl supports IPv6 on these platform where available.
- *
- * On Windows platforms greater than Vista that support a dual layer TCP/IP stack
- * a DualStackPlainDatagramSocketImpl is created for DatagramSockets. For MulticastSockets
- * a TwoStacksPlainDatagramSocketImpl is always created. This is to overcome the lack
- * of behavior defined for multicasting over a dual layer socket by the RFC.
- *
- * @author Chris Hegarty
- */
-
-class DefaultDatagramSocketImplFactory
-{
- static Class prefixImplClass = null;
-
- /* the windows version. */
- private static float version;
-
- /* java.net.preferIPv4Stack */
- private static boolean preferIPv4Stack = false;
-
- /* If the version supports a dual stack TCP implementation */
- private static boolean useDualStackImpl = false;
-
- /* sun.net.useExclusiveBind */
- private static String exclBindProp;
-
- /* True if exclusive binding is on for Windows */
- private static boolean exclusiveBind = true;
-
-
- static {
- // Determine Windows Version.
- java.security.AccessController.doPrivileged(
- new PrivilegedAction<Object>() {
- public Object run() {
- version = 0;
- try {
- version = Float.parseFloat(System.getProperties()
- .getProperty("os.version"));
- preferIPv4Stack = Boolean.parseBoolean(
- System.getProperties()
- .getProperty(
- "java.net.preferIPv4Stack"));
- exclBindProp = System.getProperty(
- "sun.net.useExclusiveBind");
- } catch (NumberFormatException e ) {
- assert false : e;
- }
- return null; // nothing to return
- }
- });
-
- String ipv6 = ikvm.internal.Util.SafeGetEnvironmentVariable("IKVM_IPV6");
- if (ipv6 != null) {
- try {
- if ((Integer.parseInt(ipv6) & 4) == 0) {
- preferIPv4Stack = true;
- } else {
- useDualStackImpl = true;
- }
- } catch (NumberFormatException _) {
- }
- } else if (!InetAddressImplFactory.isIPv6Supported()) {
- preferIPv4Stack = true;
- }
-
- // (version >= 6.0) implies Vista or greater.
- if (version >= 6.0 && !preferIPv4Stack) {
- useDualStackImpl = true;
- }
- if (exclBindProp != null) {
- // sun.net.useExclusiveBind is true
- exclusiveBind = exclBindProp.length() == 0 ? true
- : Boolean.parseBoolean(exclBindProp);
- } else if (version < 6.0) {
- exclusiveBind = false;
- }
-
- // impl.prefix
- String prefix = null;
- try {
- prefix = AccessController.doPrivileged(
- new sun.security.action.GetPropertyAction("impl.prefix", null));
- if (prefix != null)
- prefixImplClass = Class.forName("java.net."+prefix+"DatagramSocketImpl");
- } catch (Exception e) {
- System.err.println("Can't find class: java.net." +
- prefix +
- "DatagramSocketImpl: check impl.prefix property");
- }
- }
-
- /**
- * Creates a new <code>DatagramSocketImpl</code> instance.
- *
- * @param isMulticast true if this impl is to be used for a MutlicastSocket
- * @return a new instance of <code>PlainDatagramSocketImpl</code>.
- */
- static DatagramSocketImpl createDatagramSocketImpl(boolean isMulticast)
- throws SocketException {
- if (prefixImplClass != null) {
- try {
- return (DatagramSocketImpl) prefixImplClass.newInstance();
- } catch (Exception e) {
- throw new SocketException("can't instantiate DatagramSocketImpl");
- }
- } else {
- if (isMulticast)
- exclusiveBind = false;
- if (useDualStackImpl && !isMulticast)
- return new DualStackPlainDatagramSocketImpl(exclusiveBind);
- else
- return new TwoStacksPlainDatagramSocketImpl(exclusiveBind);
- }
- }
-}
diff --git a/openjdk/java/net/DualStackPlainDatagramSocketImpl.java b/openjdk/java/net/DualStackPlainDatagramSocketImpl.java
deleted file mode 100644
index 1d74e28c..00000000
--- a/openjdk/java/net/DualStackPlainDatagramSocketImpl.java
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- * Copyright (c) 2007, 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.IOException;
-
-/**
- * This class defines the plain DatagramSocketImpl that is used on
- * Windows platforms greater than or equal to Windows Vista. These
- * platforms have a dual layer TCP/IP stack and can handle both IPv4
- * and IPV6 through a single file descriptor.
- * <p>
- * Note: Multicasting on a dual layer TCP/IP stack is always done with
- * TwoStacksPlainDatagramSocketImpl. This is to overcome the lack
- * of behavior defined for multicasting over a dual layer socket by the RFC.
- *
- * @author Chris Hegarty
- */
-
-class DualStackPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl
-{
-
- // true if this socket is exclusively bound
- private final boolean exclusiveBind;
-
- /*
- * Set to true if SO_REUSEADDR is set after the socket is bound to
- * indicate SO_REUSEADDR is being emulated
- */
- private boolean reuseAddressEmulated;
-
- // emulates SO_REUSEADDR when exclusiveBind is true and socket is bound
- private boolean isReuseAddress;
-
- DualStackPlainDatagramSocketImpl(boolean exclBind) {
- exclusiveBind = exclBind;
- }
-
- protected void datagramSocketCreate() throws SocketException {
- if (fd == null)
- throw new SocketException("Socket closed");
-
- cli.System.Net.Sockets.Socket newfd = socketCreate(false /* v6Only */);
-
- fd.setSocket(newfd);
- }
-
- protected synchronized void bind0(int lport, InetAddress laddr)
- throws SocketException {
- cli.System.Net.Sockets.Socket nativefd = checkAndReturnNativeFD();
-
- if (laddr == null)
- throw new NullPointerException("argument address");
-
- socketBind(nativefd, laddr, lport, exclusiveBind);
- if (lport == 0) {
- localPort = socketLocalPort(nativefd);
- } else {
- localPort = lport;
- }
- }
-
- protected synchronized int peek(InetAddress address) throws IOException {
- cli.System.Net.Sockets.Socket nativefd = checkAndReturnNativeFD();
-
- if (address == null)
- throw new NullPointerException("Null address in peek()");
-
- // Use peekData()
- DatagramPacket peekPacket = new DatagramPacket(new byte[1], 1);
- int peekPort = peekData(peekPacket);
- address = peekPacket.getAddress();
- return peekPort;
- }
-
- protected synchronized int peekData(DatagramPacket p) throws IOException {
- cli.System.Net.Sockets.Socket nativefd = checkAndReturnNativeFD();
-
- if (p == null)
- throw new NullPointerException("packet");
- if (p.getData() == null)
- throw new NullPointerException("packet buffer");
-
- return socketReceiveOrPeekData(nativefd, p, timeout, connected, true /*peek*/);
- }
-
- protected synchronized void receive0(DatagramPacket p) throws IOException {
- cli.System.Net.Sockets.Socket nativefd = checkAndReturnNativeFD();
-
- if (p == null)
- throw new NullPointerException("packet");
- if (p.getData() == null)
- throw new NullPointerException("packet buffer");
-
- socketReceiveOrPeekData(nativefd, p, timeout, connected, false /*receive*/);
- }
-
- protected void send(DatagramPacket p) throws IOException {
- cli.System.Net.Sockets.Socket nativefd = checkAndReturnNativeFD();
-
- if (p == null)
- throw new NullPointerException("null packet");
-
- if (p.getAddress() == null ||p.getData() ==null)
- throw new NullPointerException("null address || null buffer");
-
- socketSend(nativefd, p.getData(), p.getOffset(), p.getLength(),
- p.getAddress(), p.getPort(), connected);
- }
-
- protected void connect0(InetAddress address, int port) throws SocketException {
- cli.System.Net.Sockets.Socket nativefd = checkAndReturnNativeFD();
-
- if (address == null)
- throw new NullPointerException("address");
-
- socketConnect(nativefd, address, port);
- }
-
- protected void disconnect0(int family /*unused*/) {
- if (fd == null || !fd.valid())
- return; // disconnect doesn't throw any exceptions
-
- socketDisconnect(fd.getSocket());
- }
-
- protected void datagramSocketClose() {
- if (fd == null || !fd.valid())
- return; // close doesn't throw any exceptions
-
- socketClose(fd.getSocket());
- fd.setSocket(null);
- }
-
- @SuppressWarnings("fallthrough")
- protected void socketSetOption(int opt, Object val) throws SocketException {
- cli.System.Net.Sockets.Socket nativefd = checkAndReturnNativeFD();
-
- int optionValue = 0;
-
- switch(opt) {
- case IP_TOS :
- case SO_RCVBUF :
- case SO_SNDBUF :
- optionValue = ((Integer)val).intValue();
- break;
- case SO_REUSEADDR :
- if (exclusiveBind && localPort != 0) {
- // socket already bound, emulate SO_REUSEADDR
- reuseAddressEmulated = true;
- isReuseAddress = (Boolean)val;
- return;
- }
- //Intentional fallthrough
- case SO_BROADCAST :
- optionValue = ((Boolean)val).booleanValue() ? 1 : 0;
- break;
- default: /* shouldn't get here */
- throw new SocketException("Option not supported");
- }
-
- socketSetIntOption(nativefd, opt, optionValue);
- }
-
- protected Object socketGetOption(int opt) throws SocketException {
- cli.System.Net.Sockets.Socket nativefd = checkAndReturnNativeFD();
-
- // SO_BINDADDR is not a socket option.
- if (opt == SO_BINDADDR) {
- return socketLocalAddress(nativefd);
- }
- if (opt == SO_REUSEADDR && reuseAddressEmulated)
- return isReuseAddress;
-
- int value = socketGetIntOption(nativefd, opt);
- Object returnValue = null;
-
- switch (opt) {
- case SO_REUSEADDR :
- case SO_BROADCAST :
- returnValue = (value == 0) ? Boolean.FALSE : Boolean.TRUE;
- break;
- case IP_TOS :
- case SO_RCVBUF :
- case SO_SNDBUF :
- returnValue = new Integer(value);
- break;
- default: /* shouldn't get here */
- throw new SocketException("Option not supported");
- }
-
- return returnValue;
- }
-
- /* Multicast specific methods.
- * Multicasting on a dual layer TCP/IP stack is always done with
- * TwoStacksPlainDatagramSocketImpl. This is to overcome the lack
- * of behavior defined for multicasting over a dual layer socket by the RFC.
- */
- protected void join(InetAddress inetaddr, NetworkInterface netIf)
- throws IOException {
- throw new IOException("Method not implemented!");
- }
-
- protected void leave(InetAddress inetaddr, NetworkInterface netIf)
- throws IOException {
- throw new IOException("Method not implemented!");
- }
-
- protected void setTimeToLive(int ttl) throws IOException {
- throw new IOException("Method not implemented!");
- }
-
- protected int getTimeToLive() throws IOException {
- throw new IOException("Method not implemented!");
- }
-
-
- protected void setTTL(byte ttl) throws IOException {
- throw new IOException("Method not implemented!");
- }
-
- protected byte getTTL() throws IOException {
- throw new IOException("Method not implemented!");
- }
- /* END Multicast specific methods */
-
- private cli.System.Net.Sockets.Socket checkAndReturnNativeFD() throws SocketException {
- if (fd == null || !fd.valid())
- throw new SocketException("Socket closed");
-
- return fd.getSocket();
- }
-
- /* Native methods */
-
- 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 void socketBind(cli.System.Net.Sockets.Socket fd, InetAddress localAddress,
- int localport, boolean exclBind) throws SocketException {
- ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
- DualStackPlainDatagramSocketImpl_c.socketBind(env, fd, localAddress, localport, exclBind);
- env.ThrowPendingException();
- }
-
- 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 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 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 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 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 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 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 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 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
deleted file mode 100644
index 1f4ed69b..00000000
--- a/openjdk/java/net/DualStackPlainDatagramSocketImpl_c.java
+++ /dev/null
@@ -1,488 +0,0 @@
-/*
- * Copyright (c) 2007, 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.*;
-
-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 <windows.h>
-#include <winsock2.h>
-#include "jni.h"
-#include "net_util.h"
-#include "java_net_DualStackPlainDatagramSocketImpl.h"
-
-/*
- * This function "purges" all outstanding ICMP port unreachable packets
- * outstanding on a socket and returns JNI_TRUE if any ICMP messages
- * have been purged. The rational for purging is to emulate normal BSD
- * behaviour whereby receiving a "connection reset" status resets the
- * socket.
- */
-static boolean purgeOutstandingICMP(JNIEnv env, cli.System.Net.Sockets.Socket fd)
-{
- 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(true) {
- if (select(tbl, null, null, t) <= 0) {
- break;
- }
- if (recvfrom(fd, buf, 1, MSG_PEEK,
- rmtaddr) != JVM_IO_ERR) {
- break;
- }
- if (WSAGetLastError() != WSAECONNRESET) {
- /* some other error - we don't care here */
- break;
- }
-
- recvfrom(fd, buf, 1, 0, rmtaddr);
- got_icmp = JNI_TRUE;
- }
-
- return got_icmp;
-}
-
-/*
- * Class: java_net_DualStackPlainDatagramSocketImpl
- * Method: socketCreate
- * Signature: (Z)I
- */
-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 = socket(AF_INET6, SOCK_DGRAM, 0);
- if (fd == INVALID_SOCKET) {
- NET_ThrowNew(env, WSAGetLastError(), "Socket creation failed");
- return null;
- }
-
- rv = setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, opt);
- if (rv == SOCKET_ERROR) {
- NET_ThrowNew(env, WSAGetLastError(), "Socket creation failed");
- return null;
- }
-
- //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
- * as connected sockets). The solution is to only enable this feature
- * when the socket is connected.
- */
- t = FALSE;
- WSAIoctl(fd ,SIO_UDP_CONNRESET ,false);
-
- return fd;
-}
-
-/*
- * Class: java_net_DualStackPlainDatagramSocketImpl
- * Method: socketBind
- * Signature: (ILjava/net/InetAddress;I)V
- */
-static void socketBind
- (JNIEnv env, cli.System.Net.Sockets.Socket fd, InetAddress iaObj, int port, boolean exclBind) {
- SOCKETADDRESS sa;
- sa = new SOCKETADDRESS();
- int rv;
-
- if (NET_InetAddressToSockaddr(env, iaObj, port, sa,
- JNI_TRUE) != 0) {
- return;
- }
- rv = NET_WinBind(fd, sa, exclBind);
-
- if (rv == SOCKET_ERROR) {
- if (WSAGetLastError() == WSAEACCES) {
- WSASetLastError(WSAEADDRINUSE);
- }
- NET_ThrowNew(env, WSAGetLastError(), "Cannot bind");
- }
-}
-
-/*
- * Class: java_net_DualStackPlainDatagramSocketImpl
- * Method: socketConnect
- * Signature: (ILjava/net/InetAddress;I)V
- */
-static void socketConnect
- (JNIEnv env, cli.System.Net.Sockets.Socket fd, InetAddress iaObj, int port) {
- SOCKETADDRESS sa;
- sa = new SOCKETADDRESS();
- int rv;
- int t = TRUE;
-
- if (NET_InetAddressToSockaddr(env, iaObj, port, sa,
- JNI_TRUE) != 0) {
- return;
- }
-
- rv = connect(fd, sa);
- if (rv == SOCKET_ERROR) {
- NET_ThrowNew(env, WSAGetLastError(), "connect");
- return;
- }
-
- /* see comment in socketCreate */
- WSAIoctl(fd, SIO_UDP_CONNRESET, true);
-}
-
-/*
- * Class: java_net_DualStackPlainDatagramSocketImpl
- * Method: socketDisconnect
- * Signature: (I)V
- */
-static void socketDisconnect
- (JNIEnv env, cli.System.Net.Sockets.Socket fd ) {
- SOCKETADDRESS sa;
- sa = new SOCKETADDRESS();
-
- connect(fd, sa);
-
- /* see comment in socketCreate */
- WSAIoctl(fd, SIO_UDP_CONNRESET, false);
-}
-
-/*
- * Class: java_net_DualStackPlainDatagramSocketImpl
- * Method: socketClose
- * Signature: (I)V
- */
-static void socketClose
- (JNIEnv env, cli.System.Net.Sockets.Socket fd) {
- NET_SocketClose(fd);
-}
-
-
-/*
- * Class: java_net_DualStackPlainDatagramSocketImpl
- * Method: socketLocalPort
- * Signature: (I)I
- */
-static int socketLocalPort
- (JNIEnv env, cli.System.Net.Sockets.Socket fd) {
- SOCKETADDRESS sa;
- sa = new SOCKETADDRESS();
-
- if (getsockname(fd, sa) == SOCKET_ERROR) {
- NET_ThrowNew(env, WSAGetLastError(), "JVM_GetSockName");
- return -1;
- }
- return ntohs(GET_PORT(sa));
-}
-
-/*
- * Class: java_net_DualStackPlainDatagramSocketImpl
- * Method: socketLocalAddress
- * Signature: (I)Ljava/lang/Object;
- */
-static InetAddress socketLocalAddress
- (JNIEnv env , cli.System.Net.Sockets.Socket fd) {
- SOCKETADDRESS sa;
- sa = new SOCKETADDRESS();
- InetAddress iaObj;
- int[] port = { 0 };
-
- if (getsockname(fd, sa) == SOCKET_ERROR) {
- NET_ThrowNew(env, WSAGetLastError(), "Error getting socket name");
- return null;
- }
-
- iaObj = NET_SockaddrToInetAddress(env, sa, port);
- return iaObj;
-}
-
-/*
- * Class: java_net_DualStackPlainDatagramSocketImpl
- * Method: socketReceiveOrPeekData
- * Signature: (ILjava/net/DatagramPacket;IZZ)I
- */
-static int socketReceiveOrPeekData
- (JNIEnv env, cli.System.Net.Sockets.Socket fd, DatagramPacket dpObj,
- int timeout, boolean connected, boolean peek) {
- SOCKETADDRESS sa;
- sa = new SOCKETADDRESS();
- int port, rv, flags=0;
- boolean retry;
- long prevTime = 0;
-
- int packetBufferOffset, packetBufferLen;
- byte[] packetBuffer;
-
- /* if we are only peeking. Called from peekData */
- if (peek) {
- flags = MSG_PEEK;
- }
-
- 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;
- }
- fullPacket = (char *)malloc(packetBufferLen);
- if (!fullPacket) {
- JNU_ThrowOutOfMemoryError(env, "Native heap allocation failed");
- return -1;
- }
- } else {
- fullPacket = &(BUF[0]);
- }
- */
-
- do {
- retry = false;
-
- 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",
- "Receive timed out");
- } else if (rv == JVM_IO_ERR) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
- "Socket closed");
- } else if (rv == JVM_IO_INTR) {
- JNU_ThrowByName(env, JNU_JAVAIOPKG+"InterruptedIOException",
- "operation interrupted");
- }
- return -1;
- }
- }
-
- /* receive the packet */
- rv = recvfrom(fd, packetBuffer, packetBufferOffset, packetBufferLen, flags,
- sa);
-
- if (rv == SOCKET_ERROR && (WSAGetLastError() == WSAECONNRESET)) {
- /* An icmp port unreachable - we must receive this as Windows
- * does not reset the state of the socket until this has been
- * received.
- */
- purgeOutstandingICMP(env, fd);
-
- if (connected) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"PortUnreachableException",
- "ICMP Port Unreachable");
- return -1;
- } else if (timeout != 0) {
- /* Adjust timeout */
- long newTime = JVM_CurrentTimeMillis(env, 0);
- timeout -= (int)(newTime - prevTime);
- if (timeout <= 0) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketTimeoutException",
- "Receive timed out");
- return -1;
- }
- prevTime = newTime;
- }
- retry = true;
- }
- } while (retry);
-
- port = ntohs (GET_PORT(sa));
-
- /* truncate the data if the packet's length is too small */
- if (rv > packetBufferLen) {
- rv = packetBufferLen;
- }
- if (rv < 0) {
- if (WSAGetLastError() == WSAEMSGSIZE) {
- /* it is because the buffer is too small. It's UDP, it's
- * unreliable, it's all good. discard the rest of the
- * data..
- */
- rv = packetBufferLen;
- } else {
- /* failure */
- dpObj.length = 0;
- }
- }
-
- if (rv == -1) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", "socket closed");
- } else if (rv == -2) {
- JNU_ThrowByName(env, JNU_JAVAIOPKG+"InterruptedIOException",
- "operation interrupted");
- } else if (rv < 0) {
- NET_ThrowCurrent(env, "Datagram receive failed");
- } else {
- 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 = dpObj.address;
- if (packetAddress != NULL) {
- if (!NET_SockaddrEqualsInetAddress(sa,
- packetAddress)) {
- /* force a new InetAddress to be created */
- packetAddress = null;
- }
- }
- if (packetAddress == NULL) {
- int[] tmp = { port };
- packetAddress = NET_SockaddrToInetAddress(sa, tmp);
- port = tmp[0];
- /* stuff the new Inetaddress into the packet */
- dpObj.address = packetAddress;
- }
-
- /* populate the packet */
- dpObj.port = port;
- dpObj.length = rv;
- }
-
- return port;
-}
-
-/*
- * Class: java_net_DualStackPlainDatagramSocketImpl
- * Method: socketSend
- * Signature: (I[BIILjava/net/InetAddress;IZ)V
- */
-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 rv;
-
- if (connected) {
- sa = null; /* arg to JVM_Sendto () null in this case */
- } else {
- 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;
- }
- fullPacket = (char *)malloc(length);
- if (!fullPacket) {
- JNU_ThrowOutOfMemoryError(env, "Native heap allocation failed");
- return;
- }
- } else {
- fullPacket = &(BUF[0]);
- }
- */
-
- 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",
- "operation interrupted");
- }
- }
-
-}
-
-/*
- * Class: java_net_DualStackPlainDatagramSocketImpl
- * Method: socketSetIntOption
- * Signature: (III)V
- */
-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_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
- "Invalid option");
- return;
- }
-
- if (NET_SetSockOpt(fd, level[0], opt[0], value) < 0) {
- NET_ThrowNew(env, WSAGetLastError(), "setsockopt");
- }
-}
-
-/*
- * Class: java_net_DualStackPlainDatagramSocketImpl
- * Method: socketGetIntOption
- * Signature: (II)I
- */
-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_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
- "Invalid option");
- return -1;
- }
-
- if (NET_GetSockOpt(fd, level[0], opt[0], result) < 0) {
- NET_ThrowNew(env, WSAGetLastError(), "getsockopt");
- return -1;
- }
-
- return result[0];
-}
-}
diff --git a/openjdk/java/net/DualStackPlainSocketImpl.java b/openjdk/java/net/DualStackPlainSocketImpl.java
deleted file mode 100644
index a3584d86..00000000
--- a/openjdk/java/net/DualStackPlainSocketImpl.java
+++ /dev/null
@@ -1,360 +0,0 @@
-/*
- * Copyright (c) 2007, 2008, 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.IOException;
-import java.io.FileDescriptor;
-
-/**
- * This class defines the plain SocketImpl that is used on Windows platforms
- * greater or equal to Windows Vista. These platforms have a dual
- * layer TCP/IP stack and can handle both IPv4 and IPV6 through a
- * single file descriptor.
- *
- * @author Chris Hegarty
- */
-
-class DualStackPlainSocketImpl extends AbstractPlainSocketImpl
-{
-
-
- // true if this socket is exclusively bound
- private final boolean exclusiveBind;
-
- // emulates SO_REUSEADDR when exclusiveBind is true
- private boolean isReuseAddress;
-
- public DualStackPlainSocketImpl(boolean exclBind) {
- exclusiveBind = exclBind;
- }
-
- public DualStackPlainSocketImpl(FileDescriptor fd, boolean exclBind) {
- this.fd = fd;
- exclusiveBind = exclBind;
- }
-
- void socketCreate(boolean stream) throws IOException {
- if (fd == null)
- throw new SocketException("Socket closed");
-
- cli.System.Net.Sockets.Socket newfd = socket0(stream, false /*v6 Only*/);
-
- fd.setSocket(newfd);
- }
-
- void socketConnect(InetAddress address, int port, int timeout)
- throws IOException {
- cli.System.Net.Sockets.Socket nativefd = checkAndReturnNativeFD();
-
- if (address == null)
- throw new NullPointerException("inet address argument is null.");
-
- int connectResult;
- if (timeout <= 0) {
- connectResult = connect0(nativefd, address, port);
- } else {
- configureBlocking(nativefd, false);
- try {
- connectResult = connect0(nativefd, address, port);
- if (connectResult == WOULDBLOCK) {
- waitForConnect(nativefd, timeout);
- }
- } finally {
- configureBlocking(nativefd, true);
- }
- }
- /*
- * We need to set the local port field. If bind was called
- * previous to the connect (by the client) then localport field
- * will already be set.
- */
- if (localport == 0)
- localport = localPort0(nativefd);
- }
-
- void socketBind(InetAddress address, int port) throws IOException {
- cli.System.Net.Sockets.Socket nativefd = checkAndReturnNativeFD();
-
- if (address == null)
- throw new NullPointerException("inet address argument is null.");
-
- bind0(nativefd, address, port, exclusiveBind);
- if (port == 0) {
- localport = localPort0(nativefd);
- } else {
- localport = port;
- }
-
- this.address = address;
- }
-
- void socketListen(int backlog) throws IOException {
- cli.System.Net.Sockets.Socket nativefd = checkAndReturnNativeFD();
-
- listen0(nativefd, backlog);
- }
-
- void socketAccept(SocketImpl s) throws IOException {
- cli.System.Net.Sockets.Socket nativefd = checkAndReturnNativeFD();
-
- if (s == null)
- throw new NullPointerException("socket is null");
-
- cli.System.Net.Sockets.Socket newfd = null;
- InetSocketAddress[] isaa = new InetSocketAddress[1];
- if (timeout <= 0) {
- newfd = accept0(nativefd, isaa);
- } else {
- configureBlocking(nativefd, false);
- try {
- waitForNewConnection(nativefd, timeout);
- newfd = accept0(nativefd, isaa);
- if (newfd != null) {
- configureBlocking(newfd, true);
- }
- } finally {
- configureBlocking(nativefd, true);
- }
- }
- /* Update (SocketImpl)s' fd */
- s.fd.setSocket(newfd);
- /* Update socketImpls remote port, address and localport */
- InetSocketAddress isa = isaa[0];
- s.port = isa.getPort();
- s.address = isa.getAddress();
- s.localport = localport;
- }
-
- int socketAvailable() throws IOException {
- cli.System.Net.Sockets.Socket nativefd = checkAndReturnNativeFD();
- return available0(nativefd);
- }
-
- void socketClose0(boolean useDeferredClose/*unused*/) throws IOException {
- if (fd == null)
- throw new SocketException("Socket closed");
-
- if (!fd.valid())
- return;
-
- close0(fd.getSocket());
- fd.setSocket(null);
- }
-
- void socketShutdown(int howto) throws IOException {
- cli.System.Net.Sockets.Socket nativefd = checkAndReturnNativeFD();
- shutdown0(nativefd, howto);
- }
-
- // Intentional fallthrough after SO_REUSEADDR
- @SuppressWarnings("fallthrough")
- void socketSetOption(int opt, boolean on, Object value)
- throws SocketException {
- cli.System.Net.Sockets.Socket nativefd = checkAndReturnNativeFD();
-
- if (opt == SO_TIMEOUT) { // timeout implemented through select.
- return;
- }
-
- int optionValue = 0;
-
- switch(opt) {
- case SO_REUSEADDR :
- if (exclusiveBind) {
- // SO_REUSEADDR emulated when using exclusive bind
- isReuseAddress = on;
- return;
- }
- // intentional fallthrough
- case TCP_NODELAY :
- case SO_OOBINLINE :
- case SO_KEEPALIVE :
- optionValue = on ? 1 : 0;
- break;
- case SO_SNDBUF :
- case SO_RCVBUF :
- case IP_TOS :
- optionValue = ((Integer)value).intValue();
- break;
- case SO_LINGER :
- if (on) {
- optionValue = ((Integer)value).intValue();
- } else {
- optionValue = -1;
- }
- break;
- default :/* shouldn't get here */
- throw new SocketException("Option not supported");
- }
-
- setIntOption(nativefd, opt, optionValue);
- }
-
- int socketGetOption(int opt, Object iaContainerObj) throws SocketException {
- cli.System.Net.Sockets.Socket nativefd = checkAndReturnNativeFD();
-
- // SO_BINDADDR is not a socket option.
- if (opt == SO_BINDADDR) {
- localAddress(nativefd, (InetAddressContainer)iaContainerObj);
- return 0; // return value doesn't matter.
- }
-
- // SO_REUSEADDR emulated when using exclusive bind
- if (opt == SO_REUSEADDR && exclusiveBind)
- return isReuseAddress? 1 : -1;
-
- int value = getIntOption(nativefd, opt);
-
- switch (opt) {
- case TCP_NODELAY :
- case SO_OOBINLINE :
- case SO_KEEPALIVE :
- case SO_REUSEADDR :
- return (value == 0) ? -1 : 1;
- }
- return value;
- }
-
- void socketSendUrgentData(int data) throws IOException {
- cli.System.Net.Sockets.Socket nativefd = checkAndReturnNativeFD();
- sendOOB(nativefd, data);
- }
-
- private cli.System.Net.Sockets.Socket checkAndReturnNativeFD() throws SocketException {
- if (fd == null || !fd.valid())
- throw new SocketException("Socket closed");
-
- return fd.getSocket();
- }
-
- static final int WOULDBLOCK = -2; // Nothing available (non-blocking)
-
- /* Native methods */
-
- 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 void bind0(cli.System.Net.Sockets.Socket fd, InetAddress localAddress, int localport,
- boolean exclBind)
- throws IOException {
- ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
- DualStackPlainSocketImpl_c.bind0(env, fd, localAddress, localport, exclBind);
- env.ThrowPendingException();
- }
-
- 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 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 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 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 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 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 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 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 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 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 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 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 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 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
deleted file mode 100644
index 15c2a184..00000000
--- a/openjdk/java/net/DualStackPlainSocketImpl_c.java
+++ /dev/null
@@ -1,490 +0,0 @@
-/*
- * Copyright (c) 2007, 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.*;
-
-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 <windows.h>
-#include <winsock2.h>
-#include "jni.h"
-#include "net_util.h"
-#include "java_net_DualStackPlainSocketImpl.h"
-
-#define SET_BLOCKING 0
-#define SET_NONBLOCKING 1
-
-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) {
-
- jclass cls = (*env)->FindClass(env, "java/net/InetSocketAddress");
- isa_class = (*env)->NewGlobalRef(env, cls);
- isa_ctorID = (*env)->GetMethodID(env, cls, "<init>",
- "(Ljava/net/InetAddress;I)V");
-
- // implement read timeout with select.
- isRcvTimeoutSupported = 0;
-}
-
-/*
- * Class: java_net_DualStackPlainSocketImpl
- * Method: socket0
- * Signature: (ZZ)I
- */
-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 null;
- }
-
- rv = setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, opt);
- if (rv == SOCKET_ERROR) {
- NET_ThrowNew(env, WSAGetLastError(), "create");
- }
-
-
- return fd;
-}
-
-/*
- * Class: java_net_DualStackPlainSocketImpl
- * Method: bind0
- * Signature: (ILjava/net/InetAddress;I)V
- */
-static void bind0
- (JNIEnv env, cli.System.Net.Sockets.Socket fd, InetAddress iaObj, int port,
- boolean exclBind)
-{
- SOCKETADDRESS sa;
- sa = new SOCKETADDRESS();
- int rv;
-
- if (NET_InetAddressToSockaddr(env, iaObj, port, sa,
- JNI_TRUE) != 0) {
- return;
- }
-
- rv = NET_WinBind(fd, sa, exclBind);
-
- if (rv == SOCKET_ERROR)
- NET_ThrowNew(env, WSAGetLastError(), "JVM_Bind");
-}
-
-/*
- * Class: java_net_DualStackPlainSocketImpl
- * Method: connect0
- * Signature: (ILjava/net/InetAddress;I)I
- */
-static int connect0
- (JNIEnv env, cli.System.Net.Sockets.Socket fd, InetAddress iaObj, int port) {
- SOCKETADDRESS sa;
- sa = new SOCKETADDRESS();
- int rv;
-
- if (NET_InetAddressToSockaddr(env, iaObj, port, sa,
- JNI_TRUE) != 0) {
- return -1;
- }
-
- rv = connect(fd, sa);
- if (rv == SOCKET_ERROR) {
- int err = WSAGetLastError();
- if (err == WSAEWOULDBLOCK) {
- return java.net.DualStackPlainSocketImpl.WOULDBLOCK;
- } else if (err == 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, err, "connect");
- }
- return -1; // return value not important.
- }
- return rv;
-}
-
-/*
- * Class: java_net_DualStackPlainSocketImpl
- * Method: waitForConnect
- * Signature: (II)V
- */
-static void waitForConnect
- (JNIEnv env, cli.System.Net.Sockets.Socket fd, int timeout) {
- int rv, retry;
- 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 timeout, connection established or
- * connection failed.
- */
- rv = 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 (rv == 0) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketTimeoutException",
- "connect timed out");
- shutdown( fd, SD_BOTH );
- return;
- }
-
- /*
- * Socket is writable or error occured. On some Windows editions
- * the socket will appear writable when the connect fails so we
- * check for error rather than writable.
- */
- if (!FD_ISSET(fd, ex)) {
- return; /* connection established */
- }
-
- /*
- * Connection 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.
- */
- for (retry=0; retry<3; retry++) {
- int[] tmp = { 0 };
- NET_GetSockOpt(fd, SOL_SOCKET, SO_ERROR,
- tmp);
- rv = tmp[0];
- if (rv != 0) {
- break;
- }
- Sleep(0);
- }
-
- if (rv == 0) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
- "Unable to establish connection");
- } else {
- NET_ThrowNew(env, rv, "connect");
- }
-}
-
-/*
- * Class: java_net_DualStackPlainSocketImpl
- * Method: localPort0
- * Signature: (I)I
- */
-static int localPort0
- (JNIEnv env, cli.System.Net.Sockets.Socket fd) {
- SOCKETADDRESS sa;
- sa = new SOCKETADDRESS();
-
- if (getsockname(fd, sa) == SOCKET_ERROR) {
- if (WSAGetLastError() == WSAENOTSOCK) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
- "Socket closed");
- } else {
- NET_ThrowNew(env, WSAGetLastError(), "getsockname failed");
- }
- return -1;
- }
- return ntohs(GET_PORT(sa));
-}
-
-/*
- * Class: java_net_DualStackPlainSocketImpl
- * Method: localAddress
- * Signature: (ILjava/net/InetAddressContainer;)V
- */
-static void localAddress
- (JNIEnv env, cli.System.Net.Sockets.Socket fd, InetAddressContainer iaContainerObj) {
- int[] port = { 0 };
- SOCKETADDRESS sa;
- sa = new SOCKETADDRESS();
- InetAddress iaObj;
-
- if (getsockname(fd, sa) == SOCKET_ERROR) {
- NET_ThrowNew(env, WSAGetLastError(), "Error getting socket name");
- return;
- }
- iaObj = NET_SockaddrToInetAddress(env, sa, port);
-
- iaContainerObj.addr = iaObj;
-}
-
-
-/*
- * Class: java_net_DualStackPlainSocketImpl
- * Method: listen0
- * Signature: (II)V
- */
-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");
- }
-}
-
-/*
- * Class: java_net_DualStackPlainSocketImpl
- * Method: accept0
- * Signature: (I[Ljava/net/InetSocketAddress;)I
- */
-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;
- sa = new SOCKETADDRESS();
-
- newfd = accept(fd, sa);
-
- if (newfd == INVALID_SOCKET) {
- if (WSAGetLastError() == -2) {
- JNU_ThrowByName(env, JNU_JAVAIOPKG+"InterruptedIOException",
- "operation interrupted");
- } else {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
- "socket closed");
- }
- return null;
- }
-
- ia = NET_SockaddrToInetAddress(env, sa, port);
- isa = new InetSocketAddress(ia, port[0]);
- isaa[0] = isa;
-
- return newfd;
-}
-
-/*
- * Class: java_net_DualStackPlainSocketImpl
- * Method: waitForNewConnection
- * Signature: (II)V
- */
-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",
- "Accept timed out");
- } else if (rv == -1) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", "socket closed");
- } else if (rv == -2) {
- JNU_ThrowByName(env, JNU_JAVAIOPKG+"InterruptedIOException",
- "operation interrupted");
- }
-}
-
-/*
- * Class: java_net_DualStackPlainSocketImpl
- * Method: available0
- * Signature: (I)I
- */
-static int available0
- (JNIEnv env, cli.System.Net.Sockets.Socket fd) {
- int[] available = { -1 };
-
- if ((ioctlsocket(fd, FIONREAD, available)) == SOCKET_ERROR) {
- NET_ThrowNew(env, WSAGetLastError(), "socket available");
- }
-
- return available[0];
-}
-
-/*
- * Class: java_net_DualStackPlainSocketImpl
- * Method: close0
- * Signature: (I)V
- */
-static void close0
- (JNIEnv env, cli.System.Net.Sockets.Socket fd) {
- NET_SocketClose(fd);
-}
-
-/*
- * Class: java_net_DualStackPlainSocketImpl
- * Method: shutdown0
- * Signature: (II)V
- */
-static void shutdown0
- (JNIEnv env, cli.System.Net.Sockets.Socket fd, int howto) {
- shutdown(fd, howto);
-}
-
-
-/*
- * Class: java_net_DualStackPlainSocketImpl
- * Method: setIntOption
- * Signature: (III)V
- */
-static void setIntOption
- (JNIEnv env, cli.System.Net.Sockets.Socket fd, int cmd, int value) {
-
- int[] level = { 0 };
- int[] opt = { 0 };
- linger linger;
- Object optval;
-
- if (NET_MapSocketOption(cmd, level, opt) < 0) {
- JNU_ThrowByName(env,
- JNU_JAVANETPKG+"SocketException",
- "Invalid option");
- return;
- }
-
- if (opt[0] == java.net.SocketOptions.SO_LINGER) {
- linger = new linger();
- if (value >= 0) {
- linger.l_onoff = 1;
- linger.l_linger = value & 0xFFFF;
- } else {
- linger.l_onoff = 0;
- linger.l_linger = 0;
- }
- optval = linger;
- } else {
- optval = value;
- }
-
- if (NET_SetSockOpt(fd, level[0], opt[0], optval) < 0) {
- NET_ThrowNew(env, WSAGetLastError(), "setsockopt");
- }
-}
-
-/*
- * Class: java_net_DualStackPlainSocketImpl
- * Method: getIntOption
- * Signature: (II)I
- */
-static int getIntOption
- (JNIEnv env, cli.System.Net.Sockets.Socket fd, int cmd) {
-
- int[] level = { 0 };
- int[] opt = { 0 };
- int[] result = { 0 };
- linger linger;
- Object optval;
-
- if (NET_MapSocketOption(cmd, level, opt) < 0) {
- JNU_ThrowByName(env,
- JNU_JAVANETPKG+"SocketException",
- "Unsupported socket option");
- return -1;
- }
-
- if (opt[0] == java.net.SocketOptions.SO_LINGER) {
- linger = new linger();
- optval = linger;
- } else {
- linger = null;
- optval = result;
- }
-
- if (NET_GetSockOpt(fd, level[0], opt[0], optval) < 0) {
- NET_ThrowNew(env, WSAGetLastError(), "getsockopt");
- return -1;
- }
-
- if (opt[0] == java.net.SocketOptions.SO_LINGER)
- return linger.l_onoff != 0 ? linger.l_linger : -1;
- else
- return result[0];
-}
-
-
-/*
- * Class: java_net_DualStackPlainSocketImpl
- * Method: sendOOB
- * Signature: (II)V
- */
-static void sendOOB
- (JNIEnv env, cli.System.Net.Sockets.Socket fd, int data) {
- int n;
-
- 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", null);
- }
-}
-
-/*
- * Class: java_net_DualStackPlainSocketImpl
- * Method: configureBlocking
- * Signature: (IZ)V
- */
-static void configureBlocking
- (JNIEnv env, cli.System.Net.Sockets.Socket fd, boolean blocking) {
- int arg;
- int result;
-
- if (blocking == JNI_TRUE) {
- arg = SET_BLOCKING; // 0
- } else {
- arg = SET_NONBLOCKING; // 1
- }
-
- result = ioctlsocket(fd, FIONBIO, arg);
- if (result == SOCKET_ERROR) {
- NET_ThrowNew(env, WSAGetLastError(), "configureBlocking");
- }
-}
-}
diff --git a/openjdk/java/net/PlainSocketImpl.java b/openjdk/java/net/PlainSocketImpl.java
deleted file mode 100644
index 5b7f850d..00000000
--- a/openjdk/java/net/PlainSocketImpl.java
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
- * Copyright (c) 2007, 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.*;
-import java.security.PrivilegedAction;
-
-/*
- * This class PlainSocketImpl simply delegates to the appropriate real
- * SocketImpl. We do this because PlainSocketImpl is already extended
- * by SocksSocketImpl.
- * <p>
- * There are two possibilities for the real SocketImpl,
- * TwoStacksPlainSocketImpl or DualStackPlainSocketImpl. We use
- * DualStackPlainSocketImpl on systems that have a dual stack
- * TCP implementation. Otherwise we create an instance of
- * TwoStacksPlainSocketImpl and delegate to it.
- *
- * @author Chris Hegarty
- */
-
-class PlainSocketImpl extends AbstractPlainSocketImpl
-{
- private AbstractPlainSocketImpl impl;
-
- /* the windows version. */
- private static float version;
-
- /* java.net.preferIPv4Stack */
- private static boolean preferIPv4Stack = false;
-
- /* If the version supports a dual stack TCP implementation */
- private static boolean useDualStackImpl = false;
-
- /* sun.net.useExclusiveBind */
- private static String exclBindProp;
-
- /* True if exclusive binding is on for Windows */
- private static boolean exclusiveBind = true;
-
- static {
- java.security.AccessController.doPrivileged( new PrivilegedAction<Object>() {
- public Object run() {
- version = 0;
- try {
- version = Float.parseFloat(System.getProperties().getProperty("os.version"));
- preferIPv4Stack = Boolean.parseBoolean(
- System.getProperties().getProperty("java.net.preferIPv4Stack"));
- exclBindProp = System.getProperty("sun.net.useExclusiveBind");
- } catch (NumberFormatException e ) {
- assert false : e;
- }
- return null; // nothing to return
- } });
-
- String ipv6 = ikvm.internal.Util.SafeGetEnvironmentVariable("IKVM_IPV6");
- if (ipv6 != null) {
- try {
- if ((Integer.parseInt(ipv6) & 4) == 0) {
- preferIPv4Stack = true;
- } else {
- useDualStackImpl = true;
- }
- } catch (NumberFormatException _) {
- }
- } else if (!InetAddressImplFactory.isIPv6Supported()) {
- preferIPv4Stack = true;
- }
-
- // (version >= 6.0) implies Vista or greater.
- if (version >= 6.0 && !preferIPv4Stack) {
- useDualStackImpl = true;
- }
-
- if (exclBindProp != null) {
- // sun.net.useExclusiveBind is true
- exclusiveBind = exclBindProp.length() == 0 ? true
- : Boolean.parseBoolean(exclBindProp);
- } else if (version < 6.0) {
- exclusiveBind = false;
- }
- }
-
- /**
- * Constructs an empty instance.
- */
- PlainSocketImpl() {
- if (useDualStackImpl) {
- impl = new DualStackPlainSocketImpl(exclusiveBind);
- } else {
- impl = new TwoStacksPlainSocketImpl(exclusiveBind);
- }
- }
-
- /**
- * Constructs an instance with the given file descriptor.
- */
- PlainSocketImpl(FileDescriptor fd) {
- if (useDualStackImpl) {
- impl = new DualStackPlainSocketImpl(fd, exclusiveBind);
- } else {
- impl = new TwoStacksPlainSocketImpl(fd, exclusiveBind);
- }
- }
-
- // Override methods in SocketImpl that access impl's fields.
-
- protected FileDescriptor getFileDescriptor() {
- return impl.getFileDescriptor();
- }
-
- protected InetAddress getInetAddress() {
- return impl.getInetAddress();
- }
-
- protected int getPort() {
- return impl.getPort();
- }
-
- protected int getLocalPort() {
- return impl.getLocalPort();
- }
-
- void setSocket(Socket soc) {
- impl.setSocket(soc);
- }
-
- Socket getSocket() {
- return impl.getSocket();
- }
-
- void setServerSocket(ServerSocket soc) {
- impl.setServerSocket(soc);
- }
-
- ServerSocket getServerSocket() {
- return impl.getServerSocket();
- }
-
- public String toString() {
- return impl.toString();
- }
-
- // Override methods in AbstractPlainSocketImpl that access impl's fields.
-
- protected synchronized void create(boolean stream) throws IOException {
- impl.create(stream);
-
- // set fd to delegate's fd to be compatible with older releases
- this.fd = impl.fd;
- }
-
- protected void connect(String host, int port)
- throws UnknownHostException, IOException
- {
- impl.connect(host, port);
- }
-
- protected void connect(InetAddress address, int port) throws IOException {
- impl.connect(address, port);
- }
-
- protected void connect(SocketAddress address, int timeout) throws IOException {
- impl.connect(address, timeout);
- }
-
- public void setOption(int opt, Object val) throws SocketException {
- impl.setOption(opt, val);
- }
-
- public Object getOption(int opt) throws SocketException {
- return impl.getOption(opt);
- }
-
- synchronized void doConnect(InetAddress address, int port, int timeout) throws IOException {
- impl.doConnect(address, port, timeout);
- }
-
- protected synchronized void bind(InetAddress address, int lport)
- throws IOException
- {
- impl.bind(address, lport);
- }
-
- protected synchronized void accept(SocketImpl s) throws IOException {
- // pass in the real impl not the wrapper.
- SocketImpl delegate = ((PlainSocketImpl)s).impl;
- delegate.address = new InetAddress();
- delegate.fd = new FileDescriptor();
- impl.accept(delegate);
-
- // set fd to delegate's fd to be compatible with older releases
- s.fd = delegate.fd;
- }
-
- void setFileDescriptor(FileDescriptor fd) {
- impl.setFileDescriptor(fd);
- }
-
- void setAddress(InetAddress address) {
- impl.setAddress(address);
- }
-
- void setPort(int port) {
- impl.setPort(port);
- }
-
- void setLocalPort(int localPort) {
- impl.setLocalPort(localPort);
- }
-
- protected synchronized InputStream getInputStream() throws IOException {
- return impl.getInputStream();
- }
-
- void setInputStream(SocketInputStream in) {
- impl.setInputStream(in);
- }
-
- protected synchronized OutputStream getOutputStream() throws IOException {
- return impl.getOutputStream();
- }
-
- protected void close() throws IOException {
- try {
- impl.close();
- } finally {
- // set fd to delegate's fd to be compatible with older releases
- this.fd = null;
- }
- }
-
- void reset() throws IOException {
- try {
- impl.reset();
- } finally {
- // set fd to delegate's fd to be compatible with older releases
- this.fd = null;
- }
- }
-
- protected void shutdownInput() throws IOException {
- impl.shutdownInput();
- }
-
- protected void shutdownOutput() throws IOException {
- impl.shutdownOutput();
- }
-
- protected void sendUrgentData(int data) throws IOException {
- impl.sendUrgentData(data);
- }
-
- FileDescriptor acquireFD() {
- return impl.acquireFD();
- }
-
- void releaseFD() {
- impl.releaseFD();
- }
-
- public boolean isConnectionReset() {
- return impl.isConnectionReset();
- }
-
- public boolean isConnectionResetPending() {
- return impl.isConnectionResetPending();
- }
-
- public void setConnectionReset() {
- impl.setConnectionReset();
- }
-
- public void setConnectionResetPending() {
- impl.setConnectionResetPending();
- }
-
- public boolean isClosedOrPending() {
- return impl.isClosedOrPending();
- }
-
- public int getTimeout() {
- return impl.getTimeout();
- }
-
- // Override methods in AbstractPlainSocketImpl that need to be implemented.
-
- void socketCreate(boolean isServer) throws IOException {
- impl.socketCreate(isServer);
- }
-
- void socketConnect(InetAddress address, int port, int timeout)
- throws IOException {
- impl.socketConnect(address, port, timeout);
- }
-
- void socketBind(InetAddress address, int port)
- throws IOException {
- impl.socketBind(address, port);
- }
-
- void socketListen(int count) throws IOException {
- impl.socketListen(count);
- }
-
- void socketAccept(SocketImpl s) throws IOException {
- impl.socketAccept(s);
- }
-
- int socketAvailable() throws IOException {
- return impl.socketAvailable();
- }
-
- void socketClose0(boolean useDeferredClose) throws IOException {
- impl.socketClose0(useDeferredClose);
- }
-
- void socketShutdown(int howto) throws IOException {
- impl.socketShutdown(howto);
- }
-
- void socketSetOption(int cmd, boolean on, Object value)
- throws SocketException {
- socketSetOption(cmd, on, value);
- }
-
- int socketGetOption(int opt, Object iaContainerObj) throws SocketException {
- return impl.socketGetOption(opt, iaContainerObj);
- }
-
- void socketSendUrgentData(int data) throws IOException {
- impl.socketSendUrgentData(data);
- }
-}
diff --git a/openjdk/java/net/SocketInputStream.java b/openjdk/java/net/SocketInputStream.java
deleted file mode 100644
index 161947cc..00000000
--- a/openjdk/java/net/SocketInputStream.java
+++ /dev/null
@@ -1,332 +0,0 @@
-/*
- * Copyright (c) 1995, 2010, 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 java.io.FileInputStream;
-import java.io.IOException;
-import java.nio.channels.FileChannel;
-import static ikvm.internal.Winsock.*;
-import static java.net.net_util_md.*;
-
-import sun.misc.IoTrace;
-import sun.net.ConnectionResetException;
-
-/**
- * This stream extends FileInputStream to implement a
- * SocketInputStream. Note that this class should <b>NOT</b> be
- * public.
- *
- * @author Jonathan Payne
- * @author Arthur van Hoff
- */
-class SocketInputStream extends FileInputStream
-{
-
- private boolean eof;
- private AbstractPlainSocketImpl impl = null;
- private byte temp[];
- private Socket socket = null;
-
- /**
- * Creates a new SocketInputStream. Can only be called
- * by a Socket. This method needs to hang on to the owner Socket so
- * that the fd will not be closed.
- * @param impl the implemented socket input stream
- */
- SocketInputStream(AbstractPlainSocketImpl impl) throws IOException {
- super(impl.getFileDescriptor());
- this.impl = impl;
- socket = impl.getSocket();
- }
-
- /**
- * Returns the unique {@link java.nio.channels.FileChannel FileChannel}
- * object associated with this file input stream.</p>
- *
- * The <code>getChannel</code> method of <code>SocketInputStream</code>
- * returns <code>null</code> since it is a socket based stream.</p>
- *
- * @return the file channel associated with this file input stream
- *
- * @since 1.4
- * @spec JSR-51
- */
- public final FileChannel getChannel() {
- return null;
- }
-
- /**
- * Reads into an array of bytes at the specified offset using
- * the received socket primitive.
- * @param fd the FileDescriptor
- * @param b the buffer into which the data is read
- * @param off the start offset of the data
- * @param len the maximum number of bytes read
- * @param timeout the read timeout in ms
- * @return the actual number of bytes read, -1 is
- * returned when the end of the stream is reached.
- * @exception IOException If an I/O error has occurred.
- */
- private int socketRead0(FileDescriptor fdObj, byte bufP[], int off, int len, int timeout) throws IOException
- {
- // [IKVM] this method is a direct port of the native code in openjdk6-b18\jdk\src\windows\native\java\net\SocketInputStream.c
- cli.System.Net.Sockets.Socket fd = null;
- int nread;
-
- if (IS_NULL(fdObj)) {
- throw new SocketException("socket closed");
- }
- fd = fdObj.getSocket();
- if (fd == null) {
- throw new SocketException("Socket closed");
- }
-
- if (timeout != 0) {
- if (timeout <= 5000 || !isRcvTimeoutSupported) {
- int ret = NET_Timeout (fd, timeout);
-
- if (ret <= 0) {
- if (ret == 0) {
- throw new SocketTimeoutException("Read timed out");
- } else {
- // [IKVM] the OpenJDK native code is broken and always throws this exception on any failure of NET_Timeout
- throw new SocketException("socket closed");
- }
- }
-
- /*check if the socket has been closed while we were in timeout*/
- if (fdObj.getSocket() == null) {
- throw new SocketException("Socket Closed");
- }
- }
- }
-
- nread = recv(fd, bufP, off, len, 0);
- if (nread > 0) {
- // ok
- } else {
- if (nread < 0) {
- /*
- * Recv failed.
- */
- switch (WSAGetLastError()) {
- case WSAEINTR:
- throw new SocketException("socket closed");
-
- case WSAECONNRESET:
- case WSAESHUTDOWN:
- /*
- * Connection has been reset - Windows sometimes reports
- * the reset as a shutdown error.
- */
- throw new ConnectionResetException();
-
- case WSAETIMEDOUT :
- throw new SocketTimeoutException("Read timed out");
-
- default:
- throw NET_ThrowCurrent("recv failed");
- }
- }
- }
- return nread;
- }
-
- /**
- * Reads into a byte array data from the socket.
- * @param b the buffer into which the data is read
- * @return the actual number of bytes read, -1 is
- * returned when the end of the stream is reached.
- * @exception IOException If an I/O error has occurred.
- */
- public int read(byte b[]) throws IOException {
- return read(b, 0, b.length);
- }
-
- /**
- * Reads into a byte array <i>b</i> at offset <i>off</i>,
- * <i>length</i> bytes of data.
- * @param b the buffer into which the data is read
- * @param off the start offset of the data
- * @param len the maximum number of bytes read
- * @return the actual number of bytes read, -1 is
- * returned when the end of the stream is reached.
- * @exception IOException If an I/O error has occurred.
- */
- public int read(byte b[], int off, int length) throws IOException {
- return read(b, off, length, impl.getTimeout());
- }
-
- int read(byte b[], int off, int length, int timeout) throws IOException {
- int n = 0;
-
- // EOF already encountered
- if (eof) {
- return -1;
- }
-
- // connection reset
- if (impl.isConnectionReset()) {
- throw new SocketException("Connection reset");
- }
-
- // bounds check
- if (length <= 0 || off < 0 || off + length > b.length) {
- if (length == 0) {
- return 0;
- }
- throw new ArrayIndexOutOfBoundsException();
- }
-
- boolean gotReset = false;
-
- Object traceContext = IoTrace.socketReadBegin();
- // acquire file descriptor and do the read
- FileDescriptor fd = impl.acquireFD();
- try {
- n = socketRead0(fd, b, off, length, timeout);
- if (n > 0) {
- return n;
- }
- } catch (ConnectionResetException rstExc) {
- gotReset = true;
- } finally {
- impl.releaseFD();
- IoTrace.socketReadEnd(traceContext, impl.address, impl.port,
- timeout, n > 0 ? n : 0);
- }
-
- /*
- * We receive a "connection reset" but there may be bytes still
- * buffered on the socket
- */
- if (gotReset) {
- traceContext = IoTrace.socketReadBegin();
- impl.setConnectionResetPending();
- impl.acquireFD();
- try {
- n = socketRead0(fd, b, off, length, timeout);
- if (n > 0) {
- return n;
- }
- } catch (ConnectionResetException rstExc) {
- } finally {
- impl.releaseFD();
- IoTrace.socketReadEnd(traceContext, impl.address, impl.port,
- timeout, n > 0 ? n : 0);
- }
- }
-
- /*
- * If we get here we are at EOF, the socket has been closed,
- * or the connection has been reset.
- */
- if (impl.isClosedOrPending()) {
- throw new SocketException("Socket closed");
- }
- if (impl.isConnectionResetPending()) {
- impl.setConnectionReset();
- }
- if (impl.isConnectionReset()) {
- throw new SocketException("Connection reset");
- }
- eof = true;
- return -1;
- }
-
- /**
- * Reads a single byte from the socket.
- */
- public int read() throws IOException {
- if (eof) {
- return -1;
- }
- temp = new byte[1];
- int n = read(temp, 0, 1);
- if (n <= 0) {
- return -1;
- }
- return temp[0] & 0xff;
- }
-
- /**
- * Skips n bytes of input.
- * @param n the number of bytes to skip
- * @return the actual number of bytes skipped.
- * @exception IOException If an I/O error has occurred.
- */
- public long skip(long numbytes) throws IOException {
- if (numbytes <= 0) {
- return 0;
- }
- long n = numbytes;
- int buflen = (int) Math.min(1024, n);
- byte data[] = new byte[buflen];
- while (n > 0) {
- int r = read(data, 0, (int) Math.min((long) buflen, n));
- if (r < 0) {
- break;
- }
- n -= r;
- }
- return numbytes - n;
- }
-
- /**
- * Returns the number of bytes that can be read without blocking.
- * @return the number of immediately available bytes
- */
- public int available() throws IOException {
- return impl.available();
- }
-
- /**
- * Closes the stream.
- */
- private boolean closing = false;
- public void close() throws IOException {
- // Prevent recursion. See BugId 4484411
- if (closing)
- return;
- closing = true;
- if (socket != null) {
- if (!socket.isClosed())
- socket.close();
- } else
- impl.close();
- closing = false;
- }
-
- void setEOF(boolean eof) {
- this.eof = eof;
- }
-
- /**
- * Overrides finalize, the fd is closed by the Socket.
- */
- protected void finalize() {}
-}
diff --git a/openjdk/java/net/SocketOutputStream.java b/openjdk/java/net/SocketOutputStream.java
deleted file mode 100644
index fd6e2c4f..00000000
--- a/openjdk/java/net/SocketOutputStream.java
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Copyright (c) 1995, 2007, 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 java.io.FileOutputStream;
-import java.io.IOException;
-import java.nio.channels.FileChannel;
-import static ikvm.internal.Winsock.*;
-import static java.net.net_util_md.*;
-
-import sun.misc.IoTrace;
-
-/**
- * This stream extends FileOutputStream to implement a
- * SocketOutputStream. Note that this class should <b>NOT</b> be
- * public.
- *
- * @author Jonathan Payne
- * @author Arthur van Hoff
- */
-class SocketOutputStream extends FileOutputStream
-{
- private AbstractPlainSocketImpl impl = null;
- private byte temp[] = new byte[1];
- private Socket socket = null;
-
- /**
- * Creates a new SocketOutputStream. Can only be called
- * by a Socket. This method needs to hang on to the owner Socket so
- * that the fd will not be closed.
- * @param impl the socket output stream inplemented
- */
- SocketOutputStream(AbstractPlainSocketImpl impl) throws IOException {
- super(impl.getFileDescriptor());
- this.impl = impl;
- socket = impl.getSocket();
- }
-
- /**
- * Returns the unique {@link java.nio.channels.FileChannel FileChannel}
- * object associated with this file output stream. </p>
- *
- * The <code>getChannel</code> method of <code>SocketOutputStream</code>
- * returns <code>null</code> since it is a socket based stream.</p>
- *
- * @return the file channel associated with this file output stream
- *
- * @since 1.4
- * @spec JSR-51
- */
- public final FileChannel getChannel() {
- return null;
- }
-
- /**
- * Writes to the socket.
- * @param fd the FileDescriptor
- * @param b the data to be written
- * @param off the start offset in the data
- * @param len the number of bytes that are written
- * @exception IOException If an I/O error has occurred.
- */
- private void socketWrite0(FileDescriptor fdObj, byte[] data, int off, int len) throws IOException
- {
- // [IKVM] this method is a direct port of the native code in openjdk6-b18\jdk\src\windows\native\java\net\SocketOutputStream.c
- final int MAX_BUFFER_LEN = 2048;
- cli.System.Net.Sockets.Socket fd;
- int buflen = 65536; // MAX_HEAP_BUFFER_LEN
- int n;
-
- if (IS_NULL(fdObj)) {
- throw new SocketException("socket closed");
- } else {
- fd = fdObj.getSocket();
- }
- if (IS_NULL(data)) {
- throw new NullPointerException("data argument");
- }
-
- while(len > 0) {
- int loff = 0;
- int chunkLen = Math.min(buflen, len);
- int llen = chunkLen;
- int retry = 0;
-
- while(llen > 0) {
- n = send(fd, data, off + loff, llen, 0);
- if (n > 0) {
- llen -= n;
- loff += n;
- continue;
- }
-
- /*
- * Due to a bug in Windows Sockets (observed on NT and Windows
- * 2000) it may be necessary to retry the send. The issue is that
- * on blocking sockets send/WSASend is supposed to block if there
- * is insufficient buffer space available. If there are a large
- * number of threads blocked on write due to congestion then it's
- * possile to hit the NT/2000 bug whereby send returns WSAENOBUFS.
- * The workaround we use is to retry the send. If we have a
- * large buffer to send (>2k) then we retry with a maximum of
- * 2k buffer. If we hit the issue with <=2k buffer then we backoff
- * for 1 second and retry again. We repeat this up to a reasonable
- * limit before bailing out and throwing an exception. In load
- * conditions we've observed that the send will succeed after 2-3
- * attempts but this depends on network buffers associated with
- * other sockets draining.
- */
- if (WSAGetLastError() == WSAENOBUFS) {
- if (llen > MAX_BUFFER_LEN) {
- buflen = MAX_BUFFER_LEN;
- chunkLen = MAX_BUFFER_LEN;
- llen = MAX_BUFFER_LEN;
- continue;
- }
- if (retry >= 30) {
- throw new SocketException("No buffer space available - exhausted attempts to queue buffer");
- }
- cli.System.Threading.Thread.Sleep(1000);
- retry++;
- continue;
- }
-
- /*
- * Send failed - can be caused by close or write error.
- */
- if (WSAGetLastError() == WSAENOTSOCK) {
- throw new SocketException("Socket closed");
- } else {
- throw NET_ThrowCurrent("socket write error");
- }
- }
- len -= chunkLen;
- off += chunkLen;
- }
- }
-
- /**
- * Writes to the socket with appropriate locking of the
- * FileDescriptor.
- * @param b the data to be written
- * @param off the start offset in the data
- * @param len the number of bytes that are written
- * @exception IOException If an I/O error has occurred.
- */
- private void socketWrite(byte b[], int off, int len) throws IOException {
-
- if (len <= 0 || off < 0 || off + len > b.length) {
- if (len == 0) {
- return;
- }
- throw new ArrayIndexOutOfBoundsException();
- }
-
- Object traceContext = IoTrace.socketWriteBegin();
- int bytesWritten = 0;
- FileDescriptor fd = impl.acquireFD();
- try {
- socketWrite0(fd, b, off, len);
- bytesWritten = len;
- } catch (SocketException se) {
- if (se instanceof sun.net.ConnectionResetException) {
- impl.setConnectionResetPending();
- se = new SocketException("Connection reset");
- }
- if (impl.isClosedOrPending()) {
- throw new SocketException("Socket closed");
- } else {
- throw se;
- }
- } finally {
- impl.releaseFD();
- IoTrace.socketWriteEnd(traceContext, impl.address, impl.port, bytesWritten);
- }
- }
-
- /**
- * Writes a byte to the socket.
- * @param b the data to be written
- * @exception IOException If an I/O error has occurred.
- */
- public void write(int b) throws IOException {
- temp[0] = (byte)b;
- socketWrite(temp, 0, 1);
- }
-
- /**
- * Writes the contents of the buffer <i>b</i> to the socket.
- * @param b the data to be written
- * @exception SocketException If an I/O error has occurred.
- */
- public void write(byte b[]) throws IOException {
- socketWrite(b, 0, b.length);
- }
-
- /**
- * Writes <i>length</i> bytes from buffer <i>b</i> starting at
- * offset <i>len</i>.
- * @param b the data to be written
- * @param off the start offset in the data
- * @param len the number of bytes that are written
- * @exception SocketException If an I/O error has occurred.
- */
- public void write(byte b[], int off, int len) throws IOException {
- socketWrite(b, off, len);
- }
-
- /**
- * Closes the stream.
- */
- private boolean closing = false;
- public void close() throws IOException {
- // Prevent recursion. See BugId 4484411
- if (closing)
- return;
- closing = true;
- if (socket != null) {
- if (!socket.isClosed())
- socket.close();
- } else
- impl.close();
- closing = false;
- }
-
- /**
- * Overrides finalize, the fd is closed by the Socket.
- */
- protected void finalize() {}
-}
diff --git a/openjdk/java/net/SocketUtil.java b/openjdk/java/net/SocketUtil.java
deleted file mode 100644
index d9a30869..00000000
--- a/openjdk/java/net/SocketUtil.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- Copyright (C) 2002-2010 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
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- Jeroen Frijters
- jeroen@frijters.net
-
-*/
-
-package java.net;
-
-import cli.System.Net.IPAddress;
-import cli.System.Net.IPEndPoint;
-import cli.System.Net.Sockets.SocketOptionName;
-import cli.System.Net.Sockets.SocketOptionLevel;
-import ikvm.lang.CIL;
-import java.io.IOException;
-
-@ikvm.lang.Internal
-public final class SocketUtil
-{
- private SocketUtil() { }
-
- // Winsock Error Codes
- public static final int WSAEINVAL = 10022;
- public static final int WSAEWOULDBLOCK = 10035;
- public static final int WSAEMSGSIZE = 10040;
- public static final int WSAENOPROTOOPT = 10042;
- public static final int WSAEADDRINUSE = 10048;
- public static final int WSAENETUNREACH = 10051;
- public static final int WSAECONNRESET = 10054;
- public static final int WSAESHUTDOWN = 10058;
- public static final int WSAETIMEDOUT = 10060;
- public static final int WSAECONNREFUSED = 10061;
- public static final int WSAEHOSTUNREACH = 10065;
- public static final int WSAHOST_NOT_FOUND = 11001;
-
- public static IOException convertSocketExceptionToIOException(cli.System.Net.Sockets.SocketException x) throws IOException
- {
- switch (x.get_ErrorCode())
- {
- case WSAEADDRINUSE:
- return new BindException(x.getMessage());
- case WSAENETUNREACH:
- case WSAEHOSTUNREACH:
- return new NoRouteToHostException(x.getMessage());
- case WSAETIMEDOUT:
- return new SocketTimeoutException(x.getMessage());
- case WSAECONNREFUSED:
- return new PortUnreachableException(x.getMessage());
- case WSAHOST_NOT_FOUND:
- return new UnknownHostException(x.getMessage());
- default:
- return new SocketException(x.getMessage() + "\nError Code: " + x.get_ErrorCode());
- }
- }
-
- public static IPAddress getAddressFromInetAddress(InetAddress addr)
- {
- return getAddressFromInetAddress(addr, false);
- }
-
- public static IPAddress getAddressFromInetAddress(InetAddress addr, boolean v4mapped)
- {
- byte[] b = addr.getAddress();
- if (b.length == 16)
- {
- // FXBUG in .NET 1.1 you can only construct IPv6 addresses (not IPv4) with this constructor
- // (according to the documentation this was fixed in .NET 2.0)
- return new IPAddress(b);
- }
- else if (v4mapped)
- {
- if (b[0] == 0 && b[1] == 0 && b[2] == 0 && b[3] == 0)
- {
- return IPAddress.IPv6Any;
- }
- byte[] b16 = new byte[16];
- b16[10] = -1;
- b16[11] = -1;
- b16[12] = b[0];
- b16[13] = b[1];
- b16[14] = b[2];
- b16[15] = b[3];
- return new IPAddress(b16);
- }
- else
- {
- return new IPAddress((((b[3] & 0xff) << 24) + ((b[2] & 0xff) << 16) + ((b[1] & 0xff) << 8) + (b[0] & 0xff)) & 0xffffffffL);
- }
- }
-
- public static InetAddress getInetAddressFromIPEndPoint(IPEndPoint endpoint)
- {
- try
- {
- return InetAddress.getByAddress(endpoint.get_Address().GetAddressBytes());
- }
- catch (UnknownHostException x)
- {
- // this exception only happens if the address byte array is of invalid length, which cannot happen unless
- // the .NET socket returns a bogus address
- throw (InternalError)new InternalError().initCause(x);
- }
- }
-
- static void setCommonSocketOption(cli.System.Net.Sockets.Socket netSocket, int cmd, boolean on, Object value) throws SocketException
- {
- try
- {
- if (false) throw new cli.System.Net.Sockets.SocketException();
- if (false) throw new cli.System.ObjectDisposedException("");
- switch (cmd)
- {
- case SocketOptions.SO_REUSEADDR:
- netSocket.SetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Socket), SocketOptionName.wrap(SocketOptionName.ReuseAddress), on ? 1 : 0);
- break;
- case SocketOptions.SO_SNDBUF:
- netSocket.SetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Socket), SocketOptionName.wrap(SocketOptionName.SendBuffer), ((Integer)value).intValue());
- break;
- case SocketOptions.SO_RCVBUF:
- netSocket.SetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Socket), SocketOptionName.wrap(SocketOptionName.ReceiveBuffer), ((Integer)value).intValue());
- break;
- case SocketOptions.IP_TOS:
- netSocket.SetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.IP), SocketOptionName.wrap(SocketOptionName.TypeOfService), ((Integer)value).intValue());
- break;
- case SocketOptions.SO_BINDADDR: // read-only
- default:
- throw new SocketException("Invalid socket option: " + cmd);
- }
- }
- catch (cli.System.Net.Sockets.SocketException x)
- {
- throw new SocketException(x.getMessage());
- }
- catch (cli.System.ObjectDisposedException x1)
- {
- throw new SocketException("Socket is closed");
- }
- }
-
- static int getCommonSocketOption(cli.System.Net.Sockets.Socket netSocket, int opt, Object iaContainerObj) throws SocketException
- {
- try
- {
- if (false) throw new cli.System.Net.Sockets.SocketException();
- if (false) throw new cli.System.ObjectDisposedException("");
- switch (opt)
- {
- case SocketOptions.SO_REUSEADDR:
- return CIL.unbox_int(netSocket.GetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Socket), SocketOptionName.wrap(SocketOptionName.ReuseAddress))) == 0 ? -1 : 1;
- case SocketOptions.SO_SNDBUF:
- return CIL.unbox_int(netSocket.GetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Socket), SocketOptionName.wrap(SocketOptionName.SendBuffer)));
- case SocketOptions.SO_RCVBUF:
- return CIL.unbox_int(netSocket.GetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Socket), SocketOptionName.wrap(SocketOptionName.ReceiveBuffer)));
- case SocketOptions.IP_TOS:
- // TODO handle IPv6 here
- return CIL.unbox_int(netSocket.GetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.IP), SocketOptionName.wrap(SocketOptionName.TypeOfService)));
- case SocketOptions.SO_BINDADDR:
- ((InetAddressContainer)iaContainerObj).addr = getInetAddressFromIPEndPoint((IPEndPoint)netSocket.get_LocalEndPoint());
- return 0;
- default:
- throw new SocketException("Invalid socket option: " + opt);
- }
- }
- catch (cli.System.Net.Sockets.SocketException x)
- {
- throw new SocketException(x.getMessage());
- }
- catch (cli.System.ObjectDisposedException x1)
- {
- throw new SocketException("Socket is closed");
- }
- }
-}
diff --git a/openjdk/java/net/TwoStacksPlainDatagramSocketImpl.java b/openjdk/java/net/TwoStacksPlainDatagramSocketImpl.java
deleted file mode 100644
index 2b2bde1b..00000000
--- a/openjdk/java/net/TwoStacksPlainDatagramSocketImpl.java
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * Copyright (c) 2007, 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.IOException;
-import java.io.FileDescriptor;
-import sun.net.ResourceManager;
-
-/**
- * This class defines the plain DatagramSocketImpl that is used for all
- * Windows versions lower than Vista. It adds support for IPv6 on
- * these platforms where available.
- *
- * For backward compatibility windows platforms that do not have IPv6
- * support also use this implementation, and fd1 gets set to null
- * during socket creation.
- *
- * @author Chris Hegarty
- */
-
-class TwoStacksPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl
-{
- /* Used for IPv6 on Windows only */
- FileDescriptor fd1;
-
- /*
- * Needed for ipv6 on windows because we need to know
- * if the socket was bound to ::0 or 0.0.0.0, when a caller
- * asks for it. In this case, both sockets are used, but we
- * don't know whether the caller requested ::0 or 0.0.0.0
- * and need to remember it here.
- */
- private InetAddress anyLocalBoundAddr=null;
-
- cli.System.Net.Sockets.Socket fduse=null; /* saved between peek() and receive() calls */
-
- /* saved between successive calls to receive, if data is detected
- * on both sockets at same time. To ensure that one socket is not
- * starved, they rotate using this field
- */
- cli.System.Net.Sockets.Socket lastfd=null;
-
- // true if this socket is exclusively bound
- private final boolean exclusiveBind;
-
- /*
- * Set to true if SO_REUSEADDR is set after the socket is bound to
- * indicate SO_REUSEADDR is being emulated
- */
- private boolean reuseAddressEmulated;
-
- // emulates SO_REUSEADDR when exclusiveBind is true and socket is bound
- private boolean isReuseAddress;
-
- TwoStacksPlainDatagramSocketImpl(boolean exclBind) {
- exclusiveBind = exclBind;
- }
-
- protected synchronized void create() throws SocketException {
- fd1 = new FileDescriptor();
- try {
- super.create();
- } catch (SocketException e) {
- fd1 = null;
- throw e;
- }
- }
-
- protected synchronized void bind(int lport, InetAddress laddr)
- throws SocketException {
- super.bind(lport, laddr);
- if (laddr.isAnyLocalAddress()) {
- anyLocalBoundAddr = laddr;
- }
- }
-
- @Override
- protected synchronized void bind0(int lport, InetAddress laddr)
- throws SocketException
- {
- bind0(lport, laddr, exclusiveBind);
-
- }
-
- protected synchronized void receive(DatagramPacket p)
- throws IOException {
- try {
- receive0(p);
- } finally {
- fduse = null;
- }
- }
-
- public Object getOption(int optID) throws SocketException {
- if (isClosed()) {
- throw new SocketException("Socket Closed");
- }
-
- if (optID == SO_BINDADDR) {
- if (fd != null && fd1 != null) {
- return anyLocalBoundAddr;
- }
- return socketGetOption(optID);
- } else if (optID == SO_REUSEADDR && reuseAddressEmulated) {
- return isReuseAddress;
- } else {
- return super.getOption(optID);
- }
- }
-
- protected void socketSetOption(int opt, Object val)
- throws SocketException
- {
- if (opt == SO_REUSEADDR && exclusiveBind && localPort != 0) {
- // socket already bound, emulate
- reuseAddressEmulated = true;
- isReuseAddress = (Boolean)val;
- } else {
- socketNativeSetOption(opt, val);
- }
-
- }
-
- protected boolean isClosed() {
- return (fd == null && fd1 == null) ? true : false;
- }
-
- protected void close() {
- if (fd != null || fd1 != null) {
- datagramSocketClose();
- ResourceManager.afterUdpClose();
- fd = null;
- fd1 = null;
- }
- }
-
- /* Native methods */
-
- protected synchronized void bind0(int lport, InetAddress laddr,
- boolean exclBind) throws SocketException {
- ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
- TwoStacksPlainDatagramSocketImpl_c.bind0(env, this, lport, laddr, exclBind);
- env.ThrowPendingException();
- }
-
- protected void send(DatagramPacket packet) throws IOException {
- ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
- TwoStacksPlainDatagramSocketImpl_c.send(env, this, packet);
- env.ThrowPendingException();
- }
-
- protected synchronized int peek(InetAddress addressObj) throws IOException {
- ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
- int ret = TwoStacksPlainDatagramSocketImpl_c.peek(env, this, addressObj);
- env.ThrowPendingException();
- return ret;
- }
-
- protected synchronized int peekData(DatagramPacket p) throws IOException {
- ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
- int ret = TwoStacksPlainDatagramSocketImpl_c.peekData(env, this, p);
- env.ThrowPendingException();
- return ret;
- }
-
- protected synchronized void receive0(DatagramPacket packet) throws IOException {
- ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
- TwoStacksPlainDatagramSocketImpl_c.receive0(env, this, packet);
- env.ThrowPendingException();
- }
-
- protected void setTimeToLive(int ttl) throws IOException {
- ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
- TwoStacksPlainDatagramSocketImpl_c.setTimeToLive(env, this, ttl);
- env.ThrowPendingException();
- }
-
- protected int getTimeToLive() throws IOException {
- ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
- int ret = TwoStacksPlainDatagramSocketImpl_c.getTimeToLive(env, this);
- env.ThrowPendingException();
- return ret;
- }
-
- protected void setTTL(byte ttl) throws IOException {
- ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
- TwoStacksPlainDatagramSocketImpl_c.setTTL(env, this, ttl);
- env.ThrowPendingException();
- }
-
- protected byte getTTL() throws IOException {
- ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
- byte ret = TwoStacksPlainDatagramSocketImpl_c.getTTL(env, this);
- env.ThrowPendingException();
- return ret;
- }
-
- protected void join(InetAddress inetaddr, NetworkInterface netIf) throws IOException {
- ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
- TwoStacksPlainDatagramSocketImpl_c.join(env, this, inetaddr, netIf);
- env.ThrowPendingException();
- }
-
- protected void leave(InetAddress inetaddr, NetworkInterface netIf) throws IOException {
- ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
- TwoStacksPlainDatagramSocketImpl_c.leave(env, this, inetaddr, netIf);
- env.ThrowPendingException();
- }
-
- protected void datagramSocketCreate() throws SocketException {
- ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
- TwoStacksPlainDatagramSocketImpl_c.datagramSocketCreate(env, this);
- env.ThrowPendingException();
- }
-
- protected void datagramSocketClose() {
- TwoStacksPlainDatagramSocketImpl_c.datagramSocketClose(this);
- }
-
- protected void socketNativeSetOption(int opt, Object val) throws SocketException {
- ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
- TwoStacksPlainDatagramSocketImpl_c.socketNativeSetOption(env, this, opt, val);
- env.ThrowPendingException();
- }
-
- protected Object socketGetOption(int opt) throws SocketException {
- ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
- Object ret = TwoStacksPlainDatagramSocketImpl_c.socketGetOption(env, this, opt);
- env.ThrowPendingException();
- return ret;
- }
-
- protected void connect0(InetAddress address, int port) throws SocketException {
- if (ikvm.internal.Util.MONO) {
- // MONOBUG Mono doesn't allow Socket.Connect(IPAddress.Any, 0) to disconnect a datagram socket,
- // so we throw a SocketException, this will cause DatagramSocket to emulate connectedness
- throw new SocketException("connected datagram sockets not supported on Mono");
- }
- ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
- TwoStacksPlainDatagramSocketImpl_c.connect0(env, this, address, port);
- env.ThrowPendingException();
- }
-
- protected void disconnect0(int family) {
- TwoStacksPlainDatagramSocketImpl_c.disconnect0(this, family);
- }
-}
diff --git a/openjdk/java/net/TwoStacksPlainDatagramSocketImpl_c.java b/openjdk/java/net/TwoStacksPlainDatagramSocketImpl_c.java
deleted file mode 100644
index d84a427b..00000000
--- a/openjdk/java/net/TwoStacksPlainDatagramSocketImpl_c.java
+++ /dev/null
@@ -1,2463 +0,0 @@
-/*
- * Copyright (c) 1997, 2013, 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 TwoStacksPlainDatagramSocketImpl_c
-{
-static final int ni_class = 0;
-static final int JVM_IO_ERR = -1;
-static final int JVM_IO_INTR = -2;
-
-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_SO_BROADCAST = SocketOptions.SO_BROADCAST;
-static final int java_net_SocketOptions_IP_MULTICAST_LOOP = SocketOptions.IP_MULTICAST_LOOP;
-static final int java_net_SocketOptions_IP_MULTICAST_IF = SocketOptions.IP_MULTICAST_IF;
-static final int java_net_SocketOptions_IP_MULTICAST_IF2 = SocketOptions.IP_MULTICAST_IF2;
-
-/*
-
-#include <windows.h>
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <malloc.h>
-#include <sys/types.h>
-
-#ifndef IPTOS_TOS_MASK
-#define IPTOS_TOS_MASK 0x1e
-#endif
-#ifndef IPTOS_PREC_MASK
-#define IPTOS_PREC_MASK 0xe0
-#endif
-
-#include "java_net_TwoStacksPlainDatagramSocketImpl.h"
-#include "java_net_SocketOptions.h"
-#include "java_net_NetworkInterface.h"
-
-#include "NetworkInterface.h"
-#include "jvm.h"
-#include "jni_util.h"
-#include "net_util.h"
-
-#define IN_CLASSD(i) (((long)(i) & 0xf0000000) == 0xe0000000)
-#define IN_MULTICAST(i) IN_CLASSD(i)
-
-*/
-
-static boolean IN_MULTICAST(int ipv4address) {
- return ((ipv4address >> 24) & 0xf0) == 0xe0;
-}
-
-/************************************************************************
- * TwoStacksPlainDatagramSocketImpl
- */
-
-/*
-static jfieldID IO_fd_fdID;
-static jfieldID pdsi_trafficClassID;
-jfieldID pdsi_fdID;
-jfieldID pdsi_fd1ID;
-jfieldID pdsi_fduseID;
-jfieldID pdsi_lastfdID;
-jfieldID pdsi_timeoutID;
-
-jfieldID pdsi_localPortID;
-jfieldID pdsi_connected;
-
-static jclass ia4_clazz;
-static jmethodID ia4_ctor;
-
-static CRITICAL_SECTION sizeCheckLock;
-*/
-
-/* Windows OS version is XP or better */
-static final boolean xp_or_later = true;
-/* Windows OS version is Windows 2000 or better */
-//static int w2k_or_later = 0;
-
-/*
- * Notes about UDP/IPV6 on Windows (XP and 2003 server):
- *
- * fd always points to the IPv4 fd, and fd1 points to the IPv6 fd.
- * Both fds are used when we bind to a wild-card address. When a specific
- * address is used, only one of them is used.
- */
-
-/*
- * Returns a java.lang.Integer based on 'i'
- */
-/*
-jobject createInteger(JNIEnv *env, int i) {
- static jclass i_class;
- static jmethodID i_ctrID;
- static jfieldID i_valueID;
-
- if (i_class == NULL) {
- jclass c = (*env)->FindClass(env, "java/lang/Integer");
- CHECK_NULL_RETURN(c, NULL);
- i_ctrID = (*env)->GetMethodID(env, c, "<init>", "(I)V");
- CHECK_NULL_RETURN(i_ctrID, NULL);
- i_class = (*env)->NewGlobalRef(env, c);
- CHECK_NULL_RETURN(i_class, NULL);
- }
-
- return ( (*env)->NewObject(env, i_class, i_ctrID, i) );
-}
-*/
-
-/*
- * Returns a java.lang.Boolean based on 'b'
- */
-/*
-jobject createBoolean(JNIEnv *env, int b) {
- static jclass b_class;
- static jmethodID b_ctrID;
- static jfieldID b_valueID;
-
- if (b_class == NULL) {
- jclass c = (*env)->FindClass(env, "java/lang/Boolean");
- CHECK_NULL_RETURN(c, NULL);
- b_ctrID = (*env)->GetMethodID(env, c, "<init>", "(Z)V");
- CHECK_NULL_RETURN(b_ctrID, NULL);
- b_class = (*env)->NewGlobalRef(env, c);
- CHECK_NULL_RETURN(b_class, NULL);
- }
-
- return( (*env)->NewObject(env, b_class, b_ctrID, (jboolean)(b!=0)) );
-}
-*/
-
-
-static cli.System.Net.Sockets.Socket getFD(JNIEnv env, TwoStacksPlainDatagramSocketImpl _this) {
- FileDescriptor fdObj = _this.fd;
-
- if (fdObj == NULL) {
- return null;
- }
- return fdObj.getSocket();
-}
-
-static cli.System.Net.Sockets.Socket getFD1(JNIEnv env, TwoStacksPlainDatagramSocketImpl _this) {
- FileDescriptor fdObj = _this.fd1;
-
- if (fdObj == NULL) {
- return null;
- }
- return fdObj.getSocket();
-}
-
-/*
- * This function returns JNI_TRUE if the datagram size exceeds the underlying
- * provider's ability to send to the target address. The following OS
- * oddities have been observed :-
- *
- * 1. On Windows 95/98 if we try to send a datagram > 12k to an application
- * on the same machine then the send will fail silently.
- *
- * 2. On Windows ME if we try to send a datagram > supported by underlying
- * provider then send will not return an error.
- *
- * 3. On Windows NT/2000 if we exceeds the maximum size then send will fail
- * with WSAEADDRNOTAVAIL.
- *
- * 4. On Windows 95/98 if we exceed the maximum size when sending to
- * another machine then WSAEINVAL is returned.
- *
- */
-/*
-jboolean exceedSizeLimit(JNIEnv *env, jint fd, jint addr, jint size)
-{
-#define DEFAULT_MSG_SIZE 65527
- static jboolean initDone;
- static jboolean is95or98;
- static int maxmsg;
-
- typedef struct _netaddr { /* Windows 95/98 only *-/
- unsigned long addr;
- struct _netaddr *next;
- } netaddr;
- static netaddr *addrList;
- netaddr *curr;
-
- /*
- * First time we are called we must determine which OS this is and also
- * get the maximum size supported by the underlying provider.
- *
- * In addition on 95/98 we must enumerate our IP addresses.
- *-/
- if (!initDone) {
- EnterCriticalSection(&sizeCheckLock);
-
- if (initDone) {
- /* another thread got there first *-/
- LeaveCriticalSection(&sizeCheckLock);
-
- } else {
- OSVERSIONINFO ver;
- int len;
-
- /*
- * Step 1: Determine which OS this is.
- *-/
- ver.dwOSVersionInfoSize = sizeof(ver);
- GetVersionEx(&ver);
-
- is95or98 = JNI_FALSE;
- if (ver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS &&
- ver.dwMajorVersion == 4 &&
- (ver.dwMinorVersion == 0 || ver.dwMinorVersion == 10)) {
-
- is95or98 = JNI_TRUE;
- }
-
- /*
- * Step 2: Determine the maximum datagram supported by the
- * underlying provider. On Windows 95 if winsock hasn't been
- * upgraded (ie: unsupported configuration) then we assume
- * the default 64k limit.
- *-/
- len = sizeof(maxmsg);
- if (NET_GetSockOpt(fd, SOL_SOCKET, SO_MAX_MSG_SIZE, (char *)&maxmsg, &len) < 0) {
- maxmsg = DEFAULT_MSG_SIZE;
- }
-
- /*
- * Step 3: On Windows 95/98 then enumerate the IP addresses on
- * this machine. This is neccesary because we need to check if the
- * datagram is being sent to an application on the same machine.
- *-/
- if (is95or98) {
- char hostname[255];
- struct hostent *hp;
-
- if (gethostname(hostname, sizeof(hostname)) == -1) {
- LeaveCriticalSection(&sizeCheckLock);
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Unable to obtain hostname");
- return JNI_TRUE;
- }
- hp = (struct hostent *)gethostbyname(hostname);
- if (hp != NULL) {
- struct in_addr **addrp = (struct in_addr **) hp->h_addr_list;
-
- while (*addrp != (struct in_addr *) 0) {
- curr = (netaddr *)malloc(sizeof(netaddr));
- if (curr == NULL) {
- while (addrList != NULL) {
- curr = addrList->next;
- free(addrList);
- addrList = curr;
- }
- LeaveCriticalSection(&sizeCheckLock);
- JNU_ThrowOutOfMemoryError(env, "Native heap allocation failed");
- return JNI_TRUE;
- }
- curr->addr = htonl((*addrp)->S_un.S_addr);
- curr->next = addrList;
- addrList = curr;
- addrp++;
- }
- }
- }
-
- /*
- * Step 4: initialization is done so set flag and unlock cs
- *-/
- initDone = JNI_TRUE;
- LeaveCriticalSection(&sizeCheckLock);
- }
- }
-
- /*
- * Now examine the size of the datagram :-
- *
- * (a) If exceeds size of service provider return 'false' to indicate that
- * we exceed the limit.
- * (b) If not 95/98 then return 'true' to indicate that the size is okay.
- * (c) On 95/98 if the size is <12k we are okay.
- * (d) On 95/98 if size > 12k then check if the destination is the current
- * machine.
- *-/
- if (size > maxmsg) { /* step (a) *-/
- return JNI_TRUE;
- }
- if (!is95or98) { /* step (b) *-/
- return JNI_FALSE;
- }
- if (size <= 12280) { /* step (c) *-/
- return JNI_FALSE;
- }
-
- /* step (d) *-/
-
- if ((addr & 0x7f000000) == 0x7f000000) {
- return JNI_TRUE;
- }
- curr = addrList;
- while (curr != NULL) {
- if (curr->addr == addr) {
- return JNI_TRUE;
- }
- curr = curr->next;
- }
- return JNI_FALSE;
-}
-*/
-
-/*
- * Return JNI_TRUE if this Windows edition supports ICMP Port Unreachable
- */
-static boolean supportPortUnreachable() {
- // we don't support anything pre-Win2K anyway
- return true;
-}
-
-/*
- * This function "purges" all outstanding ICMP port unreachable packets
- * outstanding on a socket and returns JNI_TRUE if any ICMP messages
- * have been purged. The rational for purging is to emulate normal BSD
- * behaviour whereby receiving a "connection reset" status resets the
- * socket.
- */
-static boolean purgeOutstandingICMP(cli.System.Net.Sockets.Socket fd)
-{
- boolean got_icmp = false;
- byte[] buf = new byte[1];
- fd_set tbl = new fd_set();
- timeval t = new timeval();
- SOCKETADDRESS rmtaddr = null;
-
- /*
- * A no-op if this OS doesn't support it.
- */
- if (!supportPortUnreachable()) {
- return JNI_FALSE;
- }
-
- /*
- * 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(true) {
- if (select(tbl, null, null, t) <= 0) {
- break;
- }
- if (recvfrom(fd, buf, 1, MSG_PEEK,
- rmtaddr) != JVM_IO_ERR) {
- break;
- }
- if (WSAGetLastError() != WSAECONNRESET) {
- /* some other error - we don't care here */
- break;
- }
-
- recvfrom(fd, buf, 1, 0, rmtaddr);
- got_icmp = JNI_TRUE;
- }
-
- return got_icmp;
-}
-
-
-/*
- * Class: java_net_TwoStacksPlainDatagramSocketImpl
- * Method: init
- * Signature: ()V
- */
-/*
-JNIEXPORT void JNICALL
-Java_java_net_TwoStacksPlainDatagramSocketImpl_init(JNIEnv *env, jclass cls) {
-
- OSVERSIONINFO ver;
- int version;
- ver.dwOSVersionInfoSize = sizeof(ver);
- GetVersionEx(&ver);
-
- version = ver.dwMajorVersion * 10 + ver.dwMinorVersion;
- xp_or_later = (ver.dwPlatformId == VER_PLATFORM_WIN32_NT) && (version >= 51);
- w2k_or_later = (ver.dwPlatformId == VER_PLATFORM_WIN32_NT) && (version >= 50);
-
- /* get fieldIDs *-/
- pdsi_fdID = (*env)->GetFieldID(env, cls, "fd", "Ljava/io/FileDescriptor;");
- CHECK_NULL(pdsi_fdID);
- pdsi_fd1ID = (*env)->GetFieldID(env, cls, "fd1", "Ljava/io/FileDescriptor;");
- CHECK_NULL(pdsi_fd1ID);
- pdsi_timeoutID = (*env)->GetFieldID(env, cls, "timeout", "I");
- CHECK_NULL(pdsi_timeoutID);
- pdsi_fduseID = (*env)->GetFieldID(env, cls, "fduse", "I");
- CHECK_NULL(pdsi_fduseID);
- pdsi_lastfdID = (*env)->GetFieldID(env, cls, "lastfd", "I");
- CHECK_NULL(pdsi_lastfdID);
- pdsi_trafficClassID = (*env)->GetFieldID(env, cls, "trafficClass", "I");
- CHECK_NULL(pdsi_trafficClassID);
- pdsi_localPortID = (*env)->GetFieldID(env, cls, "localPort", "I");
- CHECK_NULL(pdsi_localPortID);
- pdsi_connected = (*env)->GetFieldID(env, cls, "connected", "Z");
- CHECK_NULL(pdsi_connected);
-
- cls = (*env)->FindClass(env, "java/io/FileDescriptor");
- CHECK_NULL(cls);
- IO_fd_fdID = NET_GetFileDescriptorID(env);
- CHECK_NULL(IO_fd_fdID);
-
- ia4_clazz = (*env)->FindClass(env, "java/net/Inet4Address");
- CHECK_NULL(ia4_clazz);
- ia4_clazz = (*env)->NewGlobalRef(env, ia4_clazz);
- CHECK_NULL(ia4_clazz);
- ia4_ctor = (*env)->GetMethodID(env, ia4_clazz, "<init>", "()V");
- CHECK_NULL(ia4_ctor);
-
-
- InitializeCriticalSection(&sizeCheckLock);
-}
-*/
-
-static void bind0(JNIEnv env, TwoStacksPlainDatagramSocketImpl _this,
- int port, InetAddress addressObj,
- boolean exclBind) {
- FileDescriptor fdObj = _this.fd;
- FileDescriptor fd1Obj = _this.fd1;
-
- cli.System.Net.Sockets.Socket fd = null;
- cli.System.Net.Sockets.Socket fd1 = null;
- int family;
- boolean ipv6_supported = ipv6_available();
-
- SOCKETADDRESS lcladdr;
- lcladdr = new SOCKETADDRESS();
-
- family = getInetAddress_family(env, addressObj);
- 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(addressObj)) {
- JNU_ThrowNullPointerException(env, "argument address");
- return;
- }
-
- if (NET_InetAddressToSockaddr(env, addressObj, port, lcladdr, JNI_FALSE) != 0) {
- return;
- }
-
- if (ipv6_supported) {
- ipv6bind v6bind = new ipv6bind();
- v6bind.addr = lcladdr;
- v6bind.ipv4_fd = fd;
- v6bind.ipv6_fd = fd1;
- if (NET_BindV6(v6bind, exclBind) != -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 {
- NET_ThrowCurrent (env, "Cannot bind");
- return;
- }
- } else {
- if (NET_WinBind(fd, lcladdr, exclBind) == -1) {
- if (WSAGetLastError() == WSAEACCES) {
- WSASetLastError(WSAEADDRINUSE);
- }
- NET_ThrowCurrent(env, "Cannot bind");
- return;
- }
- }
-
- if (port == 0) {
- if (fd == null) {
- /* must be an IPV6 only socket. */
- fd = fd1;
- }
- if (getsockname(fd, lcladdr) == -1) {
- NET_ThrowCurrent(env, "JVM_GetSockName");
- return;
- }
- port = ntohs(GET_PORT (lcladdr));
- }
- _this.localPort = port;
-}
-
-
-/*
- * Class: java_net_TwoStacksPlainDatagramSocketImpl
- * Method: connect0
- * Signature: (Ljava/net/InetAddress;I)V
- */
-
-static void connect0(JNIEnv env, TwoStacksPlainDatagramSocketImpl _this, InetAddress address, int port) {
- /* The object's field */
- FileDescriptor fdObj = _this.fd;
- FileDescriptor fd1Obj = _this.fd1;
- /* The fdObj'fd */
- cli.System.Net.Sockets.Socket fd = null;
- cli.System.Net.Sockets.Socket fd1 = null;
- cli.System.Net.Sockets.Socket fdc;
- /* The packetAddress address, family and port */
- int addr, family;
- SOCKETADDRESS rmtaddr;
- rmtaddr = new SOCKETADDRESS();
- boolean ipv6_supported = ipv6_available();
-
- 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(address)) {
- JNU_ThrowNullPointerException(env, "address");
- return;
- }
-
- addr = getInetAddress_addr(env, address);
-
- family = getInetAddress_family(env, address);
- if (family == IPv6 && !ipv6_supported) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
- "Protocol family not supported");
- return;
- }
-
- fdc = family == IPv4? fd: fd1;
-
- if (xp_or_later) {
- /* SIO_UDP_CONNRESET fixes a bug introduced in Windows 2000, which
- * returns connection reset errors on connected UDP sockets (as well
- * as connected sockets). The solution is to only enable this feature
- * when the socket is connected
- */
- WSAIoctl(fdc, SIO_UDP_CONNRESET, true);
- }
-
- if (NET_InetAddressToSockaddr(env, address, port, rmtaddr, JNI_FALSE) != 0) {
- return;
- }
-
- if (connect(fdc, rmtaddr) == -1) {
- NET_ThrowCurrent(env, "connect");
- return;
- }
-}
-
-/*
- * Class: java_net_TwoStacksPlainDatagramSocketImpl
- * Method: disconnect0
- * Signature: ()V
- */
-
-static void disconnect0(TwoStacksPlainDatagramSocketImpl _this, int family) {
- /* The object's field */
- FileDescriptor fdObj;
- /* The fdObj'fd */
- cli.System.Net.Sockets.Socket fd;
- SOCKETADDRESS addr;
- addr = new SOCKETADDRESS();
-
- if (family == IPv4) {
- fdObj = _this.fd;
- } else {
- fdObj = _this.fd1;
- }
-
- if (IS_NULL(fdObj)) {
- /* disconnect doesn't throw any exceptions */
- return;
- }
- fd = fdObj.getSocket();
-
- connect(fd, addr);
-
- /*
- * use SIO_UDP_CONNRESET
- * to disable ICMP port unreachable handling here.
- */
- if (xp_or_later) {
- WSAIoctl(fd,SIO_UDP_CONNRESET,false);
- }
-}
-
-/*
- * Class: java_net_TwoStacksPlainDatagramSocketImpl
- * Method: send
- * Signature: (Ljava/net/DatagramPacket;)V
- */
-static void send(JNIEnv env, TwoStacksPlainDatagramSocketImpl _this, DatagramPacket packet) {
- FileDescriptor fdObj;
- cli.System.Net.Sockets.Socket fd;
-
- InetAddress iaObj;
- int address;
- int family;
-
- int packetBufferOffset, packetBufferLen, packetPort;
- byte[] packetBuffer;
- boolean connected;
-
- SOCKETADDRESS rmtaddr;
- rmtaddr = new SOCKETADDRESS();
-
- if (IS_NULL(packet)) {
- JNU_ThrowNullPointerException(env, "null packet");
- return;
- }
-
- iaObj = packet.address;
-
- packetPort = packet.port;
- packetBufferOffset = packet.offset;
- packetBuffer = packet.buf;
- connected = _this.connected;
-
- if (IS_NULL(iaObj) || IS_NULL(packetBuffer)) {
- JNU_ThrowNullPointerException(env, "null address || null buffer");
- return;
- }
-
- family = getInetAddress_family(env, iaObj);
- if (family == IPv4) {
- fdObj = _this.fd;
- } else {
- if (!ipv6_available()) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
- "Protocol not allowed");
- return;
- }
- fdObj = _this.fd1;
- }
-
- if (IS_NULL(fdObj)) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
- "Socket closed");
- return;
- }
- fd = fdObj.getSocket();
-
- packetBufferLen = packet.length;
- /* Note: the buffer needn't be greater than 65,536 (0xFFFF)...
- * the maximum size of an IP packet. Anything bigger is truncated anyway.
- */
- if (packetBufferLen > MAX_PACKET_LEN) {
- packetBufferLen = MAX_PACKET_LEN;
- }
-
- if (connected) {
- rmtaddr = null;
- } else {
- if (NET_InetAddressToSockaddr(env, iaObj, packetPort, rmtaddr, JNI_FALSE) != 0) {
- return;
- }
- }
-
- /*
- if (packetBufferLen > MAX_BUFFER_LEN) {
-
- /*
- * On 95/98 if we try to send a datagram >12k to an application
- * on the same machine then this will fail silently. Thus we
- * catch this situation here so that we can throw an exception
- * when this arises.
- * On ME if we try to send a datagram with a size greater than
- * that supported by the service provider then no error is
- * returned.
- *-/
- if (!w2k_or_later) { /* avoid this check on Win 2K or better. Does not work with IPv6.
- * Check is not necessary on these OSes *-/
- if (connected) {
- address = getInetAddress_addr(env, iaObj);
- } else {
- address = ntohl(rmtaddr.him4.sin_addr.s_addr);
- }
-
- if (exceedSizeLimit(env, fd, address, packetBufferLen)) {
- if (!((*env)->ExceptionOccurred(env))) {
- NET_ThrowNew(env, WSAEMSGSIZE, "Datagram send failed");
- }
- return;
- }
- }
-
- /* When JNI-ifying the JDK's IO routines, we turned
- * reads and writes of byte arrays of size greater
- * than 2048 bytes into several operations of size 2048.
- * This saves a malloc()/memcpy()/free() for big
- * buffers. This is OK for file IO and TCP, but that
- * strategy violates the semantics of a datagram protocol.
- * (one big send) != (several smaller sends). So here
- * we *must* alloc the buffer. Note it needn't be bigger
- * than 65,536 (0xFFFF) the max size of an IP packet.
- * anything bigger is truncated anyway.
- *-/
- fullPacket = (char *)malloc(packetBufferLen);
- if (!fullPacket) {
- JNU_ThrowOutOfMemoryError(env, "Send buf native heap allocation failed");
- return;
- }
- } else {
- fullPacket = &(BUF[0]);
- }
- */
-
- switch (sendto(fd, packetBuffer, packetBufferOffset, packetBufferLen, 0, rmtaddr)) {
- case JVM_IO_ERR:
- NET_ThrowCurrent(env, "Datagram send failed");
- break;
-
- case JVM_IO_INTR:
- JNU_ThrowByName(env, JNU_JAVAIOPKG+"InterruptedIOException",
- "operation interrupted");
- }
-}
-
-/*
- * check which socket was last serviced when there was data on both sockets.
- * Only call this if sure that there is data on both sockets.
- */
-private static cli.System.Net.Sockets.Socket checkLastFD (TwoStacksPlainDatagramSocketImpl _this, cli.System.Net.Sockets.Socket fd, cli.System.Net.Sockets.Socket fd1) {
- cli.System.Net.Sockets.Socket nextfd, lastfd = _this.lastfd;
- if (lastfd == null) {
- /* arbitrary. Choose fd */
- _this.lastfd = fd;
- return fd;
- } else {
- if (lastfd == fd) {
- nextfd = fd1;
- } else {
- nextfd = fd;
- }
- _this.lastfd = nextfd;
- return nextfd;
- }
-}
-
-/*
- * Class: java_net_TwoStacksPlainDatagramSocketImpl
- * Method: peek
- * Signature: (Ljava/net/InetAddress;)I
- */
-static int peek(JNIEnv env, TwoStacksPlainDatagramSocketImpl _this, InetAddress addressObj) {
- FileDescriptor fdObj = _this.fd;
- int timeout = _this.timeout;
- cli.System.Net.Sockets.Socket fd;
-
- /* The address and family fields of addressObj */
- int address, family;
-
- int n;
- SOCKETADDRESS remote_addr = new SOCKETADDRESS();
- byte[] buf = new byte[1];
- boolean retry;
- long prevTime = 0;
-
- if (IS_NULL(fdObj)) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", "Socket closed");
- return -1;
- } else {
- fd = fdObj.getSocket();
- if (fd == null) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
- "socket closed");
- return -1;
- }
- }
- if (IS_NULL(addressObj)) {
- JNU_ThrowNullPointerException(env, "Null address in peek()");
- return -1;
- } else {
- address = getInetAddress_addr(env, addressObj);
- /* We only handle IPv4 for now. Will support IPv6 once its in the os */
- family = AF_INET;
- }
-
- do {
- retry = FALSE;
-
- /*
- * If a timeout has been specified then we select on the socket
- * waiting for a read event or a timeout.
- */
- if (timeout != 0) {
- int ret;
- prevTime = JVM_CurrentTimeMillis(env, 0);
- ret = NET_Timeout (fd, timeout);
- if (ret == 0) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketTimeoutException",
- "Peek timed out");
- return ret;
- } else if (ret == JVM_IO_ERR) {
- NET_ThrowCurrent(env, "timeout in datagram socket peek");
- return ret;
- } else if (ret == JVM_IO_INTR) {
- JNU_ThrowByName(env, JNU_JAVAIOPKG+"InterruptedIOException",
- "operation interrupted");
- return ret;
- }
- }
-
- /* now try the peek */
- n = recvfrom(fd, buf, 1, MSG_PEEK,
- remote_addr);
-
- if (n == JVM_IO_ERR) {
- if (WSAGetLastError() == WSAECONNRESET) {
- boolean connected;
-
- /*
- * An icmp port unreachable - we must receive this as Windows
- * does not reset the state of the socket until this has been
- * received.
- */
- purgeOutstandingICMP(fd);
-
- connected = _this.connected;
- if (connected) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"PortUnreachableException",
- "ICMP Port Unreachable");
- return 0;
- }
-
- /*
- * If a timeout was specified then we need to adjust it because
- * we may have used up some of the timeout befor the icmp port
- * unreachable arrived.
- */
- if (timeout != 0) {
- long newTime = JVM_CurrentTimeMillis(env, 0);
- timeout -= (newTime - prevTime);
- if (timeout <= 0) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketTimeoutException",
- "Receive timed out");
- return 0;
- }
- prevTime = newTime;
- }
-
- /* Need to retry the recv */
- retry = TRUE;
- }
- }
- } while (retry);
-
- if (n == JVM_IO_ERR && WSAGetLastError() != WSAEMSGSIZE) {
- NET_ThrowCurrent(env, "Datagram peek failed");
- return 0;
- }
- if (n == JVM_IO_INTR) {
- JNU_ThrowByName(env, JNU_JAVAIOPKG+"InterruptedIOException", null);
- return 0;
- }
- addressObj.holder().address = ntohl(remote_addr.sin_addr.s_addr);
- addressObj.holder().family = IPv4;
-
- /* return port */
- return ntohs(remote_addr.sin_port);
-}
-
-static int peekData(JNIEnv env, TwoStacksPlainDatagramSocketImpl _this, DatagramPacket packet) {
-
- FileDescriptor fdObj = _this.fd;
- FileDescriptor fd1Obj = _this.fd1;
- int timeout = _this.timeout;
-
- byte[] packetBuffer;
- int packetBufferOffset, packetBufferLen;
-
- cli.System.Net.Sockets.Socket fd = null, fd1 = null, fduse = null;
- int nsockets=0, errorCode;
- int port;
- byte[] data;
-
- boolean checkBoth = false;
- int datalen;
- int n;
- SOCKETADDRESS remote_addr;
- remote_addr = new SOCKETADDRESS();
- boolean retry;
- long prevTime = 0;
-
- if (!IS_NULL(fdObj)) {
- fd = fdObj.getSocket();
- if (fd == null) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
- "socket closed");
- return -1;
- }
- nsockets = 1;
- }
-
- if (!IS_NULL(fd1Obj)) {
- fd1 = fd1Obj.getSocket();
- if (fd1 == null) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
- "socket closed");
- return -1;
- }
- nsockets ++;
- }
-
- switch (nsockets) {
- case 0:
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
- "socket closed");
- return -1;
- case 1:
- if (!IS_NULL(fdObj)) {
- fduse = fd;
- } else {
- fduse = fd1;
- }
- break;
- case 2:
- checkBoth = TRUE;
- break;
- }
-
- if (IS_NULL(packet)) {
- JNU_ThrowNullPointerException(env, "packet");
- return -1;
- }
-
- packetBuffer = packet.buf;
-
- if (IS_NULL(packetBuffer)) {
- JNU_ThrowNullPointerException(env, "packet buffer");
- return -1;
- }
-
- packetBufferOffset = packet.offset;
- packetBufferLen = packet.bufLength;
-
- /*
- if (packetBufferLen > MAX_BUFFER_LEN) {
-
- /* When JNI-ifying the JDK's IO routines, we turned
- * read's and write's of byte arrays of size greater
- * than 2048 bytes into several operations of size 2048.
- * This saves a malloc()/memcpy()/free() for big
- * buffers. This is OK for file IO and TCP, but that
- * strategy violates the semantics of a datagram protocol.
- * (one big send) != (several smaller sends). So here
- * we *must* alloc the buffer. Note it needn't be bigger
- * than 65,536 (0xFFFF) the max size of an IP packet.
- * anything bigger is truncated anyway.
- *-/
- fullPacket = (char *)malloc(packetBufferLen);
- if (!fullPacket) {
- JNU_ThrowOutOfMemoryError(env, "Native heap allocation failed");
- return -1;
- }
- } else {
- fullPacket = &(BUF[0]);
- }
- */
-
- do {
- int ret;
- retry = FALSE;
-
- /*
- * If a timeout has been specified then we select on the socket
- * waiting for a read event or a timeout.
- */
- if (checkBoth) {
- int t = timeout == 0 ? -1: timeout;
- prevTime = JVM_CurrentTimeMillis(env, 0);
- cli.System.Net.Sockets.Socket[] tmp = new cli.System.Net.Sockets.Socket[] { fduse };
- ret = NET_Timeout2 (fd, fd1, t, tmp);
- fduse = tmp[0];
- /* all subsequent calls to recv() or select() will use the same fd
- * for this call to peek() */
- if (ret <= 0) {
- if (ret == 0) {
- JNU_ThrowByName(env,JNU_JAVANETPKG+"SocketTimeoutException",
- "Peek timed out");
- } else if (ret == JVM_IO_ERR) {
- NET_ThrowCurrent(env, "timeout in datagram socket peek");
- } else if (ret == JVM_IO_INTR) {
- JNU_ThrowByName(env, JNU_JAVAIOPKG+"InterruptedIOException",
- "operation interrupted");
- }
- return -1;
- }
- if (ret == 2) {
- fduse = checkLastFD (_this, fd, fd1);
- }
- checkBoth = FALSE;
- } else if (timeout != 0) {
- if (prevTime == 0) {
- prevTime = JVM_CurrentTimeMillis(env, 0);
- }
- ret = NET_Timeout (fduse, timeout);
- if (ret <= 0) {
- if (ret == 0) {
- JNU_ThrowByName(env,JNU_JAVANETPKG+"SocketTimeoutException",
- "Receive timed out");
- } else if (ret == JVM_IO_ERR) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
- "Socket closed");
- } else if (ret == JVM_IO_INTR) {
- JNU_ThrowByName(env, JNU_JAVAIOPKG+"InterruptedIOException",
- "operation interrupted");
- }
- return -1;
- }
- }
-
- /* receive the packet */
- n = recvfrom(fduse, packetBuffer, packetBufferOffset, packetBufferLen, MSG_PEEK, remote_addr);
- port = ntohs (GET_PORT(remote_addr));
- if (n == JVM_IO_ERR) {
- if (WSAGetLastError() == WSAECONNRESET) {
- boolean connected;
-
- /*
- * An icmp port unreachable - we must receive this as Windows
- * does not reset the state of the socket until this has been
- * received.
- */
- purgeOutstandingICMP(fduse);
-
- connected = _this.connected;
- if (connected) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"PortUnreachableException",
- "ICMP Port Unreachable");
-
- return -1;
- }
-
- /*
- * If a timeout was specified then we need to adjust it because
- * we may have used up some of the timeout befor the icmp port
- * unreachable arrived.
- */
- if (timeout != 0) {
- long newTime = JVM_CurrentTimeMillis(env, 0);
- timeout -= (newTime - prevTime);
- if (timeout <= 0) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketTimeoutException",
- "Receive timed out");
- return -1;
- }
- prevTime = newTime;
- }
- retry = TRUE;
- }
- }
- } while (retry);
-
- if (n < 0) {
- errorCode = WSAGetLastError();
- /* check to see if it's because the buffer was too small */
- if (errorCode == WSAEMSGSIZE) {
- /* it is because the buffer is too small. It's UDP, it's
- * unreliable, it's all good. discard the rest of the
- * data..
- */
- n = packetBufferLen;
- } else {
- /* failure */
- packet.length = 0;
- }
- }
- if (n == -1) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", "socket closed");
- } else if (n == -2) {
- JNU_ThrowByName(env, JNU_JAVAIOPKG+"InterruptedIOException",
- "operation interrupted");
- } else if (n < 0) {
- NET_ThrowCurrent(env, "Datagram receive failed");
- } else {
- 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 = packet.address;
- if (packetAddress != NULL) {
- if (!NET_SockaddrEqualsInetAddress(remote_addr, packetAddress)) {
- /* force a new InetAddress to be created */
- packetAddress = null;
- }
- }
- if (packetAddress == NULL) {
- int[] tmp = { port };
- packetAddress = NET_SockaddrToInetAddress(remote_addr, tmp);
- port = tmp[0];
- /* stuff the new Inetaddress in the packet */
- packet.address = packetAddress;
- }
-
- /* populate the packet */
- packet.port = port;
- packet.length = n;
- }
-
- /* make sure receive() picks up the right fd */
- _this.fduse = fduse;
-
- return port;
-}
-
-/*
- * Class: java_net_TwoStacksPlainDatagramSocketImpl
- * Method: receive
- * Signature: (Ljava/net/DatagramPacket;)V
- */
-static void receive0(JNIEnv env, TwoStacksPlainDatagramSocketImpl _this, DatagramPacket packet) {
- FileDescriptor fdObj = _this.fd;
- FileDescriptor fd1Obj = _this.fd1;
- int timeout = _this.timeout;
- byte[] packetBuffer;
- int packetBufferOffset, packetBufferLen;
- boolean ipv6_supported = ipv6_available();
-
- /* as a result of the changes for ipv6, peek() or peekData()
- * must be called prior to receive() so that fduse can be set.
- */
- cli.System.Net.Sockets.Socket fd = null;
- cli.System.Net.Sockets.Socket fd1 = null;
- cli.System.Net.Sockets.Socket fduse = null;
- int errorCode;
-
- int n, nsockets=0;
- SOCKETADDRESS remote_addr;
- remote_addr = new SOCKETADDRESS();
- boolean retry;
- long prevTime = 0, selectTime=0;
- boolean connected;
-
- if (IS_NULL(fdObj) && IS_NULL(fd1Obj)) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
- "Socket closed");
- return;
- }
-
- if (!IS_NULL(fdObj)) {
- fd = fdObj.getSocket();
- nsockets ++;
- }
- if (!IS_NULL(fd1Obj)) {
- fd1 = fd1Obj.getSocket();
- nsockets ++;
- }
-
- if (nsockets == 2) { /* need to choose one of them */
- /* was fduse set in peek? */
- fduse = _this.fduse;
- if (fduse == null) {
- /* not set in peek(), must select on both sockets */
- int ret, t = (timeout == 0) ? -1: timeout;
- cli.System.Net.Sockets.Socket[] tmp = new cli.System.Net.Sockets.Socket[] { fduse };
- ret = NET_Timeout2 (fd, fd1, t, tmp);
- fduse = tmp[0];
- if (ret == 2) {
- fduse = checkLastFD (_this, fd, fd1);
- } else if (ret <= 0) {
- if (ret == 0) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketTimeoutException",
- "Receive timed out");
- } else if (ret == JVM_IO_ERR) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
- "Socket closed");
- } else if (ret == JVM_IO_INTR) {
- JNU_ThrowByName(env, JNU_JAVAIOPKG+"InterruptedIOException",
- "operation interrupted");
- }
- return;
- }
- }
- } else if (!ipv6_supported) {
- fduse = fd;
- } else if (IS_NULL(fdObj)) {
- /* ipv6 supported: and this socket bound to an IPV6 only address */
- fduse = fd1;
- } else {
- /* ipv6 supported: and this socket bound to an IPV4 only address */
- fduse = fd;
- }
-
- if (IS_NULL(packet)) {
- JNU_ThrowNullPointerException(env, "packet");
- return;
- }
-
- packetBuffer = packet.buf;
-
- if (IS_NULL(packetBuffer)) {
- JNU_ThrowNullPointerException(env, "packet buffer");
- return;
- }
-
- packetBufferOffset = packet.offset;
- packetBufferLen = packet.bufLength;
-
- /*
- if (packetBufferLen > MAX_BUFFER_LEN) {
-
- /* When JNI-ifying the JDK's IO routines, we turned
- * read's and write's of byte arrays of size greater
- * than 2048 bytes into several operations of size 2048.
- * This saves a malloc()/memcpy()/free() for big
- * buffers. This is OK for file IO and TCP, but that
- * strategy violates the semantics of a datagram protocol.
- * (one big send) != (several smaller sends). So here
- * we *must* alloc the buffer. Note it needn't be bigger
- * than 65,536 (0xFFFF) the max size of an IP packet.
- * anything bigger is truncated anyway.
- *-/
- fullPacket = (char *)malloc(packetBufferLen);
- if (!fullPacket) {
- JNU_ThrowOutOfMemoryError(env, "Receive buf native heap allocation failed");
- return;
- }
- } else {
- fullPacket = &(BUF[0]);
- }
- */
-
-
-
- /*
- * If this Windows edition supports ICMP port unreachable and if we
- * are not connected then we need to know if a timeout has been specified
- * and if so we need to pick up the current time. These are required in
- * order to implement the semantics of timeout, viz :-
- * timeout set to t1 but ICMP port unreachable arrives in t2 where
- * t2 < t1. In this case we must discard the ICMP packets and then
- * wait for the next packet up to a maximum of t1 minus t2.
- */
- connected = _this.connected;
- if (supportPortUnreachable() && !connected && timeout != 0 &&!ipv6_supported) {
- prevTime = JVM_CurrentTimeMillis(env, 0);
- }
-
- if (timeout != 0 && nsockets == 1) {
- int ret;
- ret = NET_Timeout(fduse, timeout);
- if (ret <= 0) {
- if (ret == 0) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketTimeoutException",
- "Receive timed out");
- } else if (ret == JVM_IO_ERR) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
- "Socket closed");
- } else if (ret == JVM_IO_INTR) {
- JNU_ThrowByName(env, JNU_JAVAIOPKG+"InterruptedIOException",
- "operation interrupted");
- }
- return;
- }
- }
-
- /*
- * Loop only if we discarding ICMP port unreachable packets
- */
- do {
- retry = FALSE;
-
- /* receive the packet */
- n = recvfrom(fduse, packetBuffer, packetBufferOffset, packetBufferLen, 0, remote_addr);
-
- if (n == JVM_IO_ERR) {
- if (WSAGetLastError() == WSAECONNRESET) {
- /*
- * An icmp port unreachable has been received - consume any other
- * outstanding packets.
- */
- purgeOutstandingICMP(fduse);
-
- /*
- * If connected throw a PortUnreachableException
- */
-
- if (connected) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"PortUnreachableException",
- "ICMP Port Unreachable");
- return;
- }
-
- /*
- * If a timeout was specified then we need to adjust it because
- * we may have used up some of the timeout before the icmp port
- * unreachable arrived.
- */
- if (timeout != 0) {
- int ret;
- long newTime = JVM_CurrentTimeMillis(env, 0);
- timeout -= (newTime - prevTime);
- prevTime = newTime;
-
- if (timeout <= 0) {
- ret = 0;
- } else {
- ret = NET_Timeout(fduse, timeout);
- }
-
- if (ret <= 0) {
- if (ret == 0) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketTimeoutException",
- "Receive timed out");
- } else if (ret == JVM_IO_ERR) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
- "Socket closed");
- } else if (ret == JVM_IO_INTR) {
- JNU_ThrowByName(env, JNU_JAVAIOPKG+"InterruptedIOException",
- "operation interrupted");
- }
- return;
- }
- }
-
- /*
- * An ICMP port unreachable was received but we are
- * not connected so ignore it.
- */
- retry = TRUE;
- }
- }
- } while (retry);
-
- if (n < 0) {
- errorCode = WSAGetLastError();
- /* check to see if it's because the buffer was too small */
- if (errorCode == WSAEMSGSIZE) {
- /* it is because the buffer is too small. It's UDP, it's
- * unreliable, it's all good. discard the rest of the
- * data..
- */
- n = packetBufferLen;
- } else {
- /* failure */
- packet.length = 0;
- }
- }
- if (n == -1) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", "socket closed");
- } else if (n == -2) {
- JNU_ThrowByName(env, JNU_JAVAIOPKG+"InterruptedIOException",
- "operation interrupted");
- } else if (n < 0) {
- NET_ThrowCurrent(env, "Datagram receive failed");
- } else {
- int port;
- 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 = packet.address;
-
- if (packetAddress != NULL) {
- if (!NET_SockaddrEqualsInetAddress(remote_addr, packetAddress)) {
- /* force a new InetAddress to be created */
- packetAddress = null;
- }
- }
- if (packetAddress == NULL) {
- int[] tmp = { 0 };
- packetAddress = NET_SockaddrToInetAddress(remote_addr, tmp);
- port = tmp[0];
- /* stuff the new Inetaddress in the packet */
- packet.address = packetAddress;
- } else {
- /* only get the new port number */
- port = NET_GetPortFromSockaddr(remote_addr);
- }
- /* populate the packet */
- packet.port = port;
- packet.length = n;
- }
-}
-
-/*
- * Class: java_net_TwoStacksPlainDatagramSocketImpl
- * Method: datagramSocketCreate
- * Signature: ()V
- */
-static void datagramSocketCreate(JNIEnv env, TwoStacksPlainDatagramSocketImpl _this) {
- 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();
-
- if (IS_NULL(fdObj) || (ipv6_supported && IS_NULL(fd1Obj))) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", "Socket closed");
- return;
- } else {
- fd = socket (AF_INET, SOCK_DGRAM, 0);
- }
- if (fd == INVALID_SOCKET) {
- NET_ThrowCurrent(env, "Socket creation failed");
- return;
- }
- fdObj.setSocket(fd);
- NET_SetSockOpt(fd, SOL_SOCKET, SO_BROADCAST, true);
-
- if (ipv6_supported) {
- /* SIO_UDP_CONNRESET fixes a bug introduced in Windows 2000, which
- * returns connection reset errors un connected UDP sockets (as well
- * as connected sockets. The solution is to only enable this feature
- * when the socket is connected
- */
- WSAIoctl(fd,SIO_UDP_CONNRESET,false);
- fd1 = socket (AF_INET6, SOCK_DGRAM, 0);
- if (fd1 == INVALID_SOCKET) {
- NET_ThrowCurrent(env, "Socket creation failed");
- return;
- }
- NET_SetSockOpt(fd1, SOL_SOCKET, SO_BROADCAST, true);
- WSAIoctl(fd1,SIO_UDP_CONNRESET,false);
- fd1Obj.setSocket(fd1);
- } else {
- /* drop the second fd */
- _this.fd1 = null;
- }
-}
-
-/*
- * Class: java_net_TwoStacksPlainDatagramSocketImpl
- * Method: datagramSocketClose
- * Signature: ()V
- */
-static void datagramSocketClose(TwoStacksPlainDatagramSocketImpl _this) {
- /*
- * REMIND: PUT A LOCK AROUND THIS CODE
- */
- FileDescriptor fdObj = _this.fd;
- FileDescriptor fd1Obj = _this.fd1;
- boolean ipv6_supported = ipv6_available();
- cli.System.Net.Sockets.Socket fd = null, fd1 = null;
-
- if (IS_NULL(fdObj) && (!ipv6_supported || IS_NULL(fd1Obj))) {
- return;
- }
-
- if (!IS_NULL(fdObj)) {
- fd = fdObj.getSocket();
- if (fd != null) {
- fdObj.setSocket(null);
- NET_SocketClose(fd);
- }
- }
-
- if (ipv6_supported && fd1Obj != NULL) {
- fd1 = fd1Obj.getSocket();
- if (fd1 == null) {
- return;
- }
- fd1Obj.setSocket(null);
- NET_SocketClose(fd1);
- }
-}
-
-/*
- * check the addresses attached to the NetworkInterface object
- * and return the first one (of the requested family Ipv4 or Ipv6)
- * in *iaddr
- */
-
-private static int getInetAddrFromIf (JNIEnv env, int family, NetworkInterface nif, InetAddress[] iaddr)
-{
- InetAddress[] addrArray;
- int len;
- InetAddress addr;
- int i;
-
- addrArray = getNetworkInterfaceAddresses(nif);
- len = addrArray.length;
-
- /*
- * Check that there is at least one address bound to this
- * interface.
- */
- if (len < 1) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
- "bad argument for IP_MULTICAST_IF2: No IP addresses bound to interface");
- return -1;
- }
- for (i=0; i<len; i++) {
- int fam;
- addr = addrArray[i];
- fam = getInetAddress_family(env, addr);
- if (fam == family) {
- iaddr[0] = addr;
- return 0;
- }
- }
- return -1;
-}
-
-private static int getInet4AddrFromIf (JNIEnv env, NetworkInterface nif, in_addr iaddr)
-{
- InetAddress[] addr = new InetAddress[1];
-
- int ret = getInetAddrFromIf (env, IPv4, nif, addr);
- if (ret == -1) {
- return -1;
- }
-
- iaddr.s_addr = htonl(getInetAddress_addr(env, addr[0]));
- return 0;
-}
-
-/* Get the multicasting index from the interface */
-
-private static int getIndexFromIf (JNIEnv env, NetworkInterface nif) {
- return nif.getIndex();
-}
-
-private static InetAddress[] getNetworkInterfaceAddresses(final NetworkInterface nif) {
- // [IKVM] this is IKVM specific, because I don't want to use reflection (or map.xml hacks) to access the "addrs" member of NetworkInterface
- return java.security.AccessController.doPrivileged(new java.security.PrivilegedAction<InetAddress[]>() {
- public InetAddress[] run() {
- java.util.ArrayList<InetAddress> list = new java.util.ArrayList<InetAddress>();
- for (java.util.Enumeration<InetAddress> e = nif.getInetAddresses(); e.hasMoreElements(); ) {
- list.add(e.nextElement());
- }
- return list.toArray(new InetAddress[list.size()]);
- }
- });
-}
-
-static int isAdapterIpv6Enabled(JNIEnv env, int index) {
- return java.security.AccessController.doPrivileged(new java.security.PrivilegedAction<Integer>() {
- public Integer run() {
- try {
- for (java.util.Enumeration<InetAddress> e = NetworkInterface.getByIndex(index).getInetAddresses(); e.hasMoreElements(); ) {
- if (e.nextElement() instanceof Inet6Address) {
- return 1;
- }
- }
- } catch (SocketException x) {
- }
- return 0;
- }
- }).intValue();
-}
-
-private static NetworkInterface Java_java_net_NetworkInterface_getByIndex(JNIEnv env, int ni_class, int index)
-{
- try {
- return NetworkInterface.getByIndex(index);
- } catch (Exception x) {
- env.Throw(x);
- return null;
- }
-}
-
-private static NetworkInterface Java_java_net_NetworkInterface_getByInetAddress0(JNIEnv env, int ni_class, Object address)
-{
- try {
- return NetworkInterface.getByInetAddress((InetAddress)address);
- } catch (Exception x) {
- env.Throw(x);
- return null;
- }
-}
-
-/*
- * Sets the multicast interface.
- *
- * SocketOptions.IP_MULTICAST_IF (argument is an InetAddress) :-
- * IPv4: set outgoing multicast interface using
- * IPPROTO_IP/IP_MULTICAST_IF
- *
- * IPv6: Get the interface to which the
- * InetAddress is bound
- * and do same as SockOptions.IF_MULTICAST_IF2
- *
- * SockOptions.IF_MULTICAST_IF2 (argument is a NetworkInterface ) :-
- * For each stack:
- * IPv4: Obtain IP address bound to network interface
- * (NetworkInterface.addres[0])
- * set outgoing multicast interface using
- * IPPROTO_IP/IP_MULTICAST_IF
- *
- * IPv6: Obtain NetworkInterface.index
- * Set outgoing multicast interface using
- * IPPROTO_IPV6/IPV6_MULTICAST_IF
- *
- */
-private static void setMulticastInterface(JNIEnv env, TwoStacksPlainDatagramSocketImpl _this, cli.System.Net.Sockets.Socket fd, cli.System.Net.Sockets.Socket fd1,
- int opt, Object value)
-{
- boolean ipv6_supported = ipv6_available();
-
- if (opt == java_net_SocketOptions_IP_MULTICAST_IF) {
- /*
- * value is an InetAddress.
- * On IPv4 system use IP_MULTICAST_IF socket option
- * On IPv6 system get the NetworkInterface that this IP
- * address is bound to and use the IPV6_MULTICAST_IF
- * option instead of IP_MULTICAST_IF
- */
- if (ipv6_supported) {
- value = Java_java_net_NetworkInterface_getByInetAddress0(env, ni_class, value);
- if (value == NULL) {
- if (env.ExceptionOccurred() == null) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
- "bad argument for IP_MULTICAST_IF"
- +": address not bound to any interface");
- }
- return;
- }
- opt = java_net_SocketOptions_IP_MULTICAST_IF2;
- } else {
- in_addr in = new in_addr();
-
- in.s_addr = htonl(getInetAddress_addr(env, (InetAddress)value));
-
- if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
- in) < 0) {
- NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG+"SocketException",
- "Error setting socket option");
- }
- return;
- }
- }
-
- if (opt == java_net_SocketOptions_IP_MULTICAST_IF2) {
- /*
- * value is a NetworkInterface.
- * On IPv6 system get the index of the interface and use the
- * IPV6_MULTICAST_IF socket option
- * On IPv4 system extract addr[0] and use the IP_MULTICAST_IF
- * option. For IPv6 both must be done.
- */
- if (ipv6_supported) {
- in_addr in = new in_addr();
- int index;
-
- index = ((NetworkInterface)value).getIndex();
-
- if ( isAdapterIpv6Enabled(env, index) != 0 ) {
- if (setsockopt(fd1, IPPROTO_IPV6, IPV6_MULTICAST_IF,
- index) < 0) {
- if (WSAGetLastError() == WSAEINVAL && index > 0) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
- "IPV6_MULTICAST_IF failed (interface has IPv4 "
- +"address only?)");
- } else {
- NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG+"SocketException",
- "Error setting socket option");
- }
- return;
- }
- }
-
- /* If there are any IPv4 addresses on this interface then
- * repeat the operation on the IPv4 fd */
-
- if (getInet4AddrFromIf (env, (NetworkInterface)value, in) < 0) {
- return;
- }
- if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
- in) < 0) {
- NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG+"SocketException",
- "Error setting socket option");
- }
- return;
- } else {
- in_addr in = new in_addr();
-
- if (getInet4AddrFromIf (env, (NetworkInterface)value, in) < 0) {
- if (env.ExceptionOccurred() != null) {
- return;
- }
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
- "no InetAddress instances of requested type");
- return;
- }
-
- if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
- in) < 0) {
- NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG+"SocketException",
- "Error setting socket option");
- }
- return;
- }
- }
-}
-
-/*
- * Class: java_net_TwoStacksPlainDatagramSocketImpl
- * Method: socketNativeSetOption
- * Signature: (ILjava/lang/Object;)V
- */
-static void socketNativeSetOption(JNIEnv env, TwoStacksPlainDatagramSocketImpl _this, int opt, Object value) {
- cli.System.Net.Sockets.Socket fd = null;
- cli.System.Net.Sockets.Socket fd1 = null;
- int[] levelv4 = new int[1];
- int[] levelv6 = new int[1];
- int[] optnamev4 = new int[1];
- int[] optnamev6 = new int[1];
- Object optval;
- boolean ipv6_supported = ipv6_available();
-
- fd = getFD(env, _this);
-
- if (ipv6_supported) {
- fd1 = getFD1(env, _this);
- }
- if (fd == null && fd1 == null) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", "socket closed");
- return;
- }
-
- if ((opt == java_net_SocketOptions_IP_MULTICAST_IF) ||
- (opt == java_net_SocketOptions_IP_MULTICAST_IF2)) {
-
- setMulticastInterface(env, _this, fd, fd1, opt, value);
- return;
- }
-
- /*
- * Map the Java level socket option to the platform specific
- * level(s) and option name(s).
- */
- if (fd1 != null) {
- if (NET_MapSocketOptionV6(opt, levelv6, optnamev6) != 0) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", "Invalid option");
- return;
- }
- }
- if (fd != null) {
- if (NET_MapSocketOption(opt, levelv4, optnamev4) != 0) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", "Invalid option");
- return;
- }
- }
-
- switch (opt) {
- 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_REUSEADDR:
- case java_net_SocketOptions_SO_BROADCAST:
- case java_net_SocketOptions_IP_MULTICAST_LOOP:
- {
- boolean on = ((Boolean)value).booleanValue();
- optval = on;
- /*
- * setLoopbackMode (true) disables IP_MULTICAST_LOOP rather
- * than enabling it.
- */
- if (opt == java_net_SocketOptions_IP_MULTICAST_LOOP) {
- optval = !on;
- }
- }
- break;
-
- default :
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
- "Socket option not supported by PlainDatagramSocketImp");
- return;
- }
-
- if (fd1 != null) {
- if (NET_SetSockOpt(fd1, levelv6[0], optnamev6[0], optval) < 0) {
- NET_ThrowCurrent(env, "setsockopt IPv6");
- return;
- }
- }
- if (fd != null) {
- if (NET_SetSockOpt(fd, levelv4[0], optnamev4[0], optval) < 0) {
- NET_ThrowCurrent(env, "setsockopt");
- return;
- }
- }
-}
-
-/*
- *
- * called by getMulticastInterface to retrieve a NetworkInterface
- * configured for IPv4.
- * The ipv4Mode parameter, is a closet boolean, which allows for a NULL return,
- * or forces the creation of a NetworkInterface object with null data.
- * It relates to its calling context in getMulticastInterface.
- * ipv4Mode == 1, the context is IPV4 processing only.
- * ipv4Mode == 0, the context is IPV6 processing
- *
- *-/
-static jobject getIPv4NetworkInterface (JNIEnv *env, jobject this, int fd, jint opt, int ipv4Mode) {
- static jclass inet4_class;
- static jmethodID inet4_ctrID;
-
- static jclass ni_class; static jmethodID ni_ctrID;
- static jfieldID ni_indexID;
- static jfieldID ni_addrsID;
-
- jobjectArray addrArray;
- jobject addr;
- jobject ni;
-
- struct in_addr in;
- struct in_addr *inP = &in;
- int len = sizeof(struct in_addr);
- if (getsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
- (char *)inP, &len) < 0) {
- NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
- "Error getting socket option");
- return NULL;
- }
-
- /*
- * Construct and populate an Inet4Address
- *-/
- if (inet4_class == NULL) {
- jclass c = (*env)->FindClass(env, "java/net/Inet4Address");
- CHECK_NULL_RETURN(c, NULL);
- inet4_ctrID = (*env)->GetMethodID(env, c, "<init>", "()V");
- CHECK_NULL_RETURN(inet4_ctrID, NULL);
- inet4_class = (*env)->NewGlobalRef(env, c);
- CHECK_NULL_RETURN(inet4_class, NULL);
- }
- addr = (*env)->NewObject(env, inet4_class, inet4_ctrID, 0);
- CHECK_NULL_RETURN(addr, NULL);
-
- setInetAddress_addr(env, addr, ntohl(in.s_addr));
-
- /*
- * For IP_MULTICAST_IF return InetAddress
- *-/
- if (opt == java_net_SocketOptions_IP_MULTICAST_IF) {
- return addr;
- }
-
- /*
- * For IP_MULTICAST_IF2 we get the NetworkInterface for
- * this address and return it
- *-/
- if (ni_class == NULL) {
- jclass c = (*env)->FindClass(env, "java/net/NetworkInterface");
- CHECK_NULL_RETURN(c, NULL);
- ni_ctrID = (*env)->GetMethodID(env, c, "<init>", "()V");
- CHECK_NULL_RETURN(ni_ctrID, NULL);
- ni_indexID = (*env)->GetFieldID(env, c, "index", "I");
- CHECK_NULL_RETURN(ni_indexID, NULL);
- ni_addrsID = (*env)->GetFieldID(env, c, "addrs",
- "[Ljava/net/InetAddress;");
- CHECK_NULL_RETURN(ni_addrsID, NULL);
- ni_class = (*env)->NewGlobalRef(env, c);
- CHECK_NULL_RETURN(ni_class, NULL);
- }
- ni = Java_java_net_NetworkInterface_getByInetAddress0(env, ni_class, addr);
- if (ni) {
- return ni;
- }
- if (ipv4Mode) {
- ni = (*env)->NewObject(env, ni_class, ni_ctrID, 0);
- CHECK_NULL_RETURN(ni, NULL);
-
- (*env)->SetIntField(env, ni, ni_indexID, -1);
- addrArray = (*env)->NewObjectArray(env, 1, inet4_class, NULL);
- CHECK_NULL_RETURN(addrArray, NULL);
- (*env)->SetObjectArrayElement(env, addrArray, 0, addr);
- (*env)->SetObjectField(env, ni, ni_addrsID, addrArray);
- } else {
- ni = NULL;
- }
- return ni;
-}
-
-/*
- * Return the multicast interface:
- *
- * SocketOptions.IP_MULTICAST_IF
- * IPv4: Query IPPROTO_IP/IP_MULTICAST_IF
- * Create InetAddress
- * IP_MULTICAST_IF returns struct ip_mreqn on 2.2
- * kernel but struct in_addr on 2.4 kernel
- * IPv6: Query IPPROTO_IPV6 / IPV6_MULTICAST_IF or
- * obtain from impl is Linux 2.2 kernel
- * If index == 0 return InetAddress representing
- * anyLocalAddress.
- * If index > 0 query NetworkInterface by index
- * and returns addrs[0]
- *
- * SocketOptions.IP_MULTICAST_IF2
- * IPv4: Query IPPROTO_IP/IP_MULTICAST_IF
- * Query NetworkInterface by IP address and
- * return the NetworkInterface that the address
- * is bound too.
- * IPv6: Query IPPROTO_IPV6 / IPV6_MULTICAST_IF
- * (except Linux .2 kernel)
- * Query NetworkInterface by index and
- * return NetworkInterface.
- */
-private static Object getMulticastInterface(JNIEnv env, TwoStacksPlainDatagramSocketImpl _this, cli.System.Net.Sockets.Socket fd, cli.System.Net.Sockets.Socket fd1, int opt) {
- boolean isIPV4 = !ipv6_available() || fd1 == null;
-
- /*
- * IPv4 implementation
- */
- if (isIPV4) {
- Inet4Address addr;
-
- in_addr in = new in_addr();
-
- if (getsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
- in) < 0) {
- NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG+"SocketException",
- "Error getting socket option");
- return NULL;
- }
-
- /*
- * Construct and populate an Inet4Address
- */
- addr = new Inet4Address();
- addr.holder().address = ntohl(in.s_addr);
-
- /*
- * For IP_MULTICAST_IF return InetAddress
- */
- if (opt == java_net_SocketOptions_IP_MULTICAST_IF) {
- return addr;
- }
-
- NetworkInterface ni;
- ni = Java_java_net_NetworkInterface_getByInetAddress0(env, ni_class, addr);
- if (ni != null) {
- return ni;
- }
-
- /*
- * The address doesn't appear to be bound at any known
- * NetworkInterface. Therefore we construct a NetworkInterface
- * with this address.
- */
- return new NetworkInterface(null, -1, new InetAddress[] { addr });
- }
-
-
- /*
- * IPv6 implementation
- */
- if ((opt == java_net_SocketOptions_IP_MULTICAST_IF) ||
- (opt == java_net_SocketOptions_IP_MULTICAST_IF2)) {
-
- int index;
-
- InetAddress[] addrArray;
- InetAddress addr;
- NetworkInterface ni;
-
- {
- int[] tmp = { 0 };
- if (getsockopt(fd1, IPPROTO_IPV6, IPV6_MULTICAST_IF,
- tmp) < 0) {
- NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG+"SocketException",
- "Error getting socket option");
- return NULL;
- }
- index = tmp[0];
- }
-
- /*
- * If multicast to a specific interface then return the
- * interface (for IF2) or the any address on that interface
- * (for IF).
- */
- if (index > 0) {
- ni = Java_java_net_NetworkInterface_getByIndex(env, ni_class,
- index);
- if (ni == NULL) {
- String errmsg = "IPV6_MULTICAST_IF returned index to unrecognized interface: " + index;
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", errmsg);
- return NULL;
- }
-
- /*
- * For IP_MULTICAST_IF2 return the NetworkInterface
- */
- if (opt == java_net_SocketOptions_IP_MULTICAST_IF2) {
- return ni;
- }
-
- /*
- * For IP_MULTICAST_IF return addrs[0]
- */
- addrArray = getNetworkInterfaceAddresses(ni);
- if (addrArray.length < 1) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
- "IPV6_MULTICAST_IF returned interface without IP bindings");
- return NULL;
- }
-
- addr = addrArray[0];
- return addr;
- }
-
- /*
- * Multicast to any address - return anyLocalAddress
- * or a NetworkInterface with addrs[0] set to anyLocalAddress
- */
-
- addr = InetAddress.anyLocalAddress();
- if (opt == java_net_SocketOptions_IP_MULTICAST_IF) {
- return addr;
- }
-
- return new NetworkInterface(null, -1, new InetAddress[] { addr });
- }
- return NULL;
-}
-/*
- * Returns relevant info as a jint.
- *
- * Class: java_net_TwoStacksPlainDatagramSocketImpl
- * Method: socketGetOption
- * Signature: (I)Ljava/lang/Object;
- */
-static Object socketGetOption(JNIEnv env, TwoStacksPlainDatagramSocketImpl _this, int opt) {
- cli.System.Net.Sockets.Socket fd = null;
- cli.System.Net.Sockets.Socket fd1 = null;
- int[] level = new int[1];
- int[] optname = new int[1];
- int[] optval = new int[1];
- boolean ipv6_supported = ipv6_available();
-
- fd = getFD(env, _this);
- if (ipv6_supported) {
- fd1 = getFD1(env, _this);
- }
-
- if (fd == null && fd1 == null) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
- "Socket closed");
- return NULL;
- }
-
- /*
- * Handle IP_MULTICAST_IF separately
- */
- if (opt == java_net_SocketOptions_IP_MULTICAST_IF ||
- opt == java_net_SocketOptions_IP_MULTICAST_IF2) {
- return getMulticastInterface(env, _this, fd, fd1, opt);
- }
-
- /*
- * 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 NULL;
- }
-
- if (fd == null) {
- if (NET_MapSocketOptionV6(opt, level, optname) != 0) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", "Invalid option");
- return NULL;
- }
- fd = fd1; /* must be IPv6 only */
- }
-
- if (NET_GetSockOpt(fd, level[0], optname[0], optval) < 0) {
- String errmsg = "error getting socket option: " + WSAGetLastError();
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", errmsg);
- return NULL;
- }
-
- switch (opt) {
- case java_net_SocketOptions_SO_BROADCAST:
- case java_net_SocketOptions_SO_REUSEADDR:
- return optval[0] != 0;
-
- case java_net_SocketOptions_IP_MULTICAST_LOOP:
- /* getLoopbackMode() returns true if IP_MULTICAST_LOOP is disabled */
- return optval[0] == 0;
-
- case java_net_SocketOptions_SO_SNDBUF:
- case java_net_SocketOptions_SO_RCVBUF:
- case java_net_SocketOptions_IP_TOS:
- return optval[0];
-
- default :
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
- "Socket option not supported by TwoStacksPlainDatagramSocketImpl");
- return NULL;
-
- }
-}
-
-/*
- * Returns local address of the socket.
- *
- * Class: java_net_TwoStacksPlainDatagramSocketImpl
- * Method: socketLocalAddress
- * Signature: (I)Ljava/lang/Object;
- */
-static Object socketLocalAddress(JNIEnv env, TwoStacksPlainDatagramSocketImpl _this,
- int family) {
- cli.System.Net.Sockets.Socket fd = null;
- cli.System.Net.Sockets.Socket fd1 = null;
- SOCKETADDRESS him;
- him = new SOCKETADDRESS();
- Object iaObj;
- boolean ipv6_supported = ipv6_available();
-
- fd = getFD(env, _this);
- if (ipv6_supported) {
- fd1 = getFD1(env, _this);
- }
-
- if (fd == null && fd1 == null) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
- "Socket closed");
- return NULL;
- }
-
- /* find out local IP address */
-
- /* family==-1 when socket is not connected */
- if ((family == IPv6) || (family == -1 && fd == null)) {
- fd = fd1; /* must be IPv6 only */
- }
-
- if (fd == null) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
- "Socket closed");
- return NULL;
- }
-
- if (getsockname(fd, him) == -1) {
- NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG+"SocketException",
- "Error getting socket name");
- return NULL;
- }
- iaObj = NET_SockaddrToInetAddress(him, new int[1]);
-
- return iaObj;
-}
-
-/*
- * Class: java_net_TwoStacksPlainDatagramSocketImpl
- * Method: setTimeToLive
- * Signature: (I)V
- */
-static void setTimeToLive(JNIEnv env, TwoStacksPlainDatagramSocketImpl _this, int ttl) {
- 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 closed");
- return;
- } else {
- if (!IS_NULL(fdObj)) {
- fd = fdObj.getSocket();
- }
- if (!IS_NULL(fd1Obj)) {
- fd1 = fd1Obj.getSocket();
- }
- }
-
- /* setsockopt to be correct ttl */
- if (fd != null) {
- if (NET_SetSockOpt(fd, IPPROTO_IP, IP_MULTICAST_TTL, ttl) < 0) {
- NET_ThrowCurrent(env, "set IP_MULTICAST_TTL failed");
- }
- }
-
- if (fd1 != null) {
- if (NET_SetSockOpt(fd1, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, ttl) <0) {
- NET_ThrowCurrent(env, "set IPV6_MULTICAST_HOPS failed");
- }
- }
-}
-
-/*
- * Class: java_net_TwoStacksPlainDatagramSocketImpl
- * Method: setTTL
- * Signature: (B)V
- */
-static void setTTL(JNIEnv env, TwoStacksPlainDatagramSocketImpl _this, byte ttl) {
- setTimeToLive(env, _this, ttl & 0xFF);
-}
-
-/*
- * Class: java_net_TwoStacksPlainDatagramSocketImpl
- * Method: getTimeToLive
- * Signature: ()I
- */
-static int getTimeToLive(JNIEnv env, TwoStacksPlainDatagramSocketImpl _this) {
- FileDescriptor fdObj = _this.fd;
- FileDescriptor fd1Obj = _this.fd1;
- cli.System.Net.Sockets.Socket fd = null;
- cli.System.Net.Sockets.Socket fd1 = null;
- int[] ttl = new int[1];
-
- if (IS_NULL(fdObj) && IS_NULL(fd1Obj)) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
- "Socket closed");
- return -1;
- } else {
- if (!IS_NULL(fdObj)) {
- fd = fdObj.getSocket();
- }
- if (!IS_NULL(fd1Obj)) {
- fd1 = fd1Obj.getSocket();
- }
- }
-
- /* getsockopt of ttl */
- if (fd != null) {
- if (NET_GetSockOpt(fd, IPPROTO_IP, IP_MULTICAST_TTL, ttl) < 0) {
- NET_ThrowCurrent(env, "get IP_MULTICAST_TTL failed");
- return -1;
- }
- return ttl[0];
- }
- if (fd1 != null) {
- if (NET_GetSockOpt(fd1, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, ttl) < 0) {
- NET_ThrowCurrent(env, "get IP_MULTICAST_TTL failed");
- return -1;
- }
- return ttl[0];
- }
- return -1;
-}
-
-/*
- * Class: java_net_TwoStacksPlainDatagramSocketImpl
- * Method: getTTL
- * Signature: ()B
- */
-static byte getTTL(JNIEnv env, TwoStacksPlainDatagramSocketImpl _this) {
- int result = getTimeToLive(env, _this);
-
- return (byte)result;
-}
-
-/* join/leave the named group on the named interface, or if no interface specified
- * then the interface set with setInterfac(), or the default interface otherwise */
-
-private static void mcast_join_leave(JNIEnv env, TwoStacksPlainDatagramSocketImpl _this, InetAddress iaObj, NetworkInterface niObj, boolean join)
-{
- FileDescriptor fdObj = _this.fd;
- FileDescriptor fd1Obj = _this.fd1;
- cli.System.Net.Sockets.Socket fd = null;
- cli.System.Net.Sockets.Socket fd1 = null;
-
- SOCKETADDRESS name;
- name = new SOCKETADDRESS();
- ip_mreq mname = new ip_mreq();
- ipv6_mreq mname6 = new ipv6_mreq();
-
- in_addr in = new in_addr();
- int ifindex;
-
- int family;
- boolean ipv6_supported = ipv6_available();
- int cmd ;
-
- if (IS_NULL(fdObj) && IS_NULL(fd1Obj)) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
- "Socket closed");
- return;
- }
- if (!IS_NULL(fdObj)) {
- fd = fdObj.getSocket();
- }
- if (ipv6_supported && !IS_NULL(fd1Obj)) {
- fd1 = fd1Obj.getSocket();
- }
-
- if (IS_NULL(iaObj)) {
- JNU_ThrowNullPointerException(env, "address");
- return;
- }
-
- if (NET_InetAddressToSockaddr(env, iaObj, 0, name, JNI_FALSE) != 0) {
- return;
- }
-
- /* Set the multicast group address in the ip_mreq field
- * eventually this check should be done by the security manager
- */
- family = name.him.sa_family;
-
- if (family == AF_INET) {
- int address = name.him4.sin_addr.s_addr;
- if (!IN_MULTICAST(ntohl(address))) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", "not in multicast");
- return;
- }
- mname.imr_multiaddr.s_addr = address;
- if (fd == null) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", "Can't join an IPv4 group on an IPv6 only socket");
- return;
- }
- if (IS_NULL(niObj)) {
- if (NET_GetSockOpt(fd, IPPROTO_IP, IP_MULTICAST_IF, in) < 0) {
- NET_ThrowCurrent(env, "get IP_MULTICAST_IF failed");
- return;
- }
- mname.imr_interface.s_addr = in.s_addr;
- } else {
- if (getInet4AddrFromIf (env, niObj, mname.imr_interface) != 0) {
- NET_ThrowCurrent(env, "no Inet4Address associated with interface");
- return;
- }
- }
-
- cmd = join ? IP_ADD_MEMBERSHIP: IP_DROP_MEMBERSHIP;
-
- /* Join the multicast group */
- if (NET_SetSockOpt(fd, IPPROTO_IP, cmd, mname) < 0) {
- if (WSAGetLastError() == WSAENOBUFS) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
- "IP_ADD_MEMBERSHIP failed (out of hardware filters?)");
- } else {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException","error setting options");
- }
- }
- } else /* AF_INET6 */ {
- if (ipv6_supported) {
- in6_addr address;
- address = in6_addr.FromSockAddr(name);
- if (!IN6_IS_ADDR_MULTICAST(address)) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", "not in6 multicast");
- return;
- }
- mname6.ipv6mr_multiaddr = address;
- } else {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", "IPv6 not supported");
- return;
- }
- if (fd1 == null) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", "Can't join an IPv6 group on a IPv4 socket");
- return;
- }
- if (IS_NULL(niObj)) {
- int[] tmp = { 0 };
- if (NET_GetSockOpt(fd1, IPPROTO_IPV6, IPV6_MULTICAST_IF, tmp) < 0) {
- NET_ThrowCurrent(env, "get IPV6_MULTICAST_IF failed");
- return;
- }
- ifindex = tmp[0];
- } else {
- ifindex = getIndexFromIf (env, niObj);
- if (ifindex == -1) {
- NET_ThrowCurrent(env, "get ifindex failed");
- return;
- }
- }
- mname6.ipv6mr_interface = ifindex;
- cmd = join ? IPV6_ADD_MEMBERSHIP: IPV6_DROP_MEMBERSHIP;
-
- /* Join the multicast group */
- if (NET_SetSockOpt(fd1, IPPROTO_IPV6, cmd, mname6) < 0) {
- if (WSAGetLastError() == WSAENOBUFS) {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
- "IP_ADD_MEMBERSHIP failed (out of hardware filters?)");
- } else {
- JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException","error setting options");
- }
- }
- }
-
- return;
-}
-
-/*
- * Class: java_net_TwoStacksPlainDatagramSocketImpl
- * Method: join
- * Signature: (Ljava/net/InetAddress;)V
- */
-static void join(JNIEnv env, TwoStacksPlainDatagramSocketImpl _this, InetAddress inetaddr, NetworkInterface netIf) {
- mcast_join_leave(env, _this, inetaddr, netIf, true);
-}
-
-/*
- * Class: java_net_TwoStacksPlainDatagramSocketImpl
- * Method: leave
- * Signature: (Ljava/net/InetAddress;)V
- */
-static void leave(JNIEnv env, TwoStacksPlainDatagramSocketImpl _this, InetAddress inetaddr, NetworkInterface netIf) {
- mcast_join_leave(env, _this, inetaddr, netIf, false);
-}
-
-}
diff --git a/openjdk/java/net/TwoStacksPlainSocketImpl.java b/openjdk/java/net/TwoStacksPlainSocketImpl.java
deleted file mode 100644
index 12c1794f..00000000
--- a/openjdk/java/net/TwoStacksPlainSocketImpl.java
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * Copyright (c) 2007, 2008, 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.IOException;
-import java.io.FileDescriptor;
-import sun.net.ResourceManager;
-
-/*
- * This class defines the plain SocketImpl that is used for all
- * Windows version lower than Vista. It adds support for IPv6 on
- * these platforms where available.
- *
- * For backward compatibility Windows platforms that do not have IPv6
- * support also use this implementation, and fd1 gets set to null
- * during socket creation.
- *
- * @author Chris Hegarty
- */
-
-class TwoStacksPlainSocketImpl extends AbstractPlainSocketImpl
-{
- /* second fd, used for ipv6 on windows only.
- * fd1 is used for listeners and for client sockets at initialization
- * until the socket is connected. Up to this point fd always refers
- * to the ipv4 socket and fd1 to the ipv6 socket. After the socket
- * becomes connected, fd always refers to the connected socket
- * (either v4 or v6) and fd1 is closed.
- *
- * For ServerSockets, fd always refers to the v4 listener and
- * fd1 the v6 listener.
- */
- FileDescriptor fd1;
-
- /*
- * Needed for ipv6 on windows because we need to know
- * if the socket is bound to ::0 or 0.0.0.0, when a caller
- * asks for it. Otherwise we don't know which socket to ask.
- */
- private InetAddress anyLocalBoundAddr = null;
-
- /* to prevent starvation when listening on two sockets, this is
- * is used to hold the id of the last socket we accepted on.
- */
- cli.System.Net.Sockets.Socket lastfd = null;
-
- // true if this socket is exclusively bound
- private final boolean exclusiveBind;
-
- // emulates SO_REUSEADDR when exclusiveBind is true
- private boolean isReuseAddress;
-
-
- public TwoStacksPlainSocketImpl(boolean exclBind) {
- exclusiveBind = exclBind;
- }
-
- public TwoStacksPlainSocketImpl(FileDescriptor fd, boolean exclBind) {
- this.fd = fd;
- exclusiveBind = exclBind;
- }
-
- /**
- * Creates a socket with a boolean that specifies whether this
- * is a stream socket (true) or an unconnected UDP socket (false).
- */
- protected synchronized void create(boolean stream) throws IOException {
- fd1 = new FileDescriptor();
- try {
- super.create(stream);
- } catch (IOException e) {
- fd1 = null;
- throw e;
- }
- }
-
- /**
- * Binds the socket to the specified address of the specified local port.
- * @param address the address
- * @param port the port
- */
- protected synchronized void bind(InetAddress address, int lport)
- throws IOException
- {
- super.bind(address, lport);
- if (address.isAnyLocalAddress()) {
- anyLocalBoundAddr = address;
- }
- }
-
- public Object getOption(int opt) throws SocketException {
- if (isClosedOrPending()) {
- throw new SocketException("Socket Closed");
- }
- if (opt == SO_BINDADDR) {
- if (fd != null && fd1 != null ) {
- /* must be unbound or else bound to anyLocal */
- return anyLocalBoundAddr;
- }
- InetAddressContainer in = new InetAddressContainer();
- socketGetOption(opt, in);
- return in.addr;
- } else if (opt == SO_REUSEADDR && exclusiveBind) {
- // SO_REUSEADDR emulated when using exclusive bind
- return isReuseAddress;
- } else
- return super.getOption(opt);
- }
-
- @Override
- void socketBind(InetAddress address, int port) throws IOException {
- socketBind(address, port, exclusiveBind);
- }
-
- @Override
- void socketSetOption(int opt, boolean on, Object value)
- throws SocketException
- {
- // SO_REUSEADDR emulated when using exclusive bind
- if (opt == SO_REUSEADDR && exclusiveBind)
- isReuseAddress = on;
- else
- socketNativeSetOption(opt, on, value);
- }
-
- /**
- * Closes the socket.
- */
- @Override
- protected void close() throws IOException {
- synchronized(fdLock) {
- if (fd != null || fd1 != null) {
- if (!stream) {
- ResourceManager.afterUdpClose();
- }
- if (fdUseCount == 0) {
- if (closePending) {
- return;
- }
- closePending = true;
- socketClose();
- fd = null;
- fd1 = null;
- return;
- } else {
- /*
- * If a thread has acquired the fd and a close
- * isn't pending then use a deferred close.
- * Also decrement fdUseCount to signal the last
- * thread that releases the fd to close it.
- */
- if (!closePending) {
- closePending = true;
- fdUseCount--;
- socketClose();
- }
- }
- }
- }
- }
-
- @Override
- void reset() throws IOException {
- if (fd != null || fd1 != null) {
- socketClose();
- }
- fd = null;
- fd1 = null;
- super.reset();
- }
-
- /*
- * Return true if already closed or close is pending
- */
- @Override
- public boolean isClosedOrPending() {
- /*
- * Lock on fdLock to ensure that we wait if a
- * close is in progress.
- */
- synchronized (fdLock) {
- if (closePending || (fd == null && fd1 == null)) {
- return true;
- } else {
- return false;
- }
- }
- }
-
- /* Native methods */
-
- void socketCreate(boolean stream) throws IOException {
- ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
- TwoStacksPlainSocketImpl_c.socketCreate(env, this, stream);
- env.ThrowPendingException();
- }
-
- void socketConnect(InetAddress address, int port, int timeout) throws IOException {
- ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
- TwoStacksPlainSocketImpl_c.socketConnect(env, this, address, port, timeout);
- env.ThrowPendingException();
- }
-
- void socketBind(InetAddress address, int localport, boolean exclBind) throws IOException {
- ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
- TwoStacksPlainSocketImpl_c.socketBind(env, this, address, localport, exclBind);
- env.ThrowPendingException();
- }
-
- void socketListen(int count) throws IOException {
- ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
- TwoStacksPlainSocketImpl_c.socketListen(env, this, count);
- env.ThrowPendingException();
- }
-
- void socketAccept(SocketImpl socket) throws IOException {
- ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
- TwoStacksPlainSocketImpl_c.socketAccept(env, this, socket);
- env.ThrowPendingException();
- }
-
- int socketAvailable() throws IOException {
- ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
- int ret = TwoStacksPlainSocketImpl_c.socketAvailable(env, this);
- env.ThrowPendingException();
- return ret;
- }
-
- void socketClose0(boolean useDeferredClose) throws IOException {
- ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
- TwoStacksPlainSocketImpl_c.socketClose0(env, this, useDeferredClose);
- env.ThrowPendingException();
- }
-
- void socketShutdown(int howto) throws IOException {
- ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
- TwoStacksPlainSocketImpl_c.socketShutdown(env, this, howto);
- env.ThrowPendingException();
- }
-
- void socketNativeSetOption(int cmd, boolean on, Object value) throws SocketException {
- ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
- TwoStacksPlainSocketImpl_c.socketNativeSetOption(env, this, cmd, on, value);
- env.ThrowPendingException();
- }
-
- int socketGetOption(int opt, Object iaContainerObj) throws SocketException {
- ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
- int ret = TwoStacksPlainSocketImpl_c.socketGetOption(env, this, opt, iaContainerObj);
- env.ThrowPendingException();
- return ret;
- }
-
- int socketGetOption1(int opt, Object iaContainerObj, FileDescriptor fd) throws SocketException {
- throw new UnsatisfiedLinkError();
- }
-
- void socketSendUrgentData(int data) throws IOException {
- ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
- TwoStacksPlainSocketImpl_c.socketSendUrgentData(env, this, data);
- env.ThrowPendingException();
- }
-}
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;
- }
-}
-}
diff --git a/openjdk/java/net/net_util_md.java b/openjdk/java/net/net_util_md.java
deleted file mode 100644
index 724ba4cc..00000000
--- a/openjdk/java/net/net_util_md.java
+++ /dev/null
@@ -1,884 +0,0 @@
-/*
- * Copyright (c) 1997, 2008, 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 cli.System.Net.IPAddress;
-import cli.System.Net.IPEndPoint;
-import static ikvm.internal.JNI.*;
-import static ikvm.internal.Winsock.*;
-
-final class net_util_md
-{
- private net_util_md() { }
-
- static final int INADDR_ANY = 0;
-
- static final int IPTOS_TOS_MASK = 0x1e;
- static final int IPTOS_PREC_MASK = 0xe0;
-
- static boolean isRcvTimeoutSupported = true;
-
- /*
- * Table of Windows Sockets errors, the specific exception we
- * throw for the error, and the error text.
- *
- * Note that this table excludes OS dependent errors.
- *
- * Latest list of Windows Sockets errors can be found at :-
- * http://msdn.microsoft.com/library/psdk/winsock/errors_3wc2.htm
- */
- private static class WinsockError
- {
- final int errCode;
- final int exc;
- final String errString;
-
- WinsockError(int errCode, int exc, String errString)
- {
- this.errCode = errCode;
- this.exc = exc;
- this.errString = errString;
- }
- }
-
- private static final int Exception_BindException = 1;
- private static final int Exception_ConnectException = 2;
- private static final int Exception_NoRouteToHostException = 3;
-
- private static final WinsockError[] winsock_errors = {
- new WinsockError(WSAEACCES, 0, "Permission denied"),
- new WinsockError(WSAEADDRINUSE, Exception_BindException, "Address already in use"),
- new WinsockError(WSAEADDRNOTAVAIL, Exception_BindException, "Cannot assign requested address"),
- new WinsockError(WSAEAFNOSUPPORT, 0, "Address family not supported by protocol family"),
- new WinsockError(WSAEALREADY, 0, "Operation already in progress"),
- new WinsockError(WSAECONNABORTED, 0, "Software caused connection abort"),
- new WinsockError(WSAECONNREFUSED, Exception_ConnectException, "Connection refused"),
- new WinsockError(WSAECONNRESET, 0, "Connection reset by peer"),
- new WinsockError(WSAEDESTADDRREQ, 0, "Destination address required"),
- new WinsockError(WSAEFAULT, 0, "Bad address"),
- new WinsockError(WSAEHOSTDOWN, 0, "Host is down"),
- new WinsockError(WSAEHOSTUNREACH, Exception_NoRouteToHostException, "No route to host"),
- new WinsockError(WSAEINPROGRESS, 0, "Operation now in progress"),
- new WinsockError(WSAEINTR, 0, "Interrupted function call"),
- new WinsockError(WSAEINVAL, 0, "Invalid argument"),
- new WinsockError(WSAEISCONN, 0, "Socket is already connected"),
- new WinsockError(WSAEMFILE, 0, "Too many open files"),
- new WinsockError(WSAEMSGSIZE, 0, "The message is larger than the maximum supported by the underlying transport"),
- new WinsockError(WSAENETDOWN, 0, "Network is down"),
- new WinsockError(WSAENETRESET, 0, "Network dropped connection on reset"),
- new WinsockError(WSAENETUNREACH, 0, "Network is unreachable"),
- new WinsockError(WSAENOBUFS, 0, "No buffer space available (maximum connections reached?)"),
- new WinsockError(WSAENOPROTOOPT, 0, "Bad protocol option"),
- new WinsockError(WSAENOTCONN, 0, "Socket is not connected"),
- new WinsockError(WSAENOTSOCK, 0, "Socket operation on nonsocket"),
- new WinsockError(WSAEOPNOTSUPP, 0, "Operation not supported"),
- new WinsockError(WSAEPFNOSUPPORT, 0, "Protocol family not supported"),
- new WinsockError(WSAEPROCLIM, 0, "Too many processes"),
- new WinsockError(WSAEPROTONOSUPPORT, 0, "Protocol not supported"),
- new WinsockError(WSAEPROTOTYPE, 0, "Protocol wrong type for socket"),
- new WinsockError(WSAESHUTDOWN, 0, "Cannot send after socket shutdown"),
- new WinsockError(WSAESOCKTNOSUPPORT, 0, "Socket type not supported"),
- new WinsockError(WSAETIMEDOUT, Exception_ConnectException, "Connection timed out"),
- new WinsockError(WSATYPE_NOT_FOUND, 0, "Class type not found"),
- new WinsockError(WSAEWOULDBLOCK, 0, "Resource temporarily unavailable"),
- new WinsockError(WSAHOST_NOT_FOUND, 0, "Host not found"),
- new WinsockError(WSA_NOT_ENOUGH_MEMORY, 0, "Insufficient memory available"),
- new WinsockError(WSANOTINITIALISED, 0, "Successful WSAStartup not yet performed"),
- new WinsockError(WSANO_DATA, 0, "Valid name, no data record of requested type"),
- new WinsockError(WSANO_RECOVERY, 0, "This is a nonrecoverable error"),
- new WinsockError(WSASYSNOTREADY, 0, "Network subsystem is unavailable"),
- new WinsockError(WSATRY_AGAIN, 0, "Nonauthoritative host not found"),
- new WinsockError(WSAVERNOTSUPPORTED, 0, "Winsock.dll version out of range"),
- new WinsockError(WSAEDISCON, 0, "Graceful shutdown in progress"),
- new WinsockError(WSA_OPERATION_ABORTED, 0, "Overlapped operation aborted")
- };
-
- /*
- * Since winsock doesn't have the equivalent of strerror(errno)
- * use table to lookup error text for the error.
- */
- static SocketException NET_ThrowNew(int errorNum, String msg)
- {
- int i;
- int table_size = winsock_errors.length;
- int excP = 0;
- String fullMsg;
-
- if (msg == null) {
- msg = "no further information";
- }
-
- /*
- * Check table for known winsock errors
- */
- i=0;
- while (i < table_size) {
- if (errorNum == winsock_errors[i].errCode) {
- break;
- }
- i++;
- }
-
- /*
- * If found get pick the specific exception and error
- * message corresponding to this error.
- */
- if (i < table_size) {
- excP = winsock_errors[i].exc;
- fullMsg = winsock_errors[i].errString + ": " + msg;
- } else {
- fullMsg = "Unrecognized Windows Sockets error: " + errorNum + ": " + msg;
- }
-
- /*
- * Throw SocketException if no specific exception for this
- * error.
- */
- switch (excP) {
- case Exception_BindException:
- return new BindException(fullMsg);
- case Exception_ConnectException:
- return new ConnectException(fullMsg);
- case Exception_NoRouteToHostException:
- return new NoRouteToHostException(fullMsg);
- default:
- return new SocketException(fullMsg);
- }
- }
-
- static void NET_ThrowNew(JNIEnv env, int errorNum, String msg)
- {
- env.Throw(NET_ThrowNew(errorNum, msg));
- }
-
- static SocketException NET_ThrowCurrent(String msg)
- {
- return NET_ThrowNew(WSAGetLastError(), msg);
- }
-
- static void NET_ThrowCurrent(JNIEnv env, String msg)
- {
- env.Throw(NET_ThrowCurrent(msg));
- }
-
- /*
- * Return the default TOS value
- */
- static int NET_GetDefaultTOS() {
- // we always use the "default" default...
- return 0;
- }
-
- /*
- * Map the Java level socket option to the platform specific
- * level and option name.
- */
-
- private static final class sockopts {
- int cmd;
- int level;
- int optname;
-
- sockopts(int cmd, int level, int optname) {
- this.cmd = cmd;
- this.level = level;
- this.optname = optname;
- }
- }
-
- private static final sockopts opts[] = {
- new sockopts(SocketOptions.TCP_NODELAY, IPPROTO_TCP, TCP_NODELAY ),
- new sockopts(SocketOptions.SO_OOBINLINE, SOL_SOCKET, SO_OOBINLINE ),
- new sockopts(SocketOptions.SO_LINGER, SOL_SOCKET, SO_LINGER ),
- new sockopts(SocketOptions.SO_SNDBUF, SOL_SOCKET, SO_SNDBUF ),
- new sockopts(SocketOptions.SO_RCVBUF, SOL_SOCKET, SO_RCVBUF ),
- new sockopts(SocketOptions.SO_KEEPALIVE, SOL_SOCKET, SO_KEEPALIVE ),
- new sockopts(SocketOptions.SO_REUSEADDR, SOL_SOCKET, SO_REUSEADDR ),
- new sockopts(SocketOptions.SO_BROADCAST, SOL_SOCKET, SO_BROADCAST ),
- new sockopts(SocketOptions.IP_MULTICAST_IF, IPPROTO_IP, IP_MULTICAST_IF ),
- new sockopts(SocketOptions.IP_MULTICAST_LOOP, IPPROTO_IP, IP_MULTICAST_LOOP ),
- new sockopts(SocketOptions.IP_TOS, IPPROTO_IP, IP_TOS ),
-
- };
-
- /* call NET_MapSocketOptionV6 for the IPv6 fd only
- * and NET_MapSocketOption for the IPv4 fd
- */
- static int NET_MapSocketOptionV6(int cmd, int[] level, int[] optname) {
-
- switch (cmd) {
- case SocketOptions.IP_MULTICAST_IF:
- case SocketOptions.IP_MULTICAST_IF2:
- level[0] = IPPROTO_IPV6;
- optname[0] = IPV6_MULTICAST_IF;
- return 0;
-
- case SocketOptions.IP_MULTICAST_LOOP:
- level[0] = IPPROTO_IPV6;
- optname[0] = IPV6_MULTICAST_LOOP;
- return 0;
- }
- return NET_MapSocketOption (cmd, level, optname);
- }
-
- static int NET_MapSocketOption(int cmd, int[] level, int[] optname) {
- /*
- * Map the Java level option to the native level
- */
- for (int i=0; i<opts.length; i++) {
- if (cmd == opts[i].cmd) {
- level[0] = opts[i].level;
- optname[0] = opts[i].optname;
- return 0;
- }
- }
-
- /* not found */
- return -1;
- }
-
- static int NET_SetSockOpt(cli.System.Net.Sockets.Socket s, int level, int optname, Object optval)
- {
- int rv;
-
- if (level == IPPROTO_IP && optname == IP_TOS) {
- int tos = (Integer)optval;
- tos &= (IPTOS_TOS_MASK | IPTOS_PREC_MASK);
- optval = tos;
- }
-
- if (optname == SO_REUSEADDR) {
- /*
- * Do not set SO_REUSEADDE if SO_EXCLUSIVEADDUSE is already set
- */
- int[] parg = new int[1];
- rv = NET_GetSockOpt(s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, parg);
- if (rv == 0 && parg[0] == 1) {
- return rv;
- }
- }
-
- rv = setsockopt(s, level, optname, optval);
-
- if (rv == SOCKET_ERROR) {
- /*
- * IP_TOS & IP_MULTICAST_LOOP can't be set on some versions
- * of Windows.
- */
- if ((WSAGetLastError() == WSAENOPROTOOPT) &&
- (level == IPPROTO_IP) &&
- (optname == IP_TOS || optname == IP_MULTICAST_LOOP)) {
- rv = 0;
- }
-
- /*
- * IP_TOS can't be set on unbound UDP sockets.
- */
- if ((WSAGetLastError() == WSAEINVAL) &&
- (level == IPPROTO_IP) &&
- (optname == IP_TOS)) {
- rv = 0;
- }
- }
-
- return rv;
- }
-
- /*
- * Wrapper for setsockopt dealing with Windows specific issues :-
- *
- * IP_TOS is not supported on some versions of Windows so
- * instead return the default value for the OS.
- */
- static int NET_GetSockOpt(cli.System.Net.Sockets.Socket s, int level, int optname, Object optval)
- {
- int rv;
-
- rv = getsockopt(s, level, optname, optval);
-
-
- /*
- * IPPROTO_IP/IP_TOS is not supported on some Windows
- * editions so return the default type-of-service
- * value.
- */
- if (rv == SOCKET_ERROR) {
-
- if (WSAGetLastError() == WSAENOPROTOOPT &&
- level == IPPROTO_IP && optname == IP_TOS) {
-
- ((int[])optval)[0] = NET_GetDefaultTOS();
-
- rv = 0;
- }
- }
-
- return rv;
- }
-
- /*
- * Sets SO_ECLUSIVEADDRUSE if SO_REUSEADDR is not already set.
- */
- static void setExclusiveBind(cli.System.Net.Sockets.Socket fd) {
- int[] parg = new int[1];
- int rv = 0;
- rv = NET_GetSockOpt(fd, SOL_SOCKET, SO_REUSEADDR, parg);
- if (rv == 0 && parg[0] == 0) {
- rv = NET_SetSockOpt(fd, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, 1);
- }
- }
-
- /*
- * Wrapper for bind winsock call - transparent converts an
- * error related to binding to a port that has exclusive access
- * into an error indicating the port is in use (facilitates
- * better error reporting).
- */
- static int NET_Bind(cli.System.Net.Sockets.Socket s, SOCKETADDRESS him)
- {
- int rv;
- rv = bind(s, him);
-
- if (rv == SOCKET_ERROR) {
- /*
- * If bind fails with WSAEACCES it means that a privileged
- * process has done an exclusive bind (NT SP4/2000/XP only).
- */
- if (WSAGetLastError() == WSAEACCES) {
- WSASetLastError(WSAEADDRINUSE);
- }
- }
-
- return rv;
- }
-
- /*
- * Wrapper for NET_Bind call. Sets SO_EXCLUSIVEADDRUSE
- * if required, and then calls NET_BIND
- */
- static int NET_WinBind(cli.System.Net.Sockets.Socket s, SOCKETADDRESS him, boolean exclBind)
- {
- if (exclBind == JNI_TRUE)
- setExclusiveBind(s);
- return NET_Bind(s, him);
- }
-
- static int NET_SocketClose(cli.System.Net.Sockets.Socket fd) {
- linger l = new linger();
- int ret;
- if (getsockopt(fd, SOL_SOCKET, SO_LINGER, l) == 0) {
- if (l.l_onoff == 0) {
- WSASendDisconnect(fd);
- }
- }
- ret = closesocket (fd);
- return ret;
- }
-
- static int NET_Timeout(cli.System.Net.Sockets.Socket fd, long timeout) {
- int ret;
- fd_set tbl = new fd_set();
- timeval t = new timeval();
- t.tv_sec = timeout / 1000;
- t.tv_usec = (timeout % 1000) * 1000;
- FD_ZERO(tbl);
- FD_SET(fd, tbl);
- ret = select (tbl, null, null, t);
- return ret;
- }
-
- /*
- * differs from NET_Timeout() as follows:
- *
- * If timeout = -1, it blocks forever.
- *
- * returns 1 or 2 depending if only one or both sockets
- * fire at same time.
- *
- * *fdret is (one of) the active fds. If both sockets
- * fire at same time, *fdret = fd always.
- */
- static int NET_Timeout2(cli.System.Net.Sockets.Socket fd, cli.System.Net.Sockets.Socket fd1, long timeout, cli.System.Net.Sockets.Socket[] fdret) {
- int ret;
- fd_set tbl = new fd_set();
- timeval t = new timeval();
- if (timeout == -1) {
- t = null;
- } else {
- t.tv_sec = timeout / 1000;
- t.tv_usec = (timeout % 1000) * 1000;
- }
- FD_ZERO(tbl);
- FD_SET(fd, tbl);
- FD_SET(fd1, tbl);
- ret = select (tbl, null, null, t);
- switch (ret) {
- case 0:
- return 0; /* timeout */
- case 1:
- if (FD_ISSET (fd, tbl)) {
- fdret[0]= fd;
- } else {
- fdret[0]= fd1;
- }
- return 1;
- case 2:
- fdret[0]= fd;
- return 2;
- }
- return -1;
- }
-
- /*
- * if ipv6 is available, call NET_BindV6 to bind to the required address/port.
- * Because the same port number may need to be reserved in both v4 and v6 space,
- * this may require socket(s) to be re-opened. Therefore, all of this information
- * is passed in and returned through the ipv6bind structure.
- *
- * If the request is to bind to a specific address, then this (by definition) means
- * only bind in either v4 or v6, and this is just the same as normal. ie. a single
- * call to bind() will suffice. The other socket is closed in this case.
- *
- * The more complicated case is when the requested address is ::0 or 0.0.0.0.
- *
- * Two further cases:
- * 2. If the reqeusted port is 0 (ie. any port) then we try to bind in v4 space
- * first with a wild-card port argument. We then try to bind in v6 space
- * using the returned port number. If this fails, we repeat the process
- * until a free port common to both spaces becomes available.
- *
- * 3. If the requested port is a specific port, then we just try to get that
- * port in both spaces, and if it is not free in both, then the bind fails.
- *
- * On failure, sockets are closed and an error returned with CLOSE_SOCKETS_AND_RETURN
- */
-
- static class ipv6bind {
- SOCKETADDRESS addr;
- cli.System.Net.Sockets.Socket ipv4_fd;
- cli.System.Net.Sockets.Socket ipv6_fd;
- }
-
- private static int CLOSE_SOCKETS_AND_RETURN(
- cli.System.Net.Sockets.Socket fd,
- cli.System.Net.Sockets.Socket ofd,
- cli.System.Net.Sockets.Socket close_fd,
- cli.System.Net.Sockets.Socket close_ofd,
- ipv6bind b) {
- if (fd != null) {
- closesocket (fd);
- }
- if (ofd != null) {
- closesocket (ofd);
- }
- if (close_fd != null) {
- closesocket (close_fd);
- }
- if (close_ofd != null) {
- closesocket (close_ofd);
- }
- b.ipv4_fd = b.ipv6_fd = null;
- return SOCKET_ERROR;
- }
-
- static int NET_BindV6(ipv6bind b, boolean exclBind) {
- cli.System.Net.Sockets.Socket fd = null;
- cli.System.Net.Sockets.Socket ofd = null;
- int rv;
- /* need to defer close until new sockets created */
- cli.System.Net.Sockets.Socket close_fd = null;
- cli.System.Net.Sockets.Socket close_ofd = null;
-
- SOCKETADDRESS oaddr = new SOCKETADDRESS();
- int family = b.addr.him.sa_family;
- int ofamily;
- int port;
- int bound_port;
-
- if (family == AF_INET && (b.addr.him4.sin_addr.s_addr != INADDR_ANY)) {
- /* bind to v4 only */
- int ret;
- ret = NET_WinBind (b.ipv4_fd, b.addr, exclBind);
- if (ret == SOCKET_ERROR) {
- return CLOSE_SOCKETS_AND_RETURN(fd, ofd, close_fd, close_ofd, b);
- }
- closesocket (b.ipv6_fd);
- b.ipv6_fd = null;
- return 0;
- }
- if (family == AF_INET6 && (!IN6ADDR_ISANY(b.addr))) {
- /* bind to v6 only */
- int ret;
- ret = NET_WinBind (b.ipv6_fd, b.addr, exclBind);
- if (ret == SOCKET_ERROR) {
- return CLOSE_SOCKETS_AND_RETURN(fd, ofd, close_fd, close_ofd, b);
- }
- closesocket (b.ipv4_fd);
- b.ipv4_fd = null;
- return 0;
- }
-
- /* We need to bind on both stacks, with the same port number */
-
- if (family == AF_INET) {
- ofamily = AF_INET6;
- fd = b.ipv4_fd;
- ofd = b.ipv6_fd;
- port = GET_PORT (b.addr);
- oaddr.set(new IPEndPoint(IPAddress.IPv6Any, htons(port)));
- } else {
- ofamily = AF_INET;
- ofd = b.ipv4_fd;
- fd = b.ipv6_fd;
- port = GET_PORT (b.addr);
- oaddr.set(new IPEndPoint(IPAddress.Any, htons(port)));
- }
-
- rv = NET_WinBind (fd, b.addr, exclBind);
- if (rv == SOCKET_ERROR) {
- return CLOSE_SOCKETS_AND_RETURN(fd, ofd, close_fd, close_ofd, b);
- }
-
- /* get the port and set it in the other address */
- if (getsockname(fd, b.addr) == -1) {
- return CLOSE_SOCKETS_AND_RETURN(fd, ofd, close_fd, close_ofd, b);
- }
- bound_port = b.addr.sin_port;
- oaddr.sin_port = bound_port;
- if ((rv=NET_Bind (ofd, oaddr)) == SOCKET_ERROR) {
-
- /* no retries unless, the request was for any free port */
-
- if (port != 0) {
- return CLOSE_SOCKETS_AND_RETURN(fd, ofd, close_fd, close_ofd, b);
- }
-
- int sotype = fd.get_SocketType().Value;
-
- /* 50 is an arbitrary limit, just to ensure that this
- * cannot be an endless loop. Would expect socket creation to
- * succeed sooner.
- */
- for (int retries = 0; retries < 50 /*SOCK_RETRIES*/; retries ++) {
- close_fd = fd;
- fd = null;
- close_ofd = ofd;
- ofd = null;
- b.ipv4_fd = null;
- b.ipv6_fd = null;
-
- /* create two new sockets */
- fd = socket (family, sotype, 0);
- if (fd == INVALID_SOCKET) {
- return CLOSE_SOCKETS_AND_RETURN(fd, ofd, close_fd, close_ofd, b);
- }
- ofd = socket (ofamily, sotype, 0);
- if (ofd == INVALID_SOCKET) {
- return CLOSE_SOCKETS_AND_RETURN(fd, ofd, close_fd, close_ofd, b);
- }
-
- /* bind random port on first socket */
- oaddr.sin_port = 0;
- rv = NET_WinBind (ofd, oaddr,
- exclBind);
- if (rv == SOCKET_ERROR) {
- return CLOSE_SOCKETS_AND_RETURN(fd, ofd, close_fd, close_ofd, b);
- }
- /* close the original pair of sockets before continuing */
- closesocket (close_fd);
- closesocket (close_ofd);
- close_fd = close_ofd = null;
-
- /* bind new port on second socket */
- if (getsockname(ofd, oaddr) == -1) {
- return CLOSE_SOCKETS_AND_RETURN(fd, ofd, close_fd, close_ofd, b);
- }
- bound_port = oaddr.sin_port;
- b.addr.sin_port = bound_port;
- rv = NET_WinBind (fd, b.addr,
- exclBind);
-
- if (rv != SOCKET_ERROR) {
- if (family == AF_INET) {
- b.ipv4_fd = fd;
- b.ipv6_fd = ofd;
- } else {
- b.ipv4_fd = ofd;
- b.ipv6_fd = fd;
- }
- return 0;
- }
- }
- return CLOSE_SOCKETS_AND_RETURN(fd, ofd, close_fd, close_ofd, b);
- }
- return 0;
- }
-
- /* If address types is IPv6, then IPv6 must be available. Otherwise
- * no address can be generated. In the case of an IPv4 Inetaddress this
- * method will return an IPv4 mapped address where IPv6 is available and
- * v4MappedAddress is TRUE. Otherwise it will return a sockaddr_in
- * structure for an IPv4 InetAddress.
- */
- static int NET_InetAddressToSockaddr(JNIEnv env, InetAddress iaObj, int port, SOCKETADDRESS him, boolean v4MappedAddress) {
- if (iaObj.family == InetAddress.IPv4) {
- him.set(new IPEndPoint(new IPAddress(htonl(iaObj.address) & 0xFFFFFFFFL), port));
- return 0;
- } else {
- Inet6Address v6addr = (Inet6Address)iaObj;
- int scope = v6addr.getScopeId();
- if (scope == 0) {
- him.set(new IPEndPoint(new IPAddress(v6addr.ipaddress), port));
- return 0;
- } else {
- him.set(new IPEndPoint(new IPAddress(v6addr.ipaddress, scope & 0xFFFFFFFFL), port));
- return 0;
- }
- }
- }
-
- static int NET_GetPortFromSockaddr(SOCKETADDRESS him) {
- return ntohs(GET_PORT(him));
- }
-
- static boolean NET_IsIPv4Mapped(byte[] caddr) {
- int i;
- for (i = 0; i < 10; i++) {
- if (caddr[i] != 0x00) {
- return false;
- }
- }
-
- if (((caddr[10] & 0xff) == 0xff) && ((caddr[11] & 0xff) == 0xff)) {
- return true;
- }
- return false;
- }
-
- static int NET_IPv4MappedToIPv4(byte[] caddr) {
- return ((caddr[12] & 0xff) << 24) | ((caddr[13] & 0xff) << 16) | ((caddr[14] & 0xff) << 8)
- | (caddr[15] & 0xff);
- }
-
- static boolean NET_IsEqual(byte[] caddr1, byte[] caddr2) {
- int i;
- for (i = 0; i < 16; i++) {
- if (caddr1[i] != caddr2[i]) {
- return false;
- }
- }
- return true;
- }
-
- static int getScopeID (SOCKETADDRESS him) {
- return him.him6.sin6_scope_id;
- }
-
- static boolean cmpScopeID (int scope, SOCKETADDRESS him) {
- return him.him6.sin6_scope_id == scope;
- }
-
- /* these methods are not from net_util_md.c */
-
- static boolean ipv6_available() {
- return InetAddressImplFactory.isIPv6Supported();
- }
-
- static boolean IS_NULL(Object obj) {
- return obj == null;
- }
-
- static boolean IN6ADDR_ISANY(SOCKETADDRESS him) {
- if (him.sa_family != AF_INET6) {
- return false;
- }
- byte[] addr = him.him6.sin6_addr;
- byte b = 0;
- for (int i = 0; i < addr.length; i++) {
- b |= addr[i];
- }
- return b == 0;
- }
-
- static boolean NET_SockaddrEqualsInetAddress(SOCKETADDRESS him, InetAddress iaObj) {
- int family = iaObj.family == InetAddress.IPv4 ? AF_INET : AF_INET6;
-
- if (him.sa_family == AF_INET6) {
- byte[] caddrNew = him.him6.sin6_addr;
- if (NET_IsIPv4Mapped(caddrNew)) {
- int addrNew;
- int addrCur;
- if (family == AF_INET6) {
- return false;
- }
- addrNew = NET_IPv4MappedToIPv4(caddrNew);
- addrCur = iaObj.address;
- if (addrNew == addrCur) {
- return true;
- } else {
- return false;
- }
- } else {
- byte[] caddrCur;
- int scope;
-
- if (family == AF_INET) {
- return false;
- }
- scope = ((Inet6Address)iaObj).getScopeId();
- caddrCur = ((Inet6Address)iaObj).ipaddress;
- if (NET_IsEqual(caddrNew, caddrCur) && cmpScopeID(scope, him)) {
- return true;
- } else {
- return false;
- }
- }
- } else {
- int addrNew, addrCur;
- if (family != AF_INET) {
- return false;
- }
- addrNew = ntohl(him.him4.sin_addr.s_addr);
- addrCur = iaObj.address;
- if (addrNew == addrCur) {
- return true;
- } else {
- return false;
- }
- }
- }
-
- 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) {
- byte[] caddr = him.him6.sin6_addr;
- if (NET_IsIPv4Mapped(caddr)) {
- iaObj = new Inet4Address(null, NET_IPv4MappedToIPv4(caddr));
- } else {
- int scope = getScopeID(him);
- iaObj = new Inet6Address(null, caddr, scope > 0 ? scope : -1);
- }
- port[0] = ntohs(him.him6.sin_port);
- } else {
- iaObj = new Inet4Address(null, ntohl(him.him4.sin_addr.s_addr));
- port[0] = ntohs(him.him4.sin_port);
- }
- return iaObj;
- }
-
- static void NET_ThrowByNameWithLastError(JNIEnv env, String exceptionClass, String message) {
- JNU_ThrowByName(env, exceptionClass, "errno: " + WSAGetLastError() + ", error: " + message + "\n");
- }
-
- static boolean IN_MULTICAST(int ipv4address) {
- return ((ipv4address >> 24) & 0xf0) == 0xe0;
- }
-
- static boolean IN6_IS_ADDR_MULTICAST(in6_addr address) {
- return (address.s6_bytes()[0] & 0xff) == 0xff;
- }
-
- static final class SOCKETADDRESS implements IIPEndPointWrapper {
- final SOCKETADDRESS him = this;
- final SOCKETADDRESS him4 = this;
- final SOCKETADDRESS him6 = this;
- final SOCKETADDRESS sin_addr = this;
- int sa_family;
- int sin_port;
- int s_addr;
- byte[] sin6_addr;
- int sin6_scope_id;
-
- public void set(IPEndPoint ep) {
- if (ep == null) {
- sa_family = 0;
- sin_port = 0;
- s_addr = 0;
- sin6_addr = null;
- sin6_scope_id = 0;
- } else {
- sa_family = ep.get_AddressFamily().Value;
- sin_port = htons(ep.get_Port());
- if (sa_family == AF_INET) {
- s_addr = (int)ep.get_Address().get_Address();
- sin6_addr = null;
- sin6_scope_id = 0;
- } else {
- s_addr = 0;
- IPAddress addr = ep.get_Address();
- sin6_addr = addr.GetAddressBytes();
- sin6_scope_id = (int)addr.get_ScopeId();
- }
- }
- }
-
- public IPEndPoint get() {
- if (sa_family == AF_INET) {
- return new IPEndPoint(new IPAddress(s_addr & 0xFFFFFFFFL), ntohs(sin_port));
- } else if (sa_family == AF_INET6) {
- IPAddress addr;
- if (sin6_addr == null) {
- addr = IPAddress.IPv6Any;
- } else {
- addr = new IPAddress(sin6_addr, sin6_scope_id & 0xFFFFFFFFL);
- }
- return new IPEndPoint(addr, ntohs(sin_port));
- } else {
- return null;
- }
- }
- }
-
- static int GET_PORT(SOCKETADDRESS sockaddr) {
- return sockaddr.sin_port;
- }
-
- 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;
- }
-
- static int getInetAddress_addr(JNIEnv env, InetAddress iaObj) {
- return iaObj.address;
- }
-
- static int getInetAddress_family(JNIEnv env, InetAddress iaObj) {
- return iaObj.family;
- }
-}