No IPv6 in this SDK package: socket(AF_INET6, ...) fails with EAFNOSUPPORT, while the manual documents IPv6 configuration for kos_net.h ("Configure the available network interfaces with IPv4 and IPv6 addressing.", configure_net_iface6(), pp. 124-125 of the 1.4 PDF). Its network stack has no IPv6 library: rumpConfig.cmake adds rump::rumpnet_netinet6 only if that target exists, and the sysroot has no librumpnet_netinet6.a.
localhost resolves only from a hosts file given to VfsNet: getaddrinfo() runs in VfsNet (the manual lists it under "Functions implemented by the vfs::lib_net library", p. 97), which reads /etc/hosts from its own file systems (in an earlier test of mine, an /etc/hosts in the application's file system changed nothing). The manual's examples list a hosts file among VfsNet's configuration files, but nothing says that name resolution, localhost included, needs one; RFC 6761 (6.3) recommends that resolvers always return the loopback address for localhost.
sendfile() from a file to a TCP socket fails with EINVAL, although it is declared and defined, so configure checks find it, and the manual's table "Functions implemented by the vfs::lib_fs library" (pp. 96-97) lists it.
shutdown() on an unconnected socket succeeds; POSIX says it "shall fail" with ENOTCONN. In NetBSD 10's source it succeeds too: its soshutdown() has no connection check, although its shutdown(2) man page lists ENOTCONN.
A socket from accept4() inherits O_NONBLOCK from a non-blocking listener. POSIX.1-2024 says the new socket's O_NONBLOCK "shall be determined solely by the flag argument", and NetBSD's accept4() (its paccept()) clears the inherited flag; only accept() may inherit it.
poll(): a closed descriptor in the set fails the whole call with EBADF instead of setting POLLNVAL in its entry, as POSIX requires and as NetBSD 10's pollscan does. (More than 512 entries fail with EINVAL, as POSIX requires: OPEN_MAX is 512 in the SDK's limits.h.)
Program
One program, https://github.com/caraioniurie47/kos-sdk-checks/blob/main/src/net-check.c, run as the only application in an image with the SDK's precompiled_vfs::VfsNet as its network backend and precompiled_vfs::VfsRamFs as its file system, after configuring en0 as the SDK's network examples do (no hosts file given to VfsNet). The same source ran on Linux for comparison (Ubuntu 22.04, kernel 6.18 under WSL2), with the two kos_net.h calls replaced by stubs. The repository has the image's build files, the scripts that ran both, and the output.
Output
Check
KasperskyOS CE 1.4.0.102
Linux
socket(AF_INET6, SOCK_STREAM, 0)
-1, errno Address family not supported by protocol family
3
getaddrinfo("localhost")
7, No address associated with hostname
0
sendfile(tcp socket, file, &offset, 512)
-1, errno Invalid argument
512
recv(tcp socket, 81920-byte buffer), 70000 bytes sent
The two recv rows are fine on both systems (partial reads are allowed; Linux's 70512 includes the 512 bytes sendfile sent). I included them because an earlier test of mine had recv with a buffer over 64 KiB fail with EINVAL; this program does not reproduce that.
What each one breaks
IPv6: portable code and test suites often assume at least an IPv6 loopback; many of .NET's socket tests do. Is IPv6 left out of the Community Edition on purpose, or not yet available? Either way, a sentence in the networking documentation would save the search.
localhost: .NET's socket tests connect to localhost by name, and 26 of them failed. After I gave VfsNet a ROMFS /etc/hosts with 127.0.0.1 localhost (as the SDK's net_with_separate_vfs example does for its own hosts), those tests, run again alone, no longer failed: 20 passed, and 4 skipped because localhost has no IPv6 address (the 2 IPv6 cases among the 26 are no longer run, as there is no IPv6). Could the documentation say that name resolution, localhost included, needs a hosts file for VfsNet or DNS?
sendfile: Socket.SendFile in .NET threw "Invalid argument"; my port now copies with read and write on KasperskyOS.
shutdown: .NET's Socket.Disconnect on an unconnected socket does not throw.
accept4 and O_NONBLOCK: .NET clears the flag after accept() on macOS and FreeBSD, but on a system with accept4 it assumes Linux behaviour. On KasperskyOS its synchronous reads on accepted sockets then failed with "Operation timed out" (its blocking-mode EAGAIN), until my port cleared the flag there too. Could accept4 take O_NONBLOCK from its flags only, as POSIX requires and NetBSD does?
poll: an event loop that polls many sockets while other threads close them gets whole-call failures instead of per-descriptor POLLNVAL. My port polls each descriptor alone after a failure to find the closed one, and splits the set into chunks of 512 (OPEN_MAX). The POSIX implementation specifics page says only that invalid handles combined with a negative (unlimited) timeout make poll() fail with EINVAL; the program above uses a zero timeout.
Could sendfile work for sockets (or be left out of the headers and libraries), could accept4 follow POSIX, could shutdown and poll either follow POSIX here or have their behaviour documented, and could the others be documented?
Summary
No IPv6 in this SDK package:
socket(AF_INET6, ...)fails withEAFNOSUPPORT, while the manual documents IPv6 configuration forkos_net.h("Configure the available network interfaces with IPv4 and IPv6 addressing.",configure_net_iface6(), pp. 124-125 of the 1.4 PDF). Its network stack has no IPv6 library:rumpConfig.cmakeaddsrump::rumpnet_netinet6only if that target exists, and the sysroot has nolibrumpnet_netinet6.a.localhostresolves only from a hosts file given to VfsNet:getaddrinfo()runs in VfsNet (the manual lists it under "Functions implemented by the vfs::lib_net library", p. 97), which reads/etc/hostsfrom its own file systems (in an earlier test of mine, an/etc/hostsin the application's file system changed nothing). The manual's examples list a hosts file among VfsNet's configuration files, but nothing says that name resolution,localhostincluded, needs one; RFC 6761 (6.3) recommends that resolvers always return the loopback address forlocalhost.sendfile()from a file to a TCP socket fails withEINVAL, although it is declared and defined, so configure checks find it, and the manual's table "Functions implemented by the vfs::lib_fs library" (pp. 96-97) lists it.shutdown()on an unconnected socket succeeds; POSIX says it "shall fail" withENOTCONN. In NetBSD 10's source it succeeds too: itssoshutdown()has no connection check, although itsshutdown(2)man page listsENOTCONN.A socket from
accept4()inheritsO_NONBLOCKfrom a non-blocking listener. POSIX.1-2024 says the new socket'sO_NONBLOCK"shall be determined solely by the flag argument", and NetBSD'saccept4()(itspaccept()) clears the inherited flag; onlyaccept()may inherit it.poll(): a closed descriptor in the set fails the whole call withEBADFinstead of settingPOLLNVALin its entry, as POSIX requires and as NetBSD 10'spollscandoes. (More than 512 entries fail withEINVAL, as POSIX requires:OPEN_MAXis 512 in the SDK'slimits.h.)Program
One program, https://github.com/caraioniurie47/kos-sdk-checks/blob/main/src/net-check.c, run as the only application in an image with the SDK's
precompiled_vfs::VfsNetas its network backend andprecompiled_vfs::VfsRamFsas its file system, after configuringen0as the SDK's network examples do (no hosts file given to VfsNet). The same source ran on Linux for comparison (Ubuntu 22.04, kernel 6.18 under WSL2), with the twokos_net.hcalls replaced by stubs. The repository has the image's build files, the scripts that ran both, and the output.Output
Check
KasperskyOS CE 1.4.0.102
Linux
socket(AF_INET6, SOCK_STREAM, 0)-1, errno Address family not supported by protocol family
3
getaddrinfo("localhost")7, No address associated with hostname
0
sendfile(tcp socket, file, &offset, 512)-1, errno Invalid argument
512
recv(tcp socket, 81920-byte buffer), 70000 bytes sent32768
70512
recv(tcp socket, 65536-byte buffer) after that24576
-1, errno Resource temporarily unavailable
shutdown(unconnected TCP socket, SHUT_RDWR)0
-1, errno Transport endpoint is not connected
accept4(non-blocking listener, SOCK_CLOEXEC): O_NONBLOCKset
clear
poll({open socket, closed descriptor}, 2, 0)-1, errno Bad file descriptor
2
revents0x0, 0x0
0x14, 0x20
poll(513 entries, every fd -1, timeout 0)-1, errno Invalid argument
0
poll(512 entries, every fd -1, timeout 0)0
0
The two
recvrows are fine on both systems (partial reads are allowed; Linux's 70512 includes the 512 bytessendfilesent). I included them because an earlier test of mine hadrecvwith a buffer over 64 KiB fail withEINVAL; this program does not reproduce that.What each one breaks
IPv6: portable code and test suites often assume at least an IPv6 loopback; many of .NET's socket tests do. Is IPv6 left out of the Community Edition on purpose, or not yet available? Either way, a sentence in the networking documentation would save the search.
localhost: .NET's socket tests connect tolocalhostby name, and 26 of them failed. After I gave VfsNet a ROMFS/etc/hostswith127.0.0.1 localhost(as the SDK'snet_with_separate_vfsexample does for its own hosts), those tests, run again alone, no longer failed: 20 passed, and 4 skipped becauselocalhosthas no IPv6 address (the 2 IPv6 cases among the 26 are no longer run, as there is no IPv6). Could the documentation say that name resolution,localhostincluded, needs a hosts file for VfsNet or DNS?sendfile:Socket.SendFilein .NET threw "Invalid argument"; my port now copies withreadandwriteon KasperskyOS.shutdown: .NET'sSocket.Disconnecton an unconnected socket does not throw.accept4andO_NONBLOCK: .NET clears the flag afteraccept()on macOS and FreeBSD, but on a system withaccept4it assumes Linux behaviour. On KasperskyOS its synchronous reads on accepted sockets then failed with "Operation timed out" (its blocking-modeEAGAIN), until my port cleared the flag there too. Couldaccept4takeO_NONBLOCKfrom its flags only, as POSIX requires and NetBSD does?poll: an event loop that polls many sockets while other threads close them gets whole-call failures instead of per-descriptorPOLLNVAL. My port polls each descriptor alone after a failure to find the closed one, and splits the set into chunks of 512 (OPEN_MAX). The POSIX implementation specifics page says only that invalid handles combined with a negative (unlimited) timeout makepoll()fail withEINVAL; the program above uses a zero timeout.Could
sendfilework for sockets (or be left out of the headers and libraries), couldaccept4follow POSIX, couldshutdownandpolleither follow POSIX here or have their behaviour documented, and could the others be documented?Context
Found while running .NET's System.Net.Sockets test suite on a KasperskyOS port of .NET (NativeAOT; latest release: https://github.com/caraioniurie47/runtime-kos/releases/latest).
Edited by Юрий К
fixed table