123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272 |
- #+build windows
- package net
- /*
- Package net implements cross-platform Berkeley Sockets, DNS resolution and associated procedures.
- For other protocols and their features, see subdirectories of this package.
- */
- /*
- Copyright 2022 Tetralux <[email protected]>
- Copyright 2022 Colin Davidson <[email protected]>
- Copyright 2022 Jeroen van Rijn <[email protected]>.
- Copyright 2024 Feoramund <[email protected]>.
- 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
- Feoramund: FreeBSD platform code
- */
- import "core:reflect"
- import win "core:sys/windows"
- _last_platform_error :: proc() -> i32 {
- return i32(win.WSAGetLastError())
- }
- _last_platform_error_string :: proc() -> string {
- description, _ := reflect.enum_name_from_value(win.System_Error(win.WSAGetLastError()))
- return description
- }
- _set_last_platform_error :: proc(err: i32) {
- win.WSASetLastError(err)
- }
- _create_socket_error :: proc() -> Create_Socket_Error {
- #partial switch win.System_Error(win.WSAGetLastError()) {
- case .WSANOTINITIALISED, .WSAENETDOWN, .WSAEINVALIDPROVIDER, .WSAEINVALIDPROCTABLE, .WSAEPROVIDERFAILEDINIT:
- return .Network_Unreachable
- case .WSAEAFNOSUPPORT, .WSAEINPROGRESS, .WSAEINVAL, .WSAEPROTOTYPE, .WSAESOCKTNOSUPPORT:
- return .Invalid_Argument
- case .WSAEMFILE, .WSAENOBUFS, .WSAEPROTONOSUPPORT:
- return .Insufficient_Resources
- case:
- return .Unknown
- }
- }
- _dial_error :: proc() -> Dial_Error {
- #partial switch win.System_Error(win.WSAGetLastError()) {
- case .WSANOTINITIALISED, .WSAENETDOWN:
- return .Network_Unreachable
- case .WSAEADDRINUSE:
- return .Address_In_Use
- case .WSAEINTR:
- return .Interrupted
- case .WSAEWOULDBLOCK:
- return .Would_Block
- case .WSAEALREADY:
- return .Already_Connecting
- case .WSAEADDRNOTAVAIL, .WSAEAFNOSUPPORT, .WSAEFAULT, .WSAENOTSOCK, .WSAEINPROGRESS, .WSAEINVAL:
- return .Invalid_Argument
- case .WSAECONNREFUSED:
- return .Refused
- case .WSAEISCONN:
- return .Already_Connected
- case .WSAEHOSTUNREACH:
- return .Host_Unreachable
- case .WSAENOBUFS:
- return .Insufficient_Resources
- case .WSAETIMEDOUT:
- return .Timeout
- case .WSAEACCES:
- return .Broadcast_Not_Supported
- case:
- return .Unknown
- }
- }
- _bind_error :: proc() -> Bind_Error {
- #partial switch win.System_Error(win.WSAGetLastError()) {
- case .WSANOTINITIALISED, .WSAENETDOWN:
- return .Network_Unreachable
- case .WSAEADDRINUSE:
- return .Address_In_Use
- case .WSAEADDRNOTAVAIL, .WSAEFAULT, .WSAEINPROGRESS, .WSAEACCES, .WSAEINVAL, .WSAENOTSOCK:
- return .Invalid_Argument
- case:
- return .Unknown
- }
- }
- _listen_error :: proc() -> Listen_Error {
- #partial switch win.System_Error(win.WSAGetLastError()) {
- case .WSANOTINITIALISED, .WSAENETDOWN:
- return .Network_Unreachable
- case .WSAEMFILE, .WSAENOBUFS:
- return .Insufficient_Resources
- case .WSAEADDRINUSE:
- return .Address_In_Use
- case .WSAEINPROGRESS, .WSAENOTSOCK:
- return .Invalid_Argument
- case .WSAEISCONN:
- return .Already_Connected
- case .WSAEOPNOTSUPP, .WSAEINVAL:
- return .Unsupported_Socket
- case:
- return .Unknown
- }
- }
- _accept_error :: proc() -> Accept_Error {
- #partial switch win.System_Error(win.WSAGetLastError()) {
- case .WSANOTINITIALISED, .WSAENETDOWN:
- return .Network_Unreachable
- case .WSAEMFILE, .WSAENOBUFS:
- return .Insufficient_Resources
- case .WSAECONNRESET:
- return .Aborted
- case .WSAEFAULT, .WSAEINPROGRESS, .WSAENOTSOCK:
- return .Invalid_Argument
- case .WSAEINTR:
- return .Interrupted
- case .WSAEINVAL:
- return .Not_Listening
- case .WSAEWOULDBLOCK:
- return .Would_Block
- case .WSAEOPNOTSUPP:
- return .Unsupported_Socket
- case:
- return .Unknown
- }
- }
- _tcp_recv_error :: proc() -> TCP_Recv_Error {
- #partial switch win.System_Error(win.WSAGetLastError()) {
- case .WSANOTINITIALISED, .WSAENETDOWN:
- return .Network_Unreachable
- case .WSAEFAULT, .WSAEINPROGRESS, .WSAENOTSOCK, .WSAEMSGSIZE, .WSAEINVAL, .WSAEOPNOTSUPP:
- return .Invalid_Argument
- case .WSAENOTCONN:
- return .Not_Connected
- case .WSAEINTR:
- return .Interrupted
- case .WSAENETRESET, .WSAESHUTDOWN, .WSAECONNABORTED, .WSAECONNRESET:
- return .Connection_Closed
- case .WSAEWOULDBLOCK:
- return .Would_Block
- case .WSAETIMEDOUT:
- return .Timeout
- case:
- return .Unknown
- }
- }
- _udp_recv_error :: proc() -> UDP_Recv_Error {
- #partial switch win.System_Error(win.WSAGetLastError()) {
- case .WSANOTINITIALISED, .WSAENETDOWN:
- return .Network_Unreachable
- case .WSAEFAULT, .WSAEINPROGRESS, .WSAEINVAL, .WSAEISCONN, .WSAENOTSOCK, .WSAEOPNOTSUPP, .WSAEMSGSIZE:
- return .Invalid_Argument
- case .WSAEINTR:
- return .Interrupted
- case .WSAENETRESET, .WSAESHUTDOWN, .WSAECONNRESET:
- return .Connection_Refused
- case .WSAEWOULDBLOCK:
- return .Would_Block
- case .WSAETIMEDOUT:
- return .Timeout
- case:
- return .Unknown
- }
- }
- _tcp_send_error :: proc() -> TCP_Send_Error {
- #partial switch win.System_Error(win.WSAGetLastError()) {
- case .WSANOTINITIALISED, .WSAENETDOWN:
- return .Network_Unreachable
- case .WSAENOBUFS:
- return .Insufficient_Resources
- case .WSAEACCES, .WSAEINPROGRESS, .WSAEFAULT, .WSAENOTSOCK, .WSAEOPNOTSUPP, .WSAEMSGSIZE, .WSAEINVAL:
- return .Invalid_Argument
- case .WSAEINTR:
- return .Interrupted
- case .WSAENETRESET, .WSAESHUTDOWN, .WSAECONNABORTED, .WSAECONNRESET:
- return .Connection_Closed
- case .WSAENOTCONN:
- return .Not_Connected
- case .WSAEWOULDBLOCK:
- return .Would_Block
- case .WSAETIMEDOUT:
- return .Timeout
- case .WSAEHOSTUNREACH:
- return .Host_Unreachable
- case:
- return .Unknown
- }
- }
- _udp_send_error :: proc() -> UDP_Send_Error {
- #partial switch win.System_Error(win.WSAGetLastError()) {
- case .WSANOTINITIALISED, .WSAENETDOWN, .WSAENETUNREACH:
- return .Network_Unreachable
- case .WSAENOBUFS:
- return .Insufficient_Resources
- case .WSAEACCES, .WSAEINVAL, .WSAEINPROGRESS, .WSAEFAULT, .WSAENOTCONN, .WSAENOTSOCK, .WSAEOPNOTSUPP, .WSAEADDRNOTAVAIL, .WSAEAFNOSUPPORT, .WSAEDESTADDRREQ:
- return .Invalid_Argument
- case .WSAEINTR:
- return .Interrupted
- case .WSAENETRESET, .WSAESHUTDOWN, .WSAECONNRESET:
- return .Connection_Refused
- case .WSAEWOULDBLOCK:
- return .Would_Block
- case .WSAETIMEDOUT:
- return .Timeout
- case:
- return .Unknown
- }
- }
- _shutdown_error :: proc() -> Shutdown_Error {
- #partial switch win.System_Error(win.WSAGetLastError()) {
- case .WSAENETDOWN, .WSANOTINITIALISED:
- return .Network_Unreachable
- case .WSAECONNABORTED, .WSAECONNRESET:
- return .Connection_Closed
- case .WSAEINPROGRESS, .WSAEINVAL, .WSAENOTCONN, .WSAENOTSOCK:
- return .Invalid_Argument
- case:
- return .Unknown
- }
- }
- _socket_info_error :: proc() -> Socket_Info_Error {
- #partial switch win.System_Error(win.WSAGetLastError()) {
- case .WSAEFAULT, .WSAEINPROGRESS, .WSAENOTSOCK, .WSAEINVAL:
- return .Invalid_Argument
- case .WSANOTINITIALISED, .WSAENETDOWN, .WSAENOTCONN:
- return .Network_Unreachable
- case:
- return .Unknown
- }
- }
- _socket_option_error :: proc() -> Socket_Option_Error {
- #partial switch win.System_Error(win.WSAGetLastError()) {
- case .WSAENETDOWN, .WSANOTINITIALISED:
- return .Network_Unreachable
- case .WSAEFAULT, .WSAEINVAL:
- return .Invalid_Value
- case .WSAENETRESET, .WSAENOTCONN, .WSAENOTSOCK:
- return .Invalid_Socket
- case .WSAENOPROTOOPT:
- return .Invalid_Option
- case:
- return .Unknown
- }
- }
- _set_blocking_error :: proc() -> Set_Blocking_Error {
- #partial switch win.System_Error(win.WSAGetLastError()) {
- case .WSAENETDOWN, .WSANOTINITIALISED:
- return .Network_Unreachable
- case .WSAEINPROGRESS, .WSAENOTSOCK, .WSAEFAULT:
- return .Invalid_Argument
- case:
- return .Unknown
- }
- }
|