Skip to content

Feat: Epoll P2P Implementation#4211

Open
Gursukh wants to merge 16 commits into
shadps4-emu:mainfrom
Gursukh:RoughP2PEpollImpl
Open

Feat: Epoll P2P Implementation#4211
Gursukh wants to merge 16 commits into
shadps4-emu:mainfrom
Gursukh:RoughP2PEpollImpl

Conversation

@Gursukh

@Gursukh Gursukh commented Apr 2, 2026

Copy link
Copy Markdown

core/net: back P2P sockets with real host sockets and unify epoll handling

Move P2P socket behavior onto actual UDP/TCP file descriptors instead of stubbed flow.
P2P sockets now own a real native socket, expose it through Native(), track socket type/non-blocking state/vport, and close cleanly on teardown.

Rewrite P2P operations to delegate to the OS:

bind/connect with address conversion and vport tracking
send/recv paths via sendto/sendmsg and recvfrom/recvmsg
socket option get/set through converted levels, including PS4-specific handling
accept returns a wrapped real accepted fd
getsockname/getpeername now return real endpoint data
Also clean up shared networking internals by promoting common helper conversions, removing duplicate Unix-side helpers/macros, and dropping the old epoll eventfd drain path.
With Native() now returning real fds for P2P sockets, epoll handling is unified across socket types.

Fyi, didnt test on windows only linux. This was targeted for LBP

@Gursukh

Gursukh commented Apr 4, 2026

Copy link
Copy Markdown
Author
  • Introduce NativeSocket between Socket and PosixSocket/UnixSocket to eliminate identical Close/Listen/fstat/IsValid/Native implementations
  • Reduce P2PSocket from ~300 lines to ~80, inheriting everything else
  • Fix msghdr reinterpret_cast corruption on 64-bit Linux (OrbisNetMsghdr uses int-sized fields vs native size_t) in both PosixSocket and UnixSocket via ConvertOrbisToNativeMsghdr helper
  • Implement sceNetEpollAbort using eventfd on Linux + atomic flag
  • Add P2P dgram epoll event filtering (EPOLLIN-only, matching PS4 kernel behavior discovered from decompilation)
  • Fix SO_LINGER rejecting P2P stream sockets
  • Fix NativeSocket::Close not invalidating the fd after close
  • Use unique_ptr in EpollTable to avoid move-constructor issues with std::atomic members

@Gursukh

Gursukh commented Apr 4, 2026

Copy link
Copy Markdown
Author
  • Add if (i >= maxevents) break guard in EpollWait event loop
  • Windows: loopback UDP socket bound to 127.0.0.1, self-connected, registered in wepoll with sentinel data.fd = -1
  • macOS/BSD: self-pipe via pipe() + O_NONBLOCK, read end registered in epoll with sentinel data.fd = -1
  • Add (void) casts on write/read return values in Abort/ClearAbort
  • Drain loops in ClearAbort for pipe/socket (handles multiple aborts)
  • Rename epoll_events_mod to epoll_events for consistency with ADD path
  • Restore libepoll-shim TODO comment for FreeBSD

@Randomuser8219

Copy link
Copy Markdown
Contributor

Windows build fails with:

FAILED: [code=1] CMakeFiles/shadps4.dir/src/core/libraries/network/net_epoll.cpp.obj 
ccache C:\PROGRA~1\LLVM\bin\clang-cl.exe  /nologo -TP -DAL_LIBTYPE_STATIC -DBOOST_ASIO_STANDALONE -DENABLE_DISCORD_RPC -DHWINFO_EXPORTS -DIMGUI_USER_CONFIG=\"imgui/imgui_config.h\" -DMINIZ_STATIC_DEFINE -DNOMINMAX -DNTDDI_VERSION=0x0A000006 -DPUGIXML_NO_EXCEPTIONS -DTRACY_NO_CALLSTACK -DTRACY_NO_CODE_TRANSFER -DTRACY_NO_CONTEXT_SWITCH -DTRACY_NO_CRASH_HANDLER -DTRACY_NO_FRAME_IMAGE -DTRACY_NO_SAMPLING -DTRACY_NO_SYSTEM_TRACING -DTRACY_ONLY_LOCALHOST -DTRACY_ON_DEMAND -DWIN32_LEAN_AND_MEAN -DWINVER=0x0A00 -DZYCORE_STATIC_BUILD -DZYDIS_STATIC_BUILD -D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS -D_SCL_SECURE_NO_WARNINGS -D_TIMESPEC_DEFINED -D_WIN32_WINNT=0x0A00 -ID:\a\shadPS4\shadPS4\src -ID:\a\shadPS4\shadPS4 -ID:\a\shadPS4\shadPS4\build\src\video_core\host_shaders\include -ID:\a\shadPS4\shadPS4\build\src\imgui\renderer\generated_fonts -ID:\a\shadPS4\shadPS4\build\_cmrc\include -imsvcD:\a\shadPS4\shadPS4\externals\magic_enum\include -imsvcD:\a\shadPS4\shadPS4\externals\fmt\include -imsvcD:\a\shadPS4\sha
In file included from D:\a\shadPS4\shadPS4\src\core\libraries\network\net_epoll.cpp:8:
D:\a\shadPS4\shadPS4\src\core\libraries\network\net_epoll.h(40,25): error: use of undeclared identifier 'INVALID_SOCKET'
   40 |     SOCKET abort_sock = INVALID_SOCKET; // loopback UDP socket for abort wake
      |                         ^
1 error generated.

@StevenMiller123

Copy link
Copy Markdown
Collaborator

Seems to break Skullgirls. Just crashes silently after it starts it's P2P stuff.
CUSA01606.log

@Gursukh

Gursukh commented Apr 4, 2026

Copy link
Copy Markdown
Author

Seems to break Skullgirls. Just crashes silently after it starts it's P2P stuff. CUSA01606.log

Ran on Windows and get the silent crash pretty much every launch sometimes immediately sometimes after a minute.
This behaviour also exists the 0.15.0 release and current main branch, I don't believe my changes are responsible.

See attached log for same crash on main branch with old (stubbed) epoll P2P implementation.
CUSA01606.log

Both crashes in and not in my branch seem to be a failed assert in libusb/core.c:1278

@StevenMiller123

Copy link
Copy Markdown
Collaborator

Seemed to be crashing quicker than usual for me on this PR, which is why I pointed it out.
Ran it under a debugger and it just seems to be the libusb issues though, so disregard my comment.

@mikusp

mikusp commented Apr 20, 2026

Copy link
Copy Markdown
Collaborator

Thank you for your contribution @Gursukh. While it seems to work with LBP3, the core principle of P2P sockets is different on the real hardware, and it won't work for multiplayer communication.

The key differences are:

  • AFAIK only SOCK_DGRAM can be used as the P2P socket as those need to be able to communicate over the internet and go through NATs
  • STREAM_P2P is implemented as a user-level TCP layer over DGRAM_P2P
  • communication over P2P sockets always uses a header with the vport embedded, so simply redirecting send/recv to OS functions is incorrect

There may be more differences, but I haven't looked into networking for some time now. RPCS3 contains a working implementation of P2P and it seems like it's almost the same as with PS4, so you can take a look at https://github.com/RPCS3/rpcs3/tree/master/rpcs3/Emu/Cell/lv2/sys_net If you have any questions feel free to ask here

@Gursukh

Gursukh commented Apr 21, 2026

Copy link
Copy Markdown
Author

Hey @mikusp, thanks for the feedback. I'll work on revising the approach. Can you recommend a game that would work well to test P2P connections?

@Hog185

Hog185 commented May 11, 2026

Copy link
Copy Markdown
Contributor

the last of us remastered has p2p for its factions mode, im aware of some weird graphical errors in the game but you can get in game on nightly

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants