mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 07:38:48 +00:00
Merge pull request #5315 from peperronii/master
Expose getpeername() in core:net package as "peer_endpoint"
This commit is contained in:
@@ -64,6 +64,7 @@ Network_Error :: union #shared_nil {
|
|||||||
UDP_Recv_Error,
|
UDP_Recv_Error,
|
||||||
Shutdown_Error,
|
Shutdown_Error,
|
||||||
Interfaces_Error,
|
Interfaces_Error,
|
||||||
|
Socket_Info_Error,
|
||||||
Socket_Option_Error,
|
Socket_Option_Error,
|
||||||
Set_Blocking_Error,
|
Set_Blocking_Error,
|
||||||
Parse_Endpoint_Error,
|
Parse_Endpoint_Error,
|
||||||
|
|||||||
@@ -246,6 +246,23 @@ Shutdown_Error :: enum i32 {
|
|||||||
Unknown,
|
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 {
|
Socket_Option_Error :: enum i32 {
|
||||||
None,
|
None,
|
||||||
// No network connection, or the network stack is not initialized.
|
// No network connection, or the network stack is not initialized.
|
||||||
|
|||||||
@@ -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 {
|
_socket_option_error :: proc() -> Socket_Option_Error {
|
||||||
#partial switch posix.errno() {
|
#partial switch posix.errno() {
|
||||||
case .ENOBUFS:
|
case .ENOBUFS:
|
||||||
|
|||||||
@@ -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 {
|
_socket_option_error :: proc(errno: freebsd.Errno) -> Socket_Option_Error {
|
||||||
assert(errno != nil)
|
assert(errno != nil)
|
||||||
_last_error = errno
|
_last_error = errno
|
||||||
|
|||||||
@@ -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 {
|
_socket_option_error :: proc(errno: linux.Errno) -> Socket_Option_Error {
|
||||||
assert(errno != nil)
|
assert(errno != nil)
|
||||||
_last_error = errno
|
_last_error = errno
|
||||||
|
|||||||
@@ -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 {
|
_socket_option_error :: proc() -> Socket_Option_Error {
|
||||||
#partial switch win.System_Error(win.WSAGetLastError()) {
|
#partial switch win.System_Error(win.WSAGetLastError()) {
|
||||||
case .WSAENETDOWN, .WSANOTINITIALISED:
|
case .WSAENETDOWN, .WSANOTINITIALISED:
|
||||||
|
|||||||
@@ -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.
|
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)
|
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) {
|
accept_tcp :: proc(socket: TCP_Socket, options := DEFAULT_TCP_OPTIONS) -> (client: TCP_Socket, source: Endpoint, err: Accept_Error) {
|
||||||
return _accept_tcp(socket, options)
|
return _accept_tcp(socket, options)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -137,11 +137,24 @@ _listen_tcp :: proc(interface_endpoint: Endpoint, backlog := 1000) -> (skt: TCP_
|
|||||||
}
|
}
|
||||||
|
|
||||||
@(private)
|
@(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: posix.sockaddr_storage
|
||||||
addr_len := posix.socklen_t(size_of(addr))
|
addr_len := posix.socklen_t(size_of(addr))
|
||||||
if posix.getsockname(posix.FD(any_socket_to_socket(sock)), (^posix.sockaddr)(&addr), &addr_len) != .OK {
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -140,12 +140,26 @@ _listen_tcp :: proc(interface_endpoint: Endpoint, backlog := 1000) -> (socket: T
|
|||||||
}
|
}
|
||||||
|
|
||||||
@(private)
|
@(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
|
sockaddr: freebsd.Socket_Address_Storage
|
||||||
|
|
||||||
errno := freebsd.getsockname(cast(Fd)any_socket_to_socket(sock), &sockaddr)
|
errno := freebsd.getsockname(cast(Fd)any_socket_to_socket(sock), &sockaddr)
|
||||||
if errno != nil {
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -218,11 +218,24 @@ _listen_tcp :: proc(endpoint: Endpoint, backlog := 1000) -> (socket: TCP_Socket,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@(private)
|
@(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
|
addr: linux.Sock_Addr_Any
|
||||||
errno := linux.getsockname(_unwrap_os_socket(sock), &addr)
|
errno := linux.getsockname(_unwrap_os_socket(sock), &addr)
|
||||||
if errno != .NONE {
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -177,11 +177,25 @@ _listen_tcp :: proc(interface_endpoint: Endpoint, backlog := 1000) -> (socket: T
|
|||||||
}
|
}
|
||||||
|
|
||||||
@(private)
|
@(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
|
sockaddr: win.SOCKADDR_STORAGE_LH
|
||||||
sockaddrlen := c.int(size_of(sockaddr))
|
sockaddrlen := c.int(size_of(sockaddr))
|
||||||
if win.getsockname(win.SOCKET(any_socket_to_socket(sock)), &sockaddr, &sockaddrlen) == win.SOCKET_ERROR {
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user