internal static void CompleteInitialization(SafeCloseSocketAndEvent socketAndEventHandle) { SafeWaitHandle safeWaitHandle = socketAndEventHandle.waitHandle.SafeWaitHandle; bool success = false; RuntimeHelpers.PrepareConstrainedRegions(); try { safeWaitHandle.DangerousAddRef(ref success); } catch { if (success) { safeWaitHandle.DangerousRelease(); socketAndEventHandle.waitHandle = null; success = false; } } finally { if (success) { safeWaitHandle.Dispose(); } } }
internal static SafeCloseSocketAndEvent CreateWSASocketWithEvent(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType, bool autoReset, bool signaled) { SafeCloseSocketAndEvent target = new SafeCloseSocketAndEvent(); SafeCloseSocket.CreateSocket(SafeCloseSocket.InnerSafeCloseSocket.CreateWSASocket(addressFamily, socketType, protocolType), target); if (target.IsInvalid) { throw new SocketException(); } target.waitHandle = new AutoResetEvent(false); CompleteInitialization(target); return target; }
internal NetworkAddressChangePolled() { int num; Socket.InitializeSockets(); if (Socket.OSSupportsIPv4) { num = -1; this.ipv4Socket = SafeCloseSocketAndEvent.CreateWSASocketWithEvent(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.IP, true, false); UnsafeNclNativeMethods.OSSOCK.ioctlsocket(this.ipv4Socket, -2147195266, ref num); } if (Socket.OSSupportsIPv6) { num = -1; this.ipv6Socket = SafeCloseSocketAndEvent.CreateWSASocketWithEvent(AddressFamily.InterNetworkV6, SocketType.Dgram, ProtocolType.IP, true, false); UnsafeNclNativeMethods.OSSOCK.ioctlsocket(this.ipv6Socket, -2147195266, ref num); } this.Setup(StartIPOptions.Both); }
public void Dispose() { if (!this.disposed) { lock (this) { if (!this.disposed) { if (this.ipv6Socket != null) { this.ipv6Socket.Close(); this.ipv6Socket = null; } if (this.ipv4Socket != null) { this.ipv4Socket.Close(); this.ipv6Socket = null; } this.disposed = true; } } } }
private static void StartHelper(NetworkAddressChangedEventHandler caller, bool captureContext, StartIPOptions startIPOptions) { lock (s_callerArray) { // setup changedEvent and native overlapped struct. if(s_ipv4Socket == null){ Socket.InitializeSockets(); int blocking; if(Socket.OSSupportsIPv4){ blocking = -1; s_ipv4Socket = SafeCloseSocketAndEvent.CreateWSASocketWithEvent(AddressFamily.InterNetwork, SocketType.Dgram, (ProtocolType)0, true, false); UnsafeNclNativeMethods.OSSOCK.ioctlsocket(s_ipv4Socket, IoctlSocketConstants.FIONBIO,ref blocking); s_ipv4WaitHandle = s_ipv4Socket.GetEventHandle(); } if(Socket.OSSupportsIPv6){ blocking = -1; s_ipv6Socket = SafeCloseSocketAndEvent.CreateWSASocketWithEvent(AddressFamily.InterNetworkV6, SocketType.Dgram, (ProtocolType)0, true, false); UnsafeNclNativeMethods.OSSOCK.ioctlsocket(s_ipv6Socket,IoctlSocketConstants.FIONBIO,ref blocking); s_ipv6WaitHandle = s_ipv6Socket.GetEventHandle(); } } if ((caller != null) && (!s_callerArray.Contains(caller))) { s_callerArray.Add(caller, captureContext ? ExecutionContext.Capture() : null); } //if s_listener is not null, it means we are already actively listening if (s_isListening || s_callerArray.Count == 0) { return; } if(!s_isPending){ int length; SocketError errorCode; if(Socket.OSSupportsIPv4 && (startIPOptions & StartIPOptions.StartIPv4) !=0){ s_registeredWait = ThreadPool.UnsafeRegisterWaitForSingleObject( s_ipv4WaitHandle, new WaitOrTimerCallback(AddressChangedCallback), StartIPOptions.StartIPv4, -1, true ); errorCode = (SocketError) UnsafeNclNativeMethods.OSSOCK.WSAIoctl_Blocking( s_ipv4Socket.DangerousGetHandle(), (int) IOControlCode.AddressListChange, null, 0, null, 0, out length, SafeNativeOverlapped.Zero, IntPtr.Zero); if (errorCode != SocketError.Success) { NetworkInformationException exception = new NetworkInformationException(); if (exception.ErrorCode != (uint)SocketError.WouldBlock) { throw exception; } } errorCode = (SocketError)UnsafeNclNativeMethods.OSSOCK.WSAEventSelect(s_ipv4Socket, s_ipv4Socket.GetEventHandle().SafeWaitHandle, AsyncEventBits.FdAddressListChange); if (errorCode != SocketError.Success) { throw new NetworkInformationException(); } } if(Socket.OSSupportsIPv6 && (startIPOptions & StartIPOptions.StartIPv6) !=0){ s_registeredWait = ThreadPool.UnsafeRegisterWaitForSingleObject( s_ipv6WaitHandle, new WaitOrTimerCallback(AddressChangedCallback), StartIPOptions.StartIPv6, -1, true ); errorCode = (SocketError) UnsafeNclNativeMethods.OSSOCK.WSAIoctl_Blocking( s_ipv6Socket.DangerousGetHandle(), (int) IOControlCode.AddressListChange, null, 0, null, 0, out length, SafeNativeOverlapped.Zero, IntPtr.Zero); if (errorCode != SocketError.Success) { NetworkInformationException exception = new NetworkInformationException(); if (exception.ErrorCode != (uint)SocketError.WouldBlock) { throw exception; } } errorCode = (SocketError)UnsafeNclNativeMethods.OSSOCK.WSAEventSelect(s_ipv6Socket, s_ipv6Socket.GetEventHandle().SafeWaitHandle, AsyncEventBits.FdAddressListChange); if (errorCode != SocketError.Success) { throw new NetworkInformationException(); } } } s_isListening = true; s_isPending = true; } }
private static void StartHelper(NetworkAddressChangedEventHandler caller, bool captureContext, StartIPOptions startIPOptions) { lock (s_callerArray) { // Setup changedEvent and native overlapped struct. if (s_ipv4Socket == null) { int blocking; // Sockets will be initialized by the call to OSSupportsIP*. if (Socket.OSSupportsIPv4) { blocking = -1; s_ipv4Socket = SafeCloseSocketAndEvent.CreateWSASocketWithEvent(AddressFamily.InterNetwork, SocketType.Dgram, (ProtocolType)0, true, false); Interop.Winsock.ioctlsocket(s_ipv4Socket, Interop.Winsock.IoctlSocketConstants.FIONBIO, ref blocking); s_ipv4WaitHandle = s_ipv4Socket.GetEventHandle(); } if (Socket.OSSupportsIPv6) { blocking = -1; s_ipv6Socket = SafeCloseSocketAndEvent.CreateWSASocketWithEvent(AddressFamily.InterNetworkV6, SocketType.Dgram, (ProtocolType)0, true, false); Interop.Winsock.ioctlsocket(s_ipv6Socket, Interop.Winsock.IoctlSocketConstants.FIONBIO, ref blocking); s_ipv6WaitHandle = s_ipv6Socket.GetEventHandle(); } } if ((caller != null) && (!s_callerArray.ContainsKey(caller))) { s_callerArray.Add(caller, captureContext ? ExecutionContext.Capture() : null); } if (s_isListening || s_callerArray.Count == 0) { return; } if (!s_isPending) { int length; SocketError errorCode; if (Socket.OSSupportsIPv4 && (startIPOptions & StartIPOptions.StartIPv4) != 0) { s_registeredWait = ThreadPool.RegisterWaitForSingleObject( s_ipv4WaitHandle, new WaitOrTimerCallback(AddressChangedCallback), StartIPOptions.StartIPv4, -1, true); errorCode = Interop.Winsock.WSAIoctl_Blocking( s_ipv4Socket.DangerousGetHandle(), (int)IOControlCode.AddressListChange, null, 0, null, 0, out length, SafeNativeOverlapped.Zero, IntPtr.Zero); if (errorCode != SocketError.Success) { NetworkInformationException exception = new NetworkInformationException(); if (exception.ErrorCode != (uint)SocketError.WouldBlock) { throw exception; } } SafeWaitHandle s_ipv4SocketGetEventHandleSafeWaitHandle = s_ipv4Socket.GetEventHandle().GetSafeWaitHandle(); errorCode = Interop.Winsock.WSAEventSelect( s_ipv4Socket, s_ipv4SocketGetEventHandleSafeWaitHandle, Interop.Winsock.AsyncEventBits.FdAddressListChange); if (errorCode != SocketError.Success) { throw new NetworkInformationException(); } } if (Socket.OSSupportsIPv6 && (startIPOptions & StartIPOptions.StartIPv6) != 0) { s_registeredWait = ThreadPool.RegisterWaitForSingleObject( s_ipv6WaitHandle, new WaitOrTimerCallback(AddressChangedCallback), StartIPOptions.StartIPv6, -1, true); errorCode = Interop.Winsock.WSAIoctl_Blocking( s_ipv6Socket.DangerousGetHandle(), (int)IOControlCode.AddressListChange, null, 0, null, 0, out length, SafeNativeOverlapped.Zero, IntPtr.Zero); if (errorCode != SocketError.Success) { NetworkInformationException exception = new NetworkInformationException(); if (exception.ErrorCode != (uint)SocketError.WouldBlock) { throw exception; } } SafeWaitHandle s_ipv6SocketGetEventHandleSafeWaitHandle = s_ipv6Socket.GetEventHandle().GetSafeWaitHandle(); errorCode = Interop.Winsock.WSAEventSelect( s_ipv6Socket, s_ipv6SocketGetEventHandleSafeWaitHandle, Interop.Winsock.AsyncEventBits.FdAddressListChange); if (errorCode != SocketError.Success) { throw new NetworkInformationException(); } } } s_isListening = true; s_isPending = true; } }
public void Dispose() { if(!disposed){ lock (this){ if (!disposed){ if(ipv6Socket != null){ ipv6Socket.Close(); ipv6Socket = null; } if(ipv4Socket != null){ ipv4Socket.Close(); ipv6Socket = null; } disposed = true; } } } }
internal unsafe NetworkAddressChangePolled() { Socket.InitializeSockets(); int blocking; if (Socket.OSSupportsIPv4) { blocking = -1; ipv4Socket = SafeCloseSocketAndEvent.CreateWSASocketWithEvent(AddressFamily.InterNetwork, SocketType.Dgram, (ProtocolType)0, true, false); UnsafeNclNativeMethods.OSSOCK.ioctlsocket(ipv4Socket, IoctlSocketConstants.FIONBIO, ref blocking); } if(Socket.OSSupportsIPv6){ blocking = -1; ipv6Socket = SafeCloseSocketAndEvent.CreateWSASocketWithEvent(AddressFamily.InterNetworkV6, SocketType.Dgram, (ProtocolType)0, true, false); UnsafeNclNativeMethods.OSSOCK.ioctlsocket(ipv6Socket,IoctlSocketConstants.FIONBIO,ref blocking); } Setup(StartIPOptions.Both); }
private static void StartHelper(NetworkAddressChangedEventHandler caller, bool captureContext, StartIPOptions startIPOptions) { lock (s_callerArray) { if (s_ipv4Socket == null) { int num; Socket.InitializeSockets(); if (Socket.OSSupportsIPv4) { num = -1; s_ipv4Socket = SafeCloseSocketAndEvent.CreateWSASocketWithEvent(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.IP, true, false); UnsafeNclNativeMethods.OSSOCK.ioctlsocket(s_ipv4Socket, -2147195266, ref num); s_ipv4WaitHandle = s_ipv4Socket.GetEventHandle(); } if (Socket.OSSupportsIPv6) { num = -1; s_ipv6Socket = SafeCloseSocketAndEvent.CreateWSASocketWithEvent(AddressFamily.InterNetworkV6, SocketType.Dgram, ProtocolType.IP, true, false); UnsafeNclNativeMethods.OSSOCK.ioctlsocket(s_ipv6Socket, -2147195266, ref num); s_ipv6WaitHandle = s_ipv6Socket.GetEventHandle(); } } if ((caller != null) && !s_callerArray.Contains(caller)) { s_callerArray.Add(caller, captureContext ? ExecutionContext.Capture() : null); } if (!s_isListening && (s_callerArray.Count != 0)) { if (!s_isPending) { int num2; if (Socket.OSSupportsIPv4 && ((startIPOptions & StartIPOptions.StartIPv4) != StartIPOptions.None)) { s_registeredWait = ThreadPool.UnsafeRegisterWaitForSingleObject(s_ipv4WaitHandle, new WaitOrTimerCallback(NetworkChange.AddressChangeListener.AddressChangedCallback), StartIPOptions.StartIPv4, -1, true); if (UnsafeNclNativeMethods.OSSOCK.WSAIoctl_Blocking(s_ipv4Socket.DangerousGetHandle(), 0x28000017, null, 0, null, 0, out num2, SafeNativeOverlapped.Zero, IntPtr.Zero) != SocketError.Success) { NetworkInformationException exception = new NetworkInformationException(); if (exception.ErrorCode != 0x2733L) { throw exception; } } if (UnsafeNclNativeMethods.OSSOCK.WSAEventSelect(s_ipv4Socket, s_ipv4Socket.GetEventHandle().SafeWaitHandle, AsyncEventBits.FdAddressListChange) != SocketError.Success) { throw new NetworkInformationException(); } } if (Socket.OSSupportsIPv6 && ((startIPOptions & StartIPOptions.StartIPv6) != StartIPOptions.None)) { s_registeredWait = ThreadPool.UnsafeRegisterWaitForSingleObject(s_ipv6WaitHandle, new WaitOrTimerCallback(NetworkChange.AddressChangeListener.AddressChangedCallback), StartIPOptions.StartIPv6, -1, true); if (UnsafeNclNativeMethods.OSSOCK.WSAIoctl_Blocking(s_ipv6Socket.DangerousGetHandle(), 0x28000017, null, 0, null, 0, out num2, SafeNativeOverlapped.Zero, IntPtr.Zero) != SocketError.Success) { NetworkInformationException exception2 = new NetworkInformationException(); if (exception2.ErrorCode != 0x2733L) { throw exception2; } } if (UnsafeNclNativeMethods.OSSOCK.WSAEventSelect(s_ipv6Socket, s_ipv6Socket.GetEventHandle().SafeWaitHandle, AsyncEventBits.FdAddressListChange) != SocketError.Success) { throw new NetworkInformationException(); } } } s_isListening = true; s_isPending = true; } } }