-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
sceNetInet socket remap #19827
sceNetInet socket remap #19827
Conversation
My |
I also don't think more than 64 sockets is necessary to support, and since as you say it's an array of sockets and not a bitset, so even if a game passes in a number of sockets to listen to that's beyond 64, it's unlikely that that many are in use. The code in this PR makes use of that fact, and in fact it now works great on Windows! Still debugging a mysterious failure on non-Windows though! |
2e1c599
to
7f1b420
Compare
OK, mysterious failure fixed, I just start allocating socket numbers from 20 instead of from 1. This must be clashing with some socket created by that adhoc thread that we start up? Will need to hook all socket access up to this socket allocator. But, let's commit in the meantime. EDIT: Only worked on Mac, heh. |
…s it clashes with the adhoc code?
7f1b420
to
2c3f7f6
Compare
Rebased, still working on Windows/Mac. Next step I think I'll have all the AdHoc stuff also use the socket mapper, so there's no risk of clashing. |
adhoc threads doesn't creates PSP socket unless the game is using AdhocMatching/GameMode(another adhoc library), the socket being created on friendfinder thread is only for communication with adhoc server, which use native TCP socket, thus doesn't consumes PSP's socket id. |
Currently we use a separated id generation for both adhoc sockets and infra sockets, where adhoc sockets are stored in As i remembered during my test on JPCSP with official prx files, adhoc sockets and infrastructure sockets seems to share the same id manager/generator. For example:
But this probably need to be confirmed on a real PSP too. |
}; | ||
|
||
// Internal socket state tracking | ||
struct InetSocket { |
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 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.
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:
// 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 >.<
Yeah I've concluded that the problem must be something different and the offset is fixing it by accident somehow :/ since indeed while joining infrastructure mode, we don't generate any other game-visible socket IDs. I'm mystified.. but I'll crack this somehow heh. |
May be it didn't get initialized properly, and somehow works on those platforms because it was coincidentally zeroed. |
Core/HLE/SocketManager.cpp
Outdated
} | ||
_dbg_assert_(false); | ||
ERROR_LOG(Log::sceNet, "Ran out of socket handles! This is BAD."); | ||
return 0; |
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.
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.
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.
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)
Added some ImDebugger UI where you can see some info about the open sockets and Np. Still haven't figured out the linux/mac problem, or why increasing the minimum helps somewhat. |
May i know why we need the minimum value? as i remembered the id is always started from 1. |
I don't know! It shouldn't be there, but it somehow fixes it on Mac and also on Linux sometimes... I want to remove it (or set it to 1) before I merge this. |
Hmm.. may be during socket creation instead of searching for an unused slot below the last id, we should use the slot after the last id, and if the socket with the last id got deleted we decrease the last id, similar to what we did on adhoc socket. For example:
|
If that was the cause, I'd expect it to fail on all platforms equally? However, it might still be worth trying, thanks for the idea. |
Btw, which game are you testing this with? the one that have issue on Linux/Android |
Wipeout Pulse. Notably, without this PR, it works on Mac/Linux (but not on Windows, of course). Haven't really tested on Android yet, but not much point until it works on Linux... |
Well without id remapping, socket's ids on non-windows are usually below 256 and already compatible with PSP socket's id limit, unlike Windows socket id that usually have value more than 1k. If the game use |
I do want to perform the same ID remapping on all platforms, and there's no reason that shouldn't work. select is definitely the main suspect... But I can't understand why it won't work :/ |
I tried your ID assignment algorithm, made no difference. What I'm seeing makes no sense at all :/ On Windows everything is fine with MIN_VALID_INET_SOCKET=1. On Linux/Mac you have to increase MIN_VALID_NET_SOCKET, on Linux by at least 50, otherwise select never returns any pending reads bits. Then it works for me (but not for a tester). I don't see anything else interesting in the log. I don't think I'm mixing up the IDs in sceNetInetSelect().. |
Really? with this PR it's fully playable in multiplayer for me on Windows. EU version. Primary DNS in settings = 67.222.156.250. |
You have the NTSC version. The server only works on PAL version. |
Hmm.. may be the issue is at ppsspp/Core/HLE/sceNetInet.cpp Line 678 in f84ec05
|
Oh, that's a good catch! I'll fix that. But it turns out that the problem was the first parameter to select, which I forgot to change according to the host socket numbers .. sigh. Anyway, it's solved now, working great on all three platforms (well, I'll test Mac now, but Linux works) |
Btw, is there a way to make the game cross-region? they probably use the same packet for communication, right? |
I'll fix accept separately, along with a few other little things. |
Making the game cross-region is on the to do list. Currently the server isn't set up to be able to have two different AppId's communicate with each other. |
As adviced by @anr2me in anr2me#21
Works great on Windows! Managed to play races in Wipeout Pulse.
But breaks other platforms currently, heh. EDIT: Was fixed eventually.