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"},
|
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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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};
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue