From 4d265357589a7c9c80d5c6d1cc871bb6939b669d Mon Sep 17 00:00:00 2001 From: RipleyTom Date: Sun, 10 Apr 2022 18:13:45 +0200 Subject: [PATCH] sys_net: bind & getsockname accuracy --- rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2p.cpp | 23 +++++++-- .../Emu/Cell/lv2/sys_net/lv2_socket_p2ps.cpp | 48 +++++++++++++++++-- rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2ps.h | 2 +- 3 files changed, 66 insertions(+), 7 deletions(-) diff --git a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2p.cpp b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2p.cpp index 7d9e2c415a..b82c208a91 100644 --- a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2p.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2p.cpp @@ -77,9 +77,12 @@ s32 lv2_socket_p2p::bind(const sys_net_sockaddr& addr, s32 ps3_id) sys_net.notice("[P2P] Trying to bind %s:%d:%d", np::ip_to_string(std::bit_cast(psa_in_p2p->sin_addr)), p2p_port, p2p_vport); - ensure(p2p_vport != 0); if (p2p_port != 3658) { + if (p2p_port == 0) + { + return -SYS_NET_EINVAL; + } sys_net.warning("[P2P] Attempting to bind a socket to a port != 3658"); } @@ -97,10 +100,24 @@ s32 lv2_socket_p2p::bind(const sys_net_sockaddr& addr, s32 ps3_id) real_socket = pport.p2p_socket; { std::lock_guard lock(pport.bound_p2p_vports_mutex); - if (pport.bound_p2p_vports.count(p2p_vport) != 0) + + if (p2p_vport == 0) { - return -SYS_NET_EADDRINUSE; + // Find a free vport starting at 30000 + p2p_vport = 30000; + while (pport.bound_p2p_vports.contains(p2p_vport)) + { + p2p_vport++; + } } + else + { + if (pport.bound_p2p_vports.contains(p2p_vport)) + { + return -SYS_NET_EADDRINUSE; + } + } + pport.bound_p2p_vports.insert(std::make_pair(p2p_vport, ps3_id)); } } diff --git a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2ps.cpp b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2ps.cpp index f588ec58b1..c9c5744067 100644 --- a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2ps.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2ps.cpp @@ -519,7 +519,11 @@ s32 lv2_socket_p2ps::bind(const sys_net_sockaddr& addr, s32 ps3_id) sys_net.notice("[P2PS] Trying to bind %s:%d:%d", np::ip_to_string(std::bit_cast(psa_in_p2p->sin_addr)), p2p_port, p2p_vport); - ensure(p2p_vport != 0); + if (p2p_port == 0) + { + p2p_port = 3658; + } + if (p2p_port != 3658) { sys_net.warning("[P2PS] Attempting to bind a socket to a port != 3658"); @@ -542,8 +546,24 @@ s32 lv2_socket_p2ps::bind(const sys_net_sockaddr& addr, s32 ps3_id) std::lock_guard vport_lock(pport.bound_p2p_vports_mutex); std::lock_guard sock_lock(mutex); - const u64 key = (static_cast(p2p_vport) << 32); - pport.bound_p2p_streams.emplace(key, ps3_id); + if (p2p_vport == 0) + { + p2p_vport = 30000; + while (pport.bound_p2p_streams.contains((static_cast(p2p_vport) << 32))) + { + p2p_vport++; + } + pport.bound_p2p_streams.emplace((static_cast(p2p_vport) << 32), ps3_id); + } + else + { + const u64 key = (static_cast(p2p_vport) << 32); + if (pport.bound_p2p_streams.contains(key)) + { + return -SYS_NET_EADDRINUSE; + } + pport.bound_p2p_streams.emplace(key, ps3_id); + } port = p2p_port; vport = p2p_vport; @@ -554,6 +574,28 @@ s32 lv2_socket_p2ps::bind(const sys_net_sockaddr& addr, s32 ps3_id) return CELL_OK; } +std::pair lv2_socket_p2ps::getsockname() +{ + std::lock_guard lock(mutex); + + // Unbound socket + if (!socket) + { + return {CELL_OK, {}}; + } + + sys_net_sockaddr sn_addr{}; + sys_net_sockaddr_in_p2p* paddr = reinterpret_cast(&sn_addr); + + paddr->sin_len = sizeof(sys_net_sockaddr_in); + paddr->sin_family = SYS_NET_AF_INET; + paddr->sin_port = vport; + paddr->sin_vport = port; + paddr->sin_addr = bound_addr; + + return {CELL_OK, sn_addr}; +} + std::optional lv2_socket_p2ps::connect(const sys_net_sockaddr& addr) { std::lock_guard lock(mutex); diff --git a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2ps.h b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2ps.h index 5b10d561d6..a56f312c12 100644 --- a/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2ps.h +++ b/rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2ps.h @@ -71,7 +71,7 @@ public: std::optional connect(const sys_net_sockaddr& addr) override; - // std::pair getsockname() override; + std::pair getsockname() override; s32 listen(s32 backlog) override;