2
Copyright (C) 2011 Jeroen Frijters
4
This software is provided 'as-is', without any express or implied
5
warranty. In no event will the authors be held liable for any damages
6
arising from the use of this software.
8
Permission is granted to anyone to use this software for any purpose,
9
including commercial applications, and to alter it and redistribute it
10
freely, subject to the following restrictions:
12
1. The origin of this software must not be misrepresented; you must not
13
claim that you wrote the original software. If you use this software
14
in a product, an acknowledgment in the product documentation would be
15
appreciated but is not required.
16
2. Altered source versions must be plainly marked as such, and must not be
17
misrepresented as being the original software.
18
3. This notice may not be removed or altered from any source distribution.
26
using System.Collections.Generic;
27
using FileDescriptor = java.io.FileDescriptor;
28
using InetAddress = java.net.InetAddress;
29
using ByteBuffer = java.nio.ByteBuffer;
31
static class Java_sun_nio_ch_DatagramChannelImpl
33
public static void initIDs()
37
public static void disconnect0(FileDescriptor fd)
42
fd.getSocket().Connect(new System.Net.IPEndPoint(System.Net.IPAddress.Any, 0));
43
IKVM.NativeCode.sun.nio.ch.Net.setConnectionReset(fd.getSocket(), false);
45
catch (System.Net.Sockets.SocketException x)
47
throw java.net.SocketUtil.convertSocketExceptionToIOException(x);
49
catch (ObjectDisposedException)
51
throw new java.net.SocketException("Socket is closed");
56
public static int receive0(object obj, FileDescriptor fd, byte[] buf, int pos, int len, bool connected)
61
sun.nio.ch.DatagramChannelImpl impl = (sun.nio.ch.DatagramChannelImpl)obj;
62
java.net.SocketAddress remoteAddress = impl.remoteAddress();
63
System.Net.EndPoint remoteEP;
64
if (fd.getSocket().AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6)
66
remoteEP = new System.Net.IPEndPoint(System.Net.IPAddress.IPv6Any, 0);
70
remoteEP = new System.Net.IPEndPoint(0, 0);
72
java.net.InetSocketAddress addr;
80
length = fd.getSocket().ReceiveFrom(buf, pos, len, System.Net.Sockets.SocketFlags.None, ref remoteEP);
83
catch (System.Net.Sockets.SocketException x)
85
if (x.ErrorCode == java.net.SocketUtil.WSAECONNRESET)
87
// A previous send failed (i.e. the remote host responded with a ICMP that the port is closed) and
88
// the winsock stack helpfully lets us know this, but we only care about this when we're connected,
89
// otherwise we'll simply retry the receive (note that we use SIO_UDP_CONNRESET to prevent these
90
// WSAECONNRESET exceptions, but when switching from connected to disconnected, some can slip through).
93
throw new java.net.PortUnreachableException();
97
if (x.ErrorCode == java.net.SocketUtil.WSAEMSGSIZE)
99
// The buffer size was too small for the packet, ReceiveFrom receives the part of the packet
100
// that fits in the buffer and then throws an exception, so we have to ignore the exception in this case.
104
if (x.ErrorCode == java.net.SocketUtil.WSAEWOULDBLOCK)
106
return sun.nio.ch.IOStatus.UNAVAILABLE;
108
throw java.net.SocketUtil.convertSocketExceptionToIOException(x);
110
catch (ObjectDisposedException)
112
throw new java.net.SocketException("Socket is closed");
115
System.Net.IPEndPoint ep = (System.Net.IPEndPoint)remoteEP;
116
addr = new java.net.InetSocketAddress(java.net.SocketUtil.getInetAddressFromIPEndPoint(ep), ep.Port);
117
} while (remoteAddress != null && !addr.equals(remoteAddress));
123
public static int send0(object obj, bool preferIPv6, FileDescriptor fd, byte[] buf, int pos, int len, object sa)
128
java.net.InetSocketAddress addr = (java.net.InetSocketAddress)sa;
131
return fd.getSocket().SendTo(buf, pos, len, System.Net.Sockets.SocketFlags.None, new System.Net.IPEndPoint(java.net.SocketUtil.getAddressFromInetAddress(addr.getAddress(), preferIPv6), addr.getPort()));
133
catch (System.Net.Sockets.SocketException x)
135
if (x.ErrorCode == java.net.SocketUtil.WSAEWOULDBLOCK)
137
return sun.nio.ch.IOStatus.UNAVAILABLE;
139
throw java.net.SocketUtil.convertSocketExceptionToIOException(x);
141
catch (ObjectDisposedException)
143
throw new java.net.SocketException("Socket is closed");
150
namespace IKVM.Internal.AsyncSocket
153
using System.Net.Sockets;
155
abstract class OperationBase<TInput>
157
private static readonly AsyncCallback callback = CallbackProc;
158
private Socket socket;
159
private sun.nio.ch.Iocp.ResultHandler handler;
161
private Exception exception;
163
internal int Do(Socket socket, TInput input, object handler)
167
this.socket = socket;
168
this.handler = (sun.nio.ch.Iocp.ResultHandler)handler;
169
IAsyncResult ar = Begin(socket, input, callback, this);
170
if (ar.CompletedSynchronously)
172
if (exception != null)
180
return sun.nio.ch.IOStatus.UNAVAILABLE;
183
catch (SocketException x)
185
throw java.net.SocketUtil.convertSocketExceptionToIOException(x);
187
catch (ObjectDisposedException)
189
throw new java.nio.channels.ClosedChannelException();
193
private static void CallbackProc(IAsyncResult ar)
195
OperationBase<TInput> obj = (OperationBase<TInput>)ar.AsyncState;
198
int result = obj.End(obj.socket, ar);
199
if (ar.CompletedSynchronously)
205
obj.handler.completed(result, false);
208
catch (SocketException x)
210
if (ar.CompletedSynchronously)
216
obj.handler.failed(x.ErrorCode, java.net.SocketUtil.convertSocketExceptionToIOException(x));
219
catch (ObjectDisposedException x)
221
if (ar.CompletedSynchronously)
227
obj.handler.failed(0, new java.nio.channels.ClosedChannelException());
232
protected abstract IAsyncResult Begin(Socket socket, TInput input, AsyncCallback callback, object state);
233
protected abstract int End(Socket socket, IAsyncResult ar);
238
static class Java_sun_nio_ch_WindowsAsynchronousServerSocketChannelImpl
241
sealed class Accept : IKVM.Internal.AsyncSocket.OperationBase<System.Net.Sockets.Socket>
243
protected override IAsyncResult Begin(System.Net.Sockets.Socket listenSocket, System.Net.Sockets.Socket acceptSocket, AsyncCallback callback, object state)
245
return listenSocket.BeginAccept(acceptSocket, 0, callback, state);
248
protected override int End(System.Net.Sockets.Socket socket, IAsyncResult ar)
250
socket.EndAccept(ar);
256
public static void initIDs()
260
public static int accept0(FileDescriptor listenSocket, FileDescriptor acceptSocket, object handler)
265
return new Accept().Do(listenSocket.getSocket(), acceptSocket.getSocket(), handler);
269
public static void updateAcceptContext(FileDescriptor listenSocket, FileDescriptor acceptSocket)
271
// already handled by .NET Framework
274
public static void closesocket0(long socket)
280
static class Java_sun_nio_ch_WindowsAsynchronousSocketChannelImpl
283
sealed class Connect : IKVM.Internal.AsyncSocket.OperationBase<System.Net.IPEndPoint>
285
protected override IAsyncResult Begin(System.Net.Sockets.Socket socket, System.Net.IPEndPoint remoteEP, AsyncCallback callback, object state)
287
return socket.BeginConnect(remoteEP, callback, state);
290
protected override int End(System.Net.Sockets.Socket socket, IAsyncResult ar)
292
socket.EndConnect(ar);
297
private static List<ArraySegment<byte>> ByteBuffersToList(ByteBuffer[] bufs)
299
List<ArraySegment<byte>> list = new List<ArraySegment<byte>>(bufs.Length);
300
foreach (ByteBuffer bb in bufs)
302
list.Add(new ArraySegment<byte>(bb.array(), bb.arrayOffset() + bb.position(), bb.remaining()));
307
sealed class Receive : IKVM.Internal.AsyncSocket.OperationBase<ByteBuffer[]>
309
protected override IAsyncResult Begin(System.Net.Sockets.Socket socket, ByteBuffer[] bufs, AsyncCallback callback, object state)
311
return socket.BeginReceive(ByteBuffersToList(bufs), System.Net.Sockets.SocketFlags.None, callback, state);
314
protected override int End(System.Net.Sockets.Socket socket, IAsyncResult ar)
316
return socket.EndReceive(ar);
320
sealed class Send : IKVM.Internal.AsyncSocket.OperationBase<ByteBuffer[]>
322
protected override IAsyncResult Begin(System.Net.Sockets.Socket socket, ByteBuffer[] bufs, AsyncCallback callback, object state)
324
return socket.BeginSend(ByteBuffersToList(bufs), System.Net.Sockets.SocketFlags.None, callback, state);
327
protected override int End(System.Net.Sockets.Socket socket, IAsyncResult ar)
329
return socket.EndSend(ar);
334
public static void initIDs()
338
public static int connect0(FileDescriptor fd, bool preferIPv6, InetAddress remote, int remotePort, object handler)
343
return new Connect().Do(fd.getSocket(), new System.Net.IPEndPoint(java.net.SocketUtil.getAddressFromInetAddress(remote, preferIPv6), remotePort), handler);
347
public static void updateConnectContext(FileDescriptor fd)
349
// already handled by .NET Framework
352
public static int read0(FileDescriptor fd, ByteBuffer[] bufs, object handler)
357
return new Receive().Do(fd.getSocket(), bufs, handler);
361
public static int write0(FileDescriptor fd, ByteBuffer[] bufs, object handler)
366
return new Send().Do(fd.getSocket(), bufs, handler);
370
public static void shutdown0(long socket, int how)
375
public static void closesocket0(long socket)
381
namespace IKVM.NativeCode.sun.nio.ch
383
static class SocketDispatcher
385
public static long read(object nd, FileDescriptor fd, ByteBuffer[] bufs, int offset, int length)
390
ByteBuffer[] altBufs = null;
391
List<ArraySegment<byte>> list = new List<ArraySegment<byte>>(length);
392
for (int i = 0; i < length; i++)
394
ByteBuffer bb = bufs[i + offset];
399
altBufs = new ByteBuffer[bufs.Length];
401
bb = altBufs[i + offset] = ByteBuffer.allocate(bb.remaining());
403
list.Add(new ArraySegment<byte>(bb.array(), bb.arrayOffset() + bb.position(), bb.remaining()));
408
count = fd.getSocket().Receive(list);
410
catch (System.Net.Sockets.SocketException x)
412
throw global::java.net.SocketUtil.convertSocketExceptionToIOException(x);
414
catch (ObjectDisposedException)
416
throw new global::java.net.SocketException("Socket is closed");
419
for (int i = 0; total > 0 && i < length; i++)
421
ByteBuffer bb = bufs[i + offset];
423
int consumed = Math.Min(total, bb.remaining());
424
if (altBufs != null && (abb = altBufs[i + offset]) != null)
426
abb.position(consumed);
432
bb.position(bb.position() + consumed);
440
public static long write(object nd, FileDescriptor fd, ByteBuffer[] bufs, int offset, int length)
445
ByteBuffer[] altBufs = null;
446
List<ArraySegment<byte>> list = new List<ArraySegment<byte>>(length);
447
for (int i = 0; i < length; i++)
449
ByteBuffer bb = bufs[i + offset];
454
altBufs = new ByteBuffer[bufs.Length];
456
ByteBuffer abb = ByteBuffer.allocate(bb.remaining());
457
int pos = bb.position();
461
bb = altBufs[i + offset] = abb;
463
list.Add(new ArraySegment<byte>(bb.array(), bb.arrayOffset() + bb.position(), bb.remaining()));
468
count = fd.getSocket().Send(list);
470
catch (System.Net.Sockets.SocketException x)
472
throw global::java.net.SocketUtil.convertSocketExceptionToIOException(x);
474
catch (ObjectDisposedException)
476
throw new global::java.net.SocketException("Socket is closed");
479
for (int i = 0; total > 0 && i < length; i++)
481
ByteBuffer bb = bufs[i + offset];
482
int consumed = Math.Min(total, bb.remaining());
483
bb.position(bb.position() + consumed);
493
public static bool isIPv6Available0()
495
string env = IKVM.Internal.JVM.SafeGetEnvironmentVariable("IKVM_IPV6");
497
if (env != null && Int32.TryParse(env, out val))
499
return (val & 2) != 0;
501
// we only support IPv6 on Vista and up (because there is no TwoStacks nio implementation)
502
// (non-Windows OSses are currently not supported)
503
// Mono on Windows doesn't appear to support IPv6 either (Mono on Linux does).
504
return Type.GetType("Mono.Runtime") == null
505
&& System.Net.Sockets.Socket.OSSupportsIPv6
506
&& Environment.OSVersion.Platform == PlatformID.Win32NT
507
&& Environment.OSVersion.Version.Major >= 6;
510
public static bool canIPv6SocketJoinIPv4Group0()
515
public static bool canJoin6WithIPv4Group0()
520
public static void shutdown(FileDescriptor fd, int how)
525
fd.getSocket().Shutdown(how == global::sun.nio.ch.Net.SHUT_RD
526
? System.Net.Sockets.SocketShutdown.Receive
527
: System.Net.Sockets.SocketShutdown.Send);
529
catch (System.Net.Sockets.SocketException x)
531
throw global::java.net.SocketUtil.convertSocketExceptionToIOException(x);
533
catch (ObjectDisposedException)
535
throw new global::java.net.SocketException("Socket is closed");
540
public static int localPort(FileDescriptor fd)
547
System.Net.IPEndPoint ep = (System.Net.IPEndPoint)fd.getSocket().LocalEndPoint;
550
catch (System.Net.Sockets.SocketException x)
552
throw global::java.net.SocketUtil.convertSocketExceptionToIOException(x);
554
catch (System.ObjectDisposedException)
556
throw new global::java.net.SocketException("Socket is closed");
561
public static InetAddress localInetAddress(FileDescriptor fd)
568
System.Net.IPEndPoint ep = (System.Net.IPEndPoint)fd.getSocket().LocalEndPoint;
569
return global::java.net.SocketUtil.getInetAddressFromIPEndPoint(ep);
571
catch (System.Net.Sockets.SocketException x)
573
throw global::java.net.SocketUtil.convertSocketExceptionToIOException(x);
575
catch (System.ObjectDisposedException)
577
throw new global::java.net.SocketException("Socket is closed");
582
public static int remotePort(FileDescriptor fd)
589
System.Net.IPEndPoint ep = (System.Net.IPEndPoint)fd.getSocket().RemoteEndPoint;
592
catch (System.Net.Sockets.SocketException x)
594
throw global::java.net.SocketUtil.convertSocketExceptionToIOException(x);
596
catch (System.ObjectDisposedException)
598
throw new global::java.net.SocketException("Socket is closed");
603
public static InetAddress remoteInetAddress(FileDescriptor fd)
610
System.Net.IPEndPoint ep = (System.Net.IPEndPoint)fd.getSocket().RemoteEndPoint;
611
return global::java.net.SocketUtil.getInetAddressFromIPEndPoint(ep);
613
catch (System.Net.Sockets.SocketException x)
615
throw global::java.net.SocketUtil.convertSocketExceptionToIOException(x);
617
catch (System.ObjectDisposedException)
619
throw new global::java.net.SocketException("Socket is closed");
624
public static int getIntOption0(FileDescriptor fd, bool mayNeedConversion, int level, int opt)
629
System.Net.Sockets.SocketOptionLevel sol = (System.Net.Sockets.SocketOptionLevel)level;
630
System.Net.Sockets.SocketOptionName son = (System.Net.Sockets.SocketOptionName)opt;
633
object obj = fd.getSocket().GetSocketOption(sol, son);
634
System.Net.Sockets.LingerOption linger = obj as System.Net.Sockets.LingerOption;
637
return linger.Enabled ? linger.LingerTime : -1;
641
catch (System.Net.Sockets.SocketException x)
643
if (mayNeedConversion)
645
if (x.ErrorCode == global::java.net.SocketUtil.WSAENOPROTOOPT
646
&& sol == System.Net.Sockets.SocketOptionLevel.IP
647
&& son == System.Net.Sockets.SocketOptionName.TypeOfService)
652
throw global::java.net.SocketUtil.convertSocketExceptionToIOException(x);
654
catch (System.ObjectDisposedException)
656
throw new global::java.net.SocketException("Socket is closed");
661
public static void setIntOption0(FileDescriptor fd, bool mayNeedConversion, int level, int opt, int arg)
664
System.Net.Sockets.SocketOptionLevel sol = (System.Net.Sockets.SocketOptionLevel)level;
665
System.Net.Sockets.SocketOptionName son = (System.Net.Sockets.SocketOptionName)opt;
666
if (mayNeedConversion)
668
const int IPTOS_TOS_MASK = 0x1e;
669
const int IPTOS_PREC_MASK = 0xe0;
670
if (sol == System.Net.Sockets.SocketOptionLevel.IP
671
&& son == System.Net.Sockets.SocketOptionName.TypeOfService)
673
arg &= (IPTOS_TOS_MASK | IPTOS_PREC_MASK);
678
fd.getSocket().SetSocketOption(sol, son, arg);
680
catch (System.Net.Sockets.SocketException x)
682
if (mayNeedConversion)
684
if (x.ErrorCode == global::java.net.SocketUtil.WSAENOPROTOOPT
685
&& sol == System.Net.Sockets.SocketOptionLevel.IP
686
&& (son == System.Net.Sockets.SocketOptionName.TypeOfService || son == System.Net.Sockets.SocketOptionName.MulticastLoopback))
690
if (x.ErrorCode == global::java.net.SocketUtil.WSAEINVAL
691
&& sol == System.Net.Sockets.SocketOptionLevel.IP
692
&& son == System.Net.Sockets.SocketOptionName.TypeOfService)
697
throw global::java.net.SocketUtil.convertSocketExceptionToIOException(x);
699
catch (System.ObjectDisposedException)
701
throw new global::java.net.SocketException("Socket is closed");
706
private static void PutInt(byte[] buf, int pos, int value)
708
buf[pos + 0] = (byte)(value >> 24);
709
buf[pos + 1] = (byte)(value >> 16);
710
buf[pos + 2] = (byte)(value >> 8);
711
buf[pos + 3] = (byte)(value >> 0);
714
public static int joinOrDrop4(bool join, FileDescriptor fd, int group, int interf, int source)
723
fd.getSocket().SetSocketOption(System.Net.Sockets.SocketOptionLevel.IP,
724
join ? System.Net.Sockets.SocketOptionName.AddMembership : System.Net.Sockets.SocketOptionName.DropMembership,
725
new System.Net.Sockets.MulticastOption(new System.Net.IPAddress(System.Net.IPAddress.HostToNetworkOrder(group) & 0xFFFFFFFFL), new System.Net.IPAddress(System.Net.IPAddress.HostToNetworkOrder(interf) & 0xFFFFFFFFL)));
730
byte[] optionValue = new byte[12];
731
PutInt(optionValue, 0, group);
732
PutInt(optionValue, 4, source);
733
PutInt(optionValue, 8, interf);
734
fd.getSocket().SetSocketOption(System.Net.Sockets.SocketOptionLevel.IP,
735
join ? System.Net.Sockets.SocketOptionName.AddSourceMembership : System.Net.Sockets.SocketOptionName.DropSourceMembership,
740
catch (System.Net.Sockets.SocketException x)
742
throw global::java.net.SocketUtil.convertSocketExceptionToIOException(x);
744
catch (System.ObjectDisposedException)
746
throw new global::java.net.SocketException("Socket is closed");
751
public static int blockOrUnblock4(bool block, FileDescriptor fd, int group, int interf, int source)
759
byte[] optionValue = new byte[12];
760
PutInt(optionValue, 0, group);
761
PutInt(optionValue, 4, source);
762
PutInt(optionValue, 8, interf);
763
fd.getSocket().SetSocketOption(System.Net.Sockets.SocketOptionLevel.IP,
764
block ? System.Net.Sockets.SocketOptionName.BlockSource : System.Net.Sockets.SocketOptionName.UnblockSource,
768
catch (System.Net.Sockets.SocketException x)
770
throw global::java.net.SocketUtil.convertSocketExceptionToIOException(x);
772
catch (System.ObjectDisposedException)
774
throw new global::java.net.SocketException("Socket is closed");
779
// write a sockaddr_in6 into optionValue at offset pos
780
private static void PutSockAddrIn6(byte[] optionValue, int pos, byte[] addr)
783
optionValue[pos] = 23; // AF_INET6
786
Buffer.BlockCopy(addr, 0, optionValue, pos + 8, addr.Length);
789
public static int joinOrDrop6(bool join, FileDescriptor fd, byte[] group, int index, byte[] source)
798
fd.getSocket().SetSocketOption(System.Net.Sockets.SocketOptionLevel.IPv6,
799
join ? System.Net.Sockets.SocketOptionName.AddMembership : System.Net.Sockets.SocketOptionName.DropMembership,
800
new System.Net.Sockets.IPv6MulticastOption(new System.Net.IPAddress(group), index));
804
const System.Net.Sockets.SocketOptionName MCAST_JOIN_SOURCE_GROUP = (System.Net.Sockets.SocketOptionName)45;
805
const System.Net.Sockets.SocketOptionName MCAST_LEAVE_SOURCE_GROUP = (System.Net.Sockets.SocketOptionName)46;
807
byte[] optionValue = new byte[264];
808
optionValue[0] = (byte)index;
809
optionValue[1] = (byte)(index >> 8);
810
optionValue[2] = (byte)(index >> 16);
811
optionValue[3] = (byte)(index >> 24);
812
PutSockAddrIn6(optionValue, 8, group);
813
PutSockAddrIn6(optionValue, 136, source);
814
fd.getSocket().SetSocketOption(System.Net.Sockets.SocketOptionLevel.IPv6, join ? MCAST_JOIN_SOURCE_GROUP : MCAST_LEAVE_SOURCE_GROUP, optionValue);
818
catch (System.Net.Sockets.SocketException x)
820
throw global::java.net.SocketUtil.convertSocketExceptionToIOException(x);
822
catch (System.ObjectDisposedException)
824
throw new global::java.net.SocketException("Socket is closed");
829
public static int blockOrUnblock6(bool block, FileDescriptor fd, byte[] group, int index, byte[] source)
836
const System.Net.Sockets.SocketOptionName MCAST_BLOCK_SOURCE = (System.Net.Sockets.SocketOptionName)43;
837
const System.Net.Sockets.SocketOptionName MCAST_UNBLOCK_SOURCE = (System.Net.Sockets.SocketOptionName)44;
839
byte[] optionValue = new byte[264];
840
optionValue[0] = (byte)index;
841
optionValue[1] = (byte)(index >> 8);
842
optionValue[2] = (byte)(index >> 16);
843
optionValue[3] = (byte)(index >> 24);
844
PutSockAddrIn6(optionValue, 8, group);
845
PutSockAddrIn6(optionValue, 136, source);
846
fd.getSocket().SetSocketOption(System.Net.Sockets.SocketOptionLevel.IPv6, block ? MCAST_BLOCK_SOURCE : MCAST_UNBLOCK_SOURCE, optionValue);
849
catch (System.Net.Sockets.SocketException x)
851
throw global::java.net.SocketUtil.convertSocketExceptionToIOException(x);
853
catch (System.ObjectDisposedException)
855
throw new global::java.net.SocketException("Socket is closed");
860
public static void setInterface4(FileDescriptor fd, int interf)
865
fd.getSocket().SetSocketOption(System.Net.Sockets.SocketOptionLevel.IP, System.Net.Sockets.SocketOptionName.MulticastInterface, System.Net.IPAddress.HostToNetworkOrder(interf));
867
catch (System.Net.Sockets.SocketException x)
869
throw global::java.net.SocketUtil.convertSocketExceptionToIOException(x);
871
catch (System.ObjectDisposedException)
873
throw new global::java.net.SocketException("Socket is closed");
878
public static int getInterface4(FileDescriptor fd)
885
return System.Net.IPAddress.NetworkToHostOrder((int)fd.getSocket().GetSocketOption(System.Net.Sockets.SocketOptionLevel.IP, System.Net.Sockets.SocketOptionName.MulticastInterface));
887
catch (System.Net.Sockets.SocketException x)
889
throw global::java.net.SocketUtil.convertSocketExceptionToIOException(x);
891
catch (System.ObjectDisposedException)
893
throw new global::java.net.SocketException("Socket is closed");
898
public static void setInterface6(FileDescriptor fd, int index)
903
fd.getSocket().SetSocketOption(System.Net.Sockets.SocketOptionLevel.IPv6, System.Net.Sockets.SocketOptionName.MulticastInterface, index);
905
catch (System.Net.Sockets.SocketException x)
907
throw global::java.net.SocketUtil.convertSocketExceptionToIOException(x);
909
catch (System.ObjectDisposedException)
911
throw new global::java.net.SocketException("Socket is closed");
916
public static int getInterface6(FileDescriptor fd)
923
return (int)fd.getSocket().GetSocketOption(System.Net.Sockets.SocketOptionLevel.IPv6, System.Net.Sockets.SocketOptionName.MulticastInterface);
925
catch (System.Net.Sockets.SocketException x)
927
throw global::java.net.SocketUtil.convertSocketExceptionToIOException(x);
929
catch (System.ObjectDisposedException)
931
throw new global::java.net.SocketException("Socket is closed");
936
public static FileDescriptor socket0(bool preferIPv6, bool stream, bool reuse)
943
System.Net.Sockets.AddressFamily addressFamily = preferIPv6
944
? System.Net.Sockets.AddressFamily.InterNetworkV6
945
: System.Net.Sockets.AddressFamily.InterNetwork;
946
System.Net.Sockets.SocketType socketType = stream
947
? System.Net.Sockets.SocketType.Stream
948
: System.Net.Sockets.SocketType.Dgram;
949
System.Net.Sockets.ProtocolType protocolType = stream
950
? System.Net.Sockets.ProtocolType.Tcp
951
: System.Net.Sockets.ProtocolType.Udp;
952
System.Net.Sockets.Socket socket = new System.Net.Sockets.Socket(addressFamily, socketType, protocolType);
955
// enable IPv4 over IPv6 sockets (note that we don't have to check for >= Vista here, because nio sockets only support IPv6 on >= Vista)
956
const System.Net.Sockets.SocketOptionName IPV6_V6ONLY = (System.Net.Sockets.SocketOptionName)27;
957
socket.SetSocketOption(System.Net.Sockets.SocketOptionLevel.IPv6, IPV6_V6ONLY, 0);
961
setConnectionReset(socket, false);
963
FileDescriptor fd = new FileDescriptor();
964
fd.setSocket(socket);
967
catch (System.Net.Sockets.SocketException x)
969
throw global::java.net.SocketUtil.convertSocketExceptionToIOException(x);
974
public static void bind0(bool preferIPv6, FileDescriptor fd, InetAddress addr, int port)
979
fd.getSocket().Bind(new System.Net.IPEndPoint(global::java.net.SocketUtil.getAddressFromInetAddress(addr, preferIPv6), port));
981
catch (System.Net.Sockets.SocketException x)
983
throw global::java.net.SocketUtil.convertSocketExceptionToIOException(x);
985
catch (System.ObjectDisposedException)
987
throw new global::java.net.SocketException("Socket is closed");
992
public static void listen(FileDescriptor fd, int backlog)
997
fd.getSocket().Listen(backlog);
999
catch (System.Net.Sockets.SocketException x)
1001
throw global::java.net.SocketUtil.convertSocketExceptionToIOException(x);
1003
catch (System.ObjectDisposedException)
1005
throw new global::java.net.SocketException("Socket is closed");
1010
internal static void setConnectionReset(System.Net.Sockets.Socket socket, bool enable)
1012
// Windows 2000 introduced a "feature" that causes it to return WSAECONNRESET from receive,
1013
// if a previous send resulted in an ICMP port unreachable. For unconnected datagram sockets,
1014
// we disable this feature by using this ioctl.
1015
const int IOC_IN = unchecked((int)0x80000000);
1016
const int IOC_VENDOR = 0x18000000;
1017
const int SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12;
1019
socket.IOControl(SIO_UDP_CONNRESET, new byte[] { enable ? (byte)1 : (byte)0 }, null);
1022
public static int connect0(bool preferIPv6, FileDescriptor fd, InetAddress remote, int remotePort)
1029
System.Net.IPEndPoint ep = new System.Net.IPEndPoint(global::java.net.SocketUtil.getAddressFromInetAddress(remote, preferIPv6), remotePort);
1030
bool datagram = fd.getSocket().SocketType == System.Net.Sockets.SocketType.Dgram;
1031
if (datagram || fd.isSocketBlocking())
1033
fd.getSocket().Connect(ep);
1036
setConnectionReset(fd.getSocket(), true);
1042
fd.setAsyncResult(fd.getSocket().BeginConnect(ep, null, null));
1043
return global::sun.nio.ch.IOStatus.UNAVAILABLE;
1046
catch (System.Net.Sockets.SocketException x)
1048
throw new global::java.net.ConnectException(x.Message);
1050
catch (System.ObjectDisposedException)
1052
throw new global::java.net.SocketException("Socket is closed");
1058
static class ServerSocketChannelImpl
1060
public static int accept0(object _this, FileDescriptor ssfd, FileDescriptor newfd, object isaa)
1067
System.Net.Sockets.Socket netSocket = ssfd.getSocket();
1068
if (netSocket.Blocking || netSocket.Poll(0, System.Net.Sockets.SelectMode.SelectRead))
1070
System.Net.Sockets.Socket accsock = netSocket.Accept();
1071
newfd.setSocket(accsock);
1072
System.Net.IPEndPoint ep = (System.Net.IPEndPoint)accsock.RemoteEndPoint;
1073
((global::java.net.InetSocketAddress[])isaa)[0] = new global::java.net.InetSocketAddress(global::java.net.SocketUtil.getInetAddressFromIPEndPoint(ep), ep.Port);
1078
return global::sun.nio.ch.IOStatus.UNAVAILABLE;
1081
catch (System.Net.Sockets.SocketException x)
1083
throw global::java.net.SocketUtil.convertSocketExceptionToIOException(x);
1085
catch (System.ObjectDisposedException)
1087
throw new global::java.net.SocketException("Socket is closed");
1092
public static void initIDs()
1097
static class SocketChannelImpl
1099
public static int checkConnect(FileDescriptor fd, bool block, bool ready)
1106
IAsyncResult asyncConnect = fd.getAsyncResult();
1107
if (block || ready || asyncConnect.IsCompleted)
1109
fd.setAsyncResult(null);
1110
fd.getSocket().EndConnect(asyncConnect);
1111
// work around for blocking issue
1112
fd.getSocket().Blocking = fd.isSocketBlocking();
1117
return global::sun.nio.ch.IOStatus.UNAVAILABLE;
1120
catch (System.Net.Sockets.SocketException x)
1122
throw new global::java.net.ConnectException(x.Message);
1124
catch (System.ObjectDisposedException)
1126
throw new global::java.net.SocketException("Socket is closed");
1131
public static int sendOutOfBandData(FileDescriptor fd, byte data)
1138
fd.getSocket().Send(new byte[] { data }, 1, System.Net.Sockets.SocketFlags.OutOfBand);
1141
catch (System.Net.Sockets.SocketException x)
1143
throw new global::java.net.ConnectException(x.Message);
1145
catch (System.ObjectDisposedException)
1147
throw new global::java.net.SocketException("Socket is closed");