mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-09-01 10:52:26 +00:00
[net] refactor to remove uneeded abstraction layer
Signed-off-by: lizzie <lizzie@eden-emu.dev>
This commit is contained in:
@@ -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 {
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user