errors_windows.odin 12 KB

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