Skip to content

feat(libSceNet): support SO_DONTROUTE in sceNetSetsockopt and sceNetGetsockopt - #12918

Open
Kikoarl wants to merge 1 commit into
boykopovar:mainfrom
Kikoarl:feat/libSceNet-so-dontroute
Open

Kikoarl wants to merge 1 commit into
boykopovar:mainfrom
Kikoarl:feat/libSceNet-so-dontroute

Conversation

@Kikoarl

@Kikoarl Kikoarl commented Oct 29, 2026

Copy link
Copy Markdown
Contributor

What

Support NET_SO_DONTROUTE (0x10) in sceNetSetsockopt and sceNetGetsockopt (libSceNet).

FreeBSD 11.4 defines SO_DONTROUTE = 0x10, which bypasses normal routing tables and sends packets directly to the network interface. Kernel sockets already map GuestDontRoute to SO_DONTROUTE in core/libs/prx/libkernel/Socket/src/SocketOptions.cpp:123, but libSceNet previously lacked NET_SO_DONTROUTE = 0x10 and rejected both sceNetSetsockopt and sceNetGetsockopt with NET_EOPNOTSUPP.

This change:

  • Defines NET_SO_DONTROUTE = 0x10 in core/libs/prx/libSceNet/Export.cpp.
  • Adds NET_SO_DONTROUTE to sceNetSetsockopt mapping to SOL_SOCKET / SO_DONTROUTE.
  • Adds NET_SO_DONTROUTE to sceNetGetsockopt readback, returning 0x10 when enabled and 0 when disabled, matching FreeBSD 11.4 sogetopt flag bit behavior.
  • Extends GuestNetBooleanReadback.cpp to verify setsockopt and getsockopt for option 16 (NET_SO_DONTROUTE) across stream/dgram and IPv4/IPv6 sockets with variable buffer lengths and truncated readback.
  • Updates docs/dev/debt/libSceNet.md to reflect SO_DONTROUTE in the boolean readback entry.

Tested

  • Unit tests: Added option 16 to core/libs/tests/GuestNetBooleanReadback.cpp.
  • Executed ctest -R guest_net_boolean_readback and all 12 guest_net test suites in /tmp/anyps5_build: 100% passed (0 failures).
  • Verified python3 tools/check_conventions.py: 0 errors.

Checklist

  • Tested on local hardware
  • Code conventions verified via python3 tools/check_conventions.py
  • AI-assisted: yes
  • Depends on: none

@oneandonlydean oneandonlydean self-assigned this Oct 29, 2026
@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.

Pull request Conflicting files (lines on main) Same exports Same new files
PR 11272 core/libs/prx/libSceNet/Export.cpp L1736

Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.

Pull request Shared files not compared
PR 5836 core/libs/prx/libSceNet/Export.cpp
docs/dev/debt/libSceNet.md
PR 9948 core/libs/prx/libSceNet/Export.cpp
docs/dev/debt/libSceNet.md
PR 12104 docs/dev/debt/libSceNet.md
PR 12683 core/libs/prx/libSceNet/Export.cpp
docs/dev/debt/libSceNet.md
PR 13486 core/libs/prx/libSceNet/Export.cpp
docs/dev/debt/libSceNet.md
PR 14212 docs/dev/debt/libSceNet.md
PR 14213 core/libs/prx/libSceNet/Export.cpp
docs/dev/debt/libSceNet.md

@JJenkx

JJenkx commented Oct 29, 2026

Copy link
Copy Markdown
Contributor

Windows run of this head (9cf7eb8c98), merged onto main bb04a4f1ea (clean merge, local only). Windows 11 Enterprise 10.0.22621, Ryzen 9 5950X, WinLibs GCC 15.2.0 UCRT r7, Ninja, Release, BUILD_TESTING=ON, no Vulkan driver visible.

  • This PR: guest_net_boolean_readback passes 3 of 3 (ctest --repeat until-fail:3).
  • Negative control: with this PR's source files (core/libs/prx/libSceNet/Export.cpp) put back to main's version and its tests kept, guest_net_boolean_readback fails.

AI-assisted: yes (Claude Code).

@rooklz rooklz left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving. I checked this head (9cf7eb8c98) host-side on macOS arm64. Nothing here is a console measurement.

Merge / conventions

  • git merge-tree onto main bb04a4f1ea: clean. git diff --check: clean. tools/check_conventions.py --base upstream/main: all checks passed.
  • Merge order with #11272 (Queuse, same file): stacking this PR on #11272 gives one textual conflict, the *optlen < sizeof(int) guard in sceNetGetsockopt. #11272 adds an empty line after it, and this PR adds NET_SO_DONTROUTE to it. Whichever lands second needs a one-line rebase. There is no semantic overlap.

Reference behaviour

  • FreeBSD 11.4 sys/kern/uipc_socket.c lists SO_DONTROUTE with the so_options flag cases in sosetopt (L2556) and sogetopt (L2797), and reads back so->so_options & sopt->sopt_name (L2808). So the bit-valued readback (0x10 / 0) and the truncated copy-out match the existing REUSEADDR/BROADCAST path.
  • libkernel's SocketOptions.cpp already maps GuestDontRoute = 0x10 to host SO_DONTROUTE, so libSceNet now agrees with it.

Host primitive (macOS 15, arm64): I ran set/get of SO_DONTROUTE for AF_INET/AF_INET6 × STREAM/DGRAM with settings {1,-1,0,4,0}. All 20 setsockopt calls returned 0, and getsockopt returned 0x10 for non-zero settings and 0 for zero. With the flag set, a UDP sendto to an off-link address (8.8.8.8) fails with ENETUNREACH (51). A send to 127.0.0.1 succeeds. This matches FreeBSD 11.4 udp_output (SO_DONTROUTE → IP_ROUTETOIF, L1422) and ip_output's IP_ROUTETOIF branch returning ENETUNREACH when no interface is on-link.

Mutation harness. I copied the changed set and get branches verbatim into a standalone file. They run against real sockets, and the PR's test loop is reproduced for options 4/16/32. Head: GREEN at -O2, and GREEN under ASan+UBSan.

mutant result
drop NET_SO_DONTROUTE from the setsockopt option list RED
setsockopt map 0x10 → falls through to SO_RCVBUF RED
drop NET_SO_DONTROUTE from the short-optlen exemption RED
drop case NET_SO_DONTROUTE: in getsockopt RED
getsockopt map 0x10 → SO_BROADCAST RED

The test covers every changed line.

Optional, non-blocking: the debt line could say what the flag does on each host. Microsoft's SOL_SOCKET options table says Winsock "silently ignore[s] this option and always consult[s] the routing table". So on Windows the flag only round-trips through get and set. On POSIX hosts, an off-link send fails with ENETUNREACH, as on FreeBSD. That gap is worth one sentence in docs/dev/debt/libSceNet.md. JJenkx's Windows run shows the readback round-trips there.

AI-assisted: yes

@Kikoarl
Kikoarl force-pushed the feat/libSceNet-so-dontroute branch from 9cf7eb8 to 9172f99 Compare November 2, 2026 20:34
@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Nov 2, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants