Commit Graph
96 Commits
Author SHA1 Message Date
Adrià ac0427f612 Merge pull request #5928 from Kurenaiiiii/feat/libSceNet-show
feat(libSceNet): return success from ShowIfconfig and ShowNetstat
2026-10-16 22:30:58 +02:00
Kurenaiiiii f00b2ef833 feat(libSceNet): return success from ShowIfconfig and ShowNetstat 2026-10-16 20:51:06 +02:00
RickandClaude Opus 5.5 831c583003 fix(libkernel): refuse a closed loopback TCP port at once on Windows
Windows answers a SYN to a closed port with a RST and then retransmits
the SYN, so connect to a closed loopback port takes about 2 s before
ECONNREFUSED; FreeBSD fails at once. PS5VR (PPSA99177) makes about 33
such connects to 127.0.0.1:17600 and reaches its home screen 45 s late.

When no socket listens on the destination port (GetExtendedTcpTable),
a loopback connect now sets SIO_TCP_INITIAL_RTO with no SYN
retransmissions and fails at once. A port with a listener keeps the
retransmissions: Windows also answers a SYN to a full accept backlog
with a RST, and the retransmission connects once the server accepts,
as the console's does after FreeBSD drops the SYN.

guest_refused_connect requires ECONNREFUSED in under a second for a
closed port through libkernel connect and sceNetConnect, and a second
connect to a listener with backlog 1 to succeed once the server accepts
the first, through both.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-15 17:04:20 +02:00
Adrià eea428ca85 Merge pull request #5536 from milescoviello/fix/scenet-getsockopt-buffers
fix(libSceNet): report SO_SNDBUF and SO_RCVBUF from sceNetGetsockopt
2026-10-15 00:29:08 +02:00
Nicolas FalesyandClaude Opus 5.5 62d8eeae76 fix(libkernel): poll libSceNet sockets with the host wait
With libSceNet sockets on ordinary descriptor numbers (#4391), poll on a
libSceNet socket threw "neither a socket nor a pipe": poll only knew
libkernel sockets and pipes, while select already asks libSceNet through
its poller. libSceNet now lends libkernel the host socket behind a
descriptor, together with an owner that keeps it open, so poll puts it in
the same WSAPoll or poll call as libkernel sockets. ProsperoLight
(PPSA99002) stopped here on Linux and now reaches its PC list.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EvDbpwUPTa78oCAJqe7m9K
2026-10-14 19:56:10 +02:00
Nicolas FalesyandClaude Opus 5.5 5dcf28d36c fix(libkernel): answer fcntl status flags on libSceNet sockets
With libSceNet sockets on ordinary descriptor numbers (#4391), a title
that makes a libSceNet socket non-blocking with plain fcntl(F_GETFL) and
fcntl(F_SETFL, O_NONBLOCK) reached File::Fcntl, whose classification
throws for a socket. libSceNet now registers a status control with
libkernel, like its option setter: F_GETFL returns O_RDWR with the
socket's non-blocking flag, F_SETFL sets it through SO_NBIO, as fcntl
already does for libkernel sockets. ProsperoLight (PPSA99002) stopped
here on Linux.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017WeVmjnnPPKdxVTpr2Vjtw
2026-10-14 19:19:54 +02:00
Dean 9858d27be7 Merge pull request #4673 from milescoviello/fix/scenet-msg-dontwait
fix(libSceNet): accept MSG_DONTWAIT in the send and receive calls
2026-10-14 19:06:13 +13:00
Dean f5424b4db3 Merge pull request #4785 from krishalivaibhav/codex/netstat-with-memory
feat(net): implement memory-pool netstat diagnostic
2026-10-14 18:09:01 +13:00
Adrià FranchandClaude fce953802a fix(libSceNet): fail the AF_UNSPEC connect with EAFNOSUPPORT as FreeBSD does
Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-14 02:58:42 +00:00
milescovielloandClaude Opus 5.5 65d56b3147 fix(libSceNet): dissolve a datagram association on connect to AF_UNSPEC
sceNetConnect() on a connected datagram socket rejected an address
whose family is AF_UNSPEC (a null address) with EINVAL before touching
the socket, so the socket stayed connected: sceNetGetpeername() still
reported the old peer and datagrams from any other sender were dropped
by the host.

FreeBSD 11.4 disconnects a connected datagram socket first and only then
looks at the address. sys/kern/uipc_socket.c, soconnectat():

	 * If protocol is connection-based, can only connect once.
	 * Otherwise, if connected, try to disconnect first.  This allows
	 * user to disconnect by connecting to, e.g., a null address.
	 */
	if (so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING) &&
	    ((so->so_proto->pr_flags & PR_CONNREQUIRED) ||
	    (error = sodisconnect(so)))) {

udp_disconnect() (sys/netinet/udp_usrreq.c) clears the peer and keeps
the local port. connect(2): "Datagram sockets may dissolve the
association by connecting to an invalid address, such as a null
address." libkernel's connect gets the same change in #4498.

A connected datagram socket given an address whose family byte is 0 is
now disconnected on the host first (AF_UNSPEC on Linux, a zeroed
address of the socket's family on Windows), and the call then fails
with EINVAL as before. Linux also drops an ephemeral local port on that
disconnect, so the port is bound again on the wildcard address, which
is what FreeBSD leaves. A host failure during the disconnect is
returned as the call's error. Stream sockets keep the previous path.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 02:58:42 +00:00
milescovielloandClaude Opus 5.5 2c25b181fe fix(libSceNet): report SO_SNDBUF and SO_RCVBUF from sceNetGetsockopt
Steam Remote Play (PPSA99350) reads SO_RCVBUF on its UDP socket with
sceNetGetsockopt, and main fails it with EOPNOTSUPP (0x8041012d),
although sceNetSetsockopt already accepts the option.

FreeBSD 11.4 answers both options with the buffer's high-water mark
(sys/kern/uipc_socket.c, sogetopt), which setsockopt sets to the
requested size through sbreserve:

	case SO_SNDBUF:
		optval = so->so_snd.sb_hiwat;
		goto integer;

	case SO_RCVBUF:
		optval = so->so_rcv.sb_hiwat;
		goto integer;

sceNetGetsockopt now answers both. A size the guest set is reported as
set, as on FreeBSD; reading the host would give twice the value on
Linux, which doubles it. Before the guest sets one, the host socket's
current size is reported.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 02:55:25 +00:00
Dean 0fb2f6c89a Merge pull request #4988 from babyhuey/feat/scenet-so-error
fix(libSceNet): report SO_ERROR from sceNetGetsockopt
2026-10-14 15:53:49 +13:00
ps54allandClaude Opus 5.5 df32a44f79 feat(libSceNet): implement sceNetResolverStartNtoa6
Resolve a host name to its first IPv6 address through the host resolver
(getaddrinfo with AF_INET6) and write the 16-byte address. The lookup
shares the IPv4 path's resolver bookkeeping (abort preservation, error
state); a name without an IPv6 address fails with RESOLVER_ENODNS like a
failed lookup. Nonzero flags throw.

Metal Gear Solid 4 Master Collection (PPSA18194) imports it and failed to
load without it (unresolved zl35YNs9jnI from libSceNet.prx).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 21:13:34 +02:00
Adrià 9d0a41d5a1 Merge pull request #4611 from EagleBearerYS/fix/libscenet-epoll-out
fix(libSceNet): sceNetEpollWait takes 2 as the OUT event
2026-10-13 17:51:30 +02:00
Adrià 765661581b Merge pull request #4613 from EagleBearerYS/fix/libscenet-copied-address-length
fix(libSceNet): report copied socket address lengths
2026-10-13 17:30:34 +02:00
Adrià c35bc4b92c Merge pull request #4612 from EagleBearerYS/fix/libscenet-epoll-ident
fix(libSceNet): report the registered socket as the epoll event ident
2026-10-13 17:30:05 +02:00
Adrià 2f6ae9fc88 Merge pull request #4610 from EagleBearerYS/fix/libscenet-sce-socket-timeouts
fix(libSceNet): take 0x1105 and 0x1106 as the send and receive timeouts
2026-10-13 17:28:11 +02:00
Adrià cba01c87d1 Merge pull request #4614 from EagleBearerYS/fix/libscenet-getsockname-unbound-windows
fix(libSceNet): name an unbound socket with the zero address on Windows
2026-10-13 17:11:20 +02:00
Yunus Shaikh 60fb528572 refactor(libSceNet): place the SCE timeout constants and timeout_option apart from new neighbours
#4988 adds a constant after NET_SO_RCVTIMEO and #4989 adds a function before receive_error, so defining the SCE timeout constants and timeout_option there made the pull requests conflict.
2026-10-13 00:34:06 -07:00
babyhuey 0daf1d5ba3 fix(libSceNet): report SO_ERROR from sceNetGetsockopt 2026-10-13 03:15:45 -04:00
screamm e99816e8f3 fix(libkernel): give guest sockets ordinary descriptor numbers below FD_SETSIZE
libkernel numbered guest sockets from GuestSockets::FirstDescriptor
(0x10000000), so a title that puts a socket in a 1024-bit fd_set writes
fd / 8 bytes past it. The Epic Online Services SDK does this on its
RtcNetworkThread and three titles stop there (#1794):

Palworld PPSA23126 (queeeef, main a11c8f7f7):
  FATAL: unhandled exception 0xc0000005 on thread 37164 'RtcNetworkThread'
    rip 0x00007ffcdb1ea2be eossdk-ps5-shipping.prx.guest.prx+0xdea2be
    rcx 0000000010000005 rsi 0000000000400000 r12 0000000010000005
The Mound PPSA26223 (xXPBSXx, main 0a8b1d32b):
  FATAL: unhandled exception 0xc0000005 on thread 'RtcNetworkThread',
  rip eossdk-ps5-shipping.prx.guest.prx+0xefc6f4, rcx = 0x10000005,
  rsi = 0x400000
Dying Light 2 PPSA02262 (tv7):
  FATAL: unhandled exception 0xc0000005 on thread 'RtcNetworkThread'
    rcx 0000000010000005 ... rsi 0000000000400000 ... r12 0000000010000005

On FreeBSD 11.4 (8c639945) FD_SETSIZE is 1024 (sys/sys/select.h:58-59)
and sockets take the lowest free entry of the one process descriptor
table that files use (kern_descrip.c:1643-1660 fdalloc,
uipc_syscalls.c kern_socket through falloc).

Every socket number is now a real host descriptor: a zero-access NUL
handle registered with _open_osfhandle on Windows (as directory
descriptors already are) and an F_DUPFD_CLOEXEC duplicate of the host
socket on Linux. The socket table maps that number to the socket, so
"is this a socket" is a table lookup instead of a range check at the 31
former FirstDescriptor comparisons. close releases both the socket entry
and the number, dup and dup2 duplicate the number through the host table
and keep the socket shared, dup2 of a file onto a socket number drops the
socket entry, and sceKernelClose now closes sockets too. sceNetSocket and
sceNetAccept take their ids from the same table instead of a counter from
32, so libkernel and libSceNet numbers never collide.

select polls guest sockets alongside libSceNet sockets, the random device,
stdio and (on Linux) host descriptors; poll throws only for an open
descriptor that is not a guest socket and reports POLLNVAL otherwise.
File calls that used to fail with EBADF on the socket range return
FreeBSD's answer for a socket: lseek ESPIPE (kern_lseek), ftruncate and
getdirentries EINVAL (invfo_truncate, getvnode), flock EOPNOTSUPP;
fstat on a socket throws. pread on a closed descriptor returns EBADF.

title failing on host descriptor numbers; these three titles are that
case, and this change keeps host numbering for files and only moves
sockets into it.

Tests: guest_socket_descriptors (new: socket below 1024, select on a
socket and a file together, close frees the number for a file, dup of a
socket, sceKernelClose), guest_select (socket and pipe together, Linux),
guest_poll, guest_dup, guest_socket_pair, guest_fstatfs,
guest_posix_filesystem and guest_sce_net updated.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
(cherry picked from commit 20378375b31eb5db922db6e55f45e44a4dae6445)
2026-10-13 03:22:36 +00:00
krishalivaibhav 565fafa85d feat(net): implement memory-pool netstat diagnostic 2026-10-13 03:19:27 +05:30
milescovielloandClaude Opus 5.5 44d46ee97c fix(libSceNet): accept MSG_DONTWAIT in the send and receive calls
sceNetSend, sceNetSendto, sceNetRecv, sceNetRecvfrom, sceNetRecvmsg and
sceNetSendmsg failed with EOPNOTSUPP for any flag other than MSG_PEEK on
a receive, so a game polling a socket with MSG_DONTWAIT got an error on
every call instead of its data or EWOULDBLOCK.

FreeBSD 11.4 defines the flag in sys/sys/socket.h:

	#define	MSG_DONTWAIT	0x80		/* this message should be nonblocking */

and soreceive_generic() (sys/kern/uipc_socket.c) treats it like a
non-blocking socket for that one call:

		if ((so->so_state & SS_NBIO) ||
		    (flags & (MSG_DONTWAIT|MSG_NBIO))) {
			SOCKBUF_UNLOCK(&so->so_rcv);
			error = EWOULDBLOCK;
			goto release;

shadPS4's sceNet uses the same value (ORBIS_NET_MSG_DONTWAIT 0x80).

On Linux and macOS the flag now maps to the host's MSG_DONTWAIT, alone
or with MSG_PEEK on a receive. Winsock has no per-call non-blocking
flag, so Windows keeps failing with EOPNOTSUPP for it; TechnicalDebt
records that. Other flags still fail with EOPNOTSUPP.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 20:18:47 +00:00
David 3d64981643 feat(libSceNet): implement sceNetResolverAbort and sceNetResolverStartNtoaMultipleRecords
UFC 6 (PPSA23566) imports sceNetResolverAbort (#992, #1502); Palworld
(PPSA23126) and LEGO Horizon Adventures (PPSA14632) import
sceNetResolverStartNtoaMultipleRecords.

Signatures and behaviour follow shadPS4 811bfcd7d17e
(src/core/libraries/net/net.cpp, net_resolver.cpp); the abort signature
also matches SharpProspero Interop/Net/Socket.cs.

sceNetResolverStartNtoaMultipleRecords shares the lookup of the Ex form
and, like it, throws for any flag. sceNetResolverAbort returns EBADF for
an unknown resolver and throws for flag bits other than NTOA (1) and
ATON (2) preservation. Host lookups cannot be interrupted, so an abort
during a running lookup makes it fail with EINTR when the host call
returns, without writing its output; with nothing running, the
preservation flags make the next lookup of that kind fail with EINTR.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
(cherry picked from commit bcc8be8a58aa6a9e6b7c288d8a90af6ed63837aa)
2026-10-12 22:03:56 +02:00
Yunus Shaikh 78d594d9f6 Merge remote-tracking branch 'origin/main' into fix/libscenet-epoll-out 2026-10-12 11:56:48 -07:00
Yunus Shaikh ac8106bda2 refactor(libSceNet): define timeout_option before receive_error
#4673 adds a function after receive_error, so defining timeout_option there made the two pull requests conflict.
2026-10-12 11:52:49 -07:00
Dean 83e6be8a69 Merge pull request #4394 from AaravMehta-07/codex/sce-net-stream-sender
fix(libSceNet): preserve successful stream recvfrom results
2026-10-13 07:23:13 +13:00
Dean 3377986a60 Merge pull request #4371 from milescoviello/fix/net-socket-timeval-timeouts
fix(libSceNet): read setsockopt timeouts as struct timeval
2026-10-13 07:21:55 +13:00
Dean edddd6a17b Merge pull request #4370 from milescoviello/fix/ipv6-only-sockets
fix(net): make new IPv6 sockets IPv6-only as FreeBSD does
2026-10-13 07:21:34 +13:00
Yunus Shaikh 4f78bd534f fix(libSceNet): report copied socket address lengths
sceNetAccept, sceNetGetsockname, sceNetGetpeername, sceNetRecvfrom and
sceNetRecvmsg stored the full address length (16 or 28) even when the
caller's buffer was shorter and only part of the address was copied.
FreeBSD 11.4 stores the copied length, the smaller of the two
(kern_accept4, kern_recvit, kern_getsockname and kern_getpeername in
sys/kern/uipc_syscalls.c), as libkernel's socket calls do since #4295.
2026-10-12 09:00:04 -07:00
Yunus Shaikh feffc67acb fix(libSceNet): name an unbound socket with the zero address on Windows
sceNetGetsockname on a socket that is neither bound nor connected failed
with EINVAL on Windows, where Winsock reports WSAEINVAL. FreeBSD 11.4
returns the wildcard address with port 0 (in_getsockaddr and
in6_getsockaddr in sys/netinet/in_pcb.c and sys/netinet6/in6_pcb.c), and
Linux already does, so the call now builds that address for the socket's
family.
2026-10-12 09:00:04 -07:00
Yunus Shaikh 53cbdebe82 fix(libSceNet): report the registered socket as the epoll event ident
sceNetEpollWait copied the whole event a title passed to
sceNetEpollControl, so the ident and reserved fields came back as the
title had left them. The ident of a returned event is the id that was
registered and reserved is 0 (shadPS4 net.cpp sceNetEpollWaitImpl,
KytyPS5 network.cpp EpollWait); a title that registers a socket without
filling ident and looks the socket up by it now finds it.
2026-10-12 09:00:03 -07:00
Yunus Shaikh b19a74f5bf fix(libSceNet): sceNetEpollWait takes 2 as the OUT event
sceNetEpollWait used Linux's EPOLLOUT bit (4) for writability. The SCE
value is 2 (shadPS4 net_types.h ORBIS_NET_EPOLLOUT, KytyPS5 network.cpp
EPOLL_OUT, SharpProspero Socket.cs EpollOut); IN (1), ERR (8) and HUP
(0x10) already match. A socket registered for OUT was never polled for
writability, so the wait ran out its timeout or blocked forever, and an
IN|OUT registration never reported OUT.
2026-10-12 09:00:02 -07:00
Yunus Shaikh febc36223b fix(libSceNet): take 0x1105 and 0x1106 as the send and receive timeouts
sceNetSetsockopt and sceNetGetsockopt answered EOPNOTSUPP for 0x1105 and
0x1106, the SCE send and receive timeouts in microseconds (shadPS4
net_types.h ORBIS_NET_SO_SNDTIMEO/RCVTIMEO, SharpProspero Socket.cs
SoSndTimeo/SoRcvTimeo, KytyPS5 network.cpp). A title that set a receive
timeout this way then blocked in sceNetRecv for good. Both options now
set and read the timeouts that 0x1005 and 0x1006 already do.
2026-10-12 09:00:02 -07:00
Dean a951cef8f4 Merge pull request #4272 from Ondra97/codex/socket-receive-host-write
fix(libs): allow socket receives into watched guest memory
2026-10-13 01:22:17 +13:00
milescovielloandClaude Opus 5.5 98f6639e9e fix(net): make new IPv6 sockets IPv6-only as FreeBSD does
On Linux, socket() and sceNetSocket() create AF_INET6 sockets in the
host's default dual-stack mode (net.ipv6.bindv6only is 0), so a wildcard
IPv6 bind also claims the IPv4 port. A title that keeps an IPv4 and an
IPv6 socket on the same port fails: with 0.0.0.0:P bound, binding [::]:P
returns EADDRINUSE (48), and an IPv6 socket bound to [::] also receives
IPv4 traffic from v4-mapped peers.

FreeBSD makes every new IPv6 socket IPv6-only. sys/netinet6/in6_proto.c:

	VNET_DEFINE(int, ip6_v6only) = 1;

sys/netinet/in_pcb.c, in_pcballoc():

	if (INP_SOCKAF(so) == AF_INET6) {
		inp->inp_vflag |= INP_IPV6PROTO;
		if (V_ip6_v6only)
			inp->inp_flags |= IN6P_IPV6_V6ONLY;
	}

and sys/netinet6/in6_pcb.c, in6_pcbbind(), looks for an IPv4 owner of
the port only when the flag is clear:

	if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0 &&
	    IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {

socket() and sceNetSocket() now set IPV6_V6ONLY on every IPv6 socket
they create. Windows already defaults to it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 08:44:27 +00:00
Dean 49b6b6a5c8 Merge pull request #4092 from yunusshaikh7/fix/libscenet-datagram-receive-timeout
fix(libSceNet): report EAGAIN when a datagram receive times out on Windows
2026-10-12 21:39:40 +13:00
milescovielloandClaude Opus 5.5 e9c5ae26be fix(libSceNet): read setsockopt timeouts as struct timeval
libkernel's setsockopt() hands options for a libSceNet socket to
sceNetSetsockopt(), whose SO_RCVTIMEO and SO_SNDTIMEO take an int of
microseconds. The POSIX call takes a struct timeval, so main read the
low half of tv_sec as microseconds: {1, 250000} set a 1 microsecond
receive timeout, {0, 500000} set 0, which disables the timeout, and an
out-of-range tv_usec was accepted.

FreeBSD reads a struct timeval, sys/kern/uipc_socket.c, sosetopt():

	case SO_SNDTIMEO:
	case SO_RCVTIMEO:
	...
		error = sooptcopyin(sopt, &tv, sizeof tv,
		    sizeof tv);
	if (error)
		goto bad;
	if (tv.tv_sec < 0 || tv.tv_usec < 0 ||
	    tv.tv_usec >= 1000000) {
		error = EDOM;
		goto bad;
	}

and sooptcopyin() fails a shorter value with EINVAL:

	if ((valsize = sopt->sopt_valsize) < minlen)
		return EINVAL;

setsockopt() on a libSceNet socket now converts the timeval for these
two options, with EINVAL for a short value and EDOM for a negative or
out-of-range one. sceNetSetsockopt() keeps taking microseconds; both
paths share the code that sets the host timeout.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 07:58:06 +00:00
Dean 98c07d8e77 Merge pull request #4111 from jdmagic/fix/kernel-close-net-sockets
fix(libkernel): close() and setsockopt() reach libSceNet sockets
2026-10-12 20:28:00 +13:00
Dean 2c51fdfba9 Merge pull request #4112 from jdmagic/fix/net-errors-set-kernel-errno
fix(libSceNet): failures also set libkernel's errno
2026-10-12 20:25:23 +13:00
Dean 4303f39b92 Merge pull request #4110 from jdmagic/fix/net-epoll-control-ops
fix(libSceNet): sceNetEpollControl takes 2 as MOD and 3 as DEL
2026-10-12 20:25:02 +13:00
Aarav 74defef675 fix(libSceNet): preserve successful stream recvfrom results 2026-10-12 10:54:08 +05:30
Ondra97 8f33897275 fix(libs): allow socket receives into watched guest memory 2026-10-12 05:37:35 +02:00
Dean 01e5f3b8a8 Merge pull request #3977 from hansjm10/fix/libscenet-sockaddr-len
fix(libSceNet): accept guest socket addresses whatever their sa_len
2026-10-12 16:08:32 +13:00
jdmagicandClaude Opus 5.5 d5805fb3e4 fix(libkernel): setsockopt sets options of libSceNet sockets
A title creating a socket with sceNetSocket sets its options with the BSD
setsockopt, which looked the descriptor up only among libkernel's own
sockets and returned EBADF. libSceNet now registers an option setter with
libkernel, as it does for close and select, and accepts SO_REUSEADDR,
SO_BROADCAST, SO_SNDBUF and SO_RCVBUF like libkernel's own sockets.

PPSA01289 (Sackboy: A Big Adventure) sets SO_BROADCAST on its UDP P2P
socket this way in UIpNetDriver::InitBase. The failure made every listen
fail, and the engine travelled back to its default map with ?closed,
reloading it about every two seconds behind the loading screen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 19:23:24 -04:00
jdmagicandClaude Opus 5.5 5d14cd02ff fix(libSceNet): failures also set libkernel's errno
libSceNet stored its errno only in its own slot (sceNetErrnoLoc). Titles
that use the BSD socket model read errno after a libSceNet call, as the
console's libSceNet calls are kernel calls that set it; shadPS4 mirrors its
net errno into the kernel errno the same way (SetKernelErrnoHook).

PPSA01289 (Sackboy: A Big Adventure) reads errno through Unreal's
GetLastErrorCode after sceNetRecvfrom. It never saw EWOULDBLOCK, so
UIpNetDriver::TickDispatch kept receiving and the game thread never left
its first networked frame.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 19:23:24 -04:00
jdmagicandClaude Opus 5.5 12b18af550 fix(libkernel): close() closes libSceNet sockets
A libSceNet socket is a kernel descriptor on the console, so titles close it
with close(). libSceNet keeps its sockets in its own table, and libkernel's
close passed their numbers to the CRT, which reported an invalid parameter
and left the socket open. libSceNet now registers a closer with libkernel,
as it registers its poller for select. PPSA01289 (Sackboy: A Big Adventure)
closes its P2P socket this way each time it tears its network session down,
leaking one open socket per attempt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 19:23:24 -04:00
jdmagicandClaude Opus 5.5 22827bf6ad fix(libSceNet): sceNetEpollControl takes 2 as MOD and 3 as DEL
sceNetEpollControl used Linux's EPOLL_CTL numbering (1 ADD, 2 DEL, 3 MOD).
The SCE values are 1 ADD, 2 MOD, 3 DEL (shadPS4 net_types.h,
ORBIS_NET_EPOLL_CTL_*). A title removing a socket with op 3 and a null
event got EINVAL, and op 2 deleted the registration it meant to modify.
PPSA01289 (Sackboy: A Big Adventure) removes its UDP socket from its epoll
this way before closing it, every time its network session is torn down.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 19:23:23 -04:00
Yunus Shaikh f7a85491ef fix(libSceNet): report EAGAIN when a datagram receive times out on Windows
With SO_RCVTIMEO set, Winsock fails a receive that waits that long with
WSAETIMEDOUT, which native_error turned into ETIMEDOUT (60). sceNetRecv,
sceNetRecvfrom and sceNetRecvmsg on a datagram socket therefore failed
with 0x8041013C on Windows, where FreeBSD's sbwait returns EWOULDBLOCK
(35) to soreceive, Linux returns EAGAIN, and POSIX (XSH 2.10.16)
requires EAGAIN or EWOULDBLOCK when no data was received.

A datagram socket has no connection that can time out, so WSAETIMEDOUT
there only means that the receive timeout the guest set has expired:
report EAGAIN. Stream sockets keep ETIMEDOUT, since Winsock leaves a
connection in an indeterminate state after a timeout; TechnicalDebt
records that gap and the one for SO_SNDTIMEO.
2026-10-11 16:01:51 -07:00
Adrià 0cff844842 Merge pull request #3707 from overlordxrz-source/feat/net-in6addr-linklocal-allnodes
feat(libSceNet): export sce_net_in6addr_linklocal_allnodes
2026-10-11 23:53:51 +02:00