Skip to content

Commit

Permalink
sockopt refactor part #1
Browse files Browse the repository at this point in the history
  • Loading branch information
hrydgard committed Jan 17, 2025
1 parent 298a18e commit 852c41d
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 32 deletions.
3 changes: 2 additions & 1 deletion Core/HLE/NetInetConstants.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,10 @@ enum {
#define PSP_NET_INET_SO_RCVTIMEO 0x1006 // receive timeout
#define PSP_NET_INET_SO_ERROR 0x1007 // get error status and clear
#define PSP_NET_INET_SO_TYPE 0x1008 // get socket type
#define PSP_NET_INET_SO_NBIO 0x1009 // SO_NONBLOCK ? // set to non-blocking I/O mode (on true, returning 0x80 when retrieved using getsockopt?)
#define PSP_NET_INET_SO_NBIO 0x1009 // SO_NONBLOCK ? // set to non-blocking I/O mode (on true, returning 0x80 when retrieved using getsockopt?). Unclear if correct.
#define PSP_NET_INET_SO_BIO 0x100a // set to blocking I/O mode (not using the optval just like SO_NBIO?)
//#define PSP_NET_INET_SO_NONBLOCK 0x100b // set to blocking or non-blocking I/O mode (using the optval)
#define PSP_NET_INET_SO_NOSIGPIPE 0x1022 // WARNING: SPECULATION

// User-settable options (used with setsockopt)
#define PSP_NET_INET_TCP_NODELAY 0x01 // don't delay send to coalesce packets
Expand Down
65 changes: 34 additions & 31 deletions Core/HLE/sceNetInet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -458,39 +458,42 @@ static int sceNetInetSetsockopt(int socket, int level, int optname, u32 optvalPt

timeval tval{};
// TODO: Ignoring SO_NBIO/SO_NONBLOCK flag if we always use non-blocking mode (ie. simulated blocking mode)
if (level == PSP_NET_INET_SOL_SOCKET && optname == PSP_NET_INET_SO_NBIO) {
inetSock->nonblocking = optval;
return hleLogSuccessI(Log::sceNet, 0);
}
// FIXME: Should we ignore SO_BROADCAST flag since we are using fake broadcast (ie. only broadcast to friends),
// But Infrastructure/Online play might need to use broadcast for SSDP and to support LAN MP with real PSP
/*else if (level == PSP_NET_INET_SOL_SOCKET && optname == PSP_NET_INET_SO_BROADCAST) {
//memcpy(&sock->so_broadcast, (int*)optval, std::min(sizeof(sock->so_broadcast), optlen));
return hleLogSuccessI(Log::sceNet, 0);
}*/
// TODO: Ignoring SO_REUSEADDR flag to prevent disrupting multiple-instance feature
else if (level == PSP_NET_INET_SOL_SOCKET && optname == PSP_NET_INET_SO_REUSEADDR) {
//memcpy(&sock->reuseaddr, (int*)optval, std::min(sizeof(sock->reuseaddr), optlen));
return hleLogSuccessI(Log::sceNet, 0);
}
// TODO: Ignoring SO_REUSEPORT flag to prevent disrupting multiple-instance feature (not sure if PSP has SO_REUSEPORT or not tho, defined as 15 on Android)
else if (level == PSP_NET_INET_SOL_SOCKET && optname == PSP_NET_INET_SO_REUSEPORT) { // 15
//memcpy(&sock->reuseport, (int*)optval, std::min(sizeof(sock->reuseport), optlen));
return hleLogSuccessI(Log::sceNet, 0);
}
// TODO: Ignoring SO_NOSIGPIPE flag to prevent crashing PPSSPP (not sure if PSP has NOSIGPIPE or not tho, defined as 0x1022 on Darwin)
else if (level == PSP_NET_INET_SOL_SOCKET && optname == 0x1022) { // PSP_NET_INET_SO_NOSIGPIPE ?
//memcpy(&sock->nosigpipe, (int*)optval, std::min(sizeof(sock->nosigpipe), optlen));
return hleLogSuccessI(Log::sceNet, 0);
}
// It seems UNO game will try to set socket buffer size with a very large size and ended getting error (-1), so we should also limit the buffer size to replicate PSP behavior
else if (level == PSP_NET_INET_SOL_SOCKET && (optname == PSP_NET_INET_SO_RCVBUF || optname == PSP_NET_INET_SO_SNDBUF)) { // PSP_NET_INET_SO_NOSIGPIPE ?
// TODO: For SOCK_STREAM max buffer size is 8 Mb on BSD, while max SOCK_DGRAM is 65535 minus the IP & UDP Header size
if (optval > 8 * 1024 * 1024) {
UpdateErrnoFromHost(ENOBUFS, __FUNCTION__); // FIXME: return ENOBUFS for SOCK_STREAM, and EINVAL for SOCK_DGRAM
return hleLogError(Log::sceNet, -1, "buffer size too large?");
if (level == PSP_NET_INET_SOL_SOCKET) {
if (optname == PSP_NET_INET_SO_NBIO) {
inetSock->nonblocking = optval;
return hleLogSuccessI(Log::sceNet, 0);
}
// FIXME: Should we ignore SO_BROADCAST flag since we are using fake broadcast (ie. only broadcast to friends),
// But Infrastructure/Online play might need to use broadcast for SSDP and to support LAN MP with real PSP
/*else if (level == PSP_NET_INET_SOL_SOCKET && optname == PSP_NET_INET_SO_BROADCAST) {
//memcpy(&sock->so_broadcast, (int*)optval, std::min(sizeof(sock->so_broadcast), optlen));
return hleLogSuccessI(Log::sceNet, 0);
}*/
// TODO: Ignoring SO_REUSEADDR flag to prevent disrupting multiple-instance feature
else if (optname == PSP_NET_INET_SO_REUSEADDR) {
//memcpy(&sock->reuseaddr, (int*)optval, std::min(sizeof(sock->reuseaddr), optlen));
return hleLogSuccessI(Log::sceNet, 0);
}
// TODO: Ignoring SO_REUSEPORT flag to prevent disrupting multiple-instance feature (not sure if PSP has SO_REUSEPORT or not tho, defined as 15 on Android)
else if (optname == PSP_NET_INET_SO_REUSEPORT) { // 15
//memcpy(&sock->reuseport, (int*)optval, std::min(sizeof(sock->reuseport), optlen));
return hleLogSuccessI(Log::sceNet, 0);
}
// TODO: Ignoring SO_NOSIGPIPE flag to prevent crashing PPSSPP (not sure if PSP has NOSIGPIPE or not tho, defined as 0x1022 on Darwin)
else if (optname == 0x1022) { // PSP_NET_INET_SO_NOSIGPIPE ?
//memcpy(&sock->nosigpipe, (int*)optval, std::min(sizeof(sock->nosigpipe), optlen));
return hleLogSuccessI(Log::sceNet, 0);
}
// It seems UNO game will try to set socket buffer size with a very large size and ended getting error (-1), so we should also limit the buffer size to replicate PSP behavior
else if (optname == PSP_NET_INET_SO_RCVBUF || optname == PSP_NET_INET_SO_SNDBUF) { // PSP_NET_INET_SO_NOSIGPIPE ?
// TODO: For SOCK_STREAM max buffer size is 8 Mb on BSD, while max SOCK_DGRAM is 65535 minus the IP & UDP Header size
if (optval > 8 * 1024 * 1024) {
UpdateErrnoFromHost(ENOBUFS, __FUNCTION__); // FIXME: return ENOBUFS for SOCK_STREAM, and EINVAL for SOCK_DGRAM
return hleLogError(Log::sceNet, -1, "buffer size too large?");
}
}
}

int retval = 0;
// PSP timeout are a single 32bit value (micro seconds)
if (level == PSP_NET_INET_SOL_SOCKET && optval && (optname == PSP_NET_INET_SO_RCVTIMEO || optname == PSP_NET_INET_SO_SNDTIMEO)) {
Expand Down

0 comments on commit 852c41d

Please sign in to comment.