GetSocketErrorForErrorCode() 공개 정적인 메소드

public static GetSocketErrorForErrorCode ( System.Net.Interop errorCode ) : SocketError
errorCode System.Net.Interop
리턴 SocketError
            private Interop.Error CloseHandle(IntPtr handle)
            {
                Interop.Error errorCode     = Interop.Error.SUCCESS;
                bool          remappedError = false;

                if (Interop.Sys.Close(handle) != 0)
                {
                    errorCode = Interop.Sys.GetLastError();
                    if (errorCode == Interop.Error.ECONNRESET)
                    {
                        // Some Unix platforms (e.g. FreeBSD) non-compliantly return ECONNRESET from close().
                        // For our purposes, we want to ignore such a "failure" and treat it as success.
                        // In such a case, the file descriptor was still closed and there's no corrective
                        // action to take.
                        errorCode     = Interop.Error.SUCCESS;
                        remappedError = true;
                    }
                }

                if (NetEventSource.IsEnabled)
                {
                    NetEventSource.Info(this, remappedError ?
                                        $"handle:{handle}, close():ECONNRESET, but treating it as SUCCESS" :
                                        $"handle:{handle}, close():{errorCode}");
                }

#if DEBUG
                _closeSocketHandle = handle;
                _closeSocketResult = SocketPal.GetSocketErrorForErrorCode(errorCode);
#endif

                return(errorCode);
            }
예제 #2
0
            public static unsafe InnerSafeCloseSocket CreateSocket(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType, out SocketError errorCode)
            {
                int fd;

                Interop.Error error = Interop.Sys.Socket(addressFamily, socketType, protocolType, &fd);
                if (error == Interop.Error.SUCCESS)
                {
                    Debug.Assert(fd != -1);

                    errorCode = SocketError.Success;

                    // The socket was created successfully; make it non-blocking and enable
                    // IPV6_V6ONLY by default for AF_INET6 sockets.
                    int err = Interop.Sys.Fcntl.SetIsNonBlocking((IntPtr)fd, 1);
                    if (err != 0)
                    {
                        Interop.Sys.Close((IntPtr)fd);
                        fd        = -1;
                        errorCode = SocketError.SocketError;
                    }
                    else if (addressFamily == AddressFamily.InterNetworkV6)
                    {
                        int on = 1;
                        error = Interop.Sys.SetSockOpt(fd, SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, (byte *)&on, sizeof(int));
                        if (error != Interop.Error.SUCCESS)
                        {
                            Interop.Sys.Close((IntPtr)fd);
                            fd        = -1;
                            errorCode = SocketPal.GetSocketErrorForErrorCode(error);
                        }
                    }
                }
                else
                {
                    Debug.Assert(fd == -1);

                    errorCode = SocketPal.GetSocketErrorForErrorCode(error);
                }

                var res = new InnerSafeCloseSocket();

                res.SetHandle((IntPtr)fd);
                return(res);
            }
            internal static unsafe InnerSafeCloseSocket CreateSocket(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType, out SocketError errorCode)
            {
                IntPtr fd;

                Interop.Error error = Interop.Sys.Socket(addressFamily, socketType, protocolType, &fd);
                if (error == Interop.Error.SUCCESS)
                {
                    Debug.Assert(fd != (IntPtr)(-1), "fd should not be -1");

                    errorCode = SocketError.Success;

                    // The socket was created successfully; enable IPV6_V6ONLY by default for normal AF_INET6 sockets.
                    // This fails on raw sockets so we just let them be in default state.
                    if (addressFamily == AddressFamily.InterNetworkV6 && socketType != SocketType.Raw)
                    {
                        int on = 1;
                        error = Interop.Sys.SetSockOpt(fd, SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, (byte *)&on, sizeof(int));
                        if (error != Interop.Error.SUCCESS)
                        {
                            Interop.Sys.Close(fd);
                            fd        = (IntPtr)(-1);
                            errorCode = SocketPal.GetSocketErrorForErrorCode(error);
                        }
                    }
                }
                else
                {
                    Debug.Assert(fd == (IntPtr)(-1), $"Unexpected fd: {fd}");

                    errorCode = SocketPal.GetSocketErrorForErrorCode(error);
                }

                var res = new InnerSafeCloseSocket();

                res.SetHandle(fd);
                return(res);
            }
예제 #4
0
            public static unsafe InnerSafeCloseSocket CreateSocket(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType, out SocketError errorCode)
            {
                int fd;

                Interop.Error error = Interop.Sys.Socket(addressFamily, socketType, protocolType, &fd);
                if (error == Interop.Error.SUCCESS)
                {
                    Debug.Assert(fd != -1, "fd should not be -1");

                    errorCode = SocketError.Success;

                    // The socket was created successfully; enable IPV6_V6ONLY by default for AF_INET6 sockets.
                    if (addressFamily == AddressFamily.InterNetworkV6)
                    {
                        int on = 1;
                        error = Interop.Sys.DangerousSetSockOpt(fd, SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, (byte *)&on, sizeof(int));
                        if (error != Interop.Error.SUCCESS)
                        {
                            Interop.Sys.Close((IntPtr)fd);
                            fd        = -1;
                            errorCode = SocketPal.GetSocketErrorForErrorCode(error);
                        }
                    }
                }
                else
                {
                    Debug.Assert(fd == -1, $"Unexpected fd: {fd}");

                    errorCode = SocketPal.GetSocketErrorForErrorCode(error);
                }

                var res = new InnerSafeCloseSocket();

                res.SetHandle((IntPtr)fd);
                return(res);
            }
            private unsafe SocketError InnerReleaseHandle()
            {
                Interop.Error errorCode = Interop.Error.SUCCESS;

                // If _abortive was set to false in Close, it's safe to block here, which means
                // we can honor the linger options set on the socket.  It also means closesocket() might return WSAEWOULDBLOCK, in which
                // case we need to do some recovery.
                if (!_abortive)
                {
                    if (NetEventSource.IsEnabled)
                    {
                        NetEventSource.Info(this, $"handle:{handle} Following 'non-abortive' branch.");
                    }

                    // Close, and if its errno is other than EWOULDBLOCK, there's nothing more to do - we either succeeded or failed.
                    errorCode = CloseHandle(handle);
                    if (errorCode != Interop.Error.EWOULDBLOCK)
                    {
                        return(SocketPal.GetSocketErrorForErrorCode(errorCode));
                    }

                    // The socket must be non-blocking with a linger timeout set.
                    // We have to set the socket to blocking.
                    if (Interop.Sys.Fcntl.DangerousSetIsNonBlocking(handle, 0) == 0)
                    {
                        // The socket successfully made blocking; retry the close().
                        return(SocketPal.GetSocketErrorForErrorCode(CloseHandle(handle)));
                    }

                    // The socket could not be made blocking; fall through to the regular abortive close.
                }

                // By default or if the non-abortive path failed, set linger timeout to zero to get an abortive close (RST).
                var linger = new Interop.Sys.LingerOption
                {
                    OnOff   = 1,
                    Seconds = 0
                };

                errorCode = Interop.Sys.SetLingerOption(handle, &linger);
#if DEBUG
                _closeSocketLinger = SocketPal.GetSocketErrorForErrorCode(errorCode);
#endif
                if (NetEventSource.IsEnabled)
                {
                    NetEventSource.Info(this, $"handle:{handle}, setsockopt():{errorCode}");
                }

                switch (errorCode)
                {
                case Interop.Error.SUCCESS:
                case Interop.Error.EINVAL:
                case Interop.Error.ENOPROTOOPT:
                    errorCode = CloseHandle(handle);
                    break;

                    // For other errors, it's too dangerous to try closesocket() - it might block!
                }

                return(SocketPal.GetSocketErrorForErrorCode(errorCode));
            }
예제 #6
0
            private unsafe SocketError InnerReleaseHandle()
            {
                int errorCode;

                // If _blockable was set in BlockingRelease, it's safe to block here, which means
                // we can honor the linger options set on the socket.  It also means closesocket() might return WSAEWOULDBLOCK, in which
                // case we need to do some recovery.
                if (_blockable)
                {
                    if (NetEventSource.IsEnabled)
                    {
                        NetEventSource.Info(this, $"handle:{handle} Following 'blockable' branch.");
                    }

                    errorCode = Interop.Sys.Close(handle);
                    if (errorCode == -1)
                    {
                        errorCode = (int)Interop.Sys.GetLastError();
                    }

                    if (NetEventSource.IsEnabled)
                    {
                        NetEventSource.Info(this, $"handle:{handle}, close()#1:{errorCode}");
                    }
#if DEBUG
                    _closeSocketHandle = handle;
                    _closeSocketResult = SocketPal.GetSocketErrorForErrorCode((Interop.Error)errorCode);
#endif

                    // If it's not EWOULDBLOCK, there's no more recourse - we either succeeded or failed.
                    if (errorCode != (int)Interop.Error.EWOULDBLOCK)
                    {
                        return(SocketPal.GetSocketErrorForErrorCode((Interop.Error)errorCode));
                    }

                    // The socket must be non-blocking with a linger timeout set.
                    // We have to set the socket to blocking.
                    errorCode = Interop.Sys.Fcntl.DangerousSetIsNonBlocking(handle, 0);
                    if (errorCode == 0)
                    {
                        // The socket successfully made blocking; retry the close().
                        errorCode = Interop.Sys.Close(handle);

                        if (NetEventSource.IsEnabled)
                        {
                            NetEventSource.Info(this, $"handle:{handle}, close()#2:{errorCode}");
                        }
#if DEBUG
                        _closeSocketHandle = handle;
                        _closeSocketResult = SocketPal.GetSocketErrorForErrorCode((Interop.Error)errorCode);
#endif
                        return(SocketPal.GetSocketErrorForErrorCode((Interop.Error)errorCode));
                    }

                    // The socket could not be made blocking; fall through to the regular abortive close.
                }

                // By default or if CloseAsIs() path failed, set linger timeout to zero to get an abortive close (RST).
                var linger = new Interop.Sys.LingerOption {
                    OnOff   = 1,
                    Seconds = 0
                };

                errorCode = (int)Interop.Sys.SetLingerOption(handle, &linger);
#if DEBUG
                _closeSocketLinger = SocketPal.GetSocketErrorForErrorCode((Interop.Error)errorCode);
#endif
                if (NetEventSource.IsEnabled)
                {
                    NetEventSource.Info(this, $"handle:{handle}, setsockopt():{errorCode}");
                }

                if (errorCode != 0 && errorCode != (int)Interop.Error.EINVAL && errorCode != (int)Interop.Error.ENOPROTOOPT)
                {
                    // Too dangerous to try closesocket() - it might block!
                    return(SocketPal.GetSocketErrorForErrorCode((Interop.Error)errorCode));
                }

                errorCode = Interop.Sys.Close(handle);
#if DEBUG
                _closeSocketHandle = handle;
                _closeSocketResult = SocketPal.GetSocketErrorForErrorCode((Interop.Error)errorCode);
#endif
                if (NetEventSource.IsEnabled)
                {
                    NetEventSource.Info(this, $"handle:{handle}, close#3():{(errorCode == -1 ? (int)Interop.Sys.GetLastError() : errorCode)}");
                }

                return(SocketPal.GetSocketErrorForErrorCode((Interop.Error)errorCode));
            }
예제 #7
0
            private unsafe SocketError InnerReleaseHandle()
            {
                int errorCode;

                if (_asyncContext != null)
                {
                    _asyncContext.Close();
                }

                // If _blockable was set in BlockingRelease, it's safe to block here, which means
                // we can honor the linger options set on the socket.  It also means closesocket() might return WSAEWOULDBLOCK, in which
                // case we need to do some recovery.
                if (_blockable)
                {
                    GlobalLog.Print("SafeCloseSocket::ReleaseHandle(handle:" + handle.ToString("x") + ") Following 'blockable' branch.");

                    errorCode = Interop.Sys.Close((int)handle);
                    if (errorCode == -1)
                    {
                        errorCode = (int)Interop.Sys.GetLastError();
                    }
                    GlobalLog.Print("SafeCloseSocket::ReleaseHandle(handle:" + handle.ToString("x") + ") close()#1:" + errorCode.ToString());

#if DEBUG
                    _closeSocketHandle = handle;
                    _closeSocketResult = SocketPal.GetSocketErrorForErrorCode((Interop.Error)errorCode);
#endif

                    // If it's not EWOULDBLOCK, there's no more recourse - we either succeeded or failed.
                    if (errorCode != (int)Interop.Error.EWOULDBLOCK)
                    {
                        if (errorCode == 0 && _asyncContext != null)
                        {
                            _asyncContext.Close();
                        }
                        return(SocketPal.GetSocketErrorForErrorCode((Interop.Error)errorCode));
                    }

                    // The socket must be non-blocking with a linger timeout set.
                    // We have to set the socket to blocking.
                    errorCode = Interop.Sys.Fcntl.SetIsNonBlocking((int)handle, 0);
                    if (errorCode == 0)
                    {
                        // The socket successfully made blocking; retry the close().
                        errorCode = Interop.Sys.Close((int)handle);

                        GlobalLog.Print("SafeCloseSocket::ReleaseHandle(handle:" + handle.ToString("x") + ") close()#2:" + errorCode.ToString());
#if DEBUG
                        _closeSocketHandle = handle;
                        _closeSocketResult = SocketPal.GetSocketErrorForErrorCode((Interop.Error)errorCode);
#endif
                        if (errorCode == 0 && _asyncContext != null)
                        {
                            _asyncContext.Close();
                        }
                        return(SocketPal.GetSocketErrorForErrorCode((Interop.Error)errorCode));
                    }

                    // The socket could not be made blocking; fall through to the regular abortive close.
                }

                // By default or if CloseAsIs() path failed, set linger timeout to zero to get an abortive close (RST).
                var linger = new Interop.libc.linger {
                    l_onoff  = 1,
                    l_linger = 0
                };

                errorCode = Interop.libc.setsockopt((int)handle, Interop.libc.SOL_SOCKET, Interop.libc.SO_LINGER, &linger, (uint)sizeof(Interop.libc.linger));
#if DEBUG
                _closeSocketLinger = SocketPal.GetSocketErrorForErrorCode((Interop.Error)errorCode);
#endif
                if (errorCode == -1)
                {
                    errorCode = (int)Interop.Sys.GetLastError();
                }
                GlobalLog.Print("SafeCloseSocket::ReleaseHandle(handle:" + handle.ToString("x") + ") setsockopt():" + errorCode.ToString());

                if (errorCode != 0 && errorCode != (int)Interop.Error.EINVAL && errorCode != (int)Interop.Error.ENOPROTOOPT)
                {
                    // Too dangerous to try closesocket() - it might block!
                    return(SocketPal.GetSocketErrorForErrorCode((Interop.Error)errorCode));
                }

                errorCode = Interop.Sys.Close((int)handle);
#if DEBUG
                _closeSocketHandle = handle;
                _closeSocketResult = SocketPal.GetSocketErrorForErrorCode((Interop.Error)errorCode);
#endif
                GlobalLog.Print("SafeCloseSocket::ReleaseHandle(handle:" + handle.ToString("x") + ") close#3():" + (errorCode == -1 ? (int)Interop.Sys.GetLastError() : errorCode).ToString());

                return(SocketPal.GetSocketErrorForErrorCode((Interop.Error)errorCode));
            }