diff options
| author | Colin Davidson <colrdavidson@gmail.com> | 2023-03-02 06:43:20 -0800 |
|---|---|---|
| committer | Colin Davidson <colrdavidson@gmail.com> | 2023-03-02 06:43:20 -0800 |
| commit | 64f200dc7419a3b1b8b4ae387d5add57b680ca3e (patch) | |
| tree | 1c05f885cb127bef5974831a74aad4b44773ab9c /core/net/errors_linux.odin | |
| parent | c02ff3af27afc013336de24570bbbaf1d66643d0 (diff) | |
big error cleanup
Diffstat (limited to 'core/net/errors_linux.odin')
| -rw-r--r-- | core/net/errors_linux.odin | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/core/net/errors_linux.odin b/core/net/errors_linux.odin new file mode 100644 index 000000000..16a5411ea --- /dev/null +++ b/core/net/errors_linux.odin @@ -0,0 +1,175 @@ +// +build linux +/* + Copyright 2022 Tetralux <tetraluxonpc@gmail.com> + Copyright 2022 Colin Davidson <colrdavidson@gmail.com> + Copyright 2022 Jeroen van Rijn <nom@duclavier.com>. + Made available under Odin's BSD-3 license. + + List of contributors: + Tetralux: Initial implementation + Colin Davidson: Linux platform code, OSX platform code, Odin-native DNS resolver + Jeroen van Rijn: Cross platform unification, code style, documentation +*/ + +/* + Package net implements cross-platform Berkeley Sockets, DNS resolution and associated procedures. + For other protocols and their features, see subdirectories of this package. +*/ +package net + +import "core:c" +import "core:os" + +Create_Socket_Error :: enum c.int { + Family_Not_Supported_For_This_Socket = c.int(os.EAFNOSUPPORT), + No_Socket_Descriptors_Available = c.int(os.EMFILE), + No_Buffer_Space_Available = c.int(os.ENOBUFS), + No_Memory_Available_Available = c.int(os.ENOMEM), + Protocol_Unsupported_By_System = c.int(os.EPROTONOSUPPORT), + Wrong_Protocol_For_Socket = c.int(os.EPROTONOSUPPORT), + Family_And_Socket_Type_Mismatch = c.int(os.EPROTONOSUPPORT), +} + +Dial_Error :: enum c.int { + Port_Required = -1, + + Address_In_Use = c.int(os.EADDRINUSE), + In_Progress = c.int(os.EINPROGRESS), + Cannot_Use_Any_Address = c.int(os.EADDRNOTAVAIL), + Wrong_Family_For_Socket = c.int(os.EAFNOSUPPORT), + Refused = c.int(os.ECONNREFUSED), + Is_Listening_Socket = c.int(os.EACCES), + Already_Connected = c.int(os.EISCONN), + Network_Unreachable = c.int(os.ENETUNREACH), // Device is offline + Host_Unreachable = c.int(os.EHOSTUNREACH), // Remote host cannot be reached + No_Buffer_Space_Available = c.int(os.ENOBUFS), + Not_Socket = c.int(os.ENOTSOCK), + Timeout = c.int(os.ETIMEDOUT), + + // TODO: we may need special handling for this; maybe make a socket a struct with metadata? + Would_Block = c.int(os.EWOULDBLOCK), +} + +Bind_Error :: enum c.int { + Address_In_Use = c.int(os.EADDRINUSE), // Another application is currently bound to this endpoint. + Given_Nonlocal_Address = c.int(os.EADDRNOTAVAIL), // The address is not a local address on this machine. + Broadcast_Disabled = c.int(os.EACCES), // To bind a UDP socket to the broadcast address, the appropriate socket option must be set. + Address_Family_Mismatch = c.int(os.EFAULT), // The address family of the address does not match that of the socket. + Already_Bound = c.int(os.EINVAL), // The socket is already bound to an address. + No_Ports_Available = c.int(os.ENOBUFS), // There are not enough ephemeral ports available. +} + +Listen_Error :: enum c.int { + Address_In_Use = c.int(os.EADDRINUSE), + Already_Connected = c.int(os.EISCONN), + No_Socket_Descriptors_Available = c.int(os.EMFILE), + No_Buffer_Space_Available = c.int(os.ENOBUFS), + Nonlocal_Address = c.int(os.EADDRNOTAVAIL), + Not_Socket = c.int(os.ENOTSOCK), + Listening_Not_Supported_For_This_Socket = c.int(os.EOPNOTSUPP), +} + +Accept_Error :: enum c.int { + Not_Listening = c.int(os.EINVAL), + No_Socket_Descriptors_Available_For_Client_Socket = c.int(os.EMFILE), + No_Buffer_Space_Available = c.int(os.ENOBUFS), + Not_Socket = c.int(os.ENOTSOCK), + Not_Connection_Oriented_Socket = c.int(os.EOPNOTSUPP), + + // TODO: we may need special handling for this; maybe make a socket a struct with metadata? + Would_Block = c.int(os.EWOULDBLOCK), +} + +TCP_Recv_Error :: enum c.int { + Shutdown = c.int(os.ESHUTDOWN), + Not_Connected = c.int(os.ENOTCONN), + Connection_Broken = c.int(os.ENETRESET), + Not_Socket = c.int(os.ENOTSOCK), + Aborted = c.int(os.ECONNABORTED), + + // TODO(tetra): Determine when this is different from the syscall returning n=0 and maybe normalize them? + Connection_Closed = c.int(os.ECONNRESET), + Offline = c.int(os.ENETDOWN), + Host_Unreachable = c.int(os.EHOSTUNREACH), + Interrupted = c.int(os.EINTR), + Timeout = c.int(os.EWOULDBLOCK), // NOTE: No, really. Presumably this means something different for nonblocking sockets... +} + +UDP_Recv_Error :: enum c.int { + // The buffer is too small to fit the entire message, and the message was truncated. + // When this happens, the rest of message is lost. + Buffer_Too_Small = c.int(os.EMSGSIZE), + Not_Socket = c.int(os.ENOTSOCK), // The so-called socket is not an open socket. + Not_Descriptor = c.int(os.EBADF), // The so-called socket is, in fact, not even a valid descriptor. + Bad_Buffer = c.int(os.EFAULT), // The buffer did not point to a valid location in memory. + Interrupted = c.int(os.EINTR), // A signal occurred before any data was transmitted. See signal(7). + + // The send timeout duration passed before all data was received. See Socket_Option.Receive_Timeout. + // NOTE: No, really. Presumably this means something different for nonblocking sockets... + Timeout = c.int(os.EWOULDBLOCK), + Socket_Not_Bound = c.int(os.EINVAL), // The socket must be bound for this operation, but isn't. +} + +// TODO +TCP_Send_Error :: enum c.int { + + // TODO(tetra): merge with other errors? + Aborted = c.int(os.ECONNABORTED), + Connection_Closed = c.int(os.ECONNRESET), + Not_Connected = c.int(os.ENOTCONN), + Shutdown = c.int(os.ESHUTDOWN), + + // The send queue was full. + // This is usually a transient issue. + // + // This also shouldn't normally happen on Linux, as data is dropped if it + // doesn't fit in the send queue. + No_Buffer_Space_Available = c.int(os.ENOBUFS), + Offline = c.int(os.ENETDOWN), + Host_Unreachable = c.int(os.EHOSTUNREACH), // A signal occurred before any data was transmitted. See signal(7). + Interrupted = c.int(os.EINTR), // The send timeout duration passed before all data was sent. See Socket_Option.Send_Timeout. + Timeout = c.int(os.EWOULDBLOCK), // NOTE: No, really. Presumably this means something different for nonblocking sockets... + Not_Socket = c.int(os.ENOTSOCK), // The so-called socket is not an open socket. +} + +// TODO +UDP_Send_Error :: enum c.int { + Message_Too_Long = c.int(os.EMSGSIZE), // The message is too big. No data was sent. + + // TODO: not sure what the exact circumstances for this is yet + Network_Unreachable = c.int(os.ENETUNREACH), + No_Outbound_Ports_Available = c.int(os.EAGAIN), // There are no more emphemeral outbound ports available to bind the socket to, in order to send. + + // The send timeout duration passed before all data was sent. See Socket_Option.Send_Timeout. + // NOTE: No, really. Presumably this means something different for nonblocking sockets... + Timeout = c.int(os.EWOULDBLOCK), + Not_Socket = c.int(os.ENOTSOCK), // The so-called socket is not an open socket. + Not_Descriptor = c.int(os.EBADF), // The so-called socket is, in fact, not even a valid descriptor. + Bad_Buffer = c.int(os.EFAULT), // The buffer did not point to a valid location in memory. + Interrupted = c.int(os.EINTR), // A signal occurred before any data was transmitted. See signal(7). + + // The send queue was full. + // This is usually a transient issue. + // + // This also shouldn't normally happen on Linux, as data is dropped if it + // doesn't fit in the send queue. + No_Buffer_Space_Available = c.int(os.ENOBUFS), + No_Memory_Available = c.int(os.ENOMEM), // No memory was available to properly manage the send queue. +} + +Shutdown_Error :: enum c.int { + Aborted = c.int(os.ECONNABORTED), + Reset = c.int(os.ECONNRESET), + Offline = c.int(os.ENETDOWN), + Not_Connected = c.int(os.ENOTCONN), + Not_Socket = c.int(os.ENOTSOCK), + Invalid_Manner = c.int(os.EINVAL), +} + +Socket_Option_Error :: enum c.int { + Offline = c.int(os.ENETDOWN), + Timeout_When_Keepalive_Set = c.int(os.ENETRESET), + Invalid_Option_For_Socket = c.int(os.ENOPROTOOPT), + Reset_When_Keepalive_Set = c.int(os.ENOTCONN), + Not_Socket = c.int(os.ENOTSOCK), +} |