bind, getsockname, sendto and recvfrom validate as for a libkernel socket
before they reach libSceNet, so a forwarded descriptor reports the same
errors. recvfrom keeps its guest address handling and MSG_WAITALL, and a
zero-length datagram receive does not wait.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
A title can create a socket with sceNetSocket and then call bind, getsockname, sendto or recvfrom from libkernel, which does not hold that descriptor, so the call failed with EBADF. PPSA06866's RakNet does this, its local server fails to start and the load after difficulty selection never ends. libSceNet now registers these four calls with libkernel, as it does for setsockopt and getsockopt.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
rooklz read sceNetConfigGetDefaultRoute (NID lFJb+BlPK1c, wrapper at
0x153f0) in libSceNet.sprx. Before sceNetInit it returns 0x804101C8
with errno 200. Without a default route it returns 0x8041130C and
leaves the output alone. With one it stores the route and returns 1,
not 0. The wrapper never checks the output pointer.
The not-initialized answer reads the library's sceNetInit/sceNetTerm
flag through fail(), as the other exports do. The route is still the
host gateway. A null output with a route throws std::invalid_argument,
where the module faults.
Co-authored-by: rooklz <[email protected]>
rooklz read sceNetInetNtopWithScopeId (FUN_00006be0) and
sceNetInetPtonWithScopeId (FUN_000072d0) in libSceNet.sprx. The zone
after '%' is one of the ten interface names, never a number, and ntop
prints the name of the interface whose index is the scope. A null
address or text and a short buffer set ENOSPC, and another family sets
EAFNOSUPPORT. Pton reads a zone only when the scope output is not null,
and answers another family with EAFNOSUPPORT and a null text with
EINVAL.
The host has none of these interfaces. Names and indexes go through the
interface table and host-index mapping of rooklz's "feat(net): resolve
interface ids to host indexes", taken with the same text so the two
changes merge without conflict there. A null destination throws
std::invalid_argument, where the module faults.
Co-authored-by: rooklz <[email protected]>
sceNetResolverStartNtoa refuses a timeout from 1 to 999999 with EINVAL
before the resolver is looked up, and takes 0 as 1000000, as a run of
firmware 13.42's module shows.
Emscripten targets wasm64 without x86 assembly, Linux-only headers or the
x87 long double. These changes add __EMSCRIPTEN__ paths beside the host
ones; native builds compile the same code as before.
- libc: long doubles in guest varargs and scanf go through
GuestLongDouble, a plain copy where long double is the x87 format;
APS5_EXPORT emits no assembler alias; the guest arena is one aligned
allocation that zeroes pages when they are committed again; getifaddrs
keeps its link-level entries on Linux; /proc lookups and the host
stderr duplicate are left out.
- libkernel: file-backed mmap, EVFILT_VNODE watches, getcontext and
setcontext throw; getdents replaces the raw getdents64 syscall;
getdtablesize takes the resource limit alone.
- VideoOut leaves SDL, the display window and the HDR probe out,
Sysmodule asks libkernel for unwind information and Net includes
sys/time.h.
sceNetGetStatisticsInfo threw NotImplemented_nid_no_patch. It now fills
the six 32-bit fields of the statistics block (kernel memory free and
minimum free, packet count, QoS packet count, library memory free and
minimum free) and fails with NET_EFAULT, setting errno, for a null
pointer. The layout and the "plenty free, nothing queued" answer follow
shadPS4's net.cpp and net_types.h; the host has no counter for the
console's network memory, so the values are not measured. The debt file
records this, and the test checks the null pointer, the field
invariants and that the flags argument is ignored.
sceNetShowIfconfigWithMemory, sceNetShowPolicyWithMemory and
sceNetShowRoute6WithMemory threw NotImplemented_nid_no_patch. They now
behave like the existing sceNetShowRouteWithMemory: an unknown memory
pool id fails with NET_EBADF (errno set), a live pool returns success
without printing. The behaviour follows shadPS4's net.cpp, which does
the same for these three. The new silent stubs are listed in the
libSceNet technical debt file, and the tests cover the invalid id, live
pool and destroyed pool cases.
guest_kernel_sys_threads_main, guest_kernel_sys_threads_main_patched and
net_ipv6only_patched link the MinGW runtime statically and load
libkernel_sys.prx or libSceNet.prx with LoadLibraryExW and
LOAD_WITH_ALTERED_SEARCH_PATH. Windows then looks for the libraries'
libstdc++-6.dll next to the .prx and on PATH, not next to the test
executable where the build copies the runtime. From Git Bash, whose PATH
starts with Git's mingw64/bin, the loader took Git's libstdc++-6.dll,
which lacks the std::__codecvt_utf8_utf16_base<wchar_t> members that
libkernel_sys, libkernel and libc import. The threads tests hung on an
"Entry Point Not Found" dialog until their 20 s timeout, and
net_ipv6only_patched, which suppresses the dialog, got error 127 and
aborted.
On MinGW, prepend the compiler's directory to their PATH, as
patched_libraries does since #10101.
Since #9137 both throw after sceNetInit. A PS5 on firmware 13.40
returns 0 from each and prints plain-text tables to stdout. They now
print the console's layout with what the emulator knows: ifconfig an
eth0 block from the host interface sceNetCtlGetInfo reports (the same
MAC, address, netmask and MTU), the console's lo0 block and the DNS
servers; netstat the header and one entry per socket and epoll of the
title, with the self and non-blocking flags, addresses, buffer sizes and
the names given to sceNetSocket and sceNetEpollCreate, which are now
kept. The debt entry lists what the console prints that is left out.
guest_sce_net captures both outputs: the lo0 block and DNS section, a
named unbound UDP socket, a non-blocking listening TCP socket bound to
127.0.0.1, an epoll, a 40-character name cut to 31, and the entries gone
after close.
Copy the iovec table only when there is one, and receive a datagram
with no iovecs in guest_sce_net: it returns 0 with MSG_TRUNC and the
sender's address.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
sceNetRecvmsg guarded the destinations of the iovec table it saw at
entry, then read the live table again to scatter the received bytes.
When an earlier destination overlapped a later iovec, the received
bytes replaced that iovec and the rest of the data went to an address
that was never guarded, which crashed the host when that address was
not writable. Copy the header and the iovec table once, as FreeBSD
11.4's sys_recvmsg does with copyin and copyiniov, use that copy for
the guards, the scatter and the address, and write the header back
from it as sys_recvmsg's copyout does.
Fixes#11610
Co-Authored-By: Claude Opus 5.5 <[email protected]>