Loading src/ssl.cpp +28 −4 Original line number Diff line number Diff line Loading @@ -127,7 +127,14 @@ void ssl::connect(const std::string& addr, int port, bool nonblock) { // First establish TCP connection tcp::connect(addr, port, nonblock); if (nonblock) // Unconditional (not just "if (nonblock)"): the handshake loop below drives its own // recv attempts via handshake_after_connect()/fetchNextHandshakePlain(), which read // through this same socket -- if it were left blocking (tcp::connect(nonblock=false) // restores blocking mode on success), a peer that accepts the TCP connection but never // sends a single byte back leaves the very first recv() blocked in the kernel forever, // and the 15s deadline below never gets a chance to fire because the loop never gets // back to checking it. Restored to blocking again below once the handshake actually // completes, for the nonblock=false caller's benefit. setNonBlock(); // Set up for client mode Loading Loading @@ -167,6 +174,10 @@ void ssl::connect(const std::string& addr, int port, bool nonblock) { throw; } } // Handshake done -- restore blocking mode now, matching what // tcp::connect(nonblock=false) itself already leaves the socket in once a plain // (non-TLS) connect succeeds, so callers see the same postcondition either way. setBlock(); } } Loading @@ -181,10 +192,18 @@ void ssl::connectTimeout(const std::string& addr, int port, int timeout_ms) { const auto start = std::chrono::steady_clock::now(); // Spends only whatever's left of timeout_ms trying every resolved address (see // tcp::connectTimeout()'s own doc comment) -- leaves the socket blocking on success, same // post-condition connect(nonblock=false) leaves it in before the handshake loop below. // tcp::connectTimeout()'s own doc comment). tcp::connectTimeout(addr, port, timeout_ms); bool is_blocking = isBlocking(); // Must run non-blocking for the handshake loop below, exactly like connect()'s identical // fix (see its doc comment) -- tcp::connectTimeout() restores blocking mode on success, // and a blocking recv() during the handshake would ignore this function's own deadline // entirely, hanging forever on a peer that accepts the TCP connection but never sends a // byte back. Restored to blocking again below once the handshake actually completes. setNonBlock(); _tls.is_client = true; _tls.hostname = addr; _tls.setSocket(this); Loading Loading @@ -216,6 +235,11 @@ void ssl::connectTimeout(const std::string& addr, int port, int timeout_ms) { throw; } } // Handshake done -- restore blocking mode, matching connectTimeout()'s own // (tcp::connectTimeout()'s) postcondition on a plain successful connect. if (is_blocking) setBlock(); } // ============================================================================ Loading Loading
src/ssl.cpp +28 −4 Original line number Diff line number Diff line Loading @@ -127,7 +127,14 @@ void ssl::connect(const std::string& addr, int port, bool nonblock) { // First establish TCP connection tcp::connect(addr, port, nonblock); if (nonblock) // Unconditional (not just "if (nonblock)"): the handshake loop below drives its own // recv attempts via handshake_after_connect()/fetchNextHandshakePlain(), which read // through this same socket -- if it were left blocking (tcp::connect(nonblock=false) // restores blocking mode on success), a peer that accepts the TCP connection but never // sends a single byte back leaves the very first recv() blocked in the kernel forever, // and the 15s deadline below never gets a chance to fire because the loop never gets // back to checking it. Restored to blocking again below once the handshake actually // completes, for the nonblock=false caller's benefit. setNonBlock(); // Set up for client mode Loading Loading @@ -167,6 +174,10 @@ void ssl::connect(const std::string& addr, int port, bool nonblock) { throw; } } // Handshake done -- restore blocking mode now, matching what // tcp::connect(nonblock=false) itself already leaves the socket in once a plain // (non-TLS) connect succeeds, so callers see the same postcondition either way. setBlock(); } } Loading @@ -181,10 +192,18 @@ void ssl::connectTimeout(const std::string& addr, int port, int timeout_ms) { const auto start = std::chrono::steady_clock::now(); // Spends only whatever's left of timeout_ms trying every resolved address (see // tcp::connectTimeout()'s own doc comment) -- leaves the socket blocking on success, same // post-condition connect(nonblock=false) leaves it in before the handshake loop below. // tcp::connectTimeout()'s own doc comment). tcp::connectTimeout(addr, port, timeout_ms); bool is_blocking = isBlocking(); // Must run non-blocking for the handshake loop below, exactly like connect()'s identical // fix (see its doc comment) -- tcp::connectTimeout() restores blocking mode on success, // and a blocking recv() during the handshake would ignore this function's own deadline // entirely, hanging forever on a peer that accepts the TCP connection but never sends a // byte back. Restored to blocking again below once the handshake actually completes. setNonBlock(); _tls.is_client = true; _tls.hostname = addr; _tls.setSocket(this); Loading Loading @@ -216,6 +235,11 @@ void ssl::connectTimeout(const std::string& addr, int port, int timeout_ms) { throw; } } // Handshake done -- restore blocking mode, matching connectTimeout()'s own // (tcp::connectTimeout()'s) postcondition on a plain successful connect. if (is_blocking) setBlock(); } // ============================================================================ Loading