mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-09-07 12:48:03 +00:00
we love when cURL has bugs?
This commit is contained in:
@@ -748,7 +748,7 @@ std::pair<s32, Network::Errno> BSD::FcntlImpl(s32 fd, Network::FcntlCmd cmd, s32
|
|||||||
ASSERT(arg == 0);
|
ASSERT(arg == 0);
|
||||||
return {descriptor.flags, Network::Errno::SUCCESS};
|
return {descriptor.flags, Network::Errno::SUCCESS};
|
||||||
case Network::FcntlCmd::SETFL: {
|
case Network::FcntlCmd::SETFL: {
|
||||||
const bool enable = (arg & Network::FLAG_O_NONBLOCK) != 0;
|
const bool enable = (arg & u32(Network::FcntlFlags::NONBLOCK_ANY)) != 0;
|
||||||
const Network::Errno bsd_errno = descriptor.socket->SetNonBlock(enable);
|
const Network::Errno bsd_errno = descriptor.socket->SetNonBlock(enable);
|
||||||
if (bsd_errno != Network::Errno::SUCCESS) {
|
if (bsd_errno != Network::Errno::SUCCESS) {
|
||||||
return {-1, bsd_errno};
|
return {-1, bsd_errno};
|
||||||
@@ -831,18 +831,16 @@ std::pair<s32, Network::Errno> BSD::RecvImpl(s32 fd, u32 flags, std::vector<u8>&
|
|||||||
FileDescriptor& descriptor = *file_descriptors[fd];
|
FileDescriptor& descriptor = *file_descriptors[fd];
|
||||||
|
|
||||||
// Apply flags
|
// Apply flags
|
||||||
using Network::FLAG_MSG_DONTWAIT;
|
if ((flags & u32(Network::MsgOpt::DONTWAIT)) != 0) {
|
||||||
using Network::FLAG_O_NONBLOCK;
|
flags &= ~u32(Network::MsgOpt::DONTWAIT);
|
||||||
if ((flags & FLAG_MSG_DONTWAIT) != 0) {
|
if ((descriptor.flags & u32(Network::FcntlFlags::NONBLOCK_ANY)) == 0) {
|
||||||
flags &= ~FLAG_MSG_DONTWAIT;
|
|
||||||
if ((descriptor.flags & FLAG_O_NONBLOCK) == 0) {
|
|
||||||
descriptor.socket->SetNonBlock(true);
|
descriptor.socket->SetNonBlock(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto [ret, bsd_errno] = descriptor.socket->Recv(flags, message);
|
const auto [ret, bsd_errno] = descriptor.socket->Recv(flags, message);
|
||||||
// Restore original state
|
// Restore original state
|
||||||
if ((descriptor.flags & FLAG_O_NONBLOCK) == 0)
|
if ((descriptor.flags & u32(Network::FcntlFlags::NONBLOCK_ANY)) == 0)
|
||||||
descriptor.socket->SetNonBlock(false);
|
descriptor.socket->SetNonBlock(false);
|
||||||
return {ret, bsd_errno};
|
return {ret, bsd_errno};
|
||||||
}
|
}
|
||||||
@@ -865,11 +863,9 @@ std::pair<s32, Network::Errno> BSD::RecvFromImpl(s32 fd, u32 flags, std::vector<
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Apply flags
|
// Apply flags
|
||||||
using Network::FLAG_MSG_DONTWAIT;
|
if ((flags & u32(Network::MsgOpt::DONTWAIT)) != 0) {
|
||||||
using Network::FLAG_O_NONBLOCK;
|
flags &= ~u32(Network::MsgOpt::DONTWAIT);
|
||||||
if ((flags & FLAG_MSG_DONTWAIT) != 0) {
|
if ((descriptor.flags & u32(Network::FcntlFlags::NONBLOCK_ANY)) == 0) {
|
||||||
flags &= ~FLAG_MSG_DONTWAIT;
|
|
||||||
if ((descriptor.flags & FLAG_O_NONBLOCK) == 0) {
|
|
||||||
descriptor.socket->SetNonBlock(true);
|
descriptor.socket->SetNonBlock(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -877,7 +873,7 @@ std::pair<s32, Network::Errno> BSD::RecvFromImpl(s32 fd, u32 flags, std::vector<
|
|||||||
const auto [ret, bsd_errno] = descriptor.socket->RecvFrom(flags, message, p_addr_in);
|
const auto [ret, bsd_errno] = descriptor.socket->RecvFrom(flags, message, p_addr_in);
|
||||||
|
|
||||||
// Restore original state
|
// Restore original state
|
||||||
if ((descriptor.flags & FLAG_O_NONBLOCK) == 0) {
|
if ((descriptor.flags & u32(Network::FcntlFlags::NONBLOCK_ANY)) == 0) {
|
||||||
descriptor.socket->SetNonBlock(false);
|
descriptor.socket->SetNonBlock(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -846,22 +846,43 @@ std::variant<std::vector<AddrInfo>, GetAddrInfoError> GetAddressInfo(const std::
|
|||||||
return TranslateGetAddrInfoErrorFromNative(gai_err);
|
return TranslateGetAddrInfoErrorFromNative(gai_err);
|
||||||
}
|
}
|
||||||
std::vector<AddrInfo> ret{};
|
std::vector<AddrInfo> ret{};
|
||||||
for (auto* current = addrinfo; current; current = current->ai_next) {
|
|
||||||
LOG_DEBUG(Network, "- entry prot={},socktype={},family={},len={}", current->ai_protocol, current->ai_socktype, current->ai_family, current->ai_addrlen);
|
auto const add_entries = [&](auto const&& filter_fn) {
|
||||||
// We should only get AF_INET results due to the hints value.
|
for (auto* current = addrinfo; current; current = current->ai_next) {
|
||||||
if (current->ai_family == AF_INET && current->ai_addrlen == sizeof(sockaddr_in)) {
|
if (filter_fn(current)) {
|
||||||
auto& out = ret.emplace_back();
|
LOG_DEBUG(Network, "- entry prot={},socktype={},family={},len={}", current->ai_protocol, current->ai_socktype, current->ai_family, current->ai_addrlen);
|
||||||
out.family = TranslateDomainFromNative(current->ai_family);
|
// We should only get AF_INET results due to the hints value.
|
||||||
out.socket_type = TranslateTypeFromNative(current->ai_socktype);
|
if (current->ai_family == AF_INET && current->ai_addrlen == sizeof(sockaddr_in)) {
|
||||||
out.protocol = TranslateProtocolFromNative(current->ai_protocol);
|
auto& out = ret.emplace_back();
|
||||||
out.addr = TranslateToSockAddrIn(*reinterpret_cast<sockaddr_in*>(current->ai_addr), current->ai_addrlen);
|
out.family = TranslateDomainFromNative(current->ai_family);
|
||||||
if (current->ai_canonname != nullptr) {
|
out.socket_type = TranslateTypeFromNative(current->ai_socktype);
|
||||||
out.canon_name = current->ai_canonname;
|
out.protocol = TranslateProtocolFromNative(current->ai_protocol);
|
||||||
|
out.addr = TranslateToSockAddrIn(*reinterpret_cast<sockaddr_in*>(current->ai_addr), current->ai_addrlen);
|
||||||
|
if (current->ai_canonname != nullptr) {
|
||||||
|
out.canon_name = current->ai_canonname;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LOG_ERROR(Network, "invalid entry family={},len={}", current->ai_family, current->ai_addrlen);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
LOG_ERROR(Network, "invalid entry family={},len={}", current->ai_family, current->ai_addrlen);
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
|
// Let me explain slowly, so HB app store depends ENTIRELY on the switch returning
|
||||||
|
// getaddrinfo stuff in a particular order, right?
|
||||||
|
// cURL is used by hb app store, which uses a tiny library called "get"; the
|
||||||
|
// specific version that 99% of users run has a bug with DNS cache queries...
|
||||||
|
// unfortunely we can only do what we do best: emulate the issue away.
|
||||||
|
//
|
||||||
|
// Please see this fuckery here -> https://github.com/curl/curl/issues/9274
|
||||||
|
// Place fucking UDP last
|
||||||
|
add_entries([](auto* current) {
|
||||||
|
return current->ai_protocol != IPPROTO_UDP;
|
||||||
|
});
|
||||||
|
// Off to the shitter you go!
|
||||||
|
add_entries([](auto* current) {
|
||||||
|
return current->ai_protocol == IPPROTO_UDP;
|
||||||
|
});
|
||||||
freeaddrinfo(addrinfo);
|
freeaddrinfo(addrinfo);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -156,8 +156,7 @@ std::pair<s32, Errno> ProxySocket::RecvFrom(int flags, std::span<u8> message, Ne
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<s32, Errno> ProxySocket::ReceivePacket(int flags, std::span<u8> message, Network::SockAddrIn* addr,
|
std::pair<s32, Errno> ProxySocket::ReceivePacket(int flags, std::span<u8> message, Network::SockAddrIn* addr, std::size_t max_length) {
|
||||||
std::size_t max_length) {
|
|
||||||
ProxyPacket& packet = received_packets.front();
|
ProxyPacket& packet = received_packets.front();
|
||||||
if (addr) {
|
if (addr) {
|
||||||
addr->len = 16;
|
addr->len = 16;
|
||||||
@@ -167,7 +166,7 @@ std::pair<s32, Errno> ProxySocket::ReceivePacket(int flags, std::span<u8> messag
|
|||||||
addr->zeroes = {};
|
addr->zeroes = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool peek = (flags & FLAG_MSG_PEEK) != 0;
|
bool peek = (flags & u32(Network::MsgOpt::PEEK)) != 0;
|
||||||
std::size_t read_bytes;
|
std::size_t read_bytes;
|
||||||
if (packet.data.size() > max_length) {
|
if (packet.data.size() > max_length) {
|
||||||
read_bytes = max_length;
|
read_bytes = max_length;
|
||||||
@@ -180,8 +179,7 @@ std::pair<s32, Errno> ProxySocket::ReceivePacket(int flags, std::span<u8> messag
|
|||||||
return {-1, Errno::MSGSIZE};
|
return {-1, Errno::MSGSIZE};
|
||||||
} else if (protocol == Protocol::TCP) {
|
} else if (protocol == Protocol::TCP) {
|
||||||
std::vector<u8> numArray(packet.data.size() - max_length);
|
std::vector<u8> numArray(packet.data.size() - max_length);
|
||||||
std::copy(packet.data.begin() + max_length, packet.data.end(),
|
std::copy(packet.data.begin() + max_length, packet.data.end(), std::back_inserter(numArray));
|
||||||
std::back_inserter(numArray));
|
|
||||||
packet.data = numArray;
|
packet.data = numArray;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -291,6 +291,13 @@ enum class FcntlCmd : s32 {
|
|||||||
SETFL = 4,
|
SETFL = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class FcntlFlags : u32 {
|
||||||
|
NONBLOCK = 0x004,
|
||||||
|
NONBLOCK_NX = 0x800,
|
||||||
|
// Provided for convenience
|
||||||
|
NONBLOCK_ANY = u32(NONBLOCK) | u32(NONBLOCK_NX),
|
||||||
|
};
|
||||||
|
|
||||||
/// Array of IPv4 address
|
/// Array of IPv4 address
|
||||||
using IPv4Address = std::array<u8, 4>;
|
using IPv4Address = std::array<u8, 4>;
|
||||||
|
|
||||||
@@ -331,10 +338,6 @@ struct Linger {
|
|||||||
};
|
};
|
||||||
static_assert(sizeof(Linger) == 8);
|
static_assert(sizeof(Linger) == 8);
|
||||||
|
|
||||||
constexpr u32 FLAG_MSG_PEEK = 0x2;
|
|
||||||
constexpr u32 FLAG_MSG_DONTWAIT = 0x80;
|
|
||||||
constexpr u32 FLAG_O_NONBLOCK = 0x800;
|
|
||||||
|
|
||||||
/// @brief Cross-platform addrinfo structure (not guest)
|
/// @brief Cross-platform addrinfo structure (not guest)
|
||||||
struct AddrInfo {
|
struct AddrInfo {
|
||||||
Domain family;
|
Domain family;
|
||||||
|
|||||||
Reference in New Issue
Block a user