[net] Better error code for binding a privileged port without root access on Darwin

This condition results in os.EACCESS, which we were translating to Broadcast_Disabled.
This was the case because binding to the broadcast address on a UDP port, without setting the BROADCAST flag, also results in this error.

Given the fact that reserved ports also produce this error, we now check for this condition in net.bind() and translate it to a custom, clearer error:
Privileged_Port_Without_Root.
This commit is contained in:
Tetralux
2024-02-22 14:41:37 +00:00
parent c5c2a4d09d
commit ec0831da70
2 changed files with 12 additions and 3 deletions

View File

@@ -34,7 +34,7 @@ Create_Socket_Error :: enum c.int {
Dial_Error :: enum c.int {
None = 0,
Port_Required = -1,
Port_Required = -1, // Attempted to dial an endpointing without a port being set.
Address_In_Use = c.int(os.EADDRINUSE),
In_Progress = c.int(os.EINPROGRESS),
@@ -54,7 +54,9 @@ Dial_Error :: enum c.int {
}
Bind_Error :: enum c.int {
None = 0,
None = 0,
Privileged_Port_Without_Root = -1, // Attempted to bind to a port less than 1024 without root access.
Address_In_Use = c.int(os.EADDRINUSE), // Another application is currently bound to this endpoint.
Given_Nonlocal_Address = c.int(os.EADDRNOTAVAIL), // The address is not a local address on this machine.
Broadcast_Disabled = c.int(os.EACCES), // To bind a UDP socket to the broadcast address, the appropriate socket option must be set.

View File

@@ -92,13 +92,20 @@ _dial_tcp_from_endpoint :: proc(endpoint: Endpoint, options := default_tcp_optio
return
}
// On Darwin, any port below 1024 is 'privileged' - which means that you need root access in order to use it.
MAX_PRIVILEGED_PORT :: 1023
@(private)
_bind :: proc(skt: Any_Socket, ep: Endpoint) -> (err: Network_Error) {
sockaddr := _endpoint_to_sockaddr(ep)
s := any_socket_to_socket(skt)
res := os.bind(os.Socket(s), (^os.SOCKADDR)(&sockaddr), i32(sockaddr.len))
if res != os.ERROR_NONE {
err = Bind_Error(res)
if res == os.EACCES && ep.port <= MAX_PRIVILEGED_PORT {
err = .Port_Reserved
} else {
err = Bind_Error(res)
}
}
return
}