You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When trying to call bind(sock, addr), defined in the package core:sys/linux, using a Sock_Addr_In as an address, the syscall to bind always returns EINVAL. This is because the Sock_Addr_In structure is not properly defined.
On Linux's source code, the sockaddr_in structure (defined here) have a sin_zero field that pads the size of the structure to be, at least, the size of struct sockaddr (defined here), which turns out to be 16 bytes (a short integer + an array of 14 bytes).
On an IPv4 bind, Linux expects the address to be, at least, the size of the previously defined sockaddr_in (here). If it doesn't have the minimum size (16 bytes), the code fails.
Sock_Addr_In (here) currently have a size of 8 bytes (2 short integers + an array of 4 bytes), so it will always fail this check.
The core:net's calls to linux.bind on the functions _bind (here) and _listen_tcp (here) get around this because of the way they unwrap the address structure from the endpoint. The _unwrap_os_addr (here) always returns a type Sock_Addr_Any, which has a size of 110 bytes, due to being a union with a Sock_Addr_Un.
Given that the bind syscall only checks for an addr_len smaller than sockaddr_in, not bigger, these calls to bind won't fail.
Thus, Sock_Addr_In needs to have the sin_zero padding.
Expected Behavior
The bind syscall returning successfully
Current Behavior
As seen with the snippet bellow, the current call to bind always returns an EINVAL error.
Failure Information (for bugs)
Steps to Reproduce
Compile the following code with odin build test.odin -file, then run using strace (strace test).
package main
import"core:sys/linux"
main :: proc()
{
using linux
sock, errno := socket(Address_Family.INET, Socket_Type.STREAM, {}, Protocol.TCP)
if errno != Errno.NONE dopanic("linux.socket")
deferclose(sock)
addr := Sock_Addr_In{ sin_family=Address_Family.INET }
errno = bind(sock, &addr) // Fails hereif errno != Errno.NONE dopanic("linux.bind") // Then panics here
}
Context
When trying to call
bind(sock, addr)
, defined in the packagecore:sys/linux
, using aSock_Addr_In
as an address, the syscall to bind always returnsEINVAL
. This is because theSock_Addr_In
structure is not properly defined.On Linux's source code, the
sockaddr_in
structure (defined here) have asin_zero
field that pads the size of the structure to be, at least, the size ofstruct sockaddr
(defined here), which turns out to be 16 bytes (a short integer + an array of 14 bytes).On an IPv4 bind, Linux expects the address to be, at least, the size of the previously defined
sockaddr_in
(here). If it doesn't have the minimum size (16 bytes), the code fails.Sock_Addr_In
(here) currently have a size of 8 bytes (2 short integers + an array of 4 bytes), so it will always fail this check.The
core:net
's calls tolinux.bind
on the functions_bind
(here) and_listen_tcp
(here) get around this because of the way they unwrap the address structure from the endpoint. The_unwrap_os_addr
(here) always returns a typeSock_Addr_Any
, which has a size of 110 bytes, due to being a union with aSock_Addr_Un
.Given that the bind syscall only checks for an
addr_len
smaller thansockaddr_in
, not bigger, these calls to bind won't fail.Thus,
Sock_Addr_In
needs to have thesin_zero
padding.Expected Behavior
The bind syscall returning successfully
Current Behavior
As seen with the snippet bellow, the current call to bind always returns an
EINVAL
error.Failure Information (for bugs)
Steps to Reproduce
Compile the following code with
odin build test.odin -file
, then run using strace (strace test
).Failure Logs
Snippet of strace's output
The text was updated successfully, but these errors were encountered: