diff options
| author | Léo Lam <leo@leolam.fr> | 2021-02-21 15:26:59 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-02-21 15:26:59 +0100 |
| commit | c040b0151d2dfc5d98ca380911d8cc2d0a3fccd8 (patch) | |
| tree | 9092cb0b37fe8711a04600f3c2c07bb1ebb351d7 /Source | |
| parent | 6f71a1ec5054d74890974b64ed65bdf5e9d4b16c (diff) | |
| parent | bf246c36f534c0772f26384be3c0a6700274d887 (diff) | |
Merge pull request #8759 from sepalani/so-connect
IOS/NET: Add timeout on blocking connect
Diffstat (limited to 'Source')
| -rw-r--r-- | Source/Core/Core/Config/MainSettings.cpp | 4 | ||||
| -rw-r--r-- | Source/Core/Core/Config/MainSettings.h | 1 | ||||
| -rw-r--r-- | Source/Core/Core/IOS/Network/Socket.cpp | 32 | ||||
| -rw-r--r-- | Source/Core/Core/IOS/Network/Socket.h | 9 |
4 files changed, 44 insertions, 2 deletions
diff --git a/Source/Core/Core/Config/MainSettings.cpp b/Source/Core/Core/Config/MainSettings.cpp index bcd8887def..d0fbd6c1f2 100644 --- a/Source/Core/Core/Config/MainSettings.cpp +++ b/Source/Core/Core/Config/MainSettings.cpp @@ -157,6 +157,10 @@ const Info<bool> MAIN_NETWORK_SSL_DUMP_ROOT_CA{{System::Main, "Network", "SSLDum const Info<bool> MAIN_NETWORK_SSL_DUMP_PEER_CERT{{System::Main, "Network", "SSLDumpPeerCert"}, false}; const Info<bool> MAIN_NETWORK_DUMP_AS_PCAP{{System::Main, "Network", "DumpAsPCAP"}, false}; +// Default value based on: +// - [RFC 1122] 4.2.3.5 TCP Connection Failures (at least 3 minutes) +// - https://dolp.in/pr8759 hwtest (3 minutes and 10 seconds) +const Info<int> MAIN_NETWORK_TIMEOUT{{System::Main, "Network", "NetworkTimeout"}, 190}; // Main.Interface diff --git a/Source/Core/Core/Config/MainSettings.h b/Source/Core/Core/Config/MainSettings.h index 1d9a687153..c0a063c624 100644 --- a/Source/Core/Core/Config/MainSettings.h +++ b/Source/Core/Core/Config/MainSettings.h @@ -130,6 +130,7 @@ extern const Info<bool> MAIN_NETWORK_SSL_VERIFY_CERTIFICATES; extern const Info<bool> MAIN_NETWORK_SSL_DUMP_ROOT_CA; extern const Info<bool> MAIN_NETWORK_SSL_DUMP_PEER_CERT; extern const Info<bool> MAIN_NETWORK_DUMP_AS_PCAP; +extern const Info<int> MAIN_NETWORK_TIMEOUT; // Main.Interface diff --git a/Source/Core/Core/IOS/Network/Socket.cpp b/Source/Core/Core/IOS/Network/Socket.cpp index 53a34fef05..663b3f05dd 100644 --- a/Source/Core/Core/IOS/Network/Socket.cpp +++ b/Source/Core/Core/IOS/Network/Socket.cpp @@ -331,11 +331,24 @@ void WiiSocket::Update(bool read, bool write, bool except) } // Fix blocking error codes - if (!nonBlock) + if (!nonBlock && it->net_type == IOCTL_SO_CONNECT) { - if (it->net_type == IOCTL_SO_CONNECT && ReturnValue == -SO_EISCONN) + switch (ReturnValue) { + case -SO_EAGAIN: + case -SO_EALREADY: + case -SO_EINPROGRESS: + if (std::chrono::steady_clock::now() > GetTimeout()) + { + ReturnValue = -SO_ENETUNREACH; + ResetTimeout(); + } + break; + case -SO_EISCONN: ReturnValue = SO_SUCCESS; + [[fallthrough]]; + default: + ResetTimeout(); } } } @@ -660,6 +673,21 @@ void WiiSocket::Update(bool read, bool write, bool except) } } +const WiiSocket::Timeout& WiiSocket::GetTimeout() +{ + if (!timeout.has_value()) + { + timeout = std::chrono::steady_clock::now() + + std::chrono::seconds(Config::Get(Config::MAIN_NETWORK_TIMEOUT)); + } + return *timeout; +} + +void WiiSocket::ResetTimeout() +{ + timeout.reset(); +} + void WiiSocket::DoSock(Request request, NET_IOCTL type) { sockop so = {request, false}; diff --git a/Source/Core/Core/IOS/Network/Socket.h b/Source/Core/Core/IOS/Network/Socket.h index c72ffd6998..6bacd6f482 100644 --- a/Source/Core/Core/IOS/Network/Socket.h +++ b/Source/Core/Core/IOS/Network/Socket.h @@ -43,8 +43,10 @@ typedef struct pollfd pollfd_t; #endif #include <algorithm> +#include <chrono> #include <cstdio> #include <list> +#include <optional> #include <string> #include <string_view> #include <unordered_map> @@ -184,6 +186,7 @@ public: WiiSocket& operator=(WiiSocket&&) = default; private: + using Timeout = std::chrono::time_point<std::chrono::steady_clock>; struct sockop { Request request; @@ -204,14 +207,20 @@ private: s32 CloseFd(); s32 FCntl(u32 cmd, u32 arg); + const Timeout& GetTimeout(); + void ResetTimeout(); + void DoSock(Request request, NET_IOCTL type); void DoSock(Request request, SSL_IOCTL type); void Update(bool read, bool write, bool except); bool IsValid() const { return fd >= 0; } + s32 fd = -1; s32 wii_fd = -1; bool nonBlock = false; std::list<sockop> pending_sockops; + + std::optional<Timeout> timeout; }; class WiiSockMan |
