Commit b7a0ecbd authored by jan.koester's avatar jan.koester
Browse files

test

parent 46cb05f0
Loading
Loading
Loading
Loading
+28 −4
Original line number Diff line number Diff line
@@ -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
@@ -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();
    }
}

@@ -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);
@@ -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();
}

// ============================================================================