mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-08-31 10:36:56 +00:00
Compare commits
56 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a67f8548af | |||
| a08edeeeeb | |||
| a28dd7cbd7 | |||
| 370b75a8ff | |||
| f2f4649411 | |||
| c34e635dbb | |||
| a663bae084 | |||
| 02634b972b | |||
| 9b1f2a5538 | |||
| 38278f3ddc | |||
| 645c5fd3ee | |||
| 262994cf12 | |||
| 9648242990 | |||
| 81b43a4a96 | |||
| 8be5a7aa92 | |||
| 20fb68aae4 | |||
| a7b577b639 | |||
| a8497ff9b4 | |||
| 2de73ed49f | |||
| 31a54da818 | |||
| 6047e3d18f | |||
| 78ee34c16d | |||
| 9fff29044f | |||
| 605060a975 | |||
| 68ba0841a9 | |||
| 4e96d5d2a6 | |||
| 9641a5424e | |||
| fd7b578525 | |||
| 9f025b31cb | |||
| 941542d437 | |||
| 75c98131b6 | |||
| fef912f342 | |||
| 47e17fae95 | |||
| 4070a80046 | |||
| 458dfe18a4 | |||
| fc4a61871d | |||
| 512b39e2aa | |||
| 1cb58a6ebc | |||
| 0d5d453862 | |||
| 2c5d2a42f3 | |||
| 7047ef2a43 | |||
| fa0b1897d7 | |||
| a328a2aed8 | |||
| 930e20be98 | |||
| c33aceddf4 | |||
| 108bdbd6ed | |||
| b824f5382c | |||
| ed296bd7d0 | |||
| 85ffb1afaf | |||
| 8d4d8d239a | |||
| 82ea59fef3 | |||
| 615a6887df | |||
| 7453d50347 | |||
| 40b3df8f77 | |||
| b7f0f98519 | |||
| 7fda6dde73 |
@@ -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> {
|
|
||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
Vendored
-3
@@ -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)
|
||||||
|
|||||||
+1
@@ -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"),
|
||||||
|
|||||||
+7
@@ -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,
|
||||||
|
|||||||
+1
@@ -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>
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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>;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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>;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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
@@ -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 {
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
|
|
||||||
@@ -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>
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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()) {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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{};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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};
|
||||||
|
|||||||
@@ -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};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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
@@ -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{};
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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"));
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
@@ -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())
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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())
|
||||||
|
|||||||
@@ -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];
|
||||||
|
|||||||
@@ -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
Reference in New Issue
Block a user