2
0

errors_darwin.odin 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. #+build darwin
  2. package net
  3. /*
  4. Package net implements cross-platform Berkeley Sockets, DNS resolution and associated procedures.
  5. For other protocols and their features, see subdirectories of this package.
  6. */
  7. /*
  8. Copyright 2022 Tetralux <[email protected]>
  9. Copyright 2022 Colin Davidson <[email protected]>
  10. Copyright 2022 Jeroen van Rijn <[email protected]>.
  11. Copyright 2024 Feoramund <[email protected]>.
  12. Made available under Odin's BSD-3 license.
  13. List of contributors:
  14. Tetralux: Initial implementation
  15. Colin Davidson: Linux platform code, OSX platform code, Odin-native DNS resolver
  16. Jeroen van Rijn: Cross platform unification, code style, documentation
  17. Feoramund: FreeBSD platform code
  18. */
  19. import "core:c"
  20. import "core:sys/posix"
  21. @(private)
  22. ESHUTDOWN :: 58
  23. Create_Socket_Error :: enum c.int {
  24. None = 0,
  25. Family_Not_Supported_For_This_Socket = c.int(posix.EAFNOSUPPORT),
  26. No_Socket_Descriptors_Available = c.int(posix.EMFILE),
  27. No_Buffer_Space_Available = c.int(posix.ENOBUFS),
  28. No_Memory_Available = c.int(posix.ENOMEM),
  29. Protocol_Unsupported_By_System = c.int(posix.EPROTONOSUPPORT),
  30. Wrong_Protocol_For_Socket = c.int(posix.EPROTONOSUPPORT),
  31. Family_And_Socket_Type_Mismatch = c.int(posix.EPROTONOSUPPORT),
  32. }
  33. Dial_Error :: enum c.int {
  34. None = 0,
  35. Port_Required = -1, // Attempted to dial an endpointing without a port being set.
  36. Address_In_Use = c.int(posix.EADDRINUSE),
  37. In_Progress = c.int(posix.EINPROGRESS),
  38. Cannot_Use_Any_Address = c.int(posix.EADDRNOTAVAIL),
  39. Wrong_Family_For_Socket = c.int(posix.EAFNOSUPPORT),
  40. Refused = c.int(posix.ECONNREFUSED),
  41. Is_Listening_Socket = c.int(posix.EACCES),
  42. Already_Connected = c.int(posix.EISCONN),
  43. Network_Unreachable = c.int(posix.ENETUNREACH), // Device is offline
  44. Host_Unreachable = c.int(posix.EHOSTUNREACH), // Remote host cannot be reached
  45. No_Buffer_Space_Available = c.int(posix.ENOBUFS),
  46. Not_Socket = c.int(posix.ENOTSOCK),
  47. Timeout = c.int(posix.ETIMEDOUT),
  48. // TODO: we may need special handling for this; maybe make a socket a struct with metadata?
  49. Would_Block = c.int(posix.EWOULDBLOCK),
  50. }
  51. Bind_Error :: enum c.int {
  52. None = 0,
  53. Privileged_Port_Without_Root = -1, // Attempted to bind to a port less than 1024 without root access.
  54. Address_In_Use = c.int(posix.EADDRINUSE), // Another application is currently bound to this endpoint.
  55. Given_Nonlocal_Address = c.int(posix.EADDRNOTAVAIL), // The address is not a local address on this machine.
  56. Broadcast_Disabled = c.int(posix.EACCES), // To bind a UDP socket to the broadcast address, the appropriate socket option must be set.
  57. Address_Family_Mismatch = c.int(posix.EFAULT), // The address family of the address does not match that of the socket.
  58. Already_Bound = c.int(posix.EINVAL), // The socket is already bound to an address.
  59. No_Ports_Available = c.int(posix.ENOBUFS), // There are not enough ephemeral ports available.
  60. }
  61. Listen_Error :: enum c.int {
  62. None = 0,
  63. Address_In_Use = c.int(posix.EADDRINUSE),
  64. Already_Connected = c.int(posix.EISCONN),
  65. No_Socket_Descriptors_Available = c.int(posix.EMFILE),
  66. No_Buffer_Space_Available = c.int(posix.ENOBUFS),
  67. Nonlocal_Address = c.int(posix.EADDRNOTAVAIL),
  68. Not_Socket = c.int(posix.ENOTSOCK),
  69. Listening_Not_Supported_For_This_Socket = c.int(posix.EOPNOTSUPP),
  70. }
  71. Accept_Error :: enum c.int {
  72. None = 0,
  73. // TODO(tetra): Is this error actually possible here? Or is like Linux, in which case we can remove it.
  74. Reset = c.int(posix.ECONNRESET),
  75. Not_Listening = c.int(posix.EINVAL),
  76. No_Socket_Descriptors_Available_For_Client_Socket = c.int(posix.EMFILE),
  77. No_Buffer_Space_Available = c.int(posix.ENOBUFS),
  78. Not_Socket = c.int(posix.ENOTSOCK),
  79. Not_Connection_Oriented_Socket = c.int(posix.EOPNOTSUPP),
  80. // TODO: we may need special handling for this; maybe make a socket a struct with metadata?
  81. Would_Block = c.int(posix.EWOULDBLOCK),
  82. }
  83. TCP_Recv_Error :: enum c.int {
  84. None = 0,
  85. Shutdown = ESHUTDOWN,
  86. Not_Connected = c.int(posix.ENOTCONN),
  87. // TODO(tetra): Is this error actually possible here?
  88. Connection_Broken = c.int(posix.ENETRESET),
  89. Not_Socket = c.int(posix.ENOTSOCK),
  90. Aborted = c.int(posix.ECONNABORTED),
  91. // TODO(tetra): Determine when this is different from the syscall returning n=0 and maybe normalize them?
  92. Connection_Closed = c.int(posix.ECONNRESET),
  93. Offline = c.int(posix.ENETDOWN),
  94. Host_Unreachable = c.int(posix.EHOSTUNREACH),
  95. Interrupted = c.int(posix.EINTR),
  96. // NOTE: No, really. Presumably this means something different for nonblocking sockets...
  97. Timeout = c.int(posix.EWOULDBLOCK),
  98. }
  99. UDP_Recv_Error :: enum c.int {
  100. None = 0,
  101. Buffer_Too_Small = c.int(posix.EMSGSIZE), // The buffer is too small to fit the entire message, and the message was truncated. When this happens, the rest of message is lost.
  102. Not_Socket = c.int(posix.ENOTSOCK), // The so-called socket is not an open socket.
  103. Not_Descriptor = c.int(posix.EBADF), // The so-called socket is, in fact, not even a valid descriptor.
  104. Bad_Buffer = c.int(posix.EFAULT), // The buffer did not point to a valid location in memory.
  105. Interrupted = c.int(posix.EINTR), // A signal occurred before any data was transmitted. See signal(7).
  106. // The send timeout duration passed before all data was sent. See Socket_Option.Send_Timeout.
  107. // NOTE: No, really. Presumably this means something different for nonblocking sockets...
  108. Timeout = c.int(posix.EWOULDBLOCK),
  109. Socket_Not_Bound = c.int(posix.EINVAL), // The socket must be bound for this operation, but isn't.
  110. }
  111. TCP_Send_Error :: enum c.int {
  112. None = 0,
  113. Aborted = c.int(posix.ECONNABORTED),
  114. Connection_Closed = c.int(posix.ECONNRESET),
  115. Not_Connected = c.int(posix.ENOTCONN),
  116. Shutdown = ESHUTDOWN,
  117. // The send queue was full.
  118. // This is usually a transient issue.
  119. //
  120. // This also shouldn't normally happen on Linux, as data is dropped if it
  121. // doesn't fit in the send queue.
  122. No_Buffer_Space_Available = c.int(posix.ENOBUFS),
  123. Offline = c.int(posix.ENETDOWN),
  124. Host_Unreachable = c.int(posix.EHOSTUNREACH),
  125. Interrupted = c.int(posix.EINTR), // A signal occurred before any data was transmitted. See signal(7).
  126. // NOTE: No, really. Presumably this means something different for nonblocking sockets...
  127. // The send timeout duration passed before all data was sent. See Socket_Option.Send_Timeout.
  128. Timeout = c.int(posix.EWOULDBLOCK),
  129. Not_Socket = c.int(posix.ENOTSOCK), // The so-called socket is not an open socket.
  130. }
  131. // TODO
  132. UDP_Send_Error :: enum c.int {
  133. None = 0,
  134. Message_Too_Long = c.int(posix.EMSGSIZE), // The message is larger than the maximum UDP packet size. No data was sent.
  135. // TODO: not sure what the exact circumstances for this is yet
  136. Network_Unreachable = c.int(posix.ENETUNREACH),
  137. No_Outbound_Ports_Available = c.int(posix.EAGAIN), // There are no more emphemeral outbound ports available to bind the socket to, in order to send.
  138. // The send timeout duration passed before all data was sent. See Socket_Option.Send_Timeout.
  139. // NOTE: No, really. Presumably this means something different for nonblocking sockets...
  140. Timeout = c.int(posix.EWOULDBLOCK),
  141. Not_Socket = c.int(posix.ENOTSOCK), // The so-called socket is not an open socket.
  142. Not_Descriptor = c.int(posix.EBADF), // The so-called socket is, in fact, not even a valid descriptor.
  143. Bad_Buffer = c.int(posix.EFAULT), // The buffer did not point to a valid location in memory.
  144. Interrupted = c.int(posix.EINTR), // A signal occurred before any data was transmitted. See signal(7).
  145. // The send queue was full.
  146. // This is usually a transient issue.
  147. //
  148. // This also shouldn't normally happen on Linux, as data is dropped if it
  149. // doesn't fit in the send queue.
  150. No_Buffer_Space_Available = c.int(posix.ENOBUFS),
  151. No_Memory_Available = c.int(posix.ENOMEM), // No memory was available to properly manage the send queue.
  152. }
  153. Shutdown_Manner :: enum c.int {
  154. Receive = c.int(posix.SHUT_RD),
  155. Send = c.int(posix.SHUT_WR),
  156. Both = c.int(posix.SHUT_RDWR),
  157. }
  158. Shutdown_Error :: enum c.int {
  159. None = 0,
  160. Aborted = c.int(posix.ECONNABORTED),
  161. Reset = c.int(posix.ECONNRESET),
  162. Offline = c.int(posix.ENETDOWN),
  163. Not_Connected = c.int(posix.ENOTCONN),
  164. Not_Socket = c.int(posix.ENOTSOCK),
  165. Invalid_Manner = c.int(posix.EINVAL),
  166. }
  167. Socket_Option_Error :: enum c.int {
  168. None = 0,
  169. Offline = c.int(posix.ENETDOWN),
  170. Timeout_When_Keepalive_Set = c.int(posix.ENETRESET),
  171. Invalid_Option_For_Socket = c.int(posix.ENOPROTOOPT),
  172. Reset_When_Keepalive_Set = c.int(posix.ENOTCONN),
  173. Not_Socket = c.int(posix.ENOTSOCK),
  174. }
  175. Set_Blocking_Error :: enum c.int {
  176. None = 0,
  177. // TODO: Add errors for `set_blocking`
  178. }