mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-12-09 05:08:43 +00:00
Epoll (#3476)
* Epoll * Change companion util stub to return NO_EVENT * Revert "Change companion util stub to return NO_EVENT" This reverts commit 8dd9913cda39b641cd3b65925e1f31fa713e8a24. * added wepoll * shallow.. * dist branch * updated wepoll * compiles on windows --------- Co-authored-by: georgemoralis <giorgosmrls@gmail.com>
This commit is contained in:
committed by
GitHub
parent
0eff74223a
commit
7bd3eb485f
5
.gitmodules
vendored
5
.gitmodules
vendored
@@ -113,3 +113,8 @@
|
|||||||
path = externals/hwinfo
|
path = externals/hwinfo
|
||||||
url = https://github.com/shadps4-emu/ext-hwinfo
|
url = https://github.com/shadps4-emu/ext-hwinfo
|
||||||
shallow = true
|
shallow = true
|
||||||
|
[submodule "externals/ext-wepoll"]
|
||||||
|
path = externals/ext-wepoll
|
||||||
|
url = https://github.com/shadps4-emu/ext-wepoll.git
|
||||||
|
shallow = true
|
||||||
|
branch = dist
|
||||||
|
|||||||
@@ -380,6 +380,8 @@ set(NETWORK_LIBS src/core/libraries/network/http.cpp
|
|||||||
src/core/libraries/network/net_ctl_codes.h
|
src/core/libraries/network/net_ctl_codes.h
|
||||||
src/core/libraries/network/net_util.cpp
|
src/core/libraries/network/net_util.cpp
|
||||||
src/core/libraries/network/net_util.h
|
src/core/libraries/network/net_util.h
|
||||||
|
src/core/libraries/network/net_epoll.cpp
|
||||||
|
src/core/libraries/network/net_epoll.h
|
||||||
src/core/libraries/network/net_error.h
|
src/core/libraries/network/net_error.h
|
||||||
src/core/libraries/network/net.h
|
src/core/libraries/network/net.h
|
||||||
src/core/libraries/network/ssl.cpp
|
src/core/libraries/network/ssl.cpp
|
||||||
@@ -1222,7 +1224,7 @@ if (ENABLE_QT_GUI)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
target_link_libraries(shadps4 PRIVATE mincore)
|
target_link_libraries(shadps4 PRIVATE mincore wepoll)
|
||||||
|
|
||||||
if (MSVC)
|
if (MSVC)
|
||||||
# MSVC likes putting opinions on what people can use, disable:
|
# MSVC likes putting opinions on what people can use, disable:
|
||||||
|
|||||||
5
externals/CMakeLists.txt
vendored
5
externals/CMakeLists.txt
vendored
@@ -238,3 +238,8 @@ if (APPLE)
|
|||||||
add_subdirectory(epoll-shim)
|
add_subdirectory(epoll-shim)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
#windows only
|
||||||
|
if (WIN32)
|
||||||
|
add_subdirectory(ext-wepoll)
|
||||||
|
endif()
|
||||||
|
|||||||
1
externals/ext-wepoll
vendored
Submodule
1
externals/ext-wepoll
vendored
Submodule
Submodule externals/ext-wepoll added at d3bb810353
@@ -11,12 +11,16 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <core/libraries/kernel/kernel.h>
|
#include <core/libraries/kernel/kernel.h>
|
||||||
|
#include <magic_enum/magic_enum.hpp>
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
|
#include "common/error.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/singleton.h"
|
#include "common/singleton.h"
|
||||||
|
#include "core/file_sys/fs.h"
|
||||||
#include "core/libraries/error_codes.h"
|
#include "core/libraries/error_codes.h"
|
||||||
#include "core/libraries/libs.h"
|
#include "core/libraries/libs.h"
|
||||||
#include "core/libraries/network/net.h"
|
#include "core/libraries/network/net.h"
|
||||||
|
#include "net_epoll.h"
|
||||||
#include "net_error.h"
|
#include "net_error.h"
|
||||||
#include "net_util.h"
|
#include "net_util.h"
|
||||||
#include "netctl.h"
|
#include "netctl.h"
|
||||||
@@ -25,6 +29,8 @@
|
|||||||
|
|
||||||
namespace Libraries::Net {
|
namespace Libraries::Net {
|
||||||
|
|
||||||
|
using FDTable = Common::Singleton<Core::FileSys::HandleTable>;
|
||||||
|
|
||||||
static thread_local int32_t net_errno = 0;
|
static thread_local int32_t net_errno = 0;
|
||||||
|
|
||||||
static bool g_isNetInitialized = true; // TODO init it properly
|
static bool g_isNetInitialized = true; // TODO init it properly
|
||||||
@@ -613,28 +619,171 @@ int PS4_SYSV_ABI sceNetEpollAbort() {
|
|||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetEpollControl() {
|
int PS4_SYSV_ABI sceNetEpollControl(OrbisNetId epollid, OrbisNetEpollFlag op, OrbisNetId id,
|
||||||
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
OrbisNetEpollEvent* event) {
|
||||||
|
auto epoll = Common::Singleton<EpollTable>::Instance()->GetEpoll(epollid);
|
||||||
|
if (!epoll) {
|
||||||
|
*sceNetErrnoLoc() = ORBIS_NET_EBADF;
|
||||||
|
return ORBIS_NET_ERROR_EBADF;
|
||||||
|
}
|
||||||
|
LOG_WARNING(Lib_Net, "called, epollid = {} ({}), op = {}, id = {}", epollid, epoll->name,
|
||||||
|
magic_enum::enum_name(op), id);
|
||||||
|
|
||||||
|
auto find_id = [&](OrbisNetId id) {
|
||||||
|
return std::ranges::find_if(epoll->events, [&](const auto& el) { return el.first == id; });
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (op) {
|
||||||
|
case ORBIS_NET_EPOLL_CTL_ADD: {
|
||||||
|
if (event == nullptr) {
|
||||||
|
*sceNetErrnoLoc() = ORBIS_NET_EINVAL;
|
||||||
|
return ORBIS_NET_ERROR_EINVAL;
|
||||||
|
}
|
||||||
|
if (find_id(id) != epoll->events.end()) {
|
||||||
|
*sceNetErrnoLoc() = ORBIS_NET_EEXIST;
|
||||||
|
return ORBIS_NET_ERROR_EEXIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto file = FDTable::Instance()->GetSocket(id);
|
||||||
|
if (!file) {
|
||||||
|
*sceNetErrnoLoc() = ORBIS_NET_EBADF;
|
||||||
|
LOG_ERROR(Lib_Net, "socket id is invalid = {}", id);
|
||||||
|
return ORBIS_NET_ERROR_EBADF;
|
||||||
|
}
|
||||||
|
epoll_event native_event = {.events = ConvertEpollEventsIn(event->events),
|
||||||
|
.data = {.fd = id}};
|
||||||
|
ASSERT(epoll_ctl(epoll->epoll_fd, EPOLL_CTL_ADD, *file->socket->Native(), &native_event) ==
|
||||||
|
0);
|
||||||
|
epoll->events.emplace_back(id, *event);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ORBIS_NET_EPOLL_CTL_MOD: {
|
||||||
|
if (event == nullptr) {
|
||||||
|
*sceNetErrnoLoc() = ORBIS_NET_EINVAL;
|
||||||
|
return ORBIS_NET_ERROR_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
UNREACHABLE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ORBIS_NET_EPOLL_CTL_DEL: {
|
||||||
|
if (event != nullptr) {
|
||||||
|
*sceNetErrnoLoc() = ORBIS_NET_EINVAL;
|
||||||
|
return ORBIS_NET_ERROR_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto it = find_id(id);
|
||||||
|
if (it == epoll->events.end()) {
|
||||||
|
*sceNetErrnoLoc() = ORBIS_NET_EBADF;
|
||||||
|
return ORBIS_NET_ERROR_EBADF;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto file = FDTable::Instance()->GetSocket(id);
|
||||||
|
if (!file) {
|
||||||
|
*sceNetErrnoLoc() = ORBIS_NET_EBADF;
|
||||||
|
LOG_ERROR(Lib_Net, "socket id is invalid = {}", id);
|
||||||
|
return ORBIS_NET_ERROR_EBADF;
|
||||||
|
}
|
||||||
|
ASSERT(epoll_ctl(epoll->epoll_fd, EPOLL_CTL_DEL, *file->socket->Native(), nullptr) == 0);
|
||||||
|
epoll->events.erase(it);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
*sceNetErrnoLoc() = ORBIS_NET_EINVAL;
|
||||||
|
return ORBIS_NET_ERROR_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetEpollCreate() {
|
int PS4_SYSV_ABI sceNetEpollCreate(const char* name, int flags) {
|
||||||
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
LOG_INFO(Lib_Net, "called, name = {}, flags = {}", name, flags);
|
||||||
|
if (flags != 0) {
|
||||||
|
*sceNetErrnoLoc() = ORBIS_NET_EINVAL;
|
||||||
|
return ORBIS_NET_ERROR_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto epoll = Common::Singleton<EpollTable>::Instance()->CreateHandle(name);
|
||||||
|
|
||||||
|
return epoll;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceNetEpollDestroy(OrbisNetId epollid) {
|
||||||
|
auto epoll = Common::Singleton<EpollTable>::Instance()->GetEpoll(epollid);
|
||||||
|
if (!epoll) {
|
||||||
|
*sceNetErrnoLoc() = ORBIS_NET_EBADF;
|
||||||
|
return ORBIS_NET_ERROR_EBADF;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_INFO(Lib_Net, "called, epollid = {} ({})", epollid, epoll->name);
|
||||||
|
|
||||||
|
epoll->Destroy();
|
||||||
|
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetEpollDestroy() {
|
int PS4_SYSV_ABI sceNetEpollWait(OrbisNetId epollid, OrbisNetEpollEvent* events, int maxevents,
|
||||||
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
int timeout) {
|
||||||
return ORBIS_OK;
|
auto epoll = Common::Singleton<EpollTable>::Instance()->GetEpoll(epollid);
|
||||||
}
|
if (!epoll) {
|
||||||
|
*sceNetErrnoLoc() = ORBIS_NET_EBADF;
|
||||||
|
return ORBIS_NET_ERROR_EBADF;
|
||||||
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetEpollWait() {
|
LOG_INFO(Lib_Net, "called, epollid = {} ({}), maxevents = {}, timeout = {}", epollid,
|
||||||
LOG_TRACE(Lib_Net, "(STUBBED) called");
|
epoll->name, maxevents, timeout);
|
||||||
return ORBIS_OK;
|
|
||||||
|
std::vector<epoll_event> native_events{static_cast<size_t>(maxevents)};
|
||||||
|
#ifdef __linux__
|
||||||
|
const timespec epoll_timeout{.tv_sec = timeout / 1000000,
|
||||||
|
.tv_nsec = (timeout % 1000000) * 1000};
|
||||||
|
int result = epoll_pwait2(epoll->epoll_fd, native_events.data(), maxevents,
|
||||||
|
timeout < 0 ? nullptr : &epoll_timeout, nullptr);
|
||||||
|
#else
|
||||||
|
int result = epoll_wait(epoll->epoll_fd, native_events.data(), maxevents,
|
||||||
|
timeout < 0 ? timeout : timeout / 1000);
|
||||||
|
#endif
|
||||||
|
if (result < 0) {
|
||||||
|
LOG_ERROR(Lib_Net, "epoll_wait failed with {}", Common::GetLastErrorMsg());
|
||||||
|
switch (errno) {
|
||||||
|
case EINTR:
|
||||||
|
*sceNetErrnoLoc() = ORBIS_NET_EINTR;
|
||||||
|
return ORBIS_NET_ERROR_EINTR;
|
||||||
|
case EINVAL:
|
||||||
|
*sceNetErrnoLoc() = ORBIS_NET_EINVAL;
|
||||||
|
return ORBIS_NET_ERROR_EINVAL;
|
||||||
|
case EBADF:
|
||||||
|
*sceNetErrnoLoc() = ORBIS_NET_EBADF;
|
||||||
|
return ORBIS_NET_ERROR_EBADF;
|
||||||
|
default:
|
||||||
|
*sceNetErrnoLoc() = ORBIS_NET_EINTERNAL;
|
||||||
|
return ORBIS_NET_ERROR_EINTERNAL;
|
||||||
|
}
|
||||||
|
} else if (result == 0) {
|
||||||
|
LOG_DEBUG(Lib_Net, "timed out");
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < result; ++i) {
|
||||||
|
const auto& current_event = native_events[i];
|
||||||
|
LOG_DEBUG(Lib_Net, "native_event[{}] = ( .events = {}, .data = {:#x} )", i,
|
||||||
|
current_event.events, current_event.data.u64);
|
||||||
|
const auto it = std::ranges::find_if(
|
||||||
|
epoll->events, [&](auto& el) { return el.first == current_event.data.fd; });
|
||||||
|
ASSERT(it != epoll->events.end());
|
||||||
|
events[i] = {
|
||||||
|
.events = ConvertEpollEventsOut(current_event.events),
|
||||||
|
.ident = static_cast<u64>(current_event.data.fd),
|
||||||
|
.data = it->second.data,
|
||||||
|
};
|
||||||
|
LOG_DEBUG(Lib_Net, "event[{}] = ( .events = {:#x}, .ident = {}, .data = {:#x} )", i,
|
||||||
|
events[i].events, events[i].ident, events[i].data.data_u64);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int* PS4_SYSV_ABI sceNetErrnoLoc() {
|
int* PS4_SYSV_ABI sceNetErrnoLoc() {
|
||||||
LOG_DEBUG(Lib_Net, "called");
|
LOG_TRACE(Lib_Net, "called");
|
||||||
return &net_errno;
|
return &net_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -713,6 +862,8 @@ int PS4_SYSV_ABI sceNetGetMacAddress(Libraries::NetCtl::OrbisNetEtherAddr* addr,
|
|||||||
LOG_ERROR(Lib_Net, "addr is null!");
|
LOG_ERROR(Lib_Net, "addr is null!");
|
||||||
return ORBIS_NET_EINVAL;
|
return ORBIS_NET_EINVAL;
|
||||||
}
|
}
|
||||||
|
LOG_DEBUG(Lib_Net, "called");
|
||||||
|
|
||||||
auto* netinfo = Common::Singleton<NetUtil::NetUtilInternal>::Instance();
|
auto* netinfo = Common::Singleton<NetUtil::NetUtilInternal>::Instance();
|
||||||
netinfo->RetrieveEthernetAddr();
|
netinfo->RetrieveEthernetAddr();
|
||||||
memcpy(addr->data, netinfo->GetEthernetAddr().data(), 6);
|
memcpy(addr->data, netinfo->GetEthernetAddr().data(), 6);
|
||||||
@@ -767,7 +918,6 @@ int PS4_SYSV_ABI sceNetGetsockname(OrbisNetId s, OrbisNetSockaddr* addr, u32* pa
|
|||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetGetsockopt(OrbisNetId s, int level, int optname, void* optval, u32* optlen) {
|
int PS4_SYSV_ABI sceNetGetsockopt(OrbisNetId s, int level, int optname, void* optval, u32* optlen) {
|
||||||
LOG_INFO(Lib_Net, "s={} level={} optname={}", s, level, optname);
|
|
||||||
if (!g_isNetInitialized) {
|
if (!g_isNetInitialized) {
|
||||||
return ORBIS_NET_ERROR_ENOTINIT;
|
return ORBIS_NET_ERROR_ENOTINIT;
|
||||||
}
|
}
|
||||||
@@ -926,6 +1076,7 @@ const char* PS4_SYSV_ABI sceNetInetNtop(int af, const void* src, char* dst, u32
|
|||||||
LOG_ERROR(Lib_Net, "returned ORBIS_NET_ENOSPC");
|
LOG_ERROR(Lib_Net, "returned ORBIS_NET_ENOSPC");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* returnvalue = nullptr;
|
const char* returnvalue = nullptr;
|
||||||
switch (af) {
|
switch (af) {
|
||||||
case ORBIS_NET_AF_INET:
|
case ORBIS_NET_AF_INET:
|
||||||
@@ -942,6 +1093,8 @@ const char* PS4_SYSV_ABI sceNetInetNtop(int af, const void* src, char* dst, u32
|
|||||||
if (returnvalue == nullptr) {
|
if (returnvalue == nullptr) {
|
||||||
*sceNetErrnoLoc() = ORBIS_NET_ENOSPC;
|
*sceNetErrnoLoc() = ORBIS_NET_ENOSPC;
|
||||||
LOG_ERROR(Lib_Net, "returned ORBIS_NET_ENOSPC");
|
LOG_ERROR(Lib_Net, "returned ORBIS_NET_ENOSPC");
|
||||||
|
} else {
|
||||||
|
LOG_DEBUG(Lib_Net, "{}: {}", magic_enum::enum_name((OrbisNetFamily)af), dst);
|
||||||
}
|
}
|
||||||
return returnvalue;
|
return returnvalue;
|
||||||
}
|
}
|
||||||
@@ -1241,7 +1394,6 @@ int PS4_SYSV_ABI sceNetSetDnsInfoToKernel() {
|
|||||||
|
|
||||||
int PS4_SYSV_ABI sceNetSetsockopt(OrbisNetId s, int level, int optname, const void* optval,
|
int PS4_SYSV_ABI sceNetSetsockopt(OrbisNetId s, int level, int optname, const void* optval,
|
||||||
u32 optlen) {
|
u32 optlen) {
|
||||||
LOG_INFO(Lib_Net, "s={} level={} optname={} optlen={}", s, level, optname, optlen);
|
|
||||||
if (!g_isNetInitialized) {
|
if (!g_isNetInitialized) {
|
||||||
return ORBIS_NET_ERROR_ENOTINIT;
|
return ORBIS_NET_ERROR_ENOTINIT;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "common/assert.h"
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
#include "netctl.h"
|
#include "netctl.h"
|
||||||
|
|
||||||
@@ -45,8 +46,28 @@ enum OrbisNetProtocol : u32 {
|
|||||||
ORBIS_NET_SOL_SOCKET = 0xFFFF
|
ORBIS_NET_SOL_SOCKET = 0xFFFF
|
||||||
};
|
};
|
||||||
|
|
||||||
enum OrbisNetSocketOption : u32 {
|
constexpr std::string_view NameOf(OrbisNetProtocol p) {
|
||||||
/* IP */
|
switch (p) {
|
||||||
|
case ORBIS_NET_IPPROTO_IP:
|
||||||
|
return "ORBIS_NET_IPPROTO_IP";
|
||||||
|
case ORBIS_NET_IPPROTO_ICMP:
|
||||||
|
return "ORBIS_NET_IPPROTO_ICMP";
|
||||||
|
case ORBIS_NET_IPPROTO_IGMP:
|
||||||
|
return "ORBIS_NET_IPPROTO_IGMP";
|
||||||
|
case ORBIS_NET_IPPROTO_TCP:
|
||||||
|
return "ORBIS_NET_IPPROTO_TCP";
|
||||||
|
case ORBIS_NET_IPPROTO_UDP:
|
||||||
|
return "ORBIS_NET_IPPROTO_UDP";
|
||||||
|
case ORBIS_NET_IPPROTO_IPV6:
|
||||||
|
return "ORBIS_NET_IPPROTO_IPV6";
|
||||||
|
case ORBIS_NET_SOL_SOCKET:
|
||||||
|
return "ORBIS_NET_SOL_SOCKET";
|
||||||
|
default:
|
||||||
|
UNREACHABLE_MSG("{}", (u32)p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum OrbisNetSocketIpOption : u32 {
|
||||||
ORBIS_NET_IP_HDRINCL = 2,
|
ORBIS_NET_IP_HDRINCL = 2,
|
||||||
ORBIS_NET_IP_TOS = 3,
|
ORBIS_NET_IP_TOS = 3,
|
||||||
ORBIS_NET_IP_TTL = 4,
|
ORBIS_NET_IP_TTL = 4,
|
||||||
@@ -57,11 +78,15 @@ enum OrbisNetSocketOption : u32 {
|
|||||||
ORBIS_NET_IP_DROP_MEMBERSHIP = 13,
|
ORBIS_NET_IP_DROP_MEMBERSHIP = 13,
|
||||||
ORBIS_NET_IP_TTLCHK = 23,
|
ORBIS_NET_IP_TTLCHK = 23,
|
||||||
ORBIS_NET_IP_MAXTTL = 24,
|
ORBIS_NET_IP_MAXTTL = 24,
|
||||||
/* TCP */
|
};
|
||||||
|
|
||||||
|
enum OrbisNetSocketTcpOption : u32 {
|
||||||
ORBIS_NET_TCP_NODELAY = 1,
|
ORBIS_NET_TCP_NODELAY = 1,
|
||||||
ORBIS_NET_TCP_MAXSEG = 2,
|
ORBIS_NET_TCP_MAXSEG = 2,
|
||||||
ORBIS_NET_TCP_MSS_TO_ADVERTISE = 3,
|
ORBIS_NET_TCP_MSS_TO_ADVERTISE = 3,
|
||||||
/* SOCKET */
|
};
|
||||||
|
|
||||||
|
enum OrbisNetSocketSoOption : u32 {
|
||||||
ORBIS_NET_SO_REUSEADDR = 0x00000004,
|
ORBIS_NET_SO_REUSEADDR = 0x00000004,
|
||||||
ORBIS_NET_SO_KEEPALIVE = 0x00000008,
|
ORBIS_NET_SO_KEEPALIVE = 0x00000008,
|
||||||
ORBIS_NET_SO_BROADCAST = 0x00000020,
|
ORBIS_NET_SO_BROADCAST = 0x00000020,
|
||||||
@@ -85,6 +110,55 @@ enum OrbisNetSocketOption : u32 {
|
|||||||
ORBIS_NET_SO_PRIORITY = 0x1203
|
ORBIS_NET_SO_PRIORITY = 0x1203
|
||||||
};
|
};
|
||||||
|
|
||||||
|
constexpr std::string_view NameOf(OrbisNetSocketSoOption o) {
|
||||||
|
switch (o) {
|
||||||
|
case ORBIS_NET_SO_REUSEADDR:
|
||||||
|
return "ORBIS_NET_SO_REUSEADDR";
|
||||||
|
case ORBIS_NET_SO_KEEPALIVE:
|
||||||
|
return "ORBIS_NET_SO_KEEPALIVE";
|
||||||
|
case ORBIS_NET_SO_BROADCAST:
|
||||||
|
return "ORBIS_NET_SO_BROADCAST";
|
||||||
|
case ORBIS_NET_SO_LINGER:
|
||||||
|
return "ORBIS_NET_SO_LINGER";
|
||||||
|
case ORBIS_NET_SO_REUSEPORT:
|
||||||
|
return "ORBIS_NET_SO_REUSEPORT";
|
||||||
|
case ORBIS_NET_SO_ONESBCAST:
|
||||||
|
return "ORBIS_NET_SO_ONESBCAST";
|
||||||
|
case ORBIS_NET_SO_USECRYPTO:
|
||||||
|
return "ORBIS_NET_SO_USECRYPTO";
|
||||||
|
case ORBIS_NET_SO_USESIGNATURE:
|
||||||
|
return "ORBIS_NET_SO_USESIGNATURE";
|
||||||
|
case ORBIS_NET_SO_SNDBUF:
|
||||||
|
return "ORBIS_NET_SO_SNDBUF";
|
||||||
|
case ORBIS_NET_SO_RCVBUF:
|
||||||
|
return "ORBIS_NET_SO_RCVBUF";
|
||||||
|
case ORBIS_NET_SO_ERROR:
|
||||||
|
return "ORBIS_NET_SO_ERROR";
|
||||||
|
case ORBIS_NET_SO_TYPE:
|
||||||
|
return "ORBIS_NET_SO_TYPE";
|
||||||
|
case ORBIS_NET_SO_SNDTIMEO:
|
||||||
|
return "ORBIS_NET_SO_SNDTIMEO";
|
||||||
|
case ORBIS_NET_SO_RCVTIMEO:
|
||||||
|
return "ORBIS_NET_SO_RCVTIMEO";
|
||||||
|
case ORBIS_NET_SO_ERROR_EX:
|
||||||
|
return "ORBIS_NET_SO_ERROR_EX";
|
||||||
|
case ORBIS_NET_SO_ACCEPTTIMEO:
|
||||||
|
return "ORBIS_NET_SO_ACCEPTTIMEO";
|
||||||
|
case ORBIS_NET_SO_CONNECTTIMEO:
|
||||||
|
return "ORBIS_NET_SO_CONNECTTIMEO";
|
||||||
|
case ORBIS_NET_SO_NBIO:
|
||||||
|
return "ORBIS_NET_SO_NBIO";
|
||||||
|
case ORBIS_NET_SO_POLICY:
|
||||||
|
return "ORBIS_NET_SO_POLICY";
|
||||||
|
case ORBIS_NET_SO_NAME:
|
||||||
|
return "ORBIS_NET_SO_NAME";
|
||||||
|
case ORBIS_NET_SO_PRIORITY:
|
||||||
|
return "ORBIS_NET_SO_PRIORITY";
|
||||||
|
default:
|
||||||
|
UNREACHABLE_MSG("{}", (u32)o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
enum OrbisNetEpollFlag : u32 {
|
enum OrbisNetEpollFlag : u32 {
|
||||||
ORBIS_NET_EPOLL_CTL_ADD = 1,
|
ORBIS_NET_EPOLL_CTL_ADD = 1,
|
||||||
ORBIS_NET_EPOLL_CTL_MOD = 2,
|
ORBIS_NET_EPOLL_CTL_MOD = 2,
|
||||||
@@ -285,10 +359,12 @@ int PS4_SYSV_ABI sceNetDumpRead();
|
|||||||
int PS4_SYSV_ABI sceNetDuplicateIpStart();
|
int PS4_SYSV_ABI sceNetDuplicateIpStart();
|
||||||
int PS4_SYSV_ABI sceNetDuplicateIpStop();
|
int PS4_SYSV_ABI sceNetDuplicateIpStop();
|
||||||
int PS4_SYSV_ABI sceNetEpollAbort();
|
int PS4_SYSV_ABI sceNetEpollAbort();
|
||||||
int PS4_SYSV_ABI sceNetEpollControl();
|
int PS4_SYSV_ABI sceNetEpollControl(OrbisNetId epollid, OrbisNetEpollFlag op, OrbisNetId id,
|
||||||
int PS4_SYSV_ABI sceNetEpollCreate();
|
OrbisNetEpollEvent* event);
|
||||||
int PS4_SYSV_ABI sceNetEpollDestroy();
|
int PS4_SYSV_ABI sceNetEpollCreate(const char* name, int flags);
|
||||||
int PS4_SYSV_ABI sceNetEpollWait();
|
int PS4_SYSV_ABI sceNetEpollDestroy(OrbisNetId epollid);
|
||||||
|
int PS4_SYSV_ABI sceNetEpollWait(OrbisNetId epollid, OrbisNetEpollEvent* events, int maxevents,
|
||||||
|
int timeout);
|
||||||
int* PS4_SYSV_ABI sceNetErrnoLoc();
|
int* PS4_SYSV_ABI sceNetErrnoLoc();
|
||||||
int PS4_SYSV_ABI sceNetEtherNtostr();
|
int PS4_SYSV_ABI sceNetEtherNtostr();
|
||||||
int PS4_SYSV_ABI sceNetEtherStrton();
|
int PS4_SYSV_ABI sceNetEtherStrton();
|
||||||
|
|||||||
72
src/core/libraries/network/net_epoll.cpp
Normal file
72
src/core/libraries/network/net_epoll.cpp
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "common/assert.h"
|
||||||
|
#include "common/types.h"
|
||||||
|
#include "net_epoll.h"
|
||||||
|
|
||||||
|
namespace Libraries::Net {
|
||||||
|
|
||||||
|
u32 ConvertEpollEventsIn(u32 orbis_events) {
|
||||||
|
u32 ret = 0;
|
||||||
|
|
||||||
|
if ((orbis_events & ORBIS_NET_EPOLLIN) != 0) {
|
||||||
|
ret |= EPOLLIN;
|
||||||
|
}
|
||||||
|
if ((orbis_events & ORBIS_NET_EPOLLOUT) != 0) {
|
||||||
|
ret |= EPOLLOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 ConvertEpollEventsOut(u32 epoll_events) {
|
||||||
|
u32 ret = 0;
|
||||||
|
|
||||||
|
if ((epoll_events & EPOLLIN) != 0) {
|
||||||
|
ret |= ORBIS_NET_EPOLLIN;
|
||||||
|
}
|
||||||
|
if ((epoll_events & EPOLLOUT) != 0) {
|
||||||
|
ret |= ORBIS_NET_EPOLLOUT;
|
||||||
|
}
|
||||||
|
if ((epoll_events & EPOLLERR) != 0) {
|
||||||
|
ret |= ORBIS_NET_EPOLLERR;
|
||||||
|
}
|
||||||
|
if ((epoll_events & EPOLLHUP) != 0) {
|
||||||
|
ret |= ORBIS_NET_EPOLLHUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int EpollTable::CreateHandle(const char* name) {
|
||||||
|
std::scoped_lock lock{m_mutex};
|
||||||
|
|
||||||
|
if (auto it = std::ranges::find_if(epolls, [](const Epoll& e) { return e.Destroyed(); });
|
||||||
|
it != epolls.end()) {
|
||||||
|
*it = Epoll(name);
|
||||||
|
const auto ret = std::distance(epolls.begin(), it);
|
||||||
|
LOG_DEBUG(Lib_Net, "epollid = {}", ret);
|
||||||
|
return ret;
|
||||||
|
} else {
|
||||||
|
epolls.emplace_back(name);
|
||||||
|
const auto ret = epolls.size() - 1;
|
||||||
|
LOG_DEBUG(Lib_Net, "epollid = {}", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EpollTable::DeleteHandle(int d) {
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
|
||||||
|
Epoll* EpollTable::GetEpoll(int epollid) {
|
||||||
|
std::scoped_lock lock{m_mutex};
|
||||||
|
if (epollid >= epolls.size() || epolls[epollid].Destroyed()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &epolls[epollid];
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Libraries::Net
|
||||||
83
src/core/libraries/network/net_epoll.h
Normal file
83
src/core/libraries/network/net_epoll.h
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "common/types.h"
|
||||||
|
#include "core/libraries/network/net.h"
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <wepoll.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__linux__) || defined(__APPLE__)
|
||||||
|
#include <sys/epoll.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace Libraries::Net {
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
using epoll_handle = HANDLE;
|
||||||
|
#else
|
||||||
|
using epoll_handle = int;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct Epoll {
|
||||||
|
std::vector<std::pair<u32 /*netId*/, OrbisNetEpollEvent>> events{};
|
||||||
|
const char* name;
|
||||||
|
epoll_handle epoll_fd;
|
||||||
|
|
||||||
|
explicit Epoll(const char* name_) : name(name_), epoll_fd(epoll_create1(0)) {
|
||||||
|
#ifdef _WIN32
|
||||||
|
ASSERT(epoll_fd != nullptr);
|
||||||
|
#else
|
||||||
|
ASSERT(epoll_fd != -1);
|
||||||
|
#endif
|
||||||
|
if (name == nullptr) {
|
||||||
|
name = "anon";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Destroyed() const noexcept {
|
||||||
|
return destroyed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Destroy() noexcept {
|
||||||
|
events.clear();
|
||||||
|
#ifdef _WIN32
|
||||||
|
epoll_fd = nullptr;
|
||||||
|
epoll_close(epoll_fd);
|
||||||
|
#else
|
||||||
|
epoll_fd = -1;
|
||||||
|
close(epoll_fd);
|
||||||
|
#endif
|
||||||
|
name = "";
|
||||||
|
destroyed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool destroyed{};
|
||||||
|
};
|
||||||
|
|
||||||
|
u32 ConvertEpollEventsIn(u32 orbis_events);
|
||||||
|
u32 ConvertEpollEventsOut(u32 epoll_events);
|
||||||
|
|
||||||
|
class EpollTable {
|
||||||
|
public:
|
||||||
|
EpollTable() = default;
|
||||||
|
virtual ~EpollTable() = default;
|
||||||
|
|
||||||
|
int CreateHandle(const char* name);
|
||||||
|
void DeleteHandle(int d);
|
||||||
|
Epoll* GetEpoll(int d);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<Epoll> epolls;
|
||||||
|
std::mutex m_mutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Libraries::Net
|
||||||
@@ -286,12 +286,9 @@ int PosixSocket::Connect(const OrbisNetSockaddr* addr, u32 namelen) {
|
|||||||
std::scoped_lock lock{m_mutex};
|
std::scoped_lock lock{m_mutex};
|
||||||
sockaddr addr2;
|
sockaddr addr2;
|
||||||
convertOrbisNetSockaddrToPosix(addr, &addr2);
|
convertOrbisNetSockaddrToPosix(addr, &addr2);
|
||||||
int result = 0;
|
int result = ::connect(sock, &addr2, sizeof(sockaddr_in));
|
||||||
do {
|
LOG_DEBUG(Lib_Net, "raw connect result = {}, errno = {}", result,
|
||||||
result = ::connect(sock, &addr2, sizeof(sockaddr_in));
|
result == -1 ? Common::GetLastErrorMsg() : "none");
|
||||||
LOG_DEBUG(Lib_Net, "raw connect result = {}, errno = {}", result,
|
|
||||||
result == -1 ? Common::GetLastErrorMsg() : "none");
|
|
||||||
} while (result == -1 && (errno == EINTR || errno == EINPROGRESS));
|
|
||||||
return ConvertReturnErrorCode(result);
|
return ConvertReturnErrorCode(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -526,7 +523,6 @@ int PosixSocket::GetSocketOptions(int level, int optname, void* optval, u32* opt
|
|||||||
|
|
||||||
int PosixSocket::GetPeerName(OrbisNetSockaddr* name, u32* namelen) {
|
int PosixSocket::GetPeerName(OrbisNetSockaddr* name, u32* namelen) {
|
||||||
std::scoped_lock lock{m_mutex};
|
std::scoped_lock lock{m_mutex};
|
||||||
LOG_DEBUG(Lib_Net, "called");
|
|
||||||
|
|
||||||
sockaddr addr;
|
sockaddr addr;
|
||||||
convertOrbisNetSockaddrToPosix(name, &addr);
|
convertOrbisNetSockaddrToPosix(name, &addr);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <common/assert.h>
|
#include <common/assert.h>
|
||||||
#include <common/logging/log.h>
|
#include <common/logging/log.h>
|
||||||
#include <core/libraries/kernel/kernel.h>
|
#include <core/libraries/kernel/kernel.h>
|
||||||
|
#include <magic_enum/magic_enum.hpp>
|
||||||
#include "common/error.h"
|
#include "common/error.h"
|
||||||
#include "common/singleton.h"
|
#include "common/singleton.h"
|
||||||
#include "core/file_sys/fs.h"
|
#include "core/file_sys/fs.h"
|
||||||
@@ -22,11 +23,13 @@ int PS4_SYSV_ABI sys_connect(OrbisNetId s, const OrbisNetSockaddr* addr, u32 add
|
|||||||
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
LOG_DEBUG(Lib_Net, "s = {} ({})", s, file->m_guest_name);
|
||||||
int returncode = file->socket->Connect(addr, addrlen);
|
int returncode = file->socket->Connect(addr, addrlen);
|
||||||
if (returncode >= 0) {
|
if (returncode >= 0) {
|
||||||
return returncode;
|
return returncode;
|
||||||
}
|
}
|
||||||
LOG_ERROR(Lib_Net, "error code returned: {}", (u32)*Libraries::Kernel::__Error());
|
LOG_ERROR(Lib_Net, "s = {} ({}) returned error code: {}", s, file->m_guest_name,
|
||||||
|
(u32)*Libraries::Kernel::__Error());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,6 +40,7 @@ int PS4_SYSV_ABI sys_bind(OrbisNetId s, const OrbisNetSockaddr* addr, u32 addrle
|
|||||||
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
LOG_DEBUG(Lib_Net, "s = {} ({})", s, file->m_guest_name);
|
||||||
int returncode = file->socket->Bind(addr, addrlen);
|
int returncode = file->socket->Bind(addr, addrlen);
|
||||||
if (returncode >= 0) {
|
if (returncode >= 0) {
|
||||||
return returncode;
|
return returncode;
|
||||||
@@ -52,10 +56,11 @@ int PS4_SYSV_ABI sys_accept(OrbisNetId s, OrbisNetSockaddr* addr, u32* paddrlen)
|
|||||||
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
LOG_DEBUG(Lib_Net, "s = {} ({})", s, file->m_guest_name);
|
||||||
auto new_sock = file->socket->Accept(addr, paddrlen);
|
auto new_sock = file->socket->Accept(addr, paddrlen);
|
||||||
if (!new_sock) {
|
if (!new_sock) {
|
||||||
LOG_ERROR(Lib_Net, "error creating new socket for accepting: {:#x}",
|
LOG_ERROR(Lib_Net, "s = {} ({}) returned error code creating new socket for accepting: {}",
|
||||||
(u32)*Libraries::Kernel::__Error());
|
s, file->m_guest_name, (u32)*Libraries::Kernel::__Error());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
auto fd = FDTable::Instance()->CreateHandle();
|
auto fd = FDTable::Instance()->CreateHandle();
|
||||||
@@ -67,14 +72,13 @@ int PS4_SYSV_ABI sys_accept(OrbisNetId s, OrbisNetSockaddr* addr, u32* paddrlen)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sys_getpeername(OrbisNetId s, OrbisNetSockaddr* addr, u32* paddrlen) {
|
int PS4_SYSV_ABI sys_getpeername(OrbisNetId s, OrbisNetSockaddr* addr, u32* paddrlen) {
|
||||||
LOG_INFO(Lib_Net, "s = {}", s);
|
|
||||||
|
|
||||||
auto file = FDTable::Instance()->GetSocket(s);
|
auto file = FDTable::Instance()->GetSocket(s);
|
||||||
if (!file) {
|
if (!file) {
|
||||||
*Libraries::Kernel::__Error() = ORBIS_NET_EBADF;
|
*Libraries::Kernel::__Error() = ORBIS_NET_EBADF;
|
||||||
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
LOG_DEBUG(Lib_Net, "s = {} ({})", s, file->m_guest_name);
|
||||||
int returncode = file->socket->GetPeerName(addr, paddrlen);
|
int returncode = file->socket->GetPeerName(addr, paddrlen);
|
||||||
if (returncode >= 0) {
|
if (returncode >= 0) {
|
||||||
return returncode;
|
return returncode;
|
||||||
@@ -90,6 +94,7 @@ int PS4_SYSV_ABI sys_getsockname(OrbisNetId s, OrbisNetSockaddr* addr, u32* padd
|
|||||||
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
LOG_DEBUG(Lib_Net, "s = {} ({})", s, file->m_guest_name);
|
||||||
int returncode = file->socket->GetSocketAddress(addr, paddrlen);
|
int returncode = file->socket->GetSocketAddress(addr, paddrlen);
|
||||||
if (returncode >= 0) {
|
if (returncode >= 0) {
|
||||||
return returncode;
|
return returncode;
|
||||||
@@ -105,8 +110,25 @@ int PS4_SYSV_ABI sys_getsockopt(OrbisNetId s, int level, int optname, void* optv
|
|||||||
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
auto name = [&] -> std::string_view {
|
||||||
|
switch (level) {
|
||||||
|
case ORBIS_NET_SOL_SOCKET:
|
||||||
|
return NameOf((OrbisNetSocketSoOption)optname);
|
||||||
|
case ORBIS_NET_IPPROTO_IP:
|
||||||
|
return magic_enum::enum_name((OrbisNetSocketIpOption)optname);
|
||||||
|
case ORBIS_NET_IPPROTO_TCP:
|
||||||
|
return magic_enum::enum_name((OrbisNetSocketTcpOption)optname);
|
||||||
|
default:
|
||||||
|
return std::string_view{"unknown"};
|
||||||
|
}
|
||||||
|
}();
|
||||||
|
LOG_DEBUG(Lib_Net, "s = {} ({}), level = {}, optname = {}", s, file->m_guest_name,
|
||||||
|
NameOf((OrbisNetProtocol)level), name);
|
||||||
int returncode = file->socket->GetSocketOptions(level, optname, optval, optlen);
|
int returncode = file->socket->GetSocketOptions(level, optname, optval, optlen);
|
||||||
if (returncode >= 0) {
|
if (returncode >= 0) {
|
||||||
|
if (optname == ORBIS_NET_SO_ERROR) {
|
||||||
|
LOG_DEBUG(Lib_Net, "so_error = {}", *reinterpret_cast<s32*>(optval));
|
||||||
|
}
|
||||||
return returncode;
|
return returncode;
|
||||||
}
|
}
|
||||||
LOG_ERROR(Lib_Net, "error code returned: {}", (u32)*Libraries::Kernel::__Error());
|
LOG_ERROR(Lib_Net, "error code returned: {}", (u32)*Libraries::Kernel::__Error());
|
||||||
@@ -120,6 +142,7 @@ int PS4_SYSV_ABI sys_listen(OrbisNetId s, int backlog) {
|
|||||||
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
LOG_DEBUG(Lib_Net, "s = {} ({}), backlog = {}", s, file->m_guest_name, backlog);
|
||||||
int returncode = file->socket->Listen(backlog);
|
int returncode = file->socket->Listen(backlog);
|
||||||
if (returncode >= 0) {
|
if (returncode >= 0) {
|
||||||
return returncode;
|
return returncode;
|
||||||
@@ -136,6 +159,20 @@ int PS4_SYSV_ABI sys_setsockopt(OrbisNetId s, int level, int optname, const void
|
|||||||
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
auto name = [&] -> std::string_view {
|
||||||
|
switch (level) {
|
||||||
|
case ORBIS_NET_SOL_SOCKET:
|
||||||
|
return NameOf((OrbisNetSocketSoOption)optname);
|
||||||
|
case ORBIS_NET_IPPROTO_IP:
|
||||||
|
return magic_enum::enum_name((OrbisNetSocketIpOption)optname);
|
||||||
|
case ORBIS_NET_IPPROTO_TCP:
|
||||||
|
return magic_enum::enum_name((OrbisNetSocketTcpOption)optname);
|
||||||
|
default:
|
||||||
|
return std::string_view{"unknown"};
|
||||||
|
}
|
||||||
|
}();
|
||||||
|
LOG_DEBUG(Lib_Net, "s = {} ({}), level = {}, optname = {}", s, file->m_guest_name,
|
||||||
|
NameOf((OrbisNetProtocol)level), name);
|
||||||
int returncode = file->socket->SetSocketOptions(level, optname, optval, optlen);
|
int returncode = file->socket->SetSocketOptions(level, optname, optval, optlen);
|
||||||
if (returncode >= 0) {
|
if (returncode >= 0) {
|
||||||
return returncode;
|
return returncode;
|
||||||
@@ -149,13 +186,10 @@ int PS4_SYSV_ABI sys_shutdown(OrbisNetId s, int how) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sys_socketex(const char* name, int family, int type, int protocol) {
|
int PS4_SYSV_ABI sys_socketex(const char* name, int family, int type, int protocol) {
|
||||||
if (name == nullptr) {
|
auto sname = name ? name : "anon";
|
||||||
LOG_INFO(Lib_Net, "name = no-named family = {} type = {} protocol = {}", family, type,
|
LOG_INFO(Lib_Net, "name = {} family = {} type = {} protocol = {}", std::string(sname),
|
||||||
protocol);
|
magic_enum::enum_name((OrbisNetFamily)family),
|
||||||
} else {
|
magic_enum::enum_name((OrbisNetSocketType)type), protocol);
|
||||||
LOG_INFO(Lib_Net, "name = {} family = {} type = {} protocol = {}", std::string(name),
|
|
||||||
family, type, protocol);
|
|
||||||
}
|
|
||||||
SocketPtr socket;
|
SocketPtr socket;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ORBIS_NET_SOCK_STREAM:
|
case ORBIS_NET_SOCK_STREAM:
|
||||||
@@ -185,7 +219,7 @@ int PS4_SYSV_ABI sys_socketex(const char* name, int family, int type, int protoc
|
|||||||
sock->is_opened = true;
|
sock->is_opened = true;
|
||||||
sock->type = Core::FileSys::FileType::Socket;
|
sock->type = Core::FileSys::FileType::Socket;
|
||||||
sock->socket = socket;
|
sock->socket = socket;
|
||||||
sock->m_guest_name = name ? name : "anon_sock";
|
sock->m_guest_name = sname;
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -298,6 +332,7 @@ int PS4_SYSV_ABI sys_socketclose(OrbisNetId s) {
|
|||||||
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
LOG_DEBUG(Lib_Net, "s = {} ({})", s, file->m_guest_name);
|
||||||
int returncode = file->socket->Close();
|
int returncode = file->socket->Close();
|
||||||
if (returncode >= 0) {
|
if (returncode >= 0) {
|
||||||
return returncode;
|
return returncode;
|
||||||
@@ -318,6 +353,7 @@ int PS4_SYSV_ABI sys_sendto(OrbisNetId s, const void* buf, u64 len, int flags,
|
|||||||
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
LOG_DEBUG(Lib_Net, "s = {} ({}), len = {}, flags = {:#x}", s, file->m_guest_name, len, flags);
|
||||||
int returncode = file->socket->SendPacket(buf, len, flags, addr, addrlen);
|
int returncode = file->socket->SendPacket(buf, len, flags, addr, addrlen);
|
||||||
if (returncode >= 0) {
|
if (returncode >= 0) {
|
||||||
return returncode;
|
return returncode;
|
||||||
@@ -354,11 +390,13 @@ s64 PS4_SYSV_ABI sys_recvfrom(OrbisNetId s, void* buf, u64 len, int flags, Orbis
|
|||||||
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
LOG_ERROR(Lib_Net, "socket id is invalid = {}", s);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
LOG_DEBUG(Lib_Net, "s = {} ({}), len = {}, flags = {:#x}", s, file->m_guest_name, len, flags);
|
||||||
int returncode = file->socket->ReceivePacket(buf, len, flags, addr, paddrlen);
|
int returncode = file->socket->ReceivePacket(buf, len, flags, addr, paddrlen);
|
||||||
if (returncode >= 0) {
|
if (returncode >= 0) {
|
||||||
return returncode;
|
return returncode;
|
||||||
}
|
}
|
||||||
LOG_ERROR(Lib_Net, "error code returned: {}", (u32)*Libraries::Kernel::__Error());
|
LOG_ERROR(Lib_Net, "s = {} ({}) returned error code: {}", s, file->m_guest_name,
|
||||||
|
(u32)*Libraries::Kernel::__Error());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user