aboutsummaryrefslogtreecommitdiff
path: root/core/net/errors_linux.odin
diff options
context:
space:
mode:
authorColin Davidson <colrdavidson@gmail.com>2023-03-02 06:43:20 -0800
committerColin Davidson <colrdavidson@gmail.com>2023-03-02 06:43:20 -0800
commit64f200dc7419a3b1b8b4ae387d5add57b680ca3e (patch)
tree1c05f885cb127bef5974831a74aad4b44773ab9c /core/net/errors_linux.odin
parentc02ff3af27afc013336de24570bbbaf1d66643d0 (diff)
big error cleanup
Diffstat (limited to 'core/net/errors_linux.odin')
-rw-r--r--core/net/errors_linux.odin175
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),
+}