diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/android/app/src/main/java/org/citron/citron_emu/NativeLibrary.kt | 26 | ||||
-rw-r--r-- | src/core/internal_network/network.cpp | 40 | ||||
-rw-r--r-- | src/core/internal_network/network.h | 2 | ||||
-rw-r--r-- | src/core/internal_network/network_interface.cpp | 18 | ||||
-rw-r--r-- | src/core/internal_network/sockets.h | 10 |
5 files changed, 85 insertions, 11 deletions
diff --git a/src/android/app/src/main/java/org/citron/citron_emu/NativeLibrary.kt b/src/android/app/src/main/java/org/citron/citron_emu/NativeLibrary.kt index fc63dc276..c61230906 100644 --- a/src/android/app/src/main/java/org/citron/citron_emu/NativeLibrary.kt +++ b/src/android/app/src/main/java/org/citron/citron_emu/NativeLibrary.kt @@ -21,6 +21,7 @@ import org.citron.citron_emu.utils.Log import org.citron.citron_emu.model.InstallResult import org.citron.citron_emu.model.Patch import org.citron.citron_emu.model.GameVerificationResult +import java.net.NetworkInterface /** * Class which contains methods that interact @@ -459,4 +460,29 @@ object NativeLibrary { * Checks if all necessary keys are present for decryption */ external fun areKeysPresent(): Boolean + + fun getNetworkInterfaces(): Array<String> { + val interfaceList = mutableListOf<String>() + try { + NetworkInterface.getNetworkInterfaces()?.toList()?.forEach { iface -> + if (iface.isUp && !iface.isLoopback) { + iface.inetAddresses.toList() + .filterNot { it.isLoopbackAddress } + .forEach { addr -> + interfaceList.add("${iface.name};${addr.hostAddress}") + } + } + } + } catch (e: Exception) { + Log.error("[NativeLibrary] Failed to enumerate network interfaces: ${e.message}") + } + + // Always ensure we have at least a loopback interface + if (interfaceList.isEmpty()) { + Log.warning("[NativeLibrary] No interfaces found, adding loopback fallback") + interfaceList.add("lo;127.0.0.1") + } + + return interfaceList.toTypedArray() + } } diff --git a/src/core/internal_network/network.cpp b/src/core/internal_network/network.cpp index df6d3cc65..261f46cad 100644 --- a/src/core/internal_network/network.cpp +++ b/src/core/internal_network/network.cpp @@ -384,7 +384,7 @@ Domain TranslateDomainFromNative(int domain) { } } -int TranslateDomainToNative(Domain domain) { +[[maybe_unused]] static int TranslateDomainToNative(Domain domain) { switch (domain) { case Domain::Unspecified: return 0; @@ -414,7 +414,7 @@ Type TranslateTypeFromNative(int type) { } } -int TranslateTypeToNative(Type type) { +[[maybe_unused]] static int TranslateTypeToNative(Type type) { switch (type) { case Type::Unspecified: return 0; @@ -444,7 +444,7 @@ Protocol TranslateProtocolFromNative(int protocol) { } } -int TranslateProtocolToNative(Protocol protocol) { +[[maybe_unused]] static int TranslateProtocolToNative(Protocol protocol) { switch (protocol) { case Protocol::Unspecified: return 0; @@ -679,14 +679,32 @@ Errno Socket::SetSockOpt(SOCKET fd_so, int option, T value) { return GetAndLogLastError(); } -Errno Socket::Initialize(Domain domain, Type type, Protocol protocol) { - fd = socket(TranslateDomainToNative(domain), TranslateTypeToNative(type), - TranslateProtocolToNative(protocol)); - if (fd != INVALID_SOCKET) { +Errno Socket::Initialize(Domain domain_, Type type_, Protocol protocol_) { + domain_value = domain_; + type_value = type_; + protocol_value = protocol_; + + if (fd >= 0) { return Errno::SUCCESS; } - return GetAndLogLastError(); + fd = static_cast<SOCKET>(socket(TranslateDomainToNative(domain_value), + TranslateTypeToNative(type_value), + TranslateProtocolToNative(protocol_value))); + if (fd < 0) { + const Errno error = GetAndLogLastError(); + LOG_ERROR(Network, "Socket creation failed"); + + // If we can't create the socket, force offline mode + if (error == Errno::NOMEM) { + LOG_WARNING(Network, "Critical socket error, forcing offline mode"); + ForceOfflineMode(); + return Errno::SUCCESS; + } + return error; + } + + return Errno::SUCCESS; } std::pair<SocketBase::AcceptResult, Errno> Socket::Accept() { @@ -930,4 +948,10 @@ void Socket::HandleProxyPacket(const ProxyPacket& packet) { LOG_WARNING(Network, "ProxyPacket received, but not in Proxy mode!"); } +void ForceOfflineMode() { + LOG_INFO(Network, "Forcing offline mode due to network initialization issues"); + // Use the correct setting name + Settings::values.network_interface = "null"; // Or whatever value indicates disabled +} + } // namespace Network diff --git a/src/core/internal_network/network.h b/src/core/internal_network/network.h index 78905ca60..abb355b96 100644 --- a/src/core/internal_network/network.h +++ b/src/core/internal_network/network.h @@ -124,4 +124,6 @@ u32 IPv4AddressToInteger(IPv4Address ip_addr); Common::Expected<std::vector<AddrInfo>, GetAddrInfoError> GetAddressInfo( const std::string& host, const std::optional<std::string>& service); +void ForceOfflineMode(); + } // namespace Network diff --git a/src/core/internal_network/network_interface.cpp b/src/core/internal_network/network_interface.cpp index 7c37f660b..17a3340dd 100644 --- a/src/core/internal_network/network_interface.cpp +++ b/src/core/internal_network/network_interface.cpp @@ -88,6 +88,15 @@ std::vector<NetworkInterface> GetAvailableNetworkInterfaces() { .gateway = gateway}); } + // If no interfaces found, create a fallback loopback interface + if (result.empty()) { + LOG_WARNING(Network, "No network interfaces detected, adding fallback loopback interface"); + NetworkInterface loopback; + loopback.name = "fallback_loopback"; + loopback.ip_address.s_addr = htonl(INADDR_LOOPBACK); + result.push_back(loopback); + } + return result; } @@ -181,6 +190,15 @@ std::vector<NetworkInterface> GetAvailableNetworkInterfaces() { freeifaddrs(ifaddr); + // If no interfaces found, create a fallback loopback interface + if (result.empty()) { + LOG_WARNING(Network, "No network interfaces detected, adding fallback loopback interface"); + NetworkInterface loopback; + loopback.name = "fallback_loopback"; + loopback.ip_address.s_addr = htonl(INADDR_LOOPBACK); + result.push_back(loopback); + } + return result; } diff --git a/src/core/internal_network/sockets.h b/src/core/internal_network/sockets.h index 3573ab311..fa1e2c408 100644 --- a/src/core/internal_network/sockets.h +++ b/src/core/internal_network/sockets.h @@ -102,6 +102,13 @@ protected: }; class Socket : public SocketBase { +private: + SOCKET fd = INVALID_SOCKET; + bool is_non_blocking = false; + Domain domain_value = Domain::Unspecified; + Type type_value = Type::Unspecified; + Protocol protocol_value = Protocol::Unspecified; + public: Socket() = default; explicit Socket(SOCKET fd_) : SocketBase{fd_} {} @@ -166,9 +173,6 @@ public: bool IsOpened() const override; void HandleProxyPacket(const ProxyPacket& packet) override; - -private: - bool is_non_blocking = false; }; std::pair<s32, Errno> Poll(std::vector<PollFD>& poll_fds, s32 timeout); |