Compare commits

...

56 Commits

Author SHA1 Message Date
lizzie a67f8548af fix bsd macro clash 2026-08-31 04:00:25 +00:00
lizzie a08edeeeeb fix horrid lag on hb appstore 2026-08-31 03:28:37 +00:00
lizzie a28dd7cbd7 Trigger Build 2026-08-31 03:28:15 +00:00
lizzie 370b75a8ff Trigger Build 2026-08-31 03:28:15 +00:00
lizzie f2f4649411 no 2026-08-31 03:28:15 +00:00
lizzie c34e635dbb me when evil android 2026-08-31 03:28:15 +00:00
lizzie a663bae084 fixups 2026-08-31 03:28:15 +00:00
lizzie 02634b972b fix windows wsa E_DESTADDRREQ 2026-08-31 03:28:15 +00:00
lizzie 9b1f2a5538 fucking shit 2026-08-31 03:28:15 +00:00
lizzie 38278f3ddc windows prot=0 2026-08-31 03:28:15 +00:00
lizzie 645c5fd3ee fix pings? 2026-08-31 03:28:15 +00:00
lizzie 262994cf12 fix winbloat 2026-08-31 03:28:15 +00:00
lizzie 9648242990 fractional time -W 2026-08-31 03:28:15 +00:00
lizzie 81b43a4a96 ffs windows 2026-08-31 03:28:15 +00:00
lizzie 8be5a7aa92 evil noperm 2026-08-31 03:28:15 +00:00
lizzie 20fb68aae4 fuck errrno2 2026-08-31 03:28:15 +00:00
lizzie a7b577b639 acurater errno 2026-08-31 03:28:15 +00:00
lizzie a8497ff9b4 ALL THE ERROR CODES 2026-08-31 03:28:15 +00:00
lizzie 2de73ed49f fixup errno 2026-08-31 03:28:15 +00:00
lizzie 31a54da818 min of 1sec 2026-08-31 03:28:15 +00:00
lizzie 6047e3d18f account for timeout 2026-08-31 03:28:15 +00:00
lizzie 78ee34c16d fix tcp on ssbu mod 2026-08-31 03:28:15 +00:00
lizzie 9fff29044f fallback only if it failed 2026-08-31 03:28:15 +00:00
lizzie 605060a975 implode windows 2026-08-31 03:28:15 +00:00
lizzie 68ba0841a9 better 2026-08-31 03:28:15 +00:00
lizzie 4e96d5d2a6 evil ping 2026-08-31 03:28:15 +00:00
lizzie 9641a5424e don't murder me for this change 2026-08-31 03:28:15 +00:00
lizzie fd7b578525 need the extra threads... 2026-08-31 03:28:15 +00:00
lizzie 9f025b31cb more gymnastics to give fake results? 2026-08-31 03:28:15 +00:00
lizzie 941542d437 first fake icmp impl 2026-08-31 03:28:15 +00:00
lizzie 75c98131b6 fix ldn sockets being regarded as normal socks 2026-08-31 03:28:15 +00:00
lizzie fef912f342 fx2 2026-08-31 03:28:15 +00:00
lizzie 47e17fae95 fix??? 2026-08-31 03:28:15 +00:00
lizzie 4070a80046 fix sockets 2026-08-31 03:28:15 +00:00
lizzie 458dfe18a4 struct pollfd 2026-08-31 03:28:15 +00:00
lizzie fc4a61871d fixup tests 2026-08-31 03:28:15 +00:00
lizzie 512b39e2aa fix windows screaming 2026-08-31 03:28:15 +00:00
lizzie 1cb58a6ebc musl scared of defines ooo 2026-08-31 03:28:15 +00:00
lizzie 0d5d453862 airplane mode takes priority 2026-08-31 03:28:15 +00:00
lizzie 2c5d2a42f3 uh 2026-08-31 03:28:15 +00:00
lizzie 7047ef2a43 add tcp options 2026-08-31 03:28:15 +00:00
lizzie fa0b1897d7 nuke extra threads, extra error support; use span instead of vector for poll fds 2026-08-31 03:28:15 +00:00
lizzie a328a2aed8 we love when cURL has bugs? 2026-08-31 03:28:15 +00:00
lizzie 930e20be98 add extra polling types 2026-08-31 03:28:15 +00:00
lizzie c33aceddf4 various fixes to sockopt 2026-08-31 03:28:15 +00:00
lizzie 108bdbd6ed allow configure socket level 2026-08-31 03:28:14 +00:00
lizzie b824f5382c coalesce the various sockopt 2026-08-31 03:28:14 +00:00
lizzie ed296bd7d0 honour the provided MSG flags 2026-08-31 03:28:14 +00:00
lizzie 85ffb1afaf extra fixups 2026-08-31 03:28:14 +00:00
lizzie 8d4d8d239a fixup stuffs for windows 2026-08-31 03:28:14 +00:00
lizzie 82ea59fef3 fix messages native flags 2026-08-31 03:28:14 +00:00
lizzie 615a6887df properly handle writebuffer and dont write OOB 2026-08-31 03:28:14 +00:00
lizzie 7453d50347 fixes for non BSD 2026-08-31 03:28:14 +00:00
lizzie 40b3df8f77 [net] refactor to remove uneeded abstraction layer
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2026-08-31 03:28:14 +00:00
xbzk b7f0f98519 [android] expose log filter setting (#4327)
- [x] I have read and followed the [Contribution Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/CONTRIBUTING.md#code-contributions).
- [x] I have read and followed the [AI Policy](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/AI.md)
- [x] I have read and followed the [Coding Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/Coding.md) to the best of my ability.

-------------------
Takes log filter to android and fixes qt "loads after setting, but ignore in next runs" issue

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4327
Reviewed-by: Lizzie and Samuel <lizzie@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
2026-08-31 04:22:15 +02:00
crueter 7fda6dde73 [common] Switch to boost::unordered_flat containers (#4326)
Replaces all instances of ankerl's unordered map/set with boost's
`unordered_flat_*` classes. This uses std::hash since boost::hash is
actually a lot slower.

Also adds an abstraction layer in `Common` so future changes are quicker
and easier.

Other implementation details:
- ankerl provided hash specializations for tuple and pair, so those were
  ported here
- std::erase_if doesn't work on boost, so just used the ADL'd erase_if

This should be about equal or superior performance as unordered_dense for everything except iteration.

Signed-off-by: crueter <crueter@eden-emu.dev>

- [x] I have read and followed the [Contribution Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/CONTRIBUTING.md#code-contributions).
- [x] I have read and followed the [AI Policy](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/AI.md)
- [x] I have read and followed the [Coding Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/Coding.md) to the best of my ability.

-------------------

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4326
Reviewed-by: Lizzie and Samuel <lizzie@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
2026-08-31 02:58:09 +02:00
153 changed files with 2356 additions and 2287 deletions
@@ -1,26 +0,0 @@
From b3622608433c183ba868a1dc8dd9cf285eb3b916 Mon Sep 17 00:00:00 2001
From: Dario Petrillo <dario.pk1@gmail.com>
Date: Thu, 27 Nov 2025 23:12:38 +0100
Subject: [PATCH] avoid extra memset when clearing an empty table
---
include/ankerl/unordered_dense.h | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/include/ankerl/unordered_dense.h b/include/ankerl/unordered_dense.h
index 0835342..4938212 100644
--- a/include/ankerl/unordered_dense.h
+++ b/include/ankerl/unordered_dense.h
@@ -1490,8 +1490,10 @@ class table : public std::conditional_t<is_map_v<T>, base_table_type_map<T>, bas
// modifiers //////////////////////////////////////////////////////////////
void clear() {
- m_values.clear();
- clear_buckets();
+ if (!empty()) {
+ m_values.clear();
+ clear_buckets();
+ }
}
auto insert(value_type const& value) -> std::pair<iterator, bool> {
-1
View File
@@ -540,7 +540,6 @@ add_subdirectory(externals)
# pass targets from externals # pass targets from externals
# TODO(crueter): CPMUtil Propagate func? # TODO(crueter): CPMUtil Propagate func?
find_package(enet) find_package(enet)
find_package(unordered_dense REQUIRED)
if (ARCHITECTURE_x86 OR ARCHITECTURE_x86_64) if (ARCHITECTURE_x86 OR ARCHITECTURE_x86_64)
find_package(xbyak) find_package(xbyak)
-11
View File
@@ -301,17 +301,6 @@
"repo": "eden-emu/tzdb_to_nx", "repo": "eden-emu/tzdb_to_nx",
"version": "230326" "version": "230326"
}, },
"unordered-dense": {
"bundled": true,
"find_args": "CONFIG",
"hash": "d2106f6640f6bfb81755e4b8bfb64982e46ec4a507cacdb38f940123212ccf35a20b43c70c6f01d7bfb8c246d1a16f7845d8052971949cea9def1475e3fa02c8",
"package": "unordered_dense",
"patches": [
"0001-avoid-memset-when-clearing-an-empty-table.patch"
],
"repo": "martinus/unordered_dense",
"version": "7b55cab841"
},
"vulkan-headers": { "vulkan-headers": {
"hash": "d2846ea228415772645eea4b52a9efd33e6a563043dd3de059e798be6391a8f0ca089f455ae420ff22574939ed0f48ed7c6ff3d5a9987d5231dbf3b3f89b484b", "hash": "d2846ea228415772645eea4b52a9efd33e6a563043dd3de059e798be6391a8f0ca089f455ae420ff22574939ed0f48ed7c6ff3d5a9987d5231dbf3b3f89b484b",
"min_version": "1.4.317", "min_version": "1.4.317",
+4 -5
View File
@@ -80,7 +80,6 @@ Certain other dependencies will be fetched by CPM regardless. System packages *c
* [httplib](https://github.com/yhirose/cpp-httplib) - if `ENABLE_UPDATE_CHECKER` or `ENABLE_WEB_SERVICE` are on * [httplib](https://github.com/yhirose/cpp-httplib) - if `ENABLE_UPDATE_CHECKER` or `ENABLE_WEB_SERVICE` are on
* This package is known to be broken on the AUR. * This package is known to be broken on the AUR.
* [cpp-jwt](https://github.com/arun11299/cpp-jwt) 1.4+ - if `ENABLE_WEB_SERVICE` is on * [cpp-jwt](https://github.com/arun11299/cpp-jwt) 1.4+ - if `ENABLE_WEB_SERVICE` is on
* [unordered-dense](https://github.com/martinus/unordered_dense)
On amd64: On amd64:
@@ -119,7 +118,7 @@ Now, install all deps:
sudo emerge -a \ sudo emerge -a \
app-arch/lz4 app-arch/zstd app-arch/unzip \ app-arch/lz4 app-arch/zstd app-arch/unzip \
dev-libs/libfmt dev-libs/libusb dev-libs/mcl dev-libs/sirit \ dev-libs/libfmt dev-libs/libusb dev-libs/mcl dev-libs/sirit \
dev-libs/unordered_dense dev-libs/boost dev-libs/openssl dev-libs/discord-rpc \ dev-libs/boost dev-libs/openssl dev-libs/discord-rpc \
dev-util/spirv-tools dev-util/spirv-headers dev-util/vulkan-headers \ dev-util/spirv-tools dev-util/spirv-headers dev-util/vulkan-headers \
dev-util/vulkan-utility-libraries dev-util/glslang \ dev-util/vulkan-utility-libraries dev-util/glslang \
media-gfx/renderdoc media-libs/libva media-libs/opus media-video/ffmpeg \ media-gfx/renderdoc media-libs/libva media-libs/opus media-video/ffmpeg \
@@ -260,7 +259,7 @@ brew install molten-vk
<details> <details>
<summary>FreeBSD</summary> <summary>FreeBSD</summary>
As root run: `pkg install devel/cmake sdl3 devel/boost-libs devel/catch2 devel/libfmt devel/nlohmann-json devel/ninja devel/nasm devel/autoconf devel/pkgconf devel/qt6-base devel/qt6-charts devel/simpleini net/enet multimedia/ffnvcodec-headers multimedia/ffmpeg audio/opus archivers/liblz4 lang/gcc12 graphics/glslang graphics/vulkan-utility-libraries graphics/spirv-tools www/cpp-httplib devel/unordered-dense vulkan-headers quazip-qt6` As root run: `pkg install devel/cmake sdl3 devel/boost-libs devel/catch2 devel/libfmt devel/nlohmann-json devel/ninja devel/nasm devel/autoconf devel/pkgconf devel/qt6-base devel/qt6-charts devel/simpleini net/enet multimedia/ffnvcodec-headers multimedia/ffmpeg audio/opus archivers/liblz4 lang/gcc12 graphics/glslang graphics/vulkan-utility-libraries graphics/spirv-tools www/cpp-httplib vulkan-headers quazip-qt6`
If using FreeBSD 12 or prior, use `devel/pkg-config` instead. If using FreeBSD 12 or prior, use `devel/pkg-config` instead.
@@ -294,7 +293,7 @@ pkg_add cmake nasm git boost unzip--iconv autoconf-2.72p0 bash ffmpeg glslang gm
<summary>DragonFlyBSD</summary> <summary>DragonFlyBSD</summary>
```sh ```sh
pkg install gcc14 git cmake unzip nasm autoconf bash pkgconf ffmpeg glslang gmake jq nlohmann-json enet spirv-tools sdl3 vulkan-utility-libraries vulkan-headers catch2 libfmt openssl liblz4 boost-libs cpp-httplib qt6-base qt6-charts quazip-qt6 unordered-dense libva-vdpau-driver libva-utils libva-intel-driver pkg install gcc14 git cmake unzip nasm autoconf bash pkgconf ffmpeg glslang gmake jq nlohmann-json enet spirv-tools sdl3 vulkan-utility-libraries vulkan-headers catch2 libfmt openssl liblz4 boost-libs cpp-httplib qt6-base qt6-charts quazip-qt6 libva-vdpau-driver libva-utils libva-intel-driver
``` ```
[Caveats](./Caveats.md#dragonflybsd). [Caveats](./Caveats.md#dragonflybsd).
@@ -328,7 +327,7 @@ sudo pkgin install git cmake autoconf build-essential libusb-1 nasm gcc13
```sh ```sh
BASE="git make autoconf libtool automake-wrapper jq patch" BASE="git make autoconf libtool automake-wrapper jq patch"
MINGW="qt6-base qt6-charts qt6-tools qt6-translations qt6-svg cmake toolchain clang python-pip openssl vulkan-memory-allocator vulkan-devel glslang boost fmt lz4 nlohmann-json zlib zstd enet opus libusb unordered_dense openssl SDL3" MINGW="qt6-base qt6-charts qt6-tools qt6-translations qt6-svg cmake toolchain clang python-pip openssl vulkan-memory-allocator vulkan-devel glslang boost fmt lz4 nlohmann-json zlib zstd enet opus libusb openssl SDL3"
# Either x86_64 or clang-aarch64 (Windows on ARM) # Either x86_64 or clang-aarch64 (Windows on ARM)
packages="$BASE" packages="$BASE"
for pkg in $MINGW; do for pkg in $MINGW; do
-26
View File
@@ -308,32 +308,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
``` ```
### unordered_dense
```
MIT License
Copyright (c) 2022 Martin Leitner-Ankerl
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
```
### xbyak ### xbyak
``` ```
-3
View File
@@ -58,9 +58,6 @@ if (WIN32 AND NOT TARGET LLVM::Demangle)
add_library(LLVM::Demangle ALIAS demangle) add_library(LLVM::Demangle ALIAS demangle)
endif() endif()
# unordered_dense
AddJsonPackage(unordered-dense)
# httplib # httplib
if (IOS) if (IOS)
set(HTTPLIB_USE_BROTLI_IF_AVAILABLE OFF) set(HTTPLIB_USE_BROTLI_IF_AVAILABLE OFF)
@@ -11,6 +11,7 @@ import org.yuzu.yuzu_emu.utils.NativeConfig
enum class StringSetting(override val key: String) : AbstractStringSetting { enum class StringSetting(override val key: String) : AbstractStringSetting {
DRIVER_PATH("driver_path"), DRIVER_PATH("driver_path"),
DEVICE_NAME("device_name"), DEVICE_NAME("device_name"),
LOG_FILTER("log_filter"),
PROGRAM_ARGS("program_args"), PROGRAM_ARGS("program_args"),
WEB_TOKEN("eden_token"), WEB_TOKEN("eden_token"),
@@ -1033,6 +1033,13 @@ abstract class SettingsItem(
descriptionId = R.string.use_auto_stub_description descriptionId = R.string.use_auto_stub_description
) )
) )
put(
StringInputSetting(
StringSetting.LOG_FILTER,
titleId = R.string.log_filter,
descriptionId = R.string.log_filter_description
)
)
put( put(
SpinBoxSetting( SpinBoxSetting(
UShortSetting.DEBUG_KNOBS, UShortSetting.DEBUG_KNOBS,
@@ -1323,6 +1323,7 @@ class SettingsFragmentPresenter(
add(HeaderSetting(R.string.log)) add(HeaderSetting(R.string.log))
add(BooleanSetting.DEBUG_FLUSH_BY_LINE.key) add(BooleanSetting.DEBUG_FLUSH_BY_LINE.key)
add(StringSetting.LOG_FILTER.key)
} }
add(HeaderSetting(R.string.general)) add(HeaderSetting(R.string.general))
@@ -20,7 +20,7 @@ struct RomMetadata {
std::vector<u8> icon; std::vector<u8> icon;
bool isHomebrew; bool isHomebrew;
}; };
static ankerl::unordered_dense::map<std::string, RomMetadata> m_rom_metadata_cache; static ::Common::unordered_map<std::string, RomMetadata> m_rom_metadata_cache;
static RomMetadata CacheRomMetadata(const std::string& path) { static RomMetadata CacheRomMetadata(const std::string& path) {
auto& instance = EmulationSession::GetInstance(); auto& instance = EmulationSession::GetInstance();
@@ -21,7 +21,7 @@
#include "input_common/drivers/virtual_gamepad.h" #include "input_common/drivers/virtual_gamepad.h"
#include "native.h" #include "native.h"
ankerl::unordered_dense::map<std::string, std::unique_ptr<AndroidConfig>> map_profiles; ::Common::unordered_map<std::string, std::unique_ptr<AndroidConfig>> map_profiles;
bool IsHandheldOnly() { bool IsHandheldOnly() {
const auto npad_style_set = const auto npad_style_set =
@@ -636,6 +636,8 @@
<string name="log">Logging</string> <string name="log">Logging</string>
<string name="flush_by_line">Flush debug logs by line</string> <string name="flush_by_line">Flush debug logs by line</string>
<string name="flush_by_line_description">Flushes debugging logs on each line written, making debugging easier in cases of crashing or freezing.</string> <string name="flush_by_line_description">Flushes debugging logs on each line written, making debugging easier in cases of crashing or freezing.</string>
<string name="log_filter">Log filter</string>
<string name="log_filter_description">Controls Eden\'s log categories. Example: *:Info Service.LM:Debug</string>
<!-- GPU Logging strings --> <!-- GPU Logging strings -->
<string name="gpu_logging_header">GPU Logging</string> <string name="gpu_logging_header">GPU Logging</string>
+3 -3
View File
@@ -108,7 +108,6 @@ add_library(
settings_input.h settings_input.h
settings_setting.h settings_setting.h
slot_vector.h slot_vector.h
socket_types.h
spin_lock.h spin_lock.h
stb.cpp stb.cpp
stb.h stb.h
@@ -147,7 +146,8 @@ add_library(
cpu_features.cpp cpu_features.cpp
cpu_features.h cpu_features.h
httplib.h httplib.h
net/net.h net/net.cpp) net/net.h net/net.cpp
container/unordered_map.h container/unordered_set.h)
if(WIN32) if(WIN32)
target_sources(common PRIVATE windows/timer_resolution.cpp target_sources(common PRIVATE windows/timer_resolution.cpp
@@ -241,7 +241,7 @@ if (lz4_ADDED)
target_include_directories(common PRIVATE ${lz4_SOURCE_DIR}/lib) target_include_directories(common PRIVATE ${lz4_SOURCE_DIR}/lib)
endif() endif()
target_link_libraries(common PUBLIC fmt::fmt stb::headers Threads::Threads unordered_dense::unordered_dense) target_link_libraries(common PUBLIC fmt::fmt stb::headers Threads::Threads)
target_link_libraries(common PRIVATE lz4::lz4 zstd::zstd) target_link_libraries(common PRIVATE lz4::lz4 zstd::zstd)
# Please refer to src/common/demangle.cpp # Please refer to src/common/demangle.cpp
+2 -2
View File
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project // SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2017 Citra Emulator Project // SPDX-FileCopyrightText: Copyright 2017 Citra Emulator Project
@@ -11,7 +11,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "common/common_types.h" #include "common/common_types.h"
#include "common/socket_types.h" #include "core/internal_network/socket_types.h"
#include "web_service/web_result.h" #include "web_service/web_result.h"
namespace AnnounceMultiplayerRoom { namespace AnnounceMultiplayerRoom {
+16
View File
@@ -0,0 +1,16 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include "common/container_hash.h"
#include <boost/unordered/unordered_flat_map.hpp>
namespace Common {
template <class Key, class T, class Hash = std::hash<Key>, class Pred = std::equal_to<Key>,
class Allocator = std::allocator<std::pair<const Key, T>>>
using unordered_map = boost::unordered::unordered_flat_map<Key, T, Hash, Pred, Allocator>;
}
+16
View File
@@ -0,0 +1,16 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include "common/container_hash.h"
#include <boost/unordered/unordered_flat_set.hpp>
namespace Common {
template <class Key, class Hash = std::hash<Key>, class Pred = std::equal_to<Key>,
class Allocator = std::allocator<Key>>
using unordered_set = boost::unordered::unordered_flat_set<Key, Hash, Pred, Allocator>;
}
+33
View File
@@ -10,8 +10,11 @@
#include <array> #include <array>
#include <climits> #include <climits>
#include <cstdint> #include <cstdint>
#include <functional>
#include <limits> #include <limits>
#include <tuple>
#include <type_traits> #include <type_traits>
#include <utility>
#include <vector> #include <vector>
namespace Common { namespace Common {
@@ -69,10 +72,17 @@ struct HashCombineImpl<64> {
} // namespace detail } // namespace detail
template <typename T> template <typename T>
requires std::is_unsigned_v<T>
inline void HashCombine(std::size_t& seed, const T& v) { inline void HashCombine(std::size_t& seed, const T& v) {
seed = detail::HashCombineImpl<sizeof(std::size_t) * CHAR_BIT>::fn(seed, detail::HashValue(v)); seed = detail::HashCombineImpl<sizeof(std::size_t) * CHAR_BIT>::fn(seed, detail::HashValue(v));
} }
template <typename T>
requires (!std::is_unsigned_v<T>)
inline void HashCombine(std::size_t& seed, const T& v) {
seed = detail::HashCombineImpl<sizeof(std::size_t) * CHAR_BIT>::fn(seed, std::hash<T>{}(v));
}
template <typename It> template <typename It>
inline std::size_t HashRange(It first, It last) { inline std::size_t HashRange(It first, It last) {
std::size_t seed = 0; std::size_t seed = 0;
@@ -95,3 +105,26 @@ std::size_t HashValue(const std::vector<T, Allocator>& v) {
} }
} // namespace Common } // namespace Common
namespace std {
template <typename... Args>
struct hash<std::tuple<Args...>> {
std::size_t operator()(const std::tuple<Args...>& t) const noexcept {
std::size_t seed = 0;
std::apply([&seed](const Args&... args) { (Common::HashCombine(seed, args), ...); }, t);
return seed;
}
};
template <class A, class B>
struct hash<std::pair<A, B>> {
std::size_t operator()(const std::pair<A, B>& p) const noexcept {
std::size_t seed = 0;
Common::HashCombine(seed, p.first);
Common::HashCombine(seed, p.second);
return seed;
}
};
} // namespace std
+3 -3
View File
@@ -7,7 +7,7 @@
#include <algorithm> #include <algorithm>
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include <ankerl/unordered_dense.h> #include "common/container/unordered_map.h"
#include "common/assert.h" #include "common/assert.h"
#include "common/fs/fs.h" #include "common/fs/fs.h"
@@ -196,8 +196,8 @@ private:
SetLegacyPathImpl(legacy_path, new_path); SetLegacyPathImpl(legacy_path, new_path);
} }
ankerl::unordered_dense::map<EdenPath, fs::path> eden_paths; ::Common::unordered_map<EdenPath, fs::path> eden_paths;
ankerl::unordered_dense::map<EmuPath, fs::path> legacy_paths; ::Common::unordered_map<EmuPath, fs::path> legacy_paths;
}; };
bool ValidatePath(const fs::path& path) { bool ValidatePath(const fs::path& path) {
+2 -2
View File
@@ -7,7 +7,7 @@
#ifdef _WIN32 #ifdef _WIN32
#include <iterator> #include <iterator>
#include <ankerl/unordered_dense.h> #include "common/container/unordered_map.h"
#include <boost/icl/separate_interval_set.hpp> #include <boost/icl/separate_interval_set.hpp>
#include <windows.h> #include <windows.h>
#include "common/dynamic_library.h" #include "common/dynamic_library.h"
@@ -391,7 +391,7 @@ private:
std::mutex placeholder_mutex; ///< Mutex for placeholders std::mutex placeholder_mutex; ///< Mutex for placeholders
boost::icl::separate_interval_set<size_t> placeholders; ///< Mapped placeholders boost::icl::separate_interval_set<size_t> placeholders; ///< Mapped placeholders
ankerl::unordered_dense::map<size_t, size_t> placeholder_host_pointers; ///< Placeholder backing offset ::Common::unordered_map<size_t, size_t> placeholder_host_pointers; ///< Placeholder backing offset
}; };
#elif defined(__OPENORBIS__) || defined(__managarm__) #elif defined(__OPENORBIS__) || defined(__managarm__)
+2 -2
View File
@@ -9,7 +9,7 @@
#include <functional> #include <functional>
#include <memory> #include <memory>
#include <string> #include <string>
#include <ankerl/unordered_dense.h> #include "common/container/unordered_map.h"
#include <utility> #include <utility>
#include <vector> #include <vector>
#include "common/logging.h" #include "common/logging.h"
@@ -412,7 +412,7 @@ public:
namespace Impl { namespace Impl {
template <typename InputDeviceType> template <typename InputDeviceType>
using FactoryListType = ankerl::unordered_dense::map<std::string, std::shared_ptr<Factory<InputDeviceType>>>; using FactoryListType = ::Common::unordered_map<std::string, std::shared_ptr<Factory<InputDeviceType>>>;
template <typename InputDeviceType> template <typename InputDeviceType>
struct FactoryList { struct FactoryList {
+2 -2
View File
@@ -8,14 +8,14 @@
#include <initializer_list> #include <initializer_list>
#include <string> #include <string>
#include <ankerl/unordered_dense.h> #include "common/container/unordered_map.h"
namespace Common { namespace Common {
/// A string-based key-value container supporting serializing to and deserializing from a string /// A string-based key-value container supporting serializing to and deserializing from a string
class ParamPackage { class ParamPackage {
public: public:
using DataType = ankerl::unordered_dense::map<std::string, std::string>; using DataType = ::Common::unordered_map<std::string, std::string>;
ParamPackage() = default; ParamPackage() = default;
explicit ParamPackage(const std::string& serialized); explicit ParamPackage(const std::string& serialized);
-178
View File
@@ -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 <optional>
#include <string>
#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<u8, 4>;
/// 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<std::string> canon_name;
};
} // namespace Network
+4 -3
View File
@@ -22,10 +22,11 @@
#endif #endif
// You must ensure this matches with src/common/x64/xbyak.h on root dir // You must ensure this matches with src/common/x64/xbyak.h on root dir
#include <ankerl/unordered_dense.h> #include "common/container/unordered_map.h"
#include "common/container/unordered_set.h"
#include <boost/unordered_map.hpp> #include <boost/unordered_map.hpp>
#define XBYAK_STD_UNORDERED_SET ankerl::unordered_dense::set #define XBYAK_STD_UNORDERED_SET ::Common::unordered_set
#define XBYAK_STD_UNORDERED_MAP ankerl::unordered_dense::map #define XBYAK_STD_UNORDERED_MAP ::Common::unordered_map
#define XBYAK_STD_UNORDERED_MULTIMAP boost::unordered_multimap #define XBYAK_STD_UNORDERED_MULTIMAP boost::unordered_multimap
#include <xbyak/xbyak.h> #include <xbyak/xbyak.h>
#include <xbyak/xbyak_util.h> #include <xbyak/xbyak_util.h>
+7
View File
@@ -1129,6 +1129,7 @@ add_library(core STATIC
internal_network/network_interface.h internal_network/network_interface.h
internal_network/socket_proxy.cpp internal_network/socket_proxy.cpp
internal_network/socket_proxy.h internal_network/socket_proxy.h
internal_network/socket_types.h
internal_network/sockets.h internal_network/sockets.h
internal_network/wifi_scanner.h internal_network/wifi_scanner.h
launch_timestamp_cache.cpp launch_timestamp_cache.cpp
@@ -1167,6 +1168,12 @@ add_library(core STATIC
tools/renderdoc.cpp tools/renderdoc.cpp
tools/renderdoc.h) tools/renderdoc.h)
if (UNIX AND NOT APPLE)
target_sources(core PRIVATE
internal_network/socket_icmp.cpp
internal_network/socket_icmp.h)
endif()
if (ENABLE_WIFI_SCAN) if (ENABLE_WIFI_SCAN)
target_sources(core PRIVATE internal_network/wifi_scanner.cpp) target_sources(core PRIVATE internal_network/wifi_scanner.cpp)
if (LINUX) if (LINUX)
+1 -1
View File
@@ -8,7 +8,7 @@
#include <atomic> #include <atomic>
#include <memory> #include <memory>
#include <ankerl/unordered_dense.h> #include "common/container/unordered_map.h"
#include <dynarmic/interface/A64/a64.h> #include <dynarmic/interface/A64/a64.h>
#include <dynarmic/interface/code_page.h> #include <dynarmic/interface/code_page.h>
+2 -2
View File
@@ -4,7 +4,7 @@
#pragma once #pragma once
#include <span> #include <span>
#include <ankerl/unordered_dense.h> #include "common/container/unordered_map.h"
#include <vector> #include <vector>
#include <oaknut/code_block.hpp> #include <oaknut/code_block.hpp>
#include <oaknut/oaknut.hpp> #include <oaknut/oaknut.hpp>
@@ -46,7 +46,7 @@ enum class PatchMode : u32 {
using ModuleTextAddress = u64; using ModuleTextAddress = u64;
using PatchTextAddress = u64; using PatchTextAddress = u64;
using EntryTrampolines = ankerl::unordered_dense::map<ModuleTextAddress, PatchTextAddress>; using EntryTrampolines = ::Common::unordered_map<ModuleTextAddress, PatchTextAddress>;
class Patcher { class Patcher {
public: public:
+2 -2
View File
@@ -8,7 +8,7 @@
#include <utility> #include <utility>
#include <span> #include <span>
#include <cctype> #include <cctype>
#include <ankerl/unordered_dense.h> #include "common/container/unordered_map.h"
#include "common/hex_util.h" #include "common/hex_util.h"
#include "common/logging.h" #include "common/logging.h"
@@ -104,7 +104,7 @@ struct IPSwitchRecord {
size_t count; size_t count;
}; };
struct IPSwitchCompiler::IPSwitchPatch { struct IPSwitchCompiler::IPSwitchPatch {
ankerl::unordered_dense::map<u32, IPSwitchRecord> records; ::Common::unordered_map<u32, IPSwitchRecord> records;
bool enabled; bool enabled;
}; };
+1 -1
View File
@@ -566,7 +566,7 @@ VirtualFile RegisteredCache::GetFileAtID(NcaID id) const {
return file; return file;
} }
static std::optional<NcaID> CheckMapForContentRecord(const ankerl::unordered_dense::map<u64, CNMT>& map, u64 title_id, ContentRecordType type) { static std::optional<NcaID> CheckMapForContentRecord(const ::Common::unordered_map<u64, CNMT>& map, u64 title_id, ContentRecordType type) {
auto cmnt_iter = map.find(title_id); auto cmnt_iter = map.find(title_id);
u8 id_offset = 0; u8 id_offset = 0;
+6 -6
View File
@@ -12,7 +12,7 @@
#include <optional> #include <optional>
#include <string> #include <string>
#include <vector> #include <vector>
#include <ankerl/unordered_dense.h> #include "common/container/unordered_map.h"
#include <boost/container/flat_map.hpp> #include <boost/container/flat_map.hpp>
#include "common/common_types.h" #include "common/common_types.h"
#include "core/crypto/key_manager.h" #include "core/crypto/key_manager.h"
@@ -209,11 +209,11 @@ private:
ContentProviderParsingFunction parser; ContentProviderParsingFunction parser;
// maps tid -> NcaID of meta // maps tid -> NcaID of meta
ankerl::unordered_dense::map<u64, NcaID> meta_id; ::Common::unordered_map<u64, NcaID> meta_id;
// maps tid -> meta // maps tid -> meta
ankerl::unordered_dense::map<u64, CNMT> meta; ::Common::unordered_map<u64, CNMT> meta;
// maps tid -> meta for CNMT in yuzu_meta // maps tid -> meta for CNMT in yuzu_meta
ankerl::unordered_dense::map<u64, CNMT> yuzu_meta; ::Common::unordered_map<u64, CNMT> yuzu_meta;
}; };
enum class ContentProviderUnionSlot { enum class ContentProviderUnionSlot {
@@ -313,8 +313,8 @@ private:
void ProcessXCI(const VirtualFile& file); void ProcessXCI(const VirtualFile& file);
std::vector<VirtualDir> load_dirs; std::vector<VirtualDir> load_dirs;
ankerl::unordered_dense::map<std::tuple<u64, ContentRecordType, TitleType>, VirtualFile> entries; ::Common::unordered_map<std::tuple<u64, ContentRecordType, TitleType>, VirtualFile> entries;
ankerl::unordered_dense::map<u64, u32> versions; ::Common::unordered_map<u64, u32> versions;
std::vector<ExternalUpdateEntry> multi_version_entries; std::vector<ExternalUpdateEntry> multi_version_entries;
}; };
+3 -3
View File
@@ -6,7 +6,7 @@
#include <algorithm> #include <algorithm>
#include <set> #include <set>
#include <ankerl/unordered_dense.h> #include "common/container/unordered_set.h"
#include <utility> #include <utility>
#include "core/file_sys/vfs/vfs_layered.h" #include "core/file_sys/vfs/vfs_layered.h"
@@ -63,7 +63,7 @@ std::string LayeredVfsDirectory::GetFullPath() const {
std::vector<VirtualFile> LayeredVfsDirectory::GetFiles() const { std::vector<VirtualFile> LayeredVfsDirectory::GetFiles() const {
std::vector<VirtualFile> out; std::vector<VirtualFile> out;
ankerl::unordered_dense::set<std::string> out_names; ::Common::unordered_set<std::string> out_names;
for (const auto& layer : dirs) { for (const auto& layer : dirs) {
for (auto& file : layer->GetFiles()) { for (auto& file : layer->GetFiles()) {
@@ -79,7 +79,7 @@ std::vector<VirtualFile> LayeredVfsDirectory::GetFiles() const {
std::vector<VirtualDir> LayeredVfsDirectory::GetSubdirectories() const { std::vector<VirtualDir> LayeredVfsDirectory::GetSubdirectories() const {
std::vector<VirtualDir> out; std::vector<VirtualDir> out;
ankerl::unordered_dense::set<std::string> out_names; ::Common::unordered_set<std::string> out_names;
for (const auto& layer : dirs) { for (const auto& layer : dirs) {
for (const auto& sd : layer->GetSubdirectories()) { for (const auto& sd : layer->GetSubdirectories()) {
+2 -2
View File
@@ -78,7 +78,7 @@ private:
std::array<DebugWatchpoint, Core::Hardware::NUM_WATCHPOINTS> m_watchpoints{}; std::array<DebugWatchpoint, Core::Hardware::NUM_WATCHPOINTS> m_watchpoints{};
std::map<KProcessAddress, u64> m_debug_page_refcounts{}; std::map<KProcessAddress, u64> m_debug_page_refcounts{};
#ifdef HAS_NCE #ifdef HAS_NCE
ankerl::unordered_dense::map<u64, u64> m_post_handlers{}; ::Common::unordered_map<u64, u64> m_post_handlers{};
#endif #endif
std::unique_ptr<Core::ExclusiveMonitor> m_exclusive_monitor; std::unique_ptr<Core::ExclusiveMonitor> m_exclusive_monitor;
Core::Memory::Memory m_memory; Core::Memory::Memory m_memory;
@@ -494,7 +494,7 @@ public:
static void Switch(KernelCore& kernel, KProcess* cur_process, KProcess* next_process); static void Switch(KernelCore& kernel, KProcess* cur_process, KProcess* next_process);
#ifdef HAS_NCE #ifdef HAS_NCE
ankerl::unordered_dense::map<u64, u64>& GetPostHandlers() noexcept { ::Common::unordered_map<u64, u64>& GetPostHandlers() noexcept {
return m_post_handlers; return m_post_handlers;
} }
#endif #endif
+4 -3
View File
@@ -10,7 +10,8 @@
#include <functional> #include <functional>
#include <memory> #include <memory>
#include <thread> #include <thread>
#include <ankerl/unordered_dense.h> #include "common/container/unordered_map.h"
#include "common/container/unordered_set.h"
#include <utility> #include <utility>
#include "common/assert.h" #include "common/assert.h"
@@ -792,8 +793,8 @@ struct KernelCore::Impl {
std::optional<KObjectNameGlobalData> object_name_global_data; std::optional<KObjectNameGlobalData> object_name_global_data;
ankerl::unordered_dense::set<KAutoObject*> registered_objects; ::Common::unordered_set<KAutoObject*> registered_objects;
ankerl::unordered_dense::set<KAutoObject*> registered_in_use_objects; ::Common::unordered_set<KAutoObject*> registered_in_use_objects;
std::mutex server_lock; std::mutex server_lock;
std::vector<std::unique_ptr<Service::ServerManager>> server_managers; std::vector<std::unique_ptr<Service::ServerManager>> server_managers;
+1 -1
View File
@@ -11,7 +11,7 @@
#include <list> #include <list>
#include <memory> #include <memory>
#include <string> #include <string>
#include <ankerl/unordered_dense.h> #include "common/container/unordered_map.h"
#include <vector> #include <vector>
#include "common/polyfill_thread.h" #include "common/polyfill_thread.h"
@@ -7,7 +7,7 @@
#pragma once #pragma once
#include <array> #include <array>
#include <ankerl/unordered_dense.h> #include "common/container/unordered_map.h"
#include <vector> #include <vector>
#include "common/common_funcs.h" #include "common/common_funcs.h"
@@ -176,6 +176,6 @@ struct WebCommonReturnValue {
}; };
static_assert(sizeof(WebCommonReturnValue) == 0x1010, "WebCommonReturnValue has incorrect size."); static_assert(sizeof(WebCommonReturnValue) == 0x1010, "WebCommonReturnValue has incorrect size.");
using WebArgInputTLVMap = ankerl::unordered_dense::map<WebArgInputTLVType, std::vector<u8>>; using WebArgInputTLVMap = ::Common::unordered_map<WebArgInputTLVType, std::vector<u8>>;
} // namespace Service::AM::Frontend } // namespace Service::AM::Frontend
@@ -40,8 +40,8 @@ std::vector<u8> default_logo_small;
std::vector<u8> default_logo_large; std::vector<u8> default_logo_large;
bool default_logos_loaded = false; bool default_logos_loaded = false;
ankerl::unordered_dense::map<std::string, std::vector<u8>> news_images_small; ::Common::unordered_map<std::string, std::vector<u8>> news_images_small;
ankerl::unordered_dense::map<std::string, std::vector<u8>> news_images_large; ::Common::unordered_map<std::string, std::vector<u8>> news_images_large;
std::mutex images_mutex; std::mutex images_mutex;
@@ -12,7 +12,7 @@
#include <optional> #include <optional>
#include <span> #include <span>
#include <string> #include <string>
#include <ankerl/unordered_dense.h> #include "common/container/unordered_map.h"
#include <vector> #include <vector>
#include "common/common_types.h" #include "common/common_types.h"
@@ -93,7 +93,7 @@ private:
static s64 Now(); static s64 Now();
mutable std::mutex mtx; mutable std::mutex mtx;
ankerl::unordered_dense::map<std::string, StoredNews> items; ::Common::unordered_map<std::string, StoredNews> items;
size_t open_counter{}; size_t open_counter{};
}; };
+2 -2
View File
@@ -6,7 +6,7 @@
#pragma once #pragma once
#include <ankerl/unordered_dense.h> #include "common/container/unordered_map.h"
#include "common/fs/fs.h" #include "common/fs/fs.h"
#include "core/hle/result.h" #include "core/hle/result.h"
@@ -88,7 +88,7 @@ private:
AlbumFileDateTime ConvertToAlbumDateTime(u64 posix_time) const; AlbumFileDateTime ConvertToAlbumDateTime(u64 posix_time) const;
bool is_mounted{}; bool is_mounted{};
ankerl::unordered_dense::map<AlbumFileId, std::filesystem::path> album_files; ::Common::unordered_map<AlbumFileId, std::filesystem::path> album_files;
Core::System& system; Core::System& system;
}; };
+3 -3
View File
@@ -15,10 +15,10 @@
#include <random> #include <random>
#include <span> #include <span>
#include <thread> #include <thread>
#include <ankerl/unordered_dense.h> #include "common/container/unordered_map.h"
#include "common/logging.h" #include "common/logging.h"
#include "common/socket_types.h" #include "core/internal_network/socket_types.h"
#include "core/hle/result.h" #include "core/hle/result.h"
#include "core/hle/service/ldn/ldn_results.h" #include "core/hle/service/ldn/ldn_results.h"
#include "core/hle/service/ldn/ldn_types.h" #include "core/hle/service/ldn/ldn_types.h"
@@ -119,7 +119,7 @@ protected:
std::array<LanStation, StationCountMax> stations; std::array<LanStation, StationCountMax> stations;
std::array<NodeLatestUpdate, NodeCountMax> node_changes{}; std::array<NodeLatestUpdate, NodeCountMax> node_changes{};
std::array<u8, NodeCountMax> node_last_states{}; std::array<u8, NodeCountMax> node_last_states{};
ankerl::unordered_dense::map<MacAddress, NetworkInfo, MACAddressHash> scan_results{}; ::Common::unordered_map<MacAddress, NetworkInfo, MACAddressHash> scan_results{};
NodeInfo node_info{}; NodeInfo node_info{};
NetworkInfo network_info{}; NetworkInfo network_info{};
State state{State::None}; State state{State::None};
+2 -2
View File
@@ -7,7 +7,7 @@
#include <string> #include <string>
#include <optional> #include <optional>
#include <ankerl/unordered_dense.h> #include "common/container/unordered_map.h"
#include <boost/container_hash/hash.hpp> #include <boost/container_hash/hash.hpp>
#include "common/logging.h" #include "common/logging.h"
#include "core/core.h" #include "core/core.h"
@@ -331,7 +331,7 @@ private:
}; };
static_assert(sizeof(LogPacketHeader) == 0x18, "LogPacketHeader is an invalid size"); static_assert(sizeof(LogPacketHeader) == 0x18, "LogPacketHeader is an invalid size");
ankerl::unordered_dense::map<LogPacketHeaderEntry, std::vector<u8>> entries{}; ::Common::unordered_map<LogPacketHeaderEntry, std::vector<u8>> entries{};
LogDestination destination{LogDestination::All}; LogDestination destination{LogDestination::All};
}; };
+1 -1
View File
@@ -23,7 +23,7 @@
#include <mutex> #include <mutex>
#include <optional> #include <optional>
#include <thread> #include <thread>
#include <ankerl/unordered_dense.h> #include "common/container/unordered_map.h"
#include <common/settings.h> #include <common/settings.h>
#ifdef _WIN32 #ifdef _WIN32
+1 -1
View File
@@ -9,7 +9,7 @@
#include <deque> #include <deque>
#include <memory> #include <memory>
#include <ankerl/unordered_dense.h> #include "common/container/unordered_map.h"
#include "core/device_memory_manager.h" #include "core/device_memory_manager.h"
#include "core/hle/service/nvdrv/nvdata.h" #include "core/hle/service/nvdrv/nvdata.h"
+2 -2
View File
@@ -12,7 +12,7 @@
#include <memory> #include <memory>
#include <mutex> #include <mutex>
#include <optional> #include <optional>
#include <ankerl/unordered_dense.h> #include "common/container/unordered_map.h"
#include <assert.h> #include <assert.h>
#include "common/bit_field.h" #include "common/bit_field.h"
@@ -161,7 +161,7 @@ private:
std::list<std::shared_ptr<Handle>> unmap_queue{}; std::list<std::shared_ptr<Handle>> unmap_queue{};
std::mutex unmap_queue_lock{}; //!< Protects access to `unmap_queue` std::mutex unmap_queue_lock{}; //!< Protects access to `unmap_queue`
ankerl::unordered_dense::map<Handle::Id, std::shared_ptr<Handle>> ::Common::unordered_map<Handle::Id, std::shared_ptr<Handle>>
handles{}; //!< Main owning map of handles handles{}; //!< Main owning map of handles
std::mutex handles_lock; //!< Protects access to `handles` std::mutex handles_lock; //!< Protects access to `handles`
@@ -13,7 +13,7 @@
#include <memory> #include <memory>
#include <mutex> #include <mutex>
#include <optional> #include <optional>
#include <ankerl/unordered_dense.h> #include "common/container/unordered_set.h"
#include <vector> #include <vector>
#include "common/address_space.h" #include "common/address_space.h"
@@ -113,7 +113,7 @@ private:
}; };
static_assert(sizeof(IoctlRemapEntry) == 20, "IoctlRemapEntry is incorrect size"); static_assert(sizeof(IoctlRemapEntry) == 20, "IoctlRemapEntry is incorrect size");
ankerl::unordered_dense::set<s64_le> map_buffer_offsets{}; ::Common::unordered_set<s64_le> map_buffer_offsets{};
struct IoctlMapBufferEx { struct IoctlMapBufferEx {
MappingFlags flags{}; // bit0: fixed_offset, bit2: cacheable MappingFlags flags{}; // bit0: fixed_offset, bit2: cacheable
@@ -217,7 +217,7 @@ private:
NvCore::SyncpointManager& syncpoint_manager; NvCore::SyncpointManager& syncpoint_manager;
NvCore::NvMap& nvmap; NvCore::NvMap& nvmap;
std::shared_ptr<Tegra::Control::ChannelState> channel_state; std::shared_ptr<Tegra::Control::ChannelState> channel_state;
ankerl::unordered_dense::map<DeviceFD, NvCore::SessionId> sessions; ::Common::unordered_map<DeviceFD, NvCore::SessionId> sessions;
u32 channel_syncpoint; u32 channel_syncpoint;
std::mutex channel_mutex; std::mutex channel_mutex;
@@ -7,7 +7,7 @@
#pragma once #pragma once
#include <deque> #include <deque>
#include <ankerl/unordered_dense.h> #include "common/container/unordered_map.h"
#include <vector> #include <vector>
#include "common/common_types.h" #include "common/common_types.h"
@@ -138,7 +138,7 @@ protected:
NvCore::NvMap& nvmap; NvCore::NvMap& nvmap;
NvCore::ChannelType channel_type; NvCore::ChannelType channel_type;
std::array<u32, MaxSyncPoints> device_syncpoints{}; std::array<u32, MaxSyncPoints> device_syncpoints{};
ankerl::unordered_dense::map<DeviceFD, NvCore::SessionId> sessions; ::Common::unordered_map<DeviceFD, NvCore::SessionId> sessions;
}; };
}; // namespace Devices }; // namespace Devices
} // namespace Service::Nvidia } // namespace Service::Nvidia
+2 -2
View File
@@ -7,7 +7,7 @@
#pragma once #pragma once
#include <memory> #include <memory>
#include <ankerl/unordered_dense.h> #include "common/container/unordered_map.h"
#include <vector> #include <vector>
#include "common/common_funcs.h" #include "common/common_funcs.h"
#include "common/common_types.h" #include "common/common_types.h"
@@ -118,7 +118,7 @@ private:
NvCore::Container& container; NvCore::Container& container;
NvCore::NvMap& file; NvCore::NvMap& file;
ankerl::unordered_dense::map<DeviceFD, NvCore::SessionId> sessions; ::Common::unordered_map<DeviceFD, NvCore::SessionId> sessions;
}; };
} // namespace Service::Nvidia::Devices } // namespace Service::Nvidia::Devices
+3 -3
View File
@@ -12,7 +12,7 @@
#include <memory> #include <memory>
#include <span> #include <span>
#include <string> #include <string>
#include <ankerl/unordered_dense.h> #include "common/container/unordered_map.h"
#include "common/common_types.h" #include "common/common_types.h"
#include "core/hle/service/kernel_helpers.h" #include "core/hle/service/kernel_helpers.h"
@@ -103,7 +103,7 @@ private:
/// Id to use for the next open file descriptor. /// Id to use for the next open file descriptor.
DeviceFD next_fd = 1; DeviceFD next_fd = 1;
using FilesContainerType = ankerl::unordered_dense::map<DeviceFD, std::shared_ptr<Devices::nvdevice>>; using FilesContainerType = ::Common::unordered_map<DeviceFD, std::shared_ptr<Devices::nvdevice>>;
/// Mapping of file descriptors to the devices they reference. /// Mapping of file descriptors to the devices they reference.
FilesContainerType open_files; FilesContainerType open_files;
@@ -111,7 +111,7 @@ private:
EventInterface events_interface; EventInterface events_interface;
ankerl::unordered_dense::map<std::string, std::function<FilesContainerType::iterator(DeviceFD)>> builders; ::Common::unordered_map<std::string, std::function<FilesContainerType::iterator(DeviceFD)>> builders;
}; };
void LoopProcess(Core::System& system); void LoopProcess(Core::System& system);
@@ -8,7 +8,7 @@
#include <memory> #include <memory>
#include <mutex> #include <mutex>
#include <ankerl/unordered_dense.h> #include "common/container/unordered_map.h"
#include "common/common_types.h" #include "common/common_types.h"
#include "core/hle/service/nvnflinger/binder.h" #include "core/hle/service/nvnflinger/binder.h"
@@ -39,8 +39,8 @@ private:
mutable std::mutex lock; mutable std::mutex lock;
s32 last_id = 0; s32 last_id = 0;
ankerl::unordered_dense::map<s32, std::shared_ptr<android::IBinder>> binders; ::Common::unordered_map<s32, std::shared_ptr<android::IBinder>> binders;
ankerl::unordered_dense::map<s32, RefCounts> refcounts; ::Common::unordered_map<s32, RefCounts> refcounts;
}; };
} // namespace Service::Nvnflinger } // namespace Service::Nvnflinger
@@ -6,7 +6,7 @@
#pragma once #pragma once
#include <ankerl/unordered_dense.h> #include "common/container/unordered_map.h"
#include "common/uuid.h" #include "common/uuid.h"
#include "core/hle/service/cmif_types.h" #include "core/hle/service/cmif_types.h"
@@ -56,10 +56,10 @@ private:
} }
}; };
ankerl::unordered_dense::map<AppKey, bool, AppKeyHash> app_auto_transfer_{}; ::Common::unordered_map<AppKey, bool, AppKeyHash> app_auto_transfer_{};
ankerl::unordered_dense::map<Common::UUID, bool> global_auto_upload_{}; ::Common::unordered_map<Common::UUID, bool> global_auto_upload_{};
ankerl::unordered_dense::map<Common::UUID, bool> global_auto_download_{}; ::Common::unordered_map<Common::UUID, bool> global_auto_download_{};
ankerl::unordered_dense::map<AppKey, u8, AppKeyHash> autonomy_task_status_{}; ::Common::unordered_map<AppKey, u8, AppKeyHash> autonomy_task_status_{};
}; };
} // namespace Service::OLSC } // namespace Service::OLSC
+7 -8
View File
@@ -129,6 +129,13 @@ ServerManager::~ServerManager() {
} }
} }
void ServerManager::StartAdditionalHostThreads(const char* name, size_t num_threads) {
for (size_t i = 0; i < num_threads; i++) {
auto thread_name = fmt::format("{}:{}", name, i + 1);
m_threads.emplace_back(m_system.Kernel().RunOnHostCoreThread(std::move(thread_name), [&] { this->LoopProcessImpl(); }));
}
}
void ServerManager::RunServer(std::unique_ptr<ServerManager>&& server_manager) { void ServerManager::RunServer(std::unique_ptr<ServerManager>&& server_manager) {
server_manager->m_system.RunServer(std::move(server_manager)); server_manager->m_system.RunServer(std::move(server_manager));
} }
@@ -245,14 +252,6 @@ Result ServerManager::ManageDeferral(Kernel::KEvent** out_event) {
R_SUCCEED(); R_SUCCEED();
} }
void ServerManager::StartAdditionalHostThreads(const char* name, size_t num_threads) {
for (size_t i = 0; i < num_threads; i++) {
auto thread_name = fmt::format("{}:{}", name, i + 1);
m_threads.emplace_back(m_system.Kernel().RunOnHostCoreThread(
std::move(thread_name), [&] { this->LoopProcessImpl(); }));
}
}
Result ServerManager::LoopProcess() { Result ServerManager::LoopProcess() {
SCOPE_EXIT { SCOPE_EXIT {
m_stopped.Set(); m_stopped.Set();
+4 -1
View File
@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@@ -48,8 +51,8 @@ public:
Result ManageDeferral(Kernel::KEvent** out_event); Result ManageDeferral(Kernel::KEvent** out_event);
Result LoopProcess(); Result LoopProcess();
void StartAdditionalHostThreads(const char* name, size_t num_threads);
void StartAdditionalHostThreads(const char* name, size_t num_threads);
static void RunServer(std::unique_ptr<ServerManager>&& server); static void RunServer(std::unique_ptr<ServerManager>&& server);
private: private:
+3 -3
View File
@@ -8,7 +8,7 @@
#include <cstddef> #include <cstddef>
#include <mutex> #include <mutex>
#include <ankerl/unordered_dense.h> #include "common/container/unordered_map.h"
#include "common/common_types.h" #include "common/common_types.h"
#include "core/hle/service/hle_ipc.h" #include "core/hle/service/hle_ipc.h"
@@ -99,8 +99,8 @@ private:
void ReportUnimplementedFunction(HLERequestContext& ctx, const FunctionInfoBase* info); void ReportUnimplementedFunction(HLERequestContext& ctx, const FunctionInfoBase* info);
protected: protected:
ankerl::unordered_dense::map<u32, FunctionInfoBase> handlers; ::Common::unordered_map<u32, FunctionInfoBase> handlers;
ankerl::unordered_dense::map<u32, FunctionInfoBase> handlers_tipc; ::Common::unordered_map<u32, FunctionInfoBase> handlers_tipc;
/// Used to gain exclusive access to the service members, e.g. from CoreTiming thread. /// Used to gain exclusive access to the service members, e.g. from CoreTiming thread.
std::mutex lock_service; std::mutex lock_service;
/// System context that the service operates under. /// System context that the service operates under.
+3 -3
View File
@@ -10,7 +10,7 @@
#include <memory> #include <memory>
#include <mutex> #include <mutex>
#include <string> #include <string>
#include <ankerl/unordered_dense.h> #include "common/container/unordered_map.h"
#include <concepts> #include <concepts>
#include "core/hle/kernel/k_port.h" #include "core/hle/kernel/k_port.h"
@@ -100,8 +100,8 @@ private:
/// Map of registered services, retrieved using GetServicePort. /// Map of registered services, retrieved using GetServicePort.
mutable std::mutex lock; mutable std::mutex lock;
ankerl::unordered_dense::map<std::string, SessionRequestHandlerFactory> registered_services; ::Common::unordered_map<std::string, SessionRequestHandlerFactory> registered_services;
ankerl::unordered_dense::map<std::string, Kernel::KClientPort*> service_ports; ::Common::unordered_map<std::string, Kernel::KClientPort*> service_ports;
/// Kernel context /// Kernel context
Kernel::KernelCore& kernel; Kernel::KernelCore& kernel;
File diff suppressed because it is too large Load Diff
+37 -37
View File
@@ -11,7 +11,7 @@
#include <variant> #include <variant>
#include "common/common_types.h" #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/service.h"
#include "core/hle/service/sockets/sockets.h" #include "core/hle/service/sockets/sockets.h"
#include "network/network.h" #include "network/network.h"
@@ -27,16 +27,16 @@ class Socket;
namespace Service::Sockets { namespace Service::Sockets {
class BSD final : public ServiceFramework<BSD> { class BSD_USA final : public ServiceFramework<BSD_USA> {
public: public:
explicit BSD(Core::System& system_, const char* name, bool is_user); explicit BSD_USA(Core::System& system_, const char* name, bool is_user);
~BSD() override; ~BSD_USA() override;
// These methods are called from SSL; the first two are also called from // These methods are called from SSL; the first two are also called from
// this class for the corresponding IPC methods. // this class for the corresponding IPC methods.
// On the real device, the SSL service makes IPC calls to this service. // On the real device, the SSL service makes IPC calls to this service.
std::variant<s32, Errno> DuplicateSocketImpl(s32 fd); std::variant<s32, Network::Errno> DuplicateSocketImpl(s32 fd);
Errno CloseImpl(s32 fd); Network::Errno CloseImpl(s32 fd);
std::optional<std::shared_ptr<Network::SocketBase>> GetSocket(s32 fd); std::optional<std::shared_ptr<Network::SocketBase>> GetSocket(s32 fd);
private: private:
@@ -50,7 +50,7 @@ private:
}; };
struct PollWork { struct PollWork {
void Execute(BSD* bsd); void Execute(BSD_USA* bsd);
void Response(HLERequestContext& ctx); void Response(HLERequestContext& ctx);
s32 nfds; s32 nfds;
@@ -58,41 +58,41 @@ private:
std::span<const u8> read_buffer; std::span<const u8> read_buffer;
std::vector<u8> write_buffer; std::vector<u8> write_buffer;
s32 ret{}; s32 ret{};
Errno bsd_errno{}; Network::Errno bsd_errno{};
}; };
struct AcceptWork { struct AcceptWork {
void Execute(BSD* bsd); void Execute(BSD_USA* bsd);
void Response(HLERequestContext& ctx); void Response(HLERequestContext& ctx);
s32 fd; s32 fd;
std::vector<u8> write_buffer; std::vector<u8> write_buffer;
s32 ret{}; s32 ret{};
Errno bsd_errno{}; Network::Errno bsd_errno{};
}; };
struct ConnectWork { struct ConnectWork {
void Execute(BSD* bsd); void Execute(BSD_USA* bsd);
void Response(HLERequestContext& ctx); void Response(HLERequestContext& ctx);
s32 fd; s32 fd;
std::span<const u8> addr; std::span<const u8> addr;
Errno bsd_errno{}; Network::Errno bsd_errno{};
}; };
struct RecvWork { struct RecvWork {
void Execute(BSD* bsd); void Execute(BSD_USA* bsd);
void Response(HLERequestContext& ctx); void Response(HLERequestContext& ctx);
s32 fd; s32 fd;
u32 flags; u32 flags;
std::vector<u8> message; std::vector<u8> message;
s32 ret{}; s32 ret{};
Errno bsd_errno{}; Network::Errno bsd_errno{};
}; };
struct RecvFromWork { struct RecvFromWork {
void Execute(BSD* bsd); void Execute(BSD_USA* bsd);
void Response(HLERequestContext& ctx); void Response(HLERequestContext& ctx);
s32 fd; s32 fd;
@@ -100,22 +100,22 @@ private:
std::vector<u8> message; std::vector<u8> message;
std::vector<u8> addr; std::vector<u8> addr;
s32 ret{}; s32 ret{};
Errno bsd_errno{}; Network::Errno bsd_errno{};
}; };
struct SendWork { struct SendWork {
void Execute(BSD* bsd); void Execute(BSD_USA* bsd);
void Response(HLERequestContext& ctx); void Response(HLERequestContext& ctx);
s32 fd; s32 fd;
u32 flags; u32 flags;
std::span<const u8> message; std::span<const u8> message;
s32 ret{}; s32 ret{};
Errno bsd_errno{}; Network::Errno bsd_errno{};
}; };
struct SendToWork { struct SendToWork {
void Execute(BSD* bsd); void Execute(BSD_USA* bsd);
void Response(HLERequestContext& ctx); void Response(HLERequestContext& ctx);
s32 fd; s32 fd;
@@ -123,7 +123,7 @@ private:
std::span<const u8> message; std::span<const u8> message;
std::span<const u8> addr; std::span<const u8> addr;
s32 ret{}; s32 ret{};
Errno bsd_errno{}; Network::Errno bsd_errno{};
}; };
void RegisterClient(HLERequestContext& ctx); void RegisterClient(HLERequestContext& ctx);
@@ -155,29 +155,29 @@ private:
template <typename Work> template <typename Work>
void ExecuteWork(HLERequestContext& ctx, Work work); void ExecuteWork(HLERequestContext& ctx, Work work);
std::pair<s32, Errno> SocketImpl(Domain domain, Type type, Protocol protocol); std::pair<s32, Network::Errno> SocketImpl(Network::Domain domain, Network::Type type, Network::Protocol protocol);
std::pair<s32, Errno> PollImpl(std::vector<u8>& write_buffer, std::span<const u8> read_buffer, s32 nfds, s32 timeout); std::pair<s32, Network::Errno> PollImpl(std::vector<u8>& write_buffer, std::span<const u8> read_buffer, s32 nfds, s32 timeout);
std::pair<s32, Errno> AcceptImpl(s32 fd, std::vector<u8>& write_buffer); std::pair<s32, Network::Errno> AcceptImpl(s32 fd, std::vector<u8>& write_buffer);
Errno BindImpl(s32 fd, std::span<const u8> addr); Network::Errno BindImpl(s32 fd, std::span<const u8> addr);
Errno ConnectImpl(s32 fd, std::span<const u8> addr); Network::Errno ConnectImpl(s32 fd, std::span<const u8> addr);
Errno GetPeerNameImpl(s32 fd, std::vector<u8>& write_buffer); Network::Errno GetPeerNameImpl(s32 fd, std::vector<u8>& write_buffer);
Errno GetSockNameImpl(s32 fd, std::vector<u8>& write_buffer); Network::Errno GetSockNameImpl(s32 fd, std::vector<u8>& write_buffer);
Errno ListenImpl(s32 fd, s32 backlog); Network::Errno ListenImpl(s32 fd, s32 backlog);
std::pair<s32, Errno> FcntlImpl(s32 fd, FcntlCmd cmd, s32 arg); std::pair<s32, Network::Errno> FcntlImpl(s32 fd, Network::FcntlCmd cmd, s32 arg);
Errno GetSockOptImpl(s32 fd, u32 level, OptName optname, std::vector<u8>& optval); Network::Errno GetSockOptImpl(s32 fd, Network::SocketLevel level, Network::OptName optname, std::vector<u8>& optval);
Errno SetSockOptImpl(s32 fd, u32 level, OptName optname, std::span<const u8> optval); Network::Errno SetSockOptImpl(s32 fd, Network::SocketLevel level, Network::OptName optname, std::span<const u8> optval);
Errno ShutdownImpl(s32 fd, s32 how); Network::Errno ShutdownImpl(s32 fd, s32 how);
std::pair<s32, Errno> RecvImpl(s32 fd, u32 flags, std::vector<u8>& message); std::pair<s32, Network::Errno> RecvImpl(s32 fd, u32 flags, std::vector<u8>& message);
std::pair<s32, Errno> RecvFromImpl(s32 fd, u32 flags, std::vector<u8>& message, std::pair<s32, Network::Errno> RecvFromImpl(s32 fd, u32 flags, std::vector<u8>& message,
std::vector<u8>& addr); std::vector<u8>& addr);
std::pair<s32, Errno> SendImpl(s32 fd, u32 flags, std::span<const u8> message); std::pair<s32, Network::Errno> SendImpl(s32 fd, u32 flags, std::span<const u8> message);
std::pair<s32, Errno> SendToImpl(s32 fd, u32 flags, std::span<const u8> message, std::pair<s32, Network::Errno> SendToImpl(s32 fd, u32 flags, std::span<const u8> message,
std::span<const u8> addr); std::span<const u8> addr);
s32 FindFreeFileDescriptorHandle() noexcept; s32 FindFreeFileDescriptorHandle() noexcept;
bool IsFileDescriptorValid(s32 fd) const 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<std::optional<FileDescriptor>, MAX_FD> file_descriptors{}; static inline std::array<std::optional<FileDescriptor>, MAX_FD> file_descriptors{};
+40 -44
View File
@@ -102,39 +102,39 @@ static bool IsBlockedHost(const std::string& host) {
[&host](const std::string& domain) { return host.find(domain) != std::string::npos; }); [&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 // These combinations have been verified on console (but are not
// exhaustive). // exhaustive).
switch (result) { switch (result) {
case GetAddrInfoError::SUCCESS: case Network::GetAddrInfoError::SUCCESS:
return NetDbError::Success; return NetDbError::Success;
case GetAddrInfoError::AGAIN: case Network::GetAddrInfoError::AGAIN:
return NetDbError::TryAgain; return NetDbError::TryAgain;
case GetAddrInfoError::NODATA: case Network::GetAddrInfoError::NODATA:
return NetDbError::HostNotFound; return NetDbError::HostNotFound;
case GetAddrInfoError::SERVICE: case Network::GetAddrInfoError::SERVICE:
return NetDbError::Success; return NetDbError::Success;
default: default:
return NetDbError::HostNotFound; 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 // These combinations have been verified on console (but are not
// exhaustive). // exhaustive).
switch (result) { switch (result) {
case GetAddrInfoError::SUCCESS: case Network::GetAddrInfoError::SUCCESS:
// Note: Sometimes a successful lookup sets errno to EADDRNOTAVAIL for // Note: Sometimes a successful lookup sets errno to EADDRNOTAVAIL for
// some reason, but that doesn't seem useful to implement. // some reason, but that doesn't seem useful to implement.
return Errno::SUCCESS; return Network::Errno::E_SUCCESS;
case GetAddrInfoError::AGAIN: case Network::GetAddrInfoError::AGAIN:
return Errno::SUCCESS; return Network::Errno::E_SUCCESS;
case GetAddrInfoError::NODATA: case Network::GetAddrInfoError::NODATA:
return Errno::SUCCESS; return Network::Errno::E_SUCCESS;
case GetAddrInfoError::SERVICE: case Network::GetAddrInfoError::SERVICE:
return Errno::INVAL; return Network::Errno::E_INVAL;
default: default:
return Errno::SUCCESS; return Network::Errno::E_SUCCESS;
} }
} }
@@ -155,9 +155,7 @@ static void AppendNulTerminated(std::vector<u8>& vec, std::string_view str) {
// host's gethostbyname, because it simplifies portability: e.g., getaddrinfo // host's gethostbyname, because it simplifies portability: e.g., getaddrinfo
// behaves the same on Unix and Windows, unlike gethostbyname where Windows // behaves the same on Unix and Windows, unlike gethostbyname where Windows
// doesn't implement h_errno. // doesn't implement h_errno.
static std::vector<u8> SerializeAddrInfoAsHostEnt(const std::vector<Network::AddrInfo>& vec, static std::vector<u8> SerializeAddrInfoAsHostEnt(std::span<const Network::AddrInfo> vec, std::string_view host) {
std::string_view host) {
std::vector<u8> data; std::vector<u8> data;
// h_name: use the input hostname (append nul-terminated) // h_name: use the input hostname (append nul-terminated)
AppendNulTerminated(data, host); AppendNulTerminated(data, host);
@@ -165,12 +163,12 @@ static std::vector<u8> SerializeAddrInfoAsHostEnt(const std::vector<Network::Add
Append<u32_be>(data, 0); // count of h_aliases Append<u32_be>(data, 0); // count of h_aliases
// (If the count were nonzero, the aliases would be appended as nul-terminated here.) // (If the count were nonzero, the aliases would be appended as nul-terminated here.)
Append<u16_be>(data, static_cast<u16>(Domain::INET)); // h_addrtype Append<u16_be>(data, u16(Network::Domain::INET)); // h_addrtype
Append<u16_be>(data, sizeof(Network::IPv4Address)); // h_length Append<u16_be>(data, sizeof(Network::IPv4Address)); // h_length
// h_addr_list: // h_addr_list:
size_t count = vec.size(); size_t count = vec.size();
ASSERT(count <= UINT32_MAX); ASSERT(count <= UINT32_MAX);
Append<u32_be>(data, static_cast<uint32_t>(count)); Append<u32_be>(data, u32(count));
for (const Network::AddrInfo& addrinfo : vec) { for (const Network::AddrInfo& addrinfo : vec) {
// On the Switch, this is passed through htonl despite already being // On the Switch, this is passed through htonl despite already being
// big-endian, so it ends up as little-endian. // big-endian, so it ends up as little-endian.
@@ -182,7 +180,7 @@ static std::vector<u8> SerializeAddrInfoAsHostEnt(const std::vector<Network::Add
return data; return data;
} }
static std::pair<u32, GetAddrInfoError> GetHostByNameRequestImpl(HLERequestContext& ctx) { static std::pair<u32, Network::GetAddrInfoError> GetHostByNameRequestImpl(HLERequestContext& ctx) {
struct InputParameters { struct InputParameters {
u8 use_nsd_resolve; u8 use_nsd_resolve;
u32 cancel_handle; u32 cancel_handle;
@@ -205,7 +203,7 @@ static std::pair<u32, GetAddrInfoError> GetHostByNameRequestImpl(HLERequestConte
// Prevent resolution of Nintendo servers // Prevent resolution of Nintendo servers
if (IsBlockedHost(host)) { if (IsBlockedHost(host)) {
LOG_WARNING(Network, "Resolution of hostname {} requested, returning EAI_AGAIN", 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); auto res_v = Network::GetAddressInfo(host, /*service*/ std::nullopt);
@@ -213,10 +211,10 @@ static std::pair<u32, GetAddrInfoError> GetHostByNameRequestImpl(HLERequestConte
const std::vector<u8> data = SerializeAddrInfoAsHostEnt(*res, host); const std::vector<u8> data = SerializeAddrInfoAsHostEnt(*res, host);
const u32 data_size = u32(data.size()); const u32 data_size = u32(data.size());
ctx.WriteBuffer(data, 0); ctx.WriteBuffer(data, 0);
return {data_size, GetAddrInfoError::SUCCESS}; return {data_size, Network::GetAddrInfoError::SUCCESS};
} }
auto* err = std::get_if<Network::GetAddrInfoError>(&res_v); auto* err = std::get_if<Network::GetAddrInfoError>(&res_v);
return {0, Translate(*err)}; return {0, *err};
} }
void SFDNSRES::GetHostByNameRequest(HLERequestContext& ctx) { void SFDNSRES::GetHostByNameRequest(HLERequestContext& ctx) {
@@ -224,7 +222,7 @@ void SFDNSRES::GetHostByNameRequest(HLERequestContext& ctx) {
struct OutputParameters { struct OutputParameters {
NetDbError netdb_error; NetDbError netdb_error;
Errno bsd_errno; Network::Errno bsd_errno;
u32 data_size; u32 data_size;
}; };
static_assert(sizeof(OutputParameters) == 0xc); static_assert(sizeof(OutputParameters) == 0xc);
@@ -244,7 +242,7 @@ void SFDNSRES::GetHostByNameRequestWithOptions(HLERequestContext& ctx) {
struct OutputParameters { struct OutputParameters {
u32 data_size; u32 data_size;
NetDbError netdb_error; NetDbError netdb_error;
Errno bsd_errno; Network::Errno bsd_errno;
}; };
static_assert(sizeof(OutputParameters) == 0xc); static_assert(sizeof(OutputParameters) == 0xc);
@@ -257,24 +255,23 @@ void SFDNSRES::GetHostByNameRequestWithOptions(HLERequestContext& ctx) {
}); });
} }
static std::vector<u8> SerializeAddrInfo(const std::vector<Network::AddrInfo>& vec, static std::vector<u8> SerializeAddrInfo(std::span<const Network::AddrInfo> vec, std::string_view host) {
std::string_view host) {
// Adapted from // Adapted from
// https://github.com/switchbrew/libnx/blob/c5a9a909a91657a9818a3b7e18c9b91ff0cbb6e3/nx/source/runtime/resolver.c#L190 // https://github.com/switchbrew/libnx/blob/c5a9a909a91657a9818a3b7e18c9b91ff0cbb6e3/nx/source/runtime/resolver.c#L190
std::vector<u8> data; std::vector<u8> data;
for (const Network::AddrInfo& addrinfo : vec) { for (const Network::AddrInfo& addrinfo : vec) {
// serialized addrinfo: // serialized addrinfo:
Append<u32_be>(data, 0xBEEFCAFE); // magic Append<u32_be>(data, 0xBEEFCAFE); // magic
Append<u32_be>(data, 0); // ai_flags Append<u32_be>(data, 0); // ai_flags
Append<u32_be>(data, static_cast<u32>(Translate(addrinfo.family))); // ai_family Append<u32_be>(data, u32(addrinfo.family)); // ai_family
Append<u32_be>(data, static_cast<u32>(Translate(addrinfo.socket_type))); // ai_socktype Append<u32_be>(data, u32(addrinfo.socket_type)); // ai_socktype
Append<u32_be>(data, static_cast<u32>(Translate(addrinfo.protocol))); // ai_protocol Append<u32_be>(data, u32(addrinfo.protocol)); // ai_protocol
Append<u32_be>(data, 16); // ai_addrlen Append<u32_be>(data, 16); // ai_addrlen
// ^ *not* sizeof(SerializedSockAddrIn), not that it matters since they're the same size // ^ *not* sizeof(SerializedSockAddrIn), not that it matters since they're the same size
// ai_addr: // ai_addr:
Append<u16_be>(data, static_cast<u16>(Translate(addrinfo.addr.family))); // sin_family Append<u16_be>(data, u16(addrinfo.addr.family)); // sin_family
// On the Switch, the following fields are passed through htonl despite // On the Switch, the following fields are passed through htonl despite
// already being big-endian, so they end up as little-endian. // already being big-endian, so they end up as little-endian.
Append<u16_le>(data, addrinfo.addr.portno); // sin_port Append<u16_le>(data, addrinfo.addr.portno); // sin_port
@@ -296,7 +293,7 @@ static std::vector<u8> SerializeAddrInfo(const std::vector<Network::AddrInfo>& v
return data; return data;
} }
static std::pair<u32, GetAddrInfoError> GetAddrInfoRequestImpl(HLERequestContext& ctx) { static std::pair<u32, Network::GetAddrInfoError> GetAddrInfoRequestImpl(HLERequestContext& ctx) {
struct InputParameters { struct InputParameters {
u8 use_nsd_resolve; u8 use_nsd_resolve;
u32 cancel_handle; u32 cancel_handle;
@@ -321,7 +318,7 @@ static std::pair<u32, GetAddrInfoError> GetAddrInfoRequestImpl(HLERequestContext
// Prevent resolution of Nintendo servers // Prevent resolution of Nintendo servers
if (IsBlockedHost(host)) { if (IsBlockedHost(host)) {
LOG_WARNING(Network, "Resolution of hostname {} requested, returning EAI_AGAIN", host); LOG_WARNING(Network, "Resolution of hostname {} requested, returning EAI_AGAIN", host);
return {0, GetAddrInfoError::AGAIN}; return {0, Network::GetAddrInfoError::AGAIN};
} }
std::optional<std::string> service = std::nullopt; std::optional<std::string> service = std::nullopt;
@@ -331,24 +328,23 @@ static std::pair<u32, GetAddrInfoError> GetAddrInfoRequestImpl(HLERequestContext
} }
// Serialized hints are also passed in a buffer, but are ignored for now. // Serialized hints are also passed in a buffer, but are ignored for now.
auto res_v = Network::GetAddressInfo(host, service); auto res_v = Network::GetAddressInfo(host, service);
if (auto* res = std::get_if<std::vector<Network::AddrInfo>>(&res_v)) { if (auto* res = std::get_if<std::vector<Network::AddrInfo>>(&res_v)) {
const std::vector<u8> data = SerializeAddrInfo(*res, host); const std::vector<u8> data = SerializeAddrInfo(*res, host);
const u32 data_size = u32(data.size()); const u32 data_size = u32(data.size());
ctx.WriteBuffer(data, 0); ctx.WriteBuffer(data, 0);
return {data_size, GetAddrInfoError::SUCCESS}; return {data_size, Network::GetAddrInfoError::SUCCESS};
} }
auto* err = std::get_if<Network::GetAddrInfoError>(&res_v); auto* err = std::get_if<Network::GetAddrInfoError>(&res_v);
return {0, Translate(*err)}; return {0, *err};
} }
void SFDNSRES::GetAddrInfoRequest(HLERequestContext& ctx) { void SFDNSRES::GetAddrInfoRequest(HLERequestContext& ctx) {
auto [data_size, emu_gai_err] = GetAddrInfoRequestImpl(ctx); auto [data_size, emu_gai_err] = GetAddrInfoRequestImpl(ctx);
struct OutputParameters { struct OutputParameters {
Errno bsd_errno; Network::Errno bsd_errno;
GetAddrInfoError gai_error; Network::GetAddrInfoError gai_error;
u32 data_size; u32 data_size;
}; };
static_assert(sizeof(OutputParameters) == 0xc); static_assert(sizeof(OutputParameters) == 0xc);
@@ -364,7 +360,7 @@ void SFDNSRES::GetAddrInfoRequest(HLERequestContext& ctx) {
void SFDNSRES::GetGaiStringErrorRequest(HLERequestContext& ctx) { void SFDNSRES::GetGaiStringErrorRequest(HLERequestContext& ctx) {
struct InputParameters { struct InputParameters {
GetAddrInfoError gai_errno; Network::GetAddrInfoError gai_errno;
}; };
IPC::RequestParser rp{ctx}; IPC::RequestParser rp{ctx};
auto input = rp.PopRaw<InputParameters>(); auto input = rp.PopRaw<InputParameters>();
@@ -382,9 +378,9 @@ void SFDNSRES::GetAddrInfoRequestWithOptions(HLERequestContext& ctx) {
struct OutputParameters { struct OutputParameters {
u32 data_size; u32 data_size;
GetAddrInfoError gai_error; Network::GetAddrInfoError gai_error;
NetDbError netdb_error; NetDbError netdb_error;
Errno bsd_errno; Network::Errno bsd_errno;
}; };
static_assert(sizeof(OutputParameters) == 0x10); static_assert(sizeof(OutputParameters) == 0x10);
+3 -3
View File
@@ -66,9 +66,9 @@ void LoopProcess(Core::System& system) {
server_manager->RegisterNamedService("ethc:c", std::make_shared<ETHC_C>(system)); server_manager->RegisterNamedService("ethc:c", std::make_shared<ETHC_C>(system));
server_manager->RegisterNamedService("ethc:i", std::make_shared<ETHC_I>(system)); server_manager->RegisterNamedService("ethc:i", std::make_shared<ETHC_I>(system));
server_manager->RegisterNamedService("bsd:s", std::make_shared<BSD>(system, "bsd:s", false)); server_manager->RegisterNamedService("bsd:s", std::make_shared<BSD_USA>(system, "bsd:s", false));
server_manager->RegisterNamedService("bsd:u", std::make_shared<BSD>(system, "bsd:u", true)); server_manager->RegisterNamedService("bsd:u", std::make_shared<BSD_USA>(system, "bsd:u", true));
server_manager->RegisterNamedService("bsd:a", std::make_shared<BSD>(system, "bsd:a", true)); server_manager->RegisterNamedService("bsd:a", std::make_shared<BSD_USA>(system, "bsd:a", true));
server_manager->RegisterNamedService("bsd:nu", std::make_shared<BSD_NU>(system)); server_manager->RegisterNamedService("bsd:nu", std::make_shared<BSD_NU>(system));
server_manager->RegisterNamedService("bsdcfg", std::make_shared<BSDCFG>(system, "bsdcfg")); server_manager->RegisterNamedService("bsdcfg", std::make_shared<BSDCFG>(system, "bsdcfg"));
server_manager->RegisterNamedService("ifcfg", std::make_shared<BSDCFG>(system, "ifcfg")); server_manager->RegisterNamedService("ifcfg", std::make_shared<BSDCFG>(system, "ifcfg"));
+1 -236
View File
@@ -8,6 +8,7 @@
#include "common/common_funcs.h" #include "common/common_funcs.h"
#include "common/common_types.h" #include "common/common_types.h"
#include "core/internal_network/socket_types.h"
namespace Core { namespace Core {
class System; class System;
@@ -15,242 +16,6 @@ class System;
namespace Service::Sockets { 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<u8, 4> ip;
std::array<u8, 248> zeroes;
};
static_assert(sizeof(SockAddrIn) == 0x100);
enum class PollEvents : u16 {
// Using Pascal case because IN is a macro on Windows.
In = 1 << 0,
Pri = 1 << 1,
Out = 1 << 2,
Err = 1 << 3,
Hup = 1 << 4,
Nval = 1 << 5,
RdNorm = 1 << 6,
RdBand = 1 << 7,
WrBand = 1 << 8,
};
DECLARE_ENUM_FLAG_OPERATORS(PollEvents);
struct PollFD {
s32 fd;
PollEvents events;
PollEvents revents;
};
struct Linger {
u32 onoff;
u32 linger;
};
void LoopProcess(Core::System& system); void LoopProcess(Core::System& system);
} // namespace Service::Sockets } // namespace Service::Sockets
@@ -15,388 +15,42 @@
namespace Service::Sockets { namespace Service::Sockets {
Errno Translate(Network::Errno value) { const char* Translate(Network::GetAddrInfoError error) {
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<s32, Errno> Translate(std::pair<s32, Network::Errno> 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) {
// https://android.googlesource.com/platform/bionic/+/085543106/libc/dns/net/getaddrinfo.c#254 // https://android.googlesource.com/platform/bionic/+/085543106/libc/dns/net/getaddrinfo.c#254
switch (error) { switch (error) {
case GetAddrInfoError::SUCCESS: case Network::GetAddrInfoError::SUCCESS:
return "Success"; return "Success";
case GetAddrInfoError::ADDRFAMILY: case Network::GetAddrInfoError::ADDRFAMILY:
return "Address family for hostname not supported"; return "Address family for hostname not supported";
case GetAddrInfoError::AGAIN: case Network::GetAddrInfoError::AGAIN:
return "Temporary failure in name resolution"; return "Temporary failure in name resolution";
case GetAddrInfoError::BADFLAGS: case Network::GetAddrInfoError::BADFLAGS:
return "Invalid value for ai_flags"; return "Invalid value for ai_flags";
case GetAddrInfoError::FAIL: case Network::GetAddrInfoError::FAIL:
return "Non-recoverable failure in name resolution"; return "Non-recoverable failure in name resolution";
case GetAddrInfoError::FAMILY: case Network::GetAddrInfoError::FAMILY:
return "ai_family not supported"; return "ai_family not supported";
case GetAddrInfoError::MEMORY: case Network::GetAddrInfoError::MEMORY:
return "Memory allocation failure"; return "Memory allocation failure";
case GetAddrInfoError::NODATA: case Network::GetAddrInfoError::NODATA:
return "No address associated with hostname"; return "No address associated with hostname";
case GetAddrInfoError::NONAME: case Network::GetAddrInfoError::NONAME:
return "hostname nor servname provided, or not known"; return "hostname nor servname provided, or not known";
case GetAddrInfoError::SERVICE: case Network::GetAddrInfoError::SERVICE:
return "servname not supported for ai_socktype"; return "servname not supported for ai_socktype";
case GetAddrInfoError::SOCKTYPE: case Network::GetAddrInfoError::SOCKTYPE:
return "ai_socktype not supported"; return "ai_socktype not supported";
case GetAddrInfoError::SYSTEM: case Network::GetAddrInfoError::SYSTEM:
return "System error returned in errno"; return "System error returned in errno";
case GetAddrInfoError::BADHINTS: case Network::GetAddrInfoError::BADHINTS:
return "Invalid value for hints"; return "Invalid value for hints";
case GetAddrInfoError::PROTOCOL: case Network::GetAddrInfoError::PROTOCOL:
return "Resolved protocol is unknown"; return "Resolved protocol is unknown";
case GetAddrInfoError::OVERFLOW_: case Network::GetAddrInfoError::OVERFLOW_:
return "Argument buffer overflow"; return "Argument buffer overflow";
default: default:
return "Unknown error"; 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<u16>(value.portno >> 8 | value.portno << 8),
};
}
SockAddrIn Translate(Network::SockAddrIn value) {
return {
.len = 16,
.family = static_cast<u8>(Translate(value.family)),
.portno = static_cast<u16>(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 } // namespace Service::Sockets
@@ -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-FileCopyrightText: Copyright 2020 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@@ -11,49 +14,7 @@
namespace Service::Sockets { 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<s32, Errno> Translate(std::pair<s32, Network::Errno> value);
/// Translate abstract getaddrinfo error to guest getaddrinfo error
GetAddrInfoError Translate(Network::GetAddrInfoError value);
/// Translate guest error to string /// Translate guest error to string
const char* Translate(GetAddrInfoError value); const char* Translate(Network::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);
} // namespace Service::Sockets } // namespace Service::Sockets
+2 -2
View File
@@ -132,7 +132,7 @@ public:
auto bsd = system.ServiceManager().GetService<Service::Sockets::BSD>("bsd:u"); auto bsd = system.ServiceManager().GetService<Service::Sockets::BSD>("bsd:u");
if (bsd) { if (bsd) {
auto err = bsd->CloseImpl(fd); auto err = bsd->CloseImpl(fd);
if (err != Service::Sockets::Errno::SUCCESS) { if (err != Network::Errno::E_SUCCESS) {
LOG_ERROR(Service_SSL, "Failed to close duplicated socket: {}", err); LOG_ERROR(Service_SSL, "Failed to close duplicated socket: {}", err);
} }
} }
@@ -203,7 +203,7 @@ private:
const bool non_block = mode == IoMode::NonBlocking; const bool non_block = mode == IoMode::NonBlocking;
const Network::Errno error = socket->SetNonBlock(non_block); const Network::Errno error = socket->SetNonBlock(non_block);
if (error != Network::Errno::SUCCESS) { if (error != Network::Errno::E_SUCCESS) {
LOG_ERROR(Service_SSL, "Failed to set native socket non-block flag to {}", non_block); LOG_ERROR(Service_SSL, "Failed to set native socket non-block flag to {}", non_block);
} }
return ResultSuccess; return ResultSuccess;
@@ -290,10 +290,10 @@ public:
BIO_clear_retry_flags(bio); BIO_clear_retry_flags(bio);
auto [actual, err] = self->socket->Send({reinterpret_cast<const u8*>(buf), len}, 0); auto [actual, err] = self->socket->Send({reinterpret_cast<const u8*>(buf), len}, 0);
switch (err) { switch (err) {
case Network::Errno::SUCCESS: case Network::Errno::E_SUCCESS:
*actual_p = actual; *actual_p = actual;
return 1; return 1;
case Network::Errno::AGAIN: case Network::Errno::E_AGAIN:
BIO_set_flags(bio, BIO_FLAGS_WRITE | BIO_FLAGS_SHOULD_RETRY); BIO_set_flags(bio, BIO_FLAGS_WRITE | BIO_FLAGS_SHOULD_RETRY);
return 0; return 0;
default: default:
@@ -309,13 +309,13 @@ public:
BIO_clear_retry_flags(bio); BIO_clear_retry_flags(bio);
auto [actual, err] = self->socket->Recv(0, {reinterpret_cast<u8*>(buf), len}); auto [actual, err] = self->socket->Recv(0, {reinterpret_cast<u8*>(buf), len});
switch (err) { switch (err) {
case Network::Errno::SUCCESS: case Network::Errno::E_SUCCESS:
*actual_p = actual; *actual_p = actual;
if (actual == 0) { if (actual == 0) {
self->got_read_eof = true; self->got_read_eof = true;
} }
return actual ? 1 : 0; return actual ? 1 : 0;
case Network::Errno::AGAIN: case Network::Errno::E_AGAIN:
BIO_set_flags(bio, BIO_FLAGS_READ | BIO_FLAGS_SHOULD_RETRY); BIO_set_flags(bio, BIO_FLAGS_READ | BIO_FLAGS_SHOULD_RETRY);
return 0; return 0;
default: default:
@@ -146,11 +146,11 @@ public:
const auto read_span = std::span(ciphertext_read_buf).subspan(offset, fill_size); const auto read_span = std::span(ciphertext_read_buf).subspan(offset, fill_size);
const auto [actual, err] = socket->Recv(0, read_span); const auto [actual, err] = socket->Recv(0, read_span);
switch (err) { switch (err) {
case Network::Errno::SUCCESS: case Network::Errno::E_SUCCESS:
ASSERT(static_cast<size_t>(actual) <= fill_size); ASSERT(static_cast<size_t>(actual) <= fill_size);
ciphertext_read_buf.resize(offset + actual); ciphertext_read_buf.resize(offset + actual);
return ResultSuccess; return ResultSuccess;
case Network::Errno::AGAIN: case Network::Errno::E_AGAIN:
ciphertext_read_buf.resize(offset); ciphertext_read_buf.resize(offset);
return ResultWouldBlock; return ResultWouldBlock;
default: default:
@@ -165,12 +165,12 @@ public:
while (!ciphertext_write_buf.empty()) { while (!ciphertext_write_buf.empty()) {
const auto [actual, err] = socket->Send(ciphertext_write_buf, 0); const auto [actual, err] = socket->Send(ciphertext_write_buf, 0);
switch (err) { switch (err) {
case Network::Errno::SUCCESS: case Network::Errno::E_SUCCESS:
ASSERT(static_cast<size_t>(actual) <= ciphertext_write_buf.size()); ASSERT(static_cast<size_t>(actual) <= ciphertext_write_buf.size());
ciphertext_write_buf.erase(ciphertext_write_buf.begin(), ciphertext_write_buf.erase(ciphertext_write_buf.begin(),
ciphertext_write_buf.begin() + actual); ciphertext_write_buf.begin() + actual);
break; break;
case Network::Errno::AGAIN: case Network::Errno::E_AGAIN:
return ResultWouldBlock; return ResultWouldBlock;
default: default:
LOG_ERROR(Service_SSL, "Socket send returned Network::Errno {}", err); LOG_ERROR(Service_SSL, "Socket send returned Network::Errno {}", err);
@@ -195,7 +195,7 @@ public:
LOG_CRITICAL(Service_SSL, "op={}, offset={} actual={}/{} err={}", is_read, offset, LOG_CRITICAL(Service_SSL, "op={}, offset={} actual={}/{} err={}", is_read, offset,
actual, cur.size(), static_cast<s32>(err)); actual, cur.size(), static_cast<s32>(err));
switch (err) { switch (err) {
case Network::Errno::SUCCESS: case Network::Errno::E_SUCCESS:
offset += actual; offset += actual;
if (actual == 0) { if (actual == 0) {
ASSERT(is_read); ASSERT(is_read);
@@ -203,7 +203,7 @@ public:
return errSecEndOfData; return errSecEndOfData;
} }
break; break;
case Network::Errno::AGAIN: case Network::Errno::E_AGAIN:
*dataLength = offset; *dataLength = offset;
return errSSLWouldBlock; return errSSLWouldBlock;
default: default:
+2 -2
View File
@@ -7,7 +7,7 @@
#pragma once #pragma once
#include <memory> #include <memory>
#include <ankerl/unordered_dense.h> #include "common/container/unordered_map.h"
#include "common/common_types.h" #include "common/common_types.h"
#include "common/polyfill_thread.h" #include "common/polyfill_thread.h"
@@ -49,7 +49,7 @@ private:
private: private:
Core::System& m_system; Core::System& m_system;
Container& m_container; Container& m_container;
ankerl::unordered_dense::map<u64, VsyncManager> m_vsync_managers; ::Common::unordered_map<u64, VsyncManager> m_vsync_managers;
std::shared_ptr<Core::Timing::EventType> m_event; std::shared_ptr<Core::Timing::EventType> m_event;
Common::Event m_signal; Common::Event m_signal;
std::jthread m_thread; std::jthread m_thread;
+3 -2
View File
@@ -1,10 +1,11 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project // SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
#pragma once #pragma once
#include <atomic> #include <atomic>
#include <common/socket_types.h>
#include <mutex> #include <mutex>
#include "core/internal_network/socket_types.h"
namespace Network { namespace Network {
File diff suppressed because it is too large Load Diff
+9 -63
View File
@@ -13,7 +13,7 @@
#include "common/common_funcs.h" #include "common/common_funcs.h"
#include "common/common_types.h" #include "common/common_types.h"
#include "common/socket_types.h" #include "core/internal_network/socket_types.h"
#ifdef _WIN32 #ifdef _WIN32
#include <winsock2.h> #include <winsock2.h>
@@ -31,68 +31,10 @@ namespace Network {
class SocketBase; class SocketBase;
class Socket; class Socket;
/// Error code for network functions struct HostPollFD {
enum class Errno { SocketBase* socket = nullptr;
SUCCESS, Network::PollEvents events = {};
BADF, Network::PollEvents revents = {};
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 {
SocketBase* socket;
PollEvents events;
PollEvents revents;
}; };
class NetworkInstance { class NetworkInstance {
@@ -101,6 +43,10 @@ public:
~NetworkInstance(); ~NetworkInstance();
}; };
sockaddr_in TranslateFromSockAddrIn(Network::SockAddrIn input);
Network::SockAddrIn TranslateToSockAddrIn(sockaddr_in input);
s32 TranslateMsgOptToNative(s32 flags);
void CancelPendingSocketOperations(); void CancelPendingSocketOperations();
void RestartSocketOperations(); void RestartSocketOperations();
@@ -46,7 +46,7 @@ namespace Network {
#ifdef _WIN32 #ifdef _WIN32
std::vector<Network::NetworkInterface> GetAvailableNetworkInterfaces() { std::vector<NetworkInterface> GetAvailableNetworkInterfaces() {
ULONG buf_size = 0; ULONG buf_size = 0;
if (GetAdaptersAddresses( if (GetAdaptersAddresses(
@@ -66,7 +66,7 @@ std::vector<Network::NetworkInterface> GetAvailableNetworkInterfaces() {
return {}; return {};
} }
std::vector<Network::NetworkInterface> result; std::vector<NetworkInterface> result;
for (auto* a = addrs; a; a = a->Next) { for (auto* a = addrs; a; a = a->Next) {
@@ -89,7 +89,7 @@ std::vector<Network::NetworkInterface> GetAvailableNetworkInterfaces() {
gw = reinterpret_cast<sockaddr_in*>(a->FirstGatewayAddress->Address.lpSockaddr) gw = reinterpret_cast<sockaddr_in*>(a->FirstGatewayAddress->Address.lpSockaddr)
->sin_addr; ->sin_addr;
result.emplace_back(Network::NetworkInterface{ result.emplace_back(NetworkInterface{
.name = Common::UTF16ToUTF8(std::wstring{a->FriendlyName}), .name = Common::UTF16ToUTF8(std::wstring{a->FriendlyName}),
.ip_address = ip, .ip_address = ip,
.subnet_mask = mask, .subnet_mask = mask,
@@ -103,7 +103,7 @@ std::vector<Network::NetworkInterface> GetAvailableNetworkInterfaces() {
#else #else
std::vector<Network::NetworkInterface> GetAvailableNetworkInterfaces() { std::vector<NetworkInterface> GetAvailableNetworkInterfaces() {
#if defined(__ANDROID__) || defined(__linux__) #if defined(__ANDROID__) || defined(__linux__)
struct ifaddrs* ifaddr = nullptr; struct ifaddrs* ifaddr = nullptr;
if (getifaddrs(&ifaddr) != 0) { if (getifaddrs(&ifaddr) != 0) {
@@ -135,7 +135,7 @@ std::vector<Network::NetworkInterface> GetAvailableNetworkInterfaces() {
LOG_WARNING(Network, "\"/proc/net/route\" not found - using gateway 0"); LOG_WARNING(Network, "\"/proc/net/route\" not found - using gateway 0");
} }
#endif #endif
std::vector<Network::NetworkInterface> ifaces; std::vector<NetworkInterface> ifaces;
for (auto ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next) { for (auto ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next) {
if (ifa->ifa_addr == nullptr || ifa->ifa_netmask == nullptr /* Have a netmask and address */ 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 */ || ifa->ifa_addr->sa_family != AF_INET /* Must be of kind AF_INET */
@@ -149,7 +149,7 @@ std::vector<Network::NetworkInterface> GetAvailableNetworkInterfaces() {
}); });
in_addr gw; // Solaris defines s_addr as a macro, can't use special C++ shenanigans here 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; gw.s_addr = it != routes.end() ? it->gateway : 0;
ifaces.emplace_back(Network::NetworkInterface{ ifaces.emplace_back(NetworkInterface{
.name = ifa->ifa_name, .name = ifa->ifa_name,
.ip_address = std::bit_cast<struct sockaddr_in>(*ifa->ifa_addr).sin_addr, .ip_address = std::bit_cast<struct sockaddr_in>(*ifa->ifa_addr).sin_addr,
.subnet_mask = std::bit_cast<struct sockaddr_in>(*ifa->ifa_netmask).sin_addr, .subnet_mask = std::bit_cast<struct sockaddr_in>(*ifa->ifa_netmask).sin_addr,
@@ -159,7 +159,7 @@ std::vector<Network::NetworkInterface> GetAvailableNetworkInterfaces() {
freeifaddrs(ifaddr); freeifaddrs(ifaddr);
return ifaces; return ifaces;
#elif defined(__FreeBSD__) #elif defined(__FreeBSD__)
std::vector<Network::NetworkInterface> ifaces; std::vector<NetworkInterface> ifaces;
int fd = ::socket(PF_ROUTE, SOCK_RAW, AF_UNSPEC); int fd = ::socket(PF_ROUTE, SOCK_RAW, AF_UNSPEC);
if (fd < 0) { if (fd < 0) {
LOG_ERROR(Network, "socket: {}", std::strerror(errno)); LOG_ERROR(Network, "socket: {}", std::strerror(errno));
@@ -191,7 +191,7 @@ std::vector<Network::NetworkInterface> GetAvailableNetworkInterfaces() {
size_t msglen = rtm->rtm_msglen - sizeof(*ifm); size_t msglen = rtm->rtm_msglen - sizeof(*ifm);
char const* p = (char const*)(ifm + 1); char const* p = (char const*)(ifm + 1);
Network::NetworkInterface iface{}; NetworkInterface iface{};
for (size_t i = 0; i < RTAX_MAX; i++) for (size_t i = 0; i < RTAX_MAX; i++)
if ((ifm->ifm_addrs & (1 << i)) != 0) { if ((ifm->ifm_addrs & (1 << i)) != 0) {
struct sockaddr const* sa = reinterpret_cast<struct sockaddr const*>(p); struct sockaddr const* sa = reinterpret_cast<struct sockaddr const*>(p);
@@ -220,7 +220,7 @@ std::vector<Network::NetworkInterface> GetAvailableNetworkInterfaces() {
#endif // _WIN32 #endif // _WIN32
std::optional<Network::NetworkInterface> GetSelectedNetworkInterface() { std::optional<NetworkInterface> GetSelectedNetworkInterface() {
auto const& sel_if = Settings::values.network_interface.GetValue(); auto const& sel_if = Settings::values.network_interface.GetValue();
if (auto const ifaces = Network::GetAvailableNetworkInterfaces(); ifaces.size() > 0) { if (auto const ifaces = Network::GetAvailableNetworkInterfaces(); ifaces.size() > 0) {
if (sel_if.empty()) if (sel_if.empty())
+277
View File
@@ -0,0 +1,277 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include <algorithm>
#include <cerrno>
#include <chrono>
#include <mutex>
#include <thread>
#ifdef __unix__
#include <spawn.h>
#include <sys/wait.h>
#include <unistd.h>
#endif
#include "common/assert.h"
#include "common/logging.h"
#include "core/internal_network/socket_icmp.h"
extern "C" {
extern char **environ;
}
namespace Network {
namespace {
u16 ComputeChecksum(std::span<const u8> data) {
u32 sum = 0;
for (size_t i = 0; i < data.size(); i += 2) {
u32 value = (u32(data[i + 0]) << 8ull) | u32(data[i + 1]); //big endian
sum += value;
}
if (data.size() % 2 != 0){
sum += u16(data[data.size() - 1]) << 8;
}
while ((sum >> 16) != 0)
sum = (sum & 0xffff) + (sum >> 16);
return (~sum) & 0xffff;
}
}
IcmpSocket::~IcmpSocket() {
if (fd == INVALID_SOCKET) {
return;
}
fd = INVALID_SOCKET;
}
Errno IcmpSocket::SetSockOpt(Network::SocketLevel level, Network::OptName optname, std::span<const u8> optval) {
LOG_WARNING(Network, "(stubbed) level={},optname={},optval={}", level, optname, optval.size());
if (optname == Network::OptName::RCVTIMEO) {
if (optval.size() < sizeof(Network::Timeval))
return Errno::E_INVAL;
std::memcpy(&rcv_timeo, optval.data(), sizeof(rcv_timeo));
}
return Errno::E_SUCCESS;
}
Errno IcmpSocket::Initialize(Domain domain, Type type, Protocol socket_protocol) {
return Errno::E_SUCCESS;
}
std::pair<IcmpSocket::AcceptResult, Errno> IcmpSocket::Accept() {
LOG_WARNING(Network, "(stubbed) called");
return {AcceptResult{}, Errno::E_SUCCESS};
}
Errno IcmpSocket::Connect(Network::SockAddrIn addr_in) {
LOG_WARNING(Network, "(stubbed) called");
connected_addr = addr_in;
return Errno::E_SUCCESS;
}
std::pair<Network::SockAddrIn, Errno> IcmpSocket::GetPeerName() {
LOG_WARNING(Network, "(stubbed) called");
return {Network::SockAddrIn{}, Errno::E_SUCCESS};
}
std::pair<Network::SockAddrIn, Errno> IcmpSocket::GetSockName() {
LOG_WARNING(Network, "(stubbed) called");
return {Network::SockAddrIn{}, Errno::E_SUCCESS};
}
Errno IcmpSocket::Bind(Network::SockAddrIn addr) {
LOG_WARNING(Network, "(stubbed) called");
return Errno::E_SUCCESS;
}
Errno IcmpSocket::Listen(s32 backlog) {
LOG_WARNING(Network, "(stubbed) called");
return Errno::E_SUCCESS;
}
Errno IcmpSocket::Shutdown(ShutdownHow how) {
LOG_WARNING(Network, "(stubbed) called");
return Errno::E_SUCCESS;
}
std::pair<s32, Errno> IcmpSocket::Recv(int flags, std::span<u8> message) {
LOG_DEBUG(Network, "(stubbed) called");
return connected_addr.has_value()
? RecvFrom(flags, message, nullptr)
: std::make_pair(s32(0), Errno::E_NOTCONN);
}
std::pair<s32, Errno> IcmpSocket::RecvFrom(int flags, std::span<u8> message, Network::SockAddrIn* addr) {
LOG_DEBUG(Network, "(stubbed) called");
ASSERT(flags == 0);
ASSERT(message.size() < std::size_t((std::numeric_limits<int>::max)()));
#if !defined(__OPENORBIS__) && (defined(__FreeBSD__) || defined(__linux__))
const auto rcv_timeout_ms = (s64(rcv_timeo.tv_sec) * 1000) + (s64(rcv_timeo.tv_usec) / 1000);
const auto timestamp = std::chrono::steady_clock::now();
while (true) {
{
std::lock_guard guard(pings_mutex);
// find ping process that is finished running
for (auto it = pings.begin(); it != pings.end();) {
pid_t result = waitpid(it->ping_pid, &it->ping_status, WNOHANG);
// ping process is still running, go to next
if (result != it->ping_pid) {
++it;
continue;
}
// ping process is finished, remove and handle it
it = pings.erase(it);
if (it->ping_status == 0) {
if (addr) {
addr->family = it->family;
addr->ip = it->ip;
addr->portno = it->portno;
addr->len = 16;
addr->zeroes = {};
}
std::array<u8, 8> data{
0,
0,
0, //checksum
0,
it->seq_ident[0],
it->seq_ident[1],
it->seq_ident[2],
it->seq_ident[3]
};
auto const csum = ComputeChecksum(std::span<const u8>{data.begin(), data.end()});
data[2] = u8(csum >> 8); //hi
data[3] = u8(csum); //lo
auto const n = std::min(data.size(), message.size());
std::copy(data.begin(), data.begin() + n, message.begin());
return {s32(n), Errno::E_SUCCESS};
}
}
}
if (!blocking)
return {-1, Errno::E_AGAIN};
const auto time_diff = std::chrono::steady_clock::now() - timestamp;
const auto time_diff_ms = std::chrono::duration_cast<std::chrono::milliseconds>(time_diff).count();
if (time_diff_ms > rcv_timeout_ms)
return {-1, Errno::E_TIMEDOUT};
std::this_thread::yield();
}
#endif
return {-1, Errno::E_INVAL};
}
std::pair<s32, Errno> IcmpSocket::Send(std::span<const u8> message, int flags) {
LOG_DEBUG(Network, "(stubbed) called");
if (connected_addr.has_value())
return SendTo(flags, message, std::addressof(connected_addr.value()));
return {s32(0), Errno::E_NOTCONN};
}
std::pair<s32, Errno> IcmpSocket::SendTo(u32 flags, std::span<const u8> message, const Network::SockAddrIn* addr) {
LOG_DEBUG(Network, "(stubbed) called");
ASSERT(message.size() < size_t((std::numeric_limits<int>::max)()));
// 0 -> 8 (IPv4), 128 (IPv6)
// 1 -> 0
// 2..4 -> checksum
// 4..6 -> ident
// 6..8 -> seq
// PLEASE DON'T KILL ME, I SWEAR THIS IS LEGITIMATELY THE BEST WAY TO DO IT
// IF YOU OPEN socket() GOOGLE WILL STRAIGHT UP IP BAN YOU AFTER 2 HOURS
#if !(defined(__OPENORBIS__) || defined(__ANDROID__)) && (defined(__FreeBSD__) || defined(__linux__))
const auto rcv_timeout_ms = (s64(rcv_timeo.tv_sec) * 1000) + (s64(rcv_timeo.tv_usec) / 1000);
if (!addr)
return {-1, Errno::E_DESTADDRREQ};
if (message.size() >= 8) {
std::string ip_str = fmt::format(
"{}.{}.{}.{}",
addr->ip[0],
addr->ip[1],
addr->ip[2],
addr->ip[3]
);
#ifdef __FreeBSD__
// ping -W option is a nonfractional int (milliseconds)
std::string timeout_str = fmt::format("{}", rcv_timeout_ms);
std::vector<char*> argv = {
const_cast<char*>("ping"),
const_cast<char*>("-c"),
const_cast<char*>("1"),
const_cast<char*>("-W"),
timeout_str.data(),
ip_str.data(),
nullptr
};
#elif defined(__linux__)
// ping -W option is a fractional float (seconds)
auto const rcv_timeout_s = f64(rcv_timeout_ms) / 1000.0;
std::string timeout_str = fmt::format("{}", rcv_timeout_s);
std::vector<char*> argv = {
const_cast<char*>("ping"),
const_cast<char*>("-c"),
const_cast<char*>("1"),
const_cast<char*>("-W"),
timeout_str.data(),
ip_str.data(),
nullptr
};
#endif
pid_t ping_pid;
// we should pass in attributes to stop stdout spam, but im too lazy to figure that out
if (posix_spawnp(&ping_pid, "ping", nullptr, nullptr, argv.data(), environ) != 0) {
LOG_ERROR(Network, "Unable to start ping process for emulated ICMP socket");
return {-1, Errno::E_INVAL};
}
std::lock_guard guard(pings_mutex);
if (pings.size() >= pings.max_size())
pings.erase(pings.begin());
pings.push_back(PingProcessData{
.ip = addr->ip,
.portno = addr->portno,
.ping_pid = ping_pid,
.ping_status = 0,
.seq_ident = {
message[4],
message[5],
message[6],
message[7]
},
.family = addr->family,
});
return {s32(message.size()), Errno::E_SUCCESS};
}
#endif
return {-1, Errno::E_INVAL};
}
Errno IcmpSocket::Close() {
LOG_DEBUG(Network, "called");
fd = INVALID_SOCKET;
return Errno::E_SUCCESS;
}
std::pair<Errno, Errno> IcmpSocket::GetPendingError() {
LOG_DEBUG(Network, "called");
return {Errno::E_SUCCESS, Errno::E_SUCCESS};
}
bool IcmpSocket::IsOpened() const {
return fd != INVALID_SOCKET;
}
void IcmpSocket::HandleProxyPacket(const ProxyPacket& packet) {
LOG_WARNING(Network, "(stubbed) called");
}
Errno IcmpSocket::SetNonBlock(bool enable) {
blocking = !enable;
return Errno::E_SUCCESS;
}
} // namespace Network
+56
View File
@@ -0,0 +1,56 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include <array>
#include <span>
#include <utility>
#include <sys/types.h>
#include <mutex>
#include <boost/container/static_vector.hpp>
#include "core/internal_network/socket_types.h"
#include "core/internal_network/sockets.h"
namespace Network {
struct PingProcessData {
IPv4Address ip;
u16 portno;
pid_t ping_pid;
pid_t ping_status;
std::array<u8, 4> seq_ident;
u8 family;
};
class IcmpSocket : public Network::SocketBase {
public:
explicit IcmpSocket() noexcept = default;
~IcmpSocket() override;
Errno Initialize(Domain domain, Type type, Protocol socket_protocol) override;
Errno Close() override;
std::pair<AcceptResult, Errno> Accept() override;
Errno Connect(Network::SockAddrIn addr_in) override;
std::pair<Network::SockAddrIn, Errno> GetPeerName() override;
std::pair<Network::SockAddrIn, Errno> GetSockName() override;
Errno Bind(Network::SockAddrIn addr) override;
Errno Listen(s32 backlog) override;
Errno Shutdown(ShutdownHow how) override;
std::pair<s32, Errno> Recv(int flags, std::span<u8> message) override;
std::pair<s32, Errno> RecvFrom(int flags, std::span<u8> message, Network::SockAddrIn* addr) override;
std::pair<s32, Errno> Send(std::span<const u8> message, int flags) override;
std::pair<s32, Errno> SendTo(u32 flags, std::span<const u8> message, const Network::SockAddrIn* addr) override;
Errno SetSockOpt(Network::SocketLevel level, Network::OptName option, std::span<const u8> value) override;
std::pair<Errno, Errno> GetPendingError() override;
bool IsOpened() const override;
void HandleProxyPacket(const ProxyPacket& packet) override;
Errno SetNonBlock(bool enable) override;
boost::container::static_vector<PingProcessData, 128> pings;
std::optional<SockAddrIn> connected_addr;
std::mutex pings_mutex;
Network::Timeval rcv_timeo;
bool blocking = true;
};
} // namespace Network
+70 -108
View File
@@ -47,71 +47,82 @@ void ProxySocket::HandleProxyPacket(const ProxyPacket& packet) {
received_packets.push(decompressed); received_packets.push(decompressed);
} }
template <typename T> Errno ProxySocket::SetNonBlock(bool enable) {
Errno ProxySocket::SetSockOpt(SOCKET fd_, int option, T value) { blocking = !enable;
LOG_DEBUG(Network, "(STUBBED) called"); return Errno::E_SUCCESS;
return Errno::SUCCESS; }
Errno ProxySocket::SetSockOpt(Network::SocketLevel level, Network::OptName optname, std::span<const u8> optval) {
LOG_DEBUG(Network, "level={},optname={},optval={}", level, optname, optval.size());
// numeric values?
if (optval.size() >= sizeof(u32)) {
u32 value;
std::memcpy(&value, optval.data(), sizeof(value));
if (optname == Network::OptName::BROADCAST)
broadcast = bool(value);
if (optname == Network::OptName::SNDTIMEO)
send_timeout = value;
if (optname == Network::OptName::RCVTIMEO)
receive_timeout = value;
}
return Errno::E_SUCCESS;
} }
Errno ProxySocket::Initialize(Domain domain, Type type, Protocol socket_protocol) { Errno ProxySocket::Initialize(Domain domain, Type type, Protocol socket_protocol) {
protocol = socket_protocol; protocol = socket_protocol;
SetSockOpt(fd, SO_TYPE, type); return Errno::E_SUCCESS;
return Errno::SUCCESS;
} }
std::pair<ProxySocket::AcceptResult, Errno> ProxySocket::Accept() { std::pair<ProxySocket::AcceptResult, Errno> ProxySocket::Accept() {
LOG_WARNING(Network, "(STUBBED) called"); LOG_WARNING(Network, "(stubbed) called");
return {AcceptResult{}, Errno::SUCCESS}; return {AcceptResult{}, Errno::E_SUCCESS};
} }
Errno ProxySocket::Connect(SockAddrIn addr_in) { Errno ProxySocket::Connect(Network::SockAddrIn addr_in) {
LOG_WARNING(Network, "(STUBBED) called"); LOG_WARNING(Network, "(stubbed) called");
return Errno::SUCCESS; return Errno::E_SUCCESS;
} }
std::pair<SockAddrIn, Errno> ProxySocket::GetPeerName() { std::pair<Network::SockAddrIn, Errno> ProxySocket::GetPeerName() {
LOG_WARNING(Network, "(STUBBED) called"); LOG_WARNING(Network, "(stubbed) called");
return {SockAddrIn{}, Errno::SUCCESS}; return {Network::SockAddrIn{}, Errno::E_SUCCESS};
} }
std::pair<SockAddrIn, Errno> ProxySocket::GetSockName() { std::pair<Network::SockAddrIn, Errno> ProxySocket::GetSockName() {
LOG_WARNING(Network, "(STUBBED) called"); LOG_WARNING(Network, "(stubbed) called");
return {SockAddrIn{}, Errno::SUCCESS}; return {Network::SockAddrIn{}, Errno::E_SUCCESS};
} }
Errno ProxySocket::Bind(SockAddrIn addr) { Errno ProxySocket::Bind(Network::SockAddrIn addr) {
if (is_bound) { if (is_bound) {
LOG_WARNING(Network, "Rebinding Socket is unimplemented!"); LOG_WARNING(Network, "Rebinding Socket is unimplemented!");
return Errno::SUCCESS; return Errno::E_SUCCESS;
} }
local_endpoint = addr; local_endpoint = addr;
is_bound = true; is_bound = true;
return Errno::E_SUCCESS;
return Errno::SUCCESS;
} }
Errno ProxySocket::Listen(s32 backlog) { Errno ProxySocket::Listen(s32 backlog) {
LOG_WARNING(Network, "(STUBBED) called"); LOG_WARNING(Network, "(stubbed) called");
return Errno::SUCCESS; return Errno::E_SUCCESS;
} }
Errno ProxySocket::Shutdown(ShutdownHow how) { Errno ProxySocket::Shutdown(ShutdownHow how) {
LOG_WARNING(Network, "(STUBBED) called"); LOG_WARNING(Network, "(stubbed) called");
return Errno::SUCCESS; return Errno::E_SUCCESS;
} }
std::pair<s32, Errno> ProxySocket::Recv(int flags, std::span<u8> message) { std::pair<s32, Errno> ProxySocket::Recv(int flags, std::span<u8> message) {
LOG_WARNING(Network, "(STUBBED) called"); LOG_WARNING(Network, "(stubbed) called");
ASSERT(flags == 0); ASSERT(flags == 0);
ASSERT(message.size() < static_cast<size_t>((std::numeric_limits<int>::max)())); ASSERT(message.size() < std::size_t((std::numeric_limits<int>::max)()));
return {s32(0), Errno::E_SUCCESS};
return {static_cast<s32>(0), Errno::SUCCESS};
} }
std::pair<s32, Errno> ProxySocket::RecvFrom(int flags, std::span<u8> message, SockAddrIn* addr) { std::pair<s32, Errno> ProxySocket::RecvFrom(int flags, std::span<u8> message, Network::SockAddrIn* addr) {
ASSERT(flags == 0); ASSERT(flags == 0);
ASSERT(message.size() < static_cast<size_t>((std::numeric_limits<int>::max)())); ASSERT(message.size() < std::size_t((std::numeric_limits<int>::max)()));
// TODO (flTobi): Verify the timeout behavior and break when connection is lost // TODO (flTobi): Verify the timeout behavior and break when connection is lost
const auto timestamp = std::chrono::steady_clock::now(); const auto timestamp = std::chrono::steady_clock::now();
@@ -128,88 +139,85 @@ std::pair<s32, Errno> ProxySocket::RecvFrom(int flags, std::span<u8> message, So
} }
if (!blocking) { if (!blocking) {
return {-1, Errno::AGAIN}; return {-1, Errno::E_AGAIN};
} }
std::this_thread::yield(); std::this_thread::yield();
const auto time_diff = std::chrono::steady_clock::now() - timestamp; const auto time_diff = std::chrono::steady_clock::now() - timestamp;
const auto time_diff_ms = const auto time_diff_ms = std::chrono::duration_cast<std::chrono::milliseconds>(time_diff).count();
std::chrono::duration_cast<std::chrono::milliseconds>(time_diff).count();
if (time_diff_ms > timeout) { if (time_diff_ms > timeout) {
return {-1, Errno::TIMEDOUT}; return {-1, Errno::E_TIMEDOUT};
} }
} }
} }
std::pair<s32, Errno> ProxySocket::ReceivePacket(int flags, std::span<u8> message, SockAddrIn* addr, std::pair<s32, Errno> ProxySocket::ReceivePacket(int flags, std::span<u8> message, Network::SockAddrIn* addr, std::size_t max_length) {
std::size_t max_length) { LOG_DEBUG(Network, "called");
ProxyPacket& packet = received_packets.front(); ProxyPacket& packet = received_packets.front();
if (addr) { 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->ip = packet.local_endpoint.ip; // The senders ip address
addr->portno = packet.local_endpoint.portno; // The senders port number addr->portno = packet.local_endpoint.portno; // The senders port number
addr->zeroes = {};
} }
bool peek = (flags & FLAG_MSG_PEEK) != 0; bool peek = (flags & u32(Network::MsgOpt::PEEK)) != 0;
std::size_t read_bytes; std::size_t read_bytes;
if (packet.data.size() > max_length) { if (packet.data.size() > max_length) {
read_bytes = max_length; read_bytes = max_length;
memcpy(message.data(), packet.data.data(), max_length); std::memcpy(message.data(), packet.data.data(), max_length);
if (protocol == Protocol::UDP) { if (protocol == Protocol::UDP) {
if (!peek) { if (!peek) {
received_packets.pop(); received_packets.pop();
} }
return {-1, Errno::MSGSIZE}; return {-1, Errno::E_MSGSIZE};
} else if (protocol == Protocol::TCP) { } else if (protocol == Protocol::TCP) {
std::vector<u8> numArray(packet.data.size() - max_length); std::vector<u8> numArray(packet.data.size() - max_length);
std::copy(packet.data.begin() + max_length, packet.data.end(), std::copy(packet.data.begin() + max_length, packet.data.end(), std::back_inserter(numArray));
std::back_inserter(numArray));
packet.data = numArray; packet.data = numArray;
} }
} else { } else {
read_bytes = packet.data.size(); read_bytes = packet.data.size();
memcpy(message.data(), packet.data.data(), read_bytes); std::memcpy(message.data(), packet.data.data(), read_bytes);
if (!peek) { if (!peek) {
received_packets.pop(); received_packets.pop();
} }
} }
return {static_cast<u32>(read_bytes), Errno::SUCCESS}; return {u32(read_bytes), Errno::E_SUCCESS};
} }
std::pair<s32, Errno> ProxySocket::Send(std::span<const u8> message, int flags) { std::pair<s32, Errno> ProxySocket::Send(std::span<const u8> message, int flags) {
LOG_WARNING(Network, "(STUBBED) called"); LOG_WARNING(Network, "(stubbed) called");
ASSERT(message.size() < static_cast<size_t>((std::numeric_limits<int>::max)())); ASSERT(message.size() < size_t((std::numeric_limits<int>::max)()));
ASSERT(flags == 0); ASSERT(flags == 0);
return {s32(0), Errno::E_SUCCESS};
return {static_cast<s32>(0), Errno::SUCCESS};
} }
void ProxySocket::SendPacket(ProxyPacket& packet) { void ProxySocket::SendPacket(ProxyPacket& packet) {
if (auto room_member = Network::GetRoomMember().lock()) { if (auto room_member = Network::GetRoomMember().lock()) {
if (room_member->IsConnected()) { if (room_member->IsConnected()) {
packet.data = Common::Compression::CompressDataZSTDDefault(packet.data.data(), packet.data = Common::Compression::CompressDataZSTDDefault(packet.data.data(), packet.data.size());
packet.data.size());
room_member->SendProxyPacket(packet); room_member->SendProxyPacket(packet);
} }
} }
} }
std::pair<s32, Errno> ProxySocket::SendTo(u32 flags, std::span<const u8> message, std::pair<s32, Errno> ProxySocket::SendTo(u32 flags, std::span<const u8> message, const Network::SockAddrIn* addr) {
const SockAddrIn* addr) { LOG_DEBUG(Network, "called");
ASSERT(flags == 0); ASSERT(flags == 0);
if (!is_bound) { if (!is_bound) {
LOG_ERROR(Network, "ProxySocket is not bound!"); LOG_ERROR(Network, "ProxySocket is not bound!");
return {static_cast<s32>(message.size()), Errno::SUCCESS}; return {s32(message.size()), Errno::E_SUCCESS};
} }
if (auto room_member = Network::GetRoomMember().lock()) { if (auto room_member = Network::GetRoomMember().lock()) {
if (!room_member->IsConnected()) { if (!room_member->IsConnected()) {
return {static_cast<s32>(message.size()), Errno::SUCCESS}; return {s32(message.size()), Errno::E_SUCCESS};
} }
} }
@@ -234,66 +242,20 @@ std::pair<s32, Errno> ProxySocket::SendTo(u32 flags, std::span<const u8> message
SendPacket(packet); SendPacket(packet);
return {static_cast<s32>(message.size()), Errno::SUCCESS}; return {s32(message.size()), Errno::E_SUCCESS};
} }
Errno ProxySocket::Close() { Errno ProxySocket::Close() {
LOG_DEBUG(Network, "called");
fd = INVALID_SOCKET; fd = INVALID_SOCKET;
closed = true; closed = true;
return Errno::SUCCESS; return Errno::E_SUCCESS;
}
Errno ProxySocket::SetLinger(bool enable, u32 linger) {
struct Linger {
u16 linger_enable;
u16 linger_time;
} values;
values.linger_enable = enable ? 1 : 0;
values.linger_time = static_cast<u16>(linger);
return SetSockOpt(fd, SO_LINGER, values);
}
Errno ProxySocket::SetReuseAddr(bool enable) {
return SetSockOpt<u32>(fd, SO_REUSEADDR, enable ? 1 : 0);
}
Errno ProxySocket::SetBroadcast(bool enable) {
broadcast = enable;
return SetSockOpt<u32>(fd, SO_BROADCAST, enable ? 1 : 0);
}
Errno ProxySocket::SetSndBuf(u32 value) {
return SetSockOpt(fd, SO_SNDBUF, value);
}
Errno ProxySocket::SetKeepAlive(bool enable) {
return Errno::SUCCESS;
}
Errno ProxySocket::SetRcvBuf(u32 value) {
return SetSockOpt(fd, SO_RCVBUF, value);
}
Errno ProxySocket::SetSndTimeo(u32 value) {
send_timeout = value;
return SetSockOpt(fd, SO_SNDTIMEO, static_cast<int>(value));
}
Errno ProxySocket::SetRcvTimeo(u32 value) {
receive_timeout = value;
return SetSockOpt(fd, SO_RCVTIMEO, static_cast<int>(value));
}
Errno ProxySocket::SetNonBlock(bool enable) {
blocking = !enable;
return Errno::SUCCESS;
} }
std::pair<Errno, Errno> ProxySocket::GetPendingError() { std::pair<Errno, Errno> ProxySocket::GetPendingError() {
LOG_DEBUG(Network, "(STUBBED) called"); LOG_DEBUG(Network, "called");
return {Errno::SUCCESS, Errno::SUCCESS}; return {Errno::E_SUCCESS, Errno::E_SUCCESS};
} }
bool ProxySocket::IsOpened() const { bool ProxySocket::IsOpened() const {
+10 -27
View File
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project // SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@@ -29,13 +29,13 @@ public:
std::pair<AcceptResult, Errno> Accept() override; std::pair<AcceptResult, Errno> Accept() override;
Errno Connect(SockAddrIn addr_in) override; Errno Connect(Network::SockAddrIn addr_in) override;
std::pair<SockAddrIn, Errno> GetPeerName() override; std::pair<Network::SockAddrIn, Errno> GetPeerName() override;
std::pair<SockAddrIn, Errno> GetSockName() override; std::pair<Network::SockAddrIn, Errno> GetSockName() override;
Errno Bind(SockAddrIn addr) override; Errno Bind(Network::SockAddrIn addr) override;
Errno Listen(s32 backlog) override; Errno Listen(s32 backlog) override;
@@ -43,9 +43,9 @@ public:
std::pair<s32, Errno> Recv(int flags, std::span<u8> message) override; std::pair<s32, Errno> Recv(int flags, std::span<u8> message) override;
std::pair<s32, Errno> RecvFrom(int flags, std::span<u8> message, SockAddrIn* addr) override; std::pair<s32, Errno> RecvFrom(int flags, std::span<u8> message, Network::SockAddrIn* addr) override;
std::pair<s32, Errno> ReceivePacket(int flags, std::span<u8> message, SockAddrIn* addr, std::pair<s32, Errno> ReceivePacket(int flags, std::span<u8> message, Network::SockAddrIn* addr,
std::size_t max_length); std::size_t max_length);
std::pair<s32, Errno> Send(std::span<const u8> message, int flags) override; std::pair<s32, Errno> Send(std::span<const u8> message, int flags) override;
@@ -53,28 +53,11 @@ public:
void SendPacket(ProxyPacket& packet); void SendPacket(ProxyPacket& packet);
std::pair<s32, Errno> SendTo(u32 flags, std::span<const u8> message, std::pair<s32, Errno> SendTo(u32 flags, std::span<const u8> message,
const SockAddrIn* addr) override; const Network::SockAddrIn* addr) override;
Errno SetLinger(bool enable, u32 linger) override;
Errno SetReuseAddr(bool enable) override;
Errno SetBroadcast(bool enable) override;
Errno SetKeepAlive(bool enable) override;
Errno SetSndBuf(u32 value) override;
Errno SetRcvBuf(u32 value) override;
Errno SetSndTimeo(u32 value) override;
Errno SetRcvTimeo(u32 value) override;
Errno SetNonBlock(bool enable) override; Errno SetNonBlock(bool enable) override;
template <typename T> Errno SetSockOpt(Network::SocketLevel level, Network::OptName option, std::span<const u8> value) override;
Errno SetSockOpt(SOCKET fd, int option, T value);
std::pair<Errno, Errno> GetPendingError() override; std::pair<Errno, Errno> GetPendingError() override;
@@ -86,7 +69,7 @@ private:
u32 send_timeout = 0; u32 send_timeout = 0;
u32 receive_timeout = 0; u32 receive_timeout = 0;
bool is_bound = false; bool is_bound = false;
SockAddrIn local_endpoint{}; Network::SockAddrIn local_endpoint{};
bool blocking = true; bool blocking = true;
std::queue<ProxyPacket> received_packets; std::queue<ProxyPacket> received_packets;
Protocol protocol; Protocol protocol;
+470
View File
@@ -0,0 +1,470 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <optional>
#include <string>
#include "common/common_types.h"
#include "common/common_funcs.h"
// Most of these structures are direct mappings of guest's
// expectations for these values, in other words, they're the
// values that HOS is expected to use AND handle.
namespace Network {
enum class Errno : u32 {
E_SUCCESS = 0,
E_PERM = 1,
E_NOENT = 2,
E_SRCH = 3,
E_INTR = 4,
E_IO = 5,
E_NXIO = 6,
E_2BIG = 7,
E_NOEXEC = 8,
E_BADF = 9,
E_CHILD = 10,
E_AGAIN = 11,
E_NOMEM = 12,
E_ACCES = 13,
E_FAULT = 14,
E_NOTBLK = 15,
E_BUSY = 16,
E_EXIST = 17,
E_XDEV = 18,
E_NODEV = 19,
E_NOTDIR = 20,
E_ISDIR = 21,
E_INVAL = 22,
E_NFILE = 23,
E_MFILE = 24,
E_NOTTY = 25,
E_TXTBSY = 26,
E_FBIG = 27,
E_NOSPC = 28,
E_SPIPE = 29,
E_ROFS = 30,
E_MLINK = 31,
E_PIPE = 32,
E_DOM = 33,
E_RANGE = 34,
E_DEADLK = 35,
E_NAMETOOLONG = 36,
E_NOLCK = 37,
E_NOSYS = 38,
E_NOTEMPTY = 39,
E_LOOP = 40,
E_NOMSG = 42,
E_IDRM = 43,
E_CHRNG = 44,
E_L2NSYNC = 45,
E_L3HLT = 46,
E_L3RST = 47,
E_LNRNG = 48,
E_UNATCH = 49,
E_NOCSI = 50,
E_L2HLT = 51,
E_BADE = 52,
E_BADR = 53,
E_XFULL = 54,
E_NOANO = 55,
E_BADRQC = 56,
E_BADSSL = 57,
E_BFONT = 59,
E_NOSTR = 60,
E_NODATA = 61,
E_TIME = 62,
E_NOSR = 63,
E_NONET = 64,
E_NOPKG = 65,
E_REMOTE = 66,
E_NOLINK = 67,
E_ADV = 68,
E_SRMNT = 69,
E_COMM = 70,
E_PROTO = 71,
E_MULTIHOP = 72,
E_DOTDOT = 73,
E_BADMSG = 74,
E_OVERFLOW = 75,
E_NOTUNUQ = 76,
E_BADFD = 77,
E_REMCHG = 78,
E_LIBACC = 79,
E_LIBBAD = 80,
E_LIBSCN = 81,
E_LIBMAX = 82,
E_LIBEXEC = 83,
E_ILSEQ = 84,
E_RESTART = 85,
E_STRPIPE = 86,
E_USERS = 87,
E_NOTSOCK = 88,
E_DESTADDRREQ = 89,
E_MSGSIZE = 90,
E_PROTOTYPE = 91,
E_NOPROTOOPT = 92,
E_PROTONOSUPPORT = 93,
E_SOCKTNOSUPPORT = 94,
E_OPNOTSUPP = 95,
E_PFNOSUPPORT = 96,
E_AFNOSUPPORT = 97,
E_ADDRINUSE = 98,
E_ADDRNOTAVAIL = 99,
E_NETDOWN = 100,
E_NETUNREACH = 101,
E_NETRESET = 102,
E_CONNABORTED = 103,
E_CONNRESET = 104,
E_NOBUFS = 105,
E_ISCONN = 106,
E_NOTCONN = 107,
E_SHUTDOWN = 108,
E_TOOMANYREFS = 109,
E_TIMEDOUT = 110,
E_CONNREFUSED = 111,
E_HOSTDOWN = 112,
E_HOSTUNREACH = 113,
E_ALREADY = 114,
E_INPROGRESS = 115,
E_STALE = 116,
E_UCLEAN = 117,
E_NOTNAM = 118,
E_NAVAIL = 119,
E_ISNAM = 120,
E_REMOTEIO = 121,
E_DQUOT = 122,
E_NOMEDIUM = 123,
E_MEDIUMTYPE = 124,
E_CANCELED = 125,
E_NOKEY = 126,
E_KEYEXPIRED = 127,
E_KEYREVOKED = 128,
E_KEYREJECTED = 129,
E_OWNERDEAD = 130,
E_NOTRECOVERABLE = 131,
E_RFKILL = 132,
E_HWPOISON = 133,
E_PROCLIM = 156,
};
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,
ICMP = 1,
TCP = 6,
UDP = 17,
CONFIG = 0xfffe,
SOCKET = 0xffff, // i.e. SOL_SOCKET
};
enum class MsgOpt : u32 {
OOB = 0x00001,
PEEK = 0x00002,
DONTROUTE = 0x00004,
EOR_ = 0x00008,
TRUNC = 0x00010,
CTRUNC = 0x00020,
WAITALL = 0x00040,
DONTWAIT = 0x00080,
EOF_ = 0x00100,
NOSIGNAL = 0x20000,
};
enum class OptName : u32 {
DEBUG = 0x0001,
ACCEPTCONN = 0x0002,
REUSEADDR = 0x0004,
KEEPALIVE = 0x0008,
DONTROUTE = 0x0010,
BROADCAST = 0x0020,
USELOOPBACK = 0x0040,
LINGER = 0x0080,
OOBINLINE = 0x0100,
REUSEPORT = 0x0200,
TIMESTAMP = 0x0400,
NOSIGPIPE = 0x0800, // at least according to libnx
ACCEPTFILER = 0x1000,
SNDBUF = 0x1001,
RCVBUF = 0x1002,
SNDTIMEO = 0x1005,
RCVTIMEO = 0x1006,
ERROR_ = 0x1007, // avoid name collision with Windows macro
ACCEPTFILTER = 0x1000,
BINTIME = 0x2000,
NO_OFFLOAD = 0x4000,
NO_DDP = 0x8000,
};
enum class TcpOptName : u32 {
NODELAY = 0x0001,
MAXSEG = 0x0002,
NOPUSH = 0x0004,
NOOPT = 0x0008,
MS5SIG = 0x0010,
INFO = 0x0020
};
enum class ShutdownHow : s32 {
RD = 0,
WR = 1,
RDWR = 2,
};
enum class FcntlCmd : s32 {
GETFL = 3,
SETFL = 4,
};
enum class FcntlFlags : u32 {
NONBLOCK = 0x004,
NONBLOCK_NX = 0x800,
// Provided for convenience
NONBLOCK_ANY = u32(NONBLOCK) | u32(NONBLOCK_NX),
};
/// Array of IPv4 address
using IPv4Address = std::array<u8, 4>;
struct SockAddrIn {
u8 len;
u8 family;
u16 portno;
IPv4Address ip;
std::array<u8, 248> zeroes;
};
static_assert(sizeof(SockAddrIn) == 0x100);
enum class PollEvents : u16 {
// Using Pascal case because IN is a macro on Windows.
IN_ = 0x0001,
PRI_ = 0x0002,
OUT_ = 0x0004,
ERR_ = 0x0008,
HUP_ = 0x0010,
NVAL = 0x0020,
RDNORM = 0x0040,
RDBAND = 0x0080,
WRBAND = 0x0100,
IGNEOF = 0x2000,
};
DECLARE_ENUM_FLAG_OPERATORS(PollEvents);
struct PollFD {
s32 fd;
Network::PollEvents events;
Network::PollEvents revents;
};
static_assert(sizeof(PollFD) == 8);
struct Linger {
s32 onoff;
s32 linger;
};
static_assert(sizeof(Linger) == 8);
struct Timeval {
u64 tv_sec;
u64 tv_usec;
};
static_assert(sizeof(Timeval) == 16);
/// @brief Cross-platform addrinfo structure (not guest)
struct AddrInfo {
Domain family;
Type socket_type;
Protocol protocol;
SockAddrIn addr;
std::optional<std::string> canon_name;
};
} // namespace Network
+19 -54
View File
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project // SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
@@ -30,7 +30,7 @@ public:
struct AcceptResult { struct AcceptResult {
std::unique_ptr<SocketBase> socket; std::unique_ptr<SocketBase> socket;
SockAddrIn sockaddr_in; Network::SockAddrIn sockaddr_in;
}; };
SocketBase() = default; SocketBase() = default;
@@ -46,13 +46,13 @@ public:
virtual std::pair<AcceptResult, Errno> Accept() = 0; virtual std::pair<AcceptResult, Errno> Accept() = 0;
virtual Errno Connect(SockAddrIn addr_in) = 0; virtual Errno Connect(Network::SockAddrIn addr_in) = 0;
virtual std::pair<SockAddrIn, Errno> GetPeerName() = 0; virtual std::pair<Network::SockAddrIn, Errno> GetPeerName() = 0;
virtual std::pair<SockAddrIn, Errno> GetSockName() = 0; virtual std::pair<Network::SockAddrIn, Errno> GetSockName() = 0;
virtual Errno Bind(SockAddrIn addr) = 0; virtual Errno Bind(Network::SockAddrIn addr) = 0;
virtual Errno Listen(s32 backlog) = 0; virtual Errno Listen(s32 backlog) = 0;
@@ -60,31 +60,16 @@ public:
virtual std::pair<s32, Errno> Recv(int flags, std::span<u8> message) = 0; virtual std::pair<s32, Errno> Recv(int flags, std::span<u8> message) = 0;
virtual std::pair<s32, Errno> RecvFrom(int flags, std::span<u8> message, SockAddrIn* addr) = 0; virtual std::pair<s32, Errno> RecvFrom(int flags, std::span<u8> message, Network::SockAddrIn* addr) = 0;
virtual std::pair<s32, Errno> Send(std::span<const u8> message, int flags) = 0; virtual std::pair<s32, Errno> Send(std::span<const u8> message, int flags) = 0;
virtual std::pair<s32, Errno> SendTo(u32 flags, std::span<const u8> message, virtual std::pair<s32, Errno> SendTo(u32 flags, std::span<const u8> message, const Network::SockAddrIn* addr) = 0;
const SockAddrIn* addr) = 0;
virtual Errno SetLinger(bool enable, u32 linger) = 0;
virtual Errno SetReuseAddr(bool enable) = 0;
virtual Errno SetKeepAlive(bool enable) = 0;
virtual Errno SetBroadcast(bool enable) = 0;
virtual Errno SetSndBuf(u32 value) = 0;
virtual Errno SetRcvBuf(u32 value) = 0;
virtual Errno SetSndTimeo(u32 value) = 0;
virtual Errno SetRcvTimeo(u32 value) = 0;
virtual Errno SetNonBlock(bool enable) = 0; virtual Errno SetNonBlock(bool enable) = 0;
virtual Errno SetSockOpt(Network::SocketLevel level, Network::OptName option, std::span<const u8> value) = 0;
virtual std::pair<Errno, Errno> GetPendingError() = 0; virtual std::pair<Errno, Errno> GetPendingError() = 0;
virtual bool IsOpened() const = 0; virtual bool IsOpened() const = 0;
@@ -95,7 +80,6 @@ public:
return fd; return fd;
} }
protected:
SOCKET fd = INVALID_SOCKET; SOCKET fd = INVALID_SOCKET;
}; };
@@ -114,13 +98,13 @@ public:
std::pair<AcceptResult, Errno> Accept() override; std::pair<AcceptResult, Errno> Accept() override;
Errno Connect(SockAddrIn addr_in) override; Errno Connect(Network::SockAddrIn addr_in) override;
std::pair<SockAddrIn, Errno> GetPeerName() override; std::pair<Network::SockAddrIn, Errno> GetPeerName() override;
std::pair<SockAddrIn, Errno> GetSockName() override; std::pair<Network::SockAddrIn, Errno> GetSockName() override;
Errno Bind(SockAddrIn addr) override; Errno Bind(Network::SockAddrIn addr) override;
Errno Listen(s32 backlog) override; Errno Listen(s32 backlog) override;
@@ -128,38 +112,19 @@ public:
std::pair<s32, Errno> Recv(int flags, std::span<u8> message) override; std::pair<s32, Errno> Recv(int flags, std::span<u8> message) override;
std::pair<s32, Errno> RecvFrom(int flags, std::span<u8> message, SockAddrIn* addr) override; std::pair<s32, Errno> RecvFrom(int flags, std::span<u8> message, Network::SockAddrIn* addr) override;
std::pair<s32, Errno> Send(std::span<const u8> message, int flags) override; std::pair<s32, Errno> Send(std::span<const u8> message, int flags) override;
std::pair<s32, Errno> SendTo(u32 flags, std::span<const u8> message, std::pair<s32, Errno> SendTo(u32 flags, std::span<const u8> message, const Network::SockAddrIn* addr) override;
const SockAddrIn* addr) override;
Errno SetLinger(bool enable, u32 linger) override;
Errno SetReuseAddr(bool enable) override;
Errno SetKeepAlive(bool enable) override;
Errno SetBroadcast(bool enable) override;
Errno SetSndBuf(u32 value) override;
Errno SetRcvBuf(u32 value) override;
Errno SetSndTimeo(u32 value) override;
Errno SetRcvTimeo(u32 value) override;
Errno SetNonBlock(bool enable) override; Errno SetNonBlock(bool enable) override;
template <typename T> Errno SetSockOpt(Network::SocketLevel level, Network::OptName option, std::span<const u8> value) override;
Errno SetSockOpt(SOCKET fd, int option, T value);
std::pair<Errno, Errno> GetPendingError() override; std::pair<Errno, Errno> GetPendingError() override;
template <typename T> Errno GetSockOpt(Network::SocketLevel level, Network::OptName optname, std::span<u8> value);
std::pair<T, Errno> GetSockOpt(SOCKET fd, int option);
bool IsOpened() const override; bool IsOpened() const override;
@@ -169,6 +134,6 @@ private:
bool is_non_blocking = false; bool is_non_blocking = false;
}; };
std::pair<s32, Errno> Poll(std::vector<PollFD>& poll_fds, s32 timeout); std::pair<s32, Errno> Poll(std::span<Network::HostPollFD> poll_fds, s32 timeout);
} // namespace Network } // namespace Network
+3 -3
View File
@@ -8,7 +8,7 @@
#include <mutex> #include <mutex>
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <ankerl/unordered_dense.h> #include "common/container/unordered_map.h"
#include <fmt/format.h> #include <fmt/format.h>
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
@@ -21,8 +21,8 @@
namespace Core::LaunchTimestampCache { namespace Core::LaunchTimestampCache {
namespace { namespace {
using CacheMap = ankerl::unordered_dense::map<u64, s64>; using CacheMap = ::Common::unordered_map<u64, s64>;
using CountMap = ankerl::unordered_dense::map<u64, u64>; using CountMap = ::Common::unordered_map<u64, u64>;
std::mutex g_mutex; std::mutex g_mutex;
CacheMap g_cache; CacheMap g_cache;
-1
View File
@@ -120,7 +120,6 @@ if (NOT Boost_FOUND)
endif() endif()
find_package(fmt 8 CONFIG) find_package(fmt 8 CONFIG)
find_package(unordered_dense REQUIRED)
if ("arm64" IN_LIST ARCHITECTURE OR DYNARMIC_TESTS) if ("arm64" IN_LIST ARCHITECTURE OR DYNARMIC_TESTS)
find_package(oaknut 2.0.1 CONFIG) find_package(oaknut 2.0.1 CONFIG)
@@ -8,7 +8,6 @@ if (NOT @BUILD_SHARED_LIBS@)
find_dependency(Boost 1.57) find_dependency(Boost 1.57)
find_dependency(fmt 9) find_dependency(fmt 9)
find_dependency(mcl 0.1.12 EXACT) find_dependency(mcl 0.1.12 EXACT)
find_dependency(unordered_dense)
if ("arm64" IN_LIST ARCHITECTURE) if ("arm64" IN_LIST ARCHITECTURE)
find_dependency(oaknut 2.0.1) find_dependency(oaknut 2.0.1)
-1
View File
@@ -387,7 +387,6 @@ set_target_properties(dynarmic PROPERTIES
target_compile_options(dynarmic PRIVATE ${DYNARMIC_CXX_FLAGS}) target_compile_options(dynarmic PRIVATE ${DYNARMIC_CXX_FLAGS})
target_link_libraries(dynarmic PRIVATE unordered_dense::unordered_dense)
target_link_libraries(dynarmic PUBLIC fmt::fmt common) target_link_libraries(dynarmic PUBLIC fmt::fmt common)
if (BOOST_NO_HEADERS) if (BOOST_NO_HEADERS)
@@ -75,7 +75,7 @@ CodePtr AddressSpace::GetOrEmit(IR::LocationDescriptor descriptor) {
return block_info.entry_point; return block_info.entry_point;
} }
void AddressSpace::InvalidateBasicBlocks(const ankerl::unordered_dense::set<IR::LocationDescriptor>& descriptors) { void AddressSpace::InvalidateBasicBlocks(const ::Common::unordered_set<IR::LocationDescriptor>& descriptors) {
UnprotectCodeMemory(); UnprotectCodeMemory();
for (const auto& descriptor : descriptors) { for (const auto& descriptor : descriptors) {
@@ -14,7 +14,8 @@
#include "common/common_types.h" #include "common/common_types.h"
#include <oaknut/code_block.hpp> #include <oaknut/code_block.hpp>
#include <oaknut/oaknut.hpp> #include <oaknut/oaknut.hpp>
#include <ankerl/unordered_dense.h> #include "common/container/unordered_map.h"
#include "common/container/unordered_set.h"
#include "dynarmic/backend/arm64/emit_arm64.h" #include "dynarmic/backend/arm64/emit_arm64.h"
#include "dynarmic/backend/arm64/fastmem.h" #include "dynarmic/backend/arm64/fastmem.h"
@@ -41,7 +42,7 @@ public:
CodePtr GetOrEmit(IR::LocationDescriptor descriptor); CodePtr GetOrEmit(IR::LocationDescriptor descriptor);
void InvalidateBasicBlocks(const ankerl::unordered_dense::set<IR::LocationDescriptor>& descriptors); void InvalidateBasicBlocks(const ::Common::unordered_set<IR::LocationDescriptor>& descriptors);
void ClearCache(); void ClearCache();
protected: protected:
@@ -76,9 +77,9 @@ protected:
// A IR::LocationDescriptor will have one current CodePtr. // A IR::LocationDescriptor will have one current CodePtr.
// However, there can be multiple other CodePtrs which are older, previously invalidated blocks. // However, there can be multiple other CodePtrs which are older, previously invalidated blocks.
std::map<CodePtr, IR::LocationDescriptor> reverse_block_entries; std::map<CodePtr, IR::LocationDescriptor> reverse_block_entries;
ankerl::unordered_dense::map<IR::LocationDescriptor, CodePtr> block_entries; ::Common::unordered_map<IR::LocationDescriptor, CodePtr> block_entries;
ankerl::unordered_dense::map<CodePtr, EmittedBlockInfo> block_infos; ::Common::unordered_map<CodePtr, EmittedBlockInfo> block_infos;
ankerl::unordered_dense::map<IR::LocationDescriptor, ankerl::unordered_dense::set<CodePtr>> block_references; ::Common::unordered_map<IR::LocationDescriptor, ::Common::unordered_set<CodePtr>> block_references;
ExceptionHandler exception_handler; ExceptionHandler exception_handler;
FastmemManager fastmem_manager; FastmemManager fastmem_manager;
@@ -14,7 +14,7 @@
#include <vector> #include <vector>
#include "common/common_types.h" #include "common/common_types.h"
#include <ankerl/unordered_dense.h> #include "common/container/unordered_map.h"
#include "dynarmic/backend/arm64/fastmem.h" #include "dynarmic/backend/arm64/fastmem.h"
#include "dynarmic/interface/A32/coprocessor.h" #include "dynarmic/interface/A32/coprocessor.h"
@@ -105,8 +105,8 @@ struct EmittedBlockInfo {
CodePtr entry_point; CodePtr entry_point;
std::size_t size; std::size_t size;
std::vector<Relocation> relocations; std::vector<Relocation> relocations;
ankerl::unordered_dense::map<IR::LocationDescriptor, std::vector<BlockRelocation>> block_relocations; ::Common::unordered_map<IR::LocationDescriptor, std::vector<BlockRelocation>> block_relocations;
ankerl::unordered_dense::map<std::ptrdiff_t, FastmemPatchInfo> fastmem_patch_info; ::Common::unordered_map<std::ptrdiff_t, FastmemPatchInfo> fastmem_patch_info;
}; };
struct EmitConfig { struct EmitConfig {
@@ -10,7 +10,7 @@
#include <cstddef> #include <cstddef>
#include <tuple> #include <tuple>
#include <ankerl/unordered_dense.h> #include "common/container/unordered_set.h"
#include "dynarmic/mcl/bit.hpp" #include "dynarmic/mcl/bit.hpp"
#include "common/common_types.h" #include "common/common_types.h"
@@ -59,7 +59,7 @@ public:
private: private:
ExceptionHandler& exception_handler; ExceptionHandler& exception_handler;
ankerl::unordered_dense::set<DoNotFastmemMarker, DoNotFastmemMarkerHash> do_not_fastmem; ::Common::unordered_set<DoNotFastmemMarker, DoNotFastmemMarkerHash> do_not_fastmem;
}; };
} // namespace Dynarmic::Backend::Arm64 } // namespace Dynarmic::Backend::Arm64
@@ -18,7 +18,8 @@
#include "common/common_types.h" #include "common/common_types.h"
#include "dynarmic/mcl/is_instance_of_template.hpp" #include "dynarmic/mcl/is_instance_of_template.hpp"
#include <oaknut/oaknut.hpp> #include <oaknut/oaknut.hpp>
#include <ankerl/unordered_dense.h> #include "common/container/unordered_map.h"
#include "common/container/unordered_set.h"
#include "dynarmic/backend/arm64/stack_layout.h" #include "dynarmic/backend/arm64/stack_layout.h"
#include "dynarmic/ir/cond.h" #include "dynarmic/ir/cond.h"
@@ -336,7 +337,7 @@ private:
std::array<HostLocInfo, SpillCount> spills; std::array<HostLocInfo, SpillCount> spills;
mutable std::size_t alloc_candidate_index = 0; mutable std::size_t alloc_candidate_index = 0;
ankerl::unordered_dense::set<const IR::Inst*> defined_insts; ::Common::unordered_set<const IR::Inst*> defined_insts;
}; };
template<typename T> template<typename T>
@@ -11,13 +11,13 @@
#include <boost/icl/interval_map.hpp> #include <boost/icl/interval_map.hpp>
#include <boost/icl/interval_set.hpp> #include <boost/icl/interval_set.hpp>
#include "common/common_types.h" #include "common/common_types.h"
#include <ankerl/unordered_dense.h> #include "common/container/unordered_set.h"
namespace Dynarmic::Backend { namespace Dynarmic::Backend {
template<typename P> template<typename P>
void BlockRangeInformation<P>::AddRange(boost::icl::discrete_interval<P> range, IR::LocationDescriptor location) { void BlockRangeInformation<P>::AddRange(boost::icl::discrete_interval<P> range, IR::LocationDescriptor location) {
block_ranges.add(std::make_pair(range, ankerl::unordered_dense::set<IR::LocationDescriptor>{location})); block_ranges.add(std::make_pair(range, ::Common::unordered_set<IR::LocationDescriptor>{location}));
} }
template<typename P> template<typename P>
@@ -26,8 +26,8 @@ void BlockRangeInformation<P>::ClearCache() {
} }
template<typename P> template<typename P>
ankerl::unordered_dense::set<IR::LocationDescriptor> BlockRangeInformation<P>::InvalidateRanges(const boost::icl::interval_set<P>& ranges) { ::Common::unordered_set<IR::LocationDescriptor> BlockRangeInformation<P>::InvalidateRanges(const boost::icl::interval_set<P>& ranges) {
ankerl::unordered_dense::set<IR::LocationDescriptor> erase_locations; ::Common::unordered_set<IR::LocationDescriptor> erase_locations;
for (auto invalidate_interval : ranges) { for (auto invalidate_interval : ranges) {
auto pair = block_ranges.equal_range(invalidate_interval); auto pair = block_ranges.equal_range(invalidate_interval);
for (auto it = pair.first; it != pair.second; ++it) for (auto it = pair.first; it != pair.second; ++it)
@@ -12,7 +12,8 @@
#include <boost/icl/interval_map.hpp> #include <boost/icl/interval_map.hpp>
#include <boost/icl/interval_set.hpp> #include <boost/icl/interval_set.hpp>
#include <ankerl/unordered_dense.h> #include "common/container/unordered_map.h"
#include "common/container/unordered_set.h"
#include "dynarmic/ir/location_descriptor.h" #include "dynarmic/ir/location_descriptor.h"
@@ -23,8 +24,8 @@ class BlockRangeInformation {
public: public:
void AddRange(boost::icl::discrete_interval<P> range, IR::LocationDescriptor location); void AddRange(boost::icl::discrete_interval<P> range, IR::LocationDescriptor location);
void ClearCache(); void ClearCache();
ankerl::unordered_dense::set<IR::LocationDescriptor> InvalidateRanges(const boost::icl::interval_set<P>& ranges); ::Common::unordered_set<IR::LocationDescriptor> InvalidateRanges(const boost::icl::interval_set<P>& ranges);
boost::icl::interval_map<P, ankerl::unordered_dense::set<IR::LocationDescriptor>> block_ranges; boost::icl::interval_map<P, ::Common::unordered_set<IR::LocationDescriptor>> block_ranges;
}; };
} // namespace Dynarmic::Backend } // namespace Dynarmic::Backend
@@ -17,7 +17,7 @@
#include <optional> #include <optional>
#include <shared_mutex> #include <shared_mutex>
#include <ankerl/unordered_dense.h> #include "common/container/unordered_map.h"
#include <fmt/format.h> #include <fmt/format.h>
#include <sys/mman.h> #include <sys/mman.h>
@@ -55,7 +55,7 @@ class SigHandler {
}); });
} }
ankerl::unordered_dense::map<u64, CodeBlockInfo> code_block_infos; ::Common::unordered_map<u64, CodeBlockInfo> code_block_infos;
std::shared_mutex code_block_infos_mutex; std::shared_mutex code_block_infos_mutex;
struct sigaction old_sa_segv; struct sigaction old_sa_segv;
struct sigaction old_sa_bus; struct sigaction old_sa_bus;
@@ -4,7 +4,7 @@
#pragma once #pragma once
#include "dynarmic/backend/loongarch64/lagoon_cpp.h" #include "dynarmic/backend/loongarch64/lagoon_cpp.h"
#include <ankerl/unordered_dense.h> #include "common/container/unordered_map.h"
#include "dynarmic/backend/loongarch64/code_block.h" #include "dynarmic/backend/loongarch64/code_block.h"
#include "dynarmic/backend/loongarch64/emit_loongarch64.h" #include "dynarmic/backend/loongarch64/emit_loongarch64.h"
@@ -53,8 +53,8 @@ private:
const A32::UserConfig conf; const A32::UserConfig conf;
CodeBlock cb; CodeBlock cb;
ankerl::unordered_dense::map<u64, CodePtr> block_entries; ::Common::unordered_map<u64, CodePtr> block_entries;
ankerl::unordered_dense::map<u64, EmittedBlockInfo> block_infos; ::Common::unordered_map<u64, EmittedBlockInfo> block_infos;
public: public:
struct PreludeInfo { struct PreludeInfo {
@@ -9,7 +9,7 @@
#include <vector> #include <vector>
#include "dynarmic/backend/loongarch64/lagoon_cpp.h" #include "dynarmic/backend/loongarch64/lagoon_cpp.h"
#include <ankerl/unordered_dense.h> #include "common/container/unordered_map.h"
#include "common/assert.h" #include "common/assert.h"
#include "common/common_types.h" #include "common/common_types.h"
@@ -9,7 +9,7 @@
#pragma once #pragma once
#include <biscuit/assembler.hpp> #include <biscuit/assembler.hpp>
#include <ankerl/unordered_dense.h> #include "common/container/unordered_map.h"
#include "dynarmic/backend/riscv64/code_block.h" #include "dynarmic/backend/riscv64/code_block.h"
#include "dynarmic/backend/riscv64/emit_riscv64.h" #include "dynarmic/backend/riscv64/emit_riscv64.h"
@@ -74,8 +74,8 @@ private:
CodeBlock cb; CodeBlock cb;
biscuit::Assembler as; biscuit::Assembler as;
ankerl::unordered_dense::map<u64, CodePtr> block_entries; ::Common::unordered_map<u64, CodePtr> block_entries;
ankerl::unordered_dense::map<u64, EmittedBlockInfo> block_infos; ::Common::unordered_map<u64, EmittedBlockInfo> block_infos;
struct PreludeInfo { struct PreludeInfo {
CodePtr end_of_prelude; CodePtr end_of_prelude;
@@ -19,7 +19,7 @@
#include "common/assert.h" #include "common/assert.h"
#include "common/common_types.h" #include "common/common_types.h"
#include "dynarmic/mcl/is_instance_of_template.hpp" #include "dynarmic/mcl/is_instance_of_template.hpp"
#include <ankerl/unordered_dense.h> #include "common/container/unordered_map.h"
#include "dynarmic/backend/riscv64/stack_layout.h" #include "dynarmic/backend/riscv64/stack_layout.h"
#include "dynarmic/ir/cond.h" #include "dynarmic/ir/cond.h"
@@ -13,7 +13,8 @@
#include <set> #include <set>
#include <tuple> #include <tuple>
#include <ankerl/unordered_dense.h> #include "common/container/unordered_map.h"
#include "common/container/unordered_set.h"
#include "dynarmic/backend/block_range_information.h" #include "dynarmic/backend/block_range_information.h"
#include "dynarmic/backend/x64/a32_jitstate.h" #include "dynarmic/backend/x64/a32_jitstate.h"
@@ -126,11 +127,11 @@ public:
RegAlloc reg_alloc; //reusable reg alloc RegAlloc reg_alloc; //reusable reg alloc
BlockRangeInformation<u32> block_ranges; BlockRangeInformation<u32> block_ranges;
std::array<FastDispatchEntry, fast_dispatch_table_size> fast_dispatch_table; std::array<FastDispatchEntry, fast_dispatch_table_size> fast_dispatch_table;
ankerl::unordered_dense::map<u64, FastmemPatchInfo> fastmem_patch_info; ::Common::unordered_map<u64, FastmemPatchInfo> fastmem_patch_info;
ankerl::unordered_dense::map<std::tuple<bool, size_t, int, int>, void (*)()> read_fallbacks; ::Common::unordered_map<std::tuple<bool, size_t, int, int>, void (*)()> read_fallbacks;
ankerl::unordered_dense::map<std::tuple<bool, size_t, int, int>, void (*)()> write_fallbacks; ::Common::unordered_map<std::tuple<bool, size_t, int, int>, void (*)()> write_fallbacks;
ankerl::unordered_dense::map<std::tuple<bool, size_t, int, int>, void (*)()> exclusive_write_fallbacks; ::Common::unordered_map<std::tuple<bool, size_t, int, int>, void (*)()> exclusive_write_fallbacks;
ankerl::unordered_dense::set<DoNotFastmemMarker> do_not_fastmem; ::Common::unordered_set<DoNotFastmemMarker> do_not_fastmem;
boost::container::stable_vector<Xbyak::Label> shared_labels; boost::container::stable_vector<Xbyak::Label> shared_labels;
void (*memory_read_128)() = nullptr; // Dummy void (*memory_read_128)() = nullptr; // Dummy
void (*memory_write_128)() = nullptr; // Dummy void (*memory_write_128)() = nullptr; // Dummy
@@ -12,7 +12,8 @@
#include <map> #include <map>
#include <optional> #include <optional>
#include <tuple> #include <tuple>
#include <ankerl/unordered_dense.h> #include "common/container/unordered_map.h"
#include "common/container/unordered_set.h"
#include <boost/container/static_vector.hpp> #include <boost/container/static_vector.hpp>
#include "dynarmic/backend/block_range_information.h" #include "dynarmic/backend/block_range_information.h"
@@ -122,11 +123,11 @@ public:
RegAlloc reg_alloc; //reusable reg alloc RegAlloc reg_alloc; //reusable reg alloc
BlockRangeInformation<u64> block_ranges; BlockRangeInformation<u64> block_ranges;
std::array<FastDispatchEntry, fast_dispatch_table_size> fast_dispatch_table; std::array<FastDispatchEntry, fast_dispatch_table_size> fast_dispatch_table;
ankerl::unordered_dense::map<u64, FastmemPatchInfo> fastmem_patch_info; ::Common::unordered_map<u64, FastmemPatchInfo> fastmem_patch_info;
ankerl::unordered_dense::map<std::tuple<bool, size_t, int, int>, void (*)()> read_fallbacks; ::Common::unordered_map<std::tuple<bool, size_t, int, int>, void (*)()> read_fallbacks;
ankerl::unordered_dense::map<std::tuple<bool, size_t, int, int>, void (*)()> write_fallbacks; ::Common::unordered_map<std::tuple<bool, size_t, int, int>, void (*)()> write_fallbacks;
ankerl::unordered_dense::map<std::tuple<bool, size_t, int, int>, void (*)()> exclusive_write_fallbacks; ::Common::unordered_map<std::tuple<bool, size_t, int, int>, void (*)()> exclusive_write_fallbacks;
ankerl::unordered_dense::set<DoNotFastmemMarker> do_not_fastmem; ::Common::unordered_set<DoNotFastmemMarker> do_not_fastmem;
boost::container::stable_vector<Xbyak::Label> shared_labels; boost::container::stable_vector<Xbyak::Label> shared_labels;
const void* terminal_handler_pop_rsb_hint = nullptr; const void* terminal_handler_pop_rsb_hint = nullptr;
const void* terminal_handler_fast_dispatch_hint = nullptr; const void* terminal_handler_fast_dispatch_hint = nullptr;
@@ -14,7 +14,7 @@
#include <utility> #include <utility>
#include "common/common_types.h" #include "common/common_types.h"
#include <ankerl/unordered_dense.h> #include "common/container/unordered_map.h"
#include "dynarmic/backend/x64/xbyak.h" #include "dynarmic/backend/x64/xbyak.h"
namespace Dynarmic::Backend::X64 { namespace Dynarmic::Backend::X64 {
@@ -43,7 +43,7 @@ private:
} }
}; };
ankerl::unordered_dense::map<ConstantT, void*, ConstantHash> constant_info; ::Common::unordered_map<ConstantT, void*, ConstantHash> constant_info;
std::span<ConstantT> pool; std::span<ConstantT> pool;
std::size_t insertion_point; std::size_t insertion_point;
}; };
@@ -14,7 +14,8 @@
#include <boost/variant/detail/apply_visitor_binary.hpp> #include <boost/variant/detail/apply_visitor_binary.hpp>
#include "dynarmic/mcl/bit.hpp" #include "dynarmic/mcl/bit.hpp"
#include "common/common_types.h" #include "common/common_types.h"
#include <ankerl/unordered_dense.h> #include "common/container/unordered_map.h"
#include "common/container/unordered_set.h"
#include "dynarmic/backend/x64/block_of_code.h" #include "dynarmic/backend/x64/block_of_code.h"
#include "dynarmic/backend/x64/nzcv_util.h" #include "dynarmic/backend/x64/nzcv_util.h"
@@ -396,7 +397,7 @@ void EmitX64::ClearCache() {
PerfMapClear(); PerfMapClear();
} }
void EmitX64::InvalidateBasicBlocks(const ankerl::unordered_dense::set<IR::LocationDescriptor>& locations) { void EmitX64::InvalidateBasicBlocks(const ::Common::unordered_set<IR::LocationDescriptor>& locations) {
code.EnableWriting(); code.EnableWriting();
for (const auto& descriptor : locations) { for (const auto& descriptor : locations) {
if (auto const it = block_descriptors.find(descriptor); it != block_descriptors.end()) { if (auto const it = block_descriptors.find(descriptor); it != block_descriptors.end()) {
@@ -16,7 +16,8 @@
#include <type_traits> #include <type_traits>
#include <vector> #include <vector>
#include <ankerl/unordered_dense.h> #include "common/container/unordered_map.h"
#include "common/container/unordered_set.h"
#include <boost/container/stable_vector.hpp> #include <boost/container/stable_vector.hpp>
#include <boost/container/small_vector.hpp> #include <boost/container/small_vector.hpp>
@@ -88,7 +89,7 @@ public:
virtual void ClearCache(); virtual void ClearCache();
/// Invalidates a selection of basic blocks. /// Invalidates a selection of basic blocks.
void InvalidateBasicBlocks(const ankerl::unordered_dense::set<IR::LocationDescriptor>& locations); void InvalidateBasicBlocks(const ::Common::unordered_set<IR::LocationDescriptor>& locations);
//protected: //protected:
// Microinstruction emitters // Microinstruction emitters
@@ -131,8 +132,8 @@ public:
// State // State
BlockOfCode& code; BlockOfCode& code;
ExceptionHandler exception_handler; ExceptionHandler exception_handler;
ankerl::unordered_dense::map<IR::LocationDescriptor, BlockDescriptor> block_descriptors; ::Common::unordered_map<IR::LocationDescriptor, BlockDescriptor> block_descriptors;
ankerl::unordered_dense::map<IR::LocationDescriptor, PatchInformation> patch_information; ::Common::unordered_map<IR::LocationDescriptor, PatchInformation> patch_information;
// We need materialized protected members // We need materialized protected members
friend class A64EmitX64; friend class A64EmitX64;
@@ -4,10 +4,11 @@
#pragma once #pragma once
// You must ensure this matches with src/common/x64/xbyak.h on root dir // You must ensure this matches with src/common/x64/xbyak.h on root dir
#include <ankerl/unordered_dense.h> #include "common/container/unordered_map.h"
#include "common/container/unordered_set.h"
#include <boost/unordered_map.hpp> #include <boost/unordered_map.hpp>
#define XBYAK_STD_UNORDERED_SET ankerl::unordered_dense::set #define XBYAK_STD_UNORDERED_SET ::Common::unordered_set
#define XBYAK_STD_UNORDERED_MAP ankerl::unordered_dense::map #define XBYAK_STD_UNORDERED_MAP ::Common::unordered_map
#define XBYAK_STD_UNORDERED_MULTIMAP boost::unordered_multimap #define XBYAK_STD_UNORDERED_MULTIMAP boost::unordered_multimap
#include <xbyak/xbyak.h> #include <xbyak/xbyak.h>
#include <xbyak/xbyak_util.h> #include <xbyak/xbyak_util.h>
+2 -2
View File
@@ -11,7 +11,7 @@
#include <map> #include <map>
#include <bit> #include <bit>
#include <ankerl/unordered_dense.h> #include "common/container/unordered_map.h"
#include "boost/container/small_vector.hpp" #include "boost/container/small_vector.hpp"
#include "dynarmic/frontend/A32/a32_ir_emitter.h" #include "dynarmic/frontend/A32/a32_ir_emitter.h"
#include "dynarmic/frontend/A32/a32_location_descriptor.h" #include "dynarmic/frontend/A32/a32_location_descriptor.h"
@@ -1433,7 +1433,7 @@ static void VerificationPass(const IR::Block& block) {
ASSERT(IR::AreTypesCompatible(t1, t2)); ASSERT(IR::AreTypesCompatible(t1, t2));
} }
} }
ankerl::unordered_dense::map<IR::Inst*, size_t> actual_uses; ::Common::unordered_map<IR::Inst*, size_t> actual_uses;
for (auto const& inst : block.instructions) { for (auto const& inst : block.instructions) {
for (size_t i = 0; i < inst.NumArgs(); i++) for (size_t i = 0; i < inst.NumArgs(); i++)
if (IR::Value const arg = inst.GetArg(i); !arg.IsImmediate()) if (IR::Value const arg = inst.GetArg(i); !arg.IsImmediate())
+2 -2
View File
@@ -8,7 +8,7 @@
#include <array> #include <array>
#include <exception> #include <exception>
#include <ankerl/unordered_dense.h> #include "common/container/unordered_map.h"
#include <catch2/catch_test_macros.hpp> #include <catch2/catch_test_macros.hpp>
#include "common/common_types.h" #include "common/common_types.h"
@@ -23,7 +23,7 @@ namespace {
class MyEnvironment final : public A64::UserCallbacks { class MyEnvironment final : public A64::UserCallbacks {
public: public:
u64 ticks_left = 0; u64 ticks_left = 0;
ankerl::unordered_dense::map<u64, u8> memory{}; ::Common::unordered_map<u64, u8> memory{};
u8 MemoryRead8(u64 vaddr) override { u8 MemoryRead8(u64 vaddr) override {
return memory[vaddr]; return memory[vaddr];
+2 -2
View File
@@ -8,7 +8,7 @@
#pragma once #pragma once
#include <ankerl/unordered_dense.h> #include "common/container/unordered_map.h"
#include "common/assert.h" #include "common/assert.h"
#include "common/common_types.h" #include "common/common_types.h"
#include "dynarmic/interface/A64/a64.h" #include "dynarmic/interface/A64/a64.h"
@@ -17,7 +17,7 @@ using Vector = Dynarmic::A64::Vector;
class A64TestEnv : public Dynarmic::A64::UserCallbacks { class A64TestEnv : public Dynarmic::A64::UserCallbacks {
public: public:
ankerl::unordered_dense::map<u64, u8> modified_memory; ::Common::unordered_map<u64, u8> modified_memory;
std::vector<u32> code_mem; std::vector<u32> code_mem;
u64 ticks_left = 0; u64 ticks_left = 0;
u64 code_mem_start_address = 0; u64 code_mem_start_address = 0;

Some files were not shown because too many files have changed in this diff Show More