From bf246c36f534c0772f26384be3c0a6700274d887 Mon Sep 17 00:00:00 2001 From: Sepalani Date: Wed, 22 Apr 2020 18:03:45 +0400 Subject: [PATCH] IOS/NET: Add timeout on blocking connect --- Source/Core/Core/Config/MainSettings.cpp | 4 +++ Source/Core/Core/Config/MainSettings.h | 1 + Source/Core/Core/IOS/Network/Socket.cpp | 32 ++++++++++++++++++++++-- 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 MAIN_NETWORK_SSL_DUMP_ROOT_CA{{System::Main, "Network", "SSLDum const Info MAIN_NETWORK_SSL_DUMP_PEER_CERT{{System::Main, "Network", "SSLDumpPeerCert"}, false}; const Info 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 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 MAIN_NETWORK_SSL_VERIFY_CERTIFICATES; extern const Info MAIN_NETWORK_SSL_DUMP_ROOT_CA; extern const Info MAIN_NETWORK_SSL_DUMP_PEER_CERT; extern const Info MAIN_NETWORK_DUMP_AS_PCAP; +extern const Info 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 +#include #include #include +#include #include #include #include @@ -184,6 +186,7 @@ public: WiiSocket& operator=(WiiSocket&&) = default; private: + using Timeout = std::chrono::time_point; 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 pending_sockops; + + std::optional timeout; }; class WiiSockMan