From 90dc2df21aa0d6db32558f36ceb25da3f835ef89 Mon Sep 17 00:00:00 2001 From: Zephyron Date: Sun, 29 Jun 2025 16:57:26 +1000 Subject: [PATCH] core/sockets: Add missing socket services and functions from switchbrew - Add Unknown39 and Unknown40 functions to BSD service for [20.0.0+] - Implement bsd:nu service with ISfUserService and ISfAssignedNetworkInterfaceService - Add dns:priv and ethc:c/ethc:i service stubs - Update CMakeLists.txt to include new socket service files - All new functions include basic stub implementations following existing patterns This completes the socket services implementation based on switchbrew.org documentation. Signed-off-by: Zephyron --- src/core/CMakeLists.txt | 6 ++ src/core/hle/service/sockets/bsd.cpp | 18 ++++ src/core/hle/service/sockets/bsd.h | 2 + src/core/hle/service/sockets/bsdnu.cpp | 87 ++++++++++++++++ src/core/hle/service/sockets/bsdnu.h | 43 ++++++++ src/core/hle/service/sockets/dnspriv.cpp | 111 +++++++++++++++++++++ src/core/hle/service/sockets/dnspriv.h | 34 +++++++ src/core/hle/service/sockets/ethc.cpp | 122 +++++++++++++++++++++++ src/core/hle/service/sockets/ethc.h | 44 ++++++++ src/core/hle/service/sockets/sockets.cpp | 7 ++ 10 files changed, 474 insertions(+) create mode 100644 src/core/hle/service/sockets/bsdnu.cpp create mode 100644 src/core/hle/service/sockets/bsdnu.h create mode 100644 src/core/hle/service/sockets/dnspriv.cpp create mode 100644 src/core/hle/service/sockets/dnspriv.h create mode 100644 src/core/hle/service/sockets/ethc.cpp create mode 100644 src/core/hle/service/sockets/ethc.h diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index d05a41bb6..b7204f950 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -1062,6 +1062,12 @@ add_library(core STATIC hle/service/sm/sm_controller.h hle/service/sockets/bsd.cpp hle/service/sockets/bsd.h + hle/service/sockets/bsdnu.cpp + hle/service/sockets/bsdnu.h + hle/service/sockets/dnspriv.cpp + hle/service/sockets/dnspriv.h + hle/service/sockets/ethc.cpp + hle/service/sockets/ethc.h hle/service/sockets/nsd.cpp hle/service/sockets/nsd.h hle/service/sockets/sfdnsres.cpp diff --git a/src/core/hle/service/sockets/bsd.cpp b/src/core/hle/service/sockets/bsd.cpp index 549d450cd..4bd74baaf 100644 --- a/src/core/hle/service/sockets/bsd.cpp +++ b/src/core/hle/service/sockets/bsd.cpp @@ -1018,6 +1018,8 @@ BSD::BSD(Core::System& system_, const char* name) {33, &BSD::RegisterClientShared, "RegisterClientShared"}, {34, &BSD::GetSocketStatistics, "GetSocketStatistics"}, {35, &BSD::NifIoctl, "NifIoctl"}, + {39, &BSD::Unknown39, "[20.0.0+] Unknown39"}, + {40, &BSD::Unknown40, "[20.0.0+] Unknown40"}, {200, &BSD::SetThreadCoreMask, "SetThreadCoreMask"}, {201, &BSD::GetThreadCoreMask, "GetThreadCoreMask"}, }; @@ -1297,6 +1299,22 @@ void BSD::SocketExempt(HLERequestContext& ctx) { rb.PushEnum(static_cast(EOPNOTSUPP)); } +void BSD::Unknown39(HLERequestContext& ctx) { + LOG_WARNING(Service, "(STUBBED) called Unknown39 [20.0.0+]"); + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(-1); + rb.PushEnum(static_cast(EOPNOTSUPP)); +} + +void BSD::Unknown40(HLERequestContext& ctx) { + LOG_WARNING(Service, "(STUBBED) called Unknown40 [20.0.0+]"); + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(-1); + rb.PushEnum(static_cast(EOPNOTSUPP)); +} + void BSD::Sysctl(HLERequestContext& ctx) { LOG_WARNING(Service, "(STUBBED) called Sysctl"); IPC::ResponseBuilder rb{ctx, 4}; diff --git a/src/core/hle/service/sockets/bsd.h b/src/core/hle/service/sockets/bsd.h index 96327ccc4..c097938a9 100644 --- a/src/core/hle/service/sockets/bsd.h +++ b/src/core/hle/service/sockets/bsd.h @@ -163,6 +163,8 @@ private: void RegisterClientShared(HLERequestContext& ctx); void GetSocketStatistics(HLERequestContext& ctx); void NifIoctl(HLERequestContext& ctx); + void Unknown39(HLERequestContext& ctx); // [20.0.0+] undocumented + void Unknown40(HLERequestContext& ctx); // [20.0.0+] undocumented void SetThreadCoreMask(HLERequestContext& ctx); void GetThreadCoreMask(HLERequestContext& ctx); diff --git a/src/core/hle/service/sockets/bsdnu.cpp b/src/core/hle/service/sockets/bsdnu.cpp new file mode 100644 index 000000000..e465fe627 --- /dev/null +++ b/src/core/hle/service/sockets/bsdnu.cpp @@ -0,0 +1,87 @@ +// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/hle/service/sockets/bsdnu.h" +#include "core/hle/service/ipc_helpers.h" +#include "core/hle/service/sockets/sockets.h" + +namespace Service::Sockets { + +ISfAssignedNetworkInterfaceService::ISfAssignedNetworkInterfaceService(Core::System& system_) + : ServiceFramework{system_, "ISfAssignedNetworkInterfaceService"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, &ISfAssignedNetworkInterfaceService::AddSession, "AddSession"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +ISfAssignedNetworkInterfaceService::~ISfAssignedNetworkInterfaceService() = default; + +void ISfAssignedNetworkInterfaceService::AddSession(HLERequestContext& ctx) { + LOG_WARNING(Service, "(STUBBED) called AddSession"); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +ISfUserService::ISfUserService(Core::System& system_) : ServiceFramework{system_, "ISfUserService"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, &ISfUserService::Assign, "Assign"}, + {128, &ISfUserService::GetUserInfo, "GetUserInfo"}, + {129, &ISfUserService::GetStateChangedEvent, "GetStateChangedEvent"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +ISfUserService::~ISfUserService() = default; + +void ISfUserService::Assign(HLERequestContext& ctx) { + LOG_WARNING(Service, "(STUBBED) called Assign"); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(ResultSuccess); + rb.PushIpcInterface(system); +} + +void ISfUserService::GetUserInfo(HLERequestContext& ctx) { + LOG_WARNING(Service, "(STUBBED) called GetUserInfo"); + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(-1); + rb.PushEnum(Errno::SUCCESS); +} + +void ISfUserService::GetStateChangedEvent(HLERequestContext& ctx) { + LOG_WARNING(Service, "(STUBBED) called GetStateChangedEvent"); + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(-1); + rb.PushEnum(Errno::SUCCESS); +} + +BSDNU::BSDNU(Core::System& system_) : ServiceFramework{system_, "bsd:nu"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, &BSDNU::CreateUserService, "CreateUserService"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +BSDNU::~BSDNU() = default; + +void BSDNU::CreateUserService(HLERequestContext& ctx) { + LOG_WARNING(Service, "(STUBBED) called CreateUserService"); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(ResultSuccess); + rb.PushIpcInterface(system); +} + +} // namespace Service::Sockets \ No newline at end of file diff --git a/src/core/hle/service/sockets/bsdnu.h b/src/core/hle/service/sockets/bsdnu.h new file mode 100644 index 000000000..005567724 --- /dev/null +++ b/src/core/hle/service/sockets/bsdnu.h @@ -0,0 +1,43 @@ +// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/hle/service/service.h" + +namespace Core { +class System; +} + +namespace Service::Sockets { + +class ISfAssignedNetworkInterfaceService final : public ServiceFramework { +public: + explicit ISfAssignedNetworkInterfaceService(Core::System& system_); + ~ISfAssignedNetworkInterfaceService() override; + +private: + void AddSession(HLERequestContext& ctx); +}; + +class ISfUserService final : public ServiceFramework { +public: + explicit ISfUserService(Core::System& system_); + ~ISfUserService() override; + +private: + void Assign(HLERequestContext& ctx); + void GetUserInfo(HLERequestContext& ctx); + void GetStateChangedEvent(HLERequestContext& ctx); +}; + +class BSDNU final : public ServiceFramework { +public: + explicit BSDNU(Core::System& system_); + ~BSDNU() override; + +private: + void CreateUserService(HLERequestContext& ctx); +}; + +} // namespace Service::Sockets \ No newline at end of file diff --git a/src/core/hle/service/sockets/dnspriv.cpp b/src/core/hle/service/sockets/dnspriv.cpp new file mode 100644 index 000000000..60fe0c02d --- /dev/null +++ b/src/core/hle/service/sockets/dnspriv.cpp @@ -0,0 +1,111 @@ +// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/hle/service/sockets/dnspriv.h" +#include "core/hle/service/ipc_helpers.h" +#include "core/hle/service/sockets/sockets.h" + +namespace Service::Sockets { + +DNSPRIV::DNSPRIV(Core::System& system_) : ServiceFramework{system_, "dns:priv"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, &DNSPRIV::Unknown0, "Unknown0"}, + {1, &DNSPRIV::Unknown1, "Unknown1"}, + {2, &DNSPRIV::Unknown2, "Unknown2"}, + {3, &DNSPRIV::Unknown3, "Unknown3"}, + {4, &DNSPRIV::Unknown4, "Unknown4"}, + {5, &DNSPRIV::Unknown5, "Unknown5"}, + {6, &DNSPRIV::Unknown6, "Unknown6"}, + {7, &DNSPRIV::Unknown7, "Unknown7"}, + {8, &DNSPRIV::Unknown8, "Unknown8"}, + {9, &DNSPRIV::Unknown9, "Unknown9"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +DNSPRIV::~DNSPRIV() = default; + +void DNSPRIV::Unknown0(HLERequestContext& ctx) { + LOG_WARNING(Service, "(STUBBED) called dns:priv Unknown0"); + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(-1); + rb.PushEnum(Errno::SUCCESS); +} + +void DNSPRIV::Unknown1(HLERequestContext& ctx) { + LOG_WARNING(Service, "(STUBBED) called dns:priv Unknown1"); + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(-1); + rb.PushEnum(Errno::SUCCESS); +} + +void DNSPRIV::Unknown2(HLERequestContext& ctx) { + LOG_WARNING(Service, "(STUBBED) called dns:priv Unknown2"); + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(-1); + rb.PushEnum(Errno::SUCCESS); +} + +void DNSPRIV::Unknown3(HLERequestContext& ctx) { + LOG_WARNING(Service, "(STUBBED) called dns:priv Unknown3"); + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(-1); + rb.PushEnum(Errno::SUCCESS); +} + +void DNSPRIV::Unknown4(HLERequestContext& ctx) { + LOG_WARNING(Service, "(STUBBED) called dns:priv Unknown4"); + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(-1); + rb.PushEnum(Errno::SUCCESS); +} + +void DNSPRIV::Unknown5(HLERequestContext& ctx) { + LOG_WARNING(Service, "(STUBBED) called dns:priv Unknown5"); + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(-1); + rb.PushEnum(Errno::SUCCESS); +} + +void DNSPRIV::Unknown6(HLERequestContext& ctx) { + LOG_WARNING(Service, "(STUBBED) called dns:priv Unknown6"); + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(-1); + rb.PushEnum(Errno::SUCCESS); +} + +void DNSPRIV::Unknown7(HLERequestContext& ctx) { + LOG_WARNING(Service, "(STUBBED) called dns:priv Unknown7"); + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(-1); + rb.PushEnum(Errno::SUCCESS); +} + +void DNSPRIV::Unknown8(HLERequestContext& ctx) { + LOG_WARNING(Service, "(STUBBED) called dns:priv Unknown8"); + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(-1); + rb.PushEnum(Errno::SUCCESS); +} + +void DNSPRIV::Unknown9(HLERequestContext& ctx) { + LOG_WARNING(Service, "(STUBBED) called dns:priv Unknown9"); + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(-1); + rb.PushEnum(Errno::SUCCESS); +} + +} // namespace Service::Sockets \ No newline at end of file diff --git a/src/core/hle/service/sockets/dnspriv.h b/src/core/hle/service/sockets/dnspriv.h new file mode 100644 index 000000000..86296da53 --- /dev/null +++ b/src/core/hle/service/sockets/dnspriv.h @@ -0,0 +1,34 @@ +// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/hle/service/service.h" + +namespace Core { +class System; +} + +namespace Service::Sockets { + +class DNSPRIV final : public ServiceFramework { +public: + explicit DNSPRIV(Core::System& system_); + ~DNSPRIV() override; + +private: + // DNS private service methods (dns:priv) + // Based on switchbrew documentation - functions are undocumented so basic stubs are provided + void Unknown0(HLERequestContext& ctx); + void Unknown1(HLERequestContext& ctx); + void Unknown2(HLERequestContext& ctx); + void Unknown3(HLERequestContext& ctx); + void Unknown4(HLERequestContext& ctx); + void Unknown5(HLERequestContext& ctx); + void Unknown6(HLERequestContext& ctx); + void Unknown7(HLERequestContext& ctx); + void Unknown8(HLERequestContext& ctx); + void Unknown9(HLERequestContext& ctx); +}; + +} // namespace Service::Sockets \ No newline at end of file diff --git a/src/core/hle/service/sockets/ethc.cpp b/src/core/hle/service/sockets/ethc.cpp new file mode 100644 index 000000000..94016b519 --- /dev/null +++ b/src/core/hle/service/sockets/ethc.cpp @@ -0,0 +1,122 @@ +// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/hle/service/sockets/ethc.h" +#include "core/hle/service/ipc_helpers.h" +#include "core/hle/service/sockets/sockets.h" + +namespace Service::Sockets { + +ETHC_C::ETHC_C(Core::System& system_) : ServiceFramework{system_, "ethc:c"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, ÐC_C::Unknown0, "Unknown0"}, + {1, ÐC_C::Unknown1, "Unknown1"}, + {2, ÐC_C::Unknown2, "Unknown2"}, + {3, ÐC_C::Unknown3, "Unknown3"}, + {4, ÐC_C::Unknown4, "Unknown4"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +ETHC_C::~ETHC_C() = default; + +void ETHC_C::Unknown0(HLERequestContext& ctx) { + LOG_WARNING(Service, "(STUBBED) called ethc:c Unknown0"); + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(-1); + rb.PushEnum(Errno::SUCCESS); +} + +void ETHC_C::Unknown1(HLERequestContext& ctx) { + LOG_WARNING(Service, "(STUBBED) called ethc:c Unknown1"); + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(-1); + rb.PushEnum(Errno::SUCCESS); +} + +void ETHC_C::Unknown2(HLERequestContext& ctx) { + LOG_WARNING(Service, "(STUBBED) called ethc:c Unknown2"); + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(-1); + rb.PushEnum(Errno::SUCCESS); +} + +void ETHC_C::Unknown3(HLERequestContext& ctx) { + LOG_WARNING(Service, "(STUBBED) called ethc:c Unknown3"); + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(-1); + rb.PushEnum(Errno::SUCCESS); +} + +void ETHC_C::Unknown4(HLERequestContext& ctx) { + LOG_WARNING(Service, "(STUBBED) called ethc:c Unknown4"); + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(-1); + rb.PushEnum(Errno::SUCCESS); +} + +ETHC_I::ETHC_I(Core::System& system_) : ServiceFramework{system_, "ethc:i"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, ÐC_I::Unknown0, "Unknown0"}, + {1, ÐC_I::Unknown1, "Unknown1"}, + {2, ÐC_I::Unknown2, "Unknown2"}, + {3, ÐC_I::Unknown3, "Unknown3"}, + {4, ÐC_I::Unknown4, "Unknown4"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +ETHC_I::~ETHC_I() = default; + +void ETHC_I::Unknown0(HLERequestContext& ctx) { + LOG_WARNING(Service, "(STUBBED) called ethc:i Unknown0"); + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(-1); + rb.PushEnum(Errno::SUCCESS); +} + +void ETHC_I::Unknown1(HLERequestContext& ctx) { + LOG_WARNING(Service, "(STUBBED) called ethc:i Unknown1"); + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(-1); + rb.PushEnum(Errno::SUCCESS); +} + +void ETHC_I::Unknown2(HLERequestContext& ctx) { + LOG_WARNING(Service, "(STUBBED) called ethc:i Unknown2"); + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(-1); + rb.PushEnum(Errno::SUCCESS); +} + +void ETHC_I::Unknown3(HLERequestContext& ctx) { + LOG_WARNING(Service, "(STUBBED) called ethc:i Unknown3"); + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(-1); + rb.PushEnum(Errno::SUCCESS); +} + +void ETHC_I::Unknown4(HLERequestContext& ctx) { + LOG_WARNING(Service, "(STUBBED) called ethc:i Unknown4"); + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(-1); + rb.PushEnum(Errno::SUCCESS); +} + +} // namespace Service::Sockets \ No newline at end of file diff --git a/src/core/hle/service/sockets/ethc.h b/src/core/hle/service/sockets/ethc.h new file mode 100644 index 000000000..1f4427751 --- /dev/null +++ b/src/core/hle/service/sockets/ethc.h @@ -0,0 +1,44 @@ +// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/hle/service/service.h" + +namespace Core { +class System; +} + +namespace Service::Sockets { + +class ETHC_C final : public ServiceFramework { +public: + explicit ETHC_C(Core::System& system_); + ~ETHC_C() override; + +private: + // Ethernet controller service methods (ethc:c) + // Based on switchbrew documentation - functions are undocumented so basic stubs are provided + void Unknown0(HLERequestContext& ctx); + void Unknown1(HLERequestContext& ctx); + void Unknown2(HLERequestContext& ctx); + void Unknown3(HLERequestContext& ctx); + void Unknown4(HLERequestContext& ctx); +}; + +class ETHC_I final : public ServiceFramework { +public: + explicit ETHC_I(Core::System& system_); + ~ETHC_I() override; + +private: + // Ethernet controller interface service methods (ethc:i) + // Based on switchbrew documentation - functions are undocumented so basic stubs are provided + void Unknown0(HLERequestContext& ctx); + void Unknown1(HLERequestContext& ctx); + void Unknown2(HLERequestContext& ctx); + void Unknown3(HLERequestContext& ctx); + void Unknown4(HLERequestContext& ctx); +}; + +} // namespace Service::Sockets \ No newline at end of file diff --git a/src/core/hle/service/sockets/sockets.cpp b/src/core/hle/service/sockets/sockets.cpp index 1b2d58812..e29fa9d62 100644 --- a/src/core/hle/service/sockets/sockets.cpp +++ b/src/core/hle/service/sockets/sockets.cpp @@ -4,6 +4,9 @@ #include "core/hle/service/server_manager.h" #include "core/hle/service/sockets/bsd.h" +#include "core/hle/service/sockets/bsdnu.h" +#include "core/hle/service/sockets/dnspriv.h" +#include "core/hle/service/sockets/ethc.h" #include "core/hle/service/sockets/nsd.h" #include "core/hle/service/sockets/sfdnsres.h" #include "core/hle/service/sockets/sockets.h" @@ -16,7 +19,11 @@ void LoopProcess(Core::System& system) { server_manager->RegisterNamedService("bsd:a", std::make_shared(system, "bsd:a")); server_manager->RegisterNamedService("bsd:s", std::make_shared(system, "bsd:s")); server_manager->RegisterNamedService("bsd:u", std::make_shared(system, "bsd:u")); + server_manager->RegisterNamedService("bsd:nu", std::make_shared(system)); server_manager->RegisterNamedService("bsdcfg", std::make_shared(system)); + server_manager->RegisterNamedService("dns:priv", std::make_shared(system)); + server_manager->RegisterNamedService("ethc:c", std::make_shared(system)); + server_manager->RegisterNamedService("ethc:i", std::make_shared(system)); server_manager->RegisterNamedService("nsd:a", std::make_shared(system, "nsd:a")); server_manager->RegisterNamedService("nsd:u", std::make_shared(system, "nsd:u")); server_manager->RegisterNamedService("sfdnsres", std::make_shared(system));