From: Remi Gacogne Date: Mon, 5 Oct 2020 12:39:08 +0000 (+0200) Subject: dnsdist: Better handling of reconnection failures X-Git-Tag: auth-4.5.0-alpha0~14^2~3 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=8904f4fd2964a948807b5feb6d353edba6087382;p=thirdparty%2Fpdns.git dnsdist: Better handling of reconnection failures --- diff --git a/pdns/dnsdist-tcp.cc b/pdns/dnsdist-tcp.cc index 1f5387e274..db17474101 100644 --- a/pdns/dnsdist-tcp.cc +++ b/pdns/dnsdist-tcp.cc @@ -935,6 +935,13 @@ static void tcpClientThread(int pipefd) if (g_downstreamTCPCleanupInterval > 0 && (now.tv_sec > (lastTCPCleanup + g_downstreamTCPCleanupInterval))) { DownstreamConnectionsManager::cleanupClosedTCPConnections(); lastTCPCleanup = now.tv_sec; + + /* + data.mplexer->runForAllWatchedFDs([](bool isRead, int fd, const FDMultiplexer::funcparam_t& param, struct timeval ttd) + { + cerr<<"- "< lastTimeoutScan) { diff --git a/pdns/dnsdistdist/dnsdist-tcp-downstream.cc b/pdns/dnsdistdist/dnsdist-tcp-downstream.cc index 8e63caf70e..622b6a9331 100644 --- a/pdns/dnsdistdist/dnsdist-tcp-downstream.cc +++ b/pdns/dnsdistdist/dnsdist-tcp-downstream.cc @@ -213,38 +213,44 @@ void TCPConnectionToBackend::handleIO(std::shared_ptr& c conn->d_ioState->reset(); ioGuard.release(); - if (conn->reconnect()) { - conn->d_ioState = make_unique(conn->d_clientConn->getIOMPlexer(), conn->d_socket->getHandle()); - - /* we need to resend the queries that were in flight, if any */ - for (auto& pending : conn->d_pendingResponses) { - conn->d_pendingQueries.push_back(std::move(pending.second)); - if (!conn->d_usedForXFR) { - --conn->d_ds->outstanding; + try { + if (conn->reconnect()) { + conn->d_ioState = make_unique(conn->d_clientConn->getIOMPlexer(), conn->d_socket->getHandle()); + + /* we need to resend the queries that were in flight, if any */ + for (auto& pending : conn->d_pendingResponses) { + conn->d_pendingQueries.push_back(std::move(pending.second)); + if (!conn->d_usedForXFR) { + --conn->d_ds->outstanding; + } } - } - conn->d_pendingResponses.clear(); - conn->d_currentPos = 0; + conn->d_pendingResponses.clear(); + conn->d_currentPos = 0; - if (conn->d_state == State::doingHandshake || - conn->d_state == State::sendingQueryToBackend) { - iostate = IOState::NeedWrite; - // resume sending query - } - else { - if (conn->d_pendingQueries.empty()) { - throw std::runtime_error("TCP connection to a backend in state " + std::to_string((int)conn->d_state) + " with no pending queries"); + if (conn->d_state == State::doingHandshake || + conn->d_state == State::sendingQueryToBackend) { + iostate = IOState::NeedWrite; + // resume sending query } + else { + if (conn->d_pendingQueries.empty()) { + throw std::runtime_error("TCP connection to a backend in state " + std::to_string((int)conn->d_state) + " with no pending queries"); + } - iostate = queueNextQuery(conn); - } + iostate = queueNextQuery(conn); + } - if (!conn->d_proxyProtocolPayloadAdded && !conn->d_proxyProtocolPayload.empty()) { - conn->d_currentQuery.d_buffer.insert(conn->d_currentQuery.d_buffer.begin(), conn->d_proxyProtocolPayload.begin(), conn->d_proxyProtocolPayload.end()); - conn->d_proxyProtocolPayloadAdded = true; - } + if (!conn->d_proxyProtocolPayloadAdded && !conn->d_proxyProtocolPayload.empty()) { + conn->d_currentQuery.d_buffer.insert(conn->d_currentQuery.d_buffer.begin(), conn->d_proxyProtocolPayload.begin(), conn->d_proxyProtocolPayload.end()); + conn->d_proxyProtocolPayloadAdded = true; + } - reconnected = true; + reconnected = true; + } + } + catch (const std::exception& e) { + // reconnect might throw on failure, let's ignore that, we just need to know + // it failed } }