IOS/NET: Add timeout on blocking connect

This commit is contained in:
Sepalani 2020-04-22 18:03:45 +04:00
parent 5e4c6d42a1
commit bf246c36f5
4 changed files with 44 additions and 2 deletions

View File

@ -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"}, const Info<bool> MAIN_NETWORK_SSL_DUMP_PEER_CERT{{System::Main, "Network", "SSLDumpPeerCert"},
false}; false};
const Info<bool> MAIN_NETWORK_DUMP_AS_PCAP{{System::Main, "Network", "DumpAsPCAP"}, 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 // Main.Interface

View File

@ -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_ROOT_CA;
extern const Info<bool> MAIN_NETWORK_SSL_DUMP_PEER_CERT; extern const Info<bool> MAIN_NETWORK_SSL_DUMP_PEER_CERT;
extern const Info<bool> MAIN_NETWORK_DUMP_AS_PCAP; extern const Info<bool> MAIN_NETWORK_DUMP_AS_PCAP;
extern const Info<int> MAIN_NETWORK_TIMEOUT;
// Main.Interface // Main.Interface

View File

@ -331,11 +331,24 @@ void WiiSocket::Update(bool read, bool write, bool except)
} }
// Fix blocking error codes // 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; 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) void WiiSocket::DoSock(Request request, NET_IOCTL type)
{ {
sockop so = {request, false}; sockop so = {request, false};

View File

@ -43,8 +43,10 @@ typedef struct pollfd pollfd_t;
#endif #endif
#include <algorithm> #include <algorithm>
#include <chrono>
#include <cstdio> #include <cstdio>
#include <list> #include <list>
#include <optional>
#include <string> #include <string>
#include <string_view> #include <string_view>
#include <unordered_map> #include <unordered_map>
@ -184,6 +186,7 @@ public:
WiiSocket& operator=(WiiSocket&&) = default; WiiSocket& operator=(WiiSocket&&) = default;
private: private:
using Timeout = std::chrono::time_point<std::chrono::steady_clock>;
struct sockop struct sockop
{ {
Request request; Request request;
@ -204,14 +207,20 @@ private:
s32 CloseFd(); s32 CloseFd();
s32 FCntl(u32 cmd, u32 arg); s32 FCntl(u32 cmd, u32 arg);
const Timeout& GetTimeout();
void ResetTimeout();
void DoSock(Request request, NET_IOCTL type); void DoSock(Request request, NET_IOCTL type);
void DoSock(Request request, SSL_IOCTL type); void DoSock(Request request, SSL_IOCTL type);
void Update(bool read, bool write, bool except); void Update(bool read, bool write, bool except);
bool IsValid() const { return fd >= 0; } bool IsValid() const { return fd >= 0; }
s32 fd = -1; s32 fd = -1;
s32 wii_fd = -1; s32 wii_fd = -1;
bool nonBlock = false; bool nonBlock = false;
std::list<sockop> pending_sockops; std::list<sockop> pending_sockops;
std::optional<Timeout> timeout;
}; };
class WiiSockMan class WiiSockMan