-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
sceNetInet socket remap #19827
Changes from all commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
303a03c
Cleanup, define socket struct
hrydgard 08f2bee
Add socket lookups
hrydgard 0f2bd65
Use the wrapper struct, except in case of poll/select
hrydgard 8505e24
Attempt to implement remapping in select/poll
hrydgard fcb3d63
Fix some closesocket bugs
hrydgard c33ea84
Implement one of ANR2ME's TODOs
hrydgard 3dc2a10
Setting a socket number minimum of 20 solved the Mac problems. I gues…
hrydgard 2c3f7f6
Add a central location for managing HLE sockets
hrydgard 5026e92
Set min socket number to 61. Somehow this fixes Linux??
hrydgard 155a9f9
Turn the socket manager into a class
hrydgard a1744a6
Add SocketManager::CreateSocket for convenience
hrydgard b97b0e4
Add Close method to socket manager
hrydgard c9c5944
Track non-blocking state
hrydgard 698b73d
ImDebugger: Add Np and Sockets debugger windows, on a new Network menu
hrydgard 728268b
Better CreateSocket errro handling
hrydgard 77fcb18
Just some code formatting
hrydgard f84ec05
Strange buildfix
hrydgard cddd3d4
Crashfix with asan, minor
hrydgard 440fa80
Use the correct count parameter for select
hrydgard File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,102 @@ | ||
| #include "Common/Net/SocketCompat.h" | ||
| #include "Core/HLE/NetInetConstants.h" | ||
| #include "Core/HLE/SocketManager.h" | ||
| #include "Common/Log.h" | ||
|
|
||
| #include <mutex> | ||
|
|
||
| SocketManager g_socketManager; | ||
| static std::mutex g_socketMutex; // TODO: Remove once the adhoc thread is gone | ||
|
|
||
| InetSocket *SocketManager::CreateSocket(int *index, int *returned_errno, SocketState state, int domain, int type, int protocol) { | ||
| _dbg_assert_(state != SocketState::Unused); | ||
|
|
||
| int hostDomain = convertSocketDomainPSP2Host(domain); | ||
| int hostType = convertSocketTypePSP2Host(type); | ||
| int hostProtocol = convertSocketProtoPSP2Host(protocol); | ||
|
|
||
| SOCKET hostSock = ::socket(hostDomain, hostType, hostProtocol); | ||
| if (hostSock < 0) { | ||
| *returned_errno = socket_errno; | ||
| return nullptr; | ||
| } | ||
|
|
||
| std::lock_guard<std::mutex> guard(g_socketMutex); | ||
|
|
||
| for (int i = MIN_VALID_INET_SOCKET; i < ARRAY_SIZE(inetSockets_); i++) { | ||
| if (inetSockets_[i].state == SocketState::Unused) { | ||
| *index = i; | ||
| InetSocket *inetSock = inetSockets_ + i; | ||
| inetSock->sock = hostSock; | ||
| inetSock->state = state; | ||
| inetSock->domain = domain; | ||
| inetSock->type = type; | ||
| inetSock->protocol = protocol; | ||
| inetSock->nonblocking = false; | ||
| *returned_errno = 0; | ||
| return inetSock; | ||
| } | ||
| } | ||
| _dbg_assert_(false); | ||
|
|
||
| ERROR_LOG(Log::sceNet, "Ran out of socket handles! This is BAD."); | ||
| closesocket(hostSock); | ||
| *index = 0; | ||
| *returned_errno = ENOMEM; // or something.. | ||
| return nullptr; | ||
| } | ||
|
|
||
| bool SocketManager::Close(InetSocket *inetSocket) { | ||
| _dbg_assert_(inetSocket->state != SocketState::Unused); | ||
| if (closesocket(inetSocket->sock) != 0) { | ||
| ERROR_LOG(Log::sceNet, "closesocket(%d) failed", inetSocket->sock); | ||
| return false; | ||
| } | ||
| inetSocket->state = SocketState::Unused; | ||
| inetSocket->sock = 0; | ||
| return true; | ||
| } | ||
|
|
||
| bool SocketManager::GetInetSocket(int sock, InetSocket **inetSocket) { | ||
| std::lock_guard<std::mutex> guard(g_socketMutex); | ||
| if (sock < MIN_VALID_INET_SOCKET || sock >= ARRAY_SIZE(inetSockets_) || inetSockets_[sock].state == SocketState::Unused) { | ||
| *inetSocket = nullptr; | ||
| return false; | ||
| } | ||
| *inetSocket = inetSockets_ + sock; | ||
| return true; | ||
| } | ||
|
|
||
| // Simplified mappers, only really useful in select/poll | ||
| SOCKET SocketManager::GetHostSocketFromInetSocket(int sock) { | ||
| std::lock_guard<std::mutex> guard(g_socketMutex); | ||
| if (sock < MIN_VALID_INET_SOCKET || sock >= ARRAY_SIZE(inetSockets_) || inetSockets_[sock].state == SocketState::Unused) { | ||
| _dbg_assert_(false); | ||
| return -1; | ||
| } | ||
| if (sock == 0) { | ||
| // Map 0 to 0, special case. | ||
| return 0; | ||
| } | ||
| return inetSockets_[sock].sock; | ||
| } | ||
|
|
||
| void SocketManager::CloseAll() { | ||
| for (auto &sock : inetSockets_) { | ||
| if (sock.state != SocketState::Unused) { | ||
| closesocket(sock.sock); | ||
| } | ||
| sock.state = SocketState::Unused; | ||
| sock.sock = 0; | ||
| } | ||
| } | ||
|
|
||
| const char *SocketStateToString(SocketState state) { | ||
| switch (state) { | ||
| case SocketState::Unused: return "unused"; | ||
| case SocketState::UsedNetInet: return "netInet"; | ||
| case SocketState::UsedProAdhoc: return "proAdhoc"; | ||
| default: | ||
| return "N/A"; | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| #pragma once | ||
|
|
||
| #include "Common/Net/SocketCompat.h" | ||
|
|
||
| // Keep track of who's using a socket. | ||
| enum class SocketState { | ||
| Unused = 0, | ||
| UsedNetInet, | ||
| UsedProAdhoc, | ||
| }; | ||
|
|
||
| const char *SocketStateToString(SocketState state); | ||
|
|
||
| // Internal socket state tracking | ||
| struct InetSocket { | ||
| SOCKET sock; // native socket | ||
| SocketState state; | ||
| // NOTE: These are the PSP types. Can be converted to the host types if needed. | ||
| int domain; | ||
| int type; | ||
| int protocol; | ||
| bool nonblocking; | ||
| }; | ||
|
|
||
| // Only use this for sockets whose ID are exposed to the game. | ||
| // Don't really need to bother with the others, as the game doesn't know about them. | ||
| class SocketManager { | ||
| public: | ||
| enum { | ||
| VALID_INET_SOCKET_COUNT = 256, | ||
| MIN_VALID_INET_SOCKET = 1, | ||
| }; | ||
|
|
||
| InetSocket *CreateSocket(int *index, int *returned_errno, SocketState state, int domain, int type, int protocol); | ||
| bool GetInetSocket(int sock, InetSocket **inetSocket); | ||
| SOCKET GetHostSocketFromInetSocket(int sock); | ||
| bool Close(InetSocket *inetSocket); | ||
| void CloseAll(); | ||
|
|
||
| // For debugger | ||
| const InetSocket *Sockets() { | ||
| return inetSockets_; | ||
| } | ||
|
|
||
| private: | ||
| // We use this array from MIN_VALID_INET_SOCKET and forward. It's probably not a good idea to return 0 as a socket. | ||
| InetSocket inetSockets_[VALID_INET_SOCKET_COUNT]; | ||
| }; | ||
|
|
||
| extern SocketManager g_socketManager; | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
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
SetSockOpttoo 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.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
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:
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 >.<