summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/android/app/src/main/java/org/citron/citron_emu/NativeLibrary.kt26
-rw-r--r--src/core/internal_network/network.cpp40
-rw-r--r--src/core/internal_network/network.h2
-rw-r--r--src/core/internal_network/network_interface.cpp18
-rw-r--r--src/core/internal_network/sockets.h10
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);