errors_windows.odin 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. #+build windows
  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 win "core:sys/windows"
  21. Create_Socket_Error :: enum c.int {
  22. None = 0,
  23. Network_Subsystem_Failure = win.WSAENETDOWN,
  24. Family_Not_Supported_For_This_Socket = win.WSAEAFNOSUPPORT,
  25. No_Socket_Descriptors_Available = win.WSAEMFILE,
  26. No_Buffer_Space_Available = win.WSAENOBUFS,
  27. Protocol_Unsupported_By_System = win.WSAEPROTONOSUPPORT,
  28. Wrong_Protocol_For_Socket = win.WSAEPROTOTYPE,
  29. Family_And_Socket_Type_Mismatch = win.WSAESOCKTNOSUPPORT,
  30. }
  31. Dial_Error :: enum c.int {
  32. None = 0,
  33. Port_Required = -1,
  34. Address_In_Use = win.WSAEADDRINUSE,
  35. In_Progress = win.WSAEALREADY,
  36. Cannot_Use_Any_Address = win.WSAEADDRNOTAVAIL,
  37. Wrong_Family_For_Socket = win.WSAEAFNOSUPPORT,
  38. Refused = win.WSAECONNREFUSED,
  39. Is_Listening_Socket = win.WSAEINVAL,
  40. Already_Connected = win.WSAEISCONN,
  41. Network_Unreachable = win.WSAENETUNREACH, // Device is offline
  42. Host_Unreachable = win.WSAEHOSTUNREACH, // Remote host cannot be reached
  43. No_Buffer_Space_Available = win.WSAENOBUFS,
  44. Not_Socket = win.WSAENOTSOCK,
  45. Timeout = win.WSAETIMEDOUT,
  46. Would_Block = win.WSAEWOULDBLOCK, // TODO: we may need special handling for this; maybe make a socket a struct with metadata?
  47. }
  48. Bind_Error :: enum c.int {
  49. None = 0,
  50. Address_In_Use = win.WSAEADDRINUSE, // Another application is currently bound to this endpoint.
  51. Given_Nonlocal_Address = win.WSAEADDRNOTAVAIL, // The address is not a local address on this machine.
  52. Broadcast_Disabled = win.WSAEACCES, // To bind a UDP socket to the broadcast address, the appropriate socket option must be set.
  53. Address_Family_Mismatch = win.WSAEFAULT, // The address family of the address does not match that of the socket.
  54. Already_Bound = win.WSAEINVAL, // The socket is already bound to an address.
  55. No_Ports_Available = win.WSAENOBUFS, // There are not enough ephemeral ports available.
  56. }
  57. Listen_Error :: enum c.int {
  58. None = 0,
  59. Address_In_Use = win.WSAEADDRINUSE,
  60. Already_Connected = win.WSAEISCONN,
  61. No_Socket_Descriptors_Available = win.WSAEMFILE,
  62. No_Buffer_Space_Available = win.WSAENOBUFS,
  63. Nonlocal_Address = win.WSAEADDRNOTAVAIL,
  64. Not_Socket = win.WSAENOTSOCK,
  65. Listening_Not_Supported_For_This_Socket = win.WSAEOPNOTSUPP,
  66. }
  67. Accept_Error :: enum c.int {
  68. None = 0,
  69. Not_Listening = win.WSAEINVAL,
  70. No_Socket_Descriptors_Available_For_Client_Socket = win.WSAEMFILE,
  71. No_Buffer_Space_Available = win.WSAENOBUFS,
  72. Not_Socket = win.WSAENOTSOCK,
  73. Not_Connection_Oriented_Socket = win.WSAEOPNOTSUPP,
  74. // TODO: we may need special handling for this; maybe make a socket a struct with metadata?
  75. Would_Block = win.WSAEWOULDBLOCK,
  76. }
  77. TCP_Recv_Error :: enum c.int {
  78. None = 0,
  79. Network_Subsystem_Failure = win.WSAENETDOWN,
  80. Not_Connected = win.WSAENOTCONN,
  81. Bad_Buffer = win.WSAEFAULT,
  82. Keepalive_Failure = win.WSAENETRESET,
  83. Not_Socket = win.WSAENOTSOCK,
  84. Shutdown = win.WSAESHUTDOWN,
  85. Would_Block = win.WSAEWOULDBLOCK,
  86. Aborted = win.WSAECONNABORTED,
  87. Timeout = win.WSAETIMEDOUT,
  88. // TODO(tetra): Determine when this is different from the syscall returning n=0 and maybe normalize them?
  89. Connection_Closed = win.WSAECONNRESET,
  90. // TODO: verify can actually happen
  91. Host_Unreachable = win.WSAEHOSTUNREACH,
  92. }
  93. UDP_Recv_Error :: enum c.int {
  94. None = 0,
  95. Network_Subsystem_Failure = win.WSAENETDOWN,
  96. Aborted = win.WSAECONNABORTED,
  97. Buffer_Too_Small = win.WSAEMSGSIZE, // The buffer is too small to fit the entire message, and the message was truncated. When this happens, the rest of message is lost.
  98. Remote_Not_Listening = win.WSAECONNRESET, // The machine at the remote endpoint doesn't have the given port open to receiving UDP data.
  99. Shutdown = win.WSAESHUTDOWN,
  100. Broadcast_Disabled = win.WSAEACCES, // A broadcast address was specified, but the .Broadcast socket option isn't set.
  101. Bad_Buffer = win.WSAEFAULT,
  102. No_Buffer_Space_Available = win.WSAENOBUFS,
  103. Not_Socket = win.WSAENOTSOCK, // The socket is not valid socket handle.
  104. Would_Block = win.WSAEWOULDBLOCK,
  105. Host_Unreachable = win.WSAEHOSTUNREACH, // The remote host cannot be reached from this host at this time.
  106. Offline = win.WSAENETUNREACH, // The network cannot be reached from this host at this time.
  107. Timeout = win.WSAETIMEDOUT,
  108. // TODO: can this actually happen? The socket isn't bound; an unknown flag specified; or MSG_OOB specified with SO_OOBINLINE enabled.
  109. Incorrectly_Configured = win.WSAEINVAL,
  110. TTL_Expired = win.WSAENETRESET, // The message took more hops than was allowed (the Time To Live) to reach the remote endpoint.
  111. }
  112. // TODO: consider merging some errors to make handling them easier
  113. // TODO: verify once more what errors to actually expose
  114. TCP_Send_Error :: enum c.int {
  115. None = 0,
  116. Aborted = win.WSAECONNABORTED,
  117. Not_Connected = win.WSAENOTCONN,
  118. Shutdown = win.WSAESHUTDOWN,
  119. Connection_Closed = win.WSAECONNRESET,
  120. No_Buffer_Space_Available = win.WSAENOBUFS,
  121. Network_Subsystem_Failure = win.WSAENETDOWN,
  122. Host_Unreachable = win.WSAEHOSTUNREACH,
  123. Would_Block = win.WSAEWOULDBLOCK,
  124. // TODO: verify possible, as not mentioned in docs
  125. Offline = win.WSAENETUNREACH,
  126. Timeout = win.WSAETIMEDOUT,
  127. // A broadcast address was specified, but the .Broadcast socket option isn't set.
  128. Broadcast_Disabled = win.WSAEACCES,
  129. Bad_Buffer = win.WSAEFAULT,
  130. // Connection is broken due to keepalive activity detecting a failure during the operation.
  131. Keepalive_Failure = win.WSAENETRESET, // TODO: not functionally different from Reset; merge?
  132. Not_Socket = win.WSAENOTSOCK, // The so-called socket is not an open socket.
  133. }
  134. UDP_Send_Error :: enum c.int {
  135. None = 0,
  136. Network_Subsystem_Failure = win.WSAENETDOWN,
  137. Aborted = win.WSAECONNABORTED,
  138. Message_Too_Long = win.WSAEMSGSIZE, // The message is larger than the maximum UDP packet size.
  139. Remote_Not_Listening = win.WSAECONNRESET, // The machine at the remote endpoint doesn't have the given port open to receiving UDP data.
  140. Shutdown = win.WSAESHUTDOWN, // A broadcast address was specified, but the .Broadcast socket option isn't set.
  141. Broadcast_Disabled = win.WSAEACCES,
  142. Bad_Buffer = win.WSAEFAULT, // Connection is broken due to keepalive activity detecting a failure during the operation.
  143. // TODO: not functionally different from Reset; merge?
  144. Keepalive_Failure = win.WSAENETRESET,
  145. No_Buffer_Space_Available = win.WSAENOBUFS,
  146. Not_Socket = win.WSAENOTSOCK, // The socket is not valid socket handle.
  147. // This socket is unidirectional and cannot be used to send any data.
  148. // TODO: verify possible; decide whether to keep if not
  149. Receive_Only = win.WSAEOPNOTSUPP,
  150. Would_Block = win.WSAEWOULDBLOCK,
  151. Host_Unreachable = win.WSAEHOSTUNREACH, // The remote host cannot be reached from this host at this time.
  152. Cannot_Use_Any_Address = win.WSAEADDRNOTAVAIL, // Attempt to send to the Any address.
  153. Family_Not_Supported_For_This_Socket = win.WSAEAFNOSUPPORT, // The address is of an incorrect address family for this socket.
  154. Offline = win.WSAENETUNREACH, // The network cannot be reached from this host at this time.
  155. Timeout = win.WSAETIMEDOUT,
  156. }
  157. Shutdown_Manner :: enum c.int {
  158. Receive = win.SD_RECEIVE,
  159. Send = win.SD_SEND,
  160. Both = win.SD_BOTH,
  161. }
  162. Shutdown_Error :: enum c.int {
  163. None = 0,
  164. Aborted = win.WSAECONNABORTED,
  165. Reset = win.WSAECONNRESET,
  166. Offline = win.WSAENETDOWN,
  167. Not_Connected = win.WSAENOTCONN,
  168. Not_Socket = win.WSAENOTSOCK,
  169. Invalid_Manner = win.WSAEINVAL,
  170. }
  171. Socket_Option :: enum c.int {
  172. // bool: Whether the address that this socket is bound to can be reused by other sockets.
  173. // This allows you to bypass the cooldown period if a program dies while the socket is bound.
  174. Reuse_Address = win.SO_REUSEADDR,
  175. // bool: Whether other programs will be inhibited from binding the same endpoint as this socket.
  176. Exclusive_Addr_Use = win.SO_EXCLUSIVEADDRUSE,
  177. // bool: When true, keepalive packets will be automatically be sent for this connection. TODO: verify this understanding
  178. Keep_Alive = win.SO_KEEPALIVE,
  179. // bool: When true, client connections will immediately be sent a TCP/IP RST response, rather than being accepted.
  180. Conditional_Accept = win.SO_CONDITIONAL_ACCEPT,
  181. // bool: If true, when the socket is closed, but data is still waiting to be sent, discard that data.
  182. Dont_Linger = win.SO_DONTLINGER,
  183. // bool: When true, 'out-of-band' data sent over the socket will be read by a normal net.recv() call, the same as normal 'in-band' data.
  184. Out_Of_Bounds_Data_Inline = win.SO_OOBINLINE,
  185. // bool: When true, disables send-coalescing, therefore reducing latency.
  186. TCP_Nodelay = win.TCP_NODELAY,
  187. // win.LINGER: Customizes how long (if at all) the socket will remain open when there
  188. // is some remaining data waiting to be sent, and net.close() is called.
  189. Linger = win.SO_LINGER,
  190. // win.DWORD: The size, in bytes, of the OS-managed receive-buffer for this socket.
  191. Receive_Buffer_Size = win.SO_RCVBUF,
  192. // win.DWORD: The size, in bytes, of the OS-managed send-buffer for this socket.
  193. Send_Buffer_Size = win.SO_SNDBUF,
  194. // win.DWORD: For blocking sockets, the time in milliseconds to wait for incoming data to be received, before giving up and returning .Timeout.
  195. // For non-blocking sockets, ignored.
  196. // Use a value of zero to potentially wait forever.
  197. Receive_Timeout = win.SO_RCVTIMEO,
  198. // win.DWORD: For blocking sockets, the time in milliseconds to wait for outgoing data to be sent, before giving up and returning .Timeout.
  199. // For non-blocking sockets, ignored.
  200. // Use a value of zero to potentially wait forever.
  201. Send_Timeout = win.SO_SNDTIMEO,
  202. // bool: Allow sending to, receiving from, and binding to, a broadcast address.
  203. Broadcast = win.SO_BROADCAST,
  204. }
  205. Socket_Option_Error :: enum c.int {
  206. None = 0,
  207. Linger_Only_Supports_Whole_Seconds = 1,
  208. // The given value is too big or small to be given to the OS.
  209. Value_Out_Of_Range,
  210. Network_Subsystem_Failure = win.WSAENETDOWN,
  211. Timeout_When_Keepalive_Set = win.WSAENETRESET,
  212. Invalid_Option_For_Socket = win.WSAENOPROTOOPT,
  213. Reset_When_Keepalive_Set = win.WSAENOTCONN,
  214. Not_Socket = win.WSAENOTSOCK,
  215. }
  216. Set_Blocking_Error :: enum c.int {
  217. None = 0,
  218. Network_Subsystem_Failure = win.WSAENETDOWN,
  219. Blocking_Call_In_Progress = win.WSAEINPROGRESS,
  220. Not_Socket = win.WSAENOTSOCK,
  221. // TODO: are those errors possible?
  222. Network_Subsystem_Not_Initialized = win.WSAENOTINITIALISED,
  223. Invalid_Argument_Pointer = win.WSAEFAULT,
  224. }