Socket error codes linux

How Socket Error Codes Depend on Runtime and Operating System

Rider consists of several processes that send messages to each other via sockets. To ensure the reliability of the whole application, it’s important to properly handle all the socket errors. In our codebase, we had the following code which was adopted from Mono Debugger Libs and helps us communicate with debugger processes:

 In the case of a failed connection because of a “ConnectionRefused” error, we are retrying the connection attempt. It works fine with .NET Framework and Mono. However, once we migrated to .NET Core, this method no longer correctly detects the “connection refused” situation on Linux and macOS. If we open the SocketException documentation, we will learn that this class has three different properties with error codes:
  • SocketError SocketErrorCode : Gets the error code that is associated with this exception.
  • int ErrorCode : Gets the error code that is associated with this exception.
  • int NativeErrorCode : Gets the Win32 error code associated with this exception.

Digging into the problem

Let’s start with the following program, which prints error code property values for SocketError.ConnectionRefused :

If we run it on Windows, we will get the same value on .NET Framework, Mono, and .NET Core:

SocketErrorCode

SocketException.SocketErrorCode returns a value from the SocketError enum. The numerical values of the enum elements are the same on all the runtimes (see its implementation in .NET Framework, .NET Core 3.1.3, and Mono 6.8.0.105):

                                              These values correspond to the Windows Sockets Error Codes.

NativeErrorCode

  In .NET Core, the native code is calculated in the constructor (see SocketException.cs#L20):
  The Windows implementation of GetNativeErrorForSocketError is trivial (see SocketException.Windows.cs):
 The Unix implementation is more complicated (see SocketException.Unix.cs):
  TryGetNativeErrorForSocketError should convert SocketError to the native Unix error code. Unfortunately, there exists no unequivocal mapping between Windows and Unix error codes. As such, the .NET team decided to create a Dictionary that maps error codes in the best possible way (see SocketErrorPal.Unix.cs):
                 Once we have an instance of Interop.Error , we call interopErr.Info().RawErrno . The implementation of RawErrno can be found in Interop.Errors.cs:
 Here we are jumping to the native function SystemNative_ConvertErrorPalToPlatform that maps Error to the native integer code that is defined in errno.h. You can get all the values using the errno util. Here is a typical output on Linux:

Note that errno may be not available by default in your Linux distro. For example, on Debian, you should call sudo apt-get install moreutils to get this utility. Here is a typical output on macOS:

Hooray! We’ve finished our fascinating journey into the internals of socket error codes. Now you know where .NET is getting the native error code for each SocketException from!

ErrorCode

The ErrorCode property is the most boring one, as it always returns NativeErrorCode . .NET Framework, Mono 6.8.0.105:

Circling back to the original method we started this post with, we rewrote ShouldRetryConnection as follows:

There was a lot of work involved in tracking down the error code to check against, but in the end, our code is much more readable now. Adding to that, this method is now also completely cross-platform, and works correctly on any runtime.

Overview of the native error codes

In some situations, you may want to have a table with native error codes on different operating systems. We can get these values with the following code snippet:

 | |"We executed this program on Windows, Linux, and macOS. Here are the aggregated results:
SocketError Windows Linux macOS
Success 0 0 0
OperationAborted 995 125 89
IOPending 997 115 36
Interrupted 10004 4 4
AccessDenied 10013 13 13
Fault 10014 14 14
InvalidArgument 10022 22 22
TooManyOpenSockets 10024 23 23
WouldBlock 10035 11 35
InProgress 10036 115 36
AlreadyInProgress 10037 114 37
NotSocket 10038 88 38
DestinationAddressRequired 10039 89 39
MessageSize 10040 90 40
ProtocolType 10041 91 41
ProtocolOption 10042 92 42
ProtocolNotSupported 10043 93 43
SocketNotSupported 10044 94 44
OperationNotSupported 10045 95 45
ProtocolFamilyNotSupported 10046 96 46
AddressFamilyNotSupported 10047 97 47
AddressAlreadyInUse 10048 98 48
AddressNotAvailable 10049 99 49
NetworkDown 10050 100 50
NetworkUnreachable 10051 101 51
NetworkReset 10052 102 52
ConnectionAborted 10053 103 53
ConnectionReset 10054 104 54
NoBufferSpaceAvailable 10055 105 55
IsConnected 10056 106 56
NotConnected 10057 107 57
Shutdown 10058 32 32
TimedOut 10060 110 60
ConnectionRefused 10061 111 61
HostDown 10064 112 64
HostUnreachable 10065 113 65
ProcessLimit 10067 10067 10067
SystemNotReady 10091 10091 10091
VersionNotSupported 10092 10092 10092
NotInitialized 10093 10093 10093
Disconnecting 10101 108 58
TypeNotFound 10109 10109 10109
HostNotFound 11001 -131073 -131073
TryAgain 11002 11 35
NoRecovery 11003 11003 11003
NoData 11004 61 96
SocketError -1 -1 -1

This table may be useful if you work with native socket error codes.

Summary

  • SocketException.SocketErrorCode returns a value from the SocketError enum. The numerical values of the enum elements always correspond to the Windows socket error codes.
  • SocketException.ErrorCode always returns SocketException.NativeErrorCode .
  • SocketException.NativeErrorCode on .NET Framework and Mono always corresponds to the Windows error codes (even if you are using Mono on Unix). On .NET Core, SocketException.NativeErrorCode equals the corresponding native error code from the current operating system.

A few practical recommendations:

  • If you want to write portable code, always use SocketException.SocketErrorCode and compare it with the values of SocketError . Never use raw numerical error codes.
  • If you want to get the native error code on .NET Core (e.g., for passing to another native program), use SocketException.NativeErrorCode . Remember that different Unix-based operating systems (e.g., Linux, macOS, Solaris) have different native code sets. You can get the exact values of the native error codes by using the errno command.

References

Источник

gabrielfalcao / tcp-socket-error-codes-errno.txt

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters

0 = Success
1 = Operation not permitted
2 = No such file or directory
3 = No such process
4 = Interrupted system call
5 = Input/output error
6 = No such device or address
7 = Argument list too long
8 = Exec format error
9 = Bad file descriptor
10 = No child processes
11 = Resource temporarily unavailable
12 = Cannot allocate memory
13 = Permission denied
14 = Bad address
15 = Block device required
16 = Device or resource busy
17 = File exists
18 = Invalid cross-device link
19 = No such device
20 = Not a directory
21 = Is a directory
22 = Invalid argument
23 = Too many open files in system
24 = Too many open files
25 = Inappropriate ioctl for device
26 = Text file busy
27 = File too large
28 = No space left on device
29 = Illegal seek
30 = Read-only file system
31 = Too many links
32 = Broken pipe
33 = Numerical argument out of domain
34 = Numerical result out of range
35 = Resource deadlock avoided
36 = File name too long
37 = No locks available
38 = Function not implemented
39 = Directory not empty
40 = Too many levels of symbolic links
41 = Unknown error 41
42 = No message of desired type
43 = Identifier removed
44 = Channel number out of range
45 = Level 2 not synchronized
46 = Level 3 halted
47 = Level 3 reset
48 = Link number out of range
49 = Protocol driver not attached
50 = No CSI structure available
51 = Level 2 halted
52 = Invalid exchange
53 = Invalid request descriptor
54 = Exchange full
55 = No anode
56 = Invalid request code
57 = Invalid slot
58 = Unknown error 58
59 = Bad font file format
60 = Device not a stream
61 = No data available
62 = Timer expired
63 = Out of streams resources
64 = Machine is not on the network
65 = Package not installed
66 = Object is remote
67 = Link has been severed
68 = Advertise error
69 = Srmount error
70 = Communication error on send
71 = Protocol error
72 = Multihop attempted
73 = RFS specific error
74 = Bad message
75 = Value too large for defined data type
76 = Name not unique on network
77 = File descriptor in bad state
78 = Remote address changed
79 = Can not access a needed shared library
80 = Accessing a corrupted shared library
81 = .lib section in a.out corrupted
82 = Attempting to link in too many shared libraries
83 = Cannot exec a shared library directly
84 = Invalid or incomplete multibyte or wide character
85 = Interrupted system call should be restarted
86 = Streams pipe error
87 = Too many users
88 = Socket operation on non-socket
89 = Destination address required
90 = Message too long
91 = Protocol wrong type for socket
92 = Protocol not available
93 = Protocol not supported
94 = Socket type not supported
95 = Operation not supported
96 = Protocol family not supported
97 = Address family not supported by protocol
98 = Address already in use
99 = Cannot assign requested address
100 = Network is down
101 = Network is unreachable
102 = Network dropped connection on reset
103 = Software caused connection abort
104 = Connection reset by peer
105 = No buffer space available
106 = Transport endpoint is already connected
107 = Transport endpoint is not connected
108 = Cannot send after transport endpoint shutdown
109 = Too many references: cannot splice
110 = Connection timed out
111 = Connection refused
112 = Host is down
113 = No route to host
114 = Operation already in progress
115 = Operation now in progress
116 = Stale NFS file handle
117 = Structure needs cleaning
118 = Not a XENIX named type file
119 = No XENIX semaphores available
120 = Is a named type file
121 = Remote I/O error
122 = Disk quota exceeded
123 = No medium found
124 = Wrong medium type

Источник

Читайте также:  Установка glpi на astra linux
Оцените статью
Adblock
detector