mirror of
https://github.com/RPCS3/rpcs3.git
synced 2026-03-16 02:05:20 +01:00
sys_net/lv2_socket_native: Various fixes
Fix is_socket_connected(always returned false) Implement SYS_NET_IP_TTLCHK and SYS_NET_IP_MAXTTL Fix lv2_socket_native::sendmsg, it was only sending the first iovec Fix sys_net_bnet_sendto addrlen check Fix assert in lv2_socket_native::recvfrom()
This commit is contained in:
parent
53dcf2ba00
commit
b7b0e06a54
|
|
@ -992,7 +992,7 @@ error_code sys_net_bnet_sendto(ppu_thread& ppu, s32 s, vm::cptr<void> buf, u32 l
|
|||
fmt::throw_exception("sys_net_bnet_sendto(s=%d): unknown flags (0x%x)", flags);
|
||||
}
|
||||
|
||||
if (addr && addrlen < 8)
|
||||
if (addr && addrlen < sizeof(sys_net_sockaddr))
|
||||
{
|
||||
sys_net.error("sys_net_bnet_sendto(s=%d): bad addrlen (%u)", s, addrlen);
|
||||
return -SYS_NET_EINVAL;
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ enum lv2_ip_option : s32
|
|||
SYS_NET_IP_MULTICAST_LOOP = 11,
|
||||
SYS_NET_IP_ADD_MEMBERSHIP = 12,
|
||||
SYS_NET_IP_DROP_MEMBERSHIP = 13,
|
||||
SYS_NET_IP_TTLCHK = 23,
|
||||
SYS_NET_IP_TTLCHK = 23, // This is probably the equivalent of IP_MINTTL on FreeBSD
|
||||
SYS_NET_IP_MAXTTL = 24,
|
||||
SYS_NET_IP_DONTFRAG = 26
|
||||
};
|
||||
|
|
|
|||
|
|
@ -551,12 +551,14 @@ std::tuple<s32, lv2_socket::sockopt_data, u32> lv2_socket_native::getsockopt(s32
|
|||
}
|
||||
case SYS_NET_IP_TTLCHK:
|
||||
{
|
||||
sys_net.error("sys_net_bnet_getsockopt(IPPROTO_IP, SYS_NET_IP_TTLCHK): stubbed option");
|
||||
out_val._int = min_ttl;
|
||||
out_len = sizeof(s32);
|
||||
return {CELL_OK, out_val, out_len};
|
||||
}
|
||||
case SYS_NET_IP_MAXTTL:
|
||||
{
|
||||
sys_net.error("sys_net_bnet_getsockopt(IPPROTO_IP, SYS_NET_IP_MAXTTL): stubbed option");
|
||||
out_val._int = max_ttl;
|
||||
out_len = sizeof(s32);
|
||||
return {CELL_OK, out_val, out_len};
|
||||
}
|
||||
case SYS_NET_IP_DONTFRAG:
|
||||
|
|
@ -834,13 +836,13 @@ s32 lv2_socket_native::setsockopt(s32 level, s32 optname, const std::vector<u8>&
|
|||
}
|
||||
case SYS_NET_IP_TTLCHK:
|
||||
{
|
||||
sys_net.error("sys_net_bnet_setsockopt(s=%d, IPPROTO_IP): Stubbed option (0x%x) (SYS_NET_IP_TTLCHK)", lv2_id, optname);
|
||||
break;
|
||||
min_ttl = native_int;
|
||||
return {};
|
||||
}
|
||||
case SYS_NET_IP_MAXTTL:
|
||||
{
|
||||
sys_net.error("sys_net_bnet_setsockopt(s=%d, IPPROTO_IP): Stubbed option (0x%x) (SYS_NET_IP_MAXTTL)", lv2_id, optname);
|
||||
break;
|
||||
max_ttl = native_int;
|
||||
return {};
|
||||
}
|
||||
case SYS_NET_IP_DONTFRAG:
|
||||
{
|
||||
|
|
@ -910,7 +912,7 @@ std::optional<std::tuple<s32, std::vector<u8>, sys_net_sockaddr>> lv2_socket_nat
|
|||
{
|
||||
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
|
||||
const auto packet = dnshook.get_dns_packet(lv2_id);
|
||||
ensure(packet.size() < len);
|
||||
ensure(packet.size() <= len);
|
||||
memcpy(res_buf.data(), packet.data(), packet.size());
|
||||
native_addr.ss_family = AF_INET;
|
||||
(reinterpret_cast<::sockaddr_in*>(&native_addr))->sin_port = std::bit_cast<u16, be_t<u16>>(53); // htons(53)
|
||||
|
|
@ -1069,18 +1071,20 @@ std::optional<s32> lv2_socket_native::sendmsg(s32 flags, const sys_net_msghdr& m
|
|||
return {-SYS_NET_ECONNRESET};
|
||||
}
|
||||
|
||||
std::vector<u8> buf_copy;
|
||||
for (int i = 0; i < msg.msg_iovlen; i++)
|
||||
{
|
||||
auto iov_base = msg.msg_iov[i].iov_base;
|
||||
const u32 len = msg.msg_iov[i].iov_len;
|
||||
const std::vector<u8> buf_copy(vm::_ptr<const char>(iov_base.addr()), vm::_ptr<const char>(iov_base.addr()) + len);
|
||||
const auto* src = vm::_ptr<const char>(iov_base.addr());
|
||||
buf_copy.insert(buf_copy.end(), src, src + len);
|
||||
}
|
||||
|
||||
native_result = ::send(native_socket, reinterpret_cast<const char*>(buf_copy.data()), ::narrow<int>(buf_copy.size()), native_flags);
|
||||
native_result = ::send(native_socket, reinterpret_cast<const char*>(buf_copy.data()), ::narrow<int>(buf_copy.size()), native_flags);
|
||||
|
||||
if (native_result >= 0)
|
||||
{
|
||||
return {native_result};
|
||||
}
|
||||
if (native_result >= 0)
|
||||
{
|
||||
return {native_result};
|
||||
}
|
||||
|
||||
result = get_last_error(!so_nbio && (flags & SYS_NET_MSG_DONTWAIT) == 0);
|
||||
|
|
@ -1232,16 +1236,16 @@ bool lv2_socket_native::is_socket_connected()
|
|||
return false;
|
||||
}
|
||||
|
||||
fd_set readfds, writefds;
|
||||
struct timeval timeout{0, 0}; // Zero timeout
|
||||
pollfd pfd{};
|
||||
pfd.fd = native_socket;
|
||||
pfd.events = POLLIN | POLLOUT;
|
||||
|
||||
FD_ZERO(&readfds);
|
||||
FD_ZERO(&writefds);
|
||||
FD_SET(native_socket, &readfds);
|
||||
FD_SET(native_socket, &writefds);
|
||||
|
||||
// Use select to check for readability and writability
|
||||
const int result = ::select(1, &readfds, &writefds, NULL, &timeout);
|
||||
// Use poll to check for readability and writability
|
||||
#ifdef _WIN32
|
||||
const int result = WSAPoll(&pfd, 1, 0);
|
||||
#else
|
||||
const int result = ::poll(&pfd, 1, 0);
|
||||
#endif
|
||||
|
||||
if (result < 0)
|
||||
{
|
||||
|
|
@ -1250,5 +1254,5 @@ bool lv2_socket_native::is_socket_connected()
|
|||
}
|
||||
|
||||
// Socket is connected if it's readable or writable
|
||||
return FD_ISSET(native_socket, &readfds) || FD_ISSET(native_socket, &writefds);
|
||||
return (pfd.revents & (POLLIN | POLLOUT)) != 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,6 +70,10 @@ private:
|
|||
s32 so_reuseaddr = 0;
|
||||
s32 so_reuseport = 0;
|
||||
#endif
|
||||
// Those values come from FreeBSD
|
||||
s32 min_ttl = 1;
|
||||
s32 max_ttl = 64;
|
||||
|
||||
u16 bound_port = 0;
|
||||
bool feign_tcp_conn_failure = false; // Savestate load related
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue