diff options
| author | Jeroen van Rijn <Kelimion@users.noreply.github.com> | 2025-06-16 11:30:34 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-06-16 11:30:34 +0200 |
| commit | 9c9380d158b799e732547200db3a32f43363ca72 (patch) | |
| tree | ff46a81015d33b38d85556c92fcfe6da7c9b46de /core/net | |
| parent | 795ceec2cdbd47fe7ae0181e1fc5d17062eea062 (diff) | |
| parent | acdab793d920388541afec713bce0a7ec1120575 (diff) | |
Merge pull request #5315 from peperronii/master
Expose getpeername() in core:net package as "peer_endpoint"
Diffstat (limited to 'core/net')
| -rw-r--r-- | core/net/common.odin | 1 | ||||
| -rw-r--r-- | core/net/errors.odin | 17 | ||||
| -rw-r--r-- | core/net/errors_darwin.odin | 17 | ||||
| -rw-r--r-- | core/net/errors_freebsd.odin | 18 | ||||
| -rw-r--r-- | core/net/errors_linux.odin | 16 | ||||
| -rw-r--r-- | core/net/errors_windows.odin | 11 | ||||
| -rw-r--r-- | core/net/socket.odin | 9 | ||||
| -rw-r--r-- | core/net/socket_darwin.odin | 17 | ||||
| -rw-r--r-- | core/net/socket_freebsd.odin | 18 | ||||
| -rw-r--r-- | core/net/socket_linux.odin | 17 | ||||
| -rw-r--r-- | core/net/socket_windows.odin | 18 |
11 files changed, 150 insertions, 9 deletions
diff --git a/core/net/common.odin b/core/net/common.odin index fb6b17511..6d64a65d7 100644 --- a/core/net/common.odin +++ b/core/net/common.odin @@ -64,6 +64,7 @@ Network_Error :: union #shared_nil { UDP_Recv_Error, Shutdown_Error, Interfaces_Error, + Socket_Info_Error, Socket_Option_Error, Set_Blocking_Error, Parse_Endpoint_Error, diff --git a/core/net/errors.odin b/core/net/errors.odin index 53c936a66..4853327b0 100644 --- a/core/net/errors.odin +++ b/core/net/errors.odin @@ -246,6 +246,23 @@ Shutdown_Error :: enum i32 { Unknown, } +Socket_Info_Error :: enum i32 { + None, + // No network connection, or the network stack is not initialized. + Network_Unreachable, + // Not enough space in internal tables/buffers to create a new socket, or an unsupported protocol is given. + Insufficient_Resources, + // Socket is invalid or not connected, or the manner given is invalid. + Invalid_Argument, + // The socket is valid, but unsupported by this opperation. + Unsupported_Socket, + // Connection was closed/aborted/shutdown. + Connection_Closed, + + // An error unable to be categorized in above categories, `last_platform_error` may have more info. + Unknown, +} + Socket_Option_Error :: enum i32 { None, // No network connection, or the network stack is not initialized. diff --git a/core/net/errors_darwin.odin b/core/net/errors_darwin.odin index 7aaa220e9..255bd351f 100644 --- a/core/net/errors_darwin.odin +++ b/core/net/errors_darwin.odin @@ -226,6 +226,23 @@ _shutdown_error :: proc() -> Shutdown_Error { } } +_socket_info_error :: proc() -> Socket_Info_Error { + #partial switch posix.errno() { + case .EBADF, .ENOTSOCK: + return .Invalid_Argument + case .ENOTCONN: + return .Network_Unreachable + case .EOPNOTSUPP: + return .Unsupported_Socket + case .EINVAL: + return .Connection_Closed + case .ENOBUFS: + return .Insufficient_Resources + case: + return .Unknown + } +} + _socket_option_error :: proc() -> Socket_Option_Error { #partial switch posix.errno() { case .ENOBUFS: diff --git a/core/net/errors_freebsd.odin b/core/net/errors_freebsd.odin index 707ffd0dd..05de41746 100644 --- a/core/net/errors_freebsd.odin +++ b/core/net/errors_freebsd.odin @@ -255,6 +255,24 @@ _shutdown_error :: proc(errno: freebsd.Errno) -> Shutdown_Error { } } +_socket_info_error :: proc(errno: freebsd.Errno) -> Socket_Info_Error { + assert(errno != nil) + _last_error = errno + + #partial switch errno { + case .EBADF, .ENOTSOCK, .EINVAL, .EFAULT: + return .Invalid_Argument + case .ENOTCONN: + return .Network_Unreachable + case .ECONNRESET: + return .Connection_Closed + case .ENOBUFS: + return .Insufficient_Resources + case: + return .Unknown + } +} + _socket_option_error :: proc(errno: freebsd.Errno) -> Socket_Option_Error { assert(errno != nil) _last_error = errno diff --git a/core/net/errors_linux.odin b/core/net/errors_linux.odin index 237579f28..258560595 100644 --- a/core/net/errors_linux.odin +++ b/core/net/errors_linux.odin @@ -258,6 +258,22 @@ _shutdown_error :: proc(errno: linux.Errno) -> Shutdown_Error { } } +_socket_info_error :: proc(errno: linux.Errno) -> Socket_Info_Error { + assert(errno != nil) + _last_error = errno + + #partial switch errno { + case .EBADF, .ENOTSOCK, .EFAULT, .EINVAL: + return .Invalid_Argument + case .ENOTCONN: + return .Network_Unreachable + case .ENOBUFS: + return .Insufficient_Resources + case: + return .Unknown + } +} + _socket_option_error :: proc(errno: linux.Errno) -> Socket_Option_Error { assert(errno != nil) _last_error = errno diff --git a/core/net/errors_windows.odin b/core/net/errors_windows.odin index b30046a17..8e0e4cda3 100644 --- a/core/net/errors_windows.odin +++ b/core/net/errors_windows.odin @@ -234,6 +234,17 @@ _shutdown_error :: proc() -> Shutdown_Error { } } +_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: diff --git a/core/net/socket.odin b/core/net/socket.odin index 801693962..f68508169 100644 --- a/core/net/socket.odin +++ b/core/net/socket.odin @@ -174,10 +174,17 @@ listen_tcp :: proc(interface_endpoint: Endpoint, backlog := 1000) -> (socket: TC /* Returns the endpoint that the given socket is listening / bound on. */ -bound_endpoint :: proc(socket: Any_Socket) -> (endpoint: Endpoint, err: Listen_Error) { +bound_endpoint :: proc(socket: Any_Socket) -> (endpoint: Endpoint, err: Socket_Info_Error) { return _bound_endpoint(socket) } +/* + Returns the endpoint that the given socket is connected to. (Peer's endpoint) +*/ +peer_endpoint :: proc(socket: Any_Socket) -> (endpoint: Endpoint, err: Socket_Info_Error) { + return _peer_endpoint(socket) +} + accept_tcp :: proc(socket: TCP_Socket, options := DEFAULT_TCP_OPTIONS) -> (client: TCP_Socket, source: Endpoint, err: Accept_Error) { return _accept_tcp(socket, options) } diff --git a/core/net/socket_darwin.odin b/core/net/socket_darwin.odin index e63f1844a..fe4b4c3b5 100644 --- a/core/net/socket_darwin.odin +++ b/core/net/socket_darwin.odin @@ -137,11 +137,24 @@ _listen_tcp :: proc(interface_endpoint: Endpoint, backlog := 1000) -> (skt: TCP_ } @(private) -_bound_endpoint :: proc(sock: Any_Socket) -> (ep: Endpoint, err: Listen_Error) { +_bound_endpoint :: proc(sock: Any_Socket) -> (ep: Endpoint, err: Socket_Info_Error) { addr: posix.sockaddr_storage addr_len := posix.socklen_t(size_of(addr)) if posix.getsockname(posix.FD(any_socket_to_socket(sock)), (^posix.sockaddr)(&addr), &addr_len) != .OK { - err = _listen_error() + err = _socket_info_error() + return + } + + ep = _sockaddr_to_endpoint(&addr) + return +} + +@(private) +_peer_endpoint :: proc(sock: Any_Socket) -> (ep: Endpoint, err: Socket_Info_Error) { + addr: posix.sockaddr_storage + addr_len := posix.socklen_t(size_of(addr)) + if posix.getpeername(posix.FD(any_socket_to_socket(sock)), (^posix.sockaddr)(&addr), &addr_len) != .OK { + err = _socket_info_error() return } diff --git a/core/net/socket_freebsd.odin b/core/net/socket_freebsd.odin index b510346ba..78bd1cdae 100644 --- a/core/net/socket_freebsd.odin +++ b/core/net/socket_freebsd.odin @@ -140,12 +140,26 @@ _listen_tcp :: proc(interface_endpoint: Endpoint, backlog := 1000) -> (socket: T } @(private) -_bound_endpoint :: proc(sock: Any_Socket) -> (ep: Endpoint, err: Listen_Error) { +_bound_endpoint :: proc(sock: Any_Socket) -> (ep: Endpoint, err: Socket_Info_Error) { sockaddr: freebsd.Socket_Address_Storage errno := freebsd.getsockname(cast(Fd)any_socket_to_socket(sock), &sockaddr) if errno != nil { - err = _listen_error(errno) + err = _socket_info_error(errno) + return + } + + ep = _sockaddr_to_endpoint(&sockaddr) + return +} + +@(private) +_peer_endpoint :: proc(sock: Any_Socket) -> (ep: Endpoint, err: Socket_Info_Error) { + sockaddr: freebsd.Socket_Address_Storage + + errno := freebsd.getpeername(cast(Fd)any_socket_to_socket(sock), &sockaddr) + if errno != nil { + err = _socket_info_error(errno) return } diff --git a/core/net/socket_linux.odin b/core/net/socket_linux.odin index 3ec3521f0..bdb48fce8 100644 --- a/core/net/socket_linux.odin +++ b/core/net/socket_linux.odin @@ -218,11 +218,24 @@ _listen_tcp :: proc(endpoint: Endpoint, backlog := 1000) -> (socket: TCP_Socket, } @(private) -_bound_endpoint :: proc(sock: Any_Socket) -> (ep: Endpoint, err: Listen_Error) { +_bound_endpoint :: proc(sock: Any_Socket) -> (ep: Endpoint, err: Socket_Info_Error) { addr: linux.Sock_Addr_Any errno := linux.getsockname(_unwrap_os_socket(sock), &addr) if errno != .NONE { - err = _listen_error(errno) + err = _socket_info_error(errno) + return + } + + ep = _wrap_os_addr(addr) + return +} + +@(private) +_peer_endpoint :: proc(sock: Any_Socket) -> (ep: Endpoint, err: Socket_Info_Error) { + addr: linux.Sock_Addr_Any + errno := linux.getpeername(_unwrap_os_socket(sock), &addr) + if errno != .NONE { + err = _socket_info_error(errno) return } diff --git a/core/net/socket_windows.odin b/core/net/socket_windows.odin index 4576149de..cab820ed5 100644 --- a/core/net/socket_windows.odin +++ b/core/net/socket_windows.odin @@ -177,11 +177,25 @@ _listen_tcp :: proc(interface_endpoint: Endpoint, backlog := 1000) -> (socket: T } @(private) -_bound_endpoint :: proc(sock: Any_Socket) -> (ep: Endpoint, err: Listen_Error) { +_bound_endpoint :: proc(sock: Any_Socket) -> (ep: Endpoint, err: Socket_Info_Error) { sockaddr: win.SOCKADDR_STORAGE_LH sockaddrlen := c.int(size_of(sockaddr)) if win.getsockname(win.SOCKET(any_socket_to_socket(sock)), &sockaddr, &sockaddrlen) == win.SOCKET_ERROR { - err = _listen_error() + err = _socket_info_error() + return + } + + ep = _sockaddr_to_endpoint(&sockaddr) + return +} + +@(private) +_peer_endpoint :: proc(sock: Any_Socket) -> (ep: Endpoint, err: Socket_Info_Error) { + sockaddr: win.SOCKADDR_STORAGE_LH + sockaddrlen := c.int(size_of(sockaddr)) + res := win.getpeername(win.SOCKET(any_socket_to_socket(sock)), &sockaddr, &sockaddrlen) + if res < 0 { + err = _socket_info_error() return } |