diff options
| -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);  | 
