mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Move flags and other constants from InetSocket onto SceNetInet.
This commit is contained in:
parent
4bc79481da
commit
727203e88f
3 changed files with 220 additions and 235 deletions
|
@ -250,7 +250,7 @@ static int sceNetInetSocket(int inetAddressFamily, int inetType, int inetProtoco
|
|||
}
|
||||
|
||||
// Map opened socket to an inet socket which is 1-indexed
|
||||
const auto inetSocket = sceNetInet->CreateAndAssociateInetSocket(nativeSocketId, nonBlocking);
|
||||
const auto inetSocket = sceNetInet->CreateAndAssociateInetSocket(nativeSocketId, nativeProtocol, nonBlocking);
|
||||
|
||||
// Set non-blocking mode since the translation function does not translate non-blocking mode due to platform incompatibilities
|
||||
if (nonBlocking) {
|
||||
|
@ -276,7 +276,7 @@ static int sceNetInetGetsockopt(int socket, int inetSocketLevel, int inetOptname
|
|||
|
||||
const auto inetSocket = sceNetInet->GetInetSocket(socket);
|
||||
if (!inetSocket) {
|
||||
sceNetInet->SetLastError(EINVAL);
|
||||
sceNetInet->SetLastError(EBADF);
|
||||
return hleLogError(SCENET, -1, "%s: Attempting to operate on unmapped socket %i", __func__, socket);
|
||||
}
|
||||
|
||||
|
@ -288,14 +288,14 @@ static int sceNetInetGetsockopt(int socket, int inetSocketLevel, int inetOptname
|
|||
return hleLogError(SCENET, -1, "[%i] %s: Unknown socket level %04x", nativeSocketId, __func__, inetSocketLevel);
|
||||
}
|
||||
|
||||
if (!inetSocket->IsSockoptNameAllowed(inetOptname)) {
|
||||
sceNetInet->SetLastError(EINVAL);
|
||||
int nativeOptname;
|
||||
if (!SceNetInet::TranslateInetOptnameToNativeOptname(nativeOptname, inetOptname)) {
|
||||
sceNetInet->SetLastError(ENOPROTOOPT);
|
||||
return hleLogError(SCENET, ERROR_NET_INET_CONFIG_INVALID_ARG, "Unknown optname %04x", inetOptname);
|
||||
}
|
||||
|
||||
const auto optname = InetSocket::TranslateInetOptnameToNativeOptname(static_cast<InetSocketOptionName>(inetOptname));
|
||||
if (optname != inetOptname) {
|
||||
DEBUG_LOG(SCENET, "sceNetInetSetsockopt: Translated optname %04x into %04x", inetOptname, optname);
|
||||
if (nativeOptname != inetOptname) {
|
||||
DEBUG_LOG(SCENET, "sceNetInetSetsockopt: Translated optname %04x into %04x", inetOptname, nativeOptname);
|
||||
}
|
||||
|
||||
#if PPSSPP_PLATFORM(WINDOWS)
|
||||
|
@ -314,7 +314,7 @@ static int sceNetInetGetsockopt(int socket, int inetSocketLevel, int inetOptname
|
|||
return hleLogError(SCENET, -1, "[%i] %s: Invalid pointer range %08x (size %i)", nativeSocketId, __func__, optvalPtr, *optlen);
|
||||
}
|
||||
|
||||
switch (optname) {
|
||||
switch (nativeOptname) {
|
||||
// No direct equivalents
|
||||
case INET_SO_NONBLOCK: {
|
||||
if (*optlen != sizeof(u32)) {
|
||||
|
@ -327,7 +327,7 @@ static int sceNetInetGetsockopt(int socket, int inetSocketLevel, int inetOptname
|
|||
// Direct 1:1 mappings
|
||||
default: {
|
||||
// TODO: implement non-blocking getsockopt
|
||||
const int ret = getsockopt(nativeSocketId, nativeSocketLevel, optname, optval, optlen);
|
||||
const int ret = getsockopt(nativeSocketId, nativeSocketLevel, nativeOptname, optval, optlen);
|
||||
if (ret < 0) {
|
||||
const auto error = sceNetInet->SetLastErrorToMatchPlatform();
|
||||
return hleLogError(SCENET, ret, "[%i] %s: returned error %i: %s", nativeSocketId, __func__, error, strerror(error));
|
||||
|
@ -347,7 +347,7 @@ static int sceNetInetSetsockopt(int socket, int inetSocketLevel, int inetOptname
|
|||
|
||||
const auto inetSocket = sceNetInet->GetInetSocket(socket);
|
||||
if (!inetSocket) {
|
||||
sceNetInet->SetLastError(EFAULT);
|
||||
sceNetInet->SetLastError(EBADF);
|
||||
return hleLogError(SCENET, -1, "%s: Attempting to operate on unmapped socket %i", __func__, socket);
|
||||
}
|
||||
|
||||
|
@ -359,14 +359,14 @@ static int sceNetInetSetsockopt(int socket, int inetSocketLevel, int inetOptname
|
|||
return hleLogError(SCENET, -1, "[%i] %s: Unknown socket level %04x", nativeSocketId, __func__, inetSocketLevel);
|
||||
}
|
||||
|
||||
if (!inetSocket->IsSockoptNameAllowed(inetOptname)) {
|
||||
sceNetInet->SetLastError(EINVAL);
|
||||
int nativeOptname;
|
||||
if (!SceNetInet::TranslateInetOptnameToNativeOptname(nativeOptname, inetOptname)) {
|
||||
sceNetInet->SetLastError(ENOPROTOOPT);
|
||||
return hleLogError(SCENET, -1, "[%i] %s: Unknown optname %04x", nativeSocketId, __func__, inetOptname);
|
||||
}
|
||||
|
||||
const auto optname = InetSocket::TranslateInetOptnameToNativeOptname(static_cast<InetSocketOptionName>(inetOptname));
|
||||
if (optname != inetOptname) {
|
||||
DEBUG_LOG(SCENET, "sceNetInetSetsockopt: Translated optname %04x into %04x", inetOptname, optname);
|
||||
if (nativeOptname != inetOptname) {
|
||||
DEBUG_LOG(SCENET, "sceNetInetSetsockopt: Translated optname %04x into %04x", inetOptname, nativeOptname);
|
||||
}
|
||||
|
||||
// If optlens of != sizeof(u32) are created, split out the handling into separate functions for readability
|
||||
|
@ -381,9 +381,9 @@ static int sceNetInetSetsockopt(int socket, int inetSocketLevel, int inetOptname
|
|||
}
|
||||
|
||||
auto optval = Memory::Read_U32(optvalPtr);
|
||||
DEBUG_LOG(SCENET, "[%i] setsockopt(%i, %i, %i, %i)", nativeSocketId, nativeSocketId, nativeSocketLevel, optname, optval);
|
||||
DEBUG_LOG(SCENET, "[%i] setsockopt(%i, %i, %i, %i)", nativeSocketId, nativeSocketId, nativeSocketLevel, nativeOptname, optval);
|
||||
|
||||
switch (optname) {
|
||||
switch (nativeOptname) {
|
||||
// Unmatched PSP functions - no direct equivalent
|
||||
case INET_SO_NONBLOCK: {
|
||||
const bool nonblocking = optval != 0;
|
||||
|
@ -397,12 +397,12 @@ static int sceNetInetSetsockopt(int socket, int inetSocketLevel, int inetOptname
|
|||
}
|
||||
// Functions with identical structs to native functions
|
||||
default: {
|
||||
INFO_LOG(SCENET, "UNTESTED sceNetInetSetsockopt(%i, %i, %i, %u, %i)", nativeSocketId, nativeSocketLevel, optname, optval, 4);
|
||||
const int ret = setsockopt(nativeSocketId, nativeSocketLevel, optname, reinterpret_cast<netBufferType*>(&optval), sizeof(optval));
|
||||
INFO_LOG(SCENET, "UNTESTED sceNetInetSetsockopt(%i, %i, %i, %u, %i)", nativeSocketId, nativeSocketLevel, nativeOptname, optval, 4);
|
||||
const int ret = setsockopt(nativeSocketId, nativeSocketLevel, nativeOptname, reinterpret_cast<netBufferType*>(&optval), sizeof(optval));
|
||||
INFO_LOG(SCENET, "setsockopt_u32: setsockopt returned %i for %i", ret, nativeSocketId);
|
||||
if (ret < 0) {
|
||||
const auto error = sceNetInet->SetLastErrorToMatchPlatform();
|
||||
return hleLogError(SCENET, ret, "[%i] %s: Failed to set optname %04x to %08x with error %i: %s", nativeSocketId, __func__, optname, optval, error, strerror(error));
|
||||
return hleLogError(SCENET, ret, "[%i] %s: Failed to set optname %04x to %08x with error %i: %s", nativeSocketId, __func__, nativeOptname, optval, error, strerror(error));
|
||||
}
|
||||
return hleLogSuccessI(SCENET, ret);
|
||||
}
|
||||
|
@ -614,7 +614,7 @@ static int sceNetInetClose(int socket) {
|
|||
|
||||
const auto inetSocket = sceNetInet->GetInetSocket(socket);
|
||||
if (!inetSocket) {
|
||||
sceNetInet->SetLastError(EINVAL);
|
||||
sceNetInet->SetLastError(EBADF);
|
||||
return hleLogWarning(SCENET, -1, "%s: Attempting to close socket %i which does not exist", __func__, socket);
|
||||
}
|
||||
|
||||
|
@ -830,8 +830,8 @@ static int sceNetInetRecv(int socket, u32 bufPtr, u32 bufLen, int flags) {
|
|||
|
||||
const auto inetSocket = sceNetInet->GetInetSocket(socket);
|
||||
if (!inetSocket) {
|
||||
WARN_LOG(SCENET, "%s: Attempting to close socket %i which does not exist", __func__, socket);
|
||||
return -1;
|
||||
sceNetInet->SetLastError(EBADF);
|
||||
return hleLogError(SCENET, -1, "%s: Attempting to close socket %i which does not exist", __func__, socket);
|
||||
}
|
||||
|
||||
const auto nativeSocketId = inetSocket->GetNativeSocketId();
|
||||
|
@ -840,7 +840,7 @@ static int sceNetInetRecv(int socket, u32 bufPtr, u32 bufLen, int flags) {
|
|||
return hleLogError(SCENET, -1, "[%i] %s: Invalid pointer %08x (size %i)", nativeSocketId, __func__, bufPtr, bufLen);
|
||||
}
|
||||
|
||||
const int nativeFlags = inetSocket->TranslateInetFlagsToNativeFlags(flags);
|
||||
const int nativeFlags = SceNetInet::TranslateInetFlagsToNativeFlags(flags, inetSocket->IsNonBlocking());
|
||||
const int ret = recv(nativeSocketId, dstBuf, bufLen, nativeFlags);
|
||||
DEBUG_LOG(SCENET, "[%i] %s: Called recv with buf size %i which returned %i", nativeSocketId, __func__, bufLen, ret);
|
||||
if (ret < 0) {
|
||||
|
@ -861,7 +861,7 @@ static int sceNetInetRecvfrom(int socket, u32 bufPtr, u32 bufLen, int flags, u32
|
|||
|
||||
const auto inetSocket = sceNetInet->GetInetSocket(socket);
|
||||
if (!inetSocket) {
|
||||
sceNetInet->SetLastError(EFAULT);
|
||||
sceNetInet->SetLastError(EBADF);
|
||||
return hleLogError(SCENET, -1, "%s: Attempting to operate on unmapped socket %i", __func__, socket);
|
||||
}
|
||||
|
||||
|
@ -873,7 +873,7 @@ static int sceNetInetRecvfrom(int socket, u32 bufPtr, u32 bufLen, int flags, u32
|
|||
}
|
||||
|
||||
// Translate PSP flags to native flags and prepare sockaddrIn to receive peer address
|
||||
const int nativeFlags = inetSocket->TranslateInetFlagsToNativeFlags(flags);
|
||||
const int nativeFlags = SceNetInet::TranslateInetFlagsToNativeFlags(flags, inetSocket->IsNonBlocking());
|
||||
sockaddr_in sockaddrIn{};
|
||||
socklen_t socklen = sizeof(sockaddr_in);
|
||||
Memory::Memset(bufPtr, 0, bufLen, __func__);
|
||||
|
@ -906,7 +906,7 @@ static int sceNetInetSend(int socket, u32 bufPtr, u32 bufLen, int flags) {
|
|||
|
||||
const auto inetSocket = sceNetInet->GetInetSocket(socket);
|
||||
if (!inetSocket) {
|
||||
sceNetInet->SetLastError(EFAULT);
|
||||
sceNetInet->SetLastError(EBADF);
|
||||
return hleLogError(SCENET, -1, "%s: Attempting to operate on unmapped socket %i", __func__, socket);
|
||||
}
|
||||
|
||||
|
@ -917,7 +917,7 @@ static int sceNetInetSend(int socket, u32 bufPtr, u32 bufLen, int flags) {
|
|||
}
|
||||
|
||||
// Translate PSP flags to native flags and send
|
||||
const int nativeFlags = inetSocket->TranslateInetFlagsToNativeFlags(flags);
|
||||
const int nativeFlags = SceNetInet::TranslateInetFlagsToNativeFlags(flags, inetSocket->IsNonBlocking());
|
||||
const int ret = send(inetSocket->GetNativeSocketId(), buf, bufLen, nativeFlags);
|
||||
if (ret < 0) {
|
||||
const auto error = sceNetInet->SetLastErrorToMatchPlatform();
|
||||
|
@ -935,7 +935,7 @@ static int sceNetInetSendto(int socket, u32 bufPtr, u32 bufLen, int flags, u32 t
|
|||
|
||||
const auto inetSocket = sceNetInet->GetInetSocket(socket);
|
||||
if (!inetSocket) {
|
||||
sceNetInet->SetLastError(EFAULT);
|
||||
sceNetInet->SetLastError(EBADF);
|
||||
return hleLogError(SCENET, -1, "%s: Attempting to operate on unmapped socket %i", __func__, socket);
|
||||
}
|
||||
|
||||
|
@ -947,7 +947,7 @@ static int sceNetInetSendto(int socket, u32 bufPtr, u32 bufLen, int flags, u32 t
|
|||
}
|
||||
|
||||
// Translate PSP flags to native flags and convert toAddr to native addr
|
||||
const int nativeFlags = inetSocket->TranslateInetFlagsToNativeFlags(flags);
|
||||
const int nativeFlags = SceNetInet::TranslateInetFlagsToNativeFlags(flags, inetSocket->IsNonBlocking());
|
||||
sockaddr_in convertedSockAddr{};
|
||||
if (!inetSockaddrToNativeSocketAddr(convertedSockAddr, toAddr, toLen)) {
|
||||
ERROR_LOG(SCENET, "[%i] %s: Unable to translate sceSockAddr to native sockaddr", nativeSocketId, __func__);
|
||||
|
@ -979,7 +979,7 @@ static int sceNetInetGetErrno() {
|
|||
INFO_LOG(SCENET, "Requested %s %i=%s", __func__, nativeError, strerror(nativeError));
|
||||
}
|
||||
|
||||
return InetSocket::TranslateNativeErrorToInetError(nativeError);
|
||||
return SceNetInet::TranslateNativeErrorToInetError(nativeError);
|
||||
}
|
||||
|
||||
static int sceNetInetBind(int socket, u32 addrPtr, u32 addrLen) {
|
||||
|
@ -991,7 +991,7 @@ static int sceNetInetBind(int socket, u32 addrPtr, u32 addrLen) {
|
|||
|
||||
const auto inetSocket = sceNetInet->GetInetSocket(socket);
|
||||
if (!inetSocket) {
|
||||
sceNetInet->SetLastError(EFAULT);
|
||||
sceNetInet->SetLastError(EBADF);
|
||||
return hleLogError(SCENET, -1, "%s: Attempting to operate on unmapped socket %i", __func__, socket);
|
||||
}
|
||||
|
||||
|
@ -1023,12 +1023,13 @@ static int sceNetInetBind(int socket, u32 addrPtr, u32 addrLen) {
|
|||
// Set UPnP
|
||||
const auto port = ntohs(convertedSockaddr.sin_port);
|
||||
switch (inetSocket->GetProtocol()) {
|
||||
case INET_PROTOCOL_TCP: {
|
||||
UPnP_Add(IP_PROTOCOL_TCP, port, port);
|
||||
case IPPROTO_UDP: {
|
||||
UPnP_Add(IP_PROTOCOL_UDP, port, port);
|
||||
break;
|
||||
}
|
||||
case INET_PROTOCOL_UDP: {
|
||||
UPnP_Add(IP_PROTOCOL_UDP, port, port);
|
||||
case IPPROTO_IP:
|
||||
case IPPROTO_TCP: {
|
||||
UPnP_Add(IP_PROTOCOL_TCP, port, port);
|
||||
break;
|
||||
}
|
||||
// TODO: Unknown IP protocol 000f when attempting to set up UPnP port forwarding
|
||||
|
@ -1076,23 +1077,24 @@ const HLEFunction sceNetInet[] = {
|
|||
};;
|
||||
|
||||
std::shared_ptr<SceNetInet> SceNetInet::gInstance;
|
||||
|
||||
std::shared_mutex SceNetInet::gLock;
|
||||
std::unordered_map<PspInetAddressFamily, int> SceNetInet::gInetAddressFamilyToNativeAddressFamily =
|
||||
{
|
||||
|
||||
std::unordered_map<PspInetAddressFamily, int> SceNetInet::gInetAddressFamilyToNativeAddressFamily = {
|
||||
{ PSP_NET_INET_AF_UNSPEC, AF_UNSPEC },
|
||||
{ PSP_NET_INET_AF_LOCAL, AF_UNIX },
|
||||
{ PSP_NET_INET_AF_INET, AF_INET },
|
||||
};
|
||||
std::unordered_map<PspInetSocketType, int> SceNetInet::gInetSocketTypeToNativeSocketType =
|
||||
{
|
||||
|
||||
std::unordered_map<PspInetSocketType, int> SceNetInet::gInetSocketTypeToNativeSocketType = {
|
||||
{ PSP_NET_INET_SOCK_STREAM, SOCK_STREAM },
|
||||
{ PSP_NET_INET_SOCK_DGRAM, SOCK_DGRAM },
|
||||
{ PSP_NET_INET_SOCK_RAW, SOCK_RAW },
|
||||
{ PSP_NET_INET_SOCK_RDM, SOCK_RDM },
|
||||
{ PSP_NET_INET_SOCK_SEQPACKET, SOCK_SEQPACKET },
|
||||
};
|
||||
std::unordered_map<PspInetProtocol, int> SceNetInet::gInetProtocolToNativeProtocol =
|
||||
{
|
||||
|
||||
std::unordered_map<PspInetProtocol, int> SceNetInet::gInetProtocolToNativeProtocol = {
|
||||
{ PSP_NET_INET_IPPROTO_IP, IPPROTO_IP },
|
||||
{ PSP_NET_INET_IPPROTO_ICMP, IPPROTO_ICMP },
|
||||
{ PSP_NET_INET_IPPROTO_IGMP, IPPROTO_IGMP },
|
||||
|
@ -1104,6 +1106,54 @@ std::unordered_map<PspInetProtocol, int> SceNetInet::gInetProtocolToNativeProtoc
|
|||
{ PSP_NET_INET_IPPROTO_RAW, IPPROTO_RAW },
|
||||
};
|
||||
|
||||
// TODO: commented out optnames
|
||||
std::unordered_map<PspInetSocketOptionName, int> SceNetInet::gInetSocketOptnameToNativeOptname = {
|
||||
{ INET_SO_ACCEPTCONN, SO_ACCEPTCONN },
|
||||
{ INET_SO_REUSEADDR, SO_REUSEADDR },
|
||||
{ INET_SO_KEEPALIVE, SO_KEEPALIVE },
|
||||
{ INET_SO_DONTROUTE, SO_DONTROUTE },
|
||||
{ INET_SO_BROADCAST, SO_BROADCAST },
|
||||
// { INET_SO_USELOOPBACK, INET_SO_USELOOPBACK },
|
||||
{ INET_SO_LINGER, SO_LINGER },
|
||||
{ INET_SO_OOBINLINE, SO_OOBINLINE },
|
||||
{ INET_SO_REUSEPORT, SO_REUSEPORT },
|
||||
{ INET_SO_TIMESTAMP, SO_TIMESTAMP },
|
||||
// { INET_SO_ONESBCAST, INET_SO_ONESBCAST },
|
||||
{ INET_SO_SNDBUF, SO_SNDBUF },
|
||||
{ INET_SO_RCVBUF, SO_RCVBUF },
|
||||
{ INET_SO_SNDLOWAT, SO_SNDLOWAT },
|
||||
{ INET_SO_RCVLOWAT, SO_RCVLOWAT },
|
||||
{ INET_SO_SNDTIMEO, SO_SNDTIMEO },
|
||||
{ INET_SO_RCVTIMEO, SO_RCVTIMEO },
|
||||
{ INET_SO_ERROR, SO_ERROR },
|
||||
{ INET_SO_TYPE, SO_TYPE },
|
||||
// { INET_SO_OVERFLOWED, INET_SO_OVERFLOWED },
|
||||
{ INET_SO_NONBLOCK, INET_SO_NONBLOCK },
|
||||
};
|
||||
|
||||
std::unordered_map<PspInetMessageFlag, int> SceNetInet::gInetMessageFlagToNativeMessageFlag = {
|
||||
{ INET_MSG_OOB, MSG_OOB },
|
||||
{ INET_MSG_PEEK, MSG_PEEK },
|
||||
{ INET_MSG_DONTROUTE, MSG_DONTROUTE },
|
||||
#if defined(MSG_EOR)
|
||||
{ INET_MSG_EOR, MSG_EOR },
|
||||
#endif
|
||||
{ INET_MSG_TRUNC, MSG_TRUNC },
|
||||
{ INET_MSG_CTRUNC, MSG_CTRUNC },
|
||||
{ INET_MSG_WAITALL, MSG_WAITALL },
|
||||
{ INET_MSG_DONTWAIT, MSG_DONTWAIT },
|
||||
#if defined(MSG_BCAST)
|
||||
{ INET_MSG_BCAST, MSG_BCAST },
|
||||
#endif
|
||||
#if defined(MSG_MCAST)
|
||||
{ INET_MSG_MCAST, MSG_MCAST },
|
||||
#endif
|
||||
};
|
||||
|
||||
std::unordered_map<int, InetErrorCode> SceNetInet::gNativeErrorCodeToInetErrorCode = {
|
||||
{ EINPROGRESS, INET_EINPROGRESS }
|
||||
};
|
||||
|
||||
bool SceNetInet::Init() {
|
||||
auto lock = std::unique_lock(gLock);
|
||||
if (gInstance) {
|
||||
|
@ -1186,6 +1236,50 @@ bool SceNetInet::TranslateInetProtocolToNative(int &destProtocol, int srcProtoco
|
|||
return true;
|
||||
}
|
||||
|
||||
bool SceNetInet::TranslateInetOptnameToNativeOptname(int &destOptname, const int inetOptname) {
|
||||
const auto it = gInetSocketOptnameToNativeOptname.find(static_cast<PspInetSocketOptionName>(inetOptname));
|
||||
if (it == gInetSocketOptnameToNativeOptname.end()) {
|
||||
return false;
|
||||
}
|
||||
destOptname = it->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
int SceNetInet::TranslateInetFlagsToNativeFlags(const int messageFlags, const bool nonBlocking) {
|
||||
int nativeFlags = 0; // The actual platform flags
|
||||
int foundFlags = 0; // The inet equivalent of the native flags, used to verify that no remaining flags need to be set
|
||||
for (const auto [inetFlag, nativeFlag] : gInetMessageFlagToNativeMessageFlag) {
|
||||
if ((messageFlags & inetFlag) != 0) {
|
||||
nativeFlags |= nativeFlag;
|
||||
foundFlags |= inetFlag;
|
||||
}
|
||||
}
|
||||
|
||||
#if !PPSSPP_PLATFORM(WINDOWS)
|
||||
if (nonBlocking) {
|
||||
nativeFlags |= MSG_DONTWAIT;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Check for any inet flags which were not successfully mapped into a native flag
|
||||
if (const int missingFlags = messageFlags & ~foundFlags; missingFlags != 0) {
|
||||
for (int i = 0; i < sizeof(int) * 8; i++) {
|
||||
if (const int val = 1 << i; (missingFlags & val) != 0) {
|
||||
DEBUG_LOG(SCENET, "Encountered unsupported platform flag at bit %i (actual value %04x), undefined behavior may ensue.", i, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
return nativeFlags;
|
||||
}
|
||||
|
||||
int SceNetInet::TranslateNativeErrorToInetError(const int nativeError) {
|
||||
if (const auto it = gNativeErrorCodeToInetErrorCode.find(nativeError);
|
||||
it != gNativeErrorCodeToInetErrorCode.end()) {
|
||||
return it->second;
|
||||
}
|
||||
return nativeError;
|
||||
}
|
||||
|
||||
int SceNetInet::GetLastError() {
|
||||
auto lock = std::shared_lock(mLock);
|
||||
return mLastError;
|
||||
|
@ -1207,7 +1301,7 @@ int SceNetInet::SetLastErrorToMatchPlatform() {
|
|||
return error;
|
||||
}
|
||||
|
||||
std::shared_ptr<InetSocket> SceNetInet::CreateAndAssociateInetSocket(int nativeSocketId, bool nonBlocking) {
|
||||
std::shared_ptr<InetSocket> SceNetInet::CreateAndAssociateInetSocket(int nativeSocketId, int protocol, bool nonBlocking) {
|
||||
auto lock = std::unique_lock(mLock);
|
||||
|
||||
int inetSocketId = ++mCurrentInetSocketId;
|
||||
|
@ -1215,7 +1309,7 @@ std::shared_ptr<InetSocket> SceNetInet::CreateAndAssociateInetSocket(int nativeS
|
|||
WARN_LOG(SCENET, "%s: Attempted to re-associate socket from already-associated inetSocketId: %i", __func__, inetSocketId);
|
||||
return nullptr;
|
||||
}
|
||||
auto inetSocket = std::make_shared<InetSocket>(inetSocketId, nativeSocketId);
|
||||
auto inetSocket = std::make_shared<InetSocket>(inetSocketId, nativeSocketId, protocol, nonBlocking);
|
||||
inetSocket->SetNonBlocking(nonBlocking);
|
||||
mInetSocketIdToNativeSocket.emplace(inetSocketId, inetSocket);
|
||||
return inetSocket;
|
||||
|
|
|
@ -91,6 +91,53 @@ enum PspInetProtocol {
|
|||
PSP_NET_INET_IPPROTO_RAW = 255, // raw IP packet
|
||||
};
|
||||
|
||||
// TODO: INET_
|
||||
enum PspInetSocketOptionName {
|
||||
// TODO: also specify minimum socket size
|
||||
INET_SO_ACCEPTCONN = 0x0002, // socket has had listen()
|
||||
INET_SO_REUSEADDR = 0x0004, // allow local address reuse
|
||||
INET_SO_KEEPALIVE = 0x0008, // keep connections alive
|
||||
INET_SO_DONTROUTE = 0x0010, // just use interface addresses
|
||||
INET_SO_BROADCAST = 0x0020, // permit sending of broadcast msgs
|
||||
INET_SO_USELOOPBACK = 0x0040, // bypass hardware when possible
|
||||
INET_SO_LINGER = 0x0080, // linger on close if data present
|
||||
INET_SO_OOBINLINE = 0x0100, // leave received OOB data in line
|
||||
INET_SO_REUSEPORT = 0x0200, // allow local address & port reuse
|
||||
INET_SO_TIMESTAMP = 0x0400, // timestamp received dgram traffic
|
||||
INET_SO_ONESBCAST = 0x0800, // allow broadcast to 255.255.255.255
|
||||
INET_SO_SNDBUF = 0x1001, // send buffer size
|
||||
INET_SO_RCVBUF = 0x1002, // receive buffer size
|
||||
INET_SO_SNDLOWAT = 0x1003, // send low-water mark
|
||||
INET_SO_RCVLOWAT = 0x1004, // receive low-water mark
|
||||
INET_SO_SNDTIMEO = 0x1005, // send timeout
|
||||
INET_SO_RCVTIMEO = 0x1006, // receive timeout
|
||||
INET_SO_ERROR = 0x1007, // get error status and clear
|
||||
INET_SO_TYPE = 0x1008, // get socket type
|
||||
INET_SO_OVERFLOWED = 0x1009, // datagrams: return packets dropped
|
||||
INET_SO_NONBLOCK = 0x1009, // non-blocking I/O
|
||||
};
|
||||
|
||||
enum PspInetLimit {
|
||||
PSP_NET_INET_SOMAXCONN = 128,
|
||||
};
|
||||
|
||||
enum PspInetMessageFlag {
|
||||
INET_MSG_OOB = 1,
|
||||
INET_MSG_PEEK = 1 << 1,
|
||||
INET_MSG_DONTROUTE = 1 << 2,
|
||||
INET_MSG_EOR = 1 << 3,
|
||||
INET_MSG_TRUNC = 1 << 4,
|
||||
INET_MSG_CTRUNC = 1 << 5,
|
||||
INET_MSG_WAITALL = 1 << 6,
|
||||
INET_MSG_DONTWAIT = 1 << 7,
|
||||
INET_MSG_BCAST = 1 << 8,
|
||||
INET_MSG_MCAST = 1 << 9
|
||||
};
|
||||
|
||||
enum InetErrorCode {
|
||||
INET_EINPROGRESS = 119,
|
||||
};
|
||||
|
||||
class SceNetInet {
|
||||
public:
|
||||
static bool Init();
|
||||
|
@ -106,13 +153,17 @@ public:
|
|||
static bool TranslateInetSocketTypeToNative(int &destSocketType, bool &destNonBlocking, int srcSocketType);
|
||||
// TODO: document that errno should be set to EPROTONOSUPPORT when this returns false
|
||||
static bool TranslateInetProtocolToNative(int &destProtocol, int srcProtocol);
|
||||
// TODO: document that errno should be set to EPROTONOSUPPORT when this returns false
|
||||
static bool TranslateInetOptnameToNativeOptname(int &destOptname, int inetOptname);
|
||||
static int TranslateInetFlagsToNativeFlags(int messageFlags, bool nonBlocking);
|
||||
static int TranslateNativeErrorToInetError(int nativeError);
|
||||
|
||||
// TODO: document
|
||||
|
||||
int GetLastError();
|
||||
void SetLastError(int error);
|
||||
int SetLastErrorToMatchPlatform();
|
||||
std::shared_ptr<InetSocket> CreateAndAssociateInetSocket(int nativeSocketId, bool nonBlocking);
|
||||
std::shared_ptr<InetSocket> CreateAndAssociateInetSocket(int nativeSocketId, int protocol, bool nonBlocking);
|
||||
std::shared_ptr<InetSocket> GetInetSocket(int inetSocketId);
|
||||
bool GetNativeSocketIdForInetSocketId(int &nativeSocketId, int inetSocketId);
|
||||
bool EraseNativeSocket(int inetSocketId);
|
||||
|
@ -127,6 +178,11 @@ private:
|
|||
// TODO: document that this does not include flags
|
||||
static std::unordered_map<PspInetSocketType, int> gInetSocketTypeToNativeSocketType;
|
||||
static std::unordered_map<PspInetProtocol, int> gInetProtocolToNativeProtocol;
|
||||
// TODO: Handle commented out options
|
||||
static std::unordered_map<PspInetSocketOptionName, int> gInetSocketOptnameToNativeOptname;
|
||||
static std::unordered_map<PspInetMessageFlag, int> gInetMessageFlagToNativeMessageFlag;
|
||||
|
||||
static std::unordered_map<int, InetErrorCode> gNativeErrorCodeToInetErrorCode;
|
||||
|
||||
int mLastError = 0;
|
||||
std::unordered_map<int, std::shared_ptr<InetSocket>> mInetSocketIdToNativeSocket;
|
||||
|
|
|
@ -1,202 +1,37 @@
|
|||
#pragma once
|
||||
|
||||
#include "ppsspp_config.h"
|
||||
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
||||
#if !PPSSPP_PLATFORM(WINDOWS)
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
#include "Log.h"
|
||||
|
||||
enum Protocol {
|
||||
INET_PROTOCOL_UDP = SOCK_DGRAM,
|
||||
INET_PROTOCOL_TCP = SOCK_STREAM
|
||||
};
|
||||
|
||||
// TODO: INET_
|
||||
enum InetSocketOptionName {
|
||||
// TODO: also specify minimum socket size
|
||||
INET_SO_ACCEPTCONN = 0x0002, // socket has had listen()
|
||||
INET_SO_REUSEADDR = 0x0004, // allow local address reuse
|
||||
INET_SO_KEEPALIVE = 0x0008, // keep connections alive
|
||||
INET_SO_DONTROUTE = 0x0010, // just use interface addresses
|
||||
INET_SO_BROADCAST = 0x0020, // permit sending of broadcast msgs
|
||||
INET_SO_USELOOPBACK = 0x0040, // bypass hardware when possible
|
||||
INET_SO_LINGER = 0x0080, // linger on close if data present
|
||||
INET_SO_OOBINLINE = 0x0100, // leave received OOB data in line
|
||||
INET_SO_REUSEPORT = 0x0200, // allow local address & port reuse
|
||||
INET_SO_TIMESTAMP = 0x0400, // timestamp received dgram traffic
|
||||
INET_SO_ONESBCAST = 0x0800, // allow broadcast to 255.255.255.255
|
||||
INET_SO_SNDBUF = 0x1001, // send buffer size
|
||||
INET_SO_RCVBUF = 0x1002, // receive buffer size
|
||||
INET_SO_SNDLOWAT = 0x1003, // send low-water mark
|
||||
INET_SO_RCVLOWAT = 0x1004, // receive low-water mark
|
||||
INET_SO_SNDTIMEO = 0x1005, // send timeout
|
||||
INET_SO_RCVTIMEO = 0x1006, // receive timeout
|
||||
INET_SO_ERROR = 0x1007, // get error status and clear
|
||||
INET_SO_TYPE = 0x1008, // get socket type
|
||||
INET_SO_OVERFLOWED = 0x1009, // datagrams: return packets dropped
|
||||
INET_SO_NONBLOCK = 0x1009, // non-blocking I/O
|
||||
};
|
||||
|
||||
// TODO: Handle commented out options
|
||||
static std::unordered_map<InetSocketOptionName, int> gInetSocketOptnameToNativeOptname = {
|
||||
{ INET_SO_ACCEPTCONN, SO_ACCEPTCONN },
|
||||
{ INET_SO_REUSEADDR, SO_REUSEADDR },
|
||||
{ INET_SO_KEEPALIVE, SO_KEEPALIVE },
|
||||
{ INET_SO_DONTROUTE, SO_DONTROUTE },
|
||||
{ INET_SO_BROADCAST, SO_BROADCAST },
|
||||
// { INET_SO_USELOOPBACK, INET_SO_USELOOPBACK },
|
||||
{ INET_SO_LINGER, SO_LINGER },
|
||||
{ INET_SO_OOBINLINE, SO_OOBINLINE },
|
||||
{ INET_SO_REUSEPORT, SO_REUSEPORT },
|
||||
{ INET_SO_TIMESTAMP, SO_TIMESTAMP },
|
||||
// { INET_SO_ONESBCAST, INET_SO_ONESBCAST },
|
||||
{ INET_SO_SNDBUF, SO_SNDBUF },
|
||||
{ INET_SO_RCVBUF, SO_RCVBUF },
|
||||
{ INET_SO_SNDLOWAT, SO_SNDLOWAT },
|
||||
{ INET_SO_RCVLOWAT, SO_RCVLOWAT },
|
||||
{ INET_SO_SNDTIMEO, SO_SNDTIMEO },
|
||||
{ INET_SO_RCVTIMEO, SO_RCVTIMEO },
|
||||
{ INET_SO_ERROR, SO_ERROR },
|
||||
{ INET_SO_TYPE, SO_TYPE },
|
||||
// { INET_SO_OVERFLOWED, INET_SO_OVERFLOWED },
|
||||
{ INET_SO_NONBLOCK, INET_SO_NONBLOCK },
|
||||
};
|
||||
|
||||
enum InetLimit {
|
||||
PSP_NET_INET_SOMAXCONN = 128,
|
||||
};
|
||||
|
||||
enum InetMessageFlag {
|
||||
INET_MSG_OOB = 1,
|
||||
INET_MSG_PEEK = 1 << 1,
|
||||
INET_MSG_DONTROUTE = 1 << 2,
|
||||
INET_MSG_EOR = 1 << 3,
|
||||
INET_MSG_TRUNC = 1 << 4,
|
||||
INET_MSG_CTRUNC = 1 << 5,
|
||||
INET_MSG_WAITALL = 1 << 6,
|
||||
INET_MSG_DONTWAIT = 1 << 7,
|
||||
INET_MSG_BCAST = 1 << 8,
|
||||
INET_MSG_MCAST = 1 << 9
|
||||
};
|
||||
|
||||
// TODO: move to better place
|
||||
static std::unordered_map<InetMessageFlag, int> gInetMessageFlagToNativeMessageFlag = {
|
||||
{ INET_MSG_OOB, MSG_OOB },
|
||||
{ INET_MSG_PEEK, MSG_PEEK },
|
||||
{ INET_MSG_DONTROUTE, MSG_DONTROUTE },
|
||||
#if defined(MSG_EOR)
|
||||
{ INET_MSG_EOR, MSG_EOR },
|
||||
#endif
|
||||
{ INET_MSG_TRUNC, MSG_TRUNC },
|
||||
{ INET_MSG_CTRUNC, MSG_CTRUNC },
|
||||
{ INET_MSG_WAITALL, MSG_WAITALL },
|
||||
{ INET_MSG_DONTWAIT, MSG_DONTWAIT },
|
||||
#if defined(MSG_BCAST)
|
||||
{ INET_MSG_BCAST, MSG_BCAST },
|
||||
#endif
|
||||
#if defined(MSG_MCAST)
|
||||
{ INET_MSG_MCAST, MSG_MCAST },
|
||||
#endif
|
||||
};
|
||||
|
||||
enum InetErrorCode {
|
||||
INET_EINPROGRESS = 119,
|
||||
};
|
||||
|
||||
static std::unordered_map<int, InetErrorCode> gNativeErrorCodeToInetErrorCode = {
|
||||
{ EINPROGRESS, INET_EINPROGRESS }
|
||||
};
|
||||
|
||||
// TODO: document
|
||||
class InetSocket {
|
||||
public:
|
||||
InetSocket(int sceSocketId, int nativeSocketId) : mInetSocketId(sceSocketId), mNativeSocketId(nativeSocketId) {}
|
||||
InetSocket(int sceSocketId, int nativeSocketId, int protocol, bool nonBlocking) :
|
||||
mInetSocketId(sceSocketId),
|
||||
mNativeSocketId(nativeSocketId),
|
||||
mProtocol(protocol),
|
||||
mNonBlocking(nonBlocking) {}
|
||||
|
||||
int GetInetSocketId() const {
|
||||
return mInetSocketId;
|
||||
}
|
||||
int GetInetSocketId() const {
|
||||
return mInetSocketId;
|
||||
}
|
||||
|
||||
int GetNativeSocketId() const {
|
||||
return mNativeSocketId;
|
||||
}
|
||||
int GetNativeSocketId() const {
|
||||
return mNativeSocketId;
|
||||
}
|
||||
|
||||
// TODO: get mask of options
|
||||
bool IsNonBlocking() const {
|
||||
return mNonBlocking;
|
||||
}
|
||||
|
||||
bool IsNonBlocking() const {
|
||||
return mNonBlocking;
|
||||
}
|
||||
|
||||
void SetNonBlocking(const bool nonBlocking) {
|
||||
mNonBlocking = nonBlocking;
|
||||
}
|
||||
|
||||
Protocol GetProtocol() const {
|
||||
return mProtocol;
|
||||
}
|
||||
|
||||
void SetProtocol(const Protocol protocol) {
|
||||
mProtocol = protocol;
|
||||
}
|
||||
|
||||
// TODO: Move me
|
||||
static bool IsSockoptNameAllowed(const int optname) {
|
||||
return gInetSocketOptnameToNativeOptname.find(static_cast<InetSocketOptionName>(optname)) != gInetSocketOptnameToNativeOptname.end();
|
||||
}
|
||||
|
||||
// TODO: rename this or the other
|
||||
static int TranslateInetOptnameToNativeOptname(const InetSocketOptionName inetOptname) {
|
||||
const auto it = gInetSocketOptnameToNativeOptname.find(inetOptname);
|
||||
if (it == gInetSocketOptnameToNativeOptname.end()) {
|
||||
return inetOptname;
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
|
||||
int TranslateInetFlagsToNativeFlags(const int messageFlags) const {
|
||||
int nativeFlags = 0; // The actual platform flags
|
||||
int foundFlags = 0; // The inet equivalent of the native flags, used to verify that no remaining flags need to be set
|
||||
for (const auto [inetFlag, nativeFlag] : gInetMessageFlagToNativeMessageFlag) {
|
||||
if ((messageFlags & inetFlag) != 0) {
|
||||
nativeFlags |= nativeFlag;
|
||||
foundFlags |= inetFlag;
|
||||
}
|
||||
}
|
||||
|
||||
#if !PPSSPP_PLATFORM(WINDOWS)
|
||||
if (this->IsNonBlocking()) {
|
||||
nativeFlags |= MSG_DONTWAIT;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Check for any inet flags which were not successfully mapped into a native flag
|
||||
if (const int missingFlags = messageFlags & ~foundFlags; missingFlags != 0) {
|
||||
for (int i = 0; i < sizeof(int) * 8; i++) {
|
||||
if (const int val = 1 << i; (missingFlags & val) != 0) {
|
||||
DEBUG_LOG(Log::sceNet, "Encountered unsupported platform flag at bit %i (actual value %04x), undefined behavior may ensue.", i, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
// DEBUG_LOG(SCENET, "Translated %04x to %04x", messageFlags, nativeFlags);
|
||||
return nativeFlags;
|
||||
}
|
||||
|
||||
// TODO: consider moving to SceNetInet
|
||||
static int TranslateNativeErrorToInetError(const int nativeError) {
|
||||
if (const auto it = gNativeErrorCodeToInetErrorCode.find(nativeError);
|
||||
it != gNativeErrorCodeToInetErrorCode.end()) {
|
||||
return it->second;
|
||||
}
|
||||
return nativeError;
|
||||
}
|
||||
void SetNonBlocking(const bool nonBlocking) {
|
||||
mNonBlocking = nonBlocking;
|
||||
}
|
||||
|
||||
// TODO: document that this is the native protocol
|
||||
int GetProtocol() const {
|
||||
return mProtocol;
|
||||
}
|
||||
private:
|
||||
int mInetSocketId;
|
||||
int mNativeSocketId;
|
||||
Protocol mProtocol;
|
||||
bool mNonBlocking = false;
|
||||
int mInetSocketId;
|
||||
int mNativeSocketId;
|
||||
int mProtocol;
|
||||
bool mNonBlocking = false;
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue