[net] refactor to remove uneeded abstraction layer

Signed-off-by: lizzie <lizzie@eden-emu.dev>
This commit is contained in:
lizzie
2026-07-01 18:16:09 +00:00
parent b7f0f98519
commit 40b3df8f77
24 changed files with 847 additions and 1299 deletions
+3 -2
View File
@@ -1,10 +1,11 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include <atomic>
#include <common/socket_types.h>
#include <mutex>
#include "core/internal_network/socket_types.h"
namespace Network {
+198 -98
View File
@@ -74,7 +74,7 @@ SOCKET GetInterruptSocket() {
return interrupt_socket;
}
sockaddr TranslateFromSockAddrIn(SockAddrIn input) {
sockaddr TranslateFromSockAddrIn(Network::SockAddrIn input) {
sockaddr_in result;
#ifdef __unix__
@@ -158,6 +158,8 @@ Errno TranslateNativeError(int e, CallType call_type = CallType::Other) {
return Errno::INPROGRESS;
case WSAEISCONN:
return Errno::ISCONN;
case WSAEADDRINUSE:
return Errno::ADDRINUSE;
default:
UNIMPLEMENTED_MSG("Unimplemented errno={}", e);
return Errno::OTHER;
@@ -213,7 +215,7 @@ SOCKET GetInterruptSocket() {
return interrupt_pipe_fd[0];
}
sockaddr TranslateFromSockAddrIn(SockAddrIn input) {
sockaddr TranslateFromSockAddrIn(Network::SockAddrIn input) {
sockaddr_in result;
switch (static_cast<Domain>(input.family)) {
@@ -265,40 +267,29 @@ bool EnableNonBlock(int fd, bool enable) {
Errno TranslateNativeError(int e, CallType call_type = CallType::Other) {
switch (e) {
case 0:
return Errno::SUCCESS;
case EBADF:
return Errno::BADF;
case EINVAL:
return Errno::INVAL;
case EMFILE:
return Errno::MFILE;
case EPIPE:
return Errno::PIPE;
case ECONNABORTED:
return Errno::CONNABORTED;
case ENOTCONN:
return Errno::NOTCONN;
case EAGAIN:
return Errno::AGAIN;
case ECONNREFUSED:
return Errno::CONNREFUSED;
case ECONNRESET:
return Errno::CONNRESET;
case EHOSTUNREACH:
return Errno::HOSTUNREACH;
case ENETDOWN:
return Errno::NETDOWN;
case ENETUNREACH:
return Errno::NETUNREACH;
case EMSGSIZE:
return Errno::MSGSIZE;
case ETIMEDOUT:
return Errno::TIMEDOUT;
case EINPROGRESS:
return Errno::INPROGRESS;
case EISCONN:
return Errno::ISCONN;
case 0: return Errno::SUCCESS;
#define NETWORK_ERROR_LIST \
NETWORK_ERROR_ELEM(BADF) \
NETWORK_ERROR_ELEM(INVAL) \
NETWORK_ERROR_ELEM(MFILE) \
NETWORK_ERROR_ELEM(PIPE) \
NETWORK_ERROR_ELEM(CONNABORTED) \
NETWORK_ERROR_ELEM(NOTCONN) \
NETWORK_ERROR_ELEM(AGAIN) \
NETWORK_ERROR_ELEM(CONNREFUSED) \
NETWORK_ERROR_ELEM(CONNRESET) \
NETWORK_ERROR_ELEM(HOSTUNREACH) \
NETWORK_ERROR_ELEM(NETDOWN) \
NETWORK_ERROR_ELEM(NETUNREACH) \
NETWORK_ERROR_ELEM(MSGSIZE) \
NETWORK_ERROR_ELEM(TIMEDOUT) \
NETWORK_ERROR_ELEM(INPROGRESS) \
NETWORK_ERROR_ELEM(ISCONN) \
NETWORK_ERROR_ELEM(ADDRINUSE)
#define NETWORK_ERROR_ELEM(name) case E##name: return Errno::name;
NETWORK_ERROR_LIST
#undef NETWORK_ERROR_ELEM
#undef NETWORK_ERROR_LIST
default:
UNIMPLEMENTED_MSG("Unimplemented errno={} ({})", e, strerror(e));
return Errno::OTHER;
@@ -361,12 +352,90 @@ GetAddrInfoError TranslateGetAddrInfoErrorFromNative(int gai_err) {
}
}
#ifdef __FreeBSD__
#define NETWORK_DOMAIN_TRANSLATE_LIST \
NETWORK_DOMAIN_TRANSLATE_ELEM(UNIX) \
NETWORK_DOMAIN_TRANSLATE_ELEM(INET) \
NETWORK_DOMAIN_TRANSLATE_ELEM(IMPLINK) \
NETWORK_DOMAIN_TRANSLATE_ELEM(PUP) \
NETWORK_DOMAIN_TRANSLATE_ELEM(CHAOS) \
NETWORK_DOMAIN_TRANSLATE_ELEM(NETBIOS) \
NETWORK_DOMAIN_TRANSLATE_ELEM(ISO) \
NETWORK_DOMAIN_TRANSLATE_ELEM(ECMA) \
NETWORK_DOMAIN_TRANSLATE_ELEM(DATAKIT) \
NETWORK_DOMAIN_TRANSLATE_ELEM(CCITT) \
NETWORK_DOMAIN_TRANSLATE_ELEM(SNA) \
NETWORK_DOMAIN_TRANSLATE_ELEM(DECnet) \
NETWORK_DOMAIN_TRANSLATE_ELEM(DLI) \
NETWORK_DOMAIN_TRANSLATE_ELEM(LAT) \
NETWORK_DOMAIN_TRANSLATE_ELEM(HYLINK) \
NETWORK_DOMAIN_TRANSLATE_ELEM(APPLETALK) \
NETWORK_DOMAIN_TRANSLATE_ELEM(ROUTE) \
NETWORK_DOMAIN_TRANSLATE_ELEM(LINK) \
NETWORK_DOMAIN_TRANSLATE_ELEM(COIP) \
NETWORK_DOMAIN_TRANSLATE_ELEM(CNT) \
NETWORK_DOMAIN_TRANSLATE_ELEM(IPX) \
NETWORK_DOMAIN_TRANSLATE_ELEM(SIP) \
NETWORK_DOMAIN_TRANSLATE_ELEM(ISDN) \
NETWORK_DOMAIN_TRANSLATE_ELEM(INET6) \
NETWORK_DOMAIN_TRANSLATE_ELEM(NATM) \
NETWORK_DOMAIN_TRANSLATE_ELEM(ATM) \
NETWORK_DOMAIN_TRANSLATE_ELEM(NETGRAPH) \
NETWORK_DOMAIN_TRANSLATE_ELEM(SLOW) \
NETWORK_DOMAIN_TRANSLATE_ELEM(SCLUSTER) \
NETWORK_DOMAIN_TRANSLATE_ELEM(ARP) \
NETWORK_DOMAIN_TRANSLATE_ELEM(BLUETOOTH) \
NETWORK_DOMAIN_TRANSLATE_ELEM(IEEE80211) \
NETWORK_DOMAIN_TRANSLATE_ELEM(NETLINK) \
NETWORK_DOMAIN_TRANSLATE_ELEM(INET_SDP) \
NETWORK_DOMAIN_TRANSLATE_ELEM(INET6_SDP)
#elif defined(__linux__)
#define NETWORK_DOMAIN_TRANSLATE_LIST \
NETWORK_DOMAIN_TRANSLATE_ELEM(UNIX) \
NETWORK_DOMAIN_TRANSLATE_ELEM(INET) \
NETWORK_DOMAIN_TRANSLATE_ELEM(SNA) \
NETWORK_DOMAIN_TRANSLATE_ELEM(DECnet) \
NETWORK_DOMAIN_TRANSLATE_ELEM(APPLETALK) \
NETWORK_DOMAIN_TRANSLATE_ELEM(ROUTE) \
NETWORK_DOMAIN_TRANSLATE_ELEM(IPX) \
NETWORK_DOMAIN_TRANSLATE_ELEM(ISDN) \
NETWORK_DOMAIN_TRANSLATE_ELEM(INET6) \
NETWORK_DOMAIN_TRANSLATE_ELEM(ATM) \
NETWORK_DOMAIN_TRANSLATE_ELEM(BLUETOOTH) \
NETWORK_DOMAIN_TRANSLATE_ELEM(NETLINK)
#elif defined(_WIN32)
#define NETWORK_DOMAIN_TRANSLATE_LIST \
NETWORK_DOMAIN_TRANSLATE_ELEM(UNIX) \
NETWORK_DOMAIN_TRANSLATE_ELEM(INET) \
NETWORK_DOMAIN_TRANSLATE_ELEM(IMPLINK) \
NETWORK_DOMAIN_TRANSLATE_ELEM(PUP) \
NETWORK_DOMAIN_TRANSLATE_ELEM(CHAOS) \
NETWORK_DOMAIN_TRANSLATE_ELEM(ISO) \
NETWORK_DOMAIN_TRANSLATE_ELEM(ECMA) \
NETWORK_DOMAIN_TRANSLATE_ELEM(DATAKIT) \
NETWORK_DOMAIN_TRANSLATE_ELEM(CCITT) \
NETWORK_DOMAIN_TRANSLATE_ELEM(SNA) \
NETWORK_DOMAIN_TRANSLATE_ELEM(DECnet) \
NETWORK_DOMAIN_TRANSLATE_ELEM(DLI) \
NETWORK_DOMAIN_TRANSLATE_ELEM(LAT) \
NETWORK_DOMAIN_TRANSLATE_ELEM(HYLINK) \
NETWORK_DOMAIN_TRANSLATE_ELEM(APPLETALK) \
NETWORK_DOMAIN_TRANSLATE_ELEM(NETBIOS) \
NETWORK_DOMAIN_TRANSLATE_ELEM(ATM) \
NETWORK_DOMAIN_TRANSLATE_ELEM(INET6) \
NETWORK_DOMAIN_TRANSLATE_ELEM(CLUSTER)
#else
#define NETWORK_DOMAIN_TRANSLATE_LIST \
NETWORK_DOMAIN_TRANSLATE_ELEM(INET) \
NETWORK_DOMAIN_TRANSLATE_ELEM(INET6)
#endif
Domain TranslateDomainFromNative(int domain) {
switch (domain) {
case 0:
return Domain::Unspecified;
case AF_INET:
return Domain::INET;
case AF_UNSPEC: return Domain::Unspecified;
#define NETWORK_DOMAIN_TRANSLATE_ELEM(x) case AF_##x: return Domain::x;
NETWORK_DOMAIN_TRANSLATE_LIST
#undef NETWORK_DOMAIN_TRANSLATE_ELEM
default:
UNIMPLEMENTED_MSG("Unhandled domain={}", domain);
return Domain::INET;
@@ -375,23 +444,26 @@ Domain TranslateDomainFromNative(int domain) {
int TranslateDomainToNative(Domain domain) {
switch (domain) {
case Domain::Unspecified:
return 0;
case Domain::INET:
return AF_INET;
case Domain::Unspecified: return AF_UNSPEC;
#define NETWORK_DOMAIN_TRANSLATE_ELEM(x) case Domain::x: return AF_##x;
NETWORK_DOMAIN_TRANSLATE_LIST
#undef NETWORK_DOMAIN_TRANSLATE_ELEM
default:
UNIMPLEMENTED_MSG("Unimplemented domain={}", domain);
return 0;
}
}
#undef NETWORK_DOMAIN_TRANSLATE_LIST
// Must account for SOCK_CLOEXEC and SOCK_NONBLOCK
// so mask the lower bits as those aren't usually used for flags
Type TranslateTypeFromNative(int type) {
switch (type) {
case 0:
return Type::Unspecified;
switch (type & 0xff) {
case 0: return Type::Unspecified;
case SOCK_STREAM: return Type::STREAM;
case SOCK_DGRAM: return Type::DGRAM;
case SOCK_RAW: return Type::RAW;
case SOCK_RDM: return Type::RDM;
case SOCK_SEQPACKET: return Type::SEQPACKET;
default:
UNIMPLEMENTED_MSG("Unimplemented type={}", type);
@@ -400,12 +472,12 @@ Type TranslateTypeFromNative(int type) {
}
int TranslateTypeToNative(Type type) {
switch (type) {
case Type::Unspecified:
return 0;
switch (Type(int(type) & 0xff)) {
case Type::Unspecified: return 0;
case Type::STREAM: return SOCK_STREAM;
case Type::DGRAM: return SOCK_DGRAM;
case Type::RAW: return SOCK_RAW;
case Type::RDM: return SOCK_RDM;
case Type::SEQPACKET: return SOCK_SEQPACKET;
default:
UNIMPLEMENTED_MSG("Unimplemented type={}", type);
@@ -530,6 +602,40 @@ int TranslateTypeToNative(Type type) {
NETWORK_PROTOCOL_TRANSLATE_ELEM(PGM) \
NETWORK_PROTOCOL_TRANSLATE_ELEM(MPLS) \
NETWORK_PROTOCOL_TRANSLATE_ELEM(PFSYNC)
#elif defined(__OPENORBIS__)
#define NETWORK_PROTOCOL_TRANSLATE_LIST \
NETWORK_PROTOCOL_TRANSLATE_ELEM(IP) \
/*NETWORK_PROTOCOL_TRANSLATE_ELEM(HOPOPTS)*/ \
NETWORK_PROTOCOL_TRANSLATE_ELEM(ICMP) \
NETWORK_PROTOCOL_TRANSLATE_ELEM(IGMP) \
/*NETWORK_PROTOCOL_TRANSLATE_ELEM(IPIP)*/ \
NETWORK_PROTOCOL_TRANSLATE_ELEM(TCP) \
NETWORK_PROTOCOL_TRANSLATE_ELEM(EGP) \
NETWORK_PROTOCOL_TRANSLATE_ELEM(PUP) \
NETWORK_PROTOCOL_TRANSLATE_ELEM(UDP) \
NETWORK_PROTOCOL_TRANSLATE_ELEM(IDP) \
NETWORK_PROTOCOL_TRANSLATE_ELEM(TP) \
NETWORK_PROTOCOL_TRANSLATE_ELEM(DCCP) \
NETWORK_PROTOCOL_TRANSLATE_ELEM(IPV6) \
NETWORK_PROTOCOL_TRANSLATE_ELEM(ROUTING) \
NETWORK_PROTOCOL_TRANSLATE_ELEM(FRAGMENT) \
NETWORK_PROTOCOL_TRANSLATE_ELEM(RSVP) \
NETWORK_PROTOCOL_TRANSLATE_ELEM(GRE) \
NETWORK_PROTOCOL_TRANSLATE_ELEM(ESP) \
NETWORK_PROTOCOL_TRANSLATE_ELEM(AH) \
NETWORK_PROTOCOL_TRANSLATE_ELEM(ICMPV6) \
NETWORK_PROTOCOL_TRANSLATE_ELEM(NONE) \
NETWORK_PROTOCOL_TRANSLATE_ELEM(DSTOPTS) \
NETWORK_PROTOCOL_TRANSLATE_ELEM(MTP) \
/*NETWORK_PROTOCOL_TRANSLATE_ELEM(BEETPH)*/ \
NETWORK_PROTOCOL_TRANSLATE_ELEM(ENCAP) \
NETWORK_PROTOCOL_TRANSLATE_ELEM(PIM) \
/*NETWORK_PROTOCOL_TRANSLATE_ELEM(COMP)*/ \
NETWORK_PROTOCOL_TRANSLATE_ELEM(SCTP) \
NETWORK_PROTOCOL_TRANSLATE_ELEM(MH) \
NETWORK_PROTOCOL_TRANSLATE_ELEM(UDPLITE) \
NETWORK_PROTOCOL_TRANSLATE_ELEM(MPLS) \
NETWORK_PROTOCOL_TRANSLATE_ELEM(RAW)
#elif defined(__linux__)
// Other platforms may not support some niche protocols.
// This is usually not an issue
@@ -620,68 +726,63 @@ int TranslateTypeToNative(Type type) {
}
#undef NETWORK_PROTOCOL_TRANSLATE_LIST
SockAddrIn TranslateToSockAddrIn(sockaddr_in input, size_t input_len) {
SockAddrIn result{};
result.family = TranslateDomainFromNative(input.sin_family);
Network::SockAddrIn TranslateToSockAddrIn(sockaddr_in input, size_t input_len) {
Network::SockAddrIn result{};
result.len = 16;
result.family = u8(TranslateDomainFromNative(input.sin_family));
result.portno = ntohs(input.sin_port);
result.ip = TranslateIPv4(input.sin_addr);
result.zeroes = {};
return result;
}
short TranslatePollEvents(PollEvents events) {
short result = 0;
const auto translate = [&result, &events](PollEvents guest, short host) {
static s16 TranslatePollEvents(Network::PollEvents events) noexcept {
s16 result = 0;
const auto translate = [&result, &events](Network::PollEvents guest, s16 host) {
if (True(events & guest)) {
events &= ~guest;
result |= host;
}
};
translate(PollEvents::In, POLLIN);
translate(PollEvents::Pri, POLLPRI);
translate(PollEvents::Out, POLLOUT);
translate(PollEvents::Err, POLLERR);
translate(PollEvents::Hup, POLLHUP);
translate(PollEvents::Nval, POLLNVAL);
translate(PollEvents::RdNorm, POLLRDNORM);
translate(PollEvents::RdBand, POLLRDBAND);
translate(PollEvents::WrBand, POLLWRBAND);
translate(Network::PollEvents::In, POLLIN);
translate(Network::PollEvents::Pri, POLLPRI);
translate(Network::PollEvents::Out, POLLOUT);
translate(Network::PollEvents::Err, POLLERR);
translate(Network::PollEvents::Hup, POLLHUP);
translate(Network::PollEvents::Nval, POLLNVAL);
translate(Network::PollEvents::RdNorm, POLLRDNORM);
translate(Network::PollEvents::RdBand, POLLRDBAND);
translate(Network::PollEvents::WrBand, POLLWRBAND);
#ifdef _WIN32
short allowed_events = POLLRDBAND | POLLRDNORM | POLLWRNORM;
s16 allowed_events = POLLRDBAND | POLLRDNORM | POLLWRNORM;
// Unlike poll on other OSes, WSAPoll will complain if any other flags are set on input.
if (result & ~allowed_events) {
LOG_DEBUG(Network,
"Removing WSAPoll input events {:#x} because Windows doesn't support them",
result & ~allowed_events);
LOG_DEBUG(Network, "Removing WSAPoll input events {:#x} because Windows doesn't support them", result & ~allowed_events);
}
result &= allowed_events;
#endif
UNIMPLEMENTED_IF_MSG((u16)events != 0, "Unhandled guest events={:#x}", (u16)events);
return result;
}
PollEvents TranslatePollRevents(short revents) {
PollEvents result{};
const auto translate = [&result, &revents](short host, PollEvents guest) {
Network::PollEvents TranslatePollRevents(short revents) {
Network::PollEvents result{};
const auto translate = [&result, &revents](short host, Network::PollEvents guest) {
if ((revents & host) != 0) {
revents &= static_cast<short>(~host);
result |= guest;
}
};
translate(POLLIN, PollEvents::In);
translate(POLLPRI, PollEvents::Pri);
translate(POLLOUT, PollEvents::Out);
translate(POLLERR, PollEvents::Err);
translate(POLLHUP, PollEvents::Hup);
translate(POLLNVAL, PollEvents::Nval);
translate(POLLRDNORM, PollEvents::RdNorm);
translate(POLLRDBAND, PollEvents::RdBand);
translate(POLLWRBAND, PollEvents::WrBand);
translate(POLLIN, Network::PollEvents::In);
translate(POLLPRI, Network::PollEvents::Pri);
translate(POLLOUT, Network::PollEvents::Out);
translate(POLLERR, Network::PollEvents::Err);
translate(POLLHUP, Network::PollEvents::Hup);
translate(POLLNVAL, Network::PollEvents::Nval);
translate(POLLRDNORM, Network::PollEvents::RdNorm);
translate(POLLRDBAND, Network::PollEvents::RdBand);
translate(POLLWRBAND, Network::PollEvents::WrBand);
UNIMPLEMENTED_IF_MSG(revents != 0, "Unhandled host revents={:#x}", revents);
@@ -753,8 +854,7 @@ std::variant<std::vector<AddrInfo>, GetAddrInfoError> GetAddressInfo(
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);
out.addr = TranslateToSockAddrIn(*reinterpret_cast<sockaddr_in*>(current->ai_addr), current->ai_addrlen);
if (current->ai_canonname != nullptr) {
out.canon_name = current->ai_canonname;
}
@@ -763,11 +863,11 @@ std::variant<std::vector<AddrInfo>, GetAddrInfoError> GetAddressInfo(
return ret;
}
std::pair<s32, Errno> Poll(std::vector<PollFD>& pollfds, s32 timeout) {
std::pair<s32, Errno> Poll(std::span<HostPollFD> pollfds, s32 timeout) {
const size_t num = pollfds.size();
std::vector<WSAPOLLFD> host_pollfds(pollfds.size());
std::transform(pollfds.begin(), pollfds.end(), host_pollfds.begin(), [](PollFD fd) {
std::transform(pollfds.begin(), pollfds.end(), host_pollfds.begin(), [](HostPollFD fd) {
WSAPOLLFD result;
result.fd = fd.socket->GetFD();
result.events = TranslatePollEvents(fd.events);
@@ -883,7 +983,7 @@ std::pair<SocketBase::AcceptResult, Errno> Socket::Accept() {
return {std::move(result), Errno::SUCCESS};
}
Errno Socket::Connect(SockAddrIn addr_in) {
Errno Socket::Connect(Network::SockAddrIn addr_in) {
const sockaddr host_addr_in = TranslateFromSockAddrIn(addr_in);
if (connect(fd, &host_addr_in, sizeof(host_addr_in)) != SOCKET_ERROR) {
return Errno::SUCCESS;
@@ -892,27 +992,27 @@ Errno Socket::Connect(SockAddrIn addr_in) {
return GetAndLogLastError();
}
std::pair<SockAddrIn, Errno> Socket::GetPeerName() {
std::pair<Network::SockAddrIn, Errno> Socket::GetPeerName() {
sockaddr_in addr;
socklen_t addrlen = sizeof(addr);
if (getpeername(fd, reinterpret_cast<sockaddr*>(&addr), &addrlen) == SOCKET_ERROR) {
return {SockAddrIn{}, GetAndLogLastError()};
return {Network::SockAddrIn{}, GetAndLogLastError()};
}
return {TranslateToSockAddrIn(addr, addrlen), Errno::SUCCESS};
}
std::pair<SockAddrIn, Errno> Socket::GetSockName() {
std::pair<Network::SockAddrIn, Errno> Socket::GetSockName() {
sockaddr_in addr;
socklen_t addrlen = sizeof(addr);
if (getsockname(fd, reinterpret_cast<sockaddr*>(&addr), &addrlen) == SOCKET_ERROR) {
return {SockAddrIn{}, GetAndLogLastError()};
return {Network::SockAddrIn{}, GetAndLogLastError()};
}
return {TranslateToSockAddrIn(addr, addrlen), Errno::SUCCESS};
}
Errno Socket::Bind(SockAddrIn addr) {
Errno Socket::Bind(Network::SockAddrIn addr) {
const sockaddr addr_in = TranslateFromSockAddrIn(addr);
if (bind(fd, &addr_in, sizeof(addr_in)) != SOCKET_ERROR) {
return Errno::SUCCESS;
@@ -965,7 +1065,7 @@ std::pair<s32, Errno> Socket::Recv(int flags, std::span<u8> message) {
return {-1, GetAndLogLastError()};
}
std::pair<s32, Errno> Socket::RecvFrom(int flags, std::span<u8> message, SockAddrIn* addr) {
std::pair<s32, Errno> Socket::RecvFrom(int flags, std::span<u8> message, Network::SockAddrIn* addr) {
ASSERT(flags == 0);
ASSERT(message.size() < static_cast<size_t>((std::numeric_limits<int>::max)()));
@@ -1004,7 +1104,7 @@ std::pair<s32, Errno> Socket::Send(std::span<const u8> message, int flags) {
}
std::pair<s32, Errno> Socket::SendTo(u32 flags, std::span<const u8> message,
const SockAddrIn* addr) {
const Network::SockAddrIn* addr) {
ASSERT(flags == 0);
const sockaddr* to = nullptr;
+4 -62
View File
@@ -13,7 +13,7 @@
#include "common/common_funcs.h"
#include "common/common_types.h"
#include "common/socket_types.h"
#include "core/internal_network/socket_types.h"
#ifdef _WIN32
#include <winsock2.h>
@@ -31,68 +31,10 @@ namespace Network {
class SocketBase;
class Socket;
/// Error code for network functions
enum class Errno {
SUCCESS,
BADF,
INVAL,
MFILE,
PIPE,
NOTCONN,
AGAIN,
CONNREFUSED,
CONNRESET,
CONNABORTED,
HOSTUNREACH,
NETDOWN,
NETUNREACH,
TIMEDOUT,
MSGSIZE,
INPROGRESS,
ISCONN,
OTHER,
};
enum class GetAddrInfoError {
SUCCESS,
ADDRFAMILY,
AGAIN,
BADFLAGS,
FAIL,
FAMILY,
MEMORY,
NODATA,
NONAME,
SERVICE,
SOCKTYPE,
SYSTEM,
BADHINTS,
PROTOCOL,
OVERFLOW_,
OTHER,
};
/// Cross-platform poll fd structure
enum class PollEvents : u16 {
// Using Pascal case because IN is a macro on Windows.
In = 1 << 0,
Pri = 1 << 1,
Out = 1 << 2,
Err = 1 << 3,
Hup = 1 << 4,
Nval = 1 << 5,
RdNorm = 1 << 6,
RdBand = 1 << 7,
WrBand = 1 << 8,
};
DECLARE_ENUM_FLAG_OPERATORS(PollEvents);
struct PollFD {
struct HostPollFD {
SocketBase* socket;
PollEvents events;
PollEvents revents;
Network::PollEvents events;
Network::PollEvents revents;
};
class NetworkInstance {
@@ -46,7 +46,7 @@ namespace Network {
#ifdef _WIN32
std::vector<Network::NetworkInterface> GetAvailableNetworkInterfaces() {
std::vector<NetworkInterface> GetAvailableNetworkInterfaces() {
ULONG buf_size = 0;
if (GetAdaptersAddresses(
@@ -66,7 +66,7 @@ std::vector<Network::NetworkInterface> GetAvailableNetworkInterfaces() {
return {};
}
std::vector<Network::NetworkInterface> result;
std::vector<NetworkInterface> result;
for (auto* a = addrs; a; a = a->Next) {
@@ -89,7 +89,7 @@ std::vector<Network::NetworkInterface> GetAvailableNetworkInterfaces() {
gw = reinterpret_cast<sockaddr_in*>(a->FirstGatewayAddress->Address.lpSockaddr)
->sin_addr;
result.emplace_back(Network::NetworkInterface{
result.emplace_back(NetworkInterface{
.name = Common::UTF16ToUTF8(std::wstring{a->FriendlyName}),
.ip_address = ip,
.subnet_mask = mask,
@@ -103,7 +103,7 @@ std::vector<Network::NetworkInterface> GetAvailableNetworkInterfaces() {
#else
std::vector<Network::NetworkInterface> GetAvailableNetworkInterfaces() {
std::vector<NetworkInterface> GetAvailableNetworkInterfaces() {
#if defined(__ANDROID__) || defined(__linux__)
struct ifaddrs* ifaddr = nullptr;
if (getifaddrs(&ifaddr) != 0) {
@@ -135,7 +135,7 @@ std::vector<Network::NetworkInterface> GetAvailableNetworkInterfaces() {
LOG_WARNING(Network, "\"/proc/net/route\" not found - using gateway 0");
}
#endif
std::vector<Network::NetworkInterface> ifaces;
std::vector<NetworkInterface> ifaces;
for (auto ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next) {
if (ifa->ifa_addr == nullptr || ifa->ifa_netmask == nullptr /* Have a netmask and address */
|| ifa->ifa_addr->sa_family != AF_INET /* Must be of kind AF_INET */
@@ -149,7 +149,7 @@ std::vector<Network::NetworkInterface> GetAvailableNetworkInterfaces() {
});
in_addr gw; // Solaris defines s_addr as a macro, can't use special C++ shenanigans here
gw.s_addr = it != routes.end() ? it->gateway : 0;
ifaces.emplace_back(Network::NetworkInterface{
ifaces.emplace_back(NetworkInterface{
.name = ifa->ifa_name,
.ip_address = std::bit_cast<struct sockaddr_in>(*ifa->ifa_addr).sin_addr,
.subnet_mask = std::bit_cast<struct sockaddr_in>(*ifa->ifa_netmask).sin_addr,
@@ -159,7 +159,7 @@ std::vector<Network::NetworkInterface> GetAvailableNetworkInterfaces() {
freeifaddrs(ifaddr);
return ifaces;
#elif defined(__FreeBSD__)
std::vector<Network::NetworkInterface> ifaces;
std::vector<NetworkInterface> ifaces;
int fd = ::socket(PF_ROUTE, SOCK_RAW, AF_UNSPEC);
if (fd < 0) {
LOG_ERROR(Network, "socket: {}", std::strerror(errno));
@@ -191,7 +191,7 @@ std::vector<Network::NetworkInterface> GetAvailableNetworkInterfaces() {
size_t msglen = rtm->rtm_msglen - sizeof(*ifm);
char const* p = (char const*)(ifm + 1);
Network::NetworkInterface iface{};
NetworkInterface iface{};
for (size_t i = 0; i < RTAX_MAX; i++)
if ((ifm->ifm_addrs & (1 << i)) != 0) {
struct sockaddr const* sa = reinterpret_cast<struct sockaddr const*>(p);
@@ -220,7 +220,7 @@ std::vector<Network::NetworkInterface> GetAvailableNetworkInterfaces() {
#endif // _WIN32
std::optional<Network::NetworkInterface> GetSelectedNetworkInterface() {
std::optional<NetworkInterface> GetSelectedNetworkInterface() {
auto const& sel_if = Settings::values.network_interface.GetValue();
if (auto const ifaces = Network::GetAvailableNetworkInterfaces(); ifaces.size() > 0) {
if (sel_if.empty())
+12 -10
View File
@@ -65,22 +65,22 @@ std::pair<ProxySocket::AcceptResult, Errno> ProxySocket::Accept() {
return {AcceptResult{}, Errno::SUCCESS};
}
Errno ProxySocket::Connect(SockAddrIn addr_in) {
Errno ProxySocket::Connect(Network::SockAddrIn addr_in) {
LOG_WARNING(Network, "(STUBBED) called");
return Errno::SUCCESS;
}
std::pair<SockAddrIn, Errno> ProxySocket::GetPeerName() {
std::pair<Network::SockAddrIn, Errno> ProxySocket::GetPeerName() {
LOG_WARNING(Network, "(STUBBED) called");
return {SockAddrIn{}, Errno::SUCCESS};
return {Network::SockAddrIn{}, Errno::SUCCESS};
}
std::pair<SockAddrIn, Errno> ProxySocket::GetSockName() {
std::pair<Network::SockAddrIn, Errno> ProxySocket::GetSockName() {
LOG_WARNING(Network, "(STUBBED) called");
return {SockAddrIn{}, Errno::SUCCESS};
return {Network::SockAddrIn{}, Errno::SUCCESS};
}
Errno ProxySocket::Bind(SockAddrIn addr) {
Errno ProxySocket::Bind(Network::SockAddrIn addr) {
if (is_bound) {
LOG_WARNING(Network, "Rebinding Socket is unimplemented!");
return Errno::SUCCESS;
@@ -109,7 +109,7 @@ std::pair<s32, Errno> ProxySocket::Recv(int flags, std::span<u8> message) {
return {static_cast<s32>(0), Errno::SUCCESS};
}
std::pair<s32, Errno> ProxySocket::RecvFrom(int flags, std::span<u8> message, SockAddrIn* addr) {
std::pair<s32, Errno> ProxySocket::RecvFrom(int flags, std::span<u8> message, Network::SockAddrIn* addr) {
ASSERT(flags == 0);
ASSERT(message.size() < static_cast<size_t>((std::numeric_limits<int>::max)()));
@@ -143,13 +143,15 @@ std::pair<s32, Errno> ProxySocket::RecvFrom(int flags, std::span<u8> message, So
}
}
std::pair<s32, Errno> ProxySocket::ReceivePacket(int flags, std::span<u8> message, SockAddrIn* addr,
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->family = Domain::INET;
addr->len = 16;
addr->family = u8(Network::Domain::INET);
addr->ip = packet.local_endpoint.ip; // The senders ip address
addr->portno = packet.local_endpoint.portno; // The senders port number
addr->zeroes = {};
}
bool peek = (flags & FLAG_MSG_PEEK) != 0;
@@ -199,7 +201,7 @@ void ProxySocket::SendPacket(ProxyPacket& packet) {
}
std::pair<s32, Errno> ProxySocket::SendTo(u32 flags, std::span<const u8> message,
const SockAddrIn* addr) {
const Network::SockAddrIn* addr) {
ASSERT(flags == 0);
if (!is_bound) {
+9 -9
View File
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -29,13 +29,13 @@ public:
std::pair<AcceptResult, Errno> Accept() override;
Errno Connect(SockAddrIn addr_in) override;
Errno Connect(Network::SockAddrIn addr_in) override;
std::pair<SockAddrIn, Errno> GetPeerName() override;
std::pair<Network::SockAddrIn, Errno> GetPeerName() override;
std::pair<SockAddrIn, Errno> GetSockName() override;
std::pair<Network::SockAddrIn, Errno> GetSockName() override;
Errno Bind(SockAddrIn addr) override;
Errno Bind(Network::SockAddrIn addr) override;
Errno Listen(s32 backlog) override;
@@ -43,9 +43,9 @@ public:
std::pair<s32, Errno> Recv(int flags, std::span<u8> message) override;
std::pair<s32, Errno> RecvFrom(int flags, std::span<u8> message, SockAddrIn* addr) override;
std::pair<s32, Errno> RecvFrom(int flags, std::span<u8> message, Network::SockAddrIn* addr) override;
std::pair<s32, Errno> ReceivePacket(int flags, std::span<u8> message, SockAddrIn* addr,
std::pair<s32, Errno> ReceivePacket(int flags, std::span<u8> message, Network::SockAddrIn* addr,
std::size_t max_length);
std::pair<s32, Errno> Send(std::span<const u8> message, int flags) override;
@@ -53,7 +53,7 @@ public:
void SendPacket(ProxyPacket& packet);
std::pair<s32, Errno> SendTo(u32 flags, std::span<const u8> message,
const SockAddrIn* addr) override;
const Network::SockAddrIn* addr) override;
Errno SetLinger(bool enable, u32 linger) override;
@@ -86,7 +86,7 @@ private:
u32 send_timeout = 0;
u32 receive_timeout = 0;
bool is_bound = false;
SockAddrIn local_endpoint{};
Network::SockAddrIn local_endpoint{};
bool blocking = true;
std::queue<ProxyPacket> received_packets;
Protocol protocol;
+313
View File
@@ -0,0 +1,313 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <optional>
#include <string>
#include "common/common_types.h"
#include "common/common_funcs.h"
// Most of these structures are direct mappings of guest's
// expectations for these values, in other words, they're the
// values that HOS is expected to use AND handle.
namespace Network {
enum class Errno : u32 {
SUCCESS = 0,
BADF = 9,
AGAIN = 11,
INVAL = 22,
MFILE = 24,
PIPE = 32,
MSGSIZE = 90,
ADDRINUSE = 98,
NETDOWN = 100,
NETUNREACH = 101,
CONNABORTED = 103,
CONNRESET = 104,
ISCONN = 106,
NOTCONN = 107,
TIMEDOUT = 110,
CONNREFUSED = 111,
HOSTUNREACH = 113,
INPROGRESS = 115,
/* made up error? */
OTHER = 196,
};
enum class GetAddrInfoError : s32 {
SUCCESS = 0,
ADDRFAMILY = 1,
AGAIN = 2,
BADFLAGS = 3,
FAIL = 4,
FAMILY = 5,
MEMORY = 6,
NODATA = 7,
NONAME = 8,
SERVICE = 9,
SOCKTYPE = 10,
SYSTEM = 11,
BADHINTS = 12,
PROTOCOL = 13,
OVERFLOW_ = 14, // avoid name collision with Windows macro
OTHER = 15,
};
enum class Domain : u32 {
Unspecified = 0,
UNIX = 1,
INET = 2,
IMPLINK = 3,
PUP = 4,
CHAOS = 5,
NETBIOS = 6,
ISO = 7,
ECMA = 8,
DATAKIT = 9,
CCITT = 10,
SNA = 11,
DECnet = 12,
DLI = 13,
LAT = 14,
HYLINK = 15,
APPLETALK = 16,
ROUTE = 17,
LINK = 18,
COIP = 20,
CNT = 21,
IPX = 23,
SIP = 24,
ISDN = 26,
INET6 = 28,
NATM = 29,
ATM = 30,
NETGRAPH = 32,
SLOW = 33,
SCLUSTER = 34,
ARP = 35,
BLUETOOTH = 36,
IEEE80211 = 37,
NETLINK = 38,
INET_SDP = 40,
INET6_SDP = 42,
};
enum class Type : u32 {
Unspecified = 0,
STREAM = 1,
DGRAM = 2,
RAW = 3,
RDM = 4,
SEQPACKET = 5,
};
enum class Protocol : u32 {
IP = 0,
ICMP = 1,
TCP = 6,
UDP = 17,
//
IPV6 = 41,
RAW = 255,
//
HOPOPTS = 0,
IGMP = 2,
GGP = 3,
IPV4 = 4,
ST = 7,
EGP = 8,
PIGP = 9,
RCCMON = 10,
NVPII = 11,
PUP = 12,
ARGUS = 13,
EMCON = 14,
XNET = 15,
CHAOS = 16,
MUX = 18,
MEAS = 19,
HMP = 20,
PRM = 21,
IDP = 22,
TRUNK1 = 23,
TRUNK2 = 24,
LEAF1 = 25,
LEAF2 = 26,
RDP = 27,
IRTP = 28,
TP = 29,
BLT = 30,
NSP = 31,
INP = 32,
DCCP = 33,
//3PC = 34,
IDPR = 35,
XTP = 36,
DDP = 37,
CMTP = 38,
TPXX = 39,
IL = 40,
SDRP = 42,
ROUTING = 43,
FRAGMENT = 44,
IDRP = 45,
RSVP = 46,
GRE = 47,
MHRP = 48,
BHA = 49,
ESP = 50,
AH = 51,
INLSP = 52,
SWIPE = 53,
NHRP = 54,
MOBILE = 55,
TLSP = 56,
SKIP = 57,
ICMPV6 = 58,
NONE = 59,
DSTOPTS = 60,
AHIP = 61,
CFTP = 62,
HELLO = 63,
SATEXPAK = 64,
KRYPTOLAN = 65,
RVD = 66,
IPPC = 67,
ADFS = 68,
SATMON = 69,
VISA = 70,
IPCV = 71,
CPNX = 72,
CPHB = 73,
WSN = 74,
PVP = 75,
BRSATMON = 76,
ND = 77,
WBMON = 78,
WBEXPAK = 79,
EON = 80,
VMTP = 81,
SVMTP = 82,
VINES = 83,
TTP = 84,
IGP = 85,
DGP = 86,
TCF = 87,
IGRP = 88,
OSPFIGP = 89,
SRPC = 90,
LARP = 91,
MTP = 92,
AX25 = 93,
IPEIP = 94,
MICP = 95,
SCCSP = 96,
ETHERIP = 97,
ENCAP = 98,
APES = 99,
GMTP = 100,
IPCOMP = 108,
SCTP = 132,
MH = 135,
UDPLITE = 136,
HIP = 139,
SHIM6 = 140,
PIM = 103,
CARP = 112,
PGM = 113,
MPLS = 137,
PFSYNC = 240,
};
enum class SocketLevel : u32 {
IP = 0,
TCP = 6,
SOCKET = 0xffff, // i.e. SOL_SOCKET
};
enum class OptName : u32 {
REUSEADDR = 0x4,
KEEPALIVE = 0x8,
BROADCAST = 0x20,
LINGER = 0x80,
SNDBUF = 0x1001,
RCVBUF = 0x1002,
SNDTIMEO = 0x1005,
RCVTIMEO = 0x1006,
ERROR_ = 0x1007, // avoid name collision with Windows macro
NOSIGPIPE = 0x800, // at least according to libnx
ACCEPTFILTER = 0x1000,
BINTIME = 0x2000,
NO_OFFLOAD = 0x4000,
NO_DDP = 0x8000,
};
enum class ShutdownHow : s32 {
RD = 0,
WR = 1,
RDWR = 2,
};
enum class FcntlCmd : s32 {
GETFL = 3,
SETFL = 4,
};
/// Array of IPv4 address
using IPv4Address = std::array<u8, 4>;
struct SockAddrIn {
u8 len;
u8 family;
u16 portno;
IPv4Address ip;
std::array<u8, 248> zeroes;
};
static_assert(sizeof(SockAddrIn) == 0x100);
enum class PollEvents : u16 {
// Using Pascal case because IN is a macro on Windows.
In = 1 << 0,
Pri = 1 << 1,
Out = 1 << 2,
Err = 1 << 3,
Hup = 1 << 4,
Nval = 1 << 5,
RdNorm = 1 << 6,
RdBand = 1 << 7,
WrBand = 1 << 8,
};
DECLARE_ENUM_FLAG_OPERATORS(PollEvents);
struct PollFD {
s32 fd;
Network::PollEvents events;
Network::PollEvents revents;
};
struct Linger {
u32 onoff;
u32 linger;
};
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;
Type socket_type;
Protocol protocol;
SockAddrIn addr;
std::optional<std::string> canon_name;
};
} // namespace Network
+15 -15
View File
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
@@ -30,7 +30,7 @@ public:
struct AcceptResult {
std::unique_ptr<SocketBase> socket;
SockAddrIn sockaddr_in;
Network::SockAddrIn sockaddr_in;
};
SocketBase() = default;
@@ -46,13 +46,13 @@ public:
virtual std::pair<AcceptResult, Errno> Accept() = 0;
virtual Errno Connect(SockAddrIn addr_in) = 0;
virtual Errno Connect(Network::SockAddrIn addr_in) = 0;
virtual std::pair<SockAddrIn, Errno> GetPeerName() = 0;
virtual std::pair<Network::SockAddrIn, Errno> GetPeerName() = 0;
virtual std::pair<SockAddrIn, Errno> GetSockName() = 0;
virtual std::pair<Network::SockAddrIn, Errno> GetSockName() = 0;
virtual Errno Bind(SockAddrIn addr) = 0;
virtual Errno Bind(Network::SockAddrIn addr) = 0;
virtual Errno Listen(s32 backlog) = 0;
@@ -60,12 +60,12 @@ public:
virtual std::pair<s32, Errno> Recv(int flags, std::span<u8> message) = 0;
virtual std::pair<s32, Errno> RecvFrom(int flags, std::span<u8> message, SockAddrIn* addr) = 0;
virtual std::pair<s32, Errno> RecvFrom(int flags, std::span<u8> message, Network::SockAddrIn* addr) = 0;
virtual std::pair<s32, Errno> Send(std::span<const u8> message, int flags) = 0;
virtual std::pair<s32, Errno> SendTo(u32 flags, std::span<const u8> message,
const SockAddrIn* addr) = 0;
const Network::SockAddrIn* addr) = 0;
virtual Errno SetLinger(bool enable, u32 linger) = 0;
@@ -114,13 +114,13 @@ public:
std::pair<AcceptResult, Errno> Accept() override;
Errno Connect(SockAddrIn addr_in) override;
Errno Connect(Network::SockAddrIn addr_in) override;
std::pair<SockAddrIn, Errno> GetPeerName() override;
std::pair<Network::SockAddrIn, Errno> GetPeerName() override;
std::pair<SockAddrIn, Errno> GetSockName() override;
std::pair<Network::SockAddrIn, Errno> GetSockName() override;
Errno Bind(SockAddrIn addr) override;
Errno Bind(Network::SockAddrIn addr) override;
Errno Listen(s32 backlog) override;
@@ -128,12 +128,12 @@ public:
std::pair<s32, Errno> Recv(int flags, std::span<u8> message) override;
std::pair<s32, Errno> RecvFrom(int flags, std::span<u8> message, SockAddrIn* addr) override;
std::pair<s32, Errno> RecvFrom(int flags, std::span<u8> message, Network::SockAddrIn* addr) override;
std::pair<s32, Errno> Send(std::span<const u8> message, int flags) override;
std::pair<s32, Errno> SendTo(u32 flags, std::span<const u8> message,
const SockAddrIn* addr) override;
const Network::SockAddrIn* addr) override;
Errno SetLinger(bool enable, u32 linger) override;
@@ -169,6 +169,6 @@ private:
bool is_non_blocking = false;
};
std::pair<s32, Errno> Poll(std::vector<PollFD>& poll_fds, s32 timeout);
std::pair<s32, Errno> Poll(std::span<Network::HostPollFD> poll_fds, s32 timeout);
} // namespace Network