mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-09-07 12:48:03 +00:00
don't murder me for this change
This commit is contained in:
@@ -550,13 +550,14 @@ std::pair<s32, Network::Errno> BSD::SocketImpl(Network::Domain domain, Network::
|
|||||||
// ENONMEM might be thrown here
|
// ENONMEM might be thrown here
|
||||||
LOG_INFO(Service, "New socket fd={},domain={},type={},prot={}", fd, domain, type, protocol);
|
LOG_INFO(Service, "New socket fd={},domain={},type={},prot={}", fd, domain, type, protocol);
|
||||||
|
|
||||||
|
// While room is important -- we need to remember ICMP takes priority over **everything else**
|
||||||
|
// TODO: rework this so proxy sockets can be done transparently? -- like what if i need
|
||||||
|
// to browse the internet while playing LDN or something stupid like that?
|
||||||
auto room_member = Network::GetRoomMember().lock();
|
auto room_member = Network::GetRoomMember().lock();
|
||||||
if (room_member && room_member->IsConnected()) {
|
if (protocol == Network::Protocol::ICMP || protocol == Network::Protocol::ICMPV6) {
|
||||||
descriptor.socket = std::make_shared<Network::ProxySocket>();
|
|
||||||
} else if ((type == Network::Type::RAW || type == Network::Type::DGRAM)
|
|
||||||
&& (domain == Network::Domain::INET && protocol == Network::Protocol::ICMP)
|
|
||||||
&& (domain == Network::Domain::INET6 && protocol == Network::Protocol::ICMPV6)) {
|
|
||||||
descriptor.socket = std::make_shared<Network::IcmpSocket>();
|
descriptor.socket = std::make_shared<Network::IcmpSocket>();
|
||||||
|
} else if (room_member && room_member->IsConnected()) {
|
||||||
|
descriptor.socket = std::make_shared<Network::ProxySocket>();
|
||||||
} else {
|
} else {
|
||||||
descriptor.socket = std::make_shared<Network::Socket>();
|
descriptor.socket = std::make_shared<Network::Socket>();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -250,7 +250,7 @@ Errno TranslateNativeError(int e, CallType call_type = CallType::Other) {
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Errno GetAndLogLastError(CallType call_type = CallType::Other) {
|
Errno GetAndLogLastError(CallType call_type) {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
int e = WSAGetLastError();
|
int e = WSAGetLastError();
|
||||||
#else
|
#else
|
||||||
@@ -262,6 +262,12 @@ Errno GetAndLogLastError(CallType call_type = CallType::Other) {
|
|||||||
LOG_DEBUG(Network, "Socket operation error: {}", Common::NativeErrorToString(e));
|
LOG_DEBUG(Network, "Socket operation error: {}", Common::NativeErrorToString(e));
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
if (call_type == CallType::Send) {
|
||||||
|
// ISCONN + PIPE occur when send()/recv() is spammed on a socket which
|
||||||
|
// hasnt been properly initialized.
|
||||||
|
LOG_DEBUG(Network, "Socket operation error: {}", Common::NativeErrorToString(e));
|
||||||
|
return err;
|
||||||
|
}
|
||||||
LOG_ERROR(Network, "Socket operation error: {}", Common::NativeErrorToString(e));
|
LOG_ERROR(Network, "Socket operation error: {}", Common::NativeErrorToString(e));
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -907,7 +913,7 @@ std::pair<s32, Errno> Poll(std::span<HostPollFD> pollfds, s32 timeout) {
|
|||||||
|
|
||||||
if (res <= 0) {
|
if (res <= 0) {
|
||||||
ASSERT(res == SOCKET_ERROR);
|
ASSERT(res == SOCKET_ERROR);
|
||||||
return {-1, GetAndLogLastError()};
|
return {-1, GetAndLogLastError(CallType::Other)};
|
||||||
}
|
}
|
||||||
return {res, Errno::SUCCESS};
|
return {res, Errno::SUCCESS};
|
||||||
}
|
}
|
||||||
@@ -1027,7 +1033,7 @@ Errno Socket::GetSockOpt(Network::SocketLevel level, Network::OptName optname, s
|
|||||||
ASSERT(len == socklen_t(value.size()));
|
ASSERT(len == socklen_t(value.size()));
|
||||||
return Errno::SUCCESS;
|
return Errno::SUCCESS;
|
||||||
}
|
}
|
||||||
return GetAndLogLastError();
|
return GetAndLogLastError(CallType::Other);
|
||||||
}
|
}
|
||||||
|
|
||||||
Errno Socket::SetNonBlock(bool enable) {
|
Errno Socket::SetNonBlock(bool enable) {
|
||||||
@@ -1035,7 +1041,7 @@ Errno Socket::SetNonBlock(bool enable) {
|
|||||||
is_non_blocking = enable;
|
is_non_blocking = enable;
|
||||||
return Errno::SUCCESS;
|
return Errno::SUCCESS;
|
||||||
}
|
}
|
||||||
return GetAndLogLastError();
|
return GetAndLogLastError(CallType::Other);
|
||||||
}
|
}
|
||||||
|
|
||||||
Errno Socket::SetSockOpt(Network::SocketLevel level, Network::OptName optname, std::span<const u8> optval) {
|
Errno Socket::SetSockOpt(Network::SocketLevel level, Network::OptName optname, std::span<const u8> optval) {
|
||||||
@@ -1050,20 +1056,20 @@ Errno Socket::SetSockOpt(Network::SocketLevel level, Network::OptName optname, s
|
|||||||
auto const linger_optval = MakeLinger(bool(linger.onoff), linger.linger);
|
auto const linger_optval = MakeLinger(bool(linger.onoff), linger.linger);
|
||||||
if (setsockopt(fd, native_level, native_optname, reinterpret_cast<const char*>(&linger_optval), sizeof(linger_optval)) != SOCKET_ERROR)
|
if (setsockopt(fd, native_level, native_optname, reinterpret_cast<const char*>(&linger_optval), sizeof(linger_optval)) != SOCKET_ERROR)
|
||||||
return Errno::SUCCESS;
|
return Errno::SUCCESS;
|
||||||
return GetAndLogLastError();
|
return GetAndLogLastError(CallType::Other);
|
||||||
}
|
}
|
||||||
return Errno::INVAL;
|
return Errno::INVAL;
|
||||||
}
|
}
|
||||||
if (setsockopt(fd, native_level, native_optname, reinterpret_cast<const char*>(optval.data()), socklen_t(optval.size())) != SOCKET_ERROR)
|
if (setsockopt(fd, native_level, native_optname, reinterpret_cast<const char*>(optval.data()), socklen_t(optval.size())) != SOCKET_ERROR)
|
||||||
return Errno::SUCCESS;
|
return Errno::SUCCESS;
|
||||||
return GetAndLogLastError();
|
return GetAndLogLastError(CallType::Other);
|
||||||
}
|
}
|
||||||
|
|
||||||
Errno Socket::Initialize(Domain domain, Type type, Protocol protocol) {
|
Errno Socket::Initialize(Domain domain, Type type, Protocol protocol) {
|
||||||
fd = socket(TranslateDomainToNative(domain), TranslateTypeToNative(type), TranslateProtocolToNative(protocol));
|
fd = socket(TranslateDomainToNative(domain), TranslateTypeToNative(type), TranslateProtocolToNative(protocol));
|
||||||
if (fd != INVALID_SOCKET)
|
if (fd != INVALID_SOCKET)
|
||||||
return Errno::SUCCESS;
|
return Errno::SUCCESS;
|
||||||
return GetAndLogLastError();
|
return GetAndLogLastError(CallType::Other);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<Socket::AcceptResult, Errno> Socket::Accept() {
|
std::pair<Socket::AcceptResult, Errno> Socket::Accept() {
|
||||||
@@ -1086,7 +1092,7 @@ std::pair<Socket::AcceptResult, Errno> Socket::Accept() {
|
|||||||
|
|
||||||
const SOCKET new_socket = accept(fd, reinterpret_cast<sockaddr*>(&addr), &addrlen);
|
const SOCKET new_socket = accept(fd, reinterpret_cast<sockaddr*>(&addr), &addrlen);
|
||||||
if (new_socket == INVALID_SOCKET) {
|
if (new_socket == INVALID_SOCKET) {
|
||||||
return {AcceptResult{}, GetAndLogLastError()};
|
return {AcceptResult{}, GetAndLogLastError(CallType::Other)};
|
||||||
}
|
}
|
||||||
|
|
||||||
AcceptResult result{
|
AcceptResult result{
|
||||||
@@ -1106,14 +1112,14 @@ Errno Socket::Connect(Network::SockAddrIn addr_in) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return GetAndLogLastError();
|
return GetAndLogLastError(CallType::Other);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<Network::SockAddrIn, Errno> Socket::GetPeerName() {
|
std::pair<Network::SockAddrIn, Errno> Socket::GetPeerName() {
|
||||||
sockaddr_in addr;
|
sockaddr_in addr;
|
||||||
socklen_t addrlen = sizeof(addr);
|
socklen_t addrlen = sizeof(addr);
|
||||||
if (getpeername(fd, reinterpret_cast<sockaddr*>(&addr), &addrlen) == SOCKET_ERROR)
|
if (getpeername(fd, reinterpret_cast<sockaddr*>(&addr), &addrlen) == SOCKET_ERROR)
|
||||||
return {Network::SockAddrIn{}, GetAndLogLastError()};
|
return {Network::SockAddrIn{}, GetAndLogLastError(CallType::Other)};
|
||||||
return {TranslateToSockAddrIn(addr), Errno::SUCCESS};
|
return {TranslateToSockAddrIn(addr), Errno::SUCCESS};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1121,7 +1127,7 @@ std::pair<Network::SockAddrIn, Errno> Socket::GetSockName() {
|
|||||||
sockaddr_in addr;
|
sockaddr_in addr;
|
||||||
socklen_t addrlen = sizeof(addr);
|
socklen_t addrlen = sizeof(addr);
|
||||||
if (getsockname(fd, reinterpret_cast<sockaddr*>(&addr), &addrlen) == SOCKET_ERROR) {
|
if (getsockname(fd, reinterpret_cast<sockaddr*>(&addr), &addrlen) == SOCKET_ERROR) {
|
||||||
return {Network::SockAddrIn{}, GetAndLogLastError()};
|
return {Network::SockAddrIn{}, GetAndLogLastError(CallType::Other)};
|
||||||
}
|
}
|
||||||
|
|
||||||
return {TranslateToSockAddrIn(addr), Errno::SUCCESS};
|
return {TranslateToSockAddrIn(addr), Errno::SUCCESS};
|
||||||
@@ -1131,13 +1137,13 @@ Errno Socket::Bind(Network::SockAddrIn addr) {
|
|||||||
auto const addr_in = TranslateFromSockAddrIn(addr);
|
auto const addr_in = TranslateFromSockAddrIn(addr);
|
||||||
if (bind(fd, reinterpret_cast<sockaddr const*>(&addr_in), sizeof(addr_in)) != SOCKET_ERROR)
|
if (bind(fd, reinterpret_cast<sockaddr const*>(&addr_in), sizeof(addr_in)) != SOCKET_ERROR)
|
||||||
return Errno::SUCCESS;
|
return Errno::SUCCESS;
|
||||||
return GetAndLogLastError();
|
return GetAndLogLastError(CallType::Other);
|
||||||
}
|
}
|
||||||
|
|
||||||
Errno Socket::Listen(s32 backlog) {
|
Errno Socket::Listen(s32 backlog) {
|
||||||
if (listen(fd, backlog) != SOCKET_ERROR)
|
if (listen(fd, backlog) != SOCKET_ERROR)
|
||||||
return Errno::SUCCESS;
|
return Errno::SUCCESS;
|
||||||
return GetAndLogLastError();
|
return GetAndLogLastError(CallType::Other);
|
||||||
}
|
}
|
||||||
|
|
||||||
Errno Socket::Shutdown(ShutdownHow how) {
|
Errno Socket::Shutdown(ShutdownHow how) {
|
||||||
@@ -1160,7 +1166,7 @@ Errno Socket::Shutdown(ShutdownHow how) {
|
|||||||
return Errno::SUCCESS;
|
return Errno::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
return GetAndLogLastError();
|
return GetAndLogLastError(CallType::Other);
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 TranslateMsgOptToNative(s32 flags) {
|
s32 TranslateMsgOptToNative(s32 flags) {
|
||||||
@@ -1203,7 +1209,7 @@ std::pair<s32, Errno> Socket::Recv(int flags, std::span<u8> message) {
|
|||||||
auto const result = recv(fd, reinterpret_cast<char*>(message.data()), int(message.size()), native_flags);
|
auto const result = recv(fd, reinterpret_cast<char*>(message.data()), int(message.size()), native_flags);
|
||||||
if (result != SOCKET_ERROR)
|
if (result != SOCKET_ERROR)
|
||||||
return {s32(result), Errno::SUCCESS};
|
return {s32(result), Errno::SUCCESS};
|
||||||
return {-1, GetAndLogLastError()};
|
return {-1, GetAndLogLastError(CallType::Other)};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<s32, Errno> Socket::RecvFrom(int flags, std::span<u8> message, Network::SockAddrIn* addr) {
|
std::pair<s32, Errno> Socket::RecvFrom(int flags, std::span<u8> message, Network::SockAddrIn* addr) {
|
||||||
@@ -1223,7 +1229,7 @@ std::pair<s32, Errno> Socket::RecvFrom(int flags, std::span<u8> message, Network
|
|||||||
}
|
}
|
||||||
return {s32(result), Errno::SUCCESS};
|
return {s32(result), Errno::SUCCESS};
|
||||||
}
|
}
|
||||||
return {-1, GetAndLogLastError()};
|
return {-1, GetAndLogLastError(CallType::Other)};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<s32, Errno> Socket::Send(std::span<const u8> message, int flags) {
|
std::pair<s32, Errno> Socket::Send(std::span<const u8> message, int flags) {
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/logging.h"
|
#include "common/logging.h"
|
||||||
#include "core/internal_network/socket_icmp.h"
|
#include "core/internal_network/socket_icmp.h"
|
||||||
|
|
||||||
#ifdef __unix__
|
#ifdef __unix__
|
||||||
|
#include <unistd.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -91,25 +93,46 @@ std::pair<s32, Errno> IcmpSocket::RecvFrom(int flags, std::span<u8> message, Net
|
|||||||
LOG_DEBUG(Network, "(stubbed) called");
|
LOG_DEBUG(Network, "(stubbed) called");
|
||||||
ASSERT(flags == 0);
|
ASSERT(flags == 0);
|
||||||
ASSERT(message.size() < std::size_t((std::numeric_limits<int>::max)()));
|
ASSERT(message.size() < std::size_t((std::numeric_limits<int>::max)()));
|
||||||
std::vector<u8> data;
|
#ifdef __unix__
|
||||||
data.push_back(8);
|
if (addr) {
|
||||||
data.push_back(0);
|
if (seq_ident.empty())
|
||||||
data.push_back(0); //checksum (placeholder 0)
|
return {0, Errno::SUCCESS};
|
||||||
data.push_back(0);
|
// PLEASE DON'T KILL ME, I SWEAR THIS IS LEGITIMATELY THE BEST WAY TO DO IT
|
||||||
data.push_back(message[4]); //ident
|
// IF YOU OPEN socket() GOOGLE WILL STRAIGHT UP IP BAN YOU AFTER 2 HOURS
|
||||||
data.push_back(message[5]);
|
auto const cmd = fmt::format("ping -o {}.{}.{}.{}", addr->ip[0], addr->ip[1], addr->ip[2], addr->ip[3]);
|
||||||
data.push_back(message[6]); //seq
|
if (::system(cmd.c_str()) == 0) {
|
||||||
data.push_back(message[7]);
|
std::vector<u8> data{
|
||||||
auto const csum = ComputeChecksum(std::span<const u8>{data.begin(), data.end()});
|
8,
|
||||||
data[2] = u8(csum >> 8); //hi
|
0,
|
||||||
data[3] = u8(csum); //lo
|
0, //checksum
|
||||||
auto const n = (std::max)(data.size(), message.size());
|
0,
|
||||||
std::copy(data.begin(), data.begin() + n, message.begin());
|
u8(seq_ident.front() >> 24), //ident
|
||||||
return {n, Errno::SUCCESS};
|
u8(seq_ident.front() >> 16),
|
||||||
|
u8(seq_ident.front() >> 8), // seq
|
||||||
|
u8(seq_ident.front() >> 0),
|
||||||
|
};
|
||||||
|
seq_ident.pop_back();
|
||||||
|
auto const csum = ComputeChecksum(std::span<const u8>{data.begin(), data.end()});
|
||||||
|
data[2] = u8(csum >> 8); //hi
|
||||||
|
data[3] = u8(csum); //lo
|
||||||
|
auto const n = (std::max)(data.size(), message.size());
|
||||||
|
std::copy(data.begin(), data.begin() + n, message.begin());
|
||||||
|
return {n, Errno::SUCCESS};
|
||||||
|
}
|
||||||
|
return {-1, Errno::TIMEDOUT};
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return {-1, Errno::INVAL};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<s32, Errno> IcmpSocket::Send(std::span<const u8> message, int flags) {
|
std::pair<s32, Errno> IcmpSocket::Send(std::span<const u8> message, int flags) {
|
||||||
LOG_DEBUG(Network, "(stubbed) called");
|
LOG_DEBUG(Network, "(stubbed) called");
|
||||||
|
seq_ident.push_back(
|
||||||
|
(u32(message[4]) << 24)
|
||||||
|
| (u32(message[5]) << 16)
|
||||||
|
| (u32(message[6]) << 8)
|
||||||
|
| (u32(message[7]) << 0)
|
||||||
|
);
|
||||||
return {s32(0), Errno::NOTCONN};
|
return {s32(0), Errno::NOTCONN};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,7 +146,7 @@ std::pair<s32, Errno> IcmpSocket::SendTo(u32 flags, std::span<const u8> message,
|
|||||||
// 6..8 -> seq
|
// 6..8 -> seq
|
||||||
if (!message.empty())
|
if (!message.empty())
|
||||||
return {s32(message.size()), Errno::SUCCESS};
|
return {s32(message.size()), Errno::SUCCESS};
|
||||||
return {s32(0), Errno::NETDOWN};
|
return {-1, Errno::INVAL};
|
||||||
}
|
}
|
||||||
|
|
||||||
Errno IcmpSocket::Close() {
|
Errno IcmpSocket::Close() {
|
||||||
@@ -145,7 +168,6 @@ void IcmpSocket::HandleProxyPacket(const ProxyPacket& packet) {
|
|||||||
LOG_WARNING(Network, "(stubbed) called");
|
LOG_WARNING(Network, "(stubbed) called");
|
||||||
}
|
}
|
||||||
Errno IcmpSocket::SetNonBlock(bool enable) {
|
Errno IcmpSocket::SetNonBlock(bool enable) {
|
||||||
LOG_WARNING(Network, "(stubbed) called");
|
|
||||||
return Errno::SUCCESS;
|
return Errno::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ public:
|
|||||||
bool IsOpened() const override;
|
bool IsOpened() const override;
|
||||||
void HandleProxyPacket(const ProxyPacket& packet) override;
|
void HandleProxyPacket(const ProxyPacket& packet) override;
|
||||||
Errno SetNonBlock(bool enable) override;
|
Errno SetNonBlock(bool enable) override;
|
||||||
|
|
||||||
|
std::vector<u32> seq_ident;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Network
|
} // namespace Network
|
||||||
|
|||||||
Reference in New Issue
Block a user