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:
@@ -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);
|
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);
|
sys_net.error("sys_net_bnet_sendto(s=%d): bad addrlen (%u)", s, addrlen);
|
||||||
return -SYS_NET_EINVAL;
|
return -SYS_NET_EINVAL;
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ enum lv2_ip_option : s32
|
|||||||
SYS_NET_IP_MULTICAST_LOOP = 11,
|
SYS_NET_IP_MULTICAST_LOOP = 11,
|
||||||
SYS_NET_IP_ADD_MEMBERSHIP = 12,
|
SYS_NET_IP_ADD_MEMBERSHIP = 12,
|
||||||
SYS_NET_IP_DROP_MEMBERSHIP = 13,
|
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_MAXTTL = 24,
|
||||||
SYS_NET_IP_DONTFRAG = 26
|
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:
|
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};
|
return {CELL_OK, out_val, out_len};
|
||||||
}
|
}
|
||||||
case SYS_NET_IP_MAXTTL:
|
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};
|
return {CELL_OK, out_val, out_len};
|
||||||
}
|
}
|
||||||
case SYS_NET_IP_DONTFRAG:
|
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:
|
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);
|
min_ttl = native_int;
|
||||||
break;
|
return {};
|
||||||
}
|
}
|
||||||
case SYS_NET_IP_MAXTTL:
|
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);
|
max_ttl = native_int;
|
||||||
break;
|
return {};
|
||||||
}
|
}
|
||||||
case SYS_NET_IP_DONTFRAG:
|
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>>();
|
auto& nph = g_fxo->get<named_thread<np::np_handler>>();
|
||||||
const auto packet = dnshook.get_dns_packet(lv2_id);
|
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());
|
memcpy(res_buf.data(), packet.data(), packet.size());
|
||||||
native_addr.ss_family = AF_INET;
|
native_addr.ss_family = AF_INET;
|
||||||
(reinterpret_cast<::sockaddr_in*>(&native_addr))->sin_port = std::bit_cast<u16, be_t<u16>>(53); // htons(53)
|
(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};
|
return {-SYS_NET_ECONNRESET};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<u8> buf_copy;
|
||||||
for (int i = 0; i < msg.msg_iovlen; i++)
|
for (int i = 0; i < msg.msg_iovlen; i++)
|
||||||
{
|
{
|
||||||
auto iov_base = msg.msg_iov[i].iov_base;
|
auto iov_base = msg.msg_iov[i].iov_base;
|
||||||
const u32 len = msg.msg_iov[i].iov_len;
|
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)
|
if (native_result >= 0)
|
||||||
{
|
{
|
||||||
return {native_result};
|
return {native_result};
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
result = get_last_error(!so_nbio && (flags & SYS_NET_MSG_DONTWAIT) == 0);
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fd_set readfds, writefds;
|
pollfd pfd{};
|
||||||
struct timeval timeout{0, 0}; // Zero timeout
|
pfd.fd = native_socket;
|
||||||
|
pfd.events = POLLIN | POLLOUT;
|
||||||
|
|
||||||
FD_ZERO(&readfds);
|
// Use poll to check for readability and writability
|
||||||
FD_ZERO(&writefds);
|
#ifdef _WIN32
|
||||||
FD_SET(native_socket, &readfds);
|
const int result = WSAPoll(&pfd, 1, 0);
|
||||||
FD_SET(native_socket, &writefds);
|
#else
|
||||||
|
const int result = ::poll(&pfd, 1, 0);
|
||||||
// Use select to check for readability and writability
|
#endif
|
||||||
const int result = ::select(1, &readfds, &writefds, NULL, &timeout);
|
|
||||||
|
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
{
|
{
|
||||||
@@ -1250,5 +1254,5 @@ bool lv2_socket_native::is_socket_connected()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Socket is connected if it's readable or writable
|
// 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_reuseaddr = 0;
|
||||||
s32 so_reuseport = 0;
|
s32 so_reuseport = 0;
|
||||||
#endif
|
#endif
|
||||||
|
// Those values come from FreeBSD
|
||||||
|
s32 min_ttl = 1;
|
||||||
|
s32 max_ttl = 64;
|
||||||
|
|
||||||
u16 bound_port = 0;
|
u16 bound_port = 0;
|
||||||
bool feign_tcp_conn_failure = false; // Savestate load related
|
bool feign_tcp_conn_failure = false; // Savestate load related
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user