2020-12-05 13:08:24 +01:00
|
|
|
#include "stdafx.h"
|
2018-09-29 01:12:00 +03:00
|
|
|
#include "sys_net.h"
|
|
|
|
|
2017-09-25 18:52:34 +03:00
|
|
|
#include "Emu/IdManager.h"
|
|
|
|
#include "Emu/Cell/PPUThread.h"
|
|
|
|
#include "Utilities/Thread.h"
|
|
|
|
|
|
|
|
#include "sys_sync.h"
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
#include <winsock2.h>
|
|
|
|
#include <WS2tcpip.h>
|
|
|
|
#else
|
2021-12-30 19:39:18 +03:00
|
|
|
#ifdef __clang__
|
|
|
|
#pragma GCC diagnostic push
|
|
|
|
#pragma GCC diagnostic ignored "-Wold-style-cast"
|
|
|
|
#endif
|
2017-09-25 18:52:34 +03:00
|
|
|
#include <errno.h>
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/socket.h>
|
|
|
|
#include <netinet/in.h>
|
2021-12-26 17:13:01 +00:00
|
|
|
#include <netinet/ip.h>
|
2017-09-25 18:52:34 +03:00
|
|
|
#include <netinet/tcp.h>
|
|
|
|
#include <arpa/inet.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <poll.h>
|
2021-12-30 19:39:18 +03:00
|
|
|
#ifdef __clang__
|
|
|
|
#pragma GCC diagnostic pop
|
|
|
|
#endif
|
2017-09-25 18:52:34 +03:00
|
|
|
#endif
|
|
|
|
|
2020-03-04 14:55:35 +01:00
|
|
|
#include "Emu/NP/np_handler.h"
|
2021-11-06 21:18:31 +01:00
|
|
|
#include "Emu/NP/np_helpers.h"
|
2021-11-03 00:53:57 +01:00
|
|
|
#include "Emu/NP/np_dnshook.h"
|
2020-03-04 14:55:35 +01:00
|
|
|
|
2020-08-27 21:47:04 +02:00
|
|
|
#include <chrono>
|
2020-11-05 18:59:01 +03:00
|
|
|
#include <shared_mutex>
|
2020-08-27 21:47:04 +02:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
#include "sys_net/network_context.h"
|
|
|
|
#include "sys_net/lv2_socket.h"
|
|
|
|
#include "sys_net/lv2_socket_native.h"
|
|
|
|
#include "sys_net/lv2_socket_raw.h"
|
|
|
|
#include "sys_net/lv2_socket_p2p.h"
|
|
|
|
#include "sys_net/lv2_socket_p2ps.h"
|
|
|
|
#include "sys_net/sys_net_helpers.h"
|
|
|
|
|
2018-08-25 15:39:00 +03:00
|
|
|
LOG_CHANNEL(sys_net);
|
2020-10-11 05:02:33 +02:00
|
|
|
LOG_CHANNEL(sys_net_dump);
|
2017-09-25 18:52:34 +03:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
template <>
|
2019-11-21 18:44:00 +02:00
|
|
|
void fmt_class_string<sys_net_error>::format(std::string& out, u64 arg)
|
|
|
|
{
|
|
|
|
format_enum(out, arg, [](auto error)
|
|
|
|
{
|
2024-11-22 13:58:10 +01:00
|
|
|
switch (static_cast<s32>(error))
|
2022-04-09 14:51:22 +02:00
|
|
|
{
|
|
|
|
#define SYS_NET_ERROR_CASE(x) \
|
|
|
|
case -x: return "-" #x; \
|
|
|
|
case x: \
|
|
|
|
return #x
|
|
|
|
SYS_NET_ERROR_CASE(SYS_NET_ENOENT);
|
|
|
|
SYS_NET_ERROR_CASE(SYS_NET_EINTR);
|
|
|
|
SYS_NET_ERROR_CASE(SYS_NET_EBADF);
|
|
|
|
SYS_NET_ERROR_CASE(SYS_NET_ENOMEM);
|
|
|
|
SYS_NET_ERROR_CASE(SYS_NET_EACCES);
|
|
|
|
SYS_NET_ERROR_CASE(SYS_NET_EFAULT);
|
|
|
|
SYS_NET_ERROR_CASE(SYS_NET_EBUSY);
|
|
|
|
SYS_NET_ERROR_CASE(SYS_NET_EINVAL);
|
|
|
|
SYS_NET_ERROR_CASE(SYS_NET_EMFILE);
|
|
|
|
SYS_NET_ERROR_CASE(SYS_NET_ENOSPC);
|
|
|
|
SYS_NET_ERROR_CASE(SYS_NET_EPIPE);
|
|
|
|
SYS_NET_ERROR_CASE(SYS_NET_EAGAIN);
|
|
|
|
static_assert(SYS_NET_EWOULDBLOCK == SYS_NET_EAGAIN);
|
|
|
|
SYS_NET_ERROR_CASE(SYS_NET_EINPROGRESS);
|
|
|
|
SYS_NET_ERROR_CASE(SYS_NET_EALREADY);
|
|
|
|
SYS_NET_ERROR_CASE(SYS_NET_EDESTADDRREQ);
|
|
|
|
SYS_NET_ERROR_CASE(SYS_NET_EMSGSIZE);
|
|
|
|
SYS_NET_ERROR_CASE(SYS_NET_EPROTOTYPE);
|
|
|
|
SYS_NET_ERROR_CASE(SYS_NET_ENOPROTOOPT);
|
|
|
|
SYS_NET_ERROR_CASE(SYS_NET_EPROTONOSUPPORT);
|
|
|
|
SYS_NET_ERROR_CASE(SYS_NET_EOPNOTSUPP);
|
|
|
|
SYS_NET_ERROR_CASE(SYS_NET_EPFNOSUPPORT);
|
|
|
|
SYS_NET_ERROR_CASE(SYS_NET_EAFNOSUPPORT);
|
|
|
|
SYS_NET_ERROR_CASE(SYS_NET_EADDRINUSE);
|
|
|
|
SYS_NET_ERROR_CASE(SYS_NET_EADDRNOTAVAIL);
|
|
|
|
SYS_NET_ERROR_CASE(SYS_NET_ENETDOWN);
|
|
|
|
SYS_NET_ERROR_CASE(SYS_NET_ENETUNREACH);
|
|
|
|
SYS_NET_ERROR_CASE(SYS_NET_ECONNABORTED);
|
|
|
|
SYS_NET_ERROR_CASE(SYS_NET_ECONNRESET);
|
|
|
|
SYS_NET_ERROR_CASE(SYS_NET_ENOBUFS);
|
|
|
|
SYS_NET_ERROR_CASE(SYS_NET_EISCONN);
|
|
|
|
SYS_NET_ERROR_CASE(SYS_NET_ENOTCONN);
|
|
|
|
SYS_NET_ERROR_CASE(SYS_NET_ESHUTDOWN);
|
|
|
|
SYS_NET_ERROR_CASE(SYS_NET_ETOOMANYREFS);
|
|
|
|
SYS_NET_ERROR_CASE(SYS_NET_ETIMEDOUT);
|
|
|
|
SYS_NET_ERROR_CASE(SYS_NET_ECONNREFUSED);
|
|
|
|
SYS_NET_ERROR_CASE(SYS_NET_EHOSTDOWN);
|
|
|
|
SYS_NET_ERROR_CASE(SYS_NET_EHOSTUNREACH);
|
2019-11-21 18:44:00 +02:00
|
|
|
#undef SYS_NET_ERROR_CASE
|
2022-04-09 14:51:22 +02:00
|
|
|
}
|
2019-11-21 18:44:00 +02:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
return unknown;
|
|
|
|
});
|
2019-11-21 18:44:00 +02:00
|
|
|
}
|
|
|
|
|
2020-06-09 18:35:14 +03:00
|
|
|
template <>
|
|
|
|
void fmt_class_string<lv2_socket_type>::format(std::string& out, u64 arg)
|
|
|
|
{
|
|
|
|
format_enum(out, arg, [](auto value)
|
|
|
|
{
|
2022-04-09 14:51:22 +02:00
|
|
|
switch (value)
|
|
|
|
{
|
|
|
|
case SYS_NET_SOCK_STREAM: return "STREAM";
|
|
|
|
case SYS_NET_SOCK_DGRAM: return "DGRAM";
|
|
|
|
case SYS_NET_SOCK_RAW: return "RAW";
|
|
|
|
case SYS_NET_SOCK_DGRAM_P2P: return "DGRAM-P2P";
|
|
|
|
case SYS_NET_SOCK_STREAM_P2P: return "STREAM-P2P";
|
|
|
|
}
|
2020-06-09 18:35:14 +03:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
return unknown;
|
|
|
|
});
|
2020-06-09 18:35:14 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
template <>
|
|
|
|
void fmt_class_string<lv2_socket_family>::format(std::string& out, u64 arg)
|
|
|
|
{
|
|
|
|
format_enum(out, arg, [](auto value)
|
|
|
|
{
|
2022-04-09 14:51:22 +02:00
|
|
|
switch (value)
|
|
|
|
{
|
|
|
|
case SYS_NET_AF_UNSPEC: return "UNSPEC";
|
|
|
|
case SYS_NET_AF_LOCAL: return "LOCAL";
|
|
|
|
case SYS_NET_AF_INET: return "INET";
|
|
|
|
case SYS_NET_AF_INET6: return "INET6";
|
|
|
|
}
|
2020-06-09 18:35:14 +03:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
return unknown;
|
|
|
|
});
|
2020-06-09 18:35:14 +03:00
|
|
|
}
|
|
|
|
|
2021-12-26 17:13:01 +00:00
|
|
|
template <>
|
|
|
|
void fmt_class_string<lv2_ip_protocol>::format(std::string& out, u64 arg)
|
|
|
|
{
|
|
|
|
format_enum(out, arg, [](auto value)
|
|
|
|
{
|
2022-04-09 14:51:22 +02:00
|
|
|
switch (value)
|
|
|
|
{
|
|
|
|
case SYS_NET_IPPROTO_IP: return "IPPROTO_IP";
|
|
|
|
case SYS_NET_IPPROTO_ICMP: return "IPPROTO_ICMP";
|
|
|
|
case SYS_NET_IPPROTO_IGMP: return "IPPROTO_IGMP";
|
|
|
|
case SYS_NET_IPPROTO_TCP: return "IPPROTO_TCP";
|
|
|
|
case SYS_NET_IPPROTO_UDP: return "IPPROTO_UDP";
|
|
|
|
case SYS_NET_IPPROTO_ICMPV6: return "IPPROTO_ICMPV6";
|
|
|
|
}
|
2021-12-26 17:13:01 +00:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
return unknown;
|
|
|
|
});
|
2021-12-26 17:13:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <>
|
|
|
|
void fmt_class_string<lv2_tcp_option>::format(std::string& out, u64 arg)
|
|
|
|
{
|
|
|
|
format_enum(out, arg, [](auto value)
|
|
|
|
{
|
2022-04-09 14:51:22 +02:00
|
|
|
switch (value)
|
|
|
|
{
|
|
|
|
case SYS_NET_TCP_NODELAY: return "TCP_NODELAY";
|
|
|
|
case SYS_NET_TCP_MAXSEG: return "TCP_MAXSEG";
|
|
|
|
case SYS_NET_TCP_MSS_TO_ADVERTISE: return "TCP_MSS_TO_ADVERTISE";
|
|
|
|
}
|
2021-12-26 17:13:01 +00:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
return unknown;
|
|
|
|
});
|
2021-12-26 17:13:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <>
|
|
|
|
void fmt_class_string<lv2_socket_option>::format(std::string& out, u64 arg)
|
|
|
|
{
|
|
|
|
format_enum(out, arg, [](auto value)
|
|
|
|
{
|
2022-04-09 14:51:22 +02:00
|
|
|
switch (value)
|
|
|
|
{
|
|
|
|
case SYS_NET_SO_SNDBUF: return "SO_SNDBUF";
|
|
|
|
case SYS_NET_SO_RCVBUF: return "SO_RCVBUF";
|
|
|
|
case SYS_NET_SO_SNDLOWAT: return "SO_SNDLOWAT";
|
|
|
|
case SYS_NET_SO_RCVLOWAT: return "SO_RCVLOWAT";
|
|
|
|
case SYS_NET_SO_SNDTIMEO: return "SO_SNDTIMEO";
|
|
|
|
case SYS_NET_SO_RCVTIMEO: return "SO_RCVTIMEO";
|
|
|
|
case SYS_NET_SO_ERROR: return "SO_ERROR";
|
|
|
|
case SYS_NET_SO_TYPE: return "SO_TYPE";
|
|
|
|
case SYS_NET_SO_NBIO: return "SO_NBIO";
|
|
|
|
case SYS_NET_SO_TPPOLICY: return "SO_TPPOLICY";
|
|
|
|
case SYS_NET_SO_REUSEADDR: return "SO_REUSEADDR";
|
|
|
|
case SYS_NET_SO_KEEPALIVE: return "SO_KEEPALIVE";
|
|
|
|
case SYS_NET_SO_BROADCAST: return "SO_BROADCAST";
|
|
|
|
case SYS_NET_SO_LINGER: return "SO_LINGER";
|
|
|
|
case SYS_NET_SO_OOBINLINE: return "SO_OOBINLINE";
|
|
|
|
case SYS_NET_SO_REUSEPORT: return "SO_REUSEPORT";
|
|
|
|
case SYS_NET_SO_ONESBCAST: return "SO_ONESBCAST";
|
|
|
|
case SYS_NET_SO_USECRYPTO: return "SO_USECRYPTO";
|
|
|
|
case SYS_NET_SO_USESIGNATURE: return "SO_USESIGNATURE";
|
|
|
|
case SYS_NET_SOL_SOCKET: return "SOL_SOCKET";
|
|
|
|
}
|
|
|
|
|
|
|
|
return unknown;
|
|
|
|
});
|
2021-12-26 17:13:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <>
|
|
|
|
void fmt_class_string<lv2_ip_option>::format(std::string& out, u64 arg)
|
|
|
|
{
|
|
|
|
format_enum(out, arg, [](auto value)
|
|
|
|
{
|
2022-04-09 14:51:22 +02:00
|
|
|
switch (value)
|
|
|
|
{
|
|
|
|
case SYS_NET_IP_HDRINCL: return "IP_HDRINCL";
|
|
|
|
case SYS_NET_IP_TOS: return "IP_TOS";
|
|
|
|
case SYS_NET_IP_TTL: return "IP_TTL";
|
|
|
|
case SYS_NET_IP_MULTICAST_IF: return "IP_MULTICAST_IF";
|
|
|
|
case SYS_NET_IP_MULTICAST_TTL: return "IP_MULTICAST_TTL";
|
|
|
|
case SYS_NET_IP_MULTICAST_LOOP: return "IP_MULTICAST_LOOP";
|
|
|
|
case SYS_NET_IP_ADD_MEMBERSHIP: return "IP_ADD_MEMBERSHIP";
|
|
|
|
case SYS_NET_IP_DROP_MEMBERSHIP: return "IP_DROP_MEMBERSHIP";
|
|
|
|
case SYS_NET_IP_TTLCHK: return "IP_TTLCHK";
|
|
|
|
case SYS_NET_IP_MAXTTL: return "IP_MAXTTL";
|
|
|
|
case SYS_NET_IP_DONTFRAG: return "IP_DONTFRAG";
|
|
|
|
}
|
2021-12-26 17:13:01 +00:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
return unknown;
|
|
|
|
});
|
2021-12-26 17:13:01 +00:00
|
|
|
}
|
|
|
|
|
2020-03-04 17:08:40 +03:00
|
|
|
template <>
|
|
|
|
void fmt_class_string<struct in_addr>::format(std::string& out, u64 arg)
|
|
|
|
{
|
2022-04-09 14:51:22 +02:00
|
|
|
const u8* data = reinterpret_cast<const u8*>(&get_object(arg));
|
2020-03-04 17:08:40 +03:00
|
|
|
|
|
|
|
fmt::append(out, "%u.%u.%u.%u", data[0], data[1], data[2], data[3]);
|
|
|
|
}
|
|
|
|
|
2022-07-04 16:02:17 +03:00
|
|
|
lv2_socket::lv2_socket(utils::serial& ar, lv2_socket_type _type)
|
|
|
|
: family(ar)
|
|
|
|
, type(_type)
|
|
|
|
, protocol(ar)
|
|
|
|
, so_nbio(ar)
|
|
|
|
, so_error(ar)
|
|
|
|
, so_tcp_maxseg(ar)
|
|
|
|
#ifdef _WIN32
|
|
|
|
, so_reuseaddr(ar)
|
|
|
|
, so_reuseport(ar)
|
|
|
|
{
|
|
|
|
#else
|
|
|
|
{
|
|
|
|
// Try to match structure between different platforms
|
|
|
|
ar.pos += 8;
|
|
|
|
#endif
|
2023-01-09 19:03:01 +02:00
|
|
|
|
2023-07-31 21:27:39 +02:00
|
|
|
[[maybe_unused]] const s32 version = GET_SERIALIZATION_VERSION(lv2_net);
|
2023-01-09 19:03:01 +02:00
|
|
|
|
2023-07-21 18:23:09 +03:00
|
|
|
ar(so_rcvtimeo, so_sendtimeo);
|
2023-01-09 19:03:01 +02:00
|
|
|
|
2022-07-04 16:02:17 +03:00
|
|
|
lv2_id = idm::last_id();
|
|
|
|
|
|
|
|
ar(last_bound_addr);
|
|
|
|
}
|
|
|
|
|
2024-12-22 20:59:48 +02:00
|
|
|
std::function<void(void*)> lv2_socket::load(utils::serial& ar)
|
2022-07-04 16:02:17 +03:00
|
|
|
{
|
|
|
|
const lv2_socket_type type{ar};
|
|
|
|
|
2024-12-22 20:59:48 +02:00
|
|
|
shared_ptr<lv2_socket> sock_lv2;
|
2022-07-04 16:02:17 +03:00
|
|
|
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case SYS_NET_SOCK_STREAM:
|
|
|
|
case SYS_NET_SOCK_DGRAM:
|
|
|
|
{
|
2024-12-22 20:59:48 +02:00
|
|
|
auto lv2_native = make_shared<lv2_socket_native>(ar, type);
|
2022-07-04 16:02:17 +03:00
|
|
|
ensure(lv2_native->create_socket() >= 0);
|
|
|
|
sock_lv2 = std::move(lv2_native);
|
|
|
|
break;
|
|
|
|
}
|
2024-12-22 20:59:48 +02:00
|
|
|
case SYS_NET_SOCK_RAW: sock_lv2 = make_shared<lv2_socket_raw>(ar, type); break;
|
|
|
|
case SYS_NET_SOCK_DGRAM_P2P: sock_lv2 = make_shared<lv2_socket_p2p>(ar, type); break;
|
|
|
|
case SYS_NET_SOCK_STREAM_P2P: sock_lv2 = make_shared<lv2_socket_p2ps>(ar, type); break;
|
2022-07-04 16:02:17 +03:00
|
|
|
}
|
|
|
|
|
2023-01-09 19:03:01 +02:00
|
|
|
if (std::memcmp(&sock_lv2->last_bound_addr, std::array<u8, 16>{}.data(), 16))
|
2022-07-04 16:02:17 +03:00
|
|
|
{
|
|
|
|
// NOTE: It is allowed fail
|
|
|
|
sock_lv2->bind(sock_lv2->last_bound_addr);
|
|
|
|
}
|
|
|
|
|
2024-12-22 20:59:48 +02:00
|
|
|
return [ptr = sock_lv2](void* storage) { *static_cast<shared_ptr<lv2_socket>*>(storage) = ptr; };;
|
2022-07-04 16:02:17 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void lv2_socket::save(utils::serial& ar, bool save_only_this_class)
|
|
|
|
{
|
|
|
|
USING_SERIALIZATION_VERSION(lv2_net);
|
|
|
|
|
|
|
|
if (save_only_this_class)
|
|
|
|
{
|
|
|
|
ar(family, protocol, so_nbio, so_error, so_tcp_maxseg);
|
|
|
|
#ifdef _WIN32
|
|
|
|
ar(so_reuseaddr, so_reuseport);
|
|
|
|
#else
|
|
|
|
ar(std::array<char, 8>{});
|
|
|
|
#endif
|
2023-01-09 19:03:01 +02:00
|
|
|
ar(so_rcvtimeo, so_sendtimeo);
|
2022-07-04 16:02:17 +03:00
|
|
|
ar(last_bound_addr);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
ar(type);
|
|
|
|
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case SYS_NET_SOCK_STREAM:
|
|
|
|
case SYS_NET_SOCK_DGRAM:
|
|
|
|
{
|
|
|
|
static_cast<lv2_socket_native*>(this)->save(ar);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case SYS_NET_SOCK_RAW: static_cast<lv2_socket_raw*>(this)->save(ar); break;
|
|
|
|
case SYS_NET_SOCK_DGRAM_P2P: static_cast<lv2_socket_p2p*>(this)->save(ar); break;
|
|
|
|
case SYS_NET_SOCK_STREAM_P2P: static_cast<lv2_socket_p2ps*>(this)->save(ar); break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-24 12:40:53 +01:00
|
|
|
void sys_net_dump_data(std::string_view desc, const u8* data, s32 len, const void* addr)
|
2019-12-17 04:00:29 +01:00
|
|
|
{
|
2024-02-24 12:40:53 +01:00
|
|
|
const sys_net_sockaddr_in_p2p* p2p_addr = reinterpret_cast<const sys_net_sockaddr_in_p2p*>(addr);
|
|
|
|
|
|
|
|
if (p2p_addr)
|
|
|
|
sys_net_dump.trace("%s(%s:%d:%d): %s", desc, np::ip_to_string(std::bit_cast<u32>(p2p_addr->sin_addr)), p2p_addr->sin_port, p2p_addr->sin_vport, fmt::buf_to_hexstring(data, len));
|
|
|
|
else
|
|
|
|
sys_net_dump.trace("%s: %s", desc, fmt::buf_to_hexstring(data, len));
|
2022-04-09 14:51:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
error_code sys_net_bnet_accept(ppu_thread& ppu, s32 s, vm::ptr<sys_net_sockaddr> addr, vm::ptr<u32> paddrlen)
|
|
|
|
{
|
|
|
|
ppu.state += cpu_flag::wait;
|
2019-12-29 19:03:57 +03:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
sys_net.warning("sys_net_bnet_accept(s=%d, addr=*0x%x, paddrlen=*0x%x)", s, addr, paddrlen);
|
2019-12-29 19:03:57 +03:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
if (addr.operator bool() != paddrlen.operator bool() || (paddrlen && *paddrlen < addr.size()))
|
2019-12-29 19:03:57 +03:00
|
|
|
{
|
2022-04-09 14:51:22 +02:00
|
|
|
return -SYS_NET_EINVAL;
|
2019-12-29 19:03:57 +03:00
|
|
|
}
|
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
s32 result = 0;
|
|
|
|
sys_net_sockaddr sn_addr{};
|
2024-12-22 20:59:48 +02:00
|
|
|
shared_ptr<lv2_socket> new_socket{};
|
2022-04-09 14:51:22 +02:00
|
|
|
|
2022-08-04 13:13:51 +03:00
|
|
|
const auto sock = idm::check<lv2_socket>(s, [&, notify = lv2_obj::notify_all_t()](lv2_socket& sock)
|
2019-12-17 04:00:29 +01:00
|
|
|
{
|
2023-10-30 23:22:50 +01:00
|
|
|
auto [success, res, res_socket, res_addr] = sock.accept();
|
2022-04-09 14:51:22 +02:00
|
|
|
|
|
|
|
if (success)
|
2019-12-17 04:00:29 +01:00
|
|
|
{
|
2022-04-09 14:51:22 +02:00
|
|
|
result = res;
|
|
|
|
sn_addr = res_addr;
|
2022-05-13 12:31:49 +02:00
|
|
|
new_socket = std::move(res_socket);
|
2022-04-09 14:51:22 +02:00
|
|
|
return true;
|
2019-12-17 04:00:29 +01:00
|
|
|
}
|
|
|
|
|
2022-08-04 21:31:34 +03:00
|
|
|
auto lock = sock.lock();
|
|
|
|
|
2022-06-21 12:38:44 +03:00
|
|
|
sock.poll_queue(idm::get_unlocked<named_thread<ppu_thread>>(ppu.id), lv2_socket::poll_t::read, [&](bs_t<lv2_socket::poll_t> events) -> bool
|
2022-04-09 14:51:22 +02:00
|
|
|
{
|
|
|
|
if (events & lv2_socket::poll_t::read)
|
|
|
|
{
|
2022-05-13 12:31:49 +02:00
|
|
|
auto [success, res, res_socket, res_addr] = sock.accept(false);
|
2022-04-09 14:51:22 +02:00
|
|
|
if (success)
|
|
|
|
{
|
|
|
|
result = res;
|
|
|
|
sn_addr = res_addr;
|
2022-05-13 12:31:49 +02:00
|
|
|
new_socket = std::move(res_socket);
|
2022-04-09 14:51:22 +02:00
|
|
|
lv2_obj::awake(&ppu);
|
|
|
|
return success;
|
|
|
|
}
|
|
|
|
}
|
2020-10-09 22:37:01 +02:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
sock.set_poll_event(lv2_socket::poll_t::read);
|
|
|
|
return false;
|
|
|
|
});
|
2020-10-09 22:37:01 +02:00
|
|
|
|
2022-08-04 13:13:51 +03:00
|
|
|
lv2_obj::prepare_for_sleep(ppu);
|
2022-04-09 14:51:22 +02:00
|
|
|
lv2_obj::sleep(ppu);
|
|
|
|
return false;
|
|
|
|
});
|
2017-09-25 18:52:34 +03:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
if (!sock)
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2022-04-09 14:51:22 +02:00
|
|
|
return -SYS_NET_EBADF;
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
if (!sock.ret)
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2022-04-09 14:51:22 +02:00
|
|
|
while (auto state = ppu.state.fetch_sub(cpu_flag::signal))
|
|
|
|
{
|
|
|
|
if (is_stopped(state))
|
|
|
|
{
|
|
|
|
return {};
|
|
|
|
}
|
2020-10-25 22:02:57 +11:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
if (state & cpu_flag::signal)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2022-09-20 11:47:05 +03:00
|
|
|
ppu.state.wait(state);
|
2022-04-09 14:51:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (ppu.gpr[3] == static_cast<u64>(-SYS_NET_EINTR))
|
|
|
|
{
|
2022-06-21 12:38:44 +03:00
|
|
|
return -SYS_NET_EINTR;
|
2022-04-09 14:51:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (result < 0)
|
|
|
|
{
|
|
|
|
return sys_net_error{result};
|
|
|
|
}
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
if (result < 0)
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2022-04-09 14:51:22 +02:00
|
|
|
return sys_net_error{result};
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
|
|
|
|
2022-05-13 12:31:49 +02:00
|
|
|
s32 id_ps3 = result;
|
|
|
|
|
|
|
|
if (!id_ps3)
|
|
|
|
{
|
|
|
|
ensure(new_socket);
|
|
|
|
id_ps3 = idm::import_existing<lv2_socket>(new_socket);
|
|
|
|
if (id_ps3 == id_manager::id_traits<lv2_socket>::invalid)
|
|
|
|
{
|
|
|
|
return -SYS_NET_EMFILE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-04 16:02:17 +03:00
|
|
|
static_cast<void>(ppu.test_stopped());
|
2017-09-25 18:52:34 +03:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
if (addr)
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2022-04-09 14:51:22 +02:00
|
|
|
*paddrlen = sizeof(sys_net_sockaddr_in);
|
|
|
|
*addr = sn_addr;
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
// Socket ID
|
2022-05-13 12:31:49 +02:00
|
|
|
return not_an_error(id_ps3);
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
error_code sys_net_bnet_bind(ppu_thread& ppu, s32 s, vm::cptr<sys_net_sockaddr> addr, u32 addrlen)
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2022-04-09 14:51:22 +02:00
|
|
|
ppu.state += cpu_flag::wait;
|
2017-09-25 18:52:34 +03:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
sys_net.warning("sys_net_bnet_bind(s=%d, addr=*0x%x, addrlen=%u)", s, addr, addrlen);
|
2017-09-25 18:52:34 +03:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
if (!addr || addrlen < addr.size())
|
2020-08-27 21:47:04 +02:00
|
|
|
{
|
2022-04-09 14:51:22 +02:00
|
|
|
return -SYS_NET_EINVAL;
|
|
|
|
}
|
2020-08-27 21:47:04 +02:00
|
|
|
|
2024-12-22 20:59:48 +02:00
|
|
|
if (!idm::check_unlocked<lv2_socket>(s))
|
2022-04-09 14:51:22 +02:00
|
|
|
{
|
|
|
|
return -SYS_NET_EBADF;
|
|
|
|
}
|
2020-08-27 21:47:04 +02:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
const sys_net_sockaddr sn_addr = *addr;
|
2020-08-27 21:47:04 +02:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
// 0 presumably defaults to AF_INET(to check?)
|
|
|
|
if (sn_addr.sa_family != SYS_NET_AF_INET && sn_addr.sa_family != SYS_NET_AF_UNSPEC)
|
|
|
|
{
|
|
|
|
sys_net.error("sys_net_bnet_bind: unsupported sa_family (%d)", sn_addr.sa_family);
|
|
|
|
return -SYS_NET_EAFNOSUPPORT;
|
|
|
|
}
|
2020-08-27 21:47:04 +02:00
|
|
|
|
2022-08-04 13:13:51 +03:00
|
|
|
const auto sock = idm::check<lv2_socket>(s, [&, notify = lv2_obj::notify_all_t()](lv2_socket& sock) -> s32
|
2022-04-09 14:51:22 +02:00
|
|
|
{
|
2022-07-04 16:02:17 +03:00
|
|
|
return sock.bind(sn_addr);
|
2022-04-09 14:51:22 +02:00
|
|
|
});
|
2020-08-27 21:47:04 +02:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
if (!sock)
|
|
|
|
{
|
|
|
|
return -SYS_NET_EBADF;
|
2020-08-27 21:47:04 +02:00
|
|
|
}
|
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
if (sock.ret)
|
2020-08-27 21:47:04 +02:00
|
|
|
{
|
2022-04-09 14:51:22 +02:00
|
|
|
return sys_net_error{sock.ret};
|
|
|
|
}
|
2020-10-08 01:25:35 +02:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
return CELL_OK;
|
|
|
|
}
|
2020-10-08 01:25:35 +02:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
error_code sys_net_bnet_connect(ppu_thread& ppu, s32 s, vm::ptr<sys_net_sockaddr> addr, u32 addrlen)
|
|
|
|
{
|
|
|
|
ppu.state += cpu_flag::wait;
|
2020-10-08 01:25:35 +02:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
sys_net.warning("sys_net_bnet_connect(s=%d, addr=*0x%x, addrlen=%u)", s, addr, addrlen);
|
2020-08-27 21:47:04 +02:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
if (!addr || addrlen < addr.size())
|
2020-08-27 21:47:04 +02:00
|
|
|
{
|
2022-04-09 14:51:22 +02:00
|
|
|
return -SYS_NET_EINVAL;
|
|
|
|
}
|
2020-08-27 21:47:04 +02:00
|
|
|
|
2023-01-31 03:36:02 +01:00
|
|
|
if (addr->sa_family != SYS_NET_AF_INET)
|
|
|
|
{
|
|
|
|
sys_net.error("sys_net_bnet_connect(s=%d): unsupported sa_family (%d)", s, addr->sa_family);
|
|
|
|
return -SYS_NET_EAFNOSUPPORT;
|
|
|
|
}
|
|
|
|
|
2024-12-22 20:59:48 +02:00
|
|
|
if (!idm::check_unlocked<lv2_socket>(s))
|
2022-04-09 14:51:22 +02:00
|
|
|
{
|
|
|
|
return -SYS_NET_EBADF;
|
|
|
|
}
|
2020-08-28 02:06:01 +02:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
s32 result = 0;
|
|
|
|
sys_net_sockaddr sn_addr = *addr;
|
2020-08-27 21:47:04 +02:00
|
|
|
|
2022-08-04 13:13:51 +03:00
|
|
|
const auto sock = idm::check<lv2_socket>(s, [&, notify = lv2_obj::notify_all_t()](lv2_socket& sock)
|
2022-04-09 14:51:22 +02:00
|
|
|
{
|
|
|
|
const auto success = sock.connect(sn_addr);
|
2020-08-27 21:47:04 +02:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
if (success)
|
|
|
|
{
|
|
|
|
result = *success;
|
|
|
|
return true;
|
|
|
|
}
|
2020-08-27 21:47:04 +02:00
|
|
|
|
2022-08-04 21:31:34 +03:00
|
|
|
auto lock = sock.lock();
|
|
|
|
|
2022-06-21 12:38:44 +03:00
|
|
|
sock.poll_queue(idm::get_unlocked<named_thread<ppu_thread>>(ppu.id), lv2_socket::poll_t::write, [&](bs_t<lv2_socket::poll_t> events) -> bool
|
2020-09-07 23:50:17 +02:00
|
|
|
{
|
2022-04-09 14:51:22 +02:00
|
|
|
if (events & lv2_socket::poll_t::write)
|
2020-08-27 21:47:04 +02:00
|
|
|
{
|
2022-04-09 14:51:22 +02:00
|
|
|
result = sock.connect_followup();
|
2020-08-27 21:47:04 +02:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
lv2_obj::awake(&ppu);
|
|
|
|
return true;
|
2020-08-27 21:47:04 +02:00
|
|
|
}
|
2022-04-09 14:51:22 +02:00
|
|
|
sock.set_poll_event(lv2_socket::poll_t::write);
|
|
|
|
return false;
|
2020-09-07 23:50:17 +02:00
|
|
|
});
|
2020-08-27 21:47:04 +02:00
|
|
|
|
2022-08-04 13:13:51 +03:00
|
|
|
lv2_obj::prepare_for_sleep(ppu);
|
2022-04-09 14:51:22 +02:00
|
|
|
lv2_obj::sleep(ppu);
|
|
|
|
return false;
|
|
|
|
});
|
2020-08-27 21:47:04 +02:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
if (!sock)
|
2020-08-27 21:47:04 +02:00
|
|
|
{
|
2022-04-09 14:51:22 +02:00
|
|
|
return -SYS_NET_EBADF;
|
2020-09-07 23:50:17 +02:00
|
|
|
}
|
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
if (sock.ret)
|
|
|
|
{
|
2022-04-10 07:42:25 +02:00
|
|
|
if (result < 0)
|
|
|
|
{
|
|
|
|
return sys_net_error{result};
|
|
|
|
}
|
|
|
|
|
|
|
|
return not_an_error(result);
|
2022-04-09 14:51:22 +02:00
|
|
|
}
|
2020-09-07 23:50:17 +02:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
if (!sock.ret)
|
|
|
|
{
|
|
|
|
while (auto state = ppu.state.fetch_sub(cpu_flag::signal))
|
2020-09-07 23:50:17 +02:00
|
|
|
{
|
2022-04-09 14:51:22 +02:00
|
|
|
if (is_stopped(state))
|
|
|
|
{
|
|
|
|
return {};
|
|
|
|
}
|
2020-08-27 21:47:04 +02:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
if (state & cpu_flag::signal)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
2020-08-27 21:47:04 +02:00
|
|
|
|
2022-09-20 11:47:05 +03:00
|
|
|
ppu.state.wait(state);
|
2022-04-09 14:51:22 +02:00
|
|
|
}
|
2020-08-27 21:47:04 +02:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
if (ppu.gpr[3] == static_cast<u64>(-SYS_NET_EINTR))
|
|
|
|
{
|
|
|
|
return -SYS_NET_EINTR;
|
|
|
|
}
|
2020-08-27 21:47:04 +02:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
if (result)
|
|
|
|
{
|
2022-04-10 07:42:25 +02:00
|
|
|
if (result < 0)
|
|
|
|
{
|
|
|
|
return sys_net_error{result};
|
|
|
|
}
|
|
|
|
|
|
|
|
return not_an_error(result);
|
2022-04-09 14:51:22 +02:00
|
|
|
}
|
|
|
|
}
|
2020-08-27 21:47:04 +02:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
return CELL_OK;
|
|
|
|
}
|
2020-08-27 21:47:04 +02:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
error_code sys_net_bnet_getpeername(ppu_thread& ppu, s32 s, vm::ptr<sys_net_sockaddr> addr, vm::ptr<u32> paddrlen)
|
|
|
|
{
|
|
|
|
ppu.state += cpu_flag::wait;
|
2020-08-27 21:47:04 +02:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
sys_net.warning("sys_net_bnet_getpeername(s=%d, addr=*0x%x, paddrlen=*0x%x)", s, addr, paddrlen);
|
2020-08-27 21:47:04 +02:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
// Note: paddrlen is both an input and output argument
|
|
|
|
if (!addr || !paddrlen || *paddrlen < addr.size())
|
|
|
|
{
|
|
|
|
return -SYS_NET_EINVAL;
|
|
|
|
}
|
2020-08-27 21:47:04 +02:00
|
|
|
|
2022-08-04 13:13:51 +03:00
|
|
|
const auto sock = idm::check<lv2_socket>(s, [&, notify = lv2_obj::notify_all_t()](lv2_socket& sock) -> s32
|
2022-04-09 14:51:22 +02:00
|
|
|
{
|
|
|
|
auto [res, sn_addr] = sock.getpeername();
|
2020-08-27 21:47:04 +02:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
if (res == CELL_OK)
|
|
|
|
{
|
|
|
|
*paddrlen = sizeof(sys_net_sockaddr);
|
|
|
|
*addr = sn_addr;
|
|
|
|
}
|
2020-08-27 21:47:04 +02:00
|
|
|
|
2022-04-10 07:42:25 +02:00
|
|
|
return res;
|
2022-04-09 14:51:22 +02:00
|
|
|
});
|
2020-08-27 21:47:04 +02:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
if (!sock)
|
2020-08-27 21:47:04 +02:00
|
|
|
{
|
2022-04-09 14:51:22 +02:00
|
|
|
return -SYS_NET_EBADF;
|
2020-08-27 21:47:04 +02:00
|
|
|
}
|
|
|
|
|
2022-04-10 07:42:25 +02:00
|
|
|
if (sock.ret < 0)
|
2020-08-27 21:47:04 +02:00
|
|
|
{
|
2022-04-10 07:42:25 +02:00
|
|
|
return sys_net_error{sock.ret};
|
2020-08-27 21:47:04 +02:00
|
|
|
}
|
|
|
|
|
2019-11-21 18:44:00 +02:00
|
|
|
return CELL_OK;
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
|
|
|
|
2019-11-21 18:44:00 +02:00
|
|
|
error_code sys_net_bnet_getsockname(ppu_thread& ppu, s32 s, vm::ptr<sys_net_sockaddr> addr, vm::ptr<u32> paddrlen)
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2020-06-05 12:36:28 +03:00
|
|
|
ppu.state += cpu_flag::wait;
|
2019-07-14 18:11:00 +03:00
|
|
|
|
2017-09-25 18:52:34 +03:00
|
|
|
sys_net.warning("sys_net_bnet_getsockname(s=%d, addr=*0x%x, paddrlen=*0x%x)", s, addr, paddrlen);
|
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
// Note: paddrlen is both an input and output argument
|
|
|
|
if (!addr || !paddrlen || *paddrlen < addr.size())
|
|
|
|
{
|
|
|
|
return -SYS_NET_EINVAL;
|
|
|
|
}
|
2017-09-25 18:52:34 +03:00
|
|
|
|
2022-08-04 13:13:51 +03:00
|
|
|
const auto sock = idm::check<lv2_socket>(s, [&, notify = lv2_obj::notify_all_t()](lv2_socket& sock) -> s32
|
2020-10-09 22:37:01 +02:00
|
|
|
{
|
2022-04-09 14:51:22 +02:00
|
|
|
auto [res, sn_addr] = sock.getsockname();
|
|
|
|
|
|
|
|
if (res == CELL_OK)
|
2020-10-09 22:37:01 +02:00
|
|
|
{
|
2022-04-09 14:51:22 +02:00
|
|
|
*paddrlen = sizeof(sys_net_sockaddr);
|
|
|
|
*addr = sn_addr;
|
2020-10-09 22:37:01 +02:00
|
|
|
}
|
2017-09-25 18:52:34 +03:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
return res;
|
|
|
|
});
|
2017-09-25 18:52:34 +03:00
|
|
|
|
|
|
|
if (!sock)
|
|
|
|
{
|
|
|
|
return -SYS_NET_EBADF;
|
|
|
|
}
|
|
|
|
|
2022-04-10 07:42:25 +02:00
|
|
|
if (sock.ret < 0)
|
2019-11-21 18:44:00 +02:00
|
|
|
{
|
2022-04-09 14:51:22 +02:00
|
|
|
return sys_net_error{sock.ret};
|
2020-08-27 21:47:04 +02:00
|
|
|
}
|
|
|
|
|
2019-11-21 18:44:00 +02:00
|
|
|
return CELL_OK;
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
|
|
|
|
2019-11-21 18:44:00 +02:00
|
|
|
error_code sys_net_bnet_getsockopt(ppu_thread& ppu, s32 s, s32 level, s32 optname, vm::ptr<void> optval, vm::ptr<u32> optlen)
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2020-06-05 12:36:28 +03:00
|
|
|
ppu.state += cpu_flag::wait;
|
2019-07-14 18:11:00 +03:00
|
|
|
|
2021-12-26 17:13:01 +00:00
|
|
|
switch (level)
|
|
|
|
{
|
|
|
|
case SYS_NET_SOL_SOCKET:
|
|
|
|
sys_net.warning("sys_net_bnet_getsockopt(s=%d, level=SYS_NET_SOL_SOCKET, optname=%s, optval=*0x%x, optlen=%u)", s, static_cast<lv2_socket_option>(optname), optval, optlen);
|
|
|
|
break;
|
|
|
|
case SYS_NET_IPPROTO_TCP:
|
|
|
|
sys_net.warning("sys_net_bnet_getsockopt(s=%d, level=SYS_NET_IPPROTO_TCP, optname=%s, optval=*0x%x, optlen=%u)", s, static_cast<lv2_tcp_option>(optname), optval, optlen);
|
|
|
|
break;
|
|
|
|
case SYS_NET_IPPROTO_IP:
|
|
|
|
sys_net.warning("sys_net_bnet_getsockopt(s=%d, level=SYS_NET_IPPROTO_IP, optname=%s, optval=*0x%x, optlen=%u)", s, static_cast<lv2_ip_option>(optname), optval, optlen);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
sys_net.warning("sys_net_bnet_getsockopt(s=%d, level=0x%x, optname=0x%x, optval=*0x%x, optlen=%u)", s, level, optname, optval, optlen);
|
|
|
|
break;
|
|
|
|
}
|
2017-09-25 18:52:34 +03:00
|
|
|
|
2020-04-12 12:53:18 +03:00
|
|
|
if (!optval || !optlen)
|
|
|
|
{
|
|
|
|
return -SYS_NET_EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
const u32 len = *optlen;
|
|
|
|
|
|
|
|
if (!len)
|
|
|
|
{
|
|
|
|
return -SYS_NET_EINVAL;
|
|
|
|
}
|
|
|
|
|
2022-08-04 13:13:51 +03:00
|
|
|
const auto sock = idm::check<lv2_socket>(s, [&, notify = lv2_obj::notify_all_t()](lv2_socket& sock) -> s32
|
2021-12-26 17:13:01 +00:00
|
|
|
{
|
2022-04-09 14:51:22 +02:00
|
|
|
if (len < sizeof(s32))
|
2021-12-26 17:13:01 +00:00
|
|
|
{
|
2022-04-09 14:51:22 +02:00
|
|
|
return -SYS_NET_EINVAL;
|
2021-12-26 17:13:01 +00:00
|
|
|
}
|
2017-09-25 18:52:34 +03:00
|
|
|
|
2023-10-30 23:22:50 +01:00
|
|
|
const auto& [res, out_val, out_len] = sock.getsockopt(level, optname, *optlen);
|
2017-09-25 18:52:34 +03:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
if (res == CELL_OK)
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2022-04-09 14:51:22 +02:00
|
|
|
std::memcpy(optval.get_ptr(), out_val.ch, out_len);
|
|
|
|
*optlen = out_len;
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
|
|
|
|
2022-04-10 07:42:25 +02:00
|
|
|
return res;
|
2022-04-09 14:51:22 +02:00
|
|
|
});
|
2017-09-25 18:52:34 +03:00
|
|
|
|
|
|
|
if (!sock)
|
|
|
|
{
|
|
|
|
return -SYS_NET_EBADF;
|
|
|
|
}
|
|
|
|
|
2022-04-10 07:42:25 +02:00
|
|
|
if (sock.ret < 0)
|
|
|
|
{
|
|
|
|
return sys_net_error{sock.ret};
|
|
|
|
}
|
|
|
|
|
|
|
|
return CELL_OK;
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
|
|
|
|
2019-11-21 18:44:00 +02:00
|
|
|
error_code sys_net_bnet_listen(ppu_thread& ppu, s32 s, s32 backlog)
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2020-06-05 12:36:28 +03:00
|
|
|
ppu.state += cpu_flag::wait;
|
2019-07-14 18:11:00 +03:00
|
|
|
|
2017-09-25 18:52:34 +03:00
|
|
|
sys_net.warning("sys_net_bnet_listen(s=%d, backlog=%d)", s, backlog);
|
|
|
|
|
2020-04-12 12:16:24 +03:00
|
|
|
if (backlog <= 0)
|
|
|
|
{
|
|
|
|
return -SYS_NET_EINVAL;
|
|
|
|
}
|
|
|
|
|
2022-08-04 13:13:51 +03:00
|
|
|
const auto sock = idm::check<lv2_socket>(s, [&, notify = lv2_obj::notify_all_t()](lv2_socket& sock) -> s32
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2022-04-10 07:42:25 +02:00
|
|
|
return sock.listen(backlog);
|
2022-04-09 14:51:22 +02:00
|
|
|
});
|
2017-09-25 18:52:34 +03:00
|
|
|
|
|
|
|
if (!sock)
|
|
|
|
{
|
|
|
|
return -SYS_NET_EBADF;
|
|
|
|
}
|
|
|
|
|
2022-04-10 07:42:25 +02:00
|
|
|
if (sock.ret < 0)
|
2019-11-21 18:44:00 +02:00
|
|
|
{
|
2022-04-10 07:42:25 +02:00
|
|
|
return sys_net_error{sock.ret};
|
2019-11-21 18:44:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return CELL_OK;
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
|
|
|
|
2019-11-21 18:44:00 +02:00
|
|
|
error_code sys_net_bnet_recvfrom(ppu_thread& ppu, s32 s, vm::ptr<void> buf, u32 len, s32 flags, vm::ptr<sys_net_sockaddr> addr, vm::ptr<u32> paddrlen)
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2020-06-05 12:36:28 +03:00
|
|
|
ppu.state += cpu_flag::wait;
|
2019-07-14 18:11:00 +03:00
|
|
|
|
2024-01-31 05:25:26 +01:00
|
|
|
sys_net.trace("sys_net_bnet_recvfrom(s=%d, buf=*0x%x, len=%u, flags=0x%x, addr=*0x%x, paddrlen=*0x%x)", s, buf, len, flags, addr, paddrlen);
|
2017-09-25 18:52:34 +03:00
|
|
|
|
2020-04-12 11:51:58 +03:00
|
|
|
// If addr is null, paddrlen must be null as well
|
|
|
|
if (!buf || !len || addr.operator bool() != paddrlen.operator bool())
|
|
|
|
{
|
|
|
|
return -SYS_NET_EINVAL;
|
|
|
|
}
|
|
|
|
|
2021-07-25 21:40:35 +03:00
|
|
|
if (flags & ~(SYS_NET_MSG_PEEK | SYS_NET_MSG_DONTWAIT | SYS_NET_MSG_WAITALL | SYS_NET_MSG_USECRYPTO | SYS_NET_MSG_USESIGNATURE))
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
|
|
|
fmt::throw_exception("sys_net_bnet_recvfrom(s=%d): unknown flags (0x%x)", flags);
|
|
|
|
}
|
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
s32 result = 0;
|
|
|
|
sys_net_sockaddr sn_addr{};
|
2017-09-25 18:52:34 +03:00
|
|
|
|
2022-08-04 13:13:51 +03:00
|
|
|
const auto sock = idm::check<lv2_socket>(s, [&, notify = lv2_obj::notify_all_t()](lv2_socket& sock)
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2022-04-09 14:51:22 +02:00
|
|
|
const auto success = sock.recvfrom(flags, len);
|
2017-09-25 18:52:34 +03:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
if (success)
|
|
|
|
{
|
|
|
|
const auto& [res, vec, res_addr] = *success;
|
|
|
|
if (res > 0)
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2022-04-09 14:51:22 +02:00
|
|
|
sn_addr = res_addr;
|
|
|
|
std::memcpy(buf.get_ptr(), vec.data(), res);
|
2024-02-24 12:40:53 +01:00
|
|
|
sys_net_dump_data("recvfrom", vec.data(), res, &res_addr);
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
2022-04-09 14:51:22 +02:00
|
|
|
|
|
|
|
result = res;
|
|
|
|
return true;
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
|
|
|
|
2022-08-04 21:31:34 +03:00
|
|
|
auto lock = sock.lock();
|
|
|
|
|
2022-06-21 12:38:44 +03:00
|
|
|
sock.poll_queue(idm::get_unlocked<named_thread<ppu_thread>>(ppu.id), lv2_socket::poll_t::read, [&](bs_t<lv2_socket::poll_t> events) -> bool
|
2022-04-09 14:51:22 +02:00
|
|
|
{
|
|
|
|
if (events & lv2_socket::poll_t::read)
|
|
|
|
{
|
|
|
|
const auto success = sock.recvfrom(flags, len, false);
|
|
|
|
|
|
|
|
if (success)
|
|
|
|
{
|
|
|
|
const auto& [res, vec, res_addr] = *success;
|
|
|
|
if (res > 0)
|
|
|
|
{
|
|
|
|
sn_addr = res_addr;
|
|
|
|
std::memcpy(buf.get_ptr(), vec.data(), res);
|
2024-02-24 12:40:53 +01:00
|
|
|
sys_net_dump_data("recvfrom", vec.data(), res, &res_addr);
|
2022-04-09 14:51:22 +02:00
|
|
|
}
|
|
|
|
result = res;
|
|
|
|
lv2_obj::awake(&ppu);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-09 19:03:01 +02:00
|
|
|
if (sock.so_rcvtimeo && get_guest_system_time() - ppu.start_time > sock.so_rcvtimeo)
|
|
|
|
{
|
|
|
|
result = -SYS_NET_EWOULDBLOCK;
|
|
|
|
lv2_obj::awake(&ppu);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
sock.set_poll_event(lv2_socket::poll_t::read);
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
|
2022-08-04 13:13:51 +03:00
|
|
|
lv2_obj::prepare_for_sleep(ppu);
|
2022-04-09 14:51:22 +02:00
|
|
|
lv2_obj::sleep(ppu);
|
2017-09-25 18:52:34 +03:00
|
|
|
return false;
|
|
|
|
});
|
|
|
|
|
|
|
|
if (!sock)
|
|
|
|
{
|
|
|
|
return -SYS_NET_EBADF;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!sock.ret)
|
|
|
|
{
|
2022-04-09 14:51:22 +02:00
|
|
|
|
2021-02-13 16:50:07 +02:00
|
|
|
while (auto state = ppu.state.fetch_sub(cpu_flag::signal))
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2021-02-13 16:50:07 +02:00
|
|
|
if (is_stopped(state))
|
|
|
|
{
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
|
|
|
if (state & cpu_flag::signal)
|
2018-10-11 01:17:19 +03:00
|
|
|
{
|
2021-02-13 16:50:07 +02:00
|
|
|
break;
|
2018-10-11 01:17:19 +03:00
|
|
|
}
|
|
|
|
|
2022-09-20 11:47:05 +03:00
|
|
|
ppu.state.wait(state);
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
|
|
|
|
2020-02-19 20:03:59 +03:00
|
|
|
if (ppu.gpr[3] == static_cast<u64>(-SYS_NET_EINTR))
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
|
|
|
return -SYS_NET_EINTR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-04 16:02:17 +03:00
|
|
|
static_cast<void>(ppu.test_stopped());
|
2019-06-06 21:32:35 +03:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
if (result == -SYS_NET_EWOULDBLOCK)
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2022-04-09 14:51:22 +02:00
|
|
|
return not_an_error(result);
|
|
|
|
}
|
2017-09-25 18:52:34 +03:00
|
|
|
|
2022-04-10 07:42:25 +02:00
|
|
|
if (result >= 0)
|
2022-04-09 14:51:22 +02:00
|
|
|
{
|
|
|
|
if (addr)
|
|
|
|
{
|
|
|
|
*paddrlen = sizeof(sys_net_sockaddr_in);
|
|
|
|
*addr = sn_addr;
|
|
|
|
}
|
2017-09-25 18:52:34 +03:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
return not_an_error(result);
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
|
|
|
|
2022-04-10 07:42:25 +02:00
|
|
|
return sys_net_error{result};
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
|
|
|
|
2019-11-21 18:44:00 +02:00
|
|
|
error_code sys_net_bnet_recvmsg(ppu_thread& ppu, s32 s, vm::ptr<sys_net_msghdr> msg, s32 flags)
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2020-06-05 12:36:28 +03:00
|
|
|
ppu.state += cpu_flag::wait;
|
2019-07-14 18:11:00 +03:00
|
|
|
|
2017-09-25 18:52:34 +03:00
|
|
|
sys_net.todo("sys_net_bnet_recvmsg(s=%d, msg=*0x%x, flags=0x%x)", s, msg, flags);
|
2019-11-21 18:44:00 +02:00
|
|
|
return CELL_OK;
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
|
|
|
|
2019-11-21 18:44:00 +02:00
|
|
|
error_code sys_net_bnet_sendmsg(ppu_thread& ppu, s32 s, vm::cptr<sys_net_msghdr> msg, s32 flags)
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2020-06-05 12:36:28 +03:00
|
|
|
ppu.state += cpu_flag::wait;
|
2019-07-14 18:11:00 +03:00
|
|
|
|
2022-09-20 21:21:26 +02:00
|
|
|
sys_net.warning("sys_net_bnet_sendmsg(s=%d, msg=*0x%x, flags=0x%x)", s, msg, flags);
|
|
|
|
|
|
|
|
if (flags & ~(SYS_NET_MSG_DONTWAIT | SYS_NET_MSG_WAITALL | SYS_NET_MSG_USECRYPTO | SYS_NET_MSG_USESIGNATURE))
|
|
|
|
{
|
|
|
|
fmt::throw_exception("sys_net_bnet_sendmsg(s=%d): unknown flags (0x%x)", flags);
|
|
|
|
}
|
|
|
|
|
|
|
|
s32 result{};
|
|
|
|
|
|
|
|
const auto sock = idm::check<lv2_socket>(s, [&](lv2_socket& sock)
|
|
|
|
{
|
|
|
|
auto netmsg = msg.get_ptr();
|
|
|
|
const auto success = sock.sendmsg(flags, *netmsg);
|
|
|
|
|
|
|
|
if (success)
|
|
|
|
{
|
|
|
|
result = *success;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
sock.poll_queue(idm::get_unlocked<named_thread<ppu_thread>>(ppu.id), lv2_socket::poll_t::write, [&](bs_t<lv2_socket::poll_t> events) -> bool
|
|
|
|
{
|
|
|
|
if (events & lv2_socket::poll_t::write)
|
|
|
|
{
|
|
|
|
const auto success = sock.sendmsg(flags, *netmsg, false);
|
|
|
|
|
|
|
|
if (success)
|
|
|
|
{
|
|
|
|
result = *success;
|
|
|
|
lv2_obj::awake(&ppu);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sock.set_poll_event(lv2_socket::poll_t::write);
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
|
|
|
|
lv2_obj::sleep(ppu);
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
|
|
|
|
if (!sock)
|
|
|
|
{
|
|
|
|
return -SYS_NET_EBADF;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!sock.ret)
|
|
|
|
{
|
|
|
|
while (true)
|
|
|
|
{
|
|
|
|
const auto state = ppu.state.fetch_sub(cpu_flag::signal);
|
|
|
|
if (is_stopped(state) || state & cpu_flag::signal)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
thread_ctrl::wait_on(ppu.state, state);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ppu.gpr[3] == static_cast<u64>(-SYS_NET_EINTR))
|
|
|
|
{
|
|
|
|
return -SYS_NET_EINTR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (result >= 0 || result == -SYS_NET_EWOULDBLOCK)
|
|
|
|
{
|
|
|
|
return not_an_error(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return sys_net_error{result};
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
|
|
|
|
2019-11-21 18:44:00 +02:00
|
|
|
error_code sys_net_bnet_sendto(ppu_thread& ppu, s32 s, vm::cptr<void> buf, u32 len, s32 flags, vm::cptr<sys_net_sockaddr> addr, u32 addrlen)
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2020-06-05 12:36:28 +03:00
|
|
|
ppu.state += cpu_flag::wait;
|
2019-07-14 18:11:00 +03:00
|
|
|
|
2024-01-31 05:25:26 +01:00
|
|
|
sys_net.trace("sys_net_bnet_sendto(s=%d, buf=*0x%x, len=%u, flags=0x%x, addr=*0x%x, addrlen=%u)", s, buf, len, flags, addr, addrlen);
|
2017-09-25 18:52:34 +03:00
|
|
|
|
2021-07-25 21:40:35 +03:00
|
|
|
if (flags & ~(SYS_NET_MSG_DONTWAIT | SYS_NET_MSG_WAITALL | SYS_NET_MSG_USECRYPTO | SYS_NET_MSG_USESIGNATURE))
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
|
|
|
fmt::throw_exception("sys_net_bnet_sendto(s=%d): unknown flags (0x%x)", flags);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (addr && addrlen < 8)
|
|
|
|
{
|
|
|
|
sys_net.error("sys_net_bnet_sendto(s=%d): bad addrlen (%u)", s, addrlen);
|
|
|
|
return -SYS_NET_EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (addr && addr->sa_family != SYS_NET_AF_INET)
|
|
|
|
{
|
|
|
|
sys_net.error("sys_net_bnet_sendto(s=%d): unsupported sa_family (%d)", s, addr->sa_family);
|
|
|
|
return -SYS_NET_EAFNOSUPPORT;
|
|
|
|
}
|
|
|
|
|
2024-02-24 12:40:53 +01:00
|
|
|
sys_net_dump_data("sendto", static_cast<const u8*>(buf.get_ptr()), len, addr ? addr.get_ptr() : nullptr);
|
2022-05-18 17:44:21 +02:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
const std::optional<sys_net_sockaddr> sn_addr = addr ? std::optional<sys_net_sockaddr>(*addr) : std::nullopt;
|
|
|
|
const std::vector<u8> buf_copy(vm::_ptr<const char>(buf.addr()), vm::_ptr<const char>(buf.addr()) + len);
|
|
|
|
s32 result{};
|
|
|
|
|
2022-08-04 13:13:51 +03:00
|
|
|
const auto sock = idm::check<lv2_socket>(s, [&, notify = lv2_obj::notify_all_t()](lv2_socket& sock)
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2022-04-09 14:51:22 +02:00
|
|
|
auto success = sock.sendto(flags, buf_copy, sn_addr);
|
2017-09-25 18:52:34 +03:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
if (success)
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2022-04-09 14:51:22 +02:00
|
|
|
result = *success;
|
|
|
|
return true;
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
2022-04-09 14:51:22 +02:00
|
|
|
|
2022-08-04 21:31:34 +03:00
|
|
|
auto lock = sock.lock();
|
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
// Enable write event
|
2022-06-21 12:38:44 +03:00
|
|
|
sock.poll_queue(idm::get_unlocked<named_thread<ppu_thread>>(ppu.id), lv2_socket::poll_t::write, [&](bs_t<lv2_socket::poll_t> events) -> bool
|
2022-04-09 14:51:22 +02:00
|
|
|
{
|
|
|
|
if (events & lv2_socket::poll_t::write)
|
|
|
|
{
|
|
|
|
auto success = sock.sendto(flags, buf_copy, sn_addr, false);
|
|
|
|
if (success)
|
|
|
|
{
|
|
|
|
result = *success;
|
|
|
|
lv2_obj::awake(&ppu);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
2023-01-09 19:03:01 +02:00
|
|
|
|
|
|
|
if (sock.so_sendtimeo && get_guest_system_time() - ppu.start_time > sock.so_sendtimeo)
|
|
|
|
{
|
|
|
|
result = -SYS_NET_EWOULDBLOCK;
|
|
|
|
lv2_obj::awake(&ppu);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
sock.set_poll_event(lv2_socket::poll_t::write);
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
|
2022-08-04 13:13:51 +03:00
|
|
|
lv2_obj::prepare_for_sleep(ppu);
|
2022-04-09 14:51:22 +02:00
|
|
|
lv2_obj::sleep(ppu);
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
|
|
|
|
if (!sock)
|
|
|
|
{
|
|
|
|
return -SYS_NET_EBADF;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!sock.ret)
|
|
|
|
{
|
|
|
|
while (true)
|
2021-12-26 17:13:01 +00:00
|
|
|
{
|
2022-04-09 14:51:22 +02:00
|
|
|
const auto state = ppu.state.fetch_sub(cpu_flag::signal);
|
|
|
|
if (is_stopped(state) || state & cpu_flag::signal)
|
2021-12-26 17:13:01 +00:00
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
2022-09-20 11:47:05 +03:00
|
|
|
ppu.state.wait(state);
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
if (ppu.gpr[3] == static_cast<u64>(-SYS_NET_EINTR))
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2022-04-09 14:51:22 +02:00
|
|
|
return -SYS_NET_EINTR;
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
2022-04-09 14:51:22 +02:00
|
|
|
}
|
2017-09-25 18:52:34 +03:00
|
|
|
|
2022-04-10 07:42:25 +02:00
|
|
|
if (result >= 0 || result == -SYS_NET_EWOULDBLOCK)
|
2022-04-09 14:51:22 +02:00
|
|
|
{
|
|
|
|
return not_an_error(result);
|
|
|
|
}
|
2022-04-10 07:42:25 +02:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
return sys_net_error{result};
|
|
|
|
}
|
2017-09-25 18:52:34 +03:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
error_code sys_net_bnet_setsockopt(ppu_thread& ppu, s32 s, s32 level, s32 optname, vm::cptr<void> optval, u32 optlen)
|
|
|
|
{
|
|
|
|
ppu.state += cpu_flag::wait;
|
|
|
|
|
|
|
|
switch (level)
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2022-04-09 14:51:22 +02:00
|
|
|
case SYS_NET_SOL_SOCKET:
|
|
|
|
sys_net.warning("sys_net_bnet_setsockopt(s=%d, level=SYS_NET_SOL_SOCKET, optname=%s, optval=*0x%x, optlen=%u)", s, static_cast<lv2_socket_option>(optname), optval, optlen);
|
|
|
|
break;
|
|
|
|
case SYS_NET_IPPROTO_TCP:
|
|
|
|
sys_net.warning("sys_net_bnet_setsockopt(s=%d, level=SYS_NET_IPPROTO_TCP, optname=%s, optval=*0x%x, optlen=%u)", s, static_cast<lv2_tcp_option>(optname), optval, optlen);
|
|
|
|
break;
|
|
|
|
case SYS_NET_IPPROTO_IP:
|
|
|
|
sys_net.warning("sys_net_bnet_setsockopt(s=%d, level=SYS_NET_IPPROTO_IP, optname=%s, optval=*0x%x, optlen=%u)", s, static_cast<lv2_ip_option>(optname), optval, optlen);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
sys_net.warning("sys_net_bnet_setsockopt(s=%d, level=0x%x, optname=0x%x, optval=*0x%x, optlen=%u)", s, level, optname, optval, optlen);
|
|
|
|
break;
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
switch (optlen)
|
2019-11-21 18:44:00 +02:00
|
|
|
{
|
2022-04-09 14:51:22 +02:00
|
|
|
case 1:
|
|
|
|
sys_net.warning("optval: 0x%02X", *static_cast<const u8*>(optval.get_ptr()));
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
sys_net.warning("optval: 0x%04X", *static_cast<const be_t<u16>*>(optval.get_ptr()));
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
sys_net.warning("optval: 0x%08X", *static_cast<const be_t<u32>*>(optval.get_ptr()));
|
|
|
|
break;
|
|
|
|
case 8:
|
|
|
|
sys_net.warning("optval: 0x%016X", *static_cast<const be_t<u64>*>(optval.get_ptr()));
|
|
|
|
break;
|
2019-11-21 18:44:00 +02:00
|
|
|
}
|
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
if (optlen < sizeof(s32))
|
|
|
|
{
|
|
|
|
return -SYS_NET_EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<u8> optval_copy(vm::_ptr<u8>(optval.addr()), vm::_ptr<u8>(optval.addr() + optlen));
|
|
|
|
|
2022-08-04 13:13:51 +03:00
|
|
|
const auto sock = idm::check<lv2_socket>(s, [&, notify = lv2_obj::notify_all_t()](lv2_socket& sock) -> s32
|
2022-04-09 14:51:22 +02:00
|
|
|
{
|
|
|
|
return sock.setsockopt(level, optname, optval_copy);
|
|
|
|
});
|
|
|
|
|
|
|
|
if (!sock)
|
|
|
|
{
|
|
|
|
return -SYS_NET_EBADF;
|
|
|
|
}
|
|
|
|
|
2022-04-10 07:42:25 +02:00
|
|
|
if (sock.ret < 0)
|
|
|
|
{
|
|
|
|
return sys_net_error{sock.ret};
|
|
|
|
}
|
|
|
|
|
|
|
|
return not_an_error(sock.ret);
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
|
|
|
|
2019-11-21 18:44:00 +02:00
|
|
|
error_code sys_net_bnet_shutdown(ppu_thread& ppu, s32 s, s32 how)
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2020-06-05 12:36:28 +03:00
|
|
|
ppu.state += cpu_flag::wait;
|
2019-07-14 18:11:00 +03:00
|
|
|
|
2017-09-25 18:52:34 +03:00
|
|
|
sys_net.warning("sys_net_bnet_shutdown(s=%d, how=%d)", s, how);
|
|
|
|
|
|
|
|
if (how < 0 || how > 2)
|
|
|
|
{
|
|
|
|
return -SYS_NET_EINVAL;
|
|
|
|
}
|
|
|
|
|
2022-08-04 13:13:51 +03:00
|
|
|
const auto sock = idm::check<lv2_socket>(s, [&, notify = lv2_obj::notify_all_t()](lv2_socket& sock) -> s32
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2022-04-09 14:51:22 +02:00
|
|
|
return sock.shutdown(how);
|
|
|
|
});
|
2017-09-25 18:52:34 +03:00
|
|
|
|
|
|
|
if (!sock)
|
|
|
|
{
|
|
|
|
return -SYS_NET_EBADF;
|
|
|
|
}
|
|
|
|
|
2022-04-10 07:42:25 +02:00
|
|
|
if (sock.ret < 0)
|
2019-11-21 18:44:00 +02:00
|
|
|
{
|
2022-04-10 07:42:25 +02:00
|
|
|
return sys_net_error{sock.ret};
|
2019-11-21 18:44:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return CELL_OK;
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
|
|
|
|
2021-12-26 17:13:01 +00:00
|
|
|
error_code sys_net_bnet_socket(ppu_thread& ppu, lv2_socket_family family, lv2_socket_type type, lv2_ip_protocol protocol)
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2020-06-05 12:36:28 +03:00
|
|
|
ppu.state += cpu_flag::wait;
|
2019-07-14 18:11:00 +03:00
|
|
|
|
2021-12-26 17:13:01 +00:00
|
|
|
sys_net.warning("sys_net_bnet_socket(family=%s, type=%s, protocol=%s)", family, type, protocol);
|
2017-09-25 18:52:34 +03:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
if (family != SYS_NET_AF_INET)
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
|
|
|
sys_net.error("sys_net_bnet_socket(): unknown family (%d)", family);
|
|
|
|
}
|
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
if (type != SYS_NET_SOCK_STREAM && type != SYS_NET_SOCK_DGRAM && type != SYS_NET_SOCK_RAW && type != SYS_NET_SOCK_DGRAM_P2P && type != SYS_NET_SOCK_STREAM_P2P)
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
|
|
|
sys_net.error("sys_net_bnet_socket(): unsupported type (%d)", type);
|
|
|
|
return -SYS_NET_EPROTONOSUPPORT;
|
|
|
|
}
|
|
|
|
|
2024-12-22 20:59:48 +02:00
|
|
|
shared_ptr<lv2_socket> sock_lv2;
|
2017-11-20 13:42:16 +00:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
switch (type)
|
2020-08-27 21:47:04 +02:00
|
|
|
{
|
2022-04-09 14:51:22 +02:00
|
|
|
case SYS_NET_SOCK_STREAM:
|
|
|
|
case SYS_NET_SOCK_DGRAM:
|
|
|
|
{
|
2024-12-22 20:59:48 +02:00
|
|
|
auto lv2_native = make_shared<lv2_socket_native>(family, type, protocol);
|
2022-04-09 14:51:22 +02:00
|
|
|
if (s32 result = lv2_native->create_socket(); result < 0)
|
2020-08-27 21:47:04 +02:00
|
|
|
{
|
2022-04-10 07:42:25 +02:00
|
|
|
return sys_net_error{result};
|
2020-08-27 21:47:04 +02:00
|
|
|
}
|
2017-09-25 18:52:34 +03:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
sock_lv2 = std::move(lv2_native);
|
|
|
|
break;
|
2020-08-27 21:47:04 +02:00
|
|
|
}
|
2024-12-22 20:59:48 +02:00
|
|
|
case SYS_NET_SOCK_RAW: sock_lv2 = make_shared<lv2_socket_raw>(family, type, protocol); break;
|
|
|
|
case SYS_NET_SOCK_DGRAM_P2P: sock_lv2 = make_shared<lv2_socket_p2p>(family, type, protocol); break;
|
|
|
|
case SYS_NET_SOCK_STREAM_P2P: sock_lv2 = make_shared<lv2_socket_p2ps>(family, type, protocol); break;
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
|
|
|
|
2020-08-27 21:47:04 +02:00
|
|
|
const s32 s = idm::import_existing<lv2_socket>(sock_lv2);
|
2017-09-25 18:52:34 +03:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
// Can't allocate more than 1000 sockets
|
2017-12-25 21:08:04 +03:00
|
|
|
if (s == id_manager::id_traits<lv2_socket>::invalid)
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
|
|
|
return -SYS_NET_EMFILE;
|
|
|
|
}
|
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
sock_lv2->set_lv2_id(s);
|
|
|
|
|
2019-11-21 18:44:00 +02:00
|
|
|
return not_an_error(s);
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
|
|
|
|
2019-11-21 18:44:00 +02:00
|
|
|
error_code sys_net_bnet_close(ppu_thread& ppu, s32 s)
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2020-06-05 12:36:28 +03:00
|
|
|
ppu.state += cpu_flag::wait;
|
2019-07-14 18:11:00 +03:00
|
|
|
|
2017-09-25 18:52:34 +03:00
|
|
|
sys_net.warning("sys_net_bnet_close(s=%d)", s);
|
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
auto sock = idm::withdraw<lv2_socket>(s);
|
2017-09-25 18:52:34 +03:00
|
|
|
|
|
|
|
if (!sock)
|
|
|
|
{
|
|
|
|
return -SYS_NET_EBADF;
|
|
|
|
}
|
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
if (sock->get_queue_size())
|
2022-05-18 17:44:21 +02:00
|
|
|
{
|
|
|
|
sock->abort_socket(0);
|
|
|
|
}
|
2017-09-25 18:52:34 +03:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
sock->close();
|
2020-11-10 09:55:49 +01:00
|
|
|
|
2022-01-16 23:51:04 +01:00
|
|
|
{
|
2022-04-09 14:51:22 +02:00
|
|
|
// Ensures the socket has no lingering copy from the network thread
|
2024-04-24 19:27:50 +02:00
|
|
|
std::lock_guard nw_lock(g_fxo->get<network_context>().mutex_thread_loop);
|
2022-04-09 14:51:22 +02:00
|
|
|
sock.reset();
|
2022-01-16 23:51:04 +01:00
|
|
|
}
|
2020-03-04 14:55:35 +01:00
|
|
|
|
2019-11-21 18:44:00 +02:00
|
|
|
return CELL_OK;
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
|
|
|
|
2019-11-21 18:44:00 +02:00
|
|
|
error_code sys_net_bnet_poll(ppu_thread& ppu, vm::ptr<sys_net_pollfd> fds, s32 nfds, s32 ms)
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2020-06-05 12:36:28 +03:00
|
|
|
ppu.state += cpu_flag::wait;
|
2019-07-14 18:11:00 +03:00
|
|
|
|
2024-01-31 05:25:26 +01:00
|
|
|
sys_net.trace("sys_net_bnet_poll(fds=*0x%x, nfds=%d, ms=%d)", fds, nfds, ms);
|
2017-09-25 18:52:34 +03:00
|
|
|
|
2020-06-04 17:30:11 +01:00
|
|
|
if (nfds <= 0)
|
|
|
|
{
|
|
|
|
return not_an_error(0);
|
|
|
|
}
|
|
|
|
|
2017-09-25 18:52:34 +03:00
|
|
|
atomic_t<s32> signaled{0};
|
|
|
|
|
|
|
|
u64 timeout = ms < 0 ? 0 : ms * 1000ull;
|
|
|
|
|
2020-04-12 09:47:33 +03:00
|
|
|
std::vector<sys_net_pollfd> fds_buf;
|
|
|
|
|
2022-04-09 17:36:31 +02:00
|
|
|
{
|
|
|
|
fds_buf.assign(fds.get_ptr(), fds.get_ptr() + nfds);
|
2017-09-25 18:52:34 +03:00
|
|
|
|
2022-08-04 13:13:51 +03:00
|
|
|
lv2_obj::prepare_for_sleep(ppu);
|
|
|
|
|
2024-04-24 19:27:50 +02:00
|
|
|
std::unique_lock nw_lock(g_fxo->get<network_context>().mutex_thread_loop);
|
2022-04-09 17:36:31 +02:00
|
|
|
std::shared_lock lock(id_manager::g_mutex);
|
2017-09-25 18:52:34 +03:00
|
|
|
|
2023-10-30 23:22:50 +01:00
|
|
|
std::vector<::pollfd> _fds(nfds);
|
2019-12-17 04:00:29 +01:00
|
|
|
#ifdef _WIN32
|
2023-10-30 23:22:50 +01:00
|
|
|
std::vector<bool> connecting(nfds);
|
2019-12-17 04:00:29 +01:00
|
|
|
#endif
|
2017-09-25 18:52:34 +03:00
|
|
|
|
2022-04-09 17:36:31 +02:00
|
|
|
for (s32 i = 0; i < nfds; i++)
|
2022-04-09 14:51:22 +02:00
|
|
|
{
|
2022-04-09 17:36:31 +02:00
|
|
|
_fds[i].fd = -1;
|
|
|
|
fds_buf[i].revents = 0;
|
2020-08-27 21:47:04 +02:00
|
|
|
|
2022-04-09 17:36:31 +02:00
|
|
|
if (fds_buf[i].fd < 0)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (auto sock = idm::check_unlocked<lv2_socket>(fds_buf[i].fd))
|
|
|
|
{
|
2022-04-13 16:53:36 +02:00
|
|
|
signaled += sock->poll(fds_buf[i], _fds[i]);
|
2019-12-17 04:00:29 +01:00
|
|
|
#ifdef _WIN32
|
2022-04-09 17:36:31 +02:00
|
|
|
connecting[i] = sock->is_connecting();
|
2019-12-17 04:00:29 +01:00
|
|
|
#endif
|
2022-04-09 17:36:31 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
fds_buf[i].revents |= SYS_NET_POLLNVAL;
|
|
|
|
signaled++;
|
|
|
|
}
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
|
|
|
|
2019-12-04 19:55:40 +00:00
|
|
|
#ifdef _WIN32
|
2022-04-09 17:36:31 +02:00
|
|
|
windows_poll(_fds, nfds, 0, connecting);
|
2019-12-04 19:55:40 +00:00
|
|
|
#else
|
2023-10-30 23:22:50 +01:00
|
|
|
::poll(_fds.data(), nfds, 0);
|
2019-12-04 19:55:40 +00:00
|
|
|
#endif
|
2022-04-09 17:36:31 +02:00
|
|
|
for (s32 i = 0; i < nfds; i++)
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2022-04-09 17:36:31 +02:00
|
|
|
if (_fds[i].revents & (POLLIN | POLLHUP))
|
|
|
|
fds_buf[i].revents |= SYS_NET_POLLIN;
|
|
|
|
if (_fds[i].revents & POLLOUT)
|
|
|
|
fds_buf[i].revents |= SYS_NET_POLLOUT;
|
|
|
|
if (_fds[i].revents & POLLERR)
|
|
|
|
fds_buf[i].revents |= SYS_NET_POLLERR;
|
|
|
|
|
|
|
|
if (fds_buf[i].revents)
|
|
|
|
{
|
|
|
|
signaled++;
|
|
|
|
}
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
2022-04-09 14:51:22 +02:00
|
|
|
|
2022-04-09 17:36:31 +02:00
|
|
|
if (ms == 0 || signaled)
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2022-04-09 17:36:31 +02:00
|
|
|
lock.unlock();
|
|
|
|
nw_lock.unlock();
|
2023-10-30 23:22:50 +01:00
|
|
|
std::memcpy(fds.get_ptr(), fds_buf.data(), nfds * sizeof(sys_net_pollfd));
|
2022-04-09 17:36:31 +02:00
|
|
|
return not_an_error(signaled);
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
|
|
|
|
2022-04-09 17:36:31 +02:00
|
|
|
for (s32 i = 0; i < nfds; i++)
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2022-04-09 17:36:31 +02:00
|
|
|
if (fds_buf[i].fd < 0)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (auto sock = idm::check_unlocked<lv2_socket>(fds_buf[i].fd))
|
|
|
|
{
|
|
|
|
auto lock = sock->lock();
|
2017-09-25 18:52:34 +03:00
|
|
|
|
2019-12-17 04:00:29 +01:00
|
|
|
#ifdef _WIN32
|
2022-04-09 17:36:31 +02:00
|
|
|
sock->set_connecting(connecting[i]);
|
2019-12-17 04:00:29 +01:00
|
|
|
#endif
|
|
|
|
|
2022-04-09 17:36:31 +02:00
|
|
|
bs_t<lv2_socket::poll_t> selected = +lv2_socket::poll_t::error;
|
2017-12-02 12:36:05 +03:00
|
|
|
|
2022-04-09 17:36:31 +02:00
|
|
|
if (fds_buf[i].events & SYS_NET_POLLIN)
|
|
|
|
selected += lv2_socket::poll_t::read;
|
|
|
|
if (fds_buf[i].events & SYS_NET_POLLOUT)
|
|
|
|
selected += lv2_socket::poll_t::write;
|
|
|
|
// if (fds_buf[i].events & SYS_NET_POLLPRI) // Unimplemented
|
|
|
|
// selected += lv2_socket::poll::error;
|
2017-09-25 18:52:34 +03:00
|
|
|
|
2022-06-21 12:38:44 +03:00
|
|
|
sock->poll_queue(idm::get_unlocked<named_thread<ppu_thread>>(ppu.id), selected, [sock, selected, &fds_buf, i, &signaled, &ppu](bs_t<lv2_socket::poll_t> events)
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2022-04-09 17:36:31 +02:00
|
|
|
if (events & selected)
|
|
|
|
{
|
|
|
|
if (events & selected & lv2_socket::poll_t::read)
|
|
|
|
fds_buf[i].revents |= SYS_NET_POLLIN;
|
|
|
|
if (events & selected & lv2_socket::poll_t::write)
|
|
|
|
fds_buf[i].revents |= SYS_NET_POLLOUT;
|
|
|
|
if (events & selected & lv2_socket::poll_t::error)
|
|
|
|
fds_buf[i].revents |= SYS_NET_POLLERR;
|
|
|
|
|
|
|
|
signaled++;
|
2024-04-24 19:27:50 +02:00
|
|
|
sock->queue_wake(&ppu);
|
2022-04-09 17:36:31 +02:00
|
|
|
return true;
|
|
|
|
}
|
2017-09-25 18:52:34 +03:00
|
|
|
|
2022-04-09 17:36:31 +02:00
|
|
|
sock->set_poll_event(selected);
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
}
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
|
|
|
|
2022-04-09 17:36:31 +02:00
|
|
|
lv2_obj::sleep(ppu, timeout);
|
|
|
|
}
|
2022-04-09 14:51:22 +02:00
|
|
|
|
2022-06-21 12:38:44 +03:00
|
|
|
bool has_timedout = false;
|
|
|
|
|
2021-02-13 16:50:07 +02:00
|
|
|
while (auto state = ppu.state.fetch_sub(cpu_flag::signal))
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2021-02-13 16:50:07 +02:00
|
|
|
if (is_stopped(state))
|
|
|
|
{
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
|
|
|
if (state & cpu_flag::signal)
|
2018-10-11 01:17:19 +03:00
|
|
|
{
|
2021-02-13 16:50:07 +02:00
|
|
|
break;
|
2018-10-11 01:17:19 +03:00
|
|
|
}
|
|
|
|
|
2017-09-25 18:52:34 +03:00
|
|
|
if (timeout)
|
|
|
|
{
|
2019-07-14 06:55:11 +03:00
|
|
|
if (lv2_obj::wait_timeout(timeout, &ppu))
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2020-03-28 06:16:59 +03:00
|
|
|
// Wait for rescheduling
|
|
|
|
if (ppu.check_state())
|
|
|
|
{
|
2021-02-13 16:50:07 +02:00
|
|
|
return {};
|
2020-03-28 06:16:59 +03:00
|
|
|
}
|
|
|
|
|
2022-06-21 12:38:44 +03:00
|
|
|
has_timedout = network_clear_queue(ppu);
|
2024-11-22 13:58:10 +01:00
|
|
|
clear_ppu_to_awake(ppu);
|
2024-06-13 21:06:12 +02:00
|
|
|
ppu.state -= cpu_flag::signal;
|
2017-09-25 18:52:34 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-09-20 11:47:05 +03:00
|
|
|
ppu.state.wait(state);
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-21 12:38:44 +03:00
|
|
|
if (!has_timedout && !signaled)
|
|
|
|
{
|
|
|
|
return -SYS_NET_EINTR;
|
|
|
|
}
|
|
|
|
|
2024-02-09 12:45:27 +01:00
|
|
|
std::memcpy(fds.get_ptr(), fds_buf.data(), nfds * sizeof(fds[0]));
|
|
|
|
|
2019-11-21 18:44:00 +02:00
|
|
|
return not_an_error(signaled);
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
|
|
|
|
2019-11-21 18:44:00 +02:00
|
|
|
error_code sys_net_bnet_select(ppu_thread& ppu, s32 nfds, vm::ptr<sys_net_fd_set> readfds, vm::ptr<sys_net_fd_set> writefds, vm::ptr<sys_net_fd_set> exceptfds, vm::ptr<sys_net_timeval> _timeout)
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2020-06-05 12:36:28 +03:00
|
|
|
ppu.state += cpu_flag::wait;
|
2019-07-14 18:11:00 +03:00
|
|
|
|
2024-04-24 19:27:50 +02:00
|
|
|
sys_net.trace("sys_net_bnet_select(nfds=%d, readfds=*0x%x, writefds=*0x%x, exceptfds=*0x%x, timeout=*0x%x(%d:%d))", nfds, readfds, writefds, exceptfds, _timeout, _timeout ? _timeout->tv_sec.value() : 0, _timeout ? _timeout->tv_usec.value() : 0);
|
2017-09-25 18:52:34 +03:00
|
|
|
|
|
|
|
atomic_t<s32> signaled{0};
|
|
|
|
|
|
|
|
if (exceptfds)
|
|
|
|
{
|
2021-09-04 10:27:40 +03:00
|
|
|
struct log_t
|
|
|
|
{
|
|
|
|
atomic_t<bool> logged = false;
|
|
|
|
};
|
|
|
|
|
|
|
|
if (!g_fxo->get<log_t>().logged.exchange(true))
|
|
|
|
{
|
|
|
|
sys_net.error("sys_net_bnet_select(): exceptfds not implemented");
|
|
|
|
}
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
|
|
|
|
2020-04-12 10:51:59 +03:00
|
|
|
sys_net_fd_set rread{}, _readfds{};
|
|
|
|
sys_net_fd_set rwrite{}, _writefds{};
|
|
|
|
sys_net_fd_set rexcept{}, _exceptfds{};
|
2017-09-25 18:52:34 +03:00
|
|
|
u64 timeout = !_timeout ? 0 : _timeout->tv_sec * 1000000ull + _timeout->tv_usec;
|
|
|
|
|
2020-01-10 03:03:10 +03:00
|
|
|
if (nfds > 0 && nfds <= 1024)
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2020-04-12 10:51:59 +03:00
|
|
|
if (readfds)
|
|
|
|
_readfds = *readfds;
|
|
|
|
if (writefds)
|
|
|
|
_writefds = *writefds;
|
|
|
|
if (exceptfds)
|
|
|
|
_exceptfds = *exceptfds;
|
|
|
|
|
2024-04-24 19:27:50 +02:00
|
|
|
std::lock_guard nw_lock(g_fxo->get<network_context>().mutex_thread_loop);
|
2017-09-25 18:52:34 +03:00
|
|
|
reader_lock lock(id_manager::g_mutex);
|
|
|
|
|
2023-10-30 23:22:50 +01:00
|
|
|
std::vector<::pollfd> _fds(nfds);
|
2019-12-17 04:00:29 +01:00
|
|
|
#ifdef _WIN32
|
2023-10-30 23:22:50 +01:00
|
|
|
std::vector<bool> connecting(nfds);
|
2019-12-17 04:00:29 +01:00
|
|
|
#endif
|
2017-09-25 18:52:34 +03:00
|
|
|
|
|
|
|
for (s32 i = 0; i < nfds; i++)
|
|
|
|
{
|
|
|
|
_fds[i].fd = -1;
|
2022-04-09 14:51:22 +02:00
|
|
|
bs_t<lv2_socket::poll_t> selected{};
|
2017-09-25 18:52:34 +03:00
|
|
|
|
2020-04-12 10:51:59 +03:00
|
|
|
if (readfds && _readfds.bit(i))
|
2022-04-09 14:51:22 +02:00
|
|
|
selected += lv2_socket::poll_t::read;
|
2020-04-12 10:51:59 +03:00
|
|
|
if (writefds && _writefds.bit(i))
|
2022-04-09 14:51:22 +02:00
|
|
|
selected += lv2_socket::poll_t::write;
|
|
|
|
// if (exceptfds && _exceptfds.bit(i))
|
2017-09-25 18:52:34 +03:00
|
|
|
// selected += lv2_socket::poll::error;
|
|
|
|
|
2018-09-02 20:22:35 +03:00
|
|
|
if (selected)
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2022-04-09 14:51:22 +02:00
|
|
|
selected += lv2_socket::poll_t::error;
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2017-12-25 21:08:04 +03:00
|
|
|
if (auto sock = idm::check_unlocked<lv2_socket>((lv2_socket::id_base & -1024) + i))
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2022-04-09 20:07:11 +02:00
|
|
|
auto [read_set, write_set, except_set] = sock->select(selected, _fds[i]);
|
|
|
|
|
|
|
|
if (read_set || write_set || except_set)
|
2020-08-27 21:47:04 +02:00
|
|
|
{
|
2022-04-09 14:51:22 +02:00
|
|
|
signaled++;
|
2020-08-27 21:47:04 +02:00
|
|
|
}
|
2022-04-09 14:51:22 +02:00
|
|
|
|
2022-04-09 20:07:11 +02:00
|
|
|
if (read_set)
|
|
|
|
{
|
|
|
|
rread.set(i);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (write_set)
|
|
|
|
{
|
|
|
|
rwrite.set(i);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (except_set)
|
|
|
|
{
|
|
|
|
rexcept.set(i);
|
|
|
|
}
|
|
|
|
|
2019-12-17 04:00:29 +01:00
|
|
|
#ifdef _WIN32
|
2022-04-09 14:51:22 +02:00
|
|
|
connecting[i] = sock->is_connecting();
|
2019-12-17 04:00:29 +01:00
|
|
|
#endif
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return -SYS_NET_EBADF;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-04 19:55:40 +00:00
|
|
|
#ifdef _WIN32
|
2019-12-17 04:00:29 +01:00
|
|
|
windows_poll(_fds, nfds, 0, connecting);
|
2019-12-04 19:55:40 +00:00
|
|
|
#else
|
2023-10-30 23:22:50 +01:00
|
|
|
::poll(_fds.data(), nfds, 0);
|
2019-12-04 19:55:40 +00:00
|
|
|
#endif
|
2017-09-25 18:52:34 +03:00
|
|
|
for (s32 i = 0; i < nfds; i++)
|
|
|
|
{
|
|
|
|
bool sig = false;
|
|
|
|
if (_fds[i].revents & (POLLIN | POLLHUP | POLLERR))
|
|
|
|
sig = true, rread.set(i);
|
|
|
|
if (_fds[i].revents & (POLLOUT | POLLERR))
|
|
|
|
sig = true, rwrite.set(i);
|
|
|
|
|
|
|
|
if (sig)
|
|
|
|
{
|
|
|
|
signaled++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((_timeout && !timeout) || signaled)
|
|
|
|
{
|
|
|
|
if (readfds)
|
|
|
|
*readfds = rread;
|
|
|
|
if (writefds)
|
|
|
|
*writefds = rwrite;
|
|
|
|
if (exceptfds)
|
|
|
|
*exceptfds = rexcept;
|
2019-11-21 18:44:00 +02:00
|
|
|
return not_an_error(signaled);
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
for (s32 i = 0; i < nfds; i++)
|
|
|
|
{
|
2022-04-09 14:51:22 +02:00
|
|
|
bs_t<lv2_socket::poll_t> selected{};
|
2017-09-25 18:52:34 +03:00
|
|
|
|
2020-04-12 10:51:59 +03:00
|
|
|
if (readfds && _readfds.bit(i))
|
2022-04-09 14:51:22 +02:00
|
|
|
selected += lv2_socket::poll_t::read;
|
2020-04-12 10:51:59 +03:00
|
|
|
if (writefds && _writefds.bit(i))
|
2022-04-09 14:51:22 +02:00
|
|
|
selected += lv2_socket::poll_t::write;
|
|
|
|
// if (exceptfds && _exceptfds.bit(i))
|
|
|
|
// selected += lv2_socket::poll_t::error;
|
2017-09-25 18:52:34 +03:00
|
|
|
|
2018-09-02 20:22:35 +03:00
|
|
|
if (selected)
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2022-04-09 14:51:22 +02:00
|
|
|
selected += lv2_socket::poll_t::error;
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2017-12-25 21:08:04 +03:00
|
|
|
if (auto sock = idm::check_unlocked<lv2_socket>((lv2_socket::id_base & -1024) + i))
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2022-04-09 14:51:22 +02:00
|
|
|
auto lock = sock->lock();
|
2019-12-17 04:00:29 +01:00
|
|
|
#ifdef _WIN32
|
2022-04-09 14:51:22 +02:00
|
|
|
sock->set_connecting(connecting[i]);
|
2019-12-17 04:00:29 +01:00
|
|
|
#endif
|
|
|
|
|
2022-06-21 12:38:44 +03:00
|
|
|
sock->poll_queue(idm::get_unlocked<named_thread<ppu_thread>>(ppu.id), selected, [sock, selected, i, &rread, &rwrite, &rexcept, &signaled, &ppu](bs_t<lv2_socket::poll_t> events)
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2022-04-09 14:51:22 +02:00
|
|
|
if (events & selected)
|
|
|
|
{
|
|
|
|
if (selected & lv2_socket::poll_t::read && events & (lv2_socket::poll_t::read + lv2_socket::poll_t::error))
|
|
|
|
rread.set(i);
|
|
|
|
if (selected & lv2_socket::poll_t::write && events & (lv2_socket::poll_t::write + lv2_socket::poll_t::error))
|
|
|
|
rwrite.set(i);
|
|
|
|
// if (events & (selected & lv2_socket::poll::error))
|
|
|
|
// rexcept.set(i);
|
2017-09-25 18:52:34 +03:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
signaled++;
|
2024-04-24 19:27:50 +02:00
|
|
|
sock->queue_wake(&ppu);
|
2022-04-09 14:51:22 +02:00
|
|
|
return true;
|
|
|
|
}
|
2017-09-25 18:52:34 +03:00
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
sock->set_poll_event(selected);
|
|
|
|
return false;
|
|
|
|
});
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return -SYS_NET_EBADF;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
lv2_obj::sleep(ppu, timeout);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return -SYS_NET_EINVAL;
|
|
|
|
}
|
2017-12-02 12:36:05 +03:00
|
|
|
|
2022-06-21 12:38:44 +03:00
|
|
|
bool has_timedout = false;
|
|
|
|
|
2021-02-13 16:50:07 +02:00
|
|
|
while (auto state = ppu.state.fetch_sub(cpu_flag::signal))
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2021-02-13 16:50:07 +02:00
|
|
|
if (is_stopped(state))
|
|
|
|
{
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
|
|
|
if (state & cpu_flag::signal)
|
2018-10-11 01:17:19 +03:00
|
|
|
{
|
2021-02-13 16:50:07 +02:00
|
|
|
break;
|
2018-10-11 01:17:19 +03:00
|
|
|
}
|
|
|
|
|
2017-09-25 18:52:34 +03:00
|
|
|
if (timeout)
|
|
|
|
{
|
2019-07-14 06:55:11 +03:00
|
|
|
if (lv2_obj::wait_timeout(timeout, &ppu))
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2020-03-28 06:16:59 +03:00
|
|
|
// Wait for rescheduling
|
|
|
|
if (ppu.check_state())
|
|
|
|
{
|
2021-02-13 16:50:07 +02:00
|
|
|
return {};
|
2020-03-28 06:16:59 +03:00
|
|
|
}
|
|
|
|
|
2022-06-21 12:38:44 +03:00
|
|
|
has_timedout = network_clear_queue(ppu);
|
2024-11-22 13:58:10 +01:00
|
|
|
clear_ppu_to_awake(ppu);
|
2024-06-13 21:06:12 +02:00
|
|
|
ppu.state -= cpu_flag::signal;
|
2017-09-25 18:52:34 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-09-20 11:47:05 +03:00
|
|
|
ppu.state.wait(state);
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-09 12:45:27 +01:00
|
|
|
if (!has_timedout && !signaled)
|
|
|
|
{
|
|
|
|
return -SYS_NET_EINTR;
|
|
|
|
}
|
|
|
|
|
2017-09-25 18:52:34 +03:00
|
|
|
if (readfds)
|
|
|
|
*readfds = rread;
|
|
|
|
if (writefds)
|
|
|
|
*writefds = rwrite;
|
|
|
|
if (exceptfds)
|
|
|
|
*exceptfds = rexcept;
|
|
|
|
|
2019-11-21 18:44:00 +02:00
|
|
|
return not_an_error(signaled);
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
|
|
|
|
2019-11-21 18:44:00 +02:00
|
|
|
error_code _sys_net_open_dump(ppu_thread& ppu, s32 len, s32 flags)
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2020-06-05 12:36:28 +03:00
|
|
|
ppu.state += cpu_flag::wait;
|
2019-07-14 18:11:00 +03:00
|
|
|
|
2017-09-25 18:52:34 +03:00
|
|
|
sys_net.todo("_sys_net_open_dump(len=%d, flags=0x%x)", len, flags);
|
2019-11-21 18:44:00 +02:00
|
|
|
return CELL_OK;
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
|
|
|
|
2019-11-21 18:44:00 +02:00
|
|
|
error_code _sys_net_read_dump(ppu_thread& ppu, s32 id, vm::ptr<void> buf, s32 len, vm::ptr<s32> pflags)
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2020-06-05 12:36:28 +03:00
|
|
|
ppu.state += cpu_flag::wait;
|
2019-07-14 18:11:00 +03:00
|
|
|
|
2017-09-25 18:52:34 +03:00
|
|
|
sys_net.todo("_sys_net_read_dump(id=0x%x, buf=*0x%x, len=%d, pflags=*0x%x)", id, buf, len, pflags);
|
2019-11-21 18:44:00 +02:00
|
|
|
return CELL_OK;
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
|
|
|
|
2019-11-21 18:44:00 +02:00
|
|
|
error_code _sys_net_close_dump(ppu_thread& ppu, s32 id, vm::ptr<s32> pflags)
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2020-06-05 12:36:28 +03:00
|
|
|
ppu.state += cpu_flag::wait;
|
2019-07-14 18:11:00 +03:00
|
|
|
|
2017-09-25 18:52:34 +03:00
|
|
|
sys_net.todo("_sys_net_close_dump(id=0x%x, pflags=*0x%x)", id, pflags);
|
2019-11-21 18:44:00 +02:00
|
|
|
return CELL_OK;
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
|
|
|
|
2019-11-21 18:44:00 +02:00
|
|
|
error_code _sys_net_write_dump(ppu_thread& ppu, s32 id, vm::cptr<void> buf, s32 len, u32 unknown)
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2020-06-05 12:36:28 +03:00
|
|
|
ppu.state += cpu_flag::wait;
|
2019-07-14 18:11:00 +03:00
|
|
|
|
2021-03-05 22:05:37 +03:00
|
|
|
sys_net.todo("_sys_net_write_dump(id=0x%x, buf=*0x%x, len=%d, unk=0x%x)", id, buf, len, unknown);
|
2019-11-21 18:44:00 +02:00
|
|
|
return CELL_OK;
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
|
|
|
|
2022-06-21 12:38:44 +03:00
|
|
|
error_code lv2_socket::abort_socket(s32 flags)
|
|
|
|
{
|
|
|
|
decltype(queue) qcopy;
|
|
|
|
{
|
|
|
|
std::lock_guard lock(mutex);
|
|
|
|
|
|
|
|
if (queue.empty())
|
|
|
|
{
|
|
|
|
if (flags & SYS_NET_ABORT_STRICT_CHECK)
|
|
|
|
{
|
|
|
|
// Strict error checking: ENOENT if nothing happened
|
|
|
|
return -SYS_NET_ENOENT;
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: Abort the subsequent function called on this socket (need to investigate correct behaviour)
|
|
|
|
return CELL_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
qcopy = std::move(queue);
|
2024-04-05 18:50:40 +02:00
|
|
|
queue = {};
|
2022-06-21 12:38:44 +03:00
|
|
|
events.store({});
|
|
|
|
}
|
|
|
|
|
|
|
|
for (auto& [ppu, _] : qcopy)
|
|
|
|
{
|
2022-05-18 17:44:21 +02:00
|
|
|
if (!ppu)
|
|
|
|
continue;
|
2023-02-13 02:33:06 -08:00
|
|
|
|
2024-11-22 13:58:10 +01:00
|
|
|
// Avoid possible double signaling
|
|
|
|
network_clear_queue(*ppu);
|
|
|
|
clear_ppu_to_awake(*ppu);
|
|
|
|
|
2022-06-21 12:38:44 +03:00
|
|
|
sys_net.warning("lv2_socket::abort_socket(): waking up \"%s\": (func: %s, r3=0x%x, r4=0x%x, r5=0x%x, r6=0x%x)", ppu->get_name(), ppu->current_function, ppu->gpr[3], ppu->gpr[4], ppu->gpr[5], ppu->gpr[6]);
|
|
|
|
ppu->gpr[3] = static_cast<u64>(-SYS_NET_EINTR);
|
|
|
|
lv2_obj::append(ppu.get());
|
|
|
|
}
|
|
|
|
|
2024-06-30 10:35:36 +02:00
|
|
|
const u32 num_waiters = ::size32(qcopy);
|
2024-04-24 19:27:50 +02:00
|
|
|
if (num_waiters && (type == SYS_NET_SOCK_STREAM || type == SYS_NET_SOCK_DGRAM))
|
|
|
|
{
|
|
|
|
auto& nc = g_fxo->get<network_context>();
|
|
|
|
const u32 prev_value = nc.num_polls.fetch_sub(num_waiters);
|
|
|
|
ensure(prev_value >= num_waiters);
|
|
|
|
}
|
|
|
|
|
2022-06-21 12:38:44 +03:00
|
|
|
lv2_obj::awake_all();
|
|
|
|
return CELL_OK;
|
|
|
|
}
|
|
|
|
|
2019-11-21 18:44:00 +02:00
|
|
|
error_code sys_net_abort(ppu_thread& ppu, s32 type, u64 arg, s32 flags)
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2020-06-05 12:36:28 +03:00
|
|
|
ppu.state += cpu_flag::wait;
|
2019-07-14 18:11:00 +03:00
|
|
|
|
2023-01-12 04:05:05 +01:00
|
|
|
sys_net.warning("sys_net_abort(type=%d, arg=0x%x, flags=0x%x)", type, arg, flags);
|
2022-06-21 12:38:44 +03:00
|
|
|
|
|
|
|
enum abort_type : s32
|
|
|
|
{
|
|
|
|
_socket,
|
|
|
|
resolver,
|
|
|
|
type_2, // ??
|
|
|
|
type_3, // ??
|
|
|
|
all,
|
|
|
|
};
|
|
|
|
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case _socket:
|
|
|
|
{
|
2024-04-24 19:27:50 +02:00
|
|
|
std::lock_guard nw_lock(g_fxo->get<network_context>().mutex_thread_loop);
|
2022-06-21 12:38:44 +03:00
|
|
|
|
2024-12-22 20:59:48 +02:00
|
|
|
const auto sock = idm::get_unlocked<lv2_socket>(static_cast<u32>(arg));
|
2022-06-21 12:38:44 +03:00
|
|
|
|
|
|
|
if (!sock)
|
|
|
|
{
|
|
|
|
return -SYS_NET_EBADF;
|
|
|
|
}
|
|
|
|
|
|
|
|
return sock->abort_socket(flags);
|
|
|
|
}
|
|
|
|
case all:
|
|
|
|
{
|
|
|
|
std::vector<u32> sockets;
|
|
|
|
|
|
|
|
idm::select<lv2_socket>([&](u32 id, lv2_socket&)
|
|
|
|
{
|
|
|
|
sockets.emplace_back(id);
|
|
|
|
});
|
|
|
|
|
|
|
|
s32 failed = 0;
|
|
|
|
|
|
|
|
for (u32 id : sockets)
|
|
|
|
{
|
|
|
|
const auto sock = idm::withdraw<lv2_socket>(id);
|
|
|
|
|
|
|
|
if (!sock)
|
|
|
|
{
|
|
|
|
failed++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sock->get_queue_size())
|
|
|
|
sys_net.error("ABORT 4");
|
|
|
|
|
|
|
|
sock->close();
|
|
|
|
|
2023-02-13 02:33:06 -08:00
|
|
|
sys_net.success("lv2_socket::handle_abort(): Closed socket %d", id);
|
2022-06-21 12:38:44 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// Ensures the socket has no lingering copy from the network thread
|
2024-04-24 19:27:50 +02:00
|
|
|
g_fxo->get<network_context>().mutex_thread_loop.lock_unlock();
|
2022-06-21 12:38:44 +03:00
|
|
|
|
|
|
|
return not_an_error(::narrow<s32>(sockets.size()) - failed);
|
|
|
|
}
|
|
|
|
case resolver:
|
|
|
|
case type_2:
|
|
|
|
case type_3:
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default: return -SYS_NET_EINVAL;
|
|
|
|
}
|
|
|
|
|
2019-11-21 18:44:00 +02:00
|
|
|
return CELL_OK;
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
|
|
|
|
2020-06-12 12:48:01 +03:00
|
|
|
struct net_infoctl_cmd_9_t
|
|
|
|
{
|
|
|
|
be_t<u32> zero;
|
|
|
|
vm::bptr<char> server_name;
|
|
|
|
// More (TODO)
|
|
|
|
};
|
|
|
|
|
2019-11-21 18:44:00 +02:00
|
|
|
error_code sys_net_infoctl(ppu_thread& ppu, s32 cmd, vm::ptr<void> arg)
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2020-06-05 12:36:28 +03:00
|
|
|
ppu.state += cpu_flag::wait;
|
2019-07-14 18:11:00 +03:00
|
|
|
|
2017-09-25 18:52:34 +03:00
|
|
|
sys_net.todo("sys_net_infoctl(cmd=%d, arg=*0x%x)", cmd, arg);
|
2020-06-12 12:48:01 +03:00
|
|
|
|
|
|
|
// TODO
|
|
|
|
switch (cmd)
|
|
|
|
{
|
|
|
|
case 9:
|
|
|
|
{
|
2020-07-07 01:25:29 -05:00
|
|
|
constexpr auto nameserver = "nameserver \0"sv;
|
|
|
|
|
2020-09-09 00:19:57 +02:00
|
|
|
char buffer[nameserver.size() + 80]{};
|
2020-07-07 01:25:29 -05:00
|
|
|
std::memcpy(buffer, nameserver.data(), nameserver.size());
|
|
|
|
|
2022-04-09 14:51:22 +02:00
|
|
|
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
|
2021-10-28 06:36:57 +02:00
|
|
|
const auto dns_str = np::ip_to_string(nph.get_dns_ip());
|
2020-09-09 00:19:57 +02:00
|
|
|
std::memcpy(buffer + nameserver.size() - 1, dns_str.data(), dns_str.size());
|
2020-07-07 01:25:29 -05:00
|
|
|
|
|
|
|
std::string_view name{buffer};
|
|
|
|
vm::static_ptr_cast<net_infoctl_cmd_9_t>(arg)->zero = 0;
|
2020-06-12 12:48:01 +03:00
|
|
|
std::memcpy(vm::static_ptr_cast<net_infoctl_cmd_9_t>(arg)->server_name.get_ptr(), name.data(), name.size());
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default: break;
|
|
|
|
}
|
|
|
|
|
2019-11-21 18:44:00 +02:00
|
|
|
return CELL_OK;
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
|
|
|
|
2019-11-21 18:44:00 +02:00
|
|
|
error_code sys_net_control(ppu_thread& ppu, u32 arg1, s32 arg2, vm::ptr<void> arg3, s32 arg4)
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2020-06-05 12:36:28 +03:00
|
|
|
ppu.state += cpu_flag::wait;
|
2019-07-14 18:11:00 +03:00
|
|
|
|
2017-09-25 18:52:34 +03:00
|
|
|
sys_net.todo("sys_net_control(0x%x, %d, *0x%x, %d)", arg1, arg2, arg3, arg4);
|
2019-11-21 18:44:00 +02:00
|
|
|
return CELL_OK;
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
|
|
|
|
2019-11-21 18:44:00 +02:00
|
|
|
error_code sys_net_bnet_ioctl(ppu_thread& ppu, s32 arg1, u32 arg2, u32 arg3)
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2020-06-05 12:36:28 +03:00
|
|
|
ppu.state += cpu_flag::wait;
|
2019-07-14 18:11:00 +03:00
|
|
|
|
2017-09-25 18:52:34 +03:00
|
|
|
sys_net.todo("sys_net_bnet_ioctl(%d, 0x%x, 0x%x)", arg1, arg2, arg3);
|
2019-11-21 18:44:00 +02:00
|
|
|
return CELL_OK;
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
|
|
|
|
2019-11-21 18:44:00 +02:00
|
|
|
error_code sys_net_bnet_sysctl(ppu_thread& ppu, u32 arg1, u32 arg2, u32 arg3, vm::ptr<void> arg4, u32 arg5, u32 arg6)
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2020-06-05 12:36:28 +03:00
|
|
|
ppu.state += cpu_flag::wait;
|
2019-07-14 18:11:00 +03:00
|
|
|
|
2017-09-25 18:52:34 +03:00
|
|
|
sys_net.todo("sys_net_bnet_sysctl(0x%x, 0x%x, 0x%x, *0x%x, 0x%x, 0x%x)", arg1, arg2, arg3, arg4, arg5, arg6);
|
2019-11-21 18:44:00 +02:00
|
|
|
return CELL_OK;
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|
|
|
|
|
2019-11-21 18:44:00 +02:00
|
|
|
error_code sys_net_eurus_post_command(ppu_thread& ppu, s32 arg1, u32 arg2, u32 arg3)
|
2017-09-25 18:52:34 +03:00
|
|
|
{
|
2020-06-05 12:36:28 +03:00
|
|
|
ppu.state += cpu_flag::wait;
|
2019-07-14 18:11:00 +03:00
|
|
|
|
2017-09-25 18:52:34 +03:00
|
|
|
sys_net.todo("sys_net_eurus_post_command(%d, 0x%x, 0x%x)", arg1, arg2, arg3);
|
2019-11-21 18:44:00 +02:00
|
|
|
return CELL_OK;
|
2017-09-25 18:52:34 +03:00
|
|
|
}
|