IOS/NET: Add timeout on blocking connect
This commit is contained in:
parent
5e4c6d42a1
commit
bf246c36f5
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue