mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-08-17 21:57:52 +00:00
we love when cURL has bugs?
This commit is contained in:
@@ -717,7 +717,7 @@ std::pair<s32, Network::Errno> BSD::FcntlImpl(s32 fd, Network::FcntlCmd cmd, s32
|
||||
ASSERT(arg == 0);
|
||||
return {descriptor.flags, Network::Errno::SUCCESS};
|
||||
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);
|
||||
if (bsd_errno != Network::Errno::SUCCESS) {
|
||||
return {-1, bsd_errno};
|
||||
@@ -800,18 +800,16 @@ std::pair<s32, Network::Errno> BSD::RecvImpl(s32 fd, u32 flags, std::vector<u8>&
|
||||
FileDescriptor& descriptor = *file_descriptors[fd];
|
||||
|
||||
// Apply flags
|
||||
using Network::FLAG_MSG_DONTWAIT;
|
||||
using Network::FLAG_O_NONBLOCK;
|
||||
if ((flags & FLAG_MSG_DONTWAIT) != 0) {
|
||||
flags &= ~FLAG_MSG_DONTWAIT;
|
||||
if ((descriptor.flags & FLAG_O_NONBLOCK) == 0) {
|
||||
if ((flags & u32(Network::MsgOpt::DONTWAIT)) != 0) {
|
||||
flags &= ~u32(Network::MsgOpt::DONTWAIT);
|
||||
if ((descriptor.flags & u32(Network::FcntlFlags::NONBLOCK_ANY)) == 0) {
|
||||
descriptor.socket->SetNonBlock(true);
|
||||
}
|
||||
}
|
||||
|
||||
const auto [ret, bsd_errno] = descriptor.socket->Recv(flags, message);
|
||||
// Restore original state
|
||||
if ((descriptor.flags & FLAG_O_NONBLOCK) == 0)
|
||||
if ((descriptor.flags & u32(Network::FcntlFlags::NONBLOCK_ANY)) == 0)
|
||||
descriptor.socket->SetNonBlock(false);
|
||||
return {ret, bsd_errno};
|
||||
}
|
||||
@@ -834,11 +832,9 @@ std::pair<s32, Network::Errno> BSD::RecvFromImpl(s32 fd, u32 flags, std::vector<
|
||||
}
|
||||
|
||||
// Apply flags
|
||||
using Network::FLAG_MSG_DONTWAIT;
|
||||
using Network::FLAG_O_NONBLOCK;
|
||||
if ((flags & FLAG_MSG_DONTWAIT) != 0) {
|
||||
flags &= ~FLAG_MSG_DONTWAIT;
|
||||
if ((descriptor.flags & FLAG_O_NONBLOCK) == 0) {
|
||||
if ((flags & u32(Network::MsgOpt::DONTWAIT)) != 0) {
|
||||
flags &= ~u32(Network::MsgOpt::DONTWAIT);
|
||||
if ((descriptor.flags & u32(Network::FcntlFlags::NONBLOCK_ANY)) == 0) {
|
||||
descriptor.socket->SetNonBlock(true);
|
||||
}
|
||||
}
|
||||
@@ -846,7 +842,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);
|
||||
|
||||
// Restore original state
|
||||
if ((descriptor.flags & FLAG_O_NONBLOCK) == 0) {
|
||||
if ((descriptor.flags & u32(Network::FcntlFlags::NONBLOCK_ANY)) == 0) {
|
||||
descriptor.socket->SetNonBlock(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -846,22 +846,43 @@ std::variant<std::vector<AddrInfo>, GetAddrInfoError> GetAddressInfo(const std::
|
||||
return TranslateGetAddrInfoErrorFromNative(gai_err);
|
||||
}
|
||||
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);
|
||||
// We should only get AF_INET results due to the hints value.
|
||||
if (current->ai_family == AF_INET && current->ai_addrlen == sizeof(sockaddr_in)) {
|
||||
auto& out = ret.emplace_back();
|
||||
out.family = TranslateDomainFromNative(current->ai_family);
|
||||
out.socket_type = TranslateTypeFromNative(current->ai_socktype);
|
||||
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;
|
||||
|
||||
auto const add_entries = [&](auto const&& filter_fn) {
|
||||
for (auto* current = addrinfo; current; current = current->ai_next) {
|
||||
if (filter_fn(current)) {
|
||||
LOG_DEBUG(Network, "- entry prot={},socktype={},family={},len={}", current->ai_protocol, current->ai_socktype, current->ai_family, current->ai_addrlen);
|
||||
// We should only get AF_INET results due to the hints value.
|
||||
if (current->ai_family == AF_INET && current->ai_addrlen == sizeof(sockaddr_in)) {
|
||||
auto& out = ret.emplace_back();
|
||||
out.family = TranslateDomainFromNative(current->ai_family);
|
||||
out.socket_type = TranslateTypeFromNative(current->ai_socktype);
|
||||
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);
|
||||
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::size_t max_length) {
|
||||
std::pair<s32, Errno> ProxySocket::ReceivePacket(int flags, std::span<u8> message, Network::SockAddrIn* addr, std::size_t max_length) {
|
||||
ProxyPacket& packet = received_packets.front();
|
||||
if (addr) {
|
||||
addr->len = 16;
|
||||
@@ -167,7 +166,7 @@ std::pair<s32, Errno> ProxySocket::ReceivePacket(int flags, std::span<u8> messag
|
||||
addr->zeroes = {};
|
||||
}
|
||||
|
||||
bool peek = (flags & FLAG_MSG_PEEK) != 0;
|
||||
bool peek = (flags & u32(Network::MsgOpt::PEEK)) != 0;
|
||||
std::size_t read_bytes;
|
||||
if (packet.data.size() > 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};
|
||||
} else if (protocol == Protocol::TCP) {
|
||||
std::vector<u8> numArray(packet.data.size() - max_length);
|
||||
std::copy(packet.data.begin() + max_length, packet.data.end(),
|
||||
std::back_inserter(numArray));
|
||||
std::copy(packet.data.begin() + max_length, packet.data.end(), std::back_inserter(numArray));
|
||||
packet.data = numArray;
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -291,6 +291,13 @@ enum class FcntlCmd : s32 {
|
||||
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
|
||||
using IPv4Address = std::array<u8, 4>;
|
||||
|
||||
@@ -331,10 +338,6 @@ struct Linger {
|
||||
};
|
||||
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)
|
||||
struct AddrInfo {
|
||||
Domain family;
|
||||
|
||||
Reference in New Issue
Block a user