From: Remi Gacogne Date: Mon, 15 Jul 2019 13:07:10 +0000 (+0200) Subject: dnsdist: Fix unlimited retries when TCP Fast Open is enabled X-Git-Tag: dnsdist-1.4.0-rc1~45^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a4aa1f330423a2d3a86b22779a70c04a5fc65a55;p=pdns dnsdist: Fix unlimited retries when TCP Fast Open is enabled Using the same flag to indicate whether a connection was reused after being pulled from the pool AND to know if the TFO flag should be passed to sendmsg() led to an unlimited number of reconnection attemps when TFO was enabled and the backend closed the connection right after a write (sendmsg() succeeds then read() returns 0 right away). --- diff --git a/pdns/dnsdist-tcp.cc b/pdns/dnsdist-tcp.cc index be50cd305..90dbfaec5 100644 --- a/pdns/dnsdist-tcp.cc +++ b/pdns/dnsdist-tcp.cc @@ -107,7 +107,7 @@ static std::unique_ptr setupTCPDownstream(shared_ptr& d class TCPConnectionToBackend { public: - TCPConnectionToBackend(std::shared_ptr& ds, uint16_t& downstreamFailures, const struct timeval& now): d_ds(ds), d_connectionStartTime(now) + TCPConnectionToBackend(std::shared_ptr& ds, uint16_t& downstreamFailures, const struct timeval& now): d_ds(ds), d_connectionStartTime(now), d_enableFastOpen(ds->tcpFastOpen) { d_socket = setupTCPDownstream(d_ds, downstreamFailures); ++d_ds->tcpCurrentConnections; @@ -154,12 +154,23 @@ public: d_fresh = false; } + void disableFastOpen() + { + d_enableFastOpen = false; + } + + bool isFastOpenEnabled() + { + return d_enableFastOpen; + } + private: std::unique_ptr d_socket{nullptr}; std::shared_ptr d_ds{nullptr}; struct timeval d_connectionStartTime; uint64_t d_queries{0}; bool d_fresh{true}; + bool d_enableFastOpen{false}; }; static thread_local map>> t_downstreamConnections; @@ -912,7 +923,7 @@ static void handleDownstreamIO(std::shared_ptr& stat if (state->d_state == IncomingTCPConnectionState::State::sendingQueryToBackend) { int socketFlags = 0; #ifdef MSG_FASTOPEN - if (state->d_ds->tcpFastOpen && state->d_downstreamConnection->isFresh()) { + if (state->d_downstreamConnection->isFastOpenEnabled()) { socketFlags |= MSG_FASTOPEN; } #endif /* MSG_FASTOPEN */ @@ -935,7 +946,7 @@ static void handleDownstreamIO(std::shared_ptr& stat state->d_currentPos += sent; iostate = IOState::NeedWrite; /* disable fast open on partial write */ - state->d_downstreamConnection->setReused(); + state->d_downstreamConnection->disableFastOpen(); } }