sys_net: bind & getsockname accuracy

This commit is contained in:
RipleyTom 2022-04-10 18:13:45 +02:00 committed by Megamouse
parent 5407e42b76
commit 4d26535758
3 changed files with 66 additions and 7 deletions

View File

@ -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<u32>(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));
}
}

View File

@ -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<u32>(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<u64>(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<u64>(p2p_vport) << 32)))
{
p2p_vport++;
}
pport.bound_p2p_streams.emplace((static_cast<u64>(p2p_vport) << 32), ps3_id);
}
else
{
const u64 key = (static_cast<u64>(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<s32, sys_net_sockaddr> 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<sys_net_sockaddr_in_p2p*>(&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<s32> lv2_socket_p2ps::connect(const sys_net_sockaddr& addr)
{
std::lock_guard lock(mutex);

View File

@ -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;