odin-lang / Odin

Odin Programming Language
https://odin-lang.org
BSD 3-Clause "New" or "Revised" License
6.1k stars 550 forks source link

Port `core:net` to FreeBSD #3810

Open Feoramund opened 5 days ago

Feoramund commented 5 days ago

I'd like to get some extra eyes on this. This is a minimal syscall-based implementation to get FreeBSD working with the net package.

I've made sure tests pass, and I have a simple echo server working in TCP with telnet, but I haven't done anything more rigorous as far as testing goes, yet. If there's something out there written in Odin that could stress test the networking side of things, I'd like to know about it. Of note, I've tested this both on AMD64 and ARM64.

Some important notes: I wrote this mostly from the ground up while keeping an eye on what Linux, Darwin, and Windows do for their internal API with regards to net. I broke from convention and implemented all of this using only the new sys/freebsd package I added, instead of trying to finagle anything with the os package, given my understanding that 1) os is not a good package in Bill's words and 2) it is due to be replaced by os2 at some point. Easily sidestepped all of that by keeping things close to the metal, as it were. I opted not to touch sys/unix either, since that package seems to be taking on too much responsibility as it is, given how little commonality there is between the UNIX-likes aside from perhaps POSIX libc overlap.

During implementation, I noticed that the different platforms tended to have different error enums exposed in their various Network_Errors. This is understandable given how systems will work differently. I implemented FreeBSD's on the basis of man page descriptions per the underlying syscalls and tried to make them fit error names that were already present, but in cases where I felt the names were not clear enough, I wrote more verbosely. This can be changed to conform with others if needed.

I'm wondering if this is something that should be standardized in the future, since it means dealing with network errors is different per-platform right now, if you actually need to know the specific error, that is.

I also had to fix the FreeBSD implementation of futexes. There was an incorrect usage of the system API in that it did not pass the size of the timeout structure, nor did it specify WAIT_UINT when it was using an unsigned integer as the underlying futex data. This was required to get net tests to pass, otherwise Wait_Group was failing with a complaint about simultaneous waiting and adding. I went ahead and removed any dependency on libc there by using direct syscalls, too.

Pinging @andreas-jonsson because I know you are interested in this for NetBSD. I haven't tinkered much with NetBSD, but I'm optimistic that this implementation could serve as a good starting point for that platform. I aimed to keep documentation and organization regarding system types and calls as helpful as possible for future maintenance or porting.

I am not so sure about OpenBSD though. I have heard that Go has had some troubles with their syscall pinning security restrictions, but it's not something I have thoroughly researched. My understanding is that OpenBSD is assertive about libc being the API to the kernel, whereas FreeBSD at least has an entire chapter in their manual dedicated to programming for the kernel in assembly with syscalls.