Skip to content

sceNetInet socket remap #19827

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 19 commits into from
Jan 8, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add a central location for managing HLE sockets
  • Loading branch information
hrydgard committed Jan 8, 2025
commit 2c3f7f6806f7ce6dcd91467f37884a2e7a04dff7
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2178,6 +2178,8 @@ add_library(${CoreLibName} ${CoreLinkType}
Core/HLE/AtracCtx2.h
Core/HLE/NetInetConstants.cpp
Core/HLE/NetInetConstants.h
Core/HLE/SocketManager.cpp
Core/HLE/SocketManager.h
Core/HLE/sceAtrac.cpp
Core/HLE/sceAtrac.h
Core/HLE/sceAudio.cpp
Expand Down
2 changes: 2 additions & 0 deletions Core/Core.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,7 @@
<ClCompile Include="HLE\sceUsbAcc.cpp" />
<ClCompile Include="HLE\sceUsbCam.cpp" />
<ClCompile Include="HLE\sceUsbMic.cpp" />
<ClCompile Include="HLE\SocketManager.cpp" />
<ClCompile Include="HW\Atrac3Standalone.cpp" />
<ClCompile Include="HW\BufferQueue.cpp" />
<ClCompile Include="HW\Camera.cpp" />
Expand Down Expand Up @@ -1199,6 +1200,7 @@
<ClInclude Include="HLE\sceUsbAcc.h" />
<ClInclude Include="HLE\sceUsbCam.h" />
<ClInclude Include="HLE\sceUsbMic.h" />
<ClInclude Include="HLE\SocketManager.h" />
<ClInclude Include="HW\Atrac3Standalone.h" />
<ClInclude Include="HW\Camera.h" />
<ClInclude Include="HW\Display.h" />
Expand Down
6 changes: 6 additions & 0 deletions Core/Core.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -1342,6 +1342,9 @@
<ClCompile Include="HLE\NetInetConstants.cpp">
<Filter>HLE\Libraries</Filter>
</ClCompile>
<ClCompile Include="HLE\SocketManager.cpp">
<Filter>HLE\Libraries</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="ELF\ElfReader.h">
Expand Down Expand Up @@ -2160,6 +2163,9 @@
<ClInclude Include="HLE\NetInetConstants.h">
<Filter>HLE\Libraries</Filter>
</ClInclude>
<ClInclude Include="HLE\SocketManager.h">
<Filter>HLE\Libraries</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\LICENSE.TXT" />
Expand Down
54 changes: 54 additions & 0 deletions Core/HLE/SocketManager.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#include "Core/HLE/SocketManager.h"
#include "Common/Log.h"

#include <mutex>

// We use this array from 1 and forward. It's probably not a good idea to return 0 as a socket.
InetSocket g_inetSockets[256];
static std::mutex g_socketMutex; // TODO: Remove once the adhoc thread is gone

int AllocInetSocket() {
std::lock_guard<std::mutex> guard(g_socketMutex);
for (int i = MIN_VALID_INET_SOCKET; i < ARRAY_SIZE(g_inetSockets); i++) {
if (g_inetSockets[i].state == SocketState::Unused) {
return i;
}
}
_dbg_assert_(false);
ERROR_LOG(Log::sceNet, "Ran out of socket handles! This is BAD.");
return 0;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Shouldn't we returned -1 in the case of failure to create a socket? just like a posix socket syscall:

On success, a file descriptor for the new socket is returned. On
error, -1 is returned, and errno is set to indicate the error.

Copy link
Owner Author

Choose a reason for hiding this comment

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

The caller is responsible for the actual syscall return value. But yeah this will be made clearer in an upcoming commit.

(either way, haven't hit this yet)

}

bool GetInetSocket(int sock, InetSocket **inetSocket) {
std::lock_guard<std::mutex> guard(g_socketMutex);
if (sock < MIN_VALID_INET_SOCKET || sock >= ARRAY_SIZE(g_inetSockets) || g_inetSockets[sock].state == SocketState::Unused) {
*inetSocket = nullptr;
return false;
}
*inetSocket = &g_inetSockets[sock];
return true;
}

// Simplified mappers, only really useful in select/poll
SOCKET GetHostSocketFromInetSocket(int sock) {
std::lock_guard<std::mutex> guard(g_socketMutex);
if (sock < MIN_VALID_INET_SOCKET || sock >= ARRAY_SIZE(g_inetSockets) || g_inetSockets[sock].state == SocketState::Unused) {
_dbg_assert_(false);
return -1;
}
if (sock == 0) {
// Map 0 to 0, special case.
return 0;
}
return g_inetSockets[sock].sock;
}

void CloseAllSockets() {
for (auto &sock : g_inetSockets) {
if (sock.state != SocketState::Unused) {
closesocket(sock.sock);
}
sock.state = SocketState::Unused;
sock.sock = 0;
}
}
34 changes: 34 additions & 0 deletions Core/HLE/SocketManager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#pragma once

#include "Common/Net/SocketCompat.h"

// Keep track of who's using a socket.
enum class SocketState {
Unused,
UsedNetInet,
UsedProAdhoc,
};

// Internal socket state tracking
struct InetSocket {
Copy link
Collaborator

@anr2me anr2me Jan 8, 2025

Choose a reason for hiding this comment

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

We should store non-blocking state here too, and probably some other value that can be set using SetSockOpt too just like non-blocking state, but non-blocking state alone should be sufficient (at least for TCP/UDP socket, while PDP/PTP sockets might need some additional info to be stored, you can checked the AdhocSocket struct for this), since we will need to retrieve the non-blocking state in order to simulate blocking mode later.

PS: Sockets are in blocking mode by default after creation, thus the default value should be nonblocking = false.

Copy link
Collaborator

@anr2me anr2me Jan 8, 2025

Choose a reason for hiding this comment

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

Also, since we have stored the socket protocol here, we can replace these code at sceNetInet.cpp by forwarding only TCP or UDP instead of forwarding both protocol:

// Enable Port-forwarding
	// TODO: Check the socket type/protocol for SOCK_STREAM/SOCK_DGRAM or IPPROTO_TCP/IPPROTO_UDP instead of forwarding both protocol
	// InetSocket* sock = pspSockets.Get<InetSocket>(socket, error);
	// UPnP_Add((sock->type == SOCK_STREAM)? IP_PROTOCOL_TCP: IP_PROTOCOL_UDP, port, port);	
	unsigned short port = ntohs(saddr.in.sin_port);
	UPnP_Add(IP_PROTOCOL_UDP, port, port);
	UPnP_Add(IP_PROTOCOL_TCP, port, port);

I opened both TCP and UDP because i use the native socket directly and there is noway to retrieve the socket protocol (at least the easy way as i remembered).

Edit: oops, you already did this >.<

SOCKET sock; // native socket
SocketState state;
// NOTE: These are the PSP types for now
int domain;
int type;
int protocol;
// These are the host types for convenience.
int hostDomain;
int hostType;
int hostProtocol;
};

#define MIN_VALID_INET_SOCKET 20
#define VALID_INET_SOCKET_COUNT 256

extern InetSocket g_inetSockets[VALID_INET_SOCKET_COUNT];

int AllocInetSocket();
bool GetInetSocket(int sock, InetSocket **inetSocket);
SOCKET GetHostSocketFromInetSocket(int sock);
void CloseAllSockets();
1 change: 0 additions & 1 deletion Core/HLE/proAdhoc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@
#include "Core/CoreTiming.h"
#include "Core/Core.h"
#include "Core/HLE/sceKernelInterrupt.h"
#include "Core/HLE/sceKernelThread.h"
#include "Core/HLE/sceKernelMemory.h"
#include "Core/HLE/sceNetAdhoc.h"
#include "Core/Instance.h"
Expand Down
55 changes: 5 additions & 50 deletions Core/HLE/sceNetInet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "Common/Serialize/SerializeFuncs.h"
#include "Common/Serialize/SerializeMap.h"

#include "Core/HLE/SocketManager.h"
#include "Core/HLE/HLE.h"
#include "Core/HLE/FunctionWrappers.h"
#include "Core/HLE/sceNet.h"
Expand All @@ -22,63 +23,17 @@
#include "Core/Util/PortManager.h"
#include "Core/Instance.h"

#define MIN_VALID_SOCKET 20

int inetLastErrno = 0; // TODO: since errno can only be read once, we should keep track the value to be used on sceNetInetGetErrno

bool netInetInited = false;

// We use this array from 1 and forward. It's probably not a good idea to return 0 as a socket.
InetSocket g_inetSockets[256];

static int AllocInetSocket() {
for (int i = MIN_VALID_SOCKET; i < ARRAY_SIZE(g_inetSockets); i++) {
if (g_inetSockets[i].state == SocketState::Unused) {
return i;
}
}
_dbg_assert_(false);
ERROR_LOG(Log::sceNet, "Ran out of socket handles! This is BAD.");
return 0;
}

static bool GetInetSocket(int sock, InetSocket **inetSocket) {
if (sock < MIN_VALID_SOCKET || sock >= ARRAY_SIZE(g_inetSockets) || g_inetSockets[sock].state == SocketState::Unused) {
*inetSocket = nullptr;
return false;
}
*inetSocket = &g_inetSockets[sock];
return true;
}

// Simplified mappers, only really useful in select/poll
static SOCKET GetHostSocketFromInetSocket(int sock) {
if (sock < MIN_VALID_SOCKET || sock >= ARRAY_SIZE(g_inetSockets) || g_inetSockets[sock].state == SocketState::Unused) {
_dbg_assert_(false);
return -1;
}
if (sock == 0) {
// Map 0 to 0, special case.
return 0;
}
return g_inetSockets[sock].sock;
}

void __NetInetShutdown() {
if (!netInetInited) {
return;
}

netInetInited = false;

for (auto &sock : g_inetSockets) {
if (sock.state != SocketState::Unused) {
closesocket(sock.sock);
}
sock.state = SocketState::Unused;
}

// TODO: Shut down any open sockets here.
CloseAllSockets();
}

static int sceNetInetInit() {
Expand Down Expand Up @@ -250,7 +205,7 @@ int sceNetInetSelect(int nfds, u32 readfdsPtr, u32 writefdsPtr, u32 exceptfdsPtr
// Save the mapping during setup.
SOCKET hostSockets[256]{};

for (int i = MIN_VALID_SOCKET; i < nfds; i++) {
for (int i = MIN_VALID_INET_SOCKET; i < nfds; i++) {
if (readfds && (NetInetFD_ISSET(i, readfds))) {
SOCKET sock = GetHostSocketFromInetSocket(i);
hostSockets[i] = sock;
Expand Down Expand Up @@ -299,7 +254,7 @@ int sceNetInetSelect(int nfds, u32 readfdsPtr, u32 writefdsPtr, u32 exceptfdsPtr
if (readfds != NULL) NetInetFD_ZERO(readfds);
if (writefds != NULL) NetInetFD_ZERO(writefds);
if (exceptfds != NULL) NetInetFD_ZERO(exceptfds);
for (int i = MIN_VALID_SOCKET; i < nfds; i++) {
for (int i = MIN_VALID_INET_SOCKET; i < nfds; i++) {
if (readfds && hostSockets[i] != 0 && FD_ISSET(hostSockets[i], &rdfds)) {
NetInetFD_SET(i, readfds);
}
Expand Down Expand Up @@ -455,7 +410,7 @@ static int sceNetInetSocket(int domain, int type, int protocol) {
return hleLogError(Log::sceNet, ERROR_NET_INTERNAL);
}
InetSocket *inetSock = &g_inetSockets[socket];
inetSock->state = SocketState::Used;
inetSock->state = SocketState::UsedNetInet;
inetSock->sock = hostSock;
inetSock->domain = domain;
inetSock->type = type;
Expand Down
21 changes: 0 additions & 21 deletions Core/HLE/sceNetInet.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,24 +186,3 @@ int sceNetApctlConnect(int connIndex);
int sceNetInetPoll(u32 fdsPtr, u32 nfds, int timeout);
int sceNetApctlTerm();
int sceNetApctlDisconnect();

enum class SocketState {
Unused,
Used,
};

// Internal socket state tracking
struct InetSocket {
SOCKET sock; // native socket
SocketState state;
// NOTE: These are the PSP types for now
int domain;
int type;
int protocol;
// These are the host types for convenience.
int hostDomain;
int hostType;
int hostProtocol;
};

extern InetSocket g_inetSockets[256];
2 changes: 2 additions & 0 deletions UWP/CoreUWP/CoreUWP.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@
<ClInclude Include="..\..\Core\HLE\sceNetInet.h" />
<ClInclude Include="..\..\Core\HLE\sceNetResolver.h" />
<ClInclude Include="..\..\Core\HLE\sceNp2.h" />
<ClInclude Include="..\..\Core\HLE\SocketManager.h" />
<ClInclude Include="..\..\Core\Instance.h" />
<ClInclude Include="..\..\Core\HLE\FunctionWrappers.h" />
<ClInclude Include="..\..\Core\HLE\HLE.h" />
Expand Down Expand Up @@ -444,6 +445,7 @@
<ClCompile Include="..\..\Core\HLE\sceNetInet.cpp" />
<ClCompile Include="..\..\Core\HLE\sceNetResolver.cpp" />
<ClCompile Include="..\..\Core\HLE\sceNp2.cpp" />
<ClCompile Include="..\..\Core\HLE\SocketManager.cpp" />
<ClCompile Include="..\..\Core\Instance.cpp" />
<ClCompile Include="..\..\Core\HLE\HLE.cpp" />
<ClCompile Include="..\..\Core\HLE\HLEHelperThread.cpp" />
Expand Down
6 changes: 6 additions & 0 deletions UWP/CoreUWP/CoreUWP.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -1232,6 +1232,9 @@
<ClCompile Include="..\..\Core\HLE\NetInetConstants.cpp">
<Filter>HLE</Filter>
</ClCompile>
<ClCompile Include="..\..\Core\HLE\SocketManager.cpp">
<Filter>HLE</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="pch.h" />
Expand Down Expand Up @@ -1948,6 +1951,9 @@
<ClInclude Include="..\..\Core\HLE\NetInetConstants.h">
<Filter>HLE</Filter>
</ClInclude>
<ClInclude Include="..\..\Core\HLE\SocketManager.h">
<Filter>HLE</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\..\ext\gason\LICENSE">
Expand Down
1 change: 1 addition & 0 deletions android/jni/Android.mk
Original file line number Diff line number Diff line change
Expand Up @@ -665,6 +665,7 @@ EXEC_AND_LIB_FILES := \
$(SRC)/Core/HLE/HLE.cpp \
$(SRC)/Core/HLE/KUBridge.cpp \
$(SRC)/Core/HLE/NetInetConstants.cpp \
$(SRC)/Core/HLE/SocketManager.cpp \
$(SRC)/Core/HLE/Plugins.cpp \
$(SRC)/Core/HLE/sceAdler.cpp \
$(SRC)/Core/HLE/sceAtrac.cpp \
Expand Down
1 change: 1 addition & 0 deletions libretro/Makefile.common
Original file line number Diff line number Diff line change
Expand Up @@ -691,6 +691,7 @@ SOURCES_CXX += \
$(COREDIR)/HLE/HLE.cpp \
$(COREDIR)/HLE/KUBridge.cpp \
$(COREDIR)/HLE/NetInetConstants.cpp \
$(COREDIR)/HLE/SocketManager.cpp \
$(COREDIR)/HLE/Plugins.cpp \
$(COREDIR)/HLE/sceSha256.cpp \
$(COREDIR)/HLE/sceSircs.cpp \
Expand Down
Loading