Files
AnyPS5/docs/dev/debt/libSceNet.md
T
Dean 587bb343e8 Merge pull request #8106 from juanpimg/feat/prx-declare-ps5-3.20-exports
feat(prx): declare the missing PS5 3.20 system exports
2026-10-20 21:13:30 +13:00

34 KiB

libSceNet technical debt

Silent stubs

  • sceNetShowIfconfig, sceNetShowNetstat (libSceNet) - return success without printing anything: the () signatures and the success return follow shadPS4, which stubs both the same way. PPSA01530 fails to load without the sceNetShowIfconfig export (#3177); PPSA11386 imports sceNetShowNetstat but does not call it during start-up. What the console prints and where is unverified

Unknown function info

Functional

  • sceNetResolverStartAton6 (libSceNet) reverse-resolves a 16-byte IPv6 address through the host resolver (getnameinfo with NI_NAMEREQD) into the caller's buffer of len bytes, as sceNetResolverStartAton does for IPv4. The (rid, addr, hostname, len, timeout, retry, flags) signature comes from SharpProspero. An address with no name, or a name longer than len - 1 bytes, fails with RESOLVER_ENODNS (0x804101E1) and leaves the buffer untouched; whether the console truncates instead is not verified. Abort flag 2 (ATON preservation) fails the next call with EINTR as it does sceNetResolverStartAton. Timeout and retry are ignored, and any nonzero flags throw because their meaning is unknown

  • sceNetAccept (libSceNet) inherits the listener's non-blocking mode through the existing SO_NBIO setter, as the libkernel socket path does and FreeBSD's sonewconn copies the socket state. The mode is sampled when accept starts; changes between connection creation and accept are not modelled. Not measured on a console.

  • sceNetConnect to AF_UNSPEC (libSceNet) dissolves a datagram association as FreeBSD 11.4's udp_disconnect() does, which resets the local address to the wildcard address and keeps the port. On Linux a socket bound to an explicit port keeps its local address as well (127.0.0.1:<port> stays 127.0.0.1:<port>), because a bound socket cannot be bound again; one bound to port 0 is bound again to the wildcard address with the port it had

  • sceNetSetsockopt (libSceNet) sets SO_RCVTIMEO and SO_SNDTIMEO as the host socket's timeouts. On Windows a receive or send on a stream socket that times out fails with ETIMEDOUT, where FreeBSD returns EAGAIN or the partial count: Winsock leaves the connection in an indeterminate state after a timeout and reports no partial count (SOL_SOCKET options), so FreeBSD's behaviour needs the timeout waited for without the host option. A receive on a datagram socket that times out fails with EAGAIN

  • sceNetSetsockopt, sceNetGetsockopt (libSceNet) take SO_SNDTIMEO and SO_RCVTIMEO (0x1005, 0x1006) as a 16-byte struct timeval, as FreeBSD 11.4's sosetopt and sogetopt do, and Sony's 0x1105 and 0x1106 as an int of microseconds. A console log of ProsperoLight (firmware 12.20) shows receives timing out every 100 ms after it gave 0x1006 a {0, 100000} timeval. The errors for a value shorter than a timeval (EINVAL) or out of range (EDOM), and sceNetGetsockopt cutting the timeval to the caller's length, follow FreeBSD's sooptcopyin and sooptcopyout and are not measured on a console

  • sceNetSetsockopt (libSceNet) stores SO_ONESBCAST (0x10000, shadPS4's ORBIS_NET_SO_ONESBCAST) per socket and sceNetGetsockopt reads back the value that was set, as shadPS4 does; PPSA34501 sets it and crashes later when it fails with EOPNOTSUPP. Sends ignore it. FreeBSD 11.4's ip(4) documents the like-named IPPROTO_IP option IP_ONESBCAST: a datagram sent to an interface's directed broadcast address, such as 192.168.2.255, leaves through that interface with its destination rewritten to 255.255.255.255, and only on a socket allowed to set SO_BROADCAST. Here host routing selects the outgoing interface and the destination is not rewritten. shadPS4 also leaves sends unchanged, and its TODO reads the option the other way round: a send to 255.255.255.255 would be converted to the interface's broadcast address. Whether the console's SOL_SOCKET option behaves like IP_ONESBCAST, and what it reads back, is not verified on hardware. FreeBSD 11.4's sogetopt() reads several boolean socket options back as their flag bit (so_options & optname, sys/kern/uipc_socket.c), not as the value set; whether the console does so for 0x10000 is unknown

  • sceNetGetsockopt (libSceNet) reads SO_ERROR from the host socket. Winsock does not clear a socket's pending error when it is read, so on Windows the library reports a pending error once and shows it again only after a new sceNetConnect; a second failure with the same code on the same socket without a sceNetConnect in between would be hidden.

  • sceNetSetsockopt, sceNetGetsockopt (libSceNet) set TCP_NODELAY (IPPROTO_TCP, 1) on the host socket of a stream socket and read it back as TF_NODELAY (4) or 0, as FreeBSD 11.4's tcp_default_ctloutput does. Every other IPPROTO_TCP option (TCP_MAXSEG, TCP_NOPUSH and TCP_KEEPIDLE among them, which FreeBSD implements) fails with ENOPROTOOPT, and the IPPROTO_TCP level on a socket that is not a stream socket fails with EINVAL, as ip_ctloutput answers it. A set on a connection that FreeBSD's tcp_ctloutput refuses with ECONNRESET (refused, reset or in TIME_WAIT) succeeds here because the host accepts it. A null value with a nonzero length fails with EINVAL, where FreeBSD's kern_setsockopt returns EFAULT, and a get into less than an int fails with EINVAL, where sooptcopyout truncates. None of this was measured on a console.

  • sceNetGetSockInfo (libSceNet) reports 0 for the name, pid, policy, priority, queue lengths, virtual ports, state, bandwidth, drops and waits, sets no status flag except SELF (0x1) and NONBLOCK (0x200000), and reports the host's buffer sizes where none was set. An IPv6 socket fails with EAFNOSUPPORT and is not counted or listed; shadPS4 lists it with zero addresses. flags bits other than 0x40 fail with EINVAL, where shadPS4 ignores flags; 0x40 adds sockets in TIME_WAIT (SharpProspero), but closed sockets are not kept. Otherwise the s below 0 count and list, the return value and EINVAL for a null info or an n below 1 follow shadPS4. Not measured on a console.

  • sceNetSendmsg and sceNetRecvmsg (libSceNet) copy the scatter/gather list through one host buffer and accept only the flags sceNetSend/sceNetRecv accept. Sending control data throws; a receive never returns control data (msg_controllen 0), since no socket option that queues it is supported

  • MSG_DONTWAIT (libSceNet) in sceNetSend, sceNetSendto, sceNetRecv, sceNetRecvfrom, sceNetRecvmsg and sceNetSendmsg makes that one call non-blocking through the host's MSG_DONTWAIT, as FreeBSD 11.4's soreceive_generic returns EWOULDBLOCK for it (sys/kern/uipc_socket.c); the value 0x80 is FreeBSD's (sys/sys/socket.h) and shadPS4's. Winsock has no per-call non-blocking flag, so on Windows the call first asks WSAPoll with a zero timeout whether the socket is ready and fails with EAGAIN when it is not. The check and the transfer are two host calls: a second thread that takes the data in between can leave a sceNetRecv blocked, and a sceNetSend of more bytes than the socket buffer holds can still block until it has sent them, where FreeBSD's sosend_generic returns a partial count

  • sceNetRecv, sceNetRecvfrom and sceNetRecvmsg (libSceNet) on a datagram socket with no local address wait on Windows until a bind, connect or send gives it one, checking the host socket every 10 ms. Winsock fails such a receive with WSAEINVAL, where FreeBSD 11.4's soreceive_dgram waits for a datagram (sys/kern/uipc_socket.c). A non-blocking socket fails with EAGAIN at once, and the receive timeout ends the wait with EAGAIN; when the address comes first, the call waits for a datagram only for what is left of the timeout. A sceNetShutdown of the receive side ends the wait and the receive returns 0, and a zero-length receive returns 0 without waiting, as soreceive_dgram does when the socket can't receive more or nothing was asked for. An abort or close ends the wait, and the host receive then fails as it did before

  • sceNetResolverAbort and sceNetResolverStartNtoaMultipleRecords (libSceNet) follow shadPS4 (net.cpp, net_resolver.cpp); the (int rid, int flags) signature of the abort also matches SharpProspero. Unverified on hardware. Lookups run synchronously over the host resolver, which cannot be interrupted: an abort while a lookup runs on another thread returns at once, and that lookup fails with EINTR without writing its output only when the host call returns; the abort flags are then ignored, as shadPS4 does for a running lookup. With nothing running, abort flag 1 (NTOA preservation) or 2 (ATON preservation) makes the next sceNetResolverStartNtoa* or sceNetResolverStartAton call on that resolver fail with EINTR, reported by sceNetResolverGetError, after its arguments are checked. Unlike shadPS4, which ignores them, other abort flag bits throw, and sceNetResolverStartNtoaMultipleRecords throws for any flag, including async (1) and 0x10000 (IP address literals disabled), as sceNetResolverStartNtoaMultipleRecordsEx does

  • sceNetResolverStartNtoa6 (libSceNet) resolves a host name to its first IPv6 address through the host resolver (getaddrinfo with AF_INET6) and writes the 16-byte address; the (rid, hostname, addr, timeout, retry, flags) signature follows sceNetResolverStartNtoa. A name with no IPv6 address fails with RESOLVER_ENODNS (0x804101E1) like a failed lookup; whether the console returns IPv4-mapped addresses instead is not verified. Timeout and retry are ignored as in sceNetResolverStartNtoa, and any nonzero flags throw because their meaning for this call is not known. Unverified on hardware.

  • sceNetInetPton (libSceNet) ends an IPv4 address at the first space, tab, LF, VT, FF or CR and ignores the rest ("1.2.3.4 x" converts), leaves the destination and sceNetErrnoLoc unchanged when a conversion fails, as PS4 firmware 10.71 does; not yet confirmed on PS5. Leading whitespace, any other trailing byte (0x01, 0xa0) and IPv6 text with whitespace fail.