From b64d86f9e9ebf3cdafc405e0cfeffa1b67855a42 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 9 Sep 2021 11:51:00 +0200 Subject: [PATCH] dnsdist: Fix outstanding counter issue when a TCP connection dies When the client closes the TCP connection while we are still waiting for the backend to send at least one response, and the backend connection then terminates anormally, we could have not properly reset the outstanding counter of that backend. --- pdns/dnsdistdist/dnsdist-tcp-downstream.cc | 4 + pdns/dnsdistdist/test-dnsdisttcp_cc.cc | 149 +++++++++++++++++++++ 2 files changed, 153 insertions(+) diff --git a/pdns/dnsdistdist/dnsdist-tcp-downstream.cc b/pdns/dnsdistdist/dnsdist-tcp-downstream.cc index 99945ffaf3..d480b38935 100644 --- a/pdns/dnsdistdist/dnsdist-tcp-downstream.cc +++ b/pdns/dnsdistdist/dnsdist-tcp-downstream.cc @@ -7,6 +7,10 @@ TCPConnectionToBackend::~TCPConnectionToBackend() { + if (d_ds && !d_pendingResponses.empty()) { + d_ds->outstanding -= d_pendingResponses.size(); + } + if (d_ds && d_handler) { --d_ds->tcpCurrentConnections; struct timeval now; diff --git a/pdns/dnsdistdist/test-dnsdisttcp_cc.cc b/pdns/dnsdistdist/test-dnsdisttcp_cc.cc index 516c2306e9..d5483edd3f 100644 --- a/pdns/dnsdistdist/test-dnsdisttcp_cc.cc +++ b/pdns/dnsdistdist/test-dnsdisttcp_cc.cc @@ -851,6 +851,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_BackendNoOOOR) BOOST_CHECK(s_writeBuffer == query); BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), query.size()); BOOST_CHECK(s_backendWriteBuffer == query); + BOOST_CHECK_EQUAL(backend->outstanding.load(), 0U); /* we need to clear them now, otherwise we end up with dangling pointers to the steps via the TLS context, etc */ IncomingTCPConnectionState::clearAllDownstreamConnections(); } @@ -889,6 +890,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_BackendNoOOOR) BOOST_CHECK_EQUAL(s_writeBuffer.size(), 0U); BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), query.size()); BOOST_CHECK(s_backendWriteBuffer == query); + BOOST_CHECK_EQUAL(backend->outstanding.load(), 0U); /* we need to clear them now, otherwise we end up with dangling pointers to the steps via the TLS context, etc */ IncomingTCPConnectionState::clearAllDownstreamConnections(); } @@ -927,6 +929,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_BackendNoOOOR) BOOST_CHECK_EQUAL(s_writeBuffer.size(), 0U); BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), query.size()); BOOST_CHECK(s_backendWriteBuffer == query); + BOOST_CHECK_EQUAL(backend->outstanding.load(), 0U); /* we need to clear them now, otherwise we end up with dangling pointers to the steps via the TLS context, etc */ IncomingTCPConnectionState::clearAllDownstreamConnections(); } @@ -969,6 +972,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_BackendNoOOOR) BOOST_CHECK_EQUAL(s_writeBuffer.size(), 0U); BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), query.size()); BOOST_CHECK(s_backendWriteBuffer == query); + BOOST_CHECK_EQUAL(backend->outstanding.load(), 0U); /* we need to clear them now, otherwise we end up with dangling pointers to the steps via the TLS context, etc */ IncomingTCPConnectionState::clearAllDownstreamConnections(); } @@ -994,6 +998,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_BackendNoOOOR) IncomingTCPConnectionState::handleIO(state, now); BOOST_CHECK_EQUAL(s_writeBuffer.size(), 0U); BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), 0U); + BOOST_CHECK_EQUAL(backend->outstanding.load(), 0U); /* we need to clear them now, otherwise we end up with dangling pointers to the steps via the TLS context, etc */ IncomingTCPConnectionState::clearAllDownstreamConnections(); @@ -1031,6 +1036,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_BackendNoOOOR) IncomingTCPConnectionState::handleIO(state, now); BOOST_CHECK_EQUAL(s_writeBuffer.size(), 0U); BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), query.size()); + BOOST_CHECK_EQUAL(backend->outstanding.load(), 0U); /* we need to clear them now, otherwise we end up with dangling pointers to the steps via the TLS context, etc */ IncomingTCPConnectionState::clearAllDownstreamConnections(); @@ -1103,6 +1109,8 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_BackendNoOOOR) } BOOST_CHECK_EQUAL(s_writeBuffer.size(), query.size() * 2U); BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), query.size() * 2U); + BOOST_CHECK_EQUAL(backend->outstanding.load(), 0U); + /* we need to clear them now, otherwise we end up with dangling pointers to the steps via the TLS context, etc */ IncomingTCPConnectionState::clearAllDownstreamConnections(); } @@ -1159,6 +1167,8 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_BackendNoOOOR) IncomingTCPConnectionState::handleIO(state, now); BOOST_CHECK_EQUAL(s_writeBuffer.size(), 0U); BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), 0U); + BOOST_CHECK_EQUAL(backend->outstanding.load(), 0U); + /* we need to clear them now, otherwise we end up with dangling pointers to the steps via the TLS context, etc */ IncomingTCPConnectionState::clearAllDownstreamConnections(); } @@ -1203,6 +1213,8 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_BackendNoOOOR) } BOOST_CHECK_EQUAL(s_writeBuffer.size(), 0U); BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), 0U); + BOOST_CHECK_EQUAL(backend->outstanding.load(), 0U); + /* we need to clear them now, otherwise we end up with dangling pointers to the steps via the TLS context, etc */ IncomingTCPConnectionState::clearAllDownstreamConnections(); } @@ -1247,6 +1259,8 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_BackendNoOOOR) } BOOST_CHECK_EQUAL(s_writeBuffer.size(), 0U); BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), query.size()); + BOOST_CHECK_EQUAL(backend->outstanding.load(), 0U); + /* we need to clear them now, otherwise we end up with dangling pointers to the steps via the TLS context, etc */ IncomingTCPConnectionState::clearAllDownstreamConnections(); } @@ -1292,6 +1306,8 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_BackendNoOOOR) IncomingTCPConnectionState::handleIO(state, now); BOOST_CHECK_EQUAL(s_writeBuffer.size(), 0U); BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), 0U); + BOOST_CHECK_EQUAL(backend->outstanding.load(), 0U); + /* we need to clear them now, otherwise we end up with dangling pointers to the steps via the TLS context, etc */ IncomingTCPConnectionState::clearAllDownstreamConnections(); } @@ -1347,6 +1363,8 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_BackendNoOOOR) BOOST_CHECK_EQUAL(s_writeBuffer.size(), query.size()); BOOST_CHECK(s_writeBuffer == query); BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), query.size()); + BOOST_CHECK_EQUAL(backend->outstanding.load(), 0U); + /* we need to clear them now, otherwise we end up with dangling pointers to the steps via the TLS context, etc */ IncomingTCPConnectionState::clearAllDownstreamConnections(); } @@ -1403,6 +1421,8 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_BackendNoOOOR) IncomingTCPConnectionState::handleIO(state, now); BOOST_CHECK_EQUAL(s_writeBuffer.size(), 0U); BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), 0U); + BOOST_CHECK_EQUAL(backend->outstanding.load(), 0U); + /* we need to clear them now, otherwise we end up with dangling pointers to the steps via the TLS context, etc */ IncomingTCPConnectionState::clearAllDownstreamConnections(); } @@ -1453,6 +1473,8 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_BackendNoOOOR) IncomingTCPConnectionState::handleIO(state, now); BOOST_CHECK_EQUAL(s_writeBuffer.size(), 0U); BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), query.size() * backend->retries); + BOOST_CHECK_EQUAL(backend->outstanding.load(), 0U); + /* we need to clear them now, otherwise we end up with dangling pointers to the steps via the TLS context, etc */ IncomingTCPConnectionState::clearAllDownstreamConnections(); } @@ -1512,6 +1534,8 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_BackendNoOOOR) BOOST_CHECK_EQUAL(s_writeBuffer.size(), query.size()); BOOST_CHECK(s_writeBuffer == query); BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), query.size() * backend->retries); + BOOST_CHECK_EQUAL(backend->outstanding.load(), 0U); + /* we need to clear them now, otherwise we end up with dangling pointers to the steps via the TLS context, etc */ IncomingTCPConnectionState::clearAllDownstreamConnections(); } @@ -1551,6 +1575,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_BackendNoOOOR) BOOST_CHECK_EQUAL(s_writeBuffer.size(), 0U); BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), query.size()); BOOST_CHECK(s_backendWriteBuffer == query); + BOOST_CHECK_EQUAL(backend->outstanding.load(), 0U); /* we need to clear them now, otherwise we end up with dangling pointers to the steps via the TLS context, etc */ IncomingTCPConnectionState::clearAllDownstreamConnections(); @@ -1610,6 +1635,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_BackendNoOOOR) auto state = std::make_shared(ConnectionInfo(&localCS), threadData, now); IncomingTCPConnectionState::handleIO(state, now); BOOST_CHECK_EQUAL(s_writeBuffer.size(), query.size() * count); + BOOST_CHECK_EQUAL(backend->outstanding.load(), 0U); /* we need to clear them now, otherwise we end up with dangling pointers to the steps via the TLS context, etc */ IncomingTCPConnectionState::clearAllDownstreamConnections(); @@ -1800,6 +1826,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnectionOOOR_BackendOOOR) BOOST_CHECK(s_writeBuffer == expectedWriteBuffer); BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), totalQueriesSize); BOOST_CHECK(s_backendWriteBuffer == expectedBackendWriteBuffer); + BOOST_CHECK_EQUAL(backend->outstanding.load(), 0U); /* we need to clear them now, otherwise we end up with dangling pointers to the steps via the TLS context, etc */ IncomingTCPConnectionState::clearAllDownstreamConnections(); @@ -1943,6 +1970,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnectionOOOR_BackendOOOR) BOOST_CHECK(s_writeBuffer == expectedWriteBuffer); BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), expectedBackendWriteBuffer.size()); BOOST_CHECK(s_backendWriteBuffer == expectedBackendWriteBuffer); + BOOST_CHECK_EQUAL(backend->outstanding.load(), 0U); /* we need to clear them now, otherwise we end up with dangling pointers to the steps via the TLS context, etc */ IncomingTCPConnectionState::clearAllDownstreamConnections(); @@ -2111,6 +2139,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnectionOOOR_BackendOOOR) BOOST_CHECK(s_writeBuffer == expectedWriteBuffer); BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), expectedBackendWriteBuffer.size()); BOOST_CHECK(s_backendWriteBuffer == expectedBackendWriteBuffer); + BOOST_CHECK_EQUAL(backend->outstanding.load(), 0U); /* we need to clear them now, otherwise we end up with dangling pointers to the steps via the TLS context, etc */ IncomingTCPConnectionState::clearAllDownstreamConnections(); @@ -2185,6 +2214,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnectionOOOR_BackendOOOR) BOOST_CHECK(s_writeBuffer == expectedWriteBuffer); BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), expectedBackendWriteBuffer.size()); BOOST_CHECK(s_backendWriteBuffer == expectedBackendWriteBuffer); + BOOST_CHECK_EQUAL(backend->outstanding.load(), 0U); /* we need to clear them now, otherwise we end up with dangling pointers to the steps via the TLS context, etc */ IncomingTCPConnectionState::clearAllDownstreamConnections(); @@ -2256,6 +2286,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnectionOOOR_BackendOOOR) BOOST_CHECK(s_writeBuffer == expectedWriteBuffer); BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), expectedBackendWriteBuffer.size()); BOOST_CHECK(s_backendWriteBuffer == expectedBackendWriteBuffer); + BOOST_CHECK_EQUAL(backend->outstanding.load(), 0U); /* we need to clear them now, otherwise we end up with dangling pointers to the steps via the TLS context, etc */ IncomingTCPConnectionState::clearAllDownstreamConnections(); @@ -2396,6 +2427,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnectionOOOR_BackendOOOR) BOOST_CHECK(s_writeBuffer == expectedWriteBuffer); BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), expectedBackendWriteBuffer.size()); BOOST_CHECK(s_backendWriteBuffer == expectedBackendWriteBuffer); + BOOST_CHECK_EQUAL(backend->outstanding.load(), 0U); /* we need to clear them now, otherwise we end up with dangling pointers to the steps via the TLS context, etc */ IncomingTCPConnectionState::clearAllDownstreamConnections(); @@ -2520,6 +2552,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnectionOOOR_BackendOOOR) BOOST_CHECK(s_writeBuffer == expectedWriteBuffer); BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), expectedBackendWriteBuffer.size()); BOOST_CHECK(s_backendWriteBuffer == expectedBackendWriteBuffer); + BOOST_CHECK_EQUAL(backend->outstanding.load(), 0U); /* we need to clear them now, otherwise we end up with dangling pointers to the steps via the TLS context, etc */ IncomingTCPConnectionState::clearAllDownstreamConnections(); @@ -2985,6 +3018,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnectionOOOR_BackendOOOR) BOOST_CHECK(s_writeBuffer == expectedWriteBuffer); BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), expectedBackendWriteBuffer.size()); BOOST_CHECK(s_backendWriteBuffer == expectedBackendWriteBuffer); + BOOST_CHECK_EQUAL(backend->outstanding.load(), 0U); /* we need to clear them now, otherwise we end up with dangling pointers to the steps via the TLS context, etc */ IncomingTCPConnectionState::clearAllDownstreamConnections(); @@ -3107,6 +3141,117 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnectionOOOR_BackendOOOR) BOOST_CHECK(s_writeBuffer == expectedWriteBuffer); BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), expectedBackendWriteBuffer.size()); BOOST_CHECK(s_backendWriteBuffer == expectedBackendWriteBuffer); + BOOST_CHECK_EQUAL(proxyEnabledBackend->outstanding.load(), 0U); + + /* we need to clear them now, otherwise we end up with dangling pointers to the steps via the TLS context, etc */ + /* we should have nothing to clear since the connection cannot be reused due to the Proxy Protocol payload */ + BOOST_CHECK_EQUAL(IncomingTCPConnectionState::clearAllDownstreamConnections(), 0U); + } + + { + TEST_INIT("=> Outgoing proxy protocol, 3 queries to the backend, the client closes while sending the first response"); + + PacketBuffer expectedWriteBuffer; + PacketBuffer expectedBackendWriteBuffer; + + auto proxyPayload = makeProxyHeader(true, ComboAddress("0.0.0.0"), local, {}); + BOOST_REQUIRE_GT(proxyPayload.size(), s_proxyProtocolMinimumHeaderSize); + + s_readBuffer.insert(s_readBuffer.end(), queries.at(0).begin(), queries.at(0).end()); + s_readBuffer.insert(s_readBuffer.end(), queries.at(1).begin(), queries.at(1).end()); + s_readBuffer.insert(s_readBuffer.end(), queries.at(2).begin(), queries.at(2).end()); + + auto proxyEnabledBackend = std::make_shared(ComboAddress("192.0.2.42:53"), ComboAddress("0.0.0.0:0"), 0, std::string(), 1, false); + proxyEnabledBackend->d_tlsCtx = tlsCtx; + /* enable out-of-order on the backend side as well */ + proxyEnabledBackend->d_maxInFlightQueriesPerConn = 65536; + proxyEnabledBackend-> useProxyProtocol = true; + + expectedBackendWriteBuffer.insert(expectedBackendWriteBuffer.end(), proxyPayload.begin(), proxyPayload.end()); + expectedBackendWriteBuffer.insert(expectedBackendWriteBuffer.end(), queries.at(0).begin(), queries.at(0).end()); + expectedBackendWriteBuffer.insert(expectedBackendWriteBuffer.end(), queries.at(1).begin(), queries.at(1).end()); + expectedBackendWriteBuffer.insert(expectedBackendWriteBuffer.end(), queries.at(2).begin(), queries.at(2).end()); + + expectedBackendWriteBuffer.insert(expectedBackendWriteBuffer.end(), proxyPayload.begin(), proxyPayload.end()); + expectedBackendWriteBuffer.insert(expectedBackendWriteBuffer.end(), queries.at(2).begin(), queries.at(2).end()); + //s_backendReadBuffer.insert(s_backendReadBuffer.end(), responses.at(2).begin(), responses.at(2).end()); + + s_steps = { + { ExpectedStep::ExpectedRequest::handshakeClient, IOState::Done }, + /* reading a query from the client (1) */ + { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 2 }, + { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, queries.at(0).size() - 2 }, + /* opening a connection to the backend */ + { ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done }, + /* sending query (1) to the backend */ + { ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, proxyPayload.size() + queries.at(0).size() }, + /* we try to read the response, not ready yet */ + { ExpectedStep::ExpectedRequest::readFromBackend, IOState::NeedRead, 0 }, + /* reading a second query from the client */ + { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 2 }, + { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, queries.at(1).size() - 2 }, + /* sending query (2) to the backend */ + { ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, queries.at(1).size() }, + /* backend is not ready yet */ + { ExpectedStep::ExpectedRequest::readFromBackend, IOState::NeedRead, 0 }, + /* reading a third query from the client */ + { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 2 }, + { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, queries.at(2).size() - 2 }, + /* sending query (3) to the backend */ + { ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, queries.at(2).size() }, + /* backend is not ready yet, but the descriptor becomes ready */ + { ExpectedStep::ExpectedRequest::readFromBackend, IOState::NeedRead, 0, [&threadData](int desc, const ExpectedStep& step) { + /* the backend descriptor becomes ready */ + dynamic_cast(threadData.mplexer.get())->setReady(desc); + }}, + /* client closes the connection */ + { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 0 }, + /* closing the client connection */ + { ExpectedStep::ExpectedRequest::closeClient, IOState::Done, 0 }, + /* try to read response from backend, connection has been closed */ + { ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, 0 }, + //{ ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, responses.at(2).size() }, + /* closing the backend connection */ + { ExpectedStep::ExpectedRequest::closeBackend, IOState::Done, 0 }, + { ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done }, + { ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, 0 }, + { ExpectedStep::ExpectedRequest::closeBackend, IOState::Done, 0 }, + { ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done }, + { ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, 0 }, + { ExpectedStep::ExpectedRequest::closeBackend, IOState::Done, 0 }, + { ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done }, + { ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, 0 }, + { ExpectedStep::ExpectedRequest::closeBackend, IOState::Done, 0 }, + { ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done }, + { ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, 0 }, + { ExpectedStep::ExpectedRequest::closeBackend, IOState::Done, 0 }, + { ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done }, + /* sending query (3) to the backend */ + { ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, proxyPayload.size() + queries.at(2).size() }, + /* sending query (2) to the backend */ + { ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, 0 }, + { ExpectedStep::ExpectedRequest::closeBackend, IOState::Done, 0 }, + }; + + s_processQuery = [proxyEnabledBackend](DNSQuestion& dq, ClientState& cs, LocalHolders& holders, std::shared_ptr& selectedBackend) -> ProcessQueryResult { + selectedBackend = proxyEnabledBackend; + return ProcessQueryResult::PassToBackend; + }; + s_processResponse = [](PacketBuffer& response, LocalStateHolder >& localRespRuleActions, DNSResponse& dr, bool muted) -> bool { + return true; + }; + + auto state = std::make_shared(ConnectionInfo(&localCS), threadData, now); + IncomingTCPConnectionState::handleIO(state, now); + while (threadData.mplexer->getWatchedFDCount(false) != 0 || threadData.mplexer->getWatchedFDCount(true) != 0) { + threadData.mplexer->run(&now); + } + + BOOST_CHECK_EQUAL(s_writeBuffer.size(), expectedWriteBuffer.size()); + BOOST_CHECK(s_writeBuffer == expectedWriteBuffer); + BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), expectedBackendWriteBuffer.size()); + BOOST_CHECK(s_backendWriteBuffer == expectedBackendWriteBuffer); + BOOST_CHECK_EQUAL(proxyEnabledBackend->outstanding.load(), 0U); /* we need to clear them now, otherwise we end up with dangling pointers to the steps via the TLS context, etc */ /* we should have nothing to clear since the connection cannot be reused due to the Proxy Protocol payload */ @@ -3180,6 +3325,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnectionOOOR_BackendOOOR) BOOST_CHECK_EQUAL(s_writeBuffer.size(), 0U); BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), 0U); + BOOST_CHECK_EQUAL(backend->outstanding.load(), 0U); /* restore */ backend->tcpSendTimeout = 30; @@ -3347,12 +3493,14 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnectionOOOR_BackendOOOR) BOOST_CHECK(s_writeBuffer == expectedWriteBuffer); BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), totalQueriesSize); BOOST_CHECK(s_backendWriteBuffer == expectedBackendWriteBuffer); + BOOST_CHECK_EQUAL(backend1->outstanding.load(), 0U); /* we need to clear them now, otherwise we end up with dangling pointers to the steps via the TLS context, etc */ BOOST_CHECK_EQUAL(IncomingTCPConnectionState::clearAllDownstreamConnections(), 2U); } } + BOOST_AUTO_TEST_CASE(test_IncomingConnectionOOOR_BackendNotOOOR) { ComboAddress local("192.0.2.1:80"); @@ -3558,6 +3706,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnectionOOOR_BackendNotOOOR) BOOST_CHECK(s_writeBuffer == expectedWriteBuffer); BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), totalQueriesSize); BOOST_CHECK(s_backendWriteBuffer == expectedBackendWriteBuffer); + BOOST_CHECK_EQUAL(backend->outstanding.load(), 0U); /* we need to clear them now, otherwise we end up with dangling pointers to the steps via the TLS context, etc */ BOOST_CHECK_EQUAL(IncomingTCPConnectionState::clearAllDownstreamConnections(), 5U); -- 2.47.2