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:
authorjfrijters <jfrijters>2010-09-09 10:55:31 +0400
committerjfrijters <jfrijters>2010-09-09 10:55:31 +0400
commite57a3213625777da5740614fc86afb6cb4e9e23e (patch)
treed117f574bdbb2afc471339612187b8bcc5dd57bc /openjdk
parent0720c24a212c240d952a1d20f5595ed15f7fabf3 (diff)
Implemented IPv6 support for java.net package APIs.
Diffstat (limited to 'openjdk')
-rw-r--r--openjdk/allsources.lst14
-rw-r--r--openjdk/ikvm/internal/JNI.java114
-rw-r--r--openjdk/ikvm/internal/Winsock.java943
-rw-r--r--openjdk/java/net/DefaultDatagramSocketImplFactory.java33
-rw-r--r--openjdk/java/net/PlainDatagramSocketImpl.java779
-rw-r--r--openjdk/java/net/PlainSocketImpl.java1044
-rw-r--r--openjdk/java/net/SocketInputStream.java71
-rw-r--r--openjdk/java/net/SocketOutputStream.java82
-rw-r--r--openjdk/java/net/TwoStacksPlainDatagramSocketImpl.java139
-rw-r--r--openjdk/java/net/TwoStacksPlainDatagramSocketImpl_c.java1383
-rw-r--r--openjdk/java/net/TwoStacksPlainSocketImpl.java100
-rw-r--r--openjdk/java/net/TwoStacksPlainSocketImpl_c.java674
-rw-r--r--openjdk/java/net/net_util_md.java824
-rw-r--r--openjdk/response.txt41
14 files changed, 3116 insertions, 3125 deletions
diff --git a/openjdk/allsources.lst b/openjdk/allsources.lst
index d5ae58f9..59b9e27a 100644
--- a/openjdk/allsources.lst
+++ b/openjdk/allsources.lst
@@ -41,7 +41,9 @@ ikvm/internal/AnnotationAttributeBase.java
ikvm/internal/FieldReflectorBase.java
ikvm/internal/IntrinsicAtomicReferenceFieldUpdater.java
ikvm/internal/IntrinsicThreadLocal.java
+ikvm/internal/JNI.java
ikvm/internal/Serialization.java
+ikvm/internal/Winsock.java
java/awt/Font.java
java/awt/GraphicsConfiguration.java
java/awt/Image.java
@@ -77,12 +79,14 @@ java/lang/reflect/Constructor.java
java/lang/reflect/Field.java
java/lang/reflect/Method.java
java/lang/reflect/ReflectHelper.java
-java/net/DefaultDatagramSocketImplFactory.java
-java/net/PlainDatagramSocketImpl.java
-java/net/PlainSocketImpl.java
+java/net/net_util_md.java
java/net/SocketInputStream.java
java/net/SocketOutputStream.java
java/net/SocketUtil.java
+java/net/TwoStacksPlainDatagramSocketImpl.java
+java/net/TwoStacksPlainDatagramSocketImpl_c.java
+java/net/TwoStacksPlainSocketImpl.java
+java/net/TwoStacksPlainSocketImpl_c.java
java/nio/Bits.java
java/security/AccessController.java
java/sql/DriverManager.java
@@ -7575,6 +7579,8 @@ sun/security/jgss/wrapper/SunNativeProvider.java
@OPENJDK@/jdk/src/share/classes/java/math/package-info.java
@OPENJDK@/jdk/src/share/classes/java/math/RoundingMode.java
@OPENJDK@/jdk/src/share/classes/java/math/SignedMutableBigInteger.java
+@OPENJDK@/jdk/src/share/classes/java/net/AbstractPlainDatagramSocketImpl.java
+@OPENJDK@/jdk/src/share/classes/java/net/AbstractPlainSocketImpl.java
@OPENJDK@/jdk/src/share/classes/java/net/Authenticator.java
@OPENJDK@/jdk/src/share/classes/java/net/BindException.java
@OPENJDK@/jdk/src/share/classes/java/net/CacheRequest.java
@@ -11591,6 +11597,8 @@ sun/security/jgss/wrapper/SunNativeProvider.java
@OPENJDK@/jdk/src/windows/classes/java/io/Win32FileSystem.java
@OPENJDK@/jdk/src/windows/classes/java/lang/ProcessEnvironment.java
@OPENJDK@/jdk/src/windows/classes/java/lang/Terminator.java
+@OPENJDK@/jdk/src/windows/classes/java/net/DefaultDatagramSocketImplFactory.java
+@OPENJDK@/jdk/src/windows/classes/java/net/PlainSocketImpl.java
@OPENJDK@/jdk/src/windows/classes/java/util/prefs/WindowsPreferences.java
@OPENJDK@/jdk/src/windows/classes/java/util/prefs/WindowsPreferencesFactory.java
@OPENJDK@/jdk/src/windows/classes/sun/nio/ch/NativeThread.java
diff --git a/openjdk/ikvm/internal/JNI.java b/openjdk/ikvm/internal/JNI.java
new file mode 100644
index 00000000..2b7aa9d4
--- /dev/null
+++ b/openjdk/ikvm/internal/JNI.java
@@ -0,0 +1,114 @@
+/*
+ Copyright (C) 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 ikvm.internal;
+
+@ikvm.lang.Internal
+public final class JNI
+{
+ public static final Object NULL = null;
+ public static final boolean TRUE = true;
+ public static final boolean FALSE = false;
+ public static final boolean JNI_TRUE = true;
+ public static final boolean JNI_FALSE = false;
+
+ public static final String JNU_JAVAIOPKG = "java.io.";
+ public static final String JNU_JAVANETPKG = "java.net.";
+
+ public static long JVM_CurrentTimeMillis(JNIEnv env, int ignored)
+ {
+ return System.currentTimeMillis();
+ }
+
+ public static void JNU_ThrowNullPointerException(JNIEnv env, String message)
+ {
+ env.Throw(new NullPointerException(message));
+ }
+
+ public static void JNU_ThrowByName(JNIEnv env, String exceptionClass, String message)
+ {
+ if (exceptionClass.equals("java.net.SocketException"))
+ {
+ env.Throw(new java.net.SocketException(message));
+ }
+ else if (exceptionClass.equals("java.net.SocketTimeoutException"))
+ {
+ env.Throw(new java.net.SocketTimeoutException(message));
+ }
+ else if (exceptionClass.equals("java.net.PortUnreachableException"))
+ {
+ env.Throw(new java.net.PortUnreachableException(message));
+ }
+ else if (exceptionClass.equals("java.io.InterruptedIOException"))
+ {
+ env.Throw(new java.io.InterruptedIOException(message));
+ }
+ else
+ {
+ try
+ {
+ env.ThrowNew(Class.forName(exceptionClass), message);
+ }
+ catch (ClassNotFoundException x)
+ {
+ env.Throw(x);
+ }
+ }
+ }
+
+ public static final class JNIEnv
+ {
+ private Throwable pendingException;
+
+ public void Throw(Throwable t)
+ {
+ pendingException = t;
+ }
+
+ public void ThrowNew(Class c, String msg)
+ {
+ try
+ {
+ pendingException = (Throwable)c.getConstructor(String.class).newInstance(msg);
+ }
+ catch (Exception x)
+ {
+ pendingException = x;
+ }
+ }
+
+ public Throwable ExceptionOccurred()
+ {
+ return pendingException;
+ }
+
+ public void ThrowPendingException()
+ {
+ if (pendingException != null)
+ {
+ sun.misc.Unsafe.getUnsafe().throwException(pendingException);
+ }
+ }
+ }
+}
diff --git a/openjdk/ikvm/internal/Winsock.java b/openjdk/ikvm/internal/Winsock.java
new file mode 100644
index 00000000..2d4959d0
--- /dev/null
+++ b/openjdk/ikvm/internal/Winsock.java
@@ -0,0 +1,943 @@
+/*
+ Copyright (C) 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 ikvm.internal;
+
+import cli.System.Net.EndPoint;
+import cli.System.Net.IPAddress;
+import cli.System.Net.IPEndPoint;
+import cli.System.Net.Sockets.AddressFamily;
+import cli.System.Net.Sockets.IOControlCode;
+import cli.System.Net.Sockets.IPv6MulticastOption;
+import cli.System.Net.Sockets.LingerOption;
+import cli.System.Net.Sockets.MulticastOption;
+import cli.System.Net.Sockets.ProtocolType;
+import cli.System.Net.Sockets.SocketFlags;
+import cli.System.Net.Sockets.SocketOptionName;
+import cli.System.Net.Sockets.SocketOptionLevel;
+import cli.System.Net.Sockets.SocketShutdown;
+import cli.System.Net.Sockets.SocketType;
+import ikvm.lang.CIL;
+
+@ikvm.lang.Internal
+public final class Winsock
+{
+ private Winsock() { }
+
+ // remember the last error code
+ @cli.System.ThreadStaticAttribute.Annotation
+ private static int lastError;
+
+ // Error Codes
+ public static final int WSA_NOT_ENOUGH_MEMORY = 8;
+ public static final int WSA_OPERATION_ABORTED = 995;
+ public static final int WSAEINTR = 10004;
+ public static final int WSAEACCES = 10013;
+ public static final int WSAEFAULT = 10014;
+ public static final int WSAEINVAL = 10022;
+ public static final int WSAEMFILE = 10024;
+ public static final int WSAEWOULDBLOCK = 10035;
+ public static final int WSAEINPROGRESS = 10036;
+ public static final int WSAEALREADY = 10037;
+ public static final int WSAENOTSOCK = 10038;
+ public static final int WSAEDESTADDRREQ = 10039;
+ public static final int WSAEMSGSIZE = 10040;
+ public static final int WSAEPROTOTYPE = 10041;
+ public static final int WSAENOPROTOOPT = 10042;
+ public static final int WSAEPROTONOSUPPORT = 10043;
+ public static final int WSAESOCKTNOSUPPORT = 10044;
+ public static final int WSAEOPNOTSUPP = 10045;
+ public static final int WSAEPFNOSUPPORT = 10046;
+ public static final int WSAEAFNOSUPPORT = 10047;
+ public static final int WSAEADDRINUSE = 10048;
+ public static final int WSAEADDRNOTAVAIL = 10049;
+ public static final int WSAENETDOWN = 10050;
+ public static final int WSAENETUNREACH = 10051;
+ public static final int WSAENETRESET = 10052;
+ public static final int WSAECONNABORTED = 10053;
+ public static final int WSAECONNRESET = 10054;
+ public static final int WSAENOBUFS = 10055;
+ public static final int WSAEISCONN = 10056;
+ public static final int WSAENOTCONN = 10057;
+ public static final int WSAESHUTDOWN = 10058;
+ public static final int WSAETIMEDOUT = 10060;
+ public static final int WSAECONNREFUSED = 10061;
+ public static final int WSAEHOSTDOWN = 10064;
+ public static final int WSAEHOSTUNREACH = 10065;
+ public static final int WSAEPROCLIM = 10067;
+ public static final int WSASYSNOTREADY = 10091;
+ public static final int WSAVERNOTSUPPORTED = 10092;
+ public static final int WSANOTINITIALISED = 10093;
+ public static final int WSAEDISCON = 10101;
+ public static final int WSATYPE_NOT_FOUND = 10109;
+ public static final int WSAHOST_NOT_FOUND = 11001;
+ public static final int WSATRY_AGAIN = 11002;
+ public static final int WSANO_RECOVERY = 11003;
+ public static final int WSANO_DATA = 11004;
+
+ // Other constants
+ public static final int SOCKET_ERROR = -1;
+ public static final cli.System.Net.Sockets.Socket INVALID_SOCKET = null;
+
+ public static final int AF_INET = AddressFamily.InterNetwork;
+ public static final int AF_INET6 = AddressFamily.InterNetworkV6;
+
+ public static final int SOCK_STREAM = SocketType.Stream;
+ public static final int SOCK_DGRAM = SocketType.Dgram;
+
+ public static final int SD_RECEIVE = SocketShutdown.Receive;
+ public static final int SD_SEND = SocketShutdown.Send;
+ public static final int SD_BOTH = SocketShutdown.Both;
+
+ public static final int SOL_SOCKET = SocketOptionLevel.Socket;
+ public static final int IPPROTO_TCP = SocketOptionLevel.Tcp;
+ public static final int IPPROTO_IP = SocketOptionLevel.IP;
+ public static final int IPPROTO_IPV6 = SocketOptionLevel.IPv6;
+
+ public static final int TCP_NODELAY = SocketOptionName.NoDelay;
+ public static final int SO_OOBINLINE = SocketOptionName.OutOfBandInline;
+ public static final int SO_LINGER = SocketOptionName.Linger;
+ public static final int SO_SNDBUF = SocketOptionName.SendBuffer;
+ public static final int SO_RCVBUF = SocketOptionName.ReceiveBuffer;
+ public static final int SO_KEEPALIVE = SocketOptionName.KeepAlive;
+ public static final int SO_REUSEADDR = SocketOptionName.ReuseAddress;
+ public static final int SO_BROADCAST = SocketOptionName.Broadcast;
+ public static final int SO_RCVTIMEO = SocketOptionName.ReceiveTimeout;
+ public static final int SO_ERROR = SocketOptionName.Error;
+ public static final int IP_MULTICAST_IF = SocketOptionName.MulticastInterface;
+ public static final int IP_MULTICAST_LOOP = SocketOptionName.MulticastLoopback;
+ public static final int IP_TOS = SocketOptionName.TypeOfService;
+ public static final int IP_MULTICAST_TTL = SocketOptionName.MulticastTimeToLive;
+ public static final int IP_ADD_MEMBERSHIP = SocketOptionName.AddMembership;
+ public static final int IP_DROP_MEMBERSHIP = SocketOptionName.DropMembership;
+ public static final int IPV6_MULTICAST_IF = SocketOptionName.MulticastInterface;
+ public static final int IPV6_MULTICAST_LOOP = SocketOptionName.MulticastLoopback;
+ public static final int IPV6_MULTICAST_HOPS = SocketOptionName.MulticastTimeToLive;
+ public static final int IPV6_ADD_MEMBERSHIP = SocketOptionName.AddMembership;
+ public static final int IPV6_DROP_MEMBERSHIP = SocketOptionName.DropMembership;
+
+ public static final int SIO_UDP_CONNRESET = 0x9800000C;
+
+ public static final int MSG_PEEK = SocketFlags.Peek;
+ public static final int MSG_OOB = SocketFlags.OutOfBand;
+
+ public static final int FIONREAD = (int)IOControlCode.DataToRead;
+ public static final int FIONBIO = (int)IOControlCode.NonBlockingIO;
+
+ public static int WSAGetLastError()
+ {
+ return lastError;
+ }
+
+ public static void WSASetLastError(int err)
+ {
+ lastError = err;
+ }
+
+ public static int WSASendDisconnect(cli.System.Net.Sockets.Socket socket)
+ {
+ if (socket == null)
+ {
+ lastError = WSAENOTSOCK;
+ return SOCKET_ERROR;
+ }
+ try
+ {
+ if (false) throw new cli.System.Net.Sockets.SocketException();
+ if (false) throw new cli.System.ObjectDisposedException("");
+ socket.Shutdown(SocketShutdown.wrap(SocketShutdown.Send));
+ return 0;
+ }
+ catch (cli.System.Net.Sockets.SocketException x)
+ {
+ lastError = x.get_ErrorCode();
+ return SOCKET_ERROR;
+ }
+ catch (cli.System.ObjectDisposedException _)
+ {
+ lastError = WSAENOTSOCK;
+ return SOCKET_ERROR;
+ }
+ }
+
+ public static int WSAIoctl(cli.System.Net.Sockets.Socket socket, int ioControlCode, boolean optionInValue)
+ {
+ byte[] in = new byte[4];
+ in[0] = optionInValue ? (byte)1 : (byte)0;
+ byte[] out = new byte[4];
+ return WSAIoctl(socket, ioControlCode, in, out);
+ }
+
+ public static int WSAIoctl(cli.System.Net.Sockets.Socket socket, int ioControlCode, byte[] optionInValue, byte[] optionOutValue)
+ {
+ if (socket == null)
+ {
+ lastError = WSAENOTSOCK;
+ return SOCKET_ERROR;
+ }
+ try
+ {
+ if (false) throw new cli.System.Net.Sockets.SocketException();
+ if (false) throw new cli.System.ObjectDisposedException("");
+ if (false) throw new cli.System.InvalidOperationException();
+ if (ioControlCode == FIONBIO)
+ {
+ // it's illegal to meddle with the blocking mode via IOControl
+ socket.set_Blocking(optionInValue[0] == 0);
+ }
+ else if (ioControlCode == FIONREAD)
+ {
+ int avail = socket.get_Available();
+ optionOutValue[0] = (byte)(avail >> 0);
+ optionOutValue[1] = (byte)(avail >> 8);
+ optionOutValue[2] = (byte)(avail >> 16);
+ optionOutValue[3] = (byte)(avail >> 24);
+ }
+ else
+ {
+ socket.IOControl(ioControlCode, optionInValue, optionOutValue);
+ }
+ return 0;
+ }
+ catch (cli.System.Net.Sockets.SocketException x)
+ {
+ lastError = x.get_ErrorCode();
+ return SOCKET_ERROR;
+ }
+ catch (cli.System.ObjectDisposedException _)
+ {
+ lastError = WSAENOTSOCK;
+ return SOCKET_ERROR;
+ }
+ catch (cli.System.InvalidOperationException _)
+ {
+ lastError = WSAEINVAL;
+ return SOCKET_ERROR;
+ }
+ }
+
+ public static int ioctlsocket(cli.System.Net.Sockets.Socket s, int cmd, int[] argp)
+ {
+ byte[] in = cli.System.BitConverter.GetBytes(argp[0]);
+ byte[] out = new byte[4];
+ int ret = WSAIoctl(s, cmd, in, out);
+ argp[0] = cli.System.BitConverter.ToInt32(out, 0);
+ return ret;
+ }
+
+ public static int ioctlsocket(cli.System.Net.Sockets.Socket s, int cmd, int arg)
+ {
+ byte[] in = cli.System.BitConverter.GetBytes(arg);
+ return WSAIoctl(s, cmd, in, in);
+ }
+
+ public static cli.System.Net.Sockets.Socket socket(int af, int type, int protocol)
+ {
+ try
+ {
+ if (false) throw new cli.System.Net.Sockets.SocketException();
+ if (false) throw new cli.System.ObjectDisposedException("");
+ return new cli.System.Net.Sockets.Socket(AddressFamily.wrap(af), SocketType.wrap(type), ProtocolType.wrap(protocol));
+ }
+ catch (cli.System.Net.Sockets.SocketException x)
+ {
+ lastError = x.get_ErrorCode();
+ return INVALID_SOCKET;
+ }
+ catch (cli.System.ObjectDisposedException _)
+ {
+ lastError = WSAENOTSOCK;
+ return INVALID_SOCKET;
+ }
+ }
+
+ public static int closesocket(cli.System.Net.Sockets.Socket socket)
+ {
+ if (socket == null)
+ {
+ lastError = WSAENOTSOCK;
+ return SOCKET_ERROR;
+ }
+ socket.Close();
+ return 0;
+ }
+
+ public static final class linger
+ {
+ public int l_onoff;
+ public int l_linger;
+
+ LingerOption ToLingerOption()
+ {
+ return new LingerOption(l_onoff != 0, l_linger);
+ }
+ }
+
+ public static final class ip_mreq
+ {
+ public final in_addr imr_multiaddr = new in_addr();
+ public final in_addr imr_interface = new in_addr();
+
+ MulticastOption ToMulticastOption()
+ {
+ return new MulticastOption(imr_multiaddr.ToIPAddress(), imr_interface.ToIPAddress());
+ }
+ }
+
+ public static final class in_addr
+ {
+ public int s_addr;
+
+ IPAddress ToIPAddress()
+ {
+ return new IPAddress(s_addr & 0xFFFFFFFFL);
+ }
+ }
+
+ public static final class ipv6_mreq
+ {
+ public in6_addr ipv6mr_multiaddr;
+ public int ipv6mr_interface;
+
+ IPv6MulticastOption ToIPv6MulticastOption()
+ {
+ return new IPv6MulticastOption(ipv6mr_multiaddr.addr, ipv6mr_interface & 0xFFFFFFFFL);
+ }
+ }
+
+ public static final class in6_addr
+ {
+ IPAddress addr;
+
+ public byte[] s6_bytes()
+ {
+ return addr == null ? new byte[16] : addr.GetAddressBytes();
+ }
+
+ public static in6_addr FromSockAddr(IIPEndPointWrapper ep)
+ {
+ in6_addr addr = new in6_addr();
+ addr.addr = ep.get().get_Address();
+ return addr;
+ }
+ }
+
+ public static int getsockopt(cli.System.Net.Sockets.Socket socket, int level, int optname, Object optval)
+ {
+ if (socket == null)
+ {
+ lastError = WSAENOTSOCK;
+ return SOCKET_ERROR;
+ }
+ try
+ {
+ if (false) throw new cli.System.Net.Sockets.SocketException();
+ if (false) throw new cli.System.ObjectDisposedException("");
+ Object val = socket.GetSocketOption(SocketOptionLevel.wrap(level), SocketOptionName.wrap(optname));
+ if (val instanceof cli.System.Int32)
+ {
+ if (optval instanceof in_addr)
+ {
+ ((in_addr)optval).s_addr = CIL.unbox_int(val);
+ }
+ else
+ {
+ ((cli.System.Array)optval).SetValue(val, 0);
+ }
+ }
+ else if (val instanceof LingerOption)
+ {
+ LingerOption lo = (LingerOption)val;
+ linger ling = (linger)optval;
+ ling.l_onoff = lo.get_Enabled() ? 1 : 0;
+ // FXBUG the linger time is treated as a signed short instead of an unsiged short
+ ling.l_linger = lo.get_LingerTime() & 0xFFFF;
+ }
+ else
+ {
+ lastError = WSAEINVAL;
+ return SOCKET_ERROR;
+ }
+ return 0;
+ }
+ catch (cli.System.Net.Sockets.SocketException x)
+ {
+ lastError = x.get_ErrorCode();
+ return SOCKET_ERROR;
+ }
+ catch (cli.System.ObjectDisposedException _)
+ {
+ lastError = WSAENOTSOCK;
+ return SOCKET_ERROR;
+ }
+ }
+
+ public static int connect(cli.System.Net.Sockets.Socket socket, IIPEndPointWrapper epw)
+ {
+ if (socket == null)
+ {
+ lastError = WSAENOTSOCK;
+ return SOCKET_ERROR;
+ }
+ try
+ {
+ if (false) throw new cli.System.Net.Sockets.SocketException();
+ if (false) throw new cli.System.ObjectDisposedException("");
+ IPEndPoint ep = epw.get();
+ if (ep == null)
+ {
+ // it is a disconnect request, we must connect to the Any address
+ if (socket.get_AddressFamily().Value == AddressFamily.InterNetwork)
+ {
+ ep = new IPEndPoint(cli.System.Net.IPAddress.Any, 0);
+ }
+ else
+ {
+ ep = new IPEndPoint(cli.System.Net.IPAddress.IPv6Any, 0);
+ }
+ }
+ if (socket.get_SocketType().Value == SocketType.Dgram)
+ {
+ // NOTE we use async connect to work around the issue that the .NET Socket class disallows sync Connect after the socket has received WSAECONNRESET
+ socket.EndConnect(socket.BeginConnect(ep, null, null));
+ }
+ else
+ {
+ socket.Connect(ep);
+ }
+ return 0;
+ }
+ catch (cli.System.Net.Sockets.SocketException x)
+ {
+ lastError = x.get_ErrorCode();
+ return SOCKET_ERROR;
+ }
+ catch (cli.System.ObjectDisposedException _)
+ {
+ lastError = WSAENOTSOCK;
+ return SOCKET_ERROR;
+ }
+ }
+
+ public static int bind(cli.System.Net.Sockets.Socket socket, IIPEndPointWrapper ep)
+ {
+ if (socket == null)
+ {
+ lastError = WSAENOTSOCK;
+ return SOCKET_ERROR;
+ }
+ try
+ {
+ if (false) throw new cli.System.Net.Sockets.SocketException();
+ if (false) throw new cli.System.ObjectDisposedException("");
+ socket.Bind(ep.get());
+ return 0;
+ }
+ catch (cli.System.Net.Sockets.SocketException x)
+ {
+ lastError = x.get_ErrorCode();
+ return SOCKET_ERROR;
+ }
+ catch (cli.System.ObjectDisposedException _)
+ {
+ lastError = WSAENOTSOCK;
+ return SOCKET_ERROR;
+ }
+ }
+
+ public static int listen(cli.System.Net.Sockets.Socket socket, int count)
+ {
+ if (socket == null)
+ {
+ lastError = WSAENOTSOCK;
+ return SOCKET_ERROR;
+ }
+ try
+ {
+ if (false) throw new cli.System.Net.Sockets.SocketException();
+ if (false) throw new cli.System.ObjectDisposedException("");
+ socket.Listen(count);
+ return 0;
+ }
+ catch (cli.System.Net.Sockets.SocketException x)
+ {
+ lastError = x.get_ErrorCode();
+ return SOCKET_ERROR;
+ }
+ catch (cli.System.ObjectDisposedException _)
+ {
+ lastError = WSAENOTSOCK;
+ return SOCKET_ERROR;
+ }
+ }
+
+ public static int shutdown(cli.System.Net.Sockets.Socket socket, int how)
+ {
+ if (socket == null)
+ {
+ lastError = WSAENOTSOCK;
+ return SOCKET_ERROR;
+ }
+ try
+ {
+ if (false) throw new cli.System.Net.Sockets.SocketException();
+ if (false) throw new cli.System.ObjectDisposedException("");
+ socket.Shutdown(SocketShutdown.wrap(how));
+ return 0;
+ }
+ catch (cli.System.Net.Sockets.SocketException x)
+ {
+ lastError = x.get_ErrorCode();
+ return SOCKET_ERROR;
+ }
+ catch (cli.System.ObjectDisposedException _)
+ {
+ lastError = WSAENOTSOCK;
+ return SOCKET_ERROR;
+ }
+ }
+
+ public static final class fd_set
+ {
+ cli.System.Collections.ArrayList list = new cli.System.Collections.ArrayList();
+ }
+
+ public static final class timeval
+ {
+ public long tv_sec;
+ public long tv_usec;
+ }
+
+ public static void FD_ZERO(fd_set set)
+ {
+ set.list.Clear();
+ }
+
+ public static void FD_SET(cli.System.Net.Sockets.Socket socket, fd_set set)
+ {
+ set.list.Add(socket);
+ }
+
+ public static boolean FD_ISSET(cli.System.Net.Sockets.Socket socket, fd_set set)
+ {
+ return set.list.Contains(socket);
+ }
+
+ private static cli.System.Collections.ArrayList copy(fd_set set)
+ {
+ return set == null ? null : (cli.System.Collections.ArrayList)set.list.Clone();
+ }
+
+ public static int select(fd_set readfds, fd_set writefds, fd_set exceptfds, timeval timeout)
+ {
+ long expiration;
+ long current = cli.System.DateTime.get_UtcNow().get_Ticks();
+ if (timeout == null)
+ {
+ // FXBUG documentation says that -1 will block forever, but in fact it returns immediately,
+ // so we simulate timeout with a large expiration
+ expiration = Long.MAX_VALUE;
+ }
+ else
+ {
+ long timeout100nanos = Math.min(Long.MAX_VALUE / 10, timeout.tv_usec) * 10 + Math.min(Long.MAX_VALUE / 10000000, timeout.tv_sec) * 10000000;
+ expiration = current + Math.min(Long.MAX_VALUE - current, timeout100nanos);
+ }
+ try
+ {
+ if (false) throw new cli.System.ArgumentNullException();
+ if (false) throw new cli.System.Net.Sockets.SocketException();
+ if (false) throw new cli.System.ObjectDisposedException("");
+ for (; ; )
+ {
+ cli.System.Collections.ArrayList checkRead = copy(readfds);
+ cli.System.Collections.ArrayList checkWrite = copy(writefds);
+ cli.System.Collections.ArrayList checkError = copy(exceptfds);
+ int microSeconds = (int)Math.min(Integer.MAX_VALUE, (expiration - current) / 10);
+ cli.System.Net.Sockets.Socket.Select(checkRead, checkWrite, checkError, microSeconds);
+ int count = 0;
+ if (checkRead != null)
+ {
+ count += checkRead.get_Count();
+ }
+ if (checkWrite != null)
+ {
+ count += checkWrite.get_Count();
+ }
+ if (checkError != null)
+ {
+ count += checkError.get_Count();
+ }
+ current = cli.System.DateTime.get_UtcNow().get_Ticks();
+ if (count != 0 || current >= expiration)
+ {
+ if (readfds != null)
+ {
+ readfds.list = checkRead;
+ }
+ if (writefds != null)
+ {
+ writefds.list = checkWrite;
+ }
+ if (exceptfds != null)
+ {
+ exceptfds.list = checkError;
+ }
+ return count;
+ }
+ }
+ }
+ catch (cli.System.ArgumentNullException _)
+ {
+ lastError = WSAEINVAL;
+ return SOCKET_ERROR;
+ }
+ catch (cli.System.Net.Sockets.SocketException x)
+ {
+ lastError = x.get_ErrorCode();
+ return SOCKET_ERROR;
+ }
+ catch (cli.System.ObjectDisposedException _)
+ {
+ lastError = WSAENOTSOCK;
+ return SOCKET_ERROR;
+ }
+ }
+
+ public static int send(cli.System.Net.Sockets.Socket socket, byte[] buf, int len, int flags)
+ {
+ return send(socket, buf, 0, len, flags);
+ }
+
+ public static int send(cli.System.Net.Sockets.Socket socket, byte[] buf, int off, int len, int flags)
+ {
+ if (socket == null)
+ {
+ lastError = WSAENOTSOCK;
+ return SOCKET_ERROR;
+ }
+ try
+ {
+ if (false) throw new cli.System.ArgumentException();
+ if (false) throw new cli.System.Net.Sockets.SocketException();
+ if (false) throw new cli.System.ObjectDisposedException("");
+ return socket.Send(buf, off, len, SocketFlags.wrap(flags));
+ }
+ catch (cli.System.ArgumentException _)
+ {
+ lastError = WSAEINVAL;
+ return SOCKET_ERROR;
+ }
+ catch (cli.System.Net.Sockets.SocketException x)
+ {
+ lastError = x.get_ErrorCode();
+ return SOCKET_ERROR;
+ }
+ catch (cli.System.ObjectDisposedException _)
+ {
+ lastError = WSAENOTSOCK;
+ return SOCKET_ERROR;
+ }
+ }
+
+ public static int recv(cli.System.Net.Sockets.Socket socket, byte[] buf, int len, int flags)
+ {
+ if (socket == null)
+ {
+ lastError = WSAENOTSOCK;
+ return SOCKET_ERROR;
+ }
+ try
+ {
+ if (false) throw new cli.System.ArgumentException();
+ if (false) throw new cli.System.Net.Sockets.SocketException();
+ if (false) throw new cli.System.ObjectDisposedException("");
+ return socket.Receive(buf, len, SocketFlags.wrap(flags));
+ }
+ catch (cli.System.ArgumentException _)
+ {
+ lastError = WSAEINVAL;
+ return SOCKET_ERROR;
+ }
+ catch (cli.System.Net.Sockets.SocketException x)
+ {
+ lastError = x.get_ErrorCode();
+ return SOCKET_ERROR;
+ }
+ catch (cli.System.ObjectDisposedException _)
+ {
+ lastError = WSAENOTSOCK;
+ return SOCKET_ERROR;
+ }
+ }
+
+ public static int sendto(cli.System.Net.Sockets.Socket socket, byte[] buf, int off, int len, int flags, IIPEndPointWrapper to)
+ {
+ if (socket == null)
+ {
+ lastError = WSAENOTSOCK;
+ return SOCKET_ERROR;
+ }
+ try
+ {
+ if (false) throw new cli.System.ArgumentException();
+ if (false) throw new cli.System.Net.Sockets.SocketException();
+ if (false) throw new cli.System.ObjectDisposedException("");
+ if (to == null)
+ {
+ return socket.Send(buf, off, len, SocketFlags.wrap(flags));
+ }
+ else
+ {
+ return socket.SendTo(buf, off, len, SocketFlags.wrap(flags), to.get());
+ }
+ }
+ catch (cli.System.ArgumentException _)
+ {
+ lastError = WSAEINVAL;
+ return SOCKET_ERROR;
+ }
+ catch (cli.System.Net.Sockets.SocketException x)
+ {
+ // on Linux we get a WSAECONNREFUSED when sending to an unreachable port/destination, so ignore that
+ if (x.get_ErrorCode() == WSAECONNREFUSED)
+ {
+ return 0;
+ }
+ lastError = x.get_ErrorCode();
+ return SOCKET_ERROR;
+ }
+ catch (cli.System.ObjectDisposedException _)
+ {
+ lastError = WSAENOTSOCK;
+ return SOCKET_ERROR;
+ }
+ }
+
+ public static int recvfrom(cli.System.Net.Sockets.Socket socket, byte[] buf, int len, int flags, IIPEndPointWrapper from)
+ {
+ return recvfrom(socket, buf, 0, len, flags, from);
+ }
+
+ public static int recvfrom(cli.System.Net.Sockets.Socket socket, byte[] buf, int off, int len, int flags, IIPEndPointWrapper from)
+ {
+ if (socket == null)
+ {
+ lastError = WSAENOTSOCK;
+ return SOCKET_ERROR;
+ }
+ try
+ {
+ if (false) throw new cli.System.ArgumentException();
+ if (false) throw new cli.System.Net.Sockets.SocketException();
+ if (false) throw new cli.System.ObjectDisposedException("");
+ EndPoint[] ep = new EndPoint[] { socket.get_AddressFamily().Value == AF_INET6 ? new IPEndPoint(IPAddress.IPv6Any, 0) : new IPEndPoint(0, 0) };
+ try
+ {
+ return socket.ReceiveFrom(buf, off, len, SocketFlags.wrap(flags), ep);
+ }
+ finally
+ {
+ if (from != null)
+ {
+ from.set((IPEndPoint)ep[0]);
+ }
+ }
+ }
+ catch (cli.System.ArgumentException _)
+ {
+ lastError = WSAEINVAL;
+ return SOCKET_ERROR;
+ }
+ catch (cli.System.Net.Sockets.SocketException x)
+ {
+ lastError = x.get_ErrorCode();
+ return SOCKET_ERROR;
+ }
+ catch (cli.System.ObjectDisposedException _)
+ {
+ lastError = WSAENOTSOCK;
+ return SOCKET_ERROR;
+ }
+ }
+
+ public static int setsockopt(cli.System.Net.Sockets.Socket s, int level, int optname, Object optval)
+ {
+ if (s == null)
+ {
+ lastError = WSAENOTSOCK;
+ return SOCKET_ERROR;
+ }
+ try
+ {
+ if (false) throw new cli.System.ArgumentException();
+ if (false) throw new cli.System.Net.Sockets.SocketException();
+ if (false) throw new cli.System.ObjectDisposedException("");
+ if (optval instanceof Boolean)
+ {
+ s.SetSocketOption(SocketOptionLevel.wrap(level), SocketOptionName.wrap(optname), ((Boolean)optval).booleanValue());
+ }
+ else if (optval instanceof Integer)
+ {
+ s.SetSocketOption(SocketOptionLevel.wrap(level), SocketOptionName.wrap(optname), ((Integer)optval).intValue());
+ }
+ else if (optval instanceof linger)
+ {
+ s.set_LingerState(((linger)optval).ToLingerOption());
+ }
+ else if (optval instanceof ip_mreq)
+ {
+ s.SetSocketOption(SocketOptionLevel.wrap(level), SocketOptionName.wrap(optname), ((ip_mreq)optval).ToMulticastOption());
+ }
+ else if (optval instanceof ipv6_mreq)
+ {
+ s.SetSocketOption(SocketOptionLevel.wrap(level), SocketOptionName.wrap(optname), ((ipv6_mreq)optval).ToIPv6MulticastOption());
+ }
+ else if (optval instanceof in_addr)
+ {
+ s.SetSocketOption(SocketOptionLevel.wrap(level), SocketOptionName.wrap(optname), ((in_addr)optval).s_addr);
+ }
+ else
+ {
+ lastError = WSAEINVAL;
+ return SOCKET_ERROR;
+ }
+ return 0;
+ }
+ catch (cli.System.ArgumentException _)
+ {
+ lastError = WSAEINVAL;
+ return SOCKET_ERROR;
+ }
+ catch (cli.System.Net.Sockets.SocketException x)
+ {
+ lastError = x.get_ErrorCode();
+ return SOCKET_ERROR;
+ }
+ catch (cli.System.ObjectDisposedException _)
+ {
+ lastError = WSAENOTSOCK;
+ return SOCKET_ERROR;
+ }
+ }
+
+ public static cli.System.Net.Sockets.Socket accept(cli.System.Net.Sockets.Socket s, IIPEndPointWrapper ep)
+ {
+ if (s == null)
+ {
+ lastError = WSAENOTSOCK;
+ return INVALID_SOCKET;
+ }
+ try
+ {
+ if (false) throw new cli.System.InvalidOperationException();
+ if (false) throw new cli.System.Net.Sockets.SocketException();
+ if (false) throw new cli.System.ObjectDisposedException("");
+ cli.System.Net.Sockets.Socket remote = s.Accept();
+ if (ep != null)
+ {
+ ep.set((IPEndPoint)remote.get_RemoteEndPoint());
+ }
+ return remote;
+ }
+ catch (cli.System.ObjectDisposedException _)
+ {
+ lastError = WSAENOTSOCK;
+ return INVALID_SOCKET;
+ }
+ catch (cli.System.InvalidOperationException _)
+ {
+ lastError = WSAEINVAL;
+ return INVALID_SOCKET;
+ }
+ catch (cli.System.Net.Sockets.SocketException x)
+ {
+ lastError = x.get_ErrorCode();
+ return INVALID_SOCKET;
+ }
+ }
+
+ public interface IIPEndPointWrapper
+ {
+ void set(IPEndPoint value);
+ IPEndPoint get();
+ }
+
+ public static int getsockname(cli.System.Net.Sockets.Socket s, IIPEndPointWrapper name)
+ {
+ if (s == null)
+ {
+ lastError = WSAENOTSOCK;
+ return SOCKET_ERROR;
+ }
+ try
+ {
+ if (false) throw new cli.System.Net.Sockets.SocketException();
+ if (false) throw new cli.System.ObjectDisposedException("");
+ IPEndPoint ep = (IPEndPoint)s.get_LocalEndPoint();
+ if (ep == null)
+ {
+ lastError = WSAEINVAL;
+ return SOCKET_ERROR;
+ }
+ name.set(ep);
+ return 0;
+ }
+ catch (ClassCastException _)
+ {
+ lastError = WSAEOPNOTSUPP;
+ return SOCKET_ERROR;
+ }
+ catch (cli.System.ObjectDisposedException _)
+ {
+ lastError = WSAENOTSOCK;
+ return SOCKET_ERROR;
+ }
+ catch (cli.System.Net.Sockets.SocketException x)
+ {
+ lastError = x.get_ErrorCode();
+ return SOCKET_ERROR;
+ }
+ }
+
+ public static int ntohl(int address)
+ {
+ return Integer.reverseBytes(address);
+ }
+
+ public static int htonl(int address)
+ {
+ return Integer.reverseBytes(address);
+ }
+
+ public static int ntohs(int port)
+ {
+ return Short.reverseBytes((short)port) & 0xFFFF;
+ }
+
+ public static int htons(int port)
+ {
+ return Short.reverseBytes((short)port) & 0xFFFF;
+ }
+}
diff --git a/openjdk/java/net/DefaultDatagramSocketImplFactory.java b/openjdk/java/net/DefaultDatagramSocketImplFactory.java
deleted file mode 100644
index 54bae661..00000000
--- a/openjdk/java/net/DefaultDatagramSocketImplFactory.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- Copyright (C) 2008 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;
-
-class DefaultDatagramSocketImplFactory
-{
- static DatagramSocketImpl createDatagramSocketImpl(boolean isMulticast) throws SocketException
- {
- return new PlainDatagramSocketImpl();
- }
-}
diff --git a/openjdk/java/net/PlainDatagramSocketImpl.java b/openjdk/java/net/PlainDatagramSocketImpl.java
deleted file mode 100644
index 0ec993d9..00000000
--- a/openjdk/java/net/PlainDatagramSocketImpl.java
+++ /dev/null
@@ -1,779 +0,0 @@
-/*
- * Copyright 1996-2003 Sun Microsystems, Inc. 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. Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-package java.net;
-
-import cli.System.Net.IPAddress;
-import cli.System.Net.IPEndPoint;
-import cli.System.Net.Sockets.SelectMode;
-import cli.System.Net.Sockets.SocketOptionName;
-import cli.System.Net.Sockets.SocketOptionLevel;
-import cli.System.Net.Sockets.MulticastOption;
-import cli.System.Net.Sockets.SocketFlags;
-import cli.System.Net.Sockets.SocketType;
-import cli.System.Net.Sockets.ProtocolType;
-import cli.System.Net.Sockets.AddressFamily;
-import ikvm.lang.CIL;
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.io.InterruptedIOException;
-import java.util.Enumeration;
-
-/**
- * Concrete datagram and multicast socket implementation base class.
- * Note: This is not a public class, so that applets cannot call
- * into the implementation directly and hence cannot bypass the
- * security checks present in the DatagramSocket and MulticastSocket
- * classes.
- *
- * @author Pavani Diwanji
- */
-
-class PlainDatagramSocketImpl extends DatagramSocketImpl
-{
- // Windows 2000 introduced a "feature" that causes it to return WSAECONNRESET from receive,
- // if a previous send resulted in an ICMP port unreachable. We disable this feature by using
- // this ioctl.
- private static final int IOC_IN = (int)0x80000000;
- private static final int IOC_VENDOR = 0x18000000;
- private static final int SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12;
-
- // Winsock Error Codes
- private static final int WSAEMSGSIZE = 10040;
- private static final int WSAECONNRESET = 10054;
-
- private cli.System.Net.Sockets.Socket netSocket;
- /* timeout value for receive() */
- private int timeout = 0;
- private int trafficClass = 0;
- private boolean connected = false;
- private InetAddress connectedAddress = null;
- private int connectedPort = -1;
-
- /* cached socket options */
- private int multicastInterface = 0;
- private boolean loopbackMode = true;
- private int ttl = -1;
-
- /* Used for IPv6 on Windows only */
- private FileDescriptor fd1;
- private int fduse=-1; /* 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
- */
- private int lastfd=-1;
-
- /*
- * 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;
-
- /**
- * Creates a datagram socket
- */
- protected synchronized void create() throws SocketException {
- fd = new FileDescriptor();
- fd1 = new FileDescriptor();
- datagramSocketCreate();
- }
-
- /**
- * Binds a datagram socket to a local port.
- */
- protected synchronized void bind(int lport, InetAddress laddr)
- throws SocketException {
-
- bind0(lport, laddr);
- if (laddr.isAnyLocalAddress()) {
- anyLocalBoundAddr = laddr;
- }
- }
-
- protected synchronized void bind0(int lport, InetAddress laddr) throws SocketException
- {
- try
- {
- if (false) throw new cli.System.Net.Sockets.SocketException();
- if (false) throw new cli.System.ObjectDisposedException("");
- netSocket.Bind(new IPEndPoint(SocketUtil.getAddressFromInetAddress(laddr), lport));
- localPort = ((IPEndPoint)netSocket.get_LocalEndPoint()).get_Port();
- }
- catch (cli.System.Net.Sockets.SocketException x)
- {
- throw new BindException(x.getMessage());
- }
- catch (cli.System.ObjectDisposedException x1)
- {
- throw new SocketException("Socket is closed");
- }
- }
-
- /**
- * Sends a datagram packet. The packet contains the data and the
- * destination address to send the packet to.
- * @param packet to be sent.
- */
- protected void send(DatagramPacket p) throws IOException
- {
- try
- {
- if (false) throw new cli.System.Net.Sockets.SocketException();
- if (false) throw new cli.System.ObjectDisposedException("");
- int len = p.getLength();
- int port = p.getPort();
- if (port < 1 || port > 65535)
- {
- throw new SocketException("Invalid port");
- }
- if (netSocket.SendTo(p.getData(), p.getOffset(), len, SocketFlags.wrap(SocketFlags.None), new IPEndPoint(SocketUtil.getAddressFromInetAddress(p.getAddress()), port)) != len)
- {
- throw new SocketException("Not all data was sent");
- }
- }
- catch (cli.System.Net.Sockets.SocketException x)
- {
- throw SocketUtil.convertSocketExceptionToIOException(x);
- }
- catch (cli.System.ObjectDisposedException x1)
- {
- throw new SocketException("Socket is closed");
- }
- }
-
- /**
- * Connects a datagram socket to a remote destination. This associates the remote
- * address with the local socket so that datagrams may only be sent to this destination
- * and received from this destination.
- * @param address the remote InetAddress to connect to
- * @param port the remote port number
- */
- protected void connect(InetAddress address, int port) throws SocketException {
- connect0(address, port);
- connectedAddress = address;
- connectedPort = port;
- connected = true;
- }
-
- /**
- * Disconnects a previously connected socket. Does nothing if the socket was
- * not connected already.
- */
- protected void disconnect() {
- disconnect0(connectedAddress.family);
- connected = false;
- connectedAddress = null;
- connectedPort = -1;
- }
-
- /**
- * Peek at the packet to see who it is from.
- * @param return the address which the packet came from.
- */
- protected synchronized int peek(InetAddress i) throws IOException
- {
- DatagramPacket p = new DatagramPacket(new byte[1], 1);
- receiveImpl(p, SocketFlags.Peek);
- i.address = p.getAddress().address;
- i.family = InetAddress.IPv4;
- return p.getPort();
- }
-
- protected synchronized int peekData(DatagramPacket p) throws IOException
- {
- receiveImpl(p, SocketFlags.Peek);
- return p.getPort();
- }
-
- /**
- * Receive the datagram packet.
- * @param Packet Received.
- */
- protected synchronized void receive(DatagramPacket p)
- throws IOException {
- try {
- receive0(p);
- } finally {
- fduse = -1;
- }
- }
-
- protected synchronized void receive0(DatagramPacket p) throws IOException
- {
- receiveImpl(p, SocketFlags.None);
- }
-
- private void receiveImpl(DatagramPacket p, int socketFlags) throws IOException
- {
- cli.System.Net.EndPoint[] remoteEP = new cli.System.Net.EndPoint[]
- {
- new cli.System.Net.IPEndPoint(0, 0)
- };
- int length;
- for (; ; )
- {
- try
- {
- if (false) throw new cli.System.Net.Sockets.SocketException();
- if (false) throw new cli.System.ObjectDisposedException("");
- if (timeout > 0 && !netSocket.Poll(Math.min(timeout, Integer.MAX_VALUE / 1000) * 1000,
- SelectMode.wrap(SelectMode.SelectRead)))
- {
- throw new SocketTimeoutException();
- }
- length = netSocket.ReceiveFrom(p.buf, p.offset, p.bufLength, SocketFlags.wrap(socketFlags), remoteEP);
- break;
- }
- catch (cli.System.Net.Sockets.SocketException x)
- {
- if (x.get_ErrorCode() == WSAECONNRESET)
- {
- // A previous send failed (i.e. the remote host responded with a ICMP that the port is closed) and
- // the winsock stack helpfully lets us know this, but we only care about this when we're connected,
- // otherwise we'll simply retry the receive (note that we use SIO_UDP_CONNRESET to prevent these
- // WSAECONNRESET exceptions, but when switching from connected to disconnected, some can slip through).
- if ((socketFlags & SocketFlags.Peek) != 0)
- {
- // We did a peek, so we still need to remove the error result.
- try
- {
- if (false) throw new cli.System.Net.Sockets.SocketException();
- if (false) throw new cli.System.ObjectDisposedException("");
- netSocket.ReceiveFrom(p.buf, 0, 0, SocketFlags.wrap(SocketFlags.None), remoteEP);
- }
- catch (cli.System.Net.Sockets.SocketException _)
- {
- }
- catch (cli.System.ObjectDisposedException _)
- {
- }
- }
- if (connected)
- {
- throw new PortUnreachableException("ICMP Port Unreachable");
- }
- continue;
- }
- if (x.get_ErrorCode() == WSAEMSGSIZE)
- {
- // The buffer size was too small for the packet, ReceiveFrom receives the part of the packet
- // that fits in the buffer and then throws an exception, so we have to ignore the exception in this case.
- length = p.bufLength;
- break;
- }
- throw SocketUtil.convertSocketExceptionToIOException(x);
- }
- catch (cli.System.ObjectDisposedException x1)
- {
- throw new SocketException("Socket is closed");
- }
- }
- IPEndPoint endpoint = (IPEndPoint)remoteEP[0];
- p.address = SocketUtil.getInetAddressFromIPEndPoint(endpoint);
- p.port = endpoint.get_Port();
- p.length = length;
- }
-
- /**
- * Set the TTL (time-to-live) option.
- * @param TTL to be set.
- */
- protected void setTimeToLive(int ttl) throws IOException
- {
- try
- {
- if (false) throw new cli.System.Net.Sockets.SocketException();
- if (false) throw new cli.System.ObjectDisposedException("");
- netSocket.SetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.IP), SocketOptionName.wrap(SocketOptionName.IpTimeToLive), ttl);
- }
- catch (cli.System.Net.Sockets.SocketException x)
- {
- throw new SocketException(x.getMessage());
- }
- catch (cli.System.ObjectDisposedException x2)
- {
- throw new SocketException("Socket is closed");
- }
- }
-
- /**
- * Get the TTL (time-to-live) option.
- */
- protected int getTimeToLive() throws IOException
- {
- try
- {
- if (false) throw new cli.System.Net.Sockets.SocketException();
- if (false) throw new cli.System.ObjectDisposedException("");
- return CIL.unbox_int(netSocket.GetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.IP), SocketOptionName.wrap(SocketOptionName.IpTimeToLive)));
- }
- catch (cli.System.Net.Sockets.SocketException x)
- {
- throw new SocketException(x.getMessage());
- }
- catch (cli.System.ObjectDisposedException x2)
- {
- throw new SocketException("Socket is closed");
- }
- }
-
- /**
- * Set the TTL (time-to-live) option.
- * @param TTL to be set.
- */
- protected void setTTL(byte ttl) throws IOException
- {
- setTimeToLive(ttl & 0xFF);
- }
-
- /**
- * Get the TTL (time-to-live) option.
- */
- protected byte getTTL() throws IOException
- {
- return (byte)getTimeToLive();
- }
-
- /**
- * Join the multicast group.
- * @param multicast address to join.
- */
- protected void join(InetAddress inetaddr) throws IOException {
- join(inetaddr, null);
- }
-
- /**
- * Leave the multicast group.
- * @param multicast address to leave.
- */
- protected void leave(InetAddress inetaddr) throws IOException {
- leave(inetaddr, null);
- }
- /**
- * Join the multicast group.
- * @param multicast address to join.
- * @param netIf specifies the local interface to receive multicast
- * datagram packets
- * @throws IllegalArgumentException if mcastaddr is null or is a
- * SocketAddress subclass not supported by this socket
- * @since 1.4
- */
-
- protected void joinGroup(SocketAddress mcastaddr, NetworkInterface netIf)
- throws IOException {
- if (mcastaddr == null || !(mcastaddr instanceof InetSocketAddress))
- throw new IllegalArgumentException("Unsupported address type");
- join(((InetSocketAddress)mcastaddr).getAddress(), netIf);
- }
-
- private void join(InetAddress inetaddr, NetworkInterface netIf) throws IOException
- {
- try
- {
- if (false) throw new cli.System.Net.Sockets.SocketException();
- if (false) throw new cli.System.ArgumentException();
- if (false) throw new cli.System.ObjectDisposedException("");
- IPAddress mcastAddr = SocketUtil.getAddressFromInetAddress(inetaddr);
- if (netIf == null)
- {
- netSocket.SetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.IP), SocketOptionName.wrap(SocketOptionName.AddMembership), new MulticastOption(mcastAddr));
- }
- else
- {
- Enumeration e = netIf.getInetAddresses();
- if (e.hasMoreElements())
- {
- IPAddress bindAddr = SocketUtil.getAddressFromInetAddress((InetAddress)e.nextElement());
- MulticastOption mcastOption = new MulticastOption(mcastAddr, bindAddr);
- netSocket.SetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.IP), SocketOptionName.wrap(SocketOptionName.AddMembership), mcastOption);
- }
- }
- }
- catch (cli.System.Net.Sockets.SocketException x)
- {
- throw SocketUtil.convertSocketExceptionToIOException(x);
- }
- catch (cli.System.ArgumentException x1)
- {
- throw new IOException(x1.getMessage());
- }
- catch (cli.System.ObjectDisposedException x2)
- {
- throw new SocketException("Socket is closed");
- }
- }
-
- /**
- * Leave the multicast group.
- * @param multicast address to leave.
- * @param netIf specified the local interface to leave the group at
- * @throws IllegalArgumentException if mcastaddr is null or is a
- * SocketAddress subclass not supported by this socket
- * @since 1.4
- */
- protected void leaveGroup(SocketAddress mcastaddr, NetworkInterface netIf)
- throws IOException {
- if (mcastaddr == null || !(mcastaddr instanceof InetSocketAddress))
- throw new IllegalArgumentException("Unsupported address type");
- leave(((InetSocketAddress)mcastaddr).getAddress(), netIf);
- }
-
- private void leave(InetAddress inetaddr, NetworkInterface netIf) throws IOException
- {
- try
- {
- if (false) throw new cli.System.Net.Sockets.SocketException();
- if (false) throw new cli.System.ArgumentException();
- if (false) throw new cli.System.ObjectDisposedException("");
- IPAddress mcastAddr = SocketUtil.getAddressFromInetAddress(inetaddr);
- if (netIf == null)
- {
- netSocket.SetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.IP), SocketOptionName.wrap(SocketOptionName.DropMembership), new MulticastOption(mcastAddr));
- }
- else
- {
- Enumeration e = netIf.getInetAddresses();
- if (e.hasMoreElements())
- {
- IPAddress bindAddr = SocketUtil.getAddressFromInetAddress((InetAddress)e.nextElement());
- MulticastOption mcastOption = new MulticastOption(mcastAddr, bindAddr);
- netSocket.SetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.IP), SocketOptionName.wrap(SocketOptionName.DropMembership), mcastOption);
- }
- }
- }
- catch (cli.System.Net.Sockets.SocketException x)
- {
- throw SocketUtil.convertSocketExceptionToIOException(x);
- }
- catch (cli.System.ArgumentException x1)
- {
- throw new IOException(x1.getMessage());
- }
- catch (cli.System.ObjectDisposedException x2)
- {
- throw new SocketException("Socket is closed");
- }
- }
-
- /**
- * Close the socket.
- */
- protected void close() {
- if (fd != null || fd1 != null) {
- datagramSocketClose();
- fd = null;
- fd1 = null;
- }
- }
-
- /**
- * set a value - since we only support (setting) binary options
- * here, o must be a Boolean
- */
-
- public void setOption(int optID, Object o) throws SocketException {
- if (fd == null && fd1 == null) {
- throw new SocketException("Socket Closed");
- }
- switch (optID) {
- /* check type safety b4 going native. These should never
- * fail, since only java.Socket* has access to
- * PlainSocketImpl.setOption().
- */
- case SO_TIMEOUT:
- if (o == null || !(o instanceof Integer)) {
- throw new SocketException("bad argument for SO_TIMEOUT");
- }
- int tmp = ((Integer) o).intValue();
- if (tmp < 0)
- throw new IllegalArgumentException("timeout < 0");
- timeout = tmp;
- return;
- case IP_TOS:
- if (o == null || !(o instanceof Integer)) {
- throw new SocketException("bad argument for IP_TOS");
- }
- trafficClass = ((Integer)o).intValue();
- break;
- case SO_REUSEADDR:
- if (o == null || !(o instanceof Boolean)) {
- throw new SocketException("bad argument for SO_REUSEADDR");
- }
- break;
- case SO_BROADCAST:
- if (o == null || !(o instanceof Boolean)) {
- throw new SocketException("bad argument for SO_BROADCAST");
- }
- break;
- case SO_BINDADDR:
- throw new SocketException("Cannot re-bind Socket");
- case SO_RCVBUF:
- case SO_SNDBUF:
- if (o == null || !(o instanceof Integer) ||
- ((Integer)o).intValue() < 0) {
- throw new SocketException("bad argument for SO_SNDBUF or " +
- "SO_RCVBUF");
- }
- break;
- case IP_MULTICAST_IF:
- if (o == null || !(o instanceof InetAddress))
- throw new SocketException("bad argument for IP_MULTICAST_IF");
- break;
- case IP_MULTICAST_IF2:
- if (o == null || !(o instanceof NetworkInterface))
- throw new SocketException("bad argument for IP_MULTICAST_IF2");
- break;
- case IP_MULTICAST_LOOP:
- if (o == null || !(o instanceof Boolean))
- throw new SocketException("bad argument for IP_MULTICAST_LOOP");
- break;
- default:
- throw new SocketException("invalid option: " + optID);
- }
- socketSetOption(optID, o);
- }
-
- /*
- * get option's state - set or not
- */
-
- public Object getOption(int optID) throws SocketException {
- if (fd == null && fd1 == null) {
- throw new SocketException("Socket Closed");
- }
-
- Object result;
-
- switch (optID) {
- case SO_TIMEOUT:
- result = new Integer(timeout);
- break;
-
- case IP_TOS:
- result = socketGetOption(optID);
- if ( ((Integer)result).intValue() == -1) {
- result = new Integer(trafficClass);
- }
- break;
-
- case SO_BINDADDR:
- if (fd != null && fd1 != null) {
- return anyLocalBoundAddr;
- }
- /* fall through */
- case IP_MULTICAST_IF:
- case IP_MULTICAST_IF2:
- case SO_RCVBUF:
- case SO_SNDBUF:
- case IP_MULTICAST_LOOP:
- case SO_REUSEADDR:
- case SO_BROADCAST:
- result = socketGetOption(optID);
- break;
-
- default:
- throw new SocketException("invalid option: " + optID);
- }
-
- return result;
- }
-
- private void datagramSocketCreate() throws SocketException
- {
- try
- {
- if (false) throw new cli.System.Net.Sockets.SocketException();
- netSocket = new cli.System.Net.Sockets.Socket(
- AddressFamily.wrap(AddressFamily.InterNetwork),
- SocketType.wrap(SocketType.Dgram),
- ProtocolType.wrap(ProtocolType.Udp));
- netSocket.SetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Socket), SocketOptionName.wrap(SocketOptionName.Broadcast), 1);
- netSocket.IOControl(SIO_UDP_CONNRESET, new byte[] { 0 }, null);
- fd1 = null;
- }
- catch (cli.System.Net.Sockets.SocketException x)
- {
- throw new SocketException(x.getMessage());
- }
- }
-
- private void datagramSocketClose()
- {
- netSocket.Close();
- }
-
- private void socketSetOption(int opt, Object val) throws SocketException
- {
- try
- {
- if (false) throw new cli.System.Net.Sockets.SocketException();
- if (false) throw new cli.System.ObjectDisposedException("");
- switch (opt)
- {
- case SocketOptions.SO_BROADCAST:
- netSocket.SetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Socket), SocketOptionName.wrap(SocketOptionName.Broadcast), ((Boolean)val).booleanValue() ? 1 : 0);
- break;
- case SocketOptions.IP_MULTICAST_IF:
- {
- InetAddress addr = (InetAddress)val;
- netSocket.SetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.IP), SocketOptionName.wrap(SocketOptionName.MulticastInterface), (int)SocketUtil.getAddressFromInetAddress(addr).get_Address());
- break;
- }
- case SocketOptions.IP_MULTICAST_IF2:
- {
- NetworkInterface netIf = (NetworkInterface)val;
- Enumeration e = netIf.getInetAddresses();
- while (e.hasMoreElements())
- {
- InetAddress addr = (InetAddress)e.nextElement();
- if (addr.getAddress().length == 4)
- {
- netSocket.SetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.IP), SocketOptionName.wrap(SocketOptionName.MulticastInterface), (int)SocketUtil.getAddressFromInetAddress(addr).get_Address());
- return;
- }
- }
- throw new SocketException("No IPv4 address found on interface");
- }
- case SocketOptions.IP_MULTICAST_LOOP:
- netSocket.SetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.IP), SocketOptionName.wrap(SocketOptionName.MulticastLoopback), ((Boolean)val).booleanValue() ? 1 : 0);
- break;
- case SocketOptions.SO_REUSEADDR:
- SocketUtil.setCommonSocketOption(netSocket, opt, ((Boolean)val).booleanValue(), null);
- break;
- default:
- SocketUtil.setCommonSocketOption(netSocket, opt, false, val);
- break;
- }
- }
- catch (cli.System.Net.Sockets.SocketException x)
- {
- throw new SocketException(x.getMessage());
- }
- catch (cli.System.ObjectDisposedException x1)
- {
- throw new SocketException("Socket is closed");
- }
- }
-
- private static InetAddress getInetAddressFromInt(int addr) throws SocketException
- {
- try
- {
- return InetAddress.getByAddress(cli.System.BitConverter.GetBytes(addr));
- }
- catch (UnknownHostException x)
- {
- throw new SocketException(x.getMessage());
- }
- }
-
- private Object socketGetOption(int opt) throws SocketException
- {
- try
- {
- if (false) throw new cli.System.Net.Sockets.SocketException();
- if (false) throw new cli.System.ObjectDisposedException("");
- switch (opt)
- {
- case SocketOptions.SO_BROADCAST:
- return CIL.unbox_int(netSocket.GetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Socket), SocketOptionName.wrap(SocketOptionName.Broadcast))) != 0;
- case SocketOptions.IP_MULTICAST_IF:
- return getInetAddressFromInt(CIL.unbox_int(netSocket.GetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.IP), SocketOptionName.wrap(SocketOptionName.MulticastInterface))));
- case SocketOptions.IP_MULTICAST_IF2:
- {
- NetworkInterface inf = NetworkInterface.getByInetAddress(getInetAddressFromInt(CIL.unbox_int(netSocket.GetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.IP), SocketOptionName.wrap(SocketOptionName.MulticastInterface)))));
- return inf != null ? inf : new NetworkInterface(null, -1, new InetAddress[] { new Inet4Address() });
- }
- case SocketOptions.IP_MULTICAST_LOOP:
- return CIL.unbox_int(netSocket.GetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.IP), SocketOptionName.wrap(SocketOptionName.MulticastLoopback))) != 0;
- case SocketOptions.SO_REUSEADDR:
- return CIL.unbox_int(netSocket.GetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Socket), SocketOptionName.wrap(SocketOptionName.ReuseAddress))) != 0;
- 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:
- return SocketUtil.getInetAddressFromIPEndPoint((IPEndPoint)netSocket.get_LocalEndPoint());
- 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");
- }
- }
-
- private void connect0(InetAddress address, int port) throws SocketException
- {
- try
- {
- if (false) throw new cli.System.Net.Sockets.SocketException();
- if (false) throw new cli.System.ObjectDisposedException("");
- IPEndPoint ep = new IPEndPoint(SocketUtil.getAddressFromInetAddress(address), port);
- // NOTE we use async connect to work around the issue that the .NET Socket class disallows sync Connect after the socket has received WSAECONNRESET
- netSocket.EndConnect(netSocket.BeginConnect(ep, null, null));
- netSocket.IOControl(SIO_UDP_CONNRESET, new byte[] { 1 }, null);
- }
- catch (cli.System.Net.Sockets.SocketException x)
- {
- throw new SocketException(x.getMessage());
- }
- catch (cli.System.ObjectDisposedException x1)
- {
- throw new SocketException("Socket is closed");
- }
- }
-
- private void disconnect0(int family)
- {
- try
- {
- if (false) throw new cli.System.Net.Sockets.SocketException();
- if (false) throw new cli.System.ObjectDisposedException("");
- // NOTE we use async connect to work around the issue that the .NET Socket class disallows sync Connect after the socket has received WSAECONNRESET
- netSocket.EndConnect(netSocket.BeginConnect(new IPEndPoint(IPAddress.Any, 0), null, null));
- netSocket.IOControl(SIO_UDP_CONNRESET, new byte[] { 0 }, null);
- }
- catch (cli.System.Net.Sockets.SocketException x)
- {
- }
- catch (cli.System.ObjectDisposedException x1)
- {
- }
- }
-}
diff --git a/openjdk/java/net/PlainSocketImpl.java b/openjdk/java/net/PlainSocketImpl.java
deleted file mode 100644
index 84bc91c0..00000000
--- a/openjdk/java/net/PlainSocketImpl.java
+++ /dev/null
@@ -1,1044 +0,0 @@
-/*
- * Copyright 1995-2006 Sun Microsystems, Inc. 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. Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-package java.net;
-
-import cli.System.Net.IPAddress;
-import cli.System.Net.IPEndPoint;
-import cli.System.Net.Sockets.LingerOption;
-import cli.System.Net.Sockets.SelectMode;
-import cli.System.Net.Sockets.SocketOptionName;
-import cli.System.Net.Sockets.SocketOptionLevel;
-import cli.System.Net.Sockets.SocketFlags;
-import cli.System.Net.Sockets.SocketType;
-import cli.System.Net.Sockets.ProtocolType;
-import cli.System.Net.Sockets.AddressFamily;
-import cli.System.Net.Sockets.SocketShutdown;
-import ikvm.lang.CIL;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.InterruptedIOException;
-import java.io.FileDescriptor;
-import java.io.ByteArrayOutputStream;
-
-import sun.net.ConnectionResetException;
-
-/**
- * Default Socket Implementation. This implementation does
- * not implement any security checks.
- * Note this class should <b>NOT</b> be public.
- *
- * @author Steven B. Byrne
- * @version 1.73, 05/05/07
- */
-@ikvm.lang.Internal
-public class PlainSocketImpl extends SocketImpl
-{
- private cli.System.Net.Sockets.Socket netSocket;
- /* instance variable for SO_TIMEOUT */
- int timeout; // timeout in millisec
- // traffic class
- private int trafficClass;
-
- private boolean shut_rd = false;
- private boolean shut_wr = false;
-
- private SocketInputStream socketInputStream = null;
-
- /* number of threads using the FileDescriptor */
- private int fdUseCount = 0;
-
- /* lock when increment/decrementing fdUseCount */
- private Object fdLock = new Object();
-
- /* indicates a close is pending on the file descriptor */
- private boolean closePending = false;
-
- /* indicates connection reset state */
- private int CONNECTION_NOT_RESET = 0;
- private int CONNECTION_RESET_PENDING = 1;
- private int CONNECTION_RESET = 2;
- private int resetState;
- private Object resetLock = new Object();
-
- /* 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.
- */
- private 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.
- */
- private int lastfd = -1;
-
- /**
- * Constructs an empty instance.
- */
- PlainSocketImpl() { }
-
- /**
- * 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 {
- fd = new FileDescriptor();
- fd1 = new FileDescriptor();
- socketCreate(stream);
- if (socket != null)
- socket.setCreated();
- if (serverSocket != null)
- serverSocket.setCreated();
- }
-
- /**
- * Creates a socket and connects it to the specified port on
- * the specified host.
- * @param host the specified host
- * @param port the specified port
- */
- protected void connect(String host, int port)
- throws UnknownHostException, IOException
- {
- IOException pending = null;
- try {
- InetAddress address = InetAddress.getByName(host);
-
- try {
- connectToAddress(address, port, timeout);
- return;
- } catch (IOException e) {
- pending = e;
- }
- } catch (UnknownHostException e) {
- pending = e;
- }
-
- // everything failed
- close();
- throw pending;
- }
-
- /**
- * Creates a socket and connects it to the specified address on
- * the specified port.
- * @param address the address
- * @param port the specified port
- */
- protected void connect(InetAddress address, int port) throws IOException {
- this.port = port;
- this.address = address;
-
- try {
- connectToAddress(address, port, timeout);
- return;
- } catch (IOException e) {
- // everything failed
- close();
- throw e;
- }
- }
-
- /**
- * Creates a socket and connects it to the specified address on
- * the specified port.
- * @param address the address
- * @param timeout the timeout value in milliseconds, or zero for no timeout.
- * @throws IOException if connection fails
- * @throws IllegalArgumentException if address is null or is a
- * SocketAddress subclass not supported by this socket
- * @since 1.4
- */
- protected void connect(SocketAddress address, int timeout) throws IOException {
- if (address == null || !(address instanceof InetSocketAddress))
- throw new IllegalArgumentException("unsupported address type");
- InetSocketAddress addr = (InetSocketAddress) address;
- if (addr.isUnresolved())
- throw new UnknownHostException(addr.getHostName());
- this.port = addr.getPort();
- this.address = addr.getAddress();
-
- try {
- connectToAddress(this.address, port, timeout);
- return;
- } catch (IOException e) {
- // everything failed
- close();
- throw e;
- }
- }
-
- private void connectToAddress(InetAddress address, int port, int timeout) throws IOException {
- if (address.isAnyLocalAddress()) {
- doConnect(InetAddress.getLocalHost(), port, timeout);
- } else {
- doConnect(address, port, timeout);
- }
- }
-
- public void setOption(int opt, Object val) throws SocketException {
- if (isClosedOrPending()) {
- throw new SocketException("Socket Closed");
- }
- boolean on = true;
- switch (opt) {
- /* check type safety b4 going native. These should never
- * fail, since only java.Socket* has access to
- * PlainSocketImpl.setOption().
- */
- case SO_LINGER:
- if (val == null || (!(val instanceof Integer) && !(val instanceof Boolean)))
- throw new SocketException("Bad parameter for option");
- if (val instanceof Boolean) {
- /* true only if disabling - enabling should be Integer */
- on = false;
- }
- break;
- case SO_TIMEOUT:
- if (val == null || (!(val instanceof Integer)))
- throw new SocketException("Bad parameter for SO_TIMEOUT");
- int tmp = ((Integer) val).intValue();
- if (tmp < 0)
- throw new IllegalArgumentException("timeout < 0");
- timeout = tmp;
- break;
- case IP_TOS:
- if (val == null || !(val instanceof Integer)) {
- throw new SocketException("bad argument for IP_TOS");
- }
- trafficClass = ((Integer)val).intValue();
- break;
- case SO_BINDADDR:
- throw new SocketException("Cannot re-bind socket");
- case TCP_NODELAY:
- if (val == null || !(val instanceof Boolean))
- throw new SocketException("bad parameter for TCP_NODELAY");
- on = ((Boolean)val).booleanValue();
- break;
- case SO_SNDBUF:
- case SO_RCVBUF:
- if (val == null || !(val instanceof Integer) ||
- !(((Integer)val).intValue() > 0)) {
- throw new SocketException("bad parameter for SO_SNDBUF " +
- "or SO_RCVBUF");
- }
- break;
- case SO_KEEPALIVE:
- if (val == null || !(val instanceof Boolean))
- throw new SocketException("bad parameter for SO_KEEPALIVE");
- on = ((Boolean)val).booleanValue();
- break;
- case SO_OOBINLINE:
- if (val == null || !(val instanceof Boolean))
- throw new SocketException("bad parameter for SO_OOBINLINE");
- on = ((Boolean)val).booleanValue();
- break;
- case SO_REUSEADDR:
- if (val == null || !(val instanceof Boolean))
- throw new SocketException("bad parameter for SO_REUSEADDR");
- on = ((Boolean)val).booleanValue();
- break;
- default:
- throw new SocketException("unrecognized TCP option: " + opt);
- }
- socketSetOption(opt, on, val);
- }
- public Object getOption(int opt) throws SocketException {
- if (isClosedOrPending()) {
- throw new SocketException("Socket Closed");
- }
- if (opt == SO_TIMEOUT) {
- return new Integer(timeout);
- }
- int ret = 0;
- /*
- * The native socketGetOption() knows about 3 options.
- * The 32 bit value it returns will be interpreted according
- * to what we're asking. A return of -1 means it understands
- * the option but its turned off. It will raise a SocketException
- * if "opt" isn't one it understands.
- */
-
- switch (opt) {
- case TCP_NODELAY:
- ret = socketGetOption(opt, null);
- return Boolean.valueOf(ret != -1);
- case SO_OOBINLINE:
- ret = socketGetOption(opt, null);
- return Boolean.valueOf(ret != -1);
- case SO_LINGER:
- ret = socketGetOption(opt, null);
- return (ret == -1) ? Boolean.FALSE: (Object)(new Integer(ret));
- case SO_REUSEADDR:
- ret = socketGetOption(opt, null);
- return Boolean.valueOf(ret != -1);
- case SO_BINDADDR:
- if (fd != null && fd1 != null ) {
- /* must be unbound or else bound to anyLocal */
- return anyLocalBoundAddr;
- }
- InetAddressContainer in = new InetAddressContainer();
- ret = socketGetOption(opt, in);
- return in.addr;
- case SO_SNDBUF:
- case SO_RCVBUF:
- ret = socketGetOption(opt, null);
- return new Integer(ret);
- case IP_TOS:
- ret = socketGetOption(opt, null);
- if (ret == -1) { // ipv6 tos
- return new Integer(trafficClass);
- } else {
- return new Integer(ret);
- }
- case SO_KEEPALIVE:
- ret = socketGetOption(opt, null);
- return Boolean.valueOf(ret != -1);
- // should never get here
- default:
- return null;
- }
- }
-
- /**
- * The workhorse of the connection operation. Tries several times to
- * establish a connection to the given <host, port>. If unsuccessful,
- * throws an IOException indicating what went wrong.
- */
-
- private synchronized void doConnect(InetAddress address, int port, int timeout) throws IOException {
- try {
- FileDescriptor fd = acquireFD();
- try {
- socketConnect(address, port, timeout);
- // If we have a ref. to the Socket, then sets the flags
- // created, bound & connected to true.
- // This is normally done in Socket.connect() but some
- // subclasses of Socket may call impl.connect() directly!
- if (socket != null) {
- socket.setBound();
- socket.setConnected();
- }
- } finally {
- releaseFD();
- }
- } catch (IOException e) {
- close();
- 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
- {
- socketBind(address, lport);
- if (socket != null)
- socket.setBound();
- if (serverSocket != null)
- serverSocket.setBound();
- if (address.isAnyLocalAddress()) {
- anyLocalBoundAddr = address;
- }
- }
-
- /**
- * Listens, for a specified amount of time, for connections.
- * @param count the amount of time to listen for connections
- */
- protected synchronized void listen(int count) throws IOException {
- socketListen(count);
- }
-
- /**
- * Accepts connections.
- * @param s the connection
- */
- protected synchronized void accept(SocketImpl s) throws IOException {
- FileDescriptor fd = acquireFD();
- try {
- socketAccept(s);
- } finally {
- releaseFD();
- }
- }
-
- void setFileDescriptor(FileDescriptor fd) {
- this.netSocket = fd.getSocket();
- }
-
- void setAddress(InetAddress address) {
- this.address = address;
- }
-
- void setPort(int port) {
- this.port = port;
- }
-
- void setLocalPort(int localPort) {
- this.localport = localPort;
- }
-
- /**
- * Gets an InputStream for this socket.
- */
- protected synchronized InputStream getInputStream() throws IOException {
- if (isClosedOrPending()) {
- throw new IOException("Socket Closed");
- }
- if (shut_rd) {
- throw new IOException("Socket input is shutdown");
- }
- if (socketInputStream == null) {
- socketInputStream = new SocketInputStream(this);
- }
- return socketInputStream;
- }
-
- void setInputStream(SocketInputStream in) {
- socketInputStream = in;
- }
-
- /**
- * Gets an OutputStream for this socket.
- */
- protected synchronized OutputStream getOutputStream() throws IOException {
- if (isClosedOrPending()) {
- throw new IOException("Socket Closed");
- }
- if (shut_wr) {
- throw new IOException("Socket output is shutdown");
- }
- return new SocketOutputStream(this);
- }
-
- /**
- * Returns the number of bytes that can be read without blocking.
- */
- protected synchronized int available() throws IOException {
- if (isClosedOrPending()) {
- throw new IOException("Stream closed.");
- }
-
- /*
- * If connection has been reset then return 0 to indicate
- * there are no buffered bytes.
- */
- if (isConnectionReset()) {
- return 0;
- }
-
- /*
- * If no bytes available and we were previously notified
- * of a connection reset then we move to the reset state.
- *
- * If are notified of a connection reset then check
- * again if there are bytes buffered on the socket.
- */
- int n = 0;
- try {
- n = socketAvailable();
- if (n == 0 && isConnectionResetPending()) {
- setConnectionReset();
- }
- } catch (ConnectionResetException exc1) {
- setConnectionResetPending();
- try {
- n = socketAvailable();
- if (n == 0) {
- setConnectionReset();
- }
- } catch (ConnectionResetException exc2) {
- }
- }
- return n;
- }
-
- /**
- * Closes the socket.
- */
- protected void close() throws IOException {
- synchronized(fdLock) {
- if (fd != null || fd1 != null) {
- if (fdUseCount == 0) {
- if (closePending) {
- return;
- }
- closePending = true;
- /*
- * We close the FileDescriptor in two-steps - first the
- * "pre-close" which closes the socket but doesn't
- * release the underlying file descriptor. This operation
- * may be lengthy due to untransmitted data and a long
- * linger interval. Once the pre-close is done we do the
- * actual socket to release the fd.
- */
- try {
- socketPreClose();
- } finally {
- 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--;
- socketPreClose();
- }
- }
- }
- }
- }
-
- void reset() throws IOException {
- if (fd != null || fd1 != null) {
- socketClose();
- }
- fd = null;
- fd1 = null;
- super.reset();
- }
-
-
- /**
- * Shutdown read-half of the socket connection;
- */
- protected void shutdownInput() throws IOException {
- if (fd != null) {
- socketShutdown(SHUT_RD);
- if (socketInputStream != null) {
- socketInputStream.setEOF(true);
- }
- shut_rd = true;
- }
- }
-
- /**
- * Shutdown write-half of the socket connection;
- */
- protected void shutdownOutput() throws IOException {
- if (fd != null) {
- socketShutdown(SHUT_WR);
- shut_wr = true;
- }
- }
-
- protected boolean supportsUrgentData () {
- return true;
- }
-
- protected void sendUrgentData (int data) throws IOException {
- if (fd == null) {
- throw new IOException("Socket Closed");
- }
- socketSendUrgentData (data);
- }
-
- /*
- * "Acquires" and returns the FileDescriptor for this impl
- *
- * A corresponding releaseFD is required to "release" the
- * FileDescriptor.
- */
- public final FileDescriptor acquireFD() {
- synchronized (fdLock) {
- fdUseCount++;
- return fd;
- }
- }
-
- /*
- * "Release" the FileDescriptor for this impl.
- *
- * If the use count goes to -1 then the socket is closed.
- */
- public final void releaseFD() {
- synchronized (fdLock) {
- fdUseCount--;
- if (fdUseCount == -1) {
- if (fd != null) {
- try {
- socketClose();
- } catch (IOException e) {
- } finally {
- fd = null;
- }
- }
- }
- }
- }
-
- public boolean isConnectionReset() {
- synchronized (resetLock) {
- return (resetState == CONNECTION_RESET);
- }
- }
-
- public boolean isConnectionResetPending() {
- synchronized (resetLock) {
- return (resetState == CONNECTION_RESET_PENDING);
- }
- }
-
- public void setConnectionReset() {
- synchronized (resetLock) {
- resetState = CONNECTION_RESET;
- }
- }
-
- public void setConnectionResetPending() {
- synchronized (resetLock) {
- if (resetState == CONNECTION_NOT_RESET) {
- resetState = CONNECTION_RESET_PENDING;
- }
- }
-
- }
-
- /*
- * Return true if already closed or close is pending
- */
- 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;
- }
- }
- }
-
- /*
- * Return the current value of SO_TIMEOUT
- */
- public int getTimeout() {
- return timeout;
- }
-
- /*
- * "Pre-close" a socket by dup'ing the file descriptor - this enables
- * the socket to be closed without releasing the file descriptor.
- */
- private void socketPreClose() throws IOException {
- socketClose0(true);
- }
-
- /*
- * Close the socket (and release the file descriptor).
- */
- private void socketClose() throws IOException {
- socketClose0(false);
- }
-
- private void socketCreate(boolean stream) throws IOException
- {
- try
- {
- if (false) throw new cli.System.Net.Sockets.SocketException();
- if (false) throw new cli.System.ObjectDisposedException("");
- if (stream)
- {
- netSocket = new cli.System.Net.Sockets.Socket(AddressFamily.wrap(AddressFamily.InterNetwork), SocketType.wrap(SocketType.Stream), ProtocolType.wrap(ProtocolType.Tcp));
- }
- else
- {
- netSocket = new cli.System.Net.Sockets.Socket(AddressFamily.wrap(AddressFamily.InterNetwork), SocketType.wrap(SocketType.Dgram), ProtocolType.wrap(ProtocolType.Udp));
- }
- fd1 = null;
- }
- catch (cli.System.Net.Sockets.SocketException x)
- {
- throw SocketUtil.convertSocketExceptionToIOException(x);
- }
- catch (cli.System.ObjectDisposedException x1)
- {
- throw new SocketException("Socket is closed");
- }
- }
-
- private void socketConnect(InetAddress address, int port, int timeout) throws IOException
- {
- try
- {
- if (false) throw new cli.System.Net.Sockets.SocketException();
- if (false) throw new cli.System.ObjectDisposedException("");
- IPEndPoint ep = new IPEndPoint(SocketUtil.getAddressFromInetAddress(address), port);
- if (timeout <= 0)
- {
- netSocket.Connect(ep);
- }
- else
- {
- cli.System.IAsyncResult result = netSocket.BeginConnect(ep, null, null);
- if (!result.get_AsyncWaitHandle().WaitOne(timeout, false))
- {
- netSocket.Close();
- throw new SocketTimeoutException();
- }
- netSocket.EndConnect(result);
- }
- this.address = address;
- this.port = port;
- if (this.localport == 0)
- {
- this.localport = ((IPEndPoint)netSocket.get_LocalEndPoint()).get_Port();
- }
- }
- catch (cli.System.Net.Sockets.SocketException x)
- {
- throw new ConnectException(x.getMessage());
- }
- catch (cli.System.ObjectDisposedException x1)
- {
- throw new SocketException("Socket is closed");
- }
- }
-
- private void socketBind(InetAddress address, int localport) throws IOException
- {
- try
- {
- if (false) throw new cli.System.Net.Sockets.SocketException();
- if (false) throw new cli.System.ObjectDisposedException("");
- netSocket.Bind(new IPEndPoint(SocketUtil.getAddressFromInetAddress(address), localport));
- this.address = address;
- if (localport == 0)
- {
- this.localport = ((IPEndPoint)netSocket.get_LocalEndPoint()).get_Port();
- }
- else
- {
- this.localport = localport;
- }
- }
- catch (cli.System.Net.Sockets.SocketException x)
- {
- throw new BindException(x.getMessage());
- }
- catch (cli.System.ObjectDisposedException x1)
- {
- throw new SocketException("Socket is closed");
- }
- }
-
- private void socketListen(int count) throws IOException
- {
- try
- {
- if (false) throw new cli.System.Net.Sockets.SocketException();
- if (false) throw new cli.System.ObjectDisposedException("");
- netSocket.Listen(count);
- }
- catch (cli.System.Net.Sockets.SocketException x)
- {
- throw SocketUtil.convertSocketExceptionToIOException(x);
- }
- catch (cli.System.ObjectDisposedException x1)
- {
- throw new SocketException("Socket is closed");
- }
- }
-
- private void socketAccept(SocketImpl s) throws IOException
- {
- PlainSocketImpl impl = (PlainSocketImpl)s;
- try
- {
- if (false) throw new cli.System.Net.Sockets.SocketException();
- if (false) throw new cli.System.ObjectDisposedException("");
- if (timeout > 0 && !netSocket.Poll(Math.min(timeout, Integer.MAX_VALUE / 1000) * 1000,
- SelectMode.wrap(SelectMode.SelectRead)))
- {
- throw new SocketTimeoutException("Accept timed out");
- }
- cli.System.Net.Sockets.Socket accept = netSocket.Accept();
- impl.netSocket = accept;
- IPEndPoint remoteEndPoint = ((IPEndPoint)accept.get_RemoteEndPoint());
- impl.address = SocketUtil.getInetAddressFromIPEndPoint(remoteEndPoint);
- impl.port = remoteEndPoint.get_Port();
- impl.localport = ((IPEndPoint)accept.get_LocalEndPoint()).get_Port();
- }
- catch (cli.System.Net.Sockets.SocketException x)
- {
- throw SocketUtil.convertSocketExceptionToIOException(x);
- }
- catch (cli.System.ObjectDisposedException x1)
- {
- // TODO we may have to throw java.io.InterruptedIOException here
- throw new SocketException("Socket is closed");
- }
- }
-
- private int socketAvailable() throws IOException
- {
- try
- {
- if (false) throw new cli.System.Net.Sockets.SocketException();
- if (false) throw new cli.System.ObjectDisposedException("");
- return netSocket.get_Available();
- }
- catch (cli.System.Net.Sockets.SocketException x)
- {
- throw SocketUtil.convertSocketExceptionToIOException(x);
- }
- catch (cli.System.ObjectDisposedException x1)
- {
- throw new SocketException("Socket is closed");
- }
- }
-
- private void socketClose0(boolean useDeferredClose) throws IOException
- {
- try
- {
- if (false) throw new cli.System.Net.Sockets.SocketException();
- if (false) throw new cli.System.ObjectDisposedException("");
- if (netSocket != null)
- {
- netSocket.Close();
- }
- }
- catch (cli.System.Net.Sockets.SocketException x)
- {
- throw SocketUtil.convertSocketExceptionToIOException(x);
- }
- catch (cli.System.ObjectDisposedException x1)
- {
- throw new SocketException("Socket is closed");
- }
- }
-
- private void socketShutdown(int howto) throws IOException
- {
- try
- {
- if (false) throw new cli.System.Net.Sockets.SocketException();
- if (false) throw new cli.System.ObjectDisposedException("");
- netSocket.Shutdown(SocketShutdown.wrap(howto == SHUT_RD ? SocketShutdown.Receive : SocketShutdown.Send));
- }
- catch (cli.System.Net.Sockets.SocketException x)
- {
- throw SocketUtil.convertSocketExceptionToIOException(x);
- }
- catch (cli.System.ObjectDisposedException x1)
- {
- throw new SocketException("Socket is closed");
- }
- }
-
- private void socketSetOption(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_LINGER:
- if (on)
- {
- netSocket.SetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Socket), SocketOptionName.wrap(SocketOptionName.Linger), new LingerOption(true, ((Integer)value).intValue()));
- }
- else
- {
- netSocket.SetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Socket), SocketOptionName.wrap(SocketOptionName.Linger), new LingerOption(false, 0));
- }
- break;
- case SocketOptions.SO_TIMEOUT:
- if (serverSocket == null)
- {
- netSocket.SetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Socket), SocketOptionName.wrap(SocketOptionName.ReceiveTimeout), timeout <= 5000 ? 0 : timeout);
- }
- break;
- case SocketOptions.TCP_NODELAY:
- netSocket.SetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Tcp), SocketOptionName.wrap(SocketOptionName.NoDelay), on ? 1 : 0);
- break;
- case SocketOptions.SO_KEEPALIVE:
- netSocket.SetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Socket), SocketOptionName.wrap(SocketOptionName.KeepAlive), on ? 1 : 0);
- break;
- case SocketOptions.SO_OOBINLINE:
- netSocket.SetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Socket), SocketOptionName.wrap(SocketOptionName.OutOfBandInline), on ? 1 : 0);
- break;
- default:
- SocketUtil.setCommonSocketOption(netSocket, cmd, on, value);
- break;
- }
- }
- catch (cli.System.Net.Sockets.SocketException x)
- {
- throw new SocketException(x.getMessage());
- }
- catch (cli.System.ObjectDisposedException x1)
- {
- throw new SocketException("Socket is closed");
- }
- }
-
- private int socketGetOption(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.TCP_NODELAY:
- return CIL.unbox_int(netSocket.GetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Tcp), SocketOptionName.wrap(SocketOptionName.NoDelay))) == 0 ? -1 : 1;
- case SocketOptions.SO_KEEPALIVE:
- return CIL.unbox_int(netSocket.GetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Socket), SocketOptionName.wrap(SocketOptionName.KeepAlive))) == 0 ? -1 : 1;
- case SocketOptions.SO_LINGER:
- {
- LingerOption linger = (LingerOption)netSocket.GetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Socket), SocketOptionName.wrap(SocketOptionName.Linger));
- if (linger.get_Enabled())
- {
- return linger.get_LingerTime();
- }
- return -1;
- }
- case SocketOptions.SO_OOBINLINE:
- return CIL.unbox_int(netSocket.GetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Socket), SocketOptionName.wrap(SocketOptionName.OutOfBandInline))) == 0 ? -1 : 1;
- default:
- return SocketUtil.getCommonSocketOption(netSocket, opt, iaContainerObj);
- }
- }
- catch (cli.System.Net.Sockets.SocketException x)
- {
- throw new SocketException(x.getMessage());
- }
- catch (cli.System.ObjectDisposedException x1)
- {
- throw new SocketException("Socket is closed");
- }
- }
-
- private void socketSendUrgentData(int data) throws IOException
- {
- try
- {
- if (false) throw new cli.System.Net.Sockets.SocketException();
- if (false) throw new cli.System.ObjectDisposedException("");
- byte[] oob = { (byte)data };
- netSocket.Send(oob, SocketFlags.wrap(SocketFlags.OutOfBand));
- }
- catch (cli.System.Net.Sockets.SocketException x)
- {
- throw SocketUtil.convertSocketExceptionToIOException(x);
- }
- catch (cli.System.ObjectDisposedException x1)
- {
- throw new SocketException("Socket is closed");
- }
- }
-
- // used by SocketInputStream
- int read(byte[] buf, int offset, int len, int timeout) throws IOException
- {
- try
- {
- if (false) throw new cli.System.Net.Sockets.SocketException();
- if (false) throw new cli.System.ObjectDisposedException("");
- if (timeout > 0 && !netSocket.Poll(Math.min(timeout, Integer.MAX_VALUE / 1000) * 1000,
- SelectMode.wrap(SelectMode.SelectRead)))
- {
- throw new SocketTimeoutException();
- }
- int read = netSocket.Receive(buf, offset, len, SocketFlags.wrap(SocketFlags.None));
- return read == 0 ? -1 : read;
- }
- catch (cli.System.Net.Sockets.SocketException x)
- {
- if (x.get_ErrorCode() == SocketUtil.WSAESHUTDOWN)
- {
- // the socket was shutdown, so we have to return EOF
- return -1;
- }
- else if (x.get_ErrorCode() == SocketUtil.WSAEWOULDBLOCK)
- {
- // nothing to read and would block
- return 0;
- }
- throw SocketUtil.convertSocketExceptionToIOException(x);
- }
- catch (cli.System.ObjectDisposedException x1)
- {
- throw new SocketException("Socket is closed");
- }
- }
-
- // used by SocketOutputStream
- int write(byte[] buf, int offset, int len) throws IOException
- {
- try
- {
- if (false) throw new cli.System.Net.Sockets.SocketException();
- if (false) throw new cli.System.ObjectDisposedException("");
- return netSocket.Send(buf, offset, len, SocketFlags.wrap(SocketFlags.None));
- }
- catch (cli.System.Net.Sockets.SocketException x)
- {
- throw SocketUtil.convertSocketExceptionToIOException(x);
- }
- catch (cli.System.ObjectDisposedException x1)
- {
- throw new SocketException("Socket is closed");
- }
- }
-
- public final static int SHUT_RD = 0;
- public final static int SHUT_WR = 1;
-}
-
-class InetAddressContainer {
- InetAddress addr;
-}
diff --git a/openjdk/java/net/SocketInputStream.java b/openjdk/java/net/SocketInputStream.java
index 68824313..0346864b 100644
--- a/openjdk/java/net/SocketInputStream.java
+++ b/openjdk/java/net/SocketInputStream.java
@@ -29,6 +29,8 @@ 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.net.ConnectionResetException;
@@ -39,12 +41,13 @@ import sun.net.ConnectionResetException;
*
* @author Jonathan Payne
* @author Arthur van Hoff
+ * @author Jeroen Frijters
*/
class SocketInputStream extends FileInputStream
{
private boolean eof;
- private PlainSocketImpl impl = null;
+ private AbstractPlainSocketImpl impl = null;
private byte temp[];
private Socket socket = null;
@@ -54,7 +57,7 @@ class SocketInputStream extends FileInputStream
* that the fd will not be closed.
* @param impl the implemented socket input stream
*/
- SocketInputStream(PlainSocketImpl impl) throws IOException {
+ SocketInputStream(AbstractPlainSocketImpl impl) throws IOException {
super(impl.getFileDescriptor());
this.impl = impl;
socket = impl.getSocket();
@@ -88,9 +91,69 @@ class SocketInputStream extends FileInputStream
* returned when the end of the stream is reached.
* @exception IOException If an I/O error has occurred.
*/
- private int socketRead0(FileDescriptor fd, byte b[], int off, int len, int timeout) throws IOException
+ private int socketRead0(FileDescriptor fdObj, byte bufP[], int off, int len, int timeout) throws IOException
{
- return impl.read(b, off, len, timeout);
+ // [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, 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;
}
/**
diff --git a/openjdk/java/net/SocketOutputStream.java b/openjdk/java/net/SocketOutputStream.java
index 11e178e2..a1295f21 100644
--- a/openjdk/java/net/SocketOutputStream.java
+++ b/openjdk/java/net/SocketOutputStream.java
@@ -29,6 +29,8 @@ 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.*;
/**
* This stream extends FileOutputStream to implement a
@@ -37,10 +39,11 @@ import java.nio.channels.FileChannel;
*
* @author Jonathan Payne
* @author Arthur van Hoff
+ * @author Jeroen Frijters
*/
class SocketOutputStream extends FileOutputStream
{
- private PlainSocketImpl impl = null;
+ private AbstractPlainSocketImpl impl = null;
private byte temp[] = new byte[1];
private Socket socket = null;
@@ -50,7 +53,7 @@ class SocketOutputStream extends FileOutputStream
* that the fd will not be closed.
* @param impl the socket output stream inplemented
*/
- SocketOutputStream(PlainSocketImpl impl) throws IOException {
+ SocketOutputStream(AbstractPlainSocketImpl impl) throws IOException {
super(impl.getFileDescriptor());
this.impl = impl;
socket = impl.getSocket();
@@ -80,9 +83,80 @@ class SocketOutputStream extends FileOutputStream
* @param len the number of bytes that are written
* @exception IOException If an I/O error has occurred.
*/
- private void socketWrite0(FileDescriptor fd, byte[] b, int off, int len) throws IOException
+ private void socketWrite0(FileDescriptor fdObj, byte[] data, int off, int len) throws IOException
{
- impl.write(b, off, len);
+ // [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;
+ }
}
/**
diff --git a/openjdk/java/net/TwoStacksPlainDatagramSocketImpl.java b/openjdk/java/net/TwoStacksPlainDatagramSocketImpl.java
index 8a4fd5df..bb6374f4 100644
--- a/openjdk/java/net/TwoStacksPlainDatagramSocketImpl.java
+++ b/openjdk/java/net/TwoStacksPlainDatagramSocketImpl.java
@@ -37,12 +37,13 @@ import java.io.FileDescriptor;
* during socket creation.
*
* @author Chris Hegarty
+ * @author Jeroen Frijters
*/
class TwoStacksPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl
{
/* Used for IPv6 on Windows only */
- private FileDescriptor fd1;
+ FileDescriptor fd1;
/*
* Needed for ipv6 on windows because we need to know
@@ -53,17 +54,13 @@ class TwoStacksPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl
*/
private InetAddress anyLocalBoundAddr=null;
- private int fduse=-1; /* saved between peek() and receive() calls */
+ 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
*/
- private int lastfd=-1;
-
- static {
- init();
- }
+ cli.System.Net.Sockets.Socket lastfd=null;
protected synchronized void create() throws SocketException {
fd1 = new FileDescriptor();
@@ -83,7 +80,7 @@ class TwoStacksPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl
try {
receive0(p);
} finally {
- fduse = -1;
+ fduse = null;
}
}
@@ -115,47 +112,121 @@ class TwoStacksPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl
/* Native methods */
- protected synchronized native void bind0(int lport, InetAddress laddr)
- throws SocketException;
+ protected synchronized void bind0(int lport, InetAddress laddr) throws SocketException {
+ ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
+ TwoStacksPlainDatagramSocketImpl_c.bind0(env, this, lport, laddr);
+ 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 native void send(DatagramPacket p) throws IOException;
+ 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 native int peek(InetAddress i) throws IOException;
+ 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 native int peekData(DatagramPacket p) throws IOException;
+ 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 synchronized native void receive0(DatagramPacket p)
- throws IOException;
+ 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 native void setTimeToLive(int ttl) throws IOException;
+ 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 native int getTimeToLive() throws IOException;
+ 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 native void setTTL(byte ttl) throws IOException;
+ 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 native byte getTTL() throws IOException;
+ 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 native void join(InetAddress inetaddr, NetworkInterface netIf)
- throws IOException;
+ 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 native void leave(InetAddress inetaddr, NetworkInterface netIf)
- throws IOException;
+ protected void datagramSocketCreate() throws SocketException {
+ ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
+ TwoStacksPlainDatagramSocketImpl_c.datagramSocketCreate(env, this);
+ env.ThrowPendingException();
+ }
- protected native void datagramSocketCreate() throws SocketException;
+ protected void datagramSocketClose() {
+ TwoStacksPlainDatagramSocketImpl_c.datagramSocketClose(this);
+ }
- protected native void datagramSocketClose();
+ protected void socketSetOption(int opt, Object val) throws SocketException {
+ ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
+ TwoStacksPlainDatagramSocketImpl_c.socketSetOption(env, this, opt, val);
+ env.ThrowPendingException();
+ }
- protected native void socketSetOption(int opt, Object val)
- throws SocketException;
+ 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 native Object socketGetOption(int opt) throws SocketException;
+ protected void connect0(InetAddress address, int port) throws SocketException {
+ if (runningOnMono) {
+ // 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 native void connect0(InetAddress address, int port) throws SocketException;
+ protected void disconnect0(int family) {
+ TwoStacksPlainDatagramSocketImpl_c.disconnect0(this, family);
+ }
- protected native void disconnect0(int family);
+ private static final boolean runningOnMono = cli.System.Type.GetType("Mono.Runtime") != null;
+}
- /**
- * Perform class load-time initializations.
- */
- private native static void init();
+// we don't support a dual-stack approach yet, so we simply make it an alias for the two-stacks approach
+class DualStackPlainDatagramSocketImpl extends TwoStacksPlainDatagramSocketImpl {
+ // we need this method, because DatagramSocket uses reflection to check for this methods existance
+ protected int peekData(DatagramPacket p) throws IOException {
+ return super.peekData(p);
+ }
}
diff --git a/openjdk/java/net/TwoStacksPlainDatagramSocketImpl_c.java b/openjdk/java/net/TwoStacksPlainDatagramSocketImpl_c.java
index 8e73b352..1564c5e7 100644
--- a/openjdk/java/net/TwoStacksPlainDatagramSocketImpl_c.java
+++ b/openjdk/java/net/TwoStacksPlainDatagramSocketImpl_c.java
@@ -22,6 +22,32 @@
* CA 95054 USA or visit www.sun.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>
@@ -50,10 +76,17 @@
#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;
@@ -69,11 +102,12 @@ static jclass ia4_clazz;
static jmethodID ia4_ctor;
static CRITICAL_SECTION sizeCheckLock;
+*/
/* Windows OS version is XP or better */
-static int xp_or_later = 0;
+static final boolean xp_or_later = true;
/* Windows OS version is Windows 2000 or better */
-static int w2k_or_later = 0;
+//static int w2k_or_later = 0;
/*
* Notes about UDP/IPV6 on Windows (XP and 2003 server):
@@ -86,6 +120,7 @@ static int w2k_or_later = 0;
/*
* Returns a java.lang.Integer based on 'i'
*/
+/*
jobject createInteger(JNIEnv *env, int i) {
static jclass i_class;
static jmethodID i_ctrID;
@@ -102,10 +137,12 @@ jobject createInteger(JNIEnv *env, int i) {
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;
@@ -122,24 +159,25 @@ jobject createBoolean(JNIEnv *env, int b) {
return( (*env)->NewObject(env, b_class, b_ctrID, (jboolean)(b!=0)) );
}
+*/
-static int getFD(JNIEnv *env, jobject this) {
- jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
+static cli.System.Net.Sockets.Socket getFD(JNIEnv env, TwoStacksPlainDatagramSocketImpl _this) {
+ FileDescriptor fdObj = _this.fd;
if (fdObj == NULL) {
- return -1;
+ return null;
}
- return (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+ return fdObj.getSocket();
}
-static int getFD1(JNIEnv *env, jobject this) {
- jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fd1ID);
+static cli.System.Net.Sockets.Socket getFD1(JNIEnv env, TwoStacksPlainDatagramSocketImpl _this) {
+ FileDescriptor fdObj = _this.fd1;
if (fdObj == NULL) {
- return -1;
+ return null;
}
- return (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+ return fdObj.getSocket();
}
/*
@@ -160,6 +198,7 @@ static int getFD1(JNIEnv *env, jobject this) {
* another machine then WSAEINVAL is returned.
*
*/
+/*
jboolean exceedSizeLimit(JNIEnv *env, jint fd, jint addr, jint size)
{
#define DEFAULT_MSG_SIZE 65527
@@ -167,7 +206,7 @@ jboolean exceedSizeLimit(JNIEnv *env, jint fd, jint addr, jint size)
static jboolean is95or98;
static int maxmsg;
- typedef struct _netaddr { /* Windows 95/98 only */
+ typedef struct _netaddr { /* Windows 95/98 only *-/
unsigned long addr;
struct _netaddr *next;
} netaddr;
@@ -179,12 +218,12 @@ jboolean exceedSizeLimit(JNIEnv *env, jint fd, jint addr, jint size)
* 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 */
+ /* another thread got there first *-/
LeaveCriticalSection(&sizeCheckLock);
} else {
@@ -193,7 +232,7 @@ jboolean exceedSizeLimit(JNIEnv *env, jint fd, jint addr, jint size)
/*
* Step 1: Determine which OS this is.
- */
+ *-/
ver.dwOSVersionInfoSize = sizeof(ver);
GetVersionEx(&ver);
@@ -210,7 +249,7 @@ jboolean exceedSizeLimit(JNIEnv *env, jint fd, jint addr, jint size)
* 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;
@@ -220,7 +259,7 @@ jboolean exceedSizeLimit(JNIEnv *env, jint fd, jint addr, jint size)
* Step 3: On Windows 95/98 then enumerate the IP addresses on
* this machine. This is necesary 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;
@@ -256,7 +295,7 @@ jboolean exceedSizeLimit(JNIEnv *env, jint fd, jint addr, jint size)
/*
* Step 4: initialization is done so set flag and unlock cs
- */
+ *-/
initDone = JNI_TRUE;
LeaveCriticalSection(&sizeCheckLock);
}
@@ -271,18 +310,18 @@ jboolean exceedSizeLimit(JNIEnv *env, jint fd, jint addr, jint size)
* (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) */
+ *-/
+ if (size > maxmsg) { /* step (a) *-/
return JNI_TRUE;
}
- if (!is95or98) { /* step (b) */
+ if (!is95or98) { /* step (b) *-/
return JNI_FALSE;
}
- if (size <= 12280) { /* step (c) */
+ if (size <= 12280) { /* step (c) *-/
return JNI_FALSE;
}
- /* step (d) */
+ /* step (d) *-/
if ((addr & 0x7f000000) == 0x7f000000) {
return JNI_TRUE;
@@ -296,26 +335,14 @@ jboolean exceedSizeLimit(JNIEnv *env, jint fd, jint addr, jint size)
}
return JNI_FALSE;
}
+*/
/*
* Return JNI_TRUE if this Windows edition supports ICMP Port Unreachable
*/
-__inline static jboolean supportPortUnreachable() {
- static jboolean initDone;
- static jboolean portUnreachableSupported;
-
- if (!initDone) {
- OSVERSIONINFO ver;
- ver.dwOSVersionInfoSize = sizeof(ver);
- GetVersionEx(&ver);
- if (ver.dwPlatformId == VER_PLATFORM_WIN32_NT && ver.dwMajorVersion >= 5) {
- portUnreachableSupported = JNI_TRUE;
- } else {
- portUnreachableSupported = JNI_FALSE;
- }
- initDone = JNI_TRUE;
- }
- return portUnreachableSupported;
+static boolean supportPortUnreachable() {
+ // we don't support anything pre-Win2K anyway
+ return true;
}
/*
@@ -325,14 +352,13 @@ __inline static jboolean supportPortUnreachable() {
* behaviour whereby receiving a "connection reset" status resets the
* socket.
*/
-static jboolean purgeOutstandingICMP(JNIEnv *env, jobject this, jint fd)
+static boolean purgeOutstandingICMP(cli.System.Net.Sockets.Socket fd)
{
- jboolean got_icmp = JNI_FALSE;
- char buf[1];
- fd_set tbl;
- struct timeval t = { 0, 0 };
- struct sockaddr_in rmtaddr;
- int addrlen = sizeof(rmtaddr);
+ boolean got_icmp = false;
+ byte[] buf = new byte[1];
+ fd_set tbl = new fd_set();
+ timeval t = new timeval();
+ SOCKETADDRESS rmtaddr = null;
/*
* A no-op if this OS doesn't support it.
@@ -345,14 +371,14 @@ static jboolean purgeOutstandingICMP(JNIEnv *env, jobject this, jint fd)
* Peek at the queue to see if there is an ICMP port unreachable. If there
* is then receive it.
*/
- FD_ZERO(&tbl);
- FD_SET(fd, &tbl);
- while(1) {
- if (select(/*ignored*/fd+1, &tbl, 0, 0, &t) <= 0) {
+ FD_ZERO(tbl);
+ FD_SET(fd, tbl);
+ while(true) {
+ if (select(tbl, null, null, t) <= 0) {
break;
}
if (recvfrom(fd, buf, 1, MSG_PEEK,
- (struct sockaddr *)&rmtaddr, &addrlen) != JVM_IO_ERR) {
+ rmtaddr) != JVM_IO_ERR) {
break;
}
if (WSAGetLastError() != WSAECONNRESET) {
@@ -360,7 +386,7 @@ static jboolean purgeOutstandingICMP(JNIEnv *env, jobject this, jint fd)
break;
}
- recvfrom(fd, buf, 1, 0, (struct sockaddr *)&rmtaddr, &addrlen);
+ recvfrom(fd, buf, 1, 0, rmtaddr);
got_icmp = JNI_TRUE;
}
@@ -373,6 +399,7 @@ static jboolean purgeOutstandingICMP(JNIEnv *env, jobject this, jint fd)
* Method: init
* Signature: ()V
*/
+/*
JNIEXPORT void JNICALL
Java_java_net_TwoStacksPlainDatagramSocketImpl_init(JNIEnv *env, jclass cls) {
@@ -385,7 +412,7 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_init(JNIEnv *env, jclass cls) {
xp_or_later = (ver.dwPlatformId == VER_PLATFORM_WIN32_NT) && (version >= 51);
w2k_or_later = (ver.dwPlatformId == VER_PLATFORM_WIN32_NT) && (version >= 50);
- /* get fieldIDs */
+ /* 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;");
@@ -418,72 +445,75 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_init(JNIEnv *env, jclass cls) {
InitializeCriticalSection(&sizeCheckLock);
}
+*/
-JNIEXPORT void JNICALL
-Java_java_net_TwoStacksPlainDatagramSocketImpl_bind0(JNIEnv *env, jobject this,
- jint port, jobject addressObj) {
- jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
- jobject fd1Obj = (*env)->GetObjectField(env, this, pdsi_fd1ID);
+static void bind0(JNIEnv env, TwoStacksPlainDatagramSocketImpl _this, int port, InetAddress addressObj) {
+ FileDescriptor fdObj = _this.fd;
+ FileDescriptor fd1Obj = _this.fd1;
- int fd, fd1, family;
- int ipv6_supported = ipv6_available();
+ cli.System.Net.Sockets.Socket fd = null;
+ cli.System.Net.Sockets.Socket fd1 = null;
+ int family;
+ boolean ipv6_supported = ipv6_available();
SOCKETADDRESS lcladdr;
- int lcladdrlen;
- int address;
+ lcladdr = new SOCKETADDRESS();
- family = (*env)->GetIntField(env, addressObj, ia_familyID);
+ if (IS_NULL(addressObj)) {
+ JNU_ThrowNullPointerException(env, "argument address");
+ return;
+ }
+
+ family = addressObj.family;
if (family == IPv6 && !ipv6_supported) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+ 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");
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", "socket closed");
return;
} else {
- fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+ fd = fdObj.getSocket();
if (ipv6_supported) {
- fd1 = (*env)->GetIntField(env, fd1Obj, IO_fd_fdID);
+ fd1 = fd1Obj.getSocket();
}
}
if (IS_NULL(addressObj)) {
JNU_ThrowNullPointerException(env, "argument address");
return;
- } else {
- address = (*env)->GetIntField(env, addressObj, ia_addressID);
}
- if (NET_InetAddressToSockaddr(env, addressObj, port, (struct sockaddr *)&lcladdr, &lcladdrlen, JNI_FALSE) != 0) {
+ if (NET_InetAddressToSockaddr(env, addressObj, port, lcladdr, JNI_FALSE) != 0) {
return;
}
if (ipv6_supported) {
- struct ipv6bind v6bind;
- v6bind.addr = &lcladdr;
+ ipv6bind v6bind = new ipv6bind();
+ v6bind.addr = lcladdr;
v6bind.ipv4_fd = fd;
v6bind.ipv6_fd = fd1;
- if (NET_BindV6(&v6bind) != -1) {
+ if (NET_BindV6(v6bind) != -1) {
/* check if the fds have changed */
if (v6bind.ipv4_fd != fd) {
fd = v6bind.ipv4_fd;
- if (fd == -1) {
+ if (fd == null) {
/* socket is closed. */
- (*env)->SetObjectField(env, this, pdsi_fdID, NULL);
+ _this.fd = null;
} else {
/* socket was re-created */
- (*env)->SetIntField(env, fdObj, IO_fd_fdID, fd);
+ fdObj.setSocket(fd);
}
}
if (v6bind.ipv6_fd != fd1) {
fd1 = v6bind.ipv6_fd;
- if (fd1 == -1) {
+ if (fd1 == null) {
/* socket is closed. */
- (*env)->SetObjectField(env, this, pdsi_fd1ID, NULL);
+ _this.fd1 = null;
} else {
/* socket was re-created */
- (*env)->SetIntField(env, fd1Obj, IO_fd_fdID, fd1);
+ fd1Obj.setSocket(fd1);
}
}
} else {
@@ -491,7 +521,7 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_bind0(JNIEnv *env, jobject this,
return;
}
} else {
- if (bind(fd, (struct sockaddr *)&lcladdr, lcladdrlen) == -1) {
+ if (bind(fd, lcladdr) == -1) {
if (WSAGetLastError() == WSAEACCES) {
WSASetLastError(WSAEADDRINUSE);
}
@@ -501,17 +531,17 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_bind0(JNIEnv *env, jobject this,
}
if (port == 0) {
- if (fd == -1) {
+ if (fd == null) {
/* must be an IPV6 only socket. */
fd = fd1;
}
- if (getsockname(fd, (struct sockaddr *)&lcladdr, &lcladdrlen) == -1) {
+ if (getsockname(fd, lcladdr) == -1) {
NET_ThrowCurrent(env, "JVM_GetSockName");
return;
}
- port = ntohs((u_short) GET_PORT (&lcladdr));
+ port = ntohs(GET_PORT (lcladdr));
}
- (*env)->SetIntField(env, this, pdsi_localPortID, port);
+ _this.localPort = port;
}
@@ -521,30 +551,30 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_bind0(JNIEnv *env, jobject this,
* Signature: (Ljava/net/InetAddress;I)V
*/
-JNIEXPORT void JNICALL
-Java_java_net_TwoStacksPlainDatagramSocketImpl_connect0(JNIEnv *env, jobject this,
- jobject address, jint port) {
+static void connect0(JNIEnv env, TwoStacksPlainDatagramSocketImpl _this, InetAddress address, int port) {
/* The object's field */
- jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
- jobject fd1Obj = (*env)->GetObjectField(env, this, pdsi_fd1ID);
+ FileDescriptor fdObj = _this.fd;
+ FileDescriptor fd1Obj = _this.fd1;
/* The fdObj'fd */
- jint fd=-1, fd1=-1, fdc;
+ 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 */
- jint addr, family;
+ int addr, family;
SOCKETADDRESS rmtaddr;
- int rmtaddrlen;
- int ipv6_supported = ipv6_available();
+ rmtaddr = new SOCKETADDRESS();
+ boolean ipv6_supported = ipv6_available();
if (IS_NULL(fdObj) && IS_NULL(fd1Obj)) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
"Socket closed");
return;
}
if (!IS_NULL(fdObj)) {
- fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+ fd = fdObj.getSocket();
}
if (!IS_NULL(fd1Obj)) {
- fd1 = (*env)->GetIntField(env, fd1Obj, IO_fd_fdID);
+ fd1 = fd1Obj.getSocket();
}
if (IS_NULL(address)) {
@@ -552,11 +582,11 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_connect0(JNIEnv *env, jobject thi
return;
}
- addr = (*env)->GetIntField(env, address, ia_addressID);
+ addr = address.address;
- family = (*env)->GetIntField(env, address, ia_familyID);
+ family = address.family;
if (family == IPv6 && !ipv6_supported) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
"Protocol family not supported");
return;
}
@@ -569,16 +599,14 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_connect0(JNIEnv *env, jobject thi
* as connected sockets. The solution is to only enable this feature
* when the socket is connected
*/
- DWORD x1, x2; /* ignored result codes */
- int res, t = TRUE;
- res = WSAIoctl(fdc,SIO_UDP_CONNRESET,&t,sizeof(t),&x1,sizeof(x1),&x2,0,0);
+ WSAIoctl(fdc, SIO_UDP_CONNRESET, true);
}
- if (NET_InetAddressToSockaddr(env, address, port,(struct sockaddr *)&rmtaddr, &rmtaddrlen, JNI_FALSE) != 0) {
+ if (NET_InetAddressToSockaddr(env, address, port, rmtaddr, JNI_FALSE) != 0) {
return;
}
- if (connect(fdc, (struct sockaddr *)&rmtaddr, sizeof(rmtaddr)) == -1) {
+ if (connect(fdc, rmtaddr) == -1) {
NET_ThrowCurrent(env, "connect");
return;
}
@@ -590,39 +618,34 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_connect0(JNIEnv *env, jobject thi
* Signature: ()V
*/
-JNIEXPORT void JNICALL
-Java_java_net_TwoStacksPlainDatagramSocketImpl_disconnect0(JNIEnv *env, jobject this, jint family) {
+static void disconnect0(TwoStacksPlainDatagramSocketImpl _this, int family) {
/* The object's field */
- jobject fdObj;
+ FileDescriptor fdObj;
/* The fdObj'fd */
- jint fd, len;
+ cli.System.Net.Sockets.Socket fd;
SOCKETADDRESS addr;
+ addr = new SOCKETADDRESS();
if (family == IPv4) {
- fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
- len = sizeof (struct sockaddr_in);
+ fdObj = _this.fd;
} else {
- fdObj = (*env)->GetObjectField(env, this, pdsi_fd1ID);
- len = sizeof (struct SOCKADDR_IN6);
+ fdObj = _this.fd1;
}
if (IS_NULL(fdObj)) {
/* disconnect doesn't throw any exceptions */
return;
}
- fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+ fd = fdObj.getSocket();
- memset(&addr, 0, len);
- connect(fd, (struct sockaddr *)&addr, len);
+ connect(fd, addr);
/*
* use SIO_UDP_CONNRESET
* to disable ICMP port unreachable handling here.
*/
if (xp_or_later) {
- DWORD x1, x2; /* ignored result codes */
- int t = FALSE;
- WSAIoctl(fd,SIO_UDP_CONNRESET,&t,sizeof(t),&x1,sizeof(x1),&x2,0,0);
+ WSAIoctl(fd,SIO_UDP_CONNRESET,false);
}
}
@@ -631,76 +654,68 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_disconnect0(JNIEnv *env, jobject
* Method: send
* Signature: (Ljava/net/DatagramPacket;)V
*/
-JNIEXPORT void JNICALL
-Java_java_net_TwoStacksPlainDatagramSocketImpl_send(JNIEnv *env, jobject this,
- jobject packet) {
+static void send(JNIEnv env, TwoStacksPlainDatagramSocketImpl _this, DatagramPacket packet) {
+ FileDescriptor fdObj;
+ cli.System.Net.Sockets.Socket fd;
- char BUF[MAX_BUFFER_LEN];
- char *fullPacket;
- jobject fdObj;
- jint fd;
-
- jobject iaObj;
- jint address;
- jint family;
+ InetAddress iaObj;
+ int address;
+ int family;
- jint packetBufferOffset, packetBufferLen, packetPort;
- jbyteArray packetBuffer;
- jboolean connected;
+ int packetBufferOffset, packetBufferLen, packetPort;
+ byte[] packetBuffer;
+ boolean connected;
SOCKETADDRESS rmtaddr;
- SOCKETADDRESS *addrp = &rmtaddr;
- int addrlen;
- int x; /* DELETE ME */
-
+ rmtaddr = new SOCKETADDRESS();
if (IS_NULL(packet)) {
JNU_ThrowNullPointerException(env, "null packet");
return;
}
- iaObj = (*env)->GetObjectField(env, packet, dp_addressID);
+ iaObj = packet.address;
- packetPort = (*env)->GetIntField(env, packet, dp_portID);
- packetBufferOffset = (*env)->GetIntField(env, packet, dp_offsetID);
- packetBuffer = (jbyteArray)(*env)->GetObjectField(env, packet, dp_bufID);
- connected = (*env)->GetBooleanField(env, this, pdsi_connected);
+ 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 = (*env)->GetIntField(env, iaObj, ia_familyID);
+ family = iaObj.family;
if (family == IPv4) {
- fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
+ fdObj = _this.fd;
} else {
if (!ipv6_available()) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
"Protocol not allowed");
return;
}
- fdObj = (*env)->GetObjectField(env, this, pdsi_fd1ID);
+ fdObj = _this.fd1;
}
if (IS_NULL(fdObj)) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
"Socket closed");
return;
}
- fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+ fd = fdObj.getSocket();
- packetBufferLen = (*env)->GetIntField(env, packet, dp_lengthID);
+ packetBufferLen = packet.length;
if (connected) {
- addrp = 0; /* arg to JVM_Sendto () null in this case */
- addrlen = 0;
+ rmtaddr = null;
} else {
- if (NET_InetAddressToSockaddr(env, iaObj, packetPort, (struct sockaddr *)&rmtaddr, &addrlen, JNI_FALSE) != 0) {
+ if (NET_InetAddressToSockaddr(env, iaObj, packetPort, rmtaddr, JNI_FALSE) != 0) {
return;
}
}
+ /*
if (packetBufferLen > MAX_BUFFER_LEN) {
/*
@@ -711,9 +726,9 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_send(JNIEnv *env, jobject this,
* 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 */
+ * Check is not necessary on these OSes *-/
if (connected) {
address = (*env)->GetIntField(env, iaObj, ia_addressID);
} else {
@@ -738,7 +753,7 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_send(JNIEnv *env, jobject this,
* 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, "heap allocation failed");
@@ -747,34 +762,28 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_send(JNIEnv *env, jobject this,
} else {
fullPacket = &(BUF[0]);
}
+ */
- (*env)->GetByteArrayRegion(env, packetBuffer, packetBufferOffset, packetBufferLen,
- (jbyte *)fullPacket);
- switch (sendto(fd, fullPacket, packetBufferLen, 0,
- (struct sockaddr *)addrp, addrlen)) {
+ 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",
+ JNU_ThrowByName(env, JNU_JAVAIOPKG+"InterruptedIOException",
"operation interrupted");
}
-
- if (packetBufferLen > MAX_BUFFER_LEN) {
- free(fullPacket);
- }
}
/*
* 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.
*/
-static int checkLastFD (JNIEnv *env, jobject this, int fd, int fd1) {
- int nextfd, lastfd = (*env)->GetIntField(env, this, pdsi_lastfdID);
- if (lastfd == -1) {
+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 */
- (*env)->SetIntField(env, this, pdsi_lastfdID, fd);
+ _this.lastfd = fd;
return fd;
} else {
if (lastfd == fd) {
@@ -782,7 +791,7 @@ static int checkLastFD (JNIEnv *env, jobject this, int fd, int fd1) {
} else {
nextfd = fd;
}
- (*env)->SetIntField(env, this, pdsi_lastfdID, nextfd);
+ _this.lastfd = nextfd;
return nextfd;
}
}
@@ -792,39 +801,36 @@ static int checkLastFD (JNIEnv *env, jobject this, int fd, int fd1) {
* Method: peek
* Signature: (Ljava/net/InetAddress;)I
*/
-JNIEXPORT jint JNICALL
-Java_java_net_TwoStacksPlainDatagramSocketImpl_peek(JNIEnv *env, jobject this,
- jobject addressObj) {
-
- jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
- jint timeout = (*env)->GetIntField(env, this, pdsi_timeoutID);
- jint fd;
+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 */
- jint address, family;
+ int address, family;
int n;
- struct sockaddr_in remote_addr;
- jint remote_addrsize = sizeof (remote_addr);
- char buf[1];
- BOOL retry;
- jlong prevTime = 0;
+ 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");
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", "Socket closed");
return -1;
} else {
- fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
- if (fd < 0) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+ 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 = (*env)->GetIntField(env, addressObj, ia_addressID);
+ address = addressObj.address;
/* We only handle IPv4 for now. Will support IPv6 once its in the os */
family = AF_INET;
}
@@ -836,19 +842,19 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_peek(JNIEnv *env, jobject this,
* If a timeout has been specified then we select on the socket
* waiting for a read event or a timeout.
*/
- if (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",
+ 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",
+ JNU_ThrowByName(env, JNU_JAVAIOPKG+"InterruptedIOException",
"operation interrupted");
return ret;
}
@@ -856,22 +862,22 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_peek(JNIEnv *env, jobject this,
/* now try the peek */
n = recvfrom(fd, buf, 1, MSG_PEEK,
- (struct sockaddr *)&remote_addr, &remote_addrsize);
+ remote_addr);
if (n == JVM_IO_ERR) {
if (WSAGetLastError() == WSAECONNRESET) {
- jboolean connected;
+ 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(env, this, fd);
+ purgeOutstandingICMP(fd);
- connected = (*env)->GetBooleanField(env, this, pdsi_connected);
+ connected = _this.connected;
if (connected) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "PortUnreachableException",
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"PortUnreachableException",
"ICMP Port Unreachable");
return 0;
}
@@ -881,11 +887,11 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_peek(JNIEnv *env, jobject this,
* we may have used up some of the timeout befor the icmp port
* unreachable arrived.
*/
- if (timeout) {
- jlong newTime = JVM_CurrentTimeMillis(env, 0);
+ if (timeout != 0) {
+ long newTime = JVM_CurrentTimeMillis(env, 0);
timeout -= (newTime - prevTime);
if (timeout <= 0) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketTimeoutException",
"Receive timed out");
return 0;
}
@@ -903,45 +909,42 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_peek(JNIEnv *env, jobject this,
return 0;
}
if (n == JVM_IO_INTR) {
- JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException", 0);
+ JNU_ThrowByName(env, JNU_JAVAIOPKG+"InterruptedIOException", null);
return 0;
}
- (*env)->SetIntField(env, addressObj, ia_addressID,
- ntohl(remote_addr.sin_addr.s_addr));
- (*env)->SetIntField(env, addressObj, ia_familyID, IPv4);
+ addressObj.address = ntohl(remote_addr.sin_addr.s_addr);
+ addressObj.family = IPv4;
/* return port */
return ntohs(remote_addr.sin_port);
}
-JNIEXPORT jint JNICALL
-Java_java_net_TwoStacksPlainDatagramSocketImpl_peekData(JNIEnv *env, jobject this,
- jobject packet) {
+static int peekData(JNIEnv env, TwoStacksPlainDatagramSocketImpl _this, DatagramPacket packet) {
- char BUF[MAX_BUFFER_LEN];
- char *fullPacket;
- jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
- jobject fd1Obj = (*env)->GetObjectField(env, this, pdsi_fd1ID);
- jint timeout = (*env)->GetIntField(env, this, pdsi_timeoutID);
+ FileDescriptor fdObj = _this.fd;
+ FileDescriptor fd1Obj = _this.fd1;
+ int timeout = _this.timeout;
- jbyteArray packetBuffer;
- jint packetBufferOffset, packetBufferLen;
+ byte[] packetBuffer;
+ int packetBufferOffset, packetBufferLen;
- int fd, fd1, fduse, nsockets=0, errorCode;
+ cli.System.Net.Sockets.Socket fd = null, fd1 = null, fduse = null;
+ int nsockets=0, errorCode;
int port;
- jbyteArray data;
+ byte[] data;
- int checkBoth = 0, datalen;
+ boolean checkBoth = false;
+ int datalen;
int n;
SOCKETADDRESS remote_addr;
- jint remote_addrsize=sizeof(remote_addr);
- BOOL retry;
- jlong prevTime = 0;
+ remote_addr = new SOCKETADDRESS();
+ boolean retry;
+ long prevTime = 0;
if (!IS_NULL(fdObj)) {
- fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
- if (fd < 0) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+ fd = fdObj.getSocket();
+ if (fd == null) {
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
"socket closed");
return -1;
}
@@ -949,9 +952,9 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_peekData(JNIEnv *env, jobject thi
}
if (!IS_NULL(fd1Obj)) {
- fd1 = (*env)->GetIntField(env, fd1Obj, IO_fd_fdID);
- if (fd1 < 0) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+ fd1 = fd1Obj.getSocket();
+ if (fd1 == null) {
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
"socket closed");
return -1;
}
@@ -960,7 +963,7 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_peekData(JNIEnv *env, jobject thi
switch (nsockets) {
case 0:
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
"socket closed");
return -1;
case 1:
@@ -980,16 +983,17 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_peekData(JNIEnv *env, jobject thi
return -1;
}
- packetBuffer = (*env)->GetObjectField(env, packet, dp_bufID);
+ packetBuffer = packet.buf;
if (IS_NULL(packetBuffer)) {
JNU_ThrowNullPointerException(env, "packet buffer");
return -1;
}
- packetBufferOffset = (*env)->GetIntField(env, packet, dp_offsetID);
- packetBufferLen = (*env)->GetIntField(env, packet, dp_bufLengthID);
+ packetBufferOffset = packet.offset;
+ packetBufferLen = packet.bufLength;
+ /*
if (packetBufferLen > MAX_BUFFER_LEN) {
/* When JNI-ifying the JDK's IO routines, we turned
@@ -1002,7 +1006,7 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_peekData(JNIEnv *env, jobject thi
* 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, "heap allocation failed");
@@ -1011,6 +1015,7 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_peekData(JNIEnv *env, jobject thi
} else {
fullPacket = &(BUF[0]);
}
+ */
do {
int ret;
@@ -1023,74 +1028,66 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_peekData(JNIEnv *env, jobject thi
if (checkBoth) {
int t = timeout == 0 ? -1: timeout;
prevTime = JVM_CurrentTimeMillis(env, 0);
- ret = NET_Timeout2 (fd, fd1, t, &fduse);
+ 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",
+ 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",
+ JNU_ThrowByName(env, JNU_JAVAIOPKG+"InterruptedIOException",
"operation interrupted");
}
- if (packetBufferLen > MAX_BUFFER_LEN) {
- free(fullPacket);
- }
return -1;
}
if (ret == 2) {
- fduse = checkLastFD (env, this, fd, fd1);
+ fduse = checkLastFD (_this, fd, fd1);
}
checkBoth = FALSE;
- } else if (timeout) {
+ } 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",
+ JNU_ThrowByName(env,JNU_JAVANETPKG+"SocketTimeoutException",
"Receive timed out");
} else if (ret == JVM_IO_ERR) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
"Socket closed");
} else if (ret == JVM_IO_INTR) {
- JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
+ JNU_ThrowByName(env, JNU_JAVAIOPKG+"InterruptedIOException",
"operation interrupted");
}
- if (packetBufferLen > MAX_BUFFER_LEN) {
- free(fullPacket);
- }
return -1;
}
}
/* receive the packet */
- n = recvfrom(fduse, fullPacket, packetBufferLen, MSG_PEEK,
- (struct sockaddr *)&remote_addr, &remote_addrsize);
- port = (int) ntohs ((u_short) GET_PORT((SOCKETADDRESS *)&remote_addr));
+ n = recvfrom(fduse, packetBuffer, packetBufferOffset, packetBufferLen, MSG_PEEK, remote_addr);
+ port = ntohs (GET_PORT(remote_addr));
if (n == JVM_IO_ERR) {
if (WSAGetLastError() == WSAECONNRESET) {
- jboolean connected;
+ 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(env, this, fduse);
+ purgeOutstandingICMP(fduse);
- connected = (*env)->GetBooleanField(env, this, pdsi_connected);
+ connected = _this.connected;
if (connected) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "PortUnreachableException",
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"PortUnreachableException",
"ICMP Port Unreachable");
- if (packetBufferLen > MAX_BUFFER_LEN) {
- free(fullPacket);
- }
return -1;
}
@@ -1099,15 +1096,12 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_peekData(JNIEnv *env, jobject thi
* we may have used up some of the timeout befor the icmp port
* unreachable arrived.
*/
- if (timeout) {
- jlong newTime = JVM_CurrentTimeMillis(env, 0);
+ if (timeout != 0) {
+ long newTime = JVM_CurrentTimeMillis(env, 0);
timeout -= (newTime - prevTime);
if (timeout <= 0) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketTimeoutException",
"Receive timed out");
- if (packetBufferLen > MAX_BUFFER_LEN) {
- free(fullPacket);
- }
return -1;
}
prevTime = newTime;
@@ -1117,10 +1111,6 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_peekData(JNIEnv *env, jobject thi
}
} while (retry);
- /* truncate the data if the packet's length is too small */
- if (n > packetBufferLen) {
- n = packetBufferLen;
- }
if (n < 0) {
errorCode = WSAGetLastError();
/* check to see if it's because the buffer was too small */
@@ -1132,52 +1122,47 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_peekData(JNIEnv *env, jobject thi
n = packetBufferLen;
} else {
/* failure */
- (*env)->SetIntField(env, packet, dp_lengthID, 0);
+ packet.length = 0;
}
}
if (n == -1) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "socket closed");
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", "socket closed");
} else if (n == -2) {
- JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
+ JNU_ThrowByName(env, JNU_JAVAIOPKG+"InterruptedIOException",
"operation interrupted");
} else if (n < 0) {
NET_ThrowCurrent(env, "Datagram receive failed");
} else {
- jobject packetAddress;
+ InetAddress packetAddress;
/*
* Check if there is an InetAddress already associated with this
* packet. If so we check if it is the same source address. We
* can't update any existing InetAddress because it is immutable
*/
- packetAddress = (*env)->GetObjectField(env, packet, dp_addressID);
+ packetAddress = packet.address;
if (packetAddress != NULL) {
- if (!NET_SockaddrEqualsInetAddress(env, (struct sockaddr *)
- &remote_addr, packetAddress)) {
+ if (!NET_SockaddrEqualsInetAddress(remote_addr, packetAddress)) {
/* force a new InetAddress to be created */
- packetAddress = NULL;
+ packetAddress = null;
}
}
if (packetAddress == NULL) {
- packetAddress = NET_SockaddrToInetAddress(env, (struct sockaddr *)
- &remote_addr, &port);
+ int[] tmp = { port };
+ packetAddress = NET_SockaddrToInetAddress(remote_addr, tmp);
+ port = tmp[0];
/* stuff the new Inetaddress in the packet */
- (*env)->SetObjectField(env, packet, dp_addressID, packetAddress);
+ packet.address = packetAddress;
}
/* populate the packet */
- (*env)->SetByteArrayRegion(env, packetBuffer, packetBufferOffset, n,
- (jbyte *)fullPacket);
- (*env)->SetIntField(env, packet, dp_portID, port);
- (*env)->SetIntField(env, packet, dp_lengthID, n);
+ packet.port = port;
+ packet.length = n;
}
/* make sure receive() picks up the right fd */
- (*env)->SetIntField(env, this, pdsi_fduseID, fduse);
+ _this.fduse = fduse;
- if (packetBufferLen > MAX_BUFFER_LEN) {
- free(fullPacket);
- }
return port;
}
@@ -1186,66 +1171,64 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_peekData(JNIEnv *env, jobject thi
* Method: receive
* Signature: (Ljava/net/DatagramPacket;)V
*/
-JNIEXPORT void JNICALL
-Java_java_net_TwoStacksPlainDatagramSocketImpl_receive0(JNIEnv *env, jobject this,
- jobject packet) {
-
- char BUF[MAX_BUFFER_LEN];
- char *fullPacket;
- jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
- jobject fd1Obj = (*env)->GetObjectField(env, this, pdsi_fd1ID);
- jint timeout = (*env)->GetIntField(env, this, pdsi_timeoutID);
- jbyteArray packetBuffer;
- jint packetBufferOffset, packetBufferLen;
- int ipv6_supported = ipv6_available();
+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.
*/
- int fd, fd1, fduse, errorCode;
- jbyteArray data;
+ cli.System.Net.Sockets.Socket fd = null;
+ cli.System.Net.Sockets.Socket fd1 = null;
+ cli.System.Net.Sockets.Socket fduse = null;
+ int errorCode;
- int datalen;
int n, nsockets=0;
SOCKETADDRESS remote_addr;
- jint remote_addrsize=sizeof(remote_addr);
- BOOL retry;
- jlong prevTime = 0, selectTime=0;
- jboolean connected;
+ 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",
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
"Socket closed");
return;
}
if (!IS_NULL(fdObj)) {
- fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+ fd = fdObj.getSocket();
nsockets ++;
}
if (!IS_NULL(fd1Obj)) {
- fd1 = (*env)->GetIntField(env, fd1Obj, IO_fd_fdID);
+ fd1 = fd1Obj.getSocket();
nsockets ++;
}
if (nsockets == 2) { /* need to choose one of them */
/* was fduse set in peek? */
- fduse = (*env)->GetIntField(env, this, pdsi_fduseID);
- if (fduse == -1) {
+ fduse = _this.fduse;
+ if (fduse == null) {
/* not set in peek(), must select on both sockets */
int ret, t = (timeout == 0) ? -1: timeout;
- ret = NET_Timeout2 (fd, fd1, t, &fduse);
+ 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 (env, this, fd, fd1);
+ fduse = checkLastFD (_this, fd, fd1);
} else if (ret <= 0) {
if (ret == 0) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketTimeoutException",
"Receive timed out");
} else if (ret == JVM_IO_ERR) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
"Socket closed");
} else if (ret == JVM_IO_INTR) {
- JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
+ JNU_ThrowByName(env, JNU_JAVAIOPKG+"InterruptedIOException",
"operation interrupted");
}
return;
@@ -1266,16 +1249,17 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_receive0(JNIEnv *env, jobject thi
return;
}
- packetBuffer = (*env)->GetObjectField(env, packet, dp_bufID);
+ packetBuffer = packet.buf;
if (IS_NULL(packetBuffer)) {
JNU_ThrowNullPointerException(env, "packet buffer");
return;
}
- packetBufferOffset = (*env)->GetIntField(env, packet, dp_offsetID);
- packetBufferLen = (*env)->GetIntField(env, packet, dp_bufLengthID);
+ packetBufferOffset = packet.offset;
+ packetBufferLen = packet.bufLength;
+ /*
if (packetBufferLen > MAX_BUFFER_LEN) {
/* When JNI-ifying the JDK's IO routines, we turned
@@ -1288,7 +1272,7 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_receive0(JNIEnv *env, jobject thi
* 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, "heap allocation failed");
@@ -1297,6 +1281,7 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_receive0(JNIEnv *env, jobject thi
} else {
fullPacket = &(BUF[0]);
}
+ */
@@ -1309,28 +1294,25 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_receive0(JNIEnv *env, jobject thi
* 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 = (*env)->GetBooleanField(env, this, pdsi_connected);
- if (supportPortUnreachable() && !connected && timeout &&!ipv6_supported) {
+ connected = _this.connected;
+ if (supportPortUnreachable() && !connected && timeout != 0 &&!ipv6_supported) {
prevTime = JVM_CurrentTimeMillis(env, 0);
}
- if (timeout && nsockets == 1) {
+ if (timeout != 0 && nsockets == 1) {
int ret;
ret = NET_Timeout(fduse, timeout);
if (ret <= 0) {
if (ret == 0) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketTimeoutException",
"Receive timed out");
} else if (ret == JVM_IO_ERR) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
"Socket closed");
} else if (ret == JVM_IO_INTR) {
- JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
+ JNU_ThrowByName(env, JNU_JAVAIOPKG+"InterruptedIOException",
"operation interrupted");
}
- if (packetBufferLen > MAX_BUFFER_LEN) {
- free(fullPacket);
- }
return;
}
}
@@ -1342,8 +1324,7 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_receive0(JNIEnv *env, jobject thi
retry = FALSE;
/* receive the packet */
- n = recvfrom(fduse, fullPacket, packetBufferLen, 0,
- (struct sockaddr *)&remote_addr, &remote_addrsize);
+ n = recvfrom(fduse, packetBuffer, packetBufferOffset, packetBufferLen, 0, remote_addr);
if (n == JVM_IO_ERR) {
if (WSAGetLastError() == WSAECONNRESET) {
@@ -1351,20 +1332,15 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_receive0(JNIEnv *env, jobject thi
* An icmp port unreachable has been received - consume any other
* outstanding packets.
*/
- purgeOutstandingICMP(env, this, fduse);
+ purgeOutstandingICMP(fduse);
/*
* If connected throw a PortUnreachableException
*/
if (connected) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "PortUnreachableException",
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"PortUnreachableException",
"ICMP Port Unreachable");
-
- if (packetBufferLen > MAX_BUFFER_LEN) {
- free(fullPacket);
- }
-
return;
}
@@ -1373,9 +1349,9 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_receive0(JNIEnv *env, jobject thi
* we may have used up some of the timeout before the icmp port
* unreachable arrived.
*/
- if (timeout) {
+ if (timeout != 0) {
int ret;
- jlong newTime = JVM_CurrentTimeMillis(env, 0);
+ long newTime = JVM_CurrentTimeMillis(env, 0);
timeout -= (newTime - prevTime);
prevTime = newTime;
@@ -1387,18 +1363,15 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_receive0(JNIEnv *env, jobject thi
if (ret <= 0) {
if (ret == 0) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketTimeoutException",
"Receive timed out");
} else if (ret == JVM_IO_ERR) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
"Socket closed");
} else if (ret == JVM_IO_INTR) {
- JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
+ JNU_ThrowByName(env, JNU_JAVAIOPKG+"InterruptedIOException",
"operation interrupted");
}
- if (packetBufferLen > MAX_BUFFER_LEN) {
- free(fullPacket);
- }
return;
}
}
@@ -1412,10 +1385,6 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_receive0(JNIEnv *env, jobject thi
}
} while (retry);
- /* truncate the data if the packet's length is too small */
- if (n > packetBufferLen) {
- n = packetBufferLen;
- }
if (n < 0) {
errorCode = WSAGetLastError();
/* check to see if it's because the buffer was too small */
@@ -1427,49 +1396,46 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_receive0(JNIEnv *env, jobject thi
n = packetBufferLen;
} else {
/* failure */
- (*env)->SetIntField(env, packet, dp_lengthID, 0);
+ packet.length = 0;
}
}
if (n == -1) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "socket closed");
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", "socket closed");
} else if (n == -2) {
- JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
+ JNU_ThrowByName(env, JNU_JAVAIOPKG+"InterruptedIOException",
"operation interrupted");
} else if (n < 0) {
NET_ThrowCurrent(env, "Datagram receive failed");
} else {
int port;
- jobject packetAddress;
+ InetAddress packetAddress;
/*
* Check if there is an InetAddress already associated with this
* packet. If so we check if it is the same source address. We
* can't update any existing InetAddress because it is immutable
*/
- packetAddress = (*env)->GetObjectField(env, packet, dp_addressID);
+ packetAddress = packet.address;
if (packetAddress != NULL) {
- if (!NET_SockaddrEqualsInetAddress(env, (struct sockaddr *)&remote_addr, packetAddress)) {
+ if (!NET_SockaddrEqualsInetAddress(remote_addr, packetAddress)) {
/* force a new InetAddress to be created */
- packetAddress = NULL;
+ packetAddress = null;
}
}
if (packetAddress == NULL) {
- packetAddress = NET_SockaddrToInetAddress(env, (struct sockaddr *)&remote_addr, &port);
+ int[] tmp = { 0 };
+ packetAddress = NET_SockaddrToInetAddress(remote_addr, tmp);
+ port = tmp[0];
/* stuff the new Inetaddress in the packet */
- (*env)->SetObjectField(env, packet, dp_addressID, packetAddress);
+ packet.address = packetAddress;
} else {
/* only get the new port number */
- port = NET_GetPortFromSockaddr((struct sockaddr *)&remote_addr);
+ port = NET_GetPortFromSockaddr(remote_addr);
}
/* populate the packet */
- (*env)->SetByteArrayRegion(env, packetBuffer, packetBufferOffset, n,
- (jbyte *)fullPacket);
- (*env)->SetIntField(env, packet, dp_portID, port);
- (*env)->SetIntField(env, packet, dp_lengthID, n);
- }
- if (packetBufferLen > MAX_BUFFER_LEN) {
- free(fullPacket);
+ packet.port = port;
+ packet.length = n;
}
}
@@ -1478,32 +1444,25 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_receive0(JNIEnv *env, jobject thi
* Method: datagramSocketCreate
* Signature: ()V
*/
-JNIEXPORT void JNICALL
-Java_java_net_TwoStacksPlainDatagramSocketImpl_datagramSocketCreate(JNIEnv *env,
- jobject this) {
- jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
- jobject fd1Obj = (*env)->GetObjectField(env, this, pdsi_fd1ID);
-
- int fd, fd1;
- int t = TRUE;
- DWORD x1, x2; /* ignored result codes */
- int ipv6_supported = ipv6_available();
-
- int arg = -1;
+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");
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", "Socket closed");
return;
} else {
- fd = (int) socket (AF_INET, SOCK_DGRAM, 0);
+ fd = socket (AF_INET, SOCK_DGRAM, 0);
}
- if (fd == JVM_IO_ERR) {
+ if (fd == INVALID_SOCKET) {
NET_ThrowCurrent(env, "Socket creation failed");
return;
}
- SetHandleInformation((HANDLE)(UINT_PTR)fd, HANDLE_FLAG_INHERIT, FALSE);
- (*env)->SetIntField(env, fdObj, IO_fd_fdID, fd);
- NET_SetSockOpt(fd, SOL_SOCKET, SO_BROADCAST, (char*)&t, sizeof(BOOL));
+ 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
@@ -1511,22 +1470,18 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_datagramSocketCreate(JNIEnv *env,
* as connected sockets. The solution is to only enable this feature
* when the socket is connected
*/
- t = FALSE;
- WSAIoctl(fd,SIO_UDP_CONNRESET,&t,sizeof(t),&x1,sizeof(x1),&x2,0,0);
- t = TRUE;
+ WSAIoctl(fd,SIO_UDP_CONNRESET,false);
fd1 = socket (AF_INET6, SOCK_DGRAM, 0);
- if (fd1 == JVM_IO_ERR) {
+ if (fd1 == INVALID_SOCKET) {
NET_ThrowCurrent(env, "Socket creation failed");
return;
}
- NET_SetSockOpt(fd1, SOL_SOCKET, SO_BROADCAST, (char*)&t, sizeof(BOOL));
- t = FALSE;
- WSAIoctl(fd1,SIO_UDP_CONNRESET,&t,sizeof(t),&x1,sizeof(x1),&x2,0,0);
- (*env)->SetIntField(env, fd1Obj, IO_fd_fdID, fd1);
- SetHandleInformation((HANDLE)(UINT_PTR)fd1, HANDLE_FLAG_INHERIT, FALSE);
+ NET_SetSockOpt(fd1, SOL_SOCKET, SO_BROADCAST, true);
+ WSAIoctl(fd1,SIO_UDP_CONNRESET,false);
+ fd1Obj.setSocket(fd1);
} else {
/* drop the second fd */
- (*env)->SetObjectField(env, this, pdsi_fd1ID, NULL);
+ _this.fd1 = null;
}
}
@@ -1535,35 +1490,33 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_datagramSocketCreate(JNIEnv *env,
* Method: datagramSocketClose
* Signature: ()V
*/
-JNIEXPORT void JNICALL
-Java_java_net_TwoStacksPlainDatagramSocketImpl_datagramSocketClose(JNIEnv *env,
- jobject this) {
+static void datagramSocketClose(TwoStacksPlainDatagramSocketImpl _this) {
/*
* REMIND: PUT A LOCK AROUND THIS CODE
*/
- jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
- jobject fd1Obj = (*env)->GetObjectField(env, this, pdsi_fd1ID);
- int ipv6_supported = ipv6_available();
- int fd=-1, fd1=-1;
+ 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 = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
- if (fd != -1) {
- (*env)->SetIntField(env, fdObj, IO_fd_fdID, -1);
+ fd = fdObj.getSocket();
+ if (fd != null) {
+ fdObj.setSocket(null);
NET_SocketClose(fd);
}
}
if (ipv6_supported && fd1Obj != NULL) {
- fd1 = (*env)->GetIntField(env, fd1Obj, IO_fd_fdID);
- if (fd1 == -1) {
+ fd1 = fd1Obj.getSocket();
+ if (fd1 == null) {
return;
}
- (*env)->SetIntField(env, fd1Obj, IO_fd_fdID, -1);
+ fd1Obj.setSocket(null);
NET_SocketClose(fd1);
}
}
@@ -1574,84 +1527,87 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_datagramSocketClose(JNIEnv *env,
* in *iaddr
*/
-static int getInetAddrFromIf (JNIEnv *env, int family, jobject nif, jobject *iaddr)
+private static int getInetAddrFromIf (JNIEnv env, int family, NetworkInterface nif, InetAddress[] iaddr)
{
- jobjectArray addrArray;
- static jfieldID ni_addrsID=0;
- static jfieldID ia_familyID=0;
- jsize len;
- jobject addr;
+ InetAddress[] addrArray;
+ int len;
+ InetAddress addr;
int i;
- if (ni_addrsID == NULL) {
- jclass c = (*env)->FindClass(env, "java/net/NetworkInterface");
- CHECK_NULL_RETURN (c, -1);
- ni_addrsID = (*env)->GetFieldID(env, c, "addrs",
- "[Ljava/net/InetAddress;");
- CHECK_NULL_RETURN (ni_addrsID, -1);
- c = (*env)->FindClass(env,"java/net/InetAddress");
- CHECK_NULL_RETURN (c, -1);
- ia_familyID = (*env)->GetFieldID(env, c, "family", "I");
- CHECK_NULL_RETURN (ia_familyID, -1);
- }
-
- addrArray = (*env)->GetObjectField(env, nif, ni_addrsID);
- len = (*env)->GetArrayLength(env, addrArray);
+ 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",
+ 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 = (*env)->GetObjectArrayElement(env, addrArray, i);
- fam = (*env)->GetIntField(env, addr, ia_familyID);
+ addr = addrArray[i];
+ fam = addr.family;
if (fam == family) {
- *iaddr = addr;
+ iaddr[0] = addr;
return 0;
}
}
return -1;
}
-static int getInet4AddrFromIf (JNIEnv *env, jobject nif, struct in_addr *iaddr)
+private static int getInet4AddrFromIf (JNIEnv env, NetworkInterface nif, in_addr iaddr)
{
- jobject addr;
- static jfieldID ia_addressID;
+ InetAddress[] addr = new InetAddress[1];
- int ret = getInetAddrFromIf (env, IPv4, nif, &addr);
+ int ret = getInetAddrFromIf (env, IPv4, nif, addr);
if (ret == -1) {
return -1;
}
- if (ia_addressID == 0) {
- jclass c = (*env)->FindClass(env,"java/net/InetAddress");
- CHECK_NULL_RETURN (c, -1);
- ia_addressID = (*env)->GetFieldID(env, c, "address", "I");
- CHECK_NULL_RETURN (ia_addressID, -1);
- }
- iaddr->s_addr = htonl((*env)->GetIntField(env, addr, ia_addressID));
+ iaddr.s_addr = htonl(addr[0].address);
return 0;
}
/* Get the multicasting index from the interface */
-static int getIndexFromIf (JNIEnv *env, jobject nif) {
- static jfieldID ni_indexID;
+private static int getIndexFromIf (JNIEnv env, NetworkInterface nif) {
+ return nif.getIndex();
+}
- if (ni_indexID == NULL) {
- jclass c = (*env)->FindClass(env, "java/net/NetworkInterface");
- CHECK_NULL_RETURN(c, -1);
- ni_indexID = (*env)->GetFieldID(env, c, "index", "I");
- CHECK_NULL_RETURN(ni_indexID, -1);
+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()]);
+ }
+ });
+}
+
+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;
}
+}
- return (*env)->GetIntField(env, nif, ni_indexID);
+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;
+ }
}
/*
@@ -1677,10 +1633,10 @@ static int getIndexFromIf (JNIEnv *env, jobject nif) {
* IPPROTO_IPV6/IPV6_MULTICAST_IF
*
*/
-static void setMulticastInterface(JNIEnv *env, jobject this, int fd, int fd1,
- jint opt, jobject value)
+private static void setMulticastInterface(JNIEnv env, TwoStacksPlainDatagramSocketImpl _this, cli.System.Net.Sockets.Socket fd, cli.System.Net.Sockets.Socket fd1,
+ int opt, Object value)
{
- int ipv6_supported = ipv6_available();
+ boolean ipv6_supported = ipv6_available();
if (opt == java_net_SocketOptions_IP_MULTICAST_IF) {
/*
@@ -1691,40 +1647,24 @@ static void setMulticastInterface(JNIEnv *env, jobject this, int fd, int fd1,
* option instead of IP_MULTICAST_IF
*/
if (ipv6_supported) {
- static jclass ni_class;
- if (ni_class == NULL) {
- jclass c = (*env)->FindClass(env, "java/net/NetworkInterface");
- CHECK_NULL(c);
- ni_class = (*env)->NewGlobalRef(env, c);
- CHECK_NULL(ni_class);
- }
-
value = Java_java_net_NetworkInterface_getByInetAddress0(env, ni_class, value);
if (value == NULL) {
- if (!(*env)->ExceptionOccurred(env)) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+ if (env.ExceptionOccurred() == null) {
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
"bad argument for IP_MULTICAST_IF"
- ": address not bound to any interface");
+ +": address not bound to any interface");
}
return;
}
opt = java_net_SocketOptions_IP_MULTICAST_IF2;
} else {
- static jfieldID ia_addressID;
- struct in_addr in;
-
- if (ia_addressID == NULL) {
- jclass c = (*env)->FindClass(env,"java/net/InetAddress");
- CHECK_NULL(c);
- ia_addressID = (*env)->GetFieldID(env, c, "address", "I");
- CHECK_NULL(ia_addressID);
- }
+ in_addr in = new in_addr();
- in.s_addr = htonl((*env)->GetIntField(env, value, ia_addressID));
+ in.s_addr = htonl(((InetAddress)value).address);
if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
- (const char*)&in, sizeof(in)) < 0) {
- NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+ in) < 0) {
+ NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG+"SocketException",
"Error setting socket option");
}
return;
@@ -1740,26 +1680,19 @@ static void setMulticastInterface(JNIEnv *env, jobject this, int fd, int fd1,
* option. For IPv6 both must be done.
*/
if (ipv6_supported) {
- static jfieldID ni_indexID;
- struct in_addr in;
+ in_addr in = new in_addr();
int index;
- if (ni_indexID == NULL) {
- jclass c = (*env)->FindClass(env, "java/net/NetworkInterface");
- CHECK_NULL(c);
- ni_indexID = (*env)->GetFieldID(env, c, "index", "I");
- CHECK_NULL(ni_indexID);
- }
- index = (*env)->GetIntField(env, value, ni_indexID);
+ index = ((NetworkInterface)value).getIndex();
if (setsockopt(fd1, IPPROTO_IPV6, IPV6_MULTICAST_IF,
- (const char*)&index, sizeof(index)) < 0) {
- if (errno == EINVAL && index > 0) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+ index) < 0) {
+ if (WSAGetLastError() == WSAEINVAL && index > 0) {
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
"IPV6_MULTICAST_IF failed (interface has IPv4 "
- "address only?)");
+ +"address only?)");
} else {
- NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+ NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG+"SocketException",
"Error setting socket option");
}
return;
@@ -1768,30 +1701,30 @@ static void setMulticastInterface(JNIEnv *env, jobject this, int fd, int fd1,
/* If there are any IPv4 addresses on this interface then
* repeat the operation on the IPv4 fd */
- if (getInet4AddrFromIf (env, value, &in) < 0) {
+ if (getInet4AddrFromIf (env, (NetworkInterface)value, in) < 0) {
return;
}
if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
- (const char*)&in, sizeof(in)) < 0) {
- NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+ in) < 0) {
+ NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG+"SocketException",
"Error setting socket option");
}
return;
} else {
- struct in_addr in;
+ in_addr in = new in_addr();
- if (getInet4AddrFromIf (env, value, &in) < 0) {
- if ((*env)->ExceptionOccurred(env)) {
+ if (getInet4AddrFromIf (env, (NetworkInterface)value, in) < 0) {
+ if (env.ExceptionOccurred() != null) {
return;
}
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
"no InetAddress instances of requested type");
return;
}
if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
- (const char*)&in, sizeof(in)) < 0) {
- NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+ in) < 0) {
+ NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG+"SocketException",
"Error setting socket option");
}
return;
@@ -1804,32 +1737,30 @@ static void setMulticastInterface(JNIEnv *env, jobject this, int fd, int fd1,
* Method: socketSetOption
* Signature: (ILjava/lang/Object;)V
*/
-JNIEXPORT void JNICALL
-Java_java_net_TwoStacksPlainDatagramSocketImpl_socketSetOption(JNIEnv *env,jobject this,
- jint opt,jobject value) {
-
- int fd=-1, fd1=-1;
- int levelv4, levelv6, optnamev4, optnamev6, optlen;
- union {
- int i;
- char c;
- } optval;
- int ipv6_supported = ipv6_available();
-
- fd = getFD(env, this);
+static void socketSetOption(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);
+ fd1 = getFD1(env, _this);
}
- if (fd < 0 && fd1 < 0) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "socket closed");
+ 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);
+ setMulticastInterface(env, _this, fd, fd1, opt, value);
return;
}
@@ -1837,15 +1768,15 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_socketSetOption(JNIEnv *env,jobje
* Map the Java level socket option to the platform specific
* level(s) and option name(s).
*/
- if (fd1 != -1) {
- if (NET_MapSocketOptionV6(opt, &levelv6, &optnamev6)) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Invalid option");
+ if (fd1 != null) {
+ if (NET_MapSocketOptionV6(opt, levelv6, optnamev6) != 0) {
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", "Invalid option");
return;
}
}
- if (fd != -1) {
- if (NET_MapSocketOption(opt, &levelv4, &optnamev4)) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Invalid option");
+ if (fd != null) {
+ if (NET_MapSocketOption(opt, levelv4, optnamev4) != 0) {
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", "Invalid option");
return;
}
}
@@ -1854,61 +1785,39 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_socketSetOption(JNIEnv *env,jobje
case java_net_SocketOptions_SO_SNDBUF :
case java_net_SocketOptions_SO_RCVBUF :
case java_net_SocketOptions_IP_TOS :
- {
- jclass cls;
- jfieldID fid;
-
- cls = (*env)->FindClass(env, "java/lang/Integer");
- CHECK_NULL(cls);
- fid = (*env)->GetFieldID(env, cls, "value", "I");
- CHECK_NULL(fid);
-
- optval.i = (*env)->GetIntField(env, value, fid);
- optlen = sizeof(optval.i);
- }
+ optval = ((Integer)value).intValue();
break;
case java_net_SocketOptions_SO_REUSEADDR:
case java_net_SocketOptions_SO_BROADCAST:
case java_net_SocketOptions_IP_MULTICAST_LOOP:
{
- jclass cls;
- jfieldID fid;
- jboolean on;
-
- cls = (*env)->FindClass(env, "java/lang/Boolean");
- CHECK_NULL(cls);
- fid = (*env)->GetFieldID(env, cls, "value", "Z");
- CHECK_NULL(fid);
-
- on = (*env)->GetBooleanField(env, value, fid);
- optval.i = (on ? 1 : 0);
+ 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.i = !optval.i;
+ optval = !on;
}
- optlen = sizeof(optval.i);
}
break;
default :
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
"Socket option not supported by PlainDatagramSocketImp");
- break;
-
+ return;
}
- if (fd1 != -1) {
- if (NET_SetSockOpt(fd1, levelv6, optnamev6, (void *)&optval, optlen) < 0) {
+ if (fd1 != null) {
+ if (NET_SetSockOpt(fd1, levelv6[0], optnamev6[0], optval) < 0) {
NET_ThrowCurrent(env, "setsockopt IPv6");
return;
}
}
- if (fd != -1) {
- if (NET_SetSockOpt(fd, levelv4, optnamev4, (void *)&optval, optlen) < 0) {
+ if (fd != null) {
+ if (NET_SetSockOpt(fd, levelv4[0], optnamev4[0], optval) < 0) {
NET_ThrowCurrent(env, "setsockopt");
return;
}
@@ -1940,33 +1849,20 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_socketSetOption(JNIEnv *env,jobje
* Query NetworkInterface by index and
* return NetworkInterface.
*/
-jobject getMulticastInterface(JNIEnv *env, jobject this, int fd, int fd1, jint opt) {
- jboolean isIPV4 = !ipv6_available() || fd1 == -1;
+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) {
- static jclass inet4_class;
- static jmethodID inet4_ctrID;
- static jfieldID inet4_addrID;
-
- static jclass ni_class;
- static jmethodID ni_ctrID;
- static jfieldID ni_indexID;
- static jfieldID ni_addrsID;
+ Inet4Address addr;
- jobjectArray addrArray;
- jobject addr;
- jobject ni;
-
- struct in_addr in;
- struct in_addr *inP = &in;
- int len = sizeof(struct in_addr);
+ in_addr in = new in_addr();
if (getsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
- (char *)inP, &len) < 0) {
- NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+ in) < 0) {
+ NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG+"SocketException",
"Error getting socket option");
return NULL;
}
@@ -1974,20 +1870,8 @@ jobject getMulticastInterface(JNIEnv *env, jobject this, int fd, int fd1, jint o
/*
* 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_addrID = (*env)->GetFieldID(env, c, "address", "I");
- CHECK_NULL_RETURN(inet4_addrID, 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);
-
- (*env)->SetIntField(env, addr, inet4_addrID, ntohl(in.s_addr));
+ addr = new Inet4Address();
+ addr.address = ntohl(in.s_addr);
/*
* For IP_MULTICAST_IF return InetAddress
@@ -1996,25 +1880,9 @@ jobject getMulticastInterface(JNIEnv *env, jobject this, int fd, int fd1, jint o
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);
- }
+ NetworkInterface ni;
ni = Java_java_net_NetworkInterface_getByInetAddress0(env, ni_class, addr);
- if (ni) {
+ if (ni != null) {
return ni;
}
@@ -2023,15 +1891,7 @@ jobject getMulticastInterface(JNIEnv *env, jobject this, int fd, int fd1, jint o
* NetworkInterface. Therefore we construct a NetworkInterface
* with this address.
*/
- 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);
- return ni;
+ return new NetworkInterface(null, -1, new InetAddress[] { addr });
}
@@ -2041,51 +1901,21 @@ jobject getMulticastInterface(JNIEnv *env, jobject this, int fd, int fd1, jint o
if ((opt == java_net_SocketOptions_IP_MULTICAST_IF) ||
(opt == java_net_SocketOptions_IP_MULTICAST_IF2)) {
- static jclass ni_class;
- static jmethodID ni_ctrID;
- static jfieldID ni_indexID;
- static jfieldID ni_addrsID;
- static jclass ia_class;
- static jmethodID ia_anyLocalAddressID;
-
int index;
- int len = sizeof(index);
- jobjectArray addrArray;
- jobject addr;
- jobject ni;
+ InetAddress[] addrArray;
+ InetAddress addr;
+ NetworkInterface ni;
{
+ int[] tmp = { 0 };
if (getsockopt(fd1, IPPROTO_IPV6, IPV6_MULTICAST_IF,
- (char*)&index, &len) < 0) {
- NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+ tmp) < 0) {
+ NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG+"SocketException",
"Error getting socket option");
return NULL;
}
- }
-
- 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);
-
- ia_class = (*env)->FindClass(env, "java/net/InetAddress");
- CHECK_NULL_RETURN(ia_class, NULL);
- ia_class = (*env)->NewGlobalRef(env, ia_class);
- CHECK_NULL_RETURN(ia_class, NULL);
- ia_anyLocalAddressID = (*env)->GetStaticMethodID(env,
- ia_class,
- "anyLocalAddress",
- "()Ljava/net/InetAddress;");
- CHECK_NULL_RETURN(ia_anyLocalAddressID, NULL);
- ni_class = (*env)->NewGlobalRef(env, c);
- CHECK_NULL_RETURN(ni_class, NULL);
+ index = tmp[0];
}
/*
@@ -2097,11 +1927,8 @@ jobject getMulticastInterface(JNIEnv *env, jobject this, int fd, int fd1, jint o
ni = Java_java_net_NetworkInterface_getByIndex(env, ni_class,
index);
if (ni == NULL) {
- char errmsg[255];
- sprintf(errmsg,
- "IPV6_MULTICAST_IF returned index to unrecognized interface: %d",
- index);
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", errmsg);
+ String errmsg = "IPV6_MULTICAST_IF returned index to unrecognized interface: " + index;
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", errmsg);
return NULL;
}
@@ -2115,14 +1942,14 @@ jobject getMulticastInterface(JNIEnv *env, jobject this, int fd, int fd1, jint o
/*
* For IP_MULTICAST_IF return addrs[0]
*/
- addrArray = (*env)->GetObjectField(env, ni, ni_addrsID);
- if ((*env)->GetArrayLength(env, addrArray) < 1) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+ addrArray = getNetworkInterfaceAddresses(ni);
+ if (addrArray.length < 1) {
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
"IPV6_MULTICAST_IF returned interface without IP bindings");
return NULL;
}
- addr = (*env)->GetObjectArrayElement(env, addrArray, 0);
+ addr = addrArray[0];
return addr;
}
@@ -2131,20 +1958,12 @@ jobject getMulticastInterface(JNIEnv *env, jobject this, int fd, int fd1, jint o
* or a NetworkInterface with addrs[0] set to anyLocalAddress
*/
- addr = (*env)->CallStaticObjectMethod(env, ia_class, ia_anyLocalAddressID,
- NULL);
+ addr = InetAddress.anyLocalAddress();
if (opt == java_net_SocketOptions_IP_MULTICAST_IF) {
return addr;
}
- 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, ia_class, NULL);
- CHECK_NULL_RETURN(addrArray, NULL);
- (*env)->SetObjectArrayElement(env, addrArray, 0, addr);
- (*env)->SetObjectField(env, ni, ni_addrsID, addrArray);
- return ni;
+ return new NetworkInterface(null, -1, new InetAddress[] { addr });
}
return NULL;
}
@@ -2155,24 +1974,21 @@ jobject getMulticastInterface(JNIEnv *env, jobject this, int fd, int fd1, jint o
* Method: socketGetOption
* Signature: (I)Ljava/lang/Object;
*/
-JNIEXPORT jobject JNICALL
-Java_java_net_TwoStacksPlainDatagramSocketImpl_socketGetOption(JNIEnv *env, jobject this,
- jint opt) {
-
- int fd=-1, fd1=-1;
- int level, optname, optlen;
- union {
- int i;
- } optval;
- int ipv6_supported = ipv6_available();
-
- fd = getFD(env, this);
+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);
+ fd1 = getFD1(env, _this);
}
- if (fd < 0 && fd1 < 0) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+ if (fd == null && fd1 == null) {
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
"Socket closed");
return NULL;
}
@@ -2182,29 +1998,25 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_socketGetOption(JNIEnv *env, jobj
*/
if (opt == java_net_SocketOptions_IP_MULTICAST_IF ||
opt == java_net_SocketOptions_IP_MULTICAST_IF2) {
- return getMulticastInterface(env, this, fd, fd1, opt);
+ return getMulticastInterface(env, _this, fd, fd1, opt);
}
if (opt == java_net_SocketOptions_SO_BINDADDR) {
/* find out local IP address */
SOCKETADDRESS him;
- int len = 0;
- int port;
- jobject iaObj;
-
- len = sizeof (struct sockaddr_in);
+ him = new SOCKETADDRESS();
+ InetAddress iaObj;
- if (fd == -1) {
+ if (fd == null) {
fd = fd1; /* must be IPv6 only */
- len = sizeof (struct SOCKADDR_IN6);
}
- if (getsockname(fd, (struct sockaddr *)&him, &len) == -1) {
- NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+ if (getsockname(fd, him) == -1) {
+ NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG+"SocketException",
"Error getting socket name");
return NULL;
}
- iaObj = NET_SockaddrToInetAddress(env, (struct sockaddr *)&him, &port);
+ iaObj = NET_SockaddrToInetAddress(him, new int[1]);
return iaObj;
}
@@ -2213,43 +2025,41 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_socketGetOption(JNIEnv *env, jobj
* Map the Java level socket option to the platform specific
* level and option name.
*/
- if (NET_MapSocketOption(opt, &level, &optname)) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Invalid option");
+ if (NET_MapSocketOption(opt, level, optname) != 0) {
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", "Invalid option");
return NULL;
}
- if (fd == -1) {
- if (NET_MapSocketOptionV6(opt, &level, &optname)) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Invalid option");
+ 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 */
}
- optlen = sizeof(optval.i);
- if (NET_GetSockOpt(fd, level, optname, (void *)&optval, &optlen) < 0) {
- char errmsg[255];
- sprintf(errmsg, "error getting socket option: %s\n", strerror(errno));
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", errmsg);
+ 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 createBoolean(env, optval.i);
+ return optval[0] != 0;
case java_net_SocketOptions_IP_MULTICAST_LOOP:
/* getLoopbackMode() returns true if IP_MULTICAST_LOOP is disabled */
- return createBoolean(env, !optval.i);
+ return optval[0] == 0;
case java_net_SocketOptions_SO_SNDBUF:
case java_net_SocketOptions_SO_RCVBUF:
case java_net_SocketOptions_IP_TOS:
- return createInteger(env, optval.i);
+ return optval[0];
default :
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
"Socket option not supported by TwoStacksPlainDatagramSocketImpl");
return NULL;
@@ -2261,39 +2071,34 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_socketGetOption(JNIEnv *env, jobj
* Method: setTimeToLive
* Signature: (I)V
*/
-JNIEXPORT void JNICALL
-Java_java_net_TwoStacksPlainDatagramSocketImpl_setTimeToLive(JNIEnv *env, jobject this,
- jint ttl) {
-
- jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
- jobject fd1Obj = (*env)->GetObjectField(env, this, pdsi_fd1ID);
- int fd = -1, fd1 = -1;
- int ittl = (int)ttl;
+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",
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
"Socket closed");
return;
} else {
if (!IS_NULL(fdObj)) {
- fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+ fd = fdObj.getSocket();
}
if (!IS_NULL(fd1Obj)) {
- fd1 = (*env)->GetIntField(env, fd1Obj, IO_fd_fdID);
+ fd1 = fd1Obj.getSocket();
}
}
/* setsockopt to be correct ttl */
- if (fd >= 0) {
- if (NET_SetSockOpt(fd, IPPROTO_IP, IP_MULTICAST_TTL, (char*)&ittl,
- sizeof (ittl)) < 0) {
+ if (fd != null) {
+ if (NET_SetSockOpt(fd, IPPROTO_IP, IP_MULTICAST_TTL, ttl) < 0) {
NET_ThrowCurrent(env, "set IP_MULTICAST_TTL failed");
}
}
- if (fd1 >= 0) {
- if (NET_SetSockOpt(fd1, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (char *)&ittl,
- sizeof(ittl)) <0) {
+ if (fd1 != null) {
+ if (NET_SetSockOpt(fd1, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, ttl) <0) {
NET_ThrowCurrent(env, "set IPV6_MULTICAST_HOPS failed");
}
}
@@ -2304,11 +2109,8 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_setTimeToLive(JNIEnv *env, jobjec
* Method: setTTL
* Signature: (B)V
*/
-JNIEXPORT void JNICALL
-Java_java_net_TwoStacksPlainDatagramSocketImpl_setTTL(JNIEnv *env, jobject this,
- jbyte ttl) {
- Java_java_net_TwoStacksPlainDatagramSocketImpl_setTimeToLive(env, this,
- (jint)ttl & 0xFF);
+static void setTTL(JNIEnv env, TwoStacksPlainDatagramSocketImpl _this, byte ttl) {
+ setTimeToLive(env, _this, ttl & 0xFF);
}
/*
@@ -2316,41 +2118,40 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_setTTL(JNIEnv *env, jobject this,
* Method: getTimeToLive
* Signature: ()I
*/
-JNIEXPORT jint JNICALL
-Java_java_net_TwoStacksPlainDatagramSocketImpl_getTimeToLive(JNIEnv *env, jobject this) {
- jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
- jobject fd1Obj = (*env)->GetObjectField(env, this, pdsi_fd1ID);
- int fd = -1, fd1 = -1;
- int ttl = 0;
- int len = sizeof(ttl);
+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",
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
"Socket closed");
return -1;
} else {
if (!IS_NULL(fdObj)) {
- fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+ fd = fdObj.getSocket();
}
if (!IS_NULL(fd1Obj)) {
- fd1 = (*env)->GetIntField(env, fd1Obj, IO_fd_fdID);
+ fd1 = fd1Obj.getSocket();
}
}
/* getsockopt of ttl */
- if (fd >= 0) {
- if (NET_GetSockOpt(fd, IPPROTO_IP, IP_MULTICAST_TTL, (char*)&ttl, &len) < 0) {
+ 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 (jint)ttl;
+ return ttl[0];
}
- if (fd1 >= 0) {
- if (NET_GetSockOpt(fd1, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (char*)&ttl, &len) < 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 (jint)ttl;
+ return ttl[0];
}
return -1;
}
@@ -2360,45 +2161,44 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_getTimeToLive(JNIEnv *env, jobjec
* Method: getTTL
* Signature: ()B
*/
-JNIEXPORT jbyte JNICALL
-Java_java_net_TwoStacksPlainDatagramSocketImpl_getTTL(JNIEnv *env, jobject this) {
- int result = Java_java_net_TwoStacksPlainDatagramSocketImpl_getTimeToLive(env, this);
+static byte getTTL(JNIEnv env, TwoStacksPlainDatagramSocketImpl _this) {
+ int result = getTimeToLive(env, _this);
- return (jbyte)result;
+ 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 */
-static void mcast_join_leave(JNIEnv *env, jobject this,
- jobject iaObj, jobject niObj,
- jboolean join)
+private static void mcast_join_leave(JNIEnv env, TwoStacksPlainDatagramSocketImpl _this, InetAddress iaObj, NetworkInterface niObj, boolean join)
{
- jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
- jobject fd1Obj = (*env)->GetObjectField(env, this, pdsi_fd1ID);
- jint fd = -1, fd1 = -1;
+ FileDescriptor fdObj = _this.fd;
+ FileDescriptor fd1Obj = _this.fd1;
+ cli.System.Net.Sockets.Socket fd = null;
+ cli.System.Net.Sockets.Socket fd1 = null;
SOCKETADDRESS name;
- struct ip_mreq mname;
- struct ipv6_mreq mname6;
+ name = new SOCKETADDRESS();
+ ip_mreq mname = new ip_mreq();
+ ipv6_mreq mname6 = new ipv6_mreq();
- struct in_addr in;
- DWORD ifindex;
+ in_addr in = new in_addr();
+ int ifindex;
- int len, family;
- int ipv6_supported = ipv6_available();
+ int family;
+ boolean ipv6_supported = ipv6_available();
int cmd ;
if (IS_NULL(fdObj) && IS_NULL(fd1Obj)) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
"Socket closed");
return;
}
if (!IS_NULL(fdObj)) {
- fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+ fd = fdObj.getSocket();
}
if (ipv6_supported && !IS_NULL(fd1Obj)) {
- fd1 = (*env)->GetIntField(env, fd1Obj, IO_fd_fdID);
+ fd1 = fd1Obj.getSocket();
}
if (IS_NULL(iaObj)) {
@@ -2406,7 +2206,7 @@ static void mcast_join_leave(JNIEnv *env, jobject this,
return;
}
- if (NET_InetAddressToSockaddr(env, iaObj, 0, (struct sockaddr *)&name, &len, JNI_FALSE) != 0) {
+ if (NET_InetAddressToSockaddr(env, iaObj, 0, name, JNI_FALSE) != 0) {
return;
}
@@ -2418,24 +2218,22 @@ static void mcast_join_leave(JNIEnv *env, jobject this,
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");
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", "not in multicast");
return;
}
mname.imr_multiaddr.s_addr = address;
- if (fd < 0) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Can't join an IPv4 group on an IPv6 only socket");
+ 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)) {
- len = sizeof (in);
- if (NET_GetSockOpt(fd, IPPROTO_IP, IP_MULTICAST_IF,
- (char *)&in, &len) < 0) {
+ 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) {
+ if (getInet4AddrFromIf (env, niObj, mname.imr_interface) != 0) {
NET_ThrowCurrent(env, "no Inet4Address associated with interface");
return;
}
@@ -2444,37 +2242,38 @@ static void mcast_join_leave(JNIEnv *env, jobject this,
cmd = join ? IP_ADD_MEMBERSHIP: IP_DROP_MEMBERSHIP;
/* Join the multicast group */
- if (NET_SetSockOpt(fd, IPPROTO_IP, cmd, (char *) &mname, sizeof (mname)) < 0) {
+ if (NET_SetSockOpt(fd, IPPROTO_IP, cmd, mname) < 0) {
if (WSAGetLastError() == WSAENOBUFS) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
"IP_ADD_MEMBERSHIP failed (out of hardware filters?)");
} else {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException","error setting options");
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException","error setting options");
}
}
} else /* AF_INET6 */ {
if (ipv6_supported) {
- struct in6_addr *address;
- address = &name.him6.sin6_addr;
+ in6_addr address;
+ address = in6_addr.FromSockAddr(name);
if (!IN6_IS_ADDR_MULTICAST(address)) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "not in6 multicast");
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", "not in6 multicast");
return;
}
- mname6.ipv6mr_multiaddr = *address;
+ mname6.ipv6mr_multiaddr = address;
} else {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "IPv6 not supported");
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", "IPv6 not supported");
return;
}
- if (fd1 < 0) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Can't join an IPv6 group on a IPv4 socket");
+ if (fd1 == null) {
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", "Can't join an IPv6 group on a IPv4 socket");
return;
}
if (IS_NULL(niObj)) {
- len = sizeof (ifindex);
- if (NET_GetSockOpt(fd1, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifindex, &len) < 0) {
+ 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) {
@@ -2486,12 +2285,12 @@ static void mcast_join_leave(JNIEnv *env, jobject this,
cmd = join ? IPV6_ADD_MEMBERSHIP: IPV6_DROP_MEMBERSHIP;
/* Join the multicast group */
- if (NET_SetSockOpt(fd1, IPPROTO_IPV6, cmd, (char *) &mname6, sizeof (mname6)) < 0) {
+ if (NET_SetSockOpt(fd1, IPPROTO_IPV6, cmd, mname6) < 0) {
if (WSAGetLastError() == WSAENOBUFS) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
"IP_ADD_MEMBERSHIP failed (out of hardware filters?)");
} else {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException","error setting options");
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException","error setting options");
}
}
}
@@ -2504,11 +2303,8 @@ static void mcast_join_leave(JNIEnv *env, jobject this,
* Method: join
* Signature: (Ljava/net/InetAddress;)V
*/
-JNIEXPORT void JNICALL
-Java_java_net_TwoStacksPlainDatagramSocketImpl_join(JNIEnv *env, jobject this,
- jobject iaObj, jobject niObj)
-{
- mcast_join_leave (env, this, iaObj, niObj, JNI_TRUE);
+static void join(JNIEnv env, TwoStacksPlainDatagramSocketImpl _this, InetAddress inetaddr, NetworkInterface netIf) {
+ mcast_join_leave(env, _this, inetaddr, netIf, true);
}
/*
@@ -2516,9 +2312,8 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_join(JNIEnv *env, jobject this,
* Method: leave
* Signature: (Ljava/net/InetAddress;)V
*/
-JNIEXPORT void JNICALL
-Java_java_net_TwoStacksPlainDatagramSocketImpl_leave(JNIEnv *env, jobject this,
- jobject iaObj, jobject niObj)
-{
- mcast_join_leave (env, this, iaObj, niObj, JNI_FALSE);
+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
index 9475bd3f..873d5d5f 100644
--- a/openjdk/java/net/TwoStacksPlainSocketImpl.java
+++ b/openjdk/java/net/TwoStacksPlainSocketImpl.java
@@ -37,6 +37,7 @@ import java.io.FileDescriptor;
* during socket creation.
*
* @author Chris Hegarty
+ * @author Jeroen Frijters
*/
class TwoStacksPlainSocketImpl extends AbstractPlainSocketImpl
@@ -51,7 +52,7 @@ class TwoStacksPlainSocketImpl extends AbstractPlainSocketImpl
* For ServerSockets, fd always refers to the v4 listener and
* fd1 the v6 listener.
*/
- private FileDescriptor fd1;
+ FileDescriptor fd1;
/*
* Needed for ipv6 on windows because we need to know
@@ -63,11 +64,7 @@ class TwoStacksPlainSocketImpl extends AbstractPlainSocketImpl
/* to prevent starvation when listening on two sockets, this is
* is used to hold the id of the last socket we accepted on.
*/
- private int lastfd = -1;
-
- static {
- initProto();
- }
+ cli.System.Net.Sockets.Socket lastfd = null;
public TwoStacksPlainSocketImpl() {}
@@ -173,34 +170,87 @@ class TwoStacksPlainSocketImpl extends AbstractPlainSocketImpl
}
/* 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();
+ }
- static native void initProto();
-
- native void socketCreate(boolean isServer) throws IOException;
-
- native void socketConnect(InetAddress address, int port, int timeout)
- throws IOException;
+ 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) throws IOException {
+ ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
+ TwoStacksPlainSocketImpl_c.socketBind(env, this, address, localport);
+ 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();
+ }
- native void socketBind(InetAddress address, int port)
- throws IOException;
+ void socketAccept(SocketImpl socket) throws IOException {
+ ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
+ TwoStacksPlainSocketImpl_c.socketAccept(env, this, socket);
+ env.ThrowPendingException();
+ }
- native void socketListen(int count) throws IOException;
+ 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;
+ }
- native void socketAccept(SocketImpl s) throws IOException;
+ void socketClose0(boolean useDeferredClose) throws IOException {
+ ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
+ TwoStacksPlainSocketImpl_c.socketClose0(env, this, useDeferredClose);
+ env.ThrowPendingException();
+ }
- native int socketAvailable() throws IOException;
+ void socketShutdown(int howto) throws IOException {
+ ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
+ TwoStacksPlainSocketImpl_c.socketShutdown(env, this, howto);
+ env.ThrowPendingException();
+ }
- native void socketClose0(boolean useDeferredClose) throws IOException;
+ void socketSetOption(int cmd, boolean on, Object value) throws SocketException {
+ ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
+ TwoStacksPlainSocketImpl_c.socketSetOption(env, this, cmd, on, value);
+ env.ThrowPendingException();
+ }
- native void socketShutdown(int howto) throws IOException;
+ 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;
+ }
- native void socketSetOption(int cmd, boolean on, Object value)
- throws SocketException;
+ int socketGetOption1(int opt, Object iaContainerObj, FileDescriptor fd) throws SocketException {
+ throw new UnsatisfiedLinkError();
+ }
- native int socketGetOption(int opt, Object iaContainerObj) throws SocketException;
+ void socketSendUrgentData(int data) throws IOException {
+ ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
+ TwoStacksPlainSocketImpl_c.socketSendUrgentData(env, this, data);
+ env.ThrowPendingException();
+ }
+}
- native int socketGetOption1(int opt, Object iaContainerObj, FileDescriptor fd)
- throws SocketException;
+// we don't support a dual-stack approach yet, so we simply make it an alias for the two-stacks approach
+class DualStackPlainSocketImpl extends TwoStacksPlainSocketImpl
+{
+ DualStackPlainSocketImpl() {
+ }
- native void socketSendUrgentData(int data) throws IOException;
+ DualStackPlainSocketImpl(FileDescriptor fd) {
+ super(fd);
+ }
}
diff --git a/openjdk/java/net/TwoStacksPlainSocketImpl_c.java b/openjdk/java/net/TwoStacksPlainSocketImpl_c.java
index cd694933..4764acfc 100644
--- a/openjdk/java/net/TwoStacksPlainSocketImpl_c.java
+++ b/openjdk/java/net/TwoStacksPlainSocketImpl_c.java
@@ -22,7 +22,32 @@
* CA 95054 USA or visit www.sun.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>
@@ -41,11 +66,13 @@
#include "jvm.h"
#include "net_util.h"
#include "jni_util.h"
+*/
/************************************************************************
* TwoStacksPlainSocketImpl
*/
+/*
static jfieldID IO_fd_fdID;
jfieldID psi_fdID;
@@ -57,6 +84,7 @@ jfieldID psi_timeoutID;
jfieldID psi_trafficClassID;
jfieldID psi_serverSocketID;
jfieldID psi_lastfdID;
+*/
/*
* the level of the TCP protocol for setsockopt and getsockopt
@@ -65,22 +93,22 @@ jfieldID psi_lastfdID;
*/
static int tcp_level = -1;
-static int getFD(JNIEnv *env, jobject this) {
- jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
+static cli.System.Net.Sockets.Socket getFD(JNIEnv env, TwoStacksPlainSocketImpl _this) {
+ FileDescriptor fdObj = _this.fd;
if (fdObj == NULL) {
- return -1;
+ return null;
}
- return (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+ return fdObj.getSocket();
}
-static int getFD1(JNIEnv *env, jobject this) {
- jobject fdObj = (*env)->GetObjectField(env, this, psi_fd1ID);
+static cli.System.Net.Sockets.Socket getFD1(JNIEnv env, TwoStacksPlainSocketImpl _this) {
+ FileDescriptor fdObj = _this.fd1;
if (fdObj == NULL) {
- return -1;
+ return null;
}
- return (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+ return fdObj.getSocket();
}
@@ -94,6 +122,7 @@ static int getFD1(JNIEnv *env, jobject this) {
* Signature: ()V
*/
+/*
JNIEXPORT void JNICALL
Java_java_net_TwoStacksPlainSocketImpl_initProto(JNIEnv *env, jclass cls) {
@@ -123,55 +152,53 @@ Java_java_net_TwoStacksPlainSocketImpl_initProto(JNIEnv *env, jclass cls) {
IO_fd_fdID = NET_GetFileDescriptorID(env);
CHECK_NULL(IO_fd_fdID);
}
+*/
/*
* Class: java_net_TwoStacksPlainSocketImpl
* Method: socketCreate
* Signature: (Z)V
*/
-JNIEXPORT void JNICALL
-Java_java_net_TwoStacksPlainSocketImpl_socketCreate(JNIEnv *env, jobject this,
- jboolean stream) {
- jobject fdObj, fd1Obj;
- int fd, fd1;
-
- fdObj = (*env)->GetObjectField(env, this, psi_fdID);
+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",
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
"null fd object");
return;
}
fd = socket(AF_INET, (stream ? SOCK_STREAM: SOCK_DGRAM), 0);
- if (fd == -1) {
+ 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);
- (*env)->SetIntField(env, fdObj, IO_fd_fdID, (int)fd);
+ //SetHandleInformation((HANDLE)(UINT_PTR)fd, HANDLE_FLAG_INHERIT, FALSE);
+ fdObj.setSocket(fd);
}
if (ipv6_available()) {
- fd1Obj = (*env)->GetObjectField(env, this, psi_fd1ID);
if (IS_NULL(fd1Obj)) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
"null fd1 object");
- (*env)->SetIntField(env, fdObj, IO_fd_fdID, -1);
+ fdObj.setSocket(null);
NET_SocketClose(fd);
return;
}
fd1 = socket(AF_INET6, (stream ? SOCK_STREAM: SOCK_DGRAM), 0);
- if (fd1 == -1) {
+ if (fd1 == INVALID_SOCKET) {
NET_ThrowCurrent(env, "create");
- (*env)->SetIntField(env, fdObj, IO_fd_fdID, -1);
+ fdObj.setSocket(null);
NET_SocketClose(fd);
return;
} else {
- (*env)->SetIntField(env, fd1Obj, IO_fd_fdID, fd1);
+ fd1Obj.setSocket(fd1);
}
} else {
- (*env)->SetObjectField(env, this, psi_fd1ID, NULL);
+ _this.fd1 = null;
}
}
@@ -183,37 +210,35 @@ Java_java_net_TwoStacksPlainSocketImpl_socketCreate(JNIEnv *env, jobject this,
* Method: socketConnect
* Signature: (Ljava/net/InetAddress;I)V
*/
-JNIEXPORT void JNICALL
-Java_java_net_TwoStacksPlainSocketImpl_socketConnect(JNIEnv *env, jobject this,
- jobject iaObj, jint port,
- jint timeout)
+static void socketConnect(JNIEnv env, TwoStacksPlainSocketImpl _this, InetAddress iaObj, int port, int timeout)
{
- jint localport = (*env)->GetIntField(env, this, psi_localportID);
+ int localport = _this.localport;
/* family and localport are int fields of iaObj */
int family;
- jint fd, fd1=-1;
- jint len;
- int ipv6_supported = ipv6_available();
+ 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.
*/
- jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
- jobject fd1Obj = (*env)->GetObjectField(env, this, psi_fd1ID);
+ 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 = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+ fd = fdObj.getSocket();
}
if (ipv6_supported && !IS_NULL(fd1Obj)) {
- fd1 = (*env)->GetIntField(env, fd1Obj, IO_fd_fdID);
+ fd1 = fd1Obj.getSocket();
}
if (IS_NULL(iaObj)) {
@@ -221,67 +246,67 @@ Java_java_net_TwoStacksPlainSocketImpl_socketConnect(JNIEnv *env, jobject this,
return;
}
- if (NET_InetAddressToSockaddr(env, iaObj, port, (struct sockaddr *)&him, &len, JNI_FALSE) != 0) {
+ 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",
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
"Protocol family not supported");
return;
} else {
- if (fd1 == -1) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+ if (fd1 == null) {
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
"Destination unreachable");
return;
}
/* close the v4 socket, and set fd to be the v6 socket */
- (*env)->SetObjectField(env, this, psi_fdID, fd1Obj);
- (*env)->SetObjectField(env, this, psi_fd1ID, NULL);
+ _this.fd = fd1Obj;
+ _this.fd1 = null;
NET_SocketClose(fd);
fd = fd1; fdObj = fd1Obj;
}
} else {
- if (fd1 != -1) {
- (*env)->SetIntField(env, fd1Obj, IO_fd_fdID, -1);
+ if (fd1 != null) {
+ fd1Obj.setSocket(null);
NET_SocketClose(fd1);
}
- if (fd == -1) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+ if (fd == null) {
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
"Destination unreachable");
return;
}
}
- (*env)->SetObjectField(env, this, psi_fd1ID, NULL);
+ _this.fd1 = null;
if (timeout <= 0) {
- connect_res = connect(fd, (struct sockaddr *) &him, SOCKETADDRESS_LEN(&him));
+ connect_res = connect(fd, him);
if (connect_res == SOCKET_ERROR) {
connect_res = WSAGetLastError();
}
} else {
int optval;
- int optlen = sizeof(optval);
/* make socket non-blocking */
optval = 1;
- ioctlsocket( fd, FIONBIO, &optval );
+ ioctlsocket( fd, FIONBIO, optval );
/* initiate the connect */
- connect_res = connect(fd, (struct sockaddr *) &him, SOCKETADDRESS_LEN(&him));
+ connect_res = connect(fd, him);
if (connect_res == SOCKET_ERROR) {
if (WSAGetLastError() != WSAEWOULDBLOCK) {
connect_res = WSAGetLastError();
} else {
fd_set wr, ex;
- struct timeval t;
+ wr = new fd_set(); ex = new fd_set();
+ timeval t = new timeval();
- FD_ZERO(&wr);
- FD_ZERO(&ex);
- FD_SET(fd, &wr);
- FD_SET(fd, &ex);
+ FD_ZERO(wr);
+ FD_ZERO(ex);
+ FD_SET(fd, wr);
+ FD_SET(fd, ex);
t.tv_sec = timeout / 1000;
t.tv_usec = (timeout % 1000) * 1000;
@@ -289,7 +314,7 @@ Java_java_net_TwoStacksPlainSocketImpl_socketConnect(JNIEnv *env, jobject this,
* Wait for timout, connection established or
* connection failed.
*/
- connect_res = select(fd+1, 0, &wr, &ex, &t);
+ connect_res = select(null, wr, ex, t);
/*
* Timeout before connection is established/failed so
@@ -298,13 +323,13 @@ Java_java_net_TwoStacksPlainSocketImpl_socketConnect(JNIEnv *env, jobject this,
* The socket should be closed immediately by the caller.
*/
if (connect_res == 0) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
+ 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 );
+ ioctlsocket( fd, FIONBIO, optval );
return;
}
@@ -317,21 +342,23 @@ Java_java_net_TwoStacksPlainSocketImpl_socketConnect(JNIEnv *env, jobject this,
* 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)) {
+ 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,
- (char*)&connect_res, &optlen);
- if (connect_res) {
+ tmp);
+ connect_res = tmp[0];
+ if (connect_res != 0) {
break;
}
Sleep(0);
}
if (connect_res == 0) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
"Unable to establish connection");
return;
}
@@ -341,12 +368,12 @@ Java_java_net_TwoStacksPlainSocketImpl_socketConnect(JNIEnv *env, jobject this,
/* make socket blocking again */
optval = 0;
- ioctlsocket(fd, FIONBIO, &optval);
+ ioctlsocket(fd, FIONBIO, optval);
}
- if (connect_res) {
+ if (connect_res != 0) {
if (connect_res == WSAEADDRNOTAVAIL) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "ConnectException",
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"ConnectException",
"connect: Address is invalid on local machine, or port is not valid on remote machine");
} else {
NET_ThrowNew(env, connect_res, "connect");
@@ -354,11 +381,11 @@ Java_java_net_TwoStacksPlainSocketImpl_socketConnect(JNIEnv *env, jobject this,
return;
}
- (*env)->SetIntField(env, fdObj, IO_fd_fdID, (int)fd);
+ fdObj.setSocket(fd);
/* set the remote peer address and port */
- (*env)->SetObjectField(env, this, psi_addressID, iaObj);
- (*env)->SetIntField(env, this, psi_portID, port);
+ _this.address = iaObj;
+ _this.port = port;
/*
* we need to initialize the local port field if bind was called
@@ -369,20 +396,18 @@ Java_java_net_TwoStacksPlainSocketImpl_socketConnect(JNIEnv *env, jobject this,
/* 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.
*/
- u_short port;
- int len = SOCKETADDRESS_LEN(&him);
- if (getsockname(fd, (struct sockaddr *)&him, &len) == -1) {
+ if (getsockname(fd, him) == -1) {
if (WSAGetLastError() == WSAENOTSOCK) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
"Socket closed");
} else {
NET_ThrowCurrent(env, "getsockname failed");
}
return;
}
- port = ntohs ((u_short)GET_PORT(&him));
- (*env)->SetIntField(env, this, psi_localportID, (int) port);
+ port = ntohs (GET_PORT(him));
+ _this.localport = port;
}
}
@@ -391,41 +416,36 @@ Java_java_net_TwoStacksPlainSocketImpl_socketConnect(JNIEnv *env, jobject this,
* Method: socketBind
* Signature: (Ljava/net/InetAddress;I)V
*/
-JNIEXPORT void JNICALL
-Java_java_net_TwoStacksPlainSocketImpl_socketBind(JNIEnv *env, jobject this,
- jobject iaObj, jint localport) {
-
- /* fdObj is the FileDescriptor field on this */
- jobject fdObj, fd1Obj;
- /* fd is an int field on fdObj */
- int fd, fd1, len;
- int ipv6_supported = ipv6_available();
+static void socketBind(JNIEnv env, TwoStacksPlainSocketImpl _this, InetAddress iaObj, int localport) {
+ 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();
- fdObj = (*env)->GetObjectField(env, this, psi_fdID);
- fd1Obj = (*env)->GetObjectField(env, this, psi_fd1ID);
-
- family = (*env)->GetIntField(env, iaObj, ia_familyID);
+ family = iaObj.family;
if (family == IPv6 && !ipv6_supported) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+ 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",
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
"Socket closed");
return;
} else {
- fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+ fd = fdObj.getSocket();
if (ipv6_supported) {
- fd1 = (*env)->GetIntField(env, fd1Obj, IO_fd_fdID);
+ fd1 = fd1Obj.getSocket();
}
}
if (IS_NULL(iaObj)) {
@@ -434,41 +454,41 @@ Java_java_net_TwoStacksPlainSocketImpl_socketBind(JNIEnv *env, jobject this,
}
if (NET_InetAddressToSockaddr(env, iaObj, localport,
- (struct sockaddr *)&him, &len, JNI_FALSE) != 0) {
+ him, JNI_FALSE) != 0) {
return;
}
if (ipv6_supported) {
- struct ipv6bind v6bind;
- v6bind.addr = &him;
+ ipv6bind v6bind = new ipv6bind();
+ v6bind.addr = him;
v6bind.ipv4_fd = fd;
v6bind.ipv6_fd = fd1;
- rv = NET_BindV6(&v6bind);
+ rv = NET_BindV6(v6bind);
if (rv != -1) {
/* check if the fds have changed */
if (v6bind.ipv4_fd != fd) {
fd = v6bind.ipv4_fd;
- if (fd == -1) {
+ if (fd == null) {
/* socket is closed. */
- (*env)->SetObjectField(env, this, psi_fdID, NULL);
+ _this.fd = null;
} else {
/* socket was re-created */
- (*env)->SetIntField(env, fdObj, IO_fd_fdID, fd);
+ fdObj.setSocket(fd);
}
}
if (v6bind.ipv6_fd != fd1) {
fd1 = v6bind.ipv6_fd;
- if (fd1 == -1) {
+ if (fd1 == null) {
/* socket is closed. */
- (*env)->SetObjectField(env, this, psi_fd1ID, NULL);
+ _this.fd1 = null;
} else {
/* socket was re-created */
- (*env)->SetIntField(env, fd1Obj, IO_fd_fdID, fd1);
+ fd1Obj.setSocket(fd1);
}
}
}
} else {
- rv = NET_Bind(fd, (struct sockaddr *)&him, len);
+ rv = NET_Bind(fd, him);
}
if (rv == -1) {
@@ -477,26 +497,25 @@ Java_java_net_TwoStacksPlainSocketImpl_socketBind(JNIEnv *env, jobject this,
}
/* set the address */
- (*env)->SetObjectField(env, this, psi_addressID, iaObj);
+ _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 len = SOCKETADDRESS_LEN(&him);
- u_short port;
+ int port;
fd = him.him.sa_family == AF_INET? fd: fd1;
- if (getsockname(fd, (struct sockaddr *)&him, &len) == -1) {
+ if (getsockname(fd, him) == -1) {
NET_ThrowCurrent(env, "getsockname in plain socketBind");
return;
}
- port = ntohs ((u_short) GET_PORT (&him));
+ port = ntohs (GET_PORT (him));
- (*env)->SetIntField(env, this, psi_localportID, (int) port);
+ _this.localport = port;
} else {
- (*env)->SetIntField(env, this, psi_localportID, localport);
+ _this.localport = localport;
}
}
@@ -505,52 +524,51 @@ Java_java_net_TwoStacksPlainSocketImpl_socketBind(JNIEnv *env, jobject this,
* Method: socketListen
* Signature: (I)V
*/
-JNIEXPORT void JNICALL
-Java_java_net_TwoStacksPlainSocketImpl_socketListen (JNIEnv *env, jobject this,
- jint count)
+static void socketListen (JNIEnv env, TwoStacksPlainSocketImpl _this, int count)
{
/* this FileDescriptor fd field */
- jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
- jobject fd1Obj = (*env)->GetObjectField(env, this, psi_fd1ID);
- jobject address;
+ FileDescriptor fdObj = _this.fd;
+ FileDescriptor fd1Obj = _this.fd1;
+ InetAddress address;
/* fdObj's int fd field */
- int fd, fd1;
- SOCKETADDRESS addr; int addrlen;
+ 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",
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
"socket closed");
return;
}
if (!IS_NULL(fdObj)) {
- fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+ 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 = (*env)->GetObjectField(env, this, psi_addressID);
+ address = _this.address;
if (IS_NULL(address)) {
JNU_ThrowNullPointerException(env, "socket address");
return;
}
- if (NET_InetAddressToSockaddr(env, address, 0, (struct sockaddr *)&addr,
- &addrlen, JNI_FALSE) != 0) {
+ if (NET_InetAddressToSockaddr(env, address, 0, addr,
+ JNI_FALSE) != 0) {
return;
}
- if (addr.him.sa_family == AF_INET || IN6ADDR_ISANY(&addr.him6)) {
+ 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);
- (*env)->SetObjectField(env, this, psi_fdID, NULL);
+ _this.fd = null;
}
if (ipv6_available() && !IS_NULL(fd1Obj)) {
- fd1 = (*env)->GetIntField(env, fd1Obj, IO_fd_fdID);
+ 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) {
@@ -558,7 +576,7 @@ Java_java_net_TwoStacksPlainSocketImpl_socketListen (JNIEnv *env, jobject this,
}
} else {
NET_SocketClose (fd1);
- (*env)->SetObjectField(env, this, psi_fd1ID, NULL);
+ _this.fd1 = null;
}
}
}
@@ -568,200 +586,139 @@ Java_java_net_TwoStacksPlainSocketImpl_socketListen (JNIEnv *env, jobject this,
* Method: socketAccept
* Signature: (Ljava/net/SocketImpl;)V
*/
-JNIEXPORT void JNICALL
-Java_java_net_TwoStacksPlainSocketImpl_socketAccept(JNIEnv *env, jobject this,
- jobject socket)
+static void socketAccept(JNIEnv env, TwoStacksPlainSocketImpl _this, SocketImpl socket)
{
/* fields on this */
- jint port;
- jint timeout = (*env)->GetIntField(env, this, psi_timeoutID);
- jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
- jobject fd1Obj = (*env)->GetObjectField(env, this, psi_fd1ID);
+ int port;
+ int timeout = _this.timeout;
+ FileDescriptor fdObj = _this.fd;
+ FileDescriptor fd1Obj = _this.fd1;
/* the FileDescriptor field on socket */
- jobject socketFdObj;
-
- /* cache the Inet4/6Address classes */
- static jclass inet4Cls;
- static jclass inet6Cls;
+ FileDescriptor socketFdObj;
/* the InetAddress field on socket */
- jobject socketAddressObj;
+ InetAddress socketAddressObj;
/* the fd int field on fdObj */
- jint fd=-1, fd1=-1;
+ cli.System.Net.Sockets.Socket fd=null, fd1=null;
SOCKETADDRESS him;
- jint len;
+ him = new SOCKETADDRESS();
if (IS_NULL(fdObj) && IS_NULL(fd1Obj)) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
"Socket closed");
return;
}
if (!IS_NULL(fdObj)) {
- fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+ fd = fdObj.getSocket();
}
if (!IS_NULL(fd1Obj)) {
- fd1 = (*env)->GetIntField(env, fd1Obj, IO_fd_fdID);
+ fd1 = fd1Obj.getSocket();
}
if (IS_NULL(socket)) {
JNU_ThrowNullPointerException(env, "socket is null");
return;
} else {
- socketFdObj = (*env)->GetObjectField(env, socket, psi_fdID);
- socketAddressObj = (*env)->GetObjectField(env, socket, psi_addressID);
+ socketFdObj = socket.fd;
+ socketAddressObj = socket.address;
}
if ((IS_NULL(socketAddressObj)) || (IS_NULL(socketFdObj))) {
JNU_ThrowNullPointerException(env, "socket address or fd obj");
return;
}
- if (fd != -1 && fd1 != -1) {
- fd_set rfds;
- struct timeval t, *tP=&t;
- int lastfd, res, fd2;
- FD_ZERO(&rfds);
- FD_SET(fd,&rfds);
- FD_SET(fd1,&rfds);
- if (timeout) {
+ 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 {
- tP = NULL;
+ t = null;
}
- res = select (fd, &rfds, NULL, NULL, tP);
+ int res = select (rfds, null, null, t);
if (res == 0) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketTimeoutException",
"Accept timed out");
return;
} else if (res == 1) {
- fd2 = FD_ISSET(fd, &rfds)? fd: fd1;
+ fd2 = FD_ISSET(fd, rfds)? fd: fd1;
} else if (res == 2) {
/* avoid starvation */
- lastfd = (*env)->GetIntField(env, this, psi_lastfdID);
- if (lastfd != -1) {
+ lastfd = _this.lastfd;
+ if (lastfd != null) {
fd2 = lastfd==fd? fd1: fd;
} else {
fd2 = fd;
}
- (*env)->SetIntField(env, this, psi_lastfdID, fd2);
+ _this.lastfd = fd2;
} else {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
"select failed");
return;
}
- if (fd2 == fd) { /* v4 */
- len = sizeof (struct sockaddr_in);
- } else {
- len = sizeof (struct SOCKADDR_IN6);
- }
fd = fd2;
} else {
int ret;
- if (fd1 != -1) {
+ if (fd1 != null) {
fd = fd1;
- len = sizeof (struct SOCKADDR_IN6);
- } else {
- len = sizeof (struct sockaddr_in);
}
- if (timeout) {
+ if (timeout != 0) {
ret = NET_Timeout(fd, timeout);
if (ret == 0) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketTimeoutException",
"Accept timed out");
return;
} else if (ret == -1) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "socket closed");
+ 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",
+ JNU_ThrowByName(env, JNU_JAVAIOPKG+"InterruptedIOException",
"operation interrupted");
return;
}
}
}
- fd = accept(fd, (struct sockaddr *)&him, &len);
- if (fd < 0) {
+ fd = accept(fd, him);
+ if (fd == null) {
/* REMIND: SOCKET CLOSED PROBLEM */
- if (fd == -2) {
- JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
+ if (false) {
+ JNU_ThrowByName(env, JNU_JAVAIOPKG+"InterruptedIOException",
"operation interrupted");
} else {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
"socket closed");
}
return;
}
- (*env)->SetIntField(env, socketFdObj, IO_fd_fdID, fd);
+ socketFdObj.setSocket(fd);
if (him.him.sa_family == AF_INET) {
- if (inet4Cls == NULL) {
- jclass c = (*env)->FindClass(env, "java/net/Inet4Address");
- if (c != NULL) {
- inet4Cls = (*env)->NewGlobalRef(env, c);
- (*env)->DeleteLocalRef(env, c);
- }
- }
/*
* fill up the remote peer port and address in the new socket structure
*/
- if (inet4Cls != NULL) {
- socketAddressObj = (*env)->NewObject(env, inet4Cls, ia4_ctrID);
- } else {
- socketAddressObj = NULL;
- }
- if (socketAddressObj == NULL) {
- /*
- * FindClass or NewObject failed so close connection and
- * exist (there will be a pending exception).
- */
- NET_SocketClose(fd);
- return;
- }
-
- (*env)->SetIntField(env, socketAddressObj, ia_addressID,
- ntohl(him.him4.sin_addr.s_addr));
- (*env)->SetIntField(env, socketAddressObj, ia_familyID, IPv4);
- (*env)->SetObjectField(env, socket, psi_addressID, socketAddressObj);
+ socketAddressObj = new Inet4Address(null, ntohl(him.him4.sin_addr.s_addr));
+ socket.address = socketAddressObj;
} else {
- jbyteArray addr;
/* AF_INET6 -> Inet6Address */
- if (inet6Cls == 0) {
- jclass c = (*env)->FindClass(env, "java/net/Inet6Address");
- if (c != NULL) {
- inet6Cls = (*env)->NewGlobalRef(env, c);
- (*env)->DeleteLocalRef(env, c);
- }
- }
- if (inet6Cls != NULL) {
- socketAddressObj = (*env)->NewObject(env, inet6Cls, ia6_ctrID);
- } else {
- socketAddressObj = NULL;
- }
- if (socketAddressObj == NULL) {
- /*
- * FindClass or NewObject failed so close connection and
- * exist (there will be a pending exception).
- */
- NET_SocketClose(fd);
- return;
- }
- addr = (*env)->GetObjectField (env, socketAddressObj, ia6_ipaddressID);
- (*env)->SetByteArrayRegion (env, addr, 0, 16, (const char *)&him.him6.sin6_addr);
- (*env)->SetIntField(env, socketAddressObj, ia_familyID, IPv6);
- (*env)->SetIntField(env, socketAddressObj, ia6_scopeidID, him.him6.sin6_scope_id);
+ socketAddressObj = new Inet6Address(null, him.him6.sin6_addr, him.him6.sin6_scope_id);
}
/* fields common to AF_INET and AF_INET6 */
- port = ntohs ((u_short) GET_PORT (&him));
- (*env)->SetIntField(env, socket, psi_portID, (int)port);
- port = (*env)->GetIntField(env, this, psi_localportID);
- (*env)->SetIntField(env, socket, psi_localportID, port);
- (*env)->SetObjectField(env, socket, psi_addressID, socketAddressObj);
+ port = ntohs (GET_PORT (him));
+ socket.port = port;
+ port = _this.localport;
+ socket.localport = port;
+ socket.address = socketAddressObj;
}
/*
@@ -769,26 +726,25 @@ Java_java_net_TwoStacksPlainSocketImpl_socketAccept(JNIEnv *env, jobject this,
* Method: socketAvailable
* Signature: ()I
*/
-JNIEXPORT jint JNICALL
-Java_java_net_TwoStacksPlainSocketImpl_socketAvailable(JNIEnv *env, jobject this) {
+static int socketAvailable(JNIEnv env, TwoStacksPlainSocketImpl _this) {
- jint available = -1;
- jint res;
- jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
- jint fd;
+ 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");
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", "Socket closed");
return -1;
} else {
- fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+ fd = fdObj.getSocket();
}
- res = ioctlsocket(fd, FIONREAD, &available);
+ 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;
+ return available[0];
}
/*
@@ -796,31 +752,30 @@ Java_java_net_TwoStacksPlainSocketImpl_socketAvailable(JNIEnv *env, jobject this
* Method: socketClose
* Signature: ()V
*/
-JNIEXPORT void JNICALL
-Java_java_net_TwoStacksPlainSocketImpl_socketClose0(JNIEnv *env, jobject this,
- jboolean useDeferredClose) {
+static void socketClose0(JNIEnv env, TwoStacksPlainSocketImpl _this, boolean useDeferredClose) {
- jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
- jobject fd1Obj = (*env)->GetObjectField(env, this, psi_fd1ID);
- jint fd=-1, fd1=-1;
+ 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",
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
"socket already closed");
return;
}
if (!IS_NULL(fdObj)) {
- fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+ fd = fdObj.getSocket();
}
if (!IS_NULL(fd1Obj)) {
- fd1 = (*env)->GetIntField(env, fd1Obj, IO_fd_fdID);
+ fd1 = fd1Obj.getSocket();
}
- if (fd != -1) {
- (*env)->SetIntField(env, fdObj, IO_fd_fdID, -1);
+ if (fd != null) {
+ fdObj.setSocket(null);
NET_SocketClose(fd);
}
- if (fd1 != -1) {
- (*env)->SetIntField(env, fd1Obj, IO_fd_fdID, -1);
+ if (fd1 != null) {
+ fd1Obj.setSocket(null);
NET_SocketClose(fd1);
}
}
@@ -833,24 +788,19 @@ Java_java_net_TwoStacksPlainSocketImpl_socketClose0(JNIEnv *env, jobject this,
* Method: socketSetOption
* Signature: (IZLjava/lang/Object;)V
*/
-JNIEXPORT void JNICALL
-Java_java_net_TwoStacksPlainSocketImpl_socketSetOption(JNIEnv *env, jobject this,
- jint cmd, jboolean on,
- jobject value) {
- int fd, fd1;
- int level, optname, optlen;
- union {
- int i;
- struct linger ling;
- } optval;
+static void socketSetOption(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 < 0 && fd1 < 0) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
+ fd = getFD(env, _this);
+ fd1 = getFD1(env, _this);
+ if (fd == null && fd1 == null) {
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", "Socket closed");
return;
}
@@ -869,7 +819,7 @@ Java_java_net_TwoStacksPlainSocketImpl_socketSetOption(JNIEnv *env, jobject this
* Don't enable the socket option on ServerSocket as it's
* meaningless (we don't receive on a ServerSocket).
*/
- jobject ssObj = (*env)->GetObjectField(env, this, psi_serverSocketID);
+ Object ssObj = _this.serverSocket;
if (ssObj != NULL) {
return;
}
@@ -881,14 +831,7 @@ Java_java_net_TwoStacksPlainSocketImpl_socketSetOption(JNIEnv *env, jobject this
* select() -- see SocketInputStream.socketRead.
*/
if (isRcvTimeoutSupported) {
- jclass iCls = (*env)->FindClass(env, "java/lang/Integer");
- jfieldID i_valueID;
- jint timeout;
-
- CHECK_NULL(iCls);
- i_valueID = (*env)->GetFieldID(env, iCls, "value", "I");
- CHECK_NULL(i_valueID);
- timeout = (*env)->GetIntField(env, value, i_valueID);
+ int timeout = ((Integer)value).intValue();
/*
* Disable SO_RCVTIMEO if timeout is <= 5 second.
@@ -897,17 +840,15 @@ Java_java_net_TwoStacksPlainSocketImpl_socketSetOption(JNIEnv *env, jobject this
timeout = 0;
}
- if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout,
- sizeof(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 != -1) {
- if (setsockopt(fd1, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout,
- sizeof(timeout)) < 0) {
+ if (fd1 != null) {
+ if (setsockopt(fd1, SOL_SOCKET, SO_RCVTIMEO, timeout) < 0) {
NET_ThrowCurrent(env, "setsockopt SO_RCVTIMEO");
}
}
@@ -919,8 +860,8 @@ Java_java_net_TwoStacksPlainSocketImpl_socketSetOption(JNIEnv *env, jobject this
* Map the Java level socket option to the platform specific
* level
*/
- if (NET_MapSocketOption(cmd, &level, &optname)) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+ if (NET_MapSocketOption(cmd, level, optname) != 0) {
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
"Invalid option");
return;
}
@@ -931,62 +872,43 @@ Java_java_net_TwoStacksPlainSocketImpl_socketSetOption(JNIEnv *env, jobject this
case java_net_SocketOptions_SO_OOBINLINE :
case java_net_SocketOptions_SO_KEEPALIVE :
case java_net_SocketOptions_SO_REUSEADDR :
- optval.i = (on ? 1 : 0);
- optlen = sizeof(optval.i);
+ optval = on;
break;
case java_net_SocketOptions_SO_SNDBUF :
case java_net_SocketOptions_SO_RCVBUF :
case java_net_SocketOptions_IP_TOS :
- {
- jclass cls;
- jfieldID fid;
-
- cls = (*env)->FindClass(env, "java/lang/Integer");
- CHECK_NULL(cls);
- fid = (*env)->GetFieldID(env, cls, "value", "I");
- CHECK_NULL(fid);
-
- optval.i = (*env)->GetIntField(env, value, fid);
- optlen = sizeof(optval.i);
- }
+ optval = ((Integer)value).intValue();
break;
case java_net_SocketOptions_SO_LINGER :
{
- jclass cls;
- jfieldID fid;
-
- cls = (*env)->FindClass(env, "java/lang/Integer");
- CHECK_NULL(cls);
- fid = (*env)->GetFieldID(env, cls, "value", "I");
- CHECK_NULL(fid);
-
+ linger ling = new linger();
if (on) {
- optval.ling.l_onoff = 1;
- optval.ling.l_linger = (*env)->GetIntField(env, value, fid);
+ ling.l_onoff = 1;
+ ling.l_linger = ((Integer)value).intValue();
} else {
- optval.ling.l_onoff = 0;
- optval.ling.l_linger = 0;
+ ling.l_onoff = 0;
+ ling.l_linger = 0;
}
- optlen = sizeof(optval.ling);
+ optval = ling;
}
break;
default: /* shouldn't get here */
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
"Option not supported by TwoStacksPlainSocketImpl");
return;
}
- if (fd != -1) {
- if (NET_SetSockOpt(fd, level, optname, (void *)&optval, optlen) < 0) {
+ if (fd != null) {
+ if (NET_SetSockOpt(fd, level[0], optname[0], optval) < 0) {
NET_ThrowCurrent(env, "setsockopt");
}
}
- if (fd1 != -1) {
- if (NET_SetSockOpt(fd1, level, optname, (void *)&optval, optlen) < 0) {
+ if (fd1 != null) {
+ if (NET_SetSockOpt(fd1, level[0], optname[0], optval) < 0) {
NET_ThrowCurrent(env, "setsockopt");
}
}
@@ -998,28 +920,24 @@ Java_java_net_TwoStacksPlainSocketImpl_socketSetOption(JNIEnv *env, jobject this
* Method: socketGetOption
* Signature: (I)I
*/
-JNIEXPORT jint JNICALL
-Java_java_net_TwoStacksPlainSocketImpl_socketGetOption(JNIEnv *env, jobject this,
- jint opt, jobject iaContainerObj) {
+static int socketGetOption(JNIEnv env, TwoStacksPlainSocketImpl _this, int opt, Object iaContainerObj) {
- int fd, fd1;
- int level, optname, optlen;
- union {
- int i;
- struct linger ling;
- } optval;
+ 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);
+ fd = getFD(env, _this);
+ fd1 = getFD1(env, _this);
- if (fd < 0 && fd1 < 0) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
+ if (fd == null && fd1 == null) {
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", "Socket closed");
return -1;
}
- if (fd < 0) {
+ if (fd == null) {
fd = fd1;
}
@@ -1029,35 +947,25 @@ Java_java_net_TwoStacksPlainSocketImpl_socketGetOption(JNIEnv *env, jobject this
* SO_BINDADDR isn't a socket option
*/
if (opt == java_net_SocketOptions_SO_BINDADDR) {
- SOCKET_ADDRESS him;
- int len;
- int port;
- jobject iaObj;
- jclass iaCntrClass;
- jfieldID iaFieldID;
-
- len = sizeof(struct sockaddr_in);
+ SOCKETADDRESS him;
+ him = new SOCKETADDRESS();
+ int[] port = { 0 };
+ InetAddress iaObj;
- if (fd == -1) {
+ if (fd == null) {
/* must be an IPV6 only socket. Case where both sockets are != -1
* is handled in java
*/
- fd = getFD1 (env, this);
- len = sizeof(struct SOCKADDR_IN6);
+ fd = getFD1 (env, _this);
}
- if (getsockname(fd, (struct sockaddr *)&him, &len) < 0) {
- NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+ if (getsockname(fd, him) < 0) {
+ NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG+"SocketException",
"Error getting socket name");
return -1;
}
- iaObj = NET_SockaddrToInetAddress(env, (struct sockaddr *)&him, &port);
- CHECK_NULL_RETURN(iaObj, -1);
-
- iaCntrClass = (*env)->GetObjectClass(env, iaContainerObj);
- iaFieldID = (*env)->GetFieldID(env, iaCntrClass, "addr", "Ljava/net/InetAddress;");
- CHECK_NULL_RETURN(iaFieldID, -1);
- (*env)->SetObjectField(env, iaContainerObj, iaFieldID, iaObj);
+ iaObj = NET_SockaddrToInetAddress(him, port);
+ ((InetAddressContainer)iaContainerObj).addr = iaObj;
return 0; /* notice change from before */
}
@@ -1065,8 +973,8 @@ Java_java_net_TwoStacksPlainSocketImpl_socketGetOption(JNIEnv *env, jobject this
* Map the Java level socket option to the platform specific
* level and option name.
*/
- if (NET_MapSocketOption(opt, &level, &optname)) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Invalid option");
+ if (NET_MapSocketOption(opt, level, optname) != 0) {
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", "Invalid option");
return -1;
}
@@ -1074,34 +982,33 @@ Java_java_net_TwoStacksPlainSocketImpl_socketGetOption(JNIEnv *env, jobject this
* Args are int except for SO_LINGER
*/
if (opt == java_net_SocketOptions_SO_LINGER) {
- optlen = sizeof(optval.ling);
+ optval = new linger();
} else {
- optlen = sizeof(optval.i);
- optval.i = 0;
+ optval = new int[1];
}
- if (NET_GetSockOpt(fd, level, optname, (void *)&optval, &optlen) < 0) {
+ 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 (optval.ling.l_onoff ? optval.ling.l_linger: -1);
+ 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 optval.i;
+ 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 (optval.i == 0) ? -1 : 1;
+ return (((int[])optval)[0] == 0) ? -1 : 1;
default: /* shouldn't get here */
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
"Option not supported by TwoStacksPlainSocketImpl");
return -1;
}
@@ -1112,24 +1019,22 @@ Java_java_net_TwoStacksPlainSocketImpl_socketGetOption(JNIEnv *env, jobject this
* Method: socketShutdown
* Signature: (I)V
*/
-JNIEXPORT void JNICALL
-Java_java_net_TwoStacksPlainSocketImpl_socketShutdown(JNIEnv *env, jobject this,
- jint howto)
+static void socketShutdown(JNIEnv env, TwoStacksPlainSocketImpl _this, int howto)
{
- jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
- jint fd;
+ 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",
+ JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException",
"socket already closed");
return;
} else {
- fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+ fd = fdObj.getSocket();
}
shutdown(fd, howto);
}
@@ -1139,35 +1044,34 @@ Java_java_net_TwoStacksPlainSocketImpl_socketShutdown(JNIEnv *env, jobject this,
* Method: socketSendUrgentData
* Signature: (B)V
*/
-JNIEXPORT void JNICALL
-Java_java_net_TwoStacksPlainSocketImpl_socketSendUrgentData(JNIEnv *env, jobject this,
- jint data) {
+static void socketSendUrgentData(JNIEnv env, TwoStacksPlainSocketImpl _this, int data) {
/* The fd field */
- jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
- int n, fd;
- unsigned char d = data & 0xff;
+ 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 = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+ 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 == -1) {
+ if (fd == null) {
JNU_ThrowByName(env, "java/net/SocketException", "Socket closed");
return;
}
}
- n = send(fd, (char *)&data, 1, MSG_OOB);
+ 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", 0);
+ 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
new file mode 100644
index 00000000..be3d368c
--- /dev/null
+++ b/openjdk/java/net/net_util_md.java
@@ -0,0 +1,824 @@
+/*
+ * Copyright 1997-2007 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.net;
+
+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;
+ }
+
+ 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;
+ }
+
+ /*
+ * 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 = 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;
+ }
+
+ 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) {
+ 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_Bind (b.ipv4_fd, b.addr);
+ 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_Bind (b.ipv6_fd, b.addr);
+ 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_Bind (fd, b.addr);
+ 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_Bind (ofd, oaddr);
+ 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_Bind (fd, b.addr);
+
+ 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(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 {
+ iaObj = new Inet6Address(null, caddr, getScopeID(him));
+ }
+ 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);
+ }
+}
diff --git a/openjdk/response.txt b/openjdk/response.txt
index 393c980b..e6c58384 100644
--- a/openjdk/response.txt
+++ b/openjdk/response.txt
@@ -140,12 +140,13 @@ assembly.class
@OPENJDK@/jdk/src/solaris/classes/sun/net/www/protocol/http/*.class
@OPENJDK@/jdk/src/windows/classes/java/io/*.class
@OPENJDK@/jdk/src/windows/classes/java/lang/*.class
+ @OPENJDK@/jdk/src/windows/classes/java/net/*.class
@OPENJDK@/jdk/src/windows/classes/sun/nio/ch/*.class
@OPENJDK@/jdk/src/windows/classes/sun/security/provider/NativePRNG.class
}
{
-out:IKVM.OpenJDK.Corba.dll
- -baseaddress:0x56960000
+ -baseaddress:0x56990000
-recurse:@OPENJDK@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/corba/*
-recurse:@OPENJDK@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/jndi/cosnaming/jndiprovider.properties
@OPENJDK@/build/linux-amd64/impsrc/com/sun/corba/se/impl/activation/*.class
@@ -263,7 +264,7 @@ assembly.class
}
{
-out:IKVM.OpenJDK.XML.API.dll
- -baseaddress:0x56FF0000
+ -baseaddress:0x57020000
@OPENJDK@/build/linux-amd64/impsrc/javax/xml/*.class
@OPENJDK@/build/linux-amd64/impsrc/javax/xml/datatype/*.class
@OPENJDK@/build/linux-amd64/impsrc/javax/xml/namespace/*.class
@@ -295,7 +296,7 @@ assembly.class
}
{
-out:IKVM.OpenJDK.XML.XPath.dll
- -baseaddress:0x570B0000
+ -baseaddress:0x570E0000
-recurse:@OPENJDK@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/org/apache/xalan/internal/res/*
@OPENJDK@/build/linux-amd64/impsrc/com/sun/org/apache/xalan/internal/extensions/*.class
@OPENJDK@/build/linux-amd64/impsrc/com/sun/org/apache/xalan/internal/res/*.class
@@ -320,7 +321,7 @@ assembly.class
}
{
-out:IKVM.OpenJDK.XML.Parse.dll
- -baseaddress:0x573E0000
+ -baseaddress:0x57410000
-resource:com/sun/org/apache/xml/internal/serialize/HTMLEntities.res=@OPENJDK@/build/linux-amd64/impsrc/com/sun/org/apache/xml/internal/serialize/HTMLEntities.res
-recurse:@OPENJDK@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/org/apache/xerces/*
-recurse:@OPENJDK@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/org/apache/xml/internal/serializer/*
@@ -379,7 +380,7 @@ assembly.class
}
{
-out:IKVM.OpenJDK.XML.Transform.dll
- -baseaddress:0x57AA0000
+ -baseaddress:0x57AD0000
@OPENJDK@/build/linux-amd64/impsrc/com/sun/java_cup/internal/runtime/*.class
@OPENJDK@/build/linux-amd64/impsrc/com/sun/org/apache/bcel/internal/*.class
@OPENJDK@/build/linux-amd64/impsrc/com/sun/org/apache/bcel/internal/classfile/*.class
@@ -403,7 +404,7 @@ assembly.class
}
{
-out:IKVM.OpenJDK.XML.Bind.dll
- -baseaddress:0x57EF0000
+ -baseaddress:0x57F20000
-recurse:@OPENJDK@/build/linux-amd64/j2re-image/lib/resources.jar/javax/xml/bind/*
-recurse:@OPENJDK@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/xml/internal/bind/*
-recurse:@OPENJDK@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/xml/internal/fastinfoset/*
@@ -461,7 +462,7 @@ assembly.class
}
{
-out:IKVM.OpenJDK.XML.WebServices.dll
- -baseaddress:0x58280000
+ -baseaddress:0x582B0000
-recurse:@OPENJDK@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/xml/internal/messaging/*
-recurse:@OPENJDK@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/xml/internal/ws/*
@OPENJDK@/build/linux-amd64/impsrc/com/sun/xml/internal/messaging/saaj/*.class
@@ -554,7 +555,7 @@ assembly.class
}
{
-out:IKVM.OpenJDK.XML.Crypto.dll
- -baseaddress:0x58700000
+ -baseaddress:0x58730000
-recurse:@OPENJDK@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/org/apache/xml/internal/security/*
@OPENJDK@/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/*.class
@OPENJDK@/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/*.class
@@ -590,7 +591,7 @@ assembly.class
}
{
-out:IKVM.OpenJDK.SwingAWT.dll
- -baseaddress:0x58850000
+ -baseaddress:0x58880000
-recurse:@OPENJDK@/build/linux-amd64/j2re-image/lib/resources.jar/META-INF/services/sun.java2d.*
-recurse:@OPENJDK@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/java/swing/*
-recurse:@OPENJDK@/build/linux-amd64/j2re-image/lib/resources.jar/javax/swing/*
@@ -669,13 +670,13 @@ assembly.class
}
{
-out:IKVM.OpenJDK.Charsets.dll
- -baseaddress:0x59780000
+ -baseaddress:0x597B0000
@OPENJDK@/jdk/src/share/classes/sun/io/*.class
@OPENJDK@/jdk/src/share/classes/sun/nio/cs/ext/*.class
}
{
-out:IKVM.OpenJDK.Util.dll
- -baseaddress:0x5A5F0000
+ -baseaddress:0x5A620000
-recurse:@OPENJDK@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/java/util/jar/pack/intrinsic.properties
java/util/zip/*.class
@OPENJDK@/build/linux-amd64/gensrc/sun/util/logging/resources/*.class
@@ -693,7 +694,7 @@ assembly.class
}
{
-out:IKVM.OpenJDK.Text.dll
- -baseaddress:0x5AA10000
+ -baseaddress:0x5AA40000
-recurse:@OPENJDK@/build/linux-amd64/j2re-image/lib/resources.jar/sun/text/*
java/text/*.class
@OPENJDK@/jdk/src/share/classes/java/text/*.class
@@ -704,7 +705,7 @@ assembly.class
}
{
-out:IKVM.OpenJDK.Security.dll
- -baseaddress:0x5ABF0000
+ -baseaddress:0x5AC20000
sun/security/jgss/wrapper/*.class
@OPENJDK@/jdk/src/share/classes/com/sun/crypto/provider/*.class
@OPENJDK@/jdk/src/share/classes/com/sun/net/ssl/*.class
@@ -769,7 +770,7 @@ assembly.class
}
{
-out:IKVM.OpenJDK.Management.dll
- -baseaddress:0x5B340000
+ -baseaddress:0x5B370000
com/sun/management/*.class
ConnectorBootstrap$DefaultValues.class
ConnectorBootstrap.class
@@ -811,7 +812,7 @@ assembly.class
}
{
-out:IKVM.OpenJDK.Misc.dll
- -baseaddress:0x5B730000
+ -baseaddress:0x5B760000
@OPENJDK@/build/linux-amd64/impsrc/javax/activity/*.class
@OPENJDK@/build/linux-amd64/impsrc/javax/annotation/*.class
@OPENJDK@/build/linux-amd64/impsrc/javax/annotation/processing/*.class
@@ -901,7 +902,7 @@ assembly.class
}
{
-out:IKVM.OpenJDK.Naming.dll
- -baseaddress:0x5B7F0000
+ -baseaddress:0x5B820000
-recurse:@OPENJDK@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/jndi/ldap/jndiprovider.properties
sun/net/dns/*.class
@OPENJDK@/jdk/src/share/classes/com/sun/jndi/dns/*.class
@@ -926,7 +927,7 @@ assembly.class
}
{
-out:IKVM.OpenJDK.Jdbc.dll
- -baseaddress:0x5B940000
+ -baseaddress:0x5B970000
-resource:META-INF/services/java.sql.Driver=resources/META-INF/services/java.sql.Driver
-recurse:@OPENJDK@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/rowset/*
-recurse:@OPENJDK@/build/linux-amd64/j2re-image/lib/resources.jar/javax/sql/*
@@ -944,7 +945,7 @@ assembly.class
}
{
-out:IKVM.OpenJDK.Remoting.dll
- -baseaddress:0x5BA90000
+ -baseaddress:0x5BAC0000
-recurse:@OPENJDK@/build/linux-amd64/j2re-image/lib/resources.jar/sun/rmi/*
@OPENJDK@/build/linux-amd64/classes/com/sun/jndi/rmi/registry/*.class
@OPENJDK@/build/linux-amd64/classes/java/rmi/activation/*.class
@@ -970,7 +971,7 @@ assembly.class
}
{
-out:IKVM.OpenJDK.Beans.dll
- -baseaddress:0x5BBB0000
+ -baseaddress:0x5BBE0000
@OPENJDK@/build/linux-amd64/impsrc/com/sun/activation/registries/*.class
@OPENJDK@/build/linux-amd64/impsrc/javax/activation/*.class
@OPENJDK@/jdk/src/share/classes/com/sun/beans/*.class
@@ -982,7 +983,7 @@ assembly.class
}
{
-out:IKVM.OpenJDK.Media.dll
- -baseaddress:0x5BC70000
+ -baseaddress:0x5BCA0000
-recurse:@OPENJDK@/build/linux-amd64/j2re-image/lib/resources.jar/META-INF/services/javax.print.*
-recurse:@OPENJDK@/build/linux-amd64/j2re-image/lib/resources.jar/META-INF/services/javax.sound.*
-recurse:@OPENJDK@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/imageio/plugins/common/iio-plugin.properties