diff --git a/implementations/Crafter.Network-ClientQUIC.cpp b/implementations/Crafter.Network-ClientQUIC.cpp index dbe16df..1857f59 100644 --- a/implementations/Crafter.Network-ClientQUIC.cpp +++ b/implementations/Crafter.Network-ClientQUIC.cpp @@ -555,6 +555,12 @@ static HQUIC OpenClientConfiguration(const std::string& alpn, const QUICClientCr QUIC_SETTINGS settings{}; settings.IsSet.IdleTimeoutMs = 1; settings.IdleTimeoutMs = 120'000; + // Bound the handshake separately from the (much longer) idle timeout. + // The constructor blocks until msquic reports the connection either up or + // shut down; without this, dialling a host that never answers leaves it + // waiting for the idle timeout — minutes rather than seconds. + settings.IsSet.HandshakeIdleTimeoutMs = 1; + settings.HandshakeIdleTimeoutMs = 10'000; // Keep the connection alive across long idle gaps. msquic sends PING frames // on its own timer thread (independent of the app), so a request/response // connection survives even while the app is blocked for a long time between @@ -618,6 +624,8 @@ ClientQUIC::ClientQUIC(const char* host, std::uint16_t port, std::string alpnIn, QUIC_STATUS handshakeStatus = QUIC_STATUS_SUCCESS; { std::unique_lock lk(impl->mtx); + // Bounded by HandshakeIdleTimeoutMs above: an unreachable peer ends in + // SHUTDOWN_INITIATED_BY_TRANSPORT rather than waiting here forever. impl->cv.wait(lk, [&]{ return impl->connected || impl->closed; }); if (impl->connected) return; handshakeStatus = impl->shutdownStatus; diff --git a/interfaces/Crafter.Network-ClientQUIC.cppm b/interfaces/Crafter.Network-ClientQUIC.cppm index 6068922..d93c5e0 100644 --- a/interfaces/Crafter.Network-ClientQUIC.cppm +++ b/interfaces/Crafter.Network-ClientQUIC.cppm @@ -180,6 +180,8 @@ namespace Crafter { // Client constructor: connects to host:port using QUIC. ALPN must // match the listener. Throws QUICException on connect failure. + // Blocks for at most the handshake idle timeout (10s), so a host that + // never answers fails in seconds rather than at the idle timeout. ClientQUIC(const char* host, std::uint16_t port, std::string alpn, QUICClientCredentials creds = {}); ClientQUIC(std::string host, std::uint16_t port, std::string alpn,