Various sys_net improvements

Implement P2PS select
Adjust P2P sendto return value
This commit is contained in:
RipleyTom 2022-04-09 20:07:11 +02:00 committed by Megamouse
parent 039d19dacf
commit c06cb4664a
12 changed files with 94 additions and 36 deletions

View File

@ -1279,10 +1279,26 @@ error_code sys_net_bnet_select(ppu_thread& ppu, s32 nfds, vm::ptr<sys_net_fd_set
if (auto sock = idm::check_unlocked<lv2_socket>((lv2_socket::id_base & -1024) + i))
{
if (sock->select(selected, _fds[i]))
auto [read_set, write_set, except_set] = sock->select(selected, _fds[i]);
if (read_set || write_set || except_set)
{
signaled++;
}
if (read_set)
{
rread.set(i);
signaled++;
}
if (write_set)
{
rwrite.set(i);
}
if (except_set)
{
rexcept.set(i);
}
#ifdef _WIN32

View File

@ -21,11 +21,10 @@
#endif
#endif
#ifdef _WIN32
using socket_type = uptr;
using socket_type = uptr;
#else
using socket_type = int;
using socket_type = int;
#endif
class lv2_socket
@ -73,34 +72,33 @@ public:
#endif
public:
virtual std::tuple<bool, s32, sys_net_sockaddr> accept(bool is_lock = true) = 0;
virtual s32 bind(const sys_net_sockaddr &addr, s32 ps3_id) = 0;
virtual s32 bind(const sys_net_sockaddr& addr, s32 ps3_id) = 0;
virtual std::optional<s32> connect(const sys_net_sockaddr &addr) = 0;
virtual s32 connect_followup() = 0;
virtual std::optional<s32> connect(const sys_net_sockaddr& addr) = 0;
virtual s32 connect_followup() = 0;
virtual std::pair<s32, sys_net_sockaddr> getpeername() = 0;
virtual std::pair<s32, sys_net_sockaddr> getsockname() = 0;
virtual std::tuple<s32, sockopt_data, u32> getsockopt(s32 level, s32 optname, u32 len) = 0;
virtual s32 setsockopt(s32 level, s32 optname, const std::vector<u8>& optval) = 0;
virtual s32 setsockopt(s32 level, s32 optname, const std::vector<u8>& optval) = 0;
virtual s32 listen(s32 backlog) = 0;
virtual std::optional<std::tuple<s32, std::vector<u8>, sys_net_sockaddr>> recvfrom(s32 flags, u32 len, bool is_lock = true) = 0;
virtual std::optional<std::tuple<s32, std::vector<u8>, sys_net_sockaddr>> recvfrom(s32 flags, u32 len, bool is_lock = true) = 0;
virtual std::optional<s32> sendto(s32 flags, const std::vector<u8>& buf, std::optional<sys_net_sockaddr> opt_sn_addr, bool is_lock = true) = 0;
virtual void close() = 0;
virtual void close() = 0;
virtual s32 shutdown(s32 how) = 0;
virtual s32 poll(sys_net_pollfd& sn_pfd, pollfd& native_pfd) = 0;
virtual s32 select(bs_t<poll_t> selected, pollfd& native_pfd) = 0;
virtual s32 poll(sys_net_pollfd& sn_pfd, pollfd& native_pfd) = 0;
virtual std::tuple<bool, bool, bool> select(bs_t<poll_t> selected, pollfd& native_pfd) = 0;
public:
// IDM data
static const u32 id_base = 24;
static const u32 id_step = 1;
static const u32 id_base = 24;
static const u32 id_step = 1;
static const u32 id_count = 1000;
protected:

View File

@ -969,7 +969,7 @@ s32 lv2_socket_native::poll(sys_net_pollfd& sn_pfd, pollfd& native_pfd)
return 0;
}
s32 lv2_socket_native::select(bs_t<lv2_socket::poll_t> selected, pollfd& native_pfd)
std::tuple<bool, bool, bool> lv2_socket_native::select(bs_t<lv2_socket::poll_t> selected, pollfd& native_pfd)
{
native_pfd.fd = socket;
if (selected & lv2_socket::poll_t::read)
@ -981,7 +981,7 @@ s32 lv2_socket_native::select(bs_t<lv2_socket::poll_t> selected, pollfd& native_
native_pfd.events |= POLLOUT;
}
return 0;
return {};
}
void lv2_socket_native::set_default_buffers()

View File

@ -48,7 +48,7 @@ public:
std::optional<s32> sendto(s32 flags, const std::vector<u8>& buf, std::optional<sys_net_sockaddr> opt_sn_addr, bool is_lock = true) override;
s32 poll(sys_net_pollfd& sn_pfd, pollfd& native_pfd) override;
s32 select(bs_t<poll_t> selected, pollfd& native_pfd) override;
std::tuple<bool, bool, bool> select(bs_t<poll_t> selected, pollfd& native_pfd) override;
s32 listen(s32 backlog) override;
void close() override;

View File

@ -221,7 +221,7 @@ std::optional<s32> lv2_socket_p2p::sendto(s32 flags, const std::vector<u8>& buf,
if (native_result >= 0)
{
return {native_result};
return {std::max<s32>(native_result - sizeof(u16), 0l)};
}
s32 result = get_last_error(!so_nbio && (flags & SYS_NET_MSG_DONTWAIT) == 0);
@ -281,15 +281,25 @@ s32 lv2_socket_p2p::poll(sys_net_pollfd& sn_pfd, [[maybe_unused]] pollfd& native
return sn_pfd.revents ? 1 : 0;
}
s32 lv2_socket_p2p::select(bs_t<lv2_socket::poll_t> selected, [[maybe_unused]] pollfd& native_pfd)
std::tuple<bool, bool, bool> lv2_socket_p2p::select(bs_t<lv2_socket::poll_t> selected, [[maybe_unused]] pollfd& native_pfd)
{
std::lock_guard lock(mutex);
bool read_set = false;
bool write_set = false;
// Check if it's a bound P2P socket
if ((selected & lv2_socket::poll_t::read) && vport && !data.empty())
{
sys_net.trace("[P2P] p2p_data for vport %d contains %d elements", vport, data.size());
return 1;
read_set = true;
}
return 0;
if (selected & lv2_socket::poll_t::write)
{
sys_net.trace("[P2P] p2p_data for vport %d contains %d elements", vport, data.size());
write_set = true;
}
return {read_set, write_set, false};
}

View File

@ -4,13 +4,13 @@
class lv2_socket_p2p : public lv2_socket
{
public:
public:
lv2_socket_p2p(lv2_socket_family family, lv2_socket_type type, lv2_ip_protocol protocol);
std::tuple<bool, s32, sys_net_sockaddr> accept(bool is_lock = true) override;
s32 bind(const sys_net_sockaddr &addr, s32 ps3_id) override;
s32 bind(const sys_net_sockaddr& addr, s32 ps3_id) override;
std::optional<s32> connect(const sys_net_sockaddr &addr) override;
std::optional<s32> connect(const sys_net_sockaddr& addr) override;
s32 connect_followup() override;
std::pair<s32, sys_net_sockaddr> getpeername() override;
@ -28,11 +28,11 @@ class lv2_socket_p2p : public lv2_socket
s32 shutdown(s32 how) override;
s32 poll(sys_net_pollfd& sn_pfd, pollfd& native_pfd) override;
s32 select(bs_t<poll_t> selected, pollfd& native_pfd) override;
std::tuple<bool, bool, bool> select(bs_t<poll_t> selected, pollfd& native_pfd) override;
void handle_new_data(sys_net_sockaddr_in_p2p p2p_addr, std::vector<u8> p2p_data);
protected:
protected:
// Port(actual bound port) and Virtual Port(indicated by u16 at the start of the packet)
u16 port = 3658, vport = 0;
u32 bound_addr = 0;

View File

@ -796,3 +796,37 @@ s32 lv2_socket_p2ps::poll(sys_net_pollfd& sn_pfd, [[maybe_unused]] pollfd& nativ
return 0;
}
std::tuple<bool, bool, bool> lv2_socket_p2ps::select(bs_t<lv2_socket::poll_t> selected, [[maybe_unused]] pollfd& native_pfd)
{
std::lock_guard lock(mutex);
bool read_set = false;
bool write_set = false;
if (status == p2ps_stream_status::stream_connected)
{
if ((selected & lv2_socket::poll_t::read) && data_available)
{
sys_net.trace("[P2PS] socket has %d bytes available", data_available);
read_set = true;
}
if (selected & lv2_socket::poll_t::write)
{
sys_net.trace("[P2PS] socket is writeable");
write_set = true;
}
}
else if (status == p2ps_stream_status::stream_listening)
{
const auto bsize = backlog.size();
if ((selected & lv2_socket::poll_t::read) && bsize)
{
sys_net.trace("[P2PS] socket has %d clients available", bsize);
read_set = true;
}
}
return {read_set, write_set, false};
}

View File

@ -21,8 +21,8 @@ constexpr be_t<u32> P2PS_U2S_SIG = (static_cast<u32>('U') << 24 | static_cast<u3
struct p2ps_encapsulated_tcp
{
be_t<u32> signature = P2PS_U2S_SIG; // Signature to verify it's P2P Stream data
be_t<u32> length = 0; // Length of data
be_t<u64> seq = 0; // This should be u32 but changed to u64 for simplicity
be_t<u32> length = 0; // Length of data
be_t<u64> seq = 0; // This should be u32 but changed to u64 for simplicity
be_t<u64> ack = 0;
be_t<u16> src_port = 0; // fake source tcp port
be_t<u16> dst_port = 0; // fake dest tcp port(should be == vport)
@ -71,7 +71,7 @@ public:
std::optional<s32> connect(const sys_net_sockaddr& addr) override;
//std::pair<s32, sys_net_sockaddr> getsockname() override;
// std::pair<s32, sys_net_sockaddr> getsockname() override;
s32 listen(s32 backlog) override;
@ -82,6 +82,7 @@ public:
s32 shutdown(s32 how) override;
s32 poll(sys_net_pollfd& sn_pfd, pollfd& native_pfd) override;
std::tuple<bool, bool, bool> select(bs_t<poll_t> selected, pollfd& native_pfd) override;
protected:
static constexpr usz MAX_RECEIVED_BUFFER = (1024 * 1024 * 10);

View File

@ -91,7 +91,7 @@ s32 lv2_socket_raw::poll([[maybe_unused]] sys_net_pollfd& sn_pfd, [[maybe_unused
return {};
}
s32 lv2_socket_raw::select([[maybe_unused]] bs_t<lv2_socket::poll_t> selected, [[maybe_unused]] pollfd& native_pfd)
std::tuple<bool, bool, bool> lv2_socket_raw::select([[maybe_unused]] bs_t<lv2_socket::poll_t> selected, [[maybe_unused]] pollfd& native_pfd)
{
sys_net.todo("lv2_socket_raw::select");
return {};

View File

@ -28,5 +28,5 @@ public:
s32 shutdown(s32 how) override;
s32 poll(sys_net_pollfd& sn_pfd, pollfd& native_pfd) override;
s32 select(bs_t<poll_t> selected, pollfd& native_pfd) override;
std::tuple<bool, bool, bool> select(bs_t<poll_t> selected, pollfd& native_pfd) override;
};

View File

@ -22,7 +22,7 @@ struct nt_p2p_port
{
// Real socket where P2P packets are received/sent
socket_type p2p_socket = 0;
u16 port = 0;
u16 port = 0;
shared_mutex bound_p2p_vports_mutex;
// For DGRAM_P2P sockets(vport, sock_id)

View File

@ -15,7 +15,6 @@
#endif
#endif
#include "Emu/Cell/lv2/sys_net.h"
int get_native_error();