diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 87c4642f04..d2bd9ac298 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -108,7 +108,6 @@ add_library( settings_input.h settings_setting.h slot_vector.h - socket_types.h spin_lock.h stb.cpp stb.h diff --git a/src/common/announce_multiplayer_room.h b/src/common/announce_multiplayer_room.h index bca0ee8e2e..25356bc1be 100644 --- a/src/common/announce_multiplayer_room.h +++ b/src/common/announce_multiplayer_room.h @@ -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 2017 Citra Emulator Project @@ -11,7 +11,7 @@ #include #include #include "common/common_types.h" -#include "common/socket_types.h" +#include "core/internal_network/socket_types.h" #include "web_service/web_result.h" namespace AnnounceMultiplayerRoom { diff --git a/src/common/socket_types.h b/src/common/socket_types.h deleted file mode 100644 index 5b1e4d7b1d..0000000000 --- a/src/common/socket_types.h +++ /dev/null @@ -1,178 +0,0 @@ -// 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 -#include - -#include "common/common_types.h" - -namespace Network { - -/// Address families -enum class Domain : u8 { - Unspecified, ///< Represents 0, used in getaddrinfo hints - INET, ///< Address family for IPv4 -}; - -/// Socket types -enum class Type { - Unspecified, ///< Represents 0, used in getaddrinfo hints - STREAM, - DGRAM, - RAW, - SEQPACKET, -}; - -/// Protocol values for sockets -enum class Protocol : u8 { - Unspecified, ///< Represents 0, usable in various places - IP, - ICMP, - TCP, - UDP, - IPV6, - RAW, - IGMP, - GGP, - IPV4, - ST, - EGP, - PIGP, - RCCMON, - NVPII, - PUP, - ARGUS, - EMCON, - XNET, - CHAOS, - MUX, - MEAS, - HMP, - PRM, - IDP, - TRUNK1, - TRUNK2, - LEAF1, - LEAF2, - RDP, - IRTP, - TP, - BLT, - NSP, - INP, - DCCP, - //TODO: 3PC, - IDPR, - XTP, - DDP, - CMTP, - TPXX, - IL, - SDRP, - ROUTING, - FRAGMENT, - IDRP, - RSVP, - GRE, - MHRP, - BHA, - ESP, - AH, - INLSP, - SWIPE, - NHRP, - MOBILE, - TLSP, - SKIP, - ICMPV6, - NONE, - DSTOPTS, - AHIP, - CFTP, - HELLO, - SATEXPAK, - KRYPTOLAN, - RVD, - IPPC, - ADFS, - SATMON, - VISA, - IPCV, - CPNX, - CPHB, - WSN, - PVP, - BRSATMON, - ND, - WBMON, - WBEXPAK, - EON, - VMTP, - SVMTP, - VINES, - TTP, - IGP, - DGP, - TCF, - IGRP, - OSPFIGP, - SRPC, - LARP, - MTP, - AX25, - IPEIP, - MICP, - SCCSP, - ETHERIP, - ENCAP, - APES, - GMTP, - IPCOMP, - SCTP, - MH, - UDPLITE, - HIP, - SHIM6, - PIM, - CARP, - PGM, - MPLS, - PFSYNC -}; - -/// Shutdown mode -enum class ShutdownHow { - RD, - WR, - RDWR, -}; - -/// Array of IPv4 address -using IPv4Address = std::array; - -/// Cross-platform sockaddr structure -struct SockAddrIn { - Domain family; - IPv4Address ip; - u16 portno; -}; - -constexpr u32 FLAG_MSG_PEEK = 0x2; -constexpr u32 FLAG_MSG_DONTWAIT = 0x80; -constexpr u32 FLAG_O_NONBLOCK = 0x800; - -/// Cross-platform addrinfo structure -struct AddrInfo { - Domain family; - Type socket_type; - Protocol protocol; - SockAddrIn addr; - std::optional canon_name; -}; - -} // namespace Network diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 16806ff0c0..8c9b4baebc 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -1133,6 +1133,7 @@ add_library(core STATIC internal_network/network_interface.h internal_network/socket_proxy.cpp internal_network/socket_proxy.h + internal_network/socket_types.h internal_network/sockets.h internal_network/wifi_scanner.h launch_timestamp_cache.cpp diff --git a/src/core/hle/service/ldn/lan_discovery.h b/src/core/hle/service/ldn/lan_discovery.h index fb24608ae1..514565116b 100644 --- a/src/core/hle/service/ldn/lan_discovery.h +++ b/src/core/hle/service/ldn/lan_discovery.h @@ -18,7 +18,7 @@ #include #include "common/logging.h" -#include "common/socket_types.h" +#include "core/internal_network/socket_types.h" #include "core/hle/result.h" #include "core/hle/service/ldn/ldn_results.h" #include "core/hle/service/ldn/ldn_types.h" diff --git a/src/core/hle/service/sockets/bsd.cpp b/src/core/hle/service/sockets/bsd.cpp index 9ffaeedd4f..4d0466c398 100644 --- a/src/core/hle/service/sockets/bsd.cpp +++ b/src/core/hle/service/sockets/bsd.cpp @@ -12,7 +12,7 @@ #include #include "common/logging.h" -#include "common/socket_types.h" +#include "core/internal_network/socket_types.h" #include "core/core.h" #include "core/hle/kernel/k_thread.h" #include "core/hle/service/ipc_helpers.h" @@ -28,11 +28,11 @@ namespace Service::Sockets { namespace { -bool IsConnectionBased(Type type) { +bool IsConnectionBased(Network::Type type) { switch (type) { - case Type::STREAM: + case Network::Type::STREAM: return true; - case Type::DGRAM: + case Network::Type::DGRAM: return false; default: UNIMPLEMENTED_MSG("Unimplemented type={}", type); @@ -92,7 +92,7 @@ void BSD::ConnectWork::Execute(BSD* bsd) { void BSD::ConnectWork::Response(HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 4}; rb.Push(ResultSuccess); - rb.Push(bsd_errno == Errno::SUCCESS ? 0 : -1); + rb.Push(bsd_errno == Network::Errno::SUCCESS ? 0 : -1); rb.PushEnum(bsd_errno); } @@ -173,8 +173,8 @@ void BSD::Socket(HLERequestContext& ctx) { LOG_DEBUG(Service, "called. domain={} type={} protocol={}", domain, type, protocol); - const auto [fd, bsd_errno] = SocketImpl(static_cast(domain), static_cast(type), - static_cast(protocol)); + const auto [fd, bsd_errno] = SocketImpl(static_cast(domain), static_cast(type), + static_cast(protocol)); IPC::ResponseBuilder rb{ctx, 4}; rb.Push(ResultSuccess); @@ -246,13 +246,13 @@ void BSD::GetPeerName(HLERequestContext& ctx) { LOG_DEBUG(Service, "called. fd={}", fd); std::vector write_buffer(ctx.GetWriteBufferSize()); - const Errno bsd_errno = GetPeerNameImpl(fd, write_buffer); + const Network::Errno bsd_errno = GetPeerNameImpl(fd, write_buffer); ctx.WriteBuffer(write_buffer); IPC::ResponseBuilder rb{ctx, 5}; rb.Push(ResultSuccess); - rb.Push(bsd_errno != Errno::SUCCESS ? -1 : 0); + rb.Push(bsd_errno != Network::Errno::SUCCESS ? -1 : 0); rb.PushEnum(bsd_errno); rb.Push(static_cast(write_buffer.size())); } @@ -264,13 +264,13 @@ void BSD::GetSockName(HLERequestContext& ctx) { LOG_DEBUG(Service, "called. fd={}", fd); std::vector write_buffer(ctx.GetWriteBufferSize()); - const Errno bsd_errno = GetSockNameImpl(fd, write_buffer); + const Network::Errno bsd_errno = GetSockNameImpl(fd, write_buffer); ctx.WriteBuffer(write_buffer); IPC::ResponseBuilder rb{ctx, 5}; rb.Push(ResultSuccess); - rb.Push(bsd_errno != Errno::SUCCESS ? -1 : 0); + rb.Push(bsd_errno != Network::Errno::SUCCESS ? -1 : 0); rb.PushEnum(bsd_errno); rb.Push(static_cast(write_buffer.size())); } @@ -279,20 +279,20 @@ void BSD::GetSockOpt(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const s32 fd = rp.Pop(); const u32 level = rp.Pop(); - const auto optname = static_cast(rp.Pop()); + const auto optname = static_cast(rp.Pop()); std::vector optval(ctx.GetWriteBufferSize()); LOG_DEBUG(Service, "called. fd={} level={} optname={:#x} len={:#x}", fd, level, optname, optval.size()); - const Errno err = GetSockOptImpl(fd, level, optname, optval); + const Network::Errno err = GetSockOptImpl(fd, level, optname, optval); ctx.WriteBuffer(optval); IPC::ResponseBuilder rb{ctx, 5}; rb.Push(ResultSuccess); - rb.Push(err == Errno::SUCCESS ? 0 : -1); + rb.Push(err == Network::Errno::SUCCESS ? 0 : -1); rb.PushEnum(err); rb.Push(static_cast(optval.size())); } @@ -315,7 +315,7 @@ void BSD::Fcntl(HLERequestContext& ctx) { LOG_DEBUG(Service, "called. fd={} cmd={} arg={}", fd, cmd, arg); - const auto [ret, bsd_errno] = FcntlImpl(fd, static_cast(cmd), arg); + const auto [ret, bsd_errno] = FcntlImpl(fd, Network::FcntlCmd(cmd), arg); IPC::ResponseBuilder rb{ctx, 4}; rb.Push(ResultSuccess); @@ -328,12 +328,10 @@ void BSD::SetSockOpt(HLERequestContext& ctx) { const s32 fd = rp.Pop(); const u32 level = rp.Pop(); - const OptName optname = static_cast(rp.Pop()); + const Network::OptName optname = Network::OptName(rp.Pop()); const auto optval = ctx.ReadBuffer(); - LOG_DEBUG(Service, "called. fd={} level={} optname={:#x} optlen={}", fd, level, - static_cast(optname), optval.size()); - + LOG_DEBUG(Service, "called. fd={} level={} optname={:#x} optlen={}", fd, level, u32(optname), optval.size()); BuildErrnoResponse(ctx, SetSockOptImpl(fd, level, optname, optval)); } @@ -454,7 +452,7 @@ void BSD::DuplicateSocket(HLERequestContext& ctx) { struct OutputParameters { s32 ret; - Errno bsd_errno; + Network::Errno bsd_errno; }; static_assert(sizeof(OutputParameters) == 0x8); @@ -468,10 +466,10 @@ void BSD::DuplicateSocket(HLERequestContext& ctx) { if (auto* res = std::get_if(&res_v)) { rb.PushRaw(OutputParameters{ .ret = *res, - .bsd_errno = Errno::SUCCESS, + .bsd_errno = Network::Errno::SUCCESS, }); } else { - auto* err = std::get_if(&res_v); + auto* err = std::get_if(&res_v); rb.PushRaw(OutputParameters{ .ret = 0, .bsd_errno = *err, @@ -486,7 +484,7 @@ void BSD::EventFd(HLERequestContext& ctx) { LOG_WARNING(Service, "(STUBBED) called. initval={}, flags={}", initval, flags); - BuildErrnoResponse(ctx, Errno::SUCCESS); + BuildErrnoResponse(ctx, Network::Errno::SUCCESS); } template @@ -495,22 +493,22 @@ void BSD::ExecuteWork(HLERequestContext& ctx, Work work) { work.Response(ctx); } -std::pair BSD::SocketImpl(Domain domain, Type type, Protocol protocol) { +std::pair BSD::SocketImpl(Network::Domain domain, Network::Type type, Network::Protocol protocol) { - if (type == Type::SEQPACKET) { + if (type == Network::Type::SEQPACKET) { UNIMPLEMENTED_MSG("SOCK_SEQPACKET errno management"); - } else if (type == Type::RAW && (domain != Domain::INET || protocol != Protocol::ICMP)) { + } else if (type == Network::Type::RAW && (domain != Network::Domain::INET || protocol != Network::Protocol::ICMP)) { UNIMPLEMENTED_MSG("SOCK_RAW errno management"); } [[maybe_unused]] const bool unk_flag = (static_cast(type) & 0x20000000) != 0; UNIMPLEMENTED_IF_MSG(unk_flag, "Unknown flag in type"); - type = static_cast(static_cast(type) & ~0x20000000); + type = Network::Type(u32(type) & ~0x20000000); const s32 fd = FindFreeFileDescriptorHandle(); if (fd < 0) { LOG_ERROR(Service, "No more file descriptors available"); - return {-1, Errno::MFILE}; + return {-1, Network::Errno::MFILE}; } file_descriptors[fd] = FileDescriptor{}; @@ -526,69 +524,69 @@ std::pair BSD::SocketImpl(Domain domain, Type type, Protocol protoco descriptor.socket = std::make_shared(); } - descriptor.socket->Initialize(Translate(domain), Translate(type), Translate(protocol)); + descriptor.socket->Initialize(domain, type, protocol); descriptor.is_connection_based = IsConnectionBased(type); if (Settings::values.airplane_mode.GetValue() && descriptor.is_connection_based) { LOG_ERROR(Service, "Airplane mode is enabled, cannot create socket"); - return {-1, Errno::NOTCONN}; + return {-1, Network::Errno::NOTCONN}; } - return {fd, Errno::SUCCESS}; + return {fd, Network::Errno::SUCCESS}; } -std::pair BSD::PollImpl(std::vector& write_buffer, std::span read_buffer, +std::pair BSD::PollImpl(std::vector& write_buffer, std::span read_buffer, s32 nfds, s32 timeout) { if (nfds <= 0) { // When no entries are provided, -1 is returned with errno zero - return {-1, Errno::SUCCESS}; + return {-1, Network::Errno::SUCCESS}; } - if (read_buffer.size() < nfds * sizeof(PollFD)) { - return {-1, Errno::INVAL}; + if (read_buffer.size() < nfds * sizeof(Network::PollFD)) { + return {-1, Network::Errno::INVAL}; } - if (write_buffer.size() < nfds * sizeof(PollFD)) { - return {-1, Errno::INVAL}; + if (write_buffer.size() < nfds * sizeof(Network::PollFD)) { + return {-1, Network::Errno::INVAL}; } - std::vector fds(nfds); - std::memcpy(fds.data(), read_buffer.data(), nfds * sizeof(PollFD)); + std::vector fds(nfds); + std::memcpy(fds.data(), read_buffer.data(), nfds * sizeof(Network::PollFD)); if (timeout >= 0) { const s64 seconds = timeout / 1000; const u64 nanoseconds = 1'000'000 * (static_cast(timeout) % 1000); if (seconds < 0) { - return {-1, Errno::INVAL}; + return {-1, Network::Errno::INVAL}; } if (nanoseconds > 999'999'999) { - return {-1, Errno::INVAL}; + return {-1, Network::Errno::INVAL}; } } else if (timeout != -1) { - return {-1, Errno::INVAL}; + return {-1, Network::Errno::INVAL}; } - for (PollFD& pollfd : fds) { + for (Network::PollFD& pollfd : fds) { ASSERT(False(pollfd.revents)); if (pollfd.fd > static_cast(MAX_FD) || pollfd.fd < 0) { LOG_ERROR(Service, "File descriptor handle={} is invalid", pollfd.fd); - pollfd.revents = PollEvents{}; - return {0, Errno::SUCCESS}; + pollfd.revents = Network::PollEvents{}; + return {0, Network::Errno::SUCCESS}; } const std::optional& descriptor = file_descriptors[pollfd.fd]; if (!descriptor) { LOG_TRACE(Service, "File descriptor handle={} is not allocated", pollfd.fd); - pollfd.revents = PollEvents::Nval; - return {0, Errno::SUCCESS}; + pollfd.revents = Network::PollEvents::Nval; + return {0, Network::Errno::SUCCESS}; } } - std::vector host_pollfds(fds.size()); - std::transform(fds.begin(), fds.end(), host_pollfds.begin(), [](PollFD pollfd) { - Network::PollFD result; + std::vector host_pollfds(fds.size()); + std::transform(fds.begin(), fds.end(), host_pollfds.begin(), [](Network::PollFD pollfd) { + Network::HostPollFD result{}; result.socket = file_descriptors[pollfd.fd]->socket.get(); - result.events = Translate(pollfd.events); + result.events = pollfd.events; result.revents = Network::PollEvents{}; return result; }); @@ -597,28 +595,27 @@ std::pair BSD::PollImpl(std::vector& write_buffer, std::span BSD::AcceptImpl(s32 fd, std::vector& write_buffer) { +std::pair BSD::AcceptImpl(s32 fd, std::vector& write_buffer) { if (!IsFileDescriptorValid(fd)) { - return {-1, Errno::BADF}; + return {-1, Network::Errno::BADF}; } const s32 new_fd = FindFreeFileDescriptorHandle(); if (new_fd < 0) { LOG_ERROR(Service, "No more file descriptors available"); - return {-1, Errno::MFILE}; + return {-1, Network::Errno::MFILE}; } FileDescriptor& descriptor = *file_descriptors[fd]; auto [result, bsd_errno] = descriptor.socket->Accept(); if (bsd_errno != Network::Errno::SUCCESS) { - return {-1, Translate(bsd_errno)}; + return {-1, bsd_errno}; } file_descriptors[new_fd] = FileDescriptor{}; @@ -626,239 +623,228 @@ std::pair BSD::AcceptImpl(s32 fd, std::vector& write_buffer) { new_descriptor.socket = std::move(result.socket); new_descriptor.is_connection_based = descriptor.is_connection_based; - const SockAddrIn guest_addr_in = Translate(result.sockaddr_in); - PutValue(write_buffer, guest_addr_in); - - return {new_fd, Errno::SUCCESS}; + PutValue(write_buffer, result.sockaddr_in); + return {new_fd, Network::Errno::SUCCESS}; } -Errno BSD::BindImpl(s32 fd, std::span addr) { +Network::Errno BSD::BindImpl(s32 fd, std::span addr) { if (!IsFileDescriptorValid(fd)) { - return Errno::BADF; + return Network::Errno::BADF; } ASSERT(addr.size() >= 16); if (!file_descriptors[fd]->socket) { LOG_WARNING(Service, "Uninitialized socket"); - return Errno::BADF; + return Network::Errno::BADF; } - auto addr_in = GetValue(addr); - - return Translate(file_descriptors[fd]->socket->Bind(Translate(addr_in))); + auto addr_in = GetValue(addr); + return file_descriptors[fd]->socket->Bind(addr_in); } -Errno BSD::ConnectImpl(s32 fd, std::span addr) { +Network::Errno BSD::ConnectImpl(s32 fd, std::span addr) { if (!IsFileDescriptorValid(fd)) { - return Errno::BADF; + return Network::Errno::BADF; } ASSERT(addr.size() >= 16); if (!file_descriptors[fd]->socket) { LOG_WARNING(Service, "Uninitialized socket"); - return Errno::BADF; + return Network::Errno::BADF; } - auto addr_in = GetValue(addr); - - const Errno result = Translate(file_descriptors[fd]->socket->Connect(Translate(addr_in))); - - if (result == Errno::ISCONN) { + auto addr_in = GetValue(addr); + const Network::Errno result = file_descriptors[fd]->socket->Connect(addr_in); + if (result == Network::Errno::ISCONN) { LOG_DEBUG(Service, "returned ISCONN - socket already connected"); - return Errno::SUCCESS; + return Network::Errno::SUCCESS; } return result; } -Errno BSD::GetPeerNameImpl(s32 fd, std::vector& write_buffer) { +Network::Errno BSD::GetPeerNameImpl(s32 fd, std::vector& write_buffer) { if (!IsFileDescriptorValid(fd)) { - return Errno::BADF; + return Network::Errno::BADF; } if (!file_descriptors[fd]->socket) { LOG_WARNING(Service, "Uninitialized socket"); - return Errno::BADF; + return Network::Errno::BADF; } const auto [addr_in, bsd_errno] = file_descriptors[fd]->socket->GetPeerName(); if (bsd_errno != Network::Errno::SUCCESS) { - return Translate(bsd_errno); + return bsd_errno; } - const SockAddrIn guest_addrin = Translate(addr_in); - - ASSERT(write_buffer.size() >= sizeof(guest_addrin)); - write_buffer.resize(sizeof(guest_addrin)); - PutValue(write_buffer, guest_addrin); - return Translate(bsd_errno); + ASSERT(write_buffer.size() >= sizeof(addr_in)); + write_buffer.resize(sizeof(addr_in)); + PutValue(write_buffer, addr_in); + return bsd_errno; } -Errno BSD::GetSockNameImpl(s32 fd, std::vector& write_buffer) { +Network::Errno BSD::GetSockNameImpl(s32 fd, std::vector& write_buffer) { if (!IsFileDescriptorValid(fd)) { - return Errno::BADF; + return Network::Errno::BADF; } if (!file_descriptors[fd]->socket) { LOG_WARNING(Service, "Uninitialized socket"); - return Errno::BADF; + return Network::Errno::BADF; } const auto [addr_in, bsd_errno] = file_descriptors[fd]->socket->GetSockName(); if (bsd_errno != Network::Errno::SUCCESS) { - return Translate(bsd_errno); + return bsd_errno; } - const SockAddrIn guest_addrin = Translate(addr_in); - - ASSERT(write_buffer.size() >= sizeof(guest_addrin)); - write_buffer.resize(sizeof(guest_addrin)); - PutValue(write_buffer, guest_addrin); - return Translate(bsd_errno); + ASSERT(write_buffer.size() >= sizeof(addr_in)); + write_buffer.resize(sizeof(addr_in)); + PutValue(write_buffer, addr_in); + return bsd_errno; } -Errno BSD::ListenImpl(s32 fd, s32 backlog) { +Network::Errno BSD::ListenImpl(s32 fd, s32 backlog) { if (!IsFileDescriptorValid(fd)) { - return Errno::BADF; + return Network::Errno::BADF; } if (!file_descriptors[fd]->socket) { LOG_WARNING(Service, "Uninitialized socket"); - return Errno::BADF; + return Network::Errno::BADF; } - return Translate(file_descriptors[fd]->socket->Listen(backlog)); + return file_descriptors[fd]->socket->Listen(backlog); } -std::pair BSD::FcntlImpl(s32 fd, FcntlCmd cmd, s32 arg) { +std::pair BSD::FcntlImpl(s32 fd, Network::FcntlCmd cmd, s32 arg) { if (!IsFileDescriptorValid(fd)) { - return {-1, Errno::BADF}; + return {-1, Network::Errno::BADF}; } if (!file_descriptors[fd]->socket) { LOG_WARNING(Service, "Uninitialized socket"); - return {-1, Errno::BADF}; + return {-1, Network::Errno::BADF}; } FileDescriptor& descriptor = *file_descriptors[fd]; switch (cmd) { - case FcntlCmd::GETFL: + case Network::FcntlCmd::GETFL: ASSERT(arg == 0); - return {descriptor.flags, Errno::SUCCESS}; - case FcntlCmd::SETFL: { + return {descriptor.flags, Network::Errno::SUCCESS}; + case Network::FcntlCmd::SETFL: { const bool enable = (arg & Network::FLAG_O_NONBLOCK) != 0; - const Errno bsd_errno = Translate(descriptor.socket->SetNonBlock(enable)); - if (bsd_errno != Errno::SUCCESS) { + const Network::Errno bsd_errno = descriptor.socket->SetNonBlock(enable); + if (bsd_errno != Network::Errno::SUCCESS) { return {-1, bsd_errno}; } descriptor.flags = arg; - return {0, Errno::SUCCESS}; + return {0, Network::Errno::SUCCESS}; } default: UNIMPLEMENTED_MSG("Unimplemented cmd={}", cmd); - return {-1, Errno::SUCCESS}; + return {-1, Network::Errno::SUCCESS}; } } -Errno BSD::GetSockOptImpl(s32 fd, u32 level, OptName optname, std::vector& optval) { +Network::Errno BSD::GetSockOptImpl(s32 fd, u32 level, Network::OptName optname, std::vector& optval) { if (!IsFileDescriptorValid(fd)) { - return Errno::BADF; + return Network::Errno::BADF; } if (!file_descriptors[fd]->socket) { LOG_WARNING(Service, "Uninitialized socket"); - return Errno::BADF; + return Network::Errno::BADF; } - if (level != static_cast(SocketLevel::SOCKET)) { + if (level != static_cast(Network::SocketLevel::SOCKET)) { UNIMPLEMENTED_MSG("Unknown getsockopt level"); - return Errno::SUCCESS; + return Network::Errno::SUCCESS; } Network::SocketBase* const socket = file_descriptors[fd]->socket.get(); switch (optname) { - case OptName::ERROR_: { + case Network::OptName::ERROR_: { auto [pending_err, getsockopt_err] = socket->GetPendingError(); if (getsockopt_err == Network::Errno::SUCCESS) { - Errno translated_pending_err = Translate(pending_err); ASSERT_OR_EXECUTE_MSG( - optval.size() == sizeof(Errno), { return Errno::INVAL; }, + optval.size() == sizeof(Network::Errno), { return Network::Errno::INVAL; }, "Incorrect getsockopt option size"); - optval.resize(sizeof(Errno)); - PutValue(optval, translated_pending_err); + optval.resize(sizeof(Network::Errno)); + PutValue(optval, pending_err); } - return Translate(getsockopt_err); + return getsockopt_err; } default: UNIMPLEMENTED_MSG("Unimplemented optname={}", optname); - return Errno::SUCCESS; + return Network::Errno::SUCCESS; } } -Errno BSD::SetSockOptImpl(s32 fd, u32 level, OptName optname, std::span optval) { +Network::Errno BSD::SetSockOptImpl(s32 fd, u32 level, Network::OptName optname, std::span optval) { if (!IsFileDescriptorValid(fd)) { - return Errno::BADF; + return Network::Errno::BADF; } if (!file_descriptors[fd]->socket) { LOG_WARNING(Service, "Uninitialized socket"); - return Errno::BADF; + return Network::Errno::BADF; } - if (level != static_cast(SocketLevel::SOCKET)) { + if (level != static_cast(Network::SocketLevel::SOCKET)) { LOG_WARNING(Service, "(STUBBED) setsockopt with level={}, optname={}", level, optname); - return Errno::SUCCESS; + return Network::Errno::SUCCESS; } Network::SocketBase* const socket = file_descriptors[fd]->socket.get(); - if (optname == OptName::LINGER) { - ASSERT(optval.size() == sizeof(Linger)); - auto linger = GetValue(optval); + if (optname == Network::OptName::LINGER) { + ASSERT(optval.size() == sizeof(Network::Linger)); + auto linger = GetValue(optval); ASSERT(linger.onoff == 0 || linger.onoff == 1); - return Translate(socket->SetLinger(linger.onoff != 0, linger.linger)); + return (socket->SetLinger(linger.onoff != 0, linger.linger)); } ASSERT(optval.size() == sizeof(u32)); auto value = GetValue(optval); switch (optname) { - case OptName::REUSEADDR: + case Network::OptName::REUSEADDR: ASSERT(value == 0 || value == 1); - return Translate(socket->SetReuseAddr(value != 0)); - case OptName::KEEPALIVE: + return (socket->SetReuseAddr(value != 0)); + case Network::OptName::KEEPALIVE: ASSERT(value == 0 || value == 1); - return Translate(socket->SetKeepAlive(value != 0)); - case OptName::BROADCAST: + return (socket->SetKeepAlive(value != 0)); + case Network::OptName::BROADCAST: ASSERT(value == 0 || value == 1); - return Translate(socket->SetBroadcast(value != 0)); - case OptName::SNDBUF: - return Translate(socket->SetSndBuf(value)); - case OptName::RCVBUF: - return Translate(socket->SetRcvBuf(value)); - case OptName::SNDTIMEO: - return Translate(socket->SetSndTimeo(value)); - case OptName::RCVTIMEO: - return Translate(socket->SetRcvTimeo(value)); - case OptName::NOSIGPIPE: + return (socket->SetBroadcast(value != 0)); + case Network::OptName::SNDBUF: + return socket->SetSndBuf(value); + case Network::OptName::RCVBUF: + return socket->SetRcvBuf(value); + case Network::OptName::SNDTIMEO: + return socket->SetSndTimeo(value); + case Network::OptName::RCVTIMEO: + return socket->SetRcvTimeo(value); + case Network::OptName::NOSIGPIPE: LOG_WARNING(Service, "(STUBBED) setting NOSIGPIPE to {}", value); - return Errno::SUCCESS; + return Network::Errno::SUCCESS; default: UNIMPLEMENTED_MSG("Unimplemented optname={}", optname); - return Errno::SUCCESS; + return Network::Errno::SUCCESS; } } -Errno BSD::ShutdownImpl(s32 fd, s32 how) { +Network::Errno BSD::ShutdownImpl(s32 fd, s32 how) { if (!IsFileDescriptorValid(fd)) { - return Errno::BADF; + return Network::Errno::BADF; } if (!file_descriptors[fd]->socket) { LOG_WARNING(Service, "Uninitialized socket"); - return Errno::BADF; + return Network::Errno::BADF; } - const Network::ShutdownHow host_how = Translate(static_cast(how)); - return Translate(file_descriptors[fd]->socket->Shutdown(host_how)); + return file_descriptors[fd]->socket->Shutdown(Network::ShutdownHow(how)); } -std::pair BSD::RecvImpl(s32 fd, u32 flags, std::vector& message) { +std::pair BSD::RecvImpl(s32 fd, u32 flags, std::vector& message) { if (!IsFileDescriptorValid(fd)) { - return {-1, Errno::BADF}; + return {-1, Network::Errno::BADF}; } FileDescriptor& descriptor = *file_descriptors[fd]; @@ -873,20 +859,17 @@ std::pair BSD::RecvImpl(s32 fd, u32 flags, std::vector& message) } } - const auto [ret, bsd_errno] = Translate(descriptor.socket->Recv(flags, message)); - + const auto [ret, bsd_errno] = descriptor.socket->Recv(flags, message); // Restore original state - if ((descriptor.flags & FLAG_O_NONBLOCK) == 0) { + if ((descriptor.flags & FLAG_O_NONBLOCK) == 0) descriptor.socket->SetNonBlock(false); - } - return {ret, bsd_errno}; } -std::pair BSD::RecvFromImpl(s32 fd, u32 flags, std::vector& message, +std::pair BSD::RecvFromImpl(s32 fd, u32 flags, std::vector& message, std::vector& addr) { if (!IsFileDescriptorValid(fd)) { - return {-1, Errno::BADF}; + return {-1, Network::Errno::BADF}; } FileDescriptor& descriptor = *file_descriptors[fd]; @@ -910,7 +893,7 @@ std::pair BSD::RecvFromImpl(s32 fd, u32 flags, std::vector& mess } } - const auto [ret, bsd_errno] = Translate(descriptor.socket->RecvFrom(flags, message, p_addr_in)); + const auto [ret, bsd_errno] = descriptor.socket->RecvFrom(flags, message, p_addr_in); // Restore original state if ((descriptor.flags & FLAG_O_NONBLOCK) == 0) { @@ -922,58 +905,57 @@ std::pair BSD::RecvFromImpl(s32 fd, u32 flags, std::vector& mess addr.clear(); } else { ASSERT(addr.size() >= 16); - const SockAddrIn result = Translate(addr_in); - PutValue(addr, result); + PutValue(addr, addr_in); } } return {ret, bsd_errno}; } -std::pair BSD::SendImpl(s32 fd, u32 flags, std::span message) { +std::pair BSD::SendImpl(s32 fd, u32 flags, std::span message) { if (!IsFileDescriptorValid(fd)) { - return {-1, Errno::BADF}; + return {-1, Network::Errno::BADF}; } if (!file_descriptors[fd]->socket) { LOG_WARNING(Service, "Uninitialized socket"); - return {-1, Errno::BADF}; + return {-1, Network::Errno::BADF}; } - return Translate(file_descriptors[fd]->socket->Send(message, flags)); + return file_descriptors[fd]->socket->Send(message, flags); } -std::pair BSD::SendToImpl(s32 fd, u32 flags, std::span message, +std::pair BSD::SendToImpl(s32 fd, u32 flags, std::span message, std::span addr) { if (!IsFileDescriptorValid(fd)) { - return {-1, Errno::BADF}; + return {-1, Network::Errno::BADF}; } if (!file_descriptors[fd]->socket) { LOG_WARNING(Service, "Uninitialized socket"); - return {-1, Errno::BADF}; + return {-1, Network::Errno::BADF}; } - Network::SockAddrIn addr_in; + Network::SockAddrIn addr_in{}; Network::SockAddrIn* p_addr_in = nullptr; if (!addr.empty()) { ASSERT(addr.size() >= 16); - auto guest_addr_in = GetValue(addr); - addr_in = Translate(guest_addr_in); + auto guest_addr_in = GetValue(addr); + addr_in = guest_addr_in; p_addr_in = &addr_in; } - return Translate(file_descriptors[fd]->socket->SendTo(flags, message, p_addr_in)); + return file_descriptors[fd]->socket->SendTo(flags, message, p_addr_in); } -Errno BSD::CloseImpl(s32 fd) { +Network::Errno BSD::CloseImpl(s32 fd) { if (!IsFileDescriptorValid(fd)) { - return Errno::BADF; + return Network::Errno::BADF; } if (!file_descriptors[fd]->socket) { LOG_WARNING(Service, "Uninitialized socket"); - return Errno::BADF; + return Network::Errno::BADF; } - const Errno bsd_errno = Translate(file_descriptors[fd]->socket->Close()); - if (bsd_errno != Errno::SUCCESS) { + auto const bsd_errno = file_descriptors[fd]->socket->Close(); + if (bsd_errno != Network::Errno::SUCCESS) { return bsd_errno; } @@ -983,15 +965,15 @@ Errno BSD::CloseImpl(s32 fd) { return bsd_errno; } -std::variant BSD::DuplicateSocketImpl(s32 fd) { +std::variant BSD::DuplicateSocketImpl(s32 fd) { if (!IsFileDescriptorValid(fd)) { - return Errno::BADF; + return Network::Errno::BADF; } const s32 new_fd = FindFreeFileDescriptorHandle(); if (new_fd < 0) { LOG_ERROR(Service, "No more file descriptors available"); - return Errno::MFILE; + return Network::Errno::MFILE; } file_descriptors[new_fd] = FileDescriptor{ @@ -1034,11 +1016,11 @@ bool BSD::IsFileDescriptorValid(s32 fd) const noexcept { return true; } -void BSD::BuildErrnoResponse(HLERequestContext& ctx, Errno bsd_errno) const noexcept { +void BSD::BuildErrnoResponse(HLERequestContext& ctx, Network::Errno bsd_errno) const noexcept { IPC::ResponseBuilder rb{ctx, 4}; rb.Push(ResultSuccess); - rb.Push(bsd_errno == Errno::SUCCESS ? 0 : -1); + rb.Push(bsd_errno == Network::Errno::SUCCESS ? 0 : -1); rb.PushEnum(bsd_errno); } diff --git a/src/core/hle/service/sockets/bsd.h b/src/core/hle/service/sockets/bsd.h index 15e4a33592..6346d665d3 100644 --- a/src/core/hle/service/sockets/bsd.h +++ b/src/core/hle/service/sockets/bsd.h @@ -11,7 +11,7 @@ #include #include "common/common_types.h" -#include "common/socket_types.h" +#include "core/internal_network/socket_types.h" #include "core/hle/service/service.h" #include "core/hle/service/sockets/sockets.h" #include "network/network.h" @@ -35,8 +35,8 @@ public: // These methods are called from SSL; the first two are also called from // this class for the corresponding IPC methods. // On the real device, the SSL service makes IPC calls to this service. - std::variant DuplicateSocketImpl(s32 fd); - Errno CloseImpl(s32 fd); + std::variant DuplicateSocketImpl(s32 fd); + Network::Errno CloseImpl(s32 fd); std::optional> GetSocket(s32 fd); private: @@ -58,7 +58,7 @@ private: std::span read_buffer; std::vector write_buffer; s32 ret{}; - Errno bsd_errno{}; + Network::Errno bsd_errno{}; }; struct AcceptWork { @@ -68,7 +68,7 @@ private: s32 fd; std::vector write_buffer; s32 ret{}; - Errno bsd_errno{}; + Network::Errno bsd_errno{}; }; struct ConnectWork { @@ -77,7 +77,7 @@ private: s32 fd; std::span addr; - Errno bsd_errno{}; + Network::Errno bsd_errno{}; }; struct RecvWork { @@ -88,7 +88,7 @@ private: u32 flags; std::vector message; s32 ret{}; - Errno bsd_errno{}; + Network::Errno bsd_errno{}; }; struct RecvFromWork { @@ -100,7 +100,7 @@ private: std::vector message; std::vector addr; s32 ret{}; - Errno bsd_errno{}; + Network::Errno bsd_errno{}; }; struct SendWork { @@ -111,7 +111,7 @@ private: u32 flags; std::span message; s32 ret{}; - Errno bsd_errno{}; + Network::Errno bsd_errno{}; }; struct SendToWork { @@ -123,7 +123,7 @@ private: std::span message; std::span addr; s32 ret{}; - Errno bsd_errno{}; + Network::Errno bsd_errno{}; }; void RegisterClient(HLERequestContext& ctx); @@ -154,30 +154,30 @@ private: template void ExecuteWork(HLERequestContext& ctx, Work work); - std::pair SocketImpl(Domain domain, Type type, Protocol protocol); - std::pair PollImpl(std::vector& write_buffer, std::span read_buffer, + std::pair SocketImpl(Network::Domain domain, Network::Type type, Network::Protocol protocol); + std::pair PollImpl(std::vector& write_buffer, std::span read_buffer, s32 nfds, s32 timeout); - std::pair AcceptImpl(s32 fd, std::vector& write_buffer); - Errno BindImpl(s32 fd, std::span addr); - Errno ConnectImpl(s32 fd, std::span addr); - Errno GetPeerNameImpl(s32 fd, std::vector& write_buffer); - Errno GetSockNameImpl(s32 fd, std::vector& write_buffer); - Errno ListenImpl(s32 fd, s32 backlog); - std::pair FcntlImpl(s32 fd, FcntlCmd cmd, s32 arg); - Errno GetSockOptImpl(s32 fd, u32 level, OptName optname, std::vector& optval); - Errno SetSockOptImpl(s32 fd, u32 level, OptName optname, std::span optval); - Errno ShutdownImpl(s32 fd, s32 how); - std::pair RecvImpl(s32 fd, u32 flags, std::vector& message); - std::pair RecvFromImpl(s32 fd, u32 flags, std::vector& message, + std::pair AcceptImpl(s32 fd, std::vector& write_buffer); + Network::Errno BindImpl(s32 fd, std::span addr); + Network::Errno ConnectImpl(s32 fd, std::span addr); + Network::Errno GetPeerNameImpl(s32 fd, std::vector& write_buffer); + Network::Errno GetSockNameImpl(s32 fd, std::vector& write_buffer); + Network::Errno ListenImpl(s32 fd, s32 backlog); + std::pair FcntlImpl(s32 fd, Network::FcntlCmd cmd, s32 arg); + Network::Errno GetSockOptImpl(s32 fd, u32 level, Network::OptName optname, std::vector& optval); + Network::Errno SetSockOptImpl(s32 fd, u32 level, Network::OptName optname, std::span optval); + Network::Errno ShutdownImpl(s32 fd, s32 how); + std::pair RecvImpl(s32 fd, u32 flags, std::vector& message); + std::pair RecvFromImpl(s32 fd, u32 flags, std::vector& message, std::vector& addr); - std::pair SendImpl(s32 fd, u32 flags, std::span message); - std::pair SendToImpl(s32 fd, u32 flags, std::span message, + std::pair SendImpl(s32 fd, u32 flags, std::span message); + std::pair SendToImpl(s32 fd, u32 flags, std::span message, std::span addr); s32 FindFreeFileDescriptorHandle() noexcept; bool IsFileDescriptorValid(s32 fd) const noexcept; - void BuildErrnoResponse(HLERequestContext& ctx, Errno bsd_errno) const noexcept; + void BuildErrnoResponse(HLERequestContext& ctx, Network::Errno bsd_errno) const noexcept; static inline std::array, MAX_FD> file_descriptors{}; diff --git a/src/core/hle/service/sockets/sfdnsres.cpp b/src/core/hle/service/sockets/sfdnsres.cpp index 9e71be3547..67c7a2d710 100644 --- a/src/core/hle/service/sockets/sfdnsres.cpp +++ b/src/core/hle/service/sockets/sfdnsres.cpp @@ -102,39 +102,39 @@ static bool IsBlockedHost(const std::string& host) { [&host](const std::string& domain) { return host.find(domain) != std::string::npos; }); } -static NetDbError GetAddrInfoErrorToNetDbError(GetAddrInfoError result) { +static NetDbError GetAddrInfoErrorToNetDbError(Network::GetAddrInfoError result) { // These combinations have been verified on console (but are not // exhaustive). switch (result) { - case GetAddrInfoError::SUCCESS: + case Network::GetAddrInfoError::SUCCESS: return NetDbError::Success; - case GetAddrInfoError::AGAIN: + case Network::GetAddrInfoError::AGAIN: return NetDbError::TryAgain; - case GetAddrInfoError::NODATA: + case Network::GetAddrInfoError::NODATA: return NetDbError::HostNotFound; - case GetAddrInfoError::SERVICE: + case Network::GetAddrInfoError::SERVICE: return NetDbError::Success; default: return NetDbError::HostNotFound; } } -static Errno GetAddrInfoErrorToErrno(GetAddrInfoError result) { +static Network::Errno GetAddrInfoErrorToErrno(Network::GetAddrInfoError result) { // These combinations have been verified on console (but are not // exhaustive). switch (result) { - case GetAddrInfoError::SUCCESS: + case Network::GetAddrInfoError::SUCCESS: // Note: Sometimes a successful lookup sets errno to EADDRNOTAVAIL for // some reason, but that doesn't seem useful to implement. - return Errno::SUCCESS; - case GetAddrInfoError::AGAIN: - return Errno::SUCCESS; - case GetAddrInfoError::NODATA: - return Errno::SUCCESS; - case GetAddrInfoError::SERVICE: - return Errno::INVAL; + return Network::Errno::SUCCESS; + case Network::GetAddrInfoError::AGAIN: + return Network::Errno::SUCCESS; + case Network::GetAddrInfoError::NODATA: + return Network::Errno::SUCCESS; + case Network::GetAddrInfoError::SERVICE: + return Network::Errno::INVAL; default: - return Errno::SUCCESS; + return Network::Errno::SUCCESS; } } @@ -155,9 +155,7 @@ static void AppendNulTerminated(std::vector& vec, std::string_view str) { // host's gethostbyname, because it simplifies portability: e.g., getaddrinfo // behaves the same on Unix and Windows, unlike gethostbyname where Windows // doesn't implement h_errno. -static std::vector SerializeAddrInfoAsHostEnt(const std::vector& vec, - std::string_view host) { - +static std::vector SerializeAddrInfoAsHostEnt(std::span vec, std::string_view host) { std::vector data; // h_name: use the input hostname (append nul-terminated) AppendNulTerminated(data, host); @@ -165,12 +163,12 @@ static std::vector SerializeAddrInfoAsHostEnt(const std::vector(data, 0); // count of h_aliases // (If the count were nonzero, the aliases would be appended as nul-terminated here.) - Append(data, static_cast(Domain::INET)); // h_addrtype + Append(data, u16(Network::Domain::INET)); // h_addrtype Append(data, sizeof(Network::IPv4Address)); // h_length // h_addr_list: size_t count = vec.size(); ASSERT(count <= UINT32_MAX); - Append(data, static_cast(count)); + Append(data, u32(count)); for (const Network::AddrInfo& addrinfo : vec) { // On the Switch, this is passed through htonl despite already being // big-endian, so it ends up as little-endian. @@ -182,7 +180,7 @@ static std::vector SerializeAddrInfoAsHostEnt(const std::vector GetHostByNameRequestImpl(HLERequestContext& ctx) { +static std::pair GetHostByNameRequestImpl(HLERequestContext& ctx) { struct InputParameters { u8 use_nsd_resolve; u32 cancel_handle; @@ -205,7 +203,7 @@ static std::pair GetHostByNameRequestImpl(HLERequestConte // Prevent resolution of Nintendo servers if (IsBlockedHost(host)) { LOG_WARNING(Network, "Resolution of hostname {} requested, returning EAI_AGAIN", host); - return {0, GetAddrInfoError::AGAIN}; + return {0, Network::GetAddrInfoError::AGAIN}; } auto res_v = Network::GetAddressInfo(host, /*service*/ std::nullopt); @@ -213,10 +211,10 @@ static std::pair GetHostByNameRequestImpl(HLERequestConte const std::vector data = SerializeAddrInfoAsHostEnt(*res, host); const u32 data_size = u32(data.size()); ctx.WriteBuffer(data, 0); - return {data_size, GetAddrInfoError::SUCCESS}; + return {data_size, Network::GetAddrInfoError::SUCCESS}; } auto* err = std::get_if(&res_v); - return {0, Translate(*err)}; + return {0, *err}; } void SFDNSRES::GetHostByNameRequest(HLERequestContext& ctx) { @@ -224,7 +222,7 @@ void SFDNSRES::GetHostByNameRequest(HLERequestContext& ctx) { struct OutputParameters { NetDbError netdb_error; - Errno bsd_errno; + Network::Errno bsd_errno; u32 data_size; }; static_assert(sizeof(OutputParameters) == 0xc); @@ -244,7 +242,7 @@ void SFDNSRES::GetHostByNameRequestWithOptions(HLERequestContext& ctx) { struct OutputParameters { u32 data_size; NetDbError netdb_error; - Errno bsd_errno; + Network::Errno bsd_errno; }; static_assert(sizeof(OutputParameters) == 0xc); @@ -257,8 +255,7 @@ void SFDNSRES::GetHostByNameRequestWithOptions(HLERequestContext& ctx) { }); } -static std::vector SerializeAddrInfo(const std::vector& vec, - std::string_view host) { +static std::vector SerializeAddrInfo(std::span vec, std::string_view host) { // Adapted from // https://github.com/switchbrew/libnx/blob/c5a9a909a91657a9818a3b7e18c9b91ff0cbb6e3/nx/source/runtime/resolver.c#L190 std::vector data; @@ -267,14 +264,14 @@ static std::vector SerializeAddrInfo(const std::vector& v // serialized addrinfo: Append(data, 0xBEEFCAFE); // magic Append(data, 0); // ai_flags - Append(data, static_cast(Translate(addrinfo.family))); // ai_family - Append(data, static_cast(Translate(addrinfo.socket_type))); // ai_socktype - Append(data, static_cast(Translate(addrinfo.protocol))); // ai_protocol + Append(data, u32(addrinfo.family)); // ai_family + Append(data, u32(addrinfo.socket_type)); // ai_socktype + Append(data, u32(addrinfo.protocol)); // ai_protocol Append(data, 16); // ai_addrlen // ^ *not* sizeof(SerializedSockAddrIn), not that it matters since they're the same size // ai_addr: - Append(data, static_cast(Translate(addrinfo.addr.family))); // sin_family + Append(data, u16(addrinfo.addr.family)); // sin_family // On the Switch, the following fields are passed through htonl despite // already being big-endian, so they end up as little-endian. Append(data, addrinfo.addr.portno); // sin_port @@ -296,7 +293,7 @@ static std::vector SerializeAddrInfo(const std::vector& v return data; } -static std::pair GetAddrInfoRequestImpl(HLERequestContext& ctx) { +static std::pair GetAddrInfoRequestImpl(HLERequestContext& ctx) { struct InputParameters { u8 use_nsd_resolve; u32 cancel_handle; @@ -321,7 +318,7 @@ static std::pair GetAddrInfoRequestImpl(HLERequestContext // Prevent resolution of Nintendo servers if (IsBlockedHost(host)) { LOG_WARNING(Network, "Resolution of hostname {} requested, returning EAI_AGAIN", host); - return {0, GetAddrInfoError::AGAIN}; + return {0, Network::GetAddrInfoError::AGAIN}; } std::optional service = std::nullopt; @@ -337,18 +334,18 @@ static std::pair GetAddrInfoRequestImpl(HLERequestContext const std::vector data = SerializeAddrInfo(*res, host); const u32 data_size = u32(data.size()); ctx.WriteBuffer(data, 0); - return {data_size, GetAddrInfoError::SUCCESS}; + return {data_size, Network::GetAddrInfoError::SUCCESS}; } auto* err = std::get_if(&res_v); - return {0, Translate(*err)}; + return {0, *err}; } void SFDNSRES::GetAddrInfoRequest(HLERequestContext& ctx) { auto [data_size, emu_gai_err] = GetAddrInfoRequestImpl(ctx); struct OutputParameters { - Errno bsd_errno; - GetAddrInfoError gai_error; + Network::Errno bsd_errno; + Network::GetAddrInfoError gai_error; u32 data_size; }; static_assert(sizeof(OutputParameters) == 0xc); @@ -364,7 +361,7 @@ void SFDNSRES::GetAddrInfoRequest(HLERequestContext& ctx) { void SFDNSRES::GetGaiStringErrorRequest(HLERequestContext& ctx) { struct InputParameters { - GetAddrInfoError gai_errno; + Network::GetAddrInfoError gai_errno; }; IPC::RequestParser rp{ctx}; auto input = rp.PopRaw(); @@ -382,9 +379,9 @@ void SFDNSRES::GetAddrInfoRequestWithOptions(HLERequestContext& ctx) { struct OutputParameters { u32 data_size; - GetAddrInfoError gai_error; + Network::GetAddrInfoError gai_error; NetDbError netdb_error; - Errno bsd_errno; + Network::Errno bsd_errno; }; static_assert(sizeof(OutputParameters) == 0x10); diff --git a/src/core/hle/service/sockets/sockets.h b/src/core/hle/service/sockets/sockets.h index 2837ce71ea..af8b80375e 100644 --- a/src/core/hle/service/sockets/sockets.h +++ b/src/core/hle/service/sockets/sockets.h @@ -8,6 +8,7 @@ #include "common/common_funcs.h" #include "common/common_types.h" +#include "core/internal_network/socket_types.h" namespace Core { class System; @@ -15,242 +16,6 @@ class System; namespace Service::Sockets { -enum class Errno : u32 { - SUCCESS = 0, - BADF = 9, - AGAIN = 11, - INVAL = 22, - MFILE = 24, - PIPE = 32, - MSGSIZE = 90, - CONNABORTED = 103, - CONNRESET = 104, - NOTCONN = 107, - TIMEDOUT = 110, - CONNREFUSED = 111, - INPROGRESS = 115, - ISCONN = 106, -}; - -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, - INET = 2, -}; - -enum class Type : u32 { - Unspecified = 0, - STREAM = 1, - DGRAM = 2, - RAW = 3, - 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, -}; - -struct SockAddrIn { - u8 len; - u8 family; - u16 portno; - std::array ip; - std::array 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; - PollEvents events; - PollEvents revents; -}; - -struct Linger { - u32 onoff; - u32 linger; -}; - void LoopProcess(Core::System& system); } // namespace Service::Sockets diff --git a/src/core/hle/service/sockets/sockets_translate.cpp b/src/core/hle/service/sockets/sockets_translate.cpp index 46ef0a89cb..c62ed307fd 100644 --- a/src/core/hle/service/sockets/sockets_translate.cpp +++ b/src/core/hle/service/sockets/sockets_translate.cpp @@ -15,388 +15,42 @@ namespace Service::Sockets { -Errno Translate(Network::Errno value) { - switch (value) { - case Network::Errno::SUCCESS: - return Errno::SUCCESS; - case Network::Errno::BADF: - return Errno::BADF; - case Network::Errno::AGAIN: - return Errno::AGAIN; - case Network::Errno::INVAL: - return Errno::INVAL; - case Network::Errno::MFILE: - return Errno::MFILE; - case Network::Errno::PIPE: - return Errno::PIPE; - case Network::Errno::CONNREFUSED: - return Errno::CONNREFUSED; - case Network::Errno::NOTCONN: - return Errno::NOTCONN; - case Network::Errno::TIMEDOUT: - return Errno::TIMEDOUT; - case Network::Errno::CONNABORTED: - return Errno::CONNABORTED; - case Network::Errno::CONNRESET: - return Errno::CONNRESET; - case Network::Errno::INPROGRESS: - return Errno::INPROGRESS; - case Network::Errno::ISCONN: - return Errno::ISCONN; - default: - UNIMPLEMENTED_MSG("Unimplemented errno={}", value); - return Errno::SUCCESS; - } -} - -std::pair Translate(std::pair value) { - return {value.first, Translate(value.second)}; -} - -GetAddrInfoError Translate(Network::GetAddrInfoError error) { - switch (error) { - case Network::GetAddrInfoError::SUCCESS: - return GetAddrInfoError::SUCCESS; - case Network::GetAddrInfoError::ADDRFAMILY: - return GetAddrInfoError::ADDRFAMILY; - case Network::GetAddrInfoError::AGAIN: - return GetAddrInfoError::AGAIN; - case Network::GetAddrInfoError::BADFLAGS: - return GetAddrInfoError::BADFLAGS; - case Network::GetAddrInfoError::FAIL: - return GetAddrInfoError::FAIL; - case Network::GetAddrInfoError::FAMILY: - return GetAddrInfoError::FAMILY; - case Network::GetAddrInfoError::MEMORY: - return GetAddrInfoError::MEMORY; - case Network::GetAddrInfoError::NODATA: - return GetAddrInfoError::NODATA; - case Network::GetAddrInfoError::NONAME: - return GetAddrInfoError::NONAME; - case Network::GetAddrInfoError::SERVICE: - return GetAddrInfoError::SERVICE; - case Network::GetAddrInfoError::SOCKTYPE: - return GetAddrInfoError::SOCKTYPE; - case Network::GetAddrInfoError::SYSTEM: - return GetAddrInfoError::SYSTEM; - case Network::GetAddrInfoError::BADHINTS: - return GetAddrInfoError::BADHINTS; - case Network::GetAddrInfoError::PROTOCOL: - return GetAddrInfoError::PROTOCOL; - case Network::GetAddrInfoError::OVERFLOW_: - return GetAddrInfoError::OVERFLOW_; - case Network::GetAddrInfoError::OTHER: - return GetAddrInfoError::OTHER; - default: - UNIMPLEMENTED_MSG("Unimplemented GetAddrInfoError={}", error); - return GetAddrInfoError::OTHER; - } -} - -const char* Translate(GetAddrInfoError error) { +const char* Translate(Network::GetAddrInfoError error) { // https://android.googlesource.com/platform/bionic/+/085543106/libc/dns/net/getaddrinfo.c#254 switch (error) { - case GetAddrInfoError::SUCCESS: + case Network::GetAddrInfoError::SUCCESS: return "Success"; - case GetAddrInfoError::ADDRFAMILY: + case Network::GetAddrInfoError::ADDRFAMILY: return "Address family for hostname not supported"; - case GetAddrInfoError::AGAIN: + case Network::GetAddrInfoError::AGAIN: return "Temporary failure in name resolution"; - case GetAddrInfoError::BADFLAGS: + case Network::GetAddrInfoError::BADFLAGS: return "Invalid value for ai_flags"; - case GetAddrInfoError::FAIL: + case Network::GetAddrInfoError::FAIL: return "Non-recoverable failure in name resolution"; - case GetAddrInfoError::FAMILY: + case Network::GetAddrInfoError::FAMILY: return "ai_family not supported"; - case GetAddrInfoError::MEMORY: + case Network::GetAddrInfoError::MEMORY: return "Memory allocation failure"; - case GetAddrInfoError::NODATA: + case Network::GetAddrInfoError::NODATA: return "No address associated with hostname"; - case GetAddrInfoError::NONAME: + case Network::GetAddrInfoError::NONAME: return "hostname nor servname provided, or not known"; - case GetAddrInfoError::SERVICE: + case Network::GetAddrInfoError::SERVICE: return "servname not supported for ai_socktype"; - case GetAddrInfoError::SOCKTYPE: + case Network::GetAddrInfoError::SOCKTYPE: return "ai_socktype not supported"; - case GetAddrInfoError::SYSTEM: + case Network::GetAddrInfoError::SYSTEM: return "System error returned in errno"; - case GetAddrInfoError::BADHINTS: + case Network::GetAddrInfoError::BADHINTS: return "Invalid value for hints"; - case GetAddrInfoError::PROTOCOL: + case Network::GetAddrInfoError::PROTOCOL: return "Resolved protocol is unknown"; - case GetAddrInfoError::OVERFLOW_: + case Network::GetAddrInfoError::OVERFLOW_: return "Argument buffer overflow"; default: return "Unknown error"; } } -Network::Domain Translate(Domain domain) { - switch (domain) { - case Domain::Unspecified: - return Network::Domain::Unspecified; - case Domain::INET: - return Network::Domain::INET; - default: - UNIMPLEMENTED_MSG("Unimplemented domain={}", domain); - return {}; - } -} - -Domain Translate(Network::Domain domain) { - switch (domain) { - case Network::Domain::Unspecified: - return Domain::Unspecified; - case Network::Domain::INET: - return Domain::INET; - default: - UNIMPLEMENTED_MSG("Unimplemented domain={}", domain); - return {}; - } -} - -Network::Type Translate(Type type) { - switch (type) { - case Type::Unspecified: - return Network::Type::Unspecified; - case Type::STREAM: - return Network::Type::STREAM; - case Type::DGRAM: - return Network::Type::DGRAM; - case Type::RAW: - return Network::Type::RAW; - case Type::SEQPACKET: - return Network::Type::SEQPACKET; - default: - UNIMPLEMENTED_MSG("Unimplemented type={}", type); - return Network::Type{}; - } -} - -Type Translate(Network::Type type) { - switch (type) { - case Network::Type::Unspecified: return Type::Unspecified; - case Network::Type::STREAM: return Type::STREAM; - case Network::Type::DGRAM: return Type::DGRAM; - case Network::Type::RAW: return Type::RAW; - case Network::Type::SEQPACKET: return Type::SEQPACKET; - default: - UNIMPLEMENTED_MSG("Unimplemented type={}", type); - return Type{}; - } -} - -#define NETWORK_PROTOCOL_TRANSLATE_LIST \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(IP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(ICMP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(TCP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(UDP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(IPV6) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(RAW) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(IGMP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(GGP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(IPV4) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(ST) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(EGP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(PIGP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(RCCMON) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(NVPII) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(PUP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(ARGUS) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(EMCON) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(XNET) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(CHAOS) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(MUX) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(MEAS) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(HMP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(PRM) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(IDP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(TRUNK1) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(TRUNK2) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(LEAF1) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(LEAF2) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(RDP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(IRTP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(TP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(BLT) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(NSP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(INP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(DCCP) \ - /*NETWORK_PROTOCOL_TRANSLATE_ELEM(3PC)*/ \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(IDPR) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(XTP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(DDP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(CMTP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(TPXX) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(IL) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(SDRP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(ROUTING) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(FRAGMENT) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(IDRP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(RSVP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(GRE) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(MHRP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(BHA) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(ESP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(AH) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(INLSP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(SWIPE) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(NHRP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(MOBILE) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(TLSP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(SKIP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(ICMPV6) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(NONE) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(DSTOPTS) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(AHIP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(CFTP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(HELLO) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(SATEXPAK) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(KRYPTOLAN) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(RVD) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(IPPC) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(ADFS) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(SATMON) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(VISA) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(IPCV) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(CPNX) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(CPHB) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(WSN) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(PVP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(BRSATMON) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(ND) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(WBMON) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(WBEXPAK) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(EON) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(VMTP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(SVMTP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(VINES) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(TTP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(IGP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(DGP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(TCF) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(IGRP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(OSPFIGP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(SRPC) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(LARP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(MTP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(AX25) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(IPEIP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(MICP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(SCCSP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(ETHERIP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(ENCAP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(APES) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(GMTP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(IPCOMP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(SCTP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(MH) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(UDPLITE) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(HIP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(SHIM6) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(PIM) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(CARP) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(PGM) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(MPLS) \ - NETWORK_PROTOCOL_TRANSLATE_ELEM(PFSYNC) -[[nodiscard]] Network::Protocol Translate(Protocol protocol) { - switch (protocol) { -#define NETWORK_PROTOCOL_TRANSLATE_ELEM(name) case Protocol::name: return Network::Protocol::name; - NETWORK_PROTOCOL_TRANSLATE_LIST -#undef NETWORK_PROTOCOL_TRANSLATE_ELEM - default: - UNIMPLEMENTED_MSG("Unimplemented protocol={}", protocol); - return {}; - } -} -[[nodiscard]] Protocol Translate(Network::Protocol protocol) { - switch (protocol) { -#define NETWORK_PROTOCOL_TRANSLATE_ELEM(name) case Network::Protocol::name: return Protocol::name; - NETWORK_PROTOCOL_TRANSLATE_LIST -#undef NETWORK_PROTOCOL_TRANSLATE_ELEM - default: - UNIMPLEMENTED_MSG("Unimplemented protocol={}", protocol); - return {}; - } -} -#undef NETWORK_PROTOCOL_TRANSLATE_LIST - -Network::PollEvents Translate(PollEvents flags) { - Network::PollEvents result{}; - const auto translate = [&result, &flags](PollEvents from, Network::PollEvents to) { - if (True(flags & from)) { - flags &= ~from; - result |= to; - } - }; - translate(PollEvents::In, Network::PollEvents::In); - translate(PollEvents::Pri, Network::PollEvents::Pri); - translate(PollEvents::Out, Network::PollEvents::Out); - translate(PollEvents::Err, Network::PollEvents::Err); - translate(PollEvents::Hup, Network::PollEvents::Hup); - translate(PollEvents::Nval, Network::PollEvents::Nval); - translate(PollEvents::RdNorm, Network::PollEvents::RdNorm); - translate(PollEvents::RdBand, Network::PollEvents::RdBand); - translate(PollEvents::WrBand, Network::PollEvents::WrBand); - - UNIMPLEMENTED_IF_MSG((u16)flags != 0, "Unimplemented flags={}", (u16)flags); - return result; -} - -PollEvents Translate(Network::PollEvents flags) { - PollEvents result{}; - const auto translate = [&result, &flags](Network::PollEvents from, PollEvents to) { - if (True(flags & from)) { - flags &= ~from; - result |= to; - } - }; - - translate(Network::PollEvents::In, PollEvents::In); - translate(Network::PollEvents::Pri, PollEvents::Pri); - translate(Network::PollEvents::Out, PollEvents::Out); - translate(Network::PollEvents::Err, PollEvents::Err); - translate(Network::PollEvents::Hup, PollEvents::Hup); - translate(Network::PollEvents::Nval, PollEvents::Nval); - translate(Network::PollEvents::RdNorm, PollEvents::RdNorm); - translate(Network::PollEvents::RdBand, PollEvents::RdBand); - translate(Network::PollEvents::WrBand, PollEvents::WrBand); - - UNIMPLEMENTED_IF_MSG((u16)flags != 0, "Unimplemented flags={}", (u16)flags); - return result; -} - -Network::SockAddrIn Translate(SockAddrIn value) { - // All lengths are valid, from [0 upto 256] - return { - .family = Translate(Domain(value.family)), - .ip = value.ip, - .portno = static_cast(value.portno >> 8 | value.portno << 8), - }; -} - -SockAddrIn Translate(Network::SockAddrIn value) { - return { - .len = 16, - .family = static_cast(Translate(value.family)), - .portno = static_cast(value.portno >> 8 | value.portno << 8), - .ip = value.ip, - .zeroes = {}, - }; -} - -Network::ShutdownHow Translate(ShutdownHow how) { - switch (how) { - case ShutdownHow::RD: - return Network::ShutdownHow::RD; - case ShutdownHow::WR: - return Network::ShutdownHow::WR; - case ShutdownHow::RDWR: - return Network::ShutdownHow::RDWR; - default: - UNIMPLEMENTED_MSG("Unimplemented how={}", how); - return {}; - } -} - } // namespace Service::Sockets diff --git a/src/core/hle/service/sockets/sockets_translate.h b/src/core/hle/service/sockets/sockets_translate.h index bd6721fd3e..d6e8a116c3 100644 --- a/src/core/hle/service/sockets/sockets_translate.h +++ b/src/core/hle/service/sockets/sockets_translate.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -11,49 +14,7 @@ namespace Service::Sockets { -/// Translate abstract errno to guest errno -Errno Translate(Network::Errno value); - -/// Translate abstract return value errno pair to guest return value errno pair -std::pair Translate(std::pair value); - -/// Translate abstract getaddrinfo error to guest getaddrinfo error -GetAddrInfoError Translate(Network::GetAddrInfoError value); - /// Translate guest error to string -const char* Translate(GetAddrInfoError value); - -/// Translate guest domain to abstract domain -Network::Domain Translate(Domain domain); - -/// Translate abstract domain to guest domain -Domain Translate(Network::Domain domain); - -/// Translate guest type to abstract type -Network::Type Translate(Type type); - -/// Translate abstract type to guest type -Type Translate(Network::Type type); - -/// Translate guest protocol to abstract protocol -Network::Protocol Translate(Protocol protocol); - -/// Translate abstract protocol to guest protocol -Protocol Translate(Network::Protocol protocol); - -/// Translate guest poll event flags to abstract poll event flags -Network::PollEvents Translate(PollEvents flags); - -/// Translate abstract poll event flags to guest poll event flags -PollEvents Translate(Network::PollEvents flags); - -/// Translate guest socket address structure to abstract socket address structure -Network::SockAddrIn Translate(SockAddrIn value); - -/// Translate abstract socket address structure to guest socket address structure -SockAddrIn Translate(Network::SockAddrIn value); - -/// Translate guest shutdown mode to abstract shutdown mode -Network::ShutdownHow Translate(ShutdownHow how); +const char* Translate(Network::GetAddrInfoError value); } // namespace Service::Sockets diff --git a/src/core/hle/service/ssl/ssl.cpp b/src/core/hle/service/ssl/ssl.cpp index f826993920..87e438b81c 100644 --- a/src/core/hle/service/ssl/ssl.cpp +++ b/src/core/hle/service/ssl/ssl.cpp @@ -132,7 +132,7 @@ public: auto bsd = system.ServiceManager().GetService("bsd:u"); if (bsd) { auto err = bsd->CloseImpl(fd); - if (err != Service::Sockets::Errno::SUCCESS) { + if (err != Network::Errno::SUCCESS) { LOG_ERROR(Service_SSL, "Failed to close duplicated socket: {}", err); } } diff --git a/src/core/internal_network/emu_net_state.h b/src/core/internal_network/emu_net_state.h index d16f1830a6..7b15feb9f1 100644 --- a/src/core/internal_network/emu_net_state.h +++ b/src/core/internal_network/emu_net_state.h @@ -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 -#include #include +#include "core/internal_network/socket_types.h" namespace Network { diff --git a/src/core/internal_network/network.cpp b/src/core/internal_network/network.cpp index 75c7bc46aa..44557538fe 100644 --- a/src/core/internal_network/network.cpp +++ b/src/core/internal_network/network.cpp @@ -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(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 get fucked #define NETWORK_PROTOCOL_TRANSLATE_LIST \ @@ -619,68 +725,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(~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); @@ -752,8 +853,7 @@ std::variant, 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(current->ai_addr), - current->ai_addrlen); + out.addr = TranslateToSockAddrIn(*reinterpret_cast(current->ai_addr), current->ai_addrlen); if (current->ai_canonname != nullptr) { out.canon_name = current->ai_canonname; } @@ -762,11 +862,11 @@ std::variant, GetAddrInfoError> GetAddressInfo( return ret; } -std::pair Poll(std::vector& pollfds, s32 timeout) { +std::pair Poll(std::span pollfds, s32 timeout) { const size_t num = pollfds.size(); std::vector 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); @@ -882,7 +982,7 @@ std::pair 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; @@ -891,27 +991,27 @@ Errno Socket::Connect(SockAddrIn addr_in) { return GetAndLogLastError(); } -std::pair Socket::GetPeerName() { +std::pair Socket::GetPeerName() { sockaddr_in addr; socklen_t addrlen = sizeof(addr); if (getpeername(fd, reinterpret_cast(&addr), &addrlen) == SOCKET_ERROR) { - return {SockAddrIn{}, GetAndLogLastError()}; + return {Network::SockAddrIn{}, GetAndLogLastError()}; } return {TranslateToSockAddrIn(addr, addrlen), Errno::SUCCESS}; } -std::pair Socket::GetSockName() { +std::pair Socket::GetSockName() { sockaddr_in addr; socklen_t addrlen = sizeof(addr); if (getsockname(fd, reinterpret_cast(&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; @@ -964,7 +1064,7 @@ std::pair Socket::Recv(int flags, std::span message) { return {-1, GetAndLogLastError()}; } -std::pair Socket::RecvFrom(int flags, std::span message, SockAddrIn* addr) { +std::pair Socket::RecvFrom(int flags, std::span message, Network::SockAddrIn* addr) { ASSERT(flags == 0); ASSERT(message.size() < static_cast((std::numeric_limits::max)())); @@ -1003,7 +1103,7 @@ std::pair Socket::Send(std::span message, int flags) { } std::pair Socket::SendTo(u32 flags, std::span message, - const SockAddrIn* addr) { + const Network::SockAddrIn* addr) { ASSERT(flags == 0); const sockaddr* to = nullptr; diff --git a/src/core/internal_network/network.h b/src/core/internal_network/network.h index 2c9ae523c5..7698644b86 100644 --- a/src/core/internal_network/network.h +++ b/src/core/internal_network/network.h @@ -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 @@ -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 { diff --git a/src/core/internal_network/network_interface.cpp b/src/core/internal_network/network_interface.cpp index f68d4617eb..0cbf62155c 100644 --- a/src/core/internal_network/network_interface.cpp +++ b/src/core/internal_network/network_interface.cpp @@ -46,7 +46,7 @@ namespace Network { #ifdef _WIN32 -std::vector GetAvailableNetworkInterfaces() { +std::vector GetAvailableNetworkInterfaces() { ULONG buf_size = 0; if (GetAdaptersAddresses( @@ -66,7 +66,7 @@ std::vector GetAvailableNetworkInterfaces() { return {}; } - std::vector result; + std::vector result; for (auto* a = addrs; a; a = a->Next) { @@ -89,7 +89,7 @@ std::vector GetAvailableNetworkInterfaces() { gw = reinterpret_cast(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 GetAvailableNetworkInterfaces() { #else -std::vector GetAvailableNetworkInterfaces() { +std::vector GetAvailableNetworkInterfaces() { #if defined(__ANDROID__) || defined(__linux__) struct ifaddrs* ifaddr = nullptr; if (getifaddrs(&ifaddr) != 0) { @@ -135,7 +135,7 @@ std::vector GetAvailableNetworkInterfaces() { LOG_WARNING(Network, "\"/proc/net/route\" not found - using gateway 0"); } #endif - std::vector ifaces; + std::vector 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 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(*ifa->ifa_addr).sin_addr, .subnet_mask = std::bit_cast(*ifa->ifa_netmask).sin_addr, @@ -159,7 +159,7 @@ std::vector GetAvailableNetworkInterfaces() { freeifaddrs(ifaddr); return ifaces; #elif defined(__FreeBSD__) - std::vector ifaces; + std::vector 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 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(p); @@ -220,7 +220,7 @@ std::vector GetAvailableNetworkInterfaces() { #endif // _WIN32 -std::optional GetSelectedNetworkInterface() { +std::optional GetSelectedNetworkInterface() { auto const& sel_if = Settings::values.network_interface.GetValue(); if (auto const ifaces = Network::GetAvailableNetworkInterfaces(); ifaces.size() > 0) { if (sel_if.empty()) diff --git a/src/core/internal_network/socket_proxy.cpp b/src/core/internal_network/socket_proxy.cpp index 744765bfcc..8ebbead4f7 100644 --- a/src/core/internal_network/socket_proxy.cpp +++ b/src/core/internal_network/socket_proxy.cpp @@ -65,22 +65,22 @@ std::pair 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 ProxySocket::GetPeerName() { +std::pair ProxySocket::GetPeerName() { LOG_WARNING(Network, "(STUBBED) called"); - return {SockAddrIn{}, Errno::SUCCESS}; + return {Network::SockAddrIn{}, Errno::SUCCESS}; } -std::pair ProxySocket::GetSockName() { +std::pair 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 ProxySocket::Recv(int flags, std::span message) { return {static_cast(0), Errno::SUCCESS}; } -std::pair ProxySocket::RecvFrom(int flags, std::span message, SockAddrIn* addr) { +std::pair ProxySocket::RecvFrom(int flags, std::span message, Network::SockAddrIn* addr) { ASSERT(flags == 0); ASSERT(message.size() < static_cast((std::numeric_limits::max)())); @@ -143,13 +143,15 @@ std::pair ProxySocket::RecvFrom(int flags, std::span message, So } } -std::pair ProxySocket::ReceivePacket(int flags, std::span message, SockAddrIn* addr, +std::pair ProxySocket::ReceivePacket(int flags, std::span 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 ProxySocket::SendTo(u32 flags, std::span message, - const SockAddrIn* addr) { + const Network::SockAddrIn* addr) { ASSERT(flags == 0); if (!is_bound) { diff --git a/src/core/internal_network/socket_proxy.h b/src/core/internal_network/socket_proxy.h index caf5d1ee23..8ba8ffbdd9 100644 --- a/src/core/internal_network/socket_proxy.h +++ b/src/core/internal_network/socket_proxy.h @@ -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 Accept() override; - Errno Connect(SockAddrIn addr_in) override; + Errno Connect(Network::SockAddrIn addr_in) override; - std::pair GetPeerName() override; + std::pair GetPeerName() override; - std::pair GetSockName() override; + std::pair 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 Recv(int flags, std::span message) override; - std::pair RecvFrom(int flags, std::span message, SockAddrIn* addr) override; + std::pair RecvFrom(int flags, std::span message, Network::SockAddrIn* addr) override; - std::pair ReceivePacket(int flags, std::span message, SockAddrIn* addr, + std::pair ReceivePacket(int flags, std::span message, Network::SockAddrIn* addr, std::size_t max_length); std::pair Send(std::span message, int flags) override; @@ -53,7 +53,7 @@ public: void SendPacket(ProxyPacket& packet); std::pair SendTo(u32 flags, std::span 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 received_packets; Protocol protocol; diff --git a/src/core/internal_network/socket_types.h b/src/core/internal_network/socket_types.h new file mode 100644 index 0000000000..bc0be4300e --- /dev/null +++ b/src/core/internal_network/socket_types.h @@ -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 +#include + +#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; + +struct SockAddrIn { + u8 len; + u8 family; + u16 portno; + IPv4Address ip; + std::array 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 canon_name; +}; + +} // namespace Network diff --git a/src/core/internal_network/sockets.h b/src/core/internal_network/sockets.h index 0b751b6622..abea299bcd 100644 --- a/src/core/internal_network/sockets.h +++ b/src/core/internal_network/sockets.h @@ -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 socket; - SockAddrIn sockaddr_in; + Network::SockAddrIn sockaddr_in; }; SocketBase() = default; @@ -46,13 +46,13 @@ public: virtual std::pair Accept() = 0; - virtual Errno Connect(SockAddrIn addr_in) = 0; + virtual Errno Connect(Network::SockAddrIn addr_in) = 0; - virtual std::pair GetPeerName() = 0; + virtual std::pair GetPeerName() = 0; - virtual std::pair GetSockName() = 0; + virtual std::pair 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 Recv(int flags, std::span message) = 0; - virtual std::pair RecvFrom(int flags, std::span message, SockAddrIn* addr) = 0; + virtual std::pair RecvFrom(int flags, std::span message, Network::SockAddrIn* addr) = 0; virtual std::pair Send(std::span message, int flags) = 0; virtual std::pair SendTo(u32 flags, std::span 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 Accept() override; - Errno Connect(SockAddrIn addr_in) override; + Errno Connect(Network::SockAddrIn addr_in) override; - std::pair GetPeerName() override; + std::pair GetPeerName() override; - std::pair GetSockName() override; + std::pair 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 Recv(int flags, std::span message) override; - std::pair RecvFrom(int flags, std::span message, SockAddrIn* addr) override; + std::pair RecvFrom(int flags, std::span message, Network::SockAddrIn* addr) override; std::pair Send(std::span message, int flags) override; std::pair SendTo(u32 flags, std::span 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 Poll(std::vector& poll_fds, s32 timeout); +std::pair Poll(std::span poll_fds, s32 timeout); } // namespace Network diff --git a/src/network/room.h b/src/network/room.h index af7a30c6f6..c37741e04c 100644 --- a/src/network/room.h +++ b/src/network/room.h @@ -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 2017 Citra Emulator Project @@ -12,7 +12,7 @@ #include #include "common/announce_multiplayer_room.h" #include "common/common_types.h" -#include "common/socket_types.h" +#include "core/internal_network/socket_types.h" #include "network/verify_user.h" namespace Network { diff --git a/src/network/room_member.cpp b/src/network/room_member.cpp index 029e103db4..43886db4da 100644 --- a/src/network/room_member.cpp +++ b/src/network/room_member.cpp @@ -10,7 +10,7 @@ #include #include "common/assert.h" #include "common/polyfill_thread.h" -#include "common/socket_types.h" +#include "core/internal_network/socket_types.h" #include "enet/enet.h" #include "network/packet.h" #include "network/room_member.h" @@ -358,19 +358,23 @@ void RoomMember::RoomMemberImpl::HandleProxyPackets(const ENetEvent* event) { // Parse the ProxyPacket from the packet u8 local_family; packet.Read(local_family); - proxy_packet.local_endpoint.family = static_cast(local_family); + proxy_packet.local_endpoint.len = 16; + proxy_packet.local_endpoint.family = u8(Network::Domain(local_family)); packet.Read(proxy_packet.local_endpoint.ip); packet.Read(proxy_packet.local_endpoint.portno); + proxy_packet.local_endpoint.zeroes = {}; u8 remote_family; packet.Read(remote_family); - proxy_packet.remote_endpoint.family = static_cast(remote_family); + proxy_packet.remote_endpoint.len = 16; + proxy_packet.remote_endpoint.family = u8(Network::Domain(remote_family)); packet.Read(proxy_packet.remote_endpoint.ip); packet.Read(proxy_packet.remote_endpoint.portno); + proxy_packet.local_endpoint.zeroes = {}; u8 protocol_type; packet.Read(protocol_type); - proxy_packet.protocol = static_cast(protocol_type); + proxy_packet.protocol = Network::Protocol(protocol_type); packet.Read(proxy_packet.broadcast); packet.Read(proxy_packet.data); diff --git a/src/network/room_member.h b/src/network/room_member.h index 8cc59adecc..ec6abf7fad 100644 --- a/src/network/room_member.h +++ b/src/network/room_member.h @@ -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 2017 Citra Emulator Project @@ -12,7 +12,7 @@ #include #include "common/announce_multiplayer_room.h" #include "common/common_types.h" -#include "common/socket_types.h" +#include "core/internal_network/socket_types.h" #include "network/room.h" namespace Network { @@ -39,8 +39,8 @@ struct LDNPacket { /// Information about the received proxy packets. struct ProxyPacket { - SockAddrIn local_endpoint; - SockAddrIn remote_endpoint; + Network::SockAddrIn local_endpoint; + Network::SockAddrIn remote_endpoint; Protocol protocol; bool broadcast; std::vector data; diff --git a/src/tests/core/internal_network/network.cpp b/src/tests/core/internal_network/network.cpp index 10ddd8b426..f9248efd7c 100644 --- a/src/tests/core/internal_network/network.cpp +++ b/src/tests/core/internal_network/network.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -16,9 +19,11 @@ TEST_CASE("Network::Errors", "[core]") { } Network::SockAddrIn addr{ + 16, Network::Domain::INET, - {127, 0, 0, 1}, 1, // hopefully nobody running this test has something listening on port 1 + {127, 0, 0, 1}, + {}, }; REQUIRE(socks[0].Connect(addr) == Network::Errno::CONNREFUSED);